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 "nancommand.h"
25 
26 #ifdef __GNUC__
27 #define PRINTF_FORMAT(a,b) __attribute__ ((format (printf, (a), (b))))
28 #define STRUCT_PACKED __attribute__ ((packed))
29 #else
30 #define PRINTF_FORMAT(a,b)
31 #define STRUCT_PACKED
32 #endif
33 
34 #include "qca-vendor.h"
35 
36 //Singleton Static Instance
37 NanCommand* NanCommand::mNanCommandInstance  = NULL;
38 
39 //Implementation of the functions exposed in nan.h
nan_register_handler(wifi_interface_handle iface,NanCallbackHandler handlers)40 wifi_error nan_register_handler(wifi_interface_handle iface,
41                                 NanCallbackHandler handlers)
42 {
43     // Obtain the singleton instance
44     int ret = 0;
45     NanCommand *nanCommand = NULL;
46     interface_info *ifaceInfo = getIfaceInfo(iface);
47     wifi_handle wifiHandle = getWifiHandle(iface);
48 
49     nanCommand = NanCommand::instance(wifiHandle);
50     if (nanCommand == NULL) {
51         ALOGE("%s: Error NanCommand NULL", __func__);
52         return WIFI_ERROR_UNKNOWN;
53     }
54 
55     ret = nanCommand->setCallbackHandler(handlers);
56     return (wifi_error)ret;
57 
58 cleanup:
59     return (wifi_error)ret;
60 }
61 
nan_get_version(wifi_handle handle,NanVersion * version)62 wifi_error nan_get_version(wifi_handle handle,
63                            NanVersion* version)
64 {
65     *version = (NAN_MAJOR_VERSION <<16 | NAN_MINOR_VERSION << 8 | NAN_MICRO_VERSION);
66     return WIFI_SUCCESS;
67 }
68 
69 /*  Function to send enable request to the wifi driver.*/
nan_enable_request(transaction_id id,wifi_interface_handle iface,NanEnableRequest * msg)70 wifi_error nan_enable_request(transaction_id id,
71                               wifi_interface_handle iface,
72                               NanEnableRequest* msg)
73 {
74     int ret = 0;
75     NanCommand *nanCommand = NULL;
76     interface_info *ifaceInfo = getIfaceInfo(iface);
77     wifi_handle wifiHandle = getWifiHandle(iface);
78 
79     nanCommand = new NanCommand(wifiHandle,
80                                 0,
81                                 OUI_QCA,
82                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
83     if (nanCommand == NULL) {
84         ALOGE("%s: Error NanCommand NULL", __func__);
85         return WIFI_ERROR_UNKNOWN;
86     }
87 
88     ret = nanCommand->create();
89     if (ret < 0)
90         goto cleanup;
91 
92     /* Set the interface Id of the message. */
93     ret = nanCommand->set_iface_id(ifaceInfo->name);
94     if (ret < 0)
95         goto cleanup;
96 
97     ret = nanCommand->putNanEnable(id, msg);
98     if (ret != 0) {
99         ALOGE("%s: putNanEnable Error:%d",__func__, ret);
100         goto cleanup;
101     }
102     ret = nanCommand->requestEvent();
103     if (ret != 0) {
104         ALOGE("%s: requestEvent Error:%d",__func__, ret);
105     }
106 cleanup:
107     delete nanCommand;
108     return (wifi_error)ret;
109 }
110 
111 /*  Function to send disable request to the wifi driver.*/
nan_disable_request(transaction_id id,wifi_interface_handle iface)112 wifi_error nan_disable_request(transaction_id id,
113                                wifi_interface_handle iface)
114 {
115     int ret = 0;
116     NanCommand *nanCommand = NULL;
117     interface_info *ifaceInfo = getIfaceInfo(iface);
118     wifi_handle wifiHandle = getWifiHandle(iface);
119 
120     nanCommand = new NanCommand(wifiHandle,
121                                 0,
122                                 OUI_QCA,
123                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
124     if (nanCommand == NULL) {
125         ALOGE("%s: Error NanCommand NULL", __func__);
126         return WIFI_ERROR_UNKNOWN;
127     }
128 
129     ret = nanCommand->create();
130     if (ret < 0)
131         goto cleanup;
132 
133     /* Set the interface Id of the message. */
134     ret = nanCommand->set_iface_id(ifaceInfo->name);
135     if (ret < 0)
136         goto cleanup;
137 
138     ret = nanCommand->putNanDisable(id);
139     if (ret != 0) {
140         ALOGE("%s: putNanDisable Error:%d",__func__, ret);
141         goto cleanup;
142     }
143     ret = nanCommand->requestEvent();
144     if (ret != 0) {
145         ALOGE("%s: requestEvent Error:%d",__func__, ret);
146     }
147 cleanup:
148     delete nanCommand;
149     return (wifi_error)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     int ret = 0;
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", __func__);
168         return WIFI_ERROR_UNKNOWN;
169     }
170 
171     ret = nanCommand->create();
172     if (ret < 0)
173         goto cleanup;
174 
175     /* Set the interface Id of the message. */
176     ret = nanCommand->set_iface_id(ifaceInfo->name);
177     if (ret < 0)
178         goto cleanup;
179 
180     ret = nanCommand->putNanPublish(id, msg);
181     if (ret != 0) {
182         ALOGE("%s: putNanPublish Error:%d",__func__, ret);
183         goto cleanup;
184     }
185     ret = nanCommand->requestEvent();
186     if (ret != 0) {
187         ALOGE("%s: requestEvent Error:%d",__func__, ret);
188     }
189 cleanup:
190     delete nanCommand;
191     return (wifi_error)ret;
192 }
193 
194 /*  Function to send publish cancel to the wifi driver.*/
nan_publish_cancel_request(transaction_id id,wifi_interface_handle iface,NanPublishCancelRequest * msg)195 wifi_error nan_publish_cancel_request(transaction_id id,
196                                       wifi_interface_handle iface,
197                                       NanPublishCancelRequest* msg)
198 {
199     int ret = 0;
200     NanCommand *nanCommand = NULL;
201     interface_info *ifaceInfo = getIfaceInfo(iface);
202     wifi_handle wifiHandle = getWifiHandle(iface);
203 
204     nanCommand = new NanCommand(wifiHandle,
205                                 0,
206                                 OUI_QCA,
207                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
208     if (nanCommand == NULL) {
209         ALOGE("%s: Error NanCommand NULL", __func__);
210         return WIFI_ERROR_UNKNOWN;
211     }
212 
213     ret = nanCommand->create();
214     if (ret < 0)
215         goto cleanup;
216 
217     /* Set the interface Id of the message. */
218     ret = nanCommand->set_iface_id(ifaceInfo->name);
219     if (ret < 0)
220         goto cleanup;
221 
222     ret = nanCommand->putNanPublishCancel(id, msg);
223     if (ret != 0) {
224         ALOGE("%s: putNanPublishCancel Error:%d",__func__, ret);
225         goto cleanup;
226     }
227     ret = nanCommand->requestEvent();
228     if (ret != 0) {
229         ALOGE("%s: requestEvent Error:%d",__func__, ret);
230     }
231 cleanup:
232     delete nanCommand;
233     return (wifi_error)ret;
234 }
235 
236 /*  Function to send Subscribe request to the wifi driver.*/
nan_subscribe_request(transaction_id id,wifi_interface_handle iface,NanSubscribeRequest * msg)237 wifi_error nan_subscribe_request(transaction_id id,
238                                  wifi_interface_handle iface,
239                                  NanSubscribeRequest* msg)
240 {
241     int ret = 0;
242     NanCommand *nanCommand = NULL;
243     interface_info *ifaceInfo = getIfaceInfo(iface);
244     wifi_handle wifiHandle = getWifiHandle(iface);
245 
246     nanCommand = new NanCommand(wifiHandle,
247                                 0,
248                                 OUI_QCA,
249                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
250     if (nanCommand == NULL) {
251         ALOGE("%s: Error NanCommand NULL", __func__);
252         return WIFI_ERROR_UNKNOWN;
253     }
254 
255     ret = nanCommand->create();
256     if (ret < 0)
257         goto cleanup;
258 
259     /* Set the interface Id of the message. */
260     ret = nanCommand->set_iface_id(ifaceInfo->name);
261     if (ret < 0)
262         goto cleanup;
263 
264     ret = nanCommand->putNanSubscribe(id, msg);
265     if (ret != 0) {
266         ALOGE("%s: putNanSubscribe Error:%d",__func__, ret);
267         goto cleanup;
268     }
269     ret = nanCommand->requestEvent();
270     if (ret != 0) {
271         ALOGE("%s: requestEvent Error:%d",__func__, ret);
272     }
273 cleanup:
274     delete nanCommand;
275     return (wifi_error)ret;
276 }
277 
278 /*  Function to cancel subscribe to the wifi driver.*/
nan_subscribe_cancel_request(transaction_id id,wifi_interface_handle iface,NanSubscribeCancelRequest * msg)279 wifi_error nan_subscribe_cancel_request(transaction_id id,
280                                         wifi_interface_handle iface,
281                                         NanSubscribeCancelRequest* msg)
282 {
283     int ret = 0;
284     NanCommand *nanCommand = NULL;
285     interface_info *ifaceInfo = getIfaceInfo(iface);
286     wifi_handle wifiHandle = getWifiHandle(iface);
287 
288     nanCommand = new NanCommand(wifiHandle,
289                                 0,
290                                 OUI_QCA,
291                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
292     if (nanCommand == NULL) {
293         ALOGE("%s: Error NanCommand NULL", __func__);
294         return WIFI_ERROR_UNKNOWN;
295     }
296 
297     ret = nanCommand->create();
298     if (ret < 0)
299         goto cleanup;
300 
301     /* Set the interface Id of the message. */
302     ret = nanCommand->set_iface_id(ifaceInfo->name);
303     if (ret < 0)
304         goto cleanup;
305 
306     ret = nanCommand->putNanSubscribeCancel(id, msg);
307     if (ret != 0) {
308         ALOGE("%s: putNanSubscribeCancel Error:%d",__func__, ret);
309         goto cleanup;
310     }
311     ret = nanCommand->requestEvent();
312     if (ret != 0) {
313         ALOGE("%s: requestEvent Error:%d",__func__, ret);
314     }
315 cleanup:
316     delete nanCommand;
317     return (wifi_error)ret;
318 }
319 
320 /*  Function to send NAN follow up request to the wifi driver.*/
nan_transmit_followup_request(transaction_id id,wifi_interface_handle iface,NanTransmitFollowupRequest * msg)321 wifi_error nan_transmit_followup_request(transaction_id id,
322                                          wifi_interface_handle iface,
323                                          NanTransmitFollowupRequest* msg)
324 {
325     int ret = 0;
326     NanCommand *nanCommand = NULL;
327     interface_info *ifaceInfo = getIfaceInfo(iface);
328     wifi_handle wifiHandle = getWifiHandle(iface);
329 
330     nanCommand = new NanCommand(wifiHandle,
331                                 0,
332                                 OUI_QCA,
333                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
334     if (nanCommand == NULL) {
335         ALOGE("%s: Error NanCommand NULL", __func__);
336         return WIFI_ERROR_UNKNOWN;
337     }
338 
339     ret = nanCommand->create();
340     if (ret < 0)
341         goto cleanup;
342 
343     /* Set the interface Id of the message. */
344     ret = nanCommand->set_iface_id(ifaceInfo->name);
345     if (ret < 0)
346         goto cleanup;
347 
348     ret = nanCommand->putNanTransmitFollowup(id, msg);
349     if (ret != 0) {
350         ALOGE("%s: putNanTransmitFollowup Error:%d",__func__, ret);
351         goto cleanup;
352     }
353     ret = nanCommand->requestEvent();
354     if (ret != 0) {
355         ALOGE("%s: requestEvent Error:%d",__func__, ret);
356     }
357 cleanup:
358     delete nanCommand;
359     return (wifi_error)ret;
360 }
361 
362 /*  Function to send NAN statistics request to the wifi driver.*/
nan_stats_request(transaction_id id,wifi_interface_handle iface,NanStatsRequest * msg)363 wifi_error nan_stats_request(transaction_id id,
364                              wifi_interface_handle iface,
365                              NanStatsRequest* msg)
366 {
367     int ret = 0;
368     NanCommand *nanCommand = NULL;
369     interface_info *ifaceInfo = getIfaceInfo(iface);
370     wifi_handle wifiHandle = getWifiHandle(iface);
371 
372     nanCommand = new NanCommand(wifiHandle,
373                                 0,
374                                 OUI_QCA,
375                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
376     if (nanCommand == NULL) {
377         ALOGE("%s: Error NanCommand NULL", __func__);
378         return WIFI_ERROR_UNKNOWN;
379     }
380 
381     ret = nanCommand->create();
382     if (ret < 0)
383         goto cleanup;
384 
385     /* Set the interface Id of the message. */
386     ret = nanCommand->set_iface_id(ifaceInfo->name);
387     if (ret < 0)
388         goto cleanup;
389 
390     ret = nanCommand->putNanStats(id, msg);
391     if (ret != 0) {
392         ALOGE("%s: putNanStats Error:%d",__func__, ret);
393         goto cleanup;
394     }
395     ret = nanCommand->requestEvent();
396     if (ret != 0) {
397         ALOGE("%s: requestEvent Error:%d",__func__, ret);
398     }
399 cleanup:
400     delete nanCommand;
401     return (wifi_error)ret;
402 }
403 
404 /*  Function to send NAN configuration request to the wifi driver.*/
nan_config_request(transaction_id id,wifi_interface_handle iface,NanConfigRequest * msg)405 wifi_error nan_config_request(transaction_id id,
406                               wifi_interface_handle iface,
407                               NanConfigRequest* msg)
408 {
409     int ret = 0;
410     NanCommand *nanCommand = NULL;
411     interface_info *ifaceInfo = getIfaceInfo(iface);
412     wifi_handle wifiHandle = getWifiHandle(iface);
413 
414     nanCommand = new NanCommand(wifiHandle,
415                                 0,
416                                 OUI_QCA,
417                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
418     if (nanCommand == NULL) {
419         ALOGE("%s: Error NanCommand NULL", __func__);
420         return WIFI_ERROR_UNKNOWN;
421     }
422 
423     ret = nanCommand->create();
424     if (ret < 0)
425         goto cleanup;
426 
427     /* Set the interface Id of the message. */
428     ret = nanCommand->set_iface_id(ifaceInfo->name);
429     if (ret < 0)
430         goto cleanup;
431 
432     ret = nanCommand->putNanConfig(id, msg);
433     if (ret != 0) {
434         ALOGE("%s: putNanConfig Error:%d",__func__, ret);
435         goto cleanup;
436     }
437     ret = nanCommand->requestEvent();
438     if (ret != 0) {
439         ALOGE("%s: requestEvent Error:%d",__func__, ret);
440     }
441 cleanup:
442     delete nanCommand;
443     return (wifi_error)ret;
444 }
445 
446 /*  Function to send NAN request to the wifi driver.*/
nan_tca_request(transaction_id id,wifi_interface_handle iface,NanTCARequest * msg)447 wifi_error nan_tca_request(transaction_id id,
448                            wifi_interface_handle iface,
449                            NanTCARequest* msg)
450 {
451     int ret = 0;
452     NanCommand *nanCommand = NULL;
453     interface_info *ifaceInfo = getIfaceInfo(iface);
454     wifi_handle wifiHandle = getWifiHandle(iface);
455 
456     nanCommand = new NanCommand(wifiHandle,
457                                 0,
458                                 OUI_QCA,
459                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
460     if (nanCommand == NULL) {
461         ALOGE("%s: Error NanCommand NULL", __func__);
462         return WIFI_ERROR_UNKNOWN;
463     }
464 
465     ret = nanCommand->create();
466     if (ret < 0)
467         goto cleanup;
468 
469     /* Set the interface Id of the message. */
470     ret = nanCommand->set_iface_id(ifaceInfo->name);
471     if (ret < 0)
472         goto cleanup;
473 
474     ret = nanCommand->putNanTCA(id, msg);
475     if (ret != 0) {
476         ALOGE("%s: putNanTCA Error:%d",__func__, ret);
477         goto cleanup;
478     }
479     ret = nanCommand->requestEvent();
480     if (ret != 0) {
481         ALOGE("%s: requestEvent Error:%d",__func__, ret);
482     }
483 cleanup:
484     delete nanCommand;
485     return (wifi_error)ret;
486 }
487 
488 /*  Function to send NAN Beacon sdf payload to the wifi driver.
489     This instructs the Discovery Engine to begin publishing the
490     received payload in any Beacon or Service Discovery Frame
491     transmitted*/
nan_beacon_sdf_payload_request(transaction_id id,wifi_interface_handle iface,NanBeaconSdfPayloadRequest * msg)492 wifi_error nan_beacon_sdf_payload_request(transaction_id id,
493                                          wifi_interface_handle iface,
494                                          NanBeaconSdfPayloadRequest* msg)
495 {
496     int ret = WIFI_ERROR_NOT_SUPPORTED;
497     NanCommand *nanCommand = NULL;
498     interface_info *ifaceInfo = getIfaceInfo(iface);
499     wifi_handle wifiHandle = getWifiHandle(iface);
500 
501     nanCommand = new NanCommand(wifiHandle,
502                                 0,
503                                 OUI_QCA,
504                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
505     if (nanCommand == NULL) {
506         ALOGE("%s: Error NanCommand NULL", __func__);
507         return WIFI_ERROR_UNKNOWN;
508     }
509 
510     ret = nanCommand->create();
511     if (ret < 0)
512         goto cleanup;
513 
514     /* Set the interface Id of the message. */
515     ret = nanCommand->set_iface_id(ifaceInfo->name);
516     if (ret < 0)
517         goto cleanup;
518 
519     ret = nanCommand->putNanBeaconSdfPayload(id, msg);
520     if (ret != 0) {
521         ALOGE("%s: putNanBeaconSdfPayload Error:%d",__func__, ret);
522         goto cleanup;
523     }
524     ret = nanCommand->requestEvent();
525     if (ret != 0) {
526         ALOGE("%s: requestEvent Error:%d",__func__, ret);
527     }
528 
529 cleanup:
530     delete nanCommand;
531     return (wifi_error)ret;
532 }
533 
nan_get_sta_parameter(transaction_id id,wifi_interface_handle iface,NanStaParameter * msg)534 wifi_error nan_get_sta_parameter(transaction_id id,
535                                  wifi_interface_handle iface,
536                                  NanStaParameter* msg)
537 {
538     int ret = WIFI_ERROR_NOT_SUPPORTED;
539     NanCommand *nanCommand = NULL;
540     interface_info *ifaceInfo = getIfaceInfo(iface);
541     wifi_handle wifiHandle = getWifiHandle(iface);
542 
543     nanCommand = NanCommand::instance(wifiHandle);
544     if (nanCommand == NULL) {
545         ALOGE("%s: Error NanCommand NULL", __func__);
546         return WIFI_ERROR_UNKNOWN;
547     }
548 
549     ret = nanCommand->getNanStaParameter(iface, msg);
550     if (ret != 0) {
551         ALOGE("%s: getNanStaParameter Error:%d",__func__, ret);
552         goto cleanup;
553     }
554 
555 cleanup:
556     return (wifi_error)ret;
557 }
558 
559 /*  Function to get NAN capabilities */
nan_get_capabilities(transaction_id id,wifi_interface_handle iface)560 wifi_error nan_get_capabilities(transaction_id id,
561                                 wifi_interface_handle iface)
562 {
563     int ret = 0;
564     NanCommand *nanCommand = NULL;
565     interface_info *ifaceInfo = getIfaceInfo(iface);
566     wifi_handle wifiHandle = getWifiHandle(iface);
567 
568     nanCommand = new NanCommand(wifiHandle,
569                                 0,
570                                 OUI_QCA,
571                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
572     if (nanCommand == NULL) {
573         ALOGE("%s: Error NanCommand NULL", __func__);
574         return WIFI_ERROR_UNKNOWN;
575     }
576 
577     ret = nanCommand->create();
578     if (ret < 0)
579         goto cleanup;
580 
581     /* Set the interface Id of the message. */
582     ret = nanCommand->set_iface_id(ifaceInfo->name);
583     if (ret < 0)
584         goto cleanup;
585 
586     ret = nanCommand->putNanCapabilities(id);
587     if (ret != 0) {
588         ALOGE("%s: putNanCapabilities Error:%d",__func__, ret);
589         goto cleanup;
590     }
591     ret = nanCommand->requestEvent();
592     if (ret != 0) {
593         ALOGE("%s: requestEvent Error:%d",__func__, ret);
594     }
595 cleanup:
596     delete nanCommand;
597     return (wifi_error)ret;
598 }
599 
600 // Implementation related to nan class common functions
601 // Constructor
602 //Making the constructor private since this class is a singleton
NanCommand(wifi_handle handle,int id,u32 vendor_id,u32 subcmd)603 NanCommand::NanCommand(wifi_handle handle, int id, u32 vendor_id, u32 subcmd)
604         : WifiVendorCommand(handle, id, vendor_id, subcmd)
605 {
606     memset(&mHandler, 0,sizeof(mHandler));
607     mNanVendorEvent = NULL;
608     mNanDataLen = 0;
609     mStaParam = NULL;
610 }
611 
instance(wifi_handle handle)612 NanCommand* NanCommand::instance(wifi_handle handle)
613 {
614     if (handle == NULL) {
615         ALOGE("Handle is invalid");
616         return NULL;
617     }
618     if (mNanCommandInstance == NULL) {
619         mNanCommandInstance = new NanCommand(handle, 0,
620                                              OUI_QCA,
621                                              QCA_NL80211_VENDOR_SUBCMD_NAN);
622         ALOGV("NanCommand %p created", mNanCommandInstance);
623         return mNanCommandInstance;
624     }
625     else
626     {
627         if (handle != getWifiHandle(mNanCommandInstance->mInfo)) {
628             /* upper layer must have cleaned up the handle and reinitialized,
629                so we need to update the same */
630             ALOGI("Handle different, update the handle");
631             mNanCommandInstance->mInfo = (hal_info *)handle;
632         }
633     }
634     ALOGV("NanCommand %p created already", mNanCommandInstance);
635     return mNanCommandInstance;
636 }
637 
cleanup()638 void NanCommand::cleanup()
639 {
640     //free the VendorData
641     if (mVendorData) {
642         free(mVendorData);
643     }
644     mVendorData = NULL;
645     //cleanup the mMsg
646     mMsg.destroy();
647 }
648 
~NanCommand()649 NanCommand::~NanCommand()
650 {
651     ALOGV("NanCommand %p destroyed", this);
652 }
653 
handleResponse(WifiEvent & reply)654 int NanCommand::handleResponse(WifiEvent &reply){
655     return NL_SKIP;
656 }
657 
setCallbackHandler(NanCallbackHandler nHandler)658 int NanCommand::setCallbackHandler(NanCallbackHandler nHandler)
659 {
660     int res = 0;
661     mHandler = nHandler;
662     res = registerVendorHandler(mVendor_id, mSubcmd);
663     if (res != 0) {
664         //error case should not happen print log
665         ALOGE("%s: Unable to register Vendor Handler Vendor Id=0x%x subcmd=%u",
666               __func__, mVendor_id, mSubcmd);
667     }
668     return res;
669 }
670 
671 /* This function implements creation of Vendor command */
create()672 int NanCommand::create() {
673     int ret = mMsg.create(NL80211_CMD_VENDOR, 0, 0);
674     if (ret < 0) {
675         goto out;
676     }
677 
678     /* Insert the oui in the msg */
679     ret = mMsg.put_u32(NL80211_ATTR_VENDOR_ID, mVendor_id);
680     if (ret < 0)
681         goto out;
682     /* Insert the subcmd in the msg */
683     ret = mMsg.put_u32(NL80211_ATTR_VENDOR_SUBCMD, mSubcmd);
684     if (ret < 0)
685         goto out;
686 out:
687     if (ret < 0) {
688         mMsg.destroy();
689     }
690     return ret;
691 }
692 
693 // This function will be the main handler for incoming event
694 // QCA_NL80211_VENDOR_SUBCMD_NAN
695 //Call the appropriate callback handler after parsing the vendor data.
handleEvent(WifiEvent & event)696 int NanCommand::handleEvent(WifiEvent &event)
697 {
698     WifiVendorCommand::handleEvent(event);
699     ALOGV("%s: Subcmd=%u Vendor data len received:%d",
700           __FUNCTION__, mSubcmd, mDataLen);
701     hexdump(mVendorData, mDataLen);
702 
703     if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NAN){
704         // Parse the vendordata and get the NAN attribute
705         struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_MAX + 1];
706         nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_MAX,
707                   (struct nlattr *)mVendorData,
708                   mDataLen, NULL);
709         // Populating the mNanVendorEvent and mNanDataLen to point to NAN data.
710         mNanVendorEvent = (char *)nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NAN]);
711         mNanDataLen = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NAN]);
712 
713         if (isNanResponse()) {
714             //handleNanResponse will parse the data and call
715             //the response callback handler with the populated
716             //NanResponseMsg
717             handleNanResponse();
718         }
719         else {
720             //handleNanIndication will parse the data and call
721             //the corresponding Indication callback handler
722             //with the corresponding populated Indication event
723             handleNanIndication();
724         }
725     }
726     else {
727         //error case should not happen print log
728         ALOGE("%s: Wrong NAN subcmd received %d", __func__, mSubcmd);
729     }
730     return NL_SKIP;
731 }
732 
733 /*Helper function to Write and Read TLV called in indication as well as request */
NANTLV_WriteTlv(pNanTlv pInTlv,u8 * pOutTlv)734 u16 NANTLV_WriteTlv(pNanTlv pInTlv, u8 *pOutTlv)
735 {
736     u16 writeLen = 0;
737     u16 i;
738 
739     if (!pInTlv)
740     {
741         ALOGE("NULL pInTlv");
742         return writeLen;
743     }
744 
745     if (!pOutTlv)
746     {
747         ALOGE("NULL pOutTlv");
748         return writeLen;
749     }
750 
751     *pOutTlv++ = pInTlv->type & 0xFF;
752     *pOutTlv++ = (pInTlv->type & 0xFF00) >> 8;
753     writeLen += 2;
754 
755     ALOGV("WRITE TLV type %u, writeLen %u", pInTlv->type, writeLen);
756 
757     *pOutTlv++ = pInTlv->length & 0xFF;
758     *pOutTlv++ = (pInTlv->length & 0xFF00) >> 8;
759     writeLen += 2;
760 
761     ALOGV("WRITE TLV length %u, writeLen %u", pInTlv->length, writeLen);
762 
763     for (i=0; i < pInTlv->length; ++i)
764     {
765         *pOutTlv++ = pInTlv->value[i];
766     }
767 
768     writeLen += pInTlv->length;
769     ALOGV("WRITE TLV value, writeLen %u", writeLen);
770     return writeLen;
771 }
772 
NANTLV_ReadTlv(u8 * pInTlv,pNanTlv pOutTlv)773 u16 NANTLV_ReadTlv(u8 *pInTlv, pNanTlv pOutTlv)
774 {
775     u16 readLen = 0;
776 
777     if (!pInTlv)
778     {
779         ALOGE("NULL pInTlv");
780         return readLen;
781     }
782 
783     if (!pOutTlv)
784     {
785         ALOGE("NULL pOutTlv");
786         return readLen;
787     }
788 
789     pOutTlv->type = *pInTlv++;
790     pOutTlv->type |= *pInTlv++ << 8;
791     readLen += 2;
792 
793     ALOGV("READ TLV type %u, readLen %u", pOutTlv->type, readLen);
794 
795     pOutTlv->length = *pInTlv++;
796     pOutTlv->length |= *pInTlv++ << 8;
797     readLen += 2;
798 
799     ALOGV("READ TLV length %u, readLen %u", pOutTlv->length, readLen);
800 
801     if (pOutTlv->length)
802     {
803         pOutTlv->value = pInTlv;
804         readLen += pOutTlv->length;
805     }
806     else
807     {
808         pOutTlv->value = NULL;
809     }
810 
811     ALOGV("READ TLV  readLen %u", readLen);
812     return readLen;
813 }
814 
addTlv(u16 type,u16 length,const u8 * value,u8 * pOutTlv)815 u8* addTlv(u16 type, u16 length, const u8* value, u8* pOutTlv)
816 {
817    NanTlv nanTlv;
818    u16 len;
819 
820    nanTlv.type = type;
821    nanTlv.length = length;
822    nanTlv.value = (u8*)value;
823 
824    len = NANTLV_WriteTlv(&nanTlv, pOutTlv);
825    return (pOutTlv + len);
826 }
827