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