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