service/nwm_uds: Add NetworkStatusChangeReason (#5377)
fixes https://github.com/citra-emu/citra/issues/3975
This commit is contained in:
parent
06a9f69d88
commit
9d5ae8e1c2
@ -124,7 +124,7 @@ void NWM_UDS::BroadcastNodeMap() {
|
||||
|
||||
void NWM_UDS::HandleNodeMapPacket(const Network::WifiPacket& packet) {
|
||||
std::lock_guard lock(connection_status_mutex);
|
||||
if (connection_status.status == static_cast<u32>(NetworkStatus::ConnectedAsHost)) {
|
||||
if (connection_status.status == NetworkStatus::ConnectedAsHost) {
|
||||
LOG_DEBUG(Service_NWM, "Ignored NodeMapPacket since connection_status is host");
|
||||
return;
|
||||
}
|
||||
@ -170,10 +170,10 @@ void NWM_UDS::HandleAssociationResponseFrame(const Network::WifiPacket& packet)
|
||||
"Could not join network");
|
||||
{
|
||||
std::lock_guard lock(connection_status_mutex);
|
||||
if (connection_status.status != static_cast<u32>(NetworkStatus::Connecting)) {
|
||||
if (connection_status.status != NetworkStatus::Connecting) {
|
||||
LOG_DEBUG(Service_NWM,
|
||||
"Ignored AssociationResponseFrame because connection status is {}",
|
||||
connection_status.status);
|
||||
static_cast<u32>(connection_status.status));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -196,9 +196,9 @@ void NWM_UDS::HandleEAPoLPacket(const Network::WifiPacket& packet) {
|
||||
std::lock(hle_lock, lock);
|
||||
|
||||
if (GetEAPoLFrameType(packet.data) == EAPoLStartMagic) {
|
||||
if (connection_status.status != static_cast<u32>(NetworkStatus::ConnectedAsHost)) {
|
||||
if (connection_status.status != NetworkStatus::ConnectedAsHost) {
|
||||
LOG_DEBUG(Service_NWM, "Connection sequence aborted, because connection status is {}",
|
||||
connection_status.status);
|
||||
static_cast<u32>(connection_status.status));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -255,7 +255,7 @@ void NWM_UDS::HandleEAPoLPacket(const Network::WifiPacket& packet) {
|
||||
SendPacket(eapol_logoff);
|
||||
|
||||
connection_status_event->Signal();
|
||||
} else if (connection_status.status == static_cast<u32>(NetworkStatus::Connecting)) {
|
||||
} else if (connection_status.status == NetworkStatus::Connecting) {
|
||||
auto logoff = ParseEAPoLLogoffFrame(packet.data);
|
||||
|
||||
network_info.host_mac_address = packet.transmitter_address;
|
||||
@ -282,14 +282,14 @@ void NWM_UDS::HandleEAPoLPacket(const Network::WifiPacket& packet) {
|
||||
}
|
||||
|
||||
// We're now connected, signal the application
|
||||
connection_status.status = static_cast<u32>(NetworkStatus::ConnectedAsClient);
|
||||
connection_status.disconnect_reason = static_cast<u32>(DisconnectStatus::Connected);
|
||||
connection_status.status = NetworkStatus::ConnectedAsClient;
|
||||
connection_status.status_change_reason = NetworkStatusChangeReason::ConnectionEstablished;
|
||||
// Some games require ConnectToNetwork to block, for now it doesn't
|
||||
// If blocking is implemented this lock needs to be changed,
|
||||
// otherwise it might cause deadlocks
|
||||
connection_status_event->Signal();
|
||||
connection_event->Signal();
|
||||
} else if (connection_status.status == static_cast<u32>(NetworkStatus::ConnectedAsClient)) {
|
||||
} else if (connection_status.status == NetworkStatus::ConnectedAsClient) {
|
||||
// TODO(B3N30): Remove that section and send/receive a proper connection_status packet
|
||||
// On a 3ds this packet wouldn't be addressed to already connected clients
|
||||
// We use this information because in the current implementation the host
|
||||
@ -328,11 +328,11 @@ void NWM_UDS::HandleSecureDataPacket(const Network::WifiPacket& packet) {
|
||||
std::unique_lock lock(connection_status_mutex, std::defer_lock);
|
||||
std::lock(hle_lock, lock);
|
||||
|
||||
if (connection_status.status != static_cast<u32>(NetworkStatus::ConnectedAsHost) &&
|
||||
connection_status.status != static_cast<u32>(NetworkStatus::ConnectedAsClient)) {
|
||||
if (connection_status.status != NetworkStatus::ConnectedAsHost &&
|
||||
connection_status.status != NetworkStatus::ConnectedAsClient) {
|
||||
// TODO(B3N30): Handle spectators
|
||||
LOG_DEBUG(Service_NWM, "Ignored SecureDataPacket, because connection status is {}",
|
||||
connection_status.status);
|
||||
static_cast<u32>(connection_status.status));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -347,12 +347,12 @@ void NWM_UDS::HandleSecureDataPacket(const Network::WifiPacket& packet) {
|
||||
// However, we might have received this packet due to a broadcast from the host, in that
|
||||
// case just ignore it.
|
||||
if (packet.destination_address != Network::BroadcastMac &&
|
||||
connection_status.status != static_cast<u32>(NetworkStatus::ConnectedAsHost)) {
|
||||
connection_status.status != NetworkStatus::ConnectedAsHost) {
|
||||
LOG_ERROR(Service_NWM, "Received packet addressed to others but we're not a host");
|
||||
return;
|
||||
}
|
||||
|
||||
if (connection_status.status == static_cast<u32>(NetworkStatus::ConnectedAsHost) &&
|
||||
if (connection_status.status == NetworkStatus::ConnectedAsHost &&
|
||||
secure_data.dest_node_id != BroadcastNetworkNodeId) {
|
||||
// Broadcast the packet so the right receiver can get it.
|
||||
// TODO(B3N30): Is there a flag that makes this kind of routing be unicast instead of
|
||||
@ -390,7 +390,7 @@ void NWM_UDS::StartConnectionSequence(const MacAddress& server) {
|
||||
WifiPacket auth_request;
|
||||
{
|
||||
std::lock_guard lock(connection_status_mutex);
|
||||
connection_status.status = static_cast<u32>(NetworkStatus::Connecting);
|
||||
connection_status.status = NetworkStatus::Connecting;
|
||||
|
||||
// TODO(Subv): Handle timeout.
|
||||
|
||||
@ -410,9 +410,9 @@ void NWM_UDS::SendAssociationResponseFrame(const MacAddress& address) {
|
||||
|
||||
{
|
||||
std::lock_guard lock(connection_status_mutex);
|
||||
if (connection_status.status != static_cast<u32>(NetworkStatus::ConnectedAsHost)) {
|
||||
if (connection_status.status != NetworkStatus::ConnectedAsHost) {
|
||||
LOG_ERROR(Service_NWM, "Connection sequence aborted, because connection status is {}",
|
||||
connection_status.status);
|
||||
static_cast<u32>(connection_status.status));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -436,10 +436,10 @@ void NWM_UDS::HandleAuthenticationFrame(const Network::WifiPacket& packet) {
|
||||
WifiPacket auth_request;
|
||||
{
|
||||
std::lock_guard lock(connection_status_mutex);
|
||||
if (connection_status.status != static_cast<u32>(NetworkStatus::ConnectedAsHost)) {
|
||||
if (connection_status.status != NetworkStatus::ConnectedAsHost) {
|
||||
LOG_ERROR(Service_NWM,
|
||||
"Connection sequence aborted, because connection status is {}",
|
||||
connection_status.status);
|
||||
static_cast<u32>(connection_status.status));
|
||||
return;
|
||||
}
|
||||
if (node_map.find(packet.transmitter_address) != node_map.end()) {
|
||||
@ -472,7 +472,7 @@ void NWM_UDS::HandleDeauthenticationFrame(const Network::WifiPacket& packet) {
|
||||
std::unique_lock hle_lock(HLE::g_hle_lock, std::defer_lock);
|
||||
std::unique_lock lock(connection_status_mutex, std::defer_lock);
|
||||
std::lock(hle_lock, lock);
|
||||
if (connection_status.status != static_cast<u32>(NetworkStatus::ConnectedAsHost)) {
|
||||
if (connection_status.status != NetworkStatus::ConnectedAsHost) {
|
||||
LOG_ERROR(Service_NWM, "Got deauthentication frame but we are not the host");
|
||||
return;
|
||||
}
|
||||
@ -667,8 +667,7 @@ ResultVal<std::shared_ptr<Kernel::Event>> NWM_UDS::Initialize(
|
||||
// Reset the connection status, it contains all zeros after initialization,
|
||||
// except for the actual status value.
|
||||
connection_status = {};
|
||||
connection_status.disconnect_reason = static_cast<u32>(DisconnectStatus::NotConnected);
|
||||
connection_status.status = static_cast<u32>(NetworkStatus::NotConnected);
|
||||
connection_status.status = NetworkStatus::NotConnected;
|
||||
node_info.clear();
|
||||
node_info.push_back(current_node);
|
||||
channel_data.clear();
|
||||
@ -856,8 +855,8 @@ ResultCode NWM_UDS::BeginHostingNetwork(const u8* network_info_buffer,
|
||||
// The real UDS module throws a fatal error if this assert fails.
|
||||
ASSERT_MSG(network_info.max_nodes > 1, "Trying to host a network of only one member.");
|
||||
|
||||
connection_status.status = static_cast<u32>(NetworkStatus::ConnectedAsHost);
|
||||
connection_status.disconnect_reason = static_cast<u32>(DisconnectStatus::Connected);
|
||||
connection_status.status = NetworkStatus::ConnectedAsHost;
|
||||
connection_status.status_change_reason = NetworkStatusChangeReason::ConnectionEstablished;
|
||||
|
||||
// Ensure the application data size is less than the maximum value.
|
||||
ASSERT_MSG(network_info.application_data_size <= ApplicationDataSize,
|
||||
@ -965,7 +964,7 @@ void NWM_UDS::EjectClient(Kernel::HLERequestContext& ctx) {
|
||||
}
|
||||
|
||||
std::lock_guard lock(connection_status_mutex);
|
||||
if (connection_status.status != static_cast<u8>(NetworkStatus::ConnectedAsHost)) {
|
||||
if (connection_status.status != NetworkStatus::ConnectedAsHost) {
|
||||
// Only the host can kick people.
|
||||
rb.Push(ResultCode(ErrorDescription::NotAuthorized, ErrorModule::UDS,
|
||||
ErrorSummary::InvalidState, ErrorLevel::Usage));
|
||||
@ -1016,11 +1015,12 @@ void NWM_UDS::DestroyNetwork(Kernel::HLERequestContext& ctx) {
|
||||
|
||||
// Only a host can destroy
|
||||
std::lock_guard lock(connection_status_mutex);
|
||||
if (connection_status.status != static_cast<u8>(NetworkStatus::ConnectedAsHost)) {
|
||||
if (connection_status.status != NetworkStatus::ConnectedAsHost) {
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
||||
rb.Push(ResultCode(ErrCodes::WrongStatus, ErrorModule::UDS, ErrorSummary::InvalidState,
|
||||
ErrorLevel::Status));
|
||||
LOG_WARNING(Service_NWM, "called with status {}", connection_status.status);
|
||||
LOG_WARNING(Service_NWM, "called with status {}",
|
||||
static_cast<u32>(connection_status.status));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1028,7 +1028,7 @@ void NWM_UDS::DestroyNetwork(Kernel::HLERequestContext& ctx) {
|
||||
|
||||
u16_le tmp_node_id = connection_status.network_node_id;
|
||||
connection_status = {};
|
||||
connection_status.status = static_cast<u32>(NetworkStatus::NotConnected);
|
||||
connection_status.status = NetworkStatus::NotConnected;
|
||||
connection_status.network_node_id = tmp_node_id;
|
||||
node_map.clear();
|
||||
connection_status_event->Signal();
|
||||
@ -1053,11 +1053,11 @@ void NWM_UDS::DisconnectNetwork(Kernel::HLERequestContext& ctx) {
|
||||
WifiPacket deauth;
|
||||
{
|
||||
std::lock_guard lock(connection_status_mutex);
|
||||
if (connection_status.status == static_cast<u32>(NetworkStatus::ConnectedAsHost)) {
|
||||
if (connection_status.status == NetworkStatus::ConnectedAsHost) {
|
||||
// A real 3ds makes strange things here. We do the same
|
||||
u16_le tmp_node_id = connection_status.network_node_id;
|
||||
connection_status = {};
|
||||
connection_status.status = static_cast<u32>(NetworkStatus::ConnectedAsHost);
|
||||
connection_status.status = NetworkStatus::ConnectedAsHost;
|
||||
connection_status.network_node_id = tmp_node_id;
|
||||
node_map.clear();
|
||||
LOG_DEBUG(Service_NWM, "called as a host");
|
||||
@ -1067,7 +1067,7 @@ void NWM_UDS::DisconnectNetwork(Kernel::HLERequestContext& ctx) {
|
||||
}
|
||||
u16_le tmp_node_id = connection_status.network_node_id;
|
||||
connection_status = {};
|
||||
connection_status.status = static_cast<u32>(NetworkStatus::NotConnected);
|
||||
connection_status.status = NetworkStatus::NotConnected;
|
||||
connection_status.network_node_id = tmp_node_id;
|
||||
node_map.clear();
|
||||
connection_status_event->Signal();
|
||||
@ -1107,8 +1107,8 @@ void NWM_UDS::SendTo(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
||||
|
||||
std::lock_guard lock(connection_status_mutex);
|
||||
if (connection_status.status != static_cast<u32>(NetworkStatus::ConnectedAsClient) &&
|
||||
connection_status.status != static_cast<u32>(NetworkStatus::ConnectedAsHost)) {
|
||||
if (connection_status.status != NetworkStatus::ConnectedAsClient &&
|
||||
connection_status.status != NetworkStatus::ConnectedAsHost) {
|
||||
rb.Push(ResultCode(ErrorDescription::NotAuthorized, ErrorModule::UDS,
|
||||
ErrorSummary::InvalidState, ErrorLevel::Status));
|
||||
return;
|
||||
@ -1179,9 +1179,9 @@ void NWM_UDS::PullPacket(Kernel::HLERequestContext& ctx) {
|
||||
u32 buff_size = std::min<u32>(max_out_buff_size_aligned, 0x172) << 2;
|
||||
|
||||
std::lock_guard lock(connection_status_mutex);
|
||||
if (connection_status.status != static_cast<u32>(NetworkStatus::ConnectedAsHost) &&
|
||||
connection_status.status != static_cast<u32>(NetworkStatus::ConnectedAsClient) &&
|
||||
connection_status.status != static_cast<u32>(NetworkStatus::ConnectedAsSpectator)) {
|
||||
if (connection_status.status != NetworkStatus::ConnectedAsHost &&
|
||||
connection_status.status != NetworkStatus::ConnectedAsClient &&
|
||||
connection_status.status != NetworkStatus::ConnectedAsSpectator) {
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
||||
rb.Push(ResultCode(ErrorDescription::NotAuthorized, ErrorModule::UDS,
|
||||
ErrorSummary::InvalidState, ErrorLevel::Status));
|
||||
@ -1242,7 +1242,7 @@ void NWM_UDS::GetChannel(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(2, 0);
|
||||
|
||||
std::lock_guard lock(connection_status_mutex);
|
||||
bool is_connected = connection_status.status != static_cast<u32>(NetworkStatus::NotConnected);
|
||||
bool is_connected = connection_status.status != NetworkStatus::NotConnected;
|
||||
|
||||
u8 channel = is_connected ? network_channel : 0;
|
||||
|
||||
@ -1445,7 +1445,7 @@ void NWM_UDS::DecryptBeaconData(Kernel::HLERequestContext& ctx) {
|
||||
// Sends a 802.11 beacon frame with information about the current network.
|
||||
void NWM_UDS::BeaconBroadcastCallback(std::uintptr_t user_data, s64 cycles_late) {
|
||||
// Don't do anything if we're not actually hosting a network
|
||||
if (connection_status.status != static_cast<u32>(NetworkStatus::ConnectedAsHost))
|
||||
if (connection_status.status != NetworkStatus::ConnectedAsHost)
|
||||
return;
|
||||
|
||||
std::vector<u8> frame = GenerateBeaconFrame(network_info, node_info);
|
||||
|
@ -65,7 +65,7 @@ static_assert(sizeof(NodeInfo) == 40, "NodeInfo has incorrect size.");
|
||||
|
||||
using NodeList = std::vector<NodeInfo>;
|
||||
|
||||
enum class NetworkStatus {
|
||||
enum class NetworkStatus : u32 {
|
||||
NotConnected = 3,
|
||||
ConnectedAsHost = 6,
|
||||
Connecting = 7,
|
||||
@ -73,15 +73,15 @@ enum class NetworkStatus {
|
||||
ConnectedAsSpectator = 10,
|
||||
};
|
||||
|
||||
enum class DisconnectStatus {
|
||||
Connected = 1,
|
||||
NotConnected = 2,
|
||||
// TODO(B3N30): Figure out the other values
|
||||
enum class NetworkStatusChangeReason : u32 {
|
||||
None = 0,
|
||||
ConnectionEstablished = 1,
|
||||
ConnectionLost = 4,
|
||||
};
|
||||
|
||||
struct ConnectionStatus {
|
||||
u32_le status;
|
||||
u32_le disconnect_reason;
|
||||
enum_le<NetworkStatus> status;
|
||||
enum_le<NetworkStatusChangeReason> status_change_reason;
|
||||
u16_le network_node_id;
|
||||
u16_le changed_nodes;
|
||||
u16_le nodes[UDSMaxNodes];
|
||||
|
Loading…
Reference in New Issue
Block a user