Fixed Bug in UART Protokol
This commit is contained in:
parent
beef75f31c
commit
50ee8009fc
54
main/client_handler.c
Normal file
54
main/client_handler.c
Normal file
@ -0,0 +1,54 @@
|
||||
#include "client_handler.h"
|
||||
#include "communication_handler.h"
|
||||
#include "esp_log.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
int get_client_id(ClientList *list, const uint8_t *client_mac) {
|
||||
for (int i = 0; i < MAX_CLIENTS; i++) {
|
||||
if (memcmp(client_mac, list->Clients[i].macAddr, MAC_LENGTH) == 0) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return CLIENT_DOES_NOT_EXISTS;
|
||||
}
|
||||
|
||||
// TODO: Sanity check when list full then list->count should be MAX_CLIENTS
|
||||
int get_next_free_slot(ClientList *list) {
|
||||
for (int i = 0; i < MAX_CLIENTS; i++) {
|
||||
// if slot is not used return index
|
||||
if (!list->Clients[i].slotIsUsed) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
// list is full
|
||||
return CLIENT_LIST_FULL;
|
||||
}
|
||||
|
||||
int add_client(ClientList *list, const uint8_t *client_mac) {
|
||||
if (get_client_id(list, client_mac) >= 0) {
|
||||
// Client already exists dont add to list
|
||||
return CLIENT_EXISTS;
|
||||
}
|
||||
|
||||
int slot = get_next_free_slot(list);
|
||||
if (slot < 0) {
|
||||
// Client list full
|
||||
return CLIENT_LIST_FULL;
|
||||
}
|
||||
|
||||
list->Clients[slot].slotIsUsed = true;
|
||||
list->Clients[slot].isAvailable = true;
|
||||
memcpy(list->Clients[slot].macAddr, client_mac, MAC_LENGTH);
|
||||
list->ClientCount++;
|
||||
return CLIENT_OK;
|
||||
}
|
||||
|
||||
int remove_client(ClientList *list, const uint8_t client_id) {
|
||||
if (client_id >= MAX_CLIENTS)
|
||||
return CLIENT_INVALID_ID; // invalid index
|
||||
list->Clients[client_id].slotIsUsed = false;
|
||||
list->ClientCount--;
|
||||
return CLIENT_OK;
|
||||
}
|
||||
43
main/client_handler.h
Normal file
43
main/client_handler.h
Normal file
@ -0,0 +1,43 @@
|
||||
#ifndef CLIENT_HANDLER_H
|
||||
#define CLIENT_HANDLER_H
|
||||
|
||||
#include "portmacro.h"
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/_intsup.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#define MAX_CLIENTS 16
|
||||
#define MAC_LENGTH 6
|
||||
|
||||
enum ClientErrors {
|
||||
CLIENT_OK = 0,
|
||||
CLIENT_EXISTS = -1,
|
||||
CLIENT_DOES_NOT_EXISTS = -2,
|
||||
CLIENT_LIST_FULL = -3,
|
||||
CLIENT_INVALID_ID = -4,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
bool slotIsUsed;
|
||||
bool isAvailable;
|
||||
uint8_t clientID;
|
||||
uint8_t macAddr[MAC_LENGTH];
|
||||
TickType_t lastSuccessfullPing;
|
||||
TickType_t lastPing;
|
||||
} ClientInfo;
|
||||
|
||||
typedef struct {
|
||||
ClientInfo Clients[MAX_CLIENTS];
|
||||
uint8_t ClientCount;
|
||||
} ClientList;
|
||||
|
||||
int get_client_id(ClientList *list, const uint8_t *client_mac);
|
||||
int add_client(ClientList *list, const uint8_t *client_mac);
|
||||
int remove_client(ClientList *list, const uint8_t clientid);
|
||||
int get_next_free_slot(ClientList *list);
|
||||
|
||||
#endif
|
||||
@ -1,41 +1,33 @@
|
||||
#include "esp_log.h"
|
||||
#include "esp_now.h"
|
||||
#include "esp_timer.h"
|
||||
#include "freertos/idf_additions.h"
|
||||
|
||||
#include "client_handler.h"
|
||||
#include "communication_handler.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static const char *TAG = "ALOX - COM";
|
||||
|
||||
QueueHandle_t messageQueue = NULL; // Warteschlange für empfangene Nachrichten
|
||||
ClientInfo clients[MAX_CLIENTS] = {
|
||||
0}; // Clients statisch initialisieren, alle auf 0 gesetzt
|
||||
size_t numClients = 0;
|
||||
size_t activeClients = 0;
|
||||
bool hasMaster = false;
|
||||
static ClientList *esp_client_list;
|
||||
|
||||
void init_com() {
|
||||
#define MAC_STRING_BUFFER_SIZE 18
|
||||
|
||||
void init_com(ClientList *clients) {
|
||||
// Initialisiere die Kommunikations-Warteschlange
|
||||
messageQueue = xQueueCreate(MESSAGE_QUEUE_SIZE, sizeof(BaseMessage));
|
||||
if (messageQueue == NULL) {
|
||||
ESP_LOGE(TAG, "Message queue creation failed");
|
||||
}
|
||||
|
||||
// Weitere Initialisierungen, falls nötig
|
||||
numClients = 0;
|
||||
activeClients = 0;
|
||||
esp_client_list = clients;
|
||||
hasMaster = false;
|
||||
}
|
||||
|
||||
// return any inactive client field for new usage
|
||||
int getNextFreeClientId() {
|
||||
for (int i = 0; i < MAX_CLIENTS; i++) {
|
||||
if (!clients[i].isAvailable) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void add_peer(uint8_t *macAddr) {
|
||||
esp_now_peer_info_t peerInfo = {
|
||||
.channel =
|
||||
@ -53,41 +45,29 @@ void add_peer(uint8_t *macAddr) {
|
||||
peerInfo.peer_addr[4], peerInfo.peer_addr[5]);
|
||||
|
||||
if (!IS_BROADCAST_ADDR(macAddr)) {
|
||||
|
||||
if (numClients >= MAX_CLIENTS) {
|
||||
ESP_LOGW(TAG, "Cannot add more clients, maximum reached.");
|
||||
return;
|
||||
int ret = add_client(esp_client_list, peerInfo.peer_addr);
|
||||
if (ret < 0) {
|
||||
ESP_LOGE(TAG, "Client could not be added to client handler, removing "
|
||||
"it from esp now client list!");
|
||||
esp_now_del_peer(peerInfo.peer_addr);
|
||||
}
|
||||
|
||||
ClientInfo newClient = {};
|
||||
memcpy(newClient.macAddr, macAddr, ESP_NOW_ETH_ALEN);
|
||||
newClient.isAvailable = true;
|
||||
newClient.lastSuccessfullPing = xTaskGetTickCount();
|
||||
newClient.lastPing = 0;
|
||||
clients[getNextFreeClientId()] = newClient;
|
||||
ESP_LOGI(TAG, "New client added.");
|
||||
}
|
||||
} else if (result == ESP_ERR_ESPNOW_EXIST) {
|
||||
ESP_LOGW(TAG, "Peer already exists.");
|
||||
// Überprüfen, ob der Client bereits existiert
|
||||
for (int i = 0; i < numClients; i++) {
|
||||
if (memcmp(clients[i].macAddr, macAddr, ESP_NOW_ETH_ALEN) == 0) {
|
||||
ESP_LOGI(TAG, "Client found again, welcome back!");
|
||||
clients[i].isAvailable = true; // Reaktiviere den Client
|
||||
break;
|
||||
}
|
||||
int id = get_client_id(esp_client_list, peerInfo.peer_addr);
|
||||
if (id >= 0) {
|
||||
ESP_LOGI(TAG, "Client found again, welcome back!");
|
||||
esp_client_list->Clients[id].isAvailable = true;
|
||||
}
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Failed to add peer: %s", esp_err_to_name(result));
|
||||
}
|
||||
}
|
||||
|
||||
// UNSAFE ACCROSS THREADS BUT EZ TO USE
|
||||
const char *MACtoString(uint8_t *macAddr) {
|
||||
static char output[18]; // 17 Zeichen + 1 für Nullterminierung
|
||||
sprintf(output, "%02X:%02X:%02X:%02X:%02X:%02X", macAddr[0], macAddr[1],
|
||||
void MACtoString(const uint8_t *macAddr, char *outputBuffer) {
|
||||
sprintf(outputBuffer, "%02X:%02X:%02X:%02X:%02X:%02X", macAddr[0], macAddr[1],
|
||||
macAddr[2], macAddr[3], macAddr[4], macAddr[5]);
|
||||
return output;
|
||||
}
|
||||
|
||||
BaseMessage MessageBuilder(CommandPages commandPage, PayloadUnion payload,
|
||||
@ -135,16 +115,17 @@ void master_broadcast_ping(void *param) {
|
||||
}
|
||||
|
||||
void master_ping_task(void *param) {
|
||||
char macBuffer[MAC_STRING_BUFFER_SIZE];
|
||||
while (1) {
|
||||
for (size_t i = 0; i < MAX_CLIENTS; i++) {
|
||||
if (clients[i].isAvailable) {
|
||||
ESP_LOGI(TAG, "SEND PING TO %zu: %s", i,
|
||||
MACtoString(clients[i].macAddr));
|
||||
if (esp_client_list->Clients[i].isAvailable) {
|
||||
MACtoString(esp_client_list->Clients[i].macAddr, macBuffer);
|
||||
ESP_LOGI(TAG, "SEND PING TO %zu: %s", i, macBuffer);
|
||||
PingPayload payload = {};
|
||||
payload.timestamp = esp_timer_get_time();
|
||||
BaseMessage message = MessageBuilder(
|
||||
PingPage, *(PayloadUnion *)&payload, sizeof(payload));
|
||||
esp_now_send(clients[i].macAddr, (uint8_t *)&message,
|
||||
esp_now_send(esp_client_list->Clients[i].macAddr, (uint8_t *)&message,
|
||||
sizeof(BaseMessage));
|
||||
ESP_LOGI(TAG, "SENDING PING!!!!");
|
||||
}
|
||||
@ -155,6 +136,7 @@ void master_ping_task(void *param) {
|
||||
|
||||
void master_receive_callback(const esp_now_recv_info_t *esp_now_info,
|
||||
const uint8_t *data, int data_len) {
|
||||
char macBuffer[MAC_STRING_BUFFER_SIZE];
|
||||
ESP_LOGI(TAG, "MASTER GOT MESSAGE");
|
||||
|
||||
const BaseMessage *message = (const BaseMessage *)data;
|
||||
@ -171,18 +153,13 @@ void master_receive_callback(const esp_now_recv_info_t *esp_now_info,
|
||||
message->payload.ping_payload.timestamp, currentTime, diff,
|
||||
diff / 1000); // ping in ms
|
||||
|
||||
for (int i = 0; i < MAX_CLIENTS; i++) {
|
||||
// Überprüfen, ob der Client existiert und die MAC-Adresse übereinstimmt
|
||||
if (clients[i].isAvailable &&
|
||||
memcmp(clients[i].macAddr, esp_now_info->src_addr,
|
||||
ESP_NOW_ETH_ALEN) == 0) {
|
||||
clients[i].lastSuccessfullPing = xTaskGetTickCount();
|
||||
clients[i].lastPing = (diff/1000);
|
||||
ESP_LOGI(TAG, "Updated client %d: %s last ping time to %lu", i,
|
||||
MACtoString(clients[i].macAddr),
|
||||
clients[i].lastSuccessfullPing);
|
||||
break;
|
||||
}
|
||||
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);
|
||||
MACtoString(esp_now_info->src_addr, macBuffer);
|
||||
ESP_LOGI(TAG, "Updated client %d: %s last ping time to %lu", id,
|
||||
macBuffer, esp_client_list->Clients[id].lastSuccessfullPing);
|
||||
}
|
||||
break;
|
||||
case BroadCastPage:
|
||||
@ -197,18 +174,11 @@ void master_receive_callback(const esp_now_recv_info_t *esp_now_info,
|
||||
switch (checkPeer) {
|
||||
case (ESP_OK):
|
||||
ESP_LOGI(TAG, "CLIENT BEKANNT");
|
||||
for (int i = 0; i < MAX_CLIENTS; i++) {
|
||||
// client in liste wiederfinden
|
||||
if (!clients[i].isAvailable &&
|
||||
memcmp(clients[i].macAddr, esp_now_info->src_addr,
|
||||
ESP_NOW_ETH_ALEN) == 0) {
|
||||
clients[i].isAvailable = true;
|
||||
clients[i].lastSuccessfullPing = xTaskGetTickCount();
|
||||
ESP_LOGI(TAG, "Updated client %d last ping time to %lu", i,
|
||||
clients[i].lastSuccessfullPing);
|
||||
break;
|
||||
}
|
||||
}
|
||||
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");
|
||||
@ -229,14 +199,12 @@ void master_receive_callback(const esp_now_recv_info_t *esp_now_info,
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void client_receive_callback(const esp_now_recv_info_t *esp_now_info,
|
||||
const uint8_t *data, int data_len) {
|
||||
char macBuffer[MAC_STRING_BUFFER_SIZE];
|
||||
ESP_LOGI(TAG, "SLAVE GOT MESSAGE");
|
||||
ESP_LOGI(TAG, "Received message from: %02X:%02X:%02X:%02X:%02X:%02X",
|
||||
esp_now_info->src_addr[0], esp_now_info->src_addr[1],
|
||||
esp_now_info->src_addr[2], esp_now_info->src_addr[3],
|
||||
esp_now_info->src_addr[4], esp_now_info->src_addr[5]);
|
||||
MACtoString(esp_now_info->src_addr, macBuffer);
|
||||
ESP_LOGI(TAG, "Received message from: %s", macBuffer);
|
||||
ESP_LOGI(TAG, "Message: %.*s", data_len, data);
|
||||
|
||||
BaseMessage replyMessage = {};
|
||||
@ -289,6 +257,7 @@ void client_data_sending_task(void *param) {
|
||||
}
|
||||
|
||||
void client_monitor_task(void *pvParameters) {
|
||||
char macBuffer[MAC_STRING_BUFFER_SIZE];
|
||||
TickType_t timeout_ticks =
|
||||
pdMS_TO_TICKS(CLIENT_TIMEOUT_MS); // Timeout in Ticks
|
||||
TickType_t interval_ticks =
|
||||
@ -298,18 +267,15 @@ void client_monitor_task(void *pvParameters) {
|
||||
TickType_t now = xTaskGetTickCount(); // Aktuelle Zeit in Ticks
|
||||
|
||||
for (int i = 0; i < MAX_CLIENTS; i++) {
|
||||
if (clients[i].isAvailable) {
|
||||
TickType_t time_diff = now - clients[i].lastSuccessfullPing;
|
||||
if (esp_client_list->Clients[i].isAvailable) {
|
||||
TickType_t time_diff =
|
||||
now - esp_client_list->Clients[i].lastSuccessfullPing;
|
||||
|
||||
// Prüfen, ob der Client als "nicht verfügbar" markiert werden soll
|
||||
if (time_diff > timeout_ticks) {
|
||||
clients[i].isAvailable = false;
|
||||
ESP_LOGW(
|
||||
TAG,
|
||||
"Client %d (MAC: %02X:%02X:%02X:%02X:%02X:%02X) is unavailable",
|
||||
i, clients[i].macAddr[0], clients[i].macAddr[1],
|
||||
clients[i].macAddr[2], clients[i].macAddr[3],
|
||||
clients[i].macAddr[4], clients[i].macAddr[5]);
|
||||
esp_client_list->Clients[i].isAvailable = false;
|
||||
MACtoString(esp_client_list->Clients[i].macAddr, macBuffer);
|
||||
ESP_LOGW(TAG, "Client %d (MAC: %s) is unavailable", macBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -318,7 +284,3 @@ void client_monitor_task(void *pvParameters) {
|
||||
vTaskDelay(interval_ticks);
|
||||
}
|
||||
}
|
||||
|
||||
ClientInfo *get_client_info(int entry) {
|
||||
return &clients[entry];
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
#ifndef COMMUNICATION_HANDLER_H
|
||||
#define COMMUNICATION_HANDLER_H
|
||||
|
||||
#include "client_handler.h"
|
||||
#include <esp_now.h>
|
||||
#include <esp_wifi.h>
|
||||
#include <freertos/FreeRTOS.h>
|
||||
@ -16,11 +17,10 @@
|
||||
#define CLIENT_TIMEOUT_MS 5000 // 5 Sekunden Timeout
|
||||
#define CHECK_INTERVAL_MS 1000 // Jede Sekunde überprüfen
|
||||
static uint8_t broadcast_address[ESP_NOW_ETH_ALEN] = {0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF};
|
||||
0xFF, 0xFF, 0xFF};
|
||||
#define IS_BROADCAST_ADDR(addr) \
|
||||
(memcmp(addr, broadcast_address, ESP_NOW_ETH_ALEN) == 0)
|
||||
|
||||
#define MAX_CLIENTS 19
|
||||
#define MESSAGE_QUEUE_SIZE 10
|
||||
|
||||
typedef enum {
|
||||
@ -63,18 +63,10 @@ typedef struct {
|
||||
static_assert(sizeof(BaseMessage) <= 255,
|
||||
"BaseMessage darf nicht größer als 255 sein");
|
||||
|
||||
typedef struct {
|
||||
uint8_t macAddr[ESP_NOW_ETH_ALEN];
|
||||
int rssi;
|
||||
bool isAvailable;
|
||||
TickType_t lastSuccessfullPing;
|
||||
TickType_t lastPing;
|
||||
} ClientInfo;
|
||||
|
||||
void init_com();
|
||||
void init_com(ClientList *clients);
|
||||
int getNextFreeClientId();
|
||||
void add_peer(uint8_t *macAddr);
|
||||
const char *MACtoString(uint8_t *macAddr);
|
||||
void MACtoString(const uint8_t *macAddr, char *outputBuffer);
|
||||
BaseMessage MessageBuilder(CommandPages commandPage, PayloadUnion payload,
|
||||
size_t payload_size);
|
||||
|
||||
@ -89,6 +81,4 @@ void client_receive_callback(const esp_now_recv_info_t *esp_now_info,
|
||||
void client_data_sending_task(void *param);
|
||||
void client_monitor_task(void *pvParameters);
|
||||
|
||||
ClientInfo *get_client_info(int entry);
|
||||
|
||||
#endif
|
||||
|
||||
131
main/main.c
131
main/main.c
@ -1,3 +1,4 @@
|
||||
#include "client_handler.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/uart.h"
|
||||
#include "esp_log.h"
|
||||
@ -11,6 +12,7 @@
|
||||
#include "message_parser.h"
|
||||
#include "nvs_flash.h"
|
||||
|
||||
#include "glob.h"
|
||||
#include "communication_handler.h"
|
||||
#include "main.h"
|
||||
#include "portmacro.h"
|
||||
@ -23,23 +25,44 @@
|
||||
|
||||
#include "message_builder.h"
|
||||
|
||||
typedef struct {
|
||||
QueueHandle_t message_queue;
|
||||
uint8_t *send_buffer;
|
||||
size_t send_buffer_size;
|
||||
} MessageBrokerTaskParams_t;
|
||||
|
||||
static const char *TAG = "ALOX - MAIN";
|
||||
static const uint16_t version = 0x0001;
|
||||
static uint8_t send_message_buffer[1024];
|
||||
static MessageBrokerTaskParams_t broker_task_params;
|
||||
|
||||
void echoCallback(uint8_t msgid, const uint8_t *payload, size_t payload_len) {
|
||||
ClientList clientList = {.Clients = {{0}}, .ClientCount = 0};
|
||||
|
||||
typedef void (*RegisterTaskCallback)(uint8_t msgid, const uint8_t *payload,
|
||||
size_t payload_len, uint8_t *send_buffer,
|
||||
size_t send_buffer_size);
|
||||
|
||||
void echoCallback(uint8_t msgid, const uint8_t *payload, size_t payload_len,
|
||||
uint8_t *send_buffer, size_t send_buffer_size) {
|
||||
// Code für den Button-Press
|
||||
ESP_LOGI(TAG, "Echo command 0x01...");
|
||||
uint8_t send_buffer[64];
|
||||
size_t len = build_message(0x01, payload, payload_len, send_buffer,
|
||||
sizeof(send_buffer));
|
||||
int len =
|
||||
build_message(0x01, payload, payload_len, send_buffer, send_buffer_size);
|
||||
if (len < 0) {
|
||||
ESP_LOGE(TAG,
|
||||
"Error Building UART Message: payload_len, %d, sendbuffer_size: "
|
||||
"%d, mes_len(error): %d",
|
||||
payload_len, send_buffer_size, len);
|
||||
return;
|
||||
}
|
||||
|
||||
uart_write_bytes(MASTER_UART, send_buffer, len);
|
||||
}
|
||||
|
||||
void versionCallback(uint8_t msgid, const uint8_t *payload,
|
||||
size_t payload_len) {
|
||||
void versionCallback(uint8_t msgid, const uint8_t *payload, size_t payload_len,
|
||||
uint8_t *send_buffer, size_t send_buffer_size) {
|
||||
// Code für den Button-Press
|
||||
ESP_LOGI(TAG, "Version command 0x02...");
|
||||
uint8_t send_buffer[64];
|
||||
size_t git_build_hash_len = strlen(BUILD_GIT_HASH);
|
||||
|
||||
uint8_t send_payload[2 + git_build_hash_len];
|
||||
@ -47,8 +70,74 @@ void versionCallback(uint8_t msgid, const uint8_t *payload,
|
||||
send_payload[1] = (uint8_t)((version >> 8) & 0xFF);
|
||||
memcpy(&send_payload[2], &BUILD_GIT_HASH, git_build_hash_len);
|
||||
|
||||
size_t len = build_message(0x02, send_payload, sizeof(send_payload),
|
||||
send_buffer, sizeof(send_buffer));
|
||||
int len = build_message(0x02, send_payload, sizeof(send_payload), send_buffer,
|
||||
send_buffer_size);
|
||||
if (len < 0) {
|
||||
ESP_LOGE(TAG,
|
||||
"Error Building UART Message: payload_len, %d, sendbuffer_size: "
|
||||
"%d, mes_len(error): %d",
|
||||
payload_len, send_buffer_size, len);
|
||||
return;
|
||||
}
|
||||
uart_write_bytes(MASTER_UART, send_buffer, len);
|
||||
}
|
||||
|
||||
void clientInfoCallback(uint8_t msgid, const uint8_t *payload,
|
||||
size_t payload_len, uint8_t *send_buffer,
|
||||
size_t send_buffer_size) {
|
||||
ESP_LOGI(TAG, "Client Info Command 0x03...");
|
||||
static uint8_t entryLength = 17;
|
||||
|
||||
ESP_LOGE(TAG, "clientList.ClientCount = %d", clientList.ClientCount);
|
||||
|
||||
uint8_t payload_size = 1 + entryLength * clientList.ClientCount;
|
||||
|
||||
ESP_LOGE(TAG, "payload_size = %d", payload_size);
|
||||
|
||||
uint8_t send_payload[payload_size];
|
||||
send_payload[0] = clientList.ClientCount;
|
||||
uint8_t offsetMult = 0;
|
||||
|
||||
uint8_t used_slots = 0;
|
||||
for (int i = 0; i < MAX_CLIENTS; i++) {
|
||||
if (clientList.Clients[i].slotIsUsed) {
|
||||
used_slots++;
|
||||
}
|
||||
}
|
||||
ESP_LOGE("SPECIAL", "USED SLOTS: %d", used_slots);
|
||||
|
||||
uint8_t loop_sanity_counter = 0;
|
||||
|
||||
for (int i = 0; i < MAX_CLIENTS; i++) {
|
||||
if (clientList.Clients[i].slotIsUsed) {
|
||||
loop_sanity_counter++;
|
||||
if (loop_sanity_counter > clientList.ClientCount) {
|
||||
ESP_LOGE("SPECIAL", "DAS KANN NICHT SEIN");
|
||||
ESP_LOGE("SPECIAL", "loop_santy_count: %d, client_count: %d", loop_sanity_counter, clientList.ClientCount);
|
||||
}
|
||||
size_t offset = 1 + (entryLength * offsetMult++);
|
||||
|
||||
ESP_LOGE("SPECIAL", "OFFSET %d", offset);
|
||||
send_payload[offset] = i;
|
||||
send_payload[offset + 1] = clientList.Clients[i].isAvailable;
|
||||
send_payload[offset + 2] = clientList.Clients[i].slotIsUsed;
|
||||
memcpy(&send_payload[offset + 3], clientList.Clients[i].macAddr,
|
||||
MAC_LENGTH);
|
||||
memcpy(&send_payload[offset + 9], &clientList.Clients[i].lastPing, 4);
|
||||
memcpy(&send_payload[offset + 13],
|
||||
&clientList.Clients[i].lastSuccessfullPing, 4);
|
||||
}
|
||||
}
|
||||
|
||||
int len = build_message(0x04, send_payload, sizeof(send_payload), send_buffer,
|
||||
send_buffer_size);
|
||||
if (len < 0) {
|
||||
ESP_LOGE(TAG,
|
||||
"Error Building UART Message: payload_len, %d, sendbuffer_size: "
|
||||
"%d, mes_len(error): %d",
|
||||
payload_len, send_buffer_size, len);
|
||||
return;
|
||||
}
|
||||
uart_write_bytes(MASTER_UART, send_buffer, len);
|
||||
}
|
||||
|
||||
@ -81,8 +170,8 @@ void app_main(void) {
|
||||
// denselben Kanal verwenden
|
||||
},
|
||||
};
|
||||
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
|
||||
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
|
||||
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
|
||||
ESP_ERROR_CHECK(esp_wifi_start());
|
||||
ESP_ERROR_CHECK(esp_now_init());
|
||||
|
||||
@ -92,36 +181,42 @@ void app_main(void) {
|
||||
ESP_ERROR_CHECK(esp_now_register_recv_cb(client_receive_callback));
|
||||
}
|
||||
|
||||
init_com();
|
||||
init_com(&clientList);
|
||||
|
||||
// Tasks starten basierend auf Master/Client
|
||||
if (isMaster) {
|
||||
ESP_LOGI(TAG, "Started in Mastermode");
|
||||
add_peer(broadcast_address);
|
||||
// xTaskCreate(master_broadcast_task, "MasterBroadcast", 4096, NULL, 1,
|
||||
// NULL);
|
||||
xTaskCreate(master_broadcast_task, "MasterBroadcast", 4096, NULL, 1, NULL);
|
||||
// xTaskCreate(master_ping_task, "MasterPing", 4096, NULL, 1, NULL);
|
||||
// xTaskCreate(master_broadcast_ping, "MasterBroadcastPing", 4096, NULL, 1,
|
||||
// NULL);
|
||||
xTaskCreate(master_broadcast_ping, "MasterBroadcastPing", 4096, NULL, 1,
|
||||
NULL);
|
||||
// xTaskCreate(client_monitor_task, "MonitorClientTask", 4096, NULL, 1,
|
||||
// NULL);
|
||||
|
||||
QueueHandle_t parsed_message_queue =
|
||||
xQueueCreate(10, sizeof(ParsedMessage_t));
|
||||
init_uart(parsed_message_queue);
|
||||
InitMessageBroker();
|
||||
|
||||
// Initialisiere die Parameterstruktur
|
||||
broker_task_params.message_queue = parsed_message_queue;
|
||||
broker_task_params.send_buffer = send_message_buffer;
|
||||
broker_task_params.send_buffer_size = sizeof(send_message_buffer);
|
||||
|
||||
xTaskCreate(MessageBrokerTask, "message_handler_task", 4096,
|
||||
(void *)&parsed_message_queue, 5, NULL);
|
||||
(void *)&broker_task_params, 5, NULL);
|
||||
|
||||
RegisterCallback(0x01, echoCallback);
|
||||
RegisterCallback(0x02, versionCallback);
|
||||
RegisterCallback(0x03, clientInfoCallback);
|
||||
|
||||
// xTaskCreate(uart_status_task, "MasterUartStatusTask", 4096, NULL, 1,
|
||||
// NULL); xTaskCreate(SendClientInfoTask, "SendCientInfo", 4096, NULL, 1,
|
||||
// NULL);
|
||||
} else {
|
||||
ESP_LOGI(TAG, "Started in Slavemode");
|
||||
//xTaskCreate(client_data_sending_task, "ClientDataSending", 4096, NULL, 1,
|
||||
// NULL);
|
||||
xTaskCreate(client_data_sending_task, "ClientDataSending", 4096, NULL, 1,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
#include "message_builder.h"
|
||||
#include "esp_log.h"
|
||||
#include "message_parser.h"
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
@ -7,8 +8,8 @@ bool needs_stuffing_byte(uint8_t byte) {
|
||||
return (byte == StartByte || byte == EscapeByte || byte == EndByte);
|
||||
}
|
||||
|
||||
bool add_byte_with_length_check(uint8_t byte, uint8_t write_index,
|
||||
uint8_t *data, uint8_t max_length) {
|
||||
bool add_byte_with_length_check(uint8_t byte, size_t write_index, uint8_t *data,
|
||||
size_t max_length) {
|
||||
if (write_index >= max_length) {
|
||||
return false;
|
||||
}
|
||||
@ -19,6 +20,8 @@ bool add_byte_with_length_check(uint8_t byte, uint8_t write_index,
|
||||
int build_message(uint8_t msgid, const uint8_t *payload, size_t payload_len,
|
||||
uint8_t *msg_buffer, size_t msg_buffer_size) {
|
||||
|
||||
ESP_LOGE("BM", "payload_len %d, msg_buffer_size %d", payload_len + 4,
|
||||
msg_buffer_size);
|
||||
if (payload_len + 4 > msg_buffer_size) {
|
||||
return PayloadBiggerThenBuffer;
|
||||
}
|
||||
@ -72,5 +75,6 @@ int build_message(uint8_t msgid, const uint8_t *payload, size_t payload_len,
|
||||
msg_buffer[write_index++] = checksum;
|
||||
msg_buffer[write_index++] = EndByte;
|
||||
|
||||
ESP_LOGE("BM", "MESSAGE FERTIG GEBAUT");
|
||||
return write_index;
|
||||
}
|
||||
|
||||
@ -6,6 +6,12 @@
|
||||
static struct MessageBroker mr;
|
||||
static char *TAG = "ALOX - Message Handler";
|
||||
|
||||
typedef struct {
|
||||
QueueHandle_t message_queue;
|
||||
uint8_t *send_buffer;
|
||||
size_t send_buffer_size;
|
||||
} MessageBrokerTaskParams_t;
|
||||
|
||||
void InitMessageBroker() {
|
||||
mr.num_direct_callbacks = 0;
|
||||
mr.num_task_callbacks = 0;
|
||||
@ -28,7 +34,12 @@ void RegisterTask(uint8_t msgid, RegisterTaskCallback callback) {
|
||||
|
||||
void MessageBrokerTask(void *param) {
|
||||
ParsedMessage_t received_msg;
|
||||
QueueHandle_t msg_queue = *(QueueHandle_t *)param;
|
||||
MessageBrokerTaskParams_t *task_params = (MessageBrokerTaskParams_t *)param;
|
||||
|
||||
// Extrahiere die einzelnen Parameter
|
||||
QueueHandle_t msg_queue = task_params->message_queue;
|
||||
uint8_t *send_message_buffer = task_params->send_buffer;
|
||||
size_t send_message_buffer_size = task_params->send_buffer_size;
|
||||
|
||||
if (msg_queue == NULL) {
|
||||
ESP_LOGE(TAG, "Message queue not initialized. Terminating task.");
|
||||
@ -44,8 +55,9 @@ void MessageBrokerTask(void *param) {
|
||||
|
||||
for (int i = 0; i < mr.num_direct_callbacks; i++) {
|
||||
if (mr.FunctionList[i].MSGID == received_msg.msgid) {
|
||||
mr.FunctionList[i].callback(received_msg.msgid, received_msg.data,
|
||||
received_msg.payload_len);
|
||||
mr.FunctionList[i].callback(
|
||||
received_msg.msgid, received_msg.data, received_msg.payload_len,
|
||||
send_message_buffer, send_message_buffer_size);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < mr.num_direct_callbacks; i++) {
|
||||
|
||||
@ -6,9 +6,12 @@
|
||||
#include <stdint.h>
|
||||
|
||||
typedef void (*RegisterFunctionCallback)(uint8_t msgid, const uint8_t *payload,
|
||||
size_t payload_len);
|
||||
size_t payload_len,
|
||||
uint8_t *send_buffer,
|
||||
size_t send_buffer_size);
|
||||
typedef void (*RegisterTaskCallback)(uint8_t msgid, const uint8_t *payload,
|
||||
size_t payload_len);
|
||||
size_t payload_len, uint8_t *send_buffer,
|
||||
size_t send_buffer_size);
|
||||
|
||||
struct RegisterdFunction {
|
||||
uint8_t MSGID;
|
||||
|
||||
@ -1283,9 +1283,9 @@ CONFIG_HAL_DEFAULT_ASSERTION_LEVEL=2
|
||||
#
|
||||
# Heap memory debugging
|
||||
#
|
||||
CONFIG_HEAP_POISONING_DISABLED=y
|
||||
# CONFIG_HEAP_POISONING_DISABLED is not set
|
||||
# CONFIG_HEAP_POISONING_LIGHT is not set
|
||||
# CONFIG_HEAP_POISONING_COMPREHENSIVE is not set
|
||||
CONFIG_HEAP_POISONING_COMPREHENSIVE=y
|
||||
CONFIG_HEAP_TRACING_OFF=y
|
||||
# CONFIG_HEAP_TRACING_STANDALONE is not set
|
||||
# CONFIG_HEAP_TRACING_TOHOST is not set
|
||||
|
||||
1908
sdkconfig.old
Normal file
1908
sdkconfig.old
Normal file
File diff suppressed because it is too large
Load Diff
115
tools/message_builder.py
Normal file
115
tools/message_builder.py
Normal file
@ -0,0 +1,115 @@
|
||||
import enum
|
||||
|
||||
START_BYTE = 0xAA
|
||||
ESCAPE_BYTE = 0xBB
|
||||
END_BYTE = 0xCC
|
||||
|
||||
|
||||
class MessageBuilderError(Exception):
|
||||
"""Basisklasse für Fehler des Message Builders."""
|
||||
pass
|
||||
|
||||
|
||||
class PayloadTooLargeError(MessageBuilderError):
|
||||
"""Ausnahme, wenn der Payload zu groß für den Puffer ist."""
|
||||
|
||||
def __init__(self, required_size, buffer_size):
|
||||
super().__init__(f"Payload ({
|
||||
required_size} bytes) ist größer als der verfügbare Puffer ({buffer_size} bytes).")
|
||||
self.required_size = required_size
|
||||
self.buffer_size = buffer_size
|
||||
|
||||
|
||||
class BufferOverflowError(MessageBuilderError):
|
||||
"""Ausnahme, wenn der Puffer während des Bauens überläuft."""
|
||||
|
||||
def __init__(self, current_size, max_size, byte_to_add=None):
|
||||
msg = f"Pufferüberlauf: Aktuelle Größe {
|
||||
current_size}, Max. Größe {max_size}."
|
||||
if byte_to_add is not None:
|
||||
msg += f" Versuch, Byte 0x{byte_to_add:02X} hinzuzufügen."
|
||||
super().__init__(msg)
|
||||
self.current_size = current_size
|
||||
self.max_size = max_size
|
||||
self.byte_to_add = byte_to_add
|
||||
|
||||
|
||||
class MessageBuilder:
|
||||
"""
|
||||
Klasse zum Aufbau von UART-Nachrichten gemäß dem definierten Protokoll,
|
||||
inklusive Stuffing und Checksummenberechnung.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def _needs_stuffing_byte(self, byte: int) -> bool:
|
||||
"""
|
||||
Prüft, ob ein Byte ein Stuffing-Byte benötigt (d.h. ob es ein Steuerbyte ist).
|
||||
"""
|
||||
return (byte == START_BYTE or byte == ESCAPE_BYTE or byte == END_BYTE)
|
||||
|
||||
def _add_byte_with_length_check(self, byte: int, buffer: bytearray, max_length: int):
|
||||
"""
|
||||
Fügt ein Byte zum Puffer hinzu und prüft auf Pufferüberlauf.
|
||||
Löst BufferOverflowError aus, wenn der Puffer voll ist.
|
||||
"""
|
||||
if len(buffer) >= max_length:
|
||||
raise BufferOverflowError(len(buffer), max_length, byte)
|
||||
buffer.append(byte)
|
||||
|
||||
def build_message(self, msgid: int, payload: bytes, msg_buffer_size: int) -> bytes:
|
||||
"""
|
||||
Baut eine vollständige UART-Nachricht.
|
||||
|
||||
Args:
|
||||
msgid (int): Die Message ID (0-255).
|
||||
payload (bytes): Die Nutzdaten der Nachricht als Byte-Objekt.
|
||||
msg_buffer_size (int): Die maximale Größe des Ausgabepuffers.
|
||||
Dies ist die maximale Länge der *fertigen* Nachricht.
|
||||
|
||||
Returns:
|
||||
bytes: Die fertig aufgebaute Nachricht als Byte-Objekt.
|
||||
|
||||
Raises:
|
||||
PayloadTooLargeError: Wenn der Payload (mit Overhead) den Puffer überschreiten würde.
|
||||
BufferOverflowError: Wenn während des Bauens ein Pufferüberlauf auftritt.
|
||||
"""
|
||||
|
||||
if len(payload) + 4 > msg_buffer_size:
|
||||
raise PayloadTooLargeError(len(payload) + 4, msg_buffer_size)
|
||||
|
||||
checksum = 0
|
||||
msg_buffer = bytearray()
|
||||
|
||||
# 1. StartByte hinzufügen
|
||||
self._add_byte_with_length_check(
|
||||
START_BYTE, msg_buffer, msg_buffer_size)
|
||||
|
||||
# 2. Message ID hinzufügen (mit Stuffing)
|
||||
if self._needs_stuffing_byte(msgid):
|
||||
self._add_byte_with_length_check(
|
||||
ESCAPE_BYTE, msg_buffer, msg_buffer_size)
|
||||
self._add_byte_with_length_check(msgid, msg_buffer, msg_buffer_size)
|
||||
checksum ^= msgid
|
||||
|
||||
# 3. Payload-Bytes hinzufügen (mit Stuffing)
|
||||
for byte_val in payload:
|
||||
if self._needs_stuffing_byte(byte_val):
|
||||
self._add_byte_with_length_check(
|
||||
ESCAPE_BYTE, msg_buffer, msg_buffer_size)
|
||||
self._add_byte_with_length_check(
|
||||
byte_val, msg_buffer, msg_buffer_size)
|
||||
checksum ^= byte_val
|
||||
|
||||
# 4. Checksumme hinzufügen (mit Stuffing)
|
||||
if self._needs_stuffing_byte(checksum):
|
||||
self._add_byte_with_length_check(
|
||||
ESCAPE_BYTE, msg_buffer, msg_buffer_size)
|
||||
self._add_byte_with_length_check(checksum, msg_buffer, msg_buffer_size)
|
||||
|
||||
# 5. EndByte hinzufügen
|
||||
self._add_byte_with_length_check(END_BYTE, msg_buffer, msg_buffer_size)
|
||||
|
||||
# Konvertiere bytearray zu unveränderlichem bytes-Objekt
|
||||
return bytes(msg_buffer)
|
||||
Loading…
x
Reference in New Issue
Block a user