Jelajahi Sumber

Adds bubbling up of encapsulation session handle

Signed-off-by: CapXilinx <melik-merkumians@acin.tuwien.ac.at>
CapXilinx 8 tahun lalu
induk
melakukan
3b13d51158

+ 4 - 2
source/src/cip/cipassembly.c

@@ -22,7 +22,8 @@ EipStatus SetAssemblyAttributeSingle(
   CipInstance *const instance,
   CipMessageRouterRequest *const message_router_request,
   CipMessageRouterResponse *const message_router_response,
-  struct sockaddr *originator_address);
+  struct sockaddr *originator_address,
+  const int encapsulation_session);
 
 /** @brief Constructor for the assembly object class
  *
@@ -124,7 +125,8 @@ EipStatus SetAssemblyAttributeSingle(
   CipInstance *const instance,
   CipMessageRouterRequest *const message_router_request,
   CipMessageRouterResponse *const message_router_response,
-  struct sockaddr *originator_address) {
+  struct sockaddr *originator_address,
+  const int encapsulation_session) {
   OPENER_TRACE_INFO(" setAttribute %d\n",
                     message_router_request->request_path.attribute_number);
 

+ 4 - 1
source/src/cip/cipclass3connection.c

@@ -8,6 +8,8 @@
 
 #include "cipclass3connection.h"
 
+#include "encap.h"
+
 /**** Global variables ****/
 extern CipConnectionObject explicit_connection_object_pool[
   OPENER_CIP_NUM_EXPLICIT_CONNS];
