// used by non-threaded version static void handleIsoConnectionsThreadless(IsoServer self) { Socket connectionSocket; if ((connectionSocket = ServerSocket_accept((ServerSocket) self->serverSocket)) != NULL) { #if (CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS != -1) if (private_IsoServer_getConnectionCounter(self) >= CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS) { if (DEBUG_ISO_SERVER) printf("ISO_SERVER: maximum number of connections reached -> reject connection attempt.\n"); Socket_destroy(connectionSocket); handleClientConnections(self); return; } #endif IsoConnection isoConnection = IsoConnection_create(connectionSocket, self); private_IsoServer_increaseConnectionCounter(self); addClientConnection(self, isoConnection); self->connectionHandler(ISO_CONNECTION_OPENED, self->connectionHandlerParameter, isoConnection); } handleClientConnections(self); }
void IsoClientConnection_close(IsoClientConnection self) { if (self->socket != NULL) Socket_destroy(self->socket); self->state = STATE_IDLE; }
void IsoConnection_close(IsoConnection self) { if (self->state != ISO_CON_STATE_STOPPED) { Socket socket = self->socket; self->state = ISO_CON_STATE_STOPPED; self->socket = NULL; Socket_destroy(socket); } }
static void handleTcpConnection(IsoConnection self) { if (DEBUG_ISO_SERVER) printf("ISO_SERVER: connection %p started\n", self); CotpIndication cotpIndication; IsoSessionIndication sIndication; AcseIndication aIndication; AcseConnection acseConnection; ByteBuffer receiveBuffer; self->cotpConnection = (CotpConnection*) calloc(1, sizeof(CotpConnection)); CotpConnection_init(self->cotpConnection, self->socket, &receiveBuffer); self->session = (IsoSession*) calloc(1, sizeof(IsoSession)); IsoSession_init(self->session); self->presentation = (IsoPresentation*) calloc(1, sizeof(IsoPresentation)); IsoPresentation_init(self->presentation); AcseConnection_init(&acseConnection, IsoServer_getAuthenticator(self->isoServer), IsoServer_getAuthenticatorParameter(self->isoServer)); while (self->msgRcvdHandlerParameter == NULL) Thread_sleep(1); if (DEBUG_ISO_SERVER) printf("ISO_SERVER: IsoConnection: Start to handle connection for client %s\n", self->clientAddress); while (self->state == ISO_CON_STATE_RUNNING) { ByteBuffer_wrap(&receiveBuffer, self->receiveBuffer, 0, RECEIVE_BUF_SIZE); cotpIndication = CotpConnection_parseIncomingMessage(self->cotpConnection); switch (cotpIndication) { case CONNECT_INDICATION: if (DEBUG_ISO_SERVER) printf("ISO_SERVER: COTP connection indication\n"); Semaphore_wait(self->conMutex); CotpConnection_sendConnectionResponseMessage(self->cotpConnection); Semaphore_post(self->conMutex); break; case DATA_INDICATION: { if (DEBUG_ISO_SERVER) printf("ISO_SERVER: COTP data indication\n"); ByteBuffer* cotpPayload = CotpConnection_getPayload(self->cotpConnection); sIndication = IsoSession_parseMessage(self->session, cotpPayload); ByteBuffer* sessionUserData = IsoSession_getUserData(self->session); switch (sIndication) { case SESSION_CONNECT: if (DEBUG_ISO_SERVER) printf("ISO_SERVER: iso_connection: session connect indication\n"); if (IsoPresentation_parseConnect(self->presentation, sessionUserData)) { if (DEBUG_ISO_SERVER) printf("ISO_SERVER: iso_connection: presentation ok\n"); ByteBuffer* acseBuffer = &(self->presentation->nextPayload); aIndication = AcseConnection_parseMessage(&acseConnection, acseBuffer); self->securityToken = acseConnection.securityToken; if (aIndication == ACSE_ASSOCIATE) { Semaphore_wait(self->conMutex); if (DEBUG_ISO_SERVER) printf("ISO_SERVER: cotp_server: acse associate\n"); ByteBuffer mmsRequest; ByteBuffer_wrap(&mmsRequest, acseConnection.userDataBuffer, acseConnection.userDataBufferSize, acseConnection.userDataBufferSize); ByteBuffer mmsResponseBuffer; /* new */ ByteBuffer_wrap(&mmsResponseBuffer, self->sendBuffer, 0, SEND_BUF_SIZE); self->msgRcvdHandler(self->msgRcvdHandlerParameter, &mmsRequest, &mmsResponseBuffer); struct sBufferChain mmsBufferPartStruct; BufferChain mmsBufferPart = &mmsBufferPartStruct; BufferChain_init(mmsBufferPart, mmsResponseBuffer.size, mmsResponseBuffer.size, NULL, self->sendBuffer); if (mmsResponseBuffer.size > 0) { if (DEBUG_ISO_SERVER) printf("iso_connection: application payload size: %i\n", mmsResponseBuffer.size); struct sBufferChain acseBufferPartStruct; BufferChain acseBufferPart = &acseBufferPartStruct; acseBufferPart->buffer = self->sendBuffer + mmsBufferPart->length; acseBufferPart->partMaxLength = SEND_BUF_SIZE - mmsBufferPart->length; AcseConnection_createAssociateResponseMessage(&acseConnection, ACSE_RESULT_ACCEPT, acseBufferPart, mmsBufferPart); struct sBufferChain presentationBufferPartStruct; BufferChain presentationBufferPart = &presentationBufferPartStruct; presentationBufferPart->buffer = self->sendBuffer + acseBufferPart->length; presentationBufferPart->partMaxLength = SEND_BUF_SIZE - acseBufferPart->length; IsoPresentation_createCpaMessage(self->presentation, presentationBufferPart, acseBufferPart); struct sBufferChain sessionBufferPartStruct; BufferChain sessionBufferPart = &sessionBufferPartStruct; sessionBufferPart->buffer = self->sendBuffer + presentationBufferPart->length; sessionBufferPart->partMaxLength = SEND_BUF_SIZE - presentationBufferPart->length; IsoSession_createAcceptSpdu(self->session, sessionBufferPart, presentationBufferPart); CotpConnection_sendDataMessage(self->cotpConnection, sessionBufferPart); } else { if (DEBUG_ISO_SERVER) printf( "ISO_SERVER: iso_connection: association error. No response from application!\n"); } Semaphore_post(self->conMutex); } else { if (DEBUG_ISO_SERVER) printf("ISO_SERVER: iso_connection: acse association failed\n"); self->state = ISO_CON_STATE_STOPPED; } } break; case SESSION_DATA: if (DEBUG_ISO_SERVER) printf("ISO_SERVER: iso_connection: session data indication\n"); if (!IsoPresentation_parseUserData(self->presentation, sessionUserData)) { if (DEBUG_ISO_SERVER) printf("ISO_SERVER: cotp_server: presentation error\n"); self->state = ISO_CON_STATE_STOPPED; break; } if (self->presentation->nextContextId == self->presentation->mmsContextId) { if (DEBUG_ISO_SERVER) printf("ISO_SERVER: iso_connection: mms message\n"); ByteBuffer* mmsRequest = &(self->presentation->nextPayload); ByteBuffer mmsResponseBuffer; IsoServer_userLock(self->isoServer); Semaphore_wait(self->conMutex); ByteBuffer_wrap(&mmsResponseBuffer, self->sendBuffer, 0, SEND_BUF_SIZE); self->msgRcvdHandler(self->msgRcvdHandlerParameter, mmsRequest, &mmsResponseBuffer); if (mmsResponseBuffer.size > 0) { struct sBufferChain mmsBufferPartStruct; BufferChain mmsBufferPart = &mmsBufferPartStruct; BufferChain_init(mmsBufferPart, mmsResponseBuffer.size, mmsResponseBuffer.size, NULL, self->sendBuffer); struct sBufferChain presentationBufferPartStruct; BufferChain presentationBufferPart = &presentationBufferPartStruct; presentationBufferPart->buffer = self->sendBuffer + mmsBufferPart->length; presentationBufferPart->partMaxLength = SEND_BUF_SIZE - mmsBufferPart->length; IsoPresentation_createUserData(self->presentation, presentationBufferPart, mmsBufferPart); struct sBufferChain sessionBufferPartStruct; BufferChain sessionBufferPart = &sessionBufferPartStruct; sessionBufferPart->buffer = self->sendBuffer + presentationBufferPart->length; sessionBufferPart->partMaxLength = SEND_BUF_SIZE - presentationBufferPart->length; IsoSession_createDataSpdu(self->session, sessionBufferPart, presentationBufferPart); CotpConnection_sendDataMessage(self->cotpConnection, sessionBufferPart); } Semaphore_post(self->conMutex); IsoServer_userUnlock(self->isoServer); } else { if (DEBUG_ISO_SERVER) printf("ISO_SERVER: iso_connection: unknown presentation layer context!"); } break; case SESSION_FINISH: if (DEBUG_ISO_SERVER) printf("ISO_SERVER: iso_connection: session finish indication\n"); if (IsoPresentation_parseUserData(self->presentation, sessionUserData)) { if (DEBUG_ISO_SERVER) printf("ISO_SERVER: iso_connection: presentation ok\n"); struct sBufferChain acseBufferPartStruct; BufferChain acseBufferPart = &acseBufferPartStruct; acseBufferPart->buffer = self->sendBuffer; acseBufferPart->partMaxLength = SEND_BUF_SIZE; AcseConnection_createReleaseResponseMessage(&acseConnection, acseBufferPart); struct sBufferChain presentationBufferPartStruct; BufferChain presentationBufferPart = &presentationBufferPartStruct; presentationBufferPart->buffer = self->sendBuffer + acseBufferPart->length; presentationBufferPart->partMaxLength = SEND_BUF_SIZE - acseBufferPart->length; IsoPresentation_createUserDataACSE(self->presentation, presentationBufferPart, acseBufferPart); struct sBufferChain sessionBufferPartStruct; BufferChain sessionBufferPart = &sessionBufferPartStruct; sessionBufferPart->buffer = self->sendBuffer + presentationBufferPart->length; sessionBufferPart->partMaxLength = SEND_BUF_SIZE - presentationBufferPart->length; IsoSession_createDisconnectSpdu(self->session, sessionBufferPart, presentationBufferPart); CotpConnection_sendDataMessage(self->cotpConnection, sessionBufferPart); } //TODO else send ABORT message break; case SESSION_ABORT: self->state = ISO_CON_STATE_STOPPED; break; case SESSION_ERROR: self->state = ISO_CON_STATE_STOPPED; break; default: /* illegal state */ self->state = ISO_CON_STATE_STOPPED; break; } } break; case ERROR: if (DEBUG_ISO_SERVER) printf("ISO_SERVER: Connection closed\n"); self->state = ISO_CON_STATE_STOPPED; break; default: if (DEBUG_ISO_SERVER) printf("ISO_SERVER: COTP Unknown Indication: %i\n", cotpIndication); self->state = ISO_CON_STATE_STOPPED; break; } } IsoServer_closeConnection(self->isoServer, self); if (self->socket != NULL) Socket_destroy(self->socket); free(self->session); free(self->presentation); AcseConnection_destroy(&acseConnection); CotpConnection_destroy(self->cotpConnection); free(self->cotpConnection); Semaphore_destroy(self->conMutex); free(self->receiveBuffer); free(self->sendBuffer); free(self->clientAddress); IsoServer isoServer = self->isoServer; free(self); if (DEBUG_ISO_SERVER) printf("ISO_SERVER: connection %p closed\n", self); private_IsoServer_decreaseConnectionCounter(isoServer); }
static void handleTcpConnection(IsoConnection self) { CotpIndication cotpIndication; CotpConnection cotpConnection; IsoSessionIndication sIndication; IsoSession session; IsoPresentation presentation; IsoPresentationIndication pIndication; AcseIndication aIndication; AcseConnection acseConnection; ByteBuffer receiveBuffer; ByteBuffer responseBuffer1; ByteBuffer responseBuffer2; CotpConnection_init(&cotpConnection, self->socket, &receiveBuffer); IsoSession_init(&session); IsoPresentation_init(&presentation); AcseConnection_init(&acseConnection); AcseConnection_setAuthenticationParameter(&acseConnection, IsoServer_getAuthenticationParameter(self->isoServer)); while (self->msgRcvdHandlerParameter == NULL) Thread_sleep(1); printf("IsoConnection: state = RUNNING. Start to handle connection\n"); while (self->state == ISO_CON_STATE_RUNNING) { ByteBuffer_wrap(&receiveBuffer, self->receive_buf, 0, RECEIVE_BUF_SIZE); ByteBuffer_wrap(&responseBuffer1, self->send_buf_1, 0, SEND_BUF_SIZE); ByteBuffer_wrap(&responseBuffer2, self->send_buf_2, 0, SEND_BUF_SIZE); cotpIndication = CotpConnection_parseIncomingMessage(&cotpConnection); switch (cotpIndication) { case CONNECT_INDICATION: if (DEBUG) printf("COTP connection indication\n"); CotpConnection_sendConnectionResponseMessage(&cotpConnection); break; case DATA_INDICATION: if (DEBUG) printf("COTP data indication\n"); ByteBuffer* cotpPayload = CotpConnection_getPayload(&cotpConnection); sIndication = IsoSession_parseMessage(&session, cotpPayload); ByteBuffer* sessionUserData = IsoSession_getUserData(&session); switch (sIndication) { case SESSION_CONNECT: if (DEBUG) printf("cotp_server: session connect indication\n"); pIndication = IsoPresentation_parseConnect(&presentation, sessionUserData); if (pIndication == PRESENTATION_OK) { if (DEBUG) printf("cotp_server: presentation ok\n"); ByteBuffer* acseBuffer = &(presentation.nextPayload); aIndication = AcseConnection_parseMessage(&acseConnection, acseBuffer); if (aIndication == ACSE_ASSOCIATE) { if (DEBUG) printf("cotp_server: acse associate\n"); ByteBuffer mmsRequest; ByteBuffer_wrap(&mmsRequest, acseConnection.userDataBuffer, acseConnection.userDataBufferSize, acseConnection.userDataBufferSize); self->msgRcvdHandler(self->msgRcvdHandlerParameter, &mmsRequest, &responseBuffer1); if (responseBuffer1.size > 0) { if (DEBUG) printf("cotp_server: application payload size: %i\n", responseBuffer1.size); AcseConnection_createAssociateResponseMessage(&acseConnection, &responseBuffer2, &responseBuffer1); responseBuffer1.size = 0; IsoPresentation_createCpaMessage(&presentation, &responseBuffer1, &responseBuffer2); responseBuffer2.size = 0; IsoSession_createAcceptSpdu(&session, &responseBuffer2, responseBuffer1.size); ByteBuffer_append(&responseBuffer2, responseBuffer1.buffer, responseBuffer1.size); CotpConnection_sendDataMessage(&cotpConnection, &responseBuffer2); break; } else { if (DEBUG) printf("cotp_server: association error. No response from application!\n"); } } else { if (DEBUG) printf("cotp_server: acse association failed\n"); self->state = ISO_CON_STATE_STOPPED; } } break; case SESSION_DATA: if (DEBUG) printf("cotp_server: session data indication\n"); pIndication = IsoPresentation_parseUserData(&presentation, sessionUserData); if (pIndication == PRESENTATION_ERROR) { if (DEBUG) printf("cotp_server: presentation error\n"); self->state = ISO_CON_STATE_STOPPED; break; } if (presentation.nextContextId == 3) { if (DEBUG) printf("cotp_server: mms message\n"); ByteBuffer* mmsRequest = &(presentation.nextPayload); self->msgRcvdHandler(self->msgRcvdHandlerParameter, mmsRequest, &responseBuffer1); IsoPresentation_createUserData(&presentation, &responseBuffer2, &responseBuffer1); responseBuffer1.size = 0; IsoSession_createDataSpdu(&session, &responseBuffer1); ByteBuffer_append(&responseBuffer1, responseBuffer2.buffer, responseBuffer2.size); CotpConnection_sendDataMessage(&cotpConnection, &responseBuffer1); } break; case SESSION_ERROR: self->state = ISO_CON_STATE_STOPPED; break; } break; case ERROR: if (DEBUG) printf("COTP protocol error\n"); self->state = ISO_CON_STATE_STOPPED; break; default: if (DEBUG) printf("COTP Unknown Indication: %i\n", cotpIndication); self->state = ISO_CON_STATE_STOPPED; break; } } Socket_destroy(self->socket); //if (DEBUG) printf("IsoConnection: connection closed!\n"); AcseConnection_destroy(&acseConnection); IsoServer_closeConnection(self->isoServer, self); CotpConnection_destroy(&cotpConnection); }