RIT VEXU Core API
Loading...
Searching...
No Matches
protocol.hpp
1#pragma once
2#include "core/device/vdb/crc32.hpp"
3#include <array>
4#include <cstdio>
5#include <cstring>
6#include <deque>
7#include <functional>
8#include <memory>
9#include <sstream>
10#include <string>
11#include <vector>
12
13namespace VDB {
14uint32_t time_ms();
15void delay_ms(uint32_t ms);
16} // namespace VDB
17
18// #define VDPTRACE
19#define VDPDEBUG
20#define VDPWARN
21
22#ifdef VDPWARN
23#define VDPWarnf(fmt, ...) printf("WARN: " fmt "\n", ##__VA_ARGS__)
24#else
25#define VDPWarnf(...)
26#endif
27
28#ifdef VDPDEBUG
29#define VDPDebugf(fmt, ...) printf("DEBUG: " fmt "\n", ##__VA_ARGS__)
30#else
31#define VDPDebugf(...)
32#endif
33
34#ifdef VDPTRACE
35#define VDPTracef(fmt, ...) printf("TRACE: " fmt "\n", ##__VA_ARGS__)
36#else
37#define VDPTracef(...)
38#endif
39
40namespace VDP {
41constexpr size_t MAX_CHANNELS = 256;
42
43class Part;
44// Shared Part Pointer to delete an object that has no pointer pointing to it
45//
46using PartPtr = std::shared_ptr<Part>;
47// Packet of bytes stored in a vector of 8 bit unsigned integers
48using Packet = std::vector<uint8_t>;
49
50// defines a channel id as an 8bit unsigned integer
51using ChannelID = uint8_t;
52class Channel {
53 public:
54 template <typename MutexType> friend class RegistryListener;
55 friend class RegistryController;
60 explicit Channel(PartPtr data) : data(data) {}
61 PartPtr data;
62 /*
63 * @return The Channel ID from 0 - 256
64 */
65 ChannelID getID() const;
66
67 private:
73 Channel(PartPtr data, ChannelID channel_id) : data(data), id(channel_id) {}
74
75 ChannelID id = 0;
76 Packet packet_scratch_space;
77 bool acked = false;
78 // std::vector
79};
80
84void dump_packet_hex(const Packet &pac);
85void dump_packet_8bit(const Packet &pac);
86
90enum class PacketType : uint8_t {
91 Broadcast = 0b00000000,
92 Data = 0b10000000
93};
94enum class PacketFunction : uint8_t {
95 Send = 0b00000000,
96 Acknowledge = 0b00100000,
97 Response = 0b01000000,
98 Request = 0b01100000
99};
106 PacketType type;
107 PacketFunction func;
108};
109enum PacketValidity : uint8_t {
110 Ok,
111 BadChecksum,
112 TooSmall,
113};
114PacketValidity validate_packet(const VDP::Packet &packet);
118enum class Type : uint8_t {
119 Record = 0,
120 String = 1,
121 // Enum
122
123 Double = 3,
124 Float = 4,
125
126 Uint8 = 5,
127 Uint16 = 6,
128 Uint32 = 7,
129 Uint64 = 8,
130
131 Int8 = 9,
132 Int16 = 10,
133 Int32 = 11,
134 Int64 = 12,
135
136};
137
138std::string to_string(Type t);
139
140class PacketReader;
141class PacketWriter;
142class Visitor;
148void add_indents(std::stringstream &ss, size_t indent);
149
154class Part {
155 friend class PacketReader;
156 friend class PacketWriter;
157 friend class Record;
158
159 public:
165 Part(std::string name);
166 /*
167 * Deleter for the Part, used to delete the data once it is no longer needed
168 * i.e after it has been sent to the debug board
169 */
170 virtual ~Part();
174 std::string pretty_print() const;
178 std::string pretty_print_data() const;
179 /*
180 * sets the data the part contains, meant to be overrided
181 */
182 virtual void fetch() = 0;
183
184 virtual void response();
185
186 template<typename T>
187 PartPtr to_PartPtr(){
188 return std::make_shared<T>(this);
189 };
190
191 virtual VDP::PartPtr clone() = 0;
196 virtual void read_data_from_message(PacketReader &reader) = 0;
197
198 std::string get_name() const;
199
200 virtual void Visit(Visitor *) = 0;
201
202 protected:
203 // These are needed to decode correctly but you shouldn't call them directly
208 virtual void write_schema(PacketWriter &sofar) const = 0;
213 virtual void write_message(PacketWriter &sofar) const = 0;
219 virtual void pprint(std::stringstream &ss, size_t indent) const = 0;
225 virtual void pprint_data(std::stringstream &ss, size_t indent) const = 0;
226
227 std::string name;
228};
229/*
230 * Defines a PacketReader, it reads packets
231 */
232class PacketReader {
233 public:
238 PacketReader(Packet pac);
244 PacketReader(Packet pac, size_t start);
248 uint8_t get_byte();
252 Type get_type();
256 std::string get_string();
257
261 template <typename Number> Number get_number() {
262 // ensures that the function is only used on numbers
263 static_assert(
264 std::is_floating_point<Number>::value || std::is_integral<Number>::value,
265 "This function should only be used on numbers"
266 );
267 // checks that the size of the number its trying to read combined with its location
268 // doesnt put it past the packet size
269 if (read_head + sizeof(Number) > pac.size()) {
270 printf(
271 "%s:%d: Reading a number[%d] at position %d would read past "
272 "buffer of "
273 "size %d\n",
274 __FILE__, __LINE__, sizeof(Number), read_head, pac.size()
275 );
276 return 0;
277 }
278 Number value = 0;
279 // copies the the number at the reader head to the Number's stored value and
280 // adds the size of the number to the read head so it moves on to the next set of bits
281 std::memcpy(&value, &pac[read_head], sizeof(Number));
282 read_head += sizeof(Number);
283 return value;
284 }
285
286 private:
287 Packet pac;
288 size_t read_head;
289};
294 public:
299 explicit PacketWriter(Packet &scratch_space);
303 void clear();
307 size_t size();
312 void write_byte(uint8_t b);
317 void write_type(Type t);
322 void write_string(const std::string &str);
327 void write_channel_acknowledge(const Channel &chan);
332 void write_channel_broadcast(const Channel &chan);
337 void write_response(std::deque<Channel> &channels);
342 void write_data_message(const Channel &part);
347 void write_request();
351 const Packet &get_packet() const;
355 template <typename Number> void write_number(const Number &num) {
356 std::array<uint8_t, sizeof(Number)> bytes;
357 std::memcpy(&bytes, &num, sizeof(Number));
358 for (const uint8_t b : bytes) {
359 write_byte(b);
360 }
361 }
362
363 private:
364 Packet &sofar;
365};
366
370 public:
377 virtual bool send_packet(const VDP::Packet &packet) = 0;
383 virtual void register_receive_callback(std::function<void(const VDP::Packet &packet)> callback) = 0;
387 virtual ~AbstractDevice();
388};
389
394PartPtr make_decoder(PacketReader &pac);
399uint8_t make_header_byte(PacketHeader head);
404PacketHeader decode_header_byte(uint8_t hb);
410std::pair<ChannelID, PartPtr> decode_broadcast(const Packet &packet);
411
412std::pair<ChannelID, PartPtr> decode_data(const Packet &packet);
413
414} // namespace VDP
Definition protocol.hpp:369
virtual ~AbstractDevice()
Definition protocol.cpp:331
virtual void register_receive_callback(std::function< void(const VDP::Packet &packet)> callback)=0
virtual bool send_packet(const VDP::Packet &packet)=0
Definition types.hpp:153
Definition protocol.hpp:293
void write_data_message(const Channel &part)
Definition protocol.cpp:272
void write_number(const Number &num)
Definition protocol.hpp:355
const Packet & get_packet() const
Definition protocol.cpp:229
void write_string(const std::string &str)
Definition protocol.cpp:219
PacketWriter(Packet &scratch_space)
Definition protocol.cpp:196
void write_channel_broadcast(const Channel &chan)
Definition protocol.cpp:252
void write_request()
Definition protocol.cpp:294
void write_type(Type t)
Definition protocol.cpp:214
void clear()
Definition protocol.cpp:200
void write_byte(uint8_t b)
Definition protocol.cpp:209
void write_channel_acknowledge(const Channel &chan)
Definition protocol.cpp:235
void write_response(std::deque< Channel > &channels)
Definition protocol.cpp:308
size_t size()
Definition protocol.cpp:204
virtual void pprint_data(std::stringstream &ss, size_t indent) const =0
virtual void write_schema(PacketWriter &sofar) const =0
std::string pretty_print_data() const
Definition protocol.cpp:115
std::string pretty_print() const
Definition protocol.cpp:106
virtual void write_message(PacketWriter &sofar) const =0
virtual void read_data_from_message(PacketReader &reader)=0
virtual void pprint(std::stringstream &ss, size_t indent) const =0
Part(std::string name)
Definition protocol.cpp:92
Definition types.hpp:336
Definition protocol.hpp:13
uint32_t time_ms()
Definition wrapper_device.cpp:16
void delay_ms(uint32_t ms)
Definition wrapper_device.cpp:12
Definition protocol.hpp:105