Ver código fonte

Connect NV data support for TCP/IP object (dummy implementation atm. only)

This adds and connects routines to load and store NV data for the TCP/IP
object. At the moment the load and store routines are only skeletons that
don't do real file IO.

This patch also adds a first implementation of functions to set CIP strings
from various sources.

Signed-off-by: Stefan Mätje <stefan.maetje@esd.eu>
Stefan Mätje 6 anos atrás
pai
commit
5782f7c7c8

+ 1 - 1
source/src/cip/CMakeLists.txt

@@ -12,7 +12,7 @@ opener_common_includes()
 #######################################
 opener_platform_support("INCLUDES")
 
-set( CIP_SRC appcontype.c cipassembly.c cipclass3connection.c cipcommon.c cipconnectionobject.c cipconnectionmanager.c ciperror.h cipethernetlink.c cipidentity.c cipioconnection.c cipmessagerouter.c ciptcpipinterface.c ciptypes.h cipepath.h cipepath.c cipelectronickey.h cipelectronickey.c cipqos.c )
+set( CIP_SRC appcontype.c cipassembly.c cipclass3connection.c cipcommon.c cipconnectionobject.c cipconnectionmanager.c ciperror.h cipethernetlink.c cipidentity.c cipioconnection.c cipmessagerouter.c ciptcpipinterface.c ciptypes.h cipepath.c cipelectronickey.c cipstring.c cipqos.c )
 
 add_library( CIP ${CIP_SRC} )
 

+ 100 - 0
source/src/cip/cipstring.c

@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * Copyright (c) 2019, Rockwell Automation, Inc.
+ * All rights reserved.
+ *
+ ******************************************************************************/
+
+/** @file
+ * @brief Implements functions to operate on CIP string types
+ *
+ * Some functions to create CIP string types from C strings or data buffers.
+ */
+
+#include "cipstring.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "opener_api.h"
+
+
+CipString *SetCipStringByData
+(
+   CipString *p_cip_string,
+   size_t str_len,
+   const EipUint8 *p_data
+)
+{
+    CipString   *p_result = p_cip_string;
+
+    if (NULL != p_cip_string->string) {
+        CipFree(p_cip_string->string);
+        p_cip_string->string = NULL;
+        p_cip_string->length = 0;
+    }
+
+    if (str_len) {
+        /* Allocate & clear +1 bytes for the trailing '\0' character. */
+        p_cip_string->string = CipCalloc(str_len+1, sizeof (EipUint8));
+        if (NULL == p_cip_string->string) {
+            p_result = NULL;
+        }
+        else {
+            p_cip_string->length = str_len;
+            memcpy(p_cip_string->string, p_data, str_len);
+        }
+    }
+    return p_result;
+}
+
+
+CipString *SetCipStringByCstr
+(
+  CipString *p_cip_string,
+  const char *p_string
+)
+{
+    return SetCipStringByData(p_cip_string, strlen(p_string),
+                              (const EipByte *)p_string);
+}
+
+
+CipShortString *SetCipShortStringByData
+(
+   CipShortString *p_cip_string,
+   size_t str_len,
+   const EipUint8 *p_data
+)
+{
+    CipShortString   *p_result = p_cip_string;
+
+    if (NULL != p_cip_string->string) {
+        CipFree(p_cip_string->string);
+        p_cip_string->string = NULL;
+        p_cip_string->length = 0;
+    }
+
+    if (str_len) {
+        /* Allocate & clear +1 bytes for the trailing '\0' character. */
+        p_cip_string->string = CipCalloc(str_len+1, sizeof (EipUint8));
+        if (NULL == p_cip_string->string) {
+            p_result = NULL;
+        }
+        else {
+            p_cip_string->length = str_len;
+            memcpy(p_cip_string->string, p_data, str_len);
+        }
+    }
+    return p_result;
+}
+
+
+CipShortString *SetCipShortStringByCstr
+(
+  CipShortString *p_cip_string,
+  const char *p_string
+)
+{
+    return SetCipShortStringByData(p_cip_string, strlen(p_string),
+                              (const EipByte *)p_string);
+}

+ 46 - 0
source/src/cip/cipstring.h

