Annotation of embedaddon/strongswan/src/libcharon/plugins/led/led_listener.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2010 Martin Willi
                      3:  * Copyright (C) 2010 revosec AG
                      4:  *
                      5:  * This program is free software; you can redistribute it and/or modify it
                      6:  * under the terms of the GNU General Public License as published by the
                      7:  * Free Software Foundation; either version 2 of the License, or (at your
                      8:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
                      9:  *
                     10:  * This program is distributed in the hope that it will be useful, but
                     11:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     12:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                     13:  * for more details.
                     14:  */
                     15: 
                     16: #include "led_listener.h"
                     17: 
                     18: #include <errno.h>
                     19: 
                     20: #include <daemon.h>
                     21: #include <threading/mutex.h>
                     22: #include <processing/jobs/callback_job.h>
                     23: 
                     24: typedef struct private_led_listener_t private_led_listener_t;
                     25: 
                     26: /**
                     27:  * Private data of an led_listener_t object.
                     28:  */
                     29: struct private_led_listener_t {
                     30: 
                     31:        /**
                     32:         * Public led_listener_t interface.
                     33:         */
                     34:        led_listener_t public;
                     35: 
                     36:        /**
                     37:         * Mutex
                     38:         */
                     39:        mutex_t *mutex;
                     40: 
                     41:        /**
                     42:         * Number of established IKE_SAs
                     43:         */
                     44:        int count;
                     45: 
                     46:        /**
                     47:         * LED blink on/off time, in ms
                     48:         */
                     49:        int blink_time;
                     50: 
                     51:        /**
                     52:         * Activity LED fd, if any
                     53:         */
                     54:        FILE *activity;
                     55: 
                     56:        /**
                     57:         * Activity LED maximum brightness
                     58:         */
                     59:        int activity_max;
                     60: };
                     61: 
                     62: /**
                     63:  * Open a LED brightness control file, get max brightness
                     64:  */
                     65: static FILE *open_led(char *name, int *max_brightness)
                     66: {
                     67:        char path[PATH_MAX];
                     68:        FILE *f;
                     69: 
                     70:        if (!name)
                     71:        {
                     72:                return NULL;
                     73:        }
                     74: 
                     75:        *max_brightness = 1;
                     76:        snprintf(path, sizeof(path), "/sys/class/leds/%s/max_brightness", name);
                     77:        f = fopen(path, "r");
                     78:        if (f)
                     79:        {
                     80:                if (fscanf(f, "%d\n", max_brightness) != 1)
                     81:                {
                     82:                        DBG1(DBG_CFG, "reading max brightness for '%s' failed: %s, using 1",
                     83:                                 name, strerror(errno));
                     84:                }
                     85:                fclose(f);
                     86:        }
                     87:        else
                     88:        {
                     89:                DBG1(DBG_CFG, "reading max_brightness for '%s' failed: %s, using 1",
                     90:                         name, strerror(errno));
                     91:        }
                     92: 
                     93:        snprintf(path, sizeof(path), "/sys/class/leds/%s/brightness", name);
                     94:        f = fopen(path, "w");
                     95:        if (!f)
                     96:        {
                     97:                DBG1(DBG_CFG, "opening LED file '%s' failed: %s", path, strerror(errno));
                     98:        }
                     99:        return f;
                    100: }
                    101: 
                    102: /**
                    103:  * Set a LED to a given brightness
                    104:  */
                    105: static void set_led(FILE *led, int brightness)
                    106: {
                    107:        if (led)
                    108:        {
                    109:                if (fprintf(led, "%d\n", brightness) <= 0 ||
                    110:                        fflush(led) != 0)
                    111:                {
                    112:                        DBG1(DBG_CFG, "setting LED brightness failed: %s", strerror(errno));
                    113:                }
                    114:        }
                    115: }
                    116: 
                    117: /**
                    118:  * Plugin unloaded?
                    119:  */
                    120: static bool plugin_gone = FALSE;
                    121: 
                    122: /**
                    123:  * Reset activity LED after timeout
                    124:  */
                    125: static job_requeue_t reset_activity_led(private_led_listener_t *this)
                    126: {
                    127:        if (!plugin_gone)
                    128:        {       /* TODO: fix race */
                    129:                this->mutex->lock(this->mutex);
                    130:                if (this->count)
                    131:                {
                    132:                        set_led(this->activity, this->activity_max);
                    133:                }
                    134:                else
                    135:                {
                    136:                        set_led(this->activity, 0);
                    137:                }
                    138:                this->mutex->unlock(this->mutex);
                    139:        }
                    140:        return JOB_REQUEUE_NONE;
                    141: }
                    142: 
                    143: /**
                    144:  * Blink the activity LED
                    145:  */
                    146: static void blink_activity(private_led_listener_t *this)
                    147: {
                    148:        if (this->activity)
                    149:        {
                    150:                this->mutex->lock(this->mutex);
                    151:                if (this->count)
                    152:                {
                    153:                        set_led(this->activity, 0);
                    154:                }
                    155:                else
                    156:                {
                    157:                        set_led(this->activity, this->activity_max);
                    158:                }
                    159:                lib->scheduler->schedule_job_ms(lib->scheduler, (job_t*)
                    160:                        callback_job_create_with_prio((callback_job_cb_t)reset_activity_led,
                    161:                                                this, NULL, NULL, JOB_PRIO_CRITICAL), this->blink_time);
                    162:                this->mutex->unlock(this->mutex);
                    163:        }
                    164: }
                    165: 
                    166: METHOD(listener_t, ike_state_change, bool,
                    167:        private_led_listener_t *this, ike_sa_t *ike_sa, ike_sa_state_t state)
                    168: {
                    169:        this->mutex->lock(this->mutex);
                    170:        if (state == IKE_ESTABLISHED && ike_sa->get_state(ike_sa) != IKE_ESTABLISHED)
                    171:        {
                    172:                this->count++;
                    173:                if (this->count == 1)
                    174:                {
                    175:                        set_led(this->activity, this->activity_max);
                    176:                }
                    177:        }
                    178:        if (ike_sa->get_state(ike_sa) == IKE_ESTABLISHED && state != IKE_ESTABLISHED)
                    179:        {
                    180:                this->count--;
                    181:                if (this->count == 0)
                    182:                {
                    183:                        set_led(this->activity, 0);
                    184:                }
                    185:        }
                    186:        this->mutex->unlock(this->mutex);
                    187:        return TRUE;
                    188: }
                    189: 
                    190: METHOD(listener_t, message_hook, bool,
                    191:        private_led_listener_t *this, ike_sa_t *ike_sa,
                    192:        message_t *message, bool incoming, bool plain)
                    193: {
                    194:        if (plain && (incoming || message->get_request(message)))
                    195:        {
                    196:                blink_activity(this);
                    197:        }
                    198:        return TRUE;
                    199: }
                    200: 
                    201: METHOD(led_listener_t, destroy, void,
                    202:        private_led_listener_t *this)
                    203: {
                    204:        this->mutex->lock(this->mutex);
                    205:        set_led(this->activity, 0);
                    206:        plugin_gone = TRUE;
                    207:        this->mutex->unlock(this->mutex);
                    208:        if (this->activity)
                    209:        {
                    210:                fclose(this->activity);
                    211:        }
                    212:        this->mutex->destroy(this->mutex);
                    213:        free(this);
                    214: }
                    215: 
                    216: /**
                    217:  * See header
                    218:  */
                    219: led_listener_t *led_listener_create()
                    220: {
                    221:        private_led_listener_t *this;
                    222: 
                    223:        INIT(this,
                    224:                .public = {
                    225:                        .listener = {
                    226:                                .ike_state_change = _ike_state_change,
                    227:                                .message = _message_hook,
                    228:                        },
                    229:                        .destroy = _destroy,
                    230:                },
                    231:                .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
                    232:                .blink_time = lib->settings->get_int(lib->settings,
                    233:                                                                "%s.plugins.led.blink_time", 50, lib->ns),
                    234:        );
                    235: 
                    236:        this->activity = open_led(lib->settings->get_str(lib->settings,
                    237:                                                                "%s.plugins.led.activity_led", NULL, lib->ns),
                    238:                                                                &this->activity_max);
                    239:        set_led(this->activity, 0);
                    240: 
                    241:        return &this->public;
                    242: }

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