mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	Merge pull request #4690 from wwylele/uds-deprecated
UDS: implement deprecated functions
This commit is contained in:
		
						commit
						2138db3d7d
					
				
					 2 changed files with 186 additions and 49 deletions
				
			
		|  | @ -615,20 +615,14 @@ void NWM_UDS::RecvBeaconBroadcastData(Kernel::HLERequestContext& ctx) { | |||
|               out_buffer_size, wlan_comm_id, id, unk1, unk2, cur_buffer_size); | ||||
| } | ||||
| 
 | ||||
| void NWM_UDS::InitializeWithVersion(Kernel::HLERequestContext& ctx) { | ||||
|     IPC::RequestParser rp(ctx, 0x1B, 12, 2); | ||||
| 
 | ||||
|     u32 sharedmem_size = rp.Pop<u32>(); | ||||
| 
 | ||||
|     // Update the node information with the data the game gave us.
 | ||||
|     rp.PopRaw(current_node); | ||||
| 
 | ||||
|     u16 version = rp.Pop<u16>(); | ||||
| 
 | ||||
|     recv_buffer_memory = rp.PopObject<Kernel::SharedMemory>(); | ||||
| ResultVal<Kernel::SharedPtr<Kernel::Event>> NWM_UDS::Initialize( | ||||
|     u32 sharedmem_size, const NodeInfo& node, u16 version, | ||||
|     Kernel::SharedPtr<Kernel::SharedMemory> sharedmem) { | ||||
| 
 | ||||
|     current_node = node; | ||||
|     initialized = true; | ||||
| 
 | ||||
|     recv_buffer_memory = std::move(sharedmem); | ||||
|     ASSERT_MSG(recv_buffer_memory->GetSize() == sharedmem_size, "Invalid shared memory size."); | ||||
| 
 | ||||
|     if (auto room_member = Network::GetRoomMember().lock()) { | ||||
|  | @ -650,14 +644,42 @@ void NWM_UDS::InitializeWithVersion(Kernel::HLERequestContext& ctx) { | |||
|         channel_data.clear(); | ||||
|     } | ||||
| 
 | ||||
|     return MakeResult(connection_status_event); | ||||
| } | ||||
| 
 | ||||
| void NWM_UDS::InitializeWithVersion(Kernel::HLERequestContext& ctx) { | ||||
|     IPC::RequestParser rp(ctx, 0x1B, 12, 2); | ||||
|     u32 sharedmem_size = rp.Pop<u32>(); | ||||
|     auto node = rp.PopRaw<NodeInfo>(); | ||||
|     u16 version = rp.Pop<u16>(); | ||||
|     auto sharedmem = rp.PopObject<Kernel::SharedMemory>(); | ||||
| 
 | ||||
|     auto result = Initialize(sharedmem_size, node, version, std::move(sharedmem)); | ||||
| 
 | ||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); | ||||
|     rb.Push(RESULT_SUCCESS); | ||||
|     rb.PushCopyObjects(connection_status_event); | ||||
|     rb.Push(result.Code()); | ||||
|     rb.PushCopyObjects(result.ValueOr(nullptr)); | ||||
| 
 | ||||
|     LOG_DEBUG(Service_NWM, "called sharedmem_size=0x{:08X}, version=0x{:08X}", sharedmem_size, | ||||
|               version); | ||||
| } | ||||
| 
 | ||||
| void NWM_UDS::InitializeDeprecated(Kernel::HLERequestContext& ctx) { | ||||
|     IPC::RequestParser rp(ctx, 0x01, 11, 2); | ||||
|     u32 sharedmem_size = rp.Pop<u32>(); | ||||
|     auto node = rp.PopRaw<NodeInfo>(); | ||||
|     auto sharedmem = rp.PopObject<Kernel::SharedMemory>(); | ||||
| 
 | ||||
|     // The deprecated version uses fixed 0x100 as the version
 | ||||
|     auto result = Initialize(sharedmem_size, node, 0x100, std::move(sharedmem)); | ||||
| 
 | ||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); | ||||
|     rb.Push(result.Code()); | ||||
|     rb.PushCopyObjects(result.ValueOr(nullptr)); | ||||
| 
 | ||||
|     LOG_DEBUG(Service_NWM, "called sharedmem_size=0x{:08X}", sharedmem_size); | ||||
| } | ||||
| 
 | ||||
