Add ability to change SI channel and detect disconnections

This commit is contained in:
Jack Andersen 2017-01-07 16:51:38 -10:00
parent 4699542f93
commit 0153e0ee6a
3 changed files with 54 additions and 12 deletions

View File

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

View File

@ -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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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;

View File

@ -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<std::mutex> lk(m_queueLock);
m_endpointQueue.push(std::make_unique<Endpoint>(
chan++, std::move(acceptData), std::move(acceptClock)));
0, std::move(acceptData), std::move(acceptClock)));
}
WaitGCTicks(GetGCTicksPerSec());
}