Connection failed detection
authorChris Tallon <chris@vomp.tv>
Sun, 12 Mar 2006 17:31:45 +0000 (17:31 +0000)
committerChris Tallon <chris@vomp.tv>
Sun, 12 Mar 2006 17:31:45 +0000 (17:31 +0000)
14 files changed:
command.cc
command.h
message.h
tcp.cc
vdr.cc
vdr.h
vinfo.cc
vinfo.h
vrecordinglist.cc
vrecordinglist.h
vrecordingmenu.cc
vrecordingmenu.h
vvideorec.cc
vwelcome.cc

index 7409b3076aa48da881912c78b98d1efdb68c7154..a65538d5339dfe175ae308cd8e739c018076f8ab 100644 (file)
@@ -29,6 +29,7 @@ Command::Command()
   initted = 0;
   isStandby = 0;
   firstBoot = 1;
+  connLost = NULL;
 }
 
 Command::~Command()
@@ -230,6 +231,12 @@ void Command::processMessage(Message* m)
     case Message::SCREENSHOT:
     {
       Osd::getInstance()->screenShot("/out.jpg");
+      break;
+    }
+    case Message::CONNECTION_LOST:
+    {
+      doFromTheTop(true);
+      break;
     }
   }
 }
@@ -238,7 +245,7 @@ void Command::handleCommand(int button)
 {
   if (isStandby && (button != Remote::POWER)) return;
 
-  if (viewman->handleCommand(button)) return;
+  if (!connLost && viewman->handleCommand(button)) return; // don't send to viewman if connLost
 
   // command was not handled
 
@@ -267,6 +274,12 @@ void Command::handleCommand(int button)
       doStandby();
       return;
     }
+    case Remote::OK:
+    {
+      if (!connLost) return; // if connLost, handle Remote::OK
+      doFromTheTop(false);
+      return;
+    }
   }
 }
 
@@ -306,6 +319,37 @@ void Command::doStandby()
   }
 }
 
+void Command::doFromTheTop(bool which)
+{
+  if (which)
+  {
+    connLost = new VInfo();
+    connLost->create(360, 200);
+    if (Video::getInstance()->getFormat() == Video::PAL)
+      connLost->setScreenPos(190, 170);
+    else
+      connLost->setScreenPos(180, 120);
+    connLost->setOneLiner(tr("Connection lost"));
+    connLost->setDropThrough();
+    connLost->setBorderOn(1);
+    connLost->setTitleBarColour(Colour::DANGER);
+    connLost->okButton();
+    connLost->draw();
+    viewman->add(connLost);
+    viewman->updateView(connLost);
+  }
+  else
+  {
+    VDR::getInstance()->disconnect();
+    viewman->removeAll();
+    viewman->updateView(wallpaper);
+    connLost = NULL;
+    VConnect* vconnect = new VConnect();
+    viewman->add(vconnect);
+    vconnect->run();
+  }
+}
+
 void Command::doReboot()
 {
   VDR::getInstance()->disconnect();
@@ -314,6 +358,14 @@ void Command::doReboot()
   reboot(LINUX_REBOOT_CMD_RESTART);
 }
 
+void Command::connectionLost()
+{
+  Message* m = new Message(); // break into master mutex
+  m->message = Message::CONNECTION_LOST;
+  m->to = this;
+  postMessageNoLock(m);
+}
+
 void Command::doJustConnected(VConnect* vconnect)
 {
   I18n::initialize();
index 13db4e25ea12780b92abdea4fadb771d57c75fe0..2760f744bf20b3c7017433a2bec12145bf5c5335 100644 (file)
--- a/command.h
+++ b/command.h
@@ -71,12 +71,14 @@ class Command : public MessageQueue
     void postMessageNoLock(Message* m); // override of MessageQueue::postMessage
     bool postMessageIfNotBusy(Message* m); // for timers, when masterMutex might be locked
     void sig1();
+    void connectionLost();
 
   private:
     void handleCommand(int);
     void doStandby();
     void doJustConnected(VConnect* vconnect);
     void doWallpaper();
+    void doFromTheTop(bool which);  // true - show vinfo,wait. false - del vinfo,restart
 
     static Command* instance;
     pid_t mainPid;
@@ -90,6 +92,7 @@ class Command : public MessageQueue
     ViewMan* viewman;
     Remote* remote;
     VWallpaper* wallpaper;
+    VInfo* connLost;
 
     void processMessage(Message* m);
 };
