another try

This commit is contained in:
mgthepro
2022-11-05 13:58:44 +01:00
parent 4a9f2bbf2a
commit 9f63fbe700
2002 changed files with 671171 additions and 671092 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -1,134 +1,134 @@
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <array>
#include <cstring>
#include <functional>
#include <memory>
#include <mutex>
#include <optional>
#include <random>
#include <span>
#include <thread>
#include <unordered_map>
#include "common/logging/log.h"
#include "common/socket_types.h"
#include "core/hle/result.h"
#include "core/hle/service/ldn/ldn_results.h"
#include "core/hle/service/ldn/ldn_types.h"
#include "network/network.h"
namespace Service::LDN {
class LANDiscovery;
class LanStation {
public:
LanStation(s8 node_id_, LANDiscovery* discovery_);
~LanStation();
void OnClose();
NodeStatus GetStatus() const;
void Reset();
void OverrideInfo();
protected:
friend class LANDiscovery;
NodeInfo* node_info;
NodeStatus status;
s8 node_id;
LANDiscovery* discovery;
};
class LANDiscovery {
public:
using LanEventFunc = std::function<void()>;
LANDiscovery(Network::RoomNetwork& room_network_);
~LANDiscovery();
State GetState() const;
void SetState(State new_state);
Result GetNetworkInfo(NetworkInfo& out_network) const;
Result GetNetworkInfo(NetworkInfo& out_network, std::vector<NodeLatestUpdate>& out_updates,
std::size_t buffer_count);
DisconnectReason GetDisconnectReason() const;
Result Scan(std::vector<NetworkInfo>& networks, u16& count, const ScanFilter& filter);
Result SetAdvertiseData(std::span<const u8> data);
Result OpenAccessPoint();
Result CloseAccessPoint();
Result OpenStation();
Result CloseStation();
Result CreateNetwork(const SecurityConfig& security_config, const UserConfig& user_config,
const NetworkConfig& network_config);
Result DestroyNetwork();
Result Connect(const NetworkInfo& network_info_, const UserConfig& user_config,
u16 local_communication_version);
Result Disconnect();
Result Initialize(LanEventFunc lan_event_ = empty_func, bool listening = true);
Result Finalize();
void ReceivePacket(const Network::LDNPacket& packet);
protected:
friend class LanStation;
void InitNetworkInfo();
void InitNodeStateChange();
void ResetStations();
void UpdateNodes();
void OnSyncNetwork(const NetworkInfo& info);
void OnDisconnectFromHost();
void OnNetworkInfoChanged();
bool IsNodeStateChanged();
bool IsFlagSet(ScanFilterFlag flag, ScanFilterFlag search_flag) const;
int GetStationCount() const;
MacAddress GetFakeMac() const;
Result GetNodeInfo(NodeInfo& node, const UserConfig& user_config,
u16 local_communication_version);
Network::IPv4Address GetLocalIp() const;
template <typename Data>
void SendPacket(Network::LDNPacketType type, const Data& data, Ipv4Address remote_ip);
void SendPacket(Network::LDNPacketType type, Ipv4Address remote_ip);
template <typename Data>
void SendBroadcast(Network::LDNPacketType type, const Data& data);
void SendBroadcast(Network::LDNPacketType type);
void SendPacket(const Network::LDNPacket& packet);
static const LanEventFunc empty_func;
static constexpr Ssid fake_ssid{"YuzuFakeSsidForLdn"};
bool inited{};
std::mutex packet_mutex;
std::array<LanStation, StationCountMax> stations;
std::array<NodeLatestUpdate, NodeCountMax> node_changes{};
std::array<u8, NodeCountMax> node_last_states{};
std::unordered_map<MacAddress, NetworkInfo, MACAddressHash> scan_results{};
NodeInfo node_info{};
NetworkInfo network_info{};
State state{State::None};
DisconnectReason disconnect_reason{DisconnectReason::None};
// TODO (flTobi): Should this be an std::set?
std::vector<Ipv4Address> connected_clients;
std::optional<Ipv4Address> host_ip;
LanEventFunc lan_event;
Network::RoomNetwork& room_network;
};
} // namespace Service::LDN
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <array>
#include <cstring>
#include <functional>
#include <memory>
#include <mutex>
#include <optional>
#include <random>
#include <span>
#include <thread>
#include <unordered_map>
#include "common/logging/log.h"
#include "common/socket_types.h"
#include "core/hle/result.h"
#include "core/hle/service/ldn/ldn_results.h"
#include "core/hle/service/ldn/ldn_types.h"
#include "network/network.h"
namespace Service::LDN {
class LANDiscovery;
class LanStation {
public:
LanStation(s8 node_id_, LANDiscovery* discovery_);
~LanStation();
void OnClose();
NodeStatus GetStatus() const;
void Reset();
void OverrideInfo();
protected:
friend class LANDiscovery;
NodeInfo* node_info;
NodeStatus status;
s8 node_id;
LANDiscovery* discovery;
};
class LANDiscovery {
public:
using LanEventFunc = std::function<void()>;
LANDiscovery(Network::RoomNetwork& room_network_);
~LANDiscovery();
State GetState() const;
void SetState(State new_state);
Result GetNetworkInfo(NetworkInfo& out_network) const;
Result GetNetworkInfo(NetworkInfo& out_network, std::vector<NodeLatestUpdate>& out_updates,
std::size_t buffer_count);
DisconnectReason GetDisconnectReason() const;
Result Scan(std::vector<NetworkInfo>& networks, u16& count, const ScanFilter& filter);
Result SetAdvertiseData(std::span<const u8> data);
Result OpenAccessPoint();
Result CloseAccessPoint();
Result OpenStation();
Result CloseStation();
Result CreateNetwork(const SecurityConfig& security_config, const UserConfig& user_config,
const NetworkConfig& network_config);
Result DestroyNetwork();
Result Connect(const NetworkInfo& network_info_, const UserConfig& user_config,
u16 local_communication_version);
Result Disconnect();
Result Initialize(LanEventFunc lan_event_ = empty_func, bool listening = true);
Result Finalize();
void ReceivePacket(const Network::LDNPacket& packet);
protected:
friend class LanStation;
void InitNetworkInfo();
void InitNodeStateChange();
void ResetStations();
void UpdateNodes();
void OnSyncNetwork(const NetworkInfo& info);
void OnDisconnectFromHost();
void OnNetworkInfoChanged();
bool IsNodeStateChanged();
bool IsFlagSet(ScanFilterFlag flag, ScanFilterFlag search_flag) const;
int GetStationCount() const;
MacAddress GetFakeMac() const;
Result GetNodeInfo(NodeInfo& node, const UserConfig& user_config,
u16 local_communication_version);
Network::IPv4Address GetLocalIp() const;
template <typename Data>
void SendPacket(Network::LDNPacketType type, const Data& data, Ipv4Address remote_ip);
void SendPacket(Network::LDNPacketType type, Ipv4Address remote_ip);
template <typename Data>
void SendBroadcast(Network::LDNPacketType type, const Data& data);
void SendBroadcast(Network::LDNPacketType type);
void SendPacket(const Network::LDNPacket& packet);
static const LanEventFunc empty_func;
static constexpr Ssid fake_ssid{"YuzuFakeSsidForLdn"};
bool inited{};
std::mutex packet_mutex;
std::array<LanStation, StationCountMax> stations;
std::array<NodeLatestUpdate, NodeCountMax> node_changes{};
std::array<u8, NodeCountMax> node_last_states{};
std::unordered_map<MacAddress, NetworkInfo, MACAddressHash> scan_results{};
NodeInfo node_info{};
NetworkInfo network_info{};
State state{State::None};
DisconnectReason disconnect_reason{DisconnectReason::None};
// TODO (flTobi): Should this be an std::set?
std::vector<Ipv4Address> connected_clients;
std::optional<Ipv4Address> host_ip;
LanEventFunc lan_event;
Network::RoomNetwork& room_network;
};
} // namespace Service::LDN

