| // 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 <wlan/mlme/device_interface.h> |
| #include <fuchsia/wlan/mlme/c/fidl.h> |
| |
| namespace wlan { |
| namespace service { |
| |
| namespace wlan_mlme = ::fuchsia::wlan::mlme; |
| |
| zx_status_t SendJoinConfirm(DeviceInterface* device, wlan_mlme::JoinResultCodes result_code) { |
| debugfn(); |
| |
| auto resp = wlan_mlme::JoinConfirm::New(); |
| resp->result_code = result_code; |
| |
| // fidl2 doesn't have a way to get the serialized size yet. 4096 bytes should be enough for |
| // everyone. |
| size_t buf_len = 4096; |
| auto buffer = GetBuffer(buf_len); |
| if (buffer == nullptr) { return ZX_ERR_NO_RESOURCES; } |
| |
| auto packet = fbl::make_unique<Packet>(fbl::move(buffer), buf_len); |
| packet->set_peer(Packet::Peer::kService); |
| auto status = SerializeServiceMsg(packet.get(), fuchsia_wlan_mlme_MLMEJoinConfOrdinal, resp.get()); |
| if (status != ZX_OK) { |
| errorf("could not serialize JoinConfirm: %d\n", status); |
| } else { |
| status = device->SendService(fbl::move(packet)); |
| } |
| |
| return status; |
| } |
| |
| zx_status_t SendAuthConfirm(DeviceInterface* device, const common::MacAddr& peer_sta, |
| wlan_mlme::AuthenticateResultCodes code) { |
| debugfn(); |
| |
| auto resp = wlan_mlme::AuthenticateConfirm::New(); |
| peer_sta.CopyTo(resp->peer_sta_address.mutable_data()); |
| // TODO(tkilbourn): set this based on the actual auth type |
| resp->auth_type = wlan_mlme::AuthenticationTypes::OPEN_SYSTEM; |
| resp->result_code = code; |
| |
| // fidl2 doesn't have a way to get the serialized size yet. 4096 bytes should be enough for |
| // everyone. |
| size_t buf_len = 4096; |
| auto buffer = GetBuffer(buf_len); |
| if (buffer == nullptr) { return ZX_ERR_NO_RESOURCES; } |
| |
| auto packet = fbl::make_unique<Packet>(fbl::move(buffer), buf_len); |
| packet->set_peer(Packet::Peer::kService); |
| auto status = |
| SerializeServiceMsg(packet.get(), fuchsia_wlan_mlme_MLMEAuthenticateConfOrdinal, resp.get()); |
| if (status != ZX_OK) { |
| errorf("could not serialize AuthenticateConfirm: %d\n", status); |
| } else { |
| status = device->SendService(fbl::move(packet)); |
| } |
| |
| return status; |
| } |
| |
| zx_status_t SendDeauthConfirm(DeviceInterface* device, const common::MacAddr& peer_sta) { |
| debugfn(); |
| |
| auto resp = wlan_mlme::DeauthenticateConfirm::New(); |
| peer_sta.CopyTo(resp->peer_sta_address.mutable_data()); |
| |
| // fidl2 doesn't have a way to get the serialized size yet. 4096 bytes should be enough for |
| // everyone. |
| size_t buf_len = 4096; |
| auto buffer = GetBuffer(buf_len); |
| if (buffer == nullptr) { return ZX_ERR_NO_RESOURCES; } |
| |
| auto packet = fbl::make_unique<Packet>(fbl::move(buffer), buf_len); |
| packet->set_peer(Packet::Peer::kService); |
| auto status = |
| SerializeServiceMsg(packet.get(), fuchsia_wlan_mlme_MLMEDeauthenticateConfOrdinal, resp.get()); |
| if (status != ZX_OK) { |
| errorf("could not serialize DeauthenticateConfirm: %d\n", status); |
| } else { |
| status = device->SendService(fbl::move(packet)); |
| } |
| |
| return status; |
| } |
| |
| zx_status_t SendDeauthIndication(DeviceInterface* device, const common::MacAddr& peer_sta, |
| wlan_mlme::ReasonCode code) { |
| debugfn(); |
| |
| auto ind = wlan_mlme::DeauthenticateIndication::New(); |
| peer_sta.CopyTo(ind->peer_sta_address.mutable_data()); |
| ind->reason_code = code; |
| |
| // fidl2 doesn't have a way to get the serialized size yet. 4096 bytes should be enough for |
| // everyone. |
| size_t buf_len = 4096; |
| auto buffer = GetBuffer(buf_len); |
| if (buffer == nullptr) { return ZX_ERR_NO_RESOURCES; } |
| |
| auto packet = fbl::make_unique<Packet>(fbl::move(buffer), buf_len); |
| packet->set_peer(Packet::Peer::kService); |
| auto status = |
| SerializeServiceMsg(packet.get(), fuchsia_wlan_mlme_MLMEDeauthenticateIndOrdinal, ind.get()); |
| if (status != ZX_OK) { |
| errorf("could not serialize DeauthenticateIndication: %d\n", status); |
| } else { |
| status = device->SendService(fbl::move(packet)); |
| } |
| |
| return status; |
| } |
| |
| zx_status_t SendAssocConfirm(DeviceInterface* device, wlan_mlme::AssociateResultCodes code, |
| uint16_t aid) { |
| debugfn(); |
| ZX_DEBUG_ASSERT(code != wlan_mlme::AssociateResultCodes::SUCCESS || aid != 0); |
| |
| auto resp = wlan_mlme::AssociateConfirm::New(); |
| resp->result_code = code; |
| resp->association_id = aid; |
| |
| // fidl2 doesn't have a way to get the serialized size yet. 4096 bytes should be enough for |
| // everyone. |
| size_t buf_len = 4096; |
| auto buffer = GetBuffer(buf_len); |
| if (buffer == nullptr) { return ZX_ERR_NO_RESOURCES; } |
| |
| auto packet = fbl::make_unique<Packet>(fbl::move(buffer), buf_len); |
| packet->set_peer(Packet::Peer::kService); |
| auto status = SerializeServiceMsg(packet.get(), fuchsia_wlan_mlme_MLMEAssociateConfOrdinal, resp.get()); |
| if (status != ZX_OK) { |
| errorf("could not serialize AssociateConfirm: %d\n", status); |
| } else { |
| status = device->SendService(fbl::move(packet)); |
| } |
| |
| return status; |
| } |
| |
| zx_status_t SendDisassociateIndication(DeviceInterface* device, const common::MacAddr& peer_sta, |
| uint16_t code) { |
| debugfn(); |
| |
| auto ind = wlan_mlme::DisassociateIndication::New(); |
| peer_sta.CopyTo(ind->peer_sta_address.mutable_data()); |
| ind->reason_code = code; |
| |
| // fidl2 doesn't have a way to get the serialized size yet. 4096 bytes should be enough for |
| // everyone. |
| size_t buf_len = 4096; |
| auto buffer = GetBuffer(buf_len); |
| if (buffer == nullptr) { return ZX_ERR_NO_RESOURCES; } |
| |
| auto packet = fbl::make_unique<Packet>(fbl::move(buffer), buf_len); |
| packet->set_peer(Packet::Peer::kService); |
| auto status = |
| SerializeServiceMsg(packet.get(), fuchsia_wlan_mlme_MLMEDisassociateIndOrdinal, ind.get()); |
| if (status != ZX_OK) { |
| errorf("could not serialize DisassociateIndication: %d\n", status); |
| } else { |
| status = device->SendService(fbl::move(packet)); |
| } |
| |
| return status; |
| } |
| |
| zx_status_t SendSignalReportIndication(DeviceInterface* device, common::dBm rssi_dbm) { |
| debugfn(); |
| |
| auto ind = wlan_mlme::SignalReportIndication::New(); |
| ind->rssi_dbm = rssi_dbm.val; |
| |
| // fidl2 doesn't have a way to get the serialized size yet. 4096 bytes should be enough for |
| // everyone. |
| size_t buf_len = 4096; |
| auto buffer = GetBuffer(buf_len); |
| if (buffer == nullptr) { return ZX_ERR_NO_RESOURCES; } |
| |
| auto packet = fbl::make_unique<Packet>(fbl::move(buffer), buf_len); |
| packet->set_peer(Packet::Peer::kService); |
| auto status = SerializeServiceMsg(packet.get(), fuchsia_wlan_mlme_MLMESignalReportOrdinal, ind.get()); |
| if (status != ZX_OK) { |
| errorf("could not serialize SignalReportIndication: %d\n", status); |
| } else { |
| status = device->SendService(fbl::move(packet)); |
| } |
| |
| return status; |
| } |
| |
| zx_status_t SendEapolConfirm(DeviceInterface* device, wlan_mlme::EapolResultCodes result_code) { |
| debugfn(); |
| |
| auto resp = wlan_mlme::EapolConfirm::New(); |
| resp->result_code = result_code; |
| |
| // fidl2 doesn't have a way to get the serialized size yet. 4096 bytes should be enough for |
| // everyone. |
| size_t buf_len = 4096; |
| auto buffer = GetBuffer(buf_len); |
| if (buffer == nullptr) { return ZX_ERR_NO_RESOURCES; } |
| |
| auto packet = fbl::make_unique<Packet>(fbl::move(buffer), buf_len); |
| packet->set_peer(Packet::Peer::kService); |
| auto status = SerializeServiceMsg(packet.get(), fuchsia_wlan_mlme_MLMEEapolConfOrdinal, resp.get()); |
| if (status != ZX_OK) { |
| errorf("could not serialize EapolConfirm: %d\n", status); |
| } else { |
| status = device->SendService(fbl::move(packet)); |
| } |
| return status; |
| } |
| |
| zx_status_t SendEapolIndication(DeviceInterface* device, const EapolFrame& 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 len = sizeof(EapolFrame) + be16toh(eapol.packet_body_length); |
| if (len > 255) { return ZX_OK; } |
| |
| auto ind = wlan_mlme::EapolIndication::New(); |
| ind->data = ::fidl::VectorPtr<uint8_t>::New(len); |
| std::memcpy(ind->data->data(), &eapol, len); |
| src.CopyTo(ind->src_addr.mutable_data()); |
| dst.CopyTo(ind->dst_addr.mutable_data()); |
| |
| // fidl2 doesn't have a way to get the serialized size yet. 4096 bytes should be enough for |
| // everyone. |
| size_t buf_len = 4096; |
| auto buffer = GetBuffer(buf_len); |
| if (buffer == nullptr) { return ZX_ERR_NO_RESOURCES; } |
| |
| auto packet = fbl::make_unique<Packet>(fbl::move(buffer), buf_len); |
| packet->set_peer(Packet::Peer::kService); |
| auto status = SerializeServiceMsg(packet.get(), fuchsia_wlan_mlme_MLMEEapolIndOrdinal, ind.get()); |
| if (status != ZX_OK) { |
| errorf("could not serialize MLME-Eapol.indication: %d\n", status); |
| } else { |
| status = device->SendService(fbl::move(packet)); |
| } |
| return status; |
| } |
| |
| } // namespace service |
| } // namespace wlan |