Add API to connect to a host, and to send messages over socket

This commit is contained in:
2024-07-03 17:08:03 +02:00
parent 72f2851f2b
commit 0f18551e62
2 changed files with 111 additions and 14 deletions

View File

@@ -27,7 +27,7 @@ struct lwip_event_packet_t
struct netif *netif;
};
typedef struct
struct udp_api_call_t
{
struct tcpip_api_call_data call;
udp_pcb * pcb;
@@ -36,7 +36,24 @@ typedef struct
struct pbuf *pb;
struct netif *netif;
err_t err;
} udp_api_call_t;
};
err_t _udp_connect_api(struct tcpip_api_call_data *api_call_msg)
{
udp_api_call_t *msg = (udp_api_call_t *)api_call_msg;
msg->err = udp_connect(msg->pcb, msg->addr, msg->port);
return msg->err;
}
err_t _udp_connect(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_connect_api, (struct tcpip_api_call_data *)&msg);
return msg.err;
}
err_t _udp_bind_api(struct tcpip_api_call_data *api_call_msg)
{
@@ -55,6 +72,22 @@ err_t _udp_bind(struct udp_pcb *pcb, const ip_addr_t *addr, u16_t port)
return msg.err;
}
err_t _udp_send_api(struct tcpip_api_call_data *api_call_msg)
{
udp_api_call_t *msg = (udp_api_call_t *)api_call_msg;
msg->err = udp_send(msg->pcb, msg->pb);
return msg->err;
}
err_t _udp_send(struct udp_pcb *pcb, struct pbuf *pb)
{
udp_api_call_t msg;
msg.pcb = pcb;
msg.pb = pb;
tcpip_api_call(_udp_send_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;
@@ -147,16 +180,8 @@ std::expected<UdpPacketWrapper, std::string> makeUdpPacketWrapper(pbufUniquePtr
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 (!ensureQueue())
return false;
close();
@@ -173,9 +198,9 @@ bool AsyncUdpListener::listen(const ip_addr_t *addr, uint16_t port)
}
// ESP_LOGI(TAG, "calling udp_bind()...");
if (_udp_bind(_pcb, addr, port) != ERR_OK)
if (const auto err = _udp_bind(_pcb, addr, port); err != ERR_OK)
{
ESP_LOGE(TAG, "failed to bind");
ESP_LOGE(TAG, "bind() failed with %i", err);
return false;
}
@@ -184,6 +209,56 @@ bool AsyncUdpListener::listen(const ip_addr_t *addr, uint16_t port)
return true;
}
bool AsyncUdpListener::connect(ip_addr_t ip, uint16_t port)
{
if (!ensureQueue())
return false;
close();
if (!_init())
{
ESP_LOGE(TAG, "failed to init");
return false;
}
// ESP_LOGI(TAG, "calling udp_connect()...");
if (const auto err = _udp_connect(_pcb, &ip, port); err != ERR_OK)
{
ESP_LOGE(TAG, "connect() failed with %i", err);
return false;
}
_connected = true;
return true;
}
bool AsyncUdpListener::connect(esp_ip_addr_t ip, uint16_t port)
{
return connect(wifi_stack::convertIp(ip), port);
}
bool AsyncUdpListener::send(std::string_view buffer)
{
auto pbt = pbufUniquePtr{pbuf_alloc(PBUF_TRANSPORT, buffer.size(), PBUF_RAM), pbuf_free};
if (!pbt)
{
ESP_LOGE(TAG, "could not allocate pbf");
return false;
}
std::memcpy(pbt->payload, buffer.data(), buffer.size());
if (const auto err = _udp_send(_pcb, pbt.get()); err != ERR_OK)
{
ESP_LOGE(TAG, "send() failed with %i", err);
return false;
}
return true;
}
std::optional<UdpPacketWrapper> AsyncUdpListener::poll(TickType_t xTicksToWait)
{
if (!_udp_queue.constructed())
@@ -280,6 +355,22 @@ void AsyncUdpListener::close()
}
}
bool AsyncUdpListener::ensureQueue()
{
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;
}
}
return true;
}
bool AsyncUdpListener::_init()
{
if (!_pcb)

View File

@@ -90,6 +90,11 @@ public:
return listen(IP_ANY_TYPE, port);
}
bool connect(ip_addr_t ip, uint16_t port);
bool connect(esp_ip_addr_t ip, uint16_t port);
bool send(std::string_view buffer);
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);
@@ -97,6 +102,7 @@ public:
void close();
private:
bool ensureQueue();
bool _init();
private: