diff --git a/disktimeout.c b/disktimeout.c index 1be3417..359ad7e 100644 --- a/disktimeout.c +++ b/disktimeout.c @@ -216,6 +216,7 @@ static int diskto_check_cb(void *privdata) continue; } } + close(fd); /* args[2]: * 0x00 - standby diff --git a/lcd.c b/lcd.c index 588df33..754073c 100644 --- a/lcd.c +++ b/lcd.c @@ -81,6 +81,7 @@ struct lcddev { struct event_timeout *reset_timeout; struct event_timeout *backlight_timeout; struct event_timeout *scroll_timeout; + struct event_timeout *update_timeout; }; void lcd_close(struct lcddev *dev) @@ -95,6 +96,11 @@ void lcd_close(struct lcddev *dev) dev->backlight_timeout = NULL; } + if (dev->update_timeout) { + event_remove_timeout(dev->update_timeout); + dev->update_timeout = NULL; + } + if (dev->scroll_timeout) { event_remove_timeout(dev->scroll_timeout); dev->scroll_timeout = NULL; @@ -327,11 +333,28 @@ int lcd_trigger_backlight(struct lcddev *dev, int timeout) return retval; } +static int lcd_update_timeout_cb(void *privdata) +{ + struct lcddev *dev = (struct lcddev *)privdata; + dev->update_timeout = NULL; + + int update = dev->event_callback(dev, LCD_EVENT_UPDATE, dev->event_privdata); + + /* update only if backlight is on (display visible) */ + if ((update != 0) && (dev->backlight_state != 0)) { + struct timeval tv = { .tv_sec = update / 1000, .tv_usec = (update % 1000) * 1000 }; + dev->update_timeout = event_add_timeout(&tv, lcd_update_timeout_cb, dev); + } + + return -1; /* singleshot */ +} + static int lcd_read_cb(int fd, void *privdata) { struct lcddev *dev = (struct lcddev *)privdata; char buf[4]; + int update = 0; int size = (dev->state != LCD_STATE_INITIALIZING) ? sizeof(buf) : 2; int len = lcd_read(dev, buf, size); @@ -348,7 +371,7 @@ static int lcd_read_cb(int fd, void *privdata) dev->state = LCD_STATE_READY; /* trigger application to set data */ - dev->event_callback(dev, LCD_EVENT_INIT, dev->event_privdata); + update = dev->event_callback(dev, LCD_EVENT_INIT, dev->event_privdata); } } else if (dev->state == LCD_STATE_READY) { @@ -359,13 +382,24 @@ static int lcd_read_cb(int fd, void *privdata) return 0; if (memcmp(buf, expect1, sizeof(buf)) == 0) { - dev->event_callback(dev, LCD_EVENT_BUTTON1, dev->event_privdata); + update = dev->event_callback(dev, LCD_EVENT_BUTTON1, dev->event_privdata); } else if (memcmp(buf, expect2, sizeof(buf)) == 0) { - dev->event_callback(dev, LCD_EVENT_BUTTON2, dev->event_privdata); + update = dev->event_callback(dev, LCD_EVENT_BUTTON2, dev->event_privdata); } } + if (dev->update_timeout != NULL) { + event_remove_timeout(dev->update_timeout); + dev->update_timeout = NULL; + } + + /* update only if backlight is on (display visible) */ + if ((update != 0) && (dev->backlight_state != 0)) { + struct timeval tv = { .tv_sec = update / 1000, .tv_usec = (update % 1000) * 1000 }; + dev->update_timeout = event_add_timeout(&tv, lcd_update_timeout_cb, dev); + } + return 0; } @@ -429,15 +463,36 @@ static int lcd_scroll_timeout_cb(void *privdata) int lcd_setlines(struct lcddev *dev, int scroll_speed, const char *line1, const char *line2) { - dev->line_data[0] = line1; - dev->line_length[0] = (line1 != NULL) ? strlen(line1) : 0; - lcd_setline(dev, 0, dev->line_length[0], dev->line_data[0]); + int i; + for (i = 0; i < 2; i++) { + if (dev->line_data[i] != NULL) { + free((void *)dev->line_data[i]); + } - dev->line_data[1] = line2; - dev->line_length[1] = (line2 != NULL) ? strlen(line2) : 0; + dev->line_data[i] = NULL; + dev->line_length[i] = 0; + } + + if (line1 != NULL) { + dev->line_data[0] = strdup(line1); + + if (dev->line_data[0] != NULL) { + dev->line_length[0] = strlen(line1); + } + } + + if (line2 != NULL) { + dev->line_data[1] = strdup(line2); + + if (dev->line_data[1] != NULL) { + dev->line_length[1] = strlen(line2); + } + } + + lcd_setline(dev, 0, dev->line_length[0], dev->line_data[0]); lcd_setline(dev, 1, dev->line_length[1], dev->line_data[1]); - int scroll_enable = (dev->line_length[0] > 16 && dev->line_length[1] > 16); + int scroll_enable = (dev->line_length[0] > 16) || (dev->line_length[1] > 16); if (dev->scroll_timeout && ((dev->scroll_speed != scroll_speed) || !scroll_enable)) { event_remove_timeout(dev->scroll_timeout); dev->scroll_timeout = NULL; @@ -447,7 +502,7 @@ int lcd_setlines(struct lcddev *dev, int scroll_speed, const char *line1, const dev->scroll_pos = 0; if ((dev->scroll_timeout == NULL) && scroll_enable && (scroll_speed > 0)) { - struct timeval tv = { .tv_usec = 1000 * dev->scroll_speed }; + struct timeval tv = { .tv_sec = dev->scroll_speed / 1000, .tv_usec = (dev->scroll_speed % 1000) * 1000 }; dev->scroll_timeout = event_add_timeout(&tv, lcd_scroll_timeout_cb, dev); } diff --git a/lcd.h b/lcd.h index ebc0c51..155b690 100644 --- a/lcd.h +++ b/lcd.h @@ -1,10 +1,11 @@ #ifndef _LCD_H_ #define _LCD_H_ -#define LCD_EVENT_INIT 0x00 -#define LCD_EVENT_BUTTON1 0x01 -#define LCD_EVENT_BUTTON2 0x02 -#define LCD_EVENT_BACKLIGHT 0x04 +#define LCD_EVENT_INIT 0x00 /* lcd initialized */ +#define LCD_EVENT_UPDATE 0x01 /* update data */ +#define LCD_EVENT_BUTTON1 0x02 /* button1 pressed */ +#define LCD_EVENT_BUTTON2 0x03 /* button2 pressed */ +#define LCD_EVENT_BACKLIGHT 0x04 /* backlight timeout */ struct lcddev; /* private data */ diff --git a/qnapd.c b/qnapd.c index 85f4283..1dd3fb3 100644 --- a/qnapd.c +++ b/qnapd.c @@ -27,6 +27,9 @@ #include #include +#include +#include + #include "configfile.h" #include "disktimeout.h" #include "event.h" @@ -62,13 +65,41 @@ static int button_callback(struct lcddev *dev, int button, void *privdata) page = (page > 0) ? page -1 : PAGE_MAX; } else if (button == LCD_EVENT_BACKLIGHT) { - return 0; + return 0; /* no update requested */ } + if (button != LCD_EVENT_UPDATE) { + lcd_trigger_backlight(dev, LCD_TIMEOUT); + } + + int update = 0; + switch (page) { - case 0: - lcd_setlines(dev, 500, "Debian GNU/Linux 5.0", "Linux 2.6.32.27-486 i586"); - break; + case 7: + { + FILE *fp = fopen("/etc/issue.net", "r"); + char line1[64]; + char line2[64]; + + memset(line1, 0x00, sizeof(line1)); + memset(line2, 0x00, sizeof(line2)); + + if (fp != NULL) { + fread(line1, 1, sizeof(line1), fp); + fclose(fp); + } else { + strcpy(line1, ""); + } + + struct utsname utsbuf; + uname(&utsbuf); + + snprintf(line2, sizeof(line2), "%s %s", utsbuf.sysname, utsbuf.release); + + lcd_setlines(dev, 500, line1, line2); + } + break; + case 1: lcd_setlines(dev, 0, "Hostname:", "storenix.lan"); break; @@ -87,21 +118,37 @@ static int button_callback(struct lcddev *dev, int button, void *privdata) case 6: lcd_setlines(dev, 0, "Uptime:", " XXXd XX:XX:XX"); break; - case 7: - lcd_setlines(dev, 0, "Time: XX:XX:XX", "Date: XX-XX-XXXX"); - break; + case 0: + { + char line1[20]; + char line2[20]; + + struct tm tmp; + time_t now; + + time(&now); + localtime_r(&now, &tmp); + + strftime(line1, sizeof(line1), "Time: %H:%M:%S", &tmp); + strftime(line2, sizeof(line2), "Date: %d-%m-%Y", &tmp); + + lcd_setlines(dev, 0, line1, line2); + update = 1000; + } + break; + + } - lcd_trigger_backlight(dev, LCD_TIMEOUT); - return 1; + return update; } static int restart_var; static void trigger_restart(void *privdata) { - int *restart = (int *)privdata; - *restart = 1; + int *restart = (int *)privdata; + *restart = 1; } int check_restart(int *maxfd, void *readfds, void *writefds, struct timeval *timeout, void *privdata) diff --git a/qnapd.conf b/qnapd.conf index 820f16e..32a9c6a 100644 --- a/qnapd.conf +++ b/qnapd.conf @@ -1,7 +1,7 @@ [global] #lcddevice /dev/ttyS0 -#lcddevice dummy +lcddevice dummy pidfile qnapd.pid logfile qnapd.log