NWM_UDS: implement disconnect_reason and EjectClient (#5331)
* NWM_UDS: Stub disconnect_reason and EjectClient * addressed review comments * fix additional semicolon Co-authored-by: Valentin Vanelslande <vvanelslandedev@gmail.com> Co-authored-by: Valentin Vanelslande <vvanelslandedev@gmail.com>
This commit is contained in:
parent
e7671d93b2
commit
7325f58763
|
@ -279,6 +279,7 @@ void NWM_UDS::HandleEAPoLPacket(const Network::WifiPacket& packet) {
|
||||||
|
|
||||||
// We're now connected, signal the application
|
// We're now connected, signal the application
|
||||||
connection_status.status = static_cast<u32>(NetworkStatus::ConnectedAsClient);
|
connection_status.status = static_cast<u32>(NetworkStatus::ConnectedAsClient);
|
||||||
|
connection_status.disconnect_reason = static_cast<u32>(DisconnectStatus::Connected);
|
||||||
// Some games require ConnectToNetwork to block, for now it doesn't
|
// Some games require ConnectToNetwork to block, for now it doesn't
|
||||||
// If blocking is implemented this lock needs to be changed,
|
// If blocking is implemented this lock needs to be changed,
|
||||||
// otherwise it might cause deadlocks
|
// otherwise it might cause deadlocks
|
||||||
|
@ -648,6 +649,7 @@ ResultVal<std::shared_ptr<Kernel::Event>> NWM_UDS::Initialize(
|
||||||
// Reset the connection status, it contains all zeros after initialization,
|
// Reset the connection status, it contains all zeros after initialization,
|
||||||
// except for the actual status value.
|
// except for the actual status value.
|
||||||
connection_status = {};
|
connection_status = {};
|
||||||
|
connection_status.disconnect_reason = static_cast<u32>(DisconnectStatus::NotConnected);
|
||||||
connection_status.status = static_cast<u32>(NetworkStatus::NotConnected);
|
connection_status.status = static_cast<u32>(NetworkStatus::NotConnected);
|
||||||
node_info.clear();
|
node_info.clear();
|
||||||
node_info.push_back(current_node);
|
node_info.push_back(current_node);
|
||||||
|
@ -837,6 +839,7 @@ ResultCode NWM_UDS::BeginHostingNetwork(const u8* network_info_buffer,
|
||||||
ASSERT_MSG(network_info.max_nodes > 1, "Trying to host a network of only one member.");
|
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.status = static_cast<u32>(NetworkStatus::ConnectedAsHost);
|
||||||
|
connection_status.disconnect_reason = static_cast<u32>(DisconnectStatus::Connected);
|
||||||
|
|
||||||
// Ensure the application data size is less than the maximum value.
|
// Ensure the application data size is less than the maximum value.
|
||||||
ASSERT_MSG(network_info.application_data_size <= ApplicationDataSize,
|
ASSERT_MSG(network_info.application_data_size <= ApplicationDataSize,
|
||||||
|
@ -928,6 +931,57 @@ void NWM_UDS::BeginHostingNetworkDeprecated(Kernel::HLERequestContext& ctx) {
|
||||||
rb.Push(result);
|
rb.Push(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NWM_UDS::EjectClient(Kernel::HLERequestContext& ctx) {
|
||||||
|
IPC::RequestParser rp(ctx, 0x05, 1, 0);
|
||||||
|
const u16 network_node_id = rp.Pop<u16>();
|
||||||
|
|
||||||
|
LOG_WARNING(Service_NWM, "(stubbed) called");
|
||||||
|
|
||||||
|
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
||||||
|
|
||||||
|
// The host can not be kicked.
|
||||||
|
if (network_node_id == 1) {
|
||||||
|
rb.Push(ResultCode(ErrorDescription::NotAuthorized, ErrorModule::UDS,
|
||||||
|
ErrorSummary::WrongArgument, ErrorLevel::Usage));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::lock_guard lock(connection_status_mutex);
|
||||||
|
if (connection_status.status != static_cast<u8>(NetworkStatus::ConnectedAsHost)) {
|
||||||
|
// Only the host can kick people.
|
||||||
|
rb.Push(ResultCode(ErrorDescription::NotAuthorized, ErrorModule::UDS,
|
||||||
|
ErrorSummary::InvalidState, ErrorLevel::Usage));
|
||||||
|
LOG_WARNING(Service_NWM, "called with status {}", connection_status.status);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function always returns success if the status is valid.
|
||||||
|
rb.Push(RESULT_SUCCESS);
|
||||||
|
|
||||||
|
using Network::WifiPacket;
|
||||||
|
Network::MacAddress dest_address = Network::BroadcastMac;
|
||||||
|
|
||||||
|
if (network_node_id != BroadcastNetworkNodeId) {
|
||||||
|
auto address = GetNodeMacAddress(network_node_id, 0);
|
||||||
|
|
||||||
|
if (!address) {
|
||||||
|
// There is no error if the network node id was not found.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
dest_address = *address;
|
||||||
|
}
|
||||||
|
|
||||||
|
WifiPacket deauth;
|
||||||
|
deauth.channel = network_channel;
|
||||||
|
deauth.destination_address = dest_address;
|
||||||
|
deauth.type = WifiPacket::PacketType::Deauthentication;
|
||||||
|
SendPacket(deauth);
|
||||||
|
if (network_node_id == BroadcastNetworkNodeId) {
|
||||||
|
SendPacket(deauth);
|
||||||
|
SendPacket(deauth);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void NWM_UDS::UpdateNetworkAttribute(Kernel::HLERequestContext& ctx) {
|
void NWM_UDS::UpdateNetworkAttribute(Kernel::HLERequestContext& ctx) {
|
||||||
IPC::RequestParser rp(ctx, 0x07, 2, 0);
|
IPC::RequestParser rp(ctx, 0x07, 2, 0);
|
||||||
rp.Skip(2, false);
|
rp.Skip(2, false);
|
||||||
|
@ -1394,7 +1448,7 @@ NWM_UDS::NWM_UDS(Core::System& system) : ServiceFramework("nwm::UDS"), system(sy
|
||||||
{0x00020000, nullptr, "Scrap"},
|
{0x00020000, nullptr, "Scrap"},
|
||||||
{0x00030000, &NWM_UDS::Shutdown, "Shutdown"},
|
{0x00030000, &NWM_UDS::Shutdown, "Shutdown"},
|
||||||
{0x00040402, &NWM_UDS::BeginHostingNetworkDeprecated, "BeginHostingNetwork (deprecated)"},
|
{0x00040402, &NWM_UDS::BeginHostingNetworkDeprecated, "BeginHostingNetwork (deprecated)"},
|
||||||
{0x00050040, nullptr, "EjectClient"},
|
{0x00050040, &NWM_UDS::EjectClient, "EjectClient"},
|
||||||
{0x00060000, nullptr, "EjectSpectator"},
|
{0x00060000, nullptr, "EjectSpectator"},
|
||||||
{0x00070080, &NWM_UDS::UpdateNetworkAttribute, "UpdateNetworkAttribute"},
|
{0x00070080, &NWM_UDS::UpdateNetworkAttribute, "UpdateNetworkAttribute"},
|
||||||
{0x00080000, &NWM_UDS::DestroyNetwork, "DestroyNetwork"},
|
{0x00080000, &NWM_UDS::DestroyNetwork, "DestroyNetwork"},
|
||||||
|
|
|
@ -73,9 +73,15 @@ enum class NetworkStatus {
|
||||||
ConnectedAsSpectator = 10,
|
ConnectedAsSpectator = 10,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class DisconnectStatus {
|
||||||
|
Connected = 1,
|
||||||
|
NotConnected = 2,
|
||||||
|
// TODO(B3N30): Figure out the other values
|
||||||
|
};
|
||||||
|
|
||||||
struct ConnectionStatus {
|
struct ConnectionStatus {
|
||||||
u32_le status;
|
u32_le status;
|
||||||
INSERT_PADDING_WORDS(1);
|
u32_le disconnect_reason;
|
||||||
u16_le network_node_id;
|
u16_le network_node_id;
|
||||||
u16_le changed_nodes;
|
u16_le changed_nodes;
|
||||||
u16_le nodes[UDSMaxNodes];
|
u16_le nodes[UDSMaxNodes];
|
||||||
|
@ -409,6 +415,17 @@ private:
|
||||||
*/
|
*/
|
||||||
void ConnectToNetworkDeprecated(Kernel::HLERequestContext& ctx);
|
void ConnectToNetworkDeprecated(Kernel::HLERequestContext& ctx);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* NWM_UDS::EjectClient Disconnects clients.
|
||||||
|
* Inputs:
|
||||||
|
* 0 : Command header
|
||||||
|
* 1 : Network node id
|
||||||
|
* Outputs:
|
||||||
|
* 0 : Return header
|
||||||
|
* 1 : Result of function, 0 on success, otherwise error code
|
||||||
|
*/
|
||||||
|
void EjectClient(Kernel::HLERequestContext& ctx);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NWM_UDS::DecryptBeaconData service function.
|
* NWM_UDS::DecryptBeaconData service function.
|
||||||
* Decrypts the encrypted data tags contained in the 802.11 beacons.
|
* Decrypts the encrypted data tags contained in the 802.11 beacons.
|
||||||
|
|
Reference in New Issue