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