[APR-2053]wlbt: Prevent issue
[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
305int NanDataCommand::getDataPathNLMsg(void *data, int subcmd, WifiRequest &request) {
306 switch (subcmd) {
307 case SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_INTERFACE_CREATE:
308 case SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_INTERFACE_DELETE:
309 return dataInterfaceCreateDelete((char *)data, subcmd, request);
310 case SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_REQUEST_INITIATOR:
311 return dataRequestInitiate((NanDataPathInitiatorRequest *)data, request);
312 case SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_INDICATION_RESPONSE:
313 return dataIndicationResponse((NanDataPathIndicationResponse *)data, request);
314 case SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_END:
315 return dataEnd((NanDataPathEndRequest *)data, request);
316 default:
317 ALOGE("unknown subcmd :%d", subcmd);
318 }
319 return WIFI_ERROR_UNKNOWN;
320}
321
322void NanDataCommand::requestSuccess(u16 id, void *data, int subcmd) {
323 switch (subcmd) {
324 case SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_INTERFACE_CREATE:
325 transaction_id[idx_iface_create] = id;
326 dataInterfaceCreated((char *)data);
327 break;
328 case SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_INTERFACE_DELETE:
329 transaction_id[idx_iface_delete] = id;
330 dataInterfaceDeleted((char *)data);
331 break;
332 case SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_REQUEST_INITIATOR:
333 transaction_id[idx_ndp_initiator] = id;
334 dataRequestInitiateSuccess((NanDataPathInitiatorRequest *)data);
335 break;
336 case SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_INDICATION_RESPONSE:
337 transaction_id[idx_ndp_responder] = id;
338 dataIndicationResponseSuccess((NanDataPathIndicationResponse *)data);
339 break;
340 case SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_END:
341 transaction_id[idx_ndp_end] = id;
342 dataEndSuccess((NanDataPathEndRequest *)data);
343 break;
344 }
345}
346
347int NanDataCommand::handleEvent(WifiEvent &event, NanCallbackHandler &callbackEventHandler) {
348 int subcmd = event.get_vendor_subcmd();
349 switch (subcmd) {
350 case SLSI_NAN_EVENT_NDP_REQ:
351 return processNdpReqEvent(event, callbackEventHandler);
352 case SLSI_NAN_EVENT_NDP_CFM:
353 return processNdpCfmEvent(event, callbackEventHandler);
354 case SLSI_NAN_EVENT_NDP_END:
355 return processNdpEndEvent(event, callbackEventHandler);
356 default:
357 return NL_OK;
358 }
359}
360
361int NanDataCommand::getResponseTransactionId(NanResponseMsg *res) {
362 u16 id;
363 switch(res->response_type) {
364 case NAN_DP_INTERFACE_CREATE:
365 id = transaction_id[idx_iface_create];
366 transaction_id[idx_iface_create] = 0;
367 break;
368 case NAN_DP_INTERFACE_DELETE:
369 id = transaction_id[idx_iface_delete];
370 transaction_id[idx_iface_delete] = 0;
371 break;
372 case NAN_DP_INITIATOR_RESPONSE:
373 id = transaction_id[idx_ndp_initiator];
374 transaction_id[idx_ndp_initiator] = 0;
375 break;
376 case NAN_DP_RESPONDER_RESPONSE:
377 id = transaction_id[idx_ndp_responder];
378 transaction_id[idx_ndp_responder] = 0;
379 break;
380 case NAN_DP_END:
381 id = transaction_id[idx_ndp_end];
382 transaction_id[idx_ndp_end] = 0;
383 break;
384 default:
385 id = 0;
386 }
387 return id;
388}
389
390void NanDataCommand::setMaxNdpSessions(int max_ndp) {
391 m_max_ndp_sessions = max_ndp > SLSI_NAN_MAX_NDP ? SLSI_NAN_MAX_NDP : max_ndp;
392}
393
394int NanDataCommand::putSecurityInfo(u32 cipher, NanSecurityKeyInfo *key_info, u32 scid_len, u8 *scid, WifiRequest *request)
395{
396 int result;
397
398 result = request->put_u32(NAN_REQ_ATTR_CIPHER_TYPE, cipher);
399 CHECK_WIFI_STATUS_RETURN_FAIL(result, "enable:Failed to put cipher_type");
400
401 result = request->put_u32(NAN_REQ_ATTR_SECURITY_KEY_TYPE, key_info->key_type);
402 CHECK_WIFI_STATUS_RETURN_FAIL(result, "enable:Failed to put cipher_type");
403
404 if (key_info->key_type == NAN_SECURITY_KEY_INPUT_PMK) {
405 result = request->put_u32(NAN_REQ_ATTR_SECURITY_PMK_LEN, key_info->body.pmk_info.pmk_len);
406 CHECK_WIFI_STATUS_RETURN_FAIL(result, "enable:Failed to put key_info->body.pmk_info.pmk_len");
407 result = request->put(NAN_REQ_ATTR_SECURITY_PMK, key_info->body.pmk_info.pmk, key_info->body.pmk_info.pmk_len);
408 CHECK_WIFI_STATUS_RETURN_FAIL(result, "enable:Failed to put key_info->body.pmk_info.pmk");
409 } else {
410 result = request->put_u32(NAN_REQ_ATTR_SECURITY_PASSPHRASE_LEN, key_info->body.passphrase_info.passphrase_len);
411 CHECK_WIFI_STATUS_RETURN_FAIL(result, "enable:Failed to put key_info->body.passphrase_info.passphrase_len");
412 result = request->put(NAN_REQ_ATTR_SECURITY_PASSPHRASE, key_info->body.passphrase_info.passphrase,
413 key_info->body.passphrase_info.passphrase_len);
414 CHECK_WIFI_STATUS_RETURN_FAIL(result, "enable:Failed to put key_info->body.passphrase_info.passphrase");
415 }
416
417 result = request->put_u32(NAN_REQ_ATTR_SCID_LEN, scid_len);
418 CHECK_WIFI_STATUS_RETURN_FAIL(result, "enable:Failed to put scid_len");
419 if (scid_len) {
420 result = request->put(NAN_REQ_ATTR_SCID, scid, scid_len);
421 CHECK_WIFI_STATUS_RETURN_FAIL(result, "enable:Failed to put scid");
422 }
423 return result;
424}