Annotation of embedtools/src/butz.c, revision 1.1.2.3

1.1.2.1   misho       1: #include "global.h"
                      2: 
                      3: 
                      4: cfg_root_t cfg;
                      5: sched_root_task_t *root;
1.1.2.3 ! misho       6: int Kill, gpio, maxpins, defact, resbut, led = -1;
1.1.2.1   misho       7: extern char compiled[], compiledby[], compilehost[];
                      8: char szCfgName[PATH_MAX] = BUTZ_CFG;
1.1.2.2   misho       9: char szDevName[PATH_MAX] = _PATH_DEVGPIOC"0";
1.1.2.1   misho      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"
1.1.2.2   misho      19:                "\t-d <devname>\tGPIO control device [default: /dev/gpioc]\n"
1.1.2.1   misho      20:                "\n", compiled, compiledby, compilehost);
                     21: }
                     22: 
1.1.2.3 ! misho      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: 
1.1.2.1   misho      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:                        }
1.1.2.3 ! misho      69:                        if (prepareGPIO())
        !            70:                                Kill++;
1.1.2.1   misho      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: 
1.1.2.2   misho      82: static void *
1.1.2.3 ! misho      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:        taskExit(task, NULL);
        !           101: }
        !           102: 
        !           103: static void *
        !           104: execDefault(sched_task_t *task)
        !           105: {
        !           106:        pid_t pid;
        !           107:        const char *str;
        !           108: 
        !           109:        str = cfg_getAttribute(&cfg, "reset", "default");
        !           110:        if (!str)
        !           111:                taskExit(task, NULL);
        !           112: 
        !           113:        if ((pid = fork()) == -1)
        !           114:                ESYSERR(0);
        !           115:        else if (!pid) {
        !           116:                execl(str, str, "default", NULL);
        !           117:                ESYSERR(0);
        !           118:                _exit(127);
        !           119:        }
        !           120: 
        !           121:        taskExit(task, NULL);
        !           122: }
        !           123: 
        !           124: static void *
1.1.2.2   misho     125: butReset(sched_task_t *task)
                    126: {
                    127:        struct timespec ts = { 1, 0 };
                    128:        struct gpio_req req;
1.1.2.3 ! misho     129:        static int flg = 0;
1.1.2.2   misho     130: 
1.1.2.3 ! misho     131:        /* toggle led pin */
        !           132:        if (led != -1) {
        !           133:                req.gp_pin = led;
        !           134:                if (ioctl(gpio, GPIOTOGGLE, &req) == -1)
        !           135:                        ESYSERR(0);
        !           136:        }
        !           137:        /* check reset button */
        !           138:        req.gp_pin = resbut;
        !           139:        if (ioctl(gpio, GPIOGET, &req) == -1) {
        !           140:                ESYSERR(0);
1.1.2.2   misho     141:                goto end;
                    142:        }
1.1.2.3 ! misho     143:        /* switch on */
        !           144:        if (!req.gp_value)
        !           145:                if (++flg == 1)
        !           146:                        schedSuspend(TASK_ROOT(task), execReset, NULL, flg, NULL, 0);
        !           147:        if (defact && flg >= defact) {
        !           148:                schedCancelby(TASK_ROOT(task), taskSUSPEND, CRITERIA_CALL, execReset, NULL);
        !           149:                schedEvent(TASK_ROOT(task), execDefault, NULL, flg, NULL, 0);
1.1.2.2   misho     150:                goto end;
                    151:        }
1.1.2.3 ! misho     152:        if (flg && req.gp_value)
        !           153:                schedResumeby(TASK_ROOT(task), CRITERIA_ID, (void*) 1);
1.1.2.2   misho     154: end:
                    155:        schedTimer(TASK_ROOT(task), TASK_FUNC(task), TASK_ARG(task), 
                    156:                        ts, TASK_DATA(task), TASK_DATLEN(task));
                    157:        taskExit(task, NULL);
                    158: }
                    159: 
1.1.2.1   misho     160: 
                    161: int
                    162: main(int argc, char **argv)
                    163: {
                    164:        char ch;
1.1.2.2   misho     165:        int gpio;
                    166:        struct timespec ts = { 1, 0 };
1.1.2.1   misho     167: 
1.1.2.3 ! misho     168:        while ((ch = getopt(argc, argv, "hc:d:")) != -1)
1.1.2.1   misho     169:                switch (ch) {
1.1.2.2   misho     170:                        case 'd':
                    171:                                strlcpy(szDevName, optarg, sizeof szDevName);
                    172:                                break;
1.1.2.1   misho     173:                        case 'c':
                    174:                                strlcpy(szCfgName, optarg, sizeof szCfgName);
                    175:                                break;
                    176:                        case 'h':
                    177:                        default:
                    178:                                Usage();
                    179:                                return 1;
                    180:                }
                    181:        argc -= optind;
                    182:        argv += optind;
                    183: 
                    184:        openlog("butz", LOG_PID | LOG_CONS, LOG_DAEMON);
1.1.2.2   misho     185:        gpio = open(szDevName, O_RDONLY);
                    186:        if (gpio == -1) {
                    187:                printf("Error:: Can't open /dev/gpioc #%d - %s\n", 
                    188:                                errno, strerror(errno));
                    189:                return 1;
                    190:        }
                    191:        if (ioctl(gpio, GPIOMAXPIN, &maxpins) == -1) {
                    192:                printf("Error:: Can't get max gpio pins #%d - %s\n", 
                    193:                                errno, strerror(errno));
                    194:                return 1;
                    195:        }
                    196: 
1.1.2.1   misho     197:        if (cfgLoadConfig(szCfgName, &cfg)) {
                    198:                ELIBERR(cfg);
1.1.2.2   misho     199:                close(gpio);
1.1.2.1   misho     200:                return 1;
                    201:        }
1.1.2.3 ! misho     202:        if (prepareGPIO()) {
        !           203:                close(gpio);
        !           204:                return 1;
        !           205:        }
1.1.2.1   misho     206:        root = schedBegin();
                    207:        if (!root) {
                    208:                ELIBERR(sched);
1.1.2.2   misho     209:                close(gpio);
1.1.2.1   misho     210:                return 1;
                    211:        }
                    212: 
                    213:        schedSignal(root, sigHandler, NULL, SIGHUP, NULL, 0);
                    214:        schedSignal(root, sigHandler, NULL, SIGTERM, NULL, 0);
1.1.2.2   misho     215:        schedTimer(root, butReset, (void*) gpio, ts, NULL, 0);
1.1.2.1   misho     216: 
1.1.2.2   misho     217:        schedRun(root, &Kill);
1.1.2.1   misho     218:        schedEnd(&root);
                    219:        cfgUnloadConfig(&cfg);
1.1.2.2   misho     220:        close(gpio);
1.1.2.1   misho     221:        closelog();
                    222:        return 0;
                    223: }

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