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