1 // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef __ESP_NOW_H__
16 #define __ESP_NOW_H__
17 
18 #include <stdbool.h>
19 #include "esp_err.h"
20 #include "esp_wifi_types.h"
21 
22 #ifdef __cplusplus
23 extern "C" {
24 #endif
25 
26 /** \defgroup WiFi_APIs WiFi Related APIs
27   * @brief WiFi APIs
28   */
29 
30 /** @addtogroup WiFi_APIs
31   * @{
32   */
33 
34 /** \defgroup ESPNOW_APIs  ESPNOW APIs
35   * @brief ESP32 ESPNOW APIs
36   *
37   */
38 
39 /** @addtogroup ESPNOW_APIs
40   * @{
41   */
42 
43 #define ESP_ERR_ESPNOW_BASE         (ESP_ERR_WIFI_BASE + 100) /*!< ESPNOW error number base. */
44 #define ESP_ERR_ESPNOW_NOT_INIT     (ESP_ERR_ESPNOW_BASE + 1) /*!< ESPNOW is not initialized. */
45 #define ESP_ERR_ESPNOW_ARG          (ESP_ERR_ESPNOW_BASE + 2) /*!< Invalid argument */
46 #define ESP_ERR_ESPNOW_NO_MEM       (ESP_ERR_ESPNOW_BASE + 3) /*!< Out of memory */
47 #define ESP_ERR_ESPNOW_FULL         (ESP_ERR_ESPNOW_BASE + 4) /*!< ESPNOW peer list is full */
48 #define ESP_ERR_ESPNOW_NOT_FOUND    (ESP_ERR_ESPNOW_BASE + 5) /*!< ESPNOW peer is not found */
49 #define ESP_ERR_ESPNOW_INTERNAL     (ESP_ERR_ESPNOW_BASE + 6) /*!< Internal error */
50 #define ESP_ERR_ESPNOW_EXIST        (ESP_ERR_ESPNOW_BASE + 7) /*!< ESPNOW peer has existed */
51 #define ESP_ERR_ESPNOW_IF           (ESP_ERR_ESPNOW_BASE + 8) /*!< Interface error */
52 
53 #define ESP_NOW_ETH_ALEN             6         /*!< Length of ESPNOW peer MAC address */
54 #define ESP_NOW_KEY_LEN              16        /*!< Length of ESPNOW peer local master key */
55 
56 #define ESP_NOW_MAX_TOTAL_PEER_NUM   20        /*!< Maximum number of ESPNOW total peers */
57 #define ESP_NOW_MAX_ENCRYPT_PEER_NUM 6         /*!< Maximum number of ESPNOW encrypted peers */
58 
59 #define ESP_NOW_MAX_DATA_LEN         250       /*!< Maximum length of ESPNOW data which is sent very time */
60 
61 /**
62  * @brief Status of sending ESPNOW data .
63  */
64 typedef enum {
65     ESP_NOW_SEND_SUCCESS = 0,       /**< Send ESPNOW data successfully */
66     ESP_NOW_SEND_FAIL,              /**< Send ESPNOW data fail */
67 } esp_now_send_status_t;
68 
69 /**
70  * @brief ESPNOW peer information parameters.
71  */
72 typedef struct esp_now_peer_info {
73     uint8_t peer_addr[ESP_NOW_ETH_ALEN];    /**< ESPNOW peer MAC address that is also the MAC address of station or softap */
74     uint8_t lmk[ESP_NOW_KEY_LEN];           /**< ESPNOW peer local master key that is used to encrypt data */
75     uint8_t channel;                        /**< Wi-Fi channel that peer uses to send/receive ESPNOW data. If the value is 0,
76                                                  use the current channel which station or softap is on. Otherwise, it must be
77                                                  set as the channel that station or softap is on. */
78     wifi_interface_t ifidx;                 /**< Wi-Fi interface that peer uses to send/receive ESPNOW data */
79     bool encrypt;                           /**< ESPNOW data that this peer sends/receives is encrypted or not */
80     void *priv;                             /**< ESPNOW peer private data */
81 } esp_now_peer_info_t;
82 
83 /**
84  * @brief Number of ESPNOW peers which exist currently.
85  */
86 typedef struct esp_now_peer_num {
87     int total_num;                           /**< Total number of ESPNOW peers, maximum value is ESP_NOW_MAX_TOTAL_PEER_NUM */
88     int encrypt_num;                         /**< Number of encrypted ESPNOW peers, maximum value is ESP_NOW_MAX_ENCRYPT_PEER_NUM */
89 } esp_now_peer_num_t;
90 
91 /**
92   * @brief     Callback function of receiving ESPNOW data
93   * @param     mac_addr peer MAC address
94   * @param     data received data
95   * @param     data_len length of received data
96   */
97 typedef void (*esp_now_recv_cb_t)(const uint8_t *mac_addr, const uint8_t *data, int data_len);
98 
99 /**
100   * @brief     Callback function of sending ESPNOW data
101   * @param     mac_addr peer MAC address
102   * @param     status status of sending ESPNOW data (succeed or fail)
103   */
104 typedef void (*esp_now_send_cb_t)(const uint8_t *mac_addr, esp_now_send_status_t status);
105 
106 /**
107   * @brief     Initialize ESPNOW function
108   *
109   * @return
110   *          - ESP_OK : succeed
111   *          - ESP_ERR_ESPNOW_INTERNAL : Internal error
112   */
113 esp_err_t esp_now_init(void);
114 
115 /**
116   * @brief     De-initialize ESPNOW function
117   *
118   * @return
119   *          - ESP_OK : succeed
120   */
121 esp_err_t esp_now_deinit(void);
122 
123 /**
124   * @brief     Get the version of ESPNOW
125   *
126   * @param     version  ESPNOW version
127   *
128   * @return
129   *          - ESP_OK : succeed
130   *          - ESP_ERR_ESPNOW_ARG : invalid argument
131   */
132 esp_err_t esp_now_get_version(uint32_t *version);
133 
134 /**
135   * @brief     Register callback function of receiving ESPNOW data
136   *
137   * @param     cb  callback function of receiving ESPNOW data
138   *
139   * @return
140   *          - ESP_OK : succeed
141   *          - ESP_ERR_ESPNOW_NOT_INIT : ESPNOW is not initialized
142   *          - ESP_ERR_ESPNOW_INTERNAL : internal error
143   */
144 esp_err_t esp_now_register_recv_cb(esp_now_recv_cb_t cb);
145 
146 /**
147   * @brief     Unregister callback function of receiving ESPNOW data
148   *
149   * @return
150   *          - ESP_OK : succeed
151   *          - ESP_ERR_ESPNOW_NOT_INIT : ESPNOW is not initialized
152   */
153 esp_err_t esp_now_unregister_recv_cb(void);
154 
155 /**
156   * @brief     Register callback function of sending ESPNOW data
157   *
158   * @param     cb  callback function of sending ESPNOW data
159   *
160   * @return
161   *          - ESP_OK : succeed
162   *          - ESP_ERR_ESPNOW_NOT_INIT : ESPNOW is not initialized
163   *          - ESP_ERR_ESPNOW_INTERNAL : internal error
164   */
165 esp_err_t esp_now_register_send_cb(esp_now_send_cb_t cb);
166 
167 /**
168   * @brief     Unregister callback function of sending ESPNOW data
169   *
170   * @return
171   *          - ESP_OK : succeed
172   *          - ESP_ERR_ESPNOW_NOT_INIT : ESPNOW is not initialized
173   */
174 esp_err_t esp_now_unregister_send_cb(void);
175 
176 /**
177   * @brief     Send ESPNOW data
178   *
179   * @attention 1. If peer_addr is not NULL, send data to the peer whose MAC address matches peer_addr
180   * @attention 2. If peer_addr is NULL, send data to all of the peers that are added to the peer list
181   * @attention 3. The maximum length of data must be less than ESP_NOW_MAX_DATA_LEN
182   * @attention 4. The buffer pointed to by data argument does not need to be valid after esp_now_send returns
183   *
184   * @param     peer_addr  peer MAC address
185   * @param     data  data to send
186   * @param     len  length of data
187   *
188   * @return
189   *          - ESP_OK : succeed
190   *          - ESP_ERR_ESPNOW_NOT_INIT : ESPNOW is not initialized
191   *          - ESP_ERR_ESPNOW_ARG : invalid argument
192   *          - ESP_ERR_ESPNOW_INTERNAL : internal error
193   *          - ESP_ERR_ESPNOW_NO_MEM : out of memory
194   *          - ESP_ERR_ESPNOW_NOT_FOUND : peer is not found
195   *          - ESP_ERR_ESPNOW_IF : current WiFi interface doesn't match that of peer
196   */
197 esp_err_t esp_now_send(const uint8_t *peer_addr, const uint8_t *data, size_t len);
198 
199 /**
200   * @brief     Add a peer to peer list
201   *
202   * @param     peer  peer information
203   *
204   * @return
205   *          - ESP_OK : succeed
206   *          - ESP_ERR_ESPNOW_NOT_INIT : ESPNOW is not initialized
207   *          - ESP_ERR_ESPNOW_ARG : invalid argument
208   *          - ESP_ERR_ESPNOW_FULL : peer list is full
209   *          - ESP_ERR_ESPNOW_NO_MEM : out of memory
210   *          - ESP_ERR_ESPNOW_EXIST : peer has existed
211   */
212 esp_err_t esp_now_add_peer(const esp_now_peer_info_t *peer);
213 
214 /**
215   * @brief     Delete a peer from peer list
216   *
217   * @param     peer_addr  peer MAC address
218   *
219   * @return
220   *          - ESP_OK : succeed
221   *          - ESP_ERR_ESPNOW_NOT_INIT : ESPNOW is not initialized
222   *          - ESP_ERR_ESPNOW_ARG : invalid argument
223   *          - ESP_ERR_ESPNOW_NOT_FOUND : peer is not found
224   */
225 esp_err_t esp_now_del_peer(const uint8_t *peer_addr);
226 
227 /**
228   * @brief     Modify a peer
229   *
230   * @param     peer  peer information
231   *
232   * @return
233   *          - ESP_OK : succeed
234   *          - ESP_ERR_ESPNOW_NOT_INIT : ESPNOW is not initialized
235   *          - ESP_ERR_ESPNOW_ARG : invalid argument
236   *          - ESP_ERR_ESPNOW_FULL : peer list is full
237   */
238 esp_err_t esp_now_mod_peer(const esp_now_peer_info_t *peer);
239 
240 /**
241   * @brief     Get a peer whose MAC address matches peer_addr from peer list
242   *
243   * @param     peer_addr  peer MAC address
244   * @param     peer  peer information
245   *
246   * @return
247   *          - ESP_OK : succeed
248   *          - ESP_ERR_ESPNOW_NOT_INIT : ESPNOW is not initialized
249   *          - ESP_ERR_ESPNOW_ARG : invalid argument
250   *          - ESP_ERR_ESPNOW_NOT_FOUND : peer is not found
251   */
252 esp_err_t esp_now_get_peer(const uint8_t *peer_addr, esp_now_peer_info_t *peer);
253 
254 /**
255   * @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.
256   *
257   * @param     from_head  fetch from head of list or not
258   * @param     peer  peer information
259   *
260   * @return
261   *          - ESP_OK : succeed
262   *          - ESP_ERR_ESPNOW_NOT_INIT : ESPNOW is not initialized
263   *          - ESP_ERR_ESPNOW_ARG : invalid argument
264   *          - ESP_ERR_ESPNOW_NOT_FOUND : peer is not found
265   */
266 esp_err_t esp_now_fetch_peer(bool from_head, esp_now_peer_info_t *peer);
267 
268 /**
269   * @brief     Peer exists or not
270   *
271   * @param     peer_addr  peer MAC address
272   *
273   * @return
274   *          - true : peer exists
275   *          - false : peer not exists
276   */
277 bool esp_now_is_peer_exist(const uint8_t *peer_addr);
278 
279 /**
280   * @brief     Get the number of peers
281   *
282   * @param     num  number of peers
283   *
284   * @return
285   *          - ESP_OK : succeed
286   *          - ESP_ERR_ESPNOW_NOT_INIT : ESPNOW is not initialized
287   *          - ESP_ERR_ESPNOW_ARG : invalid argument
288   */
289 esp_err_t esp_now_get_peer_num(esp_now_peer_num_t *num);
290 
291 /**
292   * @brief     Set the primary master key
293   *
294   * @param     pmk  primary master key
295   *
296   * @attention 1. primary master key is used to encrypt local master key
297   *
298   * @return
299   *          - ESP_OK : succeed
300   *          - ESP_ERR_ESPNOW_NOT_INIT : ESPNOW is not initialized
301   *          - ESP_ERR_ESPNOW_ARG : invalid argument
302   */
303 esp_err_t esp_now_set_pmk(const uint8_t *pmk);
304 
305 /**
306   * @brief     Set esp_now wake window for sta_disconnected power management
307   *
308   * @param     window  how much microsecond would the chip keep waked each interval, vary from 0 to 65535
309   *
310   * @attention 1. Only when ESP_WIFI_STA_DISCONNECTED_PM_ENABLE is enabled, this configuration could work
311   * @attention 2. This configuration only work for station mode and disconnected status
312   * @attention 3. If more than one module has configured its wake_window, chip would choose the largest one to stay waked
313   * @attention 4. If the gap between interval and window is smaller than 5ms, the chip would keep waked all the time
314   * @attention 5. If never configured wake_window, the chip would keep waked at disconnected once it uses esp_now
315   *
316   * @return
317   *          - ESP_OK : succeed
318   *          - ESP_ERR_ESPNOW_NOT_INIT : ESPNOW is not initialized
319   */
320 esp_err_t esp_now_set_wake_window(uint16_t window);
321 
322 /**
323   * @}
324   */
325 
326 /**
327   * @}
328   */
329 
330 #ifdef __cplusplus
331 }
332 #endif
333 
334 #endif /* __ESP_NOW_H__ */
335