From 0153e0ee6a1fdb1ff90fbb814365baaca802519d Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Sat, 7 Jan 2017 16:51:38 -1000 Subject: [PATCH] Add ability to change SI channel and detect disconnections --- include/jbus/Endpoint.hpp | 21 ++++++++++++++++---- lib/Endpoint.cpp | 40 ++++++++++++++++++++++++++++++++++----- lib/Listener.cpp | 5 ++--- 3 files changed, 54 insertions(+), 12 deletions(-) diff --git a/include/jbus/Endpoint.hpp b/include/jbus/Endpoint.hpp index b145005..cc29a42 100644 --- a/include/jbus/Endpoint.hpp +++ b/include/jbus/Endpoint.hpp @@ -176,7 +176,7 @@ class Endpoint public: /** @brief Request stop of I/O thread and block until joined. - * Further use of this Endpoint is undefined behavior. + * Further use of this Endpoint will return GBA_NOT_READY. * The destructor calls this implicitly. */ void stop(); @@ -246,8 +246,21 @@ public: FGBACallback&& callback); /** @brief Get virtual SI channel assigned to this endpoint. - * @return SI channel */ - int GetChan() const { return m_chan; } + * @return SI channel [0,3] */ + unsigned getChan() const { return m_chan; } + + /** @brief Set virtual SI channel assigned to this endpoint. + * @param chan SI channel [0,3] */ + void setChan(unsigned chan) + { + if (chan > 3) + chan = 3; + m_chan = chan; + } + + /** @brief Get connection status of this endpoint + * @return true if connected */ + bool connected() const { return m_running; } Endpoint(u8 chan, net::Socket&& data, net::Socket&& clock); ~Endpoint(); @@ -291,7 +304,7 @@ public: /** @brief Get virtual SI channel assigned to this endpoint. * @return SI channel */ - int GetChan() const { return m_ep.GetChan(); } + int getChan() const { return m_ep.getChan(); } }; } diff --git a/lib/Endpoint.cpp b/lib/Endpoint.cpp index f9cd998..647502a 100644 --- a/lib/Endpoint.cpp +++ b/lib/Endpoint.cpp @@ -177,7 +177,7 @@ void Endpoint::KawasedoChallenge::_4TransmitProgram(ThreadLocalEndpoint& endpoin } else if (x34_bytesSent == 0xc4) { - cryptWindow = endpoint.GetChan() << 0x8; + cryptWindow = endpoint.getChan() << 0x8; } if (x34_bytesSent >= 0xc0) @@ -569,6 +569,9 @@ void Endpoint::stop() EJoyReturn Endpoint::GBAGetProcessStatus(u8& percentOut) { + if (!m_running) + return GBA_NOT_READY; + std::unique_lock lk(m_syncLock); if (m_joyBoot) { @@ -585,6 +588,9 @@ EJoyReturn Endpoint::GBAGetProcessStatus(u8& percentOut) EJoyReturn Endpoint::GBAGetStatusAsync(u8* status, FGBACallback&& callback) { + if (!m_running) + return GBA_NOT_READY; + std::unique_lock lk(m_syncLock); if (m_cmdIssued) return GBA_NOT_READY; @@ -601,6 +607,9 @@ EJoyReturn Endpoint::GBAGetStatusAsync(u8* status, FGBACallback&& callback) EJoyReturn Endpoint::GBAGetStatus(u8* status) { + if (!m_running) + return GBA_NOT_READY; + std::unique_lock lk(m_syncLock); if (m_cmdIssued) return GBA_NOT_READY; @@ -618,6 +627,9 @@ EJoyReturn Endpoint::GBAGetStatus(u8* status) EJoyReturn Endpoint::GBAResetAsync(u8* status, FGBACallback&& callback) { + if (!m_running) + return GBA_NOT_READY; + std::unique_lock lk(m_syncLock); if (m_cmdIssued) return GBA_NOT_READY; @@ -634,6 +646,9 @@ EJoyReturn Endpoint::GBAResetAsync(u8* status, FGBACallback&& callback) EJoyReturn Endpoint::GBAReset(u8* status) { + if (!m_running) + return GBA_NOT_READY; + std::unique_lock lk(m_syncLock); if (m_cmdIssued) return GBA_NOT_READY; @@ -651,6 +666,9 @@ EJoyReturn Endpoint::GBAReset(u8* status) EJoyReturn Endpoint::GBAReadAsync(u8* dst, u8* status, FGBACallback&& callback) { + if (!m_running) + return GBA_NOT_READY; + std::unique_lock lk(m_syncLock); if (m_cmdIssued) return GBA_NOT_READY; @@ -668,6 +686,9 @@ EJoyReturn Endpoint::GBAReadAsync(u8* dst, u8* status, FGBACallback&& callback) EJoyReturn Endpoint::GBARead(u8* dst, u8* status) { + if (!m_running) + return GBA_NOT_READY; + std::unique_lock lk(m_syncLock); if (m_cmdIssued) return GBA_NOT_READY; @@ -686,6 +707,9 @@ EJoyReturn Endpoint::GBARead(u8* dst, u8* status) EJoyReturn Endpoint::GBAWriteAsync(const u8* src, u8* status, FGBACallback&& callback) { + if (!m_running) + return GBA_NOT_READY; + std::unique_lock lk(m_syncLock); if (m_cmdIssued) return GBA_NOT_READY; @@ -704,6 +728,9 @@ EJoyReturn Endpoint::GBAWriteAsync(const u8* src, u8* status, FGBACallback&& cal EJoyReturn Endpoint::GBAWrite(const u8* src, u8* status) { + if (!m_running) + return GBA_NOT_READY; + std::unique_lock lk(m_syncLock); if (m_cmdIssued) return GBA_NOT_READY; @@ -725,6 +752,9 @@ EJoyReturn Endpoint::GBAJoyBootAsync(s32 paletteColor, s32 paletteSpeed, const u8* programp, s32 length, u8* status, FGBACallback&& callback) { + if (!m_running) + return GBA_NOT_READY; + if (m_chan > 3) return GBA_JOYBOOT_ERR_INVALID; @@ -758,7 +788,7 @@ Endpoint::~Endpoint() { stop(); } EJoyReturn ThreadLocalEndpoint::GBAGetStatusAsync(u8* status, FGBACallback&& callback) { - if (m_ep.m_cmdIssued) + if (!m_ep.m_running || m_ep.m_cmdIssued) return GBA_NOT_READY; m_ep.m_cmdIssued = true; @@ -771,7 +801,7 @@ EJoyReturn ThreadLocalEndpoint::GBAGetStatusAsync(u8* status, FGBACallback&& cal EJoyReturn ThreadLocalEndpoint::GBAResetAsync(u8* status, FGBACallback&& callback) { - if (m_ep.m_cmdIssued) + if (!m_ep.m_running || m_ep.m_cmdIssued) return GBA_NOT_READY; m_ep.m_cmdIssued = true; @@ -784,7 +814,7 @@ EJoyReturn ThreadLocalEndpoint::GBAResetAsync(u8* status, FGBACallback&& callbac EJoyReturn ThreadLocalEndpoint::GBAReadAsync(u8* dst, u8* status, FGBACallback&& callback) { - if (m_ep.m_cmdIssued) + if (!m_ep.m_running || m_ep.m_cmdIssued) return GBA_NOT_READY; m_ep.m_cmdIssued = true; @@ -798,7 +828,7 @@ EJoyReturn ThreadLocalEndpoint::GBAReadAsync(u8* dst, u8* status, FGBACallback&& EJoyReturn ThreadLocalEndpoint::GBAWriteAsync(const u8* src, u8* status, FGBACallback&& callback) { - if (m_ep.m_cmdIssued) + if (!m_ep.m_running || m_ep.m_cmdIssued) return GBA_NOT_READY; m_ep.m_cmdIssued = true; diff --git a/lib/Listener.cpp b/lib/Listener.cpp index f28a581..b8be591 100644 --- a/lib/Listener.cpp +++ b/lib/Listener.cpp @@ -57,8 +57,7 @@ void Listener::listenerProc() net::Socket acceptData = {true}; net::Socket acceptClock = {true}; std::string hostname; - u8 chan = 1; - while (m_running && chan < 4) + while (m_running) { if (m_dataServer.accept(acceptData, hostname) == net::Socket::EResult::OK) { @@ -76,7 +75,7 @@ void Listener::listenerProc() { std::unique_lock lk(m_queueLock); m_endpointQueue.push(std::make_unique( - chan++, std::move(acceptData), std::move(acceptClock))); + 0, std::move(acceptData), std::move(acceptClock))); } WaitGCTicks(GetGCTicksPerSec()); }