more graceful handling of disconnects
This commit is contained in:
parent
47bc7bb323
commit
b858114c48
|
@ -157,10 +157,11 @@ void WriteGBASave(const u8* savedata, u32 savelen, u32 writeoffset, u32 writelen
|
||||||
bool MP_Init();
|
bool MP_Init();
|
||||||
void MP_DeInit();
|
void MP_DeInit();
|
||||||
int MP_SendPacket(u8* data, int len, u64 timestamp);
|
int MP_SendPacket(u8* data, int len, u64 timestamp);
|
||||||
int MP_RecvPacket(u8* data, bool block, u64* timestamp);
|
int MP_RecvPacket(u8* data, u64* timestamp);
|
||||||
int MP_SendCmd(u8* data, int len, u64 timestamp);
|
int MP_SendCmd(u8* data, int len, u64 timestamp);
|
||||||
int MP_SendReply(u8* data, int len, u64 timestamp, u16 aid);
|
int MP_SendReply(u8* data, int len, u64 timestamp, u16 aid);
|
||||||
int MP_SendAck(u8* data, int len, u64 timestamp);
|
int MP_SendAck(u8* data, int len, u64 timestamp);
|
||||||
|
int MP_RecvHostPacket(u8* data, u64* timestamp);
|
||||||
u16 MP_RecvReplies(u8* data, u64 timestamp, u16 aidmask);
|
u16 MP_RecvReplies(u8* data, u64 timestamp, u16 aidmask);
|
||||||
|
|
||||||
|
|
||||||
|
|
22
src/Wifi.cpp
22
src/Wifi.cpp
|
@ -1150,6 +1150,7 @@ bool CheckRX(int type) // 0=regular 1=MP replies 2=MP host frames
|
||||||
if (IOPORT(W_RXBufBegin) == IOPORT(W_RXBufEnd))
|
if (IOPORT(W_RXBufBegin) == IOPORT(W_RXBufEnd))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
int rxlen;
|
||||||
u16 framelen;
|
u16 framelen;
|
||||||
u16 framectl;
|
u16 framectl;
|
||||||
u8 txrate;
|
u8 txrate;
|
||||||
|
@ -1160,9 +1161,24 @@ bool CheckRX(int type) // 0=regular 1=MP replies 2=MP host frames
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
timestamp = 0;
|
timestamp = 0;
|
||||||
int rxlen = Platform::MP_RecvPacket(RXBuffer, (type != 0), ×tamp);
|
|
||||||
if ((rxlen == 0) && (type == 0)) rxlen = WifiAP::RecvPacket(RXBuffer);
|
if (type == 0)
|
||||||
if (rxlen == 0) return false;
|
{
|
||||||
|
rxlen = Platform::MP_RecvPacket(RXBuffer, ×tamp);
|
||||||
|
if (rxlen <= 0)
|
||||||
|
rxlen = WifiAP::RecvPacket(RXBuffer);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rxlen = Platform::MP_RecvHostPacket(RXBuffer, ×tamp);
|
||||||
|
if (rxlen < 0)
|
||||||
|
{
|
||||||
|
// host is gone
|
||||||
|
IsMPClient = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rxlen <= 0) return false;
|
||||||
if (rxlen < 12+24) continue;
|
if (rxlen < 12+24) continue;
|
||||||
|
|
||||||
framelen = *(u16*)&RXBuffer[10];
|
framelen = *(u16*)&RXBuffer[10];
|
||||||
|
|
|
@ -81,6 +81,8 @@ const u32 kReplyEnd = kQueueSize;
|
||||||
|
|
||||||
const int RecvTimeout = 500;
|
const int RecvTimeout = 500;
|
||||||
|
|
||||||
|
int LastHostID;
|
||||||
|
|
||||||
|
|
||||||
// we need to come up with our own abstraction layer for named semaphores
|
// we need to come up with our own abstraction layer for named semaphores
|
||||||
// because QSystemSemaphore doesn't support waiting with a timeout
|
// because QSystemSemaphore doesn't support waiting with a timeout
|
||||||
|
@ -220,6 +222,8 @@ bool Init()
|
||||||
SemInit(InstanceID);
|
SemInit(InstanceID);
|
||||||
SemInit(16+InstanceID);
|
SemInit(16+InstanceID);
|
||||||
|
|
||||||
|
LastHostID = -1;
|
||||||
|
|
||||||
printf("MP comm init OK, instance ID %d\n", InstanceID);
|
printf("MP comm init OK, instance ID %d\n", InstanceID);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -363,12 +367,7 @@ int SendPacketGeneric(u32 type, u8* packet, int len, u64 timestamp)
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SendPacket(u8* packet, int len, u64 timestamp)
|
int RecvPacketGeneric(u8* packet, bool block, u64* timestamp)
|
||||||
{
|
|
||||||
return SendPacketGeneric(0, packet, len, timestamp);
|
|
||||||
}
|
|
||||||
|
|
||||||
int RecvPacket(u8* packet, bool block, u64* timestamp)
|
|
||||||
{
|
{
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
|
@ -402,14 +401,29 @@ int RecvPacket(u8* packet, bool block, u64* timestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pktheader.Length)
|
if (pktheader.Length)
|
||||||
|
{
|
||||||
FIFORead(0, packet, pktheader.Length);
|
FIFORead(0, packet, pktheader.Length);
|
||||||
|
|
||||||
|
if (pktheader.Type == 1)
|
||||||
|
LastHostID = pktheader.SenderID;
|
||||||
|
}
|
||||||
|
|
||||||
if (timestamp) *timestamp = pktheader.Timestamp;
|
if (timestamp) *timestamp = pktheader.Timestamp;
|
||||||
MPQueue->unlock();
|
MPQueue->unlock();
|
||||||
return pktheader.Length;
|
return pktheader.Length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int SendPacket(u8* packet, int len, u64 timestamp)
|
||||||
|
{
|
||||||
|
return SendPacketGeneric(0, packet, len, timestamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
int RecvPacket(u8* packet, u64* timestamp)
|
||||||
|
{
|
||||||
|
return RecvPacketGeneric(packet, false, timestamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int SendCmd(u8* packet, int len, u64 timestamp)
|
int SendCmd(u8* packet, int len, u64 timestamp)
|
||||||
{
|
{
|
||||||
|
@ -426,10 +440,42 @@ int SendAck(u8* packet, int len, u64 timestamp)
|
||||||
return SendPacketGeneric(3, packet, len, timestamp);
|
return SendPacketGeneric(3, packet, len, timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int RecvHostPacket(u8* packet, u64* timestamp)
|
||||||
|
{
|
||||||
|
if (LastHostID != -1)
|
||||||
|
{
|
||||||
|
// check if the host is still connected
|
||||||
|
|
||||||
|
MPQueue->lock();
|
||||||
|
u8* data = (u8*)MPQueue->data();
|
||||||
|
MPQueueHeader* header = (MPQueueHeader*)&data[0];
|
||||||
|
u16 curinstmask = header->InstanceBitmask;
|
||||||
|
MPQueue->unlock();
|
||||||
|
|
||||||
|
if (!(curinstmask & (1 << LastHostID)))
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return RecvPacketGeneric(packet, true, timestamp);
|
||||||
|
}
|
||||||
|
|
||||||
u16 RecvReplies(u8* packets, u64 timestamp, u16 aidmask)
|
u16 RecvReplies(u8* packets, u64 timestamp, u16 aidmask)
|
||||||
{
|
{
|
||||||
u16 ret = 0;
|
u16 ret = 0;
|
||||||
u16 instmask = (1 << InstanceID);
|
u16 myinstmask = (1 << InstanceID);
|
||||||
|
u16 curinstmask;
|
||||||
|
|
||||||
|
{
|
||||||
|
MPQueue->lock();
|
||||||
|
u8* data = (u8*)MPQueue->data();
|
||||||
|
MPQueueHeader* header = (MPQueueHeader*)&data[0];
|
||||||
|
curinstmask = header->InstanceBitmask;
|
||||||
|
MPQueue->unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
// if all clients have left: return early
|
||||||
|
if ((myinstmask & curinstmask) == curinstmask)
|
||||||
|
return 0;
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
|
@ -472,8 +518,8 @@ u16 RecvReplies(u8* packets, u64 timestamp, u16 aidmask)
|
||||||
ret |= (1 << aid);
|
ret |= (1 << aid);
|
||||||
}
|
}
|
||||||
|
|
||||||
instmask |= (1 << pktheader.SenderID);
|
myinstmask |= (1 << pktheader.SenderID);
|
||||||
if ((instmask & header->InstanceBitmask) == header->InstanceBitmask)
|
if ((myinstmask & curinstmask) == curinstmask)
|
||||||
{
|
{
|
||||||
// all the clients have sent their reply
|
// all the clients have sent their reply
|
||||||
|
|
||||||
|
|
|
@ -27,10 +27,11 @@ namespace LocalMP
|
||||||
bool Init();
|
bool Init();
|
||||||
void DeInit();
|
void DeInit();
|
||||||
int SendPacket(u8* data, int len, u64 timestamp);
|
int SendPacket(u8* data, int len, u64 timestamp);
|
||||||
int RecvPacket(u8* data, bool block, u64* timestamp);
|
int RecvPacket(u8* data, u64* timestamp);
|
||||||
int SendCmd(u8* data, int len, u64 timestamp);
|
int SendCmd(u8* data, int len, u64 timestamp);
|
||||||
int SendReply(u8* data, int len, u64 timestamp, u16 aid);
|
int SendReply(u8* data, int len, u64 timestamp, u16 aid);
|
||||||
int SendAck(u8* data, int len, u64 timestamp);
|
int SendAck(u8* data, int len, u64 timestamp);
|
||||||
|
int RecvHostPacket(u8* data, u64* timestamp);
|
||||||
u16 RecvReplies(u8* data, u64 timestamp, u16 aidmask);
|
u16 RecvReplies(u8* data, u64 timestamp, u16 aidmask);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -374,9 +374,9 @@ int MP_SendPacket(u8* data, int len, u64 timestamp)
|
||||||
return LocalMP::SendPacket(data, len, timestamp);
|
return LocalMP::SendPacket(data, len, timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
int MP_RecvPacket(u8* data, bool block, u64* timestamp)
|
int MP_RecvPacket(u8* data, u64* timestamp)
|
||||||
{
|
{
|
||||||
return LocalMP::RecvPacket(data, block, timestamp);
|
return LocalMP::RecvPacket(data, timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
int MP_SendCmd(u8* data, int len, u64 timestamp)
|
int MP_SendCmd(u8* data, int len, u64 timestamp)
|
||||||
|
@ -394,6 +394,11 @@ int MP_SendAck(u8* data, int len, u64 timestamp)
|
||||||
return LocalMP::SendAck(data, len, timestamp);
|
return LocalMP::SendAck(data, len, timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int MP_RecvHostPacket(u8* data, u64* timestamp)
|
||||||
|
{
|
||||||
|
return LocalMP::RecvHostPacket(data, timestamp);
|
||||||
|
}
|
||||||
|
|
||||||
u16 MP_RecvReplies(u8* data, u64 timestamp, u16 aidmask)
|
u16 MP_RecvReplies(u8* data, u64 timestamp, u16 aidmask)
|
||||||
{
|
{
|
||||||
return LocalMP::RecvReplies(data, timestamp, aidmask);
|
return LocalMP::RecvReplies(data, timestamp, aidmask);
|
||||||
|
|
Loading…
Reference in New Issue