Merge pull request #4614 from wwylele/nwm-uds-global
NWM_UDS: move states into the class
This commit is contained in:
commit
8f2c35d7b6
|
@ -3,15 +3,7 @@
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <array>
|
|
||||||
#include <atomic>
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <list>
|
|
||||||
#include <map>
|
|
||||||
#include <mutex>
|
|
||||||
#include <unordered_map>
|
|
||||||
#include <vector>
|
|
||||||
#include <boost/optional.hpp>
|
|
||||||
#include <cryptopp/osrng.h>
|
#include <cryptopp/osrng.h>
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
|
@ -28,7 +20,6 @@
|
||||||
#include "core/hle/service/nwm/uds_connection.h"
|
#include "core/hle/service/nwm/uds_connection.h"
|
||||||
#include "core/hle/service/nwm/uds_data.h"
|
#include "core/hle/service/nwm/uds_data.h"
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
#include "network/network.h"
|
|
||||||
|
|
||||||
namespace Service::NWM {
|
namespace Service::NWM {
|
||||||
|
|
||||||
|
@ -39,87 +30,17 @@ enum {
|
||||||
};
|
};
|
||||||
} // namespace ErrCodes
|
} // namespace ErrCodes
|
||||||
|
|
||||||
// Event that is signaled every time the connection status changes.
|
|
||||||
static Kernel::SharedPtr<Kernel::Event> connection_status_event;
|
|
||||||
|
|
||||||
// Shared memory provided by the application to store the receive buffer.
|
|
||||||
// This is not currently used.
|
|
||||||
static Kernel::SharedPtr<Kernel::SharedMemory> recv_buffer_memory;
|
|
||||||
|
|
||||||
// Connection status of this 3DS.
|
|
||||||
static ConnectionStatus connection_status{};
|
|
||||||
|
|
||||||
static std::atomic<bool> initialized(false);
|
|
||||||
|
|
||||||
/* Node information about the current network.
|
|
||||||
* The amount of elements in this vector is always the maximum number
|
|
||||||
* of nodes specified in the network configuration.
|
|
||||||
* The first node is always the host.
|
|
||||||
*/
|
|
||||||
static NodeList node_info;
|
|
||||||
|
|
||||||
// Node information about our own system.
|
|
||||||
static NodeInfo current_node;
|
|
||||||
|
|
||||||
struct BindNodeData {
|
|
||||||
u32 bind_node_id; ///< Id of the bind node associated with this data.
|
|
||||||
u8 channel; ///< Channel that this bind node was bound to.
|
|
||||||
u16 network_node_id; ///< Node id this bind node is associated with, only packets from this
|
|
||||||
/// network node will be received.
|
|
||||||
Kernel::SharedPtr<Kernel::Event> event; ///< Receive event for this bind node.
|
|
||||||
std::deque<std::vector<u8>> received_packets; ///< List of packets received on this channel.
|
|
||||||
};
|
|
||||||
|
|
||||||
// Mapping of data channels to their internal data.
|
|
||||||
static std::unordered_map<u32, BindNodeData> channel_data;
|
|
||||||
|
|
||||||
// The WiFi network channel that the network is currently on.
|
|
||||||
// Since we're not actually interacting with physical radio waves, this is just a dummy value.
|
|
||||||
static u8 network_channel = DefaultNetworkChannel;
|
|
||||||
|
|
||||||
// Information about the network that we're currently connected to.
|
|
||||||
static NetworkInfo network_info;
|
|
||||||
|
|
||||||
// Mapping of mac addresses to their respective node_ids.
|
|
||||||
struct Node {
|
|
||||||
bool connected;
|
|
||||||
u16 node_id;
|
|
||||||
};
|
|
||||||
static std::map<MacAddress, Node> node_map;
|
|
||||||
|
|
||||||
// Event that will generate and send the 802.11 beacon frames.
|
|
||||||
static Core::TimingEventType* beacon_broadcast_event;
|
|
||||||
|
|
||||||
// Callback identifier for the OnWifiPacketReceived event.
|
|
||||||
static Network::RoomMember::CallbackHandle<Network::WifiPacket> wifi_packet_received;
|
|
||||||
|
|
||||||
// Mutex to synchronize access to the connection status between the emulation thread and the
|
|
||||||
// network thread.
|
|
||||||
static std::mutex connection_status_mutex;
|
|
||||||
|
|
||||||
static Kernel::SharedPtr<Kernel::Event> connection_event;
|
|
||||||
|
|
||||||
// Mutex to synchronize access to the list of received beacons between the emulation thread and the
|
|
||||||
// network thread.
|
|
||||||
static std::mutex beacon_mutex;
|
|
||||||
|
|
||||||
// Number of beacons to store before we start dropping the old ones.
|
// Number of beacons to store before we start dropping the old ones.
|
||||||
// TODO(Subv): Find a more accurate value for this limit.
|
// TODO(Subv): Find a more accurate value for this limit.
|
||||||
constexpr std::size_t MaxBeaconFrames = 15;
|
constexpr std::size_t MaxBeaconFrames = 15;
|
||||||
|
|
||||||
// List of the last <MaxBeaconFrames> beacons received from the network.
|
|
||||||
static std::list<Network::WifiPacket> received_beacons;
|
|
||||||
|
|
||||||
// Network node id used when a SecureData packet is addressed to every connected node.
|
// Network node id used when a SecureData packet is addressed to every connected node.
|
||||||
constexpr u16 BroadcastNetworkNodeId = 0xFFFF;
|
constexpr u16 BroadcastNetworkNodeId = 0xFFFF;
|
||||||
|
|
||||||
// The Host has always dest_node_id 1
|
// The Host has always dest_node_id 1
|
||||||
constexpr u16 HostDestNodeId = 1;
|
constexpr u16 HostDestNodeId = 1;
|
||||||
|
|
||||||
/**
|
std::list<Network::WifiPacket> NWM_UDS::GetReceivedBeacons(const MacAddress& sender) {
|
||||||
* Returns a list of received 802.11 beacon frames from the specified sender since the last call.
|
|
||||||
*/
|
|
||||||
std::list<Network::WifiPacket> GetReceivedBeacons(const MacAddress& sender) {
|
|
||||||
std::lock_guard<std::mutex> lock(beacon_mutex);
|
std::lock_guard<std::mutex> lock(beacon_mutex);
|
||||||
if (sender != Network::BroadcastMac) {
|
if (sender != Network::BroadcastMac) {
|
||||||
std::list<Network::WifiPacket> filtered_list;
|
std::list<Network::WifiPacket> filtered_list;
|
||||||
|
@ -149,11 +70,7 @@ void SendPacket(Network::WifiPacket& packet) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
u16 NWM_UDS::GetNextAvailableNodeId() {
|
||||||
* Returns an available index in the nodes array for the
|
|
||||||
* currently-hosted UDS network.
|
|
||||||
*/
|
|
||||||
static u16 GetNextAvailableNodeId() {
|
|
||||||
for (u16 index = 0; index < connection_status.max_nodes; ++index) {
|
for (u16 index = 0; index < connection_status.max_nodes; ++index) {
|
||||||
if ((connection_status.node_bitmask & (1 << index)) == 0)
|
if ((connection_status.node_bitmask & (1 << index)) == 0)
|
||||||
return index + 1;
|
return index + 1;
|
||||||
|
@ -163,7 +80,7 @@ static u16 GetNextAvailableNodeId() {
|
||||||
ASSERT_MSG(false, "No available connection slots in the network");
|
ASSERT_MSG(false, "No available connection slots in the network");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void BroadcastNodeMap() {
|
void NWM_UDS::BroadcastNodeMap() {
|
||||||
// Note: This is not how UDS on a 3ds does it but it shouldn't be
|
// Note: This is not how UDS on a 3ds does it but it shouldn't be
|
||||||
// necessary for citra
|
// necessary for citra
|
||||||
Network::WifiPacket packet;
|
Network::WifiPacket packet;
|
||||||
|
@ -189,7 +106,7 @@ static void BroadcastNodeMap() {
|
||||||
SendPacket(packet);
|
SendPacket(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void HandleNodeMapPacket(const Network::WifiPacket& packet) {
|
void NWM_UDS::HandleNodeMapPacket(const Network::WifiPacket& packet) {
|
||||||
std::lock_guard<std::mutex> lock(connection_status_mutex);
|
std::lock_guard<std::mutex> lock(connection_status_mutex);
|
||||||
if (connection_status.status == static_cast<u32>(NetworkStatus::ConnectedAsHost)) {
|
if (connection_status.status == static_cast<u32>(NetworkStatus::ConnectedAsHost)) {
|
||||||
LOG_DEBUG(Service_NWM, "Ignored NodeMapPacket since connection_status is host");
|
LOG_DEBUG(Service_NWM, "Ignored NodeMapPacket since connection_status is host");
|
||||||
|
@ -211,9 +128,7 @@ static void HandleNodeMapPacket(const Network::WifiPacket& packet) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inserts the received beacon frame in the beacon queue and removes any older beacons if the size
|
void NWM_UDS::HandleBeaconFrame(const Network::WifiPacket& packet) {
|
||||||
// limit is exceeded.
|
|
||||||
void HandleBeaconFrame(const Network::WifiPacket& packet) {
|
|
||||||
std::lock_guard<std::mutex> lock(beacon_mutex);
|
std::lock_guard<std::mutex> lock(beacon_mutex);
|
||||||
const auto unique_beacon =
|
const auto unique_beacon =
|
||||||
std::find_if(received_beacons.begin(), received_beacons.end(),
|
std::find_if(received_beacons.begin(), received_beacons.end(),
|
||||||
|
@ -232,7 +147,7 @@ void HandleBeaconFrame(const Network::WifiPacket& packet) {
|
||||||
received_beacons.pop_front();
|
received_beacons.pop_front();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleAssociationResponseFrame(const Network::WifiPacket& packet) {
|
void NWM_UDS::HandleAssociationResponseFrame(const Network::WifiPacket& packet) {
|
||||||
auto assoc_result = GetAssociationResult(packet.data);
|
auto assoc_result = GetAssociationResult(packet.data);
|
||||||
|
|
||||||
ASSERT_MSG(std::get<AssocStatus>(assoc_result) == AssocStatus::Successful,
|
ASSERT_MSG(std::get<AssocStatus>(assoc_result) == AssocStatus::Successful,
|
||||||
|
@ -259,7 +174,7 @@ void HandleAssociationResponseFrame(const Network::WifiPacket& packet) {
|
||||||
SendPacket(eapol_start);
|
SendPacket(eapol_start);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void HandleEAPoLPacket(const Network::WifiPacket& packet) {
|
void NWM_UDS::HandleEAPoLPacket(const Network::WifiPacket& packet) {
|
||||||
std::unique_lock<std::recursive_mutex> hle_lock(HLE::g_hle_lock, std::defer_lock);
|
std::unique_lock<std::recursive_mutex> hle_lock(HLE::g_hle_lock, std::defer_lock);
|
||||||
std::unique_lock<std::mutex> lock(connection_status_mutex, std::defer_lock);
|
std::unique_lock<std::mutex> lock(connection_status_mutex, std::defer_lock);
|
||||||
std::lock(hle_lock, lock);
|
std::lock(hle_lock, lock);
|
||||||
|
@ -378,7 +293,7 @@ static void HandleEAPoLPacket(const Network::WifiPacket& packet) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void HandleSecureDataPacket(const Network::WifiPacket& packet) {
|
void NWM_UDS::HandleSecureDataPacket(const Network::WifiPacket& packet) {
|
||||||
auto secure_data = ParseSecureDataHeader(packet.data);
|
auto secure_data = ParseSecureDataHeader(packet.data);
|
||||||
std::unique_lock<std::recursive_mutex> hle_lock(HLE::g_hle_lock, std::defer_lock);
|
std::unique_lock<std::recursive_mutex> hle_lock(HLE::g_hle_lock, std::defer_lock);
|
||||||
std::unique_lock<std::mutex> lock(connection_status_mutex, std::defer_lock);
|
std::unique_lock<std::mutex> lock(connection_status_mutex, std::defer_lock);
|
||||||
|
@ -439,11 +354,7 @@ static void HandleSecureDataPacket(const Network::WifiPacket& packet) {
|
||||||
channel_info->second.event->Signal();
|
channel_info->second.event->Signal();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
void NWM_UDS::StartConnectionSequence(const MacAddress& server) {
|
||||||
* Start a connection sequence with an UDS server. The sequence starts by sending an 802.11
|
|
||||||
* authentication frame with SEQ1.
|
|
||||||
*/
|
|
||||||
void StartConnectionSequence(const MacAddress& server) {
|
|
||||||
using Network::WifiPacket;
|
using Network::WifiPacket;
|
||||||
WifiPacket auth_request;
|
WifiPacket auth_request;
|
||||||
{
|
{
|
||||||
|
@ -462,8 +373,7 @@ void StartConnectionSequence(const MacAddress& server) {
|
||||||
SendPacket(auth_request);
|
SendPacket(auth_request);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sends an Association Response frame to the specified mac address
|
void NWM_UDS::SendAssociationResponseFrame(const MacAddress& address) {
|
||||||
void SendAssociationResponseFrame(const MacAddress& address) {
|
|
||||||
using Network::WifiPacket;
|
using Network::WifiPacket;
|
||||||
WifiPacket assoc_response;
|
WifiPacket assoc_response;
|
||||||
|
|
||||||
|
@ -488,13 +398,7 @@ void SendAssociationResponseFrame(const MacAddress& address) {
|
||||||
SendPacket(assoc_response);
|
SendPacket(assoc_response);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
void NWM_UDS::HandleAuthenticationFrame(const Network::WifiPacket& packet) {
|
||||||
* Handles the authentication request frame and sends the authentication response and association
|
|
||||||
* response frames. Once an Authentication frame with SEQ1 is received by the server, it responds
|
|
||||||
* with an Authentication frame containing SEQ2, and immediately sends an Association response frame
|
|
||||||
* containing the details of the access point and the assigned association id for the new client.
|
|
||||||
*/
|
|
||||||
void HandleAuthenticationFrame(const Network::WifiPacket& packet) {
|
|
||||||
// Only the SEQ1 auth frame is handled here, the SEQ2 frame doesn't need any special behavior
|
// Only the SEQ1 auth frame is handled here, the SEQ2 frame doesn't need any special behavior
|
||||||
if (GetAuthenticationSeqNumber(packet.data) == AuthenticationSeq::SEQ1) {
|
if (GetAuthenticationSeqNumber(packet.data) == AuthenticationSeq::SEQ1) {
|
||||||
using Network::WifiPacket;
|
using Network::WifiPacket;
|
||||||
|
@ -532,8 +436,7 @@ void HandleAuthenticationFrame(const Network::WifiPacket& packet) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handles the deauthentication frames sent from clients to hosts, when they leave a session
|
void NWM_UDS::HandleDeauthenticationFrame(const Network::WifiPacket& packet) {
|
||||||
void HandleDeauthenticationFrame(const Network::WifiPacket& packet) {
|
|
||||||
LOG_DEBUG(Service_NWM, "called");
|
LOG_DEBUG(Service_NWM, "called");
|
||||||
std::unique_lock<std::recursive_mutex> hle_lock(HLE::g_hle_lock, std::defer_lock);
|
std::unique_lock<std::recursive_mutex> hle_lock(HLE::g_hle_lock, std::defer_lock);
|
||||||
std::unique_lock<std::mutex> lock(connection_status_mutex, std::defer_lock);
|
std::unique_lock<std::mutex> lock(connection_status_mutex, std::defer_lock);
|
||||||
|
@ -573,7 +476,7 @@ void HandleDeauthenticationFrame(const Network::WifiPacket& packet) {
|
||||||
connection_status_event->Signal();
|
connection_status_event->Signal();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void HandleDataFrame(const Network::WifiPacket& packet) {
|
void NWM_UDS::HandleDataFrame(const Network::WifiPacket& packet) {
|
||||||
switch (GetFrameEtherType(packet.data)) {
|
switch (GetFrameEtherType(packet.data)) {
|
||||||
case EtherType::EAPoL:
|
case EtherType::EAPoL:
|
||||||
HandleEAPoLPacket(packet);
|
HandleEAPoLPacket(packet);
|
||||||
|
@ -585,7 +488,7 @@ static void HandleDataFrame(const Network::WifiPacket& packet) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Callback to parse and handle a received wifi packet.
|
/// Callback to parse and handle a received wifi packet.
|
||||||
void OnWifiPacketReceived(const Network::WifiPacket& packet) {
|
void NWM_UDS::OnWifiPacketReceived(const Network::WifiPacket& packet) {
|
||||||
switch (packet.type) {
|
switch (packet.type) {
|
||||||
case Network::WifiPacket::PacketType::Beacon:
|
case Network::WifiPacket::PacketType::Beacon:
|
||||||
HandleBeaconFrame(packet);
|
HandleBeaconFrame(packet);
|
||||||
|
@ -608,7 +511,7 @@ void OnWifiPacketReceived(const Network::WifiPacket& packet) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static boost::optional<Network::MacAddress> GetNodeMacAddress(u16 dest_node_id, u8 flags) {
|
boost::optional<Network::MacAddress> NWM_UDS::GetNodeMacAddress(u16 dest_node_id, u8 flags) {
|
||||||
constexpr u8 BroadcastFlag = 0x2;
|
constexpr u8 BroadcastFlag = 0x2;
|
||||||
if ((flags & BroadcastFlag) || dest_node_id == BroadcastNetworkNodeId) {
|
if ((flags & BroadcastFlag) || dest_node_id == BroadcastNetworkNodeId) {
|
||||||
// Broadcast
|
// Broadcast
|
||||||
|
@ -729,7 +632,8 @@ void NWM_UDS::InitializeWithVersion(Kernel::HLERequestContext& ctx) {
|
||||||
ASSERT_MSG(recv_buffer_memory->GetSize() == sharedmem_size, "Invalid shared memory size.");
|
ASSERT_MSG(recv_buffer_memory->GetSize() == sharedmem_size, "Invalid shared memory size.");
|
||||||
|
|
||||||
if (auto room_member = Network::GetRoomMember().lock()) {
|
if (auto room_member = Network::GetRoomMember().lock()) {
|
||||||
wifi_packet_received = room_member->BindOnWifiPacketReceived(OnWifiPacketReceived);
|
wifi_packet_received = room_member->BindOnWifiPacketReceived(
|
||||||
|
[this](const Network::WifiPacket& packet) { OnWifiPacketReceived(packet); });
|
||||||
} else {
|
} else {
|
||||||
LOG_ERROR(Service_NWM, "Network isn't initalized");
|
LOG_ERROR(Service_NWM, "Network isn't initalized");
|
||||||
}
|
}
|
||||||
|
@ -1417,18 +1321,6 @@ NWM_UDS::NWM_UDS(Core::System& system) : ServiceFramework("nwm::UDS"), system(sy
|
||||||
}
|
}
|
||||||
|
|
||||||
NWM_UDS::~NWM_UDS() {
|
NWM_UDS::~NWM_UDS() {
|
||||||
network_info = {};
|
|
||||||
channel_data.clear();
|
|
||||||
connection_status_event = nullptr;
|
|
||||||
recv_buffer_memory = nullptr;
|
|
||||||
initialized = false;
|
|
||||||
|
|
||||||
{
|
|
||||||
std::lock_guard<std::mutex> lock(connection_status_mutex);
|
|
||||||
connection_status = {};
|
|
||||||
connection_status.status = static_cast<u32>(NetworkStatus::NotConnected);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (auto room_member = Network::GetRoomMember().lock())
|
if (auto room_member = Network::GetRoomMember().lock())
|
||||||
room_member->Unbind(wifi_packet_received);
|
room_member->Unbind(wifi_packet_received);
|
||||||
|
|
||||||
|
|
|
@ -5,20 +5,36 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <atomic>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
#include <deque>
|
||||||
|
#include <list>
|
||||||
|
#include <map>
|
||||||
|
#include <mutex>
|
||||||
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <boost/optional.hpp>
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/swap.h"
|
#include "common/swap.h"
|
||||||
|
#include "core/hle/kernel/kernel.h"
|
||||||
#include "core/hle/service/service.h"
|
#include "core/hle/service/service.h"
|
||||||
|
#include "network/network.h"
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
class System;
|
class System;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace Kernel {
|
||||||
|
class Event;
|
||||||
|
class SharedMemory;
|
||||||
|
} // namespace Kernel
|
||||||
|
|
||||||
// Local-WLAN service
|
// Local-WLAN service
|
||||||
|
|
||||||
namespace Service::NWM {
|
namespace Service::NWM {
|
||||||
|
|
||||||
|
using MacAddress = std::array<u8, 6>;
|
||||||
|
|
||||||
const std::size_t ApplicationDataSize = 0xC8;
|
const std::size_t ApplicationDataSize = 0xC8;
|
||||||
const u8 DefaultNetworkChannel = 11;
|
const u8 DefaultNetworkChannel = 11;
|
||||||
|
|
||||||
|
@ -354,6 +370,121 @@ private:
|
||||||
void DecryptBeaconData(Kernel::HLERequestContext& ctx);
|
void DecryptBeaconData(Kernel::HLERequestContext& ctx);
|
||||||
|
|
||||||
void BeaconBroadcastCallback(u64 userdata, s64 cycles_late);
|
void BeaconBroadcastCallback(u64 userdata, s64 cycles_late);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of received 802.11 beacon frames from the specified sender since the last
|
||||||
|
* call.
|
||||||
|
*/
|
||||||
|
std::list<Network::WifiPacket> GetReceivedBeacons(const MacAddress& sender);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns an available index in the nodes array for the
|
||||||
|
* currently-hosted UDS network.
|
||||||
|
*/
|
||||||
|
u16 GetNextAvailableNodeId();
|
||||||
|
|
||||||
|
void BroadcastNodeMap();
|
||||||
|
void HandleNodeMapPacket(const Network::WifiPacket& packet);
|
||||||
|
void HandleBeaconFrame(const Network::WifiPacket& packet);
|
||||||
|
void HandleAssociationResponseFrame(const Network::WifiPacket& packet);
|
||||||
|
void HandleEAPoLPacket(const Network::WifiPacket& packet);
|
||||||
|
void HandleSecureDataPacket(const Network::WifiPacket& packet);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Start a connection sequence with an UDS server. The sequence starts by sending an 802.11
|
||||||
|
* authentication frame with SEQ1.
|
||||||
|
*/
|
||||||
|
void StartConnectionSequence(const MacAddress& server);
|
||||||
|
|
||||||
|
/// Sends an Association Response frame to the specified mac address
|
||||||
|
void SendAssociationResponseFrame(const MacAddress& address);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Handles the authentication request frame and sends the authentication response and
|
||||||
|
* association response frames. Once an Authentication frame with SEQ1 is received by the
|
||||||
|
* server, it responds with an Authentication frame containing SEQ2, and immediately sends an
|
||||||
|
* Association response frame containing the details of the access point and the assigned
|
||||||
|
* association id for the new client.
|
||||||
|
*/
|
||||||
|
void HandleAuthenticationFrame(const Network::WifiPacket& packet);
|
||||||
|
|
||||||
|
/// Handles the deauthentication frames sent from clients to hosts, when they leave a session
|
||||||
|
void HandleDeauthenticationFrame(const Network::WifiPacket& packet);
|
||||||
|
|
||||||
|
void HandleDataFrame(const Network::WifiPacket& packet);
|
||||||
|
|
||||||
|
/// Callback to parse and handle a received wifi packet.
|
||||||
|
void OnWifiPacketReceived(const Network::WifiPacket& packet);
|
||||||
|
|
||||||
|
boost::optional<Network::MacAddress> GetNodeMacAddress(u16 dest_node_id, u8 flags);
|
||||||
|
|
||||||
|
// Event that is signaled every time the connection status changes.
|
||||||
|
Kernel::SharedPtr<Kernel::Event> connection_status_event;
|
||||||
|
|
||||||
|
// Shared memory provided by the application to store the receive buffer.
|
||||||
|
// This is not currently used.
|
||||||
|
Kernel::SharedPtr<Kernel::SharedMemory> recv_buffer_memory;
|
||||||
|
|
||||||
|
// Connection status of this 3DS.
|
||||||
|
ConnectionStatus connection_status{};
|
||||||
|
|
||||||
|
std::atomic<bool> initialized{false};
|
||||||
|
|
||||||
|
/* Node information about the current network.
|
||||||
|
* The amount of elements in this vector is always the maximum number
|
||||||
|
* of nodes specified in the network configuration.
|
||||||
|
* The first node is always the host.
|
||||||
|
*/
|
||||||
|
NodeList node_info;
|
||||||
|
|
||||||
|
// Node information about our own system.
|
||||||
|
NodeInfo current_node;
|
||||||
|
|
||||||
|
struct BindNodeData {
|
||||||
|
u32 bind_node_id; ///< Id of the bind node associated with this data.
|
||||||
|
u8 channel; ///< Channel that this bind node was bound to.
|
||||||
|
u16 network_node_id; ///< Node id this bind node is associated with, only packets from this
|
||||||
|
/// network node will be received.
|
||||||
|
Kernel::SharedPtr<Kernel::Event> event; ///< Receive event for this bind node.
|
||||||
|
std::deque<std::vector<u8>> received_packets; ///< List of packets received on this channel.
|
||||||
|
};
|
||||||
|
|
||||||
|
// Mapping of data channels to their internal data.
|
||||||
|
std::unordered_map<u32, BindNodeData> channel_data;
|
||||||
|
|
||||||
|
// The WiFi network channel that the network is currently on.
|
||||||
|
// Since we're not actually interacting with physical radio waves, this is just a dummy value.
|
||||||
|
u8 network_channel = DefaultNetworkChannel;
|
||||||
|
|
||||||
|
// Information about the network that we're currently connected to.
|
||||||
|
NetworkInfo network_info;
|
||||||
|
|
||||||
|
// Mapping of mac addresses to their respective node_ids.
|
||||||
|
struct Node {
|
||||||
|
bool connected;
|
||||||
|
u16 node_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::map<MacAddress, Node> node_map;
|
||||||
|
|
||||||
|
// Event that will generate and send the 802.11 beacon frames.
|
||||||
|
Core::TimingEventType* beacon_broadcast_event;
|
||||||
|
|
||||||
|
// Callback identifier for the OnWifiPacketReceived event.
|
||||||
|
Network::RoomMember::CallbackHandle<Network::WifiPacket> wifi_packet_received;
|
||||||
|
|
||||||
|
// Mutex to synchronize access to the connection status between the emulation thread and the
|
||||||
|
// network thread.
|
||||||
|
std::mutex connection_status_mutex;
|
||||||
|
|
||||||
|
Kernel::SharedPtr<Kernel::Event> connection_event;
|
||||||
|
|
||||||
|
// Mutex to synchronize access to the list of received beacons between the emulation thread and
|
||||||
|
// the network thread.
|
||||||
|
std::mutex beacon_mutex;
|
||||||
|
|
||||||
|
// List of the last <MaxBeaconFrames> beacons received from the network.
|
||||||
|
std::list<Network::WifiPacket> received_beacons;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Service::NWM
|
} // namespace Service::NWM
|
||||||
|
|
Reference in New Issue