OpENer - Open Source EtherNet/IP(TM) I/O Target Stack  2.1
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
cipconnectionobject.c
Go to the documentation of this file.
1 /*******************************************************************************
2  * Copyright (c) 2017, Rockwell Automation, Inc.
3  * All rights reserved.
4  *
5  ******************************************************************************/
6 
7 #include "cipconnectionobject.h"
8 
9 #include "endianconv.h"
10 #include "trace.h"
11 #include "cipconnectionmanager.h"
12 
13 #define CIP_CONNECTION_OBJECT_STATE_NON_EXISTENT 0U
14 #define CIP_CONNECTION_OBJECT_STATE_CONFIGURING 1U
15 #define CIP_CONNECTION_OBJECT_STATE_WAITING_FOR_CONNECTION_ID 2U
16 #define CIP_CONNECTION_OBJECT_STATE_ESTABLISHED 3U
17 #define CIP_CONNECTION_OBJECT_STATE_TIMEOUT 4U
18 #define CIP_CONNECTION_OBJECT_STATE_DEFERRED_DELETE 5U
19 #define CIP_CONNECTION_OBJECT_STATE_CLOSING 6U
20 
21 #define CIP_CONNECTION_OBJECT_INSTANCE_TYPE_EXPLICIT_MESSAGING 0
22 #define CIP_CONNECTION_OBJECT_INSTANCE_TYPE_IO 1
23 #define CIP_CONNECTION_OBJECT_INSTANCE_TYPE_CIP_BRIDGED 2
24 
25 #define CIP_CONNECTION_OBJECT_TRANSPORT_CLASS_TRIGGER_PRODUCTION_TRIGGER_CYCLIC ( \
26  0 << 4)
27 #define \
28  CIP_CONNECTION_OBJECT_TRANSPORT_CLASS_TRIGGER_PRODUCTION_TRIGGER_CHANGE_OF_STATE ( \
29  1 << 4)
30 #define \
31  CIP_CONNECTION_OBJECT_TRANSPORT_CLASS_TRIGGER_PRODUCTION_TRIGGER_APPLICATION_OBJECT ( \
32  2 << 4)
33 
34 #define CIP_CONNECTION_OBJECT_TRANSPORT_CLASS_TRIGGER_TRANSPORT_CLASS_0 0
35 #define CIP_CONNECTION_OBJECT_TRANSPORT_CLASS_TRIGGER_TRANSPORT_CLASS_1 1
36 #define CIP_CONNECTION_OBJECT_TRANSPORT_CLASS_TRIGGER_TRANSPORT_CLASS_2 2
37 #define CIP_CONNECTION_OBJECT_TRANSPORT_CLASS_TRIGGER_TRANSPORT_CLASS_3 3
38 
39 #define CIP_CONNECTION_OBJECT_WATCHDOG_TIMEOUT_ACTION_TRANSITION_TO_TIMED_OUT 0
40 #define CIP_CONNECTION_OBJECT_WATCHDOG_TIMEOUT_ACTION_AUTO_DELETE 1
41 #define CIP_CONNECTION_OBJECT_WATCHDOG_TIMEOUT_ACTION_AUTO_RESET 2
42 #define CIP_CONNECTION_OBJECT_WATCHDOG_TIMEOUT_ACTION_DEFERRED_DELETE 3
43 
44 #define CIP_CONNECTION_OBJECT_CONNECTION_TYPE_NULL 0
45 #define CIP_CONNECTION_OBJECT_CONNECTION_TYPE_MULTICAST (1 << 13)
46 #define CIP_CONNECTION_OBJECT_CONNECTION_TYPE_POINT_TO_POINT (1 << 14)
47 
48 #define CIP_CONNECTION_OBJECT_PRIORITY_LOW 0
49 #define CIP_CONNECTION_OBJECT_PRIORITY_HIGH (1 << 10)
50 #define CIP_CONNECTION_OBJECT_PRIORITY_SCHEDULED (1 << 11)
51 #define CIP_CONNECTION_OBJECT_PRIORITY_URGENT (3 << 10)
52 
54 
58 
60  enum {kNodesAmount = OPENER_CIP_NUM_EXPLICIT_CONNS +
64  static DoublyLinkedListNode nodes[kNodesAmount] = {0};
65  for(size_t i = 0; i < kNodesAmount; ++i) {
66  if(nodes[i].previous == NULL && nodes[i].next == NULL && nodes[i].data ==
67  NULL) {
68  return &nodes[i];
69  }
70  }
71  return NULL;
72 }
73 
75 
76  if(NULL != node) {
77  if(NULL != *node) {
78  memset( *node, 0, sizeof(DoublyLinkedListNode) );
79  *node = NULL;
80  } else {
81  OPENER_TRACE_ERR("Attempt to delete NULL pointer to node\n");
82  }
83  OPENER_TRACE_ERR("Attempt to provide a NULL pointer to node pointer\n");
84  }
85 
86 }
87 
88 
89 /* Private methods declaration */
91  const CipConnectionObject *const connection_object);
92 
94  CipConnectionObject *const connection_object);
95 /* End private methods declaration */
96 
98  CipConnectionObject *const connection_object) {
99  memset( connection_object, 0, sizeof(*connection_object) );
100  ConnectionObjectSetState(connection_object,
102  connection_object->socket[0] = kEipInvalidSocket;
103  connection_object->socket[1] = kEipInvalidSocket;
104 }
105 
107  assert(false); /* NOT IMLEMENTED */
108  return NULL;
109 }
110 
112  const CipOctet **message,
113  CipConnectionObject *const connection_object) {
114  /* For unconnected send - can be ignored by targets, and is ignored here */
115  CipByte priority_timetick = GetSintFromMessage(message);
116  CipUsint timeout_ticks = GetSintFromMessage(message);
117 
118  /* O_to_T Conn ID */
120  GetDintFromMessage(message) );
121  /* T_to_O Conn ID */
123  GetDintFromMessage(message) );
124 
126  GetIntFromMessage(message) );
127  ConnectionObjectSetOriginatorVendorId(connection_object,
128  GetIntFromMessage(message) );
130  GetDintFromMessage(message) );
131 
132  /* keep it to none existent till the setup is done this eases error handling and
133  * the state changes within the forward open request can not be detected from
134  * the application or from outside (reason we are single threaded)
135  * */
136  ConnectionObjectSetState(connection_object,
138  connection_object->sequence_count_producing = 0; /* set the sequence count to zero */
139 
142  message) );
143 
144  MoveMessageNOctets(3, message); /* 3 bytes reserved */
145 
146  /* the requested packet interval parameter needs to be a multiple of TIMERTICK from the header file */
148  "ForwardOpen: ConConnID %" PRIu32 ", ProdConnID %" PRIu32
149  ", ConnSerNo %u\n",
150  connection_object->cip_consumed_connection_id,
151  connection_object->cip_produced_connection_id,
152  connection_object->connection_serial_number);
153 
156  message) );
157 
159 
160  //TODO: introduce setter function
162  message);
163 
165  GetDintFromMessage(message) );
166 
167  ConnectionObjectSetExpectedPacketRate(connection_object);
168 
170  message);
171 
172  connection_object->transport_class_trigger = GetSintFromMessage(message);
173 }
174 
176  const CipConnectionObject *const connection_object) {
178  switch (connection_object->state) {
181  break;
184  break;
187  break;
190  break;
192  new_state = kConnectionObjectStateTimedOut;
193  break;
196  break;
198  new_state = kConnectionObjectStateClosing;
199  break;
200  default:
201  new_state = kConnectionObjectStateInvalid;
202  break;
203  }
204  return new_state;
205 }
206 
207 void ConnectionObjectSetState(CipConnectionObject *const connection_object,
208  const ConnectionObjectState state) {
209  switch (state) {
211  connection_object->state =
213  break;
215  connection_object->state =
217  break;
219  connection_object->state =
221  break;
223  connection_object->state =
225  break;
227  connection_object->state =
229  break;
231  connection_object->state =
233  break;
235  connection_object->state =
237  break;
238  default:
239  OPENER_ASSERT(false) /* Never get here */
240  break;
241  }
242 }
243 
245  const CipConnectionObject *const connection_object) {
246  return connection_object->instance_type;
247 // switch (connection_object->instance_type) {
248 // case CIP_CONNECTION_OBJECT_INSTANCE_TYPE_EXPLICIT_MESSAGING:
249 // return kConnectionObjectInstanceTypeExplicitMessaging;
250 // break;
251 // case CIP_CONNECTION_OBJECT_INSTANCE_TYPE_IO:
252 // return kConnectionObjectInstanceTypeIO;
253 // break;
254 // case CIP_CONNECTION_OBJECT_INSTANCE_TYPE_CIP_BRIDGED:
255 // return kConnectionObjectInstanceTypeCipBridged;
256 // break;
257 // default:
258 // return kConnectionObjectInstanceTypeInvalid;
259 // }
260 }
261 
263  CipConnectionObject *const connection_object,
264  const ConnectionObjectInstanceType instance_type) {
265  connection_object->instance_type = instance_type;
266 }
267 
269  const CipConnectionObject *const connection_object) {
271  switch (connection_object->instance_type) {
274  break;
280  break;
283  break;
284  default:
285  OPENER_ASSERT(false) /* This is a fault case */
286  instance_type = kConnectionObjectInstanceTypeInvalid;
287  break;
288  }
289  return instance_type;
290 }
291 
293  const CipConnectionObject *const connection_object) {
294  switch(connection_object->instance_type) {
298  return true;
299  default: return false;
300  }
301  return false;
302 }
303 
305  const CipConnectionObject *const connection_object) {
306  switch(connection_object->instance_type) {
311  return true;
312  default: return false;
313  }
314  return false;
315 }
316 
319  const CipConnectionObject *const connection_object) {
320  const CipByte TransportClassTriggerDirectionMask = 0x80;
321  return (connection_object->transport_class_trigger &
322  TransportClassTriggerDirectionMask) ==
323  TransportClassTriggerDirectionMask ?
326 }
327 
330  const CipConnectionObject *const connection_object) {
331  const CipByte kTransportClassTriggerProductionTriggerMask = 0x70;
332 
334  switch ( (connection_object->transport_class_trigger) &
335  kTransportClassTriggerProductionTriggerMask ) {
336  case
339  break;
340  case
343  break;
344  case
347  break;
348  default:
350  break;
351  }
352  return production_trigger;
353 }
354 
357  const CipConnectionObject *const connection_object) {
358  const CipByte kTransportClassTriggerTransportClassMask = 0x0F;
359 
361  switch ( (connection_object->transport_class_trigger) &
362  kTransportClassTriggerTransportClassMask ) {
365  break;
368  break;
371  break;
374  break;
375  default:
377  }
378  return transport_class_trigger;
379 }
380 
382  const CipConnectionObject *const connection_object) {
383  return connection_object->produced_connection_size;
384 }
385 
387  CipConnectionObject *const connection_object,
388  const CipUint
389  produced_connection_size) {
390  connection_object->produced_connection_size = produced_connection_size;
391 }
392 
394  const CipConnectionObject *const connection_object) {
395  return connection_object->consumed_connection_size;
396 }
397 
399  CipConnectionObject *const connection_object,
400  const CipUint consumed_connection_size) {
401  connection_object->consumed_connection_size = consumed_connection_size;
402 }
403 
405  const CipConnectionObject *const connection_object) {
406  return connection_object->expected_packet_rate;
407 }
408 
410  const CipConnectionObject *const connection_object) {
411  CipUdint remainder_to_resolution =
412  (connection_object->t_to_o_requested_packet_interval) %
413  (kOpenerTimerTickInMilliSeconds * 1000);
414  if( 0 == remainder_to_resolution ) { /* Value can be represented in multiples of the timer resolution */
415  return (CipUint)(connection_object->t_to_o_requested_packet_interval /
416  1000);
417  }
418  else{
419  return (CipUint)(connection_object->t_to_o_requested_packet_interval /
420  1000 - remainder_to_resolution / 1000);
421  }
422 }
423 
425  CipConnectionObject *const connection_object) {
426  CipUdint remainder_to_resolution =
427  (connection_object->t_to_o_requested_packet_interval) %
428  (kOpenerTimerTickInMilliSeconds * 1000);
429  if( 0 == remainder_to_resolution ) { /* Value can be represented in multiples of the timer resolution */
430  connection_object->expected_packet_rate =
431  connection_object->t_to_o_requested_packet_interval / 1000;
432  }
433  else{
434  connection_object->expected_packet_rate =
435  connection_object->t_to_o_requested_packet_interval / 1000 +
436  ( (CipUdint)
437  kOpenerTimerTickInMilliSeconds - remainder_to_resolution / 1000 );
438  }
439 }
440 
442  const CipConnectionObject *const connection_object) {
443  return connection_object->cip_produced_connection_id;
444 }
445 
447  CipConnectionObject *const connection_object,
448  const CipUdint
449  cip_produced_connection_id) {
450  connection_object->cip_produced_connection_id = cip_produced_connection_id;
451 }
452 
454  const CipConnectionObject *const connection_object) {
455  return connection_object->cip_consumed_connection_id;
456 }
457 
459  CipConnectionObject *const connection_object,
460  const CipUdint
461  cip_consumed_connection_id) {
462  connection_object->cip_consumed_connection_id = cip_consumed_connection_id;
463 }
464 
466  const CipConnectionObject *const connection_object) {
468  switch (connection_object->watchdog_timeout_action) {
471  break;
474  break;
477  break;
480  break;
481  default:
483  break;
484  }
485  return timeout_action;
486 }
487 
489  CipConnectionObject *const connection_object,
490  const CipUsint
491  watchdog_timeout_action) {
492  switch (watchdog_timeout_action) {
494  connection_object->watchdog_timeout_action =
496  break;
498  connection_object->watchdog_timeout_action =
500  break;
502  connection_object->watchdog_timeout_action =
504  break;
506  connection_object->watchdog_timeout_action =
508  break;
509  default:
510  connection_object->watchdog_timeout_action =
512  break;
513  }
514 }
515 
517  const CipConnectionObject *const connection_object) {
518  return connection_object->produced_connection_path_length;
519 }
520 
522  CipConnectionObject *const connection_object,
523  const CipUint
524  produced_connection_path_length) {
525  connection_object->produced_connection_path_length =
526  produced_connection_path_length;
527 }
528 
530  const CipConnectionObject *const connection_object) {
531  return connection_object->consumed_connection_path_length;
532 }
533 
535  CipConnectionObject *const connection_object,
536  const CipUint
537  consumed_connection_path_length) {
538  connection_object->consumed_connection_path_length =
539  consumed_connection_path_length;
540 }
541 
543  const CipConnectionObject *const connection_object) {
544  return connection_object->production_inhibit_time;
545 }
546 
548  CipConnectionObject *const connection_object,
549  const CipUint
550  production_inhibit_time) {
551  connection_object->production_inhibit_time = production_inhibit_time;
552 }
553 
554 /*setup the preconsumption timer: max(ConnectionTimeoutMultiplier * ExpectedPacketRate, 10s) */
556  CipConnectionObject *const connection_object) {
557  const uint64_t kMinimumInitialTimeoutValue = 10000;
558  const uint64_t calculated_timeout_value =
560  connection_object);
561  connection_object->inactivity_watchdog_timer =
562  (calculated_timeout_value >
563  kMinimumInitialTimeoutValue) ? calculated_timeout_value :
564  kMinimumInitialTimeoutValue;
565 }
566 
568  CipConnectionObject *const connection_object) {
569  connection_object->inactivity_watchdog_timer =
571  connection_object);
572 }
573 
575  CipConnectionObject *const connection_object) {
576  connection_object->last_package_watchdog_timer =
578  connection_object);
579 }
580 
582  const CipConnectionObject *const connection_object) {
583  return ( ( (uint64_t)(connection_object->o_to_t_requested_packet_interval) /
584  (uint64_t)1000 ) <<
585  (2 + connection_object->connection_timeout_multiplier) );
586 }
587 
588 
589 
591  const CipConnectionObject *const connection_object) {
592  return connection_object->connection_serial_number;
593 }
594 
596  CipConnectionObject *connection_object,
597  const CipUint connection_serial_number) {
598  connection_object->connection_serial_number = connection_serial_number;
599 }
600 
602  const CipConnectionObject *const connection_object) {
603  return connection_object->originator_vendor_id;
604 }
605 
607  CipConnectionObject *connection_object,
608  const CipUint vendor_id) {
609  connection_object->originator_vendor_id = vendor_id;
610 }
611 
613  const CipConnectionObject *const connection_object) {
614  return connection_object->originator_serial_number;
615 }
616 
618  CipConnectionObject *connection_object,
619  CipUdint originator_serial_number) {
620  connection_object->originator_serial_number = originator_serial_number;
621 }
622 
624  const CipConnectionObject *const connection_object) {
625  return connection_object->connection_timeout_multiplier;
626 }
627 
629  CipConnectionObject *connection_object,
630  CipUsint connection_timeout_multiplier) {
631  connection_object->connection_timeout_multiplier =
632  connection_timeout_multiplier;
633 }
634 
636  const CipConnectionObject *const connection_object) {
637  return connection_object->o_to_t_requested_packet_interval;
638 }
639 
641  CipConnectionObject *connection_object,
642  const CipUdint requested_packet_interval) {
643  connection_object->o_to_t_requested_packet_interval =
644  requested_packet_interval;
645 }
646 
648  const CipConnectionObject *const connection_object) {
649  return connection_object->t_to_o_requested_packet_interval;
650 }
651 
653  CipConnectionObject *connection_object,
654  const CipUdint requested_packet_interval) {
655  connection_object->t_to_o_requested_packet_interval =
656  requested_packet_interval;
657 }
658 
660  const CipConnectionObject *const connection_object) {
661  const CipWord kOwnerMask = 0x80;
662  return kOwnerMask & connection_object->o_to_t_network_connection_parameters;
663 }
664 
666  const CipConnectionObject *const connection_object) {
667  const CipWord kOwnerMask = 0x80;
668  return kOwnerMask & connection_object->t_to_o_network_connection_parameters;
669 }
670 
672  const CipWord connection_parameters) {
673  const CipWord kConnectionTypeMask = 3 << 13;
674  switch(connection_parameters & kConnectionTypeMask) {
682  }
683 }
684 
686  const CipConnectionObject *const connection_object) {
688  connection_object->o_to_t_network_connection_parameters);
689 }
690 
692  const CipConnectionObject *const connection_object) {
694  connection_object->t_to_o_network_connection_parameters);
695 }
696 
698  const CipWord connection_parameters) {
699  const CipWord kPriorityMask = 3 << 10;
701  switch(connection_parameters & kPriorityMask) {
710  default: OPENER_ASSERT(false) /* Not possible to get here! */
712  break;
713  }
714  return result;
715 }
716 
718  const CipConnectionObject *const connection_object) {
720  connection_object->o_to_t_network_connection_parameters);
721 }
722 
724  const CipConnectionObject *const connection_object) {
726  connection_object->t_to_o_network_connection_parameters);
727 }
728 
729 
731  const CipWord connection_parameters) {
732  const CipWord kConnectionSizeTypeMask = 1 << 9;
733  if(connection_parameters & kConnectionSizeTypeMask) {
735  } else {
737  }
738 }
739 
741  const CipConnectionObject *const connection_object) {
743  connection_object->o_to_t_network_connection_parameters);
744 }
745 
747  const CipConnectionObject *const connection_object) {
749  connection_object->t_to_o_network_connection_parameters);
750 }
751 
752 size_t ConnectionObjectGetConnectionSize(const CipWord connection_parameters) {
753  const CipWord kConnectionSizeMask = 0x01FF;
754  return connection_parameters & kConnectionSizeMask;
755 }
756 
758  const CipConnectionObject *const connection_object) {
760  connection_object->o_to_t_network_connection_parameters);
761 }
762 
764  const CipConnectionObject *const connection_object) {
766  connection_object->t_to_o_network_connection_parameters);
767 }
768 
770  CipConnectionObject *RESTRICT destination,
771  const CipConnectionObject *RESTRICT const source
772  ) {
773  memcpy( destination, source, sizeof(CipConnectionObject) );
774 }
775 
777  CipConnectionObject *const connection_object) {
778  connection_object->eip_level_sequence_count_producing = 0;
779  connection_object->sequence_count_producing = 0;
780  connection_object->eip_level_sequence_count_consuming = 0;
781  connection_object->sequence_count_consuming = 0;
782 }
783 
785  CipConnectionObject *const connection_object) {
786  connection_object->production_inhibit_timer =
787  connection_object->production_inhibit_time;
788 }
789 
791  CipConnectionObject *const connection_object) {
792 
793  connection_object->socket[0] = kEipInvalidSocket;
794  connection_object->socket[1] = kEipInvalidSocket;
795 
797  == ConnectionObjectGetOToTConnectionType(connection_object) ) {
798  /* if we have a point to point connection for the O to T direction
799  * the target shall choose the connection ID.
800  */
802  GetConnectionId() );
803  }
804 
806  == ConnectionObjectGetTToOConnectionType(connection_object) ) {
807  /* if we have a multi-cast connection for the T to O direction the
808  * target shall choose the connection ID.
809  */
811  GetConnectionId() );
812  }
813 
814  ConnectionObjectResetSequenceCounts(connection_object);
815 
817  kConnectionObjectWatchdogTimeoutActionInvalid); /* Correct value not know at this point */
818 
820 
821  connection_object->transmission_trigger_timer = 0;
822 }
823 
825  const CipConnectionObject *const object2) {
826  if ( (object1->originator_vendor_id
827  == object2->originator_vendor_id)
828  && (object1->originator_serial_number
829  == object2->originator_serial_number) ) {
830  return true;
831  }
832  return false;
833 }
834 
835 bool EqualConnectionTriad(const CipConnectionObject *const object1,
836  const CipConnectionObject *const object2) {
837  if ( (object1->connection_serial_number
838  == object2->connection_serial_number)
839  && (object1->originator_vendor_id
840  == object2->originator_vendor_id)
841  && (object1->originator_serial_number
842  == object2->originator_serial_number) ) {
843  return true;
844  }
845  return false;
846 }
847 
849  const CipConnectionObject *const connection_object,
850  const struct sockaddr *const originator_address) {
851  return ( (struct sockaddr_in *) originator_address )->sin_addr.s_addr ==
852  connection_object->originator_address.sin_addr.s_addr;
853 }
ConnectionObjectTransportClassTriggerDirection ConnectionObjectGetTransportClassTriggerDirection(const CipConnectionObject *const connection_object)
ConnectionObjectConnectionType
CipUint ConnectionObjectGetConnectionSerialNumber(const CipConnectionObject *const connection_object)
bool ConnectionObjectIsTypeNonLOIOConnection(const CipConnectionObject *const connection_object)
CipConnectionObject explicit_connection_object_pool[OPENER_CIP_NUM_EXPLICIT_CONNS]
Array of the available explicit connections.
CipUint ConnectionObjectGetConsumedConnectionPathLength(const CipConnectionObject *const connection_object)
#define CIP_CONNECTION_OBJECT_STATE_WAITING_FOR_CONNECTION_ID
ConnectionObjectState
void CipConnectionObjectListArrayFree(DoublyLinkedListNode **node)
bool ConnectionObjectIsTypeIOConnection(const CipConnectionObject *const connection_object)
Tracing infrastructure for OpENer.
size_t ConnectionObjectGetConnectionSize(const CipWord connection_parameters)
#define CIP_CONNECTION_OBJECT_PRIORITY_SCHEDULED
CipUint ConnectionObjectGetProducedConnectionSize(const CipConnectionObject *const connection_object)
bool ConnectionObjectIsTToORedundantOwner(const CipConnectionObject *const connection_object)
#define CIP_CONNECTION_OBJECT_TRANSPORT_CLASS_TRIGGER_TRANSPORT_CLASS_0
#define OPENER_CIP_NUM_LISTEN_ONLY_CONNS
Define the number of supported listen only connections. Each of these connections has to be configure...
void ConnectionObjectSetCipProducedConnectionID(CipConnectionObject *const connection_object, const CipUdint cip_produced_connection_id)
CipUint ConnectionObjectGetExpectedPacketRate(const CipConnectionObject *const connection_object)
void ConnectionObjectSetWatchdogTimeoutAction(CipConnectionObject *const connection_object, const CipUsint watchdog_timeout_action)
EipUint32 eip_level_sequence_count_producing
void ConnectionObjectResetProductionInhibitTimer(CipConnectionObject *const connection_object)
bool CipConnectionObjectOriginatorHasSameIP(const CipConnectionObject *const connection_object, const struct sockaddr *const originator_address)
void ConnectionObjectSetInitialInactivityWatchdogTimerValue(CipConnectionObject *const connection_object)
#define OPENER_ASSERT(assertion)
CipUdint ConnectionObjectGetCipProducedConnectionID(const CipConnectionObject *const connection_object)
#define CIP_CONNECTION_OBJECT_STATE_CONFIGURING
CipUdint ConnectionObjectGetCipConsumedConnectionID(const CipConnectionObject *const connection_object)
void ConnectionObjectSetConsumedConnectionPathLength(CipConnectionObject *const connection_object, const CipUint consumed_connection_path_length)
ConnectionObjectConnectionType ConnectionObjectGetTToOConnectionType(const CipConnectionObject *const connection_object)
EipUint32 GetDintFromMessage(const EipUint8 **const buffer)
Reads EIP_UINT32 from *buffer and converts little endian to host.
Definition: endianconv.c:83
ConnectionObjectConnectionSizeType ConnectionObjectGetConnectionSizeType(const CipWord connection_parameters)
void ConnectionObjectSetProductionInhibitTime(CipConnectionObject *const connection_object, const CipUint production_inhibit_time)
ConnectionObjectWatchdogTimeoutAction
Possible values for the watch dog time out action of a connection.
void ConnectionObjectResetInactivityWatchdogTimerValue(CipConnectionObject *const connection_object)
CipUsint ConnectionObjectGetConnectionTimeoutMultiplier(const CipConnectionObject *const connection_object)
#define CIP_CONNECTION_OBJECT_TRANSPORT_CLASS_TRIGGER_PRODUCTION_TRIGGER_CYCLIC
Responsible for Endianess conversion.
#define OPENER_TRACE_ERR(...)
Definition: trace.h:86
EipUint8 GetSintFromMessage(const EipUint8 **const buffer)
Reads EIP_UINT8 from *buffer and converts little endian to host.
Definition: endianconv.c:29
#define CIP_CONNECTION_OBJECT_STATE_NON_EXISTENT
#define OPENER_CIP_NUM_INPUT_ONLY_CONNS
Define the number of supported input only connections. Each of these connections has to be configured...
void ConnectionObjectResetLastPackageInactivityTimerValue(CipConnectionObject *const connection_object)
ConnectionObjectConnectionSizeType
void ConnectionObjectSetInstanceType(CipConnectionObject *const connection_object, const ConnectionObjectInstanceType instance_type)
#define CIP_CONNECTION_OBJECT_TRANSPORT_CLASS_TRIGGER_PRODUCTION_TRIGGER_CHANGE_OF_STATE
CipUint ConnectionObjectGetProducedConnectionPathLength(const CipConnectionObject *const connection_object)
CipUdint ConnectionObjectGetTToORequestedPacketInterval(const CipConnectionObject *const connection_object)
CipConnectionObject * CipConnectionObjectCreate(const CipOctet *message)
Array allocator.
#define CIP_CONNECTION_OBJECT_INSTANCE_TYPE_IO
void ConnectionObjectInitializeEmpty(CipConnectionObject *const connection_object)
void ConnectionObjectDeepCopy(CipConnectionObject *RESTRICT destination, const CipConnectionObject *RESTRICT const source)
Copy the given connection data from source to destination.
void ConnectionObjectSetCipConsumedConnectionID(CipConnectionObject *const connection_object, const CipUdint cip_consumed_connection_id)
ConnectionObjectWatchdogTimeoutAction ConnectionObjectGetWatchdogTimeoutAction(const CipConnectionObject *const connection_object)
uint8_t CipOctet
Data types as defined in the CIP Specification Vol 1 Appendix C.
Definition: typedefs.h:41
ConnectionObjectPriority ConnectionObjectGetTToOPriority(const CipConnectionObject *const connection_object)
void ConnectionObjectSetTToORequestedPacketInterval(CipConnectionObject *connection_object, const CipUdint requested_packet_interval)
void ConnectionObjectSetConsumedConnectionSize(CipConnectionObject *const connection_object, const CipUint consumed_connection_size)
bool ConnectionObjectEqualOriginator(const CipConnectionObject *const object1, const CipConnectionObject *const object2)
CipUsint ConnectionObjectGetInstanceTypeForAttribute(const CipConnectionObject *const connection_object)
ConnectionObjectInstanceType
#define CIP_CONNECTION_OBJECT_INSTANCE_TYPE_EXPLICIT_MESSAGING
ConnectionObjectTransportClassTriggerTransportClass
#define CIP_CONNECTION_OBJECT_INSTANCE_TYPE_CIP_BRIDGED
uint8_t CipByte
Definition: typedefs.h:43
ConnectionObjectConnectionType ConnectionObjectGetOToTConnectionType(const CipConnectionObject *const connection_object)
#define CIP_CONNECTION_OBJECT_STATE_TIMEOUT
void ConnectionObjectResetSequenceCounts(CipConnectionObject *const connection_object)
void ConnectionObjectInitializeFromMessage(const CipOctet **message, CipConnectionObject *const connection_object)
#define OPENER_TRACE_INFO(...)
Definition: trace.h:89
int MoveMessageNOctets(const int amount_of_bytes_moved, const CipOctet **message_runner)
Definition: endianconv.c:258
ConnectionObjectConnectionType ConnectionObjectGetConnectionType(const CipWord connection_parameters)
ConnectionObjectConnectionSizeType ConnectionObjectGetOToTConnectionSizeType(const CipConnectionObject *const connection_object)
CipUint ConnectionObjectGetProductionInhibitTime(const CipConnectionObject *const connection_object)
CipUint ConnectionObjectGetOriginatorVendorId(const CipConnectionObject *const connection_object)
void ConnectionObjectSetOToTRequestedPacketInterval(CipConnectionObject *connection_object, const CipUdint requested_packet_interval)
CipUdint ConnectionObjectGetOriginatorSerialNumber(const CipConnectionObject *const connection_object)
void ConnectionObjectSetExpectedPacketRate(CipConnectionObject *const connection_object)
Sets the expected packet rate according to the rules of the CIP specification.
uint8_t CipUsint
Definition: typedefs.h:46
#define OPENER_CIP_NUM_EXLUSIVE_OWNER_CONNS
Define the number of supported exclusive owner connections. Each of these connections has to be confi...
ConnectionObjectState ConnectionObjectGetState(const CipConnectionObject *const connection_object)
#define CIP_CONNECTION_OBJECT_PRIORITY_URGENT
CipUint ConnectionObjectGetConsumedConnectionSize(const CipConnectionObject *const connection_object)
#define CIP_CONNECTION_OBJECT_CONNECTION_TYPE_POINT_TO_POINT
#define CIP_CONNECTION_OBJECT_CONNECTION_TYPE_NULL
#define CIP_CONNECTION_OBJECT_CONNECTION_TYPE_MULTICAST
#define OPENER_CIP_NUM_EXPLICIT_CONNS
Define the number of supported explicit connections. According to ODVA's PUB 70 this number should be...
void ConnectionObjectSetProducedConnectionPathLength(CipConnectionObject *const connection_object, const CipUint produced_connection_path_length)
ConnectionObjectPriority ConnectionObjectGetPriority(const CipWord connection_parameters)
CipUdint ConnectionObjectGetOToTRequestedPacketInterval(const CipConnectionObject *const connection_object)
#define CIP_CONNECTION_OBJECT_WATCHDOG_TIMEOUT_ACTION_AUTO_DELETE
#define CIP_CONNECTION_OBJECT_TRANSPORT_CLASS_TRIGGER_TRANSPORT_CLASS_1
#define CIP_CONNECTION_OBJECT_PRIORITY_HIGH
#define CIP_CONNECTION_OBJECT_WATCHDOG_TIMEOUT_ACTION_DEFERRED_DELETE
CipWord o_to_t_network_connection_parameters
ConnectionObjectTransportClassTriggerDirection
ConnectionObjectPriority ConnectionObjectGetOToTPriority(const CipConnectionObject *const connection_object)
bool ConnectionObjectIsOToTRedundantOwner(const CipConnectionObject *const connection_object)
void ConnectionObjectSetConnectionTimeoutMultiplier(CipConnectionObject *connection_object, CipUsint connection_timeout_multiplier)
#define CIP_CONNECTION_OBJECT_STATE_CLOSING
uint64_t ConnectionObjectCalculateRegularInactivityWatchdogTimerValue(const CipConnectionObject *const connection_object)
ConnectionObjectPriority
void ConnectionObjectSetOriginatorVendorId(CipConnectionObject *connection_object, const CipUint vendor_id)
EipUint32 eip_level_sequence_count_consuming
#define CIP_CONNECTION_OBJECT_PRIORITY_LOW
#define CIP_CONNECTION_OBJECT_TRANSPORT_CLASS_TRIGGER_PRODUCTION_TRIGGER_APPLICATION_OBJECT
uint32_t CipUdint
Definition: typedefs.h:48
size_t ConnectionObjectGetOToTConnectionSize(const CipConnectionObject *const connection_object)
DoublyLinkedList connection_list
uint16_t CipUint
Definition: typedefs.h:47
ConnectionObjectTransportClassTriggerProductionTrigger
CipUint GetConnectionId(void)
Generate a new connection Id utilizing the Incarnation Id as described in the EIP specs...
#define CIP_CONNECTION_OBJECT_TRANSPORT_CLASS_TRIGGER_TRANSPORT_CLASS_3
EipUint16 GetIntFromMessage(const EipUint8 **const buffer)
Reads EIP_UINT16 from *buffer and converts little endian to host.
Definition: endianconv.c:57
ConnectionObjectTransportClassTriggerProductionTrigger ConnectionObjectGetTransportClassTriggerProductionTrigger(const CipConnectionObject *const connection_object)
void ConnectionObjectSetState(CipConnectionObject *const connection_object, const ConnectionObjectState state)
CipUint ConnectionObjectGetRequestedPacketInterval(const CipConnectionObject *const connection_object)
DoublyLinkedListNode * CipConnectionObjectListArrayAllocator()
#define CIP_CONNECTION_OBJECT_WATCHDOG_TIMEOUT_ACTION_AUTO_RESET
#define CIP_CONNECTION_OBJECT_STATE_DEFERRED_DELETE
CipWord t_to_o_network_connection_parameters
void ConnectionObjectSetProducedConnectionSize(CipConnectionObject *const connection_object, const CipUint produced_connection_size)
#define CIP_CONNECTION_OBJECT_STATE_ESTABLISHED
#define CIP_CONNECTION_OBJECT_WATCHDOG_TIMEOUT_ACTION_TRANSITION_TO_TIMED_OUT
#define CIP_CONNECTION_OBJECT_TRANSPORT_CLASS_TRIGGER_TRANSPORT_CLASS_2
uint16_t CipWord
Definition: typedefs.h:44
void ConnectionObjectSetConnectionSerialNumber(CipConnectionObject *connection_object, const CipUint connection_serial_number)
ConnectionObjectInstanceType ConnectionObjectGetInstanceType(const CipConnectionObject *const connection_object)
struct sockaddr_in originator_address
void ConnectionObjectSetOriginatorSerialNumber(CipConnectionObject *connection_object, CipUdint originator_serial_number)
size_t ConnectionObjectGetTToOConnectionSize(const CipConnectionObject *const connection_object)
void ConnectionObjectGeneralConfiguration(CipConnectionObject *const connection_object)
Generate the ConnectionIDs and set the general configuration parameter in the given connection object...
ConnectionObjectTransportClassTriggerTransportClass ConnectionObjectGetTransportClassTriggerTransportClass(const CipConnectionObject *const connection_object)
bool EqualConnectionTriad(const CipConnectionObject *const object1, const CipConnectionObject *const object2)
ConnectionObjectConnectionSizeType ConnectionObjectGetTToOConnectionSizeType(const CipConnectionObject *const connection_object)