diff --git a/adsbus/proto.c b/adsbus/proto.c index 73e9281..74305c0 100644 --- a/adsbus/proto.c +++ b/adsbus/proto.c @@ -1,11 +1,83 @@ +#include +#include + #include "buf.h" #include "packet.h" +#include "server.h" +#include "adsb.pb-c.h" #include "proto.h" +#define PROTO_MAGIC "aDsB" + +static void proto_obj_to_buf(Adsb *wrapper, struct buf *buf) { + assert(!buf->length); + assert(adsb__get_packed_size(wrapper) <= BUF_LEN_MAX); + buf->length = adsb__pack(wrapper, (uint8_t *) buf_at(buf, 0)); + assert(buf->length); +} + +static void proto_serialize_packet(struct packet *packet, AdsbPacket *out, size_t len) { + out->source_id = (char *) packet->source_id; + if (packet->mlat_timestamp) { + out->mlat_timestamp = packet->mlat_timestamp; + out->has_mlat_timestamp = true; + } + if (packet->rssi) { + out->rssi = packet->rssi; + out->has_rssi = true; + } + out->payload.data = packet->payload; + out->payload.len = len; +} + +static void proto_serialize_mode_s_short(struct packet *packet, struct buf *buf) { + AdsbPacket packet_out = ADSB_PACKET__INIT; + proto_serialize_packet(packet, &packet_out, 7); + Adsb wrapper = ADSB__INIT; + wrapper.mode_s_short = &packet_out; + proto_obj_to_buf(&wrapper, buf); +} + +static void proto_serialize_mode_s_long(struct packet *packet, struct buf *buf) { + AdsbPacket packet_out = ADSB_PACKET__INIT; + proto_serialize_packet(packet, &packet_out, 14); + Adsb wrapper = ADSB__INIT; + wrapper.mode_s_short = &packet_out; + proto_obj_to_buf(&wrapper, buf); +} + bool proto_parse(struct buf *buf, struct packet *packet, void *state_in) { return false; } void proto_serialize(struct packet *packet, struct buf *buf) { + if (!packet) { + AdsbHeader header = ADSB_HEADER__INIT; + header.magic = PROTO_MAGIC; + header.server_version = server_version; + header.server_id = server_id; + header.mlat_timestamp_mhz = PACKET_MLAT_MHZ; + header.mlat_timestamp_max = PACKET_MLAT_MAX; + header.rssi_max = PACKET_RSSI_MAX; + + Adsb wrapper = ADSB__INIT; + wrapper.header = &header; + + proto_obj_to_buf(&wrapper, buf); + return; + } + + switch (packet->type) { + case PACKET_TYPE_NONE: + break; + + case PACKET_TYPE_MODE_S_SHORT: + proto_serialize_mode_s_short(packet, buf); + break; + + case PACKET_TYPE_MODE_S_LONG: + proto_serialize_mode_s_long(packet, buf); + break; + } } diff --git a/adsbus/send.c b/adsbus/send.c index 34ac7fb..d4ea899 100644 --- a/adsbus/send.c +++ b/adsbus/send.c @@ -11,6 +11,7 @@ #include "buf.h" #include "json.h" #include "peer.h" +#include "proto.h" #include "raw.h" #include "stats.h" #include "uuid.h" @@ -43,6 +44,10 @@ struct serializer { .name = "json", .serialize = json_serialize, }, + { + .name = "proto", + .serialize = proto_serialize, + }, { .name = "raw", .serialize = raw_serialize,