From 54411bef4eb16af0822820205a923690ea7e822a Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 17 Jul 2017 09:25:58 -0500 Subject: Services/UDS: Add functions to generate 802.11 auth and assoc response frames. --- src/core/hle/service/nwm/uds_connection.cpp | 79 +++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 src/core/hle/service/nwm/uds_connection.cpp (limited to 'src/core/hle/service/nwm/uds_connection.cpp') diff --git a/src/core/hle/service/nwm/uds_connection.cpp b/src/core/hle/service/nwm/uds_connection.cpp new file mode 100644 index 000000000..c8a76ec2a --- /dev/null +++ b/src/core/hle/service/nwm/uds_connection.cpp @@ -0,0 +1,79 @@ +// Copyright 2017 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "core/hle/service/nwm/nwm_uds.h" +#include "core/hle/service/nwm/uds_connection.h" +#include "fmt/format.h" + +namespace Service { +namespace NWM { + +// Note: These values were taken from a packet capture of an o3DS XL +// broadcasting a Super Smash Bros. 4 lobby. +constexpr u16 DefaultExtraCapabilities = 0x0431; + +std::vector GenerateAuthenticationFrame(AuthenticationSeq seq) { + AuthenticationFrame frame{}; + frame.auth_seq = static_cast(seq); + + std::vector data(sizeof(frame)); + std::memcpy(data.data(), &frame, sizeof(frame)); + + return data; +} + +AuthenticationSeq GetAuthenticationSeqNumber(const std::vector& body) { + AuthenticationFrame frame; + std::memcpy(&frame, body.data(), sizeof(frame)); + + return static_cast(frame.auth_seq); +} + +/** + * Generates an SSID tag of an 802.11 Beacon frame with an 8-byte character representation of the + * specified network id as the SSID value. + * @param network_id The network id to use. + * @returns A buffer with the SSID tag. + */ +static std::vector GenerateSSIDTag(u32 network_id) { + constexpr u8 SSIDSize = 8; + + struct { + u8 id = static_cast(TagId::SSID); + u8 size = SSIDSize; + } tag_header; + + std::vector buffer(sizeof(tag_header) + SSIDSize); + + std::memcpy(buffer.data(), &tag_header, sizeof(tag_header)); + + std::string network_name = fmt::format("{0:08X}", network_id); + + std::memcpy(buffer.data() + sizeof(tag_header), network_name.c_str(), SSIDSize); + + return buffer; +} + +std::vector GenerateAssocResponseFrame(AssocStatus status, u16 association_id, u32 network_id) { + AssociationResponseFrame frame{}; + frame.capabilities = DefaultExtraCapabilities; + frame.status_code = static_cast(status); + // The association id is ORed with this magic value (0xC000) + constexpr u16 AssociationIdMagic = 0xC000; + frame.assoc_id = association_id | AssociationIdMagic; + + std::vector data(sizeof(frame)); + std::memcpy(data.data(), &frame, sizeof(frame)); + + auto ssid_tag = GenerateSSIDTag(network_id); + data.insert(data.end(), ssid_tag.begin(), ssid_tag.end()); + + // TODO(Subv): Add the SupportedRates tag. + // TODO(Subv): Add the DSParameterSet tag. + // TODO(Subv): Add the ERPInformation tag. + return data; +} + +} // namespace NWM +} // namespace Service -- cgit v1.2.3