blob: 202497c3d8e3ed01ee827afcf500bbf403666354 [file] [log] [blame]
// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "fullmac_mlme.h"
#include <wlan/common/logging.h>
#include "debug.h"
#include "device.h"
#include "fuchsia/wlan/common/c/banjo.h"
#include "src/connectivity/wlan/lib/mlme/fullmac/c-binding/bindings.h"
namespace wlanif {
#define DEVICE(c) static_cast<Device *>(c)
FullmacMlme::FullmacMlme(Device *device)
: device_(device), rust_mlme_(nullptr, delete_fullmac_mlme) {
debugfn();
}
zx_status_t FullmacMlme::Init() {
debugfn();
auto rust_device = rust_fullmac_device_interface_t{
.device = static_cast<void *>(this->device_),
.start = [](void *device, const rust_wlan_fullmac_ifc_protocol_copy_t *ifc,
zx_handle_t *out_sme_channel) -> zx_status_t {
zx::channel channel;
zx_status_t result = DEVICE(device)->StartFullmac(ifc, &channel);
*out_sme_channel = channel.release();
return result;
},
.query_device_info = [](void *device) -> wlan_fullmac_query_info_t {
wlan_fullmac_query_info_t out_resp;
DEVICE(device)->QueryDeviceInfo(&out_resp);
return out_resp;
},
.query_mac_sublayer_support = [](void *device) -> mac_sublayer_support_t {
mac_sublayer_support_t out_resp;
DEVICE(device)->QueryMacSublayerSupport(&out_resp);
return out_resp;
},
.query_security_support = [](void *device) -> security_support_t {
security_support_t out_resp;
DEVICE(device)->QuerySecuritySupport(&out_resp);
return out_resp;
},
.query_spectrum_management_support = [](void *device) -> spectrum_management_support_t {
spectrum_management_support_t out_resp;
DEVICE(device)->QuerySpectrumManagementSupport(&out_resp);
return out_resp;
},
.start_scan =
[](void *device, wlan_fullmac_impl_base_start_scan_request_t *req) {
DEVICE(device)->StartScan(req);
},
.connect =
[](void *device, wlan_fullmac_impl_base_connect_request_t *req) {
DEVICE(device)->Connect(req);
},
.reconnect =
[](void *device, wlan_fullmac_impl_base_reconnect_request_t *req) {
DEVICE(device)->Reconnect(req);
},
.auth_resp =
[](void *device, wlan_fullmac_impl_base_auth_resp_request_t *resp) {
DEVICE(device)->AuthenticateResp(resp);
},
.deauth =
[](void *device, wlan_fullmac_impl_base_deauth_request_t *req) {
DEVICE(device)->Deauthenticate(req);
},
.assoc_resp =
[](void *device, wlan_fullmac_impl_base_assoc_resp_request_t *resp) {
DEVICE(device)->AssociateResp(resp);
},
.disassoc =
[](void *device, wlan_fullmac_impl_base_disassoc_request_t *req) {
DEVICE(device)->Disassociate(req);
},
.reset = [](void *device,
wlan_fullmac_impl_base_reset_request_t *req) { DEVICE(device)->Reset(req); },
.start_bss =
[](void *device, wlan_fullmac_impl_base_start_bss_request_t *req) {
DEVICE(device)->StartBss(req);
},
.stop_bss =
[](void *device, wlan_fullmac_impl_base_stop_bss_request_t *req) {
DEVICE(device)->StopBss(req);
},
.set_keys_req = [](void *device,
wlan_fullmac_set_keys_req_t *req) -> wlan_fullmac_set_keys_resp_t {
wlan_fullmac_set_keys_resp_t out_resp;
DEVICE(device)->SetKeysReq(req, &out_resp);
return out_resp;
},
.del_keys_req = [](void *device,
wlan_fullmac_del_keys_req_t *req) { DEVICE(device)->DeleteKeysReq(req); },
.eapol_tx =
[](void *device, wlan_fullmac_impl_base_eapol_tx_request_t *req) {
DEVICE(device)->EapolTx(req);
},
.get_iface_counter_stats = [](void *device,
int32_t *out_status) -> wlan_fullmac_iface_counter_stats_t {
wlan_fullmac_iface_counter_stats_t out_stats;
*out_status = DEVICE(device)->GetIfaceCounterStats(&out_stats);
return out_stats;
},
.get_iface_histogram_stats = [](void *device,
int32_t *out_status) -> wlan_fullmac_iface_histogram_stats_t {
wlan_fullmac_iface_histogram_stats_t out_stats;
*out_status = DEVICE(device)->GetIfaceHistogramStats(&out_stats);
return out_stats;
},
.sae_handshake_resp =
[](void *device, wlan_fullmac_sae_handshake_resp_t *resp) {
DEVICE(device)->SaeHandshakeResp(resp);
},
.sae_frame_tx = [](void *device,
wlan_fullmac_sae_frame_t *frame) { DEVICE(device)->SaeFrameTx(frame); },
.wmm_status_req = [](void *device) { DEVICE(device)->WmmStatusReq(); },
.on_link_state_changed = [](void *device,
bool online) { DEVICE(device)->OnLinkStateChanged(online); },
};
rust_mlme_ = RustFullmacMlme(start_fullmac_mlme(rust_device), delete_fullmac_mlme);
// This check is specifically needed for unit tests (where it always fails) so
// StopMainLoop() is not called during release.
if (!rust_mlme_.get()) {
FDF_LOGL(ERROR, *(device_->Logger()), "rust mlme is not valid");
return ZX_ERR_BAD_HANDLE;
}
return ZX_OK;
}
void FullmacMlme::StopMainLoop() { stop_fullmac_mlme(rust_mlme_.get()); }
} // namespace wlanif