1 #define MODULE_LOG_PREFIX "led"
7 #include "module-led.h"
8 #include "oscam-string.h"
9 #include "oscam-time.h"
19 static pthread_t arm_led_thread
;
20 static LLIST
*arm_led_actions
;
22 #define ARM_LED_TYPES 3
23 #define ARM_LED_FILES 4
32 } leds
[ARM_LED_FILES
];
35 static const struct arm_leds arm_leds
[ARM_LED_TYPES
] =
39 { LED1A
, "red:status" },
40 { LED1B
, "green:ready" },
41 { LED2
, "green:disk-1" },
42 { LED3
, "green:disk-2" }
47 { LED1A
, "orange:misc" },
48 { LED1B
, "green:health" },
49 { LED2
, "green:health" },
50 { LED3
, "orange:misc" }
55 { LED1A
, "orange:power" },
56 { LED1B
, "green:power" },
57 { LED2
, "green:wireless" },
58 { LED3
, "green:security" }
63 static int32_t arm_init_led_file(uint8_t led_type
, uint8_t led_no
, char *buf
, int32_t buflen
)
66 if(led_type
>= ARM_LED_TYPES
) { return 0; }
67 if(led_no
>= ARM_LED_FILES
) { return 0; }
68 for(i
= 0; i
< ARM_LED_FILES
; i
++)
70 if(arm_leds
[led_type
].leds
[i
].id
== led_no
)
72 return snprintf(buf
, buflen
, "/sys/class/leds/%s:%s/brightness",
73 arm_leds
[led_type
].machine
, arm_leds
[led_type
].leds
[i
].file
);
79 #define LED_TYPE_UNKNOWN 0xff
80 static uint8_t arm_led_type
= LED_TYPE_UNKNOWN
;
82 static void arm_detect_led_type(void)
86 for(i
= 0; i
< ARM_LED_TYPES
; i
++)
88 if(!arm_init_led_file(i
, 0, led_file
, sizeof(led_file
)))
90 if(access(led_file
, W_OK
) == 0)
93 cs_log("LED support for %s is activated.", arm_leds
[arm_led_type
].machine
);
97 if(arm_led_type
== LED_TYPE_UNKNOWN
)
98 { cs_log("LED support is not active. Can't detect machine type."); }
101 static void arm_switch_led_from_thread(int32_t led
, int32_t action
)
103 if(action
< 2) // only LED_ON and LED_OFF
106 if(!arm_init_led_file(arm_led_type
, led
, led_file
, sizeof(led_file
)))
108 FILE *f
= fopen(led_file
, "w");
111 fprintf(f
, "%d", action
);
119 arm_switch_led_from_thread(LED1A
, LED_OFF
);
120 arm_switch_led_from_thread(LED1B
, LED_OFF
);
121 arm_switch_led_from_thread(LED2
, LED_ON
);
122 arm_switch_led_from_thread(LED3
, LED_OFF
);
125 arm_switch_led_from_thread(led
, LED_OFF
);
127 arm_switch_led_from_thread(led
, LED_ON
);
130 arm_switch_led_from_thread(led
, LED_ON
);
132 arm_switch_led_from_thread(led
, LED_OFF
);
138 static void *arm_led_thread_main(void *UNUSED(thread_data
))
141 set_thread_name(__func__
);
144 LL_ITER iter
= ll_iter_create(arm_led_actions
);
145 struct s_arm_led
*arm_led
;
146 while((arm_led
= ll_iter_next(&iter
)))
151 action
= arm_led
->action
;
152 now
= time((time_t)0);
153 start
= arm_led
->start_time
;
154 ll_iter_remove_data(&iter
);
155 if(action
== LED_STOP_THREAD
)
160 if(now
- start
< ARM_LED_TIMEOUT
)
162 arm_switch_led_from_thread(led
, action
);
170 ll_clear_data(arm_led_actions
);
175 static void arm_led_start_thread(void)
177 arm_detect_led_type();
178 if(!cfg
.enableled
|| arm_led_type
== LED_TYPE_UNKNOWN
)
180 // call this after signal handling is done
183 arm_led_actions
= ll_create("arm_led_actions");
186 start_thread("arm led", arm_led_thread_main
, NULL
, &arm_led_thread
, 1, 1);
189 static void arm_led(int32_t led
, int32_t action
)
191 struct s_arm_led
*data
;
192 if(!cfg
.enableled
|| arm_led_type
== LED_TYPE_UNKNOWN
)
196 arm_led_actions
= ll_create("arm_led_actions");
198 if(cs_malloc(&data
, sizeof(struct s_arm_led
)))
200 data
->start_time
= time((time_t)0);
202 data
->action
= action
;
203 ll_append(arm_led_actions
, (void *)data
);
207 // arm_led_thread_main is not started at oscam startup
208 // when first arm_led calls happen
209 pthread_kill(arm_led_thread
, OSCAM_SIGNAL_WAKEUP
);
213 static void arm_led_stop_thread(void)
215 if(!cfg
.enableled
|| arm_led_type
== LED_TYPE_UNKNOWN
)
217 arm_led(0, LED_STOP_THREAD
);
220 static inline void arm_led_start_thread(void) { }
221 static inline void arm_led_stop_thread(void) { }
222 static inline void arm_led(int32_t UNUSED(led
), int32_t UNUSED(action
)) { }
227 static void qboxhd_led_blink(int32_t color
, int32_t duration
)
230 if(cfg
.enableled
!= 2)
232 // try QboxHD-MINI first
233 if((f
= open(QBOXHDMINI_LED_DEVICE
, O_RDWR
| O_NONBLOCK
)) > -1)
235 qboxhdmini_led_color_struct qbminiled
;
236 uint32_t qboxhdmini_color
= 0x000000;
237 if(color
!= QBOXHD_LED_COLOR_OFF
)
241 case QBOXHD_LED_COLOR_RED
:
242 qboxhdmini_color
= QBOXHDMINI_LED_COLOR_RED
;
244 case QBOXHD_LED_COLOR_GREEN
:
245 qboxhdmini_color
= QBOXHDMINI_LED_COLOR_GREEN
;
247 case QBOXHD_LED_COLOR_BLUE
:
248 qboxhdmini_color
= QBOXHDMINI_LED_COLOR_BLUE
;
250 case QBOXHD_LED_COLOR_YELLOW
:
251 qboxhdmini_color
= QBOXHDMINI_LED_COLOR_YELLOW
;
253 case QBOXHD_LED_COLOR_MAGENTA
:
254 qboxhdmini_color
= QBOXHDMINI_LED_COLOR_MAGENTA
;
257 // set LED on with color
258 qbminiled
.red
= (uint8_t)((qboxhdmini_color
& 0xFF0000) >> 16); // R
259 qbminiled
.green
= (uint8_t)((qboxhdmini_color
& 0x00FF00) >> 8); // G
260 qbminiled
.blue
= (uint8_t)(qboxhdmini_color
& 0x0000FF); // B
261 ioctl(f
, QBOXHDMINI_IOSET_RGB
, &qbminiled
);
262 cs_sleepms(duration
);
268 ioctl(f
, QBOXHDMINI_IOSET_RGB
, &qbminiled
);
271 else if((f
= open(QBOXHD_LED_DEVICE
, O_RDWR
| O_NONBLOCK
)) > -1)
273 qboxhd_led_color_struct qbled
;
274 if(color
!= QBOXHD_LED_COLOR_OFF
)
276 // set LED on with color
280 ioctl(f
, QBOXHD_SET_LED_ALL_PANEL_COLOR
, &qbled
);
281 cs_sleepms(duration
);
287 ioctl(f
, QBOXHD_SET_LED_ALL_PANEL_COLOR
, &qbled
);
292 static inline void qboxhd_led_blink(int32_t UNUSED(color
), int32_t UNUSED(duration
)) { }
295 void led_status_stopping(void)
297 if(cfg
.enableled
== 1)
299 arm_led(LED1B
, LED_OFF
);
300 arm_led(LED2
, LED_OFF
);
301 arm_led(LED3
, LED_OFF
);
302 arm_led(LED1A
, LED_ON
);
304 if(cfg
.enableled
== 2)
306 qboxhd_led_blink(QBOXHD_LED_COLOR_YELLOW
, QBOXHD_LED_BLINK_FAST
);
307 qboxhd_led_blink(QBOXHD_LED_COLOR_RED
, QBOXHD_LED_BLINK_FAST
);
308 qboxhd_led_blink(QBOXHD_LED_COLOR_GREEN
, QBOXHD_LED_BLINK_FAST
);
309 qboxhd_led_blink(QBOXHD_LED_COLOR_BLUE
, QBOXHD_LED_BLINK_FAST
);
310 qboxhd_led_blink(QBOXHD_LED_COLOR_MAGENTA
, QBOXHD_LED_BLINK_FAST
);
314 void led_status_cw_not_found(ECM_REQUEST
*er
)
317 { arm_led(LED2
, LED_BLINK_OFF
); }
318 if(er
->rc
< E_NOTFOUND
)
320 qboxhd_led_blink(QBOXHD_LED_COLOR_GREEN
, QBOXHD_LED_BLINK_MEDIUM
);
322 else if(er
->rc
<= E_STOPPED
)
324 qboxhd_led_blink(QBOXHD_LED_COLOR_RED
, QBOXHD_LED_BLINK_MEDIUM
);
328 void led_status_default(void)
330 arm_led(LED1A
, LED_DEFAULT
);
331 arm_led(LED1A
, LED_ON
);
334 void led_status_starting(void)
336 arm_led(LED1A
, LED_OFF
);
337 arm_led(LED1B
, LED_ON
);
338 qboxhd_led_blink(QBOXHD_LED_COLOR_YELLOW
, QBOXHD_LED_BLINK_FAST
);
339 qboxhd_led_blink(QBOXHD_LED_COLOR_RED
, QBOXHD_LED_BLINK_FAST
);
340 qboxhd_led_blink(QBOXHD_LED_COLOR_GREEN
, QBOXHD_LED_BLINK_FAST
);
341 qboxhd_led_blink(QBOXHD_LED_COLOR_BLUE
, QBOXHD_LED_BLINK_FAST
);
342 qboxhd_led_blink(QBOXHD_LED_COLOR_MAGENTA
, QBOXHD_LED_BLINK_FAST
);
345 void led_status_card_activation_error(void)
347 qboxhd_led_blink(QBOXHD_LED_COLOR_MAGENTA
, QBOXHD_LED_BLINK_MEDIUM
);
350 void led_status_found_cardsystem(void)
352 qboxhd_led_blink(QBOXHD_LED_COLOR_YELLOW
, QBOXHD_LED_BLINK_MEDIUM
);
353 qboxhd_led_blink(QBOXHD_LED_COLOR_GREEN
, QBOXHD_LED_BLINK_MEDIUM
);
354 qboxhd_led_blink(QBOXHD_LED_COLOR_YELLOW
, QBOXHD_LED_BLINK_MEDIUM
);
355 qboxhd_led_blink(QBOXHD_LED_COLOR_GREEN
, QBOXHD_LED_BLINK_MEDIUM
);
358 void led_status_unsupported_card_system(void)
360 qboxhd_led_blink(QBOXHD_LED_COLOR_MAGENTA
, QBOXHD_LED_BLINK_MEDIUM
);
363 void led_status_card_detected(void)
365 qboxhd_led_blink(QBOXHD_LED_COLOR_YELLOW
, QBOXHD_LED_BLINK_SLOW
);
368 void led_status_card_ejected(void)
370 qboxhd_led_blink(QBOXHD_LED_COLOR_RED
, QBOXHD_LED_BLINK_SLOW
);
373 void led_status_emm_ok(void)
375 arm_led(LED3
, LED_BLINK_ON
);
376 qboxhd_led_blink(QBOXHD_LED_COLOR_BLUE
, QBOXHD_LED_BLINK_MEDIUM
);
381 arm_led_start_thread();
386 arm_led_stop_thread();