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