File diff suppressed because it is too large Load Diff

View File

@@ -1,25 +1,25 @@
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/k_event.h"
#include "core/hle/result.h"
#include "core/hle/service/kernel_helpers.h"
#include "core/hle/service/sm/sm.h"
namespace Core {
class System;
}
namespace Service::SM {
class ServiceManager;
}
namespace Service::LDN {
/// Registers all LDN services with the specified service manager.
void InstallInterfaces(SM::ServiceManager& sm, Core::System& system);
} // namespace Service::LDN
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/k_event.h"
#include "core/hle/result.h"
#include "core/hle/service/kernel_helpers.h"
#include "core/hle/service/sm/sm.h"
namespace Core {
class System;
}
namespace Service::SM {
class ServiceManager;
}
namespace Service::LDN {
/// Registers all LDN services with the specified service manager.
void InstallInterfaces(SM::ServiceManager& sm, Core::System& system);
} // namespace Service::LDN

View File

@@ -1,27 +1,27 @@
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include "core/hle/result.h"
namespace Service::LDN {
constexpr Result ResultAdvertiseDataTooLarge{ErrorModule::LDN, 10};
constexpr Result ResultAuthenticationFailed{ErrorModule::LDN, 20};
constexpr Result ResultDisabled{ErrorModule::LDN, 22};
constexpr Result ResultAirplaneModeEnabled{ErrorModule::LDN, 23};
constexpr Result ResultInvalidNodeCount{ErrorModule::LDN, 30};
constexpr Result ResultConnectionFailed{ErrorModule::LDN, 31};
constexpr Result ResultBadState{ErrorModule::LDN, 32};
constexpr Result ResultNoIpAddress{ErrorModule::LDN, 33};
constexpr Result ResultInvalidBufferCount{ErrorModule::LDN, 50};
constexpr Result ResultAccessPointConnectionFailed{ErrorModule::LDN, 65};
constexpr Result ResultAuthenticationTimeout{ErrorModule::LDN, 66};
constexpr Result ResultMaximumNodeCount{ErrorModule::LDN, 67};
constexpr Result ResultBadInput{ErrorModule::LDN, 96};
constexpr Result ResultLocalCommunicationIdNotFound{ErrorModule::LDN, 97};
constexpr Result ResultLocalCommunicationVersionTooLow{ErrorModule::LDN, 113};
constexpr Result ResultLocalCommunicationVersionTooHigh{ErrorModule::LDN, 114};
} // namespace Service::LDN
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include "core/hle/result.h"
namespace Service::LDN {
constexpr Result ResultAdvertiseDataTooLarge{ErrorModule::LDN, 10};
constexpr Result ResultAuthenticationFailed{ErrorModule::LDN, 20};
constexpr Result ResultDisabled{ErrorModule::LDN, 22};
constexpr Result ResultAirplaneModeEnabled{ErrorModule::LDN, 23};
constexpr Result ResultInvalidNodeCount{ErrorModule::LDN, 30};
constexpr Result ResultConnectionFailed{ErrorModule::LDN, 31};
constexpr Result ResultBadState{ErrorModule::LDN, 32};
constexpr Result ResultNoIpAddress{ErrorModule::LDN, 33};
constexpr Result ResultInvalidBufferCount{ErrorModule::LDN, 50};
constexpr Result ResultAccessPointConnectionFailed{ErrorModule::LDN, 65};
constexpr Result ResultAuthenticationTimeout{ErrorModule::LDN, 66};
constexpr Result ResultMaximumNodeCount{ErrorModule::LDN, 67};
constexpr Result ResultBadInput{ErrorModule::LDN, 96};
constexpr Result ResultLocalCommunicationIdNotFound{ErrorModule::LDN, 97};
constexpr Result ResultLocalCommunicationVersionTooLow{ErrorModule::LDN, 113};
constexpr Result ResultLocalCommunicationVersionTooHigh{ErrorModule::LDN, 114};
} // namespace Service::LDN

