#include "wol.h"
#include "vdrrequestpacket.h"
#include "vdrresponsepacket.h"
+#include "command.h"
VDR* VDR::instance = NULL;
void VDR::threadMethod()
{
- threadSetKillable();
+ threadSetKillable(); // FIXME - change this to deal with the EDRs
ULONG channelID;
VDR_ResponsePacket* vresp;
+ int timeoutCount = 0;
+
while(1)
{
- if (!tcp->readData((UCHAR*)&channelID, sizeof(ULONG)))
+ if (!tcp->readData((UCHAR*)&channelID, sizeof(ULONG))) // 2s timeout atm
{
+ ++timeoutCount;
+
// Error or timeout.
- logger->log("VDR", Log::DEBUG, "Net read timeout");
-
- // Do timeouts
- //edLock();
- //for(EDRL::iterator i = receivers.begin(); i != receivers.end(); i++)
- //{
-
-
+
+ // Thsi is the simple version of timeout system until I work out how to make it better
+ // e.g. different timeout lengths for different requests, a decent keepalive system
+ // running in parallel etc etc.
+
+ logger->log("VDR", Log::DEBUG, "Net read timeout %i", timeoutCount);
+
+ if (!tcp->isConnected())// FIXME disabled for now until it works ... !! || (timeoutCount > 10)) // 20s
+ {
+ // timeout, kill it
+
+ connected = false; // though actually it could still be connected until someone calls vdr->disconnect
+
+ // Need to wake up any waiting channel 1 request-response threads
+ // Normally this is done by a packet coming in with channelid and requestid
+ // Instead, go through the list and for each channel 1 edr, make an empty vresp
+ // An empty vresp will have userData == NULL, which means vresp->noResponse() == true
+
+ // If it's a stream receiver, generate a stream packet with flag == connection_lost
+
+ edLock();
+ VDR_PacketReceiver* vdrpr;
+ while(receivers.size())
+ {
+ vdrpr = (VDR_PacketReceiver*) *(receivers.begin());
+ if (vdrpr->receiverChannel == CHANNEL_REQUEST_RESPONSE)
+ {
+ vresp = new VDR_ResponsePacket();
+ vresp->setResponse(vdrpr->requestSerialNumber, NULL, 0);
+ logger->log("VDR", Log::DEBUG, "Timeouts: created blank response packet for request serial %lu", vdrpr->requestSerialNumber);
+ edUnlock();
+ if (!edFindAndCall(vresp)) // makes ED lock, find receiver for vresp (using ed_cb_find() ) and then call (using ed_cb_call() )
+ {
+ // If edFindAndCall returns true, edr was called and vresp was handed off.
+ // else, delete vresp here.
+ logger->log("VDR", Log::ERR, "Timeouts: no waiting thread found for request serial %lu !!!", vdrpr->requestSerialNumber);
+ delete vresp;
+ }
+ edLock();
+ }
+ else if (vdrpr->receiverChannel == CHANNEL_STREAM)
+ {
+ vresp->setStream(vdrpr->streamID, 2 /* connection-lost flag */ , NULL, 0);
+ logger->log("VDR", Log::DEBUG, "Timeouts: created blank response packet for streamid %lu", vdrpr->streamID);
+ edUnlock();
+ if (!edFindAndCall(vresp)) // makes ED lock, find receiver for vresp (using ed_cb_find() ) and then call (using ed_cb_call() )
+ {
+ // If edFindAndCall returns true, edr was called and vresp was handed off.
+ // else, delete vresp here.
+ logger->log("VDR", Log::ERR, "Timeouts: no waiting stream receiver found for streamid %lu !!!", vdrpr->streamID);
+ delete vresp;
+ }
+ edLock();
+ }
+ }
+ edUnlock();
+ // Ok, all event receviers should be dealt with. just in case there weren't any, inform command
+
+ Command::getInstance()->connectionLost();
+
+ // return and stop this thread
+ return;
+ }
+
continue;
}
+
+ // Data was read
+
+ timeoutCount = 0;
+
channelID = ntohl(channelID);
vresp = new VDR_ResponsePacket();