1 /* 2 * SPDX-FileCopyrightText: 2019-2025 Espressif Systems (Shanghai) CO LTD 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #ifndef __ESP_NOW_H__ 8 #define __ESP_NOW_H__ 9 10 #include <stdbool.h> 11 #include "esp_err.h" 12 #include "esp_wifi_types.h" 13 14 #ifdef __cplusplus 15 extern "C" { 16 #endif 17 18 /** \defgroup WiFi_APIs WiFi Related APIs 19 * @brief WiFi APIs 20 */ 21 22 /** @addtogroup WiFi_APIs 23 * @{ 24 */ 25 26 /** \defgroup ESPNOW_APIs ESPNOW APIs 27 * @brief ESP32 ESPNOW APIs 28 * 29 */ 30 31 /** @addtogroup ESPNOW_APIs 32 * @{ 33 */ 34 35 #define ESP_ERR_ESPNOW_BASE (ESP_ERR_WIFI_BASE + 100) /*!< ESPNOW error number base. */ 36 #define ESP_ERR_ESPNOW_NOT_INIT (ESP_ERR_ESPNOW_BASE + 1) /*!< ESPNOW is not initialized. */ 37 #define ESP_ERR_ESPNOW_ARG (ESP_ERR_ESPNOW_BASE + 2) /*!< Invalid argument */ 38 #define ESP_ERR_ESPNOW_NO_MEM (ESP_ERR_ESPNOW_BASE + 3) /*!< Out of memory */ 39 #define ESP_ERR_ESPNOW_FULL (ESP_ERR_ESPNOW_BASE + 4) /*!< ESPNOW peer list is full */ 40 #define ESP_ERR_ESPNOW_NOT_FOUND (ESP_ERR_ESPNOW_BASE + 5) /*!< ESPNOW peer is not found */ 41 #define ESP_ERR_ESPNOW_INTERNAL (ESP_ERR_ESPNOW_BASE + 6) /*!< Internal error */ 42 #define ESP_ERR_ESPNOW_EXIST (ESP_ERR_ESPNOW_BASE + 7) /*!< ESPNOW peer has existed */ 43 #define ESP_ERR_ESPNOW_IF (ESP_ERR_ESPNOW_BASE + 8) /*!< Interface error */ 44 45 #define ESP_NOW_ETH_ALEN 6 /*!< Length of ESPNOW peer MAC address */ 46 #define ESP_NOW_KEY_LEN 16 /*!< Length of ESPNOW peer local master key */ 47 48 #define ESP_NOW_MAX_TOTAL_PEER_NUM 20 /*!< Maximum number of ESPNOW total peers */ 49 #define ESP_NOW_MAX_ENCRYPT_PEER_NUM 6 /*!< Maximum number of ESPNOW encrypted peers */ 50 51 #define ESP_NOW_MAX_IE_DATA_LEN 250 /**< Maximum data length in a vendor-specific element */ 52 #define ESP_NOW_MAX_DATA_LEN ESP_NOW_MAX_IE_DATA_LEN /**< Maximum length of data sent in each ESPNOW transmission for v1.0 */ 53 54 /** 55 * @brief Status of sending ESPNOW data . 56 */ 57 typedef enum { 58 ESP_NOW_SEND_SUCCESS = 0, /**< Send ESPNOW data successfully */ 59 ESP_NOW_SEND_FAIL, /**< Send ESPNOW data fail */ 60 } esp_now_send_status_t; 61 62 /** 63 * @brief ESPNOW peer information parameters. 64 */ 65 typedef struct esp_now_peer_info { 66 uint8_t peer_addr[ESP_NOW_ETH_ALEN]; /**< ESPNOW peer MAC address that is also the MAC address of station or softap */ 67 uint8_t lmk[ESP_NOW_KEY_LEN]; /**< ESPNOW peer local master key that is used to encrypt data */ 68 uint8_t channel; /**< Wi-Fi channel that peer uses to send/receive ESPNOW data. If the value is 0, 69 use the current channel which station or softap is on. Otherwise, it must be 70 set as the channel that station or softap is on. */ 71 wifi_interface_t ifidx; /**< Wi-Fi interface that peer uses to send/receive ESPNOW data */ 72 bool encrypt; /**< ESPNOW data that this peer sends/receives is encrypted or not */ 73 void *priv; /**< ESPNOW peer private data */ 74 } esp_now_peer_info_t; 75 76 /** 77 * @brief Number of ESPNOW peers which exist currently. 78 */ 79 typedef struct esp_now_peer_num { 80 int total_num; /**< Total number of ESPNOW peers, maximum value is ESP_NOW_MAX_TOTAL_PEER_NUM */ 81 int encrypt_num; /**< Number of encrypted ESPNOW peers, maximum value is ESP_NOW_MAX_ENCRYPT_PEER_NUM */ 82 } esp_now_peer_num_t; 83 84 /** 85 * @brief ESPNOW packet information 86 */ 87 typedef struct esp_now_recv_info { 88 uint8_t * src_addr; /**< Source address of ESPNOW packet */ 89 uint8_t * des_addr; /**< Destination address of ESPNOW packet */ 90 wifi_pkt_rx_ctrl_t * rx_ctrl; /**< Rx control info of ESPNOW packet */ 91 } esp_now_recv_info_t; 92 93 /** 94 * @brief ESPNOW rate config 95 */ 96 typedef wifi_tx_rate_config_t esp_now_rate_config_t; 97 98 /** 99 * @brief Callback function of receiving ESPNOW data 100 * @param esp_now_info received ESPNOW packet information 101 * @param data received data 102 * @param data_len length of received data 103 * @attention esp_now_info is a local variable,it can only be used in the callback. 104 */ 105 typedef void (*esp_now_recv_cb_t)(const esp_now_recv_info_t * esp_now_info, const uint8_t *data, int data_len); 106 107 /** 108 * @brief Callback function of sending ESPNOW data 109 * @param mac_addr peer MAC address 110 * @param status status of sending ESPNOW data (succeed or fail) 111 */ 112 typedef void (*esp_now_send_cb_t)(const uint8_t *mac_addr, esp_now_send_status_t status); 113 114 /** 115 * @brief Initialize ESPNOW function 116 * 117 * @return 118 * - ESP_OK : succeed 119 * - ESP_ERR_ESPNOW_INTERNAL : Internal error 120 */ 121 esp_err_t esp_now_init(void); 122 123 /** 124 * @brief De-initialize ESPNOW function 125 * 126 * @return 127 * - ESP_OK : succeed 128 */ 129 esp_err_t esp_now_deinit(void); 130 131 /** 132 * @brief Get the version of ESPNOW. Currently, ESPNOW supports one version: v1.0. 133 * 134 * The v1.0 devices can receive packets if the packet length is less than or equal to ESP_NOW_MAX_IE_DATA_LEN. 135 * For packets exceeding this length, the v1.0 devices will discard the packet entirely. 136 * 137 * @param version ESPNOW version 138 * 139 * @return 140 * - ESP_OK : succeed 141 * - ESP_ERR_ESPNOW_ARG : invalid argument 142 */ 143 esp_err_t esp_now_get_version(uint32_t *version); 144 145 /** 146 * @brief Register callback function of receiving ESPNOW data 147 * 148 * @param cb callback function of receiving ESPNOW data 149 * 150 * @return 151 * - ESP_OK : succeed 152 * - ESP_ERR_ESPNOW_NOT_INIT : ESPNOW is not initialized 153 * - ESP_ERR_ESPNOW_INTERNAL : internal error 154 */ 155 esp_err_t esp_now_register_recv_cb(esp_now_recv_cb_t cb); 156 157 /** 158 * @brief Unregister callback function of receiving ESPNOW data 159 * 160 * @return 161 * - ESP_OK : succeed 162 * - ESP_ERR_ESPNOW_NOT_INIT : ESPNOW is not initialized 163 */ 164 esp_err_t esp_now_unregister_recv_cb(void); 165 166 /** 167 * @brief Register callback function of sending ESPNOW data 168 * 169 * @param cb callback function of sending ESPNOW data 170 * 171 * @return 172 * - ESP_OK : succeed 173 * - ESP_ERR_ESPNOW_NOT_INIT : ESPNOW is not initialized 174 * - ESP_ERR_ESPNOW_INTERNAL : internal error 175 */ 176 esp_err_t esp_now_register_send_cb(esp_now_send_cb_t cb); 177 178 /** 179 * @brief Unregister callback function of sending ESPNOW data 180 * 181 * @return 182 * - ESP_OK : succeed 183 * - ESP_ERR_ESPNOW_NOT_INIT : ESPNOW is not initialized 184 */ 185 esp_err_t esp_now_unregister_send_cb(void); 186 187 /** 188 * @brief Send ESPNOW data 189 * 190 * @attention 1. If peer_addr is not NULL, send data to the peer whose MAC address matches peer_addr 191 * @attention 2. If peer_addr is NULL, send data to all of the peers that are added to the peer list 192 * @attention 3. The maximum length of data must be less than ESP_NOW_MAX_DATA_LEN 193 * @attention 4. The buffer pointed to by data argument does not need to be valid after esp_now_send returns 194 * 195 * @param peer_addr peer MAC address 196 * @param data data to send 197 * @param len length of data 198 * 199 * @return 200 * - ESP_OK : succeed 201 * - ESP_ERR_ESPNOW_NOT_INIT : ESPNOW is not initialized 202 * - ESP_ERR_ESPNOW_ARG : invalid argument 203 * - ESP_ERR_ESPNOW_INTERNAL : internal error 204 * - ESP_ERR_ESPNOW_NO_MEM : out of memory, when this happens, you can delay a while before sending the next data 205 * - ESP_ERR_ESPNOW_NOT_FOUND : peer is not found 206 * - ESP_ERR_ESPNOW_IF : current WiFi interface doesn't match that of peer 207 */ 208 esp_err_t esp_now_send(const uint8_t *peer_addr, const uint8_t *data, size_t len); 209 210 /** 211 * @brief Add a peer to peer list 212 * 213 * @param peer peer information 214 * 215 * @return 216 * - ESP_OK : succeed 217 * - ESP_ERR_ESPNOW_NOT_INIT : ESPNOW is not initialized 218 * - ESP_ERR_ESPNOW_ARG : invalid argument 219 * - ESP_ERR_ESPNOW_FULL : peer list is full 220 * - ESP_ERR_ESPNOW_NO_MEM : out of memory 221 * - ESP_ERR_ESPNOW_EXIST : peer has existed 222 */ 223 esp_err_t esp_now_add_peer(const esp_now_peer_info_t *peer); 224 225 /** 226 * @brief Delete a peer from peer list 227 * 228 * @param peer_addr peer MAC address 229 * 230 * @return 231 * - ESP_OK : succeed 232 * - ESP_ERR_ESPNOW_NOT_INIT : ESPNOW is not initialized 233 * - ESP_ERR_ESPNOW_ARG : invalid argument 234 * - ESP_ERR_ESPNOW_NOT_FOUND : peer is not found 235 */ 236 esp_err_t esp_now_del_peer(const uint8_t *peer_addr); 237 238 /** 239 * @brief Modify a peer 240 * 241 * @param peer peer information 242 * 243 * @return 244 * - ESP_OK : succeed 245 * - ESP_ERR_ESPNOW_NOT_INIT : ESPNOW is not initialized 246 * - ESP_ERR_ESPNOW_ARG : invalid argument 247 * - ESP_ERR_ESPNOW_FULL : peer list is full 248 */ 249 esp_err_t esp_now_mod_peer(const esp_now_peer_info_t *peer); 250 251 /** 252 * @brief Config ESPNOW rate of specified interface 253 * 254 * @deprecated please use esp_now_set_peer_rate_config() instead. 255 * 256 * @attention 1. This API should be called after esp_wifi_start(). 257 * @attention 2. This API only work when not use Wi-Fi 6 and esp_now_set_peer_rate_config() not called. 258 * 259 * @param ifx Interface to be configured. 260 * @param rate Phy rate to be configured. 261 * 262 * @return 263 * - ESP_OK: succeed 264 * - others: failed 265 */ 266 esp_err_t esp_wifi_config_espnow_rate(wifi_interface_t ifx, wifi_phy_rate_t rate) 267 __attribute__((deprecated("This API can be only used when rate is non-HE rate, \ 268 please use esp_now_set_peer_rate_config if you want full support of the rate."))); 269 270 /** 271 * @brief Set ESPNOW rate config for each peer 272 * 273 * @attention 1. This API should be called after esp_wifi_start() and esp_now_init(). 274 * 275 * @param peer_addr peer MAC address 276 * @param config rate config to be configured. 277 * 278 * @return 279 * - ESP_OK : succeed 280 * - ESP_ERR_ESPNOW_NOT_INIT : ESPNOW is not initialized 281 * - ESP_ERR_ESPNOW_ARG : invalid argument 282 * - ESP_ERR_ESPNOW_INTERNAL : internal error 283 */ 284 esp_err_t esp_now_set_peer_rate_config(const uint8_t *peer_addr, esp_now_rate_config_t *config); 285 286 /** 287 * @brief Get a peer whose MAC address matches peer_addr from peer list 288 * 289 * @param peer_addr peer MAC address 290 * @param peer peer information 291 * 292 * @return 293 * - ESP_OK : succeed 294 * - ESP_ERR_ESPNOW_NOT_INIT : ESPNOW is not initialized 295 * - ESP_ERR_ESPNOW_ARG : invalid argument 296 * - ESP_ERR_ESPNOW_NOT_FOUND : peer is not found 297 */ 298 esp_err_t esp_now_get_peer(const uint8_t *peer_addr, esp_now_peer_info_t *peer); 299 300 /** 301 * @brief Fetch a peer from peer list. Only return the peer which address is unicast, for the multicast/broadcast address, the function will ignore and try to find the next in the peer list. 302 * 303 * @param from_head fetch from head of list or not 304 * @param peer peer information 305 * 306 * @return 307 * - ESP_OK : succeed 308 * - ESP_ERR_ESPNOW_NOT_INIT : ESPNOW is not initialized 309 * - ESP_ERR_ESPNOW_ARG : invalid argument 310 * - ESP_ERR_ESPNOW_NOT_FOUND : peer is not found 311 */ 312 esp_err_t esp_now_fetch_peer(bool from_head, esp_now_peer_info_t *peer); 313 314 /** 315 * @brief Peer exists or not 316 * 317 * @param peer_addr peer MAC address 318 * 319 * @return 320 * - true : peer exists 321 * - false : peer not exists 322 */ 323 bool esp_now_is_peer_exist(const uint8_t *peer_addr); 324 325 /** 326 * @brief Get the number of peers 327 * 328 * @param num number of peers 329 * 330 * @return 331 * - ESP_OK : succeed 332 * - ESP_ERR_ESPNOW_NOT_INIT : ESPNOW is not initialized 333 * - ESP_ERR_ESPNOW_ARG : invalid argument 334 */ 335 esp_err_t esp_now_get_peer_num(esp_now_peer_num_t *num); 336 337 /** 338 * @brief Set the primary master key 339 * 340 * @param pmk primary master key 341 * 342 * @attention 1. primary master key is used to encrypt local master key 343 * 344 * @return 345 * - ESP_OK : succeed 346 * - ESP_ERR_ESPNOW_NOT_INIT : ESPNOW is not initialized 347 * - ESP_ERR_ESPNOW_ARG : invalid argument 348 */ 349 esp_err_t esp_now_set_pmk(const uint8_t *pmk); 350 351 /** 352 * @brief Set wake window for esp_now to wake up in interval unit 353 * 354 * @param window Milliseconds would the chip keep waked each interval, from 0 to 65535. 355 * 356 * @attention 1. This configuration could work at connected status. 357 * When ESP_WIFI_STA_DISCONNECTED_PM_ENABLE is enabled, this configuration could work at disconnected status. 358 * @attention 2. Default value is the maximum. 359 * 360 * @return 361 * - ESP_OK : succeed 362 * - ESP_ERR_ESPNOW_NOT_INIT : ESPNOW is not initialized 363 */ 364 esp_err_t esp_now_set_wake_window(uint16_t window); 365 366 /** 367 * @} 368 */ 369 370 /** 371 * @} 372 */ 373 374 #ifdef __cplusplus 375 } 376 #endif 377 378 #endif /* __ESP_NOW_H__ */ 379