Summary Files Commits Branches @commit @diff @stats
path: root / src / message.cpp
blob: 07695338161e15d261b4ff2631efffd84c02e1f3 (plain) (blame)
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include <cstring>
#include "message.h"

/* Private */

void Message::free() {
	delete[] this->msg;
}

void Message::copyFrom(const Message& other) {
	this->can_id = other.can_id;
	this->size = other.size;
	this->received = other.received;
	this->latest_index = other.latest_index;

	this->msg = new unsigned char[this->size];
	std::memcpy(this->msg, other.msg, this->size);
}

/* Public */

Message::Message(unsigned int can_id, const Frame& first_frame) : can_id(can_id), received(0), latest_index(0) {
	this->size = first_frame.get_size();
	this->msg = new unsigned char[this->size];
	this->receive_frame(first_frame);
}

Message::~Message() {
	this->free();
}

Message::Message(const Message& other) {
	this->copyFrom(other);
}

Message& Message::operator=(const Message& other) {
	if (this != &other) {
		this->free();
		this->copyFrom(other);
	}
	return *this;
}

void Message::receive_frame(const Frame& f) {
	// This logic isn't really necessary, but I like to be thorough
	if ((this->latest_index + 1) % 16 < f.get_index()) {
		throw std::invalid_argument("A consecutive frame was lost!");
	}
	this->latest_index = f.get_index();

	// For CFs we set the data size to 7 (the maximum), however, we may be expecting
	// to receive less data (in the last CF).
	size_t expects = std::min(this->size - this->received, f.get_data_size());

	std::memcpy(this->msg + this->received, f.get_data(), expects);
	this->received += expects;
}

bool Message::expects_more_frames() const {
	return this->received < this->size;
}

std::ostream& operator<<(std::ostream& os, const Message& m) {
	os << std::hex << m.can_id << ":";
	for (int i = 0; i < m.received; ++i) {
		os << " 0x" << (unsigned)m.msg[i];
	}
	if (m.expects_more_frames())
		os << "...";
	return os << std::dec;
}