index 3508883fbcc1a3a155bafaec33535895b52bbb60..f16262eaeca7e8055f9d201f90396ed06b50fd94 100644 (file)
--- a/message.h
+++ b/message.h
@@ -61,6 +61,7 @@ class Message
     const static ULONG EPG = 16;
     const static ULONG EPG_CLOSE = 17;
     const static ULONG CHANGED_OPTIONS = 18;
+    const static ULONG CONNECTION_LOST = 19;
 };
 
 #endif
diff --git a/tcp.cc b/tcp.cc
index 61a079ac15e930225925b450730d97b06b62f71f..07276abeb00a9370c5853bb4bbf214d43df7879a 100644 (file)
--- a/tcp.cc
+++ b/tcp.cc
@@ -249,7 +249,7 @@ int TCP::readData(UCHAR* buffer, int totalBytes)
   {
     FD_ZERO(&readSet);
     FD_SET(sock, &readSet);
-    timeout.tv_sec = 10;
+    timeout.tv_sec = 30;
     timeout.tv_usec = 0;
     success = select(sock + 1, &readSet, NULL, NULL, passToSelect);
     if (success < 1)
diff --git a/vdr.cc b/vdr.cc
index 92d50557d4503c0b192a01b4d0d7df533cc28c2c..0eee6eac660aa3208a696d0e75c6d5da0b555ad8 100644 (file)
--- a/vdr.cc
+++ b/vdr.cc
@@ -162,7 +162,11 @@ void VDR::setReceiveWindow(size_t size)
 int VDR::getPacket()
 {
   packet = (UCHAR*)tcp->receivePacket();
-  if (!packet) return 0;
+  if (!packet)
+  {
+    disconnect();
+    return 0;
+  }
   packetLength = tcp->getDataLength();
   return 1;
 }
@@ -236,6 +240,7 @@ int VDR::doLogin()
   int a = tcp->sendPacket(buffer, 14);
   if (a != 14)
   {
+    disconnect();
     pthread_mutex_unlock(&mutex);
     return 0;
   }
@@ -304,6 +309,7 @@ Directory* VDR::getRecordingsList()
   int a = tcp->sendPacket(buffer, 8);
   if (a != 8)
   {
+    disconnect();
     pthread_mutex_unlock(&mutex);
     return NULL;
   }
@@ -398,6 +404,7 @@ int VDR::deleteRecording(char* fileName)
   unsigned int a = tcp->sendPacket(buffer, totalLength);
   if (a != totalLength)
   {
+    disconnect();
     pthread_mutex_unlock(&mutex);
     return 0;
   }
@@ -430,6 +437,7 @@ char* VDR::getRecordingSummary(char* fileName)
   unsigned int a = tcp->sendPacket(buffer, totalLength);
   if (a != totalLength)
   {
+    disconnect();
     pthread_mutex_unlock(&mutex);
     return NULL;
   }
@@ -459,6 +467,7 @@ ChannelList* VDR::getChannelsList(ULONG type)
   int a = tcp->sendPacket(buffer, 8);
   if (a != 8)
   {
+    disconnect();
     pthread_mutex_unlock(&mutex);
     return NULL;
   }
@@ -512,6 +521,7 @@ int VDR::streamChannel(ULONG number)
 
   if (a != 12)
   {
+    disconnect();
     pthread_mutex_unlock(&mutex);
     return 0;
   }
@@ -543,6 +553,7 @@ int VDR::stopStreaming()
 
   if (a != 8)
   {
+    disconnect();
     pthread_mutex_unlock(&mutex);
     return 0;
   }
@@ -575,6 +586,7 @@ UCHAR* VDR::getBlock(ULLONG position, UINT maxAmount, UINT* amountReceived)
   int a = tcp->sendPacket(buffer, 20);
   if (a != 20)
   {
+    disconnect();
     pthread_mutex_unlock(&mutex);
     return NULL;
   }
@@ -611,6 +623,7 @@ ULLONG VDR::streamRecording(Recording* rec)
   unsigned int a = tcp->sendPacket(buffer, totalLength);
   if (a != totalLength)
   {
+    disconnect();
     pthread_mutex_unlock(&mutex);
     return 0;
   }
@@ -644,6 +657,7 @@ ULLONG VDR::rescanRecording()
   unsigned int a = tcp->sendPacket(buffer, totalLength);
   if (a != totalLength)
   {
+    disconnect();
     pthread_mutex_unlock(&mutex);
     return 0;
   }
@@ -678,6 +692,7 @@ ULLONG VDR::positionFromFrameNumber(ULONG frameNumber)
   unsigned int a = tcp->sendPacket(buffer, totalLength);
   if (a != totalLength)
   {
+    disconnect();
     pthread_mutex_unlock(&mutex);
     return 0;
   }
@@ -722,6 +737,7 @@ EventList* VDR::getChannelSchedule(ULONG number, time_t start, ULONG duration)
 
   if (a != 20)
   {
+    disconnect();
     pthread_mutex_unlock(&mutex);
     return NULL;
   }
@@ -735,6 +751,7 @@ EventList* VDR::getChannelSchedule(ULONG number, time_t start, ULONG duration)
   if (serverError())
   {
     freePacket();
+    disconnect();
     pthread_mutex_unlock(&mutex);
     return NULL;
   }
@@ -812,6 +829,7 @@ int VDR::configSave(char* section, char* key, const char* value)
   unsigned int a = tcp->sendPacket(buffer, totalLength);
   if (a != totalLength)
   {
+    disconnect();
     pthread_mutex_unlock(&mutex);
     return 0;
   }
@@ -848,6 +866,7 @@ char* VDR::configLoad(char* section, char* key)
   unsigned int a = tcp->sendPacket(buffer, totalLength);
   if (a != totalLength)
   {
+    disconnect();
     pthread_mutex_unlock(&mutex);
     return NULL;
   }
@@ -861,6 +880,8 @@ char* VDR::configLoad(char* section, char* key)
   freePacket();
   pthread_mutex_unlock(&mutex);
 
+  printf("%p %s\n", toReturn, toReturn);
+
   return toReturn;
 }
 
