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