示例#1
0
void
IsoServer_destroy(IsoServer self)
{

#if (CONFIG_MMS_THREADLESS_STACK != 1)
    if (self->state == ISO_SVR_STATE_RUNNING)
        IsoServer_stopListening(self);
#endif

#if (CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS == -1)

#if (CONFIG_MMS_SINGLE_THREADED == 1)
    if (self->openClientConnections != NULL)
        LinkedList_destroy(self->openClientConnections);
#else
    if (self->openClientConnections != NULL)
        LinkedList_destroyStatic(self->openClientConnections);
#endif /* (CONFIG_MMS_SINGLE_THREADED == 1) */

#if (CONFIG_MMS_THREADLESS_STACK != 1)
    lockClientConnections(self);
    Semaphore_destroy(self->openClientConnectionsMutex);
#endif

#else
    GLOBAL_FREEMEM(self->openClientConnections);
#endif /* (CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS == -1) */

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

    GLOBAL_FREEMEM(self);
}
示例#2
0
void
MmsServer_destroy(MmsServer self)
{
    Map_deleteDeep(self->openConnections, false, closeConnection);
    Map_deleteDeep(self->valueCaches, false, (void (*) (void*)) deleteSingleCache);
    Semaphore_destroy(self->modelMutex);
    free(self);
}
示例#3
0
void
IedConnection_destroy(IedConnection self)
{
    IedConnection_close(self);

    if (self->logicalDevices != NULL)
        LinkedList_destroyDeep(self->logicalDevices, (LinkedListValueDeleteFunction) ICLogicalDevice_destroy);

    if (self->enabledReports != NULL)
        LinkedList_destroyDeep(self->enabledReports, (LinkedListValueDeleteFunction) ClientReport_destroy);

    LinkedList_destroyStatic(self->clientControls);

    Semaphore_destroy(self->stateMutex);

    free(self);
}
示例#4
0
void
IsoServer_destroy(IsoServer self)
{

#if (CONFIG_MMS_THREADLESS_STACK != 1)
    if (self->state == ISO_SVR_STATE_RUNNING)
        IsoServer_stopListening(self);
#endif

#if (CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS == -1)
    LinkedList_destroy(self->openClientConnections);
#else
    free(self->openClientConnections);
#endif

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

    free(self);
}
示例#5
0
void
ControlObject_destroy(ControlObject* self)
{
    if (self->mmsValue != NULL)
        MmsValue_delete(self->mmsValue);

    if (self->sbo != NULL)
        MmsValue_delete(self->sbo);

    if (self->emptyString != NULL)
        MmsValue_delete(self->emptyString);

    if (self->ctlObjectName != NULL)
        GLOBAL_FREEMEM(self->ctlObjectName);

    if (self->error != NULL)
        MmsValue_delete(self->error);

    if (self->addCause != NULL)
        MmsValue_delete(self->addCause);

    if (self->ctlVal != NULL)
        MmsValue_delete(self->ctlVal);

    if (self->ctlNum != NULL)
        MmsValue_delete(self->ctlNum);

    if (self->origin != NULL)
        MmsValue_delete(self->origin);

    if (self->name != NULL)
        GLOBAL_FREEMEM(self->name);

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

    GLOBAL_FREEMEM(self);
}
示例#6
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);
}