GET /sessions returns the title info.
This commit is contained in:
parent
1461792289
commit
8a7bd7b69a
|
@ -18,9 +18,12 @@ using namespace xe::debug;
|
|||
|
||||
DebugClient::DebugClient(DebugServer* debug_server) :
|
||||
debug_server_(debug_server) {
|
||||
debug_server_->AddClient(this);
|
||||
}
|
||||
|
||||
DebugClient::~DebugClient() {
|
||||
debug_server_->RemoveClient(this);
|
||||
}
|
||||
|
||||
void DebugClient::MakeReady() {
|
||||
debug_server_->AddClient(this);
|
||||
}
|
||||
|
|
|
@ -29,6 +29,9 @@ public:
|
|||
virtual int Setup() = 0;
|
||||
virtual void Close() = 0;
|
||||
|
||||
protected:
|
||||
void MakeReady();
|
||||
|
||||
protected:
|
||||
DebugServer* debug_server_;
|
||||
};
|
||||
|
|
|
@ -44,6 +44,10 @@ DebugServer::~DebugServer() {
|
|||
}
|
||||
|
||||
int DebugServer::Startup() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DebugServer::BeforeEntry() {
|
||||
// HACK(benvanik): say we are ok even if we have no listener.
|
||||
if (!protocols_.size()) {
|
||||
return 0;
|
||||
|
|
|
@ -30,7 +30,10 @@ public:
|
|||
DebugServer(Emulator* emulator);
|
||||
virtual ~DebugServer();
|
||||
|
||||
Emulator* emulator() const { return emulator_; }
|
||||
|
||||
int Startup();
|
||||
int BeforeEntry();
|
||||
void Shutdown();
|
||||
|
||||
private:
|
||||
|
|
|
@ -89,9 +89,12 @@ void GDBClient::EventThread() {
|
|||
// First run the HTTP handshake.
|
||||
// This will fail if the connection is not for websockets.
|
||||
if (PerformHandshake()) {
|
||||
delete this;
|
||||
return;
|
||||
}
|
||||
|
||||
MakeReady();
|
||||
|
||||
// Loop forever.
|
||||
while (true) {
|
||||
// Wait on the event.
|
||||
|
|
|
@ -9,20 +9,28 @@
|
|||
|
||||
#include <xenia/debug/protocols/ws/ws_client.h>
|
||||
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
|
||||
#include <xenia/emulator.h>
|
||||
#include <xenia/debug/debug_server.h>
|
||||
#include <xenia/debug/protocols/ws/simple_sha1.h>
|
||||
#include <xenia/kernel/xboxkrnl/kernel_state.h>
|
||||
#include <xenia/kernel/xboxkrnl/xboxkrnl_module.h>
|
||||
#include <xenia/kernel/xboxkrnl/objects/xmodule.h>
|
||||
|
||||
#if XE_PLATFORM(WIN32)
|
||||
// Required for wslay.
|
||||
typedef SSIZE_T ssize_t;
|
||||
#endif // WIN32
|
||||
|
||||
#include <wslay/wslay.h>
|
||||
|
||||
|
||||
using namespace std;
|
||||
using namespace xe;
|
||||
using namespace xe::debug;
|
||||
using namespace xe::debug::protocols::ws;
|
||||
using namespace xe::kernel::xboxkrnl;
|
||||
|
||||
|
||||
WSClient::WSClient(DebugServer* debug_server, socket_t socket_id) :
|
||||
|
@ -204,6 +212,54 @@ int WSClient::PerformHandshake() {
|
|||
return 1;
|
||||
}
|
||||
|
||||
// If this is a get for the session list, just produce that and return.
|
||||
// We could stub out better handling here, if we wanted.
|
||||
if (headers.find("GET /sessions") != std::string::npos) {
|
||||
Emulator* emulator = debug_server_->emulator();
|
||||
KernelState* kernel_state = emulator->xboxkrnl()->kernel_state();
|
||||
XModule* module = kernel_state->GetExecutableModule();
|
||||
const xe_xex2_header_t* header = module->xex_header();
|
||||
char title_id[9];
|
||||
xesnprintfa(title_id, XECOUNT(title_id), "%.8X",
|
||||
header->execution_info.title_id);
|
||||
|
||||
ostringstream response;
|
||||
if (module) {
|
||||
response <<
|
||||
"HTTP/1.0 200 OK\r\n"
|
||||
"Content-Type: application/json\r\n"
|
||||
"Connection: close\r\n"
|
||||
"\r\n";
|
||||
response << "[{";
|
||||
response <<
|
||||
"\"name\": \"" << module->name() << "\",";
|
||||
response <<
|
||||
"\"path\": \"" << module->path() << "\",";
|
||||
response <<
|
||||
"\"titleId\": \"" << title_id << "\"";
|
||||
response << "}]";
|
||||
response <<
|
||||
"\r\n"
|
||||
"\r\n";
|
||||
} else {
|
||||
response <<
|
||||
"HTTP/1.0 200 OK\r\n"
|
||||
"Content-Type: application/json\r\n"
|
||||
"Connection: close\r\n"
|
||||
"\r\n"
|
||||
"[]"
|
||||
"\r\n"
|
||||
"\r\n";
|
||||
}
|
||||
error_code = WriteResponse(response.str());
|
||||
if (error_code) {
|
||||
return error_code;
|
||||
}
|
||||
|
||||
// Eh, we just kill the connection here.
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Parse the headers to verify its a websocket request.
|
||||
std::string::size_type keyhdstart;
|
||||
if (headers.find("Upgrade: websocket\r\n") == std::string::npos ||
|
||||
|
@ -228,6 +284,12 @@ int WSClient::PerformHandshake() {
|
|||
"Connection: Upgrade\r\n"
|
||||
"Sec-WebSocket-Accept: " + accept_key + "\r\n"
|
||||
"\r\n";
|
||||
return WriteResponse(response);
|
||||
}
|
||||
|
||||
int WSClient::WriteResponse(std::string& response) {
|
||||
int error_code = 0;
|
||||
int64_t r;
|
||||
size_t write_offset = 0;
|
||||
size_t write_length = response.size();
|
||||
while (true) {
|
||||
|
@ -250,7 +312,6 @@ int WSClient::PerformHandshake() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -261,9 +322,12 @@ void WSClient::EventThread() {
|
|||
// First run the HTTP handshake.
|
||||
// This will fail if the connection is not for websockets.
|
||||
if (PerformHandshake()) {
|
||||
delete this;
|
||||
return;
|
||||
}
|
||||
|
||||
MakeReady();
|
||||
|
||||
// Prep callbacks.
|
||||
struct wslay_event_callbacks callbacks = {
|
||||
(wslay_event_recv_callback)WSClientRecvCallback,
|
||||
|
|
|
@ -43,6 +43,7 @@ private:
|
|||
static void StartCallback(void* param);
|
||||
|
||||
int PerformHandshake();
|
||||
int WriteResponse(std::string& response);
|
||||
void EventThread();
|
||||
|
||||
xe_thread_ref thread_;
|
||||
|
|
|
@ -47,6 +47,9 @@ public:
|
|||
ExportResolver* export_resolver() const { return export_resolver_; }
|
||||
kernel::xboxkrnl::fs::FileSystem* file_system() const { return file_system_; }
|
||||
|
||||
kernel::xboxkrnl::XboxkrnlModule* xboxkrnl() const { return xboxkrnl_; }
|
||||
kernel::xam::XamModule* xam() const { return xam_; }
|
||||
|
||||
X_STATUS Setup();
|
||||
|
||||
// TODO(benvanik): raw binary.
|
||||
|
|
|
@ -132,9 +132,6 @@ X_STATUS XModule::Launch(uint32_t flags) {
|
|||
|
||||
XELOGI("Launching module...");
|
||||
|
||||
// Set as the main module, while running.
|
||||
kernel_state()->SetExecutableModule(this);
|
||||
|
||||
Dump();
|
||||
|
||||
// Create a thread to run in.
|
||||
|
@ -154,7 +151,6 @@ X_STATUS XModule::Launch(uint32_t flags) {
|
|||
// Wait until thread completes.
|
||||
thread->Wait(0, 0, 0, NULL);
|
||||
|
||||
kernel_state()->SetExecutableModule(NULL);
|
||||
thread->Release();
|
||||
|
||||
return X_STATUS_SUCCESS;
|
||||
|
|
|
@ -11,7 +11,9 @@
|
|||
|
||||
#include <gflags/gflags.h>
|
||||
|
||||
#include <xenia/emulator.h>
|
||||
#include <xenia/export_resolver.h>
|
||||
#include <xenia/debug/debug_server.h>
|
||||
#include <xenia/kernel/xboxkrnl/kernel_state.h>
|
||||
#include <xenia/kernel/xboxkrnl/xboxkrnl_private.h>
|
||||
#include <xenia/kernel/xboxkrnl/objects/xmodule.h>
|
||||
|
@ -166,15 +168,25 @@ int XboxkrnlModule::LaunchModule(const char* path) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
// Set as the main module, while running.
|
||||
kernel_state_->SetExecutableModule(module);
|
||||
|
||||
if (FLAGS_abort_before_entry) {
|
||||
XELOGI("--abort_before_entry causing an early exit");
|
||||
module->Release();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Spin up the debugger and let it know we are starting.
|
||||
if (emulator_->debug_server()->BeforeEntry()) {
|
||||
XELOGE("Debugger failed to startup.");
|
||||
return 2;
|
||||
}
|
||||
|
||||
// Launch the module.
|
||||
// NOTE: this won't return until the module exits.
|
||||
result_code = module->Launch(0);
|
||||
kernel_state_->SetExecutableModule(NULL);
|
||||
if (XFAILED(result_code)) {
|
||||
XELOGE("Failed to launch module %s: %.8X", path, result_code);
|
||||
module->Release();
|
||||
|
|
|
@ -39,6 +39,8 @@ public:
|
|||
XboxkrnlModule(Emulator* emulator);
|
||||
virtual ~XboxkrnlModule();
|
||||
|
||||
KernelState* kernel_state() const { return kernel_state_; }
|
||||
|
||||
int LaunchModule(const char* path);
|
||||
|
||||
private:
|
||||
|
|
Loading…
Reference in New Issue