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