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