[APR-2053]wlbt: NAN R2 integration fxes
[GitHub/MotorolaMobilityLLC/hardware-samsung_slsi-scsc_wifibt-wifi_hal.git] / wifi_nan_data_path.cpp
CommitLineData
c2afddcb
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"
26#include "nan_data.h"
27#include "nan_common.h"
28
29nlattr *NanDataCommand::newNlVendorMsg(int subcmd, WifiRequest &request) {
30 int result = request.create(GOOGLE_OUI, subcmd);
31 if (result != WIFI_SUCCESS) {
32 ALOGE("newNlVendorMsg:Failed to create WifiRequest (%d)", result);
33 return NULL;
34 }
35
36 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
37 if (!data) {
38 ALOGE("newNlVendorMsg: request.attr_start fail");
39 return NULL;
40 }
41 return data;
42}
43
44int NanDataCommand::dataInterfaceCreateDelete(char *ifaceName, int subcmd, WifiRequest &request) {
45 int result;
46 nlattr *data = newNlVendorMsg(subcmd, request);
47 if (!data)
48 return WIFI_ERROR_OUT_OF_MEMORY;
49
50 result = request.put_u8(NAN_REQ_ATTR_DATA_INTERFACE_NAME_LEN, strlen(ifaceName));
51 CHECK_WIFI_STATUS_RETURN_FAIL(result, "Failed to put ifaceName_len");
52 result = request.put(NAN_REQ_ATTR_DATA_INTERFACE_NAME, ifaceName, strlen(ifaceName));
53 CHECK_WIFI_STATUS_RETURN_FAIL(result, "Failed to put ifaceName");
54 request.attr_end(data);
55 return WIFI_SUCCESS;
56}
57
58int NanDataCommand::dataRequestInitiate(NanDataPathInitiatorRequest* msg, WifiRequest &request) {
59 int result;
60 nlattr *data = newNlVendorMsg(SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_REQUEST_INITIATOR, request);
61 if (!data)
62 return WIFI_ERROR_OUT_OF_MEMORY;
63 result = request.put_u32(NAN_REQ_ATTR_REQ_INSTANCE_ID, msg->requestor_instance_id);
64 CHECK_WIFI_STATUS_RETURN_FAIL(result, "Failed to put req_instance_id");
65 result = request.put_u8(NAN_REQ_ATTR_CHAN_REQ_TYPE, msg->channel_request_type);
66 CHECK_WIFI_STATUS_RETURN_FAIL(result, "Failed to put channel_request_type");
67 result = request.put_u32(NAN_REQ_ATTR_CHAN, msg->channel);
68 CHECK_WIFI_STATUS_RETURN_FAIL(result, "Failed to put channel");
69 result = request.put(NAN_REQ_ATTR_MAC_ADDR_VAL, msg->peer_disc_mac_addr, NAN_MAC_ADDR_LEN);
70 CHECK_WIFI_STATUS_RETURN_FAIL(result, "Failed to put peer_disc_mac_addr");
71 result = request.put_u8(NAN_REQ_ATTR_DATA_INTERFACE_NAME_LEN, IFNAMSIZ+1);
72 CHECK_WIFI_STATUS_RETURN_FAIL(result, "Failed to put ifaceName_len");
73 result = request.put(NAN_REQ_ATTR_DATA_INTERFACE_NAME, msg->ndp_iface, IFNAMSIZ+1);
74 CHECK_WIFI_STATUS_RETURN_FAIL(result, "Failed to put ndp_iface");
75 result = request.put_u8(NAN_REQ_ATTR_SDEA_PARAM_SECURITY_CFG, msg->ndp_cfg.security_cfg);
76 CHECK_WIFI_STATUS_RETURN_FAIL(result, "Failed to put security_cfg");
77 result = request.put_u8(NAN_REQ_ATTR_SDEA_PARAM_QOS_CFG, msg->ndp_cfg.qos_cfg);
78 CHECK_WIFI_STATUS_RETURN_FAIL(result, "Failed to put qos_cfg");
79 if(msg->app_info.ndp_app_info_len){
80 result = request.put_u16(NAN_REQ_ATTR_APP_INFO_LEN, msg->app_info.ndp_app_info_len);
81 CHECK_WIFI_STATUS_RETURN_FAIL(result, "Failed to put ndp_app_info_len");
82 result = request.put(NAN_REQ_ATTR_APP_INFO, msg->app_info.ndp_app_info, msg->app_info.ndp_app_info_len);
83 CHECK_WIFI_STATUS_RETURN_FAIL(result, "Failed to put ndp_app_info");
84 }
85 if (msg->service_name_len) {
86 result = request.put_u32(NAN_REQ_ATTR_SERVICE_NAME_LEN, msg->service_name_len);
87 CHECK_WIFI_STATUS_RETURN_FAIL(result, "Failed to put service_name_len");
88 result = request.put(NAN_REQ_ATTR_SERVICE_NAME, msg->service_name, msg->service_name_len);
89 CHECK_WIFI_STATUS_RETURN_FAIL(result, "Failed to put req_instance_id");
90 }
91 result = putSecurityInfo(msg->cipher_type, &msg->key_info, 0, NULL, &request);
92 request.attr_end(data);
93 return result;
94}
95
96int NanDataCommand::dataIndicationResponse(NanDataPathIndicationResponse* msg, WifiRequest &request) {
97 int result;
98 nlattr *data = newNlVendorMsg(SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_INDICATION_RESPONSE, request);
99 if (!data)
100 return WIFI_ERROR_OUT_OF_MEMORY;
101 result = request.put_u32(NAN_REQ_ATTR_NDP_INSTANCE_ID, msg->ndp_instance_id);
102 CHECK_WIFI_STATUS_RETURN_FAIL(result, "Failed to put ndp_instance_id");
103 result = request.put_u8(NAN_REQ_ATTR_DATA_INTERFACE_NAME_LEN, IFNAMSIZ+1);
104 CHECK_WIFI_STATUS_RETURN_FAIL(result, "Failed to put ifaceName_len");
105 result = request.put(NAN_REQ_ATTR_DATA_INTERFACE_NAME, msg->ndp_iface, IFNAMSIZ+1);
106 CHECK_WIFI_STATUS_RETURN_FAIL(result, "Failed to put ndp_iface");
107 result = request.put_u8(NAN_REQ_ATTR_SDEA_PARAM_SECURITY_CFG, msg->ndp_cfg.security_cfg);
108 CHECK_WIFI_STATUS_RETURN_FAIL(result, "Failed to put security_cfg");
109 result = request.put_u8(NAN_REQ_ATTR_SDEA_PARAM_QOS_CFG, msg->ndp_cfg.qos_cfg);
110 CHECK_WIFI_STATUS_RETURN_FAIL(result, "Failed to put qos_cfg");
111 if(msg->app_info.ndp_app_info_len){
112 result = request.put_u16(NAN_REQ_ATTR_APP_INFO_LEN, msg->app_info.ndp_app_info_len);
113 CHECK_WIFI_STATUS_RETURN_FAIL(result, "Failed to put ndp_app_info_len");
114 result = request.put(NAN_REQ_ATTR_APP_INFO, msg->app_info.ndp_app_info, msg->app_info.ndp_app_info_len);
115 CHECK_WIFI_STATUS_RETURN_FAIL(result, "Failed to put ndp_app_info");
116 }
117 result = request.put_u8(NAN_REQ_ATTR_NDP_RESPONSE_CODE, msg->rsp_code);
118 CHECK_WIFI_STATUS_RETURN_FAIL(result, "Failed to put rsp_code");
119 if (msg->service_name_len) {
120 result = request.put_u32(NAN_REQ_ATTR_SERVICE_NAME_LEN, msg->service_name_len);
121 CHECK_WIFI_STATUS_RETURN_FAIL(result, "Failed to put service_name_len");
122 result = request.put(NAN_REQ_ATTR_SERVICE_NAME, msg->service_name, msg->service_name_len);
123 CHECK_WIFI_STATUS_RETURN_FAIL(result, "Failed to put req_instance_id");
124 }
125 result = putSecurityInfo(msg->cipher_type, &msg->key_info, 0, NULL, &request);
126 request.attr_end(data);
127 return result;
128}
129
130int NanDataCommand::dataEnd(NanDataPathEndRequest* msg, WifiRequest &request) {
131 int result, i;
132 nlattr *data = newNlVendorMsg(SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_END, request);
133 if (!data)
134 return WIFI_ERROR_UNKNOWN;
135
136 for(i=0; i<SLSI_NAN_MAX_NDP; i++) {
137 result = request.put_u32(NAN_REQ_ATTR_NDP_INSTANCE_ID, msg->ndp_instance_id[i]);
138 CHECK_WIFI_STATUS_RETURN_FAIL(result, "Failed to put ndp_instance_id");
139 }
140 request.attr_end(data);
141 return result;
142}
143
144void NanDataCommand::dataInterfaceCreated(char *ifaceName) {
145 int i;
146 for(i=0; i<SLSI_NAN_MAX_NDP; i++)
147 if (m_ifaceName[i][0] == 0) {
148 strncpy(ifaceName, m_ifaceName[i], IFNAMSIZ);
149 m_data_iface_count++;
150 return;
151 }
152}
153
154void NanDataCommand::dataInterfaceDeleted(char *ifaceName) {
155 int i;
156 for(i=0; i<SLSI_NAN_MAX_NDP; i++)
157 if (strncmp(m_ifaceName[i], ifaceName, IFNAMSIZ)== 0) {
158 memset(m_ifaceName[i], 0, IFNAMSIZ);
159 m_data_iface_count--;
160 return;
161 }
162}
163
164void NanDataCommand::dataRequestInitiateSuccess(NanDataPathInitiatorRequest *msg) {
165 int i;
166 for(i=0; i<SLSI_NAN_MAX_NDP; i++)
167 if(m_ndp_instance_id[i] == 0) {
168 m_ndp_instance_id[i] = msg->requestor_instance_id;
169 m_ndp_count++;
170 return;
171 }
172}
173
174void NanDataCommand::dataIndicationResponseSuccess(NanDataPathIndicationResponse *msg) {
175 int i;
176 for(i=0; i<SLSI_NAN_MAX_NDP; i++)
177 if(m_ndp_instance_id[i] == 0) {
178 m_ndp_instance_id[i] = msg->ndp_instance_id;
179 m_ndp_count++;
180 return;
181 }
182}
183
184void NanDataCommand::dataEndSuccess(NanDataPathEndRequest *msg) {
185 int i, j;
186 for(i=0; i<msg->num_ndp_instances; i++)
187 for(j=0; j<SLSI_NAN_MAX_NDP; j++)
188 if(m_ndp_instance_id[j] == msg->ndp_instance_id[i]) {
189 m_ndp_instance_id[j] = 0;
190 m_ndp_count--;
191 }
192}
193
194void NanDataCommand::processNdpChannelInfo(nlattr *nl_data, NanChannelInfo &channel_info) {
195 for(nl_iterator nl_itr(nl_data); nl_itr.has_next(); nl_itr.next()) {
196 switch(nl_itr.get_type()) {
197 case NAN_EVT_ATTR_CHANNEL:
198 channel_info.channel = nl_itr.get_u32();
199 break;
200 case NAN_EVT_ATTR_CHANNEL_BW:
201 channel_info.bandwidth = nl_itr.get_u32();
202 break;
203 case NAN_EVT_ATTR_CHANNEL_NSS:
204 channel_info.nss = nl_itr.get_u32();
205 break;
206 }
207 }
208}
209int NanDataCommand::processNdpReqEvent(WifiEvent &event, NanCallbackHandler &callbackEventHandler) {
210 NanDataPathRequestInd ind;
211 memset(&ind,0,sizeof(NanDataPathRequestInd));
212 nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
213
214 for(nl_iterator nl_itr(vendor_data); nl_itr.has_next(); nl_itr.next()) {
215 switch(nl_itr.get_type()) {
216 case NAN_EVT_ATTR_SERVICE_INSTANCE_ID:
217 ind.service_instance_id = nl_itr.get_u16();
218 break;
219 case NAN_EVT_ATTR_MATCH_ADDR:
220 memcpy(ind.peer_disc_mac_addr, nl_itr.get_data(), ETHER_ADDR_LEN);
221 break;
222 case NAN_EVT_ATTR_NDP_INSTANCE_ID:
223 ind.ndp_instance_id = nl_itr.get_u32();
224 break;
225 case NAN_EVT_ATTR_SDEA_PARAM_SECURITY_CONFIG:
226 ind.ndp_cfg.security_cfg = (NanDataPathSecurityCfgStatus)nl_itr.get_u32();
227 break;
228 case NAN_EVT_ATTR_SDEA_PARAM_QOS_CFG:
229 ind.ndp_cfg.qos_cfg = (NanDataPathQosCfg)nl_itr.get_u32();
230 break;
231 case NAN_EVT_ATTR_APP_INFO_LEN:
232 ind.app_info.ndp_app_info_len = nl_itr.get_u16();
233 break;
234 case NAN_EVT_ATTR_APP_INFO:
235 memcpy(ind.app_info.ndp_app_info, nl_itr.get_data(), ind.app_info.ndp_app_info_len);
236 break;
237 }
238 }
239
240 if(callbackEventHandler.EventDataRequest)
241 callbackEventHandler.EventDataRequest(&ind);
242 return NL_OK;
243}
244
245int NanDataCommand::processNdpCfmEvent(WifiEvent &event, NanCallbackHandler &callbackEventHandler) {
246 NanDataPathConfirmInd ind;
247 memset(&ind,0,sizeof(NanDataPathConfirmInd));
248 nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
249
250 for(nl_iterator nl_itr(vendor_data); nl_itr.has_next(); nl_itr.next()) {
251 switch(nl_itr.get_type()) {
252 case NAN_EVT_ATTR_NDP_INSTANCE_ID:
253 ind.ndp_instance_id = nl_itr.get_u32();
254 break;
255 case NAN_EVT_ATTR_MATCH_ADDR:
256 memcpy(ind.peer_ndi_mac_addr, nl_itr.get_data(), ETHER_ADDR_LEN);
257 break;
258 case NAN_EVT_ATTR_APP_INFO_LEN:
259 ind.app_info.ndp_app_info_len = nl_itr.get_u16();
260 break;
261 case NAN_EVT_ATTR_APP_INFO:
262 memcpy(ind.app_info.ndp_app_info, nl_itr.get_data(), ind.app_info.ndp_app_info_len);
263 break;
264 case NAN_EVT_ATTR_NDP_RSP_CODE:
265 ind.rsp_code = (NanDataPathResponseCode)nl_itr.get_u32();
266 break;
267 case NAN_EVT_ATTR_STATUS_CODE:
268 ind.reason_code = (NanStatusType)nl_itr.get_u32();
269 break;
270 case NAN_EVT_ATTR_CHANNEL_INFO:
271 if (ind.num_channels < NAN_MAX_CHANNEL_INFO_SUPPORTED)
272 processNdpChannelInfo(nl_itr.get(), ind.channel_info[ind.num_channels++]);
273 break;
274 }
275 }
276 if(callbackEventHandler.EventDataConfirm)
277 callbackEventHandler.EventDataConfirm(&ind);
278 return NL_OK;
279}
280
281int NanDataCommand::processNdpEndEvent(WifiEvent &event, NanCallbackHandler &callbackEventHandler) {
282 NanDataPathEndInd ind;
283 memset(&ind,0,sizeof(NanDataPathEndInd));
284 nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
285
286 for(nl_iterator nl_itr(vendor_data); nl_itr.has_next(); nl_itr.next()) {
287 if (nl_itr.get_type() == NAN_EVT_ATTR_NDP_INSTANCE_ID) {
288 ind.ndp_instance_id[ind.num_ndp_instances++] = nl_itr.get_u32();
289 }
290 }
291 if(callbackEventHandler.EventDataEnd)
292 callbackEventHandler.EventDataEnd(&ind);
293 return NL_OK;
294}
295
296NanDataCommand::NanDataCommand() {
297 memset(m_ndp_instance_id, 0, sizeof(m_ndp_instance_id));
298 memset(m_ifaceName, 0, sizeof(m_ifaceName));
299 m_ndp_count = 0;
300 m_data_iface_count = 0;
a69d0e87
JPS
301 m_max_ndp_sessions = 0;
302 memset(transaction_id, 0, sizeof(transaction_id));
c2afddcb
JPS
303}
304
082f0000 305int NanDataCommand::getDataPathNLMsg(u16 id, void *data, int subcmd, WifiRequest &request) {
c2afddcb
JPS
306 switch (subcmd) {
307 case SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_INTERFACE_CREATE:
082f0000
JPS
308 transaction_id[idx_iface_create] = id;
309 return dataInterfaceCreateDelete((char *)data, subcmd, request);
c2afddcb 310 case SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_INTERFACE_DELETE:
082f0000 311 transaction_id[idx_iface_delete] = id;
c2afddcb
JPS
312 return dataInterfaceCreateDelete((char *)data, subcmd, request);
313 case SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_REQUEST_INITIATOR:
082f0000 314 transaction_id[idx_ndp_initiator] = id;
c2afddcb
JPS
315 return dataRequestInitiate((NanDataPathInitiatorRequest *)data, request);
316 case SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_INDICATION_RESPONSE:
082f0000 317 transaction_id[idx_ndp_responder] = id;
c2afddcb
JPS
318 return dataIndicationResponse((NanDataPathIndicationResponse *)data, request);
319 case SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_END:
082f0000 320 transaction_id[idx_ndp_end] = id;
c2afddcb
JPS
321 return dataEnd((NanDataPathEndRequest *)data, request);
322 default:
323 ALOGE("unknown subcmd :%d", subcmd);
324 }
325 return WIFI_ERROR_UNKNOWN;
326}
327
328void NanDataCommand::requestSuccess(u16 id, void *data, int subcmd) {
329 switch (subcmd) {
330 case SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_INTERFACE_CREATE:
c2afddcb
JPS
331 dataInterfaceCreated((char *)data);
332 break;
333 case SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_INTERFACE_DELETE:
c2afddcb
JPS
334 dataInterfaceDeleted((char *)data);
335 break;
336 case SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_REQUEST_INITIATOR:
c2afddcb
JPS
337 dataRequestInitiateSuccess((NanDataPathInitiatorRequest *)data);
338 break;
339 case SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_INDICATION_RESPONSE:
c2afddcb
JPS
340 dataIndicationResponseSuccess((NanDataPathIndicationResponse *)data);
341 break;
342 case SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_END:
c2afddcb
JPS
343 dataEndSuccess((NanDataPathEndRequest *)data);
344 break;
345 }
346}
347
348int NanDataCommand::handleEvent(WifiEvent &event, NanCallbackHandler &callbackEventHandler) {
349 int subcmd = event.get_vendor_subcmd();
350 switch (subcmd) {
351 case SLSI_NAN_EVENT_NDP_REQ:
352 return processNdpReqEvent(event, callbackEventHandler);
353 case SLSI_NAN_EVENT_NDP_CFM:
354 return processNdpCfmEvent(event, callbackEventHandler);
355 case SLSI_NAN_EVENT_NDP_END:
356 return processNdpEndEvent(event, callbackEventHandler);
357 default:
358 return NL_OK;
359 }
360}
361
362int NanDataCommand::getResponseTransactionId(NanResponseMsg *res) {
363 u16 id;
364 switch(res->response_type) {
365 case NAN_DP_INTERFACE_CREATE:
366 id = transaction_id[idx_iface_create];
367 transaction_id[idx_iface_create] = 0;
368 break;
369 case NAN_DP_INTERFACE_DELETE:
370 id = transaction_id[idx_iface_delete];
371 transaction_id[idx_iface_delete] = 0;
372 break;
373 case NAN_DP_INITIATOR_RESPONSE:
374 id = transaction_id[idx_ndp_initiator];
375 transaction_id[idx_ndp_initiator] = 0;
376 break;
377 case NAN_DP_RESPONDER_RESPONSE:
378 id = transaction_id[idx_ndp_responder];
379 transaction_id[idx_ndp_responder] = 0;
380 break;
381 case NAN_DP_END:
382 id = transaction_id[idx_ndp_end];
383 transaction_id[idx_ndp_end] = 0;
384 break;
385 default:
386 id = 0;
387 }
388 return id;
389}
390
391void NanDataCommand::setMaxNdpSessions(int max_ndp) {
392 m_max_ndp_sessions = max_ndp > SLSI_NAN_MAX_NDP ? SLSI_NAN_MAX_NDP : max_ndp;
393}
394
395int NanDataCommand::putSecurityInfo(u32 cipher, NanSecurityKeyInfo *key_info, u32 scid_len, u8 *scid, WifiRequest *request)
396{
397 int result;
398
399 result = request->put_u32(NAN_REQ_ATTR_CIPHER_TYPE, cipher);
400 CHECK_WIFI_STATUS_RETURN_FAIL(result, "enable:Failed to put cipher_type");
401
402 result = request->put_u32(NAN_REQ_ATTR_SECURITY_KEY_TYPE, key_info->key_type);
403 CHECK_WIFI_STATUS_RETURN_FAIL(result, "enable:Failed to put cipher_type");
404
405 if (key_info->key_type == NAN_SECURITY_KEY_INPUT_PMK) {
406 result = request->put_u32(NAN_REQ_ATTR_SECURITY_PMK_LEN, key_info->body.pmk_info.pmk_len);
407 CHECK_WIFI_STATUS_RETURN_FAIL(result, "enable:Failed to put key_info->body.pmk_info.pmk_len");
408 result = request->put(NAN_REQ_ATTR_SECURITY_PMK, key_info->body.pmk_info.pmk, key_info->body.pmk_info.pmk_len);
409 CHECK_WIFI_STATUS_RETURN_FAIL(result, "enable:Failed to put key_info->body.pmk_info.pmk");
410 } else {
411 result = request->put_u32(NAN_REQ_ATTR_SECURITY_PASSPHRASE_LEN, key_info->body.passphrase_info.passphrase_len);
412 CHECK_WIFI_STATUS_RETURN_FAIL(result, "enable:Failed to put key_info->body.passphrase_info.passphrase_len");
413 result = request->put(NAN_REQ_ATTR_SECURITY_PASSPHRASE, key_info->body.passphrase_info.passphrase,
414 key_info->body.passphrase_info.passphrase_len);
415 CHECK_WIFI_STATUS_RETURN_FAIL(result, "enable:Failed to put key_info->body.passphrase_info.passphrase");
416 }
417
418 result = request->put_u32(NAN_REQ_ATTR_SCID_LEN, scid_len);
419 CHECK_WIFI_STATUS_RETURN_FAIL(result, "enable:Failed to put scid_len");
420 if (scid_len) {
421 result = request->put(NAN_REQ_ATTR_SCID, scid, scid_len);
422 CHECK_WIFI_STATUS_RETURN_FAIL(result, "enable:Failed to put scid");
423 }
424 return result;
425}