blob: 9cdc24a09e16792d93754d0914c4c009b9575d07 [file] [log] [blame]
// Copyright 2018 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 <wlan/mlme/service.h>
#include <fuchsia/wlan/mlme/c/fidl.h>
namespace wlan {
namespace service {
namespace wlan_mlme = ::fuchsia::wlan::mlme;
std::optional<common::MacAddr> GetPeerAddr(const BaseMlmeMsg& msg) {
if (auto auth_req = msg.As<wlan_mlme::AuthenticateRequest>()) {
return std::make_optional<common::MacAddr>(auth_req->body()->peer_sta_address.data());
} else if (auto assoc_req = msg.As<wlan_mlme::AssociateRequest>()) {
return std::make_optional<common::MacAddr>(assoc_req->body()->peer_sta_address.data());
} else if (auto deauth_req = msg.As<wlan_mlme::DeauthenticateRequest>()) {
return std::make_optional<common::MacAddr>(deauth_req->body()->peer_sta_address.data());
} else if (auto eapol_req = msg.As<wlan_mlme::EapolRequest>()) {
return std::make_optional<common::MacAddr>(eapol_req->body()->dst_addr.data());
} else if (auto auth_resp = msg.As<wlan_mlme::AuthenticateResponse>()) {
return std::make_optional<common::MacAddr>(auth_resp->body()->peer_sta_address.data());
} else if (auto assoc_resp = msg.As<wlan_mlme::AssociateResponse>()) {
return std::make_optional<common::MacAddr>(assoc_resp->body()->peer_sta_address.data());
} else if (auto open_req = msg.As<wlan_mlme::SetControlledPortRequest>()) {
return std::make_optional<common::MacAddr>(open_req->body()->peer_sta_address.data());
} else {
return std::nullopt;
}
}
zx_status_t SendJoinConfirm(DeviceInterface* device, wlan_mlme::JoinResultCodes result_code) {
debugfn();
wlan_mlme::JoinConfirm conf;
conf.result_code = result_code;
return SendServiceMsg(device, &conf, fuchsia_wlan_mlme_MLMEJoinConfOrdinal);
}
zx_status_t SendAuthConfirm(DeviceInterface* device, const common::MacAddr& peer_sta,
wlan_mlme::AuthenticateResultCodes code) {
debugfn();
wlan_mlme::AuthenticateConfirm conf;
peer_sta.CopyTo(conf.peer_sta_address.mutable_data());
// TODO(tkilbourn): set this based on the actual auth type
conf.auth_type = wlan_mlme::AuthenticationTypes::OPEN_SYSTEM;
conf.result_code = code;
return SendServiceMsg(device, &conf, fuchsia_wlan_mlme_MLMEAuthenticateConfOrdinal);
}
zx_status_t SendAuthIndication(DeviceInterface* device, const common::MacAddr& peer_sta,
wlan_mlme::AuthenticationTypes auth_type) {
debugfn();
wlan_mlme::AuthenticateIndication ind;
peer_sta.CopyTo(ind.peer_sta_address.mutable_data());
ind.auth_type = auth_type;
return SendServiceMsg(device, &ind, fuchsia_wlan_mlme_MLMEAuthenticateIndOrdinal);
}
zx_status_t SendDeauthConfirm(DeviceInterface* device, const common::MacAddr& peer_sta) {
debugfn();
wlan_mlme::DeauthenticateConfirm conf;
peer_sta.CopyTo(conf.peer_sta_address.mutable_data());
return SendServiceMsg(device, &conf, fuchsia_wlan_mlme_MLMEDeauthenticateConfOrdinal);
}
zx_status_t SendDeauthIndication(DeviceInterface* device, const common::MacAddr& peer_sta,
wlan_mlme::ReasonCode code) {
debugfn();
wlan_mlme::DeauthenticateIndication ind;
peer_sta.CopyTo(ind.peer_sta_address.mutable_data());
ind.reason_code = code;
return SendServiceMsg(device, &ind, fuchsia_wlan_mlme_MLMEDeauthenticateIndOrdinal);
}
zx_status_t SendAssocConfirm(DeviceInterface* device, wlan_mlme::AssociateResultCodes code,
uint16_t aid) {
debugfn();
ZX_DEBUG_ASSERT(code != wlan_mlme::AssociateResultCodes::SUCCESS || aid != 0);
wlan_mlme::AssociateConfirm conf;
conf.result_code = code;
conf.association_id = aid;
return SendServiceMsg(device, &conf, fuchsia_wlan_mlme_MLMEAssociateConfOrdinal);
}
zx_status_t SendAssocIndication(DeviceInterface* device, const common::MacAddr& peer_sta,
uint16_t listen_interval, Span<const uint8_t> ssid,
std::optional<Span<const uint8_t>> rsn_body) {
debugfn();
wlan_mlme::AssociateIndication ind;
peer_sta.CopyTo(ind.peer_sta_address.mutable_data());
ind.listen_interval = listen_interval;
ind.ssid.resize(0);
ind.ssid->assign(ssid.begin(), ssid.end());
if (rsn_body) {
ind.rsn->reserve(2 + rsn_body->size());
ind.rsn->push_back(static_cast<uint8_t>(element_id::kRsn));
ind.rsn->push_back(rsn_body->size());
ind.rsn->insert(ind.rsn->end(), rsn_body->begin(), rsn_body->end());
}
return SendServiceMsg(device, &ind, fuchsia_wlan_mlme_MLMEAssociateIndOrdinal);
}
zx_status_t SendDisassociateIndication(DeviceInterface* device, const common::MacAddr& peer_sta,
uint16_t code) {
debugfn();
wlan_mlme::DisassociateIndication ind;
peer_sta.CopyTo(ind.peer_sta_address.mutable_data());
ind.reason_code = code;
return SendServiceMsg(device, &ind, fuchsia_wlan_mlme_MLMEDisassociateIndOrdinal);
}
zx_status_t SendSignalReportIndication(DeviceInterface* device, common::dBm rssi_dbm) {
debugfn();
wlan_mlme::SignalReportIndication ind;
ind.rssi_dbm = rssi_dbm.val;
return SendServiceMsg(device, &ind, fuchsia_wlan_mlme_MLMESignalReportOrdinal);
}
zx_status_t SendEapolConfirm(DeviceInterface* device, wlan_mlme::EapolResultCodes result_code) {
debugfn();
wlan_mlme::EapolConfirm resp;
resp.result_code = result_code;
return SendServiceMsg(device, &resp, fuchsia_wlan_mlme_MLMEEapolConfOrdinal);
}
zx_status_t SendEapolIndication(DeviceInterface* device, const EapolHdr& eapol,
const common::MacAddr& src, const common::MacAddr& dst) {
debugfn();
// Limit EAPOL packet size. The EAPOL packet's size depends on the link transport protocol and
// might exceed 255 octets. However, we don't support EAP yet and EAPOL Key frames are always
// shorter.
// TODO(hahnr): If necessary, find a better upper bound once we support EAP.
size_t frame_len = eapol.len() + eapol.get_packet_body_length();
if (frame_len > 255) { return ZX_OK; }
wlan_mlme::EapolIndication ind;
ind.data = ::std::vector<uint8_t>(frame_len);
std::memcpy(ind.data.data(), &eapol, frame_len);
src.CopyTo(ind.src_addr.mutable_data());
dst.CopyTo(ind.dst_addr.mutable_data());
return SendServiceMsg(device, &ind, fuchsia_wlan_mlme_MLMEEapolIndOrdinal);
}
zx_status_t SendStartConfirm(DeviceInterface* device, wlan_mlme::StartResultCodes code) {
wlan_mlme::StartConfirm msg;
msg.result_code = code;
return SendServiceMsg(device, &msg, fuchsia_wlan_mlme_MLMEStartConfOrdinal);
}
zx_status_t SendStopConfirm(DeviceInterface* device, wlan_mlme::StopResultCodes code) {
wlan_mlme::StopConfirm msg;
msg.result_code = code;
return SendServiceMsg(device, &msg, fuchsia_wlan_mlme_MLMEStopConfOrdinal);
}
} // namespace service
} // namespace wlan