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