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