From 753fa743d63a1e9e6496ee07248cd4d14f744ccc Mon Sep 17 00:00:00 2001 From: Vincent Prince Date: Sat, 23 May 2020 11:17:13 +0200 Subject: [PATCH 1/3] Add Large Forward Open service Signed-off-by: Vincent Prince --- source/src/cip/cipconnectionmanager.c | 42 ++++- source/src/cip/cipconnectionobject.c | 144 +++++++++++++----- source/src/cip/cipconnectionobject.h | 13 +- source/src/cip/ciptypes.h | 1 + .../sample_application/opener_user_conf.h | 2 +- 5 files changed, 161 insertions(+), 41 deletions(-) diff --git a/source/src/cip/cipconnectionmanager.c b/source/src/cip/cipconnectionmanager.c index 40764f6695..42acecb5d1 100644 --- a/source/src/cip/cipconnectionmanager.c +++ b/source/src/cip/cipconnectionmanager.c @@ -30,6 +30,7 @@ const size_t g_kForwardOpenHeaderLength = 36; /**< the length in bytes of the forward open command specific data till the start of the connection path (including con path size)*/ +const size_t g_kLargeForwardOpenHeaderLength = 40; /**< the length in bytes of the large forward open command specific data till the start of the connection path (including con path size)*/ static const int g_kNumberOfConnectableObjects = 2 + OPENER_CIP_NUM_APPLICATION_SPECIFIC_CONNECTABLE_OBJECTS; @@ -61,6 +62,13 @@ EipStatus ForwardOpen( const struct sockaddr *originator_address, const int encapsulation_session); +EipStatus LargeForwardOpen( + CipInstance *instance, + CipMessageRouterRequest *message_router_request, + CipMessageRouterResponse *message_router_response, + const struct sockaddr *originator_address, + const int encapsulation_session); + EipStatus ForwardClose( CipInstance *instance, CipMessageRouterRequest *message_router_request, @@ -217,7 +225,7 @@ EipStatus ConnectionManagerInit(EipUint16 unique_connection_id) { 2, /* # of class services */ 0, /* # of instance attributes */ 14, /* # highest instance attribute number*/ - 5, /* # of instance services */ + 6, /* # of instance services */ 1, /* # of instances */ "connection manager", /* class name */ 1, /* revision */ @@ -230,6 +238,7 @@ EipStatus ConnectionManagerInit(EipUint16 unique_connection_id) { InsertService(connection_manager, kGetAttributeAll, &GetAttributeAll, "GetAttributeAll"); InsertService(connection_manager, kForwardOpen, &ForwardOpen, "ForwardOpen"); + InsertService(connection_manager, kLargeForwardOpen, &LargeForwardOpen, "LargeForwardOpen"); InsertService(connection_manager, kForwardClose, &ForwardClose, "ForwardClose"); InsertService(connection_manager, kGetConnectionOwner, &GetConnectionOwner, @@ -471,6 +480,21 @@ static const HandleForwardOpenRequestFunction HandleNullMatchingForwardOpenRequest } }; +/** @brief Check if resources for new connection available, generate ForwardOpen Reply message. + * + * Large Forward Open service calls Forward Open service + */ +EipStatus LargeForwardOpen( + CipInstance *instance, + CipMessageRouterRequest *message_router_request, + CipMessageRouterResponse *message_router_response, + const struct sockaddr *originator_address, + const int encapsulation_session + ) { + g_dummy_connection_object.is_large_forward_open = true; + return ForwardOpen(instance, message_router_request, message_router_response, originator_address, encapsulation_session); +} + /** @brief Check if resources for new connection available, generate ForwardOpen Reply message. * * Forward Open four cases @@ -768,7 +792,12 @@ EipStatus AssembleForwardOpenResponse( AddNullAddressItem(cip_common_packet_format_data); - message_router_response->reply_service = (0x80 | kForwardOpen); + CIPServiceCode service_code = kForwardOpen; + if (connection_object->is_large_forward_open) { + service_code = kLargeForwardOpen; + } + + message_router_response->reply_service = (0x80 | service_code); message_router_response->general_status = general_status; if (kCipErrorSuccess == general_status) { @@ -1081,14 +1110,19 @@ EipUint8 ParseConnectionPath( /* with 256 we mark that we haven't got a PIT segment */ ConnectionObjectSetProductionInhibitTime(connection_object, 256); - if ( (g_kForwardOpenHeaderLength + remaining_path * 2) + size_t header_length = g_kForwardOpenHeaderLength; + if (connection_object->is_large_forward_open) { + header_length = g_kLargeForwardOpenHeaderLength; + } + + if ( (header_length + remaining_path * 2) < message_router_request->request_path_size ) { /* the received packet is larger than the data in the path */ *extended_error = 0; return kCipErrorTooMuchData; } - if ( (g_kForwardOpenHeaderLength + remaining_path * 2) + if ( (header_length + remaining_path * 2) > message_router_request->request_path_size ) { /*there is not enough data in received packet */ *extended_error = 0; diff --git a/source/src/cip/cipconnectionobject.c b/source/src/cip/cipconnectionobject.c index 8d5ef20c69..618b24a2b0 100644 --- a/source/src/cip/cipconnectionobject.c +++ b/source/src/cip/cipconnectionobject.c @@ -44,13 +44,13 @@ #define CIP_CONNECTION_OBJECT_WATCHDOG_TIMEOUT_ACTION_DEFERRED_DELETE 3 #define CIP_CONNECTION_OBJECT_CONNECTION_TYPE_NULL 0 -#define CIP_CONNECTION_OBJECT_CONNECTION_TYPE_MULTICAST (1 << 13) -#define CIP_CONNECTION_OBJECT_CONNECTION_TYPE_POINT_TO_POINT (1 << 14) +#define CIP_CONNECTION_OBJECT_CONNECTION_TYPE_MULTICAST 1 +#define CIP_CONNECTION_OBJECT_CONNECTION_TYPE_POINT_TO_POINT 2 #define CIP_CONNECTION_OBJECT_PRIORITY_LOW 0 -#define CIP_CONNECTION_OBJECT_PRIORITY_HIGH (1 << 10) -#define CIP_CONNECTION_OBJECT_PRIORITY_SCHEDULED (1 << 11) -#define CIP_CONNECTION_OBJECT_PRIORITY_URGENT (3 << 10) +#define CIP_CONNECTION_OBJECT_PRIORITY_HIGH 1 +#define CIP_CONNECTION_OBJECT_PRIORITY_SCHEDULED 2 +#define CIP_CONNECTION_OBJECT_PRIORITY_URGENT 3 /** @brief Definition of the global connection list */ DoublyLinkedList connection_list; @@ -163,17 +163,26 @@ void ConnectionObjectInitializeFromMessage( ConnectionObjectSetInitialInactivityWatchdogTimerValue(connection_object); - //TODO: introduce setter function - connection_object->o_to_t_network_connection_parameters = GetIntFromMessage( - message); + if (connection_object->is_large_forward_open == true) { + ConnectionObjectSetOToTNetworkConnectionParameters(connection_object, + GetDintFromMessage(message) ); + } else { + ConnectionObjectSetOToTNetworkConnectionParameters(connection_object, + GetIntFromMessage(message) ); + } ConnectionObjectSetTToORequestedPacketInterval(connection_object, GetDintFromMessage(message) ); ConnectionObjectSetExpectedPacketRate(connection_object); - connection_object->t_to_o_network_connection_parameters = GetIntFromMessage( - message); + if (connection_object->is_large_forward_open == true) { + ConnectionObjectSetTToONetworkConnectionParameters(connection_object, + GetDintFromMessage(message) ); + } else { + ConnectionObjectSetTToONetworkConnectionParameters(connection_object, + GetIntFromMessage(message) ); + } connection_object->transport_class_trigger = GetSintFromMessage(message); } @@ -677,22 +686,56 @@ void ConnectionObjectSetTToORequestedPacketInterval( requested_packet_interval; } +void ConnectionObjectSetTToONetworkConnectionParameters( + CipConnectionObject *connection_object, + const CipDword connection_parameters) { + connection_object->t_to_o_network_connection_parameters = + connection_parameters; +} + +void ConnectionObjectSetOToTNetworkConnectionParameters( + CipConnectionObject *connection_object, + const CipDword connection_parameters) { + connection_object->o_to_t_network_connection_parameters = + connection_parameters; +} + +bool ConnectionObjectIsRedundantOwner( + const CipDword connection_parameters, + const CipBool is_lfo) { + if (is_lfo) { + return (connection_parameters & (1 << 31)); + } else { + return (connection_parameters & (1 << 15)); + } +} + bool ConnectionObjectIsOToTRedundantOwner( const CipConnectionObject *const connection_object) { - const CipWord kOwnerMask = 0x80; - return kOwnerMask & connection_object->o_to_t_network_connection_parameters; + return ConnectionObjectIsRedundantOwner( + connection_object->o_to_t_network_connection_parameters, + connection_object->is_large_forward_open); } bool ConnectionObjectIsTToORedundantOwner( const CipConnectionObject *const connection_object) { - const CipWord kOwnerMask = 0x80; - return kOwnerMask & connection_object->t_to_o_network_connection_parameters; + return ConnectionObjectIsRedundantOwner( + connection_object->t_to_o_network_connection_parameters, + connection_object->is_large_forward_open); } ConnectionObjectConnectionType ConnectionObjectGetConnectionType( - const CipWord connection_parameters) { - const CipWord kConnectionTypeMask = 3 << 13; - switch(connection_parameters & kConnectionTypeMask) { + const CipDword connection_parameters, + const CipBool is_lfo) { + + CipUsint connection_type; + if (is_lfo) { + connection_type = (connection_parameters & (3 << 29)) >> 29; + } else { + connection_type = (connection_parameters & (3 << 13)) >> 13; + } + + switch(connection_type) { case CIP_CONNECTION_OBJECT_CONNECTION_TYPE_NULL: return kConnectionObjectConnectionTypeNull; case CIP_CONNECTION_OBJECT_CONNECTION_TYPE_MULTICAST: return @@ -706,20 +749,30 @@ ConnectionObjectConnectionType ConnectionObjectGetConnectionType( ConnectionObjectConnectionType ConnectionObjectGetOToTConnectionType( const CipConnectionObject *const connection_object) { return ConnectionObjectGetConnectionType( - connection_object->o_to_t_network_connection_parameters); + connection_object->o_to_t_network_connection_parameters, + connection_object->is_large_forward_open); } ConnectionObjectConnectionType ConnectionObjectGetTToOConnectionType( const CipConnectionObject *const connection_object) { return ConnectionObjectGetConnectionType( - connection_object->t_to_o_network_connection_parameters); + connection_object->t_to_o_network_connection_parameters, + connection_object->is_large_forward_open); } ConnectionObjectPriority ConnectionObjectGetPriority( - const CipWord connection_parameters) { - const CipWord kPriorityMask = 3 << 10; + const CipDword connection_parameters, + const CipBool is_lfo) { + + CipUsint priority; + if (is_lfo) { + priority = (connection_parameters & (3 << 26)) >> 26; + } else { + priority = (connection_parameters & (3 << 10)) >> 10; + } + ConnectionObjectPriority result; - switch(connection_parameters & kPriorityMask) { + switch(priority) { case CIP_CONNECTION_OBJECT_PRIORITY_LOW: result = kConnectionObjectPriorityLow; break; case CIP_CONNECTION_OBJECT_PRIORITY_HIGH: result = @@ -738,20 +791,30 @@ ConnectionObjectPriority ConnectionObjectGetPriority( ConnectionObjectPriority ConnectionObjectGetOToTPriority( const CipConnectionObject *const connection_object) { return ConnectionObjectGetPriority( - connection_object->o_to_t_network_connection_parameters); + connection_object->o_to_t_network_connection_parameters, + connection_object->is_large_forward_open); } ConnectionObjectPriority ConnectionObjectGetTToOPriority( const CipConnectionObject *const connection_object) { return ConnectionObjectGetPriority( - connection_object->t_to_o_network_connection_parameters); + connection_object->t_to_o_network_connection_parameters, + connection_object->is_large_forward_open); } ConnectionObjectConnectionSizeType ConnectionObjectGetConnectionSizeType( - const CipWord connection_parameters) { - const CipWord kConnectionSizeTypeMask = 1 << 9; - if(connection_parameters & kConnectionSizeTypeMask) { + const CipDword connection_parameters, + const CipBool is_lfo) { + + bool connection_size_type; + if (is_lfo) { + connection_size_type = (connection_parameters & (1 << 25)); + } else { + connection_size_type = (connection_parameters & (1 << 9)); + } + + if (connection_size_type) { return kConnectionObjectConnectionSizeTypeVariable; } else { return kConnectionObjectConnectionSizeTypeFixed; @@ -761,30 +824,43 @@ ConnectionObjectConnectionSizeType ConnectionObjectGetConnectionSizeType( ConnectionObjectConnectionSizeType ConnectionObjectGetOToTConnectionSizeType( const CipConnectionObject *const connection_object) { return ConnectionObjectGetConnectionSizeType( - connection_object->o_to_t_network_connection_parameters); + connection_object->o_to_t_network_connection_parameters, + connection_object->is_large_forward_open); } ConnectionObjectConnectionSizeType ConnectionObjectGetTToOConnectionSizeType( const CipConnectionObject *const connection_object) { return ConnectionObjectGetConnectionSizeType( - connection_object->t_to_o_network_connection_parameters); + connection_object->t_to_o_network_connection_parameters, + connection_object->is_large_forward_open); } -size_t ConnectionObjectGetConnectionSize(const CipWord connection_parameters) { - const CipWord kConnectionSizeMask = 0x01FF; - return connection_parameters & kConnectionSizeMask; +size_t ConnectionObjectGetConnectionSize( + const CipDword connection_parameters, + const CipBool is_lfo) { + const CipDword kConnectionSizeMask = 0x000001FF; + const CipDword kConnectionSizeMaskLFO = 0x0000FFFF; + + CipDword mask = kConnectionSizeMask; + if (is_lfo) { + mask = kConnectionSizeMaskLFO; + } + + return connection_parameters & mask; } size_t ConnectionObjectGetOToTConnectionSize( const CipConnectionObject *const connection_object) { return ConnectionObjectGetConnectionSize( - connection_object->o_to_t_network_connection_parameters); + connection_object->o_to_t_network_connection_parameters, + connection_object->is_large_forward_open); } size_t ConnectionObjectGetTToOConnectionSize( const CipConnectionObject *const connection_object) { return ConnectionObjectGetConnectionSize( - connection_object->t_to_o_network_connection_parameters); + connection_object->t_to_o_network_connection_parameters, + connection_object->is_large_forward_open); } void ConnectionObjectDeepCopy( diff --git a/source/src/cip/cipconnectionobject.h b/source/src/cip/cipconnectionobject.h index 2e7c41d688..e8afbecf8f 100644 --- a/source/src/cip/cipconnectionobject.h +++ b/source/src/cip/cipconnectionobject.h @@ -145,10 +145,10 @@ struct cip_connection_object { CipUdint originator_serial_number; CipUdint o_to_t_requested_packet_interval; - CipWord o_to_t_network_connection_parameters; + CipDword o_to_t_network_connection_parameters; CipUdint t_to_o_requested_packet_interval; - CipWord t_to_o_network_connection_parameters; + CipDword t_to_o_network_connection_parameters; CipUint sequence_count_producing; /**< sequence Count for Class 1 Producing Connections */ @@ -189,6 +189,7 @@ struct cip_connection_object { ConnectionReceiveDataFunction connection_receive_data_function; ENIPMessage last_reply_sent; + CipBool is_large_forward_open; }; /** @brief Extern declaration of the global connection list */ @@ -388,6 +389,14 @@ void ConnectionObjectSetTToORequestedPacketInterval( CipConnectionObject *connection_object, const CipUdint requested_packet_interval); +void ConnectionObjectSetTToONetworkConnectionParameters( + CipConnectionObject *connection_object, + const CipDword connection_parameters); + +void ConnectionObjectSetOToTNetworkConnectionParameters( + CipConnectionObject *connection_object, + const CipDword connection_parameters); + bool ConnectionObjectIsTToORedundantOwner( const CipConnectionObject *const connection_object); diff --git a/source/src/cip/ciptypes.h b/source/src/cip/ciptypes.h index 367d8bde25..ce7b664e48 100644 --- a/source/src/cip/ciptypes.h +++ b/source/src/cip/ciptypes.h @@ -96,6 +96,7 @@ typedef enum { /* Start CIP object-specific services */ kEthLinkGetAndClear = 0x4C, /**< Ethernet Link object's Get_And_Clear service */ kForwardOpen = 0x54, + kLargeForwardOpen = 0x5B, kForwardClose = 0x4E, kUnconnectedSend = 0x52, kGetConnectionOwner = 0x5A diff --git a/source/src/ports/POSIX/sample_application/opener_user_conf.h b/source/src/ports/POSIX/sample_application/opener_user_conf.h index e00e277fea..4d71e0b8d0 100644 --- a/source/src/ports/POSIX/sample_application/opener_user_conf.h +++ b/source/src/ports/POSIX/sample_application/opener_user_conf.h @@ -220,6 +220,6 @@ static const MilliSeconds kOpenerTimerTickInMilliSeconds = 10; * This buffer size will be used for any received message. * The same buffer is used for the replied explicit message. */ -#define PC_OPENER_ETHERNET_BUFFER_SIZE 512 +#define PC_OPENER_ETHERNET_BUFFER_SIZE 8192 #endif /*OPENER_USER_CONF_H_*/ From c23c329257c0fb744746340f4fcdd548c2743381 Mon Sep 17 00:00:00 2001 From: Martin Melik Merkumians Date: Wed, 27 May 2020 10:55:47 +0200 Subject: [PATCH 2/3] Uncrustify changes Signed-off-by: Martin Melik Merkumians --- source/src/cip/cipconnectionmanager.c | 22 +++-- source/src/cip/cipconnectionobject.c | 30 ++++--- .../sample_application/opener_user_conf.h | 52 +++++------ source/src/ports/nvdata/conffile.c | 33 ++++--- source/src/ports/nvdata/conffile.h | 4 +- source/src/ports/nvdata/nvdata.c | 86 +++++++++---------- source/src/ports/nvdata/nvtcpip.c | 18 ++-- 7 files changed, 128 insertions(+), 117 deletions(-) diff --git a/source/src/cip/cipconnectionmanager.c b/source/src/cip/cipconnectionmanager.c index 42acecb5d1..94edd6d486 100644 --- a/source/src/cip/cipconnectionmanager.c +++ b/source/src/cip/cipconnectionmanager.c @@ -238,7 +238,10 @@ EipStatus ConnectionManagerInit(EipUint16 unique_connection_id) { InsertService(connection_manager, kGetAttributeAll, &GetAttributeAll, "GetAttributeAll"); InsertService(connection_manager, kForwardOpen, &ForwardOpen, "ForwardOpen"); - InsertService(connection_manager, kLargeForwardOpen, &LargeForwardOpen, "LargeForwardOpen"); + InsertService(connection_manager, + kLargeForwardOpen, + &LargeForwardOpen, + "LargeForwardOpen"); InsertService(connection_manager, kForwardClose, &ForwardClose, "ForwardClose"); InsertService(connection_manager, kGetConnectionOwner, &GetConnectionOwner, @@ -491,8 +494,12 @@ EipStatus LargeForwardOpen( const struct sockaddr *originator_address, const int encapsulation_session ) { - g_dummy_connection_object.is_large_forward_open = true; - return ForwardOpen(instance, message_router_request, message_router_response, originator_address, encapsulation_session); + g_dummy_connection_object.is_large_forward_open = true; + return ForwardOpen(instance, + message_router_request, + message_router_response, + originator_address, + encapsulation_session); } /** @brief Check if resources for new connection available, generate ForwardOpen Reply message. @@ -559,10 +566,11 @@ EipStatus ForwardOpen( if(kConnectionObjectConnectionTypeMulticast == t_to_o_connection_type) { /* for multicast, check if IP is within configured net because we send TTL 1 */ - CipUdint originator_ip = ((struct sockaddr_in *)originator_address)->sin_addr.s_addr; + CipUdint originator_ip = + ( (struct sockaddr_in *)originator_address )->sin_addr.s_addr; CipUdint interface_ip = g_network_status.ip_address; CipUdint interface_mask = g_network_status.network_mask; - if((originator_ip & interface_mask)!=(interface_ip & interface_mask)) { + if( (originator_ip & interface_mask)!=(interface_ip & interface_mask) ) { return AssembleForwardOpenResponse( &g_dummy_connection_object, message_router_response, kCipErrorConnectionFailure, @@ -794,7 +802,7 @@ EipStatus AssembleForwardOpenResponse( CIPServiceCode service_code = kForwardOpen; if (connection_object->is_large_forward_open) { - service_code = kLargeForwardOpen; + service_code = kLargeForwardOpen; } message_router_response->reply_service = (0x80 | service_code); @@ -1112,7 +1120,7 @@ EipUint8 ParseConnectionPath( size_t header_length = g_kForwardOpenHeaderLength; if (connection_object->is_large_forward_open) { - header_length = g_kLargeForwardOpenHeaderLength; + header_length = g_kLargeForwardOpenHeaderLength; } if ( (header_length + remaining_path * 2) diff --git a/source/src/cip/cipconnectionobject.c b/source/src/cip/cipconnectionobject.c index 618b24a2b0..c67493d398 100644 --- a/source/src/cip/cipconnectionobject.c +++ b/source/src/cip/cipconnectionobject.c @@ -165,10 +165,12 @@ void ConnectionObjectInitializeFromMessage( if (connection_object->is_large_forward_open == true) { ConnectionObjectSetOToTNetworkConnectionParameters(connection_object, - GetDintFromMessage(message) ); + GetDintFromMessage( + message) ); } else { ConnectionObjectSetOToTNetworkConnectionParameters(connection_object, - GetIntFromMessage(message) ); + GetIntFromMessage( + message) ); } ConnectionObjectSetTToORequestedPacketInterval(connection_object, @@ -178,10 +180,12 @@ void ConnectionObjectInitializeFromMessage( if (connection_object->is_large_forward_open == true) { ConnectionObjectSetTToONetworkConnectionParameters(connection_object, - GetDintFromMessage(message) ); + GetDintFromMessage( + message) ); } else { ConnectionObjectSetTToONetworkConnectionParameters(connection_object, - GetIntFromMessage(message) ); + GetIntFromMessage( + message) ); } connection_object->transport_class_trigger = GetSintFromMessage(message); @@ -704,9 +708,9 @@ bool ConnectionObjectIsRedundantOwner( const CipDword connection_parameters, const CipBool is_lfo) { if (is_lfo) { - return (connection_parameters & (1 << 31)); + return (connection_parameters & (1 << 31) ); } else { - return (connection_parameters & (1 << 15)); + return (connection_parameters & (1 << 15) ); } } @@ -730,9 +734,9 @@ ConnectionObjectConnectionType ConnectionObjectGetConnectionType( CipUsint connection_type; if (is_lfo) { - connection_type = (connection_parameters & (3 << 29)) >> 29; + connection_type = (connection_parameters & (3 << 29) ) >> 29; } else { - connection_type = (connection_parameters & (3 << 13)) >> 13; + connection_type = (connection_parameters & (3 << 13) ) >> 13; } switch(connection_type) { @@ -766,9 +770,9 @@ ConnectionObjectPriority ConnectionObjectGetPriority( CipUsint priority; if (is_lfo) { - priority = (connection_parameters & (3 << 26)) >> 26; + priority = (connection_parameters & (3 << 26) ) >> 26; } else { - priority = (connection_parameters & (3 << 10)) >> 10; + priority = (connection_parameters & (3 << 10) ) >> 10; } ConnectionObjectPriority result; @@ -809,9 +813,9 @@ ConnectionObjectConnectionSizeType ConnectionObjectGetConnectionSizeType( bool connection_size_type; if (is_lfo) { - connection_size_type = (connection_parameters & (1 << 25)); + connection_size_type = (connection_parameters & (1 << 25) ); } else { - connection_size_type = (connection_parameters & (1 << 9)); + connection_size_type = (connection_parameters & (1 << 9) ); } if (connection_size_type) { @@ -843,7 +847,7 @@ size_t ConnectionObjectGetConnectionSize( CipDword mask = kConnectionSizeMask; if (is_lfo) { - mask = kConnectionSizeMaskLFO; + mask = kConnectionSizeMaskLFO; } return connection_parameters & mask; diff --git a/source/src/ports/POSIX/sample_application/opener_user_conf.h b/source/src/ports/POSIX/sample_application/opener_user_conf.h index 4d71e0b8d0..2ad7cdccd2 100644 --- a/source/src/ports/POSIX/sample_application/opener_user_conf.h +++ b/source/src/ports/POSIX/sample_application/opener_user_conf.h @@ -44,7 +44,7 @@ #endif #if defined(OPENER_IS_DLR_DEVICE) && 0 != OPENER_IS_DLR_DEVICE - /* Enable all the stuff the DLR device depends on */ +/* Enable all the stuff the DLR device depends on */ #define OPENER_TCPIP_IFACE_CFG_SETTABLE 1 #define OPENER_ETHLINK_CNTRS_ENABLE 1 #define OPENER_ETHLINK_IFACE_CTRL_ENABLE 1 @@ -164,50 +164,50 @@ static const MilliSeconds kOpenerTimerTickInMilliSeconds = 10; #ifdef OPENER_WITH_TRACES - /* If we have tracing enabled provide LOG_TRACE macro */ +/* If we have tracing enabled provide LOG_TRACE macro */ #include #define LOG_TRACE(...) fprintf(stderr,__VA_ARGS__) #ifdef IDLING_ASSERT - /** @brief A specialized assertion command enabled by IDLING_ASSERT that - * will log the assertion and block further - * execution in a while(1) loop. - */ +/** @brief A specialized assertion command enabled by IDLING_ASSERT that + * will log the assertion and block further + * execution in a while(1) loop. + */ #define OPENER_ASSERT(assertion) \ - do { \ - if( !(assertion) ) { \ - LOG_TRACE("Assertion \"%s\" failed: file \"%s\", line %d\n", \ - # assertion, __FILE__, __LINE__); \ - while(1) { } \ - } \ - } while(0) + do { \ + if( !(assertion) ) { \ + LOG_TRACE("Assertion \"%s\" failed: file \"%s\", line %d\n", \ + # assertion, __FILE__, __LINE__); \ + while(1) { } \ + } \ + } while(0) #else /* ifdef IDLING_ASSERT */ - /* Use standard assert() that vanishes only for release builds. */ +/* Use standard assert() that vanishes only for release builds. */ #define OPENER_ASSERT(assertion) assert(assertion) #endif /* ifdef IDLING_ASSERT */ #else /* ifdef OPENER_WITH_TRACES */ - /* Select one of the OPENER_ASSERT() variants below if trace support is off */ +/* Select one of the OPENER_ASSERT() variants below if trace support is off */ #if 0 - /* If there are any strange timing issues, you can try the version below, - * where the assertion is performed but the assert function is not used. - * This may result in "statement with no effect" warnings. - */ +/* If there are any strange timing issues, you can try the version below, + * where the assertion is performed but the assert function is not used. + * This may result in "statement with no effect" warnings. + */ #define OPENER_ASSERT(assertion) (assertion) #elif 0 - /* If you still want assertions to stop execution but without tracing, - * use the following */ +/* If you still want assertions to stop execution but without tracing, + * use the following */ #define OPENER_ASSERT(assertion) \ - do { if(!(assertion)) { while(1) {} } } while (0) + do { if(!(assertion) ) { while(1) {} } } while (0) #elif 0 - /* Even for debug builds remove assertion. May solicit unused variable - * warnings. */ +/* Even for debug builds remove assertion. May solicit unused variable + * warnings. */ #define OPENER_ASSERT(assertion) #else - /* By default use standard assert() that vanishes only - * for release builds. */ +/* By default use standard assert() that vanishes only + * for release builds. */ #define OPENER_ASSERT(assertion) assert(assertion) #endif diff --git a/source/src/ports/nvdata/conffile.c b/source/src/ports/nvdata/conffile.c index bf23729c86..9f0f55a737 100644 --- a/source/src/ports/nvdata/conffile.c +++ b/source/src/ports/nvdata/conffile.c @@ -34,19 +34,19 @@ #define CFG_BASE "nvdata/" #if ENABLE_VERBOSE != 0 -#define VERBOSE(pFile, pFmt, ...) do { fprintf(pFile, pFmt, ##__VA_ARGS__); } while (0) +#define VERBOSE(pFile, pFmt, ...) do { fprintf(pFile, pFmt, ## __VA_ARGS__); \ +} while (0) #else #define VERBOSE(pFile, pFmt, ...) #endif /** @brief Portable wrapper for mkdir(). Internally used by RecMkdir() - * - * @param[in] path the full path of the directory to create - * @return zero on success, otherwise -1 and errno set - */ -static inline int Mkdir(const char *path) -{ + * + * @param[in] path the full path of the directory to create + * @return zero on success, otherwise -1 and errno set + */ +static inline int Mkdir(const char *path) { #ifdef _WIN32 return _mkdir(path); #else @@ -56,8 +56,7 @@ static inline int Mkdir(const char *path) } -static void RecMkdir(char * const p_path) -{ +static void RecMkdir(char *const p_path) { char *sep = strrchr(p_path, '/' ); if(sep && p_path != sep) { /* "p_path != sep" avoids mkdir("/")! */ *sep = '\0'; @@ -74,8 +73,8 @@ static void RecMkdir(char * const p_path) } -static FILE *FopenMkdir(char *p_path, char *mode) -{ +static FILE *FopenMkdir(char *p_path, + char *mode) { char *sep = strrchr(p_path, '/' ); /* In write mode create missing directories. */ if(sep && 'w' == *mode) { @@ -98,10 +97,11 @@ static FILE *FopenMkdir(char *p_path, char *mode) * This function open a configuration file, possibly for write operation, * in the NV data storage directory. */ -int ConfFileOpen(bool write, const char *p_name, FILE **p_filep) -{ - char path_buf[64]; - int rc; +int ConfFileOpen(bool write, + const char *p_name, + FILE **p_filep) { + char path_buf[64]; + int rc; rc = snprintf(path_buf, sizeof path_buf, "%s%s", CFG_BASE, p_name); if (rc > 0) { @@ -125,8 +125,7 @@ int ConfFileOpen(bool write, const char *p_name, FILE **p_filep) * Closes the configuration file associated to p_filep. No data * synchronization to disk yet. */ -int ConfFileClose(FILE **p_filep) -{ +int ConfFileClose(FILE **p_filep) { int rc = fclose(*p_filep); *p_filep = NULL; return rc; diff --git a/source/src/ports/nvdata/conffile.h b/source/src/ports/nvdata/conffile.h index 91ae7d9a2b..96b3c147d1 100644 --- a/source/src/ports/nvdata/conffile.h +++ b/source/src/ports/nvdata/conffile.h @@ -14,7 +14,9 @@ #include #include -int ConfFileOpen(bool write, const char *p_name, FILE **p_filep); +int ConfFileOpen(bool write, + const char *p_name, + FILE **p_filep); int ConfFileClose(FILE **p_filep); diff --git a/source/src/ports/nvdata/nvdata.c b/source/src/ports/nvdata/nvdata.c index 8900fc7e60..9e228d7b52 100644 --- a/source/src/ports/nvdata/nvdata.c +++ b/source/src/ports/nvdata/nvdata.c @@ -35,7 +35,7 @@ */ EipStatus NvdataLoad(void) { EipStatus status = kEipStatusOk; - int rc; + int rc; /* Load NV data for QoS object instance */ rc = NvQosLoad(&g_qos); @@ -49,28 +49,27 @@ EipStatus NvdataLoad(void) { } /** A PostSetCallback for QoS class to store NV attributes -* -* @param instance pointer to instance of QoS class -* @param attribute pointer to attribute structure -* @param service the CIP service code of current request -* -* This function implements the PostSetCallback for the QoS class. The -* purpose of this function is to save the NV attributes of the QoS -* class instance to external storage. -* -* This application specific implementation chose to save all attributes -* at once using a single NvQosStore() call. -*/ + * + * @param instance pointer to instance of QoS class + * @param attribute pointer to attribute structure + * @param service the CIP service code of current request + * + * This function implements the PostSetCallback for the QoS class. The + * purpose of this function is to save the NV attributes of the QoS + * class instance to external storage. + * + * This application specific implementation chose to save all attributes + * at once using a single NvQosStore() call. + */ EipStatus NvQosSetCallback ( CipInstance *const instance, CipAttributeStruct *const attribute, CipByte service -) -{ +) { EipStatus status = kEipStatusOk; - if (0 != (kNvDataFunc & attribute->attribute_flags)) { + 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, @@ -81,36 +80,35 @@ EipStatus NvQosSetCallback } /** 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. -*/ + * + * @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; + CipInstance *const instance, + CipAttributeStruct *const attribute, + CipByte service +) { + EipStatus status = kEipStatusOk; - if (0 != (kNvDataFunc & attribute->attribute_flags)) { - /* Workaround: Update only if service is not flagged. */ - if (0 == (0x80 & service)) { - 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); - } + if (0 != (kNvDataFunc & attribute->attribute_flags) ) { + /* Workaround: Update only if service is not flagged. */ + if (0 == (0x80 & service) ) { + 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; + } + return status; } diff --git a/source/src/ports/nvdata/nvtcpip.c b/source/src/ports/nvdata/nvtcpip.c index e4349e0a55..316e802b90 100644 --- a/source/src/ports/nvdata/nvtcpip.c +++ b/source/src/ports/nvdata/nvtcpip.c @@ -28,17 +28,17 @@ * @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; +int NvTcpipLoad(CipTcpIpObject *p_tcp_ip) { + CipTcpIpObject tcpip; FILE *p_file; - int rc; + 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"); + OPENER_TRACE_ERR( + "ERROR: Loading of TCP/IP object's NV data not implemented yet\n"); /* TODO: Implement load */ rc = kEipStatusError; @@ -58,15 +58,15 @@ int NvTcpipLoad(CipTcpIpObject *p_tcp_ip) * @param p_qos pointer to the TCP/IP object's data structure * @return 0: success; -1: failure */ -int NvTcpipStore(const CipTcpIpObject *p_tcp_ip) -{ +int NvTcpipStore(const CipTcpIpObject *p_tcp_ip) { FILE *p_file; - int rc; + 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"); + OPENER_TRACE_ERR( + "ERROR: Storing of TCP/IP object's NV data not implemented yet\n"); /* TODO: Implement store */ rc = kEipStatusError; From 5474916e9afcf91f484554a4ad4867521396b7ec Mon Sep 17 00:00:00 2001 From: Martin Melik Merkumians Date: Wed, 27 May 2020 10:30:11 +0200 Subject: [PATCH 3/3] Fixes problem, that selelection on LFO stays permanent in FO The flag is_large_forward_open is set permanently, as it is never reseted and saved in the global variable struct g_dummy_connection Signed-off-by: Martin Melik Merkumians --- source/src/cip/cipclass3connection.c | 2 +- source/src/cip/cipconnectionmanager.c | 32 ++++++++++++++++--- .../sample_application/opener_user_conf.h | 2 +- 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/source/src/cip/cipclass3connection.c b/source/src/cip/cipclass3connection.c index 8698506d7e..578d6d8f43 100644 --- a/source/src/cip/cipclass3connection.c +++ b/source/src/cip/cipclass3connection.c @@ -21,7 +21,7 @@ void Class3ConnectionTimeoutHandler(CipConnectionObject *connection_object) { CloseSessionBySessionHandle); CloseConnection(connection_object); } -#define RESTRICT + /**** Implementation ****/ CipError EstablishClass3Connection( CipConnectionObject *RESTRICT const connection_object, diff --git a/source/src/cip/cipconnectionmanager.c b/source/src/cip/cipconnectionmanager.c index 94edd6d486..fb19d92eec 100644 --- a/source/src/cip/cipconnectionmanager.c +++ b/source/src/cip/cipconnectionmanager.c @@ -483,6 +483,14 @@ static const HandleForwardOpenRequestFunction HandleNullMatchingForwardOpenRequest } }; +EipStatus ForwardOpenRoutine( + CipInstance *instance, + CipMessageRouterRequest *message_router_request, + CipMessageRouterResponse *message_router_response, + const struct sockaddr *originator_address, + const int encapsulation_session + ); + /** @brief Check if resources for new connection available, generate ForwardOpen Reply message. * * Large Forward Open service calls Forward Open service @@ -495,11 +503,11 @@ EipStatus LargeForwardOpen( const int encapsulation_session ) { g_dummy_connection_object.is_large_forward_open = true; - return ForwardOpen(instance, - message_router_request, - message_router_response, - originator_address, - encapsulation_session); + return ForwardOpenRoutine(instance, + message_router_request, + message_router_response, + originator_address, + encapsulation_session); } /** @brief Check if resources for new connection available, generate ForwardOpen Reply message. @@ -524,6 +532,20 @@ EipStatus LargeForwardOpen( * -1 .. error */ EipStatus ForwardOpen( + CipInstance *instance, + CipMessageRouterRequest *message_router_request, + CipMessageRouterResponse *message_router_response, + const struct sockaddr *originator_address, + const int encapsulation_session + ) { + g_dummy_connection_object.is_large_forward_open = false; + return ForwardOpenRoutine(instance, + message_router_request, + message_router_response, + originator_address, + encapsulation_session); +} +EipStatus ForwardOpenRoutine( CipInstance *instance, CipMessageRouterRequest *message_router_request, CipMessageRouterResponse *message_router_response, diff --git a/source/src/ports/POSIX/sample_application/opener_user_conf.h b/source/src/ports/POSIX/sample_application/opener_user_conf.h index 2ad7cdccd2..319e8f5a47 100644 --- a/source/src/ports/POSIX/sample_application/opener_user_conf.h +++ b/source/src/ports/POSIX/sample_application/opener_user_conf.h @@ -220,6 +220,6 @@ static const MilliSeconds kOpenerTimerTickInMilliSeconds = 10; * This buffer size will be used for any received message. * The same buffer is used for the replied explicit message. */ -#define PC_OPENER_ETHERNET_BUFFER_SIZE 8192 +#define PC_OPENER_ETHERNET_BUFFER_SIZE 512 #endif /*OPENER_USER_CONF_H_*/