GET /sessions returns the title info.

This commit is contained in:
Ben Vanik 2013-12-20 23:44:22 -08:00
parent 1461792289
commit 8a7bd7b69a
11 changed files with 101 additions and 7 deletions

View File

@ -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);
}

View File

@ -29,6 +29,9 @@ public:
virtual int Setup() = 0;
virtual void Close() = 0;
protected:
void MakeReady();
protected:
DebugServer* debug_server_;
};

View File

@ -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;

View File

@ -30,7 +30,10 @@ public:
DebugServer(Emulator* emulator);
virtual ~DebugServer();
Emulator* emulator() const { return emulator_; }
int Startup();
int BeforeEntry();
void Shutdown();
private:

View File

@ -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.

View File

@ -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,

View File

@ -43,6 +43,7 @@ private:
static void StartCallback(void* param);
int PerformHandshake();
int WriteResponse(std::string& response);
void EventThread();
xe_thread_ref thread_;

View File

@ -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.

View File

@ -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;

View File

@ -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();

View File

@ -39,6 +39,8 @@ public:
XboxkrnlModule(Emulator* emulator);
virtual ~XboxkrnlModule();
KernelState* kernel_state() const { return kernel_state_; }
int LaunchModule(const char* path);
private: