cipconnectionobject.h 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463
  1. /*******************************************************************************
  2. * Copyright (c) 2017, Rockwell Automation, Inc.
  3. * All rights reserved.
  4. *
  5. ******************************************************************************/
  6. #ifndef SRC_CIP_CIPCONNECTIONOBJECT_H_
  7. #define SRC_CIP_CIPCONNECTIONOBJECT_H_
  8. #include "typedefs.h"
  9. #include "ciptypes.h"
  10. #include "opener_user_conf.h"
  11. #include "opener_api.h"
  12. #include "doublylinkedlist.h"
  13. #include "cipelectronickey.h"
  14. #include "cipepath.h"
  15. #define CIP_CONNECTION_OBJECT_CODE 0x05
  16. typedef enum {
  17. kConnectionObjectStateNonExistent = 0, /**< Connection is non existent */
  18. kConnectionObjectStateConfiguring, /**< Waiting for both to be configured and to apply the configuration */
  19. kConnectionObjectStateWaitingForConnectionID, /**< Only used for device net */
  20. kConnectionObjectStateEstablished, /**< Connection is established */
  21. kConnectionObjectStateTimedOut, /**< Connection timed out - inactivity or watchdog timer expired */
  22. kConnectionObjectStateDeferredDelete, /**< Only used for device net */
  23. kConnectionObjectStateClosing, /**< For CIP bridged connections - have to wait for a successful forward close */
  24. kConnectionObjectStateInvalid /**< An invalid state, shall never occur! */
  25. } ConnectionObjectState;
  26. typedef enum {
  27. kConnectionObjectInstanceTypeInvalid = (CipUsint)(~0), /**< Invalid instance type - shall never occur! */
  28. kConnectionObjectInstanceTypeExplicitMessaging = 0, /**< Connection is an explicit messaging connection */
  29. kConnectionObjectInstanceTypeIO, /**< Connection is an I/O connection */
  30. kConnectionObjectInstanceTypeIOExclusiveOwner, /**< Also I/O connection, only for easy differentiation */
  31. kConnectionObjectInstanceTypeIOInputOnly, /**< Also I/O connection, only for easy differentiation */
  32. kConnectionObjectInstanceTypeIOListenOnly, /**< Also I/O connection, only for easy differentiation */
  33. kConnectionObjectInstanceTypeCipBridged /**< Connection is a bridged connection */
  34. } ConnectionObjectInstanceType;
  35. typedef enum {
  36. kConnectionObjectTransportClassTriggerDirectionClient = 0, /**< Endpoint provides client behavior */
  37. kConnectionObjectTransportClassTriggerDirectionServer /**< Endpoint provides server behavior - production trigger bits are to be ignored */
  38. } ConnectionObjectTransportClassTriggerDirection;
  39. typedef enum {
  40. kConnectionObjectTransportClassTriggerProductionTriggerInvalid = -1, /**< Invalid Production trigger - shall never occur! */
  41. kConnectionObjectTransportClassTriggerProductionTriggerCyclic = 0, /**< Transmission Trigger Timer trigger data production */
  42. kConnectionObjectTransportClassTriggerProductionTriggerChangeOfState, /**< Production is trigger when change-of-state is detected by the Application Object */
  43. kConnectionObjectTransportClassTriggerProductionTriggerApplicationObject /**< The Application Object decided when production is triggered */
  44. } ConnectionObjectTransportClassTriggerProductionTrigger;
  45. typedef enum {
  46. kConnectionObjectTransportClassTriggerTransportClassInvalid = -1, /**< Invalid Transport Class - shall never occur! */
  47. kConnectionObjectTransportClassTriggerTransportClass0 = 0, /**< Class 0 producing or consuming connection, based on Direction */
  48. kConnectionObjectTransportClassTriggerTransportClass1, /**< Class 1 producing or consuming connection, based on Direction */
  49. kConnectionObjectTransportClassTriggerTransportClass2, /**< Class 2 producing and consuming connection, Client starts producing */
  50. kConnectionObjectTransportClassTriggerTransportClass3 /**< Class 3 producing and consuming connection, Client starts producing */
  51. /* Higher transport classes not supported */
  52. } ConnectionObjectTransportClassTriggerTransportClass;
  53. /** @brief Possible values for the watch dog time out action of a connection
  54. *
  55. * Only positive values allowed
  56. */
  57. typedef enum {
  58. kConnectionObjectWatchdogTimeoutActionTransitionToTimedOut = 0, /**< Default for I/O connections, invalid for Explicit Messaging */
  59. kConnectionObjectWatchdogTimeoutActionAutoDelete, /**< Default for explicit connections */
  60. kConnectionObjectWatchdogTimeoutActionAutoReset, /**< Invalid for explicit connections */
  61. kConnectionObjectWatchdogTimeoutActionDeferredDelete, /**< Only for Device Net, invalid for I/O connections */
  62. kConnectionObjectWatchdogTimeoutActionInvalid /**< Invalid Watchdog Timeout Action - shall never occur! */
  63. } ConnectionObjectWatchdogTimeoutAction;
  64. typedef enum {
  65. kConnectionObjectConnectionTypeNull = 0,
  66. kConnectionObjectConnectionTypeMulticast,
  67. kConnectionObjectConnectionTypePointToPoint,
  68. kConnectionObjectConnectionTypeInvalid
  69. } ConnectionObjectConnectionType;
  70. typedef enum {
  71. kConnectionObjectPriorityLow = 0,
  72. kConnectionObjectPriorityHigh,
  73. kConnectionObjectPriorityScheduled,
  74. kConnectionObjectPriorityUrgent,
  75. kConnectionObjectPriorityExplicit
  76. } ConnectionObjectPriority;
  77. typedef enum {
  78. kConnectionObjectConnectionSizeTypeFixed,
  79. kConnectionObjectConnectionSizeTypeVariable
  80. } ConnectionObjectConnectionSizeType;
  81. typedef enum {
  82. kConnectionObjectSocketTypeProducing = 0,
  83. kConnectionObjectSocketTypeConsuming = 1
  84. } ConnectionObjectSocketType;
  85. typedef struct cip_connection_object CipConnectionObject;
  86. typedef EipStatus (*CipConnectionStateHandler)(CipConnectionObject *RESTRICT
  87. const connection_object,
  88. ConnectionObjectState new_state);
  89. struct cip_connection_object {
  90. CipUsint state; /*< Attribute 1 */
  91. CipUsint instance_type; /*< Attribute 2 */
  92. CipByte transport_class_trigger; /*< Attribute 3 */
  93. /* Attribute 4-6 only for device net*/
  94. CipUint produced_connection_size; /*< Attribute 7 - Limits produced connection size - for explicit messaging 0xFFFF means no predefined limit */
  95. CipUint consumed_connection_size; /*< Attribute 8 - Limits produced connection size - for explicit messaging 0xFFFF means no predefined limit */
  96. CipUint expected_packet_rate; /*< Attribute 9 - Resolution in Milliseconds */
  97. CipUdint cip_produced_connection_id; /*< Attribute 10 */
  98. CipUdint cip_consumed_connection_id; /*< Attribute 11 */
  99. CipUsint watchdog_timeout_action; /*< Attribute 12 */
  100. CipUint produced_connection_path_length; /*< Attribute 13 */
  101. CipOctet *produced_connection_path; /*< Attribute 14 */
  102. CipConnectionPathEpath produced_path;
  103. CipUint consumed_connection_path_length; /*< Attribute 15 */
  104. CipOctet *consumed_connection_path; /*< Attribute 16 */
  105. CipConnectionPathEpath consumed_path;
  106. CipUint production_inhibit_time; /*< Attribute 17 */
  107. CipUsint connection_timeout_multiplier; /*< Attribute 18 */
  108. /* Attribute 19 not supported as Connection Bind service not supported */
  109. /* End of CIP attributes */
  110. /* Start of needed non-object variables */
  111. CipElectronicKey electronic_key; //TODO: Check if really needed
  112. CipConnectionPathEpath configuration_path;
  113. CipInstance *producing_instance;
  114. CipInstance *consuming_instance;
  115. CipUint requested_produced_connection_size;
  116. CipUint requested_consumed_connection_size;
  117. uint64_t transmission_trigger_timer;
  118. uint64_t inactivity_watchdog_timer;
  119. uint64_t last_package_watchdog_timer;
  120. uint64_t production_inhibit_timer;
  121. CipUint connection_serial_number;
  122. CipUint originator_vendor_id;
  123. CipUdint originator_serial_number;
  124. CipUint connection_number;
  125. CipUdint o_to_t_requested_packet_interval;
  126. CipDword o_to_t_network_connection_parameters;
  127. CipUdint t_to_o_requested_packet_interval;
  128. CipDword t_to_o_network_connection_parameters;
  129. CipUint sequence_count_producing; /**< sequence Count for Class 1 Producing
  130. Connections */
  131. CipUint sequence_count_consuming; /**< sequence Count for Class 1 Producing
  132. Connections */
  133. EipUint32 eip_level_sequence_count_producing; /**< the EIP level sequence Count
  134. for Class 0/1
  135. Producing Connections may have a
  136. different
  137. value than SequenceCountProducing */
  138. EipUint32 eip_level_sequence_count_consuming; /**< the EIP level sequence Count
  139. for Class 0/1
  140. Producing Connections may have a
  141. different
  142. value than SequenceCountProducing */
  143. CipBool eip_first_level_sequence_count_received; /**< False if eip_level_sequence_count_consuming
  144. hasn't been initialized with a sequence
  145. count yet, true otherwise */
  146. CipInt correct_originator_to_target_size;
  147. CipInt correct_target_to_originator_size;
  148. /* Sockets for consuming and producing connection */
  149. int socket[2];
  150. struct sockaddr_in remote_address; /* socket address for produce */
  151. struct sockaddr_in originator_address; /* the address of the originator that
  152. established the connection. needed
  153. for scanning if the right packet is
  154. arriving */
  155. CipSessionHandle associated_encapsulation_session; /* The session handle ID via which the forward open was sent */
  156. /* pointers to connection handling functions */
  157. CipConnectionStateHandler current_state_handler;
  158. ConnectionCloseFunction connection_close_function;
  159. ConnectionTimeoutFunction connection_timeout_function;
  160. ConnectionSendDataFunction connection_send_data_function;
  161. ConnectionReceiveDataFunction connection_receive_data_function;
  162. ENIPMessage last_reply_sent;
  163. CipBool is_large_forward_open;
  164. };
  165. /** @brief Extern declaration of the global connection list */
  166. extern DoublyLinkedList connection_list;
  167. DoublyLinkedListNode *CipConnectionObjectListArrayAllocator(void);
  168. void CipConnectionObjectListArrayFree(DoublyLinkedListNode **node);
  169. /** @brief Array allocator
  170. *
  171. */
  172. CipConnectionObject *CipConnectionObjectCreate(const CipOctet *message);
  173. /** @brief Array deallocator
  174. *
  175. */
  176. void CipConnectionObjectDelete(CipConnectionObject **connection_object);
  177. void ConnectionObjectInitializeEmpty(
  178. CipConnectionObject *const connection_object);
  179. void ConnectionObjectInitializeFromMessage(
  180. const CipOctet **message,
  181. CipConnectionObject *const
  182. connection_object);
  183. ConnectionObjectState ConnectionObjectGetState(
  184. const CipConnectionObject *const connection_object);
  185. void ConnectionObjectSetState(CipConnectionObject *const connection_object,
  186. const ConnectionObjectState state);
  187. ConnectionObjectInstanceType ConnectionObjectGetInstanceType(
  188. const CipConnectionObject *const connection_object);
  189. void ConnectionObjectSetInstanceType(
  190. CipConnectionObject *const connection_object,
  191. const ConnectionObjectInstanceType instance_type);
  192. CipUsint ConnectionObjectGetInstanceTypeForAttribute(
  193. const CipConnectionObject *const connection_object);
  194. ConnectionObjectTransportClassTriggerDirection
  195. ConnectionObjectGetTransportClassTriggerDirection(
  196. const CipConnectionObject *const connection_object);
  197. ConnectionObjectTransportClassTriggerProductionTrigger
  198. ConnectionObjectGetTransportClassTriggerProductionTrigger(
  199. const CipConnectionObject *const connection_object);
  200. ConnectionObjectTransportClassTriggerTransportClass
  201. ConnectionObjectGetTransportClassTriggerTransportClass(
  202. const CipConnectionObject *const connection_object);
  203. CipUint ConnectionObjectGetProducedConnectionSize(
  204. const CipConnectionObject *const connection_object);
  205. void ConnectionObjectSetProducedConnectionSize(
  206. CipConnectionObject *const connection_object,
  207. const CipUint
  208. produced_connection_size);
  209. CipUint ConnectionObjectGetConsumedConnectionSize(
  210. const CipConnectionObject *const connection_object);
  211. void ConnectionObjectSetConsumedConnectionSize(
  212. CipConnectionObject *const connection_object,
  213. const CipUint
  214. consumed_connection_size);
  215. CipUint ConnectionObjectGetExpectedPacketRate(
  216. const CipConnectionObject *const connection_object);
  217. CipUint ConnectionObjectGetRequestedPacketInterval(
  218. const CipConnectionObject *const connection_object);
  219. /**
  220. * @brief Sets the expected packet rate according to the rules of the CIP specification
  221. *
  222. * As this function sets the expected packet rate according to the rules of the CIP specification, it is not always
  223. * the exact value entered, but rounded up to the next serviceable increment, relative to the timer resolution
  224. */
  225. void ConnectionObjectSetExpectedPacketRate(
  226. CipConnectionObject *const connection_object);
  227. CipUdint ConnectionObjectGetCipProducedConnectionID(
  228. const CipConnectionObject *const connection_object);
  229. void ConnectionObjectSetCipProducedConnectionID(
  230. CipConnectionObject *const connection_object,
  231. const CipUdint
  232. cip_produced_connection_id);
  233. CipUdint ConnectionObjectGetCipConsumedConnectionID(
  234. const CipConnectionObject *const connection_object);
  235. void ConnectionObjectSetCipConsumedConnectionID(
  236. CipConnectionObject *const connection_object,
  237. const CipUdint
  238. cip_consumed_connection_id);
  239. ConnectionObjectWatchdogTimeoutAction ConnectionObjectGetWatchdogTimeoutAction(
  240. const CipConnectionObject *const connection_object);
  241. void ConnectionObjectSetWatchdogTimeoutAction(
  242. CipConnectionObject *const connection_object,
  243. const CipUsint
  244. watchdog_timeout_action);
  245. CipUint ConnectionObjectGetProducedConnectionPathLength(
  246. const CipConnectionObject *const connection_object);
  247. void ConnectionObjectSetProducedConnectionPathLength(
  248. CipConnectionObject *const connection_object,
  249. const CipUint
  250. produced_connection_path_length);
  251. CipUint ConnectionObjectGetConsumedConnectionPathLength(
  252. const CipConnectionObject *const connection_object);
  253. void ConnectionObjectSetConsumedConnectionPathLength(
  254. CipConnectionObject *const connection_object,
  255. const CipUint
  256. consumed_connection_path_length);
  257. CipUint ConnectionObjectGetProductionInhibitTime(
  258. const CipConnectionObject *const connection_object);
  259. void ConnectionObjectSetProductionInhibitTime(
  260. CipConnectionObject *const connection_object,
  261. const CipUint
  262. production_inhibit_time);
  263. CipUsint ConnectionObjectGetConnectionTimeoutMultiplier(
  264. const CipConnectionObject *const connection_object);
  265. void ConnectionObjectSetConnectionTimeoutMultiplier(
  266. CipConnectionObject *const connection_object,
  267. const CipUsint
  268. connection_timeout_multiplier);
  269. void ConnectionObjectResetInactivityWatchdogTimerValue(
  270. CipConnectionObject *const connection_object);
  271. void ConnectionObjectResetLastPackageInactivityTimerValue(
  272. CipConnectionObject *const connection_object);
  273. CipUint ConnectionObjectGetConnectionSerialNumber(
  274. const CipConnectionObject *const connection_object);
  275. void ConnectionObjectSetConnectionSerialNumber(
  276. CipConnectionObject *connection_object,
  277. const CipUint connection_serial_number);
  278. CipUint ConnectionObjectGetOriginatorVendorId(
  279. const CipConnectionObject *const connection_object);
  280. void ConnectionObjectSetOriginatorVendorId(
  281. CipConnectionObject *connection_object,
  282. const CipUint vendor_id);
  283. CipUdint ConnectionObjectGetOriginatorSerialNumber(
  284. const CipConnectionObject *const connection_object);
  285. void ConnectionObjectSetOriginatorSerialNumber(
  286. CipConnectionObject *connection_object,
  287. CipUdint originator_serial_number);
  288. void ConnectionObjectGetConnectionNumber(
  289. CipConnectionObject *connection_object,
  290. const CipUint connection_number);
  291. void ConnectionObjectSetConnectionNumber(
  292. CipConnectionObject *connection_object);
  293. CipUint GenerateRandomConnectionNumber(void);
  294. CipUdint ConnectionObjectGetOToTRequestedPacketInterval(
  295. const CipConnectionObject *const connection_object);
  296. void ConnectionObjectSetOToTRequestedPacketInterval(
  297. CipConnectionObject *connection_object,
  298. const CipUdint requested_packet_interval);
  299. bool ConnectionObjectIsOToTRedundantOwner(
  300. const CipConnectionObject *const connection_object);
  301. ConnectionObjectConnectionType ConnectionObjectGetOToTConnectionType(
  302. const CipConnectionObject *const connection_object);
  303. ConnectionObjectPriority ConnectionObjectGetOToTPriority(
  304. const CipConnectionObject *const connection_object);
  305. ConnectionObjectConnectionSizeType ConnectionObjectGetOToTConnectionSizeType(
  306. const CipConnectionObject *const connection_object);
  307. size_t ConnectionObjectGetOToTConnectionSize(
  308. const CipConnectionObject *const connection_object);
  309. /* T to O */
  310. CipUdint ConnectionObjectGetTToORequestedPacketInterval(
  311. const CipConnectionObject *const connection_object);
  312. void ConnectionObjectSetTToORequestedPacketInterval(
  313. CipConnectionObject *connection_object,
  314. const CipUdint requested_packet_interval);
  315. void ConnectionObjectSetTToONetworkConnectionParameters(
  316. CipConnectionObject *connection_object,
  317. const CipDword connection_parameters);
  318. void ConnectionObjectSetOToTNetworkConnectionParameters(
  319. CipConnectionObject *connection_object,
  320. const CipDword connection_parameters);
  321. bool ConnectionObjectIsTToORedundantOwner(
  322. const CipConnectionObject *const connection_object);
  323. ConnectionObjectConnectionType ConnectionObjectGetTToOConnectionType(
  324. const CipConnectionObject *const connection_object);
  325. ConnectionObjectPriority ConnectionObjectGetTToOPriority(
  326. const CipConnectionObject *const connection_object);
  327. ConnectionObjectConnectionSizeType ConnectionObjectGetTToOConnectionSizeType(
  328. const CipConnectionObject *const connection_object);
  329. size_t ConnectionObjectGetTToOConnectionSize(
  330. const CipConnectionObject *const connection_object);
  331. /** @brief Copy the given connection data from source to destination
  332. *
  333. * @param destination Destination of the copy operation
  334. * @param source Source of the copy operation
  335. */
  336. void ConnectionObjectDeepCopy(CipConnectionObject *RESTRICT destination,
  337. const CipConnectionObject *RESTRICT const source);
  338. void ConnectionObjectResetProductionInhibitTimer(
  339. CipConnectionObject *const connection_object);
  340. /** @brief Generate the ConnectionIDs and set the general configuration
  341. * parameter in the given connection object.
  342. *
  343. * @param connection_object pointer to the connection object that should be set
  344. * up.
  345. */
  346. void ConnectionObjectGeneralConfiguration(
  347. CipConnectionObject *const connection_object);
  348. bool ConnectionObjectIsTypeNonLOIOConnection(
  349. const CipConnectionObject *const connection_object);
  350. bool ConnectionObjectIsTypeIOConnection(
  351. const CipConnectionObject *const connection_object);
  352. bool ConnectionObjectEqualOriginator(const CipConnectionObject *const object1,
  353. const CipConnectionObject *const object2);
  354. bool EqualConnectionTriad(const CipConnectionObject *const object1,
  355. const CipConnectionObject *const object2);
  356. bool CipConnectionObjectOriginatorHasSameIP(
  357. const CipConnectionObject *const connection_object,
  358. const struct sockaddr *const originator_address);
  359. #endif /* SRC_CIP_CIPCONNECTIONOBJECT_H_ */