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