1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "sync.h" 18 19 #include "wifi_hal.h" 20 #include "nan_i.h" 21 #include "common.h" 22 #include "cpp_bindings.h" 23 #include <utils/Log.h> 24 #include "nancommand.h" 25 26 #ifdef __GNUC__ 27 #define PRINTF_FORMAT(a,b) __attribute__ ((format (printf, (a), (b)))) 28 #define STRUCT_PACKED __attribute__ ((packed)) 29 #else 30 #define PRINTF_FORMAT(a,b) 31 #define STRUCT_PACKED 32 #endif 33 34 #include "qca-vendor.h" 35 36 //Singleton Static Instance 37 NanCommand* NanCommand::mNanCommandInstance = NULL; 38 39 //Implementation of the functions exposed in nan.h 40 wifi_error nan_register_handler(wifi_interface_handle iface, 41 NanCallbackHandler handlers) 42 { 43 // Obtain the singleton instance 44 int ret = 0; 45 NanCommand *nanCommand = NULL; 46 interface_info *ifaceInfo = getIfaceInfo(iface); 47 wifi_handle wifiHandle = getWifiHandle(iface); 48 49 nanCommand = NanCommand::instance(wifiHandle); 50 if (nanCommand == NULL) { 51 ALOGE("%s: Error NanCommand NULL", __func__); 52 return WIFI_ERROR_UNKNOWN; 53 } 54 55 ret = nanCommand->setCallbackHandler(handlers); 56 return (wifi_error)ret; 57 58 cleanup: 59 return (wifi_error)ret; 60 } 61 62 wifi_error nan_get_version(wifi_handle handle, 63 NanVersion* version) 64 { 65 *version = (NAN_MAJOR_VERSION <<16 | NAN_MINOR_VERSION << 8 | NAN_MICRO_VERSION); 66 return WIFI_SUCCESS; 67 } 68 69 /* Function to send enable request to the wifi driver.*/ 70 wifi_error nan_enable_request(transaction_id id, 71 wifi_interface_handle iface, 72 NanEnableRequest* msg) 73 { 74 int ret = 0; 75 NanCommand *nanCommand = NULL; 76 interface_info *ifaceInfo = getIfaceInfo(iface); 77 wifi_handle wifiHandle = getWifiHandle(iface); 78 79 nanCommand = new NanCommand(wifiHandle, 80 0, 81 OUI_QCA, 82 QCA_NL80211_VENDOR_SUBCMD_NAN); 83 if (nanCommand == NULL) { 84 ALOGE("%s: Error NanCommand NULL", __func__); 85 return WIFI_ERROR_UNKNOWN; 86 } 87 88 ret = nanCommand->create(); 89 if (ret < 0) 90 goto cleanup; 91 92 /* Set the interface Id of the message. */ 93 ret = nanCommand->set_iface_id(ifaceInfo->name); 94 if (ret < 0) 95 goto cleanup; 96 97 ret = nanCommand->putNanEnable(id, msg); 98 if (ret != 0) { 99 ALOGE("%s: putNanEnable Error:%d",__func__, ret); 100 goto cleanup; 101 } 102 ret = nanCommand->requestEvent(); 103 if (ret != 0) { 104 ALOGE("%s: requestEvent Error:%d",__func__, ret); 105 } 106 cleanup: 107 delete nanCommand; 108 return (wifi_error)ret; 109 } 110 111 /* Function to send disable request to the wifi driver.*/ 112 wifi_error nan_disable_request(transaction_id id, 113 wifi_interface_handle iface) 114 { 115 int ret = 0; 116 NanCommand *nanCommand = NULL; 117 interface_info *ifaceInfo = getIfaceInfo(iface); 118 wifi_handle wifiHandle = getWifiHandle(iface); 119 120 nanCommand = new NanCommand(wifiHandle, 121 0, 122 OUI_QCA, 123 QCA_NL80211_VENDOR_SUBCMD_NAN); 124 if (nanCommand == NULL) { 125 ALOGE("%s: Error NanCommand NULL", __func__); 126 return WIFI_ERROR_UNKNOWN; 127 } 128 129 ret = nanCommand->create(); 130 if (ret < 0) 131 goto cleanup; 132 133 /* Set the interface Id of the message. */ 134 ret = nanCommand->set_iface_id(ifaceInfo->name); 135 if (ret < 0) 136 goto cleanup; 137 138 ret = nanCommand->putNanDisable(id); 139 if (ret != 0) { 140 ALOGE("%s: putNanDisable Error:%d",__func__, ret); 141 goto cleanup; 142 } 143 ret = nanCommand->requestEvent(); 144 if (ret != 0) { 145 ALOGE("%s: requestEvent Error:%d",__func__, ret); 146 } 147 cleanup: 148 delete nanCommand; 149 return (wifi_error)ret; 150 } 151 152 /* Function to send publish request to the wifi driver.*/ 153 wifi_error nan_publish_request(transaction_id id, 154 wifi_interface_handle iface, 155 NanPublishRequest* msg) 156 { 157 int ret = 0; 158 NanCommand *nanCommand = NULL; 159 interface_info *ifaceInfo = getIfaceInfo(iface); 160 wifi_handle wifiHandle = getWifiHandle(iface); 161 162 nanCommand = new NanCommand(wifiHandle, 163 0, 164 OUI_QCA, 165 QCA_NL80211_VENDOR_SUBCMD_NAN); 166 if (nanCommand == NULL) { 167 ALOGE("%s: Error NanCommand NULL", __func__); 168 return WIFI_ERROR_UNKNOWN; 169 } 170 171 ret = nanCommand->create(); 172 if (ret < 0) 173 goto cleanup; 174 175 /* Set the interface Id of the message. */ 176 ret = nanCommand->set_iface_id(ifaceInfo->name); 177 if (ret < 0) 178 goto cleanup; 179 180 ret = nanCommand->putNanPublish(id, msg); 181 if (ret != 0) { 182 ALOGE("%s: putNanPublish Error:%d",__func__, ret); 183 goto cleanup; 184 } 185 ret = nanCommand->requestEvent(); 186 if (ret != 0) { 187 ALOGE("%s: requestEvent Error:%d",__func__, ret); 188 } 189 cleanup: 190 delete nanCommand; 191 return (wifi_error)ret; 192 } 193 194 /* Function to send publish cancel to the wifi driver.*/ 195 wifi_error nan_publish_cancel_request(transaction_id id, 196 wifi_interface_handle iface, 197 NanPublishCancelRequest* msg) 198 { 199 int ret = 0; 200 NanCommand *nanCommand = NULL; 201 interface_info *ifaceInfo = getIfaceInfo(iface); 202 wifi_handle wifiHandle = getWifiHandle(iface); 203 204 nanCommand = new NanCommand(wifiHandle, 205 0, 206 OUI_QCA, 207 QCA_NL80211_VENDOR_SUBCMD_NAN); 208 if (nanCommand == NULL) { 209 ALOGE("%s: Error NanCommand NULL", __func__); 210 return WIFI_ERROR_UNKNOWN; 211 } 212 213 ret = nanCommand->create(); 214 if (ret < 0) 215 goto cleanup; 216 217 /* Set the interface Id of the message. */ 218 ret = nanCommand->set_iface_id(ifaceInfo->name); 219 if (ret < 0) 220 goto cleanup; 221 222 ret = nanCommand->putNanPublishCancel(id, msg); 223 if (ret != 0) { 224 ALOGE("%s: putNanPublishCancel Error:%d",__func__, ret); 225 goto cleanup; 226 } 227 ret = nanCommand->requestEvent(); 228 if (ret != 0) { 229 ALOGE("%s: requestEvent Error:%d",__func__, ret); 230 } 231 cleanup: 232 delete nanCommand; 233 return (wifi_error)ret; 234 } 235 236 /* Function to send Subscribe request to the wifi driver.*/ 237 wifi_error nan_subscribe_request(transaction_id id, 238 wifi_interface_handle iface, 239 NanSubscribeRequest* msg) 240 { 241 int ret = 0; 242 NanCommand *nanCommand = NULL; 243 interface_info *ifaceInfo = getIfaceInfo(iface); 244 wifi_handle wifiHandle = getWifiHandle(iface); 245 246 nanCommand = new NanCommand(wifiHandle, 247 0, 248 OUI_QCA, 249 QCA_NL80211_VENDOR_SUBCMD_NAN); 250 if (nanCommand == NULL) { 251 ALOGE("%s: Error NanCommand NULL", __func__); 252 return WIFI_ERROR_UNKNOWN; 253 } 254 255 ret = nanCommand->create(); 256 if (ret < 0) 257 goto cleanup; 258 259 /* Set the interface Id of the message. */ 260 ret = nanCommand->set_iface_id(ifaceInfo->name); 261 if (ret < 0) 262 goto cleanup; 263 264 ret = nanCommand->putNanSubscribe(id, msg); 265 if (ret != 0) { 266 ALOGE("%s: putNanSubscribe Error:%d",__func__, ret); 267 goto cleanup; 268 } 269 ret = nanCommand->requestEvent(); 270 if (ret != 0) { 271 ALOGE("%s: requestEvent Error:%d",__func__, ret); 272 } 273 cleanup: 274 delete nanCommand; 275 return (wifi_error)ret; 276 } 277 278 /* Function to cancel subscribe to the wifi driver.*/ 279 wifi_error nan_subscribe_cancel_request(transaction_id id, 280 wifi_interface_handle iface, 281 NanSubscribeCancelRequest* msg) 282 { 283 int ret = 0; 284 NanCommand *nanCommand = NULL; 285 interface_info *ifaceInfo = getIfaceInfo(iface); 286 wifi_handle wifiHandle = getWifiHandle(iface); 287 288 nanCommand = new NanCommand(wifiHandle, 289 0, 290 OUI_QCA, 291 QCA_NL80211_VENDOR_SUBCMD_NAN); 292 if (nanCommand == NULL) { 293 ALOGE("%s: Error NanCommand NULL", __func__); 294 return WIFI_ERROR_UNKNOWN; 295 } 296 297 ret = nanCommand->create(); 298 if (ret < 0) 299 goto cleanup; 300 301 /* Set the interface Id of the message. */ 302 ret = nanCommand->set_iface_id(ifaceInfo->name); 303 if (ret < 0) 304 goto cleanup; 305 306 ret = nanCommand->putNanSubscribeCancel(id, msg); 307 if (ret != 0) { 308 ALOGE("%s: putNanSubscribeCancel Error:%d",__func__, ret); 309 goto cleanup; 310 } 311 ret = nanCommand->requestEvent(); 312 if (ret != 0) { 313 ALOGE("%s: requestEvent Error:%d",__func__, ret); 314 } 315 cleanup: 316 delete nanCommand; 317 return (wifi_error)ret; 318 } 319 320 /* Function to send NAN follow up request to the wifi driver.*/ 321 wifi_error nan_transmit_followup_request(transaction_id id, 322 wifi_interface_handle iface, 323 NanTransmitFollowupRequest* msg) 324 { 325 int ret = 0; 326 NanCommand *nanCommand = NULL; 327 interface_info *ifaceInfo = getIfaceInfo(iface); 328 wifi_handle wifiHandle = getWifiHandle(iface); 329 330 nanCommand = new NanCommand(wifiHandle, 331 0, 332 OUI_QCA, 333 QCA_NL80211_VENDOR_SUBCMD_NAN); 334 if (nanCommand == NULL) { 335 ALOGE("%s: Error NanCommand NULL", __func__); 336 return WIFI_ERROR_UNKNOWN; 337 } 338 339 ret = nanCommand->create(); 340 if (ret < 0) 341 goto cleanup; 342 343 /* Set the interface Id of the message. */ 344 ret = nanCommand->set_iface_id(ifaceInfo->name); 345 if (ret < 0) 346 goto cleanup; 347 348 ret = nanCommand->putNanTransmitFollowup(id, msg); 349 if (ret != 0) { 350 ALOGE("%s: putNanTransmitFollowup Error:%d",__func__, ret); 351 goto cleanup; 352 } 353 ret = nanCommand->requestEvent(); 354 if (ret != 0) { 355 ALOGE("%s: requestEvent Error:%d",__func__, ret); 356 } 357 cleanup: 358 delete nanCommand; 359 return (wifi_error)ret; 360 } 361 362 /* Function to send NAN statistics request to the wifi driver.*/ 363 wifi_error nan_stats_request(transaction_id id, 364 wifi_interface_handle iface, 365 NanStatsRequest* msg) 366 { 367 int ret = 0; 368 NanCommand *nanCommand = NULL; 369 interface_info *ifaceInfo = getIfaceInfo(iface); 370 wifi_handle wifiHandle = getWifiHandle(iface); 371 372 nanCommand = new NanCommand(wifiHandle, 373 0, 374 OUI_QCA, 375 QCA_NL80211_VENDOR_SUBCMD_NAN); 376 if (nanCommand == NULL) { 377 ALOGE("%s: Error NanCommand NULL", __func__); 378 return WIFI_ERROR_UNKNOWN; 379 } 380 381 ret = nanCommand->create(); 382 if (ret < 0) 383 goto cleanup; 384 385 /* Set the interface Id of the message. */ 386 ret = nanCommand->set_iface_id(ifaceInfo->name); 387 if (ret < 0) 388 goto cleanup; 389 390 ret = nanCommand->putNanStats(id, msg); 391 if (ret != 0) { 392 ALOGE("%s: putNanStats Error:%d",__func__, ret); 393 goto cleanup; 394 } 395 ret = nanCommand->requestEvent(); 396 if (ret != 0) { 397 ALOGE("%s: requestEvent Error:%d",__func__, ret); 398 } 399 cleanup: 400 delete nanCommand; 401 return (wifi_error)ret; 402 } 403 404 /* Function to send NAN configuration request to the wifi driver.*/ 405 wifi_error nan_config_request(transaction_id id, 406 wifi_interface_handle iface, 407 NanConfigRequest* msg) 408 { 409 int ret = 0; 410 NanCommand *nanCommand = NULL; 411 interface_info *ifaceInfo = getIfaceInfo(iface); 412 wifi_handle wifiHandle = getWifiHandle(iface); 413 414 nanCommand = new NanCommand(wifiHandle, 415 0, 416 OUI_QCA, 417 QCA_NL80211_VENDOR_SUBCMD_NAN); 418 if (nanCommand == NULL) { 419 ALOGE("%s: Error NanCommand NULL", __func__); 420 return WIFI_ERROR_UNKNOWN; 421 } 422 423 ret = nanCommand->create(); 424 if (ret < 0) 425 goto cleanup; 426 427 /* Set the interface Id of the message. */ 428 ret = nanCommand->set_iface_id(ifaceInfo->name); 429 if (ret < 0) 430 goto cleanup; 431 432 ret = nanCommand->putNanConfig(id, msg); 433 if (ret != 0) { 434 ALOGE("%s: putNanConfig Error:%d",__func__, ret); 435 goto cleanup; 436 } 437 ret = nanCommand->requestEvent(); 438 if (ret != 0) { 439 ALOGE("%s: requestEvent Error:%d",__func__, ret); 440 } 441 cleanup: 442 delete nanCommand; 443 return (wifi_error)ret; 444 } 445 446 /* Function to send NAN request to the wifi driver.*/ 447 wifi_error nan_tca_request(transaction_id id, 448 wifi_interface_handle iface, 449 NanTCARequest* msg) 450 { 451 int ret = 0; 452 NanCommand *nanCommand = NULL; 453 interface_info *ifaceInfo = getIfaceInfo(iface); 454 wifi_handle wifiHandle = getWifiHandle(iface); 455 456 nanCommand = new NanCommand(wifiHandle, 457 0, 458 OUI_QCA, 459 QCA_NL80211_VENDOR_SUBCMD_NAN); 460 if (nanCommand == NULL) { 461 ALOGE("%s: Error NanCommand NULL", __func__); 462 return WIFI_ERROR_UNKNOWN; 463 } 464 465 ret = nanCommand->create(); 466 if (ret < 0) 467 goto cleanup; 468 469 /* Set the interface Id of the message. */ 470 ret = nanCommand->set_iface_id(ifaceInfo->name); 471 if (ret < 0) 472 goto cleanup; 473 474 ret = nanCommand->putNanTCA(id, msg); 475 if (ret != 0) { 476 ALOGE("%s: putNanTCA Error:%d",__func__, ret); 477 goto cleanup; 478 } 479 ret = nanCommand->requestEvent(); 480 if (ret != 0) { 481 ALOGE("%s: requestEvent Error:%d",__func__, ret); 482 } 483 cleanup: 484 delete nanCommand; 485 return (wifi_error)ret; 486 } 487 488 /* Function to send NAN Beacon sdf payload to the wifi driver. 489 This instructs the Discovery Engine to begin publishing the 490 received payload in any Beacon or Service Discovery Frame 491 transmitted*/ 492 wifi_error nan_beacon_sdf_payload_request(transaction_id id, 493 wifi_interface_handle iface, 494 NanBeaconSdfPayloadRequest* msg) 495 { 496 int ret = WIFI_ERROR_NOT_SUPPORTED; 497 NanCommand *nanCommand = NULL; 498 interface_info *ifaceInfo = getIfaceInfo(iface); 499 wifi_handle wifiHandle = getWifiHandle(iface); 500 501 nanCommand = new NanCommand(wifiHandle, 502 0, 503 OUI_QCA, 504 QCA_NL80211_VENDOR_SUBCMD_NAN); 505 if (nanCommand == NULL) { 506 ALOGE("%s: Error NanCommand NULL", __func__); 507 return WIFI_ERROR_UNKNOWN; 508 } 509 510 ret = nanCommand->create(); 511 if (ret < 0) 512 goto cleanup; 513 514 /* Set the interface Id of the message. */ 515 ret = nanCommand->set_iface_id(ifaceInfo->name); 516 if (ret < 0) 517 goto cleanup; 518 519 ret = nanCommand->putNanBeaconSdfPayload(id, msg); 520 if (ret != 0) { 521 ALOGE("%s: putNanBeaconSdfPayload Error:%d",__func__, ret); 522 goto cleanup; 523 } 524 ret = nanCommand->requestEvent(); 525 if (ret != 0) { 526 ALOGE("%s: requestEvent Error:%d",__func__, ret); 527 } 528 529 cleanup: 530 delete nanCommand; 531 return (wifi_error)ret; 532 } 533 534 wifi_error nan_get_sta_parameter(transaction_id id, 535 wifi_interface_handle iface, 536 NanStaParameter* msg) 537 { 538 int ret = WIFI_ERROR_NOT_SUPPORTED; 539 NanCommand *nanCommand = NULL; 540 interface_info *ifaceInfo = getIfaceInfo(iface); 541 wifi_handle wifiHandle = getWifiHandle(iface); 542 543 nanCommand = NanCommand::instance(wifiHandle); 544 if (nanCommand == NULL) { 545 ALOGE("%s: Error NanCommand NULL", __func__); 546 return WIFI_ERROR_UNKNOWN; 547 } 548 549 ret = nanCommand->getNanStaParameter(iface, msg); 550 if (ret != 0) { 551 ALOGE("%s: getNanStaParameter Error:%d",__func__, ret); 552 goto cleanup; 553 } 554 555 cleanup: 556 return (wifi_error)ret; 557 } 558 559 /* Function to get NAN capabilities */ 560 wifi_error nan_get_capabilities(transaction_id id, 561 wifi_interface_handle iface) 562 { 563 int ret = 0; 564 NanCommand *nanCommand = NULL; 565 interface_info *ifaceInfo = getIfaceInfo(iface); 566 wifi_handle wifiHandle = getWifiHandle(iface); 567 568 nanCommand = new NanCommand(wifiHandle, 569 0, 570 OUI_QCA, 571 QCA_NL80211_VENDOR_SUBCMD_NAN); 572 if (nanCommand == NULL) { 573 ALOGE("%s: Error NanCommand NULL", __func__); 574 return WIFI_ERROR_UNKNOWN; 575 } 576 577 ret = nanCommand->create(); 578 if (ret < 0) 579 goto cleanup; 580 581 /* Set the interface Id of the message. */ 582 ret = nanCommand->set_iface_id(ifaceInfo->name); 583 if (ret < 0) 584 goto cleanup; 585 586 ret = nanCommand->putNanCapabilities(id); 587 if (ret != 0) { 588 ALOGE("%s: putNanCapabilities Error:%d",__func__, ret); 589 goto cleanup; 590 } 591 ret = nanCommand->requestEvent(); 592 if (ret != 0) { 593 ALOGE("%s: requestEvent Error:%d",__func__, ret); 594 } 595 cleanup: 596 delete nanCommand; 597 return (wifi_error)ret; 598 } 599 600 // Implementation related to nan class common functions 601 // Constructor 602 //Making the constructor private since this class is a singleton 603 NanCommand::NanCommand(wifi_handle handle, int id, u32 vendor_id, u32 subcmd) 604 : WifiVendorCommand(handle, id, vendor_id, subcmd) 605 { 606 memset(&mHandler, 0,sizeof(mHandler)); 607 mNanVendorEvent = NULL; 608 mNanDataLen = 0; 609 mStaParam = NULL; 610 } 611 612 NanCommand* NanCommand::instance(wifi_handle handle) 613 { 614 if (handle == NULL) { 615 ALOGE("Handle is invalid"); 616 return NULL; 617 } 618 if (mNanCommandInstance == NULL) { 619 mNanCommandInstance = new NanCommand(handle, 0, 620 OUI_QCA, 621 QCA_NL80211_VENDOR_SUBCMD_NAN); 622 ALOGV("NanCommand %p created", mNanCommandInstance); 623 return mNanCommandInstance; 624 } 625 else 626 { 627 if (handle != getWifiHandle(mNanCommandInstance->mInfo)) { 628 /* upper layer must have cleaned up the handle and reinitialized, 629 so we need to update the same */ 630 ALOGI("Handle different, update the handle"); 631 mNanCommandInstance->mInfo = (hal_info *)handle; 632 } 633 } 634 ALOGV("NanCommand %p created already", mNanCommandInstance); 635 return mNanCommandInstance; 636 } 637 638 void NanCommand::cleanup() 639 { 640 //free the VendorData 641 if (mVendorData) { 642 free(mVendorData); 643 } 644 mVendorData = NULL; 645 //cleanup the mMsg 646 mMsg.destroy(); 647 } 648 649 NanCommand::~NanCommand() 650 { 651 ALOGV("NanCommand %p destroyed", this); 652 } 653 654 int NanCommand::handleResponse(WifiEvent &reply){ 655 return NL_SKIP; 656 } 657 658 int NanCommand::setCallbackHandler(NanCallbackHandler nHandler) 659 { 660 int res = 0; 661 mHandler = nHandler; 662 res = registerVendorHandler(mVendor_id, mSubcmd); 663 if (res != 0) { 664 //error case should not happen print log 665 ALOGE("%s: Unable to register Vendor Handler Vendor Id=0x%x subcmd=%u", 666 __func__, mVendor_id, mSubcmd); 667 } 668 return res; 669 } 670 671 /* This function implements creation of Vendor command */ 672 int NanCommand::create() { 673 int ret = mMsg.create(NL80211_CMD_VENDOR, 0, 0); 674 if (ret < 0) { 675 goto out; 676 } 677 678 /* Insert the oui in the msg */ 679 ret = mMsg.put_u32(NL80211_ATTR_VENDOR_ID, mVendor_id); 680 if (ret < 0) 681 goto out; 682 /* Insert the subcmd in the msg */ 683 ret = mMsg.put_u32(NL80211_ATTR_VENDOR_SUBCMD, mSubcmd); 684 if (ret < 0) 685 goto out; 686 out: 687 if (ret < 0) { 688 mMsg.destroy(); 689 } 690 return ret; 691 } 692 693 // This function will be the main handler for incoming event 694 // QCA_NL80211_VENDOR_SUBCMD_NAN 695 //Call the appropriate callback handler after parsing the vendor data. 696 int NanCommand::handleEvent(WifiEvent &event) 697 { 698 WifiVendorCommand::handleEvent(event); 699 ALOGV("%s: Subcmd=%u Vendor data len received:%d", 700 __FUNCTION__, mSubcmd, mDataLen); 701 hexdump(mVendorData, mDataLen); 702 703 if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NAN){ 704 // Parse the vendordata and get the NAN attribute 705 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_MAX + 1]; 706 nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_MAX, 707 (struct nlattr *)mVendorData, 708 mDataLen, NULL); 709 // Populating the mNanVendorEvent and mNanDataLen to point to NAN data. 710 mNanVendorEvent = (char *)nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NAN]); 711 mNanDataLen = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NAN]); 712 713 if (isNanResponse()) { 714 //handleNanResponse will parse the data and call 715 //the response callback handler with the populated 716 //NanResponseMsg 717 handleNanResponse(); 718 } 719 else { 720 //handleNanIndication will parse the data and call 721 //the corresponding Indication callback handler 722 //with the corresponding populated Indication event 723 handleNanIndication(); 724 } 725 } 726 else { 727 //error case should not happen print log 728 ALOGE("%s: Wrong NAN subcmd received %d", __func__, mSubcmd); 729 } 730 return NL_SKIP; 731 } 732 733 /*Helper function to Write and Read TLV called in indication as well as request */ 734 u16 NANTLV_WriteTlv(pNanTlv pInTlv, u8 *pOutTlv) 735 { 736 u16 writeLen = 0; 737 u16 i; 738 739 if (!pInTlv) 740 { 741 ALOGE("NULL pInTlv"); 742 return writeLen; 743 } 744 745 if (!pOutTlv) 746 { 747 ALOGE("NULL pOutTlv"); 748 return writeLen; 749 } 750 751 *pOutTlv++ = pInTlv->type & 0xFF; 752 *pOutTlv++ = (pInTlv->type & 0xFF00) >> 8; 753 writeLen += 2; 754 755 ALOGV("WRITE TLV type %u, writeLen %u", pInTlv->type, writeLen); 756 757 *pOutTlv++ = pInTlv->length & 0xFF; 758 *pOutTlv++ = (pInTlv->length & 0xFF00) >> 8; 759 writeLen += 2; 760 761 ALOGV("WRITE TLV length %u, writeLen %u", pInTlv->length, writeLen); 762 763 for (i=0; i < pInTlv->length; ++i) 764 { 765 *pOutTlv++ = pInTlv->value[i]; 766 } 767 768 writeLen += pInTlv->length; 769 ALOGV("WRITE TLV value, writeLen %u", writeLen); 770 return writeLen; 771 } 772 773 u16 NANTLV_ReadTlv(u8 *pInTlv, pNanTlv pOutTlv) 774 { 775 u16 readLen = 0; 776 777 if (!pInTlv) 778 { 779 ALOGE("NULL pInTlv"); 780 return readLen; 781 } 782 783 if (!pOutTlv) 784 { 785 ALOGE("NULL pOutTlv"); 786 return readLen; 787 } 788 789 pOutTlv->type = *pInTlv++; 790 pOutTlv->type |= *pInTlv++ << 8; 791 readLen += 2; 792 793 ALOGV("READ TLV type %u, readLen %u", pOutTlv->type, readLen); 794 795 pOutTlv->length = *pInTlv++; 796 pOutTlv->length |= *pInTlv++ << 8; 797 readLen += 2; 798 799 ALOGV("READ TLV length %u, readLen %u", pOutTlv->length, readLen); 800 801 if (pOutTlv->length) 802 { 803 pOutTlv->value = pInTlv; 804 readLen += pOutTlv->length; 805 } 806 else 807 { 808 pOutTlv->value = NULL; 809 } 810 811 ALOGV("READ TLV readLen %u", readLen); 812 return readLen; 813 } 814 815 u8* addTlv(u16 type, u16 length, const u8* value, u8* pOutTlv) 816 { 817 NanTlv nanTlv; 818 u16 len; 819 820 nanTlv.type = type; 821 nanTlv.length = length; 822 nanTlv.value = (u8*)value; 823 824 len = NANTLV_WriteTlv(&nanTlv, pOutTlv); 825 return (pOutTlv + len); 826 } 827