diff --git a/packet-radio/src/packet.h b/packet-radio/src/packet.h index 7f1bfc6..aedacd0 100644 --- a/packet-radio/src/packet.h +++ b/packet-radio/src/packet.h @@ -1,13 +1,21 @@ +/* +Copyright 2022, Savanni D'Gerinel + +This file is part of Savanni's AVR library. + +This AVR library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +This AVR library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this AVR library. If not, see . +*/ #ifndef __PACKET_H__ #define __PACKET_H__ -#ifdef __AVR__ - -#else #include +#include #include -#endif typedef enum { packet_type_data, diff --git a/packet-radio/src/packet_buffer.c b/packet-radio/src/packet_buffer.c index bee394e..d2d52fd 100644 --- a/packet-radio/src/packet_buffer.c +++ b/packet-radio/src/packet_buffer.c @@ -11,14 +11,13 @@ You should have received a copy of the GNU General Public License along with thi */ #include "radio.h" -#include "packet.h" #include "packet_buffer.h" -#include -#include +// #include +// #include size_t circular_next(size_t current, size_t max); -packet_buffer_t *packet_buffer_new() { +packet_buffer_t *packet_buffer_new(void) { packet_buffer_t *buffer = malloc(sizeof(packet_buffer_t)); packet_buffer_init(buffer); return buffer; diff --git a/packet-radio/src/packet_buffer.h b/packet-radio/src/packet_buffer.h index 4f8542e..40db79d 100644 --- a/packet-radio/src/packet_buffer.h +++ b/packet-radio/src/packet_buffer.h @@ -28,7 +28,7 @@ typedef struct { packet_t buffer[5]; } packet_buffer_t; -packet_buffer_t *packet_buffer_new(); +packet_buffer_t *packet_buffer_new(void); void packet_buffer_init(packet_buffer_t *); packet_t * packet_buffer_enqueue(packet_buffer_t *, packet_buffer_status_e *); diff --git a/packet-radio/src/radio.c b/packet-radio/src/radio.c index b5b3937..b67595d 100644 --- a/packet-radio/src/radio.c +++ b/packet-radio/src/radio.c @@ -1,54 +1,68 @@ +/* +Copyright 2022, Savanni D'Gerinel + +This file is part of Savanni's AVR library. + +This AVR library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +This AVR library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this AVR library. If not, see . +*/ #include "radio.h" #include "packet.h" +#include "packet_buffer.h" #include -#include - -typedef struct { - bool packet_sent; - bool packet_ready; -} flags_t; struct conn_s { uint16_t packet_counter; uint8_t address; - // packet_buffer_t outgoing_packets; - // packet_buffer_t incoming_packets; + packet_buffer_t outgoing; + packet_buffer_t incoming; - // packet_t outgoing_buffer[5]; - // size_t outgoing_bottom; - // size_t outgoing_top; + void (*set_mode)(radio_t *, radio_mode_e, radio_status_e *); + flags_t (*get_flags)(radio_t *, radio_status_e *); + void (*transmit)(radio_t *, packet_t *, radio_status_e *); + void (*receive)(radio_t *, uint8_t data[66], radio_status_e *); - // packet_t incoming_buffer[5]; - // size_t incoming_bottom; - // size_t incoming_top; - - void (*set_mode)(void *, radio_mode_e, radio_status_e *); - flags_t (*get_flags)(void *, radio_status_e *); - void (*transmit)(void *, packet_t *, radio_status_e *); - void (*receive)(void *, uint8_t data[66], radio_status_e *); - - void *radio; + radio_t *radio; }; +conn_t * conn_connect(radio_t *radio) { + conn_t *connection = malloc(sizeof(struct conn_s)); + connection->packet_counter = 0; + connection->address = 0; + + packet_buffer_init(&connection->outgoing); + packet_buffer_init(&connection->incoming); + + connection->set_mode = radio->set_mode; + connection->get_flags = radio->get_flags; + connection->transmit = radio->transmit; + connection->receive = radio->receive; + connection->radio = radio; + + return connection; +} void conn_set_address(conn_t *self, uint8_t addr, radio_status_e *status) { - /* if (!IS_OK(status)) return; self->address = addr; - */ } void conn_set_mode(conn_t *self, radio_mode_e mode, radio_status_e *status) { - /* if (!IS_OK(status)) return; self->set_mode(self->radio, mode, status); - */ +} + +flags_t conn_get_flags(conn_t *self, radio_status_e *status) { + if (!IS_OK(status)) return (flags_t){ .packet_sent = false, .packet_ready = false }; + return self->get_flags(self->radio, status); } void conn_send(conn_t *self, uint8_t dest, msg_t *message, radio_status_e *status) { - /* if (!IS_OK(status)) return; if (message->length > MAX_MESSAGE_LENGTH) { @@ -56,44 +70,63 @@ void conn_send(conn_t *self, uint8_t dest, msg_t *message, radio_status_e *statu return; } - if (self->outgoing_top == self->outgoing_bottom) { + if (packet_buffer_is_full(&self->outgoing)) { *status = outgoing_full; return; } - self->outgoing_buffer[self->outgoing_top].type = data; - self->outgoing_buffer[self->outgoing_top].count = self->packet_counter; - self->outgoing_buffer[self->outgoing_top].sender = self->address; - self->outgoing_buffer[self->outgoing_top].receiver = dest; - self->outgoing_buffer[self->outgoing_top].size = message->length; - memcpy(self->outgoing_buffer[self->outgoing_top].message, message->data, message->length); + packet_buffer_status_e buffer_status = packet_buffer_status_ok; - self->transmit(self->radio, &self->outgoing_buffer[self->outgoing_top], status); - if (IS_OK(status)) self->outgoing_top++; + packet_t *packet = packet_buffer_enqueue(&self->outgoing, &buffer_status); + if (!IS_OK(&buffer_status)) { + switch (buffer_status) { + case packet_buffer_status_full: + *status = outgoing_full; + break; + default: + *status = unhandled_error; + break; + } + return; + } + + packet->type = packet_type_data; + packet->count = self->packet_counter; + packet->sender = self->address; + packet->receiver = dest; + packet->length = message->length; + memcpy(&packet->message, message->data, message->length); + + self->transmit(self->radio, packet, status); + if (!IS_OK(status)) return; return; - */ } received_msg_t * conn_receive(conn_t *self, radio_status_e *status) { - /* if (!IS_OK(status)) return NULL; - if (self->incoming_bottom == self->incoming_top) { + if (packet_buffer_is_empty(&self->incoming)) { + *status = packet_buffer_status_empty; return NULL; } - size_t length = self->incoming_buffer[self->incoming_bottom].size; - received_msg_t *msg = malloc(sizeof(received_msg_t) + length); - msg->sender = self->incoming_buffer[self->incoming_bottom].sender; - msg->message.length = self->incoming_buffer[self->incoming_bottom].size; - memcpy(msg->message.data, self->incoming_buffer[self->incoming_bottom].message, msg->message.length); + packet_buffer_status_e buffer_status = packet_buffer_status_ok; + packet_t *packet = packet_buffer_head(&self->incoming, &buffer_status); + if (!IS_OK(&buffer_status)) { + // *status = + } - self->incoming_bottom++; + received_msg_t *msg = malloc(sizeof(received_msg_t) + packet->length); + msg->sender = packet->sender; + msg->message.length = packet->length; + memcpy(msg->message.data, packet->message, packet->length); + + packet_buffer_dequeue(&self->incoming, &buffer_status); + if (!IS_OK(&buffer_status)) { + } return msg; - */ - return NULL; } void conn_handle_interrupt(conn_t *self) { @@ -117,12 +150,13 @@ void conn_handle_interrupt(conn_t *self) { switch (packet->type) { case packet_type_data: - memcpy(self->incoming_buffer[self->incoming_top], packet, packet->size); - self->incoming_top++; + packet_buffer_status_e status; + packet_t *dest = packet_buffer_enqueue(self->incoming, &status); + memcpy(dest, packet, sizeof(packet_t) + packet->length); break; case packet_type_ack: - uint16_t confirmed = packet->data[0] << 8 + packet->data[1]; - while (self->outgoing_buffer[self->outgoing_bottom]->count < confirmed && !is_empty(self->outgoing_buffer) + // uint16_t confirmed = packet->data[0] << 8 + packet->data[1]; + // while (self->outgoing_buffer[self->outgoing_bottom]->count < confirmed && !is_empty(self->outgoing_buffer) break; case packet_type_retry: break; diff --git a/packet-radio/src/radio.h b/packet-radio/src/radio.h index c1f0731..3ac796b 100644 --- a/packet-radio/src/radio.h +++ b/packet-radio/src/radio.h @@ -14,13 +14,7 @@ You should have received a copy of the GNU General Public License along with thi #define __RADIO_H__ #include - -#ifdef __AVR__ - -#else -#include -#include -#endif +#include "packet.h" #define MAX_MESSAGE_LENGTH 60 #define IS_OK(val) (val == NULL || !*val) @@ -40,6 +34,7 @@ typedef enum { not_found, message_too_long, outgoing_full, + unhandled_error, } radio_status_e; typedef struct conn_s conn_t; @@ -52,8 +47,25 @@ typedef enum { listen } radio_mode_e; +typedef struct { + bool packet_sent; + bool packet_ready; +} flags_t; + +typedef struct radio_s radio_t; + +struct radio_s { + void (*set_mode)(radio_t *, radio_mode_e, radio_status_e *); + flags_t (*get_flags)(radio_t *, radio_status_e *); + void (*transmit)(radio_t *, packet_t *, radio_status_e *); + void (*receive)(radio_t *, uint8_t data[66], radio_status_e *); +}; + +conn_t * conn_connect(radio_t *radio); + void conn_set_address(conn_t *, uint8_t, radio_status_e *); void conn_set_mode(conn_t *, radio_mode_e, radio_status_e *); +flags_t conn_get_flags(conn_t *, radio_status_e *); void conn_send(conn_t *, uint8_t, msg_t *, radio_status_e *); received_msg_t * conn_receive(conn_t *, radio_status_e *); diff --git a/packet-radio/tests/radio.c b/packet-radio/tests/radio.c new file mode 100644 index 0000000..5eed553 --- /dev/null +++ b/packet-radio/tests/radio.c @@ -0,0 +1,46 @@ +/* +Copyright 2022, Savanni D'Gerinel + +This file is part of Savanni's AVR library. + +This AVR library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +This AVR library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this AVR library. If not, see . +*/ + +#include +#include "radio.h" + +/* +typedef struct { + void (*set_mode)(radio_mock_t *, radio_mode_e, radio_status_e *); + flags_t (*get_flags)(radio_mock_t *, radio_status_e *); + radio_mock_t (*transmit)(radio_mock_t *, packet_t *, radio_status_e *); + void (*receive)(radio_mock_t *, uint8_t data[66], radio_status_e *); +} radio_mock_t; +*/ + +void set_mode(radio_t *radio, radio_mode_e mode, radio_status_e *status) { } + +flags_t get_flags(radio_t *radio, radio_status_e *status) { + flags_t flags = { .packet_sent = false, .packet_ready = false }; + return flags; +} + +void transmit(radio_t *radio, packet_t *packet, radio_status_e *status) { } + +void receive(radio_t *radio, uint8_t data[66], radio_status_e *status) { } + +Test(radio, connect) { + radio_t radio = (radio_t){ .set_mode = set_mode, .get_flags = get_flags, .transmit = transmit, .receive = receive }; + conn_t *conn = conn_connect((radio_t *)&radio); + + radio_status_e status = ok; + flags_t flags = conn_get_flags(conn, &status); + cr_assert(IS_OK(&status)); + cr_assert(flags.packet_sent == false); + cr_assert(flags.packet_ready == false); +} +