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 "nan.h"
20 #include "wifi_hal.h"
21 #include "nan_i.h"
22 #include "nancommand.h"
23
putNanEnable(const NanEnableRequest * pReq)24 int NanCommand::putNanEnable(const NanEnableRequest *pReq)
25 {
26 ALOGI("NAN_ENABLE");
27 size_t message_len = NAN_MAX_ENABLE_REQ_SIZE;
28
29 if (pReq == NULL) {
30 return WIFI_ERROR_INVALID_ARGS;
31 }
32
33 #ifdef NAN_2_0
34 /* Removing the unsupported ones */
35 message_len -= \
36 (SIZEOF_TLV_HDR + sizeof(u8) /* Random Time */ + \
37 SIZEOF_TLV_HDR + sizeof(u8) /* Full Scan Int */);
38
39 message_len += \
40 (
41 pReq->config_2dot4g_support ? (SIZEOF_TLV_HDR + \
42 sizeof(pReq->support_2dot4g_val)) : 0 \
43 ) + \
44 (
45 pReq->config_2dot4g_beacons ? (SIZEOF_TLV_HDR + \
46 sizeof(pReq->beacon_2dot4g_val)) : 0 \
47 ) + \
48 (
49 pReq->config_2dot4g_discovery ? (SIZEOF_TLV_HDR + \
50 sizeof(pReq->discovery_2dot4g_val)) : 0 \
51 ) + \
52 (
53 pReq->config_5g_beacons ? (SIZEOF_TLV_HDR + \
54 sizeof(pReq->beacon_5g_val)) : 0 \
55 ) + \
56 (
57 pReq->config_5g_discovery ? (SIZEOF_TLV_HDR + \
58 sizeof(pReq->discovery_5g_val)) : 0 \
59 ) + \
60 (
61 pReq->config_5g_rssi_close ? (SIZEOF_TLV_HDR + \
62 sizeof(pReq->rssi_close_5g_val)) : 0 \
63 ) + \
64 (
65 pReq->config_5g_rssi_middle ? (SIZEOF_TLV_HDR + \
66 sizeof(pReq->rssi_middle_5g_val)) : 0 \
67 ) + \
68 (
69 pReq->config_5g_rssi_close_proximity ? (SIZEOF_TLV_HDR + \
70 sizeof(pReq->rssi_close_proximity_5g_val)) : 0 \
71 ) + \
72 (
73 pReq->config_rssi_window_size ? (SIZEOF_TLV_HDR + \
74 sizeof(pReq->rssi_window_size_val)) : 0 \
75 ) + \
76 (
77 pReq->config_oui ? (SIZEOF_TLV_HDR + \
78 sizeof(pReq->oui_val)) : 0 \
79 ) + \
80 (
81 pReq->config_intf_addr ? (SIZEOF_TLV_HDR + \
82 sizeof(pReq->intf_addr_val)) : 0 \
83 ) + \
84 (
85 pReq->config_cluster_attribute_val ? (SIZEOF_TLV_HDR + \
86 sizeof(pReq->config_cluster_attribute_val)) : 0 \
87 ) + \
88 (
89 pReq->config_scan_params ? (SIZEOF_TLV_HDR + \
90 NAN_MAX_SOCIAL_CHANNEL * sizeof(u32)) : 0 \
91 ) + \
92 (
93 pReq->config_debug_flags ? (SIZEOF_TLV_HDR + \
94 sizeof(u64)) : 0 \
95 ) + \
96 (
97 pReq->config_random_factor_force ? (SIZEOF_TLV_HDR + \
98 sizeof(pReq->random_factor_force_val)) : 0 \
99 ) + \
100 (
101 pReq->config_hop_count_force ? (SIZEOF_TLV_HDR + \
102 sizeof(pReq->hop_count_force_val)) : 0 \
103 );
104 #endif /* NAN_2_0 */
105
106 pNanEnableReqMsg pFwReq = (pNanEnableReqMsg)malloc(message_len);
107 if (pFwReq == NULL) {
108 return WIFI_ERROR_OUT_OF_MEMORY;
109 }
110
111 ALOGI("Message Len %d", message_len);
112 memset (pFwReq, 0, message_len);
113 pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
114 pFwReq->fwHeader.msgId = NAN_MSG_ID_ENABLE_REQ;
115 pFwReq->fwHeader.msgLen = message_len;
116 pFwReq->fwHeader.handle = pReq->header.handle;
117 pFwReq->fwHeader.transactionId = pReq->header.transaction_id;
118
119 u8* tlvs = pFwReq->ptlv;
120
121 /* Write the TLVs to the message. */
122 tlvs = addTlv(NAN_TLV_TYPE_5G_SUPPORT, sizeof(pReq->support_5g),
123 (const u8*)&pReq->support_5g, tlvs);
124 tlvs = addTlv(NAN_TLV_TYPE_CLUSTER_ID_LOW, sizeof(pReq->cluster_low),
125 (const u8*)&pReq->cluster_low, tlvs);
126 tlvs = addTlv(NAN_TLV_TYPE_CLUSTER_ID_HIGH, sizeof(pReq->cluster_high),
127 (const u8*)&pReq->cluster_high, tlvs);
128 tlvs = addTlv(NAN_TLV_TYPE_SID_BEACON, sizeof(pReq->sid_beacon),
129 (const u8*)&pReq->sid_beacon, tlvs);
130 tlvs = addTlv(NAN_TLV_TYPE_RSSI_CLOSE, sizeof(pReq->rssi_close),
131 (const u8*)&pReq->rssi_close, tlvs);
132 tlvs = addTlv(NAN_TLV_TYPE_RSSI_MEDIUM, sizeof(pReq->rssi_middle),
133 (const u8*)&pReq->rssi_middle, tlvs);
134 tlvs = addTlv(NAN_TLV_TYPE_HOP_COUNT_LIMIT, sizeof(pReq->hop_count_limit),
135 (const u8*)&pReq->hop_count_limit, tlvs);
136 #ifndef NAN_2_0
137 tlvs = addTlv(NAN_TLV_TYPE_RANDOM_UPDATE_TIME, sizeof(pReq->random_time),
138 (const u8*)&pReq->random_time, tlvs);
139 #endif /* NAN_2_0 */
140 tlvs = addTlv(NAN_TLV_TYPE_MASTER_PREFERENCE, sizeof(pReq->master_pref),
141 (const u8*)&pReq->master_pref, tlvs);
142 #ifndef NAN_2_0
143 tlvs = addTlv(NAN_TLV_TYPE_PERIODIC_SCAN_INTERVAL, sizeof(pReq->periodic_scan_interval),
144 (const u8*)&pReq->periodic_scan_interval, tlvs);
145 #endif /* NAN_2_0 */
146
147 #ifdef NAN_2_0
148 if (pReq->config_2dot4g_support) {
149 tlvs = addTlv(NAN_TLV_TYPE_2DOT4G_SUPPORT, sizeof(pReq->support_2dot4g_val),
150 (const u8*)&pReq->support_2dot4g_val, tlvs);
151 }
152 if (pReq->config_2dot4g_beacons) {
153 tlvs = addTlv(NAN_TLV_TYPE_2DOT4G_BEACONS, sizeof(pReq->beacon_2dot4g_val),
154 (const u8*)&pReq->beacon_2dot4g_val, tlvs);
155 }
156 if (pReq->config_2dot4g_discovery) {
157 tlvs = addTlv(NAN_TLV_TYPE_2DOT4G_SDF, sizeof(pReq->discovery_2dot4g_val),
158 (const u8*)&pReq->discovery_2dot4g_val, tlvs);
159 }
160 if (pReq->config_5g_beacons) {
161 tlvs = addTlv(NAN_TLV_TYPE_5G_BEACON, sizeof(pReq->beacon_5g_val),
162 (const u8*)&pReq->beacon_5g_val, tlvs);
163 }
164 if (pReq->config_5g_discovery) {
165 tlvs = addTlv(NAN_TLV_TYPE_5G_SDF, sizeof(pReq->discovery_5g_val),
166 (const u8*)&pReq->discovery_5g_val, tlvs);
167 }
168 /* Add the support of sending 5G RSSI values */
169 if (pReq->config_5g_rssi_close) {
170 tlvs = addTlv(NAN_TLV_TYPE_5G_RSSI_CLOSE, sizeof(pReq->rssi_close_5g_val),
171 (const u8*)&pReq->rssi_close_5g_val, tlvs);
172 }
173 if (pReq->config_5g_rssi_middle) {
174 tlvs = addTlv(NAN_TLV_TYPE_5G_RSSI_MEDIUM, sizeof(pReq->rssi_middle_5g_val),
175 (const u8*)&pReq->rssi_middle_5g_val, tlvs);
176 }
177 if (pReq->config_5g_rssi_close_proximity) {
178 tlvs = addTlv(NAN_TLV_TYPE_5G_RSSI_CLOSE_PROXIMITY,
179 sizeof(pReq->rssi_close_proximity_5g_val),
180 (const u8*)&pReq->rssi_close_proximity_5g_val, tlvs);
181 }
182 if (pReq->config_rssi_window_size) {
183 tlvs = addTlv(NAN_TLV_TYPE_RSSI_AVERAGING_WINDOW_SIZE, sizeof(pReq->rssi_window_size_val),
184 (const u8*)&pReq->rssi_window_size_val, tlvs);
185 }
186 if (pReq->config_oui) {
187 tlvs = addTlv(NAN_TLV_TYPE_CLUSTER_OUI_NETWORK_ID, sizeof(pReq->oui_val),
188 (const u8*)&pReq->oui_val, tlvs);
189 }
190 if (pReq->config_intf_addr) {
191 tlvs = addTlv(NAN_TLV_TYPE_SOURCE_MAC_ADDRESS, sizeof(pReq->intf_addr_val),
192 (const u8*)&pReq->intf_addr_val[0], tlvs);
193 }
194 if (pReq->config_cluster_attribute_val) {
195 tlvs = addTlv(NAN_TLV_TYPE_CLUSTER_ATTRIBUTE_IN_SDF, sizeof(pReq->config_cluster_attribute_val),
196 (const u8*)&pReq->config_cluster_attribute_val, tlvs);
197 }
198 if (pReq->config_scan_params) {
199 u32 socialChannelParamVal[NAN_MAX_SOCIAL_CHANNEL];
200 /* Fill the social channel param */
201 fillNanSocialChannelParamVal(&pReq->scan_params_val,
202 socialChannelParamVal);
203 int i;
204 for (i = 0; i < NAN_MAX_SOCIAL_CHANNEL; i++) {
205 tlvs = addTlv(NAN_TLV_TYPE_SOCIAL_CHANNEL_SCAN_PARAMETERS,
206 sizeof(socialChannelParamVal[i]),
207 (const u8*)&socialChannelParamVal[i], tlvs);
208 }
209 }
210 if (pReq->config_debug_flags) {
211 tlvs = addTlv(NAN_TLV_TYPE_DEBUGGING_FLAGS,
212 sizeof(pReq->debug_flags_val),
213 (const u8*)&pReq->debug_flags_val, tlvs);
214 }
215 if (pReq->config_random_factor_force) {
216 tlvs = addTlv(NAN_TLV_TYPE_RANDOM_FACTOR_FORCE,
217 sizeof(pReq->random_factor_force_val),
218 (const u8*)&pReq->random_factor_force_val, tlvs);
219 }
220 if (pReq->config_hop_count_force) {
221 tlvs = addTlv(NAN_TLV_TYPE_HOP_COUNT_FORCE,
222 sizeof(pReq->hop_count_force_val),
223 (const u8*)&pReq->hop_count_force_val, tlvs);
224 }
225 #endif /* NAN_2_0 */
226
227 mVendorData = (char*)pFwReq;
228 mDataLen = message_len;
229
230 return WIFI_SUCCESS;
231 }
232
putNanDisable(const NanDisableRequest * pReq)233 int NanCommand::putNanDisable(const NanDisableRequest *pReq)
234 {
235 ALOGI("NAN_DISABLE");
236 size_t message_len = sizeof(NanDisableReqMsg);
237
238 if (pReq == NULL) {
239 return WIFI_ERROR_INVALID_ARGS;
240 }
241
242 pNanDisableReqMsg pFwReq = (pNanDisableReqMsg)malloc(message_len);
243 if (pFwReq == NULL) {
244 return WIFI_ERROR_OUT_OF_MEMORY;
245 }
246
247 ALOGI("Message Len %d", message_len);
248 memset (pFwReq, 0, message_len);
249 pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
250 pFwReq->fwHeader.msgId = NAN_MSG_ID_DISABLE_REQ;
251 pFwReq->fwHeader.msgLen = message_len;
252 pFwReq->fwHeader.handle = pReq->header.handle;
253 pFwReq->fwHeader.transactionId = pReq->header.transaction_id;
254
255 mVendorData = (char*)pFwReq;
256 mDataLen = message_len;
257
258 return WIFI_SUCCESS;
259 }
260
putNanConfig(const NanConfigRequest * pReq)261 int NanCommand::putNanConfig(const NanConfigRequest *pReq)
262 {
263 ALOGI("NAN_CONFIG");
264 size_t message_len = NAN_MAX_CONFIGURATION_REQ_SIZE;
265
266 if (pReq == NULL) {
267 return WIFI_ERROR_INVALID_ARGS;
268 }
269
270 #ifndef NAN_2_0
271 // Add additional message size for transmitting
272 // further availability attribute if
273 // additional_disc_window_slots is Non-zero value.
274 if (pReq->additional_disc_window_slots != 0) {
275 message_len += (SIZEOF_TLV_HDR + \
276 sizeof(pReq->additional_disc_window_slots));
277 }
278 #endif /* NAN_2_0 */
279
280 #ifdef NAN_2_0
281 message_len = sizeof(NanMsgHeader);
282
283 message_len += \
284 (
285 pReq->config_sid_beacon ? (SIZEOF_TLV_HDR + \
286 sizeof(pReq->sid_beacon)) : 0 \
287 ) + \
288 (
289 pReq->config_master_pref ? (SIZEOF_TLV_HDR + \
290 sizeof(pReq->master_pref)) : 0 \
291 ) + \
292 (
293 pReq->config_5g_rssi_close_proximity ? (SIZEOF_TLV_HDR + \
294 sizeof(pReq->rssi_close_proximity_5g_val)) : 0 \
295 ) + \
296 (
297 pReq->config_rssi_window_size ? (SIZEOF_TLV_HDR + \
298 sizeof(pReq->rssi_window_size_val)) : 0 \
299 ) + \
300 (
301 pReq->config_cluster_attribute_val ? (SIZEOF_TLV_HDR + \
302 sizeof(pReq->config_cluster_attribute_val)) : 0 \
303 ) + \
304 (
305 pReq->config_scan_params ? (SIZEOF_TLV_HDR + \
306 NAN_MAX_SOCIAL_CHANNEL * sizeof(u32)) : 0 \
307 ) + \
308 (
309 pReq->config_debug_flags ? (SIZEOF_TLV_HDR + \
310 sizeof(u64)) : 0 \
311 ) + \
312 (
313 pReq->config_random_factor_force ? (SIZEOF_TLV_HDR + \
314 sizeof(pReq->random_factor_force_val)) : 0 \
315 ) + \
316 (
317 pReq->config_hop_count_force ? (SIZEOF_TLV_HDR + \
318 sizeof(pReq->hop_count_force_val)) : 0 \
319 ) + \
320 (
321 pReq->config_conn_capability ? (SIZEOF_TLV_HDR + \
322 sizeof(u32)) : 0 \
323 ) + \
324 (
325 pReq->config_discovery_attr ? (SIZEOF_TLV_HDR + \
326 calcNanTransmitPostDiscoverySize(&pReq->discovery_attr_val)) : 0 \
327 );
328
329 if (pReq->config_fam && \
330 calcNanFurtherAvailabilityMapSize(&pReq->fam_val)) {
331 message_len += (SIZEOF_TLV_HDR + \
332 calcNanFurtherAvailabilityMapSize(&pReq->fam_val));
333 }
334 #endif /* NAN_2_0 */
335
336 pNanConfigurationReqMsg pFwReq = (pNanConfigurationReqMsg)malloc(message_len);
337 if (pFwReq == NULL) {
338 return WIFI_ERROR_OUT_OF_MEMORY;
339 }
340
341 ALOGI("Message Len %d", message_len);
342 memset (pFwReq, 0, message_len);
343 pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
344 pFwReq->fwHeader.msgId = NAN_MSG_ID_CONFIGURATION_REQ;
345 pFwReq->fwHeader.msgLen = message_len;
346 pFwReq->fwHeader.handle = pReq->header.handle;
347 pFwReq->fwHeader.transactionId = pReq->header.transaction_id;
348
349 u8* tlvs = pFwReq->ptlv;
350 if (pReq->config_sid_beacon) {
351 tlvs = addTlv(NAN_TLV_TYPE_SID_BEACON, sizeof(pReq->sid_beacon),
352 (const u8*)&pReq->sid_beacon, tlvs);
353 }
354 #ifndef NAN_2_0
355 tlvs = addTlv(NAN_TLV_TYPE_RANDOM_UPDATE_TIME, sizeof(pReq->random_time),
356 (const u8*)&pReq->random_time, tlvs);
357 #endif /* NAN_2_0 */
358 if (pReq->config_master_pref) {
359 tlvs = addTlv(NAN_TLV_TYPE_MASTER_PREFERENCE, sizeof(pReq->master_pref),
360 (const u8*)&pReq->master_pref, tlvs);
361 }
362 #ifndef NAN_2_0
363 tlvs = addTlv(NAN_TLV_TYPE_PERIODIC_SCAN_INTERVAL, sizeof(pReq->periodic_scan_interval),
364 (const u8*)&pReq->periodic_scan_interval, tlvs);
365 #endif /* NAN_2_0 */
366
367 /* In 2.0 Version of NAN this parameter does not have any significance */
368 #ifndef NAN_2_0
369 if (pReq->additional_disc_window_slots != 0) {
370 /*
371 Construct the value in this manner
372 Bit0 ==> 1/0 Enable/Disable FAW
373 Bit1-2 ==> reserved
374 Bit3-7 ==> FAW Slot Value.
375 */
376 u8 faw_value = 0x01; /* Enable the first bit */
377 /* Shifting the disc_window_slots by 3 and masking it with 0xf8
378 so that the Bit 3 to 7 are updated
379 */
380 faw_value |= ((pReq->additional_disc_window_slots << 3) & (0xf8));
381 tlvs = addTlv(NAN_TLV_TYPE_FURTHER_AVAILABILITY,
382 sizeof(faw_value),
383 (const u8*)&faw_value, tlvs);
384 }
385 #endif /* NAN_2_0 */
386
387 #ifdef NAN_2_0
388 if (pReq->config_rssi_window_size) {
389 tlvs = addTlv(NAN_TLV_TYPE_RSSI_AVERAGING_WINDOW_SIZE, sizeof(pReq->rssi_window_size_val),
390 (const u8*)&pReq->rssi_window_size_val, tlvs);
391 }
392 if (pReq->config_scan_params) {
393 u32 socialChannelParamVal[NAN_MAX_SOCIAL_CHANNEL];
394 /* Fill the social channel param */
395 fillNanSocialChannelParamVal(&pReq->scan_params_val,
396 socialChannelParamVal);
397 int i;
398 for (i = 0; i < NAN_MAX_SOCIAL_CHANNEL; i++) {
399 tlvs = addTlv(NAN_TLV_TYPE_SOCIAL_CHANNEL_SCAN_PARAMETERS,
400 sizeof(socialChannelParamVal[i]),
401 (const u8*)&socialChannelParamVal[i], tlvs);
402 }
403 }
404 if (pReq->config_debug_flags) {
405 tlvs = addTlv(NAN_TLV_TYPE_DEBUGGING_FLAGS,
406 sizeof(pReq->debug_flags_val),
407 (const u8*)&pReq->debug_flags_val, tlvs);
408 }
409 if (pReq->config_random_factor_force) {
410 tlvs = addTlv(NAN_TLV_TYPE_RANDOM_FACTOR_FORCE,
411 sizeof(pReq->random_factor_force_val),
412 (const u8*)&pReq->random_factor_force_val, tlvs);
413 }
414 if (pReq->config_hop_count_force) {
415 tlvs = addTlv(NAN_TLV_TYPE_HOP_COUNT_FORCE,
416 sizeof(pReq->hop_count_force_val),
417 (const u8*)&pReq->hop_count_force_val, tlvs);
418 }
419 if (pReq->config_conn_capability) {
420 u32 val = \
421 getNanTransmitPostConnectivityCapabilityVal(&pReq->conn_capability_val);
422 tlvs = addTlv(NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_TRANSMIT,
423 sizeof(val), (const u8*)&val, tlvs);
424 }
425 if (pReq->config_discovery_attr) {
426 fillNanTransmitPostDiscoveryVal(&pReq->discovery_attr_val,
427 (u8*)(tlvs + SIZEOF_TLV_HDR));
428 tlvs = addTlv(NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_TRANSMIT,
429 calcNanTransmitPostDiscoverySize(&pReq->discovery_attr_val),
430 (const u8*)(tlvs + SIZEOF_TLV_HDR), tlvs);
431 }
432 if (pReq->config_fam && \
433 calcNanFurtherAvailabilityMapSize(&pReq->fam_val)) {
434 fillNanFurtherAvailabilityMapVal(&pReq->fam_val,
435 (u8*)(tlvs + SIZEOF_TLV_HDR));
436 tlvs = addTlv(NAN_TLV_TYPE_FURTHER_AVAILABILITY_MAP,
437 calcNanFurtherAvailabilityMapSize(&pReq->fam_val),
438 (const u8*)(tlvs + SIZEOF_TLV_HDR), tlvs);
439 }
440 #endif /* NAN_2_0 */
441
442 mVendorData = (char*)pFwReq;
443 mDataLen = message_len;
444
445 return WIFI_SUCCESS;
446 }
447
448
putNanPublish(const NanPublishRequest * pReq)449 int NanCommand::putNanPublish(const NanPublishRequest *pReq)
450 {
451 ALOGI("NAN_PUBLISH");
452 if (pReq == NULL) {
453 return WIFI_ERROR_INVALID_ARGS;
454 }
455
456 size_t message_len =
457 sizeof(NanMsgHeader) + sizeof(NanPublishServiceReqParams) +
458 (pReq->service_name_len ? SIZEOF_TLV_HDR + pReq->service_name_len : 0) +
459 (pReq->service_specific_info_len ? SIZEOF_TLV_HDR + pReq->service_specific_info_len : 0) +
460 (pReq->rx_match_filter_len ? SIZEOF_TLV_HDR + pReq->rx_match_filter_len : 0) +
461 (pReq->tx_match_filter_len ? SIZEOF_TLV_HDR + pReq->tx_match_filter_len : 0);
462
463 pNanPublishServiceReqMsg pFwReq = (pNanPublishServiceReqMsg)malloc(message_len);
464 if (pFwReq == NULL) {
465 return WIFI_ERROR_OUT_OF_MEMORY;
466 }
467
468 ALOGI("Message Len %d", message_len);
469 memset(pFwReq, 0, message_len);
470 pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
471 pFwReq->fwHeader.msgId = NAN_MSG_ID_PUBLISH_SERVICE_REQ;
472 pFwReq->fwHeader.msgLen = message_len;
473 pFwReq->fwHeader.handle = pReq->header.handle;
474 pFwReq->fwHeader.transactionId = pReq->header.transaction_id;
475
476 pFwReq->publishServiceReqParams.ttl = pReq->ttl;
477 pFwReq->publishServiceReqParams.period = pReq->period;
478 pFwReq->publishServiceReqParams.replyIndFlag = pReq->replied_event_flag;
479 pFwReq->publishServiceReqParams.publishType = pReq->publish_type;
480 pFwReq->publishServiceReqParams.txType = pReq->tx_type;
481 #ifdef NAN_2_0
482 /* Overwriting replyIndFlag to 0 based on v17 Nan Spec */
483 pFwReq->publishServiceReqParams.replyIndFlag = 0;
484 pFwReq->publishServiceReqParams.rssiThresholdFlag = pReq->rssi_threshold_flag;
485 pFwReq->publishServiceReqParams.ota_flag = pReq->ota_flag;
486 pFwReq->publishServiceReqParams.matchAlg = pReq->publish_match;
487 #endif /* NAN_2_0 */
488 pFwReq->publishServiceReqParams.count = pReq->publish_count;
489 #ifdef NAN_2_0
490 pFwReq->publishServiceReqParams.connmap = pReq->connmap;
491 #endif /* NAN_2_0 */
492 pFwReq->publishServiceReqParams.reserved2 = 0;
493
494 u8* tlvs = pFwReq->ptlv;
495 if (pReq->service_name_len) {
496 tlvs = addTlv(NAN_TLV_TYPE_SERVICE_NAME, pReq->service_name_len,
497 (const u8*)&pReq->service_name[0], tlvs);
498 }
499 if (pReq->service_specific_info_len) {
500 tlvs = addTlv(NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO, pReq->service_specific_info_len,
501 (const u8*)&pReq->service_specific_info[0], tlvs);
502 }
503 if (pReq->rx_match_filter_len) {
504 tlvs = addTlv(NAN_TLV_TYPE_RX_MATCH_FILTER, pReq->rx_match_filter_len,
505 (const u8*)&pReq->rx_match_filter[0], tlvs);
506 }
507 if (pReq->tx_match_filter_len) {
508 tlvs = addTlv(NAN_TLV_TYPE_TX_MATCH_FILTER, pReq->tx_match_filter_len,
509 (const u8*)&pReq->tx_match_filter[0], tlvs);
510 }
511
512 mVendorData = (char *)pFwReq;
513 mDataLen = message_len;
514
515 return WIFI_SUCCESS;
516 }
517
putNanPublishCancel(const NanPublishCancelRequest * pReq)518 int NanCommand::putNanPublishCancel(const NanPublishCancelRequest *pReq)
519 {
520 ALOGI("NAN_PUBLISH_CANCEL");
521 if (pReq == NULL) {
522 return WIFI_ERROR_INVALID_ARGS;
523 }
524 size_t message_len = sizeof(NanPublishServiceCancelReqMsg);
525
526 pNanPublishServiceCancelReqMsg pFwReq =
527 (pNanPublishServiceCancelReqMsg)malloc(message_len);
528 if (pFwReq == NULL) {
529 return WIFI_ERROR_INVALID_ARGS;
530 }
531
532 ALOGI("Message Len %d", message_len);
533 memset(pFwReq, 0, message_len);
534 pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
535 pFwReq->fwHeader.msgId = NAN_MSG_ID_PUBLISH_SERVICE_CANCEL_REQ;
536 pFwReq->fwHeader.msgLen = message_len;
537 pFwReq->fwHeader.handle = pReq->header.handle;
538 pFwReq->fwHeader.transactionId = pReq->header.transaction_id;
539
540 mVendorData = (char *)pFwReq;
541 mDataLen = message_len;
542
543 return WIFI_SUCCESS;
544 }
545
putNanSubscribe(const NanSubscribeRequest * pReq)546 int NanCommand::putNanSubscribe(const NanSubscribeRequest *pReq)
547 {
548
549 ALOGI("NAN_SUBSCRIBE");
550 if (pReq == NULL) {
551 return WIFI_ERROR_INVALID_ARGS;
552 }
553
554 size_t message_len =
555 sizeof(NanMsgHeader) + sizeof(NanSubscribeServiceReqParams) +
556 (pReq->service_name_len ? SIZEOF_TLV_HDR + pReq->service_name_len : 0) +
557 (pReq->service_specific_info_len ? SIZEOF_TLV_HDR + pReq->service_specific_info_len : 0) +
558 (pReq->rx_match_filter_len ? SIZEOF_TLV_HDR + pReq->rx_match_filter_len : 0) +
559 (pReq->tx_match_filter_len ? SIZEOF_TLV_HDR + pReq->tx_match_filter_len : 0);
560
561 #ifdef NAN_2_0
562 message_len += \
563 (pReq->num_intf_addr_present * (SIZEOF_TLV_HDR + NAN_MAC_ADDR_LEN));
564 #endif /* NAN_2_0 */
565
566 pNanSubscribeServiceReqMsg pFwReq = (pNanSubscribeServiceReqMsg)malloc(message_len);
567 if (pFwReq == NULL) {
568 return WIFI_ERROR_INVALID_ARGS;
569 }
570
571 ALOGI("Message Len %d", message_len);
572 memset(pFwReq, 0, message_len);
573 pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
574 pFwReq->fwHeader.msgId = NAN_MSG_ID_SUBSCRIBE_SERVICE_REQ;
575 pFwReq->fwHeader.msgLen = message_len;
576 pFwReq->fwHeader.handle = pReq->header.handle;
577 pFwReq->fwHeader.transactionId = pReq->header.transaction_id;
578
579
580 pFwReq->subscribeServiceReqParams.ttl = pReq->ttl;
581 pFwReq->subscribeServiceReqParams.period = pReq->period;
582 pFwReq->subscribeServiceReqParams.subscribeType = pReq->subscribe_type;
583 pFwReq->subscribeServiceReqParams.srfAttr = pReq->serviceResponseFilter;
584 pFwReq->subscribeServiceReqParams.srfInclude = pReq->serviceResponseInclude;
585 pFwReq->subscribeServiceReqParams.srfSend = pReq->useServiceResponseFilter;
586 pFwReq->subscribeServiceReqParams.ssiRequired = pReq->ssiRequiredForMatchIndication;
587 pFwReq->subscribeServiceReqParams.matchAlg = pReq->subscribe_match;
588 pFwReq->subscribeServiceReqParams.count = pReq->subscribe_count;
589 #ifdef NAN_2_0
590 pFwReq->subscribeServiceReqParams.rssiThresholdFlag = pReq->rssi_threshold_flag;
591 pFwReq->subscribeServiceReqParams.ota_flag = pReq->ota_flag;
592 pFwReq->subscribeServiceReqParams.connmap = pReq->connmap;
593 #endif /* NAN_2_0 */
594 pFwReq->subscribeServiceReqParams.reserved = 0;
595
596 u8* tlvs = pFwReq->ptlv;
597 if (pReq->service_name_len) {
598 tlvs = addTlv(NAN_TLV_TYPE_SERVICE_NAME, pReq->service_name_len,
599 (const u8*)&pReq->service_name[0], tlvs);
600 }
601 if (pReq->service_specific_info_len) {
602 tlvs = addTlv(NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO, pReq->service_specific_info_len,
603 (const u8*)&pReq->service_specific_info[0], tlvs);
604 }
605 if (pReq->rx_match_filter_len) {
606 tlvs = addTlv(NAN_TLV_TYPE_RX_MATCH_FILTER, pReq->rx_match_filter_len,
607 (const u8*)&pReq->rx_match_filter[0], tlvs);
608 }
609 if (pReq->tx_match_filter_len) {
610 tlvs = addTlv(NAN_TLV_TYPE_TX_MATCH_FILTER, pReq->tx_match_filter_len,
611 (const u8*)&pReq->tx_match_filter[0], tlvs);
612 }
613
614 #ifdef NAN_2_0
615 int i = 0;
616 for (i = 0; i < pReq->num_intf_addr_present; i++)
617 {
618 tlvs = addTlv(NAN_TLV_TYPE_MAC_ADDRESS,
619 NAN_MAC_ADDR_LEN,
620 (const u8*)&pReq->intf_addr[i][0], tlvs);
621 }
622 #endif /* NAN_2_0 */
623
624 mVendorData = (char *)pFwReq;
625 mDataLen = message_len;
626
627 return WIFI_SUCCESS;
628 }
629
putNanSubscribeCancel(const NanSubscribeCancelRequest * pReq)630 int NanCommand::putNanSubscribeCancel(const NanSubscribeCancelRequest *pReq)
631 {
632 ALOGI("NAN_SUBSCRIBE_CANCEL");
633 if (pReq == NULL) {
634 return WIFI_ERROR_INVALID_ARGS;
635 }
636 size_t message_len = sizeof(NanSubscribeServiceCancelReqMsg);
637
638 pNanSubscribeServiceCancelReqMsg pFwReq =
639 (pNanSubscribeServiceCancelReqMsg)malloc(message_len);
640 if (pFwReq == NULL) {
641 return WIFI_ERROR_INVALID_ARGS;
642 }
643
644 ALOGI("Message Len %d", message_len);
645 memset(pFwReq, 0, message_len);
646 pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
647 pFwReq->fwHeader.msgId = NAN_MSG_ID_SUBSCRIBE_SERVICE_CANCEL_REQ;
648 pFwReq->fwHeader.msgLen = message_len;
649 pFwReq->fwHeader.handle = pReq->header.handle;
650 pFwReq->fwHeader.transactionId = pReq->header.transaction_id;
651
652 mVendorData = (char *)pFwReq;
653 mDataLen = message_len;
654
655 return WIFI_SUCCESS;
656 }
657
658
putNanTransmitFollowup(const NanTransmitFollowupRequest * pReq)659 int NanCommand::putNanTransmitFollowup(const NanTransmitFollowupRequest *pReq)
660 {
661 ALOGI("TRANSMIT_FOLLOWUP");
662 if (pReq == NULL) {
663 return WIFI_ERROR_INVALID_ARGS;
664 }
665
666 size_t message_len =
667 sizeof(NanMsgHeader) + sizeof(NanTransmitFollowupReqParams) +
668 (pReq->service_specific_info_len ? SIZEOF_TLV_HDR +
669 pReq->service_specific_info_len : 0);
670
671 #ifdef NAN_2_0
672 /* Mac address needs to be added in TLV */
673 message_len += (SIZEOF_TLV_HDR + sizeof(pReq->addr));
674 #endif
675
676 pNanTransmitFollowupReqMsg pFwReq = (pNanTransmitFollowupReqMsg)malloc(message_len);
677 if (pFwReq == NULL) {
678 return WIFI_ERROR_INVALID_ARGS;
679 }
680
681 ALOGI("Message Len %d", message_len);
682 memset (pFwReq, 0, message_len);
683 pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
684 pFwReq->fwHeader.msgId = NAN_MSG_ID_TRANSMIT_FOLLOWUP_REQ;
685 pFwReq->fwHeader.msgLen = message_len;
686 pFwReq->fwHeader.handle = pReq->header.handle;
687 pFwReq->fwHeader.transactionId = pReq->header.transaction_id;
688
689
690 #ifndef NAN_2_0
691 memcpy(pFwReq->transmitFollowupReqParams.macAddr, pReq->addr,
692 sizeof(pFwReq->transmitFollowupReqParams.macAddr));
693 #else /* NAN_2_0 */
694 pFwReq->transmitFollowupReqParams.matchHandle = pReq->match_handle;
695 #endif /* NAN_2_0 */
696 pFwReq->transmitFollowupReqParams.priority = pReq->priority;
697 pFwReq->transmitFollowupReqParams.window = pReq->dw_or_faw;
698 pFwReq->transmitFollowupReqParams.reserved = 0;
699
700 u8* tlvs = pFwReq->ptlv;
701
702 #ifdef NAN_2_0
703 /* Mac address needs to be added in TLV */
704 tlvs = addTlv(NAN_TLV_TYPE_MAC_ADDRESS, sizeof(pReq->addr),
705 (const u8*)&pReq->addr[0], tlvs);
706 u16 tlv_type = NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO;
707 #else /* NAN_2_0 */
708 u16 tlv_type = (pReq->dw_or_faw == 0)? NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO :
709 NAN_TLV_TYPE_EXT_SERVICE_SPECIFIC_INFO;
710 #endif /* NAN_2_0 */
711
712 if (pReq->service_specific_info_len) {
713 tlvs = addTlv(tlv_type, pReq->service_specific_info_len,
714 (const u8*)&pReq->service_specific_info[0], tlvs);
715 }
716
717 mVendorData = (char *)pFwReq;
718 mDataLen = message_len;
719
720 return WIFI_SUCCESS;
721 }
722
putNanStats(const NanStatsRequest * pReq)723 int NanCommand::putNanStats(const NanStatsRequest *pReq)
724 {
725 ALOGI("NAN_STATS");
726 if (pReq == NULL) {
727 return WIFI_ERROR_INVALID_ARGS;
728 }
729 size_t message_len = sizeof(NanStatsReqMsg);
730
731 pNanStatsReqMsg pFwReq =
732 (pNanStatsReqMsg)malloc(message_len);
733 if (pFwReq == NULL) {
734 return WIFI_ERROR_INVALID_ARGS;
735 }
736
737 ALOGI("Message Len %d", message_len);
738 memset(pFwReq, 0, message_len);
739 pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
740 pFwReq->fwHeader.msgId = NAN_MSG_ID_STATS_REQ;
741 pFwReq->fwHeader.msgLen = message_len;
742 pFwReq->fwHeader.handle = pReq->header.handle;
743 pFwReq->fwHeader.transactionId = pReq->header.transaction_id;
744
745 pFwReq->statsReqParams.statsId = pReq->stats_id;
746 pFwReq->statsReqParams.clear = pReq->clear;
747 pFwReq->statsReqParams.reserved = 0;
748
749 mVendorData = (char *)pFwReq;
750 mDataLen = message_len;
751
752 return WIFI_SUCCESS;
753 }
754
putNanTCA(const NanTCARequest * pReq)755 int NanCommand::putNanTCA(const NanTCARequest *pReq)
756 {
757 ALOGI("NAN_TCA");
758 if (pReq == NULL) {
759 return WIFI_ERROR_INVALID_ARGS;
760 }
761 size_t message_len = sizeof(NanTcaReqMsg);
762
763 #ifdef NAN_2_0
764 message_len += (SIZEOF_TLV_HDR + 2 * sizeof(u32));
765 #endif
766
767 pNanTcaReqMsg pFwReq =
768 (pNanTcaReqMsg)malloc(message_len);
769 if (pFwReq == NULL) {
770 return WIFI_ERROR_INVALID_ARGS;
771 }
772
773 ALOGI("Message Len %d", message_len);
774 memset(pFwReq, 0, message_len);
775 pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
776 pFwReq->fwHeader.msgId = NAN_MSG_ID_TCA_REQ;
777 pFwReq->fwHeader.msgLen = message_len;
778 pFwReq->fwHeader.handle = pReq->header.handle;
779 pFwReq->fwHeader.transactionId = pReq->header.transaction_id;
780
781 #ifndef NAN_2_0
782 pFwReq->tcaReqParams.tcaId = pReq->tca_id;
783 pFwReq->tcaReqParams.rising = pReq->rising_direction_evt_flag;
784 pFwReq->tcaReqParams.falling = pReq->falling_direction_evt_flag;
785 pFwReq->tcaReqParams.clear = pReq->clear;
786 pFwReq->tcaReqParams.reserved = 0;
787 pFwReq->tcaReqParams.threshold = pReq->threshold;
788 #else /* NAN_2_0 */
789 u32 tcaReqParams[2];
790 memset (tcaReqParams, 0, sizeof(tcaReqParams));
791 tcaReqParams[0] = (pReq->rising_direction_evt_flag & 0x01);
792 tcaReqParams[0] |= (pReq->falling_direction_evt_flag & 0x01) << 1;
793 tcaReqParams[0] |= (pReq->clear & 0x01) << 2;
794 tcaReqParams[1] = pReq->threshold;
795
796 u8* tlvs = pFwReq->ptlv;
797
798 tlvs = addTlv(NAN_TLV_TYPE_TCA_CLUSTER_SIZE_REQ, sizeof(tcaReqParams),
799 (const u8*)&tcaReqParams[0], tlvs);
800 #endif
801
802 mVendorData = (char *)pFwReq;
803 mDataLen = message_len;
804
805 return WIFI_SUCCESS;
806 }
807
putNanBeaconSdfPayload(const NanBeaconSdfPayloadRequest * pReq)808 int NanCommand::putNanBeaconSdfPayload(const NanBeaconSdfPayloadRequest *pReq)
809 {
810 int ret = WIFI_ERROR_NOT_SUPPORTED;
811 #ifdef NAN_2_0
812 ALOGI("NAN_BEACON_SDF_PAYLAOD");
813 if (pReq == NULL) {
814 return WIFI_ERROR_INVALID_ARGS;
815 }
816 size_t message_len = sizeof(NanMsgHeader) + \
817 SIZEOF_TLV_HDR + sizeof(u32) + \
818 pReq->vsa.vsa_len;
819
820 pNanBeaconSdfPayloadReqMsg pFwReq =
821 (pNanBeaconSdfPayloadReqMsg)malloc(message_len);
822 if (pFwReq == NULL) {
823 return WIFI_ERROR_INVALID_ARGS;
824 }
825
826 ALOGI("Message Len %d", message_len);
827 memset(pFwReq, 0, message_len);
828 pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
829 pFwReq->fwHeader.msgId = NAN_MSG_ID_BEACON_SDF_REQ;
830 pFwReq->fwHeader.msgLen = message_len;
831 pFwReq->fwHeader.handle = pReq->header.handle;
832 pFwReq->fwHeader.transactionId = pReq->header.transaction_id;
833
834 /* Construct First 4 bytes of NanBeaconSdfPayloadReqMsg */
835 u32 temp = 0;
836 temp = pReq->vsa.payload_transmit_flag & 0x01;
837 temp |= (pReq->vsa.tx_in_discovery_beacon & 0x01) << 1;
838 temp |= (pReq->vsa.tx_in_sync_beacon & 0x01) << 2;
839 temp |= (pReq->vsa.tx_in_service_discovery & 0x01) << 3;
840 temp |= (pReq->vsa.vendor_oui & 0x00FFFFFF) << 8;
841
842 int tlv_len = sizeof(u32) + pReq->vsa.vsa_len;
843 u8* tempBuf = (u8*)malloc(tlv_len);
844 if (tempBuf == NULL) {
845 ALOGE("%s: Malloc failed", __func__);
846 free(pFwReq);
847 return WIFI_ERROR_INVALID_ARGS;
848 }
849 memset(tempBuf, 0, tlv_len);
850 memcpy(tempBuf, &temp, sizeof(u32));
851 memcpy((tempBuf + sizeof(u32)), pReq->vsa.vsa, pReq->vsa.vsa_len);
852
853 u8* tlvs = pFwReq->ptlv;
854
855 /* Write the TLVs to the message. */
856 tlvs = addTlv(NAN_TLV_TYPE_VENDOR_SPECIFIC_ATTRIBUTE_TRANSMIT, tlv_len,
857 (const u8*)tempBuf, tlvs);
858 free(tempBuf);
859
860 mVendorData = (char *)pFwReq;
861 mDataLen = message_len;
862 ret = WIFI_SUCCESS;
863 #endif /* NAN_2_0 */
864 return ret;
865 }
866 //callback handlers registered for nl message send
error_handler_nan(struct sockaddr_nl * nla,struct nlmsgerr * err,void * arg)867 static int error_handler_nan(struct sockaddr_nl *nla, struct nlmsgerr *err,
868 void *arg)
869 {
870 struct sockaddr_nl * tmp;
871 int *ret = (int *)arg;
872 tmp = nla;
873 *ret = err->error;
874 ALOGE("%s: Error code:%d (%s)", __func__, *ret, strerror(-(*ret)));
875 return NL_STOP;
876 }
877
878 //callback handlers registered for nl message send
ack_handler_nan(struct nl_msg * msg,void * arg)879 static int ack_handler_nan(struct nl_msg *msg, void *arg)
880 {
881 int *ret = (int *)arg;
882 struct nl_msg * a;
883
884 ALOGE("%s: called", __func__);
885 a = msg;
886 *ret = 0;
887 return NL_STOP;
888 }
889
890 //callback handlers registered for nl message send
finish_handler_nan(struct nl_msg * msg,void * arg)891 static int finish_handler_nan(struct nl_msg *msg, void *arg)
892 {
893 int *ret = (int *)arg;
894 struct nl_msg * a;
895
896 ALOGE("%s: called", __func__);
897 a = msg;
898 *ret = 0;
899 return NL_SKIP;
900 }
901
902
903 //Override base class requestEvent and implement little differently here
904 //This will send the request message
905 //We dont wait for any response back in case of Nan as it is asynchronous
906 //thus no wait for condition.
requestEvent()907 int NanCommand::requestEvent()
908 {
909 int res;
910 struct nl_cb * cb;
911
912 cb = nl_cb_alloc(NL_CB_DEFAULT);
913 if (!cb) {
914 ALOGE("%s: Callback allocation failed",__func__);
915 res = -1;
916 goto out;
917 }
918
919 /* create the message */
920 res = create();
921 if (res < 0)
922 goto out;
923
924 /* send message */
925 ALOGE("%s:Handle:%p Socket Value:%p", __func__, mInfo, mInfo->cmd_sock);
926 res = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage());
927 if (res < 0)
928 goto out;
929 res = 1;
930
931 nl_cb_err(cb, NL_CB_CUSTOM, error_handler_nan, &res);
932 nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler_nan, &res);
933 nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler_nan, &res);
934
935 // err is populated as part of finish_handler
936 while (res > 0)
937 nl_recvmsgs(mInfo->cmd_sock, cb);
938
939 ALOGD("%s: Command invoked return value:%d",__func__, res);
940
941 out:
942 //free the VendorData
943 if (mVendorData) {
944 free(mVendorData);
945 }
946 mVendorData = NULL;
947 //cleanup the mMsg
948 mMsg.destroy();
949 return res;
950 }
951
calcNanTransmitPostDiscoverySize(const NanTransmitPostDiscovery * pPostDiscovery)952 int NanCommand::calcNanTransmitPostDiscoverySize(
953 const NanTransmitPostDiscovery *pPostDiscovery)
954 {
955 /* Fixed size of u32 for Conn Type, Device Role and R flag + Dur + Rsvd*/
956 int ret = sizeof(u32);
957 /* size of availability interval bit map is 4 bytes */
958 ret += sizeof(u32);
959 /* size of mac address is 6 bytes*/
960 ret += (SIZEOF_TLV_HDR + NAN_MAC_ADDR_LEN);
961 if (pPostDiscovery &&
962 pPostDiscovery->type == NAN_CONN_WLAN_MESH) {
963 /* size of WLAN_MESH_ID */
964 ret += (SIZEOF_TLV_HDR + \
965 pPostDiscovery->mesh_id_len);
966 }
967 if (pPostDiscovery &&
968 pPostDiscovery->type == NAN_CONN_WLAN_INFRA) {
969 /* size of Infrastructure ssid */
970 ret += (SIZEOF_TLV_HDR + \
971 pPostDiscovery->infrastructure_ssid_len);
972 }
973 ALOGI("%s:size:%d", __func__, ret);
974 return ret;
975 }
976
fillNanSocialChannelParamVal(const NanSocialChannelScanParams * pScanParams,u32 * pChannelParamArr)977 void NanCommand::fillNanSocialChannelParamVal(
978 const NanSocialChannelScanParams *pScanParams,
979 u32* pChannelParamArr)
980 {
981 int i;
982 if (pChannelParamArr) {
983 memset(pChannelParamArr, 0,
984 NAN_MAX_SOCIAL_CHANNEL * sizeof(u32));
985 for (i= 0; i < NAN_MAX_SOCIAL_CHANNEL; i++) {
986 pChannelParamArr[i] = pScanParams->scan_period[i] << 16;
987 pChannelParamArr[i] |= pScanParams->dwell_time[i] << 8;
988 }
989 pChannelParamArr[NAN_CHANNEL_6] |= 6;
990 pChannelParamArr[NAN_CHANNEL_44]|= 44;
991 pChannelParamArr[NAN_CHANNEL_149]|= 149;
992 ALOGI("%s: Filled SocialChannelParamVal", __func__);
993 hexdump((char*)pChannelParamArr, NAN_MAX_SOCIAL_CHANNEL * sizeof(u32));
994 }
995 return;
996 }
997
getNanTransmitPostConnectivityCapabilityVal(const NanTransmitPostConnectivityCapability * pCapab)998 u32 NanCommand::getNanTransmitPostConnectivityCapabilityVal(
999 const NanTransmitPostConnectivityCapability *pCapab)
1000 {
1001 u32 ret = 0;
1002 ret |= (pCapab->payload_transmit_flag? 1:0) << 16;
1003 ret |= (pCapab->is_mesh_supported? 1:0) << 5;
1004 ret |= (pCapab->is_ibss_supported? 1:0) << 4;
1005 ret |= (pCapab->wlan_infra_field? 1:0) << 3;
1006 ret |= (pCapab->is_tdls_supported? 1:0) << 2;
1007 ret |= (pCapab->is_wfds_supported? 1:0) << 1;
1008 ret |= (pCapab->is_wfd_supported? 1:0);
1009 ALOGI("%s: val:%d", __func__, ret);
1010 return ret;
1011 }
1012
fillNanTransmitPostDiscoveryVal(const NanTransmitPostDiscovery * pTxDisc,u8 * pOutValue)1013 void NanCommand::fillNanTransmitPostDiscoveryVal(
1014 const NanTransmitPostDiscovery *pTxDisc,
1015 u8 *pOutValue)
1016 {
1017 #ifdef NAN_2_0
1018 if (pTxDisc && pOutValue) {
1019 u8 *tlvs = &pOutValue[8];
1020 pOutValue[0] = pTxDisc->type;
1021 pOutValue[1] = pTxDisc->role;
1022 pOutValue[2] = (pTxDisc->transmit_freq? 1:0);
1023 pOutValue[2] |= ((pTxDisc->duration & 0x03) << 1);
1024 memcpy(&pOutValue[4], &pTxDisc->avail_interval_bitmap,
1025 sizeof(pTxDisc->avail_interval_bitmap));
1026 tlvs = addTlv(NAN_TLV_TYPE_MAC_ADDRESS,
1027 NAN_MAC_ADDR_LEN,
1028 (const u8*)&pTxDisc->addr[0],
1029 tlvs);
1030 if (pTxDisc->type == NAN_CONN_WLAN_MESH) {
1031 tlvs = addTlv(NAN_TLV_TYPE_WLAN_MESH_ID,
1032 pTxDisc->mesh_id_len,
1033 (const u8*)&pTxDisc->mesh_id[0],
1034 tlvs);
1035 }
1036 if (pTxDisc->type == NAN_CONN_WLAN_INFRA) {
1037 tlvs = addTlv(NAN_TLV_TYPE_FW_WLAN_INFRASTRUCTURE_SSID,
1038 pTxDisc->infrastructure_ssid_len,
1039 (const u8*)&pTxDisc->infrastructure_ssid_val[0],
1040 tlvs);
1041 }
1042 ALOGI("%s: Filled TransmitPostDiscoveryVal", __func__);
1043 hexdump((char*)pOutValue, calcNanTransmitPostDiscoverySize(pTxDisc));
1044 }
1045 #endif /* NAN_2_0 */
1046 return;
1047 }
1048
fillNanFurtherAvailabilityMapVal(const NanFurtherAvailabilityMap * pFam,u8 * pOutValue)1049 void NanCommand::fillNanFurtherAvailabilityMapVal(
1050 const NanFurtherAvailabilityMap *pFam,
1051 u8 *pOutValue)
1052 {
1053 int idx = 0;
1054
1055 if (pFam && pOutValue) {
1056 u32 famsize = calcNanFurtherAvailabilityMapSize(pFam);
1057 pNanFurtherAvailabilityMapAttrTlv pFwReq = \
1058 (pNanFurtherAvailabilityMapAttrTlv)pOutValue;
1059
1060 memset(pOutValue, 0, famsize);
1061 pFwReq->numChan = pFam->numchans;
1062 for (idx = 0; idx < pFam->numchans; idx++) {
1063 const NanFurtherAvailabilityChannel *pFamChan = \
1064 &pFam->famchan[idx];
1065 pNanFurtherAvailabilityChan pFwFamChan = \
1066 (pNanFurtherAvailabilityChan)((u8*)&pFwReq->pFaChan[0] + \
1067 (idx * sizeof(NanFurtherAvailabilityChan)));
1068
1069 pFwFamChan->entryCtrl.availIntDuration = \
1070 pFamChan->entry_control;
1071 pFwFamChan->entryCtrl.mapId = \
1072 pFamChan->mapid;
1073 pFwFamChan->opClass = pFamChan->class_val;
1074 pFwFamChan->channel = pFamChan->channel;
1075 memcpy(&pFwFamChan->availIntBitmap,
1076 &pFamChan->avail_interval_bitmap,
1077 sizeof(pFwFamChan->availIntBitmap));
1078 }
1079 ALOGI("%s: Filled FurtherAvailabilityMapVal", __func__);
1080 hexdump((char*)pOutValue, famsize);
1081 }
1082 return;
1083 }
1084
calcNanFurtherAvailabilityMapSize(const NanFurtherAvailabilityMap * pFam)1085 int NanCommand::calcNanFurtherAvailabilityMapSize(
1086 const NanFurtherAvailabilityMap *pFam)
1087 {
1088 int ret = 0;
1089 if (pFam && pFam->numchans &&
1090 pFam->numchans <= NAN_MAX_FAM_CHANNELS) {
1091 /* Fixed size of u8 for numchans*/
1092 ret = sizeof(u8);
1093 /* numchans * sizeof(FamChannels) */
1094 ret += (pFam->numchans * sizeof(NanFurtherAvailabilityChan));
1095 }
1096 ALOGI("%s:size:%d", __func__, ret);
1097 return ret;
1098 }
1099
1100