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

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:        }
1.2.2.1 ! misho      79: 
        !            80:        schedSignalSelf(task);
1.2       misho      81:        taskExit(task, NULL);
                     82: }
                     83: 
                     84: static void *
                     85: execReset(sched_task_t *task)
                     86: {
                     87:        pid_t pid;
                     88:        const char *str;
                     89: 
                     90:        str = cfg_getAttribute(&cfg, "reset", "click");
                     91:        if (!str)
                     92:                taskExit(task, NULL);
                     93: 
                     94:        if ((pid = fork()) == -1)
                     95:                ESYSERR(0);
                     96:        else if (!pid) {
                     97:                execl(str, str, "click", NULL);
                     98:                ESYSERR(0);
                     99:                _exit(127);
                    100:        }
                    101: 
                    102:        flg ^= flg;
                    103:        taskExit(task, NULL);
                    104: }
                    105: 
                    106: static void *
                    107: execDefault(sched_task_t *task)
                    108: {
                    109:        pid_t pid;
                    110:        const char *str;
                    111: 
                    112:        str = cfg_getAttribute(&cfg, "reset", "default");
                    113:        if (!str)
                    114:                taskExit(task, NULL);
                    115: 
                    116:        if ((pid = fork()) == -1)
                    117:                ESYSERR(0);
                    118:        else if (!pid) {
                    119:                execl(str, str, "default", NULL);
                    120:                ESYSERR(0);
                    121:                _exit(127);
                    122:        }
                    123: 
                    124:        flg ^= flg;
                    125:        taskExit(task, NULL);
                    126: }
                    127: 
                    128: static void *
                    129: butReset(sched_task_t *task)
                    130: {
                    131:        struct timespec ts = { 1, 0 };
                    132:        struct gpio_req req;
                    133: 
                    134:        /* check reset button */
                    135:        req.gp_pin = resbut;
                    136:        if (ioctl(gpio, GPIOGET, &req) == -1) {
                    137:                ESYSERR(0);
                    138:                goto end;
                    139:        }
                    140:        /* switch on */
                    141:        if (flg != -1 && !req.gp_value)
                    142:                if (++flg == 1)
                    143:                        schedSuspend(TASK_ROOT(task), execReset, NULL, flg, NULL, 0);
                    144:        if (defact && flg >= defact) {
                    145:                schedCancelby(TASK_ROOT(task), taskSUSPEND, CRITERIA_CALL, execReset, NULL);
                    146:                schedEvent(TASK_ROOT(task), execDefault, NULL, flg, NULL, 0);
                    147:                flg = -1;
                    148:                goto end;
                    149:        }
                    150:        if (flg > 0 && req.gp_value)
                    151:                schedResumeby(TASK_ROOT(task), CRITERIA_ID, (void*) 1);
                    152: 
                    153:        /* toggle led pin */
                    154:        if (flg != -1 && led != -1) {
                    155:                req.gp_pin = led;
                    156:                if (ioctl(gpio, GPIOTOGGLE, &req) == -1)
                    157:                        ESYSERR(0);
                    158:        }
                    159: end:
                    160:        schedTimer(TASK_ROOT(task), TASK_FUNC(task), TASK_ARG(task), 
                    161:                        ts, TASK_DATA(task), TASK_DATLEN(task));
                    162:        taskExit(task, NULL);
                    163: }
                    164: 
                    165: 
                    166: int
                    167: main(int argc, char **argv)
                    168: {
                    169:        char ch;
                    170:        pid_t pid;
                    171:        struct timespec ts = { 1, 0 };
                    172: 
                    173:        while ((ch = getopt(argc, argv, "hc:d:")) != -1)
                    174:                switch (ch) {
                    175:                        case 'd':
                    176:                                strlcpy(szDevName, optarg, sizeof szDevName);
                    177:                                break;
                    178:                        case 'c':
                    179:                                strlcpy(szCfgName, optarg, sizeof szCfgName);
                    180:                                break;
                    181:                        case 'h':
                    182:                        default:
                    183:                                Usage();
                    184:                                return 1;
                    185:                }
                    186:        argc -= optind;
                    187:        argv += optind;
                    188: 
                    189:        switch ((pid = fork())) {
                    190:                case -1:
                    191:                        printf("Error:: failed fork() #%d - %s\n", errno, strerror(errno));
                    192:                        return 1;
                    193:                case 0:
                    194:                        setsid();
                    195:                        chdir("/");
                    196: 
                    197:                        gpio = open(_PATH_DEVNULL, O_RDWR);
                    198:                        if (gpio > 2) {
                    199:                                dup2(gpio, STDIN_FILENO);
                    200:                                dup2(gpio, STDOUT_FILENO);
                    201:                                dup2(gpio, STDERR_FILENO);
                    202:                                close(gpio);
                    203:                        }
                    204:                        break;
                    205:                default:
                    206:                        return 0;
                    207:        }
                    208: 
                    209:        openlog("butz", LOG_PID | LOG_CONS, LOG_DAEMON);
                    210:        gpio = open(szDevName, O_RDONLY);
                    211:        if (gpio == -1) {
                    212:                ESYSERR(0);
                    213:                return 1;
                    214:        }
                    215:        if (ioctl(gpio, GPIOMAXPIN, &maxpins) == -1) {
                    216:                ESYSERR(0);
                    217:                return 1;
                    218:        }
                    219: 
                    220:        if (cfgLoadConfig(szCfgName, &cfg)) {
                    221:                ELIBERR(cfg);
                    222:                close(gpio);
                    223:                return 1;
                    224:        }
                    225:        if (prepareGPIO()) {
                    226:                close(gpio);
                    227:                return 1;
                    228:        }
                    229:        root = schedBegin();
                    230:        if (!root) {
                    231:                ELIBERR(sched);
                    232:                close(gpio);
                    233:                return 1;
                    234:        }
                    235: 
                    236:        schedSignal(root, sigHandler, NULL, SIGHUP, NULL, 0);
                    237:        schedSignal(root, sigHandler, NULL, SIGTERM, NULL, 0);
                    238:        schedTimer(root, butReset, NULL, ts, NULL, 0);
                    239: 
                    240:        schedRun(root, &Kill);
                    241:        schedEnd(&root);
                    242:        cfgUnloadConfig(&cfg);
                    243:        close(gpio);
                    244:        closelog();
                    245:        return 0;
                    246: }

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