• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 int NanCommand::getNanStaParameter(wifi_interface_handle iface,
890                                    NanStaParameter *pRsp)
891 {
892     int ret = WIFI_ERROR_NONE;
893     int res = -1;
894     transaction_id id = 1;
895     interface_info *ifaceInfo = getIfaceInfo(iface);
896 
897     ret = create();
898     if (ret < 0)
899         goto cleanup;
900 
901     /* Set the interface Id of the message. */
902     ret = set_iface_id(ifaceInfo->name);
903     if (ret < 0)
904         goto cleanup;
905 
906     /*
907        Construct NL message to get the sync stats parameter
908        which has all the parameter required by staparameter.
909     */
910     NanStatsRequest syncStats;
911     memset(&syncStats, 0, sizeof(syncStats));
912     syncStats.stats_type = NAN_STATS_ID_DE_TIMING_SYNC;
913     syncStats.clear = 0;
914 
915     mStaParam = pRsp;
916     ret = putNanStats(id, &syncStats);
917     if (ret != 0) {
918         ALOGE("%s: putNanStats Error:%d",__func__, ret);
919         goto cleanup;
920     }
921     ret = requestEvent();
922     if (ret != 0) {
923         ALOGE("%s: requestEvent Error:%d",__func__, ret);
924         goto cleanup;
925     }
926 
927     struct timespec abstime;
928     abstime.tv_sec = 4;
929     abstime.tv_nsec = 0;
930     res = mCondition.wait(abstime);
931     if (res == ETIMEDOUT)
932     {
933         ALOGE("%s: Time out happened.", __func__);
934         ret = WIFI_ERROR_TIMED_OUT;
935         goto cleanup;
936     }
937     ALOGV("%s: NanStaparameter Master_pref:%x," \
938           " Random_factor:%x, hop_count:%x " \
939           " beacon_transmit_time:%d" \
940           " ndp_channel_freq:%d", __func__,
941           pRsp->master_pref, pRsp->random_factor,
942           pRsp->hop_count, pRsp->beacon_transmit_time, pRsp->ndp_channel_freq);
943 cleanup:
944     mStaParam = NULL;
945     return (int)ret;
946 }
947 
getNanTransmitFollowupInd(NanTransmitFollowupInd * event)948 int NanCommand::getNanTransmitFollowupInd(NanTransmitFollowupInd *event)
949 {
950     if (event == NULL || mNanVendorEvent == NULL) {
951         ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
952               __func__, event, mNanVendorEvent);
953         return WIFI_ERROR_INVALID_ARGS;
954     }
955 
956     pNanSelfTransmitFollowupIndMsg pRsp = (pNanSelfTransmitFollowupIndMsg)mNanVendorEvent;
957     event->id = pRsp->fwHeader.transactionId;
958     NanErrorTranslation((NanInternalStatusType)pRsp->reason, 0,
959                         (void*)event, false);
960     return WIFI_SUCCESS;
961 }
962 
963 //Function which calls the necessaryIndication callback
964 //based on the indication type
handleNdpIndication(u32 ndpCmdType,struct nlattr ** tb_vendor)965 int NanCommand::handleNdpIndication(u32 ndpCmdType, struct nlattr **tb_vendor)
966 {
967     //Based on the message_id in the header determine the Indication type
968     //and call the necessary callback handler
969     int res = 0;
970 
971     ALOGI("handleNdpIndication msg_id:%u", ndpCmdType);
972     switch (ndpCmdType) {
973     case QCA_WLAN_VENDOR_ATTR_NDP_DATA_REQUEST_IND:
974         NanDataPathRequestInd ndpRequestInd;
975         memset(&ndpRequestInd, 0, sizeof(ndpRequestInd));
976 
977         res = getNdpRequest(tb_vendor, &ndpRequestInd);
978         if (!res && mHandler.EventDataRequest) {
979             (*mHandler.EventDataRequest)(&ndpRequestInd);
980         }
981         break;
982 
983     case QCA_WLAN_VENDOR_ATTR_NDP_CONFIRM_IND:
984         NanDataPathConfirmInd ndpConfirmInd;
985         memset(&ndpConfirmInd, 0, sizeof(ndpConfirmInd));
986 
987         res = getNdpConfirm(tb_vendor, &ndpConfirmInd);
988         if (!res && mHandler.EventDataConfirm) {
989             (*mHandler.EventDataConfirm)(&ndpConfirmInd);
990         }
991         break;
992 
993     case QCA_WLAN_VENDOR_ATTR_NDP_END_IND:
994     {
995         NanDataPathEndInd *ndpEndInd = NULL;
996         u8 num_ndp_ids = 0;
997 
998         if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]) {
999             ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP not found", __FUNCTION__);
1000             return WIFI_ERROR_INVALID_ARGS;
1001         }
1002 
1003         num_ndp_ids = (u8)(nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY])/sizeof(u32));
1004         ALOGD("%s: NDP Num Instance Ids : val %d", __FUNCTION__, num_ndp_ids);
1005 
1006         if (num_ndp_ids) {
1007             ndpEndInd =
1008                 (NanDataPathEndInd *)malloc(sizeof(NanDataPathEndInd)+ (sizeof(u32) * num_ndp_ids));
1009             if (!ndpEndInd) {
1010                 ALOGE("%s: ndp_instance_id malloc Failed", __FUNCTION__);
1011                 return WIFI_ERROR_OUT_OF_MEMORY;
1012             }
1013             ndpEndInd->num_ndp_instances = num_ndp_ids;
1014             nla_memcpy(ndpEndInd->ndp_instance_id,
1015                        tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY],
1016                        sizeof(u32) * ndpEndInd->num_ndp_instances);
1017         }
1018         if (mHandler.EventDataEnd) {
1019             (*mHandler.EventDataEnd)(ndpEndInd);
1020         }
1021         free(ndpEndInd);
1022         break;
1023     }
1024     default:
1025         ALOGE("handleNdpIndication error invalid ndpCmdType:%u", ndpCmdType);
1026         res = (int)WIFI_ERROR_INVALID_REQUEST_ID;
1027         break;
1028     }
1029     return res;
1030 }
1031 
getNdpRequest(struct nlattr ** tb_vendor,NanDataPathRequestInd * event)1032 int NanCommand::getNdpRequest(struct nlattr **tb_vendor,
1033                               NanDataPathRequestInd *event)
1034 {
1035     u32 len = 0;
1036 
1037     if (event == NULL || tb_vendor == NULL) {
1038         ALOGE("%s: Invalid input argument event:%p tb_vendor:%p",
1039               __FUNCTION__, event, tb_vendor);
1040         return WIFI_ERROR_INVALID_ARGS;
1041     }
1042     if ((!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID]) ||
1043         (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]) ||
1044         (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID])) {
1045         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP not found", __FUNCTION__);
1046         return WIFI_ERROR_INVALID_ARGS;
1047     }
1048 
1049     event->service_instance_id = nla_get_u16(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID]);
1050     ALOGD("%s: Service Instance id : val %d", __FUNCTION__, event->service_instance_id);
1051 
1052     len = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]);
1053     len = ((sizeof(event->peer_disc_mac_addr) <= len) ? sizeof(event->peer_disc_mac_addr) : len);
1054     memcpy(&event->peer_disc_mac_addr[0], nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]), len);
1055 
1056     event->ndp_instance_id = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]);
1057     ALOGD("%s: Ndp Instance id: %d", __FUNCTION__, event->ndp_instance_id);
1058     if (tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]) {
1059         len = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]);
1060         len = ((sizeof(event->app_info.ndp_app_info) <= len) ? sizeof(event->app_info.ndp_app_info) : len);
1061         memcpy(&event->app_info.ndp_app_info[0], nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]), len);
1062         event->app_info.ndp_app_info_len = len;
1063     } else {
1064         ALOGD("%s: NDP App Info not present", __FUNCTION__);
1065     }
1066     return WIFI_SUCCESS;
1067 }
1068 
getNdpConfirm(struct nlattr ** tb_vendor,NanDataPathConfirmInd * event)1069 int NanCommand::getNdpConfirm(struct nlattr **tb_vendor,
1070                               NanDataPathConfirmInd *event)
1071 {
1072     u32 len = 0;
1073     NanInternalStatusType drv_reason_code;
1074 
1075     if (event == NULL || tb_vendor == NULL) {
1076         ALOGE("%s: Invalid input argument event:%p tb_vendor:%p",
1077               __FUNCTION__, event, tb_vendor);
1078         return WIFI_ERROR_INVALID_ARGS;
1079     }
1080     if ((!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]) ||
1081         (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR]) ||
1082         (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE])) {
1083         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP not found", __FUNCTION__);
1084         return WIFI_ERROR_INVALID_ARGS;
1085     }
1086 
1087     event->ndp_instance_id = nla_get_u16(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]);
1088     ALOGD("%s: Service Instance id : val %d", __FUNCTION__, event->ndp_instance_id);
1089 
1090     len = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR]);
1091     len = ((sizeof(event->peer_ndi_mac_addr) <= len) ? sizeof(event->peer_ndi_mac_addr) : len);
1092     memcpy(&event->peer_ndi_mac_addr[0], nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR]), len);
1093 
1094     event->rsp_code = (NanDataPathResponseCode)nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE]);
1095     ALOGD("%s: Response code %d", __FUNCTION__, event->rsp_code);
1096 
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     drv_reason_code = (NanInternalStatusType)nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE]);
1106     ALOGD("%s: Drv reason code %d", __FUNCTION__, drv_reason_code);
1107     switch (drv_reason_code) {
1108         case NDP_I_MGMT_FRAME_REQUEST_FAILED:
1109         case NDP_I_MGMT_FRAME_RESPONSE_FAILED:
1110         case NDP_I_MGMT_FRAME_CONFIRM_FAILED:
1111         case NDP_I_MGMT_FRAME_SECURITY_INSTALL_FAILED:
1112             event->reason_code = NAN_STATUS_PROTOCOL_FAILURE;
1113             break;
1114         default:
1115             event->reason_code = (NanStatusType)drv_reason_code;
1116             break;
1117     }
1118     ALOGD("%s: Reason code %d", __FUNCTION__, event->reason_code);
1119     return WIFI_SUCCESS;
1120 }
1121 
getNanRangeRequestReceivedInd(NanRangeRequestInd * event)1122 int NanCommand::getNanRangeRequestReceivedInd(NanRangeRequestInd *event)
1123 {
1124     if (event == NULL || mNanVendorEvent == NULL) {
1125         ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
1126               __func__, event, mNanVendorEvent);
1127         return WIFI_ERROR_INVALID_ARGS;
1128     }
1129 
1130     pNanFWRangeReqRecvdInd pRsp = (pNanFWRangeReqRecvdInd)mNanVendorEvent;
1131 
1132     u8 *pInputTlv = pRsp->ptlv;
1133     NanTlv outputTlv;
1134     u16 readLen = 0;
1135 
1136     int remainingLen = (mNanDataLen -  \
1137         (sizeof(NanMsgHeader)));
1138 
1139     if (remainingLen <= 0) {
1140         ALOGE("%s: No TLV's present",__func__);
1141         return WIFI_SUCCESS;
1142     }
1143 
1144     ALOGV("%s: TLV remaining Len:%d",__func__, remainingLen);
1145     while ((remainingLen > 0) &&
1146            (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv)))) {
1147         ALOGV("%s: Remaining Len:%d readLen:%d type:%d length:%d",
1148               __func__, remainingLen, readLen, outputTlv.type,
1149               outputTlv.length);
1150         switch (outputTlv.type) {
1151         case NAN_TLV_TYPE_NAN20_RANGING_REQUEST_RECEIVED:
1152             NanFWRangeReqRecvdMsg fwRangeReqRecvd;
1153             if (outputTlv.length > sizeof(fwRangeReqRecvd)) {
1154                 outputTlv.length = sizeof(fwRangeReqRecvd);
1155             }
1156             memcpy(&fwRangeReqRecvd, outputTlv.value, outputTlv.length);
1157             FW_MAC_ADDR_TO_CHAR_ARRAY(fwRangeReqRecvd.range_mac_addr, event->range_req_intf_addr);
1158             event->publish_id = fwRangeReqRecvd.range_id;
1159             break;
1160         default:
1161             ALOGV("Unhandled TLV type:%d", outputTlv.type);
1162             break;
1163         }
1164         remainingLen -= readLen;
1165         pInputTlv += readLen;
1166         memset(&outputTlv,0, sizeof(outputTlv));
1167     }
1168     return WIFI_SUCCESS;
1169 }
1170 
getNanRangeReportInd(NanRangeReportInd * event)1171 int NanCommand::getNanRangeReportInd(NanRangeReportInd *event)
1172 {
1173     if (event == NULL || mNanVendorEvent == NULL) {
1174         ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
1175               __func__, event, mNanVendorEvent);
1176         return WIFI_ERROR_INVALID_ARGS;
1177     }
1178 
1179     pNanFWRangeReportInd pRsp = (pNanFWRangeReportInd)mNanVendorEvent;
1180 
1181     u8 *pInputTlv = pRsp->ptlv;
1182     NanTlv outputTlv;
1183     u16 readLen = 0;
1184 
1185     int remainingLen = (mNanDataLen -  \
1186         (sizeof(NanMsgHeader)));
1187 
1188     if (remainingLen <= 0) {
1189         ALOGE("%s: No TLV's present",__func__);
1190         return WIFI_SUCCESS;
1191     }
1192 
1193     ALOGV("%s: TLV remaining Len:%d",__func__, remainingLen);
1194     while ((remainingLen > 0) &&
1195            (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv)))) {
1196         ALOGV("%s: Remaining Len:%d readLen:%d type:%d length:%d",
1197               __func__, remainingLen, readLen, outputTlv.type,
1198               outputTlv.length);
1199         switch (outputTlv.type) {
1200         case NAN_TLV_TYPE_MAC_ADDRESS:
1201             if (outputTlv.length > NAN_MAC_ADDR_LEN) {
1202                 outputTlv.length = NAN_MAC_ADDR_LEN;
1203             }
1204             memcpy(event->range_req_intf_addr, outputTlv.value, outputTlv.length);
1205             break;
1206 
1207         case NAN_TLV_TYPE_NAN20_RANGING_RESULT:
1208             NanFWRangeReportParams range_params;
1209             if (outputTlv.length > sizeof(NanFWRangeReportParams)) {
1210                 outputTlv.length = sizeof(NanFWRangeReportParams);
1211             }
1212             memcpy(&range_params, outputTlv.value, outputTlv.length);
1213             event->range_measurement_cm = range_params.range_measurement;
1214             event->publish_id = range_params.publish_id;
1215 //          event->event_type = range_params.event_type;
1216             break;
1217         default:
1218             ALOGV("Unhandled TLV type:%d", outputTlv.type);
1219             break;
1220         }
1221         remainingLen -= readLen;
1222         pInputTlv += readLen;
1223         memset(&outputTlv,0, sizeof(outputTlv));
1224     }
1225     return WIFI_SUCCESS;
1226 }
1227