Skip to content

Commit

Permalink
Merge branch 'micsat-master'
Browse files Browse the repository at this point in the history
  • Loading branch information
MartinMelikMerkumians committed May 19, 2021
2 parents 78db86b + dcdefc2 commit 79a1be7
Show file tree
Hide file tree
Showing 4 changed files with 240 additions and 5 deletions.
198 changes: 194 additions & 4 deletions source/src/cip/cipconnectionmanager.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,17 @@ EipStatus GetConnectionOwner(CipInstance *instance,
const struct sockaddr *originator_address,
const int encapsulation_session);

EipStatus GetConnectionData(CipInstance *instance,
CipMessageRouterRequest *message_router_request,
CipMessageRouterResponse *message_router_response);

EipStatus SearchConnectionData(CipInstance *instance,
CipMessageRouterRequest *message_router_request,
CipMessageRouterResponse *message_router_response);

void AssembleConnectionDataResponseMessage(CipMessageRouterResponse *message_router_response,
CipConnectionObject *connection_object);

EipStatus AssembleForwardOpenResponse(CipConnectionObject *connection_object,
CipMessageRouterResponse *message_router_response,
EipUint8 general_status,
Expand Down Expand Up @@ -212,7 +223,7 @@ EipStatus ConnectionManagerInit(EipUint16 unique_connection_id) {
2, /* # of class services */
0, /* # of instance attributes */
14, /* # highest instance attribute number*/
6, /* # of instance services */
8, /* # of instance services */
1, /* # of instances */
"connection manager", /* class name */
1, /* revision */
Expand All @@ -228,15 +239,30 @@ EipStatus ConnectionManagerInit(EipUint16 unique_connection_id) {
kGetAttributeAll,
&GetAttributeAll,
"GetAttributeAll");
InsertService(connection_manager, kForwardOpen, &ForwardOpen, "ForwardOpen");
InsertService(connection_manager, kLargeForwardOpen, &LargeForwardOpen,
InsertService(connection_manager,
kForwardOpen,
&ForwardOpen,
"ForwardOpen");
InsertService(connection_manager,
kLargeForwardOpen,
&LargeForwardOpen,
"LargeForwardOpen");
InsertService(connection_manager, kForwardClose, &ForwardClose,
InsertService(connection_manager,
kForwardClose,
&ForwardClose,
"ForwardClose");
InsertService(connection_manager,
kGetConnectionOwner,
&GetConnectionOwner,
"GetConnectionOwner");
InsertService(connection_manager,
kGetConnectionData,
&GetConnectionData,
"GetConnectionData");
InsertService(connection_manager,
kSearchConnectionData,
&SearchConnectionData,
"SearchConnectionData");

g_incarnation_id = ( (EipUint32) unique_connection_id ) << 16;

Expand Down Expand Up @@ -691,6 +717,170 @@ EipStatus GetConnectionOwner(CipInstance *instance,
return kEipStatusOk;
}

EipStatus GetConnectionData(
CipInstance *instance,
CipMessageRouterRequest *message_router_request,
CipMessageRouterResponse *message_router_response) {

CIPServiceCode service_code = kGetConnectionData;
message_router_response->reply_service = (0x80 | service_code);

//get Connection Number from request
EipUint16 Connection_number = GetUintFromMessage(&message_router_request->data);

OPENER_TRACE_INFO("GetConnectionData for Connection_number: %d\n", Connection_number);

//search connection
DoublyLinkedListNode *iterator = connection_list.first;
CipConnectionObject *search_connection_object = NULL;
CipConnectionObject *connection_object = NULL;

while (NULL != iterator) {
search_connection_object = iterator->data;

if ((search_connection_object->connection_number
== Connection_number)) {
connection_object = search_connection_object;
break;
}
iterator = iterator->next;
}

if(NULL != connection_object)
{
/* assemble response message */
AssembleConnectionDataResponseMessage(message_router_response, connection_object);
message_router_response->general_status = kEipStatusOk;
OPENER_TRACE_INFO("Connection found!\n");
}
else{
message_router_response->general_status = kCipErrorPathDestinationUnknown;
OPENER_TRACE_INFO("Connection not found!\n");
}

return kEipStatusOk;
}

EipStatus SearchConnectionData(
CipInstance *instance,
CipMessageRouterRequest *message_router_request,
CipMessageRouterResponse *message_router_response) {

CIPServiceCode service_code = kSearchConnectionData;
message_router_response->reply_service = (0x80 | service_code);

//connection data (connection triad) from request
EipUint16 Connection_serial_number = GetUintFromMessage(&message_router_request->data);
EipUint16 Originator_vendor_id = GetUintFromMessage(&message_router_request->data);
EipUint32 Originator_serial_number = GetUdintFromMessage(&message_router_request->data);

OPENER_TRACE_INFO("SearchConnectionData for ConnSerNo: %d, OrigVendId: %d, OrigSerNo: %ld,\n",
Connection_serial_number, Originator_vendor_id, Originator_serial_number);


//search connection
DoublyLinkedListNode *iterator = connection_list.first;
CipConnectionObject *search_connection_object = NULL;
CipConnectionObject *connection_object = NULL;

while (NULL != iterator) {
search_connection_object = iterator->data;

if ((search_connection_object->connection_serial_number
== Connection_serial_number)
&& (search_connection_object->originator_vendor_id
== Originator_vendor_id)
&& (search_connection_object->originator_serial_number
== Originator_serial_number)) {

connection_object = search_connection_object;
break;
}
iterator = iterator->next;
}
if(NULL != connection_object)
{
/* assemble response message */
AssembleConnectionDataResponseMessage(message_router_response, connection_object);
message_router_response->general_status = kEipStatusOk;
OPENER_TRACE_INFO("Connection found!\n");
}
else{
message_router_response->general_status = kCipErrorPathDestinationUnknown;
OPENER_TRACE_INFO("Connection not found!\n");
}

return kEipStatusOk;
}

void AssembleConnectionDataResponseMessage(CipMessageRouterResponse *message_router_response,
CipConnectionObject *connection_object) {

// Connection number UINT
AddIntToMessage(connection_object->connection_number,
&message_router_response->message);
// Connection state UINT
AddIntToMessage(connection_object->state,
&message_router_response->message);
// Originator Port UINT
AddIntToMessage(connection_object->originator_address.sin_port,
&message_router_response->message);
// Target Port UINT
AddIntToMessage(connection_object->remote_address.sin_port,
&message_router_response->message);
// Connection Serial Number UINT
AddIntToMessage(connection_object->connection_serial_number,
&message_router_response->message);
// Originator Vendor ID UINT
AddIntToMessage(connection_object->originator_vendor_id,
&message_router_response->message);
// Originator Serial number UDINT
AddDintToMessage(connection_object->originator_serial_number,
&message_router_response->message);
// Originator O->T CID UDINT
AddDintToMessage(connection_object->cip_consumed_connection_id,
&message_router_response->message);
// Target O->T CID UDINT
AddDintToMessage(connection_object->cip_consumed_connection_id,
&message_router_response->message);
// Connection Timeout Multiplier USINT
AddSintToMessage(connection_object->connection_timeout_multiplier,
&message_router_response->message);
// Reserved USINT
AddSintToMessage(0, &message_router_response->message);
// Reserved USINT
AddSintToMessage(0, &message_router_response->message);
// Reserved USINT
AddSintToMessage(0, &message_router_response->message);
// Originator RPI O->T UDINT
AddDintToMessage(connection_object->o_to_t_requested_packet_interval,
&message_router_response->message);
// Originator API O->T UDINT
AddDintToMessage(connection_object->transmission_trigger_timer,
&message_router_response->message);
// Originator T->O CID UDINT
AddDintToMessage(connection_object->cip_produced_connection_id,
&message_router_response->message);
// Target T->O CID UDINT
AddDintToMessage(connection_object->cip_produced_connection_id,
&message_router_response->message);
// Connection Timeout Multiplier USINT
AddSintToMessage(connection_object->connection_timeout_multiplier,
&message_router_response->message);
// Reserved USINT
AddSintToMessage(0, &message_router_response->message);
// Reserved USINT
AddSintToMessage(0, &message_router_response->message);
// Reserved USINT
AddSintToMessage(0, &message_router_response->message);
// Originator RPI T->O UDINT
AddDintToMessage(connection_object->t_to_o_requested_packet_interval,
&message_router_response->message);
// Originator API T->O UDINT
AddDintToMessage(connection_object->transmission_trigger_timer,
&message_router_response->message);
}

EipStatus ManageConnections(MilliSeconds elapsed_time) {
//OPENER_TRACE_INFO("Entering ManageConnections\n");
/*Inform application that it can execute */
Expand Down
33 changes: 33 additions & 0 deletions source/src/cip/cipconnectionobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "endianconv.h"
#include "trace.h"
#include "cipconnectionmanager.h"
#include "stdlib.h"

#define CIP_CONNECTION_OBJECT_STATE_NON_EXISTENT 0U
#define CIP_CONNECTION_OBJECT_STATE_CONFIGURING 1U
Expand Down Expand Up @@ -136,6 +137,8 @@ void ConnectionObjectInitializeFromMessage(const CipOctet **message,
ConnectionObjectSetOriginatorSerialNumber(connection_object,
GetUdintFromMessage(message) );

ConnectionObjectSetConnectionNumber(connection_object);

/* keep it to none existent till the setup is done this eases error handling and
* the state changes within the forward open request can not be detected from
* the application or from outside (reason we are single threaded)
Expand Down Expand Up @@ -644,6 +647,36 @@ void ConnectionObjectSetOriginatorSerialNumber(
connection_object->originator_serial_number = originator_serial_number;
}

CipUdint ConnectionObjectGetConnectionlNumber(
const CipConnectionObject *const connection_object) {
return connection_object->connection_number;
}

void ConnectionObjectSetConnectionNumber(
CipConnectionObject *connection_object) {
connection_object->connection_number = GenerateRandomConnectionNumber();
}

CipUint GenerateRandomConnectionNumber(void) {
CipUint rand_num = (CipUint)rand(); //TODO: update to random.c functions

//search for existing connection_numbers
DoublyLinkedListNode *iterator = connection_list.first;
CipConnectionObject *search_connection_object = NULL;

while (NULL != iterator) {
search_connection_object = iterator->data;

if ((search_connection_object->connection_number == rand_num)) {

rand_num = GenerateRandomConnectionNumber();
}
iterator = iterator->next;
}

return rand_num;
}

CipUsint ConnectionObjectGetConnectionTimeoutMultiplier(
const CipConnectionObject *const connection_object) {
return connection_object->connection_timeout_multiplier;
Expand Down
11 changes: 11 additions & 0 deletions source/src/cip/cipconnectionobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,8 @@ struct cip_connection_object {
CipUint originator_vendor_id;
CipUdint originator_serial_number;

CipUint connection_number;

CipUdint o_to_t_requested_packet_interval;
CipDword o_to_t_network_connection_parameters;

Expand Down Expand Up @@ -359,6 +361,15 @@ void ConnectionObjectSetOriginatorSerialNumber(
CipConnectionObject *connection_object,
CipUdint originator_serial_number);

void ConnectionObjectGetConnectionNumber(
CipConnectionObject *connection_object,
const CipUint connection_number);

void ConnectionObjectSetConnectionNumber(
CipConnectionObject *connection_object);

CipUint GenerateRandomConnectionNumber(void);

CipUdint ConnectionObjectGetOToTRequestedPacketInterval(
const CipConnectionObject *const connection_object);

Expand Down
3 changes: 2 additions & 1 deletion source/src/cip/ciptypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@ typedef enum {
kForwardClose = 0x4E,
kUnconnectedSend = 0x52,
kGetConnectionOwner = 0x5A,
kGetConnectionData = 0x56
kGetConnectionData = 0x56,
kSearchConnectionData = 0x57
/* End CIP object-specific services */
} CIPServiceCode;

Expand Down

0 comments on commit 79a1be7

Please sign in to comment.