ESPHome 2026.11.0-dev
Loading...
Searching...
No Matches
espnow_platform_esp8266.cpp
Go to the documentation of this file.
1#include "espnow_platform.h"
2
3#ifdef USE_ESP8266
4
5#include "espnow_component.h"
6
8
9// The SDK reports 0 for success and a non-zero value for any failure
10static esp_err_t sdk_result(int result) { return result == 0 ? ESP_OK : ESP_FAIL; }
11
12// Stands in for the destination address, which the SDK does not report
13static const uint8_t UNKNOWN_ADDR[ESP_NOW_ETH_ALEN] = {0};
14
15static void on_data_received(uint8_t *mac_addr, uint8_t *data, uint8_t size) {
16 global_esp_now->packet_received(mac_addr, UNKNOWN_ADDR, data, size, 0, 0);
17}
18
19static void on_send_report(uint8_t *mac_addr, uint8_t status) {
20 global_esp_now->send_reported(mac_addr, status == 0 ? ESP_NOW_SEND_SUCCESS : ESP_NOW_SEND_FAIL);
21}
22
23void init_radio() {
24 // The NONOS SDK only delivers broadcast frames to ESP-NOW while the station is associated or the
25 // soft-AP interface is up. Without Wi-Fi, run a hidden, open soft-AP that accepts no clients so
26 // broadcasts (for example from a WizMote style remote) are received.
27 softap_config ap{};
28 ap.channel = 1;
29 ap.authmode = AUTH_OPEN;
30 ap.ssid_hidden = 1;
31 ap.max_connection = 0;
32 ap.beacon_interval = 60000;
33 wifi_set_opmode_current(STATIONAP_MODE);
34 wifi_softap_set_config_current(&ap);
35 wifi_softap_dhcps_stop();
36 wifi_set_sleep_type(NONE_SLEEP_T);
37 wifi_station_disconnect();
38}
39
40void set_channel(uint8_t channel) {
41 wifi_promiscuous_enable(true);
42 wifi_set_channel(channel);
43 wifi_promiscuous_enable(false);
44 // Keep the soft-AP from init_radio() on the same channel so the SDK never retunes the radio to its own
45 softap_config ap{};
46 if (wifi_get_opmode() == STATIONAP_MODE && wifi_softap_get_config(&ap) && ap.channel != channel) {
47 ap.channel = channel;
48 wifi_softap_set_config_current(&ap);
49 }
50}
51
52uint8_t get_channel() { return wifi_get_channel(); }
53
54void read_mac(uint8_t *mac) {
55 // Frames leave from the station interface unless the device runs as a soft-AP only
56 wifi_get_macaddr(wifi_get_opmode() == SOFTAP_MODE ? SOFTAP_IF : STATION_IF, mac);
57}
58
60 int result = esp_now_init();
61 if (result == 0) {
62 // CONTROLLER sends from the station interface; the other roles send from the soft-AP MAC whenever
63 // that interface is up, so peers would no longer recognise the sender.
64 result = esp_now_set_self_role(ESP_NOW_ROLE_CONTROLLER);
65 }
66 if (result == 0) {
67 result = esp_now_register_recv_cb(on_data_received);
68 }
69 if (result == 0) {
70 result = esp_now_register_send_cb(on_send_report);
71 }
72 return sdk_result(result);
73}
74
78 return sdk_result(esp_now_deinit());
79}
80
81uint32_t get_version() { return 0; }
82
83// The SDK returns 1 when the peer exists, 0 when it does not and a negative value on error
84bool peer_exists(const uint8_t *mac) { return esp_now_is_peer_exist(const_cast<uint8_t *>(mac)) > 0; }
85
86esp_err_t add_peer(const uint8_t *mac) {
87 return sdk_result(esp_now_add_peer(const_cast<uint8_t *>(mac), ESP_NOW_ROLE_COMBO, wifi_get_channel(), nullptr, 0));
88}
89
90esp_err_t del_peer(const uint8_t *mac) { return sdk_result(esp_now_del_peer(const_cast<uint8_t *>(mac))); }
91
92void rebind_peers() {
93 const uint8_t channel = wifi_get_channel();
94 for (uint8_t *mac = esp_now_fetch_peer(true); mac != nullptr; mac = esp_now_fetch_peer(false)) {
95 esp_now_set_peer_channel(mac, channel);
96 }
97}
98
99esp_err_t send(const uint8_t *mac, const uint8_t *data, uint16_t size) {
100 return sdk_result(esp_now_send(const_cast<uint8_t *>(mac), const_cast<uint8_t *>(data), size));
101}
102
103} // namespace esphome::espnow::platform
104
105#endif // USE_ESP8266
esp_err_t esp_now_del_peer(const uint8_t *peer_addr)
esp_err_t esp_now_unregister_recv_cb(void)
esp_err_t esp_now_unregister_send_cb(void)
esp_err_t esp_now_register_send_cb(esp_now_send_cb_t cb)
esp_err_t esp_now_deinit(void)
esp_err_t esp_now_add_peer(const esp_now_peer_info_t *peer)
esp_err_t esp_now_send(const uint8_t *peer_addr, const uint8_t *data, size_t len)
bool esp_now_is_peer_exist(const uint8_t *peer_addr)
esp_err_t esp_now_register_recv_cb(esp_now_recv_cb_t cb)
esp_err_t esp_now_init(void)
esp_err_t esp_now_fetch_peer(bool, esp_now_peer_info_t *)
esp_err_t del_peer(const uint8_t *mac)
esp_err_t send(const uint8_t *mac, const uint8_t *data, uint16_t size)
void set_channel(uint8_t channel)
bool peer_exists(const uint8_t *mac)
esp_err_t add_peer(const uint8_t *mac)
ESPNowComponent * global_esp_now
uint16_t size
Definition helpers.cpp:34
static void uint32_t