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  * Changes from Qualcomm Innovation Center are provided under the following license:
17  *
18  * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
19  *
20  * Redistribution and use in source and binary forms, with or without
21  * modification, are permitted (subject to the limitations in the
22  * disclaimer below) provided that the following conditions are met:
23  *
24  *   * Redistributions of source code must retain the above copyright
25  *     notice, this list of conditions and the following disclaimer.
26  *
27  *   * Redistributions in binary form must reproduce the above
28  *     copyright notice, this list of conditions and the following
29  *     disclaimer in the documentation and/or other materials provided
30  *     with the distribution.
31  *
32  *   * Neither the name of Qualcomm Innovation Center, Inc. nor the names of its
33  *     contributors may be used to endorse or promote products derived
34  *     from this software without specific prior written permission.
35  *
36  * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
37  * GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
38  * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
39  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
40  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
41  * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
42  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
43  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
44  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
45  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
46  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
47  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
48  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
49  */
50 
51 #include "sync.h"
52 
53 #include <hardware_legacy/wifi_hal.h>
54 #include "nan_i.h"
55 #include "common.h"
56 #include "cpp_bindings.h"
57 #include <utils/Log.h>
58 #include <errno.h>
59 #include "nancommand.h"
60 #include "vendor_definitions.h"
61 #include "wificonfigcommand.h"
62 #include <ctype.h>
63 #include <openssl/sha.h>
64 #include <openssl/evp.h>
65 
66 #ifdef __GNUC__
67 #define PRINTF_FORMAT(a,b) __attribute__ ((format (printf, (a), (b))))
68 #define STRUCT_PACKED __attribute__ ((packed))
69 #else
70 #define PRINTF_FORMAT(a,b)
71 #define STRUCT_PACKED
72 #endif
73 
74 #define OUT_OF_BAND_SERVICE_INSTANCE_ID 0
75 
76 //Singleton Static Instance
77 NanCommand* NanCommand::mNanCommandInstance  = NULL;
78 
79 //Implementation of the functions exposed in nan.h
nan_register_handler(wifi_interface_handle iface,NanCallbackHandler handlers)80 wifi_error nan_register_handler(wifi_interface_handle iface,
81                                 NanCallbackHandler handlers)
82 {
83     // Obtain the singleton instance
84     wifi_error ret;
85     NanCommand *nanCommand = NULL;
86     wifi_handle wifiHandle = getWifiHandle(iface);
87 
88     nanCommand = NanCommand::instance(wifiHandle);
89     if (nanCommand == NULL) {
90         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
91         return WIFI_ERROR_UNKNOWN;
92     }
93 
94     ret = nanCommand->setCallbackHandler(handlers);
95     return ret;
96 }
97 
nan_get_version(wifi_handle handle,NanVersion * version)98 wifi_error nan_get_version(wifi_handle handle,
99                            NanVersion* version)
100 {
101     *version = (NAN_MAJOR_VERSION <<16 | NAN_MINOR_VERSION << 8 | NAN_MICRO_VERSION);
102     return WIFI_SUCCESS;
103 }
104 
105 /*  Function to send enable request to the wifi driver.*/
nan_enable_request(transaction_id id,wifi_interface_handle iface,NanEnableRequest * msg)106 wifi_error nan_enable_request(transaction_id id,
107                               wifi_interface_handle iface,
108                               NanEnableRequest* msg)
109 {
110     wifi_error ret;
111     NanCommand *nanCommand = NULL;
112     NanCommand *t_nanCommand = NULL;
113     interface_info *ifaceInfo = getIfaceInfo(iface);
114     wifi_handle wifiHandle = getWifiHandle(iface);
115     hal_info *info = getHalInfo(wifiHandle);
116 
117     if (info == NULL) {
118         ALOGE("%s: Error hal_info NULL", __FUNCTION__);
119         return WIFI_ERROR_UNKNOWN;
120     }
121 
122     nanCommand = new NanCommand(wifiHandle,
123                                 0,
124                                 OUI_QCA,
125                                 info->support_nan_ext_cmd?
126                                 QCA_NL80211_VENDOR_SUBCMD_NAN_EXT :
127                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
128     if (nanCommand == NULL) {
129         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
130         return WIFI_ERROR_UNKNOWN;
131     }
132 
133     ret = nanCommand->create();
134     if (ret != WIFI_SUCCESS)
135         goto cleanup;
136 
137     /* Set the interface Id of the message. */
138     ret = nanCommand->set_iface_id(ifaceInfo->name);
139     if (ret != WIFI_SUCCESS)
140         goto cleanup;
141 
142     ret = nanCommand->putNanEnable(id, msg);
143     if (ret != WIFI_SUCCESS) {
144         ALOGE("%s: putNanEnable Error:%d", __FUNCTION__, ret);
145         goto cleanup;
146     }
147 
148     ret = nanCommand->requestEvent();
149     if (ret != WIFI_SUCCESS)
150         ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
151 
152     if (ret == WIFI_SUCCESS) {
153         t_nanCommand = NanCommand::instance(wifiHandle);
154         if (t_nanCommand != NULL) {
155             t_nanCommand->allocSvcParams();
156         }
157     }
158 
159 cleanup:
160     delete nanCommand;
161     return ret;
162 }
163 
164 /*  Function to send disable request to the wifi driver.*/
nan_disable_request(transaction_id id,wifi_interface_handle iface)165 wifi_error nan_disable_request(transaction_id id,
166                                wifi_interface_handle iface)
167 {
168     wifi_error ret;
169     NanCommand *nanCommand = NULL;
170     NanCommand *t_nanCommand = NULL;
171     interface_info *ifaceInfo = getIfaceInfo(iface);
172     wifi_handle wifiHandle = getWifiHandle(iface);
173     hal_info *info = getHalInfo(wifiHandle);
174 
175     if (info == NULL) {
176         ALOGE("%s: Error hal_info NULL", __FUNCTION__);
177         return WIFI_ERROR_UNKNOWN;
178     }
179 
180     nanCommand = new NanCommand(wifiHandle,
181                                 0,
182                                 OUI_QCA,
183                                 info->support_nan_ext_cmd?
184                                 QCA_NL80211_VENDOR_SUBCMD_NAN_EXT :
185                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
186     if (nanCommand == NULL) {
187         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
188         return WIFI_ERROR_UNKNOWN;
189     }
190 
191     ret = nanCommand->create();
192     if (ret != WIFI_SUCCESS)
193         goto cleanup;
194 
195     /* Set the interface Id of the message. */
196     ret = nanCommand->set_iface_id(ifaceInfo->name);
197     if (ret != WIFI_SUCCESS)
198         goto cleanup;
199 
200     ret = nanCommand->putNanDisable(id);
201     if (ret != WIFI_SUCCESS) {
202         ALOGE("%s: putNanDisable Error:%d",__FUNCTION__, ret);
203         goto cleanup;
204     }
205 
206     ret = nanCommand->requestEvent();
207     if (ret != WIFI_SUCCESS)
208         ALOGE("%s: requestEvent Error:%d",__FUNCTION__, ret);
209 
210     if (ret == WIFI_SUCCESS) {
211         t_nanCommand = NanCommand::instance(wifiHandle);
212         if (t_nanCommand != NULL) {
213             t_nanCommand->deallocSvcParams();
214         }
215     }
216 
217 cleanup:
218     delete nanCommand;
219     return ret;
220 }
221 
222 /*  Function to send publish request to the wifi driver.*/
nan_publish_request(transaction_id id,wifi_interface_handle iface,NanPublishRequest * msg)223 wifi_error nan_publish_request(transaction_id id,
224                                wifi_interface_handle iface,
225                                NanPublishRequest* msg)
226 {
227     wifi_error ret;
228     NanCommand *nanCommand = NULL;
229     interface_info *ifaceInfo = getIfaceInfo(iface);
230     wifi_handle wifiHandle = getWifiHandle(iface);
231     hal_info *info = getHalInfo(wifiHandle);
232 
233     if (info == NULL) {
234         ALOGE("%s: Error hal_info NULL", __FUNCTION__);
235         return WIFI_ERROR_UNKNOWN;
236     }
237 
238     nanCommand = new NanCommand(wifiHandle,
239                                 0,
240                                 OUI_QCA,
241                                 info->support_nan_ext_cmd?
242                                 QCA_NL80211_VENDOR_SUBCMD_NAN_EXT :
243                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
244     if (nanCommand == NULL) {
245         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
246         return WIFI_ERROR_UNKNOWN;
247     }
248 
249     ret = nanCommand->create();
250     if (ret != WIFI_SUCCESS)
251         goto cleanup;
252 
253     /* Set the interface Id of the message. */
254     ret = nanCommand->set_iface_id(ifaceInfo->name);
255     if (ret != WIFI_SUCCESS)
256         goto cleanup;
257 
258     ret = nanCommand->putNanPublish(id, msg);
259     if (ret != WIFI_SUCCESS) {
260         ALOGE("%s: putNanPublish Error:%d",__FUNCTION__, ret);
261         goto cleanup;
262     }
263 
264     ret = nanCommand->requestEvent();
265     if (ret != WIFI_SUCCESS)
266         ALOGE("%s: requestEvent Error:%d",__FUNCTION__, ret);
267 
268 cleanup:
269     delete nanCommand;
270     return ret;
271 }
272 
273 /*  Function to send publish cancel to the wifi driver.*/
nan_publish_cancel_request(transaction_id id,wifi_interface_handle iface,NanPublishCancelRequest * msg)274 wifi_error nan_publish_cancel_request(transaction_id id,
275                                       wifi_interface_handle iface,
276                                       NanPublishCancelRequest* msg)
277 {
278     wifi_error ret;
279     NanCommand *nanCommand = NULL;
280     interface_info *ifaceInfo = getIfaceInfo(iface);
281     wifi_handle wifiHandle = getWifiHandle(iface);
282     hal_info *info = getHalInfo(wifiHandle);
283 
284     if (info == NULL) {
285         ALOGE("%s: Error hal_info NULL", __FUNCTION__);
286         return WIFI_ERROR_UNKNOWN;
287     }
288 
289     nanCommand = new NanCommand(wifiHandle,
290                                 0,
291                                 OUI_QCA,
292                                 info->support_nan_ext_cmd?
293                                 QCA_NL80211_VENDOR_SUBCMD_NAN_EXT :
294                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
295     if (nanCommand == NULL) {
296         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
297         return WIFI_ERROR_UNKNOWN;
298     }
299 
300     ret = nanCommand->create();
301     if (ret != WIFI_SUCCESS)
302         goto cleanup;
303 
304     /* Set the interface Id of the message. */
305     ret = nanCommand->set_iface_id(ifaceInfo->name);
306     if (ret != WIFI_SUCCESS)
307         goto cleanup;
308 
309     ret = nanCommand->putNanPublishCancel(id, msg);
310     if (ret != WIFI_SUCCESS) {
311         ALOGE("%s: putNanPublishCancel Error:%d", __FUNCTION__, ret);
312         goto cleanup;
313     }
314 
315     ret = nanCommand->requestEvent();
316     if (ret != WIFI_SUCCESS)
317         ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
318 
319 cleanup:
320     delete nanCommand;
321     return ret;
322 }
323 
324 /*  Function to send Subscribe request to the wifi driver.*/
nan_subscribe_request(transaction_id id,wifi_interface_handle iface,NanSubscribeRequest * msg)325 wifi_error nan_subscribe_request(transaction_id id,
326                                  wifi_interface_handle iface,
327                                  NanSubscribeRequest* msg)
328 {
329     wifi_error ret;
330     NanCommand *nanCommand = NULL;
331     interface_info *ifaceInfo = getIfaceInfo(iface);
332     wifi_handle wifiHandle = getWifiHandle(iface);
333     hal_info *info = getHalInfo(wifiHandle);
334 
335     if (info == NULL) {
336         ALOGE("%s: Error hal_info NULL", __FUNCTION__);
337         return WIFI_ERROR_UNKNOWN;
338     }
339 
340     nanCommand = new NanCommand(wifiHandle,
341                                 0,
342                                 OUI_QCA,
343                                 info->support_nan_ext_cmd?
344                                 QCA_NL80211_VENDOR_SUBCMD_NAN_EXT :
345                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
346     if (nanCommand == NULL) {
347         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
348         return WIFI_ERROR_UNKNOWN;
349     }
350 
351     ret = nanCommand->create();
352     if (ret != WIFI_SUCCESS)
353         goto cleanup;
354 
355     /* Set the interface Id of the message. */
356     ret = nanCommand->set_iface_id(ifaceInfo->name);
357     if (ret != WIFI_SUCCESS)
358         goto cleanup;
359 
360     ret = nanCommand->putNanSubscribe(id, msg);
361     if (ret != WIFI_SUCCESS) {
362         ALOGE("%s: putNanSubscribe Error:%d", __FUNCTION__, ret);
363         goto cleanup;
364     }
365 
366     ret = nanCommand->requestEvent();
367     if (ret != WIFI_SUCCESS)
368         ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
369 
370 cleanup:
371     delete nanCommand;
372     return ret;
373 }
374 
375 /*  Function to cancel subscribe to the wifi driver.*/
nan_subscribe_cancel_request(transaction_id id,wifi_interface_handle iface,NanSubscribeCancelRequest * msg)376 wifi_error nan_subscribe_cancel_request(transaction_id id,
377                                         wifi_interface_handle iface,
378                                         NanSubscribeCancelRequest* msg)
379 {
380     wifi_error ret;
381     NanCommand *nanCommand = NULL;
382     NanCommand *t_nanCommand = NULL;
383     interface_info *ifaceInfo = getIfaceInfo(iface);
384     wifi_handle wifiHandle = getWifiHandle(iface);
385     hal_info *info = getHalInfo(wifiHandle);
386 
387     if (info == NULL) {
388         ALOGE("%s: Error hal_info NULL", __FUNCTION__);
389         return WIFI_ERROR_UNKNOWN;
390     }
391 
392     nanCommand = new NanCommand(wifiHandle,
393                                 0,
394                                 OUI_QCA,
395                                 info->support_nan_ext_cmd?
396                                 QCA_NL80211_VENDOR_SUBCMD_NAN_EXT :
397                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
398     if (nanCommand == NULL) {
399         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
400         return WIFI_ERROR_UNKNOWN;
401     }
402 
403     ret = nanCommand->create();
404     if (ret != WIFI_SUCCESS)
405         goto cleanup;
406 
407     /* Set the interface Id of the message. */
408     ret = nanCommand->set_iface_id(ifaceInfo->name);
409     if (ret != WIFI_SUCCESS)
410         goto cleanup;
411 
412     ret = nanCommand->putNanSubscribeCancel(id, msg);
413     if (ret != WIFI_SUCCESS) {
414         ALOGE("%s: putNanSubscribeCancel Error:%d", __FUNCTION__, ret);
415         goto cleanup;
416     }
417 
418     ret = nanCommand->requestEvent();
419     if (ret != WIFI_SUCCESS)
420         ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
421 
422     if (ret == WIFI_SUCCESS) {
423         t_nanCommand = NanCommand::instance(wifiHandle);
424         if (t_nanCommand != NULL) {
425             t_nanCommand->deleteServiceId(msg->subscribe_id,
426                                           0, NAN_ROLE_SUBSCRIBER);
427         }
428     }
429 
430 cleanup:
431     delete nanCommand;
432     return ret;
433 }
434 
435 /*  Function to send NAN follow up request to the wifi driver.*/
nan_transmit_followup_request(transaction_id id,wifi_interface_handle iface,NanTransmitFollowupRequest * msg)436 wifi_error nan_transmit_followup_request(transaction_id id,
437                                          wifi_interface_handle iface,
438                                          NanTransmitFollowupRequest* msg)
439 {
440     wifi_error ret;
441     NanCommand *nanCommand = NULL;
442     interface_info *ifaceInfo = getIfaceInfo(iface);
443     wifi_handle wifiHandle = getWifiHandle(iface);
444     hal_info *info = getHalInfo(wifiHandle);
445 
446     if (info == NULL) {
447         ALOGE("%s: Error hal_info NULL", __FUNCTION__);
448         return WIFI_ERROR_UNKNOWN;
449     }
450 
451     nanCommand = new NanCommand(wifiHandle,
452                                 0,
453                                 OUI_QCA,
454                                 info->support_nan_ext_cmd?
455                                 QCA_NL80211_VENDOR_SUBCMD_NAN_EXT :
456                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
457     if (nanCommand == NULL) {
458         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
459         return WIFI_ERROR_UNKNOWN;
460     }
461 
462     ret = nanCommand->create();
463     if (ret != WIFI_SUCCESS)
464         goto cleanup;
465 
466     /* Set the interface Id of the message. */
467     ret = nanCommand->set_iface_id(ifaceInfo->name);
468     if (ret != WIFI_SUCCESS)
469         goto cleanup;
470 
471     ret = nanCommand->putNanTransmitFollowup(id, msg);
472     if (ret != WIFI_SUCCESS) {
473         ALOGE("%s: putNanTransmitFollowup Error:%d", __FUNCTION__, ret);
474         goto cleanup;
475     }
476 
477     ret = nanCommand->requestEvent();
478     if (ret != WIFI_SUCCESS)
479         ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
480 
481 cleanup:
482     delete nanCommand;
483     return ret;
484 }
485 
486 /*  Function to send NAN statistics request to the wifi driver.*/
nan_stats_request(transaction_id id,wifi_interface_handle iface,NanStatsRequest * msg)487 wifi_error nan_stats_request(transaction_id id,
488                              wifi_interface_handle iface,
489                              NanStatsRequest* msg)
490 {
491     wifi_error ret;
492     NanCommand *nanCommand = NULL;
493     interface_info *ifaceInfo = getIfaceInfo(iface);
494     wifi_handle wifiHandle = getWifiHandle(iface);
495     hal_info *info = getHalInfo(wifiHandle);
496 
497     if (info == NULL) {
498         ALOGE("%s: Error hal_info NULL", __FUNCTION__);
499         return WIFI_ERROR_UNKNOWN;
500     }
501 
502     nanCommand = new NanCommand(wifiHandle,
503                                 0,
504                                 OUI_QCA,
505                                 info->support_nan_ext_cmd?
506                                 QCA_NL80211_VENDOR_SUBCMD_NAN_EXT :
507                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
508     if (nanCommand == NULL) {
509         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
510         return WIFI_ERROR_UNKNOWN;
511     }
512 
513     ret = nanCommand->create();
514     if (ret != WIFI_SUCCESS)
515         goto cleanup;
516 
517     /* Set the interface Id of the message. */
518     ret = nanCommand->set_iface_id(ifaceInfo->name);
519     if (ret != WIFI_SUCCESS)
520         goto cleanup;
521 
522     ret = nanCommand->putNanStats(id, msg);
523     if (ret != WIFI_SUCCESS) {
524         ALOGE("%s: putNanStats Error:%d", __FUNCTION__, ret);
525         goto cleanup;
526     }
527 
528     ret = nanCommand->requestEvent();
529     if (ret != WIFI_SUCCESS)
530         ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
531 
532 cleanup:
533     delete nanCommand;
534     return ret;
535 }
536 
537 /*  Function to send NAN configuration request to the wifi driver.*/
nan_config_request(transaction_id id,wifi_interface_handle iface,NanConfigRequest * msg)538 wifi_error nan_config_request(transaction_id id,
539                               wifi_interface_handle iface,
540                               NanConfigRequest* msg)
541 {
542     wifi_error ret;
543     NanCommand *nanCommand = NULL;
544     interface_info *ifaceInfo = getIfaceInfo(iface);
545     wifi_handle wifiHandle = getWifiHandle(iface);
546     hal_info *info = getHalInfo(wifiHandle);
547 
548     if (info == NULL) {
549         ALOGE("%s: Error hal_info NULL", __FUNCTION__);
550         return WIFI_ERROR_UNKNOWN;
551     }
552 
553     nanCommand = new NanCommand(wifiHandle,
554                                 0,
555                                 OUI_QCA,
556                                 info->support_nan_ext_cmd?
557                                 QCA_NL80211_VENDOR_SUBCMD_NAN_EXT :
558                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
559     if (nanCommand == NULL) {
560         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
561         return WIFI_ERROR_UNKNOWN;
562     }
563 
564     ret = nanCommand->create();
565     if (ret != WIFI_SUCCESS)
566         goto cleanup;
567 
568     /* Set the interface Id of the message. */
569     ret = nanCommand->set_iface_id(ifaceInfo->name);
570     if (ret != WIFI_SUCCESS)
571         goto cleanup;
572 
573     ret = nanCommand->putNanConfig(id, msg);
574     if (ret != WIFI_SUCCESS) {
575         ALOGE("%s: putNanConfig Error:%d",__FUNCTION__, ret);
576         goto cleanup;
577     }
578 
579     ret = nanCommand->requestEvent();
580     if (ret != WIFI_SUCCESS)
581         ALOGE("%s: requestEvent Error:%d",__FUNCTION__, ret);
582 
583 cleanup:
584     delete nanCommand;
585     return ret;
586 }
587 
588 /*  Function to send NAN request to the wifi driver.*/
nan_tca_request(transaction_id id,wifi_interface_handle iface,NanTCARequest * msg)589 wifi_error nan_tca_request(transaction_id id,
590                            wifi_interface_handle iface,
591                            NanTCARequest* msg)
592 {
593     wifi_error ret;
594     NanCommand *nanCommand = NULL;
595     interface_info *ifaceInfo = getIfaceInfo(iface);
596     wifi_handle wifiHandle = getWifiHandle(iface);
597     hal_info *info = getHalInfo(wifiHandle);
598 
599     if (info == NULL) {
600         ALOGE("%s: Error hal_info NULL", __FUNCTION__);
601         return WIFI_ERROR_UNKNOWN;
602     }
603 
604     nanCommand = new NanCommand(wifiHandle,
605                                 0,
606                                 OUI_QCA,
607                                 info->support_nan_ext_cmd?
608                                 QCA_NL80211_VENDOR_SUBCMD_NAN_EXT :
609                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
610     if (nanCommand == NULL) {
611         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
612         return WIFI_ERROR_UNKNOWN;
613     }
614 
615     ret = nanCommand->create();
616     if (ret != WIFI_SUCCESS)
617         goto cleanup;
618 
619     /* Set the interface Id of the message. */
620     ret = nanCommand->set_iface_id(ifaceInfo->name);
621     if (ret != WIFI_SUCCESS)
622         goto cleanup;
623 
624     ret = nanCommand->putNanTCA(id, msg);
625     if (ret != WIFI_SUCCESS) {
626         ALOGE("%s: putNanTCA Error:%d",__FUNCTION__, ret);
627         goto cleanup;
628     }
629 
630     ret = nanCommand->requestEvent();
631     if (ret != WIFI_SUCCESS)
632         ALOGE("%s: requestEvent Error:%d",__FUNCTION__, ret);
633 
634 cleanup:
635     delete nanCommand;
636     return ret;
637 }
638 
639 /*  Function to send NAN Beacon sdf payload to the wifi driver.
640     This instructs the Discovery Engine to begin publishing the
641     received payload in any Beacon or Service Discovery Frame
642     transmitted*/
nan_beacon_sdf_payload_request(transaction_id id,wifi_interface_handle iface,NanBeaconSdfPayloadRequest * msg)643 wifi_error nan_beacon_sdf_payload_request(transaction_id id,
644                                          wifi_interface_handle iface,
645                                          NanBeaconSdfPayloadRequest* msg)
646 {
647     wifi_error ret;
648     NanCommand *nanCommand = NULL;
649     interface_info *ifaceInfo = getIfaceInfo(iface);
650     wifi_handle wifiHandle = getWifiHandle(iface);
651     hal_info *info = getHalInfo(wifiHandle);
652 
653     if (info == NULL) {
654         ALOGE("%s: Error hal_info NULL", __FUNCTION__);
655         return WIFI_ERROR_UNKNOWN;
656     }
657 
658     nanCommand = new NanCommand(wifiHandle,
659                                 0,
660                                 OUI_QCA,
661                                 info->support_nan_ext_cmd?
662                                 QCA_NL80211_VENDOR_SUBCMD_NAN_EXT :
663                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
664     if (nanCommand == NULL) {
665         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
666         return WIFI_ERROR_UNKNOWN;
667     }
668 
669     ret = nanCommand->create();
670     if (ret != WIFI_SUCCESS)
671         goto cleanup;
672 
673     /* Set the interface Id of the message. */
674     ret = nanCommand->set_iface_id(ifaceInfo->name);
675     if (ret != WIFI_SUCCESS)
676         goto cleanup;
677 
678     ret = nanCommand->putNanBeaconSdfPayload(id, msg);
679     if (ret != WIFI_SUCCESS) {
680         ALOGE("%s: putNanBeaconSdfPayload Error:%d", __FUNCTION__, ret);
681         goto cleanup;
682     }
683 
684     ret = nanCommand->requestEvent();
685     if (ret != WIFI_SUCCESS)
686         ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
687 
688 cleanup:
689     delete nanCommand;
690     return ret;
691 }
692 
nan_get_sta_parameter(transaction_id id,wifi_interface_handle iface,NanStaParameter * msg)693 wifi_error nan_get_sta_parameter(transaction_id id,
694                                  wifi_interface_handle iface,
695                                  NanStaParameter* msg)
696 {
697     wifi_error ret;
698     NanCommand *nanCommand = NULL;
699     wifi_handle wifiHandle = getWifiHandle(iface);
700 
701     nanCommand = NanCommand::instance(wifiHandle);
702     if (nanCommand == NULL) {
703         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
704         return WIFI_ERROR_UNKNOWN;
705     }
706 
707     ret = nanCommand->getNanStaParameter(iface, msg);
708     if (ret != WIFI_SUCCESS) {
709         ALOGE("%s: getNanStaParameter Error:%d", __FUNCTION__, ret);
710         goto cleanup;
711     }
712 
713 cleanup:
714     return ret;
715 }
716 
717 /*  Function to get NAN capabilities */
nan_get_capabilities(transaction_id id,wifi_interface_handle iface)718 wifi_error nan_get_capabilities(transaction_id id,
719                                 wifi_interface_handle iface)
720 {
721     wifi_error ret;
722     NanCommand *nanCommand = NULL;
723     interface_info *ifaceInfo = getIfaceInfo(iface);
724     wifi_handle wifiHandle = getWifiHandle(iface);
725     hal_info *info = getHalInfo(wifiHandle);
726 
727     if (info == NULL) {
728         ALOGE("%s: Error hal_info NULL", __FUNCTION__);
729         return WIFI_ERROR_UNKNOWN;
730     }
731 
732     nanCommand = new NanCommand(wifiHandle,
733                                 0,
734                                 OUI_QCA,
735                                 info->support_nan_ext_cmd?
736                                 QCA_NL80211_VENDOR_SUBCMD_NAN_EXT :
737                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
738     if (nanCommand == NULL) {
739         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
740         return WIFI_ERROR_UNKNOWN;
741     }
742 
743     ret = nanCommand->create();
744     if (ret != WIFI_SUCCESS)
745         goto cleanup;
746 
747     /* Set the interface Id of the message. */
748     ret = nanCommand->set_iface_id(ifaceInfo->name);
749     if (ret != WIFI_SUCCESS)
750         goto cleanup;
751 
752     ret = nanCommand->putNanCapabilities(id);
753     if (ret != WIFI_SUCCESS) {
754         ALOGE("%s: putNanCapabilities Error:%d",__FUNCTION__, ret);
755         goto cleanup;
756     }
757 
758     ret = nanCommand->requestEvent();
759     if (ret != WIFI_SUCCESS)
760         ALOGE("%s: requestEvent Error:%d",__FUNCTION__, ret);
761 
762 cleanup:
763     delete nanCommand;
764     return ret;
765 }
766 
767 /*  Function to get NAN capabilities */
nan_debug_command_config(transaction_id id,wifi_interface_handle iface,NanDebugParams debug,int debug_msg_length)768 wifi_error nan_debug_command_config(transaction_id id,
769                                    wifi_interface_handle iface,
770                                    NanDebugParams debug,
771                                    int debug_msg_length)
772 {
773     wifi_error ret;
774     NanCommand *nanCommand = NULL;
775     interface_info *ifaceInfo = getIfaceInfo(iface);
776     wifi_handle wifiHandle = getWifiHandle(iface);
777     hal_info *info = getHalInfo(wifiHandle);
778 
779     if (info == NULL) {
780         ALOGE("%s: Error hal_info NULL", __FUNCTION__);
781         return WIFI_ERROR_UNKNOWN;
782     }
783 
784     if (debug_msg_length <= 0) {
785         ALOGE("%s: Invalid debug message length = %d", __FUNCTION__,
786                                                        debug_msg_length);
787         return WIFI_ERROR_UNKNOWN;
788     }
789 
790     nanCommand = new NanCommand(wifiHandle,
791                                 0,
792                                 OUI_QCA,
793                                 info->support_nan_ext_cmd?
794                                 QCA_NL80211_VENDOR_SUBCMD_NAN_EXT :
795                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
796     if (nanCommand == NULL) {
797         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
798         return WIFI_ERROR_UNKNOWN;
799     }
800 
801     ret = nanCommand->create();
802     if (ret != WIFI_SUCCESS)
803         goto cleanup;
804 
805     /* Set the interface Id of the message. */
806     ret = nanCommand->set_iface_id(ifaceInfo->name);
807     if (ret != WIFI_SUCCESS)
808         goto cleanup;
809 
810     ret = nanCommand->putNanDebugCommand(debug, debug_msg_length);
811     if (ret != WIFI_SUCCESS) {
812         ALOGE("%s: putNanDebugCommand Error:%d",__FUNCTION__, ret);
813         goto cleanup;
814     }
815 
816     ret = nanCommand->requestEvent();
817     if (ret != WIFI_SUCCESS)
818         ALOGE("%s: requestEvent Error:%d",__FUNCTION__, ret);
819 
820 cleanup:
821     delete nanCommand;
822     return ret;
823 }
824 
nan_initialize_vendor_cmd(wifi_interface_handle iface,NanCommand ** nanCommand)825 wifi_error nan_initialize_vendor_cmd(wifi_interface_handle iface,
826                                      NanCommand **nanCommand)
827 {
828     wifi_error ret;
829     interface_info *ifaceInfo = getIfaceInfo(iface);
830     wifi_handle wifiHandle = getWifiHandle(iface);
831 
832     if (nanCommand == NULL) {
833         ALOGE("%s: Error nanCommand NULL", __FUNCTION__);
834         return WIFI_ERROR_INVALID_ARGS;
835     }
836 
837     *nanCommand = new NanCommand(wifiHandle,
838                                  0,
839                                  OUI_QCA,
840                                  QCA_NL80211_VENDOR_SUBCMD_NDP);
841     if (*nanCommand == NULL) {
842         ALOGE("%s: Object creation failed", __FUNCTION__);
843         return WIFI_ERROR_OUT_OF_MEMORY;
844     }
845 
846     /* Create the message */
847     ret = (*nanCommand)->create();
848     if (ret != WIFI_SUCCESS)
849         goto cleanup;
850 
851     ret = (*nanCommand)->set_iface_id(ifaceInfo->name);
852     if (ret != WIFI_SUCCESS)
853         goto cleanup;
854 
855     return WIFI_SUCCESS;
856 
857 cleanup:
858     delete *nanCommand;
859     return ret;
860 }
861 
nan_data_interface_create(transaction_id id,wifi_interface_handle iface,char * iface_name)862 wifi_error nan_data_interface_create(transaction_id id,
863                                      wifi_interface_handle iface,
864                                      char* iface_name)
865 {
866     ALOGV("NAN_DP_INTERFACE_CREATE");
867     wifi_error ret;
868     struct nlattr *nlData;
869     NanCommand *nanCommand = NULL;
870     WiFiConfigCommand *wifiConfigCommand;
871     wifi_handle handle = getWifiHandle(iface);
872     hal_info *info = getHalInfo(handle);
873     bool ndi_created = false;
874 
875     if (iface_name == NULL) {
876         ALOGE("%s: Invalid Nan Data Interface Name. \n", __FUNCTION__);
877         return WIFI_ERROR_INVALID_ARGS;
878     }
879 
880     if (!info || info->num_interfaces < 1) {
881         ALOGE("%s: Error wifi_handle NULL or base wlan interface not present",
882               __FUNCTION__);
883         return WIFI_ERROR_UNKNOWN;
884     }
885 
886     if (check_feature(QCA_WLAN_VENDOR_FEATURE_USE_ADD_DEL_VIRTUAL_INTF_FOR_NDI,
887                       &info->driver_supported_features)) {
888         wifiConfigCommand = new WiFiConfigCommand(handle,
889                                                   get_requestid(), 0, 0);
890         if (wifiConfigCommand == NULL) {
891             ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__);
892             return WIFI_ERROR_UNKNOWN;
893         }
894         wifiConfigCommand->create_generic(NL80211_CMD_NEW_INTERFACE);
895         wifiConfigCommand->put_u32(NL80211_ATTR_IFINDEX,
896                                    info->interfaces[0]->id);
897         wifiConfigCommand->put_string(NL80211_ATTR_IFNAME, iface_name);
898         wifiConfigCommand->put_u32(NL80211_ATTR_IFTYPE,
899                                    NL80211_IFTYPE_STATION);
900         /* Send the NL msg. */
901         wifiConfigCommand->waitForRsp(false);
902         ret = wifiConfigCommand->requestEvent();
903         if (ret != WIFI_SUCCESS) {
904             ALOGE("%s: Create intf failed, Error:%d", __FUNCTION__, ret);
905             delete wifiConfigCommand;
906             return ret;
907         }
908         ndi_created = true;
909         delete wifiConfigCommand;
910     }
911 
912     ret = nan_initialize_vendor_cmd(iface, &nanCommand);
913     if (ret != WIFI_SUCCESS) {
914         ALOGE("%s: Initialization failed", __FUNCTION__);
915         goto delete_ndi;
916     }
917 
918     /* Add the vendor specific attributes for the NL command. */
919     nlData = nanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
920     if (!nlData) {
921         ret = WIFI_ERROR_UNKNOWN;
922         goto cleanup;
923     }
924 
925     if (nanCommand->put_u32(
926             QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
927             QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE) ||
928         nanCommand->put_u16(
929             QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
930             id) ||
931         nanCommand->put_string(
932             QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR,
933             iface_name)) {
934         ret = WIFI_ERROR_UNKNOWN;
935         goto cleanup;
936     }
937 
938     nanCommand->attr_end(nlData);
939 
940     ret = nanCommand->requestEvent();
941     if (ret != WIFI_SUCCESS)
942         ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
943 
944 cleanup:
945     delete nanCommand;
946 
947 delete_ndi:
948     if (ndi_created && ret != WIFI_SUCCESS) {
949         wifiConfigCommand = new WiFiConfigCommand(handle,
950                                                   get_requestid(), 0, 0);
951         if (wifiConfigCommand == NULL) {
952             ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__);
953             return ret;
954         }
955         wifiConfigCommand->create_generic(NL80211_CMD_DEL_INTERFACE);
956         wifiConfigCommand->put_u32(NL80211_ATTR_IFINDEX,
957                                    if_nametoindex(iface_name));
958         /* Send the NL msg. */
959         wifiConfigCommand->waitForRsp(false);
960         if (wifiConfigCommand->requestEvent() != WIFI_SUCCESS)
961             ALOGE("%s: Delete intf failed", __FUNCTION__);
962 
963         delete wifiConfigCommand;
964     }
965     return ret;
966 }
967 
nan_data_interface_delete(transaction_id id,wifi_interface_handle iface,char * iface_name)968 wifi_error nan_data_interface_delete(transaction_id id,
969                                      wifi_interface_handle iface,
970                                      char* iface_name)
971 {
972     ALOGV("NAN_DP_INTERFACE_DELETE");
973     wifi_error ret;
974     struct nlattr *nlData;
975     NanCommand *nanCommand = NULL;
976     WiFiConfigCommand *wifiConfigCommand;
977     wifi_handle handle = getWifiHandle(iface);
978     hal_info *info = getHalInfo(handle);
979 
980     if (iface_name == NULL) {
981         ALOGE("%s: Invalid Nan Data Interface Name. \n", __FUNCTION__);
982         return WIFI_ERROR_INVALID_ARGS;
983     }
984 
985     if (!info || info->num_interfaces < 1) {
986         ALOGE("%s: Error wifi_handle NULL or base wlan interface not present",
987           __FUNCTION__);
988         return WIFI_ERROR_UNKNOWN;
989     }
990 
991     ret = nan_initialize_vendor_cmd(iface,
992                                     &nanCommand);
993     if (ret != WIFI_SUCCESS) {
994         ALOGE("%s: Initialization failed", __FUNCTION__);
995         goto delete_ndi;
996     }
997 
998     /* Add the vendor specific attributes for the NL command. */
999     nlData = nanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
1000     if (!nlData) {
1001         ret = WIFI_ERROR_UNKNOWN;
1002         goto cleanup;
1003     }
1004 
1005     if (nanCommand->put_u32(
1006             QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1007             QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE) ||
1008         nanCommand->put_u16(
1009             QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
1010             id) ||
1011         nanCommand->put_string(
1012             QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR,
1013             iface_name)) {
1014         ret = WIFI_ERROR_UNKNOWN;
1015         goto cleanup;
1016     }
1017 
1018     nanCommand->attr_end(nlData);
1019 
1020     ret = nanCommand->requestEvent();
1021     if (ret != WIFI_SUCCESS)
1022         ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
1023 
1024 cleanup:
1025     delete nanCommand;
1026 
1027 delete_ndi:
1028     if ((check_feature(QCA_WLAN_VENDOR_FEATURE_USE_ADD_DEL_VIRTUAL_INTF_FOR_NDI,
1029                        &info->driver_supported_features)) &&
1030         if_nametoindex(iface_name)) {
1031         wifiConfigCommand = new WiFiConfigCommand(handle,
1032                                                   get_requestid(), 0, 0);
1033         if (wifiConfigCommand == NULL) {
1034             ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__);
1035             return WIFI_ERROR_UNKNOWN;
1036         }
1037         wifiConfigCommand->create_generic(NL80211_CMD_DEL_INTERFACE);
1038         wifiConfigCommand->put_u32(NL80211_ATTR_IFINDEX,
1039                                    if_nametoindex(iface_name));
1040         /* Send the NL msg. */
1041         wifiConfigCommand->waitForRsp(false);
1042         if (wifiConfigCommand->requestEvent() != WIFI_SUCCESS) {
1043             ALOGE("%s: Delete intf failed", __FUNCTION__);
1044         }
1045         delete wifiConfigCommand;
1046     }
1047 
1048     return ret;
1049 }
1050 
1051 /* Service ID using SHA256 */
1052 static bool
ndp_create_service_id(const u8 * service_name,u32 service_name_len,u8 * service_id)1053 ndp_create_service_id(const u8 *service_name,
1054                       u32 service_name_len, u8 *service_id)
1055 {
1056     u8 out_service_id[NAN_SVC_HASH_SIZE] = {0};
1057     u8 *mod_service_name;
1058     unsigned char prop_oob_service_name[NAN_DEF_SVC_NAME_LEN + 1] =
1059                                                         "Wi-Fi Aware Data Path";
1060     unsigned char prop_oob_service_name_lowercase[NAN_DEF_SVC_NAME_LEN + 1] =
1061                                                         "wi-fi aware data path";
1062     bool is_default = false;
1063     int i;
1064 
1065     if (!service_name) {
1066         ALOGE("%s: NULL service name", __FUNCTION__);
1067         return false;
1068     }
1069 
1070     if (!service_name_len) {
1071         ALOGE("%s: Zero service name length", __FUNCTION__);
1072         return false;
1073     }
1074 
1075     if (!service_id) {
1076         ALOGE("%s: NULL service ID", __FUNCTION__);
1077         return false;
1078     }
1079 
1080     mod_service_name = (u8 *)malloc(service_name_len);
1081     if (!mod_service_name) {
1082         ALOGE("%s: malloc failed", __FUNCTION__);
1083         return false;
1084     }
1085 
1086     memset(mod_service_name, 0, service_name_len);
1087     memcpy(mod_service_name, service_name, service_name_len);
1088     if ((service_name_len == NAN_DEF_SVC_NAME_LEN) &&
1089         (!memcmp(mod_service_name, prop_oob_service_name, service_name_len)
1090          || !memcmp(mod_service_name,
1091                     prop_oob_service_name_lowercase, service_name_len)))
1092         is_default = true;
1093 
1094     for (i = 0; i < service_name_len; i++) {
1095     /*
1096      * As per NAN spec, the only acceptable singlebyte UTF-8 symbols for a
1097      * Service Name are alphanumeric values (A-Z, a-z, 0-9), the hyphen ('-'),
1098      * the underscore ('_'), and the period ('.').
1099      * These checks are added for all service names except the above defined
1100      * default service name.
1101      */
1102         if (!is_default && !isalnum(mod_service_name[i]) &&
1103             (mod_service_name[i] != '_') && (mod_service_name[i] != '-') &&
1104             (mod_service_name[i] != '.')) {
1105              free(mod_service_name);
1106              return false;
1107         }
1108 
1109         if ((mod_service_name[i] == ' ') && (is_default))
1110              goto end;
1111 
1112         /*
1113          * The service_name hash SHALL always be done on a lower-case
1114          * version of service_name which was passed down. Therefore,
1115          * before passing the service_name to the SHA256 function first
1116          * run through the string and call tolower on each byte.
1117          */
1118         mod_service_name[i] = tolower(mod_service_name[i]);
1119     }
1120 
1121 end:
1122     SHA256(mod_service_name, service_name_len, out_service_id);
1123     /*
1124      * As per NAN spec, Service ID is the first 48 bits of the SHA-256 hash
1125      * of the Service Name
1126      */
1127     memcpy(service_id, out_service_id, NAN_SVC_ID_SIZE);
1128 
1129     free(mod_service_name);
1130     return true;
1131 }
1132 
1133 /*
1134  * PMK = PBKDF2(<pass phrase>, <Salt Version>||<Cipher Suite ID>||<Service ID>||
1135  *              <Publisher NMI>, 4096, 32)
1136  * ndp_passphrase_to_pmk: API to calculate the service ID and PMK.
1137  * @pmk: output value of Hash
1138  * @passphrase: secret key
1139  * @salt_version: 00
1140  * @csid: cipher suite ID: 01
1141  * As per NAN spec, below are the values defined for CSID attribute:
1142  *     1 - NCS-SK-128 Cipher Suite
1143  *     2 - NCS-SK-256 Cipher Suite
1144  *     3 - NCS-PK-2WDH-128 Cipher Suite
1145  *     4 - NCS-PK-2WDH-256 Cipher Suite
1146  *     Other values are reserved
1147  * @service_id: Hash value of SHA256 on service_name
1148  * @peer_mac: Publisher NAN Management Interface address
1149  * @iterations: 4096
1150  * @pmk_len: 32
1151  */
1152 static int
ndp_passphrase_to_pmk(u32 cipher_type,u8 * pmk,u8 * passphrase,u32 passphrase_len,u8 * service_name,u32 service_name_len,u8 * svc_id,u8 * peer_mac)1153 ndp_passphrase_to_pmk(u32 cipher_type, u8 *pmk, u8 *passphrase,
1154                       u32 passphrase_len, u8 *service_name,
1155                       u32 service_name_len, u8 *svc_id, u8 *peer_mac)
1156 {
1157     int result = 0;
1158     u8 pmk_hex[NAN_PMK_INFO_LEN] = {0};
1159     u8 salt[NAN_SECURITY_SALT_SIZE] = {0};
1160     u8 service_id[NAN_SVC_ID_SIZE] = {0};
1161     unsigned char *pos = NULL;
1162     unsigned char salt_version = 0;
1163     u8 csid;
1164     /* We read only first 3-bits, as only 1-4 values are expected currently */
1165     csid = (u8)(cipher_type & 0x7);
1166     if (csid == 0)
1167         csid = NAN_DEFAULT_NCS_SK;
1168 
1169     if (svc_id != NULL) {
1170         ALOGV("Service ID received from the pool");
1171         memcpy(service_id, svc_id, NAN_SVC_ID_SIZE);
1172     } else if (ndp_create_service_id((const u8 *)service_name,
1173                                      service_name_len, service_id) == false) {
1174         ALOGE("Failed to create service ID");
1175         return result;
1176     }
1177 
1178     pos = salt;
1179     /* salt version */
1180     *pos++ = salt_version;
1181     /* CSID */
1182     *pos++ = csid;
1183     /* Service ID */
1184     memcpy(pos, service_id, NAN_SVC_ID_SIZE);
1185     pos += NAN_SVC_ID_SIZE;
1186     /* Publisher NMI */
1187     memcpy(pos, peer_mac, NAN_MAC_ADDR_LEN);
1188     pos += NAN_MAC_ADDR_LEN;
1189 
1190     ALOGV("salt dump");
1191     hexdump(salt, NAN_SECURITY_SALT_SIZE);
1192 
1193     result = PKCS5_PBKDF2_HMAC((const char *)passphrase, passphrase_len, salt,
1194                                sizeof(salt), NAN_PMK_ITERATIONS,
1195                                (const EVP_MD *) EVP_sha256(),
1196                                NAN_PMK_INFO_LEN, pmk_hex);
1197     if (result)
1198         memcpy(pmk, pmk_hex, NAN_PMK_INFO_LEN);
1199 
1200     return result;
1201 }
1202 
nan_data_request_initiator(transaction_id id,wifi_interface_handle iface,NanDataPathInitiatorRequest * msg)1203 wifi_error nan_data_request_initiator(transaction_id id,
1204                                       wifi_interface_handle iface,
1205                                       NanDataPathInitiatorRequest* msg)
1206 {
1207     ALOGV("NAN_DP_REQUEST_INITIATOR");
1208     wifi_error ret;
1209     struct nlattr *nlData, *nlCfgQos;
1210     NanCommand *nanCommand = NULL;
1211     NanCommand *t_nanCommand = NULL;
1212     wifi_handle wifiHandle = getWifiHandle(iface);
1213 
1214     if (msg == NULL)
1215         return WIFI_ERROR_INVALID_ARGS;
1216 
1217     ret = nan_initialize_vendor_cmd(iface,
1218                                     &nanCommand);
1219     if (ret != WIFI_SUCCESS) {
1220         ALOGE("%s: Initialization failed", __FUNCTION__);
1221         return ret;
1222     }
1223 
1224     t_nanCommand = NanCommand::instance(wifiHandle);
1225     if (t_nanCommand == NULL)
1226         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
1227 
1228     if ((msg->cipher_type != NAN_CIPHER_SUITE_SHARED_KEY_NONE) &&
1229         (msg->key_info.body.pmk_info.pmk_len == 0) &&
1230         (msg->key_info.body.passphrase_info.passphrase_len == 0)) {
1231         ALOGE("%s: Failed-Initiator req, missing pmk and passphrase",
1232                __FUNCTION__);
1233         return WIFI_ERROR_INVALID_ARGS;
1234     }
1235 
1236     if ((msg->cipher_type != NAN_CIPHER_SUITE_SHARED_KEY_NONE) &&
1237         (msg->requestor_instance_id == OUT_OF_BAND_SERVICE_INSTANCE_ID) &&
1238         (msg->service_name_len == 0)) {
1239         ALOGE("%s: Failed-Initiator req, missing service name for out of band request",
1240               __FUNCTION__);
1241         return WIFI_ERROR_INVALID_ARGS;
1242     }
1243 
1244     /* Add the vendor specific attributes for the NL command. */
1245     nlData = nanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
1246     if (!nlData){
1247         ret = WIFI_ERROR_UNKNOWN;
1248         goto cleanup;
1249     }
1250 
1251     if (nanCommand->put_u32(
1252             QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1253             QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_REQUEST) ||
1254         nanCommand->put_u16(
1255             QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
1256             id) ||
1257         nanCommand->put_u32(
1258             QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID,
1259             msg->requestor_instance_id) ||
1260         nanCommand->put_bytes(
1261             QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR,
1262             (char *)msg->peer_disc_mac_addr,
1263             NAN_MAC_ADDR_LEN) ||
1264         nanCommand->put_string(
1265             QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR,
1266             msg->ndp_iface)) {
1267         ret = WIFI_ERROR_UNKNOWN;
1268         goto cleanup;
1269     }
1270 
1271     if (msg->channel_request_type != NAN_DP_CHANNEL_NOT_REQUESTED) {
1272         if (nanCommand->put_u32 (
1273                 QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG,
1274                 msg->channel_request_type) ||
1275             nanCommand->put_u32(
1276                 QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL,
1277                 msg->channel)){
1278             ret = WIFI_ERROR_UNKNOWN;
1279             goto cleanup;
1280         }
1281     }
1282 
1283     if (msg->app_info.ndp_app_info_len != 0) {
1284         if (nanCommand->put_bytes(
1285                 QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO,
1286                 (char *)msg->app_info.ndp_app_info,
1287                 msg->app_info.ndp_app_info_len)) {
1288             ret = WIFI_ERROR_UNKNOWN;
1289             goto cleanup;
1290         }
1291     }
1292 
1293     if (msg->ndp_cfg.qos_cfg == NAN_DP_CONFIG_QOS) {
1294         nlCfgQos =
1295             nanCommand->attr_start(QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS);
1296         if (!nlCfgQos){
1297             ret = WIFI_ERROR_UNKNOWN;
1298             goto cleanup;
1299         }
1300         /* TBD Qos Info */
1301         nanCommand->attr_end(nlCfgQos);
1302     }
1303     if (msg->cipher_type != NAN_CIPHER_SUITE_SHARED_KEY_NONE) {
1304         if (nanCommand->put_u32(QCA_WLAN_VENDOR_ATTR_NDP_CSID,
1305                 msg->cipher_type)){
1306             ret = WIFI_ERROR_UNKNOWN;
1307             goto cleanup;
1308         }
1309     }
1310     if (msg->key_info.key_type == NAN_SECURITY_KEY_INPUT_PMK) {
1311         if (msg->key_info.body.pmk_info.pmk_len != NAN_PMK_INFO_LEN) {
1312             ret = WIFI_ERROR_UNKNOWN;
1313             ALOGE("%s: Invalid pmk len:%d", __FUNCTION__,
1314                   msg->key_info.body.pmk_info.pmk_len);
1315             goto cleanup;
1316         }
1317         if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_PMK,
1318             (char *)msg->key_info.body.pmk_info.pmk,
1319             msg->key_info.body.pmk_info.pmk_len)){
1320             ret = WIFI_ERROR_UNKNOWN;
1321             goto cleanup;
1322         }
1323     } else if (msg->key_info.key_type == NAN_SECURITY_KEY_INPUT_PASSPHRASE) {
1324         if (msg->key_info.body.passphrase_info.passphrase_len <
1325             NAN_SECURITY_MIN_PASSPHRASE_LEN ||
1326             msg->key_info.body.passphrase_info.passphrase_len >
1327             NAN_SECURITY_MAX_PASSPHRASE_LEN) {
1328             ret = WIFI_ERROR_UNKNOWN;
1329             ALOGE("%s: Invalid passphrase len:%d", __FUNCTION__,
1330                   msg->key_info.body.passphrase_info.passphrase_len);
1331             goto cleanup;
1332         }
1333         u8 *service_id = NULL;
1334 
1335         if (t_nanCommand != NULL)
1336             service_id = t_nanCommand->getServiceId(msg->requestor_instance_id,
1337                                                     NAN_ROLE_SUBSCRIBER);
1338         if (service_id == NULL)
1339             ALOGE("%s: Entry not found for Instance ID:%d",
1340                   __FUNCTION__, msg->requestor_instance_id);
1341         if (((service_id != NULL) || (msg->service_name_len)) &&
1342             ndp_passphrase_to_pmk(msg->cipher_type,
1343                                   msg->key_info.body.pmk_info.pmk,
1344                                   msg->key_info.body.passphrase_info.passphrase,
1345                                   msg->key_info.body.passphrase_info.passphrase_len,
1346                                   msg->service_name, msg->service_name_len,
1347                                   service_id, msg->peer_disc_mac_addr)) {
1348             msg->key_info.body.pmk_info.pmk_len = NAN_PMK_INFO_LEN;
1349             if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_PMK,
1350                 (char *)msg->key_info.body.pmk_info.pmk,
1351                 msg->key_info.body.pmk_info.pmk_len)){
1352                 if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE,
1353                     (char *)msg->key_info.body.passphrase_info.passphrase,
1354                     msg->key_info.body.passphrase_info.passphrase_len)){
1355                     ret = WIFI_ERROR_UNKNOWN;
1356                     goto cleanup;
1357                 }
1358             }
1359         } else if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE,
1360                    (char *)msg->key_info.body.passphrase_info.passphrase,
1361                    msg->key_info.body.passphrase_info.passphrase_len)) {
1362             ret = WIFI_ERROR_UNKNOWN;
1363             goto cleanup;
1364         }
1365     }
1366     if (msg->service_name_len) {
1367         if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME,
1368             (char *)msg->service_name, msg->service_name_len)){
1369             ret = WIFI_ERROR_UNKNOWN;
1370             goto cleanup;
1371         }
1372     }
1373     nanCommand->attr_end(nlData);
1374 
1375     ret = nanCommand->requestEvent();
1376     if (ret != WIFI_SUCCESS)
1377         ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
1378 
1379 cleanup:
1380     delete nanCommand;
1381     return ret;
1382 }
1383 
nan_data_indication_response(transaction_id id,wifi_interface_handle iface,NanDataPathIndicationResponse * msg)1384 wifi_error nan_data_indication_response(transaction_id id,
1385                                         wifi_interface_handle iface,
1386                                         NanDataPathIndicationResponse* msg)
1387 {
1388     ALOGV("NAN_DP_INDICATION_RESPONSE");
1389     wifi_error ret;
1390     struct nlattr *nlData, *nlCfgQos;
1391     NanCommand *nanCommand = NULL;
1392     NanCommand *t_nanCommand = NULL;
1393     wifi_handle wifiHandle = getWifiHandle(iface);
1394 
1395     if (msg == NULL)
1396         return WIFI_ERROR_INVALID_ARGS;
1397 
1398     ret = nan_initialize_vendor_cmd(iface,
1399                                     &nanCommand);
1400     if (ret != WIFI_SUCCESS) {
1401         ALOGE("%s: Initialization failed", __FUNCTION__);
1402         return ret;
1403     }
1404 
1405     t_nanCommand = NanCommand::instance(wifiHandle);
1406     if (t_nanCommand == NULL)
1407         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
1408 
1409     if ((msg->cipher_type != NAN_CIPHER_SUITE_SHARED_KEY_NONE) &&
1410         (msg->key_info.body.pmk_info.pmk_len == 0) &&
1411         (msg->key_info.body.passphrase_info.passphrase_len == 0)) {
1412         ALOGE("%s: Failed-Initiator req, missing pmk and passphrase",
1413                __FUNCTION__);
1414         return WIFI_ERROR_INVALID_ARGS;
1415     }
1416 
1417     /* Add the vendor specific attributes for the NL command. */
1418     nlData = nanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
1419     if (!nlData){
1420         ret = WIFI_ERROR_UNKNOWN;
1421         goto cleanup;
1422     }
1423 
1424     if (nanCommand->put_u32(
1425             QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1426             QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_REQUEST) ||
1427         nanCommand->put_u16(
1428             QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
1429             id) ||
1430         nanCommand->put_u32(
1431             QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID,
1432             msg->ndp_instance_id) ||
1433         nanCommand->put_string(
1434             QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR,
1435             msg->ndp_iface) ||
1436         nanCommand->put_u32(
1437             QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE,
1438             msg->rsp_code)) {
1439         ret = WIFI_ERROR_UNKNOWN;
1440         goto cleanup;
1441     }
1442     if (msg->app_info.ndp_app_info_len != 0) {
1443         if (nanCommand->put_bytes(
1444                 QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO,
1445                 (char *)msg->app_info.ndp_app_info,
1446                 msg->app_info.ndp_app_info_len)) {
1447             ret = WIFI_ERROR_UNKNOWN;
1448             goto cleanup;
1449         }
1450     }
1451     if (msg->ndp_cfg.qos_cfg == NAN_DP_CONFIG_QOS) {
1452         nlCfgQos =
1453             nanCommand->attr_start(QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS);
1454         if (!nlCfgQos){
1455             ret = WIFI_ERROR_UNKNOWN;
1456             goto cleanup;
1457         }
1458 
1459         /* TBD Qos Info */
1460         nanCommand->attr_end(nlCfgQos);
1461     }
1462     if (msg->cipher_type != NAN_CIPHER_SUITE_SHARED_KEY_NONE) {
1463         if (nanCommand->put_u32(QCA_WLAN_VENDOR_ATTR_NDP_CSID,
1464                 msg->cipher_type)){
1465             ret = WIFI_ERROR_UNKNOWN;
1466             goto cleanup;
1467         }
1468     }
1469     if (msg->key_info.key_type == NAN_SECURITY_KEY_INPUT_PMK) {
1470         if (msg->key_info.body.pmk_info.pmk_len != NAN_PMK_INFO_LEN) {
1471             ret = WIFI_ERROR_UNKNOWN;
1472             ALOGE("%s: Invalid pmk len:%d", __FUNCTION__,
1473                   msg->key_info.body.pmk_info.pmk_len);
1474             goto cleanup;
1475         }
1476         if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_PMK,
1477             (char *)msg->key_info.body.pmk_info.pmk,
1478             msg->key_info.body.pmk_info.pmk_len)){
1479             ret = WIFI_ERROR_UNKNOWN;
1480             goto cleanup;
1481         }
1482     } else if (msg->key_info.key_type == NAN_SECURITY_KEY_INPUT_PASSPHRASE) {
1483         if (msg->key_info.body.passphrase_info.passphrase_len <
1484             NAN_SECURITY_MIN_PASSPHRASE_LEN ||
1485             msg->key_info.body.passphrase_info.passphrase_len >
1486             NAN_SECURITY_MAX_PASSPHRASE_LEN) {
1487             ret = WIFI_ERROR_UNKNOWN;
1488             ALOGE("%s: Invalid passphrase len:%d", __FUNCTION__,
1489                   msg->key_info.body.passphrase_info.passphrase_len);
1490             goto cleanup;
1491         }
1492         u8 *service_id = NULL;
1493 
1494         if (t_nanCommand != NULL)
1495             service_id = t_nanCommand->getServiceId(msg->ndp_instance_id,
1496                                                     NAN_ROLE_PUBLISHER);
1497         if (service_id == NULL)
1498             ALOGE("%s: Entry not found for Instance ID:%d",
1499                   __FUNCTION__, msg->ndp_instance_id);
1500         if (((service_id != NULL) || (msg->service_name_len)) &&
1501             (t_nanCommand != NULL) &&
1502             ndp_passphrase_to_pmk(msg->cipher_type,
1503                                   msg->key_info.body.pmk_info.pmk,
1504                                   msg->key_info.body.passphrase_info.passphrase,
1505                                   msg->key_info.body.passphrase_info.passphrase_len,
1506                                   msg->service_name, msg->service_name_len,
1507                                   service_id, t_nanCommand->getNmi())) {
1508             msg->key_info.body.pmk_info.pmk_len = NAN_PMK_INFO_LEN;
1509             if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_PMK,
1510                 (char *)msg->key_info.body.pmk_info.pmk,
1511                 msg->key_info.body.pmk_info.pmk_len))
1512                 if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE,
1513                     (char *)msg->key_info.body.passphrase_info.passphrase,
1514                     msg->key_info.body.passphrase_info.passphrase_len)){
1515                     ret = WIFI_ERROR_UNKNOWN;
1516                     goto cleanup;
1517                 }
1518         } else if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE,
1519                    (char *)msg->key_info.body.passphrase_info.passphrase,
1520                    msg->key_info.body.passphrase_info.passphrase_len)) {
1521             ret = WIFI_ERROR_UNKNOWN;
1522             goto cleanup;
1523         }
1524     }
1525 
1526     if (msg->service_name_len) {
1527         if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME,
1528             (char *)msg->service_name, msg->service_name_len)){
1529             ret = WIFI_ERROR_UNKNOWN;
1530             goto cleanup;
1531         }
1532     }
1533     nanCommand->attr_end(nlData);
1534 
1535     ret = nanCommand->requestEvent();
1536     if (ret != WIFI_SUCCESS)
1537         ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
1538 
1539 cleanup:
1540     delete nanCommand;
1541     return ret;
1542 }
1543 
nan_data_end(transaction_id id,wifi_interface_handle iface,NanDataPathEndRequest * msg)1544 wifi_error nan_data_end(transaction_id id,
1545                         wifi_interface_handle iface,
1546                         NanDataPathEndRequest* msg)
1547 {
1548     wifi_error ret;
1549     ALOGV("NAN_DP_END");
1550     struct nlattr *nlData;
1551     NanCommand *nanCommand = NULL;
1552 
1553     if (msg == NULL)
1554         return WIFI_ERROR_INVALID_ARGS;
1555 
1556     ret = nan_initialize_vendor_cmd(iface,
1557                                     &nanCommand);
1558     if (ret != WIFI_SUCCESS) {
1559         ALOGE("%s: Initialization failed", __FUNCTION__);
1560         return ret;
1561     }
1562 
1563     /* Add the vendor specific attributes for the NL command. */
1564     nlData = nanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
1565     if (!nlData){
1566         ret = WIFI_ERROR_UNKNOWN;
1567         goto cleanup;
1568     }
1569 
1570     if (nanCommand->put_u32(
1571             QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1572             QCA_WLAN_VENDOR_ATTR_NDP_END_REQUEST) ||
1573         nanCommand->put_u16(
1574             QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
1575             id) ||
1576         nanCommand->put_bytes(
1577             QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY,
1578             (char *)msg->ndp_instance_id,
1579             msg->num_ndp_instances * sizeof(u32))) {
1580         ret = WIFI_ERROR_UNKNOWN;
1581         goto cleanup;
1582     }
1583     nanCommand->attr_end(nlData);
1584 
1585     ret = nanCommand->requestEvent();
1586     if (ret != WIFI_SUCCESS)
1587         ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
1588 
1589 cleanup:
1590     delete nanCommand;
1591     return ret;
1592 }
1593 
1594 // Implementation related to nan class common functions
1595 // Constructor
1596 //Making the constructor private since this class is a singleton
NanCommand(wifi_handle handle,int id,u32 vendor_id,u32 subcmd)1597 NanCommand::NanCommand(wifi_handle handle, int id, u32 vendor_id, u32 subcmd)
1598         : WifiVendorCommand(handle, id, vendor_id, subcmd)
1599 {
1600     memset(&mHandler, 0,sizeof(mHandler));
1601     mNanVendorEvent = NULL;
1602     mNanDataLen = 0;
1603     mStaParam = NULL;
1604     memset(mNmiMac, 0, sizeof(mNmiMac));
1605     mStorePubParams = NULL;
1606     mStoreSubParams = NULL;
1607     mNanMaxPublishes = 0;
1608     mNanMaxSubscribes = 0;
1609     mNanDiscAddrIndDisabled = false;
1610 }
1611 
instance(wifi_handle handle)1612 NanCommand* NanCommand::instance(wifi_handle handle)
1613 {
1614     hal_info *info;
1615 
1616     if (handle == NULL) {
1617         ALOGE("Handle is invalid");
1618         return NULL;
1619     }
1620     info = getHalInfo(handle);
1621     if (info == NULL) {
1622         ALOGE("%s: Error hal_info NULL", __FUNCTION__);
1623         return NULL;
1624     }
1625 
1626     if (mNanCommandInstance == NULL) {
1627         mNanCommandInstance = new NanCommand(handle, 0,
1628                                              OUI_QCA,
1629                                              info->support_nan_ext_cmd?
1630                                              QCA_NL80211_VENDOR_SUBCMD_NAN_EXT :
1631                                              QCA_NL80211_VENDOR_SUBCMD_NAN);
1632         ALOGV("NanCommand %p created", mNanCommandInstance);
1633         return mNanCommandInstance;
1634     } else {
1635         if (handle != getWifiHandle(mNanCommandInstance->mInfo)) {
1636             /* upper layer must have cleaned up the handle and reinitialized,
1637                so we need to update the same */
1638             ALOGI("Handle different, update the handle");
1639             mNanCommandInstance->mInfo = (hal_info *)handle;
1640         }
1641     }
1642     ALOGV("NanCommand %p created already", mNanCommandInstance);
1643     return mNanCommandInstance;
1644 }
1645 
cleanup()1646 void NanCommand::cleanup()
1647 {
1648     //free the VendorData
1649     if (mVendorData) {
1650         free(mVendorData);
1651     }
1652     mVendorData = NULL;
1653     //cleanup the mMsg
1654     mMsg.destroy();
1655 }
1656 
~NanCommand()1657 NanCommand::~NanCommand()
1658 {
1659     ALOGV("NanCommand %p destroyed", this);
1660 }
1661 
handleResponse(WifiEvent & reply)1662 int NanCommand::handleResponse(WifiEvent &reply){
1663     return NL_SKIP;
1664 }
1665 
1666 /* Save NAN Management Interface address */
saveNmi(u8 * mac)1667 void NanCommand::saveNmi(u8 *mac)
1668 {
1669     memcpy(mNmiMac, mac, NAN_MAC_ADDR_LEN);
1670 }
1671 
1672 /* Get NAN Management Interface address */
getNmi()1673 u8 *NanCommand::getNmi()
1674 {
1675     return mNmiMac;
1676 }
1677 
1678 /*
1679  * Save the service ID along with Subscribe/Publish ID and Instance ID, which
1680  * will be used later for Passphrase to PMK calculation.
1681  *
1682  * service_id - Service ID received from Firmware either in NAN/NDP Indication
1683  * sub_pub_handle - Subscribe/Publish ID received in NAN/NDP Indication
1684  * instance_id - Service/NDP instance ID received in NAN/NDP Indication
1685  * pool - Subscriber/Publisher entry based on NAN/NDP Indication
1686  */
saveServiceId(u8 * service_id,u16 sub_pub_handle,u32 instance_id,NanRole pool)1687 void NanCommand::saveServiceId(u8 *service_id, u16 sub_pub_handle,
1688                                u32 instance_id, NanRole pool)
1689 {
1690     int i;
1691 
1692     if ((service_id == NULL) || (!sub_pub_handle) || (!instance_id)) {
1693         ALOGE("%s: Null Parameter received, sub_pub_handle=%d instance_id=%d",
1694               __FUNCTION__, sub_pub_handle, instance_id);
1695         return;
1696     }
1697     switch(pool) {
1698     case NAN_ROLE_PUBLISHER:
1699         if ((mStorePubParams == NULL) || !mNanMaxPublishes)
1700             return;
1701         for (i = 0; i < mNanMaxPublishes; i++) {
1702             /* In 1:n case there can be multiple publish entries with same
1703              * publish ID, hence save the new entry if instance ID doesn't match
1704              * with the existing entries in the pool
1705              */
1706             if ((mStorePubParams[i].subscriber_publisher_id) &&
1707                 (mStorePubParams[i].instance_id != instance_id))
1708                 continue;
1709 
1710             memset(&mStorePubParams[i], 0, sizeof(mStorePubParams));
1711             memcpy(mStorePubParams[i].service_id, service_id, NAN_SVC_ID_SIZE);
1712             mStorePubParams[i].subscriber_publisher_id = sub_pub_handle;
1713             mStorePubParams[i].instance_id = instance_id;
1714             ALOGV("Added new entry in Publisher pool at index=%d with "
1715                   "Publish ID=%d and Instance ID=%d", i,
1716                   mStorePubParams[i].subscriber_publisher_id,
1717                   mStorePubParams[i].instance_id);
1718             return;
1719         }
1720         if (i == mNanMaxPublishes)
1721             ALOGV("No empty slot found in publisher pool, entry not saved");
1722     break;
1723     case NAN_ROLE_SUBSCRIBER:
1724         if ((mStoreSubParams == NULL) || !mNanMaxSubscribes)
1725             return;
1726         for (i = 0; i < mNanMaxSubscribes; i++) {
1727             /* In 1:n case there can be multiple subscribe entries with same
1728              * subscribe ID, hence save new entry if instance ID doesn't match
1729              * with the existing entries in the pool
1730              */
1731             if ((mStoreSubParams[i].subscriber_publisher_id) &&
1732                 (mStoreSubParams[i].instance_id != instance_id))
1733                 continue;
1734 
1735             memset(&mStoreSubParams[i], 0, sizeof(mStoreSubParams));
1736             memcpy(mStoreSubParams[i].service_id, service_id, NAN_SVC_ID_SIZE);
1737             mStoreSubParams[i].subscriber_publisher_id = sub_pub_handle;
1738             mStoreSubParams[i].instance_id = instance_id;
1739             ALOGV("Added new entry in Subscriber pool at index=%d with "
1740                   "Subscribe ID=%d and Instance ID=%d", i,
1741                   mStoreSubParams[i].subscriber_publisher_id,
1742                   mStoreSubParams[i].instance_id);
1743             return;
1744         }
1745         if (i == mNanMaxSubscribes)
1746             ALOGV("No empty slot found in subscriber pool, entry not saved");
1747     break;
1748     default:
1749         ALOGE("Invalid Pool: %d", pool);
1750     break;
1751     }
1752 }
1753 
1754 /*
1755  * Get the Service ID from the pool based on the Service/NDP instance ID that
1756  * will be used for Passphrase to PMK calculation in Initiator/Responder request
1757  *
1758  * instance_id - Service/NDP instance ID received in NAN/NDP Indication
1759  * pool - Subscriber/Publisher role based on the Initiator/Responder
1760  */
getServiceId(u32 instance_id,NanRole pool)1761 u8 *NanCommand::getServiceId(u32 instance_id, NanRole pool)
1762 {
1763     int i;
1764 
1765     switch(pool) {
1766     case NAN_ROLE_PUBLISHER:
1767         if ((mStorePubParams == NULL) || (!instance_id) || !mNanMaxPublishes)
1768             return NULL;
1769         ALOGV("Getting Service ID from publisher pool for instance ID=%d", instance_id);
1770         for (i = 0; i < mNanMaxPublishes; i++) {
1771             if (mStorePubParams[i].instance_id == instance_id)
1772                 return mStorePubParams[i].service_id;
1773         }
1774     break;
1775     case NAN_ROLE_SUBSCRIBER:
1776         if ((mStoreSubParams == NULL )|| (!instance_id) || !mNanMaxSubscribes)
1777             return NULL;
1778         ALOGV("Getting Service ID from subscriber pool for instance ID=%d", instance_id);
1779         for (i = 0; i < mNanMaxSubscribes; i++) {
1780             if (mStoreSubParams[i].instance_id == instance_id)
1781                 return mStoreSubParams[i].service_id;
1782         }
1783     break;
1784     default:
1785         ALOGE("Invalid Pool: %d", pool);
1786     break;
1787     }
1788     return NULL;
1789 }
1790 
1791 /*
1792  * Delete service ID entry from the pool based on the subscriber/Instance ID
1793  *
1794  * sub_handle - Subscriber ID received from the Subscribe Cancel
1795  * instance_id - NDP Instance ID received from the NDP End Indication
1796  */
deleteServiceId(u16 sub_handle,u32 instance_id,NanRole pool)1797 void NanCommand::deleteServiceId(u16 sub_handle,
1798                                  u32 instance_id, NanRole pool)
1799 {
1800     int i;
1801 
1802     switch(pool) {
1803     case NAN_ROLE_PUBLISHER:
1804         if ((mStorePubParams == NULL) || (!instance_id) || !mNanMaxPublishes)
1805             return;
1806         for (i = 0; i < mNanMaxPublishes; i++) {
1807             /* Delete all the entries that has the matching Instance ID */
1808             if (mStorePubParams[i].instance_id == instance_id) {
1809                 ALOGV("Deleted entry at index=%d from publisher pool "
1810                       "with publish ID=%d and instance ID=%d", i,
1811                       mStorePubParams[i].subscriber_publisher_id,
1812                       mStorePubParams[i].instance_id);
1813                 memset(&mStorePubParams[i], 0, sizeof(mStorePubParams));
1814             }
1815         }
1816     break;
1817     case NAN_ROLE_SUBSCRIBER:
1818         if ((mStoreSubParams == NULL) || (!sub_handle) || !mNanMaxSubscribes)
1819             return;
1820         for (i = 0; i < mNanMaxSubscribes; i++) {
1821             /* Delete all the entries that has the matching subscribe ID */
1822             if (mStoreSubParams[i].subscriber_publisher_id == sub_handle) {
1823                 ALOGV("Deleted entry at index=%d from subsriber pool "
1824                       "with subscribe ID=%d and instance ID=%d", i,
1825                       mStoreSubParams[i].subscriber_publisher_id,
1826                       mStoreSubParams[i].instance_id);
1827                 memset(&mStoreSubParams[i], 0, sizeof(mStoreSubParams));
1828             }
1829         }
1830     break;
1831     default:
1832         ALOGE("Invalid Pool: %d", pool);
1833     break;
1834     }
1835 }
1836 
1837 /*
1838  * Allocate the memory for the Subscribe and Publish pools using the Max values
1839  * mStorePubParams - Points the Publish pool
1840  * mStoreSubParams - Points the Subscribe pool
1841  */
allocSvcParams()1842 void NanCommand::allocSvcParams()
1843 {
1844     if (mNanMaxPublishes < NAN_DEF_PUB_SUB)
1845         mNanMaxPublishes = NAN_DEF_PUB_SUB;
1846     if (mNanMaxSubscribes < NAN_DEF_PUB_SUB)
1847         mNanMaxSubscribes = NAN_DEF_PUB_SUB;
1848 
1849     if ((mStorePubParams == NULL) && mNanMaxPublishes) {
1850         mStorePubParams =
1851         (NanStoreSvcParams *)malloc(mNanMaxPublishes*sizeof(NanStoreSvcParams));
1852         if (mStorePubParams == NULL) {
1853             ALOGE("%s: Publish pool malloc failed", __FUNCTION__);
1854             deallocSvcParams();
1855             return;
1856         }
1857         ALOGV("%s: Allocated the Publish pool for max %d entries",
1858               __FUNCTION__, mNanMaxPublishes);
1859     }
1860     if ((mStoreSubParams == NULL) && mNanMaxSubscribes) {
1861         mStoreSubParams =
1862         (NanStoreSvcParams *)malloc(mNanMaxSubscribes*sizeof(NanStoreSvcParams));
1863         if (mStoreSubParams == NULL) {
1864             ALOGE("%s: Subscribe pool malloc failed", __FUNCTION__);
1865             deallocSvcParams();
1866             return;
1867         }
1868         ALOGV("%s: Allocated the Subscribe pool for max %d entries",
1869               __FUNCTION__, mNanMaxSubscribes);
1870     }
1871 }
1872 
1873 /*
1874  * Reallocate the memory for Subscribe and Publish pools using the Max values
1875  * mStorePubParams - Points the Publish pool
1876  * mStoreSubParams - Points the Subscribe pool
1877  */
reallocSvcParams(NanRole pool)1878 void NanCommand::reallocSvcParams(NanRole pool)
1879 {
1880     switch(pool) {
1881     case NAN_ROLE_PUBLISHER:
1882         if ((mStorePubParams != NULL) && mNanMaxPublishes) {
1883             mStorePubParams =
1884             (NanStoreSvcParams *)realloc(mStorePubParams,
1885                                          mNanMaxPublishes*sizeof(NanStoreSvcParams));
1886             if (mStorePubParams == NULL) {
1887                 ALOGE("%s: Publish pool realloc failed", __FUNCTION__);
1888                 deallocSvcParams();
1889                 return;
1890             }
1891             ALOGV("%s: Reallocated the Publish pool for max %d entries",
1892                    __FUNCTION__, mNanMaxPublishes);
1893         }
1894     break;
1895     case NAN_ROLE_SUBSCRIBER:
1896         if ((mStoreSubParams != NULL) && mNanMaxSubscribes) {
1897             mStoreSubParams =
1898             (NanStoreSvcParams *)realloc(mStoreSubParams,
1899                                          mNanMaxSubscribes*sizeof(NanStoreSvcParams));
1900             if (mStoreSubParams == NULL) {
1901                 ALOGE("%s: Subscribe pool realloc failed", __FUNCTION__);
1902                 deallocSvcParams();
1903                 return;
1904             }
1905             ALOGV("%s: Reallocated the Subscribe pool for max %d entries",
1906                   __FUNCTION__, mNanMaxSubscribes);
1907         }
1908     break;
1909     default:
1910         ALOGE("Invalid Pool: %d", pool);
1911     break;
1912     }
1913 }
1914 
1915 /*
1916  * Deallocate the Subscribe and Publish pools
1917  * mStorePubParams - Points the Publish pool
1918  * mStoreSubParams - Points the Subscribe pool
1919  */
deallocSvcParams()1920 void NanCommand::deallocSvcParams()
1921 {
1922     if (mStorePubParams != NULL) {
1923         free(mStorePubParams);
1924         mStorePubParams = NULL;
1925         ALOGV("%s: Deallocated Publish pool", __FUNCTION__);
1926     }
1927     if (mStoreSubParams != NULL) {
1928         free(mStoreSubParams);
1929         mStoreSubParams = NULL;
1930         ALOGV("%s: Deallocated Subscribe pool", __FUNCTION__);
1931     }
1932 }
1933 
setCallbackHandler(NanCallbackHandler nHandler)1934 wifi_error NanCommand::setCallbackHandler(NanCallbackHandler nHandler)
1935 {
1936     wifi_error res;
1937     mHandler = nHandler;
1938     res = registerVendorHandler(mVendor_id, QCA_NL80211_VENDOR_SUBCMD_NAN);
1939     if (res != WIFI_SUCCESS) {
1940         //error case should not happen print log
1941         ALOGE("%s: Unable to register Vendor Handler Vendor Id=0x%x"
1942               "subcmd=QCA_NL80211_VENDOR_SUBCMD_NAN", __FUNCTION__, mVendor_id);
1943         return res;
1944     }
1945 
1946     res = registerVendorHandler(mVendor_id, QCA_NL80211_VENDOR_SUBCMD_NDP);
1947     if (res != WIFI_SUCCESS) {
1948         //error case should not happen print log
1949         ALOGE("%s: Unable to register Vendor Handler Vendor Id=0x%x"
1950               "subcmd=QCA_NL80211_VENDOR_SUBCMD_NDP", __FUNCTION__, mVendor_id);
1951         return res;
1952     }
1953     return res;
1954 }
1955 
1956 /* This function implements creation of Vendor command */
create()1957 wifi_error NanCommand::create() {
1958     wifi_error ret = mMsg.create(NL80211_CMD_VENDOR, 0, 0);
1959     if (ret != WIFI_SUCCESS)
1960         goto out;
1961 
1962     /* Insert the oui in the msg */
1963     ret = mMsg.put_u32(NL80211_ATTR_VENDOR_ID, mVendor_id);
1964     if (ret != WIFI_SUCCESS)
1965         goto out;
1966     /* Insert the subcmd in the msg */
1967     ret = mMsg.put_u32(NL80211_ATTR_VENDOR_SUBCMD, mSubcmd);
1968 
1969 out:
1970     if (ret != WIFI_SUCCESS)
1971         mMsg.destroy();
1972     return ret;
1973 }
1974 
1975 // This function will be the main handler for incoming event
1976 // QCA_NL80211_VENDOR_SUBCMD_NAN
1977 //Call the appropriate callback handler after parsing the vendor data.
handleEvent(WifiEvent & event)1978 int NanCommand::handleEvent(WifiEvent &event)
1979 {
1980     WifiVendorCommand::handleEvent(event);
1981     ALOGV("%s: Subcmd=%u Vendor data len received:%d",
1982           __FUNCTION__, mSubcmd, mDataLen);
1983     hexdump(mVendorData, mDataLen);
1984 
1985     if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NAN){
1986         // Parse the vendordata and get the NAN attribute
1987         struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_MAX + 1];
1988         nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_MAX,
1989                   (struct nlattr *)mVendorData,
1990                   mDataLen, NULL);
1991         // Populating the mNanVendorEvent and mNanDataLen to point to NAN data.
1992         mNanVendorEvent = (char *)nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NAN]);
1993         mNanDataLen = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NAN]);
1994 
1995         if (isNanResponse()) {
1996             //handleNanResponse will parse the data and call
1997             //the response callback handler with the populated
1998             //NanResponseMsg
1999             handleNanResponse();
2000         } else {
2001             //handleNanIndication will parse the data and call
2002             //the corresponding Indication callback handler
2003             //with the corresponding populated Indication event
2004             handleNanIndication();
2005         }
2006     } else if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NDP) {
2007         // Parse the vendordata and get the NAN attribute
2008         u32 ndpCmdType;
2009         struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1];
2010         nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX,
2011                   (struct nlattr *)mVendorData,
2012                   mDataLen, NULL);
2013 
2014         if (tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD]) {
2015             ndpCmdType =
2016                 nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD]);
2017                 ALOGD("%s: NDP Cmd Type : val 0x%x",
2018                       __FUNCTION__, ndpCmdType);
2019                 switch (ndpCmdType) {
2020                 case QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE:
2021                     handleNdpResponse(NAN_DP_INTERFACE_CREATE, tb_vendor);
2022                     break;
2023                 case QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE:
2024                     handleNdpResponse(NAN_DP_INTERFACE_DELETE, tb_vendor);
2025                     break;
2026                 case QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_RESPONSE:
2027                     handleNdpResponse(NAN_DP_INITIATOR_RESPONSE, tb_vendor);
2028                     break;
2029                 case QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_RESPONSE:
2030                     handleNdpResponse(NAN_DP_RESPONDER_RESPONSE, tb_vendor);
2031                     break;
2032                 case QCA_WLAN_VENDOR_ATTR_NDP_END_RESPONSE:
2033                     handleNdpResponse(NAN_DP_END, tb_vendor);
2034                     break;
2035                 case QCA_WLAN_VENDOR_ATTR_NDP_REQUEST_IND:
2036                 case QCA_WLAN_VENDOR_ATTR_NDP_CONFIRM_IND:
2037                 case QCA_WLAN_VENDOR_ATTR_NDP_END_IND:
2038                 case QCA_WLAN_VENDOR_ATTR_NDP_SCHEDULE_UPDATE_IND:
2039                     handleNdpIndication(ndpCmdType, tb_vendor);
2040                     break;
2041                 default:
2042                     ALOGE("%s: Invalid NDP subcmd response received %d",
2043                           __FUNCTION__, ndpCmdType);
2044                 }
2045         }
2046     } else {
2047         //error case should not happen print log
2048         ALOGE("%s: Wrong NAN subcmd received %d", __FUNCTION__, mSubcmd);
2049     }
2050     mNanVendorEvent = NULL;
2051     return NL_SKIP;
2052 }
2053 
2054 /*Helper function to Write and Read TLV called in indication as well as request */
NANTLV_WriteTlv(pNanTlv pInTlv,u8 * pOutTlv)2055 u16 NANTLV_WriteTlv(pNanTlv pInTlv, u8 *pOutTlv)
2056 {
2057     u16 writeLen = 0;
2058     u16 i;
2059 
2060     if (!pInTlv)
2061     {
2062         ALOGE("NULL pInTlv");
2063         return writeLen;
2064     }
2065 
2066     if (!pOutTlv)
2067     {
2068         ALOGE("NULL pOutTlv");
2069         return writeLen;
2070     }
2071 
2072     *pOutTlv++ = pInTlv->type & 0xFF;
2073     *pOutTlv++ = (pInTlv->type & 0xFF00) >> 8;
2074     writeLen += 2;
2075 
2076     ALOGV("WRITE TLV type %u, writeLen %u", pInTlv->type, writeLen);
2077 
2078     *pOutTlv++ = pInTlv->length & 0xFF;
2079     *pOutTlv++ = (pInTlv->length & 0xFF00) >> 8;
2080     writeLen += 2;
2081 
2082     ALOGV("WRITE TLV length %u, writeLen %u", pInTlv->length, writeLen);
2083 
2084     for (i=0; i < pInTlv->length; ++i)
2085     {
2086         *pOutTlv++ = pInTlv->value[i];
2087     }
2088 
2089     writeLen += pInTlv->length;
2090     ALOGV("WRITE TLV value, writeLen %u", writeLen);
2091     return writeLen;
2092 }
2093 
NANTLV_ReadTlv(u8 * pInTlv,pNanTlv pOutTlv,int inBufferSize)2094 u16 NANTLV_ReadTlv(u8 *pInTlv, pNanTlv pOutTlv, int inBufferSize)
2095 {
2096     u16 readLen = 0;
2097 
2098     if (!pInTlv)
2099     {
2100         ALOGE("NULL pInTlv");
2101         return readLen;
2102     }
2103 
2104     if (!pOutTlv)
2105     {
2106         ALOGE("NULL pOutTlv");
2107         return readLen;
2108     }
2109 
2110     if(inBufferSize < NAN_TLV_HEADER_SIZE) {
2111         ALOGE("Insufficient length to process TLV header, inBufferSize = %d",
2112               inBufferSize);
2113         return readLen;
2114     }
2115 
2116     pOutTlv->type = *pInTlv++;
2117     pOutTlv->type |= *pInTlv++ << 8;
2118     readLen += 2;
2119 
2120     ALOGV("READ TLV type %u, readLen %u", pOutTlv->type, readLen);
2121 
2122     pOutTlv->length = *pInTlv++;
2123     pOutTlv->length |= *pInTlv++ << 8;
2124     readLen += 2;
2125 
2126     if(pOutTlv->length > (u16)(inBufferSize - NAN_TLV_HEADER_SIZE)) {
2127         ALOGE("Insufficient length to process TLV header, inBufferSize = %d",
2128               inBufferSize);
2129         return readLen;
2130     }
2131 
2132     ALOGV("READ TLV length %u, readLen %u", pOutTlv->length, readLen);
2133 
2134     if (pOutTlv->length) {
2135         pOutTlv->value = pInTlv;
2136         readLen += pOutTlv->length;
2137     } else {
2138         pOutTlv->value = NULL;
2139     }
2140 
2141     ALOGV("READ TLV  readLen %u", readLen);
2142     return readLen;
2143 }
2144 
addTlv(u16 type,u16 length,const u8 * value,u8 * pOutTlv)2145 u8* addTlv(u16 type, u16 length, const u8* value, u8* pOutTlv)
2146 {
2147    NanTlv nanTlv;
2148    u16 len;
2149 
2150    nanTlv.type = type;
2151    nanTlv.length = length;
2152    nanTlv.value = (u8*)value;
2153 
2154    len = NANTLV_WriteTlv(&nanTlv, pOutTlv);
2155    return (pOutTlv + len);
2156 }
2157