PageRenderTime 37ms CodeModel.GetById 19ms app.highlight 14ms RepoModel.GetById 1ms app.codeStats 0ms

/src/bdremoteng.c

http://bdremote-ng.googlecode.com/
C | 340 lines | 242 code | 55 blank | 43 comment | 25 complexity | 98fcbce9c1b3687bccff0d577a2aa52a MD5 | raw file
  1/*
  2 *  bdremoteng - helper daemon for Sony(R) BD Remote Control
  3 *  Based on bdremoted, written by Anton Starikov <antst@mail.ru>.
  4 *
  5 *  Copyright (C) 2009  Michael Wojciechowski <wojci@wojci.dk>
  6 *
  7 *
  8 *  This program is free software; you can redistribute it and/or modify
  9 *  it under the terms of the GNU General Public License as published by
 10 *  the Free Software Foundation; either version 2 of the License, or
 11 *  (at your option) any later version.
 12 *
 13 *  This program is distributed in the hope that it will be useful,
 14 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 15 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 16 *  GNU General Public License for more details.
 17 *
 18 *  You should have received a copy of the GNU General Public License
 19 *  along with this program; if not, write to the Free Software
 20 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 21 *
 22 */
 23
 24/** \ingroup app
 25 *  @{
 26 */
 27
 28/*! \file bdremoteng.c
 29  \brief The main application.
 30
 31  This file contains the main application.
 32
 33*/
 34
 35#include "bdremoteng.h"
 36
 37#define _GNU_SOURCE
 38#include <stdio.h>
 39#include <errno.h>
 40#include <fcntl.h>
 41#include <unistd.h>
 42#include <stdlib.h>
 43#include <string.h>
 44#include <syslog.h>
 45#include <signal.h>
 46#include <getopt.h>
 47#include <sys/poll.h>
 48#include <sys/ioctl.h>
 49#include <sys/socket.h>
 50
 51#include <pthread.h>
 52
 53#include <sys/types.h>
 54
 55
 56#include <globaldefs.h>
 57#include <bdrcfg.h>
 58#include <captureif.h>
 59#include <lirc_srv.h>
 60#include <ug.h>
 61#include <l.h>
 62#include <event_out.h>
 63
 64/** Handle signal: HUP. */
 65static void sig_hup(int sig);
 66
 67/** Handle signal: TERM. */
 68static void sig_term(int sig);
 69
 70/** Thread. Captures from BT interface. */
 71void* listener(void* _p);
 72
 73/*unsigned int globalLogMask = MODULEMASK_LIRC_THR;*/
 74
 75unsigned int globalLogMask = 
 76   MODULEMASK_LIRC_THR | MODULEMASK_LIRC_SOCK | 
 77   MODULEMASK_LIRC_CB | MODULEMASK_BT_IF | MODULEMASK_BT_IMPL | 
 78   MODULEMASK_QUEUE | MODULEMASK_SPARE | MODULEMASK_MAIN;
 79
 80static const unsigned int moduleMask = MODULEMASK_MAIN;
 81
 82int main(int argc, char *argv[])
 83{
 84   pthread_t bt_thread;
 85   struct sigaction sa;
 86   int opt;
 87   configuration config;
 88   lirc_data ldata;
 89   captureData cdata;
 90   int ret = -1;
 91
 92   /* printf("Mask: %u.\n", globalLogMask); */
 93
 94   setDefaultLog();
 95
 96   memset(&cdata, 0, sizeof(cdata));
 97   memset(&config, 0, sizeof(config));
 98   setDefaults(&config);
 99
100   while ((opt=getopt(argc,argv,"+p:t:a:b:i:r:e:R:u:g:f:ndhlE"))!=-1)
101      {
102         switch(opt)
103            {
104            case 'p':
105               config.listen_port=atoi(optarg);
106               break;
107            case 't':
108               config.disconnect_timeout=atoi(optarg);
109               break;
110            case 'a':
111               setRemoteAddress(&config, optarg);
112               break;
113            case 'b':
114               setBatteryScript(&config, optarg);
115               break;
116            case 'i':
117               setInterfaceAddress(&config, optarg);
118               break;
119            case 'r':
120               config.repeat_rate=atoi(optarg);
121               break;
122            case 'e':
123               config.repeat_delay=atoi(optarg);
124               break;
125            case 'd':
126               config.debug = 1;
127               break;
128            case 'n':
129               config.detach=0;
130               break;
131            case 'u':
132               setUser(&config, optarg);
133               break;
134            case 'g':
135               setGroup(&config, optarg);
136               break;
137            case 'R':
138               setRelease(&config, optarg);
139               break;
140            case 'l':
141               config.lirc_namespace = 1;
142               break;
143            case 'E':
144               config.event_out = 1;
145               break;
146            case 'f':
147               setLogFilename(&config, optarg);
148               break;
149            case 'h':
150               usage();
151               exit(0);
152               break;
153            default:
154               exit(0);
155            }
156      }
157
158   if (config.remote_addr == NULL)
159      {
160         usage();
161         printf("\nPlease specify a remote BD address using the -a switch.\n");
162
163         exit(0);
164      }
165
166   if (config.debug == 1)
167      {
168         printConfig(&config);
169      }
170
171   initLircData(&ldata, &config);
172
173   InitCaptureData(&cdata,
174                   &config,
175                   &ldata);
176
177   if (config.detach == 1)
178      {
179         if (daemon(0, 0))
180            {
181               perror("Can't start daemon");
182               exit(1);
183            };
184      };
185
186   nice(-4);
187
188   ret = InitcaptureLoop(&cdata);
189   if (ret == BDREMOTE_FAIL)
190      {
191         BDREMOTE_DBG(config.debug, "InitcaptureLoop failed.");
192         return BDREMOTE_FAIL;
193      }
194
195   if (userAndGroupSet(&config) == 1)
196      {
197         BDREMOTE_DBG(config.debug, "Changing UID:GID.");
198
199         if ((getuid() == 0) && (geteuid() == 0))
200            {
201               BDREMOTE_DBG(config.debug, "Can change UID:GID.");
202            }
203         else
204            {
205               BDREMOTE_DBG(config.debug, "Unable to change UID:GID..");
206               return BDREMOTE_FAIL;
207            }
208
209         if (changeUIDAndGID(config.user, config.group) == BDREMOTE_FAIL)
210            {
211               BDREMOTE_DBG(config.debug, "changeUIDAndGID() failed.");
212               return BDREMOTE_FAIL;
213            }
214      }
215
216   /* Open the logfile after changing UID/GID. */
217   if (setLogFile(&config) == BDREMOTE_FAIL)
218      {
219         exit(0);
220      }
221
222   if (config.log_filename_set)
223      {
224         BDREMOTE_LOG(config.debug,
225                      printf("Writting log to: '%s'\n", config.log_filename);
226                      );
227      }
228
229   /* Start listening for BT clients. */
230   if (pthread_create(&bt_thread, NULL, listener, &cdata) != 0)
231      {
232         perror("Could not create BT client thread");
233         closeLogFile();
234         exit(1);
235      }
236
237   memset(&sa, 0, sizeof(sa));
238   sa.sa_flags = SA_NOCLDSTOP;
239   sa.sa_handler = sig_term;
240   sigaction(SIGTERM, &sa, NULL);
241   sigaction(SIGINT,  &sa, NULL);
242   sa.sa_handler = sig_hup;
243   sigaction(SIGHUP, &sa, NULL);
244
245   sa.sa_handler = SIG_IGN;
246   sigaction(SIGCHLD, &sa, NULL);
247   sigaction(SIGPIPE, &sa, NULL);
248
249   /* Initialize output event device. */
250   if (config.event_out)
251   {
252       event_out_init();
253   }
254
255   /* Start LIRC thread. */
256   startLircThread(&ldata);
257
258   /* Start handling LIRC clients and forwarding data. */
259   lirc_server(&config, &ldata);
260
261   BDREMOTE_DBG(config.debug, "Terminating.");
262
263   pthread_kill (bt_thread, SIGTERM);
264   BDREMOTE_DBG(config.debug, "Waiting for threads to finish.");
265   pthread_join(bt_thread, NULL);
266   waitForLircThread(&ldata);
267   BDREMOTE_DBG(config.debug, "Done.");
268
269   DestroyCaptureData(&cdata);
270   destroyLircData(&ldata);
271
272   event_out_destroy();
273
274   destroyConfig(&config);
275
276   closeLogFile();
277
278   return EXIT_SUCCESS;
279}
280
281void* listener(void* _p)
282{
283   captureData* cd = (captureData*)_p;
284   int ret         = -1;
285
286   BDREMOTE_DBG(cd->config->debug, "Started listener thread.");
287   ret = captureLoop(cd);
288   if (ret < 0)
289      {
290         BDREMOTE_DBG(cd->config->debug, "captureLoop failed.");
291      }
292
293   return 0;
294}
295
296void usage(void)
297{
298   printf("bdremoteng - Sony BD Remote helper daemon version %s\n\n", VERSION);
299   printf("Usage:\n"
300          "\tbdremoteng [options]\n"
301          "\n");
302   printf("Options:\n"
303          "\t-p <port>            Set port number for incoming LIRCD connections.\n"
304          "\t-t <timeout>         Set disconnect timeout for BD remote (in seconds).\n"
305          "\t-i <address>         BT address of interface to use.\n"
306          "\t-a <address>         BT address of remote.\n"
307          "\t                     For example: -a 00:19:C1:5A:F1:3F. \n"
308          "\t-b <script>          Execute <script> when battery info changes.\n"
309          "\t                     Arguments: <prev charge> <current charge>, both in percent.\n");
310
311   printf("\t-r <rate>            Key repeat rate. Generate <rate> repeats per second.\n"
312          "\t-e <num>             Wait <num> ms before repeating a key.\n"
313          "\t-R <suffix>          Auto-generate release events with appended <suffix>.\n"
314          "\t-l                   Follow LIRC namespace for the key names.\n"
315          "\t-E                   Make output available through a Linux event device.\n"
316          "\t-u <username>        Change UID to the UID of this user.\n"
317          "\t-g <group>           Change GID to the GID of this group.\n"
318          "\t-f <filename>        Write log to <filename>.\n"
319          "\t-d                   Enable debug.\n"
320          "\t-n                   Don't fork daemon to background.\n"
321          "\t-h, --help           Display help.\n"
322          "\n");
323
324}
325
326void sig_hup(int _sig)
327{
328   (void)_sig;
329   /* BDREMOTE_DBG("Not handling HUP."); */
330}
331
332void sig_term(int _sig)
333{
334   extern volatile sig_atomic_t __io_canceled;
335   __io_canceled = 1;
336   (void)_sig;
337}
338
339/*@}*/
340