diff --git a/src/core/core.cpp b/src/core/core.cpp index b61c2a589..00e79ae8b 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -413,6 +413,7 @@ System::ResultStatus System::Load(Frontend::EmuWindow& emu_window, const std::st apt->GetAppletManager()->SetSysMenuArg(restore_sys_menu_arg.value()); restore_sys_menu_arg.reset(); } + apt->SetWirelessRebootInfoBuffer(restore_wireless_reboot_info); } if (restore_plugin_context.has_value()) { @@ -737,6 +738,7 @@ void System::Reset() { if (auto apt = Service::APT::GetModule(*this)) { restore_deliver_arg = apt->GetAppletManager()->ReceiveDeliverArg(); restore_sys_menu_arg = apt->GetAppletManager()->GetSysMenuArg(); + restore_wireless_reboot_info = apt->GetWirelessRebootInfoBuffer(); } if (auto plg_ldr = Service::PLGLDR::GetService(*this)) { restore_plugin_context = plg_ldr->GetPluginLoaderContext(); diff --git a/src/core/core.h b/src/core/core.h index b33fea174..085a7b3b0 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -489,6 +489,7 @@ private: boost::optional restore_sys_menu_arg; boost::optional restore_plugin_context; std::unique_ptr restore_ipc_recorder; + std::vector restore_wireless_reboot_info; std::vector lle_modules; diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp index 14035af1a..fcc9b2a89 100644 --- a/src/core/hle/service/apt/apt.cpp +++ b/src/core/hle/service/apt/apt.cpp @@ -1493,6 +1493,14 @@ std::shared_ptr Module::GetAppletManager() const { return applet_manager; } +std::vector Module::GetWirelessRebootInfoBuffer() const { + return wireless_reboot_info; +} + +void Module::SetWirelessRebootInfoBuffer(std::vector info_buf) { + wireless_reboot_info = info_buf; +} + std::shared_ptr GetModule(Core::System& system) { auto apt = system.ServiceManager().GetService("APT:A"); if (!apt) diff --git a/src/core/hle/service/apt/apt.h b/src/core/hle/service/apt/apt.h index 376b113f0..85b92bb60 100644 --- a/src/core/hle/service/apt/apt.h +++ b/src/core/hle/service/apt/apt.h @@ -51,6 +51,9 @@ public: std::shared_ptr GetAppletManager() const; + std::vector GetWirelessRebootInfoBuffer() const; + void SetWirelessRebootInfoBuffer(std::vector info_buf); + class NSInterface : public ServiceFramework { public: NSInterface(std::shared_ptr apt, const char* name, u32 max_session); diff --git a/src/core/hle/service/nwm/nwm_uds.cpp b/src/core/hle/service/nwm/nwm_uds.cpp index 1672feee3..43547ee42 100644 --- a/src/core/hle/service/nwm/nwm_uds.cpp +++ b/src/core/hle/service/nwm/nwm_uds.cpp @@ -613,76 +613,6 @@ void NWM_UDS::Shutdown(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_NWM, "called"); } -void NWM_UDS::RecvBeaconBroadcastData(Kernel::HLERequestContext& ctx) { - IPC::RequestParser rp(ctx); - - u32 out_buffer_size = rp.Pop(); - - // scan input struct - u32 unk1 = rp.Pop(); - u32 unk2 = rp.Pop(); - - MacAddress mac_address; - rp.PopRaw(mac_address); - - // uninitialized data in scan input struct - rp.Skip(9, false); - - // end scan input struct - - u32 wlan_comm_id = rp.Pop(); - u32 id = rp.Pop(); - // 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. - std::shared_ptr input_event = rp.PopObject(); - - Kernel::MappedBuffer out_buffer = rp.PopMappedBuffer(); - ASSERT(out_buffer.GetSize() == out_buffer_size); - - std::size_t cur_buffer_size = sizeof(BeaconDataReplyHeader); - - // Retrieve all beacon frames that were received from the desired mac address. - auto beacons = GetReceivedBeacons(mac_address); - - BeaconDataReplyHeader data_reply_header{}; - data_reply_header.total_entries = static_cast(beacons.size()); - data_reply_header.max_output_size = out_buffer_size; - - // Write each of the received beacons into the buffer - for (const auto& beacon : beacons) { - BeaconEntryHeader entry{}; - // TODO(Subv): Figure out what this size is used for. - entry.unk_size = static_cast(sizeof(BeaconEntryHeader) + beacon.data.size()); - entry.total_size = static_cast(sizeof(BeaconEntryHeader) + beacon.data.size()); - entry.wifi_channel = beacon.channel; - entry.header_size = sizeof(BeaconEntryHeader); - entry.mac_address = beacon.transmitter_address; - - ASSERT(cur_buffer_size < out_buffer_size); - - 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()); - 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 = static_cast(cur_buffer_size); - out_buffer.Write(&data_reply_header, 0, sizeof(BeaconDataReplyHeader)); - - IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); - rb.Push(ResultSuccess); - 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={}", - out_buffer_size, wlan_comm_id, id, unk1, unk2, cur_buffer_size); -} - ResultVal> NWM_UDS::Initialize( u32 sharedmem_size, const NodeInfo& node, u16 version, std::shared_ptr sharedmem) { @@ -1307,6 +1237,82 @@ private: friend class boost::serialization::access; }; +void NWM_UDS::RecvBeaconBroadcastData(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx); + + u32 out_buffer_size = rp.Pop(); + + // scan input struct + u32 unk1 = rp.Pop(); + u32 unk2 = rp.Pop(); + + MacAddress mac_address; + rp.PopRaw(mac_address); + + // uninitialized data in scan input struct + rp.Skip(9, false); + + // end scan input struct + + u32 wlan_comm_id = rp.Pop(); + u32 id = rp.Pop(); + // 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. + std::shared_ptr input_event = rp.PopObject(); + + Kernel::MappedBuffer out_buffer = rp.PopMappedBuffer(); + ASSERT(out_buffer.GetSize() == out_buffer_size); + + std::size_t cur_buffer_size = sizeof(BeaconDataReplyHeader); + + // on a real 3ds this is about 0.38 seconds + static constexpr std::chrono::nanoseconds UDSBeaconScanInterval{300000000}; + + ctx.SleepClientThread("uds::RecvBeaconBroadcastData", UDSBeaconScanInterval, + std::make_shared(0xF)); + + // Retrieve all beacon frames that were received from the desired mac address. + auto beacons = GetReceivedBeacons(mac_address); + + BeaconDataReplyHeader data_reply_header{}; + data_reply_header.total_entries = static_cast(beacons.size()); + data_reply_header.max_output_size = out_buffer_size; + + // Write each of the received beacons into the buffer + for (const auto& beacon : beacons) { + BeaconEntryHeader entry{}; + // TODO(Subv): Figure out what this size is used for. + entry.unk_size = static_cast(sizeof(BeaconEntryHeader) + beacon.data.size()); + entry.total_size = static_cast(sizeof(BeaconEntryHeader) + beacon.data.size()); + entry.wifi_channel = beacon.channel; + entry.header_size = sizeof(BeaconEntryHeader); + entry.mac_address = beacon.transmitter_address; + + ASSERT(cur_buffer_size < out_buffer_size); + + 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()); + 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 = static_cast(cur_buffer_size); + out_buffer.Write(&data_reply_header, 0, sizeof(BeaconDataReplyHeader)); + + IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); + rb.Push(ResultSuccess); + 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={}", + out_buffer_size, wlan_comm_id, id, unk1, unk2, cur_buffer_size); +} + void NWM_UDS::ConnectToNetwork(Kernel::HLERequestContext& ctx, u16 command_id, std::span network_info_buffer, u8 connection_type, std::vector passphrase) {