[APR-1794] wlbt: NAN NDP APIs
[GitHub/MotorolaMobilityLLC/hardware-samsung_slsi-scsc_wifibt-wifi_hal.git] / wifi_nan.cpp
CommitLineData
d3a587e8
JPS
1
2#include <stdint.h>
3#include <stddef.h>
4#include <fcntl.h>
5#include <sys/socket.h>
6#include <netlink/genl/genl.h>
7#include <netlink/genl/family.h>
8#include <netlink/genl/ctrl.h>
9#include <linux/rtnetlink.h>
10#include <netpacket/packet.h>
11#include <linux/filter.h>
12#include <linux/errqueue.h>
13#include <linux/pkt_sched.h>
14#include <netlink/object-api.h>
15#include <netlink/netlink.h>
16#include <netlink/socket.h>
17#include <netlink/handlers.h>
18
19#include "sync.h"
20
21#include <utils/Log.h>
22
23#include "wifi_hal.h"
24#include "common.h"
25#include "cpp_bindings.h"
c2afddcb
JPS
26#include "nan_data.h"
27#include "nan_common.h"
d3a587e8
JPS
28
29#define SLSI_WIFI_HAL_NAN_VERSION 1
30
d3a587e8
JPS
31class NanCommand : public WifiCommand {
32 static NanCallbackHandler callbackEventHandler;
33 int subscribeID[2];
34 int publishID[2];
35 int followupID[2];
650a9e6a
JPS
36 transaction_id followupTid;
37 transaction_id publishTid;
38 transaction_id publishCancelTid;
39 transaction_id subscribeTid;
40 transaction_id subscribeCancelTid;
41 transaction_id enableTid;
42 transaction_id disableTid;
43 transaction_id configTid;
44 transaction_id capabilitiesTid;
d3a587e8
JPS
45 int version;
46 NanCapabilities capabilities;
c2afddcb 47 NanDataCommand datacmd;
d3a587e8
JPS
48
49 void registerNanEvents(void) {
50 registerVendorHandler(GOOGLE_OUI, SLSI_NAN_EVENT_PUBLISH_TERMINATED);
51 registerVendorHandler(GOOGLE_OUI, SLSI_NAN_EVENT_MATCH);
52 registerVendorHandler(GOOGLE_OUI, SLSI_NAN_EVENT_MATCH_EXPIRED);
53 registerVendorHandler(GOOGLE_OUI, SLSI_NAN_EVENT_SUBSCRIBE_TERMINATED);
54 registerVendorHandler(GOOGLE_OUI, SLSI_NAN_EVENT_FOLLOWUP);
55 registerVendorHandler(GOOGLE_OUI, SLSI_NAN_EVENT_DISCOVERY_ENGINE);
650a9e6a 56 registerVendorHandler(GOOGLE_OUI, SLSI_NAN_EVENT_TRANSMIT_FOLLOWUP_STATUS);
c2afddcb
JPS
57 registerVendorHandler(GOOGLE_OUI, SLSI_NAN_EVENT_NDP_REQ);
58 registerVendorHandler(GOOGLE_OUI, SLSI_NAN_EVENT_NDP_CFM);
59 registerVendorHandler(GOOGLE_OUI, SLSI_NAN_EVENT_NDP_END);
d3a587e8
JPS
60 }
61
62 void unregisterNanEvents(void) {
63 unregisterVendorHandler(GOOGLE_OUI, SLSI_NAN_EVENT_PUBLISH_TERMINATED);
64 unregisterVendorHandler(GOOGLE_OUI, SLSI_NAN_EVENT_MATCH);
65 unregisterVendorHandler(GOOGLE_OUI, SLSI_NAN_EVENT_MATCH_EXPIRED);
66 unregisterVendorHandler(GOOGLE_OUI, SLSI_NAN_EVENT_SUBSCRIBE_TERMINATED);
67 unregisterVendorHandler(GOOGLE_OUI, SLSI_NAN_EVENT_FOLLOWUP);
68 unregisterVendorHandler(GOOGLE_OUI, SLSI_NAN_EVENT_DISCOVERY_ENGINE);
650a9e6a 69 unregisterVendorHandler(GOOGLE_OUI, SLSI_NAN_EVENT_TRANSMIT_FOLLOWUP_STATUS);
c2afddcb
JPS
70 unregisterVendorHandler(GOOGLE_OUI, SLSI_NAN_EVENT_NDP_REQ);
71 unregisterVendorHandler(GOOGLE_OUI, SLSI_NAN_EVENT_NDP_CFM);
72 unregisterVendorHandler(GOOGLE_OUI, SLSI_NAN_EVENT_NDP_END);
d3a587e8
JPS
73 }
74
75 int processResponse(WifiEvent &reply, NanResponseMsg *response) {
76 NanCapabilities *capabilities = &response->body.nan_capabilities;
77 nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);
d3a587e8
JPS
78 unsigned int val;
79
80 for(nl_iterator nl_itr(vendor_data); nl_itr.has_next(); nl_itr.next()) {
81 switch(nl_itr.get_type()) {
82 case NAN_REPLY_ATTR_STATUS_TYPE:
83 response->status = NanStatusType(nl_itr.get_u32());
84 break;
85 case NAN_REPLY_ATTR_VALUE:
86 val = nl_itr.get_u32();
87 if (val) {
88 strncpy(response->nan_error, "Lower_layer_error",NAN_ERROR_STR_LEN);
89 }
90 break;
91 case NAN_REPLY_ATTR_RESPONSE_TYPE:
92 response->response_type = NanResponseType(nl_itr.get_u32());
93 break;
94 case NAN_REPLY_ATTR_PUBLISH_SUBSCRIBE_TYPE:
95 response->body.publish_response.publish_id = nl_itr.get_u16();
96 break;
c2afddcb
JPS
97 case NAN_REPLY_ATTR_NDP_INSTANCE_ID:
98 response->body.data_request_response.ndp_instance_id = nl_itr.get_u32();
99 break;
d3a587e8
JPS
100 case NAN_REPLY_ATTR_CAP_MAX_CONCURRENT_CLUSTER:
101 capabilities->max_concurrent_nan_clusters = nl_itr.get_u32();
102 break;
103 case NAN_REPLY_ATTR_CAP_MAX_PUBLISHES:
104 capabilities->max_publishes = nl_itr.get_u32();
105 break;
106 case NAN_REPLY_ATTR_CAP_MAX_SUBSCRIBES:
107 capabilities->max_subscribes = nl_itr.get_u32();
108 break;
109 case NAN_REPLY_ATTR_CAP_MAX_SERVICE_NAME_LEN:
110 capabilities->max_service_name_len = nl_itr.get_u32();
111 break;
112 case NAN_REPLY_ATTR_CAP_MAX_MATCH_FILTER_LEN:
113 capabilities->max_match_filter_len = nl_itr.get_u32();
114 break;
115 case NAN_REPLY_ATTR_CAP_MAX_TOTAL_MATCH_FILTER_LEN:
116 capabilities->max_total_match_filter_len = nl_itr.get_u32();
117 break;
118 case NAN_REPLY_ATTR_CAP_MAX_SERVICE_SPECIFIC_INFO_LEN:
119 capabilities->max_service_specific_info_len = nl_itr.get_u32();
120 break;
121 case NAN_REPLY_ATTR_CAP_MAX_VSA_DATA_LEN:
122 capabilities->max_vsa_data_len = nl_itr.get_u32();
123 break;
124 case NAN_REPLY_ATTR_CAP_MAX_MESH_DATA_LEN:
125 capabilities->max_mesh_data_len = nl_itr.get_u32();
126 break;
127 case NAN_REPLY_ATTR_CAP_MAX_NDI_INTERFACES:
128 capabilities->max_ndi_interfaces = nl_itr.get_u32();
129 break;
130 case NAN_REPLY_ATTR_CAP_MAX_NDP_SESSIONS:
131 capabilities->max_ndp_sessions = nl_itr.get_u32();
132 break;
133 case NAN_REPLY_ATTR_CAP_MAX_APP_INFO_LEN:
134 capabilities->max_app_info_len = nl_itr.get_u32();
135 break;
c2afddcb
JPS
136
137 case NAN_REPLY_ATTR_CAP_MAX_QUEUED_TRANSMIT_FOLLOWUP_MGS:
138 capabilities->max_queued_transmit_followup_msgs = nl_itr.get_u32();
139 break;
140 case NAN_REPLY_ATTR_CAP_MAX_NDP_SUPPORTED_BANDS:
141 capabilities->ndp_supported_bands = nl_itr.get_u32();
142 break;
143 case NAN_REPLY_ATTR_CAP_MAX_CIPHER_SUITES_SUPPORTED:
144 capabilities->cipher_suites_supported = nl_itr.get_u32();
145 break;
146 case NAN_REPLY_ATTR_CAP_MAX_SCID_LEN:
147 capabilities->max_scid_len = nl_itr.get_u32();
148 break;
149 case NAN_REPLY_ATTR_CAP_NDP_SECURITY_SUPPORTED:
150 capabilities->is_ndp_security_supported = (bool)nl_itr.get_u32();
151 break;
152 case NAN_REPLY_ATTR_CAP_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN:
153 capabilities->max_sdea_service_specific_info_len = nl_itr.get_u32();
154 break;
155 case NAN_REPLY_ATTR_CAP_MAX_SUBSCRIBE_ADDRESS:
156 capabilities->max_subscribe_address = nl_itr.get_u32();
157 break;
158 case NAN_REPLY_ATTR_CAP_NDPE_ATTR_SUPPORTED:
159 capabilities->ndpe_attr_supported = nl_itr.get_u32();
160 break;
d3a587e8
JPS
161 default :
162 ALOGE("received unknown type(%d) in response", nl_itr.get_type());
163 return NL_SKIP;
164 }
165 }
166 this->capabilities = *capabilities;
167 return NL_OK;
168 }
169
170 int processMatchEvent(WifiEvent &event) {
171 NanMatchInd ind;
172 memset(&ind,0,sizeof(NanMatchInd));
173 int famchan_idx = 0, disc_idx = 0;
174 nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
175
176 for(nl_iterator nl_itr(vendor_data); nl_itr.has_next(); nl_itr.next()) {
177 switch(nl_itr.get_type()) {
178 case NAN_EVT_ATTR_MATCH_PUBLISH_SUBSCRIBE_ID:
179 ind.publish_subscribe_id = nl_itr.get_u16();
180 break;
181 case NAN_EVT_ATTR_MATCH_REQUESTOR_INSTANCE_ID:
182 ind.requestor_instance_id = nl_itr.get_u32();
183 break;
184 case NAN_EVT_ATTR_MATCH_ADDR:
185 memcpy(ind.addr, nl_itr.get_data(), NAN_MAC_ADDR_LEN);
186 break;
187 case NAN_EVT_ATTR_MATCH_SERVICE_SPECIFIC_INFO_LEN:
188 ind.service_specific_info_len = nl_itr.get_u16();
189 break;
190 case NAN_EVT_ATTR_MATCH_SERVICE_SPECIFIC_INFO:
191 memcpy(ind.service_specific_info, nl_itr.get_data(), ind.service_specific_info_len);
192 break;
193 case NAN_EVT_ATTR_MATCH_SDF_MATCH_FILTER_LEN:
194 ind.sdf_match_filter_len = nl_itr.get_u16();
195 break;
196 case NAN_EVT_ATTR_MATCH_SDF_MATCH_FILTER:
197 memcpy(ind.sdf_match_filter, nl_itr.get_data(), ind.sdf_match_filter_len);
198 break;
199 case NAN_EVT_ATTR_MATCH_MATCH_OCCURED_FLAG:
200 ind.match_occured_flag = nl_itr.get_u8();
201 break;
202 case NAN_EVT_ATTR_MATCH_OUT_OF_RESOURCE_FLAG:
203 ind.out_of_resource_flag = nl_itr.get_u8();
204 break;
205 case NAN_EVT_ATTR_MATCH_RSSI_VALUE:
206 ind.rssi_value = nl_itr.get_u8();
207 break;
208 case NAN_EVT_ATTR_MATCH_CONN_CAPABILITY_IS_IBSS_SUPPORTED:
209 ind.conn_capability.is_ibss_supported = nl_itr.get_u8();
210 break;
211 case NAN_EVT_ATTR_MATCH_CONN_CAPABILITY_IS_WFD_SUPPORTED:
212 ind.conn_capability.is_wfd_supported = nl_itr.get_u8();
213 break;
214 case NAN_EVT_ATTR_MATCH_CONN_CAPABILITY_IS_WFDS_SUPPORTED:
215 ind.conn_capability.is_wfds_supported = nl_itr.get_u8();
216 break;
217 case NAN_EVT_ATTR_MATCH_CONN_CAPABILITY_IS_TDLS_SUPPORTED:
218 ind.conn_capability.is_tdls_supported = nl_itr.get_u8();
219 break;
220 case NAN_EVT_ATTR_MATCH_CONN_CAPABILITY_IS_MESH_SUPPORTED:
221 ind.conn_capability.is_mesh_supported= nl_itr.get_u8();
222 break;
223 case NAN_EVT_ATTR_MATCH_CONN_CAPABILITY_WLAN_INFRA_FIELD:
224 ind.conn_capability.wlan_infra_field = nl_itr.get_u8();
225 break;
226 case NAN_EVT_ATTR_MATCH_NUM_RX_DISCOVERY_ATTR:
227 ind.num_rx_discovery_attr = nl_itr.get_u8();
228 break;
229 case NAN_EVT_ATTR_MATCH_RX_DISCOVERY_ATTR:
230 NanReceivePostDiscovery *disc_attr;
231 disc_attr = &ind.discovery_attr[disc_idx];
232 disc_idx++;
233 for(nl_iterator nl_nested_itr((struct nlattr *)nl_itr.get_data()); nl_nested_itr.has_next(); nl_nested_itr.next()) {
234 switch(nl_nested_itr.get_type()) {
235 case NAN_EVT_ATTR_MATCH_DISC_ATTR_TYPE:
236 disc_attr->type = (NanConnectionType)nl_nested_itr.get_u8();
237 break;
238 case NAN_EVT_ATTR_MATCH_DISC_ATTR_ROLE:
239 disc_attr->role = (NanDeviceRole)nl_nested_itr.get_u8();
240 break;
241 case NAN_EVT_ATTR_MATCH_DISC_ATTR_DURATION:
242 disc_attr->duration = (NanAvailDuration)nl_nested_itr.get_u8();
243 break;
244 case NAN_EVT_ATTR_MATCH_DISC_ATTR_AVAIL_INTERVAL_BITMAP:
245 disc_attr->avail_interval_bitmap = nl_nested_itr.get_u32();
246 break;
247 case NAN_EVT_ATTR_MATCH_DISC_ATTR_MAPID:
248 disc_attr->mapid = nl_nested_itr.get_u8();
249 break;
250 case NAN_EVT_ATTR_MATCH_DISC_ATTR_ADDR:
251 memcpy(disc_attr->addr, nl_nested_itr.get_data(), NAN_MAC_ADDR_LEN);
252 break;
253 case NAN_EVT_ATTR_MATCH_DISC_ATTR_MESH_ID_LEN:
254 disc_attr->mesh_id_len = nl_nested_itr.get_u8();
255 break;
256 case NAN_EVT_ATTR_MATCH_DISC_ATTR_MESH_ID:
257 memcpy(disc_attr->mesh_id, nl_nested_itr.get_data(), disc_attr->mesh_id_len);
258 break;
259 case NAN_EVT_ATTR_MATCH_DISC_ATTR_INFRASTRUCTURE_SSID_LEN:
260 disc_attr->infrastructure_ssid_len = nl_nested_itr.get_u16();
261 break;
262 case NAN_EVT_ATTR_MATCH_DISC_ATTR_INFRASTRUCTURE_SSID_VAL:
263 memcpy(disc_attr->infrastructure_ssid_val, nl_nested_itr.get_data(), disc_attr->infrastructure_ssid_len);
264 break;
265 }
266 }
267 break;
268 case NAN_EVT_ATTR_MATCH_NUM_CHANS:
269 ind.num_chans = nl_itr.get_u8();
270 break;
271 case NAN_EVT_ATTR_MATCH_FAMCHAN:
272 NanFurtherAvailabilityChannel *famchan;
273 famchan = &ind.famchan[famchan_idx];
274 famchan_idx++;
275 for(nl_iterator nl_nested_itr((struct nlattr *)nl_itr.get_data()); nl_nested_itr.has_next(); nl_nested_itr.next()) {
276 switch(nl_nested_itr.get_type()) {
277 case NAN_EVT_ATTR_MATCH_FAM_ENTRY_CONTROL:
278 famchan->entry_control = (NanAvailDuration)nl_nested_itr.get_u8();
279 break;
280 case NAN_EVT_ATTR_MATCH_FAM_CLASS_VAL:
281 famchan->class_val = nl_nested_itr.get_u8();
282 break;
283 case NAN_EVT_ATTR_MATCH_FAM_CHANNEL:
284 famchan->channel = nl_nested_itr.get_u8();
285 break;
286 case NAN_EVT_ATTR_MATCH_FAM_MAPID:
287 famchan->mapid = nl_nested_itr.get_u8();
288 break;
289 case NAN_EVT_ATTR_MATCH_FAM_AVAIL_INTERVAL_BITMAP:
290 famchan->avail_interval_bitmap = nl_nested_itr.get_u32();
291 break;
292 }
293 }
45011ff7 294 break;
d3a587e8
JPS
295 case NAN_EVT_ATTR_MATCH_CLUSTER_ATTRIBUTE_LEN:
296 ind.cluster_attribute_len = nl_itr.get_u8();
297 break;
298 case NAN_EVT_ATTR_MATCH_CLUSTER_ATTRIBUTE:
299 memcpy(ind.cluster_attribute, nl_itr.get_data(), ind.cluster_attribute_len);
300 break;
f8c9e3bb
JPS
301 case NAN_EVT_ATTR_SDEA_LEN:
302 ind.sdea_service_specific_info_len = nl_itr.get_u16();
303 break;
304 case NAN_EVT_ATTR_SDEA:
305 memcpy(ind.sdea_service_specific_info, nl_itr.get_data(), ind.sdea_service_specific_info_len);
306 break;
e8aa68c3
JPS
307 case NAN_EVT_ATTR_SCID_LEN:
308 ind.scid_len = nl_itr.get_u32();
309 break;
310 case NAN_EVT_ATTR_SCID:
311 memcpy(ind.scid, nl_itr.get_data(), ind.scid_len);
312 break;
313 case NAN_EVT_ATTR_SDEA_PARAM_CONFIG_NAN_DATA_PATH:
314 ind.peer_sdea_params.config_nan_data_path = nl_itr.get_u8();
315 break;
316 case NAN_EVT_ATTR_SDEA_PARAM_NDP_TYPE:
317 ind.peer_sdea_params.ndp_type = (NdpType)nl_itr.get_u8();
318 break;
319 case NAN_EVT_ATTR_SDEA_PARAM_SECURITY_CONFIG:
320 ind.peer_sdea_params.security_cfg = (NanDataPathSecurityCfgStatus)nl_itr.get_u8();
321 break;
322 case NAN_EVT_ATTR_SDEA_PARAM_RANGE_STATE:
323 ind.peer_sdea_params.ranging_state = (NanRangingState)nl_itr.get_u8();
324 break;
325 case NAN_EVT_ATTR_SDEA_PARAM_RANGE_REPORT:
326 ind.peer_sdea_params.range_report = (NanRangeReport)nl_itr.get_u8();
327 break;
328 case NAN_EVT_ATTR_SDEA_PARAM_QOS_CFG:
329 ind.peer_sdea_params.qos_cfg = (NanQosCfgStatus)nl_itr.get_u8();
330 break;
331 case NAN_EVT_ATTR_RANGE_MEASUREMENT_MM:
332 ind.range_info.range_measurement_mm = nl_itr.get_u32();
333 break;
334 case NAN_EVT_ATTR_RANGEING_EVENT_TYPE:
335 ind.range_info.ranging_event_type = nl_itr.get_u32();
336 break;
d3a587e8
JPS
337 }
338 }
45011ff7 339
d3a587e8
JPS
340 if (this->callbackEventHandler.EventMatch)
341 this->callbackEventHandler.EventMatch(&ind);
342 return NL_OK;
343 }
344
345 int processMatchExpiredEvent(WifiEvent &event) {
346 NanMatchExpiredInd ind;
347 memset(&ind,0,sizeof(NanMatchExpiredInd));
348
349 for(nl_iterator nl_itr((struct nlattr *)event.get_vendor_data()); nl_itr.has_next(); nl_itr.next()) {
350 switch(nl_itr.get_type()) {
351 case NAN_EVT_ATTR_MATCH_PUBLISH_SUBSCRIBE_ID:
352 ind.publish_subscribe_id = nl_itr.get_u16();
353 break;
354 case NAN_EVT_ATTR_MATCH_REQUESTOR_INSTANCE_ID:
355 ind.requestor_instance_id = nl_itr.get_u32();
356 break;
357 default :
358 ALOGE("processMatchExpiredEvent: unknown attribute(%d)", nl_itr.get_type());
359 return NL_SKIP;
360 }
361 }
362
363 if (callbackEventHandler.EventMatchExpired)
364 callbackEventHandler.EventMatchExpired(&ind);
365
366 return NL_OK;
367 }
368
369 int processPublishTerminatedEvent(WifiEvent &event) {
370 NanPublishTerminatedInd ind;
371 memset(&ind,0,sizeof(ind));
372
373 for(nl_iterator nl_itr((struct nlattr *)event.get_vendor_data()); nl_itr.has_next(); nl_itr.next()) {
374 switch(nl_itr.get_type()) {
375 case NAN_EVT_ATTR_PUBLISH_ID:
376 ind.publish_id = nl_itr.get_u16();
377 break;
378 case NAN_EVT_ATTR_PUBLISH_REASON:
379 ind.reason = (NanStatusType)nl_itr.get_u32();
380 break;
381 default :
382 ALOGE("processPublishTerminatedEvent: unknown attribute(%d)", nl_itr.get_type());
383 return NL_SKIP;
384 }
385 }
386
387 if (callbackEventHandler.EventPublishTerminated)
388 callbackEventHandler.EventPublishTerminated(&ind);
389
390 return NL_OK;
391
392 }
393
394 int processSubscribeTerminatedEvent(WifiEvent &event) {
395 NanSubscribeTerminatedInd ind;
396 memset(&ind,0,sizeof(ind));
397
398 for(nl_iterator nl_itr((struct nlattr *)event.get_vendor_data()); nl_itr.has_next(); nl_itr.next()) {
399 switch(nl_itr.get_type()) {
400 case NAN_EVT_ATTR_SUBSCRIBE_ID:
401 ind.subscribe_id = nl_itr.get_u16();
402 break;
403 case NAN_EVT_ATTR_SUBSCRIBE_REASON:
404 ind.reason = (NanStatusType)nl_itr.get_u32();
405 break;
406 default :
407 ALOGE("processSubscribeTerminatedEvent: unknown attribute(%d)", nl_itr.get_type());
408 return NL_SKIP;
409 }
410 }
411
412 if (callbackEventHandler.EventSubscribeTerminated)
413 callbackEventHandler.EventSubscribeTerminated(&ind);
414
415 return NL_OK;
416 }
417
418 int processFollowupEvent(WifiEvent &event) {
419 NanFollowupInd ind;
f8c9e3bb 420 nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
d3a587e8
JPS
421 memset(&ind,0,sizeof(ind));
422
f8c9e3bb 423 for(nl_iterator nl_itr(vendor_data); nl_itr.has_next(); nl_itr.next()) {
d3a587e8
JPS
424 switch(nl_itr.get_type()) {
425 case NAN_EVT_ATTR_FOLLOWUP_PUBLISH_SUBSCRIBE_ID:
426 ind.publish_subscribe_id = nl_itr.get_u16();
427 break;
428 case NAN_EVT_ATTR_FOLLOWUP_REQUESTOR_INSTANCE_ID:
429 ind.requestor_instance_id = nl_itr.get_u32();
430 break;
431 case NAN_EVT_ATTR_FOLLOWUP_ADDR:
432 memcpy(ind.addr, nl_itr.get_data(), NAN_MAC_ADDR_LEN);
433 break;
434 case NAN_EVT_ATTR_FOLLOWUP_DW_OR_FAW:
435 ind.dw_or_faw = nl_itr.get_u8();
436 break;
437 case NAN_EVT_ATTR_FOLLOWUP_SERVICE_SPECIFIC_INFO_LEN:
438 ind.service_specific_info_len = nl_itr.get_u16();
439 break;
440 case NAN_EVT_ATTR_FOLLOWUP_SERVICE_SPECIFIC_INFO:
441 memcpy(ind.service_specific_info, nl_itr.get_data(), ind.service_specific_info_len);
442 break;
f8c9e3bb
JPS
443 case NAN_EVT_ATTR_SDEA_LEN:
444 ind.sdea_service_specific_info_len = nl_itr.get_u16();
445 break;
446 case NAN_EVT_ATTR_SDEA:
447 memcpy(ind.sdea_service_specific_info, nl_itr.get_data(), ind.sdea_service_specific_info_len);
448 break;
d3a587e8
JPS
449 default :
450 ALOGE("processNanDisabledEvent: unknown attribute(%d)", nl_itr.get_type());
451 return NL_SKIP;
452 }
453 }
454
455 if (callbackEventHandler.EventFollowup)
456 callbackEventHandler.EventFollowup(&ind);
457
458 return NL_OK;
459 }
460
461 int processNanDisabledEvent(WifiEvent &event) {
462 NanDisabledInd ind;
463 memset(&ind,0,sizeof(ind));
f8c9e3bb
JPS
464 nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
465 for(nl_iterator nl_itr(vendor_data); nl_itr.has_next(); nl_itr.next()) {
d3a587e8
JPS
466 switch(nl_itr.get_type()) {
467 case NAN_EVT_ATTR_DISABLED_REASON:
468 ind.reason = (NanStatusType)nl_itr.get_u32();
469 break;
470 default :
471 ALOGE("processNanDisabledEvent: unknown attribute(%d)", nl_itr.get_type());
472 return NL_SKIP;
473 }
474 }
475
476 if (callbackEventHandler.EventDisabled)
477 callbackEventHandler.EventDisabled(&ind);
478
479 return NL_OK;
480 }
481
482 int processNanDiscoveryEvent(WifiEvent &event) {
483 NanDiscEngEventInd ind;
484 memset(&ind,0,sizeof(ind));
cdcc8b21 485 u8 *addr = NULL;
f8c9e3bb
JPS
486 nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
487 for(nl_iterator nl_itr(vendor_data); nl_itr.has_next(); nl_itr.next()) {
d3a587e8
JPS
488 switch(nl_itr.get_type()) {
489 case NAN_EVT_ATTR_DISCOVERY_ENGINE_EVT_TYPE:
490 ind.event_type = (NanDiscEngEventType)nl_itr.get_u16();
491 break;
492 case NAN_EVT_ATTR_DISCOVERY_ENGINE_MAC_ADDR:
493 addr = (u8 *)nl_itr.get_data();
494 break;
495 default :
496 ALOGE("processNanDiscoveryEvent: unknown attribute(%d)", nl_itr.get_type());
497 return NL_SKIP;
498 }
499 }
cdcc8b21
JPS
500 if (addr) {
501 if (ind.event_type == NAN_EVENT_ID_DISC_MAC_ADDR)
502 memcpy(ind.data.mac_addr.addr, addr, NAN_MAC_ADDR_LEN);
503 else
504 memcpy(ind.data.cluster.addr, addr, NAN_MAC_ADDR_LEN);
505 } else {
506 ALOGE("processNanDiscoveryEvent: No Mac/cluster Address");
507 }
d3a587e8
JPS
508
509 if (callbackEventHandler.EventDiscEngEvent)
510 callbackEventHandler.EventDiscEngEvent(&ind);
511
512 return NL_OK;
513 }
514
650a9e6a
JPS
515 int processNanFollowupStatus(WifiEvent &event) {
516 NanTransmitFollowupInd ind;
517 memset(&ind,0,sizeof(ind));
518 ind.id = followupTid;
519 followupTid = 0;
520 nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
521 for(nl_iterator nl_itr(vendor_data); nl_itr.has_next(); nl_itr.next()) {
522 if (nl_itr.get_type() == NAN_EVT_ATTR_STATUS) {
523 ind.reason = (NanStatusType)nl_itr.get_u16();
524 } else {
525 ALOGE("processNanFollowupStatus: unknown attribute(%d)", nl_itr.get_type());
526 return NL_SKIP;
527 }
528 }
529
530 if (callbackEventHandler.EventTransmitFollowup)
531 callbackEventHandler.EventTransmitFollowup(&ind);
532
533 return NL_OK;
534 }
535
e8aa68c3
JPS
536 int putSdeaParams(NanSdeaCtrlParams *sdea_params, WifiRequest *request)
537 {
538 int result;
539
540 if (!sdea_params->config_nan_data_path)
541 return 0;
542
543 result = request->put_u8(NAN_REQ_ATTR_SDEA_PARAM_NDP_TYPE, sdea_params->ndp_type);
544 CHECK_WIFI_STATUS_RETURN_FAIL(result, "enable:Failed to put SDEA PARAM ndp_type");
545
546 result = request->put_u8(NAN_REQ_ATTR_SDEA_PARAM_SECURITY_CFG, sdea_params->security_cfg);
547 CHECK_WIFI_STATUS_RETURN_FAIL(result, "enable:Failed to put SDEA PARAM security_cfg");
548
549 result = request->put_u8(NAN_REQ_ATTR_SDEA_PARAM_RANGING_STATE, sdea_params->ranging_state);
550 CHECK_WIFI_STATUS_RETURN_FAIL(result, "enable:Failed to put SDEA PARAM ranging_state");
551
552 result = request->put_u8(NAN_REQ_ATTR_SDEA_PARAM_RANGE_REPORT, sdea_params->range_report);
553 CHECK_WIFI_STATUS_RETURN_FAIL(result, "enable:Failed to put SDEA PARAM range_report");
554
555 result = request->put_u8(NAN_REQ_ATTR_SDEA_PARAM_QOS_CFG, sdea_params->qos_cfg);
556 CHECK_WIFI_STATUS_RETURN_FAIL(result, "enable:Failed to put SDEA PARAM qos_cfg");
557
558 return result;
559 }
560
561 int putRangingCfg(NanRangingCfg *ranging_cfg, WifiRequest *request)
562 {
563 int result;
564
565 result = request->put_u32(NAN_REQ_ATTR_RANGING_CFG_INTERVAL, ranging_cfg->ranging_interval_msec);
566 CHECK_WIFI_STATUS_RETURN_FAIL(result, "enable:Failed to put Ranging CFG ranging_interval_msec");
567
568 result = request->put_u32(NAN_REQ_ATTR_RANGING_CFG_INDICATION, ranging_cfg->config_ranging_indications);
569 CHECK_WIFI_STATUS_RETURN_FAIL(result, "enable:Failed to put Ranging CFG config_ranging_indications");
570
571 result = request->put_u32(NAN_REQ_ATTR_RANGING_CFG_INGRESS_MM, ranging_cfg->distance_ingress_mm);
572 CHECK_WIFI_STATUS_RETURN_FAIL(result, "enable:Failed to put Ranging CFG distance_ingress_mm");
573
574 result = request->put_u32(NAN_REQ_ATTR_RANGING_CFG_EGRESS_MM, ranging_cfg->distance_egress_mm);
575 CHECK_WIFI_STATUS_RETURN_FAIL(result, "enable:Failed to put Ranging CFG distance_egress_mm");
576
577 return result;
578 }
579
580 int putRangeResponseCfg(NanRangeResponseCfg *range_resp_cfg, WifiRequest *request)
581 {
582 int result;
583
584 result = request->put_u16(NAN_REQ_ATTR_RANGE_RESPONSE_CFG_PUBLISH_ID, range_resp_cfg->publish_id);
585 CHECK_WIFI_STATUS_RETURN_FAIL(result, "Failed to put range response cfg::publish_id");
586
587 result = request->put_u32(NAN_REQ_ATTR_RANGE_RESPONSE_CFG_REQUESTOR_ID, range_resp_cfg->requestor_instance_id);
588 CHECK_WIFI_STATUS_RETURN_FAIL(result, "Failed to put range response cfg::requestor_instance_id");
589
590 result = request->put_addr(NAN_REQ_ATTR_RANGE_RESPONSE_CFG_PEER_ADDR, range_resp_cfg->peer_addr);
591 CHECK_WIFI_STATUS_RETURN_FAIL(result, "Failed to put range response cfg::peer_addr");
592
593 result = request->put_u16(NAN_REQ_ATTR_RANGE_RESPONSE_CFG_RANGING_RESPONSE, range_resp_cfg->ranging_response);
594 CHECK_WIFI_STATUS_RETURN_FAIL(result, "Failed to put range response cfg::ranging_response");
595
596 return result;
597 }
598
d3a587e8
JPS
599public:
600 NanCommand(wifi_interface_handle iface, int id)
c2afddcb 601 : WifiCommand(iface, id), datacmd()
d3a587e8
JPS
602 {
603 subscribeID[0] = 0;
604 subscribeID[1] = 0;
605 publishID[0] = 0;
606 publishID[1] = 0;
607 followupID[0] = 0;
650a9e6a
JPS
608 followupID[1] = 0;
609
610 followupTid = 0;
611 publishTid = 0;
612 publishCancelTid = 0;
613 subscribeTid = 0;
614 subscribeCancelTid = 0;
615 enableTid = 0;
616 disableTid = 0;
617 configTid = 0;
618 capabilitiesTid = 0;
619
d3a587e8
JPS
620 version = 0;
621 memset(&capabilities, 0, sizeof(capabilities));
622 }
623
650a9e6a
JPS
624 int enable(transaction_id id, NanEnableRequest *msg) {
625 ALOGD("NAN enable id:%d", id);
d3a587e8
JPS
626 WifiRequest request(familyId(), ifaceId());
627
628 int result = request.create(GOOGLE_OUI, SLSI_NL80211_VENDOR_SUBCMD_NAN_ENABLE);
629 CHECK_WIFI_STATUS_RETURN_FAIL(result, "enable:Failed to create WifiRequest");
630
631 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
632 if (!data) {
633 ALOGE("enable: request.attr_start fail");
634 return WIFI_ERROR_OUT_OF_MEMORY;
635 }
49e66671
JPS
636 /* Valid master pref values are 2-254 */
637 int master_pref;
638 if (msg->master_pref < 2)
639 master_pref = 2;
640 else if (msg->master_pref > 254)
641 master_pref = 254;
642 else
643 master_pref = msg->master_pref;
644 result = request.put_u8(NAN_REQ_ATTR_MASTER_PREF, master_pref);
d3a587e8
JPS
645 CHECK_WIFI_STATUS_RETURN_FAIL(result, "enable:Failed to put master_pref");
646
647 result = request.put_u16(NAN_REQ_ATTR_CLUSTER_LOW, msg->cluster_low);
648 CHECK_WIFI_STATUS_RETURN_FAIL(result, "enable:Failed to put cluster_low");
649
650 result = request.put_u16(NAN_REQ_ATTR_CLUSTER_HIGH, msg->cluster_high);
651 CHECK_WIFI_STATUS_RETURN_FAIL(result, "enable:Failed to put cluster_high");
652
653 CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_support_5g, msg->support_5g_val,
654 NAN_REQ_ATTR_SUPPORT_5G_VAL, request, result, "enable:Failed to put support_5g_val");
655
656 CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_sid_beacon, msg->sid_beacon_val,
657 NAN_REQ_ATTR_SID_BEACON_VAL, request, result, "enable:Failed to put sid_beacon_val");
658
659 CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_2dot4g_rssi_close, msg->rssi_close_2dot4g_val,
660 NAN_REQ_ATTR_RSSI_CLOSE_2G4_VAL, request, result, "enable:Failed to put rssi_close_2dot4g_val");
661
662 CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_2dot4g_rssi_middle, msg->rssi_middle_2dot4g_val,
663 NAN_REQ_ATTR_RSSI_MIDDLE_2G4_VAL, request, result, "enable:Failed to put rssi_middle_2dot4g_val");
664
665 CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_2dot4g_rssi_proximity, msg->rssi_proximity_2dot4g_val,
666 NAN_REQ_ATTR_RSSI_PROXIMITY_2G4_VAL, request, result, "enable:Failed to put rssi_proximity_2dot4g_val");
667
668 CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_hop_count_limit, msg->hop_count_limit_val,
669 NAN_REQ_ATTR_HOP_COUNT_LIMIT_VAL, request, result, "enable:Failed to put hop_count_limit_val");
670
671 CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_2dot4g_support, msg->support_2dot4g_val,
672 NAN_REQ_ATTR_SUPPORT_2G4_VAL, request, result, "enable:Failed to put support_2dot4g_val");
673
674 CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_2dot4g_beacons, msg->beacon_2dot4g_val,
675 NAN_REQ_ATTR_BEACONS_2G4_VAL, request, result, "enable:Failed to put beacon_2dot4g_val");
676
677 CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_2dot4g_sdf, msg->sdf_2dot4g_val,
678 NAN_REQ_ATTR_SDF_2G4_VAL, request, result, "enable:Failed to put sdf_2dot4g_val");
679
680 CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_5g_beacons, msg->beacon_5g_val,
681 NAN_REQ_ATTR_BEACON_5G_VAL, request, result, "enable:Failed to put beacon_5g_val");
682
683 CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_5g_sdf, msg->sdf_5g_val,
684 NAN_REQ_ATTR_SDF_5G_VAL, request, result, "enable:Failed to put sdf_5g_val");
685
686 CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_5g_rssi_close, msg->rssi_close_5g_val,
687 NAN_REQ_ATTR_RSSI_CLOSE_5G_VAL, request, result, "enable:Failed to put rssi_close_5g_val");
688
689 CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_5g_rssi_middle, msg->rssi_middle_5g_val,
690 NAN_REQ_ATTR_RSSI_MIDDLE_5G_VAL, request, result, "enable:Failed to put rssi_middle_5g_val");
691
692 CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_5g_rssi_close_proximity, msg->rssi_close_proximity_5g_val,
693 NAN_REQ_ATTR_RSSI_CLOSE_PROXIMITY_5G_VAL, request, result, "enable:Failed to put rssi_close_proximity_5g_val");
694
695 CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_rssi_window_size, msg->rssi_window_size_val,
696 NAN_REQ_ATTR_RSSI_WINDOW_SIZE_VAL, request, result, "enable:Failed to put rssi_window_size_val");
697
698 CHECK_CONFIG_PUT_32_RETURN_FAIL(msg->config_oui, msg->oui_val,
699 NAN_REQ_ATTR_OUI_VAL, request, result, "enable:Failed to put oui_val");
700
701 CHECK_CONFIG_PUT_RETURN_FAIL(msg->config_intf_addr, msg->intf_addr_val, NAN_MAC_ADDR_LEN,
702 NAN_REQ_ATTR_MAC_ADDR_VAL, request, result, "enable:Failed to put intf_addr_val");
703
704 CHECK_CONFIG_PUT_8_RETURN_FAIL(1, msg->config_cluster_attribute_val,
705 NAN_REQ_ATTR_CLUSTER_VAL, request, result, "enable:Failed to put config_cluster_attribute_val");
706
707 CHECK_CONFIG_PUT_RETURN_FAIL(msg->config_scan_params, msg->scan_params_val.dwell_time, sizeof(msg->scan_params_val.dwell_time),
708 NAN_REQ_ATTR_SOCIAL_CH_SCAN_DWELL_TIME, request, result, "enable:Failed to put scan_params_val.dwell_time");
709
710 CHECK_CONFIG_PUT_RETURN_FAIL(msg->config_scan_params, msg->scan_params_val.scan_period, sizeof(msg->scan_params_val.scan_period),
711 NAN_REQ_ATTR_SOCIAL_CH_SCAN_PERIOD, request, result, "enable:Failed to put scan_params_val.scan_period");
712
713 CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_random_factor_force, msg->random_factor_force_val,
714 NAN_REQ_ATTR_RANDOM_FACTOR_FORCE_VAL, request, result, "enable:Failed to put random_factor_force_val");
715
716 CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_hop_count_force, msg->hop_count_force_val,
717 NAN_REQ_ATTR_HOP_COUNT_FORCE_VAL, request, result, "enable:Failed to put hop_count_force_val");
718
719 CHECK_CONFIG_PUT_32_RETURN_FAIL(msg->config_24g_channel, msg->channel_24g_val,
720 NAN_REQ_ATTR_CHANNEL_2G4_MHZ_VAL, request, result, "enable:Failed to put channel_24g_val");
721
722 CHECK_CONFIG_PUT_32_RETURN_FAIL(msg->config_5g_channel, msg->channel_5g_val,
723 NAN_REQ_ATTR_CHANNEL_5G_MHZ_VAL, request, result, "enable:Failed to put channel_5g_val");
724
f8c9e3bb
JPS
725 CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_subscribe_sid_beacon, msg->subscribe_sid_beacon_val,
726 NAN_REQ_ATTR_SUBSCRIBE_SID_BEACON_VAL, request, result, "enable:Failed to put subscribe_sid_beacon_val");
727
728 CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_dw.config_2dot4g_dw_band, msg->config_dw.dw_2dot4g_interval_val,
729 NAN_REQ_ATTR_DW_2G4_INTERVAL, request, result, "enable:Failed to put dw_2dot4g_interval_val");
730
731 CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_dw.config_5g_dw_band, msg->config_dw.dw_5g_interval_val,
732 NAN_REQ_ATTR_DW_5G_INTERVAL, request, result, "enable:Failed to put dw_5g_interval_val");
733
c2afddcb 734 CHECK_CONFIG_PUT_32_RETURN_FAIL(msg->config_disc_mac_addr_randomization, msg->disc_mac_addr_rand_interval_sec,
f8c9e3bb
JPS
735 NAN_REQ_ATTR_DISC_MAC_ADDR_RANDOM_INTERVAL, request, result, "enable:Failed to put disc_mac_addr_rand_interval_sec");
736
c2afddcb
JPS
737 CHECK_CONFIG_PUT_32_RETURN_FAIL(msg->config_ndpe_attr, msg->use_ndpe_attr,
738 NAN_REQ_ATTR_USE_NDPE_ATTR, request, result, "enable:Failed to put use_ndpe_attr");
739
d3a587e8
JPS
740 request.attr_end(data);
741
742 registerNanEvents();
650a9e6a 743 enableTid = id;
d3a587e8
JPS
744 result = requestResponse(request);
745 if (result != WIFI_SUCCESS) {
650a9e6a 746 enableTid = 0;
d3a587e8
JPS
747 ALOGE("failed to NAN; result = %d", result);
748 unregisterNanEvents();
749 } else {
750 ALOGD("Start NAN...success");
751 }
752 return result;
753 }
754
650a9e6a 755 int disable(transaction_id id)
d3a587e8 756 {
650a9e6a 757 ALOGD("NAN disable id:%d", id);
d3a587e8
JPS
758 WifiRequest request(familyId(), ifaceId());
759
760 unregisterNanEvents();
761
762 int result = request.create(GOOGLE_OUI, SLSI_NL80211_VENDOR_SUBCMD_NAN_DISABLE);
763 CHECK_WIFI_STATUS_RETURN_FAIL(result, "disable:Failed to create WifiRequest");
650a9e6a 764 disableTid = id;
d3a587e8
JPS
765 result = requestResponse(request);
766 CHECK_WIFI_STATUS_RETURN_FAIL(result, "disable:Failed to requestResponse");
767 return result;
768 }
769
650a9e6a
JPS
770 int config(transaction_id id, NanConfigRequest *msg) {
771 ALOGD("NAN config id:%d", id);
d3a587e8
JPS
772 WifiRequest request(familyId(), ifaceId());
773
774 int result = request.create(GOOGLE_OUI, SLSI_NL80211_VENDOR_SUBCMD_NAN_CONFIG);
775 CHECK_WIFI_STATUS_RETURN_FAIL(result, "config:Failed to create WifiRequest");
776
777 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
778 if (!data) {
779 ALOGE("config: request.attr_start fail");
780 return WIFI_ERROR_OUT_OF_MEMORY;
781 }
782
783 CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_sid_beacon, msg->sid_beacon,
784 NAN_REQ_ATTR_SID_BEACON_VAL, request, result, "config:Failed to put sid_beacon");
785
786 CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_rssi_proximity, msg->rssi_proximity,
787 NAN_REQ_ATTR_RSSI_PROXIMITY_2G4_VAL, request, result, "config:Failed to put rssi_proximity");
788
789 CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_master_pref, msg->master_pref,
790 NAN_REQ_ATTR_MASTER_PREF, request, result, "config:Failed to put master_pref");
791
792 CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_5g_rssi_close_proximity, msg->rssi_close_proximity_5g_val,
793 NAN_REQ_ATTR_RSSI_CLOSE_PROXIMITY_5G_VAL, request, result, "config:Failed to put rssi_close_proximity_5g_val");
794
795 CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_rssi_window_size, msg->rssi_window_size_val,
796 NAN_REQ_ATTR_RSSI_WINDOW_SIZE_VAL, request, result, "config:Failed to put rssi_window_size_val");
797
798 CHECK_CONFIG_PUT_8_RETURN_FAIL(1, msg->config_cluster_attribute_val,
799 NAN_REQ_ATTR_CLUSTER_VAL, request, result, "config:Failed to put config_cluster_attribute_val");
800
801 CHECK_CONFIG_PUT_RETURN_FAIL(msg->config_scan_params, msg->scan_params_val.dwell_time, sizeof(msg->scan_params_val.dwell_time),
802 NAN_REQ_ATTR_SOCIAL_CH_SCAN_DWELL_TIME, request, result, "config:Failed to put scan_params_val.dwell_time");
803
804 CHECK_CONFIG_PUT_RETURN_FAIL(msg->config_scan_params, msg->scan_params_val.scan_period, sizeof(msg->scan_params_val.scan_period),
805 NAN_REQ_ATTR_SOCIAL_CH_SCAN_PERIOD, request, result, "config:Failed to put scan_params_val.scan_period");
806
807 CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_random_factor_force, msg->random_factor_force_val,
808 NAN_REQ_ATTR_RANDOM_FACTOR_FORCE_VAL, request, result, "config:Failed to put random_factor_force_val");
809
810 CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_hop_count_force, msg->hop_count_force_val,
811 NAN_REQ_ATTR_HOP_COUNT_FORCE_VAL, request, result, "config:Failed to put hop_count_force_val");
812
813 CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_conn_capability, msg->conn_capability_val.payload_transmit_flag,
814 NAN_REQ_ATTR_CONN_CAPABILITY_PAYLOAD_TX, request, result, "config:Failed to put payload_transmit_flag");
815
816 CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_conn_capability, msg->conn_capability_val.is_wfd_supported,
817 NAN_REQ_ATTR_CONN_CAPABILITY_WFD, request, result, "config:Failed to put is_wfd_supported");
818
819 CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_conn_capability, msg->conn_capability_val.is_wfds_supported,
820 NAN_REQ_ATTR_CONN_CAPABILITY_WFDS, request, result, "config:Failed to put is_wfds_supported");
821
822 CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_conn_capability, msg->conn_capability_val.is_tdls_supported,
823 NAN_REQ_ATTR_CONN_CAPABILITY_TDLS, request, result, "config:Failed to put is_tdls_supported");
824
825 CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_conn_capability, msg->conn_capability_val.is_ibss_supported,
826 NAN_REQ_ATTR_CONN_CAPABILITY_IBSS, request, result, "config:Failed to put is_ibss_supported");
827
828 CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_conn_capability, msg->conn_capability_val.is_mesh_supported,
829 NAN_REQ_ATTR_CONN_CAPABILITY_MESH, request, result, "config:Failed to put is_mesh_supported");
830
831 CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_conn_capability, msg->conn_capability_val.wlan_infra_field,
832 NAN_REQ_ATTR_CONN_CAPABILITY_WLAN_INFRA, request, result, "config:Failed to put wlan_infra_field");
833
834 if (msg->num_config_discovery_attr) {
835 CHECK_CONFIG_PUT_8_RETURN_FAIL(1, msg->num_config_discovery_attr,
836 NAN_REQ_ATTR_DISCOVERY_ATTR_NUM_ENTRIES, request, result, "config:Failed to put msg->num_config_discovery_attr");
837 for (int i = 0; i < msg->num_config_discovery_attr; i++) {
838 nlattr *nl_disc_attribute = request.attr_start(NAN_REQ_ATTR_DISCOVERY_ATTR_VAL);
839 NanTransmitPostDiscovery *discovery_attr = &msg->discovery_attr_val[i];
840 CHECK_CONFIG_PUT_8_RETURN_FAIL(1, discovery_attr->type,
841 NAN_REQ_ATTR_CONN_TYPE, request, result, "config:Failed to put discovery_attr->type");
842 CHECK_CONFIG_PUT_8_RETURN_FAIL(1, discovery_attr->role,
843 NAN_REQ_ATTR_NAN_ROLE, request, result, "config:Failed to put discovery_attr->role");
844 CHECK_CONFIG_PUT_8_RETURN_FAIL(1, discovery_attr->transmit_freq,
845 NAN_REQ_ATTR_TRANSMIT_FREQ, request, result, "config:Failed to put discovery_attr->transmit_freq");
846 CHECK_CONFIG_PUT_8_RETURN_FAIL(1, discovery_attr->duration,
847 NAN_REQ_ATTR_AVAILABILITY_DURATION, request, result, "config:Failed to put discovery_attr->duration");
848 CHECK_CONFIG_PUT_32_RETURN_FAIL(1, discovery_attr->avail_interval_bitmap,
849 NAN_REQ_ATTR_AVAILABILITY_INTERVAL, request, result, "config:Failed to put discovery_attr->avail_interval_bitmap");
850 CHECK_CONFIG_PUT_RETURN_FAIL(1, discovery_attr->addr, NAN_MAC_ADDR_LEN,
851 NAN_REQ_ATTR_MAC_ADDR_VAL, request, result, "config:Failed to put discovery_attr->addr");
852 CHECK_CONFIG_PUT_16_RETURN_FAIL(1, discovery_attr->mesh_id_len,
853 NAN_REQ_ATTR_MESH_ID_LEN, request, result, "config:Failed to put discovery_attr->mesh_id");
854 CHECK_CONFIG_PUT_RETURN_FAIL(discovery_attr->mesh_id_len, discovery_attr->mesh_id, discovery_attr->mesh_id_len,
855 NAN_REQ_ATTR_MESH_ID, request, result, "config:Failed to put discovery_attr->mesh_id");
856 CHECK_CONFIG_PUT_16_RETURN_FAIL(1, discovery_attr->infrastructure_ssid_len,
857 NAN_REQ_ATTR_INFRASTRUCTURE_SSID_LEN, request, result, "config:Failed to put discovery_attr->infrastructure_ssid_val");
858 CHECK_CONFIG_PUT_RETURN_FAIL(discovery_attr->infrastructure_ssid_len, discovery_attr->infrastructure_ssid_val, discovery_attr->infrastructure_ssid_len,
859 NAN_REQ_ATTR_INFRASTRUCTURE_SSID, request, result, "config:Failed to put discovery_attr->infrastructure_ssid_val");
860 request.attr_end(nl_disc_attribute);
861 }
862 }
863
864 if (msg->config_fam) {
865 CHECK_CONFIG_PUT_8_RETURN_FAIL(1, msg->fam_val.numchans,
866 NAN_REQ_ATTR_FURTHER_AVAIL_NUM_ENTRIES, request, result, "config:Failed to put msg->fam_val.numchans");
867 for (int i = 0; i < msg->fam_val.numchans; i++) {
868 nlattr *nl_fam_attribute = request.attr_start(NAN_REQ_ATTR_FURTHER_AVAIL_VAL);
869 NanFurtherAvailabilityChannel *further_avail_chan = &msg->fam_val.famchan[i];
870 CHECK_CONFIG_PUT_8_RETURN_FAIL(1, further_avail_chan->entry_control,
871 NAN_REQ_ATTR_FURTHER_AVAIL_ENTRY_CTRL, request, result, "config:Failed to put further_avail_chan->entry_control");
872 CHECK_CONFIG_PUT_8_RETURN_FAIL(1, further_avail_chan->class_val,
873 NAN_REQ_ATTR_FURTHER_AVAIL_CHAN_CLASS, request, result, "config:Failed to put further_avail_chan->class_val");
874 CHECK_CONFIG_PUT_8_RETURN_FAIL(1, further_avail_chan->channel,
875 NAN_REQ_ATTR_FURTHER_AVAIL_CHAN, request, result, "config:Failed to put further_avail_chan->channel");
876 CHECK_CONFIG_PUT_8_RETURN_FAIL(1, further_avail_chan->mapid,
877 NAN_REQ_ATTR_FURTHER_AVAIL_CHAN_MAPID, request, result, "config:Failed to put further_avail_chan->mapid");
878 CHECK_CONFIG_PUT_32_RETURN_FAIL(1, further_avail_chan->avail_interval_bitmap,
879 NAN_REQ_ATTR_FURTHER_AVAIL_INTERVAL_BITMAP, request, result, "config:Failed to put further_avail_chan->avail_interval_bitmap");
880 request.attr_end(nl_fam_attribute);
881 }
882 }
883
f8c9e3bb
JPS
884 CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_subscribe_sid_beacon, msg->subscribe_sid_beacon_val,
885 NAN_REQ_ATTR_SUBSCRIBE_SID_BEACON_VAL, request, result, "config:Failed to put subscribe_sid_beacon_val");
886
887 CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_dw.config_2dot4g_dw_band, msg->config_dw.dw_2dot4g_interval_val,
888 NAN_REQ_ATTR_DW_2G4_INTERVAL, request, result, "config:Failed to put dw_2dot4g_interval_val");
889
890 CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_dw.config_5g_dw_band, msg->config_dw.dw_5g_interval_val,
891 NAN_REQ_ATTR_DW_5G_INTERVAL, request, result, "config:Failed to put dw_5g_interval_val");
892
893 CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_disc_mac_addr_randomization, msg->disc_mac_addr_rand_interval_sec,
894 NAN_REQ_ATTR_DISC_MAC_ADDR_RANDOM_INTERVAL, request, result, "config:Failed to put disc_mac_addr_rand_interval_sec");
895
c2afddcb
JPS
896 CHECK_CONFIG_PUT_32_RETURN_FAIL(msg->config_ndpe_attr, msg->use_ndpe_attr,
897 NAN_REQ_ATTR_USE_NDPE_ATTR, request, result, "enable:Failed to put use_ndpe_attr");
898
d3a587e8 899 request.attr_end(data);
650a9e6a 900 configTid = id;
d3a587e8
JPS
901 result = requestResponse(request);
902 if (result != WIFI_SUCCESS) {
650a9e6a 903 configTid = 0;
d3a587e8
JPS
904 ALOGE("failed to set_config; result = %d", result);
905 } else {
49e66671 906 ALOGD("NAN config...success");
d3a587e8
JPS
907 }
908 return result;
909 }
910
911 static int setCallbackHandler(NanCallbackHandler handlers) {
912 callbackEventHandler = handlers;
913 return WIFI_SUCCESS;
914 }
915
916 static int getVersion(NanVersion *version) {
917 *version = SLSI_WIFI_HAL_NAN_VERSION;
918 return WIFI_SUCCESS;
919 }
920
650a9e6a
JPS
921 int publish(transaction_id id, NanPublishRequest *msg) {
922 ALOGD("NAN publish transId:%d publishId:%d publishType:%d", id, msg->publish_id, msg->publish_type);
d3a587e8
JPS
923 WifiRequest request(familyId(), ifaceId());
924
925 int result = request.create(GOOGLE_OUI, SLSI_NL80211_VENDOR_SUBCMD_NAN_PUBLISH);
926 CHECK_WIFI_STATUS_RETURN_FAIL(result, "publish:Failed to create WifiRequest");
927
928 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
929 if (!data) {
930 ALOGE("publish: request.attr_start fail");
931 return WIFI_ERROR_OUT_OF_MEMORY;
932 }
933
934 CHECK_CONFIG_PUT_16_RETURN_FAIL(msg->publish_id, msg->publish_id,
935 NAN_REQ_ATTR_PUBLISH_ID, request, result, "publish:Failed to put msg->publish_id");
936
937 CHECK_CONFIG_PUT_16_RETURN_FAIL(msg->ttl, msg->ttl,
938 NAN_REQ_ATTR_PUBLISH_TTL, request, result, "publish:Failed to put msg->ttl");
939
940 CHECK_CONFIG_PUT_16_RETURN_FAIL(1, msg->period,
941 NAN_REQ_ATTR_PUBLISH_PERIOD, request, result, "publish:Failed to put msg->period");
942
943 CHECK_CONFIG_PUT_8_RETURN_FAIL(1, msg->publish_type,
944 NAN_REQ_ATTR_PUBLISH_TYPE, request, result, "publish:Failed to put msg->publish_type");
945
946 CHECK_CONFIG_PUT_8_RETURN_FAIL(1, msg->tx_type,
947 NAN_REQ_ATTR_PUBLISH_TX_TYPE, request, result, "publish:Failed to put msg->tx_type");
948
949 CHECK_CONFIG_PUT_8_RETURN_FAIL(1, msg->publish_count,
950 NAN_REQ_ATTR_PUBLISH_COUNT, request, result, "publish:Failed to put msg->publish_count");
951
952 CHECK_CONFIG_PUT_16_RETURN_FAIL(msg->service_name_len, msg->service_name_len,
953 NAN_REQ_ATTR_PUBLISH_SERVICE_NAME_LEN, request, result, "publish:Failed to put msg->service_name_len");
954
955 CHECK_CONFIG_PUT_RETURN_FAIL(msg->service_name_len, msg->service_name, msg->service_name_len,
956 NAN_REQ_ATTR_PUBLISH_SERVICE_NAME, request, result, "publish:Failed to put msg->service_name");
957
958 CHECK_CONFIG_PUT_8_RETURN_FAIL(1, msg->publish_match_indicator,
959 NAN_REQ_ATTR_PUBLISH_MATCH_ALGO, request, result, "publish:Failed to put msg->publish_match_indicator");
960
961 CHECK_CONFIG_PUT_16_RETURN_FAIL(msg->service_specific_info_len, msg->service_specific_info_len,
962 NAN_REQ_ATTR_PUBLISH_SERVICE_INFO_LEN, request, result, "publish:Failed to put msg->service_specific_info_len");
963
964 CHECK_CONFIG_PUT_RETURN_FAIL(msg->service_specific_info_len, msg->service_specific_info, msg->service_specific_info_len,
965 NAN_REQ_ATTR_PUBLISH_SERVICE_INFO, request, result, "publish:Failed to put msg->service_specific_info");
966
967 CHECK_CONFIG_PUT_16_RETURN_FAIL(msg->rx_match_filter_len, msg->rx_match_filter_len,
968 NAN_REQ_ATTR_PUBLISH_RX_MATCH_FILTER_LEN, request, result, "publish:Failed to put msg->rx_match_filter_len");
969
970 CHECK_CONFIG_PUT_RETURN_FAIL(msg->rx_match_filter_len, msg->rx_match_filter, msg->rx_match_filter_len,
971 NAN_REQ_ATTR_PUBLISH_RX_MATCH_FILTER, request, result, "publish:Failed to put msg->rx_match_filter");
972
973 CHECK_CONFIG_PUT_16_RETURN_FAIL(msg->tx_match_filter_len, msg->tx_match_filter_len,
974 NAN_REQ_ATTR_PUBLISH_TX_MATCH_FILTER_LEN, request, result, "publish:Failed to put msg->tx_match_filter_len");
975
976 CHECK_CONFIG_PUT_RETURN_FAIL(msg->tx_match_filter_len, msg->tx_match_filter, msg->tx_match_filter_len,
977 NAN_REQ_ATTR_PUBLISH_TX_MATCH_FILTER, request, result, "publish:Failed to put msg->tx_match_filter");
978
979 CHECK_CONFIG_PUT_8_RETURN_FAIL(1, msg->rssi_threshold_flag,
980 NAN_REQ_ATTR_PUBLISH_RSSI_THRESHOLD_FLAG, request, result, "publish:Failed to put msg->rssi_threshold_flag");
981
982 CHECK_CONFIG_PUT_8_RETURN_FAIL(1, msg->connmap,
983 NAN_REQ_ATTR_PUBLISH_CONN_MAP, request, result, "publish:Failed to put msg->connmap");
984
985 CHECK_CONFIG_PUT_8_RETURN_FAIL(1, msg->recv_indication_cfg,
986 NAN_REQ_ATTR_PUBLISH_RECV_IND_CFG, request, result, "publish:Failed to put msg->recv_indication_cfg");
987
f8c9e3bb
JPS
988 CHECK_CONFIG_PUT_16_RETURN_FAIL(1, msg->sdea_service_specific_info_len,
989 NAN_REQ_ATTR_PUBLISH_SDEA_LEN, request, result, "publish:Failed to put msg->sdea_service_specific_info_len");
990
991 CHECK_CONFIG_PUT_RETURN_FAIL(msg->sdea_service_specific_info_len, msg->sdea_service_specific_info, msg->sdea_service_specific_info_len,
992 NAN_REQ_ATTR_PUBLISH_SDEA, request, result, "publish:Failed to put msg->sdea_service_specific_info");
993
e8aa68c3
JPS
994 result = request.put_u8(NAN_REQ_ATTR_RANGING_AUTO_RESPONSE, msg->ranging_auto_response);
995 CHECK_WIFI_STATUS_RETURN_FAIL(result, "enable:Failed to put ranging_auto_response");
996
997 result = putSdeaParams(&msg->sdea_params, &request);
998 if (result != 0)
999 return result;
1000 result = putRangingCfg(&msg->ranging_cfg, &request);
1001 if (result != 0)
1002 return result;
c2afddcb 1003 result = NanDataCommand::putSecurityInfo(msg->cipher_type, &msg->key_info, msg->scid_len, msg->scid, &request);
e8aa68c3
JPS
1004 if (result != 0)
1005 return result;
1006 result = putRangeResponseCfg(&msg->range_response_cfg, &request);
1007 if (result != 0)
1008 return result;
1009
d3a587e8 1010 request.attr_end(data);
650a9e6a 1011 publishTid = id;
d3a587e8
JPS
1012 result = requestResponse(request);
1013 if (result != WIFI_SUCCESS) {
650a9e6a 1014 publishTid = 0;
d3a587e8
JPS
1015 ALOGE("failed to publish; result = %d", result);
1016 } else {
49e66671 1017 ALOGD("NAN publish...success");
d3a587e8
JPS
1018 }
1019 return result;
1020 }
1021
650a9e6a
JPS
1022 int publishCancel(transaction_id id, NanPublishCancelRequest *msg) {
1023 ALOGD("NAN publishCancel transId:%d, publish_id:%d", id, msg->publish_id);
d3a587e8
JPS
1024 WifiRequest request(familyId(), ifaceId());
1025
1026 int result = request.create(GOOGLE_OUI, SLSI_NL80211_VENDOR_SUBCMD_NAN_PUBLISHCANCEL);
1027 CHECK_WIFI_STATUS_RETURN_FAIL(result, "publishCancel:Failed to create WifiRequest");
1028
1029 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
1030 if (!data) {
1031 ALOGE("publishCancel: request.attr_start fail");
1032 return WIFI_ERROR_OUT_OF_MEMORY;
1033 }
1034
1035 CHECK_CONFIG_PUT_16_RETURN_FAIL(1, msg->publish_id,
1036 NAN_REQ_ATTR_PUBLISH_ID, request, result, "publishCancel:Failed to put msg->publish_id");
1037
1038 request.attr_end(data);
650a9e6a 1039 publishCancelTid = id;
d3a587e8
JPS
1040 result = requestResponse(request);
1041 if (result != WIFI_SUCCESS) {
650a9e6a 1042 publishCancelTid = 0;
d3a587e8
JPS
1043 ALOGE("failed to publishCancel; result = %d", result);
1044 } else {
49e66671 1045 ALOGD("NAN publishCancel...success");
d3a587e8
JPS
1046 }
1047 return result;
1048
1049 }
1050
650a9e6a
JPS
1051 int subscribe(transaction_id id, NanSubscribeRequest *msg) {
1052 ALOGD("NAN subscribe trans_id:%d subscribe_id:%d subscribetype:%d", id, msg->subscribe_id, msg->subscribe_type);
d3a587e8
JPS
1053 WifiRequest request(familyId(), ifaceId());
1054
1055 int result = request.create(GOOGLE_OUI, SLSI_NL80211_VENDOR_SUBCMD_NAN_SUBSCRIBE);
1056 CHECK_WIFI_STATUS_RETURN_FAIL(result, "subscribe:Failed to create WifiRequest");
1057
1058 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
1059 if (!data) {
1060 ALOGE("subscribe: request.attr_start fail");
1061 return WIFI_ERROR_OUT_OF_MEMORY;
1062 }
1063
1064 CHECK_CONFIG_PUT_16_RETURN_FAIL(msg->subscribe_id, msg->subscribe_id,
1065 NAN_REQ_ATTR_SUBSCRIBE_ID, request, result, "subscribe:Failed to put msg->publish_id");
1066
1067 CHECK_CONFIG_PUT_16_RETURN_FAIL(1, msg->ttl,
1068 NAN_REQ_ATTR_SUBSCRIBE_TTL, request, result, "subscribe:Failed to put msg->ttl");
1069
1070 CHECK_CONFIG_PUT_16_RETURN_FAIL(1, msg->period,
1071 NAN_REQ_ATTR_SUBSCRIBE_PERIOD, request, result, "subscribe:Failed to put msg->period");
1072
1073 CHECK_CONFIG_PUT_8_RETURN_FAIL(1, msg->subscribe_type,
1074 NAN_REQ_ATTR_SUBSCRIBE_TYPE, request, result, "subscribe:Failed to put msg->subscribe_type");
1075
1076 CHECK_CONFIG_PUT_8_RETURN_FAIL(1, msg->serviceResponseFilter,
1077 NAN_REQ_ATTR_SUBSCRIBE_RESP_FILTER_TYPE, request, result, "subscribe:Failed to put msg->serviceResponseFilter");
1078
1079 CHECK_CONFIG_PUT_8_RETURN_FAIL(1, msg->serviceResponseInclude,
1080 NAN_REQ_ATTR_SUBSCRIBE_RESP_INCLUDE, request, result, "subscribe:Failed to put msg->serviceResponseInclude");
1081
1082 CHECK_CONFIG_PUT_8_RETURN_FAIL(1, msg->useServiceResponseFilter,
1083 NAN_REQ_ATTR_SUBSCRIBE_USE_RESP_FILTER, request, result, "subscribe:Failed to put msg->useServiceResponseFilter");
1084
1085 CHECK_CONFIG_PUT_8_RETURN_FAIL(1, msg->ssiRequiredForMatchIndication,
1086 NAN_REQ_ATTR_SUBSCRIBE_SSI_REQUIRED, request, result, "subscribe:Failed to put msg->ssiRequiredForMatchIndication");
1087
1088 CHECK_CONFIG_PUT_8_RETURN_FAIL(1, msg->subscribe_match_indicator,
1089 NAN_REQ_ATTR_SUBSCRIBE_MATCH_INDICATOR, request, result, "subscribe:Failed to put msg->subscribe_match_indicator");
1090
1091 CHECK_CONFIG_PUT_8_RETURN_FAIL(1, msg->subscribe_count,
1092 NAN_REQ_ATTR_SUBSCRIBE_COUNT, request, result, "subscribe:Failed to put msg->subscribe_count");
1093
1094 CHECK_CONFIG_PUT_16_RETURN_FAIL(msg->service_name_len, msg->service_name_len,
1095 NAN_REQ_ATTR_SUBSCRIBE_SERVICE_NAME_LEN, request, result, "subscribe:Failed to put msg->service_name_len");
1096
1097 CHECK_CONFIG_PUT_RETURN_FAIL(msg->service_name_len, msg->service_name, msg->service_name_len,
1098 NAN_REQ_ATTR_SUBSCRIBE_SERVICE_NAME, request, result, "subscribe:Failed to put msg->service_name");
1099
1100 CHECK_CONFIG_PUT_16_RETURN_FAIL(msg->service_specific_info_len, msg->service_specific_info_len,
1101 NAN_REQ_ATTR_SUBSCRIBE_SERVICE_INFO_LEN, request, result, "subscribe:Failed to put msg->service_specific_info_len");
1102
1103 CHECK_CONFIG_PUT_RETURN_FAIL(msg->service_specific_info_len, msg->service_specific_info, msg->service_specific_info_len,
1104 NAN_REQ_ATTR_SUBSCRIBE_SERVICE_INFO, request, result, "subscribe:Failed to put msg->service_specific_info");
1105
1106 CHECK_CONFIG_PUT_16_RETURN_FAIL(msg->rx_match_filter_len, msg->rx_match_filter_len,
1107 NAN_REQ_ATTR_SUBSCRIBE_RX_MATCH_FILTER_LEN, request, result, "subscribe:Failed to put msg->rx_match_filter_len");
1108
1109 CHECK_CONFIG_PUT_RETURN_FAIL(msg->rx_match_filter_len, msg->rx_match_filter, msg->rx_match_filter_len,
1110 NAN_REQ_ATTR_SUBSCRIBE_RX_MATCH_FILTER, request, result, "subscribe:Failed to put msg->rx_match_filter");
1111
1112 CHECK_CONFIG_PUT_16_RETURN_FAIL(msg->tx_match_filter_len, msg->tx_match_filter_len,
1113 NAN_REQ_ATTR_SUBSCRIBE_TX_MATCH_FILTER_LEN, request, result, "subscribe:Failed to put msg->tx_match_filter_len");
1114
1115 CHECK_CONFIG_PUT_RETURN_FAIL(msg->tx_match_filter_len, msg->tx_match_filter, msg->tx_match_filter_len,
1116 NAN_REQ_ATTR_SUBSCRIBE_TX_MATCH_FILTER, request, result, "subscribe:Failed to put msg->tx_match_filter");
1117
1118 CHECK_CONFIG_PUT_8_RETURN_FAIL(1, msg->rssi_threshold_flag,
1119 NAN_REQ_ATTR_SUBSCRIBE_RSSI_THRESHOLD_FLAG, request, result, "subscribe:Failed to put msg->rssi_threshold_flag");
1120
1121 CHECK_CONFIG_PUT_8_RETURN_FAIL(1, msg->connmap,
1122 NAN_REQ_ATTR_SUBSCRIBE_CONN_MAP, request, result, "subscribe:Failed to put msg->connmap");
1123
1124 CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->num_intf_addr_present, msg->num_intf_addr_present,
1125 NAN_REQ_ATTR_SUBSCRIBE_NUM_INTF_ADDR_PRESENT, request, result, "subscribe:Failed to put msg->num_intf_addr_present");
1126
1127 CHECK_CONFIG_PUT_RETURN_FAIL(msg->num_intf_addr_present, msg->intf_addr, NAN_MAC_ADDR_LEN * msg->num_intf_addr_present,
1128 NAN_REQ_ATTR_SUBSCRIBE_INTF_ADDR, request, result, "subscribe:Failed to put msg->intf_addr");
1129
1130 CHECK_CONFIG_PUT_8_RETURN_FAIL(1, msg->recv_indication_cfg,
1131 NAN_REQ_ATTR_SUBSCRIBE_RECV_IND_CFG, request, result, "subscribe:Failed to put msg->recv_indication_cfg");
1132
f8c9e3bb
JPS
1133 CHECK_CONFIG_PUT_16_RETURN_FAIL(1, msg->sdea_service_specific_info_len,
1134 NAN_REQ_ATTR_PUBLISH_SDEA_LEN, request, result, "subscribe:Failed to put msg->sdea_service_specific_info_len");
1135
1136 CHECK_CONFIG_PUT_RETURN_FAIL(msg->sdea_service_specific_info_len, msg->sdea_service_specific_info, msg->sdea_service_specific_info_len,
1137 NAN_REQ_ATTR_PUBLISH_SDEA, request, result, "subscribe:Failed to put msg->sdea_service_specific_info");
1138
e8aa68c3
JPS
1139 result = request.put_u8(NAN_REQ_ATTR_RANGING_AUTO_RESPONSE, msg->ranging_auto_response);
1140 CHECK_WIFI_STATUS_RETURN_FAIL(result, "enable:Failed to put ranging_auto_response");
1141
1142 result = putSdeaParams(&msg->sdea_params, &request);
1143 if (result != 0)
1144 return result;
1145 result = putRangingCfg(&msg->ranging_cfg, &request);
1146 if (result != 0)
1147 return result;
c2afddcb 1148 result = NanDataCommand::putSecurityInfo(msg->cipher_type, &msg->key_info, msg->scid_len, msg->scid, &request);
e8aa68c3
JPS
1149 if (result != 0)
1150 return result;
1151 result = putRangeResponseCfg(&msg->range_response_cfg, &request);
1152 if (result != 0)
1153 return result;
f8c9e3bb 1154
d3a587e8 1155 request.attr_end(data);
650a9e6a 1156 subscribeTid = id;
d3a587e8
JPS
1157 result = requestResponse(request);
1158 if (result != WIFI_SUCCESS) {
650a9e6a 1159 subscribeTid = 0;
d3a587e8
JPS
1160 ALOGE("failed to subscribe; result = %d", result);
1161 } else {
49e66671 1162 ALOGD("NAN subscribe...success");
d3a587e8
JPS
1163 }
1164 return result;
1165
1166 }
1167
650a9e6a
JPS
1168 int subscribeCancel(transaction_id id, NanSubscribeCancelRequest *msg) {
1169 ALOGD("NAN subscribeCancel transId:%d subscribeId:%d", id, msg->subscribe_id);
d3a587e8
JPS
1170 WifiRequest request(familyId(), ifaceId());
1171
1172 int result = request.create(GOOGLE_OUI, SLSI_NL80211_VENDOR_SUBCMD_NAN_SUBSCRIBECANCEL);
1173 CHECK_WIFI_STATUS_RETURN_FAIL(result, "subscribeCancel:Failed to create WifiRequest");
1174
1175 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
1176 if (!data) {
1177 ALOGE("subscribeCancel: request.attr_start fail");
1178 return WIFI_ERROR_OUT_OF_MEMORY;
1179 }
1180
1181 CHECK_CONFIG_PUT_16_RETURN_FAIL(1, msg->subscribe_id,
1182 NAN_REQ_ATTR_SUBSCRIBE_ID, request, result, "subscribeCancel:Failed to put msg->subscribe_id");
1183
1184 request.attr_end(data);
650a9e6a 1185 subscribeCancelTid = id;
d3a587e8
JPS
1186 result = requestResponse(request);
1187 if (result != WIFI_SUCCESS) {
650a9e6a 1188 subscribeCancelTid = 0;
d3a587e8
JPS
1189 ALOGE("failed to subscribeCancel; result = %d", result);
1190 } else {
49e66671 1191 ALOGD("NAN subscribeCancel...success");
d3a587e8
JPS
1192 }
1193 return result;
1194 }
1195
650a9e6a
JPS
1196 int followup(transaction_id id, NanTransmitFollowupRequest *msg) {
1197 ALOGD("NAN followup transid:%d pub/subId:%d reqInstId:%d", id, msg->publish_subscribe_id, msg->requestor_instance_id);
d3a587e8
JPS
1198 WifiRequest request(familyId(), ifaceId());
1199
1200 int result = request.create(GOOGLE_OUI, SLSI_NL80211_VENDOR_SUBCMD_NAN_TXFOLLOWUP);
1201 CHECK_WIFI_STATUS_RETURN_FAIL(result, "followup:Failed to create WifiRequest");
1202
1203 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
1204 if (!data) {
1205 ALOGE("followup: request.attr_start fail");
1206 return WIFI_ERROR_OUT_OF_MEMORY;
1207 }
1208
1209 CHECK_CONFIG_PUT_16_RETURN_FAIL(1, msg->publish_subscribe_id,
1210 NAN_REQ_ATTR_FOLLOWUP_ID, request, result, "followup:Failed to put msg->publish_subscribe_id");
1211
1212 CHECK_CONFIG_PUT_32_RETURN_FAIL(1, msg->requestor_instance_id,
1213 NAN_REQ_ATTR_FOLLOWUP_REQUESTOR_ID, request, result, "followup:Failed to put msg->requestor_instance_id");
1214
1215 CHECK_CONFIG_PUT_RETURN_FAIL(1, msg->addr, NAN_MAC_ADDR_LEN,
1216 NAN_REQ_ATTR_FOLLOWUP_ADDR, request, result, "followup:Failed to put msg->addr");
1217
1218 CHECK_CONFIG_PUT_8_RETURN_FAIL(1, msg->priority,
1219 NAN_REQ_ATTR_FOLLOWUP_PRIORITY, request, result, "followup:Failed to put msg->priority");
1220
1221 CHECK_CONFIG_PUT_8_RETURN_FAIL(1, msg->dw_or_faw,
1222 NAN_REQ_ATTR_FOLLOWUP_TX_WINDOW, request, result, "followup:Failed to put msg->dw_or_faw");
1223
1224 CHECK_CONFIG_PUT_16_RETURN_FAIL(msg->service_specific_info_len, msg->service_specific_info_len,
1225 NAN_REQ_ATTR_FOLLOWUP_SERVICE_NAME_LEN, request, result, "followup:Failed to put msg->service_specific_info_len");
1226
1227 CHECK_CONFIG_PUT_RETURN_FAIL(msg->service_specific_info_len, msg->service_specific_info, msg->service_specific_info_len,
1228 NAN_REQ_ATTR_FOLLOWUP_SERVICE_NAME, request, result, "followup:Failed to put msg->service_specific_info");
1229
1230 CHECK_CONFIG_PUT_8_RETURN_FAIL(1, msg->recv_indication_cfg,
1231 NAN_REQ_ATTR_FOLLOWUP_RECV_IND_CFG, request, result, "followup:Failed to put msg->recv_indication_cfg");
1232
f8c9e3bb
JPS
1233 CHECK_CONFIG_PUT_16_RETURN_FAIL(1, msg->sdea_service_specific_info_len,
1234 NAN_REQ_ATTR_PUBLISH_SDEA_LEN, request, result, "publish:Failed to put msg->sdea_service_specific_info_len");
1235
1236 CHECK_CONFIG_PUT_RETURN_FAIL(msg->sdea_service_specific_info_len, msg->sdea_service_specific_info, msg->sdea_service_specific_info_len,
1237 NAN_REQ_ATTR_PUBLISH_SDEA, request, result, "publish:Failed to put msg->sdea_service_specific_info");
1238
d3a587e8 1239 request.attr_end(data);
650a9e6a 1240 followupTid = id;
d3a587e8
JPS
1241 result = requestResponse(request);
1242 if (result != WIFI_SUCCESS) {
650a9e6a 1243 followupTid = 0;
d3a587e8
JPS
1244 ALOGE("failed to followup; result = %d", result);
1245 } else {
49e66671 1246 ALOGD("NAN followup...success");
d3a587e8
JPS
1247 }
1248 return result;
1249
1250 }
1251
650a9e6a
JPS
1252 int getCapabilities(transaction_id id) {
1253 ALOGD("NAN getCapabilities transId:%d", id);
d3a587e8
JPS
1254 WifiRequest request(familyId(), ifaceId());
1255
1256 int result = request.create(GOOGLE_OUI, SLSI_NL80211_VENDOR_SUBCMD_NAN_CAPABILITIES);
1257 CHECK_WIFI_STATUS_RETURN_FAIL(result, "getCapabilities:Failed to create WifiRequest");
1258
650a9e6a 1259 capabilitiesTid = id;
d3a587e8
JPS
1260 result = requestResponse(request);
1261 if (result != WIFI_SUCCESS) {
650a9e6a 1262 capabilitiesTid = 0;
d3a587e8
JPS
1263 ALOGE("failed to getCapabilities; result = %d", result);
1264 } else {
49e66671 1265 ALOGD("NAN getCapabilities...success");
d3a587e8
JPS
1266 }
1267 return result;
1268 }
1269
1270 int handleEvent(WifiEvent &event) {
1271 int ret;
d3a587e8
JPS
1272
1273 if (event.get_cmd() != NL80211_CMD_VENDOR) {
650a9e6a 1274 ALOGD("NAN %s Ignoring event with cmd = %d", __func__, event.get_cmd());
d3a587e8
JPS
1275 return NL_SKIP;
1276 }
1277
1278 int id = event.get_vendor_id();
1279 int subcmd = event.get_vendor_subcmd();
1280
650a9e6a 1281 ALOGI("NAN %s Id = %0x, subcmd = %d", __func__, id, subcmd);
d3a587e8
JPS
1282
1283 switch(subcmd) {
1284 case SLSI_NAN_EVENT_MATCH:
1285 ret = processMatchEvent(event);
1286 break;
1287 case SLSI_NAN_EVENT_MATCH_EXPIRED:
1288 ret = processMatchExpiredEvent(event);
1289 break;
1290 case SLSI_NAN_EVENT_PUBLISH_TERMINATED:
1291 ret = processPublishTerminatedEvent(event);
1292 break;
1293 case SLSI_NAN_EVENT_SUBSCRIBE_TERMINATED:
1294 ret = processSubscribeTerminatedEvent(event);
1295 break;
1296 case SLSI_NAN_EVENT_FOLLOWUP:
1297 ret = processFollowupEvent(event);
1298 break;
1299 case SLSI_NAN_EVENT_DISABLED:
1300 ret = processNanDisabledEvent(event);
1301 break;
1302 case SLSI_NAN_EVENT_DISCOVERY_ENGINE:
1303 ret = processNanDiscoveryEvent(event);
1304 break;
650a9e6a
JPS
1305 case SLSI_NAN_EVENT_TRANSMIT_FOLLOWUP_STATUS:
1306 ret = processNanFollowupStatus(event);
1307 break;
c2afddcb
JPS
1308 default:
1309 return datacmd.handleEvent(event, callbackEventHandler);
d3a587e8
JPS
1310 }
1311
1312 return NL_OK;
1313 }
1314
1315 int handleResponse(WifiEvent &reply) {
d3a587e8 1316 if (reply.get_cmd() != NL80211_CMD_VENDOR) {
650a9e6a 1317 ALOGD("NAN %s Ignoring reply with cmd = %d", __func__, reply.get_cmd());
d3a587e8
JPS
1318 return NL_SKIP;
1319 }
1320
d3a587e8
JPS
1321 NanResponseMsg response;
1322 memset(&response, 0, sizeof(response));
1323
1324 if (processResponse(reply, &response) == NL_SKIP)
1325 return NL_SKIP;
1326
650a9e6a
JPS
1327 transaction_id id = 0;
1328 switch ((int)response.response_type) {
1329 case NAN_RESPONSE_PUBLISH:
1330 id = publishTid;
1331 publishTid = 0;
1332 break;
1333 case NAN_RESPONSE_ENABLED:
1334 id = enableTid;
1335 enableTid = 0;
1336 break;
1337 case NAN_RESPONSE_DISABLED:
1338 id = disableTid;
1339 disableTid = 0;
1340 break;
1341 case NAN_RESPONSE_PUBLISH_CANCEL:
1342 id = publishCancelTid;
1343 publishCancelTid = 0;
1344 break;
1345 case NAN_RESPONSE_SUBSCRIBE_CANCEL:
1346 id = subscribeCancelTid;
1347 subscribeCancelTid = 0;
1348 break;
1349 case NAN_RESPONSE_CONFIG:
1350 id = configTid;
1351 configTid = 0;
1352 break;
1353 case NAN_GET_CAPABILITIES:
1354 id = capabilitiesTid;
1355 capabilitiesTid = 0;
1356 break;
1357 case NAN_RESPONSE_SUBSCRIBE:
1358 id = subscribeTid;
1359 subscribeTid = 0;
1360 break;
1361 case NAN_RESPONSE_TRANSMIT_FOLLOWUP:
1362 id = followupTid;
1363 /* followupTid is required on receiving followup_up transmit status.
1364 * Do not reset followupTid here*/
1365 break;
c2afddcb
JPS
1366 default:
1367 id = datacmd.getResponseTransactionId(&response);
650a9e6a
JPS
1368 }
1369 ALOGD("NAN %s transId:%d status:%d, response:%d", __func__, id, response.status, response.response_type);
d3a587e8 1370 if (callbackEventHandler.NotifyResponse)
650a9e6a 1371 callbackEventHandler.NotifyResponse(id, &response);
d3a587e8
JPS
1372 return NL_OK;
1373 }
c2afddcb
JPS
1374
1375 int dataPathReq(u16 id, void *data, int subcmd) {
1376 int result;
1377 WifiRequest request(familyId(), ifaceId());
1378
1379 ALOGI("NAN DATA-PATH req subcmd:%d", subcmd);
1380
1381 result = datacmd.getDataPathNLMsg(data, subcmd, request);
1382 if (result != WIFI_SUCCESS) {
1383 return result;
1384 }
1385 result = requestResponse(request);
1386 if (result != WIFI_SUCCESS) {
1387 ALOGE("failed NDP req; result = %d", result);
1388 unregisterNanEvents();
1389 } else {
1390 datacmd.requestSuccess(id, data, subcmd);
1391 ALOGD("NAN DATA-PATH req(subcmd:%d)...success", subcmd);
1392 }
1393 return result;
1394 }
d3a587e8
JPS
1395};
1396
1397NanCallbackHandler NanCommand::callbackEventHandler;
1398
1399NanCommand *nan_get_object(transaction_id id,
1400 wifi_interface_handle iface) {
1401 wifi_handle handle = getWifiHandle(iface);
650a9e6a 1402 NanCommand *nanRequest = (NanCommand *)wifi_get_nan_cmd(handle);
d3a587e8
JPS
1403 if (!nanRequest) {
1404 nanRequest = new NanCommand(iface, id);
1405 if (!nanRequest){
1406 ALOGE("Could not alloc NanCommand");
1407 return NULL;
1408 }
1409 }
1410 return nanRequest;
1411}
1412
1413wifi_error nan_enable_request(transaction_id id,
1414 wifi_interface_handle iface,
1415 NanEnableRequest *msg) {
1416 wifi_handle handle = getWifiHandle(iface);
1417 wifi_error ret;
1418
1419 NanCommand *nanRequest = new NanCommand(iface, id);
1420 if (!nanRequest) {
1421 ALOGE("nan_enable_request:: Unable to create NanCommand");
1422 return WIFI_ERROR_OUT_OF_MEMORY;
1423 }
1424
650a9e6a
JPS
1425 wifi_set_nan_cmd(handle, nanRequest);
1426 ret = (wifi_error)nanRequest->enable(id, msg);
d3a587e8 1427 if (ret != WIFI_SUCCESS) {
650a9e6a 1428 wifi_reset_nan_cmd(handle);
d3a587e8
JPS
1429 delete nanRequest;
1430 }
1431 return ret;
1432}
1433
1434/* Disable NAN functionality. */
1435wifi_error nan_disable_request(transaction_id id, wifi_interface_handle iface) {
1436 NanCommand *nanRequest = nan_get_object(id, iface);
1437 wifi_error ret;
1438
1439 if (!nanRequest) {
1440 return WIFI_ERROR_OUT_OF_MEMORY;
1441 }
650a9e6a
JPS
1442 ret = (wifi_error)nanRequest->disable(id);
1443 wifi_reset_nan_cmd(getWifiHandle(iface));
d3a587e8
JPS
1444 delete nanRequest;
1445 return ret;
1446}
1447
1448/* Publish request to advertize a service. */
1449wifi_error nan_publish_request(transaction_id id,
1450 wifi_interface_handle iface,
1451 NanPublishRequest *msg) {
1452 NanCommand *nanRequest = nan_get_object(id, iface);
1453 if (!nanRequest) {
1454 return WIFI_ERROR_OUT_OF_MEMORY;
1455 }
650a9e6a 1456 return (wifi_error)nanRequest->publish(id, msg);
d3a587e8
JPS
1457}
1458
1459/* Cancel previous publish requests. */
1460wifi_error nan_publish_cancel_request(transaction_id id,
1461 wifi_interface_handle iface,
1462 NanPublishCancelRequest *msg) {
1463 NanCommand *nanRequest = nan_get_object(id, iface);
1464 if (!nanRequest) {
1465 return WIFI_ERROR_OUT_OF_MEMORY;
1466 }
650a9e6a 1467 return (wifi_error)nanRequest->publishCancel(id, msg);
d3a587e8
JPS
1468}
1469
1470/* Subscribe request to search for a service. */
1471wifi_error nan_subscribe_request(transaction_id id,
1472 wifi_interface_handle iface,
1473 NanSubscribeRequest *msg) {
1474 NanCommand *nanRequest = nan_get_object(id, iface);
1475 if (!nanRequest) {
1476 return WIFI_ERROR_OUT_OF_MEMORY;
1477 }
650a9e6a 1478 return (wifi_error)nanRequest->subscribe(id, msg);
d3a587e8
JPS
1479}
1480
1481/* Cancel previous subscribe requests. */
1482wifi_error nan_subscribe_cancel_request(transaction_id id,
1483 wifi_interface_handle iface,
1484 NanSubscribeCancelRequest *msg) {
1485 NanCommand *nanRequest = nan_get_object(id, iface);
1486 if (!nanRequest) {
1487 return WIFI_ERROR_OUT_OF_MEMORY;
1488 }
650a9e6a 1489 return (wifi_error)nanRequest->subscribeCancel(id, msg);
d3a587e8
JPS
1490}
1491
1492/* NAN transmit follow up request. */
1493wifi_error nan_transmit_followup_request(transaction_id id,
1494 wifi_interface_handle iface,
1495 NanTransmitFollowupRequest *msg) {
1496 NanCommand *nanRequest = nan_get_object(id, iface);
1497 if (!nanRequest) {
1498 return WIFI_ERROR_OUT_OF_MEMORY;
1499 }
650a9e6a 1500 return (wifi_error)nanRequest->followup(id, msg);
d3a587e8
JPS
1501}
1502
1503/* NAN configuration request. */
1504wifi_error nan_config_request(transaction_id id,
1505 wifi_interface_handle iface,
1506 NanConfigRequest *msg) {
1507 NanCommand *nanRequest = nan_get_object(id, iface);
1508 if (!nanRequest) {
1509 return WIFI_ERROR_OUT_OF_MEMORY;
1510 }
650a9e6a 1511 return (wifi_error)nanRequest->config(id, msg);
d3a587e8
JPS
1512}
1513
1514/* Register NAN callbacks. */
1515wifi_error nan_register_handler(wifi_interface_handle iface,
1516 NanCallbackHandler handlers) {
1517 return (wifi_error)NanCommand::setCallbackHandler(handlers);
1518}
1519
1520/* Get NAN HAL version. */
1521wifi_error nan_get_version(wifi_handle handle,
1522 NanVersion *version) {
1523 return (wifi_error)NanCommand::getVersion(version);
1524}
1525
1526/* Get NAN capabilities. */
1527wifi_error nan_get_capabilities(transaction_id id,
1528 wifi_interface_handle iface) {
1529 NanCommand *nanRequest = nan_get_object(id, iface);
1530 if (!nanRequest) {
1531 return WIFI_ERROR_OUT_OF_MEMORY;
1532 }
650a9e6a 1533 return (wifi_error)nanRequest->getCapabilities(id);
d3a587e8
JPS
1534}
1535
c2afddcb
JPS
1536wifi_error nan_data_interface_create(transaction_id id,
1537 wifi_interface_handle iface,
1538 char* iface_name) {
1539 NanCommand *nanRequest = nan_get_object(id, iface);
1540 if (!nanRequest) {
1541 return WIFI_ERROR_OUT_OF_MEMORY;
1542 }
1543 return (wifi_error)nanRequest->dataPathReq(id, iface,
1544 SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_INTERFACE_CREATE);
1545}
1546
1547wifi_error nan_data_interface_delete(transaction_id id,
1548 wifi_interface_handle iface,
1549 char* iface_name) {
1550 NanCommand *nanRequest = nan_get_object(id, iface);
1551 if (!nanRequest) {
1552 return WIFI_ERROR_OUT_OF_MEMORY;
1553 }
1554 return (wifi_error)nanRequest->dataPathReq(id, iface,
1555 SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_INTERFACE_DELETE);
1556
1557}
1558
1559wifi_error nan_data_request_initiator(transaction_id id,
1560 wifi_interface_handle iface,
1561 NanDataPathInitiatorRequest* msg) {
1562 NanCommand *nanRequest = nan_get_object(id, iface);
1563 if (!nanRequest) {
1564 return WIFI_ERROR_OUT_OF_MEMORY;
1565 }
1566 return (wifi_error)nanRequest->dataPathReq(id, iface,
1567 SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_REQUEST_INITIATOR);
1568
1569}
1570
1571wifi_error nan_data_indication_response(transaction_id id,
1572 wifi_interface_handle iface,
1573 NanDataPathIndicationResponse* msg) {
1574 NanCommand *nanRequest = nan_get_object(id, iface);
1575 if (!nanRequest) {
1576 return WIFI_ERROR_OUT_OF_MEMORY;
1577 }
1578 return (wifi_error)nanRequest->dataPathReq(id, iface,
1579 SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_INDICATION_RESPONSE);
1580
1581}
1582
1583wifi_error nan_data_end(transaction_id id,
1584 wifi_interface_handle iface,
1585 NanDataPathEndRequest* msg) {
1586 NanCommand *nanRequest = nan_get_object(id, iface);
1587 if (!nanRequest) {
1588 return WIFI_ERROR_OUT_OF_MEMORY;
1589 }
1590 return (wifi_error)nanRequest->dataPathReq(id, iface,
1591 SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_END);
1592
1593}
1594