mirror of
https://github.com/UtilitechAS/amsreader-firmware.git
synced 2026-01-16 00:33:14 +00:00
58 lines
1.4 KiB
C++
58 lines
1.4 KiB
C++
#include "Arduino.h"
|
|
#include "MbusAssembler.h"
|
|
#include "ams/hdlc.h"
|
|
|
|
MbusAssembler::MbusAssembler() {
|
|
buf = (uint8_t *)malloc((size_t)1024); // TODO find out from first package ?
|
|
}
|
|
|
|
uint8_t MbusAssembler::append(const uint8_t* d, int length) {
|
|
MbusHeader* h = (MbusHeader*) d;
|
|
uint8_t* ptr = (uint8_t*) &h[1];
|
|
|
|
uint8_t len = h->len1;
|
|
|
|
uint8_t control = *ptr;
|
|
ptr++; len--;
|
|
|
|
uint8_t address = *ptr;
|
|
ptr++; len--;
|
|
|
|
uint8_t ci = *ptr;
|
|
ptr++; len--;
|
|
|
|
uint8_t stsap = *ptr;
|
|
ptr++; len--;
|
|
|
|
uint8_t dtsap = *ptr;
|
|
ptr++; len--;
|
|
|
|
uint8_t sequenceNumber = ci & 0x0F;
|
|
if(sequenceNumber == 0) {
|
|
memcpy(buf, d, length - 2); // Do not include FCS and MBUS_STOP
|
|
buf[6] = 0x10; // Mark that this is a single, complete frame
|
|
pos = length - 2;
|
|
lastSequenceNumber = 0;
|
|
return 0;
|
|
} else if(pos + len > 1024 || sequenceNumber != (lastSequenceNumber + 1)) { // TODO return error
|
|
pos = 0;
|
|
lastSequenceNumber = -1;
|
|
return -1;
|
|
} else {
|
|
if(len > length) return -1;
|
|
memcpy(buf + pos, ptr, len);
|
|
pos += len;
|
|
lastSequenceNumber = sequenceNumber;
|
|
return 0;
|
|
}
|
|
return -2;
|
|
}
|
|
|
|
uint16_t MbusAssembler::write(const uint8_t* d) {
|
|
buf[1] = buf[2] = 0x00;
|
|
buf[pos++] = mbusChecksum(buf+4, pos-4);
|
|
buf[pos++] = MBUS_END;
|
|
memcpy((uint8_t *) d, buf, pos);
|
|
return pos;
|
|
}
|