@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2019, Rockwell Automation, Inc.
+ * All rights reserved.
+ *
+ ******************************************************************************/
+
+/** @file
+ * @brief Declare functions to operate on CIP string types
+ *
+ * Some functions to create CIP string types from C strings or data buffers.
+ */
+
+#ifndef OPENER_CIPSTRING_H_
+#define OPENER_CIPSTRING_H_
+
+#include "typedefs.h"
+#include "ciptypes.h"
+
+
+CipString *SetCipStringByData
+(
+   CipString *p_cip_string,
+   size_t str_len,
+   const EipUint8 *p_data
+);
+
+CipString *SetCipStringByCstr
+(
+  CipString *p_cip_string,
+  const char *p_string
+);
+
+CipShortString *SetCipShortStringByData
+(
+   CipShortString *p_cip_string,
+   size_t str_len,
+   const EipUint8 *p_data
+);
+
+CipShortString *SetCipShortStringByCstr
+(
+  CipShortString *p_cip_string,
+  const char *p_string
+);
+
+#endif /* of OPENER_CIPSTRING_H_ */

+ 3 - 0
source/src/ports/MINGW/sample_application/sampleapplication.c

@@ -71,6 +71,9 @@ EipStatus ApplicationInitialization(void) {
    */
   InsertGetSetCallback(GetCipClass(kCipQoSClassCode), NvQosSetCallback,
                        kNvDataFunc);
+  InsertGetSetCallback(GetCipClass(kCipTcpIpInterfaceClassCode),
+                       NvTcpipSetCallback(),
+                       kNvDataFunc);
 
   return kEipStatusOk;
 }

+ 3 - 0
source/src/ports/POSIX/sample_application/sampleapplication.c

@@ -74,6 +74,9 @@ EipStatus ApplicationInitialization(void) {
    */
   InsertGetSetCallback(GetCipClass(kCipQoSClassCode), NvQosSetCallback,
                        kNvDataFunc);
+  InsertGetSetCallback(GetCipClass(kCipTcpIpInterfaceClassCode),
+                       NvTcpipSetCallback,
+                       kNvDataFunc);
 
   return kEipStatusOk;
 }

+ 3 - 0
source/src/ports/WIN32/sample_application/sampleapplication.c

@@ -70,6 +70,9 @@ EipStatus ApplicationInitialization(void) {
    */
   InsertGetSetCallback(GetCipClass(kCipQoSClassCode), NvQosSetCallback,
                        kNvDataFunc);
+  InsertGetSetCallback(GetCipClass(kCipTcpIpInterfaceClassCode),
+                       NvTcpipSetCallback(),
+                       kNvDataFunc);
 
   return kEipStatusOk;
 }

+ 1 - 1
source/src/ports/nvdata/CMakeLists.txt

@@ -2,7 +2,7 @@
 # Non Volatile data storage library   #
 #######################################
 
-set( NVDATA_SRC nvdata.c conffile.c nvqos.c )
+set( NVDATA_SRC nvdata.c conffile.c nvqos.c nvtcpip.c )
 
 #######################################
 # Add common includes                 #

+ 33 - 0
source/src/ports/nvdata/nvdata.c

@@ -18,6 +18,7 @@
 
 /* Include headers of objects that need support for NV data here. */
 #include "nvqos.h"
+#include "nvtcpip.h"
 
 /** @brief Load NV data for all object classes
  *
@@ -78,3 +79,35 @@ EipStatus NvQosSetCallback
   }
   return status;
 }
+
+/** A PostSetCallback for TCP/IP class to store NV attributes
+*
+* @param  instance  pointer to instance of TCP/IP class
+* @param  attribute pointer to attribute structure
+* @param  service   the CIP service code of current request
+*
+* This function implements the PostSetCallback for the TCP/IP class. The
+* purpose of this function is to save the NV attributes of the TCP/IP
+* class instance to external storage.
+*
+* This application specific implementation chose to save all attributes
+* at once using a single NvTcpipStore() call.
+*/
+EipStatus NvTcpipSetCallback
+(
+    CipInstance *const instance,
+    CipAttributeStruct *const attribute,
+    CipByte service
+)
+{
+    EipStatus status = kEipStatusOk;
+
+    if (0 != (kNvDataFunc & attribute->attribute_flags)) {
+        OPENER_TRACE_INFO("NV data update: %s, i %" PRIu32 ", a %" PRIu16 "\n",
+                          instance->cip_class->class_name,
+                          instance->instance_number,
+                          attribute->attribute_number);
+        status = NvTcpipStore(&g_tcpip);
+    }
+    return status;
+}

