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 "nan.h" 21 #include "wifi_hal.h" 22 #include "nan_i.h" 23 #include "nancommand.h" 24 #include <errno.h> 25 26 #define NAN_TERMINATED_BEGINNING_OFFSET 8192 27 28 //Function which calls the necessaryIndication callback 29 //based on the indication type 30 int NanCommand::handleNanIndication() 31 { 32 //Based on the message_id in the header determine the Indication type 33 //and call the necessary callback handler 34 u16 msg_id; 35 int res = 0; 36 37 ALOGI("handleNanIndication called %p", this); 38 msg_id = getIndicationType(); 39 40 ALOGI("handleNanIndication msg_id:%u", msg_id); 41 switch (msg_id) { 42 case NAN_INDICATION_PUBLISH_REPLIED: 43 NanPublishRepliedInd publishRepliedInd; 44 memset(&publishRepliedInd, 0, sizeof(publishRepliedInd)); 45 res = getNanPublishReplied(&publishRepliedInd); 46 if (!res && mHandler.EventPublishReplied) { 47 (*mHandler.EventPublishReplied)(&publishRepliedInd, 48 mUserData); 49 } 50 break; 51 52 case NAN_INDICATION_PUBLISH_TERMINATED: 53 NanPublishTerminatedInd publishTerminatedInd; 54 memset(&publishTerminatedInd, 0, sizeof(publishTerminatedInd)); 55 res = getNanPublishTerminated(&publishTerminatedInd); 56 if (!res && mHandler.EventPublishTerminated) { 57 (*mHandler.EventPublishTerminated)(&publishTerminatedInd, 58 mUserData); 59 } 60 break; 61 62 case NAN_INDICATION_MATCH: 63 NanMatchInd matchInd; 64 memset(&matchInd, 0, sizeof(matchInd)); 65 res = getNanMatch(&matchInd); 66 if (!res && mHandler.EventMatch) { 67 (*mHandler.EventMatch)(&matchInd, mUserData); 68 } 69 break; 70 71 case NAN_INDICATION_UNMATCH: 72 NanUnmatchInd unMatchInd; 73 memset(&unMatchInd, 0, sizeof(unMatchInd)); 74 res = getNanUnMatch(&unMatchInd); 75 if (!res && mHandler.EventUnMatch) { 76 (*mHandler.EventUnMatch)(&unMatchInd, mUserData); 77 } 78 break; 79 80 case NAN_INDICATION_SUBSCRIBE_TERMINATED: 81 NanSubscribeTerminatedInd subscribeTerminatedInd; 82 memset(&subscribeTerminatedInd, 0, sizeof(subscribeTerminatedInd)); 83 res = getNanSubscribeTerminated(&subscribeTerminatedInd); 84 if (!res && mHandler.EventSubscribeTerminated) { 85 (*mHandler.EventSubscribeTerminated)(&subscribeTerminatedInd, 86 mUserData); 87 } 88 break; 89 90 case NAN_INDICATION_DE_EVENT: 91 NanDiscEngEventInd discEngEventInd; 92 memset(&discEngEventInd, 0, sizeof(discEngEventInd)); 93 res = getNanDiscEngEvent(&discEngEventInd); 94 if (!res && mHandler.EventDiscEngEvent) { 95 (*mHandler.EventDiscEngEvent)(&discEngEventInd, 96 mUserData); 97 } 98 break; 99 100 case NAN_INDICATION_FOLLOWUP: 101 NanFollowupInd followupInd; 102 memset(&followupInd, 0, sizeof(followupInd)); 103 res = getNanFollowup(&followupInd); 104 if (!res && mHandler.EventFollowup) { 105 (*mHandler.EventFollowup)(&followupInd, 106 mUserData); 107 } 108 break; 109 110 case NAN_INDICATION_DISABLED: 111 NanDisabledInd disabledInd; 112 memset(&disabledInd, 0, sizeof(disabledInd)); 113 res = getNanDisabled(&disabledInd); 114 if (!res && mHandler.EventDisabled) { 115 (*mHandler.EventDisabled)(&disabledInd, 116 mUserData); 117 } 118 break; 119 120 case NAN_INDICATION_TCA: 121 NanTCAInd tcaInd; 122 memset(&tcaInd, 0, sizeof(tcaInd)); 123 res = getNanTca(&tcaInd); 124 if (!res && mHandler.EventTca) { 125 (*mHandler.EventTca)(&tcaInd, 126 mUserData); 127 } 128 break; 129 130 case NAN_INDICATION_BEACON_SDF_PAYLOAD: 131 NanBeaconSdfPayloadInd beaconSdfPayloadInd; 132 memset(&beaconSdfPayloadInd, 0, sizeof(beaconSdfPayloadInd)); 133 res = getNanBeaconSdfPayload(&beaconSdfPayloadInd); 134 if (!res && mHandler.EventSdfPayload) { 135 (*mHandler.EventSdfPayload)(&beaconSdfPayloadInd, 136 mUserData); 137 } 138 break; 139 140 default: 141 ALOGE("handleNanIndication error invalid msg_id:%u", msg_id); 142 res = (int)WIFI_ERROR_INVALID_REQUEST_ID; 143 break; 144 } 145 return res; 146 } 147 148 //Function which will return the Nan Indication type based on 149 //the initial few bytes of mNanVendorEvent 150 NanIndicationType NanCommand::getIndicationType() 151 { 152 if (mNanVendorEvent == NULL) { 153 ALOGE("%s: Invalid argument mNanVendorEvent:%p", 154 __func__, mNanVendorEvent); 155 return NAN_INDICATION_UNKNOWN; 156 } 157 158 NanMsgHeader *pHeader = (NanMsgHeader *)mNanVendorEvent; 159 160 switch (pHeader->msgId) { 161 case NAN_MSG_ID_PUBLISH_REPLIED_IND: 162 return NAN_INDICATION_PUBLISH_REPLIED; 163 case NAN_MSG_ID_PUBLISH_TERMINATED_IND: 164 return NAN_INDICATION_PUBLISH_TERMINATED; 165 case NAN_MSG_ID_MATCH_IND: 166 return NAN_INDICATION_MATCH; 167 case NAN_MSG_ID_UNMATCH_IND: 168 return NAN_INDICATION_UNMATCH; 169 case NAN_MSG_ID_FOLLOWUP_IND: 170 return NAN_INDICATION_FOLLOWUP; 171 case NAN_MSG_ID_SUBSCRIBE_TERMINATED_IND: 172 return NAN_INDICATION_SUBSCRIBE_TERMINATED; 173 case NAN_MSG_ID_DE_EVENT_IND: 174 return NAN_INDICATION_DE_EVENT; 175 case NAN_MSG_ID_DISABLE_IND: 176 return NAN_INDICATION_DISABLED; 177 case NAN_MSG_ID_TCA_IND: 178 return NAN_INDICATION_TCA; 179 #ifdef NAN_2_0 180 case NAN_MSG_ID_BEACON_SDF_IND: 181 return NAN_INDICATION_BEACON_SDF_PAYLOAD; 182 #endif /* NAN_2_0 */ 183 default: 184 return NAN_INDICATION_UNKNOWN; 185 } 186 } 187 188 int NanCommand::getNanPublishReplied(NanPublishRepliedInd *event) 189 { 190 if (event == NULL || mNanVendorEvent == NULL) { 191 ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p", 192 __func__, event, mNanVendorEvent); 193 return WIFI_ERROR_INVALID_ARGS; 194 } 195 196 pNanPublishRepliedIndMsg pRsp = (pNanPublishRepliedIndMsg)mNanVendorEvent; 197 event->header.handle = pRsp->fwHeader.handle; 198 event->header.transaction_id = pRsp->fwHeader.transactionId; 199 #ifndef NAN_2_0 200 memcpy(event->addr, pRsp->publishRepliedIndParams.macAddr, sizeof(event->addr)); 201 #else /* NAN_2_0 */ 202 event->rssi_value = 0; 203 u8 *pInputTlv = pRsp->ptlv; 204 NanTlv outputTlv; 205 u16 readLen = 0; 206 int ret = 0; 207 int remainingLen = (mNanDataLen - \ 208 (sizeof(NanMsgHeader))); 209 210 //Has NAN Mac address mandatory, received RSSI value optional 211 //POST_NAN_CONNECTIVITY_CAPABILITIES_RECEIVE 212 //POST_NAN_DISCOVERY_ATTRIBUTE_RECEIVE 213 //NAN_FURTHER_AVAILABILITY_MAP 214 //NAN_CLUSTER_ATTRIBUTE 215 if (remainingLen <= 0) { 216 ALOGI("%s: No TLV's present",__func__); 217 return WIFI_SUCCESS; 218 } 219 ALOGI("%s: TLV remaining Len:%d",__func__, remainingLen); 220 while ((remainingLen > 0) && 221 (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv)))) { 222 ALOGI("%s: Remaining Len:%d readLen:%d type:%d length:%d", 223 __func__, remainingLen, readLen, outputTlv.type, 224 outputTlv.length); 225 switch (outputTlv.type) { 226 case NAN_TLV_TYPE_MAC_ADDRESS: 227 if (outputTlv.length > sizeof(event->addr)) { 228 outputTlv.length = sizeof(event->addr); 229 } 230 memcpy(event->addr, outputTlv.value, outputTlv.length); 231 break; 232 case NAN_TLV_TYPE_RECEIVED_RSSI_VALUE: 233 if (outputTlv.length > sizeof(event->rssi_value)) { 234 outputTlv.length = sizeof(event->rssi_value); 235 } 236 memcpy(&event->rssi_value, outputTlv.value, 237 outputTlv.length); 238 break; 239 case NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_RECEIVE: 240 if (outputTlv.length != sizeof(u32)) { 241 ALOGE("NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_RECEIVE" 242 "Incorrect size:%d expecting %d", outputTlv.length, 243 sizeof(u32)); 244 break; 245 } 246 event->is_conn_capability_valid = 1; 247 /* Populate conn_capability from received TLV */ 248 getNanReceivePostConnectivityCapabilityVal(outputTlv.value, 249 &event->conn_capability); 250 break; 251 case NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_RECEIVE: 252 /* Populate receive discovery attribute from 253 received TLV */ 254 ret = getNanReceivePostDiscoveryVal(outputTlv.value, 255 outputTlv.length, 256 &event->discovery_attr); 257 if (ret == 0) { 258 event->is_discovery_attr_valid = 1; 259 } 260 else { 261 ALOGE("NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_RECEIVE" 262 "Incorrect"); 263 } 264 break; 265 case NAN_TLV_TYPE_FURTHER_AVAILABILITY_MAP: 266 /* Populate further availability bitmap from 267 received TLV */ 268 ret = getNanFurtherAvailabilityMap(outputTlv.value, 269 outputTlv.length, 270 &event->fam); 271 if (ret == 0) { 272 event->is_fam_valid = 1; 273 } 274 else { 275 ALOGE("NAN_TLV_TYPE_FURTHER_AVAILABILITY_MAP" 276 "Incorrect"); 277 } 278 break; 279 case NAN_TLV_TYPE_CLUSTER_ATTIBUTE: 280 if (outputTlv.length > sizeof(event->cluster_attribute)) { 281 outputTlv.length = sizeof(event->cluster_attribute); 282 } 283 memcpy(event->cluster_attribute, 284 outputTlv.value, outputTlv.length); 285 event->cluster_attribute_len = outputTlv.length; 286 break; 287 default: 288 ALOGI("Unknown TLV type skipped"); 289 break; 290 } 291 remainingLen -= readLen; 292 pInputTlv += readLen; 293 memset(&outputTlv, 0, sizeof(outputTlv)); 294 } 295 #endif /* NAN_2_0 */ 296 return WIFI_SUCCESS; 297 } 298 299 300 int NanCommand::getNanPublishTerminated(NanPublishTerminatedInd *event) 301 { 302 if (event == NULL || mNanVendorEvent == NULL) { 303 ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p", 304 __func__, event, mNanVendorEvent); 305 return WIFI_ERROR_INVALID_ARGS; 306 } 307 308 pNanPublishTerminatedIndMsg pRsp = (pNanPublishTerminatedIndMsg)mNanVendorEvent; 309 event->header.handle = pRsp->fwHeader.handle; 310 event->header.transaction_id = pRsp->fwHeader.transactionId; 311 #ifdef NAN_2_0 312 pRsp->reason -= NAN_TERMINATED_BEGINNING_OFFSET; 313 #endif /* NAN_2_0 */ 314 event->reason = (NanTerminatedStatus)pRsp->reason; 315 return WIFI_SUCCESS; 316 } 317 318 int NanCommand::getNanMatch(NanMatchInd *event) 319 { 320 if (event == NULL || mNanVendorEvent == NULL) { 321 ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p", 322 __func__, event, mNanVendorEvent); 323 return WIFI_ERROR_INVALID_ARGS; 324 } 325 326 pNanMatchIndMsg pRsp = (pNanMatchIndMsg)mNanVendorEvent; 327 event->header.handle = pRsp->fwHeader.handle; 328 event->header.transaction_id = pRsp->fwHeader.transactionId; 329 event->match_handle = pRsp->matchIndParams.matchHandle; 330 #ifndef NAN_2_0 331 memcpy(event->addr, pRsp->matchIndParams.macAddr, sizeof(event->addr)); 332 #else /* NAN_2_0 */ 333 event->match_occured_flag = pRsp->matchIndParams.matchOccuredFlag; 334 event->out_of_resource_flag = pRsp->matchIndParams.outOfResourceFlag; 335 #endif /* NAN_2_0 */ 336 337 u8 *pInputTlv = pRsp->ptlv; 338 NanTlv outputTlv; 339 u16 readLen = 0; 340 int remainingLen = (mNanDataLen - \ 341 (sizeof(NanMsgHeader) + sizeof(NanMatchIndParams))); 342 int ret = 0; 343 344 //Has SDF match filter and service specific info TLV 345 if (remainingLen <= 0) { 346 ALOGI("%s: No TLV's present",__func__); 347 return WIFI_SUCCESS; 348 } 349 ALOGI("%s: TLV remaining Len:%d",__func__, remainingLen); 350 while ((remainingLen > 0) && 351 (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv)))) { 352 ALOGI("%s: Remaining Len:%d readLen:%d type:%d length:%d", 353 __func__, remainingLen, readLen, outputTlv.type, 354 outputTlv.length); 355 switch (outputTlv.type) { 356 case NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO: 357 if (outputTlv.length > NAN_MAX_SERVICE_NAME_LEN) { 358 outputTlv.length = NAN_MAX_SERVICE_NAME_LEN; 359 } 360 event->service_specific_info_len = outputTlv.length; 361 memcpy(event->service_specific_info, outputTlv.value, 362 outputTlv.length); 363 break; 364 case NAN_TLV_TYPE_SDF_MATCH_FILTER: 365 if (outputTlv.length > NAN_MAX_MATCH_FILTER_LEN) { 366 outputTlv.length = NAN_MAX_MATCH_FILTER_LEN; 367 } 368 event->sdf_match_filter_len = outputTlv.length; 369 memcpy(event->sdf_match_filter, outputTlv.value, 370 outputTlv.length); 371 break; 372 #ifdef NAN_2_0 373 case NAN_TLV_TYPE_MAC_ADDRESS: 374 if (outputTlv.length > sizeof(event->addr)) { 375 outputTlv.length = sizeof(event->addr); 376 } 377 memcpy(event->addr, outputTlv.value, outputTlv.length); 378 break; 379 case NAN_TLV_TYPE_RECEIVED_RSSI_VALUE: 380 if (outputTlv.length > sizeof(event->rssi_value)) { 381 outputTlv.length = sizeof(event->rssi_value); 382 } 383 memcpy(&event->rssi_value, outputTlv.value, 384 outputTlv.length); 385 break; 386 case NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_RECEIVE: 387 if (outputTlv.length != sizeof(u32)) { 388 ALOGE("NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_RECEIVE" 389 "Incorrect size:%d expecting %d", outputTlv.length, 390 sizeof(u32)); 391 break; 392 } 393 event->is_conn_capability_valid = 1; 394 /* Populate conn_capability from received TLV */ 395 getNanReceivePostConnectivityCapabilityVal(outputTlv.value, 396 &event->conn_capability); 397 break; 398 case NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_RECEIVE: 399 /* Populate receive discovery attribute from 400 received TLV */ 401 ret = getNanReceivePostDiscoveryVal(outputTlv.value, 402 outputTlv.length, 403 &event->discovery_attr); 404 if (ret == 0) { 405 event->is_discovery_attr_valid = 1; 406 } 407 else { 408 ALOGE("NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_RECEIVE" 409 "Incorrect"); 410 } 411 break; 412 case NAN_TLV_TYPE_FURTHER_AVAILABILITY_MAP: 413 /* Populate further availability bitmap from 414 received TLV */ 415 ret = getNanFurtherAvailabilityMap(outputTlv.value, 416 outputTlv.length, 417 &event->fam); 418 if (ret == 0) { 419 event->is_fam_valid = 1; 420 } 421 else { 422 ALOGE("NAN_TLV_TYPE_FURTHER_AVAILABILITY_MAP" 423 "Incorrect"); 424 } 425 break; 426 case NAN_TLV_TYPE_CLUSTER_ATTIBUTE: 427 if (outputTlv.length > sizeof(event->cluster_attribute)) { 428 outputTlv.length = sizeof(event->cluster_attribute); 429 } 430 memcpy(event->cluster_attribute, 431 outputTlv.value, outputTlv.length); 432 event->cluster_attribute_len = outputTlv.length; 433 break; 434 #endif /* NAN_2_0 */ 435 default: 436 ALOGI("Unknown TLV type skipped"); 437 break; 438 } 439 remainingLen -= readLen; 440 pInputTlv += readLen; 441 memset(&outputTlv, 0, sizeof(outputTlv)); 442 } 443 return WIFI_SUCCESS; 444 } 445 446 int NanCommand::getNanUnMatch(NanUnmatchInd *event) 447 { 448 if (event == NULL || mNanVendorEvent == NULL) { 449 ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p", 450 __func__, event, mNanVendorEvent); 451 return WIFI_ERROR_INVALID_ARGS; 452 } 453 454 pNanUnmatchIndMsg pRsp = (pNanUnmatchIndMsg)mNanVendorEvent; 455 event->header.handle = pRsp->fwHeader.handle; 456 event->header.transaction_id = pRsp->fwHeader.transactionId; 457 event->match_handle = pRsp->unmatchIndParams.matchHandle; 458 return WIFI_SUCCESS; 459 } 460 461 int NanCommand::getNanSubscribeTerminated(NanSubscribeTerminatedInd *event) 462 { 463 if (event == NULL || mNanVendorEvent == NULL) { 464 ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p", 465 __func__, event, mNanVendorEvent); 466 return WIFI_ERROR_INVALID_ARGS; 467 } 468 469 pNanSubscribeTerminatedIndMsg pRsp = (pNanSubscribeTerminatedIndMsg)mNanVendorEvent; 470 event->header.handle = pRsp->fwHeader.handle; 471 event->header.transaction_id = pRsp->fwHeader.transactionId; 472 #ifdef NAN_2_0 473 pRsp->reason -= NAN_TERMINATED_BEGINNING_OFFSET; 474 #endif /* NAN_2_0 */ 475 event->reason = (NanTerminatedStatus)pRsp->reason; 476 return WIFI_SUCCESS; 477 } 478 479 int NanCommand::getNanFollowup(NanFollowupInd *event) 480 { 481 if (event == NULL || mNanVendorEvent == NULL) { 482 ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p", 483 __func__, event, mNanVendorEvent); 484 return WIFI_ERROR_INVALID_ARGS; 485 } 486 487 pNanFollowupIndMsg pRsp = (pNanFollowupIndMsg)mNanVendorEvent; 488 event->header.handle = pRsp->fwHeader.handle; 489 event->header.transaction_id = pRsp->fwHeader.transactionId; 490 #ifndef NAN_2_0 491 memcpy(event->addr, pRsp->followupIndParams.macAddr, sizeof(event->addr)); 492 #else /* NAN_2_0*/ 493 event->match_handle = pRsp->followupIndParams.matchHandle; 494 #endif 495 event->dw_or_faw = pRsp->followupIndParams.window; 496 497 u8 *pInputTlv = pRsp->ptlv; 498 NanTlv outputTlv; 499 u16 readLen = 0; 500 int remainingLen = (mNanDataLen - \ 501 (sizeof(NanMsgHeader) + sizeof(NanFollowupIndParams))); 502 503 //Has service specific info and extended service specific info TLV 504 if (remainingLen <= 0) { 505 ALOGI("%s: No TLV's present",__func__); 506 return WIFI_SUCCESS; 507 } 508 ALOGI("%s: TLV remaining Len:%d",__func__, remainingLen); 509 while ((remainingLen > 0) && 510 (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv)))) { 511 ALOGI("%s: Remaining Len:%d readLen:%d type:%d length:%d", 512 __func__, remainingLen, readLen, outputTlv.type, 513 outputTlv.length); 514 switch (outputTlv.type) { 515 case NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO: 516 case NAN_TLV_TYPE_EXT_SERVICE_SPECIFIC_INFO: 517 if (outputTlv.length > NAN_MAX_SERVICE_SPECIFIC_INFO_LEN) { 518 outputTlv.length = NAN_MAX_SERVICE_SPECIFIC_INFO_LEN; 519 } 520 event->service_specific_info_len = outputTlv.length; 521 memcpy(event->service_specific_info, outputTlv.value, 522 outputTlv.length); 523 break; 524 #ifdef NAN_2_0 525 case NAN_TLV_TYPE_MAC_ADDRESS: 526 if (outputTlv.length > sizeof(event->addr)) { 527 outputTlv.length = sizeof(event->addr); 528 } 529 memcpy(event->addr, outputTlv.value, outputTlv.length); 530 break; 531 #endif /* NAN_2_0 */ 532 default: 533 ALOGI("Unknown TLV type skipped"); 534 break; 535 } 536 remainingLen -= readLen; 537 pInputTlv += readLen; 538 memset(&outputTlv, 0, sizeof(outputTlv)); 539 } 540 return WIFI_SUCCESS; 541 } 542 543 int NanCommand::getNanDiscEngEvent(NanDiscEngEventInd *event) 544 { 545 if (event == NULL || mNanVendorEvent == NULL) { 546 ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p", 547 __func__, event, mNanVendorEvent); 548 return WIFI_ERROR_INVALID_ARGS; 549 } 550 551 pNanEventIndMsg pRsp = (pNanEventIndMsg)mNanVendorEvent; 552 event->header.handle = pRsp->fwHeader.handle; 553 event->header.transaction_id = pRsp->fwHeader.transactionId; 554 #ifndef NAN_2_0 555 event->event_id = (NanEventId)pRsp->eventIndParams.eventId; 556 #endif /* NAN_2_0 */ 557 memset(&event->data, 0, sizeof(event->data)); 558 559 u8 *pInputTlv = pRsp->ptlv; 560 NanTlv outputTlv; 561 u16 readLen = 0; 562 #ifndef NAN_2_0 563 int remainingLen = (mNanDataLen - \ 564 (sizeof(NanMsgHeader) + sizeof(NanEventIndParams))); 565 #else /* NAN_2_0 */ 566 int remainingLen = (mNanDataLen - \ 567 (sizeof(NanMsgHeader))); 568 #endif /* NAN_2_0 */ 569 570 //Has Self-STA Mac TLV 571 if (remainingLen <= 0) { 572 ALOGI("%s: No TLV's present",__func__); 573 return WIFI_SUCCESS; 574 } 575 576 ALOGI("%s: TLV remaining Len:%d event_id:%d",__func__, 577 remainingLen, event->event_id); 578 while ((remainingLen > 0) && 579 (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv)))) { 580 ALOGI("%s: Remaining Len:%d readLen:%d type:%d length:%d", 581 __func__, remainingLen, readLen, outputTlv.type, 582 outputTlv.length); 583 #ifdef NAN_2_0 584 event->event_id = (NanEventId)outputTlv.type; 585 #endif /* NAN_2_0 */ 586 //Here we should check on the event_id 587 switch (event->event_id) { 588 case NAN_EVENT_ID_STA_MAC_ADDR: 589 if (outputTlv.length > NAN_MAC_ADDR_LEN) { 590 ALOGI("%s: Reading only first %d bytes of TLV", 591 __func__, NAN_MAC_ADDR_LEN); 592 outputTlv.length = NAN_MAC_ADDR_LEN; 593 } 594 memcpy(event->data.mac_addr.addr, outputTlv.value, 595 outputTlv.length); 596 break; 597 case NAN_EVENT_ID_STARTED_CLUSTER: 598 case NAN_EVENT_ID_JOINED_CLUSTER: 599 if (outputTlv.length > NAN_MAC_ADDR_LEN) { 600 ALOGI("%s: Reading only first %d bytes of TLV", 601 __func__, NAN_MAC_ADDR_LEN); 602 outputTlv.length = NAN_MAC_ADDR_LEN; 603 } 604 memcpy(event->data.cluster.addr, outputTlv.value, 605 outputTlv.length); 606 break; 607 default: 608 ALOGI("Unhandled eventId:%d", event->event_id); 609 break; 610 } 611 remainingLen -= readLen; 612 pInputTlv += readLen; 613 memset(&outputTlv,0, sizeof(outputTlv)); 614 } 615 return WIFI_SUCCESS; 616 } 617 618 int NanCommand::getNanDisabled(NanDisabledInd *event) 619 { 620 if (event == NULL || mNanVendorEvent == NULL) { 621 ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p", 622 __func__, event, mNanVendorEvent); 623 return WIFI_ERROR_INVALID_ARGS; 624 } 625 626 pNanDisableIndMsg pRsp = (pNanDisableIndMsg)mNanVendorEvent; 627 event->header.handle = pRsp->fwHeader.handle; 628 event->header.transaction_id = pRsp->fwHeader.transactionId; 629 event->reason = (NanStatusType)pRsp->reason; 630 return WIFI_SUCCESS; 631 632 } 633 634 int NanCommand::getNanTca(NanTCAInd *event) 635 { 636 if (event == NULL || mNanVendorEvent == NULL) { 637 ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p", 638 __func__, event, mNanVendorEvent); 639 return WIFI_ERROR_INVALID_ARGS; 640 } 641 642 pNanTcaIndMsg pRsp = (pNanTcaIndMsg)mNanVendorEvent; 643 event->header.handle = pRsp->fwHeader.handle; 644 event->header.transaction_id = pRsp->fwHeader.transactionId; 645 memset(&event->data, 0, sizeof(event->data)); 646 #ifndef NAN_2_0 647 event->tca_id = (NanTcaId)pRsp->tcaIndParams.tcaId; 648 #else /* NAN_2_0 */ 649 event->tca_id = (NanTcaId)0; 650 #endif /* NAN_2_0 */ 651 652 u8 *pInputTlv = pRsp->ptlv; 653 NanTlv outputTlv; 654 u16 readLen = 0; 655 #ifndef NAN_2_0 656 int remainingLen = (mNanDataLen - \ 657 (sizeof(NanMsgHeader) + sizeof(NanTcaIndParams))); 658 #else 659 int remainingLen = (mNanDataLen - \ 660 (sizeof(NanMsgHeader))); 661 #endif 662 663 //Has NAN_TCA_ID_CLUSTER_SIZE 664 if (remainingLen <= 0) { 665 ALOGI("%s: No TLV's present",__func__); 666 return WIFI_SUCCESS; 667 } 668 669 ALOGI("%s: TLV remaining Len:%d tca_id:%d",__func__, 670 remainingLen, event->tca_id); 671 while ((remainingLen > 0) && 672 (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv)))) { 673 ALOGI("%s: Remaining Len:%d readLen:%d type:%d length:%d", 674 __func__, remainingLen, readLen, outputTlv.type, 675 outputTlv.length); 676 //Here we should check on the event_id 677 switch (event->tca_id) { 678 case NAN_TCA_ID_CLUSTER_SIZE: 679 #ifndef NAN_2_0 680 if (outputTlv.length > sizeof(event->data.cluster.cluster_size)) { 681 outputTlv.length = sizeof(event->data.cluster.cluster_size); 682 } 683 memcpy(&(event->data.cluster.cluster_size), outputTlv.value, 684 outputTlv.length); 685 #else /* NAN_2_0 */ 686 if (outputTlv.length != 2 * sizeof(u32)) { 687 ALOGE("%s: Wrong length %d in Tca Indication expecting %d bytes", 688 __func__, outputTlv.length, 2 * sizeof(u32)); 689 break; 690 } 691 event->rising_direction_evt_flag = outputTlv.value[0] & 0x01; 692 event->falling_direction_evt_flag = (outputTlv.value[0] & 0x02) >> 1; 693 memcpy(&(event->data.cluster.cluster_size), &outputTlv.value[4], 694 sizeof(event->data.cluster.cluster_size)); 695 #endif /* NAN_2_0 */ 696 break; 697 default: 698 ALOGI("Unhandled eventId:%d", event->tca_id); 699 break; 700 } 701 remainingLen -= readLen; 702 pInputTlv += readLen; 703 memset(&outputTlv,0, sizeof(outputTlv)); 704 } 705 return WIFI_SUCCESS; 706 } 707 708 int NanCommand::getNanBeaconSdfPayload(NanBeaconSdfPayloadInd *event) 709 { 710 if (event == NULL || mNanVendorEvent == NULL) { 711 ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p", 712 __func__, event, mNanVendorEvent); 713 return WIFI_ERROR_INVALID_ARGS; 714 } 715 716 #ifdef NAN_2_0 717 pNanBeaconSdfPayloadIndMsg pRsp = (pNanBeaconSdfPayloadIndMsg)mNanVendorEvent; 718 event->header.handle = pRsp->fwHeader.handle; 719 event->header.transaction_id = pRsp->fwHeader.transactionId; 720 memset(&event->data, 0, sizeof(event->data)); 721 722 u8 *pInputTlv = pRsp->ptlv; 723 NanTlv outputTlv; 724 u16 readLen = 0; 725 int remainingLen = (mNanDataLen - \ 726 (sizeof(NanMsgHeader))); 727 728 //Has Mac address 729 if (remainingLen <= 0) { 730 ALOGI("%s: No TLV's present",__func__); 731 return WIFI_SUCCESS; 732 } 733 734 ALOGI("%s: TLV remaining Len:%d",__func__, remainingLen); 735 while ((remainingLen > 0) && 736 (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv)))) { 737 ALOGI("%s: Remaining Len:%d readLen:%d type:%d length:%d", 738 __func__, remainingLen, readLen, outputTlv.type, 739 outputTlv.length); 740 //Here we should check on the event_id 741 switch (outputTlv.type) { 742 case NAN_TLV_TYPE_SELF_MAC_ADDR: 743 if (outputTlv.length > sizeof(event->addr)) { 744 outputTlv.length = sizeof(event->addr); 745 } 746 memcpy(event->addr, outputTlv.value, 747 outputTlv.length); 748 break; 749 750 case NAN_TLV_TYPE_VENDOR_SPECIFIC_ATTRIBUTE_RECEIVE: 751 { 752 NanReceiveVendorSpecificAttribute* recvVsaattr = &event->vsa; 753 if (outputTlv.length < sizeof(u32)) { 754 ALOGE("NAN_TLV_TYPE_VENDOR_SPECIFIC_ATTRIBUTE_RECEIVE" 755 "Incorrect length:%d", outputTlv.length); 756 break; 757 } 758 event->is_vsa_received = 1; 759 recvVsaattr->vsa_received_on = (outputTlv.value[0] >> 1) & 0x07; 760 memcpy(&recvVsaattr->vendor_oui, &outputTlv.value[1], 761 3); 762 recvVsaattr->attr_len = outputTlv.length - 4; 763 if (recvVsaattr->attr_len > NAN_MAX_VSA_DATA_LEN) { 764 recvVsaattr->attr_len = NAN_MAX_VSA_DATA_LEN; 765 } 766 if (recvVsaattr->attr_len) { 767 memcpy(recvVsaattr->vsa, &outputTlv.value[4], 768 recvVsaattr->attr_len); 769 } 770 break; 771 } 772 773 case NAN_TLV_TYPE_BEACON_SDF_PAYLOAD_RECEIVE: 774 event->is_beacon_sdf_payload_received = 1; 775 event->data.frame_len = outputTlv.length; 776 if (event->data.frame_len > NAN_MAX_VSA_DATA_LEN) { 777 event->data.frame_len = NAN_MAX_VSA_DATA_LEN; 778 } 779 memcpy(&event->data.frame_data, &outputTlv.value[0], 780 event->data.frame_len); 781 break; 782 783 default: 784 ALOGI("Unhandled TLV Type:%d", outputTlv.type); 785 break; 786 } 787 remainingLen -= readLen; 788 pInputTlv += readLen; 789 memset(&outputTlv,0, sizeof(outputTlv)); 790 } 791 return WIFI_SUCCESS; 792 #else /* NAN_2_0 */ 793 return WIFI_ERROR_INVALID_ARGS; 794 #endif /* NAN_2_0 */ 795 } 796 797 void NanCommand::getNanReceivePostConnectivityCapabilityVal( 798 const u8 *pInValue, 799 NanReceivePostConnectivityCapability *pRxCapab) 800 { 801 if (pInValue && pRxCapab) { 802 pRxCapab->is_mesh_supported = (pInValue[0] && (0x01 << 5)); 803 pRxCapab->is_ibss_supported = (pInValue[0] && (0x01 << 4)); 804 pRxCapab->wlan_infra_field = (pInValue[0] && (0x01 << 3)); 805 pRxCapab->is_tdls_supported = (pInValue[0] && (0x01 << 2)); 806 pRxCapab->is_wfds_supported = (pInValue[0] && (0x01 << 1)); 807 pRxCapab->is_wfd_supported = pInValue[0] && 0x01; 808 } 809 } 810 811 int NanCommand::getNanReceivePostDiscoveryVal(const u8 *pInValue, 812 u32 length, 813 NanReceivePostDiscovery *pRxDisc) 814 { 815 int ret = 0; 816 817 #ifdef NAN_2_0 818 if (length <= 8 || pInValue == NULL) { 819 ALOGE("%s: Invalid Arg TLV Len %d < 4", 820 __func__, length); 821 return -1; 822 } 823 824 pRxDisc->type = (NanConnectionType) pInValue[0]; 825 pRxDisc->role = (NanDeviceRole) pInValue[1]; 826 pRxDisc->duration = (NanAvailDuration) (pInValue[2] & 0x03); 827 pRxDisc->mapid = ((pInValue[2] >> 2) & 0x0F); 828 memcpy(&pRxDisc->avail_interval_bitmap, 829 &pInValue[4], 830 sizeof(pRxDisc->avail_interval_bitmap)); 831 832 u8 *pInputTlv = (u8 *)&pInValue[8]; 833 NanTlv outputTlv; 834 u16 readLen = 0; 835 int remainingLen = (length - 8); 836 837 //Has Mac address 838 if (remainingLen <= 0) { 839 ALOGE("%s: No TLV's present",__func__); 840 return -1; 841 } 842 843 ALOGI("%s: TLV remaining Len:%d",__func__, remainingLen); 844 while ((remainingLen > 0) && 845 (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv)))) { 846 ALOGI("%s: Remaining Len:%d readLen:%d type:%d length:%d", 847 __func__, remainingLen, readLen, outputTlv.type, 848 outputTlv.length); 849 switch (outputTlv.type) { 850 case NAN_TLV_TYPE_MAC_ADDRESS: 851 if (outputTlv.length > sizeof(pRxDisc->addr)) { 852 outputTlv.length = sizeof(pRxDisc->addr); 853 } 854 memcpy(pRxDisc->addr, outputTlv.value, outputTlv.length); 855 break; 856 case NAN_TLV_TYPE_WLAN_MESH_ID: 857 if (outputTlv.length > sizeof(pRxDisc->mesh_id)) { 858 outputTlv.length = sizeof(pRxDisc->mesh_id); 859 } 860 memcpy(pRxDisc->mesh_id, outputTlv.value, outputTlv.length); 861 pRxDisc->mesh_id_len = outputTlv.length; 862 break; 863 case NAN_TLV_TYPE_WLAN_INFRASTRUCTURE_SSID: 864 if (outputTlv.length > sizeof(pRxDisc->infrastructure_ssid_val)) { 865 outputTlv.length = sizeof(pRxDisc->infrastructure_ssid_val); 866 } 867 memcpy(pRxDisc->infrastructure_ssid_val, outputTlv.value, 868 outputTlv.length); 869 pRxDisc->infrastructure_ssid_len = outputTlv.length; 870 default: 871 ALOGI("Unhandled TLV Type:%d", outputTlv.type); 872 break; 873 } 874 remainingLen -= readLen; 875 pInputTlv += readLen; 876 memset(&outputTlv,0, sizeof(outputTlv)); 877 } 878 #endif /* NAN_2_0 */ 879 return ret; 880 } 881 882 int NanCommand::getNanFurtherAvailabilityMap(const u8 *pInValue, 883 u32 length, 884 NanFurtherAvailabilityMap *pFam) 885 { 886 #ifdef NAN_2_0 887 int idx = 0; 888 889 if ((length == 0) || pInValue == NULL) { 890 ALOGE("%s: Invalid Arg TLV Len %d or pInValue NULL", 891 __func__, length); 892 return -1; 893 } 894 895 pFam->numchans = pInValue[0]; 896 if (pFam->numchans > NAN_MAX_FAM_CHANNELS) { 897 ALOGE("%s: Unable to accommodate numchans %d", 898 __func__, pFam->numchans); 899 return -1; 900 } 901 for (idx = 0; idx < pFam->numchans; idx++) { 902 pNanFurtherAvailabilityChan pRsp = \ 903 (pNanFurtherAvailabilityChan)(pInValue[1] + \ 904 (idx * sizeof(NanFurtherAvailabilityChan))); 905 NanFurtherAvailabilityChannel *pFamChan = &pFam->famchan[idx]; 906 907 pFamChan->entry_control = \ 908 (NanAvailDuration)(pRsp->entryCtrl.availIntDuration); 909 pFamChan->mapid = pRsp->entryCtrl.mapId; 910 pFamChan->class_val = pRsp->opClass; 911 pFamChan->channel = pRsp->channel; 912 memcpy(&pFamChan->avail_interval_bitmap, 913 &pRsp->availIntBitmap, 914 sizeof(pFamChan->avail_interval_bitmap)); 915 } 916 #endif /* NAN_2_0*/ 917 return 0; 918 } 919 920 int NanCommand::getNanStaParameter(NanStaParameter *pRsp) 921 { 922 int ret = WIFI_ERROR_NONE; 923 int res = -1; 924 925 /* 926 Construct NL message to get the sync stats parameter 927 which has all the parameter required by staparameter. 928 */ 929 NanStatsRequest syncStats; 930 memset(&syncStats, 0, sizeof(syncStats)); 931 syncStats.header.handle = 0x0; 932 syncStats.header.transaction_id = 0x1234; 933 syncStats.stats_id = NAN_STATS_ID_DE_TIMING_SYNC; 934 syncStats.clear = 0; 935 936 mStaParam = pRsp; 937 ret = putNanStats(&syncStats); 938 if (ret != 0) { 939 ALOGE("%s: putNanStats Error:%d",__func__, ret); 940 goto cleanup; 941 } 942 ret = requestEvent(); 943 if (ret != 0) { 944 ALOGE("%s: requestEvent Error:%d",__func__, ret); 945 goto cleanup; 946 } 947 948 struct timespec abstime; 949 abstime.tv_sec = 4; 950 abstime.tv_nsec = 0; 951 res = mCondition.wait(abstime); 952 if (res == ETIMEDOUT) 953 { 954 ALOGE("%s: Time out happened.", __func__); 955 ret = WIFI_ERROR_TIMED_OUT; 956 goto cleanup; 957 } 958 ALOGI("%s: NanStaparameter Master_pref:%x," \ 959 " Random_factor:%x, hop_count:%x " \ 960 " beacon_transmit_time:%d", __func__, 961 pRsp->master_pref, pRsp->random_factor, 962 pRsp->hop_count, pRsp->beacon_transmit_time); 963 cleanup: 964 mStaParam = NULL; 965 return (int)ret; 966 } 967