iec61850_model.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650
  1. /*
  2. * model.h
  3. *
  4. * Copyright 2013-2016 Michael Zillgith
  5. *
  6. * This file is part of libIEC61850.
  7. *
  8. * libIEC61850 is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation, either version 3 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * libIEC61850 is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with libIEC61850. If not, see <http://www.gnu.org/licenses/>.
  20. *
  21. * See COPYING file for the complete license text.
  22. */
  23. #ifndef MODEL_H_
  24. #define MODEL_H_
  25. #include "iec61850_common.h"
  26. #ifdef __cplusplus
  27. extern "C" {
  28. #endif
  29. /** \addtogroup server_api_group
  30. * @{
  31. */
  32. /**
  33. * @defgroup DATA_MODEL General data model definitions, access and iteration functions
  34. *
  35. * @{
  36. */
  37. /**
  38. * \brief abstract base type for IEC 61850 data model nodes
  39. */
  40. typedef struct sModelNode ModelNode;
  41. /**
  42. * \brief IEC 61850 data model element of type data attribute
  43. */
  44. typedef struct sDataAttribute DataAttribute;
  45. /**
  46. * \brief IEC 61850 data model element of type data object
  47. */
  48. typedef struct sDataObject DataObject;
  49. /**
  50. * \brief IEC 61850 data model element of type logical node
  51. */
  52. typedef struct sLogicalNode LogicalNode;
  53. /**
  54. * \brief IEC 61850 data model element of type logical device
  55. */
  56. typedef struct sLogicalDevice LogicalDevice;
  57. /**
  58. * \brief Root node of the IEC 61850 data model. This is usually created by the model generator tool (genmodel.jar)
  59. */
  60. typedef struct sIedModel IedModel;
  61. typedef struct sDataSet DataSet;
  62. typedef struct sReportControlBlock ReportControlBlock;
  63. /**
  64. * \brief IEC 61850 data model of setting group control block (SGCB)
  65. */
  66. typedef struct sSettingGroupControlBlock SettingGroupControlBlock;
  67. typedef struct sGSEControlBlock GSEControlBlock;
  68. typedef struct sSVControlBlock SVControlBlock;
  69. typedef struct sLogControlBlock LogControlBlock;
  70. typedef struct sLog Log;
  71. typedef enum {
  72. IEC61850_UNKNOWN_TYPE = -1,
  73. IEC61850_BOOLEAN = 0,/* int */
  74. IEC61850_INT8 = 1, /* int8_t */
  75. IEC61850_INT16 = 2, /* int16_t */
  76. IEC61850_INT32 = 3, /* int32_t */
  77. IEC61850_INT64 = 4, /* int64_t */
  78. IEC61850_INT128 = 5, /* no native mapping! */
  79. IEC61850_INT8U = 6, /* uint8_t */
  80. IEC61850_INT16U = 7, /* uint16_t */
  81. IEC61850_INT24U = 8, /* uint32_t */
  82. IEC61850_INT32U = 9, /* uint32_t */
  83. IEC61850_FLOAT32 = 10, /* float */
  84. IEC61850_FLOAT64 = 11, /* double */
  85. IEC61850_ENUMERATED = 12,
  86. IEC61850_OCTET_STRING_64 = 13,
  87. IEC61850_OCTET_STRING_6 = 14,
  88. IEC61850_OCTET_STRING_8 = 15,
  89. IEC61850_VISIBLE_STRING_32 = 16,
  90. IEC61850_VISIBLE_STRING_64 = 17,
  91. IEC61850_VISIBLE_STRING_65 = 18,
  92. IEC61850_VISIBLE_STRING_129 = 19,
  93. IEC61850_VISIBLE_STRING_255 = 20,
  94. IEC61850_UNICODE_STRING_255 = 21,
  95. IEC61850_TIMESTAMP = 22,
  96. IEC61850_QUALITY = 23,
  97. IEC61850_CHECK = 24,
  98. IEC61850_CODEDENUM = 25,
  99. IEC61850_GENERIC_BITSTRING = 26,
  100. IEC61850_CONSTRUCTED = 27,
  101. IEC61850_ENTRY_TIME = 28,
  102. IEC61850_PHYCOMADDR = 29,
  103. IEC61850_CURRENCY = 30,
  104. IEC61850_OPTFLDS = 31, /* bit-string(10) */
  105. IEC61850_TRGOPS = 32 /* bit-string(6) */
  106. #if (CONFIG_IEC61850_USE_COMPAT_TYPE_DECLARATIONS == 1)
  107. ,
  108. BOOLEAN = 0,/* int */
  109. INT8 = 1, /* int8_t */
  110. INT16 = 2, /* int16_t */
  111. INT32 = 3, /* int32_t */
  112. INT64 = 4, /* int64_t */
  113. INT128 = 5, /* no native mapping! */
  114. INT8U = 6, /* uint8_t */
  115. INT16U = 7, /* uint16_t */
  116. INT24U = 8, /* uint32_t */
  117. INT32U = 9, /* uint32_t */
  118. FLOAT32 = 10, /* float */
  119. FLOAT64 = 11, /* double */
  120. ENUMERATED = 12,
  121. OCTET_STRING_64 = 13,
  122. OCTET_STRING_6 = 14,
  123. OCTET_STRING_8 = 15,
  124. VISIBLE_STRING_32 = 16,
  125. VISIBLE_STRING_64 = 17,
  126. VISIBLE_STRING_65 = 18,
  127. VISIBLE_STRING_129 = 19,
  128. VISIBLE_STRING_255 = 20,
  129. UNICODE_STRING_255 = 21,
  130. TIMESTAMP = 22,
  131. QUALITY = 23,
  132. CHECK = 24,
  133. CODEDENUM = 25,
  134. GENERIC_BITSTRING = 26,
  135. CONSTRUCTED = 27,
  136. ENTRY_TIME = 28,
  137. PHYCOMADDR = 29,
  138. CURRENCY = 30
  139. OPTFLDS = 31,
  140. TRGOPS = 32
  141. #endif
  142. } DataAttributeType;
  143. typedef enum {
  144. LogicalDeviceModelType,
  145. LogicalNodeModelType,
  146. DataObjectModelType,
  147. DataAttributeModelType
  148. } ModelNodeType;
  149. struct sIedModel {
  150. char* name;
  151. LogicalDevice* firstChild;
  152. DataSet* dataSets;
  153. ReportControlBlock* rcbs;
  154. GSEControlBlock* gseCBs;
  155. SVControlBlock* svCBs;
  156. SettingGroupControlBlock* sgcbs;
  157. LogControlBlock* lcbs;
  158. Log* logs;
  159. void (*initializer) (void);
  160. };
  161. struct sLogicalDevice {
  162. ModelNodeType modelType;
  163. char* name;
  164. ModelNode* parent;
  165. ModelNode* sibling;
  166. ModelNode* firstChild;
  167. };
  168. struct sModelNode {
  169. ModelNodeType modelType;
  170. char* name;
  171. ModelNode* parent;
  172. ModelNode* sibling;
  173. ModelNode* firstChild;
  174. };
  175. struct sLogicalNode {
  176. ModelNodeType modelType;
  177. char* name;
  178. ModelNode* parent;
  179. ModelNode* sibling;
  180. ModelNode* firstChild;
  181. };
  182. struct sDataObject {
  183. ModelNodeType modelType;
  184. char* name;
  185. ModelNode* parent;
  186. ModelNode* sibling;
  187. ModelNode* firstChild;
  188. int elementCount; /* > 0 if this is an array */
  189. };
  190. struct sDataAttribute {
  191. ModelNodeType modelType;
  192. char* name;
  193. ModelNode* parent;
  194. ModelNode* sibling;
  195. ModelNode* firstChild;
  196. int elementCount; /* > 0 if this is an array */
  197. FunctionalConstraint fc;
  198. DataAttributeType type;
  199. uint8_t triggerOptions; /* TRG_OPT_DATA_CHANGED | TRG_OPT_QUALITY_CHANGED | TRG_OPT_DATA_UPDATE */
  200. MmsValue* mmsValue;
  201. uint32_t sAddr;
  202. };
  203. typedef struct sDataSetEntry {
  204. char* logicalDeviceName;
  205. bool isLDNameDynamicallyAllocated;
  206. char* variableName;
  207. int index;
  208. char* componentName;
  209. MmsValue* value;
  210. struct sDataSetEntry* sibling;
  211. } DataSetEntry;
  212. struct sDataSet {
  213. char* logicalDeviceName;
  214. char* name; /* eg. MMXU1$dataset1 */
  215. int elementCount;
  216. DataSetEntry* fcdas;
  217. DataSet* sibling;
  218. };
  219. struct sReportControlBlock {
  220. LogicalNode* parent;
  221. char* name;
  222. char* rptId;
  223. bool buffered;
  224. char* dataSetName; /* pre loaded with relative name in logical node */
  225. uint32_t confRef; /* ConfRef - configuration revision */
  226. uint8_t trgOps; /* TrgOps - trigger conditions */
  227. uint8_t options; /* OptFlds */
  228. uint32_t bufferTime; /* BufTm - time to buffer events until a report is generated */
  229. uint32_t intPeriod; /* IntgPd - integrity period */
  230. /* type (first byte) and address of the pre-configured client
  231. type can be one of (0 - no reservation, 4 - IPv4 client, 6 - IPv6 client) */
  232. uint8_t clientReservation[17];
  233. ReportControlBlock* sibling; /* next control block in list or NULL if this is the last entry
  234. * at runtime reuse as pointer to ReportControl instance!
  235. **/
  236. };
  237. struct sLogControlBlock {
  238. LogicalNode* parent;
  239. char* name;
  240. char* dataSetName;
  241. char* logRef; /* object reference to the journal */
  242. uint8_t trgOps; /* TrgOps - trigger conditions */
  243. uint32_t intPeriod; /* IntgPd - integrity period */
  244. bool logEna; /* enable log by default */
  245. bool reasonCode; /* include reason code in log */
  246. LogControlBlock* sibling; /* next control block in list or NULL if this is the last entry */
  247. };
  248. struct sLog {
  249. LogicalNode* parent;
  250. char* name;
  251. Log* sibling; /* next log instance in list or NULL if this is the last entry */
  252. };
  253. struct sSettingGroupControlBlock {
  254. LogicalNode* parent;
  255. uint8_t actSG; /* value from SCL file */
  256. uint8_t numOfSGs; /* value from SCL file */
  257. uint8_t editSG; /* 0 at power-up */
  258. bool cnfEdit; /* false at power-up */
  259. uint64_t timestamp;
  260. uint16_t resvTms;
  261. SettingGroupControlBlock* sibling; /* next control block in list or NULL if this is the last entry */
  262. };
  263. struct sGSEControlBlock {
  264. LogicalNode* parent;
  265. char* name;
  266. char* appId;
  267. char* dataSetName; /* pre loaded with relative name in logical node */
  268. uint32_t confRev; /* ConfRev - configuration revision */
  269. bool fixedOffs; /* fixed offsets */
  270. PhyComAddress* address; /* GSE communication parameters */
  271. int minTime; /* optional minTime parameter --> -1 if not present */
  272. int maxTime; /* optional maxTime parameter --> -1 if not present */
  273. GSEControlBlock* sibling; /* next control block in list or NULL if this is the last entry */
  274. };
  275. struct sSVControlBlock {
  276. LogicalNode* parent;
  277. char* name;
  278. char* svId; /* MsvUD/UsvID */
  279. char* dataSetName; /* pre loaded with relative name in logical node */
  280. uint8_t optFlds;
  281. uint8_t smpMod;
  282. uint16_t smpRate;
  283. uint32_t confRev; /* ConfRev - configuration revision */
  284. PhyComAddress* dstAddress; /* SV communication parameters */
  285. bool isUnicast;
  286. int noASDU;
  287. SVControlBlock* sibling; /* next control block in list or NULL if this is the last entry */
  288. };
  289. /**
  290. * \brief get the number of direct children of a model node
  291. *
  292. * \param self the model node instance
  293. *
  294. * \return the number of children of the model node
  295. * ¸
  296. */
  297. LIB61850_API int
  298. ModelNode_getChildCount(ModelNode* self);
  299. /**
  300. * \brief return a child model node
  301. *
  302. * \param self the model node instance
  303. * \param name the name of the child model node
  304. *
  305. * \return the model node instance or NULL if model node does not exist.
  306. */
  307. LIB61850_API ModelNode*
  308. ModelNode_getChild(ModelNode* self, const char* name);
  309. /**
  310. * \brief return a child model node with a given functional constraint
  311. *
  312. * Sometimes the name is not enough to identify a model node. This is the case when
  313. * editable setting groups are used. In this case the setting group members have two different
  314. * model nodes associated that differ in their FC (SG and SE).
  315. *
  316. * \param self the model node instance
  317. * \param name the name of the child model node
  318. * \param fc the functional constraint of the model node
  319. *
  320. * \return the model node instance or NULL if model node does not exist.
  321. */
  322. LIB61850_API ModelNode*
  323. ModelNode_getChildWithFc(ModelNode* self, const char* name, FunctionalConstraint fc);
  324. /**
  325. * \brief Return the IEC 61850 object reference of a model node
  326. *
  327. * \param self the model node instance
  328. * \param objectReference pointer to a buffer where to write the object reference string. If NULL
  329. * is given the buffer is allocated by the function.
  330. *
  331. * \return the object reference string
  332. */
  333. LIB61850_API char*
  334. ModelNode_getObjectReference(ModelNode* self, char* objectReference);
  335. /**
  336. * \brief Return the IEC 61850 object reference of a model node
  337. *
  338. * \param self the model node instance
  339. * \param objectReference pointer to a buffer where to write the object reference string. If NULL
  340. * is given the buffer is allocated by the function.
  341. * \param withoutIedName create object reference without IED name part
  342. *
  343. * \return the object reference string
  344. */
  345. LIB61850_API char*
  346. ModelNode_getObjectReferenceEx(ModelNode* node, char* objectReference, bool withoutIedName);
  347. /**
  348. * \brief Get the type of the ModelNode
  349. *
  350. * \param self the ModelNode instance
  351. *
  352. * \return the type of the ModelNode (one of LD, LN, DO, DA)
  353. */
  354. LIB61850_API ModelNodeType
  355. ModelNode_getType(ModelNode* self);
  356. /**
  357. * \brief Get the name of the ModelNode
  358. *
  359. * \param self the ModelNode instance
  360. *
  361. * \return the name of the ModelNode
  362. */
  363. LIB61850_API const char*
  364. ModelNode_getName(ModelNode* self);
  365. /**
  366. * \brief Get the parent ModelNode of this ModelNode instance
  367. *
  368. * \param self the ModelNode instance
  369. *
  370. * \return the parent instance, or NULL when the ModelNode has no parent
  371. */
  372. LIB61850_API ModelNode*
  373. ModelNode_getParent(ModelNode* self);
  374. /**
  375. * \brief Get the list of direct child nodes
  376. *
  377. * \param self the ModelNode instance
  378. *
  379. * \return the list of private child nodes, or NULL when the node has no children
  380. */
  381. LIB61850_API LinkedList
  382. ModelNode_getChildren(ModelNode* self);
  383. /**
  384. * \brief Set the name of the IED
  385. *
  386. * This will change the default name (usualy "TEMPLATE") to a user configured values.
  387. * NOTE: This function has to be called before IedServer_create !
  388. *
  389. * \param model the IedModel instance
  390. * \param the name of the configured IED
  391. */
  392. LIB61850_API void
  393. IedModel_setIedName(IedModel* self, const char* iedName);
  394. /**
  395. * \brief Lookup a model node by its object reference
  396. *
  397. * This function uses the full logical device name as part of the object reference
  398. * as it happens to appear on the wire. E.g. if IED name in SCL file would be "IED1"
  399. * and the logical device "WD1" the resulting LD name would be "IED1WD".
  400. *
  401. * \param self the IedModel instance that holds the model node
  402. * \param objectReference the IEC 61850 object reference
  403. *
  404. * \return the model node instance or NULL if model node does not exist.
  405. */
  406. LIB61850_API ModelNode*
  407. IedModel_getModelNodeByObjectReference(IedModel* self, const char* objectReference);
  408. LIB61850_API SVControlBlock*
  409. IedModel_getSVControlBlock(IedModel* self, LogicalNode* parentLN, const char* svcbName);
  410. /**
  411. * \brief Lookup a model node by its short (normalized) reference
  412. *
  413. * This version uses the object reference that does not contain the
  414. * IED name as part of the logical device name. This function is useful for
  415. * devices where the IED name can be configured.
  416. *
  417. * \param self the IedModel instance that holds the model node
  418. * \param objectReference the IEC 61850 object reference
  419. *
  420. * \return the model node instance or NULL if model node does not exist.
  421. */
  422. LIB61850_API ModelNode*
  423. IedModel_getModelNodeByShortObjectReference(IedModel* self, const char* objectReference);
  424. /**
  425. * \brief Lookup a model node by its short address
  426. *
  427. * Short address is a 32 bit unsigned integer as specified in the "sAddr" attribute of
  428. * the ICD file or in the configuration file.
  429. *
  430. * \param self the IedModel instance that holds the model node
  431. * \param shortAddress
  432. *
  433. * \return the model node instance or NULL if model node does not exist.
  434. */
  435. LIB61850_API ModelNode*
  436. IedModel_getModelNodeByShortAddress(IedModel* self, uint32_t shortAddress);
  437. /**
  438. * \brief Lookup logical device (LD) by device instance name (SCL attribute "inst")
  439. *
  440. * \param self IedModel instance
  441. * \param ldInst the logical device instance name (SCL attribute "inst")
  442. *
  443. * \return The matching LogicalDevice instance
  444. */
  445. LIB61850_API LogicalDevice*
  446. IedModel_getDeviceByInst(IedModel* self, const char* ldInst);
  447. /**
  448. * \brief Lookup logical device (LD) instance by index
  449. *
  450. * \param self IedModel instance
  451. * \param index the index of the LD in the range (0 .. number of LDs - 1)
  452. *
  453. * \return the corresponding LogicalDevice* object or NULL if the index is out of range
  454. */
  455. LIB61850_API LogicalDevice*
  456. IedModel_getDeviceByIndex(IedModel* self, int index);
  457. /**
  458. * \brief Lookup a logical node by name that is part of the given logical device
  459. *
  460. * \param device the logical device instance
  461. * \param lnName the logical node name
  462. *
  463. * \return the logical device instance or NULL if it does not exist
  464. */
  465. LIB61850_API LogicalNode*
  466. LogicalDevice_getLogicalNode(LogicalDevice* self, const char* lnName);
  467. /**
  468. * \brief Get the setting group control block (SGCB) of the logical device
  469. *
  470. * \param device the logical device instance
  471. *
  472. * \return the SGCB instance or NULL if no SGCB is available
  473. */
  474. LIB61850_API SettingGroupControlBlock*
  475. LogicalDevice_getSettingGroupControlBlock(LogicalDevice* self);
  476. /**@}*/
  477. /**@}*/
  478. /**
  479. * \brief unset all MmsValue references in the data model
  480. *
  481. * \param self the IedModel instance that holds the model node
  482. */
  483. LIB61850_API void
  484. IedModel_setAttributeValuesToNull(IedModel* self);
  485. /**
  486. * \brief Lookup logical device (LD) by device name
  487. *
  488. * \param self IedModel instance
  489. * \param ldInst the logical device name (as it is seen from the protocol side - MMS domain name)
  490. *
  491. * \return The matching LogicalDevice instance
  492. */
  493. LIB61850_API LogicalDevice*
  494. IedModel_getDevice(IedModel* self, const char* ldName);
  495. /**
  496. * \brief Lookup a data set in the IED model
  497. *
  498. * \param self IedModel instance
  499. * \param dataSetReference MMS mapping object reference! e.g. ied1Inverter/LLN0$dataset1
  500. *
  501. * \return The matching DataSet instance
  502. */
  503. LIB61850_API DataSet*
  504. IedModel_lookupDataSet(IedModel* self, const char* dataSetReference);
  505. /**
  506. * \brief Lookup a DataAttribute instance with the corresponding MmsValue instance
  507. *
  508. * \param self IedModel instance
  509. * \param value the MmsValue instance (from the MMS value cache)
  510. *
  511. * \return the matching DataAttribute instance
  512. */
  513. LIB61850_API DataAttribute*
  514. IedModel_lookupDataAttributeByMmsValue(IedModel* self, MmsValue* value);
  515. /**
  516. * \brief Get the number of logical devices
  517. *
  518. * \param self IedModel instance
  519. *
  520. * \return the number of logical devices
  521. */
  522. LIB61850_API int
  523. IedModel_getLogicalDeviceCount(IedModel* self);
  524. LIB61850_API int
  525. LogicalDevice_getLogicalNodeCount(LogicalDevice* self);
  526. LIB61850_API ModelNode*
  527. LogicalDevice_getChildByMmsVariableName(LogicalDevice* self, const char* mmsVariableName);
  528. LIB61850_API bool
  529. LogicalNode_hasFCData(LogicalNode* self, FunctionalConstraint fc);
  530. LIB61850_API bool
  531. LogicalNode_hasBufferedReports(LogicalNode* self);
  532. LIB61850_API bool
  533. LogicalNode_hasUnbufferedReports(LogicalNode* self);
  534. /**
  535. * \brief get a data set instance
  536. *
  537. * \param self the logical node instance of the data set
  538. * \param dataSetName the name of the data set
  539. *
  540. * \return the data set instance or NULL if the data set does not exist
  541. */
  542. LIB61850_API DataSet*
  543. LogicalNode_getDataSet(LogicalNode* self, const char* dataSetName);
  544. LIB61850_API bool
  545. DataObject_hasFCData(DataObject* self, FunctionalConstraint fc);
  546. #ifdef __cplusplus
  547. }
  548. #endif
  549. #endif /* MODEL_H_ */