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