2016-02-17 12:11:50 -08:00
|
|
|
#include <assert.h>
|
|
|
|
|
|
2016-02-22 16:41:34 -08:00
|
|
|
#include "buf.h"
|
2016-02-22 16:36:27 -08:00
|
|
|
#include "hex.h"
|
2016-02-22 16:58:13 -08:00
|
|
|
#include "packet.h"
|
2016-02-22 16:36:27 -08:00
|
|
|
|
2016-02-17 12:11:50 -08:00
|
|
|
#include "raw.h"
|
|
|
|
|
|
2016-02-27 21:50:15 -08:00
|
|
|
struct __attribute__((packed)) raw_overlay {
|
2016-02-17 12:11:50 -08:00
|
|
|
char semicolon;
|
2016-02-18 17:06:20 -08:00
|
|
|
char cr_lf;
|
2016-02-17 12:11:50 -08:00
|
|
|
char lf;
|
|
|
|
|
};
|
|
|
|
|
|
2016-02-27 21:50:15 -08:00
|
|
|
static bool raw_parse_packet(struct buf *buf, struct packet *packet, enum packet_type type) {
|
|
|
|
|
size_t payload_bytes = packet_payload_len[type];
|
2016-02-27 22:21:09 -08:00
|
|
|
size_t overlay_start = 1 + (payload_bytes * 2);
|
2016-02-27 21:50:15 -08:00
|
|
|
struct raw_overlay *overlay = (struct raw_overlay *) buf_at(buf, overlay_start);
|
|
|
|
|
size_t total_len = overlay_start + sizeof(*overlay);
|
2016-02-17 12:11:50 -08:00
|
|
|
|
2016-02-27 22:53:57 -08:00
|
|
|
if (((buf->length < total_len - 1 || overlay->cr_lf != '\n') &&
|
|
|
|
|
(buf->length < total_len || overlay->cr_lf != '\r' || overlay->lf != '\n')) ||
|
2016-02-27 21:50:15 -08:00
|
|
|
buf_chr(buf, 0) != '*' ||
|
2016-02-26 14:18:28 -08:00
|
|
|
overlay->semicolon != ';') {
|
2016-02-17 12:11:50 -08:00
|
|
|
return false;
|
|
|
|
|
}
|
2016-02-27 21:50:15 -08:00
|
|
|
if (!hex_to_bin(packet->payload, buf_at(buf, 1), payload_bytes)) {
|
2016-02-26 14:09:37 -08:00
|
|
|
return false;
|
|
|
|
|
}
|
2016-02-27 21:50:15 -08:00
|
|
|
packet->type = type;
|
|
|
|
|
buf_consume(buf, overlay->cr_lf == '\r' ? total_len : total_len - 1);
|
2016-02-17 12:11:50 -08:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2016-02-17 16:40:09 -08:00
|
|
|
void raw_init() {
|
2016-02-27 21:50:15 -08:00
|
|
|
assert(1 + PACKET_PAYLOAD_LEN_MAX + sizeof(struct raw_overlay) < BUF_LEN_MAX);
|
2016-02-17 16:40:09 -08:00
|
|
|
}
|
2016-02-17 12:11:50 -08:00
|
|
|
|
2016-02-25 23:37:37 -08:00
|
|
|
bool raw_parse(struct buf *buf, struct packet *packet, void __attribute__((unused)) *state_in) {
|
2016-02-17 12:11:50 -08:00
|
|
|
return (
|
2016-02-27 21:50:15 -08:00
|
|
|
raw_parse_packet(buf, packet, PACKET_TYPE_MODE_AC) ||
|
|
|
|
|
raw_parse_packet(buf, packet, PACKET_TYPE_MODE_S_SHORT) ||
|
|
|
|
|
raw_parse_packet(buf, packet, PACKET_TYPE_MODE_S_LONG));
|
2016-02-17 12:11:50 -08:00
|
|
|
}
|
2016-02-17 20:14:44 -08:00
|
|
|
|
|
|
|
|
void raw_serialize(struct packet *packet, struct buf *buf) {
|
2016-02-27 21:50:15 -08:00
|
|
|
size_t payload_bytes = packet_payload_len[packet->type];
|
2016-02-27 22:19:02 -08:00
|
|
|
size_t overlay_start = 1 + (payload_bytes * 2);
|
|
|
|
|
struct raw_overlay *overlay = (struct raw_overlay *) buf_at(buf, overlay_start);
|
|
|
|
|
size_t total_len = overlay_start + sizeof(*overlay);
|
2016-02-27 21:50:15 -08:00
|
|
|
buf_chr(buf, 0) = '*';
|
|
|
|
|
overlay->semicolon = ';';
|
2016-02-27 22:19:02 -08:00
|
|
|
overlay->cr_lf = '\n';
|
2016-02-27 21:50:15 -08:00
|
|
|
hex_from_bin_upper(buf_at(buf, 1), packet->payload, payload_bytes);
|
2016-02-27 22:19:02 -08:00
|
|
|
buf->length = total_len - 1;
|
2016-02-17 20:14:44 -08:00
|
|
|
}
|