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