2 Copyright 2004-2005 Chris Tallon
\r
4 This file is part of VOMP.
\r
6 VOMP is free software; you can redistribute it and/or modify
\r
7 it under the terms of the GNU General Public License as published by
\r
8 the Free Software Foundation; either version 2 of the License, or
\r
9 (at your option) any later version.
\r
11 VOMP is distributed in the hope that it will be useful,
\r
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
14 GNU General Public License for more details.
\r
16 You should have received a copy of the GNU General Public License
\r
17 along with VOMP; if not, write to the Free Software
\r
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
\r
30 #include "defines.h"
\r
32 #ifdef HANDLE_VT_SWITCHING
\r
34 #include <sys/ioctl.h>
\r
35 #include <linux/vt.h>
\r
40 #include "boxstack.h"
\r
41 #include "command.h"
\r
44 #ifdef VOMP_PLATTFORM_MVP
\r
48 #include "remotemvp.h"
\r
51 #include "audiomvp.h"
\r
52 #include "videomvp.h"
\r
56 int ticonfig_main(int, char**);
\r
61 #ifdef VOMP_PLATTFORM_NMT
\r
64 #include "remotelirc.h"
\r
66 #include "osddirectfb.h"
\r
67 #include "audionmt.h"
\r
68 #include "videonmt.h"
\r
72 #ifdef VOMP_PLATTFORM_RASPBERRY
\r
74 #include "mtdraspberry.h"
\r
75 #include "remotelinux.h"
\r
76 #include "ledraspberry.h"
\r
77 #include "osdopenvg.h"
\r
78 #include "audioomx.h"
\r
79 #include "videoomx.h"
\r
87 #include "vsleeptimer.h"
\r
91 void sighandler(int signalReceived);
\r
94 void shutdown(int code);
\r
98 // Global variables --------------------------------------------------------------------------------------------------
\r
105 BoxStack* boxstack;
\r
111 Sleeptimer* sleeptimer;
\r
113 #ifdef HANDLE_VT_SWITCHING
\r
115 struct vt_mode old_vtmode;
\r
118 // Linux MVP main function and sighandler
\r
120 int main(int argc, char** argv)
\r
122 #ifdef VOMP_PLATTFORM_MVP
\r
123 if (strstr(argv[0], "ticonfig")) return ticonfig_main(argc, argv);
\r
126 bool daemonize = true;
\r
127 bool debugEnabled = false;
\r
128 bool crashed = false;
\r
129 char* setServer = NULL;
\r
132 while ((c = getopt(argc, argv, "cdns:")) != -1)
\r
140 debugEnabled = true; // and...
\r
145 setServer = optarg;
\r
148 printf("Unknown option\n");
\r
151 printf("Option error\n");
\r
156 // Init global vars ------------------------------------------------------------------------------------------------
\r
157 logger = new Log();
\r
158 timers = new Timers();
\r
161 mtd = new Mtd_TYPE();
\r
162 remote = new Remote_TYPE();
\r
163 led = new Led_TYPE();
\r
164 osd = new Osd_TYPE();
\r
165 audio = new Audio_TYPE();
\r
166 video = new Video_TYPE();
\r
170 boxstack = new BoxStack();
\r
171 command = new Command();
\r
173 sleeptimer = new Sleeptimer();
\r
175 if (!logger || !remote || !mtd || !led || !osd || !video || !audio || !boxstack || !command || !wol || !sleeptimer)
\r
177 printf("Could not create objects. Memory problems?\n");
\r
181 // Get logging module started --------------------------------------------------------------------------------------
\r
183 if (!logger->init(Log::DEBUG, "dummy", debugEnabled ? 1 : 0))
\r
185 printf("Could not initialise log object. Aborting.\n");
\r
189 logger->log("Core", Log::INFO, "Starting up...");
\r
191 // Daemonize if not -d
\r
196 pid_t forkTest = fork();
\r
197 if (forkTest == -1)
\r
198 { printf("Cannot fork (1).\n"); exit(1); }
\r
199 if (forkTest != 0) _exit(0); // PID returned, I am the parent
\r
200 // otherwise, I am the child
\r
203 if (forkTest == -1)
\r
204 { printf("Cannot fork (2).\n"); exit(1); }
\r
205 if (forkTest != 0) _exit(0); // PID returned, I am the parent
\r
206 // otherwise, I am the child
\r
212 // Set up signal handling ------------------------------------------------------------------------------------------
\r
214 sighandler_t sigtest;
\r
216 sigtest = signal(SIGPIPE, SIG_IGN);
\r
217 if (sigtest == SIG_ERR)
\r
219 logger->log("Core", Log::EMERG, "Could not set up signal handler for SIGPIPE. Aborting.");
\r
222 sigtest = signal(SIGINT, sighandler);
\r
223 if (sigtest == SIG_ERR)
\r
225 logger->log("Core", Log::EMERG, "Could not set up signal handler for SIGINT. Aborting.");
\r
228 sigtest = signal(SIGTERM, sighandler);
\r
229 if (sigtest == SIG_ERR)
\r
231 logger->log("Core", Log::EMERG, "Could not set up signal handler for SIGTERM. Aborting.");
\r
234 sigtest = signal(SIGUSR1, sighandler);
\r
235 if (sigtest == SIG_ERR)
\r
237 logger->log("Core", Log::EMERG, "Could not set up signal handler for SIGUSR1. Aborting.");
\r
241 sigtest = signal(SIGUSR2, sighandler);
\r
242 if (sigtest == SIG_ERR)
\r
244 logger->log("Core", Log::EMERG, "Could not set up signal handler for SIGUSR2. Aborting.");
\r
248 sigtest = signal(SIGURG, sighandler);
\r
249 if (sigtest == SIG_ERR)
\r
251 logger->log("Core", Log::EMERG, "Could not set up signal handler for SIGURG. Aborting.");
\r
255 logger->log("Core", Log::INFO, "Signal handlers set up successfully");
\r
257 #ifdef HANDLE_VT_SWITCHING
\r
258 if ((fdtty = open("/dev/tty", O_WRONLY),0) == -1) {
\r
259 logger->log("Core", Log::EMERG, "Could not open /dev/tty. Please change permissions");
\r
262 if (ioctl(fdtty,VT_OPENQRY,&free_vt)==-1 || free_vt==-1){
\r
263 logger->log("Core", Log::EMERG, "Could not retrieve free virtual console, please change permissions");
\r
265 ioctl(fdtty,VT_ACTIVATE,free_vt);
\r
266 ioctl(fdtty,VT_WAITACTIVE,free_vt);
\r
267 ioctl(fdtty, VT_LOCKSWITCH, 1);
\r
273 // Init modules ----------------------------------------------------------------------------------------------------
\r
276 success = remote->init(RemoteStartDev);
\r
280 logger->log("Core", Log::INFO, "Remote module initialised");
\r
284 logger->log("Core", Log::EMERG, "Remote module failed to initialise");
\r
287 #ifdef VOMP_PLATTFORM_MVP
\r
288 success = led->init(((RemoteMVP*)remote)->getDevice());
\r
290 success = led->init(-1);
\r
294 logger->log("Core", Log::INFO, "LED module initialised");
\r
298 logger->log("Core", Log::EMERG, "LED module failed to initialise");
\r
302 success = mtd->init();
\r
305 logger->log("Core", Log::INFO, "Mtd module initialised");
\r
309 logger->log("Core", Log::EMERG, "Mtd module failed to initialise");
\r
313 success = timers->init();
\r
316 logger->log("Core", Log::INFO, "Timers module initialised");
\r
320 logger->log("Core", Log::EMERG, "Timers module failed to initialise");
\r
324 UCHAR videoFormat = (UCHAR)mtd->getPALorNTSC();
\r
325 if (videoFormat == Video::PAL) logger->log("Core", Log::INFO, "Read from MTD: PAL 720x576");
\r
326 else if (videoFormat == Video::NTSC) logger->log("Core", Log::INFO, "Read from MTD: NTSC 720x480");
\r
327 else logger->log("Core", Log::INFO, "No help from MTD. Assuming NTSC 720x480");
\r
329 success = video->init(videoFormat);
\r
332 logger->log("Core", Log::INFO, "Video module initialised");
\r
336 logger->log("Core", Log::EMERG, "Video module failed to initialise");
\r
340 success = osd->init((void*)OsdStartDev);
\r
343 logger->log("Core", Log::INFO, "OSD module initialised");
\r
347 logger->log("Core", Log::EMERG, "OSD module failed to initialise");
\r
351 success = audio->init(Audio::MPEG2_PES);
\r
354 logger->log("Core", Log::INFO, "Audio module initialised");
\r
358 logger->log("Core", Log::EMERG, "Audio module failed to initialise");
\r
362 success = vdr->init(3024);
\r
365 logger->log("Core", Log::INFO, "VDR module initialised");
\r
369 logger->log("Core", Log::EMERG, "VDR module failed to initialise");
\r
373 success = boxstack->init();
\r
376 logger->log("Core", Log::INFO, "BoxStack module initialised");
\r
380 logger->log("Core", Log::EMERG, "BoxStack module failed to initialise");
\r
384 success = command->init(crashed, setServer);
\r
387 logger->log("Core", Log::INFO, "Command module initialised");
\r
391 logger->log("Core", Log::EMERG, "Command module failed to initialise");
\r
395 // Other init ------------------------------------------------------------------------------------------------------
\r
397 logger->log("Core", Log::NOTICE, "Startup successful");
\r
399 // Run main loop ---------------------------------------------------------------------------------------------------
\r
401 // Ok, all major device components and other bits are loaded and ready
\r
404 // When that returns quit ------------------------------------------------------------------------------------------
\r
410 // -------------------------------------------------------------------------------------------------------------------
\r
412 void sighandler(int signalReceived)
\r
414 logger->log("Core", Log::NOTICE, "Signal %i received", signalReceived);
\r
416 switch (signalReceived)
\r
420 logger->log("Core", Log::NOTICE, "Interrupt signal, shutting down...");
\r
421 command->stop(); // FIXME this is probably not safe - use the messaging system / is that even safe?
\r
426 logger->log("Core", Log::NOTICE, "Term signal, shutting down...");
\r
427 command->stop(); // FIXME this is probably not safe - use the messaging system / is that even safe?
\r
438 logger->log("Core", Log::DEBUG, "SIGUSR1 caught");
\r
439 logger->upLogLevel();
\r
444 logger->log("Core", Log::DEBUG, "SIGUSR2 caught");
\r
445 logger->downLogLevel();
\r
451 logger->log("Core", Log::DEBUG, "SIGURG caught");
\r
458 // -------------------------------------------------------------------------------------------------------------------
\r
460 void shutdown(int code)
\r
464 boxstack->shutdown();
\r
466 logger->log("Core", Log::NOTICE, "BoxStack module shut down");
\r
469 // FIXME, send a del all to boxstack first, then get rid of it after command?
\r
470 if (command) // shut down command here in case views have posted messages
\r
472 command->shutdown();
\r
474 logger->log("Core", Log::NOTICE, "Command module shut down");
\r
481 logger->log("Core", Log::NOTICE, "VDR module shut down");
\r
488 logger->log("Core", Log::NOTICE, "OSD module shut down");
\r
495 logger->log("Core", Log::NOTICE, "Audio module shut down");
\r
502 logger->log("Core", Log::NOTICE, "Video module shut down");
\r
507 timers->shutdown();
\r
509 logger->log("Core", Log::NOTICE, "Timers module shut down");
\r
516 logger->log("Core", Log::NOTICE, "MTD module shut down");
\r
523 logger->log("Core", Log::NOTICE, "LED module shut down");
\r
528 remote->shutdown();
\r
530 logger->log("Core", Log::NOTICE, "Remote module shut down");
\r
536 logger->log("Core", Log::NOTICE, "WOL module shut down");
\r
542 logger->log("Core", Log::NOTICE, "Sleeptimer module shut down");
\r
544 #ifdef HANDLE_VT_SWITCHING
\r
545 ioctl(fdtty, VT_UNLOCKSWITCH, 1);
\r
551 logger->log("Core", Log::NOTICE, "Log module shutting down... bye!\n\n");
\r
552 logger->shutdown();
\r
559 // -------------------------------------------------------------------------------------------------------------------
\r
561 ULLONG htonll(ULLONG a)
\r
563 #if BYTE_ORDER == BIG_ENDIAN
\r
568 b = ((a << 56) & 0xFF00000000000000ULL)
\r
569 | ((a << 40) & 0x00FF000000000000ULL)
\r
570 | ((a << 24) & 0x0000FF0000000000ULL)
\r
571 | ((a << 8) & 0x000000FF00000000ULL)
\r
572 | ((a >> 8) & 0x00000000FF000000ULL)
\r
573 | ((a >> 24) & 0x0000000000FF0000ULL)
\r
574 | ((a >> 40) & 0x000000000000FF00ULL)
\r
575 | ((a >> 56) & 0x00000000000000FFULL) ;
\r
581 ULLONG ntohll(ULLONG a)
\r
586 void MILLISLEEP(ULONG a)
\r
589 struct timespec delayTime;
\r
590 delayTime.tv_sec = a / 1000;
\r
591 delayTime.tv_nsec = (a % 1000) * 1000000;
\r
592 nanosleep(&delayTime, NULL);
\r
598 long long getTimeMS() {
\r
599 struct timespec ts;
\r
600 clock_gettime(VOMP_LINUX_CLOCK, &ts);
\r
601 return ts.tv_sec*1000+ts.tv_nsec/1000000LL;
\r
604 int min(UINT a, int b)
\r
606 if (a > b) return b;
\r
610 int max(int a, int b)
\r
612 if (a > b) return a;
\r