Skip to content

Instantly share code, notes, and snippets.

@Micrified
Created September 22, 2020 21:46
Show Gist options
  • Save Micrified/8360d29f1b01da5d5ab0fa273642692f to your computer and use it in GitHub Desktop.
Save Micrified/8360d29f1b01da5d5ab0fa273642692f to your computer and use it in GitHub Desktop.
Packet processing
recv_result recv_msg_queue (queue *rqp, msg_type *tp, void *msg_data_p) {
static unsigned char buffer[MSG_MAX_SIZE];
static msg_type t;
static automaton_recv_state state = STATE_RECV_MARKERS;
static int markers = 0;
static off_t offset = 0;
static ssize_t payload_size = 0;
int exists_pending_data = 0, msg_is_valid;
unsigned char c;
// Check the queue for bytes to process (disable interrupts)
// __disable_irq();
if (rqp->count > 0) {
exists_pending_data = 1;
c = dequeue(rqp);
}
// __enable_irq();
// If there is nothing to process, return immediately
if (exists_pending_data == 0) {
return RECV_NOTHING;
}
// Otherwise, process the symbol in the automaton
switch (state) {
// Processes message markers [0xFF,0xFF]
case STATE_RECV_MARKERS: {
if (c == MSG_MARKER_BYTE) {
markers++;
} else {
markers = 0;
}
if (markers == 2) {
markers = 0;
buffer[0] = buffer[1] = MSG_MARKER_BYTE;
offset = 2;
state = STATE_RECV_TYPE;
}
}
return RECV_NOTHING;
// Processes the message type
case STATE_RECV_TYPE: {
if (msg_type_valid((msg_type)c)) {
t = buffer[offset++] = (msg_type)c;
payload_size = table_msg_payload_size[t];
state = STATE_RECV_PAYLOAD;
} else {
ERR_MSG("Received an invalid message state");
break;
}
}
return RECV_NOTHING;
// Processes the message payload
case STATE_RECV_PAYLOAD: {
if (payload_size > 1) {
buffer[offset++] = c;
payload_size--;
} else {
buffer[offset++] = c;
payload_size = 0;
state = STATE_RECV_CRC;
}
}
return RECV_NOTHING;
// Processes the CRC (reuses markers variable)
case STATE_RECV_CRC: {
if (markers == 1) {
buffer[offset++] = c;
markers = 0;
msg_is_valid = validate_buffer_crc(offset, buffer);
offset = 0;
state = STATE_RECV_MARKERS;
if (msg_is_valid == 1) {
*tp = t;
unpack_msg(t, msg_data_p, buffer + 3);
return RECV_MESSAGE;
}
break;
} else {
buffer[offset++] = c;
markers++;
}
}
return RECV_NOTHING;
default:
ERR_MSG("Unreachable code reached (god help us all)");
break;
}
// Resets the machine. Should be executed on encountering anomalies
state = STATE_RECV_MARKERS;
markers = offset = payload_size = 0;
return RECV_ERROR;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment