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(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 request
.attr_end(data
);
58 int NanDataCommand::dataRequestInitiate(NanDataPathInitiatorRequest
* msg
, WifiRequest
&request
) {
60 nlattr
*data
= newNlVendorMsg(SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_REQUEST_INITIATOR
, request
);
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");
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");
91 result
= putSecurityInfo(msg
->cipher_type
, &msg
->key_info
, 0, NULL
, &request
);
92 request
.attr_end(data
);
96 int NanDataCommand::dataIndicationResponse(NanDataPathIndicationResponse
* msg
, WifiRequest
&request
) {
98 nlattr
*data
= newNlVendorMsg(SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_INDICATION_RESPONSE
, request
);
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");
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");
125 result
= putSecurityInfo(msg
->cipher_type
, &msg
->key_info
, 0, NULL
, &request
);
126 request
.attr_end(data
);
130 int NanDataCommand::dataEnd(NanDataPathEndRequest
* msg
, WifiRequest
&request
) {
132 nlattr
*data
= newNlVendorMsg(SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_END
, request
);
134 return WIFI_ERROR_UNKNOWN
;
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");
140 request
.attr_end(data
);
144 void NanDataCommand::dataInterfaceCreated(char *ifaceName
) {
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
++;
154 void NanDataCommand::dataInterfaceDeleted(char *ifaceName
) {
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
--;
164 void NanDataCommand::dataRequestInitiateSuccess(NanDataPathInitiatorRequest
*msg
) {
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
;
174 void NanDataCommand::dataIndicationResponseSuccess(NanDataPathIndicationResponse
*msg
) {
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
;
184 void NanDataCommand::dataEndSuccess(NanDataPathEndRequest
*msg
) {
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;
194 void 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();
200 case NAN_EVT_ATTR_CHANNEL_BW
:
201 channel_info
.bandwidth
= nl_itr
.get_u32();
203 case NAN_EVT_ATTR_CHANNEL_NSS
:
204 channel_info
.nss
= nl_itr
.get_u32();
209 int 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
);
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();
219 case NAN_EVT_ATTR_MATCH_ADDR
:
220 memcpy(ind
.peer_disc_mac_addr
, nl_itr
.get_data(), ETHER_ADDR_LEN
);
222 case NAN_EVT_ATTR_NDP_INSTANCE_ID
:
223 ind
.ndp_instance_id
= nl_itr
.get_u32();
225 case NAN_EVT_ATTR_SDEA_PARAM_SECURITY_CONFIG
:
226 ind
.ndp_cfg
.security_cfg
= (NanDataPathSecurityCfgStatus
)nl_itr
.get_u32();
228 case NAN_EVT_ATTR_SDEA_PARAM_QOS_CFG
:
229 ind
.ndp_cfg
.qos_cfg
= (NanDataPathQosCfg
)nl_itr
.get_u32();
231 case NAN_EVT_ATTR_APP_INFO_LEN
:
232 ind
.app_info
.ndp_app_info_len
= nl_itr
.get_u16();
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
);
240 if(callbackEventHandler
.EventDataRequest
)
241 callbackEventHandler
.EventDataRequest(&ind
);
245 int 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
);
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();
255 case NAN_EVT_ATTR_MATCH_ADDR
:
256 memcpy(ind
.peer_ndi_mac_addr
, nl_itr
.get_data(), ETHER_ADDR_LEN
);
258 case NAN_EVT_ATTR_APP_INFO_LEN
:
259 ind
.app_info
.ndp_app_info_len
= nl_itr
.get_u16();
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
);
264 case NAN_EVT_ATTR_NDP_RSP_CODE
:
265 ind
.rsp_code
= (NanDataPathResponseCode
)nl_itr
.get_u32();
267 case NAN_EVT_ATTR_STATUS_CODE
:
268 ind
.reason_code
= (NanStatusType
)nl_itr
.get_u32();
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
++]);
276 if(callbackEventHandler
.EventDataConfirm
)
277 callbackEventHandler
.EventDataConfirm(&ind
);
281 int 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
);
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();
291 if(callbackEventHandler
.EventDataEnd
)
292 callbackEventHandler
.EventDataEnd(&ind
);
296 NanDataCommand::NanDataCommand() {
297 memset(m_ndp_instance_id
, 0, sizeof(m_ndp_instance_id
));
298 memset(m_ifaceName
, 0, sizeof(m_ifaceName
));
300 m_data_iface_count
= 0;
303 int NanDataCommand::getDataPathNLMsg(void *data
, int subcmd
, WifiRequest
&request
) {
305 case SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_INTERFACE_CREATE
:
306 case SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_INTERFACE_DELETE
:
307 return dataInterfaceCreateDelete((char *)data
, subcmd
, request
);
308 case SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_REQUEST_INITIATOR
:
309 return dataRequestInitiate((NanDataPathInitiatorRequest
*)data
, request
);
310 case SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_INDICATION_RESPONSE
:
311 return dataIndicationResponse((NanDataPathIndicationResponse
*)data
, request
);
312 case SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_END
:
313 return dataEnd((NanDataPathEndRequest
*)data
, request
);
315 ALOGE("unknown subcmd :%d", subcmd
);
317 return WIFI_ERROR_UNKNOWN
;
320 void NanDataCommand::requestSuccess(u16 id
, void *data
, int subcmd
) {
322 case SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_INTERFACE_CREATE
:
323 transaction_id
[idx_iface_create
] = id
;
324 dataInterfaceCreated((char *)data
);
326 case SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_INTERFACE_DELETE
:
327 transaction_id
[idx_iface_delete
] = id
;
328 dataInterfaceDeleted((char *)data
);
330 case SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_REQUEST_INITIATOR
:
331 transaction_id
[idx_ndp_initiator
] = id
;
332 dataRequestInitiateSuccess((NanDataPathInitiatorRequest
*)data
);
334 case SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_INDICATION_RESPONSE
:
335 transaction_id
[idx_ndp_responder
] = id
;
336 dataIndicationResponseSuccess((NanDataPathIndicationResponse
*)data
);
338 case SLSI_NL80211_VENDOR_SUBCMD_NAN_DATA_END
:
339 transaction_id
[idx_ndp_end
] = id
;
340 dataEndSuccess((NanDataPathEndRequest
*)data
);
345 int NanDataCommand::handleEvent(WifiEvent
&event
, NanCallbackHandler
&callbackEventHandler
) {
346 int subcmd
= event
.get_vendor_subcmd();
348 case SLSI_NAN_EVENT_NDP_REQ
:
349 return processNdpReqEvent(event
, callbackEventHandler
);
350 case SLSI_NAN_EVENT_NDP_CFM
:
351 return processNdpCfmEvent(event
, callbackEventHandler
);
352 case SLSI_NAN_EVENT_NDP_END
:
353 return processNdpEndEvent(event
, callbackEventHandler
);
359 int NanDataCommand::getResponseTransactionId(NanResponseMsg
*res
) {
361 switch(res
->response_type
) {
362 case NAN_DP_INTERFACE_CREATE
:
363 id
= transaction_id
[idx_iface_create
];
364 transaction_id
[idx_iface_create
] = 0;
366 case NAN_DP_INTERFACE_DELETE
:
367 id
= transaction_id
[idx_iface_delete
];
368 transaction_id
[idx_iface_delete
] = 0;
370 case NAN_DP_INITIATOR_RESPONSE
:
371 id
= transaction_id
[idx_ndp_initiator
];
372 transaction_id
[idx_ndp_initiator
] = 0;
374 case NAN_DP_RESPONDER_RESPONSE
:
375 id
= transaction_id
[idx_ndp_responder
];
376 transaction_id
[idx_ndp_responder
] = 0;
379 id
= transaction_id
[idx_ndp_end
];
380 transaction_id
[idx_ndp_end
] = 0;
388 void NanDataCommand::setMaxNdpSessions(int max_ndp
) {
389 m_max_ndp_sessions
= max_ndp
> SLSI_NAN_MAX_NDP
? SLSI_NAN_MAX_NDP
: max_ndp
;
392 int NanDataCommand::putSecurityInfo(u32 cipher
, NanSecurityKeyInfo
*key_info
, u32 scid_len
, u8
*scid
, WifiRequest
*request
)
396 result
= request
->put_u32(NAN_REQ_ATTR_CIPHER_TYPE
, cipher
);
397 CHECK_WIFI_STATUS_RETURN_FAIL(result
, "enable:Failed to put cipher_type");
399 result
= request
->put_u32(NAN_REQ_ATTR_SECURITY_KEY_TYPE
, key_info
->key_type
);
400 CHECK_WIFI_STATUS_RETURN_FAIL(result
, "enable:Failed to put cipher_type");
402 if (key_info
->key_type
== NAN_SECURITY_KEY_INPUT_PMK
) {
403 result
= request
->put_u32(NAN_REQ_ATTR_SECURITY_PMK_LEN
, key_info
->body
.pmk_info
.pmk_len
);
404 CHECK_WIFI_STATUS_RETURN_FAIL(result
, "enable:Failed to put key_info->body.pmk_info.pmk_len");
405 result
= request
->put(NAN_REQ_ATTR_SECURITY_PMK
, key_info
->body
.pmk_info
.pmk
, key_info
->body
.pmk_info
.pmk_len
);
406 CHECK_WIFI_STATUS_RETURN_FAIL(result
, "enable:Failed to put key_info->body.pmk_info.pmk");
408 result
= request
->put_u32(NAN_REQ_ATTR_SECURITY_PASSPHRASE_LEN
, key_info
->body
.passphrase_info
.passphrase_len
);
409 CHECK_WIFI_STATUS_RETURN_FAIL(result
, "enable:Failed to put key_info->body.passphrase_info.passphrase_len");
410 result
= request
->put(NAN_REQ_ATTR_SECURITY_PASSPHRASE
, key_info
->body
.passphrase_info
.passphrase
,
411 key_info
->body
.passphrase_info
.passphrase_len
);
412 CHECK_WIFI_STATUS_RETURN_FAIL(result
, "enable:Failed to put key_info->body.passphrase_info.passphrase");
415 result
= request
->put_u32(NAN_REQ_ATTR_SCID_LEN
, scid_len
);
416 CHECK_WIFI_STATUS_RETURN_FAIL(result
, "enable:Failed to put scid_len");
418 result
= request
->put(NAN_REQ_ATTR_SCID
, scid
, scid_len
);
419 CHECK_WIFI_STATUS_RETURN_FAIL(result
, "enable:Failed to put scid");