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 
19 #include "wifi_hal.h"
20 #include "nan_i.h"
21 #include "common.h"
22 #include "cpp_bindings.h"
23 #include <utils/Log.h>
24 #include <errno.h>
25 #include "nancommand.h"
26 #include "vendor_definitions.h"
27 
28 #ifdef __GNUC__
29 #define PRINTF_FORMAT(a,b) __attribute__ ((format (printf, (a), (b))))
30 #define STRUCT_PACKED __attribute__ ((packed))
31 #else
32 #define PRINTF_FORMAT(a,b)
33 #define STRUCT_PACKED
34 #endif
35 
36 #define OUT_OF_BAND_SERVICE_INSTANCE_ID 0
37 
38 //Singleton Static Instance
39 NanCommand* NanCommand::mNanCommandInstance  = NULL;
40 
41 //Implementation of the functions exposed in nan.h
nan_register_handler(wifi_interface_handle iface,NanCallbackHandler handlers)42 wifi_error nan_register_handler(wifi_interface_handle iface,
43                                 NanCallbackHandler handlers)
44 {
45     // Obtain the singleton instance
46     int ret = 0;
47     NanCommand *nanCommand = NULL;
48     wifi_handle wifiHandle = getWifiHandle(iface);
49 
50     nanCommand = NanCommand::instance(wifiHandle);
51     if (nanCommand == NULL) {
52         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
53         return WIFI_ERROR_UNKNOWN;
54     }
55 
56     ret = nanCommand->setCallbackHandler(handlers);
57     return (wifi_error)ret;
58 }
59 
nan_get_version(wifi_handle handle,NanVersion * version)60 wifi_error nan_get_version(wifi_handle handle,
61                            NanVersion* version)
62 {
63     *version = (NAN_MAJOR_VERSION <<16 | NAN_MINOR_VERSION << 8 | NAN_MICRO_VERSION);
64     return WIFI_SUCCESS;
65 }
66 
67 /*  Function to send enable request to the wifi driver.*/
nan_enable_request(transaction_id id,wifi_interface_handle iface,NanEnableRequest * msg)68 wifi_error nan_enable_request(transaction_id id,
69                               wifi_interface_handle iface,
70                               NanEnableRequest* msg)
71 {
72     int ret = 0;
73     NanCommand *nanCommand = NULL;
74     interface_info *ifaceInfo = getIfaceInfo(iface);
75     wifi_handle wifiHandle = getWifiHandle(iface);
76 
77     nanCommand = new NanCommand(wifiHandle,
78                                 0,
79                                 OUI_QCA,
80                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
81     if (nanCommand == NULL) {
82         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
83         return WIFI_ERROR_UNKNOWN;
84     }
85 
86     ret = nanCommand->create();
87     if (ret < 0)
88         goto cleanup;
89 
90     /* Set the interface Id of the message. */
91     ret = nanCommand->set_iface_id(ifaceInfo->name);
92     if (ret < 0)
93         goto cleanup;
94 
95     ret = nanCommand->putNanEnable(id, msg);
96     if (ret != 0) {
97         ALOGE("%s: putNanEnable Error:%d", __FUNCTION__, ret);
98         goto cleanup;
99     }
100     ret = nanCommand->requestEvent();
101     if (ret != 0) {
102         ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
103     }
104 cleanup:
105     delete nanCommand;
106     return (wifi_error)ret;
107 }
108 
109 /*  Function to send disable request to the wifi driver.*/
nan_disable_request(transaction_id id,wifi_interface_handle iface)110 wifi_error nan_disable_request(transaction_id id,
111                                wifi_interface_handle iface)
112 {
113     int ret = 0;
114     NanCommand *nanCommand = NULL;
115     interface_info *ifaceInfo = getIfaceInfo(iface);
116     wifi_handle wifiHandle = getWifiHandle(iface);
117 
118     nanCommand = new NanCommand(wifiHandle,
119                                 0,
120                                 OUI_QCA,
121                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
122     if (nanCommand == NULL) {
123         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
124         return WIFI_ERROR_UNKNOWN;
125     }
126 
127     ret = nanCommand->create();
128     if (ret < 0)
129         goto cleanup;
130 
131     /* Set the interface Id of the message. */
132     ret = nanCommand->set_iface_id(ifaceInfo->name);
133     if (ret < 0)
134         goto cleanup;
135 
136     ret = nanCommand->putNanDisable(id);
137     if (ret != 0) {
138         ALOGE("%s: putNanDisable Error:%d",__FUNCTION__, ret);
139         goto cleanup;
140     }
141     ret = nanCommand->requestEvent();
142     if (ret != 0) {
143         ALOGE("%s: requestEvent Error:%d",__FUNCTION__, ret);
144     }
145 cleanup:
146     delete nanCommand;
147     return (wifi_error)ret;
148 }
149 
150 /*  Function to send publish request to the wifi driver.*/
nan_publish_request(transaction_id id,wifi_interface_handle iface,NanPublishRequest * msg)151 wifi_error nan_publish_request(transaction_id id,
152                                wifi_interface_handle iface,
153                                NanPublishRequest* msg)
154 {
155     int ret = 0;
156     NanCommand *nanCommand = NULL;
157     interface_info *ifaceInfo = getIfaceInfo(iface);
158     wifi_handle wifiHandle = getWifiHandle(iface);
159 
160     nanCommand = new NanCommand(wifiHandle,
161                                 0,
162                                 OUI_QCA,
163                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
164     if (nanCommand == NULL) {
165         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
166         return WIFI_ERROR_UNKNOWN;
167     }
168 
169     ret = nanCommand->create();
170     if (ret < 0)
171         goto cleanup;
172 
173     /* Set the interface Id of the message. */
174     ret = nanCommand->set_iface_id(ifaceInfo->name);
175     if (ret < 0)
176         goto cleanup;
177 
178     ret = nanCommand->putNanPublish(id, msg);
179     if (ret != 0) {
180         ALOGE("%s: putNanPublish Error:%d",__FUNCTION__, ret);
181         goto cleanup;
182     }
183     ret = nanCommand->requestEvent();
184     if (ret != 0) {
185         ALOGE("%s: requestEvent Error:%d",__FUNCTION__, ret);
186     }
187 cleanup:
188     delete nanCommand;
189     return (wifi_error)ret;
190 }
191 
192 /*  Function to send publish cancel to the wifi driver.*/
nan_publish_cancel_request(transaction_id id,wifi_interface_handle iface,NanPublishCancelRequest * msg)193 wifi_error nan_publish_cancel_request(transaction_id id,
194                                       wifi_interface_handle iface,
195                                       NanPublishCancelRequest* msg)
196 {
197     int ret = 0;
198     NanCommand *nanCommand = NULL;
199     interface_info *ifaceInfo = getIfaceInfo(iface);
200     wifi_handle wifiHandle = getWifiHandle(iface);
201 
202     nanCommand = new NanCommand(wifiHandle,
203                                 0,
204                                 OUI_QCA,
205                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
206     if (nanCommand == NULL) {
207         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
208         return WIFI_ERROR_UNKNOWN;
209     }
210 
211     ret = nanCommand->create();
212     if (ret < 0)
213         goto cleanup;
214 
215     /* Set the interface Id of the message. */
216     ret = nanCommand->set_iface_id(ifaceInfo->name);
217     if (ret < 0)
218         goto cleanup;
219 
220     ret = nanCommand->putNanPublishCancel(id, msg);
221     if (ret != 0) {
222         ALOGE("%s: putNanPublishCancel Error:%d", __FUNCTION__, ret);
223         goto cleanup;
224     }
225     ret = nanCommand->requestEvent();
226     if (ret != 0) {
227         ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
228     }
229 cleanup:
230     delete nanCommand;
231     return (wifi_error)ret;
232 }
233 
234 /*  Function to send Subscribe request to the wifi driver.*/
nan_subscribe_request(transaction_id id,wifi_interface_handle iface,NanSubscribeRequest * msg)235 wifi_error nan_subscribe_request(transaction_id id,
236                                  wifi_interface_handle iface,
237                                  NanSubscribeRequest* msg)
238 {
239     int ret = 0;
240     NanCommand *nanCommand = NULL;
241     interface_info *ifaceInfo = getIfaceInfo(iface);
242     wifi_handle wifiHandle = getWifiHandle(iface);
243 
244     nanCommand = new NanCommand(wifiHandle,
245                                 0,
246                                 OUI_QCA,
247                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
248     if (nanCommand == NULL) {
249         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
250         return WIFI_ERROR_UNKNOWN;
251     }
252 
253     ret = nanCommand->create();
254     if (ret < 0)
255         goto cleanup;
256 
257     /* Set the interface Id of the message. */
258     ret = nanCommand->set_iface_id(ifaceInfo->name);
259     if (ret < 0)
260         goto cleanup;
261 
262     ret = nanCommand->putNanSubscribe(id, msg);
263     if (ret != 0) {
264         ALOGE("%s: putNanSubscribe Error:%d", __FUNCTION__, ret);
265         goto cleanup;
266     }
267     ret = nanCommand->requestEvent();
268     if (ret != 0) {
269         ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
270     }
271 cleanup:
272     delete nanCommand;
273     return (wifi_error)ret;
274 }
275 
276 /*  Function to cancel subscribe to the wifi driver.*/
nan_subscribe_cancel_request(transaction_id id,wifi_interface_handle iface,NanSubscribeCancelRequest * msg)277 wifi_error nan_subscribe_cancel_request(transaction_id id,
278                                         wifi_interface_handle iface,
279                                         NanSubscribeCancelRequest* msg)
280 {
281     int ret = 0;
282     NanCommand *nanCommand = NULL;
283     interface_info *ifaceInfo = getIfaceInfo(iface);
284     wifi_handle wifiHandle = getWifiHandle(iface);
285 
286     nanCommand = new NanCommand(wifiHandle,
287                                 0,
288                                 OUI_QCA,
289                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
290     if (nanCommand == NULL) {
291         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
292         return WIFI_ERROR_UNKNOWN;
293     }
294 
295     ret = nanCommand->create();
296     if (ret < 0)
297         goto cleanup;
298 
299     /* Set the interface Id of the message. */
300     ret = nanCommand->set_iface_id(ifaceInfo->name);
301     if (ret < 0)
302         goto cleanup;
303 
304     ret = nanCommand->putNanSubscribeCancel(id, msg);
305     if (ret != 0) {
306         ALOGE("%s: putNanSubscribeCancel Error:%d", __FUNCTION__, ret);
307         goto cleanup;
308     }
309     ret = nanCommand->requestEvent();
310     if (ret != 0) {
311         ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
312     }
313 cleanup:
314     delete nanCommand;
315     return (wifi_error)ret;
316 }
317 
318 /*  Function to send NAN follow up request to the wifi driver.*/
nan_transmit_followup_request(transaction_id id,wifi_interface_handle iface,NanTransmitFollowupRequest * msg)319 wifi_error nan_transmit_followup_request(transaction_id id,
320                                          wifi_interface_handle iface,
321                                          NanTransmitFollowupRequest* msg)
322 {
323     int ret = 0;
324     NanCommand *nanCommand = NULL;
325     interface_info *ifaceInfo = getIfaceInfo(iface);
326     wifi_handle wifiHandle = getWifiHandle(iface);
327 
328     nanCommand = new NanCommand(wifiHandle,
329                                 0,
330                                 OUI_QCA,
331                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
332     if (nanCommand == NULL) {
333         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
334         return WIFI_ERROR_UNKNOWN;
335     }
336 
337     ret = nanCommand->create();
338     if (ret < 0)
339         goto cleanup;
340 
341     /* Set the interface Id of the message. */
342     ret = nanCommand->set_iface_id(ifaceInfo->name);
343     if (ret < 0)
344         goto cleanup;
345 
346     ret = nanCommand->putNanTransmitFollowup(id, msg);
347     if (ret != 0) {
348         ALOGE("%s: putNanTransmitFollowup Error:%d", __FUNCTION__, ret);
349         goto cleanup;
350     }
351     ret = nanCommand->requestEvent();
352     if (ret != 0) {
353         ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
354     }
355 cleanup:
356     delete nanCommand;
357     return (wifi_error)ret;
358 }
359 
360 /*  Function to send NAN statistics request to the wifi driver.*/
nan_stats_request(transaction_id id,wifi_interface_handle iface,NanStatsRequest * msg)361 wifi_error nan_stats_request(transaction_id id,
362                              wifi_interface_handle iface,
363                              NanStatsRequest* msg)
364 {
365     int ret = 0;
366     NanCommand *nanCommand = NULL;
367     interface_info *ifaceInfo = getIfaceInfo(iface);
368     wifi_handle wifiHandle = getWifiHandle(iface);
369 
370     nanCommand = new NanCommand(wifiHandle,
371                                 0,
372                                 OUI_QCA,
373                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
374     if (nanCommand == NULL) {
375         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
376         return WIFI_ERROR_UNKNOWN;
377     }
378 
379     ret = nanCommand->create();
380     if (ret < 0)
381         goto cleanup;
382 
383     /* Set the interface Id of the message. */
384     ret = nanCommand->set_iface_id(ifaceInfo->name);
385     if (ret < 0)
386         goto cleanup;
387 
388     ret = nanCommand->putNanStats(id, msg);
389     if (ret != 0) {
390         ALOGE("%s: putNanStats Error:%d", __FUNCTION__, ret);
391         goto cleanup;
392     }
393     ret = nanCommand->requestEvent();
394     if (ret != 0) {
395         ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
396     }
397 cleanup:
398     delete nanCommand;
399     return (wifi_error)ret;
400 }
401 
402 /*  Function to send NAN configuration request to the wifi driver.*/
nan_config_request(transaction_id id,wifi_interface_handle iface,NanConfigRequest * msg)403 wifi_error nan_config_request(transaction_id id,
404                               wifi_interface_handle iface,
405                               NanConfigRequest* msg)
406 {
407     int ret = 0;
408     NanCommand *nanCommand = NULL;
409     interface_info *ifaceInfo = getIfaceInfo(iface);
410     wifi_handle wifiHandle = getWifiHandle(iface);
411 
412     nanCommand = new NanCommand(wifiHandle,
413                                 0,
414                                 OUI_QCA,
415                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
416     if (nanCommand == NULL) {
417         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
418         return WIFI_ERROR_UNKNOWN;
419     }
420 
421     ret = nanCommand->create();
422     if (ret < 0)
423         goto cleanup;
424 
425     /* Set the interface Id of the message. */
426     ret = nanCommand->set_iface_id(ifaceInfo->name);
427     if (ret < 0)
428         goto cleanup;
429 
430     ret = nanCommand->putNanConfig(id, msg);
431     if (ret != 0) {
432         ALOGE("%s: putNanConfig Error:%d",__FUNCTION__, ret);
433         goto cleanup;
434     }
435     ret = nanCommand->requestEvent();
436     if (ret != 0) {
437         ALOGE("%s: requestEvent Error:%d",__FUNCTION__, ret);
438     }
439 cleanup:
440     delete nanCommand;
441     return (wifi_error)ret;
442 }
443 
444 /*  Function to send NAN request to the wifi driver.*/
nan_tca_request(transaction_id id,wifi_interface_handle iface,NanTCARequest * msg)445 wifi_error nan_tca_request(transaction_id id,
446                            wifi_interface_handle iface,
447                            NanTCARequest* msg)
448 {
449     int ret = 0;
450     NanCommand *nanCommand = NULL;
451     interface_info *ifaceInfo = getIfaceInfo(iface);
452     wifi_handle wifiHandle = getWifiHandle(iface);
453 
454     nanCommand = new NanCommand(wifiHandle,
455                                 0,
456                                 OUI_QCA,
457                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
458     if (nanCommand == NULL) {
459         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
460         return WIFI_ERROR_UNKNOWN;
461     }
462 
463     ret = nanCommand->create();
464     if (ret < 0)
465         goto cleanup;
466 
467     /* Set the interface Id of the message. */
468     ret = nanCommand->set_iface_id(ifaceInfo->name);
469     if (ret < 0)
470         goto cleanup;
471 
472     ret = nanCommand->putNanTCA(id, msg);
473     if (ret != 0) {
474         ALOGE("%s: putNanTCA Error:%d",__FUNCTION__, ret);
475         goto cleanup;
476     }
477     ret = nanCommand->requestEvent();
478     if (ret != 0) {
479         ALOGE("%s: requestEvent Error:%d",__FUNCTION__, ret);
480     }
481 cleanup:
482     delete nanCommand;
483     return (wifi_error)ret;
484 }
485 
486 /*  Function to send NAN Beacon sdf payload to the wifi driver.
487     This instructs the Discovery Engine to begin publishing the
488     received payload in any Beacon or Service Discovery Frame
489     transmitted*/
nan_beacon_sdf_payload_request(transaction_id id,wifi_interface_handle iface,NanBeaconSdfPayloadRequest * msg)490 wifi_error nan_beacon_sdf_payload_request(transaction_id id,
491                                          wifi_interface_handle iface,
492                                          NanBeaconSdfPayloadRequest* msg)
493 {
494     int ret = WIFI_ERROR_NOT_SUPPORTED;
495     NanCommand *nanCommand = NULL;
496     interface_info *ifaceInfo = getIfaceInfo(iface);
497     wifi_handle wifiHandle = getWifiHandle(iface);
498 
499     nanCommand = new NanCommand(wifiHandle,
500                                 0,
501                                 OUI_QCA,
502                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
503     if (nanCommand == NULL) {
504         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
505         return WIFI_ERROR_UNKNOWN;
506     }
507 
508     ret = nanCommand->create();
509     if (ret < 0)
510         goto cleanup;
511 
512     /* Set the interface Id of the message. */
513     ret = nanCommand->set_iface_id(ifaceInfo->name);
514     if (ret < 0)
515         goto cleanup;
516 
517     ret = nanCommand->putNanBeaconSdfPayload(id, msg);
518     if (ret != 0) {
519         ALOGE("%s: putNanBeaconSdfPayload Error:%d", __FUNCTION__, ret);
520         goto cleanup;
521     }
522     ret = nanCommand->requestEvent();
523     if (ret != 0) {
524         ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
525     }
526 
527 cleanup:
528     delete nanCommand;
529     return (wifi_error)ret;
530 }
531 
nan_get_sta_parameter(transaction_id id,wifi_interface_handle iface,NanStaParameter * msg)532 wifi_error nan_get_sta_parameter(transaction_id id,
533                                  wifi_interface_handle iface,
534                                  NanStaParameter* msg)
535 {
536     int ret = WIFI_ERROR_NOT_SUPPORTED;
537     NanCommand *nanCommand = NULL;
538     wifi_handle wifiHandle = getWifiHandle(iface);
539 
540     nanCommand = NanCommand::instance(wifiHandle);
541     if (nanCommand == NULL) {
542         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
543         return WIFI_ERROR_UNKNOWN;
544     }
545 
546     ret = nanCommand->getNanStaParameter(iface, msg);
547     if (ret != 0) {
548         ALOGE("%s: getNanStaParameter Error:%d", __FUNCTION__, ret);
549         goto cleanup;
550     }
551 
552 cleanup:
553     return (wifi_error)ret;
554 }
555 
556 /*  Function to get NAN capabilities */
nan_get_capabilities(transaction_id id,wifi_interface_handle iface)557 wifi_error nan_get_capabilities(transaction_id id,
558                                 wifi_interface_handle iface)
559 {
560     int ret = 0;
561     NanCommand *nanCommand = NULL;
562     interface_info *ifaceInfo = getIfaceInfo(iface);
563     wifi_handle wifiHandle = getWifiHandle(iface);
564 
565     nanCommand = new NanCommand(wifiHandle,
566                                 0,
567                                 OUI_QCA,
568                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
569     if (nanCommand == NULL) {
570         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
571         return WIFI_ERROR_UNKNOWN;
572     }
573 
574     ret = nanCommand->create();
575     if (ret < 0)
576         goto cleanup;
577 
578     /* Set the interface Id of the message. */
579     ret = nanCommand->set_iface_id(ifaceInfo->name);
580     if (ret < 0)
581         goto cleanup;
582 
583     ret = nanCommand->putNanCapabilities(id);
584     if (ret != 0) {
585         ALOGE("%s: putNanCapabilities Error:%d",__FUNCTION__, ret);
586         goto cleanup;
587     }
588     ret = nanCommand->requestEvent();
589     if (ret != 0) {
590         ALOGE("%s: requestEvent Error:%d",__FUNCTION__, ret);
591     }
592 cleanup:
593     delete nanCommand;
594     return (wifi_error)ret;
595 }
596 
597 /*  Function to get NAN capabilities */
nan_debug_command_config(transaction_id id,wifi_interface_handle iface,NanDebugParams debug,int debug_msg_length)598 wifi_error nan_debug_command_config(transaction_id id,
599                                    wifi_interface_handle iface,
600                                    NanDebugParams debug,
601                                    int debug_msg_length)
602 {
603     int ret = 0;
604     NanCommand *nanCommand = NULL;
605     interface_info *ifaceInfo = getIfaceInfo(iface);
606     wifi_handle wifiHandle = getWifiHandle(iface);
607 
608     nanCommand = new NanCommand(wifiHandle,
609                                 0,
610                                 OUI_QCA,
611                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
612     if (nanCommand == NULL) {
613         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
614         return WIFI_ERROR_UNKNOWN;
615     }
616 
617     if (debug_msg_length <= 0) {
618         ALOGE("%s: Invalid debug message length = %d", __FUNCTION__,
619                                                        debug_msg_length);
620         return WIFI_ERROR_UNKNOWN;
621     }
622 
623     ret = nanCommand->create();
624     if (ret < 0)
625         goto cleanup;
626 
627     /* Set the interface Id of the message. */
628     ret = nanCommand->set_iface_id(ifaceInfo->name);
629     if (ret < 0)
630         goto cleanup;
631 
632     ret = nanCommand->putNanDebugCommand(debug, debug_msg_length);
633     if (ret != 0) {
634         ALOGE("%s: putNanDebugCommand Error:%d",__FUNCTION__, ret);
635         goto cleanup;
636     }
637 
638     ret = nanCommand->requestEvent();
639     if (ret != 0) {
640         ALOGE("%s: requestEvent Error:%d",__FUNCTION__, ret);
641     }
642 cleanup:
643     delete nanCommand;
644     return (wifi_error)ret;
645 }
646 
nan_initialize_vendor_cmd(wifi_interface_handle iface,NanCommand ** nanCommand)647 wifi_error nan_initialize_vendor_cmd(wifi_interface_handle iface,
648                                      NanCommand **nanCommand)
649 {
650     int ret = 0;
651     interface_info *ifaceInfo = getIfaceInfo(iface);
652     wifi_handle wifiHandle = getWifiHandle(iface);
653 
654     if (nanCommand == NULL) {
655         ALOGE("%s: Error nanCommand NULL", __FUNCTION__);
656         return WIFI_ERROR_INVALID_ARGS;
657     }
658 
659     *nanCommand = new NanCommand(wifiHandle,
660                                  0,
661                                  OUI_QCA,
662                                  QCA_NL80211_VENDOR_SUBCMD_NDP);
663     if (*nanCommand == NULL) {
664         ALOGE("%s: Object creation failed", __FUNCTION__);
665         return WIFI_ERROR_OUT_OF_MEMORY;
666     }
667 
668     /* Create the message */
669     ret = (*nanCommand)->create();
670     if (ret < 0)
671         goto cleanup;
672 
673     ret = (*nanCommand)->set_iface_id(ifaceInfo->name);
674     if (ret < 0)
675         goto cleanup;
676 
677     return WIFI_SUCCESS;
678 cleanup:
679     delete *nanCommand;
680     return (wifi_error)ret;
681 }
682 
nan_data_interface_create(transaction_id id,wifi_interface_handle iface,char * iface_name)683 wifi_error nan_data_interface_create(transaction_id id,
684                                      wifi_interface_handle iface,
685                                      char* iface_name)
686 {
687     ALOGV("NAN_DP_INTERFACE_CREATE");
688     int ret = WIFI_SUCCESS;
689     struct nlattr *nlData;
690     NanCommand *nanCommand = NULL;
691 
692     if (iface_name == NULL) {
693         ALOGE("%s: Invalid Nan Data Interface Name. \n", __FUNCTION__);
694         return WIFI_ERROR_INVALID_ARGS;
695     }
696 
697     ret = nan_initialize_vendor_cmd(iface,
698                                     &nanCommand);
699     if (ret != WIFI_SUCCESS) {
700         ALOGE("%s: Initialization failed", __FUNCTION__);
701         return (wifi_error)ret;
702     }
703 
704     /* Add the vendor specific attributes for the NL command. */
705     nlData = nanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
706     if (!nlData)
707         goto cleanup;
708 
709     if (nanCommand->put_u32(
710             QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
711             QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE) ||
712         nanCommand->put_u16(
713             QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
714             id) ||
715         nanCommand->put_string(
716             QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR,
717             iface_name)) {
718         goto cleanup;
719     }
720 
721     nanCommand->attr_end(nlData);
722     ret = nanCommand->requestEvent();
723     if (ret != 0) {
724         ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
725     }
726 cleanup:
727     delete nanCommand;
728     return (wifi_error)ret;
729 }
730 
nan_data_interface_delete(transaction_id id,wifi_interface_handle iface,char * iface_name)731 wifi_error nan_data_interface_delete(transaction_id id,
732                                      wifi_interface_handle iface,
733                                      char* iface_name)
734 {
735     ALOGV("NAN_DP_INTERFACE_DELETE");
736     int ret = WIFI_SUCCESS;
737     struct nlattr *nlData;
738     NanCommand *nanCommand = NULL;
739 
740     if (iface_name == NULL) {
741         ALOGE("%s: Invalid Nan Data Interface Name. \n", __FUNCTION__);
742         return WIFI_ERROR_INVALID_ARGS;
743     }
744     ret = nan_initialize_vendor_cmd(iface,
745                                     &nanCommand);
746     if (ret != WIFI_SUCCESS) {
747         ALOGE("%s: Initialization failed", __FUNCTION__);
748         return (wifi_error)ret;
749     }
750 
751     /* Add the vendor specific attributes for the NL command. */
752     nlData = nanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
753     if (!nlData)
754         goto cleanup;
755 
756     if (nanCommand->put_u32(
757             QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
758             QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE) ||
759         nanCommand->put_u16(
760             QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
761             id) ||
762         nanCommand->put_string(
763             QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR,
764             iface_name)) {
765         goto cleanup;
766     }
767 
768     nanCommand->attr_end(nlData);
769 
770     ret = nanCommand->requestEvent();
771     if (ret != 0) {
772         ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
773     }
774 cleanup:
775     delete nanCommand;
776     return (wifi_error)ret;
777 }
778 
nan_data_request_initiator(transaction_id id,wifi_interface_handle iface,NanDataPathInitiatorRequest * msg)779 wifi_error nan_data_request_initiator(transaction_id id,
780                                       wifi_interface_handle iface,
781                                       NanDataPathInitiatorRequest* msg)
782 {
783     ALOGV("NAN_DP_REQUEST_INITIATOR");
784     int ret = WIFI_SUCCESS;
785     struct nlattr *nlData, *nlCfgSecurity, *nlCfgQos;
786     NanCommand *nanCommand = NULL;
787 
788     if (msg == NULL)
789         return WIFI_ERROR_INVALID_ARGS;
790 
791     ret = nan_initialize_vendor_cmd(iface,
792                                     &nanCommand);
793     if (ret != WIFI_SUCCESS) {
794         ALOGE("%s: Initialization failed", __FUNCTION__);
795         return (wifi_error)ret;
796     }
797 
798     if ((msg->cipher_type != NAN_CIPHER_SUITE_SHARED_KEY_NONE) &&
799         (msg->key_info.body.pmk_info.pmk_len == 0) &&
800         (msg->key_info.body.passphrase_info.passphrase_len == 0)) {
801         ALOGE("%s: Failed-Initiator req, missing pmk and passphrase",
802                __FUNCTION__);
803         return WIFI_ERROR_INVALID_ARGS;
804     }
805 
806     if ((msg->cipher_type != NAN_CIPHER_SUITE_SHARED_KEY_NONE) &&
807         (msg->requestor_instance_id == OUT_OF_BAND_SERVICE_INSTANCE_ID) &&
808         (msg->service_name_len == 0)) {
809         ALOGE("%s: Failed-Initiator req, missing service name for out of band request",
810               __FUNCTION__);
811         return WIFI_ERROR_INVALID_ARGS;
812     }
813 
814     /* Add the vendor specific attributes for the NL command. */
815     nlData = nanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
816     if (!nlData)
817         goto cleanup;
818 
819     if (nanCommand->put_u32(
820             QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
821             QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_REQUEST) ||
822         nanCommand->put_u16(
823             QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
824             id) ||
825         nanCommand->put_u32(
826             QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID,
827             msg->requestor_instance_id) ||
828         nanCommand->put_bytes(
829             QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR,
830             (char *)msg->peer_disc_mac_addr,
831             NAN_MAC_ADDR_LEN) ||
832         nanCommand->put_string(
833             QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR,
834             msg->ndp_iface)) {
835         goto cleanup;
836     }
837 
838     if (msg->channel_request_type != NAN_DP_CHANNEL_NOT_REQUESTED) {
839         if (nanCommand->put_u32 (
840                 QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG,
841                 msg->channel_request_type) ||
842             nanCommand->put_u32(
843                 QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL,
844                 msg->channel))
845             goto cleanup;
846     }
847 
848     if (msg->app_info.ndp_app_info_len != 0) {
849         if (nanCommand->put_bytes(
850                 QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO,
851                 (char *)msg->app_info.ndp_app_info,
852                 msg->app_info.ndp_app_info_len)) {
853             goto cleanup;
854         }
855     }
856     if (msg->ndp_cfg.security_cfg == NAN_DP_CONFIG_SECURITY) {
857         nlCfgSecurity =
858             nanCommand->attr_start(QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_SECURITY);
859         if (!nlCfgSecurity)
860             goto cleanup;
861 
862         if (nanCommand->put_u32(
863             QCA_WLAN_VENDOR_ATTR_NDP_SECURITY_TYPE,
864             0)) {
865             goto cleanup;
866         }
867         nanCommand->attr_end(nlCfgSecurity);
868     }
869     if (msg->ndp_cfg.qos_cfg == NAN_DP_CONFIG_QOS) {
870         nlCfgQos =
871             nanCommand->attr_start(QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS);
872         if (!nlCfgQos)
873             goto cleanup;
874         /* TBD Qos Info */
875         nanCommand->attr_end(nlCfgQos);
876     }
877     if (msg->cipher_type != NAN_CIPHER_SUITE_SHARED_KEY_NONE) {
878         if (nanCommand->put_u32(QCA_WLAN_VENDOR_ATTR_NDP_CSID,
879                 msg->cipher_type))
880             goto cleanup;
881 
882         if ( msg->key_info.key_type == NAN_SECURITY_KEY_INPUT_PMK &&
883              msg->key_info.body.pmk_info.pmk_len == NAN_PMK_INFO_LEN) {
884             if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_PMK,
885                 (char *)msg->key_info.body.pmk_info.pmk,
886                 msg->key_info.body.pmk_info.pmk_len))
887                 goto cleanup;
888         } else if (msg->key_info.key_type ==
889             NAN_SECURITY_KEY_INPUT_PASSPHRASE &&
890             msg->key_info.body.passphrase_info.passphrase_len >=
891             NAN_SECURITY_MIN_PASSPHRASE_LEN &&
892             msg->key_info.body.passphrase_info.passphrase_len <=
893             NAN_SECURITY_MAX_PASSPHRASE_LEN) {
894             if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE,
895                 (char *)msg->key_info.body.passphrase_info.passphrase,
896                 msg->key_info.body.passphrase_info.passphrase_len))
897                 goto cleanup;
898         }
899 
900         if (msg->service_name_len) {
901             if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME,
902                 (char *)msg->service_name, msg->service_name_len))
903                 goto cleanup;
904         }
905     }
906     nanCommand->attr_end(nlData);
907 
908     ret = nanCommand->requestEvent();
909     if (ret != 0) {
910         ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
911     }
912 cleanup:
913     delete nanCommand;
914     return (wifi_error)ret;
915 }
916 
nan_data_indication_response(transaction_id id,wifi_interface_handle iface,NanDataPathIndicationResponse * msg)917 wifi_error nan_data_indication_response(transaction_id id,
918                                         wifi_interface_handle iface,
919                                         NanDataPathIndicationResponse* msg)
920 {
921     ALOGV("NAN_DP_INDICATION_RESPONSE");
922     int ret = WIFI_SUCCESS;
923     struct nlattr *nlData, *nlCfgSecurity, *nlCfgQos;
924     NanCommand *nanCommand = NULL;
925 
926     if (msg == NULL)
927         return WIFI_ERROR_INVALID_ARGS;
928 
929     ret = nan_initialize_vendor_cmd(iface,
930                                     &nanCommand);
931     if (ret != WIFI_SUCCESS) {
932         ALOGE("%s: Initialization failed", __FUNCTION__);
933         return (wifi_error)ret;
934     }
935 
936     if ((msg->cipher_type != NAN_CIPHER_SUITE_SHARED_KEY_NONE) &&
937         (msg->key_info.body.pmk_info.pmk_len == 0) &&
938         (msg->key_info.body.passphrase_info.passphrase_len == 0)) {
939         ALOGE("%s: Failed-Initiator req, missing pmk and passphrase",
940                __FUNCTION__);
941         return WIFI_ERROR_INVALID_ARGS;
942     }
943 
944     /* Add the vendor specific attributes for the NL command. */
945     nlData = nanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
946     if (!nlData)
947         goto cleanup;
948 
949     if (nanCommand->put_u32(
950             QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
951             QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_REQUEST) ||
952         nanCommand->put_u16(
953             QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
954             id) ||
955         nanCommand->put_u32(
956             QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID,
957             msg->ndp_instance_id) ||
958         nanCommand->put_string(
959             QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR,
960             msg->ndp_iface) ||
961         nanCommand->put_u32(
962             QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE,
963             msg->rsp_code)) {
964         goto cleanup;
965     }
966     if (msg->app_info.ndp_app_info_len != 0) {
967         if (nanCommand->put_bytes(
968                 QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO,
969                 (char *)msg->app_info.ndp_app_info,
970                 msg->app_info.ndp_app_info_len)) {
971             goto cleanup;
972         }
973     }
974     if (msg->ndp_cfg.security_cfg == NAN_DP_CONFIG_SECURITY) {
975         nlCfgSecurity =
976             nanCommand->attr_start(QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_SECURITY);
977         if (!nlCfgSecurity)
978             goto cleanup;
979         /* Setting value to 0 for now */
980         if (nanCommand->put_u32(
981             QCA_WLAN_VENDOR_ATTR_NDP_SECURITY_TYPE,
982             0)) {
983             goto cleanup;
984         }
985         nanCommand->attr_end(nlCfgSecurity);
986     }
987     if (msg->ndp_cfg.qos_cfg == NAN_DP_CONFIG_QOS) {
988         nlCfgQos =
989             nanCommand->attr_start(QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS);
990         if (!nlCfgQos)
991             goto cleanup;
992 
993         /* TBD Qos Info */
994         nanCommand->attr_end(nlCfgQos);
995     }
996     if (msg->cipher_type != NAN_CIPHER_SUITE_SHARED_KEY_NONE) {
997         if (nanCommand->put_u32(QCA_WLAN_VENDOR_ATTR_NDP_CSID,
998                 msg->cipher_type))
999             goto cleanup;
1000 
1001         if ( msg->key_info.key_type == NAN_SECURITY_KEY_INPUT_PMK &&
1002              msg->key_info.body.pmk_info.pmk_len == NAN_PMK_INFO_LEN) {
1003             if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_PMK,
1004                 (char *)msg->key_info.body.pmk_info.pmk,
1005                 msg->key_info.body.pmk_info.pmk_len))
1006                 goto cleanup;
1007         } else if (msg->key_info.key_type == NAN_SECURITY_KEY_INPUT_PASSPHRASE &&
1008             msg->key_info.body.passphrase_info.passphrase_len >=
1009             NAN_SECURITY_MIN_PASSPHRASE_LEN &&
1010             msg->key_info.body.passphrase_info.passphrase_len <=
1011             NAN_SECURITY_MAX_PASSPHRASE_LEN) {
1012             if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE,
1013                 (char *)msg->key_info.body.passphrase_info.passphrase,
1014                 msg->key_info.body.passphrase_info.passphrase_len))
1015                 goto cleanup;
1016         }
1017 
1018         if (msg->service_name_len) {
1019             if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME,
1020                 (char *)msg->service_name, msg->service_name_len))
1021                 goto cleanup;
1022         }
1023     }
1024     nanCommand->attr_end(nlData);
1025 
1026     ret = nanCommand->requestEvent();
1027     if (ret != 0) {
1028         ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
1029     }
1030 cleanup:
1031     delete nanCommand;
1032     return (wifi_error)ret;
1033 }
1034 
nan_data_end(transaction_id id,wifi_interface_handle iface,NanDataPathEndRequest * msg)1035 wifi_error nan_data_end(transaction_id id,
1036                         wifi_interface_handle iface,
1037                         NanDataPathEndRequest* msg)
1038 {
1039     ALOGV("NAN_DP_END");
1040     int ret = WIFI_SUCCESS;
1041     struct nlattr *nlData;
1042     NanCommand *nanCommand = NULL;
1043 
1044     if (msg == NULL)
1045         return WIFI_ERROR_INVALID_ARGS;
1046 
1047     ret = nan_initialize_vendor_cmd(iface,
1048                                     &nanCommand);
1049     if (ret != WIFI_SUCCESS) {
1050         ALOGE("%s: Initialization failed", __FUNCTION__);
1051         return (wifi_error)ret;
1052     }
1053 
1054     /* Add the vendor specific attributes for the NL command. */
1055     nlData = nanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
1056     if (!nlData)
1057         goto cleanup;
1058 
1059     if (nanCommand->put_u32(
1060             QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1061             QCA_WLAN_VENDOR_ATTR_NDP_END_REQUEST) ||
1062         nanCommand->put_u16(
1063             QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
1064             id) ||
1065         nanCommand->put_bytes(
1066             QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY,
1067             (char *)msg->ndp_instance_id,
1068             msg->num_ndp_instances * sizeof(u32))) {
1069         goto cleanup;
1070     }
1071     nanCommand->attr_end(nlData);
1072 
1073     ret = nanCommand->requestEvent();
1074     if (ret != 0) {
1075         ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
1076     }
1077 cleanup:
1078     delete nanCommand;
1079     return (wifi_error)ret;
1080 }
1081 
1082 // Implementation related to nan class common functions
1083 // Constructor
1084 //Making the constructor private since this class is a singleton
NanCommand(wifi_handle handle,int id,u32 vendor_id,u32 subcmd)1085 NanCommand::NanCommand(wifi_handle handle, int id, u32 vendor_id, u32 subcmd)
1086         : WifiVendorCommand(handle, id, vendor_id, subcmd)
1087 {
1088     memset(&mHandler, 0,sizeof(mHandler));
1089     mNanVendorEvent = NULL;
1090     mNanDataLen = 0;
1091     mStaParam = NULL;
1092 }
1093 
instance(wifi_handle handle)1094 NanCommand* NanCommand::instance(wifi_handle handle)
1095 {
1096     if (handle == NULL) {
1097         ALOGE("Handle is invalid");
1098         return NULL;
1099     }
1100     if (mNanCommandInstance == NULL) {
1101         mNanCommandInstance = new NanCommand(handle, 0,
1102                                              OUI_QCA,
1103                                              QCA_NL80211_VENDOR_SUBCMD_NAN);
1104         ALOGV("NanCommand %p created", mNanCommandInstance);
1105         return mNanCommandInstance;
1106     } else {
1107         if (handle != getWifiHandle(mNanCommandInstance->mInfo)) {
1108             /* upper layer must have cleaned up the handle and reinitialized,
1109                so we need to update the same */
1110             ALOGI("Handle different, update the handle");
1111             mNanCommandInstance->mInfo = (hal_info *)handle;
1112         }
1113     }
1114     ALOGV("NanCommand %p created already", mNanCommandInstance);
1115     return mNanCommandInstance;
1116 }
1117 
cleanup()1118 void NanCommand::cleanup()
1119 {
1120     //free the VendorData
1121     if (mVendorData) {
1122         free(mVendorData);
1123     }
1124     mVendorData = NULL;
1125     //cleanup the mMsg
1126     mMsg.destroy();
1127 }
1128 
~NanCommand()1129 NanCommand::~NanCommand()
1130 {
1131     ALOGV("NanCommand %p destroyed", this);
1132 }
1133 
handleResponse(WifiEvent & reply)1134 int NanCommand::handleResponse(WifiEvent &reply){
1135     return NL_SKIP;
1136 }
1137 
setCallbackHandler(NanCallbackHandler nHandler)1138 int NanCommand::setCallbackHandler(NanCallbackHandler nHandler)
1139 {
1140     int res = WIFI_SUCCESS;
1141     mHandler = nHandler;
1142     res = registerVendorHandler(mVendor_id, QCA_NL80211_VENDOR_SUBCMD_NAN);
1143     if (res != 0) {
1144         //error case should not happen print log
1145         ALOGE("%s: Unable to register Vendor Handler Vendor Id=0x%x"
1146               "subcmd=QCA_NL80211_VENDOR_SUBCMD_NAN", __FUNCTION__, mVendor_id);
1147         return res;
1148     }
1149 
1150     res = registerVendorHandler(mVendor_id, QCA_NL80211_VENDOR_SUBCMD_NDP);
1151     if (res != 0) {
1152         //error case should not happen print log
1153         ALOGE("%s: Unable to register Vendor Handler Vendor Id=0x%x"
1154               "subcmd=QCA_NL80211_VENDOR_SUBCMD_NDP", __FUNCTION__, mVendor_id);
1155         return res;
1156     }
1157     return res;
1158 }
1159 
1160 /* This function implements creation of Vendor command */
create()1161 int NanCommand::create() {
1162     int ret = mMsg.create(NL80211_CMD_VENDOR, 0, 0);
1163     if (ret < 0) {
1164         goto out;
1165     }
1166 
1167     /* Insert the oui in the msg */
1168     ret = mMsg.put_u32(NL80211_ATTR_VENDOR_ID, mVendor_id);
1169     if (ret < 0)
1170         goto out;
1171     /* Insert the subcmd in the msg */
1172     ret = mMsg.put_u32(NL80211_ATTR_VENDOR_SUBCMD, mSubcmd);
1173     if (ret < 0)
1174         goto out;
1175 out:
1176     if (ret < 0) {
1177         mMsg.destroy();
1178     }
1179     return ret;
1180 }
1181 
1182 // This function will be the main handler for incoming event
1183 // QCA_NL80211_VENDOR_SUBCMD_NAN
1184 //Call the appropriate callback handler after parsing the vendor data.
handleEvent(WifiEvent & event)1185 int NanCommand::handleEvent(WifiEvent &event)
1186 {
1187     WifiVendorCommand::handleEvent(event);
1188     ALOGV("%s: Subcmd=%u Vendor data len received:%d",
1189           __FUNCTION__, mSubcmd, mDataLen);
1190     hexdump(mVendorData, mDataLen);
1191 
1192     if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NAN){
1193         // Parse the vendordata and get the NAN attribute
1194         struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_MAX + 1];
1195         nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_MAX,
1196                   (struct nlattr *)mVendorData,
1197                   mDataLen, NULL);
1198         // Populating the mNanVendorEvent and mNanDataLen to point to NAN data.
1199         mNanVendorEvent = (char *)nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NAN]);
1200         mNanDataLen = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NAN]);
1201 
1202         if (isNanResponse()) {
1203             //handleNanResponse will parse the data and call
1204             //the response callback handler with the populated
1205             //NanResponseMsg
1206             handleNanResponse();
1207         } else {
1208             //handleNanIndication will parse the data and call
1209             //the corresponding Indication callback handler
1210             //with the corresponding populated Indication event
1211             handleNanIndication();
1212         }
1213     } else if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NDP) {
1214         // Parse the vendordata and get the NAN attribute
1215         u32 ndpCmdType;
1216         struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_AFTER_LAST + 1];
1217         nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_NDP_MAX,
1218                   (struct nlattr *)mVendorData,
1219                   mDataLen, NULL);
1220 
1221         if (tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD]) {
1222             ndpCmdType =
1223                 nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD]);
1224                 ALOGD("%s: NDP Cmd Type : val 0x%x",
1225                       __FUNCTION__, ndpCmdType);
1226                 switch (ndpCmdType) {
1227                 case QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE:
1228                     handleNdpResponse(NAN_DP_INTERFACE_CREATE, tb_vendor);
1229                     break;
1230                 case QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE:
1231                     handleNdpResponse(NAN_DP_INTERFACE_DELETE, tb_vendor);
1232                     break;
1233                 case QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_RESPONSE:
1234                     handleNdpResponse(NAN_DP_INITIATOR_RESPONSE, tb_vendor);
1235                     break;
1236                 case QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_RESPONSE:
1237                     handleNdpResponse(NAN_DP_RESPONDER_RESPONSE, tb_vendor);
1238                     break;
1239                 case QCA_WLAN_VENDOR_ATTR_NDP_END_RESPONSE:
1240                     handleNdpResponse(NAN_DP_END, tb_vendor);
1241                     break;
1242                 case QCA_WLAN_VENDOR_ATTR_NDP_DATA_REQUEST_IND:
1243                 case QCA_WLAN_VENDOR_ATTR_NDP_CONFIRM_IND:
1244                 case QCA_WLAN_VENDOR_ATTR_NDP_END_IND:
1245                     handleNdpIndication(ndpCmdType, tb_vendor);
1246                     break;
1247                 default:
1248                     ALOGE("%s: Invalid NDP subcmd response received %d",
1249                           __FUNCTION__, ndpCmdType);
1250                 }
1251         }
1252     } else {
1253         //error case should not happen print log
1254         ALOGE("%s: Wrong NAN subcmd received %d", __FUNCTION__, mSubcmd);
1255     }
1256     return NL_SKIP;
1257 }
1258 
1259 /*Helper function to Write and Read TLV called in indication as well as request */
NANTLV_WriteTlv(pNanTlv pInTlv,u8 * pOutTlv)1260 u16 NANTLV_WriteTlv(pNanTlv pInTlv, u8 *pOutTlv)
1261 {
1262     u16 writeLen = 0;
1263     u16 i;
1264 
1265     if (!pInTlv)
1266     {
1267         ALOGE("NULL pInTlv");
1268         return writeLen;
1269     }
1270 
1271     if (!pOutTlv)
1272     {
1273         ALOGE("NULL pOutTlv");
1274         return writeLen;
1275     }
1276 
1277     *pOutTlv++ = pInTlv->type & 0xFF;
1278     *pOutTlv++ = (pInTlv->type & 0xFF00) >> 8;
1279     writeLen += 2;
1280 
1281     ALOGV("WRITE TLV type %u, writeLen %u", pInTlv->type, writeLen);
1282 
1283     *pOutTlv++ = pInTlv->length & 0xFF;
1284     *pOutTlv++ = (pInTlv->length & 0xFF00) >> 8;
1285     writeLen += 2;
1286 
1287     ALOGV("WRITE TLV length %u, writeLen %u", pInTlv->length, writeLen);
1288 
1289     for (i=0; i < pInTlv->length; ++i)
1290     {
1291         *pOutTlv++ = pInTlv->value[i];
1292     }
1293 
1294     writeLen += pInTlv->length;
1295     ALOGV("WRITE TLV value, writeLen %u", writeLen);
1296     return writeLen;
1297 }
1298 
NANTLV_ReadTlv(u8 * pInTlv,pNanTlv pOutTlv)1299 u16 NANTLV_ReadTlv(u8 *pInTlv, pNanTlv pOutTlv)
1300 {
1301     u16 readLen = 0;
1302 
1303     if (!pInTlv)
1304     {
1305         ALOGE("NULL pInTlv");
1306         return readLen;
1307     }
1308 
1309     if (!pOutTlv)
1310     {
1311         ALOGE("NULL pOutTlv");
1312         return readLen;
1313     }
1314 
1315     pOutTlv->type = *pInTlv++;
1316     pOutTlv->type |= *pInTlv++ << 8;
1317     readLen += 2;
1318 
1319     ALOGV("READ TLV type %u, readLen %u", pOutTlv->type, readLen);
1320 
1321     pOutTlv->length = *pInTlv++;
1322     pOutTlv->length |= *pInTlv++ << 8;
1323     readLen += 2;
1324 
1325     ALOGV("READ TLV length %u, readLen %u", pOutTlv->length, readLen);
1326 
1327     if (pOutTlv->length) {
1328         pOutTlv->value = pInTlv;
1329         readLen += pOutTlv->length;
1330     } else {
1331         pOutTlv->value = NULL;
1332     }
1333 
1334     ALOGV("READ TLV  readLen %u", readLen);
1335     return readLen;
1336 }
1337 
addTlv(u16 type,u16 length,const u8 * value,u8 * pOutTlv)1338 u8* addTlv(u16 type, u16 length, const u8* value, u8* pOutTlv)
1339 {
1340    NanTlv nanTlv;
1341    u16 len;
1342 
1343    nanTlv.type = type;
1344    nanTlv.length = length;
1345    nanTlv.value = (u8*)value;
1346 
1347    len = NANTLV_WriteTlv(&nanTlv, pOutTlv);
1348    return (pOutTlv + len);
1349 }
1350