Skip to content

Commit

Permalink
Merge pull request EIPStackGroup#132 from EIPStackGroup/Issue_131
Browse files Browse the repository at this point in the history
Closes EIPStackGroup#131 Issue 131
  • Loading branch information
MartinMelikMerkumians authored Feb 5, 2018
2 parents e8704f9 + 5f16840 commit d7a04bb
Show file tree
Hide file tree
Showing 25 changed files with 347 additions and 99 deletions.
1 change: 1 addition & 0 deletions source/src/cip/appcontype.c
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,7 @@ bool ConnectionWithSameConfigPointExists(const EipUint32 config_point) {

while (NULL != node) {
CipConnectionObject *connection = node->data;
OPENER_ASSERT(NULL != connection);
if (config_point == connection->configuration_path.instance_id) {
return (NULL != connection);
}
Expand Down
6 changes: 4 additions & 2 deletions source/src/cip/cipassembly.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ EipStatus SetAssemblyAttributeSingle(
CipInstance *const instance,
CipMessageRouterRequest *const message_router_request,
CipMessageRouterResponse *const message_router_response,
struct sockaddr *originator_address);
struct sockaddr *originator_address,
const int encapsulation_session);

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

Expand Down
10 changes: 9 additions & 1 deletion source/src/cip/cipclass3connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,20 @@

#include "cipclass3connection.h"

#include "encap.h"

/**** Global variables ****/
extern CipConnectionObject explicit_connection_object_pool[
OPENER_CIP_NUM_EXPLICIT_CONNS];

CipConnectionObject *GetFreeExplicitConnection(void);

void Class3ConnectionTimeoutHandler(CipConnectionObject *connection_object) {
CheckForTimedOutConnectionsAndCloseTCPConnections(connection_object,
CloseSessionBySessionHandle);
CloseConnection(connection_object);
}

/**** Implementation ****/
EipStatus EstablishClass3Connection(
CipConnectionObject *RESTRICT const connection_object,
Expand Down Expand Up @@ -42,7 +50,7 @@ EipStatus EstablishClass3Connection(
CloseConnection;
/* explicit connection have to be closed on time out*/
explicit_connection->connection_timeout_function =
CloseConnection;
Class3ConnectionTimeoutHandler;

AddNewActiveConnection(explicit_connection);
}
Expand Down
24 changes: 15 additions & 9 deletions source/src/cip/cipcommon.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ 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) {
struct sockaddr *originator_address,
const int encapsulation_session) {

/* find the instance: if instNr==0, the class is addressed, else find the instance */
EipUint16 instance_number = message_router_request->request_path
Expand All @@ -97,7 +98,8 @@ EipStatus NotifyClass(const CipClass *RESTRICT const cip_class,
OPENER_ASSERT(NULL != service->service_function);
return service->service_function(instance, message_router_request,
message_router_response,
originator_address);
originator_address,
encapsulation_session);
} else {
service++;
}
Expand Down Expand Up @@ -136,8 +138,8 @@ CipInstance *AddCipInstances(CipClass *RESTRICT const cip_class,
instance_number++; /* keep track of what the first new instance number will be */
}

CipInstance *current_instance = current_instance = (CipInstance *) CipCalloc(
number_of_instances, sizeof(CipInstance) ); /* allocate a block of memory for all created instances*/
CipInstance *current_instance = (CipInstance *) CipCalloc(
number_of_instances, sizeof(CipInstance) ); /* allocate a block of memory for all created instances*/
CipInstance *first_instance = current_instance; /* allocate a block of memory for all created instances*/

OPENER_ASSERT(NULL != current_instance);
Expand Down Expand Up @@ -170,7 +172,7 @@ CipInstance *AddCIPInstance(CipClass *RESTRICT const class,
const EipUint32 instance_id) {
CipInstance *instance = GetCipInstance(class, instance_id);

if (0 == instance) { /*we have no instance with given id*/
if (NULL == instance) { /*we have no instance with given id*/
instance = AddCipInstances(class, 1);
instance->instance_number = instance_id;
}
Expand Down Expand Up @@ -383,7 +385,8 @@ EipStatus GetAttributeSingle(
CipInstance *RESTRICT const instance,
CipMessageRouterRequest *const message_router_request,
CipMessageRouterResponse *const message_router_response,
struct sockaddr *originator_address) {
struct sockaddr *originator_address,
const int encapsulation_session) {
/* Mask for filtering get-ability */

CipAttributeStruct *attribute = GetCipAttribute(
Expand Down Expand Up @@ -680,7 +683,8 @@ int DecodeData(const EipUint8 cip_type,
EipStatus GetAttributeAll(CipInstance *instance,
CipMessageRouterRequest *message_router_request,
CipMessageRouterResponse *message_router_response,
struct sockaddr *originator_address) {
struct sockaddr *originator_address,
const int encapsulation_session) {

EipUint8 *reply = message_router_response->data; /* pointer into the reply */
CipAttributeStruct *attribute = instance->attributes; /* pointer to list of attributes*/
Expand Down Expand Up @@ -714,7 +718,8 @@ EipStatus GetAttributeAll(CipInstance *instance,
if ( kEipStatusOkSend
!= service->service_function(instance, message_router_request,
message_router_response,
originator_address) ) {
originator_address,
encapsulation_session) ) {
message_router_response->data = reply;
return kEipStatusError;
}
Expand Down Expand Up @@ -961,7 +966,8 @@ size_t GetSizeOfAttribute(const CipAttributeStruct *const attribute_struct) {
break;
case (kCipStringN): {
CipStringN *data = (CipStringN *) attribute_struct->data;
return sizeof(CipUint) + sizeof(CipUint) + (data->length) * (data->size);
return sizeof(CipUint) + sizeof(CipUint) + (size_t)(data->length) *
(size_t)(data->size);
}
break;
case (kCipShortString): {
Expand Down
9 changes: 6 additions & 3 deletions source/src/cip/cipcommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ 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);
struct sockaddr *originator_address,
const int encapsulation_session);

/** @brief Generic implementation of the GetAttributeSingle CIP service
*
Expand All @@ -54,7 +55,8 @@ EipStatus GetAttributeSingle(
message_router_request,
CipMessageRouterResponse *const
message_router_response,
struct sockaddr *originator_address);
struct sockaddr *originator_address,
const int encapsulation_session);

/** @brief Generic implementation of the GetAttributeAll CIP service
*
Expand All @@ -68,7 +70,8 @@ EipStatus GetAttributeSingle(
EipStatus GetAttributeAll(CipInstance *instance,
CipMessageRouterRequest *message_router_request,
CipMessageRouterResponse *message_router_response,
struct sockaddr *originator_address);
struct sockaddr *originator_address,
const int encapsulation_session);

/** @brief Decodes padded EPath
* @param epath EPath to the receiving element
Expand Down
46 changes: 38 additions & 8 deletions source/src/cip/cipconnectionmanager.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,19 +66,22 @@ EipStatus ForwardOpen(
CipInstance *instance,
CipMessageRouterRequest *message_router_request,
CipMessageRouterResponse *message_router_response,
struct sockaddr *originator_address);
struct sockaddr *originator_address,
const int encapsulation_session);

EipStatus ForwardClose(
CipInstance *instance,
CipMessageRouterRequest *message_router_request,
CipMessageRouterResponse *message_router_response,
struct sockaddr *originator_address);
struct sockaddr *originator_address,
const int encapsulation_session);

EipStatus GetConnectionOwner(
CipInstance *instance,
CipMessageRouterRequest *message_router_request,
CipMessageRouterResponse *message_router_response,
struct sockaddr *originator_address);
struct sockaddr *originator_address,
const int encapsulation_session);

EipStatus AssembleForwardOpenResponse(
CipConnectionObject *connection_object,
Expand Down Expand Up @@ -266,6 +269,7 @@ EipStatus HandleReceivedConnectedData(
/* only handle the data if it is coming from the originator */
if (connection_object->originator_address.sin_addr.s_addr
== from_address->sin_addr.s_addr) {
ConnectionObjectResetLastPackageInactivityTimerValue(connection_object);

if ( SEQ_GT32(
g_common_packet_format_data_item.address_item.data.
Expand Down Expand Up @@ -487,7 +491,8 @@ EipStatus ForwardOpen(
CipInstance *instance,
CipMessageRouterRequest *message_router_request,
CipMessageRouterResponse *message_router_response,
struct sockaddr *originator_address
struct sockaddr *originator_address,
const int encapsulation_session
) {
(void) instance; /*suppress compiler warning */

Expand All @@ -497,6 +502,8 @@ EipStatus ForwardOpen(
/*first check if we have already a connection with the given params */
ConnectionObjectInitializeFromMessage(&(message_router_request->data),
&g_dummy_connection_object);
g_dummy_connection_object.associated_encapsulation_session =
encapsulation_session;

memcpy( &(g_dummy_connection_object.originator_address), originator_address,
sizeof(g_dummy_connection_object.originator_address) );
Expand Down Expand Up @@ -552,8 +559,8 @@ EipStatus ForwardClose(
CipInstance *instance,
CipMessageRouterRequest *message_router_request,
CipMessageRouterResponse *message_router_response,
struct sockaddr *originator_address
) {
struct sockaddr *originator_address,
const int encapsulation_session) {
/*Suppress compiler warning*/
(void) instance;

Expand Down Expand Up @@ -628,8 +635,8 @@ EipStatus GetConnectionOwner(
CipInstance *instance,
CipMessageRouterRequest *message_router_request,
CipMessageRouterResponse *message_router_response,
struct sockaddr *originator_address
) {
struct sockaddr *originator_address,
const int encapsulation_session) {
/* suppress compiler warnings */
(void) instance;
(void) message_router_request;
Expand Down Expand Up @@ -663,6 +670,7 @@ EipStatus ManageConnections(MilliSeconds elapsed_time) {
connection_object->connection_timeout_function(connection_object);
} else {
connection_object->inactivity_watchdog_timer -= elapsed_time;
connection_object->last_package_watchdog_timer -= elapsed_time;
}
}
/* only if the connection has not timed out check if data is to be send */
Expand Down Expand Up @@ -1493,6 +1501,28 @@ EipStatus TriggerConnections(
return status;
}

void CheckForTimedOutConnectionsAndCloseTCPConnections(
const CipConnectionObject *const connection_object,
CloseSessionFunction CloseSessions) {

DoublyLinkedListNode *search_node = connection_list.first;
bool non_timed_out_connection_found = false;
while(NULL != search_node) {
CipConnectionObject *search_connection = search_node->data;
if(ConnectionObjectEqualOriginator(connection_object, search_connection)
&& connection_object != search_connection
&& kConnectionObjectStateTimedOut !=
ConnectionObjectGetState(search_connection) ) {
non_timed_out_connection_found = true;
break;
}
search_node = search_node->next;
}
if(false == non_timed_out_connection_found) {
CloseSessions(connection_object);
}
}

void InitializeConnectionManagerData() {
memset( g_connection_management_list, 0,
g_kNumberOfConnectableObjects *
Expand Down
7 changes: 7 additions & 0 deletions source/src/cip/cipconnectionmanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -222,4 +222,11 @@ void RemoveFromActiveConnections(CipConnectionObject *const connection_object);

CipUint GetConnectionId(void);

typedef void (*CloseSessionFunction)(const CipConnectionObject *const
connection_object);

void CheckForTimedOutConnectionsAndCloseTCPConnections(
const CipConnectionObject *const connection_object,
CloseSessionFunction CloseSessions);

#endif /* OPENER_CIPCONNECTIONMANAGER_H_ */
36 changes: 29 additions & 7 deletions source/src/cip/cipconnectionobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,14 @@ DoublyLinkedListNode *CipConnectionObjectListArrayAllocator() {

void CipConnectionObjectListArrayFree(DoublyLinkedListNode **node) {

if(NULL != *node && NULL != node) {
memset( *node, 0, sizeof(DoublyLinkedListNode) );
*node = NULL;
} else {
OPENER_TRACE_ERR("Attempt to delete NULL pointer to node\n");
if(NULL != node) {
if(NULL != *node) {
memset( *node, 0, sizeof(DoublyLinkedListNode) );
*node = NULL;
} else {
OPENER_TRACE_ERR("Attempt to delete NULL pointer to node\n");
}
OPENER_TRACE_ERR("Attempt to provide a NULL pointer to node pointer\n");
}

}
Expand Down Expand Up @@ -546,10 +549,18 @@ void ConnectionObjectResetInactivityWatchdogTimerValue(
connection_object);
}

void ConnectionObjectResetLastPackageInactivityTimerValue(
CipConnectionObject *const connection_object) {
connection_object->last_package_watchdog_timer =
ConnectionObjectCalculateRegularInactivityWatchdogTimerValue(
connection_object);
}

uint64_t ConnectionObjectCalculateRegularInactivityWatchdogTimerValue(
const CipConnectionObject *const connection_object) {
return ( ( (connection_object->o_to_t_requested_packet_interval) /
1000 ) << (2 + connection_object->connection_timeout_multiplier) );
return ( ( (uint64_t)(connection_object->o_to_t_requested_packet_interval) /
(uint64_t)1000 ) <<
(2 + connection_object->connection_timeout_multiplier) );
}


Expand Down Expand Up @@ -786,6 +797,17 @@ void ConnectionObjectGeneralConfiguration(
connection_object->transmission_trigger_timer = 0;
}

bool ConnectionObjectEqualOriginator(const CipConnectionObject *const object1,
const CipConnectionObject *const object2) {
if ( (object1->originator_vendor_id
== object2->originator_vendor_id)
&& (object1->originator_serial_number
== object2->originator_serial_number) ) {
return true;
}
return false;
}

bool EqualConnectionTriad(const CipConnectionObject *const object1,
const CipConnectionObject *const object2) {
if ( (object1->connection_serial_number
Expand Down
11 changes: 10 additions & 1 deletion source/src/cip/cipconnectionobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ struct cip_connection_object {

uint64_t transmission_trigger_timer;
uint64_t inactivity_watchdog_timer;
uint64_t last_package_watchdog_timer;
uint64_t production_inhibit_timer;

CipUint connection_serial_number;
Expand Down Expand Up @@ -176,6 +177,8 @@ struct cip_connection_object {
for scanning if the right packet is
arriving */

size_t associated_encapsulation_session; /* The session handle ID via which the forward open was sent */

/* pointers to connection handling functions */
CipConnectionStateHandler current_state_handler;

Expand Down Expand Up @@ -323,7 +326,10 @@ void ConnectionObjectSetConnectionTimeoutMultiplier(
connection_timeout_multiplier);

void ConnectionObjectResetInactivityWatchdogTimerValue(
CipConnectionObject *connection_object);
CipConnectionObject *const connection_object);

void ConnectionObjectResetLastPackageInactivityTimerValue(
CipConnectionObject *const connection_object);

CipUint ConnectionObjectGetConnectionSerialNumber(
const CipConnectionObject *const connection_object);
Expand Down Expand Up @@ -414,6 +420,9 @@ void ConnectionObjectGeneralConfiguration(
bool ConnectionObjectIsTypeIOConnection(
const CipConnectionObject *const connection_object);

bool ConnectionObjectEqualOriginator(const CipConnectionObject *const object1,
const CipConnectionObject *const object2);

bool EqualConnectionTriad(const CipConnectionObject *const object1,
const CipConnectionObject *const object2);

Expand Down
Loading

0 comments on commit d7a04bb

Please sign in to comment.