|
|
@@ -3,11 +3,15 @@
|
|
|
|
|
|
#include <memory>
|
|
|
|
|
|
-#include "core/hle/ipc_helpers.h"
|
|
|
-#include "core/hle/result.h"
|
|
|
-#include "core/hle/service/ldn/errors.h"
|
|
|
+#include "core/core.h"
|
|
|
#include "core/hle/service/ldn/ldn.h"
|
|
|
-#include "core/hle/service/sm/sm.h"
|
|
|
+#include "core/hle/service/ldn/ldn_results.h"
|
|
|
+#include "core/hle/service/ldn/ldn_types.h"
|
|
|
+#include "core/internal_network/network.h"
|
|
|
+#include "core/internal_network/network_interface.h"
|
|
|
+
|
|
|
+// This is defined by synchapi.h and conflicts with ServiceContext::CreateEvent
|
|
|
+#undef CreateEvent
|
|
|
|
|
|
namespace Service::LDN {
|
|
|
|
|
|
@@ -100,74 +104,418 @@ class IUserLocalCommunicationService final
|
|
|
: public ServiceFramework<IUserLocalCommunicationService> {
|
|
|
public:
|
|
|
explicit IUserLocalCommunicationService(Core::System& system_)
|
|
|
- : ServiceFramework{system_, "IUserLocalCommunicationService"} {
|
|
|
+ : ServiceFramework{system_, "IUserLocalCommunicationService", ServiceThreadType::CreateNew},
|
|
|
+ service_context{system, "IUserLocalCommunicationService"}, room_network{
|
|
|
+ system_.GetRoomNetwork()} {
|
|
|
// clang-format off
|
|
|
static const FunctionInfo functions[] = {
|
|
|
{0, &IUserLocalCommunicationService::GetState, "GetState"},
|
|
|
- {1, nullptr, "GetNetworkInfo"},
|
|
|
+ {1, &IUserLocalCommunicationService::GetNetworkInfo, "GetNetworkInfo"},
|
|
|
{2, nullptr, "GetIpv4Address"},
|
|
|
- {3, nullptr, "GetDisconnectReason"},
|
|
|
- {4, nullptr, "GetSecurityParameter"},
|
|
|
- {5, nullptr, "GetNetworkConfig"},
|
|
|
- {100, nullptr, "AttachStateChangeEvent"},
|
|
|
- {101, nullptr, "GetNetworkInfoLatestUpdate"},
|
|
|
- {102, nullptr, "Scan"},
|
|
|
- {103, nullptr, "ScanPrivate"},
|
|
|
+ {3, &IUserLocalCommunicationService::GetDisconnectReason, "GetDisconnectReason"},
|
|
|
+ {4, &IUserLocalCommunicationService::GetSecurityParameter, "GetSecurityParameter"},
|
|
|
+ {5, &IUserLocalCommunicationService::GetNetworkConfig, "GetNetworkConfig"},
|
|
|
+ {100, &IUserLocalCommunicationService::AttachStateChangeEvent, "AttachStateChangeEvent"},
|
|
|
+ {101, &IUserLocalCommunicationService::GetNetworkInfoLatestUpdate, "GetNetworkInfoLatestUpdate"},
|
|
|
+ {102, &IUserLocalCommunicationService::Scan, "Scan"},
|
|
|
+ {103, &IUserLocalCommunicationService::ScanPrivate, "ScanPrivate"},
|
|
|
{104, nullptr, "SetWirelessControllerRestriction"},
|
|
|
- {200, nullptr, "OpenAccessPoint"},
|
|
|
- {201, nullptr, "CloseAccessPoint"},
|
|
|
- {202, nullptr, "CreateNetwork"},
|
|
|
- {203, nullptr, "CreateNetworkPrivate"},
|
|
|
- {204, nullptr, "DestroyNetwork"},
|
|
|
+ {200, &IUserLocalCommunicationService::OpenAccessPoint, "OpenAccessPoint"},
|
|
|
+ {201, &IUserLocalCommunicationService::CloseAccessPoint, "CloseAccessPoint"},
|
|
|
+ {202, &IUserLocalCommunicationService::CreateNetwork, "CreateNetwork"},
|
|
|
+ {203, &IUserLocalCommunicationService::CreateNetworkPrivate, "CreateNetworkPrivate"},
|
|
|
+ {204, &IUserLocalCommunicationService::DestroyNetwork, "DestroyNetwork"},
|
|
|
{205, nullptr, "Reject"},
|
|
|
- {206, nullptr, "SetAdvertiseData"},
|
|
|
- {207, nullptr, "SetStationAcceptPolicy"},
|
|
|
- {208, nullptr, "AddAcceptFilterEntry"},
|
|
|
+ {206, &IUserLocalCommunicationService::SetAdvertiseData, "SetAdvertiseData"},
|
|
|
+ {207, &IUserLocalCommunicationService::SetStationAcceptPolicy, "SetStationAcceptPolicy"},
|
|
|
+ {208, &IUserLocalCommunicationService::AddAcceptFilterEntry, "AddAcceptFilterEntry"},
|
|
|
{209, nullptr, "ClearAcceptFilter"},
|
|
|
- {300, nullptr, "OpenStation"},
|
|
|
- {301, nullptr, "CloseStation"},
|
|
|
- {302, nullptr, "Connect"},
|
|
|
+ {300, &IUserLocalCommunicationService::OpenStation, "OpenStation"},
|
|
|
+ {301, &IUserLocalCommunicationService::CloseStation, "CloseStation"},
|
|
|
+ {302, &IUserLocalCommunicationService::Connect, "Connect"},
|
|
|
{303, nullptr, "ConnectPrivate"},
|
|
|
- {304, nullptr, "Disconnect"},
|
|
|
- {400, nullptr, "Initialize"},
|
|
|
- {401, nullptr, "Finalize"},
|
|
|
- {402, &IUserLocalCommunicationService::Initialize2, "Initialize2"}, // 7.0.0+
|
|
|
+ {304, &IUserLocalCommunicationService::Disconnect, "Disconnect"},
|
|
|
+ {400, &IUserLocalCommunicationService::Initialize, "Initialize"},
|
|
|
+ {401, &IUserLocalCommunicationService::Finalize, "Finalize"},
|
|
|
+ {402, &IUserLocalCommunicationService::Initialize2, "Initialize2"},
|
|
|
};
|
|
|
// clang-format on
|
|
|
|
|
|
RegisterHandlers(functions);
|
|
|
+
|
|
|
+ state_change_event =
|
|
|
+ service_context.CreateEvent("IUserLocalCommunicationService:StateChangeEvent");
|
|
|
+ }
|
|
|
+
|
|
|
+ ~IUserLocalCommunicationService() {
|
|
|
+ service_context.CloseEvent(state_change_event);
|
|
|
+ }
|
|
|
+
|
|
|
+ void OnEventFired() {
|
|
|
+ state_change_event->GetWritableEvent().Signal();
|
|
|
}
|
|
|
|
|
|
void GetState(Kernel::HLERequestContext& ctx) {
|
|
|
+ State state = State::Error;
|
|
|
+ LOG_WARNING(Service_LDN, "(STUBBED) called, state = {}", state);
|
|
|
+
|
|
|
+ IPC::ResponseBuilder rb{ctx, 3};
|
|
|
+ rb.Push(ResultSuccess);
|
|
|
+ rb.PushEnum(state);
|
|
|
+ }
|
|
|
+
|
|
|
+ void GetNetworkInfo(Kernel::HLERequestContext& ctx) {
|
|
|
+ const auto write_buffer_size = ctx.GetWriteBufferSize();
|
|
|
+
|
|
|
+ if (write_buffer_size != sizeof(NetworkInfo)) {
|
|
|
+ LOG_ERROR(Service_LDN, "Invalid buffer size {}", write_buffer_size);
|
|
|
+ IPC::ResponseBuilder rb{ctx, 2};
|
|
|
+ rb.Push(ResultBadInput);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ NetworkInfo network_info{};
|
|
|
+ const auto rc = ResultSuccess;
|
|
|
+ if (rc.IsError()) {
|
|
|
+ LOG_ERROR(Service_LDN, "NetworkInfo is not valid {}", rc.raw);
|
|
|
+ IPC::ResponseBuilder rb{ctx, 2};
|
|
|
+ rb.Push(rc);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ LOG_WARNING(Service_LDN, "(STUBBED) called, ssid='{}', nodes={}",
|
|
|
+ network_info.common.ssid.GetStringValue(), network_info.ldn.node_count);
|
|
|
+
|
|
|
+ ctx.WriteBuffer<NetworkInfo>(network_info);
|
|
|
+ IPC::ResponseBuilder rb{ctx, 2};
|
|
|
+ rb.Push(rc);
|
|
|
+ }
|
|
|
+
|
|
|
+ void GetDisconnectReason(Kernel::HLERequestContext& ctx) {
|
|
|
+ const auto disconnect_reason = DisconnectReason::None;
|
|
|
+
|
|
|
+ LOG_WARNING(Service_LDN, "(STUBBED) called, disconnect_reason={}", disconnect_reason);
|
|
|
+
|
|
|
+ IPC::ResponseBuilder rb{ctx, 3};
|
|
|
+ rb.Push(ResultSuccess);
|
|
|
+ rb.PushEnum(disconnect_reason);
|
|
|
+ }
|
|
|
+
|
|
|
+ void GetSecurityParameter(Kernel::HLERequestContext& ctx) {
|
|
|
+ SecurityParameter security_parameter{};
|
|
|
+ NetworkInfo info{};
|
|
|
+ const Result rc = ResultSuccess;
|
|
|
+
|
|
|
+ if (rc.IsError()) {
|
|
|
+ LOG_ERROR(Service_LDN, "NetworkInfo is not valid {}", rc.raw);
|
|
|
+ IPC::ResponseBuilder rb{ctx, 2};
|
|
|
+ rb.Push(rc);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ security_parameter.session_id = info.network_id.session_id;
|
|
|
+ std::memcpy(security_parameter.data.data(), info.ldn.security_parameter.data(),
|
|
|
+ sizeof(SecurityParameter::data));
|
|
|
+
|
|
|
LOG_WARNING(Service_LDN, "(STUBBED) called");
|
|
|
|
|
|
+ IPC::ResponseBuilder rb{ctx, 10};
|
|
|
+ rb.Push(rc);
|
|
|
+ rb.PushRaw<SecurityParameter>(security_parameter);
|
|
|
+ }
|
|
|
+
|
|
|
+ void GetNetworkConfig(Kernel::HLERequestContext& ctx) {
|
|
|
+ NetworkConfig config{};
|
|
|
+ NetworkInfo info{};
|
|
|
+ const Result rc = ResultSuccess;
|
|
|
+
|
|
|
+ if (rc.IsError()) {
|
|
|
+ LOG_ERROR(Service_LDN, "NetworkConfig is not valid {}", rc.raw);
|
|
|
+ IPC::ResponseBuilder rb{ctx, 2};
|
|
|
+ rb.Push(rc);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ config.intent_id = info.network_id.intent_id;
|
|
|
+ config.channel = info.common.channel;
|
|
|
+ config.node_count_max = info.ldn.node_count_max;
|
|
|
+ config.local_communication_version = info.ldn.nodes[0].local_communication_version;
|
|
|
+
|
|
|
+ LOG_WARNING(Service_LDN,
|
|
|
+ "(STUBBED) called, intent_id={}/{}, channel={}, node_count_max={}, "
|
|
|
+ "local_communication_version={}",
|
|
|
+ config.intent_id.local_communication_id, config.intent_id.scene_id,
|
|
|
+ config.channel, config.node_count_max, config.local_communication_version);
|
|
|
+
|
|
|
+ IPC::ResponseBuilder rb{ctx, 10};
|
|
|
+ rb.Push(rc);
|
|
|
+ rb.PushRaw<NetworkConfig>(config);
|
|
|
+ }
|
|
|
+
|
|
|
+ void AttachStateChangeEvent(Kernel::HLERequestContext& ctx) {
|
|
|
+ LOG_INFO(Service_LDN, "called");
|
|
|
+
|
|
|
+ IPC::ResponseBuilder rb{ctx, 2, 1};
|
|
|
+ rb.Push(ResultSuccess);
|
|
|
+ rb.PushCopyObjects(state_change_event->GetReadableEvent());
|
|
|
+ }
|
|
|
+
|
|
|
+ void GetNetworkInfoLatestUpdate(Kernel::HLERequestContext& ctx) {
|
|
|
+ const std::size_t network_buffer_size = ctx.GetWriteBufferSize(0);
|
|
|
+ const std::size_t node_buffer_count = ctx.GetWriteBufferSize(1) / sizeof(NodeLatestUpdate);
|
|
|
+
|
|
|
+ if (node_buffer_count == 0 || network_buffer_size != sizeof(NetworkInfo)) {
|
|
|
+ LOG_ERROR(Service_LDN, "Invalid buffer size {}, {}", network_buffer_size,
|
|
|
+ node_buffer_count);
|
|
|
+ IPC::ResponseBuilder rb{ctx, 2};
|
|
|
+ rb.Push(ResultBadInput);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ NetworkInfo info;
|
|
|
+ std::vector<NodeLatestUpdate> latest_update(node_buffer_count);
|
|
|
+
|
|
|
+ const auto rc = ResultSuccess;
|
|
|
+ if (rc.IsError()) {
|
|
|
+ LOG_ERROR(Service_LDN, "NetworkInfo is not valid {}", rc.raw);
|
|
|
+ IPC::ResponseBuilder rb{ctx, 2};
|
|
|
+ rb.Push(rc);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ LOG_WARNING(Service_LDN, "(STUBBED) called, ssid='{}', nodes={}",
|
|
|
+ info.common.ssid.GetStringValue(), info.ldn.node_count);
|
|
|
+
|
|
|
+ ctx.WriteBuffer(info, 0);
|
|
|
+ ctx.WriteBuffer(latest_update, 1);
|
|
|
+
|
|
|
+ IPC::ResponseBuilder rb{ctx, 2};
|
|
|
+ rb.Push(ResultSuccess);
|
|
|
+ }
|
|
|
+
|
|
|
+ void Scan(Kernel::HLERequestContext& ctx) {
|
|
|
+ ScanImpl(ctx);
|
|
|
+ }
|
|
|
+
|
|
|
+ void ScanPrivate(Kernel::HLERequestContext& ctx) {
|
|
|
+ ScanImpl(ctx, true);
|
|
|
+ }
|
|
|
+
|
|
|
+ void ScanImpl(Kernel::HLERequestContext& ctx, bool is_private = false) {
|
|
|
+ IPC::RequestParser rp{ctx};
|
|
|
+ const auto channel{rp.PopEnum<WifiChannel>()};
|
|
|
+ const auto scan_filter{rp.PopRaw<ScanFilter>()};
|
|
|
+
|
|
|
+ const std::size_t network_info_size = ctx.GetWriteBufferSize() / sizeof(NetworkInfo);
|
|
|
+
|
|
|
+ if (network_info_size == 0) {
|
|
|
+ LOG_ERROR(Service_LDN, "Invalid buffer size {}", network_info_size);
|
|
|
+ IPC::ResponseBuilder rb{ctx, 2};
|
|
|
+ rb.Push(ResultBadInput);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ u16 count = 0;
|
|
|
+ std::vector<NetworkInfo> network_infos(network_info_size);
|
|
|
+
|
|
|
+ LOG_WARNING(Service_LDN,
|
|
|
+ "(STUBBED) called, channel={}, filter_scan_flag={}, filter_network_type={}",
|
|
|
+ channel, scan_filter.flag, scan_filter.network_type);
|
|
|
+
|
|
|
+ ctx.WriteBuffer(network_infos);
|
|
|
+
|
|
|
IPC::ResponseBuilder rb{ctx, 3};
|
|
|
+ rb.Push(ResultSuccess);
|
|
|
+ rb.Push<u32>(count);
|
|
|
+ }
|
|
|
+
|
|
|
+ void OpenAccessPoint(Kernel::HLERequestContext& ctx) {
|
|
|
+ LOG_WARNING(Service_LDN, "(STUBBED) called");
|
|
|
+
|
|
|
+ IPC::ResponseBuilder rb{ctx, 2};
|
|
|
+ rb.Push(ResultSuccess);
|
|
|
+ }
|
|
|
+
|
|
|
+ void CloseAccessPoint(Kernel::HLERequestContext& ctx) {
|
|
|
+ LOG_WARNING(Service_LDN, "(STUBBED) called");
|
|
|
+
|
|
|
+ IPC::ResponseBuilder rb{ctx, 2};
|
|
|
+ rb.Push(ResultSuccess);
|
|
|
+ }
|
|
|
+
|
|
|
+ void CreateNetwork(Kernel::HLERequestContext& ctx) {
|
|
|
+ IPC::RequestParser rp{ctx};
|
|
|
+ struct Parameters {
|
|
|
+ SecurityConfig security_config;
|
|
|
+ UserConfig user_config;
|
|
|
+ INSERT_PADDING_WORDS_NOINIT(1);
|
|
|
+ NetworkConfig network_config;
|
|
|
+ };
|
|
|
+ static_assert(sizeof(Parameters) == 0x98, "Parameters has incorrect size.");
|
|
|
+
|
|
|
+ const auto parameters{rp.PopRaw<Parameters>()};
|
|
|
+
|
|
|
+ LOG_WARNING(Service_LDN,
|
|
|
+ "(STUBBED) called, passphrase_size={}, security_mode={}, "
|
|
|
+ "local_communication_version={}",
|
|
|
+ parameters.security_config.passphrase_size,
|
|
|
+ parameters.security_config.security_mode,
|
|
|
+ parameters.network_config.local_communication_version);
|
|
|
+
|
|
|
+ IPC::ResponseBuilder rb{ctx, 2};
|
|
|
+ rb.Push(ResultSuccess);
|
|
|
+ }
|
|
|
+
|
|
|
+ void CreateNetworkPrivate(Kernel::HLERequestContext& ctx) {
|
|
|
+ IPC::RequestParser rp{ctx};
|
|
|
+ struct Parameters {
|
|
|
+ SecurityConfig security_config;
|
|
|
+ SecurityParameter security_parameter;
|
|
|
+ UserConfig user_config;
|
|
|
+ NetworkConfig network_config;
|
|
|
+ };
|
|
|
+ static_assert(sizeof(Parameters) == 0xB8, "Parameters has incorrect size.");
|
|
|
+
|
|
|
+ const auto parameters{rp.PopRaw<Parameters>()};
|
|
|
+
|
|
|
+ LOG_WARNING(Service_LDN,
|
|
|
+ "(STUBBED) called, passphrase_size={}, security_mode={}, "
|
|
|
+ "local_communication_version={}",
|
|
|
+ parameters.security_config.passphrase_size,
|
|
|
+ parameters.security_config.security_mode,
|
|
|
+ parameters.network_config.local_communication_version);
|
|
|
+
|
|
|
+ IPC::ResponseBuilder rb{ctx, 2};
|
|
|
+ rb.Push(ResultSuccess);
|
|
|
+ }
|
|
|
+
|
|
|
+ void DestroyNetwork(Kernel::HLERequestContext& ctx) {
|
|
|
+ LOG_WARNING(Service_LDN, "(STUBBED) called");
|
|
|
+
|
|
|
+ IPC::ResponseBuilder rb{ctx, 2};
|
|
|
+ rb.Push(ResultSuccess);
|
|
|
+ }
|
|
|
+
|
|
|
+ void SetAdvertiseData(Kernel::HLERequestContext& ctx) {
|
|
|
+ std::vector<u8> read_buffer = ctx.ReadBuffer();
|
|
|
+
|
|
|
+ LOG_WARNING(Service_LDN, "(STUBBED) called, size {}", read_buffer.size());
|
|
|
+
|
|
|
+ IPC::ResponseBuilder rb{ctx, 2};
|
|
|
+ rb.Push(ResultSuccess);
|
|
|
+ }
|
|
|
+
|
|
|
+ void SetStationAcceptPolicy(Kernel::HLERequestContext& ctx) {
|
|
|
+ LOG_WARNING(Service_LDN, "(STUBBED) called");
|
|
|
+
|
|
|
+ IPC::ResponseBuilder rb{ctx, 2};
|
|
|
+ rb.Push(ResultSuccess);
|
|
|
+ }
|
|
|
|
|
|
- // Indicate a network error, as we do not actually emulate LDN
|
|
|
- rb.Push(static_cast<u32>(State::Error));
|
|
|
+ void AddAcceptFilterEntry(Kernel::HLERequestContext& ctx) {
|
|
|
+ LOG_WARNING(Service_LDN, "(STUBBED) called");
|
|
|
|
|
|
+ IPC::ResponseBuilder rb{ctx, 2};
|
|
|
+ rb.Push(ResultSuccess);
|
|
|
+ }
|
|
|
+
|
|
|
+ void OpenStation(Kernel::HLERequestContext& ctx) {
|
|
|
+ LOG_WARNING(Service_LDN, "(STUBBED) called");
|
|
|
+
|
|
|
+ IPC::ResponseBuilder rb{ctx, 2};
|
|
|
+ rb.Push(ResultSuccess);
|
|
|
+ }
|
|
|
+
|
|
|
+ void CloseStation(Kernel::HLERequestContext& ctx) {
|
|
|
+ LOG_WARNING(Service_LDN, "(STUBBED) called");
|
|
|
+
|
|
|
+ IPC::ResponseBuilder rb{ctx, 2};
|
|
|
+ rb.Push(ResultSuccess);
|
|
|
+ }
|
|
|
+
|
|
|
+ void Connect(Kernel::HLERequestContext& ctx) {
|
|
|
+ IPC::RequestParser rp{ctx};
|
|
|
+ struct Parameters {
|
|
|
+ SecurityConfig security_config;
|
|
|
+ UserConfig user_config;
|
|
|
+ u32 local_communication_version;
|
|
|
+ u32 option;
|
|
|
+ };
|
|
|
+ static_assert(sizeof(Parameters) == 0x7C, "Parameters has incorrect size.");
|
|
|
+
|
|
|
+ const auto parameters{rp.PopRaw<Parameters>()};
|
|
|
+
|
|
|
+ LOG_WARNING(Service_LDN,
|
|
|
+ "(STUBBED) called, passphrase_size={}, security_mode={}, "
|
|
|
+ "local_communication_version={}",
|
|
|
+ parameters.security_config.passphrase_size,
|
|
|
+ parameters.security_config.security_mode,
|
|
|
+ parameters.local_communication_version);
|
|
|
+
|
|
|
+ const std::vector<u8> read_buffer = ctx.ReadBuffer();
|
|
|
+ NetworkInfo network_info{};
|
|
|
+
|
|
|
+ if (read_buffer.size() != sizeof(NetworkInfo)) {
|
|
|
+ LOG_ERROR(Frontend, "NetworkInfo doesn't match read_buffer size!");
|
|
|
+ IPC::ResponseBuilder rb{ctx, 2};
|
|
|
+ rb.Push(ResultBadInput);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ std::memcpy(&network_info, read_buffer.data(), read_buffer.size());
|
|
|
+
|
|
|
+ IPC::ResponseBuilder rb{ctx, 2};
|
|
|
+ rb.Push(ResultSuccess);
|
|
|
+ }
|
|
|
+
|
|
|
+ void Disconnect(Kernel::HLERequestContext& ctx) {
|
|
|
+ LOG_WARNING(Service_LDN, "(STUBBED) called");
|
|
|
+
|
|
|
+ IPC::ResponseBuilder rb{ctx, 2};
|
|
|
+ rb.Push(ResultSuccess);
|
|
|
+ }
|
|
|
+ void Initialize(Kernel::HLERequestContext& ctx) {
|
|
|
+ LOG_WARNING(Service_LDN, "(STUBBED) called");
|
|
|
+
|
|
|
+ const auto rc = InitializeImpl(ctx);
|
|
|
+
|
|
|
+ IPC::ResponseBuilder rb{ctx, 2};
|
|
|
+ rb.Push(rc);
|
|
|
+ }
|
|
|
+
|
|
|
+ void Finalize(Kernel::HLERequestContext& ctx) {
|
|
|
+ LOG_WARNING(Service_LDN, "(STUBBED) called");
|
|
|
+
|
|
|
+ is_initialized = false;
|
|
|
+
|
|
|
+ IPC::ResponseBuilder rb{ctx, 2};
|
|
|
rb.Push(ResultSuccess);
|
|
|
}
|
|
|
|
|
|
void Initialize2(Kernel::HLERequestContext& ctx) {
|
|
|
- LOG_DEBUG(Service_LDN, "called");
|
|
|
+ LOG_WARNING(Service_LDN, "(STUBBED) called");
|
|
|
|
|
|
- is_initialized = true;
|
|
|
+ const auto rc = InitializeImpl(ctx);
|
|
|
|
|
|
IPC::ResponseBuilder rb{ctx, 2};
|
|
|
- rb.Push(ERROR_DISABLED);
|
|
|
+ rb.Push(rc);
|
|
|
+ }
|
|
|
+
|
|
|
+ Result InitializeImpl(Kernel::HLERequestContext& ctx) {
|
|
|
+ const auto network_interface = Network::GetSelectedNetworkInterface();
|
|
|
+ if (!network_interface) {
|
|
|
+ LOG_ERROR(Service_LDN, "No network interface is set");
|
|
|
+ return ResultAirplaneModeEnabled;
|
|
|
+ }
|
|
|
+
|
|
|
+ is_initialized = true;
|
|
|
+ // TODO (flTobi): Change this to ResultSuccess when LDN is fully implemented
|
|
|
+ return ResultAirplaneModeEnabled;
|
|
|
}
|
|
|
|
|
|
-private:
|
|
|
- enum class State {
|
|
|
- None,
|
|
|
- Initialized,
|
|
|
- AccessPointOpened,
|
|
|
- AccessPointCreated,
|
|
|
- StationOpened,
|
|
|
- StationConnected,
|
|
|
- Error,
|
|
|
- };
|
|
|
+ KernelHelpers::ServiceContext service_context;
|
|
|
+ Kernel::KEvent* state_change_event;
|
|
|
+ Network::RoomNetwork& room_network;
|
|
|
|
|
|
bool is_initialized{};
|
|
|
};
|
|
|
@@ -273,7 +621,7 @@ public:
|
|
|
LOG_WARNING(Service_LDN, "(STUBBED) called");
|
|
|
|
|
|
IPC::ResponseBuilder rb{ctx, 2};
|
|
|
- rb.Push(ERROR_DISABLED);
|
|
|
+ rb.Push(ResultDisabled);
|
|
|
}
|
|
|
};
|
|
|
|