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