ApfelNetzwerk/embedded/components/network/zh_network.c
2024-10-11 20:28:10 +02:00

904 lines
53 KiB
C

#include "zh_network.h"
#define DATA_SEND_SUCCESS BIT0
#define DATA_SEND_FAIL BIT1
#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
static void _send_cb(const uint8_t *mac_addr, esp_now_send_status_t status);
#if defined CONFIG_IDF_TARGET_ESP8266 || ESP_IDF_VERSION_MAJOR == 4
static void _recv_cb(const uint8_t *mac_addr, const uint8_t *data, int data_len);
#else
static void _recv_cb(const esp_now_recv_info_t *esp_now_info, const uint8_t *data, int data_len);
#endif
static void _processing(void *pvParameter);
static const char *TAG = "zh_network";
static EventGroupHandle_t _event_group_handle = {0};
static QueueHandle_t _queue_handle = {0};
static TaskHandle_t _processing_task_handle = {0};
static SemaphoreHandle_t _id_vector_mutex = {0};
static zh_network_init_config_t _init_config = {0};
static zh_vector_t _id_vector = {0};
static zh_vector_t _session_vector = {0};
static zh_vector_t _route_vector = {0};
static zh_vector_t _response_vector = {0};
static uint8_t _self_mac[6] = {0};
static const uint8_t _broadcast_mac[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
static bool _is_initialized = false;
static uint8_t _attempts = 0;
typedef struct
{
uint8_t original_target_mac[6];
uint8_t intermediate_target_mac[6];
} _routing_table_t;
typedef struct
{
uint64_t time;
enum
{
TO_SEND,
ON_RECV,
WAIT_ROUTE,
WAIT_RESPONSE,
} id;
struct
{
enum
{
BROADCAST,
UNICAST,
DELIVERY_CONFIRM,
SEARCH_REQUEST,
SEARCH_RESPONSE
} __attribute__((packed)) message_type;
uint32_t network_id;
uint32_t message_id;
uint32_t confirm_id;
uint8_t original_target_mac[6];
uint8_t original_sender_mac[6];
uint8_t sender_mac[6];
uint8_t payload[ZH_NETWORK_MAX_MESSAGE_SIZE];
uint8_t payload_len;
} __attribute__((packed)) data;
} _queue_t;
ESP_EVENT_DEFINE_BASE(ZH_NETWORK);
esp_err_t zh_network_init(const zh_network_init_config_t *config)
{
ESP_LOGI(TAG, "ESP-NOW initialization begin.");
if (config == NULL)
{
ESP_LOGE(TAG, "ESP-NOW initialization fail. Invalid argument.");
return ESP_ERR_INVALID_ARG;
}
_init_config = *config;
if (_init_config.wifi_channel < 1 || _init_config.wifi_channel > 14)
{
ESP_LOGE(TAG, "ESP-NOW initialization fail. WiFi channel incorrect.");
return ESP_ERR_INVALID_ARG;
}
esp_err_t err = esp_wifi_set_channel(_init_config.wifi_channel, WIFI_SECOND_CHAN_NONE);
if (err == ESP_ERR_WIFI_NOT_INIT || err == ESP_ERR_WIFI_NOT_STARTED)
{
ESP_LOGE(TAG, "ESP-NOW initialization fail. WiFi not initialized.");
return ESP_ERR_WIFI_NOT_INIT;
}
else if (err == ESP_FAIL)
{
uint8_t prim = 0;
wifi_second_chan_t sec = 0;
esp_wifi_get_channel(&prim, &sec);
if (prim != _init_config.wifi_channel)
{
ESP_LOGW(TAG, "ESP-NOW initialization warning. The device is connected to the router. Channel %d will be used for ESP-NOW.", prim);
}
}
if ((sizeof(_queue_t) - 14) > ESP_NOW_MAX_DATA_LEN)
{
ESP_LOGE(TAG, "ESP-NOW initialization fail. The maximum value of the transmitted data size is incorrect.");
return ESP_ERR_INVALID_ARG;
}
if (_init_config.wifi_interface == WIFI_IF_STA)
{
esp_read_mac(_self_mac, ESP_MAC_WIFI_STA);
}
else
{
esp_read_mac(_self_mac, ESP_MAC_WIFI_SOFTAP);
}
_event_group_handle = xEventGroupCreate();
_queue_handle = xQueueCreate(_init_config.queue_size, sizeof(_queue_t));
zh_vector_init(&_id_vector, sizeof(uint32_t), false);
zh_vector_init(&_session_vector, sizeof(uint32_t), false);
zh_vector_init(&_route_vector, sizeof(_routing_table_t), false);
zh_vector_init(&_response_vector, sizeof(uint32_t), false);
_id_vector_mutex = xSemaphoreCreateMutex();
if (esp_now_init() != ESP_OK || esp_now_register_send_cb(_send_cb) != ESP_OK || esp_now_register_recv_cb(_recv_cb) != ESP_OK)
{
ESP_LOGE(TAG, "ESP-NOW initialization fail. Internal error.");
return ESP_FAIL;
}
if (xTaskCreatePinnedToCore(&_processing, "NULL", _init_config.stack_size, NULL, _init_config.task_priority, &_processing_task_handle, tskNO_AFFINITY) != pdPASS)
{
ESP_LOGE(TAG, "ESP-NOW initialization fail. Internal error.");
return ESP_FAIL;
}
_is_initialized = true;
ESP_LOGI(TAG, "ESP-NOW initialization success.");
return ESP_OK;
}
esp_err_t zh_network_deinit(void)
{
ESP_LOGI(TAG, "ESP-NOW deinitialization begin.");
if (_is_initialized == false)
{
ESP_LOGE(TAG, "ESP-NOW deinitialization fail. ESP-NOW not initialized.");
return ESP_FAIL;
}
vEventGroupDelete(_event_group_handle);
vQueueDelete(_queue_handle);
esp_now_unregister_send_cb();
esp_now_unregister_recv_cb();
esp_now_deinit();
zh_vector_free(&_id_vector);
zh_vector_free(&_route_vector);
zh_vector_free(&_response_vector);
vTaskDelete(_processing_task_handle);
_is_initialized = false;
ESP_LOGI(TAG, "ESP-NOW deinitialization success.");
return ESP_OK;
}
esp_err_t zh_network_send(const uint8_t *target, const uint8_t *data, const uint8_t data_len)
{
if (target == NULL)
{
ESP_LOGI(TAG, "Adding outgoing ESP-NOW data to MAC FF:FF:FF:FF:FF:FF to queue begin.");
}
else
{
ESP_LOGI(TAG, "Adding outgoing ESP-NOW data to MAC %02X:%02X:%02X:%02X:%02X:%02X to queue begin.", MAC2STR(target));
}
if (_is_initialized == false)
{
ESP_LOGE(TAG, "Adding outgoing ESP-NOW data to queue fail. ESP-NOW not initialized.");
return ESP_FAIL;
}
if (data_len == 0 || data == NULL || data_len > ZH_NETWORK_MAX_MESSAGE_SIZE)
{
ESP_LOGE(TAG, "Adding outgoing ESP-NOW data to queue fail. Invalid argument.");
return ESP_ERR_INVALID_ARG;
}
if (uxQueueSpacesAvailable(_queue_handle) < _init_config.queue_size / 2)
{
ESP_LOGW(TAG, "Adding outgoing ESP-NOW data to queue fail. Queue is almost full.");
return ESP_ERR_INVALID_STATE;
}
_queue_t queue = {0};
queue.id = TO_SEND;
queue.data.network_id = _init_config.network_id;
queue.data.message_id = abs(esp_random()); // It is not clear why esp_random() sometimes gives negative values.
memcpy(queue.data.original_sender_mac, _self_mac, 6);
if (target == NULL)
{
queue.data.message_type = BROADCAST;
memcpy(queue.data.original_target_mac, _broadcast_mac, 6);
}
else
{
if (memcmp(target, _broadcast_mac, 6) != 0)
{
queue.data.message_type = UNICAST;
memcpy(queue.data.original_target_mac, target, 6);
}
else
{
queue.data.message_type = BROADCAST;
memcpy(queue.data.original_target_mac, _broadcast_mac, 6);
}
}
memcpy(queue.data.payload, data, data_len);
queue.data.payload_len = data_len;
if (target == NULL)
{
ESP_LOGI(TAG, "Adding outgoing ESP-NOW data to MAC FF:FF:FF:FF:FF:FF to queue success.");
}
else
{
ESP_LOGI(TAG, "Adding outgoing ESP-NOW data to MAC %02X:%02X:%02X:%02X:%02X:%02X to queue success.", MAC2STR(target));
}
if (xQueueSend(_queue_handle, &queue, portTICK_PERIOD_MS) != pdTRUE)
{
ESP_LOGE(TAG, "ESP-NOW message processing task internal error at line %d.", __LINE__);
return ESP_FAIL;
}
return ESP_OK;
}
static void _send_cb(const uint8_t *mac_addr, esp_now_send_status_t status)
{
if (status == ESP_NOW_SEND_SUCCESS)
{
xEventGroupSetBits(_event_group_handle, DATA_SEND_SUCCESS);
}
else
{
xEventGroupSetBits(_event_group_handle, DATA_SEND_FAIL);
}
}
#if defined CONFIG_IDF_TARGET_ESP8266 || ESP_IDF_VERSION_MAJOR == 4
static void _recv_cb(const uint8_t *mac_addr, const uint8_t *data, int data_len)
#else
static void _recv_cb(const esp_now_recv_info_t *esp_now_info, const uint8_t *data, int data_len)
#endif
{
#if defined CONFIG_IDF_TARGET_ESP8266 || ESP_IDF_VERSION_MAJOR == 4
ESP_LOGI(TAG, "Adding incoming ESP-NOW data from MAC %02X:%02X:%02X:%02X:%02X:%02X to queue begin.", MAC2STR(mac_addr));
#else
ESP_LOGI(TAG, "Adding incoming ESP-NOW data from MAC %02X:%02X:%02X:%02X:%02X:%02X to queue begin.", MAC2STR(esp_now_info->src_addr));
#endif
if (uxQueueSpacesAvailable(_queue_handle) < (_init_config.queue_size - 2))
{
ESP_LOGW(TAG, "Adding incoming ESP-NOW data to queue fail. Queue is almost full.");
return;
}
if (data_len == sizeof(_queue_t) - 14)
{
_queue_t queue = {0};
queue.id = ON_RECV;
memcpy(&queue.data, data, data_len);
if (memcmp(&queue.data.network_id, &_init_config.network_id, sizeof(queue.data.network_id)) != 0)
{
ESP_LOGW(TAG, "Adding incoming ESP-NOW data to queue fail. Incorrect mesh network ID.");
return;
}
for (uint16_t i = 0; i < zh_vector_get_size(&_id_vector); ++i)
{
uint32_t *message_id = zh_vector_get_item(&_id_vector, i);
if (memcmp(&queue.data.message_id, message_id, sizeof(queue.data.message_id)) == 0)
{
ESP_LOGW(TAG, "Adding incoming ESP-NOW data to queue fail. Repeat message received.");
return;
}
}
if (xSemaphoreTake(_id_vector_mutex, portTICK_PERIOD_MS) == pdTRUE)
{
zh_vector_push_back(&_id_vector, &queue.data.message_id);
if (zh_vector_get_size(&_id_vector) > _init_config.id_vector_size)
{
zh_vector_delete_item(&_id_vector, 0);
}
xSemaphoreGive(_id_vector_mutex);
}
#if defined CONFIG_IDF_TARGET_ESP8266 || ESP_IDF_VERSION_MAJOR == 4
memcpy(queue.data.sender_mac, mac_addr, 6);
#else
memcpy(queue.data.sender_mac, esp_now_info->src_addr, 6);
#endif
#if defined CONFIG_IDF_TARGET_ESP8266 || ESP_IDF_VERSION_MAJOR == 4
ESP_LOGI(TAG, "Adding incoming ESP-NOW data from MAC %02X:%02X:%02X:%02X:%02X:%02X to queue success.", MAC2STR(mac_addr));
#else
ESP_LOGI(TAG, "Adding incoming ESP-NOW data from MAC %02X:%02X:%02X:%02X:%02X:%02X to queue success.", MAC2STR(esp_now_info->src_addr));
#endif
if (xQueueSendToFront(_queue_handle, &queue, portTICK_PERIOD_MS) != pdTRUE)
{
ESP_LOGE(TAG, "ESP-NOW message processing task internal error at line %d.", __LINE__);
}
}
else
{
ESP_LOGW(TAG, "Adding incoming ESP-NOW data to queue fail. Incorrect ESP-NOW data size.");
}
}
static void _processing(void *pvParameter)
{
_queue_t queue = {0};
while (xQueueReceive(_queue_handle, &queue, portMAX_DELAY) == pdTRUE)
{
bool flag = false;
switch (queue.id)
{
case TO_SEND:
ESP_LOGI(TAG, "Outgoing ESP-NOW data from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X processing begin.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac));
esp_now_peer_info_t *peer = heap_caps_malloc(sizeof(esp_now_peer_info_t), MALLOC_CAP_8BIT);
if (peer == NULL)
{
ESP_LOGE(TAG, "Outgoing ESP-NOW data processing fail. Memory allocation fail or no free memory in the heap.");
heap_caps_free(peer);
break;
}
memset(peer, 0, sizeof(esp_now_peer_info_t));
peer->ifidx = _init_config.wifi_interface;
if (queue.data.message_type == BROADCAST || queue.data.message_type == SEARCH_REQUEST || queue.data.message_type == SEARCH_RESPONSE)
{
memcpy(peer->peer_addr, _broadcast_mac, 6);
if (memcmp(queue.data.original_sender_mac, _self_mac, 6) == 0)
{
if (xSemaphoreTake(_id_vector_mutex, portTICK_PERIOD_MS) == pdTRUE)
{
zh_vector_push_back(&_id_vector, &queue.data.message_id);
if (zh_vector_get_size(&_id_vector) > _init_config.id_vector_size)
{
zh_vector_delete_item(&_id_vector, 0);
}
xSemaphoreGive(_id_vector_mutex);
}
}
}
else
{
ESP_LOGI(TAG, "Checking routing table to MAC %02X:%02X:%02X:%02X:%02X:%02X.", MAC2STR(queue.data.original_target_mac));
int64_t route_time = esp_timer_get_time();
printf("-------------\n");
for (uint16_t i = 0; i < zh_vector_get_size(&_route_vector); ++i)
{
_routing_table_t *routing_table = zh_vector_get_item(&_route_vector, i);
printf("%02X:%02X:%02X:%02X:%02X:%02X -> %02X:%02X:%02X:%02X:%02X:%02X\n", MAC2STR(routing_table->original_target_mac), MAC2STR(routing_table->intermediate_target_mac));
if (memcmp(queue.data.original_target_mac, routing_table->original_target_mac, 6) == 0)
{
memcpy(peer->peer_addr, routing_table->intermediate_target_mac, 6);
flag = true;
ESP_LOGI(TAG, "Routing to MAC %02X:%02X:%02X:%02X:%02X:%02X is found. Forwarding via MAC %02X:%02X:%02X:%02X:%02X:%02X.", MAC2STR(queue.data.original_target_mac), MAC2STR(peer->peer_addr));
printf("found route in cache");
break;
}
}
route_time = esp_timer_get_time() - route_time;
printf("Took: %lld\n", route_time);
if (flag == false)
{
ESP_LOGI(TAG, "Routing to MAC %02X:%02X:%02X:%02X:%02X:%02X not found.", MAC2STR(queue.data.original_target_mac));
if (queue.data.message_type == UNICAST)
{
ESP_LOGI(TAG, "Unicast message from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X transferred to routing waiting list.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac));
}
else
{
ESP_LOGI(TAG, "System message for message receiving confirmation from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X transferred to routing waiting list.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac));
}
queue.id = WAIT_ROUTE;
queue.time = esp_timer_get_time() / 1000;
if (xQueueSend(_queue_handle, &queue, portTICK_PERIOD_MS) != pdTRUE)
{
ESP_LOGE(TAG, "ESP-NOW message processing task internal error at line %d.", __LINE__);
}
ESP_LOGI(TAG, "System message for routing request from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X added to queue.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac));
queue.id = TO_SEND;
queue.data.message_type = SEARCH_REQUEST;
memcpy(queue.data.original_sender_mac, _self_mac, 6);
queue.data.payload_len = 0;
memset(queue.data.payload, 0, ZH_NETWORK_MAX_MESSAGE_SIZE);
queue.data.message_id = abs(esp_random()); // It is not clear why esp_random() sometimes gives negative values.
ESP_LOGI(TAG, "Outgoing ESP-NOW data from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X processed success.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac));
if (xQueueSendToFront(_queue_handle, &queue, portTICK_PERIOD_MS) != pdTRUE)
{
ESP_LOGE(TAG, "ESP-NOW message processing task internal error at line %d.", __LINE__);
}
heap_caps_free(peer);
break;
}
}
if (esp_now_add_peer(peer) != ESP_OK)
{
ESP_LOGE(TAG, "Outgoing ESP-NOW data processing fail. Internal error with adding peer.");
heap_caps_free(peer);
break;
}
zh_network_event_on_send_t *on_send = heap_caps_malloc(sizeof(zh_network_event_on_send_t), MALLOC_CAP_8BIT);
if (on_send == NULL)
{
ESP_LOGE(TAG, "Outgoing ESP-NOW data processing fail. Memory allocation fail or no free memory in the heap.");
heap_caps_free(peer);
heap_caps_free(on_send);
break;
}
memset(on_send, 0, sizeof(zh_network_event_on_send_t));
memcpy(on_send->mac_addr, queue.data.original_target_mac, 6);
SEND:
++_attempts;
if (esp_now_send((uint8_t *)peer->peer_addr, (uint8_t *)&queue.data, sizeof(_queue_t) - 14) != ESP_OK)
{
ESP_LOGE(TAG, "ESP-NOW message processing task internal error at line %d.", __LINE__);
heap_caps_free(peer);
heap_caps_free(on_send);
break;
}
EventBits_t bit = xEventGroupWaitBits(_event_group_handle, DATA_SEND_SUCCESS | DATA_SEND_FAIL, pdTRUE, pdFALSE, 50 / portTICK_PERIOD_MS);
if ((bit & DATA_SEND_SUCCESS) != 0)
{
_attempts = 0;
if (memcmp(queue.data.original_sender_mac, _self_mac, 6) == 0)
{
if (queue.data.message_type == BROADCAST)
{
printf("BROADCAST STARTED");
ESP_LOGI(TAG, "Broadcast message from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X sent success.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac));
on_send->status = ZH_NETWORK_SEND_SUCCESS;
ESP_LOGI(TAG, "Outgoing ESP-NOW data from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X processed success.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac));
if (esp_event_post(ZH_NETWORK, ZH_NETWORK_ON_SEND_EVENT, on_send, sizeof(zh_network_event_on_send_t), portTICK_PERIOD_MS) != ESP_OK)
{
ESP_LOGE(TAG, "ESP-NOW message processing task internal error at line %d.", __LINE__);
}
}
if (queue.data.message_type == SEARCH_REQUEST)
{
printf("SEARCH REQUEST SENT");
ESP_LOGI(TAG, "System message for routing request from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X sent success.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac));
ESP_LOGI(TAG, "Outgoing ESP-NOW data from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X processed success.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac));
}
if (queue.data.message_type == SEARCH_RESPONSE)
{
ESP_LOGI(TAG, "System message for routing response from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X sent success.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac));
ESP_LOGI(TAG, "Outgoing ESP-NOW data from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X processed success.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac));
}
if (queue.data.message_type == DELIVERY_CONFIRM)
{
printf("Sent Delivery Confirm: %d", queue.data.message_id);
ESP_LOGI(TAG, "System message for message receiving confirmation from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X via MAC %02X:%02X:%02X:%02X:%02X:%02X sent success.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac), MAC2STR(peer->peer_addr));
ESP_LOGI(TAG, "Outgoing ESP-NOW data from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X processed success.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac));
}
if (queue.data.message_type == UNICAST)
{
printf("Queued waiting for response");
ESP_LOGI(TAG, "Unicast message from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X via MAC %02X:%02X:%02X:%02X:%02X:%02X sent success.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac), MAC2STR(peer->peer_addr));
ESP_LOGI(TAG, "Unicast message from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X transferred to confirmation message waiting list.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac));
ESP_LOGI(TAG, "Outgoing ESP-NOW data from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X processed success.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac));
queue.id = WAIT_RESPONSE;
queue.time = esp_timer_get_time() / 1000;
zh_vector_push_back(&_session_vector, &queue.data.message_id);
if (xQueueSend(_queue_handle, &queue, portTICK_PERIOD_MS) != pdTRUE)
{
ESP_LOGE(TAG, "ESP-NOW message processing task internal error at line %d.", __LINE__);
}
}
}
else
{
if (queue.data.message_type == BROADCAST)
{
ESP_LOGI(TAG, "Broadcast message from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X sent success.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac));
ESP_LOGI(TAG, "Outgoing ESP-NOW data from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X processed success.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac));
}
if (queue.data.message_type == SEARCH_REQUEST)
{
ESP_LOGI(TAG, "System message for routing request from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X sent success.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac));
ESP_LOGI(TAG, "Outgoing ESP-NOW data from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X processed success.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac));
}
if (queue.data.message_type == SEARCH_RESPONSE)
{
ESP_LOGI(TAG, "System message for routing response from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X sent success.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac));
ESP_LOGI(TAG, "Outgoing ESP-NOW data from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X processed success.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac));
}
if (queue.data.message_type == DELIVERY_CONFIRM)
{
printf("Sent Delivery Confirm: %d\n", queue.data.message_id);
ESP_LOGI(TAG, "System message for message receiving confirmation from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X via MAC %02X:%02X:%02X:%02X:%02X:%02X sent success.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac), MAC2STR(peer->peer_addr));
ESP_LOGI(TAG, "Outgoing ESP-NOW data from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X processed success.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac));
}
if (queue.data.message_type == UNICAST)
{
ESP_LOGI(TAG, "Unicast message from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X via MAC %02X:%02X:%02X:%02X:%02X:%02X sent success.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac), MAC2STR(peer->peer_addr));
ESP_LOGI(TAG, "Outgoing ESP-NOW data from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X processed success.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac));
}
}
}
else
{
if (_attempts < _init_config.attempts)
{
goto SEND;
}
_attempts = 0;
if (memcmp(queue.data.original_target_mac, _broadcast_mac, 6) != 0)
{
ESP_LOGI(TAG, "Routing to MAC %02X:%02X:%02X:%02X:%02X:%02X via MAC %02X:%02X:%02X:%02X:%02X:%02X is incorrect.", MAC2STR(queue.data.original_target_mac), MAC2STR(peer->peer_addr));
for (uint16_t i = 0; i < zh_vector_get_size(&_route_vector); ++i)
{
_routing_table_t *routing_table = zh_vector_get_item(&_route_vector, i);
if (memcmp(queue.data.original_target_mac, routing_table->original_target_mac, 6) == 0)
{
zh_vector_delete_item(&_route_vector, i);
}
}
if (queue.data.message_type == UNICAST)
{
ESP_LOGI(TAG, "Unicast message from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X transferred to routing waiting list.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac));
}
if (queue.data.message_type == DELIVERY_CONFIRM)
{
ESP_LOGI(TAG, "System message for message receiving confirmation from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X transferred to routing waiting list.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac));
}
queue.id = WAIT_ROUTE;
queue.time = esp_timer_get_time() / 1000;
if (xQueueSend(_queue_handle, &queue, portTICK_PERIOD_MS) != pdTRUE)
{
ESP_LOGE(TAG, "ESP-NOW message processing task internal error at line %d.", __LINE__);
}
ESP_LOGI(TAG, "System message for routing request to MAC %02X:%02X:%02X:%02X:%02X:%02X added to queue.", MAC2STR(queue.data.original_target_mac));
queue.id = TO_SEND;
queue.data.message_type = SEARCH_REQUEST;
memcpy(queue.data.original_sender_mac, _self_mac, 6);
queue.data.payload_len = 0;
memset(queue.data.payload, 0, ZH_NETWORK_MAX_MESSAGE_SIZE);
queue.data.message_id = abs(esp_random()); // It is not clear why esp_random() sometimes gives negative values.
ESP_LOGI(TAG, "Outgoing ESP-NOW data from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X processed success.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac));
if (xQueueSendToFront(_queue_handle, &queue, portTICK_PERIOD_MS) != pdTRUE)
{
ESP_LOGE(TAG, "ESP-NOW message processing task internal error at line %d.", __LINE__);
}
}
}
esp_now_del_peer(peer->peer_addr);
heap_caps_free(on_send);
heap_caps_free(peer);
break;
case ON_RECV:
ESP_LOGI(TAG, "Incoming ESP-NOW data from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X processing begin.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac));
switch (queue.data.message_type)
{
case BROADCAST:
ESP_LOGI(TAG, "Broadcast message from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X is received.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac));
zh_network_event_on_recv_t *on_recv = heap_caps_malloc(sizeof(zh_network_event_on_recv_t), MALLOC_CAP_8BIT);
if (on_recv == NULL)
{
ESP_LOGE(TAG, "ESP-NOW message processing task internal error at line %d.", __LINE__);
heap_caps_free(on_recv);
break;
}
memset(on_recv, 0, sizeof(zh_network_event_on_recv_t));
memcpy(on_recv->mac_addr, queue.data.original_sender_mac, 6);
on_recv->data_len = queue.data.payload_len;
on_recv->data = heap_caps_malloc(queue.data.payload_len, MALLOC_CAP_8BIT);
if (on_recv->data == NULL)
{
ESP_LOGE(TAG, "ESP-NOW message processing task internal error at line %d.", __LINE__);
heap_caps_free(on_recv);
heap_caps_free(on_recv->data);
break;
}
memset(on_recv->data, 0, queue.data.payload_len);
memcpy(on_recv->data, queue.data.payload, queue.data.payload_len);
ESP_LOGI(TAG, "Broadcast message from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X added to queue for resend to all nodes.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac));
ESP_LOGI(TAG, "Incoming ESP-NOW data from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X processed success.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac));
if (esp_event_post(ZH_NETWORK, ZH_NETWORK_ON_RECV_EVENT, on_recv, sizeof(zh_network_event_on_recv_t) + on_recv->data_len + sizeof(on_recv->data_len), portTICK_PERIOD_MS) != ESP_OK)
{
ESP_LOGE(TAG, "ESP-NOW message processing task internal error at line %d.", __LINE__);
}
heap_caps_free(on_recv);
queue.id = TO_SEND;
if (xQueueSend(_queue_handle, &queue, portTICK_PERIOD_MS) != pdTRUE)
{
ESP_LOGE(TAG, "ESP-NOW message processing task internal error at line %d.", __LINE__);
}
break;
case UNICAST:
ESP_LOGI(TAG, "Unicast message from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X is received.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac));
if (memcmp(queue.data.original_target_mac, _self_mac, 6) == 0)
{
zh_network_event_on_recv_t *on_recv = heap_caps_malloc(sizeof(zh_network_event_on_recv_t), MALLOC_CAP_8BIT);
if (on_recv == NULL)
{
ESP_LOGE(TAG, "ESP-NOW message processing task internal error at line %d.", __LINE__);
heap_caps_free(on_recv);
break;
}
memset(on_recv, 0, sizeof(zh_network_event_on_recv_t));
memcpy(on_recv->mac_addr, queue.data.original_sender_mac, 6);
on_recv->data_len = queue.data.payload_len;
on_recv->data = heap_caps_malloc(queue.data.payload_len, MALLOC_CAP_8BIT);
if (on_recv->data == NULL)
{
ESP_LOGE(TAG, "ESP-NOW message processing task internal error at line %d.", __LINE__);
heap_caps_free(on_recv);
heap_caps_free(on_recv->data);
break;
}
memset(on_recv->data, 0, queue.data.payload_len);
memcpy(on_recv->data, queue.data.payload, queue.data.payload_len);
ESP_LOGI(TAG, "Incoming ESP-NOW data from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X processed success.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac));
if (esp_event_post(ZH_NETWORK, ZH_NETWORK_ON_RECV_EVENT, on_recv, sizeof(zh_network_event_on_recv_t) + on_recv->data_len + sizeof(on_recv->data_len), portTICK_PERIOD_MS) != ESP_OK)
{
ESP_LOGE(TAG, "ESP-NOW message processing task internal error at line %d.", __LINE__);
}
heap_caps_free(on_recv);
queue.id = TO_SEND;
queue.data.message_type = DELIVERY_CONFIRM;
memcpy(queue.data.original_target_mac, queue.data.original_sender_mac, 6);
memcpy(queue.data.original_sender_mac, _self_mac, 6);
queue.data.payload_len = 0;
memset(queue.data.payload, 0, ZH_NETWORK_MAX_MESSAGE_SIZE);
queue.data.confirm_id = queue.data.message_id;
queue.data.message_id = abs(esp_random()); // It is not clear why esp_random() sometimes gives negative values.
if (xQueueSendToFront(_queue_handle, &queue, portTICK_PERIOD_MS) != pdTRUE)
{
ESP_LOGE(TAG, "ESP-NOW message processing task internal error at line %d.", __LINE__);
}
break;
}
ESP_LOGI(TAG, "Unicast message from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X added to queue for forwarding.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac));
ESP_LOGI(TAG, "Incoming ESP-NOW data from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X processed success.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac));
queue.id = TO_SEND;
if (xQueueSendToFront(_queue_handle, &queue, portTICK_PERIOD_MS) != pdTRUE)
{
ESP_LOGE(TAG, "ESP-NOW message processing task internal error at line %d.", __LINE__);
}
break;
case DELIVERY_CONFIRM:
printf("Received Delivery Confirm: %d\n", queue.data.message_id);
ESP_LOGI(TAG, "System message for message receiving confirmation from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X is received.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac));
if (memcmp(queue.data.original_target_mac, _self_mac, 6) == 0)
{
for (uint16_t i = 0; i < zh_vector_get_size(&_session_vector); ++i)
{
uint32_t *message_id = zh_vector_get_item(&_session_vector, i);
if (memcmp(&queue.data.confirm_id, message_id, sizeof(uint32_t)) == 0)
{
printf("SESSION MATCHED\n");
zh_vector_push_back(&_response_vector, &queue.data.confirm_id);
if (zh_vector_get_size(&_response_vector) > _init_config.queue_size)
{
zh_vector_delete_item(&_response_vector, 0);
}
ESP_LOGI(TAG, "Incoming ESP-NOW data from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X processed success.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac));
break;
}
}
break;
}
ESP_LOGI(TAG, "System message for message receiving confirmation from MAC %02X:%02X:%02X:%02X:%02X:%02X fto MAC %02X:%02X:%02X:%02X:%02X:%02X added to queue for forwarding.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac));
ESP_LOGI(TAG, "Incoming ESP-NOW data from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X processed success.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac));
queue.id = TO_SEND;
if (xQueueSendToFront(_queue_handle, &queue, portTICK_PERIOD_MS) != pdTRUE)
{
ESP_LOGE(TAG, "ESP-NOW message processing task internal error at line %d.", __LINE__);
}
break;
case SEARCH_REQUEST:
printf("SEARCH REQUEST RECEIVED\n");
ESP_LOGI(TAG, "System message for routing request from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X is received.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac));
for (uint16_t i = 0; i < zh_vector_get_size(&_route_vector); ++i)
{
_routing_table_t *routing_table = zh_vector_get_item(&_route_vector, i);
if (memcmp(queue.data.original_target_mac, routing_table->original_target_mac, 6) == 0)
{
zh_vector_delete_item(&_route_vector, i);
}
}
{ // Just to avoid the compiler warning.
_routing_table_t routing_table = {0};
memcpy(routing_table.original_target_mac, queue.data.original_sender_mac, 6);
memcpy(routing_table.intermediate_target_mac, queue.data.sender_mac, 6);
zh_vector_push_back(&_route_vector, &routing_table);
}
if (zh_vector_get_size(&_route_vector) > _init_config.route_vector_size)
{
zh_vector_delete_item(&_route_vector, 0);
}
if (memcmp(queue.data.original_target_mac, _self_mac, 6) == 0)
{
ESP_LOGI(TAG, "System message for routing response from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X added to the queue.", MAC2STR(queue.data.original_target_mac), MAC2STR(queue.data.original_sender_mac));
queue.id = TO_SEND;
queue.data.message_type = SEARCH_RESPONSE;
memcpy(queue.data.original_target_mac, queue.data.original_sender_mac, 6);
memcpy(queue.data.original_sender_mac, _self_mac, 6);
queue.data.payload_len = 0;
memset(queue.data.payload, 0, ZH_NETWORK_MAX_MESSAGE_SIZE);
queue.data.message_id = abs(esp_random()); // It is not clear why esp_random() sometimes gives negative values.
ESP_LOGI(TAG, "Incoming ESP-NOW data from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X processed success.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac));
if (xQueueSendToFront(_queue_handle, &queue, portTICK_PERIOD_MS) != pdTRUE)
{
ESP_LOGE(TAG, "ESP-NOW message processing task internal error at line %d.", __LINE__);
}
break;
}
ESP_LOGI(TAG, "System message for routing request to MAC %02X:%02X:%02X:%02X:%02X:%02X from MAC %02X:%02X:%02X:%02X:%02X:%02X added to queue for resend to all nodes.", MAC2STR(queue.data.original_target_mac), MAC2STR(queue.data.original_sender_mac));
ESP_LOGI(TAG, "Incoming ESP-NOW data from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X processed success.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac));
queue.id = TO_SEND;
if (xQueueSendToFront(_queue_handle, &queue, portTICK_PERIOD_MS) != pdTRUE)
{
ESP_LOGE(TAG, "ESP-NOW message processing task internal error at line %d.", __LINE__);
}
break;
case SEARCH_RESPONSE:
printf("Received Search Response\n");
ESP_LOGI(TAG, "System message for routing response from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X is received.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac));
for (uint16_t i = 0; i < zh_vector_get_size(&_route_vector); ++i)
{
_routing_table_t *routing_table = zh_vector_get_item(&_route_vector, i);
if (memcmp(queue.data.original_target_mac, routing_table->original_target_mac, 6) == 0)
{
zh_vector_delete_item(&_route_vector, i);
}
}
{ // Just to avoid the compiler warning.
_routing_table_t routing_table = {0};
memcpy(routing_table.original_target_mac, queue.data.original_sender_mac, 6);
memcpy(routing_table.intermediate_target_mac, queue.data.sender_mac, 6);
zh_vector_push_back(&_route_vector, &routing_table);
}
if (zh_vector_get_size(&_route_vector) > _init_config.route_vector_size)
{
zh_vector_delete_item(&_route_vector, 0);
}
if (memcmp(queue.data.original_target_mac, _self_mac, 6) != 0)
{
ESP_LOGI(TAG, "System message for routing response from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X added to queue for resend to all nodes.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac));
ESP_LOGI(TAG, "Incoming ESP-NOW data from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X processed success.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac));
queue.id = TO_SEND;
if (xQueueSendToFront(_queue_handle, &queue, portTICK_PERIOD_MS) != pdTRUE)
{
ESP_LOGE(TAG, "ESP-NOW message processing task internal error at line %d.", __LINE__);
}
break;
}
ESP_LOGI(TAG, "Incoming ESP-NOW data from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X processed success.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac));
break;
default:
break;
}
break;
case WAIT_RESPONSE:
printf("WAIT_RESPONSE queue entry: %d\n", zh_vector_get_size(&_response_vector));
for (uint16_t i = 0; i < zh_vector_get_size(&_response_vector); ++i)
{
uint32_t *message_id = zh_vector_get_item(&_response_vector, i);
if (memcmp(&queue.data.message_id, message_id, sizeof(queue.data.message_id)) == 0)
{
zh_vector_delete_item(&_response_vector, i);
zh_network_event_on_send_t *on_send = heap_caps_malloc(sizeof(zh_network_event_on_send_t), MALLOC_CAP_8BIT);
if (on_send == NULL)
{
ESP_LOGE(TAG, "ESP-NOW message processing task internal error at line %d.", __LINE__);
heap_caps_free(on_send);
break;
}
memset(on_send, 0, sizeof(zh_network_event_on_send_t));
memcpy(on_send->mac_addr, queue.data.original_target_mac, 6);
on_send->status = ZH_NETWORK_SEND_SUCCESS;
ESP_LOGI(TAG, "Unicast message from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X sent success.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac));
ESP_LOGI(TAG, "Unicast message from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X removed from confirmation message waiting list.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac));
if (esp_event_post(ZH_NETWORK, ZH_NETWORK_ON_SEND_EVENT, on_send, sizeof(zh_network_event_on_send_t), portTICK_PERIOD_MS) != ESP_OK)
{
ESP_LOGE(TAG, "ESP-NOW message processing task internal error at line %d.", __LINE__);
}
heap_caps_free(on_send);
flag = true;
for (uint16_t i = 0; i < zh_vector_get_size(&_session_vector); ++i)
{
uint32_t *message_id = zh_vector_get_item(&_session_vector, i);
if (memcmp(&queue.data.message_id, message_id, sizeof(uint32_t)) == 0)
{
zh_vector_delete_item(&_session_vector, i);
printf("FREED SESSION: %d\n", queue.data.message_id);
break;
}
}
break;
}
}
if (flag == false)
{
if ((esp_timer_get_time() / 1000 - queue.time) > _init_config.max_waiting_time)
{
ESP_LOGW(TAG, "Time for waiting confirmation message from MAC %02X:%02X:%02X:%02X:%02X:%02X is expired.", MAC2STR(queue.data.original_target_mac));
for (uint16_t i = 0; i < zh_vector_get_size(&_session_vector); ++i)
{
uint32_t *message_id = zh_vector_get_item(&_session_vector, i);
if (memcmp(&queue.data.message_id, message_id, sizeof(uint32_t)) == 0)
{
zh_vector_delete_item(&_session_vector, i);
printf("FREED SESSION: %d\n", queue.data.message_id);
break;
}
}
if (memcmp(queue.data.original_sender_mac, _self_mac, 6) == 0)
{
zh_network_event_on_send_t *on_send = heap_caps_malloc(sizeof(zh_network_event_on_send_t), MALLOC_CAP_8BIT);
if (on_send == NULL)
{
ESP_LOGE(TAG, "ESP-NOW message processing task internal error at line %d.", __LINE__);
heap_caps_free(on_send);
break;
}
memset(on_send, 0, sizeof(zh_network_event_on_send_t));
memcpy(on_send->mac_addr, queue.data.original_target_mac, 6);
on_send->status = ZH_NETWORK_SEND_FAIL;
ESP_LOGE(TAG, "Unicast message from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X sent fail.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac));
ESP_LOGI(TAG, "Unicast message from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X removed from confirmation message waiting list.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac));
if (esp_event_post(ZH_NETWORK, ZH_NETWORK_ON_SEND_EVENT, on_send, sizeof(zh_network_event_on_send_t), portTICK_PERIOD_MS) != ESP_OK)
{
ESP_LOGE(TAG, "ESP-NOW message processing task internal error at line %d.", __LINE__);
}
heap_caps_free(on_send);
}
break;
}
if (xQueueSend(_queue_handle, &queue, portTICK_PERIOD_MS) != pdTRUE)
{
ESP_LOGE(TAG, "ESP-NOW message processing task internal error at line %d.", __LINE__);
}
}
break;
case WAIT_ROUTE:
printf("Wait Route Queue Entry\n");
for (uint16_t i = 0; i < zh_vector_get_size(&_route_vector); ++i)
{
_routing_table_t *routing_table = zh_vector_get_item(&_route_vector, i);
if (memcmp(queue.data.original_target_mac, routing_table->original_target_mac, 6) == 0)
{
ESP_LOGI(TAG, "Routing to MAC %02X:%02X:%02X:%02X:%02X:%02X is received.", MAC2STR(queue.data.original_target_mac));
if (queue.data.message_type == UNICAST)
{
ESP_LOGI(TAG, "Unicast message from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X removed from routing waiting list and added to queue.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac));
}
if (queue.data.message_type == DELIVERY_CONFIRM)
{
ESP_LOGI(TAG, "System message for message receiving confirmation from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X removed from routing waiting list and added to queue.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac));
}
queue.id = TO_SEND;
if (xQueueSend(_queue_handle, &queue, portTICK_PERIOD_MS) != pdTRUE)
{
ESP_LOGE(TAG, "ESP-NOW message processing task internal error at line %d.", __LINE__);
}
flag = true;
break;
}
}
if (flag == false)
{
if ((esp_timer_get_time() / 1000 - queue.time) > _init_config.max_waiting_time)
{
ESP_LOGW(TAG, "Time for waiting routing to MAC %02X:%02X:%02X:%02X:%02X:%02X is expired.", MAC2STR(queue.data.original_target_mac));
if (memcmp(queue.data.original_sender_mac, _self_mac, 6) == 0)
{
zh_network_event_on_send_t *on_send = heap_caps_malloc(sizeof(zh_network_event_on_send_t), MALLOC_CAP_8BIT);
if (on_send == NULL)
{
ESP_LOGE(TAG, "ESP-NOW message processing task internal error at line %d.", __LINE__);
heap_caps_free(on_send);
break;
}
memset(on_send, 0, sizeof(zh_network_event_on_send_t));
memcpy(on_send->mac_addr, queue.data.original_target_mac, 6);
on_send->status = ZH_NETWORK_SEND_FAIL;
ESP_LOGE(TAG, "Unicast message from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X sent fail.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac));
ESP_LOGI(TAG, "Unicast message from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X removed from routing waiting list.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac));
if (esp_event_post(ZH_NETWORK, ZH_NETWORK_ON_SEND_EVENT, on_send, sizeof(zh_network_event_on_send_t), portTICK_PERIOD_MS) != ESP_OK)
{
ESP_LOGE(TAG, "ESP-NOW message processing task internal error at line %d.", __LINE__);
}
heap_caps_free(on_send);
}
else
{
if (queue.data.message_type == UNICAST)
{
ESP_LOGI(TAG, "Unicast message from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X removed from routing waiting list.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac));
}
if (queue.data.message_type == DELIVERY_CONFIRM)
{
ESP_LOGI(TAG, "System message for message receiving confirmation from MAC %02X:%02X:%02X:%02X:%02X:%02X to MAC %02X:%02X:%02X:%02X:%02X:%02X removed from routing waiting list.", MAC2STR(queue.data.original_sender_mac), MAC2STR(queue.data.original_target_mac));
}
}
break;
}
if (xQueueSend(_queue_handle, &queue, portTICK_PERIOD_MS) != pdTRUE)
{
ESP_LOGE(TAG, "ESP-NOW message processing task internal error at line %d.", __LINE__);
}
}
break;
default:
break;
}
}
vTaskDelete(NULL);
}