+ 7 - 0
source/src/ports/nvdata/nvdata.h

@@ -24,4 +24,11 @@ EipStatus NvQosSetCallback
   CipByte service
 );
 
+EipStatus NvTcpipSetCallback
+(
+    CipInstance *const instance,
+    CipAttributeStruct *const attribute,
+    CipByte service
+);
+
 #endif  /* ifndef NVDATA_H_ */

+ 77 - 0
source/src/ports/nvdata/nvtcpip.c

@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2019, Rockwell Automation, Inc.
+ * All rights reserved.
+ *
+ ******************************************************************************/
+
+/** @file nvtcpip.c
+ *  @brief This file implements the functions to handle TCP/IP object's NV data.
+ *
+ *  This is only a code skeleton. The real load and store operation is NOT
+ *  implemented.
+ */
+#include "nvtcpip.h"
+
+// #include <inttypes.h>
+// #include <stdio.h>
+#include <string.h>
+
+#include "trace.h"
+
+#include "conffile.h"
+
+#define TCPIP_CFG_NAME  "tcpip.cfg" /**< Name of the configuration file */
+
+
+/** @brief Load NV data of the TCP/IP object from file
+ *
+ *  @param  p_qos pointer to the TCP/IP object's data structure
+ *  @return       0: success; -1: failure
+ */
+int NvTcpipLoad(CipTcpIpObject *p_tcp_ip)
+{
+  CipTcpIpObject  tcpip;
+  FILE  *p_file;
+  int   rc;
+
+  memset(&tcpip, 0, sizeof tcpip);
+  rc = ConfFileOpen(false, TCPIP_CFG_NAME, &p_file);
+  if (0 == rc) {
+    /* Read input data */
+    OPENER_TRACE_ERR("ERROR: Loading of TCP/IP object's NV data not implemented yet\n");
+    /* TODO: Implement load */
+    rc = kEipStatusError;
+
+    /* Need to try to close all stuff in any case. */
+    rc = ConfFileClose(&p_file);
+  }
+  if (0 == rc) {
+    /* If all NV attributes were read copy them attribute by attribute
+     * to the caller's TCP/IP object. */
+    /* TODO: copy all NV attributes */
+  }
+  return rc;
+}
+
+/** @brief Store NV data of the TCP/IP object to file
+ *
+ *  @param  p_qos pointer to the TCP/IP object's data structure
+ *  @return       0: success; -1: failure
+ */
+int NvTcpipStore(const CipTcpIpObject *p_tcp_ip)
+{
+  FILE  *p_file;
+  int   rc;
+
+  rc = ConfFileOpen(true, TCPIP_CFG_NAME, &p_file);
+  if (rc >= 0) {
+    /* Print output data */
+    OPENER_TRACE_ERR("ERROR: Storing of TCP/IP object's NV data not implemented yet\n");
+    /* TODO: Implement store */
+    rc = kEipStatusError;
+
+    /* Need to try to close all stuff in any case. */
+    rc |= ConfFileClose(&p_file);
+  }
+  return rc;
+}

+ 22 - 0
source/src/ports/nvdata/nvtcpip.h

@@ -0,0 +1,22 @@
+/*******************************************************************************
+ * Copyright (c) 2019, Rockwell Automation, Inc.
+ * All rights reserved.
+ *
+ ******************************************************************************/
+
+/** @file nvtcpip.h
+ *  @brief This file provides the interface to handle TCP/IP object's NV data.
+ *
+ */
+#ifndef _NVTCPIP_H_
+#define _NVTCPIP_H_
+
+#include "typedefs.h"
+
+#include "ciptcpipinterface.h"
+
+int NvTcpipLoad(CipTcpIpObject *p_tcp_ip);
+
+int NvTcpipStore(const CipTcpIpObject *p_tcp_ip);
+
+#endif  /* _NVTCPIP_H_ */