opcua_basictypes.c 38 KB

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