@@ -877,6 +898,7 @@ RecTimerList* VDR::getRecTimersList()
   int a = tcp->sendPacket(buffer, 8);
   if (a != 8)
   {
+    disconnect();
     pthread_mutex_unlock(&mutex);
     return NULL;
   }
@@ -945,6 +967,7 @@ ULONG VDR::setEventTimer(char* timerString)
   unsigned int a = tcp->sendPacket(buffer, totalLength);
   if (a != totalLength)
   {
+    disconnect();
     pthread_mutex_unlock(&mutex);
     return 0;
   }
diff --git a/vdr.h b/vdr.h
index 0c4dd7fd296c2affe0b6df4d078af8f36721cd5b..616c30899edc451298550dfcdd61aced71b66797 100644 (file)
--- a/vdr.h
+++ b/vdr.h
@@ -39,8 +39,6 @@
 
 using namespace std;
 
- // FIXME do some tcp connection error checking and kill it!
-
 typedef vector<Event*> EventList;
 typedef vector<Channel*> ChannelList;
 typedef vector<RecTimer*> RecTimerList;
@@ -106,11 +104,30 @@ class VDR
     void setServerIP(char*);
     int connect();
     void disconnect();
+    bool isConnected() { return connected; }
     ULLONG getResumePoint(char* fileName);  // uses configLoad
 
     void setReceiveWindow(size_t size);
 
     // protocol functions
+    // for the following, if result == false then the connection has died
+    //  doLogin
+    //  getRecordingList
+    //  getChannelsList
+    //  getChannelSchedule
+    //  getRecTimersList
+    // isConnected can be called after the following to determine if still ok
+    //  getRecordingSummary
+    //  deleteRecording
+    //  streamRecording
+    //  rescanRecording
+    //  positionFromFrameNumber
+    //  streamChannel
+    //  getBlock
+    //  stopStreaming
+    //  configLoad
+    //  configSave
+    //  setEventTimer
 
     int doLogin();
 
index 3760da736228fbf3ef303524ddcd8be23d2c9ebd..1febf929070bd3a83408a8ee16532f40d287d312 100644 (file)
--- a/vinfo.cc
+++ b/vinfo.cc
@@ -25,6 +25,7 @@ VInfo::VInfo()
   mainText = NULL;
   exitable = 0;
   dropThrough = 0;
+  okbutton = false;
 
   setBackgroundColour(Colour::VIEWBACKGROUND);
   setTitleBarOn(1);
@@ -79,6 +80,16 @@ void VInfo::draw()
       else drawTextCentre(mainText, area.w / 2, 55, Colour::LIGHTTEXT);
     }
   }
+
+  if (okbutton)
+  {
+    WButton button;
+    button.setSurface(surface);
+    button.setSurfaceOffset((area.w / 2) - 30, area.h - 50);
+    button.setText(tr("OK"));
+    button.setActive(1);
+    button.draw();
+  }
 }
 
 int VInfo::handleCommand(int command)
@@ -96,3 +107,8 @@ int VInfo::handleCommand(int command)
 
   return 1;
 }
