nodestoreAccessExample.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393
  1. /*
  2. * nodestoreAccessExample.c
  3. *
  4. * Created on: Oct 16, 2014
  5. * Author: opcua
  6. */
  7. #include "nodestoreAccessExample.h"
  8. enum UA_AttributeId {
  9. UA_ATTRIBUTEID_NODEID = 1,
  10. UA_ATTRIBUTEID_NODECLASS = 2,
  11. UA_ATTRIBUTEID_BROWSENAME = 3,
  12. UA_ATTRIBUTEID_DISPLAYNAME = 4,
  13. UA_ATTRIBUTEID_DESCRIPTION = 5,
  14. UA_ATTRIBUTEID_WRITEMASK = 6,
  15. UA_ATTRIBUTEID_USERWRITEMASK = 7,
  16. UA_ATTRIBUTEID_ISABSTRACT = 8,
  17. UA_ATTRIBUTEID_SYMMETRIC = 9,
  18. UA_ATTRIBUTEID_INVERSENAME = 10,
  19. UA_ATTRIBUTEID_CONTAINSNOLOOPS = 11,
  20. UA_ATTRIBUTEID_EVENTNOTIFIER = 12,
  21. UA_ATTRIBUTEID_VALUE = 13,
  22. UA_ATTRIBUTEID_DATATYPE = 14,
  23. UA_ATTRIBUTEID_VALUERANK = 15,
  24. UA_ATTRIBUTEID_ARRAYDIMENSIONS = 16,
  25. UA_ATTRIBUTEID_ACCESSLEVEL = 17,
  26. UA_ATTRIBUTEID_USERACCESSLEVEL = 18,
  27. UA_ATTRIBUTEID_MINIMUMSAMPLINGINTERVAL = 19,
  28. UA_ATTRIBUTEID_HISTORIZING = 20,
  29. UA_ATTRIBUTEID_EXECUTABLE = 21,
  30. UA_ATTRIBUTEID_USEREXECUTABLE = 22
  31. };
  32. static UA_VariableNode *myNode;
  33. UA_Int32 initMyNode()
  34. {
  35. UA_ExpandedNodeId ObjId_NamespaceArray; NS0EXPANDEDNODEID(ObjId_NamespaceArray, 2255);
  36. UA_VariableNode_new(&myNode);
  37. myNode->nodeId = ObjId_NamespaceArray.nodeId;
  38. myNode->nodeClass = UA_NODECLASS_VARIABLE; //FIXME: this should go into _new?
  39. UA_QualifiedName_copycstring("myNode", &myNode->browseName);
  40. UA_LocalizedText_copycstring("myNode", &myNode->displayName);
  41. UA_LocalizedText_copycstring("myNode", &myNode->description);
  42. UA_Array_new((void **)&myNode->value.storage.data.dataPtr, 2, &UA_[UA_STRING]);
  43. myNode->value.vt = &UA_[UA_STRING];
  44. myNode->value.storage.data.arrayLength = 2;
  45. UA_String_copycstring("http://opcfoundation.org/UA/", &((UA_String *)(myNode->value.storage.data.dataPtr))[0]);
  46. UA_String_copycstring("http://localhost:16664/open62541/", &((UA_String *)(myNode->value.storage.data.dataPtr))[1]);
  47. myNode->arrayDimensionsSize = 1;
  48. UA_UInt32 *dimensions = UA_NULL;
  49. dimensions = malloc(sizeof(UA_UInt32));
  50. *dimensions = 2;
  51. myNode->arrayDimensions = dimensions;
  52. myNode->dataType = NS0NODEID(UA_STRING_NS0);
  53. myNode->valueRank = 1;
  54. myNode->minimumSamplingInterval = 1.0;
  55. myNode->historizing = UA_FALSE;
  56. return 0;
  57. }
  58. #define CHECK_NODECLASS(CLASS) \
  59. if(!(myNode->nodeClass & (CLASS))) { \
  60. v[readValueIdIndices[i]].encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE; \
  61. v[readValueIdIndices[i]].status = UA_STATUSCODE_BADNOTREADABLE; \
  62. break; \
  63. } \
  64. UA_Int32 readNodes(UA_ReadValueId * readValueIds, UA_UInt32 *readValueIdIndices, UA_UInt32 readValueIdsSize, UA_DataValue *v, UA_Boolean timeStampToReturn, UA_DiagnosticInfo *diagnosticInfo)
  65. {
  66. UA_ReadValueId *id;
  67. UA_Int32 retval = UA_SUCCESS;
  68. for(UA_UInt32 i = 0; i<readValueIdsSize; i++){
  69. id = &readValueIds[readValueIdIndices[i]];
  70. UA_DataValue_init(&v[readValueIdIndices[i]]);
  71. /*Access Node here */
  72. /* */
  73. switch(id->attributeId) {
  74. case UA_ATTRIBUTEID_NODEID:
  75. v[readValueIdIndices[i]].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
  76. retval |= UA_Variant_copySetValue(&v[readValueIdIndices[i]].value, &UA_[UA_NODEID], &myNode->nodeId);
  77. break;
  78. case UA_ATTRIBUTEID_NODECLASS:
  79. v[readValueIdIndices[i]].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
  80. retval |= UA_Variant_copySetValue(&v[readValueIdIndices[i]].value, &UA_[UA_INT32], &myNode->nodeClass);
  81. break;
  82. case UA_ATTRIBUTEID_BROWSENAME:
  83. v[readValueIdIndices[i]].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
  84. retval |= UA_Variant_copySetValue(&v[readValueIdIndices[i]].value, &UA_[UA_QUALIFIEDNAME], &myNode->browseName);
  85. break;
  86. case UA_ATTRIBUTEID_DISPLAYNAME:
  87. v[readValueIdIndices[i]].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
  88. retval |= UA_Variant_copySetValue(&v[readValueIdIndices[i]].value, &UA_[UA_LOCALIZEDTEXT],
  89. &myNode->displayName);
  90. break;
  91. case UA_ATTRIBUTEID_DESCRIPTION:
  92. v[readValueIdIndices[i]].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
  93. retval |= UA_Variant_copySetValue(&v[readValueIdIndices[i]].value, &UA_[UA_LOCALIZEDTEXT],
  94. &myNode->description);
  95. break;
  96. case UA_ATTRIBUTEID_WRITEMASK:
  97. v[readValueIdIndices[i]].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
  98. retval |= UA_Variant_copySetValue(&v[readValueIdIndices[i]].value, &UA_[UA_UINT32], &myNode->writeMask);
  99. break;
  100. case UA_ATTRIBUTEID_USERWRITEMASK:
  101. v[readValueIdIndices[i]].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
  102. retval |= UA_Variant_copySetValue(&v[readValueIdIndices[i]].value, &UA_[UA_UINT32], &myNode->userWriteMask);
  103. break;
  104. case UA_ATTRIBUTEID_ISABSTRACT:
  105. CHECK_NODECLASS(
  106. UA_NODECLASS_REFERENCETYPE | UA_NODECLASS_OBJECTTYPE | UA_NODECLASS_VARIABLETYPE |
  107. UA_NODECLASS_DATATYPE);
  108. v[readValueIdIndices[i]].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
  109. retval |=
  110. UA_Variant_copySetValue(&v[readValueIdIndices[i]].value, &UA_[UA_BOOLEAN],
  111. &((UA_ReferenceTypeNode *)myNode)->isAbstract);
  112. break;
  113. case UA_ATTRIBUTEID_SYMMETRIC:
  114. CHECK_NODECLASS(UA_NODECLASS_REFERENCETYPE);
  115. v[readValueIdIndices[i]].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
  116. retval |= UA_Variant_copySetValue(&v[readValueIdIndices[i]].value, &UA_[UA_BOOLEAN],
  117. &((UA_ReferenceTypeNode *)myNode)->symmetric);
  118. break;
  119. case UA_ATTRIBUTEID_INVERSENAME:
  120. CHECK_NODECLASS(UA_NODECLASS_REFERENCETYPE);
  121. v[readValueIdIndices[i]].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
  122. retval |= UA_Variant_copySetValue(&v[readValueIdIndices[i]].value, &UA_[UA_LOCALIZEDTEXT],
  123. &((UA_ReferenceTypeNode *)myNode)->inverseName);
  124. break;
  125. case UA_ATTRIBUTEID_CONTAINSNOLOOPS:
  126. CHECK_NODECLASS(UA_NODECLASS_VIEW);
  127. v[readValueIdIndices[i]].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
  128. retval |= UA_Variant_copySetValue(&v[readValueIdIndices[i]].value, &UA_[UA_BOOLEAN],
  129. &((UA_ViewNode *)myNode)->containsNoLoops);
  130. break;
  131. case UA_ATTRIBUTEID_EVENTNOTIFIER:
  132. CHECK_NODECLASS(UA_NODECLASS_VIEW | UA_NODECLASS_OBJECT);
  133. v[readValueIdIndices[i]].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
  134. retval |= UA_Variant_copySetValue(&v[readValueIdIndices[i]].value, &UA_[UA_BYTE],
  135. &((UA_ViewNode *)myNode)->eventNotifier);
  136. break;
  137. case UA_ATTRIBUTEID_VALUE:
  138. CHECK_NODECLASS(UA_NODECLASS_VARIABLE | UA_NODECLASS_VARIABLETYPE);
  139. v[readValueIdIndices[i]].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
  140. retval |= UA_Variant_copy(&((UA_VariableNode *)myNode)->value, &v[readValueIdIndices[i]].value); // todo: zero-copy
  141. break;
  142. case UA_ATTRIBUTEID_DATATYPE:
  143. CHECK_NODECLASS(UA_NODECLASS_VARIABLE | UA_NODECLASS_VARIABLETYPE);
  144. v[readValueIdIndices[i]].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
  145. retval |= UA_Variant_copySetValue(&v[readValueIdIndices[i]].value, &UA_[UA_NODEID],
  146. &((UA_VariableTypeNode *)myNode)->dataType);
  147. break;
  148. case UA_ATTRIBUTEID_VALUERANK:
  149. CHECK_NODECLASS(UA_NODECLASS_VARIABLE | UA_NODECLASS_VARIABLETYPE);
  150. v[readValueIdIndices[i]].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
  151. retval |= UA_Variant_copySetValue(&v[readValueIdIndices[i]].value, &UA_[UA_INT32],
  152. &((UA_VariableTypeNode *)myNode)->valueRank);
  153. break;
  154. case UA_ATTRIBUTEID_ARRAYDIMENSIONS:
  155. CHECK_NODECLASS(UA_NODECLASS_VARIABLE | UA_NODECLASS_VARIABLETYPE);
  156. v[readValueIdIndices[i]].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
  157. UA_Variant_copySetArray(&v[readValueIdIndices[i]].value, &UA_[UA_UINT32],
  158. ((UA_VariableTypeNode *)myNode)->arrayDimensionsSize,
  159. &((UA_VariableTypeNode *)myNode)->arrayDimensions);
  160. break;
  161. case UA_ATTRIBUTEID_ACCESSLEVEL:
  162. CHECK_NODECLASS(UA_NODECLASS_VARIABLE);
  163. v[readValueIdIndices[i]].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
  164. retval |= UA_Variant_copySetValue(&v[readValueIdIndices[i]].value, &UA_[UA_BYTE],
  165. &((UA_VariableNode *)myNode)->accessLevel);
  166. break;
  167. case UA_ATTRIBUTEID_USERACCESSLEVEL:
  168. CHECK_NODECLASS(UA_NODECLASS_VARIABLE);
  169. v[readValueIdIndices[i]].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
  170. retval |= UA_Variant_copySetValue(&v[readValueIdIndices[i]].value, &UA_[UA_BYTE],
  171. &((UA_VariableNode *)myNode)->userAccessLevel);
  172. break;
  173. case UA_ATTRIBUTEID_MINIMUMSAMPLINGINTERVAL:
  174. CHECK_NODECLASS(UA_NODECLASS_VARIABLE);
  175. v[readValueIdIndices[i]].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
  176. retval |= UA_Variant_copySetValue(&v[readValueIdIndices[i]].value, &UA_[UA_DOUBLE],
  177. &((UA_VariableNode *)myNode)->minimumSamplingInterval);
  178. break;
  179. case UA_ATTRIBUTEID_HISTORIZING:
  180. CHECK_NODECLASS(UA_NODECLASS_VARIABLE);
  181. v[readValueIdIndices[i]].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
  182. retval |= UA_Variant_copySetValue(&v[readValueIdIndices[i]].value, &UA_[UA_BOOLEAN],
  183. &((UA_VariableNode *)myNode)->historizing);
  184. break;
  185. case UA_ATTRIBUTEID_EXECUTABLE:
  186. CHECK_NODECLASS(UA_NODECLASS_METHOD);
  187. v[readValueIdIndices[i]].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
  188. retval |= UA_Variant_copySetValue(&v[readValueIdIndices[i]].value, &UA_[UA_BOOLEAN],
  189. &((UA_MethodNode *)myNode)->executable);
  190. break;
  191. case UA_ATTRIBUTEID_USEREXECUTABLE:
  192. CHECK_NODECLASS(UA_NODECLASS_METHOD);
  193. v[readValueIdIndices[i]].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
  194. retval |= UA_Variant_copySetValue(&v[readValueIdIndices[i]].value, &UA_[UA_BOOLEAN],
  195. &((UA_MethodNode *)myNode)->userExecutable);
  196. break;
  197. default:
  198. v[readValueIdIndices[i]].encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
  199. v[readValueIdIndices[i]].status = UA_STATUSCODE_BADATTRIBUTEIDINVALID;
  200. break;
  201. }
  202. if(retval != UA_SUCCESS) {
  203. v[readValueIdIndices[i]].encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
  204. v[readValueIdIndices[i]].status = UA_STATUSCODE_BADNOTREADABLE;
  205. }
  206. }
  207. return retval;
  208. }
  209. UA_Int32 writeNodes(UA_WriteValue *writeValues,UA_UInt32 *indices ,UA_UInt32 indicesSize, UA_StatusCode *writeNodesResults, UA_DiagnosticInfo *diagnosticInfos)
  210. {
  211. UA_Int32 retval = UA_SUCCESS;
  212. for(UA_UInt32 i=0;i<indicesSize;i++){
  213. switch(writeValues[indices[i]].attributeId) {
  214. case UA_ATTRIBUTEID_NODEID:
  215. /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){ } */
  216. writeNodesResults[indices[i]] = UA_STATUSCODE_BADWRITENOTSUPPORTED;
  217. return UA_ERROR;
  218. break;
  219. case UA_ATTRIBUTEID_NODECLASS:
  220. /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){ } */
  221. writeNodesResults[indices[i]] = UA_STATUSCODE_BADWRITENOTSUPPORTED;
  222. return UA_ERROR;
  223. break;
  224. case UA_ATTRIBUTEID_BROWSENAME:
  225. /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
  226. writeNodesResults[indices[i]] = UA_STATUSCODE_BADWRITENOTSUPPORTED;
  227. return UA_ERROR;
  228. break;
  229. case UA_ATTRIBUTEID_DISPLAYNAME:
  230. /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
  231. writeNodesResults[indices[i]] = UA_STATUSCODE_BADWRITENOTSUPPORTED;
  232. return UA_ERROR;
  233. break;
  234. case UA_ATTRIBUTEID_DESCRIPTION:
  235. /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
  236. writeNodesResults[indices[i]] = UA_STATUSCODE_BADWRITENOTSUPPORTED;
  237. return UA_ERROR;
  238. break;
  239. case UA_ATTRIBUTEID_WRITEMASK:
  240. /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
  241. break;
  242. case UA_ATTRIBUTEID_USERWRITEMASK:
  243. /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
  244. writeNodesResults[indices[i]] = UA_STATUSCODE_BADWRITENOTSUPPORTED;
  245. return UA_ERROR;
  246. break;
  247. case UA_ATTRIBUTEID_ISABSTRACT:
  248. /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
  249. writeNodesResults[indices[i]] = UA_STATUSCODE_BADWRITENOTSUPPORTED;
  250. break;
  251. case UA_ATTRIBUTEID_SYMMETRIC:
  252. /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
  253. writeNodesResults[indices[i]] = UA_STATUSCODE_BADWRITENOTSUPPORTED;
  254. return UA_ERROR;
  255. break;
  256. case UA_ATTRIBUTEID_INVERSENAME:
  257. /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
  258. writeNodesResults[indices[i]] = UA_STATUSCODE_BADWRITENOTSUPPORTED;
  259. break;
  260. case UA_ATTRIBUTEID_CONTAINSNOLOOPS:
  261. /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
  262. writeNodesResults[indices[i]] = UA_STATUSCODE_BADWRITENOTSUPPORTED;
  263. return UA_ERROR;
  264. break;
  265. case UA_ATTRIBUTEID_EVENTNOTIFIER:
  266. /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
  267. writeNodesResults[indices[i]] = UA_STATUSCODE_BADWRITENOTSUPPORTED;
  268. break;
  269. case UA_ATTRIBUTEID_VALUE:
  270. if(writeValues[indices[i]].value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT) {
  271. retval |= UA_Variant_copy(&writeValues[indices[i]].value.value, &((UA_VariableNode *)myNode)->value); // todo: zero-copy
  272. writeNodesResults[indices[i]] = UA_STATUSCODE_GOOD;
  273. }
  274. break;
  275. case UA_ATTRIBUTEID_DATATYPE:
  276. /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
  277. writeNodesResults[indices[i]] = UA_STATUSCODE_BADWRITENOTSUPPORTED;
  278. break;
  279. case UA_ATTRIBUTEID_VALUERANK:
  280. /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
  281. writeNodesResults[indices[i]] = UA_STATUSCODE_BADWRITENOTSUPPORTED;
  282. break;
  283. case UA_ATTRIBUTEID_ARRAYDIMENSIONS:
  284. /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
  285. writeNodesResults[indices[i]] = UA_STATUSCODE_BADWRITENOTSUPPORTED;
  286. break;
  287. case UA_ATTRIBUTEID_ACCESSLEVEL:
  288. /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
  289. writeNodesResults[indices[i]] = UA_STATUSCODE_BADWRITENOTSUPPORTED;
  290. break;
  291. case UA_ATTRIBUTEID_USERACCESSLEVEL:
  292. /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
  293. writeNodesResults[indices[i]] = UA_STATUSCODE_BADWRITENOTSUPPORTED;
  294. return UA_ERROR;
  295. break;
  296. case UA_ATTRIBUTEID_MINIMUMSAMPLINGINTERVAL:
  297. /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
  298. writeNodesResults[indices[i]] = UA_STATUSCODE_BADWRITENOTSUPPORTED;
  299. break;
  300. case UA_ATTRIBUTEID_HISTORIZING:
  301. /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
  302. writeNodesResults[indices[i]] = UA_STATUSCODE_BADWRITENOTSUPPORTED;
  303. break;
  304. case UA_ATTRIBUTEID_EXECUTABLE:
  305. /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
  306. writeNodesResults[indices[i]] = UA_STATUSCODE_BADWRITENOTSUPPORTED;
  307. break;
  308. case UA_ATTRIBUTEID_USEREXECUTABLE:
  309. /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
  310. writeNodesResults[indices[i]] = UA_STATUSCODE_BADWRITENOTSUPPORTED;
  311. break;
  312. default:
  313. writeNodesResults[indices[i]] = UA_STATUSCODE_BADATTRIBUTEIDINVALID;
  314. break;
  315. }
  316. }
  317. return retval;
  318. }