MCPcopy Create free account
hub / github.com/UtilitechAS/amsreader-firmware / parse

Method parse

lib/AmsDecoder/src/MbusParser.cpp:9–78  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

7#include "MbusParser.h"
8
9int8_t MBUSParser::parse(uint8_t *d, DataParserContext &ctx) {
10 int len;
11 int headersize = 3;
12 int footersize = 1;
13
14 uint8_t* ptr;
15
16 // https://m-bus.com/documentation-wired/06-application-layer
17 if(ctx.length < 4)
18 return DATA_PARSE_INCOMPLETE;
19
20 MbusHeader* mh = (MbusHeader*) d;
21 if(mh->flag1 != MBUS_START || mh->flag2 != MBUS_START)
22 return DATA_PARSE_BOUNDARY_FLAG_MISSING;
23
24 // First two bytes is 1-byte length value repeated. Only used for last segment
25 if(mh->len1 != mh->len2)
26 return MBUS_FRAME_LENGTH_NOT_EQUAL;
27 len = mh->len1;
28 ptr = (uint8_t*) &mh[1];
29 headersize = 4;
30 footersize = 2;
31
32 if(len == 0x00)
33 len = ctx.length - headersize - footersize;
34 // Payload can max be 255 bytes, so I think the following case is only valid for austrian meters
35 if(len < headersize)
36 len += 256;
37
38 if((headersize + footersize + len) > ctx.length)
39 return DATA_PARSE_INCOMPLETE;
40
41 MbusFooter* mf = (MbusFooter*) (d + len + headersize);
42 if(mf->flag != MBUS_END)
43 return DATA_PARSE_BOUNDARY_FLAG_MISSING;
44 if(checksum(d + headersize, len) != mf->fcs)
45 return DATA_PARSE_FOOTER_CHECKSUM_ERROR;
46
47 ptr += 2; len -= 2;
48
49 // Control information field
50 uint8_t ci = *ptr;
51
52 // Skip CI, STSAP and DTSAP
53 ptr += 3; len -= 3;
54
55 // Bits 7 6 5 4 3 2 1 0
56 // 0 0 0 Finished Sequence number
57 uint8_t sequenceNumber = (ci & 0x0F);
58 if((ci & 0x10) == 0x00) { // Not finished yet
59 if(sequenceNumber == 0) {
60 if(buf == NULL) buf = (uint8_t *)malloc((size_t)1024); // TODO find out from first package ?
61 pos = 0;
62 } else if(buf == NULL || pos + len > 1024 || sequenceNumber != (lastSequenceNumber + 1)) {
63 return DATA_PARSE_FAIL;
64 }
65 memcpy(buf+pos, ptr, len);
66 pos += len;

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected