• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "sync.h"
18 #include <utils/Log.h>
19 #include "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