Diff for /embedtools/src/butz.c between versions 1.1 and 1.2

version 1.1, 2014/02/07 23:37:41 version 1.2, 2014/02/08 20:57:16
Line 0 Line 1
   #include "global.h"
   
   
   cfg_root_t cfg;
   sched_root_task_t *root;
   int Kill, gpio, flg, maxpins, defact, resbut, led = -1;
   extern char compiled[], compiledby[], compilehost[];
   char szCfgName[PATH_MAX] = BUTZ_CFG;
   char szDevName[PATH_MAX] = _PATH_DEVGPIOC"0";
   
   static void
   Usage()
   {
           printf( " -= Butz =- Service for board buttons management\n"
                   "=== %s === %s@%s ===\n\n"
                   "  Syntax: butz [options] [set_value]\n"
                   "\n"
                   "\t-c <cfgfile>\tConfig file [default: /etc/butz.conf]\n"
                   "\t-d <devname>\tGPIO control device [default: /dev/gpioc]\n"
                   "\n", compiled, compiledby, compilehost);
   }
   
   static int
   prepareGPIO()
   {
           const char *str;
           struct gpio_pin pin;
           struct gpio_req req;
   
           str = cfg_getAttribute(&cfg, "reset", "default_after");
           if (str)
                   defact = strtol(str, NULL, 0);
           str = cfg_getAttribute(&cfg, "reset", "gpio_led_ping");
           if (str)
                   led = strtol(str, NULL, 0);
           str = cfg_getAttribute(&cfg, "reset", "gpio_pin");
           if (!str || maxpins < (resbut = strtol(str, NULL, 0))) {
                   EERROR(EINVAL, "Reset button pin not defined or wrong number!");
                   return -1;
           }
   
           /* switch button pin into input state */
           pin.gp_pin = resbut;
           pin.gp_flags = GPIO_PIN_INPUT;
           if (ioctl(gpio, GPIOSETCONFIG, &pin) == -1)
                   return -1;
           /* toggle led pin */
           if (led != -1) {
                   req.gp_pin = led;
                   if (ioctl(gpio, GPIOTOGGLE, &req) == -1) {
                           ESYSERR(0);
                           return -1;
                   }
           }
   
           return 0;
   }
   
   static void *
   sigHandler(sched_task_t *task)
   {
           switch (TASK_VAL(task)) {
                   case SIGHUP:
                           cfgUnloadConfig(&cfg);
                           if (cfgLoadConfig(szCfgName, &cfg)) {
                                   ELIBERR(cfg);
                                   Kill++;
                           }
                           if (prepareGPIO())
                                   Kill++;
                           break;
                   case SIGTERM:
                           Kill++;
                           break;
                   default:
                           EERROR(EINVAL, "Undefined signal %lu!", TASK_VAL(task));
                           break;
           }
           taskExit(task, NULL);
   }
   
   static void *
   execReset(sched_task_t *task)
   {
           pid_t pid;
           const char *str;
   
           str = cfg_getAttribute(&cfg, "reset", "click");
           if (!str)
                   taskExit(task, NULL);
   
           if ((pid = fork()) == -1)
                   ESYSERR(0);
           else if (!pid) {
                   execl(str, str, "click", NULL);
                   ESYSERR(0);
                   _exit(127);
           }
   
           flg ^= flg;
           taskExit(task, NULL);
   }
   
   static void *
   execDefault(sched_task_t *task)
   {
           pid_t pid;
           const char *str;
   
           str = cfg_getAttribute(&cfg, "reset", "default");
           if (!str)
                   taskExit(task, NULL);
   
           if ((pid = fork()) == -1)
                   ESYSERR(0);
           else if (!pid) {
                   execl(str, str, "default", NULL);
                   ESYSERR(0);
                   _exit(127);
           }
   
           flg ^= flg;
           taskExit(task, NULL);
   }
   
   static void *
   butReset(sched_task_t *task)
   {
           struct timespec ts = { 1, 0 };
           struct gpio_req req;
   
           /* check reset button */
           req.gp_pin = resbut;
           if (ioctl(gpio, GPIOGET, &req) == -1) {
                   ESYSERR(0);
                   goto end;
           }
           /* switch on */
           if (flg != -1 && !req.gp_value)
                   if (++flg == 1)
                           schedSuspend(TASK_ROOT(task), execReset, NULL, flg, NULL, 0);
           if (defact && flg >= defact) {
                   schedCancelby(TASK_ROOT(task), taskSUSPEND, CRITERIA_CALL, execReset, NULL);
                   schedEvent(TASK_ROOT(task), execDefault, NULL, flg, NULL, 0);
                   flg = -1;
                   goto end;
           }
           if (flg > 0 && req.gp_value)
                   schedResumeby(TASK_ROOT(task), CRITERIA_ID, (void*) 1);
   
           /* toggle led pin */
           if (flg != -1 && led != -1) {
                   req.gp_pin = led;
                   if (ioctl(gpio, GPIOTOGGLE, &req) == -1)
                           ESYSERR(0);
           }
   end:
           schedTimer(TASK_ROOT(task), TASK_FUNC(task), TASK_ARG(task), 
                           ts, TASK_DATA(task), TASK_DATLEN(task));
           taskExit(task, NULL);
   }
   
   
   int
   main(int argc, char **argv)
   {
           char ch;
           pid_t pid;
           struct timespec ts = { 1, 0 };
   
           while ((ch = getopt(argc, argv, "hc:d:")) != -1)
                   switch (ch) {
                           case 'd':
                                   strlcpy(szDevName, optarg, sizeof szDevName);
                                   break;
                           case 'c':
                                   strlcpy(szCfgName, optarg, sizeof szCfgName);
                                   break;
                           case 'h':
                           default:
                                   Usage();
                                   return 1;
                   }
           argc -= optind;
           argv += optind;
   
           switch ((pid = fork())) {
                   case -1:
                           printf("Error:: failed fork() #%d - %s\n", errno, strerror(errno));
                           return 1;
                   case 0:
                           setsid();
                           chdir("/");
   
                           gpio = open(_PATH_DEVNULL, O_RDWR);
                           if (gpio > 2) {
                                   dup2(gpio, STDIN_FILENO);
                                   dup2(gpio, STDOUT_FILENO);
                                   dup2(gpio, STDERR_FILENO);
                                   close(gpio);
                           }
                           break;
                   default:
                           return 0;
           }
   
           openlog("butz", LOG_PID | LOG_CONS, LOG_DAEMON);
           gpio = open(szDevName, O_RDONLY);
           if (gpio == -1) {
                   ESYSERR(0);
                   return 1;
           }
           if (ioctl(gpio, GPIOMAXPIN, &maxpins) == -1) {
                   ESYSERR(0);
                   return 1;
           }
   
           if (cfgLoadConfig(szCfgName, &cfg)) {
                   ELIBERR(cfg);
                   close(gpio);
                   return 1;
           }
           if (prepareGPIO()) {
                   close(gpio);
                   return 1;
           }
           root = schedBegin();
           if (!root) {
                   ELIBERR(sched);
                   close(gpio);
                   return 1;
           }
   
           schedSignal(root, sigHandler, NULL, SIGHUP, NULL, 0);
           schedSignal(root, sigHandler, NULL, SIGTERM, NULL, 0);
           schedTimer(root, butReset, NULL, ts, NULL, 0);
   
           schedRun(root, &Kill);
           schedEnd(&root);
           cfgUnloadConfig(&cfg);
           close(gpio);
           closelog();
           return 0;
   }

Removed from v.1.1  
changed lines
  Added in v.1.2


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>