void
MmsServer_lockModel(MmsServer self)
{
#if (CONFIG_MMS_THREADLESS_STACK != 1)
    Semaphore_wait(self->modelMutex);
#endif
}
static void
IedConnection_setState(IedConnection self, IedConnectionState newState)
{
    Semaphore_wait(self->stateMutex);
    self->state = newState;
    Semaphore_post(self->stateMutex);
}
Exemple #3
0
int send_digital_to_ihm(int socketfd, struct sockaddr_in * server_sock_addr,unsigned int nponto, unsigned char ihm_station, unsigned char state, time_t time_stamp,unsigned short time_stamp_extended, char report){
	//struct tm * time_result;
	struct tm time_result = {0};

	t_msgsup msg_sup;
	unsigned char digital_state;

	memset(&msg_sup, 0, sizeof(t_msgsup));
	msg_sup.signature = IHM_SINGLE_POINT_SIGN;
	msg_sup.endereco = nponto;
	msg_sup.prim = ihm_station;
	
	digital_state = get_digital_state(state);

	//only send as report if timestamp is valid
	if(report && time_stamp != 0xffffffff){
		digital_w_time7_seq digital_value;
		msg_sup.causa=3; //report
		msg_sup.tipo=30;
		msg_sup.taminfo=sizeof(digital_w_time7_seq);
		digital_value.iq = digital_state;
		//time_result = (struct tm *)localtime(&time_stamp);
		//
		Semaphore_wait(localtime_mutex);	
		if(localtime_r(&time_stamp, &time_result) == 0){
			LOG_MESSAGE("error obtaining localtime nponto %d, time_stamp %d, extended %d \n", nponto, time_stamp, time_stamp_extended);
		}
		Semaphore_post(localtime_mutex);	

		digital_value.ms=(time_result.tm_sec*1000)+time_stamp_extended;
		digital_value.min=time_result.tm_min;
		digital_value.hora=time_result.tm_hour;
		digital_value.dia=time_result.tm_mday;
		digital_value.mes=time_result.tm_mon+1;
		if(time_result.tm_year >=100)
			digital_value.ano=time_result.tm_year-100;
		else
			digital_value.ano=time_result.tm_year;
		memcpy(msg_sup.info,(char *) &digital_value, sizeof(digital_w_time7_seq));
	}
	else {
		digital_seq digital_value_gi;
		msg_sup.tipo=1;
		if(report){
			msg_sup.causa=3; //report
			LOG_MESSAGE("report with invalid timestamp nponto %d, time_stamp %d, extended %d \n", nponto, time_stamp, time_stamp_extended);
		}else
			msg_sup.causa=20; //integrity
		msg_sup.taminfo=sizeof(digital_seq);
		digital_value_gi.iq = digital_state;
		memcpy(msg_sup.info,(char *) &digital_value_gi, sizeof(digital_seq));
	}
	
	return SendT(socketfd,(void *)&msg_sup, sizeof(t_msgsup), server_sock_addr);
}
IedConnectionState
IedConnection_getState(IedConnection self)
{
    IedConnectionState state;

    Semaphore_wait(self->stateMutex);
    state = self->state;
    Semaphore_post(self->stateMutex);

    return state;
}
Exemple #5
0
static void
setState(ControlObject* self, int newState)
{
#if (CONFIG_MMS_THREADLESS_STACK != 1)
    Semaphore_wait(self->stateLock);
#endif

    self->state = newState;

#if (CONFIG_MMS_THREADLESS_STACK != 1)
    Semaphore_post(self->stateLock);
#endif
}
Exemple #6
0
void
private_IsoServer_increaseConnectionCounter(IsoServer self)
{
#if (CONFIG_MMS_THREADLESS_STACK != 1)
    Semaphore_wait(self->connectionCounterMutex);
#endif

    self->connectionCounter++;
    if (DEBUG_ISO_SERVER)
        printf("IsoServer: increase connection counter to %i!\n", self->connectionCounter);

#if (CONFIG_MMS_THREADLESS_STACK != 1)
    Semaphore_post(self->connectionCounterMutex);
#endif
}
void
IsoConnection_sendMessage(IsoConnection self, ByteBuffer* message, bool handlerMode)
{
    if (self->state == ISO_CON_STATE_STOPPED) {
        if (DEBUG_ISO_SERVER)
            printf("DEBUG_ISO_SERVER: sendMessage: connection already stopped!\n");
        return;
    }

    if (!handlerMode)
        Semaphore_wait(self->conMutex);

    struct sBufferChain payloadBufferStruct;
    BufferChain payloadBuffer = &payloadBufferStruct;
    payloadBuffer->length = message->size;
    payloadBuffer->partLength = message->size;
    payloadBuffer->partMaxLength = message->size;
    payloadBuffer->buffer = message->buffer;
    payloadBuffer->nextPart = NULL;

    struct sBufferChain presentationBufferStruct;
    BufferChain presentationBuffer = &presentationBufferStruct;
    presentationBuffer->buffer = self->sendBuffer;
    presentationBuffer->partMaxLength = SEND_BUF_SIZE;

    IsoPresentation_createUserData(self->presentation,
            presentationBuffer, payloadBuffer);

    struct sBufferChain sessionBufferStruct;
    BufferChain sessionBuffer = &sessionBufferStruct;
    sessionBuffer->buffer = self->sendBuffer + presentationBuffer->partLength;

    IsoSession_createDataSpdu(self->session, sessionBuffer, presentationBuffer);

    CotpIndication indication;

    indication = CotpConnection_sendDataMessage(self->cotpConnection, sessionBuffer);

    if (DEBUG_ISO_SERVER) {
        if (indication != OK)
            printf("ISO_SERVER: IsoConnection_sendMessage failed!\n");
        else
            printf("ISO_SERVER: IsoConnection_sendMessage success!\n");
    }

    if (!handlerMode)
        Semaphore_post(self->conMutex);
}
Exemple #8
0
int
private_IsoServer_getConnectionCounter(IsoServer self)
{
    int connectionCounter;

#if (CONFIG_MMS_THREADLESS_STACK != 1)
    Semaphore_wait(self->connectionCounterMutex);
#endif

    connectionCounter = self->connectionCounter;

#if (CONFIG_MMS_THREADLESS_STACK != 1)
    Semaphore_post(self->connectionCounterMutex);
#endif

    return connectionCounter;
}
Exemple #9
0
static int
getState(ControlObject* self)
{
    int state;

#if (CONFIG_MMS_THREADLESS_STACK != 1)
    Semaphore_wait(self->stateLock);
#endif

    state = self->state;

#if (CONFIG_MMS_THREADLESS_STACK != 1)
    Semaphore_post(self->stateLock);
#endif

    return state;
}
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);
}
Exemple #11
0
static inline void
lockClientConnections(IsoServer self)
{
    Semaphore_wait(self->openClientConnectionsMutex);
}
Exemple #12
0
void
IsoServer_userLock(IsoServer self)
{
    if (self->userLock != NULL)
        Semaphore_wait(self->userLock);
}
Exemple #13
0
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);
}