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