From c291db5d959cd65f2145f54a2e9d6c0cbfd72f4f Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Wed, 8 Nov 2017 08:53:37 +0100 Subject: [PATCH] - updated README file - SV receiver: Added semaphore to make subscriber list thread-safe --- README.md | 12 +++--- .../server/mms_named_variable_list_service.c | 7 +--- src/sampled_values/sv_subscriber.c | 39 +++++++++++++++++++ 3 files changed, 48 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 53f5cd97..e4e945c0 100644 --- a/README.md +++ b/README.md @@ -73,15 +73,17 @@ To build the library and run libiec61850 applications with GOOSE support on Wind ## Building with the cmake build script -With the help of the cmake build script it is possible to create platform independet project descriptions and let cmake create specific project or build files for other tools like Make or Visual Studio. +With the help of the cmake build script it is possible to create platform independent project descriptions and let cmake create specific project or build files for other tools like Make or Visual Studio. -If you have cmake installed fire up a command line (cmd.exe) and create a new subdirectory in the libiec61850 folder. Change to this subdirectory. Then you can invoke cmake. As an command line argument you have to supply a "generator" that is used by cmake to create the project file for the actual build tool (in our case Visual Studio). +If you have cmake installed fire up a command line (cmd.exe) and create a new subdirectory in the libiec61850 folder. Change to this subdirectory. Then you can invoke cmake. As an command line argument you have to supply a "generator" that is used by cmake to create the project file for the actual build tool (in our case Visual Studio 2015). -`cmake -G "Visual Studio 11" ..` +`cmake -G "Visual Studio 14 2015" ..` -will instruct cmake to create a "solution" for Visual Studio 2012. To do the same thing for Visual Studio 2010 type +will instruct cmake to create a "solution" for Visual Studio 2015. The resulting project files will be 32 bit. -`cmake -G "Visual Studio 10" ..` +To build 64 bit libraries the "Win64" generator option has to be added. + +`cmake -G "Visual Studio 14 2015 Win64" ..` Note: The ".." at the end of the command line tells cmake where to find the main build script file (called CMakeLists.txt). This should point to the folder libiec61850 which is in our case the parent directory (..). diff --git a/src/mms/iso_mms/server/mms_named_variable_list_service.c b/src/mms/iso_mms/server/mms_named_variable_list_service.c index c56f6ca6..9192f68b 100644 --- a/src/mms/iso_mms/server/mms_named_variable_list_service.c +++ b/src/mms/iso_mms/server/mms_named_variable_list_service.c @@ -498,8 +498,7 @@ mmsServer_handleDefineNamedVariableListRequest( char variableListName[65]; if (request->variableListName.choice.aaspecific.size > 64) { - //TODO send reject PDU instead? - mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_NON_EXISTENT); + mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_REQUEST_INVALID_ARGUMENT, response); goto exit_free_struct; } @@ -543,8 +542,7 @@ mmsServer_handleDefineNamedVariableListRequest( char variableListName[65]; if (request->variableListName.choice.vmdspecific.size > 64) { - //TODO send reject PDU instead? - mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_NON_EXISTENT); + mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_REQUEST_INVALID_ARGUMENT, response); goto exit_free_struct; } @@ -583,7 +581,6 @@ mmsServer_handleDefineNamedVariableListRequest( exit_free_struct: asn_DEF_MmsPdu.free_struct(&asn_DEF_MmsPdu, mmsPdu, 0); -exit_function: return; } diff --git a/src/sampled_values/sv_subscriber.c b/src/sampled_values/sv_subscriber.c index 5ebaadb3..4d2f70fc 100644 --- a/src/sampled_values/sv_subscriber.c +++ b/src/sampled_values/sv_subscriber.c @@ -50,7 +50,13 @@ struct sSVReceiver { uint8_t* buffer; EthernetSocket ethSocket; + LinkedList subscriberList; + +#if (CONFIG_MMS_THREADLESS_STACK == 0) + Semaphore subscriberListLock; +#endif + }; struct sSVSubscriber { @@ -88,6 +94,10 @@ SVReceiver_create(void) self->buffer = (uint8_t*) GLOBAL_MALLOC(ETH_BUFFER_LENGTH); self->checkDestAddr = false; + +#if (CONFIG_MMS_THREADLESS_STACK == 0) + self->subscriberListLock = Semaphore_create(1); +#endif } return self; @@ -111,13 +121,29 @@ SVReceiver_disableDestAddrCheck(SVReceiver self) void SVReceiver_addSubscriber(SVReceiver self, SVSubscriber subscriber) { +#if (CONFIG_MMS_THREADLESS_STACK == 0) + Semaphore_wait(self->subscriberListLock); +#endif + LinkedList_add(self->subscriberList, (void*) subscriber); + +#if (CONFIG_MMS_THREADLESS_STACK == 0) + Semaphore_post(self->subscriberListLock); +#endif } void SVReceiver_removeSubscriber(SVReceiver self, SVSubscriber subscriber) { +#if (CONFIG_MMS_THREADLESS_STACK == 0) + Semaphore_wait(self->subscriberListLock); +#endif + LinkedList_remove(self->subscriberList, (void*) subscriber); + +#if (CONFIG_MMS_THREADLESS_STACK == 0) + Semaphore_post(self->subscriberListLock); +#endif } static void @@ -174,6 +200,10 @@ SVReceiver_destroy(SVReceiver self) LinkedList_destroyDeep(self->subscriberList, (LinkedListValueDeleteFunction) SVSubscriber_destroy); +#if (CONFIG_MMS_THREADLESS_STACK == 0) + Semaphore_destroy(self->subscriberListLock); +#endif + GLOBAL_FREEMEM(self->buffer); GLOBAL_FREEMEM(self); } @@ -398,6 +428,11 @@ parseSVMessage(SVReceiver self, int numbytes) /* check if there is a matching subscriber */ + +#if (CONFIG_MMS_THREADLESS_STACK == 0) + Semaphore_wait(self->subscriberListLock); +#endif + LinkedList element = LinkedList_getNext(self->subscriberList); SVSubscriber subscriber; @@ -427,6 +462,10 @@ parseSVMessage(SVReceiver self, int numbytes) element = LinkedList_getNext(element); } +#if (CONFIG_MMS_THREADLESS_STACK == 0) + Semaphore_post(self->subscriberListLock); +#endif + if (subscriberFound) parseSVPayload(self, subscriber, buffer + bufPos, apduLength);