소스 검색

Adds further functions to new connection object, removes some warnings

Signed-off-by: CapXilinx <melik-merkumians@acin.tuwien.ac.at>
CapXilinx 8 년 전
부모
커밋
a5b419ebfe

+ 315 - 104
source/src/cip/cipconnectionobject.c

@@ -41,6 +41,15 @@
 #define CIP_CONNECTION_OBJECT_WATCHDOG_TIMEOUT_ACTION_AUTO_RESET 2
 #define CIP_CONNECTION_OBJECT_WATCHDOG_TIMEOUT_ACTION_DEFERRED_DELETE 3
 
+#define CIP_CONNECTION_OBJECT_CONNECTION_TYPE_NULL 0
+#define CIP_CONNECTION_OBJECT_CONNECTION_TYPE_MULTICAST (1 << 13)
+#define CIP_CONNECTION_OBJECT_CONNECTION_TYPE_POINT_TO_POINT (1 << 14)
+
+#define CIP_CONNECTION_OBJECT_PRIORITY_LOW 0
+#define CIP_CONNECTION_OBJECT_PRIORITY_HIGH (1 << 13)
+#define CIP_CONNECTION_OBJECT_PRIORITY_SCHEDULED (1 << 14)
+#define CIP_CONNECTION_OBJECT_PRIORITY_URGENT (3 << 13)
+
 static CipConnectionObject explicit_connection_object_pool[
   OPENER_CIP_NUM_EXPLICIT_CONNS];
 static CipConnectionObject input_only_connection_object_pool[
@@ -50,6 +59,11 @@ static CipConnectionObject exclusive_owner_connection_object_pool[
 static CipConnectionObject listen_only_connection_object_pool[
   OPENER_CIP_NUM_LISTEN_ONLY_CONNS];
 
+/* Private methods declaration */
+uint64_t ConnectionObjectCalculateRegularInactivityWatchdogTimerValue(
+  const CipConnectionObject *connection_object);
+/* End private methods declaration */
+
 void ConnectionObjectInitializeEmpty(
   CipConnectionObject *const connection_object) {
   memset( connection_object, 0, sizeof(*connection_object) );
@@ -63,28 +77,28 @@ void ConnectionObjectInitializeFromMessage(
   const CipOctet *message,
   CipConnectionObject *const
   connection_object) {
+  /* For unconnected send - can be ignored by targets, and is ignored here */
   CipByte priority_timetick = GetSintFromMessage(&message);
   CipUsint timeout_ticks = GetSintFromMessage(&message);
+
   /* O_to_T Conn ID */
-  connection_object->cip_consumed_connection_id = GetDintFromMessage(
-    &message);
+  ConnectionObjectSetCipConsumedConnectionID(connection_object, GetDintFromMessage(&message));
   /* T_to_O Conn ID */
-  connection_object->cip_produced_connection_id = GetDintFromMessage(
-    &message);
-  connection_object->connection_serial_number = GetIntFromMessage(
-    &message);
-  connection_object->originator_vendor_id = GetIntFromMessage(
-    &message);
-  connection_object->originator_serial_number = GetDintFromMessage(
-    &message);
+  ConnectionObjectSetCipProducedConnectionID(connection_object, GetDintFromMessage(&message));
+
+  ConnectionObjectSetConnectionSerialNumber(connection_object, GetIntFromMessage(&message));
+  ConnectionObjectSetOriginatorVendorId(connection_object, GetIntFromMessage(&message));
+  ConnectionObjectSetOriginatorSerialNumber(connection_object, GetDintFromMessage(&message));
 
   /* keep it to none existent till the setup is done this eases error handling and
    * the state changes within the forward open request can not be detected from
-   * the application or from outside (reason we are single threaded)*/
-  connection_object->state = kConnectionObjectStateNonExistent;
+   * the application or from outside (reason we are single threaded)
+   * */
+  ConnectionObjectSetState(connection_object, kConnectionObjectStateNonExistent);
   connection_object->sequence_count_producing = 0; /* set the sequence count to zero */
 
-  CipUsint connection_timeout_multiplier = GetSintFromMessage(&message);
+  ConnectionObjectSetConnectionTimeoutMultiplier(connection_object, GetSintFromMessage(
+    &message));
 
   MoveMessageNOctets(3, &message); /* 3 bytes reserved */
 
@@ -96,83 +110,103 @@ void ConnectionObjectInitializeFromMessage(
     connection_object->cip_produced_connection_id,
     connection_object->connection_serial_number);
 
-  CipUdint o_to_t_requested_packet_interval = GetDintFromMessage(
-    &message);
-
-  CipWord o_to_t_network_connection_parameter = GetIntFromMessage(
-    &message);
-  CipUdint t_to_o_requested_packet_interval = GetDintFromMessage(
-    &message);
-
-  ConnectionObjectSetExpectedPacketRate(connection_object, t_to_o_requested_packet_interval);
-  EipUint32 temp = t_to_o_requested_packet_interval
-                   % (kOpenerTimerTickInMilliSeconds * 1000);
-  if (temp > 0) {
-    t_to_o_requested_packet_interval =
-      (EipUint32) ( t_to_o_requested_packet_interval
-                    / (kOpenerTimerTickInMilliSeconds * 1000) )
-      * (kOpenerTimerTickInMilliSeconds * 1000)
-      + (kOpenerTimerTickInMilliSeconds * 1000);
-  }
+  ConnectionObjectSetOToTRequestedPacketInterval(connection_object, GetDintFromMessage(
+    &message));
+
+  ConnectionObjectResetInactivityWatchdogTimerValue(connection_object);
 
-  CipWord t_to_o_network_connection_parameter = GetIntFromMessage(
-    &message);
+  //TODO: introduce setter function
+  connection_object->o_to_t_network_connection_parameters = GetIntFromMessage(&message);
 
-  CipByte transport_type_class_trigger = GetSintFromMessage(&message);
+  connection_object->t_to_o_requested_packet_interval = GetDintFromMessage(&message);
+
+  ConnectionObjectSetExpectedPacketRate(connection_object,
+      connection_object->t_to_o_requested_packet_interval);
+
+  connection_object->t_to_o_network_connection_parameters = GetIntFromMessage(&message);
+
+  connection_object->transport_class_trigger = GetSintFromMessage(&message);
 }
 
 ConnectionObjectState ConnectionObjectGetState(
   const CipConnectionObject *const connection_object) {
-  switch(connection_object->state) {
-    case CIP_CONNECTION_OBJECT_STATE_NON_EXISTENT: return
-        kConnectionObjectStateNonExistent; break;
-    case CIP_CONNECTION_OBJECT_STATE_CONFIGURING: return
-        kConnectionObjectStateConfiguring; break;
-    case CIP_CONNECTION_OBJECT_STATE_WAITING_FOR_CONNECTION_ID: return
-        kConnectionObjectStateWaitingForConnectionID; break;
-    case CIP_CONNECTION_OBJECT_STATE_ESTABLISHED: return
-        kConnectionObjectStateEstablished; break;
-    case CIP_CONNECTION_OBJECT_STATE_TIMEOUT: return
-        kConnectionObjectStateTimedOut; break;
-    case CIP_CONNECTION_OBJECT_STATE_DEFERRED_DELETE: return
-        kConnectionObjectStateDeferredDelete; break;
-    case CIP_CONNECTION_OBJECT_STATE_CLOSING: return
-        kConnectionObjectStateClosing; break;
-    default: return kConnectionObjectStateInvalid;
+  switch (connection_object->state) {
+    case CIP_CONNECTION_OBJECT_STATE_NON_EXISTENT:
+      return kConnectionObjectStateNonExistent;
+      break;
+    case CIP_CONNECTION_OBJECT_STATE_CONFIGURING:
+      return kConnectionObjectStateConfiguring;
+      break;
+    case CIP_CONNECTION_OBJECT_STATE_WAITING_FOR_CONNECTION_ID:
+      return kConnectionObjectStateWaitingForConnectionID;
+      break;
+    case CIP_CONNECTION_OBJECT_STATE_ESTABLISHED:
+      return kConnectionObjectStateEstablished;
+      break;
+    case CIP_CONNECTION_OBJECT_STATE_TIMEOUT:
+      return kConnectionObjectStateTimedOut;
+      break;
+    case CIP_CONNECTION_OBJECT_STATE_DEFERRED_DELETE:
+      return kConnectionObjectStateDeferredDelete;
+      break;
+    case CIP_CONNECTION_OBJECT_STATE_CLOSING:
+      return kConnectionObjectStateClosing;
+      break;
+    default:
+      return kConnectionObjectStateInvalid;
   }
 }
 
 void ConnectionObjectSetState(CipConnectionObject *const connection_object,
                               const ConnectionObjectState state) {
-  switch(state) {
-    case kConnectionObjectStateNonExistent: connection_object->state =
-      CIP_CONNECTION_OBJECT_STATE_NON_EXISTENT; break;
-    case kConnectionObjectStateConfiguring: connection_object->state =
-      CIP_CONNECTION_OBJECT_STATE_CONFIGURING; break;
-    case kConnectionObjectStateWaitingForConnectionID: connection_object->state
-        = CIP_CONNECTION_OBJECT_STATE_WAITING_FOR_CONNECTION_ID; break;
-    case kConnectionObjectStateEstablished: connection_object->state =
-      CIP_CONNECTION_OBJECT_STATE_ESTABLISHED; break;
-    case kConnectionObjectStateTimedOut: connection_object->state =
-      CIP_CONNECTION_OBJECT_STATE_TIMEOUT; break;
-    case kConnectionObjectStateDeferredDelete: connection_object->state =
-      CIP_CONNECTION_OBJECT_STATE_DEFERRED_DELETE; break;
-    case kConnectionObjectStateClosing: connection_object->state =
-      CIP_CONNECTION_OBJECT_STATE_CLOSING; break;
-    default: OPENER_ASSERT(false);     /* Never get here */
+  switch (state) {
+    case kConnectionObjectStateNonExistent:
+      connection_object->state =
+        CIP_CONNECTION_OBJECT_STATE_NON_EXISTENT;
+      break;
+    case kConnectionObjectStateConfiguring:
+      connection_object->state =
+        CIP_CONNECTION_OBJECT_STATE_CONFIGURING;
+      break;
+    case kConnectionObjectStateWaitingForConnectionID:
+      connection_object->state =
+        CIP_CONNECTION_OBJECT_STATE_WAITING_FOR_CONNECTION_ID;
+      break;
+    case kConnectionObjectStateEstablished:
+      connection_object->state =
+        CIP_CONNECTION_OBJECT_STATE_ESTABLISHED;
+      break;
+    case kConnectionObjectStateTimedOut:
+      connection_object->state =
+        CIP_CONNECTION_OBJECT_STATE_TIMEOUT;
+      break;
+    case kConnectionObjectStateDeferredDelete:
+      connection_object->state =
+        CIP_CONNECTION_OBJECT_STATE_DEFERRED_DELETE;
+      break;
+    case kConnectionObjectStateClosing:
+      connection_object->state =
+        CIP_CONNECTION_OBJECT_STATE_CLOSING;
+      break;
+    default:
+      OPENER_ASSERT(false); /* Never get here */
   }
 }
 
 ConnectionObjectInstanceType ConnectionObjectGetInstanceType(
   const CipConnectionObject *const connection_object) {
-  switch(connection_object->instance_type) {
-    case CIP_CONNECTION_OBJECT_INSTANCE_TYPE_EXPLICIT_MESSAGING: return
-        kConnectionObjectInstanceTypeExplicitMessaging; break;
-    case CIP_CONNECTION_OBJECT_INSTANCE_TYPE_IO: return
-        kConnectionObjectInstanceTypeIO; break;
-    case CIP_CONNECTION_OBJECT_INSTANCE_TYPE_CIP_BRIDGED: return
-        kConnectionObjectInstanceTypeCipBridged; break;
-    default: return kConnectionObjectInstanceTypeInvalid;
+  switch (connection_object->instance_type) {
+    case CIP_CONNECTION_OBJECT_INSTANCE_TYPE_EXPLICIT_MESSAGING:
+      return kConnectionObjectInstanceTypeExplicitMessaging;
+      break;
+    case CIP_CONNECTION_OBJECT_INSTANCE_TYPE_IO:
+      return kConnectionObjectInstanceTypeIO;
+      break;
+    case CIP_CONNECTION_OBJECT_INSTANCE_TYPE_CIP_BRIDGED:
+      return kConnectionObjectInstanceTypeCipBridged;
+      break;
+    default:
+      return kConnectionObjectInstanceTypeInvalid;
   }
 }
 
@@ -191,24 +225,26 @@ ConnectionObjectTransportClassTriggerProductionTrigger
 ConnectionObjectGetTransportClassTriggerProductionTrigger(
   const CipConnectionObject *const connection_object) {
   const CipByte kTransportClassTriggerProductionTriggerMask = 0x70;
-  switch( (connection_object->transport_class_trigger) &
-          kTransportClassTriggerProductionTriggerMask ) {
+  switch ( (connection_object->transport_class_trigger) &
+           kTransportClassTriggerProductionTriggerMask ) {
     case
       CIP_CONNECTION_OBJECT_TRANSPORT_CLASS_TRIGGER_PRODUCTION_TRIGGER_CYCLIC:
       return kConnectionObjectTransportClassTriggerProductionTriggerCyclic;
       break;
     case
       CIP_CONNECTION_OBJECT_TRANSPORT_CLASS_TRIGGER_PRODUCTION_TRIGGER_CHANGE_OF_STATE
-      : return
+      :
+      return
         kConnectionObjectTransportClassTriggerProductionTriggerChangeOfState;
       break;
     case
       CIP_CONNECTION_OBJECT_TRANSPORT_CLASS_TRIGGER_PRODUCTION_TRIGGER_APPLICATION_OBJECT
-      : return
+      :
+      return
         kConnectionObjectTransportClassTriggerProductionTriggerApplicationObject;
       break;
-    default: return
-        kConnectionObjectTransportClassTriggerProductionTriggerInvalid;
+    default:
+      return kConnectionObjectTransportClassTriggerProductionTriggerInvalid;
   }
 }
 
@@ -216,17 +252,22 @@ ConnectionObjectTransportClassTriggerTransportClass
 ConnectionObjectGetTransportClassTriggerTransportClass(
   const CipConnectionObject *const connection_object) {
   const CipByte kTransportClassTriggerTransportClassMask = 0x0F;
-  switch( (connection_object->transport_class_trigger) &
-          kTransportClassTriggerTransportClassMask ) {
+  switch ( (connection_object->transport_class_trigger) &
+           kTransportClassTriggerTransportClassMask ) {
     case CIP_CONNECTION_OBJECT_TRANSPORT_CLASS_TRIGGER_TRANSPORT_CLASS_0:
-      return kConnectionObjectTransportClassTriggerTransportClass0; break;
+      return kConnectionObjectTransportClassTriggerTransportClass0;
+      break;
     case CIP_CONNECTION_OBJECT_TRANSPORT_CLASS_TRIGGER_TRANSPORT_CLASS_1:
-      return kConnectionObjectTransportClassTriggerTransportClass1; break;
+      return kConnectionObjectTransportClassTriggerTransportClass1;
+      break;
     case CIP_CONNECTION_OBJECT_TRANSPORT_CLASS_TRIGGER_TRANSPORT_CLASS_2:
-      return kConnectionObjectTransportClassTriggerTransportClass2; break;
+      return kConnectionObjectTransportClassTriggerTransportClass2;
+      break;
     case CIP_CONNECTION_OBJECT_TRANSPORT_CLASS_TRIGGER_TRANSPORT_CLASS_3:
-      return kConnectionObjectTransportClassTriggerTransportClass3; break;
-    default: return kConnectionObjectTransportClassTriggerTransportClassInvalid;
+      return kConnectionObjectTransportClassTriggerTransportClass3;
+      break;
+    default:
+      return kConnectionObjectTransportClassTriggerTransportClassInvalid;
   }
 }
 
@@ -264,7 +305,8 @@ void ConnectionObjectSetExpectedPacketRate(
   CipUint expected_packet_rate) {
   if( (expected_packet_rate % kOpenerTimerTickInMilliSeconds) == 0 ) {
     connection_object->expected_packet_rate = expected_packet_rate;
-  } else {
+  }
+  else{
     connection_object->expected_packet_rate = expected_packet_rate +
                                               (kOpenerTimerTickInMilliSeconds -
                                                expected_packet_rate %
@@ -298,16 +340,22 @@ void ConnectionObjectSetCipConsumedConnectionID(
 
 ConnectionObjectWatchdogTimeoutAction ConnectionObjectGetWatchdogTimeoutAction(
   const CipConnectionObject *const connection_object) {
-  switch(connection_object->watchdog_timeout_action) {
+  switch (connection_object->watchdog_timeout_action) {
     case CIP_CONNECTION_OBJECT_WATCHDOG_TIMEOUT_ACTION_TRANSITION_TO_TIMED_OUT:
-      return kConnectionObjectWatchdogTimeoutActionTransitionToTimedOut; break;
-    case CIP_CONNECTION_OBJECT_WATCHDOG_TIMEOUT_ACTION_AUTO_DELETE: return
-        kConnectionObjectWatchdogTimeoutActionAutoDelete; break;
-    case CIP_CONNECTION_OBJECT_WATCHDOG_TIMEOUT_ACTION_AUTO_RESET: return
-        kConnectionObjectWatchdogTimeoutActionAutoReset; break;
-    case CIP_CONNECTION_OBJECT_WATCHDOG_TIMEOUT_ACTION_DEFERRED_DELETE: return
-        kConnectionObjectWatchdogTimeoutActionDeferredDelete; break;
-    default: return kConnectionObjectWatchdogTimeoutActionInvalid; break;
+      return kConnectionObjectWatchdogTimeoutActionTransitionToTimedOut;
+      break;
+    case CIP_CONNECTION_OBJECT_WATCHDOG_TIMEOUT_ACTION_AUTO_DELETE:
+      return kConnectionObjectWatchdogTimeoutActionAutoDelete;
+      break;
+    case CIP_CONNECTION_OBJECT_WATCHDOG_TIMEOUT_ACTION_AUTO_RESET:
+      return kConnectionObjectWatchdogTimeoutActionAutoReset;
+      break;
+    case CIP_CONNECTION_OBJECT_WATCHDOG_TIMEOUT_ACTION_DEFERRED_DELETE:
+      return kConnectionObjectWatchdogTimeoutActionDeferredDelete;
+      break;
+    default:
+      return kConnectionObjectWatchdogTimeoutActionInvalid;
+      break;
   }
 }
 
@@ -315,21 +363,27 @@ void ConnectionObjectSetWatchdogTimeoutAction(
   CipConnectionObject *const connection_object,
   const CipUsint
   watchdog_timeout_action) {
-  switch(watchdog_timeout_action) {
+  switch (watchdog_timeout_action) {
     case CIP_CONNECTION_OBJECT_WATCHDOG_TIMEOUT_ACTION_TRANSITION_TO_TIMED_OUT:
       connection_object->watchdog_timeout_action =
-        kConnectionObjectWatchdogTimeoutActionTransitionToTimedOut; break;
+        kConnectionObjectWatchdogTimeoutActionTransitionToTimedOut;
+      break;
     case CIP_CONNECTION_OBJECT_WATCHDOG_TIMEOUT_ACTION_AUTO_DELETE:
       connection_object->watchdog_timeout_action =
-        kConnectionObjectWatchdogTimeoutActionAutoDelete; break;
+        kConnectionObjectWatchdogTimeoutActionAutoDelete;
+      break;
     case CIP_CONNECTION_OBJECT_WATCHDOG_TIMEOUT_ACTION_AUTO_RESET:
       connection_object->watchdog_timeout_action =
-        kConnectionObjectWatchdogTimeoutActionAutoReset; break;
+        kConnectionObjectWatchdogTimeoutActionAutoReset;
+      break;
     case CIP_CONNECTION_OBJECT_WATCHDOG_TIMEOUT_ACTION_DEFERRED_DELETE:
       connection_object->watchdog_timeout_action =
-        kConnectionObjectWatchdogTimeoutActionDeferredDelete; break;
-    default: connection_object->watchdog_timeout_action =
-      kConnectionObjectWatchdogTimeoutActionInvalid; break;
+        kConnectionObjectWatchdogTimeoutActionDeferredDelete;
+      break;
+    default:
+      connection_object->watchdog_timeout_action =
+        kConnectionObjectWatchdogTimeoutActionInvalid;
+      break;
   }
 }
 
@@ -359,3 +413,160 @@ void ConnectionObjectSetConsumedConnectionPathLength(
     consumed_connection_path_length;
 }
 
+void ConnectionObjectSetInitialInactivityWatchdogTimerValue(
+  CipConnectionObject *connection_object) {
+  connection_object->inactivity_watchdog_timer =
+    (ConnectionObjectCalculateRegularInactivityWatchdogTimerValue(
+       connection_object) >
+     10000) ? ConnectionObjectCalculateRegularInactivityWatchdogTimerValue(
+      connection_object)
+    :
+    10000;
+}
+
+void ConnectionObjectResetInactivityWatchdogTimerValue(
+  CipConnectionObject *connection_object) {
+  connection_object->inactivity_watchdog_timer =
+    ConnectionObjectCalculateRegularInactivityWatchdogTimerValue(
+      connection_object);
+}
+
+uint64_t ConnectionObjectCalculateRegularInactivityWatchdogTimerValue(
+  const CipConnectionObject *connection_object) {
+  return ( ( (connection_object->o_to_t_requested_packet_interval) /
+             1000 ) << (2 + connection_object->connection_timeout_multiplier) );
+}
+
+CipUint ConnectionObjectGetConnectionSerialNumber(
+    const CipConnectionObject *const connection_object) {
+  return connection_object->connection_serial_number;
+}
+
+void ConnectionObjectSetConnectionSerialNumber(
+    CipConnectionObject *connection_object, const CipUint connection_serial_number) {
+  connection_object->connection_serial_number = connection_serial_number;
+}
+
+CipUint ConnectionObjectGetOriginatorVendorId(
+    const CipConnectionObject *const connection_object) {
+  return connection_object->originator_vendor_id;
+}
+
+void ConnectionObjectSetOriginatorVendorId(
+    CipConnectionObject *connection_object, const CipUint vendor_id){
+  connection_object->originator_vendor_id = vendor_id;
+}
+
+CipUdint ConnectionObjectGetOriginatorSerialNumber(
+    const CipConnectionObject *const connection_object) {
+  return connection_object->originator_serial_number;
+}
+
+void ConnectionObjectSetOriginatorSerialNumber(
+    CipConnectionObject *connection_object, CipUdint originator_serial_number) {
+  connection_object->originator_serial_number = originator_serial_number;
+}
+
+CipUsint ConnectionObjectGetConnectionTimeoutMultiplier(
+    const CipConnectionObject *const connection_object) {
+  return connection_object->connection_timeout_multiplier;
+}
+
+void ConnectionObjectSetConnectionTimeoutMultiplier(
+    CipConnectionObject *connection_object, CipUsint connection_timeout_multiplier) {
+  connection_object->connection_timeout_multiplier = connection_timeout_multiplier;
+}
+
+CipUdint ConnectionObjectGetOToTRequestedPacketInterval(const CipConnectionObject *const connection_object) {
+  return connection_object->o_to_t_requested_packet_interval;
+}
+
+void ConnectionObjectSetOToTRequestedPacketInterval(CipConnectionObject *connection_object, const CipUdint requested_packet_interval) {
+  connection_object->o_to_t_requested_packet_interval = requested_packet_interval;
+}
+
+CipUdint ConnectionObjectGetTToORequestedPacketInterval(const CipConnectionObject *const connection_object) {
+  return connection_object->t_to_o_requested_packet_interval;
+}
+
+void ConnectionObjectSetTToORequestedPacketInterval(CipConnectionObject *connection_object, const CipUdint requested_packet_interval) {
+  connection_object->t_to_o_requested_packet_interval = requested_packet_interval;
+}
+
+bool ConnectionObjectIsOToTRedundantOwner(const CipConnectionObject *const connection_object) {
+  const CipWord kOwnerMask = 0x80;
+  return kOwnerMask & connection_object->o_to_t_network_connection_parameters;
+}
+
+bool ConnectionObjectIsTToORedundantOwner(const CipConnectionObject *const connection_object) {
+  const CipWord kOwnerMask = 0x80;
+  return kOwnerMask & connection_object->t_to_o_network_connection_parameters;
+}
+
+ConnectionObjectConnectionType ConnectionObjectGetConnectionType(const CipWord connection_parameters) {
+  const CipWord kConnectionTypeMask = 3 << 13;
+  switch(connection_parameters & kConnectionTypeMask) {
+    case CIP_CONNECTION_OBJECT_CONNECTION_TYPE_NULL: return kConnectionObjectConnectionTypeNull;
+    case CIP_CONNECTION_OBJECT_CONNECTION_TYPE_MULTICAST: return kConnectionObjectConnectionTypeMulticast;
+    case CIP_CONNECTION_OBJECT_CONNECTION_TYPE_POINT_TO_POINT: return kConnectionObjectConnectionTypePointToPoint;
+    default: return kConnectionObjectConnectionTypeInvalid;
+  }
+}
+
+ConnectionObjectConnectionType ConnectionObjectGetOToTConnectionType(const CipConnectionObject *const connection_object) {
+  ConnectionObjectGetConnectionType(connection_object->o_to_t_network_connection_parameters);
+}
+
+ConnectionObjectConnectionType ConnectionObjectGetTToOConnectionType(const CipConnectionObject *const connection_object) {
+  ConnectionObjectGetConnectionType(connection_object->t_to_o_network_connection_parameters);
+}
+
+ConnectionObjectPriority ConnectionObjectGetPriority(const CipWord connection_parameters) {
+  const CipWord kPriorityMask = 3 << 10;
+  switch(connection_parameters & kPriorityMask) {
+    case CIP_CONNECTION_OBJECT_PRIORITY_LOW: return kConnectionObjectPriorityLow;
+    case CIP_CONNECTION_OBJECT_PRIORITY_HIGH: return kConnectionObjectPriorityHigh;
+    case CIP_CONNECTION_OBJECT_PRIORITY_SCHEDULED: return kConnectionObjectPriorityScheduled;
+    case CIP_CONNECTION_OBJECT_PRIORITY_URGENT: return kConnectionObjectPriorityUrgent;
+    default: OPENER_ASSERT(false); //Not possible to get here!
+  }
+}
+
+ConnectionObjectPriority ConnectionObjectGetOToTPriority(const CipConnectionObject *const connection_object) {
+  return ConnectionObjectGetPriority(connection_object->o_to_t_network_connection_parameters);
+}
+
+ConnectionObjectPriority ConnectionObjectGetTToOPriority(const CipConnectionObject *const connection_object) {
+  return ConnectionObjectGetPriority(connection_object->t_to_o_network_connection_parameters);
+}
+
+
+ConnectionObjectConnectionSizeType ConnectionObjectGetConnectionSizeType(const CipWord connection_parameters) {
+  const CipWord kConnectionSizeTypeMask = 1 << 9;
+  if(connection_parameters & kConnectionSizeTypeMask) {
+    return kConnectionObjectConnectionSizeTypeVariable;
+  } else {
+    return kConnectionObjectConnectionSizeTypeFixed;
+  }
+}
+
+ConnectionObjectConnectionSizeType ConnectionObjectGetOToTConnectionSizeType(const CipConnectionObject *const connection_object) {
+  return ConnectionObjectGetConnectionSizeType(connection_object->o_to_t_network_connection_parameters);
+}
+
+ConnectionObjectConnectionSizeType ConnectionObjectGetTToOConnectionSizeType(const CipConnectionObject *const connection_object) {
+  return ConnectionObjectGetConnectionSizeType(connection_object->t_to_o_network_connection_parameters);
+}
+
+size_t ConnectionObjectGetConnectionSize(const CipWord connection_parameters) {
+  const CipWord kConnectionSizeMask = 0x01FF;
+  return connection_parameters & kConnectionSizeMask;
+}
+
+size_t ConnectionObjectGetOToTConnectionSize(const CipConnectionObject *const connection_object) {
+  return ConnectionObjectGetConnectionSize(connection_object->o_to_t_network_connection_parameters);
+}
+
+size_t ConnectionObjectGetTToOConnectionSize(const CipConnectionObject *const connection_object) {
+  return ConnectionObjectGetConnectionSize(connection_object->t_to_o_network_connection_parameters);
+}

+ 74 - 0
source/src/cip/cipconnectionobject.h

@@ -59,6 +59,25 @@ typedef enum {
   kConnectionObjectWatchdogTimeoutActionDeferredDelete       /**< Only for Device Net, invalid for I/O connections */
 } ConnectionObjectWatchdogTimeoutAction;
 
+typedef enum {
+  kConnectionObjectConnectionTypeInvalid = -1,
+  kConnectionObjectConnectionTypeNull = 0,
+  kConnectionObjectConnectionTypeMulticast,
+  kConnectionObjectConnectionTypePointToPoint
+} ConnectionObjectConnectionType;
+
+typedef enum {
+  kConnectionObjectPriorityLow = 0,
+  kConnectionObjectPriorityHigh,
+  kConnectionObjectPriorityScheduled,
+  kConnectionObjectPriorityUrgent
+} ConnectionObjectPriority;
+
+typedef enum {
+  kConnectionObjectConnectionSizeTypeFixed,
+  kConnectionObjectConnectionSizeTypeVariable
+} ConnectionObjectConnectionSizeType;
+
 typedef struct cip_connection_object CipConnectionObject;
 
 typedef EipStatus (*CipConnectionStateHandler)(CipConnectionObject *RESTRICT const connection_object, ConnectionObjectState new_state);
@@ -95,6 +114,12 @@ struct cip_connection_object {
   CipUint originator_vendor_id;
   CipUdint originator_serial_number;
 
+  CipUdint o_to_t_requested_packet_interval;
+  CipWord o_to_t_network_connection_parameters;
+
+  CipUdint t_to_o_requested_packet_interval;
+  CipWord t_to_o_network_connection_parameters;
+
   CipUint sequence_count_producing;
 
   CipConnectionStateHandler current_state_handler;
@@ -225,5 +250,54 @@ void ConnectionObjectSetConnectionTimeoutMultiplier(
   const CipUsint
   connection_timeout_multiplier);
 
+void ConnectionObjectResetInactivityWatchdogTimerValue(
+  CipConnectionObject *connection_object);
+
+CipUint ConnectionObjectGetConnectionSerialNumber(
+    const CipConnectionObject *const connection_object);
+
+void ConnectionObjectSetConnectionSerialNumber(
+    CipConnectionObject *connection_object, const CipUint connection_serial_number);
+
+CipUint ConnectionObjectGetOriginatorVendorId(
+    const CipConnectionObject *const connection_object);
+
+void ConnectionObjectSetOriginatorVendorId(
+    CipConnectionObject *connection_object, const CipUint vendor_id);
+
+CipUdint ConnectionObjectGetOriginatorSerialNumber(
+    const CipConnectionObject *const connection_object);
+
+void ConnectionObjectSetOriginatorSerialNumber(
+    CipConnectionObject *connection_object, CipUdint originator_serial_number);
+
+CipUdint ConnectionObjectGetOToTRequestedPacketInterval(const CipConnectionObject *const connection_object);
+
+void ConnectionObjectSetOToTRequestedPacketInterval(CipConnectionObject *connection_object, const CipUdint requested_packet_interval);
+
+bool ConnectionObjectIsOToTRedundantOwner(const CipConnectionObject *const connection_object);
+
+ConnectionObjectConnectionType ConnectionObjectGetOToTConnectionType(const CipConnectionObject *const connection_object);
+
+ConnectionObjectPriority ConnectionObjectGetOToTPriority(const CipConnectionObject *const connection_object);
+
+ConnectionObjectConnectionSizeType ConnectionObjectGetOToTConnectionSizeType(const CipConnectionObject *const connection_object);
+
+size_t ConnectionObjectGetOToTConnectionSize(const CipConnectionObject *const connection_object);
+
+/* T to O */
+CipUdint ConnectionObjectGetTToORequestedPacketInterval(const CipConnectionObject *const connection_object);
+
+void ConnectionObjectSetTToORequestedPacketInterval(CipConnectionObject *connection_object, const CipUdint requested_packet_interval);
+
+bool ConnectionObjectIsTToORedundantOwner(const CipConnectionObject *const connection_object);
+
+ConnectionObjectConnectionType ConnectionObjectGetTToOConnectionType(const CipConnectionObject *const connection_object);
+
+ConnectionObjectPriority ConnectionObjectGetTToOPriority(const CipConnectionObject *const connection_object);
+
+ConnectionObjectConnectionSizeType ConnectionObjectGetTToOConnectionSizeType(const CipConnectionObject *const connection_object);
+
+size_t ConnectionObjectGetTToOConnectionSize(const CipConnectionObject *const connection_object);
 
 #endif /* SRC_CIP_CIPCONNECTIONOBJECT_H_ */

+ 6 - 6
source/src/enet_encap/encap.c

@@ -311,10 +311,10 @@ int HandleReceivedExplictUdpData(int socket,
 }
 
 int EncapsulateData(const EncapsulationData *const send_data) {
-  EipUint8 *communcation_buffer = send_data->communication_buffer_start + 2;
+  CipOctet *communcation_buffer = send_data->communication_buffer_start + 2;
   AddIntToMessage(send_data->data_length, &communcation_buffer);
   /*the CommBuf should already contain the correct session handle*/
-  MoveMessageNOctets(4, &communcation_buffer);
+  MoveMessageNOctets(4, (const CipOctet**)&communcation_buffer);
   AddDintToMessage(send_data->status, &communcation_buffer);
   /*the CommBuf should already contain the correct sender context*/
   /*the CommBuf should already contain the correct  options value*/
@@ -393,13 +393,13 @@ void HandleReceivedListIdentityCommandUdp(int socket,
 
 ptrdiff_t EncapsulateListIdentyResponseMessage(
   EipByte *const communication_buffer) {
-  EipUint8 *communication_buffer_runner = communication_buffer;
+  CipOctet *communication_buffer_runner = communication_buffer;
 
   AddIntToMessage( 1, &(communication_buffer_runner) ); /* Item count: one item */
   AddIntToMessage(kCipItemIdListIdentityResponse, &communication_buffer_runner);
 
   EipByte *id_length_buffer = communication_buffer_runner;
-  MoveMessageNOctets(2, &communication_buffer_runner); /*at this place the real length will be inserted below*/
+  MoveMessageNOctets(2, (const CipOctet**)&communication_buffer_runner); /*at this place the real length will be inserted below*/
 
   AddIntToMessage(kSupportedProtocolVersion, &communication_buffer_runner);
 
@@ -408,7 +408,7 @@ ptrdiff_t EncapsulateListIdentyResponseMessage(
                        &communication_buffer_runner);
 
   memset(communication_buffer_runner, 0, 8);
-  MoveMessageNOctets(8, &communication_buffer_runner);
+  MoveMessageNOctets(8, (const CipOctet**)&communication_buffer_runner);
 
   AddIntToMessage(vendor_id_, &communication_buffer_runner);
   AddIntToMessage(device_type_, &communication_buffer_runner);
@@ -432,7 +432,7 @@ ptrdiff_t EncapsulateListIdentyResponseMessage(
 void DetermineDelayTime(EipByte *buffer_start,
                         DelayedEncapsulationMessage *delayed_message_buffer) {
 
-  MoveMessageNOctets(12, &buffer_start); /* start of the sender context */
+  MoveMessageNOctets(12, (const CipOctet**)&buffer_start); /* start of the sender context */
   EipUint16 maximum_delay_time = GetIntFromMessage(
     (const EipUint8 **const)&buffer_start );
 

+ 2 - 2
source/src/enet_encap/endianconv.c

@@ -251,7 +251,7 @@ int GetEndianess() {
   return g_opener_platform_endianess;
 }
 
-void MoveMessageNOctets(int amount_of_bytes_moved, CipOctet **message_runner) {
+void MoveMessageNOctets(int amount_of_bytes_moved, const CipOctet **message_runner) {
   (*message_runner) += amount_of_bytes_moved;
 }
 
@@ -266,7 +266,7 @@ int FillNextNMessageOctetsWithValueAndMoveToNextPosition(CipOctet value,
                                                          unsigned int amount_of_filled_bytes,
                                                          CipOctet **message) {
   FillNextNMessageOctetsWith(value, amount_of_filled_bytes, message);
-  MoveMessageNOctets(amount_of_filled_bytes, message);
+  MoveMessageNOctets(amount_of_filled_bytes, (const CipOctet**)message);
   return amount_of_filled_bytes;
 }
 

+ 1 - 1
source/src/enet_encap/endianconv.h

@@ -120,7 +120,7 @@ void DetermineEndianess(void);
  */
 int GetEndianess(void);
 
-void MoveMessageNOctets(int n, CipOctet **message_runner);
+void MoveMessageNOctets(int n, const CipOctet **message_runner);
 
 int FillNextNMessageOctetsWith(CipOctet value,unsigned int n,
                                CipOctet **message);

+ 1 - 1
source/src/ports/POSIX/sample_application/opener_user_conf.h

@@ -36,7 +36,7 @@
 #define OPENER_DEVICE_PRODUCT_CODE      65001
 #define OPENER_DEVICE_MAJOR_REVISION      1
 #define OPENER_DEVICE_MINOR_REVISION      2
-#define OPENER_DEVICE_NAME      "OpENer PC"
+#define OPENER_DEVICE_NAME      ("OpENer PC")
 
 /** @brief Define the number of objects that may be used in connections
  *

+ 74 - 0
source/tests/cip/cipconnectionobjecttest.cpp

@@ -234,3 +234,77 @@ TEST(CipConnectionObject, ExpectedPacketRateZero) {
     &connection_object);
   CHECK_EQUAL(0, expected_packet_rate);
 }
+
+TEST(CipConnectionObject, ParseConnectionData) {
+  CipConnectionObject connection_object = { 0 };
+  CipOctet message[] = "\x06\x28\x00\x00\x00\x00\x00\x00\x00\x00\x98\xff\x18\x00\x78\x56" \
+"\x34\x12\x00\x00\x00\x00\xe0\x93\x04\x00\x02\x40\xa0\x86\x01\x00" \
+"\x22\x20\x01\x04\x20\x04\x24\x97\x2c\x98\x2c\x64";
+
+  ConnectionObjectInitializeFromMessage(message, &connection_object);
+  CipUdint o_to_t_network_connection_id = ConnectionObjectGetCipConsumedConnectionID(&connection_object);
+  CHECK_EQUAL(0, o_to_t_network_connection_id);
+
+  CipUdint t_to_o_network_connection_id = ConnectionObjectGetCipProducedConnectionID(&connection_object);
+  CHECK_EQUAL(0, t_to_o_network_connection_id);
+
+  CipUint connection_serial_number = ConnectionObjectGetConnectionSerialNumber(&connection_object);
+  CHECK_EQUAL(0xff98, connection_serial_number);
+
+  CipUint vendor_id = ConnectionObjectGetOriginatorVendorId(&connection_object);
+  CHECK_EQUAL(0x0018, vendor_id);
+
+  CipUdint originator_serial_number = ConnectionObjectGetOriginatorSerialNumber(&connection_object);
+  CHECK_EQUAL(0x12345678, originator_serial_number);
+
+  CipUsint connection_timeout_multiplier = ConnectionObjectGetConnectionTimeoutMultiplier(&connection_object);
+  CHECK_EQUAL(0, connection_timeout_multiplier);
+
+  CipUdint o_to_t_rpi_in_microseconds = ConnectionObjectGetOToTRequestedPacketInterval(&connection_object);
+  CHECK_EQUAL(300000, o_to_t_rpi_in_microseconds);
+
+  bool o_to_t_redundant_owner = ConnectionObjectIsOToTRedundantOwner(&connection_object);
+  CHECK_EQUAL(false, o_to_t_redundant_owner);
+
+  ConnectionObjectConnectionType o_to_t_connection_type = ConnectionObjectGetOToTConnectionType(&connection_object);
+  CHECK_EQUAL(kConnectionObjectConnectionTypePointToPoint, o_to_t_connection_type);
+
+  ConnectionObjectPriority o_to_t_priority = ConnectionObjectGetOToTPriority(&connection_object);
+  CHECK_EQUAL(kConnectionObjectPriorityLow, o_to_t_priority);
+
+  ConnectionObjectConnectionSizeType o_to_t_connection_size_type = ConnectionObjectGetOToTConnectionSizeType(&connection_object);
+  CHECK_EQUAL(kConnectionObjectConnectionSizeTypeFixed, o_to_t_connection_size_type);
+
+  size_t o_to_t_connection_size = ConnectionObjectGetOToTConnectionSize(&connection_object);
+  CHECK_EQUAL(2ULL, o_to_t_connection_size);
+
+  //T to O Tests
+
+  CipUdint t_to_o_rpi_in_microseconds = ConnectionObjectGetTToORequestedPacketInterval(&connection_object);
+  CHECK_EQUAL(100000, t_to_o_rpi_in_microseconds);
+
+  bool t_to_o_redundant_owner = ConnectionObjectIsTToORedundantOwner(&connection_object);
+  CHECK_EQUAL(false, t_to_o_redundant_owner);
+
+  ConnectionObjectConnectionType t_to_o_connection_type = ConnectionObjectGetTToOConnectionType(&connection_object);
+  CHECK_EQUAL(kConnectionObjectConnectionTypeMulticast, t_to_o_connection_type);
+
+  ConnectionObjectPriority t_to_o_priority = ConnectionObjectGetTToOPriority(&connection_object);
+  CHECK_EQUAL(kConnectionObjectPriorityLow, t_to_o_priority);
+
+  ConnectionObjectConnectionSizeType t_to_o_connection_size_type = ConnectionObjectGetTToOConnectionSizeType(&connection_object);
+  CHECK_EQUAL(kConnectionObjectConnectionSizeTypeFixed, t_to_o_connection_size_type);
+
+  size_t t_to_o_connection_size = ConnectionObjectGetTToOConnectionSize(&connection_object);
+  CHECK_EQUAL(34ULL, t_to_o_connection_size);
+
+  ConnectionObjectTransportClassTriggerDirection direction = ConnectionObjectGetTransportClassTriggerDirection(&connection_object);
+  CHECK_EQUAL(kConnectionObjectTransportClassTriggerDirectionClient, direction);
+
+  ConnectionObjectTransportClassTriggerProductionTrigger trigger = ConnectionObjectGetTransportClassTriggerProductionTrigger(&connection_object);
+  CHECK_EQUAL(kConnectionObjectTransportClassTriggerProductionTriggerCyclic, trigger);
+
+  ConnectionObjectTransportClassTriggerTransportClass transport_class = ConnectionObjectGetTransportClassTriggerTransportClass(&connection_object);
+  CHECK_EQUAL(kConnectionObjectTransportClassTriggerTransportClass1, transport_class);
+
+}

+ 2 - 2
source/tests/enet_encap/endianconvtest.cpp

@@ -130,8 +130,8 @@ TEST(EndianConversion, EncapsulateIpAddress) {
 }
 
 TEST(EndianConversion, MoveMessageNOctets) {
-  CipOctet message[8];
-  CipOctet *message_runner = message;
+  const CipOctet message[] = "This is a test message";
+  const CipOctet *message_runner = message;
 
   MoveMessageNOctets(4, &message_runner);