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