p2p_sd.c revision 1f69aa52ea2e0a73ac502565df8c666ee49cab6a
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/* 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Wi-Fi Direct - P2P service discovery 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Copyright (c) 2009, Atheros Communications 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * 5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * This program is free software; you can redistribute it and/or modify 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * it under the terms of the GNU General Public License version 2 as 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * published by the Free Software Foundation. 8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * 9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * Alternatively, this software may be distributed under the terms of BSD 10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * license. 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * See README and COPYING for more details. 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "includes.h" 16116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "common.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "common/ieee802_11_defs.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "common/gas.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "p2p_i.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "p2p.h" 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 23116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 24116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstruct p2p_sd_query * p2p_pending_sd_req(struct p2p_data *p2p, 25116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch struct p2p_device *dev) 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) struct p2p_sd_query *q; 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!(dev->info.dev_capab & P2P_DEV_CAPAB_SERVICE_DISCOVERY)) 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; /* peer does not support SD */ 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (q = p2p->sd_queries; q; q = q->next) { 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (q->for_all_peers && !(dev->flags & P2P_DEV_SD_INFO)) 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return q; 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!q->for_all_peers && 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) os_memcmp(q->peer, dev->info.p2p_device_addr, ETH_ALEN) == 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 0) 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return q; 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 40116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 44 45static int p2p_unlink_sd_query(struct p2p_data *p2p, 46 struct p2p_sd_query *query) 47{ 48 struct p2p_sd_query *q, *prev; 49 q = p2p->sd_queries; 50 prev = NULL; 51 while (q) { 52 if (q == query) { 53 if (prev) 54 prev->next = q->next; 55 else 56 p2p->sd_queries = q->next; 57 if (p2p->sd_query == query) 58 p2p->sd_query = NULL; 59 return 1; 60 } 61 prev = q; 62 q = q->next; 63 } 64 return 0; 65} 66 67 68static void p2p_free_sd_query(struct p2p_sd_query *q) 69{ 70 if (q == NULL) 71 return; 72 wpabuf_free(q->tlvs); 73 os_free(q); 74} 75 76 77void p2p_free_sd_queries(struct p2p_data *p2p) 78{ 79 struct p2p_sd_query *q, *prev; 80 q = p2p->sd_queries; 81 p2p->sd_queries = NULL; 82 while (q) { 83 prev = q; 84 q = q->next; 85 p2p_free_sd_query(prev); 86 } 87} 88 89 90static struct wpabuf * p2p_build_sd_query(u16 update_indic, 91 struct wpabuf *tlvs) 92{ 93 struct wpabuf *buf; 94 u8 *len_pos; 95 96 buf = gas_anqp_build_initial_req(0, 100 + wpabuf_len(tlvs)); 97 if (buf == NULL) 98 return NULL; 99 100 /* ANQP Query Request Frame */ 101 len_pos = gas_anqp_add_element(buf, ANQP_VENDOR_SPECIFIC); 102 wpabuf_put_be24(buf, OUI_WFA); 103 wpabuf_put_u8(buf, P2P_OUI_TYPE); 104 wpabuf_put_le16(buf, update_indic); /* Service Update Indicator */ 105 wpabuf_put_buf(buf, tlvs); 106 gas_anqp_set_element_len(buf, len_pos); 107 108 gas_anqp_set_len(buf); 109 110 return buf; 111} 112 113 114static void p2p_send_gas_comeback_req(struct p2p_data *p2p, const u8 *dst, 115 u8 dialog_token, int freq) 116{ 117 struct wpabuf *req; 118 119 req = gas_build_comeback_req(dialog_token); 120 if (req == NULL) 121 return; 122 123 p2p->pending_action_state = P2P_NO_PENDING_ACTION; 124 if (p2p_send_action(p2p, freq, dst, p2p->cfg->dev_addr, dst, 125 wpabuf_head(req), wpabuf_len(req), 200) < 0) 126 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 127 "P2P: Failed to send Action frame"); 128 129 wpabuf_free(req); 130} 131 132 133static struct wpabuf * p2p_build_sd_response(u8 dialog_token, u16 status_code, 134 u16 comeback_delay, 135 u16 update_indic, 136 const struct wpabuf *tlvs) 137{ 138 struct wpabuf *buf; 139 u8 *len_pos; 140 141 buf = gas_anqp_build_initial_resp(dialog_token, status_code, 142 comeback_delay, 143 100 + (tlvs ? wpabuf_len(tlvs) : 0)); 144 if (buf == NULL) 145 return NULL; 146 147 if (tlvs) { 148 /* ANQP Query Response Frame */ 149 len_pos = gas_anqp_add_element(buf, ANQP_VENDOR_SPECIFIC); 150 wpabuf_put_be24(buf, OUI_WFA); 151 wpabuf_put_u8(buf, P2P_OUI_TYPE); 152 /* Service Update Indicator */ 153 wpabuf_put_le16(buf, update_indic); 154 wpabuf_put_buf(buf, tlvs); 155 gas_anqp_set_element_len(buf, len_pos); 156 } 157 158 gas_anqp_set_len(buf); 159 160 return buf; 161} 162 163 164static struct wpabuf * p2p_build_gas_comeback_resp(u8 dialog_token, 165 u16 status_code, 166 u16 update_indic, 167 const u8 *data, size_t len, 168 u8 frag_id, u8 more, 169 u16 total_len) 170{ 171 struct wpabuf *buf; 172 173 buf = gas_anqp_build_comeback_resp(dialog_token, status_code, frag_id, 174 more, 0, 100 + len); 175 if (buf == NULL) 176 return NULL; 177 178 if (frag_id == 0) { 179 /* ANQP Query Response Frame */ 180 wpabuf_put_le16(buf, ANQP_VENDOR_SPECIFIC); /* Info ID */ 181 wpabuf_put_le16(buf, 3 + 1 + 2 + total_len); 182 wpabuf_put_be24(buf, OUI_WFA); 183 wpabuf_put_u8(buf, P2P_OUI_TYPE); 184 /* Service Update Indicator */ 185 wpabuf_put_le16(buf, update_indic); 186 } 187 188 wpabuf_put_data(buf, data, len); 189 gas_anqp_set_len(buf); 190 191 return buf; 192} 193 194 195int p2p_start_sd(struct p2p_data *p2p, struct p2p_device *dev) 196{ 197 struct wpabuf *req; 198 int ret = 0; 199 struct p2p_sd_query *query; 200 int freq; 201 202 freq = dev->listen_freq > 0 ? dev->listen_freq : dev->oper_freq; 203 if (freq <= 0) { 204 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 205 "P2P: No Listen/Operating frequency known for the " 206 "peer " MACSTR " to send SD Request", 207 MAC2STR(dev->info.p2p_device_addr)); 208 return -1; 209 } 210 211 query = p2p_pending_sd_req(p2p, dev); 212 if (query == NULL) 213 return -1; 214 215 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 216 "P2P: Start Service Discovery with " MACSTR, 217 MAC2STR(dev->info.p2p_device_addr)); 218 219 req = p2p_build_sd_query(p2p->srv_update_indic, query->tlvs); 220 if (req == NULL) 221 return -1; 222 223 p2p->sd_peer = dev; 224 p2p->sd_query = query; 225 p2p->pending_action_state = P2P_PENDING_SD; 226 227 if (p2p_send_action(p2p, freq, dev->info.p2p_device_addr, 228 p2p->cfg->dev_addr, dev->info.p2p_device_addr, 229 wpabuf_head(req), wpabuf_len(req), 5000) < 0) { 230 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 231 "P2P: Failed to send Action frame"); 232 ret = -1; 233 } 234 235 wpabuf_free(req); 236 237 return ret; 238} 239 240 241void p2p_rx_gas_initial_req(struct p2p_data *p2p, const u8 *sa, 242 const u8 *data, size_t len, int rx_freq) 243{ 244 const u8 *pos = data; 245 const u8 *end = data + len; 246 const u8 *next; 247 u8 dialog_token; 248 u16 slen; 249 int freq; 250 u16 update_indic; 251 252 253 if (p2p->cfg->sd_request == NULL) 254 return; 255 256 if (rx_freq > 0) 257 freq = rx_freq; 258 else 259 freq = p2p_channel_to_freq(p2p->cfg->country, 260 p2p->cfg->reg_class, 261 p2p->cfg->channel); 262 if (freq < 0) 263 return; 264 265 if (len < 1 + 2) 266 return; 267 268 dialog_token = *pos++; 269 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 270 "P2P: GAS Initial Request from " MACSTR " (dialog token %u, " 271 "freq %d)", 272 MAC2STR(sa), dialog_token, rx_freq); 273 274 if (*pos != WLAN_EID_ADV_PROTO) { 275 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 276 "P2P: Unexpected IE in GAS Initial Request: %u", *pos); 277 return; 278 } 279 pos++; 280 281 slen = *pos++; 282 next = pos + slen; 283 if (next > end || slen < 2) { 284 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 285 "P2P: Invalid IE in GAS Initial Request"); 286 return; 287 } 288 pos++; /* skip QueryRespLenLimit and PAME-BI */ 289 290 if (*pos != ACCESS_NETWORK_QUERY_PROTOCOL) { 291 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 292 "P2P: Unsupported GAS advertisement protocol id %u", 293 *pos); 294 return; 295 } 296 297 pos = next; 298 /* Query Request */ 299 if (pos + 2 > end) 300 return; 301 slen = WPA_GET_LE16(pos); 302 pos += 2; 303 if (pos + slen > end) 304 return; 305 end = pos + slen; 306 307 /* ANQP Query Request */ 308 if (pos + 4 > end) 309 return; 310 if (WPA_GET_LE16(pos) != ANQP_VENDOR_SPECIFIC) { 311 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 312 "P2P: Unsupported ANQP Info ID %u", WPA_GET_LE16(pos)); 313 return; 314 } 315 pos += 2; 316 317 slen = WPA_GET_LE16(pos); 318 pos += 2; 319 if (pos + slen > end || slen < 3 + 1) { 320 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 321 "P2P: Invalid ANQP Query Request length"); 322 return; 323 } 324 325 if (WPA_GET_BE24(pos) != OUI_WFA) { 326 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 327 "P2P: Unsupported ANQP OUI %06x", WPA_GET_BE24(pos)); 328 return; 329 } 330 pos += 3; 331 332 if (*pos != P2P_OUI_TYPE) { 333 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 334 "P2P: Unsupported ANQP vendor type %u", *pos); 335 return; 336 } 337 pos++; 338 339 if (pos + 2 > end) 340 return; 341 update_indic = WPA_GET_LE16(pos); 342 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 343 "P2P: Service Update Indicator: %u", update_indic); 344 pos += 2; 345 346 p2p->cfg->sd_request(p2p->cfg->cb_ctx, freq, sa, dialog_token, 347 update_indic, pos, end - pos); 348 /* the response will be indicated with a call to p2p_sd_response() */ 349} 350 351 352void p2p_sd_response(struct p2p_data *p2p, int freq, const u8 *dst, 353 u8 dialog_token, const struct wpabuf *resp_tlvs) 354{ 355 struct wpabuf *resp; 356 357 /* TODO: fix the length limit to match with the maximum frame length */ 358 if (wpabuf_len(resp_tlvs) > 1400) { 359 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: SD response long " 360 "enough to require fragmentation"); 361 if (p2p->sd_resp) { 362 /* 363 * TODO: Could consider storing the fragmented response 364 * separately for each peer to avoid having to drop old 365 * one if there is more than one pending SD query. 366 * Though, that would eat more memory, so there are 367 * also benefits to just using a single buffer. 368 */ 369 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Drop " 370 "previous SD response"); 371 wpabuf_free(p2p->sd_resp); 372 } 373 os_memcpy(p2p->sd_resp_addr, dst, ETH_ALEN); 374 p2p->sd_resp_dialog_token = dialog_token; 375 p2p->sd_resp = wpabuf_dup(resp_tlvs); 376 p2p->sd_resp_pos = 0; 377 p2p->sd_frag_id = 0; 378 resp = p2p_build_sd_response(dialog_token, WLAN_STATUS_SUCCESS, 379 1, p2p->srv_update_indic, NULL); 380 } else { 381 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: SD response fits " 382 "in initial response"); 383 resp = p2p_build_sd_response(dialog_token, 384 WLAN_STATUS_SUCCESS, 0, 385 p2p->srv_update_indic, resp_tlvs); 386 } 387 if (resp == NULL) 388 return; 389 390 p2p->pending_action_state = P2P_NO_PENDING_ACTION; 391 if (p2p_send_action(p2p, freq, dst, p2p->cfg->dev_addr, 392 p2p->cfg->dev_addr, 393 wpabuf_head(resp), wpabuf_len(resp), 200) < 0) 394 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 395 "P2P: Failed to send Action frame"); 396 397 wpabuf_free(resp); 398} 399 400 401void p2p_rx_gas_initial_resp(struct p2p_data *p2p, const u8 *sa, 402 const u8 *data, size_t len, int rx_freq) 403{ 404 const u8 *pos = data; 405 const u8 *end = data + len; 406 const u8 *next; 407 u8 dialog_token; 408 u16 status_code; 409 u16 comeback_delay; 410 u16 slen; 411 u16 update_indic; 412 413 if (p2p->state != P2P_SD_DURING_FIND || p2p->sd_peer == NULL || 414 os_memcmp(sa, p2p->sd_peer->info.p2p_device_addr, ETH_ALEN) != 0) { 415 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 416 "P2P: Ignore unexpected GAS Initial Response from " 417 MACSTR, MAC2STR(sa)); 418 return; 419 } 420 p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 421 p2p_clear_timeout(p2p); 422 423 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 424 "P2P: Received GAS Initial Response from " MACSTR " (len=%d)", 425 MAC2STR(sa), (int) len); 426 427 if (len < 5 + 2) { 428 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 429 "P2P: Too short GAS Initial Response frame"); 430 return; 431 } 432 433 dialog_token = *pos++; 434 /* TODO: check dialog_token match */ 435 status_code = WPA_GET_LE16(pos); 436 pos += 2; 437 comeback_delay = WPA_GET_LE16(pos); 438 pos += 2; 439 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 440 "P2P: dialog_token=%u status_code=%u comeback_delay=%u", 441 dialog_token, status_code, comeback_delay); 442 if (status_code) { 443 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 444 "P2P: Service Discovery failed: status code %u", 445 status_code); 446 return; 447 } 448 449 if (*pos != WLAN_EID_ADV_PROTO) { 450 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 451 "P2P: Unexpected IE in GAS Initial Response: %u", 452 *pos); 453 return; 454 } 455 pos++; 456 457 slen = *pos++; 458 next = pos + slen; 459 if (next > end || slen < 2) { 460 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 461 "P2P: Invalid IE in GAS Initial Response"); 462 return; 463 } 464 pos++; /* skip QueryRespLenLimit and PAME-BI */ 465 466 if (*pos != ACCESS_NETWORK_QUERY_PROTOCOL) { 467 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 468 "P2P: Unsupported GAS advertisement protocol id %u", 469 *pos); 470 return; 471 } 472 473 pos = next; 474 /* Query Response */ 475 if (pos + 2 > end) { 476 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Too short Query " 477 "Response"); 478 return; 479 } 480 slen = WPA_GET_LE16(pos); 481 pos += 2; 482 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Query Response Length: %d", 483 slen); 484 if (pos + slen > end) { 485 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Not enough Query " 486 "Response data"); 487 return; 488 } 489 end = pos + slen; 490 491 if (comeback_delay) { 492 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Fragmented " 493 "response - request fragments"); 494 if (p2p->sd_rx_resp) { 495 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Drop " 496 "old SD reassembly buffer"); 497 wpabuf_free(p2p->sd_rx_resp); 498 p2p->sd_rx_resp = NULL; 499 } 500 p2p_send_gas_comeback_req(p2p, sa, dialog_token, rx_freq); 501 return; 502 } 503 504 /* ANQP Query Response */ 505 if (pos + 4 > end) 506 return; 507 if (WPA_GET_LE16(pos) != ANQP_VENDOR_SPECIFIC) { 508 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 509 "P2P: Unsupported ANQP Info ID %u", WPA_GET_LE16(pos)); 510 return; 511 } 512 pos += 2; 513 514 slen = WPA_GET_LE16(pos); 515 pos += 2; 516 if (pos + slen > end || slen < 3 + 1) { 517 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 518 "P2P: Invalid ANQP Query Response length"); 519 return; 520 } 521 522 if (WPA_GET_BE24(pos) != OUI_WFA) { 523 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 524 "P2P: Unsupported ANQP OUI %06x", WPA_GET_BE24(pos)); 525 return; 526 } 527 pos += 3; 528 529 if (*pos != P2P_OUI_TYPE) { 530 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 531 "P2P: Unsupported ANQP vendor type %u", *pos); 532 return; 533 } 534 pos++; 535 536 if (pos + 2 > end) 537 return; 538 update_indic = WPA_GET_LE16(pos); 539 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 540 "P2P: Service Update Indicator: %u", update_indic); 541 pos += 2; 542 543 p2p->sd_peer->flags |= P2P_DEV_SD_INFO; 544 p2p->sd_peer->flags &= ~P2P_DEV_SD_SCHEDULE; 545 p2p->sd_peer = NULL; 546 547 if (p2p->sd_query) { 548 if (!p2p->sd_query->for_all_peers) { 549 struct p2p_sd_query *q; 550 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 551 "P2P: Remove completed SD query %p", 552 p2p->sd_query); 553 q = p2p->sd_query; 554 p2p_unlink_sd_query(p2p, p2p->sd_query); 555 p2p_free_sd_query(q); 556 } 557 p2p->sd_query = NULL; 558 } 559 560 if (p2p->cfg->sd_response) 561 p2p->cfg->sd_response(p2p->cfg->cb_ctx, sa, update_indic, 562 pos, end - pos); 563 p2p_continue_find(p2p); 564} 565 566 567void p2p_rx_gas_comeback_req(struct p2p_data *p2p, const u8 *sa, 568 const u8 *data, size_t len, int rx_freq) 569{ 570 struct wpabuf *resp; 571 u8 dialog_token; 572 size_t frag_len; 573 int more = 0; 574 575 wpa_hexdump(MSG_DEBUG, "P2P: RX GAS Comeback Request", data, len); 576 if (len < 1) 577 return; 578 dialog_token = *data; 579 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Dialog Token: %u", 580 dialog_token); 581 if (dialog_token != p2p->sd_resp_dialog_token) { 582 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: No pending SD " 583 "response fragment for dialog token %u", dialog_token); 584 return; 585 } 586 587 if (p2p->sd_resp == NULL) { 588 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: No pending SD " 589 "response fragment available"); 590 return; 591 } 592 if (os_memcmp(sa, p2p->sd_resp_addr, ETH_ALEN) != 0) { 593 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: No pending SD " 594 "response fragment for " MACSTR, MAC2STR(sa)); 595 return; 596 } 597 598 frag_len = wpabuf_len(p2p->sd_resp) - p2p->sd_resp_pos; 599 if (frag_len > 1400) { 600 frag_len = 1400; 601 more = 1; 602 } 603 resp = p2p_build_gas_comeback_resp(dialog_token, WLAN_STATUS_SUCCESS, 604 p2p->srv_update_indic, 605 wpabuf_head_u8(p2p->sd_resp) + 606 p2p->sd_resp_pos, frag_len, 607 p2p->sd_frag_id, more, 608 wpabuf_len(p2p->sd_resp)); 609 if (resp == NULL) 610 return; 611 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Send GAS Comeback " 612 "Response (frag_id %d more=%d frag_len=%d)", 613 p2p->sd_frag_id, more, (int) frag_len); 614 p2p->sd_frag_id++; 615 p2p->sd_resp_pos += frag_len; 616 617 if (more) { 618 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: %d more bytes " 619 "remain to be sent", 620 (int) (wpabuf_len(p2p->sd_resp) - p2p->sd_resp_pos)); 621 } else { 622 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: All fragments of " 623 "SD response sent"); 624 wpabuf_free(p2p->sd_resp); 625 p2p->sd_resp = NULL; 626 } 627 628 p2p->pending_action_state = P2P_NO_PENDING_ACTION; 629 if (p2p_send_action(p2p, rx_freq, sa, p2p->cfg->dev_addr, 630 p2p->cfg->dev_addr, 631 wpabuf_head(resp), wpabuf_len(resp), 200) < 0) 632 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 633 "P2P: Failed to send Action frame"); 634 635 wpabuf_free(resp); 636} 637 638 639void p2p_rx_gas_comeback_resp(struct p2p_data *p2p, const u8 *sa, 640 const u8 *data, size_t len, int rx_freq) 641{ 642 const u8 *pos = data; 643 const u8 *end = data + len; 644 const u8 *next; 645 u8 dialog_token; 646 u16 status_code; 647 u8 frag_id; 648 u8 more_frags; 649 u16 comeback_delay; 650 u16 slen; 651 652 wpa_hexdump(MSG_DEBUG, "P2P: RX GAS Comeback Response", data, len); 653 654 if (p2p->state != P2P_SD_DURING_FIND || p2p->sd_peer == NULL || 655 os_memcmp(sa, p2p->sd_peer->info.p2p_device_addr, ETH_ALEN) != 0) { 656 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 657 "P2P: Ignore unexpected GAS Comeback Response from " 658 MACSTR, MAC2STR(sa)); 659 return; 660 } 661 p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 662 p2p_clear_timeout(p2p); 663 664 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 665 "P2P: Received GAS Comeback Response from " MACSTR " (len=%d)", 666 MAC2STR(sa), (int) len); 667 668 if (len < 6 + 2) { 669 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 670 "P2P: Too short GAS Comeback Response frame"); 671 return; 672 } 673 674 dialog_token = *pos++; 675 /* TODO: check dialog_token match */ 676 status_code = WPA_GET_LE16(pos); 677 pos += 2; 678 frag_id = *pos & 0x7f; 679 more_frags = (*pos & 0x80) >> 7; 680 pos++; 681 comeback_delay = WPA_GET_LE16(pos); 682 pos += 2; 683 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 684 "P2P: dialog_token=%u status_code=%u frag_id=%d more_frags=%d " 685 "comeback_delay=%u", 686 dialog_token, status_code, frag_id, more_frags, 687 comeback_delay); 688 /* TODO: check frag_id match */ 689 if (status_code) { 690 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 691 "P2P: Service Discovery failed: status code %u", 692 status_code); 693 return; 694 } 695 696 if (*pos != WLAN_EID_ADV_PROTO) { 697 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 698 "P2P: Unexpected IE in GAS Comeback Response: %u", 699 *pos); 700 return; 701 } 702 pos++; 703 704 slen = *pos++; 705 next = pos + slen; 706 if (next > end || slen < 2) { 707 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 708 "P2P: Invalid IE in GAS Comeback Response"); 709 return; 710 } 711 pos++; /* skip QueryRespLenLimit and PAME-BI */ 712 713 if (*pos != ACCESS_NETWORK_QUERY_PROTOCOL) { 714 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 715 "P2P: Unsupported GAS advertisement protocol id %u", 716 *pos); 717 return; 718 } 719 720 pos = next; 721 /* Query Response */ 722 if (pos + 2 > end) { 723 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Too short Query " 724 "Response"); 725 return; 726 } 727 slen = WPA_GET_LE16(pos); 728 pos += 2; 729 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Query Response Length: %d", 730 slen); 731 if (pos + slen > end) { 732 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Not enough Query " 733 "Response data"); 734 return; 735 } 736 if (slen == 0) { 737 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: No Query Response " 738 "data"); 739 return; 740 } 741 end = pos + slen; 742 743 if (p2p->sd_rx_resp) { 744 /* 745 * ANQP header is only included in the first fragment; rest of 746 * the fragments start with continue TLVs. 747 */ 748 goto skip_nqp_header; 749 } 750 751 /* ANQP Query Response */ 752 if (pos + 4 > end) 753 return; 754 if (WPA_GET_LE16(pos) != ANQP_VENDOR_SPECIFIC) { 755 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 756 "P2P: Unsupported ANQP Info ID %u", WPA_GET_LE16(pos)); 757 return; 758 } 759 pos += 2; 760 761 slen = WPA_GET_LE16(pos); 762 pos += 2; 763 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: ANQP Query Response " 764 "length: %u", slen); 765 if (slen < 3 + 1) { 766 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 767 "P2P: Invalid ANQP Query Response length"); 768 return; 769 } 770 if (pos + 4 > end) 771 return; 772 773 if (WPA_GET_BE24(pos) != OUI_WFA) { 774 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 775 "P2P: Unsupported ANQP OUI %06x", WPA_GET_BE24(pos)); 776 return; 777 } 778 pos += 3; 779 780 if (*pos != P2P_OUI_TYPE) { 781 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 782 "P2P: Unsupported ANQP vendor type %u", *pos); 783 return; 784 } 785 pos++; 786 787 if (pos + 2 > end) 788 return; 789 p2p->sd_rx_update_indic = WPA_GET_LE16(pos); 790 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 791 "P2P: Service Update Indicator: %u", p2p->sd_rx_update_indic); 792 pos += 2; 793 794skip_nqp_header: 795 if (wpabuf_resize(&p2p->sd_rx_resp, end - pos) < 0) 796 return; 797 wpabuf_put_data(p2p->sd_rx_resp, pos, end - pos); 798 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Current SD reassembly " 799 "buffer length: %u", 800 (unsigned int) wpabuf_len(p2p->sd_rx_resp)); 801 802 if (more_frags) { 803 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: More fragments " 804 "remains"); 805 /* TODO: what would be a good size limit? */ 806 if (wpabuf_len(p2p->sd_rx_resp) > 64000) { 807 wpabuf_free(p2p->sd_rx_resp); 808 p2p->sd_rx_resp = NULL; 809 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Too long " 810 "SD response - drop it"); 811 return; 812 } 813 p2p_send_gas_comeback_req(p2p, sa, dialog_token, rx_freq); 814 return; 815 } 816 817 p2p->sd_peer->flags |= P2P_DEV_SD_INFO; 818 p2p->sd_peer->flags &= ~P2P_DEV_SD_SCHEDULE; 819 p2p->sd_peer = NULL; 820 821 if (p2p->sd_query) { 822 if (!p2p->sd_query->for_all_peers) { 823 struct p2p_sd_query *q; 824 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 825 "P2P: Remove completed SD query %p", 826 p2p->sd_query); 827 q = p2p->sd_query; 828 p2p_unlink_sd_query(p2p, p2p->sd_query); 829 p2p_free_sd_query(q); 830 } 831 p2p->sd_query = NULL; 832 } 833 834 if (p2p->cfg->sd_response) 835 p2p->cfg->sd_response(p2p->cfg->cb_ctx, sa, 836 p2p->sd_rx_update_indic, 837 wpabuf_head(p2p->sd_rx_resp), 838 wpabuf_len(p2p->sd_rx_resp)); 839 wpabuf_free(p2p->sd_rx_resp); 840 p2p->sd_rx_resp = NULL; 841 842 p2p_continue_find(p2p); 843} 844 845 846void * p2p_sd_request(struct p2p_data *p2p, const u8 *dst, 847 const struct wpabuf *tlvs) 848{ 849 struct p2p_sd_query *q; 850 851 q = os_zalloc(sizeof(*q)); 852 if (q == NULL) 853 return NULL; 854 855 if (dst) 856 os_memcpy(q->peer, dst, ETH_ALEN); 857 else 858 q->for_all_peers = 1; 859 860 q->tlvs = wpabuf_dup(tlvs); 861 if (q->tlvs == NULL) { 862 p2p_free_sd_query(q); 863 return NULL; 864 } 865 866 q->next = p2p->sd_queries; 867 p2p->sd_queries = q; 868 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Added SD Query %p", q); 869 870 return q; 871} 872 873 874void p2p_sd_service_update(struct p2p_data *p2p) 875{ 876 p2p->srv_update_indic++; 877} 878 879 880int p2p_sd_cancel_request(struct p2p_data *p2p, void *req) 881{ 882 if (p2p_unlink_sd_query(p2p, req)) { 883 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 884 "P2P: Cancel pending SD query %p", req); 885 p2p_free_sd_query(req); 886 return 0; 887 } 888 return -1; 889} 890