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>
21 #include <utils/Log.h>
25 #include "cpp_bindings.h"
27 #include "nan_common.h"
29 nlattr
*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
);
36 nlattr
*data
= request
.attr_start(NL80211_ATTR_VENDOR_DATA
);
38 ALOGE("newNlVendorMsg: request.attr_start fail");
44 int NanDataCommand::dataInterfaceCreateDelete(u16 id
, char *ifaceName
, int subcmd
, WifiRequest
&request
) {
46 nlattr
*data
= newNlVendorMsg(subcmd
, request
);
48 return WIFI_ERROR_OUT_OF_MEMORY
;
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 CHECK_CONFIG_PUT_16_RETURN_FAIL(1, id
, NAN_REQ_ATTR_HAL_TRANSACTION_ID
, request
, result
, "dataInterfacecreateDelete:Failed to put transaction id");
56 request
.attr_end(data
);
60 int NanDataCommand::dataRequestInitiate(u16 id
, NanDataPathInitiatorRequest
* msg
, WifiRequest
&request
) {
62 nlattr
*data
= newNlVendorMsg(SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_REQUEST_INITIATOR
, request
);
64 return WIFI_ERROR_OUT_OF_MEMORY
;
65 result
= request
.put_u32(NAN_REQ_ATTR_REQ_INSTANCE_ID
, msg
->requestor_instance_id
);
66 CHECK_WIFI_STATUS_RETURN_FAIL(result
, "Failed to put req_instance_id");
67 result
= request
.put_u8(NAN_REQ_ATTR_CHAN_REQ_TYPE
, msg
->channel_request_type
);
68 CHECK_WIFI_STATUS_RETURN_FAIL(result
, "Failed to put channel_request_type");
69 result
= request
.put_u32(NAN_REQ_ATTR_CHAN
, msg
->channel
);
70 CHECK_WIFI_STATUS_RETURN_FAIL(result
, "Failed to put channel");
71 result
= request
.put(NAN_REQ_ATTR_MAC_ADDR_VAL
, msg
->peer_disc_mac_addr
, NAN_MAC_ADDR_LEN
);
72 CHECK_WIFI_STATUS_RETURN_FAIL(result
, "Failed to put peer_disc_mac_addr");
73 result
= request
.put_u8(NAN_REQ_ATTR_DATA_INTERFACE_NAME_LEN
, IFNAMSIZ
+1);
74 CHECK_WIFI_STATUS_RETURN_FAIL(result
, "Failed to put ifaceName_len");
75 result
= request
.put(NAN_REQ_ATTR_DATA_INTERFACE_NAME
, msg
->ndp_iface
, IFNAMSIZ
+1);
76 CHECK_WIFI_STATUS_RETURN_FAIL(result
, "Failed to put ndp_iface");
77 result
= request
.put_u8(NAN_REQ_ATTR_SDEA_PARAM_SECURITY_CFG
, msg
->ndp_cfg
.security_cfg
);
78 CHECK_WIFI_STATUS_RETURN_FAIL(result
, "Failed to put security_cfg");
79 result
= request
.put_u8(NAN_REQ_ATTR_SDEA_PARAM_QOS_CFG
, msg
->ndp_cfg
.qos_cfg
);
80 CHECK_WIFI_STATUS_RETURN_FAIL(result
, "Failed to put qos_cfg");
81 if(msg
->app_info
.ndp_app_info_len
){
82 result
= request
.put_u16(NAN_REQ_ATTR_APP_INFO_LEN
, msg
->app_info
.ndp_app_info_len
);
83 CHECK_WIFI_STATUS_RETURN_FAIL(result
, "Failed to put ndp_app_info_len");
84 result
= request
.put(NAN_REQ_ATTR_APP_INFO
, msg
->app_info
.ndp_app_info
, msg
->app_info
.ndp_app_info_len
);
85 CHECK_WIFI_STATUS_RETURN_FAIL(result
, "Failed to put ndp_app_info");
87 if (msg
->service_name_len
) {
88 result
= request
.put_u32(NAN_REQ_ATTR_SERVICE_NAME_LEN
, msg
->service_name_len
);
89 CHECK_WIFI_STATUS_RETURN_FAIL(result
, "Failed to put service_name_len");
90 result
= request
.put(NAN_REQ_ATTR_SERVICE_NAME
, msg
->service_name
, msg
->service_name_len
);
91 CHECK_WIFI_STATUS_RETURN_FAIL(result
, "Failed to put req_instance_id");
93 result
= putSecurityInfo(msg
->cipher_type
, &msg
->key_info
, 0, NULL
, &request
);
94 CHECK_CONFIG_PUT_16_RETURN_FAIL(1, id
, NAN_REQ_ATTR_HAL_TRANSACTION_ID
, request
, result
, "dataRequestInitiate:Failed to put transaction id");
96 request
.attr_end(data
);
100 int NanDataCommand::dataIndicationResponse(u16 id
, NanDataPathIndicationResponse
* msg
, WifiRequest
&request
) {
102 nlattr
*data
= newNlVendorMsg(SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_INDICATION_RESPONSE
, request
);
104 return WIFI_ERROR_OUT_OF_MEMORY
;
105 result
= request
.put_u32(NAN_REQ_ATTR_NDP_INSTANCE_ID
, msg
->ndp_instance_id
);
106 CHECK_WIFI_STATUS_RETURN_FAIL(result
, "Failed to put ndp_instance_id");
107 result
= request
.put_u8(NAN_REQ_ATTR_DATA_INTERFACE_NAME_LEN
, IFNAMSIZ
+1);
108 CHECK_WIFI_STATUS_RETURN_FAIL(result
, "Failed to put ifaceName_len");
109 result
= request
.put(NAN_REQ_ATTR_DATA_INTERFACE_NAME
, msg
->ndp_iface
, IFNAMSIZ
+1);
110 CHECK_WIFI_STATUS_RETURN_FAIL(result
, "Failed to put ndp_iface");
111 result
= request
.put_u8(NAN_REQ_ATTR_SDEA_PARAM_SECURITY_CFG
, msg
->ndp_cfg
.security_cfg
);
112 CHECK_WIFI_STATUS_RETURN_FAIL(result
, "Failed to put security_cfg");
113 result
= request
.put_u8(NAN_REQ_ATTR_SDEA_PARAM_QOS_CFG
, msg
->ndp_cfg
.qos_cfg
);
114 CHECK_WIFI_STATUS_RETURN_FAIL(result
, "Failed to put qos_cfg");
115 if(msg
->app_info
.ndp_app_info_len
){
116 result
= request
.put_u16(NAN_REQ_ATTR_APP_INFO_LEN
, msg
->app_info
.ndp_app_info_len
);
117 CHECK_WIFI_STATUS_RETURN_FAIL(result
, "Failed to put ndp_app_info_len");
118 result
= request
.put(NAN_REQ_ATTR_APP_INFO
, msg
->app_info
.ndp_app_info
, msg
->app_info
.ndp_app_info_len
);
119 CHECK_WIFI_STATUS_RETURN_FAIL(result
, "Failed to put ndp_app_info");
121 result
= request
.put_u8(NAN_REQ_ATTR_NDP_RESPONSE_CODE
, msg
->rsp_code
);
122 CHECK_WIFI_STATUS_RETURN_FAIL(result
, "Failed to put rsp_code");
123 if (msg
->service_name_len
) {
124 result
= request
.put_u32(NAN_REQ_ATTR_SERVICE_NAME_LEN
, msg
->service_name_len
);
125 CHECK_WIFI_STATUS_RETURN_FAIL(result
, "Failed to put service_name_len");
126 result
= request
.put(NAN_REQ_ATTR_SERVICE_NAME
, msg
->service_name
, msg
->service_name_len
);
127 CHECK_WIFI_STATUS_RETURN_FAIL(result
, "Failed to put req_instance_id");
129 result
= putSecurityInfo(msg
->cipher_type
, &msg
->key_info
, 0, NULL
, &request
);
130 CHECK_CONFIG_PUT_16_RETURN_FAIL(1, id
, NAN_REQ_ATTR_HAL_TRANSACTION_ID
, request
, result
, "dataIndicationResponse:Failed to put transaction id");
132 request
.attr_end(data
);
136 int NanDataCommand::dataEnd(u16 id
, NanDataPathEndRequest
* msg
, WifiRequest
&request
) {
138 nlattr
*data
= newNlVendorMsg(SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_END
, request
);
140 return WIFI_ERROR_UNKNOWN
;
141 for(i
=0; i
<msg
->num_ndp_instances
; i
++) {
142 result
= request
.put_u32(NAN_REQ_ATTR_NDP_INSTANCE_ID
, msg
->ndp_instance_id
[i
]);
143 CHECK_WIFI_STATUS_RETURN_FAIL(result
, "Failed to put ndp_instance_id");
145 CHECK_CONFIG_PUT_16_RETURN_FAIL(1, id
, NAN_REQ_ATTR_HAL_TRANSACTION_ID
, request
, result
, "dataEnd:Failed to put transaction id");
147 request
.attr_end(data
);
151 void NanDataCommand::dataInterfaceCreated(char *ifaceName
) {
153 for(i
=0; i
<SLSI_NAN_MAX_NDP
; i
++)
154 if (m_ifaceName
[i
][0] == 0) {
155 strncpy(ifaceName
, m_ifaceName
[i
], IFNAMSIZ
);
156 m_data_iface_count
++;
161 void NanDataCommand::dataInterfaceDeleted(char *ifaceName
) {
163 for(i
=0; i
<SLSI_NAN_MAX_NDP
; i
++)
164 if (strncmp(m_ifaceName
[i
], ifaceName
, IFNAMSIZ
)== 0) {
165 memset(m_ifaceName
[i
], 0, IFNAMSIZ
);
166 m_data_iface_count
--;
171 void NanDataCommand::dataRequestInitiateSuccess(NanDataPathInitiatorRequest
*msg
) {
173 for(i
=0; i
<SLSI_NAN_MAX_NDP
; i
++)
174 if(m_ndp_instance_id
[i
] == 0) {
175 m_ndp_instance_id
[i
] = msg
->requestor_instance_id
;
181 void NanDataCommand::dataIndicationResponseSuccess(NanDataPathIndicationResponse
*msg
) {
183 for(i
=0; i
<SLSI_NAN_MAX_NDP
; i
++)
184 if(m_ndp_instance_id
[i
] == 0) {
185 m_ndp_instance_id
[i
] = msg
->ndp_instance_id
;
191 void NanDataCommand::dataEndSuccess(NanDataPathEndRequest
*msg
) {
193 for(i
=0; i
<msg
->num_ndp_instances
; i
++)
194 for(j
=0; j
<SLSI_NAN_MAX_NDP
; j
++)
195 if(m_ndp_instance_id
[j
] == msg
->ndp_instance_id
[i
]) {
196 m_ndp_instance_id
[j
] = 0;
201 void NanDataCommand::processNdpChannelInfo(nlattr
*nl_data
, NanChannelInfo
&channel_info
) {
202 for(nl_iterator
nl_itr(nl_data
); nl_itr
.has_next(); nl_itr
.next()) {
203 switch(nl_itr
.get_type()) {
204 case NAN_EVT_ATTR_CHANNEL
:
205 channel_info
.channel
= nl_itr
.get_u32();
207 case NAN_EVT_ATTR_CHANNEL_BW
:
208 channel_info
.bandwidth
= nl_itr
.get_u32();
210 case NAN_EVT_ATTR_CHANNEL_NSS
:
211 channel_info
.nss
= nl_itr
.get_u32();
216 int NanDataCommand::processNdpReqEvent(WifiEvent
&event
, NanCallbackHandler
&callbackEventHandler
) {
217 NanDataPathRequestInd ind
;
218 memset(&ind
,0,sizeof(NanDataPathRequestInd
));
219 nlattr
*vendor_data
= event
.get_attribute(NL80211_ATTR_VENDOR_DATA
);
221 for(nl_iterator
nl_itr(vendor_data
); nl_itr
.has_next(); nl_itr
.next()) {
222 switch(nl_itr
.get_type()) {
223 case NAN_EVT_ATTR_SERVICE_INSTANCE_ID
:
224 ind
.service_instance_id
= nl_itr
.get_u16();
226 case NAN_EVT_ATTR_MATCH_ADDR
:
227 memcpy(ind
.peer_disc_mac_addr
, nl_itr
.get_data(), ETHER_ADDR_LEN
);
229 case NAN_EVT_ATTR_NDP_INSTANCE_ID
:
230 ind
.ndp_instance_id
= nl_itr
.get_u32();
232 case NAN_EVT_ATTR_SDEA_PARAM_SECURITY_CONFIG
:
233 ind
.ndp_cfg
.security_cfg
= (NanDataPathSecurityCfgStatus
)nl_itr
.get_u32();
235 case NAN_EVT_ATTR_SDEA_PARAM_QOS_CFG
:
236 ind
.ndp_cfg
.qos_cfg
= (NanDataPathQosCfg
)nl_itr
.get_u32();
238 case NAN_EVT_ATTR_APP_INFO_LEN
:
239 ind
.app_info
.ndp_app_info_len
= nl_itr
.get_u16();
241 case NAN_EVT_ATTR_APP_INFO
:
242 memcpy(ind
.app_info
.ndp_app_info
, nl_itr
.get_data(), ind
.app_info
.ndp_app_info_len
);
247 if(callbackEventHandler
.EventDataRequest
)
248 callbackEventHandler
.EventDataRequest(&ind
);
252 int NanDataCommand::processNdpCfmEvent(WifiEvent
&event
, NanCallbackHandler
&callbackEventHandler
) {
253 NanDataPathConfirmInd ind
;
254 memset(&ind
,0,sizeof(NanDataPathConfirmInd
));
255 nlattr
*vendor_data
= event
.get_attribute(NL80211_ATTR_VENDOR_DATA
);
257 for(nl_iterator
nl_itr(vendor_data
); nl_itr
.has_next(); nl_itr
.next()) {
258 switch(nl_itr
.get_type()) {
259 case NAN_EVT_ATTR_NDP_INSTANCE_ID
:
260 ind
.ndp_instance_id
= nl_itr
.get_u32();
262 case NAN_EVT_ATTR_MATCH_ADDR
:
263 memcpy(ind
.peer_ndi_mac_addr
, nl_itr
.get_data(), ETHER_ADDR_LEN
);
265 case NAN_EVT_ATTR_APP_INFO_LEN
:
266 ind
.app_info
.ndp_app_info_len
= nl_itr
.get_u16();
268 case NAN_EVT_ATTR_APP_INFO
:
269 memcpy(ind
.app_info
.ndp_app_info
, nl_itr
.get_data(), ind
.app_info
.ndp_app_info_len
);
271 case NAN_EVT_ATTR_NDP_RSP_CODE
:
272 ind
.rsp_code
= (NanDataPathResponseCode
)nl_itr
.get_u32();
274 case NAN_EVT_ATTR_STATUS_CODE
:
275 ind
.reason_code
= (NanStatusType
)nl_itr
.get_u32();
277 case NAN_EVT_ATTR_CHANNEL_INFO
:
278 if (ind
.num_channels
< NAN_MAX_CHANNEL_INFO_SUPPORTED
)
279 processNdpChannelInfo(nl_itr
.get(), ind
.channel_info
[ind
.num_channels
++]);
283 if(callbackEventHandler
.EventDataConfirm
)
284 callbackEventHandler
.EventDataConfirm(&ind
);
288 int NanDataCommand::processNdpEndEvent(WifiEvent
&event
, NanCallbackHandler
&callbackEventHandler
) {
289 NanDataPathEndInd ind
;
290 memset(&ind
,0,sizeof(NanDataPathEndInd
));
291 nlattr
*vendor_data
= event
.get_attribute(NL80211_ATTR_VENDOR_DATA
);
293 for(nl_iterator
nl_itr(vendor_data
); nl_itr
.has_next(); nl_itr
.next()) {
294 if (nl_itr
.get_type() == NAN_EVT_ATTR_NDP_INSTANCE_ID
) {
295 ind
.ndp_instance_id
[ind
.num_ndp_instances
++] = nl_itr
.get_u32();
298 if(callbackEventHandler
.EventDataEnd
)
299 callbackEventHandler
.EventDataEnd(&ind
);
303 NanDataCommand::NanDataCommand() {
304 memset(m_ndp_instance_id
, 0, sizeof(m_ndp_instance_id
));
305 memset(m_ifaceName
, 0, sizeof(m_ifaceName
));
307 m_data_iface_count
= 0;
308 m_max_ndp_sessions
= 0;
311 int NanDataCommand::getDataPathNLMsg(u16 id
, void *data
, int subcmd
, WifiRequest
&request
) {
313 case SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_INTERFACE_CREATE
:
314 return dataInterfaceCreateDelete(id
, (char *)data
, subcmd
, request
);
315 case SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_INTERFACE_DELETE
:
316 return dataInterfaceCreateDelete(id
, (char *)data
, subcmd
, request
);
317 case SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_REQUEST_INITIATOR
:
318 return dataRequestInitiate(id
, (NanDataPathInitiatorRequest
*)data
, request
);
319 case SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_INDICATION_RESPONSE
:
320 return dataIndicationResponse(id
, (NanDataPathIndicationResponse
*)data
, request
);
321 case SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_END
:
322 return dataEnd(id
, (NanDataPathEndRequest
*)data
, request
);
324 ALOGE("unknown subcmd :0x%x", subcmd
);
326 return WIFI_ERROR_UNKNOWN
;
329 void NanDataCommand::requestSuccess(u16 id
, void *data
, int subcmd
) {
331 case SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_INTERFACE_CREATE
:
332 dataInterfaceCreated((char *)data
);
334 case SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_INTERFACE_DELETE
:
335 dataInterfaceDeleted((char *)data
);
337 case SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_REQUEST_INITIATOR
:
338 dataRequestInitiateSuccess((NanDataPathInitiatorRequest
*)data
);
340 case SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_INDICATION_RESPONSE
:
341 dataIndicationResponseSuccess((NanDataPathIndicationResponse
*)data
);
343 case SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_END
:
344 dataEndSuccess((NanDataPathEndRequest
*)data
);
349 int NanDataCommand::handleEvent(WifiEvent
&event
, NanCallbackHandler
&callbackEventHandler
) {
350 int subcmd
= event
.get_vendor_subcmd();
352 case SLSI_NAN_EVENT_NDP_REQ
:
353 return processNdpReqEvent(event
, callbackEventHandler
);
354 case SLSI_NAN_EVENT_NDP_CFM
:
355 return processNdpCfmEvent(event
, callbackEventHandler
);
356 case SLSI_NAN_EVENT_NDP_END
:
357 return processNdpEndEvent(event
, callbackEventHandler
);
363 void NanDataCommand::setMaxNdpSessions(int max_ndp
) {
364 m_max_ndp_sessions
= max_ndp
> SLSI_NAN_MAX_NDP
? SLSI_NAN_MAX_NDP
: max_ndp
;
367 int NanDataCommand::putSecurityInfo(u32 cipher
, NanSecurityKeyInfo
*key_info
, u32 scid_len
, u8
*scid
, WifiRequest
*request
)
371 result
= request
->put_u32(NAN_REQ_ATTR_CIPHER_TYPE
, cipher
);
372 CHECK_WIFI_STATUS_RETURN_FAIL(result
, "enable:Failed to put cipher_type");
374 result
= request
->put_u32(NAN_REQ_ATTR_SECURITY_KEY_TYPE
, key_info
->key_type
);
375 CHECK_WIFI_STATUS_RETURN_FAIL(result
, "enable:Failed to put cipher_type");
377 if (key_info
->key_type
== NAN_SECURITY_KEY_INPUT_PMK
) {
378 result
= request
->put_u32(NAN_REQ_ATTR_SECURITY_PMK_LEN
, key_info
->body
.pmk_info
.pmk_len
);
379 CHECK_WIFI_STATUS_RETURN_FAIL(result
, "enable:Failed to put key_info->body.pmk_info.pmk_len");
380 result
= request
->put(NAN_REQ_ATTR_SECURITY_PMK
, key_info
->body
.pmk_info
.pmk
, key_info
->body
.pmk_info
.pmk_len
);
381 CHECK_WIFI_STATUS_RETURN_FAIL(result
, "enable:Failed to put key_info->body.pmk_info.pmk");
383 result
= request
->put_u32(NAN_REQ_ATTR_SECURITY_PASSPHRASE_LEN
, key_info
->body
.passphrase_info
.passphrase_len
);
384 CHECK_WIFI_STATUS_RETURN_FAIL(result
, "enable:Failed to put key_info->body.passphrase_info.passphrase_len");
385 result
= request
->put(NAN_REQ_ATTR_SECURITY_PASSPHRASE
, key_info
->body
.passphrase_info
.passphrase
,
386 key_info
->body
.passphrase_info
.passphrase_len
);
387 CHECK_WIFI_STATUS_RETURN_FAIL(result
, "enable:Failed to put key_info->body.passphrase_info.passphrase");
390 result
= request
->put_u32(NAN_REQ_ATTR_SCID_LEN
, scid_len
);
391 CHECK_WIFI_STATUS_RETURN_FAIL(result
, "enable:Failed to put scid_len");
393 result
= request
->put(NAN_REQ_ATTR_SCID
, scid
, scid_len
);
394 CHECK_WIFI_STATUS_RETURN_FAIL(result
, "enable:Failed to put scid");
399 const u8
*NanDataCommand::getCmdName(int cmd
){
401 case SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_INTERFACE_CREATE
:
402 return (const u8
*)"SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_INTERFACE_CREATE";
403 case SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_INTERFACE_DELETE
:
404 return (const u8
*)"SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_INTERFACE_DELETE";
405 case SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_REQUEST_INITIATOR
:
406 return (const u8
*)"SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_REQUEST_INITIATOR";
407 case SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_INDICATION_RESPONSE
:
408 return (const u8
*)"SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_INDICATION_RESPONSE";
409 case SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_END
:
410 return (const u8
*)"SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_END";
412 return (const u8
*)"UNKNOWN CMD";
414 return (const u8
*)"UNKNOWN CMD";