-
Notifications
You must be signed in to change notification settings - Fork 1
/
packet.cpp
47 lines (40 loc) · 1.26 KB
/
packet.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include "packet.h"
static uint16_t checksum(void *buf, int len) {
uint32_t sum = 0;
const uint16_t *p = reinterpret_cast<uint16_t *>(buf);
for (int i = 0; i < len / 2; i++) {
sum += p[i];
if (sum & 0xFFFF0000) {
sum &= 0xFFFF;
sum++;
}
}
return ~(sum & 0xFFFF);
}
bool PacketHelper::isValidPacket(const std::unique_ptr<Packet> &packet) {
return checksum(packet.get(), ROUND_UP(packet->len, sizeof(uint16_t))) == 0;
}
std::unique_ptr<Packet> PacketHelper::makePacket(
PacketType type,
uint32_t num,
const void *data,
uint32_t len
) {
// do round up, so we can calculate checksum
int alignedPacketSize = ROUND_UP(sizeof(Packet) + len, sizeof(uint16_t));
// allocate memory and clear it to all 0
auto packet = reinterpret_cast<Packet *>(new uint8_t[alignedPacketSize]{});
// fill packet
packet->type = type;
packet->num = num;
packet->len = sizeof(Packet) + len;
if (type == PacketType::DATA) {
memcpy(packet->data, data, len);
}
// calc checksum
// first set checksum to 0
packet->checksum = 0;
// calculate it now
packet->checksum = checksum(packet, alignedPacketSize);
return std::unique_ptr<Packet>(packet);
}