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     pNanEnableReqMsg pFwReq = (pNanEnableReqMsg)malloc(message_len);
127     if (pFwReq == NULL) {
128         cleanup();
129         return WIFI_ERROR_OUT_OF_MEMORY;
130     }
131 
132     ALOGV("Message Len %zu", message_len);
133     memset (pFwReq, 0, message_len);
134     pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
135     pFwReq->fwHeader.msgId = NAN_MSG_ID_ENABLE_REQ;
136     pFwReq->fwHeader.msgLen = message_len;
137     pFwReq->fwHeader.transactionId = id;
138 
139     u8* tlvs = pFwReq->ptlv;
140 
141     /* Write the TLVs to the message. */
142 
143     tlvs = addTlv(NAN_TLV_TYPE_CLUSTER_ID_LOW, sizeof(pReq->cluster_low),
144                   (const u8*)&pReq->cluster_low, tlvs);
145     tlvs = addTlv(NAN_TLV_TYPE_CLUSTER_ID_HIGH, sizeof(pReq->cluster_high),
146                   (const u8*)&pReq->cluster_high, tlvs);
147     tlvs = addTlv(NAN_TLV_TYPE_MASTER_PREFERENCE, sizeof(pReq->master_pref),
148                   (const u8*)&pReq->master_pref, tlvs);
149     if (pReq->config_support_5g) {
150         tlvs = addTlv(NAN_TLV_TYPE_5G_SUPPORT, sizeof(pReq->support_5g_val),
151                      (const u8*)&pReq->support_5g_val, tlvs);
152     }
153     if (pReq->config_sid_beacon) {
154         tlvs = addTlv(NAN_TLV_TYPE_SID_BEACON, sizeof(pReq->sid_beacon_val),
155                       (const u8*)&pReq->sid_beacon_val, tlvs);
156     }
157     if (pReq->config_2dot4g_rssi_close) {
158         tlvs = addTlv(NAN_TLV_TYPE_24G_RSSI_CLOSE,
159                       sizeof(pReq->rssi_close_2dot4g_val),
160                       (const u8*)&pReq->rssi_close_2dot4g_val, tlvs);
161     }
162     if (pReq->config_2dot4g_rssi_middle) {
163         tlvs = addTlv(NAN_TLV_TYPE_24G_RSSI_MIDDLE,
164                       sizeof(pReq->rssi_middle_2dot4g_val),
165                       (const u8*)&pReq->rssi_middle_2dot4g_val, tlvs);
166     }
167     if (pReq->config_hop_count_limit) {
168         tlvs = addTlv(NAN_TLV_TYPE_HOP_COUNT_LIMIT,
169                       sizeof(pReq->hop_count_limit_val),
170                       (const u8*)&pReq->hop_count_limit_val, tlvs);
171     }
172     if (pReq->config_2dot4g_support) {
173         tlvs = addTlv(NAN_TLV_TYPE_24G_SUPPORT, sizeof(pReq->support_2dot4g_val),
174                       (const u8*)&pReq->support_2dot4g_val, tlvs);
175     }
176     if (pReq->config_2dot4g_beacons) {
177         tlvs = addTlv(NAN_TLV_TYPE_24G_BEACON, sizeof(pReq->beacon_2dot4g_val),
178                       (const u8*)&pReq->beacon_2dot4g_val, tlvs);
179     }
180     if (pReq->config_2dot4g_sdf) {
181         tlvs = addTlv(NAN_TLV_TYPE_24G_SDF, sizeof(pReq->sdf_2dot4g_val),
182                       (const u8*)&pReq->sdf_2dot4g_val, tlvs);
183     }
184     if (pReq->config_5g_beacons) {
185         tlvs = addTlv(NAN_TLV_TYPE_5G_BEACON, sizeof(pReq->beacon_5g_val),
186                       (const u8*)&pReq->beacon_5g_val, tlvs);
187     }
188     if (pReq->config_5g_sdf) {
189         tlvs = addTlv(NAN_TLV_TYPE_5G_SDF, sizeof(pReq->sdf_5g_val),
190                       (const u8*)&pReq->sdf_5g_val, tlvs);
191     }
192     if (pReq->config_2dot4g_rssi_proximity) {
193         tlvs = addTlv(NAN_TLV_TYPE_24G_RSSI_CLOSE_PROXIMITY,
194                       sizeof(pReq->rssi_proximity_2dot4g_val),
195                       (const u8*)&pReq->rssi_proximity_2dot4g_val, tlvs);
196     }
197     /* Add the support of sending 5G RSSI values */
198     if (pReq->config_5g_rssi_close) {
199         tlvs = addTlv(NAN_TLV_TYPE_5G_RSSI_CLOSE, sizeof(pReq->rssi_close_5g_val),
200                       (const u8*)&pReq->rssi_close_5g_val, tlvs);
201     }
202     if (pReq->config_5g_rssi_middle) {
203         tlvs = addTlv(NAN_TLV_TYPE_5G_RSSI_MIDDLE, sizeof(pReq->rssi_middle_5g_val),
204                       (const u8*)&pReq->rssi_middle_5g_val, tlvs);
205     }
206     if (pReq->config_5g_rssi_close_proximity) {
207         tlvs = addTlv(NAN_TLV_TYPE_5G_RSSI_CLOSE_PROXIMITY,
208                       sizeof(pReq->rssi_close_proximity_5g_val),
209                       (const u8*)&pReq->rssi_close_proximity_5g_val, tlvs);
210     }
211     if (pReq->config_rssi_window_size) {
212         tlvs = addTlv(NAN_TLV_TYPE_RSSI_AVERAGING_WINDOW_SIZE, sizeof(pReq->rssi_window_size_val),
213                       (const u8*)&pReq->rssi_window_size_val, tlvs);
214     }
215     if (pReq->config_oui) {
216         tlvs = addTlv(NAN_TLV_TYPE_CLUSTER_OUI_NETWORK_ID, sizeof(pReq->oui_val),
217                       (const u8*)&pReq->oui_val, tlvs);
218     }
219     if (pReq->config_intf_addr) {
220         tlvs = addTlv(NAN_TLV_TYPE_SOURCE_MAC_ADDRESS, sizeof(pReq->intf_addr_val),
221                       (const u8*)&pReq->intf_addr_val[0], tlvs);
222     }
223     if (pReq->config_cluster_attribute_val) {
224         tlvs = addTlv(NAN_TLV_TYPE_CLUSTER_ATTRIBUTE_IN_SDF, sizeof(pReq->config_cluster_attribute_val),
225                       (const u8*)&pReq->config_cluster_attribute_val, tlvs);
226     }
227     if (pReq->config_scan_params) {
228         u32 socialChannelParamVal[NAN_MAX_SOCIAL_CHANNELS];
229         /* Fill the social channel param */
230         fillNanSocialChannelParamVal(&pReq->scan_params_val,
231                                      socialChannelParamVal);
232         int i;
233         for (i = 0; i < NAN_MAX_SOCIAL_CHANNELS; i++) {
234             tlvs = addTlv(NAN_TLV_TYPE_SOCIAL_CHANNEL_SCAN_PARAMS,
235                           sizeof(socialChannelParamVal[i]),
236                           (const u8*)&socialChannelParamVal[i], tlvs);
237         }
238     }
239     if (pReq->config_random_factor_force) {
240         tlvs = addTlv(NAN_TLV_TYPE_RANDOM_FACTOR_FORCE,
241                       sizeof(pReq->random_factor_force_val),
242                       (const u8*)&pReq->random_factor_force_val, tlvs);
243     }
244     if (pReq->config_hop_count_force) {
245         tlvs = addTlv(NAN_TLV_TYPE_HOP_COUNT_FORCE,
246                       sizeof(pReq->hop_count_force_val),
247                       (const u8*)&pReq->hop_count_force_val, tlvs);
248     }
249     if (pReq->config_24g_channel) {
250         tlvs = addTlv(NAN_TLV_TYPE_24G_CHANNEL,
251                       sizeof(u32),
252                       (const u8*)&pReq->channel_24g_val, tlvs);
253     }
254     if (pReq->config_5g_channel) {
255         tlvs = addTlv(NAN_TLV_TYPE_5G_CHANNEL,
256                       sizeof(u32),
257                       (const u8*)&pReq->channel_5g_val, tlvs);
258     }
259     mVendorData = (char*)pFwReq;
260     mDataLen = message_len;
261 
262     //Insert the vendor specific data
263     int ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
264     if (ret < 0) {
265         ALOGE("%s: put_bytes Error:%d",__func__, ret);
266         cleanup();
267         return ret;
268     }
269     hexdump(mVendorData, mDataLen);
270     return ret;
271 }
272 
putNanDisable(transaction_id id)273 int NanCommand::putNanDisable(transaction_id id)
274 {
275     ALOGV("NAN_DISABLE");
276     size_t message_len = sizeof(NanDisableReqMsg);
277 
278     pNanDisableReqMsg pFwReq = (pNanDisableReqMsg)malloc(message_len);
279     if (pFwReq == NULL) {
280         cleanup();
281         return WIFI_ERROR_OUT_OF_MEMORY;
282     }
283 
284     ALOGV("Message Len %zu", message_len);
285     memset (pFwReq, 0, message_len);
286     pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
287     pFwReq->fwHeader.msgId = NAN_MSG_ID_DISABLE_REQ;
288     pFwReq->fwHeader.msgLen = message_len;
289     pFwReq->fwHeader.transactionId = id;
290 
291     mVendorData = (char*)pFwReq;
292     mDataLen = message_len;
293 
294     int ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
295     if (ret < 0) {
296         ALOGE("%s: put_bytes Error:%d",__func__, ret);
297         cleanup();
298         return ret;
299     }
300     hexdump(mVendorData, mDataLen);
301     return ret;
302 }
303 
putNanConfig(transaction_id id,const NanConfigRequest * pReq)304 int NanCommand::putNanConfig(transaction_id id, const NanConfigRequest *pReq)
305 {
306     ALOGV("NAN_CONFIG");
307     size_t message_len = NAN_MAX_CONFIGURATION_REQ_SIZE;
308     int idx = 0;
309 
310     if (pReq == NULL ||
311         pReq->num_config_discovery_attr > NAN_MAX_POSTDISCOVERY_LEN) {
312         cleanup();
313         return WIFI_ERROR_INVALID_ARGS;
314     }
315 
316     message_len = sizeof(NanMsgHeader);
317 
318     message_len += \
319          (
320            pReq->config_sid_beacon ? (SIZEOF_TLV_HDR + \
321            sizeof(pReq->sid_beacon)) : 0 \
322          ) + \
323          (
324            pReq->config_master_pref ? (SIZEOF_TLV_HDR + \
325            sizeof(pReq->master_pref)) : 0 \
326          ) + \
327          (
328            pReq->config_rssi_proximity ? (SIZEOF_TLV_HDR + \
329            sizeof(pReq->rssi_proximity)) : 0 \
330          ) + \
331          (
332            pReq->config_5g_rssi_close_proximity ? (SIZEOF_TLV_HDR + \
333            sizeof(pReq->rssi_close_proximity_5g_val)) : 0 \
334          ) + \
335          (
336            pReq->config_rssi_window_size ? (SIZEOF_TLV_HDR + \
337            sizeof(pReq->rssi_window_size_val)) : 0 \
338          ) + \
339          (
340            pReq->config_cluster_attribute_val ? (SIZEOF_TLV_HDR + \
341            sizeof(pReq->config_cluster_attribute_val)) : 0 \
342          ) + \
343          (
344            pReq->config_scan_params ? (SIZEOF_TLV_HDR + \
345            NAN_MAX_SOCIAL_CHANNELS * sizeof(u32)) : 0 \
346          ) + \
347          (
348            pReq->config_random_factor_force ? (SIZEOF_TLV_HDR + \
349            sizeof(pReq->random_factor_force_val)) : 0 \
350           ) + \
351          (
352            pReq->config_hop_count_force ? (SIZEOF_TLV_HDR + \
353            sizeof(pReq->hop_count_force_val)) : 0 \
354          ) + \
355          (
356            pReq->config_conn_capability ? (SIZEOF_TLV_HDR + \
357            sizeof(u32)) : 0 \
358          );
359 
360     if (pReq->num_config_discovery_attr) {
361         for (idx = 0; idx < pReq->num_config_discovery_attr; idx ++) {
362             message_len += SIZEOF_TLV_HDR +\
363                 calcNanTransmitPostDiscoverySize(&pReq->discovery_attr_val[idx]);
364         }
365     }
366 
367     if (pReq->config_fam && \
368         calcNanFurtherAvailabilityMapSize(&pReq->fam_val)) {
369         message_len += (SIZEOF_TLV_HDR + \
370            calcNanFurtherAvailabilityMapSize(&pReq->fam_val));
371     }
372 
373     pNanConfigurationReqMsg pFwReq = (pNanConfigurationReqMsg)malloc(message_len);
374     if (pFwReq == NULL) {
375         cleanup();
376         return WIFI_ERROR_OUT_OF_MEMORY;
377     }
378 
379     ALOGV("Message Len %zu", message_len);
380     memset (pFwReq, 0, message_len);
381     pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
382     pFwReq->fwHeader.msgId = NAN_MSG_ID_CONFIGURATION_REQ;
383     pFwReq->fwHeader.msgLen = message_len;
384     pFwReq->fwHeader.transactionId = id;
385 
386     u8* tlvs = pFwReq->ptlv;
387     if (pReq->config_sid_beacon) {
388         tlvs = addTlv(NAN_TLV_TYPE_SID_BEACON, sizeof(pReq->sid_beacon),
389                       (const u8*)&pReq->sid_beacon, tlvs);
390     }
391     if (pReq->config_master_pref) {
392         tlvs = addTlv(NAN_TLV_TYPE_MASTER_PREFERENCE, sizeof(pReq->master_pref),
393                       (const u8*)&pReq->master_pref, tlvs);
394     }
395 
396     if (pReq->config_rssi_window_size) {
397         tlvs = addTlv(NAN_TLV_TYPE_RSSI_AVERAGING_WINDOW_SIZE, sizeof(pReq->rssi_window_size_val),
398                       (const u8*)&pReq->rssi_window_size_val, tlvs);
399     }
400     if (pReq->config_rssi_proximity) {
401         tlvs = addTlv(NAN_TLV_TYPE_24G_RSSI_CLOSE_PROXIMITY, sizeof(pReq->rssi_proximity),
402                       (const u8*)&pReq->rssi_proximity, tlvs);
403     }
404     if (pReq->config_scan_params) {
405         u32 socialChannelParamVal[NAN_MAX_SOCIAL_CHANNELS];
406         /* Fill the social channel param */
407         fillNanSocialChannelParamVal(&pReq->scan_params_val,
408                                  socialChannelParamVal);
409         int i;
410         for (i = 0; i < NAN_MAX_SOCIAL_CHANNELS; i++) {
411             tlvs = addTlv(NAN_TLV_TYPE_SOCIAL_CHANNEL_SCAN_PARAMS,
412                           sizeof(socialChannelParamVal[i]),
413                           (const u8*)&socialChannelParamVal[i], tlvs);
414         }
415     }
416     if (pReq->config_random_factor_force) {
417         tlvs = addTlv(NAN_TLV_TYPE_RANDOM_FACTOR_FORCE,
418                       sizeof(pReq->random_factor_force_val),
419                       (const u8*)&pReq->random_factor_force_val, tlvs);
420     }
421     if (pReq->config_hop_count_force) {
422         tlvs = addTlv(NAN_TLV_TYPE_HOP_COUNT_FORCE,
423                       sizeof(pReq->hop_count_force_val),
424                       (const u8*)&pReq->hop_count_force_val, tlvs);
425     }
426     if (pReq->config_conn_capability) {
427         u32 val = \
428         getNanTransmitPostConnectivityCapabilityVal(&pReq->conn_capability_val);
429         tlvs = addTlv(NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_TRANSMIT,
430                       sizeof(val), (const u8*)&val, tlvs);
431     }
432     if (pReq->num_config_discovery_attr) {
433         for (idx = 0; idx < pReq->num_config_discovery_attr; idx ++) {
434             fillNanTransmitPostDiscoveryVal(&pReq->discovery_attr_val[idx],
435                                             (u8*)(tlvs + SIZEOF_TLV_HDR));
436             tlvs = addTlv(NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_TRANSMIT,
437                           calcNanTransmitPostDiscoverySize(
438                               &pReq->discovery_attr_val[idx]),
439                           (const u8*)(tlvs + SIZEOF_TLV_HDR), tlvs);
440         }
441     }
442     if (pReq->config_fam && \
443         calcNanFurtherAvailabilityMapSize(&pReq->fam_val)) {
444         fillNanFurtherAvailabilityMapVal(&pReq->fam_val,
445                                         (u8*)(tlvs + SIZEOF_TLV_HDR));
446         tlvs = addTlv(NAN_TLV_TYPE_FURTHER_AVAILABILITY_MAP,
447                       calcNanFurtherAvailabilityMapSize(&pReq->fam_val),
448                       (const u8*)(tlvs + SIZEOF_TLV_HDR), tlvs);
449     }
450 
451     mVendorData = (char*)pFwReq;
452     mDataLen = message_len;
453 
454     int ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
455     if (ret < 0) {
456         ALOGE("%s: put_bytes Error:%d",__func__, ret);
457         cleanup();
458         return ret;
459     }
460     hexdump(mVendorData, mDataLen);
461     return ret;
462 }
463 
464 
putNanPublish(transaction_id id,const NanPublishRequest * pReq)465 int NanCommand::putNanPublish(transaction_id id, const NanPublishRequest *pReq)
466 {
467     ALOGV("NAN_PUBLISH");
468     if (pReq == NULL) {
469         cleanup();
470         return WIFI_ERROR_INVALID_ARGS;
471     }
472 
473     size_t message_len =
474         sizeof(NanMsgHeader) + sizeof(NanPublishServiceReqParams) +
475         (pReq->service_name_len ? SIZEOF_TLV_HDR + pReq->service_name_len : 0) +
476         (pReq->service_specific_info_len ? SIZEOF_TLV_HDR + pReq->service_specific_info_len : 0) +
477         (pReq->rx_match_filter_len ? SIZEOF_TLV_HDR + pReq->rx_match_filter_len : 0) +
478         (pReq->tx_match_filter_len ? SIZEOF_TLV_HDR + pReq->tx_match_filter_len : 0);
479 
480     pNanPublishServiceReqMsg pFwReq = (pNanPublishServiceReqMsg)malloc(message_len);
481     if (pFwReq == NULL) {
482         cleanup();
483         return WIFI_ERROR_OUT_OF_MEMORY;
484     }
485 
486     ALOGV("Message Len %zu", message_len);
487     memset(pFwReq, 0, message_len);
488     pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
489     pFwReq->fwHeader.msgId = NAN_MSG_ID_PUBLISH_SERVICE_REQ;
490     pFwReq->fwHeader.msgLen = message_len;
491     if (pReq->publish_id == 0) {
492         pFwReq->fwHeader.handle = 0xFFFF;
493     } else {
494         pFwReq->fwHeader.handle = pReq->publish_id;
495     }
496     pFwReq->fwHeader.transactionId = id;
497 
498     pFwReq->publishServiceReqParams.ttl = pReq->ttl;
499     pFwReq->publishServiceReqParams.period = pReq->period;
500     pFwReq->publishServiceReqParams.reserved = 0;
501     pFwReq->publishServiceReqParams.publishType = pReq->publish_type;
502     pFwReq->publishServiceReqParams.txType = pReq->tx_type;
503 
504     pFwReq->publishServiceReqParams.rssiThresholdFlag = pReq->rssi_threshold_flag;
505     pFwReq->publishServiceReqParams.matchAlg = pReq->publish_match_indicator;
506     pFwReq->publishServiceReqParams.count = pReq->publish_count;
507     pFwReq->publishServiceReqParams.connmap = pReq->connmap;
508     pFwReq->publishServiceReqParams.pubTerminatedIndDisableFlag =
509                                    (pReq->recv_indication_cfg & BIT_0) ? 1 : 0;
510     pFwReq->publishServiceReqParams.pubMatchExpiredIndDisableFlag =
511                                    (pReq->recv_indication_cfg & BIT_1) ? 1 : 0;
512     pFwReq->publishServiceReqParams.followupRxIndDisableFlag =
513                                    (pReq->recv_indication_cfg & BIT_2) ? 1 : 0;
514 
515     pFwReq->publishServiceReqParams.reserved2 = 0;
516 
517     u8* tlvs = pFwReq->ptlv;
518     if (pReq->service_name_len) {
519         tlvs = addTlv(NAN_TLV_TYPE_SERVICE_NAME, pReq->service_name_len,
520                       (const u8*)&pReq->service_name[0], tlvs);
521     }
522     if (pReq->service_specific_info_len) {
523         tlvs = addTlv(NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO, pReq->service_specific_info_len,
524                       (const u8*)&pReq->service_specific_info[0], tlvs);
525     }
526     if (pReq->rx_match_filter_len) {
527         tlvs = addTlv(NAN_TLV_TYPE_RX_MATCH_FILTER, pReq->rx_match_filter_len,
528                       (const u8*)&pReq->rx_match_filter[0], tlvs);
529     }
530     if (pReq->tx_match_filter_len) {
531         tlvs = addTlv(NAN_TLV_TYPE_TX_MATCH_FILTER, pReq->tx_match_filter_len,
532                       (const u8*)&pReq->tx_match_filter[0], tlvs);
533     }
534 
535     mVendorData = (char *)pFwReq;
536     mDataLen = message_len;
537 
538     int ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
539     if (ret < 0) {
540         ALOGE("%s: put_bytes Error:%d",__func__, ret);
541         cleanup();
542         return ret;
543     }
544     hexdump(mVendorData, mDataLen);
545     return ret;
546 }
547 
putNanPublishCancel(transaction_id id,const NanPublishCancelRequest * pReq)548 int NanCommand::putNanPublishCancel(transaction_id id, const NanPublishCancelRequest *pReq)
549 {
550     ALOGV("NAN_PUBLISH_CANCEL");
551     if (pReq == NULL) {
552         cleanup();
553         return WIFI_ERROR_INVALID_ARGS;
554     }
555     size_t message_len = sizeof(NanPublishServiceCancelReqMsg);
556 
557     pNanPublishServiceCancelReqMsg pFwReq =
558         (pNanPublishServiceCancelReqMsg)malloc(message_len);
559     if (pFwReq == NULL) {
560         cleanup();
561         return WIFI_ERROR_OUT_OF_MEMORY;
562     }
563 
564     ALOGV("Message Len %zu", message_len);
565     memset(pFwReq, 0, message_len);
566     pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
567     pFwReq->fwHeader.msgId = NAN_MSG_ID_PUBLISH_SERVICE_CANCEL_REQ;
568     pFwReq->fwHeader.msgLen = message_len;
569     pFwReq->fwHeader.handle = pReq->publish_id;
570     pFwReq->fwHeader.transactionId = id;
571 
572     mVendorData = (char *)pFwReq;
573     mDataLen = message_len;
574 
575     int ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
576     if (ret < 0) {
577         ALOGE("%s: put_bytes Error:%d",__func__, ret);
578         cleanup();
579         return ret;
580     }
581     hexdump(mVendorData, mDataLen);
582     return ret;
583 }
584 
putNanSubscribe(transaction_id id,const NanSubscribeRequest * pReq)585 int NanCommand::putNanSubscribe(transaction_id id,
586                                 const NanSubscribeRequest *pReq)
587 {
588 
589     ALOGV("NAN_SUBSCRIBE");
590     if (pReq == NULL) {
591         cleanup();
592         return WIFI_ERROR_INVALID_ARGS;
593     }
594 
595     size_t message_len =
596         sizeof(NanMsgHeader) + sizeof(NanSubscribeServiceReqParams) +
597         (pReq->service_name_len ? SIZEOF_TLV_HDR + pReq->service_name_len : 0) +
598         (pReq->service_specific_info_len ? SIZEOF_TLV_HDR + pReq->service_specific_info_len : 0) +
599         (pReq->rx_match_filter_len ? SIZEOF_TLV_HDR + pReq->rx_match_filter_len : 0) +
600         (pReq->tx_match_filter_len ? SIZEOF_TLV_HDR + pReq->tx_match_filter_len : 0);
601 
602     message_len += \
603         (pReq->num_intf_addr_present * (SIZEOF_TLV_HDR + NAN_MAC_ADDR_LEN));
604 
605     pNanSubscribeServiceReqMsg pFwReq = (pNanSubscribeServiceReqMsg)malloc(message_len);
606     if (pFwReq == NULL) {
607         cleanup();
608         return WIFI_ERROR_OUT_OF_MEMORY;
609     }
610 
611     ALOGV("Message Len %zu", message_len);
612     memset(pFwReq, 0, message_len);
613     pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
614     pFwReq->fwHeader.msgId = NAN_MSG_ID_SUBSCRIBE_SERVICE_REQ;
615     pFwReq->fwHeader.msgLen = message_len;
616     if (pReq->subscribe_id == 0) {
617         pFwReq->fwHeader.handle = 0xFFFF;
618     } else {
619         pFwReq->fwHeader.handle = pReq->subscribe_id;
620     }
621     pFwReq->fwHeader.transactionId = id;
622 
623     pFwReq->subscribeServiceReqParams.ttl = pReq->ttl;
624     pFwReq->subscribeServiceReqParams.period = pReq->period;
625     pFwReq->subscribeServiceReqParams.subscribeType = pReq->subscribe_type;
626     pFwReq->subscribeServiceReqParams.srfAttr = pReq->serviceResponseFilter;
627     pFwReq->subscribeServiceReqParams.srfInclude = pReq->serviceResponseInclude;
628     pFwReq->subscribeServiceReqParams.srfSend = pReq->useServiceResponseFilter;
629     pFwReq->subscribeServiceReqParams.ssiRequired = pReq->ssiRequiredForMatchIndication;
630     pFwReq->subscribeServiceReqParams.matchAlg = pReq->subscribe_match_indicator;
631     pFwReq->subscribeServiceReqParams.count = pReq->subscribe_count;
632     pFwReq->subscribeServiceReqParams.rssiThresholdFlag = pReq->rssi_threshold_flag;
633     pFwReq->subscribeServiceReqParams.subTerminatedIndDisableFlag =
634                                    (pReq->recv_indication_cfg & BIT_0) ? 1 : 0;
635     pFwReq->subscribeServiceReqParams.subMatchExpiredIndDisableFlag =
636                                    (pReq->recv_indication_cfg & BIT_1) ? 1 : 0;
637     pFwReq->subscribeServiceReqParams.followupRxIndDisableFlag =
638                                    (pReq->recv_indication_cfg & BIT_2) ? 1 : 0;
639     pFwReq->subscribeServiceReqParams.connmap = pReq->connmap;
640     pFwReq->subscribeServiceReqParams.reserved = 0;
641 
642     u8* tlvs = pFwReq->ptlv;
643     if (pReq->service_name_len) {
644         tlvs = addTlv(NAN_TLV_TYPE_SERVICE_NAME, pReq->service_name_len,
645                       (const u8*)&pReq->service_name[0], tlvs);
646     }
647     if (pReq->service_specific_info_len) {
648         tlvs = addTlv(NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO, pReq->service_specific_info_len,
649                       (const u8*)&pReq->service_specific_info[0], tlvs);
650     }
651     if (pReq->rx_match_filter_len) {
652         tlvs = addTlv(NAN_TLV_TYPE_RX_MATCH_FILTER, pReq->rx_match_filter_len,
653                       (const u8*)&pReq->rx_match_filter[0], tlvs);
654     }
655     if (pReq->tx_match_filter_len) {
656         tlvs = addTlv(NAN_TLV_TYPE_TX_MATCH_FILTER, pReq->tx_match_filter_len,
657                       (const u8*)&pReq->tx_match_filter[0], tlvs);
658     }
659 
660     int i = 0;
661     for (i = 0; i < pReq->num_intf_addr_present; i++)
662     {
663         tlvs = addTlv(NAN_TLV_TYPE_MAC_ADDRESS,
664                       NAN_MAC_ADDR_LEN,
665                       (const u8*)&pReq->intf_addr[i][0], tlvs);
666     }
667 
668     mVendorData = (char *)pFwReq;
669     mDataLen = message_len;
670     int ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
671     if (ret < 0) {
672         ALOGE("%s: put_bytes Error:%d",__func__, ret);
673         cleanup();
674         return ret;
675     }
676     hexdump(mVendorData, mDataLen);
677     return ret;
678 }
679 
putNanSubscribeCancel(transaction_id id,const NanSubscribeCancelRequest * pReq)680 int NanCommand::putNanSubscribeCancel(transaction_id id,
681                                       const NanSubscribeCancelRequest *pReq)
682 {
683     ALOGV("NAN_SUBSCRIBE_CANCEL");
684     if (pReq == NULL) {
685         cleanup();
686         return WIFI_ERROR_INVALID_ARGS;
687     }
688     size_t message_len = sizeof(NanSubscribeServiceCancelReqMsg);
689 
690     pNanSubscribeServiceCancelReqMsg pFwReq =
691         (pNanSubscribeServiceCancelReqMsg)malloc(message_len);
692     if (pFwReq == NULL) {
693         cleanup();
694         return WIFI_ERROR_OUT_OF_MEMORY;
695     }
696 
697     ALOGV("Message Len %zu", message_len);
698     memset(pFwReq, 0, message_len);
699     pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
700     pFwReq->fwHeader.msgId = NAN_MSG_ID_SUBSCRIBE_SERVICE_CANCEL_REQ;
701     pFwReq->fwHeader.msgLen = message_len;
702     pFwReq->fwHeader.handle = pReq->subscribe_id;
703     pFwReq->fwHeader.transactionId = id;
704 
705     mVendorData = (char *)pFwReq;
706     mDataLen = message_len;
707     int ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
708     if (ret < 0) {
709         ALOGE("%s: put_bytes Error:%d",__func__, ret);
710         cleanup();
711         return ret;
712     }
713     hexdump(mVendorData, mDataLen);
714     return ret;
715 }
716 
717 
putNanTransmitFollowup(transaction_id id,const NanTransmitFollowupRequest * pReq)718 int NanCommand::putNanTransmitFollowup(transaction_id id,
719                                        const NanTransmitFollowupRequest *pReq)
720 {
721     ALOGV("TRANSMIT_FOLLOWUP");
722     if (pReq == NULL) {
723         cleanup();
724         return WIFI_ERROR_INVALID_ARGS;
725     }
726 
727     size_t message_len =
728         sizeof(NanMsgHeader) + sizeof(NanTransmitFollowupReqParams) +
729         (pReq->service_specific_info_len ? SIZEOF_TLV_HDR +
730          pReq->service_specific_info_len : 0);
731 
732     /* Mac address needs to be added in TLV */
733     message_len += (SIZEOF_TLV_HDR + sizeof(pReq->addr));
734 
735     pNanTransmitFollowupReqMsg pFwReq = (pNanTransmitFollowupReqMsg)malloc(message_len);
736     if (pFwReq == NULL) {
737         cleanup();
738         return WIFI_ERROR_OUT_OF_MEMORY;
739     }
740 
741     ALOGV("Message Len %zu", message_len);
742     memset (pFwReq, 0, message_len);
743     pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
744     pFwReq->fwHeader.msgId = NAN_MSG_ID_TRANSMIT_FOLLOWUP_REQ;
745     pFwReq->fwHeader.msgLen = message_len;
746     pFwReq->fwHeader.handle = pReq->publish_subscribe_id;
747     pFwReq->fwHeader.transactionId = id;
748 
749     pFwReq->transmitFollowupReqParams.matchHandle = pReq->requestor_instance_id;
750     if (pReq->priority != NAN_TX_PRIORITY_HIGH) {
751         pFwReq->transmitFollowupReqParams.priority = 1;
752     } else {
753         pFwReq->transmitFollowupReqParams.priority = 2;
754     }
755     pFwReq->transmitFollowupReqParams.window = pReq->dw_or_faw;
756     pFwReq->transmitFollowupReqParams.followupTxRspDisableFlag =
757                                    (pReq->recv_indication_cfg & BIT_0) ? 1 : 0;
758     pFwReq->transmitFollowupReqParams.reserved = 0;
759 
760     u8* tlvs = pFwReq->ptlv;
761 
762     /* Mac address needs to be added in TLV */
763     tlvs = addTlv(NAN_TLV_TYPE_MAC_ADDRESS, sizeof(pReq->addr),
764                   (const u8*)&pReq->addr[0], tlvs);
765     u16 tlv_type = NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO;
766 
767     if (pReq->service_specific_info_len) {
768         tlvs = addTlv(tlv_type, pReq->service_specific_info_len,
769                       (const u8*)&pReq->service_specific_info[0], tlvs);
770     }
771 
772     mVendorData = (char *)pFwReq;
773     mDataLen = message_len;
774 
775     int ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
776     if (ret < 0) {
777         ALOGE("%s: put_bytes Error:%d",__func__, ret);
778         cleanup();
779         return ret;
780     }
781     hexdump(mVendorData, mDataLen);
782     return ret;
783 }
784 
putNanStats(transaction_id id,const NanStatsRequest * pReq)785 int NanCommand::putNanStats(transaction_id id, const NanStatsRequest *pReq)
786 {
787     ALOGV("NAN_STATS");
788     if (pReq == NULL) {
789         cleanup();
790         return WIFI_ERROR_INVALID_ARGS;
791     }
792     size_t message_len = sizeof(NanStatsReqMsg);
793 
794     pNanStatsReqMsg pFwReq =
795         (pNanStatsReqMsg)malloc(message_len);
796     if (pFwReq == NULL) {
797         cleanup();
798         return WIFI_ERROR_OUT_OF_MEMORY;
799     }
800 
801     ALOGV("Message Len %zu", message_len);
802     memset(pFwReq, 0, message_len);
803     pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
804     pFwReq->fwHeader.msgId = NAN_MSG_ID_STATS_REQ;
805     pFwReq->fwHeader.msgLen = message_len;
806     pFwReq->fwHeader.transactionId = id;
807 
808     pFwReq->statsReqParams.statsType = pReq->stats_type;
809     pFwReq->statsReqParams.clear = pReq->clear;
810     pFwReq->statsReqParams.reserved = 0;
811 
812     mVendorData = (char *)pFwReq;
813     mDataLen = message_len;
814 
815     int ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
816     if (ret < 0) {
817         ALOGE("%s: put_bytes Error:%d",__func__, ret);
818         cleanup();
819         return ret;
820     }
821     hexdump(mVendorData, mDataLen);
822     return ret;
823 }
824 
putNanTCA(transaction_id id,const NanTCARequest * pReq)825 int NanCommand::putNanTCA(transaction_id id, const NanTCARequest *pReq)
826 {
827     ALOGV("NAN_TCA");
828     if (pReq == NULL) {
829         cleanup();
830         return WIFI_ERROR_INVALID_ARGS;
831     }
832     size_t message_len = sizeof(NanTcaReqMsg);
833 
834     message_len += (SIZEOF_TLV_HDR + 2 * sizeof(u32));
835     pNanTcaReqMsg pFwReq =
836         (pNanTcaReqMsg)malloc(message_len);
837     if (pFwReq == NULL) {
838         cleanup();
839         return WIFI_ERROR_OUT_OF_MEMORY;
840     }
841 
842     ALOGV("Message Len %zu", message_len);
843     memset(pFwReq, 0, message_len);
844     pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
845     pFwReq->fwHeader.msgId = NAN_MSG_ID_TCA_REQ;
846     pFwReq->fwHeader.msgLen = message_len;
847     pFwReq->fwHeader.transactionId = id;
848 
849     u32 tcaReqParams[2];
850     memset (tcaReqParams, 0, sizeof(tcaReqParams));
851     tcaReqParams[0] = (pReq->rising_direction_evt_flag & 0x01);
852     tcaReqParams[0] |= (pReq->falling_direction_evt_flag & 0x01) << 1;
853     tcaReqParams[0] |= (pReq->clear & 0x01) << 2;
854     tcaReqParams[1] = pReq->threshold;
855 
856     u8* tlvs = pFwReq->ptlv;
857 
858     if (pReq->tca_type == NAN_TCA_ID_CLUSTER_SIZE) {
859         tlvs = addTlv(NAN_TLV_TYPE_CLUSTER_SIZE_REQ, sizeof(tcaReqParams),
860                       (const u8*)&tcaReqParams[0], tlvs);
861     }
862     else {
863         ALOGE("%s: Unrecognized tca_type:%u", __FUNCTION__, pReq->tca_type);
864         cleanup();
865         return WIFI_ERROR_INVALID_ARGS;
866     }
867 
868     mVendorData = (char *)pFwReq;
869     mDataLen = message_len;
870 
871     int ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
872     if (ret < 0) {
873         ALOGE("%s: put_bytes Error:%d",__func__, ret);
874         cleanup();
875         return ret;
876     }
877     hexdump(mVendorData, mDataLen);
878     return ret;
879 }
880 
putNanBeaconSdfPayload(transaction_id id,const NanBeaconSdfPayloadRequest * pReq)881 int NanCommand::putNanBeaconSdfPayload(transaction_id id,
882                                        const NanBeaconSdfPayloadRequest *pReq)
883 {
884     ALOGV("NAN_BEACON_SDF_PAYLAOD");
885     if (pReq == NULL) {
886         cleanup();
887         return WIFI_ERROR_INVALID_ARGS;
888     }
889     size_t message_len = sizeof(NanMsgHeader) + \
890         SIZEOF_TLV_HDR + sizeof(u32) + \
891         pReq->vsa.vsa_len;
892 
893     pNanBeaconSdfPayloadReqMsg pFwReq =
894         (pNanBeaconSdfPayloadReqMsg)malloc(message_len);
895     if (pFwReq == NULL) {
896         cleanup();
897         return WIFI_ERROR_OUT_OF_MEMORY;
898     }
899 
900     ALOGV("Message Len %zu", message_len);
901     memset(pFwReq, 0, message_len);
902     pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
903     pFwReq->fwHeader.msgId = NAN_MSG_ID_BEACON_SDF_REQ;
904     pFwReq->fwHeader.msgLen = message_len;
905     pFwReq->fwHeader.transactionId = id;
906 
907     /* Construct First 4 bytes of NanBeaconSdfPayloadReqMsg */
908     u32 temp = 0;
909     temp = pReq->vsa.payload_transmit_flag & 0x01;
910     temp |= (pReq->vsa.tx_in_discovery_beacon & 0x01) << 1;
911     temp |= (pReq->vsa.tx_in_sync_beacon & 0x01) << 2;
912     temp |= (pReq->vsa.tx_in_service_discovery & 0x01) << 3;
913     temp |= (pReq->vsa.vendor_oui & 0x00FFFFFF) << 8;
914 
915     int tlv_len = sizeof(u32) + pReq->vsa.vsa_len;
916     u8* tempBuf = (u8*)malloc(tlv_len);
917     if (tempBuf == NULL) {
918         ALOGE("%s: Malloc failed", __func__);
919         free(pFwReq);
920         cleanup();
921         return WIFI_ERROR_OUT_OF_MEMORY;
922     }
923     memset(tempBuf, 0, tlv_len);
924     memcpy(tempBuf, &temp, sizeof(u32));
925     memcpy((tempBuf + sizeof(u32)), pReq->vsa.vsa, pReq->vsa.vsa_len);
926 
927     u8* tlvs = pFwReq->ptlv;
928 
929     /* Write the TLVs to the message. */
930     tlvs = addTlv(NAN_TLV_TYPE_VENDOR_SPECIFIC_ATTRIBUTE_TRANSMIT, tlv_len,
931                   (const u8*)tempBuf, tlvs);
932     free(tempBuf);
933 
934     mVendorData = (char *)pFwReq;
935     mDataLen = message_len;
936 
937     int ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
938     if (ret < 0) {
939         ALOGE("%s: put_bytes Error:%d",__func__, ret);
940         cleanup();
941         return ret;
942     }
943     hexdump(mVendorData, mDataLen);
944     return ret;
945 }
946 
947 //callback handlers registered for nl message send
error_handler_nan(struct sockaddr_nl * nla,struct nlmsgerr * err,void * arg)948 static int error_handler_nan(struct sockaddr_nl *nla, struct nlmsgerr *err,
949                          void *arg)
950 {
951     struct sockaddr_nl * tmp;
952     int *ret = (int *)arg;
953     tmp = nla;
954     *ret = err->error;
955     ALOGE("%s: Error code:%d (%s)", __func__, *ret, strerror(-(*ret)));
956     return NL_STOP;
957 }
958 
959 //callback handlers registered for nl message send
ack_handler_nan(struct nl_msg * msg,void * arg)960 static int ack_handler_nan(struct nl_msg *msg, void *arg)
961 {
962     int *ret = (int *)arg;
963     struct nl_msg * a;
964 
965     ALOGE("%s: called", __func__);
966     a = msg;
967     *ret = 0;
968     return NL_STOP;
969 }
970 
971 //callback handlers registered for nl message send
finish_handler_nan(struct nl_msg * msg,void * arg)972 static int finish_handler_nan(struct nl_msg *msg, void *arg)
973 {
974   int *ret = (int *)arg;
975   struct nl_msg * a;
976 
977   ALOGE("%s: called", __func__);
978   a = msg;
979   *ret = 0;
980   return NL_SKIP;
981 }
982 
983 
984 //Override base class requestEvent and implement little differently here
985 //This will send the request message
986 //We dont wait for any response back in case of Nan as it is asynchronous
987 //thus no wait for condition.
requestEvent()988 int NanCommand::requestEvent()
989 {
990     int res;
991     struct nl_cb * cb;
992 
993     cb = nl_cb_alloc(NL_CB_DEFAULT);
994     if (!cb) {
995         ALOGE("%s: Callback allocation failed",__func__);
996         res = -1;
997         goto out;
998     }
999 
1000     /* send message */
1001     ALOGV("%s:Handle:%p Socket Value:%p", __func__, mInfo, mInfo->cmd_sock);
1002     res = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage());
1003     if (res < 0)
1004         goto out;
1005     res = 1;
1006 
1007     nl_cb_err(cb, NL_CB_CUSTOM, error_handler_nan, &res);
1008     nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler_nan, &res);
1009     nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler_nan, &res);
1010 
1011     // err is populated as part of finish_handler
1012     while (res > 0)
1013         nl_recvmsgs(mInfo->cmd_sock, cb);
1014 
1015 out:
1016     //free the VendorData
1017     if (mVendorData) {
1018         free(mVendorData);
1019     }
1020     mVendorData = NULL;
1021     //cleanup the mMsg
1022     mMsg.destroy();
1023     return res;
1024 }
1025 
calcNanTransmitPostDiscoverySize(const NanTransmitPostDiscovery * pPostDiscovery)1026 int NanCommand::calcNanTransmitPostDiscoverySize(
1027     const NanTransmitPostDiscovery *pPostDiscovery)
1028 {
1029     /* Fixed size of u32 for Conn Type, Device Role and R flag + Dur + Rsvd*/
1030     int ret = sizeof(u32);
1031     /* size of availability interval bit map is 4 bytes */
1032     ret += sizeof(u32);
1033     /* size of mac address is 6 bytes*/
1034     ret += (SIZEOF_TLV_HDR + NAN_MAC_ADDR_LEN);
1035     if (pPostDiscovery &&
1036         pPostDiscovery->type == NAN_CONN_WLAN_MESH) {
1037         /* size of WLAN_MESH_ID  */
1038         ret += (SIZEOF_TLV_HDR + \
1039                 pPostDiscovery->mesh_id_len);
1040     }
1041     if (pPostDiscovery &&
1042         pPostDiscovery->type == NAN_CONN_WLAN_INFRA) {
1043         /* size of Infrastructure ssid  */
1044         ret += (SIZEOF_TLV_HDR + \
1045                 pPostDiscovery->infrastructure_ssid_len);
1046     }
1047     ALOGV("%s:size:%d", __func__, ret);
1048     return ret;
1049 }
1050 
fillNanSocialChannelParamVal(const NanSocialChannelScanParams * pScanParams,u32 * pChannelParamArr)1051 void NanCommand::fillNanSocialChannelParamVal(
1052     const NanSocialChannelScanParams *pScanParams,
1053     u32* pChannelParamArr)
1054 {
1055     int i;
1056     if (pChannelParamArr) {
1057         memset(pChannelParamArr, 0,
1058                NAN_MAX_SOCIAL_CHANNELS * sizeof(u32));
1059         for (i= 0; i < NAN_MAX_SOCIAL_CHANNELS; i++) {
1060             pChannelParamArr[i] = pScanParams->scan_period[i] << 16;
1061             pChannelParamArr[i] |= pScanParams->dwell_time[i] << 8;
1062         }
1063         pChannelParamArr[NAN_CHANNEL_24G_BAND] |= 6;
1064         pChannelParamArr[NAN_CHANNEL_5G_BAND_LOW]|= 44;
1065         pChannelParamArr[NAN_CHANNEL_5G_BAND_HIGH]|= 149;
1066         ALOGV("%s: Filled SocialChannelParamVal", __func__);
1067         hexdump((char*)pChannelParamArr, NAN_MAX_SOCIAL_CHANNELS * sizeof(u32));
1068     }
1069     return;
1070 }
1071 
getNanTransmitPostConnectivityCapabilityVal(const NanTransmitPostConnectivityCapability * pCapab)1072 u32 NanCommand::getNanTransmitPostConnectivityCapabilityVal(
1073     const NanTransmitPostConnectivityCapability *pCapab)
1074 {
1075     u32 ret = 0;
1076     ret |= (pCapab->payload_transmit_flag? 1:0) << 16;
1077     ret |= (pCapab->is_mesh_supported? 1:0) << 5;
1078     ret |= (pCapab->is_ibss_supported? 1:0) << 4;
1079     ret |= (pCapab->wlan_infra_field? 1:0) << 3;
1080     ret |= (pCapab->is_tdls_supported? 1:0) << 2;
1081     ret |= (pCapab->is_wfds_supported? 1:0) << 1;
1082     ret |= (pCapab->is_wfd_supported? 1:0);
1083     ALOGV("%s: val:%d", __func__, ret);
1084     return ret;
1085 }
1086 
fillNanTransmitPostDiscoveryVal(const NanTransmitPostDiscovery * pTxDisc,u8 * pOutValue)1087 void NanCommand::fillNanTransmitPostDiscoveryVal(
1088     const NanTransmitPostDiscovery *pTxDisc,
1089     u8 *pOutValue)
1090 {
1091 
1092     if (pTxDisc && pOutValue) {
1093         u8 *tlvs = &pOutValue[8];
1094         pOutValue[0] = pTxDisc->type;
1095         pOutValue[1] = pTxDisc->role;
1096         pOutValue[2] = (pTxDisc->transmit_freq? 1:0);
1097         pOutValue[2] |= ((pTxDisc->duration & 0x03) << 1);
1098         memcpy(&pOutValue[4], &pTxDisc->avail_interval_bitmap,
1099                sizeof(pTxDisc->avail_interval_bitmap));
1100         tlvs = addTlv(NAN_TLV_TYPE_MAC_ADDRESS,
1101                     NAN_MAC_ADDR_LEN,
1102                     (const u8*)&pTxDisc->addr[0],
1103                     tlvs);
1104         if (pTxDisc->type == NAN_CONN_WLAN_MESH) {
1105             tlvs = addTlv(NAN_TLV_TYPE_WLAN_MESH_ID,
1106                         pTxDisc->mesh_id_len,
1107                         (const u8*)&pTxDisc->mesh_id[0],
1108                         tlvs);
1109         }
1110         if (pTxDisc->type == NAN_CONN_WLAN_INFRA) {
1111             tlvs = addTlv(NAN_TLV_TYPE_WLAN_INFRA_SSID,
1112                         pTxDisc->infrastructure_ssid_len,
1113                         (const u8*)&pTxDisc->infrastructure_ssid_val[0],
1114                         tlvs);
1115         }
1116         ALOGV("%s: Filled TransmitPostDiscoveryVal", __func__);
1117         hexdump((char*)pOutValue, calcNanTransmitPostDiscoverySize(pTxDisc));
1118     }
1119 
1120     return;
1121 }
1122 
fillNanFurtherAvailabilityMapVal(const NanFurtherAvailabilityMap * pFam,u8 * pOutValue)1123 void NanCommand::fillNanFurtherAvailabilityMapVal(
1124     const NanFurtherAvailabilityMap *pFam,
1125     u8 *pOutValue)
1126 {
1127     int idx = 0;
1128 
1129     if (pFam && pOutValue) {
1130         u32 famsize = calcNanFurtherAvailabilityMapSize(pFam);
1131         pNanFurtherAvailabilityMapAttrTlv pFwReq = \
1132             (pNanFurtherAvailabilityMapAttrTlv)pOutValue;
1133 
1134         memset(pOutValue, 0, famsize);
1135         pFwReq->numChan = pFam->numchans;
1136         for (idx = 0; idx < pFam->numchans; idx++) {
1137             const NanFurtherAvailabilityChannel *pFamChan =  \
1138                 &pFam->famchan[idx];
1139             pNanFurtherAvailabilityChan pFwFamChan = \
1140                 (pNanFurtherAvailabilityChan)((u8*)&pFwReq->pFaChan[0] + \
1141                 (idx * sizeof(NanFurtherAvailabilityChan)));
1142 
1143             pFwFamChan->entryCtrl.availIntDuration = \
1144                 pFamChan->entry_control;
1145             pFwFamChan->entryCtrl.mapId = \
1146                 pFamChan->mapid;
1147             pFwFamChan->opClass =  pFamChan->class_val;
1148             pFwFamChan->channel = pFamChan->channel;
1149             memcpy(&pFwFamChan->availIntBitmap,
1150                    &pFamChan->avail_interval_bitmap,
1151                    sizeof(pFwFamChan->availIntBitmap));
1152         }
1153         ALOGV("%s: Filled FurtherAvailabilityMapVal", __func__);
1154         hexdump((char*)pOutValue, famsize);
1155     }
1156     return;
1157 }
1158 
calcNanFurtherAvailabilityMapSize(const NanFurtherAvailabilityMap * pFam)1159 int NanCommand::calcNanFurtherAvailabilityMapSize(
1160     const NanFurtherAvailabilityMap *pFam)
1161 {
1162     int ret = 0;
1163     if (pFam && pFam->numchans &&
1164         pFam->numchans <= NAN_MAX_FAM_CHANNELS) {
1165         /* Fixed size of u8 for numchans*/
1166         ret = sizeof(u8);
1167         /* numchans * sizeof(FamChannels) */
1168         ret += (pFam->numchans * sizeof(NanFurtherAvailabilityChan));
1169     }
1170     ALOGV("%s:size:%d", __func__, ret);
1171     return ret;
1172 }
1173 
putNanCapabilities(transaction_id id)1174 int NanCommand::putNanCapabilities(transaction_id id)
1175 {
1176     size_t message_len = sizeof(NanCapabilitiesReqMsg);
1177 
1178     pNanCapabilitiesReqMsg pFwReq = (pNanCapabilitiesReqMsg)malloc(message_len);
1179     if (pFwReq == NULL) {
1180         cleanup();
1181         return WIFI_ERROR_OUT_OF_MEMORY;
1182     }
1183 
1184     memset (pFwReq, 0, message_len);
1185     pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
1186     pFwReq->fwHeader.msgId = NAN_MSG_ID_CAPABILITIES_REQ;
1187     pFwReq->fwHeader.msgLen = message_len;
1188     pFwReq->fwHeader.transactionId = id;
1189 
1190     mVendorData = (char*)pFwReq;
1191     mDataLen = message_len;
1192 
1193     int ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
1194     if (ret < 0) {
1195         ALOGE("%s: put_bytes Error:%d",__func__, ret);
1196         cleanup();
1197         return ret;
1198     }
1199     hexdump(mVendorData, mDataLen);
1200     return ret;
1201 }
1202