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