From d8716c232ebb2ae7b9889fc846c1fd907dbe58b1 Mon Sep 17 00:00:00 2001 From: simon Date: Sat, 23 Aug 2025 21:14:18 +0200 Subject: [PATCH] Updated Message Handling to new MessageBroker --- main/communication_handler.c | 331 +++++++++++++++++++---------------- main/communication_handler.h | 4 +- main/espnow_handler.c | 0 main/espnow_handler.h | 0 main/main.c | 1 + 5 files changed, 180 insertions(+), 156 deletions(-) create mode 100644 main/espnow_handler.c create mode 100644 main/espnow_handler.h diff --git a/main/communication_handler.c b/main/communication_handler.c index d6566e1..f9a6279 100644 --- a/main/communication_handler.c +++ b/main/communication_handler.c @@ -1,3 +1,4 @@ +#include "esp_err.h" #include "esp_log.h" #include "esp_now.h" #include "esp_timer.h" @@ -16,6 +17,25 @@ static const char *TAG = "ALOX - COM"; static struct ESP_MessageBroker mr; static QueueHandle_t ESP_recieved_message_queue; +void free_ESPNOW_MessageInfo(ESPNOW_MessageInfo *msg) { + if (msg->esp_now_info.src_addr) { + free(msg->esp_now_info.src_addr); + msg->esp_now_info.src_addr = NULL; + } + if (msg->esp_now_info.des_addr) { + free(msg->esp_now_info.des_addr); + msg->esp_now_info.des_addr = NULL; + } + if (msg->esp_now_info.rx_ctrl) { + free(msg->esp_now_info.rx_ctrl); + msg->esp_now_info.rx_ctrl = NULL; + } + if (msg->data) { + free(msg->data); + msg->data = NULL; + } +} + void ESP_InitMessageBroker(QueueHandle_t msg_queue_handle) { mr.num_direct_callbacks = 0; mr.num_task_callbacks = 0; @@ -59,12 +79,14 @@ void ESP_MessageBrokerTask(void *param) { const BaseMessage *message = (const BaseMessage *)received_msg.data; ESP_LOGI(TAG, "Broker searching for command page %d", message->commandPage); - for (int i = 0; i < mr.num_direct_callbacks; i++) { + for (int i = 0; i < mr.num_direct_callbacks; + i++) { // TODO: there should not be a loop needed here if (mr.FunctionList[i].MSGID == message->commandPage) { mr.FunctionList[i].callback(&received_msg.esp_now_info, received_msg.data, received_msg.data_len); ESP_LOGI(TAG, "Broker found matching msgid %d", mr.FunctionList[i].MSGID); + free_ESPNOW_MessageInfo(&received_msg); } } for (int i = 0; i < mr.num_direct_callbacks; i++) { @@ -87,7 +109,7 @@ static uint8_t channelNumber = 0; int init_com(ClientList *clients, uint8_t wifi_channel) { // Initialisiere die Kommunikations-Warteschlange - messageQueue = xQueueCreate(MESSAGE_QUEUE_SIZE, sizeof(BaseMessage)); + messageQueue = xQueueCreate(MESSAGE_QUEUE_SIZE, sizeof(ESPNOW_MessageInfo)); if (messageQueue == NULL) { ESP_LOGE(TAG, "Message queue creation failed"); return -1; @@ -103,7 +125,7 @@ int add_peer(uint8_t *macAddr) { esp_now_peer_info_t peerInfo = { .channel = channelNumber, .ifidx = ESP_IF_WIFI_STA, - .encrypt = false, // Keine Verschlüsselung (kann geändert werden) + .encrypt = false, // Keine Verschlüsselung // TODO: should be changed }; memcpy(peerInfo.peer_addr, macAddr, ESP_NOW_ETH_ALEN); @@ -139,13 +161,11 @@ BaseMessage MessageBuilder(CommandPages commandPage, PayloadUnion payload, size_t payload_size) { BaseMessage message; - // Initialisierung der BaseMessage message.commandPage = commandPage; message.version = 1; message.length = (uint16_t)payload_size; - // Kopieren des Payloads in die Union - memset(&message.payload, 0, sizeof(message.payload)); // Sicherheitsmaßnahme + memset(&message.payload, 0, sizeof(message.payload)); memcpy(&message.payload, &payload, payload_size); return message; @@ -160,7 +180,8 @@ void master_broadcast_task(void *param) { ESP_ERROR_CHECK(esp_now_send(broadcast_address, (uint8_t *)&message, sizeof(BaseMessage))); - ESP_LOGI(TAG, "Broadcast Message sent"); + + // ESP_LOGI(TAG, "Broadcast Message sent"); vTaskDelay(pdMS_TO_TICKS(5000)); } } @@ -173,7 +194,7 @@ void master_broadcast_ping(void *param) { MessageBuilder(PingPage, *(PayloadUnion *)&payload, sizeof(payload)); ESP_ERROR_CHECK(esp_now_send(broadcast_address, (uint8_t *)&message, sizeof(BaseMessage))); - ESP_LOGI(TAG, "Broadcast PING Message sent"); + // ESP_LOGI(TAG, "Broadcast PING Message sent"); vTaskDelay(pdMS_TO_TICKS(2500)); } } @@ -236,15 +257,22 @@ void master_RegisterCallback(const esp_now_recv_info_t *esp_now_info, ESP_LOGI(TAG, "ESP ERR ESPNOW_ARG"); break; case (ESP_ERR_ESPNOW_NOT_FOUND): - ESP_LOGI(TAG, "CLIENT WIRD IN DIE LISTE AUFGENOMMEN"); - add_peer(esp_now_info->src_addr); + ESP_LOGI(TAG, "CLIENT WIRD IN DIE LISTE AUFGENOMMEN " MACSTR, + MAC2STR(esp_now_info->src_addr)); + int peer_err = add_peer(esp_now_info->src_addr); + if (peer_err < 0) { + ESP_LOGE(TAG, "Could not add ESP TO ClientList %d", peer_err); + } ESP_LOGI(TAG, "FRAGE CLIENT STATUS AN"); GetStatusPayload payload = {}; replyMessage = MessageBuilder(GetStatusPage, *(PayloadUnion *)&payload, sizeof(payload)); - ESP_ERROR_CHECK(esp_now_send( - esp_now_info->src_addr, (uint8_t *)&replyMessage, sizeof(BaseMessage))); + esp_err_t err = esp_now_send(esp_now_info->src_addr, + (uint8_t *)&replyMessage, sizeof(BaseMessage)); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Could not send Message Error %s", esp_err_to_name(err)); + } break; default: @@ -252,9 +280,102 @@ void master_RegisterCallback(const esp_now_recv_info_t *esp_now_info, } } +void master_pingCallback(const esp_now_recv_info_t *esp_now_info, + const uint8_t *data, int data_len) { + BaseMessage replyMessage = {}; + const BaseMessage *message = (const BaseMessage *)data; + + ESP_LOGI(TAG, "GOT PING MESSAGE"); + uint32_t currentTime = esp_timer_get_time(); + uint32_t diff = currentTime - message->payload.ping_payload.timestamp; + + ESP_LOGI(TAG, "Start: %lu, End: %lu, Diff: %lu, Ping: %lu", + message->payload.ping_payload.timestamp, currentTime, diff, + diff / 1000); // ping in ms + + int id = get_client_id(esp_client_list, esp_now_info->src_addr); + if (id >= 0) { + esp_client_list->Clients[id].lastSuccessfullPing = xTaskGetTickCount(); + esp_client_list->Clients[id].lastPing = (diff / 1000); + ESP_LOGI(TAG, "Updated client %d: " MACSTR " last ping time to %lu", id, + MAC2STR(esp_now_info->src_addr), + esp_client_list->Clients[id].lastSuccessfullPing); + } +} + +void master_broadcastCallback(const esp_now_recv_info_t *esp_now_info, + const uint8_t *data, int data_len) { + ESP_LOGI(TAG, + "Master should not recieve Broadcast is there another master " + "Calling got message from " MACSTR, + MAC2STR(esp_now_info->src_addr)); +} + void ESPNOW_RegisterMasterCallbacks() { ESP_RegisterFunction(StatusPage, master_StatusCallback); ESP_RegisterFunction(RegisterPage, master_RegisterCallback); + ESP_RegisterFunction(PingPage, master_pingCallback); + ESP_RegisterFunction(BroadCastPage, master_broadcastCallback); +} + +void slave_broadcastCallback(const esp_now_recv_info_t *esp_now_info, + const uint8_t *data, int data_len) { + BaseMessage replyMessage = {}; + const BaseMessage *message = (const BaseMessage *)data; + + ESP_LOGI(TAG, "GOT BROADCAST MESSAGE"); + if (!hasMaster) { + if (IS_BROADCAST_ADDR(esp_now_info->des_addr)) { + ESP_LOGI(TAG, "GOT BROADCAST MESSAGE ATTEMPTING TO REGISTER TO MASTER!"); + add_peer(esp_now_info->src_addr); + replyMessage = + MessageBuilder(RegisterPage, *(PayloadUnion *)&message->payload, + sizeof(message->payload)); + ESP_ERROR_CHECK(esp_now_send(esp_now_info->src_addr, + (uint8_t *)&replyMessage, + sizeof(BaseMessage))); + hasMaster = true; + } + } else { + ESP_LOGI(TAG, "Already have master wont register by the new one"); + } +} +void slave_getstatusCallback(const esp_now_recv_info_t *esp_now_info, + const uint8_t *data, int data_len) { + BaseMessage replyMessage = {}; + const BaseMessage *message = (const BaseMessage *)data; + + StatusPayload payload = { + .status = 1, + .runningPartition = 1, + .uptime = 100, + .version = 0x0002, + + }; + replyMessage = + MessageBuilder(StatusPage, *(PayloadUnion *)&payload, sizeof(payload)); + ESP_ERROR_CHECK(esp_now_send(esp_now_info->src_addr, (uint8_t *)&replyMessage, + sizeof(BaseMessage))); +} +void slave_pingCallback(const esp_now_recv_info_t *esp_now_info, + const uint8_t *data, int data_len) { + if (!hasMaster) + return; + + BaseMessage replyMessage = {}; + const BaseMessage *message = (const BaseMessage *)data; + + ESP_LOGI(TAG, "GOT PING MESSAGE"); + replyMessage = MessageBuilder(PingPage, *(PayloadUnion *)&message->payload, + sizeof(message->payload)); + ESP_ERROR_CHECK(esp_now_send(esp_now_info->src_addr, (uint8_t *)&replyMessage, + sizeof(BaseMessage))); +} + +void ESPNOW_RegisterSlaveCallbacks() { + ESP_RegisterFunction(BroadCastPage, slave_broadcastCallback); + ESP_RegisterFunction(GetStatusPage, slave_getstatusCallback); + ESP_RegisterFunction(PingPage, slave_pingCallback); } void master_receive_callback(const esp_now_recv_info_t *esp_now_info, @@ -269,6 +390,50 @@ void master_receive_callback(const esp_now_recv_info_t *esp_now_info, } memcpy(copied_data, data, data_len); + // Fülle die neue Struktur mit kopierten Daten + ESPNOW_MessageInfo msg_info; + msg_info.esp_now_info.src_addr = malloc(6); + if (msg_info.esp_now_info.src_addr) { + memcpy(msg_info.esp_now_info.src_addr, esp_now_info->src_addr, 6); + } + + // Speicher für des_addr kopieren + msg_info.esp_now_info.des_addr = malloc(6); + if (msg_info.esp_now_info.des_addr) { + memcpy(msg_info.esp_now_info.des_addr, esp_now_info->des_addr, 6); + } + + // rx_ctrl Struktur kopieren + msg_info.esp_now_info.rx_ctrl = malloc(sizeof(wifi_pkt_rx_ctrl_t)); + if (msg_info.esp_now_info.rx_ctrl) { + memcpy(msg_info.esp_now_info.rx_ctrl, esp_now_info->rx_ctrl, + sizeof(wifi_pkt_rx_ctrl_t)); + } + + msg_info.data = copied_data; + msg_info.data_len = data_len; + + if (xQueueSend(ESP_recieved_message_queue, &msg_info, portMAX_DELAY) != + pdPASS) { + // Fehlerbehandlung: Queue voll oder Senden fehlgeschlagen + ESP_LOGE(TAG, "Failed to send parsed message to queue."); + } + return; +} + +void client_receive_callback(const esp_now_recv_info_t *esp_now_info, + const uint8_t *data, int data_len) { + ESP_LOGI(TAG, "SLAVE GOT MESSAGE"); + ESP_LOGI(TAG, "Received message from: " MACSTR, + MAC2STR(esp_now_info->src_addr)); + + uint8_t *copied_data = (uint8_t *)malloc(data_len); + if (copied_data == NULL) { + ESP_LOGE(TAG, "Failed to allocate memory for message data."); + return; + } + memcpy(copied_data, data, data_len); + // Fülle die neue Struktur mit kopierten Daten ESPNOW_MessageInfo msg_info; memcpy(&msg_info.esp_now_info, esp_now_info, sizeof(esp_now_recv_info_t)); @@ -280,149 +445,7 @@ void master_receive_callback(const esp_now_recv_info_t *esp_now_info, // Fehlerbehandlung: Queue voll oder Senden fehlgeschlagen ESP_LOGE(TAG, "Failed to send parsed message to queue."); } - return; - // TODO: just testing if callback queue logic works here - - BaseMessage replyMessage = {}; - const BaseMessage *message = (const BaseMessage *)data; - int id; - switch (message->commandPage) { - case StatusPage: - ESP_LOGI(TAG, "GOT STATUS MESSAGE"); - id = get_client_id(esp_client_list, esp_now_info->src_addr); - if (id >= 0) { - esp_client_list->Clients[id].clientVersion = - message->payload.status_payload.version; - } - - break; - case PingPage: - ESP_LOGI(TAG, "GOT PING MESSAGE"); - uint32_t currentTime = esp_timer_get_time(); - uint32_t diff = currentTime - message->payload.ping_payload.timestamp; - - ESP_LOGI(TAG, "Start: %lu, End: %lu, Diff: %lu, Ping: %lu", - message->payload.ping_payload.timestamp, currentTime, diff, - diff / 1000); // ping in ms - - id = get_client_id(esp_client_list, esp_now_info->src_addr); - if (id >= 0) { - esp_client_list->Clients[id].lastSuccessfullPing = xTaskGetTickCount(); - esp_client_list->Clients[id].lastPing = (diff / 1000); - ESP_LOGI(TAG, "Updated client %d: " MACSTR " last ping time to %lu", id, - MAC2STR(esp_now_info->src_addr), - esp_client_list->Clients[id].lastSuccessfullPing); - } - break; - case BroadCastPage: - ESP_LOGI(TAG, "MASTER SHOULD NOT GET BROADCAST MESSAGE, is there another " - "master calling?"); - break; - case RegisterPage: - ESP_LOGI(TAG, "WILL REGISTER DEVICE"); - esp_now_peer_info_t checkPeerInfo; - esp_err_t checkPeer = - esp_now_get_peer(esp_now_info->src_addr, &checkPeerInfo); - switch (checkPeer) { - case (ESP_OK): - ESP_LOGI(TAG, "CLIENT BEKANNT"); - int id = get_client_id(esp_client_list, esp_now_info->src_addr); - esp_client_list->Clients[id].isAvailable = true; - esp_client_list->Clients[id].lastSuccessfullPing = xTaskGetTickCount(); - ESP_LOGI(TAG, "Updated client %d last ping time to %lu", id, - esp_client_list->Clients[id].lastSuccessfullPing); - break; - case (ESP_ERR_ESPNOW_NOT_INIT): - ESP_LOGI(TAG, "Not initalised"); - break; - case (ESP_ERR_ESPNOW_ARG): - ESP_LOGI(TAG, "ESP ERR ESPNOW_ARG"); - break; - case (ESP_ERR_ESPNOW_NOT_FOUND): - ESP_LOGI(TAG, "CLIENT WIRD IN DIE LISTE AUFGENOMMEN"); - add_peer(esp_now_info->src_addr); - ESP_LOGI(TAG, "FRAGE CLIENT STATUS AN"); - - GetStatusPayload payload = {}; - replyMessage = MessageBuilder(GetStatusPage, *(PayloadUnion *)&payload, - sizeof(payload)); - ESP_ERROR_CHECK(esp_now_send(esp_now_info->src_addr, - (uint8_t *)&replyMessage, - sizeof(BaseMessage))); - - break; - default: - ESP_LOGI(TAG, "Unknown Message %i", checkPeer); - } - break; - default: - ESP_LOGI(TAG, "Unknown CommandPage %i", message->commandPage); - break; - } -} - -void client_receive_callback(const esp_now_recv_info_t *esp_now_info, - const uint8_t *data, int data_len) { - ESP_LOGI(TAG, "SLAVE GOT MESSAGE"); - ESP_LOGI(TAG, "Received message from: " MACSTR, - MAC2STR(esp_now_info->src_addr)); - ESP_LOGI(TAG, "Message: %.*s", data_len, data); - - BaseMessage replyMessage = {}; - - const BaseMessage *message = (const BaseMessage *)data; - switch (message->commandPage) { - case StatusPage: - ESP_LOGI(TAG, "GOT STATUS MESSAGE"); - break; - case GetStatusPage: { - StatusPayload payload = { - .status = 1, - .runningPartition = 1, - .uptime = 100, - .version = 0x0002, - - }; - replyMessage = - MessageBuilder(StatusPage, *(PayloadUnion *)&payload, sizeof(payload)); - ESP_ERROR_CHECK(esp_now_send( - esp_now_info->src_addr, (uint8_t *)&replyMessage, sizeof(BaseMessage))); - - } break; - case PingPage: - ESP_LOGI(TAG, "GOT PING MESSAGE"); - replyMessage = MessageBuilder(PingPage, *(PayloadUnion *)&message->payload, - sizeof(message->payload)); - ESP_ERROR_CHECK(esp_now_send( - esp_now_info->src_addr, (uint8_t *)&replyMessage, sizeof(BaseMessage))); - break; - case BroadCastPage: - ESP_LOGI(TAG, "GOT BROADCAST MESSAGE"); - if (!hasMaster) { - if (IS_BROADCAST_ADDR(esp_now_info->des_addr)) { - ESP_LOGI(TAG, - "GOT BROADCAST MESSAGE ATTEMPTING TO REGISTER TO MASTER!"); - add_peer(esp_now_info->src_addr); - replyMessage = - MessageBuilder(RegisterPage, *(PayloadUnion *)&message->payload, - sizeof(message->payload)); - ESP_ERROR_CHECK(esp_now_send(esp_now_info->src_addr, - (uint8_t *)&replyMessage, - sizeof(BaseMessage))); - hasMaster = true; - } - break; - } - // check if its an update message - - break; - case RegisterPage: - break; - default: - ESP_LOGI(TAG, "GOT UNKONW MESSAGE"); - break; - } } void client_data_sending_task(void *param) { diff --git a/main/communication_handler.h b/main/communication_handler.h index d94aa15..fa65b06 100644 --- a/main/communication_handler.h +++ b/main/communication_handler.h @@ -144,7 +144,7 @@ typedef struct { typedef struct { esp_now_recv_info_t esp_now_info; - const uint8_t *data; + uint8_t *data; int data_len; } ESPNOW_MessageInfo; @@ -155,7 +155,7 @@ void ESP_RegisterTask(CommandPages command, ESP_RegisterTaskCallback callback); void ESP_MessageBrokerTask(void *param); void ESPNOW_RegisterMasterCallbacks(); - +void ESPNOW_RegisterSlaveCallbacks(); int init_com(ClientList *clients, uint8_t wifi_channel); int getNextFreeClientId(); diff --git a/main/espnow_handler.c b/main/espnow_handler.c new file mode 100644 index 0000000..e69de29 diff --git a/main/espnow_handler.h b/main/espnow_handler.h new file mode 100644 index 0000000..e69de29 diff --git a/main/main.c b/main/main.c index e21e2c7..6e88c3a 100644 --- a/main/main.c +++ b/main/main.c @@ -306,6 +306,7 @@ void app_main(void) { // NULL); } else { ESP_LOGI(TAG, "Started in Slavemode"); + ESPNOW_RegisterSlaveCallbacks(); // xTaskCreate(client_data_sending_task, "ClientDataSending", 4096, NULL, 1, // NULL); }