Commit db7daa83 authored by Reto Da Forno's avatar Reto Da Forno
Browse files

fix some issues in rx callback with header check and allow reception of...

fix some issues in rx callback with header check and allow reception of timestamp if sync bit not set
parent 068858a7
......@@ -54,14 +54,14 @@ void gloria_run_flood(gloria_flood_t* flood, gloria_flood_cb_t callback)
// initialize flood parameters
current_flood->first_rx_index = (current_flood->ack_mode ? -2 : -1);
current_flood->header.protocol_id = PROTOCOL_ID_GLORIA;
current_flood->header.type = 0;
current_flood->header.type = GLORIA_PKT_TYPE_DATA;
current_flood->header.slot_index = 0;
current_flood->msg_received = current_flood->initiator;
current_flood->last_active_slot = gloria_calculate_last_active_slot(current_flood);
current_flood->rem_retransmissions = current_flood->max_retransmissions;
current_flood->ack_message.protocol_id = PROTOCOL_ID_GLORIA;
current_flood->ack_message.type = 0;
current_flood->ack_message.type = GLORIA_PKT_TYPE_ACK;
current_flood->ack_message.sync = 0;
current_flood->ack_message.dst = 0;
current_flood->ack_counter = 0;
......@@ -69,9 +69,7 @@ void gloria_run_flood(gloria_flood_t* flood, gloria_flood_cb_t callback)
// calculate the message size; always needed for the initiator; other nodes need it for low power listening
current_flood->header_size = (current_flood->ack_mode ? GLORIA_HEADER_LENGTH : GLORIA_HEADER_LENGTH_MIN);
if (current_flood->header.sync) {
current_flood->header_size += GLORIA_TIMESTAMP_LENGTH;
}
uint8_t max_packet_len = current_flood->header_size + current_flood->payload_size + GLORIA_TIMESTAMP_LENGTH;
// calculate the message size for the initiator, initialize markers
if (current_flood->initiator) {
......@@ -82,6 +80,7 @@ void gloria_run_flood(gloria_flood_t* flood, gloria_flood_cb_t callback)
if (current_flood->header.sync) {
uint64_t new_timestamp = current_flood->received_marker / GLORIA_SCHEDULE_GRANULARITY;
memcpy(current_flood->header.timestamp, (uint8_t*)&new_timestamp, GLORIA_TIMESTAMP_LENGTH);
current_flood->header_size += GLORIA_TIMESTAMP_LENGTH;
}
}
else {
......@@ -96,7 +95,7 @@ void gloria_run_flood(gloria_flood_t* flood, gloria_flood_cb_t callback)
slot_time = gloria_calculate_slot_time(current_flood->modulation, current_flood->ack_mode, 1, GLORIA_ACK_LENGTH);
}
else {
slot_time = gloria_calculate_slot_time(current_flood->modulation, current_flood->ack_mode, 0, current_flood->payload_size + current_flood->header_size);
slot_time = gloria_calculate_slot_time(current_flood->modulation, current_flood->ack_mode, 0, current_flood->header_size + current_flood->payload_size);
}
if (slot_time < rx2rx_trans + gloria_calculate_rx_timeout(current_flood)) {
......@@ -126,7 +125,6 @@ void gloria_run_flood(gloria_flood_t* flood, gloria_flood_cb_t callback)
current_flood->crc_timeout = false;
// set radio config
uint8_t max_packet_len = current_flood->payload_size + current_flood->header_size;
radio_set_config(current_flood->modulation, current_flood->band, current_flood->power, max_packet_len);
gloria_process_slot();
......@@ -170,34 +168,42 @@ void gloria_process_slot()
static void gloria_rx_callback(uint8_t* payload, uint8_t size)
{
if (payload == NULL || size == 0) {
gloria_finish_slot();
}
else if (size == GLORIA_ACK_LENGTH) {
gloria_ack_msg_t* ack_message = (gloria_ack_msg_t*) payload;
if (ack_message->dst) {
current_flood->acked = true;
current_flood->ack_message.dst = ack_message->dst;
// prevent ack destination from retransmitting the ack message (ack_mode 2)
// prevent nodes that have not yet sent the message from retransmitting acks (ack mode 1)
if (!current_flood->msg_received || ((current_flood->ack_mode == 2) && ack_message->dst == current_flood->node_id) ||
((current_flood->ack_mode == 1) && (current_flood->header.slot_index - current_flood->first_rx_index == 1))) {
// increase slot index to be consistent with other flood ends
current_flood->header.slot_index++;
// finish flood
flood_callback();
return;
}
if (payload && size > 0) {
switch (((gloria_header_t*)payload)->type) {
case GLORIA_PKT_TYPE_ACK:
{
gloria_ack_msg_t* ack_message = (gloria_ack_msg_t*)payload;
if (ack_message->dst) {
current_flood->acked = true;
current_flood->ack_message.dst = ack_message->dst;
// prevent ack destination from retransmitting the ack message (ack_mode 2)
// prevent nodes that have not yet sent the message from retransmitting acks (ack mode 1)
if (!current_flood->msg_received || ((current_flood->ack_mode == 2) && ack_message->dst == current_flood->node_id) ||
((current_flood->ack_mode == 1) && (current_flood->header.slot_index - current_flood->first_rx_index == 1))) {
// increase slot index to be consistent with other flood ends
current_flood->header.slot_index++;
// finish flood
flood_callback();
return;
}
}
} break;
case GLORIA_PKT_TYPE_DATA:
if (size >= current_flood->header_size) {
gloria_process_rx(payload, size);
}
break;
default:
LOG_WARNING("unknown gloria message type");
break;
}
gloria_finish_slot();
}
else if (size >= current_flood->header_size) {
gloria_process_rx(payload, size);
}
else {
gloria_finish_slot();
}
gloria_finish_slot();
}
......@@ -207,12 +213,16 @@ static void gloria_process_rx(uint8_t* payload, uint8_t size)
if (!current_flood->msg_received) {
// the size of the actual payload is the message size minus the header length and for sync floods minus the timestamp length
// copy the header
memcpy((uint8_t*)&current_flood->header, payload, current_flood->header_size);
// the size of the actual payload is the message size minus the header length
// NOTE: the received payload must not exceed the specified max. payload length on the receiver
current_flood->payload_size = MIN(current_flood->payload_size, size - current_flood->header_size);
current_flood->msg_received = true;
memcpy(current_flood->payload, payload + current_flood->header_size, current_flood->payload_size);
current_flood->header.slot_index = header->slot_index;
//current_flood->header.slot_index = header->slot_index;
gloria_reconstruct_flood_marker(current_flood);
// make sure the timer is only synced if the flood contains a timestamp
......@@ -245,8 +255,6 @@ static void gloria_process_rx(uint8_t* payload, uint8_t size)
current_flood->header.slot_index += current_flood->tx_delay_slots;
}
}
gloria_finish_slot();
}
......
......@@ -32,7 +32,7 @@
#define PROTOCOL_GLORIA_GLORIA_CONSTANTS_H_
#define GLORIA_PHY_MAX_PAYLOAD 255 // max length of the physical layer payload (given by the hardware)
#define GLORIA_HEADER_LENGTH_WITH_TS (4 + GLORIA_TIMESTAMP_LENGTH) // length of the gloria header, with timestamp
#define GLORIA_HEADER_LENGTH_WITH_TS (GLORIA_HEADER_LENGTH + GLORIA_TIMESTAMP_LENGTH) // length of the gloria header, with timestamp
#define GLORIA_HEADER_LENGTH 4 // length of the gloria header
#define GLORIA_HEADER_LENGTH_MIN 2 // length of the gloria header without ACK mode
#define GLORIA_MAX_PAYLOAD_LENGTH (GLORIA_PHY_MAX_PAYLOAD - GLORIA_HEADER_LENGTH_WITH_TS)
......
......@@ -50,7 +50,6 @@ static uint8_t internal_modulation = GLORIA_INTERFACE_MODULATION; // int
static uint8_t internal_band = GLORIA_INTERFACE_RF_BAND; // internal state for the frequency band (can be adapted from the upper layer)
static bool internal_enable_flood_printing = false; // enable printing of finished (i.e. completely received/transmitted) floods
static bool internal_append_timestamp = GLORIA_INTERFACE_APPEND_TIMESTAMP;
static uint64_t tx_start_timestamp = 0; // an optional user-defined TX start marker
/* variables to store gloria_start arguments */
static uint8_t* arg_payload_ptr = NULL; // pointer to payload of currently ongoing flood
......@@ -156,11 +155,8 @@ void gloria_start(bool is_initiator,
if (is_initiator) {
// send flood
// set the TX marker (timestamp when flood shall start) must be set on the initiator
if (tx_start_timestamp && (tx_start_timestamp > hs_timer_get_current_timestamp())) {
// user-defined start time
flood.marker = tx_start_timestamp;
} else {
// set the TX marker (timestamp when flood shall start), must be set on the initiator
if (flood.marker < hs_timer_get_current_timestamp()) {
// use current timestamp
flood.marker = ((hs_timer_get_current_timestamp() + (GLORIA_SCHEDULE_GRANULARITY - 1))) / GLORIA_SCHEDULE_GRANULARITY * GLORIA_SCHEDULE_GRANULARITY;
}
......@@ -414,11 +410,13 @@ void gloria_enable_append_timestamp(bool enable)
}
void gloria_get_received_timestamp(uint8_t* out_timestamp)
bool gloria_get_received_timestamp(uint8_t* out_timestamp)
{
if (out_timestamp) {
if (out_timestamp && flood.header.sync) {
memcpy(out_timestamp, flood.header.timestamp, GLORIA_TIMESTAMP_LENGTH);
return true;
}
return false;
}
......@@ -452,7 +450,7 @@ static void copy_payload(void)
memcpy(arg_payload_ptr, flood.payload, flood.payload_size);
}
else {
LOG_WARNING("Payload length in received message is larger than payload length of Gloria interface (GLORIA_MAX_PAYLOAD_LENGTH)! Payload has been truncated!");
LOG_WARNING("Payload length in received message is larger than payload length of Gloria interface (GLORIA_INTERFACE_MAX_PAYLOAD_LEN)! Payload has been truncated!");
memcpy(arg_payload_ptr, flood.payload, GLORIA_INTERFACE_MAX_PAYLOAD_LEN);
flood.payload_size = GLORIA_INTERFACE_MAX_PAYLOAD_LEN;
}
......
......@@ -127,8 +127,6 @@
* location data provided by the application.
* At a receiver, Glossy writes to the given memory
* location data for the application.
* NOTE: At the receiver, the payload buffer must have a
* size of at least GLORIA_INTERFACE_MAX_PAYLOAD_LEN Bytes.
* \param payload_len Size of the `payload` buffer in bytes. On the receiver
* side, this value limits the max. packet size that will
* be accepted. Note that a payload length of zero is
......@@ -369,8 +367,10 @@ void gloria_enable_append_timestamp(bool enable);
/**
* \brief Returns the last received Gloria timestamp
* \param buffer to hold the timestamp
* \return true if a timestamp has been received during the last
* flood (and copied into `out_timestamp`), false otherwise
*/
void gloria_get_received_timestamp(uint8_t* out_timestamp);
bool gloria_get_received_timestamp(uint8_t* out_timestamp);
/**
......
......@@ -284,18 +284,27 @@ static void gloria_radio_rx_timeout_callback(bool crc_error)
static void gloria_radio_rx_callback(uint8_t* payload, uint16_t size, int16_t rssi, int8_t snr, bool crc_error)
{
// we expect at least GLORIA_HEADER_LENGTH_MIN bytes
if (size < GLORIA_HEADER_LENGTH_MIN) {
gloria_radio_continue_rx();
return;
}
if (crc_error) {
current_flood->crc_error = true;
gloria_radio_continue_rx();
return;
}
// update header size
current_flood->header_size = (current_flood->ack_mode ? GLORIA_HEADER_LENGTH : GLORIA_HEADER_LENGTH_MIN) + ((gloria_header_t*)payload)->sync * GLORIA_TIMESTAMP_LENGTH;
// check packet type and apply user-defined packet filter
else if ((current_flood->header.protocol_id != PROTOCOL_ID_GLORIA) ||
(current_flood->filter_cb && (size > current_flood->header_size) && !current_flood->filter_cb(payload + current_flood->header_size, size - current_flood->header_size))) {
if (!PROTOCOL_CHECK_ID(*payload, GLORIA) ||
(current_flood->filter_cb && (size > current_flood->header_size) && !current_flood->filter_cb(payload + current_flood->header_size, size - current_flood->header_size))) {
gloria_radio_continue_rx();
}
else {
current_flood->rssi = rssi;
current_flood->snr = snr;
current_flood->snr = snr;
rx_callback(payload, size);
}
}
......
......@@ -53,6 +53,12 @@ typedef struct __attribute__((__packed__, __aligned__(1))) {
uint8_t timestamp[GLORIA_TIMESTAMP_LENGTH];
} gloria_header_t;
typedef enum {
GLORIA_PKT_TYPE_DATA = 0,
GLORIA_PKT_TYPE_ACK = 1,
GLORIA_PKT_TYPE_LAST = 7, // 3 bits only, 7 is the last valid value
} gloria_pkt_type_t;
typedef struct {
// parameters to specify before flood start
gloria_flood_cb_t flood_cb; // callback function after flood finished
......
......@@ -182,7 +182,7 @@ void radio_set_config_tx(uint8_t modulation_index,
int8_t power,
int32_t bandwidth, // DSB
int32_t datarate,
int32_t preamble_length,
int32_t preamble_len,
bool implicit,
bool crc)
{
......@@ -190,8 +190,8 @@ void radio_set_config_tx(uint8_t modulation_index,
current_modulation = modulation_index;
if (preamble_length == -1) {
preamble_length = radio_modulations[current_modulation].preambleLen;
if (preamble_len == -1) {
preamble_len = radio_modulations[current_modulation].preambleLen;
}
// Do not allow for illegal power level
......@@ -221,7 +221,7 @@ void radio_set_config_tx(uint8_t modulation_index,
(radio_modulations[current_modulation].modem == MODEM_LORA) ? bandwidth : 0,
datarate,
(radio_modulations[current_modulation].modem == MODEM_LORA) ? radio_modulations[current_modulation].coderate : 0,
preamble_length,
preamble_len,
implicit,
crc,
false, // FHSS
......@@ -236,7 +236,7 @@ void radio_set_config_rx(uint8_t modulation_index,
uint8_t band_index,
int32_t bandwidth, // DSB
int32_t datarate,
int32_t preamble_length,
int32_t preamble_len,
uint16_t timeout,
bool implicit,
uint8_t implicit_len,
......@@ -247,8 +247,8 @@ void radio_set_config_rx(uint8_t modulation_index,
current_modulation = modulation_index;
if (preamble_length == -1) {
preamble_length = radio_modulations[current_modulation].preambleLen;
if (preamble_len == -1) {
preamble_len = radio_modulations[current_modulation].preambleLen;
}
if (bandwidth == -1) {
bandwidth = radio_modulations[current_modulation].bandwidth;
......@@ -268,7 +268,7 @@ void radio_set_config_rx(uint8_t modulation_index,
datarate,
(radio_modulations[current_modulation].modem == MODEM_LORA) ? radio_modulations[current_modulation].coderate : 0,
0, // AFC Bandwidth (FSK only)
preamble_length,
preamble_len,
timeout,
implicit,
(implicit ? implicit_len : RADIO_MAX_PAYLOAD_SIZE),
......@@ -339,7 +339,7 @@ void radio_set_config_rxtx(bool lora_mode,
int32_t datarate,
int8_t power,
int32_t bandwidth, // DSB
int32_t preamble_length,
int32_t preamble_len,
uint8_t coderate,
uint16_t timeout,
bool implicit,
......@@ -367,7 +367,7 @@ void radio_set_config_rxtx(bool lora_mode,
(lora_mode) ? bandwidth : 0, // bandwidth (LoRa only)
datarate, // datarate (FSK: bits/s, LoRa: spreading-factor)
(lora_mode) ? coderate : 0, // coderate (LoRa only)
preamble_length, // preamble length (FSK: num bytes, LoRa: symbols (HW adds 4 symbols))
preamble_len, // preamble length (FSK: num bytes, LoRa: symbols (HW adds 4 symbols))
implicit, // fixed length packets [0: variable, 1: fixed]
crc, // CRC on
false, // FHSS
......@@ -382,7 +382,7 @@ void radio_set_config_rxtx(bool lora_mode,
datarate, // datarate (FSK: bits/s, LoRa: spreading-factor)
(lora_mode) ? coderate : 0, // coderate (LoRa only)
0, // AFC Bandwidth (FSK only, not used with SX126x!)
preamble_length, // preamble length (FSK: num bytes, LoRa: symbols (HW adds 4 symbols))
preamble_len, // preamble length (FSK: num bytes, LoRa: symbols (HW adds 4 symbols))
timeout, // RxSingle timeout value
implicit, // fixed length packets [0: variable, 1: fixed]
(implicit ? implicit_len : RADIO_MAX_PAYLOAD_SIZE), // no fixed payload length (as it is explicit header mode / variable packet length)
......
......@@ -40,10 +40,10 @@ void radio_set_config_rx(uint8_t modulation_index,
uint8_t band_index,
int32_t bandwidth,
int32_t datarate,
int32_t preamble_length,
int32_t preamble_len,
uint16_t timeout,
bool implicit,
uint8_t payload_len,
uint8_t implicit_len,
bool crc,
bool stop_rx_on_preamble);
void radio_set_config_tx(uint8_t modulation_index,
......@@ -51,7 +51,7 @@ void radio_set_config_tx(uint8_t modulation_index,
int8_t power,
int32_t bandwidth,
int32_t datarate,
int32_t preamble_length,
int32_t preamble_len,
bool implicit,
bool crc);
void radio_set_config_rxtx(bool lora_mode,
......@@ -59,11 +59,11 @@ void radio_set_config_rxtx(bool lora_mode,
int32_t datarate,
int8_t power,
int32_t bandwidth,
int32_t preamble_length,
int32_t preamble_len,
uint8_t coderate,
uint16_t timeout,
bool implicit,
uint8_t payload_len,
uint8_t implicit_len,
bool crc);
void radio_set_config(uint8_t modulation_index,
uint8_t band_index,
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment