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