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