OpENer - Open Source EtherNet/IP(TM) I/O Target Stack  2.1
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
encap.c File Reference
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include "encap.h"
#include "opener_api.h"
#include "cpf.h"
#include "endianconv.h"
#include "cipcommon.h"
#include "cipmessagerouter.h"
#include "cipconnectionmanager.h"
#include "cipidentity.h"
#include "generic_networkhandler.h"
#include "trace.h"
#include "socket_timer.h"
#include "opener_error.h"
Include dependency graph for encap.c:

Go to the source code of this file.

Data Structures

struct  DelayedEncapsulationMessage
 Delayed Encapsulation Message structure. More...
 

Macros

#define ENCAP_MAX_DELAYED_ENCAP_MESSAGE_SIZE
 
#define ENCAP_NUMBER_OF_SUPPORTED_DELAYED_ENCAP_MESSAGES   2
 

Enumerations

enum  CapabilityFlags { kCapabilityFlagsCipTcp = 0x0020, kCapabilityFlagsCipUdpClass0or1 = 0x0100 }
 definition of capability flags More...
 
enum  EncapsulationCommand {
  kEncapsulationCommandNoOperation = 0x0000, kEncapsulationCommandListServices = 0x0004, kEncapsulationCommandListIdentity = 0x0063, kEncapsulationCommandListInterfaces = 0x0064,
  kEncapsulationCommandRegisterSession = 0x0065, kEncapsulationCommandUnregisterSession = 0x0066, kEncapsulationCommandSendRequestReplyData = 0x006F, kEncapsulationCommandSendUnitData = 0x0070
}
 definition of known encapsulation commands More...
 
enum  SessionStatus { kSessionStatusInvalid = -1, kSessionStatusValid = 0 }
 

Functions

SessionStatus CheckRegisteredSessions (const EncapsulationData *const receive_data)
 Check if received package belongs to registered session. More...
 
void CloseClass3ConnectionBasedOnSession (size_t encapsulation_session_handle)
 
void CloseEncapsulationSessionBySockAddr (const CipConnectionObject *const connection_object)
 
void CloseSession (int socket)
 Inform the encapsulation layer that the remote host has closed the connection. More...
 
void CloseSessionBySessionHandle (const CipConnectionObject *const connection_object)
 
EipInt16 CreateEncapsulationStructure (const EipUint8 *receive_buffer, int receive_buffer_length, EncapsulationData *const encapsulation_data)
 copy data from pa_buf in little endian to host in structure. More...
 
void DetermineDelayTime (const EipByte *const buffer_start, DelayedEncapsulationMessage *const delayed_message_buffer)
 
void EncapsulateListIdentityResponseMessage (const EncapsulationData *const receive_data, ENIPMessage *const outgoing_message)
 
void EncapsulateRegisterSessionCommandResponseMessage (const EncapsulationData *const receive_data, const size_t session_handle, const EncapsulationProtocolErrorCode encapsulation_protocol_status, ENIPMessage *const outgoing_message)
 
void EncapsulationInit (void)
 Initialize the encapsulation layer. More...
 
void EncapsulationShutDown (void)
 Shutdown the encapsulation layer. More...
 
void GenerateEncapsulationHeader (const EncapsulationData *const receive_data, const size_t command_specific_data_length, const size_t session_handle, const EncapsulationProtocolErrorCode encapsulation_protocol_status, ENIPMessage *const outgoing_message)
 
int GetFreeSessionIndex (void)
 search for available sessions an return index. More...
 
size_t GetSessionFromSocket (const int socket_handle)
 
int HandleReceivedExplictTcpData (int socket, EipUint8 *buffer, size_t length, int *remaining_bytes, struct sockaddr *originator_address, ENIPMessage *const outgoing_message)
 Notify the encapsulation layer that an explicit message has been received via TCP. More...
 
int HandleReceivedExplictUdpData (const int socket, const struct sockaddr_in *from_address, const EipUint8 *buffer, const size_t buffer_length, int *number_of_remaining_bytes, bool unicast, ENIPMessage *const outgoing_message)
 Notify the encapsulation layer that an explicit message has been received via UDP. More...
 
EipStatus HandleReceivedInvalidCommand (const EncapsulationData *const receive_data, ENIPMessage *const outgoing_message)
 
