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 "nancommand.h"
25 #include "vendor_definitions.h"
26 #ifdef __GNUC__
27 #define PRINTF_FORMAT(a,b) __attribute__ ((format (printf, (a), (b))))
28 #define STRUCT_PACKED __attribute__ ((packed))
29 #else
30 #define PRINTF_FORMAT(a,b)
31 #define STRUCT_PACKED
32 #endif
33
34 //Singleton Static Instance
35 NanCommand* NanCommand::mNanCommandInstance = NULL;
36
37 //Implementation of the functions exposed in nan.h
nan_register_handler(wifi_interface_handle iface,NanCallbackHandler handlers)38 wifi_error nan_register_handler(wifi_interface_handle iface,
39 NanCallbackHandler handlers)
40 {
41 // Obtain the singleton instance
42 int ret = 0;
43 NanCommand *nanCommand = NULL;
44 wifi_handle wifiHandle = getWifiHandle(iface);
45
46 nanCommand = NanCommand::instance(wifiHandle);
47 if (nanCommand == NULL) {
48 ALOGE("%s: Error NanCommand NULL", __func__);
49 return WIFI_ERROR_UNKNOWN;
50 }
51
52 ret = nanCommand->setCallbackHandler(handlers);
53 return (wifi_error)ret;
54
55 return (wifi_error)ret;
56 }
57
nan_get_version(wifi_handle handle,NanVersion * version)58 wifi_error nan_get_version(wifi_handle handle,
59 NanVersion* version)
60 {
61 *version = (NAN_MAJOR_VERSION <<16 | NAN_MINOR_VERSION << 8 | NAN_MICRO_VERSION);
62 return WIFI_SUCCESS;
63 }
64
65 /* Function to send enable request to the wifi driver.*/
nan_enable_request(transaction_id id,wifi_interface_handle iface,NanEnableRequest * msg)66 wifi_error nan_enable_request(transaction_id id,
67 wifi_interface_handle iface,
68 NanEnableRequest* msg)
69 {
70 int ret = 0;
71 NanCommand *nanCommand = NULL;
72 interface_info *ifaceInfo = getIfaceInfo(iface);
73 wifi_handle wifiHandle = getWifiHandle(iface);
74
75 nanCommand = new NanCommand(wifiHandle,
76 0,
77 OUI_QCA,
78 QCA_NL80211_VENDOR_SUBCMD_NAN);
79 if (nanCommand == NULL) {
80 ALOGE("%s: Error NanCommand NULL", __func__);
81 return WIFI_ERROR_UNKNOWN;
82 }
83
84 ret = nanCommand->create();
85 if (ret < 0)
86 goto cleanup;
87
88 /* Set the interface Id of the message. */
89 ret = nanCommand->set_iface_id(ifaceInfo->name);
90 if (ret < 0)
91 goto cleanup;
92
93 ret = nanCommand->putNanEnable(id, msg);
94 if (ret != 0) {
95 ALOGE("%s: putNanEnable Error:%d",__func__, ret);
96 goto cleanup;
97 }
98 ret = nanCommand->requestEvent();
99 if (ret != 0) {
100 ALOGE("%s: requestEvent Error:%d",__func__, ret);
101 }
102 cleanup:
103 delete nanCommand;
104 return (wifi_error)ret;
105 }
106
107 /* Function to send disable request to the wifi driver.*/
nan_disable_request(transaction_id id,wifi_interface_handle iface)108 wifi_error nan_disable_request(transaction_id id,
109 wifi_interface_handle iface)
110 {
111 int ret = 0;
112 NanCommand *nanCommand = NULL;
113 interface_info *ifaceInfo = getIfaceInfo(iface);
114 wifi_handle wifiHandle = getWifiHandle(iface);
115
116 nanCommand = new NanCommand(wifiHandle,
117 0,
118 OUI_QCA,
119 QCA_NL80211_VENDOR_SUBCMD_NAN);
120 if (nanCommand == NULL) {
121 ALOGE("%s: Error NanCommand NULL", __func__);
122 return WIFI_ERROR_UNKNOWN;
123 }
124
125 ret = nanCommand->create();
126 if (ret < 0)
127 goto cleanup;
128
129 /* Set the interface Id of the message. */
130 ret = nanCommand->set_iface_id(ifaceInfo->name);
131 if (ret < 0)
132 goto cleanup;
133
134 ret = nanCommand->putNanDisable(id);
135 if (ret != 0) {
136 ALOGE("%s: putNanDisable Error:%d",__func__, ret);
137 goto cleanup;
138 }
139 ret = nanCommand->requestEvent();
140 if (ret != 0) {
141 ALOGE("%s: requestEvent Error:%d",__func__, ret);
142 }
143 cleanup:
144 delete nanCommand;
145 return (wifi_error)ret;
146 }
147
148 /* Function to send publish request to the wifi driver.*/
nan_publish_request(transaction_id id,wifi_interface_handle iface,NanPublishRequest * msg)149 wifi_error nan_publish_request(transaction_id id,
150 wifi_interface_handle iface,
151 NanPublishRequest* msg)
152 {
153 int ret = 0;
154 NanCommand *nanCommand = NULL;
155 interface_info *ifaceInfo = getIfaceInfo(iface);
156 wifi_handle wifiHandle = getWifiHandle(iface);
157
158 nanCommand = new NanCommand(wifiHandle,
159 0,
160 OUI_QCA,
161 QCA_NL80211_VENDOR_SUBCMD_NAN);
162 if (nanCommand == NULL) {
163 ALOGE("%s: Error NanCommand NULL", __func__);
164 return WIFI_ERROR_UNKNOWN;
165 }
166
167 ret = nanCommand->create();
168 if (ret < 0)
169 goto cleanup;
170
171 /* Set the interface Id of the message. */
172 ret = nanCommand->set_iface_id(ifaceInfo->name);
173 if (ret < 0)
174 goto cleanup;
175
176 ret = nanCommand->putNanPublish(id, msg);
177 if (ret != 0) {
178 ALOGE("%s: putNanPublish Error:%d",__func__, ret);
179 goto cleanup;
180 }
181 ret = nanCommand->requestEvent();
182 if (ret != 0) {
183 ALOGE("%s: requestEvent Error:%d",__func__, ret);
184 }
185 cleanup:
186 delete nanCommand;
187 return (wifi_error)ret;
188 }
189
190 /* Function to send publish cancel to the wifi driver.*/
nan_publish_cancel_request(transaction_id id,wifi_interface_handle iface,NanPublishCancelRequest * msg)191 wifi_error nan_publish_cancel_request(transaction_id id,
192 wifi_interface_handle iface,
193 NanPublishCancelRequest* msg)
194 {
195 int ret = 0;
196 NanCommand *nanCommand = NULL;
197 interface_info *ifaceInfo = getIfaceInfo(iface);
198 wifi_handle wifiHandle = getWifiHandle(iface);
199
200 nanCommand = new NanCommand(wifiHandle,
201 0,
202 OUI_QCA,
203 QCA_NL80211_VENDOR_SUBCMD_NAN);
204 if (nanCommand == NULL) {
205 ALOGE("%s: Error NanCommand NULL", __func__);
206 return WIFI_ERROR_UNKNOWN;
207 }
208
209 ret = nanCommand->create();
210 if (ret < 0)
211 goto cleanup;
212
213 /* Set the interface Id of the message. */
214 ret = nanCommand->set_iface_id(ifaceInfo->name);
215 if (ret < 0)
216 goto cleanup;
217
218 ret = nanCommand->putNanPublishCancel(id, msg);
219 if (ret != 0) {
220 ALOGE("%s: putNanPublishCancel Error:%d",__func__, ret);
221 goto cleanup;
222 }
223 ret = nanCommand->requestEvent();
224 if (ret != 0) {
225 ALOGE("%s: requestEvent Error:%d",__func__, ret);
226 }
227 cleanup:
228 delete nanCommand;
229 return (wifi_error)ret;
230 }
231
232 /* Function to send Subscribe request to the wifi driver.*/
nan_subscribe_request(transaction_id id,wifi_interface_handle iface,NanSubscribeRequest * msg)233 wifi_error nan_subscribe_request(transaction_id id,
234 wifi_interface_handle iface,
235 NanSubscribeRequest* msg)
236 {
237 int ret = 0;
238 NanCommand *nanCommand = NULL;
239 interface_info *ifaceInfo = getIfaceInfo(iface);
240 wifi_handle wifiHandle = getWifiHandle(iface);
241
242 nanCommand = new NanCommand(wifiHandle,
243 0,
244 OUI_QCA,
245 QCA_NL80211_VENDOR_SUBCMD_NAN);
246 if (nanCommand == NULL) {
247 ALOGE("%s: Error NanCommand NULL", __func__);
248 return WIFI_ERROR_UNKNOWN;
249 }
250
251 ret = nanCommand->create();
252 if (ret < 0)
253 goto cleanup;
254
255 /* Set the interface Id of the message. */
256
257 ret = nanCommand->set_iface_id(ifaceInfo->name);
258 if (ret < 0)
259 goto cleanup;
260
261 ret = nanCommand->putNanSubscribe(id, msg);
262 if (ret != 0) {
263 ALOGE("%s: putNanSubscribe Error:%d",__func__, ret);
264 goto cleanup;
265 }
266 ret = nanCommand->requestEvent();
267 if (ret != 0) {
268 ALOGE("%s: requestEvent Error:%d",__func__, ret);
269 }
270 cleanup:
271 delete nanCommand;
272 return (wifi_error)ret;
273 }
274
275 /* Function to cancel subscribe to the wifi driver.*/
nan_subscribe_cancel_request(transaction_id id,wifi_interface_handle iface,NanSubscribeCancelRequest * msg)276 wifi_error nan_subscribe_cancel_request(transaction_id id,
277 wifi_interface_handle iface,
278 NanSubscribeCancelRequest* msg)
279 {
280 int ret = 0;
281 NanCommand *nanCommand = NULL;
282 interface_info *ifaceInfo = getIfaceInfo(iface);
283 wifi_handle wifiHandle = getWifiHandle(iface);
284
285 nanCommand = new NanCommand(wifiHandle,
286 0,
287 OUI_QCA,
288 QCA_NL80211_VENDOR_SUBCMD_NAN);
289 if (nanCommand == NULL) {
290 ALOGE("%s: Error NanCommand NULL", __func__);
291 return WIFI_ERROR_UNKNOWN;
292 }
293
294 ret = nanCommand->create();
295 if (ret < 0)
296 goto cleanup;
297
298 /* Set the interface Id of the message. */
299 ret = nanCommand->set_iface_id(ifaceInfo->name);
300 if (ret < 0)
301 goto cleanup;
302
303 ret = nanCommand->putNanSubscribeCancel(id, msg);
304 if (ret != 0) {
305 ALOGE("%s: putNanSubscribeCancel Error:%d",__func__, ret);
306 goto cleanup;
307 }
308 ret = nanCommand->requestEvent();
309 if (ret != 0) {
310 ALOGE("%s: requestEvent Error:%d",__func__, ret);
311 }
312 cleanup:
313 delete nanCommand;
314 return (wifi_error)ret;
315 }
316
317 /* Function to send NAN follow up request to the wifi driver.*/
nan_transmit_followup_request(transaction_id id,wifi_interface_handle iface,NanTransmitFollowupRequest * msg)318 wifi_error nan_transmit_followup_request(transaction_id id,
319 wifi_interface_handle iface,
320 NanTransmitFollowupRequest* msg)
321 {
322 int ret = 0;
323 NanCommand *nanCommand = NULL;
324 interface_info *ifaceInfo = getIfaceInfo(iface);
325 wifi_handle wifiHandle = getWifiHandle(iface);
326
327 nanCommand = new NanCommand(wifiHandle,
328 0,
329 OUI_QCA,
330 QCA_NL80211_VENDOR_SUBCMD_NAN);
331 if (nanCommand == NULL) {
332 ALOGE("%s: Error NanCommand NULL", __func__);
333 return WIFI_ERROR_UNKNOWN;
334 }
335
336 ret = nanCommand->create();
337 if (ret < 0)
338 goto cleanup;
339
340 /* Set the interface Id of the message. */
341 ret = nanCommand->set_iface_id(ifaceInfo->name);
342 if (ret < 0)
343 goto cleanup;
344
345 ret = nanCommand->putNanTransmitFollowup(id, msg);
346 if (ret != 0) {
347 ALOGE("%s: putNanTransmitFollowup Error:%d",__func__, ret);
348 goto cleanup;
349 }
350 ret = nanCommand->requestEvent();
351 if (ret != 0) {
352 ALOGE("%s: requestEvent Error:%d",__func__, ret);
353 }
354 cleanup:
355 delete nanCommand;
356 return (wifi_error)ret;
357 }
358
359 /* Function to send NAN statistics request to the wifi driver.*/
nan_stats_request(transaction_id id,wifi_interface_handle iface,NanStatsRequest * msg)360 wifi_error nan_stats_request(transaction_id id,
361 wifi_interface_handle iface,
362 NanStatsRequest* msg)
363 {
364 int ret = 0;
365 NanCommand *nanCommand = NULL;
366 interface_info *ifaceInfo = getIfaceInfo(iface);
367 wifi_handle wifiHandle = getWifiHandle(iface);
368
369 nanCommand = new NanCommand(wifiHandle,
370 0,
371 OUI_QCA,
372 QCA_NL80211_VENDOR_SUBCMD_NAN);
373 if (nanCommand == NULL) {
374 ALOGE("%s: Error NanCommand NULL", __func__);
375 return WIFI_ERROR_UNKNOWN;
376 }
377
378 ret = nanCommand->create();
379 if (ret < 0)
380 goto cleanup;
381
382 /* Set the interface Id of the message. */
383 ret = nanCommand->set_iface_id(ifaceInfo->name);
384 if (ret < 0)
385 goto cleanup;
386
387 ret = nanCommand->putNanStats(id, msg);
388 if (ret != 0) {
389 ALOGE("%s: putNanStats Error:%d",__func__, ret);
390 goto cleanup;
391 }
392 ret = nanCommand->requestEvent();
393 if (ret != 0) {
394 ALOGE("%s: requestEvent Error:%d",__func__, ret);
395 }
396 cleanup:
397 delete nanCommand;
398 return (wifi_error)ret;
399 }
400
401 /* Function to send NAN configuration request to the wifi driver.*/
nan_config_request(transaction_id id,wifi_interface_handle iface,NanConfigRequest * msg)402 wifi_error nan_config_request(transaction_id id,
403 wifi_interface_handle iface,
404 NanConfigRequest* msg)
405 {
406 int ret = 0;
407 NanCommand *nanCommand = NULL;
408 interface_info *ifaceInfo = getIfaceInfo(iface);
409 wifi_handle wifiHandle = getWifiHandle(iface);
410
411 nanCommand = new NanCommand(wifiHandle,
412 0,
413 OUI_QCA,
414 QCA_NL80211_VENDOR_SUBCMD_NAN);
415 if (nanCommand == NULL) {
416 ALOGE("%s: Error NanCommand NULL", __func__);
417 return WIFI_ERROR_UNKNOWN;
418 }
419
420 ret = nanCommand->create();
421 if (ret < 0)
422 goto cleanup;
423
424 /* Set the interface Id of the message. */
425 ret = nanCommand->set_iface_id(ifaceInfo->name);
426 if (ret < 0)
427 goto cleanup;
428
429 ret = nanCommand->putNanConfig(id, msg);
430 if (ret != 0) {
431 ALOGE("%s: putNanConfig Error:%d",__func__, ret);
432 goto cleanup;
433 }
434 ret = nanCommand->requestEvent();
435 if (ret != 0) {
436 ALOGE("%s: requestEvent Error:%d",__func__, ret);
437 }
438 cleanup:
439 delete nanCommand;
440 return (wifi_error)ret;
441 }
442
443 /* Function to send NAN request to the wifi driver.*/
nan_tca_request(transaction_id id,wifi_interface_handle iface,NanTCARequest * msg)444 wifi_error nan_tca_request(transaction_id id,
445 wifi_interface_handle iface,
446 NanTCARequest* msg)
447 {
448 int ret = 0;
449 NanCommand *nanCommand = NULL;
450 interface_info *ifaceInfo = getIfaceInfo(iface);
451 wifi_handle wifiHandle = getWifiHandle(iface);
452
453 nanCommand = new NanCommand(wifiHandle,
454 0,
455 OUI_QCA,
456 QCA_NL80211_VENDOR_SUBCMD_NAN);
457 if (nanCommand == NULL) {
458 ALOGE("%s: Error NanCommand NULL", __func__);
459 return WIFI_ERROR_UNKNOWN;
460 }
461
462 ret = nanCommand->create();
463 if (ret < 0)
464 goto cleanup;
465
466 /* Set the interface Id of the message. */
467 ret = nanCommand->set_iface_id(ifaceInfo->name);
468 if (ret < 0)
469 goto cleanup;
470
471 ret = nanCommand->putNanTCA(id, msg);
472 if (ret != 0) {
473 ALOGE("%s: putNanTCA Error:%d",__func__, ret);
474 goto cleanup;
475 }
476 ret = nanCommand->requestEvent();
477 if (ret != 0) {
478 ALOGE("%s: requestEvent Error:%d",__func__, ret);
479 }
480 cleanup:
481 delete nanCommand;
482 return (wifi_error)ret;
483 }
484
485 /* Function to send NAN Beacon sdf payload to the wifi driver.
486 This instructs the Discovery Engine to begin publishing the
487 received payload in any Beacon or Service Discovery Frame
488 transmitted*/
nan_beacon_sdf_payload_request(transaction_id id,wifi_interface_handle iface,NanBeaconSdfPayloadRequest * msg)489 wifi_error nan_beacon_sdf_payload_request(transaction_id id,
490 wifi_interface_handle iface,
491 NanBeaconSdfPayloadRequest* msg)
492 {
493 int ret = WIFI_ERROR_NOT_SUPPORTED;
494 NanCommand *nanCommand = NULL;
495 interface_info *ifaceInfo = getIfaceInfo(iface);
496 wifi_handle wifiHandle = getWifiHandle(iface);
497
498 nanCommand = new NanCommand(wifiHandle,
499 0,
500 OUI_QCA,
501 QCA_NL80211_VENDOR_SUBCMD_NAN);
502 if (nanCommand == NULL) {
503 ALOGE("%s: Error NanCommand NULL", __func__);
504 return WIFI_ERROR_UNKNOWN;
505 }
506
507 ret = nanCommand->create();
508 if (ret < 0)
509 goto cleanup;
510
511 /* Set the interface Id of the message. */
512 ret = nanCommand->set_iface_id(ifaceInfo->name);
513 if (ret < 0)
514 goto cleanup;
515
516 ret = nanCommand->putNanBeaconSdfPayload(id, msg);
517 if (ret != 0) {
518 ALOGE("%s: putNanBeaconSdfPayload Error:%d",__func__, ret);
519 goto cleanup;
520 }
521 ret = nanCommand->requestEvent();
522 if (ret != 0) {
523 ALOGE("%s: requestEvent Error:%d",__func__, ret);
524 }
525
526 cleanup:
527 delete nanCommand;
528 return (wifi_error)ret;
529 }
530
nan_get_sta_parameter(transaction_id id,wifi_interface_handle iface,NanStaParameter * msg)531 wifi_error nan_get_sta_parameter(transaction_id id,
532 wifi_interface_handle iface,
533 NanStaParameter* msg)
534 {
535 int ret = WIFI_ERROR_NOT_SUPPORTED;
536 NanCommand *nanCommand = NULL;
537 wifi_handle wifiHandle = getWifiHandle(iface);
538
539 nanCommand = NanCommand::instance(wifiHandle);
540 if (nanCommand == NULL) {
541 ALOGE("%s: Error NanCommand NULL", __func__);
542 return WIFI_ERROR_UNKNOWN;
543 }
544
545 ret = nanCommand->getNanStaParameter(iface, msg);
546 if (ret != 0) {
547 ALOGE("%s: getNanStaParameter Error:%d",__func__, ret);
548 goto cleanup;
549 }
550
551 cleanup:
552 return (wifi_error)ret;
553 }
554
555 /* Function to get NAN capabilities */
nan_get_capabilities(transaction_id id,wifi_interface_handle iface)556 wifi_error nan_get_capabilities(transaction_id id,
557 wifi_interface_handle iface)
558 {
559 int ret = 0;
560 NanCommand *nanCommand = NULL;
561 interface_info *ifaceInfo = getIfaceInfo(iface);
562 wifi_handle wifiHandle = getWifiHandle(iface);
563
564 nanCommand = new NanCommand(wifiHandle,
565 0,
566 OUI_QCA,
567 QCA_NL80211_VENDOR_SUBCMD_NAN);
568 if (nanCommand == NULL) {
569 ALOGE("%s: Error NanCommand NULL", __func__);
570 return WIFI_ERROR_UNKNOWN;
571 }
572
573 ret = nanCommand->create();
574 if (ret < 0)
575 goto cleanup;
576
577 /* Set the interface Id of the message. */
578 ret = nanCommand->set_iface_id(ifaceInfo->name);
579 if (ret < 0)
580 goto cleanup;
581
582 ret = nanCommand->putNanCapabilities(id);
583 if (ret != 0) {
584 ALOGE("%s: putNanCapabilities Error:%d",__func__, ret);
585 goto cleanup;
586 }
587 ret = nanCommand->requestEvent();
588 if (ret != 0) {
589 ALOGE("%s: requestEvent Error:%d",__func__, ret);
590 }
591 cleanup:
592 delete nanCommand;
593 return (wifi_error)ret;
594 }
595
596 // Implementation related to nan class common functions
597 // Constructor
598 //Making the constructor private since this class is a singleton
NanCommand(wifi_handle handle,int id,u32 vendor_id,u32 subcmd)599 NanCommand::NanCommand(wifi_handle handle, int id, u32 vendor_id, u32 subcmd)
600 : WifiVendorCommand(handle, id, vendor_id, subcmd)
601 {
602 memset(&mHandler, 0,sizeof(mHandler));
603 mNanVendorEvent = NULL;
604 mNanDataLen = 0;
605 mStaParam = NULL;
606 }
607
instance(wifi_handle handle)608 NanCommand* NanCommand::instance(wifi_handle handle)
609 {
610 if (handle == NULL) {
611 ALOGE("Handle is invalid");
612 return NULL;
613 }
614 if (mNanCommandInstance == NULL) {
615 mNanCommandInstance = new NanCommand(handle, 0,
616 OUI_QCA,
617 QCA_NL80211_VENDOR_SUBCMD_NAN);
618 ALOGV("NanCommand %p created", mNanCommandInstance);
619 return mNanCommandInstance;
620 }
621 else
622 {
623 if (handle != getWifiHandle(mNanCommandInstance->mInfo)) {
624 /* upper layer must have cleaned up the handle and reinitialized,
625 so we need to update the same */
626 ALOGI("Handle different, update the handle");
627 mNanCommandInstance->mInfo = (hal_info *)handle;
628 }
629 }
630 ALOGV("NanCommand %p created already", mNanCommandInstance);
631 return mNanCommandInstance;
632 }
633
cleanup()634 void NanCommand::cleanup()
635 {
636 //free the VendorData
637 if (mVendorData) {
638 free(mVendorData);
639 }
640 mVendorData = NULL;
641 //cleanup the mMsg
642 mMsg.destroy();
643 }
644
~NanCommand()645 NanCommand::~NanCommand()
646 {
647 ALOGV("NanCommand %p destroyed", this);
648 }
649
handleResponse(WifiEvent & reply)650 int NanCommand::handleResponse(WifiEvent &reply){
651 return NL_SKIP;
652 }
653
setCallbackHandler(NanCallbackHandler nHandler)654 int NanCommand::setCallbackHandler(NanCallbackHandler nHandler)
655 {
656 int res = 0;
657 mHandler = nHandler;
658 res = registerVendorHandler(mVendor_id, mSubcmd);
659 if (res != 0) {
660 //error case should not happen print log
661 ALOGE("%s: Unable to register Vendor Handler Vendor Id=0x%x subcmd=%u",
662 __func__, mVendor_id, mSubcmd);
663 }
664 return res;
665 }
666
667 /* This function implements creation of Vendor command */
create()668 int NanCommand::create() {
669 int ret = mMsg.create(NL80211_CMD_VENDOR, 0, 0);
670 if (ret < 0) {
671 goto out;
672 }
673
674 /* Insert the oui in the msg */
675 ret = mMsg.put_u32(NL80211_ATTR_VENDOR_ID, mVendor_id);
676 if (ret < 0)
677 goto out;
678 /* Insert the subcmd in the msg */
679 ret = mMsg.put_u32(NL80211_ATTR_VENDOR_SUBCMD, mSubcmd);
680 if (ret < 0)
681 goto out;
682 out:
683 if (ret < 0) {
684 mMsg.destroy();
685 }
686 return ret;
687 }
688
689 // This function will be the main handler for incoming event
690 // QCA_NL80211_VENDOR_SUBCMD_NAN
691 //Call the appropriate callback handler after parsing the vendor data.
handleEvent(WifiEvent & event)692 int NanCommand::handleEvent(WifiEvent &event)
693 {
694 WifiVendorCommand::handleEvent(event);
695 ALOGV("%s: Subcmd=%u Vendor data len received:%d",
696 __FUNCTION__, mSubcmd, mDataLen);
697 hexdump(mVendorData, mDataLen);
698
699 if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NAN){
700 // Parse the vendordata and get the NAN attribute
701 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_MAX + 1];
702 nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_MAX,
703 (struct nlattr *)mVendorData,
704 mDataLen, NULL);
705 // Populating the mNanVendorEvent and mNanDataLen to point to NAN data.
706 mNanVendorEvent = (char *)nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NAN]);
707 mNanDataLen = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NAN]);
708
709 if (isNanResponse()) {
710 //handleNanResponse will parse the data and call
711 //the response callback handler with the populated
712 //NanResponseMsg
713 handleNanResponse();
714 }
715 else {
716 //handleNanIndication will parse the data and call
717 //the corresponding Indication callback handler
718 //with the corresponding populated Indication event
719 handleNanIndication();
720 }
721 }
722 else {
723 //error case should not happen print log
724 ALOGE("%s: Wrong NAN subcmd received %d", __func__, mSubcmd);
725 }
726 return NL_SKIP;
727 }
728
729 /*Helper function to Write and Read TLV called in indication as well as request */
NANTLV_WriteTlv(pNanTlv pInTlv,u8 * pOutTlv)730 u16 NANTLV_WriteTlv(pNanTlv pInTlv, u8 *pOutTlv)
731 {
732 u16 writeLen = 0;
733 u16 i;
734
735 if (!pInTlv)
736 {
737 ALOGE("NULL pInTlv");
738 return writeLen;
739 }
740
741 if (!pOutTlv)
742 {
743 ALOGE("NULL pOutTlv");
744 return writeLen;
745 }
746
747 *pOutTlv++ = pInTlv->type & 0xFF;
748 *pOutTlv++ = (pInTlv->type & 0xFF00) >> 8;
749 writeLen += 2;
750
751 ALOGV("WRITE TLV type %u, writeLen %u", pInTlv->type, writeLen);
752
753 *pOutTlv++ = pInTlv->length & 0xFF;
754 *pOutTlv++ = (pInTlv->length & 0xFF00) >> 8;
755 writeLen += 2;
756
757 ALOGV("WRITE TLV length %u, writeLen %u", pInTlv->length, writeLen);
758
759 for (i=0; i < pInTlv->length; ++i)
760 {
761 *pOutTlv++ = pInTlv->value[i];
762 }
763
764 writeLen += pInTlv->length;
765 ALOGV("WRITE TLV value, writeLen %u", writeLen);
766 return writeLen;
767 }
768
NANTLV_ReadTlv(u8 * pInTlv,pNanTlv pOutTlv)769 u16 NANTLV_ReadTlv(u8 *pInTlv, pNanTlv pOutTlv)
770 {
771 u16 readLen = 0;
772
773 if (!pInTlv)
774 {
775 ALOGE("NULL pInTlv");
776 return readLen;
777 }
778
779 if (!pOutTlv)
780 {
781 ALOGE("NULL pOutTlv");
782 return readLen;
783 }
784
785 pOutTlv->type = *pInTlv++;
786 pOutTlv->type |= *pInTlv++ << 8;
787 readLen += 2;
788
789 ALOGV("READ TLV type %u, readLen %u", pOutTlv->type, readLen);
790
791 pOutTlv->length = *pInTlv++;
792 pOutTlv->length |= *pInTlv++ << 8;
793 readLen += 2;
794
795 ALOGV("READ TLV length %u, readLen %u", pOutTlv->length, readLen);
796
797 if (pOutTlv->length)
798 {
799 pOutTlv->value = pInTlv;
800 readLen += pOutTlv->length;
801 }
802 else
803 {
804 pOutTlv->value = NULL;
805 }
806
807 ALOGV("READ TLV readLen %u", readLen);
808 return readLen;
809 }
810
addTlv(u16 type,u16 length,const u8 * value,u8 * pOutTlv)811 u8* addTlv(u16 type, u16 length, const u8* value, u8* pOutTlv)
812 {
813 NanTlv nanTlv;
814 u16 len;
815
816 nanTlv.type = type;
817 nanTlv.length = length;
818 nanTlv.value = (u8*)value;
819
820 len = NANTLV_WriteTlv(&nanTlv, pOutTlv);
821 return (pOutTlv + len);
822 }
823