/src/bdremoteng.c

http://bdremote-ng.googlecode.com/ · C · 340 lines · 242 code · 55 blank · 43 comment · 26 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. /** \ingroup app
  24. * @{
  25. */
  26. /*! \file bdremoteng.c
  27. \brief The main application.
  28. This file contains the main application.
  29. */
  30. #include "bdremoteng.h"
  31. #define _GNU_SOURCE
  32. #include <stdio.h>
  33. #include <errno.h>
  34. #include <fcntl.h>
  35. #include <unistd.h>
  36. #include <stdlib.h>
  37. #include <string.h>
  38. #include <syslog.h>
  39. #include <signal.h>
  40. #include <getopt.h>
  41. #include <sys/poll.h>
  42. #include <sys/ioctl.h>
  43. #include <sys/socket.h>
  44. #include <pthread.h>
  45. #include <sys/types.h>
  46. #include <globaldefs.h>
  47. #include <bdrcfg.h>
  48. #include <captureif.h>
  49. #include <lirc_srv.h>
  50. #include <ug.h>
  51. #include <l.h>
  52. #include <event_out.h>
  53. /** Handle signal: HUP. */
  54. static void sig_hup(int sig);
  55. /** Handle signal: TERM. */
  56. static void sig_term(int sig);
  57. /** Thread. Captures from BT interface. */
  58. void* listener(void* _p);
  59. /*unsigned int globalLogMask = MODULEMASK_LIRC_THR;*/
  60. unsigned int globalLogMask =
  61. MODULEMASK_LIRC_THR | MODULEMASK_LIRC_SOCK |
  62. MODULEMASK_LIRC_CB | MODULEMASK_BT_IF | MODULEMASK_BT_IMPL |
  63. MODULEMASK_QUEUE | MODULEMASK_SPARE | MODULEMASK_MAIN;
  64. static const unsigned int moduleMask = MODULEMASK_MAIN;
  65. int main(int argc, char *argv[])
  66. {
  67. pthread_t bt_thread;
  68. struct sigaction sa;
  69. int opt;
  70. configuration config;
  71. lirc_data ldata;
  72. captureData cdata;
  73. int ret = -1;
  74. /* printf("Mask: %u.\n", globalLogMask); */
  75. setDefaultLog();
  76. memset(&cdata, 0, sizeof(cdata));
  77. memset(&config, 0, sizeof(config));
  78. setDefaults(&config);
  79. while ((opt=getopt(argc,argv,"+p:t:a:b:i:r:e:R:u:g:f:ndhlE"))!=-1)
  80. {
  81. switch(opt)
  82. {
  83. case 'p':
  84. config.listen_port=atoi(optarg);
  85. break;
  86. case 't':
  87. config.disconnect_timeout=atoi(optarg);
  88. break;
  89. case 'a':
  90. setRemoteAddress(&config, optarg);
  91. break;
  92. case 'b':
  93. setBatteryScript(&config, optarg);
  94. break;
  95. case 'i':
  96. setInterfaceAddress(&config, optarg);
  97. break;
  98. case 'r':
  99. config.repeat_rate=atoi(optarg);
  100. break;
  101. case 'e':
  102. config.repeat_delay=atoi(optarg);
  103. break;
  104. case 'd':
  105. config.debug = 1;
  106. break;
  107. case 'n':
  108. config.detach=0;
  109. break;
  110. case 'u':
  111. setUser(&config, optarg);
  112. break;
  113. case 'g':
  114. setGroup(&config, optarg);
  115. break;
  116. case 'R':
  117. setRelease(&config, optarg);
  118. break;
  119. case 'l':
  120. config.lirc_namespace = 1;
  121. break;
  122. case 'E':
  123. config.event_out = 1;
  124. break;
  125. case 'f':
  126. setLogFilename(&config, optarg);
  127. break;
  128. case 'h':
  129. usage();
  130. exit(0);
  131. break;
  132. default:
  133. exit(0);
  134. }
  135. }
  136. if (config.remote_addr == NULL)
  137. {
  138. usage();
  139. printf("\nPlease specify a remote BD address using the -a switch.\n");
  140. exit(0);
  141. }
  142. if (config.debug == 1)
  143. {
  144. printConfig(&config);
  145. }
  146. initLircData(&ldata, &config);
  147. InitCaptureData(&cdata,
  148. &config,
  149. &ldata);
  150. if (config.detach == 1)
  151. {
  152. if (daemon(0, 0))
  153. {
  154. perror("Can't start daemon");
  155. exit(1);
  156. };
  157. };
  158. nice(-4);
  159. ret = InitcaptureLoop(&cdata);
  160. if (ret == BDREMOTE_FAIL)
  161. {
  162. BDREMOTE_DBG(config.debug, "InitcaptureLoop failed.");
  163. return BDREMOTE_FAIL;
  164. }
  165. if (userAndGroupSet(&config) == 1)
  166. {
  167. BDREMOTE_DBG(config.debug, "Changing UID:GID.");
  168. if ((getuid() == 0) && (geteuid() == 0))
  169. {
  170. BDREMOTE_DBG(config.debug, "Can change UID:GID.");
  171. }
  172. else
  173. {
  174. BDREMOTE_DBG(config.debug, "Unable to change UID:GID..");
  175. return BDREMOTE_FAIL;
  176. }
  177. if (changeUIDAndGID(config.user, config.group) == BDREMOTE_FAIL)
  178. {
  179. BDREMOTE_DBG(config.debug, "changeUIDAndGID() failed.");
  180. return BDREMOTE_FAIL;
  181. }
  182. }
  183. /* Open the logfile after changing UID/GID. */
  184. if (setLogFile(&config) == BDREMOTE_FAIL)
  185. {
  186. exit(0);
  187. }
  188. if (config.log_filename_set)
  189. {
  190. BDREMOTE_LOG(config.debug,
  191. printf("Writting log to: '%s'\n", config.log_filename);
  192. );
  193. }
  194. /* Start listening for BT clients. */
  195. if (pthread_create(&bt_thread, NULL, listener, &cdata) != 0)
  196. {
  197. perror("Could not create BT client thread");
  198. closeLogFile();
  199. exit(1);
  200. }
  201. memset(&sa, 0, sizeof(sa));
  202. sa.sa_flags = SA_NOCLDSTOP;
  203. sa.sa_handler = sig_term;
  204. sigaction(SIGTERM, &sa, NULL);
  205. sigaction(SIGINT, &sa, NULL);
  206. sa.sa_handler = sig_hup;
  207. sigaction(SIGHUP, &sa, NULL);
  208. sa.sa_handler = SIG_IGN;
  209. sigaction(SIGCHLD, &sa, NULL);
  210. sigaction(SIGPIPE, &sa, NULL);
  211. /* Initialize output event device. */
  212. if (config.event_out)
  213. {
  214. event_out_init();
  215. }
  216. /* Start LIRC thread. */
  217. startLircThread(&ldata);
  218. /* Start handling LIRC clients and forwarding data. */
  219. lirc_server(&config, &ldata);
  220. BDREMOTE_DBG(config.debug, "Terminating.");
  221. pthread_kill (bt_thread, SIGTERM);
  222. BDREMOTE_DBG(config.debug, "Waiting for threads to finish.");
  223. pthread_join(bt_thread, NULL);
  224. waitForLircThread(&ldata);
  225. BDREMOTE_DBG(config.debug, "Done.");
  226. DestroyCaptureData(&cdata);
  227. destroyLircData(&ldata);
  228. event_out_destroy();
  229. destroyConfig(&config);
  230. closeLogFile();
  231. return EXIT_SUCCESS;
  232. }
  233. void* listener(void* _p)
  234. {
  235. captureData* cd = (captureData*)_p;
  236. int ret = -1;
  237. BDREMOTE_DBG(cd->config->debug, "Started listener thread.");
  238. ret = captureLoop(cd);
  239. if (ret < 0)
  240. {
  241. BDREMOTE_DBG(cd->config->debug, "captureLoop failed.");
  242. }
  243. return 0;
  244. }
  245. void usage(void)
  246. {
  247. printf("bdremoteng - Sony BD Remote helper daemon version %s\n\n", VERSION);
  248. printf("Usage:\n"
  249. "\tbdremoteng [options]\n"
  250. "\n");
  251. printf("Options:\n"
  252. "\t-p <port> Set port number for incoming LIRCD connections.\n"
  253. "\t-t <timeout> Set disconnect timeout for BD remote (in seconds).\n"
  254. "\t-i <address> BT address of interface to use.\n"
  255. "\t-a <address> BT address of remote.\n"
  256. "\t For example: -a 00:19:C1:5A:F1:3F. \n"
  257. "\t-b <script> Execute <script> when battery info changes.\n"
  258. "\t Arguments: <prev charge> <current charge>, both in percent.\n");
  259. printf("\t-r <rate> Key repeat rate. Generate <rate> repeats per second.\n"
  260. "\t-e <num> Wait <num> ms before repeating a key.\n"
  261. "\t-R <suffix> Auto-generate release events with appended <suffix>.\n"
  262. "\t-l Follow LIRC namespace for the key names.\n"
  263. "\t-E Make output available through a Linux event device.\n"
  264. "\t-u <username> Change UID to the UID of this user.\n"
  265. "\t-g <group> Change GID to the GID of this group.\n"
  266. "\t-f <filename> Write log to <filename>.\n"
  267. "\t-d Enable debug.\n"
  268. "\t-n Don't fork daemon to background.\n"
  269. "\t-h, --help Display help.\n"
  270. "\n");
  271. }
  272. void sig_hup(int _sig)
  273. {
  274. (void)_sig;
  275. /* BDREMOTE_DBG("Not handling HUP."); */
  276. }
  277. void sig_term(int _sig)
  278. {
  279. extern volatile sig_atomic_t __io_canceled;
  280. __io_canceled = 1;
  281. (void)_sig;
  282. }
  283. /*@}*/