Pārlūkot izejas kodu

Fix for issue#180. Following are done as part of fix:
- Modified DetermineDelayTime() formula to compute delay. The computed delay would be between 0 to default 90% maximum_delay_time sent by requester
- Modified HandleReceivedListIdentityCommandUdp() & ManageEncapsulationMessages to store and send delayed ListIdentity response message respectively

Sharifuddin Amin 6 gadi atpakaļ
vecāks
revīzija
39f4808d67
1 mainītis faili ar 27 papildinājumiem un 13 dzēšanām
  1. 27 13
      source/src/enet_encap/encap.c

+ 27 - 13
source/src/enet_encap/encap.c

@@ -42,6 +42,17 @@ const int kEncapsulationHeaderSessionHandlePosition = 4; /**< the position of th
 const int kListIdentityDefaultDelayTime = 2000; /**< Default delay time for List Identity response */
 const int kListIdentityMinimumDelayTime = 500; /**< Minimum delay time for List Identity response */
 
+/**< Default trasmit time for List Identity response */
+/* Transmit buffer time (set to default 90%, application can change as per their usecase). 
+ * This is done to ensure that the response is received to sender within 
+ * the maximum_delay_time sent by the requester.
+ * While computing the response delay time, 90% of maximum_delay_time is taken.
+ * So, max computed delay would be 90% of maximum_delay_time requester has sent.
+ * In case we set it to 100% then max computed delay can be 1200ms for a request having 1200ms max delay
+ * and in that case sender would receive response >= 1200ms which might be rejected by the sender
+ */
+const int kListIdentityDelayXmitBuffer  = 90;
+
 typedef enum {
   kSessionStatusInvalid = -1, kSessionStatusValid = 0
 } SessionStatus;
@@ -77,8 +88,7 @@ typedef struct {
   EipInt32 time_out;       /**< time out in milli seconds */
   int socket;       /**< associated socket */
   struct sockaddr_in receiver;
-  EipByte message[ENCAP_MAX_DELAYED_ENCAP_MESSAGE_SIZE];
-  size_t message_size;
+  ENIPMessage outgoing_message;
 } DelayedEncapsulationMessage;
 
 EncapsulationInterfaceInformation g_interface_information;
@@ -407,11 +417,15 @@ void HandleReceivedListIdentityCommandUdp(const int socket,
                                           const EncapsulationData *const receive_data,
                                           ENIPMessage *const outgoing_message) {
   DelayedEncapsulationMessage *delayed_message_buffer = NULL;
+  ENIPMessage* p_outgoing_message = NULL;
 
   for (size_t i = 0; i < ENCAP_NUMBER_OF_SUPPORTED_DELAYED_ENCAP_MESSAGES;
        i++) {
     if (kEipInvalidSocket == g_delayed_encapsulation_messages[i].socket) {
       delayed_message_buffer = &(g_delayed_encapsulation_messages[i]);
+
+      p_outgoing_message = &(delayed_message_buffer->outgoing_message);
+      InitializeENIPMessage(p_outgoing_message);
       break;
     }
   }
@@ -424,12 +438,7 @@ void HandleReceivedListIdentityCommandUdp(const int socket,
     DetermineDelayTime(receive_data->communication_buffer_start,
                        delayed_message_buffer);
 
-    memcpy(&(delayed_message_buffer->message[0]),
-           receive_data->communication_buffer_start,
-           ENCAPSULATION_HEADER_LENGTH);
-
-    EncapsulateListIdentityResponseMessage(
-      receive_data, outgoing_message);
+    EncapsulateListIdentityResponseMessage(receive_data, p_outgoing_message);
   }
 }
 
@@ -523,7 +532,11 @@ void DetermineDelayTime(const EipByte *const buffer_start,
   } else if (kListIdentityMinimumDelayTime > maximum_delay_time) {       /* if maximum_delay_time is between 1 and 500ms set it to 500ms */
     maximum_delay_time = kListIdentityMinimumDelayTime;
   }
-  delayed_message_buffer->time_out = (maximum_delay_time * rand() ) / RAND_MAX;      /* Sets delay time between 0 and maximum_delay_time */
+  /* Sets delay time between 0 and 90% of maximum_delay_time */
+  /* 90% is taken to have some room for response to reach the requester 
+   * within maximum_delay_time sent by requester
+   */
+  delayed_message_buffer->time_out = rand() % ((maximum_delay_time * kListIdentityDelayXmitBuffer)/100);
 }
 
 void EncapsulateRegisterSessionCommandResponseMessage(
@@ -861,10 +874,11 @@ void ManageEncapsulationMessages(const MilliSeconds elapsed_time) {
       g_delayed_encapsulation_messages[i].time_out -= elapsed_time;
       if (0 >= g_delayed_encapsulation_messages[i].time_out) {
         /* If delay is reached or passed, send the UDP message */
-        SendUdpData(&(g_delayed_encapsulation_messages[i].receiver),
-                    g_delayed_encapsulation_messages[i].socket,
-                    &(g_delayed_encapsulation_messages[i].message[0]),
-                    g_delayed_encapsulation_messages[i].message_size);
+        sendto(g_delayed_encapsulation_messages[i].socket,
+                    (char *) g_delayed_encapsulation_messages[i].outgoing_message.message_buffer,
+                    g_delayed_encapsulation_messages[i].outgoing_message.used_message_length, 0,
+                    (struct sockaddr *) &(g_delayed_encapsulation_messages[i].receiver), 
+                    sizeof(struct sockaddr));
         g_delayed_encapsulation_messages[i].socket = kEipInvalidSocket;
       }
     }