citra-emu
/
citra
Archived
1
0
Fork 0

Merge pull request #3476 from wwylele/nfc-new-framework

Service/NFC: convert to ServiceFramework
This commit is contained in:
Weiyi Wang 2018-03-09 19:01:12 +02:00 committed by GitHub
commit ebb8a9b8f0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 272 additions and 260 deletions

View File

@ -2,10 +2,8 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "core/hle/ipc.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/event.h"
#include "core/hle/kernel/handle_table.h"
#include "core/hle/service/nfc/nfc.h"
#include "core/hle/service/nfc/nfc_m.h"
#include "core/hle/service/nfc/nfc_u.h"
@ -13,48 +11,46 @@
namespace Service {
namespace NFC {
static Kernel::SharedPtr<Kernel::Event> tag_in_range_event;
static Kernel::SharedPtr<Kernel::Event> tag_out_of_range_event;
static TagState nfc_tag_state = TagState::NotInitialized;
static CommunicationStatus nfc_status = CommunicationStatus::NfcInitialized;
void Module::Interface::Initialize(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x01, 1, 0);
u8 param = rp.Pop<u8>();
void Initialize(Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer();
nfc->nfc_tag_state = TagState::NotScanning;
u8 param = static_cast<u8>(cmd_buff[1] & 0xFF);
nfc_tag_state = TagState::NotScanning;
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
rb.Push(RESULT_SUCCESS);
LOG_WARNING(Service_NFC, "(STUBBED) called, param=%u", param);
}
void Shutdown(Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer();
void Module::Interface::Shutdown(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x02, 1, 0);
u8 param = rp.Pop<u8>();
u8 param = static_cast<u8>(cmd_buff[1] & 0xFF);
nfc_tag_state = TagState::NotInitialized;
nfc->nfc_tag_state = TagState::NotInitialized;
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
rb.Push(RESULT_SUCCESS);
LOG_WARNING(Service_NFC, "(STUBBED) called, param=%u", param);
}
void StartCommunication(Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer();
void Module::Interface::StartCommunication(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x03, 0, 0);
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
rb.Push(RESULT_SUCCESS);
LOG_WARNING(Service_NFC, "(STUBBED) called");
}
void StopCommunication(Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer();
void Module::Interface::StopCommunication(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x04, 0, 0);
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
rb.Push(RESULT_SUCCESS);
LOG_WARNING(Service_NFC, "(STUBBED) called");
}
void StartTagScanning(Interface* self) {
IPC::RequestParser rp(Kernel::GetCommandBuffer(), 5, 1, 0); // 0x00050040
void Module::Interface::StartTagScanning(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x05, 1, 0); // 0x00050040
u16 in_val = rp.Pop<u16>();
ResultCode result = RESULT_SUCCESS;
@ -64,8 +60,8 @@ void StartTagScanning(Interface* self) {
ErrorSummary::InvalidState, ErrorLevel::Status);
if (result == RESULT_SUCCESS) {
nfc_tag_state = TagState::TagInRange;
tag_in_range_event->Signal();
nfc->nfc_tag_state = TagState::TagInRange;
nfc->tag_in_range_event->Signal();
}
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
@ -73,83 +69,90 @@ void StartTagScanning(Interface* self) {
LOG_WARNING(Service_NFC, "(STUBBED) called, in_val=%04x", in_val);
}
void StopTagScanning(Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer();
void Module::Interface::StopTagScanning(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x06, 0, 0);
nfc_tag_state = TagState::NotScanning;
nfc->nfc_tag_state = TagState::NotScanning;
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
rb.Push(RESULT_SUCCESS);
LOG_WARNING(Service_NFC, "(STUBBED) called");
}
void LoadAmiiboData(Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer();
void Module::Interface::LoadAmiiboData(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x07, 0, 0);
nfc_tag_state = TagState::TagDataLoaded;
nfc->nfc_tag_state = TagState::TagDataLoaded;
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
rb.Push(RESULT_SUCCESS);
LOG_WARNING(Service_NFC, "(STUBBED) called");
}
void ResetTagScanState(Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer();
void Module::Interface::ResetTagScanState(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x08, 0, 0);
nfc_tag_state = TagState::NotScanning;
nfc->nfc_tag_state = TagState::NotScanning;
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
rb.Push(RESULT_SUCCESS);
LOG_WARNING(Service_NFC, "(STUBBED) called");
}
void GetTagInRangeEvent(Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer();
void Module::Interface::GetTagInRangeEvent(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x0B, 0, 0);
cmd_buff[0] = IPC::MakeHeader(0xB, 1, 2);
cmd_buff[1] = RESULT_SUCCESS.raw;
cmd_buff[2] = IPC::CopyHandleDesc();
cmd_buff[3] = Kernel::g_handle_table.Create(tag_in_range_event).Unwrap();
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
rb.Push(RESULT_SUCCESS);
rb.PushCopyObjects(nfc->tag_in_range_event);
LOG_WARNING(Service_NFC, "(STUBBED) called");
}
void GetTagOutOfRangeEvent(Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer();
void Module::Interface::GetTagOutOfRangeEvent(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x0C, 0, 0);
cmd_buff[0] = IPC::MakeHeader(0xC, 1, 2);
cmd_buff[1] = RESULT_SUCCESS.raw;
cmd_buff[2] = IPC::CopyHandleDesc();
cmd_buff[3] = Kernel::g_handle_table.Create(tag_out_of_range_event).Unwrap();
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
rb.Push(RESULT_SUCCESS);
rb.PushCopyObjects(nfc->tag_out_of_range_event);
LOG_WARNING(Service_NFC, "(STUBBED) called");
}
void GetTagState(Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer();
void Module::Interface::GetTagState(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x0D, 0, 0);
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
cmd_buff[2] = static_cast<u8>(nfc_tag_state);
IPC::RequestBuilder rb = rp.MakeBuilder(2, 0);
rb.Push(RESULT_SUCCESS);
rb.PushEnum(nfc->nfc_tag_state);
LOG_DEBUG(Service_NFC, "(STUBBED) called");
}
void CommunicationGetStatus(Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer();
void Module::Interface::CommunicationGetStatus(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x0F, 0, 0);
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
cmd_buff[2] = static_cast<u8>(nfc_status);
IPC::RequestBuilder rb = rp.MakeBuilder(2, 0);
rb.Push(RESULT_SUCCESS);
rb.PushEnum(nfc->nfc_status);
LOG_DEBUG(Service_NFC, "(STUBBED) called");
}
void Init() {
AddService(new NFC_M());
AddService(new NFC_U());
Module::Interface::Interface(std::shared_ptr<Module> nfc, const char* name, u32 max_session)
: ServiceFramework(name, max_session), nfc(std::move(nfc)) {}
Module::Interface::~Interface() = default;
Module::Module() {
tag_in_range_event =
Kernel::Event::Create(Kernel::ResetType::OneShot, "NFC::tag_in_range_event");
tag_out_of_range_event =
Kernel::Event::Create(Kernel::ResetType::OneShot, "NFC::tag_out_range_event");
nfc_tag_state = TagState::NotInitialized;
}
void Shutdown() {
tag_in_range_event = nullptr;
tag_out_of_range_event = nullptr;
Module::~Module() = default;
void InstallInterfaces(SM::ServiceManager& service_manager) {
auto nfc = std::make_shared<Module>();
std::make_shared<NFC_M>(nfc)->InstallAsService(service_manager);
std::make_shared<NFC_U>(nfc)->InstallAsService(service_manager);
}
} // namespace NFC

View File

@ -4,12 +4,16 @@
#pragma once
#include <memory>
#include "common/common_types.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/service/service.h"
namespace Kernel {
class Event;
} // namespace Kernel
namespace Service {
class Interface;
namespace NFC {
namespace ErrCodes {
@ -32,6 +36,17 @@ enum class CommunicationStatus : u8 {
NfcInitialized = 2,
};
class Module final {
public:
Module();
~Module();
class Interface : public ServiceFramework<Interface> {
public:
Interface(std::shared_ptr<Module> nfc, const char* name, u32 max_session);
~Interface();
protected:
/**
* NFC::Initialize service function
* Inputs:
@ -40,7 +55,7 @@ enum class CommunicationStatus : u8 {
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
*/
void Initialize(Interface* self);
void Initialize(Kernel::HLERequestContext& ctx);
/**
* NFC::Shutdown service function
@ -50,7 +65,7 @@ void Initialize(Interface* self);
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
*/
void Shutdown(Interface* self);
void Shutdown(Kernel::HLERequestContext& ctx);
/**
* NFC::StartCommunication service function
@ -59,7 +74,7 @@ void Shutdown(Interface* self);
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
*/
void StartCommunication(Interface* self);
void StartCommunication(Kernel::HLERequestContext& ctx);
/**
* NFC::StopCommunication service function
@ -68,7 +83,7 @@ void StartCommunication(Interface* self);
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
*/
void StopCommunication(Interface* self);
void StopCommunication(Kernel::HLERequestContext& ctx);
/**
* NFC::StartTagScanning service function
@ -78,7 +93,7 @@ void StopCommunication(Interface* self);
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
*/
void StartTagScanning(Interface* self);
void StartTagScanning(Kernel::HLERequestContext& ctx);
/**
* NFC::StopTagScanning service function
@ -87,7 +102,7 @@ void StartTagScanning(Interface* self);
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
*/
void StopTagScanning(Interface* self);
void StopTagScanning(Kernel::HLERequestContext& ctx);
/**
* NFC::LoadAmiiboData service function
@ -96,7 +111,7 @@ void StopTagScanning(Interface* self);
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
*/
void LoadAmiiboData(Interface* self);
void LoadAmiiboData(Kernel::HLERequestContext& ctx);
/**
* NFC::ResetTagScanState service function
@ -105,7 +120,7 @@ void LoadAmiiboData(Interface* self);
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
*/
void ResetTagScanState(Interface* self);
void ResetTagScanState(Kernel::HLERequestContext& ctx);
/**
* NFC::GetTagInRangeEvent service function
@ -116,7 +131,7 @@ void ResetTagScanState(Interface* self);
* 2 : Copy handle descriptor
* 3 : Event Handle
*/
void GetTagInRangeEvent(Interface* self);
void GetTagInRangeEvent(Kernel::HLERequestContext& ctx);
/**
* NFC::GetTagOutOfRangeEvent service function
@ -127,7 +142,7 @@ void GetTagInRangeEvent(Interface* self);
* 2 : Copy handle descriptor
* 3 : Event Handle
*/
void GetTagOutOfRangeEvent(Interface* self);
void GetTagOutOfRangeEvent(Kernel::HLERequestContext& ctx);
/**
* NFC::GetTagState service function
@ -137,7 +152,7 @@ void GetTagOutOfRangeEvent(Interface* self);
* 1 : Result of function, 0 on success, otherwise error code
* 2 : (u8) Tag state
*/
void GetTagState(Interface* self);
void GetTagState(Kernel::HLERequestContext& ctx);
/**
* NFC::CommunicationGetStatus service function
@ -147,13 +162,20 @@ void GetTagState(Interface* self);
* 1 : Result of function, 0 on success, otherwise error code
* 2 : (u8) Communication state
*/
void CommunicationGetStatus(Interface* self);
void CommunicationGetStatus(Kernel::HLERequestContext& ctx);
/// Initialize all NFC services.
void Init();
private:
std::shared_ptr<Module> nfc;
};
/// Shutdown all NFC services.
void Shutdown();
private:
Kernel::SharedPtr<Kernel::Event> tag_in_range_event;
Kernel::SharedPtr<Kernel::Event> tag_out_of_range_event;
TagState nfc_tag_state = TagState::NotInitialized;
CommunicationStatus nfc_status = CommunicationStatus::NfcInitialized;
};
void InstallInterfaces(SM::ServiceManager& service_manager);
} // namespace NFC
} // namespace Service

View File

@ -2,28 +2,28 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "core/hle/service/nfc/nfc.h"
#include "core/hle/service/nfc/nfc_m.h"
namespace Service {
namespace NFC {
const Interface::FunctionInfo FunctionTable[] = {
NFC_M::NFC_M(std::shared_ptr<Module> nfc) : Module::Interface(std::move(nfc), "nfc:m", 1) {
static const FunctionInfo functions[] = {
// clang-format off
// nfc:u shared commands
{0x00010040, Initialize, "Initialize"},
{0x00020040, Shutdown, "Shutdown"},
{0x00030000, StartCommunication, "StartCommunication"},
{0x00040000, StopCommunication, "StopCommunication"},
{0x00050040, StartTagScanning, "StartTagScanning"},
{0x00060000, StopTagScanning, "StopTagScanning"},
{0x00070000, LoadAmiiboData, "LoadAmiiboData"},
{0x00080000, ResetTagScanState, "ResetTagScanState"},
{0x00010040, &NFC_M::Initialize, "Initialize"},
{0x00020040, &NFC_M::Shutdown, "Shutdown"},
{0x00030000, &NFC_M::StartCommunication, "StartCommunication"},
{0x00040000, &NFC_M::StopCommunication, "StopCommunication"},
{0x00050040, &NFC_M::StartTagScanning, "StartTagScanning"},
{0x00060000, &NFC_M::StopTagScanning, "StopTagScanning"},
{0x00070000, &NFC_M::LoadAmiiboData, "LoadAmiiboData"},
{0x00080000, &NFC_M::ResetTagScanState, "ResetTagScanState"},
{0x00090002, nullptr, "UpdateStoredAmiiboData"},
{0x000B0000, GetTagInRangeEvent, "GetTagInRangeEvent"},
{0x000C0000, GetTagOutOfRangeEvent, "GetTagOutOfRangeEvent"},
{0x000D0000, GetTagState, "GetTagState"},
{0x000F0000, CommunicationGetStatus, "CommunicationGetStatus"},
{0x000B0000, &NFC_M::GetTagInRangeEvent, "GetTagInRangeEvent"},
{0x000C0000, &NFC_M::GetTagOutOfRangeEvent, "GetTagOutOfRangeEvent"},
{0x000D0000, &NFC_M::GetTagState, "GetTagState"},
{0x000F0000, &NFC_M::CommunicationGetStatus, "CommunicationGetStatus"},
{0x00100000, nullptr, "GetTagInfo2"},
{0x00110000, nullptr, "GetTagInfo"},
{0x00120000, nullptr, "CommunicationGetResult"},
@ -38,9 +38,7 @@ const Interface::FunctionInfo FunctionTable[] = {
{0x04040A40, nullptr, "SetAmiiboSettings"}
// clang-format on
};
NFC_M::NFC_M() {
Register(FunctionTable);
RegisterHandlers(functions);
}
} // namespace NFC

View File

@ -4,18 +4,14 @@
#pragma once
#include "core/hle/service/service.h"
#include "core/hle/service/nfc/nfc.h"
namespace Service {
namespace NFC {
class NFC_M final : public Interface {
class NFC_M final : public Module::Interface {
public:
NFC_M();
std::string GetPortName() const override {
return "nfc:m";
}
explicit NFC_M(std::shared_ptr<Module> nfc);
};
} // namespace NFC

View File

@ -2,27 +2,27 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "core/hle/service/nfc/nfc.h"
#include "core/hle/service/nfc/nfc_u.h"
namespace Service {
namespace NFC {
const Interface::FunctionInfo FunctionTable[] = {
NFC_U::NFC_U(std::shared_ptr<Module> nfc) : Module::Interface(std::move(nfc), "nfc:u", 1) {
static const FunctionInfo functions[] = {
// clang-format off
{0x00010040, Initialize, "Initialize"},
{0x00020040, Shutdown, "Shutdown"},
{0x00030000, StartCommunication, "StartCommunication"},
{0x00040000, StopCommunication, "StopCommunication"},
{0x00050040, StartTagScanning, "StartTagScanning"},
{0x00060000, StopTagScanning, "StopTagScanning"},
{0x00070000, LoadAmiiboData, "LoadAmiiboData"},
{0x00080000, ResetTagScanState, "ResetTagScanState"},
{0x00010040, &NFC_U::Initialize, "Initialize"},
{0x00020040, &NFC_U::Shutdown, "Shutdown"},
{0x00030000, &NFC_U::StartCommunication, "StartCommunication"},
{0x00040000, &NFC_U::StopCommunication, "StopCommunication"},
{0x00050040, &NFC_U::StartTagScanning, "StartTagScanning"},
{0x00060000, &NFC_U::StopTagScanning, "StopTagScanning"},
{0x00070000, &NFC_U::LoadAmiiboData, "LoadAmiiboData"},
{0x00080000, &NFC_U::ResetTagScanState, "ResetTagScanState"},
{0x00090002, nullptr, "UpdateStoredAmiiboData"},
{0x000B0000, GetTagInRangeEvent, "GetTagInRangeEvent"},
{0x000C0000, GetTagOutOfRangeEvent, "GetTagOutOfRangeEvent"},
{0x000D0000, GetTagState, "GetTagState"},
{0x000F0000, CommunicationGetStatus, "CommunicationGetStatus"},
{0x000B0000, &NFC_U::GetTagInRangeEvent, "GetTagInRangeEvent"},
{0x000C0000, &NFC_U::GetTagOutOfRangeEvent, "GetTagOutOfRangeEvent"},
{0x000D0000, &NFC_U::GetTagState, "GetTagState"},
{0x000F0000, &NFC_U::CommunicationGetStatus, "CommunicationGetStatus"},
{0x00100000, nullptr, "GetTagInfo2"},
{0x00110000, nullptr, "GetTagInfo"},
{0x00120000, nullptr, "CommunicationGetResult"},
@ -35,9 +35,7 @@ const Interface::FunctionInfo FunctionTable[] = {
{0x00190000, nullptr, "GetAppDataInitStruct"},
// clang-format on
};
NFC_U::NFC_U() {
Register(FunctionTable);
RegisterHandlers(functions);
}
} // namespace NFC

View File

@ -4,18 +4,14 @@
#pragma once
#include "core/hle/service/service.h"
#include "core/hle/service/nfc/nfc.h"
namespace Service {
namespace NFC {
class NFC_U final : public Interface {
class NFC_U final : public Module::Interface {
public:
NFC_U();
std::string GetPortName() const override {
return "nfc:u";
}
explicit NFC_U(std::shared_ptr<Module> nfc);
};
} // namespace NFC

View File

@ -251,7 +251,7 @@ void Init() {
MVD::Init();
NDM::Init();
NEWS::InstallInterfaces(*SM::g_service_manager);
NFC::Init();
NFC::InstallInterfaces(*SM::g_service_manager);
NIM::InstallInterfaces(*SM::g_service_manager);
NWM::Init();
PTM::InstallInterfaces(*SM::g_service_manager);
@ -271,7 +271,6 @@ void Init() {
/// Shutdown ServiceManager
void Shutdown() {
NFC::Shutdown();
NDM::Shutdown();
DLP::Shutdown();
CFG::Shutdown();