Skip to content
Snippets Groups Projects
Commit ef440370 authored by fxk8y's avatar fxk8y :spider:
Browse files

adding callbacks to UDP server

parent 697747af
No related branches found
No related tags found
1 merge request!9Adding callbacks to UDP server
This commit is part of merge request !9. Comments created here will be created in the context of that merge request.
#include <qthing.h>
#include <map>
#include "esp_log.h"
#include "lwip/err.h"
......@@ -11,9 +13,38 @@ static const char *TAG = "udp-server";
static const in_port_t PORT = 4213;
static std::map<uint32_t, qthing::udpPacketCallback> packetCallbackMap;
void qthing::addUDPPacketCallback(uint32_t magicNumber, qthing::udpPacketCallback callback) {
if (packetCallbackMap.count(magicNumber) > 0) {
qthing::udpPacketCallback old_callback = packetCallbackMap.at(magicNumber);
packetCallbackMap[magicNumber] = [old_callback, callback](udpPacket packet) {
old_callback(packet);
callback(packet);
};
} else {
packetCallbackMap[magicNumber] = callback;
}
ESP_LOGI(TAG, "Registered callback for packets with magic number 0x%08X", magicNumber);
}
std::string to_string(struct sockaddr_in6 sourceAddr) {
char addr_str[128];
if (sourceAddr.sin6_family == PF_INET) {
inet_ntoa_r(((struct sockaddr_in *)&sourceAddr)->sin_addr.s_addr, addr_str, sizeof(addr_str) - 1);
} else if (sourceAddr.sin6_family == PF_INET6) {
inet6_ntoa_r(sourceAddr.sin6_addr, addr_str, sizeof(addr_str) - 1);
}
return(std::string(addr_str));
}
static char rx_buffer[2048]; // TODO: get MTU
static void udp_server_task(void *pvParameters)
{
char rx_buffer[128];
char addr_str[128];
int addr_family;
int ip_protocol;
......@@ -39,10 +70,9 @@ static void udp_server_task(void *pvParameters)
ESP_LOGE(TAG, "Socket unable to bind: errno %d", errno);
}
ESP_LOGI(TAG, "Socket bound");
ESP_LOGI(TAG, "Waiting for data");
while (true) {
ESP_LOGI(TAG, "Waiting for data");
struct sockaddr_in6 sourceAddr; // Large enough for both IPv4 or IPv6
socklen_t socklen = sizeof(sourceAddr);
......@@ -55,21 +85,30 @@ static void udp_server_task(void *pvParameters)
}
// Data received
else {
// Get the sender's ip address as string
if (sourceAddr.sin6_family == PF_INET) {
inet_ntoa_r(((struct sockaddr_in *)&sourceAddr)->sin_addr.s_addr, addr_str, sizeof(addr_str) - 1);
} else if (sourceAddr.sin6_family == PF_INET6) {
inet6_ntoa_r(sourceAddr.sin6_addr, addr_str, sizeof(addr_str) - 1);
}
rx_buffer[len] = 0; // Null-terminate whatever we received and treat like a string...
ESP_LOGI(TAG, "Received %d bytes from %s:", len, addr_str);
ESP_LOGI(TAG, "%s", rx_buffer);
int err = sendto(sock, rx_buffer, len, 0, (struct sockaddr *)&sourceAddr, sizeof(sourceAddr));
if (err < 0) {
ESP_LOGE(TAG, "Error occured during sending: errno %d", errno);
break;
ESP_LOGI(TAG, "Received %d bytes from %s:", len, to_string(sourceAddr).c_str());
if (len >= sizeof(uint32_t)) {
uint32_t magicNumber = rx_buffer[0] << 24 |
rx_buffer[1] << 16 |
rx_buffer[2] << 8 |
rx_buffer[3];
qthing::udpPacket packet = {
.sourceAddr = sourceAddr,
.payload = rx_buffer + 4,
.length = (uint16_t)(len - 4)
};
auto iterator = packetCallbackMap.find(magicNumber);
if (iterator != packetCallbackMap.end()) {
auto callback = iterator->second;
callback(packet);
} else {
ESP_LOGW(TAG, "Packet has unknown magic number 0x%08X", magicNumber);
}
} else {
ESP_LOGW(TAG, "Packet is too small, cannot determine magic number");
}
}
}
......@@ -85,4 +124,4 @@ static void udp_server_task(void *pvParameters)
void start_udp_server() {
xTaskCreate(udp_server_task, "udp_server", 4096, NULL, 5, NULL);
}
\ No newline at end of file
}
......@@ -7,6 +7,10 @@
#include <functional>
#include "driver/gpio.h"
#include "lwip/sockets.h"
// undefining IPADDR_NONE from lwip because it is redefined in arduino
#undef INADDR_NONE
// types
enum pull_resistor_t { none, pullup, pulldown };
......@@ -105,10 +109,22 @@ namespace qthing {
typedef std::function<void()> ntp_callback_t;
void enable_ntp(std::string address = "pool.ntp.org", std::string timezone = "CET-1CEST,M3.5.0,M10.5.0/3", qthing::ntp_callback_t callback = NULL);
typedef struct {
struct sockaddr_in6 sourceAddr;
const char* payload;
const uint16_t length;
} udpPacket;
typedef std::function<void(udpPacket)> udpPacketCallback;
void addUDPPacketCallback(uint32_t magicNumber, udpPacketCallback callback);
void start_udp_server();
}
// utility
std::string to_string(float value, int precision = 2);
std::string to_string(uint32_t value);
std::string to_string(struct sockaddr_in6 sourceAddr);
#endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment