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 #include <utils/Log.h> 19 #include <errno.h> 20 #include "wifi_hal.h" 21 #include "nan_i.h" 22 #include "nancommand.h" 23 #include <errno.h> 24 25 //Function which calls the necessaryIndication callback 26 //based on the indication type 27 int NanCommand::handleNanIndication() 28 { 29 //Based on the message_id in the header determine the Indication type 30 //and call the necessary callback handler 31 u16 msg_id; 32 int res = 0; 33 34 msg_id = getIndicationType(); 35 36 ALOGV("handleNanIndication msg_id:%u", msg_id); 37 switch (msg_id) { 38 case NAN_INDICATION_PUBLISH_TERMINATED: 39 NanPublishTerminatedInd publishTerminatedInd; 40 memset(&publishTerminatedInd, 0, sizeof(publishTerminatedInd)); 41 res = getNanPublishTerminated(&publishTerminatedInd); 42 if (!res && mHandler.EventPublishTerminated) { 43 (*mHandler.EventPublishTerminated)(&publishTerminatedInd); 44 } 45 break; 46 47 case NAN_INDICATION_MATCH: 48 NanMatchInd matchInd; 49 memset(&matchInd, 0, sizeof(matchInd)); 50 res = getNanMatch(&matchInd); 51 if (!res && mHandler.EventMatch) { 52 (*mHandler.EventMatch)(&matchInd); 53 } 54 break; 55 56 case NAN_INDICATION_MATCH_EXPIRED: 57 NanMatchExpiredInd matchExpiredInd; 58 memset(&matchExpiredInd, 0, sizeof(matchExpiredInd)); 59 res = getNanMatchExpired(&matchExpiredInd); 60 if (!res && mHandler.EventMatchExpired) { 61 (*mHandler.EventMatchExpired)(&matchExpiredInd); 62 } 63 break; 64 65 case NAN_INDICATION_SUBSCRIBE_TERMINATED: 66 NanSubscribeTerminatedInd subscribeTerminatedInd; 67 memset(&subscribeTerminatedInd, 0, sizeof(subscribeTerminatedInd)); 68 res = getNanSubscribeTerminated(&subscribeTerminatedInd); 69 if (!res && mHandler.EventSubscribeTerminated) { 70 (*mHandler.EventSubscribeTerminated)(&subscribeTerminatedInd); 71 } 72 break; 73 74 case NAN_INDICATION_DE_EVENT: 75 NanDiscEngEventInd discEngEventInd; 76 memset(&discEngEventInd, 0, sizeof(discEngEventInd)); 77 res = getNanDiscEngEvent(&discEngEventInd); 78 if (!res && mHandler.EventDiscEngEvent) { 79 (*mHandler.EventDiscEngEvent)(&discEngEventInd); 80 } 81 break; 82 83 case NAN_INDICATION_FOLLOWUP: 84 NanFollowupInd followupInd; 85 memset(&followupInd, 0, sizeof(followupInd)); 86 res = getNanFollowup(&followupInd); 87 if (!res && mHandler.EventFollowup) { 88 (*mHandler.EventFollowup)(&followupInd); 89 } 90 break; 91 92 case NAN_INDICATION_DISABLED: 93 NanDisabledInd disabledInd; 94 memset(&disabledInd, 0, sizeof(disabledInd)); 95 res = getNanDisabled(&disabledInd); 96 if (!res && mHandler.EventDisabled) { 97 (*mHandler.EventDisabled)(&disabledInd); 98 } 99 break; 100 101 case NAN_INDICATION_TCA: 102 NanTCAInd tcaInd; 103 memset(&tcaInd, 0, sizeof(tcaInd)); 104 res = getNanTca(&tcaInd); 105 if (!res && mHandler.EventTca) { 106 (*mHandler.EventTca)(&tcaInd); 107 } 108 break; 109 110 case NAN_INDICATION_BEACON_SDF_PAYLOAD: 111 NanBeaconSdfPayloadInd beaconSdfPayloadInd; 112 memset(&beaconSdfPayloadInd, 0, sizeof(beaconSdfPayloadInd)); 113 res = getNanBeaconSdfPayload(&beaconSdfPayloadInd); 114 if (!res && mHandler.EventBeaconSdfPayload) { 115 (*mHandler.EventBeaconSdfPayload)(&beaconSdfPayloadInd); 116 } 117 break; 118 119 case NAN_INDICATION_SELF_TRANSMIT_FOLLOWUP: 120 NanTransmitFollowupInd transmitFollowupInd; 121 memset(&transmitFollowupInd, 0, sizeof(NanTransmitFollowupInd)); 122 res = getNanTransmitFollowupInd(&transmitFollowupInd); 123 if (!res && mHandler.EventTransmitFollowup) { 124 (*mHandler.EventTransmitFollowup)(&transmitFollowupInd); 125 } 126 break; 127 128 case NAN_INDICATION_RANGING_REQUEST_RECEIVED: 129 NanRangeRequestInd rangeRequestInd; 130 memset(&rangeRequestInd, 0, sizeof(NanRangeRequestInd)); 131 res = getNanRangeRequestReceivedInd(&rangeRequestInd); 132 if (!res && mHandler.EventRangeRequest) { 133 (*mHandler.EventRangeRequest)(&rangeRequestInd); 134 } 135 break; 136 137 case NAN_INDICATION_RANGING_RESULT: 138 NanRangeReportInd rangeReportInd; 139 memset(&rangeReportInd, 0, sizeof(NanRangeReportInd)); 140 res = getNanRangeReportInd(&rangeReportInd); 141 if (!res && mHandler.EventRangeReport) { 142 (*mHandler.EventRangeReport)(&rangeReportInd); 143 } 144 break; 145 146 default: 147 ALOGE("handleNanIndication error invalid msg_id:%u", msg_id); 148 res = (int)WIFI_ERROR_INVALID_REQUEST_ID; 149 break; 150 } 151 return res; 152 } 153 154 //Function which will return the Nan Indication type based on 155 //the initial few bytes of mNanVendorEvent 156 NanIndicationType NanCommand::getIndicationType() 157 { 158 if (mNanVendorEvent == NULL) { 159 ALOGE("%s: Invalid argument mNanVendorEvent:%p", 160 __func__, mNanVendorEvent); 161 return NAN_INDICATION_UNKNOWN; 162 } 163 164 NanMsgHeader *pHeader = (NanMsgHeader *)mNanVendorEvent; 165 166 switch (pHeader->msgId) { 167 case NAN_MSG_ID_PUBLISH_REPLIED_IND: 168 return NAN_INDICATION_UNKNOWN; 169 case NAN_MSG_ID_PUBLISH_TERMINATED_IND: 170 return NAN_INDICATION_PUBLISH_TERMINATED; 171 case NAN_MSG_ID_MATCH_IND: 172 return NAN_INDICATION_MATCH; 173 case NAN_MSG_ID_MATCH_EXPIRED_IND: 174 return NAN_INDICATION_MATCH_EXPIRED; 175 case NAN_MSG_ID_FOLLOWUP_IND: 176 return NAN_INDICATION_FOLLOWUP; 177 case NAN_MSG_ID_SUBSCRIBE_TERMINATED_IND: 178 return NAN_INDICATION_SUBSCRIBE_TERMINATED; 179 case NAN_MSG_ID_DE_EVENT_IND: 180 return NAN_INDICATION_DE_EVENT; 181 case NAN_MSG_ID_DISABLE_IND: 182 return NAN_INDICATION_DISABLED; 183 case NAN_MSG_ID_TCA_IND: 184 return NAN_INDICATION_TCA; 185 case NAN_MSG_ID_BEACON_SDF_IND: 186 return NAN_INDICATION_BEACON_SDF_PAYLOAD; 187 case NAN_MSG_ID_SELF_TRANSMIT_FOLLOWUP_IND: 188 return NAN_INDICATION_SELF_TRANSMIT_FOLLOWUP; 189 case NAN_MSG_ID_RANGING_REQUEST_RECEVD_IND: 190 return NAN_INDICATION_RANGING_REQUEST_RECEIVED; 191 case NAN_MSG_ID_RANGING_RESULT_IND: 192 return NAN_INDICATION_RANGING_RESULT; 193 default: 194 return NAN_INDICATION_UNKNOWN; 195 } 196 } 197 198 int NanCommand::getNanPublishTerminated(NanPublishTerminatedInd *event) 199 { 200 if (event == NULL || mNanVendorEvent == NULL) { 201 ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p", 202 __func__, event, mNanVendorEvent); 203 return WIFI_ERROR_INVALID_ARGS; 204 } 205 206 pNanPublishTerminatedIndMsg pRsp = (pNanPublishTerminatedIndMsg)mNanVendorEvent; 207 event->publish_id = pRsp->fwHeader.handle; 208 NanErrorTranslation((NanInternalStatusType)pRsp->reason, 0, 209 (void*)event); 210 return WIFI_SUCCESS; 211 } 212 213 int NanCommand::getNanMatch(NanMatchInd *event) 214 { 215 if (event == NULL || mNanVendorEvent == NULL) { 216 ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p", 217 __func__, event, mNanVendorEvent); 218 return WIFI_ERROR_INVALID_ARGS; 219 } 220 221 pNanMatchIndMsg pRsp = (pNanMatchIndMsg)mNanVendorEvent; 222 event->publish_subscribe_id = pRsp->fwHeader.handle; 223 event->requestor_instance_id = pRsp->matchIndParams.matchHandle; 224 event->match_occured_flag = pRsp->matchIndParams.matchOccuredFlag; 225 event->out_of_resource_flag = pRsp->matchIndParams.outOfResourceFlag; 226 227 u8 *pInputTlv = pRsp->ptlv; 228 NanTlv outputTlv; 229 u16 readLen = 0; 230 int remainingLen = (mNanDataLen - \ 231 (sizeof(NanMsgHeader) + sizeof(NanMatchIndParams))); 232 int ret = 0, idx = 0; 233 234 //Has SDF match filter and service specific info TLV 235 if (remainingLen <= 0) { 236 ALOGV("%s: No TLV's present",__func__); 237 return WIFI_SUCCESS; 238 } 239 ALOGV("%s: TLV remaining Len:%d",__func__, remainingLen); 240 while ((remainingLen > 0) && 241 (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv)))) { 242 ALOGV("%s: Remaining Len:%d readLen:%d type:%d length:%d", 243 __func__, remainingLen, readLen, outputTlv.type, 244 outputTlv.length); 245 switch (outputTlv.type) { 246 case NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO: 247 if (outputTlv.length > NAN_MAX_SERVICE_NAME_LEN) { 248 outputTlv.length = NAN_MAX_SERVICE_NAME_LEN; 249 } 250 event->service_specific_info_len = outputTlv.length; 251 memcpy(event->service_specific_info, outputTlv.value, 252 outputTlv.length); 253 break; 254 case NAN_TLV_TYPE_SDF_MATCH_FILTER: 255 if (outputTlv.length > NAN_MAX_MATCH_FILTER_LEN) { 256 outputTlv.length = NAN_MAX_MATCH_FILTER_LEN; 257 } 258 event->sdf_match_filter_len = outputTlv.length; 259 memcpy(event->sdf_match_filter, outputTlv.value, 260 outputTlv.length); 261 break; 262 case NAN_TLV_TYPE_MAC_ADDRESS: 263 if (outputTlv.length > sizeof(event->addr)) { 264 outputTlv.length = sizeof(event->addr); 265 } 266 memcpy(event->addr, outputTlv.value, outputTlv.length); 267 break; 268 case NAN_TLV_TYPE_RECEIVED_RSSI_VALUE: 269 if (outputTlv.length > sizeof(event->rssi_value)) { 270 outputTlv.length = sizeof(event->rssi_value); 271 } 272 memcpy(&event->rssi_value, outputTlv.value, 273 outputTlv.length); 274 break; 275 case NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_RECEIVE: 276 if (outputTlv.length != sizeof(u32)) { 277 ALOGE("NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_RECEIVE" 278 "Incorrect size:%d expecting %zu", outputTlv.length, 279 sizeof(u32)); 280 break; 281 } 282 event->is_conn_capability_valid = 1; 283 /* Populate conn_capability from received TLV */ 284 getNanReceivePostConnectivityCapabilityVal(outputTlv.value, 285 &event->conn_capability); 286 break; 287 case NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_RECEIVE: 288 /* Populate receive discovery attribute from 289 received TLV */ 290 idx = event->num_rx_discovery_attr; 291 ret = getNanReceivePostDiscoveryVal(outputTlv.value, 292 outputTlv.length, 293 &event->discovery_attr[idx]); 294 if (ret == 0) { 295 event->num_rx_discovery_attr++; 296 } else { 297 ALOGE("NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_RECEIVE" 298 "Incorrect"); 299 } 300 break; 301 case NAN_TLV_TYPE_FURTHER_AVAILABILITY_MAP: 302 /* Populate further availability bitmap from 303 received TLV */ 304 ret = getNanFurtherAvailabilityMap(outputTlv.value, 305 outputTlv.length, 306 &event->num_chans, 307 &event->famchan[0]); 308 if (ret < 0) 309 ALOGE("NAN_TLV_TYPE_FURTHER_AVAILABILITY_MAP" 310 "Incorrect"); 311 break; 312 case NAN_TLV_TYPE_CLUSTER_ATTRIBUTE: 313 if (outputTlv.length > sizeof(event->cluster_attribute)) { 314 outputTlv.length = sizeof(event->cluster_attribute); 315 } 316 memcpy(event->cluster_attribute, 317 outputTlv.value, outputTlv.length); 318 event->cluster_attribute_len = outputTlv.length; 319 break; 320 case NAN_TLV_TYPE_NAN_CSID: 321 if (outputTlv.length > sizeof(event->peer_cipher_type)) { 322 outputTlv.length = sizeof(event->peer_cipher_type); 323 } 324 memcpy(&event->peer_cipher_type, outputTlv.value, 325 outputTlv.length); 326 break; 327 case NAN_TLV_TYPE_NAN_SCID: 328 if (outputTlv.length > sizeof(event->scid)) { 329 outputTlv.length = sizeof(event->scid); 330 } 331 event->scid_len = outputTlv.length; 332 memcpy(event->scid, outputTlv.value, outputTlv.length); 333 break; 334 case NAN_TLV_TYPE_SDEA_CTRL_PARAMS: 335 if (outputTlv.length != sizeof(u32)) { 336 ALOGE("NAN_TLV_TYPE_SDEA_CTRL_PARAMS" 337 "Incorrect size:%d expecting %zu", outputTlv.length, 338 sizeof(u32)); 339 break; 340 } 341 getNanReceiveSdeaCtrlParams(outputTlv.value, 342 &event->peer_sdea_params); 343 break; 344 case NAN_TLV_TYPE_NAN20_RANGING_RESULT: 345 if (outputTlv.length > sizeof(event->range_info)) { 346 outputTlv.length = sizeof(event->range_info); 347 } 348 memcpy(&event->range_info, outputTlv.value, outputTlv.length); 349 break; 350 case NAN_TLV_TYPE_SDEA_SERVICE_SPECIFIC_INFO: 351 if (outputTlv.length > NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN) { 352 outputTlv.length = NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN; 353 } 354 event->sdea_service_specific_info_len = outputTlv.length; 355 memcpy(event->sdea_service_specific_info, outputTlv.value, 356 outputTlv.length); 357 break; 358 default: 359 ALOGV("Unknown TLV type skipped"); 360 break; 361 } 362 remainingLen -= readLen; 363 pInputTlv += readLen; 364 memset(&outputTlv, 0, sizeof(outputTlv)); 365 } 366 return WIFI_SUCCESS; 367 } 368 369 int NanCommand::getNanMatchExpired(NanMatchExpiredInd *event) 370 { 371 if (event == NULL || mNanVendorEvent == NULL) { 372 ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p", 373 __func__, event, mNanVendorEvent); 374 return WIFI_ERROR_INVALID_ARGS; 375 } 376 377 pNanMatchExpiredIndMsg pRsp = (pNanMatchExpiredIndMsg)mNanVendorEvent; 378 event->publish_subscribe_id = pRsp->fwHeader.handle; 379 event->requestor_instance_id = pRsp->matchExpiredIndParams.matchHandle; 380 return WIFI_SUCCESS; 381 } 382 383 int NanCommand::getNanSubscribeTerminated(NanSubscribeTerminatedInd *event) 384 { 385 if (event == NULL || mNanVendorEvent == NULL) { 386 ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p", 387 __func__, event, mNanVendorEvent); 388 return WIFI_ERROR_INVALID_ARGS; 389 } 390 391 pNanSubscribeTerminatedIndMsg pRsp = (pNanSubscribeTerminatedIndMsg)mNanVendorEvent; 392 event->subscribe_id = pRsp->fwHeader.handle; 393 NanErrorTranslation((NanInternalStatusType)pRsp->reason, 0, 394 (void*)event); 395 return WIFI_SUCCESS; 396 } 397 398 int NanCommand::getNanFollowup(NanFollowupInd *event) 399 { 400 if (event == NULL || mNanVendorEvent == NULL) { 401 ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p", 402 __func__, event, mNanVendorEvent); 403 return WIFI_ERROR_INVALID_ARGS; 404 } 405 406 pNanFollowupIndMsg pRsp = (pNanFollowupIndMsg)mNanVendorEvent; 407 event->publish_subscribe_id = pRsp->fwHeader.handle; 408 event->requestor_instance_id = pRsp->followupIndParams.matchHandle; 409 event->dw_or_faw = pRsp->followupIndParams.window; 410 411 u8 *pInputTlv = pRsp->ptlv; 412 NanTlv outputTlv; 413 u16 readLen = 0; 414 int remainingLen = (mNanDataLen - \ 415 (sizeof(NanMsgHeader) + sizeof(NanFollowupIndParams))); 416 417 //Has service specific info and extended service specific info TLV 418 if (remainingLen <= 0) { 419 ALOGV("%s: No TLV's present",__func__); 420 return WIFI_SUCCESS; 421 } 422 ALOGV("%s: TLV remaining Len:%d",__func__, remainingLen); 423 while ((remainingLen > 0) && 424 (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv)))) { 425 ALOGV("%s: Remaining Len:%d readLen:%d type:%d length:%d", 426 __func__, remainingLen, readLen, outputTlv.type, 427 outputTlv.length); 428 switch (outputTlv.type) { 429 case NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO: 430 case NAN_TLV_TYPE_EXT_SERVICE_SPECIFIC_INFO: 431 if (outputTlv.length > NAN_MAX_SERVICE_SPECIFIC_INFO_LEN) { 432 outputTlv.length = NAN_MAX_SERVICE_SPECIFIC_INFO_LEN; 433 } 434 event->service_specific_info_len = outputTlv.length; 435 memcpy(event->service_specific_info, outputTlv.value, 436 outputTlv.length); 437 break; 438 case NAN_TLV_TYPE_MAC_ADDRESS: 439 if (outputTlv.length > sizeof(event->addr)) { 440 outputTlv.length = sizeof(event->addr); 441 } 442 memcpy(event->addr, outputTlv.value, outputTlv.length); 443 break; 444 case NAN_TLV_TYPE_SDEA_SERVICE_SPECIFIC_INFO: 445 if (outputTlv.length > NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN) { 446 outputTlv.length = NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN; 447 } 448 event->sdea_service_specific_info_len = outputTlv.length; 449 memcpy(event->sdea_service_specific_info, outputTlv.value, 450 outputTlv.length); 451 break; 452 default: 453 ALOGV("Unknown TLV type skipped"); 454 break; 455 } 456 remainingLen -= readLen; 457 pInputTlv += readLen; 458 memset(&outputTlv, 0, sizeof(outputTlv)); 459 } 460 return WIFI_SUCCESS; 461 } 462 463 int NanCommand::getNanDiscEngEvent(NanDiscEngEventInd *event) 464 { 465 if (event == NULL || mNanVendorEvent == NULL) { 466 ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p", 467 __func__, event, mNanVendorEvent); 468 return WIFI_ERROR_INVALID_ARGS; 469 } 470 471 pNanEventIndMsg pRsp = (pNanEventIndMsg)mNanVendorEvent; 472 memset(&event->data, 0, sizeof(event->data)); 473 474 u8 *pInputTlv = pRsp->ptlv; 475 NanTlv outputTlv; 476 u16 readLen = 0; 477 int remainingLen = (mNanDataLen - \ 478 (sizeof(NanMsgHeader))); 479 480 //Has Self-STA Mac TLV 481 if (remainingLen <= 0) { 482 ALOGE("%s: No TLV's present",__func__); 483 return WIFI_SUCCESS; 484 } 485 486 ALOGV("%s: TLV remaining Len:%d",__func__, remainingLen); 487 while ((remainingLen > 0) && 488 (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv)))) { 489 ALOGV("%s: Remaining Len:%d readLen:%d type:%d length:%d", 490 __func__, remainingLen, readLen, outputTlv.type, 491 outputTlv.length); 492 switch (outputTlv.type) { 493 case NAN_TLV_TYPE_EVENT_SELF_STATION_MAC_ADDRESS: 494 if (outputTlv.length > NAN_MAC_ADDR_LEN) { 495 ALOGV("%s: Reading only first %d bytes of TLV", 496 __func__, NAN_MAC_ADDR_LEN); 497 outputTlv.length = NAN_MAC_ADDR_LEN; 498 } 499 memcpy(event->data.mac_addr.addr, outputTlv.value, 500 outputTlv.length); 501 event->event_type = NAN_EVENT_ID_DISC_MAC_ADDR; 502 break; 503 case NAN_TLV_TYPE_EVENT_STARTED_CLUSTER: 504 if (outputTlv.length > NAN_MAC_ADDR_LEN) { 505 ALOGV("%s: Reading only first %d bytes of TLV", 506 __func__, NAN_MAC_ADDR_LEN); 507 outputTlv.length = NAN_MAC_ADDR_LEN; 508 } 509 memcpy(event->data.cluster.addr, outputTlv.value, 510 outputTlv.length); 511 event->event_type = NAN_EVENT_ID_STARTED_CLUSTER; 512 break; 513 case NAN_TLV_TYPE_EVENT_JOINED_CLUSTER: 514 if (outputTlv.length > NAN_MAC_ADDR_LEN) { 515 ALOGV("%s: Reading only first %d bytes of TLV", 516 __func__, NAN_MAC_ADDR_LEN); 517 outputTlv.length = NAN_MAC_ADDR_LEN; 518 } 519 memcpy(event->data.cluster.addr, outputTlv.value, 520 outputTlv.length); 521 event->event_type = NAN_EVENT_ID_JOINED_CLUSTER; 522 break; 523 default: 524 ALOGV("Unhandled TLV type:%d", outputTlv.type); 525 break; 526 } 527 remainingLen -= readLen; 528 pInputTlv += readLen; 529 memset(&outputTlv,0, sizeof(outputTlv)); 530 } 531 return WIFI_SUCCESS; 532 } 533 534 int NanCommand::getNanDisabled(NanDisabledInd *event) 535 { 536 if (event == NULL || mNanVendorEvent == NULL) { 537 ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p", 538 __func__, event, mNanVendorEvent); 539 return WIFI_ERROR_INVALID_ARGS; 540 } 541 542 pNanDisableIndMsg pRsp = (pNanDisableIndMsg)mNanVendorEvent; 543 NanErrorTranslation((NanInternalStatusType)pRsp->reason, 0, 544 (void*)event); 545 return WIFI_SUCCESS; 546 547 } 548 549 int NanCommand::getNanTca(NanTCAInd *event) 550 { 551 if (event == NULL || mNanVendorEvent == NULL) { 552 ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p", 553 __func__, event, mNanVendorEvent); 554 return WIFI_ERROR_INVALID_ARGS; 555 } 556 557 pNanTcaIndMsg pRsp = (pNanTcaIndMsg)mNanVendorEvent; 558 memset(&event->data, 0, sizeof(event->data)); 559 560 u8 *pInputTlv = pRsp->ptlv; 561 NanTlv outputTlv; 562 u16 readLen = 0; 563 564 int remainingLen = (mNanDataLen - \ 565 (sizeof(NanMsgHeader))); 566 567 //Has NAN_TCA_ID_CLUSTER_SIZE 568 if (remainingLen <= 0) { 569 ALOGE("%s: No TLV's present",__func__); 570 return WIFI_SUCCESS; 571 } 572 573 ALOGV("%s: TLV remaining Len:%d",__func__, remainingLen); 574 while ((remainingLen > 0) && 575 (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv)))) { 576 ALOGV("%s: Remaining Len:%d readLen:%d type:%d length:%d", 577 __func__, remainingLen, readLen, outputTlv.type, 578 outputTlv.length); 579 switch (outputTlv.type) { 580 case NAN_TLV_TYPE_CLUSTER_SIZE_RSP: 581 if (outputTlv.length != 2 * sizeof(u32)) { 582 ALOGE("%s: Wrong length %d in Tca Indication expecting %zu bytes", 583 __func__, outputTlv.length, 2 * sizeof(u32)); 584 break; 585 } 586 event->rising_direction_evt_flag = outputTlv.value[0] & 0x01; 587 event->falling_direction_evt_flag = (outputTlv.value[0] & 0x02) >> 1; 588 memcpy(&(event->data.cluster.cluster_size), &outputTlv.value[4], 589 sizeof(event->data.cluster.cluster_size)); 590 event->tca_type = NAN_TCA_ID_CLUSTER_SIZE; 591 break; 592 default: 593 ALOGV("Unhandled TLV type:%d", outputTlv.type); 594 break; 595 } 596 remainingLen -= readLen; 597 pInputTlv += readLen; 598 memset(&outputTlv,0, sizeof(outputTlv)); 599 } 600 return WIFI_SUCCESS; 601 } 602 603 int NanCommand::getNanBeaconSdfPayload(NanBeaconSdfPayloadInd *event) 604 { 605 if (event == NULL || mNanVendorEvent == NULL) { 606 ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p", 607 __func__, event, mNanVendorEvent); 608 return WIFI_ERROR_INVALID_ARGS; 609 } 610 611 pNanBeaconSdfPayloadIndMsg pRsp = (pNanBeaconSdfPayloadIndMsg)mNanVendorEvent; 612 memset(&event->data, 0, sizeof(event->data)); 613 614 u8 *pInputTlv = pRsp->ptlv; 615 NanTlv outputTlv; 616 u16 readLen = 0; 617 int remainingLen = (mNanDataLen - \ 618 (sizeof(NanMsgHeader))); 619 620 //Has Mac address 621 if (remainingLen <= 0) { 622 ALOGV("%s: No TLV's present",__func__); 623 return WIFI_SUCCESS; 624 } 625 626 ALOGV("%s: TLV remaining Len:%d",__func__, remainingLen); 627 while ((remainingLen > 0) && 628 (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv)))) { 629 ALOGV("%s: Remaining Len:%d readLen:%d type:%d length:%d", 630 __func__, remainingLen, readLen, outputTlv.type, 631 outputTlv.length); 632 switch (outputTlv.type) { 633 case NAN_TLV_TYPE_MAC_ADDRESS: 634 if (outputTlv.length > sizeof(event->addr)) { 635 outputTlv.length = sizeof(event->addr); 636 } 637 memcpy(event->addr, outputTlv.value, 638 outputTlv.length); 639 break; 640 641 case NAN_TLV_TYPE_VENDOR_SPECIFIC_ATTRIBUTE_RECEIVE: 642 { 643 NanReceiveVendorSpecificAttribute* recvVsaattr = &event->vsa; 644 if (outputTlv.length < sizeof(u32)) { 645 ALOGE("NAN_TLV_TYPE_VENDOR_SPECIFIC_ATTRIBUTE_RECEIVE" 646 "Incorrect length:%d", outputTlv.length); 647 break; 648 } 649 event->is_vsa_received = 1; 650 recvVsaattr->vsa_received_on = (outputTlv.value[0] >> 1) & 0x07; 651 memcpy(&recvVsaattr->vendor_oui, &outputTlv.value[1], 652 3); 653 recvVsaattr->attr_len = outputTlv.length - 4; 654 if (recvVsaattr->attr_len > NAN_MAX_VSA_DATA_LEN) { 655 recvVsaattr->attr_len = NAN_MAX_VSA_DATA_LEN; 656 } 657 if (recvVsaattr->attr_len) { 658 memcpy(recvVsaattr->vsa, &outputTlv.value[4], 659 recvVsaattr->attr_len); 660 } 661 break; 662 } 663 664 case NAN_TLV_TYPE_BEACON_SDF_PAYLOAD_RECEIVE: 665 event->is_beacon_sdf_payload_received = 1; 666 event->data.frame_len = outputTlv.length; 667 if (event->data.frame_len > NAN_MAX_FRAME_DATA_LEN) { 668 event->data.frame_len = NAN_MAX_FRAME_DATA_LEN; 669 } 670 memcpy(&event->data.frame_data, &outputTlv.value[0], 671 event->data.frame_len); 672 break; 673 674 default: 675 ALOGV("Unhandled TLV Type:%d", outputTlv.type); 676 break; 677 } 678 remainingLen -= readLen; 679 pInputTlv += readLen; 680 memset(&outputTlv,0, sizeof(outputTlv)); 681 } 682 return WIFI_SUCCESS; 683 } 684 685 void NanCommand::getNanReceivePostConnectivityCapabilityVal( 686 const u8 *pInValue, 687 NanReceivePostConnectivityCapability *pRxCapab) 688 { 689 if (pInValue && pRxCapab) { 690 pRxCapab->is_mesh_supported = (pInValue[0] & (0x01 << 5)); 691 pRxCapab->is_ibss_supported = (pInValue[0] & (0x01 << 4)); 692 pRxCapab->wlan_infra_field = (pInValue[0] & (0x01 << 3)); 693 pRxCapab->is_tdls_supported = (pInValue[0] & (0x01 << 2)); 694 pRxCapab->is_wfds_supported = (pInValue[0] & (0x01 << 1)); 695 pRxCapab->is_wfd_supported = pInValue[0] & 0x01; 696 } 697 } 698 699 void NanCommand::getNanReceiveSdeaCtrlParams(const u8* pInValue, 700 NanSdeaCtrlParams *pPeerSdeaParams) 701 { 702 if (pInValue && pPeerSdeaParams) { 703 pPeerSdeaParams->security_cfg = 704 (NanDataPathSecurityCfgStatus)((pInValue[0] & BIT_6) ? 705 NAN_DP_CONFIG_SECURITY : NAN_DP_CONFIG_NO_SECURITY); 706 pPeerSdeaParams->ranging_state = 707 (NanRangingState)((pInValue[0] & BIT_7) ? 708 NAN_RANGING_ENABLE : NAN_RANGING_DISABLE); 709 #if 0 710 pPeerSdeaParams->enable_ranging_limit = 711 (NanRangingLimitState)((pInValue[0] & BIT_8) ? 712 NAN_RANGING_LIMIT_ENABLE : NAN_RANGING_LIMIT_DISABLE); 713 #endif 714 } 715 return; 716 } 717 718 int NanCommand::getNanReceivePostDiscoveryVal(const u8 *pInValue, 719 u32 length, 720 NanReceivePostDiscovery *pRxDisc) 721 { 722 int ret = 0; 723 724 if (length <= 8 || pInValue == NULL) { 725 ALOGE("%s: Invalid Arg TLV Len %d < 4", 726 __func__, length); 727 return -1; 728 } 729 730 pRxDisc->type = (NanConnectionType) pInValue[0]; 731 pRxDisc->role = (NanDeviceRole) pInValue[1]; 732 pRxDisc->duration = (NanAvailDuration) (pInValue[2] & 0x03); 733 pRxDisc->mapid = ((pInValue[2] >> 2) & 0x0F); 734 memcpy(&pRxDisc->avail_interval_bitmap, 735 &pInValue[4], 736 sizeof(pRxDisc->avail_interval_bitmap)); 737 738 u8 *pInputTlv = (u8 *)&pInValue[8]; 739 NanTlv outputTlv; 740 u16 readLen = 0; 741 int remainingLen = (length - 8); 742 743 //Has Mac address 744 if (remainingLen <= 0) { 745 ALOGE("%s: No TLV's present",__func__); 746 return -1; 747 } 748 749 ALOGV("%s: TLV remaining Len:%d",__func__, remainingLen); 750 while ((remainingLen > 0) && 751 (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv)))) { 752 ALOGV("%s: Remaining Len:%d readLen:%d type:%d length:%d", 753 __func__, remainingLen, readLen, outputTlv.type, 754 outputTlv.length); 755 switch (outputTlv.type) { 756 case NAN_TLV_TYPE_MAC_ADDRESS: 757 if (outputTlv.length > sizeof(pRxDisc->addr)) { 758 outputTlv.length = sizeof(pRxDisc->addr); 759 } 760 memcpy(pRxDisc->addr, outputTlv.value, outputTlv.length); 761 break; 762 case NAN_TLV_TYPE_WLAN_MESH_ID: 763 if (outputTlv.length > sizeof(pRxDisc->mesh_id)) { 764 outputTlv.length = sizeof(pRxDisc->mesh_id); 765 } 766 memcpy(pRxDisc->mesh_id, outputTlv.value, outputTlv.length); 767 pRxDisc->mesh_id_len = outputTlv.length; 768 break; 769 case NAN_TLV_TYPE_WLAN_INFRA_SSID: 770 if (outputTlv.length > sizeof(pRxDisc->infrastructure_ssid_val)) { 771 outputTlv.length = sizeof(pRxDisc->infrastructure_ssid_val); 772 } 773 memcpy(pRxDisc->infrastructure_ssid_val, outputTlv.value, 774 outputTlv.length); 775 pRxDisc->infrastructure_ssid_len = outputTlv.length; 776 default: 777 ALOGV("Unhandled TLV Type:%d", outputTlv.type); 778 break; 779 } 780 remainingLen -= readLen; 781 pInputTlv += readLen; 782 memset(&outputTlv,0, sizeof(outputTlv)); 783 } 784 return ret; 785 } 786 787 int NanCommand::getNanFurtherAvailabilityMap(const u8 *pInValue, 788 u32 length, 789 u8 *num_chans, 790 NanFurtherAvailabilityChannel *pFac) 791 { 792 int idx = 0; 793 794 if ((length == 0) || pInValue == NULL) { 795 ALOGE("%s: Invalid Arg TLV Len %d or pInValue NULL", 796 __func__, length); 797 return -1; 798 } 799 800 *num_chans = pInValue[0]; 801 if (*num_chans > NAN_MAX_FAM_CHANNELS) { 802 ALOGE("%s: Unable to accommodate numchans %d", 803 __func__, *num_chans); 804 return -1; 805 } 806 807 if (length < (sizeof(u8) + 808 (*num_chans * sizeof(NanFurtherAvailabilityChan)))) { 809 ALOGE("%s: Invalid TLV Length", __func__); 810 return -1; 811 } 812 813 for (idx = 0; idx < *num_chans; idx++) { 814 pNanFurtherAvailabilityChan pRsp = \ 815 (pNanFurtherAvailabilityChan)((u8 *)&pInValue[1] + \ 816 (idx * sizeof(NanFurtherAvailabilityChan))); 817 818 pFac->entry_control = \ 819 (NanAvailDuration)(pRsp->entryCtrl.availIntDuration); 820 pFac->mapid = pRsp->entryCtrl.mapId; 821 pFac->class_val = pRsp->opClass; 822 pFac->channel = pRsp->channel; 823 memcpy(&pFac->avail_interval_bitmap, 824 &pRsp->availIntBitmap, 825 sizeof(pFac->avail_interval_bitmap)); 826 pFac++; 827 } 828 return 0; 829 } 830 831 int NanCommand::getNanStaParameter(wifi_interface_handle iface, 832 NanStaParameter *pRsp) 833 { 834 int ret = WIFI_ERROR_NONE; 835 int res = -1; 836 transaction_id id = 1; 837 interface_info *ifaceInfo = getIfaceInfo(iface); 838 839 ret = create(); 840 if (ret < 0) 841 goto cleanup; 842 843 /* Set the interface Id of the message. */ 844 ret = set_iface_id(ifaceInfo->name); 845 if (ret < 0) 846 goto cleanup; 847 848 /* 849 Construct NL message to get the sync stats parameter 850 which has all the parameter required by staparameter. 851 */ 852 NanStatsRequest syncStats; 853 memset(&syncStats, 0, sizeof(syncStats)); 854 syncStats.stats_type = NAN_STATS_ID_DE_TIMING_SYNC; 855 syncStats.clear = 0; 856 857 mStaParam = pRsp; 858 ret = putNanStats(id, &syncStats); 859 if (ret != 0) { 860 ALOGE("%s: putNanStats Error:%d",__func__, ret); 861 goto cleanup; 862 } 863 ret = requestEvent(); 864 if (ret != 0) { 865 ALOGE("%s: requestEvent Error:%d",__func__, ret); 866 goto cleanup; 867 } 868 869 struct timespec abstime; 870 abstime.tv_sec = 4; 871 abstime.tv_nsec = 0; 872 res = mCondition.wait(abstime); 873 if (res == ETIMEDOUT) 874 { 875 ALOGE("%s: Time out happened.", __func__); 876 ret = WIFI_ERROR_TIMED_OUT; 877 goto cleanup; 878 } 879 ALOGV("%s: NanStaparameter Master_pref:%x," \ 880 " Random_factor:%x, hop_count:%x " \ 881 " beacon_transmit_time:%d" \ 882 " ndp_channel_freq:%d", __func__, 883 pRsp->master_pref, pRsp->random_factor, 884 pRsp->hop_count, pRsp->beacon_transmit_time, pRsp->ndp_channel_freq); 885 cleanup: 886 mStaParam = NULL; 887 return (int)ret; 888 } 889 890 int NanCommand::getNanTransmitFollowupInd(NanTransmitFollowupInd *event) 891 { 892 if (event == NULL || mNanVendorEvent == NULL) { 893 ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p", 894 __func__, event, mNanVendorEvent); 895 return WIFI_ERROR_INVALID_ARGS; 896 } 897 898 pNanSelfTransmitFollowupIndMsg pRsp = (pNanSelfTransmitFollowupIndMsg)mNanVendorEvent; 899 event->id = pRsp->fwHeader.transactionId; 900 NanErrorTranslation((NanInternalStatusType)pRsp->reason, 0, 901 (void*)event); 902 return WIFI_SUCCESS; 903 } 904 905 //Function which calls the necessaryIndication callback 906 //based on the indication type 907 int NanCommand::handleNdpIndication(u32 ndpCmdType, struct nlattr **tb_vendor) 908 { 909 //Based on the message_id in the header determine the Indication type 910 //and call the necessary callback handler 911 int res = 0; 912 913 ALOGI("handleNdpIndication msg_id:%u", ndpCmdType); 914 switch (ndpCmdType) { 915 case QCA_WLAN_VENDOR_ATTR_NDP_DATA_REQUEST_IND: 916 NanDataPathRequestInd ndpRequestInd; 917 memset(&ndpRequestInd, 0, sizeof(ndpRequestInd)); 918 919 res = getNdpRequest(tb_vendor, &ndpRequestInd); 920 if (!res && mHandler.EventDataRequest) { 921 (*mHandler.EventDataRequest)(&ndpRequestInd); 922 } 923 break; 924 925 case QCA_WLAN_VENDOR_ATTR_NDP_CONFIRM_IND: 926 NanDataPathConfirmInd ndpConfirmInd; 927 memset(&ndpConfirmInd, 0, sizeof(ndpConfirmInd)); 928 929 res = getNdpConfirm(tb_vendor, &ndpConfirmInd); 930 if (!res && mHandler.EventDataConfirm) { 931 (*mHandler.EventDataConfirm)(&ndpConfirmInd); 932 } 933 break; 934 935 case QCA_WLAN_VENDOR_ATTR_NDP_END_IND: 936 { 937 NanDataPathEndInd *ndpEndInd = NULL; 938 u8 num_ndp_ids = 0; 939 940 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]) { 941 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP not found", __FUNCTION__); 942 return WIFI_ERROR_INVALID_ARGS; 943 } 944 945 num_ndp_ids = (u8)(nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY])/sizeof(u32)); 946 ALOGD("%s: NDP Num Instance Ids : val %d", __FUNCTION__, num_ndp_ids); 947 948 if (num_ndp_ids) { 949 ndpEndInd = 950 (NanDataPathEndInd *)malloc(sizeof(NanDataPathEndInd)+ (sizeof(u32) * num_ndp_ids)); 951 if (!ndpEndInd) { 952 ALOGE("%s: ndp_instance_id malloc Failed", __FUNCTION__); 953 return WIFI_ERROR_OUT_OF_MEMORY; 954 } 955 ndpEndInd->num_ndp_instances = num_ndp_ids; 956 nla_memcpy(ndpEndInd->ndp_instance_id, 957 tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY], 958 sizeof(u32) * ndpEndInd->num_ndp_instances); 959 } 960 if (mHandler.EventDataEnd) { 961 (*mHandler.EventDataEnd)(ndpEndInd); 962 } 963 free(ndpEndInd); 964 break; 965 } 966 default: 967 ALOGE("handleNdpIndication error invalid ndpCmdType:%u", ndpCmdType); 968 res = (int)WIFI_ERROR_INVALID_REQUEST_ID; 969 break; 970 } 971 return res; 972 } 973 974 int NanCommand::getNdpRequest(struct nlattr **tb_vendor, 975 NanDataPathRequestInd *event) 976 { 977 u32 len = 0; 978 979 if (event == NULL || tb_vendor == NULL) { 980 ALOGE("%s: Invalid input argument event:%p tb_vendor:%p", 981 __FUNCTION__, event, tb_vendor); 982 return WIFI_ERROR_INVALID_ARGS; 983 } 984 if ((!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID]) || 985 (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]) || 986 (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID])) { 987 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP not found", __FUNCTION__); 988 return WIFI_ERROR_INVALID_ARGS; 989 } 990 991 event->service_instance_id = nla_get_u16(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID]); 992 ALOGD("%s: Service Instance id : val %d", __FUNCTION__, event->service_instance_id); 993 994 len = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]); 995 len = ((sizeof(event->peer_disc_mac_addr) <= len) ? sizeof(event->peer_disc_mac_addr) : len); 996 memcpy(&event->peer_disc_mac_addr[0], nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]), len); 997 998 event->ndp_instance_id = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]); 999 ALOGD("%s: Ndp Instance id: %d", __FUNCTION__, event->ndp_instance_id); 1000 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]) { 1001 len = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]); 1002 len = ((sizeof(event->app_info.ndp_app_info) <= len) ? sizeof(event->app_info.ndp_app_info) : len); 1003 memcpy(&event->app_info.ndp_app_info[0], nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]), len); 1004 event->app_info.ndp_app_info_len = len; 1005 } else { 1006 ALOGD("%s: NDP App Info not present", __FUNCTION__); 1007 } 1008 return WIFI_SUCCESS; 1009 } 1010 1011 int NanCommand::getNdpConfirm(struct nlattr **tb_vendor, 1012 NanDataPathConfirmInd *event) 1013 { 1014 u32 len = 0; 1015 1016 if (event == NULL || tb_vendor == NULL) { 1017 ALOGE("%s: Invalid input argument event:%p tb_vendor:%p", 1018 __FUNCTION__, event, tb_vendor); 1019 return WIFI_ERROR_INVALID_ARGS; 1020 } 1021 if ((!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]) || 1022 (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR]) || 1023 (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE])) { 1024 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP not found", __FUNCTION__); 1025 return WIFI_ERROR_INVALID_ARGS; 1026 } 1027 1028 event->ndp_instance_id = nla_get_u16(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]); 1029 ALOGD("%s: Service Instance id : val %d", __FUNCTION__, event->ndp_instance_id); 1030 1031 len = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR]); 1032 len = ((sizeof(event->peer_ndi_mac_addr) <= len) ? sizeof(event->peer_ndi_mac_addr) : len); 1033 memcpy(&event->peer_ndi_mac_addr[0], nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR]), len); 1034 1035 event->rsp_code = (NanDataPathResponseCode)nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE]); 1036 ALOGD("%s: Response code %d", __FUNCTION__, event->rsp_code); 1037 1038 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]) { 1039 len = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]); 1040 len = ((sizeof(event->app_info.ndp_app_info) <= len) ? sizeof(event->app_info.ndp_app_info) : len); 1041 memcpy(&event->app_info.ndp_app_info[0], nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]), len); 1042 event->app_info.ndp_app_info_len = len; 1043 } else { 1044 ALOGD("%s: NDP App Info not present", __FUNCTION__); 1045 } 1046 return WIFI_SUCCESS; 1047 } 1048 1049 int NanCommand::getNanRangeRequestReceivedInd(NanRangeRequestInd *event) 1050 { 1051 if (event == NULL || mNanVendorEvent == NULL) { 1052 ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p", 1053 __func__, event, mNanVendorEvent); 1054 return WIFI_ERROR_INVALID_ARGS; 1055 } 1056 1057 pNanFWRangeReqRecvdInd pRsp = (pNanFWRangeReqRecvdInd)mNanVendorEvent; 1058 1059 u8 *pInputTlv = pRsp->ptlv; 1060 NanTlv outputTlv; 1061 u16 readLen = 0; 1062 1063 int remainingLen = (mNanDataLen - \ 1064 (sizeof(NanMsgHeader))); 1065 1066 if (remainingLen <= 0) { 1067 ALOGE("%s: No TLV's present",__func__); 1068 return WIFI_SUCCESS; 1069 } 1070 1071 ALOGV("%s: TLV remaining Len:%d",__func__, remainingLen); 1072 while ((remainingLen > 0) && 1073 (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv)))) { 1074 ALOGV("%s: Remaining Len:%d readLen:%d type:%d length:%d", 1075 __func__, remainingLen, readLen, outputTlv.type, 1076 outputTlv.length); 1077 switch (outputTlv.type) { 1078 case NAN_TLV_TYPE_NAN20_RANGING_REQUEST_RECEIVED: 1079 NanFWRangeReqRecvdMsg fwRangeReqRecvd; 1080 if (outputTlv.length > sizeof(fwRangeReqRecvd)) { 1081 outputTlv.length = sizeof(fwRangeReqRecvd); 1082 } 1083 memcpy(&fwRangeReqRecvd, outputTlv.value, outputTlv.length); 1084 FW_MAC_ADDR_TO_CHAR_ARRAY(fwRangeReqRecvd.range_mac_addr, event->range_req_intf_addr); 1085 event->publish_id = fwRangeReqRecvd.range_id; 1086 break; 1087 default: 1088 ALOGV("Unhandled TLV type:%d", outputTlv.type); 1089 break; 1090 } 1091 remainingLen -= readLen; 1092 pInputTlv += readLen; 1093 memset(&outputTlv,0, sizeof(outputTlv)); 1094 } 1095 return WIFI_SUCCESS; 1096 } 1097 1098 int NanCommand::getNanRangeReportInd(NanRangeReportInd *event) 1099 { 1100 if (event == NULL || mNanVendorEvent == NULL) { 1101 ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p", 1102 __func__, event, mNanVendorEvent); 1103 return WIFI_ERROR_INVALID_ARGS; 1104 } 1105 1106 pNanFWRangeReportInd pRsp = (pNanFWRangeReportInd)mNanVendorEvent; 1107 1108 u8 *pInputTlv = pRsp->ptlv; 1109 NanTlv outputTlv; 1110 u16 readLen = 0; 1111 1112 int remainingLen = (mNanDataLen - \ 1113 (sizeof(NanMsgHeader))); 1114 1115 if (remainingLen <= 0) { 1116 ALOGE("%s: No TLV's present",__func__); 1117 return WIFI_SUCCESS; 1118 } 1119 1120 ALOGV("%s: TLV remaining Len:%d",__func__, remainingLen); 1121 while ((remainingLen > 0) && 1122 (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv)))) { 1123 ALOGV("%s: Remaining Len:%d readLen:%d type:%d length:%d", 1124 __func__, remainingLen, readLen, outputTlv.type, 1125 outputTlv.length); 1126 switch (outputTlv.type) { 1127 case NAN_TLV_TYPE_MAC_ADDRESS: 1128 if (outputTlv.length > NAN_MAC_ADDR_LEN) { 1129 outputTlv.length = NAN_MAC_ADDR_LEN; 1130 } 1131 memcpy(event->range_req_intf_addr, outputTlv.value, outputTlv.length); 1132 break; 1133 1134 case NAN_TLV_TYPE_NAN20_RANGING_RESULT: 1135 NanFWRangeReportParams range_params; 1136 if (outputTlv.length > sizeof(NanFWRangeReportParams)) { 1137 outputTlv.length = sizeof(NanFWRangeReportParams); 1138 } 1139 memcpy(&range_params, outputTlv.value, outputTlv.length); 1140 event->range_measurement_cm = range_params.range_measurement; 1141 event->publish_id = range_params.publish_id; 1142 // event->event_type = range_params.event_type; 1143 break; 1144 default: 1145 ALOGV("Unhandled TLV type:%d", outputTlv.type); 1146 break; 1147 } 1148 remainingLen -= readLen; 1149 pInputTlv += readLen; 1150 memset(&outputTlv,0, sizeof(outputTlv)); 1151 } 1152 return WIFI_SUCCESS; 1153 } 1154