Return to led_listener.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libcharon / plugins / led |
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: }