|
|
@@ -193,7 +193,7 @@ CipUdint GetConnectionId(void) {
|
|
|
#else
|
|
|
CipUint connection_id = NextXorShiftUint32();
|
|
|
#endif
|
|
|
- return ( g_incarnation_id | (connection_id & 0x0000FFFF) );
|
|
|
+ return (g_incarnation_id | (connection_id & 0x0000FFFF) );
|
|
|
}
|
|
|
|
|
|
void InitializeConnectionManager(CipClass *class) {
|
|
|
@@ -285,9 +285,8 @@ EipStatus HandleReceivedConnectedData(const EipUint8 *const data,
|
|
|
int data_length,
|
|
|
struct sockaddr_in *from_address) {
|
|
|
|
|
|
- if( ( CreateCommonPacketFormatStructure(data, data_length,
|
|
|
- &g_common_packet_format_data_item) )
|
|
|
- ==
|
|
|
+ if( (CreateCommonPacketFormatStructure(data, data_length,
|
|
|
+ &g_common_packet_format_data_item) ) ==
|
|
|
kEipStatusError ) {
|
|
|
return kEipStatusError;
|
|
|
} else {
|
|
|
@@ -456,9 +455,9 @@ EipStatus HandleNonNullNonMatchingForwardOpenRequest(
|
|
|
EipUint16 connection_status = kConnectionManagerExtendedStatusCodeSuccess;
|
|
|
|
|
|
/*check if the trigger type value is invalid or ok */
|
|
|
- if( kConnectionObjectTransportClassTriggerProductionTriggerInvalid ==
|
|
|
- ConnectionObjectGetTransportClassTriggerProductionTrigger(&
|
|
|
- g_dummy_connection_object) )
|
|
|
+ if(kConnectionObjectTransportClassTriggerProductionTriggerInvalid ==
|
|
|
+ ConnectionObjectGetTransportClassTriggerProductionTrigger(&
|
|
|
+ g_dummy_connection_object) )
|
|
|
{
|
|
|
return AssembleForwardOpenResponse(&g_dummy_connection_object,
|
|
|
message_router_response,
|
|
|
@@ -483,7 +482,7 @@ EipStatus HandleNonNullNonMatchingForwardOpenRequest(
|
|
|
if(NULL != connection_management_entry) {
|
|
|
if (NULL != connection_management_entry->open_connection_function) {
|
|
|
temp = connection_management_entry->open_connection_function(
|
|
|
- &g_dummy_connection_object, &connection_status);
|
|
|
+ &g_dummy_connection_object, &connection_status);
|
|
|
} else {
|
|
|
connection_status = kConnectionManagerExtendedStatusCodeMiscellaneous;
|
|
|
}
|
|
|
@@ -595,9 +594,9 @@ EipStatus ForwardOpenRoutine(CipInstance *instance,
|
|
|
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) );
|
|
|
+ memcpy(&(g_dummy_connection_object.originator_address),
|
|
|
+ originator_address,
|
|
|
+ sizeof(g_dummy_connection_object.originator_address) );
|
|
|
|
|
|
ConnectionObjectConnectionType o_to_t_connection_type =
|
|
|
ConnectionObjectGetOToTConnectionType(&g_dummy_connection_object);
|
|
|
@@ -644,7 +643,7 @@ EipStatus ForwardOpenRoutine(CipInstance *instance,
|
|
|
}
|
|
|
|
|
|
/* Check if we have a matching or non matching request */
|
|
|
- if( NULL != CheckForExistingConnection(&g_dummy_connection_object) ) {
|
|
|
+ if(NULL != CheckForExistingConnection(&g_dummy_connection_object) ) {
|
|
|
OPENER_TRACE_INFO("We have a Matching request\n");
|
|
|
is_matching_request = true;
|
|
|
|
|
|
@@ -695,10 +694,10 @@ EipStatus ForwardClose(CipInstance *instance,
|
|
|
while(NULL != node) {
|
|
|
/* this check should not be necessary as only established connections should be in the active connection list */
|
|
|
CipConnectionObject *connection_object = node->data;
|
|
|
- if( ( kConnectionObjectStateEstablished ==
|
|
|
- ConnectionObjectGetState(connection_object) )
|
|
|
- || ( kConnectionObjectStateTimedOut ==
|
|
|
- ConnectionObjectGetState(connection_object) ) ) {
|
|
|
+ if( (kConnectionObjectStateEstablished ==
|
|
|
+ ConnectionObjectGetState(connection_object) )
|
|
|
+ || (kConnectionObjectStateTimedOut ==
|
|
|
+ ConnectionObjectGetState(connection_object) ) ) {
|
|
|
if( (connection_object->connection_serial_number ==
|
|
|
connection_serial_number) &&
|
|
|
(connection_object->originator_vendor_id == originator_vendor_id)
|
|
|
@@ -933,11 +932,11 @@ EipStatus ManageConnections(MilliSeconds elapsed_time) {
|
|
|
while(NULL != node) {
|
|
|
//OPENER_TRACE_INFO("Entering Connection Object loop\n");
|
|
|
CipConnectionObject *connection_object = node->data;
|
|
|
- if( kConnectionObjectStateEstablished ==
|
|
|
- ConnectionObjectGetState(connection_object) ) {
|
|
|
+ if(kConnectionObjectStateEstablished ==
|
|
|
+ ConnectionObjectGetState(connection_object) ) {
|
|
|
if( (NULL != connection_object->consuming_instance) || /* we have a consuming connection check inactivity watchdog timer */
|
|
|
- ( kConnectionObjectTransportClassTriggerDirectionServer ==
|
|
|
- ConnectionObjectGetTransportClassTriggerDirection(connection_object) ) ) /* all server connections have to maintain an inactivity watchdog timer */
|
|
|
+ (kConnectionObjectTransportClassTriggerDirectionServer ==
|
|
|
+ ConnectionObjectGetTransportClassTriggerDirection(connection_object) ) ) /* all server connections have to maintain an inactivity watchdog timer */
|
|
|
{
|
|
|
if(elapsed_time >= connection_object->inactivity_watchdog_timer) {
|
|
|
/* we have a timed out connection perform watchdog time out action*/
|
|
|
@@ -951,16 +950,16 @@ EipStatus ManageConnections(MilliSeconds elapsed_time) {
|
|
|
}
|
|
|
}
|
|
|
/* only if the connection has not timed out check if data is to be send */
|
|
|
- if( kConnectionObjectStateEstablished ==
|
|
|
- ConnectionObjectGetState(connection_object) ) {
|
|
|
+ if(kConnectionObjectStateEstablished ==
|
|
|
+ ConnectionObjectGetState(connection_object) ) {
|
|
|
/* client connection */
|
|
|
- if( ( 0 != ConnectionObjectGetExpectedPacketRate(connection_object) )
|
|
|
+ if( (0 != ConnectionObjectGetExpectedPacketRate(connection_object) )
|
|
|
&& (kEipInvalidSocket !=
|
|
|
connection_object->socket[kUdpCommuncationDirectionProducing]) ) /* only produce for the master connection */
|
|
|
{
|
|
|
- if( kConnectionObjectTransportClassTriggerProductionTriggerCyclic !=
|
|
|
- ConnectionObjectGetTransportClassTriggerProductionTrigger(
|
|
|
- connection_object) ) {
|
|
|
+ if(kConnectionObjectTransportClassTriggerProductionTriggerCyclic !=
|
|
|
+ ConnectionObjectGetTransportClassTriggerProductionTrigger(
|
|
|
+ connection_object) ) {
|
|
|
/* non cyclic connections have to decrement production inhibit timer */
|
|
|
if(elapsed_time <= connection_object->production_inhibit_timer) {
|
|
|
//The connection is allowed to send again
|
|
|
@@ -986,15 +985,13 @@ EipStatus ManageConnections(MilliSeconds elapsed_time) {
|
|
|
connection_object->transmission_trigger_timer -= elapsed_time;
|
|
|
} else { /* elapsed time was longer than RPI */
|
|
|
connection_object->transmission_trigger_timer = 0;
|
|
|
- OPENER_TRACE_INFO(
|
|
|
- "elapsed time: %lu ms was longer than RPI: %u ms\n",
|
|
|
- elapsed_time,
|
|
|
- ConnectionObjectGetRequestedPacketInterval(
|
|
|
- connection_object) );
|
|
|
+ OPENER_TRACE_INFO("elapsed time: %lu ms was longer than RPI: %u ms\n",
|
|
|
+ elapsed_time,
|
|
|
+ ConnectionObjectGetRequestedPacketInterval(connection_object));
|
|
|
}
|
|
|
- if( kConnectionObjectTransportClassTriggerProductionTriggerCyclic !=
|
|
|
- ConnectionObjectGetTransportClassTriggerProductionTrigger(
|
|
|
- connection_object) ) {
|
|
|
+ if(kConnectionObjectTransportClassTriggerProductionTriggerCyclic !=
|
|
|
+ ConnectionObjectGetTransportClassTriggerProductionTrigger(
|
|
|
+ connection_object) ) {
|
|
|
/* non cyclic connections have to reload the production inhibit timer */
|
|
|
ConnectionObjectResetProductionInhibitTimer(connection_object);
|
|
|
}
|
|
|
@@ -1059,10 +1056,7 @@ EipStatus AssembleForwardOpenResponse(CipConnectionObject *connection_object,
|
|
|
&message_router_response->message);
|
|
|
} else {
|
|
|
/* we have an connection creation error */
|
|
|
- OPENER_TRACE_WARN(
|
|
|
- "AssembleForwardOpenResponse: sending error response, general/extended status=%d/%d\n",
|
|
|
- general_status,
|
|
|
- extended_status);
|
|
|
+ OPENER_TRACE_WARN("AssembleForwardOpenResponse: sending error response, general/extended status=%d/%d\n", general_status, extended_status);
|
|
|
ConnectionObjectSetState(connection_object,
|
|
|
kConnectionObjectStateNonExistent);
|
|
|
/* Expected data length is 10 octets */
|
|
|
@@ -1206,10 +1200,10 @@ CipConnectionObject *GetConnectedObject(const EipUint32 connection_id) {
|
|
|
DoublyLinkedListNode *iterator = connection_list.first;
|
|
|
|
|
|
while(NULL != iterator) {
|
|
|
- if( kConnectionObjectStateEstablished ==
|
|
|
- ConnectionObjectGetState(iterator->data)
|
|
|
- && connection_id ==
|
|
|
- ConnectionObjectGetCipConsumedConnectionID(iterator->data) ) {
|
|
|
+ if(kConnectionObjectStateEstablished ==
|
|
|
+ ConnectionObjectGetState(iterator->data)
|
|
|
+ && connection_id ==
|
|
|
+ ConnectionObjectGetCipConsumedConnectionID(iterator->data) ) {
|
|
|
return iterator->data;
|
|
|
}
|
|
|
iterator = iterator->next;
|
|
|
@@ -1224,10 +1218,10 @@ CipConnectionObject *GetConnectedOutputAssembly(
|
|
|
while(NULL != iterator) {
|
|
|
if(kConnectionObjectInstanceTypeIOExclusiveOwner ==
|
|
|
ConnectionObjectGetInstanceType(iterator->data)
|
|
|
- && ( kConnectionObjectStateEstablished ==
|
|
|
- ConnectionObjectGetState(iterator->data)
|
|
|
- || kConnectionObjectStateTimedOut ==
|
|
|
- ConnectionObjectGetState(iterator->data) )
|
|
|
+ && (kConnectionObjectStateEstablished ==
|
|
|
+ ConnectionObjectGetState(iterator->data)
|
|
|
+ || kConnectionObjectStateTimedOut ==
|
|
|
+ ConnectionObjectGetState(iterator->data) )
|
|
|
&& output_assembly_id ==
|
|
|
( (CipConnectionObject *) iterator->data )->produced_path.instance_id) {
|
|
|
return iterator->data;
|
|
|
@@ -1243,9 +1237,9 @@ CipConnectionObject *CheckForExistingConnection(
|
|
|
DoublyLinkedListNode *iterator = connection_list.first;
|
|
|
|
|
|
while(NULL != iterator) {
|
|
|
- if( kConnectionObjectStateEstablished ==
|
|
|
- ConnectionObjectGetState(iterator->data) ) {
|
|
|
- if( EqualConnectionTriad(connection_object, iterator->data) ) {
|
|
|
+ if(kConnectionObjectStateEstablished ==
|
|
|
+ ConnectionObjectGetState(iterator->data) ) {
|
|
|
+ if(EqualConnectionTriad(connection_object, iterator->data) ) {
|
|
|
return iterator->data;
|
|
|
}
|
|
|
}
|
|
|
@@ -1295,7 +1289,7 @@ EipStatus CheckElectronicKeyData(EipUint8 key_format,
|
|
|
|
|
|
if(false == compatiblity_mode) {
|
|
|
/* Major = 0 is valid */
|
|
|
- if( 0 == ElectronicKeyFormat4GetMajorRevision(key_data) ) {
|
|
|
+ if(0 == ElectronicKeyFormat4GetMajorRevision(key_data) ) {
|
|
|
return kEipStatusOk;
|
|
|
}
|
|
|
|
|
|
@@ -1348,7 +1342,7 @@ EipUint8 ParseConnectionPath(CipConnectionObject *connection_object,
|
|
|
CipClass *class = NULL;
|
|
|
|
|
|
CipDword class_id = 0x0;
|
|
|
- CipDword instance_id = 0x0;
|
|
|
+ CipInstanceNum instance_id = 0x0;
|
|
|
|
|
|
/* with 256 we mark that we haven't got a PIT segment */
|
|
|
ConnectionObjectSetProductionInhibitTime(connection_object, 256);
|
|
|
@@ -1358,14 +1352,14 @@ EipUint8 ParseConnectionPath(CipConnectionObject *connection_object,
|
|
|
header_length = g_kLargeForwardOpenHeaderLength;
|
|
|
}
|
|
|
|
|
|
- if( (header_length + remaining_path * 2) <
|
|
|
+ if( ( header_length + remaining_path * sizeof(CipWord) ) <
|
|
|
message_router_request->request_data_size ) {
|
|
|
/* the received packet is larger than the data in the path */
|
|
|
*extended_error = 0;
|
|
|
return kCipErrorTooMuchData;
|
|
|
}
|
|
|
|
|
|
- if( (header_length + remaining_path * 2) >
|
|
|
+ if( ( header_length + remaining_path * sizeof(CipWord) ) >
|
|
|
message_router_request->request_data_size ) {
|
|
|
/*there is not enough data in received packet */
|
|
|
*extended_error = 0;
|
|
|
@@ -1375,13 +1369,13 @@ EipUint8 ParseConnectionPath(CipConnectionObject *connection_object,
|
|
|
|
|
|
if(remaining_path > 0) {
|
|
|
/* first look if there is an electronic key */
|
|
|
- if( kSegmentTypeLogicalSegment == GetPathSegmentType(message) ) {
|
|
|
- if( kLogicalSegmentLogicalTypeSpecial ==
|
|
|
- GetPathLogicalSegmentLogicalType(message) ) {
|
|
|
- if( kLogicalSegmentSpecialTypeLogicalFormatElectronicKey ==
|
|
|
- GetPathLogicalSegmentSpecialTypeLogicalType(message) ) {
|
|
|
- if( kElectronicKeySegmentFormatKeyFormat4 ==
|
|
|
- GetPathLogicalSegmentElectronicKeyFormat(message) ) {
|
|
|
+ if(kSegmentTypeLogicalSegment == GetPathSegmentType(message) ) {
|
|
|
+ if(kLogicalSegmentLogicalTypeSpecial ==
|
|
|
+ GetPathLogicalSegmentLogicalType(message) ) {
|
|
|
+ if(kLogicalSegmentSpecialTypeLogicalFormatElectronicKey ==
|
|
|
+ GetPathLogicalSegmentSpecialTypeLogicalType(message) ) {
|
|
|
+ if(kElectronicKeySegmentFormatKeyFormat4 ==
|
|
|
+ GetPathLogicalSegmentElectronicKeyFormat(message) ) {
|
|
|
/* Check if there is enough data for holding the electronic key segment */
|
|
|
if(remaining_path < 5) {
|
|
|
*extended_error = 0;
|
|
|
@@ -1408,12 +1402,12 @@ EipUint8 ParseConnectionPath(CipConnectionObject *connection_object,
|
|
|
electronic_key.key_data),
|
|
|
ElectronicKeyFormat4GetMinorRevision(connection_object->
|
|
|
electronic_key.key_data) );
|
|
|
- if( kEipStatusOk
|
|
|
- != CheckElectronicKeyData(connection_object->electronic_key.
|
|
|
- key_format,
|
|
|
- connection_object->electronic_key.
|
|
|
- key_data,
|
|
|
- extended_error) ) {
|
|
|
+ if(kEipStatusOk
|
|
|
+ != CheckElectronicKeyData(connection_object->electronic_key.
|
|
|
+ key_format,
|
|
|
+ connection_object->electronic_key.
|
|
|
+ key_data,
|
|
|
+ extended_error) ) {
|
|
|
ElectronicKeyFormat4Delete(&electronic_key);
|
|
|
return kCipErrorConnectionFailure;
|
|
|
}
|
|
|
@@ -1427,12 +1421,12 @@ EipUint8 ParseConnectionPath(CipConnectionObject *connection_object,
|
|
|
}
|
|
|
|
|
|
//TODO: Refactor this afterwards
|
|
|
- if( kConnectionObjectTransportClassTriggerProductionTriggerCyclic !=
|
|
|
- ConnectionObjectGetTransportClassTriggerProductionTrigger(
|
|
|
- connection_object) )
|
|
|
+ if(kConnectionObjectTransportClassTriggerProductionTriggerCyclic !=
|
|
|
+ ConnectionObjectGetTransportClassTriggerProductionTrigger(
|
|
|
+ connection_object) )
|
|
|
{
|
|
|
/*non cyclic connections may have a production inhibit */
|
|
|
- if( kSegmentTypeNetworkSegment == GetPathSegmentType(message) ) {
|
|
|
+ if(kSegmentTypeNetworkSegment == GetPathSegmentType(message) ) {
|
|
|
NetworkSegmentSubtype network_segment_subtype =
|
|
|
GetPathNetworkSegmentSubtype(message);
|
|
|
if(kNetworkSegmentSubtypeProductionInhibitTimeInMilliseconds ==
|
|
|
@@ -1445,9 +1439,9 @@ EipUint8 ParseConnectionPath(CipConnectionObject *connection_object,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if( kSegmentTypeLogicalSegment == GetPathSegmentType(message) &&
|
|
|
- kLogicalSegmentLogicalTypeClassId ==
|
|
|
- GetPathLogicalSegmentLogicalType(message) ) {
|
|
|
+ if(kSegmentTypeLogicalSegment == GetPathSegmentType(message) &&
|
|
|
+ kLogicalSegmentLogicalTypeClassId ==
|
|
|
+ GetPathLogicalSegmentLogicalType(message) ) {
|
|
|
|
|
|
class_id = CipEpathGetLogicalValue(&message);
|
|
|
class = GetCipClass(class_id);
|
|
|
@@ -1476,28 +1470,29 @@ EipUint8 ParseConnectionPath(CipConnectionObject *connection_object,
|
|
|
remaining_path -= 1; /* 1 16Bit word for the class part of the path */
|
|
|
|
|
|
/* Get instance ID */
|
|
|
- if( kSegmentTypeLogicalSegment == GetPathSegmentType(message) &&
|
|
|
- kLogicalSegmentLogicalTypeInstanceId ==
|
|
|
- GetPathLogicalSegmentLogicalType(message) ) { /* store the configuration ID for later checking in the application connection types */
|
|
|
- instance_id = CipEpathGetLogicalValue(&message);
|
|
|
+ if(kSegmentTypeLogicalSegment == GetPathSegmentType(message) &&
|
|
|
+ kLogicalSegmentLogicalTypeInstanceId ==
|
|
|
+ GetPathLogicalSegmentLogicalType(message) ) { /* store the configuration ID for later checking in the application connection types */
|
|
|
+ const CipDword temp_id = CipEpathGetLogicalValue(&message);
|
|
|
|
|
|
OPENER_TRACE_INFO("Configuration instance id %" PRId32 "\n",
|
|
|
- instance_id);
|
|
|
- if( NULL == GetCipInstance(class, instance_id) ) {
|
|
|
+ temp_id);
|
|
|
+ if( (temp_id > kCipInstanceNumMax) ||
|
|
|
+ ( NULL == GetCipInstance(class, (CipInstanceNum)temp_id) ) ) {
|
|
|
/*according to the test tool we should respond with this extended error code */
|
|
|
*extended_error =
|
|
|
kConnectionManagerExtendedStatusCodeErrorInvalidSegmentTypeInPath;
|
|
|
return kCipErrorConnectionFailure;
|
|
|
}
|
|
|
+ instance_id = (CipInstanceNum)temp_id;
|
|
|
/* 1 or 2 16Bit words for the configuration instance part of the path */
|
|
|
remaining_path -= (instance_id > 0xFF) ? 2 : 1; //TODO: 32 bit case missing
|
|
|
} else {
|
|
|
OPENER_TRACE_INFO("no config data\n");
|
|
|
}
|
|
|
|
|
|
- if( kConnectionObjectTransportClassTriggerTransportClass3 ==
|
|
|
- ConnectionObjectGetTransportClassTriggerTransportClass(
|
|
|
- connection_object) )
|
|
|
+ if(kConnectionObjectTransportClassTriggerTransportClass3 ==
|
|
|
+ ConnectionObjectGetTransportClassTriggerTransportClass(connection_object) )
|
|
|
{
|
|
|
/*we have Class 3 connection*/
|
|
|
if(remaining_path > 0) {
|
|
|
@@ -1519,20 +1514,20 @@ EipUint8 ParseConnectionPath(CipConnectionObject *connection_object,
|
|
|
{ .class_id = class_id, .instance_id = instance_id,
|
|
|
.attribute_id_or_connection_point = 0 };
|
|
|
|
|
|
- memcpy( &(connection_object->configuration_path),
|
|
|
- &connection_epath,
|
|
|
- sizeof(connection_object->configuration_path) );
|
|
|
- memcpy( &(connection_object->produced_path), &connection_epath,
|
|
|
- sizeof(connection_object->produced_path) );
|
|
|
+ memcpy(&(connection_object->configuration_path),
|
|
|
+ &connection_epath,
|
|
|
+ sizeof(connection_object->configuration_path) );
|
|
|
+ memcpy(&(connection_object->produced_path), &connection_epath,
|
|
|
+ sizeof(connection_object->produced_path) );
|
|
|
|
|
|
/* End class 3 connection handling */
|
|
|
} else { /* we have an IO connection */
|
|
|
CipConnectionPathEpath connection_epath =
|
|
|
{ .class_id = class_id, .instance_id = instance_id,
|
|
|
.attribute_id_or_connection_point = 0 };
|
|
|
- memcpy( &(connection_object->configuration_path),
|
|
|
- &connection_epath,
|
|
|
- sizeof(connection_object->configuration_path) );
|
|
|
+ memcpy(&(connection_object->configuration_path),
|
|
|
+ &connection_epath,
|
|
|
+ sizeof(connection_object->configuration_path) );
|
|
|
ConnectionObjectConnectionType originator_to_target_connection_type =
|
|
|
ConnectionObjectGetOToTConnectionType(connection_object);
|
|
|
ConnectionObjectConnectionType target_to_originator_connection_type =
|
|
|
@@ -1571,28 +1566,38 @@ EipUint8 ParseConnectionPath(CipConnectionObject *connection_object,
|
|
|
|
|
|
for(size_t i = 0; i < number_of_encoded_paths; i++) /* process up to 2 encoded paths */
|
|
|
{
|
|
|
- if( kSegmentTypeLogicalSegment == GetPathSegmentType(message)
|
|
|
- && ( kLogicalSegmentLogicalTypeInstanceId ==
|
|
|
- GetPathLogicalSegmentLogicalType(message)
|
|
|
- || kLogicalSegmentLogicalTypeConnectionPoint ==
|
|
|
- GetPathLogicalSegmentLogicalType(message) ) ) /* Connection Point interpreted as InstanceNr -> only in Assembly Objects */
|
|
|
+ if(kSegmentTypeLogicalSegment == GetPathSegmentType(message)
|
|
|
+ && (kLogicalSegmentLogicalTypeInstanceId ==
|
|
|
+ GetPathLogicalSegmentLogicalType(message)
|
|
|
+ || kLogicalSegmentLogicalTypeConnectionPoint ==
|
|
|
+ GetPathLogicalSegmentLogicalType(message) ) ) /* Connection Point interpreted as InstanceNr -> only in Assembly Objects */
|
|
|
{ /* Attribute Id or Connection Point */
|
|
|
- CipDword attribute_id = CipEpathGetLogicalValue(&message);
|
|
|
- CipConnectionPathEpath path =
|
|
|
- { .class_id = class_id, .instance_id = attribute_id,
|
|
|
- .attribute_id_or_connection_point = 0 };
|
|
|
- memcpy( paths_to_encode[i], &path,
|
|
|
- sizeof(connection_object->produced_path) );
|
|
|
+
|
|
|
+ /* Validate encoded instance number. */
|
|
|
+ const CipDword temp_instance_id = CipEpathGetLogicalValue(&message);
|
|
|
+ if (temp_instance_id > kCipInstanceNumMax) {
|
|
|
+ *extended_error =
|
|
|
+ kConnectionManagerExtendedStatusCodeErrorInvalidSegmentTypeInPath;
|
|
|
+ return kCipErrorConnectionFailure;
|
|
|
+ }
|
|
|
+ instance_id = (CipInstanceNum)temp_instance_id;
|
|
|
+
|
|
|
+ CipConnectionPathEpath path;
|
|
|
+ path.class_id = class_id;
|
|
|
+ path.instance_id = instance_id;
|
|
|
+ path.attribute_id_or_connection_point = 0;
|
|
|
+ memcpy(paths_to_encode[i], &path,
|
|
|
+ sizeof(connection_object->produced_path) );
|
|
|
OPENER_TRACE_INFO(
|
|
|
"connection point %" PRIu32 "\n",
|
|
|
- attribute_id);
|
|
|
- if( NULL == GetCipInstance(class, attribute_id) ) { /* Old code - Probably here the attribute ID marks the instance for the assembly object */
|
|
|
+ instance_id);
|
|
|
+ if( NULL == GetCipInstance(class, instance_id) ) {
|
|
|
*extended_error =
|
|
|
kConnectionManagerExtendedStatusCodeInconsistentApplicationPathCombo;
|
|
|
return kCipErrorConnectionFailure;
|
|
|
}
|
|
|
/* 1 or 2 16Bit word for the connection point part of the path */
|
|
|
- remaining_path -= (attribute_id > 0xFF) ? 2 : 1;
|
|
|
+ remaining_path -= (instance_id > 0xFF) ? 2 : 1;
|
|
|
} else {
|
|
|
*extended_error =
|
|
|
kConnectionManagerExtendedStatusCodeErrorInvalidSegmentTypeInPath;
|
|
|
@@ -1628,10 +1633,9 @@ EipUint8 ParseConnectionPath(CipConnectionObject *connection_object,
|
|
|
GetPathNetworkSegmentSubtype(message);
|
|
|
switch(subtype) {
|
|
|
case kNetworkSegmentSubtypeProductionInhibitTimeInMilliseconds:
|
|
|
- if(
|
|
|
- kConnectionObjectTransportClassTriggerProductionTriggerCyclic
|
|
|
- != ConnectionObjectGetTransportClassTriggerProductionTrigger(
|
|
|
- connection_object) ) {
|
|
|
+ if(kConnectionObjectTransportClassTriggerProductionTriggerCyclic
|
|
|
+ != ConnectionObjectGetTransportClassTriggerProductionTrigger(
|
|
|
+ connection_object) ) {
|
|
|
/* only non cyclic connections may have a production inhibit */
|
|
|
connection_object->production_inhibit_time = message[1];
|
|
|
message += 2;
|
|
|
@@ -1668,12 +1672,11 @@ EipUint8 ParseConnectionPath(CipConnectionObject *connection_object,
|
|
|
|
|
|
void CloseConnection(CipConnectionObject *RESTRICT connection_object) {
|
|
|
|
|
|
- OPENER_TRACE_INFO( "cipconnectionmanager: CloseConnection, trigger: %d \n",
|
|
|
- ConnectionObjectGetTransportClassTriggerTransportClass(
|
|
|
- connection_object) );
|
|
|
+ OPENER_TRACE_INFO("cipconnectionmanager: CloseConnection, trigger: %d \n",
|
|
|
+ ConnectionObjectGetTransportClassTriggerTransportClass(connection_object));
|
|
|
|
|
|
- if( kConnectionObjectTransportClassTriggerTransportClass3 !=
|
|
|
- ConnectionObjectGetTransportClassTriggerTransportClass(connection_object) )
|
|
|
+ if(kConnectionObjectTransportClassTriggerTransportClass3 !=
|
|
|
+ ConnectionObjectGetTransportClassTriggerTransportClass(connection_object) )
|
|
|
{
|
|
|
/* only close the UDP connection for not class 3 connections */
|
|
|
CloseUdpSocket(connection_object->socket[kUdpCommuncationDirectionConsuming]);
|
|
|
@@ -1704,7 +1707,7 @@ void RemoveFromActiveConnections(CipConnectionObject *const connection_object) {
|
|
|
} OPENER_TRACE_ERR("Connection not found in active connection list\n");
|
|
|
}
|
|
|
|
|
|
-EipBool8 IsConnectedOutputAssembly(const EipUint32 instance_number) {
|
|
|
+EipBool8 IsConnectedOutputAssembly(const CipInstanceNum instance_number) {
|
|
|
EipBool8 is_connected = false;
|
|
|
|
|
|
DoublyLinkedListNode *node = connection_list.first;
|
|
|
@@ -1713,8 +1716,8 @@ EipBool8 IsConnectedOutputAssembly(const EipUint32 instance_number) {
|
|
|
CipConnectionObject *connection_object = (CipConnectionObject *) node->data;
|
|
|
CipDword consumed_connection_point =
|
|
|
connection_object->consumed_path.instance_id;
|
|
|
- if( instance_number == consumed_connection_point &&
|
|
|
- true == ConnectionObjectIsTypeIOConnection(connection_object) ) {
|
|
|
+ if(instance_number == consumed_connection_point &&
|
|
|
+ true == ConnectionObjectIsTypeIOConnection(connection_object) ) {
|
|
|
is_connected = true;
|
|
|
break;
|
|
|
}
|
|
|
@@ -1784,17 +1787,18 @@ EipStatus TriggerConnections(unsigned int output_assembly,
|
|
|
|
|
|
void CheckForTimedOutConnectionsAndCloseTCPConnections(
|
|
|
const CipConnectionObject *const connection_object,
|
|
|
- CloseSessionFunction CloseSessions) {
|
|
|
+ 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) ) {
|
|
|
+ if(ConnectionObjectEqualOriginator(connection_object,
|
|
|
+ search_connection) &&
|
|
|
+ connection_object != search_connection
|
|
|
+ && kConnectionObjectStateTimedOut !=
|
|
|
+ ConnectionObjectGetState(search_connection) ) {
|
|
|
non_timed_out_connection_found = true;
|
|
|
break;
|
|
|
}
|
|
|
@@ -1806,10 +1810,9 @@ void CheckForTimedOutConnectionsAndCloseTCPConnections(
|
|
|
}
|
|
|
|
|
|
void InitializeConnectionManagerData() {
|
|
|
- memset( g_connection_management_list,
|
|
|
- 0,
|
|
|
- g_kNumberOfConnectableObjects *
|
|
|
- sizeof(ConnectionManagementHandling) );
|
|
|
+ memset(g_connection_management_list,
|
|
|
+ 0,
|
|
|
+ g_kNumberOfConnectableObjects * sizeof(ConnectionManagementHandling) );
|
|
|
InitializeClass3ConnectionData();
|
|
|
InitializeIoConnectionData();
|
|
|
}
|