]> git.vomp.tv Git - vompclient.git/blob - command.cc
Timeouts, keepalives...
[vompclient.git] / command.cc
1 /*
2     Copyright 2004-2005 Chris Tallon
3
4     This file is part of VOMP.
5
6     VOMP is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     VOMP is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with VOMP; if not, write to the Free Software
18     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19 */
20
21 #ifndef WIN32
22 #include <linux/errno.h>
23 #endif
24
25 #include "command.h"
26
27 #ifdef WIN32
28 #include "remotewin.h"
29 #endif
30
31 #include "led.h"
32 #include "video.h"
33 #include "audio.h"
34 #include "vdr.h"
35 #include "vvolume.h"
36 #include "vserverselect.h"
37 #include "vwelcome.h"
38 #include "vmute.h"
39 #include "colour.h"
40 #include "osd.h"
41 #include "i18n.h"
42 #include "timerreceiver.h"
43 #include "timers.h"
44 #include "wol.h"
45 #include "vvideolive.h"
46 #include "vconnect.h"
47 #include "message.h"
48 #include "remote.h"
49 #include "vinfo.h"
50 #include "boxx.h"
51 #include "boxstack.h"
52 #include "log.h"
53
54
55 Command* Command::instance = NULL;
56
57 Command::Command()
58 {
59   if (instance) return;
60   instance = this;
61   initted = 0;
62   isStandby = 0;
63   firstBoot = 1;
64   connLost = NULL;
65   crashed = false;
66   server = NULL;
67 }
68
69 Command::~Command()
70 {
71   instance = NULL;
72 }
73
74 Command* Command::getInstance()
75 {
76   return instance;
77 }
78
79 int Command::init(bool tcrashed, char* tServer)
80 {
81   if (initted) return 0;
82   initted = 1;
83   crashed = tcrashed;
84   server = tServer;
85
86   logger = Log::getInstance();
87   boxstack = BoxStack::getInstance();
88   remote = Remote::getInstance();
89   
90   remote->InitHWCListwithDefaults();
91   
92   if (!logger || !boxstack || !remote)
93   {
94     initted = 0;
95     return 0;
96   }
97 #ifndef WIN32
98   pthread_mutex_init(&masterLock, NULL);
99 #else
100   masterLock=CreateMutex(NULL,FALSE,NULL);
101 #endif
102
103   return 1;
104 }
105
106 int Command::shutdown()
107 {
108   if (!initted) return 0;
109   initted = 0;
110   return 1;
111 }
112
113 void Command::stop()
114 {
115 //  VDR::getInstance()->cancelFindingServer();
116   udp.shutdown();
117   irun = 0;
118 }
119
120 void Command::doWallpaper()
121 {
122   Video* video = Video::getInstance();
123
124   // Blue background
125   Boxx* bbg = new Boxx();
126   bbg->setSize(video->getScreenWidth(), video->getScreenHeight());
127   bbg->createBuffer();
128   bbg->fillColour(Colour::VIDEOBLUE);
129   boxstack->add(bbg);
130   boxstack->update(bbg);
131   boxstack->remove(bbg);
132
133   // Wallpaper
134   WJpeg* wallpaperj = new WJpeg();
135   wallpaperj->setSize(video->getScreenWidth(), video->getScreenHeight());
136   wallpaperj->createBuffer();
137
138   if (video->getFormat() == Video::PAL)
139   {
140     logger->log("Command", Log::DEBUG, "PAL wallpaper selected");
141     wallpaperj->init("/wallpaperPAL.jpg");
142   }
143   else
144   {
145     logger->log("Command", Log::DEBUG, "NTSC wallpaper selected");
146     wallpaperj->init("/wallpaperNTSC.jpg");
147   }
148   wallpaperj->draw();
149
150   boxstack->add(wallpaperj);
151   boxstack->update(wallpaperj);
152
153   wallpaper = wallpaperj;
154 }
155
156 void Command::run()
157 {
158   if (!initted) return;
159   irun = 1;
160 #ifndef WIN32
161   mainPid = getpid();
162 #endif
163
164   // just in case
165   Video::getInstance()->signalOn();
166   Led::getInstance()->on();
167
168   doWallpaper();
169
170   // End of startup. Lock the mutex and put the first view up
171 //  logger->log("Command", Log::DEBUG, "WANT LOCK");
172 #ifndef WIN32
173   pthread_mutex_lock(&masterLock);
174 #else
175   WaitForSingleObject(masterLock, INFINITE );
176 #endif
177   //logger->log("Command", Log::DEBUG, "LOCKED");
178
179   if (crashed)
180   {
181     buildCrashedBox();
182   }
183   else
184   {
185     VConnect* vconnect = new VConnect(server);
186     boxstack->add(vconnect);
187     vconnect->run();
188   }
189
190   // Start method 2 of getting commands in...
191   udp.run(this);
192
193   UCHAR button = 0;
194   while(irun)
195   {
196     // unlock and wait
197     //logger->log("Command", Log::DEBUG, "UNLOCK");
198 #ifndef WIN32
199     pthread_mutex_unlock(&masterLock);
200 #else
201     ReleaseMutex(masterLock);
202 #endif
203     button = remote->getButtonPress(2);  // FIXME why is this set to 2 and not 0? so it can quit
204     // something happened, lock and process
205
206     //  logger->log("Command", Log::DEBUG, "WANT LOCK");
207 #ifndef WIN32
208     pthread_mutex_lock(&masterLock);
209 #else
210     WaitForSingleObject(masterLock, INFINITE );
211 #endif
212     // logger->log("Command", Log::DEBUG, "LOCK");
213
214     if ((button == Remote::NA_NONE) /*|| (button == Remote::NA_UNKNOWN)*/) continue;
215
216     if (button != Remote::NA_SIGNAL) handleCommand(button);
217     processMessageQueue();
218   }
219
220   //logger->log("Command", Log::DEBUG, "UNLOCK");
221 #ifndef WIN32
222   pthread_mutex_unlock(&masterLock);
223 #else
224   ReleaseMutex(masterLock);
225 #endif
226 }
227
228 void Command::postMessage(Message* m)
229 {
230   // This is locked here in case the main loop is not waiting for an event, but is processing one
231   // it could be killed but then not react to it because the signal wouldn't cause
232   // remote->getButtonPress to break
233   // locking the mutex ensures that the master thread is waiting on getButtonPress
234
235
236   //logger->log("Command", Log::DEBUG, "WANT LOCK");
237 #ifndef WIN32
238   pthread_mutex_lock(&masterLock);
239 #else
240   WaitForSingleObject(masterLock, INFINITE );
241 #endif
242   //logger->log("Command", Log::DEBUG, "LOCK");
243   MessageQueue::postMessage(m);
244
245 #ifndef WIN32
246   kill(mainPid, SIGURG);
247   pthread_mutex_unlock(&masterLock);
248 #else
249   ((RemoteWin*)Remote::getInstance())->Signal();
250   ReleaseMutex(masterLock);
251 #endif
252   //logger->log("Command", Log::DEBUG, "UNLOCK");
253 }
254
255 void Command::postMessageNoLock(Message* m)
256 {
257   // As above but use this one if this message is being posted because of a button press
258   // the mutex is already locked, locking around postMessage is not needed as the
259   // queue is guaranteed to be run when the button has been processed
260   MessageQueue::postMessage(m);
261 }
262
263 bool Command::postMessageIfNotBusy(Message* m)
264 {
265   // Used for Windows mouse events
266
267   //logger->log("Command", Log::DEBUG, "TRY LOCK");
268 #ifndef WIN32
269   if (pthread_mutex_trylock(&masterLock) != EBUSY)
270   {
271     //logger->log("Command", Log::DEBUG, "LOCK");
272     MessageQueue::postMessage(m);
273     kill(mainPid, SIGURG);
274     pthread_mutex_unlock(&masterLock);
275     //logger->log("Command", Log::DEBUG, "UNLOCK");
276     return true;
277   }
278   else
279   {
280     return false;
281   }
282 #else
283   switch (WaitForSingleObject(masterLock, 0 ))
284   { //FIXME this is not "if not busy" check
285     case WAIT_OBJECT_0: //but with proper argument 0 this did not work
286     // case WAIT_ABANDONED:
287     MessageQueue::postMessage(m);
288     ((RemoteWin*)Remote::getInstance())->Signal();
289     ReleaseMutex(masterLock);
290     return true;
291
292     case WAIT_ABANDONED: return false;
293     case WAIT_TIMEOUT: return false;
294   }
295     return false;
296 #endif
297 }
298
299 void Command::postMessageFromOuterSpace(Message* m)
300 {
301   /*
302   Yet another way of getting messages into Command. This one is for events that
303   are not standard button presses (or UDP generated buttons). It is also not for
304   events that are generated as a result of other events (events that can safely
305   call postMessageNoLock and be guaranteed that the message will be processed
306   because it is known that the queue is currently being processed).
307   This is for events that come from outer space and can occur when the master
308   mutex is locked or not, they need to be queued and executed but it doesn't
309   matter when.
310   Actually so far it is for events caused by the video stream - aspect ratio
311   changes. These can occur when the master mutex is locked and so postMessage
312   doesn't work. postMessageNoLock doesn't work because if the mutex *isn't*
313   locked at the time then the message could be sat around a while before
314   being noticed.
315   The whole message system was at first supposed to prevent the problem of
316   calling a function on an object that had just been deleted, by ordering
317   messages such that all calls are done before object deletion. However,
318   because of the new centralised messaging system and the fact that BoxStack
319   locates the destination object before calling it, the messaging system now
320   allows the kind of sloppy calls it was supposed to stop. Weird huh. This
321   is mentioned here because the video stream might generate an event just as
322   the user hits stop. The mutex is locked, and by the time the message
323   is examined the vvideorec/live has been deleted. This doesn't matter because
324   boxstack will drop the message if it can't find the matching object to
325   deliver it to.
326   Finally, all this is fine and dandy, except that I'm not 100% sure that
327   this sloppy postMessage and hope a queued signal will force it to be processed
328   thingy will actually work. Hmmm.
329   Lastly <g>, I will consider making the naming system a little more sane
330   if this works.
331   */
332
333   logger->log("Command", Log::DEBUG, "PMFOS called");
334   MessageQueue::postMessage(m);
335
336 #ifndef WIN32
337   kill(mainPid, SIGURG);
338 #else
339   ((RemoteWin*)Remote::getInstance())->Signal();
340 #endif
341 }
342
343 void Command::processMessage(Message* m)
344 {
345     // FIXME - a slight modification - how if messagereceivers were to register
346     // themselves as receivers to avoid the calling-a-deleted-object problem
347     // then only deliver/register/unregister would have to be protected
348
349   logger->log("Command", Log::DEBUG, "processing message %i", m->message);
350
351
352   if (m->to == this)
353   {
354     switch(m->message)
355     {
356       case Message::STANDBY:
357       {
358         doStandby();
359         break;
360       }
361
362
363       // << FIXME OBSELETE
364       case Message::STOP_PLAYBACK:
365       {
366         handleCommand(Remote::STOP); // an odd way of doing it, but so simple
367         break;
368       }
369       case Message::STREAM_END:
370       {
371         VVideoLive::getInstance()->streamEnd();
372         break;
373       }
374       // Also connection_lost comes from player - anywhere else?
375       // FIXME OBSELETE >>
376
377
378       case Message::VDR_CONNECTED:
379       {
380         doJustConnected((VConnect*)m->from);
381         break;
382       }
383       case Message::SCREENSHOT:
384       {
385         Osd::getInstance()->screenShot("/out.jpg");
386         break;
387       }
388       case Message::CONNECTION_LOST:
389       {
390         doFromTheTop(true);
391         break;
392       }
393       case Message::UDP_BUTTON:
394       {
395         handleCommand(m->parameter);
396         break;
397       }
398       case Message::CHANGE_LANGUAGE:
399       {
400         boxstack->removeAll();
401         boxstack->update(wallpaper);
402         I18n::initialize();
403         if (!VDR::getInstance()->isConnected()) { connectionLost(); break; }
404         VWelcome* vw = new VWelcome();
405         vw->draw();
406         boxstack->add(vw);
407         boxstack->update(vw);
408         break;
409       }
410       case Message::LAST_VIEW_CLOSE:
411       {
412         // Shouldn't be done like this. Some generic message pass back from vinfo perhaps
413         if (crashed)
414         {
415           crashed = false;
416           doFromTheTop(false);        
417         }
418       
419 //        VWelcome* vw = new VWelcome();
420 //        vw->draw();
421 //        boxstack->add(vw);
422 //        boxstack->update(vw);
423
424         break;
425       }
426     }
427   }
428   else
429   {
430     /* FIXME
431     
432     Instead of sending through the boxstack, implement a more generic MessageReceiver interface
433     and have potential receivers register with something
434     When a message needs to be delivered, check if the receiver is still registered, if so, deliver the message
435     This could all be done using the existing big command mutex to keep it simple
436     */
437   
438     logger->log("Command", Log::DEBUG, "Sending message to boxstack");
439     boxstack->processMessage(m);
440   }
441 }
442
443 void Command::handleCommand(int button)
444 {
445   if (isStandby && (button != Remote::POWER)) return;
446   if (!connLost && boxstack->handleCommand(button)) return; // don't send to boxstack if connLost
447
448   // command was not handled
449
450   switch(button)
451   {
452     case Remote::DF_LEFT:
453     case Remote::DF_RIGHT:
454     case Remote::VOLUMEUP:
455     case Remote::VOLUMEDOWN:
456     {
457       VVolume* v = new VVolume();
458       boxstack->add(v);
459       v->handleCommand(button); // this will draw+show
460       return;
461     }
462     case Remote::MUTE:
463     {
464       VMute* v = new VMute();
465       v->draw();
466       boxstack->add(v);
467       boxstack->update(v);
468       return;
469     }
470     case Remote::POWER:
471     {
472       doStandby();
473       return;
474     }
475     case Remote::OK:
476     {
477       // FIXME
478       if (!connLost) return; // if connLost, handle Remote::OK
479       doFromTheTop(false);
480       return;
481     }
482   }
483 }
484
485 void Command::sig1()
486 {
487 #ifdef DEV
488   Message* m = new Message(); // break into master mutex
489   m->message = Message::SCREENSHOT;
490   m->to = this;
491   postMessage(m);
492 #endif
493 }
494
495 void Command::doStandby()
496 {
497   if (isStandby)
498   {
499     Video::getInstance()->signalOn();
500     Led::getInstance()->on();
501     isStandby = 0;
502
503
504     VConnect* vconnect = new VConnect(server);
505     boxstack->add(vconnect);
506     vconnect->run();
507   }
508   else
509   {
510     boxstack->removeAll();
511     Video::getInstance()->signalOff();
512     boxstack->update(wallpaper);
513
514     VDR::getInstance()->configSave("General", "Last Power State", "Off");
515     VDR::getInstance()->disconnect();
516     Led::getInstance()->off();
517     isStandby = 1;
518 #ifdef WIN32
519     stop(); //different behavoiur on windows, we exit
520 #endif
521   }
522 }
523
524 void Command::doFromTheTop(bool which)
525 {
526   if (which)
527   {
528     logger->log("Command", Log::NOTICE, "Doing connection lost dialog");
529     connLost = new VInfo();
530     connLost->setSize(360, 200);
531     connLost->createBuffer();
532     if (Video::getInstance()->getFormat() == Video::PAL)
533       connLost->setPosition(190, 170);
534     else
535       connLost->setPosition(180, 120);
536     connLost->setOneLiner(tr("Connection lost"));
537     connLost->setDropThrough();
538     connLost->setBorderOn(1);
539     connLost->setTitleBarColour(Colour::DANGER);
540     connLost->okButton();
541     connLost->draw();
542     boxstack->add(connLost);
543     boxstack->update(connLost);
544     remote->clearBuffer();
545   }
546   else
547   {
548     VDR::getInstance()->disconnect();
549     boxstack->removeAll();
550     boxstack->update(wallpaper);
551     connLost = NULL;
552     VConnect* vconnect = new VConnect(server);
553     boxstack->add(vconnect);
554     vconnect->run();
555   }
556 }
557
558 void Command::doReboot()
559 {
560   VDR::getInstance()->disconnect();
561   // just kill it...
562   logger->log("Command", Log::NOTICE, "Reboot");
563 #ifndef WIN32
564   reboot(LINUX_REBOOT_CMD_RESTART);
565 #endif //Would we support this on windows?
566 }
567
568 void Command::connectionLost()
569 {
570   Message* m = new Message(); // break into master mutex
571   m->message = Message::CONNECTION_LOST;
572   m->to = this;
573   postMessageFromOuterSpace(m);
574 }
575
576 void Command::buildCrashedBox()
577 {
578   VInfo* crash = new VInfo();
579   crash->setSize(360, 250);
580   crash->createBuffer();
581   if (Video::getInstance()->getFormat() == Video::PAL)
582     crash->setPosition(190, 146);
583   else
584     crash->setPosition(180, 96);
585   crash->setMainText("Oops, vomp crashed.. :(\nPlease report this crash to the author, with as much detail as possible about what you were doing at the time that might have caused the crash.");
586   crash->setBorderOn(1);
587   crash->setTitleBarColour(Colour::DANGER);
588   crash->okButton();
589   crash->setExitable();
590   crash->draw();
591   boxstack->add(crash);
592   boxstack->update(crash);
593 }
594
595 void Command::doJustConnected(VConnect* vconnect)
596 {
597   I18n::initialize();
598   if (!VDR::getInstance()->isConnected()) { connectionLost(); return; }
599   
600   Video* video = Video::getInstance();
601   Audio* audio = Audio::getInstance();  
602   boxstack->remove(vconnect);
603
604   VInfo* vi = new VInfo();
605   vi->setSize(400, 200);
606   vi->createBuffer();
607   if (video->getFormat() == Video::PAL)
608     vi->setPosition(170, 200);
609   else
610     vi->setPosition(160, 150);
611   vi->setOneLiner(tr("Connected, loading config"));
612   vi->draw();
613   boxstack->add(vi);
614   boxstack->update(vi);
615
616   VDR* vdr = VDR::getInstance();
617   char* config;
618
619   // See if config says to override video format (PAL/NTSC)
620   config = vdr->configLoad("General", "Override Video Format");
621   if (config)
622   {
623     logger->log("Command", Log::DEBUG, "Override Video Format is present");
624
625     if (   (!strcmp(config, "PAL") && (video->getFormat() == Video::NTSC))
626         || (!strcmp(config, "NTSC") && (video->getFormat() == Video::PAL))  )
627     {
628       // Oh sheesh, need to switch format. Bye bye TV...
629
630       // Take everything down
631       boxstack->removeAll();
632       boxstack->remove(wallpaper);
633       Osd* osd = Osd::getInstance();
634       osd->shutdown();
635       video->shutdown();
636
637       // Get video and osd back up with the new mode
638       if (!strcmp(config, "PAL"))
639       {
640         logger->log("Command", Log::DEBUG, "Switching to PAL");
641         video->init(Video::PAL);
642       }
643       else if (!strcmp(config, "NTSC"))
644       {
645         logger->log("Command", Log::DEBUG, "Switching to NTSC");
646         video->init(Video::NTSC);
647       }
648       osd->init((char*)("/dev/stbgfx"));
649
650       // Put the wallpaper back
651       doWallpaper();
652
653       // Re add the vinfo
654       vi = new VInfo();
655       vi->setSize(400, 200);
656       vi->createBuffer();
657       if (video->getFormat() == Video::PAL)
658         vi->setPosition(170, 200);
659       else
660         vi->setPosition(160, 150);
661
662       vi->setOneLiner(tr("Connected, loading config"));
663       vi->draw();
664       boxstack->add(vi);
665       boxstack->update(vi);
666     }
667     else
668     {
669       logger->log("Command", Log::DEBUG, "Already in requested mode, or request was not 'PAL' or 'NTSC'");
670     }
671   }
672   else
673   {
674     logger->log("Command", Log::DEBUG, "Phew, no dangerous on-the-fly mode switching to do!");
675   }
676
677   // Power off if first boot and config says so
678   if (firstBoot)
679   {
680     firstBoot = 0;
681
682     logger->log("Command", Log::DEBUG, "Load power after boot");
683
684     config = vdr->configLoad("General", "Power After Boot");
685
686     if (config)
687     {
688       if (!STRCASECMP(config, "On"))
689       {
690         logger->log("Command", Log::INFO, "Config says Power After Boot = On");
691       }
692       else if (!STRCASECMP(config, "Off"))
693       {
694         logger->log("Command", Log::INFO, "Config says Power After Boot = Off");
695         doStandby();
696         delete[] config;
697         return; // quit here
698       }
699       else if (!STRCASECMP(config, "Last state"))
700       {
701         char* lastPowerState = vdr->configLoad("General", "Last Power State");
702         if (lastPowerState)
703         {
704           if (!STRCASECMP(lastPowerState, "On"))
705           {
706             logger->log("Command", Log::INFO, "Config says Last Power State = On");
707           }
708           else if (!STRCASECMP(lastPowerState, "Off"))
709           {
710             logger->log("Command", Log::INFO, "Config says Last Power State = Off");
711             doStandby();
712             delete[] config;
713             return; // quit here
714           }
715           else
716           {
717             logger->log("Command", Log::INFO, "Config General/Last Power State not understood");
718           }
719         }
720         else
721         {
722           logger->log("Command", Log::INFO, "Config General/Last Power State not found");
723         }
724       }
725       else
726       {
727         logger->log("Command", Log::INFO, "Config/Power After Boot not understood");
728       }
729       delete[] config;
730     }
731     else
732     {
733       logger->log("Command", Log::INFO, "Config General/Power After Boot not found");
734     }
735   }
736
737
738   // Go S-Video if config says so
739
740   config = vdr->configLoad("TV", "Connection");
741
742   if (config)
743   {
744     if (!STRCASECMP(config, "S-Video"))
745     {
746       logger->log("Command", Log::INFO, "Switching to S-Video as Connection=%s", config);
747       video->setConnection(Video::SVIDEO);
748     }
749     else
750     {
751       logger->log("Command", Log::INFO, "Switching to RGB/Composite as Connection=%s", config);
752       video->setConnection(Video::COMPOSITERGB);
753     }
754     delete[] config;
755   }
756   else
757   {
758     logger->log("Command", Log::INFO, "Config TV/S-Video not found");
759   }
760
761   // Set remote type
762
763   config = vdr->configLoad("General", "Remote type");
764
765   if (config)
766   {
767     if (!STRCASECMP(config, "New"))
768     {
769       logger->log("Command", Log::INFO, "Switching to New remote type");
770       remote->setRemoteType(Remote::NEWREMOTE);
771     }
772     else
773     {
774       logger->log("Command", Log::INFO, "Switching to Old remote type");
775       remote->setRemoteType(Remote::OLDREMOTE);
776     }
777     delete[] config;
778   }
779   else
780   {
781     logger->log("Command", Log::INFO, "Config General/Remote type not found");
782     remote->setRemoteType(Remote::OLDREMOTE);
783   }
784
785
786
787
788   // Get TV aspect ratio
789
790   config = vdr->configLoad("TV", "Aspect");
791   if (config)
792   {
793     if (!STRCASECMP(config, "16:9"))
794     {
795       logger->log("Command", Log::INFO, "/// Switching to TV aspect 16:9");
796       video->setTVsize(Video::ASPECT16X9);
797     }
798     else
799     {
800       logger->log("Command", Log::INFO, "/// Switching to TV aspect 4:3");
801       video->setTVsize(Video::ASPECT4X3);
802     }
803     delete[] config;
804   }
805   else
806   {
807     logger->log("Command", Log::INFO, "Config TV/Aspect type not found, going 4:3");
808     video->setTVsize(Video::ASPECT4X3);
809   }
810
811   config = vdr->configLoad("TV", "Widemode");
812   if (config)
813   {
814     if (!STRCASECMP(config, "Letterbox"))
815     {
816       logger->log("Command", Log::INFO, "Setting letterbox mode");
817       video->setMode(Video::LETTERBOX);
818     }
819     else
820     {
821       logger->log("Command", Log::INFO, "Setting chop-sides mode");
822       video->setMode(Video::NORMAL);
823     }
824     delete[] config;
825   }
826   else
827   {
828     logger->log("Command", Log::INFO, "Config TV/Widemode not found, Setting chop-sides mode");
829     video->setMode(Video::NORMAL);
830   }
831
832   config = vdr->configLoad("Advanced", "TCP receive window");
833   if (config)
834   {
835     size_t newTCPsize = atoi(config);
836     delete[] config;
837
838     logger->log("Command", Log::INFO, "Setting TCP window size %i", newTCPsize);
839     vdr->setReceiveWindow(newTCPsize);
840   }
841   else
842   {
843     logger->log("Command", Log::INFO, "TCP window size not found, setting 2048");
844     vdr->setReceiveWindow(2048); // Default
845   }
846
847   config = vdr->configLoad("Advanced", "Disable WOL");
848   if (config)
849   {
850     if (!STRCASECMP(config, "Yes"))
851     {
852       logger->log("Command", Log::INFO, "Config says disable WOL");
853       Wol::getInstance()->setEnabled(false);
854     }
855     else
856     {
857       logger->log("Command", Log::INFO, "Config says enable WOL");
858       Wol::getInstance()->setEnabled(true);
859     }
860
861     delete[] config;
862   }
863   else
864   {
865     logger->log("Command", Log::INFO, "By default, enable WOL");
866     Wol::getInstance()->setEnabled(true);
867   }
868   /* device dependend config */
869   audio->loadOptionsfromServer(vdr);
870   video->loadOptionsfromServer(vdr);
871   remote->loadOptionsfromServer(vdr);
872   // config done
873
874   // Save power state = on
875
876   vdr->configSave("General", "Last Power State", "On");
877
878   // Make sure connection didn't die
879   if (!vdr->isConnected())
880   {
881     Command::getInstance()->connectionLost();
882   }
883   else
884   {
885     boxstack->remove(vi);
886
887     VWelcome* vw = new VWelcome();
888     vw->draw();
889     boxstack->add(vw);
890     boxstack->update(vw);
891
892     // Enter pre-keys here
893 //    handleCommand(Remote::OK);
894 //    handleCommand(Remote::ONE);
895 //    handleCommand(Remote::SIX);
896 //    handleCommand(Remote::OK);
897 //    handleCommand(Remote::UP);
898 //    handleCommand(Remote::PLAY);
899 //    handleCommand(Remote::DOWN);
900 //    handleCommand(Remote::DOWN);
901 //    handleCommand(Remote::DOWN);
902 //    handleCommand(Remote::OK);
903 //    handleCommand(Remote::RED);
904   }
905 }