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