ua_pubsub_networkmessage.c 59 KB

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