From 7eeac08551c0e5e4776822c2c85a0b7c6ad3bc78 Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Wed, 8 Jul 2015 16:04:35 +0300 Subject: [PATCH 01/14] - first commit for pavo changes --- config/stack_config.h | 2 +- src/goose/goose_publisher.c | 2 ++ src/goose/goose_receiver.c | 1 - src/iec61850/client/ied_connection.c | 16 ++++++++++++++++ tools/model_generator/genmodel.jar | Bin 75190 -> 75201 bytes 5 files changed, 19 insertions(+), 2 deletions(-) diff --git a/config/stack_config.h b/config/stack_config.h index 49fb2e5c..72245fdd 100644 --- a/config/stack_config.h +++ b/config/stack_config.h @@ -21,7 +21,7 @@ #define DEBUG_IED_CLIENT 0 #define DEBUG_MMS_CLIENT 0 #define DEBUG_MMS_SERVER 0 -#define DEBUG_GOOSE_SUBSCRIBER 0 +#define DEBUG_GOOSE_SUBSCRIBER 1 #define DEBUG_GOOSE_PUBLISHER 0 /* Maximum MMS PDU SIZE - default is 65000 */ diff --git a/src/goose/goose_publisher.c b/src/goose/goose_publisher.c index cc453865..c09466ee 100644 --- a/src/goose/goose_publisher.c +++ b/src/goose/goose_publisher.c @@ -201,6 +201,7 @@ prepareGooseBuffer(GoosePublisher self, CommParameters* parameters, const char* int bufPos = 12; +#if 0 /* Priority tag - IEEE 802.1Q */ self->buffer[bufPos++] = 0x81; self->buffer[bufPos++] = 0x00; @@ -212,6 +213,7 @@ prepareGooseBuffer(GoosePublisher self, CommParameters* parameters, const char* self->buffer[bufPos++] = tci1; /* Priority + VLAN-ID */ self->buffer[bufPos++] = tci2; /* VLAN-ID */ +#endif /* EtherType GOOSE */ self->buffer[bufPos++] = 0x88; diff --git a/src/goose/goose_receiver.c b/src/goose/goose_receiver.c index 44595d97..960073a3 100644 --- a/src/goose/goose_receiver.c +++ b/src/goose/goose_receiver.c @@ -752,7 +752,6 @@ GooseReceiver_destroy(GooseReceiver self) void GooseReceiver_startThreadless(GooseReceiver self) { - if (self->interfaceId == NULL) self->ethSocket = Ethernet_createSocket(CONFIG_ETHERNET_INTERFACE_ID, NULL); else diff --git a/src/iec61850/client/ied_connection.c b/src/iec61850/client/ied_connection.c index f71a4451..77a912f6 100644 --- a/src/iec61850/client/ied_connection.c +++ b/src/iec61850/client/ied_connection.c @@ -604,21 +604,37 @@ IedConnection_close(IedConnection self) void IedConnection_destroy(IedConnection self) { + printf("D1\n"); + IedConnection_close(self); + printf("D2\n"); + MmsConnection_destroy(self->connection); + printf("D3\n"); + if (self->logicalDevices != NULL) LinkedList_destroyDeep(self->logicalDevices, (LinkedListValueDeleteFunction) ICLogicalDevice_destroy); + printf("D4\n"); + +#if 0 if (self->enabledReports != NULL) LinkedList_destroyDeep(self->enabledReports, (LinkedListValueDeleteFunction) ClientReport_destroy); +#endif LinkedList_destroyStatic(self->clientControls); + printf("D6\n"); + Semaphore_destroy(self->stateMutex); + printf("D7\n"); + GLOBAL_FREEMEM(self); + + printf("D8\n"); } MmsVariableSpecification* diff --git a/tools/model_generator/genmodel.jar b/tools/model_generator/genmodel.jar index 2f84d3f0cf473a060599bd9963ff978e1d3a0646..f0c858a9a7ceec6bf3138f8655f41317876dd160 100644 GIT binary patch delta 4140 zcmZ`+dpuO>8$ZYWGQ!LljN2F{G;WhiqC#OqKU73fD#|5=MQJOuNs&r&;>e|%$i0R} zDb!NPrCpKRD!H_k+G0^{{VMx=&pWnlw$E?ok8|dEzt8viKF|A{_dIj0L!z-mLcz;j zT!Mg2*6*6Xu0-ARN=h?$f2P za#RKHq@q%S07)+uVnM*C9~UQXu&gu)5tO45LPOv5a#V}B>P1ZcBX}e zn`)u5_>d;5D2U2w6C*%ZFmq{0z9fG}5_%nRw}RKo^=!cl_bC`aP`SPf!m;`)7Ird7 zO27}W6B_v5Y=Mkdp#=2N8Dup`M1u71NNxWR@*pyp@wBeh8!|aG@-Rz6l|npjc06(HZWNfes3n*mwXFaM})yLFpK8 znvLf(P$j{G_CJK;O=it%ep5!pQ2DQR9s{B9PA!xoC@GK;;s{TmPXbraLrDVD@jhXh zIfD==EvUGtW-g*OV9Dulw$w0sh#2FPl1rO+cnY9i6M3{V-#`@80L zgRYA?49nGc%A-M2kkw??L73B$e3l@0XU*T9EI~*31u@kx?I+TnOwgXHSY6sY(Z0s` zbX~ks10~}{bWjQ_Zm_U`S!p3cTFxK~_t!vG1!_l%zX&2cnB2^D4`V1kYJcT#$A*d? z`iJtId822q6^?EQmk(VjFNIlKvb@R~tbZ+%ceReNzIgruGu3zh_nO=DqN&@nr=0T| zucaKS=M>y2;2ym7VWjR*&tycme}?pd54U1&&1_5kz1`X* zD5Ub`&rcgQe^*y%md)uc41dFE{baK>w3c@US9|4V-I19e#^O$R>XWSSpc1-##<|ZM zTr3n9TJBq3d+N=`M_PZf-c(0=d6pb_&5_b|U?2H!de&;`nHSN$YO7n;>X)9#ar?C2 zuWiFVd0!_dH>V9wE=e9;QbkX~`+DB2@^H%H*_P&1F<))>+~+*<);XW`itPGH^8M9n zl39ntAJsFOd8?O3HgS9J(35?*`nF!)<6~%W>}VoMad2B~RCin3?s#>zQLEtJHj{U$ z?_H%Fudd25c|ta|usppkX?YHQrR;eBl++GcGKwZiU0GLvp4Pb--vHlJyFa|J+<~kGnrFiQXAvRH7c!t**8<XI)A#xl6j|*H#*X4xFTr1}}PvaNoC z-xh|`H_YE_$iGM~YaDT7m&y*UESIfWV;{wXE zJ7fF6l_z7HTv>}sJaTF6Yc1o{cRZ*b>!!N7492Zb>yKR1I#us_ll%IE{lGffJ>I5P z_L7}HD7G(;HjML5Q(jKFA2zmd+j*LnE3Jgl@AulsSLWJ-W|d2gnmHp28rvri7H+$z z)_=v#(fZ-6|E{VGQdZmR8xd|6CZ129s}#37b{6OGq+9*l3Rij8FVwtQYId*KLA|B& z;4Qs};}&}7Q|(==%f|Q_+-AFDd5`Ch?KZDnyKHchF-m&P`f=!Ww&d@d?a!xDGz`QH z-g)3b^R~u+Jg|~<=<&yr?bq90hK>fuC*^G7`9!tFl)S!LGq^F%qU5Kem($jbE~Agz zTHWJC&oiBPr>%IctSVvF`s@;i2cgB~duip|`2|*4tKIL4S0AS-gmk$XawkS;TKubN zH=iz(oHk1L?2oC5zA-ZW;X+4T)`<<4(U;CS`tu8Vrz#t#RId4zDUN98H%s-ms7EX) z>k603y^)+Ib=T9w?Qx%p^|9c03Vmyg?E)7at235Z(eJc7WcH+8=j_;-r7kxmhpms9 z91h+o&+H=qdi`_I8{_zA{<-E&+%xwX{*NA~81&s+25uzQ_J> zpi}4C9RA)4v)+#yKBm6sDBK#q~ddUP4A3TU}0ir`JjQjPuzus@|fgVNiTP4nKQiu=ed#yLY)61qYD-t z#sUYw5-y{GDhtLEC&d&{F)H$9jKF8es15OA!A&WsJ-mscpl0yq0tK~$HzO3(5sp0V zG8_kM6$H6!f*>4xAr)Ohj3{IV@OL?cir+O8M-Xc%1X=jiXoMgnRUB189Uv+;bJoNP zpcVs^g$OE_jyqCOM;Opa1@#w7P(c^Te=V1%iE4=Lb;n25Q5|CP(SWQw>IbkMz*sa7 z=n`Q~^uQVuXn33^Y6J;C68=|xg#L@PP%5-~XaQ@vKaSE+LufFj0mBn$(8ON2)9`&X zlmtU{?C6i(EruZ85(r{05=v|{zC{&X22nG)2l}W0)d*5G5JB~AC8B6z`~U@f0Fc6P zsYE#YZNe29FBQ0=LsXR$%E&AS8!JIV5K|E%Wt^jqs)7NG4$&~|i}v-2g&D5yVOasvalQkr$?cztWsb+ZOlxOB*nsmHu~yJ$6Gl zZmx#vL1u@N@D(H=cey%(=!r0Q{6N$lPQ^GZxnVNqSfKr{j=Zb`im{nk(Inr|t}a5xznRK|q^-^{K@OB*u74`KRI#cjUABFJ>8EuzCcLiWcYA4I(T{+#@m=@1mg;2p6Nuu_i#i0YIrJ{J*s@K9*ge^v`2( zp9zv)@sn_u!Fa6(N$P**YZ)p40tSMxMU?qA3rR|@&cn~?%soqKdVpl08&>Y#w36b# zDu=i0f_39wxE?U5{LMOF8?2)Pa687eQTSI4mtz29SK+`sY$3*n3q>Mu(nD^Db3F1fuDVz|NCjtC`of54M ztk2&O#~hZsQ~8@tnF$EjiUs@c4>nh{Q(8Vkr;c!8d&wdH=g)&k&9i2K)BFXZ-I)K& zpV@9;pA$h&qWSdAVkp=0n^ZJ3dq);V6Y6!9jeCx>w KGD!vx0P;Vd)6!D_ delta 3894 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 Date: Mon, 20 Jul 2015 10:37:40 +0200 Subject: [PATCH 02/14] - added function LogicalNode_getDataSet --- config/stack_config.h | 6 +-- src/goose/goose_publisher.c | 5 +++ src/goose/goose_receiver.c | 7 +++ src/iec61850/inc/iec61850_model.h | 11 +++++ src/iec61850/inc/iec61850_server.h | 6 ++- src/iec61850/inc_private/mms_mapping.h | 2 +- src/iec61850/server/impl/ied_server.c | 35 +++++++++------ src/iec61850/server/mms_mapping/mms_goose.c | 1 - src/iec61850/server/mms_mapping/mms_mapping.c | 13 ++++-- src/iec61850/server/model/model.c | 40 ++++++++++++++++++ src/mms/iso_mms/server/mms_access_result.c | 18 ++++---- tools/model_generator/genmodel.jar | Bin 75201 -> 75201 bytes 12 files changed, 111 insertions(+), 33 deletions(-) diff --git a/config/stack_config.h b/config/stack_config.h index 72245fdd..74622810 100644 --- a/config/stack_config.h +++ b/config/stack_config.h @@ -10,7 +10,7 @@ #define STACK_CONFIG_H_ /* include asserts if set to 1 */ -#define DEBUG 1 +#define DEBUG 0 /* print debugging information with printf if set to 1 */ #define DEBUG_SOCKET 0 @@ -21,7 +21,7 @@ #define DEBUG_IED_CLIENT 0 #define DEBUG_MMS_CLIENT 0 #define DEBUG_MMS_SERVER 0 -#define DEBUG_GOOSE_SUBSCRIBER 1 +#define DEBUG_GOOSE_SUBSCRIBER 0 #define DEBUG_GOOSE_PUBLISHER 0 /* Maximum MMS PDU SIZE - default is 65000 */ @@ -136,7 +136,7 @@ #define CONFIG_IEC61850_SETTING_GROUPS 1 /* default reservation time of a setting group control block in s */ -#define CONFIG_IEC61850_SG_RESVTMS 10 +#define CONFIG_IEC61850_SG_RESVTMS 300 /* default results for MMS identify service */ #define CONFIG_DEFAULT_MMS_VENDOR_NAME "libiec61850.com" diff --git a/src/goose/goose_publisher.c b/src/goose/goose_publisher.c index c09466ee..cea381c4 100644 --- a/src/goose/goose_publisher.c +++ b/src/goose/goose_publisher.c @@ -376,6 +376,11 @@ GoosePublisher_publish(GoosePublisher self, LinkedList dataSet) if (DEBUG_GOOSE_PUBLISHER) printf("GOOSE_PUBLISHER: send GOOSE message\n"); + struct timeval tv; + + gettimeofday(&tv,NULL/*&tz*/); + printf("GOOSE SEND: %ld %ld\n",tv.tv_sec, tv.tv_usec); + Ethernet_sendPacket(self->ethernetSocket, self->buffer, self->payloadStart + payloadLength); return 0; diff --git a/src/goose/goose_receiver.c b/src/goose/goose_receiver.c index 960073a3..201fcf93 100644 --- a/src/goose/goose_receiver.c +++ b/src/goose/goose_receiver.c @@ -612,6 +612,13 @@ exit_with_fault: static void parseGooseMessage(GooseReceiver self, int numbytes) { + struct timeval tv; + + gettimeofday(&tv,NULL/*&tz*/); + + printf("RCVD GOOSE: %ld %ld\n",tv.tv_sec, tv.tv_usec); + + int bufPos; bool subscriberFound = false; uint8_t* buffer = self->buffer; diff --git a/src/iec61850/inc/iec61850_model.h b/src/iec61850/inc/iec61850_model.h index f8d36e63..338c5038 100644 --- a/src/iec61850/inc/iec61850_model.h +++ b/src/iec61850/inc/iec61850_model.h @@ -416,6 +416,17 @@ LogicalNode_hasBufferedReports(LogicalNode* node); bool LogicalNode_hasUnbufferedReports(LogicalNode* node); +/** + * \brief get a data set instance + * + * \param self the logical node instance of the data set + * \param dataSetName the name of the data set + * + * \return the data set instance or NULL if the data set does not exist + */ +DataSet* +LogicalNode_getDataSet(LogicalNode* self, const char* dataSetName); + bool DataObject_hasFCData(DataObject* dataObject, FunctionalConstraint fc); diff --git a/src/iec61850/inc/iec61850_server.h b/src/iec61850/inc/iec61850_server.h index 263f6f52..834a4673 100644 --- a/src/iec61850/inc/iec61850_server.h +++ b/src/iec61850/inc/iec61850_server.h @@ -960,11 +960,12 @@ IedServer_observeDataAttribute(IedServer self, DataAttribute* dataAttribute, * \param the data attribute that has been written by an MMS client. * \param the value the client want to write to the data attribute * \param connection the connection object of the client connection that invoked the write operation + * \param parameter the user provided parameter * * \return true if access is accepted, false if access is denied. */ typedef MmsDataAccessError -(*WriteAccessHandler) (DataAttribute* dataAttribute, MmsValue* value, ClientConnection connection); +(*WriteAccessHandler) (DataAttribute* dataAttribute, MmsValue* value, ClientConnection connection, void* parameter); /** * \brief Install a WriteAccessHandler for a data attribute. @@ -979,10 +980,11 @@ typedef MmsDataAccessError * \param dataAttribute the data attribute to monitor * \param handler the callback function that is invoked if a client tries to write to * the monitored data attribute. + * \param parameter a user provided parameter that is passed to the WriteAccessHandler when called. */ void IedServer_handleWriteAccess(IedServer self, DataAttribute* dataAttribute, - WriteAccessHandler handler); + WriteAccessHandler handler, void* parameter); typedef enum { ACCESS_POLICY_ALLOW, diff --git a/src/iec61850/inc_private/mms_mapping.h b/src/iec61850/inc_private/mms_mapping.h index 527a72c9..11e7a778 100644 --- a/src/iec61850/inc_private/mms_mapping.h +++ b/src/iec61850/inc_private/mms_mapping.h @@ -139,7 +139,7 @@ void MmsMapping_setConnectionIndicationHandler(MmsMapping* self, IedConnectionIndicationHandler handler, void* parameter); void -MmsMapping_installWriteAccessHandler(MmsMapping* self, DataAttribute* dataAttribute, WriteAccessHandler handler); +MmsMapping_installWriteAccessHandler(MmsMapping* self, DataAttribute* dataAttribute, WriteAccessHandler handler, void* parameter); MmsDataAccessError Control_writeAccessControlObject(MmsMapping* self, MmsDomain* domain, char* variableIdOrig, diff --git a/src/iec61850/server/impl/ied_server.c b/src/iec61850/server/impl/ied_server.c index d630087f..d7622e37 100644 --- a/src/iec61850/server/impl/ied_server.c +++ b/src/iec61850/server/impl/ied_server.c @@ -476,7 +476,7 @@ singleThreadedServerThread(void* parameter) while (running) { - if (IedServer_waitReady(self, 100) > 0) { + if (IedServer_waitReady(self, 25) > 0) { MmsServer_handleIncomingMessages(self->mmsServer); IedServer_performPeriodicTasks(self); } @@ -770,26 +770,26 @@ checkForChangedTriggers(IedServer self, DataAttribute* dataAttribute) #if (CONFIG_IEC61850_REPORT_SERVICE == 1) || (CONFIG_INCLUDE_GOOSE_SUPPORT == 1) if (dataAttribute->triggerOptions & TRG_OPT_DATA_CHANGED) { +#if (CONFIG_INCLUDE_GOOSE_SUPPORT == 1) + MmsMapping_triggerGooseObservers(self->mmsMapping, dataAttribute->mmsValue); +#endif + #if (CONFIG_IEC61850_REPORT_SERVICE == 1) MmsMapping_triggerReportObservers(self->mmsMapping, dataAttribute->mmsValue, REPORT_CONTROL_VALUE_CHANGED); #endif + } + + else if (dataAttribute->triggerOptions & TRG_OPT_QUALITY_CHANGED) { #if (CONFIG_INCLUDE_GOOSE_SUPPORT == 1) MmsMapping_triggerGooseObservers(self->mmsMapping, dataAttribute->mmsValue); #endif - } - - else if (dataAttribute->triggerOptions & TRG_OPT_QUALITY_CHANGED) { #if (CONFIG_IEC61850_REPORT_SERVICE == 1) MmsMapping_triggerReportObservers(self->mmsMapping, dataAttribute->mmsValue, REPORT_CONTROL_QUALITY_CHANGED); #endif - -#if (CONFIG_INCLUDE_GOOSE_SUPPORT == 1) - MmsMapping_triggerGooseObservers(self->mmsMapping, dataAttribute->mmsValue); -#endif } #endif /* (CONFIG_IEC61850_REPORT_SERVICE== 1) || (CONFIG_INCLUDE_GOOSE_SUPPORT == 1) */ @@ -916,9 +916,16 @@ IedServer_updateBooleanAttributeValue(IedServer self, DataAttribute* dataAttribu bool currentValue = MmsValue_getBoolean(dataAttribute->mmsValue); if (currentValue == value) { + checkForUpdateTrigger(self, dataAttribute); } else { +// struct timeval tv; +// +// gettimeofday(&tv,NULL/*&tz*/); +// printf("UPDATE BOOL: %ld %ld\n",tv.tv_sec, tv.tv_usec); + + MmsValue_setBoolean(dataAttribute->mmsValue, value); checkForChangedTriggers(self, dataAttribute); @@ -993,15 +1000,15 @@ IedServer_updateQuality(IedServer self, DataAttribute* dataAttribute, Quality qu if (oldQuality != (uint32_t) quality) { MmsValue_setBitStringFromInteger(dataAttribute->mmsValue, (uint32_t) quality); +#if (CONFIG_INCLUDE_GOOSE_SUPPORT == 1) + MmsMapping_triggerGooseObservers(self->mmsMapping, dataAttribute->mmsValue); +#endif + #if (CONFIG_IEC61850_REPORT_SERVICE == 1) if (dataAttribute->triggerOptions & TRG_OPT_QUALITY_CHANGED) MmsMapping_triggerReportObservers(self->mmsMapping, dataAttribute->mmsValue, REPORT_CONTROL_QUALITY_CHANGED); #endif - -#if (CONFIG_INCLUDE_GOOSE_SUPPORT == 1) - MmsMapping_triggerGooseObservers(self->mmsMapping, dataAttribute->mmsValue); -#endif } @@ -1079,12 +1086,12 @@ IedServer_setWriteAccessPolicy(IedServer self, FunctionalConstraint fc, AccessPo } void -IedServer_handleWriteAccess(IedServer self, DataAttribute* dataAttribute, WriteAccessHandler handler) +IedServer_handleWriteAccess(IedServer self, DataAttribute* dataAttribute, WriteAccessHandler handler, void* parameter) { if (dataAttribute == NULL) *((int*) NULL) = 1; - MmsMapping_installWriteAccessHandler(self->mmsMapping, dataAttribute, handler); + MmsMapping_installWriteAccessHandler(self->mmsMapping, dataAttribute, handler, parameter); } void diff --git a/src/iec61850/server/mms_mapping/mms_goose.c b/src/iec61850/server/mms_mapping/mms_goose.c index e4c0678c..8b9d723f 100644 --- a/src/iec61850/server/mms_mapping/mms_goose.c +++ b/src/iec61850/server/mms_mapping/mms_goose.c @@ -169,7 +169,6 @@ MmsGooseControlBlock_enable(MmsGooseControlBlock self) if (!MmsGooseControlBlock_isEnabled(self)) { - if (self->dataSetRef != NULL) { GLOBAL_FREEMEM(self->dataSetRef); diff --git a/src/iec61850/server/mms_mapping/mms_mapping.c b/src/iec61850/server/mms_mapping/mms_mapping.c index c3fcc93c..7d14eabf 100644 --- a/src/iec61850/server/mms_mapping/mms_mapping.c +++ b/src/iec61850/server/mms_mapping/mms_mapping.c @@ -50,6 +50,7 @@ typedef struct { DataAttribute* attribute; WriteAccessHandler handler; + void* parameter; } AttributeAccessHandler; @@ -1759,6 +1760,8 @@ mmsWriteHandler(void* parameter, MmsDomain* domain, sg->editSgConfirmedHandler(sg->editSgConfirmedHandlerParameter, sg->sgcb, sg->sgcb->editSG); + unselectSettingGroup(sg); + return DATA_ACCESS_ERROR_SUCCESS; } else @@ -1826,7 +1829,8 @@ mmsWriteHandler(void* parameter, MmsDomain* domain, if (matchingValue != NULL) { MmsDataAccessError handlerResult = - accessHandler->handler(dataAttribute, matchingValue, (ClientConnection) connection); + accessHandler->handler(dataAttribute, matchingValue, (ClientConnection) connection, + accessHandler->parameter); if (handlerResult == DATA_ACCESS_ERROR_SUCCESS) handlerFound = true; @@ -1838,8 +1842,8 @@ mmsWriteHandler(void* parameter, MmsDomain* domain, else { /* if ACCESS_POLICY_DENY only allow direct access to handled data attribute */ if (dataAttribute->mmsValue == cachedValue) { MmsDataAccessError handlerResult = - accessHandler->handler(dataAttribute, value, (ClientConnection) connection); - + accessHandler->handler(dataAttribute, value, (ClientConnection) connection, + accessHandler->parameter); if (handlerResult == DATA_ACCESS_ERROR_SUCCESS) { handlerFound = true; @@ -1923,7 +1927,7 @@ getAccessHandlerForAttribute(MmsMapping* self, DataAttribute* dataAttribute) } void -MmsMapping_installWriteAccessHandler(MmsMapping* self, DataAttribute* dataAttribute, WriteAccessHandler handler) +MmsMapping_installWriteAccessHandler(MmsMapping* self, DataAttribute* dataAttribute, WriteAccessHandler handler, void* parameter) { AttributeAccessHandler* accessHandler = getAccessHandlerForAttribute(self, dataAttribute); @@ -1931,6 +1935,7 @@ MmsMapping_installWriteAccessHandler(MmsMapping* self, DataAttribute* dataAttrib accessHandler = (AttributeAccessHandler*) GLOBAL_MALLOC(sizeof(AttributeAccessHandler)); accessHandler->attribute = dataAttribute; + accessHandler->parameter = parameter; LinkedList_add(self->attributeAccessHandlers, (void*) accessHandler); } diff --git a/src/iec61850/server/model/model.c b/src/iec61850/server/model/model.c index ad1bd598..a6513c73 100644 --- a/src/iec61850/server/model/model.c +++ b/src/iec61850/server/model/model.c @@ -345,6 +345,46 @@ LogicalNode_hasFCData(LogicalNode* node, FunctionalConstraint fc) return false; } +DataSet* +LogicalNode_getDataSet(LogicalNode* self, const char* dataSetName) +{ + assert(self->modelType == LogicalNodeModelType); + assert(dataSetName != NULL); + + char dsName[66]; + + LogicalDevice* ld = (LogicalDevice*) self->parent; + + if (strlen(dataSetName) > 32) { + + if (DEBUG_IED_SERVER) { + printf("IED_SERVER: LogicalNode_getDataSet - data set name %s too long!\n", dataSetName); + } + + goto exit_error; + } + + StringUtils_createStringInBuffer(dsName, 3, self->name, "$", dataSetName); + + IedModel* iedModel = (IedModel*) ld->parent; + + DataSet* ds = iedModel->dataSets; + + while (ds != NULL) { + if (strcmp(ds->logicalDeviceName, ld->name) == 0) { + if (strcmp(ds->name, dsName) == 0) { + return ds; + } + } + + ds = ds->sibling; + } + + +exit_error: + return NULL; +} + int LogicalDevice_getLogicalNodeCount(LogicalDevice* logicalDevice) { diff --git a/src/mms/iso_mms/server/mms_access_result.c b/src/mms/iso_mms/server/mms_access_result.c index 3b4f033c..59d52ab6 100644 --- a/src/mms/iso_mms/server/mms_access_result.c +++ b/src/mms/iso_mms/server/mms_access_result.c @@ -103,12 +103,19 @@ encodeStructuredAccessResult(MmsValue* value, uint8_t* buffer, int bufPos, bool int mmsServer_encodeAccessResult(MmsValue* value, uint8_t* buffer, int bufPos, bool encode) { - if (value == NULL) // TODO report internal error - return 0; +// if (value == NULL) // TODO report internal error +// return 0; int size; switch (value->type) { + case MMS_BOOLEAN: + if (encode) + bufPos = BerEncoder_encodeBoolean(0x83, value->value.boolean, buffer, bufPos); + else + size = 3; + break; + case MMS_STRUCTURE: if (encode) bufPos = encodeStructuredAccessResult(value, buffer, bufPos, true); @@ -166,12 +173,7 @@ mmsServer_encodeAccessResult(MmsValue* value, uint8_t* buffer, int bufPos, bool else size = BerEncoder_determineEncodedBitStringSize(value->value.bitString.size); break; - case MMS_BOOLEAN: - if (encode) - bufPos = BerEncoder_encodeBoolean(0x83, value->value.boolean, buffer, bufPos); - else - size = 3; - break; + case MMS_BINARY_TIME: if (encode) bufPos = BerEncoder_encodeOctetString(0x8c, value->value.binaryTime.buf, diff --git a/tools/model_generator/genmodel.jar b/tools/model_generator/genmodel.jar index f0c858a9a7ceec6bf3138f8655f41317876dd160..21472b0a386fd369defe16bc120a8e647299e0cd 100644 GIT binary patch delta 1278 zcmYjPT}V@57~bprnNzpfHm7HEKW_7)BdA1>iDZRAX={c*)wGEwkqLRzZX^)82ojY% z!ABI4Na#RG{Q@&Hm68YvDHFV~>?Rl(Yldj_qn-19pX6@7XV3fmeCIu9c0PV~K0eJ~ zu8udUG#ZVnYb5M3(K&vd3YK0(Oaey+qAhaSQ#R4uGwExIMeN}lro>MDc5)>erh#8=# zugc%XDKzcz6(r$&W0TEkta>g1nP-86D2WAZ@kqo1qU3K&p=AyC(JZBOdZms~BGok& zv$Trl1tuK{D-$h=W`cp%xA4S@W|8{a7EwZ8=mFiNKMSl<>-BHg(c|;dj!-pA(JkYh z^fa|SH=vPlh#@=vEH;suJ9L?Vxp$S((I>7%)0X-LbV)UcS#c3QOb zfdSp}5VKFM{9zBHln=V(@~tl+HfsAi%*4(}H&)QmXeoQNjm;HyLHXU#pT7rDC-rZa zV5KwSB?b@JY3|M?3?G-jtINz#wB#i-ZqSic4|-lw?w5lqm(Y8v#E>GHirmWY&yu6hXcT>JW6BpdLZg1Q!vUF+%{su$kw4H$yEl zCo{NfFa!L^+z`M@GAytk{~fn*Yu_%|vA|gzRb|2j1f!X79zj|bXIiqL0hxDMJU&kV zA2M=$8G<>1yIfWt7_#!Nk5)b^u)#SLciNx{!MY795tL;^5Wzq;7pv{OqRI}{I2y8Z zdy<2LMh71~cR&qlj84v6b#mslljoRSd`Z__T=T}oyWBZ^$2W6$^5-1Bzd|?Hbh+U) YR(x`Eafye&kcS@LwdLWXS}(Nx1EhBx1^@s6 delta 1278 zcmYjPT}V@57~bp8oSU1oZT_6i{kYAGCa6S^iDbos(rku5)igzu$b`Jf8w-RkfWhx)3rd^{(X+@wK(Wa3GO zRQjsyU7SqQzKVh*oNsKhIgM7&BqH<7zaJ%0za;^QsNW;{+BMYMcn{5@rrRxcbttK> zxtOJux6CnVFd$FVB$5ewTHneO%Ue9u*FKLD@*)+`O$M{TEVfEXp^Tro;;rEqI7DN+Q2(pr#LJj%bmVLaBZ}m+iD@ z;UfdO#SvzoSo*^rMlK(ANab5!I@qZF>nIc3S9`I7h9afx(Ka@h*af9`Lx27rMx8jg zU4oVNRX5SQz)Evt7ce|5eODKmp=iNPrktQ7D=tV5?@NLq=9N7%AJ(fOfZt45dZ~xd zPPX^J0Xdlz86-*uod&>9k&GIk7@0K#97d3DggOMhMyN*+F~WHSr%d2SFlypC-%U`9 z%<**Y8cqivGS>w#lk^POi~o*haO=Phh-JWO993n)IRv3hIEz4=#hKPDXhi0H7LU&p zpaK~w-iu&H;4X)m2X>fw*C#U{6 Date: Mon, 20 Jul 2015 16:39:28 +0200 Subject: [PATCH 03/14] - added function LogicalDevice_getChildByMmsVariableName --- src/iec61850/inc/iec61850_model.h | 3 ++ src/iec61850/server/model/model.c | 50 +++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/src/iec61850/inc/iec61850_model.h b/src/iec61850/inc/iec61850_model.h index 338c5038..665a2491 100644 --- a/src/iec61850/inc/iec61850_model.h +++ b/src/iec61850/inc/iec61850_model.h @@ -407,6 +407,9 @@ IedModel_getLogicalDeviceCount(IedModel* iedModel); int LogicalDevice_getLogicalNodeCount(LogicalDevice* logicalDevice); +ModelNode* +LogicalDevice_getChildByMmsVariableName(LogicalDevice* logicalDevice, const char* mmsVariableName); + bool LogicalNode_hasFCData(LogicalNode* node, FunctionalConstraint fc); diff --git a/src/iec61850/server/model/model.c b/src/iec61850/server/model/model.c index a6513c73..3f7d195d 100644 --- a/src/iec61850/server/model/model.c +++ b/src/iec61850/server/model/model.c @@ -143,6 +143,8 @@ IedModel_getDevice(IedModel* model, const char* deviceName) if (strcmp(domainName, deviceName) == 0) return device; + printf("domainename: %s\n", domainName); + device = (LogicalDevice*) device->sibling; } @@ -400,6 +402,54 @@ LogicalDevice_getLogicalNodeCount(LogicalDevice* logicalDevice) return lnCount; } +ModelNode* +LogicalDevice_getChildByMmsVariableName(LogicalDevice* logicalDevice, const char* mmsVariableName) +{ + + + char fcString[3]; + char nameRef[65]; + + char* separator = strchr(mmsVariableName,'$'); + + if (separator == NULL) + return NULL; + + if (strlen(separator) > 4) { + fcString[0] = separator[1]; + fcString[1] = separator[2]; + fcString[2] = 0; + + char* strpos = mmsVariableName; + + int targetPos = 0; + + while (strpos < separator) { + nameRef[targetPos++] = strpos[0]; + strpos++; + } + + nameRef[targetPos++] = '.'; + + strpos = separator + 4; + + while (strpos[0] != 0) { + nameRef[targetPos++] = strpos[0]; + strpos++; + } + + nameRef[targetPos++] = 0; + + StringUtils_replace(nameRef, '$', '.'); + + FunctionalConstraint fc = FunctionalConstraint_fromString(fcString); + + return ModelNode_getChildWithFc((ModelNode*) logicalDevice, nameRef, fc); + } + + return NULL; +} + static int createObjectReference(ModelNode* node, char* objectReference) { From f024528d85ef5f2ebed048143916ca3bedc40f90 Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Mon, 10 Aug 2015 09:52:45 +0200 Subject: [PATCH 04/14] - enabled VLAN tag in goose publisher --- src/goose/goose_publisher.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/goose/goose_publisher.c b/src/goose/goose_publisher.c index cea381c4..47b85995 100644 --- a/src/goose/goose_publisher.c +++ b/src/goose/goose_publisher.c @@ -201,7 +201,7 @@ prepareGooseBuffer(GoosePublisher self, CommParameters* parameters, const char* int bufPos = 12; -#if 0 +#if 1 /* Priority tag - IEEE 802.1Q */ self->buffer[bufPos++] = 0x81; self->buffer[bufPos++] = 0x00; From 2e24ecb4eb4571f607fe229cbd99be69bdc4e391 Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Thu, 13 Aug 2015 08:08:31 +0200 Subject: [PATCH 05/14] - changed TimeOfEntry to TimeofEntry for Buffered reporting to deal with "bug" in 8-1 specification - deal with SE/SG in SCL file -> SE will automatically create SG attribute in data model - added wildcard "*" support to file service - fixed problem with filesystem file modification date on embedded linux syste, --- src/goose/goose_publisher.c | 2 +- .../filesystem/linux/file_provider_linux.c | 4 ++-- src/iec61850/client/client_report_control.c | 2 +- src/iec61850/server/mms_mapping/reporting.c | 4 ++-- src/mms/iso_mms/server/mms_file_service.c | 7 +++++++ tools/model_generator/genconfig.jar | Bin 75191 -> 75407 bytes tools/model_generator/genmodel.jar | Bin 75201 -> 75424 bytes .../libiec61850/scl/model/DataAttribute.java | 3 +++ .../com/libiec61850/scl/model/DataObject.java | 9 +++++++++ 9 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/goose/goose_publisher.c b/src/goose/goose_publisher.c index 47b85995..cea381c4 100644 --- a/src/goose/goose_publisher.c +++ b/src/goose/goose_publisher.c @@ -201,7 +201,7 @@ prepareGooseBuffer(GoosePublisher self, CommParameters* parameters, const char* int bufPos = 12; -#if 1 +#if 0 /* Priority tag - IEEE 802.1Q */ self->buffer[bufPos++] = 0x81; self->buffer[bufPos++] = 0x00; diff --git a/src/hal/filesystem/linux/file_provider_linux.c b/src/hal/filesystem/linux/file_provider_linux.c index f95cff5c..1f0e2885 100644 --- a/src/hal/filesystem/linux/file_provider_linux.c +++ b/src/hal/filesystem/linux/file_provider_linux.c @@ -131,8 +131,8 @@ FileSystem_getFileInfo(char* filename, uint32_t* fileSize, uint64_t* lastModific return false; if (lastModificationTimestamp != NULL) - *lastModificationTimestamp = fileStats.st_mtime * 1000; - // does not work on older systems --> *lastModificationTimestamp = fileStats.st_ctim.tv_sec * 1000; + *lastModificationTimestamp = (uint64_t) (fileStats.st_mtime) * 1000LL; + // does not work on older systems --> *lastModificationTimestamp = (uint64_t) (fileStats.st_ctim.tv_sec) * 1000LL; if (fileSize != NULL) *fileSize = fileStats.st_size; diff --git a/src/iec61850/client/client_report_control.c b/src/iec61850/client/client_report_control.c index 9ed5f615..933a9378 100644 --- a/src/iec61850/client/client_report_control.c +++ b/src/iec61850/client/client_report_control.c @@ -611,7 +611,7 @@ IedConnection_setRCBValues(IedConnection self, IedClientError* error, ClientRepo if (!isBuffered) goto error_invalid_parameter; - strcpy(itemId + itemIdLen, "$TimeOfEntry"); + strcpy(itemId + itemIdLen, "$TimeofEntry"); LinkedList_add(itemIds, copyString(itemId)); LinkedList_add(values, rcb->timeOfEntry); diff --git a/src/iec61850/server/mms_mapping/reporting.c b/src/iec61850/server/mms_mapping/reporting.c index 8763d9b3..9184a690 100644 --- a/src/iec61850/server/mms_mapping/reporting.c +++ b/src/iec61850/server/mms_mapping/reporting.c @@ -214,7 +214,7 @@ ReportControl_getRCBValue(ReportControl* rc, char* elementName) return MmsValue_getElement(rc->rcbValues, 10); else if (strcmp(elementName, "EntryID") == 0) return MmsValue_getElement(rc->rcbValues, 11); - else if (strcmp(elementName, "TimeOfEntry") == 0) + else if (strcmp(elementName, "TimeofEntry") == 0) return MmsValue_getElement(rc->rcbValues, 12); else if (strcmp(elementName, "ResvTms") == 0) return MmsValue_getElement(rc->rcbValues, 13); @@ -949,7 +949,7 @@ createBufferedReportControlBlock(ReportControlBlock* reportControlBlock, mmsValue->value.structure.components[11] = MmsValue_newOctetString(8, 8); namedVariable = (MmsVariableSpecification*) GLOBAL_CALLOC(1, sizeof(MmsVariableSpecification)); - namedVariable->name = copyString("TimeOfEntry"); + namedVariable->name = copyString("TimeofEntry"); namedVariable->type = MMS_BINARY_TIME; namedVariable->typeSpec.binaryTime = 6; rcb->typeSpec.structure.elements[12] = namedVariable; diff --git a/src/mms/iso_mms/server/mms_file_service.c b/src/mms/iso_mms/server/mms_file_service.c index 03618b45..4ee6f93f 100644 --- a/src/mms/iso_mms/server/mms_file_service.c +++ b/src/mms/iso_mms/server/mms_file_service.c @@ -532,6 +532,9 @@ createFileDirectoryResponse(uint32_t invokeId, ByteBuffer* response, char* direc FileSystem_closeDirectory(directory); } else { + + //TODO check if it is a directory + if (DEBUG_MMS_SERVER) printf("Error opening directory!\n"); @@ -678,6 +681,10 @@ mmsServer_handleFileDirectoryRequest( case 0xa0: /* filename */ if (!parseFileName(filename, buffer, &bufPos, bufPos + length, invokeId, response)) return; + + /* check for wildcard character(*) */ + if (strcmp(filename, "*") == 0) filename[0] = 0; + break; case 0xa1: /* continue-after */ diff --git a/tools/model_generator/genconfig.jar b/tools/model_generator/genconfig.jar index 1c00bf010e1a00dddd8de1820578456497f71d48..26d4d57eb2eecc5d7ced63873c375494a7c06dbf 100644 GIT binary patch delta 8086 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 diff --git a/tools/model_generator/genmodel.jar b/tools/model_generator/genmodel.jar index 21472b0a386fd369defe16bc120a8e647299e0cd..7f8cf31b55630da79c51dc7e30914d84db260671 100644 GIT binary patch delta 5616 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 HVIcnlFGhNW diff --git a/tools/model_generator/src/com/libiec61850/scl/model/DataAttribute.java b/tools/model_generator/src/com/libiec61850/scl/model/DataAttribute.java index 573183f2..44193d78 100644 --- a/tools/model_generator/src/com/libiec61850/scl/model/DataAttribute.java +++ b/tools/model_generator/src/com/libiec61850/scl/model/DataAttribute.java @@ -62,6 +62,9 @@ public class DataAttribute implements DataModelNode { if (this.fc == null) this.fc = fc; + if (fc != null) + this.fc = fc; + if ((parent != null) && (parent instanceof DataAttribute)) this.triggerOptions = ((DataAttribute) parent).getTriggerOptions(); else diff --git a/tools/model_generator/src/com/libiec61850/scl/model/DataObject.java b/tools/model_generator/src/com/libiec61850/scl/model/DataObject.java index 13a373e0..7a861767 100644 --- a/tools/model_generator/src/com/libiec61850/scl/model/DataObject.java +++ b/tools/model_generator/src/com/libiec61850/scl/model/DataObject.java @@ -81,7 +81,16 @@ public class DataObject implements DataModelNode { daDefinitions = ((DataAttributeType) sclType).getSubDataAttributes(); for (DataAttributeDefinition daDefinition : daDefinitions) { + + if (daDefinition.getFc() == FunctionalConstraint.SE) { + + System.out.println("Add SG DA for corresponding SE DA: "); + this.dataAttributes.add(new DataAttribute(daDefinition, typeDeclarations, FunctionalConstraint.SG, this)); + } + this.dataAttributes.add(new DataAttribute(daDefinition, typeDeclarations, null, this)); + + } } From 3969e0725697ca47a34fbea6dbdc3595659fa1c8 Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Fri, 14 Aug 2015 17:28:44 +0200 Subject: [PATCH 06/14] - fixed problem with trailing characters in dataRef in buffered reports - TimeOfEntry is stored for each buffered report entry in report buffer --- src/iec61850/inc_private/reporting.h | 1 + src/iec61850/server/mms_mapping/reporting.c | 39 +++++++++++++-------- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/src/iec61850/inc_private/reporting.h b/src/iec61850/inc_private/reporting.h index 1f4b1bc2..739bdf22 100644 --- a/src/iec61850/inc_private/reporting.h +++ b/src/iec61850/inc_private/reporting.h @@ -29,6 +29,7 @@ typedef struct sReportBufferEntry ReportBufferEntry; struct sReportBufferEntry { uint8_t entryId[8]; uint8_t flags; /* bit 0 (1 = isIntegrityReport), bit 1 (1 = isGiReport) */ + uint64_t timeOfEntry; int entryLength; ReportBufferEntry* next; }; diff --git a/src/iec61850/server/mms_mapping/reporting.c b/src/iec61850/server/mms_mapping/reporting.c index 9184a690..b3513b0f 100644 --- a/src/iec61850/server/mms_mapping/reporting.c +++ b/src/iec61850/server/mms_mapping/reporting.c @@ -1420,7 +1420,6 @@ Reporting_RCBWriteAccessHandler(MmsMapping* self, ReportControl* rc, char* eleme if (rcbValue != NULL) MmsValue_update(rcbValue, value); else { - printf("AAAAAA\n"); retVal = DATA_ACCESS_ERROR_OBJECT_VALUE_INVALID; goto exit_function; } @@ -1520,7 +1519,7 @@ printReportId(ReportBufferEntry* report) #endif static void -enqueueReport(ReportControl* reportControl, bool isIntegrity, bool isGI) +enqueueReport(ReportControl* reportControl, bool isIntegrity, bool isGI, uint64_t timeOfEntry) { if (DEBUG_IED_SERVER) printf("IED_SERVER: enqueueReport: RCB name: %s (SQN:%u) enabled:%i buffered:%i buffering:%i intg:%i GI:%i\n", reportControl->name, (unsigned) reportControl->sqNum, reportControl->enabled, @@ -1746,15 +1745,17 @@ enqueueReport(ReportControl* reportControl, bool isIntegrity, bool isGI) ReportBufferEntry* entry = (ReportBufferEntry*) entryBufPos; /* ENTRY_ID is set to system time in ms! */ - uint64_t timestamp = Hal_getTimeInMs(); + uint64_t entryId = timeOfEntry; - if (timestamp <= reportControl->lastEntryId) - timestamp = reportControl->lastEntryId + 1; + if (entryId <= reportControl->lastEntryId) + entryId = reportControl->lastEntryId + 1; + + entry->timeOfEntry = entryId; #if (ORDER_LITTLE_ENDIAN == 1) - memcpyReverseByteOrder(entry->entryId, (uint8_t*) ×tamp, 8); + memcpyReverseByteOrder(entry->entryId, (uint8_t*) &entryId, 8); #else - memcpy (entry->entryId, (uint8_t*) ×tamp, 8); + memcpy (entry->entryId, (uint8_t*) &entryId, 8); #endif #if (DEBUG_IED_SERVER == 1) @@ -1844,7 +1845,7 @@ enqueueReport(ReportControl* reportControl, bool isIntegrity, bool isGI) if (buffer->oldestReport == NULL) buffer->oldestReport = buffer->lastEnqueuedReport; - reportControl->lastEntryId = timestamp; + reportControl->lastEntryId = entryId; } static void @@ -1924,7 +1925,15 @@ sendNextReportEntry(ReportControl* self) goto return_out_of_memory; if (MmsValue_getBitStringBit(optFlds, 2)) { /* report time stamp */ - if (MemAllocLinkedList_add(reportElements, self->timeOfEntry) == NULL) + MmsValue* timeOfEntry = (MmsValue*) MemoryAllocator_allocate(&ma, sizeof(MmsValue)); + + if (timeOfEntry == NULL) goto return_out_of_memory; + + timeOfEntry->deleteValue = 0; + timeOfEntry->type = MMS_UTC_TIME; + MmsValue_setUtcTimeMs(timeOfEntry, report->timeOfEntry); + + if (MemAllocLinkedList_add(reportElements, timeOfEntry) == NULL) goto return_out_of_memory; } @@ -2010,7 +2019,7 @@ sendNextReportEntry(ReportControl* self) + ldNameLength + variableNameLength + 1; - char* dataReference = (char*) MemoryAllocator_allocate(&ma, refLen); + char* dataReference = (char*) MemoryAllocator_allocate(&ma, refLen + 1); if (dataReference == NULL) goto return_out_of_memory; @@ -2214,7 +2223,7 @@ processEventsForReport(ReportControl* rc, uint64_t currentTimeInMs) /* send current events in event buffer before GI report */ if (rc->triggered) { if (rc->buffered) - enqueueReport(rc, false, false); + enqueueReport(rc, false, false, currentTimeInMs); else sendReport(rc, false, false); @@ -2224,7 +2233,7 @@ processEventsForReport(ReportControl* rc, uint64_t currentTimeInMs) updateTimeOfEntry(rc, currentTimeInMs); if (rc->buffered) - enqueueReport(rc, false, true); + enqueueReport(rc, false, true, currentTimeInMs); else sendReport(rc, false, true); @@ -2242,7 +2251,7 @@ processEventsForReport(ReportControl* rc, uint64_t currentTimeInMs) /* send current events in event buffer before integrity report */ if (rc->triggered) { if (rc->buffered) - enqueueReport(rc, false, false); + enqueueReport(rc, false, false, currentTimeInMs); else sendReport(rc, false, false); @@ -2253,7 +2262,7 @@ processEventsForReport(ReportControl* rc, uint64_t currentTimeInMs) updateTimeOfEntry(rc, currentTimeInMs); if (rc->buffered) - enqueueReport(rc, true, false); + enqueueReport(rc, true, false, currentTimeInMs); else sendReport(rc, true, false); @@ -2266,7 +2275,7 @@ processEventsForReport(ReportControl* rc, uint64_t currentTimeInMs) if (currentTimeInMs >= rc->reportTime) { if (rc->buffered) - enqueueReport(rc, false, false); + enqueueReport(rc, false, false, currentTimeInMs); else sendReport(rc, false, false); From eb31da81a8c7e3be3244aebda1466d77bab74075 Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Fri, 25 Sep 2015 07:53:34 -0300 Subject: [PATCH 07/14] - added ControlObjectClient_setOrigin to VS def files --- src/vs/libiec61850-wo-goose.def | 1 + src/vs/libiec61850.def | 1 + 2 files changed, 2 insertions(+) diff --git a/src/vs/libiec61850-wo-goose.def b/src/vs/libiec61850-wo-goose.def index 8f305081..52b7ad6a 100644 --- a/src/vs/libiec61850-wo-goose.def +++ b/src/vs/libiec61850-wo-goose.def @@ -490,3 +490,4 @@ EXPORTS ClientReport_getBufOvfl MmsValue_getUtcTimeInMsWithUs IedModel_setIedNameForDynamicModel + ControlObjectClient_setOrigin diff --git a/src/vs/libiec61850.def b/src/vs/libiec61850.def index fa29b647..d0189d88 100644 --- a/src/vs/libiec61850.def +++ b/src/vs/libiec61850.def @@ -514,3 +514,4 @@ EXPORTS ClientReport_getBufOvfl MmsValue_getUtcTimeInMsWithUs IedModel_setIedNameForDynamicModel + ControlObjectClient_setOrigin From 0bc0fd94ed3a29df648fff6d87de9341bbd9b892 Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Fri, 9 Oct 2015 15:22:47 +0200 Subject: [PATCH 08/14] - fixed bug in get name list service when client sends wrong domain name --- src/mms/iso_mms/server/mms_get_namelist_service.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/mms/iso_mms/server/mms_get_namelist_service.c b/src/mms/iso_mms/server/mms_get_namelist_service.c index fcd3b663..0bb0af18 100644 --- a/src/mms/iso_mms/server/mms_get_namelist_service.c +++ b/src/mms/iso_mms/server/mms_get_namelist_service.c @@ -436,9 +436,12 @@ mmsServer_handleGetNameListRequest( else if (objectClass == OBJECT_CLASS_NAMED_VARIABLE_LIST) { LinkedList nameList = getNamedVariableListsDomainSpecific(connection, domainSpecificName); - createNameListResponse(connection, invokeId, nameList, response, continueAfter); - - LinkedList_destroy(nameList); + if (nameList == NULL) + mmsServer_createConfirmedErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_NON_EXISTENT); + else { + createNameListResponse(connection, invokeId, nameList, response, continueAfter); + LinkedList_destroy(nameList); + } } #endif /* (MMS_DATA_SET_SERVICE == 1) */ @@ -447,7 +450,6 @@ mmsServer_handleGetNameListRequest( mmsServer_createConfirmedErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_ACCESS_UNSUPPORTED); } - } else if (objectScope == OBJECT_SCOPE_VMD) { /* vmd-specific */ From 120a36c9e3c73107b844a76a8fc182df7b7f11d9 Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Mon, 12 Oct 2015 12:29:57 +0200 Subject: [PATCH 09/14] - added missing functions to .def files --- src/vs/libiec61850-wo-goose.def | 3 ++- src/vs/libiec61850.def | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/vs/libiec61850-wo-goose.def b/src/vs/libiec61850-wo-goose.def index 09c2cdab..54cabdeb 100644 --- a/src/vs/libiec61850-wo-goose.def +++ b/src/vs/libiec61850-wo-goose.def @@ -492,4 +492,5 @@ EXPORTS IedModel_setIedNameForDynamicModel ControlObjectClient_useConstantT ControlObjectClient_setOrigin - + LogicalDevice_getChildByMmsVariableName + LogicalNode_getDataset diff --git a/src/vs/libiec61850.def b/src/vs/libiec61850.def index 9682ddad..73d532e7 100644 --- a/src/vs/libiec61850.def +++ b/src/vs/libiec61850.def @@ -516,3 +516,5 @@ EXPORTS IedModel_setIedNameForDynamicModel ControlObjectClient_useConstantT ControlObjectClient_setOrigin + LogicalDevice_getChildByMmsVariableName + LogicalNode_getDataset From b5fe0992fd4d44512f9c8b4ff77aee9e5eeaa6e3 Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Mon, 12 Oct 2015 12:33:56 +0200 Subject: [PATCH 10/14] - removed debugging code --- src/iec61850/client/ied_connection.c | 16 ---------------- src/iec61850/server/impl/ied_server.c | 6 ------ src/iec61850/server/model/model.c | 2 -- 3 files changed, 24 deletions(-) diff --git a/src/iec61850/client/ied_connection.c b/src/iec61850/client/ied_connection.c index 77a912f6..f71a4451 100644 --- a/src/iec61850/client/ied_connection.c +++ b/src/iec61850/client/ied_connection.c @@ -604,37 +604,21 @@ IedConnection_close(IedConnection self) void IedConnection_destroy(IedConnection self) { - printf("D1\n"); - IedConnection_close(self); - printf("D2\n"); - MmsConnection_destroy(self->connection); - printf("D3\n"); - if (self->logicalDevices != NULL) LinkedList_destroyDeep(self->logicalDevices, (LinkedListValueDeleteFunction) ICLogicalDevice_destroy); - printf("D4\n"); - -#if 0 if (self->enabledReports != NULL) LinkedList_destroyDeep(self->enabledReports, (LinkedListValueDeleteFunction) ClientReport_destroy); -#endif LinkedList_destroyStatic(self->clientControls); - printf("D6\n"); - Semaphore_destroy(self->stateMutex); - printf("D7\n"); - GLOBAL_FREEMEM(self); - - printf("D8\n"); } MmsVariableSpecification* diff --git a/src/iec61850/server/impl/ied_server.c b/src/iec61850/server/impl/ied_server.c index d7622e37..5f418cf6 100644 --- a/src/iec61850/server/impl/ied_server.c +++ b/src/iec61850/server/impl/ied_server.c @@ -920,12 +920,6 @@ IedServer_updateBooleanAttributeValue(IedServer self, DataAttribute* dataAttribu checkForUpdateTrigger(self, dataAttribute); } else { -// struct timeval tv; -// -// gettimeofday(&tv,NULL/*&tz*/); -// printf("UPDATE BOOL: %ld %ld\n",tv.tv_sec, tv.tv_usec); - - MmsValue_setBoolean(dataAttribute->mmsValue, value); checkForChangedTriggers(self, dataAttribute); diff --git a/src/iec61850/server/model/model.c b/src/iec61850/server/model/model.c index 3f7d195d..d48888c6 100644 --- a/src/iec61850/server/model/model.c +++ b/src/iec61850/server/model/model.c @@ -143,8 +143,6 @@ IedModel_getDevice(IedModel* model, const char* deviceName) if (strcmp(domainName, deviceName) == 0) return device; - printf("domainename: %s\n", domainName); - device = (LogicalDevice*) device->sibling; } From 4a4963b9642a19721fd21ed1329b25185d99a206 Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Mon, 12 Oct 2015 12:41:42 +0200 Subject: [PATCH 11/14] - fixed server_example5 (new writeAccessHandler) --- examples/server_example5/server_example5.c | 4 ++-- src/iec61850/server/model/model.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/server_example5/server_example5.c b/examples/server_example5/server_example5.c index 21f5207a..1d6d90ee 100644 --- a/examples/server_example5/server_example5.c +++ b/examples/server_example5/server_example5.c @@ -22,7 +22,7 @@ void sigint_handler(int signalId) } static MmsDataAccessError -writeAccessHandler (DataAttribute* dataAttribute, MmsValue* value, ClientConnection connection) +writeAccessHandler (DataAttribute* dataAttribute, MmsValue* value, ClientConnection connection, void* parameter) { if (dataAttribute == IEDMODEL_Inverter_ZINV1_OutVarSet_setMag_f) { @@ -54,7 +54,7 @@ int main(int argc, char** argv) { /* Instruct the server that we will be informed if a clients writes to a * certain variables we are interested in. */ - IedServer_handleWriteAccess(iedServer, IEDMODEL_Inverter_ZINV1_OutVarSet_setMag_f, writeAccessHandler); + IedServer_handleWriteAccess(iedServer, IEDMODEL_Inverter_ZINV1_OutVarSet_setMag_f, writeAccessHandler, NULL); if (!IedServer_isRunning(iedServer)) { printf("Starting server failed! Exit.\n"); diff --git a/src/iec61850/server/model/model.c b/src/iec61850/server/model/model.c index d48888c6..6e752faa 100644 --- a/src/iec61850/server/model/model.c +++ b/src/iec61850/server/model/model.c @@ -418,7 +418,7 @@ LogicalDevice_getChildByMmsVariableName(LogicalDevice* logicalDevice, const char fcString[1] = separator[2]; fcString[2] = 0; - char* strpos = mmsVariableName; + const char* strpos = mmsVariableName; int targetPos = 0; From 758615a3f88d0bdfd45ff203917f428391c8d643 Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Mon, 12 Oct 2015 16:58:51 +0200 Subject: [PATCH 12/14] - extended beaglebone demo --- demos/beaglebone/beagle_demo.c | 90 +++- demos/beaglebone/beagle_demo.icd | 125 ++++- demos/beaglebone/beaglebone_leds.h | 3 + demos/beaglebone/static_model.c | 707 ++++++++++++++++++++++++----- demos/beaglebone/static_model.h | 112 ++++- 5 files changed, 896 insertions(+), 141 deletions(-) diff --git a/demos/beaglebone/beagle_demo.c b/demos/beaglebone/beagle_demo.c index 31cc3c6a..82c1ac05 100644 --- a/demos/beaglebone/beagle_demo.c +++ b/demos/beaglebone/beagle_demo.c @@ -77,27 +77,27 @@ static void updateLED1stVal(bool newLedState, uint64_t timeStamp) { switchLED(LED1, newLedState); + IedServer_updateUTCTimeAttributeValue(iedServer, IEDMODEL_GenericIO_GGIO1_SPCSO1_t, timeStamp); IedServer_updateBooleanAttributeValue(iedServer, IEDMODEL_GenericIO_GGIO1_SPCSO1_stVal, newLedState); IedServer_updateQuality(iedServer, IEDMODEL_GenericIO_GGIO1_SPCSO1_q, QUALITY_VALIDITY_GOOD | QUALITY_SOURCE_SUBSTITUTED); - IedServer_updateUTCTimeAttributeValue(iedServer, IEDMODEL_GenericIO_GGIO1_SPCSO1_t, timeStamp); } static void updateLED2stVal(bool newLedState, uint64_t timeStamp) { switchLED(LED2, newLedState); + IedServer_updateUTCTimeAttributeValue(iedServer, IEDMODEL_GenericIO_GGIO1_SPCSO2_t, timeStamp); IedServer_updateBooleanAttributeValue(iedServer, IEDMODEL_GenericIO_GGIO1_SPCSO2_stVal, newLedState); IedServer_updateQuality(iedServer, IEDMODEL_GenericIO_GGIO1_SPCSO2_q, QUALITY_VALIDITY_QUESTIONABLE | QUALITY_DETAIL_OSCILLATORY); - IedServer_updateUTCTimeAttributeValue(iedServer, IEDMODEL_GenericIO_GGIO1_SPCSO2_t, timeStamp); } static void updateLED3stVal(bool newLedState, uint64_t timeStamp) { switchLED(LED3, newLedState); + IedServer_updateUTCTimeAttributeValue(iedServer, IEDMODEL_GenericIO_GGIO1_SPCSO3_t, timeStamp); IedServer_updateBooleanAttributeValue(iedServer, IEDMODEL_GenericIO_GGIO1_SPCSO3_stVal, newLedState); IedServer_updateQuality(iedServer, IEDMODEL_GenericIO_GGIO1_SPCSO3_q, QUALITY_VALIDITY_GOOD); - IedServer_updateUTCTimeAttributeValue(iedServer, IEDMODEL_GenericIO_GGIO1_SPCSO3_t, timeStamp); } static ControlHandlerResult @@ -146,6 +146,62 @@ controlHandlerForBinaryOutput(void* parameter, MmsValue* value, bool test) return CONTROL_RESULT_OK; } +static int ledOnTimeMs = 1000; +static int ledOffTimeMs = 1000; +static int32_t opCnt = 0; + +static ControlHandlerResult +controlHandlerForInt32Controls(void* parameter, MmsValue* value, bool test) +{ + if (test) + return CONTROL_RESULT_OK; + + if (parameter == IEDMODEL_GenericIO_TIM_GAPC1_OpCntRs) { + int32_t newValue = MmsValue_toInt32(value); + + opCnt = newValue; + + uint64_t currentTime = Hal_getTimeInMs(); + + IedServer_updateUTCTimeAttributeValue(iedServer, IEDMODEL_GenericIO_TIM_GAPC1_OpCntRs_t, currentTime); + IedServer_updateInt32AttributeValue(iedServer, IEDMODEL_GenericIO_TIM_GAPC1_OpCntRs_stVal, opCnt); + } + + return CONTROL_RESULT_OK; +} + + + +static MmsDataAccessError +int32WriteAccessHandler (DataAttribute* dataAttribute, MmsValue* value, ClientConnection connection, void* parameter) +{ + int newValue = MmsValue_toInt32(value); + + /* Check if value is inside of valid range */ + if (newValue < 0) + return DATA_ACCESS_ERROR_OBJECT_VALUE_INVALID; + + if (dataAttribute == IEDMODEL_GenericIO_TIM_GAPC1_OpDlTmms_setVal) { + + printf("New value for TIM_GAPC1.OpDlTmms.setVal = %i\n", newValue); + + ledOffTimeMs = newValue; + + return DATA_ACCESS_ERROR_SUCCESS; + } + + if (dataAttribute == IEDMODEL_GenericIO_TIM_GAPC1_RsDlTmms_setVal) { + + printf("New value for TIM_GAPC1.RsDlTmms.setVal = %i\n", newValue); + + ledOnTimeMs = newValue; + + return DATA_ACCESS_ERROR_SUCCESS; + } + + return DATA_ACCESS_ERROR_OBJECT_ACCESS_DENIED; +} + int main(int argc, char** argv) { @@ -153,7 +209,7 @@ int main(int argc, char** argv) { iedServer = IedServer_create(&iedModel); - /* Set callback handlers */ + /* Set control callback handlers */ IedServer_setConnectionIndicationHandler(iedServer, (IedConnectionIndicationHandler) connectionIndicationHandler, NULL); IedServer_setPerformCheckHandler(iedServer, IEDMODEL_GenericIO_GGIO1_SPCSO1, @@ -181,11 +237,22 @@ int main(int argc, char** argv) { IEDMODEL_GenericIO_GGIO1_DPCSO1); - /* Initialize process values */ + IedServer_setControlHandler(iedServer, IEDMODEL_GenericIO_TIM_GAPC1_OpCntRs, (ControlHandler) controlHandlerForInt32Controls, + IEDMODEL_GenericIO_TIM_GAPC1_OpCntRs); + /* Initialize process values */ MmsValue* DPCSO1_stVal = IedServer_getAttributeValue(iedServer, IEDMODEL_GenericIO_GGIO1_DPCSO1_stVal); MmsValue_setBitStringFromInteger(DPCSO1_stVal, 1); /* set DPC to OFF */ + /* Intitalize setting values */ + IedServer_updateInt32AttributeValue(iedServer, IEDMODEL_GenericIO_TIM_GAPC1_OpDlTmms_setVal, ledOffTimeMs); + IedServer_updateInt32AttributeValue(iedServer, IEDMODEL_GenericIO_TIM_GAPC1_RsDlTmms_setVal, ledOnTimeMs); + + /* Set callback handler for settings */ + IedServer_handleWriteAccess(iedServer, IEDMODEL_GenericIO_TIM_GAPC1_OpDlTmms_setVal, int32WriteAccessHandler, NULL); + IedServer_handleWriteAccess(iedServer, IEDMODEL_GenericIO_TIM_GAPC1_RsDlTmms_setVal, int32WriteAccessHandler, NULL); + + /* MMS server will be instructed to start listening to client connections. */ IedServer_start(iedServer, 102); @@ -210,10 +277,21 @@ int main(int argc, char** argv) { if (automaticOperationMode) { if (nextLedToggleTime <= currentTime) { - nextLedToggleTime = currentTime + 1000; + + + if (ledStateValue) + nextLedToggleTime = currentTime + ledOffTimeMs; + else + nextLedToggleTime = currentTime + ledOnTimeMs; ledStateValue = !ledStateValue; + if (ledStateValue) { + opCnt++; + IedServer_updateUTCTimeAttributeValue(iedServer, IEDMODEL_GenericIO_TIM_GAPC1_OpCntRs_t, currentTime); + IedServer_updateInt32AttributeValue(iedServer, IEDMODEL_GenericIO_TIM_GAPC1_OpCntRs_stVal, opCnt); + } + updateLED1stVal(ledStateValue, currentTime); updateLED2stVal(ledStateValue, currentTime); updateLED3stVal(ledStateValue, currentTime); diff --git a/demos/beaglebone/beagle_demo.icd b/demos/beaglebone/beagle_demo.icd index 6169c814..259c21f5 100644 --- a/demos/beaglebone/beagle_demo.icd +++ b/demos/beaglebone/beagle_demo.icd @@ -72,6 +72,7 @@ + @@ -99,6 +100,9 @@ + + + @@ -106,20 +110,22 @@ - - - + + + + - + + - - - + + + @@ -134,17 +140,65 @@ - + + + + + + + + + + + + + + + + + + EXT:2015 + + + + + + + + + + - + + + direct-with-normal-security + - - - - + + + + + + + + + + + + + + + + + + + + status-only + + @@ -152,24 +206,29 @@ + + + + + @@ -177,11 +236,13 @@ + + @@ -189,6 +250,7 @@ + @@ -198,6 +260,7 @@ + @@ -205,13 +268,33 @@ + + + + + + + + + + + + + + + + + + + + @@ -228,6 +311,21 @@ + + + on + blocked + test + test/blocked + off + + + + unknown + forward + backward + both + status-only @@ -236,6 +334,7 @@ direct-with-enhanced-security sbo-with-enhanced-security + not-supported bay-control diff --git a/demos/beaglebone/beaglebone_leds.h b/demos/beaglebone/beaglebone_leds.h index 2bcfa0d9..61a396c7 100644 --- a/demos/beaglebone/beaglebone_leds.h +++ b/demos/beaglebone/beaglebone_leds.h @@ -9,6 +9,9 @@ /* set to 1 if you want to run the demo on a PC */ //#define SIMULATED 1 + + +/* select correct file paths to access LEDs - depends on beaglebones linux distro/version */ #if 0 #define LED1 "/sys/class/leds/beaglebone::usr0" #define LED2 "/sys/class/leds/beaglebone::usr1" diff --git a/demos/beaglebone/static_model.c b/demos/beaglebone/static_model.c index 9d2b861b..993db3ec 100644 --- a/demos/beaglebone/static_model.c +++ b/demos/beaglebone/static_model.c @@ -76,36 +76,36 @@ LogicalNode iedModel_GenericIO_LLN0 = { "LLN0", (ModelNode*) &iedModel_GenericIO, (ModelNode*) &iedModel_GenericIO_LPHD1, - (ModelNode*) &iedModel_GenericIO_LLN0_Mod, + (ModelNode*) &iedModel_GenericIO_LLN0_Beh, }; -DataObject iedModel_GenericIO_LLN0_Mod = { +DataObject iedModel_GenericIO_LLN0_Beh = { DataObjectModelType, - "Mod", + "Beh", (ModelNode*) &iedModel_GenericIO_LLN0, - (ModelNode*) &iedModel_GenericIO_LLN0_Beh, - (ModelNode*) &iedModel_GenericIO_LLN0_Mod_stVal, + (ModelNode*) &iedModel_GenericIO_LLN0_Mod, + (ModelNode*) &iedModel_GenericIO_LLN0_Beh_stVal, 0 }; -DataAttribute iedModel_GenericIO_LLN0_Mod_stVal = { +DataAttribute iedModel_GenericIO_LLN0_Beh_stVal = { DataAttributeModelType, "stVal", - (ModelNode*) &iedModel_GenericIO_LLN0_Mod, - (ModelNode*) &iedModel_GenericIO_LLN0_Mod_q, + (ModelNode*) &iedModel_GenericIO_LLN0_Beh, + (ModelNode*) &iedModel_GenericIO_LLN0_Beh_q, NULL, 0, IEC61850_FC_ST, - INT32, + ENUMERATED, 0 + TRG_OPT_DATA_CHANGED, NULL, 0}; -DataAttribute iedModel_GenericIO_LLN0_Mod_q = { +DataAttribute iedModel_GenericIO_LLN0_Beh_q = { DataAttributeModelType, "q", - (ModelNode*) &iedModel_GenericIO_LLN0_Mod, - (ModelNode*) &iedModel_GenericIO_LLN0_Mod_t, + (ModelNode*) &iedModel_GenericIO_LLN0_Beh, + (ModelNode*) &iedModel_GenericIO_LLN0_Beh_t, NULL, 0, IEC61850_FC_ST, @@ -114,11 +114,11 @@ DataAttribute iedModel_GenericIO_LLN0_Mod_q = { NULL, 0}; -DataAttribute iedModel_GenericIO_LLN0_Mod_t = { +DataAttribute iedModel_GenericIO_LLN0_Beh_t = { DataAttributeModelType, "t", - (ModelNode*) &iedModel_GenericIO_LLN0_Mod, - (ModelNode*) &iedModel_GenericIO_LLN0_Mod_ctlModel, + (ModelNode*) &iedModel_GenericIO_LLN0_Beh, + NULL, NULL, 0, IEC61850_FC_ST, @@ -127,46 +127,33 @@ DataAttribute iedModel_GenericIO_LLN0_Mod_t = { NULL, 0}; -DataAttribute iedModel_GenericIO_LLN0_Mod_ctlModel = { - DataAttributeModelType, - "ctlModel", - (ModelNode*) &iedModel_GenericIO_LLN0_Mod, - NULL, - NULL, - 0, - IEC61850_FC_CF, - ENUMERATED, - 0, - NULL, - 0}; - -DataObject iedModel_GenericIO_LLN0_Beh = { +DataObject iedModel_GenericIO_LLN0_Mod = { DataObjectModelType, - "Beh", + "Mod", (ModelNode*) &iedModel_GenericIO_LLN0, (ModelNode*) &iedModel_GenericIO_LLN0_Health, - (ModelNode*) &iedModel_GenericIO_LLN0_Beh_stVal, + (ModelNode*) &iedModel_GenericIO_LLN0_Mod_stVal, 0 }; -DataAttribute iedModel_GenericIO_LLN0_Beh_stVal = { +DataAttribute iedModel_GenericIO_LLN0_Mod_stVal = { DataAttributeModelType, "stVal", - (ModelNode*) &iedModel_GenericIO_LLN0_Beh, - (ModelNode*) &iedModel_GenericIO_LLN0_Beh_q, + (ModelNode*) &iedModel_GenericIO_LLN0_Mod, + (ModelNode*) &iedModel_GenericIO_LLN0_Mod_q, NULL, 0, IEC61850_FC_ST, - INT32, + ENUMERATED, 0 + TRG_OPT_DATA_CHANGED, NULL, 0}; -DataAttribute iedModel_GenericIO_LLN0_Beh_q = { +DataAttribute iedModel_GenericIO_LLN0_Mod_q = { DataAttributeModelType, "q", - (ModelNode*) &iedModel_GenericIO_LLN0_Beh, - (ModelNode*) &iedModel_GenericIO_LLN0_Beh_t, + (ModelNode*) &iedModel_GenericIO_LLN0_Mod, + (ModelNode*) &iedModel_GenericIO_LLN0_Mod_t, NULL, 0, IEC61850_FC_ST, @@ -175,11 +162,11 @@ DataAttribute iedModel_GenericIO_LLN0_Beh_q = { NULL, 0}; -DataAttribute iedModel_GenericIO_LLN0_Beh_t = { +DataAttribute iedModel_GenericIO_LLN0_Mod_t = { DataAttributeModelType, "t", - (ModelNode*) &iedModel_GenericIO_LLN0_Beh, - NULL, + (ModelNode*) &iedModel_GenericIO_LLN0_Mod, + (ModelNode*) &iedModel_GenericIO_LLN0_Mod_ctlModel, NULL, 0, IEC61850_FC_ST, @@ -188,6 +175,19 @@ DataAttribute iedModel_GenericIO_LLN0_Beh_t = { NULL, 0}; +DataAttribute iedModel_GenericIO_LLN0_Mod_ctlModel = { + DataAttributeModelType, + "ctlModel", + (ModelNode*) &iedModel_GenericIO_LLN0_Mod, + NULL, + NULL, + 0, + IEC61850_FC_CF, + ENUMERATED, + 0, + NULL, + 0}; + DataObject iedModel_GenericIO_LLN0_Health = { DataObjectModelType, "Health", @@ -205,7 +205,7 @@ DataAttribute iedModel_GenericIO_LLN0_Health_stVal = { NULL, 0, IEC61850_FC_ST, - INT32, + ENUMERATED, 0 + TRG_OPT_DATA_CHANGED, NULL, 0}; @@ -357,7 +357,7 @@ DataAttribute iedModel_GenericIO_LPHD1_PhyHealth_stVal = { NULL, 0, IEC61850_FC_ST, - INT32, + ENUMERATED, 0 + TRG_OPT_DATA_CHANGED, NULL, 0}; @@ -440,85 +440,85 @@ LogicalNode iedModel_GenericIO_GGIO1 = { LogicalNodeModelType, "GGIO1", (ModelNode*) &iedModel_GenericIO, - NULL, - (ModelNode*) &iedModel_GenericIO_GGIO1_Mod, + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1, + (ModelNode*) &iedModel_GenericIO_GGIO1_Beh, }; -DataObject iedModel_GenericIO_GGIO1_Mod = { +DataObject iedModel_GenericIO_GGIO1_Beh = { DataObjectModelType, - "Mod", + "Beh", (ModelNode*) &iedModel_GenericIO_GGIO1, - (ModelNode*) &iedModel_GenericIO_GGIO1_Beh, - (ModelNode*) &iedModel_GenericIO_GGIO1_Mod_q, + (ModelNode*) &iedModel_GenericIO_GGIO1_Mod, + (ModelNode*) &iedModel_GenericIO_GGIO1_Beh_stVal, 0 }; -DataAttribute iedModel_GenericIO_GGIO1_Mod_q = { +DataAttribute iedModel_GenericIO_GGIO1_Beh_stVal = { DataAttributeModelType, - "q", - (ModelNode*) &iedModel_GenericIO_GGIO1_Mod, - (ModelNode*) &iedModel_GenericIO_GGIO1_Mod_t, + "stVal", + (ModelNode*) &iedModel_GenericIO_GGIO1_Beh, + (ModelNode*) &iedModel_GenericIO_GGIO1_Beh_q, NULL, 0, IEC61850_FC_ST, - QUALITY, - 0 + TRG_OPT_QUALITY_CHANGED, + ENUMERATED, + 0 + TRG_OPT_DATA_CHANGED, NULL, 0}; -DataAttribute iedModel_GenericIO_GGIO1_Mod_t = { +DataAttribute iedModel_GenericIO_GGIO1_Beh_q = { DataAttributeModelType, - "t", - (ModelNode*) &iedModel_GenericIO_GGIO1_Mod, - (ModelNode*) &iedModel_GenericIO_GGIO1_Mod_ctlModel, + "q", + (ModelNode*) &iedModel_GenericIO_GGIO1_Beh, + (ModelNode*) &iedModel_GenericIO_GGIO1_Beh_t, NULL, 0, IEC61850_FC_ST, - TIMESTAMP, - 0, + QUALITY, + 0 + TRG_OPT_QUALITY_CHANGED, NULL, 0}; -DataAttribute iedModel_GenericIO_GGIO1_Mod_ctlModel = { +DataAttribute iedModel_GenericIO_GGIO1_Beh_t = { DataAttributeModelType, - "ctlModel", - (ModelNode*) &iedModel_GenericIO_GGIO1_Mod, + "t", + (ModelNode*) &iedModel_GenericIO_GGIO1_Beh, NULL, NULL, 0, - IEC61850_FC_CF, - ENUMERATED, + IEC61850_FC_ST, + TIMESTAMP, 0, NULL, 0}; -DataObject iedModel_GenericIO_GGIO1_Beh = { +DataObject iedModel_GenericIO_GGIO1_Mod = { DataObjectModelType, - "Beh", + "Mod", (ModelNode*) &iedModel_GenericIO_GGIO1, (ModelNode*) &iedModel_GenericIO_GGIO1_Health, - (ModelNode*) &iedModel_GenericIO_GGIO1_Beh_stVal, + (ModelNode*) &iedModel_GenericIO_GGIO1_Mod_stVal, 0 }; -DataAttribute iedModel_GenericIO_GGIO1_Beh_stVal = { +DataAttribute iedModel_GenericIO_GGIO1_Mod_stVal = { DataAttributeModelType, "stVal", - (ModelNode*) &iedModel_GenericIO_GGIO1_Beh, - (ModelNode*) &iedModel_GenericIO_GGIO1_Beh_q, + (ModelNode*) &iedModel_GenericIO_GGIO1_Mod, + (ModelNode*) &iedModel_GenericIO_GGIO1_Mod_q, NULL, 0, IEC61850_FC_ST, - INT32, + ENUMERATED, 0 + TRG_OPT_DATA_CHANGED, NULL, 0}; -DataAttribute iedModel_GenericIO_GGIO1_Beh_q = { +DataAttribute iedModel_GenericIO_GGIO1_Mod_q = { DataAttributeModelType, "q", - (ModelNode*) &iedModel_GenericIO_GGIO1_Beh, - (ModelNode*) &iedModel_GenericIO_GGIO1_Beh_t, + (ModelNode*) &iedModel_GenericIO_GGIO1_Mod, + (ModelNode*) &iedModel_GenericIO_GGIO1_Mod_t, NULL, 0, IEC61850_FC_ST, @@ -527,11 +527,11 @@ DataAttribute iedModel_GenericIO_GGIO1_Beh_q = { NULL, 0}; -DataAttribute iedModel_GenericIO_GGIO1_Beh_t = { +DataAttribute iedModel_GenericIO_GGIO1_Mod_t = { DataAttributeModelType, "t", - (ModelNode*) &iedModel_GenericIO_GGIO1_Beh, - NULL, + (ModelNode*) &iedModel_GenericIO_GGIO1_Mod, + (ModelNode*) &iedModel_GenericIO_GGIO1_Mod_ctlModel, NULL, 0, IEC61850_FC_ST, @@ -540,6 +540,19 @@ DataAttribute iedModel_GenericIO_GGIO1_Beh_t = { NULL, 0}; +DataAttribute iedModel_GenericIO_GGIO1_Mod_ctlModel = { + DataAttributeModelType, + "ctlModel", + (ModelNode*) &iedModel_GenericIO_GGIO1_Mod, + NULL, + NULL, + 0, + IEC61850_FC_CF, + ENUMERATED, + 0, + NULL, + 0}; + DataObject iedModel_GenericIO_GGIO1_Health = { DataObjectModelType, "Health", @@ -557,7 +570,7 @@ DataAttribute iedModel_GenericIO_GGIO1_Health_stVal = { NULL, 0, IEC61850_FC_ST, - INT32, + ENUMERATED, 0 + TRG_OPT_DATA_CHANGED, NULL, 0}; @@ -1901,44 +1914,526 @@ DataAttribute iedModel_GenericIO_GGIO1_Ind4_t = { NULL, 0}; -extern ReportControlBlock iedModel_GenericIO_LLN0_report0; -extern ReportControlBlock iedModel_GenericIO_LLN0_report1; -extern ReportControlBlock iedModel_GenericIO_LLN0_report2; -extern ReportControlBlock iedModel_GenericIO_LLN0_report3; -extern ReportControlBlock iedModel_GenericIO_LLN0_report4; - -ReportControlBlock iedModel_GenericIO_LLN0_report0 = {&iedModel_GenericIO_LLN0, "EventsRCB01", "Events1", false, "Events", 1, 8, 111, 50, 1000, &iedModel_GenericIO_LLN0_report1}; -ReportControlBlock iedModel_GenericIO_LLN0_report1 = {&iedModel_GenericIO_LLN0, "EventsRCB02", "Events1", false, "Events", 1, 8, 111, 50, 1000, &iedModel_GenericIO_LLN0_report2}; -ReportControlBlock iedModel_GenericIO_LLN0_report2 = {&iedModel_GenericIO_LLN0, "EventsRCB03", "Events1", false, "Events", 1, 8, 111, 50, 1000, &iedModel_GenericIO_LLN0_report3}; -ReportControlBlock iedModel_GenericIO_LLN0_report3 = {&iedModel_GenericIO_LLN0, "EventsRCB04", "Events1", false, "Events", 1, 8, 111, 50, 1000, &iedModel_GenericIO_LLN0_report4}; -ReportControlBlock iedModel_GenericIO_LLN0_report4 = {&iedModel_GenericIO_LLN0, "EventsRCB05", "Events1", false, "Events", 1, 8, 111, 50, 1000, NULL}; - +LogicalNode iedModel_GenericIO_TIM_GAPC1 = { + LogicalNodeModelType, + "TIM_GAPC1", + (ModelNode*) &iedModel_GenericIO, + NULL, + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_Beh, +}; +DataObject iedModel_GenericIO_TIM_GAPC1_Beh = { + DataObjectModelType, + "Beh", + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1, + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_Mod, + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_Beh_stVal, + 0 +}; +DataAttribute iedModel_GenericIO_TIM_GAPC1_Beh_stVal = { + DataAttributeModelType, + "stVal", + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_Beh, + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_Beh_q, + NULL, + 0, + IEC61850_FC_ST, + ENUMERATED, + 0 + TRG_OPT_DATA_CHANGED, + NULL, + 0}; -IedModel iedModel = { - "beagle", - &iedModel_GenericIO, - &iedModelds_GenericIO_LLN0_Events, - &iedModel_GenericIO_LLN0_report0, +DataAttribute iedModel_GenericIO_TIM_GAPC1_Beh_q = { + DataAttributeModelType, + "q", + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_Beh, + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_Beh_t, NULL, + 0, + IEC61850_FC_ST, + QUALITY, + 0 + TRG_OPT_QUALITY_CHANGED, NULL, - initializeValues -}; + 0}; -static void -initializeValues() -{ +DataAttribute iedModel_GenericIO_TIM_GAPC1_Beh_t = { + DataAttributeModelType, + "t", + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_Beh, + NULL, + NULL, + 0, + IEC61850_FC_ST, + TIMESTAMP, + 0, + NULL, + 0}; -iedModel_GenericIO_LLN0_Mod_ctlModel.mmsValue = MmsValue_newIntegerFromInt32(0); +DataObject iedModel_GenericIO_TIM_GAPC1_Mod = { + DataObjectModelType, + "Mod", + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1, + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_Str, + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_Mod_stVal, + 0 +}; -iedModel_GenericIO_GGIO1_Mod_ctlModel.mmsValue = MmsValue_newIntegerFromInt32(0); +DataAttribute iedModel_GenericIO_TIM_GAPC1_Mod_stVal = { + DataAttributeModelType, + "stVal", + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_Mod, + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_Mod_q, + NULL, + 0, + IEC61850_FC_ST, + ENUMERATED, + 0 + TRG_OPT_DATA_CHANGED, + NULL, + 0}; -iedModel_GenericIO_GGIO1_SPCSO1_ctlModel.mmsValue = MmsValue_newIntegerFromInt32(1); +DataAttribute iedModel_GenericIO_TIM_GAPC1_Mod_q = { + DataAttributeModelType, + "q", + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_Mod, + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_Mod_t, + NULL, + 0, + IEC61850_FC_ST, + QUALITY, + 0 + TRG_OPT_QUALITY_CHANGED, + NULL, + 0}; -iedModel_GenericIO_GGIO1_SPCSO2_ctlModel.mmsValue = MmsValue_newIntegerFromInt32(2); +DataAttribute iedModel_GenericIO_TIM_GAPC1_Mod_t = { + DataAttributeModelType, + "t", + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_Mod, + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_Mod_ctlModel, + NULL, + 0, + IEC61850_FC_ST, + TIMESTAMP, + 0, + NULL, + 0}; + +DataAttribute iedModel_GenericIO_TIM_GAPC1_Mod_ctlModel = { + DataAttributeModelType, + "ctlModel", + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_Mod, + NULL, + NULL, + 0, + IEC61850_FC_CF, + ENUMERATED, + 0, + NULL, + 0}; + +DataObject iedModel_GenericIO_TIM_GAPC1_Str = { + DataObjectModelType, + "Str", + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1, + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_Op, + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_Str_general, + 0 +}; + +DataAttribute iedModel_GenericIO_TIM_GAPC1_Str_general = { + DataAttributeModelType, + "general", + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_Str, + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_Str_dirGeneral, + NULL, + 0, + IEC61850_FC_ST, + BOOLEAN, + 0 + TRG_OPT_DATA_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_GenericIO_TIM_GAPC1_Str_dirGeneral = { + DataAttributeModelType, + "dirGeneral", + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_Str, + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_Str_q, + NULL, + 0, + IEC61850_FC_ST, + ENUMERATED, + 0 + TRG_OPT_DATA_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_GenericIO_TIM_GAPC1_Str_q = { + DataAttributeModelType, + "q", + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_Str, + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_Str_t, + NULL, + 0, + IEC61850_FC_ST, + QUALITY, + 0 + TRG_OPT_QUALITY_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_GenericIO_TIM_GAPC1_Str_t = { + DataAttributeModelType, + "t", + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_Str, + NULL, + NULL, + 0, + IEC61850_FC_ST, + TIMESTAMP, + 0, + NULL, + 0}; + +DataObject iedModel_GenericIO_TIM_GAPC1_Op = { + DataObjectModelType, + "Op", + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1, + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_OpDlTmms, + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_Op_general, + 0 +}; + +DataAttribute iedModel_GenericIO_TIM_GAPC1_Op_general = { + DataAttributeModelType, + "general", + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_Op, + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_Op_q, + NULL, + 0, + IEC61850_FC_ST, + BOOLEAN, + 0 + TRG_OPT_DATA_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_GenericIO_TIM_GAPC1_Op_q = { + DataAttributeModelType, + "q", + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_Op, + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_Op_t, + NULL, + 0, + IEC61850_FC_ST, + QUALITY, + 0 + TRG_OPT_QUALITY_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_GenericIO_TIM_GAPC1_Op_t = { + DataAttributeModelType, + "t", + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_Op, + NULL, + NULL, + 0, + IEC61850_FC_ST, + TIMESTAMP, + 0, + NULL, + 0}; + +DataObject iedModel_GenericIO_TIM_GAPC1_OpDlTmms = { + DataObjectModelType, + "OpDlTmms", + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1, + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_RsDlTmms, + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_OpDlTmms_setVal, + 0 +}; + +DataAttribute iedModel_GenericIO_TIM_GAPC1_OpDlTmms_setVal = { + DataAttributeModelType, + "setVal", + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_OpDlTmms, + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_OpDlTmms_dataNs, + NULL, + 0, + IEC61850_FC_SP, + INT32, + 0 + TRG_OPT_DATA_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_GenericIO_TIM_GAPC1_OpDlTmms_dataNs = { + DataAttributeModelType, + "dataNs", + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_OpDlTmms, + NULL, + NULL, + 0, + IEC61850_FC_EX, + VISIBLE_STRING_255, + 0, + NULL, + 0}; + +DataObject iedModel_GenericIO_TIM_GAPC1_RsDlTmms = { + DataObjectModelType, + "RsDlTmms", + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1, + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_OpCntRs, + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_RsDlTmms_setVal, + 0 +}; + +DataAttribute iedModel_GenericIO_TIM_GAPC1_RsDlTmms_setVal = { + DataAttributeModelType, + "setVal", + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_RsDlTmms, + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_RsDlTmms_dataNs, + NULL, + 0, + IEC61850_FC_SP, + INT32, + 0 + TRG_OPT_DATA_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_GenericIO_TIM_GAPC1_RsDlTmms_dataNs = { + DataAttributeModelType, + "dataNs", + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_RsDlTmms, + NULL, + NULL, + 0, + IEC61850_FC_EX, + VISIBLE_STRING_255, + 0, + NULL, + 0}; + +DataObject iedModel_GenericIO_TIM_GAPC1_OpCntRs = { + DataObjectModelType, + "OpCntRs", + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1, + NULL, + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_OpCntRs_stVal, + 0 +}; + +DataAttribute iedModel_GenericIO_TIM_GAPC1_OpCntRs_stVal = { + DataAttributeModelType, + "stVal", + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_OpCntRs, + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_OpCntRs_q, + NULL, + 0, + IEC61850_FC_ST, + INT32, + 0 + TRG_OPT_DATA_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_GenericIO_TIM_GAPC1_OpCntRs_q = { + DataAttributeModelType, + "q", + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_OpCntRs, + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_OpCntRs_t, + NULL, + 0, + IEC61850_FC_ST, + QUALITY, + 0 + TRG_OPT_QUALITY_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_GenericIO_TIM_GAPC1_OpCntRs_t = { + DataAttributeModelType, + "t", + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_OpCntRs, + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_OpCntRs_Oper, + NULL, + 0, + IEC61850_FC_ST, + TIMESTAMP, + 0, + NULL, + 0}; + +DataAttribute iedModel_GenericIO_TIM_GAPC1_OpCntRs_Oper = { + DataAttributeModelType, + "Oper", + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_OpCntRs, + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_OpCntRs_ctlModel, + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_OpCntRs_Oper_ctlVal, + 0, + IEC61850_FC_CO, + CONSTRUCTED, + 0, + NULL, + 0}; + +DataAttribute iedModel_GenericIO_TIM_GAPC1_OpCntRs_Oper_ctlVal = { + DataAttributeModelType, + "ctlVal", + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_OpCntRs_Oper, + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_OpCntRs_Oper_origin, + NULL, + 0, + IEC61850_FC_CO, + BOOLEAN, + 0, + NULL, + 0}; + +DataAttribute iedModel_GenericIO_TIM_GAPC1_OpCntRs_Oper_origin = { + DataAttributeModelType, + "origin", + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_OpCntRs_Oper, + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_OpCntRs_Oper_ctlNum, + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_OpCntRs_Oper_origin_orCat, + 0, + IEC61850_FC_CO, + CONSTRUCTED, + 0, + NULL, + 0}; + +DataAttribute iedModel_GenericIO_TIM_GAPC1_OpCntRs_Oper_origin_orCat = { + DataAttributeModelType, + "orCat", + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_OpCntRs_Oper_origin, + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_OpCntRs_Oper_origin_orIdent, + NULL, + 0, + IEC61850_FC_CO, + ENUMERATED, + 0, + NULL, + 0}; + +DataAttribute iedModel_GenericIO_TIM_GAPC1_OpCntRs_Oper_origin_orIdent = { + DataAttributeModelType, + "orIdent", + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_OpCntRs_Oper_origin, + NULL, + NULL, + 0, + IEC61850_FC_CO, + OCTET_STRING_64, + 0, + NULL, + 0}; + +DataAttribute iedModel_GenericIO_TIM_GAPC1_OpCntRs_Oper_ctlNum = { + DataAttributeModelType, + "ctlNum", + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_OpCntRs_Oper, + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_OpCntRs_Oper_T, + NULL, + 0, + IEC61850_FC_CO, + INT8U, + 0, + NULL, + 0}; + +DataAttribute iedModel_GenericIO_TIM_GAPC1_OpCntRs_Oper_T = { + DataAttributeModelType, + "T", + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_OpCntRs_Oper, + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_OpCntRs_Oper_Test, + NULL, + 0, + IEC61850_FC_CO, + TIMESTAMP, + 0, + NULL, + 0}; + +DataAttribute iedModel_GenericIO_TIM_GAPC1_OpCntRs_Oper_Test = { + DataAttributeModelType, + "Test", + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_OpCntRs_Oper, + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_OpCntRs_Oper_Check, + NULL, + 0, + IEC61850_FC_CO, + BOOLEAN, + 0, + NULL, + 0}; + +DataAttribute iedModel_GenericIO_TIM_GAPC1_OpCntRs_Oper_Check = { + DataAttributeModelType, + "Check", + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_OpCntRs_Oper, + NULL, + NULL, + 0, + IEC61850_FC_CO, + CHECK, + 0, + NULL, + 0}; + +DataAttribute iedModel_GenericIO_TIM_GAPC1_OpCntRs_ctlModel = { + DataAttributeModelType, + "ctlModel", + (ModelNode*) &iedModel_GenericIO_TIM_GAPC1_OpCntRs, + NULL, + NULL, + 0, + IEC61850_FC_CF, + ENUMERATED, + 0, + NULL, + 0}; + +extern ReportControlBlock iedModel_GenericIO_LLN0_report0; +extern ReportControlBlock iedModel_GenericIO_LLN0_report1; +extern ReportControlBlock iedModel_GenericIO_LLN0_report2; +extern ReportControlBlock iedModel_GenericIO_LLN0_report3; +extern ReportControlBlock iedModel_GenericIO_LLN0_report4; + +ReportControlBlock iedModel_GenericIO_LLN0_report0 = {&iedModel_GenericIO_LLN0, "EventsRCB01", "Events1", false, "Events", 1, 24, 111, 50, 1000, &iedModel_GenericIO_LLN0_report1}; +ReportControlBlock iedModel_GenericIO_LLN0_report1 = {&iedModel_GenericIO_LLN0, "EventsRCB02", "Events1", false, "Events", 1, 24, 111, 50, 1000, &iedModel_GenericIO_LLN0_report2}; +ReportControlBlock iedModel_GenericIO_LLN0_report2 = {&iedModel_GenericIO_LLN0, "EventsRCB03", "Events1", false, "Events", 1, 24, 111, 50, 1000, &iedModel_GenericIO_LLN0_report3}; +ReportControlBlock iedModel_GenericIO_LLN0_report3 = {&iedModel_GenericIO_LLN0, "EventsRCB04", "Events1", false, "Events", 1, 24, 111, 50, 1000, &iedModel_GenericIO_LLN0_report4}; +ReportControlBlock iedModel_GenericIO_LLN0_report4 = {&iedModel_GenericIO_LLN0, "EventsRCB05", "Events1", false, "Events", 1, 24, 111, 50, 1000, NULL}; + + + + +IedModel iedModel = { + "beagle", + &iedModel_GenericIO, + &iedModelds_GenericIO_LLN0_Events, + &iedModel_GenericIO_LLN0_report0, + NULL, + NULL, + initializeValues +}; + +static void +initializeValues() +{ + +iedModel_GenericIO_LLN0_Mod_ctlModel.mmsValue = MmsValue_newIntegerFromInt32(0); + +iedModel_GenericIO_GGIO1_Mod_ctlModel.mmsValue = MmsValue_newIntegerFromInt32(0); + +iedModel_GenericIO_GGIO1_SPCSO1_ctlModel.mmsValue = MmsValue_newIntegerFromInt32(1); + +iedModel_GenericIO_GGIO1_SPCSO2_ctlModel.mmsValue = MmsValue_newIntegerFromInt32(2); iedModel_GenericIO_GGIO1_SPCSO3_ctlModel.mmsValue = MmsValue_newIntegerFromInt32(1); iedModel_GenericIO_GGIO1_DPCSO1_ctlModel.mmsValue = MmsValue_newIntegerFromInt32(3); + +iedModel_GenericIO_TIM_GAPC1_Mod_ctlModel.mmsValue = MmsValue_newIntegerFromInt32(0); + +iedModel_GenericIO_TIM_GAPC1_OpDlTmms_dataNs.mmsValue = MmsValue_newVisibleString("EXT:2015"); + +iedModel_GenericIO_TIM_GAPC1_RsDlTmms_dataNs.mmsValue = MmsValue_newVisibleString("EXT:2015"); + +iedModel_GenericIO_TIM_GAPC1_OpCntRs_ctlModel.mmsValue = MmsValue_newIntegerFromInt32(1); } diff --git a/demos/beaglebone/static_model.h b/demos/beaglebone/static_model.h index 36a7e0f7..a50ade81 100644 --- a/demos/beaglebone/static_model.h +++ b/demos/beaglebone/static_model.h @@ -13,15 +13,15 @@ extern IedModel iedModel; extern LogicalDevice iedModel_GenericIO; extern LogicalNode iedModel_GenericIO_LLN0; +extern DataObject iedModel_GenericIO_LLN0_Beh; +extern DataAttribute iedModel_GenericIO_LLN0_Beh_stVal; +extern DataAttribute iedModel_GenericIO_LLN0_Beh_q; +extern DataAttribute iedModel_GenericIO_LLN0_Beh_t; extern DataObject iedModel_GenericIO_LLN0_Mod; extern DataAttribute iedModel_GenericIO_LLN0_Mod_stVal; extern DataAttribute iedModel_GenericIO_LLN0_Mod_q; extern DataAttribute iedModel_GenericIO_LLN0_Mod_t; extern DataAttribute iedModel_GenericIO_LLN0_Mod_ctlModel; -extern DataObject iedModel_GenericIO_LLN0_Beh; -extern DataAttribute iedModel_GenericIO_LLN0_Beh_stVal; -extern DataAttribute iedModel_GenericIO_LLN0_Beh_q; -extern DataAttribute iedModel_GenericIO_LLN0_Beh_t; extern DataObject iedModel_GenericIO_LLN0_Health; extern DataAttribute iedModel_GenericIO_LLN0_Health_stVal; extern DataAttribute iedModel_GenericIO_LLN0_Health_q; @@ -44,14 +44,15 @@ extern DataAttribute iedModel_GenericIO_LPHD1_Proxy_stVal; extern DataAttribute iedModel_GenericIO_LPHD1_Proxy_q; extern DataAttribute iedModel_GenericIO_LPHD1_Proxy_t; extern LogicalNode iedModel_GenericIO_GGIO1; -extern DataObject iedModel_GenericIO_GGIO1_Mod; -extern DataAttribute iedModel_GenericIO_GGIO1_Mod_q; -extern DataAttribute iedModel_GenericIO_GGIO1_Mod_t; -extern DataAttribute iedModel_GenericIO_GGIO1_Mod_ctlModel; extern DataObject iedModel_GenericIO_GGIO1_Beh; extern DataAttribute iedModel_GenericIO_GGIO1_Beh_stVal; extern DataAttribute iedModel_GenericIO_GGIO1_Beh_q; extern DataAttribute iedModel_GenericIO_GGIO1_Beh_t; +extern DataObject iedModel_GenericIO_GGIO1_Mod; +extern DataAttribute iedModel_GenericIO_GGIO1_Mod_stVal; +extern DataAttribute iedModel_GenericIO_GGIO1_Mod_q; +extern DataAttribute iedModel_GenericIO_GGIO1_Mod_t; +extern DataAttribute iedModel_GenericIO_GGIO1_Mod_ctlModel; extern DataObject iedModel_GenericIO_GGIO1_Health; extern DataAttribute iedModel_GenericIO_GGIO1_Health_stVal; extern DataAttribute iedModel_GenericIO_GGIO1_Health_q; @@ -161,20 +162,59 @@ extern DataObject iedModel_GenericIO_GGIO1_Ind4; extern DataAttribute iedModel_GenericIO_GGIO1_Ind4_stVal; extern DataAttribute iedModel_GenericIO_GGIO1_Ind4_q; extern DataAttribute iedModel_GenericIO_GGIO1_Ind4_t; +extern LogicalNode iedModel_GenericIO_TIM_GAPC1; +extern DataObject iedModel_GenericIO_TIM_GAPC1_Beh; +extern DataAttribute iedModel_GenericIO_TIM_GAPC1_Beh_stVal; +extern DataAttribute iedModel_GenericIO_TIM_GAPC1_Beh_q; +extern DataAttribute iedModel_GenericIO_TIM_GAPC1_Beh_t; +extern DataObject iedModel_GenericIO_TIM_GAPC1_Mod; +extern DataAttribute iedModel_GenericIO_TIM_GAPC1_Mod_stVal; +extern DataAttribute iedModel_GenericIO_TIM_GAPC1_Mod_q; +extern DataAttribute iedModel_GenericIO_TIM_GAPC1_Mod_t; +extern DataAttribute iedModel_GenericIO_TIM_GAPC1_Mod_ctlModel; +extern DataObject iedModel_GenericIO_TIM_GAPC1_Str; +extern DataAttribute iedModel_GenericIO_TIM_GAPC1_Str_general; +extern DataAttribute iedModel_GenericIO_TIM_GAPC1_Str_dirGeneral; +extern DataAttribute iedModel_GenericIO_TIM_GAPC1_Str_q; +extern DataAttribute iedModel_GenericIO_TIM_GAPC1_Str_t; +extern DataObject iedModel_GenericIO_TIM_GAPC1_Op; +extern DataAttribute iedModel_GenericIO_TIM_GAPC1_Op_general; +extern DataAttribute iedModel_GenericIO_TIM_GAPC1_Op_q; +extern DataAttribute iedModel_GenericIO_TIM_GAPC1_Op_t; +extern DataObject iedModel_GenericIO_TIM_GAPC1_OpDlTmms; +extern DataAttribute iedModel_GenericIO_TIM_GAPC1_OpDlTmms_setVal; +extern DataAttribute iedModel_GenericIO_TIM_GAPC1_OpDlTmms_dataNs; +extern DataObject iedModel_GenericIO_TIM_GAPC1_RsDlTmms; +extern DataAttribute iedModel_GenericIO_TIM_GAPC1_RsDlTmms_setVal; +extern DataAttribute iedModel_GenericIO_TIM_GAPC1_RsDlTmms_dataNs; +extern DataObject iedModel_GenericIO_TIM_GAPC1_OpCntRs; +extern DataAttribute iedModel_GenericIO_TIM_GAPC1_OpCntRs_stVal; +extern DataAttribute iedModel_GenericIO_TIM_GAPC1_OpCntRs_q; +extern DataAttribute iedModel_GenericIO_TIM_GAPC1_OpCntRs_t; +extern DataAttribute iedModel_GenericIO_TIM_GAPC1_OpCntRs_Oper; +extern DataAttribute iedModel_GenericIO_TIM_GAPC1_OpCntRs_Oper_ctlVal; +extern DataAttribute iedModel_GenericIO_TIM_GAPC1_OpCntRs_Oper_origin; +extern DataAttribute iedModel_GenericIO_TIM_GAPC1_OpCntRs_Oper_origin_orCat; +extern DataAttribute iedModel_GenericIO_TIM_GAPC1_OpCntRs_Oper_origin_orIdent; +extern DataAttribute iedModel_GenericIO_TIM_GAPC1_OpCntRs_Oper_ctlNum; +extern DataAttribute iedModel_GenericIO_TIM_GAPC1_OpCntRs_Oper_T; +extern DataAttribute iedModel_GenericIO_TIM_GAPC1_OpCntRs_Oper_Test; +extern DataAttribute iedModel_GenericIO_TIM_GAPC1_OpCntRs_Oper_Check; +extern DataAttribute iedModel_GenericIO_TIM_GAPC1_OpCntRs_ctlModel; #define IEDMODEL_GenericIO (&iedModel_GenericIO) #define IEDMODEL_GenericIO_LLN0 (&iedModel_GenericIO_LLN0) +#define IEDMODEL_GenericIO_LLN0_Beh (&iedModel_GenericIO_LLN0_Beh) +#define IEDMODEL_GenericIO_LLN0_Beh_stVal (&iedModel_GenericIO_LLN0_Beh_stVal) +#define IEDMODEL_GenericIO_LLN0_Beh_q (&iedModel_GenericIO_LLN0_Beh_q) +#define IEDMODEL_GenericIO_LLN0_Beh_t (&iedModel_GenericIO_LLN0_Beh_t) #define IEDMODEL_GenericIO_LLN0_Mod (&iedModel_GenericIO_LLN0_Mod) #define IEDMODEL_GenericIO_LLN0_Mod_stVal (&iedModel_GenericIO_LLN0_Mod_stVal) #define IEDMODEL_GenericIO_LLN0_Mod_q (&iedModel_GenericIO_LLN0_Mod_q) #define IEDMODEL_GenericIO_LLN0_Mod_t (&iedModel_GenericIO_LLN0_Mod_t) #define IEDMODEL_GenericIO_LLN0_Mod_ctlModel (&iedModel_GenericIO_LLN0_Mod_ctlModel) -#define IEDMODEL_GenericIO_LLN0_Beh (&iedModel_GenericIO_LLN0_Beh) -#define IEDMODEL_GenericIO_LLN0_Beh_stVal (&iedModel_GenericIO_LLN0_Beh_stVal) -#define IEDMODEL_GenericIO_LLN0_Beh_q (&iedModel_GenericIO_LLN0_Beh_q) -#define IEDMODEL_GenericIO_LLN0_Beh_t (&iedModel_GenericIO_LLN0_Beh_t) #define IEDMODEL_GenericIO_LLN0_Health (&iedModel_GenericIO_LLN0_Health) #define IEDMODEL_GenericIO_LLN0_Health_stVal (&iedModel_GenericIO_LLN0_Health_stVal) #define IEDMODEL_GenericIO_LLN0_Health_q (&iedModel_GenericIO_LLN0_Health_q) @@ -197,14 +237,15 @@ extern DataAttribute iedModel_GenericIO_GGIO1_Ind4_t; #define IEDMODEL_GenericIO_LPHD1_Proxy_q (&iedModel_GenericIO_LPHD1_Proxy_q) #define IEDMODEL_GenericIO_LPHD1_Proxy_t (&iedModel_GenericIO_LPHD1_Proxy_t) #define IEDMODEL_GenericIO_GGIO1 (&iedModel_GenericIO_GGIO1) -#define IEDMODEL_GenericIO_GGIO1_Mod (&iedModel_GenericIO_GGIO1_Mod) -#define IEDMODEL_GenericIO_GGIO1_Mod_q (&iedModel_GenericIO_GGIO1_Mod_q) -#define IEDMODEL_GenericIO_GGIO1_Mod_t (&iedModel_GenericIO_GGIO1_Mod_t) -#define IEDMODEL_GenericIO_GGIO1_Mod_ctlModel (&iedModel_GenericIO_GGIO1_Mod_ctlModel) #define IEDMODEL_GenericIO_GGIO1_Beh (&iedModel_GenericIO_GGIO1_Beh) #define IEDMODEL_GenericIO_GGIO1_Beh_stVal (&iedModel_GenericIO_GGIO1_Beh_stVal) #define IEDMODEL_GenericIO_GGIO1_Beh_q (&iedModel_GenericIO_GGIO1_Beh_q) #define IEDMODEL_GenericIO_GGIO1_Beh_t (&iedModel_GenericIO_GGIO1_Beh_t) +#define IEDMODEL_GenericIO_GGIO1_Mod (&iedModel_GenericIO_GGIO1_Mod) +#define IEDMODEL_GenericIO_GGIO1_Mod_stVal (&iedModel_GenericIO_GGIO1_Mod_stVal) +#define IEDMODEL_GenericIO_GGIO1_Mod_q (&iedModel_GenericIO_GGIO1_Mod_q) +#define IEDMODEL_GenericIO_GGIO1_Mod_t (&iedModel_GenericIO_GGIO1_Mod_t) +#define IEDMODEL_GenericIO_GGIO1_Mod_ctlModel (&iedModel_GenericIO_GGIO1_Mod_ctlModel) #define IEDMODEL_GenericIO_GGIO1_Health (&iedModel_GenericIO_GGIO1_Health) #define IEDMODEL_GenericIO_GGIO1_Health_stVal (&iedModel_GenericIO_GGIO1_Health_stVal) #define IEDMODEL_GenericIO_GGIO1_Health_q (&iedModel_GenericIO_GGIO1_Health_q) @@ -314,6 +355,45 @@ extern DataAttribute iedModel_GenericIO_GGIO1_Ind4_t; #define IEDMODEL_GenericIO_GGIO1_Ind4_stVal (&iedModel_GenericIO_GGIO1_Ind4_stVal) #define IEDMODEL_GenericIO_GGIO1_Ind4_q (&iedModel_GenericIO_GGIO1_Ind4_q) #define IEDMODEL_GenericIO_GGIO1_Ind4_t (&iedModel_GenericIO_GGIO1_Ind4_t) +#define IEDMODEL_GenericIO_TIM_GAPC1 (&iedModel_GenericIO_TIM_GAPC1) +#define IEDMODEL_GenericIO_TIM_GAPC1_Beh (&iedModel_GenericIO_TIM_GAPC1_Beh) +#define IEDMODEL_GenericIO_TIM_GAPC1_Beh_stVal (&iedModel_GenericIO_TIM_GAPC1_Beh_stVal) +#define IEDMODEL_GenericIO_TIM_GAPC1_Beh_q (&iedModel_GenericIO_TIM_GAPC1_Beh_q) +#define IEDMODEL_GenericIO_TIM_GAPC1_Beh_t (&iedModel_GenericIO_TIM_GAPC1_Beh_t) +#define IEDMODEL_GenericIO_TIM_GAPC1_Mod (&iedModel_GenericIO_TIM_GAPC1_Mod) +#define IEDMODEL_GenericIO_TIM_GAPC1_Mod_stVal (&iedModel_GenericIO_TIM_GAPC1_Mod_stVal) +#define IEDMODEL_GenericIO_TIM_GAPC1_Mod_q (&iedModel_GenericIO_TIM_GAPC1_Mod_q) +#define IEDMODEL_GenericIO_TIM_GAPC1_Mod_t (&iedModel_GenericIO_TIM_GAPC1_Mod_t) +#define IEDMODEL_GenericIO_TIM_GAPC1_Mod_ctlModel (&iedModel_GenericIO_TIM_GAPC1_Mod_ctlModel) +#define IEDMODEL_GenericIO_TIM_GAPC1_Str (&iedModel_GenericIO_TIM_GAPC1_Str) +#define IEDMODEL_GenericIO_TIM_GAPC1_Str_general (&iedModel_GenericIO_TIM_GAPC1_Str_general) +#define IEDMODEL_GenericIO_TIM_GAPC1_Str_dirGeneral (&iedModel_GenericIO_TIM_GAPC1_Str_dirGeneral) +#define IEDMODEL_GenericIO_TIM_GAPC1_Str_q (&iedModel_GenericIO_TIM_GAPC1_Str_q) +#define IEDMODEL_GenericIO_TIM_GAPC1_Str_t (&iedModel_GenericIO_TIM_GAPC1_Str_t) +#define IEDMODEL_GenericIO_TIM_GAPC1_Op (&iedModel_GenericIO_TIM_GAPC1_Op) +#define IEDMODEL_GenericIO_TIM_GAPC1_Op_general (&iedModel_GenericIO_TIM_GAPC1_Op_general) +#define IEDMODEL_GenericIO_TIM_GAPC1_Op_q (&iedModel_GenericIO_TIM_GAPC1_Op_q) +#define IEDMODEL_GenericIO_TIM_GAPC1_Op_t (&iedModel_GenericIO_TIM_GAPC1_Op_t) +#define IEDMODEL_GenericIO_TIM_GAPC1_OpDlTmms (&iedModel_GenericIO_TIM_GAPC1_OpDlTmms) +#define IEDMODEL_GenericIO_TIM_GAPC1_OpDlTmms_setVal (&iedModel_GenericIO_TIM_GAPC1_OpDlTmms_setVal) +#define IEDMODEL_GenericIO_TIM_GAPC1_OpDlTmms_dataNs (&iedModel_GenericIO_TIM_GAPC1_OpDlTmms_dataNs) +#define IEDMODEL_GenericIO_TIM_GAPC1_RsDlTmms (&iedModel_GenericIO_TIM_GAPC1_RsDlTmms) +#define IEDMODEL_GenericIO_TIM_GAPC1_RsDlTmms_setVal (&iedModel_GenericIO_TIM_GAPC1_RsDlTmms_setVal) +#define IEDMODEL_GenericIO_TIM_GAPC1_RsDlTmms_dataNs (&iedModel_GenericIO_TIM_GAPC1_RsDlTmms_dataNs) +#define IEDMODEL_GenericIO_TIM_GAPC1_OpCntRs (&iedModel_GenericIO_TIM_GAPC1_OpCntRs) +#define IEDMODEL_GenericIO_TIM_GAPC1_OpCntRs_stVal (&iedModel_GenericIO_TIM_GAPC1_OpCntRs_stVal) +#define IEDMODEL_GenericIO_TIM_GAPC1_OpCntRs_q (&iedModel_GenericIO_TIM_GAPC1_OpCntRs_q) +#define IEDMODEL_GenericIO_TIM_GAPC1_OpCntRs_t (&iedModel_GenericIO_TIM_GAPC1_OpCntRs_t) +#define IEDMODEL_GenericIO_TIM_GAPC1_OpCntRs_Oper (&iedModel_GenericIO_TIM_GAPC1_OpCntRs_Oper) +#define IEDMODEL_GenericIO_TIM_GAPC1_OpCntRs_Oper_ctlVal (&iedModel_GenericIO_TIM_GAPC1_OpCntRs_Oper_ctlVal) +#define IEDMODEL_GenericIO_TIM_GAPC1_OpCntRs_Oper_origin (&iedModel_GenericIO_TIM_GAPC1_OpCntRs_Oper_origin) +#define IEDMODEL_GenericIO_TIM_GAPC1_OpCntRs_Oper_origin_orCat (&iedModel_GenericIO_TIM_GAPC1_OpCntRs_Oper_origin_orCat) +#define IEDMODEL_GenericIO_TIM_GAPC1_OpCntRs_Oper_origin_orIdent (&iedModel_GenericIO_TIM_GAPC1_OpCntRs_Oper_origin_orIdent) +#define IEDMODEL_GenericIO_TIM_GAPC1_OpCntRs_Oper_ctlNum (&iedModel_GenericIO_TIM_GAPC1_OpCntRs_Oper_ctlNum) +#define IEDMODEL_GenericIO_TIM_GAPC1_OpCntRs_Oper_T (&iedModel_GenericIO_TIM_GAPC1_OpCntRs_Oper_T) +#define IEDMODEL_GenericIO_TIM_GAPC1_OpCntRs_Oper_Test (&iedModel_GenericIO_TIM_GAPC1_OpCntRs_Oper_Test) +#define IEDMODEL_GenericIO_TIM_GAPC1_OpCntRs_Oper_Check (&iedModel_GenericIO_TIM_GAPC1_OpCntRs_Oper_Check) +#define IEDMODEL_GenericIO_TIM_GAPC1_OpCntRs_ctlModel (&iedModel_GenericIO_TIM_GAPC1_OpCntRs_ctlModel) #endif /* STATIC_MODEL_H_ */ From 2daa5fdec4ce0e1d9862c0965bf20458276f418c Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Tue, 13 Oct 2015 14:54:36 +0200 Subject: [PATCH 13/14] - changed server side getFileDirectory service to return flat file directory --- CHANGELOG | 2 + src/goose/goose_publisher.c | 2 +- .../filesystem/linux/file_provider_linux.c | 2 +- .../filesystem/win32/file_provider_win32.c | 2 +- src/hal/inc/hal_filesystem.h | 4 + src/mms/iso_mms/server/mms_file_service.c | 150 +++++++++--------- 6 files changed, 84 insertions(+), 78 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 9b7a70c8..250f33e6 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,7 @@ Changes to version 0.8.7 ------------------------ +- extended beoglebone demo (write access to GAPC settings, ...) +- File service: support for wildcard character ('*') in requests - server: changed signature of WriteAccessHandler: Handler now return MmsDataAccessError instead of boolean value! - server: added function IedModel_setIedNameForDynamicModel diff --git a/src/goose/goose_publisher.c b/src/goose/goose_publisher.c index cea381c4..47b85995 100644 --- a/src/goose/goose_publisher.c +++ b/src/goose/goose_publisher.c @@ -201,7 +201,7 @@ prepareGooseBuffer(GoosePublisher self, CommParameters* parameters, const char* int bufPos = 12; -#if 0 +#if 1 /* Priority tag - IEEE 802.1Q */ self->buffer[bufPos++] = 0x81; self->buffer[bufPos++] = 0x00; diff --git a/src/hal/filesystem/linux/file_provider_linux.c b/src/hal/filesystem/linux/file_provider_linux.c index 1f0e2885..c973dd2a 100644 --- a/src/hal/filesystem/linux/file_provider_linux.c +++ b/src/hal/filesystem/linux/file_provider_linux.c @@ -123,7 +123,7 @@ FileSystem_getFileInfo(char* filename, uint32_t* fileSize, uint64_t* lastModific { struct stat fileStats; - char fullPath[sizeof(CONFIG_VIRTUAL_FILESTORE_BASEPATH) + 255]; + char fullPath[sizeof(CONFIG_VIRTUAL_FILESTORE_BASEPATH) + 256]; createFullPathFromFileName(fullPath, filename); diff --git a/src/hal/filesystem/win32/file_provider_win32.c b/src/hal/filesystem/win32/file_provider_win32.c index 662f5439..8df94e58 100644 --- a/src/hal/filesystem/win32/file_provider_win32.c +++ b/src/hal/filesystem/win32/file_provider_win32.c @@ -96,7 +96,7 @@ FileSystem_closeFile(FileHandle handle) bool FileSystem_getFileInfo(char* filename, uint32_t* fileSize, uint64_t* lastModificationTimestamp) { - char fullPath[sizeof(CONFIG_VIRTUAL_FILESTORE_BASEPATH) + 255]; + char fullPath[sizeof(CONFIG_VIRTUAL_FILESTORE_BASEPATH) + 256]; createFullPathFromFileName(fullPath, filename); diff --git a/src/hal/inc/hal_filesystem.h b/src/hal/inc/hal_filesystem.h index 10272958..f18f6745 100644 --- a/src/hal/inc/hal_filesystem.h +++ b/src/hal/inc/hal_filesystem.h @@ -133,6 +133,10 @@ FileSystem_openDirectory(char* directoryName); /** * \brief read the next directory entry * + * This function returns the next directory entry. The entry is only a valid pointer as long as the + * FileSystem_closeDirectory or another FileSystem_readDirectory function is not called for the given + * DirectoryHandle. + * * \param directory the handle to identify the directory * \param isDirectory return value that indicates if the directory entry is itself a directory (true) * diff --git a/src/mms/iso_mms/server/mms_file_service.c b/src/mms/iso_mms/server/mms_file_service.c index 4ee6f93f..4f2b63ec 100644 --- a/src/mms/iso_mms/server/mms_file_service.c +++ b/src/mms/iso_mms/server/mms_file_service.c @@ -214,11 +214,11 @@ mmsServer_handleFileDeleteRequest( filename[length] = 0; if (DEBUG_MMS_SERVER) - printf("mms_file_service.c: Delete file (%s)\n", filename); + printf("MMS_SERVER: mms_file_service.c: Delete file (%s)\n", filename); if (!FileSystem_getFileInfo(filename, NULL, NULL)) { if (DEBUG_MMS_SERVER) - printf("mms_file_service.c: File (%s) not found\n", filename); + printf("MMS_SERVER: mms_file_service.c: File (%s) not found\n", filename); mmsServer_createConfirmedErrorPdu(invokeId, response, MMS_ERROR_FILE_FILE_NON_EXISTENT); return; @@ -226,7 +226,7 @@ mmsServer_handleFileDeleteRequest( if (!FileSystem_deleteFile(filename)) { if (DEBUG_MMS_SERVER) - printf("mms_file_service.c: Delete file (%s) failed\n", filename); + printf("MMS_SERVER: mms_file_service.c: Delete file (%s) failed\n", filename); mmsServer_createConfirmedErrorPdu(invokeId, response, MMS_ERROR_FILE_FILE_ACCESS_DENIED); return; @@ -381,7 +381,7 @@ mmsServer_handleFileReadRequest( int32_t frsmId = (int32_t) BerDecoder_decodeUint32(buffer, maxBufPos - bufPos, bufPos); if (DEBUG_MMS_SERVER) - printf("mmsServer_handleFileReadRequest read request for frsmId: %i\n", frsmId); + printf("MMS_SERVER: mmsServer_handleFileReadRequest read request for frsmId: %i\n", frsmId); MmsFileReadStateMachine* frsm = getFrsm(connection, frsmId); @@ -436,107 +436,106 @@ encodeFileSpecification(uint8_t tag, char* fileSpecification, uint8_t* buffer, i } } - - -static void -createFileDirectoryResponse(uint32_t invokeId, ByteBuffer* response, char* directoryName, char* continueAfterFileName) +static int +addFileEntriesToResponse(uint8_t* buffer, int bufPos, int maxBufSize, char* directoryName, char* continueAfterFileName, bool* moreFollows) { - int maxSize = response->maxSize - 3; /* reserve space for moreFollows */ - uint8_t* buffer = response->buffer; - - bool moreFollows = false; - - int tempStartPos = 30; /* estimated header part with safety margin */ - int tempCurPos = tempStartPos; - int tempEncoded = 0; - - char extendedFileName[300]; + int directoryNameLength = strlen(directoryName); DirectoryHandle directory = FileSystem_openDirectory(directoryName); - if (continueAfterFileName != NULL) { - if (strlen(continueAfterFileName) == 0) - continueAfterFileName = NULL; - } - if (directory != NULL) { bool isDirectory; char* fileName = FileSystem_readDirectory(directory, &isDirectory); while (fileName != NULL) { - if (isDirectory) { - strcpy(extendedFileName, fileName); - strcat(extendedFileName, "/"); - - fileName = extendedFileName; - } + directoryName[directoryNameLength] = 0; - if (continueAfterFileName != NULL) { - if (strcmp(continueAfterFileName, fileName) == 0) - continueAfterFileName = NULL; - } - else { - uint64_t msTime; + if (directoryNameLength > 0) + strcat(directoryName, "/"); - char fullPath[CONFIG_MMS_FILE_SERVICE_MAX_FILENAME_LENGTH]; + strcat(directoryName, fileName); - if (directoryName != NULL) { - int directoryLen = strlen(directoryName); + if (isDirectory) { + bufPos = addFileEntriesToResponse(buffer, bufPos, maxBufSize, directoryName, continueAfterFileName, moreFollows); - strcpy(fullPath, directoryName); + if (*moreFollows == true) + break; + } + else { + if (continueAfterFileName != NULL) { + if (strcmp(continueAfterFileName, directoryName) == 0) + continueAfterFileName = NULL; + } + else { + uint64_t msTime; - if (directoryName[directoryLen - 1] != CONFIG_SYSTEM_FILE_SEPARATOR) { - fullPath[directoryLen] = CONFIG_SYSTEM_FILE_SEPARATOR; - fullPath[directoryLen + 1] = 0; - } + uint32_t fileSize; - strcat(fullPath, fileName); - } - else { - strncpy(fullPath, fileName, CONFIG_MMS_FILE_SERVICE_MAX_FILENAME_LENGTH - 1); - fullPath[CONFIG_MMS_FILE_SERVICE_MAX_FILENAME_LENGTH - 1] = 0; - } + FileSystem_getFileInfo(directoryName, &fileSize, &msTime); - uint32_t fileSize; + char gtString[30]; - FileSystem_getFileInfo(fullPath, &fileSize, &msTime); + Conversions_msTimeToGeneralizedTime(msTime, (uint8_t*) gtString); - char gtString[30]; + int fileAttributesSize = encodeFileAttributes(0xa1, fileSize, gtString, NULL, 0); - Conversions_msTimeToGeneralizedTime(msTime, (uint8_t*) gtString); + int filenameSize = encodeFileSpecification(0xa0, directoryName, NULL, 0); - int fileAttributesSize = encodeFileAttributes(0xa1, fileSize, gtString, NULL, 0); + int dirEntrySize = 2 + fileAttributesSize + filenameSize; - int filenameSize = encodeFileSpecification(0xa0, fileName, NULL, 0); + int overallEntrySize = 1 + BerEncoder_determineLengthSize(dirEntrySize) + dirEntrySize; - int dirEntrySize = 2 + fileAttributesSize + filenameSize; + int bufferSpaceLeft = maxBufSize - bufPos; - int overallEntrySize = 1 + BerEncoder_determineLengthSize(dirEntrySize) + dirEntrySize; + if (overallEntrySize > bufferSpaceLeft) { - int bufferSpaceLeft = maxSize - tempCurPos; + *moreFollows = true; + break; + } - if (overallEntrySize > bufferSpaceLeft) { - moreFollows = true; - break; - } + bufPos = BerEncoder_encodeTL(0x30, dirEntrySize, buffer, bufPos); /* SEQUENCE (DirectoryEntry) */ + bufPos = encodeFileSpecification(0xa0, directoryName, buffer, bufPos); /* fileName */ + bufPos = encodeFileAttributes(0xa1, fileSize, gtString, buffer, bufPos); /* file attributes */ - tempCurPos = BerEncoder_encodeTL(0x30, dirEntrySize, buffer, tempCurPos); /* SEQUENCE (DirectoryEntry) */ - tempCurPos = encodeFileSpecification(0xa0, fileName, buffer, tempCurPos); /* fileName */ - tempCurPos = encodeFileAttributes(0xa1, fileSize, gtString, buffer, tempCurPos); /* file attributes */ + } } + fileName = FileSystem_readDirectory(directory, &isDirectory); } FileSystem_closeDirectory(directory); } - else { - //TODO check if it is a directory + directoryName[directoryNameLength] = 0; + + return bufPos; +} + +static void +createFileDirectoryResponse(uint32_t invokeId, ByteBuffer* response, char* directoryName, char* continueAfterFileName) +{ + int maxSize = response->maxSize - 3; /* reserve space for moreFollows */ + uint8_t* buffer = response->buffer; + + bool moreFollows = false; + + int tempStartPos = 30; /* estimated header part with safety margin */ + int tempCurPos = tempStartPos; + int tempEncoded = 0; + + if (continueAfterFileName != NULL) { + if (strlen(continueAfterFileName) == 0) + continueAfterFileName = NULL; + } + + tempCurPos = addFileEntriesToResponse(buffer, tempCurPos, maxSize, directoryName, continueAfterFileName, &moreFollows); + + if (tempCurPos < 0) { if (DEBUG_MMS_SERVER) - printf("Error opening directory!\n"); + printf("MMS_SERVER: Error opening directory!\n"); mmsServer_createConfirmedErrorPdu(invokeId, response, MMS_ERROR_FILE_FILE_NON_EXISTENT); @@ -611,7 +610,7 @@ mmsServer_handleFileRenameRequest( return; if (DEBUG_MMS_SERVER) - printf("currentFileName: (%s)\n", currentFileName); + printf("MMS_SERVER: currentFileName: (%s)\n", currentFileName); break; @@ -620,12 +619,12 @@ mmsServer_handleFileRenameRequest( return; if (DEBUG_MMS_SERVER) - printf("newFileName: (%s)\n", newFileName); + printf("MMS_SERVER: newFileName: (%s)\n", newFileName); break; default: /* ignore unknown tag */ if (DEBUG_MMS_SERVER) - printf("unknown tag: (%02x)\n", tag); + printf("MMS_SERVER: unknown tag: (%02x)\n", tag); bufPos += length; break; @@ -640,7 +639,7 @@ mmsServer_handleFileRenameRequest( else { if (DEBUG_MMS_SERVER) - printf("rename file failed!\n"); + printf("MMS_SERVER: rename file failed!\n"); mmsServer_createConfirmedErrorPdu(invokeId, response, MMS_ERROR_FILE_OTHER); } @@ -658,7 +657,7 @@ mmsServer_handleFileDirectoryRequest( ByteBuffer* response) { if (DEBUG_MMS_SERVER) - printf("handleFileDirectoryRequest bufPos:%i, maxBufPus:%i\n", bufPos, maxBufPos); + printf("MMS_SERVER: handleFileDirectoryRequest bufPos:%i, maxBufPus:%i\n", bufPos, maxBufPos); char filename[256] = ""; @@ -683,7 +682,8 @@ mmsServer_handleFileDirectoryRequest( return; /* check for wildcard character(*) */ - if (strcmp(filename, "*") == 0) filename[0] = 0; + if ((strcmp(filename, "*") == 0) || (strcmp(filename, "/") == 0) || (strcmp(filename, "\\") == 0)) + filename[0] = 0; break; @@ -697,7 +697,7 @@ mmsServer_handleFileDirectoryRequest( default: /* unrecognized parameter */ if (DEBUG_MMS_SERVER) - printf("handleFileDirectoryRequest: unrecognized parameter\n"); + printf("MMS_SERVER: handleFileDirectoryRequest: unrecognized parameter\n"); mmsServer_writeMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_INVALID_PDU, response); return; } From e0a60e6591add656bac2ca064b472e54020be610 Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Thu, 15 Oct 2015 13:20:30 +0200 Subject: [PATCH 14/14] - added missing error evaluation in client getNameList service --- src/mms/iso_mms/client/mms_client_connection.c | 5 +++-- src/mms/iso_mms/server/mms_file_service.c | 1 - 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mms/iso_mms/client/mms_client_connection.c b/src/mms/iso_mms/client/mms_client_connection.c index 90455d98..c91005cd 100644 --- a/src/mms/iso_mms/client/mms_client_connection.c +++ b/src/mms/iso_mms/client/mms_client_connection.c @@ -1058,11 +1058,12 @@ mmsClient_getNameListSingleRequest( ByteBuffer* responseMessage = sendRequestAndWaitForResponse(self, invokeId, payload); - - if (responseMessage != NULL) moreFollows = mmsClient_parseGetNameListResponse(nameList, self->lastResponse, NULL); + if (self->lastResponseError != MMS_ERROR_NONE) + *mmsError = self->lastResponseError; + releaseResponse(self); if (self->associationState == MMS_STATE_CLOSED) diff --git a/src/mms/iso_mms/server/mms_file_service.c b/src/mms/iso_mms/server/mms_file_service.c index 4f2b63ec..d0780fb3 100644 --- a/src/mms/iso_mms/server/mms_file_service.c +++ b/src/mms/iso_mms/server/mms_file_service.c @@ -488,7 +488,6 @@ addFileEntriesToResponse(uint8_t* buffer, int bufPos, int maxBufSize, char* dire int bufferSpaceLeft = maxBufSize - bufPos; if (overallEntrySize > bufferSpaceLeft) { - *moreFollows = true; break; }