void HandleReceivedListIdentityCommandTcp (const EncapsulationData *const receive_data, ENIPMessage *const outgoing_message)
 
void HandleReceivedListIdentityCommandUdp (const int socket, const struct sockaddr_in *const from_address, const EncapsulationData *const receive_data, ENIPMessage *const outgoing_message)
 
void HandleReceivedListInterfacesCommand (const EncapsulationData *const receive_data, ENIPMessage *const outgoing_message)
 
void HandleReceivedListServicesCommand (const EncapsulationData *const receive_data, ENIPMessage *const outgoing_message)
 generate reply with "Communications Services" + compatibility Flags. More...
 
void HandleReceivedRegisterSessionCommand (int socket, const EncapsulationData *const receive_data, ENIPMessage *const outgoing_message)
 
EipStatus HandleReceivedSendRequestResponseDataCommand (const EncapsulationData *const receive_data, const struct sockaddr *const originator_address, ENIPMessage *const outgoing_message)
 Call UCMM or Message Router if UCMM not implemented. More...
 
EipStatus HandleReceivedSendUnitDataCommand (const EncapsulationData *const receive_data, const struct sockaddr *const originator_address, ENIPMessage *const outgoing_message)
 Call Connection Manager. More...
 
EipStatus HandleReceivedUnregisterSessionCommand (const EncapsulationData *const receive_data, ENIPMessage *const outgoing_message)
 
void ManageEncapsulationMessages (const MilliSeconds elapsed_time)
 Handle delayed encapsulation message responses. More...
 
void RemoveSession (const int socket)
 
void SkipEncapsulationHeader (ENIPMessage *const outgoing_message)
 

Variables

CipUint device_type_
 
DelayedEncapsulationMessage g_delayed_encapsulation_messages [ENCAP_NUMBER_OF_SUPPORTED_DELAYED_ENCAP_MESSAGES]
 
EncapsulationInterfaceInformation g_interface_information
 
int g_registered_sessions [OPENER_NUMBER_OF_SUPPORTED_SESSIONS]
 
CipTcpIpNetworkInterfaceConfiguration interface_configuration_
 
const int kEncapsulationHeaderOptionsFlag = 0x00
 
const int kEncapsulationHeaderSessionHandlePosition = 4
 
const int kListIdentityDefaultDelayTime = 2000
 
const int kListIdentityMinimumDelayTime = 500
 
const int kSenderContextSize = 8
 
const int kSupportedProtocolVersion = 1
 
CipUint product_code_
 
CipShortString product_name_
 
CipRevision revision_
 
CipUdint serial_number_
 
CipWord status_
 
CipUint vendor_id_
 

Macro Definition Documentation

#define ENCAP_MAX_DELAYED_ENCAP_MESSAGE_SIZE
Value:
39 + sizeof(OPENER_DEVICE_NAME) ) /* currently we only have the size of an encapsulation message */
#define ENCAPSULATION_HEADER_LENGTH
Definition: encap.h:22
#define OPENER_DEVICE_NAME
Definition: devicedata.h:15

Definition at line 70 of file encap.c.

#define ENCAP_NUMBER_OF_SUPPORTED_DELAYED_ENCAP_MESSAGES   2

According to EIP spec at least 2 delayed message requests should be supported

Definition at line 68 of file encap.c.

Referenced by EncapsulationInit(), HandleReceivedListIdentityCommandUdp(), and ManageEncapsulationMessages().

Enumeration Type Documentation

definition of capability flags

Enumerator
kCapabilityFlagsCipTcp 
kCapabilityFlagsCipUdpClass0or1 

Definition at line 64 of file encap.c.

definition of known encapsulation commands

Enumerator
kEncapsulationCommandNoOperation 

only allowed for TCP

kEncapsulationCommandListServices 

allowed for both UDP and TCP

kEncapsulationCommandListIdentity 

allowed for both UDP and TCP

kEncapsulationCommandListInterfaces 

optional, allowed for both UDP and TCP

kEncapsulationCommandRegisterSession 

only allowed for TCP

kEncapsulationCommandUnregisterSession 

only allowed for TCP

kEncapsulationCommandSendRequestReplyData 

only allowed for TCP

