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