Implement network interface services

nifm:u is used by applications to enable a connection to the network.
This commit is contained in:
Billy Laws 2020-07-09 14:31:04 +01:00 committed by ◱ PixelyIon
parent 7102fa910e
commit 2aefb4ae84
9 changed files with 161 additions and 0 deletions

View File

@ -119,6 +119,9 @@ add_library(skyline SHARED
${source_DIR}/skyline/services/friends/IFriendService.cpp ${source_DIR}/skyline/services/friends/IFriendService.cpp
${source_DIR}/skyline/services/nfp/IUserManager.cpp ${source_DIR}/skyline/services/nfp/IUserManager.cpp
${source_DIR}/skyline/services/nfp/IUser.cpp ${source_DIR}/skyline/services/nfp/IUser.cpp
${source_DIR}/skyline/services/nifm/IStaticService.cpp
${source_DIR}/skyline/services/nifm/IGeneralService.cpp
${source_DIR}/skyline/services/nifm/IRequest.cpp
${source_DIR}/skyline/vfs/partition_filesystem.cpp ${source_DIR}/skyline/vfs/partition_filesystem.cpp
${source_DIR}/skyline/vfs/rom_filesystem.cpp ${source_DIR}/skyline/vfs/rom_filesystem.cpp
${source_DIR}/skyline/vfs/os_backing.cpp ${source_DIR}/skyline/vfs/os_backing.cpp

View File

@ -75,6 +75,9 @@ namespace skyline::service {
friends_IFriendService, friends_IFriendService,
nfp_IUserManager, nfp_IUserManager,
nfp_IUser, nfp_IUser,
nifm_IStaticService,
nifm_IGeneralService,
nifm_IRequest,
}; };
/** /**
@ -111,6 +114,7 @@ namespace skyline::service {
{"acc:u0", Service::account_IAccountServiceForApplication}, {"acc:u0", Service::account_IAccountServiceForApplication},
{"friend:u", Service::friends_IServiceCreator}, {"friend:u", Service::friends_IServiceCreator},
{"nfp:user", Service::nfp_IUserManager}, {"nfp:user", Service::nfp_IUserManager},
{"nifm:u", Service::nifm_IStaticService},
}; };
class ServiceManager; class ServiceManager;

View File

@ -0,0 +1,15 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
#include "IRequest.h"
#include "IGeneralService.h"
namespace skyline::service::nifm {
IGeneralService::IGeneralService(const DeviceState &state, ServiceManager &manager) : BaseService(state, manager, Service::nifm_IGeneralService, "nifm:IGeneralService", {
{0x4, SFUNC(IGeneralService::CreateRequest)}
}) {}
void IGeneralService::CreateRequest(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
manager.RegisterService(SRVREG(IRequest), session, response);
}
}

View File

@ -0,0 +1,22 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
#pragma once
#include <services/base_service.h>
#include <services/serviceman.h>
namespace skyline::service::nifm {
/**
* @brief IGeneralService is used by applications to control the network connection (https://switchbrew.org/wiki/Network_Interface_services#IGeneralService)
*/
class IGeneralService : public BaseService {
public:
IGeneralService(const DeviceState &state, ServiceManager &manager);
/**
* @brief This creates an IRequest instance that can be used to bring up the network (https://switchbrew.org/wiki/Network_Interface_services#CreateRequest)
*/
void CreateRequest(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
};
}

View File