kEncapsulationCommandSendUnitData 

only allowed for TCP

Definition at line 52 of file encap.c.

Enumerator
kSessionStatusInvalid 
kSessionStatusValid 

Definition at line 45 of file encap.c.

Function Documentation

SessionStatus CheckRegisteredSessions ( const EncapsulationData *const  receive_data)

Check if received package belongs to registered session.

Parameters
receive_dataReceived data.
Returns
0 .. Session registered kInvalidSession .. invalid session -> return unsupported command received

Definition at line 800 of file encap.c.

References g_registered_sessions, kSessionStatusInvalid, kSessionStatusValid, OPENER_NUMBER_OF_SUPPORTED_SESSIONS, and encapsulation_data::session_handle.

Referenced by HandleReceivedSendRequestResponseDataCommand(), and HandleReceivedSendUnitDataCommand().

Here is the caller graph for this function:

void CloseClass3ConnectionBasedOnSession ( size_t  encapsulation_session_handle)

Definition at line 906 of file encap.c.

References cip_connection_object::associated_encapsulation_session, cip_connection_object::connection_close_function, connection_list, ConnectionObjectGetTransportClassTriggerTransportClass(), doubly_linked_list_node::data, DoublyLinkedList::first, kConnectionObjectTransportClassTriggerTransportClass3, and doubly_linked_list_node::next.

Referenced by CheckEncapsulationInactivity(), CloseSession(), HandleReceivedUnregisterSessionCommand(), and RemoveSession().

Here is the call graph for this function:

Here is the caller graph for this function:

void CloseEncapsulationSessionBySockAddr ( const CipConnectionObject *const  connection_object)

Definition at line 874 of file encap.c.

References CloseSession(), FreeErrorMessage(), g_registered_sessions, GetErrorMessage(), GetSocketErrorNumber(), OPENER_NUMBER_OF_SUPPORTED_SESSIONS, OPENER_TRACE_ERR, and cip_connection_object::originator_address.

Referenced by HandleIoConnectionTimeOut().

Here is the call graph for this function:

Here is the caller graph for this function:

void CloseSessionBySessionHandle ( const CipConnectionObject *const  connection_object)

Definition at line 813 of file encap.c.

References cip_connection_object::associated_encapsulation_session, CloseTcpSocket(), g_registered_sessions, and OPENER_TRACE_INFO.

Referenced by Class3ConnectionTimeoutHandler().

Here is the call graph for this function:

Here is the caller graph for this function:

EipInt16 CreateEncapsulationStructure ( const EipUint8 receive_buffer,
int  receive_buffer_length,
EncapsulationData *const  encapsulation_data 
)

copy data from pa_buf in little endian to host in structure.

Parameters
receive_bufferReceived message
receive_buffer_lengthLength of the data in receive_buffer. Might be more than one message
encapsulation_datastructure to which data shall be copied
Returns
return difference between bytes in pa_buf an data_length 0 .. full package received >0 .. more than one packet received <0 .. only fragment of data portion received

Definition at line 774 of file encap.c.

References encapsulation_data::command_code, encapsulation_data::communication_buffer_start, encapsulation_data::current_communication_buffer_position, encapsulation_data::data_length, ENCAPSULATION_HEADER_LENGTH, GetDintFromMessage(), GetIntFromMessage(), kSenderContextSize, encapsulation_data::options, encapsulation_data::sender_context, encapsulation_data::session_handle, and encapsulation_data::status.

Referenced by HandleReceivedExplictTcpData(), and HandleReceivedExplictUdpData().

Here is the call graph for this function:

Here is the caller graph for this function:

void DetermineDelayTime ( const EipByte *const  buffer_start,
DelayedEncapsulationMessage *const  delayed_message_buffer 
)

Definition at line 513 of file encap.c.

References GetIntFromMessage(), kListIdentityDefaultDelayTime, kListIdentityMinimumDelayTime, MoveMessageNOctets(), and DelayedEncapsulationMessage::time_out.

Referenced by HandleReceivedListIdentityCommandUdp().

Here is the call graph for this function:

Here is the caller graph for this function:

void EncapsulateListIdentityResponseMessage ( const EncapsulationData *const  receive_data,
ENIPMessage *const  outgoing_message 
)

