Removed AsyncUdpListener again

This commit is contained in:
2021-10-14 20:21:10 +02:00
parent 39af218aed
commit 34792268a8
4 changed files with 0 additions and 444 deletions

View File

@@ -1,5 +1,4 @@
set(headers
src/asyncudplistener.h
src/espwifistack.h
src/espwifistackconfig.h
src/espwifistackenums.h
@@ -8,7 +7,6 @@ set(headers
)
set(sources
src/asyncudplistener.cpp
src/espwifistack.cpp
src/espwifistackenums.cpp
src/espwifiutils.cpp

View File

@@ -1,41 +1,5 @@
menu "ESP WiFi Stack settings"
choice LOG_LOCAL_LEVEL_ASYNC_UDP_LISTENER
bool "ASYNC_UDP_LISTENER log verbosity"
default LOG_LOCAL_LEVEL_ASYNC_UDP_LISTENER_INFO
help
Specify how much output to compile into the binary.
You can set lower verbosity level at runtime using
esp_log_level_set function.
Note that this setting limits which log statements
are compiled into the program. So setting this to,
say, "Warning" would mean that changing log level
to "Debug" at runtime will not be possible.
config LOG_LOCAL_LEVEL_ASYNC_UDP_LISTENER_NONE
bool "No output"
config LOG_LOCAL_LEVEL_ASYNC_UDP_LISTENER_ERROR
bool "Error"
config LOG_LOCAL_LEVEL_ASYNC_UDP_LISTENER_WARN
bool "Warning"
config LOG_LOCAL_LEVEL_ASYNC_UDP_LISTENER_INFO
bool "Info"
config LOG_LOCAL_LEVEL_ASYNC_UDP_LISTENER_DEBUG
bool "Debug"
config LOG_LOCAL_LEVEL_ASYNC_UDP_LISTENER_VERBOSE
bool "Verbose"
endchoice
config LOG_LOCAL_LEVEL_ASYNC_UDP_LISTENER
int
default 0 if LOG_LOCAL_LEVEL_ASYNC_UDP_LISTENER_NONE
default 1 if LOG_LOCAL_LEVEL_ASYNC_UDP_LISTENER_ERROR
default 2 if LOG_LOCAL_LEVEL_ASYNC_UDP_LISTENER_WARN
default 3 if LOG_LOCAL_LEVEL_ASYNC_UDP_LISTENER_INFO
default 4 if LOG_LOCAL_LEVEL_ASYNC_UDP_LISTENER_DEBUG
default 5 if LOG_LOCAL_LEVEL_ASYNC_UDP_LISTENER_VERBOSE
choice LOG_LOCAL_LEVEL_WIFI_STACK
bool "WIFI_STACK log verbosity"
default LOG_LOCAL_LEVEL_WIFI_STACK_INFO

View File

@@ -1,297 +0,0 @@
#include "asyncudplistener.h"
#include "sdkconfig.h"
#define LOG_LOCAL_LEVEL CONFIG_LOG_LOCAL_LEVEL_ASYNC_UDP_LISTENER
// system includes
#include <cassert>
// esp-idf includes
#include <lwip/priv/tcpip_priv.h>
#include <lwip/prot/ethernet.h>
#include <esp_log.h>
namespace wifi_stack {
namespace {
constexpr const char * const TAG = "ASYNC_UDP_LISTENER";
struct lwip_event_packet_t
{
udp_pcb *pcb;
pbufUniquePtr pb;
const ip_addr_t *addr;
uint16_t port;
struct netif *netif;
};
typedef struct
{
struct tcpip_api_call_data call;
udp_pcb * pcb;
const ip_addr_t *addr;
uint16_t port;
struct pbuf *pb;
struct netif *netif;
err_t err;
} udp_api_call_t;
err_t _udp_bind_api(struct tcpip_api_call_data *api_call_msg)
{
udp_api_call_t *msg = (udp_api_call_t *)api_call_msg;
msg->err = udp_bind(msg->pcb, msg->addr, msg->port);
return msg->err;
}
err_t _udp_bind(struct udp_pcb *pcb, const ip_addr_t *addr, u16_t port)
{
udp_api_call_t msg;
msg.pcb = pcb;
msg.addr = addr;
msg.port = port;
tcpip_api_call(_udp_bind_api, (struct tcpip_api_call_data*)&msg);
return msg.err;
}
err_t _udp_disconnect_api(struct tcpip_api_call_data *api_call_msg)
{
udp_api_call_t *msg = (udp_api_call_t *)api_call_msg;
msg->err = 0;
udp_disconnect(msg->pcb);
return msg->err;
}
void _udp_disconnect(struct udp_pcb *pcb)
{
udp_api_call_t msg;
msg.pcb = pcb;
tcpip_api_call(_udp_disconnect_api, (struct tcpip_api_call_data*)&msg);
}
void _udp_recv(void *arg, udp_pcb *pcb, pbuf *pb, const ip_addr_t *addr, uint16_t port)
{
if (!arg)
{
ESP_LOGW(TAG, "called without arg");
return;
}
auto *_this = reinterpret_cast<AsyncUdpListener*>(arg);
_this->_udp_task_post(pcb, pb, addr, port, ip_current_input_netif());
}
UdpPacketWrapper makeUdpPacketWrapper(pbufUniquePtr &&_pb, const ip_addr_t *raddr, uint16_t rport, struct netif *_ntif)
{
assert(_pb);
auto payload = reinterpret_cast<const char *>(_pb->payload);
uint16_t _localPort;
uint16_t _remotePort;
{
const udp_hdr *udphdr = reinterpret_cast<const udp_hdr*>(payload - UDP_HLEN);
_localPort = ntohs(udphdr->dest);
_remotePort = ntohs(udphdr->src);
}
const eth_hdr *ethHdr{};
//memcpy(&_remoteIp, raddr, sizeof(ip_addr_t));
ip_addr_t _localAddr { .type = raddr->type };
ip_addr_t _remoteAddr { .type = raddr->type };
switch (_remoteAddr.type)
{
case IPADDR_TYPE_V4:
{
ethHdr = reinterpret_cast<const eth_hdr *>(payload - UDP_HLEN - IP_HLEN - SIZEOF_ETH_HDR);
const ip_hdr *iphdr = reinterpret_cast<const ip_hdr *>(payload - UDP_HLEN - IP_HLEN);
_localAddr.u_addr.ip4.addr = iphdr->dest.addr;
_remoteAddr.u_addr.ip4.addr = iphdr->src.addr;
break;
}
case IPADDR_TYPE_V6:
{
ethHdr = reinterpret_cast<const eth_hdr *>(payload - UDP_HLEN - IP6_HLEN - SIZEOF_ETH_HDR);
const ip6_hdr *ip6hdr = reinterpret_cast<const ip6_hdr *>(payload - UDP_HLEN - IP6_HLEN);
std::copy(std::cbegin(ip6hdr->dest.addr), std::cend(ip6hdr->dest.addr), std::begin(_localAddr.u_addr.ip6.addr));
std::copy(std::cbegin(ip6hdr->src.addr), std::cend(ip6hdr->src.addr), std::begin(_remoteAddr.u_addr.ip6.addr));
break;
}
default:
ESP_LOGW(TAG, "unknown ip type %i", _remoteAddr.type);
}
std::string_view _data{payload, _pb->len};
return UdpPacketWrapper{
._pb = std::move(_pb),
._data = _data,
._ntif = _ntif,
._local = { .addr = _localAddr, .port = _localPort },
._remote = { .addr = _remoteAddr, .port = _remotePort },
._remoteMac = ethHdr ? wifi_stack::mac_t{ethHdr->src.addr} : wifi_stack::mac_t{}
};
}
} // namespace
tcpip_adapter_if_t UdpPacketWrapper::tcpIpAdapter() const
{
for (int i = 0; i < TCPIP_ADAPTER_IF_MAX; i++)
{
tcpip_adapter_if_t tcpip_if = tcpip_adapter_if_t(i);
struct netif *nif{};
if (const auto result = tcpip_adapter_get_netif(tcpip_if, &nif); result != ESP_OK)
{
ESP_LOGW(TAG, "tcpip_adapter_get_netif() failed with %s", esp_err_to_name(result));
continue;
}
if (nif && nif == _ntif)
return tcpip_if;
}
return TCPIP_ADAPTER_IF_MAX;
}
bool AsyncUdpListener::listen(const ip_addr_t *addr, uint16_t port)
{
if (!_udp_queue.constructed())
{
_udp_queue.construct(UBaseType_t{32}, sizeof(lwip_event_packet_t *));
if (!_udp_queue->handle)
{
_udp_queue.destruct();
ESP_LOGE(TAG, "xQueueCreate failed");
return false;
}
}
if (!_init())
{
ESP_LOGE(TAG, "failed to init");
return false;
}
close();
if (addr)
{
IP_SET_TYPE_VAL(_pcb->local_ip, addr->type);
IP_SET_TYPE_VAL(_pcb->remote_ip, addr->type);
}
if (_udp_bind(_pcb, addr, port) != ERR_OK)
{
ESP_LOGE(TAG, "failed to bind");
return false;
}
_connected = true;
return true;
}
std::optional<UdpPacketWrapper> AsyncUdpListener::poll(TickType_t xTicksToWait)
{
if (!_udp_queue.constructed())
{
ESP_LOGW(TAG, "queue not constructed");
return std::nullopt;
}
lwip_event_packet_t *ePtr{};
if (const auto result = _udp_queue->receive(&ePtr, xTicksToWait); result != pdTRUE)
{
//ESP_LOGE(TAG, "_udp_queue->receive() failed with %i", result);
return std::nullopt;
}
if (!ePtr)
{
ESP_LOGE(TAG, "invalid ptr from queue received");
return std::nullopt;
}
std::unique_ptr<lwip_event_packet_t> e{ePtr};
if (!e->pb)
{
ESP_LOGE(TAG, "invalid pb");
return std::nullopt;
}
// we can only return 1, so no linked lists please
assert(!e->pb->next);
//udp_pcb *upcb = e->pcb;
const ip_addr_t *addr = e->addr;
uint16_t port = e->port;
struct netif *netif = e->netif;
return makeUdpPacketWrapper(std::move(e->pb), addr, port, netif);
}
void AsyncUdpListener::_udp_task_post(udp_pcb *_pcb, pbuf *pb, const ip_addr_t *_addr, uint16_t _port, struct netif *_netif)
{
if (!_udp_queue.constructed())
{
ESP_LOGW(TAG, "queue not constructed");
return;
}
while (pb)
{
pbufUniquePtr this_pb{pb, pbuf_free};
pb = pb->next;
this_pb->next = nullptr;
auto e = std::unique_ptr<lwip_event_packet_t>{new lwip_event_packet_t{
.pcb = _pcb,
.pb = std::move(this_pb),
.addr = _addr,
.port = _port,
.netif = _netif
}};
auto ptr = e.get();
if (const auto result = _udp_queue->send(&ptr, portMAX_DELAY); result != pdPASS)
{
ESP_LOGE(TAG, "_udp_queue->send failed with %i", result);
continue;
}
// queue takes ownership
e.release();
}
}
bool AsyncUdpListener::_init()
{
if (_pcb)
return true;
_pcb = udp_new();
if (!_pcb)
{
ESP_LOGE(TAG, "udp_new() failed");
return false;
}
udp_recv(_pcb, &_udp_recv, (void *)this);
return true;
}
void AsyncUdpListener::close()
{
if (_pcb)
{
if (_connected)
_udp_disconnect(_pcb);
_connected = false;
}
}
} // namespace wifi_stack

View File

@@ -1,109 +0,0 @@
#pragma once
// system includes
#include <cstring>
#include <optional>
#include <array>
#include <string_view>
#include <memory>
// esp-idf includes
#include <lwip/ip_addr.h>
#include <lwip/udp.h>
#include <lwip/pbuf.h>
#include <esp_netif.h>
// local includes
#include "cppmacros.h"
#include "delayedconstruction.h"
#include "espwifiutils.h"
#include "wrappers/queue.h"
namespace wifi_stack {
using pbufUniquePtr = std::unique_ptr<pbuf, decltype(&pbuf_free)>;
struct UdpPacketWrapper
{
//UdpPacketWrapper(pbufUniquePtr &&pb, const ip_addr_t *addr, uint16_t port, struct netif * netif);
~UdpPacketWrapper() = default;
UdpPacketWrapper(UdpPacketWrapper &&other) = default;
UdpPacketWrapper(const UdpPacketWrapper &other) = delete;
UdpPacketWrapper &operator=(UdpPacketWrapper &&other) = default;
UdpPacketWrapper &operator=(const UdpPacketWrapper &other) = delete;
auto data() const { return _data; }
tcpip_adapter_if_t tcpIpAdapter() const;
struct netif *ntif() const { return _ntif; }
bool isBroadcast() const { return ip_addr_isbroadcast(&(_local.addr), _ntif); }
bool isMulticast() const { return ip_addr_ismulticast(&(_local.addr)); }
ip_addr_t localAddr() const { return _local.addr; }
uint16_t localPort() const { return _local.port; }
ip_addr_t remoteAddr() const { return _remote.addr; }
uint16_t remotePort() const { return _remote.port; }
wifi_stack::mac_t remoteMac() const { return _remoteMac; }
pbufUniquePtr _pb;
std::string_view _data;
struct netif *_ntif;
struct {
ip_addr_t addr;
uint16_t port;
} _local, _remote;
wifi_stack::mac_t _remoteMac;
};
class AsyncUdpListener
{
CPP_DISABLE_COPY_MOVE(AsyncUdpListener)
public:
AsyncUdpListener() = default;
bool listen(const ip_addr_t *addr, uint16_t port);
// bool listen(const IPAddress addr, uint16_t port)
// {
// ip_addr_t laddr;
// laddr.type = IPADDR_TYPE_V4;
// laddr.u_addr.ip4.addr = addr;
// return listen(&laddr, port);
// }
// bool listen(const IPv6Address addr, uint16_t port)
// {
// ip_addr_t laddr;
// laddr.type = IPADDR_TYPE_V6;
// memcpy((uint8_t*)(laddr.u_addr.ip6.addr), (const uint8_t*)addr, 16);
// return listen(&laddr, port);
// }
bool listen(uint16_t port)
{
return listen(IP_ANY_TYPE, port);
}
std::optional<UdpPacketWrapper> poll(TickType_t xTicksToWait = 0);
void _udp_task_post(udp_pcb *pcb, pbuf *pb, const ip_addr_t *addr, uint16_t port, struct netif *netif);
private:
bool _init();
void close();
private:
cpputils::DelayedConstruction<espcpputils::queue> _udp_queue;
udp_pcb *_pcb{};
bool _connected{};
};
} // namespace wifi_stack