opcua_basictypes.c 35 KB

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