1 /*
2  * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include "esp_wifi.h"
8 #include "esp_private/wifi.h"
9 #include "esp_wifi_netif.h"
10 #include "freertos/event_groups.h"
11 #include "lwip/netdb.h"
12 #include "lwip/sockets.h"
13 #include "esp_event.h"
14 #include "esp_log.h"
15 #include "esp_check.h"
16 #include "esp_mac.h"
17 #include "os.h"
18 #include "esp_nan.h"
19 
20 /* NAN States */
21 #define NAN_STARTED_BIT     BIT0
22 #define NAN_STOPPED_BIT     BIT1
23 
24 /* NAN Events */
25 #define NDP_INDICATION      BIT2
26 #define NDP_ACCEPTED        BIT3
27 #define NDP_TERMINATED      BIT4
28 #define NDP_REJECTED        BIT5
29 
30 /* Macros */
31 #define MACADDR_LEN             6
32 #define MACADDR_EQUAL(a1, a2)   (memcmp(a1, a2, MACADDR_LEN))
33 #define MACADDR_COPY(dst, src)  (memcpy(dst, src, MACADDR_LEN))
34 #define NAN_DW_INTVL_MS         524     /* NAN DW interval (512 TU's ~= 524 mSec) */
35 #define NAN_NDP_RESP_TIMEOUT_DW 8
36 #define NAN_NDP_RESP_TIMEOUT    NAN_NDP_RESP_TIMEOUT_DW*NAN_DW_INTVL_MS
37 #define NAN_NDP_TERM_TIMEOUT    2*NAN_DW_INTVL_MS /* NDP Termination Timeout - 2 DW*/
38 
39 /* Global Variables */
40 static const char *TAG = "nan_app";
41 static EventGroupHandle_t nan_event_group;
42 static bool s_app_default_handlers_set = false;
43 static uint8_t null_mac[MACADDR_LEN] = {0};
44 static void *s_nan_data_lock = NULL;
45 
46 #define NAN_DATA_LOCK() os_mutex_lock(s_nan_data_lock)
47 #define NAN_DATA_UNLOCK() os_mutex_unlock(s_nan_data_lock)
48 
49 struct peer_svc_info {
50     SLIST_ENTRY(peer_svc_info) next;
51     uint8_t peer_svc_info[ESP_WIFI_MAX_SVC_INFO_LEN];   /**< Information for followup message */
52     uint8_t svc_id;                                     /**< Identifier of peer's service */
53     uint8_t own_svc_id;                                 /**< Identifier for own service  */
54     uint8_t type;                                       /**< Service type (Publish/Subscribe) */
55     uint8_t peer_nmi[MACADDR_LEN];                      /**< Peer's NAN Management Interface address */
56 };
57 
58 struct own_svc_info {
59     char svc_name[ESP_WIFI_MAX_SVC_NAME_LEN];           /**< Name identifying a service */
60     uint8_t svc_id;                                     /**< Identifier for a service */
61     uint8_t type;                                       /**< Service type (Publish/Subscribe) */
62     bool ndp_resp_needed;                               /**< If enabled, NDP response is required */
63     uint8_t num_peer_records;                           /**< Count of peer records associated with svc_id */
64     SLIST_HEAD(peer_list_t, peer_svc_info) peer_list;   /**< List of peers matched for specific service */
65 };
66 
67 struct ndl_info {
68     uint8_t ndp_id;                                     /**< Identifier for instance of NDP */
69     uint8_t peer_ndi[MACADDR_LEN];                      /**< Peer's NAN Data Interface address */
70     uint8_t peer_nmi[MACADDR_LEN];                      /**< Peer's NAN Management Interface address */
71     uint8_t publisher_id;                               /**< Publisher's service identifier */
72     uint8_t own_role;                                   /**< Own role (Publisher/Subscriber) */
73 };
74 
75 typedef struct {
76     uint8_t state;
77     uint8_t event;
78     struct ndl_info ndl[ESP_WIFI_NAN_DATAPATH_MAX_PEERS];        /**< Record of NDL of all peers */
79     struct own_svc_info own_svc[ESP_WIFI_NAN_MAX_SVC_SUPPORTED]; /**< Record of own service(s) */
80     esp_netif_t *nan_netif;
81 } nan_ctx_t;
82 
83 static nan_ctx_t s_nan_ctx;
84 
esp_wifi_nan_get_ipv6_linklocal_from_mac(ip6_addr_t * ip6,uint8_t * mac_addr)85 void esp_wifi_nan_get_ipv6_linklocal_from_mac(ip6_addr_t *ip6, uint8_t *mac_addr)
86 {
87     if (ip6 == NULL || mac_addr == NULL)
88         return;
89     /* Link-local prefix. */
90     ip6->addr[0] = htonl(0xfe800000ul);
91     ip6->addr[1] = 0;
92 
93     /* Assume hwaddr is a 48-bit IEEE 802 MAC. Convert to EUI-64 address. Complement Group bit. */
94     ip6->addr[2] = htonl((((uint32_t)(mac_addr[0] ^ 0x02)) << 24) |
95                          ((uint32_t)(mac_addr[1]) << 16) |
96                          ((uint32_t)(mac_addr[2]) << 8) |
97                          (0xff));
98     ip6->addr[3] = htonl((uint32_t)(0xfeul << 24) |
99                          ((uint32_t)(mac_addr[3]) << 16) |
100                          ((uint32_t)(mac_addr[4]) << 8) |
101                          (mac_addr[5]));
102 
103     ip6->zone = IP6_NO_ZONE;
104 }
105 
nan_find_own_svc(uint8_t svc_id)106 static struct own_svc_info *nan_find_own_svc(uint8_t svc_id)
107 {
108     struct own_svc_info *p_svc = NULL;
109 
110     if (svc_id == 0) {
111         ESP_LOGE(TAG, "Service id cannot be 0!");
112         return NULL;
113     }
114 
115     for (int i = 0; i < ESP_WIFI_NAN_MAX_SVC_SUPPORTED; i++) {
116         if (s_nan_ctx.own_svc[i].svc_id == svc_id) {
117             p_svc = &s_nan_ctx.own_svc[i];
118             break;
119         }
120     }
121 
122     return p_svc;
123 }
124 
nan_find_own_svc_by_name(const char * svc_name)125 static struct own_svc_info *nan_find_own_svc_by_name(const char *svc_name)
126 {
127     struct own_svc_info *p_svc = NULL;
128 
129     if (!svc_name) {
130         ESP_LOGE(TAG, "Service name not given!");
131         return NULL;
132     }
133 
134     for (int i = 0; i < ESP_WIFI_NAN_MAX_SVC_SUPPORTED; i++) {
135         if (s_nan_ctx.own_svc[i].svc_id && !strcmp(s_nan_ctx.own_svc[i].svc_name, svc_name)) {
136             p_svc = &s_nan_ctx.own_svc[i];
137             break;
138         }
139     }
140 
141     return p_svc;
142 }
143 
nan_find_peer_svc(uint8_t own_svc_id,uint8_t peer_svc_id,uint8_t peer_nmi[])144 static struct peer_svc_info *nan_find_peer_svc(uint8_t own_svc_id, uint8_t peer_svc_id, uint8_t peer_nmi[])
145 {
146     struct peer_svc_info *p_peer_svc = NULL, *temp;
147     struct own_svc_info *p_own_svc = NULL;
148     uint8_t *peer_nmi_valid = NULL;
149     int idx = 0;
150 
151     if (MACADDR_EQUAL(peer_nmi, null_mac)) {
152         /* non-zero Peer NMI given, use it */
153         peer_nmi_valid = peer_nmi;
154     }
155     while (idx < ESP_WIFI_NAN_MAX_SVC_SUPPORTED) {
156         if (own_svc_id) {
157             p_own_svc = nan_find_own_svc(own_svc_id);
158             if (!p_own_svc) {
159                 ESP_LOGE(TAG, "Cannot find own service with id %d!", own_svc_id);
160                 return NULL;
161             }
162         } else {
163             p_own_svc = &s_nan_ctx.own_svc[idx++];
164         }
165         SLIST_FOREACH(temp, &(p_own_svc->peer_list), next) {
166             if (peer_svc_id != 0 && peer_nmi_valid) {
167                 if (temp->svc_id == peer_svc_id && !MACADDR_EQUAL(temp->peer_nmi, peer_nmi_valid)) {
168                     p_peer_svc = temp;
169                     break;
170                 }
171             } else if (peer_svc_id != 0) {
172                 if (temp->svc_id == peer_svc_id) {
173                     p_peer_svc = temp;
174                     break;
175                 }
176             } else {
177                 if (peer_nmi_valid && !MACADDR_EQUAL(temp->peer_nmi, peer_nmi_valid)) {
178                     p_peer_svc = temp;
179                     break;
180                 }
181             }
182         }
183         if (p_peer_svc || own_svc_id) { /* If no peer found with given own_svc_id, don't search in other services */
184             break;
185         }
186     }
187     return p_peer_svc;
188 }
189 
nan_record_peer_svc(uint8_t own_svc_id,uint8_t peer_svc_id,uint8_t peer_nmi[])190 static bool nan_record_peer_svc(uint8_t own_svc_id, uint8_t peer_svc_id, uint8_t peer_nmi[])
191 {
192     struct own_svc_info *p_own_svc;
193     struct peer_svc_info *p_peer_svc;
194 
195     p_own_svc = nan_find_own_svc(own_svc_id);
196     if (!p_own_svc) {
197         ESP_LOGE(TAG, "Unable to find own service with id %d", own_svc_id);
198         return false;
199     }
200     p_peer_svc = (struct peer_svc_info *)os_zalloc(sizeof(struct peer_svc_info));
201     if (!p_peer_svc) {
202         ESP_LOGE(TAG, "Unable to allocate for Peer Service");
203         return false;
204     }
205     p_peer_svc->svc_id = peer_svc_id;
206     p_peer_svc->own_svc_id = own_svc_id;
207     p_peer_svc->type = (p_own_svc->type == ESP_NAN_SUBSCRIBE) ? ESP_NAN_PUBLISH : ESP_NAN_SUBSCRIBE;
208     MACADDR_COPY(p_peer_svc->peer_nmi, peer_nmi);
209 
210     if (p_own_svc->num_peer_records < NAN_MAX_PEERS_RECORD) {
211         SLIST_INSERT_HEAD(&(p_own_svc->peer_list), p_peer_svc, next);
212         p_own_svc->num_peer_records++;
213     } else {
214         /* Remove the oldest peer service entry */
215         struct peer_svc_info *prev_ele = NULL, *cur_ele = NULL;
216 
217         SLIST_FOREACH(cur_ele, &(p_own_svc->peer_list), next) {
218             if (SLIST_NEXT(cur_ele, next) == NULL) {
219                 if (SLIST_FIRST(&(p_own_svc->peer_list)) == cur_ele) {
220                     SLIST_REMOVE_HEAD(&(p_own_svc->peer_list), next);
221                 } else {
222                     SLIST_REMOVE_AFTER(prev_ele, next);
223                 }
224                 break;
225             }
226             prev_ele = cur_ele;
227         }
228         /* Insert new peer service entry */
229         SLIST_INSERT_HEAD(&(p_own_svc->peer_list), p_peer_svc, next);
230         os_free(cur_ele);
231     }
232 
233     return true;
234 }
235 
nan_reset_service(uint8_t svc_id,bool reset_all)236 static void nan_reset_service(uint8_t svc_id, bool reset_all)
237 {
238     struct own_svc_info *p_own_svc = NULL;
239     struct peer_svc_info *p_peer_svc = NULL, *temp;
240     int idx = 0;
241 
242     if (svc_id == 0 && !reset_all) {
243         return;
244     }
245 
246     while (idx < ESP_WIFI_NAN_MAX_SVC_SUPPORTED) {
247         p_own_svc = &s_nan_ctx.own_svc[idx++];
248         if (reset_all || (svc_id && p_own_svc->svc_id == svc_id)) {
249             SLIST_FOREACH_SAFE(p_peer_svc, &(p_own_svc->peer_list), next, temp) {
250                 SLIST_REMOVE(&(p_own_svc->peer_list), p_peer_svc, peer_svc_info, next);
251                 os_free(p_peer_svc);
252             }
253             memset(p_own_svc, 0, sizeof(struct own_svc_info));
254         }
255     }
256 }
257 
nan_reset_ndl(uint8_t ndp_id,bool reset_all)258 static void nan_reset_ndl(uint8_t ndp_id, bool reset_all)
259 {
260     struct ndl_info *ndl = NULL;
261 
262     if (reset_all) {
263         memset(s_nan_ctx.ndl, 0, sizeof(struct ndl_info) * ESP_WIFI_NAN_DATAPATH_MAX_PEERS);
264         return;
265     }
266     for (int i = 0; i < ESP_WIFI_NAN_DATAPATH_MAX_PEERS; i++) {
267         ndl = &s_nan_ctx.ndl[i];
268         if (ndl->ndp_id == ndp_id) {
269             memset(ndl, 0, sizeof(struct ndl_info));
270             break;
271         }
272     }
273 }
274 
nan_services_limit_reached(void)275 static bool nan_services_limit_reached(void)
276 {
277     for (int i = 0; i < ESP_WIFI_NAN_MAX_SVC_SUPPORTED; i++) {
278         if (s_nan_ctx.own_svc[i].svc_id == 0) {
279             return false;
280         }
281     }
282     return true;
283 }
284 
nan_record_own_svc(uint8_t id,uint8_t type,const char svc_name[],bool ndp_resp_needed)285 static void nan_record_own_svc(uint8_t id, uint8_t type, const char svc_name[], bool ndp_resp_needed)
286 {
287     struct own_svc_info *p_svc = NULL;
288 
289     for (int i = 0; i < ESP_WIFI_NAN_MAX_SVC_SUPPORTED; i++) {
290         if (s_nan_ctx.own_svc[i].svc_id == 0) {
291             p_svc = &s_nan_ctx.own_svc[i];
292             break;
293         }
294     }
295 
296     if (!p_svc) {
297         return;
298     }
299 
300     p_svc->svc_id = id;
301     p_svc->type = type;
302     strlcpy(p_svc->svc_name, svc_name, ESP_WIFI_MAX_SVC_NAME_LEN);
303     SLIST_INIT(&(p_svc->peer_list));
304     if (type == ESP_NAN_PUBLISH) {
305         p_svc->ndp_resp_needed = ndp_resp_needed;
306     }
307 }
308 
ndl_limit_reached(void)309 static bool ndl_limit_reached(void)
310 {
311     for (int i = 0; i < ESP_WIFI_NAN_DATAPATH_MAX_PEERS; i++) {
312         if (s_nan_ctx.ndl[i].ndp_id == 0) {
313             return false;
314         }
315     }
316     return true;
317 }
318 
nan_record_new_ndl(uint8_t ndp_id,uint8_t publish_id,uint8_t peer_nmi[],uint8_t own_role)319 static void nan_record_new_ndl(uint8_t ndp_id, uint8_t publish_id, uint8_t peer_nmi[], uint8_t own_role)
320 {
321     struct ndl_info *ndl = NULL;
322 
323     for (int i = 0; i < ESP_WIFI_NAN_DATAPATH_MAX_PEERS; i++) {
324         if (s_nan_ctx.ndl[i].ndp_id == 0) {
325             ndl = &s_nan_ctx.ndl[i];
326             break;
327         }
328     }
329     if (!ndl) {
330         return;
331     }
332     ndl->ndp_id = ndp_id;
333     if (peer_nmi) {
334         MACADDR_COPY(ndl->peer_nmi, peer_nmi);
335     }
336     ndl->publisher_id = publish_id;
337     ndl->own_role = own_role;
338 }
339 
nan_find_ndl(uint8_t ndp_id,uint8_t peer_nmi[])340 static struct ndl_info *nan_find_ndl(uint8_t ndp_id, uint8_t peer_nmi[])
341 {
342     struct ndl_info *ndl = NULL;
343 
344     for (int i = 0; i < ESP_WIFI_NAN_DATAPATH_MAX_PEERS; i++) {
345         ndl = &s_nan_ctx.ndl[i];
346         if (ndp_id != 0 && peer_nmi) {
347             if (ndl->ndp_id == ndp_id && !MACADDR_EQUAL(ndl->peer_nmi, peer_nmi)) {
348                 return ndl;
349             }
350         } else if (ndp_id != 0) {
351             if (ndl->ndp_id == ndp_id) {
352                 return ndl;
353             }
354         } else if (peer_nmi) {
355             if (!MACADDR_EQUAL(ndl->peer_nmi, peer_nmi)) {
356                 return ndl;
357             }
358         }
359     }
360     return NULL;
361 }
362 
nan_is_datapath_active(void)363 static bool nan_is_datapath_active(void)
364 {
365     for (int i = 0; i < ESP_WIFI_NAN_DATAPATH_MAX_PEERS; i++) {
366         if (s_nan_ctx.ndl[i].ndp_id != 0) {
367             return true;
368         }
369     }
370     return false;
371 }
372 
nan_update_peer_svc(uint8_t own_svc_id,uint8_t peer_svc_id,uint8_t peer_nmi[])373 static void nan_update_peer_svc(uint8_t own_svc_id, uint8_t peer_svc_id, uint8_t peer_nmi[])
374 {
375     struct peer_svc_info *peer_info = nan_find_peer_svc(own_svc_id, 0, peer_nmi);
376     if (peer_info) {
377         peer_info->svc_id = peer_svc_id;
378     }
379 
380     struct ndl_info *ndl = nan_find_ndl(0, peer_nmi);
381     if (ndl) {
382         ndl->publisher_id = peer_svc_id;
383     }
384 }
385 
nan_fill_params_from_event(void * evt_data,uint8_t event)386 static void nan_fill_params_from_event(void *evt_data, uint8_t event)
387 {
388     switch (event) {
389     case WIFI_EVENT_NDP_INDICATION: {
390         wifi_event_ndp_indication_t *evt = (wifi_event_ndp_indication_t *)evt_data;
391         nan_record_new_ndl(evt->ndp_id, evt->publish_id, evt->peer_nmi, ESP_WIFI_NDP_ROLE_RESPONDER);
392         break;
393     }
394     case WIFI_EVENT_NDP_CONFIRM: {
395         wifi_event_ndp_confirm_t *evt = (wifi_event_ndp_confirm_t *)evt_data;
396         struct ndl_info *ndl = NULL;
397 
398         if ((ndl = nan_find_ndl(evt->ndp_id, evt->peer_nmi)) == NULL) {
399             ESP_LOGE(TAG, "No NDL with ndp id %d", evt->ndp_id);
400             return;
401         }
402         MACADDR_COPY(ndl->peer_ndi, evt->peer_ndi);
403         break;
404     }
405     case WIFI_EVENT_NAN_REPLIED: {
406         wifi_event_nan_replied_t *evt = (wifi_event_nan_replied_t *)evt_data;
407 
408         if (!nan_find_peer_svc(evt->publish_id, evt->subscribe_id, evt->sub_if_mac)) {
409             nan_record_peer_svc(evt->publish_id, evt->subscribe_id, evt->sub_if_mac);
410         }
411         break;
412     }
413     case WIFI_EVENT_NAN_RECEIVE: {
414         wifi_event_nan_receive_t *evt = (wifi_event_nan_receive_t *)evt_data;
415 
416         if (!nan_find_peer_svc(evt->inst_id, evt->peer_inst_id, evt->peer_if_mac)) {
417             nan_record_peer_svc(evt->inst_id, evt->peer_inst_id, evt->peer_if_mac);
418         }
419         break;
420     }
421     case WIFI_EVENT_NAN_SVC_MATCH: {
422         wifi_event_nan_svc_match_t *evt = (wifi_event_nan_svc_match_t *)evt_data;
423 
424         if (evt->update_pub_id) {
425             nan_update_peer_svc(evt->subscribe_id, evt->publish_id, evt->pub_if_mac);
426         }
427 
428         if (!nan_find_peer_svc(evt->subscribe_id, evt->publish_id, evt->pub_if_mac)) {
429             nan_record_peer_svc(evt->subscribe_id, evt->publish_id, evt->pub_if_mac);
430         }
431         break;
432     }
433     default:
434         break;
435     }
436 }
437 
nan_app_action_service_match(void * arg,esp_event_base_t event_base,int32_t event_id,void * data)438 static void nan_app_action_service_match(void *arg, esp_event_base_t event_base, int32_t event_id, void *data)
439 {
440     if (data == NULL) {
441         return;
442     }
443     wifi_event_nan_svc_match_t *evt = (wifi_event_nan_svc_match_t *)data;
444 
445     ESP_LOGI(TAG, "Service matched with "MACSTR" [Peer Publish id - %d]",
446              MAC2STR(evt->pub_if_mac), evt->publish_id);
447 
448     NAN_DATA_LOCK();
449     nan_fill_params_from_event(evt, WIFI_EVENT_NAN_SVC_MATCH);
450     NAN_DATA_UNLOCK();
451 }
452 
nan_app_action_replied(void * arg,esp_event_base_t event_base,int32_t event_id,void * data)453 static void nan_app_action_replied(void *arg, esp_event_base_t event_base, int32_t event_id, void *data)
454 {
455     if (data == NULL) {
456         return;
457     }
458     wifi_event_nan_replied_t *evt = (wifi_event_nan_replied_t *)data;
459 
460     ESP_LOGD(TAG, "Sent Publish to Peer "MACSTR" [Peer Subscribe id - %d]",
461              MAC2STR(evt->sub_if_mac), evt->subscribe_id);
462 
463     NAN_DATA_LOCK();
464     nan_fill_params_from_event(evt, WIFI_EVENT_NAN_REPLIED);
465     NAN_DATA_UNLOCK();
466 }
467 
nan_app_action_receive(void * arg,esp_event_base_t event_base,int32_t event_id,void * data)468 static void nan_app_action_receive(void *arg, esp_event_base_t event_base, int32_t event_id, void *data)
469 {
470     if (data == NULL) {
471         return;
472     }
473     wifi_event_nan_receive_t *evt = (wifi_event_nan_receive_t *)data;
474 
475     ESP_LOGI(TAG, "Received message '%s' from Peer "MACSTR" [Peer Service id - %d]",
476              evt->peer_svc_info, MAC2STR(evt->peer_if_mac), evt->peer_inst_id);
477 
478     NAN_DATA_LOCK();
479     nan_fill_params_from_event(evt, WIFI_EVENT_NAN_RECEIVE);
480     NAN_DATA_UNLOCK();
481 }
482 
nan_app_action_ndp_indication(void * arg,esp_event_base_t event_base,int32_t event_id,void * data)483 static void nan_app_action_ndp_indication(void *arg, esp_event_base_t event_base, int32_t event_id, void *data)
484 {
485     if (data == NULL) {
486         return;
487     }
488     wifi_event_ndp_indication_t *evt = (wifi_event_ndp_indication_t *)data;
489 
490     NAN_DATA_LOCK();
491     struct own_svc_info *p_own_svc = nan_find_own_svc(evt->publish_id);
492 
493     if (!p_own_svc) {
494         ESP_LOGE(TAG, "No Publish found with id %d", evt->publish_id);
495         goto done;
496     }
497     if (ndl_limit_reached()) {
498         ESP_LOGE(TAG, "NDP limit reached");
499         goto done;
500     }
501 
502     nan_fill_params_from_event(evt, WIFI_EVENT_NDP_INDICATION);
503     if (p_own_svc->ndp_resp_needed) {
504         ESP_LOGI(TAG, "NDP Req from "MACSTR" [NDP Id: %d], Accept OR Deny using NDP command",
505                  MAC2STR(evt->peer_nmi), evt->ndp_id);
506         s_nan_ctx.event |= NDP_INDICATION;
507     } else {
508         wifi_nan_datapath_resp_t ndp_resp = {0};
509         ndp_resp.accept = true;
510         ndp_resp.ndp_id = evt->ndp_id;
511         MACADDR_COPY(ndp_resp.peer_mac, evt->peer_nmi);
512 
513         esp_nan_internal_datapath_resp(&ndp_resp);
514     }
515 
516 done:
517     NAN_DATA_UNLOCK();
518 }
519 
nan_app_action_ndp_confirm(void * arg,esp_event_base_t event_base,int32_t event_id,void * data)520 static void nan_app_action_ndp_confirm(void *arg, esp_event_base_t event_base, int32_t event_id, void *data)
521 {
522     if (data == NULL) {
523         return;
524     }
525     wifi_event_ndp_confirm_t *evt = (wifi_event_ndp_confirm_t *)data;
526 
527     NAN_DATA_LOCK();
528     wifi_netif_driver_t driver = esp_netif_get_io_driver(s_nan_ctx.nan_netif);
529     ip_addr_t target_addr = {0};
530 
531     if (!s_nan_ctx.nan_netif) {
532         ESP_LOGE(TAG, "%s: NAN netif is NULL", __func__);
533         goto done;
534     }
535 
536     if (nan_find_ndl(evt->ndp_id, NULL) == NULL) {
537         /* As ndl isn't found, timeout has occured for NDP response and datapath request is rejected */
538         goto done;
539     }
540     if (evt->status == NDP_STATUS_REJECTED) {
541         ESP_LOGE(TAG, "NDP request to Peer "MACSTR" rejected [NDP ID - %d]", MAC2STR(evt->peer_nmi), evt->ndp_id);
542         nan_reset_ndl(evt->ndp_id, false);
543         os_event_group_set_bits(nan_event_group, NDP_REJECTED);
544         goto done;
545     }
546 
547     /* If interface not ready when started, rxcb to be registered on connection */
548     if (esp_wifi_register_if_rxcb(driver,  esp_netif_receive, s_nan_ctx.nan_netif) != ESP_OK) {
549         ESP_LOGE(TAG, "%s: esp_wifi_register_if_rxcb failed", __func__);
550         goto done;
551     }
552 
553     nan_fill_params_from_event(evt, WIFI_EVENT_NDP_CONFIRM);
554 
555     esp_netif_action_connected(s_nan_ctx.nan_netif, event_base, event_id, data);
556 
557     esp_netif_create_ip6_linklocal(s_nan_ctx.nan_netif);
558     NAN_DATA_UNLOCK();
559     esp_wifi_nan_get_ipv6_linklocal_from_mac(&target_addr.u_addr.ip6, evt->peer_ndi);
560     target_addr.type = IPADDR_TYPE_V6;
561     ESP_LOGI(TAG, "NDP confirmed with Peer "MACSTR" [NDP ID - %d, Peer IPv6 - %s]",
562              MAC2STR(evt->peer_nmi), evt->ndp_id, inet6_ntoa(*ip_2_ip6(&target_addr)));
563     os_event_group_set_bits(nan_event_group, NDP_ACCEPTED);
564     return;
565 
566 done:
567     NAN_DATA_UNLOCK();
568     return;
569 }
570 
nan_app_action_ndp_terminated(void * arg,esp_event_base_t event_base,int32_t event_id,void * data)571 static void nan_app_action_ndp_terminated(void *arg, esp_event_base_t event_base, int32_t event_id, void *data)
572 {
573     if (data == NULL) {
574         return;
575     }
576     wifi_event_ndp_terminated_t *evt = (wifi_event_ndp_terminated_t *)data;
577 
578     NAN_DATA_LOCK();
579     if (s_nan_ctx.nan_netif && !nan_is_datapath_active()) {
580         esp_netif_action_disconnected(s_nan_ctx.nan_netif, event_base, event_id, data);
581     }
582     ESP_LOGI(TAG, "NDP terminated with Peer "MACSTR" [NDP ID - %d]", MAC2STR(evt->init_ndi), evt->ndp_id);
583     nan_reset_ndl(evt->ndp_id, false);
584 
585     s_nan_ctx.event &= ~(NDP_INDICATION);
586     NAN_DATA_UNLOCK();
587     os_event_group_set_bits(nan_event_group, NDP_TERMINATED);
588 }
589 
590 /* types of ipv6 addresses to be displayed on ipv6 events */
591 static const char *s_ipv6_addr_types[] = {
592     "UNKNOWN",
593     "GLOBAL",
594     "LINK_LOCAL",
595     "SITE_LOCAL",
596     "UNIQUE_LOCAL",
597     "IPV4_MAPPED_IPV6"
598 };
599 
nan_app_action_got_ipv6(void * arg,esp_event_base_t event_base,int32_t event_id,void * data)600 static void nan_app_action_got_ipv6(void *arg, esp_event_base_t event_base, int32_t event_id, void *data)
601 {
602     if (data == NULL) {
603         return;
604     }
605     ip_event_got_ip6_t *event = (ip_event_got_ip6_t *)data;
606 
607     NAN_DATA_LOCK();
608     if (event->esp_netif == s_nan_ctx.nan_netif) {
609         esp_ip6_addr_type_t ipv6_type = esp_netif_ip6_get_addr_type(&event->ip6_info.ip);
610         ESP_LOGD(TAG, "NAN Data Interface ready [IPv6 - "IPV6STR", type - %s]",
611                  IPV62STR(event->ip6_info.ip), s_ipv6_addr_types[ipv6_type]);
612     }
613     NAN_DATA_UNLOCK();
614 }
615 
nan_clear_app_default_handlers(void)616 static esp_err_t nan_clear_app_default_handlers(void)
617 {
618     esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_NAN_SVC_MATCH, nan_app_action_service_match);
619     esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_NAN_REPLIED, nan_app_action_replied);
620     esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_NAN_RECEIVE, nan_app_action_receive);
621     esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_NDP_INDICATION, nan_app_action_ndp_indication);
622     esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_NDP_CONFIRM, nan_app_action_ndp_confirm);
623     esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_NDP_TERMINATED, nan_app_action_ndp_terminated);
624     esp_event_handler_unregister(IP_EVENT, IP_EVENT_GOT_IP6, nan_app_action_got_ipv6);
625     s_app_default_handlers_set = false;
626 
627     return ESP_OK;
628 }
629 
nan_set_app_default_handlers(void)630 static esp_err_t nan_set_app_default_handlers(void)
631 {
632     if (s_app_default_handlers_set) {
633         return ESP_OK;
634     }
635 
636     int ret;
637     (void) ret;
638     ESP_GOTO_ON_ERROR(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_NAN_SVC_MATCH,
639                                                  nan_app_action_service_match, NULL), fail, TAG, "Registering event handler failed");
640 
641     ESP_GOTO_ON_ERROR(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_NAN_REPLIED,
642                                              nan_app_action_replied, NULL), fail, TAG, "Registering event handler failed");
643 
644     ESP_GOTO_ON_ERROR(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_NAN_RECEIVE,
645                                              nan_app_action_receive, NULL), fail, TAG, "Registering event handler failed");
646 
647     ESP_GOTO_ON_ERROR(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_NDP_INDICATION,
648                                              nan_app_action_ndp_indication, NULL), fail, TAG, "Registering event handler failed");
649 
650     ESP_GOTO_ON_ERROR(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_NDP_CONFIRM,
651                                              nan_app_action_ndp_confirm, NULL), fail, TAG, "Registering event handler failed");
652 
653     ESP_GOTO_ON_ERROR(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_NDP_TERMINATED,
654                                              nan_app_action_ndp_terminated, NULL), fail, TAG, "Registering event handler failed");
655 
656     ESP_GOTO_ON_ERROR(esp_event_handler_register(IP_EVENT, IP_EVENT_GOT_IP6,
657                                              nan_app_action_got_ipv6, NULL), fail, TAG, "Registering event handler failed");
658 
659     s_app_default_handlers_set = true;
660     return ESP_OK;
661 
662 fail:
663     nan_clear_app_default_handlers();
664     return ESP_FAIL;
665 }
666 
esp_nan_app_deinit(void)667 void esp_nan_app_deinit(void)
668 {
669     if (nan_event_group) {
670         os_event_group_delete(nan_event_group);
671         nan_event_group = NULL;
672     }
673 
674     if (s_nan_data_lock) {
675         os_mutex_delete(s_nan_data_lock);
676         s_nan_data_lock = NULL;
677     }
678 }
679 
esp_nan_app_init(void)680 void esp_nan_app_init(void)
681 {
682     if (nan_event_group) {
683         os_event_group_delete(nan_event_group);
684         nan_event_group = NULL;
685     }
686     nan_event_group = os_event_group_create();
687 
688     s_nan_data_lock = os_recursive_mutex_create();
689     if (!s_nan_data_lock) {
690         ESP_LOGE(TAG, "Failed to create NAN data lock");
691         esp_nan_app_deinit();
692     }
693 }
694 
esp_nan_action_start(esp_netif_t * nan_netif)695 void esp_nan_action_start(esp_netif_t *nan_netif)
696 {
697     if (nan_set_app_default_handlers() != ESP_OK) {
698         ESP_LOGE(TAG, "Registering NAN handlers failed");
699         return;
700     }
701 
702     NAN_DATA_LOCK();
703     s_nan_ctx.nan_netif = nan_netif;
704     s_nan_ctx.state = NAN_STARTED_BIT;
705     NAN_DATA_UNLOCK();
706 
707     ESP_LOGI(TAG, "NAN Discovery started.");
708     os_event_group_set_bits(nan_event_group, NAN_STARTED_BIT);
709 }
710 
esp_nan_action_stop(void)711 void esp_nan_action_stop(void)
712 {
713     nan_clear_app_default_handlers();
714 
715     NAN_DATA_LOCK();
716     if (nan_is_datapath_active()) {
717         nan_reset_ndl(0, true);
718         esp_wifi_internal_reg_rxcb(WIFI_IF_NAN, NULL);
719     }
720 
721     nan_reset_service(0, true);
722     s_nan_ctx.state &= ~NAN_STARTED_BIT;
723     s_nan_ctx.state |= NAN_STOPPED_BIT;
724     NAN_DATA_UNLOCK();
725 
726     os_event_group_set_bits(nan_event_group, NAN_STOPPED_BIT);
727 }
728 
esp_wifi_nan_start(const wifi_nan_config_t * nan_cfg)729 esp_err_t esp_wifi_nan_start(const wifi_nan_config_t *nan_cfg)
730 {
731     wifi_mode_t mode;
732     esp_err_t ret;
733     wifi_config_t config = {0};
734 
735     ret = esp_wifi_get_mode(&mode);
736     if (ret == ESP_ERR_WIFI_NOT_INIT) {
737         ESP_LOGE(TAG, "WiFi not initialised!");
738         return ret;
739     } else if (ret != ESP_OK) {
740         ESP_LOGE(TAG, "Unable to get mode");
741         return ret;
742     }
743 
744     if (!s_nan_data_lock) {
745         ESP_LOGE(TAG, "NAN Data lock doesn't exist");
746         return ESP_FAIL;
747     }
748 
749     NAN_DATA_LOCK();
750     if (s_nan_ctx.state & NAN_STARTED_BIT) {
751         ESP_LOGI(TAG, "NAN already started");
752         NAN_DATA_UNLOCK();
753         return ESP_OK;
754     }
755     NAN_DATA_UNLOCK();
756 
757     ESP_RETURN_ON_ERROR(esp_wifi_set_mode(WIFI_MODE_NAN), TAG, "Set mode NAN failed");
758 
759     memcpy(&config.nan, nan_cfg, sizeof(wifi_nan_config_t));
760     ESP_RETURN_ON_ERROR(esp_wifi_set_config(WIFI_IF_NAN, &config), TAG, "Setting NAN config failed");
761 
762     if (esp_wifi_start() != ESP_OK) {
763         ESP_LOGE(TAG, "Starting wifi failed");
764         NAN_DATA_LOCK();
765         s_nan_ctx.nan_netif = NULL;
766         NAN_DATA_UNLOCK();
767         return ESP_FAIL;
768     }
769 
770     EventBits_t bits = os_event_group_wait_bits(nan_event_group, NAN_STARTED_BIT, pdFALSE, pdFALSE, portMAX_DELAY);
771     if (!(bits & NAN_STARTED_BIT)) {
772         NAN_DATA_LOCK();
773         s_nan_ctx.nan_netif = NULL;
774         NAN_DATA_UNLOCK();
775         return ESP_FAIL;
776     }
777     return ESP_OK;
778 }
779 
esp_wifi_nan_stop(void)780 esp_err_t esp_wifi_nan_stop(void)
781 {
782     NAN_DATA_LOCK();
783     if (!(s_nan_ctx.state & NAN_STARTED_BIT)) {
784         ESP_LOGE(TAG, "NAN isn't started");
785         NAN_DATA_UNLOCK();
786         return ESP_FAIL;
787     }
788 
789     if (nan_is_datapath_active()) {
790         /* Terminate all NDP's */
791         wifi_nan_datapath_end_req_t ndp_end = {0};
792         for (int i=0; i < ESP_WIFI_NAN_DATAPATH_MAX_PEERS; i++) {
793              if (s_nan_ctx.ndl[i].ndp_id) {
794                  MACADDR_COPY(ndp_end.peer_mac, s_nan_ctx.ndl[i].peer_nmi);
795                  ndp_end.ndp_id = s_nan_ctx.ndl[i].ndp_id;
796                  esp_nan_internal_datapath_end(&ndp_end);
797              }
798         }
799         nan_reset_ndl(0, true);
800 
801         NAN_DATA_UNLOCK();
802         os_event_group_clear_bits(nan_event_group, NDP_TERMINATED);
803         os_event_group_wait_bits(nan_event_group, NDP_TERMINATED, pdFALSE, pdFALSE, pdMS_TO_TICKS(NAN_NDP_TERM_TIMEOUT));
804         os_event_group_clear_bits(nan_event_group, NDP_TERMINATED);
805         /* Wait for 1 NAN DW interval (512 TU's ~= 524 mSec) for successful termination */
806         g_wifi_osi_funcs._task_delay(NAN_DW_INTVL_MS/portTICK_PERIOD_MS);
807     } else {
808         NAN_DATA_UNLOCK();
809     }
810 
811     ESP_RETURN_ON_ERROR(esp_wifi_stop(), TAG, "Stopping NAN failed");
812 
813     EventBits_t bits = os_event_group_wait_bits(nan_event_group, NAN_STOPPED_BIT, pdFALSE, pdFALSE, portMAX_DELAY);
814     if (!(bits & NAN_STOPPED_BIT)) {
815         return ESP_FAIL;
816     }
817 
818     NAN_DATA_LOCK();
819     memset(&s_nan_ctx, 0, sizeof(nan_ctx_t));
820     NAN_DATA_UNLOCK();
821     return ESP_OK;
822 }
823 
esp_wifi_nan_publish_service(const wifi_nan_publish_cfg_t * publish_cfg,bool ndp_resp_needed)824 uint8_t esp_wifi_nan_publish_service(const wifi_nan_publish_cfg_t *publish_cfg, bool ndp_resp_needed)
825 {
826     uint8_t pub_id;
827 
828     NAN_DATA_LOCK();
829     if (!(s_nan_ctx.state & NAN_STARTED_BIT)) {
830         ESP_LOGE(TAG, "NAN not started!");
831         goto fail;
832     }
833     if (nan_services_limit_reached()) {
834         ESP_LOGE(TAG, "Maximum services limit reached");
835         goto fail;
836     }
837 
838     if (nan_find_own_svc_by_name(publish_cfg->service_name)) {
839         ESP_LOGE(TAG, "Service name %s already used!", publish_cfg->service_name);
840         goto fail;
841     }
842 
843     if (esp_nan_internal_publish_service(publish_cfg, &pub_id, false) != ESP_OK) {
844         ESP_LOGE(TAG, "Failed to publish service '%s'", publish_cfg->service_name);
845         goto fail;
846     }
847 
848     ESP_LOGI(TAG, "Started Publishing %s [Service ID - %u]", publish_cfg->service_name, pub_id);
849     nan_record_own_svc(pub_id, ESP_NAN_PUBLISH, publish_cfg->service_name, ndp_resp_needed);
850     NAN_DATA_UNLOCK();
851 
852     return pub_id;
853 fail:
854     NAN_DATA_UNLOCK();
855     return 0;
856 }
857 
esp_wifi_nan_subscribe_service(const wifi_nan_subscribe_cfg_t * subscribe_cfg)858 uint8_t esp_wifi_nan_subscribe_service(const wifi_nan_subscribe_cfg_t *subscribe_cfg)
859 {
860     uint8_t sub_id;
861 
862     NAN_DATA_LOCK();
863     if (!(s_nan_ctx.state & NAN_STARTED_BIT)) {
864         ESP_LOGE(TAG, "NAN not started!");
865         goto fail;
866     }
867     if (nan_services_limit_reached()) {
868         ESP_LOGE(TAG, "Maximum services limit reached");
869         goto fail;
870     }
871 
872     if (nan_find_own_svc_by_name(subscribe_cfg->service_name)) {
873         ESP_LOGE(TAG, "Service name already used!");
874         goto fail;
875     }
876 
877     if (esp_nan_internal_subscribe_service(subscribe_cfg, &sub_id, false) != ESP_OK) {
878         ESP_LOGE(TAG, "Failed to subscribe to service '%s'", subscribe_cfg->service_name);
879         goto fail;
880     }
881 
882     ESP_LOGI(TAG, "Started Subscribing to %s [Service ID - %u]", subscribe_cfg->service_name, sub_id);
883     nan_record_own_svc(sub_id, ESP_NAN_SUBSCRIBE, subscribe_cfg->service_name, false);
884     NAN_DATA_UNLOCK();
885 
886     return sub_id;
887 fail:
888     NAN_DATA_UNLOCK();
889     return 0;
890 }
891 
esp_wifi_nan_send_message(wifi_nan_followup_params_t * fup_params)892 esp_err_t esp_wifi_nan_send_message(wifi_nan_followup_params_t *fup_params)
893 {
894     struct peer_svc_info *p_peer_svc;
895 
896     NAN_DATA_LOCK();
897     p_peer_svc = nan_find_peer_svc(fup_params->inst_id, fup_params->peer_inst_id,
898                                         fup_params->peer_mac);
899     if (!p_peer_svc) {
900         ESP_LOGE(TAG, "Cannot send Follow-up, peer not found!");
901         NAN_DATA_UNLOCK();
902         return ESP_FAIL;
903     }
904 
905     if (!fup_params->inst_id) {
906         fup_params->inst_id = p_peer_svc->own_svc_id;
907     }
908     if (!fup_params->peer_inst_id) {
909         fup_params->peer_inst_id = p_peer_svc->svc_id;
910     }
911     if (!MACADDR_EQUAL(fup_params->peer_mac, null_mac)) {
912         MACADDR_COPY(fup_params->peer_mac, p_peer_svc->peer_nmi);
913     }
914 
915     NAN_DATA_UNLOCK();
916     if (esp_nan_internal_send_followup(fup_params) != ESP_OK) {
917         ESP_LOGE(TAG, "Failed to send Follow-up message!");
918         return ESP_FAIL;
919     }
920     ESP_LOGI(TAG, "Sent message '%s' to Peer "MACSTR" with Service ID %d", fup_params->svc_info,
921                   MAC2STR(fup_params->peer_mac), fup_params->peer_inst_id);
922     return ESP_OK;
923 }
924 
esp_wifi_nan_cancel_service(uint8_t service_id)925 esp_err_t esp_wifi_nan_cancel_service(uint8_t service_id)
926 {
927     NAN_DATA_LOCK();
928     struct own_svc_info *p_own_svc = nan_find_own_svc(service_id);
929 
930     if (!p_own_svc) {
931         ESP_LOGE(TAG, "Cannot find own service with id %d!", service_id);
932         goto fail;
933     }
934 
935     if (p_own_svc->type == ESP_NAN_PUBLISH) {
936         if (esp_nan_internal_publish_service(NULL, &service_id, true) == ESP_OK) {
937             nan_reset_service(service_id, false);
938             ESP_LOGI(TAG, "Cancelled Publish with Service ID %d", service_id);
939             goto done;
940         }
941     }
942 
943     if (p_own_svc->type == ESP_NAN_SUBSCRIBE) {
944         if (esp_nan_internal_subscribe_service(NULL, &service_id, true) == ESP_OK) {
945             nan_reset_service(service_id, false);
946             ESP_LOGI(TAG, "Cancelled Subscribe with Service ID %d", service_id);
947             goto done;
948         }
949     }
950 
951 fail:
952     NAN_DATA_UNLOCK();
953     return ESP_FAIL;
954 
955 done:
956     NAN_DATA_UNLOCK();
957     return ESP_OK;
958 }
959 
esp_wifi_nan_datapath_req(wifi_nan_datapath_req_t * req)960 uint8_t esp_wifi_nan_datapath_req(wifi_nan_datapath_req_t *req)
961 {
962     uint8_t ndp_id = 0;
963 
964     NAN_DATA_LOCK();
965     struct peer_svc_info *p_peer_svc = nan_find_peer_svc(0, req->pub_id, req->peer_mac);
966 
967     if (!p_peer_svc) {
968         ESP_LOGE(TAG, "Cannot send NDP Req, peer not found!");
969         goto fail;
970     }
971     if (req->pub_id == 0)
972         req->pub_id = p_peer_svc->svc_id;
973 
974     if (p_peer_svc->type != ESP_NAN_PUBLISH) {
975         ESP_LOGE(TAG, "Only subscriber can send an NDP Req to a Publisher");
976         goto fail;
977     }
978     if (ndl_limit_reached()) {
979         ESP_LOGE(TAG, "Cannot establish new datapath, limit reached!");
980         goto fail;
981     }
982 
983     if (!MACADDR_EQUAL(req->peer_mac, null_mac)) {
984         MACADDR_COPY(req->peer_mac, p_peer_svc->peer_nmi);
985     }
986 
987     if (esp_nan_internal_datapath_req(req, &ndp_id) != ESP_OK) {
988         ESP_LOGE(TAG, "Failed to initiate NDP req");
989         goto fail;
990     }
991 
992     nan_record_new_ndl(ndp_id, req->pub_id, req->peer_mac, ESP_WIFI_NDP_ROLE_INITIATOR);
993     NAN_DATA_UNLOCK();
994 
995     ESP_LOGD(TAG, "Requested NDP with "MACSTR" [NDP ID - %d]", MAC2STR(req->peer_mac), ndp_id);
996 
997     EventBits_t bits = os_event_group_wait_bits(nan_event_group, NDP_ACCEPTED | NDP_REJECTED, pdFALSE, pdFALSE, pdMS_TO_TICKS(NAN_NDP_RESP_TIMEOUT));
998     if (bits & NDP_ACCEPTED) {
999         os_event_group_clear_bits(nan_event_group, NDP_ACCEPTED);
1000         return ndp_id;
1001     } else if (bits & NDP_REJECTED) {
1002         os_event_group_clear_bits(nan_event_group, NDP_REJECTED);
1003         return 0;
1004     } else {
1005         NAN_DATA_LOCK();
1006         nan_reset_ndl(ndp_id, false);
1007         NAN_DATA_UNLOCK();
1008         return 0;
1009     }
1010 fail:
1011     NAN_DATA_UNLOCK();
1012     return 0;
1013 }
1014 
esp_wifi_nan_datapath_resp(wifi_nan_datapath_resp_t * resp)1015 esp_err_t esp_wifi_nan_datapath_resp(wifi_nan_datapath_resp_t *resp)
1016 {
1017     NAN_DATA_LOCK();
1018     struct ndl_info *ndl = nan_find_ndl(resp->ndp_id, NULL);
1019 
1020     if (!ndl) {
1021         ESP_LOGE(TAG, "No NDL with ndp id %d", resp->ndp_id);
1022         goto fail;
1023     }
1024     if (!(s_nan_ctx.event & NDP_INDICATION)) { //INDICATION of specific peer
1025         ESP_LOGE(TAG, "Need NDP Indication before NDP Response can be sent");
1026         goto fail;
1027     }
1028 
1029     if (!MACADDR_EQUAL(resp->peer_mac, null_mac)) {
1030         MACADDR_COPY(resp->peer_mac, ndl->peer_nmi);
1031     }
1032 
1033     if (esp_nan_internal_datapath_resp(resp) == ESP_OK) {
1034         s_nan_ctx.event &= ~NDP_INDICATION;
1035         NAN_DATA_UNLOCK();
1036         return ESP_OK;
1037     }
1038 
1039 fail:
1040     NAN_DATA_UNLOCK();
1041     return ESP_FAIL;
1042 }
1043 
esp_wifi_nan_datapath_end(wifi_nan_datapath_end_req_t * req)1044 esp_err_t esp_wifi_nan_datapath_end(wifi_nan_datapath_end_req_t *req)
1045 {
1046     struct ndl_info *ndl = NULL;
1047 
1048     NAN_DATA_LOCK();
1049     if (!nan_is_datapath_active()) {
1050         ESP_LOGE(TAG, "No Datapath active");
1051         NAN_DATA_UNLOCK();
1052         return ESP_FAIL;
1053     }
1054 
1055     ndl = nan_find_ndl(req->ndp_id, NULL);
1056     if (!ndl) {
1057         ESP_LOGE(TAG, "No NDL with ndp id %d", req->ndp_id);
1058         NAN_DATA_UNLOCK();
1059         return ESP_FAIL;
1060     }
1061 
1062     if (!MACADDR_EQUAL(req->peer_mac, null_mac)) {
1063         MACADDR_COPY(req->peer_mac, ndl->peer_nmi);
1064     }
1065 
1066     NAN_DATA_UNLOCK();
1067     if (esp_nan_internal_datapath_end(req) == ESP_OK) {
1068         return ESP_OK;
1069     }
1070 
1071     return ESP_FAIL;
1072 }
1073 
esp_wifi_nan_get_own_svc_info(uint8_t * own_svc_id,char * svc_name,int * num_peer_records)1074 esp_err_t esp_wifi_nan_get_own_svc_info(uint8_t *own_svc_id, char *svc_name, int *num_peer_records)
1075 {
1076     struct own_svc_info *own_svc = NULL;
1077 
1078     if (!own_svc_id || !num_peer_records || !svc_name) {
1079         ESP_LOGE(TAG, "NULL memory address for input parameters");
1080         return ESP_FAIL;
1081     }
1082 
1083     NAN_DATA_LOCK();
1084     if (*own_svc_id == 0) {
1085         own_svc = nan_find_own_svc_by_name(svc_name);
1086         if (!own_svc) {
1087             ESP_LOGE(TAG, "No record found for given service name %s", svc_name);
1088             goto fail;
1089         }
1090         *own_svc_id = own_svc->svc_id;
1091     } else {
1092         own_svc = nan_find_own_svc(*own_svc_id);
1093         if (!own_svc) {
1094             ESP_LOGE(TAG, "No record found for given service ID %d", *own_svc_id);
1095             goto fail;
1096         }
1097         strlcpy(svc_name, own_svc->svc_name, ESP_WIFI_MAX_SVC_NAME_LEN);
1098     }
1099 
1100     *num_peer_records = own_svc->num_peer_records;
1101     NAN_DATA_UNLOCK();
1102     return ESP_OK;
1103 
1104 fail:
1105     NAN_DATA_UNLOCK();
1106     return ESP_FAIL;
1107 }
1108 
esp_wifi_nan_get_peer_records(int * num_peer_records,uint8_t own_svc_id,struct nan_peer_record * peer_record)1109 esp_err_t esp_wifi_nan_get_peer_records(int *num_peer_records, uint8_t own_svc_id, struct nan_peer_record *peer_record)
1110 {
1111     struct own_svc_info *own_record = NULL;
1112     struct peer_svc_info *temp = NULL;
1113     int peer_num = 0;
1114 
1115     if (!peer_record || !num_peer_records) {
1116         ESP_LOGE(TAG, "NULL memory address for input parameters");
1117         return ESP_FAIL;
1118     }
1119     if (own_svc_id == 0) {
1120         ESP_LOGE(TAG, "Invalid service ID");
1121         return ESP_FAIL;
1122     }
1123     if (*num_peer_records == 0) {
1124         ESP_LOGE(TAG, "Number of peer records provided is 0");
1125         return ESP_FAIL;
1126     }
1127 
1128     NAN_DATA_LOCK();
1129     own_record = nan_find_own_svc(own_svc_id);
1130     if (own_record) {
1131         SLIST_FOREACH(temp, &(own_record->peer_list), next) {
1132             struct ndl_info *p_ndl;
1133             peer_record[peer_num].peer_svc_id = temp->svc_id;
1134             peer_record[peer_num].own_svc_id = own_svc_id;
1135             peer_record[peer_num].peer_svc_type = temp->type;
1136             MACADDR_COPY(peer_record[peer_num].peer_nmi, temp->peer_nmi);
1137             p_ndl = nan_find_ndl(0, temp->peer_nmi);
1138             if (p_ndl) {
1139                 if (p_ndl->own_role == ESP_NAN_PUBLISH) {
1140                     if (p_ndl->publisher_id == own_svc_id) {
1141                         peer_record[peer_num].ndp_id = p_ndl->ndp_id;
1142                         MACADDR_COPY(peer_record[peer_num].peer_ndi, p_ndl->peer_ndi);
1143                     }
1144                 } else if (p_ndl->own_role == ESP_NAN_SUBSCRIBE) {
1145                     struct peer_svc_info *peer_info = NULL;
1146                     peer_info = nan_find_peer_svc(own_svc_id, temp->svc_id, temp->peer_nmi);
1147                     if (peer_info && peer_info->svc_id == p_ndl->publisher_id) {
1148                         peer_record[peer_num].ndp_id = p_ndl->ndp_id;
1149                         MACADDR_COPY(peer_record[peer_num].peer_ndi, p_ndl->peer_ndi);
1150                     }
1151                 }
1152             } else {
1153                 peer_record[peer_num].ndp_id = 0;
1154                 MACADDR_COPY(peer_record[peer_num].peer_ndi, null_mac);
1155             }
1156             peer_num ++;
1157             if (peer_num == *num_peer_records) {
1158                 break;
1159             }
1160         }
1161         if (*num_peer_records > peer_num) {
1162             *num_peer_records = peer_num;
1163         }
1164 
1165         NAN_DATA_UNLOCK();
1166         return ESP_OK;
1167     } else {
1168         *num_peer_records = 0;
1169         ESP_LOGD(TAG, "No record found for own service id %d", own_svc_id);
1170         NAN_DATA_UNLOCK();
1171         return ESP_FAIL;
1172     }
1173 }
1174 
esp_wifi_nan_get_peer_info(char * svc_name,uint8_t * peer_mac,struct nan_peer_record * peer_info)1175 esp_err_t esp_wifi_nan_get_peer_info(char *svc_name, uint8_t *peer_mac, struct nan_peer_record *peer_info)
1176 {
1177     struct peer_svc_info *peer_svc = NULL;
1178     uint8_t own_svc_id = 0;
1179 
1180     if (!peer_mac || !peer_info) {
1181         ESP_LOGE(TAG, "Invalid memory address for input parameters");
1182         return ESP_FAIL;
1183     }
1184 
1185     NAN_DATA_LOCK();
1186     if (svc_name) {
1187         struct own_svc_info *own_svc = nan_find_own_svc_by_name(svc_name);
1188         if (!own_svc) {
1189             ESP_LOGE(TAG, "No record found for given service name %s", svc_name);
1190             NAN_DATA_UNLOCK();
1191             return ESP_FAIL;
1192         }
1193         own_svc_id = own_svc->svc_id;
1194     }
1195 
1196     peer_svc = nan_find_peer_svc(own_svc_id, 0, peer_mac);
1197     if (peer_svc) {
1198         struct ndl_info *p_ndl;
1199         peer_info->peer_svc_id = peer_svc->svc_id;
1200         peer_info->own_svc_id = peer_svc->own_svc_id;
1201         peer_info->peer_svc_type = peer_svc->type;
1202         MACADDR_COPY(peer_info->peer_nmi, peer_mac);
1203         p_ndl = nan_find_ndl(0, peer_mac);
1204         if (p_ndl) {
1205             peer_info->ndp_id = p_ndl->ndp_id;
1206             MACADDR_COPY(peer_info->peer_ndi, p_ndl->peer_ndi);
1207         } else {
1208             peer_info->ndp_id = 0;
1209             MACADDR_COPY(peer_info->peer_ndi, null_mac);
1210         }
1211         NAN_DATA_UNLOCK();
1212         return ESP_OK;
1213     } else {
1214         ESP_LOGD(TAG, "No record found for Peer "MACSTR, MAC2STR(peer_mac));
1215         NAN_DATA_UNLOCK();
1216         return ESP_FAIL;
1217     }
1218 }
1219