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); }
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; }
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 }
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); }
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; }
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); }
static inline void lockClientConnections(IsoServer self) { Semaphore_wait(self->openClientConnectionsMutex); }
void IsoServer_userLock(IsoServer self) { if (self->userLock != NULL) Semaphore_wait(self->userLock); }
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); }