ua_pubsub_networkmessage.c 48 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291
  1. /* This Source Code Form is subject to the terms of the Mozilla Public
  2. * License, v. 2.0. If a copy of the MPL was not distributed with this
  3. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  4. *
  5. * Copyright (c) 2017 - 2018 Fraunhofer IOSB (Author: Tino Bischoff)
  6. */
  7. #include "ua_types.h"
  8. #include "ua_pubsub_networkmessage.h"
  9. #include "ua_types_encoding_binary.h"
  10. #include "ua_types_generated.h"
  11. #include "ua_types_generated_encoding_binary.h"
  12. #include "ua_types_generated_handling.h"
  13. #include "ua_log_stdout.h"
  14. const UA_Byte NM_VERSION_MASK = 15;
  15. const UA_Byte NM_PUBLISHER_ID_ENABLED_MASK = 16;
  16. const UA_Byte NM_GROUP_HEADER_ENABLED_MASK = 32;
  17. const UA_Byte NM_PAYLOAD_HEADER_ENABLED_MASK = 64;
  18. const UA_Byte NM_EXTENDEDFLAGS1_ENABLED_MASK = 128;
  19. const UA_Byte NM_PUBLISHER_ID_MASK = 7;
  20. const UA_Byte NM_DATASET_CLASSID_ENABLED_MASK = 8;
  21. const UA_Byte NM_SECURITY_ENABLED_MASK = 16;
  22. const UA_Byte NM_TIMESTAMP_ENABLED_MASK = 32;
  23. const UA_Byte NM_PICOSECONDS_ENABLED_MASK = 64;
  24. const UA_Byte NM_EXTENDEDFLAGS2_ENABLED_MASK = 128;
  25. const UA_Byte NM_NETWORK_MSG_TYPE_MASK = 28;
  26. const UA_Byte NM_CHUNK_MESSAGE_MASK = 1;
  27. const UA_Byte NM_PROMOTEDFIELDS_ENABLED_MASK = 2;
  28. const UA_Byte GROUP_HEADER_WRITER_GROUPID_ENABLED = 1;
  29. const UA_Byte GROUP_HEADER_GROUP_VERSION_ENABLED = 2;
  30. const UA_Byte GROUP_HEADER_NM_NUMBER_ENABLED = 4;
  31. const UA_Byte GROUP_HEADER_SEQUENCE_NUMBER_ENABLED = 8;
  32. const UA_Byte SECURITY_HEADER_NM_SIGNED = 1;
  33. const UA_Byte SECURITY_HEADER_NM_ENCRYPTED = 2;
  34. const UA_Byte SECURITY_HEADER_SEC_FOOTER_ENABLED = 4;
  35. const UA_Byte SECURITY_HEADER_FORCE_KEY_RESET = 8;
  36. const UA_Byte DS_MESSAGEHEADER_DS_MSG_VALID = 1;
  37. const UA_Byte DS_MESSAGEHEADER_FIELD_ENCODING_MASK = 6;
  38. const UA_Byte DS_MESSAGEHEADER_SEQ_NR_ENABLED_MASK = 8;
  39. const UA_Byte DS_MESSAGEHEADER_STATUS_ENABLED_MASK = 16;
  40. const UA_Byte DS_MESSAGEHEADER_CONFIGMAJORVERSION_ENABLED_MASK = 32;
  41. const UA_Byte DS_MESSAGEHEADER_CONFIGMINORVERSION_ENABLED_MASK = 64;
  42. const UA_Byte DS_MESSAGEHEADER_FLAGS2_ENABLED_MASK = 128;
  43. const UA_Byte DS_MESSAGEHEADER_DS_MESSAGE_TYPE_MASK = 15;
  44. const UA_Byte DS_MESSAGEHEADER_TIMESTAMP_ENABLED_MASK = 16;
  45. const UA_Byte DS_MESSAGEHEADER_PICOSECONDS_INCLUDED_MASK = 32;
  46. const UA_Byte NM_SHIFT_LEN = 2;
  47. const UA_Byte DS_MH_SHIFT_LEN = 1;
  48. static UA_Boolean UA_NetworkMessage_ExtendedFlags1Enabled(const UA_NetworkMessage* src);
  49. static UA_Boolean UA_NetworkMessage_ExtendedFlags2Enabled(const UA_NetworkMessage* src);
  50. static UA_Boolean UA_DataSetMessageHeader_DataSetFlags2Enabled(const UA_DataSetMessageHeader* src);
  51. UA_StatusCode
  52. UA_NetworkMessage_encodeBinary(const UA_NetworkMessage* src, UA_Byte **bufPos,
  53. const UA_Byte *bufEnd) {
  54. UA_StatusCode retval = UA_STATUSCODE_BADNOTIMPLEMENTED;
  55. /* UADPVersion + UADP Flags */
  56. UA_Byte v = src->version;
  57. if(src->publisherIdEnabled)
  58. v |= NM_PUBLISHER_ID_ENABLED_MASK;
  59. if(src->groupHeaderEnabled)
  60. v |= NM_GROUP_HEADER_ENABLED_MASK;
  61. if(src->payloadHeaderEnabled)
  62. v |= NM_PAYLOAD_HEADER_ENABLED_MASK;
  63. if(UA_NetworkMessage_ExtendedFlags1Enabled(src))
  64. v |= NM_EXTENDEDFLAGS1_ENABLED_MASK;
  65. UA_StatusCode rv = UA_Byte_encodeBinary(&v, bufPos, bufEnd);
  66. if(rv != UA_STATUSCODE_GOOD)
  67. return rv;
  68. // ExtendedFlags1
  69. if(UA_NetworkMessage_ExtendedFlags1Enabled(src)) {
  70. v = src->publisherIdType;
  71. if(src->dataSetClassIdEnabled)
  72. v |= NM_DATASET_CLASSID_ENABLED_MASK;
  73. if(src->securityEnabled)
  74. v |= NM_SECURITY_ENABLED_MASK;
  75. if(src->timestampEnabled)
  76. v |= NM_TIMESTAMP_ENABLED_MASK;
  77. if(src->picosecondsEnabled)
  78. v |= NM_PICOSECONDS_ENABLED_MASK;
  79. if(UA_NetworkMessage_ExtendedFlags2Enabled(src))
  80. v |= NM_EXTENDEDFLAGS2_ENABLED_MASK;
  81. rv = UA_Byte_encodeBinary(&v, bufPos, bufEnd);
  82. if(rv != UA_STATUSCODE_GOOD)
  83. return rv;
  84. // ExtendedFlags2
  85. if(UA_NetworkMessage_ExtendedFlags2Enabled(src)) {
  86. v = src->networkMessageType;
  87. // shift left 2 bit
  88. v = (UA_Byte) (v << NM_SHIFT_LEN);
  89. if(src->chunkMessage)
  90. v |= NM_CHUNK_MESSAGE_MASK;
  91. if(src->promotedFieldsEnabled)
  92. v |= NM_PROMOTEDFIELDS_ENABLED_MASK;
  93. rv = UA_Byte_encodeBinary(&v, bufPos, bufEnd);
  94. if(rv != UA_STATUSCODE_GOOD)
  95. return rv;
  96. }
  97. }
  98. // PublisherId
  99. if(src->publisherIdEnabled) {
  100. switch (src->publisherIdType) {
  101. case UA_PUBLISHERDATATYPE_BYTE:
  102. rv = UA_Byte_encodeBinary(&(src->publisherId.publisherIdByte), bufPos, bufEnd);
  103. break;
  104. case UA_PUBLISHERDATATYPE_UINT16:
  105. rv = UA_UInt16_encodeBinary(&(src->publisherId.publisherIdUInt16), bufPos, bufEnd);
  106. break;
  107. case UA_PUBLISHERDATATYPE_UINT32:
  108. rv = UA_UInt32_encodeBinary(&(src->publisherId.publisherIdUInt32), bufPos, bufEnd);
  109. break;
  110. case UA_PUBLISHERDATATYPE_UINT64:
  111. rv = UA_UInt64_encodeBinary(&(src->publisherId.publisherIdUInt64), bufPos, bufEnd);
  112. break;
  113. case UA_PUBLISHERDATATYPE_STRING:
  114. rv = UA_String_encodeBinary(&(src->publisherId.publisherIdString), bufPos, bufEnd);
  115. break;
  116. default:
  117. rv = UA_STATUSCODE_BADINTERNALERROR;
  118. break;
  119. }
  120. if(rv != UA_STATUSCODE_GOOD)
  121. return rv;
  122. }
  123. // DataSetClassId
  124. if(src->dataSetClassIdEnabled) {
  125. rv = UA_Guid_encodeBinary(&(src->dataSetClassId), bufPos, bufEnd);
  126. if(rv != UA_STATUSCODE_GOOD)
  127. return rv;
  128. }
  129. // Group Header
  130. if(src->groupHeaderEnabled) {
  131. v = 0;
  132. if(src->groupHeader.writerGroupIdEnabled)
  133. v |= GROUP_HEADER_WRITER_GROUPID_ENABLED;
  134. if(src->groupHeader.groupVersionEnabled)
  135. v |= GROUP_HEADER_GROUP_VERSION_ENABLED;
  136. if(src->groupHeader.networkMessageNumberEnabled)
  137. v |= GROUP_HEADER_NM_NUMBER_ENABLED;
  138. if(src->groupHeader.sequenceNumberEnabled)
  139. v |= GROUP_HEADER_SEQUENCE_NUMBER_ENABLED;
  140. rv = UA_Byte_encodeBinary(&v, bufPos, bufEnd);
  141. if(rv != UA_STATUSCODE_GOOD)
  142. return rv;
  143. if(src->groupHeader.writerGroupIdEnabled) {
  144. rv = UA_UInt16_encodeBinary(&(src->groupHeader.writerGroupId), bufPos, bufEnd);
  145. if(rv != UA_STATUSCODE_GOOD)
  146. return rv;
  147. }
  148. if(src->groupHeader.groupVersionEnabled) {
  149. rv = UA_UInt32_encodeBinary(&(src->groupHeader.groupVersion), bufPos, bufEnd);
  150. if(rv != UA_STATUSCODE_GOOD)
  151. return rv;
  152. }
  153. if(src->groupHeader.networkMessageNumberEnabled) {
  154. rv = UA_UInt16_encodeBinary(&(src->groupHeader.networkMessageNumber), bufPos, bufEnd);
  155. if(rv != UA_STATUSCODE_GOOD)
  156. return rv;
  157. }
  158. if(src->groupHeader.sequenceNumberEnabled) {
  159. rv = UA_UInt16_encodeBinary(&(src->groupHeader.sequenceNumber), bufPos, bufEnd);
  160. if(rv != UA_STATUSCODE_GOOD)
  161. return rv;
  162. }
  163. }
  164. // Payload-Header
  165. if(src->payloadHeaderEnabled) {
  166. if(src->networkMessageType == UA_NETWORKMESSAGE_DATASET) {
  167. rv = UA_Byte_encodeBinary(&(src->payloadHeader.dataSetPayloadHeader.count), bufPos, bufEnd);
  168. if(src->payloadHeader.dataSetPayloadHeader.dataSetWriterIds != NULL) {
  169. for (UA_Byte i = 0; i < src->payloadHeader.dataSetPayloadHeader.count; i++) {
  170. rv = UA_UInt16_encodeBinary(&(src->payloadHeader.dataSetPayloadHeader.dataSetWriterIds[i]), bufPos, bufEnd);
  171. if(rv != UA_STATUSCODE_GOOD)
  172. return rv;
  173. }
  174. } else {
  175. rv = UA_STATUSCODE_BADENCODINGERROR;
  176. UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "no dataSetWriterIds given!");
  177. }
  178. } else {
  179. rv = UA_STATUSCODE_BADNOTIMPLEMENTED;
  180. }
  181. }
  182. if(rv != UA_STATUSCODE_GOOD)
  183. return rv;
  184. // Timestamp
  185. if(src->timestampEnabled) {
  186. rv = UA_DateTime_encodeBinary(&(src->timestamp), bufPos, bufEnd);
  187. }
  188. // Picoseconds
  189. if(src->picosecondsEnabled) {
  190. rv = UA_UInt16_encodeBinary(&(src->picoseconds), bufPos, bufEnd);
  191. }
  192. // PromotedFields
  193. if(src->promotedFieldsEnabled) {
  194. /* Size (calculate & encode) */
  195. UA_UInt16 pfSize = 0;
  196. for(UA_UInt16 i = 0; i < src->promotedFieldsSize; i++)
  197. pfSize = (UA_UInt16) (pfSize + UA_Variant_calcSizeBinary(&src->promotedFields[i]));
  198. rv |= UA_UInt16_encodeBinary(&pfSize, bufPos, bufEnd);
  199. for (UA_UInt16 i = 0; i < src->promotedFieldsSize; i++)
  200. rv |= UA_Variant_encodeBinary(&(src->promotedFields[i]), bufPos, bufEnd);
  201. }
  202. // SecurityHeader
  203. if(src->securityEnabled) {
  204. // SecurityFlags
  205. v = 0;
  206. if(src->securityHeader.networkMessageSigned)
  207. v |= SECURITY_HEADER_NM_SIGNED;
  208. if(src->securityHeader.networkMessageEncrypted)
  209. v |= SECURITY_HEADER_NM_ENCRYPTED;
  210. if(src->securityHeader.securityFooterEnabled)
  211. v |= SECURITY_HEADER_SEC_FOOTER_ENABLED;
  212. if(src->securityHeader.forceKeyReset)
  213. v |= SECURITY_HEADER_FORCE_KEY_RESET;
  214. rv = UA_Byte_encodeBinary(&v, bufPos, bufEnd);
  215. if(rv != UA_STATUSCODE_GOOD)
  216. return rv;
  217. // SecurityTokenId
  218. rv = UA_UInt32_encodeBinary(&src->securityHeader.securityTokenId, bufPos, bufEnd);
  219. if(rv != UA_STATUSCODE_GOOD)
  220. return rv;
  221. // NonceLength
  222. rv = UA_Byte_encodeBinary(&src->securityHeader.nonceLength, bufPos, bufEnd);
  223. if(rv != UA_STATUSCODE_GOOD)
  224. return rv;
  225. // MessageNonce
  226. for (UA_Byte i = 0; i < src->securityHeader.nonceLength; i++) {
  227. rv = UA_Byte_encodeBinary(&(src->securityHeader.messageNonce.data[i]), bufPos, bufEnd);
  228. if(rv != UA_STATUSCODE_GOOD)
  229. return rv;
  230. }
  231. // SecurityFooterSize
  232. if(src->securityHeader.securityFooterEnabled) {
  233. rv = UA_UInt16_encodeBinary(&src->securityHeader.securityFooterSize, bufPos, bufEnd);
  234. if(rv != UA_STATUSCODE_GOOD)
  235. return rv;
  236. }
  237. }
  238. // Payload
  239. if(src->networkMessageType == UA_NETWORKMESSAGE_DATASET) {
  240. UA_Byte count = 1;
  241. if(src->payloadHeaderEnabled) {
  242. count = src->payloadHeader.dataSetPayloadHeader.count;
  243. if(count > 1) {
  244. for (UA_Byte i = 0; i < count; i++) {
  245. // initially calculate the size, if not specified
  246. UA_UInt16 sz = 0;
  247. if((src->payload.dataSetPayload.sizes != NULL) && (src->payload.dataSetPayload.sizes[i] != 0)) {
  248. sz = src->payload.dataSetPayload.sizes[i];
  249. } else {
  250. sz = (UA_UInt16)UA_DataSetMessage_calcSizeBinary(&(src->payload.dataSetPayload.dataSetMessages[i]));
  251. }
  252. rv = UA_UInt16_encodeBinary(&sz, bufPos, bufEnd);
  253. if(rv != UA_STATUSCODE_GOOD)
  254. return rv;
  255. }
  256. }
  257. }
  258. for (UA_Byte i = 0; i < count; i++) {
  259. rv = UA_DataSetMessage_encodeBinary(&(src->payload.dataSetPayload.dataSetMessages[i]), bufPos, bufEnd);
  260. if(rv != UA_STATUSCODE_GOOD)
  261. return rv;
  262. }
  263. } else {
  264. rv = UA_STATUSCODE_BADNOTIMPLEMENTED;
  265. }
  266. if(rv != UA_STATUSCODE_GOOD)
  267. return rv;
  268. // SecurityFooter
  269. if(src->securityHeader.securityFooterEnabled) {
  270. for (UA_Byte i = 0; i < src->securityHeader.securityFooterSize; i++) {
  271. rv = UA_Byte_encodeBinary(&(src->securityFooter.data[i]), bufPos, bufEnd);
  272. if(rv != UA_STATUSCODE_GOOD)
  273. return rv;
  274. }
  275. }
  276. // Signature
  277. rv = UA_ByteString_encodeBinary(&(src->signature), bufPos, bufEnd);
  278. if(rv != UA_STATUSCODE_GOOD)
  279. return rv;
  280. retval = UA_STATUSCODE_GOOD;
  281. return retval;
  282. }
  283. static UA_StatusCode
  284. UA_NetworkMessage_decodeBinaryInternal(const UA_ByteString *src, size_t *offset,
  285. UA_NetworkMessage* dst) {
  286. UA_StatusCode retval = UA_STATUSCODE_BADNOTIMPLEMENTED;
  287. memset(dst, 0, sizeof(UA_NetworkMessage));
  288. UA_Byte v = 0;
  289. UA_StatusCode rv = UA_Byte_decodeBinary(src, offset, &v);
  290. if(rv != UA_STATUSCODE_GOOD)
  291. return rv;
  292. dst->version = v & NM_VERSION_MASK;
  293. if((v & NM_PUBLISHER_ID_ENABLED_MASK) != 0)
  294. dst->publisherIdEnabled = true;
  295. if((v & NM_GROUP_HEADER_ENABLED_MASK) != 0)
  296. dst->groupHeaderEnabled = true;
  297. if((v & NM_PAYLOAD_HEADER_ENABLED_MASK) != 0)
  298. dst->payloadHeaderEnabled = true;
  299. if((v & NM_EXTENDEDFLAGS1_ENABLED_MASK) != 0) {
  300. v = 0;
  301. rv = UA_Byte_decodeBinary(src, offset, &v);
  302. if(rv != UA_STATUSCODE_GOOD)
  303. return rv;
  304. dst->publisherIdType = (UA_PublisherIdDatatype)(v & NM_PUBLISHER_ID_MASK);
  305. if((v & NM_DATASET_CLASSID_ENABLED_MASK) != 0)
  306. dst->dataSetClassIdEnabled = true;
  307. if((v & NM_SECURITY_ENABLED_MASK) != 0)
  308. dst->securityEnabled = true;
  309. if((v & NM_TIMESTAMP_ENABLED_MASK) != 0)
  310. dst->timestampEnabled = true;
  311. if((v & NM_PICOSECONDS_ENABLED_MASK) != 0)
  312. dst->picosecondsEnabled = true;
  313. if((v & NM_EXTENDEDFLAGS2_ENABLED_MASK) != 0) {
  314. v = 0;
  315. rv = UA_Byte_decodeBinary(src, offset, &v);
  316. if(rv != UA_STATUSCODE_GOOD)
  317. return rv;
  318. if((v & NM_CHUNK_MESSAGE_MASK) != 0)
  319. dst->chunkMessage = true;
  320. if((v & NM_PROMOTEDFIELDS_ENABLED_MASK) != 0)
  321. dst->promotedFieldsEnabled = true;
  322. v = v & NM_NETWORK_MSG_TYPE_MASK;
  323. v = (UA_Byte) (v >> NM_SHIFT_LEN);
  324. dst->networkMessageType = (UA_NetworkMessageType)v;
  325. }
  326. }
  327. if(dst->publisherIdEnabled) {
  328. switch (dst->publisherIdType) {
  329. case UA_PUBLISHERDATATYPE_BYTE:
  330. rv = UA_Byte_decodeBinary(src, offset, &(dst->publisherId.publisherIdByte));
  331. break;
  332. case UA_PUBLISHERDATATYPE_UINT16:
  333. rv = UA_UInt16_decodeBinary(src, offset, &(dst->publisherId.publisherIdUInt16));
  334. break;
  335. case UA_PUBLISHERDATATYPE_UINT32:
  336. rv = UA_UInt32_decodeBinary(src, offset, &(dst->publisherId.publisherIdUInt32));
  337. break;
  338. case UA_PUBLISHERDATATYPE_UINT64:
  339. rv = UA_UInt64_decodeBinary(src, offset, &(dst->publisherId.publisherIdUInt64));
  340. break;
  341. case UA_PUBLISHERDATATYPE_STRING:
  342. rv = UA_String_decodeBinary(src, offset, &(dst->publisherId.publisherIdString));
  343. break;
  344. default:
  345. rv = UA_STATUSCODE_BADINTERNALERROR;
  346. break;
  347. }
  348. if(rv != UA_STATUSCODE_GOOD)
  349. return rv;
  350. }
  351. if(dst->dataSetClassIdEnabled) {
  352. rv = UA_Guid_decodeBinary(src, offset, &(dst->dataSetClassId));
  353. if(rv != UA_STATUSCODE_GOOD)
  354. return rv;
  355. }
  356. // GroupHeader
  357. if(dst->groupHeaderEnabled) {
  358. v = 0;
  359. rv = UA_Byte_decodeBinary(src, offset, &v);
  360. if(rv != UA_STATUSCODE_GOOD)
  361. return rv;
  362. if((v & GROUP_HEADER_WRITER_GROUPID_ENABLED) != 0)
  363. dst->groupHeader.writerGroupIdEnabled = true;
  364. if((v & GROUP_HEADER_GROUP_VERSION_ENABLED) != 0)
  365. dst->groupHeader.groupVersionEnabled = true;
  366. if((v & GROUP_HEADER_NM_NUMBER_ENABLED) != 0)
  367. dst->groupHeader.networkMessageNumberEnabled = true;
  368. if((v & GROUP_HEADER_SEQUENCE_NUMBER_ENABLED) != 0)
  369. dst->groupHeader.sequenceNumberEnabled = true;
  370. if(dst->groupHeader.writerGroupIdEnabled) {
  371. rv = UA_UInt16_decodeBinary(src, offset, &dst->groupHeader.writerGroupId);
  372. if(rv != UA_STATUSCODE_GOOD)
  373. return rv;
  374. }
  375. if(dst->groupHeader.groupVersionEnabled) {
  376. rv = UA_UInt32_decodeBinary(src, offset, &dst->groupHeader.groupVersion);
  377. if(rv != UA_STATUSCODE_GOOD)
  378. return rv;
  379. }
  380. if(dst->groupHeader.networkMessageNumberEnabled) {
  381. rv = UA_UInt16_decodeBinary(src, offset, &dst->groupHeader.networkMessageNumber);
  382. if(rv != UA_STATUSCODE_GOOD)
  383. return rv;
  384. }
  385. if(dst->groupHeader.sequenceNumberEnabled) {
  386. rv = UA_UInt16_decodeBinary(src, offset, &dst->groupHeader.sequenceNumber);
  387. if(rv != UA_STATUSCODE_GOOD)
  388. return rv;
  389. }
  390. }
  391. // Payload-Header
  392. if(dst->payloadHeaderEnabled) {
  393. if(dst->networkMessageType == UA_NETWORKMESSAGE_DATASET) {
  394. rv = UA_Byte_decodeBinary(src, offset, &dst->payloadHeader.dataSetPayloadHeader.count);
  395. if(rv != UA_STATUSCODE_GOOD)
  396. return rv;
  397. dst->payloadHeader.dataSetPayloadHeader.dataSetWriterIds =
  398. (UA_UInt16 *)UA_Array_new(dst->payloadHeader.dataSetPayloadHeader.count, &UA_TYPES[UA_TYPES_UINT16]);
  399. for (UA_Byte i = 0; i < dst->payloadHeader.dataSetPayloadHeader.count; i++) {
  400. rv = UA_UInt16_decodeBinary(src, offset, &(dst->payloadHeader.dataSetPayloadHeader.dataSetWriterIds[i]));
  401. if(rv != UA_STATUSCODE_GOOD)
  402. return rv;
  403. }
  404. } else {
  405. rv = UA_STATUSCODE_BADNOTIMPLEMENTED;
  406. return rv;
  407. }
  408. }
  409. // Timestamp
  410. if(dst->timestampEnabled) {
  411. rv = UA_DateTime_decodeBinary(src, offset, &(dst->timestamp));
  412. if(rv != UA_STATUSCODE_GOOD)
  413. return rv;
  414. }
  415. // Picoseconds
  416. if(dst->picosecondsEnabled) {
  417. rv = UA_UInt16_decodeBinary(src, offset, &(dst->picoseconds));
  418. if(rv != UA_STATUSCODE_GOOD)
  419. return rv;
  420. }
  421. // PromotedFields
  422. if(dst->promotedFieldsEnabled) {
  423. // Size
  424. UA_UInt16 promotedFieldsSize = 0;
  425. rv = UA_UInt16_decodeBinary(src, offset, &promotedFieldsSize);
  426. if(rv != UA_STATUSCODE_GOOD)
  427. return rv;
  428. // promotedFieldsSize: here size in Byte, not the number of objects!
  429. if(promotedFieldsSize > 0) {
  430. // store offset, later compared with promotedFieldsSize
  431. size_t offsetEnd = (*offset) + promotedFieldsSize;
  432. unsigned int counter = 0;
  433. do {
  434. if(counter == 0) {
  435. dst->promotedFields = (UA_Variant*)UA_malloc(UA_TYPES[UA_TYPES_VARIANT].memSize);
  436. // set promotedFieldsSize to the number of objects
  437. dst->promotedFieldsSize = (UA_UInt16) (counter + 1);
  438. } else {
  439. dst->promotedFields = (UA_Variant*)UA_realloc(dst->promotedFields,
  440. UA_TYPES[UA_TYPES_VARIANT].memSize * (counter + 1));
  441. // set promotedFieldsSize to the number of objects
  442. dst->promotedFieldsSize = (UA_UInt16) (counter + 1);
  443. }
  444. UA_Variant_init(&dst->promotedFields[counter]);
  445. rv = UA_Variant_decodeBinary(src, offset, &dst->promotedFields[counter]);
  446. if(rv != UA_STATUSCODE_GOOD)
  447. return rv;
  448. counter++;
  449. } while ((*offset) < offsetEnd);
  450. }
  451. }
  452. // SecurityHeader
  453. if(dst->securityEnabled) {
  454. // SecurityFlags
  455. v = 0;
  456. rv = UA_Byte_decodeBinary(src, offset, &v);
  457. if(rv != UA_STATUSCODE_GOOD)
  458. return rv;
  459. if((v & SECURITY_HEADER_NM_SIGNED) != 0)
  460. dst->securityHeader.networkMessageSigned = true;
  461. if((v & SECURITY_HEADER_NM_ENCRYPTED) != 0)
  462. dst->securityHeader.networkMessageEncrypted = true;
  463. if((v & SECURITY_HEADER_SEC_FOOTER_ENABLED) != 0)
  464. dst->securityHeader.securityFooterEnabled = true;
  465. if((v & SECURITY_HEADER_FORCE_KEY_RESET) != 0)
  466. dst->securityHeader.forceKeyReset = true;
  467. // SecurityTokenId
  468. rv = UA_UInt32_decodeBinary(src, offset, &dst->securityHeader.securityTokenId);
  469. if(rv != UA_STATUSCODE_GOOD)
  470. return rv;
  471. // NonceLength
  472. rv = UA_Byte_decodeBinary(src, offset, &dst->securityHeader.nonceLength);
  473. if(rv != UA_STATUSCODE_GOOD)
  474. return rv;
  475. // MessageNonce
  476. if(dst->securityHeader.nonceLength > 0) {
  477. rv = UA_ByteString_allocBuffer(&dst->securityHeader.messageNonce, dst->securityHeader.nonceLength);
  478. if(rv != UA_STATUSCODE_GOOD)
  479. return rv;
  480. for (UA_Byte i = 0; i < dst->securityHeader.nonceLength; i++) {
  481. rv = UA_Byte_decodeBinary(src, offset, &(dst->securityHeader.messageNonce.data[i]));
  482. if(rv != UA_STATUSCODE_GOOD)
  483. return rv;
  484. }
  485. }
  486. // SecurityFooterSize
  487. if(dst->securityHeader.securityFooterEnabled) {
  488. rv = UA_UInt16_decodeBinary(src, offset, &dst->securityHeader.securityFooterSize);
  489. if(rv != UA_STATUSCODE_GOOD)
  490. return rv;
  491. }
  492. }
  493. // Payload
  494. if(dst->networkMessageType == UA_NETWORKMESSAGE_DATASET) {
  495. UA_Byte count = 1;
  496. if(dst->payloadHeaderEnabled) {
  497. count = dst->payloadHeader.dataSetPayloadHeader.count;
  498. if(count > 1) {
  499. dst->payload.dataSetPayload.sizes = (UA_UInt16 *)UA_Array_new(count, &UA_TYPES[UA_TYPES_UINT16]);
  500. for (UA_Byte i = 0; i < count; i++) {
  501. rv = UA_UInt16_decodeBinary(src, offset, &(dst->payload.dataSetPayload.sizes[i]));
  502. if(rv != UA_STATUSCODE_GOOD)
  503. return rv;
  504. }
  505. }
  506. }
  507. dst->payload.dataSetPayload.dataSetMessages = (UA_DataSetMessage*)UA_calloc(count, sizeof(UA_DataSetMessage));
  508. for (UA_Byte i = 0; i < count; i++) {
  509. rv = UA_DataSetMessage_decodeBinary(src, offset, &(dst->payload.dataSetPayload.dataSetMessages[i]));
  510. if(rv != UA_STATUSCODE_GOOD)
  511. return rv;
  512. }
  513. } else {
  514. rv = UA_STATUSCODE_BADNOTIMPLEMENTED;
  515. }
  516. if(rv != UA_STATUSCODE_GOOD)
  517. return rv;
  518. // SecurityFooter
  519. if(dst->securityHeader.securityFooterEnabled && (dst->securityHeader.securityFooterSize > 0)) {
  520. rv = UA_ByteString_allocBuffer(&dst->securityFooter, dst->securityHeader.securityFooterSize);
  521. if(rv != UA_STATUSCODE_GOOD)
  522. return rv;
  523. for (UA_Byte i = 0; i < dst->securityHeader.securityFooterSize; i++) {
  524. rv = UA_Byte_decodeBinary(src, offset, &(dst->securityFooter.data[i]));
  525. if(rv != UA_STATUSCODE_GOOD)
  526. return rv;
  527. }
  528. }
  529. // Signature.
  530. rv = UA_ByteString_decodeBinary(src, offset, &(dst->signature));
  531. if(rv != UA_STATUSCODE_GOOD)
  532. return rv;
  533. retval = UA_STATUSCODE_GOOD;
  534. return retval;
  535. }
  536. UA_StatusCode
  537. UA_NetworkMessage_decodeBinary(const UA_ByteString *src, size_t *offset, UA_NetworkMessage* dst) {
  538. UA_StatusCode retval = UA_NetworkMessage_decodeBinaryInternal(src, offset, dst);
  539. if(retval != UA_STATUSCODE_GOOD)
  540. UA_NetworkMessage_deleteMembers(dst);
  541. return retval;
  542. }
  543. size_t UA_NetworkMessage_calcSizeBinary(const UA_NetworkMessage* p) {
  544. size_t retval = 0;
  545. UA_Byte byte;
  546. size_t size = UA_Byte_calcSizeBinary(&byte); // UADPVersion + UADPFlags
  547. if(UA_NetworkMessage_ExtendedFlags1Enabled(p)) {
  548. size += UA_Byte_calcSizeBinary(&byte);
  549. if(UA_NetworkMessage_ExtendedFlags2Enabled(p))
  550. size += UA_Byte_calcSizeBinary(&byte);
  551. }
  552. if(p->publisherIdEnabled) {
  553. switch (p->publisherIdType) {
  554. case UA_PUBLISHERDATATYPE_BYTE:
  555. size += UA_Byte_calcSizeBinary(&p->publisherId.publisherIdByte);
  556. break;
  557. case UA_PUBLISHERDATATYPE_UINT16:
  558. size += UA_UInt16_calcSizeBinary(&p->publisherId.publisherIdUInt16);
  559. break;
  560. case UA_PUBLISHERDATATYPE_UINT32:
  561. size += UA_UInt32_calcSizeBinary(&p->publisherId.publisherIdUInt32);
  562. break;
  563. case UA_PUBLISHERDATATYPE_UINT64:
  564. size += UA_UInt64_calcSizeBinary(&p->publisherId.publisherIdUInt64);
  565. break;
  566. case UA_PUBLISHERDATATYPE_STRING:
  567. size += UA_String_calcSizeBinary(&p->publisherId.publisherIdString);
  568. break;
  569. }
  570. }
  571. if(p->dataSetClassIdEnabled)
  572. size += UA_Guid_calcSizeBinary(&p->dataSetClassId);
  573. // Group Header
  574. if(p->groupHeaderEnabled) {
  575. size += UA_Byte_calcSizeBinary(&byte);
  576. if(p->groupHeader.writerGroupIdEnabled)
  577. size += UA_UInt16_calcSizeBinary(&p->groupHeader.writerGroupId);
  578. if(p->groupHeader.groupVersionEnabled)
  579. size += UA_UInt32_calcSizeBinary(&p->groupHeader.groupVersion);
  580. if(p->groupHeader.networkMessageNumberEnabled)
  581. size += UA_UInt16_calcSizeBinary(&p->groupHeader.networkMessageNumber);
  582. if(p->groupHeader.sequenceNumberEnabled)
  583. size += UA_UInt16_calcSizeBinary(&p->groupHeader.sequenceNumber);
  584. }
  585. // Payload Header
  586. if(p->payloadHeaderEnabled) {
  587. if(p->networkMessageType == UA_NETWORKMESSAGE_DATASET) {
  588. size += UA_Byte_calcSizeBinary(&p->payloadHeader.dataSetPayloadHeader.count);
  589. if(p->payloadHeader.dataSetPayloadHeader.dataSetWriterIds != NULL) {
  590. size += UA_UInt16_calcSizeBinary(&p->payloadHeader.dataSetPayloadHeader.dataSetWriterIds[0]) *
  591. p->payloadHeader.dataSetPayloadHeader.count;
  592. } else {
  593. UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "no dataSetWriterIds given!");
  594. }
  595. } else {
  596. // not implemented
  597. }
  598. }
  599. if(p->timestampEnabled)
  600. size += UA_DateTime_calcSizeBinary(&p->timestamp);
  601. if(p->picosecondsEnabled)
  602. size += UA_UInt16_calcSizeBinary(&p->picoseconds);
  603. if(p->promotedFieldsEnabled) {
  604. size += UA_UInt16_calcSizeBinary(&p->promotedFieldsSize);
  605. for (UA_UInt16 i = 0; i < p->promotedFieldsSize; i++)
  606. size += UA_Variant_calcSizeBinary(&p->promotedFields[i]);
  607. }
  608. if(p->securityEnabled) {
  609. size += UA_Byte_calcSizeBinary(&byte);
  610. size += UA_UInt32_calcSizeBinary(&p->securityHeader.securityTokenId);
  611. size += UA_Byte_calcSizeBinary(&p->securityHeader.nonceLength);
  612. if(p->securityHeader.nonceLength > 0)
  613. size += (UA_Byte_calcSizeBinary(&p->securityHeader.messageNonce.data[0]) * p->securityHeader.nonceLength);
  614. if(p->securityHeader.securityFooterEnabled)
  615. size += UA_UInt16_calcSizeBinary(&p->securityHeader.securityFooterSize);
  616. }
  617. if(p->networkMessageType == UA_NETWORKMESSAGE_DATASET) {
  618. UA_Byte count = 1;
  619. if(p->payloadHeaderEnabled) {
  620. count = p->payloadHeader.dataSetPayloadHeader.count;
  621. if(count > 1)
  622. size += UA_UInt16_calcSizeBinary(&(p->payload.dataSetPayload.sizes[0])) * count;
  623. }
  624. for (size_t i = 0; i < count; i++)
  625. size += UA_DataSetMessage_calcSizeBinary(&(p->payload.dataSetPayload.dataSetMessages[i]));
  626. }
  627. if(p->securityHeader.securityFooterEnabled)
  628. size += p->securityHeader.securityFooterSize;
  629. size += UA_ByteString_calcSizeBinary(&p->signature);
  630. retval = size;
  631. return retval;
  632. }
  633. void
  634. UA_NetworkMessage_deleteMembers(UA_NetworkMessage* p) {
  635. if(p->promotedFieldsEnabled)
  636. UA_Array_delete(p->promotedFields, p->promotedFieldsSize, &UA_TYPES[UA_TYPES_VARIANT]);
  637. if(p->securityEnabled && (p->securityHeader.nonceLength > 0))
  638. UA_ByteString_deleteMembers(&p->securityHeader.messageNonce);
  639. if(p->networkMessageType == UA_NETWORKMESSAGE_DATASET) {
  640. if(p->payloadHeaderEnabled) {
  641. if(p->payloadHeader.dataSetPayloadHeader.dataSetWriterIds != NULL) {
  642. UA_Array_delete(p->payloadHeader.dataSetPayloadHeader.dataSetWriterIds,
  643. p->payloadHeader.dataSetPayloadHeader.count, &UA_TYPES[UA_TYPES_UINT16]);
  644. }
  645. if(p->payload.dataSetPayload.sizes != NULL) {
  646. UA_Array_delete(p->payload.dataSetPayload.sizes,
  647. p->payloadHeader.dataSetPayloadHeader.count, &UA_TYPES[UA_TYPES_UINT16]);
  648. }
  649. }
  650. if(p->payload.dataSetPayload.dataSetMessages != NULL) {
  651. UA_Byte count = 1;
  652. if(p->payloadHeaderEnabled)
  653. count = p->payloadHeader.dataSetPayloadHeader.count;
  654. for (size_t i = 0; i < count; i++)
  655. UA_DataSetMessage_free(&(p->payload.dataSetPayload.dataSetMessages[i]));
  656. UA_free(p->payload.dataSetPayload.dataSetMessages);
  657. }
  658. }
  659. if(p->securityHeader.securityFooterEnabled && (p->securityHeader.securityFooterSize > 0))
  660. UA_ByteString_deleteMembers(&p->securityFooter);
  661. memset(p, 0, sizeof(UA_NetworkMessage));
  662. }
  663. void UA_NetworkMessage_delete(UA_NetworkMessage* p) {
  664. UA_NetworkMessage_deleteMembers(p);
  665. }
  666. UA_Boolean
  667. UA_NetworkMessage_ExtendedFlags1Enabled(const UA_NetworkMessage* src) {
  668. UA_Boolean retval = false;
  669. if((src->publisherIdType != UA_PUBLISHERDATATYPE_BYTE)
  670. || src->dataSetClassIdEnabled
  671. || src->securityEnabled
  672. || src->timestampEnabled
  673. || src->picosecondsEnabled
  674. || UA_NetworkMessage_ExtendedFlags2Enabled(src))
  675. {
  676. retval = true;
  677. }
  678. return retval;
  679. }
  680. UA_Boolean
  681. UA_NetworkMessage_ExtendedFlags2Enabled(const UA_NetworkMessage* src) {
  682. UA_Boolean retval = false;
  683. if(src->chunkMessage
  684. || src->promotedFieldsEnabled
  685. || (src->networkMessageType != UA_NETWORKMESSAGE_DATASET))
  686. {
  687. retval = true;
  688. }
  689. return retval;
  690. }
  691. UA_Boolean
  692. UA_DataSetMessageHeader_DataSetFlags2Enabled(const UA_DataSetMessageHeader* src) {
  693. UA_Boolean retval = false;
  694. if((src->dataSetMessageType != UA_DATASETMESSAGE_DATAKEYFRAME) || src->timestampEnabled || src->picoSecondsIncluded)
  695. {
  696. retval = true;
  697. }
  698. return retval;
  699. }
  700. UA_StatusCode
  701. UA_DataSetMessageHeader_encodeBinary(const UA_DataSetMessageHeader* src, UA_Byte **bufPos,
  702. const UA_Byte *bufEnd) {
  703. UA_StatusCode retval = UA_STATUSCODE_BADNOTIMPLEMENTED;
  704. UA_Byte v;
  705. // DataSetFlags1
  706. v = src->fieldEncoding;
  707. // shift left 1 bit
  708. v = (UA_Byte)(v << DS_MH_SHIFT_LEN);
  709. if(src->dataSetMessageValid)
  710. v |= DS_MESSAGEHEADER_DS_MSG_VALID;
  711. if(src->dataSetMessageSequenceNrEnabled)
  712. v |= DS_MESSAGEHEADER_SEQ_NR_ENABLED_MASK;
  713. if(src->statusEnabled)
  714. v |= DS_MESSAGEHEADER_STATUS_ENABLED_MASK;
  715. if(src->configVersionMajorVersionEnabled)
  716. v |= DS_MESSAGEHEADER_CONFIGMAJORVERSION_ENABLED_MASK;
  717. if(src->configVersionMinorVersionEnabled)
  718. v |= DS_MESSAGEHEADER_CONFIGMINORVERSION_ENABLED_MASK;
  719. if(UA_DataSetMessageHeader_DataSetFlags2Enabled(src))
  720. v |= DS_MESSAGEHEADER_FLAGS2_ENABLED_MASK;
  721. UA_StatusCode rv = UA_Byte_encodeBinary(&v, bufPos, bufEnd);
  722. if(rv != UA_STATUSCODE_GOOD)
  723. return rv;
  724. // DataSetFlags2
  725. if(UA_DataSetMessageHeader_DataSetFlags2Enabled(src)) {
  726. v = src->dataSetMessageType;
  727. if(src->timestampEnabled)
  728. v |= DS_MESSAGEHEADER_TIMESTAMP_ENABLED_MASK;
  729. if(src->picoSecondsIncluded)
  730. v |= DS_MESSAGEHEADER_PICOSECONDS_INCLUDED_MASK;
  731. rv = UA_Byte_encodeBinary(&v, bufPos, bufEnd);
  732. if(rv != UA_STATUSCODE_GOOD)
  733. return rv;
  734. }
  735. // DataSetMessageSequenceNr
  736. if(src->dataSetMessageSequenceNrEnabled) {
  737. rv = UA_UInt16_encodeBinary(&src->dataSetMessageSequenceNr, bufPos, bufEnd);
  738. if(rv != UA_STATUSCODE_GOOD)
  739. return rv;
  740. }
  741. // Timestamp
  742. if(src->timestampEnabled) {
  743. rv = UA_DateTime_encodeBinary(&(src->timestamp), bufPos, bufEnd); /* UtcTime */
  744. if(rv != UA_STATUSCODE_GOOD)
  745. return rv;
  746. }
  747. // PicoSeconds
  748. if(src->picoSecondsIncluded) {
  749. rv = UA_UInt16_encodeBinary(&(src->picoSeconds), bufPos, bufEnd);
  750. if(rv != UA_STATUSCODE_GOOD)
  751. return rv;
  752. }
  753. // Status
  754. if(src->statusEnabled) {
  755. rv = UA_UInt16_encodeBinary(&(src->status), bufPos, bufEnd);
  756. if(rv != UA_STATUSCODE_GOOD)
  757. return rv;
  758. }
  759. // ConfigVersionMajorVersion
  760. if(src->configVersionMajorVersionEnabled) {
  761. rv = UA_UInt32_encodeBinary(&(src->configVersionMajorVersion), bufPos, bufEnd);
  762. if(rv != UA_STATUSCODE_GOOD)
  763. return rv;
  764. }
  765. // ConfigVersionMinorVersion
  766. if(src->configVersionMinorVersionEnabled) {
  767. rv = UA_UInt32_encodeBinary(&(src->configVersionMinorVersion), bufPos, bufEnd);
  768. if(rv != UA_STATUSCODE_GOOD)
  769. return rv;
  770. }
  771. retval = UA_STATUSCODE_GOOD;
  772. return retval;
  773. }
  774. UA_StatusCode
  775. UA_DataSetMessageHeader_decodeBinary(const UA_ByteString *src, size_t *offset,
  776. UA_DataSetMessageHeader* dst) {
  777. UA_StatusCode retval = UA_STATUSCODE_BADNOTIMPLEMENTED;
  778. memset(dst, 0, sizeof(UA_DataSetMessageHeader));
  779. UA_Byte v = 0;
  780. UA_StatusCode rv = UA_Byte_decodeBinary(src, offset, &v);
  781. if(rv != UA_STATUSCODE_GOOD)
  782. return rv;
  783. UA_Byte v2 = v & DS_MESSAGEHEADER_FIELD_ENCODING_MASK;
  784. v2 = (UA_Byte)(v2 >> DS_MH_SHIFT_LEN);
  785. dst->fieldEncoding = (UA_FieldEncoding)v2;
  786. if((v & DS_MESSAGEHEADER_DS_MSG_VALID) != 0)
  787. dst->dataSetMessageValid = true;
  788. if((v & DS_MESSAGEHEADER_SEQ_NR_ENABLED_MASK) != 0)
  789. dst->dataSetMessageSequenceNrEnabled = true;
  790. if((v & DS_MESSAGEHEADER_STATUS_ENABLED_MASK) != 0)
  791. dst->statusEnabled = true;
  792. if((v & DS_MESSAGEHEADER_CONFIGMAJORVERSION_ENABLED_MASK) != 0)
  793. dst->configVersionMajorVersionEnabled = true;
  794. if((v & DS_MESSAGEHEADER_CONFIGMINORVERSION_ENABLED_MASK) != 0)
  795. dst->configVersionMinorVersionEnabled = true;
  796. if((v & DS_MESSAGEHEADER_FLAGS2_ENABLED_MASK) != 0) {
  797. v = 0;
  798. rv = UA_Byte_decodeBinary(src, offset, &v);
  799. if(rv != UA_STATUSCODE_GOOD)
  800. return rv;
  801. dst->dataSetMessageType = (UA_DataSetMessageType)(v & DS_MESSAGEHEADER_DS_MESSAGE_TYPE_MASK);
  802. if((v & DS_MESSAGEHEADER_TIMESTAMP_ENABLED_MASK) != 0)
  803. dst->timestampEnabled = true;
  804. if((v & DS_MESSAGEHEADER_PICOSECONDS_INCLUDED_MASK) != 0)
  805. dst->picoSecondsIncluded = true;
  806. } else {
  807. dst->dataSetMessageType = UA_DATASETMESSAGE_DATAKEYFRAME;
  808. dst->picoSecondsIncluded = false;
  809. }
  810. if(dst->dataSetMessageSequenceNrEnabled) {
  811. rv = UA_UInt16_decodeBinary(src, offset, &dst->dataSetMessageSequenceNr);
  812. if(rv != UA_STATUSCODE_GOOD)
  813. return rv;
  814. } else {
  815. dst->dataSetMessageSequenceNr = 0;
  816. }
  817. if(dst->timestampEnabled) {
  818. rv = UA_DateTime_decodeBinary(src, offset, &dst->timestamp); /* UtcTime */
  819. if(rv != UA_STATUSCODE_GOOD)
  820. return rv;
  821. } else {
  822. dst->timestamp = 0;
  823. }
  824. if(dst->picoSecondsIncluded) {
  825. rv = UA_UInt16_decodeBinary(src, offset, &dst->picoSeconds);
  826. if(rv != UA_STATUSCODE_GOOD)
  827. return rv;
  828. } else {
  829. dst->picoSeconds = 0;
  830. }
  831. if(dst->statusEnabled) {
  832. rv = UA_UInt16_decodeBinary(src, offset, &dst->status);
  833. if(rv != UA_STATUSCODE_GOOD)
  834. return rv;
  835. } else {
  836. dst->status = 0;
  837. }
  838. if(dst->configVersionMajorVersionEnabled) {
  839. rv = UA_UInt32_decodeBinary(src, offset, &dst->configVersionMajorVersion);
  840. if(rv != UA_STATUSCODE_GOOD)
  841. return rv;
  842. } else {
  843. dst->configVersionMajorVersion = 0;
  844. }
  845. if(dst->configVersionMinorVersionEnabled) {
  846. rv = UA_UInt32_decodeBinary(src, offset, &dst->configVersionMinorVersion);
  847. if(rv != UA_STATUSCODE_GOOD)
  848. return rv;
  849. } else {
  850. dst->configVersionMinorVersion = 0;
  851. }
  852. retval = UA_STATUSCODE_GOOD;
  853. return retval;
  854. }
  855. size_t
  856. UA_DataSetMessageHeader_calcSizeBinary(const UA_DataSetMessageHeader* p) {
  857. UA_Byte byte;
  858. size_t size = UA_Byte_calcSizeBinary(&byte); // DataSetMessage Type + Flags
  859. if(UA_DataSetMessageHeader_DataSetFlags2Enabled(p))
  860. size += UA_Byte_calcSizeBinary(&byte);
  861. if(p->dataSetMessageSequenceNrEnabled)
  862. size += UA_UInt16_calcSizeBinary(&p->dataSetMessageSequenceNr);
  863. if(p->timestampEnabled)
  864. size += UA_DateTime_calcSizeBinary(&p->timestamp); /* UtcTime */
  865. if(p->picoSecondsIncluded)
  866. size += UA_UInt16_calcSizeBinary(&p->picoSeconds);
  867. if(p->statusEnabled)
  868. size += UA_UInt16_calcSizeBinary(&p->status);
  869. if(p->configVersionMajorVersionEnabled)
  870. size += UA_UInt32_calcSizeBinary(&p->configVersionMajorVersion);
  871. if(p->configVersionMinorVersionEnabled)
  872. size += UA_UInt32_calcSizeBinary(&p->configVersionMinorVersion);
  873. return size;
  874. }
  875. UA_StatusCode
  876. UA_DataSetMessage_encodeBinary(const UA_DataSetMessage* src, UA_Byte **bufPos,
  877. const UA_Byte *bufEnd) {
  878. UA_StatusCode rv = UA_DataSetMessageHeader_encodeBinary(&src->header, bufPos, bufEnd);
  879. if(rv != UA_STATUSCODE_GOOD)
  880. return rv;
  881. if(src->header.dataSetMessageType == UA_DATASETMESSAGE_DATAKEYFRAME) {
  882. if(src->header.fieldEncoding != UA_FIELDENCODING_RAWDATA) {
  883. rv = UA_UInt16_encodeBinary(&(src->data.keyFrameData.fieldCount), bufPos, bufEnd);
  884. if(rv != UA_STATUSCODE_GOOD)
  885. return rv;
  886. }
  887. if(src->header.fieldEncoding == UA_FIELDENCODING_VARIANT) {
  888. for (UA_UInt16 i = 0; i < src->data.keyFrameData.fieldCount; i++) {
  889. rv = UA_Variant_encodeBinary(&(src->data.keyFrameData.dataSetFields[i].value), bufPos, bufEnd);
  890. if(rv != UA_STATUSCODE_GOOD)
  891. return rv;
  892. }
  893. } else if(src->header.fieldEncoding == UA_FIELDENCODING_RAWDATA) {
  894. return UA_STATUSCODE_BADNOTIMPLEMENTED;
  895. } else if(src->header.fieldEncoding == UA_FIELDENCODING_DATAVALUE) {
  896. for (UA_UInt16 i = 0; i < src->data.keyFrameData.fieldCount; i++) {
  897. rv = UA_DataValue_encodeBinary(&(src->data.keyFrameData.dataSetFields[i]), bufPos, bufEnd);
  898. if(rv != UA_STATUSCODE_GOOD)
  899. return rv;
  900. }
  901. }
  902. } else if(src->header.dataSetMessageType == UA_DATASETMESSAGE_DATADELTAFRAME) {
  903. // Encode Delta Frame
  904. // Here the FieldCount is always present
  905. rv = UA_UInt16_encodeBinary(&(src->data.keyFrameData.fieldCount), bufPos, bufEnd);
  906. if(rv != UA_STATUSCODE_GOOD)
  907. return rv;
  908. if(src->header.fieldEncoding == UA_FIELDENCODING_VARIANT) {
  909. for (UA_UInt16 i = 0; i < src->data.deltaFrameData.fieldCount; i++) {
  910. rv = UA_UInt16_encodeBinary(&(src->data.deltaFrameData.deltaFrameFields[i].fieldIndex), bufPos, bufEnd);
  911. if(rv != UA_STATUSCODE_GOOD)
  912. return rv;
  913. rv = UA_Variant_encodeBinary(&(src->data.deltaFrameData.deltaFrameFields[i].fieldValue.value), bufPos, bufEnd);
  914. if(rv != UA_STATUSCODE_GOOD)
  915. return rv;
  916. }
  917. } else if(src->header.fieldEncoding == UA_FIELDENCODING_RAWDATA) {
  918. return UA_STATUSCODE_BADNOTIMPLEMENTED;
  919. } else if(src->header.fieldEncoding == UA_FIELDENCODING_DATAVALUE) {
  920. for (UA_UInt16 i = 0; i < src->data.deltaFrameData.fieldCount; i++) {
  921. rv = UA_UInt16_encodeBinary(&(src->data.deltaFrameData.deltaFrameFields[i].fieldIndex), bufPos, bufEnd);
  922. if(rv != UA_STATUSCODE_GOOD)
  923. return rv;
  924. rv = UA_DataValue_encodeBinary(&(src->data.deltaFrameData.deltaFrameFields[i].fieldValue), bufPos, bufEnd);
  925. if(rv != UA_STATUSCODE_GOOD)
  926. return rv;
  927. }
  928. }
  929. } else if(src->header.dataSetMessageType != UA_DATASETMESSAGE_KEEPALIVE) {
  930. return UA_STATUSCODE_BADNOTIMPLEMENTED;
  931. }
  932. /* Keep-Alive Message contains no Payload Data */
  933. return UA_STATUSCODE_GOOD;
  934. }
  935. UA_StatusCode
  936. UA_DataSetMessage_decodeBinary(const UA_ByteString *src, size_t *offset, UA_DataSetMessage* dst) {
  937. memset(dst, 0, sizeof(UA_DataSetMessage));
  938. UA_StatusCode rv = UA_DataSetMessageHeader_decodeBinary(src, offset, &dst->header);
  939. if(rv != UA_STATUSCODE_GOOD)
  940. return rv;
  941. if(dst->header.dataSetMessageType == UA_DATASETMESSAGE_DATAKEYFRAME) {
  942. if(dst->header.fieldEncoding != UA_FIELDENCODING_RAWDATA) {
  943. rv = UA_UInt16_decodeBinary(src, offset, &dst->data.keyFrameData.fieldCount);
  944. if(rv != UA_STATUSCODE_GOOD)
  945. return rv;
  946. if(dst->header.fieldEncoding == UA_FIELDENCODING_VARIANT) {
  947. dst->data.keyFrameData.dataSetFields =
  948. (UA_DataValue *)UA_Array_new(dst->data.keyFrameData.fieldCount, &UA_TYPES[UA_TYPES_DATAVALUE]);
  949. for (UA_UInt16 i = 0; i < dst->data.keyFrameData.fieldCount; i++) {
  950. UA_DataValue_init(&dst->data.keyFrameData.dataSetFields[i]);
  951. rv = UA_Variant_decodeBinary(src, offset, &dst->data.keyFrameData.dataSetFields[i].value);
  952. if(rv != UA_STATUSCODE_GOOD)
  953. return rv;
  954. dst->data.keyFrameData.dataSetFields[i].hasValue = true;
  955. }
  956. } else if(dst->header.fieldEncoding == UA_FIELDENCODING_RAWDATA) {
  957. return UA_STATUSCODE_BADNOTIMPLEMENTED;
  958. } else if(dst->header.fieldEncoding == UA_FIELDENCODING_DATAVALUE) {
  959. dst->data.keyFrameData.dataSetFields =
  960. (UA_DataValue *)UA_Array_new(dst->data.keyFrameData.fieldCount, &UA_TYPES[UA_TYPES_DATAVALUE]);
  961. for (UA_UInt16 i = 0; i < dst->data.keyFrameData.fieldCount; i++) {
  962. rv = UA_DataValue_decodeBinary(src, offset, &(dst->data.keyFrameData.dataSetFields[i]));
  963. if(rv != UA_STATUSCODE_GOOD)
  964. return rv;
  965. }
  966. }
  967. }
  968. } else if(dst->header.dataSetMessageType == UA_DATASETMESSAGE_DATADELTAFRAME) {
  969. if(dst->header.fieldEncoding != UA_FIELDENCODING_RAWDATA) {
  970. rv = UA_UInt16_decodeBinary(src, offset, &dst->data.deltaFrameData.fieldCount);
  971. if(rv != UA_STATUSCODE_GOOD)
  972. return rv;
  973. if(dst->header.fieldEncoding == UA_FIELDENCODING_VARIANT) {
  974. size_t memsize = sizeof(UA_DataSetMessage_DeltaFrameField) * dst->data.deltaFrameData.fieldCount;
  975. dst->data.deltaFrameData.deltaFrameFields = (UA_DataSetMessage_DeltaFrameField*)UA_malloc(memsize);
  976. for (UA_UInt16 i = 0; i < dst->data.deltaFrameData.fieldCount; i++) {
  977. rv = UA_UInt16_decodeBinary(src, offset, &dst->data.deltaFrameData.deltaFrameFields[i].fieldIndex);
  978. if(rv != UA_STATUSCODE_GOOD)
  979. return rv;
  980. UA_DataValue_init(&dst->data.deltaFrameData.deltaFrameFields[i].fieldValue);
  981. rv = UA_Variant_decodeBinary(src, offset, &dst->data.deltaFrameData.deltaFrameFields[i].fieldValue.value);
  982. if(rv != UA_STATUSCODE_GOOD)
  983. return rv;
  984. dst->data.deltaFrameData.deltaFrameFields[i].fieldValue.hasValue = true;
  985. }
  986. } else if(dst->header.fieldEncoding == UA_FIELDENCODING_RAWDATA) {
  987. return UA_STATUSCODE_BADNOTIMPLEMENTED;
  988. } else if(dst->header.fieldEncoding == UA_FIELDENCODING_DATAVALUE) {
  989. size_t memsize = sizeof(UA_DataSetMessage_DeltaFrameField) * dst->data.deltaFrameData.fieldCount;
  990. dst->data.deltaFrameData.deltaFrameFields = (UA_DataSetMessage_DeltaFrameField*)UA_malloc(memsize);
  991. for (UA_UInt16 i = 0; i < dst->data.deltaFrameData.fieldCount; i++) {
  992. rv = UA_UInt16_decodeBinary(src, offset, &dst->data.deltaFrameData.deltaFrameFields[i].fieldIndex);
  993. if(rv != UA_STATUSCODE_GOOD)
  994. return rv;
  995. rv = UA_DataValue_decodeBinary(src, offset, &(dst->data.deltaFrameData.deltaFrameFields[i].fieldValue));
  996. if(rv != UA_STATUSCODE_GOOD)
  997. return rv;
  998. }
  999. }
  1000. }
  1001. } else if(dst->header.dataSetMessageType != UA_DATASETMESSAGE_KEEPALIVE) {
  1002. return UA_STATUSCODE_BADNOTIMPLEMENTED;
  1003. }
  1004. /* Keep-Alive Message contains no Payload Data */
  1005. return UA_STATUSCODE_GOOD;
  1006. }
  1007. size_t
  1008. UA_DataSetMessage_calcSizeBinary(const UA_DataSetMessage* p) {
  1009. size_t size = UA_DataSetMessageHeader_calcSizeBinary(&p->header);
  1010. if(p->header.dataSetMessageType == UA_DATASETMESSAGE_DATAKEYFRAME) {
  1011. if(p->header.fieldEncoding != UA_FIELDENCODING_RAWDATA)
  1012. size += UA_calcSizeBinary(&p->data.keyFrameData.fieldCount, &UA_TYPES[UA_TYPES_UINT16]);
  1013. if(p->header.fieldEncoding == UA_FIELDENCODING_VARIANT) {
  1014. for (UA_UInt16 i = 0; i < p->data.keyFrameData.fieldCount; i++)
  1015. size += UA_calcSizeBinary(&p->data.keyFrameData.dataSetFields[i].value, &UA_TYPES[UA_TYPES_VARIANT]);
  1016. } else if(p->header.fieldEncoding == UA_FIELDENCODING_RAWDATA) {
  1017. // not implemented
  1018. } else if(p->header.fieldEncoding == UA_FIELDENCODING_DATAVALUE) {
  1019. for (UA_UInt16 i = 0; i < p->data.keyFrameData.fieldCount; i++)
  1020. size += UA_calcSizeBinary(&p->data.keyFrameData.dataSetFields[i], &UA_TYPES[UA_TYPES_DATAVALUE]);
  1021. }
  1022. } else if(p->header.dataSetMessageType == UA_DATASETMESSAGE_DATADELTAFRAME) {
  1023. if(p->header.fieldEncoding != UA_FIELDENCODING_RAWDATA)
  1024. size += UA_calcSizeBinary(&p->data.deltaFrameData.fieldCount, &UA_TYPES[UA_TYPES_UINT16]);
  1025. if(p->header.fieldEncoding == UA_FIELDENCODING_VARIANT) {
  1026. for (UA_UInt16 i = 0; i < p->data.deltaFrameData.fieldCount; i++) {
  1027. size += UA_calcSizeBinary(&p->data.deltaFrameData.deltaFrameFields[i].fieldIndex, &UA_TYPES[UA_TYPES_UINT16]);
  1028. size += UA_calcSizeBinary(&p->data.deltaFrameData.deltaFrameFields[i].fieldValue.value, &UA_TYPES[UA_TYPES_VARIANT]);
  1029. }
  1030. } else if(p->header.fieldEncoding == UA_FIELDENCODING_RAWDATA) {
  1031. // not implemented
  1032. } else if(p->header.fieldEncoding == UA_FIELDENCODING_DATAVALUE) {
  1033. for (UA_UInt16 i = 0; i < p->data.deltaFrameData.fieldCount; i++) {
  1034. size += UA_calcSizeBinary(&p->data.deltaFrameData.deltaFrameFields[i].fieldIndex, &UA_TYPES[UA_TYPES_UINT16]);
  1035. size += UA_calcSizeBinary(&p->data.deltaFrameData.deltaFrameFields[i].fieldValue, &UA_TYPES[UA_TYPES_DATAVALUE]);
  1036. }
  1037. }
  1038. }
  1039. /* KeepAlive-Message contains no Payload Data */
  1040. return size;
  1041. }
  1042. void UA_DataSetMessage_free(const UA_DataSetMessage* p) {
  1043. if(p->header.dataSetMessageType == UA_DATASETMESSAGE_DATAKEYFRAME) {
  1044. if(p->data.keyFrameData.dataSetFields != NULL)
  1045. UA_Array_delete(p->data.keyFrameData.dataSetFields, p->data.keyFrameData.fieldCount,
  1046. &UA_TYPES[UA_TYPES_DATAVALUE]);
  1047. } else if(p->header.dataSetMessageType == UA_DATASETMESSAGE_DATADELTAFRAME) {
  1048. if(p->data.deltaFrameData.deltaFrameFields != NULL) {
  1049. for(UA_UInt16 i = 0; i < p->data.deltaFrameData.fieldCount; i++) {
  1050. if(p->header.fieldEncoding == UA_FIELDENCODING_DATAVALUE) {
  1051. UA_DataValue_deleteMembers(&p->data.deltaFrameData.deltaFrameFields[i].fieldValue);
  1052. } else if(p->header.fieldEncoding == UA_FIELDENCODING_VARIANT) {
  1053. UA_Variant_deleteMembers(&p->data.deltaFrameData.deltaFrameFields[i].fieldValue.value);
  1054. }
  1055. }
  1056. UA_free(p->data.deltaFrameData.deltaFrameFields);
  1057. }
  1058. }
  1059. }