From f29a9ac3c10b767f965dd924b2918646611d914f Mon Sep 17 00:00:00 2001 From: B3n30 Date: Tue, 31 Oct 2017 13:19:51 +0100 Subject: [PATCH 01/11] UDS: Add coonnect and disconnect --- src/core/hle/service/nwm/nwm_uds.cpp | 249 +++++++++++++++++++++------ 1 file changed, 200 insertions(+), 49 deletions(-) diff --git a/src/core/hle/service/nwm/nwm_uds.cpp b/src/core/hle/service/nwm/nwm_uds.cpp index 8cd2fe04b3..bcffae4ae6 100644 --- a/src/core/hle/service/nwm/nwm_uds.cpp +++ b/src/core/hle/service/nwm/nwm_uds.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -75,13 +76,22 @@ 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. +static std::map node_map; + // Event that will generate and send the 802.11 beacon frames. static CoreTiming::EventType* beacon_broadcast_event; +// Callback identifier for the OnWifiPacketReceived event. +static Network::RoomMember::CallbackHandle 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; +// token for the blocking ConnectToNetwork +static ThreadContinuationToken connection_token; + // Mutex to synchronize access to the list of received beacons between the emulation thread and the // network thread. static std::mutex beacon_mutex; @@ -119,7 +129,12 @@ std::list GetReceivedBeacons(const MacAddress& sender) { /// Sends a WifiPacket to the room we're currently connected to. void SendPacket(Network::WifiPacket& packet) { - // TODO(Subv): Implement. + if (auto room_member = Network::GetRoomMember().lock()) { + if (room_member->GetState() == Network::RoomMember::State::Joined) { + packet.transmitter_address = room_member->GetMacAddress(); + room_member->SendWifiPacket(packet); + } + } } /* @@ -214,6 +229,8 @@ static void HandleEAPoLPacket(const Network::WifiPacket& packet) { network_info.total_nodes++; + node_map[packet.transmitter_address] = node_id; + // Send the EAPoL-Logoff packet. using Network::WifiPacket; WifiPacket eapol_logoff; @@ -237,6 +254,7 @@ static void HandleEAPoLPacket(const Network::WifiPacket& packet) { } auto logoff = ParseEAPoLLogoffFrame(packet.data); + network_info.host_mac_address = packet.transmitter_address; network_info.total_nodes = logoff.connected_nodes; network_info.max_nodes = logoff.max_nodes; @@ -260,6 +278,9 @@ static void HandleEAPoLPacket(const Network::WifiPacket& packet) { // If blocking is implemented this lock needs to be changed, // otherwise it might cause deadlocks connection_status_event->Signal(); + if (connection_token.IsValid()) { + ContinueClientThread(connection_token); + } } } @@ -397,6 +418,36 @@ 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) { + LOG_DEBUG(Service_NWM, "called"); + 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(NetworkStatus::ConnectedAsHost)) { + LOG_ERROR(Service_NWM, "Got deauthentication frame but we are not the host"); + return; + } + if (node_map.find(packet.transmitter_address) == node_map.end()) { + LOG_ERROR(Service_NWM, "Got deauthentication frame from unknown node"); + return; + } + + u16 node_id = node_map[packet.transmitter_address]; + auto node = std::find_if(node_info.begin(), node_info.end(), [&node_id](const NodeInfo& info) { + return info.network_node_id == node_id + 1; + }); + ASSERT(node != node_info.end()); + + connection_status.node_bitmask &= ~(1 << node_id); + connection_status.changed_nodes |= 1 << node_id; + connection_status.total_nodes--; + + network_info.total_nodes--; + node_info.erase(node); + connection_status_event->Signal(); +} + static void HandleDataFrame(const Network::WifiPacket& packet) { switch (GetFrameEtherType(packet.data)) { case EtherType::EAPoL: @@ -423,6 +474,9 @@ void OnWifiPacketReceived(const Network::WifiPacket& packet) { case Network::WifiPacket::PacketType::Data: HandleDataFrame(packet); break; + case Network::WifiPacket::PacketType::Deauthentication: + HandleDeauthenticationFrame(packet); + break; } } @@ -435,13 +489,22 @@ void OnWifiPacketReceived(const Network::WifiPacket& packet) { * 1 : Result of function, 0 on success, otherwise error code */ static void Shutdown(Interface* self) { - u32* cmd_buff = Kernel::GetCommandBuffer(); + IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x03, 0, 0); - // TODO(purpasmart): Verify return header on HW + if (auto room_member = Network::GetRoomMember().lock()) + room_member->Unbind(wifi_packet_received); - cmd_buff[1] = RESULT_SUCCESS.raw; + // TODO(B3N30): Check on HW if Shutdown signals those events + for (auto bind_node : channel_data) { + bind_node.second.event->Signal(); + } + channel_data.clear(); - LOG_WARNING(Service_NWM, "(STUBBED) called"); + recv_buffer_memory.reset(); + + IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); + rb.Push(RESULT_SUCCESS); + LOG_DEBUG(Service_NWM, "called"); } /** @@ -494,7 +557,6 @@ static void RecvBeaconBroadcastData(Interface* self) { Memory::WriteBlock(current_buffer_pos, &data_reply_header, sizeof(BeaconDataReplyHeader)); current_buffer_pos += sizeof(BeaconDataReplyHeader); - // Write each of the received beacons into the buffer for (const auto& beacon : beacons) { BeaconEntryHeader entry{}; @@ -560,6 +622,16 @@ static void InitializeWithVersion(Interface* self) { ASSERT_MSG(recv_buffer_memory->size == sharedmem_size, "Invalid shared memory size."); + if (auto room_member = Network::GetRoomMember().lock()) { + wifi_packet_received = room_member->BindOnWifiPacketReceived(OnWifiPacketReceived); + } else { + LOG_ERROR(Service_NWM, "Network isn't initalized"); + IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); + // TODO(B3N30): Find the correct error code and return it; + rb.Push(-1); + return; + } + { std::lock_guard lock(connection_status_mutex); @@ -567,15 +639,14 @@ static void InitializeWithVersion(Interface* self) { // except for the actual status value. connection_status = {}; connection_status.status = static_cast(NetworkStatus::NotConnected); + node_info.clear(); + node_info.push_back(NodeInfo{}); } IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); rb.Push(RESULT_SUCCESS); rb.PushCopyHandles(Kernel::g_handle_table.Create(connection_status_event).Unwrap()); - // TODO(Subv): Connect the OnWifiPacketReceived function to the wifi packet received callback of - // the room we're currently in. - LOG_DEBUG(Service_NWM, "called sharedmem_size=0x%08X, version=0x%08X, sharedmem_handle=0x%08X", sharedmem_size, version, sharedmem_handle); } @@ -857,26 +928,79 @@ static void BeginHostingNetwork(Interface* self) { static void DestroyNetwork(Interface* self) { IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x08, 0, 0); - // TODO(Subv): Find out what happens if this is called while - // no network is being hosted. - // Unschedule the beacon broadcast event. CoreTiming::UnscheduleEvent(beacon_broadcast_event, 0); - { - std::lock_guard lock(connection_status_mutex); - - // TODO(Subv): Check if connection_status is indeed reset after this call. - connection_status = {}; - connection_status.status = static_cast(NetworkStatus::NotConnected); + // Only a host can destroy + std::lock_guard lock(connection_status_mutex); + if (connection_status.status != static_cast(NetworkStatus::ConnectedAsHost)) { + IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); + rb.Push(RESULT_SUCCESS); + LOG_WARNING(Service_NWM, "called with status %u", connection_status.status); + return; } + + // TODO(B3N30): Send 3 Deauth packets + + u16_le tmp_node_id = connection_status.network_node_id; + connection_status = {}; + connection_status.status = static_cast(NetworkStatus::NotConnected); + connection_status.network_node_id = tmp_node_id; connection_status_event->Signal(); IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); + // TODO(B3N30): HW test if events get signaled here. + for (auto bind_node : channel_data) { + bind_node.second.event->Signal(); + } + channel_data.clear(); + rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_NWM, "called"); + LOG_DEBUG(Service_NWM, "called"); +} + +static void DisconnectNetwork(Interface* self) { + IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0xA, 0, 0); + IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); + rb.Push(RESULT_SUCCESS); + + using Network::WifiPacket; + WifiPacket deauth; + { + std::lock_guard lock(connection_status_mutex); + if (connection_status.status == static_cast(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(NetworkStatus::ConnectedAsHost); + connection_status.network_node_id = tmp_node_id; + LOG_DEBUG(Service_NWM, "called as a host"); + return; + } + u16_le tmp_node_id = connection_status.network_node_id; + connection_status = {}; + connection_status.status = static_cast(NetworkStatus::NotConnected); + connection_status.network_node_id = tmp_node_id; + connection_status_event->Signal(); + + deauth.channel = network_channel; + // TODO(B3N30): Add disconnect reason + deauth.data = {}; + deauth.destination_address = network_info.host_mac_address; + deauth.type = WifiPacket::PacketType::Deauthentication; + } + + SendPacket(deauth); + + // TODO(B3N30): Check on HW if Shutdown signals those events + for (auto bind_node : channel_data) { + bind_node.second.event->Signal(); + } + channel_data.clear(); + + LOG_DEBUG(Service_NWM, "called"); } /** @@ -1075,6 +1199,55 @@ static void GetChannel(Interface* self) { LOG_DEBUG(Service_NWM, "called"); } +/** + * NWM_UDS::ConnectToNetwork service function. + * This connects to the specified network + * Inputs: + * 0 : Command header + * 1 : Connection type: 0x1 = Client, 0x2 = Spectator. + * 2 : Passphrase buffer size + * 3 : (NetworkStructSize<<12) | 0x402 + * 4 : Network struct buffer ptr + * 5 : (PassphraseSize<<12) | 2 + * 6 : Input passphrase buffer ptr + * Outputs: + * 0 : Return header + * 1 : Result of function, 0 on success, otherwise error code + */ +static void ConnectToNetwork(Interface* self) { + IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x1E, 2, 4); + + u8 connection_type = rp.Pop(); + u32 passphrase_size = rp.Pop(); + + size_t desc_size; + const VAddr network_struct_addr = rp.PopStaticBuffer(&desc_size); + ASSERT(desc_size == sizeof(NetworkInfo)); + + size_t passphrase_desc_size; + const VAddr passphrase_addr = rp.PopStaticBuffer(&passphrase_desc_size); + + Memory::ReadBlock(network_struct_addr, &network_info, sizeof(network_info)); + + // Start the connection sequence + StartConnectionSequence(network_info.host_mac_address); + + connection_token = + SleepClientThread("uds::ConnectToNetwork", [](Kernel::SharedPtr thread) { + VAddr address = thread->GetCommandBufferAddress(); + std::array buffer; + IPC::RequestBuilder rb(buffer.data(), 0x1E, 1, 0); + // TODO(B3N30): Add error handling for host full and timeout + rb.Push(RESULT_SUCCESS); + Memory::WriteBlock(address, &*thread->owner_process, *buffer.data()); + + LOG_DEBUG(Service_NWM, "connection sequence finished"); + }); + + // TODO(B3N30): Add a timout for the connection sequence + LOG_DEBUG(Service_NWM, "called"); +} + /** * NWM_UDS::SetApplicationData service function. * Updates the application data that is being broadcast in the beacon frames @@ -1088,7 +1261,7 @@ static void GetChannel(Interface* self) { * 2 : Channel of the current WiFi network connection. */ static void SetApplicationData(Interface* self) { - IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x1A, 1, 2); + IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x10, 1, 2); u32 size = rp.Pop(); @@ -1147,8 +1320,8 @@ static void DecryptBeaconData(Interface* self) { // This size is hardcoded in the 3DS UDS code. ASSERT(output_buffer_size == sizeof(NodeInfo) * UDSMaxNodes); - LOG_WARNING(Service_NWM, "called in0=%08X in1=%08X out=%08X", encrypted_data0_addr, - encrypted_data1_addr, output_buffer_addr); + LOG_DEBUG(Service_NWM, "called in0=%08X in1=%08X out=%08X", encrypted_data0_addr, + encrypted_data1_addr, output_buffer_addr); NetworkInfo net_info; Memory::ReadBlock(network_struct_addr, &net_info, sizeof(net_info)); @@ -1158,15 +1331,10 @@ static void DecryptBeaconData(Interface* self) { std::array oui; Memory::ReadBlock(encrypted_data0_addr, oui.data(), oui.size()); ASSERT_MSG(oui == NintendoOUI, "Unexpected OUI"); - Memory::ReadBlock(encrypted_data1_addr, oui.data(), oui.size()); - ASSERT_MSG(oui == NintendoOUI, "Unexpected OUI"); ASSERT_MSG(Memory::Read8(encrypted_data0_addr + 3) == static_cast(NintendoTagId::EncryptedData0), "Unexpected tag id"); - ASSERT_MSG(Memory::Read8(encrypted_data1_addr + 3) == - static_cast(NintendoTagId::EncryptedData1), - "Unexpected tag id"); std::vector beacon_data(data0_size + data1_size); Memory::ReadBlock(encrypted_data0_addr + 4, beacon_data.data(), data0_size); @@ -1230,26 +1398,6 @@ static void BeaconBroadcastCallback(u64 userdata, int cycles_late) { beacon_broadcast_event, 0); } -/* - * Called when a client connects to an UDS network we're hosting, - * updates the connection status and signals the update event. - * @param network_node_id Network Node Id of the connecting client. - */ -void OnClientConnected(u16 network_node_id) { - std::lock_guard lock(connection_status_mutex); - ASSERT_MSG(connection_status.status == static_cast(NetworkStatus::ConnectedAsHost), - "Can not accept clients if we're not hosting a network"); - ASSERT_MSG(connection_status.total_nodes < connection_status.max_nodes, - "Can not accept connections on a full network"); - - u32 node_id = GetNextAvailableNodeId(); - connection_status.node_bitmask |= 1 << node_id; - connection_status.changed_nodes |= 1 << node_id; - connection_status.nodes[node_id] = network_node_id; - connection_status.total_nodes++; - connection_status_event->Signal(); -} - const Interface::FunctionInfo FunctionTable[] = { {0x000102C2, nullptr, "Initialize (deprecated)"}, {0x00020000, nullptr, "Scrap"}, @@ -1260,7 +1408,7 @@ const Interface::FunctionInfo FunctionTable[] = { {0x00070080, nullptr, "UpdateNetworkAttribute"}, {0x00080000, DestroyNetwork, "DestroyNetwork"}, {0x00090442, nullptr, "ConnectNetwork (deprecated)"}, - {0x000A0000, nullptr, "DisconnectNetwork"}, + {0x000A0000, DisconnectNetwork, "DisconnectNetwork"}, {0x000B0000, GetConnectionStatus, "GetConnectionStatus"}, {0x000D0040, GetNodeInformation, "GetNodeInformation"}, {0x000E0006, nullptr, "DecryptBeaconData (deprecated)"}, @@ -1275,7 +1423,7 @@ const Interface::FunctionInfo FunctionTable[] = { {0x001A0000, GetChannel, "GetChannel"}, {0x001B0302, InitializeWithVersion, "InitializeWithVersion"}, {0x001D0044, BeginHostingNetwork, "BeginHostingNetwork"}, - {0x001E0084, nullptr, "ConnectToNetwork"}, + {0x001E0084, ConnectToNetwork, "ConnectToNetwork"}, {0x001F0006, DecryptBeaconData, "DecryptBeaconData"}, {0x00200040, nullptr, "Flush"}, {0x00210080, nullptr, "SetProbeResponseParam"}, @@ -1305,6 +1453,9 @@ NWM_UDS::~NWM_UDS() { connection_status.status = static_cast(NetworkStatus::NotConnected); } + if (auto room_member = Network::GetRoomMember().lock()) + room_member->Unbind(wifi_packet_received); + CoreTiming::UnscheduleEvent(beacon_broadcast_event, 0); } From 5904e112152aaa5b6ca409f4ae774a1ae713007b Mon Sep 17 00:00:00 2001 From: B3n30 Date: Sat, 4 Nov 2017 10:28:53 +0100 Subject: [PATCH 02/11] fixup! UDS: Add coonnect and disconnect --- src/core/hle/service/nwm/nwm_uds.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/core/hle/service/nwm/nwm_uds.cpp b/src/core/hle/service/nwm/nwm_uds.cpp index bcffae4ae6..576a5f2559 100644 --- a/src/core/hle/service/nwm/nwm_uds.cpp +++ b/src/core/hle/service/nwm/nwm_uds.cpp @@ -444,7 +444,6 @@ void HandleDeauthenticationFrame(const Network::WifiPacket& packet) { connection_status.total_nodes--; network_info.total_nodes--; - node_info.erase(node); connection_status_event->Signal(); } From 520ecf7be61b98ba3250153b1d86821e6879f190 Mon Sep 17 00:00:00 2001 From: B3n30 Date: Sat, 25 Nov 2017 21:08:45 +0100 Subject: [PATCH 03/11] NWM_UDS: Convert to service framework --- src/core/hle/service/nwm/nwm.cpp | 5 +- src/core/hle/service/nwm/nwm.h | 3 + src/core/hle/service/nwm/nwm_uds.cpp | 491 +++++++----------------- src/core/hle/service/nwm/nwm_uds.h | 246 +++++++++++- src/core/hle/service/nwm/uds_beacon.cpp | 2 +- src/core/hle/service/nwm/uds_beacon.h | 2 +- src/core/hle/service/service.cpp | 2 + 7 files changed, 392 insertions(+), 359 deletions(-) diff --git a/src/core/hle/service/nwm/nwm.cpp b/src/core/hle/service/nwm/nwm.cpp index 9f1994dc3c..ce4c98bce9 100644 --- a/src/core/hle/service/nwm/nwm.cpp +++ b/src/core/hle/service/nwm/nwm.cpp @@ -21,7 +21,10 @@ void Init() { AddService(new NWM_SAP); AddService(new NWM_SOC); AddService(new NWM_TST); - AddService(new NWM_UDS); +} + +void InstallInterfaces(SM::ServiceManager& service_manager) { + std::make_shared()->InstallAsService(service_manager); } } // namespace NWM diff --git a/src/core/hle/service/nwm/nwm.h b/src/core/hle/service/nwm/nwm.h index 6926b29a6b..9c560c3abe 100644 --- a/src/core/hle/service/nwm/nwm.h +++ b/src/core/hle/service/nwm/nwm.h @@ -4,11 +4,14 @@ #pragma once +#include "core/hle/service/service.h" + namespace Service { namespace NWM { /// Initialize all NWM services void Init(); +void InstallInterfaces(SM::ServiceManager& service_manager); } // namespace NWM } // namespace Service diff --git a/src/core/hle/service/nwm/nwm_uds.cpp b/src/core/hle/service/nwm/nwm_uds.cpp index 576a5f2559..0c52c25607 100644 --- a/src/core/hle/service/nwm/nwm_uds.cpp +++ b/src/core/hle/service/nwm/nwm_uds.cpp @@ -89,8 +89,7 @@ static Network::RoomMember::CallbackHandle wifi_packet_rece // network thread. static std::mutex connection_status_mutex; -// token for the blocking ConnectToNetwork -static ThreadContinuationToken connection_token; +static Kernel::SharedPtr connection_event; // Mutex to synchronize access to the list of received beacons between the emulation thread and the // network thread. @@ -278,9 +277,7 @@ static void HandleEAPoLPacket(const Network::WifiPacket& packet) { // If blocking is implemented this lock needs to be changed, // otherwise it might cause deadlocks connection_status_event->Signal(); - if (connection_token.IsValid()) { - ContinueClientThread(connection_token); - } + connection_event->Signal(); } } @@ -479,16 +476,8 @@ void OnWifiPacketReceived(const Network::WifiPacket& packet) { } } -/** - * NWM_UDS::Shutdown service function - * Inputs: - * 1 : None - * Outputs: - * 0 : Return header - * 1 : Result of function, 0 on success, otherwise error code - */ -static void Shutdown(Interface* self) { - IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x03, 0, 0); +void NWM_UDS::Shutdown(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx, 0x03, 0, 0); if (auto room_member = Network::GetRoomMember().lock()) room_member->Unbind(wifi_packet_received); @@ -506,26 +495,8 @@ static void Shutdown(Interface* self) { LOG_DEBUG(Service_NWM, "called"); } -/** - * NWM_UDS::RecvBeaconBroadcastData service function - * Returns the raw beacon data for nearby networks that match the supplied WlanCommId. - * Inputs: - * 1 : Output buffer max size - * 2-3 : Unknown - * 4-5 : Host MAC address. - * 6-14 : Unused - * 15 : WLan Comm Id - * 16 : Id - * 17 : Value 0 - * 18 : Input handle - * 19 : (Size<<4) | 12 - * 20 : Output buffer ptr - * Outputs: - * 0 : Return header - * 1 : Result of function, 0 on success, otherwise error code - */ -static void RecvBeaconBroadcastData(Interface* self) { - IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x0F, 16, 4); +void NWM_UDS::RecvBeaconBroadcastData(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx, 0x0F, 16, 4); u32 out_buffer_size = rp.Pop(); u32 unk1 = rp.Pop(); @@ -540,11 +511,10 @@ static void RecvBeaconBroadcastData(Interface* self) { u32 id = rp.Pop(); Kernel::Handle input_handle = rp.PopHandle(); - size_t desc_size; - const VAddr out_buffer_ptr = rp.PopMappedBuffer(&desc_size); - ASSERT(desc_size == out_buffer_size); + Kernel::MappedBuffer out_buffer = rp.PopMappedBuffer(); + ASSERT(out_buffer.GetSize() == out_buffer_size); - VAddr current_buffer_pos = out_buffer_ptr; + size_t offset = sizeof(BeaconDataReplyHeader); u32 total_size = sizeof(BeaconDataReplyHeader); // Retrieve all beacon frames that were received from the desired mac address. @@ -554,8 +524,6 @@ static void RecvBeaconBroadcastData(Interface* self) { data_reply_header.total_entries = static_cast(beacons.size()); data_reply_header.max_output_size = out_buffer_size; - Memory::WriteBlock(current_buffer_pos, &data_reply_header, sizeof(BeaconDataReplyHeader)); - current_buffer_pos += sizeof(BeaconDataReplyHeader); // Write each of the received beacons into the buffer for (const auto& beacon : beacons) { BeaconEntryHeader entry{}; @@ -566,45 +534,31 @@ static void RecvBeaconBroadcastData(Interface* self) { entry.header_size = sizeof(BeaconEntryHeader); entry.mac_address = beacon.transmitter_address; - ASSERT(current_buffer_pos < out_buffer_ptr + out_buffer_size); + ASSERT(offset < out_buffer_size); - Memory::WriteBlock(current_buffer_pos, &entry, sizeof(BeaconEntryHeader)); - current_buffer_pos += sizeof(BeaconEntryHeader); - - Memory::WriteBlock(current_buffer_pos, beacon.data.data(), beacon.data.size()); - current_buffer_pos += static_cast(beacon.data.size()); + out_buffer.Write(&entry, offset, sizeof(BeaconEntryHeader)); + offset += sizeof(BeaconEntryHeader); + const unsigned char* beacon_data = beacon.data.data(); + out_buffer.Write(const_cast(static_cast(beacon_data)), offset, beacon.data.size()); + offset += beacon.data.size(); total_size += static_cast(sizeof(BeaconEntryHeader) + beacon.data.size()); } // Update the total size in the structure and write it to the buffer again. data_reply_header.total_size = total_size; - Memory::WriteBlock(out_buffer_ptr, &data_reply_header, sizeof(BeaconDataReplyHeader)); + out_buffer.Write(&data_reply_header, 0, sizeof(BeaconDataReplyHeader)); IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); rb.Push(RESULT_SUCCESS); LOG_DEBUG(Service_NWM, "called out_buffer_size=0x%08X, wlan_comm_id=0x%08X, id=0x%08X," - "input_handle=0x%08X, out_buffer_ptr=0x%08X, unk1=0x%08X, unk2=0x%08X", - out_buffer_size, wlan_comm_id, id, input_handle, out_buffer_ptr, unk1, unk2); + "input_handle=0x%08X, unk1=0x%08X, unk2=0x%08X, offset=%d", + out_buffer_size, wlan_comm_id, id, input_handle, unk1, unk2, offset); } -/** - * NWM_UDS::Initialize service function - * Inputs: - * 1 : Shared memory size - * 2-11 : Input NodeInfo Structure - * 12 : 2-byte Version - * 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 - */ -static void InitializeWithVersion(Interface* self) { - IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x1B, 12, 2); +void NWM_UDS::InitializeWithVersion(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx, 0x1B, 12, 2); u32 sharedmem_size = rp.Pop(); @@ -613,9 +567,7 @@ static void InitializeWithVersion(Interface* self) { u16 version = rp.Pop(); - Kernel::Handle sharedmem_handle = rp.PopHandle(); - - recv_buffer_memory = Kernel::g_handle_table.Get(sharedmem_handle); + recv_buffer_memory = rp.PopObject(); initialized = true; @@ -644,26 +596,14 @@ static void InitializeWithVersion(Interface* self) { IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); rb.Push(RESULT_SUCCESS); - rb.PushCopyHandles(Kernel::g_handle_table.Create(connection_status_event).Unwrap()); + rb.PushCopyObjects(connection_status_event); - LOG_DEBUG(Service_NWM, "called sharedmem_size=0x%08X, version=0x%08X, sharedmem_handle=0x%08X", - sharedmem_size, version, sharedmem_handle); + LOG_DEBUG(Service_NWM, "called sharedmem_size=0x%08X, version=0x%08X", + sharedmem_size, version); } -/** - * NWM_UDS::GetConnectionStatus service function. - * Returns the connection status structure for the currently open network connection. - * This structure contains information about the connection, - * like the number of connected nodes, etc. - * Inputs: - * 0 : Command header. - * Outputs: - * 0 : Return header - * 1 : Result of function, 0 on success, otherwise error code - * 2-13 : Channel of the current WiFi network connection. - */ -static void GetConnectionStatus(Interface* self) { - IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0xB, 0, 0); +void NWM_UDS::GetConnectionStatus(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx, 0xB, 0, 0); IPC::RequestBuilder rb = rp.MakeBuilder(13, 0); rb.Push(RESULT_SUCCESS); @@ -681,19 +621,8 @@ static void GetConnectionStatus(Interface* self) { LOG_DEBUG(Service_NWM, "called"); } -/** - * NWM_UDS::GetNodeInformation service function. - * Returns the node inforamtion structure for the currently connected node. - * Inputs: - * 0 : Command header. - * 1 : Node ID. - * Outputs: - * 0 : Return header - * 1 : Result of function, 0 on success, otherwise error code - * 2-11 : NodeInfo structure. - */ -static void GetNodeInformation(Interface* self) { - IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0xD, 1, 0); +void NWM_UDS::GetNodeInformation(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx, 0xD, 1, 0); u16 network_node_id = rp.Pop(); if (!initialized) { @@ -723,22 +652,8 @@ static void GetNodeInformation(Interface* self) { LOG_DEBUG(Service_NWM, "called"); } -/** - * NWM_UDS::Bind service function. - * Binds a BindNodeId to a data channel and retrieves a data event. - * Inputs: - * 1 : BindNodeId - * 2 : Receive buffer size. - * 3 : u8 Data channel to bind to. - * 4 : Network node id. - * Outputs: - * 0 : Return header - * 1 : Result of function, 0 on success, otherwise error code - * 2 : Copy handle descriptor. - * 3 : Data available event handle. - */ -static void Bind(Interface* self) { - IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x12, 4, 0); +void NWM_UDS::Bind(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx, 0x12, 4, 0); u32 bind_node_id = rp.Pop(); u32 recv_buffer_size = rp.Pop(); @@ -751,6 +666,7 @@ static void Bind(Interface* self) { IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); rb.Push(ResultCode(ErrorDescription::NotAuthorized, ErrorModule::UDS, ErrorSummary::WrongArgument, ErrorLevel::Usage)); + LOG_DEBUG(Service_NWM, "data_channel = %d, bind_node_id = %d", data_channel, bind_node_id); return; } @@ -759,6 +675,7 @@ static void Bind(Interface* self) { IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); rb.Push(ResultCode(ErrorDescription::OutOfMemory, ErrorModule::UDS, ErrorSummary::OutOfResource, ErrorLevel::Status)); + LOG_DEBUG(Service_NWM, "max bind nodes"); return; } @@ -767,6 +684,7 @@ static void Bind(Interface* self) { IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); rb.Push(ResultCode(ErrorDescription::TooLarge, ErrorModule::UDS, ErrorSummary::WrongArgument, ErrorLevel::Usage)); + LOG_DEBUG(Service_NWM, "MinRecvBufferSize"); return; } @@ -781,20 +699,11 @@ static void Bind(Interface* self) { IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); rb.Push(RESULT_SUCCESS); - rb.PushCopyHandles(Kernel::g_handle_table.Create(event).Unwrap()); + rb.PushCopyObjects(event); } -/** - * NWM_UDS::Unbind service function. - * Unbinds a BindNodeId from a data channel. - * Inputs: - * 1 : BindNodeId - * Outputs: - * 0 : Return header - * 1 : Result of function, 0 on success, otherwise error code - */ -static void Unbind(Interface* self) { - IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x12, 1, 0); +void NWM_UDS::Unbind(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx, 0x12, 1, 0); u32 bind_node_id = rp.Pop(); if (bind_node_id == 0) { @@ -824,27 +733,15 @@ static void Unbind(Interface* self) { rb.Push(0); } -/** - * NWM_UDS::BeginHostingNetwork service function. - * Creates a network and starts broadcasting its presence. - * Inputs: - * 1 : Passphrase buffer size. - * 3 : VAddr of the NetworkInfo structure. - * 5 : VAddr of the passphrase. - * Outputs: - * 0 : Return header - * 1 : Result of function, 0 on success, otherwise error code - */ -static void BeginHostingNetwork(Interface* self) { - IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x1D, 1, 4); +void NWM_UDS::BeginHostingNetwork(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx, 0x1D, 1, 4); const u32 passphrase_size = rp.Pop(); - size_t desc_size; - const VAddr network_info_address = rp.PopStaticBuffer(&desc_size); - ASSERT(desc_size == sizeof(NetworkInfo)); - const VAddr passphrase_address = rp.PopStaticBuffer(&desc_size); - ASSERT(desc_size == passphrase_size); + const std::vector network_info_buffer = rp.PopStaticBuffer(); + ASSERT(network_info_buffer.size() == sizeof(NetworkInfo)); + const std::vector passphrase = rp.PopStaticBuffer(); + ASSERT(passphrase.size() == passphrase_size); // TODO(Subv): Store the passphrase and verify it when attempting a connection. @@ -852,8 +749,7 @@ static void BeginHostingNetwork(Interface* self) { { std::lock_guard lock(connection_status_mutex); - - Memory::ReadBlock(network_info_address, &network_info, sizeof(NetworkInfo)); + std::memcpy(&network_info, network_info_buffer.data(), sizeof(NetworkInfo)); // 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."); @@ -915,17 +811,15 @@ static void BeginHostingNetwork(Interface* self) { rb.Push(RESULT_SUCCESS); } -/** - * NWM_UDS::DestroyNetwork service function. - * Closes the network that we're currently hosting. - * Inputs: - * 0 : Command header. - * Outputs: - * 0 : Return header - * 1 : Result of function, 0 on success, otherwise error code - */ -static void DestroyNetwork(Interface* self) { - IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x08, 0, 0); +void NWM_UDS::UpdateNetworkAttribute(Kernel::HLERequestContext& ctx){ + IPC::RequestParser rp(ctx, 0x07, 2, 0); + rp.Skip(2, false); + IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); + rb.Push(RESULT_SUCCESS); +} + +void NWM_UDS::DestroyNetwork(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx, 0x08, 0, 0); // Unschedule the beacon broadcast event. CoreTiming::UnscheduleEvent(beacon_broadcast_event, 0); @@ -960,8 +854,8 @@ static void DestroyNetwork(Interface* self) { LOG_DEBUG(Service_NWM, "called"); } -static void DisconnectNetwork(Interface* self) { - IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0xA, 0, 0); +void NWM_UDS::DisconnectNetwork(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx, 0xA, 0, 0); IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); rb.Push(RESULT_SUCCESS); @@ -1002,25 +896,8 @@ static void DisconnectNetwork(Interface* self) { LOG_DEBUG(Service_NWM, "called"); } -/** - * NWM_UDS::SendTo service function. - * Sends a data frame to the UDS network we're connected to. - * Inputs: - * 0 : Command header. - * 1 : Unknown. - * 2 : u16 Destination network node id. - * 3 : u8 Data channel. - * 4 : Buffer size >> 2 - * 5 : Data size - * 6 : Flags - * 7 : Input buffer descriptor - * 8 : Input buffer address - * Outputs: - * 0 : Return header - * 1 : Result of function, 0 on success, otherwise error code - */ -static void SendTo(Interface* self) { - IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x17, 6, 2); +void NWM_UDS::SendTo(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx, 0x17, 6, 2); rp.Skip(1, false); u16 dest_node_id = rp.Pop(); @@ -1029,9 +906,8 @@ static void SendTo(Interface* self) { u32 data_size = rp.Pop(); u32 flags = rp.Pop(); - size_t desc_size; - const VAddr input_address = rp.PopStaticBuffer(&desc_size); - ASSERT(desc_size >= data_size); + const std::vector input_buffer = rp.PopStaticBuffer(); + ASSERT(input_buffer.size() >= data_size); IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); @@ -1058,13 +934,10 @@ static void SendTo(Interface* self) { return; } - std::vector data(data_size); - Memory::ReadBlock(input_address, data.data(), data.size()); - // TODO(B3N30): Increment the sequence number after each sent packet. u16 sequence_number = 0; std::vector data_payload = GenerateDataPayload( - data, data_channel, dest_node_id, connection_status.network_node_id, sequence_number); + input_buffer, data_channel, dest_node_id, connection_status.network_node_id, sequence_number); // TODO(B3N30): Retrieve the MAC address of the dest_node_id and our own to encrypt // and encapsulate the payload. @@ -1085,34 +958,13 @@ static void SendTo(Interface* self) { rb.Push(RESULT_SUCCESS); } -/** - * NWM_UDS::PullPacket service function. - * Receives a data frame from the specified bind node id - * Inputs: - * 0 : Command header. - * 1 : Bind node id. - * 2 : Max out buff size >> 2. - * 3 : Max out buff size. - * 64 : Output buffer descriptor - * 65 : Output buffer address - * Outputs: - * 0 : Return header - * 1 : Result of function, 0 on success, otherwise error code - * 2 : Received data size - * 3 : u16 Source network node id - * 4 : Buffer descriptor - * 5 : Buffer address - */ -static void PullPacket(Interface* self) { - IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x14, 3, 0); +void NWM_UDS::PullPacket(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx, 0x14, 3, 0); u32 bind_node_id = rp.Pop(); u32 max_out_buff_size_aligned = rp.Pop(); u32 max_out_buff_size = rp.Pop(); - size_t desc_size; - const VAddr output_address = rp.PeekStaticBuffer(0, &desc_size); - ASSERT(desc_size == max_out_buff_size); std::lock_guard lock(connection_status_mutex); if (connection_status.status != static_cast(NetworkStatus::ConnectedAsHost) && @@ -1137,12 +989,12 @@ static void PullPacket(Interface* self) { } if (channel->second.received_packets.empty()) { - Memory::ZeroBlock(output_address, desc_size); + std::vector output_buffer(max_out_buff_size, 0); IPC::RequestBuilder rb = rp.MakeBuilder(3, 2); rb.Push(RESULT_SUCCESS); rb.Push(0); rb.Push(0); - rb.PushStaticBuffer(output_address, desc_size, 0); + rb.PushStaticBuffer(output_buffer, 0); return; } @@ -1159,32 +1011,23 @@ static void PullPacket(Interface* self) { } IPC::RequestBuilder rb = rp.MakeBuilder(3, 2); - Memory::ZeroBlock(output_address, desc_size); + + std::vector output_buffer(max_out_buff_size, 0); // Write the actual data. - Memory::WriteBlock(output_address, + std::memcpy(output_buffer.data(), next_packet.data() + sizeof(LLCHeader) + sizeof(SecureDataHeader), data_size); rb.Push(RESULT_SUCCESS); rb.Push(data_size); rb.Push(secure_data.src_node_id); - rb.PushStaticBuffer(output_address, desc_size, 0); + rb.PushStaticBuffer(output_buffer, 0); channel->second.received_packets.pop_front(); } -/** - * NWM_UDS::GetChannel service function. - * Returns the WiFi channel in which the network we're connected to is transmitting. - * Inputs: - * 0 : Command header. - * Outputs: - * 0 : Return header - * 1 : Result of function, 0 on success, otherwise error code - * 2 : Channel of the current WiFi network connection. - */ -static void GetChannel(Interface* self) { - IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x1A, 0, 0); +void NWM_UDS::GetChannel(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx, 0x1A, 0, 0); IPC::RequestBuilder rb = rp.MakeBuilder(2, 0); std::lock_guard lock(connection_status_mutex); @@ -1198,48 +1041,32 @@ static void GetChannel(Interface* self) { LOG_DEBUG(Service_NWM, "called"); } -/** - * NWM_UDS::ConnectToNetwork service function. - * This connects to the specified network - * Inputs: - * 0 : Command header - * 1 : Connection type: 0x1 = Client, 0x2 = Spectator. - * 2 : Passphrase buffer size - * 3 : (NetworkStructSize<<12) | 0x402 - * 4 : Network struct buffer ptr - * 5 : (PassphraseSize<<12) | 2 - * 6 : Input passphrase buffer ptr - * Outputs: - * 0 : Return header - * 1 : Result of function, 0 on success, otherwise error code - */ -static void ConnectToNetwork(Interface* self) { - IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x1E, 2, 4); +void NWM_UDS::ConnectToNetwork(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx, 0x1E, 2, 4); u8 connection_type = rp.Pop(); u32 passphrase_size = rp.Pop(); - size_t desc_size; - const VAddr network_struct_addr = rp.PopStaticBuffer(&desc_size); - ASSERT(desc_size == sizeof(NetworkInfo)); + const std::vector network_struct_buffer = rp.PopStaticBuffer(); + ASSERT(network_struct_buffer.size() == sizeof(NetworkInfo)); - size_t passphrase_desc_size; - const VAddr passphrase_addr = rp.PopStaticBuffer(&passphrase_desc_size); + const std::vector passphrase = rp.PopStaticBuffer(); - Memory::ReadBlock(network_struct_addr, &network_info, sizeof(network_info)); + std::memcpy(&network_info, network_struct_buffer.data(), sizeof(network_info)); // Start the connection sequence StartConnectionSequence(network_info.host_mac_address); - connection_token = - SleepClientThread("uds::ConnectToNetwork", [](Kernel::SharedPtr thread) { - VAddr address = thread->GetCommandBufferAddress(); - std::array buffer; - IPC::RequestBuilder rb(buffer.data(), 0x1E, 1, 0); - // TODO(B3N30): Add error handling for host full and timeout - rb.Push(RESULT_SUCCESS); - Memory::WriteBlock(address, &*thread->owner_process, *buffer.data()); + // 300 ms + // Since this timing is handled by core_timing it could differ from the 'real world' time + static constexpr u64 UDSConnectionTimeout = 300000000; + connection_event = + ctx.SleepClientThread(Kernel::GetCurrentThread(), "uds::ConnectToNetwork", UDSConnectionTimeout, [](Kernel::SharedPtr thread, Kernel::HLERequestContext& ctx, + ThreadWakeupReason reason) { + // TODO(B3N30): Add error handling for host full and timeout + IPC::RequestBuilder rb(ctx, 0x1E, 1, 0); + rb.Push(RESULT_SUCCESS); LOG_DEBUG(Service_NWM, "connection sequence finished"); }); @@ -1247,26 +1074,13 @@ static void ConnectToNetwork(Interface* self) { LOG_DEBUG(Service_NWM, "called"); } -/** - * NWM_UDS::SetApplicationData service function. - * Updates the application data that is being broadcast in the beacon frames - * for the network that we're hosting. - * Inputs: - * 1 : Data size. - * 3 : VAddr of the data. - * Outputs: - * 0 : Return header - * 1 : Result of function, 0 on success, otherwise error code - * 2 : Channel of the current WiFi network connection. - */ -static void SetApplicationData(Interface* self) { - IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x10, 1, 2); +void NWM_UDS::SetApplicationData(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx, 0x10, 1, 2); u32 size = rp.Pop(); - size_t desc_size; - const VAddr address = rp.PopStaticBuffer(&desc_size); - ASSERT(desc_size == size); + const std::vector address = rp.PopStaticBuffer(); + ASSERT(address.size() == size); LOG_DEBUG(Service_NWM, "called"); @@ -1279,68 +1093,43 @@ static void SetApplicationData(Interface* self) { } network_info.application_data_size = size; - Memory::ReadBlock(address, network_info.application_data.data(), size); + memcpy(network_info.application_data.data(), address.data(), size); rb.Push(RESULT_SUCCESS); } -/** - * NWM_UDS::DecryptBeaconData service function. - * Decrypts the encrypted data tags contained in the 802.11 beacons. - * Inputs: - * 1 : Input network struct buffer descriptor. - * 2 : Input network struct buffer ptr. - * 3 : Input tag0 encrypted buffer descriptor. - * 4 : Input tag0 encrypted buffer ptr. - * 5 : Input tag1 encrypted buffer descriptor. - * 6 : Input tag1 encrypted buffer ptr. - * 64 : Output buffer descriptor. - * 65 : Output buffer ptr. - * Outputs: - * 0 : Return header - * 1 : Result of function, 0 on success, otherwise error code - */ -static void DecryptBeaconData(Interface* self) { - IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x1F, 0, 6); +void NWM_UDS::DecryptBeaconData(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx, 0x1F, 0, 6); - size_t desc_size; - const VAddr network_struct_addr = rp.PopStaticBuffer(&desc_size); - ASSERT(desc_size == sizeof(NetworkInfo)); + const std::vector network_struct_buffer = rp.PopStaticBuffer(); + ASSERT(network_struct_buffer.size() == sizeof(NetworkInfo)); - size_t data0_size; - const VAddr encrypted_data0_addr = rp.PopStaticBuffer(&data0_size); + const std::vector encrypted_data0_buffer = rp.PopStaticBuffer(); - size_t data1_size; - const VAddr encrypted_data1_addr = rp.PopStaticBuffer(&data1_size); + const std::vector encrypted_data1_buffer = rp.PopStaticBuffer(); - size_t output_buffer_size; - const VAddr output_buffer_addr = rp.PeekStaticBuffer(0, &output_buffer_size); - // This size is hardcoded in the 3DS UDS code. - ASSERT(output_buffer_size == sizeof(NodeInfo) * UDSMaxNodes); - - LOG_DEBUG(Service_NWM, "called in0=%08X in1=%08X out=%08X", encrypted_data0_addr, - encrypted_data1_addr, output_buffer_addr); + LOG_DEBUG(Service_NWM, "called"); NetworkInfo net_info; - Memory::ReadBlock(network_struct_addr, &net_info, sizeof(net_info)); + std::memcpy(&net_info, network_struct_buffer.data(), sizeof(net_info)); // Read the encrypted data. // The first 4 bytes should be the OUI and the OUI Type of the tags. std::array oui; - Memory::ReadBlock(encrypted_data0_addr, oui.data(), oui.size()); + std::memcpy(oui.data(), encrypted_data0_buffer.data(), oui.size()); ASSERT_MSG(oui == NintendoOUI, "Unexpected OUI"); - ASSERT_MSG(Memory::Read8(encrypted_data0_addr + 3) == + ASSERT_MSG(encrypted_data0_buffer[3] == static_cast(NintendoTagId::EncryptedData0), "Unexpected tag id"); - std::vector beacon_data(data0_size + data1_size); - Memory::ReadBlock(encrypted_data0_addr + 4, beacon_data.data(), data0_size); - Memory::ReadBlock(encrypted_data1_addr + 4, beacon_data.data() + data0_size, data1_size); + std::vector beacon_data(encrypted_data0_buffer.size() + encrypted_data1_buffer.size()); + std::memcpy(beacon_data.data(), encrypted_data0_buffer.data() + 4, encrypted_data0_buffer.size()); + std::memcpy(beacon_data.data() + encrypted_data0_buffer.size(), encrypted_data1_buffer.data() + 4, encrypted_data1_buffer.size()); // Decrypt the data - DecryptBeaconData(net_info, beacon_data); + DecryptBeacon(net_info, beacon_data); // The beacon data header contains the MD5 hash of the data. BeaconData beacon_header; @@ -1367,12 +1156,12 @@ static void DecryptBeaconData(Interface* self) { nodes.push_back(node); } - Memory::ZeroBlock(output_buffer_addr, sizeof(NodeInfo) * UDSMaxNodes); - Memory::WriteBlock(output_buffer_addr, nodes.data(), sizeof(NodeInfo) * nodes.size()); - IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); - rb.PushStaticBuffer(output_buffer_addr, output_buffer_size, 0); rb.Push(RESULT_SUCCESS); + + std::vector output_buffer(sizeof(NodeInfo) * UDSMaxNodes, 0); + std::memcpy(output_buffer.data(), nodes.data(), sizeof(NodeInfo) * nodes.size()); + rb.PushStaticBuffer(output_buffer, 0); } // Sends a 802.11 beacon frame with information about the current network. @@ -1397,43 +1186,43 @@ static void BeaconBroadcastCallback(u64 userdata, int cycles_late) { beacon_broadcast_event, 0); } -const Interface::FunctionInfo FunctionTable[] = { - {0x000102C2, nullptr, "Initialize (deprecated)"}, - {0x00020000, nullptr, "Scrap"}, - {0x00030000, Shutdown, "Shutdown"}, - {0x00040402, nullptr, "CreateNetwork (deprecated)"}, - {0x00050040, nullptr, "EjectClient"}, - {0x00060000, nullptr, "EjectSpectator"}, - {0x00070080, nullptr, "UpdateNetworkAttribute"}, - {0x00080000, DestroyNetwork, "DestroyNetwork"}, - {0x00090442, nullptr, "ConnectNetwork (deprecated)"}, - {0x000A0000, DisconnectNetwork, "DisconnectNetwork"}, - {0x000B0000, GetConnectionStatus, "GetConnectionStatus"}, - {0x000D0040, GetNodeInformation, "GetNodeInformation"}, - {0x000E0006, nullptr, "DecryptBeaconData (deprecated)"}, - {0x000F0404, RecvBeaconBroadcastData, "RecvBeaconBroadcastData"}, - {0x00100042, SetApplicationData, "SetApplicationData"}, - {0x00110040, nullptr, "GetApplicationData"}, - {0x00120100, Bind, "Bind"}, - {0x00130040, Unbind, "Unbind"}, - {0x001400C0, PullPacket, "PullPacket"}, - {0x00150080, nullptr, "SetMaxSendDelay"}, - {0x00170182, SendTo, "SendTo"}, - {0x001A0000, GetChannel, "GetChannel"}, - {0x001B0302, InitializeWithVersion, "InitializeWithVersion"}, - {0x001D0044, BeginHostingNetwork, "BeginHostingNetwork"}, - {0x001E0084, ConnectToNetwork, "ConnectToNetwork"}, - {0x001F0006, DecryptBeaconData, "DecryptBeaconData"}, - {0x00200040, nullptr, "Flush"}, - {0x00210080, nullptr, "SetProbeResponseParam"}, - {0x00220402, nullptr, "ScanOnConnection"}, -}; -NWM_UDS::NWM_UDS() { +NWM_UDS::NWM_UDS() : ServiceFramework("nwm::UDS") { + static const FunctionInfo functions[] = { + {0x000102C2, nullptr, "Initialize (deprecated)"}, + {0x00020000, nullptr, "Scrap"}, + {0x00030000, &NWM_UDS::Shutdown, "Shutdown"}, + {0x00040402, nullptr, "CreateNetwork (deprecated)"}, + {0x00050040, nullptr, "EjectClient"}, + {0x00060000, nullptr, "EjectSpectator"}, + {0x00070080, &NWM_UDS::UpdateNetworkAttribute, "UpdateNetworkAttribute"}, + {0x00080000, &NWM_UDS::DestroyNetwork, "DestroyNetwork"}, + {0x00090442, nullptr, "ConnectNetwork (deprecated)"}, + {0x000A0000, &NWM_UDS::DisconnectNetwork, "DisconnectNetwork"}, + {0x000B0000, &NWM_UDS::GetConnectionStatus, "GetConnectionStatus"}, + {0x000D0040, &NWM_UDS::GetNodeInformation, "GetNodeInformation"}, + {0x000E0006, nullptr, "DecryptBeaconData (deprecated)"}, + {0x000F0404, &NWM_UDS::RecvBeaconBroadcastData, "RecvBeaconBroadcastData"}, + {0x00100042, &NWM_UDS::SetApplicationData, "SetApplicationData"}, + {0x00110040, nullptr, "GetApplicationData"}, + {0x00120100, &NWM_UDS::Bind, "Bind"}, + {0x00130040, &NWM_UDS::Unbind, "Unbind"}, + {0x001400C0, &NWM_UDS::PullPacket, "PullPacket"}, + {0x00150080, nullptr, "SetMaxSendDelay"}, + {0x00170182, &NWM_UDS::SendTo, "SendTo"}, + {0x001A0000, &NWM_UDS::GetChannel, "GetChannel"}, + {0x001B0302, &NWM_UDS::InitializeWithVersion, "InitializeWithVersion"}, + {0x001D0044, &NWM_UDS::BeginHostingNetwork, "BeginHostingNetwork"}, + {0x001E0084, &NWM_UDS::ConnectToNetwork, "ConnectToNetwork"}, + {0x001F0006, &NWM_UDS::DecryptBeaconData, "DecryptBeaconData"}, + {0x00200040, nullptr, "Flush"}, + {0x00210080, nullptr, "SetProbeResponseParam"}, + {0x00220402, nullptr, "ScanOnConnection"}, + }; connection_status_event = Kernel::Event::Create(Kernel::ResetType::OneShot, "NWM::connection_status_event"); - Register(FunctionTable); + RegisterHandlers(functions); beacon_broadcast_event = CoreTiming::RegisterEvent("UDS::BeaconBroadcastCallback", BeaconBroadcastCallback); diff --git a/src/core/hle/service/nwm/nwm_uds.h b/src/core/hle/service/nwm/nwm_uds.h index f1caaf9746..4eaf6d515e 100644 --- a/src/core/hle/service/nwm/nwm_uds.h +++ b/src/core/hle/service/nwm/nwm_uds.h @@ -97,14 +97,250 @@ enum class TagId : u8 { VendorSpecific = 221 }; -class NWM_UDS final : public Interface { +class NWM_UDS final : public ServiceFramework { public: NWM_UDS(); - ~NWM_UDS() override; + ~NWM_UDS(); + +private: + + void UpdateNetworkAttribute(Kernel::HLERequestContext& ctx); + + /** + * NWM_UDS::Shutdown service function + * Inputs: + * 1 : None + * Outputs: + * 0 : Return header + * 1 : Result of function, 0 on success, otherwise error code + */ + void Shutdown(Kernel::HLERequestContext& ctx); + + /** + * NWM_UDS::DestroyNetwork service function. + * Closes the network that we're currently hosting. + * Inputs: + * 0 : Command header. + * Outputs: + * 0 : Return header + * 1 : Result of function, 0 on success, otherwise error code + */ + void DestroyNetwork(Kernel::HLERequestContext& ctx); + + /** + * NWM_UDS::DisconnectNetwork service function. + * This disconnects this device from the network. + * Inputs: + * 0 : Command header. + * Outputs: + * 0 : Return header + * 1 : Result of function, 0 on success, otherwise error code + */ + void DisconnectNetwork(Kernel::HLERequestContext& ctx); + + /** + * NWM_UDS::GetConnectionStatus service function. + * Returns the connection status structure for the currently open network connection. + * This structure contains information about the connection, + * like the number of connected nodes, etc. + * Inputs: + * 0 : Command header. + * Outputs: + * 0 : Return header + * 1 : Result of function, 0 on success, otherwise error code + * 2-13 : Channel of the current WiFi network connection. + */ + void GetConnectionStatus(Kernel::HLERequestContext& ctx); + + /** + * NWM_UDS::GetNodeInformation service function. + * Returns the node inforamtion structure for the currently connected node. + * Inputs: + * 0 : Command header. + * 1 : Node ID. + * Outputs: + * 0 : Return header + * 1 : Result of function, 0 on success, otherwise error code + * 2-11 : NodeInfo structure. + */ + void GetNodeInformation(Kernel::HLERequestContext& ctx); + + /** + * NWM_UDS::RecvBeaconBroadcastData service function + * Returns the raw beacon data for nearby networks that match the supplied WlanCommId. + * Inputs: + * 1 : Output buffer max size + * 2-3 : Unknown + * 4-5 : Host MAC address. + * 6-14 : Unused + * 15 : WLan Comm Id + * 16 : Id + * 17 : Value 0 + * 18 : Input handle + * 19 : (Size<<4) | 12 + * 20 : Output buffer ptr + * Outputs: + * 0 : Return header + * 1 : Result of function, 0 on success, otherwise error code + */ + void RecvBeaconBroadcastData(Kernel::HLERequestContext& ctx); + + /** + * NWM_UDS::SetApplicationData service function. + * Updates the application data that is being broadcast in the beacon frames + * for the network that we're hosting. + * Inputs: + * 1 : Data size. + * 3 : VAddr of the data. + * Outputs: + * 0 : Return header + * 1 : Result of function, 0 on success, otherwise error code + * 2 : Channel of the current WiFi network connection. + */ + void SetApplicationData(Kernel::HLERequestContext& ctx); + + /** + * NWM_UDS::Bind service function. + * Binds a BindNodeId to a data channel and retrieves a data event. + * Inputs: + * 1 : BindNodeId + * 2 : Receive buffer size. + * 3 : u8 Data channel to bind to. + * 4 : Network node id. + * Outputs: + * 0 : Return header + * 1 : Result of function, 0 on success, otherwise error code + * 2 : Copy handle descriptor. + * 3 : Data available event handle. + */ + void Bind(Kernel::HLERequestContext& ctx); + + /** + * NWM_UDS::Unbind service function. + * Unbinds a BindNodeId from a data channel. + * Inputs: + * 1 : BindNodeId + * Outputs: + * 0 : Return header + * 1 : Result of function, 0 on success, otherwise error code + */ + void Unbind(Kernel::HLERequestContext& ctx); + + /** + * NWM_UDS::PullPacket service function. + * Receives a data frame from the specified bind node id + * Inputs: + * 0 : Command header. + * 1 : Bind node id. + * 2 : Max out buff size >> 2. + * 3 : Max out buff size. + * 64 : Output buffer descriptor + * 65 : Output buffer address + * Outputs: + * 0 : Return header + * 1 : Result of function, 0 on success, otherwise error code + * 2 : Received data size + * 3 : u16 Source network node id + * 4 : Buffer descriptor + * 5 : Buffer address + */ + void PullPacket(Kernel::HLERequestContext& ctx); + + /** + * NWM_UDS::SendTo service function. + * Sends a data frame to the UDS network we're connected to. + * Inputs: + * 0 : Command header. + * 1 : Unknown. + * 2 : u16 Destination network node id. + * 3 : u8 Data channel. + * 4 : Buffer size >> 2 + * 5 : Data size + * 6 : Flags + * 7 : Input buffer descriptor + * 8 : Input buffer address + * Outputs: + * 0 : Return header + * 1 : Result of function, 0 on success, otherwise error code + */ + void SendTo(Kernel::HLERequestContext& ctx); + + /** + * NWM_UDS::GetChannel service function. + * Returns the WiFi channel in which the network we're connected to is transmitting. + * Inputs: + * 0 : Command header. + * Outputs: + * 0 : Return header + * 1 : Result of function, 0 on success, otherwise error code + * 2 : Channel of the current WiFi network connection. + */ + void GetChannel(Kernel::HLERequestContext& ctx); + + /** + * NWM_UDS::Initialize service function + * Inputs: + * 1 : Shared memory size + * 2-11 : Input NodeInfo Structure + * 12 : 2-byte Version + * 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 InitializeWithVersion(Kernel::HLERequestContext& ctx); + + /** + * NWM_UDS::BeginHostingNetwork service function. + * Creates a network and starts broadcasting its presence. + * Inputs: + * 1 : Passphrase buffer size. + * 3 : VAddr of the NetworkInfo structure. + * 5 : VAddr of the passphrase. + * Outputs: + * 0 : Return header + * 1 : Result of function, 0 on success, otherwise error code + */ + void BeginHostingNetwork(Kernel::HLERequestContext& ctx); + + /** + * NWM_UDS::ConnectToNetwork service function. + * This connects to the specified network + * Inputs: + * 0 : Command header + * 1 : Connection type: 0x1 = Client, 0x2 = Spectator. + * 2 : Passphrase buffer size + * 3 : (NetworkStructSize<<12) | 0x402 + * 4 : Network struct buffer ptr + * 5 : (PassphraseSize<<12) | 2 + * 6 : Input passphrase buffer ptr + * Outputs: + * 0 : Return header + * 1 : Result of function, 0 on success, otherwise error code + */ + void ConnectToNetwork(Kernel::HLERequestContext& ctx); + + /** + * NWM_UDS::DecryptBeaconData service function. + * Decrypts the encrypted data tags contained in the 802.11 beacons. + * Inputs: + * 1 : Input network struct buffer descriptor. + * 2 : Input network struct buffer ptr. + * 3 : Input tag0 encrypted buffer descriptor. + * 4 : Input tag0 encrypted buffer ptr. + * 5 : Input tag1 encrypted buffer descriptor. + * 6 : Input tag1 encrypted buffer ptr. + * 64 : Output buffer descriptor. + * 65 : Output buffer ptr. + * Outputs: + * 0 : Return header + * 1 : Result of function, 0 on success, otherwise error code + */ + void DecryptBeaconData(Kernel::HLERequestContext& ctx); - std::string GetPortName() const override { - return "nwm::UDS"; - } }; } // namespace NWM diff --git a/src/core/hle/service/nwm/uds_beacon.cpp b/src/core/hle/service/nwm/uds_beacon.cpp index 466c02ae89..020876d730 100644 --- a/src/core/hle/service/nwm/uds_beacon.cpp +++ b/src/core/hle/service/nwm/uds_beacon.cpp @@ -224,7 +224,7 @@ std::vector GeneratedEncryptedData(const NetworkInfo& network_info, const No return buffer; } -void DecryptBeaconData(const NetworkInfo& network_info, std::vector& buffer) { +void DecryptBeacon(const NetworkInfo& network_info, std::vector& buffer) { // Decrypt the data using AES-CTR and the NWM beacon key. using CryptoPP::AES; std::array counter = GetBeaconCryptoCTR(network_info); diff --git a/src/core/hle/service/nwm/uds_beacon.h b/src/core/hle/service/nwm/uds_beacon.h index 50cc76da2d..e8743e9541 100644 --- a/src/core/hle/service/nwm/uds_beacon.h +++ b/src/core/hle/service/nwm/uds_beacon.h @@ -127,7 +127,7 @@ static_assert(sizeof(BeaconData) == 0x12, "BeaconData has incorrect size."); /** * Decrypts the beacon data buffer for the network described by `network_info`. */ -void DecryptBeaconData(const NetworkInfo& network_info, std::vector& buffer); +void DecryptBeacon(const NetworkInfo& network_info, std::vector& buffer); /** * Generates an 802.11 beacon frame starting at the management frame header. diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index ccbb398b5a..ff9e20b735 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -265,6 +265,8 @@ void Init() { AC::InstallInterfaces(*SM::g_service_manager); LDR::InstallInterfaces(*SM::g_service_manager); MIC::InstallInterfaces(*SM::g_service_manager); + NWM::InstallInterfaces(*SM::g_service_manager); + NWM::InstallInterfaces(*SM::g_service_manager); FS::ArchiveInit(); ACT::Init(); From 27e6e03d163e126ae7bb4e121d237e5641e3b285 Mon Sep 17 00:00:00 2001 From: B3n30 Date: Tue, 16 Jan 2018 21:23:19 +0100 Subject: [PATCH 04/11] Fixups from Subvs comments --- src/core/hle/service/nwm/nwm_uds.cpp | 15 +++++++-------- src/core/hle/service/service.cpp | 1 - 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/core/hle/service/nwm/nwm_uds.cpp b/src/core/hle/service/nwm/nwm_uds.cpp index 0c52c25607..20b46e6d6f 100644 --- a/src/core/hle/service/nwm/nwm_uds.cpp +++ b/src/core/hle/service/nwm/nwm_uds.cpp @@ -32,6 +32,7 @@ namespace NWM { namespace ErrCodes { enum { NotInitialized = 2, + WrongStatus = 490, }; } // namespace ErrCodes @@ -577,10 +578,6 @@ void NWM_UDS::InitializeWithVersion(Kernel::HLERequestContext& ctx) { wifi_packet_received = room_member->BindOnWifiPacketReceived(OnWifiPacketReceived); } else { LOG_ERROR(Service_NWM, "Network isn't initalized"); - IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); - // TODO(B3N30): Find the correct error code and return it; - rb.Push(-1); - return; } { @@ -591,7 +588,7 @@ void NWM_UDS::InitializeWithVersion(Kernel::HLERequestContext& ctx) { connection_status = {}; connection_status.status = static_cast(NetworkStatus::NotConnected); node_info.clear(); - node_info.push_back(NodeInfo{}); + node_info.push_back(current_node); } IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); @@ -828,7 +825,8 @@ void NWM_UDS::DestroyNetwork(Kernel::HLERequestContext& ctx) { std::lock_guard lock(connection_status_mutex); if (connection_status.status != static_cast(NetworkStatus::ConnectedAsHost)) { IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); - rb.Push(RESULT_SUCCESS); + rb.Push(ResultCode(ErrCodes::WrongStatus, ErrorModule::UDS, + ErrorSummary::InvalidState, ErrorLevel::Status)); LOG_WARNING(Service_NWM, "called with status %u", connection_status.status); return; } @@ -857,7 +855,6 @@ void NWM_UDS::DestroyNetwork(Kernel::HLERequestContext& ctx) { void NWM_UDS::DisconnectNetwork(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp(ctx, 0xA, 0, 0); IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); - rb.Push(RESULT_SUCCESS); using Network::WifiPacket; WifiPacket deauth; @@ -870,6 +867,8 @@ void NWM_UDS::DisconnectNetwork(Kernel::HLERequestContext& ctx) { connection_status.status = static_cast(NetworkStatus::ConnectedAsHost); connection_status.network_node_id = tmp_node_id; LOG_DEBUG(Service_NWM, "called as a host"); + rb.Push(ResultCode(ErrCodes::WrongStatus, ErrorModule::UDS, + ErrorSummary::InvalidState, ErrorLevel::Status)); return; } u16_le tmp_node_id = connection_status.network_node_id; @@ -893,6 +892,7 @@ void NWM_UDS::DisconnectNetwork(Kernel::HLERequestContext& ctx) { } channel_data.clear(); + rb.Push(RESULT_SUCCESS); LOG_DEBUG(Service_NWM, "called"); } @@ -1070,7 +1070,6 @@ void NWM_UDS::ConnectToNetwork(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_NWM, "connection sequence finished"); }); - // TODO(B3N30): Add a timout for the connection sequence LOG_DEBUG(Service_NWM, "called"); } diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index ff9e20b735..934cec30ab 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -266,7 +266,6 @@ void Init() { LDR::InstallInterfaces(*SM::g_service_manager); MIC::InstallInterfaces(*SM::g_service_manager); NWM::InstallInterfaces(*SM::g_service_manager); - NWM::InstallInterfaces(*SM::g_service_manager); FS::ArchiveInit(); ACT::Init(); From d793624c61f8a57eae6983521cc6a7dca48e8dcb Mon Sep 17 00:00:00 2001 From: B3n30 Date: Mon, 22 Jan 2018 22:06:45 +0100 Subject: [PATCH 05/11] fixup! NWM_UDS: Convert to service framework --- src/core/hle/service/nwm/nwm_uds.cpp | 58 ++++++++++++++------------- src/core/hle/service/nwm/nwm_uds.h | 2 - src/core/hle/service/nwm/uds_data.cpp | 5 ++- 3 files changed, 33 insertions(+), 32 deletions(-) diff --git a/src/core/hle/service/nwm/nwm_uds.cpp b/src/core/hle/service/nwm/nwm_uds.cpp index 20b46e6d6f..9d08edbd05 100644 --- a/src/core/hle/service/nwm/nwm_uds.cpp +++ b/src/core/hle/service/nwm/nwm_uds.cpp @@ -540,7 +540,8 @@ void NWM_UDS::RecvBeaconBroadcastData(Kernel::HLERequestContext& ctx) { out_buffer.Write(&entry, offset, sizeof(BeaconEntryHeader)); offset += sizeof(BeaconEntryHeader); const unsigned char* beacon_data = beacon.data.data(); - out_buffer.Write(const_cast(static_cast(beacon_data)), offset, beacon.data.size()); + out_buffer.Write(const_cast(static_cast(beacon_data)), offset, + beacon.data.size()); offset += beacon.data.size(); total_size += static_cast(sizeof(BeaconEntryHeader) + beacon.data.size()); @@ -553,9 +554,10 @@ void NWM_UDS::RecvBeaconBroadcastData(Kernel::HLERequestContext& ctx) { IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); rb.Push(RESULT_SUCCESS); - LOG_DEBUG(Service_NWM, "called out_buffer_size=0x%08X, wlan_comm_id=0x%08X, id=0x%08X," - "input_handle=0x%08X, unk1=0x%08X, unk2=0x%08X, offset=%d", - out_buffer_size, wlan_comm_id, id, input_handle, unk1, unk2, offset); + LOG_DEBUG(Service_NWM, + "called out_buffer_size=0x%08X, wlan_comm_id=0x%08X, id=0x%08X," + "input_handle=0x%08X, unk1=0x%08X, unk2=0x%08X, offset=%d", + out_buffer_size, wlan_comm_id, id, input_handle, unk1, unk2, offset); } void NWM_UDS::InitializeWithVersion(Kernel::HLERequestContext& ctx) { @@ -595,8 +597,7 @@ void NWM_UDS::InitializeWithVersion(Kernel::HLERequestContext& ctx) { rb.Push(RESULT_SUCCESS); rb.PushCopyObjects(connection_status_event); - LOG_DEBUG(Service_NWM, "called sharedmem_size=0x%08X, version=0x%08X", - sharedmem_size, version); + LOG_DEBUG(Service_NWM, "called sharedmem_size=0x%08X, version=0x%08X", sharedmem_size, version); } void NWM_UDS::GetConnectionStatus(Kernel::HLERequestContext& ctx) { @@ -808,7 +809,7 @@ void NWM_UDS::BeginHostingNetwork(Kernel::HLERequestContext& ctx) { rb.Push(RESULT_SUCCESS); } -void NWM_UDS::UpdateNetworkAttribute(Kernel::HLERequestContext& ctx){ +void NWM_UDS::UpdateNetworkAttribute(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp(ctx, 0x07, 2, 0); rp.Skip(2, false); IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); @@ -825,8 +826,8 @@ void NWM_UDS::DestroyNetwork(Kernel::HLERequestContext& ctx) { std::lock_guard lock(connection_status_mutex); if (connection_status.status != static_cast(NetworkStatus::ConnectedAsHost)) { IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); - rb.Push(ResultCode(ErrCodes::WrongStatus, ErrorModule::UDS, - ErrorSummary::InvalidState, ErrorLevel::Status)); + rb.Push(ResultCode(ErrCodes::WrongStatus, ErrorModule::UDS, ErrorSummary::InvalidState, + ErrorLevel::Status)); LOG_WARNING(Service_NWM, "called with status %u", connection_status.status); return; } @@ -867,8 +868,8 @@ void NWM_UDS::DisconnectNetwork(Kernel::HLERequestContext& ctx) { connection_status.status = static_cast(NetworkStatus::ConnectedAsHost); connection_status.network_node_id = tmp_node_id; LOG_DEBUG(Service_NWM, "called as a host"); - rb.Push(ResultCode(ErrCodes::WrongStatus, ErrorModule::UDS, - ErrorSummary::InvalidState, ErrorLevel::Status)); + rb.Push(ResultCode(ErrCodes::WrongStatus, ErrorModule::UDS, ErrorSummary::InvalidState, + ErrorLevel::Status)); return; } u16_le tmp_node_id = connection_status.network_node_id; @@ -906,8 +907,9 @@ void NWM_UDS::SendTo(Kernel::HLERequestContext& ctx) { u32 data_size = rp.Pop(); u32 flags = rp.Pop(); - const std::vector input_buffer = rp.PopStaticBuffer(); + std::vector input_buffer = rp.PopStaticBuffer(); ASSERT(input_buffer.size() >= data_size); + input_buffer.resize(data_size); IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); @@ -936,8 +938,9 @@ void NWM_UDS::SendTo(Kernel::HLERequestContext& ctx) { // TODO(B3N30): Increment the sequence number after each sent packet. u16 sequence_number = 0; - std::vector data_payload = GenerateDataPayload( - input_buffer, data_channel, dest_node_id, connection_status.network_node_id, sequence_number); + std::vector data_payload = + GenerateDataPayload(input_buffer, data_channel, dest_node_id, + connection_status.network_node_id, sequence_number); // TODO(B3N30): Retrieve the MAC address of the dest_node_id and our own to encrypt // and encapsulate the payload. @@ -965,6 +968,7 @@ void NWM_UDS::PullPacket(Kernel::HLERequestContext& ctx) { u32 max_out_buff_size_aligned = rp.Pop(); u32 max_out_buff_size = rp.Pop(); + u32 buff_size = std::min(max_out_buff_size_aligned, 0x172) << 2; std::lock_guard lock(connection_status_mutex); if (connection_status.status != static_cast(NetworkStatus::ConnectedAsHost) && @@ -989,7 +993,7 @@ void NWM_UDS::PullPacket(Kernel::HLERequestContext& ctx) { } if (channel->second.received_packets.empty()) { - std::vector output_buffer(max_out_buff_size, 0); + std::vector output_buffer(buff_size, 0); IPC::RequestBuilder rb = rp.MakeBuilder(3, 2); rb.Push(RESULT_SUCCESS); rb.Push(0); @@ -1012,11 +1016,10 @@ void NWM_UDS::PullPacket(Kernel::HLERequestContext& ctx) { IPC::RequestBuilder rb = rp.MakeBuilder(3, 2); - std::vector output_buffer(max_out_buff_size, 0); + std::vector output_buffer(buff_size, 0); // Write the actual data. std::memcpy(output_buffer.data(), - next_packet.data() + sizeof(LLCHeader) + sizeof(SecureDataHeader), - data_size); + next_packet.data() + sizeof(LLCHeader) + sizeof(SecureDataHeader), data_size); rb.Push(RESULT_SUCCESS); rb.Push(data_size); @@ -1061,8 +1064,9 @@ void NWM_UDS::ConnectToNetwork(Kernel::HLERequestContext& ctx) { // Since this timing is handled by core_timing it could differ from the 'real world' time static constexpr u64 UDSConnectionTimeout = 300000000; - connection_event = - ctx.SleepClientThread(Kernel::GetCurrentThread(), "uds::ConnectToNetwork", UDSConnectionTimeout, [](Kernel::SharedPtr thread, Kernel::HLERequestContext& ctx, + connection_event = ctx.SleepClientThread( + Kernel::GetCurrentThread(), "uds::ConnectToNetwork", UDSConnectionTimeout, + [](Kernel::SharedPtr thread, Kernel::HLERequestContext& ctx, ThreadWakeupReason reason) { // TODO(B3N30): Add error handling for host full and timeout IPC::RequestBuilder rb(ctx, 0x1E, 1, 0); @@ -1092,7 +1096,7 @@ void NWM_UDS::SetApplicationData(Kernel::HLERequestContext& ctx) { } network_info.application_data_size = size; - memcpy(network_info.application_data.data(), address.data(), size); + std::memcpy(network_info.application_data.data(), address.data(), size); rb.Push(RESULT_SUCCESS); } @@ -1104,10 +1108,8 @@ void NWM_UDS::DecryptBeaconData(Kernel::HLERequestContext& ctx) { ASSERT(network_struct_buffer.size() == sizeof(NetworkInfo)); const std::vector encrypted_data0_buffer = rp.PopStaticBuffer(); - const std::vector encrypted_data1_buffer = rp.PopStaticBuffer(); - LOG_DEBUG(Service_NWM, "called"); NetworkInfo net_info; @@ -1119,13 +1121,14 @@ void NWM_UDS::DecryptBeaconData(Kernel::HLERequestContext& ctx) { std::memcpy(oui.data(), encrypted_data0_buffer.data(), oui.size()); ASSERT_MSG(oui == NintendoOUI, "Unexpected OUI"); - ASSERT_MSG(encrypted_data0_buffer[3] == - static_cast(NintendoTagId::EncryptedData0), + ASSERT_MSG(encrypted_data0_buffer[3] == static_cast(NintendoTagId::EncryptedData0), "Unexpected tag id"); std::vector beacon_data(encrypted_data0_buffer.size() + encrypted_data1_buffer.size()); - std::memcpy(beacon_data.data(), encrypted_data0_buffer.data() + 4, encrypted_data0_buffer.size()); - std::memcpy(beacon_data.data() + encrypted_data0_buffer.size(), encrypted_data1_buffer.data() + 4, encrypted_data1_buffer.size()); + std::memcpy(beacon_data.data(), encrypted_data0_buffer.data() + 4, + encrypted_data0_buffer.size()); + std::memcpy(beacon_data.data() + encrypted_data0_buffer.size(), + encrypted_data1_buffer.data() + 4, encrypted_data1_buffer.size()); // Decrypt the data DecryptBeacon(net_info, beacon_data); @@ -1185,7 +1188,6 @@ static void BeaconBroadcastCallback(u64 userdata, int cycles_late) { beacon_broadcast_event, 0); } - NWM_UDS::NWM_UDS() : ServiceFramework("nwm::UDS") { static const FunctionInfo functions[] = { {0x000102C2, nullptr, "Initialize (deprecated)"}, diff --git a/src/core/hle/service/nwm/nwm_uds.h b/src/core/hle/service/nwm/nwm_uds.h index 4eaf6d515e..e389b96d09 100644 --- a/src/core/hle/service/nwm/nwm_uds.h +++ b/src/core/hle/service/nwm/nwm_uds.h @@ -103,7 +103,6 @@ public: ~NWM_UDS(); private: - void UpdateNetworkAttribute(Kernel::HLERequestContext& ctx); /** @@ -340,7 +339,6 @@ private: * 1 : Result of function, 0 on success, otherwise error code */ void DecryptBeaconData(Kernel::HLERequestContext& ctx); - }; } // namespace NWM diff --git a/src/core/hle/service/nwm/uds_data.cpp b/src/core/hle/service/nwm/uds_data.cpp index 6a693c0796..16d20166c2 100644 --- a/src/core/hle/service/nwm/uds_data.cpp +++ b/src/core/hle/service/nwm/uds_data.cpp @@ -187,8 +187,9 @@ static std::vector DecryptDataFrame(const std::vector& encrypted_payload d.SpecifyDataLengths(aad.size(), encrypted_payload.size() - 8, 0); CryptoPP::AuthenticatedDecryptionFilter df( - d, nullptr, CryptoPP::AuthenticatedDecryptionFilter::MAC_AT_END | - CryptoPP::AuthenticatedDecryptionFilter::THROW_EXCEPTION); + d, nullptr, + CryptoPP::AuthenticatedDecryptionFilter::MAC_AT_END | + CryptoPP::AuthenticatedDecryptionFilter::THROW_EXCEPTION); // put aad df.ChannelPut(CryptoPP::AAD_CHANNEL, aad.data(), aad.size()); From cc6a83621c8f0ff4b16b8eaf890550bbd4dbd200 Mon Sep 17 00:00:00 2001 From: B3n30 Date: Tue, 23 Jan 2018 23:38:57 +0100 Subject: [PATCH 06/11] fix clang --- src/core/hle/service/nwm/nwm_uds.cpp | 5 ++--- src/core/hle/service/nwm/uds_data.cpp | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/core/hle/service/nwm/nwm_uds.cpp b/src/core/hle/service/nwm/nwm_uds.cpp index 9d08edbd05..426ce6ad8f 100644 --- a/src/core/hle/service/nwm/nwm_uds.cpp +++ b/src/core/hle/service/nwm/nwm_uds.cpp @@ -554,9 +554,8 @@ void NWM_UDS::RecvBeaconBroadcastData(Kernel::HLERequestContext& ctx) { IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); rb.Push(RESULT_SUCCESS); - LOG_DEBUG(Service_NWM, - "called out_buffer_size=0x%08X, wlan_comm_id=0x%08X, id=0x%08X," - "input_handle=0x%08X, unk1=0x%08X, unk2=0x%08X, offset=%d", + LOG_DEBUG(Service_NWM, "called out_buffer_size=0x%08X, wlan_comm_id=0x%08X, id=0x%08X," + "input_handle=0x%08X, unk1=0x%08X, unk2=0x%08X, offset=%d", out_buffer_size, wlan_comm_id, id, input_handle, unk1, unk2, offset); } diff --git a/src/core/hle/service/nwm/uds_data.cpp b/src/core/hle/service/nwm/uds_data.cpp index 16d20166c2..6a693c0796 100644 --- a/src/core/hle/service/nwm/uds_data.cpp +++ b/src/core/hle/service/nwm/uds_data.cpp @@ -187,9 +187,8 @@ static std::vector DecryptDataFrame(const std::vector& encrypted_payload d.SpecifyDataLengths(aad.size(), encrypted_payload.size() - 8, 0); CryptoPP::AuthenticatedDecryptionFilter df( - d, nullptr, - CryptoPP::AuthenticatedDecryptionFilter::MAC_AT_END | - CryptoPP::AuthenticatedDecryptionFilter::THROW_EXCEPTION); + d, nullptr, CryptoPP::AuthenticatedDecryptionFilter::MAC_AT_END | + CryptoPP::AuthenticatedDecryptionFilter::THROW_EXCEPTION); // put aad df.ChannelPut(CryptoPP::AAD_CHANNEL, aad.data(), aad.size()); From cbf514190ec32794c16e2f9bd6aabfd8c7a2518f Mon Sep 17 00:00:00 2001 From: B3n30 Date: Thu, 15 Feb 2018 22:13:53 +0100 Subject: [PATCH 07/11] NWM_UDS: Addressed wwyleles comments --- src/core/hle/service/nwm/nwm_uds.cpp | 30 +++++++++++++++++----------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/src/core/hle/service/nwm/nwm_uds.cpp b/src/core/hle/service/nwm/nwm_uds.cpp index 426ce6ad8f..8b0ea61808 100644 --- a/src/core/hle/service/nwm/nwm_uds.cpp +++ b/src/core/hle/service/nwm/nwm_uds.cpp @@ -510,7 +510,11 @@ void NWM_UDS::RecvBeaconBroadcastData(Kernel::HLERequestContext& ctx) { u32 wlan_comm_id = rp.Pop(); u32 id = rp.Pop(); - Kernel::Handle input_handle = rp.PopHandle(); + // From 3dbrew: + // 'Official user processes create a new event handle which is then passed to this command. + // However, those user processes don't save that handle anywhere afterwards.' + // So we don't save/use that event too. + Kernel::SharedPtr input_event = rp.PopObject(); Kernel::MappedBuffer out_buffer = rp.PopMappedBuffer(); ASSERT(out_buffer.GetSize() == out_buffer_size); @@ -540,7 +544,7 @@ void NWM_UDS::RecvBeaconBroadcastData(Kernel::HLERequestContext& ctx) { out_buffer.Write(&entry, offset, sizeof(BeaconEntryHeader)); offset += sizeof(BeaconEntryHeader); const unsigned char* beacon_data = beacon.data.data(); - out_buffer.Write(const_cast(static_cast(beacon_data)), offset, + out_buffer.Write(beacon_data, offset, beacon.data.size()); offset += beacon.data.size(); @@ -551,12 +555,13 @@ void NWM_UDS::RecvBeaconBroadcastData(Kernel::HLERequestContext& ctx) { data_reply_header.total_size = total_size; out_buffer.Write(&data_reply_header, 0, sizeof(BeaconDataReplyHeader)); - IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); + IPC::RequestBuilder rb = rp.MakeBuilder(1, 1); rb.Push(RESULT_SUCCESS); + rb.PushMappedBuffer(out_buffer); LOG_DEBUG(Service_NWM, "called out_buffer_size=0x%08X, wlan_comm_id=0x%08X, id=0x%08X," - "input_handle=0x%08X, unk1=0x%08X, unk2=0x%08X, offset=%d", - out_buffer_size, wlan_comm_id, id, input_handle, unk1, unk2, offset); + "unk1=0x%08X, unk2=0x%08X, offset=%zu", + out_buffer_size, wlan_comm_id, id, unk1, unk2, offset); } void NWM_UDS::InitializeWithVersion(Kernel::HLERequestContext& ctx) { @@ -663,7 +668,7 @@ void NWM_UDS::Bind(Kernel::HLERequestContext& ctx) { IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); rb.Push(ResultCode(ErrorDescription::NotAuthorized, ErrorModule::UDS, ErrorSummary::WrongArgument, ErrorLevel::Usage)); - LOG_DEBUG(Service_NWM, "data_channel = %d, bind_node_id = %d", data_channel, bind_node_id); + LOG_WARNING(Service_NWM, "data_channel = %d, bind_node_id = %d", data_channel, bind_node_id); return; } @@ -672,7 +677,7 @@ void NWM_UDS::Bind(Kernel::HLERequestContext& ctx) { IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); rb.Push(ResultCode(ErrorDescription::OutOfMemory, ErrorModule::UDS, ErrorSummary::OutOfResource, ErrorLevel::Status)); - LOG_DEBUG(Service_NWM, "max bind nodes"); + LOG_WARNING(Service_NWM, "max bind nodes"); return; } @@ -681,7 +686,7 @@ void NWM_UDS::Bind(Kernel::HLERequestContext& ctx) { IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); rb.Push(ResultCode(ErrorDescription::TooLarge, ErrorModule::UDS, ErrorSummary::WrongArgument, ErrorLevel::Usage)); - LOG_DEBUG(Service_NWM, "MinRecvBufferSize"); + LOG_WARNING(Service_NWM, "MinRecvBufferSize"); return; } @@ -967,6 +972,7 @@ void NWM_UDS::PullPacket(Kernel::HLERequestContext& ctx) { u32 max_out_buff_size_aligned = rp.Pop(); u32 max_out_buff_size = rp.Pop(); + // This size is hard coded into the uds module. We don't know the meaning yet. u32 buff_size = std::min(max_out_buff_size_aligned, 0x172) << 2; std::lock_guard lock(connection_status_mutex); @@ -1123,11 +1129,11 @@ void NWM_UDS::DecryptBeaconData(Kernel::HLERequestContext& ctx) { ASSERT_MSG(encrypted_data0_buffer[3] == static_cast(NintendoTagId::EncryptedData0), "Unexpected tag id"); - std::vector beacon_data(encrypted_data0_buffer.size() + encrypted_data1_buffer.size()); + std::vector beacon_data(encrypted_data0_buffer.size() - 4 + encrypted_data1_buffer.size() - 4); std::memcpy(beacon_data.data(), encrypted_data0_buffer.data() + 4, - encrypted_data0_buffer.size()); - std::memcpy(beacon_data.data() + encrypted_data0_buffer.size(), - encrypted_data1_buffer.data() + 4, encrypted_data1_buffer.size()); + encrypted_data0_buffer.size() - 4); + std::memcpy(beacon_data.data() + encrypted_data0_buffer.size() - 4, + encrypted_data1_buffer.data() + 4, encrypted_data1_buffer.size() - 4); // Decrypt the data DecryptBeacon(net_info, beacon_data); From 237835a8b6d8f6e9543eedf8439789b0e3706e55 Mon Sep 17 00:00:00 2001 From: B3n30 Date: Thu, 15 Feb 2018 23:00:32 +0100 Subject: [PATCH 08/11] NWM_UDS: More of wwyleles comments --- src/core/hle/service/nwm/nwm_uds.cpp | 25 +++++++++++-------------- src/core/hle/service/nwm/nwm_uds.h | 2 ++ 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/core/hle/service/nwm/nwm_uds.cpp b/src/core/hle/service/nwm/nwm_uds.cpp index 8b0ea61808..e1fe0d17e1 100644 --- a/src/core/hle/service/nwm/nwm_uds.cpp +++ b/src/core/hle/service/nwm/nwm_uds.cpp @@ -519,8 +519,7 @@ void NWM_UDS::RecvBeaconBroadcastData(Kernel::HLERequestContext& ctx) { Kernel::MappedBuffer out_buffer = rp.PopMappedBuffer(); ASSERT(out_buffer.GetSize() == out_buffer_size); - size_t offset = sizeof(BeaconDataReplyHeader); - u32 total_size = sizeof(BeaconDataReplyHeader); + size_t cur_buffer_size = sizeof(BeaconDataReplyHeader); // Retrieve all beacon frames that were received from the desired mac address. auto beacons = GetReceivedBeacons(mac_address); @@ -539,20 +538,18 @@ void NWM_UDS::RecvBeaconBroadcastData(Kernel::HLERequestContext& ctx) { entry.header_size = sizeof(BeaconEntryHeader); entry.mac_address = beacon.transmitter_address; - ASSERT(offset < out_buffer_size); + ASSERT(cur_buffer_size < out_buffer_size); - out_buffer.Write(&entry, offset, sizeof(BeaconEntryHeader)); - offset += sizeof(BeaconEntryHeader); + out_buffer.Write(&entry, cur_buffer_size, sizeof(BeaconEntryHeader)); + cur_buffer_size += sizeof(BeaconEntryHeader); const unsigned char* beacon_data = beacon.data.data(); - out_buffer.Write(beacon_data, offset, + out_buffer.Write(beacon_data, cur_buffer_size, beacon.data.size()); - offset += beacon.data.size(); - - total_size += static_cast(sizeof(BeaconEntryHeader) + beacon.data.size()); + cur_buffer_size += beacon.data.size(); } // Update the total size in the structure and write it to the buffer again. - data_reply_header.total_size = total_size; + data_reply_header.total_size = cur_buffer_size; out_buffer.Write(&data_reply_header, 0, sizeof(BeaconDataReplyHeader)); IPC::RequestBuilder rb = rp.MakeBuilder(1, 1); @@ -561,7 +558,7 @@ void NWM_UDS::RecvBeaconBroadcastData(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_NWM, "called out_buffer_size=0x%08X, wlan_comm_id=0x%08X, id=0x%08X," "unk1=0x%08X, unk2=0x%08X, offset=%zu", - out_buffer_size, wlan_comm_id, id, unk1, unk2, offset); + out_buffer_size, wlan_comm_id, id, unk1, unk2, cur_buffer_size); } void NWM_UDS::InitializeWithVersion(Kernel::HLERequestContext& ctx) { @@ -1087,8 +1084,8 @@ void NWM_UDS::SetApplicationData(Kernel::HLERequestContext& ctx) { u32 size = rp.Pop(); - const std::vector address = rp.PopStaticBuffer(); - ASSERT(address.size() == size); + const std::vector application_data = rp.PopStaticBuffer(); + ASSERT(application_data.size() == size); LOG_DEBUG(Service_NWM, "called"); @@ -1101,7 +1098,7 @@ void NWM_UDS::SetApplicationData(Kernel::HLERequestContext& ctx) { } network_info.application_data_size = size; - std::memcpy(network_info.application_data.data(), address.data(), size); + std::memcpy(network_info.application_data.data(), application_data.data(), size); rb.Push(RESULT_SUCCESS); } diff --git a/src/core/hle/service/nwm/nwm_uds.h b/src/core/hle/service/nwm/nwm_uds.h index e389b96d09..763eb8dc07 100644 --- a/src/core/hle/service/nwm/nwm_uds.h +++ b/src/core/hle/service/nwm/nwm_uds.h @@ -181,6 +181,7 @@ private: * Outputs: * 0 : Return header * 1 : Result of function, 0 on success, otherwise error code + * 2, 3: output buffer return descriptor & ptr */ void RecvBeaconBroadcastData(Kernel::HLERequestContext& ctx); @@ -337,6 +338,7 @@ private: * Outputs: * 0 : Return header * 1 : Result of function, 0 on success, otherwise error code + * 2, 3: output buffer return descriptor & ptr */ void DecryptBeaconData(Kernel::HLERequestContext& ctx); }; From 7cb3d84a98be70b33ebcaeb7f1e1c2a2e790a113 Mon Sep 17 00:00:00 2001 From: B3n30 Date: Sat, 17 Feb 2018 12:54:48 +0100 Subject: [PATCH 09/11] HW checked signals Disconnect, Destroy and Shutdown --- src/core/hle/service/nwm/nwm_uds.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/core/hle/service/nwm/nwm_uds.cpp b/src/core/hle/service/nwm/nwm_uds.cpp index e1fe0d17e1..61c0666d36 100644 --- a/src/core/hle/service/nwm/nwm_uds.cpp +++ b/src/core/hle/service/nwm/nwm_uds.cpp @@ -483,7 +483,6 @@ void NWM_UDS::Shutdown(Kernel::HLERequestContext& ctx) { if (auto room_member = Network::GetRoomMember().lock()) room_member->Unbind(wifi_packet_received); - // TODO(B3N30): Check on HW if Shutdown signals those events for (auto bind_node : channel_data) { bind_node.second.event->Signal(); } @@ -843,7 +842,6 @@ void NWM_UDS::DestroyNetwork(Kernel::HLERequestContext& ctx) { IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); - // TODO(B3N30): HW test if events get signaled here. for (auto bind_node : channel_data) { bind_node.second.event->Signal(); } @@ -888,7 +886,6 @@ void NWM_UDS::DisconnectNetwork(Kernel::HLERequestContext& ctx) { SendPacket(deauth); - // TODO(B3N30): Check on HW if Shutdown signals those events for (auto bind_node : channel_data) { bind_node.second.event->Signal(); } From 853a79c94c623eff3533316e25a7c780f76d5177 Mon Sep 17 00:00:00 2001 From: B3n30 Date: Sat, 17 Feb 2018 13:45:52 +0100 Subject: [PATCH 10/11] clang-format fix --- src/core/hle/service/nwm/nwm_uds.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/core/hle/service/nwm/nwm_uds.cpp b/src/core/hle/service/nwm/nwm_uds.cpp index 61c0666d36..95e6f26dc6 100644 --- a/src/core/hle/service/nwm/nwm_uds.cpp +++ b/src/core/hle/service/nwm/nwm_uds.cpp @@ -542,8 +542,7 @@ void NWM_UDS::RecvBeaconBroadcastData(Kernel::HLERequestContext& ctx) { out_buffer.Write(&entry, cur_buffer_size, sizeof(BeaconEntryHeader)); cur_buffer_size += sizeof(BeaconEntryHeader); const unsigned char* beacon_data = beacon.data.data(); - out_buffer.Write(beacon_data, cur_buffer_size, - beacon.data.size()); + out_buffer.Write(beacon_data, cur_buffer_size, beacon.data.size()); cur_buffer_size += beacon.data.size(); } @@ -556,7 +555,7 @@ void NWM_UDS::RecvBeaconBroadcastData(Kernel::HLERequestContext& ctx) { rb.PushMappedBuffer(out_buffer); LOG_DEBUG(Service_NWM, "called out_buffer_size=0x%08X, wlan_comm_id=0x%08X, id=0x%08X," - "unk1=0x%08X, unk2=0x%08X, offset=%zu", + "unk1=0x%08X, unk2=0x%08X, offset=%zu", out_buffer_size, wlan_comm_id, id, unk1, unk2, cur_buffer_size); } @@ -664,7 +663,8 @@ void NWM_UDS::Bind(Kernel::HLERequestContext& ctx) { IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); rb.Push(ResultCode(ErrorDescription::NotAuthorized, ErrorModule::UDS, ErrorSummary::WrongArgument, ErrorLevel::Usage)); - LOG_WARNING(Service_NWM, "data_channel = %d, bind_node_id = %d", data_channel, bind_node_id); + LOG_WARNING(Service_NWM, "data_channel = %d, bind_node_id = %d", data_channel, + bind_node_id); return; } @@ -1123,7 +1123,8 @@ void NWM_UDS::DecryptBeaconData(Kernel::HLERequestContext& ctx) { ASSERT_MSG(encrypted_data0_buffer[3] == static_cast(NintendoTagId::EncryptedData0), "Unexpected tag id"); - std::vector beacon_data(encrypted_data0_buffer.size() - 4 + encrypted_data1_buffer.size() - 4); + std::vector beacon_data(encrypted_data0_buffer.size() - 4 + encrypted_data1_buffer.size() - + 4); std::memcpy(beacon_data.data(), encrypted_data0_buffer.data() + 4, encrypted_data0_buffer.size() - 4); std::memcpy(beacon_data.data() + encrypted_data0_buffer.size() - 4, From dfc22661a47c1b9b3c6f38e87b87612cbf782f57 Mon Sep 17 00:00:00 2001 From: wwylele Date: Thu, 22 Feb 2018 16:44:04 +0200 Subject: [PATCH 11/11] NWM_UDS: change SleepClientThread to use std::chrono::nanoseconds --- src/core/hle/service/nwm/nwm_uds.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/hle/service/nwm/nwm_uds.cpp b/src/core/hle/service/nwm/nwm_uds.cpp index 95e6f26dc6..43dbe59020 100644 --- a/src/core/hle/service/nwm/nwm_uds.cpp +++ b/src/core/hle/service/nwm/nwm_uds.cpp @@ -555,7 +555,7 @@ void NWM_UDS::RecvBeaconBroadcastData(Kernel::HLERequestContext& ctx) { rb.PushMappedBuffer(out_buffer); LOG_DEBUG(Service_NWM, "called out_buffer_size=0x%08X, wlan_comm_id=0x%08X, id=0x%08X," - "unk1=0x%08X, unk2=0x%08X, offset=%zu", + "unk1=0x%08X, unk2=0x%08X, offset=%zu", out_buffer_size, wlan_comm_id, id, unk1, unk2, cur_buffer_size); } @@ -1061,7 +1061,7 @@ void NWM_UDS::ConnectToNetwork(Kernel::HLERequestContext& ctx) { // 300 ms // Since this timing is handled by core_timing it could differ from the 'real world' time - static constexpr u64 UDSConnectionTimeout = 300000000; + static constexpr std::chrono::nanoseconds UDSConnectionTimeout{300000000}; connection_event = ctx.SleepClientThread( Kernel::GetCurrentThread(), "uds::ConnectToNetwork", UDSConnectionTimeout,