diff --git a/src/goose/goose_receiver.c b/src/goose/goose_receiver.c index 0de87f9..0a6c958 100644 --- a/src/goose/goose_receiver.c +++ b/src/goose/goose_receiver.c @@ -47,6 +47,7 @@ struct sGooseReceiver { bool running; + bool stopped; char* interfaceId; uint8_t* buffer; EthernetSocket ethSocket; @@ -696,16 +697,20 @@ gooseReceiverLoop(void* threadParameter) { GooseReceiver self = (GooseReceiver) threadParameter; + self->running = true; + self->stopped = false; + GooseReceiver_startThreadless(self); while (self->running) { - GooseReceiver_tick(self); - - Thread_sleep(1); + if (GooseReceiver_tick(self) == false) + Thread_sleep(1); } GooseReceiver_stopThreadless(self); + + self->stopped = true; } @@ -732,6 +737,9 @@ void GooseReceiver_stop(GooseReceiver self) { self->running = false; + + while (self->stopped == false) + Thread_sleep(1); } void @@ -770,11 +778,15 @@ GooseReceiver_stopThreadless(GooseReceiver self) } // call after reception of ethernet frame and periodically to to house keeping tasks -void +bool GooseReceiver_tick(GooseReceiver self) { int packetSize = Ethernet_receivePacket(self->ethSocket, self->buffer, ETH_BUFFER_LENGTH); - if (packetSize > 0) + if (packetSize > 0) { parseGooseMessage(self, packetSize); + return true; + } + else + return false; } diff --git a/src/goose/goose_receiver.h b/src/goose/goose_receiver.h index c57f1d7..4fa6edb 100644 --- a/src/goose/goose_receiver.h +++ b/src/goose/goose_receiver.h @@ -34,9 +34,27 @@ GooseReceiver_create(void); void GooseReceiver_setInterfaceId(GooseReceiver self, const char* interfaceId); +/** + * \brief Add a subscriber to this receiver instance + * + * NOTE: Do not call this function while the receiver is running (after GooseReceiver_start + * has been called)! + * + * \param self the GooseReceiver instance + * \param subscriber the GooseSubscriber instance to add + */ void GooseReceiver_addSubscriber(GooseReceiver self, GooseSubscriber subscriber); +/** + * \brief Remove a subscriber from this receiver instance + * + * NOTE: Do not call this function while the receiver is running (after GooseReceiver_start + * has been called)! + * + * \param self the GooseReceiver instance + * \param subscriber the GooseSubscriber instance to remove + */ void GooseReceiver_removeSubscriber(GooseReceiver self, GooseSubscriber subscriber); @@ -63,8 +81,16 @@ GooseReceiver_startThreadless(GooseReceiver self); void GooseReceiver_stopThreadless(GooseReceiver self); -// call after reception of ethernet frame and periodically to to house keeping tasks -void +/** + * \brief Parse GOOSE messages if they are available + * + * Call after reception of ethernet frame and periodically to to house keeping tasks + * + * \param self the receiver object + * + * \return true if a message was available and has been parsed, false otherwise + */ +bool GooseReceiver_tick(GooseReceiver self); #endif /* GOOSE_RECEIVER_H_ */ diff --git a/src/hal/socket/bsd/socket_bsd.c b/src/hal/socket/bsd/socket_bsd.c index 0945721..4c60940 100644 --- a/src/hal/socket/bsd/socket_bsd.c +++ b/src/hal/socket/bsd/socket_bsd.c @@ -306,7 +306,7 @@ Socket_connect(Socket self, const char* address, int port) timeout.tv_sec = self->connectTimeout / 1000; timeout.tv_usec = (self->connectTimeout % 1000) * 1000; - if (select(self->fd + 1, NULL, &fdSet, NULL, &timeout) < 0) + if (select(self->fd + 1, NULL, &fdSet, NULL, &timeout) <= 0) return false; else return true; diff --git a/src/hal/socket/linux/socket_linux.c b/src/hal/socket/linux/socket_linux.c index 3a878ef..98d255b 100644 --- a/src/hal/socket/linux/socket_linux.c +++ b/src/hal/socket/linux/socket_linux.c @@ -334,7 +334,7 @@ Socket_connect(Socket self, const char* address, int port) timeout.tv_sec = self->connectTimeout / 1000; timeout.tv_usec = (self->connectTimeout % 1000) * 1000; - if (select(self->fd + 1, NULL, &fdSet, NULL, &timeout) < 0) + if (select(self->fd + 1, NULL, &fdSet, NULL, &timeout) <= 0) return false; else return true; diff --git a/src/hal/socket/win32/socket_win32.c b/src/hal/socket/win32/socket_win32.c index 528237a..fd7c6a6 100644 --- a/src/hal/socket/win32/socket_win32.c +++ b/src/hal/socket/win32/socket_win32.c @@ -311,7 +311,7 @@ Socket_connect(Socket self, const char* address, int port) timeout.tv_sec = self->connectTimeout / 1000; timeout.tv_usec = (self->connectTimeout % 1000) * 1000; - if (select(self->fd + 1, NULL, &fdSet, NULL, &timeout) < 0) + if (select(self->fd + 1, NULL, &fdSet, NULL, &timeout) <= 0) return false; else return true; diff --git a/src/iec61850/client/client_goose_control.c b/src/iec61850/client/client_goose_control.c index 3ee6de5..5a8c56c 100644 --- a/src/iec61850/client/client_goose_control.c +++ b/src/iec61850/client/client_goose_control.c @@ -214,7 +214,7 @@ ClientGooseControlBlock_getDstAddress_priority(ClientGooseControlBlock self) void ClientGooseControlBlock_setDstAddress_priority(ClientGooseControlBlock self, uint8_t priorityValue) { - if (self->dstAddress != NULL) + if (self->dstAddress == NULL) self->dstAddress = newEmptyPhyCommAddress(); MmsValue* priority = MmsValue_getElement(self->dstAddress, 1); @@ -233,7 +233,7 @@ ClientGooseControlBlock_getDstAddress_vid(ClientGooseControlBlock self) void ClientGooseControlBlock_setDstAddress_vid(ClientGooseControlBlock self, uint16_t vidValue) { - if (self->dstAddress != NULL) + if (self->dstAddress == NULL) self->dstAddress = newEmptyPhyCommAddress(); MmsValue* vid = MmsValue_getElement(self->dstAddress, 2); @@ -252,7 +252,7 @@ ClientGooseControlBlock_getDstAddress_appid(ClientGooseControlBlock self) void ClientGooseControlBlock_setDstAddress_appid(ClientGooseControlBlock self, uint16_t appidValue) { - if (self->dstAddress != NULL) + if (self->dstAddress == NULL) self->dstAddress = newEmptyPhyCommAddress(); MmsValue* appid = MmsValue_getElement(self->dstAddress, 3); diff --git a/src/iec61850/client/client_report.c b/src/iec61850/client/client_report.c index 181e09d..fe0b5d4 100644 --- a/src/iec61850/client/client_report.c +++ b/src/iec61850/client/client_report.c @@ -328,8 +328,6 @@ private_IedConnection_handleReport(IedConnection self, MmsValue* value) char* rptId = report->rptId; - printf("Report ID is null!\n"); - if (rptId == NULL) rptId = report->rcbReference; diff --git a/src/iec61850/server/mms_mapping/mms_mapping.c b/src/iec61850/server/mms_mapping/mms_mapping.c index dc29190..a3f9f5a 100644 --- a/src/iec61850/server/mms_mapping/mms_mapping.c +++ b/src/iec61850/server/mms_mapping/mms_mapping.c @@ -2399,21 +2399,25 @@ MmsMapping_createMmsVariableNameFromObjectReference(const char* objectReference, int sourceIndex = i; int destIndex = 0; - while (objectReference[sourceIndex] != '.') - mmsVariableName[destIndex++] = objectReference[sourceIndex++]; - - sourceIndex++; - - mmsVariableName[destIndex++] = '$'; - mmsVariableName[destIndex++] = fcString[0]; - mmsVariableName[destIndex++] = fcString[1]; - mmsVariableName[destIndex++] = '$'; + bool fcAdded = false; while (sourceIndex < objRefLength) { + if (objectReference[sourceIndex] != '.') mmsVariableName[destIndex++] = objectReference[sourceIndex++]; else { - mmsVariableName[destIndex++] = '$'; + + if (!fcAdded) { + mmsVariableName[destIndex++] = '$'; + mmsVariableName[destIndex++] = fcString[0]; + mmsVariableName[destIndex++] = fcString[1]; + mmsVariableName[destIndex++] = '$'; + + fcAdded = true; + } + else + mmsVariableName[destIndex++] = '$'; + sourceIndex++; } }