Selaa lähdekoodia

Merge pull request #261 from EIPStackGroup/Issue_214

Closes #214
Martin Melik-Merkumians 6 vuotta sitten
vanhempi
sitoutus
b0195f42c3

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

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

+ 3 - 3
source/src/cip/cipcommon.c

@@ -75,7 +75,7 @@ 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,
+                      const struct sockaddr *originator_address,
                       const int encapsulation_session) {
 
   /* find the instance: if instNr==0, the class is addressed, else find the instance */
@@ -404,7 +404,7 @@ CipAttributeStruct *GetCipAttribute(const CipInstance *const instance,
 EipStatus GetAttributeSingle(CipInstance *RESTRICT const instance,
                              CipMessageRouterRequest *const message_router_request,
                              CipMessageRouterResponse *const message_router_response,
-                             struct sockaddr *originator_address,
+                             const struct sockaddr *originator_address,
                              const int encapsulation_session) {
   /* Mask for filtering get-ability */
 
@@ -718,7 +718,7 @@ CipServiceStruct *GetCipService(const CipInstance *const instance,
 EipStatus GetAttributeAll(CipInstance *instance,
                           CipMessageRouterRequest *message_router_request,
                           CipMessageRouterResponse *message_router_response,
-                          struct sockaddr *originator_address,
+                          const struct sockaddr *originator_address,
                           const int encapsulation_session) {
 
   EipUint8 *reply = message_router_response->data;       /* pointer into the reply */

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

@@ -38,7 +38,7 @@ 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,
+                      const struct sockaddr *originator_address,
                       const int encapsulation_session);
 
 /** @brief Generic implementation of the GetAttributeSingle CIP service
@@ -59,7 +59,7 @@ EipStatus GetAttributeSingle(
   message_router_request,
   CipMessageRouterResponse *const
   message_router_response,
-  struct sockaddr *originator_address,
+  const struct sockaddr *originator_address,
   const int encapsulation_session);
 
 /** @brief Generic implementation of the GetAttributeAll CIP service
@@ -76,7 +76,7 @@ EipStatus GetAttributeSingle(
 EipStatus GetAttributeAll(CipInstance *instance,
                           CipMessageRouterRequest *message_router_request,
                           CipMessageRouterResponse *message_router_response,
-                          struct sockaddr *originator_address,
+                          const struct sockaddr *originator_address,
                           const int encapsulation_session);
 
 /** @brief Decodes padded EPath

+ 6 - 6
source/src/cip/cipconnectionmanager.c

@@ -65,21 +65,21 @@ EipStatus ForwardOpen(
   CipInstance *instance,
   CipMessageRouterRequest *message_router_request,
   CipMessageRouterResponse *message_router_response,
-  struct sockaddr *originator_address,
+  const struct sockaddr *originator_address,
   const int encapsulation_session);
 
 EipStatus ForwardClose(
   CipInstance *instance,
   CipMessageRouterRequest *message_router_request,
   CipMessageRouterResponse *message_router_response,
-  struct sockaddr *originator_address,
+  const struct sockaddr *originator_address,
   const int encapsulation_session);
 
 EipStatus GetConnectionOwner(
   CipInstance *instance,
   CipMessageRouterRequest *message_router_request,
   CipMessageRouterResponse *message_router_response,
-  struct sockaddr *originator_address,
+  const struct sockaddr *originator_address,
   const int encapsulation_session);
 
 EipStatus AssembleForwardOpenResponse(
@@ -492,7 +492,7 @@ EipStatus ForwardOpen(
   CipInstance *instance,
   CipMessageRouterRequest *message_router_request,
   CipMessageRouterResponse *message_router_response,
-  struct sockaddr *originator_address,
+  const struct sockaddr *originator_address,
   const int encapsulation_session
   ) {
   (void) instance; /*suppress compiler warning */
@@ -560,7 +560,7 @@ EipStatus ForwardClose(
   CipInstance *instance,
   CipMessageRouterRequest *message_router_request,
   CipMessageRouterResponse *message_router_response,
-  struct sockaddr *originator_address,
+  const struct sockaddr *originator_address,
   const int encapsulation_session) {
   /*Suppress compiler warning*/
   (void) instance;
@@ -636,7 +636,7 @@ EipStatus GetConnectionOwner(
   CipInstance *instance,
   CipMessageRouterRequest *message_router_request,
   CipMessageRouterResponse *message_router_response,
-  struct sockaddr *originator_address,
+  const struct sockaddr *originator_address,
   const int encapsulation_session) {
   /* suppress compiler warnings */
   (void) instance;

+ 1 - 1
source/src/cip/cipepath.c

@@ -329,7 +329,7 @@ void SetPathLogicalSegmentLogicalFormat(LogicalSegmentLogicalFormat format,
   }
 }
 
-const CipDword CipEpathGetLogicalValue(const EipUint8 **message) {
+CipDword CipEpathGetLogicalValue(const EipUint8 **message) {
   LogicalSegmentLogicalFormat logical_format =
     GetPathLogicalSegmentLogicalFormat(*message);
   CipDword data = 0;

+ 1 - 1
source/src/cip/cipepath.h

@@ -257,7 +257,7 @@ LogicalSegmentLogicalFormat GetPathLogicalSegmentLogicalFormat(
 void SetPathLogicalSegmentLogicalFormat(LogicalSegmentLogicalFormat format,
                                         CipOctet *const cip_path);
 
-const CipDword CipEpathGetLogicalValue(const EipUint8 **message);
+CipDword CipEpathGetLogicalValue(const EipUint8 **message);
 
 size_t CipEpathSetLogicalValue(const CipDword logical_value,
                                const LogicalSegmentLogicalFormat logical_format,

+ 2 - 2
source/src/cip/cipethernetlink.c

@@ -38,7 +38,7 @@ EipStatus GetAttributeSingleEthernetLink(
   CipInstance *RESTRICT const instance,
   CipMessageRouterRequest *const message_router_request,
   CipMessageRouterResponse *const message_router_response,
-  struct sockaddr *originator_address,
+  const struct sockaddr *originator_address,
   const int encapsulation_session);
 
 /** @brief Configures the MAC address of the Ethernet Link object*
@@ -177,7 +177,7 @@ EipStatus GetAttributeSingleEthernetLink(
   CipInstance *RESTRICT const instance,
   CipMessageRouterRequest *const message_router_request,
   CipMessageRouterResponse *const message_router_response,
-  struct sockaddr *originator_address,
+  const struct sockaddr *originator_address,
   const int encapsulation_session) {
   /* Mask for filtering get-ability */
 

+ 0 - 7
source/src/cip/cipethernetlink.h

@@ -26,13 +26,6 @@ int EncodeInterfaceControl(EipUint8 **pa_acMsg);
 
 int EncodeInterfaceCapability(EipUint8 **pa_acMsg);
 
-EipStatus GetAttributeSingleEthernetLink(
-  CipInstance *RESTRICT const instance,
-  CipMessageRouterRequest *const message_router_request,
-  CipMessageRouterResponse *const message_router_response,
-  struct sockaddr *originator_address,
-  const int encapsulation_session);
-
 /** @brief Data of an CIP Ethernet Link object */
 typedef struct {
   EipUint32 interface_speed; /**< 10/100/1000 Mbit/sec */

+ 1 - 1
source/src/cip/cipidentity.c

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

+ 1 - 1
source/src/cip/cipmessagerouter.c

@@ -175,7 +175,7 @@ EipStatus NotifyMessageRouter(EipUint8 *data,
                               const struct sockaddr *const originator_address,
                               const int encapsulation_session) {
   EipStatus eip_status = kEipStatusOkSend;
-  EipByte status = kCipErrorSuccess;
+  CipError status = kCipErrorSuccess;
 
   g_message_router_response.data = g_message_data_reply_buffer; /* set reply buffer, using a fixed buffer (OPENER_MESSAGE_DATA_REPLY_BUFFER bytes) */
 

+ 2 - 2
source/src/cip/cipqos.c

@@ -30,7 +30,7 @@ EipStatus GetAttributeSingleQoS(
   CipInstance *const RESTRICT instance,
   CipMessageRouterRequest *RESTRICT const message_router_request,
   CipMessageRouterResponse *RESTRICT const message_router_response,
-  struct sockaddr *originator_address,
+  const struct sockaddr *originator_address,
   const int encapsulation_session) {
 
   return GetAttributeSingle(instance, message_router_request,
@@ -42,7 +42,7 @@ EipStatus SetAttributeSingleQoS(
   CipInstance *instance,
   CipMessageRouterRequest *message_router_request,
   CipMessageRouterResponse *message_router_response,
-  struct sockaddr *originator_address,
+  const struct sockaddr *originator_address,
   const int encapsulation_session) {
 
   CipAttributeStruct *attribute = GetCipAttribute(

+ 5 - 5
source/src/cip/ciptcpipinterface.c

@@ -67,21 +67,21 @@ EipStatus GetAttributeSingleTcpIpInterface(
   CipInstance *const RESTRICT instance,
   CipMessageRouterRequest *const RESTRICT message_router_request,
   CipMessageRouterResponse *const RESTRICT message_router_response,
-  struct sockaddr *originator_address,
+  const struct sockaddr *originator_address,
   const int encapsulation_session);
 
 EipStatus GetAttributeAllTcpIpInterface(
   CipInstance *instance,
   CipMessageRouterRequest *message_router_request,
   CipMessageRouterResponse *message_router_response,
-  struct sockaddr *originator_address,
+  const struct sockaddr *originator_address,
   const int encapsulation_session);
 
 EipStatus SetAttributeSingleTcp(
   CipInstance *instance,
   CipMessageRouterRequest *message_router_request,
   CipMessageRouterResponse *message_router_response,
-  struct sockaddr *originator_address,
+  const struct sockaddr *originator_address,
   const int encapsulation_session) {
   CipAttributeStruct *attribute = GetCipAttribute(
     instance, message_router_request->request_path.attribute_number);
@@ -229,7 +229,7 @@ EipStatus GetAttributeSingleTcpIpInterface(
   CipInstance *const RESTRICT instance,
   CipMessageRouterRequest *const RESTRICT message_router_request,
   CipMessageRouterResponse *const RESTRICT message_router_response,
-  struct sockaddr *originator_address,
+  const struct sockaddr *originator_address,
   const int encapsulation_session) {
 
   EipUint16 attribute_number = message_router_request->request_path
@@ -293,7 +293,7 @@ EipStatus GetAttributeAllTcpIpInterface(
   CipInstance *instance,
   CipMessageRouterRequest *message_router_request,
   CipMessageRouterResponse *message_router_response,
-  struct sockaddr *originator_address,
+  const struct sockaddr *originator_address,
   const int encapsulation_session) {
 
   EipUint8 *response = message_router_response->data; /* pointer into the reply */

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

@@ -259,7 +259,7 @@ typedef struct cip_class {
  *  @typedef  EipStatus (*CipServiceFunction)(CipInstance *const instance,
  *    CipMessageRouterRequest *const message_router_request,
  *    CipMessageRouterResponse *const message_router_response,
- *    struct sockaddr *originator_address, const int encapsulation_session)
+ *    const struct sockaddr *originator_address, const int encapsulation_session)
  *  @brief Signature definition for the implementation of CIP services.
  *
  *  CIP services have to follow this signature in order to be handled correctly
@@ -269,6 +269,8 @@ typedef struct cip_class {
  *  @param message_router_request request data
  *  @param message_router_response storage for the response data, including a buffer for
  *   extended data
+ *  @param originator_address  address of the originator as received from socket
+ *  @param encapsulation_session associated encapsulation session of the explicit message
  *  @return kEipOkSend if service could be executed successfully and a response
  *   should be sent
  */
@@ -276,7 +278,7 @@ typedef EipStatus (*CipServiceFunction)(
   CipInstance *const instance,
   CipMessageRouterRequest *const message_router_request,
   CipMessageRouterResponse *const message_router_response,
-  struct sockaddr *originator_address,
+  const struct sockaddr *originator_address,
   const int encapsulation_session);
 
 /** @brief Service descriptor. These are stored in an array */

+ 27 - 19
source/src/enet_encap/cpf.c

@@ -23,10 +23,13 @@ const size_t sequenced_address_item_length = 8;
 
 CipCommonPacketFormatData g_common_packet_format_data_item; /**< CPF global data items */
 
-int NotifyCommonPacketFormat(const EncapsulationData *const received_data,
-                             const struct sockaddr *const originator_address,
-                             ENIPMessage *const outgoing_message) {
-  int return_value = kEipStatusError;
+EipStatus NotifyCommonPacketFormat
+(
+  const EncapsulationData *const received_data,
+  const struct sockaddr *const originator_address,
+  ENIPMessage *const outgoing_message)
+{
+  EipStatus return_value = kEipStatusError;
 
   if (kEipStatusError == ( return_value = CreateCommonPacketFormatStructure(
                              received_data->
@@ -35,7 +38,7 @@ int NotifyCommonPacketFormat(const EncapsulationData *const received_data,
                              &g_common_packet_format_data_item) ) ) {
     OPENER_TRACE_ERR("notifyCPF: error from createCPFstructure\n");
   } else {
-    return_value = kEipStatusOk; /* In cases of errors we normally need to send an error response */
+    return_value = kEipStatusOkSend;  /* In cases of errors we normally need to send an error response */
     if (g_common_packet_format_data_item.address_item.type_id
         == kCipItemIdNullAddress) /* check if NullAddressItem received, otherwise it is no unconnected message and should not be here*/
     {     /* found null address item*/
@@ -48,7 +51,9 @@ int NotifyCommonPacketFormat(const EncapsulationData *const received_data,
           received_data->session_handle);
         if (return_value != kEipStatusError) {
           SkipEncapsulationHeader(outgoing_message);
-          return_value = AssembleLinearMessage(
+          /* TODO: Here we lose a possible kEipStatusError from AssembleLinearMessage().
+           *  Its not clear how to transport this error information to the requester. */
+          int response_len = AssembleLinearMessage(
             &g_message_router_response, &g_common_packet_format_data_item,
             outgoing_message);
 
@@ -56,44 +61,44 @@ int NotifyCommonPacketFormat(const EncapsulationData *const received_data,
           outgoing_message->current_message_position =
             outgoing_message->message_buffer;
           GenerateEncapsulationHeader(received_data,
-                                      return_value,
+                                      response_len,
                                       received_data->session_handle,
                                       kEncapsulationProtocolSuccess,
                                       outgoing_message);
           outgoing_message->current_message_position = buffer;
-          return_value = outgoing_message->used_message_length;
+          return_value = kEipStatusOkSend;
         }
       } else {
         /* wrong data item detected*/
         OPENER_TRACE_ERR(
           "notifyCPF: got something besides the expected CIP_ITEM_ID_UNCONNECTEDMESSAGE\n");
         GenerateEncapsulationHeader(received_data,
-                                    return_value,
+                                    0,
                                     received_data->session_handle,
                                     kEncapsulationProtocolIncorrectData,
                                     outgoing_message);
-        return_value = outgoing_message->used_message_length;
+        return_value = kEipStatusOkSend;
       }
     } else {
       OPENER_TRACE_ERR(
         "notifyCPF: got something besides the expected CIP_ITEM_ID_NULL\n");
       GenerateEncapsulationHeader(received_data,
-                                  return_value,
+                                  0,
                                   received_data->session_handle,
                                   kEncapsulationProtocolIncorrectData,
                                   outgoing_message);
-      return_value = outgoing_message->used_message_length;
+      return_value = kEipStatusOkSend;
     }
   }
   return return_value;
 }
 
-int NotifyConnectedCommonPacketFormat(
+EipStatus NotifyConnectedCommonPacketFormat(
   const EncapsulationData *const received_data,
   const struct sockaddr *const originator_address,
   ENIPMessage *const outgoing_message) {
 
-  int return_value = CreateCommonPacketFormatStructure(
+  EipStatus return_value = CreateCommonPacketFormatStructure(
     received_data->current_communication_buffer_position,
     received_data->data_length, &g_common_packet_format_data_item);
 
@@ -139,7 +144,7 @@ int NotifyConnectedCommonPacketFormat(
                                         outgoing_message);
             outgoing_message->current_message_position = buffer;
             /* End regenerate encapsulation header for new message */
-            return outgoing_message->used_message_length;
+            return kEipStatusOkSend;
           }
           connection_object->sequence_count_consuming =
             g_common_packet_format_data_item.address_item.data.sequence_number;
@@ -157,7 +162,9 @@ int NotifyConnectedCommonPacketFormat(
             .connection_identifier = connection_object
                                      ->cip_produced_connection_id;
             SkipEncapsulationHeader(outgoing_message);
-            return_value = AssembleLinearMessage(
+            /* TODO: Here we lose a possible kEipStatusError from AssembleLinearMessage().
+             *  Its not clear how to transport this error information to the requester. */
+            int response_len = AssembleLinearMessage(
               &g_message_router_response, &g_common_packet_format_data_item,
               outgoing_message);
 
@@ -165,7 +172,7 @@ int NotifyConnectedCommonPacketFormat(
             outgoing_message->current_message_position =
               outgoing_message->message_buffer;
             GenerateEncapsulationHeader(received_data,
-                                        return_value,
+                                        response_len,
                                         received_data->session_handle,
                                         kEncapsulationProtocolSuccess,
                                         outgoing_message);
@@ -173,7 +180,7 @@ int NotifyConnectedCommonPacketFormat(
             memcpy(&connection_object->last_reply_sent,
                    outgoing_message,
                    sizeof(ENIPMessage) );
-            return_value = outgoing_message->used_message_length;
+            return_value = kEipStatusOkSend;
           }
         } else {
           /* wrong data item detected*/
@@ -189,7 +196,8 @@ int NotifyConnectedCommonPacketFormat(
         "notifyConnectedCPF: got something besides the expected CIP_ITEM_ID_NULL\n");
     }
   }
-  return outgoing_message->used_message_length;
+  // return outgoing_message->used_message_length;
+  return (0 != outgoing_message->used_message_length ? kEipStatusOkSend : kEipStatusOk); /* TODO: What would the right EipStatus to return? */
 }
 
 /**

+ 10 - 9
source/src/enet_encap/cpf.h

@@ -78,11 +78,12 @@ typedef struct {
  * @param received_data pointer to the encapsulation structure with the received message
  * @param originator_address Address struct of the originator
  * @param outgoing_message The outgoing ENIP message struct
- * @return number of bytes to be sent back. < 0 if nothing should be sent
+ * @return kEipStatusOkSend: a response needs to be sent, others: EIP stack status
  */
-int NotifyCommonPacketFormat(const EncapsulationData *const received_data,
-                             const struct sockaddr *const originator_address,
-                             ENIPMessage *const outgoing_message);
+EipStatus NotifyCommonPacketFormat(
+  const EncapsulationData *const received_data,
+  const struct sockaddr *const originator_address,
+  ENIPMessage *const outgoing_message);
 
 /** @ingroup ENCAP
  * Parse the CPF data from a received connected explicit message, check
@@ -92,9 +93,9 @@ int NotifyCommonPacketFormat(const EncapsulationData *const received_data,
  * @param received_data pointer to the encapsulation structure with the received message
  * @param originator_address Address struct of the originator
  * @param outgoing_message The outgoing ENIP message struct
- * @return number of bytes to be sent back. < 0 if nothing should be sent
+ * @return kEipStatusOkSend: a response needs to be sent, others: EIP stack status
  */
-int NotifyConnectedCommonPacketFormat(
+EipStatus NotifyConnectedCommonPacketFormat(
   const EncapsulationData *const received_data,
   const struct sockaddr *const originator_address,
   ENIPMessage *const outgoing_message);
@@ -116,9 +117,9 @@ EipStatus CreateCommonPacketFormatStructure(
 /** @ingroup ENCAP
  * Copy data from CPFDataItem into linear memory in message for transmission over in encapsulation.
  * @param  common_packet_format_data_item pointer to CPF structure which has to be aligned into linear memory.
- * @param  message Modified ENIP message struct
+ * @param  message Modified ENIPMessage struct
  * @return length of modification in bytes
- *     EIP_ERROR .. error
+ *     kEipStatusError .. error
  */
 int AssembleIOMessage(
   const CipCommonPacketFormatData *const common_packet_format_data_item,
@@ -131,7 +132,7 @@ int AssembleIOMessage(
  *
  * @param  message_router_response	pointer to message router response which has to be aligned into linear memory.
  * @param  common_packet_format_data_item	pointer to CPF structure which has to be aligned into linear memory.
- * @param  outgoing_message Modified ENIP message struct
+ * @param  outgoing_message Modified ENIPMessage struct
  * @return length of modification in bytes
  *         kEipStatusError .. error
  */

+ 47 - 50
source/src/enet_encap/encap.c

@@ -150,12 +150,15 @@ void EncapsulationInit(void) {
             "Communications" );
 }
 
-int HandleReceivedExplictTcpData(int socket,
-                                 EipUint8 *buffer,
-                                 size_t length,
-                                 int *remaining_bytes,
-                                 struct sockaddr *originator_address,
-                                 ENIPMessage *const outgoing_message) {
+EipStatus HandleReceivedExplictTcpData
+(
+  int socket,
+  EipUint8 *buffer,
+  size_t length,
+  int *remaining_bytes,
+  struct sockaddr *originator_address,
+  ENIPMessage *const outgoing_message)
+{
   OPENER_TRACE_INFO("Handles data for TCP socket: %d\n", socket);
   EipStatus return_value = kEipStatusOk;
   EncapsulationData encapsulation_data = { 0 };
@@ -234,14 +237,17 @@ int HandleReceivedExplictTcpData(int socket,
   return return_value;
 }
 
-int HandleReceivedExplictUdpData(const int socket,
-                                 const struct sockaddr_in *from_address,
-                                 const EipUint8 *buffer,
-                                 const size_t buffer_length,
-                                 int *number_of_remaining_bytes,
-                                 bool unicast,
-                                 ENIPMessage *const outgoing_message) {
-  EipStatus status = kEipStatusOk;
+EipStatus HandleReceivedExplictUdpData
+(
+  const int socket,
+  const struct sockaddr_in *from_address,
+  const EipUint8 *buffer,
+  const size_t buffer_length,
+  int *number_of_remaining_bytes,
+  bool unicast,
+  ENIPMessage *const outgoing_message)
+{
+  EipStatus return_value = kEipStatusOk;
   EncapsulationData encapsulation_data = { 0 };
   /* eat the encapsulation header*/
   /* the structure contains a pointer to the encapsulated data*/
@@ -256,7 +262,7 @@ int HandleReceivedExplictUdpData(const int socket,
     {
       /* full package or more received */
       encapsulation_data.status = kEncapsulationProtocolSuccess;
-      status = kEipStatusOkSend;
+      return_value = kEipStatusOkSend;
       /* most of these functions need a reply to be send */
       switch (encapsulation_data.command_code) {
         case (kEncapsulationCommandListServices):
@@ -275,8 +281,9 @@ int HandleReceivedExplictUdpData(const int socket,
                                                  from_address,
                                                  &encapsulation_data,
                                                  outgoing_message);
-            status = kEipStatusOk;
-          }                       /* as the response has to be delayed do not send it now */
+            /* as the response has to be delayed do not send it now */
+            return_value = kEipStatusOk;
+          }
           break;
 
         case (kEncapsulationCommandListInterfaces):
@@ -299,19 +306,14 @@ int HandleReceivedExplictUdpData(const int socket,
           encapsulation_data.data_length = 0;
           break;
       }
-
-      if (kEipStatusOk < status) {
-        /* if status is greater than 0 data has to be sent */
-        //status = EncapsulateData(&encapsulation_data);
-      }
     }
   }
-  return outgoing_message->used_message_length;
+  return return_value;
 }
 
 void SkipEncapsulationHeader(ENIPMessage *const outgoing_message) {
   MoveMessageNOctets(ENCAPSULATION_HEADER_LENGTH,
-                     &outgoing_message->current_message_position);
+                     (const CipOctet **)&outgoing_message->current_message_position);
 }
 
 void GenerateEncapsulationHeader(const EncapsulationData *const receive_data,
@@ -613,11 +615,13 @@ void HandleReceivedRegisterSessionCommand(int socket,
 
 }
 
-/*   TODO: Update and doxyfy
- * INT8 UnregisterSession(struct S_Encapsulation_Data *pa_S_ReceiveData)
- *   close all corresponding TCP connections and delete session handle.
- *      pa_S_ReceiveData pointer to unregister session request with corresponding socket handle.
- */
+/** @brief Unregister encapsulation session
+* @param receive_data Pointer to structure with data and header information.
+* @param outgoing_message The outgoing ENIP message
+* @return kEipStatusOkSend: a response needs to be sent, others: EIP stack status
+*
+* Close all corresponding TCP connections and delete session handle.
+*/
 EipStatus HandleReceivedUnregisterSessionCommand(
   const EncapsulationData *const receive_data,
   ENIPMessage *const outgoing_message) {
@@ -653,6 +657,7 @@ EipStatus HandleReceivedSendUnitDataCommand(
   const struct sockaddr *const originator_address,
   ENIPMessage *const outgoing_message) {
   EipStatus return_value = kEipStatusOkSend;
+  /*EipStatus*/ return_value = kEipStatusOk;    /* TODO: Shouldn't this be kEipStatusOk cause we must not send any response if data_length < 6? */
 
   if (receive_data->data_length >= 6) {
     /* Command specific data UDINT .. Interface Handle, UINT .. Timeout, CPF packets */
@@ -665,16 +670,9 @@ EipStatus HandleReceivedSendUnitDataCommand(
 
     if (kSessionStatusValid == CheckRegisteredSessions(receive_data) )            /* see if the EIP session is registered*/
     {
-      EipInt16 send_size =
-        NotifyConnectedCommonPacketFormat(receive_data,
-                                          originator_address,
-                                          outgoing_message);
-
-      return_value = send_size;
-
-      if (send_size < 0) {                   /* need to send reply */
-        return_value = kEipStatusError;
-      }
+      return_value = NotifyConnectedCommonPacketFormat(receive_data,
+                                                       originator_address,
+                                                       outgoing_message);
     } else {             /* received a package with non registered session handle */
       InitializeENIPMessage(outgoing_message);
       GenerateEncapsulationHeader(receive_data,
@@ -682,6 +680,7 @@ EipStatus HandleReceivedSendUnitDataCommand(
                                   receive_data->session_handle,
                                   kEncapsulationProtocolInvalidSessionHandle,
                                   outgoing_message);
+      return_value = kEipStatusOkSend;  /* TODO: Needs to be here if line with first TODO of this function is adjusted. */
     }
   }
   return return_value;
@@ -692,6 +691,7 @@ EipStatus HandleReceivedSendUnitDataCommand(
  *  @param originator_address Address of the originator as received from socket
  *  @param outgoing_message The outgoing ENIP message
  *  @return status      kEipStatusOk .. success.
+ *                      kEipStatusOkSend .. success & need to send response
  *                      kEipStatusError .. error
  */
 EipStatus HandleReceivedSendRequestResponseDataCommand(
@@ -699,6 +699,7 @@ EipStatus HandleReceivedSendRequestResponseDataCommand(
   const struct sockaddr *const originator_address,
   ENIPMessage *const outgoing_message) {
   EipStatus return_value = kEipStatusOkSend;
+  /* EipStatus*/ return_value = kEipStatusOk;   /* TODO: Shouldn't this be kEipStatusOk cause we must not send any response if data_length < 6? */
 
   if (receive_data->data_length >= 6) {
     /* Command specific data UDINT .. Interface Handle, UINT .. Timeout, CPF packets */
@@ -711,15 +712,9 @@ EipStatus HandleReceivedSendRequestResponseDataCommand(
 
     if (kSessionStatusValid == CheckRegisteredSessions(receive_data) )            /* see if the EIP session is registered*/
     {
-      EipInt16 send_size =
-        NotifyCommonPacketFormat(receive_data,
-                                 originator_address,
-                                 outgoing_message);
-      return_value = send_size;
-
-      if (send_size < 0) {                   /* need to send reply */
-        return_value = kEipStatusError;
-      }
+      return_value = NotifyCommonPacketFormat(receive_data,
+                                              originator_address,
+                                              outgoing_message);
     } else {             /* received a package with non registered session handle */
       InitializeENIPMessage(outgoing_message);
       GenerateEncapsulationHeader(receive_data,
@@ -727,6 +722,7 @@ EipStatus HandleReceivedSendRequestResponseDataCommand(
                                   receive_data->session_handle,
                                   kEncapsulationProtocolInvalidSessionHandle,
                                   outgoing_message);
+      return_value = kEipStatusOkSend;  /* TODO: Needs to be here if line with first TODO of this function is adjusted. */
     }
   }
   return return_value;
@@ -742,7 +738,7 @@ EipStatus HandleReceivedInvalidCommand(
                               receive_data->session_handle,
                               kEncapsulationProtocolInvalidCommand,
                               outgoing_message);
-  return outgoing_message->used_message_length;
+  return kEipStatusOkSend;
 
 }
 
@@ -880,7 +876,8 @@ void CloseEncapsulationSessionBySockAddr(
       struct sockaddr_in encapsulation_session_addr = { 0 };
       socklen_t addrlength = sizeof(encapsulation_session_addr);
       if (getpeername(g_registered_sessions[i],
-                      &encapsulation_session_addr, &addrlength) < 0) {                   /* got error */
+                      (struct sockaddr *)&encapsulation_session_addr,
+                      &addrlength) < 0) {                   /* got error */
         int error_code = GetSocketErrorNumber();
         char *error_message = GetErrorMessage(error_code);
         OPENER_TRACE_ERR(

+ 28 - 22
source/src/opener_api.h

@@ -156,8 +156,8 @@ CipClass *CreateCipClass( const EipUint32 class_id,
 /** @ingroup CIP_API
  * @brief Add a number of CIP instances to a given CIP class
  *
- * The required number of instances are created in a block, but are attached to
- * the class as a linked list.
+ * The required number of instances are attached to the class as a linked list.
+ *
  * The instances are numbered sequentially -- i.e. the first node in the chain
  * is instance 1, the second is 2, and so on.
  * You can add new instances at any time (you do not have to create all the
@@ -188,6 +188,7 @@ CipInstance *AddCipInstances(
 CipInstance *AddCIPInstance(CipClass *RESTRICT const cip_class_to_add_instance,
                             const EipUint32 instance_id);
 
+
 /** @ingroup CIP_API
  * @brief Insert an attribute in an instance of a CIP class
  *
@@ -201,14 +202,13 @@ CipInstance *AddCIPInstance(CipClass *RESTRICT const cip_class_to_add_instance,
  *  @param cip_data Pointer to data of attribute.
  *  @param cip_flags Flags to indicate set-ability and get-ability of attribute.
  */
-
-
-
 void InsertAttribute(CipInstance *const cip_instance,
                      const EipUint16 attribute_number,
                      const EipUint8 cip_data_type,
                      void *const cip_data,
                      const EipByte cip_flags);
+
+
 /** @ingroup CIP_API
  * @brief Allocates Attribute bitmasks
  *
@@ -433,14 +433,17 @@ void ConfigureListenOnlyConnectionPoint(
  * over after we're done here
  * @param originator_address Address struct of the message originator
  * @param outgoing_message The outgoing ENIP message
- * @return length of reply that need to be sent back
+ * @return kEipStatusOkSend: a response needs to be sent, others: EIP stack status
  */
-int HandleReceivedExplictTcpData(int socket_handle,
-                                 EipUint8 *buffer,
-                                 size_t length,
-                                 int *number_of_remaining_bytes,
-                                 struct sockaddr *originator_address,
-                                 ENIPMessage *const outgoing_message);
+EipStatus HandleReceivedExplictTcpData
+(
+  int socket_handle,
+  EipUint8 *buffer,
+  size_t length,
+  int *number_of_remaining_bytes,
+  struct sockaddr *originator_address,
+  ENIPMessage *const outgoing_message);
+
 
 /** @ingroup CIP_API
  * @brief Notify the encapsulation layer that an explicit message has been
@@ -453,17 +456,20 @@ int HandleReceivedExplictTcpData(int socket_handle,
  * @param buffer_length length of the data in buffer.
  * @param number_of_remaining_bytes return how many bytes of the input are left
  * over after we're done here
- * @param unicast Was the data receieved from a multicast address
+ * @param unicast Was the data received as unicast message?
  * @param outgoing_message Outgoing ENIP message
- * @return length of reply that need to be sent back
- */
-int HandleReceivedExplictUdpData(const int socket_handle,
-                                 const struct sockaddr_in *from_address,
-                                 const EipUint8 *buffer,
-                                 const size_t buffer_length,
-                                 int *number_of_remaining_bytes,
-                                 bool unicast,
-                                 ENIPMessage *const outgoing_message);
+ * @return kEipStatusOkSend: a response needs to be sent, others: EIP stack status
+ */
+EipStatus HandleReceivedExplictUdpData
+(
+  const int socket_handle,
+  const struct sockaddr_in *from_address,
+  const EipUint8 *buffer,
+  const size_t buffer_length,
+  int *number_of_remaining_bytes,
+  bool unicast,
+  ENIPMessage *const outgoing_message);
+
 
 /** @ingroup CIP_API
  *  @brief Notify the connection manager that data for a connection has been

+ 7 - 7
source/src/ports/generic_networkhandler.c

@@ -493,7 +493,7 @@ void CheckAndHandleUdpGlobalBroadcastSocket(void) {
     do {
       ENIPMessage outgoing_message;
       InitializeENIPMessage(&outgoing_message);
-      int reply_length = HandleReceivedExplictUdpData(
+      EipStatus need_to_send = HandleReceivedExplictUdpData(
         g_network_status.udp_global_broadcast_listener,
         &from_address,
         receive_buffer,
@@ -505,7 +505,7 @@ void CheckAndHandleUdpGlobalBroadcastSocket(void) {
       receive_buffer += received_size - remaining_bytes;
       received_size = remaining_bytes;
 
-      if (reply_length > 0) {
+      if (need_to_send > 0) {
         OPENER_TRACE_INFO("UDP broadcast reply sent:\n");
 
         /* if the active socket matches a registered UDP callback, handle a UDP packet */
@@ -513,7 +513,7 @@ void CheckAndHandleUdpGlobalBroadcastSocket(void) {
                     (char *) outgoing_message.message_buffer,
                     outgoing_message.used_message_length, 0,
                     (struct sockaddr *) &from_address, sizeof(from_address) )
-            != reply_length) {
+            != outgoing_message.used_message_length) {
           OPENER_TRACE_INFO(
             "networkhandler: UDP response was not fully sent\n");
         }
@@ -558,14 +558,14 @@ void CheckAndHandleUdpUnicastSocket(void) {
     ENIPMessage outgoing_message;
     InitializeENIPMessage(&outgoing_message);
     do {
-      int reply_length = HandleReceivedExplictUdpData(
+      EipStatus need_to_send = HandleReceivedExplictUdpData(
         g_network_status.udp_unicast_listener, &from_address, receive_buffer,
         received_size, &remaining_bytes, true, &outgoing_message);
 
       receive_buffer += received_size - remaining_bytes;
       received_size = remaining_bytes;
 
-      if (reply_length > 0) {
+      if (need_to_send > 0) {
         OPENER_TRACE_INFO("UDP unicast reply sent:\n");
 
         /* if the active socket matches a registered UDP callback, handle a UDP packet */
@@ -573,7 +573,7 @@ void CheckAndHandleUdpUnicastSocket(void) {
                     (char *) outgoing_message.message_buffer,
                     outgoing_message.used_message_length, 0,
                     (struct sockaddr *) &from_address, sizeof(from_address) )
-            != reply_length) {
+            != outgoing_message.used_message_length) {
           OPENER_TRACE_INFO(
             "networkhandler: UDP unicast response was not fully sent\n");
         }
@@ -786,7 +786,7 @@ EipStatus HandleDataOnTcpSocket(int socket) {
 
     ENIPMessage outgoing_message = {0};
     InitializeENIPMessage(&outgoing_message);
-    int need_to_send = HandleReceivedExplictTcpData(
+    EipStatus need_to_send = HandleReceivedExplictTcpData(
       socket, incoming_message, data_size, &remaining_bytes,
       &sender_address, &outgoing_message);
     SocketTimer *socket_timer = SocketTimerArrayGetSocketTimer(