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 wifi_error NanCommand::getNanStaParameter(wifi_interface_handle iface,
890 NanStaParameter *pRsp)
891 {
892 wifi_error ret = WIFI_ERROR_NONE;
893 transaction_id id = 1;
894 interface_info *ifaceInfo = getIfaceInfo(iface);
895
896 ret = create();
897 if (ret != WIFI_SUCCESS)
898 goto cleanup;
899
900 /* Set the interface Id of the message. */
901 ret = set_iface_id(ifaceInfo->name);
902 if (ret != WIFI_SUCCESS)
903 goto cleanup;
904
905 /*
906 Construct NL message to get the sync stats parameter
907 which has all the parameter required by staparameter.
908 */
909 NanStatsRequest syncStats;
910 memset(&syncStats, 0, sizeof(syncStats));
911 syncStats.stats_type = NAN_STATS_ID_DE_TIMING_SYNC;
912 syncStats.clear = 0;
913
914 mStaParam = pRsp;
915 ret = putNanStats(id, &syncStats);
916 if (ret != WIFI_SUCCESS) {
917 ALOGE("%s: putNanStats Error:%d",__func__, ret);
918 goto cleanup;
919 }
920 ret = requestEvent();
921 if (ret != 0) {
922 ALOGE("%s: requestEvent Error:%d",__func__, ret);
923 goto cleanup;
924 }
925
926 struct timespec abstime;
927 abstime.tv_sec = 4;
928 abstime.tv_nsec = 0;
929 ret = mCondition.wait(abstime);
930 if (ret == WIFI_ERROR_TIMED_OUT)
931 {
932 ALOGE("%s: Time out happened.", __func__);
933 goto cleanup;
934 }
935 ALOGV("%s: NanStaparameter Master_pref:%x," \
936 " Random_factor:%x, hop_count:%x " \
937 " beacon_transmit_time:%d" \
938 " ndp_channel_freq:%d", __func__,
939 pRsp->master_pref, pRsp->random_factor,
940 pRsp->hop_count, pRsp->beacon_transmit_time, pRsp->ndp_channel_freq);
941 cleanup:
942 mStaParam = NULL;
943 return ret;
944 }
945
getNanTransmitFollowupInd(NanTransmitFollowupInd * event)946 int NanCommand::getNanTransmitFollowupInd(NanTransmitFollowupInd *event)
947 {
948 if (event == NULL || mNanVendorEvent == NULL) {
949 ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
950 __func__, event, mNanVendorEvent);
951 return WIFI_ERROR_INVALID_ARGS;
952 }
953
954 pNanSelfTransmitFollowupIndMsg pRsp = (pNanSelfTransmitFollowupIndMsg)mNanVendorEvent;
955 event->id = pRsp->fwHeader.transactionId;
956 NanErrorTranslation((NanInternalStatusType)pRsp->reason, 0,
957 (void*)event, false);
958 return WIFI_SUCCESS;
959 }
960
961 //Function which calls the necessaryIndication callback
962 //based on the indication type
handleNdpIndication(u32 ndpCmdType,struct nlattr ** tb_vendor)963 int NanCommand::handleNdpIndication(u32 ndpCmdType, struct nlattr **tb_vendor)
964 {
965 //Based on the message_id in the header determine the Indication type
966 //and call the necessary callback handler
967 int res = 0;
968
969 ALOGI("handleNdpIndication msg_id:%u", ndpCmdType);
970 switch (ndpCmdType) {
971 case QCA_WLAN_VENDOR_ATTR_NDP_REQUEST_IND:
972 NanDataPathRequestInd ndpRequestInd;
973 memset(&ndpRequestInd, 0, sizeof(ndpRequestInd));
974
975 res = getNdpRequest(tb_vendor, &ndpRequestInd);
976 if (!res && mHandler.EventDataRequest) {
977 (*mHandler.EventDataRequest)(&ndpRequestInd);
978 }
979 break;
980
981 case QCA_WLAN_VENDOR_ATTR_NDP_CONFIRM_IND:
982 NanDataPathConfirmInd ndpConfirmInd;
983 memset(&ndpConfirmInd, 0, sizeof(ndpConfirmInd));
984
985 res = getNdpConfirm(tb_vendor, &ndpConfirmInd);
986 if (!res && mHandler.EventDataConfirm) {
987 (*mHandler.EventDataConfirm)(&ndpConfirmInd);
988 }
989 break;
990
991 case QCA_WLAN_VENDOR_ATTR_NDP_END_IND:
992 {
993 NanDataPathEndInd *ndpEndInd = NULL;
994 u8 num_ndp_ids = 0;
995
996 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]) {
997 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP not found", __FUNCTION__);
998 return WIFI_ERROR_INVALID_ARGS;
999 }
1000
1001 num_ndp_ids = (u8)(nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY])/sizeof(u32));
1002 ALOGD("%s: NDP Num Instance Ids : val %d", __FUNCTION__, num_ndp_ids);
1003
1004 if (num_ndp_ids) {
1005 ndpEndInd =
1006 (NanDataPathEndInd *)malloc(sizeof(NanDataPathEndInd)+ (sizeof(u32) * num_ndp_ids));
1007 if (!ndpEndInd) {
1008 ALOGE("%s: ndp_instance_id malloc Failed", __FUNCTION__);
1009 return WIFI_ERROR_OUT_OF_MEMORY;
1010 }
1011 ndpEndInd->num_ndp_instances = num_ndp_ids;
1012 nla_memcpy(ndpEndInd->ndp_instance_id,
1013 tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY],
1014 sizeof(u32) * ndpEndInd->num_ndp_instances);
1015 }
1016 if (mHandler.EventDataEnd) {
1017 (*mHandler.EventDataEnd)(ndpEndInd);
1018 }
1019 free(ndpEndInd);
1020 break;
1021 }
1022
1023 case QCA_WLAN_VENDOR_ATTR_NDP_SCHEDULE_UPDATE_IND:
1024 {
1025 NanDataPathScheduleUpdateInd *pNdpScheduleUpdateInd;
1026 u32 num_channels = 0, num_ndp_ids = 0;
1027
1028 if ((!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]) ||
1029 (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_SCHEDULE_UPDATE_REASON]) ||
1030 (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY])) {
1031 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP not found", __FUNCTION__);
1032 return WIFI_ERROR_INVALID_ARGS;
1033 }
1034 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_NUM_CHANNELS]) {
1035 num_channels = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_NUM_CHANNELS]);
1036 ALOGD("%s: num_channels = %d", __FUNCTION__, num_channels);
1037 if ((num_channels > NAN_MAX_CHANNEL_INFO_SUPPORTED) &&
1038 (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO])) {
1039 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO not found", __FUNCTION__);
1040 return WIFI_ERROR_INVALID_ARGS;
1041 }
1042 }
1043 num_ndp_ids = (u8)(nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY])/sizeof(u32));
1044 ALOGD("%s: NDP Num Instance Ids : val %d", __FUNCTION__, num_ndp_ids);
1045
1046 pNdpScheduleUpdateInd =
1047 (NanDataPathScheduleUpdateInd *)malloc(sizeof(NanDataPathScheduleUpdateInd)
1048 + (sizeof(u32) * num_ndp_ids));
1049 if (!pNdpScheduleUpdateInd) {
1050 ALOGE("%s: NdpScheduleUpdate malloc Failed", __FUNCTION__);
1051 return WIFI_ERROR_OUT_OF_MEMORY;
1052 }
1053 pNdpScheduleUpdateInd->num_channels = num_channels;
1054 pNdpScheduleUpdateInd->num_ndp_instances = num_ndp_ids;
1055
1056 res = getNdpScheduleUpdate(tb_vendor, pNdpScheduleUpdateInd);
1057 if (!res && mHandler.EventScheduleUpdate) {
1058 (*mHandler.EventScheduleUpdate)(pNdpScheduleUpdateInd);
1059 }
1060 free(pNdpScheduleUpdateInd);
1061 break;
1062 }
1063 default:
1064 ALOGE("handleNdpIndication error invalid ndpCmdType:%u", ndpCmdType);
1065 res = (int)WIFI_ERROR_INVALID_REQUEST_ID;
1066 break;
1067 }
1068 return res;
1069 }
1070
getNdpRequest(struct nlattr ** tb_vendor,NanDataPathRequestInd * event)1071 int NanCommand::getNdpRequest(struct nlattr **tb_vendor,
1072 NanDataPathRequestInd *event)
1073 {
1074 u32 len = 0;
1075
1076 if (event == NULL || tb_vendor == NULL) {
1077 ALOGE("%s: Invalid input argument event:%p tb_vendor:%p",
1078 __FUNCTION__, event, tb_vendor);
1079 return WIFI_ERROR_INVALID_ARGS;
1080 }
1081 if ((!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID]) ||
1082 (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]) ||
1083 (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID])) {
1084 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP not found", __FUNCTION__);
1085 return WIFI_ERROR_INVALID_ARGS;
1086 }
1087
1088 event->service_instance_id = nla_get_u16(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID]);
1089 ALOGD("%s: Service Instance id : val %d", __FUNCTION__, event->service_instance_id);
1090
1091 len = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]);
1092 len = ((sizeof(event->peer_disc_mac_addr) <= len) ? sizeof(event->peer_disc_mac_addr) : len);
1093 memcpy(&event->peer_disc_mac_addr[0], nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]), len);
1094
1095 event->ndp_instance_id = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]);
1096 ALOGD("%s: Ndp Instance id: %d", __FUNCTION__, event->ndp_instance_id);
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 return WIFI_SUCCESS;
1106 }
1107
getNdpConfirm(struct nlattr ** tb_vendor,NanDataPathConfirmInd * event)1108 int NanCommand::getNdpConfirm(struct nlattr **tb_vendor,
1109 NanDataPathConfirmInd *event)
1110 {
1111 u32 len = 0;
1112 NanInternalStatusType drv_reason_code;
1113 struct nlattr *chInfo;
1114 NanChannelInfo *pChInfo;
1115 int rem;
1116 u32 i = 0;
1117
1118 if (event == NULL || tb_vendor == NULL) {
1119 ALOGE("%s: Invalid input argument event:%p tb_vendor:%p",
1120 __FUNCTION__, event, tb_vendor);
1121 return WIFI_ERROR_INVALID_ARGS;
1122 }
1123 if ((!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]) ||
1124 (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR]) ||
1125 (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE])) {
1126 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP not found", __FUNCTION__);
1127 return WIFI_ERROR_INVALID_ARGS;
1128 }
1129
1130 event->ndp_instance_id = nla_get_u16(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]);
1131 ALOGD("%s: Service Instance id : val %d", __FUNCTION__, event->ndp_instance_id);
1132
1133 len = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR]);
1134 len = ((sizeof(event->peer_ndi_mac_addr) <= len) ? sizeof(event->peer_ndi_mac_addr) : len);
1135 memcpy(&event->peer_ndi_mac_addr[0], nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR]), len);
1136
1137 event->rsp_code = (NanDataPathResponseCode)nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE]);
1138 ALOGD("%s: Response code %d", __FUNCTION__, event->rsp_code);
1139
1140 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]) {
1141 len = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]);
1142 len = ((sizeof(event->app_info.ndp_app_info) <= len) ? sizeof(event->app_info.ndp_app_info) : len);
1143 memcpy(&event->app_info.ndp_app_info[0], nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]), len);
1144 event->app_info.ndp_app_info_len = len;
1145 } else {
1146 ALOGD("%s: NDP App Info not present", __FUNCTION__);
1147 }
1148 drv_reason_code = (NanInternalStatusType)nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE]);
1149 ALOGD("%s: Drv reason code %d", __FUNCTION__, drv_reason_code);
1150 switch (drv_reason_code) {
1151 case NDP_I_MGMT_FRAME_REQUEST_FAILED:
1152 case NDP_I_MGMT_FRAME_RESPONSE_FAILED:
1153 case NDP_I_MGMT_FRAME_CONFIRM_FAILED:
1154 case NDP_I_MGMT_FRAME_SECURITY_INSTALL_FAILED:
1155 event->reason_code = NAN_STATUS_PROTOCOL_FAILURE;
1156 break;
1157 default:
1158 event->reason_code = (NanStatusType)drv_reason_code;
1159 break;
1160 }
1161 ALOGD("%s: Reason code %d", __FUNCTION__, event->reason_code);
1162
1163 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_NUM_CHANNELS]) {
1164 event->num_channels =
1165 nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_NUM_CHANNELS]);
1166 ALOGD("%s: num_channels = %d", __FUNCTION__, event->num_channels);
1167 if ((event->num_channels > NAN_MAX_CHANNEL_INFO_SUPPORTED) &&
1168 (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO])) {
1169 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO not found", __FUNCTION__);
1170 return WIFI_ERROR_INVALID_ARGS;
1171 }
1172 }
1173
1174 if (event->num_channels != 0) {
1175 for (chInfo =
1176 (struct nlattr *) nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO]),
1177 rem = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO]);
1178 (i < NAN_MAX_CHANNEL_INFO_SUPPORTED && nla_ok(chInfo, rem));
1179 chInfo = nla_next(chInfo, &(rem))) {
1180 struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1];
1181
1182 pChInfo =
1183 (NanChannelInfo *) ((u8 *)event->channel_info + (i++ * (sizeof(NanChannelInfo))));
1184 nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX,
1185 (struct nlattr *) nla_data(chInfo), nla_len(chInfo), NULL);
1186
1187 if (!tb2[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL]) {
1188 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_CHANNEL not found", __FUNCTION__);
1189 return WIFI_ERROR_INVALID_ARGS;
1190 }
1191 pChInfo->channel = nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL]);
1192 ALOGD("%s: Channel = %d", __FUNCTION__, pChInfo->channel);
1193
1194 if (!tb2[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_WIDTH]) {
1195 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_WIDTH not found", __FUNCTION__);
1196 return WIFI_ERROR_INVALID_ARGS;
1197 }
1198 pChInfo->bandwidth = nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_WIDTH]);
1199 ALOGD("%s: Channel BW = %d", __FUNCTION__, pChInfo->bandwidth);
1200
1201 if (!tb2[QCA_WLAN_VENDOR_ATTR_NDP_NSS]) {
1202 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP_NSS not found", __FUNCTION__);
1203 return WIFI_ERROR_INVALID_ARGS;
1204 }
1205 pChInfo->nss = nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_NDP_NSS]);
1206 ALOGD("%s: No. Spatial Stream = %d", __FUNCTION__, pChInfo->nss);
1207 }
1208 }
1209 return WIFI_SUCCESS;
1210 }
1211
getNdpScheduleUpdate(struct nlattr ** tb_vendor,NanDataPathScheduleUpdateInd * event)1212 int NanCommand::getNdpScheduleUpdate(struct nlattr **tb_vendor,
1213 NanDataPathScheduleUpdateInd *event)
1214 {
1215 u32 len = 0;
1216 struct nlattr *chInfo;
1217 NanChannelInfo *pChInfo;
1218 int rem;
1219 u32 i = 0;
1220
1221 len = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]);
1222 len = ((sizeof(event->peer_mac_addr) <= len) ? sizeof(event->peer_mac_addr) : len);
1223 memcpy(&event->peer_mac_addr[0], nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]), len);
1224
1225 event->schedule_update_reason_code = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_SCHEDULE_UPDATE_REASON]);
1226 ALOGD("%s: Reason code %d", __FUNCTION__, event->schedule_update_reason_code);
1227
1228 if (event->num_channels != 0) {
1229 for (chInfo =
1230 (struct nlattr *) nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO]),
1231 rem = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO]);
1232 (i < NAN_MAX_CHANNEL_INFO_SUPPORTED && nla_ok(chInfo, rem));
1233 chInfo = nla_next(chInfo, &(rem))) {
1234 struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1];
1235
1236 pChInfo =
1237 (NanChannelInfo *) ((u8 *)event->channel_info + (i++ * (sizeof(NanChannelInfo))));
1238 nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX,
1239 (struct nlattr *) nla_data(chInfo), nla_len(chInfo), NULL);
1240
1241 if (!tb2[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL]) {
1242 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_CHANNEL not found", __FUNCTION__);
1243 return WIFI_ERROR_INVALID_ARGS;
1244 }
1245 pChInfo->channel = nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL]);
1246 ALOGD("%s: Channel = %d", __FUNCTION__, pChInfo->channel);
1247
1248 if (!tb2[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_WIDTH]) {
1249 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_WIDTH not found", __FUNCTION__);
1250 return WIFI_ERROR_INVALID_ARGS;
1251 }
1252 pChInfo->bandwidth = nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_WIDTH]);
1253 ALOGD("%s: Channel BW = %d", __FUNCTION__, pChInfo->bandwidth);
1254
1255 if (!tb2[QCA_WLAN_VENDOR_ATTR_NDP_NSS]) {
1256 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP_NSS not found", __FUNCTION__);
1257 return WIFI_ERROR_INVALID_ARGS;
1258 }
1259 pChInfo->nss = nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_NDP_NSS]);
1260 ALOGD("%s: No. Spatial Stream = %d", __FUNCTION__, pChInfo->nss);
1261 }
1262 }
1263
1264 if (event->num_ndp_instances) {
1265 nla_memcpy(event->ndp_instance_id,
1266 tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY],
1267 sizeof(u32) * event->num_ndp_instances);
1268 }
1269 return WIFI_SUCCESS;
1270 }
1271
getNanRangeRequestReceivedInd(NanRangeRequestInd * event)1272 int NanCommand::getNanRangeRequestReceivedInd(NanRangeRequestInd *event)
1273 {
1274 if (event == NULL || mNanVendorEvent == NULL) {
1275 ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
1276 __func__, event, mNanVendorEvent);
1277 return WIFI_ERROR_INVALID_ARGS;
1278 }
1279
1280 pNanFWRangeReqRecvdInd pRsp = (pNanFWRangeReqRecvdInd)mNanVendorEvent;
1281
1282 u8 *pInputTlv = pRsp->ptlv;
1283 NanTlv outputTlv;
1284 u16 readLen = 0;
1285
1286 int remainingLen = (mNanDataLen - \
1287 (sizeof(NanMsgHeader)));
1288
1289 if (remainingLen <= 0) {
1290 ALOGE("%s: No TLV's present",__func__);
1291 return WIFI_SUCCESS;
1292 }
1293
1294 ALOGV("%s: TLV remaining Len:%d",__func__, remainingLen);
1295 while ((remainingLen > 0) &&
1296 (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv)))) {
1297 ALOGV("%s: Remaining Len:%d readLen:%d type:%d length:%d",
1298 __func__, remainingLen, readLen, outputTlv.type,
1299 outputTlv.length);
1300 switch (outputTlv.type) {
1301 case NAN_TLV_TYPE_NAN20_RANGING_REQUEST_RECEIVED:
1302 NanFWRangeReqRecvdMsg fwRangeReqRecvd;
1303 if (outputTlv.length > sizeof(fwRangeReqRecvd)) {
1304 outputTlv.length = sizeof(fwRangeReqRecvd);
1305 }
1306 memcpy(&fwRangeReqRecvd, outputTlv.value, outputTlv.length);
1307 FW_MAC_ADDR_TO_CHAR_ARRAY(fwRangeReqRecvd.range_mac_addr, event->range_req_intf_addr);
1308 event->publish_id = fwRangeReqRecvd.range_id;
1309 break;
1310 default:
1311 ALOGV("Unhandled TLV type:%d", outputTlv.type);
1312 break;
1313 }
1314 remainingLen -= readLen;
1315 pInputTlv += readLen;
1316 memset(&outputTlv,0, sizeof(outputTlv));
1317 }
1318 return WIFI_SUCCESS;
1319 }
1320
getNanRangeReportInd(NanRangeReportInd * event)1321 int NanCommand::getNanRangeReportInd(NanRangeReportInd *event)
1322 {
1323 if (event == NULL || mNanVendorEvent == NULL) {
1324 ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
1325 __func__, event, mNanVendorEvent);
1326 return WIFI_ERROR_INVALID_ARGS;
1327 }
1328
1329 pNanFWRangeReportInd pRsp = (pNanFWRangeReportInd)mNanVendorEvent;
1330
1331 u8 *pInputTlv = pRsp->ptlv;
1332 NanTlv outputTlv;
1333 u16 readLen = 0;
1334
1335 int remainingLen = (mNanDataLen - \
1336 (sizeof(NanMsgHeader)));
1337
1338 if (remainingLen <= 0) {
1339 ALOGE("%s: No TLV's present",__func__);
1340 return WIFI_SUCCESS;
1341 }
1342
1343 ALOGV("%s: TLV remaining Len:%d",__func__, remainingLen);
1344 while ((remainingLen > 0) &&
1345 (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv)))) {
1346 ALOGV("%s: Remaining Len:%d readLen:%d type:%d length:%d",
1347 __func__, remainingLen, readLen, outputTlv.type,
1348 outputTlv.length);
1349 switch (outputTlv.type) {
1350 case NAN_TLV_TYPE_MAC_ADDRESS:
1351 if (outputTlv.length > NAN_MAC_ADDR_LEN) {
1352 outputTlv.length = NAN_MAC_ADDR_LEN;
1353 }
1354 memcpy(event->range_req_intf_addr, outputTlv.value, outputTlv.length);
1355 break;
1356
1357 case NAN_TLV_TYPE_NAN20_RANGING_RESULT:
1358 NanFWRangeReportParams range_params;
1359 if (outputTlv.length > sizeof(NanFWRangeReportParams)) {
1360 outputTlv.length = sizeof(NanFWRangeReportParams);
1361 }
1362 memcpy(&range_params, outputTlv.value, outputTlv.length);
1363 event->range_measurement_mm = range_params.range_measurement;
1364 event->publish_id = range_params.publish_id;
1365 // event->event_type = range_params.event_type;
1366 break;
1367 default:
1368 ALOGV("Unhandled TLV type:%d", outputTlv.type);
1369 break;
1370 }
1371 remainingLen -= readLen;
1372 pInputTlv += readLen;
1373 memset(&outputTlv,0, sizeof(outputTlv));
1374 }
1375 return WIFI_SUCCESS;
1376 }
1377