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>