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