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