opcua_basictypes.c 35 KB

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