1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "sync.h"
18 #include <utils/Log.h>
19 #include "wifi_hal.h"
20 #include "nan_i.h"
21 #include "nancommand.h"
22 
putNanEnable(transaction_id id,const NanEnableRequest * pReq)23 wifi_error NanCommand::putNanEnable(transaction_id id, const NanEnableRequest *pReq)
24 {
25     wifi_error ret;
26     ALOGV("NAN_ENABLE");
27     size_t message_len = NAN_MAX_ENABLE_REQ_SIZE;
28 
29     if (pReq == NULL) {
30         cleanup();
31         return WIFI_ERROR_INVALID_ARGS;
32     }
33 
34     message_len += \
35         (
36           pReq->config_support_5g ? (SIZEOF_TLV_HDR + \
37           sizeof(pReq->support_5g_val)) : 0 \
38         ) + \
39         (
40           pReq->config_sid_beacon ? (SIZEOF_TLV_HDR + \
41           sizeof(pReq->sid_beacon_val)) : 0 \
42         ) + \
43         (
44           pReq->config_2dot4g_rssi_close ? (SIZEOF_TLV_HDR + \
45           sizeof(pReq->rssi_close_2dot4g_val)) : 0 \
46         ) + \
47         (
48           pReq->config_2dot4g_rssi_middle ? (SIZEOF_TLV_HDR + \
49           sizeof(pReq->rssi_middle_2dot4g_val)) : 0 \
50         ) + \
51         (
52           pReq->config_hop_count_limit ? (SIZEOF_TLV_HDR + \
53           sizeof(pReq->hop_count_limit_val)) : 0 \
54         ) + \
55         (
56           pReq->config_2dot4g_support ? (SIZEOF_TLV_HDR + \
57           sizeof(pReq->support_2dot4g_val)) : 0 \
58         ) + \
59         (
60           pReq->config_2dot4g_beacons ? (SIZEOF_TLV_HDR + \
61           sizeof(pReq->beacon_2dot4g_val)) : 0 \
62         ) + \
63         (
64           pReq->config_2dot4g_sdf ? (SIZEOF_TLV_HDR + \
65           sizeof(pReq->sdf_2dot4g_val)) : 0 \
66         ) + \
67         (
68           pReq->config_5g_beacons ? (SIZEOF_TLV_HDR + \
69           sizeof(pReq->beacon_5g_val)) : 0 \
70         ) + \
71         (
72           pReq->config_5g_sdf ? (SIZEOF_TLV_HDR + \
73           sizeof(pReq->sdf_5g_val)) : 0 \
74         ) + \
75         (
76           pReq->config_5g_rssi_close ? (SIZEOF_TLV_HDR + \
77           sizeof(pReq->rssi_close_5g_val)) : 0 \
78         ) + \
79         (
80           pReq->config_5g_rssi_middle ? (SIZEOF_TLV_HDR + \
81           sizeof(pReq->rssi_middle_5g_val)) : 0 \
82         ) + \
83         (
84           pReq->config_2dot4g_rssi_proximity ? (SIZEOF_TLV_HDR + \
85           sizeof(pReq->rssi_proximity_2dot4g_val)) : 0 \
86         ) + \
87         (
88           pReq->config_5g_rssi_close_proximity ? (SIZEOF_TLV_HDR + \
89           sizeof(pReq->rssi_close_proximity_5g_val)) : 0 \
90         ) + \
91         (
92           pReq->config_rssi_window_size ? (SIZEOF_TLV_HDR + \
93           sizeof(pReq->rssi_window_size_val)) : 0 \
94         ) + \
95         (
96           pReq->config_oui ? (SIZEOF_TLV_HDR + \
97           sizeof(pReq->oui_val)) : 0 \
98         ) + \
99         (
100           pReq->config_intf_addr ? (SIZEOF_TLV_HDR + \
101           sizeof(pReq->intf_addr_val)) : 0 \
102         ) + \
103         (
104           pReq->config_cluster_attribute_val ? (SIZEOF_TLV_HDR + \
105           sizeof(pReq->config_cluster_attribute_val)) : 0 \
106         ) + \
107         (
108           pReq->config_scan_params ? NAN_MAX_SOCIAL_CHANNELS *
109           (SIZEOF_TLV_HDR + sizeof(u32)) : 0 \
110         ) + \
111         (
112           pReq->config_random_factor_force ? (SIZEOF_TLV_HDR + \
113           sizeof(pReq->random_factor_force_val)) : 0 \
114         ) + \
115         (
116           pReq->config_hop_count_force ? (SIZEOF_TLV_HDR + \
117           sizeof(pReq->hop_count_force_val)) : 0 \
118         ) + \
119         (
120           pReq->config_24g_channel ? (SIZEOF_TLV_HDR + \
121           sizeof(u32)) : 0 \
122         ) + \
123         (
124           pReq->config_5g_channel ? (SIZEOF_TLV_HDR + \
125           sizeof(u32)) : 0 \
126         ) + \
127         (
128            pReq->config_dw.config_2dot4g_dw_band ? (SIZEOF_TLV_HDR + \
129            sizeof(u32)) : 0 \
130         ) + \
131         (
132            pReq->config_dw.config_5g_dw_band ? (SIZEOF_TLV_HDR + \
133            sizeof(u32)) : 0 \
134         ) + \
135         (
136            pReq->config_disc_mac_addr_randomization ? (SIZEOF_TLV_HDR + \
137            sizeof(u32)) : 0 \
138         ) + \
139         (
140            /* Always include cfg discovery indication TLV */
141            SIZEOF_TLV_HDR + sizeof(u32) \
142         ) + \
143         (
144           pReq->config_subscribe_sid_beacon ? (SIZEOF_TLV_HDR + \
145           sizeof(pReq->subscribe_sid_beacon_val)) : 0 \
146         ) + \
147         (
148            pReq->config_discovery_beacon_int ? (SIZEOF_TLV_HDR + \
149            sizeof(u32)) : 0 \
150         ) + \
151         (
152            pReq->config_nss ? (SIZEOF_TLV_HDR + \
153            sizeof(u32)) : 0 \
154         ) + \
155         (
156            pReq->config_enable_ranging ? (SIZEOF_TLV_HDR + \
157            sizeof(u32)) : 0 \
158         ) + \
159         (
160            pReq->config_dw_early_termination ? (SIZEOF_TLV_HDR + \
161            sizeof(u32)) : 0 \
162         );
163 
164     pNanEnableReqMsg pFwReq = (pNanEnableReqMsg)malloc(message_len);
165     if (pFwReq == NULL) {
166         cleanup();
167         return WIFI_ERROR_OUT_OF_MEMORY;
168     }
169 
170     ALOGV("Message Len %zu", message_len);
171     memset (pFwReq, 0, message_len);
172     pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
173     pFwReq->fwHeader.msgId = NAN_MSG_ID_ENABLE_REQ;
174     pFwReq->fwHeader.msgLen = message_len;
175     pFwReq->fwHeader.transactionId = id;
176 
177     u8* tlvs = pFwReq->ptlv;
178 
179     /* Write the TLVs to the message. */
180 
181     tlvs = addTlv(NAN_TLV_TYPE_CLUSTER_ID_LOW, sizeof(pReq->cluster_low),
182                   (const u8*)&pReq->cluster_low, tlvs);
183     tlvs = addTlv(NAN_TLV_TYPE_CLUSTER_ID_HIGH, sizeof(pReq->cluster_high),
184                   (const u8*)&pReq->cluster_high, tlvs);
185     tlvs = addTlv(NAN_TLV_TYPE_MASTER_PREFERENCE, sizeof(pReq->master_pref),
186                   (const u8*)&pReq->master_pref, tlvs);
187     if (pReq->config_support_5g) {
188         tlvs = addTlv(NAN_TLV_TYPE_5G_SUPPORT, sizeof(pReq->support_5g_val),
189                      (const u8*)&pReq->support_5g_val, tlvs);
190     }
191     if (pReq->config_sid_beacon) {
192         tlvs = addTlv(NAN_TLV_TYPE_SID_BEACON, sizeof(pReq->sid_beacon_val),
193                       (const u8*)&pReq->sid_beacon_val, tlvs);
194     }
195     if (pReq->config_2dot4g_rssi_close) {
196         tlvs = addTlv(NAN_TLV_TYPE_24G_RSSI_CLOSE,
197                       sizeof(pReq->rssi_close_2dot4g_val),
198                       (const u8*)&pReq->rssi_close_2dot4g_val, tlvs);
199     }
200     if (pReq->config_2dot4g_rssi_middle) {
201         tlvs = addTlv(NAN_TLV_TYPE_24G_RSSI_MIDDLE,
202                       sizeof(pReq->rssi_middle_2dot4g_val),
203                       (const u8*)&pReq->rssi_middle_2dot4g_val, tlvs);
204     }
205     if (pReq->config_hop_count_limit) {
206         tlvs = addTlv(NAN_TLV_TYPE_HOP_COUNT_LIMIT,
207                       sizeof(pReq->hop_count_limit_val),
208                       (const u8*)&pReq->hop_count_limit_val, tlvs);
209     }
210     if (pReq->config_2dot4g_support) {
211         tlvs = addTlv(NAN_TLV_TYPE_24G_SUPPORT, sizeof(pReq->support_2dot4g_val),
212                       (const u8*)&pReq->support_2dot4g_val, tlvs);
213     }
214     if (pReq->config_2dot4g_beacons) {
215         tlvs = addTlv(NAN_TLV_TYPE_24G_BEACON, sizeof(pReq->beacon_2dot4g_val),
216                       (const u8*)&pReq->beacon_2dot4g_val, tlvs);
217     }
218     if (pReq->config_2dot4g_sdf) {
219         tlvs = addTlv(NAN_TLV_TYPE_24G_SDF, sizeof(pReq->sdf_2dot4g_val),
220                       (const u8*)&pReq->sdf_2dot4g_val, tlvs);
221     }
222     if (pReq->config_5g_beacons) {
223         tlvs = addTlv(NAN_TLV_TYPE_5G_BEACON, sizeof(pReq->beacon_5g_val),
224                       (const u8*)&pReq->beacon_5g_val, tlvs);
225     }
226     if (pReq->config_5g_sdf) {
227         tlvs = addTlv(NAN_TLV_TYPE_5G_SDF, sizeof(pReq->sdf_5g_val),
228                       (const u8*)&pReq->sdf_5g_val, tlvs);
229     }
230     if (pReq->config_2dot4g_rssi_proximity) {
231         tlvs = addTlv(NAN_TLV_TYPE_24G_RSSI_CLOSE_PROXIMITY,
232                       sizeof(pReq->rssi_proximity_2dot4g_val),
233                       (const u8*)&pReq->rssi_proximity_2dot4g_val, tlvs);
234     }
235     /* Add the support of sending 5G RSSI values */
236     if (pReq->config_5g_rssi_close) {
237         tlvs = addTlv(NAN_TLV_TYPE_5G_RSSI_CLOSE, sizeof(pReq->rssi_close_5g_val),
238                       (const u8*)&pReq->rssi_close_5g_val, tlvs);
239     }
240     if (pReq->config_5g_rssi_middle) {
241         tlvs = addTlv(NAN_TLV_TYPE_5G_RSSI_MIDDLE, sizeof(pReq->rssi_middle_5g_val),
242                       (const u8*)&pReq->rssi_middle_5g_val, tlvs);
243     }
244     if (pReq->config_5g_rssi_close_proximity) {
245         tlvs = addTlv(NAN_TLV_TYPE_5G_RSSI_CLOSE_PROXIMITY,
246                       sizeof(pReq->rssi_close_proximity_5g_val),
247                       (const u8*)&pReq->rssi_close_proximity_5g_val, tlvs);
248     }
249     if (pReq->config_rssi_window_size) {
250         tlvs = addTlv(NAN_TLV_TYPE_RSSI_AVERAGING_WINDOW_SIZE, sizeof(pReq->rssi_window_size_val),
251                       (const u8*)&pReq->rssi_window_size_val, tlvs);
252     }
253     if (pReq->config_oui) {
254         tlvs = addTlv(NAN_TLV_TYPE_CLUSTER_OUI_NETWORK_ID, sizeof(pReq->oui_val),
255                       (const u8*)&pReq->oui_val, tlvs);
256     }
257     if (pReq->config_intf_addr) {
258         tlvs = addTlv(NAN_TLV_TYPE_SOURCE_MAC_ADDRESS, sizeof(pReq->intf_addr_val),
259                       (const u8*)&pReq->intf_addr_val[0], tlvs);
260     }
261     if (pReq->config_cluster_attribute_val) {
262         tlvs = addTlv(NAN_TLV_TYPE_CLUSTER_ATTRIBUTE_IN_SDF, sizeof(pReq->config_cluster_attribute_val),
263                       (const u8*)&pReq->config_cluster_attribute_val, tlvs);
264     }
265     if (pReq->config_scan_params) {
266         u32 socialChannelParamVal[NAN_MAX_SOCIAL_CHANNELS];
267         /* Fill the social channel param */
268         fillNanSocialChannelParamVal(&pReq->scan_params_val,
269                                      socialChannelParamVal);
270         int i;
271         for (i = 0; i < NAN_MAX_SOCIAL_CHANNELS; i++) {
272             tlvs = addTlv(NAN_TLV_TYPE_SOCIAL_CHANNEL_SCAN_PARAMS,
273                           sizeof(socialChannelParamVal[i]),
274                           (const u8*)&socialChannelParamVal[i], tlvs);
275         }
276     }
277     if (pReq->config_random_factor_force) {
278         tlvs = addTlv(NAN_TLV_TYPE_RANDOM_FACTOR_FORCE,
279                       sizeof(pReq->random_factor_force_val),
280                       (const u8*)&pReq->random_factor_force_val, tlvs);
281     }
282     if (pReq->config_hop_count_force) {
283         tlvs = addTlv(NAN_TLV_TYPE_HOP_COUNT_FORCE,
284                       sizeof(pReq->hop_count_force_val),
285                       (const u8*)&pReq->hop_count_force_val, tlvs);
286     }
287     if (pReq->config_24g_channel) {
288         tlvs = addTlv(NAN_TLV_TYPE_24G_CHANNEL,
289                       sizeof(u32),
290                       (const u8*)&pReq->channel_24g_val, tlvs);
291     }
292     if (pReq->config_5g_channel) {
293         tlvs = addTlv(NAN_TLV_TYPE_5G_CHANNEL,
294                       sizeof(u32),
295                       (const u8*)&pReq->channel_5g_val, tlvs);
296     }
297     if (pReq->config_dw.config_2dot4g_dw_band) {
298         tlvs = addTlv(NAN_TLV_TYPE_2G_COMMITTED_DW,
299                       sizeof(pReq->config_dw.dw_2dot4g_interval_val),
300                       (const u8*)&pReq->config_dw.dw_2dot4g_interval_val, tlvs);
301     }
302     if (pReq->config_dw.config_5g_dw_band) {
303         tlvs = addTlv(NAN_TLV_TYPE_5G_COMMITTED_DW,
304                       sizeof(pReq->config_dw.dw_5g_interval_val),
305                       (const u8*)&pReq->config_dw.dw_5g_interval_val, tlvs);
306     }
307     if (pReq->config_disc_mac_addr_randomization) {
308         tlvs = addTlv(NAN_TLV_TYPE_DISC_MAC_ADDR_RANDOM_INTERVAL,
309                       sizeof(u32),
310                       (const u8*)&pReq->disc_mac_addr_rand_interval_sec, tlvs);
311     }
312 
313     u32 config_discovery_indications;
314     config_discovery_indications = (u32)pReq->discovery_indication_cfg;
315     tlvs = addTlv(NAN_TLV_TYPE_CONFIG_DISCOVERY_INDICATIONS,
316                   sizeof(u32),
317                   (const u8*)&config_discovery_indications, tlvs);
318 
319     if (pReq->config_subscribe_sid_beacon) {
320         tlvs = addTlv(NAN_TLV_TYPE_SUBSCRIBE_SID_BEACON,
321                       sizeof(pReq->subscribe_sid_beacon_val),
322                       (const u8*)&pReq->subscribe_sid_beacon_val, tlvs);
323     }
324     if (pReq->config_discovery_beacon_int) {
325         tlvs = addTlv(NAN_TLV_TYPE_DB_INTERVAL, sizeof(u32),
326                       (const u8*)&pReq->discovery_beacon_interval, tlvs);
327     }
328     if (pReq->config_nss) {
329         tlvs = addTlv(NAN_TLV_TYPE_TX_RX_CHAINS, sizeof(u32),
330                       (const u8*)&pReq->nss, tlvs);
331     }
332     if (pReq->config_enable_ranging) {
333         tlvs = addTlv(NAN_TLV_TYPE_ENABLE_DEVICE_RANGING, sizeof(u32),
334                       (const u8*)&pReq->enable_ranging, tlvs);
335     }
336     if (pReq->config_dw_early_termination) {
337         tlvs = addTlv(NAN_TLV_TYPE_DW_EARLY_TERMINATION, sizeof(u32),
338                       (const u8*)&pReq->enable_dw_termination, tlvs);
339     }
340 
341     mVendorData = (char*)pFwReq;
342     mDataLen = message_len;
343 
344     //Insert the vendor specific data
345     ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
346     if (ret != WIFI_SUCCESS) {
347         ALOGE("%s: put_bytes Error:%d",__func__, ret);
348         cleanup();
349         return ret;
350     }
351     hexdump(mVendorData, mDataLen);
352     return ret;
353 }
354 
putNanDisable(transaction_id id)355 wifi_error NanCommand::putNanDisable(transaction_id id)
356 {
357     wifi_error ret;
358     ALOGV("NAN_DISABLE");
359     size_t message_len = sizeof(NanDisableReqMsg);
360 
361     pNanDisableReqMsg pFwReq = (pNanDisableReqMsg)malloc(message_len);
362     if (pFwReq == NULL) {
363         cleanup();
364         return WIFI_ERROR_OUT_OF_MEMORY;
365     }
366 
367     ALOGV("Message Len %zu", message_len);
368     memset (pFwReq, 0, message_len);
369     pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
370     pFwReq->fwHeader.msgId = NAN_MSG_ID_DISABLE_REQ;
371     pFwReq->fwHeader.msgLen = message_len;
372     pFwReq->fwHeader.transactionId = id;
373 
374     mVendorData = (char*)pFwReq;
375     mDataLen = message_len;
376 
377     ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
378     if (ret != WIFI_SUCCESS) {
379         ALOGE("%s: put_bytes Error:%d",__func__, ret);
380         cleanup();
381         return ret;
382     }
383     hexdump(mVendorData, mDataLen);
384     return ret;
385 }
386 
putNanConfig(transaction_id id,const NanConfigRequest * pReq)387 wifi_error NanCommand::putNanConfig(transaction_id id, const NanConfigRequest *pReq)
388 {
389     wifi_error ret;
390     ALOGV("NAN_CONFIG");
391     size_t message_len = 0;
392     int idx = 0;
393 
394     if (pReq == NULL ||
395         pReq->num_config_discovery_attr > NAN_MAX_POSTDISCOVERY_LEN) {
396         cleanup();
397         return WIFI_ERROR_INVALID_ARGS;
398     }
399 
400     message_len = sizeof(NanMsgHeader);
401 
402     message_len += \
403         (
404            pReq->config_sid_beacon ? (SIZEOF_TLV_HDR + \
405            sizeof(pReq->sid_beacon)) : 0 \
406         ) + \
407         (
408            pReq->config_master_pref ? (SIZEOF_TLV_HDR + \
409            sizeof(pReq->master_pref)) : 0 \
410         ) + \
411         (
412            pReq->config_rssi_proximity ? (SIZEOF_TLV_HDR + \
413            sizeof(pReq->rssi_proximity)) : 0 \
414         ) + \
415         (
416            pReq->config_5g_rssi_close_proximity ? (SIZEOF_TLV_HDR + \
417            sizeof(pReq->rssi_close_proximity_5g_val)) : 0 \
418         ) + \
419         (
420            pReq->config_rssi_window_size ? (SIZEOF_TLV_HDR + \
421            sizeof(pReq->rssi_window_size_val)) : 0 \
422         ) + \
423         (
424            pReq->config_cluster_attribute_val ? (SIZEOF_TLV_HDR + \
425            sizeof(pReq->config_cluster_attribute_val)) : 0 \
426         ) + \
427         (
428            pReq->config_scan_params ? NAN_MAX_SOCIAL_CHANNELS *
429            (SIZEOF_TLV_HDR + sizeof(u32)) : 0 \
430         ) + \
431         (
432            pReq->config_random_factor_force ? (SIZEOF_TLV_HDR + \
433            sizeof(pReq->random_factor_force_val)) : 0 \
434         ) + \
435         (
436            pReq->config_hop_count_force ? (SIZEOF_TLV_HDR + \
437            sizeof(pReq->hop_count_force_val)) : 0 \
438         ) + \
439         (
440            pReq->config_conn_capability ? (SIZEOF_TLV_HDR + \
441            sizeof(u32)) : 0 \
442         ) + \
443         (
444            pReq->config_dw.config_2dot4g_dw_band ? (SIZEOF_TLV_HDR + \
445            sizeof(u32)) : 0 \
446         ) + \
447         (
448            pReq->config_dw.config_5g_dw_band ? (SIZEOF_TLV_HDR + \
449            sizeof(u32)) : 0 \
450         ) + \
451         (
452            pReq->config_disc_mac_addr_randomization ? (SIZEOF_TLV_HDR + \
453            sizeof(u32)) : 0 \
454         ) + \
455         (
456           pReq->config_subscribe_sid_beacon ? (SIZEOF_TLV_HDR + \
457           sizeof(pReq->subscribe_sid_beacon_val)) : 0 \
458         ) + \
459         (
460            /* Always include cfg discovery indication TLV */
461            SIZEOF_TLV_HDR + sizeof(u32) \
462         ) + \
463         (
464            pReq->config_discovery_beacon_int ? (SIZEOF_TLV_HDR + \
465            sizeof(u32)) : 0 \
466         ) + \
467         (
468            pReq->config_nss ? (SIZEOF_TLV_HDR + \
469            sizeof(u32)) : 0 \
470         ) + \
471         (
472            pReq->config_enable_ranging ? (SIZEOF_TLV_HDR + \
473            sizeof(u32)) : 0 \
474         ) + \
475         (
476            pReq->config_dw_early_termination ? (SIZEOF_TLV_HDR + \
477            sizeof(u32)) : 0 \
478         );
479 
480     if (pReq->num_config_discovery_attr) {
481         for (idx = 0; idx < pReq->num_config_discovery_attr; idx ++) {
482             message_len += SIZEOF_TLV_HDR +\
483                 calcNanTransmitPostDiscoverySize(&pReq->discovery_attr_val[idx]);
484         }
485     }
486 
487     if (pReq->config_fam && \
488         calcNanFurtherAvailabilityMapSize(&pReq->fam_val)) {
489         message_len += (SIZEOF_TLV_HDR + \
490            calcNanFurtherAvailabilityMapSize(&pReq->fam_val));
491     }
492 
493     pNanConfigurationReqMsg pFwReq = (pNanConfigurationReqMsg)malloc(message_len);
494     if (pFwReq == NULL) {
495         cleanup();
496         return WIFI_ERROR_OUT_OF_MEMORY;
497     }
498 
499     ALOGV("Message Len %zu", message_len);
500     memset (pFwReq, 0, message_len);
501     pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
502     pFwReq->fwHeader.msgId = NAN_MSG_ID_CONFIGURATION_REQ;
503     pFwReq->fwHeader.msgLen = message_len;
504     pFwReq->fwHeader.transactionId = id;
505 
506     u8* tlvs = pFwReq->ptlv;
507     if (pReq->config_sid_beacon) {
508         tlvs = addTlv(NAN_TLV_TYPE_SID_BEACON, sizeof(pReq->sid_beacon),
509                       (const u8*)&pReq->sid_beacon, tlvs);
510     }
511     if (pReq->config_master_pref) {
512         tlvs = addTlv(NAN_TLV_TYPE_MASTER_PREFERENCE, sizeof(pReq->master_pref),
513                       (const u8*)&pReq->master_pref, tlvs);
514     }
515     if (pReq->config_rssi_window_size) {
516         tlvs = addTlv(NAN_TLV_TYPE_RSSI_AVERAGING_WINDOW_SIZE, sizeof(pReq->rssi_window_size_val),
517                       (const u8*)&pReq->rssi_window_size_val, tlvs);
518     }
519     if (pReq->config_rssi_proximity) {
520         tlvs = addTlv(NAN_TLV_TYPE_24G_RSSI_CLOSE_PROXIMITY, sizeof(pReq->rssi_proximity),
521                       (const u8*)&pReq->rssi_proximity, tlvs);
522     }
523     if (pReq->config_5g_rssi_close_proximity) {
524         tlvs = addTlv(NAN_TLV_TYPE_5G_RSSI_CLOSE_PROXIMITY,
525                       sizeof(pReq->rssi_close_proximity_5g_val),
526                       (const u8*)&pReq->rssi_close_proximity_5g_val, tlvs);
527     }
528     if (pReq->config_cluster_attribute_val) {
529         tlvs = addTlv(NAN_TLV_TYPE_CLUSTER_ATTRIBUTE_IN_SDF, sizeof(pReq->config_cluster_attribute_val),
530                       (const u8*)&pReq->config_cluster_attribute_val, tlvs);
531     }
532     if (pReq->config_scan_params) {
533         u32 socialChannelParamVal[NAN_MAX_SOCIAL_CHANNELS];
534         /* Fill the social channel param */
535         fillNanSocialChannelParamVal(&pReq->scan_params_val,
536                                  socialChannelParamVal);
537         int i;
538         for (i = 0; i < NAN_MAX_SOCIAL_CHANNELS; i++) {
539             tlvs = addTlv(NAN_TLV_TYPE_SOCIAL_CHANNEL_SCAN_PARAMS,
540                           sizeof(socialChannelParamVal[i]),
541                           (const u8*)&socialChannelParamVal[i], tlvs);
542         }
543     }
544     if (pReq->config_random_factor_force) {
545         tlvs = addTlv(NAN_TLV_TYPE_RANDOM_FACTOR_FORCE,
546                       sizeof(pReq->random_factor_force_val),
547                       (const u8*)&pReq->random_factor_force_val, tlvs);
548     }
549     if (pReq->config_hop_count_force) {
550         tlvs = addTlv(NAN_TLV_TYPE_HOP_COUNT_FORCE,
551                       sizeof(pReq->hop_count_force_val),
552                       (const u8*)&pReq->hop_count_force_val, tlvs);
553     }
554     if (pReq->config_conn_capability) {
555         u32 val = \
556         getNanTransmitPostConnectivityCapabilityVal(&pReq->conn_capability_val);
557         tlvs = addTlv(NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_TRANSMIT,
558                       sizeof(val), (const u8*)&val, tlvs);
559     }
560     if (pReq->num_config_discovery_attr) {
561         for (idx = 0; idx < pReq->num_config_discovery_attr; idx ++) {
562             fillNanTransmitPostDiscoveryVal(&pReq->discovery_attr_val[idx],
563                                             (u8*)(tlvs + SIZEOF_TLV_HDR));
564             tlvs = addTlv(NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_TRANSMIT,
565                           calcNanTransmitPostDiscoverySize(
566                               &pReq->discovery_attr_val[idx]),
567                           (const u8*)(tlvs + SIZEOF_TLV_HDR), tlvs);
568         }
569     }
570     if (pReq->config_fam && \
571         calcNanFurtherAvailabilityMapSize(&pReq->fam_val)) {
572         fillNanFurtherAvailabilityMapVal(&pReq->fam_val,
573                                         (u8*)(tlvs + SIZEOF_TLV_HDR));
574         tlvs = addTlv(NAN_TLV_TYPE_FURTHER_AVAILABILITY_MAP,
575                       calcNanFurtherAvailabilityMapSize(&pReq->fam_val),
576                       (const u8*)(tlvs + SIZEOF_TLV_HDR), tlvs);
577     }
578     if (pReq->config_dw.config_2dot4g_dw_band) {
579         tlvs = addTlv(NAN_TLV_TYPE_2G_COMMITTED_DW,
580                       sizeof(pReq->config_dw.dw_2dot4g_interval_val),
581                       (const u8*)&pReq->config_dw.dw_2dot4g_interval_val, tlvs);
582     }
583     if (pReq->config_dw.config_5g_dw_band) {
584         tlvs = addTlv(NAN_TLV_TYPE_5G_COMMITTED_DW,
585                       sizeof(pReq->config_dw.dw_5g_interval_val),
586                       (const u8*)&pReq->config_dw.dw_5g_interval_val, tlvs);
587     }
588     if (pReq->config_disc_mac_addr_randomization) {
589         tlvs = addTlv(NAN_TLV_TYPE_DISC_MAC_ADDR_RANDOM_INTERVAL,
590                       sizeof(u32),
591                       (const u8*)&pReq->disc_mac_addr_rand_interval_sec, tlvs);
592     }
593     if (pReq->config_subscribe_sid_beacon) {
594         tlvs = addTlv(NAN_TLV_TYPE_SUBSCRIBE_SID_BEACON,
595                       sizeof(pReq->subscribe_sid_beacon_val),
596                       (const u8*)&pReq->subscribe_sid_beacon_val, tlvs);
597     }
598     if (pReq->config_discovery_beacon_int) {
599         tlvs = addTlv(NAN_TLV_TYPE_DB_INTERVAL, sizeof(u32),
600                       (const u8*)&pReq->discovery_beacon_interval, tlvs);
601     }
602 
603     u32 config_discovery_indications;
604     config_discovery_indications = (u32)(pReq->discovery_indication_cfg);
605     /* Always include the discovery cfg TLV as there is no cfg flag */
606     tlvs = addTlv(NAN_TLV_TYPE_CONFIG_DISCOVERY_INDICATIONS,
607                   sizeof(u32),
608                   (const u8*)&config_discovery_indications, tlvs);
609 
610     if (pReq->config_nss) {
611         tlvs = addTlv(NAN_TLV_TYPE_TX_RX_CHAINS, sizeof(u32),
612                       (const u8*)&pReq->nss, tlvs);
613     }
614     if (pReq->config_enable_ranging) {
615         tlvs = addTlv(NAN_TLV_TYPE_ENABLE_DEVICE_RANGING, sizeof(u32),
616                       (const u8*)&pReq->enable_ranging, tlvs);
617     }
618     if (pReq->config_dw_early_termination) {
619         tlvs = addTlv(NAN_TLV_TYPE_DW_EARLY_TERMINATION, sizeof(u32),
620                       (const u8*)&pReq->enable_dw_termination, tlvs);
621     }
622 
623     mVendorData = (char*)pFwReq;
624     mDataLen = message_len;
625 
626     ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
627     if (ret != WIFI_SUCCESS) {
628         ALOGE("%s: put_bytes Error:%d",__func__, ret);
629         cleanup();
630         return ret;
631     }
632     hexdump(mVendorData, mDataLen);
633     return ret;
634 }
635 
putNanPublish(transaction_id id,const NanPublishRequest * pReq)636 wifi_error NanCommand::putNanPublish(transaction_id id, const NanPublishRequest *pReq)
637 {
638     wifi_error ret;
639     ALOGV("NAN_PUBLISH");
640     if (pReq == NULL) {
641         cleanup();
642         return WIFI_ERROR_INVALID_ARGS;
643     }
644 
645     size_t message_len =
646         sizeof(NanMsgHeader) + sizeof(NanPublishServiceReqParams) +
647         (pReq->service_name_len ? SIZEOF_TLV_HDR + pReq->service_name_len : 0) +
648         (pReq->service_specific_info_len ? SIZEOF_TLV_HDR + pReq->service_specific_info_len : 0) +
649         (pReq->rx_match_filter_len ? SIZEOF_TLV_HDR + pReq->rx_match_filter_len : 0) +
650         (pReq->tx_match_filter_len ? SIZEOF_TLV_HDR + pReq->tx_match_filter_len : 0) +
651         (SIZEOF_TLV_HDR + sizeof(NanServiceAcceptPolicy)) +
652         (pReq->cipher_type ? SIZEOF_TLV_HDR + sizeof(NanCsidType) : 0) +
653         ((pReq->sdea_params.config_nan_data_path || pReq->sdea_params.security_cfg ||
654           pReq->sdea_params.ranging_state || pReq->sdea_params.range_report ||
655           pReq->sdea_params.qos_cfg) ?
656           SIZEOF_TLV_HDR + sizeof(NanFWSdeaCtrlParams) : 0) +
657         ((pReq->ranging_cfg.ranging_interval_msec || pReq->ranging_cfg.config_ranging_indications ||
658           pReq->ranging_cfg.distance_ingress_mm || pReq->ranging_cfg.distance_egress_mm) ?
659           SIZEOF_TLV_HDR + sizeof(NanFWRangeConfigParams) : 0) +
660         ((pReq->range_response_cfg.publish_id ||
661           pReq->range_response_cfg.ranging_response) ?
662           SIZEOF_TLV_HDR + sizeof(NanFWRangeReqMsg) : 0)  +
663         (pReq->sdea_service_specific_info_len ? SIZEOF_TLV_HDR + pReq->sdea_service_specific_info_len : 0);
664 
665     if ((pReq->key_info.key_type ==  NAN_SECURITY_KEY_INPUT_PMK) &&
666         (pReq->key_info.body.pmk_info.pmk_len == NAN_PMK_INFO_LEN))
667         message_len += SIZEOF_TLV_HDR + NAN_PMK_INFO_LEN;
668     else if ((pReq->key_info.key_type ==  NAN_SECURITY_KEY_INPUT_PASSPHRASE) &&
669              (pReq->key_info.body.passphrase_info.passphrase_len >=
670               NAN_SECURITY_MIN_PASSPHRASE_LEN) &&
671              (pReq->key_info.body.passphrase_info.passphrase_len <=
672               NAN_SECURITY_MAX_PASSPHRASE_LEN))
673         message_len += SIZEOF_TLV_HDR +
674                        pReq->key_info.body.passphrase_info.passphrase_len;
675 
676     pNanPublishServiceReqMsg pFwReq = (pNanPublishServiceReqMsg)malloc(message_len);
677     if (pFwReq == NULL) {
678         cleanup();
679         return WIFI_ERROR_OUT_OF_MEMORY;
680     }
681 
682     ALOGV("Message Len %zu", message_len);
683     memset(pFwReq, 0, message_len);
684     pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
685     pFwReq->fwHeader.msgId = NAN_MSG_ID_PUBLISH_SERVICE_REQ;
686     pFwReq->fwHeader.msgLen = message_len;
687     if (pReq->publish_id == 0) {
688         pFwReq->fwHeader.handle = 0xFFFF;
689     } else {
690         pFwReq->fwHeader.handle = pReq->publish_id;
691     }
692     pFwReq->fwHeader.transactionId = id;
693 
694     pFwReq->publishServiceReqParams.ttl = pReq->ttl;
695     pFwReq->publishServiceReqParams.period = pReq->period;
696     pFwReq->publishServiceReqParams.replyIndFlag =
697                                    (pReq->recv_indication_cfg & BIT_3) ? 0 : 1;
698     pFwReq->publishServiceReqParams.publishType = pReq->publish_type;
699     pFwReq->publishServiceReqParams.txType = pReq->tx_type;
700 
701     pFwReq->publishServiceReqParams.rssiThresholdFlag = pReq->rssi_threshold_flag;
702     pFwReq->publishServiceReqParams.matchAlg = pReq->publish_match_indicator;
703     pFwReq->publishServiceReqParams.count = pReq->publish_count;
704     pFwReq->publishServiceReqParams.connmap = pReq->connmap;
705     pFwReq->publishServiceReqParams.pubTerminatedIndDisableFlag =
706                                    (pReq->recv_indication_cfg & BIT_0) ? 1 : 0;
707     pFwReq->publishServiceReqParams.pubMatchExpiredIndDisableFlag =
708                                    (pReq->recv_indication_cfg & BIT_1) ? 1 : 0;
709     pFwReq->publishServiceReqParams.followupRxIndDisableFlag =
710                                    (pReq->recv_indication_cfg & BIT_2) ? 1 : 0;
711 
712     pFwReq->publishServiceReqParams.reserved2 = 0;
713 
714     u8* tlvs = pFwReq->ptlv;
715     if (pReq->service_name_len) {
716         tlvs = addTlv(NAN_TLV_TYPE_SERVICE_NAME, pReq->service_name_len,
717                       (const u8*)&pReq->service_name[0], tlvs);
718     }
719     if (pReq->service_specific_info_len) {
720         tlvs = addTlv(NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO, pReq->service_specific_info_len,
721                       (const u8*)&pReq->service_specific_info[0], tlvs);
722     }
723     if (pReq->rx_match_filter_len) {
724         tlvs = addTlv(NAN_TLV_TYPE_RX_MATCH_FILTER, pReq->rx_match_filter_len,
725                       (const u8*)&pReq->rx_match_filter[0], tlvs);
726     }
727     if (pReq->tx_match_filter_len) {
728         tlvs = addTlv(NAN_TLV_TYPE_TX_MATCH_FILTER, pReq->tx_match_filter_len,
729                       (const u8*)&pReq->tx_match_filter[0], tlvs);
730     }
731 
732     /* Pass the Accept policy always */
733     tlvs = addTlv(NAN_TLV_TYPE_NAN_SERVICE_ACCEPT_POLICY, sizeof(NanServiceAcceptPolicy),
734                   (const u8*)&pReq->service_responder_policy, tlvs);
735 
736     if (pReq->cipher_type) {
737         NanCsidType pNanCsidType;
738         pNanCsidType.csid_type = pReq->cipher_type;
739         tlvs = addTlv(NAN_TLV_TYPE_NAN_CSID, sizeof(NanCsidType),
740                         (const u8*)&pNanCsidType, tlvs);
741     }
742 
743     if ((pReq->key_info.key_type ==  NAN_SECURITY_KEY_INPUT_PMK) &&
744         (pReq->key_info.body.pmk_info.pmk_len == NAN_PMK_INFO_LEN)) {
745         tlvs = addTlv(NAN_TLV_TYPE_NAN_PMK,
746                       pReq->key_info.body.pmk_info.pmk_len,
747                       (const u8*)&pReq->key_info.body.pmk_info.pmk[0], tlvs);
748     } else if ((pReq->key_info.key_type == NAN_SECURITY_KEY_INPUT_PASSPHRASE) &&
749         (pReq->key_info.body.passphrase_info.passphrase_len >=
750          NAN_SECURITY_MIN_PASSPHRASE_LEN) &&
751         (pReq->key_info.body.passphrase_info.passphrase_len <=
752          NAN_SECURITY_MAX_PASSPHRASE_LEN)) {
753         tlvs = addTlv(NAN_TLV_TYPE_NAN_PASSPHRASE,
754                   pReq->key_info.body.passphrase_info.passphrase_len,
755                   (const u8*)&pReq->key_info.body.passphrase_info.passphrase[0],
756                   tlvs);
757     }
758 
759     if (pReq->sdea_params.config_nan_data_path ||
760         pReq->sdea_params.security_cfg ||
761         pReq->sdea_params.ranging_state ||
762         pReq->sdea_params.range_report ||
763         pReq->sdea_params.qos_cfg) {
764         NanFWSdeaCtrlParams pNanFWSdeaCtrlParams;
765         memset(&pNanFWSdeaCtrlParams, 0, sizeof(NanFWSdeaCtrlParams));
766 
767         if (pReq->sdea_params.config_nan_data_path) {
768             pNanFWSdeaCtrlParams.data_path_required = 1;
769             pNanFWSdeaCtrlParams.data_path_type =
770                                   (pReq->sdea_params.ndp_type & BIT_0) ?
771                                   NAN_DATA_PATH_MULTICAST_MSG :
772                                   NAN_DATA_PATH_UNICAST_MSG;
773 
774         }
775         if (pReq->sdea_params.security_cfg) {
776             pNanFWSdeaCtrlParams.security_required =
777                                          pReq->sdea_params.security_cfg;
778         }
779         if (pReq->sdea_params.ranging_state) {
780             pNanFWSdeaCtrlParams.ranging_required =
781                                          pReq->sdea_params.ranging_state;
782         }
783         if (pReq->sdea_params.range_report) {
784             pNanFWSdeaCtrlParams.range_report =
785                 (((pReq->sdea_params.range_report & NAN_ENABLE_RANGE_REPORT) >> 1) ? 1 : 0);
786         }
787         if (pReq->sdea_params.qos_cfg) {
788             pNanFWSdeaCtrlParams.qos_required = pReq->sdea_params.qos_cfg;
789         }
790         tlvs = addTlv(NAN_TLV_TYPE_SDEA_CTRL_PARAMS, sizeof(NanFWSdeaCtrlParams),
791                         (const u8*)&pNanFWSdeaCtrlParams, tlvs);
792     }
793 
794     if (pReq->ranging_cfg.ranging_interval_msec ||
795         pReq->ranging_cfg.config_ranging_indications ||
796         pReq->ranging_cfg.distance_ingress_mm ||
797         pReq->ranging_cfg.distance_egress_mm) {
798         NanFWRangeConfigParams pNanFWRangingCfg;
799 
800         memset(&pNanFWRangingCfg, 0, sizeof(NanFWRangeConfigParams));
801         pNanFWRangingCfg.range_interval =
802                                 pReq->ranging_cfg.ranging_interval_msec;
803         pNanFWRangingCfg.ranging_indication_event =
804             ((pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_CONTINUOUS_MASK) |
805             (pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_INGRESS_MET_MASK) |
806             (pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_EGRESS_MET_MASK));
807 
808         pNanFWRangingCfg.ranging_indication_event = pReq->ranging_cfg.config_ranging_indications;
809         if (pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_INGRESS_MET_MASK)
810             pNanFWRangingCfg.geo_fence_threshold.inner_threshold =
811                                         pReq->ranging_cfg.distance_ingress_mm;
812         if (pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_EGRESS_MET_MASK)
813             pNanFWRangingCfg.geo_fence_threshold.outer_threshold =
814                                        pReq->ranging_cfg.distance_egress_mm;
815         tlvs = addTlv(NAN_TLV_TYPE_NAN_RANGING_CFG, sizeof(NanFWRangeConfigParams),
816                                                     (const u8*)&pNanFWRangingCfg, tlvs);
817     }
818 
819     if (pReq->sdea_service_specific_info_len) {
820         tlvs = addTlv(NAN_TLV_TYPE_SDEA_SERVICE_SPECIFIC_INFO, pReq->sdea_service_specific_info_len,
821                       (const u8*)&pReq->sdea_service_specific_info[0], tlvs);
822     }
823 
824     if (pReq->range_response_cfg.publish_id || pReq->range_response_cfg.ranging_response) {
825 
826         NanFWRangeReqMsg pNanFWRangeReqMsg;
827         memset(&pNanFWRangeReqMsg, 0, sizeof(NanFWRangeReqMsg));
828         pNanFWRangeReqMsg.range_id =
829                                 (u16)pReq->range_response_cfg.publish_id;
830         CHAR_ARRAY_TO_MAC_ADDR(pReq->range_response_cfg.peer_addr, pNanFWRangeReqMsg.range_mac_addr);
831         pNanFWRangeReqMsg.ranging_accept =
832             ((pReq->range_response_cfg.ranging_response == NAN_RANGE_REQUEST_ACCEPT) ? 1 : 0);
833         pNanFWRangeReqMsg.ranging_reject =
834             ((pReq->range_response_cfg.ranging_response == NAN_RANGE_REQUEST_REJECT) ? 1 : 0);
835         pNanFWRangeReqMsg.ranging_cancel =
836             ((pReq->range_response_cfg.ranging_response == NAN_RANGE_REQUEST_CANCEL) ? 1 : 0);
837         tlvs = addTlv(NAN_TLV_TYPE_NAN20_RANGING_REQUEST, sizeof(NanFWRangeReqMsg),
838                                                     (const u8*)&pNanFWRangeReqMsg, tlvs);
839     }
840 
841     mVendorData = (char *)pFwReq;
842     mDataLen = message_len;
843 
844     ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
845     if (ret != WIFI_SUCCESS) {
846         ALOGE("%s: put_bytes Error:%d",__func__, ret);
847         cleanup();
848         return ret;
849     }
850     hexdump(mVendorData, mDataLen);
851     return ret;
852 }
853 
putNanPublishCancel(transaction_id id,const NanPublishCancelRequest * pReq)854 wifi_error NanCommand::putNanPublishCancel(transaction_id id, const NanPublishCancelRequest *pReq)
855 {
856     wifi_error ret;
857     ALOGV("NAN_PUBLISH_CANCEL");
858     if (pReq == NULL) {
859         cleanup();
860         return WIFI_ERROR_INVALID_ARGS;
861     }
862     size_t message_len = sizeof(NanPublishServiceCancelReqMsg);
863 
864     pNanPublishServiceCancelReqMsg pFwReq =
865         (pNanPublishServiceCancelReqMsg)malloc(message_len);
866     if (pFwReq == NULL) {
867         cleanup();
868         return WIFI_ERROR_OUT_OF_MEMORY;
869     }
870 
871     ALOGV("Message Len %zu", message_len);
872     memset(pFwReq, 0, message_len);
873     pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
874     pFwReq->fwHeader.msgId = NAN_MSG_ID_PUBLISH_SERVICE_CANCEL_REQ;
875     pFwReq->fwHeader.msgLen = message_len;
876     pFwReq->fwHeader.handle = pReq->publish_id;
877     pFwReq->fwHeader.transactionId = id;
878 
879     mVendorData = (char *)pFwReq;
880     mDataLen = message_len;
881 
882     ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
883     if (ret != WIFI_SUCCESS) {
884         ALOGE("%s: put_bytes Error:%d",__func__, ret);
885         cleanup();
886         return ret;
887     }
888     hexdump(mVendorData, mDataLen);
889     return ret;
890 }
891 
putNanSubscribe(transaction_id id,const NanSubscribeRequest * pReq)892 wifi_error NanCommand::putNanSubscribe(transaction_id id,
893                                 const NanSubscribeRequest *pReq)
894 {
895     wifi_error ret;
896 
897     ALOGV("NAN_SUBSCRIBE");
898     if (pReq == NULL) {
899         cleanup();
900         return WIFI_ERROR_INVALID_ARGS;
901     }
902 
903     size_t message_len =
904         sizeof(NanMsgHeader) + sizeof(NanSubscribeServiceReqParams) +
905         (pReq->service_name_len ? SIZEOF_TLV_HDR + pReq->service_name_len : 0) +
906         (pReq->service_specific_info_len ? SIZEOF_TLV_HDR + pReq->service_specific_info_len : 0) +
907         (pReq->rx_match_filter_len ? SIZEOF_TLV_HDR + pReq->rx_match_filter_len : 0) +
908         (pReq->tx_match_filter_len ? SIZEOF_TLV_HDR + pReq->tx_match_filter_len : 0) +
909         (pReq->cipher_type ? SIZEOF_TLV_HDR + sizeof(NanCsidType) : 0) +
910         ((pReq->sdea_params.config_nan_data_path || pReq->sdea_params.security_cfg ||
911           pReq->sdea_params.ranging_state || pReq->sdea_params.range_report ||
912           pReq->sdea_params.qos_cfg) ?
913           SIZEOF_TLV_HDR + sizeof(NanFWSdeaCtrlParams) : 0) +
914         ((pReq->ranging_cfg.ranging_interval_msec || pReq->ranging_cfg.config_ranging_indications ||
915           pReq->ranging_cfg.distance_ingress_mm || pReq->ranging_cfg.distance_egress_mm) ?
916           SIZEOF_TLV_HDR + sizeof(NanFWRangeConfigParams) : 0) +
917         ((pReq->range_response_cfg.requestor_instance_id ||
918           pReq->range_response_cfg.ranging_response) ?
919           SIZEOF_TLV_HDR + sizeof(NanFWRangeReqMsg) : 0) +
920         (pReq->sdea_service_specific_info_len ? SIZEOF_TLV_HDR + pReq->sdea_service_specific_info_len : 0);
921 
922     message_len += \
923         (pReq->num_intf_addr_present * (SIZEOF_TLV_HDR + NAN_MAC_ADDR_LEN));
924 
925 
926     if ((pReq->key_info.key_type ==  NAN_SECURITY_KEY_INPUT_PMK) &&
927         (pReq->key_info.body.pmk_info.pmk_len == NAN_PMK_INFO_LEN))
928         message_len += SIZEOF_TLV_HDR + NAN_PMK_INFO_LEN;
929     else if ((pReq->key_info.key_type ==  NAN_SECURITY_KEY_INPUT_PASSPHRASE) &&
930              (pReq->key_info.body.passphrase_info.passphrase_len >=
931               NAN_SECURITY_MIN_PASSPHRASE_LEN) &&
932              (pReq->key_info.body.passphrase_info.passphrase_len <=
933               NAN_SECURITY_MAX_PASSPHRASE_LEN))
934         message_len += SIZEOF_TLV_HDR +
935                        pReq->key_info.body.passphrase_info.passphrase_len;
936 
937 
938     pNanSubscribeServiceReqMsg pFwReq = (pNanSubscribeServiceReqMsg)malloc(message_len);
939     if (pFwReq == NULL) {
940         cleanup();
941         return WIFI_ERROR_OUT_OF_MEMORY;
942     }
943 
944     ALOGV("Message Len %zu", message_len);
945     memset(pFwReq, 0, message_len);
946     pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
947     pFwReq->fwHeader.msgId = NAN_MSG_ID_SUBSCRIBE_SERVICE_REQ;
948     pFwReq->fwHeader.msgLen = message_len;
949     if (pReq->subscribe_id == 0) {
950         pFwReq->fwHeader.handle = 0xFFFF;
951     } else {
952         pFwReq->fwHeader.handle = pReq->subscribe_id;
953     }
954     pFwReq->fwHeader.transactionId = id;
955 
956     pFwReq->subscribeServiceReqParams.ttl = pReq->ttl;
957     pFwReq->subscribeServiceReqParams.period = pReq->period;
958     pFwReq->subscribeServiceReqParams.subscribeType = pReq->subscribe_type;
959     pFwReq->subscribeServiceReqParams.srfAttr = pReq->serviceResponseFilter;
960     pFwReq->subscribeServiceReqParams.srfInclude = pReq->serviceResponseInclude;
961     pFwReq->subscribeServiceReqParams.srfSend = pReq->useServiceResponseFilter;
962     pFwReq->subscribeServiceReqParams.ssiRequired = pReq->ssiRequiredForMatchIndication;
963     pFwReq->subscribeServiceReqParams.matchAlg = pReq->subscribe_match_indicator;
964     pFwReq->subscribeServiceReqParams.count = pReq->subscribe_count;
965     pFwReq->subscribeServiceReqParams.rssiThresholdFlag = pReq->rssi_threshold_flag;
966     pFwReq->subscribeServiceReqParams.subTerminatedIndDisableFlag =
967                                    (pReq->recv_indication_cfg & BIT_0) ? 1 : 0;
968     pFwReq->subscribeServiceReqParams.subMatchExpiredIndDisableFlag =
969                                    (pReq->recv_indication_cfg & BIT_1) ? 1 : 0;
970     pFwReq->subscribeServiceReqParams.followupRxIndDisableFlag =
971                                    (pReq->recv_indication_cfg & BIT_2) ? 1 : 0;
972     pFwReq->subscribeServiceReqParams.connmap = pReq->connmap;
973     pFwReq->subscribeServiceReqParams.reserved = 0;
974 
975     u8* tlvs = pFwReq->ptlv;
976     if (pReq->service_name_len) {
977         tlvs = addTlv(NAN_TLV_TYPE_SERVICE_NAME, pReq->service_name_len,
978                       (const u8*)&pReq->service_name[0], tlvs);
979     }
980     if (pReq->service_specific_info_len) {
981         tlvs = addTlv(NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO, pReq->service_specific_info_len,
982                       (const u8*)&pReq->service_specific_info[0], tlvs);
983     }
984     if (pReq->rx_match_filter_len) {
985         tlvs = addTlv(NAN_TLV_TYPE_RX_MATCH_FILTER, pReq->rx_match_filter_len,
986                       (const u8*)&pReq->rx_match_filter[0], tlvs);
987     }
988     if (pReq->tx_match_filter_len) {
989         tlvs = addTlv(NAN_TLV_TYPE_TX_MATCH_FILTER, pReq->tx_match_filter_len,
990                       (const u8*)&pReq->tx_match_filter[0], tlvs);
991     }
992 
993     int i = 0;
994     for (i = 0; i < pReq->num_intf_addr_present; i++)
995     {
996         tlvs = addTlv(NAN_TLV_TYPE_MAC_ADDRESS,
997                       NAN_MAC_ADDR_LEN,
998                       (const u8*)&pReq->intf_addr[i][0], tlvs);
999     }
1000 
1001     if (pReq->cipher_type) {
1002         NanCsidType pNanCsidType;
1003         pNanCsidType.csid_type = pReq->cipher_type;
1004         tlvs = addTlv(NAN_TLV_TYPE_NAN_CSID, sizeof(NanCsidType),
1005                         (const u8*)&pNanCsidType, tlvs);
1006     }
1007 
1008     if ((pReq->key_info.key_type ==  NAN_SECURITY_KEY_INPUT_PMK) &&
1009         (pReq->key_info.body.pmk_info.pmk_len == NAN_PMK_INFO_LEN)) {
1010         tlvs = addTlv(NAN_TLV_TYPE_NAN_PMK,
1011                       pReq->key_info.body.pmk_info.pmk_len,
1012                       (const u8*)&pReq->key_info.body.pmk_info.pmk[0], tlvs);
1013     } else if ((pReq->key_info.key_type == NAN_SECURITY_KEY_INPUT_PASSPHRASE) &&
1014         (pReq->key_info.body.passphrase_info.passphrase_len >=
1015          NAN_SECURITY_MIN_PASSPHRASE_LEN) &&
1016         (pReq->key_info.body.passphrase_info.passphrase_len <=
1017          NAN_SECURITY_MAX_PASSPHRASE_LEN)) {
1018         tlvs = addTlv(NAN_TLV_TYPE_NAN_PASSPHRASE,
1019                   pReq->key_info.body.passphrase_info.passphrase_len,
1020                   (const u8*)&pReq->key_info.body.passphrase_info.passphrase[0],
1021                   tlvs);
1022     }
1023 
1024     if (pReq->sdea_params.config_nan_data_path ||
1025         pReq->sdea_params.security_cfg ||
1026         pReq->sdea_params.ranging_state ||
1027         pReq->sdea_params.range_report ||
1028         pReq->sdea_params.qos_cfg) {
1029         NanFWSdeaCtrlParams pNanFWSdeaCtrlParams;
1030         memset(&pNanFWSdeaCtrlParams, 0, sizeof(NanFWSdeaCtrlParams));
1031 
1032         if (pReq->sdea_params.config_nan_data_path) {
1033             pNanFWSdeaCtrlParams.data_path_required = 1;
1034             pNanFWSdeaCtrlParams.data_path_type =
1035                                   (pReq->sdea_params.ndp_type & BIT_0) ?
1036                                   NAN_DATA_PATH_MULTICAST_MSG :
1037                                   NAN_DATA_PATH_UNICAST_MSG;
1038 
1039         }
1040         if (pReq->sdea_params.security_cfg) {
1041             pNanFWSdeaCtrlParams.security_required =
1042                                          pReq->sdea_params.security_cfg;
1043         }
1044         if (pReq->sdea_params.ranging_state) {
1045             pNanFWSdeaCtrlParams.ranging_required =
1046                                          pReq->sdea_params.ranging_state;
1047         }
1048         if (pReq->sdea_params.range_report) {
1049             pNanFWSdeaCtrlParams.range_report =
1050                 ((pReq->sdea_params.range_report & NAN_ENABLE_RANGE_REPORT >> 1) ? 1 : 0);
1051         }
1052         if (pReq->sdea_params.qos_cfg) {
1053             pNanFWSdeaCtrlParams.qos_required = pReq->sdea_params.qos_cfg;
1054         }
1055         tlvs = addTlv(NAN_TLV_TYPE_SDEA_CTRL_PARAMS, sizeof(NanFWSdeaCtrlParams),
1056                         (const u8*)&pNanFWSdeaCtrlParams, tlvs);
1057 
1058     }
1059 
1060     if (pReq->ranging_cfg.ranging_interval_msec || pReq->ranging_cfg.config_ranging_indications || pReq->ranging_cfg.distance_ingress_mm
1061         || pReq->ranging_cfg.distance_egress_mm) {
1062         NanFWRangeConfigParams pNanFWRangingCfg;
1063         memset(&pNanFWRangingCfg, 0, sizeof(NanFWRangeConfigParams));
1064         pNanFWRangingCfg.range_interval =
1065                                 pReq->ranging_cfg.ranging_interval_msec;
1066         pNanFWRangingCfg.ranging_indication_event =
1067             ((pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_CONTINUOUS_MASK) |
1068             (pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_INGRESS_MET_MASK) |
1069             (pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_EGRESS_MET_MASK));
1070 
1071         pNanFWRangingCfg.ranging_indication_event =
1072                                           pReq->ranging_cfg.config_ranging_indications;
1073         if (pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_INGRESS_MET_MASK)
1074             pNanFWRangingCfg.geo_fence_threshold.inner_threshold =
1075                                         pReq->ranging_cfg.distance_ingress_mm;
1076         if (pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_EGRESS_MET_MASK)
1077             pNanFWRangingCfg.geo_fence_threshold.outer_threshold =
1078                                        pReq->ranging_cfg.distance_egress_mm;
1079         tlvs = addTlv(NAN_TLV_TYPE_NAN_RANGING_CFG, sizeof(NanFWRangeConfigParams),
1080                                                     (const u8*)&pNanFWRangingCfg, tlvs);
1081     }
1082 
1083     if (pReq->sdea_service_specific_info_len) {
1084         tlvs = addTlv(NAN_TLV_TYPE_SDEA_SERVICE_SPECIFIC_INFO, pReq->sdea_service_specific_info_len,
1085                       (const u8*)&pReq->sdea_service_specific_info[0], tlvs);
1086     }
1087 
1088     if (pReq->range_response_cfg.requestor_instance_id || pReq->range_response_cfg.ranging_response) {
1089         NanFWRangeReqMsg pNanFWRangeReqMsg;
1090         memset(&pNanFWRangeReqMsg, 0, sizeof(NanFWRangeReqMsg));
1091         pNanFWRangeReqMsg.range_id =
1092                                 pReq->range_response_cfg.requestor_instance_id;
1093         memcpy(&pNanFWRangeReqMsg.range_mac_addr, &pReq->range_response_cfg.peer_addr, NAN_MAC_ADDR_LEN);
1094         pNanFWRangeReqMsg.ranging_accept =
1095             ((pReq->range_response_cfg.ranging_response == NAN_RANGE_REQUEST_ACCEPT) ? 1 : 0);
1096         pNanFWRangeReqMsg.ranging_reject =
1097             ((pReq->range_response_cfg.ranging_response == NAN_RANGE_REQUEST_REJECT) ? 1 : 0);
1098         pNanFWRangeReqMsg.ranging_cancel =
1099             ((pReq->range_response_cfg.ranging_response == NAN_RANGE_REQUEST_CANCEL) ? 1 : 0);
1100         tlvs = addTlv(NAN_TLV_TYPE_NAN20_RANGING_REQUEST, sizeof(NanFWRangeReqMsg),
1101                                                     (const u8*)&pNanFWRangeReqMsg, tlvs);
1102     }
1103 
1104     mVendorData = (char *)pFwReq;
1105     mDataLen = message_len;
1106     ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
1107     if (ret != WIFI_SUCCESS) {
1108         ALOGE("%s: put_bytes Error:%d",__func__, ret);
1109         cleanup();
1110         return ret;
1111     }
1112     hexdump(mVendorData, mDataLen);
1113     return ret;
1114 }
1115 
putNanSubscribeCancel(transaction_id id,const NanSubscribeCancelRequest * pReq)1116 wifi_error NanCommand::putNanSubscribeCancel(transaction_id id,
1117                                       const NanSubscribeCancelRequest *pReq)
1118 {
1119     wifi_error ret;
1120     ALOGV("NAN_SUBSCRIBE_CANCEL");
1121     if (pReq == NULL) {
1122         cleanup();
1123         return WIFI_ERROR_INVALID_ARGS;
1124     }
1125     size_t message_len = sizeof(NanSubscribeServiceCancelReqMsg);
1126 
1127     pNanSubscribeServiceCancelReqMsg pFwReq =
1128         (pNanSubscribeServiceCancelReqMsg)malloc(message_len);
1129     if (pFwReq == NULL) {
1130         cleanup();
1131         return WIFI_ERROR_OUT_OF_MEMORY;
1132     }
1133 
1134     ALOGV("Message Len %zu", message_len);
1135     memset(pFwReq, 0, message_len);
1136     pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
1137     pFwReq->fwHeader.msgId = NAN_MSG_ID_SUBSCRIBE_SERVICE_CANCEL_REQ;
1138     pFwReq->fwHeader.msgLen = message_len;
1139     pFwReq->fwHeader.handle = pReq->subscribe_id;
1140     pFwReq->fwHeader.transactionId = id;
1141 
1142     mVendorData = (char *)pFwReq;
1143     mDataLen = message_len;
1144     ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
1145     if (ret != WIFI_SUCCESS) {
1146         ALOGE("%s: put_bytes Error:%d",__func__, ret);
1147         cleanup();
1148         return ret;
1149     }
1150     hexdump(mVendorData, mDataLen);
1151     return ret;
1152 }
1153 
putNanTransmitFollowup(transaction_id id,const NanTransmitFollowupRequest * pReq)1154 wifi_error NanCommand::putNanTransmitFollowup(transaction_id id,
1155                                        const NanTransmitFollowupRequest *pReq)
1156 {
1157     wifi_error ret;
1158     ALOGV("TRANSMIT_FOLLOWUP");
1159     if (pReq == NULL) {
1160         cleanup();
1161         return WIFI_ERROR_INVALID_ARGS;
1162     }
1163 
1164     size_t message_len =
1165         sizeof(NanMsgHeader) + sizeof(NanTransmitFollowupReqParams) +
1166         (pReq->service_specific_info_len ? SIZEOF_TLV_HDR +
1167          pReq->service_specific_info_len : 0) +
1168         (pReq->sdea_service_specific_info_len ? SIZEOF_TLV_HDR + pReq->sdea_service_specific_info_len : 0);
1169 
1170     /* Mac address needs to be added in TLV */
1171     message_len += (SIZEOF_TLV_HDR + sizeof(pReq->addr));
1172 
1173     pNanTransmitFollowupReqMsg pFwReq = (pNanTransmitFollowupReqMsg)malloc(message_len);
1174     if (pFwReq == NULL) {
1175         cleanup();
1176         return WIFI_ERROR_OUT_OF_MEMORY;
1177     }
1178 
1179     ALOGV("Message Len %zu", message_len);
1180     memset (pFwReq, 0, message_len);
1181     pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
1182     pFwReq->fwHeader.msgId = NAN_MSG_ID_TRANSMIT_FOLLOWUP_REQ;
1183     pFwReq->fwHeader.msgLen = message_len;
1184     pFwReq->fwHeader.handle = pReq->publish_subscribe_id;
1185     pFwReq->fwHeader.transactionId = id;
1186 
1187     pFwReq->transmitFollowupReqParams.matchHandle = pReq->requestor_instance_id;
1188     if (pReq->priority != NAN_TX_PRIORITY_HIGH) {
1189         pFwReq->transmitFollowupReqParams.priority = 1;
1190     } else {
1191         pFwReq->transmitFollowupReqParams.priority = 2;
1192     }
1193     pFwReq->transmitFollowupReqParams.window = pReq->dw_or_faw;
1194     pFwReq->transmitFollowupReqParams.followupTxRspDisableFlag =
1195                                    (pReq->recv_indication_cfg & BIT_0) ? 1 : 0;
1196     pFwReq->transmitFollowupReqParams.reserved = 0;
1197 
1198     u8* tlvs = pFwReq->ptlv;
1199 
1200     /* Mac address needs to be added in TLV */
1201     tlvs = addTlv(NAN_TLV_TYPE_MAC_ADDRESS, sizeof(pReq->addr),
1202                   (const u8*)&pReq->addr[0], tlvs);
1203     u16 tlv_type = NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO;
1204 
1205     if (pReq->service_specific_info_len) {
1206         tlvs = addTlv(tlv_type, pReq->service_specific_info_len,
1207                       (const u8*)&pReq->service_specific_info[0], tlvs);
1208     }
1209 
1210     if (pReq->sdea_service_specific_info_len) {
1211         tlvs = addTlv(NAN_TLV_TYPE_SDEA_SERVICE_SPECIFIC_INFO, pReq->sdea_service_specific_info_len,
1212                       (const u8*)&pReq->sdea_service_specific_info[0], tlvs);
1213     }
1214 
1215     mVendorData = (char *)pFwReq;
1216     mDataLen = message_len;
1217 
1218     ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
1219     if (ret != WIFI_SUCCESS) {
1220         ALOGE("%s: put_bytes Error:%d",__func__, ret);
1221         cleanup();
1222         return ret;
1223     }
1224     hexdump(mVendorData, mDataLen);
1225     return ret;
1226 }
1227 
putNanStats(transaction_id id,const NanStatsRequest * pReq)1228 wifi_error NanCommand::putNanStats(transaction_id id, const NanStatsRequest *pReq)
1229 {
1230     wifi_error ret;
1231     ALOGV("NAN_STATS");
1232     if (pReq == NULL) {
1233         cleanup();
1234         return WIFI_ERROR_INVALID_ARGS;
1235     }
1236     size_t message_len = sizeof(NanStatsReqMsg);
1237 
1238     pNanStatsReqMsg pFwReq =
1239         (pNanStatsReqMsg)malloc(message_len);
1240     if (pFwReq == NULL) {
1241         cleanup();
1242         return WIFI_ERROR_OUT_OF_MEMORY;
1243     }
1244 
1245     ALOGV("Message Len %zu", message_len);
1246     memset(pFwReq, 0, message_len);
1247     pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
1248     pFwReq->fwHeader.msgId = NAN_MSG_ID_STATS_REQ;
1249     pFwReq->fwHeader.msgLen = message_len;
1250     pFwReq->fwHeader.transactionId = id;
1251 
1252     pFwReq->statsReqParams.statsType = pReq->stats_type;
1253     pFwReq->statsReqParams.clear = pReq->clear;
1254     pFwReq->statsReqParams.reserved = 0;
1255 
1256     mVendorData = (char *)pFwReq;
1257     mDataLen = message_len;
1258 
1259     ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
1260     if (ret != WIFI_SUCCESS) {
1261         ALOGE("%s: put_bytes Error:%d",__func__, ret);
1262         cleanup();
1263         return ret;
1264     }
1265     hexdump(mVendorData, mDataLen);
1266     return ret;
1267 }
1268 
putNanTCA(transaction_id id,const NanTCARequest * pReq)1269 wifi_error NanCommand::putNanTCA(transaction_id id, const NanTCARequest *pReq)
1270 {
1271     wifi_error ret;
1272     ALOGV("NAN_TCA");
1273     if (pReq == NULL) {
1274         cleanup();
1275         return WIFI_ERROR_INVALID_ARGS;
1276     }
1277     size_t message_len = sizeof(NanTcaReqMsg);
1278 
1279     message_len += (SIZEOF_TLV_HDR + 2 * sizeof(u32));
1280     pNanTcaReqMsg pFwReq =
1281         (pNanTcaReqMsg)malloc(message_len);
1282     if (pFwReq == NULL) {
1283         cleanup();
1284         return WIFI_ERROR_OUT_OF_MEMORY;
1285     }
1286 
1287     ALOGV("Message Len %zu", message_len);
1288     memset(pFwReq, 0, message_len);
1289     pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
1290     pFwReq->fwHeader.msgId = NAN_MSG_ID_TCA_REQ;
1291     pFwReq->fwHeader.msgLen = message_len;
1292     pFwReq->fwHeader.transactionId = id;
1293 
1294     u32 tcaReqParams[2];
1295     memset (tcaReqParams, 0, sizeof(tcaReqParams));
1296     tcaReqParams[0] = (pReq->rising_direction_evt_flag & 0x01);
1297     tcaReqParams[0] |= (pReq->falling_direction_evt_flag & 0x01) << 1;
1298     tcaReqParams[0] |= (pReq->clear & 0x01) << 2;
1299     tcaReqParams[1] = pReq->threshold;
1300 
1301     u8* tlvs = pFwReq->ptlv;
1302 
1303     if (pReq->tca_type == NAN_TCA_ID_CLUSTER_SIZE) {
1304         tlvs = addTlv(NAN_TLV_TYPE_CLUSTER_SIZE_REQ, sizeof(tcaReqParams),
1305                       (const u8*)&tcaReqParams[0], tlvs);
1306     } else {
1307         ALOGE("%s: Unrecognized tca_type:%u", __FUNCTION__, pReq->tca_type);
1308         cleanup();
1309         return WIFI_ERROR_INVALID_ARGS;
1310     }
1311 
1312     mVendorData = (char *)pFwReq;
1313     mDataLen = message_len;
1314 
1315     ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
1316     if (ret != WIFI_SUCCESS) {
1317         ALOGE("%s: put_bytes Error:%d",__func__, ret);
1318         cleanup();
1319         return ret;
1320     }
1321     hexdump(mVendorData, mDataLen);
1322     return ret;
1323 }
1324 
putNanBeaconSdfPayload(transaction_id id,const NanBeaconSdfPayloadRequest * pReq)1325 wifi_error NanCommand::putNanBeaconSdfPayload(transaction_id id,
1326                                        const NanBeaconSdfPayloadRequest *pReq)
1327 {
1328     wifi_error ret;
1329     ALOGV("NAN_BEACON_SDF_PAYLAOD");
1330     if (pReq == NULL) {
1331         cleanup();
1332         return WIFI_ERROR_INVALID_ARGS;
1333     }
1334     size_t message_len = sizeof(NanMsgHeader) + \
1335         SIZEOF_TLV_HDR + sizeof(u32) + \
1336         pReq->vsa.vsa_len;
1337 
1338     pNanBeaconSdfPayloadReqMsg pFwReq =
1339         (pNanBeaconSdfPayloadReqMsg)malloc(message_len);
1340     if (pFwReq == NULL) {
1341         cleanup();
1342         return WIFI_ERROR_OUT_OF_MEMORY;
1343     }
1344 
1345     ALOGV("Message Len %zu", message_len);
1346     memset(pFwReq, 0, message_len);
1347     pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
1348     pFwReq->fwHeader.msgId = NAN_MSG_ID_BEACON_SDF_REQ;
1349     pFwReq->fwHeader.msgLen = message_len;
1350     pFwReq->fwHeader.transactionId = id;
1351 
1352     /* Construct First 4 bytes of NanBeaconSdfPayloadReqMsg */
1353     u32 temp = 0;
1354     temp = pReq->vsa.payload_transmit_flag & 0x01;
1355     temp |= (pReq->vsa.tx_in_discovery_beacon & 0x01) << 1;
1356     temp |= (pReq->vsa.tx_in_sync_beacon & 0x01) << 2;
1357     temp |= (pReq->vsa.tx_in_service_discovery & 0x01) << 3;
1358     temp |= (pReq->vsa.vendor_oui & 0x00FFFFFF) << 8;
1359 
1360     int tlv_len = sizeof(u32) + pReq->vsa.vsa_len;
1361     u8* tempBuf = (u8*)malloc(tlv_len);
1362     if (tempBuf == NULL) {
1363         ALOGE("%s: Malloc failed", __func__);
1364         free(pFwReq);
1365         cleanup();
1366         return WIFI_ERROR_OUT_OF_MEMORY;
1367     }
1368     memset(tempBuf, 0, tlv_len);
1369     memcpy(tempBuf, &temp, sizeof(u32));
1370     memcpy((tempBuf + sizeof(u32)), pReq->vsa.vsa, pReq->vsa.vsa_len);
1371 
1372     u8* tlvs = pFwReq->ptlv;
1373 
1374     /* Write the TLVs to the message. */
1375     tlvs = addTlv(NAN_TLV_TYPE_VENDOR_SPECIFIC_ATTRIBUTE_TRANSMIT, tlv_len,
1376                   (const u8*)tempBuf, tlvs);
1377     free(tempBuf);
1378 
1379     mVendorData = (char *)pFwReq;
1380     mDataLen = message_len;
1381 
1382     ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
1383     if (ret != WIFI_SUCCESS) {
1384         ALOGE("%s: put_bytes Error:%d",__func__, ret);
1385         cleanup();
1386         return ret;
1387     }
1388     hexdump(mVendorData, mDataLen);
1389     return ret;
1390 }
1391 
1392 //callback handlers registered for nl message send
error_handler_nan(struct sockaddr_nl * nla,struct nlmsgerr * err,void * arg)1393 static int error_handler_nan(struct sockaddr_nl *nla, struct nlmsgerr *err,
1394                          void *arg)
1395 {
1396     struct sockaddr_nl * tmp;
1397     int *ret = (int *)arg;
1398     tmp = nla;
1399     *ret = err->error;
1400     ALOGE("%s: Error code:%d (%s)", __func__, *ret, strerror(-(*ret)));
1401     return NL_STOP;
1402 }
1403 
1404 //callback handlers registered for nl message send
ack_handler_nan(struct nl_msg * msg,void * arg)1405 static int ack_handler_nan(struct nl_msg *msg, void *arg)
1406 {
1407     int *ret = (int *)arg;
1408     struct nl_msg * a;
1409 
1410     ALOGE("%s: called", __func__);
1411     a = msg;
1412     *ret = 0;
1413     return NL_STOP;
1414 }
1415 
1416 //callback handlers registered for nl message send
finish_handler_nan(struct nl_msg * msg,void * arg)1417 static int finish_handler_nan(struct nl_msg *msg, void *arg)
1418 {
1419   int *ret = (int *)arg;
1420   struct nl_msg * a;
1421 
1422   ALOGE("%s: called", __func__);
1423   a = msg;
1424   *ret = 0;
1425   return NL_SKIP;
1426 }
1427 
1428 
1429 //Override base class requestEvent and implement little differently here
1430 //This will send the request message
1431 //We dont wait for any response back in case of Nan as it is asynchronous
1432 //thus no wait for condition.
requestEvent()1433 wifi_error NanCommand::requestEvent()
1434 {
1435     wifi_error res;
1436     int status;
1437     struct nl_cb * cb;
1438 
1439     cb = nl_cb_alloc(NL_CB_DEFAULT);
1440     if (!cb) {
1441         ALOGE("%s: Callback allocation failed",__func__);
1442         res = WIFI_ERROR_OUT_OF_MEMORY;
1443         goto out;
1444     }
1445 
1446     if (!mInfo->cmd_sock) {
1447         ALOGE("%s: Command socket is null",__func__);
1448         res = WIFI_ERROR_OUT_OF_MEMORY;
1449         goto out;
1450     }
1451 
1452     /* send message */
1453     ALOGV("%s:Handle:%p Socket Value:%p", __func__, mInfo, mInfo->cmd_sock);
1454     status = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage());
1455     if (status < 0) {
1456         res = mapKernelErrortoWifiHalError(status);
1457         goto out;
1458     }
1459 
1460     status = 1;
1461 
1462     nl_cb_err(cb, NL_CB_CUSTOM, error_handler_nan, &status);
1463     nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler_nan, &status);
1464     nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler_nan, &status);
1465 
1466     // err is populated as part of finish_handler
1467     while (status > 0)
1468         nl_recvmsgs(mInfo->cmd_sock, cb);
1469 
1470     res = mapKernelErrortoWifiHalError(status);
1471 out:
1472     //free the VendorData
1473     if (mVendorData) {
1474         free(mVendorData);
1475     }
1476     mVendorData = NULL;
1477     //cleanup the mMsg
1478     mMsg.destroy();
1479     return res;
1480 }
1481 
calcNanTransmitPostDiscoverySize(const NanTransmitPostDiscovery * pPostDiscovery)1482 int NanCommand::calcNanTransmitPostDiscoverySize(
1483     const NanTransmitPostDiscovery *pPostDiscovery)
1484 {
1485     /* Fixed size of u32 for Conn Type, Device Role and R flag + Dur + Rsvd*/
1486     int ret = sizeof(u32);
1487     /* size of availability interval bit map is 4 bytes */
1488     ret += sizeof(u32);
1489     /* size of mac address is 6 bytes*/
1490     ret += (SIZEOF_TLV_HDR + NAN_MAC_ADDR_LEN);
1491     if (pPostDiscovery &&
1492         pPostDiscovery->type == NAN_CONN_WLAN_MESH) {
1493         /* size of WLAN_MESH_ID  */
1494         ret += (SIZEOF_TLV_HDR + \
1495                 pPostDiscovery->mesh_id_len);
1496     }
1497     if (pPostDiscovery &&
1498         pPostDiscovery->type == NAN_CONN_WLAN_INFRA) {
1499         /* size of Infrastructure ssid  */
1500         ret += (SIZEOF_TLV_HDR + \
1501                 pPostDiscovery->infrastructure_ssid_len);
1502     }
1503     ALOGV("%s:size:%d", __func__, ret);
1504     return ret;
1505 }
1506 
fillNanSocialChannelParamVal(const NanSocialChannelScanParams * pScanParams,u32 * pChannelParamArr)1507 void NanCommand::fillNanSocialChannelParamVal(
1508     const NanSocialChannelScanParams *pScanParams,
1509     u32* pChannelParamArr)
1510 {
1511     int i;
1512     if (pChannelParamArr) {
1513         memset(pChannelParamArr, 0,
1514                NAN_MAX_SOCIAL_CHANNELS * sizeof(u32));
1515         for (i= 0; i < NAN_MAX_SOCIAL_CHANNELS; i++) {
1516             pChannelParamArr[i] = pScanParams->scan_period[i] << 16;
1517             pChannelParamArr[i] |= pScanParams->dwell_time[i] << 8;
1518         }
1519         pChannelParamArr[NAN_CHANNEL_24G_BAND] |= 6;
1520         pChannelParamArr[NAN_CHANNEL_5G_BAND_LOW]|= 44;
1521         pChannelParamArr[NAN_CHANNEL_5G_BAND_HIGH]|= 149;
1522         ALOGV("%s: Filled SocialChannelParamVal", __func__);
1523         hexdump((char*)pChannelParamArr, NAN_MAX_SOCIAL_CHANNELS * sizeof(u32));
1524     }
1525     return;
1526 }
1527 
getNanTransmitPostConnectivityCapabilityVal(const NanTransmitPostConnectivityCapability * pCapab)1528 u32 NanCommand::getNanTransmitPostConnectivityCapabilityVal(
1529     const NanTransmitPostConnectivityCapability *pCapab)
1530 {
1531     u32 ret = 0;
1532     ret |= (pCapab->payload_transmit_flag? 1:0) << 16;
1533     ret |= (pCapab->is_mesh_supported? 1:0) << 5;
1534     ret |= (pCapab->is_ibss_supported? 1:0) << 4;
1535     ret |= (pCapab->wlan_infra_field? 1:0) << 3;
1536     ret |= (pCapab->is_tdls_supported? 1:0) << 2;
1537     ret |= (pCapab->is_wfds_supported? 1:0) << 1;
1538     ret |= (pCapab->is_wfd_supported? 1:0);
1539     ALOGV("%s: val:%d", __func__, ret);
1540     return ret;
1541 }
1542 
fillNanTransmitPostDiscoveryVal(const NanTransmitPostDiscovery * pTxDisc,u8 * pOutValue)1543 void NanCommand::fillNanTransmitPostDiscoveryVal(
1544     const NanTransmitPostDiscovery *pTxDisc,
1545     u8 *pOutValue)
1546 {
1547 
1548     if (pTxDisc && pOutValue) {
1549         u8 *tlvs = &pOutValue[8];
1550         pOutValue[0] = pTxDisc->type;
1551         pOutValue[1] = pTxDisc->role;
1552         pOutValue[2] = (pTxDisc->transmit_freq? 1:0);
1553         pOutValue[2] |= ((pTxDisc->duration & 0x03) << 1);
1554         memcpy(&pOutValue[4], &pTxDisc->avail_interval_bitmap,
1555                sizeof(pTxDisc->avail_interval_bitmap));
1556         tlvs = addTlv(NAN_TLV_TYPE_MAC_ADDRESS,
1557                     NAN_MAC_ADDR_LEN,
1558                     (const u8*)&pTxDisc->addr[0],
1559                     tlvs);
1560         if (pTxDisc->type == NAN_CONN_WLAN_MESH) {
1561             tlvs = addTlv(NAN_TLV_TYPE_WLAN_MESH_ID,
1562                         pTxDisc->mesh_id_len,
1563                         (const u8*)&pTxDisc->mesh_id[0],
1564                         tlvs);
1565         }
1566         if (pTxDisc->type == NAN_CONN_WLAN_INFRA) {
1567             tlvs = addTlv(NAN_TLV_TYPE_WLAN_INFRA_SSID,
1568                         pTxDisc->infrastructure_ssid_len,
1569                         (const u8*)&pTxDisc->infrastructure_ssid_val[0],
1570                         tlvs);
1571         }
1572         ALOGV("%s: Filled TransmitPostDiscoveryVal", __func__);
1573         hexdump((char*)pOutValue, calcNanTransmitPostDiscoverySize(pTxDisc));
1574     }
1575 
1576     return;
1577 }
1578 
fillNanFurtherAvailabilityMapVal(const NanFurtherAvailabilityMap * pFam,u8 * pOutValue)1579 void NanCommand::fillNanFurtherAvailabilityMapVal(
1580     const NanFurtherAvailabilityMap *pFam,
1581     u8 *pOutValue)
1582 {
1583     int idx = 0;
1584 
1585     if (pFam && pOutValue) {
1586         u32 famsize = calcNanFurtherAvailabilityMapSize(pFam);
1587         pNanFurtherAvailabilityMapAttrTlv pFwReq = \
1588             (pNanFurtherAvailabilityMapAttrTlv)pOutValue;
1589 
1590         memset(pOutValue, 0, famsize);
1591         pFwReq->numChan = pFam->numchans;
1592         for (idx = 0; idx < pFam->numchans; idx++) {
1593             const NanFurtherAvailabilityChannel *pFamChan =  \
1594                 &pFam->famchan[idx];
1595             pNanFurtherAvailabilityChan pFwFamChan = \
1596                 (pNanFurtherAvailabilityChan)((u8*)&pFwReq->pFaChan[0] + \
1597                 (idx * sizeof(NanFurtherAvailabilityChan)));
1598 
1599             pFwFamChan->entryCtrl.availIntDuration = \
1600                 pFamChan->entry_control;
1601             pFwFamChan->entryCtrl.mapId = \
1602                 pFamChan->mapid;
1603             pFwFamChan->opClass =  pFamChan->class_val;
1604             pFwFamChan->channel = pFamChan->channel;
1605             memcpy(&pFwFamChan->availIntBitmap,
1606                    &pFamChan->avail_interval_bitmap,
1607                    sizeof(pFwFamChan->availIntBitmap));
1608         }
1609         ALOGV("%s: Filled FurtherAvailabilityMapVal", __func__);
1610         hexdump((char*)pOutValue, famsize);
1611     }
1612     return;
1613 }
1614 
calcNanFurtherAvailabilityMapSize(const NanFurtherAvailabilityMap * pFam)1615 int NanCommand::calcNanFurtherAvailabilityMapSize(
1616     const NanFurtherAvailabilityMap *pFam)
1617 {
1618     int ret = 0;
1619     if (pFam && pFam->numchans &&
1620         pFam->numchans <= NAN_MAX_FAM_CHANNELS) {
1621         /* Fixed size of u8 for numchans*/
1622         ret = sizeof(u8);
1623         /* numchans * sizeof(FamChannels) */
1624         ret += (pFam->numchans * sizeof(NanFurtherAvailabilityChan));
1625     }
1626     ALOGV("%s:size:%d", __func__, ret);
1627     return ret;
1628 }
1629 
putNanCapabilities(transaction_id id)1630 wifi_error NanCommand::putNanCapabilities(transaction_id id)
1631 {
1632     wifi_error ret;
1633     ALOGV("NAN_CAPABILITIES");
1634     size_t message_len = sizeof(NanCapabilitiesReqMsg);
1635 
1636     pNanCapabilitiesReqMsg pFwReq = (pNanCapabilitiesReqMsg)malloc(message_len);
1637     if (pFwReq == NULL) {
1638         cleanup();
1639         return WIFI_ERROR_OUT_OF_MEMORY;
1640     }
1641 
1642     memset (pFwReq, 0, message_len);
1643     pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
1644     pFwReq->fwHeader.msgId = NAN_MSG_ID_CAPABILITIES_REQ;
1645     pFwReq->fwHeader.msgLen = message_len;
1646     pFwReq->fwHeader.transactionId = id;
1647 
1648     mVendorData = (char*)pFwReq;
1649     mDataLen = message_len;
1650 
1651     ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
1652     if (ret != WIFI_SUCCESS) {
1653         ALOGE("%s: put_bytes Error:%d",__func__, ret);
1654         cleanup();
1655         return ret;
1656     }
1657     hexdump(mVendorData, mDataLen);
1658     return ret;
1659 }
1660 
putNanDebugCommand(NanDebugParams debug,int debug_msg_length)1661 wifi_error NanCommand::putNanDebugCommand(NanDebugParams debug,
1662                                    int debug_msg_length)
1663 {
1664     wifi_error ret;
1665     ALOGV("NAN_AVAILABILITY_DEBUG");
1666     size_t message_len = sizeof(NanTestModeReqMsg);
1667 
1668     message_len += (SIZEOF_TLV_HDR + debug_msg_length);
1669     pNanTestModeReqMsg pFwReq = (pNanTestModeReqMsg)malloc(message_len);
1670     if (pFwReq == NULL) {
1671         cleanup();
1672         return WIFI_ERROR_OUT_OF_MEMORY;
1673     }
1674 
1675     ALOGV("Message Len %zu\n", message_len);
1676     ALOGV("%s: Debug Command Type = 0x%x \n", __func__, debug.cmd);
1677     ALOGV("%s: ** Debug Command Data Start **", __func__);
1678     hexdump(debug.debug_cmd_data, debug_msg_length);
1679     ALOGV("%s: ** Debug Command Data End **", __func__);
1680 
1681     memset (pFwReq, 0, message_len);
1682     pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
1683     pFwReq->fwHeader.msgId = NAN_MSG_ID_TESTMODE_REQ;
1684     pFwReq->fwHeader.msgLen = message_len;
1685     pFwReq->fwHeader.transactionId = 0;
1686 
1687     u8* tlvs = pFwReq->ptlv;
1688     tlvs = addTlv(NAN_TLV_TYPE_TESTMODE_GENERIC_CMD, debug_msg_length,
1689                   (const u8*)&debug, tlvs);
1690 
1691     mVendorData = (char*)pFwReq;
1692     mDataLen = message_len;
1693 
1694     /* Write the TLVs to the message. */
1695     ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
1696     if (ret != WIFI_SUCCESS) {
1697         ALOGE("%s: put_bytes Error:%d",__func__, ret);
1698         cleanup();
1699         return ret;
1700     }
1701     hexdump(mVendorData, mDataLen);
1702     return ret;
1703 }
1704