diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp index 0b2fabec9..b459d79e1 100644 --- a/src/common/logging/backend.cpp +++ b/src/common/logging/backend.cpp @@ -38,6 +38,7 @@ namespace Log { SUB(Service, FS) \ SUB(Service, ERR) \ SUB(Service, APT) \ + SUB(Service, BOSS) \ SUB(Service, GSP) \ SUB(Service, AC) \ SUB(Service, AM) \ diff --git a/src/common/logging/log.h b/src/common/logging/log.h index c6910b1c7..a199b1d28 100644 --- a/src/common/logging/log.h +++ b/src/common/logging/log.h @@ -53,6 +53,7 @@ enum class Class : ClassType { Service_FS, ///< The FS (Filesystem) service implementation Service_ERR, ///< The ERR (Error) port implementation Service_APT, ///< The APT (Applets) service + Service_BOSS, ///< The BOSS (SpotPass) service Service_GSP, ///< The GSP (GPU control) service Service_AC, ///< The AC (WiFi status) service Service_AM, ///< The AM (Application manager) service diff --git a/src/core/hle/service/boss/boss.cpp b/src/core/hle/service/boss/boss.cpp index 419ec976e..c8e71775f 100644 --- a/src/core/hle/service/boss/boss.cpp +++ b/src/core/hle/service/boss/boss.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/service/service.h" #include "core/hle/service/boss/boss.h" #include "core/hle/service/boss/boss_p.h" #include "core/hle/service/boss/boss_u.h" @@ -10,11 +9,172 @@ namespace Service { namespace BOSS { +static u32 output_flag; + +void InitializeSession(Service::Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + // TODO(JamePeng): Figure out the meaning of these parameters + u64 unk_param = ((u64)cmd_buff[1] | ((u64)cmd_buff[2] << 32)); + u32 unk_translation = cmd_buff[3]; + u32 unk_param4 = cmd_buff[4]; + + if (unk_translation != IPC::CallingPidDesc()) { + cmd_buff[0] = IPC::MakeHeader(0, 0x1, 0); // 0x40 + cmd_buff[1] = ResultCode(ErrorDescription::OS_InvalidBufferDescriptor, + ErrorModule::OS, ErrorSummary::WrongArgument, ErrorLevel::Permanent).raw; // 0xD9001830 + LOG_ERROR(Service_BOSS, "The translation was invalid, translation=0x%08X",unk_translation); + return; + } + + cmd_buff[0] = IPC::MakeHeader(0x1, 0x1, 0); + cmd_buff[1] = RESULT_SUCCESS.raw; + + LOG_WARNING(Service_BOSS, "(STUBBED) unk_param=0x%016X, unk_translation=0x%08X, unk_param4=0x%08X", + unk_param, unk_translation, unk_param4); +} + +void RegisterStorage(Service::Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + // TODO(JamePeng): Figure out the meaning of these parameters + u32 unk_param1 = cmd_buff[1]; + u32 unk_param2 = cmd_buff[2]; + u32 unk_param3 = cmd_buff[3]; + u32 unk_flag = cmd_buff[4] & 0xF; + + cmd_buff[0] = IPC::MakeHeader(0x2, 0x1, 0); + cmd_buff[1] = RESULT_SUCCESS.raw; + + LOG_WARNING(Service_BOSS, "(STUBBED) unk_param1=0x%08X, unk_param2=0x%08X, unk_param3=0x%08X, unk_flag=0x%08X", + unk_param1, unk_param2, unk_param3, unk_flag); +} + +void UnregisterStorage(Service::Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + + cmd_buff[0] = IPC::MakeHeader(0x3, 0x1, 0); + cmd_buff[1] = RESULT_SUCCESS.raw; + + LOG_WARNING(Service_BOSS, "(STUBBED) called"); +} + +void RegisterNewArrivalEvent(Service::Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + // TODO(JamePeng): Figure out the meaning of these parameters + u32 unk_param1 = cmd_buff[1]; + u32 unk_param2 = cmd_buff[2]; + + cmd_buff[0] = IPC::MakeHeader(0x8, 0x1, 0); + cmd_buff[1] = RESULT_SUCCESS.raw; + + LOG_WARNING(Service_BOSS, "(STUBBED) unk_param1=0x%08X, unk_param2=0x%08X",unk_param1, unk_param2); +} + +void SetOptoutFlag(Service::Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + + output_flag = cmd_buff[1] & 0xF; + + cmd_buff[0] = IPC::MakeHeader(0x9, 0x1, 0); + cmd_buff[1] = RESULT_SUCCESS.raw; + + LOG_WARNING(Service_BOSS, "output_flag=%u", output_flag); +} + +void GetOptoutFlag(Service::Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + + cmd_buff[0] = IPC::MakeHeader(0xA, 0x2, 0); + cmd_buff[1] = RESULT_SUCCESS.raw; + cmd_buff[2] = output_flag; + + LOG_WARNING(Service_BOSS, "output_flag=%u", output_flag); +} + +void GetTaskIdList(Service::Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + + cmd_buff[0] = IPC::MakeHeader(0xE, 0x1, 0); + cmd_buff[1] = RESULT_SUCCESS.raw; + + LOG_WARNING(Service_BOSS, "(STUBBED) called"); +} + +void GetOwnNsDataIdList(Service::Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + // TODO(JamePeng): Figure out the meaning of these parameters + u32 unk_param1 = cmd_buff[1]; + u32 unk_param2 = cmd_buff[2]; + u32 unk_param3 = cmd_buff[3]; + u32 unk_param4 = cmd_buff[4]; + u32 unk_param5 = cmd_buff[5]; + u32 buff_addr = cmd_buff[6]; + + cmd_buff[0] = IPC::MakeHeader(0x11, 0x3, 0); + cmd_buff[1] = RESULT_SUCCESS.raw; + cmd_buff[2] = 0; // stub 0 (16 bit value) + cmd_buff[3] = 0; // stub 0 (16 bit value) + + LOG_WARNING(Service_BOSS, "(STUBBED) unk_param1=0x%08X, unk_param2=0x%08X, unk_param3=0x%08X, unk_param4=0x%08X, unk_param5=0x%08X, buff_addr=0x%08X", + unk_param1, unk_param2, unk_param3, unk_param4, unk_param5, buff_addr); +} + +void ReceiveProperty(Service::Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + // TODO(JamePeng): Figure out the meaning of these parameters + u32 unk_param1 = cmd_buff[1]; + u32 buff_size = cmd_buff[2]; + u32 translation = cmd_buff[3]; + u32 buff_addr = cmd_buff[4]; + + cmd_buff[0] = IPC::MakeHeader(0x16, 0x3, 0); + cmd_buff[1] = RESULT_SUCCESS.raw; + cmd_buff[2] = 0; // stub 0 (16 bit value) + cmd_buff[3] = 0; // stub 0 (16 bit value) + + LOG_WARNING(Service_BOSS, "(STUBBED) unk_param1=0x%08X, buff_size=0x%08X, translation=0x%08X, buff_addr=0x%08X", + unk_param1, buff_size, translation, buff_addr); +} + +void UpdateTaskCount(Service::Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + // TODO(JamePeng): Figure out the meaning of these parameters + u32 buff_size = cmd_buff[1]; + u32 unk_param2 = cmd_buff[2]; + u32 translation = cmd_buff[3]; + u32 buff_addr = cmd_buff[4]; + + cmd_buff[0] = IPC::MakeHeader(0x18, 0x1, 0); + cmd_buff[1] = RESULT_SUCCESS.raw; + + LOG_WARNING(Service_BOSS, "(STUBBED) buff_size=0x%08X, unk_param2=0x%08X, translation=0x%08X, buff_addr=0x%08X", + buff_size, unk_param2, translation, buff_addr); +} + +void GetTaskState(Service::Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + // TODO(JamePeng): Figure out the meaning of these parameters + u32 buff_size = cmd_buff[1]; + u32 unk_param2 = cmd_buff[2]; + u32 translation = cmd_buff[3]; + u32 buff_addr = cmd_buff[4]; + + cmd_buff[0] = IPC::MakeHeader(0x20, 0x4, 0); + cmd_buff[1] = RESULT_SUCCESS.raw; + cmd_buff[2] = 0; // stub 0 (8 bit value) + cmd_buff[3] = 0; // stub 0 (32 bit value) + cmd_buff[4] = 0; // stub 0 (8 bit value) + + LOG_WARNING(Service_BOSS, "(STUBBED) buff_size=0x%08X, unk_param2=0x%08X, translation=0x%08X, buff_addr=0x%08X", + buff_size, unk_param2, translation, buff_addr); +} + void Init() { using namespace Kernel; AddService(new BOSS_P_Interface); AddService(new BOSS_U_Interface); + + output_flag = 0; } void Shutdown() { diff --git a/src/core/hle/service/boss/boss.h b/src/core/hle/service/boss/boss.h index d3b5d7101..a0f5f95a4 100644 --- a/src/core/hle/service/boss/boss.h +++ b/src/core/hle/service/boss/boss.h @@ -4,9 +4,147 @@ #pragma once +#include "core/hle/service/service.h" + namespace Service { namespace BOSS { +/** + * BOSS::InitializeSession service function + * Inputs: + * 0 : Header Code[0x00010082] + * 1 : u32 lower 64bit value (unused) + * 2 : u32 higher 64bit value (unused) + * 3 : 0x20 + * 4 : u32 unknown value + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + */ +void InitializeSession(Service::Interface* self); + +/** + * BOSS::RegisterStorage service function + * Inputs: + * 0 : Header Code[0x00020010] + * 1 : u32 unknown1 + * 2 : u32 unknown2 + * 3 : u32 unknown3 + * 4 : u8 unknown_flag + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + */ +void RegisterStorage(Service::Interface* self); + +/** + * BOSS::UnregisterStorage service function + * Inputs: + * 0 : Header Code[0x00030000] + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + */ +void UnregisterStorage(Service::Interface* self); + +/** + * BOSS::RegisterNewArrivalEvent service function + * Inputs: + * 0 : Header Code[0x00080002] + * 1 : u32 unknown1 + * 2 : u32 unknown2 + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + */ +void RegisterNewArrivalEvent(Service::Interface* self); + +/** + * BOSS::SetOptoutFlag service function + * Inputs: + * 0 : Header Code[0x00090040] + * 1 : u8 output_flag + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + */ +void SetOptoutFlag(Service::Interface* self); + +/** + * BOSS::GetOptoutFlag service function + * Inputs: + * 0 : Header Code[0x000A0000] + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + * 2 : u8 output_flag + */ +void GetOptoutFlag(Service::Interface* self); + +/** + * BOSS::GetTaskIdList service function + * Inputs: + * 0 : Header Code[0x000E0000] + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + */ +void GetTaskIdList(Service::Interface* self); + +/** + * BOSS::GetOwnNsDataIdList service function + * Inputs: + * 0 : Header Code[0x00110102] + * 1 : u32 unknown1 + * 2 : u32 unknown2 + * 3 : u32 unknown3 + * 4 : u32 unknown4 + * 5 : u32 unknown5 + * 6 : u32 buff_addr + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + * 2 : u16 unknown value + * 3 : u16 unknown value + */ +void GetOwnNsDataIdList(Service::Interface* self); + +/** + * BOSS::ReceiveProperty service function + * Inputs: + * 0 : Header Code[0x00160082] + * 1 : u32 unknown1 + * 2 : u32 buff_size + * 3 : MappedBufferDesc(permission = W) + * 4 : u32 buff addr + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + * 2 : u16 unknown value + * 3 : u16 unknown value + */ +void ReceiveProperty(Service::Interface* self); + +/** + * BOSS::UpdateTaskCount service function + * Inputs: + * 0 : Header Code[0x00180082] + * 1 : u32 buff_size + * 2 : u32 unknown2 + * 3 : u32 MappedBufferDesc(permission = W) + * 4 : u32 buff_addr + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + */ +void UpdateTaskCount(Service::Interface* self); + +/** + * BOSS::GetTaskState service function + * Inputs: + * 0 : Header Code[0x00200082] + * 1 : u32 buff_size + * 2 : 0 + * 3 : MappedBufferDesc(permission = R) + * 4 : u32 buff_addr + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + * 2 : u8 unknown value + * 3 : u32 unknown value + * 4 : u8 unknown value + */ +void GetTaskState(Service::Interface* self); + /// Initialize BOSS service(s) void Init(); diff --git a/src/core/hle/service/boss/boss_u.cpp b/src/core/hle/service/boss/boss_u.cpp index d59babe71..4c566ca68 100644 --- a/src/core/hle/service/boss/boss_u.cpp +++ b/src/core/hle/service/boss/boss_u.cpp @@ -2,16 +2,68 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "core/hle/service/boss/boss.h" #include "core/hle/service/boss/boss_u.h" namespace Service { namespace BOSS { const Interface::FunctionInfo FunctionTable[] = { - {0x00020100, nullptr, "GetStorageInfo"}, - {0x000C0082, nullptr, "UnregisterTask"}, - {0x001E0042, nullptr, "CancelTask"}, - {0x00330042, nullptr, "StartBgImmediate"}, + {0x00010082, InitializeSession, "InitializeSession"}, + {0x00020100, RegisterStorage, "RegisterStorage"}, + {0x00030000, UnregisterStorage, "UnregisterStorage"}, + {0x00040000, nullptr, "GetStorageInfo"}, + {0x00050042, nullptr, "RegisterPrivateRootCa"}, + {0x00060084, nullptr, "RegisterPrivateClientCert"}, + {0x00070000, nullptr, "GetNewArrivalFlag"}, + {0x00080002, RegisterNewArrivalEvent, "RegisterNewArrivalEvent"}, + {0x00090040, SetOptoutFlag, "SetOptoutFlag"}, + {0x000A0000, GetOptoutFlag, "GetOptoutFlag"}, + {0x000B00C2, nullptr, "RegisterTask"}, + {0x000C0082, nullptr, "UnregisterTask"}, + {0x000D0082, nullptr, "ReconfigureTask"}, + {0x000E0000, GetTaskIdList, "GetTaskIdList"}, + {0x000F0042, nullptr, "GetStepIdList"}, + {0x00100102, nullptr, "GetNsDataIdList"}, + {0x00110102, GetOwnNsDataIdList, "GetOwnNsDataIdList"}, + {0x00120102, nullptr, "GetNewDataNsDataIdList"}, + {0x00130102, nullptr, "GetOwnNewDataNsDataIdList"}, + {0x00140082, nullptr, "SendProperty"}, + {0x00150042, nullptr, "SendPropertyHandle"}, + {0x00160082, ReceiveProperty, "ReceiveProperty"}, + {0x00170082, nullptr, "UpdateTaskInterval"}, + {0x00180082, UpdateTaskCount, "UpdateTaskCount"}, + {0x00190042, nullptr, "GetTaskInterval"}, + {0x001A0042, nullptr, "GetTaskCount"}, + {0x001B0042, nullptr, "GetTaskServiceStatus"}, + {0x001C0042, nullptr, "StartTask"}, + {0x001D0042, nullptr, "StartTaskImmediate"}, + {0x001E0042, nullptr, "CancelTask"}, + {0x001F0000, nullptr, "GetTaskFinishHandle"}, + {0x00200082, GetTaskState, "GetTaskState"}, + {0x00210042, nullptr, "GetTaskResult"}, + {0x00220042, nullptr, "GetTaskCommErrorCode"}, + {0x002300C2, nullptr, "GetTaskStatus"}, + {0x00240082, nullptr, "GetTaskError"}, + {0x00250082, nullptr, "GetTaskInfo"}, + {0x00260040, nullptr, "DeleteNsData"}, + {0x002700C2, nullptr, "GetNsDataHeaderInfo"}, + {0x00280102, nullptr, "ReadNsData"}, + {0x00290080, nullptr, "SetNsDataAdditionalInfo"}, + {0x002A0040, nullptr, "GetNsDataAdditionalInfo"}, + {0x002B0080, nullptr, "SetNsDataNewFlag"}, + {0x002C0040, nullptr, "GetNsDataNewFlag"}, + {0x002D0040, nullptr, "GetNsDataLastUpdate"}, + {0x002E0040, nullptr, "GetErrorCode"}, + {0x002F0140, nullptr, "RegisterStorageEntry"}, + {0x00300000, nullptr, "GetStorageEntryInfo"}, + {0x00310100, nullptr, "SetStorageOption"}, + {0x00320000, nullptr, "GetStorageOption"}, + {0x00330042, nullptr, "StartBgImmediate"}, + {0x00340042, nullptr, "GetTaskActivePriority"}, + {0x003500C2, nullptr, "RegisterImmediateTask"}, + {0x00360084, nullptr, "SetTaskQuery"}, + {0x00370044, nullptr, "GetTaskQuery"}, }; BOSS_U_Interface::BOSS_U_Interface() {