Annotation of embedtools/src/butz.c, revision 1.2
1.2 ! misho 1: #include "global.h"
! 2:
! 3:
! 4: cfg_root_t cfg;
! 5: sched_root_task_t *root;
! 6: int Kill, gpio, flg, maxpins, defact, resbut, led = -1;
! 7: extern char compiled[], compiledby[], compilehost[];
! 8: char szCfgName[PATH_MAX] = BUTZ_CFG;
! 9: char szDevName[PATH_MAX] = _PATH_DEVGPIOC"0";
! 10:
! 11: static void
! 12: Usage()
! 13: {
! 14: printf( " -= Butz =- Service for board buttons management\n"
! 15: "=== %s === %s@%s ===\n\n"
! 16: " Syntax: butz [options] [set_value]\n"
! 17: "\n"
! 18: "\t-c <cfgfile>\tConfig file [default: /etc/butz.conf]\n"
! 19: "\t-d <devname>\tGPIO control device [default: /dev/gpioc]\n"
! 20: "\n", compiled, compiledby, compilehost);
! 21: }
! 22:
! 23: static int
! 24: prepareGPIO()
! 25: {
! 26: const char *str;
! 27: struct gpio_pin pin;
! 28: struct gpio_req req;
! 29:
! 30: str = cfg_getAttribute(&cfg, "reset", "default_after");
! 31: if (str)
! 32: defact = strtol(str, NULL, 0);
! 33: str = cfg_getAttribute(&cfg, "reset", "gpio_led_ping");
! 34: if (str)
! 35: led = strtol(str, NULL, 0);
! 36: str = cfg_getAttribute(&cfg, "reset", "gpio_pin");
! 37: if (!str || maxpins < (resbut = strtol(str, NULL, 0))) {
! 38: EERROR(EINVAL, "Reset button pin not defined or wrong number!");
! 39: return -1;
! 40: }
! 41:
! 42: /* switch button pin into input state */
! 43: pin.gp_pin = resbut;
! 44: pin.gp_flags = GPIO_PIN_INPUT;
! 45: if (ioctl(gpio, GPIOSETCONFIG, &pin) == -1)
! 46: return -1;
! 47: /* toggle led pin */
! 48: if (led != -1) {
! 49: req.gp_pin = led;
! 50: if (ioctl(gpio, GPIOTOGGLE, &req) == -1) {
! 51: ESYSERR(0);
! 52: return -1;
! 53: }
! 54: }
! 55:
! 56: return 0;
! 57: }
! 58:
! 59: static void *
! 60: sigHandler(sched_task_t *task)
! 61: {
! 62: switch (TASK_VAL(task)) {
! 63: case SIGHUP:
! 64: cfgUnloadConfig(&cfg);
! 65: if (cfgLoadConfig(szCfgName, &cfg)) {
! 66: ELIBERR(cfg);
! 67: Kill++;
! 68: }
! 69: if (prepareGPIO())
! 70: Kill++;
! 71: break;
! 72: case SIGTERM:
! 73: Kill++;
! 74: break;
! 75: default:
! 76: EERROR(EINVAL, "Undefined signal %lu!", TASK_VAL(task));
! 77: break;
! 78: }
! 79: taskExit(task, NULL);
! 80: }
! 81:
! 82: static void *
! 83: execReset(sched_task_t *task)
! 84: {
! 85: pid_t pid;
! 86: const char *str;
! 87:
! 88: str = cfg_getAttribute(&cfg, "reset", "click");
! 89: if (!str)
! 90: taskExit(task, NULL);
! 91:
! 92: if ((pid = fork()) == -1)
! 93: ESYSERR(0);
! 94: else if (!pid) {
! 95: execl(str, str, "click", NULL);
! 96: ESYSERR(0);
! 97: _exit(127);
! 98: }
! 99:
! 100: flg ^= flg;
! 101: taskExit(task, NULL);
! 102: }
! 103:
! 104: static void *
! 105: execDefault(sched_task_t *task)
! 106: {
! 107: pid_t pid;
! 108: const char *str;
! 109:
! 110: str = cfg_getAttribute(&cfg, "reset", "default");
! 111: if (!str)
! 112: taskExit(task, NULL);
! 113:
! 114: if ((pid = fork()) == -1)
! 115: ESYSERR(0);
! 116: else if (!pid) {
! 117: execl(str, str, "default", NULL);
! 118: ESYSERR(0);
! 119: _exit(127);
! 120: }
! 121:
! 122: flg ^= flg;
! 123: taskExit(task, NULL);
! 124: }
! 125:
! 126: static void *
! 127: butReset(sched_task_t *task)
! 128: {
! 129: struct timespec ts = { 1, 0 };
! 130: struct gpio_req req;
! 131:
! 132: /* check reset button */
! 133: req.gp_pin = resbut;
! 134: if (ioctl(gpio, GPIOGET, &req) == -1) {
! 135: ESYSERR(0);
! 136: goto end;
! 137: }
! 138: /* switch on */
! 139: if (flg != -1 && !req.gp_value)
! 140: if (++flg == 1)
! 141: schedSuspend(TASK_ROOT(task), execReset, NULL, flg, NULL, 0);
! 142: if (defact && flg >= defact) {
! 143: schedCancelby(TASK_ROOT(task), taskSUSPEND, CRITERIA_CALL, execReset, NULL);
! 144: schedEvent(TASK_ROOT(task), execDefault, NULL, flg, NULL, 0);
! 145: flg = -1;
! 146: goto end;
! 147: }
! 148: if (flg > 0 && req.gp_value)
! 149: schedResumeby(TASK_ROOT(task), CRITERIA_ID, (void*) 1);
! 150:
! 151: /* toggle led pin */
! 152: if (flg != -1 && led != -1) {
! 153: req.gp_pin = led;
! 154: if (ioctl(gpio, GPIOTOGGLE, &req) == -1)
! 155: ESYSERR(0);
! 156: }
! 157: end:
! 158: schedTimer(TASK_ROOT(task), TASK_FUNC(task), TASK_ARG(task),
! 159: ts, TASK_DATA(task), TASK_DATLEN(task));
! 160: taskExit(task, NULL);
! 161: }
! 162:
! 163:
! 164: int
! 165: main(int argc, char **argv)
! 166: {
! 167: char ch;
! 168: pid_t pid;
! 169: struct timespec ts = { 1, 0 };
! 170:
! 171: while ((ch = getopt(argc, argv, "hc:d:")) != -1)
! 172: switch (ch) {
! 173: case 'd':
! 174: strlcpy(szDevName, optarg, sizeof szDevName);
! 175: break;
! 176: case 'c':
! 177: strlcpy(szCfgName, optarg, sizeof szCfgName);
! 178: break;
! 179: case 'h':
! 180: default:
! 181: Usage();
! 182: return 1;
! 183: }
! 184: argc -= optind;
! 185: argv += optind;
! 186:
! 187: switch ((pid = fork())) {
! 188: case -1:
! 189: printf("Error:: failed fork() #%d - %s\n", errno, strerror(errno));
! 190: return 1;
! 191: case 0:
! 192: setsid();
! 193: chdir("/");
! 194:
! 195: gpio = open(_PATH_DEVNULL, O_RDWR);
! 196: if (gpio > 2) {
! 197: dup2(gpio, STDIN_FILENO);
! 198: dup2(gpio, STDOUT_FILENO);
! 199: dup2(gpio, STDERR_FILENO);
! 200: close(gpio);
! 201: }
! 202: break;
! 203: default:
! 204: return 0;
! 205: }
! 206:
! 207: openlog("butz", LOG_PID | LOG_CONS, LOG_DAEMON);
! 208: gpio = open(szDevName, O_RDONLY);
! 209: if (gpio == -1) {
! 210: ESYSERR(0);
! 211: return 1;
! 212: }
! 213: if (ioctl(gpio, GPIOMAXPIN, &maxpins) == -1) {
! 214: ESYSERR(0);
! 215: return 1;
! 216: }
! 217:
! 218: if (cfgLoadConfig(szCfgName, &cfg)) {
! 219: ELIBERR(cfg);
! 220: close(gpio);
! 221: return 1;
! 222: }
! 223: if (prepareGPIO()) {
! 224: close(gpio);
! 225: return 1;
! 226: }
! 227: root = schedBegin();
! 228: if (!root) {
! 229: ELIBERR(sched);
! 230: close(gpio);
! 231: return 1;
! 232: }
! 233:
! 234: schedSignal(root, sigHandler, NULL, SIGHUP, NULL, 0);
! 235: schedSignal(root, sigHandler, NULL, SIGTERM, NULL, 0);
! 236: schedTimer(root, butReset, NULL, ts, NULL, 0);
! 237:
! 238: schedRun(root, &Kill);
! 239: schedEnd(&root);
! 240: cfgUnloadConfig(&cfg);
! 241: close(gpio);
! 242: closelog();
! 243: return 0;
! 244: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>