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