From 4ddd04707a3e166c55b3dd8abbb91367bda53dbb Mon Sep 17 00:00:00 2001 From: Chris Tallon Date: Sun, 24 Jul 2005 17:18:04 +0000 Subject: [PATCH] Fix for cant power down if server unavailable Support for bootup power state --- Makefile | 2 +- command.cc | 343 +++++++++++++++-------------------------------- command.h | 13 +- message.h | 2 + remote.cc | 7 + vconnect.cc | 158 ++++++++++++++++++++++ vconnect.h | 60 +++++++++ vdr.cc | 3 +- view.cc | 5 + view.h | 2 + vinfo.h | 6 +- vquestion.cc | 7 +- vquestion.h | 2 - vserverselect.cc | 9 +- vserverselect.h | 4 +- 15 files changed, 361 insertions(+), 262 deletions(-) create mode 100644 vconnect.cc create mode 100644 vconnect.h diff --git a/Makefile b/Makefile index e58d89f..1ccbb7d 100644 --- a/Makefile +++ b/Makefile @@ -15,7 +15,7 @@ OBJECTS = main.o command.o log.o remote.o led.o mtd.o video.o audio.o tcp.o dire list.o queue.o node.o recording.o channel.o message.o playerradio.o messagequeue.o \ view.o vinfo.o vwallpaper.o vvolume.o vrecordinglist.o vlivebanner.o vmute.o \ vrecordingmenu.o vquestion.o vchannellist.o vwelcome.o vvideolive.o vvideorec.o vradiolive.o \ - vchannelselect.o vserverselect.o colour.o \ + vchannelselect.o vserverselect.o colour.o vconnect.o \ wselectlist.o wjpeg.o wsymbol.o wbutton.o \ fonts/helvB24.o fonts/helvB18.o diff --git a/command.cc b/command.cc index 8667409..06ae398 100644 --- a/command.cc +++ b/command.cc @@ -27,7 +27,8 @@ Command::Command() if (instance) return; instance = this; initted = 0; - state = 0; + isStandby = 0; + firstBoot = 1; } Command::~Command() @@ -113,138 +114,14 @@ void Command::run() w->show(); viewman->add(w); + VConnect* vconnect = new VConnect(); + viewman->add(vconnect); + vconnect->run(); -// handleCommand(Remote::TWO); -// handleCommand(Remote::UP); -// handleCommand(Remote::PLAY); -// handleCommand(Remote::DOWN); -// handleCommand(Remote::OK); - -// handleCommand(Remote::DOWN); -// handleCommand(Remote::DOWN); -// handleCommand(Remote::DOWN); -// handleCommand(Remote::OK); - - // state values: - // 0 = not connected - // 1 = got servers - // 2 = multiple servers, showing select box - // 3 = a server has been selected - // 4 = connected - // 5 = standby - - int selectServer; UCHAR button = 0; while(irun) { - if (state != 4) // not really necessary, but chops out all the connecting rubbish if already connected - { - if (state == 0) - { - clearServerIPs(); - broadcastForServers(); - if (!irun) break; - state = 1; - } - - if (state == 1) - { - if (serverIPs.size() == 1) - { - selectServer = 0; - state = 3; - } - else - { - selectServer = -1; - state = 2; - VServerSelect* vs = new VServerSelect(&serverIPs, &selectServer); - vs->draw(); - vs->show(); - viewman->add(vs); - } - } - - if (state == 2) - { - // entering loop for 2nd time.. has a server been selected? - if (selectServer != -1) state = 3; - } - - if (state == 3) - { - logger->log("Command", Log::DEBUG, "Server selected: %i", selectServer); - - int success = connectToServer(selectServer); - clearServerIPs(); - - if (success) - { - VWelcome* vw = new VWelcome(); - vw->draw(); - vw->show(); - viewman->add(vw); - state = 4; - - // test area for just after connect - char* svideo = VDR::getInstance()->configLoad("TV", "S-Video"); - - if (svideo) - { - if (!strcasecmp(svideo, "Yes")) - { - logger->log("Command", Log::INFO, "Switching to S-Video as S-Video=%s", svideo); - video->setConnection(Video::SVIDEO); - } - else - { - logger->log("Command", Log::INFO, "Leaving video output as S-Video=%s", svideo); - video->setConnection(Video::COMPOSITERGB); - } - } - else - { - logger->log("Command", Log::INFO, "Config TV/S-Video not found"); - } - -/* - - if ((isWidescreen != NULL) && (!strcmp(isWidescreen, "Yes"))) - { - logger->log("Command", Log::DEBUG, "Setting 16x9"); - - int a = video->setAspectRatio(Video::ASPECT16X9); - printf("success = %i\n", a); - video->reset(); - } - else - { - //temp - logger->log("Command", Log::DEBUG, "Setting 4x3"); - int a = video->setAspectRatio(Video::ASPECT4X3); - printf("success = %i\n", a); - video->reset(); - } -*/ - - // end of test area - - } - else - { - state = 0; - } - } - - if (state == 0) continue; - // state can't be 1 - // if state == 2 then drop to remote handling below - // state can't be 3 - // if state == 4 then drop through to main system, job done - } - - button = remote->getButtonPress(2); // FIXME why is this set to 2 and not 0? so it can quit if ((button == Remote::NONE) || (button == Remote::UNKNOWN)) continue; @@ -275,22 +152,17 @@ void Command::processMessage(Message* m) handleCommand(Remote::STOP); // an odd way of doing it, but so simple break; } + case Message::VDR_CONNECTED: + { + doJustConnected((VConnect*)m->from); + break; + } } } -void Command::clearServerIPs() -{ - // Clear the serverIPs vector - for(UINT k = 0; k < serverIPs.size(); k++) - { - delete[] serverIPs[k]; - } - serverIPs.clear(); -} - void Command::handleCommand(int button) { - if (state == 5 && (button != Remote::POWER)) return; + if (isStandby && (button != Remote::POWER)) return; if (viewman->handleCommand(button)) return; @@ -329,136 +201,133 @@ void Command::handleCommand(int button) } } -void Command::broadcastForServers() +void Command::doStandby() { - VInfo* viewWait = new VInfo(); - viewWait->setDimensions(200, 400); - if (Video::getInstance()->getFormat() == Video::PAL) + if (isStandby) { - viewWait->setScreenPos(170, 200); + Video::getInstance()->signalOn(); + Led::getInstance()->on(); + isStandby = 0; + + + VConnect* vconnect = new VConnect(); + viewman->add(vconnect); + vconnect->run(); } else { - viewWait->setScreenPos(160, 150); - } - viewWait->setMainText("\n Locating server"); - viewWait->draw(); - viewWait->show(); - viewman->add(viewWait); + ViewMan* viewman = ViewMan::getInstance(); + viewman->removeAll(); + viewman->redrawAll(); - VDR* vdr = VDR::getInstance(); - vdr->findServers(serverIPs); - if (!irun) return; - viewman->removeView(viewWait); + VDR::getInstance()->configSave("General", "Last Power State", "Off"); + VDR::getInstance()->disconnect(); + Video::getInstance()->signalOff(); + Led::getInstance()->off(); + isStandby = 1; + } } -int Command::connectToServer(int vectorIndex) +void Command::doReboot() { - char a[60]; - struct timespec ts; + VDR::getInstance()->disconnect(); + // just kill it... + logger->log("Command", Log::NOTICE, "Reboot"); + reboot(LINUX_REBOOT_CMD_RESTART); +} +void Command::doJustConnected(VConnect* vconnect) +{ VDR* vdr = VDR::getInstance(); - vdr->setServerIP(serverIPs[vectorIndex]); + ViewMan* viewman = ViewMan::getInstance(); + viewman->removeView(vconnect, 0, 1); - logger->log("Command", Log::NOTICE, "Connecting to server at %s", serverIPs[vectorIndex]); - - VInfo* viewWait = new VInfo(); - viewWait->setDimensions(200, 400); - if (Video::getInstance()->getFormat() == Video::PAL) - { - viewWait->setScreenPos(170, 200); - } - else + // Power off if first boot and config says so + if (firstBoot) { - viewWait->setScreenPos(160, 150); - } - viewWait->setMainText("\n Connecting to VDR"); - viewWait->draw(); - viewWait->show(); - viewman->add(viewWait); + firstBoot = 0; - int success = vdr->connect(); - - if (success) - { - logger->log("Command", Log::DEBUG, "Connected ok, doing login"); - success = vdr->doLogin(); + char* powerAfterBoot = vdr->configLoad("General", "Power After Boot"); - if (success) + if (powerAfterBoot) { - strcpy(a, "\n Connected"); - ts.tv_sec = 0; - ts.tv_nsec = 500000000; + if (!strcasecmp(powerAfterBoot, "On")) + { + logger->log("Command", Log::INFO, "Config says Power After Boot = On"); + } + else if (!strcasecmp(powerAfterBoot, "Off")) + { + logger->log("Command", Log::INFO, "Config says Power After Boot = Off"); + doStandby(); + return; // quit here + } + else if (!strcasecmp(powerAfterBoot, "Last state")) + { + char* lastPowerState = vdr->configLoad("General", "Last Power State"); + if (lastPowerState) + { + if (!strcasecmp(lastPowerState, "On")) + { + logger->log("Command", Log::INFO, "Config says Last Power State = On"); + } + else if (!strcasecmp(lastPowerState, "Off")) + { + logger->log("Command", Log::INFO, "Config says Last Power State = Off"); + doStandby(); + return; // quit here + } + else + { + logger->log("Command", Log::INFO, "Config General/Last Power State not understood"); + } + } + else + { + logger->log("Command", Log::INFO, "Config General/Last Power State not found"); + } + } + else + { + logger->log("Command", Log::INFO, "Config/Power After Boot not understood"); + } } else { - strcpy(a, "\n Login failed"); - ts.tv_sec = 3; - ts.tv_nsec = 0; + logger->log("Command", Log::INFO, "Config General/Power After Boot not found"); } } - else - { - strcpy(a, "\n Connection failed"); - ts.tv_sec = 3; - ts.tv_nsec = 0; - } - - viewWait->setMainText(a); - viewWait->draw(); - viewWait->show(); - if (irun) nanosleep(&ts, NULL); // only do the wait if we aren't shutting down + // Save power state = on -/* - vdr->configSave("Section Name This Is blah blah blah 495834509725049375032end", "thekey with this space ", "1234value"); - sleep(10); + vdr->configSave("General", "Last Power State", "On"); - char* conf = vdr->configLoad("fred", "bill"); - if (conf) - { - //printf("And the config value returned is %s\n", conf); - delete[] conf; - } - else - { - //printf("Conf value return is NULL :(\n"); - } -*/ - viewman->removeView(viewWait); + // Go S-Video if config says so - return success; -} + char* svideo = vdr->configLoad("TV", "S-Video"); -void Command::doStandby() -{ - if (state == 5) + if (svideo) { - Video::getInstance()->signalOn(); - Led::getInstance()->on(); - state = 0; + if (!strcasecmp(svideo, "Yes")) + { + logger->log("Command", Log::INFO, "Switching to S-Video as S-Video=%s", svideo); + Video::getInstance()->setConnection(Video::SVIDEO); + } + else + { + logger->log("Command", Log::INFO, "Leaving video output as S-Video=%s", svideo); + Video::getInstance()->setConnection(Video::COMPOSITERGB); + } } else { - ViewMan* viewman = ViewMan::getInstance(); - - viewman->removeAll(); - viewman->redrawAll(); - - - VDR::getInstance()->disconnect(); - Video::getInstance()->signalOff(); - Led::getInstance()->off(); - state = 5; + logger->log("Command", Log::INFO, "Config TV/S-Video not found"); } -} -void Command::doReboot() -{ - VDR::getInstance()->disconnect(); - // just kill it... - logger->log("Command", Log::NOTICE, "Reboot"); - reboot(LINUX_REBOOT_CMD_RESTART); + // s video done + + VWelcome* vw = new VWelcome(); + viewman->add(vw); + viewman->redrawAll(); } diff --git a/command.h b/command.h index 8e907f6..29155d8 100644 --- a/command.h +++ b/command.h @@ -26,7 +26,6 @@ #include #include -#include #include @@ -45,12 +44,15 @@ #include "vinfo.h" #include "vwallpaper.h" #include "vvolume.h" +#include "vconnect.h" #include "vserverselect.h" #include "vwelcome.h" #include "vmute.h" #include "colour.h" #include "osd.h" +class VConnect; + class Command : public MessageQueue { public: @@ -67,18 +69,15 @@ class Command : public MessageQueue private: void handleCommand(int); - void broadcastForServers(); - int connectToServer(int vectorIndex); void doStandby(); - void clearServerIPs(); + void doJustConnected(VConnect* vconnect); static Command* instance; pid_t mainPid; UCHAR initted; UCHAR irun; - UCHAR state; - - std::vector serverIPs; + UCHAR isStandby; + UCHAR firstBoot; Log* logger; ViewMan* viewman; diff --git a/message.h b/message.h index 523bf76..1ce6c72 100644 --- a/message.h +++ b/message.h @@ -47,6 +47,8 @@ class Message const static ULONG RESUME_SELECTED_RECORDING = 8; const static ULONG STANDBY = 9; const static ULONG STOP_PLAYBACK = 10; + const static ULONG SERVER_SELECTED = 11; + const static ULONG VDR_CONNECTED = 12; }; #endif diff --git a/remote.cc b/remote.cc index 080bab8..c589ab1 100644 --- a/remote.cc +++ b/remote.cc @@ -77,6 +77,7 @@ UCHAR Remote::getButtonPress(int waitType) /* how = 0 - block how = 1 - start new wait how = 2 - continue wait + how = 3 - no wait */ unsigned long input; @@ -103,6 +104,12 @@ UCHAR Remote::getButtonPress(int waitType) } passToSelect = &tv; } + else if (waitType == 3) + { + tv.tv_sec = 0; + tv.tv_usec = 0; + passToSelect = &tv; + } FD_ZERO(&readfds); FD_SET(device, &readfds); diff --git a/vconnect.cc b/vconnect.cc new file mode 100644 index 0000000..79abef7 --- /dev/null +++ b/vconnect.cc @@ -0,0 +1,158 @@ +/* + Copyright 2004-2005 Chris Tallon + + This file is part of VOMP. + + VOMP is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + VOMP is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with VOMP; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "vconnect.h" + +VConnect::VConnect() +{ + vdr = VDR::getInstance(); + logger = Log::getInstance(); + + setDimensions(200, 400); + if (Video::getInstance()->getFormat() == Video::PAL) + { + setScreenPos(170, 200); + } + else + { + setScreenPos(160, 150); + } + + exitable = 0; + irun = 0; +} + +VConnect::~VConnect() +{ + irun = 0; + vdr->cancelFindingServer(); + threadStop(); +} + +void VConnect::draw() +{ + VInfo::draw(); +} + +int VConnect::handleCommand(int command) +{ + return 1; +} + +void VConnect::run() +{ + threadStart(); +} + +void VConnect::threadMethod() +{ + struct timespec ts; + int success; + irun = 1; + + ViewMan* viewman = ViewMan::getInstance(); + + do + { + setMainText("\n Locating server"); + draw(); + show(); + + vdr->findServers(serverIPs); + if (!irun) return; + + if (serverIPs.size() == 1) + { + selectedServer = 0; + } + else + { + selectedServer = -1; + VServerSelect* vs = new VServerSelect(&serverIPs); + vs->setParent(this); + vs->draw(); + vs->show(); + viewman->add(vs); + threadWaitForSignal(); + } + + printf("server selected %i\n", selectedServer); + + vdr->setServerIP(serverIPs[selectedServer]); + + // Clear the serverIPs vector + for(UINT k = 0; k < serverIPs.size(); k++) + { + delete[] serverIPs[k]; + } + serverIPs.clear(); + + logger->log("Command", Log::NOTICE, "Connecting to server at %s", serverIPs[selectedServer]); + setMainText("\n Connecting to VDR"); + draw(); + show(); + + success = vdr->connect(); + if (success) + { + logger->log("Command", Log::DEBUG, "Connected ok, doing login"); + success = vdr->doLogin(); + + if (success) + { + setMainText("\n Connected"); + ts.tv_sec = 0; + ts.tv_nsec = 500000000; + } + else + { + vdr->disconnect(); + setMainText("\n Login failed"); + ts.tv_sec = 3; + ts.tv_nsec = 0; + } + } + else + { + setMainText("\n Connection failed"); + ts.tv_sec = 3; + ts.tv_nsec = 0; + } + + draw(); + show(); + nanosleep(&ts, NULL); + + } while(!success); + + Message* m = new Message(); + m->from = this; + m->message = Message::VDR_CONNECTED; + Command::getInstance()->postMessage(m); +} + +void VConnect::processMessage(Message* m) +{ + if (m->message == Message::SERVER_SELECTED) + { + selectedServer = m->parameter; + threadSignal(); + } +} diff --git a/vconnect.h b/vconnect.h new file mode 100644 index 0000000..545f5a9 --- /dev/null +++ b/vconnect.h @@ -0,0 +1,60 @@ +/* + Copyright 2004-2005 Chris Tallon + + This file is part of VOMP. + + VOMP is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + VOMP is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with VOMP; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef VCONNECT_H +#define VCONNECT_H + +#include +#include +#include + +#include "view.h" +#include "viewman.h" +#include "vdr.h" +#include "command.h" +#include "message.h" +#include "colour.h" +#include "video.h" +#include "thread.h" + +class VConnect : public VInfo, public Thread +{ + public: + VConnect(); + ~VConnect(); + + int handleCommand(int command); + void processMessage(Message* m); + void draw(); + + void run(); + + private: + void threadMethod(); + void clearServerIPs(); + + UCHAR irun; + VDR* vdr; + Log* logger; + std::vector serverIPs; + int selectedServer; +}; + +#endif diff --git a/vdr.cc b/vdr.cc index ecb2e49..093fcc9 100644 --- a/vdr.cc +++ b/vdr.cc @@ -74,7 +74,7 @@ void VDR::findServers(std::vector& serverIPs) { if (waitType == 1) { - logger->log("Core", Log::NOTICE, "Broadcasting for server"); + logger->log("VDR", Log::NOTICE, "Broadcasting for server"); ds.send("255.255.255.255", 3024, message, strlen(message)); } retval = ds.waitforMessage(waitType); @@ -123,6 +123,7 @@ void VDR::disconnect() { if (tcp) delete tcp; tcp = NULL; + Log::getInstance()->log("VDR", Log::DEBUG, "Disconnect"); } long VDR::getSimpleReply() diff --git a/view.cc b/view.cc index 3a57030..2030c5f 100644 --- a/view.cc +++ b/view.cc @@ -105,3 +105,8 @@ void View::setBorderOn(UCHAR on) { borderOn = on; } + +void View::setParent(View* tParent) +{ + parent = tParent; +} diff --git a/view.h b/view.h index a8f40c6..bfe3831 100644 --- a/view.h +++ b/view.h @@ -43,6 +43,7 @@ class View : public Box void setTitleText(char* title); void setBackgroundColour(Colour& colour); void setTitleBarColour(Colour& colour); + void setParent(View* parent); // For use by ViewMan long delSec; @@ -64,6 +65,7 @@ class View : public Box protected: Colour titleBarColour; + View* parent; }; #endif diff --git a/vinfo.h b/vinfo.h index 6fa1382..7c156e2 100644 --- a/vinfo.h +++ b/vinfo.h @@ -33,15 +33,15 @@ class VInfo : public View { public: VInfo(); - ~VInfo(); + virtual ~VInfo(); void setMainText(char* title); void setExitable(); - int handleCommand(int command); + virtual int handleCommand(int command); void draw(); - private: + protected: char* mainText; UCHAR exitable; }; diff --git a/vquestion.cc b/vquestion.cc index d4f5a83..d15a562 100644 --- a/vquestion.cc +++ b/vquestion.cc @@ -97,7 +97,7 @@ int VQuestion::handleCommand(int command) Message* m = new Message(); m->from = this; - m->to = questionReceiver; + m->to = parent; m->message = Message::QUESTION_YES; ViewMan::getInstance()->postMessage(m); @@ -107,11 +107,6 @@ int VQuestion::handleCommand(int command) return 1; } -void VQuestion::setParent(View* tquestionReceiver) -{ - questionReceiver = tquestionReceiver; -} - void VQuestion::setDefault(UCHAR option) { selectedOption = option; diff --git a/vquestion.h b/vquestion.h index e887491..67f7d01 100644 --- a/vquestion.h +++ b/vquestion.h @@ -35,7 +35,6 @@ class VQuestion : public View public: VQuestion(); ~VQuestion(); - void setParent(View* tquestionReceiver); void setDefault(UCHAR option); void setMainText(char* title); @@ -50,7 +49,6 @@ class VQuestion : public View void swap(); - View* questionReceiver; UCHAR selectedOption; WButton buttonYes; diff --git a/vserverselect.cc b/vserverselect.cc index 3d6ee3e..d0ae51f 100644 --- a/vserverselect.cc +++ b/vserverselect.cc @@ -20,13 +20,12 @@ #include "vserverselect.h" -VServerSelect::VServerSelect(std::vector* serverIPs, int* tselectServer) +VServerSelect::VServerSelect(std::vector* serverIPs) { // I tried the whole passing using a reference here, but // the program segfaulted when settitletext tried to new // a char array. so now we have the messy dereferencing... // anyway, now it doesn't use a object wide reference. - selectServer = tselectServer; if (Video::getInstance()->getFormat() == Video::PAL) { @@ -80,7 +79,11 @@ int VServerSelect::handleCommand(int command) } else if (command == Remote::OK) { - *selectServer = sl.getCurrentOption(); + Message* m = new Message(); + m->to = parent; + m->message = Message::SERVER_SELECTED; + m->parameter = sl.getCurrentOption(); + ViewMan::getInstance()->postMessage(m); return 4; } diff --git a/vserverselect.h b/vserverselect.h index 81ec597..463e104 100644 --- a/vserverselect.h +++ b/vserverselect.h @@ -31,11 +31,12 @@ #include "wselectlist.h" #include "colour.h" #include "video.h" +#include "viewman.h" class VServerSelect : public View { public: - VServerSelect(std::vector* tserverIPs, int* tselectServer); + VServerSelect(std::vector* tserverIPs); ~VServerSelect(); int handleCommand(int command); @@ -43,7 +44,6 @@ class VServerSelect : public View private: WSelectList sl; - int* selectServer; }; #endif -- 2.39.5