/src/bdremoteng.c
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