View File

@@ -1,306 +1,306 @@
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include <fmt/format.h>
#include "common/common_funcs.h"
#include "common/common_types.h"
#include "network/network.h"
namespace Service::LDN {
constexpr size_t SsidLengthMax = 32;
constexpr size_t AdvertiseDataSizeMax = 384;
constexpr size_t UserNameBytesMax = 32;
constexpr int NodeCountMax = 8;
constexpr int StationCountMax = NodeCountMax - 1;
constexpr size_t PassphraseLengthMax = 64;
enum class SecurityMode : u16 {
All,
Retail,
Debug,
};
enum class NodeStateChange : u8 {
None,
Connect,
Disconnect,
DisconnectAndConnect,
};
DECLARE_ENUM_FLAG_OPERATORS(NodeStateChange)
enum class ScanFilterFlag : u32 {
None = 0,
LocalCommunicationId = 1 << 0,
SessionId = 1 << 1,
NetworkType = 1 << 2,
Ssid = 1 << 4,
SceneId = 1 << 5,
IntentId = LocalCommunicationId | SceneId,
NetworkId = IntentId | SessionId,
};
enum class NetworkType : u32 {
None,
General,
Ldn,
All,
};
enum class PackedNetworkType : u8 {
None,
General,
Ldn,
All,
};
enum class State : u32 {
None,
Initialized,
AccessPointOpened,
AccessPointCreated,
StationOpened,
StationConnected,
Error,
};
enum class DisconnectReason : s16 {
Unknown = -1,
None,
DisconnectedByUser,
DisconnectedBySystem,
DestroyedByUser,
DestroyedBySystem,
Rejected,
SignalLost,
};
enum class NetworkError {
Unknown = -1,
None = 0,
PortUnreachable,
TooManyPlayers,
VersionTooLow,
VersionTooHigh,
ConnectFailure,
ConnectNotFound,
ConnectTimeout,
ConnectRejected,
RejectFailed,
};
enum class AcceptPolicy : u8 {
AcceptAll,
RejectAll,
BlackList,
WhiteList,
};
enum class WifiChannel : s16 {
Default = 0,
Wifi24_1 = 1,
Wifi24_6 = 6,
Wifi24_11 = 11,
Wifi50_36 = 36,
Wifi50_40 = 40,
Wifi50_44 = 44,
Wifi50_48 = 48,
};
enum class LinkLevel : s8 {
Bad,
Low,
Good,
Excellent,
};
enum class NodeStatus : u8 {
Disconnected,
Connected,
};
struct NodeLatestUpdate {
NodeStateChange state_change;
INSERT_PADDING_BYTES(0x7); // Unknown
};
static_assert(sizeof(NodeLatestUpdate) == 0x8, "NodeLatestUpdate is an invalid size");
struct SessionId {
u64 high;
u64 low;
bool operator==(const SessionId&) const = default;
};
static_assert(sizeof(SessionId) == 0x10, "SessionId is an invalid size");
struct IntentId {
u64 local_communication_id;
INSERT_PADDING_BYTES(0x2); // Reserved
u16 scene_id;
INSERT_PADDING_BYTES(0x4); // Reserved
};
static_assert(sizeof(IntentId) == 0x10, "IntentId is an invalid size");
struct NetworkId {
IntentId intent_id;
SessionId session_id;
};
static_assert(sizeof(NetworkId) == 0x20, "NetworkId is an invalid size");
struct Ssid {
u8 length{};
std::array<char, SsidLengthMax + 1> raw{};
Ssid() = default;
constexpr explicit Ssid(std::string_view data) {
length = static_cast<u8>(std::min(data.size(), SsidLengthMax));
data.copy(raw.data(), length);
raw[length] = 0;
}
std::string GetStringValue() const {
return std::string(raw.data());
}
bool operator==(const Ssid& b) const {
return (length == b.length) && (std::memcmp(raw.data(), b.raw.data(), length) == 0);
}
bool operator!=(const Ssid& b) const {
return !operator==(b);
}
};
static_assert(sizeof(Ssid) == 0x22, "Ssid is an invalid size");
using Ipv4Address = std::array<u8, 4>;
static_assert(sizeof(Ipv4Address) == 0x4, "Ipv4Address is an invalid size");
struct MacAddress {
std::array<u8, 6> raw{};
friend bool operator==(const MacAddress& lhs, const MacAddress& rhs) = default;
};
static_assert(sizeof(MacAddress) == 0x6, "MacAddress is an invalid size");
struct MACAddressHash {
size_t operator()(const MacAddress& address) const {
u64 value{};
std::memcpy(&value, address.raw.data(), sizeof(address.raw));
return value;
}
};
struct ScanFilter {
NetworkId network_id;
NetworkType network_type;
MacAddress mac_address;
Ssid ssid;
INSERT_PADDING_BYTES(0x10);
ScanFilterFlag flag;
};
static_assert(sizeof(ScanFilter) == 0x60, "ScanFilter is an invalid size");
struct CommonNetworkInfo {
MacAddress bssid;
Ssid ssid;
WifiChannel channel;
LinkLevel link_level;
PackedNetworkType network_type;
INSERT_PADDING_BYTES(0x4);
};
static_assert(sizeof(CommonNetworkInfo) == 0x30, "CommonNetworkInfo is an invalid size");
struct NodeInfo {
Ipv4Address ipv4_address;
MacAddress mac_address;
s8 node_id;
u8 is_connected;
std::array<u8, UserNameBytesMax + 1> user_name;
INSERT_PADDING_BYTES(0x1); // Reserved
s16 local_communication_version;
INSERT_PADDING_BYTES(0x10); // Reserved
};
static_assert(sizeof(NodeInfo) == 0x40, "NodeInfo is an invalid size");
struct LdnNetworkInfo {
std::array<u8, 0x10> security_parameter;
SecurityMode security_mode;
AcceptPolicy station_accept_policy;
u8 has_action_frame;
INSERT_PADDING_BYTES(0x2); // Padding
u8 node_count_max;
u8 node_count;
std::array<NodeInfo, NodeCountMax> nodes;
INSERT_PADDING_BYTES(0x2); // Reserved
u16 advertise_data_size;
std::array<u8, AdvertiseDataSizeMax> advertise_data;
INSERT_PADDING_BYTES(0x8C); // Reserved
u64 random_authentication_id;
};
static_assert(sizeof(LdnNetworkInfo) == 0x430, "LdnNetworkInfo is an invalid size");
struct NetworkInfo {
NetworkId network_id;
CommonNetworkInfo common;
LdnNetworkInfo ldn;
};
static_assert(sizeof(NetworkInfo) == 0x480, "NetworkInfo is an invalid size");
struct SecurityConfig {
SecurityMode security_mode;
u16 passphrase_size;
std::array<u8, PassphraseLengthMax> passphrase;
};
static_assert(sizeof(SecurityConfig) == 0x44, "SecurityConfig is an invalid size");
struct UserConfig {
std::array<u8, UserNameBytesMax + 1> user_name;
INSERT_PADDING_BYTES(0xF); // Reserved
};
static_assert(sizeof(UserConfig) == 0x30, "UserConfig is an invalid size");
#pragma pack(push, 4)
struct ConnectRequest {
SecurityConfig security_config;
UserConfig user_config;
u32 local_communication_version;
u32 option_unknown;
NetworkInfo network_info;
};
static_assert(sizeof(ConnectRequest) == 0x4FC, "ConnectRequest is an invalid size");
#pragma pack(pop)
struct SecurityParameter {
std::array<u8, 0x10> data; // Data, used with the same key derivation as SecurityConfig
SessionId session_id;
};
static_assert(sizeof(SecurityParameter) == 0x20, "SecurityParameter is an invalid size");
struct NetworkConfig {
IntentId intent_id;
WifiChannel channel;
u8 node_count_max;
INSERT_PADDING_BYTES(0x1); // Reserved
u16 local_communication_version;
INSERT_PADDING_BYTES(0xA); // Reserved
};
static_assert(sizeof(NetworkConfig) == 0x20, "NetworkConfig is an invalid size");
struct AddressEntry {
Ipv4Address ipv4_address;
MacAddress mac_address;
INSERT_PADDING_BYTES(0x2); // Reserved
};
static_assert(sizeof(AddressEntry) == 0xC, "AddressEntry is an invalid size");
struct AddressList {
std::array<AddressEntry, 0x8> addresses;
};
static_assert(sizeof(AddressList) == 0x60, "AddressList is an invalid size");
} // namespace Service::LDN
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include <fmt/format.h>
#include "common/common_funcs.h"
#include "common/common_types.h"
#include "network/network.h"
namespace Service::LDN {
constexpr size_t SsidLengthMax = 32;
constexpr size_t AdvertiseDataSizeMax = 384;
constexpr size_t UserNameBytesMax = 32;
constexpr int NodeCountMax = 8;
constexpr int StationCountMax = NodeCountMax - 1;
constexpr size_t PassphraseLengthMax = 64;
enum class SecurityMode : u16 {
All,
Retail,
Debug,
};
enum class NodeStateChange : u8 {
None,
Connect,
Disconnect,
DisconnectAndConnect,
};
DECLARE_ENUM_FLAG_OPERATORS(NodeStateChange)
enum class ScanFilterFlag : u32 {
None = 0,
LocalCommunicationId = 1 << 0,
SessionId = 1 << 1,
NetworkType = 1 << 2,
Ssid = 1 << 4,
SceneId = 1 << 5,
IntentId = LocalCommunicationId | SceneId,
NetworkId = IntentId | SessionId,
};
enum class NetworkType : u32 {
None,
General,
Ldn,
All,
};
enum class PackedNetworkType : u8 {
None,
General,
Ldn,
All,
};
enum class State : u32 {
None,
Initialized,
AccessPointOpened,
AccessPointCreated,
StationOpened,
StationConnected,
Error,
};
enum class DisconnectReason : s16 {
Unknown = -1,
None,
DisconnectedByUser,
DisconnectedBySystem,
DestroyedByUser,
DestroyedBySystem,
Rejected,
SignalLost,
};
enum class NetworkError {
Unknown = -1,
None = 0,
PortUnreachable,
TooManyPlayers,
VersionTooLow,
VersionTooHigh,
ConnectFailure,
ConnectNotFound,
ConnectTimeout,
ConnectRejected,
RejectFailed,
};
enum class AcceptPolicy : u8 {
AcceptAll,
RejectAll,
BlackList,
WhiteList,
};
enum class WifiChannel : s16 {
Default = 0,
Wifi24_1 = 1,
Wifi24_6 = 6,
Wifi24_11 = 11,
Wifi50_36 = 36,
Wifi50_40 = 40,
Wifi50_44 = 44,
Wifi50_48 = 48,
};
enum class LinkLevel : s8 {
Bad,
Low,
Good,
Excellent,
};
enum class NodeStatus : u8 {
Disconnected,
Connected,
};
struct NodeLatestUpdate {
NodeStateChange state_change;
INSERT_PADDING_BYTES(0x7); // Unknown
};
static_assert(sizeof(NodeLatestUpdate) == 0x8, "NodeLatestUpdate is an invalid size");
struct SessionId {
u64 high;
u64 low;
bool operator==(const SessionId&) const = default;
};
static_assert(sizeof(SessionId) == 0x10, "SessionId is an invalid size");
struct IntentId {
u64 local_communication_id;
INSERT_PADDING_BYTES(0x2); // Reserved
u16 scene_id;
INSERT_PADDING_BYTES(0x4); // Reserved
};
static_assert(sizeof(IntentId) == 0x10, "IntentId is an invalid size");
struct NetworkId {
IntentId intent_id;
SessionId session_id;
};
static_assert(sizeof(NetworkId) == 0x20, "NetworkId is an invalid size");
struct Ssid {
u8 length{};
std::array<char, SsidLengthMax + 1> raw{};
Ssid() = default;
constexpr explicit Ssid(std::string_view data) {
length = static_cast<u8>(std::min(data.size(), SsidLengthMax));
data.copy(raw.data(), length);
raw[length] = 0;
}
std::string GetStringValue() const {
return std::string(raw.data());
}
bool operator==(const Ssid& b) const {
return (length == b.length) && (std::memcmp(raw.data(), b.raw.data(), length) == 0);
}
bool operator!=(const Ssid& b) const {
return !operator==(b);
}
};
static_assert(sizeof(Ssid) == 0x22, "Ssid is an invalid size");
using Ipv4Address = std::array<u8, 4>;
static_assert(sizeof(Ipv4Address) == 0x4, "Ipv4Address is an invalid size");
struct MacAddress {
std::array<u8, 6> raw{};
friend bool operator==(const MacAddress& lhs, const MacAddress& rhs) = default;
};
static_assert(sizeof(MacAddress) == 0x6, "MacAddress is an invalid size");
struct MACAddressHash {
size_t operator()(const MacAddress& address) const {
u64 value{};
std::memcpy(&value, address.raw.data(), sizeof(address.raw));
return value;
}
};
struct ScanFilter {
NetworkId network_id;
NetworkType network_type;
MacAddress mac_address;
Ssid ssid;
INSERT_PADDING_BYTES(0x10);
ScanFilterFlag flag;
};
static_assert(sizeof(ScanFilter) == 0x60, "ScanFilter is an invalid size");
struct CommonNetworkInfo {
MacAddress bssid;
Ssid ssid;
WifiChannel channel;
LinkLevel link_level;
PackedNetworkType network_type;
INSERT_PADDING_BYTES(0x4);
};
static_assert(sizeof(CommonNetworkInfo) == 0x30, "CommonNetworkInfo is an invalid size");
struct NodeInfo {
Ipv4Address ipv4_address;
MacAddress mac_address;
s8 node_id;
u8 is_connected;
std::array<u8, UserNameBytesMax + 1> user_name;
INSERT_PADDING_BYTES(0x1); // Reserved
s16 local_communication_version;
INSERT_PADDING_BYTES(0x10); // Reserved
};
static_assert(sizeof(NodeInfo) == 0x40, "NodeInfo is an invalid size");
struct LdnNetworkInfo {
std::array<u8, 0x10> security_parameter;
SecurityMode security_mode;
AcceptPolicy station_accept_policy;
u8 has_action_frame;
INSERT_PADDING_BYTES(0x2); // Padding
u8 node_count_max;
u8 node_count;
std::array<NodeInfo, NodeCountMax> nodes;
INSERT_PADDING_BYTES(0x2); // Reserved
u16 advertise_data_size;
std::array<u8, AdvertiseDataSizeMax> advertise_data;
INSERT_PADDING_BYTES(0x8C); // Reserved
u64 random_authentication_id;
};
static_assert(sizeof(LdnNetworkInfo) == 0x430, "LdnNetworkInfo is an invalid size");
struct NetworkInfo {
NetworkId network_id;
CommonNetworkInfo common;
LdnNetworkInfo ldn;
};
static_assert(sizeof(NetworkInfo) == 0x480, "NetworkInfo is an invalid size");
struct SecurityConfig {
SecurityMode security_mode;
u16 passphrase_size;
std::array<u8, PassphraseLengthMax> passphrase;
};
static_assert(sizeof(SecurityConfig) == 0x44, "SecurityConfig is an invalid size");
struct UserConfig {
std::array<u8, UserNameBytesMax + 1> user_name;
INSERT_PADDING_BYTES(0xF); // Reserved
};
static_assert(sizeof(UserConfig) == 0x30, "UserConfig is an invalid size");
#pragma pack(push, 4)
struct ConnectRequest {
SecurityConfig security_config;
UserConfig user_config;
u32 local_communication_version;
u32 option_unknown;
NetworkInfo network_info;
};
static_assert(sizeof(ConnectRequest) == 0x4FC, "ConnectRequest is an invalid size");
#pragma pack(pop)
struct SecurityParameter {
std::array<u8, 0x10> data; // Data, used with the same key derivation as SecurityConfig
SessionId session_id;
};
static_assert(sizeof(SecurityParameter) == 0x20, "SecurityParameter is an invalid size");
struct NetworkConfig {
IntentId intent_id;
WifiChannel channel;
u8 node_count_max;
INSERT_PADDING_BYTES(0x1); // Reserved
u16 local_communication_version;
INSERT_PADDING_BYTES(0xA); // Reserved
};
static_assert(sizeof(NetworkConfig) == 0x20, "NetworkConfig is an invalid size");
struct AddressEntry {
Ipv4Address ipv4_address;
MacAddress mac_address;
INSERT_PADDING_BYTES(0x2); // Reserved
};
static_assert(sizeof(AddressEntry) == 0xC, "AddressEntry is an invalid size");
struct AddressList {
std::array<AddressEntry, 0x8> addresses;
};
static_assert(sizeof(AddressList) == 0x60, "AddressList is an invalid size");
} // namespace Service::LDN