OpENeruCPort/OrginalSourceRepo/OpENer-master/source/src/cip/cipclass3connection.c

97 lines
3.2 KiB
C

/*******************************************************************************
* Copyright (c) 2011, Rockwell Automation, Inc.
* All rights reserved.
*
******************************************************************************/
#include <string.h>
#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 ****/
CipError EstablishClass3Connection(
CipConnectionObject *RESTRICT const connection_object,
EipUint16 *const extended_error) {
CipError cip_error = kCipErrorSuccess;
CipConnectionObject *explicit_connection = GetFreeExplicitConnection();
if (NULL == explicit_connection) {
cip_error = kCipErrorConnectionFailure;
*extended_error =
kConnectionManagerExtendedStatusCodeErrorNoMoreConnectionsAvailable;
} else {
ConnectionObjectDeepCopy(explicit_connection, connection_object);
ConnectionObjectGeneralConfiguration(explicit_connection);
ConnectionObjectSetInstanceType(explicit_connection,
kConnectionObjectInstanceTypeExplicitMessaging);
/* set the connection call backs */
explicit_connection->connection_close_function =
CloseConnection;
/* explicit connection have to be closed on time out*/
explicit_connection->connection_timeout_function =
Class3ConnectionTimeoutHandler;
AddNewActiveConnection(explicit_connection);
}
return cip_error;
}
/** @brief Searches and returns a free explicit connection slot
*
* @return Free explicit connection slot, or NULL if no slot is free
*/
CipConnectionObject *GetFreeExplicitConnection(void) {
for (size_t i = 0; i < OPENER_CIP_NUM_EXPLICIT_CONNS; ++i) {
if (ConnectionObjectGetState(&(explicit_connection_object_pool[i]) ) ==
kConnectionObjectStateNonExistent) {
return &(explicit_connection_object_pool[i]);
}
}
return NULL;
}
void InitializeClass3ConnectionData(void) {
memset( explicit_connection_object_pool, 0,
OPENER_CIP_NUM_EXPLICIT_CONNS * sizeof(CipConnectionObject) );
}
EipStatus CipClass3ConnectionObjectStateEstablishedHandler(
CipConnectionObject *RESTRICT const connection_object,
ConnectionObjectState new_state) {
switch(new_state) {
case kConnectionObjectStateNonExistent:
ConnectionObjectInitializeEmpty(connection_object);
ConnectionObjectSetState(connection_object, new_state);
return kEipStatusOk;
default: return kEipStatusError;
}
}
EipStatus CipClass3ConnectionObjectStateNonExistentHandler(
CipConnectionObject *RESTRICT const connection_object,
ConnectionObjectState new_state) {
switch(new_state) {
case kConnectionObjectStateEstablished:
ConnectionObjectSetState(connection_object, new_state);
return kEipStatusOk;
default: return kEipStatusError;
}
}