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  * Changes from Qualcomm Innovation Center are provided under the following license:
17  *
18  * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
19  *
20  * Redistribution and use in source and binary forms, with or without
21  * modification, are permitted (subject to the limitations in the
22  * disclaimer below) provided that the following conditions are met:
23  *
24  *   * Redistributions of source code must retain the above copyright
25  *     notice, this list of conditions and the following disclaimer.
26  *
27  *   * Redistributions in binary form must reproduce the above
28  *     copyright notice, this list of conditions and the following
29  *     disclaimer in the documentation and/or other materials provided
30  *     with the distribution.
31  *
32  *   * Neither the name of Qualcomm Innovation Center, Inc. nor the names of its
33  *     contributors may be used to endorse or promote products derived
34  *     from this software without specific prior written permission.
35  *
36  * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
37  * GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
38  * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
39  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
40  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
41  * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
42  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
43  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
44  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
45  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
46  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
47  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
48  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
49  */
50 
51 #include "sync.h"
52 #include <utils/Log.h>
53 #include <errno.h>
54 #include <hardware_legacy/wifi_hal.h>
55 #include "nan_i.h"
56 #include "nancommand.h"
57 #include <errno.h>
58 
59 //Function which calls the necessaryIndication callback
60 //based on the indication type
handleNanIndication()61 int NanCommand::handleNanIndication()
62 {
63     //Based on the message_id in the header determine the Indication type
64     //and call the necessary callback handler
65     u16 msg_id;
66     int res = 0;
67 
68     msg_id = getIndicationType();
69 
70     ALOGV("handleNanIndication msg_id:%u", msg_id);
71     switch (msg_id) {
72     case NAN_INDICATION_PUBLISH_REPLIED:
73         NanPublishRepliedInd publishRepliedInd;
74         memset(&publishRepliedInd, 0, sizeof(publishRepliedInd));
75         res = getNanPublishReplied(&publishRepliedInd);
76         if (!res && mHandler.EventPublishReplied) {
77             (*mHandler.EventPublishReplied)(&publishRepliedInd);
78         }
79         break;
80 
81     case NAN_INDICATION_PUBLISH_TERMINATED:
82         NanPublishTerminatedInd publishTerminatedInd;
83         memset(&publishTerminatedInd, 0, sizeof(publishTerminatedInd));
84         res = getNanPublishTerminated(&publishTerminatedInd);
85         if (!res && mHandler.EventPublishTerminated) {
86             (*mHandler.EventPublishTerminated)(&publishTerminatedInd);
87         }
88         break;
89 
90     case NAN_INDICATION_MATCH:
91         NanMatchInd matchInd;
92         memset(&matchInd, 0, sizeof(matchInd));
93         res = getNanMatch(&matchInd);
94         if (!res && mHandler.EventMatch) {
95             (*mHandler.EventMatch)(&matchInd);
96         }
97         break;
98 
99     case NAN_INDICATION_MATCH_EXPIRED:
100         NanMatchExpiredInd matchExpiredInd;
101         memset(&matchExpiredInd, 0, sizeof(matchExpiredInd));
102         res = getNanMatchExpired(&matchExpiredInd);
103         if (!res && mHandler.EventMatchExpired) {
104             (*mHandler.EventMatchExpired)(&matchExpiredInd);
105         }
106         break;
107 
108     case NAN_INDICATION_SUBSCRIBE_TERMINATED:
109         NanSubscribeTerminatedInd subscribeTerminatedInd;
110         memset(&subscribeTerminatedInd, 0, sizeof(subscribeTerminatedInd));
111         res = getNanSubscribeTerminated(&subscribeTerminatedInd);
112         if (!res && mHandler.EventSubscribeTerminated) {
113             (*mHandler.EventSubscribeTerminated)(&subscribeTerminatedInd);
114         }
115         break;
116 
117     case NAN_INDICATION_DE_EVENT:
118         NanDiscEngEventInd discEngEventInd;
119         memset(&discEngEventInd, 0, sizeof(discEngEventInd));
120         res = getNanDiscEngEvent(&discEngEventInd);
121         /* Save the self MAC address received in DE indication event to use it
122          * in Passphrase to PMK calculation. And do not call the handler if the
123          * framework has disabled the self MAC address indication.
124          */
125         if (!res &&
126             (discEngEventInd.event_type == NAN_EVENT_ID_DISC_MAC_ADDR)) {
127             mNanCommandInstance->saveNmi(discEngEventInd.data.mac_addr.addr);
128             if (mNanCommandInstance->mNanDiscAddrIndDisabled)
129                 break;
130         }
131         if (!res && mHandler.EventDiscEngEvent) {
132             (*mHandler.EventDiscEngEvent)(&discEngEventInd);
133         }
134         break;
135 
136     case NAN_INDICATION_FOLLOWUP:
137         NanFollowupInd followupInd;
138         memset(&followupInd, 0, sizeof(followupInd));
139         res = getNanFollowup(&followupInd);
140         if (!res && mHandler.EventFollowup) {
141             (*mHandler.EventFollowup)(&followupInd);
142         }
143         break;
144 
145     case NAN_INDICATION_DISABLED:
146         NanDisabledInd disabledInd;
147         memset(&disabledInd, 0, sizeof(disabledInd));
148         res = getNanDisabled(&disabledInd);
149         if (!res && mHandler.EventDisabled) {
150             (*mHandler.EventDisabled)(&disabledInd);
151         }
152         break;
153 
154     case NAN_INDICATION_TCA:
155         NanTCAInd tcaInd;
156         memset(&tcaInd, 0, sizeof(tcaInd));
157         res = getNanTca(&tcaInd);
158         if (!res && mHandler.EventTca) {
159             (*mHandler.EventTca)(&tcaInd);
160         }
161         break;
162 
163     case NAN_INDICATION_BEACON_SDF_PAYLOAD:
164         NanBeaconSdfPayloadInd beaconSdfPayloadInd;
165         memset(&beaconSdfPayloadInd, 0, sizeof(beaconSdfPayloadInd));
166         res = getNanBeaconSdfPayload(&beaconSdfPayloadInd);
167         if (!res && mHandler.EventBeaconSdfPayload) {
168             (*mHandler.EventBeaconSdfPayload)(&beaconSdfPayloadInd);
169         }
170         break;
171 
172     case NAN_INDICATION_SELF_TRANSMIT_FOLLOWUP:
173         NanTransmitFollowupInd transmitFollowupInd;
174         memset(&transmitFollowupInd, 0, sizeof(NanTransmitFollowupInd));
175         res = getNanTransmitFollowupInd(&transmitFollowupInd);
176         if (!res && mHandler.EventTransmitFollowup) {
177             (*mHandler.EventTransmitFollowup)(&transmitFollowupInd);
178         }
179         break;
180 
181     case NAN_INDICATION_RANGING_REQUEST_RECEIVED:
182         NanRangeRequestInd rangeRequestInd;
183         memset(&rangeRequestInd, 0, sizeof(NanRangeRequestInd));
184         res = getNanRangeRequestReceivedInd(&rangeRequestInd);
185         if (!res && mHandler.EventRangeRequest) {
186             (*mHandler.EventRangeRequest)(&rangeRequestInd);
187         }
188         break;
189 
190     case NAN_INDICATION_RANGING_RESULT:
191         NanRangeReportInd rangeReportInd;
192         memset(&rangeReportInd, 0, sizeof(NanRangeReportInd));
193         res = getNanRangeReportInd(&rangeReportInd);
194         if (!res && mHandler.EventRangeReport) {
195             (*mHandler.EventRangeReport)(&rangeReportInd);
196         }
197         break;
198 
199     default:
200         ALOGE("handleNanIndication error invalid msg_id:%u", msg_id);
201         res = (int)WIFI_ERROR_INVALID_REQUEST_ID;
202         break;
203     }
204     return res;
205 }
206 
207 //Function which will return the Nan Indication type based on
208 //the initial few bytes of mNanVendorEvent
getIndicationType()209 NanIndicationType NanCommand::getIndicationType()
210 {
211     if (mNanVendorEvent == NULL) {
212         ALOGE("%s: Invalid argument mNanVendorEvent:%p",
213               __func__, mNanVendorEvent);
214         return NAN_INDICATION_UNKNOWN;
215     }
216 
217     NanMsgHeader *pHeader = (NanMsgHeader *)mNanVendorEvent;
218 
219     switch (pHeader->msgId) {
220     case NAN_MSG_ID_PUBLISH_REPLIED_IND:
221         return NAN_INDICATION_PUBLISH_REPLIED;
222     case NAN_MSG_ID_PUBLISH_TERMINATED_IND:
223         return NAN_INDICATION_PUBLISH_TERMINATED;
224     case NAN_MSG_ID_MATCH_IND:
225         return NAN_INDICATION_MATCH;
226     case NAN_MSG_ID_MATCH_EXPIRED_IND:
227         return NAN_INDICATION_MATCH_EXPIRED;
228     case NAN_MSG_ID_FOLLOWUP_IND:
229         return NAN_INDICATION_FOLLOWUP;
230     case NAN_MSG_ID_SUBSCRIBE_TERMINATED_IND:
231         return NAN_INDICATION_SUBSCRIBE_TERMINATED;
232     case  NAN_MSG_ID_DE_EVENT_IND:
233         return NAN_INDICATION_DE_EVENT;
234     case NAN_MSG_ID_DISABLE_IND:
235         return NAN_INDICATION_DISABLED;
236     case NAN_MSG_ID_TCA_IND:
237         return NAN_INDICATION_TCA;
238     case NAN_MSG_ID_BEACON_SDF_IND:
239         return NAN_INDICATION_BEACON_SDF_PAYLOAD;
240     case NAN_MSG_ID_SELF_TRANSMIT_FOLLOWUP_IND:
241         return NAN_INDICATION_SELF_TRANSMIT_FOLLOWUP;
242     case NAN_MSG_ID_RANGING_REQUEST_RECEVD_IND:
243         return NAN_INDICATION_RANGING_REQUEST_RECEIVED;
244     case NAN_MSG_ID_RANGING_RESULT_IND:
245         return NAN_INDICATION_RANGING_RESULT;
246     default:
247         return NAN_INDICATION_UNKNOWN;
248     }
249 }
250 
getNanPublishReplied(NanPublishRepliedInd * event)251 int NanCommand::getNanPublishReplied(NanPublishRepliedInd *event)
252 {
253     if (event == NULL || mNanVendorEvent == NULL) {
254         ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
255               __func__, event, mNanVendorEvent);
256         return WIFI_ERROR_INVALID_ARGS;
257     }
258 
259     pNanPublishRepliedIndMsg pRsp = (pNanPublishRepliedIndMsg)mNanVendorEvent;
260     event->requestor_instance_id = pRsp->publishRepliedIndParams.matchHandle;
261 
262     event->rssi_value = 0;
263     u8 *pInputTlv = pRsp->ptlv;
264     NanTlv outputTlv;
265     u16 readLen = 0;
266     int remainingLen = (mNanDataLen - \
267         (sizeof(NanMsgHeader)));
268 
269     if (remainingLen <= 0) {
270         ALOGI("%s: No TLV's present",__func__);
271         return WIFI_SUCCESS;
272     }
273     while ((remainingLen > 0) &&
274            (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv, remainingLen)))) {
275         switch (outputTlv.type) {
276         case NAN_TLV_TYPE_MAC_ADDRESS:
277             if (outputTlv.length > sizeof(event->addr)) {
278                 outputTlv.length = sizeof(event->addr);
279             }
280             memcpy(event->addr, outputTlv.value, outputTlv.length);
281             break;
282         case NAN_TLV_TYPE_RECEIVED_RSSI_VALUE:
283             if (outputTlv.length > sizeof(event->rssi_value)) {
284                 outputTlv.length = sizeof(event->rssi_value);
285             }
286             memcpy(&event->rssi_value, outputTlv.value,
287                    outputTlv.length);
288             break;
289         default:
290             ALOGI("Unknown TLV type skipped");
291             break;
292         }
293         remainingLen -= readLen;
294         pInputTlv += readLen;
295         memset(&outputTlv, 0, sizeof(outputTlv));
296     }
297     return WIFI_SUCCESS;
298 }
299 
getNanPublishTerminated(NanPublishTerminatedInd * event)300 int NanCommand::getNanPublishTerminated(NanPublishTerminatedInd *event)
301 {
302     if (event == NULL || mNanVendorEvent == NULL) {
303         ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
304               __func__, event, mNanVendorEvent);
305         return WIFI_ERROR_INVALID_ARGS;
306     }
307 
308     pNanPublishTerminatedIndMsg pRsp = (pNanPublishTerminatedIndMsg)mNanVendorEvent;
309     event->publish_id = pRsp->fwHeader.handle;
310     NanErrorTranslation((NanInternalStatusType)pRsp->reason, 0,
311                         (void*)event, false);
312     return WIFI_SUCCESS;
313 }
314 
getNanMatch(NanMatchInd * event)315 int NanCommand::getNanMatch(NanMatchInd *event)
316 {
317     if (event == NULL || mNanVendorEvent == NULL) {
318         ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
319               __func__, event, mNanVendorEvent);
320         return WIFI_ERROR_INVALID_ARGS;
321     }
322 
323     pNanMatchIndMsg pRsp = (pNanMatchIndMsg)mNanVendorEvent;
324     event->publish_subscribe_id = pRsp->fwHeader.handle;
325     event->requestor_instance_id = pRsp->matchIndParams.matchHandle;
326     event->match_occured_flag = pRsp->matchIndParams.matchOccuredFlag;
327     event->out_of_resource_flag = pRsp->matchIndParams.outOfResourceFlag;
328 
329     u8 *pInputTlv = pRsp->ptlv;
330     NanTlv outputTlv;
331     u16 readLen = 0;
332     int remainingLen = (mNanDataLen - \
333         (sizeof(NanMsgHeader) + sizeof(NanMatchIndParams)));
334     int ret = 0, idx = 0;
335 
336     //Has SDF match filter and service specific info TLV
337     if (remainingLen <= 0) {
338         ALOGV("%s: No TLV's present",__func__);
339         return WIFI_SUCCESS;
340     }
341     ALOGV("%s: TLV remaining Len:%d",__func__, remainingLen);
342     while ((remainingLen > 0) &&
343            (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv, remainingLen)))) {
344         ALOGV("%s: Remaining Len:%d readLen:%d type:%d length:%d",
345               __func__, remainingLen, readLen, outputTlv.type,
346               outputTlv.length);
347         switch (outputTlv.type) {
348         case NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO:
349             if (outputTlv.length > NAN_MAX_SERVICE_NAME_LEN) {
350                 outputTlv.length = NAN_MAX_SERVICE_NAME_LEN;
351             }
352             event->service_specific_info_len = outputTlv.length;
353             memcpy(event->service_specific_info, outputTlv.value,
354                    outputTlv.length);
355             break;
356         case NAN_TLV_TYPE_SDF_MATCH_FILTER:
357             if (outputTlv.length > NAN_MAX_MATCH_FILTER_LEN) {
358                 outputTlv.length = NAN_MAX_MATCH_FILTER_LEN;
359             }
360             event->sdf_match_filter_len = outputTlv.length;
361             memcpy(event->sdf_match_filter, outputTlv.value,
362                    outputTlv.length);
363             break;
364         case NAN_TLV_TYPE_MAC_ADDRESS:
365             if (outputTlv.length > sizeof(event->addr)) {
366                 outputTlv.length = sizeof(event->addr);
367             }
368             memcpy(event->addr, outputTlv.value, outputTlv.length);
369             break;
370         case NAN_TLV_TYPE_RECEIVED_RSSI_VALUE:
371             if (outputTlv.length > sizeof(event->rssi_value)) {
372                 outputTlv.length = sizeof(event->rssi_value);
373             }
374             memcpy(&event->rssi_value, outputTlv.value,
375                    outputTlv.length);
376             break;
377         case NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_RECEIVE:
378             if (outputTlv.length != sizeof(u32)) {
379                 ALOGE("NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_RECEIVE"
380                       "Incorrect size:%d expecting %zu", outputTlv.length,
381                       sizeof(u32));
382                 break;
383             }
384             event->is_conn_capability_valid = 1;
385             /* Populate conn_capability from received TLV */
386             getNanReceivePostConnectivityCapabilityVal(outputTlv.value,
387                                                        &event->conn_capability);
388             break;
389         case NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_RECEIVE:
390             /* Populate receive discovery attribute from
391                received TLV */
392             idx = event->num_rx_discovery_attr;
393             if (idx < 0 || idx >= NAN_MAX_POSTDISCOVERY_LEN) {
394                 ALOGE("NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_RECEIVE"
395                       " Incorrect index:%d >= %d", idx, NAN_MAX_POSTDISCOVERY_LEN);
396                 break;
397             }
398             ret = getNanReceivePostDiscoveryVal(outputTlv.value,
399                                                 outputTlv.length,
400                                                 &event->discovery_attr[idx]);
401             if (ret == 0) {
402                 event->num_rx_discovery_attr++;
403             } else {
404                 ALOGE("NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_RECEIVE"
405                       "Incorrect");
406             }
407             break;
408         case NAN_TLV_TYPE_FURTHER_AVAILABILITY_MAP:
409             /* Populate further availability bitmap from
410                received TLV */
411             ret = getNanFurtherAvailabilityMap(outputTlv.value,
412                                                outputTlv.length,
413                                                &event->num_chans,
414                                                &event->famchan[0]);
415             if (ret < 0)
416                 ALOGE("NAN_TLV_TYPE_FURTHER_AVAILABILITY_MAP"
417                       "Incorrect");
418             break;
419         case NAN_TLV_TYPE_CLUSTER_ATTRIBUTE:
420             if (outputTlv.length > sizeof(event->cluster_attribute)) {
421                 outputTlv.length = sizeof(event->cluster_attribute);
422             }
423             memcpy(event->cluster_attribute,
424                    outputTlv.value, outputTlv.length);
425             event->cluster_attribute_len = outputTlv.length;
426             break;
427         case NAN_TLV_TYPE_NAN_CSID:
428             if (outputTlv.length > sizeof(event->peer_cipher_type)) {
429                 outputTlv.length = sizeof(event->peer_cipher_type);
430             }
431             memcpy(&event->peer_cipher_type, outputTlv.value,
432                    outputTlv.length);
433             break;
434         case NAN_TLV_TYPE_NAN_SCID:
435             if (outputTlv.length > sizeof(event->scid)) {
436                 outputTlv.length = sizeof(event->scid);
437             }
438             event->scid_len = outputTlv.length;
439             memcpy(event->scid, outputTlv.value, outputTlv.length);
440             break;
441         case NAN_TLV_TYPE_SDEA_CTRL_PARAMS:
442             if (outputTlv.length != sizeof(u32)) {
443                 ALOGE("NAN_TLV_TYPE_SDEA_CTRL_PARAMS"
444                       "Incorrect size:%d expecting %zu", outputTlv.length,
445                       sizeof(u32));
446                 break;
447             }
448             getNanReceiveSdeaCtrlParams(outputTlv.value,
449                                              &event->peer_sdea_params);
450             break;
451         case NAN_TLV_TYPE_NAN20_RANGING_RESULT:
452             if (outputTlv.length > sizeof(event->range_info)) {
453                 outputTlv.length = sizeof(event->range_info);
454             }
455             memcpy(&event->range_info, outputTlv.value, outputTlv.length);
456             break;
457         case NAN_TLV_TYPE_SDEA_SERVICE_SPECIFIC_INFO:
458             if (outputTlv.length > NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN) {
459                 outputTlv.length = NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN;
460             }
461             event->sdea_service_specific_info_len = outputTlv.length;
462             memcpy(event->sdea_service_specific_info, outputTlv.value,
463                    outputTlv.length);
464             break;
465         case NAN_TLV_TYPE_SERVICE_ID:
466             mNanCommandInstance->saveServiceId(outputTlv.value,
467                                                event->publish_subscribe_id,
468                                                event->requestor_instance_id,
469                                                NAN_ROLE_SUBSCRIBER);
470             break;
471         default:
472             ALOGV("Unknown TLV type skipped");
473             break;
474         }
475         remainingLen -= readLen;
476         pInputTlv += readLen;
477         memset(&outputTlv, 0, sizeof(outputTlv));
478     }
479     return WIFI_SUCCESS;
480 }
481 
getNanMatchExpired(NanMatchExpiredInd * event)482 int NanCommand::getNanMatchExpired(NanMatchExpiredInd *event)
483 {
484     if (event == NULL || mNanVendorEvent == NULL) {
485         ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
486               __func__, event, mNanVendorEvent);
487         return WIFI_ERROR_INVALID_ARGS;
488     }
489 
490     pNanMatchExpiredIndMsg pRsp = (pNanMatchExpiredIndMsg)mNanVendorEvent;
491     event->publish_subscribe_id = pRsp->fwHeader.handle;
492     event->requestor_instance_id = pRsp->matchExpiredIndParams.matchHandle;
493     return WIFI_SUCCESS;
494 }
495 
getNanSubscribeTerminated(NanSubscribeTerminatedInd * event)496 int NanCommand::getNanSubscribeTerminated(NanSubscribeTerminatedInd *event)
497 {
498     if (event == NULL || mNanVendorEvent == NULL) {
499         ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
500               __func__, event, mNanVendorEvent);
501         return WIFI_ERROR_INVALID_ARGS;
502     }
503 
504     pNanSubscribeTerminatedIndMsg pRsp = (pNanSubscribeTerminatedIndMsg)mNanVendorEvent;
505     event->subscribe_id = pRsp->fwHeader.handle;
506     NanErrorTranslation((NanInternalStatusType)pRsp->reason, 0,
507                         (void*)event, false);
508     return WIFI_SUCCESS;
509 }
510 
getNanFollowup(NanFollowupInd * event)511 int NanCommand::getNanFollowup(NanFollowupInd *event)
512 {
513     if (event == NULL || mNanVendorEvent == NULL) {
514         ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
515               __func__, event, mNanVendorEvent);
516         return WIFI_ERROR_INVALID_ARGS;
517     }
518 
519     pNanFollowupIndMsg pRsp = (pNanFollowupIndMsg)mNanVendorEvent;
520     event->publish_subscribe_id = pRsp->fwHeader.handle;
521     event->requestor_instance_id = pRsp->followupIndParams.matchHandle;
522     event->dw_or_faw = pRsp->followupIndParams.window;
523 
524     u8 *pInputTlv = pRsp->ptlv;
525     NanTlv outputTlv;
526     u16 readLen = 0;
527     int remainingLen = (mNanDataLen -  \
528         (sizeof(NanMsgHeader) + sizeof(NanFollowupIndParams)));
529 
530     //Has service specific info and extended service specific info TLV
531     if (remainingLen <= 0) {
532         ALOGV("%s: No TLV's present",__func__);
533         return WIFI_SUCCESS;
534     }
535     ALOGV("%s: TLV remaining Len:%d",__func__, remainingLen);
536     while ((remainingLen > 0) &&
537            (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv, remainingLen)))) {
538         ALOGV("%s: Remaining Len:%d readLen:%d type:%d length:%d",
539               __func__, remainingLen, readLen, outputTlv.type,
540               outputTlv.length);
541         switch (outputTlv.type) {
542         case NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO:
543         case NAN_TLV_TYPE_EXT_SERVICE_SPECIFIC_INFO:
544             if (outputTlv.length > NAN_MAX_SERVICE_SPECIFIC_INFO_LEN) {
545                 outputTlv.length = NAN_MAX_SERVICE_SPECIFIC_INFO_LEN;
546             }
547             event->service_specific_info_len = outputTlv.length;
548             memcpy(event->service_specific_info, outputTlv.value,
549                    outputTlv.length);
550             break;
551         case NAN_TLV_TYPE_MAC_ADDRESS:
552             if (outputTlv.length > sizeof(event->addr)) {
553                 outputTlv.length = sizeof(event->addr);
554             }
555             memcpy(event->addr, outputTlv.value, outputTlv.length);
556             break;
557         case NAN_TLV_TYPE_SDEA_SERVICE_SPECIFIC_INFO:
558             if (outputTlv.length > NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN) {
559                 outputTlv.length = NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN;
560             }
561             event->sdea_service_specific_info_len = outputTlv.length;
562             memcpy(event->sdea_service_specific_info, outputTlv.value,
563                    outputTlv.length);
564             break;
565         default:
566             ALOGV("Unknown TLV type skipped");
567             break;
568         }
569         remainingLen -= readLen;
570         pInputTlv += readLen;
571         memset(&outputTlv, 0, sizeof(outputTlv));
572     }
573     return WIFI_SUCCESS;
574 }
575 
getNanDiscEngEvent(NanDiscEngEventInd * event)576 int NanCommand::getNanDiscEngEvent(NanDiscEngEventInd *event)
577 {
578     if (event == NULL || mNanVendorEvent == NULL) {
579         ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
580               __func__, event, mNanVendorEvent);
581         return WIFI_ERROR_INVALID_ARGS;
582     }
583 
584     pNanEventIndMsg pRsp = (pNanEventIndMsg)mNanVendorEvent;
585     memset(&event->data, 0, sizeof(event->data));
586 
587     u8 *pInputTlv = pRsp->ptlv;
588     NanTlv outputTlv;
589     u16 readLen = 0;
590     int remainingLen = (mNanDataLen -  \
591         (sizeof(NanMsgHeader)));
592 
593     //Has Self-STA Mac TLV
594     if (remainingLen <= 0) {
595         ALOGE("%s: No TLV's present",__func__);
596         return WIFI_SUCCESS;
597     }
598 
599     ALOGV("%s: TLV remaining Len:%d",__func__, remainingLen);
600     while ((remainingLen > 0) &&
601            (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv, remainingLen)))) {
602         ALOGV("%s: Remaining Len:%d readLen:%d type:%d length:%d",
603               __func__, remainingLen, readLen, outputTlv.type,
604               outputTlv.length);
605         switch (outputTlv.type) {
606         case NAN_TLV_TYPE_EVENT_SELF_STATION_MAC_ADDRESS:
607             if (outputTlv.length > NAN_MAC_ADDR_LEN) {
608                 ALOGV("%s: Reading only first %d bytes of TLV",
609                       __func__, NAN_MAC_ADDR_LEN);
610                 outputTlv.length = NAN_MAC_ADDR_LEN;
611             }
612             memcpy(event->data.mac_addr.addr, outputTlv.value,
613                    outputTlv.length);
614             event->event_type = NAN_EVENT_ID_DISC_MAC_ADDR;
615             break;
616         case NAN_TLV_TYPE_EVENT_STARTED_CLUSTER:
617             if (outputTlv.length > NAN_MAC_ADDR_LEN) {
618                 ALOGV("%s: Reading only first %d bytes of TLV",
619                       __func__, NAN_MAC_ADDR_LEN);
620                 outputTlv.length = NAN_MAC_ADDR_LEN;
621             }
622             memcpy(event->data.cluster.addr, outputTlv.value,
623                    outputTlv.length);
624             event->event_type = NAN_EVENT_ID_STARTED_CLUSTER;
625             break;
626         case NAN_TLV_TYPE_EVENT_JOINED_CLUSTER:
627             if (outputTlv.length > NAN_MAC_ADDR_LEN) {
628                 ALOGV("%s: Reading only first %d bytes of TLV",
629                       __func__, NAN_MAC_ADDR_LEN);
630                 outputTlv.length = NAN_MAC_ADDR_LEN;
631             }
632             memcpy(event->data.cluster.addr, outputTlv.value,
633                    outputTlv.length);
634             event->event_type = NAN_EVENT_ID_JOINED_CLUSTER;
635             break;
636         default:
637             ALOGV("Unhandled TLV type:%d", outputTlv.type);
638             break;
639         }
640         remainingLen -= readLen;
641         pInputTlv += readLen;
642         memset(&outputTlv,0, sizeof(outputTlv));
643     }
644     return WIFI_SUCCESS;
645 }
646 
getNanDisabled(NanDisabledInd * event)647 int NanCommand::getNanDisabled(NanDisabledInd *event)
648 {
649     if (event == NULL || mNanVendorEvent == NULL) {
650         ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
651               __func__, event, mNanVendorEvent);
652         return WIFI_ERROR_INVALID_ARGS;
653     }
654 
655     pNanDisableIndMsg pRsp = (pNanDisableIndMsg)mNanVendorEvent;
656     NanErrorTranslation((NanInternalStatusType)pRsp->reason, 0,
657                         (void*)event, false);
658     return WIFI_SUCCESS;
659 
660 }
661 
getNanTca(NanTCAInd * event)662 int NanCommand::getNanTca(NanTCAInd *event)
663 {
664     if (event == NULL || mNanVendorEvent == NULL) {
665         ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
666               __func__, event, mNanVendorEvent);
667         return WIFI_ERROR_INVALID_ARGS;
668     }
669 
670     pNanTcaIndMsg pRsp = (pNanTcaIndMsg)mNanVendorEvent;
671     memset(&event->data, 0, sizeof(event->data));
672 
673     u8 *pInputTlv = pRsp->ptlv;
674     NanTlv outputTlv;
675     u16 readLen = 0;
676 
677     int remainingLen = (mNanDataLen -  \
678         (sizeof(NanMsgHeader)));
679 
680     //Has NAN_TCA_ID_CLUSTER_SIZE
681     if (remainingLen <= 0) {
682         ALOGE("%s: No TLV's present",__func__);
683         return WIFI_SUCCESS;
684     }
685 
686     ALOGV("%s: TLV remaining Len:%d",__func__, remainingLen);
687     while ((remainingLen > 0) &&
688            (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv, remainingLen)))) {
689         ALOGV("%s: Remaining Len:%d readLen:%d type:%d length:%d",
690               __func__, remainingLen, readLen, outputTlv.type,
691               outputTlv.length);
692         switch (outputTlv.type) {
693         case NAN_TLV_TYPE_CLUSTER_SIZE_RSP:
694             if (outputTlv.length != 2 * sizeof(u32)) {
695                 ALOGE("%s: Wrong length %d in Tca Indication expecting %zu bytes",
696                       __func__, outputTlv.length, 2 * sizeof(u32));
697                 break;
698             }
699             event->rising_direction_evt_flag = outputTlv.value[0] & 0x01;
700             event->falling_direction_evt_flag = (outputTlv.value[0] & 0x02) >> 1;
701             memcpy(&(event->data.cluster.cluster_size), &outputTlv.value[4],
702                    sizeof(event->data.cluster.cluster_size));
703             event->tca_type = NAN_TCA_ID_CLUSTER_SIZE;
704             break;
705         default:
706             ALOGV("Unhandled TLV type:%d", outputTlv.type);
707             break;
708         }
709         remainingLen -= readLen;
710         pInputTlv += readLen;
711         memset(&outputTlv,0, sizeof(outputTlv));
712     }
713     return WIFI_SUCCESS;
714 }
715 
getNanBeaconSdfPayload(NanBeaconSdfPayloadInd * event)716 int NanCommand::getNanBeaconSdfPayload(NanBeaconSdfPayloadInd *event)
717 {
718     if (event == NULL || mNanVendorEvent == NULL) {
719         ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
720               __func__, event, mNanVendorEvent);
721         return WIFI_ERROR_INVALID_ARGS;
722     }
723 
724     pNanBeaconSdfPayloadIndMsg pRsp = (pNanBeaconSdfPayloadIndMsg)mNanVendorEvent;
725     memset(&event->data, 0, sizeof(event->data));
726 
727     u8 *pInputTlv = pRsp->ptlv;
728     NanTlv outputTlv;
729     u16 readLen = 0;
730     int remainingLen = (mNanDataLen -  \
731         (sizeof(NanMsgHeader)));
732 
733     //Has Mac address
734     if (remainingLen <= 0) {
735         ALOGV("%s: No TLV's present",__func__);
736         return WIFI_SUCCESS;
737     }
738 
739     ALOGV("%s: TLV remaining Len:%d",__func__, remainingLen);
740     while ((remainingLen > 0) &&
741            (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv, remainingLen)))) {
742         ALOGV("%s: Remaining Len:%d readLen:%d type:%d length:%d",
743               __func__, remainingLen, readLen, outputTlv.type,
744               outputTlv.length);
745         switch (outputTlv.type) {
746         case NAN_TLV_TYPE_MAC_ADDRESS:
747             if (outputTlv.length > sizeof(event->addr)) {
748                 outputTlv.length = sizeof(event->addr);
749             }
750             memcpy(event->addr, outputTlv.value,
751                    outputTlv.length);
752             break;
753 
754         case NAN_TLV_TYPE_VENDOR_SPECIFIC_ATTRIBUTE_RECEIVE:
755         {
756             NanReceiveVendorSpecificAttribute* recvVsaattr = &event->vsa;
757             if (outputTlv.length < sizeof(u32)) {
758                 ALOGE("NAN_TLV_TYPE_VENDOR_SPECIFIC_ATTRIBUTE_RECEIVE"
759                       "Incorrect length:%d", outputTlv.length);
760                 break;
761             }
762             event->is_vsa_received = 1;
763             recvVsaattr->vsa_received_on = (outputTlv.value[0] >> 1) & 0x07;
764             memcpy(&recvVsaattr->vendor_oui, &outputTlv.value[1],
765                    3);
766             recvVsaattr->attr_len = outputTlv.length - 4;
767             if (recvVsaattr->attr_len > NAN_MAX_VSA_DATA_LEN) {
768                 recvVsaattr->attr_len = NAN_MAX_VSA_DATA_LEN;
769             }
770             if (recvVsaattr->attr_len) {
771                 memcpy(recvVsaattr->vsa, &outputTlv.value[4],
772                        recvVsaattr->attr_len);
773             }
774             break;
775         }
776 
777         case NAN_TLV_TYPE_BEACON_SDF_PAYLOAD_RECEIVE:
778             event->is_beacon_sdf_payload_received = 1;
779             event->data.frame_len = outputTlv.length;
780             if (event->data.frame_len > NAN_MAX_FRAME_DATA_LEN) {
781                 event->data.frame_len = NAN_MAX_FRAME_DATA_LEN;
782             }
783             memcpy(&event->data.frame_data, &outputTlv.value[0],
784                    event->data.frame_len);
785             break;
786 
787         default:
788             ALOGV("Unhandled TLV Type:%d", outputTlv.type);
789             break;
790         }
791         remainingLen -= readLen;
792         pInputTlv += readLen;
793         memset(&outputTlv,0, sizeof(outputTlv));
794     }
795     return WIFI_SUCCESS;
796 }
797 
getNanReceivePostConnectivityCapabilityVal(const u8 * pInValue,NanReceivePostConnectivityCapability * pRxCapab)798 void NanCommand::getNanReceivePostConnectivityCapabilityVal(
799     const u8 *pInValue,
800     NanReceivePostConnectivityCapability *pRxCapab)
801 {
802     if (pInValue && pRxCapab) {
803         pRxCapab->is_mesh_supported = (pInValue[0] & (0x01 << 5));
804         pRxCapab->is_ibss_supported = (pInValue[0] & (0x01 << 4));
805         pRxCapab->wlan_infra_field = (pInValue[0] & (0x01 << 3));
806         pRxCapab->is_tdls_supported = (pInValue[0] & (0x01 << 2));
807         pRxCapab->is_wfds_supported = (pInValue[0] & (0x01 << 1));
808         pRxCapab->is_wfd_supported = pInValue[0] & 0x01;
809     }
810 }
811 
getNanReceiveSdeaCtrlParams(const u8 * pInValue,NanSdeaCtrlParams * pPeerSdeaParams)812 void NanCommand::getNanReceiveSdeaCtrlParams(const u8* pInValue,
813     NanSdeaCtrlParams *pPeerSdeaParams)
814 {
815     if (pInValue && pPeerSdeaParams) {
816         pPeerSdeaParams->security_cfg =
817                           (NanDataPathSecurityCfgStatus)((pInValue[0] & BIT_6) ?
818                            NAN_DP_CONFIG_SECURITY : NAN_DP_CONFIG_NO_SECURITY);
819         pPeerSdeaParams->ranging_state =
820                            (NanRangingState)((pInValue[0] & BIT_7) ?
821                             NAN_RANGING_ENABLE : NAN_RANGING_DISABLE);
822 #if 0
823         pPeerSdeaParams->enable_ranging_limit =
824                          (NanRangingLimitState)((pInValue[0] & BIT_8) ?
825                           NAN_RANGING_LIMIT_ENABLE : NAN_RANGING_LIMIT_DISABLE);
826 #endif
827     }
828     return;
829 }
830 
getNanReceivePostDiscoveryVal(const u8 * pInValue,u32 length,NanReceivePostDiscovery * pRxDisc)831 int NanCommand::getNanReceivePostDiscoveryVal(const u8 *pInValue,
832                                               u32 length,
833                                               NanReceivePostDiscovery *pRxDisc)
834 {
835     int ret = 0;
836 
837     if (length <= 8 || pInValue == NULL) {
838         ALOGE("%s: Invalid Arg TLV Len %d < 4",
839               __func__, length);
840         return -1;
841     }
842 
843     pRxDisc->type = (NanConnectionType) pInValue[0];
844     pRxDisc->role = (NanDeviceRole) pInValue[1];
845     pRxDisc->duration = (NanAvailDuration) (pInValue[2] & 0x03);
846     pRxDisc->mapid = ((pInValue[2] >> 2) & 0x0F);
847     memcpy(&pRxDisc->avail_interval_bitmap,
848            &pInValue[4],
849            sizeof(pRxDisc->avail_interval_bitmap));
850 
851     u8 *pInputTlv = (u8 *)&pInValue[8];
852     NanTlv outputTlv;
853     u16 readLen = 0;
854     int remainingLen = (length - 8);
855 
856     //Has Mac address
857     if (remainingLen <= 0) {
858         ALOGE("%s: No TLV's present",__func__);
859         return -1;
860     }
861 
862     ALOGV("%s: TLV remaining Len:%d",__func__, remainingLen);
863     while ((remainingLen > 0) &&
864            (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv, remainingLen)))) {
865         ALOGV("%s: Remaining Len:%d readLen:%d type:%d length:%d",
866               __func__, remainingLen, readLen, outputTlv.type,
867               outputTlv.length);
868         switch (outputTlv.type) {
869         case NAN_TLV_TYPE_MAC_ADDRESS:
870             if (outputTlv.length > sizeof(pRxDisc->addr)) {
871                 outputTlv.length = sizeof(pRxDisc->addr);
872             }
873             memcpy(pRxDisc->addr, outputTlv.value, outputTlv.length);
874             break;
875         case NAN_TLV_TYPE_WLAN_MESH_ID:
876             if (outputTlv.length > sizeof(pRxDisc->mesh_id)) {
877                 outputTlv.length = sizeof(pRxDisc->mesh_id);
878             }
879             memcpy(pRxDisc->mesh_id, outputTlv.value, outputTlv.length);
880             pRxDisc->mesh_id_len = outputTlv.length;
881             break;
882         case NAN_TLV_TYPE_WLAN_INFRA_SSID:
883             if (outputTlv.length > sizeof(pRxDisc->infrastructure_ssid_val)) {
884                 outputTlv.length = sizeof(pRxDisc->infrastructure_ssid_val);
885             }
886             memcpy(pRxDisc->infrastructure_ssid_val, outputTlv.value,
887                    outputTlv.length);
888             pRxDisc->infrastructure_ssid_len = outputTlv.length;
889             break;
890         default:
891             ALOGV("Unhandled TLV Type:%d", outputTlv.type);
892             break;
893         }
894         remainingLen -= readLen;
895         pInputTlv += readLen;
896         memset(&outputTlv,0, sizeof(outputTlv));
897     }
898     return ret;
899 }
900 
getNanFurtherAvailabilityMap(const u8 * pInValue,u32 length,u8 * num_chans,NanFurtherAvailabilityChannel * pFac)901 int NanCommand::getNanFurtherAvailabilityMap(const u8 *pInValue,
902                                              u32 length,
903                                              u8 *num_chans,
904                                              NanFurtherAvailabilityChannel *pFac)
905 {
906     int idx = 0;
907 
908     if ((length == 0) || pInValue == NULL) {
909         ALOGE("%s: Invalid Arg TLV Len %d or pInValue NULL",
910               __func__, length);
911         return -1;
912     }
913 
914     *num_chans = pInValue[0];
915     if (*num_chans > NAN_MAX_FAM_CHANNELS) {
916         ALOGE("%s: Unable to accommodate numchans %d",
917               __func__, *num_chans);
918         return -1;
919     }
920 
921     if (length < (sizeof(u8) +
922         (*num_chans * sizeof(NanFurtherAvailabilityChan)))) {
923         ALOGE("%s: Invalid TLV Length", __func__);
924         return -1;
925     }
926 
927     for (idx = 0; idx < *num_chans; idx++) {
928         pNanFurtherAvailabilityChan pRsp = \
929               (pNanFurtherAvailabilityChan)((u8 *)&pInValue[1] + \
930               (idx * sizeof(NanFurtherAvailabilityChan)));
931 
932         pFac->entry_control = \
933             (NanAvailDuration)(pRsp->entryCtrl.availIntDuration);
934         pFac->mapid = pRsp->entryCtrl.mapId;
935         pFac->class_val = pRsp->opClass;
936         pFac->channel = pRsp->channel;
937         memcpy(&pFac->avail_interval_bitmap,
938                &pRsp->availIntBitmap,
939                sizeof(pFac->avail_interval_bitmap));
940         pFac++;
941     }
942     return 0;
943 }
944 
getNanStaParameter(wifi_interface_handle iface,NanStaParameter * pRsp)945 wifi_error NanCommand::getNanStaParameter(wifi_interface_handle iface,
946                                    NanStaParameter *pRsp)
947 {
948     wifi_error ret = WIFI_ERROR_NONE;
949     transaction_id id = 1;
950     interface_info *ifaceInfo = getIfaceInfo(iface);
951 
952     ret = create();
953     if (ret != WIFI_SUCCESS)
954         goto cleanup;
955 
956     /* Set the interface Id of the message. */
957     ret = set_iface_id(ifaceInfo->name);
958     if (ret != WIFI_SUCCESS)
959         goto cleanup;
960 
961     /*
962        Construct NL message to get the sync stats parameter
963        which has all the parameter required by staparameter.
964     */
965     NanStatsRequest syncStats;
966     memset(&syncStats, 0, sizeof(syncStats));
967     syncStats.stats_type = NAN_STATS_ID_DE_TIMING_SYNC;
968     syncStats.clear = 0;
969 
970     mStaParam = pRsp;
971     ret = putNanStats(id, &syncStats);
972     if (ret != WIFI_SUCCESS) {
973         ALOGE("%s: putNanStats Error:%d",__func__, ret);
974         goto cleanup;
975     }
976     ret = requestEvent();
977     if (ret != 0) {
978         ALOGE("%s: requestEvent Error:%d",__func__, ret);
979         goto cleanup;
980     }
981 
982     struct timespec abstime;
983     abstime.tv_sec = 4;
984     abstime.tv_nsec = 0;
985     ret = mCondition.wait(abstime);
986     if (ret == WIFI_ERROR_TIMED_OUT)
987     {
988         ALOGE("%s: Time out happened.", __func__);
989         goto cleanup;
990     }
991     ALOGV("%s: NanStaparameter Master_pref:%x," \
992           " Random_factor:%x, hop_count:%x " \
993           " beacon_transmit_time:%d" \
994           " ndp_channel_freq:%d", __func__,
995           pRsp->master_pref, pRsp->random_factor,
996           pRsp->hop_count, pRsp->beacon_transmit_time, pRsp->ndp_channel_freq);
997 cleanup:
998     mStaParam = NULL;
999     return ret;
1000 }
1001 
getNanTransmitFollowupInd(NanTransmitFollowupInd * event)1002 int NanCommand::getNanTransmitFollowupInd(NanTransmitFollowupInd *event)
1003 {
1004     if (event == NULL || mNanVendorEvent == NULL) {
1005         ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
1006               __func__, event, mNanVendorEvent);
1007         return WIFI_ERROR_INVALID_ARGS;
1008     }
1009 
1010     pNanSelfTransmitFollowupIndMsg pRsp = (pNanSelfTransmitFollowupIndMsg)mNanVendorEvent;
1011     event->id = pRsp->fwHeader.transactionId;
1012     NanErrorTranslation((NanInternalStatusType)pRsp->reason, 0,
1013                         (void*)event, false);
1014     return WIFI_SUCCESS;
1015 }
1016 
1017 //Function which calls the necessaryIndication callback
1018 //based on the indication type
handleNdpIndication(u32 ndpCmdType,struct nlattr ** tb_vendor)1019 int NanCommand::handleNdpIndication(u32 ndpCmdType, struct nlattr **tb_vendor)
1020 {
1021     //Based on the message_id in the header determine the Indication type
1022     //and call the necessary callback handler
1023     int res = 0;
1024 
1025     ALOGI("handleNdpIndication msg_id:%u", ndpCmdType);
1026     switch (ndpCmdType) {
1027     case QCA_WLAN_VENDOR_ATTR_NDP_REQUEST_IND:
1028         NanDataPathRequestInd ndpRequestInd;
1029         memset(&ndpRequestInd, 0, sizeof(ndpRequestInd));
1030 
1031         res = getNdpRequest(tb_vendor, &ndpRequestInd);
1032         if (!res && mHandler.EventDataRequest) {
1033             (*mHandler.EventDataRequest)(&ndpRequestInd);
1034         }
1035         break;
1036 
1037     case QCA_WLAN_VENDOR_ATTR_NDP_CONFIRM_IND:
1038         NanDataPathConfirmInd ndpConfirmInd;
1039         memset(&ndpConfirmInd, 0, sizeof(ndpConfirmInd));
1040 
1041         res = getNdpConfirm(tb_vendor, &ndpConfirmInd);
1042         if (!res && mHandler.EventDataConfirm) {
1043             (*mHandler.EventDataConfirm)(&ndpConfirmInd);
1044         }
1045         break;
1046 
1047     case QCA_WLAN_VENDOR_ATTR_NDP_END_IND:
1048     {
1049         NanDataPathEndInd *ndpEndInd = NULL;
1050         u8 num_ndp_ids = 0;
1051         u8 i;
1052 
1053         if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]) {
1054             ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP not found", __FUNCTION__);
1055             return WIFI_ERROR_INVALID_ARGS;
1056         }
1057 
1058         num_ndp_ids = (u8)(nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY])/sizeof(u32));
1059         ALOGD("%s: NDP Num Instance Ids : val %d", __FUNCTION__, num_ndp_ids);
1060 
1061         if (num_ndp_ids) {
1062             ndpEndInd =
1063                 (NanDataPathEndInd *)malloc(sizeof(NanDataPathEndInd)+ (sizeof(u32) * num_ndp_ids));
1064             if (!ndpEndInd) {
1065                 ALOGE("%s: ndp_instance_id malloc Failed", __FUNCTION__);
1066                 return WIFI_ERROR_OUT_OF_MEMORY;
1067             }
1068             ndpEndInd->num_ndp_instances = num_ndp_ids;
1069             nla_memcpy(ndpEndInd->ndp_instance_id,
1070                        tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY],
1071                        sizeof(u32) * ndpEndInd->num_ndp_instances);
1072         }
1073         for (i = 0; i < num_ndp_ids; i++) {
1074             mNanCommandInstance->deleteServiceId(0,
1075                                                  ndpEndInd->ndp_instance_id[i],
1076                                                  NAN_ROLE_PUBLISHER);
1077         }
1078         if (mHandler.EventDataEnd) {
1079             (*mHandler.EventDataEnd)(ndpEndInd);
1080         }
1081         free(ndpEndInd);
1082         break;
1083     }
1084 
1085     case QCA_WLAN_VENDOR_ATTR_NDP_SCHEDULE_UPDATE_IND:
1086     {
1087         NanDataPathScheduleUpdateInd *pNdpScheduleUpdateInd;
1088         u32 num_channels = 0, num_ndp_ids = 0;
1089 
1090         if ((!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]) ||
1091             (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_SCHEDULE_UPDATE_REASON]) ||
1092             (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY])) {
1093             ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP not found", __FUNCTION__);
1094             return WIFI_ERROR_INVALID_ARGS;
1095         }
1096         if (tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_NUM_CHANNELS]) {
1097              num_channels = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_NUM_CHANNELS]);
1098              ALOGD("%s: num_channels = %d", __FUNCTION__, num_channels);
1099              if ((num_channels > NAN_MAX_CHANNEL_INFO_SUPPORTED) &&
1100                  (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO])) {
1101                  ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO not found", __FUNCTION__);
1102                  return WIFI_ERROR_INVALID_ARGS;
1103             }
1104         }
1105         num_ndp_ids = (u8)(nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY])/sizeof(u32));
1106         ALOGD("%s: NDP Num Instance Ids : val %d", __FUNCTION__, num_ndp_ids);
1107 
1108         pNdpScheduleUpdateInd =
1109             (NanDataPathScheduleUpdateInd *)malloc(sizeof(NanDataPathScheduleUpdateInd)
1110             + (sizeof(u32) * num_ndp_ids));
1111         if (!pNdpScheduleUpdateInd) {
1112             ALOGE("%s: NdpScheduleUpdate malloc Failed", __FUNCTION__);
1113             return WIFI_ERROR_OUT_OF_MEMORY;
1114         }
1115         pNdpScheduleUpdateInd->num_channels = num_channels;
1116         pNdpScheduleUpdateInd->num_ndp_instances = num_ndp_ids;
1117 
1118         res = getNdpScheduleUpdate(tb_vendor, pNdpScheduleUpdateInd);
1119         if (!res && mHandler.EventScheduleUpdate) {
1120             (*mHandler.EventScheduleUpdate)(pNdpScheduleUpdateInd);
1121         }
1122         free(pNdpScheduleUpdateInd);
1123         break;
1124     }
1125     default:
1126         ALOGE("handleNdpIndication error invalid ndpCmdType:%u", ndpCmdType);
1127         res = (int)WIFI_ERROR_INVALID_REQUEST_ID;
1128         break;
1129     }
1130     return res;
1131 }
1132 
getNdpRequest(struct nlattr ** tb_vendor,NanDataPathRequestInd * event)1133 int NanCommand::getNdpRequest(struct nlattr **tb_vendor,
1134                               NanDataPathRequestInd *event)
1135 {
1136     u32 len = 0;
1137 
1138     if (event == NULL || tb_vendor == NULL) {
1139         ALOGE("%s: Invalid input argument event:%p tb_vendor:%p",
1140               __FUNCTION__, event, tb_vendor);
1141         return WIFI_ERROR_INVALID_ARGS;
1142     }
1143     if ((!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID]) ||
1144         (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]) ||
1145         (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID])) {
1146         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP not found", __FUNCTION__);
1147         return WIFI_ERROR_INVALID_ARGS;
1148     }
1149 
1150     event->service_instance_id = nla_get_u16(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID]);
1151     ALOGD("%s: Service Instance id : val %d", __FUNCTION__, event->service_instance_id);
1152 
1153     len = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]);
1154     len = ((sizeof(event->peer_disc_mac_addr) <= len) ? sizeof(event->peer_disc_mac_addr) : len);
1155     memcpy(&event->peer_disc_mac_addr[0], nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]), len);
1156 
1157     event->ndp_instance_id = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]);
1158     ALOGD("%s: Ndp Instance id: %d", __FUNCTION__, event->ndp_instance_id);
1159     if (tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]) {
1160         len = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]);
1161         len = ((sizeof(event->app_info.ndp_app_info) <= len) ? sizeof(event->app_info.ndp_app_info) : len);
1162         memcpy(&event->app_info.ndp_app_info[0], nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]), len);
1163         event->app_info.ndp_app_info_len = len;
1164     } else {
1165         ALOGD("%s: NDP App Info not present", __FUNCTION__);
1166     }
1167 
1168     if (tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_ID]) {
1169             mNanCommandInstance->saveServiceId((u8 *)nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_ID]),
1170                                                event->service_instance_id,
1171                                                event->ndp_instance_id,
1172                                                NAN_ROLE_PUBLISHER);
1173     } else {
1174         ALOGD("%s: Service ID not present", __FUNCTION__);
1175     }
1176 
1177     return WIFI_SUCCESS;
1178 }
1179 
getNdpConfirm(struct nlattr ** tb_vendor,NanDataPathConfirmInd * event)1180 int NanCommand::getNdpConfirm(struct nlattr **tb_vendor,
1181                               NanDataPathConfirmInd *event)
1182 {
1183     u32 len = 0;
1184     NanInternalStatusType drv_reason_code;
1185     struct nlattr *chInfo;
1186     NanChannelInfo *pChInfo;
1187     int rem;
1188     u32 i = 0;
1189 
1190     if (event == NULL || tb_vendor == NULL) {
1191         ALOGE("%s: Invalid input argument event:%p tb_vendor:%p",
1192               __FUNCTION__, event, tb_vendor);
1193         return WIFI_ERROR_INVALID_ARGS;
1194     }
1195     if ((!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]) ||
1196         (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR]) ||
1197         (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE])) {
1198         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP not found", __FUNCTION__);
1199         return WIFI_ERROR_INVALID_ARGS;
1200     }
1201 
1202     event->ndp_instance_id = nla_get_u16(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]);
1203     ALOGD("%s: Service Instance id : val %d", __FUNCTION__, event->ndp_instance_id);
1204 
1205     len = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR]);
1206     len = ((sizeof(event->peer_ndi_mac_addr) <= len) ? sizeof(event->peer_ndi_mac_addr) : len);
1207     memcpy(&event->peer_ndi_mac_addr[0], nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR]), len);
1208 
1209     event->rsp_code = (NanDataPathResponseCode)nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE]);
1210     ALOGD("%s: Response code %d", __FUNCTION__, event->rsp_code);
1211 
1212     if (tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]) {
1213         len = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]);
1214         len = ((sizeof(event->app_info.ndp_app_info) <= len) ? sizeof(event->app_info.ndp_app_info) : len);
1215         memcpy(&event->app_info.ndp_app_info[0], nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]), len);
1216         event->app_info.ndp_app_info_len = len;
1217     } else {
1218         ALOGD("%s: NDP App Info not present", __FUNCTION__);
1219     }
1220     drv_reason_code = (NanInternalStatusType)nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE]);
1221     ALOGD("%s: Drv reason code %d", __FUNCTION__, drv_reason_code);
1222     switch (drv_reason_code) {
1223         case NDP_I_MGMT_FRAME_REQUEST_FAILED:
1224         case NDP_I_MGMT_FRAME_RESPONSE_FAILED:
1225         case NDP_I_MGMT_FRAME_CONFIRM_FAILED:
1226         case NDP_I_MGMT_FRAME_END_REQUEST_FAILED:
1227         case NDP_I_MGMT_FRAME_SECURITY_INSTALL_FAILED:
1228             event->reason_code = NAN_STATUS_PROTOCOL_FAILURE;
1229             break;
1230         case NDP_I_END_FAILED:
1231             event->reason_code = NAN_STATUS_INTERNAL_FAILURE;
1232             break;
1233         default:
1234             event->reason_code = (NanStatusType)drv_reason_code;
1235             break;
1236     }
1237     ALOGD("%s: Reason code %d", __FUNCTION__, event->reason_code);
1238 
1239     if (tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_NUM_CHANNELS]) {
1240         event->num_channels =
1241             nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_NUM_CHANNELS]);
1242         ALOGD("%s: num_channels = %d", __FUNCTION__, event->num_channels);
1243         if ((event->num_channels > NAN_MAX_CHANNEL_INFO_SUPPORTED) &&
1244             (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO])) {
1245             ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO not found", __FUNCTION__);
1246             return WIFI_ERROR_INVALID_ARGS;
1247         }
1248     }
1249 
1250     if (event->num_channels != 0) {
1251         for (chInfo =
1252             (struct nlattr *) nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO]),
1253             rem = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO]);
1254             (i < NAN_MAX_CHANNEL_INFO_SUPPORTED && nla_ok(chInfo, rem));
1255             chInfo = nla_next(chInfo, &(rem))) {
1256              struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1];
1257 
1258              pChInfo =
1259                  (NanChannelInfo *) ((u8 *)event->channel_info + (i++ * (sizeof(NanChannelInfo))));
1260              nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX,
1261                  (struct nlattr *) nla_data(chInfo), nla_len(chInfo), NULL);
1262 
1263             if (!tb2[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL]) {
1264                 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_CHANNEL not found", __FUNCTION__);
1265                 return WIFI_ERROR_INVALID_ARGS;
1266             }
1267             pChInfo->channel = nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL]);
1268             ALOGD("%s: Channel = %d", __FUNCTION__, pChInfo->channel);
1269 
1270             if (!tb2[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_WIDTH]) {
1271                 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_WIDTH not found", __FUNCTION__);
1272                 return WIFI_ERROR_INVALID_ARGS;
1273             }
1274             pChInfo->bandwidth = nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_WIDTH]);
1275             ALOGD("%s: Channel BW = %d", __FUNCTION__, pChInfo->bandwidth);
1276 
1277             if (!tb2[QCA_WLAN_VENDOR_ATTR_NDP_NSS]) {
1278                 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP_NSS not found", __FUNCTION__);
1279                 return WIFI_ERROR_INVALID_ARGS;
1280             }
1281             pChInfo->nss = nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_NDP_NSS]);
1282             ALOGD("%s: No. Spatial Stream = %d", __FUNCTION__, pChInfo->nss);
1283         }
1284     }
1285     return WIFI_SUCCESS;
1286 }
1287 
getNdpScheduleUpdate(struct nlattr ** tb_vendor,NanDataPathScheduleUpdateInd * event)1288 int NanCommand::getNdpScheduleUpdate(struct nlattr **tb_vendor,
1289                                      NanDataPathScheduleUpdateInd *event)
1290 {
1291     u32 len = 0;
1292     struct nlattr *chInfo;
1293     NanChannelInfo *pChInfo;
1294     int rem;
1295     u32 i = 0;
1296 
1297     len = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]);
1298     len = ((sizeof(event->peer_mac_addr) <= len) ? sizeof(event->peer_mac_addr) : len);
1299     memcpy(&event->peer_mac_addr[0], nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]), len);
1300 
1301     event->schedule_update_reason_code = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_SCHEDULE_UPDATE_REASON]);
1302     ALOGD("%s: Reason code %d", __FUNCTION__, event->schedule_update_reason_code);
1303 
1304     if (event->num_channels != 0) {
1305         for (chInfo =
1306             (struct nlattr *) nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO]),
1307             rem = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO]);
1308             (i < NAN_MAX_CHANNEL_INFO_SUPPORTED && nla_ok(chInfo, rem));
1309             chInfo = nla_next(chInfo, &(rem))) {
1310             struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1];
1311 
1312             pChInfo =
1313                 (NanChannelInfo *) ((u8 *)event->channel_info + (i++ * (sizeof(NanChannelInfo))));
1314             nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX,
1315                 (struct nlattr *) nla_data(chInfo), nla_len(chInfo), NULL);
1316 
1317             if (!tb2[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL]) {
1318                 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_CHANNEL not found", __FUNCTION__);
1319                 return WIFI_ERROR_INVALID_ARGS;
1320             }
1321             pChInfo->channel = nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL]);
1322             ALOGD("%s: Channel = %d", __FUNCTION__, pChInfo->channel);
1323 
1324             if (!tb2[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_WIDTH]) {
1325                 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_WIDTH not found", __FUNCTION__);
1326                 return WIFI_ERROR_INVALID_ARGS;
1327             }
1328             pChInfo->bandwidth = nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_WIDTH]);
1329             ALOGD("%s: Channel BW = %d", __FUNCTION__, pChInfo->bandwidth);
1330 
1331            if (!tb2[QCA_WLAN_VENDOR_ATTR_NDP_NSS]) {
1332                 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP_NSS not found", __FUNCTION__);
1333                 return WIFI_ERROR_INVALID_ARGS;
1334             }
1335             pChInfo->nss = nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_NDP_NSS]);
1336             ALOGD("%s: No. Spatial Stream = %d", __FUNCTION__, pChInfo->nss);
1337         }
1338     }
1339 
1340     if (event->num_ndp_instances) {
1341         nla_memcpy(event->ndp_instance_id,
1342                    tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY],
1343                    sizeof(u32) * event->num_ndp_instances);
1344     }
1345     return WIFI_SUCCESS;
1346 }
1347 
getNanRangeRequestReceivedInd(NanRangeRequestInd * event)1348 int NanCommand::getNanRangeRequestReceivedInd(NanRangeRequestInd *event)
1349 {
1350     if (event == NULL || mNanVendorEvent == NULL) {
1351         ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
1352               __func__, event, mNanVendorEvent);
1353         return WIFI_ERROR_INVALID_ARGS;
1354     }
1355 
1356     pNanFWRangeReqRecvdInd pRsp = (pNanFWRangeReqRecvdInd)mNanVendorEvent;
1357 
1358     u8 *pInputTlv = pRsp->ptlv;
1359     NanTlv outputTlv;
1360     u16 readLen = 0;
1361 
1362     int remainingLen = (mNanDataLen -  \
1363         (sizeof(NanMsgHeader)));
1364 
1365     if (remainingLen <= 0) {
1366         ALOGE("%s: No TLV's present",__func__);
1367         return WIFI_SUCCESS;
1368     }
1369 
1370     ALOGV("%s: TLV remaining Len:%d",__func__, remainingLen);
1371     while ((remainingLen > 0) &&
1372            (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv, remainingLen)))) {
1373         ALOGV("%s: Remaining Len:%d readLen:%d type:%d length:%d",
1374               __func__, remainingLen, readLen, outputTlv.type,
1375               outputTlv.length);
1376         switch (outputTlv.type) {
1377         case NAN_TLV_TYPE_NAN20_RANGING_REQUEST_RECEIVED:
1378             NanFWRangeReqRecvdMsg fwRangeReqRecvd;
1379             if (outputTlv.length > sizeof(fwRangeReqRecvd)) {
1380                 outputTlv.length = sizeof(fwRangeReqRecvd);
1381             }
1382             memcpy(&fwRangeReqRecvd, outputTlv.value, outputTlv.length);
1383             FW_MAC_ADDR_TO_CHAR_ARRAY(fwRangeReqRecvd.range_mac_addr, event->range_req_intf_addr);
1384             event->publish_id = fwRangeReqRecvd.range_id;
1385             break;
1386         default:
1387             ALOGV("Unhandled TLV type:%d", outputTlv.type);
1388             break;
1389         }
1390         remainingLen -= readLen;
1391         pInputTlv += readLen;
1392         memset(&outputTlv,0, sizeof(outputTlv));
1393     }
1394     return WIFI_SUCCESS;
1395 }
1396 
getNanRangeReportInd(NanRangeReportInd * event)1397 int NanCommand::getNanRangeReportInd(NanRangeReportInd *event)
1398 {
1399     if (event == NULL || mNanVendorEvent == NULL) {
1400         ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
1401               __func__, event, mNanVendorEvent);
1402         return WIFI_ERROR_INVALID_ARGS;
1403     }
1404 
1405     pNanFWRangeReportInd pRsp = (pNanFWRangeReportInd)mNanVendorEvent;
1406 
1407     u8 *pInputTlv = pRsp->ptlv;
1408     NanTlv outputTlv;
1409     u16 readLen = 0;
1410 
1411     int remainingLen = (mNanDataLen -  \
1412         (sizeof(NanMsgHeader)));
1413 
1414     if (remainingLen <= 0) {
1415         ALOGE("%s: No TLV's present",__func__);
1416         return WIFI_SUCCESS;
1417     }
1418 
1419     ALOGV("%s: TLV remaining Len:%d",__func__, remainingLen);
1420     while ((remainingLen > 0) &&
1421            (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv, remainingLen)))) {
1422         ALOGV("%s: Remaining Len:%d readLen:%d type:%d length:%d",
1423               __func__, remainingLen, readLen, outputTlv.type,
1424               outputTlv.length);
1425         switch (outputTlv.type) {
1426         case NAN_TLV_TYPE_MAC_ADDRESS:
1427             if (outputTlv.length > NAN_MAC_ADDR_LEN) {
1428                 outputTlv.length = NAN_MAC_ADDR_LEN;
1429             }
1430             memcpy(event->range_req_intf_addr, outputTlv.value, outputTlv.length);
1431             break;
1432 
1433         case NAN_TLV_TYPE_NAN20_RANGING_RESULT:
1434             NanFWRangeReportParams range_params;
1435             if (outputTlv.length > sizeof(NanFWRangeReportParams)) {
1436                 outputTlv.length = sizeof(NanFWRangeReportParams);
1437             }
1438             memcpy(&range_params, outputTlv.value, outputTlv.length);
1439             event->range_measurement_mm = range_params.range_measurement;
1440             event->publish_id = range_params.publish_id;
1441 //          event->event_type = range_params.event_type;
1442             break;
1443         default:
1444             ALOGV("Unhandled TLV type:%d", outputTlv.type);
1445             break;
1446         }
1447         remainingLen -= readLen;
1448         pInputTlv += readLen;
1449         memset(&outputTlv,0, sizeof(outputTlv));
1450     }
1451     return WIFI_SUCCESS;
1452 }
1453