]> git.vomp.tv Git - vompclient.git/blob - main.cc
Portability
[vompclient.git] / main.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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <signal.h>
25 #ifndef WIN32
26 #include <unistd.h>
27 #include <endian.h>
28 #endif
29
30 #include "defines.h"
31 #include "log.h"
32 #include "timers.h"
33 #include "vdr.h"
34 #include "viewman.h"
35 #include "command.h"
36
37 #ifdef WIN32
38   #include "mtdwin.h"
39   #include "remotewin.h"
40   #include "ledwin.h"
41   #include "osdwin.h"
42   #include "audiowin.h"
43   #include "videowin.h"
44 #else
45   #include "mtdmvp.h"
46   #include "remotemvp.h"
47   #include "ledmvp.h"
48   #include "osdmvp.h"
49   #include "audiomvp.h"
50   #include "videomvp.h"
51 #endif
52
53 void sighandler(int signalReceived);
54 void shutdown(int code);
55
56 // Global variables --------------------------------------------------------------------------------------------------
57 int debugEnabled = 0;
58 Log* logger;
59 Remote* remote;
60 Mtd* mtd;
61 Led* led;
62 Osd* osd;
63 Timers* timers;
64 ViewMan* viewman;
65 Command* command;
66 VDR* vdr;
67 Video* video;
68 Audio* audio;
69
70 int main(int argc, char** argv)
71 {
72   if ((argc > 1) && (!strcmp(argv[1], "-d"))) debugEnabled = 1;
73
74
75   // Init global vars ------------------------------------------------------------------------------------------------
76
77   logger     = new Log();
78   timers     = new Timers();
79   vdr        = new VDR();
80 #ifdef WIN32
81   mtd        = new MtdWin();
82   remote     = new RemoteWin();
83   led        = new LedWin();
84   osd        = new OsdWin();
85   audio      = new AudioWin();
86   video      = new VideoWin();
87 #else
88   mtd        = new MtdMVP();
89   remote     = new RemoteMVP();
90   led        = new LedMVP();
91   osd        = new OsdMVP();
92   audio      = new AudioMVP();
93   video      = new VideoMVP();
94 #endif
95   viewman    = new ViewMan();
96   command    = new Command();
97
98   if (!logger || !remote || !mtd || !led || !osd || !video || !audio || !viewman || !command)
99   {
100     printf("Could not create objects. Memory problems?\n");
101     shutdown(1);
102   }
103
104   // Get logging module started --------------------------------------------------------------------------------------
105
106   if (!logger->init(Log::DEBUG, "dummy", debugEnabled))
107   {
108     printf("Could not initialise log object. Aborting.\n");
109     shutdown(1);
110   }
111
112   logger->log("Core", Log::INFO, "Starting up...");
113
114   // Daemonize if not -d
115
116   if (!debugEnabled)
117   {
118     // Fork away
119     pid_t forkTest = fork();
120     if (forkTest == -1)
121     { printf("Cannot fork (1).\n"); exit(1); }
122     if (forkTest != 0) _exit(0); // PID returned, I am the parent
123     // otherwise, I am the child
124     setsid();
125     forkTest = fork();
126     if (forkTest == -1)
127     { printf("Cannot fork (2).\n"); exit(1); }
128     if (forkTest != 0) _exit(0); // PID returned, I am the parent
129     // otherwise, I am the child
130     close(0);
131     close(1);
132     close(2);
133   }
134
135   // Set up signal handling ------------------------------------------------------------------------------------------
136
137   sighandler_t sigtest;
138
139   sigtest = signal(SIGPIPE, SIG_IGN);
140   if (sigtest == SIG_ERR)
141   {
142     logger->log("Core", Log::EMERG, "Could not set up signal handler for SIGPIPE. Aborting.");
143     shutdown(1);
144   }
145   sigtest = signal(SIGINT, sighandler);
146   if (sigtest == SIG_ERR)
147   {
148     logger->log("Core", Log::EMERG, "Could not set up signal handler for SIGINT. Aborting.");
149     shutdown(1);
150   }
151   sigtest = signal(SIGTERM, sighandler);
152   if (sigtest == SIG_ERR)
153   {
154     logger->log("Core", Log::EMERG, "Could not set up signal handler for SIGTERM. Aborting.");
155     shutdown(1);
156   }
157   sigtest = signal(SIGUSR1, sighandler);
158   if (sigtest == SIG_ERR)
159   {
160     logger->log("Core", Log::EMERG, "Could not set up signal handler for SIGUSR1. Aborting.");
161     shutdown(1);
162   }
163 /*
164   sigtest = signal(SIGUSR2, sighandler);
165   if (sigtest == SIG_ERR)
166   {
167     logger->log("Core", Log::EMERG, "Could not set up signal handler for SIGUSR2. Aborting.");
168     shutdown(1);
169   }
170 */
171   sigtest = signal(SIGURG, sighandler);
172   if (sigtest == SIG_ERR)
173   {
174     logger->log("Core", Log::EMERG, "Could not set up signal handler for SIGURG. Aborting.");
175     shutdown(1);
176   }
177
178   logger->log("Core", Log::INFO, "Signal handlers set up successfully");
179
180
181   // Init modules ----------------------------------------------------------------------------------------------------
182   int success;
183
184   success = remote->init("/dev/rawir");
185   if (success)
186   {
187     logger->log("Core", Log::INFO, "Remote module initialised");
188   }
189   else
190   {
191     logger->log("Core", Log::EMERG, "Remote module failed to initialise");
192     shutdown(1);
193   }
194
195 #ifdef WIN32
196   success = led->init();
197 #else
198   success = led->init(((RemoteMVP*)remote)->getDevice());
199 #endif
200   if (success)
201   {
202     logger->log("Core", Log::INFO, "LED module initialised");
203   }
204   else
205   {
206     logger->log("Core", Log::EMERG, "LED module failed to initialise");
207     shutdown(1);
208   }
209
210   success = mtd->init("/dev/mtd1");
211   if (success)
212   {
213     logger->log("Core", Log::INFO, "Mtd module initialised");
214   }
215   else
216   {
217     logger->log("Core", Log::EMERG, "Mtd module failed to initialise");
218     shutdown(1);
219   }
220
221   success = timers->init();
222   if (success)
223   {
224     logger->log("Core", Log::INFO, "Timers module initialised");
225   }
226   else
227   {
228     logger->log("Core", Log::EMERG, "Timers module failed to initialise");
229     shutdown(1);
230   }
231
232   UCHAR videoFormat = (UCHAR)mtd->getPALorNTSC();
233   if      (videoFormat == Video::PAL)  logger->log("Core", Log::INFO, "Read from MTD: PAL 720x576");
234   else if (videoFormat == Video::NTSC) logger->log("Core", Log::INFO, "Read from MTD: NTSC 720x480");
235   else                                 logger->log("Core", Log::INFO, "No help from MTD. Assuming NTSC 720x480");
236
237   success = video->init(videoFormat);
238   if (success)
239   {
240     logger->log("Core", Log::INFO, "Video module initialised");
241   }
242   else
243   {
244     logger->log("Core", Log::EMERG, "Video module failed to initialise");
245     shutdown(1);
246   }
247
248   success = osd->init("/dev/stbgfx");
249   if (success)
250   {
251     logger->log("Core", Log::INFO, "OSD module initialised");
252   }
253   else
254   {
255     logger->log("Core", Log::EMERG, "OSD module failed to initialise");
256     shutdown(1);
257   }
258
259   success = audio->init(Audio::MPEG2_PES);
260   if (success)
261   {
262     logger->log("Core", Log::INFO, "Audio module initialised");
263   }
264   else
265   {
266     logger->log("Core", Log::EMERG, "Audio module failed to initialise");
267     shutdown(1);
268   }
269
270   success = vdr->init(3024);
271   if (success)
272   {
273     logger->log("Core", Log::INFO, "VDR module initialised");
274   }
275   else
276   {
277     logger->log("Core", Log::EMERG, "VDR module failed to initialise");
278     shutdown(1);
279   }
280
281   success = viewman->init();
282   if (success)
283   {
284     logger->log("Core", Log::INFO, "ViewMan module initialised");
285   }
286   else
287   {
288     logger->log("Core", Log::EMERG, "ViewMan module failed to initialise");
289     shutdown(1);
290   }
291
292   success = command->init();
293   if (success)
294   {
295     logger->log("Core", Log::INFO, "Command module initialised");
296   }
297   else
298   {
299     logger->log("Core", Log::EMERG, "Command module failed to initialise");
300     shutdown(1);
301   }
302
303   // Other init ------------------------------------------------------------------------------------------------------
304
305   logger->log("Core", Log::NOTICE, "Startup successful");
306
307   // Run main loop ---------------------------------------------------------------------------------------------------
308
309   // Ok, all major device components and other bits are loaded and ready
310   command->run();
311
312   // When that returns quit ------------------------------------------------------------------------------------------
313
314   shutdown(0);
315   return 0;
316 }
317
318 // -------------------------------------------------------------------------------------------------------------------
319
320 void shutdown(int code)
321 {
322   if (viewman)
323   {
324     viewman->shutdown();
325     delete viewman;
326     logger->log("Core", Log::NOTICE, "ViewMan module shut down");
327   }
328
329   if (command) // shut down command here in case views have posted messages
330   {
331     command->shutdown();
332     delete command;
333     logger->log("Core", Log::NOTICE, "Command module shut down");
334   }
335
336   if (vdr)
337   {
338     vdr->shutdown();
339     delete vdr;
340     logger->log("Core", Log::NOTICE, "VDR module shut down");
341   }
342
343   if (osd)
344   {
345     osd->shutdown();
346     delete osd;
347     logger->log("Core", Log::NOTICE, "OSD module shut down");
348   }
349
350   if (audio)
351   {
352     audio->shutdown();
353     delete audio;
354     logger->log("Core", Log::NOTICE, "Audio module shut down");
355   }
356
357   if (video)
358   {
359     video->shutdown();
360     delete video;
361     logger->log("Core", Log::NOTICE, "Video module shut down");
362   }
363
364   if (timers)
365   {
366     timers->shutdown();
367     delete timers;
368     logger->log("Core", Log::NOTICE, "Timers module shut down");
369   }
370
371   if (mtd)
372   {
373     mtd->shutdown();
374     delete mtd;
375     logger->log("Core", Log::NOTICE, "MTD module shut down");
376   }
377
378   if (led)
379   {
380     led->shutdown();
381     delete led;
382     logger->log("Core", Log::NOTICE, "LED module shut down");
383   }
384
385   if (remote)
386   {
387     remote->shutdown();
388     delete remote;
389     logger->log("Core", Log::NOTICE, "Remote module shut down");
390   }
391
392   if (logger)
393   {
394     logger->log("Core", Log::NOTICE, "Log module shutting down... bye!\n\n");
395     logger->shutdown();
396     delete logger;
397   }
398
399   exit(code);
400 }
401
402 // -------------------------------------------------------------------------------------------------------------------
403
404 void sighandler(int signalReceived)
405 {
406   logger->log("Core", Log::NOTICE, "Signal %i received", signalReceived);
407
408   switch (signalReceived)
409   {
410     case SIGINT:
411     {
412       logger->log("Core", Log::NOTICE, "Interrupt signal, shutting down...");
413       command->stop(); // FIXME this is probably not safe - use the messaging system / is that even safe?
414       break;
415     }
416     case SIGTERM:
417     {
418       logger->log("Core", Log::NOTICE, "Term signal, shutting down...");
419       command->stop(); // FIXME this is probably not safe - use the messaging system / is that even safe?
420       break;
421     }
422     case SIGUSR1:
423     {
424       command->sig1();
425       break;
426     }
427 /*
428     case SIGUSR1:
429     {
430       logger->log("Core", Log::DEBUG, "SIGUSR1 caught");
431       logger->upLogLevel();
432       break;
433     }
434     case SIGUSR2:
435     {
436       logger->log("Core", Log::DEBUG, "SIGUSR2 caught");
437       logger->downLogLevel();
438       break;
439     }
440 */
441     case SIGURG:
442     {
443       logger->log("Core", Log::DEBUG, "SIGURG caught");
444       break;
445     }
446   }
447 }
448
449 // -------------------------------------------------------------------------------------------------------------------
450
451 ULLONG ntohll(ULLONG a)
452 {
453   return htonll(a);
454 }
455
456 ULLONG htonll(ULLONG a)
457 {
458   #if BYTE_ORDER == BIG_ENDIAN
459     return a;
460   #else
461     ULLONG b = 0;
462
463     b = ((a << 56) & 0xFF00000000000000ULL)
464       | ((a << 40) & 0x00FF000000000000ULL)
465       | ((a << 24) & 0x0000FF0000000000ULL)
466       | ((a <<  8) & 0x000000FF00000000ULL)
467       | ((a >>  8) & 0x00000000FF000000ULL)
468       | ((a >> 24) & 0x0000000000FF0000ULL)
469       | ((a >> 40) & 0x000000000000FF00ULL)
470       | ((a >> 56) & 0x00000000000000FFULL) ;
471
472     return b;
473   #endif
474 }
475
476 void MILLISLEEP(ULONG a)
477 {
478 #ifndef WIN32
479   struct timespec delayTime;
480   delayTime.tv_sec = a / 1000;
481   delayTime.tv_nsec = (a % 1000) * 1000000;
482   nanosleep(&delayTime, NULL);
483 #else
484   Sleep(a);
485 #endif
486 }