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 if (idx < 0 || idx >= NAN_MAX_POSTDISCOVERY_LEN) {
350 ALOGE("NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_RECEIVE"
351 " Incorrect index:%d >= %d", idx, NAN_MAX_POSTDISCOVERY_LEN);
352 break;
353 }
354 ret = getNanReceivePostDiscoveryVal(outputTlv.value,
355 outputTlv.length,
356 &event->discovery_attr[idx]);
357 if (ret == 0) {
358 event->num_rx_discovery_attr++;
359 } else {
360 ALOGE("NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_RECEIVE"
361 "Incorrect");
362 }
363 break;
364 case NAN_TLV_TYPE_FURTHER_AVAILABILITY_MAP:
365 /* Populate further availability bitmap from
366 received TLV */
367 ret = getNanFurtherAvailabilityMap(outputTlv.value,
368 outputTlv.length,
369 &event->num_chans,
370 &event->famchan[0]);
371 if (ret < 0)
372 ALOGE("NAN_TLV_TYPE_FURTHER_AVAILABILITY_MAP"
373 "Incorrect");
374 break;
375 case NAN_TLV_TYPE_CLUSTER_ATTRIBUTE:
376 if (outputTlv.length > sizeof(event->cluster_attribute)) {
377 outputTlv.length = sizeof(event->cluster_attribute);
378 }
379 memcpy(event->cluster_attribute,
380 outputTlv.value, outputTlv.length);
381 event->cluster_attribute_len = outputTlv.length;
382 break;
383 case NAN_TLV_TYPE_NAN_CSID:
384 if (outputTlv.length > sizeof(event->peer_cipher_type)) {
385 outputTlv.length = sizeof(event->peer_cipher_type);
386 }
387 memcpy(&event->peer_cipher_type, outputTlv.value,
388 outputTlv.length);
389 break;
390 case NAN_TLV_TYPE_NAN_SCID:
391 if (outputTlv.length > sizeof(event->scid)) {
392 outputTlv.length = sizeof(event->scid);
393 }
394 event->scid_len = outputTlv.length;
395 memcpy(event->scid, outputTlv.value, outputTlv.length);
396 break;
397 case NAN_TLV_TYPE_SDEA_CTRL_PARAMS:
398 if (outputTlv.length != sizeof(u32)) {
399 ALOGE("NAN_TLV_TYPE_SDEA_CTRL_PARAMS"
400 "Incorrect size:%d expecting %zu", outputTlv.length,
401 sizeof(u32));
402 break;
403 }
404 getNanReceiveSdeaCtrlParams(outputTlv.value,
405 &event->peer_sdea_params);
406 break;
407 case NAN_TLV_TYPE_NAN20_RANGING_RESULT:
408 if (outputTlv.length > sizeof(event->range_info)) {
409 outputTlv.length = sizeof(event->range_info);
410 }
411 memcpy(&event->range_info, outputTlv.value, outputTlv.length);
412 break;
413 case NAN_TLV_TYPE_SDEA_SERVICE_SPECIFIC_INFO:
414 if (outputTlv.length > NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN) {
415 outputTlv.length = NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN;
416 }
417 event->sdea_service_specific_info_len = outputTlv.length;
418 memcpy(event->sdea_service_specific_info, outputTlv.value,
419 outputTlv.length);
420 break;
421 default:
422 ALOGV("Unknown TLV type skipped");
423 break;
424 }
425 remainingLen -= readLen;
426 pInputTlv += readLen;
427 memset(&outputTlv, 0, sizeof(outputTlv));
428 }
429 return WIFI_SUCCESS;
430 }
431
getNanMatchExpired(NanMatchExpiredInd * event)432 int NanCommand::getNanMatchExpired(NanMatchExpiredInd *event)
433 {
434 if (event == NULL || mNanVendorEvent == NULL) {
435 ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
436 __func__, event, mNanVendorEvent);
437 return WIFI_ERROR_INVALID_ARGS;
438 }
439
440 pNanMatchExpiredIndMsg pRsp = (pNanMatchExpiredIndMsg)mNanVendorEvent;
441 event->publish_subscribe_id = pRsp->fwHeader.handle;
442 event->requestor_instance_id = pRsp->matchExpiredIndParams.matchHandle;
443 return WIFI_SUCCESS;
444 }
445
getNanSubscribeTerminated(NanSubscribeTerminatedInd * event)446 int NanCommand::getNanSubscribeTerminated(NanSubscribeTerminatedInd *event)
447 {
448 if (event == NULL || mNanVendorEvent == NULL) {
449 ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
450 __func__, event, mNanVendorEvent);
451 return WIFI_ERROR_INVALID_ARGS;
452 }
453
454 pNanSubscribeTerminatedIndMsg pRsp = (pNanSubscribeTerminatedIndMsg)mNanVendorEvent;
455 event->subscribe_id = pRsp->fwHeader.handle;
456 NanErrorTranslation((NanInternalStatusType)pRsp->reason, 0,
457 (void*)event, false);
458 return WIFI_SUCCESS;
459 }
460
getNanFollowup(NanFollowupInd * event)461 int NanCommand::getNanFollowup(NanFollowupInd *event)
462 {
463 if (event == NULL || mNanVendorEvent == NULL) {
464 ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
465 __func__, event, mNanVendorEvent);
466 return WIFI_ERROR_INVALID_ARGS;
467 }
468
469 pNanFollowupIndMsg pRsp = (pNanFollowupIndMsg)mNanVendorEvent;
470 event->publish_subscribe_id = pRsp->fwHeader.handle;
471 event->requestor_instance_id = pRsp->followupIndParams.matchHandle;
472 event->dw_or_faw = pRsp->followupIndParams.window;
473
474 u8 *pInputTlv = pRsp->ptlv;
475 NanTlv outputTlv;
476 u16 readLen = 0;
477 int remainingLen = (mNanDataLen - \
478 (sizeof(NanMsgHeader) + sizeof(NanFollowupIndParams)));
479
480 //Has service specific info and extended service specific info TLV
481 if (remainingLen <= 0) {
482 ALOGV("%s: No TLV's present",__func__);
483 return WIFI_SUCCESS;
484 }
485 ALOGV("%s: TLV remaining Len:%d",__func__, remainingLen);
486 while ((remainingLen > 0) &&
487 (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv)))) {
488 ALOGV("%s: Remaining Len:%d readLen:%d type:%d length:%d",
489 __func__, remainingLen, readLen, outputTlv.type,
490 outputTlv.length);
491 switch (outputTlv.type) {
492 case NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO:
493 case NAN_TLV_TYPE_EXT_SERVICE_SPECIFIC_INFO:
494 if (outputTlv.length > NAN_MAX_SERVICE_SPECIFIC_INFO_LEN) {
495 outputTlv.length = NAN_MAX_SERVICE_SPECIFIC_INFO_LEN;
496 }
497 event->service_specific_info_len = outputTlv.length;
498 memcpy(event->service_specific_info, outputTlv.value,
499 outputTlv.length);
500 break;
501 case NAN_TLV_TYPE_MAC_ADDRESS:
502 if (outputTlv.length > sizeof(event->addr)) {
503 outputTlv.length = sizeof(event->addr);
504 }
505 memcpy(event->addr, outputTlv.value, outputTlv.length);
506 break;
507 case NAN_TLV_TYPE_SDEA_SERVICE_SPECIFIC_INFO:
508 if (outputTlv.length > NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN) {
509 outputTlv.length = NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN;
510 }
511 event->sdea_service_specific_info_len = outputTlv.length;
512 memcpy(event->sdea_service_specific_info, outputTlv.value,
513 outputTlv.length);
514 break;
515 default:
516 ALOGV("Unknown TLV type skipped");
517 break;
518 }
519 remainingLen -= readLen;
520 pInputTlv += readLen;
521 memset(&outputTlv, 0, sizeof(outputTlv));
522 }
523 return WIFI_SUCCESS;
524 }
525
getNanDiscEngEvent(NanDiscEngEventInd * event)526 int NanCommand::getNanDiscEngEvent(NanDiscEngEventInd *event)
527 {
528 if (event == NULL || mNanVendorEvent == NULL) {
529 ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
530 __func__, event, mNanVendorEvent);
531 return WIFI_ERROR_INVALID_ARGS;
532 }
533
534 pNanEventIndMsg pRsp = (pNanEventIndMsg)mNanVendorEvent;
535 memset(&event->data, 0, sizeof(event->data));
536
537 u8 *pInputTlv = pRsp->ptlv;
538 NanTlv outputTlv;
539 u16 readLen = 0;
540 int remainingLen = (mNanDataLen - \
541 (sizeof(NanMsgHeader)));
542
543 //Has Self-STA Mac TLV
544 if (remainingLen <= 0) {
545 ALOGE("%s: No TLV's present",__func__);
546 return WIFI_SUCCESS;
547 }
548
549 ALOGV("%s: TLV remaining Len:%d",__func__, remainingLen);
550 while ((remainingLen > 0) &&
551 (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv)))) {
552 ALOGV("%s: Remaining Len:%d readLen:%d type:%d length:%d",
553 __func__, remainingLen, readLen, outputTlv.type,
554 outputTlv.length);
555 switch (outputTlv.type) {
556 case NAN_TLV_TYPE_EVENT_SELF_STATION_MAC_ADDRESS:
557 if (outputTlv.length > NAN_MAC_ADDR_LEN) {
558 ALOGV("%s: Reading only first %d bytes of TLV",
559 __func__, NAN_MAC_ADDR_LEN);
560 outputTlv.length = NAN_MAC_ADDR_LEN;
561 }
562 memcpy(event->data.mac_addr.addr, outputTlv.value,
563 outputTlv.length);
564 event->event_type = NAN_EVENT_ID_DISC_MAC_ADDR;
565 break;
566 case NAN_TLV_TYPE_EVENT_STARTED_CLUSTER:
567 if (outputTlv.length > NAN_MAC_ADDR_LEN) {
568 ALOGV("%s: Reading only first %d bytes of TLV",
569 __func__, NAN_MAC_ADDR_LEN);
570 outputTlv.length = NAN_MAC_ADDR_LEN;
571 }
572 memcpy(event->data.cluster.addr, outputTlv.value,
573 outputTlv.length);
574 event->event_type = NAN_EVENT_ID_STARTED_CLUSTER;
575 break;
576 case NAN_TLV_TYPE_EVENT_JOINED_CLUSTER:
577 if (outputTlv.length > NAN_MAC_ADDR_LEN) {
578 ALOGV("%s: Reading only first %d bytes of TLV",
579 __func__, NAN_MAC_ADDR_LEN);
580 outputTlv.length = NAN_MAC_ADDR_LEN;
581 }
582 memcpy(event->data.cluster.addr, outputTlv.value,
583 outputTlv.length);
584 event->event_type = NAN_EVENT_ID_JOINED_CLUSTER;
585 break;
586 default:
587 ALOGV("Unhandled TLV type:%d", outputTlv.type);
588 break;
589 }
590 remainingLen -= readLen;
591 pInputTlv += readLen;
592 memset(&outputTlv,0, sizeof(outputTlv));
593 }
594 return WIFI_SUCCESS;
595 }
596
getNanDisabled(NanDisabledInd * event)597 int NanCommand::getNanDisabled(NanDisabledInd *event)
598 {
599 if (event == NULL || mNanVendorEvent == NULL) {
600 ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
601 __func__, event, mNanVendorEvent);
602 return WIFI_ERROR_INVALID_ARGS;
603 }
604
605 pNanDisableIndMsg pRsp = (pNanDisableIndMsg)mNanVendorEvent;
606 NanErrorTranslation((NanInternalStatusType)pRsp->reason, 0,
607 (void*)event, false);
608 return WIFI_SUCCESS;
609
610 }
611
getNanTca(NanTCAInd * event)612 int NanCommand::getNanTca(NanTCAInd *event)
613 {
614 if (event == NULL || mNanVendorEvent == NULL) {
615 ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
616 __func__, event, mNanVendorEvent);
617 return WIFI_ERROR_INVALID_ARGS;
618 }
619
620 pNanTcaIndMsg pRsp = (pNanTcaIndMsg)mNanVendorEvent;
621 memset(&event->data, 0, sizeof(event->data));
622
623 u8 *pInputTlv = pRsp->ptlv;
624 NanTlv outputTlv;
625 u16 readLen = 0;
626
627 int remainingLen = (mNanDataLen - \
628 (sizeof(NanMsgHeader)));
629
630 //Has NAN_TCA_ID_CLUSTER_SIZE
631 if (remainingLen <= 0) {
632 ALOGE("%s: No TLV's present",__func__);
633 return WIFI_SUCCESS;
634 }
635
636 ALOGV("%s: TLV remaining Len:%d",__func__, remainingLen);
637 while ((remainingLen > 0) &&
638 (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv)))) {
639 ALOGV("%s: Remaining Len:%d readLen:%d type:%d length:%d",
640 __func__, remainingLen, readLen, outputTlv.type,
641 outputTlv.length);
642 switch (outputTlv.type) {
643 case NAN_TLV_TYPE_CLUSTER_SIZE_RSP:
644 if (outputTlv.length != 2 * sizeof(u32)) {
645 ALOGE("%s: Wrong length %d in Tca Indication expecting %zu bytes",
646 __func__, outputTlv.length, 2 * sizeof(u32));
647 break;
648 }
649 event->rising_direction_evt_flag = outputTlv.value[0] & 0x01;
650 event->falling_direction_evt_flag = (outputTlv.value[0] & 0x02) >> 1;
651 memcpy(&(event->data.cluster.cluster_size), &outputTlv.value[4],
652 sizeof(event->data.cluster.cluster_size));
653 event->tca_type = NAN_TCA_ID_CLUSTER_SIZE;
654 break;
655 default:
656 ALOGV("Unhandled TLV type:%d", outputTlv.type);
657 break;
658 }
659 remainingLen -= readLen;
660 pInputTlv += readLen;
661 memset(&outputTlv,0, sizeof(outputTlv));
662 }
663 return WIFI_SUCCESS;
664 }
665
getNanBeaconSdfPayload(NanBeaconSdfPayloadInd * event)666 int NanCommand::getNanBeaconSdfPayload(NanBeaconSdfPayloadInd *event)
667 {
668 if (event == NULL || mNanVendorEvent == NULL) {
669 ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
670 __func__, event, mNanVendorEvent);
671 return WIFI_ERROR_INVALID_ARGS;
672 }
673
674 pNanBeaconSdfPayloadIndMsg pRsp = (pNanBeaconSdfPayloadIndMsg)mNanVendorEvent;
675 memset(&event->data, 0, sizeof(event->data));
676
677 u8 *pInputTlv = pRsp->ptlv;
678 NanTlv outputTlv;
679 u16 readLen = 0;
680 int remainingLen = (mNanDataLen - \
681 (sizeof(NanMsgHeader)));
682
683 //Has Mac address
684 if (remainingLen <= 0) {
685 ALOGV("%s: No TLV's present",__func__);
686 return WIFI_SUCCESS;
687 }
688
689 ALOGV("%s: TLV remaining Len:%d",__func__, remainingLen);
690 while ((remainingLen > 0) &&
691 (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv)))) {
692 ALOGV("%s: Remaining Len:%d readLen:%d type:%d length:%d",
693 __func__, remainingLen, readLen, outputTlv.type,
694 outputTlv.length);
695 switch (outputTlv.type) {
696 case NAN_TLV_TYPE_MAC_ADDRESS:
697 if (outputTlv.length > sizeof(event->addr)) {
698 outputTlv.length = sizeof(event->addr);
699 }
700 memcpy(event->addr, outputTlv.value,
701 outputTlv.length);
702 break;
703
704 case NAN_TLV_TYPE_VENDOR_SPECIFIC_ATTRIBUTE_RECEIVE:
705 {
706 NanReceiveVendorSpecificAttribute* recvVsaattr = &event->vsa;
707 if (outputTlv.length < sizeof(u32)) {
708 ALOGE("NAN_TLV_TYPE_VENDOR_SPECIFIC_ATTRIBUTE_RECEIVE"
709 "Incorrect length:%d", outputTlv.length);
710 break;
711 }
712 event->is_vsa_received = 1;
713 recvVsaattr->vsa_received_on = (outputTlv.value[0] >> 1) & 0x07;
714 memcpy(&recvVsaattr->vendor_oui, &outputTlv.value[1],
715 3);
716 recvVsaattr->attr_len = outputTlv.length - 4;
717 if (recvVsaattr->attr_len > NAN_MAX_VSA_DATA_LEN) {
718 recvVsaattr->attr_len = NAN_MAX_VSA_DATA_LEN;
719 }
720 if (recvVsaattr->attr_len) {
721 memcpy(recvVsaattr->vsa, &outputTlv.value[4],
722 recvVsaattr->attr_len);
723 }
724 break;
725 }
726
727 case NAN_TLV_TYPE_BEACON_SDF_PAYLOAD_RECEIVE:
728 event->is_beacon_sdf_payload_received = 1;
729 event->data.frame_len = outputTlv.length;
730 if (event->data.frame_len > NAN_MAX_FRAME_DATA_LEN) {
731 event->data.frame_len = NAN_MAX_FRAME_DATA_LEN;
732 }
733 memcpy(&event->data.frame_data, &outputTlv.value[0],
734 event->data.frame_len);
735 break;
736
737 default:
738 ALOGV("Unhandled TLV Type:%d", outputTlv.type);
739 break;
740 }
741 remainingLen -= readLen;
742 pInputTlv += readLen;
743 memset(&outputTlv,0, sizeof(outputTlv));
744 }
745 return WIFI_SUCCESS;
746 }
747
getNanReceivePostConnectivityCapabilityVal(const u8 * pInValue,NanReceivePostConnectivityCapability * pRxCapab)748 void NanCommand::getNanReceivePostConnectivityCapabilityVal(
749 const u8 *pInValue,
750 NanReceivePostConnectivityCapability *pRxCapab)
751 {
752 if (pInValue && pRxCapab) {
753 pRxCapab->is_mesh_supported = (pInValue[0] & (0x01 << 5));
754 pRxCapab->is_ibss_supported = (pInValue[0] & (0x01 << 4));
755 pRxCapab->wlan_infra_field = (pInValue[0] & (0x01 << 3));
756 pRxCapab->is_tdls_supported = (pInValue[0] & (0x01 << 2));
757 pRxCapab->is_wfds_supported = (pInValue[0] & (0x01 << 1));
758 pRxCapab->is_wfd_supported = pInValue[0] & 0x01;
759 }
760 }
761
getNanReceiveSdeaCtrlParams(const u8 * pInValue,NanSdeaCtrlParams * pPeerSdeaParams)762 void NanCommand::getNanReceiveSdeaCtrlParams(const u8* pInValue,
763 NanSdeaCtrlParams *pPeerSdeaParams)
764 {
765 if (pInValue && pPeerSdeaParams) {
766 pPeerSdeaParams->security_cfg =
767 (NanDataPathSecurityCfgStatus)((pInValue[0] & BIT_6) ?
768 NAN_DP_CONFIG_SECURITY : NAN_DP_CONFIG_NO_SECURITY);
769 pPeerSdeaParams->ranging_state =
770 (NanRangingState)((pInValue[0] & BIT_7) ?
771 NAN_RANGING_ENABLE : NAN_RANGING_DISABLE);
772 #if 0
773 pPeerSdeaParams->enable_ranging_limit =
774 (NanRangingLimitState)((pInValue[0] & BIT_8) ?
775 NAN_RANGING_LIMIT_ENABLE : NAN_RANGING_LIMIT_DISABLE);
776 #endif
777 }
778 return;
779 }
780
getNanReceivePostDiscoveryVal(const u8 * pInValue,u32 length,NanReceivePostDiscovery * pRxDisc)781 int NanCommand::getNanReceivePostDiscoveryVal(const u8 *pInValue,
782 u32 length,
783 NanReceivePostDiscovery *pRxDisc)
784 {
785 int ret = 0;
786
787 if (length <= 8 || pInValue == NULL) {
788 ALOGE("%s: Invalid Arg TLV Len %d < 4",
789 __func__, length);
790 return -1;
791 }
792
793 pRxDisc->type = (NanConnectionType) pInValue[0];
794 pRxDisc->role = (NanDeviceRole) pInValue[1];
795 pRxDisc->duration = (NanAvailDuration) (pInValue[2] & 0x03);
796 pRxDisc->mapid = ((pInValue[2] >> 2) & 0x0F);
797 memcpy(&pRxDisc->avail_interval_bitmap,
798 &pInValue[4],
799 sizeof(pRxDisc->avail_interval_bitmap));
800
801 u8 *pInputTlv = (u8 *)&pInValue[8];
802 NanTlv outputTlv;
803 u16 readLen = 0;
804 int remainingLen = (length - 8);
805
806 //Has Mac address
807 if (remainingLen <= 0) {
808 ALOGE("%s: No TLV's present",__func__);
809 return -1;
810 }
811
812 ALOGV("%s: TLV remaining Len:%d",__func__, remainingLen);
813 while ((remainingLen > 0) &&
814 (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv)))) {
815 ALOGV("%s: Remaining Len:%d readLen:%d type:%d length:%d",
816 __func__, remainingLen, readLen, outputTlv.type,
817 outputTlv.length);
818 switch (outputTlv.type) {
819 case NAN_TLV_TYPE_MAC_ADDRESS:
820 if (outputTlv.length > sizeof(pRxDisc->addr)) {
821 outputTlv.length = sizeof(pRxDisc->addr);
822 }
823 memcpy(pRxDisc->addr, outputTlv.value, outputTlv.length);
824 break;
825 case NAN_TLV_TYPE_WLAN_MESH_ID:
826 if (outputTlv.length > sizeof(pRxDisc->mesh_id)) {
827 outputTlv.length = sizeof(pRxDisc->mesh_id);
828 }
829 memcpy(pRxDisc->mesh_id, outputTlv.value, outputTlv.length);
830 pRxDisc->mesh_id_len = outputTlv.length;
831 break;
832 case NAN_TLV_TYPE_WLAN_INFRA_SSID:
833 if (outputTlv.length > sizeof(pRxDisc->infrastructure_ssid_val)) {
834 outputTlv.length = sizeof(pRxDisc->infrastructure_ssid_val);
835 }
836 memcpy(pRxDisc->infrastructure_ssid_val, outputTlv.value,
837 outputTlv.length);
838 pRxDisc->infrastructure_ssid_len = outputTlv.length;
839 default:
840 ALOGV("Unhandled TLV Type:%d", outputTlv.type);
841 break;
842 }
843 remainingLen -= readLen;
844 pInputTlv += readLen;
845 memset(&outputTlv,0, sizeof(outputTlv));
846 }
847 return ret;
848 }
849
getNanFurtherAvailabilityMap(const u8 * pInValue,u32 length,u8 * num_chans,NanFurtherAvailabilityChannel * pFac)850 int NanCommand::getNanFurtherAvailabilityMap(const u8 *pInValue,
851 u32 length,
852 u8 *num_chans,
853 NanFurtherAvailabilityChannel *pFac)
854 {
855 int idx = 0;
856
857 if ((length == 0) || pInValue == NULL) {
858 ALOGE("%s: Invalid Arg TLV Len %d or pInValue NULL",
859 __func__, length);
860 return -1;
861 }
862
863 *num_chans = pInValue[0];
864 if (*num_chans > NAN_MAX_FAM_CHANNELS) {
865 ALOGE("%s: Unable to accommodate numchans %d",
866 __func__, *num_chans);
867 return -1;
868 }
869
870 if (length < (sizeof(u8) +
871 (*num_chans * sizeof(NanFurtherAvailabilityChan)))) {
872 ALOGE("%s: Invalid TLV Length", __func__);
873 return -1;
874 }
875
876 for (idx = 0; idx < *num_chans; idx++) {
877 pNanFurtherAvailabilityChan pRsp = \
878 (pNanFurtherAvailabilityChan)((u8 *)&pInValue[1] + \
879 (idx * sizeof(NanFurtherAvailabilityChan)));
880
881 pFac->entry_control = \
882 (NanAvailDuration)(pRsp->entryCtrl.availIntDuration);
883 pFac->mapid = pRsp->entryCtrl.mapId;
884 pFac->class_val = pRsp->opClass;
885 pFac->channel = pRsp->channel;
886 memcpy(&pFac->avail_interval_bitmap,
887 &pRsp->availIntBitmap,
888 sizeof(pFac->avail_interval_bitmap));
889 pFac++;
890 }
891 return 0;
892 }
893
getNanStaParameter(wifi_interface_handle iface,NanStaParameter * pRsp)894 wifi_error NanCommand::getNanStaParameter(wifi_interface_handle iface,
895 NanStaParameter *pRsp)
896 {
897 wifi_error ret = WIFI_ERROR_NONE;
898 transaction_id id = 1;
899 interface_info *ifaceInfo = getIfaceInfo(iface);
900
901 ret = create();
902 if (ret != WIFI_SUCCESS)
903 goto cleanup;
904
905 /* Set the interface Id of the message. */
906 ret = set_iface_id(ifaceInfo->name);
907 if (ret != WIFI_SUCCESS)
908 goto cleanup;
909
910 /*
911 Construct NL message to get the sync stats parameter
912 which has all the parameter required by staparameter.
913 */
914 NanStatsRequest syncStats;
915 memset(&syncStats, 0, sizeof(syncStats));
916 syncStats.stats_type = NAN_STATS_ID_DE_TIMING_SYNC;
917 syncStats.clear = 0;
918
919 mStaParam = pRsp;
920 ret = putNanStats(id, &syncStats);
921 if (ret != WIFI_SUCCESS) {
922 ALOGE("%s: putNanStats Error:%d",__func__, ret);
923 goto cleanup;
924 }
925 ret = requestEvent();
926 if (ret != 0) {
927 ALOGE("%s: requestEvent Error:%d",__func__, ret);
928 goto cleanup;
929 }
930
931 struct timespec abstime;
932 abstime.tv_sec = 4;
933 abstime.tv_nsec = 0;
934 ret = mCondition.wait(abstime);
935 if (ret == WIFI_ERROR_TIMED_OUT)
936 {
937 ALOGE("%s: Time out happened.", __func__);
938 goto cleanup;
939 }
940 ALOGV("%s: NanStaparameter Master_pref:%x," \
941 " Random_factor:%x, hop_count:%x " \
942 " beacon_transmit_time:%d" \
943 " ndp_channel_freq:%d", __func__,
944 pRsp->master_pref, pRsp->random_factor,
945 pRsp->hop_count, pRsp->beacon_transmit_time, pRsp->ndp_channel_freq);
946 cleanup:
947 mStaParam = NULL;
948 return ret;
949 }
950
getNanTransmitFollowupInd(NanTransmitFollowupInd * event)951 int NanCommand::getNanTransmitFollowupInd(NanTransmitFollowupInd *event)
952 {
953 if (event == NULL || mNanVendorEvent == NULL) {
954 ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
955 __func__, event, mNanVendorEvent);
956 return WIFI_ERROR_INVALID_ARGS;
957 }
958
959 pNanSelfTransmitFollowupIndMsg pRsp = (pNanSelfTransmitFollowupIndMsg)mNanVendorEvent;
960 event->id = pRsp->fwHeader.transactionId;
961 NanErrorTranslation((NanInternalStatusType)pRsp->reason, 0,
962 (void*)event, false);
963 return WIFI_SUCCESS;
964 }
965
966 //Function which calls the necessaryIndication callback
967 //based on the indication type
handleNdpIndication(u32 ndpCmdType,struct nlattr ** tb_vendor)968 int NanCommand::handleNdpIndication(u32 ndpCmdType, struct nlattr **tb_vendor)
969 {
970 //Based on the message_id in the header determine the Indication type
971 //and call the necessary callback handler
972 int res = 0;
973
974 ALOGI("handleNdpIndication msg_id:%u", ndpCmdType);
975 switch (ndpCmdType) {
976 case QCA_WLAN_VENDOR_ATTR_NDP_REQUEST_IND:
977 NanDataPathRequestInd ndpRequestInd;
978 memset(&ndpRequestInd, 0, sizeof(ndpRequestInd));
979
980 res = getNdpRequest(tb_vendor, &ndpRequestInd);
981 if (!res && mHandler.EventDataRequest) {
982 (*mHandler.EventDataRequest)(&ndpRequestInd);
983 }
984 break;
985
986 case QCA_WLAN_VENDOR_ATTR_NDP_CONFIRM_IND:
987 NanDataPathConfirmInd ndpConfirmInd;
988 memset(&ndpConfirmInd, 0, sizeof(ndpConfirmInd));
989
990 res = getNdpConfirm(tb_vendor, &ndpConfirmInd);
991 if (!res && mHandler.EventDataConfirm) {
992 (*mHandler.EventDataConfirm)(&ndpConfirmInd);
993 }
994 break;
995
996 case QCA_WLAN_VENDOR_ATTR_NDP_END_IND:
997 {
998 NanDataPathEndInd *ndpEndInd = NULL;
999 u8 num_ndp_ids = 0;
1000
1001 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]) {
1002 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP not found", __FUNCTION__);
1003 return WIFI_ERROR_INVALID_ARGS;
1004 }
1005
1006 num_ndp_ids = (u8)(nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY])/sizeof(u32));
1007 ALOGD("%s: NDP Num Instance Ids : val %d", __FUNCTION__, num_ndp_ids);
1008
1009 if (num_ndp_ids) {
1010 ndpEndInd =
1011 (NanDataPathEndInd *)malloc(sizeof(NanDataPathEndInd)+ (sizeof(u32) * num_ndp_ids));
1012 if (!ndpEndInd) {
1013 ALOGE("%s: ndp_instance_id malloc Failed", __FUNCTION__);
1014 return WIFI_ERROR_OUT_OF_MEMORY;
1015 }
1016 ndpEndInd->num_ndp_instances = num_ndp_ids;
1017 nla_memcpy(ndpEndInd->ndp_instance_id,
1018 tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY],
1019 sizeof(u32) * ndpEndInd->num_ndp_instances);
1020 }
1021 if (mHandler.EventDataEnd) {
1022 (*mHandler.EventDataEnd)(ndpEndInd);
1023 }
1024 free(ndpEndInd);
1025 break;
1026 }
1027
1028 case QCA_WLAN_VENDOR_ATTR_NDP_SCHEDULE_UPDATE_IND:
1029 {
1030 NanDataPathScheduleUpdateInd *pNdpScheduleUpdateInd;
1031 u32 num_channels = 0, num_ndp_ids = 0;
1032
1033 if ((!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]) ||
1034 (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_SCHEDULE_UPDATE_REASON]) ||
1035 (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY])) {
1036 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP not found", __FUNCTION__);
1037 return WIFI_ERROR_INVALID_ARGS;
1038 }
1039 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_NUM_CHANNELS]) {
1040 num_channels = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_NUM_CHANNELS]);
1041 ALOGD("%s: num_channels = %d", __FUNCTION__, num_channels);
1042 if ((num_channels > NAN_MAX_CHANNEL_INFO_SUPPORTED) &&
1043 (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO])) {
1044 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO not found", __FUNCTION__);
1045 return WIFI_ERROR_INVALID_ARGS;
1046 }
1047 }
1048 num_ndp_ids = (u8)(nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY])/sizeof(u32));
1049 ALOGD("%s: NDP Num Instance Ids : val %d", __FUNCTION__, num_ndp_ids);
1050
1051 pNdpScheduleUpdateInd =
1052 (NanDataPathScheduleUpdateInd *)malloc(sizeof(NanDataPathScheduleUpdateInd)
1053 + (sizeof(u32) * num_ndp_ids));
1054 if (!pNdpScheduleUpdateInd) {
1055 ALOGE("%s: NdpScheduleUpdate malloc Failed", __FUNCTION__);
1056 return WIFI_ERROR_OUT_OF_MEMORY;
1057 }
1058 pNdpScheduleUpdateInd->num_channels = num_channels;
1059 pNdpScheduleUpdateInd->num_ndp_instances = num_ndp_ids;
1060
1061 res = getNdpScheduleUpdate(tb_vendor, pNdpScheduleUpdateInd);
1062 if (!res && mHandler.EventScheduleUpdate) {
1063 (*mHandler.EventScheduleUpdate)(pNdpScheduleUpdateInd);
1064 }
1065 free(pNdpScheduleUpdateInd);
1066 break;
1067 }
1068 default:
1069 ALOGE("handleNdpIndication error invalid ndpCmdType:%u", ndpCmdType);
1070 res = (int)WIFI_ERROR_INVALID_REQUEST_ID;
1071 break;
1072 }
1073 return res;
1074 }
1075
getNdpRequest(struct nlattr ** tb_vendor,NanDataPathRequestInd * event)1076 int NanCommand::getNdpRequest(struct nlattr **tb_vendor,
1077 NanDataPathRequestInd *event)
1078 {
1079 u32 len = 0;
1080
1081 if (event == NULL || tb_vendor == NULL) {
1082 ALOGE("%s: Invalid input argument event:%p tb_vendor:%p",
1083 __FUNCTION__, event, tb_vendor);
1084 return WIFI_ERROR_INVALID_ARGS;
1085 }
1086 if ((!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID]) ||
1087 (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]) ||
1088 (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID])) {
1089 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP not found", __FUNCTION__);
1090 return WIFI_ERROR_INVALID_ARGS;
1091 }
1092
1093 event->service_instance_id = nla_get_u16(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID]);
1094 ALOGD("%s: Service Instance id : val %d", __FUNCTION__, event->service_instance_id);
1095
1096 len = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]);
1097 len = ((sizeof(event->peer_disc_mac_addr) <= len) ? sizeof(event->peer_disc_mac_addr) : len);
1098 memcpy(&event->peer_disc_mac_addr[0], nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]), len);
1099
1100 event->ndp_instance_id = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]);
1101 ALOGD("%s: Ndp Instance id: %d", __FUNCTION__, event->ndp_instance_id);
1102 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]) {
1103 len = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]);
1104 len = ((sizeof(event->app_info.ndp_app_info) <= len) ? sizeof(event->app_info.ndp_app_info) : len);
1105 memcpy(&event->app_info.ndp_app_info[0], nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]), len);
1106 event->app_info.ndp_app_info_len = len;
1107 } else {
1108 ALOGD("%s: NDP App Info not present", __FUNCTION__);
1109 }
1110 return WIFI_SUCCESS;
1111 }
1112
getNdpConfirm(struct nlattr ** tb_vendor,NanDataPathConfirmInd * event)1113 int NanCommand::getNdpConfirm(struct nlattr **tb_vendor,
1114 NanDataPathConfirmInd *event)
1115 {
1116 u32 len = 0;
1117 NanInternalStatusType drv_reason_code;
1118 struct nlattr *chInfo;
1119 NanChannelInfo *pChInfo;
1120 int rem;
1121 u32 i = 0;
1122
1123 if (event == NULL || tb_vendor == NULL) {
1124 ALOGE("%s: Invalid input argument event:%p tb_vendor:%p",
1125 __FUNCTION__, event, tb_vendor);
1126 return WIFI_ERROR_INVALID_ARGS;
1127 }
1128 if ((!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]) ||
1129 (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR]) ||
1130 (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE])) {
1131 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP not found", __FUNCTION__);
1132 return WIFI_ERROR_INVALID_ARGS;
1133 }
1134
1135 event->ndp_instance_id = nla_get_u16(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]);
1136 ALOGD("%s: Service Instance id : val %d", __FUNCTION__, event->ndp_instance_id);
1137
1138 len = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR]);
1139 len = ((sizeof(event->peer_ndi_mac_addr) <= len) ? sizeof(event->peer_ndi_mac_addr) : len);
1140 memcpy(&event->peer_ndi_mac_addr[0], nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR]), len);
1141
1142 event->rsp_code = (NanDataPathResponseCode)nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE]);
1143 ALOGD("%s: Response code %d", __FUNCTION__, event->rsp_code);
1144
1145 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]) {
1146 len = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]);
1147 len = ((sizeof(event->app_info.ndp_app_info) <= len) ? sizeof(event->app_info.ndp_app_info) : len);
1148 memcpy(&event->app_info.ndp_app_info[0], nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]), len);
1149 event->app_info.ndp_app_info_len = len;
1150 } else {
1151 ALOGD("%s: NDP App Info not present", __FUNCTION__);
1152 }
1153 drv_reason_code = (NanInternalStatusType)nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE]);
1154 ALOGD("%s: Drv reason code %d", __FUNCTION__, drv_reason_code);
1155 switch (drv_reason_code) {
1156 case NDP_I_MGMT_FRAME_REQUEST_FAILED:
1157 case NDP_I_MGMT_FRAME_RESPONSE_FAILED:
1158 case NDP_I_MGMT_FRAME_CONFIRM_FAILED:
1159 case NDP_I_MGMT_FRAME_SECURITY_INSTALL_FAILED:
1160 event->reason_code = NAN_STATUS_PROTOCOL_FAILURE;
1161 break;
1162 default:
1163 event->reason_code = (NanStatusType)drv_reason_code;
1164 break;
1165 }
1166 ALOGD("%s: Reason code %d", __FUNCTION__, event->reason_code);
1167
1168 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_NUM_CHANNELS]) {
1169 event->num_channels =
1170 nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_NUM_CHANNELS]);
1171 ALOGD("%s: num_channels = %d", __FUNCTION__, event->num_channels);
1172 if ((event->num_channels > NAN_MAX_CHANNEL_INFO_SUPPORTED) &&
1173 (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO])) {
1174 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO not found", __FUNCTION__);
1175 return WIFI_ERROR_INVALID_ARGS;
1176 }
1177 }
1178
1179 if (event->num_channels != 0) {
1180 for (chInfo =
1181 (struct nlattr *) nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO]),
1182 rem = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO]);
1183 (i < NAN_MAX_CHANNEL_INFO_SUPPORTED && nla_ok(chInfo, rem));
1184 chInfo = nla_next(chInfo, &(rem))) {
1185 struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1];
1186
1187 pChInfo =
1188 (NanChannelInfo *) ((u8 *)event->channel_info + (i++ * (sizeof(NanChannelInfo))));
1189 nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX,
1190 (struct nlattr *) nla_data(chInfo), nla_len(chInfo), NULL);
1191
1192 if (!tb2[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL]) {
1193 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_CHANNEL not found", __FUNCTION__);
1194 return WIFI_ERROR_INVALID_ARGS;
1195 }
1196 pChInfo->channel = nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL]);
1197 ALOGD("%s: Channel = %d", __FUNCTION__, pChInfo->channel);
1198
1199 if (!tb2[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_WIDTH]) {
1200 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_WIDTH not found", __FUNCTION__);
1201 return WIFI_ERROR_INVALID_ARGS;
1202 }
1203 pChInfo->bandwidth = nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_WIDTH]);
1204 ALOGD("%s: Channel BW = %d", __FUNCTION__, pChInfo->bandwidth);
1205
1206 if (!tb2[QCA_WLAN_VENDOR_ATTR_NDP_NSS]) {
1207 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP_NSS not found", __FUNCTION__);
1208 return WIFI_ERROR_INVALID_ARGS;
1209 }
1210 pChInfo->nss = nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_NDP_NSS]);
1211 ALOGD("%s: No. Spatial Stream = %d", __FUNCTION__, pChInfo->nss);
1212 }
1213 }
1214 return WIFI_SUCCESS;
1215 }
1216
getNdpScheduleUpdate(struct nlattr ** tb_vendor,NanDataPathScheduleUpdateInd * event)1217 int NanCommand::getNdpScheduleUpdate(struct nlattr **tb_vendor,
1218 NanDataPathScheduleUpdateInd *event)
1219 {
1220 u32 len = 0;
1221 struct nlattr *chInfo;
1222 NanChannelInfo *pChInfo;
1223 int rem;
1224 u32 i = 0;
1225
1226 len = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]);
1227 len = ((sizeof(event->peer_mac_addr) <= len) ? sizeof(event->peer_mac_addr) : len);
1228 memcpy(&event->peer_mac_addr[0], nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]), len);
1229
1230 event->schedule_update_reason_code = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_SCHEDULE_UPDATE_REASON]);
1231 ALOGD("%s: Reason code %d", __FUNCTION__, event->schedule_update_reason_code);
1232
1233 if (event->num_channels != 0) {
1234 for (chInfo =
1235 (struct nlattr *) nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO]),
1236 rem = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO]);
1237 (i < NAN_MAX_CHANNEL_INFO_SUPPORTED && nla_ok(chInfo, rem));
1238 chInfo = nla_next(chInfo, &(rem))) {
1239 struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1];
1240
1241 pChInfo =
1242 (NanChannelInfo *) ((u8 *)event->channel_info + (i++ * (sizeof(NanChannelInfo))));
1243 nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX,
1244 (struct nlattr *) nla_data(chInfo), nla_len(chInfo), NULL);
1245
1246 if (!tb2[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL]) {
1247 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_CHANNEL not found", __FUNCTION__);
1248 return WIFI_ERROR_INVALID_ARGS;
1249 }
1250 pChInfo->channel = nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL]);
1251 ALOGD("%s: Channel = %d", __FUNCTION__, pChInfo->channel);
1252
1253 if (!tb2[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_WIDTH]) {
1254 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_WIDTH not found", __FUNCTION__);
1255 return WIFI_ERROR_INVALID_ARGS;
1256 }
1257 pChInfo->bandwidth = nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_WIDTH]);
1258 ALOGD("%s: Channel BW = %d", __FUNCTION__, pChInfo->bandwidth);
1259
1260 if (!tb2[QCA_WLAN_VENDOR_ATTR_NDP_NSS]) {
1261 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP_NSS not found", __FUNCTION__);
1262 return WIFI_ERROR_INVALID_ARGS;
1263 }
1264 pChInfo->nss = nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_NDP_NSS]);
1265 ALOGD("%s: No. Spatial Stream = %d", __FUNCTION__, pChInfo->nss);
1266 }
1267 }
1268
1269 if (event->num_ndp_instances) {
1270 nla_memcpy(event->ndp_instance_id,
1271 tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY],
1272 sizeof(u32) * event->num_ndp_instances);
1273 }
1274 return WIFI_SUCCESS;
1275 }
1276
getNanRangeRequestReceivedInd(NanRangeRequestInd * event)1277 int NanCommand::getNanRangeRequestReceivedInd(NanRangeRequestInd *event)
1278 {
1279 if (event == NULL || mNanVendorEvent == NULL) {
1280 ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
1281 __func__, event, mNanVendorEvent);
1282 return WIFI_ERROR_INVALID_ARGS;
1283 }
1284
1285 pNanFWRangeReqRecvdInd pRsp = (pNanFWRangeReqRecvdInd)mNanVendorEvent;
1286
1287 u8 *pInputTlv = pRsp->ptlv;
1288 NanTlv outputTlv;
1289 u16 readLen = 0;
1290
1291 int remainingLen = (mNanDataLen - \
1292 (sizeof(NanMsgHeader)));
1293
1294 if (remainingLen <= 0) {
1295 ALOGE("%s: No TLV's present",__func__);
1296 return WIFI_SUCCESS;
1297 }
1298
1299 ALOGV("%s: TLV remaining Len:%d",__func__, remainingLen);
1300 while ((remainingLen > 0) &&
1301 (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv)))) {
1302 ALOGV("%s: Remaining Len:%d readLen:%d type:%d length:%d",
1303 __func__, remainingLen, readLen, outputTlv.type,
1304 outputTlv.length);
1305 switch (outputTlv.type) {
1306 case NAN_TLV_TYPE_NAN20_RANGING_REQUEST_RECEIVED:
1307 NanFWRangeReqRecvdMsg fwRangeReqRecvd;
1308 if (outputTlv.length > sizeof(fwRangeReqRecvd)) {
1309 outputTlv.length = sizeof(fwRangeReqRecvd);
1310 }
1311 memcpy(&fwRangeReqRecvd, outputTlv.value, outputTlv.length);
1312 FW_MAC_ADDR_TO_CHAR_ARRAY(fwRangeReqRecvd.range_mac_addr, event->range_req_intf_addr);
1313 event->publish_id = fwRangeReqRecvd.range_id;
1314 break;
1315 default:
1316 ALOGV("Unhandled TLV type:%d", outputTlv.type);
1317 break;
1318 }
1319 remainingLen -= readLen;
1320 pInputTlv += readLen;
1321 memset(&outputTlv,0, sizeof(outputTlv));
1322 }
1323 return WIFI_SUCCESS;
1324 }
1325
getNanRangeReportInd(NanRangeReportInd * event)1326 int NanCommand::getNanRangeReportInd(NanRangeReportInd *event)
1327 {
1328 if (event == NULL || mNanVendorEvent == NULL) {
1329 ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
1330 __func__, event, mNanVendorEvent);
1331 return WIFI_ERROR_INVALID_ARGS;
1332 }
1333
1334 pNanFWRangeReportInd pRsp = (pNanFWRangeReportInd)mNanVendorEvent;
1335
1336 u8 *pInputTlv = pRsp->ptlv;
1337 NanTlv outputTlv;
1338 u16 readLen = 0;
1339
1340 int remainingLen = (mNanDataLen - \
1341 (sizeof(NanMsgHeader)));
1342
1343 if (remainingLen <= 0) {
1344 ALOGE("%s: No TLV's present",__func__);
1345 return WIFI_SUCCESS;
1346 }
1347
1348 ALOGV("%s: TLV remaining Len:%d",__func__, remainingLen);
1349 while ((remainingLen > 0) &&
1350 (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv)))) {
1351 ALOGV("%s: Remaining Len:%d readLen:%d type:%d length:%d",
1352 __func__, remainingLen, readLen, outputTlv.type,
1353 outputTlv.length);
1354 switch (outputTlv.type) {
1355 case NAN_TLV_TYPE_MAC_ADDRESS:
1356 if (outputTlv.length > NAN_MAC_ADDR_LEN) {
1357 outputTlv.length = NAN_MAC_ADDR_LEN;
1358 }
1359 memcpy(event->range_req_intf_addr, outputTlv.value, outputTlv.length);
1360 break;
1361
1362 case NAN_TLV_TYPE_NAN20_RANGING_RESULT:
1363 NanFWRangeReportParams range_params;
1364 if (outputTlv.length > sizeof(NanFWRangeReportParams)) {
1365 outputTlv.length = sizeof(NanFWRangeReportParams);
1366 }
1367 memcpy(&range_params, outputTlv.value, outputTlv.length);
1368 event->range_measurement_mm = range_params.range_measurement;
1369 event->publish_id = range_params.publish_id;
1370 // event->event_type = range_params.event_type;
1371 break;
1372 default:
1373 ALOGV("Unhandled TLV type:%d", outputTlv.type);
1374 break;
1375 }
1376 remainingLen -= readLen;
1377 pInputTlv += readLen;
1378 memset(&outputTlv,0, sizeof(outputTlv));
1379 }
1380 return WIFI_SUCCESS;
1381 }
1382