Array of USINT - length 8 shall be set to zero

Definition at line 436 of file encap.c.

References AddDintToMessage(), AddIntToMessage(), enip_message::current_message_position, device_type_, EncapsulateIpAddress(), GenerateEncapsulationHeader(), CipTcpIpNetworkInterfaceConfiguration::ip_address, kEncapsulationProtocolSuccess, kSupportedProtocolVersion, CipShortString::length, CipRevision::major_revision, CipRevision::minor_revision, MoveMessageNOctets(), product_code_, serial_number_, status_, CipShortString::string, enip_message::used_message_length, and vendor_id_.

Referenced by HandleReceivedListIdentityCommandTcp(), and HandleReceivedListIdentityCommandUdp().

Here is the call graph for this function:

Here is the caller graph for this function:

void EncapsulateRegisterSessionCommandResponseMessage ( const EncapsulationData *const  receive_data,
const size_t  session_handle,
const EncapsulationProtocolErrorCode  encapsulation_protocol_status,
ENIPMessage *const  outgoing_message 
)

Definition at line 529 of file encap.c.

References AddIntToMessage(), enip_message::current_message_position, GenerateEncapsulationHeader(), and enip_message::used_message_length.

Referenced by HandleReceivedRegisterSessionCommand().

Here is the call graph for this function:

Here is the caller graph for this function:

void GenerateEncapsulationHeader ( const EncapsulationData *const  receive_data,
const size_t  command_specific_data_length,
const size_t  session_handle,
const EncapsulationProtocolErrorCode  encapsulation_protocol_status,
ENIPMessage *const  outgoing_message 
)
int GetFreeSessionIndex ( void  )

search for available sessions an return index.

Returns
return index of free session in anRegisteredSessions. kInvalidSession .. no free session available

Definition at line 754 of file encap.c.

References g_registered_sessions, kSessionStatusInvalid, and OPENER_NUMBER_OF_SUPPORTED_SESSIONS.

Referenced by HandleReceivedRegisterSessionCommand().

Here is the caller graph for this function:

size_t GetSessionFromSocket ( const int  socket_handle)

Definition at line 897 of file encap.c.

References g_registered_sessions, and OPENER_NUMBER_OF_SUPPORTED_SESSIONS.

Referenced by CheckEncapsulationInactivity().

Here is the caller graph for this function:

EipStatus HandleReceivedInvalidCommand ( const EncapsulationData *const  receive_data,
ENIPMessage *const  outgoing_message 
)

Definition at line 736 of file encap.c.

References GenerateEncapsulationHeader(), kEncapsulationProtocolInvalidCommand, encapsulation_data::session_handle, and enip_message::used_message_length.

Referenced by HandleReceivedExplictTcpData().

Here is the call graph for this function:

Here is the caller graph for this function:

void HandleReceivedListIdentityCommandTcp ( const EncapsulationData *const  receive_data,
ENIPMessage *const  outgoing_message 
)

Definition at line 399 of file encap.c.

References EncapsulateListIdentityResponseMessage().

Referenced by HandleReceivedExplictTcpData(), and HandleReceivedExplictUdpData().

Here is the call graph for this function:

Here is the caller graph for this function:

void HandleReceivedListIdentityCommandUdp ( const int  socket,
const struct sockaddr_in *const  from_address,
const EncapsulationData *const  receive_data,
ENIPMessage *const  outgoing_message 
)

Definition at line 405 of file encap.c.

References encapsulation_data::communication_buffer_start, DetermineDelayTime(), ENCAP_NUMBER_OF_SUPPORTED_DELAYED_ENCAP_MESSAGES, EncapsulateListIdentityResponseMessage(), ENCAPSULATION_HEADER_LENGTH, DelayedEncapsulationMessage::message, DelayedEncapsulationMessage::receiver, and DelayedEncapsulationMessage::socket.

Referenced by HandleReceivedExplictUdpData().

Here is the call graph for this function:

Here is the caller graph for this function:

void HandleReceivedListInterfacesCommand ( const EncapsulationData *const  receive_data,
ENIPMessage *const  outgoing_message 
)

Definition at line 381 of file encap.c.

