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