00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "beep.h"
00025
00026 #include <core/threading/thread.h>
00027 #include <utils/system/signal.h>
00028 #include <utils/system/argparser.h>
00029 #include <blackboard/remote.h>
00030 #include <interfaces/SwitchInterface.h>
00031 #include <utils/time/time.h>
00032
00033 #include <cstdio>
00034 #include <unistd.h>
00035 #include <cmath>
00036 #ifdef HAVE_LIBDAEMON
00037 # include <cerrno>
00038 # include <cstring>
00039 # include <libdaemon/dfork.h>
00040 # include <libdaemon/dlog.h>
00041 # include <libdaemon/dpid.h>
00042 # include <sys/stat.h>
00043 # include <sys/wait.h>
00044 #endif
00045
00046 using namespace std;
00047 using namespace fawkes;
00048
00049
00050
00051
00052
00053 class FawkesBeepDaemon
00054 : public Thread,
00055 public SignalHandler
00056 {
00057 public:
00058
00059 FawkesBeepDaemon()
00060 : Thread("FawkesBeepDaemon", Thread::OPMODE_CONTINUOUS)
00061 {
00062 __until = NULL;
00063 __bb = NULL;
00064 __switch_if = NULL;
00065 }
00066
00067 virtual void loop()
00068 {
00069 while (! (__bb && __bb->is_alive() && __switch_if->is_valid())) {
00070 if (__bb) {
00071 printf("Lost connection to blackboard\n");
00072 __bb->close(__switch_if);
00073 delete __bb;
00074 __bb = NULL;
00075 }
00076 try {
00077 printf("Trying to connect to remote BB...");
00078 __bb = new RemoteBlackBoard("localhost", 1910);
00079 __switch_if = __bb->open_for_writing<SwitchInterface>("Beep");
00080 printf("succeeded\n");
00081 } catch (Exception &e) {
00082 printf("failed\n");
00083 delete __bb;
00084 __bb = NULL;
00085 sleep(5);
00086 }
00087 }
00088
00089 if (__until) {
00090 Time now;
00091 if ((now - __until) >= 0) {
00092 __beep.beep_off();
00093 delete __until;
00094 __until = NULL;
00095 }
00096 }
00097
00098 while (! __switch_if->msgq_empty()) {
00099 if ( __switch_if->msgq_first_is<SwitchInterface::SetMessage>() ) {
00100 SwitchInterface::SetMessage *msg = __switch_if->msgq_first<SwitchInterface::SetMessage>();
00101 if (msg->value() > 0.0) {
00102 __beep.beep_on(msg->value());
00103 } else if (msg->is_enabled()) {
00104 __beep.beep_on();
00105 } else {
00106 __beep.beep_off();
00107 }
00108
00109 } else if ( __switch_if->msgq_first_is<SwitchInterface::EnableDurationMessage>() ) {
00110 SwitchInterface::EnableDurationMessage *msg =
00111 __switch_if->msgq_first<SwitchInterface::EnableDurationMessage>();
00112 float duration = fabs(msg->duration());
00113 float value = fabs(msg->value());
00114
00115 delete __until;
00116 __until = new Time();
00117 *__until += duration;
00118 __beep.beep_on(value);
00119 } else if (__switch_if->msgq_first_is<SwitchInterface::EnableSwitchMessage>() ) {
00120 __beep.beep_on();
00121 } else if (__switch_if->msgq_first_is<SwitchInterface::DisableSwitchMessage>() ) {
00122 __beep.beep_off();
00123 }
00124
00125 __switch_if->msgq_pop();
00126 }
00127
00128 usleep(10000);
00129 }
00130
00131
00132
00133
00134
00135 void handle_signal(int signum)
00136 {
00137 this->cancel();
00138 }
00139
00140 private:
00141 BeepController __beep;
00142 BlackBoard *__bb;
00143 SwitchInterface *__switch_if;
00144
00145 Time *__until;
00146 };
00147
00148
00149 void
00150 usage(const char *progname)
00151 {
00152 }
00153
00154
00155 #ifdef HAVE_LIBDAEMON
00156 void
00157 daemonize_cleanup()
00158 {
00159 daemon_retval_send(-1);
00160 daemon_retval_done();
00161 daemon_pid_file_remove();
00162 }
00163
00164 pid_t
00165 daemonize(int argc, char **argv)
00166 {
00167 pid_t pid;
00168 mode_t old_umask = umask(0);
00169
00170
00171 daemon_retval_init();
00172
00173
00174 if ((pid = daemon_fork()) < 0) {
00175 return -1;
00176
00177 } else if (pid) {
00178 int ret;
00179
00180
00181 if ((ret = daemon_retval_wait(20)) < 0) {
00182 daemon_log(LOG_ERR, "Could not recieve return value from daemon process.");
00183 return -1;
00184 }
00185
00186 if ( ret != 0 ) {
00187 daemon_log(LOG_ERR, "*** Daemon startup failed, see syslog for details. ***");
00188 switch (ret) {
00189 case 1:
00190 daemon_log(LOG_ERR, "Daemon failed to close file descriptors");
00191 break;
00192 case 2:
00193 daemon_log(LOG_ERR, "Daemon failed to create PID file");
00194 break;
00195 }
00196 return -1;
00197 } else {
00198 return pid;
00199 }
00200
00201 } else {
00202 #ifdef DAEMON_CLOSE_ALL_AVAILABLE
00203 if (daemon_close_all(-1) < 0) {
00204 daemon_log(LOG_ERR, "Failed to close all file descriptors: %s", strerror(errno));
00205
00206 daemon_retval_send(1);
00207 return -1;
00208 }
00209 #endif
00210
00211
00212 if (daemon_pid_file_create() < 0) {
00213 printf("Could not create PID file (%s).", strerror(errno));
00214 daemon_log(LOG_ERR, "Could not create PID file (%s).", strerror(errno));
00215
00216
00217 daemon_retval_send(2);
00218 return -1;
00219 }
00220
00221
00222 daemon_retval_send(0);
00223
00224 daemon_log(LOG_INFO, "Sucessfully started");
00225
00226 umask(old_umask);
00227 return 0;
00228 }
00229 }
00230
00231
00232
00233 const char *fawkes_pid_file;
00234
00235
00236
00237
00238 const char *
00239 fawkes_daemon_pid_file_proc()
00240 {
00241 return fawkes_pid_file;
00242 }
00243 #endif // HAVE_LIBDAEMON
00244
00245
00246
00247
00248
00249 int
00250 main(int argc, char **argv)
00251 {
00252 ArgumentParser *argp = new ArgumentParser(argc, argv, "hD::ks");
00253
00254
00255 const char *user = NULL;
00256 const char *group = NULL;
00257 if (argp->has_arg("u")) {
00258 user = argp->arg("u");
00259 }
00260 if (argp->has_arg("g")) {
00261 group = argp->arg("g");
00262 }
00263
00264 #ifdef HAVE_LIBDAEMON
00265 pid_t pid;
00266 int ret;
00267
00268 if ( argp->has_arg("D") ) {
00269
00270 daemon_pid_file_ident = daemon_log_ident = daemon_ident_from_argv0(argv[0]);
00271 if ( argp->arg("D") != NULL ) {
00272 fawkes_pid_file = argp->arg("D");
00273 daemon_pid_file_proc = fawkes_daemon_pid_file_proc;
00274 }
00275
00276
00277 if ( argp->has_arg("k") ) {
00278
00279 if ((pid = daemon_pid_file_is_running()) < 0) {
00280 daemon_log(LOG_ERR, "Fawkes daemon not running.");
00281 return 1;
00282 }
00283
00284
00285 if ((ret = daemon_pid_file_kill_wait(SIGINT, 5)) < 0) {
00286 daemon_log(LOG_WARNING, "Failed to kill daemon");
00287 }
00288 return (ret < 0) ? 1 : 0;
00289 }
00290
00291 if ( argp->has_arg("s") ) {
00292
00293 return (daemon_pid_file_is_running() < 0);
00294 }
00295
00296
00297 if ((pid = daemon_pid_file_is_running()) >= 0) {
00298 daemon_log(LOG_ERR, "Daemon already running on (PID %u)", pid);
00299 return 201;
00300 }
00301
00302 pid = daemonize(argc, argv);
00303 if ( pid < 0 ) {
00304 daemonize_cleanup();
00305 return 201;
00306 } else if (pid) {
00307
00308 return 0;
00309 }
00310 }
00311 #else
00312 if ( argp->has_arg("D") ) {
00313 printf("Daemonizing support is not available.\n"
00314 "(libdaemon[-devel] was not available at compile time)\n");
00315 return 202;
00316 }
00317 #endif
00318
00319 Thread::init_main();
00320
00321 if ( argp->has_arg("h") ) {
00322 usage(argv[0]);
00323 delete argp;
00324 return 0;
00325 }
00326
00327 FawkesBeepDaemon beepd;
00328 SignalManager::register_handler(SIGINT, &beepd);
00329 SignalManager::register_handler(SIGTERM, &beepd);
00330
00331 beepd.start();
00332 beepd.join();
00333
00334 Thread::destroy_main();
00335
00336 #ifdef HAVE_LIBDAEMON
00337 if ( argp->has_arg("D") ) {
00338 daemonize_cleanup();
00339 }
00340 #endif
00341
00342 delete argp;
00343 return 0;
00344 }