opcua_basictypes.c 40 KB

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