From c57fbd53e7a2ce135ab45dd5b9f219cb0a07cd04 Mon Sep 17 00:00:00 2001 From: Justin Chow Date: Fri, 11 Jul 2025 12:39:35 -0400 Subject: [PATCH] link layer routing works --- components/dataLink/DataLinkManager.cpp | 219 +++++++++++++++--- components/dataLink/include/DataLinkManager.h | 9 +- components/dataLink/include/Frames.h | 2 +- components/dataLink/include/Tables.h | 18 +- components/rmt/RMTManager.cpp | 1 - main/link_layer_main.cpp | 103 +++++--- 6 files changed, 279 insertions(+), 73 deletions(-) diff --git a/components/dataLink/DataLinkManager.cpp b/components/dataLink/DataLinkManager.cpp index 76f0ea7..77751b9 100644 --- a/components/dataLink/DataLinkManager.cpp +++ b/components/dataLink/DataLinkManager.cpp @@ -103,7 +103,7 @@ esp_err_t DataLinkManager::get_board_id(uint8_t& board_id){ * @param type * @return esp_err_t */ -esp_err_t DataLinkManager::send(uint8_t dest_board, uint8_t* data, uint16_t data_len, FrameType type, uint8_t curr_channel){ +esp_err_t DataLinkManager::send(uint8_t dest_board, uint8_t* data, uint16_t data_len, FrameType type, uint8_t flag){ if (phys_comms == nullptr){ ESP_LOGE(DEBUG_LINK_TAG, "Failed to send frame due to no RMT object"); return ESP_FAIL; @@ -118,10 +118,6 @@ esp_err_t DataLinkManager::send(uint8_t dest_board, uint8_t* data, uint16_t data ESP_LOGE(DEBUG_LINK_TAG, "This board is not assigned a board id"); return ESP_FAIL; } - - if (curr_channel >= num_channels){ - return ESP_FAIL; - } esp_err_t res; @@ -137,11 +133,12 @@ esp_err_t DataLinkManager::send(uint8_t dest_board, uint8_t* data, uint16_t data .sender_id = this_board_id, .receiver_id = dest_board, .seq_num = sequence_num_map[dest_board]++, - .type_flag = static_cast(type), + .type_flag = (uint8_t)((static_cast(type) & 0xF0) | (flag & 0xF)), .data_len = static_cast(data_len), .crc_16 = 0, //not made yet }; + ESP_LOGI(DEBUG_LINK_TAG, "type flag %X\n", new_frame.type_flag); // printf("size of control frame %d\n", sizeof(control_frame)); // printf("size of message %d\n", new_frame.data_len); // printf("message %s\n", data); @@ -184,7 +181,10 @@ esp_err_t DataLinkManager::send(uint8_t dest_board, uint8_t* data, uint16_t data uint8_t channel_to_route = MAX_CHANNELS; if (new_frame.receiver_id == BROADCAST_ADDR){ - channel_to_route = curr_channel; + for (uint8_t i = 0; i < num_channels; i++){ + phys_comms->send(send_data, offset, &config, i); + } + } else { res = route_frame(new_frame.receiver_id, &channel_to_route); @@ -192,8 +192,8 @@ esp_err_t DataLinkManager::send(uint8_t dest_board, uint8_t* data, uint16_t data ESP_LOGE(DEBUG_LINK_TAG, "Failed to find entry for %d", new_frame.receiver_id); return ESP_FAIL; } + phys_comms->send(send_data, offset, &config, channel_to_route); } - phys_comms->send(send_data, offset, &config, channel_to_route); //can wait for the rmt to finish // esp_err_t res = phys_comms->wait_until_send_complete(curr_channel); //this cannot be here in deployment but until the RMT manager can hold this copy of data this will have to be here @@ -280,35 +280,34 @@ esp_err_t DataLinkManager::receive(uint8_t* data, size_t data_len, size_t* recv_ frame_header header; res = get_data_from_frame(data, *recv_len, message, &message_size, &header); if (res != ESP_OK){ + vPortFree((void*)message); return ESP_FAIL; } - ESP_LOGI(DEBUG_LINK_TAG, "Received frame destined for board %d", header.receiver_id); + // ESP_LOGI(DEBUG_LINK_TAG, "Received frame of type 0x%X destined for board %d", GET_TYPE(header.type_flag), header.receiver_id); //check for a rip frame - if (static_cast(header.type_flag) == FrameType::RIP_TABLE_CONTROL){ + if (static_cast(GET_TYPE(header.type_flag)) == FrameType::RIP_TABLE_CONTROL){ printf("Got a RIP frame\n"); - if (res != ESP_OK){ - return ESP_FAIL; //crc or data len failed - } - for (size_t i = 0; i < message_size-1; i+=2){ uint8_t board_id = message[i]; uint8_t hops = message[i+1]; ESP_LOGI(DEBUG_LINK_TAG, "Received: board_id %d and number of hops %d on channel %d", board_id, hops, curr_channel); - + RIPRow* entry = nullptr; - + res = rip_find_entry(board_id, &entry, true); if (res != ESP_OK){ + vPortFree((void*)message); return ESP_FAIL; } - + if (entry == nullptr){ printf("rip pointer\n"); + vPortFree((void*)message); return ESP_FAIL; //no room for more entries in the table } - + if (entry->valid == RIP_NEW_ROW){ //adding a new entry rip_add_entry(board_id, hops + 1, curr_channel, &entry); @@ -316,18 +315,39 @@ esp_err_t DataLinkManager::receive(uint8_t* data, size_t data_len, size_t* recv_ //updating an entry rip_update_entry(hops + 1, curr_channel, &entry); } + + if (GET_FLAG(header.type_flag) == FLAG_DISCOVERY){ + //discovery -> send routing table + ESP_LOGI(DEBUG_LINK_TAG, "got discovery reply"); + RIPRow_public row_queue = { + .info = entry->info, + .channel = entry->channel + }; + + xQueueSendToBack(discovery_tables, &row_queue, (TickType_t)10); + } + } *recv_len = 0; + if (message_size == RIP_DISCOVERY_MESSAGE_SIZE){ + res = send_rip_frame(false, header.sender_id); + if (res != ESP_OK){ + ESP_LOGE(DEBUG_LINK_TAG, "Failed to send back rip table to board %d", header.sender_id); + return res; + } + } } //got frame but not destined for this board - if (header.receiver_id != this_board_id && header.receiver_id != BROADCAST_ADDR && header.seq_num != sequence_num_map[header.receiver_id]){ + if (header.receiver_id != this_board_id && header.receiver_id != BROADCAST_ADDR && header.seq_num > sequence_num_map[header.receiver_id]){ ESP_LOGI(DEBUG_LINK_TAG, "Sending message to board %d with message %s", header.receiver_id, message); - res = send(header.receiver_id, message, message_size, FrameType::DEBUG_CONTROL_TYPE, curr_channel); + res = send(header.receiver_id, message, message_size, FrameType::DEBUG_CONTROL_TYPE, 0); *recv_len = 0; + vPortFree((void*)message); return res; } + vPortFree((void*)message); return ESP_OK; } @@ -362,6 +382,11 @@ esp_err_t DataLinkManager::get_data_from_frame(uint8_t* data, size_t data_len, u return ESP_FAIL; } + if (header->data_len == 0){ + ESP_LOGE(DEBUG_LINK_TAG, "Data len 0"); + return ESP_FAIL; + } + *message_size = header->data_len; memcpy(message, &data[8], header->data_len); @@ -473,6 +498,8 @@ void DataLinkManager::init_rip(){ // rip_table[2].ttl = RIP_TTL_START, // rip_table[2].valid = 1; + discovery_tables = xQueueCreate(RIP_MAX_ROUTES, sizeof(RIPRow_public)); + start_rip_tasks(); } @@ -493,9 +520,15 @@ esp_err_t DataLinkManager::rip_add_entry(uint8_t board_id, uint8_t hops, uint8_t (*entry)->ttl = RIP_TTL_START; (*entry)->valid = 1; + ESP_LOGI(DEBUG_LINK_TAG, "board_id %d now has hops %d from channel %d", (*entry)->info.board_id, (*entry)->info.hops, channel); - + xSemaphoreGive((*entry)->row_sem); + + if (uxQueueMessagesWaiting(manual_broadcasts) == 0){ + bool dummy = true; + xQueueSend(manual_broadcasts, &dummy, 0); //new row - send broadcast + } return ESP_OK; } @@ -534,6 +567,8 @@ esp_err_t DataLinkManager::rip_update_entry(uint8_t new_hop, uint8_t channel, RI return ESP_FAIL; } + uint8_t old_hops = (*entry)->info.hops; + if ((*entry)->info.hops > new_hop && (*entry)->info.hops != RIP_MAX_HOPS + 1){ //no count to infinity if path is invalid (*entry)->info.hops = new_hop; (*entry)->channel = channel; @@ -546,6 +581,12 @@ esp_err_t DataLinkManager::rip_update_entry(uint8_t new_hop, uint8_t channel, RI xSemaphoreGive((*entry)->row_sem); + if (uxQueueMessagesWaiting(manual_broadcasts) == 0 && old_hops > new_hop && old_hops != RIP_MAX_HOPS + 1){ + //if hops were changed, send broadcast (if there isn't already one manual broadcast request pending) + bool dummy = true; + xQueueSend(manual_broadcasts, &dummy, 0); + } + return ESP_OK; } @@ -598,7 +639,14 @@ esp_err_t DataLinkManager::rip_find_entry(uint8_t board_id, RIPRow** entry, bool return ESP_OK; } -esp_err_t DataLinkManager::broadcast_rip_frame(bool manual_broadcast = false){ +/** + * @brief Sends RIP frame + * + * @param broadcast True - broadcasts (sends rip table to all available channels); False - sends rip table via routing based on `dest_id` + * @param dest_id Destination board (requesting board) to send the rip table to (ignored if `broadcast is true`) + * @return esp_err_t + */ +esp_err_t DataLinkManager::send_rip_frame(bool broadcast, uint8_t dest_id){ //use the control frame for the demo (as the number of rows increase, we will need to use the generic frame) //data will be [board_id (1), hops (1), board_id (2), hops (2), ...] @@ -615,7 +663,7 @@ esp_err_t DataLinkManager::broadcast_rip_frame(bool manual_broadcast = false){ if (rip_table[i].info.hops == RIP_MAX_HOPS + 1){ //invalid hop, decrement counter rip_table[i].ttl_flush--; - if (rip_table[i].ttl_flush == 0 && !manual_broadcast){ + if (rip_table[i].ttl_flush == 0){ rip_table[i].valid = RIP_INVALID_ROW; xSemaphoreGive(rip_table[i].row_sem); continue; @@ -635,12 +683,14 @@ esp_err_t DataLinkManager::broadcast_rip_frame(bool manual_broadcast = false){ } esp_err_t res; - - for (uint8_t channel = 0; channel < num_channels; channel++){ - res = send(BROADCAST_ADDR, rip_message, message_idx, FrameType::RIP_TABLE_CONTROL, channel); - if (res != ESP_OK){ - ESP_LOGE(DEBUG_LINK_TAG, "Failed to send rip frame on channel %d", channel); - } + if (broadcast){ + res = send(BROADCAST_ADDR, rip_message, message_idx, FrameType::RIP_TABLE_CONTROL, 0); + } else { + ESP_LOGI(DEBUG_LINK_TAG, "replying to discovery request to board %d", dest_id); + res = send(dest_id, rip_message, message_idx, FrameType::RIP_TABLE_CONTROL, FLAG_DISCOVERY); + } + if (res != ESP_OK){ + ESP_LOGE(DEBUG_LINK_TAG, "Failed to send rip frame on channel %d", 0); } return ESP_OK; @@ -672,6 +722,106 @@ esp_err_t DataLinkManager::route_frame(uint8_t dest_id, uint8_t* channel_to_send return ESP_OK; } +esp_err_t DataLinkManager::get_routing_table(RIPRow_public* table, size_t* table_size){ + if (table == nullptr){ + ESP_LOGE(DEBUG_LINK_TAG, "Invalid table pointer"); + return ESP_FAIL; + } + + if (table_size == nullptr){ + ESP_LOGE(DEBUG_LINK_TAG, "Invalid table size pointer"); + return ESP_FAIL; + } + + if (*table_size < RIP_MAX_ROUTES){ + ESP_LOGE(DEBUG_LINK_TAG, "Invalid table size (must be greater than %d)", RIP_MAX_ROUTES); + return ESP_FAIL; + } + + size_t curr_size = 0; + + for (size_t i = 0; i < RIP_MAX_ROUTES; i++){ + if (xSemaphoreTake(rip_table[i].row_sem, (TickType_t)RIP_MAX_SEM_WAIT) != pdTRUE){ + return ESP_FAIL; + } + if (rip_table[i].valid == RIP_VALID_ROW){ + table[i].info = rip_table[i].info; + table[i].channel = rip_table[i].channel; + curr_size++; + } + xSemaphoreGive(rip_table[i].row_sem); + } + + *table_size = curr_size; + + return ESP_OK; +} + +/** + * @brief Gets all of the routing tables of each board in the network and returns a routing matrix (entire topology of the network). + * + * RIP table will have an entry that refers to its own board id (and will always have hop value of 0 and a channel value of `MAX_CHANNELS + 1`) + * + * @warning not completely working (unable to get other board's table properly) + * + * @param matrix + * @param matrix_size size in multiples of `sizeof(RIPRow_public)` + * @return esp_err_t + */ +esp_err_t DataLinkManager::get_network_toplogy(RIPRow_public_matrix* matrix, size_t* matrix_size){ + if (matrix == nullptr){ + ESP_LOGE(DEBUG_LINK_TAG, "Invalid matrix pointer"); + return ESP_FAIL; + } + + if (matrix_size == nullptr){ + ESP_LOGE(DEBUG_LINK_TAG, "Invalid matrix size pointer"); + return ESP_FAIL; + } + + if (*matrix_size < RIP_MAX_ROUTES){ + ESP_LOGE(DEBUG_LINK_TAG, "Invalid matrix size (must be greater than %d)", RIP_MAX_ROUTES); + return ESP_FAIL; + } + + size_t curr_size = 0; + matrix[0].board_id = this_board_id; + if (matrix[0].table == nullptr || matrix[0].size < RIP_MAX_ROUTES){ + ESP_LOGE(DEBUG_LINK_TAG, "Invalid table size for index 0"); + return ESP_FAIL; + } + + esp_err_t res; + + res = get_routing_table(matrix[0].table, &matrix[0].size); + if (res != ESP_OK){ + return ESP_FAIL; + } + curr_size++; + + uint8_t message[RIP_DISCOVERY_MESSAGE_SIZE] = {0}; + for (size_t i = 1; i < matrix[0].size; i++){ + ESP_LOGI(DEBUG_LINK_TAG, "Sending discovery request for board %d", matrix[0].table[i].info.board_id); + send(matrix[0].table[i].info.board_id, message, 1, FrameType::RIP_TABLE_CONTROL, FLAG_DISCOVERY); //send a discovery request to a board in this board's table index i + uint8_t table_idx = 0; + RIPRow_public temp; + while (xQueueReceive(discovery_tables, &temp, (TickType_t)1000) == pdTRUE){ //the board should have responded with rows from its routing table to insert into the matrix + ESP_LOGI(DEBUG_LINK_TAG, "putting discovery reply into matrix"); + matrix[i].table[table_idx].info.board_id = temp.info.board_id; + matrix[i].table[table_idx].info.hops = temp.info.hops; + matrix[i].table[table_idx++].channel = temp.channel; + } + matrix[i].size = table_idx; + curr_size++; + + xQueueReset(discovery_tables); //reset the queue + } + + *matrix_size = curr_size; + + return ESP_OK; +} + [[noreturn]] void DataLinkManager::rip_broadcast_timer_function(void* args){ DataLinkManager* link_layer_obj = static_cast(args); if (link_layer_obj == nullptr || link_layer_obj->manual_broadcasts == nullptr){ @@ -686,7 +836,7 @@ esp_err_t DataLinkManager::route_frame(uint8_t dest_id, uint8_t* channel_to_send bool dummy; xQueueReceive(link_layer_obj->manual_broadcasts, &dummy, pdMS_TO_TICKS(RIP_BROADCAST_INTERVAL)); //wait up to RIP_BROADCAST_INTERVAL ms ESP_LOGI(DEBUG_LINK_TAG, "Broadcasting table..."); //debug - res = link_layer_obj->broadcast_rip_frame(true); + res = link_layer_obj->send_rip_frame(true, 0); if (res != ESP_OK){ ESP_LOGE(DEBUG_LINK_TAG, "Failed to broadcast rip frame"); } @@ -701,6 +851,8 @@ esp_err_t DataLinkManager::route_frame(uint8_t dest_id, uint8_t* channel_to_send } ESP_LOGI(DEBUG_LINK_TAG, "Starting RIP ttl decrement task"); bool broadcast = false; + bool dummy = true; + xQueueSend(link_layer_obj->manual_broadcasts, &dummy, 0); while(true){ vTaskDelay(pdMS_TO_TICKS(RIP_MS_TO_SEC)); //run every second for (size_t i = 0; i < RIP_MAX_ROUTES; i++){ @@ -730,7 +882,6 @@ esp_err_t DataLinkManager::route_frame(uint8_t dest_id, uint8_t* channel_to_send if (broadcast && uxQueueMessagesWaiting(link_layer_obj->manual_broadcasts) == 0){ broadcast = false; - bool dummy = true; xQueueSend(link_layer_obj->manual_broadcasts, &dummy, 0); } } @@ -743,10 +894,10 @@ esp_err_t DataLinkManager::route_frame(uint8_t dest_id, uint8_t* channel_to_send * - start a task to periodically decrement the ttl values of each row in the RIP table (WIP) - this will require some sort of mutex on the table itself */ void DataLinkManager::start_rip_tasks(){ - manual_broadcasts = xQueueCreate(1, sizeof(bool)); + manual_broadcasts = xQueueCreate(2, sizeof(bool)); ESP_LOGI(DEBUG_LINK_TAG, "Starting RIP Broadcast task"); - xTaskCreate(DataLinkManager::rip_broadcast_timer_function, "RIPBroadcast", 2048, static_cast(this), 5, NULL); + xTaskCreate(DataLinkManager::rip_broadcast_timer_function, "RIPBroadcast", 4096, static_cast(this), 5, NULL); ESP_LOGI(DEBUG_LINK_TAG, "Starting RIP TTL task"); xTaskCreate(DataLinkManager::rip_ttl_decrement_task, "RIPTTL", 2048, static_cast(this), 5, NULL); -} \ No newline at end of file +} \ No newline at end of file diff --git a/components/dataLink/include/DataLinkManager.h b/components/dataLink/include/DataLinkManager.h index a932992..118da53 100644 --- a/components/dataLink/include/DataLinkManager.h +++ b/components/dataLink/include/DataLinkManager.h @@ -41,11 +41,12 @@ class DataLinkManager{ public: DataLinkManager(uint8_t board_id, uint8_t num_channels); ~DataLinkManager(); - esp_err_t send(uint8_t dest_board, uint8_t* data, uint16_t data_len, FrameType type, uint8_t curr_channel); + esp_err_t send(uint8_t dest_board, uint8_t* data, uint16_t data_len, FrameType type, uint8_t flag); esp_err_t start_receive_frames(uint8_t curr_channel); esp_err_t receive(uint8_t* data, size_t data_len, size_t* recv_len, uint8_t curr_channel); esp_err_t print_frame_info(uint8_t* data, size_t data_len, uint8_t* message); - esp_err_t send_discover_frame(); + esp_err_t get_network_toplogy(RIPRow_public_matrix* matrix, size_t* matrix_size); + esp_err_t get_routing_table(RIPRow_public* table, size_t* table_size); private: uint8_t this_board_id = 0; uint8_t num_channels = MAX_CHANNELS; @@ -80,10 +81,12 @@ class DataLinkManager{ RIPRow rip_table[RIP_MAX_ROUTES]; //temp using a static array void start_rip_tasks(); - esp_err_t broadcast_rip_frame(bool manual_broadcast); + esp_err_t send_rip_frame(bool broadcast, uint8_t dest_id); [[noreturn]] static void rip_broadcast_timer_function(void* args); [[noreturn]] static void rip_ttl_decrement_task(void* args); QueueHandle_t manual_broadcasts; + + QueueHandle_t discovery_tables; esp_err_t route_frame(uint8_t dest_id, uint8_t* channel_to_send); }; diff --git a/components/dataLink/include/Frames.h b/components/dataLink/include/Frames.h index 8ea1f18..163a457 100644 --- a/components/dataLink/include/Frames.h +++ b/components/dataLink/include/Frames.h @@ -20,7 +20,7 @@ #define GET_TYPE(x) ((x) & 0xF0) #define GET_FLAG(x) ((x) & 0x0F) -#define MAKE_TYPE_FLAG(type, flag) ((type) | (flag)) +#define MAKE_TYPE_FLAG(type, flag) ((uint8_t)((type & 0xF0) | (flag & 0xF))) #define IS_CONTROL_FRAME(x) (((x) & 0x80) != 0) #define CONTROL_FRAME_OVERHEAD 9 diff --git a/components/dataLink/include/Tables.h b/components/dataLink/include/Tables.h index 5e531f1..1b31884 100644 --- a/components/dataLink/include/Tables.h +++ b/components/dataLink/include/Tables.h @@ -14,6 +14,7 @@ #define RIP_MAX_SEM_WAIT 30 #define RIP_FLUSH_COUNT 8 //flush after 8*30 seconds = 240 seconds +#define RIP_DISCOVERY_MESSAGE_SIZE 1 /** * @brief Routing data to a board * This struct will be sent to other boards @@ -28,9 +29,24 @@ typedef struct _rip_row{ uint8_t channel; //rmt channel uint8_t ttl; //how long this entry is valid for. starting value is 180 seconds uint8_t valid; //is this a valid entry? - uint8_t ttl_flush; //if hops is invalid, this would count the amount of time until this entry would be invalid (in multiples of 30 seconds) + uint8_t ttl_flush; //if hops is invalid, this would count the amount of time until this entry would be invalid (max is in multiples of 30 seconds) but can vary StaticSemaphore_t mutex_buf; //where mutex state is stored SemaphoreHandle_t row_sem; //mutex sem handle of mutex_buf } RIPRow; +/** + * @brief Public facing RIP table row + * + */ +typedef struct _rip_public_row{ + RIPHop info; + uint8_t channel; //rmt channel +} RIPRow_public; + +typedef struct _rip_public_matrix{ + RIPRow_public* table; + size_t size; + uint8_t board_id; //Board ID's routing table +} RIPRow_public_matrix; + #endif //DATA_LINK diff --git a/components/rmt/RMTManager.cpp b/components/rmt/RMTManager.cpp index abcb38a..f68d622 100644 --- a/components/rmt/RMTManager.cpp +++ b/components/rmt/RMTManager.cpp @@ -440,7 +440,6 @@ esp_err_t RMTManager::send(uint8_t* data, size_t size, rmt_transmit_config_t* co ESP_LOGE(DEBUG_TAG, "Failed to send %s", data); return ESP_FAIL; } - return ESP_OK; } diff --git a/main/link_layer_main.cpp b/main/link_layer_main.cpp index e84e070..28aa08c 100644 --- a/main/link_layer_main.cpp +++ b/main/link_layer_main.cpp @@ -97,12 +97,11 @@ void multi_transceiver(void* arg) { uint8_t dest_board_id = args->receiver_id; //using a dummy number for now - there is no board with id 2 right now - const char* message = "THIS IS A TEXT MESSAGE"; + const char* message = "FROM BEST BOARD"; uint8_t curr_channel = args->task_id; QueueHandle_t shared_queue = (QueueHandle_t)args->receive_queue; - uint8_t send_buf[DATA_SIZE_TEST]; uint8_t recv_buf[DATA_SIZE_TEST]; memset(recv_buf, 0, DATA_SIZE_TEST); @@ -125,55 +124,93 @@ void multi_transceiver(void* arg) { uint32_t num_incorrect = 0; uint32_t total_transactions = 0; + + RIPRow_public_matrix matrix[RIP_MAX_ROUTES]; + size_t matrix_size = RIP_MAX_ROUTES; + + for (int i = 0; i < RIP_MAX_ROUTES; i++){ + RIPRow_public* table = (RIPRow_public*)pvPortMalloc(sizeof(RIPRow_public)*RIP_MAX_ROUTES); + matrix[i] = { + .table = table, + .size = RIP_MAX_ROUTES + }; + } ReceviedFrame recv_frame = {}; printf("task %d starting...\n", curr_channel); vTaskDelay(3000 / portTICK_PERIOD_MS); + bool receive_only = false; + while(1){ - // vTaskDelay(1000 / portTICK_PERIOD_MS); // wait 1 second before trying to send again - - // snprintf(reinterpret_cast(send_buf), sizeof(send_buf), "%s %d CH. %d", message, iteration, curr_channel); - - // ESP_ERROR_CHECK(gptimer_get_raw_count(gptimer, &start_count)); - // res = obj->send(dest_board_id, send_buf, strlen(reinterpret_cast(send_buf)), FrameType::DEBUG_CONTROL_TYPE, curr_channel); - // ESP_ERROR_CHECK(gptimer_get_raw_count(gptimer, &end_count)); - - // snprintf(reinterpret_cast(send_buf), sizeof(send_buf), "%s RANDOM", message); //modifying the data while it transmits shouldn't affect the actual transmission here - - // if (res != ESP_OK){ - // ESP_LOGE("thread", "Failed to send message on thread %d", curr_channel); - // } else { - // printf("Successfully sent message\n"); - // // printf("Sent %zu B sized in %" PRIu64 " us\n", strlen(reinterpret_cast(send_buf)) + CONTROL_FRAME_OVERHEAD, end_count-start_count); - // } - - //wait on a queue for a few ms (if there's nothing, just send another frame. otherwise pop from queue and read it) - if (xQueueReceive(shared_queue, (void*)&recv_frame, (TickType_t) 50) != pdPASS){ - memset(send_buf, 0, 256); - continue; //nothing or failed to pop from queue + if(!receive_only){ + vTaskDelay(1000 / portTICK_PERIOD_MS); // wait 1 second before trying to send again + + snprintf(reinterpret_cast(send_buf), sizeof(send_buf), "%s %d CH. %d", message, 4, curr_channel); + + // ESP_ERROR_CHECK(gptimer_get_raw_count(gptimer, &start_count)); + res = obj->send(dest_board_id, send_buf, strlen(reinterpret_cast(send_buf)), FrameType::DEBUG_CONTROL_TYPE, 0x0); + // ESP_ERROR_CHECK(gptimer_get_raw_count(gptimer, &end_count)); + + snprintf(reinterpret_cast(send_buf), sizeof(send_buf), "%s RANDOM", message); //modifying the data while it transmits shouldn't affect the actual transmission here + + if (res != ESP_OK){ + ESP_LOGE("thread", "Failed to send message on thread %d", curr_channel); + continue; + } else { + printf("Successfully sent message\n"); + // printf("Sent %zu B sized in %" PRIu64 " us\n", strlen(reinterpret_cast(send_buf)) + CONTROL_FRAME_OVERHEAD, end_count-start_count); + } } - - res = obj->print_frame_info(recv_frame.buf, recv_frame.len, recv_buf); - if (res != ESP_OK){ - num_incorrect++; - printf("Received %ld bad frames on tx/rx round %ld for thread %d\n", num_incorrect, total_transactions, curr_channel); - } else { - printf("Received message %s on channel %d on round %ld. Total bad frames %ld\n", recv_buf, curr_channel, total_transactions, num_incorrect); + if (receive_only){ + //wait on a queue for a few ms (if there's nothing, just send another frame. otherwise pop from queue and read it) + if (xQueueReceive(shared_queue, (void*)&recv_frame, (TickType_t) 50) != pdPASS){ + memset(send_buf, 0, 256); + continue; //nothing or failed to pop from queue + } + + res = obj->print_frame_info(recv_frame.buf, recv_frame.len, recv_buf); + + if (res != ESP_OK){ + num_incorrect++; + printf("Received %ld bad frames on tx/rx round %ld for thread %d\n", num_incorrect, total_transactions, curr_channel); + } else { + printf("Received message %s on channel %d on round %ld. Total bad frames %ld\n", recv_buf, curr_channel, total_transactions, num_incorrect); + } } total_transactions++; iteration++; - if (iteration == 100){ + if (iteration == 10){ iteration = 0; + // if (!receive_only){ + // matrix_size = RIP_MAX_ROUTES; + // res = obj->get_network_toplogy(matrix, &matrix_size); + // if (res != ESP_OK){ + // ESP_LOGE("multi", "Failed to get topology"); + // } else { + // for (int i = 0; i < matrix_size; i++){ + // printf("Table for board %d:\n", matrix[i].board_id); + // printf("board_id\t\tHops\t\tChannel\n"); + // for (int j = 0; j < matrix[i].size; j++){ + // printf("%d\t\t%d\t\t%d\n", matrix[i].table[j].info.board_id, matrix[i].table[j].info.hops, matrix[i].table[j].channel); + // } + // printf("=====\n"); + + // //reset matrix + // matrix[i].size = RIP_MAX_ROUTES; + // } + // } + // } } // vTaskDelay(1000 / portTICK_PERIOD_MS); // wait 1 second before trying to send again //reset temp buffers memset(recv_buf, 0, DATA_SIZE_TEST); memset(send_buf, 0, DATA_SIZE_TEST); + } while(true){ @@ -215,7 +252,7 @@ extern "C" [[noreturn]] void app_main(void) { // uint8_t iteration = 0; // const char* message = "THIS IS A TEXT MESSAGE"; uint8_t num_channels = 1; - uint8_t board_id = 69; + uint8_t board_id = 4; std::unique_ptr obj = std::make_unique(board_id, num_channels); // uint8_t dest_board_id = 2; //using a dummy number for now - there is no board with id 2 right now @@ -235,7 +272,7 @@ extern "C" [[noreturn]] void app_main(void) { for (uint8_t i = 0; i < num_channels; i++){ args[i].link_layer_obj = obj_to_send; args[i].task_id = i; - args[i].receiver_id = 1; + args[i].receiver_id = 69; args[i].receive_queue = xQueueCreate(10, sizeof(ReceviedFrame)); //queue storing up to 10 control frames xTaskCreate(multi_transceiver, "multi_transceiver", 4096, static_cast(&args[i]), 5, NULL); vTaskDelay(500 / portTICK_PERIOD_MS);