@@ -15,7 +17,8 @@ extern CipConnectionObject explicit_connection_object_pool[
 CipConnectionObject *GetFreeExplicitConnection(void);
 
 void Class3ConnectionTimeoutHandler(CipConnectionObject *connection_object) {
-  CheckForTimedOutConnectionsAndCloseTCPConnections(connection_object);
+  CheckForTimedOutConnectionsAndCloseTCPConnections(connection_object,
+                                                    CloseEncapsulationSessionBySockAddr);
   CloseConnection(connection_object);
 }
 

+ 10 - 5
source/src/cip/cipcommon.c

@@ -74,7 +74,8 @@ void ShutdownCipStack(void) {
 EipStatus NotifyClass(const CipClass *RESTRICT const cip_class,
                       CipMessageRouterRequest *const message_router_request,
                       CipMessageRouterResponse *const message_router_response,
-                      struct sockaddr *originator_address) {
+                      struct sockaddr *originator_address,
+                      const int encapsulation_session) {
 
   /* find the instance: if instNr==0, the class is addressed, else find the instance */
   EipUint16 instance_number = message_router_request->request_path
@@ -97,7 +98,8 @@ EipStatus NotifyClass(const CipClass *RESTRICT const cip_class,
           OPENER_ASSERT(NULL != service->service_function);
           return service->service_function(instance, message_router_request,
                                            message_router_response,
-                                           originator_address);
+                                           originator_address,
+                                           encapsulation_session);
         } else {
           service++;
         }
@@ -383,7 +385,8 @@ EipStatus GetAttributeSingle(
   CipInstance *RESTRICT const instance,
   CipMessageRouterRequest *const message_router_request,
   CipMessageRouterResponse *const message_router_response,
-  struct sockaddr *originator_address) {
+  struct sockaddr *originator_address,
+  const int encapsulation_session) {
   /* Mask for filtering get-ability */
 
   CipAttributeStruct *attribute = GetCipAttribute(
@@ -680,7 +683,8 @@ int DecodeData(const EipUint8 cip_type,
 EipStatus GetAttributeAll(CipInstance *instance,
                           CipMessageRouterRequest *message_router_request,
                           CipMessageRouterResponse *message_router_response,
-                          struct sockaddr *originator_address) {
+                          struct sockaddr *originator_address,
+                          const int encapsulation_session) {
 
   EipUint8 *reply = message_router_response->data; /* pointer into the reply */
   CipAttributeStruct *attribute = instance->attributes; /* pointer to list of attributes*/
@@ -714,7 +718,8 @@ EipStatus GetAttributeAll(CipInstance *instance,
             if ( kEipStatusOkSend
                  != service->service_function(instance, message_router_request,
                                               message_router_response,
-                                              originator_address) ) {
+                                              originator_address,
+                                              encapsulation_session) ) {
               message_router_response->data = reply;
               return kEipStatusError;
             }

+ 6 - 3
source/src/cip/cipcommon.h

@@ -36,7 +36,8 @@ static const EipUint16 kCipUintZero = 0; /**< Zero value for returning the UINT
 EipStatus NotifyClass(const CipClass *const RESTRICT cip_class,
                       CipMessageRouterRequest *const message_router_request,
                       CipMessageRouterResponse *const message_router_response,
-                      struct sockaddr *originator_address);
+                      struct sockaddr *originator_address,
+                      const int encapsulation_session);
 
 /** @brief Generic implementation of the GetAttributeSingle CIP service
  *
@@ -54,7 +55,8 @@ EipStatus GetAttributeSingle(
   message_router_request,
   CipMessageRouterResponse *const
   message_router_response,
-  struct sockaddr *originator_address);
+  struct sockaddr *originator_address,
+  const int encapsulation_session);
 
 /** @brief Generic implementation of the GetAttributeAll CIP service
  *
@@ -68,7 +70,8 @@ EipStatus GetAttributeSingle(
 EipStatus GetAttributeAll(CipInstance *instance,
                           CipMessageRouterRequest *message_router_request,
                           CipMessageRouterResponse *message_router_response,
-                          struct sockaddr *originator_address);
+                          struct sockaddr *originator_address,
+                          const int encapsulation_session);
 
 /** @brief Decodes padded EPath
  *  @param epath EPath to the receiving element

+ 17 - 10
source/src/cip/cipconnectionmanager.c

@@ -66,19 +66,22 @@ EipStatus ForwardOpen(
   CipInstance *instance,
   CipMessageRouterRequest *message_router_request,
   CipMessageRouterResponse *message_router_response,
-  struct sockaddr *originator_address);
+  struct sockaddr *originator_address,
+  const int encapsulation_session);
 
 EipStatus ForwardClose(
   CipInstance *instance,
   CipMessageRouterRequest *message_router_request,
   CipMessageRouterResponse *message_router_response,
-  struct sockaddr *originator_address);
+  struct sockaddr *originator_address,
+  const int encapsulation_session);
 
 EipStatus GetConnectionOwner(
   CipInstance *instance,
   CipMessageRouterRequest *message_router_request,
   CipMessageRouterResponse *message_router_response,
-  struct sockaddr *originator_address);
+  struct sockaddr *originator_address,
+  const int encapsulation_session);
 
 EipStatus AssembleForwardOpenResponse(
   CipConnectionObject *connection_object,
@@ -488,7 +491,8 @@ EipStatus ForwardOpen(
   CipInstance *instance,
   CipMessageRouterRequest *message_router_request,
   CipMessageRouterResponse *message_router_response,
-  struct sockaddr *originator_address
+  struct sockaddr *originator_address,
+  const int encapsulation_session
   ) {
   (void) instance; /*suppress compiler warning */
 
@@ -498,6 +502,8 @@ EipStatus ForwardOpen(
   /*first check if we have already a connection with the given params */
   ConnectionObjectInitializeFromMessage(&(message_router_request->data),
                                         &g_dummy_connection_object);
+  g_dummy_connection_object.associated_encapsulation_session =
+    encapsulation_session;
 
   memcpy( &(g_dummy_connection_object.originator_address), originator_address,
           sizeof(g_dummy_connection_object.originator_address) );
@@ -553,8 +559,8 @@ EipStatus ForwardClose(
   CipInstance *instance,
   CipMessageRouterRequest *message_router_request,
   CipMessageRouterResponse *message_router_response,
-  struct sockaddr *originator_address
-  ) {
+  struct sockaddr *originator_address,
+  const int encapsulation_session) {
   /*Suppress compiler warning*/
   (void) instance;
 
@@ -629,8 +635,8 @@ EipStatus GetConnectionOwner(
   CipInstance *instance,
   CipMessageRouterRequest *message_router_request,
   CipMessageRouterResponse *message_router_response,
-  struct sockaddr *originator_address
-  ) {
+  struct sockaddr *originator_address,
+  const int encapsulation_session) {
   /* suppress compiler warnings */
   (void) instance;
   (void) message_router_request;
@@ -1496,7 +1502,8 @@ EipStatus TriggerConnections(
 }
 
 void CheckForTimedOutConnectionsAndCloseTCPConnections(
-  const CipConnectionObject *const connection_object) {
+  const CipConnectionObject *const connection_object,
+  CloseSessionFunction CloseSessions) {
 
   DoublyLinkedListNode *search_node = connection_list.first;
   bool non_timed_out_connection_found = false;
@@ -1512,7 +1519,7 @@ void CheckForTimedOutConnectionsAndCloseTCPConnections(
     search_node = search_node->next;
   }
   if(false == non_timed_out_connection_found) {
-    CloseEncapsulationSessionBySockAddr(connection_object);
+    CloseSessions(connection_object);
   }
 }
 

+ 5 - 1
source/src/cip/cipconnectionmanager.h

@@ -222,7 +222,11 @@ void RemoveFromActiveConnections(CipConnectionObject *const connection_object);
 
 CipUint GetConnectionId(void);
 
+typedef void (*CloseSessionFunction)(const CipConnectionObject *const
+                                     connection_object);
+
 void CheckForTimedOutConnectionsAndCloseTCPConnections(
-  );
+  const CipConnectionObject *const connection_object,
+  CloseSessionFunction CloseSessions);
 
 #endif /* OPENER_CIPCONNECTIONMANAGER_H_ */

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

@@ -177,6 +177,8 @@ struct cip_connection_object {
                                               for scanning if the right packet is
                                               arriving */
 
+  size_t associated_encapsulation_session; /* The session handle ID via which the forward open was sent */
+
   /* pointers to connection handling functions */
   CipConnectionStateHandler current_state_handler;
 

+ 7 - 3
source/src/cip/cipethernetlink.c

@@ -38,7 +38,8 @@ EipStatus GetAttributeSingleEthernetLink(
   CipInstance *RESTRICT const instance,
   CipMessageRouterRequest *const message_router_request,
   CipMessageRouterResponse *const message_router_response,
-  struct sockaddr *originator_address);
+  struct sockaddr *originator_address,
+  const int encapsulation_session);
 
 /** @bried Configures the MAC address of the Ethernet Link object*
  *
@@ -175,7 +176,8 @@ EipStatus GetAttributeSingleEthernetLink(
   CipInstance *RESTRICT const instance,
   CipMessageRouterRequest *const message_router_request,
   CipMessageRouterResponse *const message_router_response,
-  struct sockaddr *originator_address) {
+  struct sockaddr *originator_address,
+  const int encapsulation_session) {
   /* Mask for filtering get-ability */
 
   CipAttributeStruct *attribute = GetCipAttribute(
@@ -229,7 +231,9 @@ EipStatus GetAttributeSingleEthernetLink(
 
         default:
           GetAttributeSingle(instance, message_router_request,
-                             message_router_response, originator_address);
+                             message_router_response,
+                             originator_address,
+                             encapsulation_session);
       }
 
     }

+ 2 - 1
source/src/cip/cipethernetlink.h

@@ -30,7 +30,8 @@ EipStatus GetAttributeSingleEthernetLink(
   CipInstance *RESTRICT const instance,
   CipMessageRouterRequest *const message_router_request,
   CipMessageRouterResponse *const message_router_response,
-  struct sockaddr *originator_address);
+  struct sockaddr *originator_address,
+  const int encapsulation_session);
 
 /** @brief Data of an CIP Ethernet Link object */
 typedef struct {

+ 3 - 2
source/src/cip/cipidentity.c

@@ -72,8 +72,9 @@ static EipStatus Reset(CipInstance *instance,
 /* pointer to instance*/
                        CipMessageRouterRequest *message_router_request,
                        /* pointer to message router request*/
-                       CipMessageRouterResponse *message_router_response,
-                       struct sockaddr *originator_address) { /* pointer to message router response*/
+                       CipMessageRouterResponse *message_router_response,  /* pointer to message router response*/
+                       struct sockaddr *originator_address,
+                       const int encapsulation_session) {
   (void) instance;
 
   EipStatus eip_status = kEipStatusOkSend;

+ 2 - 1
source/src/cip/cipioconnection.c

@@ -715,7 +715,8 @@ void HandleIoConnectionTimeOut(CipConnectionObject *connection_object) {
 
   if(connection_object->last_package_watchdog_timer ==
      connection_object->inactivity_watchdog_timer) {
-    CheckForTimedOutConnectionsAndCloseTCPConnections(connection_object);
+    CheckForTimedOutConnectionsAndCloseTCPConnections(connection_object,
+                                                      CloseEncapsulationSessionBySockAddr);
   }
 
   if ( kConnectionObjectConnectionTypeMulticast

+ 5 - 2
source/src/cip/cipmessagerouter.c

@@ -172,7 +172,8 @@ EipStatus RegisterCipClass(CipClass *cip_class) {
 
 EipStatus NotifyMessageRouter(EipUint8 *data,
                               int data_length,
-                              struct sockaddr *originator_address) {
+                              struct sockaddr *originator_address,
+                              const int encapsulation_session) {
   EipStatus eip_status = kEipStatusOkSend;
   EipByte status = kCipErrorSuccess;
 
@@ -217,7 +218,9 @@ EipStatus NotifyMessageRouter(EipUint8 *data,
         registered_object->cip_class->class_name);
       eip_status = NotifyClass(registered_object->cip_class,
                                &g_message_router_request,
-                               &g_message_router_response, originator_address);
+                               &g_message_router_response,
+                               originator_address,
+                               encapsulation_session);
 
 #ifdef OPENER_TRACE_ENABLED
       if (eip_status == kEipStatusError) {

+ 2 - 1
source/src/cip/cipmessagerouter.h

@@ -40,7 +40,8 @@ void DeleteAllClasses(void);
  */
 EipStatus NotifyMessageRouter(EipUint8 *data,
                               int data_length,
-                              struct sockaddr *originator_address);
+                              struct sockaddr *originator_address,
+                              const int encapsulation_session);
 
 /*! Register a class at the message router.
  *  In order that the message router can deliver

+ 6 - 3
source/src/cip/cipqos.c

@@ -30,17 +30,20 @@ EipStatus GetAttributeSingleQoS(
   CipInstance *const RESTRICT instance,
   CipMessageRouterRequest *RESTRICT const message_router_request,
   CipMessageRouterResponse *RESTRICT const message_router_response,
-  struct sockaddr *originator_address) {
+  struct sockaddr *originator_address,
+  const int encapsulation_session) {
 
   return GetAttributeSingle(instance, message_router_request,
-                            message_router_response, originator_address);
+                            message_router_response, originator_address,
+                            encapsulation_session);
 }
 
 EipStatus SetAttributeSingleQoS(
   CipInstance *instance,
   CipMessageRouterRequest *message_router_request,
   CipMessageRouterResponse *message_router_response,
-  struct sockaddr *originator_address) {
+  struct sockaddr *originator_address,
+  const int encapsulation_session) {
 
   CipAttributeStruct *attribute = GetCipAttribute(
     instance, message_router_request->request_path.attribute_number);

+ 12 - 6
source/src/cip/ciptcpipinterface.c

@@ -67,19 +67,22 @@ EipStatus GetAttributeSingleTcpIpInterface(
   CipInstance *instance,
   CipMessageRouterRequest *message_router_request,
   CipMessageRouterResponse *message_router_response,
-  struct sockaddr *originator_address);
+  struct sockaddr *originator_address,
+  const int encapsulation_session);
 
 EipStatus GetAttributeAllTcpIpInterface(
   CipInstance *instance,
   CipMessageRouterRequest *message_router_request,
   CipMessageRouterResponse *message_router_response,
-  struct sockaddr *originator_address);
+  struct sockaddr *originator_address,
+  const int encapsulation_session);
 
 EipStatus SetAttributeSingleTcp(
   CipInstance *instance,
   CipMessageRouterRequest *message_router_request,
   CipMessageRouterResponse *message_router_response,
-  struct sockaddr *originator_address) {
+  struct sockaddr *originator_address,
+  const int encapsulation_session) {
   CipAttributeStruct *attribute = GetCipAttribute(
     instance, message_router_request->request_path.attribute_number);
   (void) instance; /*Suppress compiler warning */
@@ -226,7 +229,8 @@ EipStatus GetAttributeSingleTcpIpInterface(
   CipInstance *const RESTRICT instance,
   CipMessageRouterRequest *RESTRICT const message_router_request,
   CipMessageRouterResponse *RESTRICT const message_router_response,
-  struct sockaddr *originator_address) {
+  struct sockaddr *originator_address,
+  const int encapsulation_session) {
 
   EipStatus status = kEipStatusOkSend;
   EipByte *message = message_router_response->data;
@@ -323,7 +327,8 @@ EipStatus GetAttributeAllTcpIpInterface(
   CipInstance *instance,
   CipMessageRouterRequest *message_router_request,
   CipMessageRouterResponse *message_router_response,
-  struct sockaddr *originator_address) {
+  struct sockaddr *originator_address,
+  const int encapsulation_session) {
 
   EipUint8 *response = message_router_response->data; /* pointer into the reply */
   CipAttributeStruct *attribute = instance->attributes;
@@ -343,7 +348,8 @@ EipStatus GetAttributeAllTcpIpInterface(
       if ( kEipStatusOkSend
            != GetAttributeSingleTcpIpInterface(instance, message_router_request,
                                                message_router_response,
-                                               originator_address) ) {
+                                               originator_address,
+                                               encapsulation_session) ) {
         message_router_response->data = response;
         return kEipStatusError;
       }

+ 2 - 1
source/src/cip/ciptypes.h

@@ -273,7 +273,8 @@ typedef EipStatus (*CipServiceFunction)(
   CipInstance *const instance,
   CipMessageRouterRequest *const message_router_request,
   CipMessageRouterResponse *const message_router_response,
-  struct sockaddr *originator_address);
+  struct sockaddr *originator_address,
+  const int encapsulation_session);
 
 /** @brief Service descriptor. These are stored in an array */
 typedef struct cip_service_struct {

+ 4 - 2
source/src/enet_encap/cpf.c

@@ -42,7 +42,8 @@ int NotifyCommonPacketFormat(EncapsulationData *const receive_data,
         return_value = NotifyMessageRouter(
           g_common_packet_format_data_item.data_item.data,
           g_common_packet_format_data_item.data_item.length,
-          originator_address);
+          originator_address,
+          receive_data->session_handle);
         if (return_value != kEipStatusError) {
           return_value = AssembleLinearMessage(
             &g_message_router_response, &g_common_packet_format_data_item,
@@ -94,7 +95,8 @@ int NotifyConnectedCommonPacketFormat(EncapsulationData *received_data,
           return_value = NotifyMessageRouter(
             buffer,
             g_common_packet_format_data_item.data_item.length - 2,
-            originator_address);
+            originator_address,
+            received_data->session_handle);
 
           if (return_value != kEipStatusError) {
             g_common_packet_format_data_item.address_item.data

+ 9 - 0
source/src/enet_encap/encap.c

@@ -676,6 +676,15 @@ SessionStatus CheckRegisteredSessions(EncapsulationData *receive_data) {
   return kSessionStatusInvalid;
 }
 
+void CloseSessionBySessionHandle(
+  const CipConnectionObject *const connection_object) {
+  OPENER_TRACE_INFO("encap.c: Close session by handle\n");
+  size_t session_handle = connection_object->associated_encapsulation_session;
+  CloseTcpSocket(g_registered_sessions[session_handle - 1]);
+  g_registered_sessions[session_handle - 1] = kEipInvalidSocket;
+  OPENER_TRACE_INFO("encap.c: Close session by handle done\n");
+}
+
 void CloseSession(int socket) {
   OPENER_TRACE_INFO("encap.c: Close session\n");
   for (size_t i = 0; i < OPENER_NUMBER_OF_SUPPORTED_SESSIONS; ++i) {

+ 3 - 0
source/src/enet_encap/encap.h

@@ -83,6 +83,9 @@ void ManageEncapsulationMessages(const MilliSeconds elapsed_time);
 
 void RemoveSession(const int socket);
 
+void CloseSessionBySessionHandle(
+  const CipConnectionObject *const connection_object);
+
 void CloseEncapsulationSessionBySockAddr(
   const CipConnectionObject *const connection_object);