Compare commits

..

2 Commits

Author SHA1 Message Date
erki
cd331bfccb Fix sending out broadcast messages
Broadcast peer must be added to the peer list before being able to use it.
2023-06-11 18:55:25 +03:00
erki
cc36fc6676 Project configuration items. 2023-06-11 16:12:45 +03:00
2 changed files with 60 additions and 12 deletions

23
main/Kconfig.projbuild Normal file
View File

@ -0,0 +1,23 @@
menu "EspTunnel Configuration"
config ESPTNL_PMK
string "ESPNOW primary master key"
default "pmk1234567890123"
help
ESPNOW primary master key. Must be 16 bytes.
config ESPTNL_LMK
string "ESPNOW local master key"
default "lmk1234567890123"
help
ESPNOW local master key. Must be 16 bytes.
config ESPTNL_CHANNEL
int "Channel"
default 1
range 0 14
help
The channel for sending and receiving ESPNOW data.
endmenu

View File

@ -10,6 +10,7 @@
#include "esp_now.h" #include "esp_now.h"
#include "esp_wifi.h" #include "esp_wifi.h"
#include "esp_log.h" #include "esp_log.h"
#include "esp_wifi.h"
namespace namespace
{ {
@ -21,10 +22,18 @@ static const char* TAG = "Networking";
static_assert(std::is_standard_layout_v<EspNowEvent> && std::is_trivial_v<EspNowEvent>, static_assert(std::is_standard_layout_v<EspNowEvent> && std::is_trivial_v<EspNowEvent>,
"EspNowEvent is not compatible with a FreeRTOS queue."); "EspNowEvent is not compatible with a FreeRTOS queue.");
template<std::size_t N>
constexpr auto STR_LEN(const char (&s)[N])
{
return N;
}
static_assert(STR_LEN(CONFIG_ESPTNL_PMK) == ESP_NOW_KEY_LEN + 1, "CONFIG_ESPTNL_PMK must be of length 16 bytes + 1 null terminator.");
static_assert(STR_LEN(CONFIG_ESPTNL_LMK) == ESP_NOW_KEY_LEN + 1, "CONFIG_ESPTNL_LMK must be of length 16 bytes + 1 null terminator.");
QueueHandle_t s_esp_now_queue = nullptr; QueueHandle_t s_esp_now_queue = nullptr;
std::array<std::uint8_t, 128> s_rx_buffer; std::array<std::uint8_t, 128> s_rx_buffer;
std::variant<MacAddress, std::monostate> s_peer; std::variant<MacAddress, std::monostate> s_peer;
bool s_tx_inflight = false;
bool s_isBroadcastAddress(const std::uint8_t* mac) bool s_isBroadcastAddress(const std::uint8_t* mac)
{ {
@ -37,13 +46,28 @@ bool s_isBroadcastAddress(const esp_now_recv_info_t* sender)
return s_isBroadcastAddress(sender->src_addr); return s_isBroadcastAddress(sender->src_addr);
} }
bool s_addPeer(const MacAddress& peer_address)
{
esp_now_peer_info_t broadcast_peer;
std::memset(&broadcast_peer, 0, sizeof(broadcast_peer));
broadcast_peer.channel = CONFIG_ESPTNL_CHANNEL;
broadcast_peer.ifidx = WIFI_IF_STA;
broadcast_peer.encrypt = false;
std::memcpy(broadcast_peer.lmk, CONFIG_ESPTNL_LMK, ESP_NOW_KEY_LEN);
std::memcpy(broadcast_peer.peer_addr, peer_address.data(), peer_address.size());
auto successful = esp_now_add_peer(&broadcast_peer);
ESP_ERROR_CHECK_WITHOUT_ABORT(successful);
return successful == ESP_OK;
}
void s_cbEspNowSendComplete(const std::uint8_t* peer_mac, esp_now_send_status_t status) void s_cbEspNowSendComplete(const std::uint8_t* peer_mac, esp_now_send_status_t status)
{ {
s_tx_inflight = false;
EspNowEvent event = { EspNowEvent::MSG_SEND_COMPLETE, 0 }; EspNowEvent event = { EspNowEvent::MSG_SEND_COMPLETE, 0 };
xQueueSend(s_esp_now_queue, &event, 0); xQueueSend(s_esp_now_queue, &event, 0);
ESP_LOGD(TAG, "Send complete. s_tx_inflight = false."); ESP_LOGD(TAG, "Send complete.");
} }
void s_cbEspNowReceiveComplete(const esp_now_recv_info_t* recv_info, const std::uint8_t* data, int len) void s_cbEspNowReceiveComplete(const esp_now_recv_info_t* recv_info, const std::uint8_t* data, int len)
@ -72,7 +96,7 @@ void setupWifi()
ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_start()); ESP_ERROR_CHECK(esp_wifi_start());
ESP_ERROR_CHECK(esp_wifi_set_channel(1, WIFI_SECOND_CHAN_NONE)); ESP_ERROR_CHECK(esp_wifi_set_channel(CONFIG_ESPTNL_CHANNEL, WIFI_SECOND_CHAN_NONE));
} }
QueueHandle_t setupEspNow() QueueHandle_t setupEspNow()
@ -81,12 +105,15 @@ QueueHandle_t setupEspNow()
ESP_ERROR_CHECK(s_esp_now_queue == nullptr); ESP_ERROR_CHECK(s_esp_now_queue == nullptr);
ESP_ERROR_CHECK(esp_now_init()); ESP_ERROR_CHECK(esp_now_init());
// ESP_ERROR_CHECK(esp_now_set_pmk(nullptr)); ESP_ERROR_CHECK(esp_now_set_pmk((const std::uint8_t*)CONFIG_ESPTNL_PMK));
ESP_ERROR_CHECK(esp_now_register_send_cb(s_cbEspNowSendComplete)); ESP_ERROR_CHECK(esp_now_register_send_cb(s_cbEspNowSendComplete));
ESP_ERROR_CHECK(esp_now_register_recv_cb(s_cbEspNowReceiveComplete)); ESP_ERROR_CHECK(esp_now_register_recv_cb(s_cbEspNowReceiveComplete));
s_peer = MacAddress{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; const auto broadcast_mac = MacAddress{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
s_peer = broadcast_mac;
ESP_ERROR_CHECK(s_addPeer(broadcast_mac));
return s_esp_now_queue; return s_esp_now_queue;
} }
@ -99,13 +126,11 @@ const std::array<std::uint8_t, 128>& getRxBuffer()
void sendData(const std::array<std::uint8_t, 128>& buffer, const std::size_t length) void sendData(const std::array<std::uint8_t, 128>& buffer, const std::size_t length)
{ {
if (const MacAddress* peer_mac = std::get_if<MacAddress>(&s_peer); if (const MacAddress* peer_mac = std::get_if<MacAddress>(&s_peer);
!s_tx_inflight && peer_mac != nullptr) peer_mac != nullptr)
{ {
esp_now_send(peer_mac->data(), buffer.data(), length); ESP_ERROR_CHECK_WITHOUT_ABORT(esp_now_send(peer_mac->data(), buffer.data(), length));
if (!s_isBroadcastAddress(peer_mac->data()))
s_tx_inflight = true;
ESP_LOGD(TAG, "Message send started. s_tx_inflight = %d.", s_tx_inflight); ESP_LOGD(TAG, "Message send started.");
} }
else else
{ {