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