]> git.vomp.tv Git - vompclient.git/blob - main.cc
MVP code removal
[vompclient.git] / main.cc
1 /*
2     Copyright 2004-2020 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, see <https://www.gnu.org/licenses/>.
18 */
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <signal.h>
24 #ifndef WIN32
25 #include <unistd.h>
26 #include <endian.h>
27 #endif
28
29 #include "defines.h"
30
31 #ifdef HANDLE_VT_SWITCHING
32 #include <signal.h>
33 #include <sys/ioctl.h>
34 #include <linux/vt.h>
35 #endif
36 #include "log.h"
37 #include "timers.h"
38 #include "vdr.h"
39 #include "boxstack.h"
40 #include "command.h"
41
42 #ifdef VOMP_PLATTFORM_NMT
43
44 #include "remotelirc.h"
45 #include "lednmt.h"
46 #include "osddirectfb.h"
47 #include "audionmt.h"
48 #include "videonmt.h"
49
50 #endif
51
52 #ifdef VOMP_PLATFORM_RASPBERRY
53
54 #include "remotelinux.h"
55 #include "ledraspberry.h"
56 #include "osdopenvg.h"
57 #include "audioomx.h"
58 #include "videoomx.h"
59
60 #endif
61
62
63 #include "wol.h"
64 #include "vsleeptimer.h"
65
66
67 #ifndef WIN32
68 void sighandler(int signalReceived);
69 #endif
70
71 void shutdown(int code);
72
73 // Global variables --------------------------------------------------------------------------------------------------
74 Log* logger;
75 Remote* remote;
76 Led* led;
77 Osd* osd;
78 Timers* timers;
79 BoxStack* boxstack;
80 Command* command;
81 VDR* vdr;
82 Video* video;
83 Audio* audio;
84 Wol* wol;
85 Sleeptimer* sleeptimer;
86
87 #ifdef HANDLE_VT_SWITCHING
88 int fdtty;
89 struct vt_mode old_vtmode;
90 #endif
91
92 // Linux main function and sighandler
93 #ifndef WIN32
94 int main(int argc, char** argv)
95 {
96   bool daemonize = true;
97   bool debugEnabled = false;
98   bool crashed = false;
99   char* setServer = NULL;
100   int c;
101
102   while ((c = getopt(argc, argv, "cdns:")) != -1)
103   {
104     switch (c)
105     {
106       case 'c':
107         crashed = true;
108         break;
109       case 'd':
110         debugEnabled = true; // and...
111       case 'n':
112         daemonize = false;
113         break;
114       case 's':
115         setServer = optarg;
116         break;
117       case '?':
118         printf("Unknown option\n");
119         return 1;
120       default:
121         printf("Option error\n");
122         return 1;
123     }
124   }
125
126   // Init global vars ------------------------------------------------------------------------------------------------
127   logger     = new Log();
128   timers     = new Timers();
129   vdr        = new VDR();
130
131   remote     = new Remote_TYPE();
132   led        = new Led_TYPE();
133   osd        = new Osd_TYPE();
134   audio      = new Audio_TYPE();
135   video      = new Video_TYPE();
136
137
138
139   boxstack   = new BoxStack();
140   command    = new Command();
141   wol        = new Wol();
142   sleeptimer = new Sleeptimer();
143
144   if (!logger || !remote || !led || !osd || !video || !audio || !boxstack || !command || !wol || !sleeptimer)
145   {
146     printf("Could not create objects. Memory problems?\n");
147     shutdown(1);
148   }
149
150   // Get logging module started --------------------------------------------------------------------------------------
151
152   if (!logger->init(Log::DEBUG, "dummy", debugEnabled ? 1 : 0))
153   {
154     printf("Could not initialise log object. Aborting.\n");
155     shutdown(1);
156   }
157
158   logger->log("Core", Log::INFO, "Starting up...");
159
160   // Daemonize if not -d
161
162   if (daemonize)
163   {
164     // Fork away
165     pid_t forkTest = fork();
166     if (forkTest == -1)
167     { printf("Cannot fork (1).\n"); exit(1); }
168     if (forkTest != 0) _exit(0); // PID returned, I am the parent
169     // otherwise, I am the child
170     setsid();
171     forkTest = fork();
172     if (forkTest == -1)
173     { printf("Cannot fork (2).\n"); exit(1); }
174     if (forkTest != 0) _exit(0); // PID returned, I am the parent
175     // otherwise, I am the child
176     close(0);
177     close(1);
178     close(2);
179   }
180
181   // Set up signal handling ------------------------------------------------------------------------------------------
182
183   sighandler_t sigtest;
184
185   sigtest = signal(SIGPIPE, SIG_IGN);
186   if (sigtest == SIG_ERR)
187   {
188     logger->log("Core", Log::EMERG, "Could not set up signal handler for SIGPIPE. Aborting.");
189     shutdown(1);
190   }
191   sigtest = signal(SIGINT, sighandler);
192   if (sigtest == SIG_ERR)
193   {
194     logger->log("Core", Log::EMERG, "Could not set up signal handler for SIGINT. Aborting.");
195     shutdown(1);
196   }
197   sigtest = signal(SIGTERM, sighandler);
198   if (sigtest == SIG_ERR)
199   {
200     logger->log("Core", Log::EMERG, "Could not set up signal handler for SIGTERM. Aborting.");
201     shutdown(1);
202   }
203   sigtest = signal(SIGUSR1, sighandler);
204   if (sigtest == SIG_ERR)
205   {
206     logger->log("Core", Log::EMERG, "Could not set up signal handler for SIGUSR1. Aborting.");
207     shutdown(1);
208   }
209   sigtest = signal(SIGUSR2, sighandler);
210   if (sigtest == SIG_ERR)
211   {
212     logger->log("Core", Log::EMERG, "Could not set up signal handler for SIGUSR2. Aborting.");
213     shutdown(1);
214   }
215   sigtest = signal(SIGURG, sighandler);
216   if (sigtest == SIG_ERR)
217   {
218     logger->log("Core", Log::EMERG, "Could not set up signal handler for SIGURG. Aborting.");
219     shutdown(1);
220   }
221
222   logger->log("Core", Log::INFO, "Signal handlers set up successfully");
223
224 #ifdef HANDLE_VT_SWITCHING
225   if ((fdtty = open("/dev/tty", O_WRONLY),0) == -1) {
226           logger->log("Core", Log::EMERG, "Could not open /dev/tty. Please change permissions");
227   } else {
228           int free_vt;
229           if (ioctl(fdtty,VT_OPENQRY,&free_vt)==-1 || free_vt==-1){
230                   logger->log("Core", Log::EMERG, "Could not retrieve free virtual console, please change permissions");
231           } else {
232                   ioctl(fdtty,VT_ACTIVATE,free_vt);
233                   ioctl(fdtty,VT_WAITACTIVE,free_vt);
234                   ioctl(fdtty, VT_LOCKSWITCH, 1);
235           }
236   }
237
238 #endif
239
240   // Init modules ----------------------------------------------------------------------------------------------------
241   int success;
242
243   success = remote->init(RemoteStartDev);
244
245   if (success)
246   {
247     logger->log("Core", Log::INFO, "Remote module initialised");
248   }
249   else
250   {
251     logger->log("Core", Log::EMERG, "Remote module failed to initialise");
252     shutdown(1);
253   }
254
255   success = led->init(-1);
256   if (success)
257   {
258     logger->log("Core", Log::INFO, "LED module initialised");
259   }
260   else
261   {
262     logger->log("Core", Log::EMERG, "LED module failed to initialise");
263     shutdown(1);
264   }
265
266   success = timers->init();
267   if (success)
268   {
269     logger->log("Core", Log::INFO, "Timers module initialised");
270   }
271   else
272   {
273     logger->log("Core", Log::EMERG, "Timers module failed to initialise");
274     shutdown(1);
275   }
276
277   UCHAR videoFormat = Video::PAL; // PALNTSC FIXME
278
279   success = video->init(videoFormat);
280   if (success)
281   {
282     logger->log("Core", Log::INFO, "Video module initialised");
283   }
284   else
285   {
286     logger->log("Core", Log::EMERG, "Video module failed to initialise");
287     shutdown(1);
288   }
289
290   success = osd->init((void*)OsdStartDev);
291   if (success)
292   {
293     logger->log("Core", Log::INFO, "OSD module initialised");
294   }
295   else
296   {
297     logger->log("Core", Log::EMERG, "OSD module failed to initialise");
298     shutdown(1);
299   }
300
301   success = audio->init(Audio::MPEG2_PES);
302   if (success)
303   {
304     logger->log("Core", Log::INFO, "Audio module initialised");
305   }
306   else
307   {
308     logger->log("Core", Log::EMERG, "Audio module failed to initialise");
309     shutdown(1);
310   }
311
312   success = vdr->init();
313   if (success)
314   {
315     logger->log("Core", Log::INFO, "VDR module initialised");
316   }
317   else
318   {
319     logger->log("Core", Log::EMERG, "VDR module failed to initialise");
320     shutdown(1);
321   }
322
323   success = boxstack->init();
324   if (success)
325   {
326     logger->log("Core", Log::INFO, "BoxStack module initialised");
327   }
328   else
329   {
330     logger->log("Core", Log::EMERG, "BoxStack module failed to initialise");
331     shutdown(1);
332   }
333
334   success = command->init(crashed, setServer);
335   if (success)
336   {
337     logger->log("Core", Log::INFO, "Command module initialised");
338   }
339   else
340   {
341     logger->log("Core", Log::EMERG, "Command module failed to initialise");
342     shutdown(1);
343   }
344
345   // Other init ------------------------------------------------------------------------------------------------------
346
347   logger->log("Core", Log::NOTICE, "Startup successful");
348
349   // Run main loop ---------------------------------------------------------------------------------------------------
350
351   // Ok, all major device components and other bits are loaded and ready
352   command->run();
353
354   // When that returns quit ------------------------------------------------------------------------------------------
355   shutdown(0);
356   return 0;
357 }
358
359 // -------------------------------------------------------------------------------------------------------------------
360
361 void sighandler(int signalReceived)
362 {
363   if (command) command->setSignal(signalReceived);
364 }
365
366 #endif
367
368 // -------------------------------------------------------------------------------------------------------------------
369
370 void shutdown(int code)
371 {
372   if (boxstack)
373   {
374     boxstack->shutdown();
375     delete boxstack;
376     logger->log("Core", Log::NOTICE, "BoxStack module shut down");
377   }
378
379   // FIXME, send a del all to boxstack first, then get rid of it after command?
380   if (command) // shut down command here in case views have posted messages
381   {
382     command->shutdown();
383     delete command;
384     command = NULL;
385     logger->log("Core", Log::NOTICE, "Command module shut down");
386   }
387
388   if (vdr)
389   {
390     vdr->shutdown();
391     delete vdr;
392     logger->log("Core", Log::NOTICE, "VDR module shut down");
393   }
394
395   if (osd)
396   {
397     osd->shutdown();
398     delete osd;
399     logger->log("Core", Log::NOTICE, "OSD module shut down");
400   }
401
402   if (audio)
403   {
404     audio->shutdown();
405     delete audio;
406     logger->log("Core", Log::NOTICE, "Audio module shut down");
407   }
408
409   if (video)
410   {
411     video->shutdown();
412     delete video;
413     logger->log("Core", Log::NOTICE, "Video module shut down");
414   }
415
416   if (timers)
417   {
418     timers->shutdown();
419     delete timers;
420     logger->log("Core", Log::NOTICE, "Timers module shut down");
421   }
422
423   if (led)
424   {
425     led->shutdown();
426     delete led;
427     logger->log("Core", Log::NOTICE, "LED module shut down");
428   }
429
430   if (remote)
431   {
432     remote->shutdown();
433     delete remote;
434     logger->log("Core", Log::NOTICE, "Remote module shut down");
435   }
436
437   if (wol)
438   {
439     delete wol;
440     logger->log("Core", Log::NOTICE, "WOL module shut down");
441   }
442
443   if (sleeptimer)
444   {
445     delete sleeptimer;
446     logger->log("Core", Log::NOTICE, "Sleeptimer module shut down");
447   }
448 #ifdef HANDLE_VT_SWITCHING
449   ioctl(fdtty, VT_UNLOCKSWITCH, 1);
450   close(fdtty);
451 #endif
452
453   if (logger)
454   {
455     logger->log("Core", Log::NOTICE, "Log module shutting down... bye!\n\n");
456     logger->shutdown();
457     delete logger;
458   }
459
460   exit(code);
461 }
462
463 // -------------------------------------------------------------------------------------------------------------------
464
465 ULLONG htonll(ULLONG a)
466 {
467   #if BYTE_ORDER == BIG_ENDIAN
468     return a;
469   #else
470     ULLONG b = 0;
471
472     b = ((a << 56) & 0xFF00000000000000ULL)
473       | ((a << 40) & 0x00FF000000000000ULL)
474       | ((a << 24) & 0x0000FF0000000000ULL)
475       | ((a <<  8) & 0x000000FF00000000ULL)
476       | ((a >>  8) & 0x00000000FF000000ULL)
477       | ((a >> 24) & 0x0000000000FF0000ULL)
478       | ((a >> 40) & 0x000000000000FF00ULL)
479       | ((a >> 56) & 0x00000000000000FFULL) ;
480
481     return b;
482   #endif
483 }
484
485 ULLONG ntohll(ULLONG a)
486 {
487   return htonll(a);
488 }
489
490 void MILLISLEEP(ULONG a)
491 {
492 #ifndef WIN32
493   struct timespec delayTime;
494   delayTime.tv_sec = a / 1000;
495   delayTime.tv_nsec = (a % 1000) * 1000000;
496   nanosleep(&delayTime, NULL);
497 #else
498   Sleep(a);
499 #endif
500 }
501
502 long long getTimeMS()
503 {
504   struct timespec ts;
505   clock_gettime(VOMP_LINUX_CLOCK, &ts);
506   return ts.tv_sec * 1000 + ts.tv_nsec / 1000000LL;
507 }
508
509 int getClockRealTime(struct timespec *tp)
510 {
511   return clock_gettime(CLOCK_REALTIME, tp);
512 }
513
514 int min(UINT a, int b)
515 {
516   if (a > b) return b;
517   else return a;
518 }
519
520 int max(int a, int b)
521 {
522   if (a > b) return a;
523   else return b;
524 }