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