void IsoConnection_sendMessage(IsoConnection self, ByteBuffer* message) { ByteBuffer presWriteBuffer; ByteBuffer sessionWriteBuffer; Semaphore_wait(self->conMutex); ByteBuffer_wrap(&presWriteBuffer, self->send_buf_1, 0, SEND_BUF_SIZE); ByteBuffer_wrap(&sessionWriteBuffer, self->send_buf_2, 0, SEND_BUF_SIZE); IsoPresentation_createUserData(self->presentation, &presWriteBuffer, message); IsoSession_createDataSpdu(self->session, &sessionWriteBuffer); ByteBuffer_append(&sessionWriteBuffer, presWriteBuffer.buffer, presWriteBuffer.currPos); CotpConnection_sendDataMessage(self->cotpConnection, &sessionWriteBuffer); Semaphore_post(self->conMutex); }
void IsoClientConnection_associate(IsoClientConnection self, IsoConnectionParameters* params, ByteBuffer* payload) { Socket socket = TcpSocket_create(); self->socket = socket; if (!Socket_connect(socket, params->hostname, params->tcpPort)) goto returnError; self->cotpBuf = malloc(ISO_CLIENT_BUFFER_SIZE); self->cotpBuffer = calloc(1, sizeof(ByteBuffer)); ByteBuffer_wrap(self->cotpBuffer, self->cotpBuf, 0, ISO_CLIENT_BUFFER_SIZE); self->cotpConnection = calloc(1, sizeof(CotpConnection)); CotpConnection_init(self->cotpConnection, socket, self->cotpBuffer); /* COTP handshake */ CotpIndication cotpIndication = CotpConnection_sendConnectionRequestMessage(self->cotpConnection); cotpIndication = CotpConnection_parseIncomingMessage(self->cotpConnection); if (cotpIndication != CONNECT_INDICATION) goto returnError; /* Upper layers handshake */ AcseConnection acse; ByteBuffer acseBuffer; ByteBuffer_wrap(&acseBuffer, self->buffer1, 0, ISO_CLIENT_BUFFER_SIZE); AcseConnection_init(&acse); if (params != NULL) AcseConnection_setAuthenticationParameter(&acse, params->acseAuthParameter); AcseConnection_createAssociateRequestMessage(&acse, &acseBuffer, payload); ByteBuffer presentationBuffer; ByteBuffer_wrap(&presentationBuffer, self->buffer2, 0, ISO_CLIENT_BUFFER_SIZE); self->presentation = calloc(1, sizeof(IsoPresentation)); IsoPresentation_init(self->presentation); IsoPresentation_createConnectPdu(self->presentation, &presentationBuffer, &acseBuffer); ByteBuffer sessionBuffer; ByteBuffer_wrap(&sessionBuffer, self->buffer1, 0, ISO_CLIENT_BUFFER_SIZE); self->session = calloc(1, sizeof(IsoSession)); IsoSession_init(self->session); IsoSession_createConnectSpdu(self->session, &sessionBuffer, ByteBuffer_getSize(&presentationBuffer)); ByteBuffer_append(&sessionBuffer, ByteBuffer_getBuffer(&presentationBuffer), ByteBuffer_getSize(&presentationBuffer)); CotpConnection_sendDataMessage(self->cotpConnection, &sessionBuffer); cotpIndication = CotpConnection_parseIncomingMessage(self->cotpConnection); if (cotpIndication != DATA_INDICATION) goto returnError; IsoSessionIndication sessionIndication; sessionIndication = IsoSession_parseMessage(self->session, CotpConnection_getPayload(self->cotpConnection)); if (sessionIndication != SESSION_CONNECT) { if (DEBUG) printf("IsoClientConnection_associate: no session connect indication\n"); goto returnError; } IsoPresentationIndication presentationIndication; presentationIndication = IsoPresentation_parseAcceptMessage(self->presentation, IsoSession_getUserData(self->session)); if (presentationIndication != PRESENTATION_OK) { if (DEBUG) printf("IsoClientConnection_associate: no presentation ok indication\n"); goto returnError; } AcseIndication acseIndication; acseIndication = AcseConnection_parseMessage(&acse, &self->presentation->nextPayload); if (acseIndication != ACSE_ASSOCIATE) { if (DEBUG) printf("IsoClientConnection_associate: no ACSE_ASSOCIATE indication\n"); goto returnError; } ByteBuffer acsePayload; //TODO allocate buffer dynamically??? ByteBuffer_wrap(&acsePayload, acse.userDataBuffer, acse.userDataBufferSize, 1024); self->callback(ISO_IND_ASSOCIATION_SUCCESS, self->callbackParameter, &acsePayload); self->state = STATE_ASSOCIATED; AcseConnection_destroy(&acse); self->thread = Thread_create(connectionHandlingThread, self, false); Thread_start(self->thread); return; returnError: self->callback(ISO_IND_ASSOCIATION_FAILED, self->callbackParameter, &acsePayload); AcseConnection_destroy(&acse); self->state = STATE_ERROR; return; }
int mmsClient_write_out(void *buffer, size_t size, void *app_key) { ByteBuffer* writeBuffer = (ByteBuffer*) app_key; return ByteBuffer_append(writeBuffer, (uint8_t*) buffer, size); }
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); }