@ -0,0 +1,33 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
#include <kernel/types/KProcess.h>
#include "IRequest.h"
namespace skyline::service::nifm {
IRequest::IRequest(const DeviceState &state, ServiceManager &manager) : event0(std::make_shared<type::KEvent>(state)), event1(std::make_shared<type::KEvent>(state)), BaseService(state, manager, Service::nifm_IRequest, "nifm:IRequest", {
{0x0, SFUNC(IRequest::GetRequestState)},
{0x1, SFUNC(IRequest::GetResult)},
{0x2, SFUNC(IRequest::GetSystemEventReadableHandles)},
{0x4, SFUNC(IRequest::Submit)},
}) {}
void IRequest::GetRequestState(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
constexpr u32 Unsubmitted = 1; //!< The request has not been submitted
response.Push<u32>(Unsubmitted);
}
void IRequest::GetResult(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {}
void IRequest::GetSystemEventReadableHandles(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
auto handle = state.process->InsertItem(event0);
state.logger->Debug("Request Event 0 Handle: 0x{:X}", handle);
response.copyHandles.push_back(handle);
handle = state.process->InsertItem(event1);
state.logger->Debug("Request Event 1 Handle: 0x{:X}", handle);
response.copyHandles.push_back(handle);
}
void IRequest::Submit(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {}
}

View File

@ -0,0 +1,42 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
#pragma once
#include <kernel/types/KEvent.h>
#include <services/base_service.h>
#include <services/serviceman.h>
namespace skyline::service::nifm {
/**
* @brief IRequest is used by applications to bring up a network (https://switchbrew.org/wiki/Network_Interface_services#IRequest)
*/
class IRequest : public BaseService {
private:
std::shared_ptr<type::KEvent> event0; //!< The KEvent that is signalled on request state changes
std::shared_ptr<type::KEvent> event1; //!< The KEvent that is signalled on request changes
public:
IRequest(const DeviceState &state, ServiceManager &manager);
/**
* @brief This returns the current state of the request (https://switchbrew.org/wiki/Network_Interface_services#GetRequestState)
*/
void GetRequestState(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This returns the error code if a network bring up request fails (https://switchbrew.org/wiki/Network_Interface_services#GetResult)
*/
void GetResult(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This returns two KEvent handles that signal request on request updates (https://switchbrew.org/wiki/Network_Interface_services#GetSystemEventReadableHandles)
*/
void GetSystemEventReadableHandles(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This submits a request to bring up a network (https://switchbrew.org/wiki/Network_Interface_services#Submit)
*/
void Submit(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
};
}

View File

@ -0,0 +1,16 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
#include "IGeneralService.h"
#include "IStaticService.h"
namespace skyline::service::nifm {
IStaticService::IStaticService(const DeviceState &state, ServiceManager &manager) : BaseService(state, manager, Service::nifm_IStaticService, "nifm:IStaticService", {
{0x4, SFUNC(IStaticService::CreateGeneralService)},
{0x5, SFUNC(IStaticService::CreateGeneralService)}
}) {}
void IStaticService::CreateGeneralService(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
manager.RegisterService(SRVREG(IGeneralService), session, response);
}
}

View File

@ -0,0 +1,22 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
#pragma once
#include <services/base_service.h>
#include <services/serviceman.h>
namespace skyline::service::nifm {
/**
* @brief IStaticService or nifm:u is used by applications to open an IGeneralService instance for controlling the network connection (https://switchbrew.org/wiki/Network_Interface_services#IGeneralService)
*/
class IStaticService : public BaseService {
public:
IStaticService(const DeviceState &state, ServiceManager &manager);
/**
* @brief This opens an IGeneralService that can be used by applications to control the network connection (https://switchbrew.org/wiki/Network_Interface_services#CreateGeneralServiceOld)
*/
void CreateGeneralService(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
};
}

View File

@ -23,6 +23,7 @@
#include "account/IAccountServiceForApplication.h" #include "account/IAccountServiceForApplication.h"
#include "friends/IServiceCreator.h" #include "friends/IServiceCreator.h"
#include "nfp/IUserManager.h" #include "nfp/IUserManager.h"
#include "nifm/IStaticService.h"
#include "serviceman.h" #include "serviceman.h"
namespace skyline::service { namespace skyline::service {
@ -98,6 +99,9 @@ namespace skyline::service {
case Service::nfp_IUserManager: case Service::nfp_IUserManager:
serviceObj = std::make_shared<nfp::IUserManager>(state, *this); serviceObj = std::make_shared<nfp::IUserManager>(state, *this);
break; break;
case Service::nifm_IStaticService:
serviceObj = std::make_shared<nifm::IStaticService>(state, *this);
break;
default: default:
throw exception("CreateService called on missing object, type: {}", serviceType); throw exception("CreateService called on missing object, type: {}", serviceType);
} }