Esempio n. 1
0
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);
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
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);
}
Esempio n. 4
0
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);
}