2 * Copyright (C) 2010 Martin Willi
3 * Copyright (C) 2010 revosec AG
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>.
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
16 #include "led_listener.h"
21 #include <threading/mutex.h>
22 #include <processing/jobs/callback_job.h>
24 typedef struct private_led_listener_t private_led_listener_t
;
27 * Private data of an led_listener_t object.
29 struct private_led_listener_t
{
32 * Public led_listener_t interface.
34 led_listener_t
public;
42 * Number of established IKE_SAs
47 * LED blink on/off time, in ms
52 * Activity LED fd, if any
57 * Activity LED maximum brightness
63 * Open a LED brightness control file, get max brightness
65 static FILE *open_led(char *name
, int *max_brightness
)
76 snprintf(path
, sizeof(path
), "/sys/class/leds/%s/max_brightness", name
);
80 if (fscanf(f
, "%d\n", max_brightness
) != 1)
82 DBG1(DBG_CFG
, "reading max brightness for '%s' failed: %s, using 1",
83 name
, strerror(errno
));
89 DBG1(DBG_CFG
, "reading max_brightness for '%s' failed: %s, using 1",
90 name
, strerror(errno
));
93 snprintf(path
, sizeof(path
), "/sys/class/leds/%s/brightness", name
);
97 DBG1(DBG_CFG
, "opening LED file '%s' failed: %s", path
, strerror(errno
));
103 * Set a LED to a given brightness
105 static void set_led(FILE *led
, int brightness
)
109 if (fprintf(led
, "%d\n", brightness
) <= 0 ||
112 DBG1(DBG_CFG
, "setting LED brightness failed: %s", strerror(errno
));
120 static bool plugin_gone
= FALSE
;
123 * Reset activity LED after timeout
125 static job_requeue_t
reset_activity_led(private_led_listener_t
*this)
128 { /* TODO: fix race */
129 this->mutex
->lock(this->mutex
);
132 set_led(this->activity
, this->activity_max
);
136 set_led(this->activity
, 0);
138 this->mutex
->unlock(this->mutex
);
140 return JOB_REQUEUE_NONE
;
144 * Blink the activity LED
146 static void blink_activity(private_led_listener_t
*this)
150 this->mutex
->lock(this->mutex
);
153 set_led(this->activity
, 0);
157 set_led(this->activity
, this->activity_max
);
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
);
166 METHOD(listener_t
, ike_state_change
, bool,
167 private_led_listener_t
*this, ike_sa_t
*ike_sa
, ike_sa_state_t state
)
169 this->mutex
->lock(this->mutex
);
170 if (state
== IKE_ESTABLISHED
&& ike_sa
->get_state(ike_sa
) != IKE_ESTABLISHED
)
173 if (this->count
== 1)
175 set_led(this->activity
, this->activity_max
);
178 if (ike_sa
->get_state(ike_sa
) == IKE_ESTABLISHED
&& state
!= IKE_ESTABLISHED
)
181 if (this->count
== 0)
183 set_led(this->activity
, 0);
186 this->mutex
->unlock(this->mutex
);
190 METHOD(listener_t
, message_hook
, bool,
191 private_led_listener_t
*this, ike_sa_t
*ike_sa
,
192 message_t
*message
, bool incoming
)
194 if (incoming
|| message
->get_request(message
))
196 blink_activity(this);
201 METHOD(led_listener_t
, destroy
, void,
202 private_led_listener_t
*this)
204 this->mutex
->lock(this->mutex
);
205 set_led(this->activity
, 0);
207 this->mutex
->unlock(this->mutex
);
210 fclose(this->activity
);
212 this->mutex
->destroy(this->mutex
);
219 led_listener_t
*led_listener_create()
221 private_led_listener_t
*this;
226 .ike_state_change
= _ike_state_change
,
227 .message
= _message_hook
,
231 .mutex
= mutex_create(MUTEX_TYPE_DEFAULT
),
232 .blink_time
= lib
->settings
->get_int(lib
->settings
,
233 "charon.plugins.led.blink_time", 50),
236 this->activity
= open_led(lib
->settings
->get_str(lib
->settings
,
237 "charon.plugins.led.activity_led", NULL
), &this->activity_max
);
238 set_led(this->activity
, 0);
240 return &this->public;