Эх сурвалжийг харах

Fix: Rejected Listen Only Connection even if another IO Connection exists

OpENer rejected to open a Listen Only Connection even if another IO
connection existed because it looked only for Multicast connections and
ignored existing Point-To-Point connections.

Looking at the table 3-6.2 in Vol. 1 Section 3-6.3 it can be derived that
the establishment of a new Listen Only connection should succeed for both
cases (existing connection in Multicast or Point-to-Point mode).

Renamed the function GetExistingProducerMulticastConnection() to
GetExistingProducerIoConnection() and provided a parameter that controls
if it should look for Multicast connections only or return also
Point-To-Point connections. Adjusted the use of the function accordingly.

Signed-off-by: Stefan Mätje <stefan.maetje@esd.eu>
Stefan Mätje 6 жил өмнө
parent
commit
f2b8fd90a4

+ 22 - 17
source/src/cip/appcontype.c

@@ -293,9 +293,10 @@ CipConnectionObject *GetListenOnlyConnection(
         break;
       }
 
-      if ( NULL
-           == GetExistingProducerMulticastConnection(
-             connection_object->produced_path.instance_id) ) {
+      /* Here we look for both Point-to-Point and Multicast IO connections */
+      if ( NULL == GetExistingProducerIoConnection(false,
+             connection_object->produced_path.instance_id) )
+      {
         *extended_error =
           kConnectionManagerExtendedStatusCodeNonListenOnlyConnectionNotOpened;
         break;
@@ -333,27 +334,31 @@ CipConnectionObject *GetListenOnlyConnection(
   return NULL;
 }
 
-CipConnectionObject *GetExistingProducerMulticastConnection(
+CipConnectionObject *GetExistingProducerIoConnection(
+  const bool multicast_only,
   const EipUint32 input_point) {
   DoublyLinkedListNode *node = connection_list.first;
 
   while (NULL != node) {
-    CipConnectionObject *producer_multicast_connection = node->data;
-    if ( true ==
-         ConnectionObjectIsTypeIOConnection(producer_multicast_connection) &&
-         (input_point ==
-          producer_multicast_connection->produced_path.instance_id) &&
-         ( kConnectionObjectConnectionTypeMulticast ==
-           ConnectionObjectGetTToOConnectionType(producer_multicast_connection) )
-         &&
-         (kEipInvalidSocket !=
-          producer_multicast_connection->socket[
-            kUdpCommuncationDirectionProducing]) )
+    CipConnectionObject *producer_io_connection = node->data;
+    if (ConnectionObjectIsTypeIOConnection(producer_io_connection) &&
+        (input_point == producer_io_connection->produced_path.instance_id) &&
+        (kEipInvalidSocket !=
+         producer_io_connection->socket[kUdpCommuncationDirectionProducing]) )
     {
+      ConnectionObjectConnectionType cnxn_type =
+        ConnectionObjectGetTToOConnectionType(producer_io_connection);
       /* we have a connection that produces the same input assembly,
-       * is a multicast producer and manages the connection.
+       * and manages the connection.
        */
-      return producer_multicast_connection;
+      if (kConnectionObjectConnectionTypeMulticast == cnxn_type) {
+        return producer_io_connection;
+      }
+      if (!multicast_only &&
+          kConnectionObjectConnectionTypePointToPoint == cnxn_type)
+      {
+        return producer_io_connection;
+      }
     }
     node = node->next;
   }

+ 5 - 3
source/src/cip/appcontype.h

@@ -30,10 +30,12 @@ CipConnectionObject *GetIoConnectionForConnectionData(
 /** @brief Check if there exists already an exclusive owner or listen only connection
  *         which produces the input assembly.
  *
- *  @param input_point the Input point to be produced
- *  @return if a connection could be found a pointer to this connection if not NULL
+ *  @param  multicast_only  Look only for multi-cast connections
+ *  @param  input_point     the Input point to be produced
+ *  @return   a pointer to the found connection; NULL if nothing found
  */
-CipConnectionObject *GetExistingProducerMulticastConnection(
+CipConnectionObject *GetExistingProducerIoConnection(
+  const bool multicast_only,
   const EipUint32 input_point);
 
 /** @brief check if there exists an producing multicast exclusive owner or

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

@@ -447,8 +447,9 @@ EipStatus OpenProducingMulticastConnection(
   CipConnectionObject *connection_object,
   CipCommonPacketFormatData *common_packet_format_data
   ) {
+  /* Here we look for existing multi-cast IO connections only. */
   CipConnectionObject *existing_connection_object =
-    GetExistingProducerMulticastConnection(
+    GetExistingProducerIoConnection(true,
       connection_object->produced_path.instance_id);
 
   int j = 0; /* allocate an unused sockaddr struct to use */