Stratosphere: Skeleton actual IPC dispatch in ServiceSession

This commit is contained in:
Michael Scire 2018-04-18 12:53:04 -06:00
parent 49719c8a44
commit 8ba3894c3a
9 changed files with 57 additions and 16 deletions

View file

@ -4,5 +4,5 @@
class IServiceObject { class IServiceObject {
public: public:
virtual ~IServiceObject() { } virtual ~IServiceObject() { }
virtual Result dispatch(IpcParsedCommand *r, u32 *cmd_buf, u32 cmd_id, u32 *in_rawdata, u32 in_rawdata_size, u32 *out_rawdata, u32 *out_raw_data_count) = 0; virtual Result dispatch(IpcParsedCommand *r, IpcCommand *out_c, u32 *cmd_buf, u32 cmd_id, u32 *in_rawdata, u32 in_rawdata_size, u32 *out_rawdata, u32 *out_raw_data_count) = 0;
}; };

View file

@ -12,7 +12,7 @@ class IWaitable {
virtual void get_waitables(IWaitable **dst) = 0; virtual void get_waitables(IWaitable **dst) = 0;
virtual void delete_child(IWaitable *child) = 0; virtual void delete_child(IWaitable *child) = 0;
virtual Handle get_handle() = 0; virtual Handle get_handle() = 0;
virtual Result handle_signaled() = 0; virtual Result handle_signaled(u64 timeout) = 0;
bool has_parent() { bool has_parent() {
return this->parent_waitable != NULL; return this->parent_waitable != NULL;

View file

@ -2,7 +2,7 @@
#include "ldr_debug_monitor.hpp" #include "ldr_debug_monitor.hpp"
#include "ldr_launch_queue.hpp" #include "ldr_launch_queue.hpp"
Result DebugMonitorService::dispatch(IpcParsedCommand *r, u32 *cmd_buf, u32 cmd_id, u32 *in_rawdata, u32 in_rawdata_size, u32 *out_rawdata, u32 *out_raw_data_count) { Result DebugMonitorService::dispatch(IpcParsedCommand *r, IpcCommand *out_c, u32 *cmd_buf, u32 cmd_id, u32 *in_rawdata, u32 in_rawdata_size, u32 *out_rawdata, u32 *out_raw_data_count) {
Result rc = 0xF601; Result rc = 0xF601;

View file

@ -11,7 +11,7 @@ enum DebugMonitorServiceCmd {
class DebugMonitorService : IServiceObject { class DebugMonitorService : IServiceObject {
public: public:
Result dispatch(IpcParsedCommand *r, u32 *cmd_buf, u32 cmd_id, u32 *in_rawdata, u32 in_rawdata_size, u32 *out_rawdata, u32 *out_raw_data_count); Result dispatch(IpcParsedCommand *r, IpcCommand *out_c, u32 *cmd_buf, u32 cmd_id, u32 *in_rawdata, u32 in_rawdata_size, u32 *out_rawdata, u32 *out_raw_data_count);
private: private:
/* Actual commands. */ /* Actual commands. */

View file

@ -2,7 +2,7 @@
#include "ldr_shell.hpp" #include "ldr_shell.hpp"
#include "ldr_launch_queue.hpp" #include "ldr_launch_queue.hpp"
Result ShellService::dispatch(IpcParsedCommand *r, u32 *cmd_buf, u32 cmd_id, u32 *in_rawdata, u32 in_rawdata_size, u32 *out_rawdata, u32 *out_raw_data_count) { Result ShellService::dispatch(IpcParsedCommand *r, IpcCommand *out_c, u32 *cmd_buf, u32 cmd_id, u32 *in_rawdata, u32 in_rawdata_size, u32 *out_rawdata, u32 *out_raw_data_count) {
Result rc = 0xF601; Result rc = 0xF601;

View file

@ -10,7 +10,7 @@ enum ShellServiceCmd {
class ShellService : IServiceObject { class ShellService : IServiceObject {
public: public:
Result dispatch(IpcParsedCommand *r, u32 *cmd_buf, u32 cmd_id, u32 *in_rawdata, u32 in_rawdata_size, u32 *out_rawdata, u32 *out_raw_data_count); Result dispatch(IpcParsedCommand *r, IpcCommand *out_c, u32 *cmd_buf, u32 cmd_id, u32 *in_rawdata, u32 in_rawdata_size, u32 *out_rawdata, u32 *out_raw_data_count);
private: private:
/* Actual commands. */ /* Actual commands. */

View file

@ -87,7 +87,7 @@ class ServiceServer : public IWaitable {
return this->port_handle; return this->port_handle;
} }
virtual Result handle_signaled() { virtual Result handle_signaled(u64 timeout) {
/* If this server's port was signaled, accept a new session. */ /* If this server's port was signaled, accept a new session. */
Handle session_h; Handle session_h;
svcAcceptSession(&session_h, this->port_handle); svcAcceptSession(&session_h, this->port_handle);

View file

@ -53,8 +53,47 @@ class ServiceSession : public IWaitable {
return this->server_handle; return this->server_handle;
} }
virtual Result handle_signaled() { virtual Result handle_signaled(u64 timeout) {
/* TODO */ Result rc;
return 0; int handle_index;
if (R_SUCCEEDED(rc = svcReplyAndReceive(&handle_index, &this->server_handle, 1, 0, timeout))) {
if (handle_index != 0) {
/* TODO: Panic? */
}
u32 *cmdbuf = (u32 *)armGetTls();
u32 out_words = 4;
u32 extra_rawdata_count = 0;
u32 wordcount = 0;
Result retval = 0;
u32 *rawdata_start = cmdbuf;
IpcParsedCommand r;
IpcCommand c;
ipcInitialize(&c);
retval = ipcParse(&r);
if (R_SUCCEEDED(retval)) {
rawdata_start = (u32 *)r.Raw;
wordcount = r.RawSize;
retval = this->service_object->dispatch(&r, &c, cmdbuf, rawdata_start[2], &rawdata_start[4], wordcount - 6, &cmdbuf[8], &extra_rawdata_count);
out_words += extra_rawdata_count;
}
struct {
u64 magic;
u64 retval;
} *raw;
raw = (decltype(raw))ipcPrepareHeader(&c, out_words);
raw->magic = SFCO_MAGIC;
raw->retval = retval;
rc = svcReplyAndReceive(&handle_index, &this->server_handle, 1, this->server_handle, 0);
}
return rc;
} }
}; };

View file

@ -43,8 +43,8 @@ void WaitableManager::process() {
rc = svcWaitSynchronization(&handle_index, handles.data(), handles.size(), this->timeout); rc = svcWaitSynchronization(&handle_index, handles.data(), handles.size(), this->timeout);
if (R_SUCCEEDED(rc)) { if (R_SUCCEEDED(rc)) {
/* Handle a signaled waitable. */ /* Handle a signaled waitable. */
/* TODO: What should be done with the result here? */ /* TODO: What timeout should be passed here? */
signalables[handle_index]->handle_signaled(); rc = signalables[handle_index]->handle_signaled(0);
for (int i = 0; i < handle_index; i++) { for (int i = 0; i < handle_index; i++) {
signalables[i]->update_priority(); signalables[i]->update_priority();
@ -54,7 +54,11 @@ void WaitableManager::process() {
for (auto & waitable : signalables) { for (auto & waitable : signalables) {
waitable->update_priority(); waitable->update_priority();
} }
} else if (rc == 0xF601) { } else if (rc != 0xF601) {
/* TODO: Panic. When can this happen? */
}
if (rc == 0xF601) {
/* handles[handle_index] was closed! */ /* handles[handle_index] was closed! */
/* Close the handle. */ /* Close the handle. */
@ -73,8 +77,6 @@ void WaitableManager::process() {
for (int i = 0; i < handle_index; i++) { for (int i = 0; i < handle_index; i++) {
signalables[i]->update_priority(); signalables[i]->update_priority();
} }
} else {
/* TODO: Panic. When can this happen? */
} }
} }
} }