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