opcua_basictypes.c 35 KB

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