+
+void VInfo::okButton()
+{
+  okbutton = true;
+}
diff --git a/vinfo.h b/vinfo.h
index 5a8b286dc2779ef10e74b568666118f9e3469a49..d8e7783932c482627dd539ec94c7b078d02abd8c 100644 (file)
--- a/vinfo.h
+++ b/vinfo.h
@@ -28,6 +28,8 @@
 #include "view.h"
 #include "remote.h"
 #include "colour.h"
+#include "wbutton.h"
+#include "i18n.h"
 
 class VInfo : public View
 {
@@ -39,6 +41,7 @@ class VInfo : public View
     void setOneLiner(char* text);
     void setExitable();
     void setDropThrough();
+    void okButton();
 
     virtual int handleCommand(int command);
     void draw();
@@ -48,6 +51,8 @@ class VInfo : public View
     UCHAR exitable;
     UCHAR dropThrough;
     UCHAR mainTextType;
+    bool okbutton;
+
     const static UCHAR NORMAL = 1;
     const static UCHAR ONELINER = 2;
 };
index bd1575e115029c612d71a7534c220b80a9e286a0..8fc3948c7d29c0f1489dd0133e5e7892b978f257 100644 (file)
@@ -219,7 +219,13 @@ void VRecordingList::doDeleteSelected()
     Log::getInstance()->log("VRecordingList", Log::DEBUG, "FOUND: %i %s %s", toDelete->index, toDelete->getProgName(), toDelete->fileName);
 
     VDR* vdr = VDR::getInstance();
-    vdr->deleteRecording(toDelete->fileName);
+    int success = vdr->deleteRecording(toDelete->fileName);
+    if (!success && !vdr->isConnected())
+    {
+      Command::getInstance()->connectionLost();
+    }
+
+    // FIXME add notify of fail to delete
 
     delete toDelete;
 
index ac7c823d3d6d8c46dc818fae4ec56bbd7aeef988..48ff61f21cb911bd5eff0a71a7569ab75b8e7e0f 100644 (file)
@@ -39,6 +39,7 @@
 #include "colour.h"
 #include "video.h"
 #include "i18n.h"
+#include "command.h"
 
 class VRecordingList : public View
 {
index eaa887979babdbd05aae751f797bc16ac3642949..87ee0c330c50071ab225fdfca30ef31a5db9b471 100644 (file)
@@ -34,7 +34,6 @@ VRecordingMenu::VRecordingMenu()
     setScreenPos(250, 160);
   }
 
-
   setBackgroundColour(Colour::VIEWBACKGROUND);
   setTitleBarOn(1);
   setBorderOn(1);
@@ -115,6 +114,11 @@ int VRecordingMenu::handleCommand(int command)
       if (sl.getCurrentOption() == 2)
       {
         char* summary = VDR::getInstance()->getRecordingSummary(rec->fileName);
+        if (!summary && !VDR::getInstance()->isConnected())
+        {
+          Command::getInstance()->connectionLost();
+          return 2;
+        }
 
         VInfo* vi = new VInfo();
         vi->setTitleText(tr("Programme summary"));
index 3fae830ad85bf22b0cb7e4939e7192d2cad1092c..a72e2b06a6040fe519adc47967cf47caa84f848b 100644 (file)
@@ -36,6 +36,7 @@
 #include "colour.h"
 #include "video.h"
 #include "i18n.h"
+#include "command.h"
 
 class VRecordingList;
 
index d4d921e3bdb184cdfa360a80a247aa9bb2ff14c0..63cb0bc921c07a2f5a14fbccaefcab8eba817743 100644 (file)
@@ -106,6 +106,14 @@ void VVideoRec::go(ULLONG startPosition)
   }
   else
   {
+    stopPlay(); // clean up
+
+    if (!vdr->isConnected())
+    {
+      Command::getInstance()->connectionLost();
+      return;
+    }
+
     ViewMan* viewman = ViewMan::getInstance();
 
     Message* m = new Message();
index b495bae03ff2b0bc9ccc741ee1ab41cfb5cf68c0..7f20431df774bfc20ba44a1fdc16d304e6a7ce40 100644 (file)
@@ -268,10 +268,12 @@ void VWelcome::doRecordingsList()
     viewman->add(vrec);
     viewman->updateView(vrec);
   }
+  else
+  {
+    Command::getInstance()->connectionLost();
+  }
 
-  Log::getInstance()->log("VWelcome", Log::DEBUG, "possible delay start");
   viewman->removeView(viewWait);
-  Log::getInstance()->log("VWelcome", Log::DEBUG, "possible delay end");
 }
 
 void VWelcome::doTimersList()