opcua_binaryEncDec.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. /*
  2. * opcua_binaryEncDec.c
  3. *
  4. * Created on: Dec 18, 2013
  5. * Author: opcua
  6. */
  7. #include "opcua_binaryEncDec.h"
  8. #include "opcua_types.h"
  9. Byte decodeByte(const char *buf, Int32 *pos)
  10. {
  11. *pos = (*pos) + 1;
  12. return (Byte) buf[(*pos) - 1];
  13. }
  14. void encodeByte(Byte encodeByte, Int32 *pos, AD_RawMessage *dstBuf)
  15. {
  16. dstBuf->message[*pos] = encodeByte;
  17. *pos = (*pos) + 1;
  18. }
  19. UInt16 decodeUInt16(const char* buf, Int32 *pos)
  20. {
  21. Byte t1 = buf[*pos];
  22. UInt16 t2 = (UInt16) (buf[*pos + 1] << 8);
  23. *pos += 2;
  24. return t1 + t2;
  25. }
  26. void encodeUInt16(UInt16 value, Int32 *pos, AD_RawMessage *dstBuf)
  27. {
  28. memcpy(dstBuf->message, &value, sizeof(UInt16));
  29. *pos = (*pos) + sizeof(UInt16);
  30. }
  31. Int16 decodeInt16(const char* buf, Int32 *pos)
  32. {
  33. Byte t1 = buf[*pos];
  34. Int32 t2 = (Int16) (buf[*pos + 1] << 8);
  35. *pos += 2;
  36. return t1 + t2;
  37. }
  38. void encodeInt16(Int16 value, Int32 *pos, AD_RawMessage *dstBuf)
  39. {
  40. memcpy(dstBuf->message, &value, sizeof(Int16));
  41. *pos = (*pos) + sizeof(Int16);
  42. }
  43. Int32 decodeInt32(const char* buf, Int32 *pos)
  44. {
  45. SByte t1 = buf[*pos];
  46. Int32 t2 = (UInt32) (buf[*pos + 1] << 8);
  47. Int32 t3 = (UInt32) (buf[*pos + 2] << 16);
  48. Int32 t4 = (UInt32) (buf[*pos + 3] << 24);
  49. *pos += 4;
  50. return t1 + t2 + t3 + t4;
  51. }
  52. void encodeInt32(Int32 value, Int32 *pos, AD_RawMessage *dstBuf)
  53. {
  54. memcpy(dstBuf->message, &value, sizeof(Int32));
  55. *pos = (*pos) + sizeof(Int32);
  56. }
  57. UInt32 decodeUInt32(const char* buf, Int32 *pos)
  58. {
  59. Byte t1 = buf[*pos];
  60. UInt32 t2 = (UInt32) (buf[*pos + 1] << 8);
  61. UInt32 t3 = (UInt32) (buf[*pos + 2] << 16);
  62. UInt32 t4 = (UInt32) (buf[*pos + 3] << 24);
  63. *pos += 4;
  64. return t1 + t2 + t3 + t4;
  65. }
  66. void encodeUInt32(UInt32 value, char *dstBuf, Int32 *pos)
  67. {
  68. memcpy(&(dstBuf[*pos]), &value, sizeof(value));
  69. pos += 4;
  70. }
  71. Int64 decodeInt64(const char* buf, Int32 *pos)
  72. {
  73. SByte t1 = buf[*pos];
  74. UInt64 t2 = (UInt64) (buf[*pos + 1] << 8);
  75. UInt64 t3 = (UInt64) (buf[*pos + 2] << 16);
  76. UInt64 t4 = (UInt64) (buf[*pos + 3] << 24);
  77. UInt64 t5 = (UInt64) (buf[*pos + 4] << 32);
  78. UInt64 t6 = (UInt64) (buf[*pos + 5] << 40);
  79. UInt64 t7 = (UInt64) (buf[*pos + 6] << 48);
  80. UInt64 t8 = (UInt64) (buf[*pos + 7] << 56);
  81. pos += 8;
  82. return t1 + t2 + t3 + t4 + t5 + t6 + t7 + t8;
  83. }
  84. void encodeInt64(Int64 value, Int64 *pos, AD_RawMessage *dstBuf)
  85. {
  86. memcpy(dstBuf->message, &value, sizeof(Int64));
  87. *pos = (*pos) + sizeof(Int64);
  88. }
  89. Int32 decodeUAString(const char* buf, Int32 *pos, UA_String *dstUAString)
  90. {
  91. dstUAString->Length = decodeInt32(buf, pos);
  92. if (dstUAString->Length > 0)
  93. {
  94. dstUAString->Data = &(buf[*pos]);
  95. }
  96. else
  97. {
  98. dstUAString->Length = 0;
  99. dstUAString->Data = NULL;
  100. }
  101. *pos += dstUAString->Length;
  102. return 0;
  103. }
  104. Int32 decodeUAGuid(const char *buf, Int32 *pos, UA_Guid *dstGUID)
  105. {
  106. dstGUID->Data1 = decodeUInt32(buf, pos);
  107. dstGUID->Data2 = decodeUInt16(buf, pos);
  108. dstGUID->Data3 = decodeUInt16(buf, pos);
  109. decodeUAByteString(buf, pos, &(dstGUID->Data4));
  110. return 0;
  111. }
  112. void decodeUAByteString(const char *buf, Int32* pos,
  113. UA_ByteString *dstBytestring)
  114. {
  115. decodeUAString(buf, pos, dstBytestring->Data);
  116. }
  117. UA_DateTime decodeUADateTime(const char *buf, Int32 *pos)
  118. {
  119. return decodeInt64(buf, pos);
  120. }
  121. UA_StatusCode decodeUAStatusCode(const char* buf, Int32 *pos)
  122. {
  123. return decodeUInt32(buf, pos);
  124. }
  125. Int32 decodeUANodeId(const char* buf, Int32 *pos, UA_NodeId *dstNodeId)
  126. {
  127. dstNodeId->EncodingByte = decodeInt32(buf, pos);
  128. switch (dstNodeId->EncodingByte)
  129. {
  130. case NIEVT_TWO_BYTE:
  131. {
  132. dstNodeId->Identifier.Numeric = decodeByte(buf, pos);
  133. break;
  134. }
  135. case NIEVT_FOUR_BYTE:
  136. {
  137. dstNodeId->Identifier.Numeric = decodeInt16(buf, pos);
  138. break;
  139. }
  140. case NIEVT_NUMERIC:
  141. {
  142. dstNodeId->Identifier.Numeric = decodeInt32(buf, pos);
  143. break;
  144. }
  145. case NIEVT_STRING:
  146. {
  147. decodeUAString(buf, pos, &dstNodeId->Identifier.String);
  148. break;
  149. }
  150. case NIEVT_GUID:
  151. {
  152. decodeUAGuid(buf, pos, &(dstNodeId->Identifier.Guid));
  153. break;
  154. }
  155. case NIEVT_BYTESTRING:
  156. {
  157. decodeUAByteString(buf, pos, &(dstNodeId->Identifier.OPAQUE));
  158. break;
  159. }
  160. case NIEVT_NAMESPACE_URI_FLAG:
  161. {
  162. //TODO implement
  163. break;
  164. }
  165. default:
  166. break;
  167. }
  168. return 0;
  169. }
  170. /**
  171. * IntegerId
  172. * Part: 4
  173. * Chapter: 7.13
  174. * Page: 118
  175. */
  176. T_IntegerId decodeIntegerId(char* buf, Int32 *pos)
  177. {
  178. return decodeUInt32(buf, pos);
  179. }
  180. /**
  181. * DiagnosticInfo
  182. * Part: 4
  183. * Chapter: 7.9
  184. * Page: 116
  185. */
  186. enum encodingMask
  187. {
  188. encodingMask_HasSymbolicId = 0x01,
  189. encodingMask_HasNamespace = 0x02,
  190. encodingMask_HasLocalizedText = 0x04,
  191. encodingMask_HasLocale = 0x08,
  192. encodingMask_HasAdditionalInfo = 0x10,
  193. encodingMask_HasInnerStatusCode = 0x20,
  194. encodingMask_HasInnerDiagnosticInfo= 0x40
  195. };
  196. Int32 decodeToDiagnosticInfo(char* buf, Int32 *pos,
  197. T_DiagnosticInfo* dstDiagnosticInfo)
  198. {
  199. Byte encodingByte = (buf[*pos]);
  200. Byte mask;
  201. for(mask = 1; mask <= 0x40; mask << 2)
  202. {
  203. switch(mask && encodingByte)
  204. {
  205. DIEMT_SYMBOLIC_ID:
  206. dstDiagnosticInfo->symbolicId = decodeInt32(buf, pos);
  207. break;
  208. DIEMT_NAMESPACE:
  209. dstDiagnosticInfo->namespaceUri = decodeInt32(buf, pos);
  210. break;
  211. DIEMT_LOCALIZED_TEXT:
  212. dstDiagnosticInfo->localizesText = decodeInt32(buf, pos);
  213. break;
  214. DIEMT_LOCALE:
  215. dstDiagnosticInfo->locale = decodeInt32(buf, pos);
  216. break;
  217. DIEMT_ADDITIONAL_INFO:
  218. decodeUAString(buf, pos, &dstDiagnosticInfo->additionalInfo);
  219. break;
  220. DIEMT_INNER_STATUS_CODE:
  221. dstDiagnosticInfo->innerStatusCode = decodeUAStatusCode(buf, pos);
  222. break;
  223. DIEMT_INNER_DIAGNOSTIC_INFO:
  224. dstDiagnosticInfo->innerDiagnosticInfo = opcua_malloc(sizeof(T_DiagnosticInfo));
  225. decodeToDiagnosticInfo(buf, pos,
  226. dstDiagnosticInfo->innerDiagnosticInfo);
  227. break;
  228. }
  229. }
  230. *pos += 1;
  231. return 0;
  232. }
  233. Int32 DiagnosticInfo_calcSize(T_DiagnosticInfo *diagnosticInfo)
  234. {
  235. Int32 minimumLength = 20;
  236. Int32 length;
  237. length += minimumLength;
  238. length += diagnosticInfo->additionalInfo.Length;
  239. length += sizeof(UInt32);
  240. length += DiagnosticInfo_calcSize(diagnosticInfo->innerDiagnosticInfo);
  241. return length;
  242. }
  243. /**
  244. * RequestHeader
  245. * Part: 4
  246. * Chapter: 7.26
  247. * Page: 132
  248. */
  249. /** \copydoc decodeRequestHeader */
  250. Int32 decodeRequestHeader(const AD_RawMessage *srcRaw, Int32 *pos,
  251. T_RequestHeader *dstRequestHeader)
  252. {
  253. decodeUANodeId(srcRaw->message, pos,
  254. &(dstRequestHeader->authenticationToken));
  255. dstRequestHeader->timestamp = decodeUADateTime(srcRaw->message, pos);
  256. dstRequestHeader->requestHandle = decodeIntegerId(srcRaw->message, pos);
  257. dstRequestHeader->returnDiagnostics = decodeUInt32(srcRaw->message, pos);
  258. decodeUAString(srcRaw->message, pos, &dstRequestHeader->auditEntryId);
  259. dstRequestHeader->timeoutHint = decodeUInt32(srcRaw->message, pos);
  260. // AdditionalHeader will stay empty, need to be changed if there is relevant information
  261. return 0;
  262. }
  263. /**
  264. * ResponseHeader
  265. * Part: 4
  266. * Chapter: 7.27
  267. * Page: 133
  268. */
  269. /** \copydoc encodeResponseHeader */
  270. /*Int32 encodeResponseHeader(const T_ResponseHeader *responseHeader, Int32 *pos,
  271. AD_RawMessage *dstBuf)
  272. {
  273. return 0;
  274. }*/
  275. Int32 ResponseHeader_calcSize(T_ResponseHeader *responseHeader)
  276. {
  277. Int32 minimumLength = 24; // summation of all simple types
  278. Int32 i, length;
  279. length += minimumLength;
  280. for (i = 0; i < responseHeader->noOfStringTable; i++)
  281. {
  282. length += responseHeader->stringTable[i].Length;
  283. length += sizeof(UInt32); // length of the encoded length field
  284. }
  285. //TODO
  286. return 0;
  287. }