mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-11-03 23:28:48 +00:00 
			
		
		
		
	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
					
				
					 2 changed files with 73 additions and 2 deletions
				
			
		| 
						 | 
				
			
			@ -279,6 +279,7 @@ 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);
 | 
			
		||||
        // 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
 | 
			
		||||
| 
						 | 
				
			
			@ -648,6 +649,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);
 | 
			
		||||
        node_info.clear();
 | 
			
		||||
        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.");
 | 
			
		||||
 | 
			
		||||
        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.
 | 
			
		||||
        ASSERT_MSG(network_info.application_data_size <= ApplicationDataSize,
 | 
			
		||||
| 
						 | 
				
			
			@ -928,6 +931,57 @@ void NWM_UDS::BeginHostingNetworkDeprecated(Kernel::HLERequestContext& ctx) {
 | 
			
		|||
    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) {
 | 
			
		||||
    IPC::RequestParser rp(ctx, 0x07, 2, 0);
 | 
			
		||||
    rp.Skip(2, false);
 | 
			
		||||
| 
						 | 
				
			
			@ -1394,7 +1448,7 @@ NWM_UDS::NWM_UDS(Core::System& system) : ServiceFramework("nwm::UDS"), system(sy
 | 
			
		|||
        {0x00020000, nullptr, "Scrap"},
 | 
			
		||||
        {0x00030000, &NWM_UDS::Shutdown, "Shutdown"},
 | 
			
		||||
        {0x00040402, &NWM_UDS::BeginHostingNetworkDeprecated, "BeginHostingNetwork (deprecated)"},
 | 
			
		||||
        {0x00050040, nullptr, "EjectClient"},
 | 
			
		||||
        {0x00050040, &NWM_UDS::EjectClient, "EjectClient"},
 | 
			
		||||
        {0x00060000, nullptr, "EjectSpectator"},
 | 
			
		||||
        {0x00070080, &NWM_UDS::UpdateNetworkAttribute, "UpdateNetworkAttribute"},
 | 
			
		||||
        {0x00080000, &NWM_UDS::DestroyNetwork, "DestroyNetwork"},
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -73,9 +73,15 @@ enum class NetworkStatus {
 | 
			
		|||
    ConnectedAsSpectator = 10,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum class DisconnectStatus {
 | 
			
		||||
    Connected = 1,
 | 
			
		||||
    NotConnected = 2,
 | 
			
		||||
    // TODO(B3N30): Figure out the other values
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct ConnectionStatus {
 | 
			
		||||
    u32_le status;
 | 
			
		||||
    INSERT_PADDING_WORDS(1);
 | 
			
		||||
    u32_le disconnect_reason;
 | 
			
		||||
    u16_le network_node_id;
 | 
			
		||||
    u16_le changed_nodes;
 | 
			
		||||
    u16_le nodes[UDSMaxNodes];
 | 
			
		||||
| 
						 | 
				
			
			@ -409,6 +415,17 @@ private:
 | 
			
		|||
     */
 | 
			
		||||
    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.
 | 
			
		||||
     * Decrypts the encrypted data tags contained in the 802.11 beacons.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue