opcua_basictypes.c 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255
  1. /*
  2. * opcua_basictypes.c
  3. *
  4. * Created on: 13.03.2014
  5. * Author: mrt
  6. */
  7. #include "opcua.h"
  8. #include <memory.h>
  9. Int32 UA_calcSize(void* const data, UInt32 type) {
  10. return (UA_namespace_zero[type].calcSize)(data);
  11. }
  12. Int32 UA_Array_calcSize(Int32 nElements, Int32 type, void const ** data) {
  13. int length = sizeof(UA_Int32);
  14. int i;
  15. if (nElements > 0) {
  16. for(i=0; i<nElements;i++,data++) {
  17. length += UA_calcSize(data,type);
  18. }
  19. }
  20. return length;
  21. }
  22. Int32 UA_Boolean_calcSize(UA_Boolean const * ptr) { return sizeof(UA_Boolean); }
  23. Int32 UA_Boolean_encode(UA_Boolean const * src, Int32* pos, char * dst) {
  24. UA_Boolean tmpBool = ((*src > 0) ? UA_TRUE : UA_FALSE);
  25. memcpy(&(dst[(*pos)++]), &tmpBool, sizeof(UA_Boolean));
  26. return UA_SUCCESS;
  27. }
  28. Int32 UA_Boolean_decode(char const * src, Int32* pos, UA_Boolean * dst) {
  29. *dst = ((UA_Boolean) (src[(*pos)++]) > 0) ? UA_TRUE : UA_FALSE;
  30. return UA_SUCCESS;
  31. }
  32. Int32 UA_Boolean_delete(UA_Boolean* p) { return UA_memfree(p); };
  33. Int32 UA_Boolean_deleteMembers(UA_Boolean* p) { return UA_SUCCESS; };
  34. Int32 UA_Byte_calcSize(UA_Byte const * ptr) { return sizeof(UA_Byte); }
  35. Int32 UA_Byte_encode(UA_Byte const * src, Int32* pos, char * dst) {
  36. *dst = src[(*pos)++];
  37. return UA_SUCCESS;
  38. }
  39. Int32 UA_Byte_decode(char const * src, Int32* pos, UA_Byte * dst) {
  40. memcpy(&(dst[(*pos)++]), src, sizeof(UA_Byte));
  41. return UA_SUCCESS;
  42. }
  43. Int32 UA_Byte_delete(UA_Byte* p) { return UA_memfree(p); };
  44. Int32 UA_Byte_deleteMembers(UA_Byte* p) { return UA_SUCCESS; };
  45. Int32 UA_SByte_calcSize(UA_SByte const * ptr) { return sizeof(UA_SByte); }
  46. Int32 UA_SByte_encode(UA_SByte const * src, Int32* pos, char * dst) {
  47. dst[(*pos)++] = *src;
  48. return UA_SUCCESS;
  49. }
  50. Int32 UA_SByte_decode(char const * src, Int32* pos, UA_SByte * dst) {
  51. *dst = src[(*pos)++];
  52. return 1;
  53. }
  54. Int32 UA_SByte_delete(UA_SByte* p) { return UA_memfree(p); };
  55. Int32 UA_SByte_deleteMembers(UA_SByte* p) { return UA_SUCCESS; };
  56. Int32 UA_UInt16_calcSize(UA_UInt16* p) { return sizeof(UA_UInt16); }
  57. Int32 UA_UInt16_encode(UA_UInt16 const *src, Int32* pos, char * dst) {
  58. memcpy(&(dst[*pos]), src, sizeof(UA_UInt16));
  59. *pos += sizeof(UA_UInt16);
  60. return UA_SUCCESS;
  61. }
  62. Int32 UA_UInt16_decode(char const * src, Int32* pos, UA_UInt16* dst) {
  63. Byte t1 = src[(*pos)++];
  64. UInt16 t2 = (UInt16) (src[(*pos)++] << 8);
  65. *dst = t1 + t2;
  66. return UA_SUCCESS;
  67. }
  68. Int32 UA_UInt16_delete(UA_UInt16* p) { return UA_memfree(p); };
  69. Int32 UA_UInt16_deleteMembers(UA_UInt16* p) { return UA_SUCCESS; };
  70. Int32 UA_Int16_calcSize(UA_Int16* p) { return sizeof(UA_Int16); }
  71. Int32 UA_Int16_encode(UA_Int16 const* src, Int32* pos, char* dst) {
  72. memcpy(&(dst[*pos]), src, sizeof(UA_Int16));
  73. *pos += sizeof(UA_Int16);
  74. return UA_SUCCESS;
  75. }
  76. Int32 UA_Int16_decode(char const * src, Int32* pos, UA_Int16 *dst) {
  77. Int16 t1 = (Int16) (((SByte) (src[(*pos)++]) & 0xFF));
  78. Int16 t2 = (Int16) (((SByte) (src[(*pos)++]) & 0xFF) << 8);
  79. *dst = t1 + t2;
  80. return UA_SUCCESS;
  81. }
  82. Int32 UA_Int16_delete(UA_Int16* p) { return UA_memfree(p); };
  83. Int32 UA_Int16_deleteMembers(UA_Int16* p) { return UA_SUCCESS; };
  84. Int32 decodeInt32(char const * buf, Int32 *pos, Int32 *dst) {
  85. Int32 t1 = (Int32) (((SByte) (buf[*pos]) & 0xFF));
  86. Int32 t2 = (Int32) (((SByte) (buf[*pos + 1]) & 0xFF) << 8);
  87. Int32 t3 = (Int32) (((SByte) (buf[*pos + 2]) & 0xFF) << 16);
  88. Int32 t4 = (Int32) (((SByte) (buf[*pos + 3]) & 0xFF) << 24);
  89. *pos += sizeof(Int32);
  90. *dst = t1 + t2 + t3 + t4;
  91. return UA_SUCCESS;
  92. }
  93. void encodeInt32(Int32 value, Int32 *pos, char *dstBuf) {
  94. memcpy(&(dstBuf[*pos]), &value, sizeof(Int32));
  95. *pos = (*pos) + sizeof(Int32);
  96. }
  97. Int32 decodeUInt32(char const * buf, Int32 *pos, UInt32 *dst) {
  98. Byte t1 = buf[*pos];
  99. UInt32 t2 = (UInt32) buf[*pos + 1] << 8;
  100. UInt32 t3 = (UInt32) buf[*pos + 2] << 16;
  101. UInt32 t4 = (UInt32) buf[*pos + 3] << 24;
  102. *pos += sizeof(UInt32);
  103. *dst = t1 + t2 + t3 + t4;
  104. return UA_NO_ERROR;
  105. }
  106. void encodeUInt32(UInt32 value, Int32 *pos, char *dstBuf) {
  107. memcpy(&(dstBuf[*pos]), &value, sizeof(UInt32));
  108. *pos += 4;
  109. }
  110. Int32 decodeInt64(char const * buf, Int32 *pos, Int64 *dst) {
  111. SByte t1 = buf[*pos];
  112. Int64 t2 = (Int64) buf[*pos + 1] << 8;
  113. Int64 t3 = (Int64) buf[*pos + 2] << 16;
  114. Int64 t4 = (Int64) buf[*pos + 3] << 24;
  115. Int64 t5 = (Int64) buf[*pos + 4] << 32;
  116. Int64 t6 = (Int64) buf[*pos + 5] << 40;
  117. Int64 t7 = (Int64) buf[*pos + 6] << 48;
  118. Int64 t8 = (Int64) buf[*pos + 7] << 56;
  119. *pos += 8;
  120. *dst = t1 + t2 + t3 + t4 + t5 + t6 + t7 + t8;
  121. return UA_NO_ERROR;
  122. }
  123. void encodeInt64(Int64 value, Int32 *pos, char *dstBuf) {
  124. memcpy(&(dstBuf[*pos]), &value, sizeof(Int64));
  125. *pos = (*pos) + sizeof(Int64);
  126. }
  127. Int32 decodeUInt64(char const * buf, Int32 *pos, UInt64 *dst) {
  128. Byte t1 = buf[*pos];
  129. UInt64 t2 = (UInt64) buf[*pos + 1] << 8;
  130. UInt64 t3 = (UInt64) buf[*pos + 2] << 16;
  131. UInt64 t4 = (UInt64) buf[*pos + 3] << 24;
  132. UInt64 t5 = (UInt64) buf[*pos + 4] << 32;
  133. UInt64 t6 = (UInt64) buf[*pos + 5] << 40;
  134. UInt64 t7 = (UInt64) buf[*pos + 6] << 48;
  135. UInt64 t8 = (UInt64) buf[*pos + 7] << 56;
  136. *pos += 8;
  137. *dst = t1 + t2 + t3 + t4 + t5 + t6 + t7 + t8;
  138. return UA_NO_ERROR;
  139. }
  140. void encodeUInt64(UInt64 value, Int32 *pos, char *dstBuf) {
  141. memcpy(&(dstBuf[*pos]), &value, sizeof(UInt64));
  142. *pos = (*pos) + sizeof(UInt64);
  143. }
  144. Int32 decodeFloat(char const * buf, Int32 *pos, Float *dst) {
  145. Float tmpFloat;
  146. memcpy(&tmpFloat, &(buf[*pos]), sizeof(Float));
  147. *pos += sizeof(Float);
  148. *dst = tmpFloat;
  149. return UA_NO_ERROR;
  150. }
  151. Int32 encodeFloat(Float value, Int32 *pos, char *dstBuf) {
  152. memcpy(&(dstBuf[*pos]), &value, sizeof(Float));
  153. *pos += sizeof(Float);
  154. return UA_NO_ERROR;
  155. }
  156. Int32 decodeDouble(char const * buf, Int32 *pos, Double *dst) {
  157. Double tmpDouble;
  158. tmpDouble = (Double) (buf[*pos]);
  159. *pos += sizeof(Double);
  160. *dst = tmpDouble;
  161. return UA_NO_ERROR;
  162. }
  163. Int32 encodeDouble(Double value, Int32 *pos, char *dstBuf) {
  164. memcpy(&(dstBuf[*pos]), &value, sizeof(Double));
  165. *pos *= sizeof(Double);
  166. return UA_NO_ERROR;
  167. }
  168. Int32 UA_String_calcSize(UA_String const * string) {
  169. if (string->length > 0) {
  170. return string->length + sizeof(string->length);
  171. } else {
  172. return sizeof(UA_Int32);
  173. }
  174. }
  175. // TODO: UA_String_encode
  176. // TODO: UA_String_decode
  177. Int32 UA_String_delete(UA_String* p) { return UA_memfree(p); };
  178. Int32 UA_String_deleteMembers(UA_String* p) { return UA_Byte_delete(p->data); };
  179. // TODO: can we really handle UA_String and UA_ByteString the same way?
  180. Int32 UA_ByteString_calcSize(UA_ByteString const * string) {
  181. return UA_String_calcSize((UA_String*) string);
  182. }
  183. // TODO: UA_ByteString_encode
  184. // TODO: UA_ByteString_decode
  185. Int32 UA_ByteString_delete(UA_ByteString* p) { return UA_String_delete((UA_String*) p); };
  186. Int32 UA_ByteString_deleteMembers(UA_ByteString* p) { return UA_String_deleteMembers((UA_String*) p); };
  187. Int32 UA_Guid_calcSize(UA_Guid const * guid) {
  188. return sizeof(guid->Data1)
  189. + sizeof(guid->Data2)
  190. + sizeof(guid->Data3)
  191. + UA_ByteString_calcSize(&(guid->Data4));
  192. }
  193. // TODO: UA_Guid_encode
  194. // TODO: UA_Guid_decode
  195. Int32 UA_Guid_delete(UA_Guid* p) { return UA_memfree(p); };
  196. Int32 UA_Guid_deleteMembers(UA_Guid* p) { return UA_ByteString_delete(p->Data4); };
  197. Int32 UA_LocalizedText_calcSize(UA_LocalizedText const * localizedText) {
  198. Int32 length = 0;
  199. length += localizedText->EncodingMask;
  200. if (localizedText->EncodingMask & 0x01) {
  201. length += UA_String_calcSize(&(localizedText->Locale));
  202. }
  203. if (localizedText->EncodingMask & 0x02) {
  204. length += UA_String_calcSize(&(localizedText->Text));
  205. }
  206. return length;
  207. }
  208. // TODO: UA_LocalizedText_encode
  209. // TODO: UA_LocalizedText_decode
  210. Int32 UA_LocalizedText_delete(UA_LocalizedText* p) { return UA_memfree(p); };
  211. Int32 UA_LocalizedText_deleteMembers(UA_LocalizedText* p) {
  212. return UA_SUCCESS
  213. // TODO: both locale and text are yet neither pointers nor allocated
  214. // || UA_ByteString_delete(p->locale)
  215. // || UA_ByteString_delete(p->text)
  216. ;
  217. };
  218. Int32 UA_NodeId_calcSize(UA_NodeId const *nodeId) {
  219. Int32 length = 0;
  220. switch (nodeId->EncodingByte) {
  221. case NIEVT_TWO_BYTE:
  222. length += 2 * sizeof(UA_Byte);
  223. break;
  224. case NIEVT_FOUR_BYTE:
  225. length += 4 * sizeof(UA_Byte);
  226. break;
  227. case NIEVT_NUMERIC:
  228. length += sizeof(UA_Byte) + sizeof(UA_UInt16) + sizeof(UInt32);
  229. break;
  230. case NIEVT_STRING:
  231. length += sizeof(UA_Byte) + sizeof(UA_UInt16) + UA_String_calcSize(&(nodeId->Identifier.String));
  232. break;
  233. case NIEVT_GUID:
  234. length += sizeof(UA_Byte) + sizeof(UA_UInt16) + UA_Guid_calcSize(&(nodeId->Identifier.Guid));
  235. break;
  236. case NIEVT_BYTESTRING:
  237. length += sizeof(UA_Byte) + sizeof(UA_UInt16) + UA_ByteString_calcSize(&(nodeId->Identifier.ByteString));
  238. break;
  239. default:
  240. break;
  241. }
  242. return length;
  243. }
  244. // TODO: UA_NodeID_encode
  245. // TODO: UA_NodeID_decode
  246. // TODO: UA_NodeID_delete
  247. // TODO: UA_NodeID_deleteMembers
  248. Int32 UA_ExpandedNodeId_calcSize(UA_ExpandedNodeId *nodeId) {
  249. Int32 length = sizeof(UA_Byte);
  250. length += UA_NodeId_calcSize(&(nodeId->NodeId));
  251. if (nodeId->NodeId.EncodingByte & NIEVT_NAMESPACE_URI_FLAG) {
  252. length += sizeof(UInt16); //nodeId->NodeId.Namespace
  253. length += UA_String_calcSize(&(nodeId->NamespaceUri)); //nodeId->NamespaceUri
  254. }
  255. if (nodeId->NodeId.EncodingByte & NIEVT_SERVERINDEX_FLAG) {
  256. length += sizeof(UInt32); //nodeId->ServerIndex
  257. }
  258. return length;
  259. }
  260. // TODO: UA_ExpandedNodeID_encode
  261. // TODO: UA_ExpandedNodeID_decode
  262. // TODO: UA_ExpandedNodeID_delete
  263. // TODO: UA_ExpandedNodeID_deleteMembers
  264. Int32 UA_ExtensionObject_calcSize(UA_ExtensionObject *extensionObject) {
  265. Int32 length = 0;
  266. length += UA_NodeId_calcSize(&(extensionObject->TypeId));
  267. length += sizeof(Byte); //extensionObject->Encoding
  268. switch (extensionObject->Encoding) {
  269. case 0x00:
  270. length += sizeof(Int32); //extensionObject->Body.Length
  271. break;
  272. case 0x01:
  273. length += UA_ByteString_calcSize(&(extensionObject->Body));
  274. break;
  275. case 0x02:
  276. length += UA_ByteString_calcSize(&(extensionObject->Body));
  277. break;
  278. }
  279. return length;
  280. }
  281. // TODO: UA_ExtensionObject_encode
  282. // TODO: UA_ExtensionObject_decode
  283. // TODO: UA_ExtensionObject_delete
  284. // TODO: UA_ExtensionObject_deleteMembers
  285. Int32 UA_DataValue_calcSize(UA_DataValue *dataValue) {
  286. Int32 length = 0;
  287. length += sizeof(UA_Byte); //dataValue->EncodingMask
  288. if (dataValue->EncodingMask & 0x01) {
  289. length += UA_Variant_calcSize(&(dataValue->Value));
  290. }
  291. if (dataValue->EncodingMask & 0x02) {
  292. length += sizeof(UA_UInt32); //dataValue->Status
  293. }
  294. if (dataValue->EncodingMask & 0x04) {
  295. length += sizeof(UA_Int64); //dataValue->SourceTimestamp
  296. }
  297. if (dataValue->EncodingMask & 0x08) {
  298. length += sizeof(UA_Int64); //dataValue->ServerTimestamp
  299. }
  300. if (dataValue->EncodingMask & 0x10) {
  301. length += sizeof(UA_Int64); //dataValue->SourcePicoseconds
  302. }
  303. if (dataValue->EncodingMask & 0x20) {
  304. length += sizeof(UA_Int64); //dataValue->ServerPicoseconds
  305. }
  306. return length;
  307. }
  308. // TODO: UA_DataValue_encode
  309. // TODO: UA_DataValue_decode
  310. // TODO: UA_DataValue_delete
  311. // TODO: UA_DataValue_deleteMembers
  312. Int32 UA_DiagnosticInfo_calcSize(UA_DiagnosticInfo *diagnosticInfo) {
  313. Int32 length = 0;
  314. Byte mask;
  315. length += sizeof(Byte); // EncodingMask
  316. for (mask = 0x01; mask <= 0x40; mask *= 2) {
  317. switch (mask & (diagnosticInfo->EncodingMask)) {
  318. case DIEMT_SYMBOLIC_ID:
  319. // puts("diagnosticInfo symbolic id");
  320. length += sizeof(Int32);
  321. break;
  322. case DIEMT_NAMESPACE:
  323. length += sizeof(Int32);
  324. break;
  325. case DIEMT_LOCALIZED_TEXT:
  326. length += sizeof(Int32);
  327. break;
  328. case DIEMT_LOCALE:
  329. length += sizeof(Int32);
  330. break;
  331. case DIEMT_ADDITIONAL_INFO:
  332. length += UA_String_calcSize(&(diagnosticInfo->AdditionalInfo));
  333. break;
  334. case DIEMT_INNER_STATUS_CODE:
  335. length += sizeof(UA_StatusCode);
  336. break;
  337. case DIEMT_INNER_DIAGNOSTIC_INFO:
  338. length += UA_DiagnosticInfo_calcSize(
  339. diagnosticInfo->InnerDiagnosticInfo);
  340. break;
  341. }
  342. }
  343. return length;
  344. }
  345. // TODO: UA_DiagnosticInfo_encode
  346. // TODO: UA_DiagnosticInfo_decode
  347. // TODO: UA_DiagnosticInfo_delete
  348. // TODO: UA_DiagnosticInfo_deleteMembers
  349. Int32 decodeUAString(char const * buf, Int32 *pos, UA_String * dstUAString) {
  350. decoder_decodeBuiltInDatatype(buf, INT32, pos, &(dstUAString->Length));
  351. if (dstUAString->Length > 0) {
  352. dstUAString->Data = &(buf[*pos]);
  353. } else {
  354. dstUAString->Length = 0;
  355. dstUAString->Data = (void*) 0;
  356. }
  357. *pos += dstUAString->Length;
  358. return 0;
  359. }
  360. Int32 encodeUAString(UA_String *string, Int32 *pos, char *dstBuf) {
  361. if (string->Length > 0) {
  362. memcpy(&(dstBuf[*pos]), &(string->Length), sizeof(Int32));
  363. *pos += sizeof(Int32);
  364. memcpy(&(dstBuf[*pos]), string->Data, string->Length);
  365. *pos += string->Length;
  366. } else {
  367. int lengthNULL = 0xFFFFFFFF;
  368. memcpy(&(dstBuf[*pos]), &lengthNULL, sizeof(Int32));
  369. *pos += sizeof(Int32);
  370. }
  371. return 0;
  372. }
  373. Int32 UAString_calcSize(UA_String *string) {
  374. if (string->Length > 0) {
  375. return string->Length + sizeof(string->Length);
  376. } else {
  377. return sizeof(Int32);
  378. }
  379. }
  380. Int32 decodeUADateTime(char const * buf, Int32 *pos, UA_DateTime *dst) {
  381. decoder_decodeBuiltInDatatype(buf, INT64, pos, dst);
  382. return UA_NO_ERROR;
  383. }
  384. void encodeUADateTime(UA_DateTime time, Int32 *pos, char *dstBuf) {
  385. encodeInt64(time, pos, dstBuf);
  386. }
  387. Int32 decodeUAGuid(char const * buf, Int32 *pos, UA_Guid *dstGUID) {
  388. decoder_decodeBuiltInDatatype(buf, INT32, pos, &(dstGUID->Data1));
  389. decoder_decodeBuiltInDatatype(buf, INT16, pos, &(dstGUID->Data2));
  390. decoder_decodeBuiltInDatatype(buf, INT16, pos, &(dstGUID->Data3));
  391. decoder_decodeBuiltInDatatype(buf, STRING, pos, &(dstGUID->Data4));
  392. decodeUAByteString(buf, pos, &(dstGUID->Data4));
  393. return UA_NO_ERROR;
  394. }
  395. Int32 encodeUAGuid(UA_Guid *srcGuid, Int32 *pos, char *buf) {
  396. encodeUInt32(srcGuid->Data1, pos, buf);
  397. encodeUInt16(srcGuid->Data2, pos, buf);
  398. encodeUInt16(srcGuid->Data3, pos, buf);
  399. encodeUAByteString(srcGuid->Data4, pos, buf);
  400. return UA_NO_ERROR;
  401. }
  402. Int32 UAGuid_calcSize(UA_Guid *guid) {
  403. return sizeof(guid->Data1) + sizeof(guid->Data2) + sizeof(guid->Data3)
  404. + UAByteString_calcSize(&(guid->Data4));
  405. }
  406. Int32 decodeUAByteString(char const * buf, Int32* pos,
  407. UA_ByteString *dstBytestring) {
  408. return decodeUAString(buf, pos, (UA_String*) dstBytestring);
  409. }
  410. Int32 encodeUAByteString(UA_ByteString *srcByteString, Int32* pos, char *dstBuf) {
  411. return encodeUAString((UA_String*) srcByteString, pos, dstBuf);
  412. }
  413. Int32 encodeXmlElement(UA_XmlElement *xmlElement, Int32 *pos, char *dstBuf) {
  414. return encodeUAByteString(&(xmlElement->Data), pos, dstBuf);
  415. }
  416. Int32 decodeXmlElement(char const * buf, Int32* pos, UA_XmlElement *xmlElement) {
  417. return decodeUAByteString(buf, pos, &xmlElement->Data);
  418. }
  419. Int32 UAByteString_calcSize(UA_ByteString *byteString) {
  420. return UAString_calcSize((UA_String*) byteString);
  421. }
  422. /* Serialization of UANodeID is specified in 62541-6, §5.2.2.9 */
  423. Int32 decodeUANodeId(char const * buf, Int32 *pos, UA_NodeId *dstNodeId) {
  424. // Vars for overcoming decoder_decodeXXX's non-endian-savenes
  425. Byte dstByte;
  426. UInt16 dstUInt16;
  427. decoder_decodeBuiltInDatatype(buf, BYTE, pos, &(dstNodeId->EncodingByte));
  428. switch (dstNodeId->EncodingByte) {
  429. case NIEVT_TWO_BYTE: // Table 7
  430. decoder_decodeBuiltInDatatype(buf, BYTE, pos, &dstByte);
  431. dstNodeId->Identifier.Numeric = dstByte;
  432. dstNodeId->Namespace = 0; // default OPC UA Namespace
  433. break;
  434. case NIEVT_FOUR_BYTE: // Table 8
  435. decoder_decodeBuiltInDatatype(buf, BYTE, pos, &dstByte);
  436. dstNodeId->Namespace = dstByte;
  437. decoder_decodeBuiltInDatatype(buf, UINT16, pos, &dstUInt16);
  438. dstNodeId->Identifier.Numeric = dstUInt16;
  439. break;
  440. case NIEVT_NUMERIC: // Table 6, first entry
  441. decoder_decodeBuiltInDatatype(buf, UINT16, pos,
  442. &(dstNodeId->Namespace));
  443. decoder_decodeBuiltInDatatype(buf, UINT32, pos,
  444. &(dstNodeId->Identifier.Numeric));
  445. break;
  446. case NIEVT_STRING: // Table 6, second entry
  447. decoder_decodeBuiltInDatatype(buf, UINT16, pos,
  448. &(dstNodeId->Namespace));
  449. decoder_decodeBuiltInDatatype(buf, STRING, pos,
  450. &(dstNodeId->Identifier.String));
  451. break;
  452. case NIEVT_GUID: // Table 6, third entry
  453. decoder_decodeBuiltInDatatype(buf, UINT16, pos,
  454. &(dstNodeId->Namespace));
  455. decoder_decodeBuiltInDatatype(buf, GUID, pos,
  456. &(dstNodeId->Identifier.Guid));
  457. break;
  458. case NIEVT_BYTESTRING: // Table 6, "OPAQUE"
  459. decoder_decodeBuiltInDatatype(buf, UINT16, pos,
  460. &(dstNodeId->Namespace));
  461. decoder_decodeBuiltInDatatype(buf, BYTE_STRING, pos,
  462. &(dstNodeId->Identifier.ByteString));
  463. break;
  464. }
  465. return UA_NO_ERROR;
  466. }
  467. Int32 encodeUANodeId(UA_NodeId *srcNodeId, Int32 *pos, char *buf) {
  468. buf[*pos] = srcNodeId->EncodingByte;
  469. *pos += sizeof(Byte);
  470. switch (srcNodeId->EncodingByte) {
  471. case NIEVT_TWO_BYTE:
  472. memcpy(&(buf[*pos]), &(srcNodeId->Identifier.Numeric), sizeof(Byte));
  473. *pos += sizeof(Byte);
  474. break;
  475. case NIEVT_FOUR_BYTE:
  476. encodeByte((Byte) (srcNodeId->Namespace & 0xFF), pos, buf);
  477. encodeUInt16((UInt16) (srcNodeId->Identifier.Numeric & 0xFFFF), pos,
  478. buf);
  479. break;
  480. case NIEVT_NUMERIC:
  481. encodeUInt16((UInt16) (srcNodeId->Namespace & 0xFFFF), pos, buf);
  482. encodeUInt32(srcNodeId->Identifier.Numeric, pos, buf);
  483. break;
  484. case NIEVT_STRING:
  485. encodeUInt16(srcNodeId->Namespace, pos, buf);
  486. encodeUAString(&(srcNodeId->Identifier.String), pos, buf);
  487. break;
  488. case NIEVT_GUID:
  489. encodeUInt16(srcNodeId->Namespace, pos, buf);
  490. encodeUAGuid(&(srcNodeId->Identifier.Guid), pos, buf);
  491. break;
  492. case NIEVT_BYTESTRING:
  493. encodeUInt16(srcNodeId->Namespace, pos, buf);
  494. encodeUAByteString(&(srcNodeId->Identifier.ByteString), pos, buf);
  495. break;
  496. }
  497. return UA_NO_ERROR;
  498. }
  499. Int32 nodeId_calcSize(UA_NodeId *nodeId) {
  500. Int32 length = 0;
  501. switch (nodeId->EncodingByte) {
  502. case NIEVT_TWO_BYTE:
  503. length += 2 * sizeof(Byte);
  504. break;
  505. case NIEVT_FOUR_BYTE:
  506. length += 4 * sizeof(Byte);
  507. break;
  508. case NIEVT_NUMERIC:
  509. length += sizeof(Byte) + sizeof(UInt16) + sizeof(UInt32);
  510. break;
  511. case NIEVT_STRING:
  512. length += sizeof(Byte) + sizeof(UInt16) + sizeof(UInt32)
  513. + nodeId->Identifier.String.Length;
  514. break;
  515. case NIEVT_GUID:
  516. length += sizeof(Byte) + sizeof(UInt16) + sizeof(UInt32)
  517. + sizeof(UInt16) + sizeof(UInt16) + 8 * sizeof(Byte);
  518. break;
  519. case NIEVT_BYTESTRING:
  520. length += sizeof(Byte) + sizeof(UInt16) + sizeof(UInt32)
  521. + nodeId->Identifier.ByteString.Length;
  522. break;
  523. default:
  524. break;
  525. }
  526. return length;
  527. }
  528. /**
  529. * IntegerId
  530. * Part: 4
  531. * Chapter: 7.13
  532. * Page: 118
  533. */
  534. Int32 decodeIntegerId(char const * buf, Int32 *pos, Int32 *dst) {
  535. decoder_decodeBuiltInDatatype(buf, INT32, pos, dst);
  536. return UA_NO_ERROR;
  537. }
  538. void encodeIntegerId(UA_AD_IntegerId integerId, Int32 *pos, char *buf) {
  539. encodeInt32(integerId, pos, buf);
  540. }
  541. Int32 decodeExpandedNodeId(char const * buf, Int32 *pos,
  542. UA_ExpandedNodeId *nodeId) {
  543. decoder_decodeBuiltInDatatype(buf, BYTE, pos,
  544. &(nodeId->NodeId.EncodingByte));
  545. switch (nodeId->NodeId.EncodingByte) {
  546. case NIEVT_TWO_BYTE:
  547. decoder_decodeBuiltInDatatype(buf, BYTE, pos,
  548. &(nodeId->NodeId.Identifier.Numeric));
  549. break;
  550. case NIEVT_FOUR_BYTE:
  551. decoder_decodeBuiltInDatatype(buf, UINT16, pos,
  552. &(nodeId->NodeId.Identifier.Numeric));
  553. break;
  554. case NIEVT_NUMERIC:
  555. decoder_decodeBuiltInDatatype(buf, UINT32, pos,
  556. &(nodeId->NodeId.Identifier.Numeric));
  557. break;
  558. case NIEVT_STRING:
  559. decoder_decodeBuiltInDatatype(buf, STRING, pos,
  560. &(nodeId->NodeId.Identifier.String));
  561. break;
  562. case NIEVT_GUID:
  563. decoder_decodeBuiltInDatatype(buf, GUID, pos,
  564. &(nodeId->NodeId.Identifier.Guid));
  565. break;
  566. case NIEVT_BYTESTRING:
  567. decoder_decodeBuiltInDatatype(buf, BYTE_STRING, pos,
  568. &(nodeId->NodeId.Identifier.ByteString));
  569. break;
  570. }
  571. if (nodeId->NodeId.EncodingByte & NIEVT_NAMESPACE_URI_FLAG) {
  572. nodeId->NodeId.Namespace = 0;
  573. decoder_decodeBuiltInDatatype(buf, STRING, pos,
  574. &(nodeId->NamespaceUri));
  575. }
  576. if (nodeId->NodeId.EncodingByte & NIEVT_SERVERINDEX_FLAG) {
  577. decoder_decodeBuiltInDatatype(buf, UINT32, pos, &(nodeId->ServerIndex));
  578. }
  579. return UA_NO_ERROR;
  580. }
  581. Int32 encodeExpandedNodeId(UA_ExpandedNodeId *nodeId, Int32 *pos, char *dstBuf) {
  582. encoder_encodeBuiltInDatatype((void*) &(nodeId->NodeId.EncodingByte), BYTE,
  583. pos, dstBuf);
  584. switch (nodeId->NodeId.EncodingByte) {
  585. case NIEVT_TWO_BYTE:
  586. encoder_encodeBuiltInDatatype(
  587. (void*) &(nodeId->NodeId.Identifier.Numeric), BYTE, pos,
  588. dstBuf);
  589. break;
  590. case NIEVT_FOUR_BYTE:
  591. encoder_encodeBuiltInDatatype(
  592. (void*) &(nodeId->NodeId.Identifier.Numeric), UINT16, pos,
  593. dstBuf);
  594. break;
  595. case NIEVT_NUMERIC:
  596. encoder_encodeBuiltInDatatype(
  597. (void*) &(nodeId->NodeId.Identifier.Numeric), UINT32, pos,
  598. dstBuf);
  599. break;
  600. case NIEVT_STRING:
  601. encoder_encodeBuiltInDatatype(
  602. (void*) &(nodeId->NodeId.Identifier.String), STRING, pos,
  603. dstBuf);
  604. break;
  605. case NIEVT_GUID:
  606. encoder_encodeBuiltInDatatype((void*) &(nodeId->NodeId.Identifier.Guid),
  607. STRING, pos, dstBuf);
  608. break;
  609. case NIEVT_BYTESTRING:
  610. encoder_encodeBuiltInDatatype(
  611. (void*) &(nodeId->NodeId.Identifier.ByteString), BYTE_STRING,
  612. pos, dstBuf);
  613. break;
  614. }
  615. if (nodeId->NodeId.EncodingByte & NIEVT_NAMESPACE_URI_FLAG) {
  616. nodeId->NodeId.Namespace = 0;
  617. encoder_encodeBuiltInDatatype((void*) &(nodeId->NamespaceUri), STRING,
  618. pos, dstBuf);
  619. }
  620. if (nodeId->NodeId.EncodingByte & NIEVT_SERVERINDEX_FLAG) {
  621. encoder_encodeBuiltInDatatype((void*) &(nodeId->ServerIndex), UINT32,
  622. pos, dstBuf);
  623. }
  624. return UA_NO_ERROR;
  625. }
  626. Int32 ExpandedNodeId_calcSize(UA_ExpandedNodeId *nodeId) {
  627. Int32 length = 0;
  628. length += sizeof(UInt32); //nodeId->NodeId.EncodingByte
  629. switch (nodeId->NodeId.EncodingByte) {
  630. case NIEVT_TWO_BYTE:
  631. length += sizeof(Byte); //nodeId->NodeId.Identifier.Numeric
  632. break;
  633. case NIEVT_FOUR_BYTE:
  634. length += sizeof(UInt16); //nodeId->NodeId.Identifier.Numeric
  635. break;
  636. case NIEVT_NUMERIC:
  637. length += sizeof(UInt32); //nodeId->NodeId.Identifier.Numeric
  638. break;
  639. case NIEVT_STRING:
  640. //nodeId->NodeId.Identifier.String
  641. length += UAString_calcSize(&(nodeId->NodeId.Identifier.String));
  642. break;
  643. case NIEVT_GUID:
  644. //nodeId->NodeId.Identifier.Guid
  645. length += UAGuid_calcSize(&(nodeId->NodeId.Identifier.Guid));
  646. break;
  647. case NIEVT_BYTESTRING:
  648. //nodeId->NodeId.Identifier.ByteString
  649. length += UAByteString_calcSize(
  650. &(nodeId->NodeId.Identifier.ByteString));
  651. break;
  652. }
  653. if (nodeId->NodeId.EncodingByte & NIEVT_NAMESPACE_URI_FLAG) {
  654. length += sizeof(UInt16); //nodeId->NodeId.Namespace
  655. length += UAString_calcSize(&(nodeId->NamespaceUri)); //nodeId->NamespaceUri
  656. }
  657. if (nodeId->NodeId.EncodingByte & NIEVT_SERVERINDEX_FLAG) {
  658. length += sizeof(UInt32); //nodeId->ServerIndex
  659. }
  660. return length;
  661. }
  662. Int32 decodeUAStatusCode(char const * buf, Int32 *pos, UA_StatusCode* dst) {
  663. decoder_decodeBuiltInDatatype(buf, UINT32, pos, dst);
  664. return UA_NO_ERROR;
  665. }
  666. Int32 decodeQualifiedName(char const * buf, Int32 *pos,
  667. UA_QualifiedName *dstQualifiedName) {
  668. //TODO memory management for ua string
  669. decoder_decodeBuiltInDatatype(buf, STRING, pos,
  670. &(dstQualifiedName->NamespaceIndex));
  671. decoder_decodeBuiltInDatatype(buf, STRING, pos, &(dstQualifiedName->Name));
  672. return UA_NO_ERROR;
  673. }
  674. Int32 encodeQualifiedName(UA_QualifiedName *qualifiedName, Int32 *pos,
  675. char *dstBuf) {
  676. encoder_encodeBuiltInDatatype((void*) &(qualifiedName->NamespaceIndex),
  677. UINT16, pos, dstBuf);
  678. encoder_encodeBuiltInDatatype((void*) &(qualifiedName->Name), STRING, pos,
  679. dstBuf);
  680. return UA_NO_ERROR;
  681. }
  682. Int32 QualifiedName_calcSize(UA_QualifiedName *qualifiedName) {
  683. Int32 length = 0;
  684. length += sizeof(UInt16); //qualifiedName->NamespaceIndex
  685. length += UAString_calcSize(&(qualifiedName->Name)); //qualifiedName->Name
  686. length += sizeof(UInt16); //qualifiedName->Reserved
  687. return length;
  688. }
  689. Int32 decodeLocalizedText(char const * buf, Int32 *pos,
  690. UA_LocalizedText *dstLocalizedText) {
  691. //TODO memory management for ua string
  692. decoder_decodeBuiltInDatatype(buf, BYTE, pos,
  693. &(dstLocalizedText->EncodingMask));
  694. decoder_decodeBuiltInDatatype(buf, STRING, pos,
  695. &(dstLocalizedText->Locale));
  696. decoder_decodeBuiltInDatatype(buf, STRING, pos, &(dstLocalizedText->Text));
  697. return UA_NO_ERROR;
  698. }
  699. Int32 encodeLocalizedText(UA_LocalizedText *localizedText, Int32 *pos,
  700. char *dstBuf) {
  701. if (localizedText->EncodingMask & 0x01) {
  702. encoder_encodeBuiltInDatatype((void*) &(localizedText->Locale), STRING,
  703. pos, dstBuf);
  704. }
  705. if (localizedText->EncodingMask & 0x02) {
  706. encoder_encodeBuiltInDatatype((void*) &(localizedText->Text), STRING,
  707. pos, dstBuf);
  708. }
  709. return UA_NO_ERROR;
  710. }
  711. Int32 LocalizedText_calcSize(UA_LocalizedText *localizedText) {
  712. Int32 length = 0;
  713. length += localizedText->EncodingMask;
  714. if (localizedText->EncodingMask & 0x01) {
  715. length += UAString_calcSize(&(localizedText->Locale));
  716. }
  717. if (localizedText->EncodingMask & 0x02) {
  718. length += UAString_calcSize(&(localizedText->Text));
  719. }
  720. return length;
  721. }
  722. Int32 decodeExtensionObject(char const * buf, Int32 *pos,
  723. UA_ExtensionObject *dstExtensionObject) {
  724. decoder_decodeBuiltInDatatype(buf, NODE_ID, pos,
  725. &(dstExtensionObject->TypeId));
  726. decoder_decodeBuiltInDatatype(buf, BYTE, pos,
  727. &(dstExtensionObject->Encoding));
  728. switch (dstExtensionObject->Encoding) {
  729. case NO_BODY_IS_ENCODED:
  730. break;
  731. case BODY_IS_BYTE_STRING:
  732. case BODY_IS_XML_ELEMENT:
  733. decoder_decodeBuiltInDatatype(buf, BYTE_STRING, pos,
  734. &(dstExtensionObject->Body));
  735. break;
  736. }
  737. return UA_NO_ERROR;
  738. }
  739. Int32 encodeExtensionObject(UA_ExtensionObject *extensionObject, Int32 *pos,
  740. char *dstBuf) {
  741. encoder_encodeBuiltInDatatype((void*) &(extensionObject->TypeId), NODE_ID,
  742. pos, dstBuf);
  743. encoder_encodeBuiltInDatatype((void*) &(extensionObject->Encoding), BYTE,
  744. pos, dstBuf);
  745. switch (extensionObject->Encoding) {
  746. case NO_BODY_IS_ENCODED:
  747. break;
  748. case BODY_IS_BYTE_STRING:
  749. case BODY_IS_XML_ELEMENT:
  750. encoder_encodeBuiltInDatatype((void*) &(extensionObject->Body),
  751. BYTE_STRING, pos, dstBuf);
  752. break;
  753. }
  754. return UA_NO_ERROR;
  755. }
  756. Int32 ExtensionObject_calcSize(UA_ExtensionObject *extensionObject) {
  757. Int32 length = 0;
  758. length += nodeId_calcSize(&(extensionObject->TypeId));
  759. length += sizeof(Byte); //extensionObject->Encoding
  760. switch (extensionObject->Encoding) {
  761. case 0x00:
  762. length += sizeof(Int32); //extensionObject->Body.Length
  763. break;
  764. case 0x01:
  765. length += UAByteString_calcSize(&(extensionObject->Body));
  766. break;
  767. case 0x02:
  768. length += UAByteString_calcSize(&(extensionObject->Body));
  769. break;
  770. }
  771. return length;
  772. }
  773. Int32 decodeVariant(char const * buf, Int32 *pos, UA_Variant *dstVariant) {
  774. decoder_decodeBuiltInDatatype(buf, BYTE, pos, &(dstVariant->EncodingMask));
  775. if (dstVariant->EncodingMask & (1 << 7)) {
  776. decoder_decodeBuiltInDatatype(buf, INT32, pos,
  777. &(dstVariant->ArrayLength));
  778. // dstVariant->Value->
  779. }
  780. //TODO implement the multiarray decoding
  781. return UA_NO_ERROR;
  782. }
  783. Int32 encodeVariant(UA_Variant *variant, Int32 *pos, char *dstBuf) {
  784. encoder_encodeBuiltInDatatype((void*) &(variant->EncodingMask), BYTE, pos,
  785. dstBuf);
  786. /* array of values is encoded */
  787. if (variant->EncodingMask & (1 << 7)) // array length is encoded
  788. {
  789. encoder_encodeBuiltInDatatype((void*) &(variant->ArrayLength), INT32,
  790. pos, dstBuf);
  791. if (variant->ArrayLength > 0) {
  792. //encode array as given by variant type
  793. encode_builtInDatatypeArray((void*) variant->Value,
  794. variant->ArrayLength, (variant->EncodingMask & 31), pos,
  795. dstBuf);
  796. }
  797. //single value to encode
  798. encoder_encodeBuiltInDatatype((void*) variant->Value,
  799. (variant->EncodingMask & 31), pos, dstBuf);
  800. } else //single value to encode
  801. {
  802. encoder_encodeBuiltInDatatype((void*) variant->Value,
  803. (variant->EncodingMask & 31), pos, dstBuf);
  804. }
  805. if (variant->EncodingMask & (1 << 6)) // encode array dimension field
  806. {
  807. encoder_encodeBuiltInDatatype((void*) variant->Value,
  808. (variant->EncodingMask & 31), pos, dstBuf);
  809. }
  810. return UA_NO_ERROR;
  811. }
  812. Int32 Variant_calcSize(UA_Variant *variant) {
  813. Int32 length = 0;
  814. length += sizeof(Byte); //variant->EncodingMask
  815. if (variant->EncodingMask & (1 << 7)) // array length is encoded
  816. {
  817. length += sizeof(Int32); //variant->ArrayLength
  818. if (variant->ArrayLength > 0) {
  819. //encode array as given by variant type
  820. //ToDo: tobeInsert: length += the calcSize for VariantUnions
  821. }
  822. //single value to encode
  823. //ToDo: tobeInsert: length += the calcSize for VariantUnions
  824. } else //single value to encode
  825. {
  826. //ToDo: tobeInsert: length += the calcSize for VariantUnions
  827. }
  828. if (variant->EncodingMask & (1 << 6)) // encode array dimension field
  829. {
  830. //ToDo: tobeInsert: length += the calcSize for VariantUnions
  831. }
  832. return length;
  833. }
  834. Int32 decodeDataValue(char const * buf, Int32 *pos, UA_DataValue *dstDataValue) {
  835. decoder_decodeBuiltInDatatype(buf, BYTE, pos,
  836. &(dstDataValue->EncodingMask));
  837. decoder_decodeBuiltInDatatype(buf, VARIANT, pos, &(dstDataValue->Value));
  838. decoder_decodeBuiltInDatatype(buf, STATUS_CODE, pos,
  839. &(dstDataValue->Status));
  840. decoder_decodeBuiltInDatatype(buf, DATE_TIME, pos,
  841. &(dstDataValue->SourceTimestamp));
  842. decoder_decodeBuiltInDatatype(buf, UINT16, pos,
  843. &(dstDataValue->SourcePicoseconds));
  844. if (dstDataValue->SourcePicoseconds > MAX_PICO_SECONDS) {
  845. dstDataValue->SourcePicoseconds = MAX_PICO_SECONDS;
  846. }
  847. decoder_decodeBuiltInDatatype(buf, DATE_TIME, pos,
  848. &(dstDataValue->ServerTimestamp));
  849. decoder_decodeBuiltInDatatype(buf, UINT16, pos,
  850. &(dstDataValue->ServerPicoseconds));
  851. if (dstDataValue->ServerPicoseconds > MAX_PICO_SECONDS) {
  852. dstDataValue->ServerPicoseconds = MAX_PICO_SECONDS;
  853. }
  854. //TODO to be implemented
  855. return UA_NO_ERROR;
  856. }
  857. Int32 encodeDataValue(UA_DataValue *dataValue, Int32 *pos, char *dstBuf) {
  858. encoder_encodeBuiltInDatatype((void*) &(dataValue->EncodingMask), BYTE, pos,
  859. dstBuf);
  860. if (dataValue->EncodingMask & 0x01) {
  861. encoder_encodeBuiltInDatatype((void*) &(dataValue->Value), VARIANT, pos,
  862. dstBuf);
  863. }
  864. if (dataValue->EncodingMask & 0x02) {
  865. encoder_encodeBuiltInDatatype((void*) &(dataValue->Status), STATUS_CODE,
  866. pos, dstBuf);
  867. }
  868. if (dataValue->EncodingMask & 0x04) {
  869. encoder_encodeBuiltInDatatype((void*) &(dataValue->SourceTimestamp),
  870. DATE_TIME, pos, dstBuf);
  871. }
  872. if (dataValue->EncodingMask & 0x08) {
  873. encoder_encodeBuiltInDatatype((void*) &(dataValue->ServerTimestamp),
  874. DATE_TIME, pos, dstBuf);
  875. }
  876. if (dataValue->EncodingMask & 0x10) {
  877. encoder_encodeBuiltInDatatype((void*) &(dataValue->SourcePicoseconds),
  878. UINT16, pos, dstBuf);
  879. }
  880. if (dataValue->EncodingMask & 0x20) {
  881. encoder_encodeBuiltInDatatype((void*) &(dataValue->ServerPicoseconds),
  882. UINT16, pos, dstBuf);
  883. }
  884. return UA_NO_ERROR;
  885. }
  886. Int32 DataValue_calcSize(UA_DataValue *dataValue) {
  887. Int32 length = 0;
  888. length += sizeof(Byte); //dataValue->EncodingMask
  889. if (dataValue->EncodingMask & 0x01) {
  890. length += Variant_calcSize(&(dataValue->Value));
  891. }
  892. if (dataValue->EncodingMask & 0x02) {
  893. length += sizeof(UInt32); //dataValue->Status
  894. }
  895. if (dataValue->EncodingMask & 0x04) {
  896. length += sizeof(Int64); //dataValue->SourceTimestamp
  897. }
  898. if (dataValue->EncodingMask & 0x08) {
  899. length += sizeof(Int64); //dataValue->ServerTimestamp
  900. }
  901. if (dataValue->EncodingMask & 0x10) {
  902. length += sizeof(Int64); //dataValue->SourcePicoseconds
  903. }
  904. if (dataValue->EncodingMask & 0x20) {
  905. length += sizeof(Int64); //dataValue->ServerPicoseconds
  906. }
  907. return length;
  908. }
  909. /**
  910. * DiagnosticInfo
  911. * Part: 4
  912. * Chapter: 7.9
  913. * Page: 116
  914. */
  915. Int32 decodeDiagnosticInfo(char const * buf, Int32 *pos,
  916. UA_DiagnosticInfo *dstDiagnosticInfo) {
  917. Byte encodingByte = (buf[*pos]);
  918. Byte mask;
  919. for (mask = 1; mask <= 0x40; mask << 2) {
  920. switch (mask & encodingByte) {
  921. case DIEMT_SYMBOLIC_ID:
  922. decoder_decodeBuiltInDatatype(buf, INT32, pos,
  923. &(dstDiagnosticInfo->SymbolicId));
  924. //dstDiagnosticInfo->symbolicId = decodeInt32(buf, pos);
  925. break;
  926. case DIEMT_NAMESPACE:
  927. decoder_decodeBuiltInDatatype(buf, INT32, pos,
  928. &(dstDiagnosticInfo->NamespaceUri));
  929. //dstDiagnosticInfo->namespaceUri = decodeInt32(buf, pos);
  930. break;
  931. case DIEMT_LOCALIZED_TEXT:
  932. decoder_decodeBuiltInDatatype(buf, INT32, pos,
  933. &(dstDiagnosticInfo->LocalizedText));
  934. //dstDiagnosticInfo->localizesText = decodeInt32(buf, pos);
  935. break;
  936. case DIEMT_LOCALE:
  937. decoder_decodeBuiltInDatatype(buf, INT32, pos,
  938. &(dstDiagnosticInfo->Locale));
  939. //dstDiagnosticInfo->locale = decodeInt32(buf, pos);
  940. break;
  941. case DIEMT_ADDITIONAL_INFO:
  942. decoder_decodeBuiltInDatatype(buf, STRING, pos,
  943. &(dstDiagnosticInfo->AdditionalInfo));
  944. decodeUAString(buf, pos, &dstDiagnosticInfo->AdditionalInfo);
  945. break;
  946. case DIEMT_INNER_STATUS_CODE:
  947. decoder_decodeBuiltInDatatype(buf, STATUS_CODE, pos,
  948. &(dstDiagnosticInfo->InnerStatusCode));
  949. //dstDiagnosticInfo->innerStatusCode = decodeUAStatusCode(buf, pos);
  950. break;
  951. case DIEMT_INNER_DIAGNOSTIC_INFO:
  952. //TODO memory management should be checked (getting memory within a function)
  953. dstDiagnosticInfo->InnerDiagnosticInfo =
  954. (UA_DiagnosticInfo*) opcua_malloc(
  955. sizeof(UA_DiagnosticInfo));
  956. decoder_decodeBuiltInDatatype(buf, DIAGNOSTIC_INFO, pos,
  957. &(dstDiagnosticInfo->InnerDiagnosticInfo));
  958. break;
  959. }
  960. }
  961. *pos += 1;
  962. return 0;
  963. }
  964. Int32 encodeDiagnosticInfo(UA_DiagnosticInfo *diagnosticInfo, Int32 *pos,
  965. char *dstbuf) {
  966. Byte mask;
  967. int i;
  968. encoder_encodeBuiltInDatatype((void*) (&(diagnosticInfo->EncodingMask)),
  969. BYTE, pos, dstbuf);
  970. for (i = 0; i < 7; i++) {
  971. switch ( (0x01 << i) & diagnosticInfo->EncodingMask) {
  972. case DIEMT_SYMBOLIC_ID:
  973. // puts("diagnosticInfo symbolic id");
  974. encoder_encodeBuiltInDatatype((void*) &(diagnosticInfo->SymbolicId),
  975. INT32, pos, dstbuf);
  976. break;
  977. case DIEMT_NAMESPACE:
  978. encoder_encodeBuiltInDatatype(
  979. (void*) &(diagnosticInfo->NamespaceUri), INT32, pos,
  980. dstbuf);
  981. break;
  982. case DIEMT_LOCALIZED_TEXT:
  983. encoder_encodeBuiltInDatatype(
  984. (void*) &(diagnosticInfo->LocalizedText), INT32, pos,
  985. dstbuf);
  986. break;
  987. case DIEMT_LOCALE:
  988. encoder_encodeBuiltInDatatype((void*) &(diagnosticInfo->Locale),
  989. INT32, pos, dstbuf);
  990. break;
  991. case DIEMT_ADDITIONAL_INFO:
  992. encoder_encodeBuiltInDatatype(
  993. (void*) &(diagnosticInfo->AdditionalInfo), STRING, pos,
  994. dstbuf);
  995. break;
  996. case DIEMT_INNER_STATUS_CODE:
  997. encoder_encodeBuiltInDatatype(
  998. (void*) &(diagnosticInfo->InnerStatusCode), STATUS_CODE,
  999. pos, dstbuf);
  1000. break;
  1001. case DIEMT_INNER_DIAGNOSTIC_INFO:
  1002. encoder_encodeBuiltInDatatype(
  1003. (void*) &(diagnosticInfo->InnerDiagnosticInfo),
  1004. DIAGNOSTIC_INFO, pos, dstbuf);
  1005. break;
  1006. }
  1007. }
  1008. return UA_NO_ERROR;
  1009. }
  1010. Int32 diagnosticInfo_calcSize(UA_DiagnosticInfo *diagnosticInfo) {
  1011. Int32 length = 0;
  1012. Byte mask;
  1013. length += sizeof(Byte); // EncodingMask
  1014. for (mask = 0x01; mask <= 0x40; mask *= 2) {
  1015. switch (mask & (diagnosticInfo->EncodingMask)) {
  1016. case DIEMT_SYMBOLIC_ID:
  1017. // puts("diagnosticInfo symbolic id");
  1018. length += sizeof(Int32);
  1019. break;
  1020. case DIEMT_NAMESPACE:
  1021. length += sizeof(Int32);
  1022. break;
  1023. case DIEMT_LOCALIZED_TEXT:
  1024. length += sizeof(Int32);
  1025. break;
  1026. case DIEMT_LOCALE:
  1027. length += sizeof(Int32);
  1028. break;
  1029. case DIEMT_ADDITIONAL_INFO:
  1030. length += UAString_calcSize(&(diagnosticInfo->AdditionalInfo));
  1031. break;
  1032. case DIEMT_INNER_STATUS_CODE:
  1033. length += sizeof(UA_StatusCode);
  1034. break;
  1035. case DIEMT_INNER_DIAGNOSTIC_INFO:
  1036. length += diagnosticInfo_calcSize(
  1037. diagnosticInfo->InnerDiagnosticInfo);
  1038. break;
  1039. }
  1040. }
  1041. return length;
  1042. }
  1043. /**
  1044. * RequestHeader
  1045. * Part: 4
  1046. * Chapter: 7.26
  1047. * Page: 132
  1048. */
  1049. /** \copydoc decodeRequestHeader */
  1050. Int32 decodeRequestHeader(const AD_RawMessage *srcRaw, Int32 *pos,
  1051. UA_AD_RequestHeader *dstRequestHeader) {
  1052. return decoder_decodeRequestHeader(srcRaw->message, pos, dstRequestHeader);
  1053. }
  1054. Int32 decoder_decodeRequestHeader(char const * message, Int32 *pos,
  1055. UA_AD_RequestHeader *dstRequestHeader) {
  1056. // 62541-4 §5.5.2.2 OpenSecureChannelServiceParameters
  1057. // requestHeader - common request parameters. The authenticationToken is always omitted
  1058. decoder_decodeBuiltInDatatype(message, NODE_ID, pos,
  1059. &(dstRequestHeader->authenticationToken));
  1060. decoder_decodeBuiltInDatatype(message, DATE_TIME, pos,
  1061. &(dstRequestHeader->timestamp));
  1062. decoder_decodeBuiltInDatatype(message, UINT32, pos,
  1063. &(dstRequestHeader->requestHandle));
  1064. decoder_decodeBuiltInDatatype(message, UINT32, pos,
  1065. &(dstRequestHeader->returnDiagnostics));
  1066. decoder_decodeBuiltInDatatype(message, STRING, pos,
  1067. &(dstRequestHeader->auditEntryId));
  1068. decoder_decodeBuiltInDatatype(message, UINT32, pos,
  1069. &(dstRequestHeader->timeoutHint));
  1070. decoder_decodeBuiltInDatatype(message, EXTENSION_OBJECT, pos,
  1071. &(dstRequestHeader->additionalHeader));
  1072. // AdditionalHeader will stay empty, need to be changed if there is relevant information
  1073. return 0;
  1074. }
  1075. /**
  1076. * ResponseHeader
  1077. * Part: 4
  1078. * Chapter: 7.27
  1079. * Page: 133
  1080. */
  1081. /** \copydoc encodeResponseHeader */
  1082. Int32 encodeResponseHeader(UA_AD_ResponseHeader const * responseHeader,
  1083. Int32 *pos, UA_ByteString *dstBuf) {
  1084. encodeUADateTime(responseHeader->timestamp, pos, dstBuf->Data);
  1085. encodeIntegerId(responseHeader->requestHandle, pos, dstBuf->Data);
  1086. encodeUInt32(responseHeader->serviceResult, pos, dstBuf->Data);
  1087. encodeDiagnosticInfo(responseHeader->serviceDiagnostics, pos, dstBuf->Data);
  1088. encoder_encodeBuiltInDatatypeArray(responseHeader->stringTable,
  1089. responseHeader->noOfStringTable, STRING_ARRAY, pos, dstBuf->Data);
  1090. encodeExtensionObject(responseHeader->additionalHeader, pos, dstBuf->Data);
  1091. //Kodieren von String Datentypen
  1092. return 0;
  1093. }
  1094. Int32 extensionObject_calcSize(UA_ExtensionObject *extensionObject) {
  1095. Int32 length = 0;
  1096. length += nodeId_calcSize(&(extensionObject->TypeId));
  1097. length += sizeof(Byte); //The EncodingMask Byte
  1098. if (extensionObject->Encoding == BODY_IS_BYTE_STRING
  1099. || extensionObject->Encoding == BODY_IS_XML_ELEMENT) {
  1100. length += UAByteString_calcSize(&(extensionObject->Body));
  1101. }
  1102. return length;
  1103. }
  1104. Int32 responseHeader_calcSize(UA_AD_ResponseHeader *responseHeader) {
  1105. Int32 i;
  1106. Int32 length = 0;
  1107. // UtcTime timestamp 8
  1108. length += sizeof(UA_DateTime);
  1109. // IntegerId requestHandle 4
  1110. length += sizeof(UA_AD_IntegerId);
  1111. // StatusCode serviceResult 4
  1112. length += sizeof(UA_StatusCode);
  1113. // DiagnosticInfo serviceDiagnostics
  1114. length += diagnosticInfo_calcSize(responseHeader->serviceDiagnostics);
  1115. // String stringTable[], see 62541-6 § 5.2.4
  1116. length += sizeof(Int32); // Length of Stringtable always
  1117. if (responseHeader->noOfStringTable > 0) {
  1118. for (i = 0; i < responseHeader->noOfStringTable; i++) {
  1119. length += UAString_calcSize(responseHeader->stringTable[i]);
  1120. }
  1121. }
  1122. // ExtensibleObject additionalHeader
  1123. length += extensionObject_calcSize(responseHeader->additionalHeader);
  1124. return length;
  1125. }