References AddIntToMessage(), enip_message::current_message_position, GenerateEncapsulationHeader(), kEncapsulationProtocolSuccess, and enip_message::used_message_length.

Referenced by HandleReceivedExplictTcpData(), and HandleReceivedExplictUdpData().

Here is the call graph for this function:

Here is the caller graph for this function:

void HandleReceivedListServicesCommand ( const EncapsulationData *const  receive_data,
ENIPMessage *const  outgoing_message 
)

generate reply with "Communications Services" + compatibility Flags.

Parameters
receive_datapointer to structure with received data
outgoing_messageThe outgoing ENIP message

Definition at line 345 of file encap.c.

References AddIntToMessage(), encapsulation_interface_information::capability_flags, enip_message::current_message_position, encapsulation_interface_information::encapsulation_protocol_version, GenerateEncapsulationHeader(), kEncapsulationProtocolSuccess, encapsulation_interface_information::length, encapsulation_interface_information::name_of_service, encapsulation_interface_information::type_code, and enip_message::used_message_length.

Referenced by HandleReceivedExplictTcpData(), and HandleReceivedExplictUdpData().

Here is the call graph for this function:

Here is the caller graph for this function:

void HandleReceivedRegisterSessionCommand ( int  socket,
const EncapsulationData *const  receive_data,
ENIPMessage *const  outgoing_message 
)

Definition at line 556 of file encap.c.

References encapsulation_data::current_communication_buffer_position, EncapsulateRegisterSessionCommandResponseMessage(), g_actual_time, g_registered_sessions, g_timestamps, GetFreeSessionIndex(), GetIntFromMessage(), kEncapsulationProtocolInsufficientMemory, kEncapsulationProtocolInvalidCommand, kEncapsulationProtocolSuccess, kEncapsulationProtocolUnsupportedProtocol, kSessionStatusInvalid, kSupportedProtocolVersion, OPENER_NUMBER_OF_SUPPORTED_SESSIONS, OPENER_TRACE_INFO, SocketTimerArrayGetEmptySocketTimer(), SocketTimerSetLastUpdate(), and SocketTimerSetSocket().

Referenced by HandleReceivedExplictTcpData().

Here is the call graph for this function:

Here is the caller graph for this function:

EipStatus HandleReceivedSendRequestResponseDataCommand ( const EncapsulationData *const  receive_data,
const struct sockaddr *const  originator_address,
ENIPMessage *const  outgoing_message 
)

Call UCMM or Message Router if UCMM not implemented.

Parameters
receive_dataPointer to structure with data and header information.
originator_addressAddress of the originator as received from socket
outgoing_messageThe outgoing ENIP message
Returns
status kEipStatusOk .. success. kEipStatusError .. error

Definition at line 698 of file encap.c.

References CheckRegisteredSessions(), encapsulation_data::current_communication_buffer_position, encapsulation_data::data_length, GenerateEncapsulationHeader(), GetDintFromMessage(), GetIntFromMessage(), InitializeENIPMessage(), kEipStatusError, kEipStatusOkSend, kEncapsulationProtocolInvalidSessionHandle, kSessionStatusValid, NotifyCommonPacketFormat(), and encapsulation_data::session_handle.

Referenced by HandleReceivedExplictTcpData().

Here is the call graph for this function:

Here is the caller graph for this function:

EipStatus HandleReceivedSendUnitDataCommand ( const EncapsulationData *const  receive_data,
const struct sockaddr *const  originator_address,
ENIPMessage *const  outgoing_message 
)

Call Connection Manager.

Parameters
receive_dataPointer to structure with data and header information.
originator_addressAddress of the originator as received from socket
outgoing_messageThe outgoing ENIP message

Definition at line 652 of file encap.c.

References CheckRegisteredSessions(), encapsulation_data::current_communication_buffer_position, encapsulation_data::data_length, GenerateEncapsulationHeader(), GetDintFromMessage(), GetIntFromMessage(), InitializeENIPMessage(), kEipStatusError, kEipStatusOkSend, kEncapsulationProtocolInvalidSessionHandle, kSessionStatusValid, NotifyConnectedCommonPacketFormat(), and encapsulation_data::session_handle.

Referenced by HandleReceivedExplictTcpData().

Here is the call graph for this function:

Here is the caller graph for this function:

