opcua_basictypes.c 33 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075
  1. /*
  2. * opcua_basictypes.c
  3. *
  4. * Created on: 13.03.2014
  5. * Author: mrt
  6. */
  7. #include "opcua.h"
  8. #include <stdlib.h>
  9. #include <string.h>
  10. Int32 UA_calcSize(void* const data, UInt32 type) {
  11. return (UA_[type].calcSize)(data);
  12. }
  13. Int32 UA_Array_calcSize(Int32 nElements, Int32 type, void const ** data) {
  14. int length = sizeof(UA_Int32);
  15. int i;
  16. if (nElements > 0) {
  17. for(i=0; i<nElements;i++,data++) {
  18. length += UA_calcSize(data,type);
  19. }
  20. }
  21. return length;
  22. }
  23. Int32 UA_Array_encode(void const **src, Int32 noElements, Int32 type, Int32* pos, char * dst) {
  24. //TODO: Implement
  25. return UA_ERR_NOT_IMPLEMENTED;
  26. }
  27. Int32 UA_Array_decode(char const * src, Int32 noElements, Int32 type, Int32* pos, void const **dst) {
  28. //TODO: Implement
  29. return UA_ERR_NOT_IMPLEMENTED;
  30. }
  31. Int32 UA_free(void * ptr){
  32. free(ptr);
  33. return UA_SUCCESS;
  34. }
  35. Int32 UA_alloc(void ** ptr, int size){
  36. *ptr = malloc(size);
  37. if(*ptr == UA_NULL) return UA_ERR_NO_MEMORY;
  38. return UA_SUCCESS;
  39. }
  40. Int32 UA_memcpy(void * dst, void const * src, int size){
  41. memcpy(dst, src, size);
  42. return UA_SUCCESS;
  43. }
  44. UA_TYPE_METHOD_CALCSIZE_SIZEOF(UA_Boolean)
  45. Int32 UA_Boolean_encode(UA_Boolean const * src, Int32* pos, char * dst) {
  46. UA_Boolean tmpBool = ((*src > 0) ? UA_TRUE : UA_FALSE);
  47. memcpy(&(dst[(*pos)++]), &tmpBool, sizeof(UA_Boolean));
  48. return UA_SUCCESS;
  49. }
  50. Int32 UA_Boolean_decode(char const * src, Int32* pos, UA_Boolean * dst) {
  51. *dst = ((UA_Boolean) (src[(*pos)++]) > 0) ? UA_TRUE : UA_FALSE;
  52. return UA_SUCCESS;
  53. }
  54. UA_TYPE_METHOD_DELETE_FREE(UA_Boolean)
  55. UA_TYPE_METHOD_DELETEMEMBERS_NOACTION(UA_Boolean)
  56. UA_TYPE_METHOD_CALCSIZE_SIZEOF(UA_Byte)
  57. Int32 UA_Byte_encode(UA_Byte const * src, Int32* pos, char * dst) {
  58. *dst = src[(*pos)++];
  59. return UA_SUCCESS;
  60. }
  61. Int32 UA_Byte_decode(char const * src, Int32* pos, UA_Byte * dst) {
  62. memcpy(&(dst[(*pos)++]), src, sizeof(UA_Byte));
  63. return UA_SUCCESS;
  64. }
  65. UA_TYPE_METHOD_DELETE_FREE(UA_Byte)
  66. UA_TYPE_METHOD_DELETEMEMBERS_NOACTION(UA_Byte)
  67. UA_TYPE_METHOD_CALCSIZE_SIZEOF(UA_SByte)
  68. Int32 UA_SByte_encode(UA_SByte const * src, Int32* pos, char * dst) {
  69. dst[(*pos)++] = *src;
  70. return UA_SUCCESS;
  71. }
  72. Int32 UA_SByte_decode(char const * src, Int32* pos, UA_SByte * dst) {
  73. *dst = src[(*pos)++];
  74. return 1;
  75. }
  76. UA_TYPE_METHOD_DELETE_FREE(UA_SByte)
  77. UA_TYPE_METHOD_DELETEMEMBERS_NOACTION(UA_SByte)
  78. UA_TYPE_METHOD_CALCSIZE_SIZEOF(UA_UInt16)
  79. Int32 UA_UInt16_encode(UA_UInt16 const *src, Int32* pos, char * dst) {
  80. memcpy(&(dst[*pos]), src, sizeof(UA_UInt16));
  81. *pos += sizeof(UA_UInt16);
  82. return UA_SUCCESS;
  83. }
  84. Int32 UA_UInt16_decode(char const * src, Int32* pos, UA_UInt16* dst) {
  85. Byte t1 = src[(*pos)++];
  86. UInt16 t2 = (UInt16) (src[(*pos)++] << 8);
  87. *dst = t1 + t2;
  88. return UA_SUCCESS;
  89. }
  90. UA_TYPE_METHOD_DELETE_FREE(UA_UInt16)
  91. UA_TYPE_METHOD_DELETEMEMBERS_NOACTION(UA_UInt16)
  92. UA_TYPE_METHOD_CALCSIZE_SIZEOF(UA_Int16)
  93. Int32 UA_Int16_encode(UA_Int16 const * src, Int32* pos, char* dst) {
  94. memcpy(&(dst[*pos]), src, sizeof(UA_Int16));
  95. *pos += sizeof(UA_Int16);
  96. return UA_SUCCESS;
  97. }
  98. Int32 UA_Int16_decode(char const * src, Int32* pos, UA_Int16 *dst) {
  99. Int16 t1 = (Int16) (((SByte) (src[(*pos)++]) & 0xFF));
  100. Int16 t2 = (Int16) (((SByte) (src[(*pos)++]) & 0xFF) << 8);
  101. *dst = t1 + t2;
  102. return UA_SUCCESS;
  103. }
  104. UA_TYPE_METHOD_DELETE_FREE(UA_Int16)
  105. UA_TYPE_METHOD_DELETEMEMBERS_NOACTION(UA_Int16)
  106. UA_TYPE_METHOD_CALCSIZE_SIZEOF(UA_Int32)
  107. Int32 UA_Int32_encode(UA_Int32 const * src, Int32* pos, char *dst) {
  108. memcpy(&(dst[*pos]), src, sizeof(UA_Int32));
  109. *pos += sizeof(UA_Int32);
  110. return UA_SUCCESS;
  111. }
  112. Int32 UA_Int32_decode(char const * src, Int32* pos, UA_Int32* dst) {
  113. Int32 t1 = (Int32) (((SByte) (src[(*pos)++]) & 0xFF));
  114. Int32 t2 = (Int32) (((SByte) (src[(*pos)++]) & 0xFF) << 8);
  115. Int32 t3 = (Int32) (((SByte) (src[(*pos)++]) & 0xFF) << 16);
  116. Int32 t4 = (Int32) (((SByte) (src[(*pos)++]) & 0xFF) << 24);
  117. *dst = t1 + t2 + t3 + t4;
  118. return UA_SUCCESS;
  119. }
  120. UA_TYPE_METHOD_DELETE_FREE(UA_Int32)
  121. UA_TYPE_METHOD_DELETEMEMBERS_NOACTION(UA_Int32)
  122. UA_TYPE_METHOD_CALCSIZE_SIZEOF(UA_UInt32)
  123. Int32 UA_UInt32_encode(UA_UInt32 const * src, Int32* pos, char *dst) {
  124. memcpy(&(dst[*pos]), src, sizeof(UA_UInt32));
  125. *pos += sizeof(UA_UInt32);
  126. return UA_SUCCESS;
  127. }
  128. Int32 UA_UInt32_decode(char const * src, Int32* pos, UA_UInt32 *dst) {
  129. UInt32 t1 = (UInt32) src[(*pos)++];
  130. UInt32 t2 = (UInt32) src[(*pos)++] << 8;
  131. UInt32 t3 = (UInt32) src[(*pos)++] << 16;
  132. UInt32 t4 = (UInt32) src[(*pos)++] << 24;
  133. *dst = t1 + t2 + t3 + t4;
  134. return UA_SUCCESS;
  135. }
  136. UA_TYPE_METHOD_DELETE_FREE(UA_UInt32)
  137. UA_TYPE_METHOD_DELETEMEMBERS_NOACTION(UA_UInt32)
  138. UA_TYPE_METHOD_CALCSIZE_SIZEOF(UA_Int64)
  139. Int32 UA_Int64_encode(UA_Int64 const * src, Int32* pos, char *dst) {
  140. memcpy(&(dst[*pos]), src, sizeof(UA_Int64));
  141. *pos += sizeof(UA_Int64);
  142. return UA_SUCCESS;
  143. }
  144. Int32 UA_Int64_decode(char const * src, Int32* pos, UA_Int64* dst) {
  145. Int64 t1 = (Int64) src[(*pos)++];
  146. Int64 t2 = (Int64) src[(*pos)++] << 8;
  147. Int64 t3 = (Int64) src[(*pos)++] << 16;
  148. Int64 t4 = (Int64) src[(*pos)++] << 24;
  149. Int64 t5 = (Int64) src[(*pos)++] << 32;
  150. Int64 t6 = (Int64) src[(*pos)++] << 40;
  151. Int64 t7 = (Int64) src[(*pos)++] << 48;
  152. Int64 t8 = (Int64) src[(*pos)++] << 56;
  153. *dst = t1 + t2 + t3 + t4 + t5 + t6 + t7 + t8;
  154. return UA_SUCCESS;
  155. }
  156. UA_TYPE_METHOD_DELETE_FREE(UA_Int64)
  157. UA_TYPE_METHOD_DELETEMEMBERS_NOACTION(UA_Int64)
  158. UA_TYPE_METHOD_CALCSIZE_SIZEOF(UA_UInt64)
  159. Int32 UA_UInt64_encode(UA_UInt64 const * src , Int32* pos, char * dst) {
  160. memcpy(&(dst[*pos]), src, sizeof(UA_UInt64));
  161. *pos += sizeof(UInt64);
  162. return UA_SUCCESS;
  163. }
  164. Int32 UA_UInt64_decode(char const * src, Int32* pos, UA_UInt64* dst) {
  165. UInt64 t1 = (UInt64) src[(*pos)++];
  166. UInt64 t2 = (UInt64) src[(*pos)++] << 8;
  167. UInt64 t3 = (UInt64) src[(*pos)++] << 16;
  168. UInt64 t4 = (UInt64) src[(*pos)++] << 24;
  169. UInt64 t5 = (UInt64) src[(*pos)++] << 32;
  170. UInt64 t6 = (UInt64) src[(*pos)++] << 40;
  171. UInt64 t7 = (UInt64) src[(*pos)++] << 48;
  172. UInt64 t8 = (UInt64) src[(*pos)++] << 56;
  173. *dst = t1 + t2 + t3 + t4 + t5 + t6 + t7 + t8;
  174. return UA_SUCCESS;
  175. }
  176. UA_TYPE_METHOD_DELETE_FREE(UA_UInt64)
  177. UA_TYPE_METHOD_DELETEMEMBERS_NOACTION(UA_UInt64)
  178. UA_TYPE_METHOD_CALCSIZE_SIZEOF(UA_Float)
  179. Int32 UA_Float_decode(char const * src, Int32* pos, UA_Float* dst) {
  180. // TODO: not yet implemented
  181. memcpy(dst, &(src[*pos]), sizeof(UA_Float));
  182. *pos += sizeof(UA_Float);
  183. return UA_SUCCESS;
  184. }
  185. Int32 UA_Float_encode(UA_Float const * src, Int32* pos, char *dst) {
  186. // TODO: not yet implemented
  187. memcpy(&(dst[*pos]), src, sizeof(UA_Float));
  188. *pos += sizeof(UA_Float);
  189. return UA_SUCCESS;
  190. }
  191. UA_TYPE_METHOD_DELETE_FREE(UA_Float)
  192. UA_TYPE_METHOD_DELETEMEMBERS_NOACTION(UA_Float)
  193. UA_TYPE_METHOD_CALCSIZE_SIZEOF(UA_Double)
  194. Int32 UA_Double_decode(char const * src, Int32* pos, UA_Double * dst) {
  195. // TODO: not yet implemented
  196. Double tmpDouble;
  197. tmpDouble = (Double) (src[*pos]);
  198. *pos += sizeof(UA_Double);
  199. *dst = tmpDouble;
  200. return UA_SUCCESS;
  201. }
  202. Int32 UA_Double_encode(UA_Double const * src, Int32 *pos, char * dst) {
  203. // TODO: not yet implemented
  204. memcpy(&(dst[*pos]), src, sizeof(UA_Double));
  205. *pos *= sizeof(UA_Double);
  206. return UA_SUCCESS;
  207. }
  208. UA_TYPE_METHOD_DELETE_FREE(UA_Double)
  209. UA_TYPE_METHOD_DELETEMEMBERS_NOACTION(UA_Double)
  210. Int32 UA_String_calcSize(UA_String const * string) {
  211. if (string == UA_NULL) {
  212. // internal size for UA_memalloc
  213. return sizeof(UA_String);
  214. } else {
  215. // binary encoding size
  216. if (string->length > 0) {
  217. return sizeof(UA_Int32) + string->length * sizeof(UA_Byte);
  218. } else {
  219. return sizeof(UA_Int32);
  220. }
  221. }
  222. }
  223. Int32 UA_String_encode(UA_String const * src, Int32* pos, char *dst) {
  224. UA_Int32_encode(&(src->length),pos,dst);
  225. if (src->length > 0) {
  226. UA_memcpy((void*)&(dst[*pos]), src->data, src->length);
  227. *pos += src->length;
  228. }
  229. return UA_SUCCESS;
  230. }
  231. Int32 UA_String_decode(char const * src, Int32* pos, UA_String * dst) {
  232. Int32 retval = UA_SUCCESS;
  233. retval |= UA_Int32_decode(src,pos,&(dst->length));
  234. if (dst->length > 0) {
  235. retval |= UA_alloc(&(dst->data),dst->length);
  236. retval |= UA_memcpy((void*)&(src[*pos]),dst->data,dst->length);
  237. *pos += dst->length;
  238. } else {
  239. dst->data = UA_NULL;
  240. }
  241. return retval;
  242. }
  243. UA_TYPE_METHOD_DELETE_STRUCT(UA_String)
  244. Int32 UA_String_deleteMembers(UA_String* p) { return UA_free(p->data); };
  245. Int32 UA_String_copy(UA_String const * src, UA_String* dst) {
  246. Int32 retval = UA_SUCCESS;
  247. dst->length = src->length;
  248. dst->data = UA_NULL;
  249. if (src->length > 0) {
  250. retval |= UA_alloc(&(dst->data), src->length);
  251. if (retval == UA_SUCCESS) {
  252. retval |= UA_memcpy((void*)dst->data, src->data, src->length);
  253. }
  254. }
  255. return retval;
  256. }
  257. UA_String UA_String_null = { -1, UA_NULL };
  258. UA_Byte UA_Byte_securityPoliceNoneData[] = "http://opcfoundation.org/UA/SecurityPolicy#None";
  259. UA_String UA_String_securityPoliceNone = { sizeof(UA_Byte_securityPoliceNoneData), UA_Byte_securityPoliceNoneData };
  260. // TODO: should we really handle UA_String and UA_ByteString the same way?
  261. UA_TYPE_METHOD_CALCSIZE_AS(UA_ByteString, UA_String)
  262. UA_TYPE_METHOD_ENCODE_AS(UA_ByteString, UA_String)
  263. UA_TYPE_METHOD_DECODE_AS(UA_ByteString, UA_String)
  264. UA_TYPE_METHOD_DELETE_AS(UA_ByteString, UA_String)
  265. UA_TYPE_METHOD_DELETEMEMBERS_AS(UA_ByteString, UA_String)
  266. Int32 UA_Guid_calcSize(UA_Guid const * p) {
  267. if (p == UA_NULL) {
  268. return sizeof(UA_Guid);
  269. } else {
  270. return 0
  271. + sizeof(p->data1)
  272. + sizeof(p->data2)
  273. + sizeof(p->data3)
  274. + UA_ByteString_calcSize(&(p->data4))
  275. ;
  276. }
  277. }
  278. Int32 UA_Guid_encode(UA_Guid const *src, Int32* pos, char *dst) {
  279. Int32 retval = UA_SUCCESS;
  280. retval |= UA_UInt32_encode(&(src->data1), pos, dst);
  281. retval |= UA_UInt16_encode(&(src->data2), pos, dst);
  282. retval |= UA_UInt16_encode(&(src->data3), pos, dst);
  283. retval |= UA_ByteString_encode(&(src->data4), pos, dst);
  284. return UA_SUCCESS;
  285. }
  286. Int32 UA_Guid_decode(char const * src, Int32* pos, UA_Guid *dst) {
  287. Int32 retval = UA_SUCCESS;
  288. retval |= UA_Int32_decode(src,pos,&(dst->data1));
  289. retval |= UA_Int16_decode(src,pos,&(dst->data2));
  290. retval |= UA_Int16_decode(src,pos,&(dst->data3));
  291. retval |= UA_ByteString_decode(src,pos,&(dst->data4));
  292. return retval;
  293. }
  294. UA_TYPE_METHOD_DELETE_STRUCT(UA_Guid)
  295. Int32 UA_Guid_deleteMembers(UA_Guid* p) { return UA_ByteString_delete(&(p->data4)); };
  296. Int32 UA_LocalizedText_calcSize(UA_LocalizedText const * p) {
  297. Int32 length = 0;
  298. if (p==UA_NULL) {
  299. // size for UA_memalloc
  300. length = sizeof(UA_LocalizedText);
  301. } else {
  302. // size for binary encoding
  303. length += p->encodingMask;
  304. if (p->encodingMask & 0x01) {
  305. length += UA_String_calcSize(&(p->locale));
  306. }
  307. if (p->encodingMask & 0x02) {
  308. length += UA_String_calcSize(&(p->text));
  309. }
  310. }
  311. return length;
  312. }
  313. Int32 UA_LocalizedText_encode(UA_LocalizedText const * src, Int32 *pos,
  314. char * dst) {
  315. Int32 retval = UA_SUCCESS;
  316. retval |= UA_Byte_encode(&(src->encodingMask),pos,dst);
  317. if (src->encodingMask & 0x01) {
  318. UA_String_encode(&(src->locale),pos,dst);
  319. }
  320. if (src->encodingMask & 0x02) {
  321. UA_String_encode(&(src->text),pos,dst);
  322. }
  323. return retval;
  324. }
  325. Int32 UA_LocalizedText_decode(char const * src, Int32 *pos,
  326. UA_LocalizedText *dst) {
  327. Int32 retval = UA_SUCCESS;
  328. retval |= UA_String_copy(&UA_String_null,&(dst->locale));
  329. retval |= UA_String_copy(&UA_String_null,&(dst->text));
  330. retval |= UA_Byte_decode(src,pos,&(dst->encodingMask));
  331. if (dst->encodingMask & 0x01) {
  332. retval |= UA_String_decode(src,pos,&(dst->locale));
  333. }
  334. if (dst->encodingMask & 0x02) {
  335. retval |= UA_String_decode(src,pos,&(dst->text));
  336. }
  337. return retval;
  338. }
  339. UA_TYPE_METHOD_DELETE_STRUCT(UA_LocalizedText)
  340. Int32 UA_LocalizedText_deleteMembers(UA_LocalizedText* p) {
  341. return UA_SUCCESS
  342. || UA_String_deleteMembers(&(p->locale))
  343. || UA_String_deleteMembers(&(p->text))
  344. ;
  345. };
  346. /* Serialization of UA_NodeID is specified in 62541-6, §5.2.2.9 */
  347. Int32 UA_NodeId_calcSize(UA_NodeId const *p) {
  348. Int32 length = 0;
  349. if (p == UA_NULL) {
  350. length = sizeof(UA_NodeId);
  351. } else {
  352. switch (p->encodingByte) {
  353. case UA_NodeIdType_TwoByte:
  354. length += 2 * sizeof(UA_Byte);
  355. break;
  356. case UA_NodeIdType_FourByte:
  357. length += 4 * sizeof(UA_Byte);
  358. break;
  359. case UA_NodeIdType_Numeric:
  360. length += sizeof(UA_Byte) + sizeof(UA_UInt16) + sizeof(UInt32);
  361. break;
  362. case UA_NodeIdType_String:
  363. length += sizeof(UA_Byte) + sizeof(UA_UInt16) + UA_String_calcSize(&(p->identifier.string));
  364. break;
  365. case UA_NodeIdType_Guid:
  366. length += sizeof(UA_Byte) + sizeof(UA_UInt16) + UA_Guid_calcSize(&(p->identifier.guid));
  367. break;
  368. case UA_NodeIdType_ByteString:
  369. length += sizeof(UA_Byte) + sizeof(UA_UInt16) + UA_ByteString_calcSize(&(p->identifier.byteString));
  370. break;
  371. default:
  372. break;
  373. }
  374. }
  375. return length;
  376. }
  377. Int32 UA_NodeId_encode(UA_NodeId const * src, Int32* pos, char *dst) {
  378. // temporary variables for endian-save code
  379. UA_Byte srcByte;
  380. UA_UInt16 srcUInt16;
  381. int retval = UA_SUCCESS;
  382. retval |= UA_Byte_encode(&(src->encodingByte),pos,dst);
  383. switch (src->encodingByte) {
  384. case UA_NodeIdType_TwoByte:
  385. srcByte = src->identifier.numeric;
  386. retval |= UA_Byte_encode(&srcByte,pos,dst);
  387. break;
  388. case UA_NodeIdType_FourByte:
  389. srcByte = src->namespace;
  390. srcUInt16 = src->identifier.numeric;
  391. retval |= UA_Byte_encode(&srcByte,pos,dst);
  392. retval |= UA_UInt16_encode(&srcUInt16,pos,dst);
  393. break;
  394. case UA_NodeIdType_Numeric:
  395. retval |= UA_UInt16_encode(&(src->namespace), pos, dst);
  396. retval |= UA_UInt32_encode(&(src->identifier.numeric), pos, dst);
  397. break;
  398. case UA_NodeIdType_String:
  399. retval |= UA_UInt16_encode(&(src->namespace), pos, dst);
  400. retval |= UA_String_encode(&(src->identifier.string), pos, dst);
  401. break;
  402. case UA_NodeIdType_Guid:
  403. retval |= UA_UInt16_encode(&(src->namespace), pos, dst);
  404. retval |= UA_Guid_encode(&(src->identifier.guid), pos, dst);
  405. break;
  406. case UA_NodeIdType_ByteString:
  407. retval |= UA_UInt16_encode(&(src->namespace), pos, dst);
  408. retval |= UA_ByteString_encode(&(src->identifier.byteString), pos, dst);
  409. break;
  410. }
  411. return retval;
  412. }
  413. Int32 UA_NodeId_decode(char const * src, Int32* pos, UA_NodeId *dst) {
  414. int retval = UA_SUCCESS;
  415. // temporary variables to overcome decoder's non-endian-saveness for datatypes
  416. Byte dstByte;
  417. UInt16 dstUInt16;
  418. retval |= UA_Byte_decode(src,pos,&(dst->encodingByte));
  419. switch (dst->encodingByte) {
  420. case UA_NodeIdType_TwoByte: // Table 7
  421. retval |=UA_Byte_decode(src, pos, &dstByte);
  422. dst->identifier.numeric = dstByte;
  423. dst->namespace = 0; // default namespace
  424. break;
  425. case UA_NodeIdType_FourByte: // Table 8
  426. retval |=UA_Byte_decode(src, pos, &dstByte);
  427. dst->namespace= dstByte;
  428. retval |=UA_UInt16_decode(src, pos, &dstUInt16);
  429. dst->identifier.numeric = dstUInt16;
  430. break;
  431. case UA_NodeIdType_Numeric: // Table 6, first entry
  432. retval |=UA_Int16_decode(src,pos,&(dst->namespace));
  433. retval |=UA_Int32_decode(src,pos,&(dst->identifier.numeric));
  434. break;
  435. case UA_NodeIdType_String: // Table 6, second entry
  436. retval |=UA_Int16_decode(src,pos,&(dst->namespace));
  437. retval |=UA_String_decode(src,pos,&(dst->identifier.string));
  438. break;
  439. case UA_NodeIdType_Guid: // Table 6, third entry
  440. retval |=UA_Int16_decode(src,pos,&(dst->namespace));
  441. retval |=UA_Guid_decode(src,pos,&(dst->identifier.guid));
  442. break;
  443. case UA_NodeIdType_ByteString: // Table 6, "OPAQUE"
  444. retval |=UA_Int16_decode(src,pos,&(dst->namespace));
  445. retval |=UA_ByteString_decode(src,pos,&(dst->identifier.byteString));
  446. break;
  447. }
  448. return retval;
  449. }
  450. UA_TYPE_METHOD_DELETE_STRUCT(UA_NodeId)
  451. Int32 UA_NodeId_deleteMembers(UA_NodeId* p) {
  452. int retval = UA_SUCCESS;
  453. switch (p->encodingByte) {
  454. case UA_NodeIdType_TwoByte:
  455. case UA_NodeIdType_FourByte:
  456. case UA_NodeIdType_Numeric:
  457. // nothing to do
  458. break;
  459. case UA_NodeIdType_String: // Table 6, second entry
  460. retval |= UA_String_deleteMembers(&(p->identifier.string));
  461. break;
  462. case UA_NodeIdType_Guid: // Table 6, third entry
  463. retval |= UA_Guid_deleteMembers(&(p->identifier.guid));
  464. break;
  465. case UA_NodeIdType_ByteString: // Table 6, "OPAQUE"
  466. retval |= UA_ByteString_deleteMembers(&(p->identifier.byteString));
  467. break;
  468. }
  469. return retval;
  470. }
  471. //FIXME: Sten Where do these two flags come from?
  472. #define NIEVT_NAMESPACE_URI_FLAG 0x80 //Is only for ExpandedNodeId required
  473. #define NIEVT_SERVERINDEX_FLAG 0x40 //Is only for ExpandedNodeId required
  474. Int32 UA_ExpandedNodeId_calcSize(UA_ExpandedNodeId const * p) {
  475. Int32 length = 0;
  476. if (p == UA_NULL) {
  477. length = sizeof(UA_ExpandedNodeId);
  478. } else {
  479. length = UA_NodeId_calcSize(&(p->nodeId));
  480. if (p->nodeId.encodingByte & NIEVT_NAMESPACE_URI_FLAG) {
  481. length += UA_String_calcSize(&(p->namespaceUri)); //p->namespaceUri
  482. }
  483. if (p->nodeId.encodingByte & NIEVT_SERVERINDEX_FLAG) {
  484. length += sizeof(UA_UInt32); //p->serverIndex
  485. }
  486. }
  487. return length;
  488. }
  489. Int32 UA_ExpandedNodeId_encode(UA_ExpandedNodeId const * src, Int32* pos, char *dst) {
  490. UInt32 retval = UA_SUCCESS;
  491. retval |= UA_NodeId_encode(&(src->nodeId),pos,dst);
  492. if (src->nodeId.encodingByte & NIEVT_NAMESPACE_URI_FLAG) {
  493. retval |= UA_String_encode(&(src->namespaceUri),pos,dst);
  494. }
  495. if (src->nodeId.encodingByte & NIEVT_SERVERINDEX_FLAG) {
  496. retval |= UA_UInt32_encode(&(src->serverIndex),pos,dst);
  497. }
  498. return retval;
  499. }
  500. Int32 UA_ExpandedNodeId_decode(char const * src, Int32* pos,
  501. UA_ExpandedNodeId *dst) {
  502. UInt32 retval = UA_SUCCESS;
  503. retval |= UA_NodeId_decode(src,pos,&(dst->nodeId));
  504. if (dst->nodeId.encodingByte & NIEVT_NAMESPACE_URI_FLAG) {
  505. dst->nodeId.namespace = 0;
  506. retval |= UA_String_decode(src,pos,&(dst->namespaceUri));
  507. } else {
  508. retval |= UA_String_copy(&UA_String_null, &(dst->namespaceUri));
  509. }
  510. if (dst->nodeId.encodingByte & NIEVT_SERVERINDEX_FLAG) {
  511. retval |= UA_UInt32_decode(src,pos,&(dst->serverIndex));
  512. }
  513. return retval;
  514. }
  515. UA_TYPE_METHOD_DELETE_STRUCT(UA_ExpandedNodeId)
  516. Int32 UA_ExpandedNodeId_deleteMembers(UA_ExpandedNodeId* p) {
  517. Int32 retval = UA_SUCCESS;
  518. retval |= UA_NodeId_deleteMembers(&(p->nodeId));
  519. retval |= UA_String_deleteMembers(&(p->namespaceUri));
  520. return retval;
  521. }
  522. Int32 UA_ExtensionObject_calcSize(UA_ExtensionObject const * p) {
  523. Int32 length = 0;
  524. if (p == UA_NULL) {
  525. length = sizeof(UA_ExtensionObject);
  526. } else {
  527. length += UA_NodeId_calcSize(&(p->typeId));
  528. length += sizeof(Byte); //p->encoding
  529. switch (p->encoding) {
  530. case 0x00:
  531. length += sizeof(UA_Int32); //p->body.length
  532. break;
  533. case 0x01:
  534. length += UA_ByteString_calcSize(&(p->body));
  535. break;
  536. case 0x02:
  537. length += UA_ByteString_calcSize(&(p->body));
  538. break;
  539. }
  540. }
  541. return length;
  542. }
  543. Int32 UA_ExtensionObject_encode(UA_ExtensionObject const *src, Int32* pos, char * dst) {
  544. Int32 retval = UA_SUCCESS;
  545. retval |= UA_NodeId_encode(&(src->typeId),pos,dst);
  546. retval |= UA_Byte_encode(&(src->encoding),pos,dst);
  547. switch (src->encoding) {
  548. case NO_BODY_IS_ENCODED:
  549. break;
  550. case BODY_IS_BYTE_STRING:
  551. case BODY_IS_XML_ELEMENT:
  552. retval |= UA_ByteString_encode(&(src->body),pos,dst);
  553. break;
  554. }
  555. return retval;
  556. }
  557. Int32 UA_ExtensionObject_decode(char const * src, Int32 *pos,
  558. UA_ExtensionObject *dst) {
  559. Int32 retval = UA_SUCCESS;
  560. retval |= UA_NodeId_decode(src,pos,&(dst->typeId));
  561. retval |= UA_Byte_decode(src,pos,&(dst->encoding));
  562. retval |= UA_String_copy(&UA_String_null, (UA_String*) &(dst->body));
  563. switch (dst->encoding) {
  564. case NO_BODY_IS_ENCODED:
  565. break;
  566. case BODY_IS_BYTE_STRING:
  567. case BODY_IS_XML_ELEMENT:
  568. retval |= UA_ByteString_decode(src,pos,&(dst->body));
  569. break;
  570. }
  571. return retval;
  572. }
  573. UA_TYPE_METHOD_DELETE_STRUCT(UA_ExtensionObject)
  574. Int32 UA_ExtensionObject_deleteMembers(UA_ExtensionObject *p) {
  575. Int32 retval = UA_SUCCESS;
  576. retval |= UA_NodeId_deleteMembers(&(p->typeId));
  577. retval |= UA_ByteString_deleteMembers(&(p->body));
  578. return retval;
  579. }
  580. // TODO: UA_DataValue_encode
  581. // TODO: UA_DataValue_decode
  582. // TODO: UA_DataValue_delete
  583. // TODO: UA_DataValue_deleteMembers
  584. /** DiagnosticInfo - Part: 4, Chapter: 7.9, Page: 116 */
  585. Int32 UA_DiagnosticInfo_decode(char const * src, Int32 *pos, UA_DiagnosticInfo *dst) {
  586. Int32 retval = UA_SUCCESS;
  587. int i;
  588. retval |= UA_Byte_decode(src, pos, &(dst->encodingMask));
  589. for (i = 0; i < 7; i++) {
  590. switch ( (0x01 << i) & dst->encodingMask) {
  591. case DIEMT_SYMBOLIC_ID:
  592. retval |= UA_Int32_decode(src, pos, &(dst->symbolicId));
  593. break;
  594. case DIEMT_NAMESPACE:
  595. retval |= UA_Int32_decode(src, pos, &(dst->namespaceUri));
  596. break;
  597. case DIEMT_LOCALIZED_TEXT:
  598. retval |= UA_Int32_decode(src, pos, &(dst->localizedText));
  599. break;
  600. case DIEMT_LOCALE:
  601. retval |= UA_Int32_decode(src, pos, &(dst->locale));
  602. break;
  603. case DIEMT_ADDITIONAL_INFO:
  604. retval |= UA_String_decode(src, pos, &(dst->additionalInfo));
  605. break;
  606. case DIEMT_INNER_STATUS_CODE:
  607. retval |= UA_StatusCode_decode(src, pos, &(dst->innerStatusCode));
  608. break;
  609. case DIEMT_INNER_DIAGNOSTIC_INFO:
  610. // innerDiagnosticInfo is a pointer to struct, therefore allocate
  611. retval |= UA_alloc((void **) &(dst->innerDiagnosticInfo),UA_DiagnosticInfo_calcSize(UA_NULL));
  612. retval |= UA_DiagnosticInfo_decode(src, pos, dst->innerDiagnosticInfo);
  613. break;
  614. }
  615. }
  616. return retval;
  617. }
  618. Int32 UA_DiagnosticInfo_encode(UA_DiagnosticInfo const *src, Int32 *pos, char *dst) {
  619. Int32 retval = UA_SUCCESS;
  620. Byte mask;
  621. int i;
  622. UA_Byte_encode(&(src->encodingMask), pos, dst);
  623. for (i = 0; i < 7; i++) {
  624. switch ( (0x01 << i) & src->encodingMask) {
  625. case DIEMT_SYMBOLIC_ID:
  626. retval |= UA_Int32_encode(&(src->symbolicId), pos, dst);
  627. break;
  628. case DIEMT_NAMESPACE:
  629. retval |= UA_Int32_encode( &(src->namespaceUri), pos, dst);
  630. break;
  631. case DIEMT_LOCALIZED_TEXT:
  632. retval |= UA_Int32_encode(&(src->localizedText), pos, dst);
  633. break;
  634. case DIEMT_LOCALE:
  635. retval |= UA_Int32_encode(&(src->locale), pos, dst);
  636. break;
  637. case DIEMT_ADDITIONAL_INFO:
  638. retval |= UA_String_encode(&(src->additionalInfo), pos, dst);
  639. break;
  640. case DIEMT_INNER_STATUS_CODE:
  641. retval |= UA_StatusCode_encode(&(src->innerStatusCode), pos, dst);
  642. break;
  643. case DIEMT_INNER_DIAGNOSTIC_INFO:
  644. retval |= UA_DiagnosticInfo_encode(src->innerDiagnosticInfo, pos, dst);
  645. break;
  646. }
  647. }
  648. return retval;
  649. }
  650. Int32 UA_DiagnosticInfo_calcSize(UA_DiagnosticInfo const * ptr) {
  651. Int32 length = 0;
  652. if (ptr == UA_NULL) {
  653. length = sizeof(UA_DiagnosticInfo);
  654. } else {
  655. Byte mask;
  656. length += sizeof(Byte); // EncodingMask
  657. for (mask = 0x01; mask <= 0x40; mask *= 2) {
  658. switch (mask & (ptr->encodingMask)) {
  659. case DIEMT_SYMBOLIC_ID:
  660. // puts("diagnosticInfo symbolic id");
  661. length += sizeof(UA_Int32);
  662. break;
  663. case DIEMT_NAMESPACE:
  664. length += sizeof(UA_Int32);
  665. break;
  666. case DIEMT_LOCALIZED_TEXT:
  667. length += sizeof(UA_Int32);
  668. break;
  669. case DIEMT_LOCALE:
  670. length += sizeof(UA_Int32);
  671. break;
  672. case DIEMT_ADDITIONAL_INFO:
  673. length += UA_String_calcSize(&(ptr->additionalInfo));
  674. break;
  675. case DIEMT_INNER_STATUS_CODE:
  676. length += sizeof(UA_StatusCode);
  677. break;
  678. case DIEMT_INNER_DIAGNOSTIC_INFO:
  679. length += UA_DiagnosticInfo_calcSize(ptr->innerDiagnosticInfo);
  680. break;
  681. }
  682. }
  683. }
  684. return length;
  685. }
  686. UA_TYPE_METHOD_DELETE_STRUCT(UA_DiagnosticInfo)
  687. Int32 UA_DiagnosticInfo_deleteMembers(UA_DiagnosticInfo *p) {
  688. Int32 retval = UA_SUCCESS;
  689. if (p->encodingMask & DIEMT_INNER_DIAGNOSTIC_INFO) {
  690. retval |= UA_DiagnosticInfo_deleteMembers(p->innerDiagnosticInfo);
  691. retval |= UA_free(p->innerDiagnosticInfo);
  692. }
  693. return retval;
  694. }
  695. UA_TYPE_METHOD_CALCSIZE_SIZEOF(UA_DateTime)
  696. UA_TYPE_METHOD_ENCODE_AS(UA_DateTime,UA_Int64)
  697. UA_TYPE_METHOD_DECODE_AS(UA_DateTime,UA_Int64)
  698. UA_TYPE_METHOD_DELETE_FREE(UA_DateTime)
  699. UA_TYPE_METHOD_DELETEMEMBERS_NOACTION(UA_DateTime)
  700. UA_TYPE_METHOD_CALCSIZE_AS(UA_XmlElement, UA_ByteString)
  701. UA_TYPE_METHOD_ENCODE_AS(UA_XmlElement, UA_ByteString)
  702. UA_TYPE_METHOD_DECODE_AS(UA_XmlElement, UA_ByteString)
  703. UA_TYPE_METHOD_DELETE_AS(UA_XmlElement, UA_ByteString)
  704. UA_TYPE_METHOD_DELETEMEMBERS_AS(UA_XmlElement, UA_ByteString)
  705. /** IntegerId - Part: 4, Chapter: 7.13, Page: 118 */
  706. UA_TYPE_METHOD_CALCSIZE_AS(UA_IntegerId, UA_Int32)
  707. UA_TYPE_METHOD_ENCODE_AS(UA_IntegerId, UA_Int32)
  708. UA_TYPE_METHOD_DECODE_AS(UA_IntegerId, UA_Int32)
  709. UA_TYPE_METHOD_DELETE_AS(UA_IntegerId, UA_Int32)
  710. UA_TYPE_METHOD_DELETEMEMBERS_AS(UA_IntegerId, UA_Int32)
  711. UA_TYPE_METHOD_CALCSIZE_AS(UA_StatusCode, UA_UInt32)
  712. UA_TYPE_METHOD_ENCODE_AS(UA_StatusCode, UA_UInt32)
  713. UA_TYPE_METHOD_DECODE_AS(UA_StatusCode, UA_UInt32)
  714. UA_TYPE_METHOD_DELETE_AS(UA_StatusCode, UA_UInt32)
  715. UA_TYPE_METHOD_DELETEMEMBERS_AS(UA_StatusCode, UA_UInt32)
  716. Int32 UA_QualifiedName_calcSize(UA_QualifiedName const * p) {
  717. Int32 length = 0;
  718. length += sizeof(UInt16); //qualifiedName->namespaceIndex
  719. length += sizeof(UInt16); //qualifiedName->reserved
  720. length += UA_String_calcSize(&(p->name)); //qualifiedName->name
  721. return length;
  722. }
  723. Int32 UA_QualifiedName_decode(char const * src, Int32 *pos,
  724. UA_QualifiedName *dst) {
  725. Int32 retval = UA_SUCCESS;
  726. retval |= UA_UInt16_decode(src,pos,&(dst->namespaceIndex));
  727. retval |= UA_UInt16_decode(src,pos,&(dst->reserved));
  728. retval |= UA_String_decode(src,pos,&(dst->name));
  729. return retval;
  730. }
  731. Int32 UA_QualifiedName_encode(UA_QualifiedName const *src, Int32* pos,
  732. char *dst) {
  733. Int32 retval = UA_SUCCESS;
  734. retval |= UA_UInt16_encode(&(src->namespaceIndex),pos,dst);
  735. retval |= UA_UInt16_encode(&(src->reserved),pos,dst);
  736. retval |= UA_String_encode(&(src->name),pos,dst);
  737. return retval;
  738. }
  739. Int32 UA_Variant_calcSize(UA_Variant const * p) {
  740. Int32 length = 0;
  741. Int32 ns0Id = p->encodingMask & 0x1F; // Bits 1-5
  742. Boolean isArray = p->encodingMask & (0x01 << 7); // Bit 7
  743. Boolean hasDimensions = p->encodingMask & (0x01 << 6); // Bit 6
  744. int i;
  745. if (p->vt == UA_NULL || p->encodingMask != p->vt->Id) {
  746. return UA_ERR_INCONSISTENT;
  747. }
  748. length += sizeof(Byte); //p->encodingMask
  749. if (isArray) { // array length is encoded
  750. length += sizeof(Int32); //p->arrayLength
  751. if (p->arrayLength > 0) {
  752. // TODO: add suggestions of @jfpr to not iterate over arrays with fixed len elements
  753. for (i=0;i<p->arrayLength;i++) {
  754. length += p->vt->calcSize(p->data[i]);
  755. }
  756. }
  757. } else { //single value to encode
  758. length += p->vt->calcSize(p->data[0]);
  759. }
  760. if (hasDimensions) {
  761. //ToDo: tobeInsert: length += the calcSize for dimensions
  762. }
  763. return length;
  764. }
  765. Int32 UA_Variant_encode(UA_Variant const *src, Int32* pos, char *dst) {
  766. Int32 retval = UA_SUCCESS;
  767. int i;
  768. if (src->vt == UA_NULL || src->encodingMask != src->vt->Id) {
  769. return UA_ERR_INCONSISTENT;
  770. }
  771. retval |= UA_Byte_encode(&(src->encodingMask),pos,dst);
  772. if (src->encodingMask & (0x01 << 7)) { // encode array length
  773. retval |= UA_Int32_encode(&(src->arrayLength),pos,dst);
  774. }
  775. if (src->arrayLength > 0) {
  776. //encode array as given by variant type
  777. for (i=0;i<src->arrayLength;i++) {
  778. retval |= src->vt->encode(src->data[i],pos,dst);
  779. }
  780. } else {
  781. retval |= src->vt->encode(src->data[i],pos,dst);
  782. }
  783. if (src->encodingMask & (1 << 6)) { // encode array dimension field
  784. // TODO: encode array dimension field
  785. }
  786. return retval;
  787. }
  788. Int32 UA_Variant_decode(char const * src, Int32 *pos, UA_Variant *dst) {
  789. Int32 retval = UA_SUCCESS;
  790. Int32 ns0Id;
  791. int i;
  792. retval |= UA_Byte_decode(src,pos,&(dst->encodingMask));
  793. ns0Id = dst->encodingMask & 0x1F;
  794. // initialize vTable
  795. if (ns0Id < UA_BOOLEAN && ns0Id > UA_DOUBLECOMPLEXNUMBERTYPE) {
  796. return UA_ERR_INVALID_VALUE;
  797. } else {
  798. dst->vt = &UA_[UA_toIndex(ns0Id)];
  799. }
  800. // get size of array
  801. if (dst->encodingMask & (0x01 << 7)) { // encode array length
  802. retval |= UA_Int32_decode(src,pos,&(dst->arrayLength));
  803. } else {
  804. dst->arrayLength = 1;
  805. }
  806. // allocate place for arrayLength pointers to any type
  807. retval |= UA_alloc(dst->data,dst->arrayLength * sizeof(void*));
  808. for (i=0;i<dst->arrayLength;i++) {
  809. // TODO: this is crazy, how to work with variants with variable size?
  810. // actually we have two different sizes - the storage size without
  811. // dynamic members and the storage size with the dynamic members, e.g.
  812. // for a string we here need to allocate definitely 8 byte (length=4, data*=4)
  813. // on a 32-bit architecture - so this code is definitely wrong
  814. retval |= UA_alloc(&(dst->data[i]),dst->vt->calcSize(UA_NULL));
  815. retval |= dst->vt->decode(src,pos,dst->data[i]);
  816. }
  817. if (dst->encodingMask & (1 << 6)) {
  818. // TODO: decode array dimension field
  819. }
  820. return retval;
  821. }
  822. //TODO: place this define at the server configuration
  823. #define MAX_PICO_SECONDS 1000
  824. Int32 UA_DataValue_decode(char const * src, Int32* pos, UA_DataValue* dst) {
  825. Int32 retval = UA_SUCCESS;
  826. retval |= UA_Byte_decode(src,pos,&(dst->encodingMask));
  827. if (dst->encodingMask & 0x01) {
  828. retval |= UA_Variant_decode(src,pos,&(dst->value));
  829. }
  830. if (dst->encodingMask & 0x02) {
  831. retval |= UA_StatusCode_decode(src,pos,&(dst->status));
  832. }
  833. if (dst->encodingMask & 0x04) {
  834. retval |= UA_DateTime_decode(src,pos,&(dst->sourceTimestamp));
  835. }
  836. if (dst->encodingMask & 0x08) {
  837. retval |= UA_DateTime_decode(src,pos,&(dst->serverTimestamp));
  838. }
  839. if (dst->encodingMask & 0x10) {
  840. retval |= UA_UInt16_decode(src,pos,&(dst->sourcePicoseconds));
  841. if (dst->sourcePicoseconds > MAX_PICO_SECONDS) {
  842. dst->sourcePicoseconds = MAX_PICO_SECONDS;
  843. }
  844. }
  845. if (dst->encodingMask & 0x20) {
  846. retval |= UA_UInt16_decode(src,pos,&(dst->serverPicoseconds));
  847. if (dst->serverPicoseconds > MAX_PICO_SECONDS) {
  848. dst->serverPicoseconds = MAX_PICO_SECONDS;
  849. }
  850. }
  851. return retval;
  852. }
  853. Int32 UA_DataValue_encode(UA_DataValue const * src, Int32* pos, char *dst) {
  854. Int32 retval = UA_SUCCESS;
  855. retval |= UA_Byte_encode(&(src->encodingMask),pos,dst);
  856. if (src->encodingMask & 0x01) {
  857. retval |= UA_Variant_encode(&(src->value),pos,dst);
  858. }
  859. if (src->encodingMask & 0x02) {
  860. retval |= UA_StatusCode_encode(&(src->status),pos,dst);
  861. }
  862. if (src->encodingMask & 0x04) {
  863. retval |= UA_DateTime_encode(&(src->sourceTimestamp),pos,dst);
  864. }
  865. if (src->encodingMask & 0x08) {
  866. retval |= UA_DateTime_encode(&(src->serverTimestamp),pos,dst);
  867. }
  868. if (src->encodingMask & 0x10) {
  869. retval |= UA_UInt16_encode(&(src->sourcePicoseconds),pos,dst);
  870. }
  871. if (src->encodingMask & 0x10) {
  872. retval |= UA_UInt16_encode(&(src->serverPicoseconds),pos,dst);
  873. }
  874. return retval;
  875. }
  876. Int32 UA_DataValue_calcSize(UA_DataValue const * p) {
  877. Int32 length = 0;
  878. if (p == UA_NULL) { // get static storage size
  879. length = sizeof(UA_DataValue);
  880. } else { // get decoding size
  881. length = sizeof(UA_Byte);
  882. if (p->encodingMask & 0x01) {
  883. length += UA_Variant_calcSize(&(p->value));
  884. }
  885. if (p->encodingMask & 0x02) {
  886. length += sizeof(UInt32); //dataValue->status
  887. }
  888. if (p->encodingMask & 0x04) {
  889. length += sizeof(Int64); //dataValue->sourceTimestamp
  890. }
  891. if (p->encodingMask & 0x08) {
  892. length += sizeof(Int64); //dataValue->serverTimestamp
  893. }
  894. if (p->encodingMask & 0x10) {
  895. length += sizeof(Int64); //dataValue->sourcePicoseconds
  896. }
  897. if (p->encodingMask & 0x20) {
  898. length += sizeof(Int64); //dataValue->serverPicoseconds
  899. }
  900. }
  901. return length;
  902. }
  903. /**
  904. * RequestHeader
  905. * Part: 4
  906. * Chapter: 7.26
  907. * Page: 132
  908. */
  909. /** \copydoc decodeRequestHeader */
  910. /*** Sten: removed to compile
  911. Int32 decodeRequestHeader(const AD_RawMessage *srcRaw, Int32 *pos,
  912. UA_AD_RequestHeader *dstRequestHeader) {
  913. return decoder_decodeRequestHeader(srcRaw->message, pos, dstRequestHeader);
  914. }
  915. ***/
  916. /*** Sten: removed to compile
  917. Int32 decoder_decodeRequestHeader(char const * message, Int32 *pos,
  918. UA_AD_RequestHeader *dstRequestHeader) {
  919. // 62541-4 §5.5.2.2 OpenSecureChannelServiceParameters
  920. // requestHeader - common request parameters. The authenticationToken is always omitted
  921. decoder_decodeBuiltInDatatype(message, NODE_ID, pos,
  922. &(dstRequestHeader->authenticationToken));
  923. decoder_decodeBuiltInDatatype(message, DATE_TIME, pos,
  924. &(dstRequestHeader->timestamp));
  925. decoder_decodeBuiltInDatatype(message, UINT32, pos,
  926. &(dstRequestHeader->requestHandle));
  927. decoder_decodeBuiltInDatatype(message, UINT32, pos,
  928. &(dstRequestHeader->returnDiagnostics));
  929. decoder_decodeBuiltInDatatype(message, STRING, pos,
  930. &(dstRequestHeader->auditEntryId));
  931. decoder_decodeBuiltInDatatype(message, UINT32, pos,
  932. &(dstRequestHeader->timeoutHint));
  933. decoder_decodeBuiltInDatatype(message, EXTENSION_OBJECT, pos,
  934. &(dstRequestHeader->additionalHeader));
  935. // AdditionalHeader will stay empty, need to be changed if there is relevant information
  936. return 0;
  937. }
  938. ***/
  939. /**
  940. * ResponseHeader
  941. * Part: 4
  942. * Chapter: 7.27
  943. * Page: 133
  944. */
  945. /** \copydoc encodeResponseHeader */
  946. /*** Sten: removed to compile
  947. Int32 encodeResponseHeader(UA_AD_ResponseHeader const * responseHeader,
  948. Int32 *pos, UA_ByteString *dstBuf) {
  949. encodeUADateTime(responseHeader->timestamp, pos, dstBuf->data);
  950. encodeIntegerId(responseHeader->requestHandle, pos, dstBuf->data);
  951. encodeUInt32(responseHeader->serviceResult, pos, dstBuf->data);
  952. encodeDiagnosticInfo(responseHeader->serviceDiagnostics, pos, dstBuf->data);
  953. encoder_encodeBuiltInDatatypeArray(responseHeader->stringTable,
  954. responseHeader->noOfStringTable, STRING_ARRAY, pos, dstBuf->data);
  955. encodeExtensionObject(responseHeader->additionalHeader, pos, dstBuf->data);
  956. //Kodieren von String Datentypen
  957. return 0;
  958. }
  959. ***/
  960. /*** Sten: removed to compile
  961. Int32 extensionObject_calcSize(UA_ExtensionObject *extensionObject) {
  962. Int32 length = 0;
  963. length += nodeId_calcSize(&(extensionObject->typeId));
  964. length += sizeof(Byte); //The EncodingMask Byte
  965. if (extensionObject->encoding == BODY_IS_BYTE_STRING
  966. || extensionObject->encoding == BODY_IS_XML_ELEMENT) {
  967. length += UAByteString_calcSize(&(extensionObject->body));
  968. }
  969. return length;
  970. }
  971. ***/
  972. /*** Sten: removed to compile
  973. Int32 responseHeader_calcSize(UA_AD_ResponseHeader *responseHeader) {
  974. Int32 i;
  975. Int32 length = 0;
  976. // UtcTime timestamp 8
  977. length += sizeof(UA_DateTime);
  978. // IntegerId requestHandle 4
  979. length += sizeof(UA_AD_IntegerId);
  980. // StatusCode serviceResult 4
  981. length += sizeof(UA_StatusCode);
  982. // DiagnosticInfo serviceDiagnostics
  983. length += diagnosticInfo_calcSize(responseHeader->serviceDiagnostics);
  984. // String stringTable[], see 62541-6 § 5.2.4
  985. length += sizeof(Int32); // Length of Stringtable always
  986. if (responseHeader->noOfStringTable > 0) {
  987. for (i = 0; i < responseHeader->noOfStringTable; i++) {
  988. length += UAString_calcSize(responseHeader->stringTable[i]);
  989. }
  990. }
  991. // ExtensibleObject additionalHeader
  992. length += extensionObject_calcSize(responseHeader->additionalHeader);
  993. return length;
  994. }
  995. ***/