|
|
@ -3,7 +3,7 @@
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* Client side representation of the ISO stack (COTP, session, presentation, ACSE)
|
|
|
|
* Client side representation of the ISO stack (COTP, session, presentation, ACSE)
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* Copyright 2013-2022 Michael Zillgith
|
|
|
|
* Copyright 2013-2024 Michael Zillgith
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* This file is part of libIEC61850.
|
|
|
|
* This file is part of libIEC61850.
|
|
|
|
*
|
|
|
|
*
|
|
|
@ -146,7 +146,8 @@ IsoClientConnection_create(IsoConnectionParameters parameters, IsoIndicationCall
|
|
|
|
{
|
|
|
|
{
|
|
|
|
IsoClientConnection self = (IsoClientConnection) GLOBAL_CALLOC(1, sizeof(struct sIsoClientConnection));
|
|
|
|
IsoClientConnection self = (IsoClientConnection) GLOBAL_CALLOC(1, sizeof(struct sIsoClientConnection));
|
|
|
|
|
|
|
|
|
|
|
|
if (self) {
|
|
|
|
if (self)
|
|
|
|
|
|
|
|
{
|
|
|
|
self->parameters = parameters;
|
|
|
|
self->parameters = parameters;
|
|
|
|
self->callback = callback;
|
|
|
|
self->callback = callback;
|
|
|
|
self->callbackParameter = callbackParameter;
|
|
|
|
self->callbackParameter = callbackParameter;
|
|
|
@ -196,7 +197,8 @@ sendConnectionRequestMessage(IsoClientConnection self)
|
|
|
|
int socketExtensionBufferSize = CONFIG_MMS_MAXIMUM_PDU_SIZE + 1000;
|
|
|
|
int socketExtensionBufferSize = CONFIG_MMS_MAXIMUM_PDU_SIZE + 1000;
|
|
|
|
uint8_t* socketExtensionBuffer = NULL;
|
|
|
|
uint8_t* socketExtensionBuffer = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
if (self->cotpConnection) {
|
|
|
|
if (self->cotpConnection)
|
|
|
|
|
|
|
|
{
|
|
|
|
/* Destroy existing handle set when connection is reused */
|
|
|
|
/* Destroy existing handle set when connection is reused */
|
|
|
|
if (self->cotpConnection->handleSet)
|
|
|
|
if (self->cotpConnection->handleSet)
|
|
|
|
Handleset_destroy(self->cotpConnection->handleSet);
|
|
|
|
Handleset_destroy(self->cotpConnection->handleSet);
|
|
|
@ -205,19 +207,20 @@ sendConnectionRequestMessage(IsoClientConnection self)
|
|
|
|
socketExtensionBuffer = self->cotpConnection->socketExtensionBuffer;
|
|
|
|
socketExtensionBuffer = self->cotpConnection->socketExtensionBuffer;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (socketExtensionBuffer == NULL) {
|
|
|
|
if (socketExtensionBuffer == NULL)
|
|
|
|
|
|
|
|
{
|
|
|
|
socketExtensionBuffer = (uint8_t*)GLOBAL_MALLOC(socketExtensionBufferSize);
|
|
|
|
socketExtensionBuffer = (uint8_t*)GLOBAL_MALLOC(socketExtensionBufferSize);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (socketExtensionBuffer) {
|
|
|
|
if (socketExtensionBuffer)
|
|
|
|
|
|
|
|
{
|
|
|
|
/* COTP (ISO transport) handshake */
|
|
|
|
/* COTP (ISO transport) handshake */
|
|
|
|
CotpConnection_init(self->cotpConnection, self->socket, self->receiveBuffer, self->cotpReadBuffer, self->cotpWriteBuffer,
|
|
|
|
CotpConnection_init(self->cotpConnection, self->socket, self->receiveBuffer, self->cotpReadBuffer, self->cotpWriteBuffer,
|
|
|
|
socketExtensionBuffer, socketExtensionBufferSize);
|
|
|
|
socketExtensionBuffer, socketExtensionBufferSize);
|
|
|
|
|
|
|
|
|
|
|
|
#if (CONFIG_MMS_SUPPORT_TLS == 1)
|
|
|
|
#if (CONFIG_MMS_SUPPORT_TLS == 1)
|
|
|
|
if (self->parameters->tlsConfiguration) {
|
|
|
|
if (self->parameters->tlsConfiguration)
|
|
|
|
|
|
|
|
{
|
|
|
|
TLSConfiguration_setClientMode(self->parameters->tlsConfiguration);
|
|
|
|
TLSConfiguration_setClientMode(self->parameters->tlsConfiguration);
|
|
|
|
|
|
|
|
|
|
|
|
/* create TLSSocket and start TLS authentication */
|
|
|
|
/* create TLSSocket and start TLS authentication */
|
|
|
@ -225,8 +228,8 @@ sendConnectionRequestMessage(IsoClientConnection self)
|
|
|
|
|
|
|
|
|
|
|
|
if (tlsSocket)
|
|
|
|
if (tlsSocket)
|
|
|
|
self->cotpConnection->tlsSocket = tlsSocket;
|
|
|
|
self->cotpConnection->tlsSocket = tlsSocket;
|
|
|
|
else {
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
if (DEBUG_ISO_CLIENT)
|
|
|
|
if (DEBUG_ISO_CLIENT)
|
|
|
|
printf("ISO_CLIENT: TLS handshake failed!\n");
|
|
|
|
printf("ISO_CLIENT: TLS handshake failed!\n");
|
|
|
|
|
|
|
|
|
|
|
@ -244,7 +247,8 @@ sendConnectionRequestMessage(IsoClientConnection self)
|
|
|
|
else
|
|
|
|
else
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
if (DEBUG_ISO_CLIENT)
|
|
|
|
if (DEBUG_ISO_CLIENT)
|
|
|
|
printf("ISO_CLIENT: Failed to allocate socket extension buffer\n");
|
|
|
|
printf("ISO_CLIENT: Failed to allocate socket extension buffer\n");
|
|
|
|
|
|
|
|
|
|
|
@ -298,14 +302,14 @@ sendAcseInitiateRequest(IsoClientConnection self)
|
|
|
|
Semaphore_post(self->transmitBufferMutex);
|
|
|
|
Semaphore_post(self->transmitBufferMutex);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
static void
|
|
|
|
releaseSocket(IsoClientConnection self)
|
|
|
|
releaseSocket(IsoClientConnection self)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (self->socket) {
|
|
|
|
if (self->socket)
|
|
|
|
|
|
|
|
{
|
|
|
|
#if (CONFIG_MMS_SUPPORT_TLS == 1)
|
|
|
|
#if (CONFIG_MMS_SUPPORT_TLS == 1)
|
|
|
|
if (self->cotpConnection->tlsSocket) {
|
|
|
|
if (self->cotpConnection->tlsSocket)
|
|
|
|
|
|
|
|
{
|
|
|
|
TLSSocket_close(self->cotpConnection->tlsSocket);
|
|
|
|
TLSSocket_close(self->cotpConnection->tlsSocket);
|
|
|
|
self->cotpConnection->tlsSocket = NULL;
|
|
|
|
self->cotpConnection->tlsSocket = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -345,29 +349,34 @@ IsoClientConnection_handleConnection(IsoClientConnection self)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
SocketState socketState = Socket_checkAsyncConnectState(self->socket);
|
|
|
|
SocketState socketState = Socket_checkAsyncConnectState(self->socket);
|
|
|
|
|
|
|
|
|
|
|
|
if (socketState == SOCKET_STATE_CONNECTED) {
|
|
|
|
if (socketState == SOCKET_STATE_CONNECTED)
|
|
|
|
if (sendConnectionRequestMessage(self)) {
|
|
|
|
{
|
|
|
|
|
|
|
|
if (sendConnectionRequestMessage(self))
|
|
|
|
|
|
|
|
{
|
|
|
|
self->nextReadTimeout = Hal_getTimeInMs() + self->readTimeoutInMs;
|
|
|
|
self->nextReadTimeout = Hal_getTimeInMs() + self->readTimeoutInMs;
|
|
|
|
nextState = INT_STATE_WAIT_FOR_COTP_CONNECT_RESP;
|
|
|
|
nextState = INT_STATE_WAIT_FOR_COTP_CONNECT_RESP;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
IsoClientConnection_releaseTransmitBuffer(self);
|
|
|
|
IsoClientConnection_releaseTransmitBuffer(self);
|
|
|
|
self->callback(ISO_IND_ASSOCIATION_FAILED, self->callbackParameter, NULL);
|
|
|
|
self->callback(ISO_IND_ASSOCIATION_FAILED, self->callbackParameter, NULL);
|
|
|
|
nextState = INT_STATE_CLOSE_ON_ERROR;
|
|
|
|
nextState = INT_STATE_CLOSE_ON_ERROR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (socketState == SOCKET_STATE_FAILED) {
|
|
|
|
else if (socketState == SOCKET_STATE_FAILED)
|
|
|
|
|
|
|
|
{
|
|
|
|
IsoClientConnection_releaseTransmitBuffer(self);
|
|
|
|
IsoClientConnection_releaseTransmitBuffer(self);
|
|
|
|
self->callback(ISO_IND_ASSOCIATION_FAILED, self->callbackParameter, NULL);
|
|
|
|
self->callback(ISO_IND_ASSOCIATION_FAILED, self->callbackParameter, NULL);
|
|
|
|
nextState = INT_STATE_CLOSE_ON_ERROR;
|
|
|
|
nextState = INT_STATE_CLOSE_ON_ERROR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
/* check connect timeout */
|
|
|
|
/* check connect timeout */
|
|
|
|
|
|
|
|
|
|
|
|
uint64_t currentTime = Hal_getTimeInMs();
|
|
|
|
uint64_t currentTime = Hal_getTimeInMs();
|
|
|
|
|
|
|
|
|
|
|
|
if (currentTime > self->nextReadTimeout) {
|
|
|
|
if (currentTime > self->nextReadTimeout)
|
|
|
|
|
|
|
|
{
|
|
|
|
IsoClientConnection_releaseTransmitBuffer(self);
|
|
|
|
IsoClientConnection_releaseTransmitBuffer(self);
|
|
|
|
self->callback(ISO_IND_ASSOCIATION_FAILED, self->callbackParameter, NULL);
|
|
|
|
self->callback(ISO_IND_ASSOCIATION_FAILED, self->callbackParameter, NULL);
|
|
|
|
nextState = INT_STATE_CLOSE_ON_ERROR;
|
|
|
|
nextState = INT_STATE_CLOSE_ON_ERROR;
|
|
|
@ -385,8 +394,8 @@ IsoClientConnection_handleConnection(IsoClientConnection self)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
uint64_t currentTime = Hal_getTimeInMs();
|
|
|
|
uint64_t currentTime = Hal_getTimeInMs();
|
|
|
|
|
|
|
|
|
|
|
|
if (currentTime > self->nextReadTimeout) {
|
|
|
|
if (currentTime > self->nextReadTimeout)
|
|
|
|
|
|
|
|
{
|
|
|
|
if (DEBUG_ISO_CLIENT)
|
|
|
|
if (DEBUG_ISO_CLIENT)
|
|
|
|
printf("ISO_CLIENT: Timeout waiting for COTP CR\n");
|
|
|
|
printf("ISO_CLIENT: Timeout waiting for COTP CR\n");
|
|
|
|
|
|
|
|
|
|
|
@ -396,15 +405,16 @@ IsoClientConnection_handleConnection(IsoClientConnection self)
|
|
|
|
|
|
|
|
|
|
|
|
nextState = INT_STATE_CLOSE_ON_ERROR;
|
|
|
|
nextState = INT_STATE_CLOSE_ON_ERROR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
TpktState packetState = CotpConnection_readToTpktBuffer(self->cotpConnection);
|
|
|
|
TpktState packetState = CotpConnection_readToTpktBuffer(self->cotpConnection);
|
|
|
|
|
|
|
|
|
|
|
|
if (packetState == TPKT_PACKET_COMPLETE) {
|
|
|
|
if (packetState == TPKT_PACKET_COMPLETE)
|
|
|
|
|
|
|
|
{
|
|
|
|
CotpIndication cotpIndication = CotpConnection_parseIncomingMessage(self->cotpConnection);
|
|
|
|
CotpIndication cotpIndication = CotpConnection_parseIncomingMessage(self->cotpConnection);
|
|
|
|
|
|
|
|
|
|
|
|
if (cotpIndication != COTP_CONNECT_INDICATION) {
|
|
|
|
if (cotpIndication != COTP_CONNECT_INDICATION)
|
|
|
|
|
|
|
|
{
|
|
|
|
if (DEBUG_ISO_CLIENT)
|
|
|
|
if (DEBUG_ISO_CLIENT)
|
|
|
|
printf("ISO_CLIENT: Unexpected COTP state (%i)\n", cotpIndication);
|
|
|
|
printf("ISO_CLIENT: Unexpected COTP state (%i)\n", cotpIndication);
|
|
|
|
|
|
|
|
|
|
|
@ -414,7 +424,8 @@ IsoClientConnection_handleConnection(IsoClientConnection self)
|
|
|
|
|
|
|
|
|
|
|
|
nextState = INT_STATE_CLOSE_ON_ERROR;
|
|
|
|
nextState = INT_STATE_CLOSE_ON_ERROR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
sendAcseInitiateRequest(self);
|
|
|
|
sendAcseInitiateRequest(self);
|
|
|
|
|
|
|
|
|
|
|
|
self->nextReadTimeout = Hal_getTimeInMs() + self->readTimeoutInMs;
|
|
|
|
self->nextReadTimeout = Hal_getTimeInMs() + self->readTimeoutInMs;
|
|
|
@ -422,7 +433,8 @@ IsoClientConnection_handleConnection(IsoClientConnection self)
|
|
|
|
nextState = INT_STATE_WAIT_FOR_ACSE_RESP;
|
|
|
|
nextState = INT_STATE_WAIT_FOR_ACSE_RESP;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (packetState == TPKT_ERROR) {
|
|
|
|
else if (packetState == TPKT_ERROR)
|
|
|
|
|
|
|
|
{
|
|
|
|
if (DEBUG_ISO_CLIENT)
|
|
|
|
if (DEBUG_ISO_CLIENT)
|
|
|
|
printf("ISO_CLIENT: Error receiving COTP message\n");
|
|
|
|
printf("ISO_CLIENT: Error receiving COTP message\n");
|
|
|
|
|
|
|
|
|
|
|
@ -435,7 +447,6 @@ IsoClientConnection_handleConnection(IsoClientConnection self)
|
|
|
|
else {
|
|
|
|
else {
|
|
|
|
waits = true;
|
|
|
|
waits = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
break;
|
|
|
@ -444,8 +455,8 @@ IsoClientConnection_handleConnection(IsoClientConnection self)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
uint64_t currentTime = Hal_getTimeInMs();
|
|
|
|
uint64_t currentTime = Hal_getTimeInMs();
|
|
|
|
|
|
|
|
|
|
|
|
if (currentTime > self->nextReadTimeout) {
|
|
|
|
if (currentTime > self->nextReadTimeout)
|
|
|
|
|
|
|
|
{
|
|
|
|
if (DEBUG_ISO_CLIENT)
|
|
|
|
if (DEBUG_ISO_CLIENT)
|
|
|
|
printf("ISO_CLIENT: Timeout waiting for ACSE initiate response\n");
|
|
|
|
printf("ISO_CLIENT: Timeout waiting for ACSE initiate response\n");
|
|
|
|
|
|
|
|
|
|
|
@ -453,15 +464,16 @@ IsoClientConnection_handleConnection(IsoClientConnection self)
|
|
|
|
|
|
|
|
|
|
|
|
nextState = INT_STATE_CLOSE_ON_ERROR;
|
|
|
|
nextState = INT_STATE_CLOSE_ON_ERROR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
TpktState packetState = CotpConnection_readToTpktBuffer(self->cotpConnection);
|
|
|
|
TpktState packetState = CotpConnection_readToTpktBuffer(self->cotpConnection);
|
|
|
|
|
|
|
|
|
|
|
|
if (packetState == TPKT_PACKET_COMPLETE) {
|
|
|
|
if (packetState == TPKT_PACKET_COMPLETE)
|
|
|
|
|
|
|
|
{
|
|
|
|
CotpIndication cotpIndication = CotpConnection_parseIncomingMessage(self->cotpConnection);
|
|
|
|
CotpIndication cotpIndication = CotpConnection_parseIncomingMessage(self->cotpConnection);
|
|
|
|
|
|
|
|
|
|
|
|
if (cotpIndication != COTP_DATA_INDICATION) {
|
|
|
|
if (cotpIndication != COTP_DATA_INDICATION)
|
|
|
|
|
|
|
|
{
|
|
|
|
if (DEBUG_ISO_CLIENT)
|
|
|
|
if (DEBUG_ISO_CLIENT)
|
|
|
|
printf("ISO_CLIENT: Unexpected COTP state (%i)\n", cotpIndication);
|
|
|
|
printf("ISO_CLIENT: Unexpected COTP state (%i)\n", cotpIndication);
|
|
|
|
|
|
|
|
|
|
|
@ -469,67 +481,71 @@ IsoClientConnection_handleConnection(IsoClientConnection self)
|
|
|
|
|
|
|
|
|
|
|
|
nextState = INT_STATE_CLOSE_ON_ERROR;
|
|
|
|
nextState = INT_STATE_CLOSE_ON_ERROR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
/* parse ACSE response */
|
|
|
|
/* parse ACSE response */
|
|
|
|
|
|
|
|
|
|
|
|
IsoSessionIndication sessionIndication;
|
|
|
|
IsoSessionIndication sessionIndication;
|
|
|
|
|
|
|
|
|
|
|
|
sessionIndication =
|
|
|
|
|
|
|
|
IsoSession_parseMessage(self->session, CotpConnection_getPayload(self->cotpConnection));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (sessionIndication != SESSION_CONNECT) {
|
|
|
|
|
|
|
|
if (DEBUG_ISO_CLIENT)
|
|
|
|
|
|
|
|
printf("ISO_CLIENT: IsoClientConnection_associate: no session connect indication\n");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self->callback(ISO_IND_ASSOCIATION_FAILED, self->callbackParameter, NULL);
|
|
|
|
sessionIndication =
|
|
|
|
|
|
|
|
IsoSession_parseMessage(self->session, CotpConnection_getPayload(self->cotpConnection));
|
|
|
|
|
|
|
|
|
|
|
|
nextState = INT_STATE_CLOSE_ON_ERROR;
|
|
|
|
if (sessionIndication != SESSION_CONNECT)
|
|
|
|
}
|
|
|
|
{
|
|
|
|
else {
|
|
|
|
if (DEBUG_ISO_CLIENT)
|
|
|
|
|
|
|
|
printf("ISO_CLIENT: IsoClientConnection_associate: no session connect indication\n");
|
|
|
|
if (IsoPresentation_parseAcceptMessage(self->presentation, IsoSession_getUserData(self->session)) == false) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (DEBUG_ISO_CLIENT)
|
|
|
|
|
|
|
|
printf("ISO_CLIENT: IsoClientConnection_associate: no presentation ok indication\n");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self->callback(ISO_IND_ASSOCIATION_FAILED, self->callbackParameter, NULL);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
nextState = INT_STATE_CLOSE_ON_ERROR;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
AcseIndication acseIndication = AcseConnection_parseMessage(&(self->acseConnection), &self->presentation->nextPayload);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (acseIndication != ACSE_ASSOCIATE) {
|
|
|
|
|
|
|
|
if (DEBUG_ISO_CLIENT)
|
|
|
|
|
|
|
|
printf("ISO_CLIENT: IsoClientConnection_associate: no ACSE_ASSOCIATE indication\n");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self->callback(ISO_IND_ASSOCIATION_FAILED, self->callbackParameter, NULL);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
nextState = INT_STATE_CLOSE_ON_ERROR;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ByteBuffer_wrap(self->receivePayloadBuffer, self->acseConnection.userDataBuffer,
|
|
|
|
|
|
|
|
self->acseConnection.userDataBufferSize, self->acseConnection.userDataBufferSize);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
setState(self, STATE_CONNECTED);
|
|
|
|
self->callback(ISO_IND_ASSOCIATION_FAILED, self->callbackParameter, NULL);
|
|
|
|
nextState = INT_STATE_WAIT_FOR_DATA_MSG;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (self->callback(ISO_IND_ASSOCIATION_SUCCESS, self->callbackParameter, self->receivePayloadBuffer) == false) {
|
|
|
|
nextState = INT_STATE_CLOSE_ON_ERROR;
|
|
|
|
nextState = INT_STATE_CLOSE_ON_ERROR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (IsoPresentation_parseAcceptMessage(self->presentation, IsoSession_getUserData(self->session)) == false)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (DEBUG_ISO_CLIENT)
|
|
|
|
|
|
|
|
printf("ISO_CLIENT: no presentation accept indication\n");
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
self->callback(ISO_IND_ASSOCIATION_FAILED, self->callbackParameter, NULL);
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
nextState = INT_STATE_CLOSE_ON_ERROR;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
AcseIndication acseIndication = AcseConnection_parseMessage(&(self->acseConnection), &self->presentation->nextPayload);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (acseIndication != ACSE_ASSOCIATE)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (DEBUG_ISO_CLIENT)
|
|
|
|
|
|
|
|
printf("ISO_CLIENT: no ACSE_ASSOCIATE indication\n");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self->callback(ISO_IND_ASSOCIATION_FAILED, self->callbackParameter, NULL);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
nextState = INT_STATE_CLOSE_ON_ERROR;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (DEBUG_ISO_CLIENT)
|
|
|
|
|
|
|
|
printf("ISO_CLIENT: ACSE AARE - association accepted\n");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ByteBuffer_wrap(self->receivePayloadBuffer, self->acseConnection.userDataBuffer,
|
|
|
|
|
|
|
|
self->acseConnection.userDataBufferSize, self->acseConnection.userDataBufferSize);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
setState(self, STATE_CONNECTED);
|
|
|
|
|
|
|
|
nextState = INT_STATE_WAIT_FOR_DATA_MSG;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (self->callback(ISO_IND_ASSOCIATION_SUCCESS, self->callbackParameter, self->receivePayloadBuffer) == false) {
|
|
|
|
|
|
|
|
nextState = INT_STATE_CLOSE_ON_ERROR;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
CotpConnection_resetPayload(self->cotpConnection);
|
|
|
|
CotpConnection_resetPayload(self->cotpConnection);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (packetState == TPKT_ERROR) {
|
|
|
|
else if (packetState == TPKT_ERROR)
|
|
|
|
|
|
|
|
{
|
|
|
|
if (DEBUG_ISO_CLIENT)
|
|
|
|
if (DEBUG_ISO_CLIENT)
|
|
|
|
printf("ISO_CLIENT: Error receiving COTP message\n");
|
|
|
|
printf("ISO_CLIENT: Error receiving COTP message\n");
|
|
|
|
|
|
|
|
|
|
|
@ -540,7 +556,6 @@ IsoClientConnection_handleConnection(IsoClientConnection self)
|
|
|
|
else {
|
|
|
|
else {
|
|
|
|
waits = true;
|
|
|
|
waits = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
break;
|
|
|
@ -552,8 +567,8 @@ IsoClientConnection_handleConnection(IsoClientConnection self)
|
|
|
|
if (packetState == TPKT_ERROR) {
|
|
|
|
if (packetState == TPKT_ERROR) {
|
|
|
|
nextState = INT_STATE_CLOSE_ON_ERROR;
|
|
|
|
nextState = INT_STATE_CLOSE_ON_ERROR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (packetState == TPKT_PACKET_COMPLETE) {
|
|
|
|
else if (packetState == TPKT_PACKET_COMPLETE)
|
|
|
|
|
|
|
|
{
|
|
|
|
CotpIndication cotpIndication = CotpConnection_parseIncomingMessage(self->cotpConnection);
|
|
|
|
CotpIndication cotpIndication = CotpConnection_parseIncomingMessage(self->cotpConnection);
|
|
|
|
|
|
|
|
|
|
|
|
switch (cotpIndication) {
|
|
|
|
switch (cotpIndication) {
|
|
|
@ -576,23 +591,24 @@ IsoClientConnection_handleConnection(IsoClientConnection self)
|
|
|
|
IsoSession_parseMessage(self->session,
|
|
|
|
IsoSession_parseMessage(self->session,
|
|
|
|
CotpConnection_getPayload(self->cotpConnection));
|
|
|
|
CotpConnection_getPayload(self->cotpConnection));
|
|
|
|
|
|
|
|
|
|
|
|
if (sessionIndication != SESSION_DATA) {
|
|
|
|
if (sessionIndication != SESSION_DATA)
|
|
|
|
|
|
|
|
{
|
|
|
|
if (DEBUG_ISO_CLIENT)
|
|
|
|
if (DEBUG_ISO_CLIENT)
|
|
|
|
printf("ISO_CLIENT_CONNECTION: Invalid session message\n");
|
|
|
|
printf("ISO_CLIENT_CONNECTION: Invalid session message\n");
|
|
|
|
|
|
|
|
|
|
|
|
nextState = INT_STATE_CLOSE_ON_ERROR;
|
|
|
|
nextState = INT_STATE_CLOSE_ON_ERROR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
if (!IsoPresentation_parseUserData(self->presentation, IsoSession_getUserData(self->session))) {
|
|
|
|
if (!IsoPresentation_parseUserData(self->presentation, IsoSession_getUserData(self->session)))
|
|
|
|
|
|
|
|
{
|
|
|
|
if (DEBUG_ISO_CLIENT)
|
|
|
|
if (DEBUG_ISO_CLIENT)
|
|
|
|
printf("ISO_CLIENT_CONNECTION: Invalid presentation message\n");
|
|
|
|
printf("ISO_CLIENT_CONNECTION: Invalid presentation message\n");
|
|
|
|
|
|
|
|
|
|
|
|
nextState = INT_STATE_CLOSE_ON_ERROR;
|
|
|
|
nextState = INT_STATE_CLOSE_ON_ERROR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
self->callback(ISO_IND_DATA, self->callbackParameter,
|
|
|
|
self->callback(ISO_IND_DATA, self->callbackParameter,
|
|
|
|
&(self->presentation->nextPayload));
|
|
|
|
&(self->presentation->nextPayload));
|
|
|
|
|
|
|
|
|
|
|
@ -659,7 +675,6 @@ IsoClientConnection_handleConnection(IsoClientConnection self)
|
|
|
|
return waits;
|
|
|
|
return waits;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
bool
|
|
|
|
IsoClientConnection_associateAsync(IsoClientConnection self, uint32_t connectTimeoutInMs, uint32_t readTimeoutInMs)
|
|
|
|
IsoClientConnection_associateAsync(IsoClientConnection self, uint32_t connectTimeoutInMs, uint32_t readTimeoutInMs)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -669,7 +684,8 @@ IsoClientConnection_associateAsync(IsoClientConnection self, uint32_t connectTim
|
|
|
|
|
|
|
|
|
|
|
|
self->socket = TcpSocket_create();
|
|
|
|
self->socket = TcpSocket_create();
|
|
|
|
|
|
|
|
|
|
|
|
if (self->socket == NULL) {
|
|
|
|
if (self->socket == NULL)
|
|
|
|
|
|
|
|
{
|
|
|
|
Semaphore_post(self->tickMutex);
|
|
|
|
Semaphore_post(self->tickMutex);
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -697,8 +713,8 @@ IsoClientConnection_associateAsync(IsoClientConnection self, uint32_t connectTim
|
|
|
|
Socket_bind(self->socket, self->parameters->localIpAddress, self->parameters->localTcpPort);
|
|
|
|
Socket_bind(self->socket, self->parameters->localIpAddress, self->parameters->localTcpPort);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (Socket_connectAsync(self->socket, self->parameters->hostname, self->parameters->tcpPort) == false) {
|
|
|
|
if (Socket_connectAsync(self->socket, self->parameters->hostname, self->parameters->tcpPort) == false)
|
|
|
|
|
|
|
|
{
|
|
|
|
Socket_destroy(self->socket);
|
|
|
|
Socket_destroy(self->socket);
|
|
|
|
self->socket = NULL;
|
|
|
|
self->socket = NULL;
|
|
|
|
|
|
|
|
|
|
|
@ -718,7 +734,8 @@ IsoClientConnection_associateAsync(IsoClientConnection self, uint32_t connectTim
|
|
|
|
void
|
|
|
|
void
|
|
|
|
IsoClientConnection_sendMessage(IsoClientConnection self, ByteBuffer* payloadBuffer)
|
|
|
|
IsoClientConnection_sendMessage(IsoClientConnection self, ByteBuffer* payloadBuffer)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (getState(self) == STATE_CONNECTED) {
|
|
|
|
if (getState(self) == STATE_CONNECTED)
|
|
|
|
|
|
|
|
{
|
|
|
|
struct sBufferChain payloadBCMemory;
|
|
|
|
struct sBufferChain payloadBCMemory;
|
|
|
|
BufferChain payload = &payloadBCMemory;
|
|
|
|
BufferChain payload = &payloadBCMemory;
|
|
|
|
|
|
|
|
|
|
|
@ -743,7 +760,8 @@ IsoClientConnection_sendMessage(IsoClientConnection self, ByteBuffer* payloadBuf
|
|
|
|
if (DEBUG_ISO_CLIENT)
|
|
|
|
if (DEBUG_ISO_CLIENT)
|
|
|
|
printf("ISO_CLIENT: IsoClientConnection_sendMessage: send message failed!\n");
|
|
|
|
printf("ISO_CLIENT: IsoClientConnection_sendMessage: send message failed!\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
if (DEBUG_ISO_CLIENT)
|
|
|
|
if (DEBUG_ISO_CLIENT)
|
|
|
|
printf("ISO_CLIENT: Not connected --> cannot send message\n");
|
|
|
|
printf("ISO_CLIENT: Not connected --> cannot send message\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -762,7 +780,8 @@ IsoClientConnection_close(IsoClientConnection self)
|
|
|
|
|
|
|
|
|
|
|
|
eIsoClientInternalState intState = getIntState(self);
|
|
|
|
eIsoClientInternalState intState = getIntState(self);
|
|
|
|
|
|
|
|
|
|
|
|
if ((intState != INT_STATE_IDLE) && (intState != INT_STATE_ERROR) && (intState != INT_STATE_CLOSE_ON_ERROR)) {
|
|
|
|
if ((intState != INT_STATE_IDLE) && (intState != INT_STATE_ERROR) && (intState != INT_STATE_CLOSE_ON_ERROR))
|
|
|
|
|
|
|
|
{
|
|
|
|
setIntState(self, INT_STATE_CLOSING_CONNECTION);
|
|
|
|
setIntState(self, INT_STATE_CLOSING_CONNECTION);
|
|
|
|
|
|
|
|
|
|
|
|
Semaphore_post(self->tickMutex);
|
|
|
|
Semaphore_post(self->tickMutex);
|
|
|
@ -783,8 +802,8 @@ IsoClientConnection_destroy(IsoClientConnection self)
|
|
|
|
|
|
|
|
|
|
|
|
int state = getState(self);
|
|
|
|
int state = getState(self);
|
|
|
|
|
|
|
|
|
|
|
|
if (state == STATE_CONNECTED) {
|
|
|
|
if (state == STATE_CONNECTED)
|
|
|
|
|
|
|
|
{
|
|
|
|
if (DEBUG_ISO_CLIENT)
|
|
|
|
if (DEBUG_ISO_CLIENT)
|
|
|
|
printf("ISO_CLIENT: call IsoClientConnection_close\n");
|
|
|
|
printf("ISO_CLIENT: call IsoClientConnection_close\n");
|
|
|
|
|
|
|
|
|
|
|
@ -798,7 +817,8 @@ IsoClientConnection_destroy(IsoClientConnection self)
|
|
|
|
if (self->receiveBuffer != NULL)
|
|
|
|
if (self->receiveBuffer != NULL)
|
|
|
|
GLOBAL_FREEMEM(self->receiveBuffer);
|
|
|
|
GLOBAL_FREEMEM(self->receiveBuffer);
|
|
|
|
|
|
|
|
|
|
|
|
if (self->cotpConnection != NULL) {
|
|
|
|
if (self->cotpConnection != NULL)
|
|
|
|
|
|
|
|
{
|
|
|
|
if (self->cotpConnection->handleSet != NULL)
|
|
|
|
if (self->cotpConnection->handleSet != NULL)
|
|
|
|
Handleset_destroy(self->cotpConnection->handleSet);
|
|
|
|
Handleset_destroy(self->cotpConnection->handleSet);
|
|
|
|
|
|
|
|
|
|
|
@ -910,7 +930,6 @@ IsoClientConnection_release(IsoClientConnection self)
|
|
|
|
Semaphore_post(self->transmitBufferMutex);
|
|
|
|
Semaphore_post(self->transmitBufferMutex);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ByteBuffer*
|
|
|
|
ByteBuffer*
|
|
|
|
IsoClientConnection_allocateTransmitBuffer(IsoClientConnection self)
|
|
|
|
IsoClientConnection_allocateTransmitBuffer(IsoClientConnection self)
|
|
|
|
{
|
|
|
|
{
|
|
|
|