EipStatus HandleReceivedUnregisterSessionCommand ( const EncapsulationData *const  receive_data,
ENIPMessage *const  outgoing_message 
)

Definition at line 622 of file encap.c.

References CloseClass3ConnectionBasedOnSession(), CloseTcpSocket(), g_registered_sessions, GenerateEncapsulationHeader(), kEipStatusOk, kEipStatusOkSend, kEncapsulationProtocolInvalidSessionHandle, OPENER_NUMBER_OF_SUPPORTED_SESSIONS, OPENER_TRACE_INFO, and encapsulation_data::session_handle.

Referenced by HandleReceivedExplictTcpData().

Here is the call graph for this function:

Here is the caller graph for this function:

void RemoveSession ( const int  socket)

Definition at line 835 of file encap.c.

References CloseClass3ConnectionBasedOnSession(), g_registered_sessions, OPENER_NUMBER_OF_SUPPORTED_SESSIONS, and OPENER_TRACE_INFO.

Referenced by CheckEncapsulationInactivity(), HandleDataOnTcpSocket(), and NetworkHandlerProcessOnce().

Here is the call graph for this function:

Here is the caller graph for this function:

void SkipEncapsulationHeader ( ENIPMessage *const  outgoing_message)

Definition at line 312 of file encap.c.

References enip_message::current_message_position, ENCAPSULATION_HEADER_LENGTH, and MoveMessageNOctets().

Referenced by NotifyCommonPacketFormat(), and NotifyConnectedCommonPacketFormat().

Here is the call graph for this function:

Here is the caller graph for this function:

Variable Documentation

CipUint device_type_

Attribute 2: Device Type

Definition at line 42 of file cipidentity.c.

Referenced by CipIdentityInit(), and EncapsulateListIdentityResponseMessage().

Definition at line 89 of file encap.c.

EncapsulationInterfaceInformation g_interface_information

Definition at line 84 of file encap.c.

Referenced by EncapsulationInit().

CipTcpIpNetworkInterfaceConfiguration interface_configuration_

#5 IP, network mask, gateway, name server 1 & 2, domain name

Definition at line 30 of file ciptcpipinterface.c.

const int kEncapsulationHeaderOptionsFlag = 0x00

Mask of which options are supported as of the current CIP specs no other option value as 0 should be supported.

Definition at line 38 of file encap.c.

Referenced by HandleReceivedExplictTcpData(), and HandleReceivedExplictUdpData().

const int kEncapsulationHeaderSessionHandlePosition = 4

the position of the session handle within the encapsulation header

Definition at line 40 of file encap.c.

const int kListIdentityDefaultDelayTime = 2000

Default delay time for List Identity response

Definition at line 42 of file encap.c.

Referenced by DetermineDelayTime().

const int kListIdentityMinimumDelayTime = 500

Minimum delay time for List Identity response

Definition at line 43 of file encap.c.

Referenced by DetermineDelayTime().

const int kSenderContextSize = 8

size of sender context in encapsulation header

Definition at line 49 of file encap.c.

Referenced by CreateEncapsulationStructure(), and GenerateEncapsulationHeader().

const int kSupportedProtocolVersion = 1

Supported Encapsulation protocol version

Definition at line 36 of file encap.c.

Referenced by EncapsulateListIdentityResponseMessage(), and HandleReceivedRegisterSessionCommand().

CipUint product_code_

Attribute 3: Product Code

Definition at line 43 of file cipidentity.c.

Referenced by CipIdentityInit(), and EncapsulateListIdentityResponseMessage().

CipShortString product_name_

Attribute 7: Product Name

Definition at line 48 of file cipidentity.c.

CipRevision revision_

Attribute 4: Revision / USINT Major, USINT Minor

Definition at line 44 of file cipidentity.c.

CipUdint serial_number_

Attribute 6: Serial Number, has to be set prior to OpENer initialization

Definition at line 47 of file cipidentity.c.

Referenced by CipIdentityInit(), EncapsulateListIdentityResponseMessage(), and SetDeviceSerialNumber().

CipUint vendor_id_

Attribute 1: Vendor ID

Definition at line 41 of file cipidentity.c.

Referenced by CipIdentityInit(), and EncapsulateListIdentityResponseMessage().