1 /*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Portions copyright (C) 2017 Broadcom Limited
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19 #include <stdint.h>
20 #include <fcntl.h>
21 #include <sys/socket.h>
22 #include <netlink/genl/genl.h>
23 #include <netlink/genl/family.h>
24 #include <netlink/genl/ctrl.h>
25 #include <linux/rtnetlink.h>
26 #include <netpacket/packet.h>
27 #include <linux/filter.h>
28 #include <linux/errqueue.h>
29 #include <ctype.h>
30 #include <linux/pkt_sched.h>
31 #include <netlink/object-api.h>
32 #include <netlink/netlink.h>
33 #include <netlink/socket.h>
34
35 #include "nl80211_copy.h"
36
37 #include "sync.h"
38
39 #define LOG_TAG "WifiHAL"
40
41 #include <utils/Log.h>
42 #include <log/log.h>
43 #include "wifi_hal.h"
44 #include "common.h"
45 #include "cpp_bindings.h"
46 #include "netinet/in.h"
47 #include "arpa/inet.h"
48 #include <openssl/sha.h>
49 #include <openssl/evp.h>
50 #include <sys/ioctl.h>
51
52 /* Changes between incompatible Version of NAN */
53 #define NAN_MAJOR_REL_VERSION 1
54 /* Changes between Source and Binary compatible Version of NAN */
55 #define NAN_MINOR_REL_VERSION 2
56 /* Changes between perfectly compatible Version of NAN */
57 #define NAN_PATCH_REL_VERSION 3
58
59 #define SVC_NAME_TO_HASH 1
60 #define NAN_SVC_HASH_SIZE 6
61 #define C2S(x) case x: return #x;
62 #define NAN_PUB_RECV_FLAG_MAX 15
63 #define NAN_SUB_RECV_FLAG_MAX 7
64 #define NAN_DISC_IND_MAX 7
65 #define NAN_MAX 255
66 #define NAN_MIN 0
67 #define INVALID 0xFF
68 #define NAN_MAX_PERIOD 16
69 #define ISGREATER(i, x) (i > x) ? 1 : 0
70 #define NAN_MAX_RSSI 90
71 #define NAN_SECURITY_SALT_SIZE 14
72 #define NAN_MAC_INVALID_TRANSID 0xFFFF
73
74 #define SVCHASH_ISNULL(svc_hash) ((((u8 *)(svc_hash))[0] | \
75 ((u8 *)(svc_hash))[1] | \
76 ((u8 *)(svc_hash))[2] | \
77 ((u8 *)(svc_hash))[3] | \
78 ((u8 *)(svc_hash))[4] | \
79 ((u8 *)(svc_hash))[5]) == 0)
80 #define ETHER_ISNULLADDR(ea) ((((u8 *)(ea))[0] | \
81 ((u8 *)(ea))[1] | \
82 ((u8 *)(ea))[2] | \
83 ((u8 *)(ea))[3] | \
84 ((u8 *)(ea))[4] | \
85 ((u8 *)(ea))[5]) == 0)
86
87 /* NAN structs versioning b/w DHD and HAL
88 * TODO:add versions for each struct*/
89 #define NAN_HAL_VERSION_1 0x2
90 struct nan_dbg_cntrs {
91 u32 dp_req; /* cmd */
92 u32 dp_resp; /* cmd */
93 u32 dp_req_evt;
94 u32 dp_confirm_evt;
95 u32 transmit_req; /* cmd */
96 u32 transmit_txs; /* event */
97 u32 transmit_recv; /* event */
98 };
99 nan_dbg_cntrs counters;
100
101 u32 current_dhd_hal_ver = 0;
102
103 /* TODO: Known bug in Android which was discovered too late and then left in for backward compatibility.
104 * The issue is that the Service Name selected by the framework is invalid - it contains a space.
105 * Therefore, the underlying implementation partially converts it to lower case and uses the results for PMK generation.
106 * I.e. the PMK is generated based on the following service name: "Wi-Fi Aware Data Path"
107 */
108 /* SVC Hash generated for svc name string "Wi-Fi Aware Data Path" */
109 u8 NAN_OOB_INTEROP_SVC_HASH[NAN_SVC_HASH_SIZE] = {0x05, 0x9e, 0xd4, 0xcf, 0x89, 0x1a};
110 #define NAN_OOB_INTEROP_SVC_NAME "Wi-Fi Aware Data Path"
111
NanStatusToString(NanStatusType status)112 static const char *NanStatusToString(NanStatusType status)
113 {
114 switch (status) {
115 C2S(NAN_STATUS_SUCCESS)
116 C2S(NAN_STATUS_INTERNAL_FAILURE)
117 C2S(NAN_STATUS_PROTOCOL_FAILURE)
118 C2S(NAN_STATUS_INVALID_PUBLISH_SUBSCRIBE_ID)
119 C2S(NAN_STATUS_NO_RESOURCE_AVAILABLE)
120 C2S(NAN_STATUS_INVALID_PARAM)
121 C2S(NAN_STATUS_INVALID_REQUESTOR_INSTANCE_ID)
122 C2S(NAN_STATUS_INVALID_NDP_ID)
123 C2S(NAN_STATUS_NAN_NOT_ALLOWED)
124 C2S(NAN_STATUS_NO_OTA_ACK)
125 C2S(NAN_STATUS_ALREADY_ENABLED)
126 C2S(NAN_STATUS_FOLLOWUP_QUEUE_FULL)
127 C2S(NAN_STATUS_UNSUPPORTED_CONCURRENCY_NAN_DISABLED)
128
129 default:
130 return "NAN_STATUS_INTERNAL_FAILURE";
131 }
132 }
133
134 /* Nan Data Path Security Information */
135 typedef struct {
136 /*
137 Unique Instance Id identifying the Responder's service.
138 This is same as publish_id notified on the subscribe side
139 in a publish/subscribe scenario
140 */
141 u32 requestor_instance_id; /* Value 0 for no publish/subscribe */
142 /*
143 Discovery MAC addr of the publisher/peer
144 */
145 u8 peer_disc_mac_addr[NAN_MAC_ADDR_LEN];
146 /*
147 Unique token Id generated on the initiator/responder
148 side used for a NDP session between two NAN devices
149 */
150 NanDataPathId ndp_instance_id;
151 } NanDataPathSecInfoRequest;
152 /*
153 * Note: NAN_ATTRIBUTE should match with one that on driver side, wl_cfgnan.h and
154 * NanAttrToString as well for enum to string.
155 */
156 typedef enum {
157 NAN_ATTRIBUTE_HEADER = 100,
158 NAN_ATTRIBUTE_HANDLE = 101,
159 NAN_ATTRIBUTE_TRANSAC_ID = 102,
160
161 /* NAN Enable request attributes */
162 NAN_ATTRIBUTE_2G_SUPPORT = 103,
163 NAN_ATTRIBUTE_5G_SUPPORT = 104,
164 NAN_ATTRIBUTE_CLUSTER_LOW = 105,
165 NAN_ATTRIBUTE_CLUSTER_HIGH = 106,
166 NAN_ATTRIBUTE_SID_BEACON = 107,
167 NAN_ATTRIBUTE_SYNC_DISC_2G_BEACON = 108,
168 NAN_ATTRIBUTE_SYNC_DISC_5G_BEACON = 109,
169 NAN_ATTRIBUTE_SDF_2G_SUPPORT = 110,
170 NAN_ATTRIBUTE_SDF_5G_SUPPORT = 111,
171 NAN_ATTRIBUTE_RSSI_CLOSE = 112,
172 NAN_ATTRIBUTE_RSSI_MIDDLE = 113,
173 NAN_ATTRIBUTE_RSSI_PROXIMITY = 114,
174 NAN_ATTRIBUTE_HOP_COUNT_LIMIT = 115,
175 NAN_ATTRIBUTE_RANDOM_FACTOR = 116,
176 NAN_ATTRIBUTE_MASTER_PREF = 117,
177 NAN_ATTRIBUTE_PERIODIC_SCAN_INTERVAL = 118,
178
179 /* Nan Publish/Subscribe request attributes */
180 NAN_ATTRIBUTE_PUBLISH_ID = 119,
181 NAN_ATTRIBUTE_TTL = 120,
182 NAN_ATTRIBUTE_PERIOD = 121,
183 NAN_ATTRIBUTE_REPLIED_EVENT_FLAG = 122,
184 NAN_ATTRIBUTE_PUBLISH_TYPE = 123,
185 NAN_ATTRIBUTE_TX_TYPE = 124,
186 NAN_ATTRIBUTE_PUBLISH_COUNT = 125,
187 NAN_ATTRIBUTE_SERVICE_NAME_LEN = 126,
188 NAN_ATTRIBUTE_SERVICE_NAME = 127,
189 NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO_LEN = 128,
190 NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO = 129,
191 NAN_ATTRIBUTE_RX_MATCH_FILTER_LEN = 130,
192 NAN_ATTRIBUTE_RX_MATCH_FILTER = 131,
193 NAN_ATTRIBUTE_TX_MATCH_FILTER_LEN = 132,
194 NAN_ATTRIBUTE_TX_MATCH_FILTER = 133,
195 NAN_ATTRIBUTE_SUBSCRIBE_ID = 134,
196 NAN_ATTRIBUTE_SUBSCRIBE_TYPE = 135,
197 NAN_ATTRIBUTE_SERVICERESPONSEFILTER = 136,
198 NAN_ATTRIBUTE_SERVICERESPONSEINCLUDE = 137,
199 NAN_ATTRIBUTE_USESERVICERESPONSEFILTER = 138,
200 NAN_ATTRIBUTE_SSIREQUIREDFORMATCHINDICATION = 139,
201 NAN_ATTRIBUTE_SUBSCRIBE_MATCH = 140,
202 NAN_ATTRIBUTE_SUBSCRIBE_COUNT = 141,
203 NAN_ATTRIBUTE_MAC_ADDR = 142,
204 NAN_ATTRIBUTE_MAC_ADDR_LIST = 143,
205 NAN_ATTRIBUTE_MAC_ADDR_LIST_NUM_ENTRIES = 144,
206 NAN_ATTRIBUTE_PUBLISH_MATCH = 145,
207
208 /* Nan Event attributes */
209 NAN_ATTRIBUTE_ENABLE_STATUS = 146,
210 NAN_ATTRIBUTE_JOIN_STATUS = 147,
211 NAN_ATTRIBUTE_ROLE = 148,
212 NAN_ATTRIBUTE_MASTER_RANK = 149,
213 NAN_ATTRIBUTE_ANCHOR_MASTER_RANK = 150,
214 NAN_ATTRIBUTE_CNT_PEND_TXFRM = 151,
215 NAN_ATTRIBUTE_CNT_BCN_TX = 152,
216 NAN_ATTRIBUTE_CNT_BCN_RX = 153,
217 NAN_ATTRIBUTE_CNT_SVC_DISC_TX = 154,
218 NAN_ATTRIBUTE_CNT_SVC_DISC_RX = 155,
219 NAN_ATTRIBUTE_AMBTT = 156,
220 NAN_ATTRIBUTE_CLUSTER_ID = 157,
221 NAN_ATTRIBUTE_INST_ID = 158,
222 NAN_ATTRIBUTE_OUI = 159,
223 NAN_ATTRIBUTE_STATUS = 160,
224 NAN_ATTRIBUTE_DE_EVENT_TYPE = 161,
225 NAN_ATTRIBUTE_MERGE = 162,
226 NAN_ATTRIBUTE_IFACE = 163,
227 NAN_ATTRIBUTE_CHANNEL = 164,
228 NAN_ATTRIBUTE_PEER_ID = 165,
229 NAN_ATTRIBUTE_NDP_ID = 167,
230 NAN_ATTRIBUTE_SECURITY = 168,
231 NAN_ATTRIBUTE_QOS = 169,
232 NAN_ATTRIBUTE_RSP_CODE = 170,
233 NAN_ATTRIBUTE_INST_COUNT = 171,
234 NAN_ATTRIBUTE_PEER_DISC_MAC_ADDR = 172,
235 NAN_ATTRIBUTE_PEER_NDI_MAC_ADDR = 173,
236 NAN_ATTRIBUTE_IF_ADDR = 174,
237 NAN_ATTRIBUTE_WARMUP_TIME = 175,
238 NAN_ATTRIBUTE_RECV_IND_CFG = 176,
239 NAN_ATTRIBUTE_RSSI_CLOSE_5G = 177,
240 NAN_ATTRIBUTE_RSSI_MIDDLE_5G = 178,
241 NAN_ATTRIBUTE_RSSI_PROXIMITY_5G = 179,
242 NAN_ATTRIBUTE_CONNMAP = 180,
243 NAN_ATTRIBUTE_24G_CHANNEL = 181,
244 NAN_ATTRIBUTE_5G_CHANNEL = 182,
245 NAN_ATTRIBUTE_DWELL_TIME = 183,
246 NAN_ATTRIBUTE_SCAN_PERIOD = 184,
247 NAN_ATTRIBUTE_RSSI_WINDOW_SIZE = 185,
248 NAN_ATTRIBUTE_CONF_CLUSTER_VAL = 186,
249 NAN_ATTRIBUTE_AVAIL_BIT_MAP = 187,
250 NAN_ATTRIBUTE_ENTRY_CONTROL = 188,
251 NAN_ATTRIBUTE_CIPHER_SUITE_TYPE = 189,
252 NAN_ATTRIBUTE_KEY_TYPE = 190,
253 NAN_ATTRIBUTE_KEY_LEN = 191,
254 NAN_ATTRIBUTE_SCID = 192,
255 NAN_ATTRIBUTE_SCID_LEN = 193,
256 NAN_ATTRIBUTE_SDE_CONTROL_CONFIG_DP = 194,
257 NAN_ATTRIBUTE_SDE_CONTROL_SECURITY = 195,
258 NAN_ATTRIBUTE_SDE_CONTROL_DP_TYPE = 196,
259 NAN_ATTRIBUTE_SDE_CONTROL_RANGE_SUPPORT = 197,
260 NAN_ATTRIBUTE_NO_CONFIG_AVAIL = 198,
261 NAN_ATTRIBUTE_2G_AWAKE_DW = 199,
262 NAN_ATTRIBUTE_5G_AWAKE_DW = 200,
263 NAN_ATTRIBUTE_RANGING_INTERVAL = 201,
264 NAN_ATTRIBUTE_RANGING_INDICATION = 202,
265 NAN_ATTRIBUTE_RANGING_INGRESS_LIMIT = 203,
266 NAN_ATTRIBUTE_RANGING_EGRESS_LIMIT = 204,
267 NAN_ATTRIBUTE_RANGING_AUTO_ACCEPT = 205,
268 NAN_ATTRIBUTE_RANGING_RESULT = 206,
269 NAN_ATTRIBUTE_DISC_IND_CFG = 207,
270 NAN_ATTRIBUTE_RSSI_THRESHOLD_FLAG = 208,
271 NAN_ATTRIBUTE_KEY_DATA = 209,
272 NAN_ATTRIBUTE_SDEA_SERVICE_SPECIFIC_INFO_LEN = 210,
273 NAN_ATTRIBUTE_SDEA_SERVICE_SPECIFIC_INFO = 211,
274 NAN_ATTRIBUTE_REASON = 212,
275 NAN_ATTRIBUTE_MATCH_OCCURRED_FLAG = 213,
276 NAN_ATTRIBUTE_OUT_OF_RESOURCE_FLAG = 214,
277 NAN_ATTRIBUTE_DWELL_TIME_5G = 215,
278 NAN_ATTRIBUTE_SCAN_PERIOD_5G = 216,
279 NAN_ATTRIBUTE_SVC_RESPONDER_POLICY = 217,
280 NAN_ATTRIBUTE_EVENT_MASK = 218,
281 NAN_ATTRIBUTE_SUB_SID_BEACON = 219,
282 NAN_ATTRIBUTE_RANDOMIZATION_INTERVAL = 220,
283 NAN_ATTRIBUTE_CMD_RESP_DATA = 221,
284 NAN_ATTRIBUTE_CMD_USE_NDPE = 222,
285 NAN_ATTRIBUTE_ENABLE_MERGE = 223,
286 NAN_ATTRIBUTE_DISCOVERY_BEACON_INTERVAL = 224,
287 NAN_ATTRIBUTE_NSS = 225,
288 NAN_ATTRIBUTE_ENABLE_RANGING = 226,
289 NAN_ATTRIBUTE_DW_EARLY_TERM = 227,
290 NAN_ATTRIBUTE_CHANNEL_INFO = 228,
291 NAN_ATTRIBUTE_NUM_CHANNELS = 229
292 } NAN_ATTRIBUTE;
293
294 typedef enum {
295 NAN_REQUEST_ENABLE = 0,
296 NAN_REQUEST_DISABLE = 1,
297 NAN_REQUEST_PUBLISH = 2,
298 NAN_REQUEST_PUBLISH_CANCEL = 3,
299 NAN_REQUEST_TRANSMIT_FOLLOWUP = 4,
300 NAN_REQUEST_SUBSCRIBE = 5,
301 NAN_REQUEST_SUBSCRIBE_CANCEL = 6,
302 NAN_REQUEST_STATS = 7,
303 NAN_REQUEST_CONFIG = 8,
304 NAN_REQUEST_TCA = 9,
305 NAN_REQUEST_EVENT_CHECK = 10,
306 NAN_REQUEST_GET_CAPABILTIES = 11,
307 NAN_DATA_PATH_IFACE_CREATE = 12,
308 NAN_DATA_PATH_IFACE_DELETE = 13,
309 NAN_DATA_PATH_INIT_REQUEST = 14,
310 NAN_DATA_PATH_IND_RESPONSE = 15,
311 NAN_DATA_PATH_END = 16,
312 NAN_DATA_PATH_IFACE_UP = 17,
313 NAN_DATA_PATH_SEC_INFO = 18,
314 NAN_VERSION_INFO = 19,
315 NAN_REQUEST_LAST = 0xFFFF
316 } NanRequestType;
317
318 /*
319 * The enum is based on the BCME Response defs
320 * used in the firmware and defined at
321 * path: src/include/bcmeutils.h
322 */
323 enum nan_response_status {
324 BCME_OK = 0,
325 BCME_ERROR = -1,
326 BCME_BADARG = -2,
327 BCME_BADRATESET = -12,
328 BCME_BADBAND = -13,
329 BCME_BUSY = -16,
330 BCME_BADCHAN = -20,
331 BCME_UNSUPPORTED = -23,
332 BCME_BADLEN = -24,
333 BCME_NOTREADY = -25,
334 BCME_NOMEM = -27,
335 BCME_NOTFOUND = -30,
336 BCME_TXFAIL = -38,
337 BCME_RXFAIL = -39,
338 BCME_SCANREJECT = -43,
339 BCME_USAGE_ERROR = -44,
340 BCME_IOCTL_ERROR = -45
341 };
342
343 enum nan_de_event_type {
344 NAN_EVENT_IFACE = 0,
345 NAN_EVENT_START = 1,
346 NAN_EVENT_JOIN = 2,
347 NAN_EVENT_ROLE_CHANGE = 3,
348 NAN_EVENT_MERGE = 4
349 };
350
351 typedef struct _nan_hal_resp {
352 u16 instance_id;
353 u16 subcmd;
354 int32_t status;
355 int32_t value;
356 /* Identifier for the instance of the NDP */
357 u16 ndp_instance_id;
358 /* Publisher NMI */
359 u8 pub_nmi[NAN_MAC_ADDR_LEN];
360 /* SVC_HASH */
361 u8 svc_hash[NAN_SVC_HASH_SIZE];
362 char nan_reason[NAN_ERROR_STR_LEN]; /* Describe the NAN reason type */
363 char pad[3];
364 NanCapabilities capabilities;
365 } nan_hal_resp_t;
366
367 typedef int (*match_fn)(void *p1, void *data);
368
369 typedef struct _nan_hal_info {
370 void *nan_handle;
371 void *nan_mac_control;
372 void *nan_disc_control;
373 void *nan_dp_control;
374 } nan_hal_info_t;
375
376 u8 mNmi[NAN_MAC_ADDR_LEN];
377 /* Static functions */
378 static int is_de_event(int cmd);
379 static int is_dp_event(int cmd);
380 static int is_cmd_response(int cmd);
381
382 static int get_svc_hash(unsigned char *svc_name, u16 svc_name_len,
383 u8 *svc_hash, u16 svc_hash_len);
384 NanResponseType get_response_type(WIFI_SUB_COMMAND nan_subcmd);
385 static NanStatusType nan_map_response_status(int vendor_status);
386
387 /* Function to separate the common events to NAN1.0 events */
is_de_event(int cmd)388 static int is_de_event(int cmd) {
389 bool is_de_evt = false;
390
391 switch(cmd) {
392 case NAN_EVENT_SUBSCRIBE_UNMATCH:
393 case NAN_EVENT_SUBSCRIBE_TERMINATED:
394 case NAN_EVENT_PUBLISH_TERMINATED:
395 case NAN_EVENT_SUBSCRIBE_MATCH:
396 case NAN_EVENT_FOLLOWUP:
397 case NAN_EVENT_TRANSMIT_FOLLOWUP_IND:
398 case NAN_EVENT_PUBLISH_REPLIED_IND:
399 case NAN_EVENT_MATCH_EXPIRY:
400 is_de_evt = true;
401 break;
402 default:
403 /* Not used */
404 break;
405 }
406 return is_de_evt;
407 }
408
409 /* Function to separate NAN2.0 events */
is_dp_event(int cmd)410 static int is_dp_event(int cmd) {
411 bool is_dp_evt = false;
412
413 switch(cmd) {
414 case NAN_EVENT_DATA_REQUEST:
415 case NAN_EVENT_DATA_CONFIRMATION:
416 case NAN_EVENT_DATA_END:
417 is_dp_evt = true;
418 break;
419 default:
420 /* Not used */
421 break;
422 }
423 return is_dp_evt;
424 }
425
is_cmd_response(int cmd)426 static int is_cmd_response(int cmd) {
427 bool is_cmd_resp = false;
428
429 switch(cmd) {
430 case NAN_ASYNC_RESPONSE_DISABLED:
431 is_cmd_resp = true;
432 break;
433 default:
434 break;
435 }
436 return is_cmd_resp;
437 }
438
nan_map_response_status(int vendor_status)439 static NanStatusType nan_map_response_status (int vendor_status) {
440 NanStatusType hal_status;
441
442 switch(vendor_status) {
443 case BCME_OK:
444 hal_status = NAN_STATUS_SUCCESS;
445 break;
446 case BCME_BUSY:
447 hal_status = NAN_STATUS_NO_RESOURCE_AVAILABLE;
448 break;
449 case BCME_NOTREADY:
450 hal_status = NAN_STATUS_NAN_NOT_ALLOWED;
451 break;
452 case BCME_BADLEN:
453 case BCME_BADBAND:
454 hal_status = NAN_STATUS_INVALID_PARAM;
455 break;
456 case BCME_NOMEM:
457 hal_status = NAN_STATUS_NO_RESOURCE_AVAILABLE;
458 break;
459 case NAN_STATUS_INTERNAL_FAILURE:
460 case NAN_STATUS_PROTOCOL_FAILURE:
461 case NAN_STATUS_INVALID_PUBLISH_SUBSCRIBE_ID:
462 case NAN_STATUS_NO_RESOURCE_AVAILABLE:
463 case NAN_STATUS_INVALID_PARAM:
464 case NAN_STATUS_INVALID_REQUESTOR_INSTANCE_ID:
465 case NAN_STATUS_INVALID_NDP_ID:
466 case NAN_STATUS_NAN_NOT_ALLOWED:
467 case NAN_STATUS_NO_OTA_ACK:
468 case NAN_STATUS_ALREADY_ENABLED:
469 case NAN_STATUS_FOLLOWUP_QUEUE_FULL:
470 case NAN_STATUS_UNSUPPORTED_CONCURRENCY_NAN_DISABLED:
471 hal_status = (NanStatusType)vendor_status;
472 break;
473 default:
474 ALOGE("%s Unknown vendor status, status = %d\n",
475 __func__, vendor_status);
476 /* Generic error */
477 hal_status = NAN_STATUS_INTERNAL_FAILURE;
478 }
479 return hal_status;
480 }
481
482 static void prhex(const char *msg, u8 *buf, u32 nbytes);
483 static const char *NanAttrToString(u16 cmd);
484 static const char *NanCmdToString(int cmd);
485 static const char *NanRspToString(int cmd);
486
487 #define NAN_DBG_ENTER() {ALOGI("Enter: %s\n", __func__);}
488 #define NAN_DBG_EXIT() {ALOGI("Exit: %s\n", __func__);}
489
passphrase_to_pmk(u8 * peer_mac,u32 cipher_type,u8 * svc_hash,NanSecurityKeyInfo * key_info,u8 * pmk_hex)490 static int passphrase_to_pmk(u8 *peer_mac, u32 cipher_type,
491 u8 *svc_hash, NanSecurityKeyInfo *key_info, u8 *pmk_hex) {
492 int result = NAN_STATUS_SUCCESS;
493 u8 salt[NAN_SECURITY_SALT_SIZE];
494
495 NAN_DBG_ENTER();
496 salt[0] = 0; /* salt_version */
497 salt[1] = cipher_type;
498 if (svc_hash && peer_mac) {
499 memcpy(&salt[2], svc_hash, NAN_SVC_HASH_SIZE);
500 memcpy(&salt[2 + NAN_SVC_HASH_SIZE], peer_mac,
501 ETHER_ADDR_LEN);
502 prhex("Salt", salt, NAN_SECURITY_SALT_SIZE);
503 } else {
504 ALOGE("Mandory parameters are not present\n");
505 return WIFI_ERROR_INVALID_ARGS;
506 }
507 if (key_info->body.passphrase_info.passphrase_len < NAN_SECURITY_MIN_PASSPHRASE_LEN ||
508 key_info->body.passphrase_info.passphrase_len > NAN_SECURITY_MAX_PASSPHRASE_LEN) {
509 ALOGE("passphrase must be between %d and %d characters long\n",
510 NAN_SECURITY_MIN_PASSPHRASE_LEN,
511 NAN_SECURITY_MAX_PASSPHRASE_LEN);
512 return WIFI_ERROR_INVALID_ARGS;
513 }
514
515 result = PKCS5_PBKDF2_HMAC((const char *) key_info->body.passphrase_info.passphrase,
516 key_info->body.passphrase_info.passphrase_len, salt, sizeof(salt),
517 4096, ((cipher_type == NAN_CIPHER_SUITE_SHARED_KEY_128_MASK) ?
518 (const EVP_MD *)EVP_sha256():(const EVP_MD *)EVP_sha384()), NAN_PMK_INFO_LEN, pmk_hex);
519 prhex("PMK_HEX", pmk_hex, 32);
520 NAN_DBG_EXIT();
521 return result;
522 }
523
524 typedef void *NanRequest;
525 nan_hal_info_t info;
526
527 #define SVC_LIST(info) ((info).svc_list)
528 #define SVC_LIST_SIZE(info) ((info).svc_list.total_items)
529 #define DP_SVC_LIST(info) ((info).dp_svc_list)
530 #define DP_SVC_LIST_SIZE(info) ((info).dp_svc_list.total_items)
531 #define NAN_HANDLE(info) ((info).nan_handle)
532 #define GET_NAN_HANDLE(info) ((NanHandle *)info.nan_handle)
533 #define NAN_MAC_CONTROL(info) ((info).nan_mac_control)
534
535 ///////////////////////////////////////////////////////////////////////////////
536 class NanHandle
537 {
538 public:
539 NanCallbackHandler mHandlers;
NanHandle(wifi_handle handle,NanCallbackHandler handlers)540 NanHandle(wifi_handle handle, NanCallbackHandler handlers):mHandlers(handlers)
541 {}
542
543 };
544
HandleExpiryEvent(nan_hal_info_t info,nlattr * vendor_data)545 void HandleExpiryEvent(nan_hal_info_t info, nlattr *vendor_data) {
546 ALOGI("Received NAN_EVENT_MATCH_EXPIRY\n");
547 u16 attr_type;
548 NanMatchExpiredInd expired_event;
549 memset(&expired_event, 0, sizeof(NanMatchExpiredInd));
550
551 for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
552 attr_type = it.get_type();
553 if (attr_type == NAN_ATTRIBUTE_SUBSCRIBE_ID) {
554 expired_event.publish_subscribe_id = it.get_u16();
555 ALOGI("pub_sub id = %u\n",
556 expired_event.publish_subscribe_id);
557 } else if (attr_type == NAN_ATTRIBUTE_PUBLISH_ID) {
558 expired_event.requestor_instance_id = it.get_u32();
559 ALOGI("req_inst id = %u\n", expired_event.requestor_instance_id);
560 }
561 }
562
563 if (expired_event.requestor_instance_id && expired_event.publish_subscribe_id) {
564 GET_NAN_HANDLE(info)->mHandlers.EventMatchExpired(&expired_event);
565 } else {
566 ALOGE("Invalid values for notifying the expired event, dropping the event\n");
567 }
568 }
569
570 ///////////////////////////////////////////////////////////////////////////////
571 class NanDiscEnginePrimitive : public WifiCommand
572 {
573 NanRequest mParams;
574 NanRequestType mType;
575 u16 mInstId;
576 u32 mPeerId;
577 u16 mTxId;
578
579 public:
NanDiscEnginePrimitive(wifi_interface_handle iface,int id,NanRequest params,NanRequestType cmdType)580 NanDiscEnginePrimitive(wifi_interface_handle iface, int id,
581 NanRequest params, NanRequestType cmdType)
582 : WifiCommand("NanCommand", iface, id), mParams(params), mType(cmdType)
583 {
584 mInstId = 0;
585 mPeerId = 0;
586 setTransactionId(id);
587 }
588
~NanDiscEnginePrimitive()589 ~NanDiscEnginePrimitive() {
590 ALOGE("NanDiscEnginePrimitive destroyed\n");
591 }
592
setType(NanRequestType type)593 void setType(NanRequestType type) {
594 mType = type;
595 }
596
setInstId(u16 inst_id)597 void setInstId(u16 inst_id) {
598 mInstId = inst_id;
599 }
600
getInstanceId()601 int getInstanceId() {
602 return mInstId;
603 }
604
setTransactionId(u16 tx_id)605 void setTransactionId(u16 tx_id) {
606 mTxId = tx_id;
607 }
608
getTransactionId()609 int getTransactionId() {
610 return mTxId;
611 }
612
setParams(NanRequest params)613 void setParams(NanRequest params) {
614 mParams = params;
615 }
616
createRequest(WifiRequest & request)617 int createRequest(WifiRequest& request)
618 {
619 ALOGI("NAN CMD: %s\n", NanCmdToString(mType));
620 if (mType == NAN_REQUEST_SUBSCRIBE) {
621 return createSubscribeRequest(request,
622 (NanSubscribeRequest *)mParams);
623 } else if (mType == NAN_REQUEST_SUBSCRIBE_CANCEL) {
624 return createSubscribeCancelRequest(request,
625 (NanSubscribeCancelRequest *)mParams);
626 } else if (mType == NAN_REQUEST_PUBLISH) {
627 return createPublishRequest(request,
628 (NanPublishRequest *)mParams);
629 } else if (mType == NAN_REQUEST_PUBLISH_CANCEL) {
630 return createPublishCancelRequest(request,
631 (NanPublishCancelRequest *)mParams);
632 } else if (mType == NAN_REQUEST_TRANSMIT_FOLLOWUP) {
633 return createTransmitFollowupRequest(request,
634 (NanTransmitFollowupRequest *)mParams);
635 } else if (mType == NAN_REQUEST_GET_CAPABILTIES) {
636 return getCapabilitiesRequest(request);
637 } else {
638 ALOGE("%s Unknown Nan request\n", __func__);
639 }
640 return WIFI_SUCCESS;
641 }
642
createPublishRequest(WifiRequest & request,NanPublishRequest * mParams)643 int createPublishRequest(WifiRequest& request, NanPublishRequest *mParams)
644 {
645 NAN_DBG_ENTER();
646 u8 pmk_hex[NAN_PMK_INFO_LEN];
647 int result = request.create(GOOGLE_OUI, NAN_SUBCMD_PUBLISH);
648 if (result < 0) {
649 ALOGE("%s Failed to create request, result = %d\n", __func__, result);
650 return result;
651 }
652
653 /* If handle is 0xFFFF, then update instance_id in response of this request
654 * otherwise, update not needed
655 */
656 mInstId = mParams->publish_id;
657 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
658
659 result = request.put_u32(NAN_ATTRIBUTE_PUBLISH_ID, mInstId);
660 if (result < 0) {
661 ALOGE("%s: Failed to fill pub id, result = %d\n", __func__, result);
662 return result;
663 }
664
665 result = request.put_u16(NAN_ATTRIBUTE_TTL, mParams->ttl);
666 if (result < 0) {
667 ALOGE("%s: Failed to fill ttl, result = %d\n", __func__, result);
668 return result;
669 }
670
671 if (ISGREATER(mParams->period, NAN_MAX_PERIOD)) {
672 ALOGE("%s:Invalid period value.\n", __FUNCTION__);
673 return WIFI_ERROR_NOT_SUPPORTED;
674 }
675 result = request.put_u16(NAN_ATTRIBUTE_PERIOD, mParams->period);
676 if (result < 0) {
677 ALOGE("%s: Failed to fill period, result = %d\n", __func__, result);
678 return result;
679 }
680
681 result = request.put_u8(NAN_ATTRIBUTE_PUBLISH_TYPE, mParams->publish_type);
682 if (result < 0) {
683 ALOGE("%s: Failed to fill pub type, result = %d\n", __func__, result);
684 return result;
685 }
686
687 result = request.put_u8(NAN_ATTRIBUTE_TX_TYPE, mParams->tx_type);
688 if (result < 0) {
689 ALOGE("%s: Failed to fill tx type, result = %d\n", __func__, result);
690 return result;
691 }
692
693 result = request.put_u8(NAN_ATTRIBUTE_PUBLISH_COUNT, mParams->publish_count);
694 if (result < 0) {
695 ALOGE("%s: Failed to fill pub cnt, result = %d\n", __func__, result);
696 return result;
697 }
698
699 if (mParams->service_name_len) {
700 u8 svc_hash[NAN_SVC_HASH_SIZE];
701
702 result = get_svc_hash(mParams->service_name, mParams->service_name_len,
703 svc_hash, NAN_SVC_HASH_SIZE);
704 if (result < 0) {
705 ALOGE("%s: Failed to get hashed svc name\n", __func__);
706 return result;
707 }
708
709 mParams->service_name_len = NAN_SVC_HASH_SIZE;
710 memcpy(mParams->service_name, svc_hash, mParams->service_name_len);
711
712 result = request.put_u16(NAN_ATTRIBUTE_SERVICE_NAME_LEN, mParams->service_name_len);
713 if (result < 0) {
714 ALOGE("%s: Failed to fill svc name len, result = %d\n", __func__, result);
715 return result;
716 }
717
718 result = request.put(NAN_ATTRIBUTE_SERVICE_NAME, (void *)mParams->service_name,
719 mParams->service_name_len);
720 if (result < 0) {
721 ALOGE("%s: Failed to fill svc name, result = %d\n", __func__, result);
722 return result;
723 }
724 }
725
726 if (mParams->service_specific_info_len) {
727 result = request.put_u16(NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO_LEN,
728 mParams->service_specific_info_len);
729 if (result < 0) {
730 ALOGE("%s: Failed to fill svc info len, result = %d\n", __func__, result);
731 return result;
732 }
733
734 result = request.put(NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO,
735 (void *)mParams->service_specific_info, mParams->service_specific_info_len);
736 if (result < 0) {
737 ALOGE("%s: Failed to fill svc info, result = %d\n", __func__, result);
738 return result;
739 }
740 }
741
742 if (mParams->rx_match_filter_len) {
743 result = request.put_u16(NAN_ATTRIBUTE_RX_MATCH_FILTER_LEN,
744 mParams->rx_match_filter_len);
745 if (result < 0) {
746 ALOGE("%s: Failed to fill rx match filter len, result = %d\n",
747 __func__, result);
748 return result;
749 }
750
751 prhex(NULL, mParams->rx_match_filter, mParams->rx_match_filter_len);
752 result = request.put(NAN_ATTRIBUTE_RX_MATCH_FILTER,
753 (void *)mParams->rx_match_filter, mParams->rx_match_filter_len);
754 if (result < 0) {
755 ALOGE("%s: Failed to fill rx match filter, result = %d\n", __func__, result);
756 return result;
757 }
758 }
759
760 if (mParams->tx_match_filter_len) {
761 result = request.put_u16(NAN_ATTRIBUTE_TX_MATCH_FILTER_LEN,
762 mParams->tx_match_filter_len);
763 if (result < 0) {
764 ALOGE("%s: Failed to fill tx match filter, result = %d\n", __func__, result);
765 return result;
766 }
767
768 prhex(NULL, mParams->tx_match_filter, mParams->tx_match_filter_len);
769 result = request.put(NAN_ATTRIBUTE_TX_MATCH_FILTER,
770 (void *)mParams->tx_match_filter, mParams->tx_match_filter_len);
771 if (result < 0) {
772 ALOGE("%s: Failed to fill tx match filter, result = %d\n",
773 __func__, result);
774 return result;
775 }
776 }
777
778 result = request.put_u8(NAN_ATTRIBUTE_PUBLISH_MATCH, mParams->publish_match_indicator);
779 if (result < 0) {
780 ALOGE("%s: Failed to fill NAN_ATTRIBUTE_PUBLISH_MATCH, result = %d\n",
781 __func__, result);
782 return result;
783 }
784
785 if (ISGREATER(mParams->recv_indication_cfg, NAN_PUB_RECV_FLAG_MAX)) {
786 ALOGE("%s:Invalid recv_flag value.\n", __FUNCTION__);
787 return WIFI_ERROR_NOT_SUPPORTED;
788 }
789 result = request.put_u8(NAN_ATTRIBUTE_RECV_IND_CFG,
790 mParams->recv_indication_cfg);
791 if (result < 0) {
792 ALOGE("%s: Failed to fill NAN_ATTRIBUTE_RECV_IND_CFG, result = %d\n",
793 __func__, result);
794 return result;
795 }
796
797 result = request.put_u8(NAN_ATTRIBUTE_CIPHER_SUITE_TYPE,
798 mParams->cipher_type);
799 if (result < 0) {
800 ALOGE("%s: Failed to fill NAN_ATTRIBUTE_CIPHER_SUITE_TYPE, result = %d\n",
801 __func__, result);
802 return result;
803 }
804
805 result = request.put_u8(NAN_ATTRIBUTE_KEY_TYPE,
806 mParams->key_info.key_type);
807 if (result < 0) {
808 ALOGE("%s: Failed to fill NAN_ATTRIBUTE_KEY_TYPE, result = %d\n",
809 __func__, result);
810 return result;
811 }
812
813 if (mParams->key_info.key_type == NAN_SECURITY_KEY_INPUT_PMK) {
814 if (mParams->key_info.body.pmk_info.pmk_len) {
815 result = request.put_u32(NAN_ATTRIBUTE_KEY_LEN,
816 mParams->key_info.body.pmk_info.pmk_len);
817 if (result < 0) {
818 ALOGE("%s: Failed to fill pmk len, result = %d\n", __func__, result);
819 return result;
820 }
821 result = request.put(NAN_ATTRIBUTE_KEY_DATA,
822 (void *)mParams->key_info.body.pmk_info.pmk,
823 mParams->key_info.body.pmk_info.pmk_len);
824 if (result < 0) {
825 ALOGE("%s: Failed to fill pmk, result = %d\n", __func__, result);
826 return result;
827 }
828 }
829 }
830
831 if (mParams->key_info.key_type == NAN_SECURITY_KEY_INPUT_PASSPHRASE) {
832 if (mParams->key_info.body.passphrase_info.passphrase_len < NAN_SECURITY_MIN_PASSPHRASE_LEN ||
833 mParams->key_info.body.passphrase_info.passphrase_len > NAN_SECURITY_MAX_PASSPHRASE_LEN) {
834 ALOGE("passphrase must be between %d and %d characters long\n",
835 NAN_SECURITY_MIN_PASSPHRASE_LEN,
836 NAN_SECURITY_MAX_PASSPHRASE_LEN);
837 return NAN_STATUS_INVALID_PARAM;
838 } else {
839 memset(pmk_hex, 0, NAN_PMK_INFO_LEN);
840 result = passphrase_to_pmk(mNmi, mParams->cipher_type,
841 mParams->service_name, &mParams->key_info, pmk_hex);
842 if (result < 0) {
843 ALOGE("%s: Failed to convert passphrase to key data, result = %d\n", __func__, result);
844 return result;
845 }
846 result = request.put_u32(NAN_ATTRIBUTE_KEY_LEN, NAN_PMK_INFO_LEN);
847 if (result < 0) {
848 ALOGE("%s: Failed to fill passphrase len, result = %d\n", __func__, result);
849 return result;
850 }
851 result = request.put(NAN_ATTRIBUTE_KEY_DATA, pmk_hex, NAN_PMK_INFO_LEN);
852 if (result < 0) {
853 ALOGE("%s: Failed to fill passphrase, result = %d\n", __func__, result);
854 return result;
855 }
856 }
857 }
858
859 if (mParams->scid_len) {
860 result = request.put_u32(NAN_ATTRIBUTE_SCID_LEN,
861 mParams->scid_len);
862 if (result < 0) {
863 ALOGE("%s: Failed to fill scid len, result = %d\n", __func__, result);
864 return result;
865 }
866
867 prhex(NULL, mParams->scid, mParams->scid_len);
868 result = request.put(NAN_ATTRIBUTE_SCID,
869 (void *)mParams->scid, mParams->scid_len);
870 if (result < 0) {
871 ALOGE("%s: Failed to fill scid, result = %d\n", __func__, result);
872 return result;
873 }
874 }
875
876 result = request.put_u8(NAN_ATTRIBUTE_SDE_CONTROL_CONFIG_DP,
877 mParams->sdea_params.config_nan_data_path);
878
879 if (result < 0) {
880 ALOGE("%s: Failed to fill NAN_ATTRIBUTE_SDE_CONTROL_CONFIG_DP, result = %d\n", __func__, result);
881 return result;
882 }
883
884 result = request.put_u8(NAN_ATTRIBUTE_SDE_CONTROL_SECURITY,
885 mParams->sdea_params.security_cfg);
886 if (result < 0) {
887 ALOGE("%s: Failed to fill NAN_ATTRIBUTE_SDE_CONTROL_SECURITY, result = %d\n", __func__, result);
888 return result;
889 }
890
891 result = request.put_u8(NAN_ATTRIBUTE_SDE_CONTROL_DP_TYPE,
892 mParams->sdea_params.ndp_type);
893 if (result < 0) {
894 ALOGE("%s: Failed to fill NAN_ATTRIBUTE_SDE_CONTROL_DP_TYPE, result = %d\n", __func__, result);
895 return result;
896 }
897
898 result = request.put_u8(NAN_ATTRIBUTE_SDE_CONTROL_RANGE_SUPPORT,
899 mParams->sdea_params.ranging_state);
900 if (result < 0) {
901 ALOGE("%s: Failed to fill NAN_ATTRIBUTE_SDE_CONTROL_RANGE_SUPPORT, result = %d\n", __func__, result);
902 return result;
903 }
904
905 result = request.put_u8(NAN_ATTRIBUTE_RSSI_THRESHOLD_FLAG,
906 mParams->rssi_threshold_flag);
907 if (result < 0) {
908 ALOGE("%s: Failed to fill NAN_ATTRIBUTE_RSSI_THRESHOLD_FLAG, result = %d\n",
909 __func__, result);
910 return result;
911 }
912
913 if (mParams->sdea_service_specific_info_len) {
914 result = request.put_u16(NAN_ATTRIBUTE_SDEA_SERVICE_SPECIFIC_INFO_LEN,
915 mParams->sdea_service_specific_info_len);
916 if (result < 0) {
917 ALOGE("%s: Failed to fill sdea svc info len, result = %d\n", __func__, result);
918 return result;
919 }
920
921 prhex(NULL, mParams->sdea_service_specific_info, mParams->sdea_service_specific_info_len);
922 result = request.put(NAN_ATTRIBUTE_SDEA_SERVICE_SPECIFIC_INFO,
923 (void *)mParams->sdea_service_specific_info, mParams->sdea_service_specific_info_len);
924 if (result < 0) {
925 ALOGE("%s: Failed to fill sdea svc info, result = %d\n", __func__, result);
926 return result;
927 }
928 }
929
930 result = request.put_u8(NAN_ATTRIBUTE_SVC_RESPONDER_POLICY,
931 mParams->service_responder_policy);
932 if (result < 0) {
933 ALOGE("%s: Failed to fill NAN_ATTRIBUTE_SVC_RESPONDER_POLICY, result = %d\n",
934 __func__, result);
935 return result;
936 }
937
938 request.attr_end(data);
939
940 ALOGI("Returning successfully\n");
941 NAN_DBG_EXIT();
942 return result;
943 }
944
createPublishCancelRequest(WifiRequest & request,NanPublishCancelRequest * mParams)945 int createPublishCancelRequest(WifiRequest& request, NanPublishCancelRequest *mParams)
946 {
947 int result = request.create(GOOGLE_OUI, NAN_SUBCMD_PUBLISH_CANCEL);
948 if (result < 0) {
949 ALOGE("%s: Failed to create request, result = %d\n", __func__, result);
950 return result;
951 }
952
953 NAN_DBG_ENTER();
954 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
955
956 if (ISGREATER(mInstId, NAN_MAX)) {
957 ALOGE("%s:Invalid publish count value.\n", __FUNCTION__);
958 return WIFI_ERROR_NOT_SUPPORTED;
959 }
960 ALOGI("%s: pub id = %d, inst_id = %d\n", __func__, mParams->publish_id, mInstId);
961
962 result = request.put_u32(NAN_ATTRIBUTE_PUBLISH_ID, mInstId);
963 if (result < 0) {
964 ALOGE("%s: Failed to fill NAN_ATTRIBUTE_PUBLISH_ID, result = %d\n",
965 __func__, result);
966 return result;
967 }
968 request.attr_end(data);
969 NAN_DBG_EXIT();
970 return WIFI_SUCCESS;
971 }
972
createSubscribeRequest(WifiRequest & request,NanSubscribeRequest * mParams)973 int createSubscribeRequest(WifiRequest& request, NanSubscribeRequest *mParams)
974 {
975 int result = request.create(GOOGLE_OUI, NAN_SUBCMD_SUBSCRIBE);
976 if (result < 0) {
977 ALOGE("%s Failed to create request\n", __func__);
978 return result;
979 }
980
981 NAN_DBG_ENTER();
982
983 /* If handle is 0xFFFF, then update instance_id in response of this request
984 * otherwise, update not needed
985 */
986 mInstId = mParams->subscribe_id;
987 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
988
989 result = request.put_u16(NAN_ATTRIBUTE_SUBSCRIBE_ID, mInstId);
990 if (result < 0) {
991 ALOGE("%s: Failed to fill sub id, result = %d\n", __func__, result);
992 return result;
993 }
994
995 result = request.put_u16(NAN_ATTRIBUTE_TTL, mParams->ttl);
996 if (result < 0) {
997 ALOGE("%s: Failed to fill ttl, result = %d\n", __func__, result);
998 return result;
999 }
1000
1001 if (ISGREATER(mParams->period, NAN_MAX_PERIOD)) {
1002 ALOGE("%s:Invalid period value.\n", __FUNCTION__);
1003 return WIFI_ERROR_NOT_SUPPORTED;
1004 }
1005 result = request.put_u16(NAN_ATTRIBUTE_PERIOD, mParams->period);
1006 if (result < 0) {
1007 ALOGE("%s: Failed to fill period, result = %d\n", __func__, result);
1008 return result;
1009 }
1010
1011 result = request.put_u8(NAN_ATTRIBUTE_SUBSCRIBE_TYPE, mParams->subscribe_type);
1012 if (result < 0) {
1013 ALOGE("%s: Failed to fill sub type, result = %d\n", __func__, result);
1014 return result;
1015 }
1016
1017 result = request.put_u8(NAN_ATTRIBUTE_SERVICERESPONSEFILTER,
1018 mParams->serviceResponseFilter);
1019 if (result < 0) {
1020 ALOGE("%s: Failed to fill svc resp filter, result = %d\n", __func__, result);
1021 return result;
1022 }
1023
1024 result = request.put_u8(NAN_ATTRIBUTE_SERVICERESPONSEINCLUDE,
1025 mParams->serviceResponseInclude);
1026 if (result < 0) {
1027 ALOGE("%s: Failed to fill svc resp include, result = %d\n", __func__, result);
1028 return result;
1029 }
1030
1031 result = request.put_u8(NAN_ATTRIBUTE_USESERVICERESPONSEFILTER,
1032 mParams->useServiceResponseFilter);
1033 if (result < 0) {
1034 ALOGE("%s: Failed to fill use svc resp filter, result = %d\n", __func__, result);
1035 return result;
1036 }
1037
1038 result = request.put_u8(NAN_ATTRIBUTE_SSIREQUIREDFORMATCHINDICATION,
1039 mParams->ssiRequiredForMatchIndication);
1040 if (result < 0) {
1041 ALOGE("%s: Failed to fill ssi req match ind, result = %d\n", __func__, result);
1042 return result;
1043 }
1044
1045 result = request.put_u8(NAN_ATTRIBUTE_SUBSCRIBE_MATCH,
1046 mParams->subscribe_match_indicator);
1047 if (result < 0) {
1048 ALOGE("%s: Failed to fill sub match, result = %d\n", __func__, result);
1049 return result;
1050 }
1051
1052 result = request.put_u8(NAN_ATTRIBUTE_SUBSCRIBE_COUNT, mParams->subscribe_count);
1053 if (result < 0) {
1054 ALOGE("%s: Failed to fill sub cnt, result = %d\n", __func__, result);
1055 return result;
1056 }
1057
1058 if (mParams->service_name_len) {
1059 u8 svc_hash[NAN_SVC_HASH_SIZE];
1060
1061 result = get_svc_hash(mParams->service_name, mParams->service_name_len,
1062 svc_hash, NAN_SVC_HASH_SIZE);
1063 if (result < 0) {
1064 ALOGE("%s: Failed to get hashed svc name\n", __func__);
1065 return result;
1066 }
1067
1068 mParams->service_name_len = NAN_SVC_HASH_SIZE;
1069 memcpy(mParams->service_name, svc_hash, mParams->service_name_len);
1070
1071 result = request.put_u16(NAN_ATTRIBUTE_SERVICE_NAME_LEN, mParams->service_name_len);
1072 if (result < 0) {
1073 ALOGE("%s: Failed to fill svc hash len, result = %d\n",
1074 __func__, result);
1075 return result;
1076 }
1077
1078 result = request.put(NAN_ATTRIBUTE_SERVICE_NAME, (void *)mParams->service_name,
1079 mParams->service_name_len);
1080 if (result < 0) {
1081 ALOGE("%s: Failed to fill hashed svc name, result = %d\n", __func__, result);
1082 return result;
1083 }
1084 }
1085
1086 if (mParams->service_specific_info_len) {
1087 result = request.put_u16(NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO_LEN,
1088 mParams->service_specific_info_len);
1089 if (result < 0) {
1090 ALOGE("%s: Failed to fill svc info len, result = %d\n", __func__, result);
1091 return result;
1092 }
1093
1094 result = request.put(NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO,
1095 (void *)mParams->service_specific_info, mParams->service_specific_info_len);
1096 if (result < 0) {
1097 ALOGE("%s: Failed to fill svc info, result = %d\n", __func__, result);
1098 return result;
1099 }
1100 }
1101
1102 if (mParams->rx_match_filter_len) {
1103 result = request.put_u16(NAN_ATTRIBUTE_RX_MATCH_FILTER_LEN,
1104 mParams->rx_match_filter_len);
1105 if (result < 0) {
1106 ALOGE("%s: Failed to fill rx match filter len, result = %d\n", __func__, result);
1107 return result;
1108 }
1109
1110 prhex(NULL, mParams->rx_match_filter, mParams->rx_match_filter_len);
1111 result = request.put(NAN_ATTRIBUTE_RX_MATCH_FILTER,
1112 (void *)mParams->rx_match_filter, mParams->rx_match_filter_len);
1113 if (result < 0) {
1114 ALOGE("%s: Failed to fill rx match filter, result = %d\n", __func__, result);
1115 return result;
1116 }
1117 }
1118
1119 if (mParams->tx_match_filter_len) {
1120 result = request.put_u16(NAN_ATTRIBUTE_TX_MATCH_FILTER_LEN,
1121 mParams->tx_match_filter_len);
1122 if (result < 0) {
1123 ALOGE("%s: Failed to fill tx match filter len, result = %d\n", __func__, result);
1124 return result;
1125 }
1126
1127 prhex(NULL, mParams->tx_match_filter, mParams->tx_match_filter_len);
1128 result = request.put(NAN_ATTRIBUTE_TX_MATCH_FILTER,
1129 (void *)mParams->tx_match_filter, mParams->tx_match_filter_len);
1130 if (result < 0) {
1131 ALOGE("%s: Failed to fill tx match filter, result = %d\n", __func__, result);
1132 return result;
1133 }
1134 }
1135
1136 if (mParams->num_intf_addr_present > NAN_MAX_SUBSCRIBE_MAX_ADDRESS) {
1137 ALOGE("%s: Number of mac addrs: %d have crossed the threshold, fail to subscribe\n",
1138 __func__, mParams->num_intf_addr_present);
1139 return WIFI_ERROR_NOT_SUPPORTED;
1140 } else if (mParams->num_intf_addr_present) {
1141 result = request.put_u16(NAN_ATTRIBUTE_MAC_ADDR_LIST_NUM_ENTRIES,
1142 mParams->num_intf_addr_present);
1143 if (result < 0) {
1144 ALOGE("%s: Failed to fill mac addr list no, result = %d\n",
1145 __func__, result);
1146 return result;
1147 }
1148
1149 prhex(NULL, (u8 *)mParams->intf_addr,
1150 (mParams->num_intf_addr_present * NAN_MAC_ADDR_LEN));
1151 result = request.put(NAN_ATTRIBUTE_MAC_ADDR_LIST, (void *)mParams->intf_addr,
1152 (mParams->num_intf_addr_present * NAN_MAC_ADDR_LEN));
1153 if (result < 0) {
1154 ALOGE("%s: Failed to fill mac addr list, result = %d\n", __func__, result);
1155 return result;
1156 }
1157 }
1158
1159 if (ISGREATER(mParams->recv_indication_cfg, NAN_SUB_RECV_FLAG_MAX)) {
1160 ALOGE("%s:Invalid recv_flag value.\n", __FUNCTION__);
1161 return WIFI_ERROR_NOT_SUPPORTED;
1162 }
1163 result = request.put_u8(NAN_ATTRIBUTE_RECV_IND_CFG,
1164 mParams->recv_indication_cfg);
1165 if (result < 0) {
1166 ALOGE("%s: Failed to fill recv_indication_cfg, result = %d\n",
1167 __func__, result);
1168 return result;
1169 }
1170
1171 if (mParams->scid_len) {
1172 result = request.put_u32(NAN_ATTRIBUTE_SCID_LEN,
1173 mParams->scid_len);
1174 if (result < 0) {
1175 ALOGE("%s: Failed to fill scid len, result = %d\n", __func__, result);
1176 return result;
1177 }
1178
1179 prhex(NULL, mParams->scid, mParams->scid_len);
1180 result = request.put(NAN_ATTRIBUTE_SCID,
1181 (void *)mParams->scid, mParams->scid_len);
1182 if (result < 0) {
1183 ALOGE("%s: Failed to fill scid, result = %d\n", __func__, result);
1184 return result;
1185 }
1186 }
1187
1188 result = request.put_u8(NAN_ATTRIBUTE_SDE_CONTROL_CONFIG_DP,
1189 mParams->sdea_params.config_nan_data_path);
1190 if (result < 0) {
1191 ALOGE("%s: Failed to fill config_nan_data_path, result = %d\n", __func__, result);
1192 return result;
1193 }
1194
1195 result = request.put_u8(NAN_ATTRIBUTE_SDE_CONTROL_SECURITY,
1196 mParams->sdea_params.security_cfg);
1197 if (result < 0) {
1198 ALOGE("%s: Failed to fill security_cfg, result = %d\n", __func__, result);
1199 return result;
1200 }
1201
1202 result = request.put_u8(NAN_ATTRIBUTE_SDE_CONTROL_DP_TYPE,
1203 mParams->sdea_params.ndp_type);
1204 if (result < 0) {
1205 ALOGE("%s: Failed to fill ndp_type, result = %d\n", __func__, result);
1206 return result;
1207 }
1208
1209 result = request.put_u8(NAN_ATTRIBUTE_SDE_CONTROL_RANGE_SUPPORT,
1210 mParams->sdea_params.ranging_state);
1211 if (result < 0) {
1212 ALOGE("%s: Failed to fill ranging state, result = %d\n", __func__, result);
1213 return result;
1214 }
1215
1216 if (mParams->sdea_params.ranging_state == NAN_RANGING_ENABLE) {
1217 result = request.put_u32(NAN_ATTRIBUTE_RANGING_INTERVAL,
1218 mParams->ranging_cfg.ranging_interval_msec);
1219 if (result < 0) {
1220 ALOGE("%s: Failed to fill ranging_interval_msec, result = %d\n", __func__, result);
1221 return result;
1222 }
1223
1224 result = request.put_u32(NAN_ATTRIBUTE_RANGING_EGRESS_LIMIT,
1225 mParams->ranging_cfg.distance_egress_mm);
1226 if (result < 0) {
1227 ALOGE("%s: Failed to fill distance_egress_mm, result = %d\n", __func__, result);
1228 return result;
1229 }
1230
1231 result = request.put_u32(NAN_ATTRIBUTE_RANGING_INDICATION,
1232 mParams->ranging_cfg.config_ranging_indications);
1233 if (result < 0) {
1234 ALOGE("%s: Failed to fill config_ranging_indications, result = %d\n", __func__, result);
1235 return result;
1236 }
1237
1238 result = request.put_u32(NAN_ATTRIBUTE_RANGING_INGRESS_LIMIT,
1239 mParams->ranging_cfg.distance_ingress_mm);
1240 if (result < 0) {
1241 ALOGE("%s: Failed to fill distance_ingress_mm, result = %d\n", __func__, result);
1242 return result;
1243 }
1244 }
1245
1246 ALOGI("%s:RSSI threshold flag %d", __func__, mParams->rssi_threshold_flag);
1247 result = request.put_u8(NAN_ATTRIBUTE_RSSI_THRESHOLD_FLAG,
1248 mParams->rssi_threshold_flag);
1249 if (result < 0) {
1250 ALOGE("%s: Failed to fill rssi_threshold_flag, result = %d\n",
1251 __func__, result);
1252 return result;
1253 }
1254
1255 if (mParams->sdea_service_specific_info_len) {
1256 result = request.put_u16(NAN_ATTRIBUTE_SDEA_SERVICE_SPECIFIC_INFO_LEN,
1257 mParams->sdea_service_specific_info_len);
1258 if (result < 0) {
1259 ALOGE("%s: Failed to fill sdea svc info len, result = %d\n", __func__, result);
1260 return result;
1261 }
1262
1263 prhex(NULL, mParams->sdea_service_specific_info, mParams->sdea_service_specific_info_len);
1264 result = request.put(NAN_ATTRIBUTE_SDEA_SERVICE_SPECIFIC_INFO,
1265 (void *)mParams->sdea_service_specific_info, mParams->sdea_service_specific_info_len);
1266 if (result < 0) {
1267 ALOGE("%s: Failed to fill sdea svc info, result = %d\n", __func__, result);
1268 return result;
1269 }
1270 }
1271
1272 request.attr_end(data);
1273 NAN_DBG_EXIT();
1274 return WIFI_SUCCESS;
1275 }
1276
createSubscribeCancelRequest(WifiRequest & request,NanSubscribeCancelRequest * mParams)1277 int createSubscribeCancelRequest(WifiRequest& request,
1278 NanSubscribeCancelRequest *mParams) {
1279 int result = request.create(GOOGLE_OUI, NAN_SUBCMD_SUBSCRIBE_CANCEL);
1280 if (result < 0) {
1281 ALOGE("%s Failed to create request \n", __func__);
1282 return result;
1283 }
1284
1285 NAN_DBG_ENTER();
1286 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
1287
1288 if (ISGREATER(mInstId, NAN_MAX)) {
1289 ALOGE("%s:Invalid subscribe id value.\n", __FUNCTION__);
1290 return WIFI_ERROR_NOT_SUPPORTED;
1291 }
1292 ALOGI("%s: sub id = %u\n", __func__, mInstId);
1293
1294 result = request.put_u16(NAN_ATTRIBUTE_SUBSCRIBE_ID, mInstId);
1295 if (result < 0) {
1296 ALOGE("%s: Failed to fill sub id, result = %d\n", __func__, result);
1297 return result;
1298 }
1299
1300 request.attr_end(data);
1301 NAN_DBG_EXIT();
1302 return WIFI_SUCCESS;
1303 }
1304
createTransmitFollowupRequest(WifiRequest & request,NanTransmitFollowupRequest * mParams)1305 int createTransmitFollowupRequest(WifiRequest& request,
1306 NanTransmitFollowupRequest *mParams)
1307 {
1308 int result = request.create(GOOGLE_OUI, NAN_SUBCMD_TRANSMIT_FOLLOWUP);
1309 if (result < 0) {
1310 ALOGE("%s Failed to create request \n", __func__);
1311 return result;
1312 }
1313
1314 NAN_DBG_ENTER();
1315
1316 /* If handle is 0xFFFF, then update instance_id in response of this request
1317 * otherwise, update not needed
1318 */
1319 mInstId = mParams->publish_subscribe_id;
1320 mPeerId = mParams->requestor_instance_id;
1321 mTxId = getTransactionId();
1322 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
1323
1324 result = request.put_u32(NAN_ATTRIBUTE_PEER_ID, mPeerId);
1325 if (result < 0) {
1326 ALOGE("%s: Failed to fill peer id, result = %d\n", __func__, result);
1327 return result;
1328 }
1329
1330 result = request.put_u16(NAN_ATTRIBUTE_INST_ID, mInstId);
1331 if (result < 0) {
1332 ALOGE("%s Failed to fill inst id = %d \n", __func__, mInstId);
1333 return result;
1334 }
1335
1336 result = request.put_addr(NAN_ATTRIBUTE_MAC_ADDR, mParams->addr);
1337 if (result < 0) {
1338 ALOGE("%s: Failed to fill mac addr\n", __func__);
1339 return result;
1340 }
1341
1342 if (mParams->service_specific_info_len > 0) {
1343 result = request.put_u16(NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO_LEN,
1344 mParams->service_specific_info_len);
1345 if (result < 0) {
1346 ALOGE("%s: Failed to fill svc info len \n", __func__);
1347 return result;
1348 }
1349
1350 prhex(NULL, mParams->service_specific_info, mParams->service_specific_info_len);
1351 result = request.put(NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO,
1352 (void *)mParams->service_specific_info, mParams->service_specific_info_len);
1353 if (result < 0) {
1354 ALOGE("%s: Failed to put svc info, result = %d", __func__, result);
1355 return result;
1356 }
1357 mParams->service_specific_info[mParams->service_specific_info_len] = '\0';
1358 ALOGI("Transmit service info string is %s\n", mParams->service_specific_info);
1359 }
1360
1361 if (ISGREATER(mParams->recv_indication_cfg, NAN_PUB_RECV_FLAG_MAX)) {
1362 ALOGE("%s:Invalid recv_flag value.\n", __FUNCTION__);
1363 return WIFI_ERROR_NOT_SUPPORTED;
1364 }
1365
1366 result = request.put_u8(NAN_ATTRIBUTE_RECV_IND_CFG,
1367 mParams->recv_indication_cfg);
1368 if (result < 0) {
1369 ALOGE("%s: Failed to fill NAN_ATTRIBUTE_RECV_IND_CFG, result = %d\n",
1370 __func__, result);
1371 return result;
1372 }
1373 result = request.put_u16(NAN_ATTRIBUTE_TRANSAC_ID, mTxId);
1374 if (result < 0) {
1375 ALOGE("%s: Failed to fill NAN_ATTRIBUTE_TRANSAC_ID, result = %d\n",
1376 __func__, result);
1377 return result;
1378 }
1379
1380 if (mParams->sdea_service_specific_info_len) {
1381 result = request.put_u16(NAN_ATTRIBUTE_SDEA_SERVICE_SPECIFIC_INFO_LEN,
1382 mParams->sdea_service_specific_info_len);
1383 if (result < 0) {
1384 ALOGE("%s: Failed to fill sdea svc info len, result = %d\n", __func__, result);
1385 return result;
1386 }
1387
1388 prhex(NULL, mParams->sdea_service_specific_info, mParams->sdea_service_specific_info_len);
1389 result = request.put(NAN_ATTRIBUTE_SDEA_SERVICE_SPECIFIC_INFO,
1390 (void *)mParams->sdea_service_specific_info, mParams->sdea_service_specific_info_len);
1391 if (result < 0) {
1392 ALOGE("%s: Failed to fill sdea svc info, result = %d\n", __func__, result);
1393 return result;
1394 }
1395 }
1396
1397 request.attr_end(data);
1398 NAN_DBG_EXIT();
1399 return WIFI_SUCCESS;
1400 }
1401
getCapabilitiesRequest(WifiRequest & request)1402 int getCapabilitiesRequest(WifiRequest& request) {
1403 int result = 0;
1404 NAN_DBG_ENTER();
1405
1406 result = request.create(GOOGLE_OUI, NAN_SUBCMD_GET_CAPABILITIES);
1407 if (result < 0) {
1408 ALOGE("%s Failed to create request \n", __func__);
1409 return result;
1410 }
1411 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
1412
1413 request.attr_end(data);
1414
1415 NAN_DBG_EXIT();
1416 return WIFI_SUCCESS;
1417 }
1418
start()1419 int start()
1420 {
1421 int result = 0;
1422 WifiRequest request(familyId(), ifaceId());
1423 result = createRequest(request);
1424 if (result != WIFI_SUCCESS) {
1425 ALOGE("%s: Failed to create setup request; result = %d\n", __func__, result);
1426 return result;
1427 }
1428
1429 result = requestResponse(request);
1430 if (result != WIFI_SUCCESS) {
1431 ALOGE("%s: Failed to configure setup; result = %d\n", __func__, result);
1432 return result;
1433 }
1434
1435 request.destroy();
1436 return WIFI_SUCCESS;
1437 }
1438
valid_disc_response_type(int response_type)1439 virtual bool valid_disc_response_type(int response_type) {
1440 bool valid = false;
1441 switch(response_type) {
1442 case NAN_RESPONSE_PUBLISH:
1443 case NAN_RESPONSE_SUBSCRIBE:
1444 case NAN_GET_CAPABILITIES:
1445 case NAN_RESPONSE_PUBLISH_CANCEL:
1446 case NAN_RESPONSE_SUBSCRIBE_CANCEL:
1447 case NAN_RESPONSE_TRANSMIT_FOLLOWUP:
1448 valid = true;
1449 break;
1450 default:
1451 ALOGE("NanDiscEnginePrmitive:Unknown cmd Response: %d\n", response_type);
1452 break;
1453 }
1454 return valid;
1455 }
1456
handleResponse(WifiEvent & reply)1457 int handleResponse(WifiEvent& reply)
1458 {
1459 nan_hal_resp_t *rsp_vndr_data = NULL;
1460 NanResponseMsg rsp_data;
1461 if (reply.get_cmd() != NL80211_CMD_VENDOR || reply.get_vendor_data() == NULL) {
1462 ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
1463 return NL_SKIP;
1464 }
1465 rsp_vndr_data = (nan_hal_resp_t *)reply.get_vendor_data();
1466 ALOGI("NanDiscEnginePrmitive::handle response\n");
1467 memset(&rsp_data, 0, sizeof(NanResponseMsg));
1468 rsp_data.response_type = get_response_type((WIFI_SUB_COMMAND)rsp_vndr_data->subcmd);
1469 if (!valid_disc_response_type(rsp_data.response_type))
1470 return NL_SKIP;
1471
1472 rsp_data.status = nan_map_response_status(rsp_vndr_data->status);
1473 ALOGE("Mapped hal status = %d\n", rsp_data.status);
1474 if (rsp_vndr_data->nan_reason[0] == '\0') {
1475 memcpy(rsp_data.nan_error, NanStatusToString(rsp_data.status),
1476 strlen(NanStatusToString(rsp_data.status)));
1477 rsp_data.nan_error[strlen(NanStatusToString(rsp_data.status))] = '\0';
1478 }
1479 rsp_data.nan_error[NAN_ERROR_STR_LEN - 1] = '\0';
1480 ALOGI("\n Received nan_error string %s\n", (u8*)rsp_data.nan_error);
1481
1482 if (mInstId == 0 &&
1483 (rsp_data.response_type == NAN_RESPONSE_PUBLISH ||
1484 rsp_data.response_type == NAN_RESPONSE_SUBSCRIBE)) {
1485 ALOGI("Received service instance_id %d\n", rsp_vndr_data->instance_id);
1486 mInstId = rsp_vndr_data->instance_id;
1487 }
1488
1489 if (rsp_data.response_type == NAN_RESPONSE_PUBLISH) {
1490 rsp_data.body.publish_response.publish_id = mInstId;
1491 } else if (rsp_data.response_type == NAN_RESPONSE_SUBSCRIBE) {
1492 rsp_data.body.subscribe_response.subscribe_id = mInstId;
1493 } else if (rsp_data.response_type == NAN_GET_CAPABILITIES) {
1494 memcpy((void *)&rsp_data.body.nan_capabilities, (void *)&rsp_vndr_data->capabilities,
1495 sizeof(rsp_data.body.nan_capabilities));
1496 }
1497
1498 GET_NAN_HANDLE(info)->mHandlers.NotifyResponse(id(), &rsp_data);
1499 ALOGI("NanDiscEnginePrmitive:Received response for cmd [%s], ret %d\n",
1500 NanRspToString(rsp_data.response_type), rsp_data.status);
1501
1502 return NL_SKIP;
1503 }
1504
handleEvent(WifiEvent & event)1505 int handleEvent(WifiEvent& event) {
1506 int cmd = event.get_vendor_subcmd();
1507 u16 attr_type;
1508
1509 ALOGI("Received NanDiscEnginePrimitive event: %d\n", event.get_cmd());
1510 nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
1511
1512 switch(cmd) {
1513 case NAN_EVENT_PUBLISH_TERMINATED:
1514 NanPublishTerminatedInd pub_term_event;
1515
1516 memset(&pub_term_event, 0, sizeof(NanPublishTerminatedInd));
1517
1518 for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
1519 attr_type = it.get_type();
1520
1521 if (attr_type == NAN_ATTRIBUTE_PUBLISH_ID) {
1522 pub_term_event.publish_id = it.get_u32();
1523 ALOGI("pub id = %u", pub_term_event.publish_id);
1524 } else if (attr_type == NAN_ATTRIBUTE_STATUS) {
1525 pub_term_event.reason = (NanStatusType)it.get_u8();
1526 ALOGI("pub termination status %u", pub_term_event.reason);
1527 } else if (attr_type == NAN_ATTRIBUTE_REASON) {
1528 u8 len = min(it.get_len(), sizeof(pub_term_event.nan_reason));
1529 memcpy(pub_term_event.nan_reason, it.get_data(), len);
1530 ALOGI("pub termination reason: %s, len = %d\n",
1531 pub_term_event.nan_reason, len);
1532 } else {
1533 ALOGE("Unknown attr: %u\n", attr_type);
1534 }
1535 }
1536
1537 GET_NAN_HANDLE(info)->mHandlers.EventPublishTerminated(&pub_term_event);
1538 break;
1539
1540 case NAN_EVENT_SUBSCRIBE_MATCH:
1541 NanMatchInd subscribe_event;
1542
1543 memset(&subscribe_event, 0, sizeof(NanMatchInd));
1544
1545 /* By default FW is unable to cache this match */
1546 subscribe_event.out_of_resource_flag = true;
1547
1548 for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
1549 attr_type = it.get_type();
1550
1551 if (attr_type == NAN_ATTRIBUTE_SUBSCRIBE_ID) {
1552 ALOGI("sub id: %u", it.get_u16());
1553 subscribe_event.publish_subscribe_id = it.get_u8();
1554 } else if (attr_type == NAN_ATTRIBUTE_PUBLISH_ID) {
1555 ALOGI("pub id: %u", it.get_u32());
1556 subscribe_event.requestor_instance_id = it.get_u8();
1557 } else if (attr_type == NAN_ATTRIBUTE_MAC_ADDR) {
1558 memcpy(subscribe_event.addr, it.get_data(), NAN_MAC_ADDR_LEN);
1559 ALOGI("Publisher mac: " MACSTR, MAC2STR(subscribe_event.addr));
1560 } else if (attr_type == NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO_LEN) {
1561 ALOGI("svc length %d", it.get_u16());
1562 subscribe_event.service_specific_info_len = it.get_u16();
1563 } else if (attr_type == NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO) {
1564 memcpy(subscribe_event.service_specific_info, it.get_data(),
1565 subscribe_event.service_specific_info_len);
1566 subscribe_event.service_specific_info
1567 [subscribe_event.service_specific_info_len] = '\0';
1568 ALOGI("service info: %s", subscribe_event.service_specific_info);
1569 } else if (attr_type == NAN_ATTRIBUTE_TX_MATCH_FILTER_LEN) {
1570 ALOGI("sdf match filter length: %d", subscribe_event.sdf_match_filter_len);
1571 subscribe_event.sdf_match_filter_len = it.get_u16();
1572 } else if (attr_type == NAN_ATTRIBUTE_TX_MATCH_FILTER) {
1573 memcpy(subscribe_event.sdf_match_filter, it.get_data(),
1574 subscribe_event.sdf_match_filter_len);
1575 subscribe_event.sdf_match_filter
1576 [subscribe_event.sdf_match_filter_len] = '\0';
1577 ALOGI("sdf match filter: %s", subscribe_event.sdf_match_filter);
1578 } else if (attr_type == NAN_ATTRIBUTE_CIPHER_SUITE_TYPE) {
1579 ALOGI("Peer Cipher suite type: %u", it.get_u8());
1580 subscribe_event.peer_cipher_type = it.get_u8();
1581 } else if (attr_type == NAN_ATTRIBUTE_SCID_LEN) {
1582 ALOGI("scid length %d", it.get_u32());
1583 subscribe_event.scid_len= it.get_u32();
1584 } else if (attr_type == NAN_ATTRIBUTE_SCID) {
1585 memcpy(subscribe_event.scid, it.get_data(),
1586 subscribe_event.scid_len);
1587 subscribe_event.scid
1588 [subscribe_event.scid_len] = '\0';
1589 ALOGI("scid: %s", subscribe_event.scid);
1590 } else if (attr_type == NAN_ATTRIBUTE_RANGING_INDICATION) {
1591 subscribe_event.range_info.ranging_event_type = it.get_u32();
1592 ALOGI("ranging indication %d", it.get_u32());
1593 } else if (attr_type == NAN_ATTRIBUTE_RANGING_RESULT) {
1594 subscribe_event.range_info.range_measurement_mm = it.get_u32();
1595 ALOGI("ranging result %d", it.get_u32());
1596 } else if (attr_type == NAN_ATTRIBUTE_RSSI_PROXIMITY) {
1597 subscribe_event.rssi_value = it.get_u8();
1598 ALOGI("rssi value : %u", it.get_u8());
1599 } else if (attr_type == NAN_ATTRIBUTE_SDEA_SERVICE_SPECIFIC_INFO_LEN) {
1600 ALOGI("sdea svc length %d", it.get_u16());
1601 subscribe_event.sdea_service_specific_info_len = it.get_u16();
1602 } else if (attr_type == NAN_ATTRIBUTE_SDEA_SERVICE_SPECIFIC_INFO) {
1603 memcpy(subscribe_event.sdea_service_specific_info, it.get_data(),
1604 subscribe_event.sdea_service_specific_info_len);
1605 subscribe_event.sdea_service_specific_info
1606 [subscribe_event.sdea_service_specific_info_len] = '\0';
1607 ALOGI("sdea service info: %s", subscribe_event.sdea_service_specific_info);
1608 } else if (attr_type == NAN_ATTRIBUTE_MATCH_OCCURRED_FLAG) {
1609 ALOGI("match occurred flag: %u", it.get_u8());
1610 subscribe_event.match_occured_flag = it.get_u8();
1611 } else if (attr_type == NAN_ATTRIBUTE_OUT_OF_RESOURCE_FLAG) {
1612 ALOGI("Out of resource flag: %u", it.get_u8());
1613 subscribe_event.out_of_resource_flag = it.get_u8();
1614 } else if (attr_type == NAN_ATTRIBUTE_SDE_CONTROL_CONFIG_DP) {
1615 ALOGI("Peer config for data path needed: %u", it.get_u8());
1616 subscribe_event.peer_sdea_params.config_nan_data_path = it.get_u8();
1617 } else if (attr_type == NAN_ATTRIBUTE_SDE_CONTROL_DP_TYPE) {
1618 ALOGI("Data Path type: %u", it.get_u8());
1619 subscribe_event.peer_sdea_params.ndp_type = (NdpType)it.get_u8();
1620 } else if (attr_type == NAN_ATTRIBUTE_SDE_CONTROL_SECURITY) {
1621 ALOGI("Security configuration: %u", it.get_u8());
1622 subscribe_event.peer_sdea_params.security_cfg =
1623 (NanDataPathSecurityCfgStatus)it.get_u8();
1624 } else if (attr_type == NAN_ATTRIBUTE_SDE_CONTROL_RANGE_SUPPORT) {
1625 ALOGI("Ranging report state: %u", it.get_u8());
1626 subscribe_event.peer_sdea_params.range_report = (NanRangeReport)it.get_u8();
1627 }
1628 }
1629
1630 GET_NAN_HANDLE(info)->mHandlers.EventMatch(&subscribe_event);
1631 break;
1632
1633 case NAN_EVENT_SUBSCRIBE_UNMATCH:
1634 ALOGE("%s: Not applicable yet\n", __func__);
1635 break;
1636
1637 case NAN_EVENT_SUBSCRIBE_TERMINATED:
1638 NanSubscribeTerminatedInd sub_term_event;
1639 memset(&sub_term_event, 0, sizeof(NanSubscribeTerminatedInd));
1640
1641 for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
1642 attr_type = it.get_type();
1643
1644 if (attr_type == NAN_ATTRIBUTE_SUBSCRIBE_ID) {
1645 sub_term_event.subscribe_id = it.get_u16();
1646 ALOGI("sub id = %u", sub_term_event.subscribe_id);
1647 } else if (attr_type == NAN_ATTRIBUTE_STATUS) {
1648 sub_term_event.reason = (NanStatusType)it.get_u16();
1649 ALOGI("sub termination status %u", sub_term_event.reason);
1650 } else if (attr_type == NAN_ATTRIBUTE_REASON) {
1651 u8 len = min(it.get_len(), sizeof(sub_term_event.nan_reason));
1652 memcpy(sub_term_event.nan_reason, it.get_data(), len);
1653 ALOGI("sub termination nan reason: %s, len = %d\n",
1654 sub_term_event.nan_reason, len);
1655 } else {
1656 ALOGI("Unknown attr: %d\n", attr_type);
1657 }
1658 }
1659
1660 GET_NAN_HANDLE(info)->mHandlers.EventSubscribeTerminated(&sub_term_event);
1661 break;
1662 case NAN_EVENT_MATCH_EXPIRY:
1663 HandleExpiryEvent(info, vendor_data);
1664 break;
1665 case NAN_EVENT_FOLLOWUP:
1666 NanFollowupInd followup_event;
1667 memset(&followup_event, 0, sizeof(NanFollowupInd));
1668
1669 for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
1670 attr_type = it.get_type();
1671
1672 if (attr_type == NAN_ATTRIBUTE_MAC_ADDR) {
1673 memcpy(followup_event.addr, it.get_data(), NAN_MAC_ADDR_LEN);
1674 } else if (attr_type == NAN_ATTRIBUTE_PEER_ID) {
1675 followup_event.publish_subscribe_id = it.get_u16();
1676 } else if (attr_type == NAN_ATTRIBUTE_INST_ID) {
1677 followup_event.requestor_instance_id = it.get_u32();
1678 } else if (attr_type == NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO_LEN) {
1679 followup_event.service_specific_info_len = it.get_u16();
1680 } else if (attr_type == NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO) {
1681 memcpy(followup_event.service_specific_info, it.get_data(),
1682 followup_event.service_specific_info_len);
1683 } else if (attr_type == NAN_ATTRIBUTE_SDEA_SERVICE_SPECIFIC_INFO) {
1684 memcpy(followup_event.sdea_service_specific_info, it.get_data(),
1685 followup_event.sdea_service_specific_info_len);
1686 }
1687 }
1688 counters.transmit_recv++;
1689 GET_NAN_HANDLE(info)->mHandlers.EventFollowup(&followup_event);
1690 break;
1691
1692 case NAN_EVENT_TRANSMIT_FOLLOWUP_IND:
1693 NanTransmitFollowupInd followup_ind;
1694 counters.transmit_txs++;
1695 memset(&followup_ind, 0, sizeof(NanTransmitFollowupInd));
1696 for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
1697 attr_type = it.get_type();
1698 if (attr_type == NAN_ATTRIBUTE_TRANSAC_ID) {
1699 followup_ind.id = it.get_u16();
1700 } else if (attr_type == NAN_ATTRIBUTE_STATUS) {
1701 followup_ind.reason = (NanStatusType)it.get_u8();
1702 } else if (attr_type == NAN_ATTRIBUTE_REASON) {
1703 u8 len = min(it.get_len(), sizeof(followup_ind.nan_reason));
1704 memcpy(followup_ind.nan_reason, it.get_data(), len);
1705 ALOGI("nan transmit followup ind: reason: %s, len = %d\n",
1706 followup_ind.nan_reason, len);
1707 }
1708 }
1709 GET_NAN_HANDLE(info)->mHandlers.EventTransmitFollowup(&followup_ind);
1710 break;
1711 #ifdef NOT_YET
1712 case NAN_EVENT_PUBLISH_REPLIED_IND:
1713 NanPublishRepliedInd pub_reply_event;
1714 memset(&pub_reply_event, 0, sizeof(pub_reply_event));
1715
1716 for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
1717 attr_type = it.get_type();
1718
1719 if (attr_type == NAN_ATTRIBUTE_SUBSCRIBE_ID) {
1720 ALOGI("sub id: %u", it.get_u16());
1721 pub_reply_event.requestor_instance_id = it.get_u8();
1722 } else if (attr_type == NAN_ATTRIBUTE_MAC_ADDR) {
1723 memcpy(pub_reply_event.addr, it.get_data(), NAN_MAC_ADDR_LEN);
1724 ALOGI("Subscriber mac: " MACSTR, MAC2STR(pub_reply_event.addr));
1725 } else if (attr_type == NAN_ATTRIBUTE_RSSI_PROXIMITY) {
1726 pub_reply_event.rssi_value = it.get_u8();
1727 ALOGI("Received rssi value : %u", it.get_u8());
1728 }
1729 }
1730 GET_NAN_HANDLE(info)->mHandlers.EventPublishReplied(&pub_reply_event);
1731 break;
1732 #endif /* NOT_YET */
1733 } // end-of-switch-case
1734 return NL_SKIP;
1735 }
1736 };
1737
1738
1739 ///////////////////////////////////////////////////////////////////////////////
1740 class NanDataPathPrimitive : public WifiCommand
1741 {
1742 NanRequest reqContext;
1743 u32 mNdpId;
1744 NanRequestType mType;
1745 u8 count;
1746
1747 public:
NanDataPathPrimitive(wifi_interface_handle iface,int id,NanRequest params,NanRequestType cmdType)1748 NanDataPathPrimitive(wifi_interface_handle iface, int id,
1749 NanRequest params, NanRequestType cmdType)
1750 : WifiCommand("NanCommand", iface, id), reqContext(params), mType(cmdType)
1751 {
1752 mNdpId = 0;
1753 count = 0;
1754 }
~NanDataPathPrimitive()1755 ~NanDataPathPrimitive() {
1756 ALOGE("NanDataPathPrimitive destroyed\n");
1757 }
1758 u8 mSvcHash[NAN_SVC_HASH_SIZE];
1759 u8 mPubNmi[NAN_MAC_ADDR_LEN];
1760
setType(NanRequestType type)1761 void setType(NanRequestType type ) {
1762 mType = type;
1763 }
1764
getNdpId()1765 int getNdpId() {
1766 return mNdpId;
1767 }
1768
createRequest(WifiRequest & request)1769 int createRequest(WifiRequest& request)
1770 {
1771 ALOGI("NAN CMD: %s\n", NanCmdToString(mType));
1772 if (mType == NAN_DATA_PATH_IFACE_CREATE) {
1773 return createDataPathIfaceRequest(request, (char *)reqContext);
1774 } else if (mType == NAN_DATA_PATH_IFACE_DELETE) {
1775 return deleteDataPathIfaceRequest(request, (char *)reqContext);
1776 } else if (mType == NAN_DATA_PATH_INIT_REQUEST) {
1777 return createDataPathInitRequest(request,
1778 (NanDataPathInitiatorRequest *)reqContext);
1779 } else if (mType == NAN_DATA_PATH_IND_RESPONSE) {
1780 return createDataPathIndResponse(request,
1781 (NanDataPathIndicationResponse *)reqContext);
1782 } else if (mType == NAN_DATA_PATH_END) {
1783 return createDataPathEndRequest(request,
1784 (NanDataPathEndRequest *)reqContext);
1785 } else if (mType == NAN_DATA_PATH_SEC_INFO) {
1786 return createDataPathSecInfoRequest(request,
1787 (NanDataPathSecInfoRequest *)reqContext);
1788 } else {
1789 ALOGE("%s: Unknown NDP request: %d\n", __func__, mType);
1790 }
1791
1792 return WIFI_SUCCESS;
1793 }
1794
createDataPathIfaceRequest(WifiRequest & request,char * iface_name)1795 int createDataPathIfaceRequest(WifiRequest& request, char *iface_name)
1796 {
1797 int result = request.create(GOOGLE_OUI, NAN_SUBCMD_DATA_PATH_IFACE_CREATE);
1798 if (result < 0) {
1799 ALOGE("%s Failed to create request\n", __func__);
1800 return result;
1801 }
1802
1803 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
1804 result = request.put_string(NAN_ATTRIBUTE_IFACE, (char *)iface_name);
1805 if (result < 0) {
1806 ALOGE("%s: Failed to fill iface, result = %d\n", __func__, result);
1807 return result;
1808 }
1809
1810 request.attr_end(data);
1811 return WIFI_SUCCESS;
1812 }
1813
deleteDataPathIfaceRequest(WifiRequest & request,char * iface_name)1814 int deleteDataPathIfaceRequest(WifiRequest& request, char *iface_name)
1815 {
1816 int result = request.create(GOOGLE_OUI, NAN_SUBCMD_DATA_PATH_IFACE_DELETE);
1817 if (result < 0) {
1818 ALOGE("%s: Failed to create request, result = %d\n", __func__, result);
1819 return result;
1820 }
1821
1822 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
1823
1824 result = request.put_string(NAN_ATTRIBUTE_IFACE, (char *)iface_name);
1825 if (result < 0) {
1826 ALOGE("%s: Failed to fill iface, result = %d\n", __func__, result);
1827 return result;
1828 }
1829
1830 request.attr_end(data);
1831 return WIFI_SUCCESS;
1832 }
1833
createDataPathSecInfoRequest(WifiRequest & request,NanDataPathSecInfoRequest * mParams)1834 int createDataPathSecInfoRequest(WifiRequest& request, NanDataPathSecInfoRequest *mParams)
1835 {
1836 int result = request.create(GOOGLE_OUI, NAN_SUBCMD_DATA_PATH_SEC_INFO);
1837 if (result < 0) {
1838 ALOGE("%s Failed to create request\n", __func__);
1839 return result;
1840 }
1841
1842 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
1843
1844 result = request.put_u32(NAN_ATTRIBUTE_PUBLISH_ID, mParams->requestor_instance_id);
1845 if (result < 0) {
1846 ALOGE("%s: Failed to fill instance id = %d, result = %d\n",
1847 __func__, mParams->requestor_instance_id, result);
1848 return result;
1849 }
1850
1851 result = request.put_addr(NAN_ATTRIBUTE_MAC_ADDR, mParams->peer_disc_mac_addr);
1852 if (result < 0) {
1853 ALOGE("%s: Failed to fill mac addr, result = %d\n", __func__, result);
1854 return result;
1855 }
1856
1857 result = request.put_u32(NAN_ATTRIBUTE_NDP_ID, mParams->ndp_instance_id);
1858 if (result < 0) {
1859 ALOGE("%s: Failed to fill ndp_instance_id = %d, result = %d\n",
1860 __func__, mParams->ndp_instance_id, result);
1861 return result;
1862 }
1863
1864 request.attr_end(data);
1865 return WIFI_SUCCESS;
1866 }
1867
createDataPathInitRequest(WifiRequest & request,NanDataPathInitiatorRequest * mParams)1868 int createDataPathInitRequest(WifiRequest& request, NanDataPathInitiatorRequest *mParams)
1869 {
1870 int result = request.create(GOOGLE_OUI, NAN_SUBCMD_DATA_PATH_REQUEST);
1871 u8 pmk_hex[NAN_PMK_INFO_LEN];
1872 if (result < 0) {
1873 ALOGE("%s: Failed to create request, result = %d\n", __func__, result);
1874 return result;
1875 }
1876
1877 mNdpId = mParams->requestor_instance_id;
1878 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
1879
1880 result = request.put_u32(NAN_ATTRIBUTE_PUBLISH_ID, mParams->requestor_instance_id);
1881 if (result < 0) {
1882 ALOGE("%s: Failed to fill pub id = %d, result = %d\n",
1883 __func__, mParams->requestor_instance_id, result);
1884 return result;
1885 }
1886
1887 result = request.put_u32(NAN_ATTRIBUTE_CHANNEL, (u32)mParams->channel);
1888 if (result < 0) {
1889 ALOGE("%s: Failed to fill channel = %d, result = %d\n",
1890 __func__, mParams->channel, result);
1891 return result;
1892 }
1893
1894 result = request.put_addr(NAN_ATTRIBUTE_MAC_ADDR, mParams->peer_disc_mac_addr);
1895 if (result < 0) {
1896 ALOGE("%s: Failed to fill mac addr, result = %d\n", __func__, result);
1897 return result;
1898 }
1899
1900 result = request.put_string(NAN_ATTRIBUTE_IFACE, mParams->ndp_iface);
1901 if (result < 0) {
1902 ALOGE("%s: Failed to fill ndp_iface, result = %d\n", __func__, result);
1903 return result;
1904 }
1905
1906 result = request.put_u8(NAN_ATTRIBUTE_SECURITY,
1907 (NanDataPathSecurityCfgStatus)mParams->ndp_cfg.security_cfg);
1908 if (result < 0) {
1909 ALOGE("%s: Failed to fill security, result = %d\n", __func__, result);
1910 return result;
1911 }
1912
1913 result = request.put_u8(NAN_ATTRIBUTE_QOS,
1914 (NanDataPathQosCfg) mParams->ndp_cfg.qos_cfg);
1915 if (result < 0) {
1916 ALOGE("%s: Failed to fill QoS, result = %d\n", __func__, result);
1917 return result;
1918 }
1919
1920 if (mParams->app_info.ndp_app_info_len) {
1921 result = request.put_u16(NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO_LEN,
1922 mParams->app_info.ndp_app_info_len);
1923 if (result < 0) {
1924 ALOGE("%s: Failed to fill svc info len = %d, result = %d\n",
1925 __func__, mParams->app_info.ndp_app_info_len, result);
1926 return result;
1927 }
1928
1929 result = request.put(NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO,
1930 (void *)mParams->app_info.ndp_app_info, mParams->app_info.ndp_app_info_len);
1931 if (result < 0) {
1932 ALOGE("%s: Failed to fill svc info, result = %d\n", __func__, result);
1933 return result;
1934 }
1935 }
1936
1937 result = request.put_u8(NAN_ATTRIBUTE_CIPHER_SUITE_TYPE,
1938 mParams->cipher_type);
1939 if (result < 0) {
1940 ALOGE("%s: Failed to fill NAN_ATTRIBUTE_CIPHER_SUITE_TYPE, result = %d\n",
1941 __func__, result);
1942 return result;
1943 }
1944
1945 result = request.put_u8(NAN_ATTRIBUTE_KEY_TYPE,
1946 mParams->key_info.key_type);
1947 if (result < 0) {
1948 ALOGE("%s: Failed to fill NAN_ATTRIBUTE_KEY_TYPE, result = %d\n",
1949 __func__, result);
1950 return result;
1951 }
1952
1953
1954 if (mParams->service_name_len) {
1955 result = request.put_u16(NAN_ATTRIBUTE_SERVICE_NAME_LEN, mParams->service_name_len);
1956 if (result < 0) {
1957 ALOGE("%s: Failed to fill svc name len, result = %d\n", __func__, result);
1958 return result;
1959 }
1960
1961 prhex(NULL, mParams->service_name, mParams->service_name_len);
1962 result = request.put(NAN_ATTRIBUTE_SERVICE_NAME, (void *)mParams->service_name,
1963 mParams->service_name_len);
1964 if (result < 0) {
1965 ALOGE("%s: Failed to fill svc name, result = %d\n", __func__, result);
1966 return result;
1967 }
1968 }
1969
1970 if (mParams->key_info.key_type == NAN_SECURITY_KEY_INPUT_PMK) {
1971 if (mParams->key_info.body.pmk_info.pmk_len) {
1972 result = request.put_u32(NAN_ATTRIBUTE_KEY_LEN,
1973 mParams->key_info.body.pmk_info.pmk_len);
1974 if (result < 0) {
1975 ALOGE("%s: Failed to fill pmk len, result = %d\n", __func__, result);
1976 return result;
1977 }
1978 result = request.put(NAN_ATTRIBUTE_KEY_DATA,
1979 (void *)mParams->key_info.body.pmk_info.pmk,
1980 mParams->key_info.body.pmk_info.pmk_len);
1981 if (result < 0) {
1982 ALOGE("%s: Failed to fill pmk, result = %d\n", __func__, result);
1983 return result;
1984 }
1985 }
1986 }
1987
1988 if (mParams->key_info.key_type == NAN_SECURITY_KEY_INPUT_PASSPHRASE) {
1989 if (mParams->key_info.body.passphrase_info.passphrase_len < NAN_SECURITY_MIN_PASSPHRASE_LEN ||
1990 mParams->key_info.body.passphrase_info.passphrase_len > NAN_SECURITY_MAX_PASSPHRASE_LEN) {
1991 ALOGE("passphrase must be between %d and %d characters long\n",
1992 NAN_SECURITY_MIN_PASSPHRASE_LEN,
1993 NAN_SECURITY_MAX_PASSPHRASE_LEN);
1994 return NAN_STATUS_INVALID_PARAM;
1995 } else {
1996 memset(pmk_hex, 0, NAN_PMK_INFO_LEN);
1997 result = passphrase_to_pmk(mParams->peer_disc_mac_addr, mParams->cipher_type,
1998 mParams->service_name, &mParams->key_info, pmk_hex);
1999 if (result < 0) {
2000 ALOGE("%s: Failed to convert passphrase to key data, result = %d\n", __func__, result);
2001 return result;
2002 }
2003 result = request.put_u32(NAN_ATTRIBUTE_KEY_LEN, NAN_PMK_INFO_LEN);
2004 if (result < 0) {
2005 ALOGE("%s: Failed to fill passphrase len, result = %d\n", __func__, result);
2006 return result;
2007 }
2008 result = request.put(NAN_ATTRIBUTE_KEY_DATA, pmk_hex, NAN_PMK_INFO_LEN);
2009 if (result < 0) {
2010 ALOGE("%s: Failed to fill passphrase, result = %d\n", __func__, result);
2011 return result;
2012 }
2013 prhex("PMK", pmk_hex, NAN_PMK_INFO_LEN);
2014 }
2015 }
2016
2017 request.attr_end(data);
2018 return WIFI_SUCCESS;
2019 }
2020
createDataPathIndResponse(WifiRequest & request,NanDataPathIndicationResponse * mParams)2021 int createDataPathIndResponse(WifiRequest& request,
2022 NanDataPathIndicationResponse *mParams)
2023 {
2024 int result = request.create(GOOGLE_OUI, NAN_SUBCMD_DATA_PATH_RESPONSE);
2025 u8 pmk_hex[NAN_PMK_INFO_LEN];
2026 if (result < 0) {
2027 ALOGE("%s: Failed to create request, result = %d\n", __func__, result);
2028 return result;
2029 }
2030
2031 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
2032
2033 result = request.put_u32(NAN_ATTRIBUTE_NDP_ID, mParams->ndp_instance_id);
2034 if (result < 0) {
2035 ALOGE("%s: Failed to fill ndp_instance_id = %d, result = %d\n",
2036 __func__, mParams->ndp_instance_id, result);
2037 return result;
2038 }
2039
2040 result = request.put_string(NAN_ATTRIBUTE_IFACE, mParams->ndp_iface);
2041 if (result < 0) {
2042 ALOGE("%s: Failed to fill ndp_iface, result = %d\n", __func__, result);
2043 return result;
2044 }
2045
2046 result = request.put_u8(NAN_ATTRIBUTE_SECURITY,
2047 (NanDataPathSecurityCfgStatus)mParams->ndp_cfg.security_cfg);
2048 if (result < 0) {
2049 ALOGE("%s: Failed to fill security_cfg, result = %d\n", __func__, result);
2050 return result;
2051 }
2052
2053 result = request.put_u8(NAN_ATTRIBUTE_QOS,
2054 (NanDataPathQosCfg)mParams->ndp_cfg.qos_cfg);
2055 if (result < 0) {
2056 ALOGE("%s: Failed to fill qos_cfg, result = %d\n", __func__, result);
2057 return result;
2058 }
2059
2060 if (mParams->app_info.ndp_app_info_len) {
2061 result = request.put_u16(NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO_LEN,
2062 mParams->app_info.ndp_app_info_len);
2063 if (result < 0) {
2064 ALOGE("%s: Failed to fill svc info len = %d, result = %d\n",
2065 __func__, mParams->app_info.ndp_app_info_len, result);
2066 return result;
2067 }
2068
2069 result = request.put(NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO,
2070 (void *)mParams->app_info.ndp_app_info, mParams->app_info.ndp_app_info_len);
2071 if (result < 0) {
2072 ALOGE("%s: Failed to fill svc info, result = %d\n", __func__, result);
2073 return result;
2074 }
2075 }
2076
2077 result = request.put_u8(NAN_ATTRIBUTE_RSP_CODE, mParams->rsp_code);
2078 if (result < 0) {
2079 ALOGE("%s: Failed to fill resp code = %d, result = %d\n",
2080 __func__, mParams->rsp_code, result);
2081 return result;
2082 }
2083
2084 result = request.put_u8(NAN_ATTRIBUTE_CIPHER_SUITE_TYPE,
2085 mParams->cipher_type);
2086 if (result < 0) {
2087 ALOGE("%s: Failed to fill cipher_type, result = %d\n",
2088 __func__, result);
2089 return result;
2090 }
2091
2092 result = request.put_u8(NAN_ATTRIBUTE_KEY_TYPE,
2093 mParams->key_info.key_type);
2094 if (result < 0) {
2095 ALOGE("%s: Failed to fill key type, result = %d\n",
2096 __func__, result);
2097 return result;
2098 }
2099
2100 if (mParams->service_name_len) {
2101 result = request.put_u16(NAN_ATTRIBUTE_SERVICE_NAME_LEN, mParams->service_name_len);
2102 if (result < 0) {
2103 ALOGE("%s: Failed to fill svc name len, result = %d\n", __func__, result);
2104 return result;
2105 }
2106
2107 prhex(NULL, mParams->service_name, mParams->service_name_len);
2108 result = request.put(NAN_ATTRIBUTE_SERVICE_NAME, (void *)mParams->service_name,
2109 mParams->service_name_len);
2110 if (result < 0) {
2111 ALOGE("%s: Failed to fill svc name, result = %d\n", __func__, result);
2112 return result;
2113 }
2114 }
2115
2116 if (mParams->key_info.key_type == NAN_SECURITY_KEY_INPUT_PMK) {
2117 if (mParams->key_info.body.pmk_info.pmk_len) {
2118 result = request.put_u32(NAN_ATTRIBUTE_KEY_LEN,
2119 mParams->key_info.body.pmk_info.pmk_len);
2120 if (result < 0) {
2121 ALOGE("%s: Failed to fill pmk len, result = %d\n", __func__, result);
2122 return result;
2123 }
2124 result = request.put(NAN_ATTRIBUTE_KEY_DATA,
2125 (void *)mParams->key_info.body.pmk_info.pmk,
2126 mParams->key_info.body.pmk_info.pmk_len);
2127 if (result < 0) {
2128 ALOGE("%s: Failed to fill pmk, result = %d\n", __func__, result);
2129 return result;
2130 }
2131 }
2132 }
2133
2134 if (mParams->key_info.key_type == NAN_SECURITY_KEY_INPUT_PASSPHRASE) {
2135 if (mParams->key_info.body.passphrase_info.passphrase_len < NAN_SECURITY_MIN_PASSPHRASE_LEN ||
2136 mParams->key_info.body.passphrase_info.passphrase_len > NAN_SECURITY_MAX_PASSPHRASE_LEN) {
2137 ALOGE("passphrase must be between %d and %d characters long\n",
2138 NAN_SECURITY_MIN_PASSPHRASE_LEN,
2139 NAN_SECURITY_MAX_PASSPHRASE_LEN);
2140 return NAN_STATUS_INVALID_PARAM;
2141 } else {
2142 memset(pmk_hex, 0, NAN_PMK_INFO_LEN);
2143 result = passphrase_to_pmk(mPubNmi, mParams->cipher_type,
2144 mParams->service_name, &mParams->key_info, pmk_hex);
2145 if (result < 0) {
2146 ALOGE("%s: Failed to convert passphrase to key data, result = %d\n", __func__, result);
2147 return result;
2148 }
2149 result = request.put_u32(NAN_ATTRIBUTE_KEY_LEN, NAN_PMK_INFO_LEN);
2150 if (result < 0) {
2151 ALOGE("%s: Failed to fill passphrase len, result = %d\n", __func__, result);
2152 return result;
2153 }
2154 result = request.put(NAN_ATTRIBUTE_KEY_DATA, pmk_hex, NAN_PMK_INFO_LEN);
2155 if (result < 0) {
2156 ALOGE("%s: Failed to fill passphrase, result = %d\n", __func__, result);
2157 return result;
2158 }
2159 }
2160 }
2161
2162 request.attr_end(data);
2163 return WIFI_SUCCESS;
2164 }
2165
createDataPathEndRequest(WifiRequest & request,NanDataPathEndRequest * mParams)2166 int createDataPathEndRequest(WifiRequest& request, NanDataPathEndRequest *mParams)
2167 {
2168 int result = request.create(GOOGLE_OUI, NAN_SUBCMD_DATA_PATH_END);
2169 if (result < 0) {
2170 ALOGE("%s: Failed to create request, result = %d\n", __func__, result);
2171 return result;
2172 }
2173
2174 count = mParams->num_ndp_instances;
2175 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
2176
2177 result = request.put_u8(NAN_ATTRIBUTE_INST_COUNT, mParams->num_ndp_instances);
2178 if (result < 0) {
2179 ALOGE("%s: Failed to fill num_ndp_instances = %d, result = %d\n",
2180 __func__, mParams->num_ndp_instances, result);
2181 return result;
2182 }
2183
2184 while (count) {
2185 result = request.put_u32(NAN_ATTRIBUTE_NDP_ID, mParams->ndp_instance_id[count-1]);
2186 if (result < 0) {
2187 ALOGE("%s: Failed to fill ndp id = %d, result = %d\n",
2188 __func__, mParams->ndp_instance_id[count-1], result);
2189 return result;
2190 }
2191 ALOGE("%s:NDP ID = %d\n", __func__, mParams->ndp_instance_id[count-1]);
2192 count -= 1;
2193 }
2194
2195 request.attr_end(data);
2196 return WIFI_SUCCESS;
2197 }
2198
open()2199 int open()
2200 {
2201 WifiRequest request(familyId(), ifaceId());
2202 int result = createRequest(request);
2203 if (result != WIFI_SUCCESS) {
2204 ALOGE("%s: failed to create setup request; result = %d", __func__, result);
2205 return result;
2206 }
2207
2208 result = requestResponse(request);
2209 if (result != WIFI_SUCCESS) {
2210 ALOGE("%s: failed to configure setup; result = %d", __func__, result);
2211 return result;
2212 }
2213
2214 request.destroy();
2215 return WIFI_SUCCESS;
2216 }
2217
valid_dp_response_type(int response_type)2218 virtual bool valid_dp_response_type(int response_type) {
2219 bool valid = false;
2220 switch(response_type) {
2221 case NAN_DP_INTERFACE_CREATE:
2222 case NAN_DP_INTERFACE_DELETE:
2223 case NAN_DP_INITIATOR_RESPONSE:
2224 case NAN_DP_RESPONDER_RESPONSE:
2225 case NAN_DP_END:
2226 valid = true;
2227 break;
2228 default:
2229 ALOGE("NanDataPathPrmitive::Unknown cmd Response: %d\n", response_type);
2230 break;
2231 }
2232 return valid;
2233 }
2234
handleResponse(WifiEvent & reply)2235 int handleResponse(WifiEvent& reply)
2236 {
2237 nan_hal_resp_t *rsp_vndr_data = NULL;
2238
2239 if (reply.get_cmd() != NL80211_CMD_VENDOR || reply.get_vendor_data() == NULL) {
2240 ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
2241 return NL_SKIP;
2242 }
2243
2244 rsp_vndr_data = (nan_hal_resp_t *)reply.get_vendor_data();
2245 ALOGI("NanDataPathPrmitive::handle response\n");
2246 int32_t result = rsp_vndr_data->value;
2247 NanResponseMsg rsp_data;
2248
2249 memset(&rsp_data, 0, sizeof(NanResponseMsg));
2250 rsp_data.response_type = get_response_type((WIFI_SUB_COMMAND)rsp_vndr_data->subcmd);
2251
2252 if ((WIFI_SUB_COMMAND)rsp_vndr_data->subcmd == NAN_SUBCMD_DATA_PATH_SEC_INFO) {
2253 /* Follow through */
2254 } else if (!valid_dp_response_type(rsp_data.response_type)) {
2255 return NL_SKIP;
2256 }
2257 rsp_data.status = nan_map_response_status(rsp_vndr_data->status);
2258 ALOGE("Mapped hal status = %d\n", rsp_data.status);
2259
2260 if (rsp_vndr_data->nan_reason[0] == '\0') {
2261 memcpy(rsp_data.nan_error, NanStatusToString(rsp_data.status),
2262 strlen(NanStatusToString(rsp_data.status)));
2263 rsp_data.nan_error[strlen(NanStatusToString(rsp_data.status))] = '\0';
2264 }
2265 rsp_data.nan_error[NAN_ERROR_STR_LEN - 1] = '\0';
2266 ALOGI("\n Received nan_error string %s\n", (u8*)rsp_data.nan_error);
2267
2268 if (rsp_data.response_type == NAN_DP_INITIATOR_RESPONSE) {
2269 ALOGI("received ndp instance_id %d and ret = %d\n", rsp_vndr_data->ndp_instance_id, result);
2270 rsp_data.body.data_request_response.ndp_instance_id = rsp_vndr_data->ndp_instance_id;
2271 mNdpId = rsp_vndr_data->ndp_instance_id;
2272 } else if ((WIFI_SUB_COMMAND)rsp_vndr_data->subcmd == NAN_SUBCMD_DATA_PATH_SEC_INFO) {
2273 memcpy(mPubNmi, rsp_vndr_data->pub_nmi, NAN_MAC_ADDR_LEN);
2274 memcpy(mSvcHash, rsp_vndr_data->svc_hash, NAN_SVC_HASH_SIZE);
2275 return NL_SKIP;
2276 }
2277
2278 ALOGI("NanDataPathPrmitive:Received response for cmd [%s], ret %d\n",
2279 NanRspToString(rsp_data.response_type), rsp_data.status);
2280 GET_NAN_HANDLE(info)->mHandlers.NotifyResponse(id(), &rsp_data);
2281 return NL_SKIP;
2282 }
2283
handleEvent(WifiEvent & event)2284 int handleEvent(WifiEvent& event)
2285 {
2286 int cmd = event.get_vendor_subcmd();
2287 u16 attr_type;
2288
2289 nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
2290
2291 switch(cmd) {
2292 case NAN_EVENT_DATA_REQUEST: {
2293 NanDataPathRequestInd ndp_request_event;
2294 memset(&ndp_request_event, 0, sizeof(NanDataPathRequestInd));
2295 u16 ndp_ind_app_info_len = 0;
2296 counters.dp_req_evt++;
2297 ALOGI("Received NAN_EVENT_DATA_REQUEST_INDICATION\n");
2298
2299 for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
2300 attr_type = it.get_type();
2301
2302 if (attr_type == NAN_ATTRIBUTE_PUBLISH_ID) {
2303 ALOGI("publish_id: %u", it.get_u32());
2304 ndp_request_event.service_instance_id = it.get_u32();
2305
2306 } else if (attr_type == NAN_ATTRIBUTE_MAC_ADDR) {
2307 memcpy(ndp_request_event.peer_disc_mac_addr,
2308 it.get_data(), NAN_MAC_ADDR_LEN);
2309 ALOGI("Discovery MAC addr of the peer/initiator: " MACSTR "\n",
2310 MAC2STR(ndp_request_event.peer_disc_mac_addr));
2311
2312 } else if (attr_type == NAN_ATTRIBUTE_NDP_ID) {
2313 ALOGI("ndp id: %u", it.get_u32());
2314 ndp_request_event.ndp_instance_id = it.get_u32();
2315
2316 } else if (attr_type == NAN_ATTRIBUTE_SECURITY) {
2317 ALOGI("security: %u",
2318 (NanDataPathSecurityCfgStatus)it.get_u8());
2319 ndp_request_event.ndp_cfg.security_cfg =
2320 (NanDataPathSecurityCfgStatus)it.get_u8();
2321
2322 } else if (attr_type == NAN_ATTRIBUTE_QOS) {
2323 ALOGI("QoS: %u", (NanDataPathQosCfg)it.get_u8());
2324 ndp_request_event.ndp_cfg.qos_cfg = (NanDataPathQosCfg)it.get_u8();
2325
2326 } else if (attr_type == NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO_LEN) {
2327 ndp_request_event.app_info.ndp_app_info_len = it.get_u16();
2328 ndp_ind_app_info_len = ndp_request_event.app_info.ndp_app_info_len;
2329
2330 } else if (attr_type == NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO) {
2331 memcpy(ndp_request_event.app_info.ndp_app_info, it.get_data(),
2332 ndp_ind_app_info_len);
2333 ndp_request_event.app_info.ndp_app_info
2334 [ndp_ind_app_info_len] = '\0';
2335 ALOGI("service info: %s", ndp_request_event.app_info.ndp_app_info);
2336
2337 }
2338 }
2339
2340 GET_NAN_HANDLE(info)->mHandlers.EventDataRequest(&ndp_request_event);
2341 break;
2342 }
2343 case NAN_EVENT_DATA_CONFIRMATION: {
2344 NanDataPathConfirmInd ndp_create_confirmation_event;
2345 memset(&ndp_create_confirmation_event, 0, sizeof(NanDataPathConfirmInd));
2346 u16 ndp_conf_app_info_len = 0;
2347 u8 chan_idx = 0;
2348 counters.dp_confirm_evt++;
2349 ALOGI("Received NAN_EVENT_DATA_CONFIRMATION\n");
2350
2351 for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
2352 attr_type = it.get_type();
2353
2354 if (attr_type == NAN_ATTRIBUTE_NDP_ID) {
2355 ALOGI("ndp id: %u", it.get_u32());
2356 ndp_create_confirmation_event.ndp_instance_id = it.get_u32();
2357
2358 } else if (attr_type == NAN_ATTRIBUTE_PEER_NDI_MAC_ADDR) {
2359 memcpy(ndp_create_confirmation_event.peer_ndi_mac_addr, it.get_data(),
2360 NAN_MAC_ADDR_LEN);
2361 ALOGI("NDI mac address of the peer: " MACSTR "\n",
2362 MAC2STR(ndp_create_confirmation_event.peer_ndi_mac_addr));
2363
2364 } else if (attr_type == NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO_LEN) {
2365 ALOGI("service info len: %d", it.get_u16());
2366 ndp_create_confirmation_event.app_info.ndp_app_info_len = it.get_u16();
2367 ndp_conf_app_info_len = ndp_create_confirmation_event.app_info.ndp_app_info_len;
2368 } else if (attr_type == NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO) {
2369 memcpy(ndp_create_confirmation_event.app_info.ndp_app_info,
2370 it.get_data(), ndp_conf_app_info_len);
2371 ndp_create_confirmation_event.app_info.ndp_app_info[ndp_conf_app_info_len]
2372 = '\0';
2373 ALOGI("service info: %s",
2374 ndp_create_confirmation_event.app_info.ndp_app_info);
2375
2376 } else if (attr_type == NAN_ATTRIBUTE_RSP_CODE) {
2377 ALOGI("response code: %u", (NanDataPathResponseCode)it.get_u8());
2378 ndp_create_confirmation_event.rsp_code =
2379 (NanDataPathResponseCode)it.get_u8();
2380 } else if (attr_type == NAN_ATTRIBUTE_STATUS) {
2381 ALOGI("reason code %u", (NanDataPathResponseCode)it.get_u8());
2382 ndp_create_confirmation_event.rsp_code =
2383 (NanDataPathResponseCode)it.get_u8();
2384 } else if (attr_type == NAN_ATTRIBUTE_NUM_CHANNELS) {
2385 ALOGI("num channels %u", it.get_u32());
2386 if (it.get_u32() <= NAN_MAX_CHANNEL_INFO_SUPPORTED) {
2387 ndp_create_confirmation_event.num_channels = it.get_u32();
2388 } else {
2389 ndp_create_confirmation_event.num_channels =
2390 NAN_MAX_CHANNEL_INFO_SUPPORTED;
2391 ALOGE("num channels reset to max allowed %u",
2392 ndp_create_confirmation_event.num_channels);
2393 }
2394 } else if (attr_type == NAN_ATTRIBUTE_CHANNEL_INFO) {
2395 ALOGI("Channel info \n");
2396 memcpy((u8 *)ndp_create_confirmation_event.channel_info, it.get_data(),
2397 ndp_create_confirmation_event.num_channels * sizeof(NanChannelInfo));
2398 while (chan_idx < ndp_create_confirmation_event.num_channels) {
2399 ALOGI("channel: %u, Bandwidth: %u, nss: %u\n",
2400 ndp_create_confirmation_event.channel_info[chan_idx].channel,
2401 ndp_create_confirmation_event.channel_info[chan_idx].bandwidth,
2402 ndp_create_confirmation_event.channel_info[chan_idx].nss);
2403 chan_idx++;
2404 }
2405 }
2406 }
2407 GET_NAN_HANDLE(info)->mHandlers.EventDataConfirm(&ndp_create_confirmation_event);
2408 break;
2409 }
2410 case NAN_EVENT_DATA_END: {
2411 NanDataPathEndInd ndp_end_event;
2412 memset(&ndp_end_event, 0, sizeof(NanDataPathEndInd));
2413 u16 attr_type;
2414 ALOGI("Received NAN_EVENT_DATA_END\n");
2415
2416 for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
2417 attr_type = it.get_type();
2418
2419 if (attr_type == NAN_ATTRIBUTE_INST_COUNT) {
2420 ALOGI("ndp count: %u\n", it.get_u8());
2421 ndp_end_event.num_ndp_instances = it.get_u8();
2422 count = it.get_u8();
2423 } else if (attr_type == NAN_ATTRIBUTE_NDP_ID) {
2424 while (count) {
2425 ndp_end_event.ndp_instance_id[count-1] = it.get_u32();
2426 ALOGI("NDP Id from the Event = %u\n", ndp_end_event.ndp_instance_id[count-1]);
2427 count -= 1;
2428 }
2429 } else {
2430 ALOGI("Unknown attr_type: %s\n", NanAttrToString(attr_type));
2431 }
2432 }
2433
2434 GET_NAN_HANDLE(info)->mHandlers.EventDataEnd(&ndp_end_event);
2435 break;
2436 }
2437 } // end-of-switch
2438 return NL_SKIP;
2439 }
2440 };
2441
2442
2443 ///////////////////////////////////////////////////////////////////////////////
2444 class NanMacControl : public WifiCommand
2445 {
2446 NanRequest mParams;
2447 transaction_id mId = NAN_MAC_INVALID_TRANSID;
2448 wifi_interface_handle mIface;
2449 NanRequestType mType;
2450 u32 mVersion;
2451
2452 public:
NanMacControl(wifi_interface_handle iface,int id,NanRequest params,NanRequestType cmdType)2453 NanMacControl(wifi_interface_handle iface, int id,
2454 NanRequest params, NanRequestType cmdType)
2455 : WifiCommand("NanCommand", iface, id), mParams(params), mType(cmdType)
2456 {
2457 mVersion = 0;
2458 setIface(iface);
2459 setId(id);
2460 }
~NanMacControl()2461 ~NanMacControl() {
2462 ALOGE("NanMacControl destroyed\n");
2463 }
2464
setIface(wifi_interface_handle iface)2465 void setIface(wifi_interface_handle iface ) {
2466 mIface = iface;
2467 }
2468
setId(transaction_id id)2469 void setId(transaction_id id) {
2470 if (id != NAN_MAC_INVALID_TRANSID) {
2471 mId = id;
2472 }
2473 }
2474
getId()2475 transaction_id getId() {
2476 return mId;
2477 }
2478
setType(NanRequestType type)2479 void setType(NanRequestType type) {
2480 mType = type;
2481 }
getVersion()2482 u32 getVersion() {
2483 return mVersion;
2484 }
2485
setMsg(NanRequest params)2486 void setMsg(NanRequest params) {
2487 mParams = params;
2488 }
2489
createRequest(WifiRequest & request)2490 int createRequest(WifiRequest& request) {
2491 ALOGI("NAN CMD: %s\n", NanCmdToString(mType));
2492 if (mType == NAN_REQUEST_ENABLE) {
2493 return createEnableRequest(request, (NanEnableRequest *)mParams);
2494 } else if (mType == NAN_REQUEST_DISABLE) {
2495 return createDisableRequest(request);
2496 } else if (mType == NAN_REQUEST_CONFIG) {
2497 return createConfigRequest(request, (NanConfigRequest*)mParams);
2498 } else if (mType == NAN_REQUEST_STATS) {
2499 /* TODO: Not yet implemented */
2500 } else if (mType == NAN_REQUEST_TCA) {
2501 /* TODO: Not yet implemented */
2502 } else if (mType == NAN_VERSION_INFO) {
2503 return createVersionRequest(request);
2504 } else {
2505 ALOGE("Unknown Nan request\n");
2506 }
2507
2508 return WIFI_SUCCESS;
2509 }
2510
createVersionRequest(WifiRequest & request)2511 int createVersionRequest(WifiRequest& request) {
2512 int result = request.create(GOOGLE_OUI, NAN_SUBCMD_VERSION_INFO);
2513 if (result < 0) {
2514 ALOGE("%s: Fail to create request\n", __func__);
2515 return result;
2516 }
2517 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
2518 request.attr_end(data);
2519 NAN_DBG_EXIT();
2520 return WIFI_SUCCESS;
2521 }
2522
createEnableRequest(WifiRequest & request,NanEnableRequest * mParams)2523 int createEnableRequest(WifiRequest& request, NanEnableRequest *mParams) {
2524 int result = request.create(GOOGLE_OUI, NAN_SUBCMD_ENABLE);
2525 s8 rssi;
2526 if (result < 0) {
2527 ALOGE("%s: Fail to create request\n", __func__);
2528 return result;
2529 }
2530
2531 NAN_DBG_ENTER();
2532
2533 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
2534
2535 if (mParams->config_2dot4g_support) {
2536 result = request.put_u8(NAN_ATTRIBUTE_2G_SUPPORT, mParams->support_2dot4g_val);
2537 if (result < 0) {
2538 ALOGE("%s: Failing in 2g support, result = %d\n", __func__, result);
2539 return result;
2540 }
2541 }
2542
2543 if (mParams->config_support_5g) {
2544 result = request.put_u8(NAN_ATTRIBUTE_5G_SUPPORT, mParams->support_5g_val);
2545 if (result < 0) {
2546 ALOGE("%s: Failing in 5g support, result = %d\n", __func__, result);
2547 return result;
2548 }
2549 }
2550
2551 result = request.put_u16(NAN_ATTRIBUTE_CLUSTER_LOW, mParams->cluster_low);
2552 if (result < 0) {
2553 ALOGE("%s: Failing in cluster low, result = %d\n", __func__, result);
2554 return result;
2555 }
2556
2557 result = request.put_u16(NAN_ATTRIBUTE_CLUSTER_HIGH, mParams->cluster_high);
2558 if (result < 0) {
2559 ALOGE("%s: Failing in cluster high, result = %d\n", __func__, result);
2560 return result;
2561 }
2562
2563 if (mParams->config_sid_beacon) {
2564 result = request.put_u8(NAN_ATTRIBUTE_SID_BEACON, mParams->sid_beacon_val);
2565 if (result < 0) {
2566 ALOGE("%s: Failing in sid beacon, result = %d\n", __func__, result);
2567 return result;
2568 }
2569 }
2570
2571 if (mParams->config_subscribe_sid_beacon) {
2572 result = request.put_u8(NAN_ATTRIBUTE_SUB_SID_BEACON, mParams->subscribe_sid_beacon_val);
2573 if (result < 0) {
2574 ALOGE("%s: Failing in sub sid beacon, result = %d\n", __func__, result);
2575 return result;
2576 }
2577 }
2578
2579 if (mParams->config_2dot4g_beacons) {
2580 result = request.put_u8(NAN_ATTRIBUTE_SYNC_DISC_2G_BEACON, mParams->beacon_2dot4g_val);
2581 if (result < 0) {
2582 ALOGE("%s: Failing in beacon_2dot4g_val, result = %d\n", __func__, result);
2583 return result;
2584 }
2585 }
2586
2587 if (mParams->config_5g_beacons) {
2588 result = request.put_u8(NAN_ATTRIBUTE_SYNC_DISC_5G_BEACON, mParams->beacon_5g_val);
2589 if (result < 0) {
2590 ALOGE("%s: Failing in 5g beacon, result = %d\n", __func__, result);
2591 return result;
2592 }
2593 }
2594
2595 if (mParams->config_2dot4g_sdf) {
2596 result = request.put_u8(NAN_ATTRIBUTE_SDF_2G_SUPPORT, mParams->sdf_2dot4g_val);
2597 if (result < 0) {
2598 ALOGE("%s: Failing in 2dot4g sdf, result = %d\n", __func__, result);
2599 return result;
2600 }
2601 }
2602
2603 if (mParams->config_5g_sdf) {
2604 result = request.put_u8(NAN_ATTRIBUTE_SDF_5G_SUPPORT, mParams->sdf_5g_val);
2605 if (result < 0) {
2606 ALOGE("%s: Failing in 5g sdf, result = %d\n", __func__, result);
2607 return result;
2608 }
2609 }
2610
2611 if (mParams->config_2dot4g_rssi_close) {
2612 if (ISGREATER(mParams->rssi_close_2dot4g_val, NAN_MAX_RSSI)) {
2613 ALOGI("%s: Invalid rssi param \n", __func__);
2614 return WIFI_ERROR_INVALID_ARGS;
2615 }
2616 rssi = -mParams->rssi_close_2dot4g_val;
2617 result = request.put_s8(NAN_ATTRIBUTE_RSSI_CLOSE, rssi);
2618 if (result < 0) {
2619 ALOGE("%s: Failing in 2g rssi close, result = %d\n", __func__, result);
2620 return result;
2621 }
2622 }
2623
2624 if (mParams->config_2dot4g_rssi_middle) {
2625 if (ISGREATER(mParams->rssi_middle_2dot4g_val, NAN_MAX_RSSI)) {
2626 ALOGI("%s: Invalid rssi param \n", __func__);
2627 return WIFI_ERROR_INVALID_ARGS;
2628 }
2629 rssi = -mParams->rssi_middle_2dot4g_val;
2630 result = request.put_s8(NAN_ATTRIBUTE_RSSI_MIDDLE, rssi);
2631 if (result < 0) {
2632 ALOGE("%s: Failing in 2g rssi middle, result = %d\n", __func__, result);
2633 return result;
2634 }
2635 }
2636
2637 if (mParams->config_2dot4g_rssi_proximity) {
2638 if (ISGREATER(mParams->rssi_proximity_2dot4g_val, NAN_MAX_RSSI)) {
2639 ALOGI("%s: Invalid rssi param \n", __func__);
2640 return WIFI_ERROR_INVALID_ARGS;
2641 }
2642 rssi = -mParams->rssi_proximity_2dot4g_val;
2643 result = request.put_s8(NAN_ATTRIBUTE_RSSI_PROXIMITY, rssi);
2644 if (result < 0) {
2645 ALOGE("%s: Failing in 2g rssi proximity, result = %d\n", __func__, result);
2646 return result;
2647 }
2648 }
2649
2650 if (mParams->config_5g_rssi_close) {
2651 if (ISGREATER(mParams->rssi_close_5g_val, NAN_MAX_RSSI)) {
2652 ALOGI("%s: Invalid rssi param \n", __func__);
2653 return WIFI_ERROR_INVALID_ARGS;
2654 }
2655 rssi = -mParams->rssi_close_5g_val;
2656 result = request.put_s8(NAN_ATTRIBUTE_RSSI_CLOSE_5G, rssi);
2657 if (result < 0) {
2658 ALOGE("%s: Failing in 5g rssi close, result = %d\n", __func__, result);
2659 return result;
2660 }
2661 }
2662
2663 if (mParams->config_5g_rssi_middle) {
2664 if (ISGREATER(mParams->rssi_middle_5g_val, NAN_MAX_RSSI)) {
2665 ALOGI("%s: Invalid rssi param \n", __func__);
2666 return WIFI_ERROR_INVALID_ARGS;
2667 }
2668 rssi = -mParams->rssi_middle_5g_val;
2669 result = request.put_s8(NAN_ATTRIBUTE_RSSI_MIDDLE_5G, rssi);
2670 if (result < 0) {
2671 ALOGE("%s: Failing in 5g rssi middle, result = %d\n", __func__, result);
2672 return result;
2673 }
2674 }
2675
2676 if (mParams->config_5g_rssi_close_proximity) {
2677 if (ISGREATER(mParams->rssi_close_proximity_5g_val, NAN_MAX_RSSI)) {
2678 ALOGI("%s: Invalid rssi param \n", __func__);
2679 return WIFI_ERROR_INVALID_ARGS;
2680 }
2681 rssi = -mParams->rssi_close_proximity_5g_val;
2682 result = request.put_s8(NAN_ATTRIBUTE_RSSI_PROXIMITY_5G, rssi);
2683 if (result < 0) {
2684 ALOGE("%s: Failing in rssi_close_proximity_5g_val, result = %d\n", __func__, result);
2685 return result;
2686 }
2687 }
2688
2689 if (mParams->config_cluster_attribute_val) {
2690 result = request.put_u8(NAN_ATTRIBUTE_CONF_CLUSTER_VAL, mParams->config_cluster_attribute_val);
2691 if (result < 0) {
2692 ALOGE("%s: Failing in config_cluster_attribute_val, result = %d\n", __func__, result);
2693 return result;
2694 }
2695 }
2696
2697 if (mParams->config_hop_count_limit) {
2698 result = request.put_u8(NAN_ATTRIBUTE_HOP_COUNT_LIMIT,
2699 mParams->hop_count_limit_val);
2700 if (result < 0) {
2701 ALOGE("%s: Failing in hop cnt limit, result = %d\n", __func__, result);
2702 return result;
2703 }
2704 }
2705
2706 if (mParams->config_oui) {
2707 ALOGI("%s: oui = 0x%04x\n", __func__, mParams->oui_val);
2708 result = request.put_u32(NAN_ATTRIBUTE_OUI, mParams->oui_val);
2709 if (result < 0) {
2710 ALOGE("%s: Failing in oui, result = %d\n", __func__, result);
2711 return result;
2712 }
2713 }
2714
2715 result = request.put_u8(NAN_ATTRIBUTE_MASTER_PREF, mParams->master_pref);
2716 if (result < 0) {
2717 ALOGE("%s: Failing in master pref, result = %d\n", __func__, result);
2718 return result;
2719 }
2720 if (mParams->config_random_factor_force) {
2721 result = request.put_u8(NAN_ATTRIBUTE_RANDOM_FACTOR, mParams->random_factor_force_val);
2722 if (result < 0) {
2723 ALOGE("%s: Failing in random factor, result = %d\n", __func__, result);
2724 return result;
2725 }
2726 }
2727
2728 if (mParams->config_24g_channel) {
2729 result = request.put_u32(NAN_ATTRIBUTE_24G_CHANNEL, mParams->channel_24g_val);
2730 if (result < 0) {
2731 ALOGE("%s: Failing in 2.4g channel, result = %d\n", __func__, result);
2732 return result;
2733 }
2734 }
2735
2736 if (mParams->config_5g_channel) {
2737 result = request.put_u32(NAN_ATTRIBUTE_5G_CHANNEL, mParams->channel_5g_val);
2738 if (result < 0) {
2739 ALOGE("%s: Failing in 5g channel, result = %d\n", __func__, result);
2740 return result;
2741 }
2742 }
2743
2744 if (mParams->config_intf_addr) {
2745 result = request.put_addr(NAN_ATTRIBUTE_IF_ADDR, mParams->intf_addr_val);
2746 if (result < 0) {
2747 ALOGE("%s: Failing in intf addr val, result = %d\n", __func__, result);
2748 return result;
2749 }
2750 }
2751
2752 if (mParams->config_dw.config_2dot4g_dw_band) {
2753 result = request.put_u32(NAN_ATTRIBUTE_2G_AWAKE_DW, mParams->config_dw.dw_2dot4g_interval_val);
2754 if (result < 0) {
2755 ALOGE("%s: Failing in 2dot4g awake dw, result = %d\n", __func__, result);
2756 return result;
2757 }
2758 }
2759
2760 if (mParams->config_dw.config_5g_dw_band) {
2761 result = request.put_u32(NAN_ATTRIBUTE_5G_AWAKE_DW, mParams->config_dw.dw_5g_interval_val);
2762 if (result < 0) {
2763 ALOGE("%s: Failing in 5g awake dw, result = %d\n", __func__, result);
2764 return result;
2765 }
2766 }
2767
2768 if (ISGREATER(mParams->discovery_indication_cfg, NAN_DISC_IND_MAX)) {
2769 ALOGE("%s:Invalid disc_ind_cfg value.\n", __FUNCTION__);
2770 return WIFI_ERROR_INVALID_ARGS;
2771 }
2772
2773 result = request.put_u8(NAN_ATTRIBUTE_DISC_IND_CFG,
2774 mParams->discovery_indication_cfg);
2775 if (result < 0) {
2776 ALOGE("%s: Failed to fill NAN_ATTRIBUTE_DISC_IND_CFG, result = %d\n",
2777 __func__, result);
2778 return result;
2779 }
2780
2781 if (mParams->config_rssi_window_size) {
2782 result = request.put_u8(NAN_ATTRIBUTE_RSSI_WINDOW_SIZE,
2783 mParams->rssi_window_size_val);
2784 if (result < 0) {
2785 ALOGE("%s: Failing in rssi_window_size_val, result = %d\n", __func__, result);
2786 return result;
2787 }
2788 }
2789
2790 if (mParams->config_scan_params) {
2791 result = request.put_u8(NAN_ATTRIBUTE_DWELL_TIME,
2792 mParams->scan_params_val.dwell_time[0]);
2793 if (result < 0) {
2794 ALOGE("%s: Failing in dwell time, result = %d\n", __func__, result);
2795 return result;
2796 }
2797 result = request.put_u8(NAN_ATTRIBUTE_DWELL_TIME_5G,
2798 mParams->scan_params_val.dwell_time[1]);
2799 if (result < 0) {
2800 ALOGE("%s: Failing in 5g dwell time, result = %d\n", __func__, result);
2801 return result;
2802 }
2803 result = request.put_u16(NAN_ATTRIBUTE_SCAN_PERIOD,
2804 mParams->scan_params_val.scan_period[0]);
2805 if (result < 0) {
2806 ALOGE("%s: Failing in scan_period, result = %d\n", __func__, result);
2807 return result;
2808 }
2809 result = request.put_u16(NAN_ATTRIBUTE_SCAN_PERIOD_5G,
2810 mParams->scan_params_val.scan_period[1]);
2811 if (result < 0) {
2812 ALOGE("%s: Failing in 5g scan_period, result = %d\n", __func__, result);
2813 return result;
2814 }
2815 }
2816
2817 if (mParams->config_disc_mac_addr_randomization) {
2818 result = request.put_u32(NAN_ATTRIBUTE_RANDOMIZATION_INTERVAL,
2819 mParams->disc_mac_addr_rand_interval_sec);
2820 if (result < 0) {
2821 ALOGE("%s: Failing to fill rand mac address interval, result = %d\n", __func__, result);
2822 return result;
2823 }
2824 }
2825
2826 if (mParams->config_discovery_beacon_int) {
2827 result = request.put_u32(NAN_ATTRIBUTE_DISCOVERY_BEACON_INTERVAL,
2828 mParams->discovery_beacon_interval);
2829 if (result < 0) {
2830 ALOGE("%s: Failing to fill disc beacon interval, result = %d\n", __func__, result);
2831 return result;
2832 }
2833 }
2834
2835 if (mParams->config_nss) {
2836 result = request.put_u32(NAN_ATTRIBUTE_NSS, mParams->nss);
2837 if (result < 0) {
2838 ALOGE("%s: Failing to fill nss, result = %d\n", __func__, result);
2839 return result;
2840 }
2841 }
2842
2843 if (mParams->config_enable_ranging) {
2844 result = request.put_u32(NAN_ATTRIBUTE_ENABLE_RANGING, mParams->enable_ranging);
2845 if (result < 0) {
2846 ALOGE("%s: Failing to fill enable ranging value, result = %d\n", __func__, result);
2847 return result;
2848 }
2849 }
2850
2851 if (mParams->config_dw_early_termination) {
2852 result = request.put_u32(NAN_ATTRIBUTE_DW_EARLY_TERM, mParams->enable_dw_termination);
2853 if (result < 0) {
2854 ALOGE("%s: Failing to fill enable dw termination value, result = %d\n",
2855 __func__, result);
2856 return result;
2857 }
2858 }
2859
2860 if (mParams->config_ndpe_attr) {
2861 result = request.put_u32(NAN_ATTRIBUTE_CMD_USE_NDPE,
2862 mParams->use_ndpe_attr);
2863 if (result < 0) {
2864 ALOGE("%s: Failing to fill use_ndpe, result = %d\n", __func__, result);
2865 return result;
2866 }
2867 }
2868
2869 request.attr_end(data);
2870 NAN_DBG_EXIT();
2871 return WIFI_SUCCESS;
2872 }
2873
createDisableRequest(WifiRequest & request)2874 int createDisableRequest(WifiRequest& request) {
2875 NAN_DBG_ENTER();
2876
2877 int result = request.create(GOOGLE_OUI, NAN_SUBCMD_DISABLE);
2878 if (result < 0) {
2879 ALOGE("%s: Fail to create request, result = %d\n", __func__, result);
2880 return result;
2881 }
2882
2883 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
2884
2885 request.attr_end(data);
2886
2887 NAN_DBG_EXIT();
2888 return result;
2889 }
2890
createConfigRequest(WifiRequest & request,NanConfigRequest * mParams)2891 int createConfigRequest(WifiRequest& request, NanConfigRequest *mParams) {
2892
2893 int result = request.create(GOOGLE_OUI, NAN_SUBCMD_CONFIG);
2894 s8 rssi;
2895 if (result < 0) {
2896 ALOGE("%s: Fail to create config request\n", __func__);
2897 return result;
2898 }
2899
2900 NAN_DBG_ENTER();
2901
2902 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
2903
2904 if (mParams->config_sid_beacon) {
2905 result = request.put_u8(NAN_ATTRIBUTE_SID_BEACON, mParams->sid_beacon);
2906 if (result < 0) {
2907 ALOGE("%s: Failing in sid beacon, result = %d\n", __func__, result);
2908 return result;
2909 }
2910 }
2911
2912 if (mParams->config_subscribe_sid_beacon) {
2913 result = request.put_u8(NAN_ATTRIBUTE_SUB_SID_BEACON, mParams->subscribe_sid_beacon_val);
2914 if (result < 0) {
2915 ALOGE("%s: Failing in sub sid beacon, result = %d\n", __func__, result);
2916 return result;
2917 }
2918 }
2919
2920 if (mParams->config_rssi_proximity) {
2921 if (ISGREATER(mParams->rssi_proximity, NAN_MAX_RSSI)) {
2922 ALOGI("%s: Invalid rssi param \n", __func__);
2923 return WIFI_ERROR_INVALID_ARGS;
2924 }
2925 rssi = -mParams->rssi_proximity;
2926 result = request.put_s8(NAN_ATTRIBUTE_RSSI_PROXIMITY, rssi);
2927 if (result < 0) {
2928 ALOGE("%s: Failing in rssi_proximity, result = %d\n", __func__, result);
2929 return result;
2930 }
2931 }
2932
2933 if (mParams->config_master_pref) {
2934 ALOGI("%s: master pref = %u\n", __func__, mParams->master_pref);
2935 result = request.put_u8(NAN_ATTRIBUTE_MASTER_PREF, mParams->master_pref);
2936 if (result < 0) {
2937 ALOGE("%s: Failing in master pref, result = %d\n", __func__, result);
2938 return result;
2939 }
2940 }
2941
2942 if (mParams->config_5g_rssi_close_proximity) {
2943 if (ISGREATER(mParams->rssi_close_proximity_5g_val, NAN_MAX_RSSI)) {
2944 ALOGI("%s: Invalid rssi param \n", __func__);
2945 return WIFI_ERROR_INVALID_ARGS;
2946 }
2947 rssi = -mParams->rssi_close_proximity_5g_val;
2948 result = request.put_s8(NAN_ATTRIBUTE_RSSI_PROXIMITY_5G, rssi);
2949 if (result < 0) {
2950 ALOGE("%s: Failing in rssi_close_proximity_5g_val, result = %d\n", __func__, result);
2951 return result;
2952 }
2953 }
2954
2955 if (mParams->config_rssi_window_size) {
2956 result = request.put_u8(NAN_ATTRIBUTE_RSSI_WINDOW_SIZE,
2957 mParams->rssi_window_size_val);
2958 if (result < 0) {
2959 ALOGE("%s: Failing in rssi_window_size_val, result = %d\n", __func__, result);
2960 return result;
2961 }
2962 }
2963
2964 if (mParams->config_scan_params) {
2965 result = request.put_u8(NAN_ATTRIBUTE_DWELL_TIME,
2966 mParams->scan_params_val.dwell_time[0]);
2967 if (result < 0) {
2968 ALOGE("%s: Failing in dwell time, result = %d\n", __func__, result);
2969 return result;
2970 }
2971
2972 result = request.put_u8(NAN_ATTRIBUTE_DWELL_TIME_5G,
2973 mParams->scan_params_val.dwell_time[1]);
2974 if (result < 0) {
2975 ALOGE("%s: Failing in 5g dwell time, result = %d\n", __func__, result);
2976 return result;
2977 }
2978 result = request.put_u16(NAN_ATTRIBUTE_SCAN_PERIOD,
2979 mParams->scan_params_val.scan_period[0]);
2980 if (result < 0) {
2981 ALOGE("%s: Failing in scan_period, result = %d\n", __func__, result);
2982 return result;
2983 }
2984
2985 result = request.put_u16(NAN_ATTRIBUTE_SCAN_PERIOD_5G,
2986 mParams->scan_params_val.scan_period[1]);
2987 if (result < 0) {
2988 ALOGE("%s: Failing in 5g scan_period, result = %d\n", __func__, result);
2989 return result;
2990 }
2991 }
2992
2993 if (mParams->config_random_factor_force) {
2994 result = request.put_u8(NAN_ATTRIBUTE_RANDOM_FACTOR, mParams->random_factor_force_val);
2995 if (result < 0) {
2996 ALOGE("%s: Failing in random factor, result = %d\n", __func__, result);
2997 return result;
2998 }
2999 }
3000
3001 if (mParams->config_hop_count_force) {
3002 result = request.put_u8(NAN_ATTRIBUTE_HOP_COUNT_LIMIT,
3003 mParams->hop_count_force_val);
3004 if (result < 0) {
3005 ALOGE("%s: Failing in hop cnt limit, result = %d\n", __func__, result);
3006 return result;
3007 }
3008 }
3009
3010 if (mParams->config_cluster_attribute_val) {
3011 result = request.put_u8(NAN_ATTRIBUTE_CONF_CLUSTER_VAL, mParams->config_cluster_attribute_val);
3012 if (result < 0) {
3013 ALOGE("%s: Failing in config_cluster_attribute_val, result = %d\n", __func__, result);
3014 return result;
3015 }
3016 }
3017
3018 if (mParams->config_fam) {
3019 while (mParams->fam_val.numchans) {
3020 result = request.put_u8(NAN_ATTRIBUTE_ENTRY_CONTROL,
3021 mParams->fam_val.famchan[mParams->fam_val.numchans].entry_control);
3022 if (result < 0) {
3023 ALOGE("%s: Failing in entry control, result = %d\n", __func__, result);
3024 return result;
3025 }
3026
3027 result = request.put_u32(NAN_ATTRIBUTE_CHANNEL,
3028 (u32)mParams->fam_val.famchan[mParams->fam_val.numchans].channel);
3029 if (result < 0) {
3030 ALOGE("%s: Failed to fill channel = %d, result = %d\n", __func__,
3031 mParams->fam_val.famchan[mParams->fam_val.numchans].channel, result);
3032 return result;
3033 }
3034
3035 result = request.put_u32(NAN_ATTRIBUTE_AVAIL_BIT_MAP,
3036 (u32)mParams->fam_val.famchan[mParams->fam_val.numchans].avail_interval_bitmap);
3037 if (result < 0) {
3038 ALOGE("%s: Failed to fill avail interval bitmap = %d, result = %d\n", __func__,
3039 mParams->fam_val.famchan[mParams->fam_val.numchans].avail_interval_bitmap, result);
3040 return result;
3041 }
3042 mParams->fam_val.numchans -= 1;
3043 }
3044
3045 }
3046
3047 if (mParams->config_dw.config_2dot4g_dw_band) {
3048 result = request.put_u32(NAN_ATTRIBUTE_2G_AWAKE_DW, mParams->config_dw.dw_2dot4g_interval_val);
3049 if (result < 0) {
3050 ALOGE("%s: Failing in 2dot4g awake dw, result = %d\n", __func__, result);
3051 return result;
3052 }
3053 }
3054
3055 if (mParams->config_dw.config_5g_dw_band) {
3056 result = request.put_u32(NAN_ATTRIBUTE_5G_AWAKE_DW, mParams->config_dw.dw_5g_interval_val);
3057 if (result < 0) {
3058 ALOGE("%s: Failing in 5g awake dw, result = %d\n", __func__, result);
3059 return result;
3060 }
3061 }
3062 if (ISGREATER(mParams->discovery_indication_cfg, NAN_DISC_IND_MAX)) {
3063 ALOGE("%s:Invalid disc_ind_cfg value.\n", __FUNCTION__);
3064 return WIFI_ERROR_INVALID_ARGS;
3065 }
3066 result = request.put_u8(NAN_ATTRIBUTE_DISC_IND_CFG,
3067 mParams->discovery_indication_cfg);
3068 if (result < 0) {
3069 ALOGE("%s: Failed to fill NAN_ATTRIBUTE_DISC_IND_CFG, result = %d\n",
3070 __func__, result);
3071 return result;
3072 }
3073 if (mParams->config_disc_mac_addr_randomization) {
3074 result = request.put_u32(NAN_ATTRIBUTE_RANDOMIZATION_INTERVAL,
3075 mParams->disc_mac_addr_rand_interval_sec);
3076 if (result < 0) {
3077 ALOGE("%s: Failing in 5g scan_period, result = %d\n", __func__, result);
3078 return result;
3079 }
3080 }
3081 if (mParams->config_ndpe_attr) {
3082 result = request.put_u32(NAN_ATTRIBUTE_CMD_USE_NDPE,
3083 mParams->use_ndpe_attr);
3084 if (result < 0) {
3085 ALOGE("%s: Failing to fill use_ndpe, result = %d\n", __func__, result);
3086 return result;
3087 }
3088 }
3089
3090 if (mParams->config_disc_mac_addr_randomization) {
3091 result = request.put_u32(NAN_ATTRIBUTE_RANDOMIZATION_INTERVAL,
3092 mParams->disc_mac_addr_rand_interval_sec);
3093 if (result < 0) {
3094 ALOGE("%s: Failing to fill rand mac interval, result = %d\n", __func__, result);
3095 return result;
3096 }
3097 }
3098
3099 if (mParams->config_discovery_beacon_int) {
3100 result = request.put_u32(NAN_ATTRIBUTE_DISCOVERY_BEACON_INTERVAL,
3101 mParams->discovery_beacon_interval);
3102 if (result < 0) {
3103 ALOGE("%s: Failing to fill disc beacon interval, result = %d\n", __func__, result);
3104 return result;
3105 }
3106 }
3107
3108 if (mParams->config_nss) {
3109 result = request.put_u32(NAN_ATTRIBUTE_NSS, mParams->nss);
3110 if (result < 0) {
3111 ALOGE("%s: Failing to fill nss, result = %d\n", __func__, result);
3112 return result;
3113 }
3114 }
3115
3116 if (mParams->config_enable_ranging) {
3117 result = request.put_u32(NAN_ATTRIBUTE_ENABLE_RANGING, mParams->enable_ranging);
3118 if (result < 0) {
3119 ALOGE("%s: Failing to fill enable ranging value, result = %d\n", __func__, result);
3120 return result;
3121 }
3122 }
3123
3124 if (mParams->config_dw_early_termination) {
3125 result = request.put_u32(NAN_ATTRIBUTE_DW_EARLY_TERM, mParams->enable_dw_termination);
3126 if (result < 0) {
3127 ALOGE("%s: Failing to fill enable dw termination value, result = %d\n",
3128 __func__, result);
3129 return result;
3130 }
3131 }
3132 request.attr_end(data);
3133 NAN_DBG_EXIT();
3134 return WIFI_SUCCESS;
3135 }
3136
start()3137 int start()
3138 {
3139 NAN_DBG_ENTER();
3140
3141 WifiRequest request(familyId(), ifaceId());
3142 int result = createRequest(request);
3143 if (result != WIFI_SUCCESS) {
3144 ALOGE("%s: Failed to create setup request; result = %d", __func__, result);
3145 return result;
3146 }
3147
3148 result = requestResponse(request);
3149 if (result != WIFI_SUCCESS) {
3150 ALOGE("%s: Failed to configure setup; result = %d", __func__, result);
3151 return result;
3152 }
3153
3154 request.destroy();
3155 NAN_DBG_EXIT();
3156 return WIFI_SUCCESS;
3157 }
3158
cancel()3159 int cancel()
3160 {
3161 NAN_DBG_ENTER();
3162
3163 WifiRequest request(familyId(), ifaceId());
3164 int result = createRequest(request);
3165 if (result != WIFI_SUCCESS) {
3166 ALOGE("%s: Failed to create setup request; result = %d", __func__, result);
3167 return result;
3168 }
3169
3170 result = requestResponse(request);
3171 if (result != WIFI_SUCCESS) {
3172 ALOGE("%s: Failed to configure setup; result = %d", __func__, result);
3173 return result;
3174 }
3175
3176 request.destroy();
3177 NAN_DBG_EXIT();
3178 return WIFI_SUCCESS;
3179 }
3180
handleResponse(WifiEvent & reply)3181 int handleResponse(WifiEvent& reply) {
3182 nan_hal_resp_t *rsp_vndr_data = NULL;
3183
3184 if (reply.get_cmd() != NL80211_CMD_VENDOR || reply.get_vendor_data() == NULL) {
3185 ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
3186 return NL_SKIP;
3187 }
3188
3189 rsp_vndr_data = (nan_hal_resp_t *)reply.get_vendor_data();
3190 ALOGI("NanMacControl::handleResponse\n");
3191 if (mType == NAN_VERSION_INFO) {
3192 mVersion = *((u32*)reply.get_vendor_data());
3193 ALOGI("Response not required for version cmd %d\n", mVersion);
3194 return NL_SKIP;
3195 }
3196 if (rsp_vndr_data->subcmd == NAN_SUBCMD_CONFIG) {
3197 NanResponseMsg rsp_data;
3198 memset(&rsp_data, 0, sizeof(NanResponseMsg));
3199 rsp_data.response_type = get_response_type((WIFI_SUB_COMMAND)rsp_vndr_data->subcmd);
3200 rsp_data.status = nan_map_response_status(rsp_vndr_data->status);
3201
3202 ALOGI("NanMacControl:Received response for cmd [%s], TxID %d ret %d\n",
3203 NanRspToString(rsp_data.response_type), id(), rsp_data.status);
3204
3205 GET_NAN_HANDLE(info)->mHandlers.NotifyResponse(id(), &rsp_data);
3206 }
3207 if (rsp_vndr_data->subcmd == NAN_SUBCMD_ENABLE) {
3208 NanResponseMsg rsp_data;
3209 memset(&rsp_data, 0, sizeof(NanResponseMsg));
3210 rsp_data.response_type = get_response_type((WIFI_SUB_COMMAND)rsp_vndr_data->subcmd);
3211 rsp_data.status = nan_map_response_status(rsp_vndr_data->status);
3212
3213 ALOGI("NanMacControl:Received response for cmd [%s], TxID %d ret %d\n",
3214 NanRspToString(rsp_data.response_type), mId, rsp_data.status);
3215
3216 if( rsp_data.status != NAN_STATUS_SUCCESS) {
3217 GET_NAN_HANDLE(info)->mHandlers.NotifyResponse(mId, &rsp_data);
3218 }
3219 }
3220 return NL_SKIP;
3221 }
3222
handleAsyncResponse(nan_hal_resp_t * rsp_vndr_data)3223 int handleAsyncResponse(nan_hal_resp_t *rsp_vndr_data) {
3224 NanResponseMsg rsp_data;
3225 ALOGI("NanMacControl::handleAsyncResponse\n");
3226 /* Enable response will be provided to framework in event path */
3227 if (rsp_vndr_data->subcmd == NAN_SUBCMD_ENABLE) {
3228 return NL_SKIP;
3229 }
3230 memset(&rsp_data, 0, sizeof(NanResponseMsg));
3231 rsp_data.response_type = get_response_type((WIFI_SUB_COMMAND)rsp_vndr_data->subcmd);
3232 rsp_data.status = nan_map_response_status(rsp_vndr_data->status);
3233 ALOGE("Mapped hal status = %d\n", rsp_data.status);
3234
3235 /* populate error string if not coming from DHD */
3236 if (rsp_vndr_data->nan_reason[0] == '\0') {
3237 memcpy(rsp_data.nan_error, NanStatusToString(rsp_data.status),
3238 strlen(NanStatusToString(rsp_data.status)));
3239 rsp_data.nan_error[strlen(NanStatusToString(rsp_data.status))] = '\0';
3240 }
3241 rsp_data.nan_error[NAN_ERROR_STR_LEN - 1] = '\0';
3242 ALOGI("\n Received nan_error string %s\n", (u8*)rsp_data.nan_error);
3243 ALOGI("Retrieved ID = %d\n", mId);
3244
3245 if ((rsp_vndr_data->subcmd == NAN_SUBCMD_DISABLE) &&
3246 (mId != NAN_MAC_INVALID_TRANSID)) {
3247 GET_NAN_HANDLE(info)->mHandlers.NotifyResponse(mId, &rsp_data);
3248 mId = NAN_MAC_INVALID_TRANSID;
3249 }
3250 return NL_SKIP;
3251 }
3252
handleEvent(WifiEvent & event)3253 int handleEvent(WifiEvent& event) {
3254 u16 inst_id;
3255 u32 ndp_instance_id = 0;
3256 int event_id = event.get_vendor_subcmd();
3257 nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
3258 int len = event.get_vendor_data_len();
3259 u16 attr_type;
3260 nan_hal_resp_t *rsp_vndr_data = NULL;
3261
3262 ALOGI("%s: Received NanMacControl event = %d (len=%d)\n",
3263 __func__, event.get_cmd(), len);
3264 if (!vendor_data || len == 0) {
3265 ALOGE("No event data found");
3266 return NL_SKIP;
3267 }
3268
3269 for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
3270 attr_type = it.get_type();
3271
3272 if (it.get_type() == NAN_ATTRIBUTE_HANDLE) {
3273 inst_id = it.get_u8();
3274 } else if (it.get_type() == NAN_ATTRIBUTE_NDP_ID) {
3275 ndp_instance_id = it.get_u32();
3276 ALOGI("handleEvent: ndp_instance_id = [%d]\n", ndp_instance_id);
3277 } else if (attr_type == NAN_ATTRIBUTE_CMD_RESP_DATA) {
3278 ALOGI("sizeof cmd response data: %ld, it.get_len() = %d\n",
3279 sizeof(nan_hal_resp_t), it.get_len());
3280 if (it.get_len() == sizeof(nan_hal_resp_t)) {
3281 rsp_vndr_data = (nan_hal_resp_t*)it.get_data();
3282 } else {
3283 ALOGE("Wrong cmd response data received\n");
3284 return NL_SKIP;
3285 }
3286 }
3287 }
3288
3289 ALOGI("Received vendor sub cmd %d\n", event_id);
3290 if (is_de_event(event_id)) {
3291
3292 NanDiscEnginePrimitive *de_prim =
3293 (NanDiscEnginePrimitive *)(info.nan_disc_control);
3294 if (de_prim != NULL) {
3295 de_prim->handleEvent(event);
3296 } else {
3297 ALOGE("%s: de_primitive is no more available\n", __func__);
3298 }
3299 return NL_SKIP;
3300
3301 } else if (is_dp_event(event_id)) {
3302
3303 NanDataPathPrimitive *dp_prim =
3304 (NanDataPathPrimitive *)(info.nan_dp_control);
3305 ALOGI("ndp_instance_id = [%d]\n", ndp_instance_id);
3306 if (dp_prim != NULL) {
3307 dp_prim->handleEvent(event);
3308 } else {
3309 ALOGE("%s: dp_primitive is no more available\n", __func__);
3310 }
3311 return NL_SKIP;
3312 } else {
3313 if (is_cmd_response(event_id)) {
3314 ALOGE("Handling cmd response asynchronously\n");
3315 if (rsp_vndr_data != NULL) {
3316 handleAsyncResponse(rsp_vndr_data);
3317 } else {
3318 ALOGE("Wrong response data, rsp_vndr_data is NULL\n");
3319 return NL_SKIP;
3320 }
3321 }
3322 }
3323
3324 switch(event_id) {
3325 case NAN_EVENT_DE_EVENT:
3326 NanDiscEngEventInd de_event;
3327 memset(&de_event, 0, sizeof(de_event));
3328
3329 for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
3330 attr_type = it.get_type();
3331
3332 if (attr_type == NAN_ATTRIBUTE_CLUSTER_ID) {
3333 memcpy(&de_event.data.cluster.addr, it.get_data(), NAN_MAC_ADDR_LEN);
3334 ALOGI("cluster id = " MACSTR "\n", MAC2STR(de_event.data.cluster.addr));
3335 } else if (attr_type == NAN_ATTRIBUTE_ENABLE_STATUS) {
3336 ALOGI("nan enable status = %u\n", it.get_u16());
3337 } else if (attr_type == NAN_ATTRIBUTE_JOIN_STATUS) {
3338 ALOGI("nan joined status = %u\n", it.get_u16());
3339 } else if (attr_type == NAN_ATTRIBUTE_DE_EVENT_TYPE) {
3340 u8 de_type = it.get_u8();
3341 ALOGI("nan de event type = %u\n", de_type);
3342 if (de_type == NAN_EVENT_IFACE) {
3343 de_event.event_type = NAN_EVENT_ID_DISC_MAC_ADDR;
3344 ALOGI("received NAN_EVENT_ID_DISC_MAC_ADDR event\n");
3345 } else if (de_type == NAN_EVENT_START) {
3346 de_event.event_type = NAN_EVENT_ID_STARTED_CLUSTER;
3347 ALOGI("received NAN cluster started event\n");
3348 } else if (de_type == NAN_EVENT_JOIN) {
3349 /* To be deprecated */
3350 de_event.event_type = NAN_EVENT_ID_JOINED_CLUSTER;
3351 ALOGI("received join event\n");
3352 } else if (de_type == NAN_EVENT_ROLE_CHANGE) {
3353 ALOGI("received device role change event\n");
3354 } else if (de_type == NAN_EVENT_MERGE) {
3355 ALOGI("received merge event\n");
3356 } else {
3357 ALOGI("received unknown DE event, [%d]\n", de_type);
3358 }
3359 } else if (attr_type == NAN_ATTRIBUTE_MAC_ADDR) {
3360 memcpy(&de_event.data.mac_addr.addr, it.get_data(), NAN_MAC_ADDR_LEN);
3361 memcpy(mNmi, it.get_data(), NAN_MAC_ADDR_LEN);
3362 ALOGI("Primary discovery mac address = " MACSTR "\n",
3363 MAC2STR(mNmi));
3364 }
3365 }
3366 GET_NAN_HANDLE(info)->mHandlers.EventDiscEngEvent(&de_event);
3367 /* XXX: WAR for sending intf addr to generate Identity
3368 * change callback in framework
3369 * Also WAR for enable response
3370 */
3371 if (de_event.event_type == NAN_EVENT_ID_STARTED_CLUSTER) {
3372 NanResponseMsg rsp_data;
3373 memcpy(&de_event.data.mac_addr.addr, mNmi, NAN_MAC_ADDR_LEN);
3374 de_event.event_type = NAN_EVENT_ID_DISC_MAC_ADDR;
3375 GET_NAN_HANDLE(info)->mHandlers.EventDiscEngEvent(&de_event);
3376 rsp_data.response_type = NAN_RESPONSE_ENABLED;
3377 rsp_data.status = NAN_STATUS_SUCCESS;
3378 memcpy(rsp_data.nan_error, NanStatusToString(rsp_data.status),
3379 strlen(NanStatusToString(rsp_data.status)));
3380 GET_NAN_HANDLE(info)->mHandlers.NotifyResponse(mId, &rsp_data);
3381 /* clean up mId to distinguish duplciated disable command */
3382 mId = NAN_MAC_INVALID_TRANSID;
3383 }
3384 break;
3385
3386 case NAN_EVENT_DISABLED:
3387 ALOGI("Received NAN_EVENT_DISABLED\n");
3388 NanDisabledInd disabled_ind;
3389 memset(&disabled_ind, 0, sizeof(NanDisabledInd));
3390 for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
3391 attr_type = it.get_type();
3392 if (attr_type == NAN_ATTRIBUTE_STATUS) {
3393 disabled_ind.reason = (NanStatusType)it.get_u8();
3394 ALOGI("Nan Disable:status %u", disabled_ind.reason);
3395 } else if (attr_type == NAN_ATTRIBUTE_REASON) {
3396 u8 len = min(it.get_len(), sizeof(disabled_ind.nan_reason));
3397 memcpy(disabled_ind.nan_reason, it.get_data(), len);
3398 ALOGI("Disabled nan reason: %s, len = %d\n",
3399 disabled_ind.nan_reason, len);
3400 }
3401 }
3402
3403 GET_NAN_HANDLE(info)->mHandlers.EventDisabled(&disabled_ind);
3404 /* unregister Nan vendor events */
3405 unRegisterNanVendorEvents();
3406 break;
3407
3408 case NAN_EVENT_SDF:
3409 ALOGI("Received NAN_EVENT_SDF:\n");
3410 NanBeaconSdfPayloadInd sdfInd;
3411 memset(&sdfInd, 0, sizeof(sdfInd));
3412
3413 for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
3414 attr_type = it.get_type();
3415
3416 if (attr_type == NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO_LEN) {
3417 sdfInd.data.frame_len = it.get_u16();
3418 if (sdfInd.data.frame_len > NAN_MAX_FRAME_DATA_LEN) {
3419 sdfInd.data.frame_len = NAN_MAX_FRAME_DATA_LEN;
3420 }
3421 ALOGI("Received NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO_LEN: 0x%x(%d)\n",
3422 sdfInd.data.frame_len, sdfInd.data.frame_len);
3423
3424 } else if (attr_type == NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO) {
3425 ALOGI("Received NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO\n");
3426 memcpy(&sdfInd.data.frame_data, it.get_data(), sdfInd.data.frame_len);
3427 prhex("sdfInd.data.frame_data: ", (u8*)sdfInd.data.frame_data,
3428 sdfInd.data.frame_len);
3429 }
3430 }
3431 GET_NAN_HANDLE(info)->mHandlers.EventBeaconSdfPayload(&sdfInd);
3432 break;
3433
3434 case NAN_EVENT_TCA:
3435 ALOGI("Received NAN_EVENT_TCA\n");
3436 break;
3437
3438 case NAN_EVENT_UNKNOWN:
3439 ALOGI("Received NAN_EVENT_UNKNOWN\n");
3440 break;
3441 } // end-of-switch
3442
3443 return NL_SKIP;
3444 }
unRegisterNanVendorEvents()3445 void unRegisterNanVendorEvents()
3446 {
3447 int i = 0;
3448 for (i = NAN_EVENT_ENABLED; i <= NAN_EVENT_DATA_END; i++) {
3449 unregisterVendorHandler(GOOGLE_OUI, i);
3450 }
3451 unregisterVendorHandler(GOOGLE_OUI, NAN_ASYNC_RESPONSE_DISABLED);
3452 unregisterVendorHandler(GOOGLE_OUI, NAN_EVENT_MATCH_EXPIRY);
3453 }
registerNanVendorEvents()3454 void registerNanVendorEvents()
3455 {
3456 int i = 0;
3457 for (i = NAN_EVENT_ENABLED; i <= NAN_EVENT_DATA_END; i++) {
3458 registerVendorHandler(GOOGLE_OUI, i);
3459 }
3460 registerVendorHandler(GOOGLE_OUI, NAN_ASYNC_RESPONSE_DISABLED);
3461 registerVendorHandler(GOOGLE_OUI, NAN_EVENT_MATCH_EXPIRY);
3462 }
3463 };
3464
3465 /* pretty hex print a contiguous buffer */
prhex(const char * msg,u8 * buf,u32 nbytes)3466 static void prhex(const char *msg, u8 *buf, u32 nbytes)
3467 {
3468 char line[128];
3469 char *p;
3470 int len = sizeof(line);
3471 int nchar;
3472 u32 i;
3473
3474 if (msg && (msg[0] != '\0')) {
3475 printf("%s:\n", msg);
3476 }
3477
3478 p = line;
3479 for (i = 0; i < nbytes; i++) {
3480 if (i % 16 == 0) {
3481 nchar = snprintf(p, len, " %04d: ", i); /* line prefix */
3482 p += nchar;
3483 len -= nchar;
3484 }
3485
3486 if (len > 0) {
3487 nchar = snprintf(p, len, "%02x ", buf[i]);
3488 p += nchar;
3489 len -= nchar;
3490 }
3491
3492 if (i % 16 == 15) {
3493 ALOGE("%s\n", line); /* flush line */
3494 p = line;
3495 len = sizeof(line);
3496 }
3497 }
3498
3499 /* flush last partial line */
3500 if (p != line) {
3501 ALOGE("%s\n", line);
3502 }
3503 }
3504
3505
NanRspToString(int cmd_resp)3506 static const char *NanRspToString(int cmd_resp)
3507 {
3508 switch (cmd_resp) {
3509 C2S(NAN_RESPONSE_ENABLED)
3510 C2S(NAN_RESPONSE_DISABLED)
3511 C2S(NAN_RESPONSE_PUBLISH)
3512 C2S(NAN_RESPONSE_SUBSCRIBE)
3513 C2S(NAN_RESPONSE_PUBLISH_CANCEL)
3514 C2S(NAN_RESPONSE_SUBSCRIBE_CANCEL)
3515 C2S(NAN_RESPONSE_TRANSMIT_FOLLOWUP)
3516 C2S(NAN_RESPONSE_CONFIG)
3517 C2S(NAN_RESPONSE_TCA)
3518 C2S(NAN_RESPONSE_STATS)
3519 C2S(NAN_DP_INTERFACE_CREATE)
3520 C2S(NAN_DP_INTERFACE_DELETE)
3521 C2S(NAN_DP_INITIATOR_RESPONSE)
3522 C2S(NAN_DP_RESPONDER_RESPONSE)
3523 C2S(NAN_DP_END)
3524 C2S(NAN_GET_CAPABILITIES)
3525
3526 default:
3527 return "UNKNOWN_NAN_CMD_RESPONSE";
3528 }
3529 }
3530
NanCmdToString(int cmd)3531 static const char *NanCmdToString(int cmd)
3532 {
3533 switch (cmd) {
3534 C2S(NAN_REQUEST_ENABLE)
3535 C2S(NAN_REQUEST_DISABLE)
3536 C2S(NAN_REQUEST_PUBLISH)
3537 C2S(NAN_REQUEST_PUBLISH_CANCEL)
3538 C2S(NAN_REQUEST_TRANSMIT_FOLLOWUP)
3539 C2S(NAN_REQUEST_SUBSCRIBE)
3540 C2S(NAN_REQUEST_SUBSCRIBE_CANCEL)
3541 C2S(NAN_REQUEST_STATS)
3542 C2S(NAN_REQUEST_CONFIG)
3543 C2S(NAN_REQUEST_TCA)
3544 C2S(NAN_REQUEST_EVENT_CHECK)
3545 C2S(NAN_REQUEST_GET_CAPABILTIES)
3546 C2S(NAN_DATA_PATH_IFACE_CREATE)
3547 C2S(NAN_DATA_PATH_IFACE_DELETE)
3548 C2S(NAN_DATA_PATH_INIT_REQUEST)
3549 C2S(NAN_DATA_PATH_IND_RESPONSE)
3550 C2S(NAN_DATA_PATH_END)
3551 C2S(NAN_DATA_PATH_IFACE_UP)
3552 C2S(NAN_DATA_PATH_SEC_INFO)
3553 C2S(NAN_VERSION_INFO)
3554 default:
3555 return "UNKNOWN_NAN_CMD";
3556 }
3557 }
3558
NanAttrToString(u16 cmd)3559 static const char *NanAttrToString(u16 cmd)
3560 {
3561 switch (cmd) {
3562 C2S(NAN_ATTRIBUTE_HEADER)
3563 C2S(NAN_ATTRIBUTE_HANDLE)
3564 C2S(NAN_ATTRIBUTE_TRANSAC_ID)
3565 C2S(NAN_ATTRIBUTE_5G_SUPPORT)
3566 C2S(NAN_ATTRIBUTE_CLUSTER_LOW)
3567 C2S(NAN_ATTRIBUTE_CLUSTER_HIGH)
3568 C2S(NAN_ATTRIBUTE_SID_BEACON)
3569 C2S(NAN_ATTRIBUTE_SYNC_DISC_5G_BEACON)
3570 C2S(NAN_ATTRIBUTE_RSSI_CLOSE)
3571 C2S(NAN_ATTRIBUTE_RSSI_MIDDLE)
3572 C2S(NAN_ATTRIBUTE_RSSI_PROXIMITY)
3573 C2S(NAN_ATTRIBUTE_HOP_COUNT_LIMIT)
3574 C2S(NAN_ATTRIBUTE_RANDOM_FACTOR)
3575 C2S(NAN_ATTRIBUTE_MASTER_PREF)
3576 C2S(NAN_ATTRIBUTE_PERIODIC_SCAN_INTERVAL)
3577 C2S(NAN_ATTRIBUTE_PUBLISH_ID)
3578 C2S(NAN_ATTRIBUTE_TTL)
3579 C2S(NAN_ATTRIBUTE_PERIOD)
3580 C2S(NAN_ATTRIBUTE_REPLIED_EVENT_FLAG)
3581 C2S(NAN_ATTRIBUTE_PUBLISH_TYPE)
3582 C2S(NAN_ATTRIBUTE_TX_TYPE)
3583 C2S(NAN_ATTRIBUTE_PUBLISH_COUNT)
3584 C2S(NAN_ATTRIBUTE_SERVICE_NAME_LEN)
3585 C2S(NAN_ATTRIBUTE_SERVICE_NAME)
3586 C2S(NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO_LEN)
3587 C2S(NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO)
3588 C2S(NAN_ATTRIBUTE_RX_MATCH_FILTER_LEN)
3589 C2S(NAN_ATTRIBUTE_RX_MATCH_FILTER)
3590 C2S(NAN_ATTRIBUTE_TX_MATCH_FILTER_LEN)
3591 C2S(NAN_ATTRIBUTE_TX_MATCH_FILTER)
3592 C2S(NAN_ATTRIBUTE_SUBSCRIBE_ID)
3593 C2S(NAN_ATTRIBUTE_SUBSCRIBE_TYPE)
3594 C2S(NAN_ATTRIBUTE_SERVICERESPONSEFILTER)
3595 C2S(NAN_ATTRIBUTE_SERVICERESPONSEINCLUDE)
3596 C2S(NAN_ATTRIBUTE_USESERVICERESPONSEFILTER)
3597 C2S(NAN_ATTRIBUTE_SSIREQUIREDFORMATCHINDICATION)
3598 C2S(NAN_ATTRIBUTE_SUBSCRIBE_MATCH)
3599 C2S(NAN_ATTRIBUTE_SUBSCRIBE_COUNT)
3600 C2S(NAN_ATTRIBUTE_MAC_ADDR)
3601 C2S(NAN_ATTRIBUTE_MAC_ADDR_LIST)
3602 C2S(NAN_ATTRIBUTE_MAC_ADDR_LIST_NUM_ENTRIES)
3603 C2S(NAN_ATTRIBUTE_PUBLISH_MATCH)
3604 C2S(NAN_ATTRIBUTE_ENABLE_STATUS)
3605 C2S(NAN_ATTRIBUTE_JOIN_STATUS)
3606 C2S(NAN_ATTRIBUTE_ROLE)
3607 C2S(NAN_ATTRIBUTE_MASTER_RANK)
3608 C2S(NAN_ATTRIBUTE_ANCHOR_MASTER_RANK)
3609 C2S(NAN_ATTRIBUTE_CNT_PEND_TXFRM)
3610 C2S(NAN_ATTRIBUTE_CNT_BCN_TX)
3611 C2S(NAN_ATTRIBUTE_CNT_BCN_RX)
3612 C2S(NAN_ATTRIBUTE_CNT_SVC_DISC_TX)
3613 C2S(NAN_ATTRIBUTE_CNT_SVC_DISC_RX)
3614 C2S(NAN_ATTRIBUTE_AMBTT)
3615 C2S(NAN_ATTRIBUTE_CLUSTER_ID)
3616 C2S(NAN_ATTRIBUTE_INST_ID)
3617 C2S(NAN_ATTRIBUTE_OUI)
3618 C2S(NAN_ATTRIBUTE_STATUS)
3619 C2S(NAN_ATTRIBUTE_DE_EVENT_TYPE)
3620 C2S(NAN_ATTRIBUTE_MERGE)
3621 C2S(NAN_ATTRIBUTE_IFACE)
3622 C2S(NAN_ATTRIBUTE_CHANNEL)
3623 C2S(NAN_ATTRIBUTE_PEER_ID)
3624 C2S(NAN_ATTRIBUTE_NDP_ID)
3625 C2S(NAN_ATTRIBUTE_SECURITY)
3626 C2S(NAN_ATTRIBUTE_QOS)
3627 C2S(NAN_ATTRIBUTE_RSP_CODE)
3628 C2S(NAN_ATTRIBUTE_INST_COUNT)
3629 C2S(NAN_ATTRIBUTE_PEER_DISC_MAC_ADDR)
3630 C2S(NAN_ATTRIBUTE_PEER_NDI_MAC_ADDR)
3631 C2S(NAN_ATTRIBUTE_IF_ADDR)
3632 C2S(NAN_ATTRIBUTE_WARMUP_TIME)
3633 C2S(NAN_ATTRIBUTE_RANGING_RESULT)
3634 C2S(NAN_ATTRIBUTE_RANGING_INDICATION)
3635 C2S(NAN_ATTRIBUTE_SDEA_SERVICE_SPECIFIC_INFO_LEN)
3636 C2S(NAN_ATTRIBUTE_SDEA_SERVICE_SPECIFIC_INFO)
3637 C2S(NAN_ATTRIBUTE_RANDOMIZATION_INTERVAL)
3638 C2S(NAN_ATTRIBUTE_ENABLE_MERGE)
3639
3640 default:
3641 return "NAN_ATTRIBUTE_UNKNOWN";
3642 }
3643 }
3644
get_response_type(WIFI_SUB_COMMAND nan_subcmd)3645 NanResponseType get_response_type(WIFI_SUB_COMMAND nan_subcmd)
3646 {
3647 NanResponseType response_type;
3648
3649 switch(nan_subcmd) {
3650 case NAN_SUBCMD_ENABLE:
3651 response_type = NAN_RESPONSE_ENABLED;
3652 break;
3653 case NAN_SUBCMD_DISABLE:
3654 response_type = NAN_RESPONSE_DISABLED;
3655 break;
3656 case NAN_SUBCMD_PUBLISH:
3657 response_type = NAN_RESPONSE_PUBLISH;
3658 break;
3659 case NAN_SUBCMD_SUBSCRIBE:
3660 response_type = NAN_RESPONSE_SUBSCRIBE;
3661 break;
3662 case NAN_SUBCMD_PUBLISH_CANCEL:
3663 response_type = NAN_RESPONSE_PUBLISH_CANCEL;
3664 break;
3665 case NAN_SUBCMD_SUBSCRIBE_CANCEL:
3666 response_type = NAN_RESPONSE_SUBSCRIBE_CANCEL;
3667 break;
3668 case NAN_SUBCMD_TRANSMIT_FOLLOWUP:
3669 response_type = NAN_RESPONSE_TRANSMIT_FOLLOWUP;
3670 break;
3671 case NAN_SUBCMD_CONFIG:
3672 response_type = NAN_RESPONSE_CONFIG;
3673 break;
3674 case NAN_SUBCMD_TCA:
3675 response_type = NAN_RESPONSE_TCA;
3676 break;
3677 case NAN_SUBCMD_STATS:
3678 response_type = NAN_RESPONSE_STATS;
3679 break;
3680 case NAN_SUBCMD_DATA_PATH_IFACE_CREATE:
3681 response_type = NAN_DP_INTERFACE_CREATE;
3682 break;
3683 case NAN_SUBCMD_DATA_PATH_IFACE_DELETE:
3684 response_type = NAN_DP_INTERFACE_DELETE;
3685 break;
3686 case NAN_SUBCMD_DATA_PATH_REQUEST:
3687 response_type = NAN_DP_INITIATOR_RESPONSE;
3688 break;
3689 case NAN_SUBCMD_DATA_PATH_RESPONSE:
3690 response_type = NAN_DP_RESPONDER_RESPONSE;
3691 break;
3692 case NAN_SUBCMD_DATA_PATH_END:
3693 response_type = NAN_DP_END;
3694 break;
3695 case NAN_SUBCMD_GET_CAPABILITIES:
3696 response_type = NAN_GET_CAPABILITIES;
3697 break;
3698 default:
3699 /* unknown response for a command */
3700 response_type = NAN_RESPONSE_ERROR;
3701 break;
3702 }
3703
3704 return response_type;
3705 }
3706
get_svc_hash(unsigned char * svc_name,u16 svc_name_len,u8 * svc_hash,u16 svc_hash_len)3707 static int get_svc_hash(unsigned char *svc_name,
3708 u16 svc_name_len, u8 *svc_hash, u16 svc_hash_len)
3709 {
3710 SHA256_CTX sha_ctx;
3711 u8 sha_hash[SHA256_DIGEST_LENGTH];
3712 unsigned char *p;
3713 int len = svc_name_len;
3714
3715 if (!svc_name || !svc_hash) {
3716 ALOGE("Bad arguments!!\n");
3717 return WIFI_ERROR_UNKNOWN;
3718 }
3719
3720 if (svc_hash_len < NAN_SVC_HASH_SIZE) {
3721 ALOGE("Bad len!!\n");
3722 return WIFI_ERROR_UNKNOWN;
3723 }
3724 for (p = svc_name; *p; p++)
3725 {
3726 *p = tolower((int)*p);
3727 }
3728 SHA256_Init(&sha_ctx);
3729 SHA256_Update(&sha_ctx, svc_name, len);
3730 SHA256_Final(sha_hash, &sha_ctx);
3731
3732 memcpy(svc_hash, sha_hash, NAN_SVC_HASH_SIZE);
3733 ALOGI("svc_name: %s\n", svc_name);
3734 prhex("svc_hash:", svc_hash, NAN_SVC_HASH_SIZE);
3735
3736 return WIFI_SUCCESS;
3737 }
3738
3739 #ifdef CONFIG_BRCM
dump_NanEnableRequest(NanEnableRequest * msg)3740 static int dump_NanEnableRequest(NanEnableRequest* msg)
3741 {
3742 ALOGI("%s: Dump NanEnableRequest msg:\n", __func__);
3743
3744 if (msg == NULL) {
3745 ALOGE("Invalid msg\n");
3746 return WIFI_ERROR_UNKNOWN;
3747 }
3748
3749 ALOGI("master_pref=%u\n", msg->master_pref);
3750 ALOGI("cluster_low=%u\n", msg->cluster_low);
3751 ALOGI("cluster_high=%u\n", msg->cluster_high);
3752 ALOGI("config_support_5g=%u\n", msg->config_support_5g);
3753 ALOGI("support_5g_val=%u\n", msg->support_5g_val);
3754 ALOGI("config_sid_beacon=%u\n", msg->config_sid_beacon);
3755 ALOGI("sid beacon=%u\n", msg->sid_beacon_val);
3756 ALOGI("config_sub_sid_beacon=%u\n", msg->config_subscribe_sid_beacon);
3757 ALOGI("sub sid beacon=%u\n", msg->subscribe_sid_beacon_val);
3758 ALOGI("config_2dot4g_rssi_close=%u\n", msg->config_2dot4g_rssi_close);
3759 ALOGI("rssi_close_2dot4g_val=%u\n", msg->rssi_close_2dot4g_val);
3760 ALOGI("config_2dot4g_rssi_middle=%u\n", msg->config_2dot4g_rssi_middle);
3761 ALOGI("rssi_middle_2dot4g_val=%u\n", msg->rssi_middle_2dot4g_val);
3762 ALOGI("config_2dot4g_rssi_proximity=%u\n", msg->config_2dot4g_rssi_proximity);
3763 ALOGI("rssi_proximity_2dot4g_val=%u\n", msg->rssi_proximity_2dot4g_val);
3764 ALOGI("config_hop_count_limit=%u\n", msg->config_hop_count_limit);
3765 ALOGI("hop_count_limit_val=%u\n", msg->hop_count_limit_val);
3766 ALOGI("config_2dot4g_support=%u\n", msg->config_2dot4g_support);
3767 ALOGI("support_2dot4g_val=%u\n", msg->support_2dot4g_val);
3768 ALOGI("config_2dot4g_beacons=%u\n", msg->config_2dot4g_beacons);
3769 ALOGI("beacon_2dot4g_val=%u\n", msg->beacon_2dot4g_val);
3770 ALOGI("config_2dot4g_sdf=%u\n", msg->config_2dot4g_sdf);
3771 ALOGI("sdf_2dot4g_val=%u\n", msg->sdf_2dot4g_val);
3772 ALOGI("config_5g_beacons=%u\n", msg->config_5g_beacons);
3773 ALOGI("beacon_5g_val=%u\n", msg->beacon_5g_val);
3774 ALOGI("config_5g_sdf=%u\n", msg->config_5g_sdf);
3775 ALOGI("config_5g_rssi_close=%u\n", msg->config_5g_rssi_close);
3776 ALOGI("rssi_close_5g_val=%u\n", msg->rssi_close_5g_val);
3777 ALOGI("config_5g_rssi_middle=%u\n", msg->config_5g_rssi_middle);
3778 ALOGI("rssi_middle_5g_val=%u\n", msg->rssi_middle_5g_val);
3779 ALOGI("config_5g_rssi_close_proximity=%u\n", msg->config_5g_rssi_close_proximity);
3780 ALOGI("rssi_close_proximity_5g_val=%u\n", msg->rssi_close_proximity_5g_val);
3781 ALOGI("config_rssi_window_size=%u\n", msg->config_rssi_window_size);
3782 ALOGI("rssi_window_size_val=%u\n", msg->rssi_window_size_val);
3783 ALOGI("config_oui=%u\n", msg->config_oui);
3784 ALOGI("oui_val=%u\n", msg->oui_val);
3785 ALOGI("config_intf_addr=%u\n", msg->config_intf_addr);
3786 ALOGI("intf_addr_val=" MACSTR "\n", MAC2STR(msg->intf_addr_val));
3787 ALOGI("config_cluster_attribute_val=%u\n", msg->config_cluster_attribute_val);
3788 ALOGI("config_scan_params=%u\n", msg->config_scan_params);
3789 if (msg->config_scan_params) {
3790 ALOGI("dwell_time=%u\n", msg->scan_params_val.dwell_time[0]);
3791 ALOGI("scan_period=%u\n", msg->scan_params_val.scan_period[0]);
3792 }
3793 ALOGI("config_random_factor_force=%u\n", msg->config_random_factor_force);
3794 ALOGI("random_factor_force_val=%u\n", msg->random_factor_force_val);
3795 ALOGI("config_hop_count_force=%u\n", msg->config_hop_count_force);
3796 ALOGI("config_24g_channel=%u\n", msg->config_24g_channel);
3797 ALOGI("channel_24g_val=%u\n", msg->channel_24g_val);
3798 ALOGI("config_5g_channel=%u\n", msg->config_5g_channel);
3799 ALOGI("channel_5g_val=%u\n", msg->channel_5g_val);
3800 ALOGI("config_dw.config_2dot4g_dw_band=%u\n", msg->config_dw.config_2dot4g_dw_band);
3801 if (msg->config_dw.config_2dot4g_dw_band) {
3802 ALOGI("dw_2dot4g_interval_val=%u\n", msg->config_dw.dw_2dot4g_interval_val);
3803 }
3804 ALOGI("config_dw.config_5g_dw_band=%u\n", msg->config_dw.config_5g_dw_band);
3805 if (msg->config_dw.config_5g_dw_band) {
3806 ALOGI("dw_5g_interval_val=%u\n", msg->config_dw.dw_5g_interval_val);
3807 }
3808 ALOGI("discovery_indication_cfg=%u\n", msg->discovery_indication_cfg);
3809 ALOGI("config_ndpe_attr=%u\n", msg->config_ndpe_attr);
3810 if (msg->config_ndpe_attr) {
3811 ALOGI("use_ndpe_attr=%u\n", msg->use_ndpe_attr);
3812 }
3813 ALOGI("config_discovery_beacon_int=%u\n", msg->config_discovery_beacon_int);
3814 if (msg->config_discovery_beacon_int) {
3815 ALOGI("discovery beacon interval =%u\n", msg->discovery_beacon_interval);
3816 }
3817 ALOGI("config_nss=%u\n", msg->config_nss);
3818 if (msg->config_nss) {
3819 ALOGI("nss =%u\n", msg->nss);
3820 }
3821 ALOGI("config_enable_ranging =%u\n", msg->config_enable_ranging);
3822 if (msg->config_enable_ranging) {
3823 ALOGI("enable_ranging =%u\n", msg->enable_ranging);
3824 }
3825 ALOGI("config_dw_early_termination =%u\n", msg->config_dw_early_termination);
3826 if (msg->config_dw_early_termination) {
3827 ALOGI("enable_dw_termination =%u\n", msg->enable_dw_termination);
3828 }
3829 ALOGI("config_disc_mac_addr_randomization=%u\n", msg->config_disc_mac_addr_randomization);
3830 if (msg->config_disc_mac_addr_randomization) {
3831 ALOGI("disc_mac_addr_rand_interval_sec =%u\n", msg->disc_mac_addr_rand_interval_sec);
3832 }
3833
3834 return WIFI_SUCCESS;
3835 }
3836
dump_NanConfigRequestRequest(NanConfigRequest * msg)3837 static int dump_NanConfigRequestRequest(NanConfigRequest* msg)
3838 {
3839 ALOGI("%s: Dump NanConfigRequest msg:\n", __func__);
3840
3841 if (msg == NULL) {
3842 ALOGE("Invalid msg\n");
3843 return WIFI_ERROR_UNKNOWN;
3844 }
3845
3846 ALOGI("master_pref=%u\n", msg->master_pref);
3847 ALOGI("sid beacon=%u\n", msg->sid_beacon);
3848 ALOGI("config_sub_sid_beacon=%u\n", msg->config_subscribe_sid_beacon);
3849 ALOGI("sub sid beacon=%u\n", msg->subscribe_sid_beacon_val);
3850 ALOGI("rssi_proximity=%u\n", msg->rssi_proximity);
3851 ALOGI("rssi_close_proximity_5g_val=%u\n", msg->rssi_close_proximity_5g_val);
3852 ALOGI("rssi_window_size_val=%u\n", msg->rssi_window_size_val);
3853 ALOGI("scan_params_val.dwell_time[0]=%u\n", msg->scan_params_val.dwell_time[0]);
3854 ALOGI("scan_params_val.scan_period[0]=%u\n", msg->scan_params_val.scan_period[0]);
3855 ALOGI("config_scan_params=%u\n", msg->config_scan_params);
3856 ALOGI("random_factor_force_val=%u\n", msg->random_factor_force_val);
3857 ALOGI("hop_count_force_val=%u\n", msg->hop_count_force_val);
3858 ALOGI("fam_val.numchans=%u\n", msg->fam_val.numchans);
3859 ALOGI("fam_val.famchan[0].entry_control=%u\n", msg->fam_val.famchan[0].entry_control);
3860 ALOGI("fam_val.famchan[0].class_val=%u\n", msg->fam_val.famchan[0].class_val);
3861 ALOGI("fam_val.famchan[0].channel=%u\n", msg->fam_val.famchan[0].channel);
3862 ALOGI("fam_val.famchan[0].mapid=%u\n", msg->fam_val.famchan[0].mapid);
3863 ALOGI("fam_val.famchan[0].avail_interval_bitmap=%u\n", msg->fam_val.famchan[0].avail_interval_bitmap);
3864 ALOGI("config_dw.config_2dot4g_dw_band=%u\n", msg->config_dw.config_2dot4g_dw_band);
3865 if (msg->config_dw.config_2dot4g_dw_band) {
3866 ALOGI("dw_2dot4g_interval_val=%u\n", msg->config_dw.dw_2dot4g_interval_val);
3867 }
3868 ALOGI("config_dw.config_5g_dw_band=%u\n", msg->config_dw.config_5g_dw_band);
3869 if (msg->config_dw.config_5g_dw_band) {
3870 ALOGI("dw_5g_interval_val=%u\n", msg->config_dw.dw_5g_interval_val);
3871 }
3872 ALOGI("discovery_indication_cfg=%u\n", msg->discovery_indication_cfg);
3873 ALOGI("config_ndpe_attr=%u\n", msg->config_ndpe_attr);
3874 if (msg->config_ndpe_attr) {
3875 ALOGI("use_ndpe_attr=%u\n", msg->use_ndpe_attr);
3876 }
3877 ALOGI("config_discovery_beacon_int=%u\n", msg->config_discovery_beacon_int);
3878 if (msg->config_discovery_beacon_int) {
3879 ALOGI("discovery beacon interval =%u\n", msg->discovery_beacon_interval);
3880 }
3881 ALOGI("config_nss=%u\n", msg->config_nss);
3882 if (msg->config_nss) {
3883 ALOGI("nss =%u\n", msg->nss);
3884 }
3885 ALOGI("config_enable_ranging =%u\n", msg->config_enable_ranging);
3886 if (msg->config_enable_ranging) {
3887 ALOGI("enable_ranging =%u\n", msg->enable_ranging);
3888 }
3889 ALOGI("config_dw_early_termination =%u\n", msg->config_dw_early_termination);
3890 if (msg->config_dw_early_termination) {
3891 ALOGI("enable_dw_termination =%u\n", msg->enable_dw_termination);
3892 }
3893
3894 ALOGI("config_disc_mac_addr_randomization=%u\n", msg->config_disc_mac_addr_randomization);
3895 if (msg->config_disc_mac_addr_randomization) {
3896 ALOGI("disc_mac_addr_rand_interval_sec =%u\n", msg->disc_mac_addr_rand_interval_sec);
3897 }
3898 return WIFI_SUCCESS;
3899 }
3900
dump_NanPublishRequest(NanPublishRequest * msg)3901 static int dump_NanPublishRequest(NanPublishRequest* msg)
3902 {
3903 ALOGI("%s: Dump NanPublishRequest msg:\n", __func__);
3904 if (msg == NULL) {
3905 ALOGE("Invalid msg\n");
3906 return WIFI_ERROR_UNKNOWN;
3907 }
3908 ALOGI("publish_id=%u\n", msg->publish_id);
3909 ALOGI("ttl=%u\n", msg->ttl);
3910 ALOGI("period=%u\n", msg->period);
3911 ALOGI("publish_type=%u\n", msg->publish_type);
3912 ALOGI("tx_type=%u\n", msg->tx_type);
3913 ALOGI("publish_count=%u\n", msg->publish_count);
3914 ALOGI("publish_match_indicator=%u\n", msg->publish_match_indicator);
3915 ALOGI("service_responder_policy=%u\n", msg->service_responder_policy);
3916 ALOGI("service_name_len=%u\n", msg->service_name_len);
3917 if (msg->service_name_len)
3918 ALOGI("service_name=%s\n", msg->service_name);
3919 ALOGI("service_specific_info_len=%u\n", msg->service_specific_info_len);
3920 if (msg->service_specific_info_len)
3921 ALOGI("service_specific_info=%s\n", msg->service_specific_info);
3922 ALOGI("rx_match_filter_len=%u\n", msg->rx_match_filter_len);
3923 if (msg->rx_match_filter_len)
3924 prhex("rx_match_filter", msg->rx_match_filter, msg->rx_match_filter_len);
3925 ALOGI("tx_match_filter_len=%u\n", msg->tx_match_filter_len);
3926 if (msg->tx_match_filter_len)
3927 prhex("tx_match_filter", msg->tx_match_filter, msg->tx_match_filter_len);
3928 ALOGI("rssi_threshold_flag=%u\n", msg->rssi_threshold_flag);
3929 ALOGI("connmap=%u\n", msg->connmap);
3930 ALOGI("recv_indication_cfg=%u\n", msg->recv_indication_cfg);
3931 ALOGI("cipher_type=%u\n", msg->cipher_type);
3932 ALOGI("key_info: key_type =%u\n", msg->key_info.key_type);
3933 ALOGI("key_info: pmk info=%s\n", msg->key_info.body.pmk_info.pmk);
3934 ALOGI("key_info: passphrase_info=%s\n", msg->key_info.body.passphrase_info.passphrase);
3935 ALOGI("scid_len=%u\n", msg->scid_len);
3936 if (msg->scid_len)
3937 ALOGI("scid=%s\n", msg->scid);
3938 ALOGI("NanSdeaCtrlParams NdpType=%u\n", msg->sdea_params.ndp_type);
3939 ALOGI("NanSdeaCtrlParams security_cfg=%u\n", msg->sdea_params.security_cfg);
3940 ALOGI("NanSdeaCtrlParams ranging_state=%u\n", msg->sdea_params.ranging_state);
3941 ALOGI("NanSdeaCtrlParams range_report=%u\n", msg->sdea_params.range_report);
3942 ALOGI("NanRangingCfg ranging_interval_msec=%u\n", msg->ranging_cfg.ranging_interval_msec);
3943 ALOGI("NanRangingCfg config_ranging_indications=%u\n", msg->ranging_cfg.config_ranging_indications);
3944 ALOGI("NanRangingCfg distance_ingress_mm=%u\n", msg->ranging_cfg.distance_ingress_mm);
3945 ALOGI("NanRangingCfg distance_egress_mm=%u\n", msg->ranging_cfg.distance_egress_mm);
3946 ALOGI("NanRangingAutoResponse = %u\n", msg->ranging_auto_response);
3947 ALOGI("range_response_cfg=%u\n", msg->range_response_cfg.ranging_response);
3948
3949 ALOGI("sdea_service_specific_info_len=%u\n", msg->sdea_service_specific_info_len);
3950 if (msg->sdea_service_specific_info_len)
3951 ALOGI("sdea_service_specific_info=%s\n", msg->sdea_service_specific_info);
3952
3953 return WIFI_SUCCESS;
3954 }
3955
dump_NanSubscribeRequest(NanSubscribeRequest * msg)3956 static int dump_NanSubscribeRequest(NanSubscribeRequest* msg)
3957 {
3958 ALOGI("%s: Dump NanSubscribeRequest msg:\n", __func__);
3959 u8 i = 0;
3960 if (msg == NULL) {
3961 ALOGE("Invalid msg\n");
3962 return WIFI_ERROR_UNKNOWN;
3963 }
3964 ALOGI("subscribe_id=%u\n", msg->subscribe_id);
3965 ALOGI("ttl=%u\n", msg->ttl);
3966 ALOGI("period=%u\n", msg->period);
3967 ALOGI("subscribe_type=%u\n", msg->subscribe_type);
3968 ALOGI("serviceResponseFilter=%u\n", msg->serviceResponseFilter);
3969 ALOGI("serviceResponseInclude=%u\n", msg->serviceResponseInclude);
3970 ALOGI("useServiceResponseFilter=%u\n", msg->useServiceResponseFilter);
3971 ALOGI("ssiRequiredForMatchIndication=%u\n", msg->ssiRequiredForMatchIndication);
3972 ALOGI("subscribe_count=%u\n", msg->subscribe_count);
3973 ALOGI("subscribe_match_indicator=%u\n", msg->subscribe_match_indicator);
3974 ALOGI("service_name_len=%u\n", msg->service_name_len);
3975 if (msg->service_name_len)
3976 ALOGI("service_name=%s\n", msg->service_name);
3977 ALOGI("service_specific_info_len=%u\n", msg->service_specific_info_len);
3978 if (msg->service_specific_info_len)
3979 ALOGI("service_specific_info=%s\n", msg->service_specific_info);
3980 ALOGI("rx_match_filter_len=%u\n", msg->rx_match_filter_len);
3981 if (msg->rx_match_filter_len)
3982 prhex("rx_match_filter", msg->rx_match_filter, msg->rx_match_filter_len);
3983 ALOGI("tx_match_filter_len=%u\n", msg->tx_match_filter_len);
3984 if (msg->tx_match_filter_len)
3985 prhex("tx_match_filter", msg->tx_match_filter, msg->tx_match_filter_len);
3986 ALOGI("rssi_threshold_flag=%u\n", msg->rssi_threshold_flag);
3987 ALOGI("connmap=%u\n", msg->connmap);
3988 ALOGI("num_intf_addr_present=%u\n", msg->num_intf_addr_present);
3989 if (msg->num_intf_addr_present) {
3990 for (i = 0; i < NAN_MAX_SUBSCRIBE_MAX_ADDRESS; i++) {
3991 ALOGI("peer_disc_mac_addr=" MACSTR "\n", MAC2STR(msg->intf_addr[i]));
3992 }
3993 }
3994 ALOGI("recv_indication_cfg=%u\n", msg->recv_indication_cfg);
3995 ALOGI("cipher_type=%u\n", msg->cipher_type);
3996 ALOGI("key_info: key_type =%u\n", msg->key_info.key_type);
3997 ALOGI("key_info: pmk info=%s\n", msg->key_info.body.pmk_info.pmk);
3998 ALOGI("key_info: passphrase_info=%s\n", msg->key_info.body.passphrase_info.passphrase);
3999 ALOGI("scid_len=%u\n", msg->scid_len);
4000 if (msg->scid_len)
4001 ALOGI("scid=%s\n", msg->scid);
4002 ALOGI("NanSdeaCtrlParams NdpType=%u\n", msg->sdea_params.ndp_type);
4003 ALOGI("NanSdeaCtrlParams security_cfg=%u\n", msg->sdea_params.security_cfg);
4004 ALOGI("NanSdeaCtrlParams ranging_state=%u\n", msg->sdea_params.ranging_state);
4005 ALOGI("NanSdeaCtrlParams range_report=%u\n", msg->sdea_params.range_report);
4006 ALOGI("NanRangingCfg ranging_interval_msec=%u\n", msg->ranging_cfg.ranging_interval_msec);
4007 ALOGI("NanRangingCfg config_ranging_indications=%u\n", msg->ranging_cfg.config_ranging_indications);
4008 ALOGI("NanRangingCfg distance_ingress_mm=%u\n", msg->ranging_cfg.distance_ingress_mm);
4009 ALOGI("NanRangingCfg distance_egress_mm=%u\n", msg->ranging_cfg.distance_egress_mm);
4010 ALOGI("NanRangingAutoResponse = %u\n", msg->ranging_auto_response);
4011 ALOGI("range_response = %u\n", msg->range_response_cfg.ranging_response);
4012
4013 ALOGI("sdea_service_specific_info_len=%u\n", msg->sdea_service_specific_info_len);
4014 if (msg->sdea_service_specific_info_len)
4015 ALOGI("sdea_service_specific_info=%s\n", msg->sdea_service_specific_info);
4016
4017 return WIFI_SUCCESS;
4018 }
4019
dump_NanTransmitFollowupRequest(NanTransmitFollowupRequest * msg)4020 static int dump_NanTransmitFollowupRequest(NanTransmitFollowupRequest* msg)
4021 {
4022 ALOGI("%s: Dump NanTransmitFollowupRequest msg:\n", __func__);
4023 if (msg == NULL) {
4024 ALOGE("Invalid msg\n");
4025 return WIFI_ERROR_UNKNOWN;
4026 }
4027 ALOGI("publish_subscribe_id=%u\n", msg->publish_subscribe_id);
4028 ALOGI("requestor_instance_id=%u\n", msg->requestor_instance_id);
4029 ALOGI("addr=" MACSTR "\n", MAC2STR(msg->addr));
4030 ALOGI("priority=%u\n", msg->priority);
4031 ALOGI("dw_or_faw=%u\n", msg->dw_or_faw);
4032 ALOGI("service_specific_info_len=%u\n", msg->service_specific_info_len);
4033 if (msg->service_specific_info_len)
4034 ALOGI("service_specific_info=%s\n", msg->service_specific_info);
4035 ALOGI("recv_indication_cfg=%u\n", msg->recv_indication_cfg);
4036 ALOGI("sdea_service_specific_info_len=%u\n", msg->sdea_service_specific_info_len);
4037 if (msg->sdea_service_specific_info_len)
4038 ALOGI("sdea_service_specific_info=%s\n", msg->sdea_service_specific_info);
4039
4040 return WIFI_SUCCESS;
4041 }
4042
dump_NanDataPathInitiatorRequest(NanDataPathInitiatorRequest * msg)4043 static int dump_NanDataPathInitiatorRequest(NanDataPathInitiatorRequest* msg)
4044 {
4045 ALOGI("%s: Dump NanDataPathInitiatorRequest msg:\n", __func__);
4046
4047 if (msg == NULL) {
4048 ALOGE("Invalid msg\n");
4049 return WIFI_ERROR_UNKNOWN;
4050 }
4051
4052 ALOGI("requestor_instance_id=%d\n", msg->requestor_instance_id);
4053 ALOGI("channel_request_type=%d\n", msg->channel_request_type);
4054 ALOGI("channel=%u\n", msg->channel);
4055 ALOGI("peer_disc_mac_addr=" MACSTR "\n", MAC2STR(msg->peer_disc_mac_addr));
4056 ALOGI("ndp_iface=%s\n", msg->ndp_iface);
4057 ALOGI("ndp_cfg: security_cfg =%u\n", msg->ndp_cfg.security_cfg);
4058 ALOGI("ndp_cfg: qos_cfg=%u\n", msg->ndp_cfg.qos_cfg);
4059 ALOGI("dp app info len=%u\n", msg->app_info.ndp_app_info_len);
4060 if (msg->app_info.ndp_app_info_len) {
4061 prhex("dp app info=: ", (u8*)msg->app_info.ndp_app_info,
4062 msg->app_info.ndp_app_info_len);
4063 }
4064 ALOGI("cipher_type=%u\n", msg->cipher_type);
4065 ALOGI("key_info: key_type =%u\n", msg->key_info.key_type);
4066 ALOGI("key_info: pmk info=%s\n", msg->key_info.body.pmk_info.pmk);
4067 ALOGI("key_info: passphrase_info=%s\n", msg->key_info.body.passphrase_info.passphrase);
4068 if (msg->service_name_len) {
4069 ALOGI("service_name=%s\n", msg->service_name);
4070 }
4071 return WIFI_SUCCESS;
4072 }
4073
dump_NanDataPathIndicationResponse(NanDataPathIndicationResponse * msg)4074 static int dump_NanDataPathIndicationResponse(NanDataPathIndicationResponse* msg)
4075 {
4076 ALOGI("%s: Dump NanDataPathIndicationResponse msg:\n", __func__);
4077
4078 if (msg == NULL) {
4079 ALOGE("Invalid msg\n");
4080 return WIFI_ERROR_UNKNOWN;
4081 }
4082
4083 ALOGI("ndp_instance_id=%d\n", msg->ndp_instance_id);
4084 ALOGI("ndp_iface=%s\n", msg->ndp_iface);
4085 ALOGI("ndp_cfg: security_cfg =%u\n", msg->ndp_cfg.security_cfg);
4086 ALOGI("response code =%u\n", msg->rsp_code);
4087 ALOGI("ndp_cfg: qos_cfg=%u\n", msg->ndp_cfg.qos_cfg);
4088 ALOGI("dp app info len=%u\n", msg->app_info.ndp_app_info_len);
4089 if (msg->app_info.ndp_app_info_len) {
4090 prhex("dp app info=: ", (u8*)msg->app_info.ndp_app_info,
4091 msg->app_info.ndp_app_info_len);
4092 }
4093 ALOGI("cipher_type=%u\n", msg->cipher_type);
4094 ALOGI("key_info: key_type =%u\n", msg->key_info.key_type);
4095 ALOGI("key_info: pmk info=%s\n", msg->key_info.body.pmk_info.pmk);
4096 ALOGI("key_info: passphrase_info=%s\n", msg->key_info.body.passphrase_info.passphrase);
4097 ALOGI("service_name_len=%u\n", msg->service_name_len);
4098 if (msg->service_name_len) {
4099 ALOGI("service_name=%s\n", msg->service_name);
4100 }
4101 return WIFI_SUCCESS;
4102 }
4103 #endif /* CONFIG_BRCM */
4104
nan_reset_dbg_counters()4105 void nan_reset_dbg_counters()
4106 {
4107 memset(&counters, 0, sizeof(counters));
4108 }
4109
4110 ///////////////////////////////////////////////////////////////////////////////
nan_enable_request(transaction_id id,wifi_interface_handle iface,NanEnableRequest * msg)4111 wifi_error nan_enable_request(transaction_id id,
4112 wifi_interface_handle iface, NanEnableRequest* msg)
4113 {
4114 wifi_error ret = WIFI_SUCCESS;
4115 wifi_handle handle = getWifiHandle(iface);
4116 NanRequestType cmdType = NAN_REQUEST_ENABLE;
4117
4118 ALOGI("Enabling Nan, Handle = %p\n", handle);
4119
4120 #ifdef CONFIG_BRCM
4121 // check up nan enable params from Nan manager level
4122 dump_NanEnableRequest(msg);
4123 #endif /* CONFIG_BRCM */
4124 nan_reset_dbg_counters();
4125 /* XXX: WAR posting async enable response */
4126 //NanMacControl *cmd = new NanMacControl(iface, id, (void *)msg, cmdType);
4127 NanMacControl *cmd = (NanMacControl*)(info.nan_mac_control);
4128 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
4129 cmd->setType(cmdType);
4130 cmd->setId(id);
4131 cmd->setMsg((void *)msg);
4132 ret = (wifi_error)cmd->start();
4133 if (ret != WIFI_SUCCESS) {
4134 ALOGE("%s : failed in start, error = %d\n", __func__, ret);
4135 }
4136 //cmd->releaseRef();
4137 return ret;
4138 }
4139
nan_dump_dbg_counters()4140 void nan_dump_dbg_counters()
4141 {
4142 ALOGI("Num Data Path Requests %d\n", counters.dp_req);
4143 ALOGI("Num Data Path Responses %d\n", counters.dp_resp);
4144 ALOGI("Num Data Path Confirms %d\n", counters.dp_confirm_evt);
4145 ALOGI("Num Data Path Request Events %d\n", counters.dp_req_evt);
4146 ALOGI("Num Transmit Requests %d\n", counters.transmit_req);
4147 ALOGI("Num Followup Transmits Recvd %d\n", counters.transmit_recv);
4148 ALOGI("Num Transmit Success %d\n", counters.transmit_txs);
4149 }
4150
nan_disable_request(transaction_id id,wifi_interface_handle iface)4151 wifi_error nan_disable_request(transaction_id id,
4152 wifi_interface_handle iface)
4153 {
4154 wifi_handle handle = getWifiHandle(iface);
4155 NanRequestType cmdType = NAN_REQUEST_DISABLE;
4156 wifi_error ret = WIFI_SUCCESS;
4157
4158 ALOGI("Disabling Nan, Handle = %p\n", handle);
4159 NanMacControl *cmd = new NanMacControl(iface, id, NULL, cmdType);
4160 NanMacControl *mac_prim = (NanMacControl*)(info.nan_mac_control);
4161
4162 if (id != NAN_MAC_INVALID_TRANSID) {
4163 ALOGE("Disable NAN MAC transId= %d\n", id);
4164 mac_prim->setId(id);
4165 } else {
4166 ALOGE("Invalid transId= %d cur= %d\n", id, mac_prim->getId());
4167 }
4168
4169 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
4170
4171 nan_dump_dbg_counters();
4172
4173 ret = (wifi_error)cmd->cancel();
4174 if (ret != WIFI_SUCCESS) {
4175 ALOGE("cancel failed, error = %d\n", ret);
4176 } else {
4177 ALOGE("Deinitializing Nan Mac Control = %p\n", cmd);
4178 }
4179 cmd->releaseRef();
4180 return ret;
4181 }
4182
nan_publish_request(transaction_id id,wifi_interface_handle iface,NanPublishRequest * msg)4183 wifi_error nan_publish_request(transaction_id id,
4184 wifi_interface_handle iface, NanPublishRequest* msg)
4185 {
4186 wifi_error ret = WIFI_SUCCESS;
4187 wifi_handle handle = getWifiHandle(iface);
4188
4189 ALOGI("Publish Nan, halHandle = %p\n", handle);
4190 #ifdef CONFIG_BRCM
4191 dump_NanPublishRequest(msg);
4192 #endif /* CONFIG_BRCM */
4193
4194 NanRequestType cmdType = NAN_REQUEST_PUBLISH;
4195 NanDiscEnginePrimitive *cmd = new NanDiscEnginePrimitive(iface, id, (void *)msg, cmdType);
4196 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
4197 ret = (wifi_error)cmd->start();
4198 if (ret != WIFI_SUCCESS) {
4199 ALOGE("%s : failed in start, error = %d\n", __func__, ret);
4200 }
4201 cmd->releaseRef();
4202 return ret;
4203 }
4204
4205 /* Function to send NAN request to the wifi driver */
nan_publish_cancel_request(transaction_id id,wifi_interface_handle iface,NanPublishCancelRequest * msg)4206 wifi_error nan_publish_cancel_request(transaction_id id,
4207 wifi_interface_handle iface, NanPublishCancelRequest* msg)
4208 {
4209 wifi_error ret = WIFI_SUCCESS;
4210 NanDiscEnginePrimitive *cmd;
4211 NanRequestType cmdType = NAN_REQUEST_PUBLISH_CANCEL;
4212
4213 ALOGE("Cancellling publish request %d\n", msg->publish_id);
4214 cmd = new NanDiscEnginePrimitive(iface, id, (void *)msg, cmdType);
4215 cmd->setInstId(msg->publish_id);
4216 cmd->setType(cmdType);
4217 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
4218
4219 ret = (wifi_error)cmd->start();
4220 if (ret != WIFI_SUCCESS) {
4221 ALOGE("%s : failed in start, error = %d\n", __func__, ret);
4222 }
4223 cmd->releaseRef();
4224 return ret;
4225 }
4226
4227 /* Function to send NAN request to the wifi driver */
nan_subscribe_request(transaction_id id,wifi_interface_handle iface,NanSubscribeRequest * msg)4228 wifi_error nan_subscribe_request(transaction_id id,
4229 wifi_interface_handle iface, NanSubscribeRequest* msg)
4230 {
4231 wifi_error ret = WIFI_SUCCESS;
4232 wifi_handle handle = getWifiHandle(iface);
4233 ALOGI("Subscribe Nan, halHandle = %p handle[%d]\n", handle, msg->subscribe_id);
4234 NanDiscEnginePrimitive *cmd;
4235 #ifdef CONFIG_BRCM
4236 dump_NanSubscribeRequest(msg);
4237 #endif /* CONFIG_BRCM */
4238
4239 NanRequestType cmdType = NAN_REQUEST_SUBSCRIBE;
4240 cmd = new NanDiscEnginePrimitive(iface, id, (void *)msg, cmdType);
4241 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
4242 ret = (wifi_error)cmd->start();
4243 if (ret != WIFI_SUCCESS) {
4244 ALOGE("%s : failed in start, error = %d\n", __func__, ret);
4245 }
4246 cmd->releaseRef();
4247 return ret;
4248
4249 }
4250
4251 /* Function to send NAN request to the wifi driver.*/
nan_subscribe_cancel_request(transaction_id id,wifi_interface_handle iface,NanSubscribeCancelRequest * msg)4252 wifi_error nan_subscribe_cancel_request(transaction_id id,
4253 wifi_interface_handle iface, NanSubscribeCancelRequest* msg)
4254 {
4255 wifi_error ret = WIFI_SUCCESS;
4256 NanDiscEnginePrimitive *cmd;
4257 NanRequestType cmdType = NAN_REQUEST_SUBSCRIBE_CANCEL;
4258
4259 ALOGE("creating new instance + %d\n", msg->subscribe_id);
4260 cmd = new NanDiscEnginePrimitive(iface, id, (void *)msg, cmdType);
4261 cmd->setInstId(msg->subscribe_id);
4262 cmd->setType(cmdType);
4263 ret = (wifi_error)cmd->start();
4264 if (ret != WIFI_SUCCESS) {
4265 ALOGE("%s : failed in start, error = %d\n", __func__, ret);
4266 }
4267 cmd->releaseRef();
4268
4269 return ret;
4270 }
4271
4272 /* Function to send nan transmit followup Request to the wifi driver.*/
nan_transmit_followup_request(transaction_id id,wifi_interface_handle iface,NanTransmitFollowupRequest * msg)4273 wifi_error nan_transmit_followup_request(transaction_id id,
4274 wifi_interface_handle iface, NanTransmitFollowupRequest* msg)
4275 {
4276 NanDiscEnginePrimitive *cmd = NULL;
4277 NanRequestType cmdType = NAN_REQUEST_TRANSMIT_FOLLOWUP;
4278 wifi_error ret = WIFI_SUCCESS;
4279
4280 #ifdef CONFIG_BRCM
4281 dump_NanTransmitFollowupRequest(msg);
4282 #endif /* CONFIG_BRCM */
4283 counters.transmit_req++;
4284 cmd = new NanDiscEnginePrimitive(iface, id, (void *)msg, cmdType);
4285 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
4286 cmd->setTransactionId(id);
4287
4288 ret = (wifi_error)cmd->start();
4289 if (ret != WIFI_SUCCESS) {
4290 ALOGE("%s : failed in start, error = %d\n", __func__, ret);
4291 }
4292 cmd->releaseRef();
4293 return ret;
4294 }
4295
4296 /* Function to send NAN statistics request to the wifi driver */
nan_stats_request(transaction_id id,wifi_interface_handle iface,NanStatsRequest * msg)4297 wifi_error nan_stats_request(transaction_id id,
4298 wifi_interface_handle iface, NanStatsRequest* msg)
4299 {
4300 wifi_handle handle = getWifiHandle(iface);
4301
4302 ALOGI("Nan Stats, halHandle = %p", handle);
4303
4304 #ifdef NOT_SUPPORTED
4305 NanRequestType cmdType = NAN_REQUEST_STATS;
4306 wifi_error ret = WIFI_SUCCESS;
4307 NanCommand *cmd = new NanCommand(iface, id, (void *)msg, cmdType);
4308 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
4309 ret = (wifi_error)cmd->start();
4310 if (ret != WIFI_SUCCESS) {
4311 ALOGE("%s : failed in start, error = %d\n", __func__, ret);
4312 }
4313 cmd->releaseRef();
4314 return ret;
4315 #else
4316 return WIFI_ERROR_NOT_SUPPORTED;
4317 #endif
4318 }
4319
4320 /* Function to send NAN configuration request to the wifi driver */
nan_config_request(transaction_id id,wifi_interface_handle iface,NanConfigRequest * msg)4321 wifi_error nan_config_request(transaction_id id,
4322 wifi_interface_handle iface, NanConfigRequest* msg)
4323 {
4324 wifi_error ret = WIFI_SUCCESS;
4325 wifi_handle handle = getWifiHandle(iface);
4326 NanRequestType cmdType = NAN_REQUEST_CONFIG;
4327
4328 ALOGI("Configuring Nan, halHandle = %p\n", handle);
4329
4330 #ifdef CONFIG_BRCM
4331 /* check up nan config params from Nan manager level */
4332 dump_NanConfigRequestRequest(msg);
4333 #endif /* CONFIG_BRCM */
4334
4335 NanMacControl *cmd = new NanMacControl(iface, id, (void *)msg, cmdType);
4336 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
4337
4338 cmd->setType(cmdType);
4339 ret = (wifi_error)cmd->start();
4340 if (ret != WIFI_SUCCESS) {
4341 ALOGE("start failed, error = %d\n", ret);
4342 } else {
4343 ALOGE("Initializing Nan Mac Control = %p\n", cmd);
4344 }
4345 cmd->releaseRef();
4346 return ret;
4347 }
4348
4349 /* Function to send NAN request to the wifi driver */
nan_tca_request(transaction_id id,wifi_interface_handle iface,NanTCARequest * msg)4350 wifi_error nan_tca_request(transaction_id id,
4351 wifi_interface_handle iface, NanTCARequest* msg)
4352 {
4353 wifi_handle handle = getWifiHandle(iface);
4354
4355 ALOGI("Nan TCA, halHandle = %p", handle);
4356
4357 #ifdef NOT_SUPPORTED
4358 NanRequestType cmdType = NAN_REQUEST_TCA;
4359 wifi_error ret = WIFI_SUCCESS;
4360 NanCommand *cmd = new NanCommand(iface, id, (void *)msg, cmdType);
4361 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
4362
4363 ret = (wifi_error)cmd->start();
4364 if (ret != WIFI_SUCCESS) {
4365 ALOGE("%s : failed in start, error = %d\n", __func__, ret);
4366 }
4367 cmd->releaseRef();
4368 return ret;
4369 #else
4370 return WIFI_ERROR_NOT_SUPPORTED;
4371 #endif
4372 }
4373
nan_beacon_sdf_payload_request(transaction_id id,wifi_interface_handle iface,NanBeaconSdfPayloadRequest * msg)4374 wifi_error nan_beacon_sdf_payload_request(transaction_id id,
4375 wifi_interface_handle iface, NanBeaconSdfPayloadRequest* msg)
4376 {
4377 ALOGI("Nan Beacon Sdf Payload Request");
4378 return WIFI_ERROR_NOT_SUPPORTED;
4379 }
4380
nan_get_capabilities(transaction_id id,wifi_interface_handle iface)4381 wifi_error nan_get_capabilities(transaction_id id, wifi_interface_handle iface)
4382 {
4383 wifi_error ret = WIFI_SUCCESS;
4384 wifi_handle handle = getWifiHandle(iface);
4385 ALOGI("Get Nan Capabilties, id=%d, halHandle=%p\n", id, handle);
4386
4387 NanRequestType cmdType = NAN_REQUEST_GET_CAPABILTIES;
4388 NanDiscEnginePrimitive *cmd = new NanDiscEnginePrimitive(iface, id, NULL, cmdType);
4389 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
4390
4391 ret = (wifi_error)cmd->start();
4392 if (ret != WIFI_SUCCESS) {
4393 ALOGE("%s : failed in start, error = %d\n", __func__, ret);
4394 }
4395 cmd->releaseRef();
4396 return ret;
4397 }
nan_check_dhd_hal_version(wifi_interface_handle iface,wifi_handle handle)4398 wifi_error nan_check_dhd_hal_version(wifi_interface_handle iface,
4399 wifi_handle handle)
4400 {
4401 NanRequestType cmdType = NAN_VERSION_INFO;
4402 NanMacControl *cmd = new NanMacControl(iface, 0, NULL, cmdType);
4403 wifi_error ret = WIFI_SUCCESS;
4404 u32 version;
4405
4406 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
4407
4408 cmd->setType(cmdType);
4409
4410 ret = (wifi_error)cmd->start();
4411 if (ret != WIFI_SUCCESS) {
4412 ALOGI("\nVersion subcmd failed ret = %x\n", ret);
4413 ret = WIFI_ERROR_NOT_SUPPORTED;
4414 goto done;
4415 }
4416 version = cmd->getVersion();
4417 /* check if version handled..can support multiple versions */
4418 if (version == NAN_HAL_VERSION_1) {
4419 ALOGI("\nGot the supported version %d\n", version);
4420 current_dhd_hal_ver = version;
4421 ret = WIFI_SUCCESS;
4422 goto done;
4423 } else {
4424 ALOGI("\nGot the unsupported version %d\n", version);
4425 ret = WIFI_ERROR_NOT_SUPPORTED;
4426 goto done;
4427 }
4428 done:
4429 cmd->releaseRef();
4430 return ret;
4431 }
nan_deinit_handler()4432 wifi_error nan_deinit_handler()
4433 {
4434 if (info.nan_mac_control) {
4435 /* register for Nan vendor events with info mac class*/
4436 NanMacControl *cmd_event = (NanMacControl*)(info.nan_mac_control);
4437 cmd_event->unRegisterNanVendorEvents();
4438 delete (NanMacControl*)info.nan_mac_control;
4439 info.nan_mac_control = NULL;
4440 }
4441 if (info.nan_disc_control) {
4442 delete (NanDiscEnginePrimitive*)info.nan_disc_control;
4443 info.nan_disc_control = NULL;
4444 }
4445 if (info.nan_dp_control) {
4446 delete (NanDataPathPrimitive*)info.nan_dp_control;
4447 info.nan_dp_control = NULL;
4448 }
4449 if (NAN_HANDLE(info)) {
4450 delete GET_NAN_HANDLE(info);
4451 NAN_HANDLE(info) = NULL;
4452 }
4453 ALOGI("wifi nan internal clean up done");
4454 return WIFI_SUCCESS;
4455 }
nan_register_handler(wifi_interface_handle iface,NanCallbackHandler handlers)4456 wifi_error nan_register_handler(wifi_interface_handle iface,
4457 NanCallbackHandler handlers)
4458 {
4459 wifi_handle handle = getWifiHandle(iface);
4460 if (NAN_HANDLE(info)) {
4461 /* cleanup and re-register */
4462 nan_deinit_handler();
4463 }
4464 ALOGI("\nChecking version compat\n");
4465 /* checking version compat b/w DHD and HAL */
4466 if (nan_check_dhd_hal_version(iface, handle) != WIFI_SUCCESS) {
4467 ALOGE("\n Get version failed..check DHD\n");
4468 return WIFI_ERROR_NOT_SUPPORTED;
4469 }
4470 memset(&info, 0, sizeof(info));
4471 NAN_HANDLE(info) = new NanHandle(handle, handlers);
4472 info.nan_mac_control =
4473 (void*)new NanMacControl(iface, 0, NULL, NAN_REQUEST_LAST);
4474 NULL_CHECK_RETURN(info.nan_mac_control, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
4475 info.nan_disc_control =
4476 (void*)new NanDiscEnginePrimitive(iface, 0, NULL, NAN_REQUEST_LAST);
4477 NULL_CHECK_RETURN(info.nan_disc_control, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
4478 info.nan_dp_control =
4479 (void*)new NanDataPathPrimitive(iface, 0, NULL, NAN_REQUEST_LAST);
4480 NULL_CHECK_RETURN(info.nan_dp_control, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
4481
4482 /* register for Nan vendor events with info mac class*/
4483 NanMacControl *cmd_event = (NanMacControl*)(info.nan_mac_control);
4484 cmd_event->registerNanVendorEvents();
4485 return WIFI_SUCCESS;
4486 }
4487
nan_get_version(wifi_handle handle,NanVersion * version)4488 wifi_error nan_get_version(wifi_handle handle, NanVersion* version)
4489 {
4490 wifi_error ret = WIFI_SUCCESS;
4491 if (version) {
4492 *version = (NAN_MAJOR_REL_VERSION << 16 | NAN_MINOR_REL_VERSION << 8 |
4493 NAN_PATCH_REL_VERSION);
4494 } else {
4495 ret = WIFI_ERROR_INVALID_ARGS;
4496 }
4497
4498 return ret;
4499 }
4500
4501
4502 ///////////////////////////////////////////////////////////////////////////////
4503 class NanEventCap : public WifiCommand
4504 {
4505 public:
NanEventCap(wifi_interface_handle iface,int id)4506 NanEventCap(wifi_interface_handle iface, int id)
4507 : WifiCommand("NanCommand", iface, id)
4508 {}
4509
start()4510 int start()
4511 {
4512 registerNanVendorEvents();
4513 return WIFI_SUCCESS;
4514 }
4515
handleResponse(WifiEvent & reply)4516 int handleResponse(WifiEvent& reply) {
4517 return NL_SKIP;
4518 }
unRegisterNanVendorEvents()4519 void unRegisterNanVendorEvents()
4520 {
4521 int i = 0;
4522 for (i = NAN_EVENT_ENABLED; i <= NAN_EVENT_DATA_END; i++) {
4523 unregisterVendorHandler(GOOGLE_OUI, i);
4524 }
4525 unregisterVendorHandler(GOOGLE_OUI, NAN_ASYNC_RESPONSE_DISABLED);
4526 unregisterVendorHandler(GOOGLE_OUI, NAN_EVENT_MATCH_EXPIRY);
4527 }
registerNanVendorEvents()4528 void registerNanVendorEvents()
4529 {
4530 int i = 0;
4531 for (i = NAN_EVENT_ENABLED; i <= NAN_EVENT_DATA_END; i++) {
4532 registerVendorHandler(GOOGLE_OUI, i);
4533 }
4534 registerVendorHandler(GOOGLE_OUI, NAN_ASYNC_RESPONSE_DISABLED);
4535 registerVendorHandler(GOOGLE_OUI, NAN_EVENT_MATCH_EXPIRY);
4536 }
4537
handleEvent(WifiEvent & event)4538 int handleEvent(WifiEvent& event) {
4539 int cmd = event.get_vendor_subcmd();
4540 u16 attr_type;
4541 nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
4542
4543 switch(cmd) {
4544 case NAN_EVENT_DE_EVENT: {
4545 u16 attr_type;
4546 NanDiscEngEventInd de_event;
4547 memset(&de_event, 0, sizeof(NanDiscEngEventInd));
4548
4549 for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
4550 attr_type = it.get_type();
4551 if (attr_type == NAN_ATTRIBUTE_CLUSTER_ID) {
4552 memcpy(&de_event.data.cluster.addr, it.get_data(), NAN_MAC_ADDR_LEN);
4553 ALOGI("cluster id = " MACSTR "\n", MAC2STR(de_event.data.cluster.addr));
4554 } else if (attr_type == NAN_ATTRIBUTE_ENABLE_STATUS) {
4555 ALOGI("nan enable status = %u\n", it.get_u16());
4556 } else if (attr_type == NAN_ATTRIBUTE_JOIN_STATUS) {
4557 ALOGI("nan joined status = %u\n", it.get_u16());
4558 } else if (attr_type == NAN_ATTRIBUTE_DE_EVENT_TYPE) {
4559 u8 de_type = it.get_u8();
4560 ALOGI("nan de event type = %u\n", de_type);
4561 if (de_type == NAN_EVENT_IFACE) {
4562 de_event.event_type = NAN_EVENT_ID_DISC_MAC_ADDR;
4563 ALOGI("received NAN_EVENT_ID_DISC_MAC_ADDR event\n");
4564 } else if (de_type == NAN_EVENT_START) {
4565 de_event.event_type = NAN_EVENT_ID_STARTED_CLUSTER;
4566 ALOGI("received NAN cluster started event\n");
4567 } else if (de_type == NAN_EVENT_JOIN) {
4568 /* To be deprecated */
4569 de_event.event_type = NAN_EVENT_ID_JOINED_CLUSTER;
4570 ALOGI("received join event\n");
4571 } else if (de_type == NAN_EVENT_ROLE_CHANGE) {
4572 ALOGI("received device role change event\n");
4573 } else if (de_type == NAN_EVENT_MERGE) {
4574 ALOGI("received Merge Event\n");
4575 } else {
4576 ALOGI("received unknown DE event, [%d]\n", de_type);
4577 }
4578 } else if (attr_type == NAN_ATTRIBUTE_MAC_ADDR) {
4579 memcpy(&de_event.data.cluster.addr, it.get_data(), NAN_MAC_ADDR_LEN);
4580 memcpy(mNmi, it.get_data(), NAN_MAC_ADDR_LEN);
4581 ALOGI("Primary discovery mac address = " MACSTR "\n",
4582 MAC2STR(mNmi));
4583 }
4584 }
4585
4586 GET_NAN_HANDLE(info)->mHandlers.EventDiscEngEvent(&de_event);
4587 break;
4588 }
4589 case NAN_EVENT_DISABLED: {
4590 ALOGI("Received NAN_EVENT_DISABLED\n");
4591 NanDisabledInd disabled_ind;
4592 memset(&disabled_ind, 0, sizeof(NanDisabledInd));
4593 for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
4594 attr_type = it.get_type();
4595 if (attr_type == NAN_ATTRIBUTE_STATUS) {
4596 disabled_ind.reason = (NanStatusType)it.get_u8();
4597 ALOGI("Nan Disable:status %u", disabled_ind.reason);
4598 } else if (attr_type == NAN_ATTRIBUTE_REASON) {
4599 u8 len = min(it.get_len(), sizeof(disabled_ind.nan_reason));
4600 memcpy(disabled_ind.nan_reason, it.get_data(), len);
4601 ALOGI("nan disabled reason: %s, len = %d\n",
4602 disabled_ind.nan_reason, len);
4603 }
4604 }
4605
4606 GET_NAN_HANDLE(info)->mHandlers.EventDisabled(&disabled_ind);
4607 unRegisterNanVendorEvents();
4608 break;
4609 }
4610 case NAN_EVENT_PUBLISH_TERMINATED: {
4611 ALOGI("Received NAN_EVENT_PUBLISH_TERMINATED\n");
4612 NanPublishTerminatedInd pub_term_event;
4613 memset(&pub_term_event, 0, sizeof(NanPublishTerminatedInd));
4614
4615 for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
4616 attr_type = it.get_type();
4617
4618 if (attr_type == NAN_ATTRIBUTE_PUBLISH_ID) {
4619 pub_term_event.publish_id = it.get_u32();
4620 ALOGI("pub id %u", pub_term_event.publish_id);
4621 } else if (attr_type == NAN_ATTRIBUTE_STATUS) {
4622 pub_term_event.reason = (NanStatusType)it.get_u8();
4623 ALOGI("pub termination status %u", pub_term_event.reason);
4624 } else if (attr_type == NAN_ATTRIBUTE_REASON) {
4625 u8 len = min(it.get_len(), sizeof(pub_term_event.nan_reason));
4626 memcpy(pub_term_event.nan_reason, it.get_data(), len);
4627 ALOGI("Pub termination nan reason: %s, len = %d\n",
4628 pub_term_event.nan_reason, len);
4629 } else {
4630 ALOGE("Unknown attr\n");
4631 }
4632 }
4633
4634 GET_NAN_HANDLE(info)->mHandlers.EventPublishTerminated(&pub_term_event);
4635 break;
4636 }
4637 case NAN_EVENT_SUBSCRIBE_MATCH: {
4638 NanMatchInd subscribe_event;
4639 memset(&subscribe_event, 0, sizeof(NanMatchInd));
4640 ALOGI("Received NAN_EVENT_SUBSCRIBE_MATCH\n");
4641
4642 /* By default FW is unable to cache this match */
4643 subscribe_event.out_of_resource_flag = true;
4644
4645 for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
4646 attr_type = it.get_type();
4647
4648 if (attr_type == NAN_ATTRIBUTE_SUBSCRIBE_ID) {
4649 ALOGI("sub id: %u", it.get_u16());
4650 subscribe_event.publish_subscribe_id = it.get_u16();
4651
4652 } else if (attr_type == NAN_ATTRIBUTE_PUBLISH_ID) {
4653 ALOGI("pub id %u", it.get_u32());
4654 subscribe_event.requestor_instance_id = it.get_u32();
4655
4656 } else if (attr_type == NAN_ATTRIBUTE_MAC_ADDR) {
4657 memcpy(subscribe_event.addr, it.get_data(), NAN_MAC_ADDR_LEN);
4658 ALOGI("publisher mac: " MACSTR, MAC2STR(subscribe_event.addr));
4659
4660 } else if (attr_type == NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO_LEN) {
4661 ALOGI("svc length: %d", it.get_u16());
4662 subscribe_event.service_specific_info_len = it.get_u16();
4663
4664 } else if (attr_type == NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO) {
4665 memcpy(subscribe_event.service_specific_info, it.get_data(),
4666 subscribe_event.service_specific_info_len);
4667 subscribe_event.service_specific_info
4668 [subscribe_event.service_specific_info_len] = '\0';
4669 ALOGI("service info: %s", subscribe_event.service_specific_info);
4670
4671 } else if (attr_type == NAN_ATTRIBUTE_TX_MATCH_FILTER_LEN) {
4672 ALOGI("sdf match filter length: %d", subscribe_event.sdf_match_filter_len);
4673 subscribe_event.sdf_match_filter_len = it.get_u16();
4674
4675 } else if (attr_type == NAN_ATTRIBUTE_TX_MATCH_FILTER) {
4676 memcpy(subscribe_event.sdf_match_filter, it.get_data(),
4677 subscribe_event.sdf_match_filter_len);
4678 subscribe_event.sdf_match_filter
4679 [subscribe_event.sdf_match_filter_len] = '\0';
4680 ALOGI("sdf match filter: %s", subscribe_event.sdf_match_filter);
4681 } else if (attr_type == NAN_ATTRIBUTE_CIPHER_SUITE_TYPE) {
4682 ALOGI("Peer Cipher suite type: %u", it.get_u8());
4683 subscribe_event.peer_cipher_type = it.get_u8();
4684 } else if (attr_type == NAN_ATTRIBUTE_SCID_LEN) {
4685 ALOGI("scid length %d", it.get_u32());
4686 subscribe_event.scid_len= it.get_u32();
4687 } else if (attr_type == NAN_ATTRIBUTE_SCID) {
4688 memcpy(subscribe_event.scid, it.get_data(),
4689 subscribe_event.scid_len);
4690 subscribe_event.scid
4691 [subscribe_event.scid_len] = '\0';
4692 ALOGI("scid: %s", subscribe_event.scid);
4693 } else if (attr_type == NAN_ATTRIBUTE_RANGING_INDICATION) {
4694 subscribe_event.range_info.ranging_event_type = it.get_u32();
4695 ALOGI("ranging indication %d", it.get_u32());
4696 } else if (attr_type == NAN_ATTRIBUTE_RANGING_RESULT) {
4697 subscribe_event.range_info.range_measurement_mm = it.get_u32();
4698 ALOGI("ranging result %d", it.get_u32());
4699 } else if (attr_type == NAN_ATTRIBUTE_RSSI_PROXIMITY) {
4700 subscribe_event.rssi_value = it.get_u8();
4701 ALOGI("rssi value : %u", it.get_u8());
4702 } else if (attr_type == NAN_ATTRIBUTE_SDEA_SERVICE_SPECIFIC_INFO_LEN) {
4703 ALOGI("sdea svc length %d", it.get_u16());
4704 subscribe_event.sdea_service_specific_info_len = it.get_u16();
4705 } else if (attr_type == NAN_ATTRIBUTE_SDEA_SERVICE_SPECIFIC_INFO) {
4706 memcpy(subscribe_event.sdea_service_specific_info, it.get_data(),
4707 subscribe_event.sdea_service_specific_info_len);
4708 subscribe_event.sdea_service_specific_info
4709 [subscribe_event.sdea_service_specific_info_len] = '\0';
4710 ALOGI("sdea service info: %s", subscribe_event.sdea_service_specific_info);
4711 } else if (attr_type == NAN_ATTRIBUTE_MATCH_OCCURRED_FLAG) {
4712 ALOGI("match occurred flag: %u", it.get_u8());
4713 subscribe_event.match_occured_flag = it.get_u8();
4714 } else if (attr_type == NAN_ATTRIBUTE_OUT_OF_RESOURCE_FLAG) {
4715 ALOGI("Out of resource flag: %u", it.get_u8());
4716 subscribe_event.out_of_resource_flag = it.get_u8();
4717 } else if (attr_type == NAN_ATTRIBUTE_SDE_CONTROL_CONFIG_DP) {
4718 ALOGI("Peer config for data path needed: %u", it.get_u8());
4719 subscribe_event.peer_sdea_params.config_nan_data_path = it.get_u8();
4720 } else if (attr_type == NAN_ATTRIBUTE_SDE_CONTROL_DP_TYPE) {
4721 ALOGI("Data Path type: %u", it.get_u8());
4722 subscribe_event.peer_sdea_params.ndp_type = (NdpType)it.get_u8();
4723 } else if (attr_type == NAN_ATTRIBUTE_SDE_CONTROL_SECURITY) {
4724 ALOGI("Security configuration: %u", it.get_u8());
4725 subscribe_event.peer_sdea_params.security_cfg =
4726 (NanDataPathSecurityCfgStatus)it.get_u8();
4727 } else if (attr_type == NAN_ATTRIBUTE_SDE_CONTROL_RANGE_SUPPORT) {
4728 ALOGI("Ranging report state: %u", it.get_u8());
4729 subscribe_event.peer_sdea_params.range_report = (NanRangeReport)it.get_u8();
4730 }
4731 }
4732
4733 GET_NAN_HANDLE(info)->mHandlers.EventMatch(&subscribe_event);
4734 break;
4735 }
4736 case NAN_EVENT_SUBSCRIBE_UNMATCH: {
4737 ALOGI("Received NAN_EVENT_SUBSCRIBE_UNMATCH\n");
4738 ALOGE("%s: Not applicable yet\n", __func__);
4739 break;
4740 }
4741 case NAN_EVENT_SUBSCRIBE_TERMINATED: {
4742 NanSubscribeTerminatedInd sub_term_event;
4743 memset(&sub_term_event, 0, sizeof(NanSubscribeTerminatedInd));
4744 ALOGI("Received NAN_EVENT_SUBSCRIBE_TERMINATED\n");
4745
4746 for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
4747 attr_type = it.get_type();
4748
4749 if (attr_type == NAN_ATTRIBUTE_SUBSCRIBE_ID) {
4750 sub_term_event.subscribe_id = it.get_u16();
4751 ALOGI("sub id: %u", sub_term_event.subscribe_id);
4752 } else if (attr_type == NAN_ATTRIBUTE_STATUS) {
4753 sub_term_event.reason = (NanStatusType)it.get_u8();
4754 ALOGI("sub termination status %u", sub_term_event.reason);
4755 } else if (attr_type == NAN_ATTRIBUTE_REASON) {
4756 u8 len = min(it.get_len(), sizeof(sub_term_event.nan_reason));
4757 memcpy(sub_term_event.nan_reason, it.get_data(), len);
4758 ALOGI("sub termination nan reason: %s, len = %d\n",
4759 sub_term_event.nan_reason, len);
4760 } else {
4761 ALOGE("Unknown attr: %u\n", attr_type);
4762 }
4763 }
4764
4765 GET_NAN_HANDLE(info)->mHandlers.EventSubscribeTerminated(&sub_term_event);
4766 break;
4767 }
4768 case NAN_EVENT_MATCH_EXPIRY:
4769 HandleExpiryEvent(info, vendor_data);
4770 break;
4771 case NAN_EVENT_FOLLOWUP: {
4772 NanFollowupInd followup_event;
4773 memset(&followup_event, 0, sizeof(NanFollowupInd));
4774 ALOGI("Received NAN_EVENT_FOLLOWUP\n");
4775
4776 for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
4777 attr_type = it.get_type();
4778
4779 if (attr_type == NAN_ATTRIBUTE_MAC_ADDR) {
4780 memcpy(followup_event.addr, it.get_data(), NAN_MAC_ADDR_LEN);
4781
4782 } else if (attr_type == NAN_ATTRIBUTE_PEER_ID) {
4783 followup_event.publish_subscribe_id = it.get_u16();
4784
4785 } else if (attr_type == NAN_ATTRIBUTE_INST_ID) {
4786 followup_event.requestor_instance_id = it.get_u32();
4787
4788 } else if (attr_type == NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO_LEN) {
4789 followup_event.service_specific_info_len = it.get_u16();
4790
4791 } else if (attr_type == NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO) {
4792 memcpy(followup_event.service_specific_info, it.get_data(),
4793 followup_event.service_specific_info_len);
4794 followup_event.service_specific_info[followup_event.service_specific_info_len] =
4795 '\0';
4796 } else if (attr_type == NAN_ATTRIBUTE_SDEA_SERVICE_SPECIFIC_INFO_LEN) {
4797 ALOGI("sdea svc length %d", it.get_u16());
4798 followup_event.sdea_service_specific_info_len = it.get_u16();
4799 } else if (attr_type == NAN_ATTRIBUTE_SDEA_SERVICE_SPECIFIC_INFO) {
4800 memcpy(followup_event.sdea_service_specific_info, it.get_data(),
4801 followup_event.sdea_service_specific_info_len);
4802 followup_event.sdea_service_specific_info[followup_event.sdea_service_specific_info_len] = '\0';
4803 ALOGI("sdea service info: %s", followup_event.sdea_service_specific_info);
4804 }
4805 }
4806
4807 GET_NAN_HANDLE(info)->mHandlers.EventFollowup(&followup_event);
4808 break;
4809 }
4810 case NAN_EVENT_SDF: {
4811 ALOGI("Received NAN_EVENT_SDF:\n");
4812 NanBeaconSdfPayloadInd sdfInd;
4813 memset(&sdfInd, 0, sizeof(sdfInd));
4814
4815 for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
4816 attr_type = it.get_type();
4817
4818 if (attr_type == NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO_LEN) {
4819 sdfInd.data.frame_len = it.get_u16();
4820 if (sdfInd.data.frame_len > NAN_MAX_FRAME_DATA_LEN) {
4821 sdfInd.data.frame_len = NAN_MAX_FRAME_DATA_LEN;
4822 }
4823 ALOGI("Received NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO_LEN: 0x%x(%d)\n",
4824 sdfInd.data.frame_len, sdfInd.data.frame_len);
4825
4826 } else if (attr_type == NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO) {
4827 ALOGI("Received NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO\n");
4828 memcpy(&sdfInd.data.frame_data, it.get_data(), sdfInd.data.frame_len);
4829 prhex("sdfInd.data.frame_data: ", (u8*)sdfInd.data.frame_data,
4830 sdfInd.data.frame_len);
4831 }
4832 }
4833 GET_NAN_HANDLE(info)->mHandlers.EventBeaconSdfPayload(&sdfInd);
4834 break;
4835 }
4836 #ifdef NOT_YET
4837 case NAN_EVENT_PUBLISH_REPLIED_IND: {
4838 ALOGI("Received NAN_EVENT_PUBLISH_REPLIED_IND\n");
4839 NanPublishRepliedInd pub_reply_event;
4840 memset(&pub_reply_event, 0, sizeof(pub_reply_event));
4841
4842 for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
4843 attr_type = it.get_type();
4844
4845 if (attr_type == NAN_ATTRIBUTE_SUBSCRIBE_ID) {
4846 ALOGI("sub id: %u", it.get_u32());
4847 pub_reply_event.requestor_instance_id = it.get_u32();
4848 } else if (attr_type == NAN_ATTRIBUTE_MAC_ADDR) {
4849 memcpy(pub_reply_event.addr, it.get_data(), NAN_MAC_ADDR_LEN);
4850 ALOGI("Subscriber mac: " MACSTR, MAC2STR(pub_reply_event.addr));
4851 } else if (attr_type == NAN_ATTRIBUTE_RSSI_PROXIMITY) {
4852 pub_reply_event.rssi_value = it.get_u8();
4853 ALOGI("Received rssi value : %u", it.get_u8());
4854 }
4855 }
4856 GET_NAN_HANDLE(info)->mHandlers.EventPublishReplied(&pub_reply_event);
4857 break;
4858 }
4859 #endif /* NOT_YET */
4860 case NAN_EVENT_TCA: {
4861 ALOGI("Received NAN_EVENT_TCA\n");
4862 //GET_NAN_HANDLE(info)->mHandlers.EventTca(&sdfPayload);
4863 break;
4864 }
4865 case NAN_EVENT_DATA_REQUEST: {
4866 ALOGI("Received NAN_EVENT_DATA_REQUEST_INDICATION\n");
4867 NanDataPathRequestInd ndp_request_event;
4868 memset(&ndp_request_event, 0, sizeof(NanDataPathRequestInd));
4869 u16 ndp_ind_app_info_len = 0;
4870
4871 for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
4872 attr_type = it.get_type();
4873
4874 if (attr_type == NAN_ATTRIBUTE_PUBLISH_ID) {
4875 ALOGI("publish_id: %u\n", it.get_u32());
4876 ndp_request_event.service_instance_id = it.get_u32();
4877
4878 } else if (attr_type == NAN_ATTRIBUTE_MAC_ADDR) {
4879 memcpy(ndp_request_event.peer_disc_mac_addr,
4880 it.get_data(), NAN_MAC_ADDR_LEN);
4881 ALOGI("Discovery MAC addr of the peer/initiator: " MACSTR "\n",
4882 MAC2STR(ndp_request_event.peer_disc_mac_addr));
4883
4884 } else if (attr_type == NAN_ATTRIBUTE_NDP_ID) {
4885 ALOGI("ndp id: %u\n", it.get_u32());
4886 ndp_request_event.ndp_instance_id = it.get_u32();
4887
4888 } else if (attr_type == NAN_ATTRIBUTE_SECURITY) {
4889 ALOGI("security: %u\n", (NanDataPathSecurityCfgStatus) it.get_u8());
4890 ndp_request_event.ndp_cfg.security_cfg =
4891 (NanDataPathSecurityCfgStatus)it.get_u8();
4892
4893 } else if (attr_type == NAN_ATTRIBUTE_QOS) {
4894 ALOGI("QoS: %u", (NanDataPathQosCfg)it.get_u8());
4895 ndp_request_event.ndp_cfg.qos_cfg = (NanDataPathQosCfg)it.get_u8();
4896
4897 } else if (attr_type == NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO_LEN) {
4898 ALOGI("service info len: %d\n", it.get_u16());
4899 ndp_ind_app_info_len = it.get_u16();
4900 ndp_request_event.app_info.ndp_app_info_len = ndp_ind_app_info_len;
4901
4902 } else if (attr_type == NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO) {
4903 memcpy(ndp_request_event.app_info.ndp_app_info,
4904 it.get_data(), ndp_ind_app_info_len);
4905 ndp_request_event.app_info.ndp_app_info[ndp_ind_app_info_len] = '\0';
4906 ALOGI("service info: %s\n", ndp_request_event.app_info.ndp_app_info);
4907
4908 }
4909 }
4910
4911 GET_NAN_HANDLE(info)->mHandlers.EventDataRequest(&ndp_request_event);
4912 break;
4913 }
4914 case NAN_EVENT_DATA_CONFIRMATION: {
4915 ALOGI("Received NAN_EVENT_DATA_CONFIRMATION\n");
4916 NanDataPathConfirmInd ndp_create_confirmation_event;
4917 memset(&ndp_create_confirmation_event, 0, sizeof(NanDataPathConfirmInd));
4918 u16 ndp_conf_app_info_len = 0;
4919
4920 for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
4921 attr_type = it.get_type();
4922
4923 if (attr_type == NAN_ATTRIBUTE_NDP_ID) {
4924 ALOGI("ndp id: %u", it.get_u32());
4925 ndp_create_confirmation_event.ndp_instance_id = it.get_u32();
4926
4927 } else if (attr_type == NAN_ATTRIBUTE_PEER_NDI_MAC_ADDR) {
4928 memcpy(ndp_create_confirmation_event.peer_ndi_mac_addr,
4929 it.get_data(), NAN_MAC_ADDR_LEN);
4930 ALOGI("NDI mac address of the peer: " MACSTR "\n",
4931 MAC2STR(ndp_create_confirmation_event.peer_ndi_mac_addr));
4932
4933 } else if (attr_type == NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO_LEN) {
4934 ALOGI("service info string len: %d\n", it.get_u16());
4935 ndp_conf_app_info_len = it.get_u16();
4936 ndp_create_confirmation_event.app_info.ndp_app_info_len =
4937 ndp_conf_app_info_len;
4938
4939 } else if (attr_type == NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO) {
4940 memcpy(ndp_create_confirmation_event.app_info.ndp_app_info, it.get_data(),
4941 ndp_conf_app_info_len);
4942 ndp_create_confirmation_event.app_info.ndp_app_info[ndp_conf_app_info_len] =
4943 '\0';
4944 ALOGI("service info string: %s\n",
4945 ndp_create_confirmation_event.app_info.ndp_app_info);
4946
4947 } else if (attr_type == NAN_ATTRIBUTE_RSP_CODE) {
4948 ALOGI("response code %u\n", (NanDataPathResponseCode) it.get_u8());
4949 ndp_create_confirmation_event.rsp_code =
4950 (NanDataPathResponseCode)it.get_u8();
4951 }
4952 }
4953
4954 GET_NAN_HANDLE(info)->mHandlers.EventDataConfirm(&ndp_create_confirmation_event);
4955 break;
4956 }
4957 case NAN_EVENT_DATA_END: {
4958 ALOGI("Received NAN_EVENT_DATA_END\n");
4959 NanDataPathEndInd ndp_end_event;
4960 memset(&ndp_end_event, 0, sizeof(NanDataPathEndInd));
4961 u8 count = 0;
4962
4963 for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
4964 attr_type = it.get_type();
4965 if (attr_type == NAN_ATTRIBUTE_INST_COUNT) {
4966 ALOGI("ndp count: %u\n", it.get_u8());
4967 ndp_end_event.num_ndp_instances = it.get_u8();
4968 count = it.get_u8();
4969 } else if (attr_type == NAN_ATTRIBUTE_NDP_ID) {
4970 ALOGI("count: %u\n", count);
4971 while (count) {
4972 ndp_end_event.ndp_instance_id[count-1] = it.get_u32();
4973 ALOGI("ndp id: %u\n", ndp_end_event.ndp_instance_id[count-1]);
4974 count -= 1;
4975 }
4976 } else {
4977 ALOGI("Unknown attr_type: %s\n", NanAttrToString(attr_type));
4978 }
4979 }
4980
4981 GET_NAN_HANDLE(info)->mHandlers.EventDataEnd(&ndp_end_event);
4982 break;
4983 }
4984 case NAN_EVENT_TRANSMIT_FOLLOWUP_IND: {
4985 ALOGI("Received NAN_EVENT_TRANSMIT_FOLLOWUP_IND\n");
4986 NanTransmitFollowupInd followup_ind;
4987 memset(&followup_ind, 0, sizeof(NanTransmitFollowupInd));
4988
4989 for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
4990 attr_type = it.get_type();
4991 if (attr_type == NAN_ATTRIBUTE_TRANSAC_ID) {
4992 followup_ind.id = it.get_u16();
4993 } else if (attr_type == NAN_ATTRIBUTE_STATUS) {
4994 followup_ind.reason = (NanStatusType)it.get_u8();
4995 } else if (attr_type == NAN_ATTRIBUTE_REASON) {
4996 u8 len = min(it.get_len(), sizeof(followup_ind.nan_reason));
4997 memcpy(followup_ind.nan_reason, it.get_data(), len);
4998 ALOGI("nan transmit followup ind: reason: %s, len = %d\n",
4999 followup_ind.nan_reason, len);
5000 }
5001 }
5002
5003 GET_NAN_HANDLE(info)->mHandlers.EventTransmitFollowup(&followup_ind);
5004 break;
5005 }
5006 case NAN_EVENT_UNKNOWN:
5007 ALOGI("Received NAN_EVENT_UNKNOWN\n");
5008 break;
5009 } // end-of-switch
5010 return NL_SKIP;
5011 }
5012 };
5013
5014 /* To see event prints in console */
nan_event_check_request(transaction_id id,wifi_interface_handle iface)5015 wifi_error nan_event_check_request(transaction_id id, wifi_interface_handle iface)
5016 {
5017 NanEventCap *cmd = new NanEventCap(iface, id);
5018 if (cmd == NULL) {
5019 return WIFI_ERROR_NOT_SUPPORTED;
5020 }
5021 return (wifi_error)cmd->start();
5022 }
5023
5024 /* Create NAN Data Interface */
nan_data_interface_create(transaction_id id,wifi_interface_handle iface,char * iface_name)5025 wifi_error nan_data_interface_create(transaction_id id,
5026 wifi_interface_handle iface, char* iface_name)
5027 {
5028 wifi_error ret = WIFI_SUCCESS;
5029 NAN_DBG_ENTER();
5030
5031 NanRequestType cmdType = NAN_DATA_PATH_IFACE_CREATE;
5032 NanDataPathPrimitive *cmd =
5033 new NanDataPathPrimitive(iface, id, (void *)iface_name, cmdType);
5034 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
5035
5036 ret = (wifi_error)cmd->open();
5037 if (ret != WIFI_SUCCESS) {
5038 ALOGE("%s : failed in open, error = %d\n", __func__, ret);
5039 }
5040 cmd->releaseRef();
5041
5042 NAN_DBG_EXIT();
5043 return ret;
5044 }
5045
5046 /* Delete NAN Data Interface */
nan_data_interface_delete(transaction_id id,wifi_interface_handle iface,char * iface_name)5047 wifi_error nan_data_interface_delete(transaction_id id,
5048 wifi_interface_handle iface, char* iface_name)
5049 {
5050 wifi_error ret = WIFI_SUCCESS;
5051 NAN_DBG_ENTER();
5052
5053 NanRequestType cmdType = NAN_DATA_PATH_IFACE_DELETE;
5054 NanDataPathPrimitive *cmd =
5055 new NanDataPathPrimitive(iface, id, (void *)iface_name, cmdType);
5056 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
5057
5058 ret = (wifi_error)cmd->open();
5059 if (ret != WIFI_SUCCESS) {
5060 ALOGE("%s : failed in open, error = %d\n", __func__, ret);
5061 }
5062 cmd->releaseRef();
5063
5064 NAN_DBG_EXIT();
5065 return ret;
5066 }
5067
5068 /* Initiate a NDP session: Initiator */
nan_data_request_initiator(transaction_id id,wifi_interface_handle iface,NanDataPathInitiatorRequest * msg)5069 wifi_error nan_data_request_initiator(transaction_id id,
5070 wifi_interface_handle iface, NanDataPathInitiatorRequest* msg)
5071 {
5072 wifi_error ret = WIFI_SUCCESS;
5073
5074 NAN_DBG_ENTER();
5075 NanRequestType cmdType;
5076 NanDataPathPrimitive *cmd = NULL;
5077
5078 #ifdef CONFIG_BRCM
5079 dump_NanDataPathInitiatorRequest(msg);
5080 #endif /* CONFIG_BRCM */
5081 counters.dp_req++;
5082 if (msg->service_name_len) {
5083 if (strncmp(NAN_OOB_INTEROP_SVC_NAME,
5084 (char*)msg->service_name, msg->service_name_len) == 0) {
5085 ALOGI("Use Hardcoded svc_hash\n");
5086 msg->service_name_len = NAN_SVC_HASH_SIZE;
5087 memcpy(msg->service_name, NAN_OOB_INTEROP_SVC_HASH, NAN_SVC_HASH_SIZE);
5088 } else {
5089 u8 svc_hash[NAN_SVC_HASH_SIZE];
5090
5091 ret = (wifi_error)get_svc_hash(msg->service_name, msg->service_name_len,
5092 svc_hash, NAN_SVC_HASH_SIZE);
5093 if (ret < 0) {
5094 ALOGE("%s: Failed to get hashed svc name\n", __func__);
5095 goto done;
5096 }
5097
5098 ALOGI("Created svc_hash\n");
5099 msg->service_name_len = NAN_SVC_HASH_SIZE;
5100 memcpy(msg->service_name, svc_hash, msg->service_name_len);
5101 }
5102 } else if (msg->key_info.key_type == NAN_SECURITY_KEY_INPUT_PASSPHRASE) {
5103 NanDataPathSecInfoRequest msg_sec_info;
5104 if (msg->requestor_instance_id == 0) {
5105 ALOGE("Invalid Pub ID = %d, Mandatory param is missing\n", msg->requestor_instance_id);
5106 ret = WIFI_ERROR_INVALID_ARGS;
5107 goto done;
5108 } else {
5109 ALOGI("Pub ID = %d, Mandatory param is present\n", msg->requestor_instance_id);
5110 }
5111 if (ETHER_ISNULLADDR(msg->peer_disc_mac_addr)) {
5112 ALOGE("Invalid Pub NMI, Mandatory param is missing\n");
5113 ret = WIFI_ERROR_INVALID_ARGS;
5114 goto done;
5115 }
5116
5117 msg_sec_info.requestor_instance_id = msg->requestor_instance_id;
5118 memcpy(msg_sec_info.peer_disc_mac_addr, msg->peer_disc_mac_addr, NAN_MAC_ADDR_LEN);
5119 msg_sec_info.ndp_instance_id = 0;
5120 cmdType = NAN_DATA_PATH_SEC_INFO;
5121 cmd = new NanDataPathPrimitive(iface, id, (void *)&msg_sec_info, cmdType);
5122 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
5123 ret = (wifi_error)cmd->open();
5124 if (ret != WIFI_SUCCESS) {
5125 ALOGE("%s : failed in start, error = %d\n", __func__, ret);
5126 goto done;
5127 }
5128 memcpy(msg->service_name, cmd->mSvcHash, NAN_SVC_HASH_SIZE);
5129 }
5130 /* free old command */
5131 if (cmd) {
5132 cmd->releaseRef();
5133 }
5134 cmdType = NAN_DATA_PATH_INIT_REQUEST;
5135 cmd = new NanDataPathPrimitive(iface, id, (void *)msg, cmdType);
5136 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
5137 ret = (wifi_error)cmd->open();
5138 if (ret != WIFI_SUCCESS) {
5139 ALOGE("%s : failed in open, error = %d\n", __func__, ret);
5140 goto done;
5141 }
5142 done:
5143 if (cmd) {
5144 cmd->releaseRef();
5145 }
5146
5147 NAN_DBG_EXIT();
5148 return ret;
5149 }
5150
5151 /* Response to a data indication received corresponding to a NDP session.
5152 * An indication is received with a data request and the responder will send a data response
5153 */
nan_data_indication_response(transaction_id id,wifi_interface_handle iface,NanDataPathIndicationResponse * msg)5154 wifi_error nan_data_indication_response(transaction_id id,
5155 wifi_interface_handle iface, NanDataPathIndicationResponse* msg)
5156 {
5157 wifi_error ret = WIFI_SUCCESS;
5158 NAN_DBG_ENTER();
5159 NanRequestType cmdType;
5160 u8 pub_nmi[NAN_MAC_ADDR_LEN] = {0};
5161 NanDataPathPrimitive *cmd = NULL;
5162
5163 #ifdef CONFIG_BRCM
5164 dump_NanDataPathIndicationResponse(msg);
5165 #endif /* CONFIG_BRCM */
5166 counters.dp_resp++;
5167 if (msg->service_name_len) {
5168 if (strncmp(NAN_OOB_INTEROP_SVC_NAME,
5169 (char*)msg->service_name, msg->service_name_len) == 0) {
5170 ALOGI("Use Hardcoded svc_hash\n");
5171 msg->service_name_len = NAN_SVC_HASH_SIZE;
5172 memcpy(msg->service_name, NAN_OOB_INTEROP_SVC_HASH, NAN_SVC_HASH_SIZE);
5173 } else {
5174 u8 svc_hash[NAN_SVC_HASH_SIZE];
5175
5176 ret = (wifi_error)get_svc_hash(msg->service_name, msg->service_name_len,
5177 svc_hash, NAN_SVC_HASH_SIZE);
5178 if (ret < 0) {
5179 ALOGE("%s: Failed to get hashed svc name\n", __func__);
5180 goto done;
5181 }
5182 ALOGI("Created svc_hash\n");
5183 msg->service_name_len = NAN_SVC_HASH_SIZE;
5184 memcpy(msg->service_name, svc_hash, msg->service_name_len);
5185 }
5186 }
5187 if (msg->key_info.key_type == NAN_SECURITY_KEY_INPUT_PASSPHRASE) {
5188 NanDataPathSecInfoRequest msg_sec_info;
5189
5190 if (msg->ndp_instance_id == 0) {
5191 ALOGE("Invalid NDP ID, Mandatory info is not present\n");
5192 ret = WIFI_ERROR_INVALID_ARGS;
5193 goto done;
5194 } else {
5195 ALOGI("NDP ID = %d, Mandatory info is present\n", msg->ndp_instance_id);
5196 }
5197 msg_sec_info.ndp_instance_id = msg->ndp_instance_id;
5198 msg_sec_info.requestor_instance_id = 0;
5199 cmdType = NAN_DATA_PATH_SEC_INFO;
5200 cmd = new NanDataPathPrimitive(iface, id, (void *)&msg_sec_info, cmdType);
5201 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
5202
5203 ret = (wifi_error)cmd->open();
5204 if (ret != WIFI_SUCCESS) {
5205 ALOGE("%s : failed in start, error = %d\n", __func__, ret);
5206 goto done;
5207 }
5208
5209 if (ETHER_ISNULLADDR(cmd->mPubNmi)) {
5210 ALOGE("Invalid Pub NMI\n");
5211 ret = WIFI_ERROR_INVALID_ARGS;
5212 goto done;
5213 }
5214 memcpy(pub_nmi, cmd->mPubNmi, NAN_MAC_ADDR_LEN);
5215
5216 if (!msg->service_name_len) {
5217 if (SVCHASH_ISNULL(cmd->mSvcHash)) {
5218 ALOGE("Invalid svc_hash\n");
5219 ret = WIFI_ERROR_INVALID_ARGS;
5220 goto done;
5221 }
5222 memcpy(msg->service_name, cmd->mSvcHash, NAN_SVC_HASH_SIZE);
5223 }
5224 }
5225 /* free old command */
5226 if (cmd) {
5227 cmd->releaseRef();
5228 }
5229 cmdType = NAN_DATA_PATH_IND_RESPONSE;
5230 cmd = new NanDataPathPrimitive(iface, id, (void *)msg, cmdType);
5231 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
5232 memcpy(cmd->mPubNmi, pub_nmi, NAN_MAC_ADDR_LEN);
5233 ret = (wifi_error)cmd->open();
5234 if (ret != WIFI_SUCCESS) {
5235 ALOGE("%s : failed in open, error = %d\n", __func__, ret);
5236 goto done;
5237 }
5238
5239 done:
5240 if (cmd) {
5241 cmd->releaseRef();
5242 }
5243 NAN_DBG_EXIT();
5244 return ret;
5245 }
5246
5247 /* NDL termination request: from either Initiator/Responder */
nan_data_end(transaction_id id,wifi_interface_handle iface,NanDataPathEndRequest * msg)5248 wifi_error nan_data_end(transaction_id id,
5249 wifi_interface_handle iface, NanDataPathEndRequest* msg)
5250 {
5251 wifi_error ret = WIFI_SUCCESS;
5252 NanDataPathPrimitive *cmd;
5253 NanRequestType cmdType = NAN_DATA_PATH_END;
5254 NAN_DBG_ENTER();
5255
5256 cmd = new NanDataPathPrimitive(iface, id, (void *)msg, cmdType);
5257 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
5258
5259 ret = (wifi_error)cmd->open();
5260 if (ret != WIFI_SUCCESS) {
5261 ALOGE("%s : failed in open, error = %d\n", __func__, ret);
5262 }
5263 cmd->releaseRef();
5264 NAN_DBG_EXIT();
5265 return ret;
5266 }
5267