diff options
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/core/hle/service/nwm/nwm_uds.h | 12 | ||||
| -rw-r--r-- | src/core/hle/service/nwm/uds_beacon.h | 11 | ||||
| -rw-r--r-- | src/core/hle/service/nwm/uds_connection.cpp | 79 | ||||
| -rw-r--r-- | src/core/hle/service/nwm/uds_connection.h | 51 | 
5 files changed, 144 insertions, 11 deletions
| diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index ea09819e5..0719138af 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -144,6 +144,7 @@ set(SRCS              hle/service/nwm/nwm_tst.cpp              hle/service/nwm/nwm_uds.cpp              hle/service/nwm/uds_beacon.cpp +            hle/service/nwm/uds_connection.cpp              hle/service/nwm/uds_data.cpp              hle/service/pm_app.cpp              hle/service/ptm/ptm.cpp @@ -342,6 +343,7 @@ set(HEADERS              hle/service/nwm/nwm_tst.h              hle/service/nwm/nwm_uds.h              hle/service/nwm/uds_beacon.h +            hle/service/nwm/uds_connection.h              hle/service/nwm/uds_data.h              hle/service/pm_app.h              hle/service/ptm/ptm.h diff --git a/src/core/hle/service/nwm/nwm_uds.h b/src/core/hle/service/nwm/nwm_uds.h index 141f49f9c..f1caaf974 100644 --- a/src/core/hle/service/nwm/nwm_uds.h +++ b/src/core/hle/service/nwm/nwm_uds.h @@ -42,6 +42,7 @@ using NodeList = std::vector<NodeInfo>;  enum class NetworkStatus {      NotConnected = 3,      ConnectedAsHost = 6, +    Connecting = 7,      ConnectedAsClient = 9,      ConnectedAsSpectator = 10,  }; @@ -85,6 +86,17 @@ static_assert(offsetof(NetworkInfo, oui_value) == 0xC, "oui_value is at the wron  static_assert(offsetof(NetworkInfo, wlan_comm_id) == 0x10, "wlancommid is at the wrong offset.");  static_assert(sizeof(NetworkInfo) == 0x108, "NetworkInfo has incorrect size."); +/// Additional block tag ids in the Beacon and Association Response frames +enum class TagId : u8 { +    SSID = 0, +    SupportedRates = 1, +    DSParameterSet = 2, +    TrafficIndicationMap = 5, +    CountryInformation = 7, +    ERPInformation = 42, +    VendorSpecific = 221 +}; +  class NWM_UDS final : public Interface {  public:      NWM_UDS(); diff --git a/src/core/hle/service/nwm/uds_beacon.h b/src/core/hle/service/nwm/uds_beacon.h index caacf4c6f..c726b04d9 100644 --- a/src/core/hle/service/nwm/uds_beacon.h +++ b/src/core/hle/service/nwm/uds_beacon.h @@ -17,17 +17,6 @@ namespace NWM {  using MacAddress = std::array<u8, 6>;  constexpr std::array<u8, 3> NintendoOUI = {0x00, 0x1F, 0x32}; -/// Additional block tag ids in the Beacon frames -enum class TagId : u8 { -    SSID = 0, -    SupportedRates = 1, -    DSParameterSet = 2, -    TrafficIndicationMap = 5, -    CountryInformation = 7, -    ERPInformation = 42, -    VendorSpecific = 221 -}; -  /**   * Internal vendor-specific tag ids as stored inside   * VendorSpecific blocks in the Beacon frames. 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<u8> GenerateAuthenticationFrame(AuthenticationSeq seq) { +    AuthenticationFrame frame{}; +    frame.auth_seq = static_cast<u16>(seq); + +    std::vector<u8> data(sizeof(frame)); +    std::memcpy(data.data(), &frame, sizeof(frame)); + +    return data; +} + +AuthenticationSeq GetAuthenticationSeqNumber(const std::vector<u8>& body) { +    AuthenticationFrame frame; +    std::memcpy(&frame, body.data(), sizeof(frame)); + +    return static_cast<AuthenticationSeq>(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<u8> GenerateSSIDTag(u32 network_id) { +    constexpr u8 SSIDSize = 8; + +    struct { +        u8 id = static_cast<u8>(TagId::SSID); +        u8 size = SSIDSize; +    } tag_header; + +    std::vector<u8> 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<u8> GenerateAssocResponseFrame(AssocStatus status, u16 association_id, u32 network_id) { +    AssociationResponseFrame frame{}; +    frame.capabilities = DefaultExtraCapabilities; +    frame.status_code = static_cast<u16>(status); +    // The association id is ORed with this magic value (0xC000) +    constexpr u16 AssociationIdMagic = 0xC000; +    frame.assoc_id = association_id | AssociationIdMagic; + +    std::vector<u8> 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 diff --git a/src/core/hle/service/nwm/uds_connection.h b/src/core/hle/service/nwm/uds_connection.h new file mode 100644 index 000000000..73f55a4fd --- /dev/null +++ b/src/core/hle/service/nwm/uds_connection.h @@ -0,0 +1,51 @@ +// Copyright 2017 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include <vector> +#include "common/common_types.h" +#include "common/swap.h" +#include "core/hle/service/service.h" + +namespace Service { +namespace NWM { + +/// Sequence number of the 802.11 authentication frames. +enum class AuthenticationSeq : u16 { SEQ1 = 1, SEQ2 = 2 }; + +enum class AuthAlgorithm : u16 { OpenSystem = 0 }; + +enum class AuthStatus : u16 { Successful = 0 }; + +enum class AssocStatus : u16 { Successful = 0 }; + +struct AuthenticationFrame { +    u16_le auth_algorithm = static_cast<u16>(AuthAlgorithm::OpenSystem); +    u16_le auth_seq; +    u16_le status_code = static_cast<u16>(AuthStatus::Successful); +}; + +static_assert(sizeof(AuthenticationFrame) == 6, "AuthenticationFrame has wrong size"); + +struct AssociationResponseFrame { +    u16_le capabilities; +    u16_le status_code; +    u16_le assoc_id; +}; + +static_assert(sizeof(AssociationResponseFrame) == 6, "AssociationResponseFrame has wrong size"); + +/// Generates an 802.11 authentication frame, starting at the frame body. +std::vector<u8> GenerateAuthenticationFrame(AuthenticationSeq seq); + +/// Returns the sequence number from the body of an Authentication frame. +AuthenticationSeq GetAuthenticationSeqNumber(const std::vector<u8>& body); + +/// Generates an 802.11 association response frame with the specified status, association id and +/// network id, starting at the frame body. +std::vector<u8> GenerateAssocResponseFrame(AssocStatus status, u16 association_id, u32 network_id); + +} // namespace NWM +} // namespace Service | 