| void NWM_UDS::GetConnectionStatus(Kernel::HLERequestContext& ctx) { | ||||
|     IPC::RequestParser rp(ctx, 0xB, 0, 0); | ||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(13, 0); | ||||
|  | @ -792,23 +814,14 @@ void NWM_UDS::Unbind(Kernel::HLERequestContext& ctx) { | |||
|     rb.Push<u32>(0); | ||||
| } | ||||
| 
 | ||||
| void NWM_UDS::BeginHostingNetwork(Kernel::HLERequestContext& ctx) { | ||||
|     IPC::RequestParser rp(ctx, 0x1D, 1, 4); | ||||
| 
 | ||||
|     const u32 passphrase_size = rp.Pop<u32>(); | ||||
| 
 | ||||
|     const std::vector<u8> network_info_buffer = rp.PopStaticBuffer(); | ||||
|     ASSERT(network_info_buffer.size() == sizeof(NetworkInfo)); | ||||
|     const std::vector<u8> passphrase = rp.PopStaticBuffer(); | ||||
|     ASSERT(passphrase.size() == passphrase_size); | ||||
| 
 | ||||
| ResultCode NWM_UDS::BeginHostingNetwork(const u8* network_info_buffer, | ||||
|                                         std::size_t network_info_size, std::vector<u8> passphrase) { | ||||
|     // TODO(Subv): Store the passphrase and verify it when attempting a connection.
 | ||||
| 
 | ||||
|     LOG_DEBUG(Service_NWM, "called"); | ||||
| 
 | ||||
|     { | ||||
|         std::lock_guard<std::mutex> lock(connection_status_mutex); | ||||
|         std::memcpy(&network_info, network_info_buffer.data(), sizeof(NetworkInfo)); | ||||
|         network_info = {}; | ||||
|         std::memcpy(&network_info, network_info_buffer, network_info_size); | ||||
| 
 | ||||
|         // 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."); | ||||
|  | @ -864,10 +877,45 @@ void NWM_UDS::BeginHostingNetwork(Kernel::HLERequestContext& ctx) { | |||
|     system.CoreTiming().ScheduleEvent(msToCycles(DefaultBeaconInterval * MillisecondsPerTU), | ||||
|                                       beacon_broadcast_event, 0); | ||||
| 
 | ||||
|     return RESULT_SUCCESS; | ||||
| } | ||||
| 
 | ||||
| void NWM_UDS::BeginHostingNetwork(Kernel::HLERequestContext& ctx) { | ||||
|     IPC::RequestParser rp(ctx, 0x1D, 1, 4); | ||||
| 
 | ||||
|     const u32 passphrase_size = rp.Pop<u32>(); | ||||
| 
 | ||||
|     const std::vector<u8> network_info_buffer = rp.PopStaticBuffer(); | ||||
|     ASSERT(network_info_buffer.size() == sizeof(NetworkInfo)); | ||||
|     std::vector<u8> passphrase = rp.PopStaticBuffer(); | ||||
|     ASSERT(passphrase.size() == passphrase_size); | ||||
| 
 | ||||
|     LOG_DEBUG(Service_NWM, "called"); | ||||
|     auto result = BeginHostingNetwork(network_info_buffer.data(), network_info_buffer.size(), | ||||
|                                       std::move(passphrase)); | ||||
|     LOG_DEBUG(Service_NWM, "An UDS network has been created."); | ||||
| 
 | ||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||
|     rb.Push(RESULT_SUCCESS); | ||||
|     rb.Push(result); | ||||
| } | ||||
| 
 | ||||
| void NWM_UDS::BeginHostingNetworkDeprecated(Kernel::HLERequestContext& ctx) { | ||||
|     IPC::RequestParser rp(ctx, 0x04, 0x10, 2); | ||||
|     // Real NWM module reads 0x108 bytes from the command buffer into the network info, where the
 | ||||
|     // last 0xCC bytes (application_data and size) are undefined values. Here we just read the first
 | ||||
|     // 0x3C defined bytes and zero application_data in BeginHostingNetwork.
 | ||||
|     const auto network_info_buffer = rp.PopRaw<std::array<u8, 0x3C>>(); | ||||
|     const u32 passphrase_size = rp.Pop<u32>(); | ||||
|     std::vector<u8> passphrase = rp.PopStaticBuffer(); | ||||
|     ASSERT(passphrase.size() == passphrase_size); | ||||
| 
 | ||||
|     LOG_DEBUG(Service_NWM, "called"); | ||||
|     auto result = BeginHostingNetwork(network_info_buffer.data(), network_info_buffer.size(), | ||||
|                                       std::move(passphrase)); | ||||
|     LOG_DEBUG(Service_NWM, "An UDS network has been created."); | ||||
| 
 | ||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||
|     rb.Push(result); | ||||
| } | ||||
| 
 | ||||
| void NWM_UDS::UpdateNetworkAttribute(Kernel::HLERequestContext& ctx) { | ||||
|  | @ -1117,18 +1165,11 @@ void NWM_UDS::GetChannel(Kernel::HLERequestContext& ctx) { | |||
|     LOG_DEBUG(Service_NWM, "called"); | ||||
| } | ||||
| 
 | ||||
| void NWM_UDS::ConnectToNetwork(Kernel::HLERequestContext& ctx) { | ||||
|     IPC::RequestParser rp(ctx, 0x1E, 2, 4); | ||||
| 
 | ||||
|     u8 connection_type = rp.Pop<u8>(); | ||||
|     u32 passphrase_size = rp.Pop<u32>(); | ||||
| 
 | ||||
|     const std::vector<u8> network_struct_buffer = rp.PopStaticBuffer(); | ||||
|     ASSERT(network_struct_buffer.size() == sizeof(NetworkInfo)); | ||||
| 
 | ||||
|     const std::vector<u8> passphrase = rp.PopStaticBuffer(); | ||||
| 
 | ||||
|     std::memcpy(&network_info, network_struct_buffer.data(), sizeof(network_info)); | ||||
| void NWM_UDS::ConnectToNetwork(Kernel::HLERequestContext& ctx, u16 command_id, | ||||
|                                const u8* network_info_buffer, std::size_t network_info_size, | ||||
|                                u8 connection_type, std::vector<u8> passphrase) { | ||||
|     network_info = {}; | ||||
|     std::memcpy(&network_info, network_info_buffer, network_info_size); | ||||
| 
 | ||||
|     // Start the connection sequence
 | ||||
|     StartConnectionSequence(network_info.host_mac_address); | ||||
|  | @ -1140,13 +1181,46 @@ void NWM_UDS::ConnectToNetwork(Kernel::HLERequestContext& ctx) { | |||
|     connection_event = ctx.SleepClientThread( | ||||
|         system.Kernel().GetThreadManager().GetCurrentThread(), "uds::ConnectToNetwork", | ||||
|         UDSConnectionTimeout, | ||||
|         [](Kernel::SharedPtr<Kernel::Thread> thread, Kernel::HLERequestContext& ctx, | ||||
|            Kernel::ThreadWakeupReason reason) { | ||||
|         [command_id](Kernel::SharedPtr<Kernel::Thread> thread, Kernel::HLERequestContext& ctx, | ||||
|                      Kernel::ThreadWakeupReason reason) { | ||||
|             // TODO(B3N30): Add error handling for host full and timeout
 | ||||
|             IPC::RequestBuilder rb(ctx, 0x1E, 1, 0); | ||||
|             IPC::RequestBuilder rb(ctx, command_id, 1, 0); | ||||
|             rb.Push(RESULT_SUCCESS); | ||||
|             LOG_DEBUG(Service_NWM, "connection sequence finished"); | ||||
|         }); | ||||
| } | ||||
| 
 | ||||
| void NWM_UDS::ConnectToNetwork(Kernel::HLERequestContext& ctx) { | ||||
|     IPC::RequestParser rp(ctx, 0x1E, 2, 4); | ||||
| 
 | ||||
|     u8 connection_type = rp.Pop<u8>(); | ||||
|     u32 passphrase_size = rp.Pop<u32>(); | ||||
| 
 | ||||
|     const std::vector<u8> network_info_buffer = rp.PopStaticBuffer(); | ||||
|     ASSERT(network_info_buffer.size() == sizeof(NetworkInfo)); | ||||
| 
 | ||||
|     std::vector<u8> passphrase = rp.PopStaticBuffer(); | ||||
| 
 | ||||
|     ConnectToNetwork(ctx, 0x1E, network_info_buffer.data(), network_info_buffer.size(), | ||||
|                      connection_type, std::move(passphrase)); | ||||
| 
 | ||||
|     LOG_DEBUG(Service_NWM, "called"); | ||||
| } | ||||
| 
 | ||||
| void NWM_UDS::ConnectToNetworkDeprecated(Kernel::HLERequestContext& ctx) { | ||||
|     IPC::RequestParser rp(ctx, 0x09, 0x11, 2); | ||||
| 
 | ||||
|     // Similar to BeginHostingNetworkDeprecated, we only read the first 0x3C bytes into the network
 | ||||
|     // info
 | ||||
|     const auto network_info_buffer = rp.PopRaw<std::array<u8, 0x3C>>(); | ||||
| 
 | ||||
|     u8 connection_type = rp.Pop<u8>(); | ||||
|     u32 passphrase_size = rp.Pop<u32>(); | ||||
| 
 | ||||
|     std::vector<u8> passphrase = rp.PopStaticBuffer(); | ||||
| 
 | ||||
|     ConnectToNetwork(ctx, 0x09, network_info_buffer.data(), network_info_buffer.size(), | ||||
|                      connection_type, std::move(passphrase)); | ||||
| 
 | ||||
|     LOG_DEBUG(Service_NWM, "called"); | ||||
| } | ||||
|  | @ -1175,8 +1249,8 @@ void NWM_UDS::SetApplicationData(Kernel::HLERequestContext& ctx) { | |||
|     rb.Push(RESULT_SUCCESS); | ||||
| } | ||||
| 
 | ||||
| void NWM_UDS::DecryptBeaconData(Kernel::HLERequestContext& ctx) { | ||||
|     IPC::RequestParser rp(ctx, 0x1F, 0, 6); | ||||
| void NWM_UDS::DecryptBeaconData(Kernel::HLERequestContext& ctx, u16 command_id) { | ||||
|     IPC::RequestParser rp(ctx, command_id, 0, 6); | ||||
| 
 | ||||
|     const std::vector<u8> network_struct_buffer = rp.PopStaticBuffer(); | ||||
|     ASSERT(network_struct_buffer.size() == sizeof(NetworkInfo)); | ||||
|  | @ -1241,6 +1315,11 @@ void NWM_UDS::DecryptBeaconData(Kernel::HLERequestContext& ctx) { | |||
|     rb.PushStaticBuffer(output_buffer, 0); | ||||
| } | ||||
| 
 | ||||
| template <u16 command_id> | ||||
| void NWM_UDS::DecryptBeaconData(Kernel::HLERequestContext& ctx) { | ||||
|     DecryptBeaconData(ctx, command_id); | ||||
| } | ||||
| 
 | ||||
| // Sends a 802.11 beacon frame with information about the current network.
 | ||||
| void NWM_UDS::BeaconBroadcastCallback(u64 userdata, s64 cycles_late) { | ||||
|     // Don't do anything if we're not actually hosting a network
 | ||||
|  | @ -1266,19 +1345,19 @@ void NWM_UDS::BeaconBroadcastCallback(u64 userdata, s64 cycles_late) { | |||
| 
 | ||||
| NWM_UDS::NWM_UDS(Core::System& system) : ServiceFramework("nwm::UDS"), system(system) { | ||||
|     static const FunctionInfo functions[] = { | ||||
|         {0x000102C2, nullptr, "Initialize (deprecated)"}, | ||||
|         {0x000102C2, &NWM_UDS::InitializeDeprecated, "Initialize (deprecated)"}, | ||||
|         {0x00020000, nullptr, "Scrap"}, | ||||
|         {0x00030000, &NWM_UDS::Shutdown, "Shutdown"}, | ||||
|         {0x00040402, nullptr, "CreateNetwork (deprecated)"}, | ||||
|         {0x00040402, &NWM_UDS::BeginHostingNetworkDeprecated, "BeginHostingNetwork (deprecated)"}, | ||||
|         {0x00050040, nullptr, "EjectClient"}, | ||||
|         {0x00060000, nullptr, "EjectSpectator"}, | ||||
|         {0x00070080, &NWM_UDS::UpdateNetworkAttribute, "UpdateNetworkAttribute"}, | ||||
|         {0x00080000, &NWM_UDS::DestroyNetwork, "DestroyNetwork"}, | ||||
|         {0x00090442, nullptr, "ConnectNetwork (deprecated)"}, | ||||
|         {0x00090442, &NWM_UDS::ConnectToNetworkDeprecated, "ConnectToNetwork (deprecated)"}, | ||||
|         {0x000A0000, &NWM_UDS::DisconnectNetwork, "DisconnectNetwork"}, | ||||
|         {0x000B0000, &NWM_UDS::GetConnectionStatus, "GetConnectionStatus"}, | ||||
|         {0x000D0040, &NWM_UDS::GetNodeInformation, "GetNodeInformation"}, | ||||
|         {0x000E0006, nullptr, "DecryptBeaconData (deprecated)"}, | ||||
|         {0x000E0006, &NWM_UDS::DecryptBeaconData<0x0E>, "DecryptBeaconData (deprecated)"}, | ||||
|         {0x000F0404, &NWM_UDS::RecvBeaconBroadcastData, "RecvBeaconBroadcastData"}, | ||||
|         {0x00100042, &NWM_UDS::SetApplicationData, "SetApplicationData"}, | ||||
|         {0x00110040, nullptr, "GetApplicationData"}, | ||||
|  | @ -1291,7 +1370,7 @@ NWM_UDS::NWM_UDS(Core::System& system) : ServiceFramework("nwm::UDS"), system(sy | |||
|         {0x001B0302, &NWM_UDS::InitializeWithVersion, "InitializeWithVersion"}, | ||||
|         {0x001D0044, &NWM_UDS::BeginHostingNetwork, "BeginHostingNetwork"}, | ||||
|         {0x001E0084, &NWM_UDS::ConnectToNetwork, "ConnectToNetwork"}, | ||||
|         {0x001F0006, &NWM_UDS::DecryptBeaconData, "DecryptBeaconData"}, | ||||
|         {0x001F0006, &NWM_UDS::DecryptBeaconData<0x1F>, "DecryptBeaconData"}, | ||||
|         {0x00200040, nullptr, "Flush"}, | ||||
|         {0x00210080, nullptr, "SetProbeResponseParam"}, | ||||
|         {0x00220402, nullptr, "ScanOnConnection"}, | ||||
|  |  | |||
|  | @ -320,6 +320,21 @@ private: | |||
|      */ | ||||
|     void InitializeWithVersion(Kernel::HLERequestContext& ctx); | ||||
| 
 | ||||
|     /**
 | ||||
|      * NWM_UDS::InitializeDeprecated service function | ||||
|      *  Inputs: | ||||
|      *      1 : Shared memory size | ||||
|      *   2-11 : Input NodeInfo Structure | ||||
|      *     13 : Value 0 | ||||
|      *     14 : Shared memory handle | ||||
|      *  Outputs: | ||||
|      *      0 : Return header | ||||
|      *      1 : Result of function, 0 on success, otherwise error code | ||||
|      *      2 : Value 0 | ||||
|      *      3 : Output event handle | ||||
|      */ | ||||
|     void InitializeDeprecated(Kernel::HLERequestContext& ctx); | ||||
| 
 | ||||
|     /**
 | ||||
|      * NWM_UDS::BeginHostingNetwork service function. | ||||
|      * Creates a network and starts broadcasting its presence. | ||||
|  | @ -333,6 +348,19 @@ private: | |||
|      */ | ||||
|     void BeginHostingNetwork(Kernel::HLERequestContext& ctx); | ||||
| 
 | ||||
|     /**
 | ||||
|      * NWM_UDS::BeginHostingNetworkDeprecated service function. | ||||
|      * Creates a network and starts broadcasting its presence. | ||||
|      *  Inputs: | ||||
|      *      1 - 15 : the NetworkInfo structure, excluding application data | ||||
|      *      16 : passphrase size | ||||
|      *      18 : VAddr of the passphrase. | ||||
|      *  Outputs: | ||||
|      *      0 : Return header | ||||
|      *      1 : Result of function, 0 on success, otherwise error code | ||||
|      */ | ||||
|     void BeginHostingNetworkDeprecated(Kernel::HLERequestContext& ctx); | ||||
| 
 | ||||
|     /**
 | ||||
|      * NWM_UDS::ConnectToNetwork service function. | ||||
|      * This connects to the specified network | ||||
|  | @ -350,6 +378,22 @@ private: | |||
|      */ | ||||
|     void ConnectToNetwork(Kernel::HLERequestContext& ctx); | ||||
| 
 | ||||
|     /**
 | ||||
|      * NWM_UDS::ConnectToNetwork Deprecatedservice function. | ||||
|      * This connects to the specified network | ||||
|      *  Inputs: | ||||
|      *      0 : Command header | ||||
|      *      1 - 15 : the NetworkInfo structure, excluding application data | ||||
|      *      16 : Connection type: 0x1 = Client, 0x2 = Spectator. | ||||
|      *      17 : Passphrase buffer size | ||||
|      *      18 : (PassphraseSize<<12) | 2 | ||||
|      *      19 : Input passphrase buffer ptr | ||||
|      *  Outputs: | ||||
|      *      0 : Return header | ||||
|      *      1 : Result of function, 0 on success, otherwise error code | ||||
|      */ | ||||
|     void ConnectToNetworkDeprecated(Kernel::HLERequestContext& ctx); | ||||
| 
 | ||||
|     /**
 | ||||
|      * NWM_UDS::DecryptBeaconData service function. | ||||
|      * Decrypts the encrypted data tags contained in the 802.11 beacons. | ||||
|  | @ -367,8 +411,22 @@ private: | |||
|      *      1 : Result of function, 0 on success, otherwise error code | ||||
|      *      2, 3: output buffer return descriptor & ptr | ||||
|      */ | ||||
|     void DecryptBeaconData(Kernel::HLERequestContext& ctx, u16 command_id); | ||||
| 
 | ||||
|     template <u16 command_id> | ||||
|     void DecryptBeaconData(Kernel::HLERequestContext& ctx); | ||||
| 
 | ||||
|     ResultVal<Kernel::SharedPtr<Kernel::Event>> Initialize( | ||||
|         u32 sharedmem_size, const NodeInfo& node, u16 version, | ||||
|         Kernel::SharedPtr<Kernel::SharedMemory> sharedmem); | ||||
| 
 | ||||
|     ResultCode BeginHostingNetwork(const u8* network_info_buffer, std::size_t network_info_size, | ||||
|                                    std::vector<u8> passphrase); | ||||
| 
 | ||||
|     void ConnectToNetwork(Kernel::HLERequestContext& ctx, u16 command_id, | ||||
|                           const u8* network_info_buffer, std::size_t network_info_size, | ||||
|                           u8 connection_type, std::vector<u8> passphrase); | ||||
| 
 | ||||
|     void BeaconBroadcastCallback(u64 userdata, s64 cycles_late); | ||||
| 
 | ||||
|     /**
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue