Browse Source
Merge pull request #2831 from Subv/uds_auth
Merge pull request #2831 from Subv/uds_auth
Services/UDS: Handle beacon frames and the basic AP connection sequence frames.pull/15/merge
committed by
GitHub
7 changed files with 289 additions and 53 deletions
-
2src/core/CMakeLists.txt
-
165src/core/hle/service/nwm/nwm_uds.cpp
-
12src/core/hle/service/nwm/nwm_uds.h
-
3src/core/hle/service/nwm/uds_beacon.cpp
-
30src/core/hle/service/nwm/uds_beacon.h
-
79src/core/hle/service/nwm/uds_connection.cpp
-
51src/core/hle/service/nwm/uds_connection.h
@ -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
|
|||
@ -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 |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue