/usr/include/odil/dul/StateMachine.h is in libodil-dev 0.8.0-4build1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 | /*************************************************************************
* odil - Copyright (C) Universite de Strasbourg
* Distributed under the terms of the CeCILL-B license, as published by
* the CEA-CNRS-INRIA. Refer to the LICENSE file or to
* http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
* for details.
************************************************************************/
#ifndef _981c80db_b2ac_4f25_af6c_febf5563d178
#define _981c80db_b2ac_4f25_af6c_febf5563d178
#include <functional>
#include <map>
#include <tuple>
#include <utility>
#include <boost/asio.hpp>
#include "odil/AssociationAcceptor.h"
#include "odil/dul/EventData.h"
#include "odil/dul/Transport.h"
#include "odil/odil.h"
namespace odil
{
namespace dul
{
/// @brief State machine for the DICOM upper layer.
class ODIL_API StateMachine
{
public:
/// @brief States of the state machine.
enum class State
{
Sta1,
Sta2, Sta3, Sta4, Sta5,
Sta6,
Sta7, Sta8, Sta9, Sta10, Sta11, Sta12,
Sta13
};
/// @brief Event causing the transitions.
enum class Event
{
None, // dummy event to allow easier initialization
TransportConnectionIndication, TransportConnectionConfirmation,
TransportConnectionClosedIndication,
AAssociateRQLocal, AAssociateRQRemote,
AAssociateACLocal, AAssociateACRemote,
AAssociateRJLocal, AAssociateRJRemote,
AReleaseRQLocal, AReleaseRQRemote,
AReleaseRPLocal, AReleaseRPRemote,
PDataTFLocal, PDataTFRemote,
AAbortLocal, AAbortRemote,
ARTIMTimerExpired, InvalidPDU,
};
/// @brief Duration of the timeout.
typedef boost::asio::deadline_timer::duration_type duration_type;
/// @brief Constructor, initializing to Sta1.
StateMachine();
/// @brief Destructor, closing the transport.
~StateMachine();
/**
* @brief Perform the transition related to the event and current state.
* Raise an exception if no such transition exists.
*/
void transition(Event const & event, EventData & data);
/// @brief Return the current state.
State get_state() const;
/// @brief Return the TCP transport.
Transport const & get_transport() const;
/// @brief Return the TCP transport.
Transport & get_transport();
/// @brief Return the timeout, default to infinity.
duration_type get_timeout() const;
/// @brief Set the timeout.
void set_timeout(duration_type timeout);
/**
* @brief Receive a connection on the TCP transport, perform the
* corresponding transition.
*/
void receive(EventData & data);
/// @brief Send a PDU to the transport, perform the corresponding transition.
void send_pdu(EventData & data);
/// @brief Receive a PDU on the transport, perform the corresponding transition.
void receive_pdu(EventData & data);
/// @brief Start (or re-start if already started) the ARTIM timer.
void start_timer(EventData & data);
/// @brief Stop the ARTIM timer.
void stop_timer();
/**
* @brief Return the callback checking whether the association request is
* acceptable.
*
* By default, all association requests are accepted.
*/
AssociationAcceptor const & get_association_acceptor() const;
/**
* @brief Set the callback checking whether the association request is
* acceptable.
*/
void set_association_acceptor(AssociationAcceptor const & acceptor);
private:
enum class Action
{
AE_1, AE_2, AE_3, AE_4, AE_5, AE_6, AE_7, AE_8,
DT_1, DT_2,
AR_1, AR_2, AR_3, AR_4, AR_5, AR_6, AR_7, AR_8, AR_9, AR_10,
AA_1, AA_2, AA_3, AA_4, AA_5, AA_6, AA_7, AA_8
};
typedef std::map<
std::tuple<State, Event, bool>,
std::pair<Action, State>> TransitionMap;
typedef std::map<
std::pair<State, Event>,
std::function<bool(StateMachine const &, EventData &)>> GuardMap;
static TransitionMap const _transitions;
static GuardMap const _guards;
/// @brief Current state.
State _state;
/// @brief TCP transport.
Transport _transport;
/// @brief Timeout of the ARTIM timer.
duration_type _timeout;
/// @brief Association Request/Reject/Release Timer.
boost::asio::deadline_timer _artim_timer;
/// @brief Callback checking whether an association request is acceptable.
AssociationAcceptor _association_acceptor;
/// @brief Check the PDU type in data and send it.
void _send_pdu(EventData & data, uint8_t pdu_type);
/**
* @brief Issue TRANSPORT CONNECT request primitive to local transport
* service.
*/
void AE_1(EventData & data);
/// @brief Send A-ASSOCIATE-RQ-PDU.
void AE_2(EventData & data);
/// @brief Issue A-ASSOCIATE confirmation (accept) primitive.
void AE_3(EventData & data);
/**
* @brief Issue A-ASSOCIATE confirmation (reject) primitive and close
* transport connection.
*/
void AE_4(EventData & data);
/// @brief Issue Transport connection response primitive; start ARTIM timer.
void AE_5(EventData & data);
/// @brief Stop ARTIM timer and accept or reject connection.
void AE_6(EventData & data);
/// @brief Send A-ASSOCIATE-AC PDU.
void AE_7(EventData & data);
/// @brief Send A-ASSOCIATE-RJ PDU and start ARTIM timer.
void AE_8(EventData & data);
/// @brief Send P-DATA-TF PDU.
void DT_1(EventData & data);
/// @brief Send P-DATA indication primitive.
void DT_2(EventData & data);
/// @brief Send A-RELEASE-RQ PDU.
void AR_1(EventData & data);
/// @brief Issue A-RELEASE indication primitive.
void AR_2(EventData & data);
/**
* @brief Issue A-RELEASE confirmation primitive, and close transport.
* connection.
*/
void AR_3(EventData & data);
/// @brief Issue A-RELEASE-RP PDU and start ARTIM timer.
void AR_4(EventData & data);
/// @brief Stop ARTIM timer.
void AR_5(EventData & data);
/// @brief Issue P-DATA indication.
void AR_6(EventData & data);
/// @brief Issue P-DATA-TF PDU.
void AR_7(EventData & data);
/// @brief Issue A-RELEASE indication (release collision).
void AR_8(EventData & data);
/// @brief Send A-RELEASE-RP PDU.
void AR_9(EventData & data);
/// @brief Issue A-RELEASE confirmation primitive.
void AR_10(EventData & data);
/**
* @brief Send A-ABORT PDU (service-user source) and start (or restart if
* already started) ARTIM timer.
*/
void AA_1(EventData & data);
/// @brief Stop ARTIM timer if running. Close transport connection.
void AA_2(EventData & data);
/**
* @brief If (service-user inititated abort): issue A-ABORT indication and
* close transport connection ; otherwise (service-provider inititated
* abort): issue A-P-ABORT indication and close transport connection.
*/
void AA_3(EventData & data);
/// @brief Issue A-P-ABORT indication primitive.
void AA_4(EventData & data);
/// @brief Stop ARTIM timer.
void AA_5(EventData & data);
/// @brief Ignore PDU.
void AA_6(EventData & data);
/// @brief Send A-ABORT PDU.
void AA_7(EventData & data);
/**
* @brief Send A-ABORT PDU (service-provider source-), issue an A-P-ABORT
* indication, and start ARTIM timer.
*/
void AA_8(EventData & data);
};
}
}
#endif // _981c80db_b2ac_4f25_af6c_febf5563d178
|