Loading...
Searching...
No Matches
expansion_protocol.h
Go to the documentation of this file.
1
12#pragma once
13
14#include <stddef.h>
15#include <stdint.h>
16#include <stdbool.h>
17
18#ifdef __cplusplus
19extern "C" {
20#endif
21
25#define EXPANSION_PROTOCOL_DEFAULT_BAUD_RATE (9600UL)
26
30#define EXPANSION_PROTOCOL_MAX_DATA_SIZE (64U)
31
35#define EXPANSION_PROTOCOL_TIMEOUT_MS (250U)
36
40#define EXPANSION_PROTOCOL_BAUD_CHANGE_DT_MS (25U)
41
53
62
90
91#pragma pack(push, 1)
92
96typedef struct {
97 uint8_t type;
99
103typedef struct {
106
110typedef struct {
111 uint8_t error;
113
117typedef struct {
118 uint32_t baud;
120
124typedef struct {
125 uint8_t command;
127
131typedef struct {
133 uint8_t size;
137
151
152#pragma pack(pop)
153
158
169typedef size_t (*ExpansionFrameReceiveCallback)(uint8_t* data, size_t data_size, void* context);
170
181typedef size_t (*ExpansionFrameSendCallback)(const uint8_t* data, size_t data_size, void* context);
182
191static inline size_t expansion_frame_get_encoded_size(const ExpansionFrame* frame) {
192 switch(frame->header.type) {
194 return sizeof(frame->header);
196 return sizeof(frame->header) + sizeof(frame->content.status);
198 return sizeof(frame->header) + sizeof(frame->content.baud_rate);
200 return sizeof(frame->header) + sizeof(frame->content.control);
202 return sizeof(frame->header) + sizeof(frame->content.data.size) + frame->content.data.size;
203 default:
204 return 0;
205 }
206}
207
219static inline bool expansion_frame_get_remaining_size(
220 const ExpansionFrame* frame,
221 size_t received_size,
222 size_t* remaining_size) {
223 if(received_size < sizeof(ExpansionFrameHeader)) {
224 // Frame type is unknown as of now
225 *remaining_size = sizeof(ExpansionFrameHeader);
226 return true;
227 }
228
229 const size_t received_content_size = received_size - sizeof(ExpansionFrameHeader);
230 size_t content_size;
231
232 switch(frame->header.type) {
234 content_size = 0;
235 break;
237 content_size = sizeof(frame->content.status);
238 break;
240 content_size = sizeof(frame->content.baud_rate);
241 break;
243 content_size = sizeof(frame->content.control);
244 break;
246 if(received_content_size < sizeof(frame->content.data.size)) {
247 // Data size is unknown as of now
248 content_size = sizeof(frame->content.data.size);
249 } else if(frame->content.data.size > sizeof(frame->content.data.bytes)) {
250 // Malformed frame or garbage input
251 return false;
252 } else {
253 content_size = sizeof(frame->content.data.size) + frame->content.data.size;
254 }
255 break;
256 default:
257 return false;
258 }
259
260 if(content_size > received_content_size) {
261 *remaining_size = content_size - received_content_size;
262 } else {
263 *remaining_size = 0;
264 }
265
266 return true;
267}
268
278
288static inline ExpansionFrameChecksum
289 expansion_protocol_get_checksum(const uint8_t* data, size_t data_size) {
290 ExpansionFrameChecksum checksum = 0;
291 for(size_t i = 0; i < data_size; ++i) {
292 checksum ^= data[i];
293 }
294 return checksum;
295}
296
307static inline ExpansionProtocolStatus expansion_protocol_decode(
308 ExpansionFrame* frame,
310 void* context) {
311 size_t total_size = 0;
312 size_t remaining_size;
313
314 while(true) {
315 if(!expansion_frame_get_remaining_size(frame, total_size, &remaining_size)) {
317 } else if(remaining_size == 0) {
318 break;
319 }
320
321 const size_t received_size =
322 receive((uint8_t*)frame + total_size, remaining_size, context);
323
324 if(received_size == 0) {
326 }
327
328 total_size += received_size;
329 }
330
331 ExpansionFrameChecksum checksum;
332 const size_t received_size = receive(&checksum, sizeof(checksum), context);
333
334 if(received_size != sizeof(checksum)) {
336 } else if(checksum != expansion_protocol_get_checksum((const uint8_t*)frame, total_size)) {
338 } else {
340 }
341}
342
351static inline ExpansionProtocolStatus expansion_protocol_encode(
352 const ExpansionFrame* frame,
354 void* context) {
355 const size_t encoded_size = expansion_frame_get_encoded_size(frame);
356 if(encoded_size == 0) {
358 }
359
360 const ExpansionFrameChecksum checksum =
361 expansion_protocol_get_checksum((const uint8_t*)frame, encoded_size);
362
363 if((send((const uint8_t*)frame, encoded_size, context) != encoded_size) ||
364 (send(&checksum, sizeof(checksum), context) != sizeof(checksum))) {
366 } else {
368 }
369}
370
371#ifdef __cplusplus
372}
373#endif
ExpansionFrameControlCommand
Enumeration of suported control commands.
Definition expansion_protocol.h:66
@ ExpansionFrameControlCommandStartRpc
Start an RPC session.
Definition expansion_protocol.h:71
@ ExpansionFrameControlCommandEnableOtg
Enable OTG (5V) on external GPIO.
Definition expansion_protocol.h:82
@ ExpansionFrameControlCommandStopRpc
Stop an open RPC session.
Definition expansion_protocol.h:76
@ ExpansionFrameControlCommandDisableOtg
Disable OTG (5V) on external GPIO.
Definition expansion_protocol.h:88
ExpansionProtocolStatus
Enumeration of protocol parser statuses.
Definition expansion_protocol.h:272
@ ExpansionProtocolStatusErrorFormat
Invalid frame type.
Definition expansion_protocol.h:274
@ ExpansionProtocolStatusOk
No error has occurred.
Definition expansion_protocol.h:273
@ ExpansionProtocolStatusErrorChecksum
Checksum mismatch.
Definition expansion_protocol.h:275
@ ExpansionProtocolStatusErrorCommunication
Input/output error.
Definition expansion_protocol.h:276
ExpansionFrameError
Enumeration of possible error types.
Definition expansion_protocol.h:57
@ ExpansionFrameErrorNone
No error occurred.
Definition expansion_protocol.h:58
@ ExpansionFrameErrorUnknown
An unknown error has occurred (generic response).
Definition expansion_protocol.h:59
@ ExpansionFrameErrorBaudRate
Requested baud rate is not supported.
Definition expansion_protocol.h:60
ExpansionFrameType
Enumeration of supported frame types.
Definition expansion_protocol.h:45
@ ExpansionFrameTypeData
Data frame.
Definition expansion_protocol.h:50
@ ExpansionFrameTypeHeartbeat
Heartbeat frame.
Definition expansion_protocol.h:46
@ ExpansionFrameTypeReserved
Special value.
Definition expansion_protocol.h:51
@ ExpansionFrameTypeControl
Control frame.
Definition expansion_protocol.h:49
@ ExpansionFrameTypeStatus
Status report frame.
Definition expansion_protocol.h:47
@ ExpansionFrameTypeBaudRate
Baud rate negotiation frame.
Definition expansion_protocol.h:48
#define EXPANSION_PROTOCOL_MAX_DATA_SIZE
Maximum data size per frame, in bytes.
Definition expansion_protocol.h:30
size_t(* ExpansionFrameReceiveCallback)(uint8_t *data, size_t data_size, void *context)
Receive function type declaration.
Definition expansion_protocol.h:169
size_t(* ExpansionFrameSendCallback)(const uint8_t *data, size_t data_size, void *context)
Send function type declaration.
Definition expansion_protocol.h:181
uint8_t ExpansionFrameChecksum
Expansion checksum type.
Definition expansion_protocol.h:157
Baud rate frame contents.
Definition expansion_protocol.h:117
uint32_t baud
Requested baud rate.
Definition expansion_protocol.h:118
Control frame contents.
Definition expansion_protocol.h:124
uint8_t command
Control command number.
Definition expansion_protocol.h:125
Data frame contents.
Definition expansion_protocol.h:131
uint8_t bytes[EXPANSION_PROTOCOL_MAX_DATA_SIZE]
Data bytes.
Definition expansion_protocol.h:135
uint8_t size
Size of the data.
Definition expansion_protocol.h:133
Frame header structure.
Definition expansion_protocol.h:96
uint8_t type
Type of the frame.
Definition expansion_protocol.h:97
Heartbeat frame contents.
Definition expansion_protocol.h:103
Expansion protocol frame structure.
Definition expansion_protocol.h:141
ExpansionFrameStatus status
Status frame contents.
Definition expansion_protocol.h:145
ExpansionFrameData data
Data frame contents.
Definition expansion_protocol.h:148
ExpansionFrameHeader header
Header of the frame.
Definition expansion_protocol.h:142
ExpansionFrameBaudRate baud_rate
Baud rate frame contents.
Definition expansion_protocol.h:146
union ExpansionFrame::@4 content
Contents of the frame.
ExpansionFrameHeartbeat heartbeat
Heartbeat frame contents.
Definition expansion_protocol.h:144
ExpansionFrameControl control
Control frame contents.
Definition expansion_protocol.h:147
Status frame contents.
Definition expansion_protocol.h:110
uint8_t error
Reported error code.
Definition expansion_protocol.h:111