1 /* 2 * NAN unsynchronized service discovery (USD) 3 * Copyright (c) 2024, Qualcomm Innovation Center, Inc. 4 * 5 * This software may be distributed under the terms of the BSD license. 6 * See README for more details. 7 */ 8 9 #include "utils/includes.h" 10 11 #include "utils/common.h" 12 #include "common/nan_de.h" 13 #include "wpa_supplicant_i.h" 14 #include "offchannel.h" 15 #include "driver_i.h" 16 #include "nan_usd.h" 17 18 19 static const char * 20 tx_status_result_txt(enum offchannel_send_action_result result) 21 { 22 switch (result) { 23 case OFFCHANNEL_SEND_ACTION_SUCCESS: 24 return "success"; 25 case OFFCHANNEL_SEND_ACTION_NO_ACK: 26 return "no-ack"; 27 case OFFCHANNEL_SEND_ACTION_FAILED: 28 return "failed"; 29 } 30 31 return "?"; 32 } 33 34 35 static void wpas_nan_de_tx_status(struct wpa_supplicant *wpa_s, 36 unsigned int freq, const u8 *dst, 37 const u8 *src, const u8 *bssid, 38 const u8 *data, size_t data_len, 39 enum offchannel_send_action_result result) 40 { 41 if (!wpa_s->nan_de) 42 return; 43 44 wpa_printf(MSG_DEBUG, "NAN: TX status A1=" MACSTR " A2=" MACSTR 45 " A3=" MACSTR " freq=%d len=%zu result=%s", 46 MAC2STR(dst), MAC2STR(src), MAC2STR(bssid), freq, 47 data_len, tx_status_result_txt(result)); 48 49 nan_de_tx_status(wpa_s->nan_de, freq, dst); 50 } 51 52 53 struct wpas_nan_usd_tx_work { 54 unsigned int freq; 55 unsigned int wait_time; 56 u8 dst[ETH_ALEN]; 57 u8 src[ETH_ALEN]; 58 u8 bssid[ETH_ALEN]; 59 struct wpabuf *buf; 60 }; 61 62 63 static void wpas_nan_usd_tx_work_free(struct wpas_nan_usd_tx_work *twork) 64 { 65 if (!twork) 66 return; 67 wpabuf_free(twork->buf); 68 os_free(twork); 69 } 70 71 72 static void wpas_nan_usd_tx_work_done(struct wpa_supplicant *wpa_s) 73 { 74 struct wpas_nan_usd_tx_work *twork; 75 76 if (!wpa_s->nan_usd_tx_work) 77 return; 78 79 twork = wpa_s->nan_usd_tx_work->ctx; 80 wpas_nan_usd_tx_work_free(twork); 81 radio_work_done(wpa_s->nan_usd_tx_work); 82 wpa_s->nan_usd_tx_work = NULL; 83 } 84 85 86 static int wpas_nan_de_tx_send(struct wpa_supplicant *wpa_s, unsigned int freq, 87 unsigned int wait_time, const u8 *dst, 88 const u8 *src, const u8 *bssid, 89 const struct wpabuf *buf) 90 { 91 wpa_printf(MSG_DEBUG, "NAN: TX NAN SDF A1=" MACSTR " A2=" MACSTR 92 " A3=" MACSTR " freq=%d len=%zu", 93 MAC2STR(dst), MAC2STR(src), MAC2STR(bssid), freq, 94 wpabuf_len(buf)); 95 96 return offchannel_send_action(wpa_s, freq, dst, src, bssid, 97 wpabuf_head(buf), wpabuf_len(buf), 98 wait_time, wpas_nan_de_tx_status, 1); 99 } 100 101 102 static void wpas_nan_usd_start_tx_cb(struct wpa_radio_work *work, int deinit) 103 { 104 struct wpa_supplicant *wpa_s = work->wpa_s; 105 struct wpas_nan_usd_tx_work *twork = work->ctx; 106 107 if (deinit) { 108 if (work->started) { 109 wpa_s->nan_usd_tx_work = NULL; 110 offchannel_send_action_done(wpa_s); 111 } 112 wpas_nan_usd_tx_work_free(twork); 113 return; 114 } 115 116 wpa_s->nan_usd_tx_work = work; 117 118 if (wpas_nan_de_tx_send(wpa_s, twork->freq, twork->wait_time, 119 twork->dst, twork->src, twork->bssid, 120 twork->buf) < 0) 121 wpas_nan_usd_tx_work_done(wpa_s); 122 } 123 124 125 static int wpas_nan_de_tx(void *ctx, unsigned int freq, unsigned int wait_time, 126 const u8 *dst, const u8 *src, const u8 *bssid, 127 const struct wpabuf *buf) 128 { 129 struct wpa_supplicant *wpa_s = ctx; 130 struct wpas_nan_usd_tx_work *twork; 131 132 if (wpa_s->nan_usd_tx_work || wpa_s->nan_usd_listen_work) { 133 /* Reuse ongoing radio work */ 134 return wpas_nan_de_tx_send(wpa_s, freq, wait_time, dst, src, 135 bssid, buf); 136 } 137 138 twork = os_zalloc(sizeof(*twork)); 139 if (!twork) 140 return -1; 141 twork->freq = freq; 142 twork->wait_time = wait_time; 143 os_memcpy(twork->dst, dst, ETH_ALEN); 144 os_memcpy(twork->src, src, ETH_ALEN); 145 os_memcpy(twork->bssid, bssid, ETH_ALEN); 146 twork->buf = wpabuf_dup(buf); 147 if (!twork->buf) { 148 wpas_nan_usd_tx_work_free(twork); 149 return -1; 150 } 151 152 if (radio_add_work(wpa_s, freq, "nan-usd-tx", 0, 153 wpas_nan_usd_start_tx_cb, twork) < 0) { 154 wpas_nan_usd_tx_work_free(twork); 155 return -1; 156 } 157 158 return 0; 159 } 160 161 162 struct wpas_nan_usd_listen_work { 163 unsigned int freq; 164 unsigned int duration; 165 }; 166 167 168 static void wpas_nan_usd_listen_work_done(struct wpa_supplicant *wpa_s) 169 { 170 struct wpas_nan_usd_listen_work *lwork; 171 172 if (!wpa_s->nan_usd_listen_work) 173 return; 174 175 lwork = wpa_s->nan_usd_listen_work->ctx; 176 os_free(lwork); 177 radio_work_done(wpa_s->nan_usd_listen_work); 178 wpa_s->nan_usd_listen_work = NULL; 179 } 180 181 182 static void wpas_nan_usd_start_listen_cb(struct wpa_radio_work *work, 183 int deinit) 184 { 185 struct wpa_supplicant *wpa_s = work->wpa_s; 186 struct wpas_nan_usd_listen_work *lwork = work->ctx; 187 unsigned int duration; 188 189 if (deinit) { 190 if (work->started) { 191 wpa_s->nan_usd_listen_work = NULL; 192 wpa_drv_cancel_remain_on_channel(wpa_s); 193 } 194 os_free(lwork); 195 return; 196 } 197 198 wpa_s->nan_usd_listen_work = work; 199 200 duration = lwork->duration; 201 if (duration > wpa_s->max_remain_on_chan) 202 duration = wpa_s->max_remain_on_chan; 203 wpa_printf(MSG_DEBUG, "NAN: Start listen on %u MHz for %u ms", 204 lwork->freq, duration); 205 if (wpa_drv_remain_on_channel(wpa_s, lwork->freq, duration) < 0) { 206 wpa_printf(MSG_DEBUG, 207 "NAN: Failed to request the driver to remain on channel (%u MHz) for listen", 208 lwork->freq); 209 wpas_nan_usd_listen_work_done(wpa_s); 210 return; 211 } 212 } 213 214 215 static int wpas_nan_de_listen(void *ctx, unsigned int freq, 216 unsigned int duration) 217 { 218 struct wpa_supplicant *wpa_s = ctx; 219 struct wpas_nan_usd_listen_work *lwork; 220 221 lwork = os_zalloc(sizeof(*lwork)); 222 if (!lwork) 223 return -1; 224 lwork->freq = freq; 225 lwork->duration = duration; 226 227 if (radio_add_work(wpa_s, freq, "nan-usd-listen", 0, 228 wpas_nan_usd_start_listen_cb, lwork) < 0) { 229 os_free(lwork); 230 return -1; 231 } 232 233 return 0; 234 } 235 236 237 static void 238 wpas_nan_de_discovery_result(void *ctx, int subscribe_id, 239 enum nan_service_protocol_type srv_proto_type, 240 const u8 *ssi, size_t ssi_len, int peer_publish_id, 241 const u8 *peer_addr, bool fsd, bool fsd_gas) 242 { 243 struct wpa_supplicant *wpa_s = ctx; 244 char *ssi_hex; 245 246 ssi_hex = os_zalloc(2 * ssi_len + 1); 247 if (!ssi_hex) 248 return; 249 if (ssi) 250 wpa_snprintf_hex(ssi_hex, 2 * ssi_len + 1, ssi, ssi_len); 251 wpa_msg(wpa_s, MSG_INFO, NAN_DISCOVERY_RESULT 252 "subscribe_id=%d publish_id=%d address=" MACSTR 253 " fsd=%d fsd_gas=%d srv_proto_type=%u ssi=%s", 254 subscribe_id, peer_publish_id, MAC2STR(peer_addr), 255 fsd, fsd_gas, srv_proto_type, ssi_hex); 256 os_free(ssi_hex); 257 } 258 259 260 static void wpas_nan_de_replied(void *ctx, int publish_id, const u8 *peer_addr, 261 int peer_subscribe_id, 262 enum nan_service_protocol_type srv_proto_type, 263 const u8 *ssi, size_t ssi_len) 264 { 265 struct wpa_supplicant *wpa_s = ctx; 266 char *ssi_hex; 267 268 ssi_hex = os_zalloc(2 * ssi_len + 1); 269 if (!ssi_hex) 270 return; 271 if (ssi) 272 wpa_snprintf_hex(ssi_hex, 2 * ssi_len + 1, ssi, ssi_len); 273 wpa_msg(wpa_s, MSG_INFO, NAN_REPLIED 274 "publish_id=%d address=" MACSTR 275 " subscribe_id=%d srv_proto_type=%u ssi=%s", 276 publish_id, MAC2STR(peer_addr), peer_subscribe_id, 277 srv_proto_type, ssi_hex); 278 os_free(ssi_hex); 279 } 280 281 282 static const char * nan_reason_txt(enum nan_de_reason reason) 283 { 284 switch (reason) { 285 case NAN_DE_REASON_TIMEOUT: 286 return "timeout"; 287 case NAN_DE_REASON_USER_REQUEST: 288 return "user-request"; 289 case NAN_DE_REASON_FAILURE: 290 return "failure"; 291 } 292 293 return "unknown"; 294 } 295 296 297 static void wpas_nan_de_publish_terminated(void *ctx, int publish_id, 298 enum nan_de_reason reason) 299 { 300 struct wpa_supplicant *wpa_s = ctx; 301 302 wpa_msg(wpa_s, MSG_INFO, NAN_PUBLISH_TERMINATED 303 "publish_id=%d reason=%s", 304 publish_id, nan_reason_txt(reason)); 305 } 306 307 308 static void wpas_nan_de_subscribe_terminated(void *ctx, int subscribe_id, 309 enum nan_de_reason reason) 310 { 311 struct wpa_supplicant *wpa_s = ctx; 312 313 wpa_msg(wpa_s, MSG_INFO, NAN_SUBSCRIBE_TERMINATED 314 "subscribe_id=%d reason=%s", 315 subscribe_id, nan_reason_txt(reason)); 316 } 317 318 319 static void wpas_nan_de_receive(void *ctx, int id, int peer_instance_id, 320 const u8 *ssi, size_t ssi_len, 321 const u8 *peer_addr) 322 { 323 struct wpa_supplicant *wpa_s = ctx; 324 char *ssi_hex; 325 326 ssi_hex = os_zalloc(2 * ssi_len + 1); 327 if (!ssi_hex) 328 return; 329 if (ssi) 330 wpa_snprintf_hex(ssi_hex, 2 * ssi_len + 1, ssi, ssi_len); 331 wpa_msg(wpa_s, MSG_INFO, NAN_RECEIVE 332 "id=%d peer_instance_id=%d address=" MACSTR " ssi=%s", 333 id, peer_instance_id, MAC2STR(peer_addr), ssi_hex); 334 os_free(ssi_hex); 335 } 336 337 338 int wpas_nan_usd_init(struct wpa_supplicant *wpa_s) 339 { 340 struct nan_callbacks cb; 341 342 os_memset(&cb, 0, sizeof(cb)); 343 cb.ctx = wpa_s; 344 cb.tx = wpas_nan_de_tx; 345 cb.listen = wpas_nan_de_listen; 346 cb.discovery_result = wpas_nan_de_discovery_result; 347 cb.replied = wpas_nan_de_replied; 348 cb.publish_terminated = wpas_nan_de_publish_terminated; 349 cb.subscribe_terminated = wpas_nan_de_subscribe_terminated; 350 cb.receive = wpas_nan_de_receive; 351 352 wpa_s->nan_de = nan_de_init(wpa_s->own_addr, false, &cb); 353 if (!wpa_s->nan_de) 354 return -1; 355 return 0; 356 } 357 358 359 void wpas_nan_usd_deinit(struct wpa_supplicant *wpa_s) 360 { 361 nan_de_deinit(wpa_s->nan_de); 362 wpa_s->nan_de = NULL; 363 } 364 365 366 void wpas_nan_usd_rx_sdf(struct wpa_supplicant *wpa_s, const u8 *src, 367 unsigned int freq, const u8 *buf, size_t len) 368 { 369 if (!wpa_s->nan_de) 370 return; 371 nan_de_rx_sdf(wpa_s->nan_de, src, freq, buf, len); 372 } 373 374 375 void wpas_nan_usd_flush(struct wpa_supplicant *wpa_s) 376 { 377 if (!wpa_s->nan_de) 378 return; 379 nan_de_flush(wpa_s->nan_de); 380 } 381 382 383 int wpas_nan_usd_publish(struct wpa_supplicant *wpa_s, const char *service_name, 384 enum nan_service_protocol_type srv_proto_type, 385 const struct wpabuf *ssi, 386 struct nan_publish_params *params) 387 { 388 int publish_id; 389 struct wpabuf *elems = NULL; 390 391 if (!wpa_s->nan_de) 392 return -1; 393 394 publish_id = nan_de_publish(wpa_s->nan_de, service_name, srv_proto_type, 395 ssi, elems, params); 396 wpabuf_free(elems); 397 return publish_id; 398 } 399 400 401 void wpas_nan_usd_cancel_publish(struct wpa_supplicant *wpa_s, int publish_id) 402 { 403 if (!wpa_s->nan_de) 404 return; 405 nan_de_cancel_publish(wpa_s->nan_de, publish_id); 406 } 407 408 409 int wpas_nan_usd_update_publish(struct wpa_supplicant *wpa_s, int publish_id, 410 const struct wpabuf *ssi) 411 { 412 if (!wpa_s->nan_de) 413 return -1; 414 return nan_de_update_publish(wpa_s->nan_de, publish_id, ssi); 415 } 416 417 418 int wpas_nan_usd_subscribe(struct wpa_supplicant *wpa_s, 419 const char *service_name, 420 enum nan_service_protocol_type srv_proto_type, 421 const struct wpabuf *ssi, 422 struct nan_subscribe_params *params) 423 { 424 int subscribe_id; 425 struct wpabuf *elems = NULL; 426 427 if (!wpa_s->nan_de) 428 return -1; 429 430 subscribe_id = nan_de_subscribe(wpa_s->nan_de, service_name, 431 srv_proto_type, ssi, elems, params); 432 wpabuf_free(elems); 433 return subscribe_id; 434 } 435 436 437 void wpas_nan_usd_cancel_subscribe(struct wpa_supplicant *wpa_s, 438 int subscribe_id) 439 { 440 if (!wpa_s->nan_de) 441 return; 442 nan_de_cancel_subscribe(wpa_s->nan_de, subscribe_id); 443 } 444 445 446 int wpas_nan_usd_transmit(struct wpa_supplicant *wpa_s, int handle, 447 const struct wpabuf *ssi, const struct wpabuf *elems, 448 const u8 *peer_addr, u8 req_instance_id) 449 { 450 if (!wpa_s->nan_de) 451 return -1; 452 return nan_de_transmit(wpa_s->nan_de, handle, ssi, elems, peer_addr, 453 req_instance_id); 454 } 455 456 457 void wpas_nan_usd_remain_on_channel_cb(struct wpa_supplicant *wpa_s, 458 unsigned int freq, unsigned int duration) 459 { 460 wpas_nan_usd_listen_work_done(wpa_s); 461 462 if (wpa_s->nan_de) 463 nan_de_listen_started(wpa_s->nan_de, freq, duration); 464 } 465 466 467 void wpas_nan_usd_cancel_remain_on_channel_cb(struct wpa_supplicant *wpa_s, 468 unsigned int freq) 469 { 470 if (wpa_s->nan_de) 471 nan_de_listen_ended(wpa_s->nan_de, freq); 472 } 473 474 475 void wpas_nan_usd_tx_wait_expire(struct wpa_supplicant *wpa_s) 476 { 477 wpas_nan_usd_tx_work_done(wpa_s); 478 479 if (wpa_s->nan_de) 480 nan_de_tx_wait_ended(wpa_s->nan_de); 481 } 482 483 484 int * wpas_nan_usd_all_freqs(struct wpa_supplicant *wpa_s) 485 { 486 int i, j; 487 int *freqs = NULL; 488 489 if (!wpa_s->hw.modes) 490 return NULL; 491 492 for (i = 0; i < wpa_s->hw.num_modes; i++) { 493 struct hostapd_hw_modes *mode = &wpa_s->hw.modes[i]; 494 495 for (j = 0; j < mode->num_channels; j++) { 496 struct hostapd_channel_data *chan = &mode->channels[j]; 497 498 /* All 20 MHz channels on 2.4 and 5 GHz band */ 499 if (chan->freq < 2412 || chan->freq > 5900) 500 continue; 501 502 /* that allow frames to be transmitted */ 503 if (chan->flag & (HOSTAPD_CHAN_DISABLED | 504 HOSTAPD_CHAN_NO_IR | 505 HOSTAPD_CHAN_RADAR)) 506 continue; 507 508 int_array_add_unique(&freqs, chan->freq); 509 } 510 } 511 512 return freqs; 513 } 514