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