diff --git a/include/services/boss.hpp b/include/services/boss.hpp index 57452e2d..aa0f1a2a 100644 --- a/include/services/boss.hpp +++ b/include/services/boss.hpp @@ -12,9 +12,13 @@ class BOSSService { // Service commands void cancelTask(u32 messagePointer); + void deleteNsData(u32 messagePointer); void initializeSession(u32 messagePointer); + void getAppNewFlag(u32 messagePointer); void getErrorCode(u32 messagePointer); + void getNsDataHeaderInfo(u32 messagePointer); void getNsDataIdList(u32 messagePointer, u32 commandWord); + void getNsDataLastUpdated(u32 messagePointer); void getOptoutFlag(u32 messagePointer); void getStorageEntryInfo(u32 messagePointer); // Unknown what this is, name taken from Citra void getTaskIdList(u32 messagePointer); @@ -23,12 +27,15 @@ class BOSSService { void getTaskState(u32 messagePointer); void getTaskStatus(u32 messagePointer); void getTaskStorageInfo(u32 messagePointer); + void readNsData(u32 messagePointer); void receiveProperty(u32 messagePointer); void registerNewArrivalEvent(u32 messagePointer); void registerStorageEntry(u32 messagePointer); void registerTask(u32 messagePointer); void sendProperty(u32 messagePointer); + void setAppNewFlag(u32 messagePointer); void setOptoutFlag(u32 messagePointer); + void startBgImmediate(u32 messagePointer); void startTask(u32 messagePointer); void unregisterStorage(u32 messagePointer); void unregisterTask(u32 messagePointer); diff --git a/src/core/services/boss.cpp b/src/core/services/boss.cpp index 0a834665..24d19e9c 100644 --- a/src/core/services/boss.cpp +++ b/src/core/services/boss.cpp @@ -22,9 +22,17 @@ namespace BOSSCommands { GetTaskState = 0x00200082, GetTaskStatus = 0x002300C2, GetTaskInfo = 0x00250082, + DeleteNsData = 0x00260040, + GetNsDataHeaderInfo = 0x002700C2, + ReadNsData = 0x00280102, + GetNsDataLastUpdated = 0x002D0040, GetErrorCode = 0x002E0040, RegisterStorageEntry = 0x002F0140, GetStorageEntryInfo = 0x00300000, + StartBgImmediate = 0x00330042, + InitializeSessionPrivileged = 0x04010082, + GetAppNewFlag = 0x04040080, + SetAppNewFlag = 0x040500C0, // Probably }; } @@ -33,14 +41,17 @@ void BOSSService::reset() { } void BOSSService::handleSyncRequest(u32 messagePointer) { - // Note: Clearing this bit maps boss:P commands onto their boss:U counterparts - const u32 command = mem.read32(messagePointer) & ~0x4000000; + const u32 command = mem.read32(messagePointer); switch (command) { case BOSSCommands::CancelTask: cancelTask(messagePointer); break; + case BOSSCommands::DeleteNsData: deleteNsData(messagePointer); break; + case BOSSCommands::GetAppNewFlag: getAppNewFlag(messagePointer); break; case BOSSCommands::GetErrorCode: getErrorCode(messagePointer); break; + case BOSSCommands::GetNsDataHeaderInfo: getNsDataHeaderInfo(messagePointer); break; case BOSSCommands::GetNsDataIdList: case BOSSCommands::GetNsDataIdList1: getNsDataIdList(messagePointer, command); break; + case BOSSCommands::GetNsDataLastUpdated: getNsDataLastUpdated(messagePointer); break; case BOSSCommands::GetOptoutFlag: getOptoutFlag(messagePointer); break; case BOSSCommands::GetStorageEntryInfo: getStorageEntryInfo(messagePointer); break; case BOSSCommands::GetTaskIdList: getTaskIdList(messagePointer); break; @@ -49,13 +60,18 @@ void BOSSService::handleSyncRequest(u32 messagePointer) { case BOSSCommands::GetTaskState: getTaskState(messagePointer); break; case BOSSCommands::GetTaskStatus: getTaskStatus(messagePointer); break; case BOSSCommands::GetTaskStorageInfo: getTaskStorageInfo(messagePointer); break; - case BOSSCommands::InitializeSession: initializeSession(messagePointer); break; + case BOSSCommands::InitializeSession: + case BOSSCommands::InitializeSessionPrivileged: + initializeSession(messagePointer); break; + case BOSSCommands::ReadNsData: readNsData(messagePointer); break; case BOSSCommands::ReceiveProperty: receiveProperty(messagePointer); break; case BOSSCommands::RegisterNewArrivalEvent: registerNewArrivalEvent(messagePointer); break; case BOSSCommands::RegisterStorageEntry: registerStorageEntry(messagePointer); break; case BOSSCommands::RegisterTask: registerTask(messagePointer); break; case BOSSCommands::SendProperty: sendProperty(messagePointer); break; + case BOSSCommands::SetAppNewFlag: setAppNewFlag(messagePointer); break; case BOSSCommands::SetOptoutFlag: setOptoutFlag(messagePointer); break; + case BOSSCommands::StartBgImmediate: startBgImmediate(messagePointer); break; case BOSSCommands::StartTask: startTask(messagePointer); break; case BOSSCommands::UnregisterStorage: unregisterStorage(messagePointer); break; case BOSSCommands::UnregisterTask: unregisterTask(messagePointer); break; @@ -241,4 +257,91 @@ void BOSSService::unregisterStorage(u32 messagePointer) { log("BOSS::UnregisterStorage (stubbed)\n"); mem.write32(messagePointer, IPC::responseHeader(0x3, 1, 0)); mem.write32(messagePointer + 4, Result::Success); +} + +void BOSSService::startBgImmediate(u32 messagePointer) { + const u32 size = mem.read32(messagePointer + 8); + const u32 taskIDs = mem.read32(messagePointer + 12); + log("BOSS::StartBgImmediate (size = %X, task ID pointer = %X) (stubbed)\n", size, taskIDs); + + mem.write32(messagePointer, IPC::responseHeader(0x33, 1, 2)); + mem.write32(messagePointer + 4, Result::Success); + mem.write32(messagePointer + 8, IPC::pointerHeader(0, size, IPC::BufferType::Send)); + mem.write32(messagePointer + 12, taskIDs); +} + +void BOSSService::getAppNewFlag(u32 messagePointer) { + const u64 appID = mem.read64(messagePointer + 4); + log("BOSS::GetAppNewFlag (app ID = %llX)\n", appID); + + mem.write32(messagePointer, IPC::responseHeader(0x404, 2, 0)); + mem.write32(messagePointer + 4, Result::Success); + mem.write8(messagePointer + 8, 0); // No new content +} + +void BOSSService::getNsDataHeaderInfo(u32 messagePointer) { + const u32 nsDataID = mem.read32(messagePointer + 4); + const u8 type = mem.read8(messagePointer + 8); + const u32 size = mem.read32(messagePointer + 12); + const u32 nsDataHeaderInfo = mem.read32(messagePointer + 20); + log("BOSS::GetNsDataHeaderInfo (NS data ID = %X, type = %X, size = %X, NS data header info pointer = %X) (stubbed)\n", nsDataID, type, size, nsDataHeaderInfo); + + switch (type) { + case 3: + case 5: + mem.write32(nsDataHeaderInfo, 0); break; // ?? + + default: Helpers::panic("Unimplemented NS data header info type %X", type); + } + + mem.write32(messagePointer, IPC::responseHeader(0x27, 1, 2)); + mem.write32(messagePointer + 4, Result::Success); + mem.write32(messagePointer + 8, IPC::pointerHeader(0, size, IPC::BufferType::Receive)); + mem.write32(messagePointer + 12, nsDataHeaderInfo); +} + +void BOSSService::getNsDataLastUpdated(u32 messagePointer) { + const u32 nsDataID = mem.read32(messagePointer + 4); + log("BOSS::GetNsDataLastUpdated (NS data ID = %X) (stubbed)\n", nsDataID); + + mem.write32(messagePointer, IPC::responseHeader(0x2D, 3, 0)); + mem.write32(messagePointer + 4, Result::Success); + mem.write64(messagePointer + 8, 0); // Milliseconds since last update? +} + +void BOSSService::readNsData(u32 messagePointer) { + const u32 nsDataID = mem.read32(messagePointer + 4); + const s64 offset = mem.read64(messagePointer + 8); + const u32 size = mem.read32(messagePointer + 20); + const u32 data = mem.read32(messagePointer + 24); + log("BOSS::ReadNsData (NS data ID = %X, offset = %llX, size = %X, data pointer = %X) (stubbed)\n", nsDataID, offset, size, data); + + for (u32 i = 0; i < size; i++) { + mem.write8(data + i, 0); + } + + mem.write32(messagePointer, IPC::responseHeader(0x28, 3, 2)); + mem.write32(messagePointer + 4, Result::Success); + mem.write32(messagePointer + 8, size); // Technically how many bytes have been read + mem.write32(messagePointer + 12, 0); // ?? + mem.write32(messagePointer + 16, IPC::pointerHeader(0, size, IPC::BufferType::Receive)); + mem.write32(messagePointer + 20, data); +} + +void BOSSService::deleteNsData(u32 messagePointer) { + const u32 nsDataID = mem.read32(messagePointer + 4); + log("BOSS::DeleteNsData (NS data ID = %X) (stubbed)\n", nsDataID); + + mem.write32(messagePointer, IPC::responseHeader(0x26, 1, 0)); + mem.write32(messagePointer + 4, Result::Success); +} + +// Judging by the inputs and command number, this could very well be a "SetAppNewFlag" +void BOSSService::setAppNewFlag(u32 messagePointer) { + const u64 appID = mem.read64(messagePointer + 4); + const u8 flag = mem.read32(messagePointer + 12); + log("BOSS::SetAppNewFlag (app ID = %llX, flag = %X)\n", appID, flag); + + mem.write32(messagePointer, IPC::responseHeader(0x405, 1, 0)); + mem.write32(messagePointer + 4, Result::Success); } \ No newline at end of file