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>