more work

This commit is contained in:
Olaf Rempel 2012-12-09 01:30:37 +01:00
parent 031b7e540d
commit 606a3306c5
10 changed files with 337 additions and 221 deletions

View File

@ -1,7 +0,0 @@
#ifndef _DISKTIMEOUT_H_
#define _DISKTIMEOUT_H_
int disktimeout_exit(void);
int disktimeout_init(void);
#endif /* _DISKTIMEOUT_H_ */

View File

@ -26,9 +26,12 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <fcntl.h> #include <fcntl.h>
#include <ctype.h> #include <ctype.h>
#include <time.h>
#include "configfile.h" #include "configfile.h"
#include "diskwatch.h"
#include "event.h" #include "event.h"
#include "lcd.h"
#include "list.h" #include "list.h"
#include "logging.h" #include "logging.h"
@ -41,88 +44,93 @@ int prefer_ata12 = 0;
struct disk_entry { struct disk_entry {
struct list_head list; struct list_head list;
const char device[16]; const char device[32];
unsigned int timeout; unsigned int timeout_sec;
int flags; int flags;
time_t standby_timeout;
unsigned int sectors_rd; unsigned int sectors_rd;
unsigned int sectors_wr; unsigned int sectors_wr;
struct event_timeout *timeout_event;
}; };
static LIST_HEAD(disk_list); struct diskwatch {
static struct event_timeout *check_timeout; struct list_head disk_list;
struct lcddev *lcd;
struct event_timeout *check_timeout;
};
static int diskto_timeout_cb(int timerid, void *privdata) static struct diskwatch diskwatch_glob;
static int lcdpage_diskwatch(struct lcddev *lcd, int event, void *privdata)
{ {
struct disk_entry *entry = (struct disk_entry *) privdata; static struct disk_entry *entry;
entry->timeout_event = NULL; struct diskwatch *dwatch = (struct diskwatch *)privdata;
if (!(entry->flags & F_PRESENT))
return -1;
int fd = open(entry->device, O_RDONLY | O_NONBLOCK);
if (fd < 0) {
log_print(LOG_WARN, "%s: failed to open %s", __FUNCTION__, entry->device);
return -1;
}
// log_print(LOG_INFO, "disktimeout: %s standby after %ds", entry->device, entry->timeout);
unsigned char args[4] = { ATA_OP_STANDBYNOW1, 0, 0, 0};
if (do_drive_cmd(fd, args)) {
args[0] = ATA_OP_STANDBYNOW2;
if (do_drive_cmd(fd, args)) {
log_print(LOG_WARN, "%s: do_drive_cmd(ATA_OP_STANDBYNOW) failed on %s", __FUNCTION__, entry->device);
close(fd);
return -1;
}
}
entry->flags |= F_STANDBY;
close(fd);
return -1;
}
static int diskto_add_disk(struct strtoken *tokens, void *privdata)
{
if (tokens->count != 2) {
log_print(LOG_WARN, "%s(): invalid config line '%s'", __FUNCTION__, tokens->input);
return -1;
}
struct disk_entry *entry = malloc(sizeof(struct disk_entry));
if (entry == NULL) { if (entry == NULL) {
log_print(LOG_WARN, "%s(): out of memory", __FUNCTION__); if (list_empty(&dwatch->disk_list)) {
return -1; return LCDPAGE_COMMAND_NEXT;
} }
strncpy((char *)entry->device, tokens->field[0], sizeof(entry->device)); entry = list_entry(dwatch->disk_list.next, struct disk_entry, list);
char *tmp;
entry->timeout = strtol(tokens->field[1], &tmp, 0);
if (*tmp != '\0' && !isspace(*tmp)) {
log_print(LOG_WARN, "%s(): invalid timeout value '%s'", __FUNCTION__, tokens->field[1]);
free(entry);
return -1;
} }
entry->flags = 0; switch (event) {
entry->sectors_rd = 0; case LCDPAGE_EVENT_BUTTON1:
entry->sectors_wr = 0; if (entry->list.next == &dwatch->disk_list) {
entry = NULL;
return LCDPAGE_COMMAND_NEXT;
}
entry->timeout_event = event_add_timeout_ms(entry->timeout * 1000, diskto_timeout_cb, 0, (void *)entry); entry = list_entry(entry->list.next, struct disk_entry, list);
lcd_set_backlight(lcd, 1);
break;
log_print(LOG_INFO, "disktimeout: watching '%s' (standby timeout: %ds)", entry->device, entry->timeout); case LCDPAGE_EVENT_ENTER:
list_add_tail(&entry->list, &disk_list); entry = list_entry(dwatch->disk_list.next, struct disk_entry, list);
lcd_set_backlight(lcd, 1);
break;
case LCDPAGE_EVENT_BACKLIGHT:
case LCDPAGE_EVENT_EXIT:
return 0; return 0;
default:
break;
}
char line1[32];
char line2[32];
snprintf(line1, sizeof(line1), "DISK(%s):", entry->device);
if (entry->flags & F_PRESENT) {
if (entry->flags & F_STANDBY) {
snprintf(line2, sizeof(line2), "STANDBY");
} else {
int timeout = entry->standby_timeout - time(NULL);
int hours = timeout / 3600;
timeout = timeout % 3600;
int minutes = timeout / 60;
timeout = timeout % 60;
snprintf(line2, sizeof(line2), "RUN -%02d:%02d:%02d", hours, minutes, timeout);
}
} else {
snprintf(line2, sizeof(line2), "not present");
}
lcd_setlines(lcd, line1, line2);
return 1000;
} }
static int diskto_check_cb(int timerid, void *privdata) static int diskwatch_check_cb(int timerid, void *privdata)
{ {
struct diskwatch *dwatch = (struct diskwatch *)privdata;
struct disk_entry *entry; struct disk_entry *entry;
list_for_each_entry(entry, &disk_list, list) { list_for_each_entry(entry, &dwatch->disk_list, list) {
entry->flags &= ~(F_PRESENT); entry->flags &= ~(F_PRESENT);
} }
@ -132,10 +140,12 @@ static int diskto_check_cb(int timerid, void *privdata)
return -1; return -1;
} }
time_t now = time(NULL);
char buffer[256]; char buffer[256];
while (fgets(buffer, sizeof(buffer), fp) != NULL) { while (fgets(buffer, sizeof(buffer), fp) != NULL) {
int major, minor; int major, minor;
char device[16]; char device[32];
unsigned int val[11]; unsigned int val[11];
/* field - description /* field - description
@ -166,7 +176,7 @@ static int diskto_check_cb(int timerid, void *privdata)
} }
struct disk_entry *entry; struct disk_entry *entry;
list_for_each_entry(entry, &disk_list, list) { list_for_each_entry(entry, &dwatch->disk_list, list) {
char *dev = strrchr(entry->device, '/'); char *dev = strrchr(entry->device, '/');
if (dev == NULL || *(dev +1) == '\0') if (dev == NULL || *(dev +1) == '\0')
continue; continue;
@ -182,19 +192,13 @@ static int diskto_check_cb(int timerid, void *privdata)
entry->flags &= ~(F_STANDBY); entry->flags &= ~(F_STANDBY);
entry->sectors_rd = val[2]; entry->sectors_rd = val[2];
entry->sectors_wr = val[6]; entry->sectors_wr = val[6];
entry->standby_timeout = now + entry->timeout_sec;
/* remove old timeout */
if (entry->timeout_event != NULL)
event_remove_timeout(entry->timeout_event);
/* set new one */
entry->timeout_event = event_add_timeout_ms(entry->timeout * 1000, diskto_timeout_cb, 0, (void *)entry);
} }
} }
fclose(fp); fclose(fp);
list_for_each_entry(entry, &disk_list, list) { list_for_each_entry(entry, &dwatch->disk_list, list) {
if (!(entry->flags & F_PRESENT)) if (!(entry->flags & F_PRESENT))
continue; continue;
@ -208,12 +212,11 @@ static int diskto_check_cb(int timerid, void *privdata)
if (do_drive_cmd(fd, args)) { if (do_drive_cmd(fd, args)) {
args[0] = ATA_OP_CHECKPOWERMODE2; args[0] = ATA_OP_CHECKPOWERMODE2;
if (do_drive_cmd(fd, args)) { if (do_drive_cmd(fd, args)) {
log_print(LOG_WARN, "%s: do_drive_cmd(ATA_OP_CHECKPOWERMODE) failed on %s", __FUNCTION__, entry->device); log_print(LOG_WARN, "%s: do_drive_cmd(ATA_OP_CHECKPOWERMODEx) failed on %s", __FUNCTION__, entry->device);
close(fd); close(fd);
continue; continue;
} }
} }
close(fd);
/* args[2]: /* args[2]:
* 0x00 - standby * 0x00 - standby
@ -222,65 +225,103 @@ static int diskto_check_cb(int timerid, void *privdata)
* 0x80 - idle * 0x80 - idle
* 0xFF - active/idle * 0xFF - active/idle
*/ */
/* drive is in standby */
if (args[2] == 0x00) {
entry->flags |= F_STANDBY;
if (args[2] != 0x00) { /* drive was in standby, and is now active (without change in sector counts */
if (entry->flags & F_STANDBY) { } else if (entry->flags & F_STANDBY) {
// log_print(LOG_INFO, "disktimeout: %s is awake, starting timer", entry->device, entry->timeout);
/* device is not in standby mode, start timer */
if (entry->timeout_event == NULL) {
entry->timeout_event = event_add_timeout_ms(entry->timeout * 1000, diskto_timeout_cb, 0, (void *)entry);
}
entry->flags &= ~(F_STANDBY); entry->flags &= ~(F_STANDBY);
entry->standby_timeout = now + entry->timeout_sec;
/* drive is active, and timeout is up */
} else if (now >= entry->standby_timeout) {
unsigned char args[4] = { ATA_OP_STANDBYNOW1, 0, 0, 0};
if (do_drive_cmd(fd, args)) {
args[0] = ATA_OP_STANDBYNOW2;
if (do_drive_cmd(fd, args)) {
log_print(LOG_WARN, "%s: do_drive_cmd(ATA_OP_STANDBYNOWx) failed on %s", __FUNCTION__, entry->device);
close(fd);
continue;
}
} }
} else {
if (!(entry->flags & F_STANDBY)) {
// log_print(LOG_INFO, "disktimeout: %s standby, stopping timer", entry->device, entry->timeout);
/* device is in standby, stop timer */
if (entry->timeout_event != NULL)
event_remove_timeout(entry->timeout_event);
entry->flags |= F_STANDBY; entry->flags |= F_STANDBY;
} }
}
close(fd);
} }
return 0; return 0;
} }
int disktimeout_exit(void) static int diskwatch_add_disk(struct strtoken *tokens, void *privdata)
{ {
struct disk_entry *entry, *tmp; struct diskwatch *dwatch = (struct diskwatch *)privdata;
list_for_each_entry_safe(entry, tmp, &disk_list, list) { if (tokens->count != 2) {
if (entry->timeout_event != NULL) { log_print(LOG_WARN, "%s(): invalid config line '%s'", __FUNCTION__, tokens->input);
event_remove_timeout(entry->timeout_event); return -1;
entry->timeout_event = NULL;
} }
struct disk_entry *entry = malloc(sizeof(struct disk_entry));
if (entry == NULL) {
log_print(LOG_WARN, "%s(): out of memory", __FUNCTION__);
return -1;
}
memset(entry, 0x00, sizeof(struct disk_entry));
strncpy((char *)entry->device, tokens->field[0], sizeof(entry->device));
char *tmp;
entry->timeout_sec = strtol(tokens->field[1], &tmp, 0);
if (*tmp != '\0' && !isspace(*tmp)) {
log_print(LOG_WARN, "%s(): invalid timeout value '%s'", __FUNCTION__, tokens->field[1]);
free(entry);
return -1;
}
log_print(LOG_INFO, "diskwatch: watching '%s' (standby timeout: %ds)", entry->device, entry->timeout_sec);
list_add_tail(&entry->list, &dwatch->disk_list);
return 0;
}
void diskwatch_exit(void)
{
struct diskwatch *dwatch = &diskwatch_glob;
struct disk_entry *entry, *tmp;
list_for_each_entry_safe(entry, tmp, &dwatch->disk_list, list) {
list_del(&entry->list); list_del(&entry->list);
free(entry); free(entry);
} }
if (check_timeout != NULL) { if (dwatch->check_timeout != NULL) {
event_remove_timeout(check_timeout); event_remove_timeout(dwatch->check_timeout);
check_timeout = NULL; dwatch->check_timeout = NULL;
} }
return 0;
} }
int disktimeout_init(void) int diskwatch_init(struct lcddev *lcd)
{ {
int diskcount = config_get_strtokens("disktimeout", "disk", ",", 2, diskto_add_disk, NULL); struct diskwatch *dwatch = &diskwatch_glob;
INIT_LIST_HEAD(&dwatch->disk_list);
int diskcount = config_get_strtokens("diskwatch", "disk", ",", 2, diskwatch_add_disk, dwatch);
if (diskcount <= 0) if (diskcount <= 0)
return diskcount; return 0;
diskwatch_check_cb(0, dwatch);
int check_interval = 0; int check_interval = 0;
config_get_int("disktimeout", "check_interval", &check_interval, 60); config_get_int("diskwatch", "check_interval", &check_interval, 60);
dwatch->check_timeout = event_add_timeout_ms(check_interval * 1000, diskwatch_check_cb, 0, dwatch);
check_timeout = event_add_timeout_ms(check_interval * 1000, diskto_check_cb, 0, NULL); dwatch->lcd = lcd;
if (dwatch->lcd != NULL) {
lcd_addpage_cb(dwatch->lcd, 150, lcdpage_diskwatch, dwatch);
}
return 0; return 0;
} }

9
diskwatch.h Normal file
View File

@ -0,0 +1,9 @@
#ifndef _DISKWATCH_H_
#define _DISKWATCH_H_
#include "lcd.h"
void diskwatch_exit(void);
int diskwatch_init(struct lcddev *lcd);
#endif /* _DISKWATCH_H_ */

183
lcd.c
View File

@ -87,6 +87,8 @@ struct lcddev {
int line_length[2]; int line_length[2];
int scroll_pos; int scroll_pos;
int update_ms;
struct event_fd *read_event; struct event_fd *read_event;
struct event_timeout *reset_timeout; struct event_timeout *reset_timeout;
struct event_timeout *backlight_timeout; struct event_timeout *backlight_timeout;
@ -342,27 +344,45 @@ static int lcd_backlight_timeout_cb(int timerid, void *privdata)
struct lcddev *dev = (struct lcddev *)privdata; struct lcddev *dev = (struct lcddev *)privdata;
dev->backlight_timeout = NULL; dev->backlight_timeout = NULL;
lcd_pagecallback(dev, LCDPAGE_EVENT_BACKLIGHT); lcd_set_backlight(dev, 0);
if (dev->backlight_timeout == NULL) {
lcd_backlight(dev, 0);
}
return -1; /* singleshot */ return -1; /* singleshot */
} }
int lcd_trigger_backlight(struct lcddev *dev, int enable, int timeout_ms) int lcd_set_backlight(struct lcddev *dev, int enable)
{ {
if (dev->backlight_timeout != NULL) { if (dev->backlight_timeout != NULL) {
event_remove_timeout(dev->backlight_timeout); event_remove_timeout(dev->backlight_timeout);
dev->backlight_timeout = NULL; dev->backlight_timeout = NULL;
} }
if (!enable) {
lcd_pagecallback(dev, LCDPAGE_EVENT_BACKLIGHT);
/* callback re-enabled backlight */
if (dev->backlight_timeout != NULL) {
return 0;
}
}
int retval = lcd_backlight(dev, enable); int retval = lcd_backlight(dev, enable);
if (enable && (timeout_ms != -1)) { if (enable) {
dev->backlight_timeout_ms = timeout_ms; /* start backlight timeout */
dev->backlight_timeout = event_add_timeout_ms(timeout_ms * 1000, lcd_backlight_timeout_cb, 0, dev); dev->backlight_timeout = event_add_timeout_ms(dev->backlight_timeout_ms, lcd_backlight_timeout_cb, 0, dev);
} else {
/* disable updates (display is not visible) */
if (dev->update_timeout != NULL) {
event_remove_timeout(dev->update_timeout);
dev->update_timeout = NULL;
}
/* disable scrolling (display is not visible) */
if (dev->scroll_timeout != NULL) {
event_remove_timeout(dev->scroll_timeout);
dev->scroll_timeout = NULL;
}
} }
return retval; return retval;
@ -378,6 +398,20 @@ static int lcd_update_timeout_cb(int timerid, void *privdata)
return -1; /* singleshot */ return -1; /* singleshot */
} }
static void lcd_update_start(struct lcddev *dev, int update_ms)
{
dev->update_ms = update_ms;
if (dev->update_timeout != NULL) {
event_remove_timeout(dev->update_timeout);
dev->update_timeout = NULL;
}
if (update_ms > 0) {
dev->update_timeout = event_add_timeout_ms(update_ms, lcd_update_timeout_cb, 0, dev);
}
}
static int lcd_read_cb(int fd, void *privdata) static int lcd_read_cb(int fd, void *privdata)
{ {
struct lcddev *dev = (struct lcddev *)privdata; struct lcddev *dev = (struct lcddev *)privdata;
@ -445,12 +479,6 @@ static int lcd_scroll_timeout_cb(int timerid, void *privdata)
struct lcddev *dev = (struct lcddev *)privdata; struct lcddev *dev = (struct lcddev *)privdata;
int i, reset_pos = 0; int i, reset_pos = 0;
/* disable scrolling if backlight is off (display is not visible) */
if (dev->backlight_enabled == 0) {
dev->scroll_timeout = NULL;
return -1;
}
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
int line_pos = dev->scroll_pos; int line_pos = dev->scroll_pos;
if (line_pos < 0) if (line_pos < 0)
@ -478,49 +506,52 @@ static int lcd_scroll_timeout_cb(int timerid, void *privdata)
return 0; return 0;
} }
int lcd_setlines(struct lcddev *dev, const char *line1, const char *line2) static void lcd_scroll_start(struct lcddev *dev)
{ {
int i;
for (i = 0; i < 2; i++) {
if (dev->line_data[i] != NULL) {
free((void *)dev->line_data[i]);
}
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]);
if ((dev->line_length[0] > 16) || (dev->line_length[1] > 16)) {
if (dev->scroll_timeout == NULL) {
dev->scroll_pos = 0;
dev->scroll_timeout = event_add_timeout_ms(LCD_SCROLL_SPEED, lcd_scroll_timeout_cb, 0, dev);
}
} else {
if (dev->scroll_timeout != NULL) { if (dev->scroll_timeout != NULL) {
event_remove_timeout(dev->scroll_timeout); event_remove_timeout(dev->scroll_timeout);
dev->scroll_timeout = NULL; dev->scroll_timeout = NULL;
} }
if ((dev->line_length[0] > 16) || (dev->line_length[1] > 16)) {
dev->scroll_timeout = event_add_timeout_ms(LCD_SCROLL_SPEED, lcd_scroll_timeout_cb, 0, dev);
}
}
int lcd_setlines(struct lcddev *dev, const char *line1, const char *line2)
{
int i;
int line_length[2] = { 0, 0 };
const char *line[2] = { line1, line2 };
for (i = 0; i < 2; i++) {
if (line[i] != NULL) {
line_length[i] = strlen(line[i]);
if ((line_length[i] == dev->line_length[i]) && (dev->line_data[i] != NULL)) {
if (memcmp(line[i], dev->line_data[i], line_length[i]) == 0) {
/* same data, no update needed */
continue;
}
}
}
if (dev->line_data[i] != NULL) {
free((void *)dev->line_data[i]);
dev->line_data[i] = NULL;
}
if (line[i] != NULL) {
dev->line_data[i] = strdup(line[i]);
}
dev->line_length[i] = line_length[i];
if (dev->backlight_enabled) {
lcd_setline(dev, i, dev->line_length[i], dev->line_data[i]);
dev->scroll_pos = 0;
lcd_scroll_start(dev);
}
} }
return 0; return 0;
@ -541,8 +572,12 @@ static void lcd_pagecallback(struct lcddev *dev, int event)
} }
if ((dev->backlight_enabled == 0x00) && ((event == LCDPAGE_EVENT_BUTTON1) || (event == LCDPAGE_EVENT_BUTTON2))) { if ((dev->backlight_enabled == 0x00) && ((event == LCDPAGE_EVENT_BUTTON1) || (event == LCDPAGE_EVENT_BUTTON2))) {
lcd_trigger_backlight(dev, 1, dev->backlight_timeout_ms); lcd_set_backlight(dev, 1);
return;
event = LCDPAGE_EVENT_UPDATE;
/* restart scrolling if needed */
lcd_scroll_start(dev);
} }
int next; int next;
@ -551,19 +586,7 @@ static void lcd_pagecallback(struct lcddev *dev, int event)
int retval = dev->current_page->callback(dev, event, dev->current_page->privdata); int retval = dev->current_page->callback(dev, event, dev->current_page->privdata);
log_print(LOG_DEBUG, "%s: cb(%p, 0x%x) => 0x%x", __FUNCTION__, dev->current_page, event, retval); log_print(LOG_DEBUG, "%s: cb(%p, 0x%x) => 0x%x", __FUNCTION__, dev->current_page, event, retval);
next = 0; next = (retval == LCDPAGE_COMMAND_NEXT);
if ((event == LCDPAGE_EVENT_ENTER) && (retval == -1)) {
next = 1;
} else if (retval == LCDPAGE_COMMAND_NEXT) {
next = 1;
}
if (dev->update_timeout != NULL) {
event_remove_timeout(dev->update_timeout);
dev->update_timeout = NULL;
}
if (next) { if (next) {
struct lcdpage *page = dev->current_page; struct lcdpage *page = dev->current_page;
@ -573,19 +596,30 @@ static void lcd_pagecallback(struct lcddev *dev, int event)
page = list_entry(page->list.next->next, struct lcdpage, list); page = list_entry(page->list.next->next, struct lcdpage, list);
} }
/* no other page ready */
if (page == dev->current_page) { if (page == dev->current_page) {
next = 0;
break; break;
} }
if (next) { /* remove update interval for next page */
if (dev->update_timeout != NULL) {
event_remove_timeout(dev->update_timeout);
dev->update_timeout = NULL;
}
/* remove scroll interval for next page */
if (dev->scroll_timeout != NULL) {
event_remove_timeout(dev->scroll_timeout);
dev->scroll_timeout = NULL;
}
dev->current_page->callback(dev, LCDPAGE_EVENT_EXIT, dev->current_page->privdata); dev->current_page->callback(dev, LCDPAGE_EVENT_EXIT, dev->current_page->privdata);
dev->current_page = page; dev->current_page = page;
event = LCDPAGE_EVENT_ENTER; event = LCDPAGE_EVENT_ENTER;
}
} else if ((retval != 0x00) && (dev->backlight_enabled != 0)) { /* retval is update interval */
dev->update_timeout = event_add_timeout_ms(retval, lcd_update_timeout_cb, 0, dev); } else if ((event != LCDPAGE_EVENT_BACKLIGHT) && (event != LCDPAGE_EVENT_EXIT)) {
lcd_update_start(dev, retval);
} }
} while (next); } while (next);
} }
@ -626,7 +660,7 @@ int lcd_addpage_cb(struct lcddev *dev,
return 0; return 0;
} }
struct lcddev * lcd_open(const char *devicename) struct lcddev * lcd_open(const char *devicename, int backlight_timeout)
{ {
struct lcddev *dev = malloc(sizeof(struct lcddev)); struct lcddev *dev = malloc(sizeof(struct lcddev));
if (dev == NULL) { if (dev == NULL) {
@ -654,6 +688,7 @@ struct lcddev * lcd_open(const char *devicename)
} }
dev->read_event = event_add_readfd(NULL, dev->fd, lcd_read_cb, dev); dev->read_event = event_add_readfd(NULL, dev->fd, lcd_read_cb, dev);
dev->backlight_timeout_ms = backlight_timeout * 1000;
lcd_reset(dev); lcd_reset(dev);
return dev; return dev;

7
lcd.h
View File

@ -3,10 +3,10 @@
struct lcddev; /* private data */ struct lcddev; /* private data */
struct lcddev * lcd_open(const char *devicename); struct lcddev * lcd_open(const char *devicename, int backlight_timeout);
void lcd_close(struct lcddev *dev); void lcd_close(struct lcddev *dev);
int lcd_trigger_backlight(struct lcddev *dev, int enable, int timeout); int lcd_set_backlight(struct lcddev *dev, int enable);
int lcd_setlines(struct lcddev *dev, const char *line1, const char *line2); int lcd_setlines(struct lcddev *dev, const char *line1, const char *line2);
#define LCDPAGE_EVENT_BUTTON1 0xFFFFFF01 /* button "enter" pressed */ #define LCDPAGE_EVENT_BUTTON1 0xFFFFFF01 /* button "enter" pressed */
@ -22,7 +22,4 @@ int lcd_addpage_cb(struct lcddev *dev,
int (*event_callback)(struct lcddev *dev, int event, void *privdata), int (*event_callback)(struct lcddev *dev, int event, void *privdata),
void *event_privdata); void *event_privdata);
int lcdpage_init(struct lcddev *dev);
void lcdpage_free(void);
#endif /* _LCD_H_ */ #endif /* _LCD_H_ */

View File

@ -27,8 +27,7 @@
#include <time.h> #include <time.h>
#include "lcd.h" #include "lcd.h"
#include "lcdpage.h"
#define LCD_TIMEOUT 15
/* /*
* system: * system:
@ -72,16 +71,23 @@ static int lcdpage_system(struct lcddev *dev, int event, void *privdata)
memset(line1, 0x00, sizeof(line1)); memset(line1, 0x00, sizeof(line1));
memset(line2, 0x00, sizeof(line2)); memset(line2, 0x00, sizeof(line2));
if (event == LCDPAGE_EVENT_BUTTON1) { switch (event) {
lcd_trigger_backlight(dev, 1, LCD_TIMEOUT); case LCDPAGE_EVENT_BUTTON1:
lcd_set_backlight(dev, 1);
subpage++; subpage++;
break;
} else if (event == LCDPAGE_EVENT_ENTER) { case LCDPAGE_EVENT_ENTER:
lcd_trigger_backlight(dev, 1, LCD_TIMEOUT); lcd_set_backlight(dev, 1);
subpage = 0; subpage = 0;
break;
} else if (event != LCDPAGE_EVENT_UPDATE) { case LCDPAGE_EVENT_BACKLIGHT:
case LCDPAGE_EVENT_EXIT:
return 0; return 0;
default:
break;
} }
if (subpage == 0) { if (subpage == 0) {
@ -167,7 +173,7 @@ static int lcdpage_system(struct lcddev *dev, int event, void *privdata)
} }
snprintf(line2, sizeof(line2), " %1.2f %1.2f %1.2f", loadavg[0], loadavg[1], loadavg[2]); snprintf(line2, sizeof(line2), " %1.2f %1.2f %1.2f", loadavg[0], loadavg[1], loadavg[2]);
lcd_setlines(dev, "LoadAVG:", line2); lcd_setlines(dev, "Load Average:", line2);
retval = 1000; retval = 1000;
} else { } else {
@ -182,16 +188,23 @@ static int lcdpage_network(struct lcddev *dev, int event, void *privdata)
{ {
static int subpage; static int subpage;
if (event == LCDPAGE_EVENT_BUTTON1) { switch (event) {
lcd_trigger_backlight(dev, 1, LCD_TIMEOUT); case LCDPAGE_EVENT_BUTTON1:
lcd_set_backlight(dev, 1);
subpage++; subpage++;
break;
} else if (event == LCDPAGE_EVENT_ENTER) { case LCDPAGE_EVENT_ENTER:
lcd_trigger_backlight(dev, 1, LCD_TIMEOUT); lcd_set_backlight(dev, 1);
subpage = 0; subpage = 0;
break;
} else if (event != LCDPAGE_EVENT_UPDATE) { case LCDPAGE_EVENT_BACKLIGHT:
case LCDPAGE_EVENT_EXIT:
return 0; return 0;
default:
break;
} }
switch (subpage) { switch (subpage) {

9
lcdpage.h Normal file
View File

@ -0,0 +1,9 @@
#ifndef _LCDPAGE_H_
#define _LCDPAGE_H_
#include "lcd.h"
int lcdpage_init(struct lcddev *dev);
void lcdpage_free(void);
#endif /* _LCDPAGE_H_ */

21
pic.c
View File

@ -174,23 +174,32 @@ static int lcdpage_case(struct lcddev *lcd, int event, void *privdata)
{ {
struct picdev *dev = (struct picdev *)privdata; struct picdev *dev = (struct picdev *)privdata;
if (event == LCDPAGE_EVENT_BUTTON1) { switch (event) {
case LCDPAGE_EVENT_BUTTON1:
return LCDPAGE_COMMAND_NEXT; return LCDPAGE_COMMAND_NEXT;
} else if (event == LCDPAGE_EVENT_BUTTON2) { case LCDPAGE_EVENT_BUTTON2:
{
int fan_speed = PIC_CMD_FANSPEED_0 + dev->fan_speed +1; int fan_speed = PIC_CMD_FANSPEED_0 + dev->fan_speed +1;
if (fan_speed > PIC_CMD_FANSPEED_5) if (fan_speed > PIC_CMD_FANSPEED_5)
fan_speed = PIC_CMD_FANSPEED_0; fan_speed = PIC_CMD_FANSPEED_0;
pic_set_fanspeed(dev, fan_speed); pic_set_fanspeed(dev, fan_speed);
lcd_trigger_backlight(lcd, 1, 15); lcd_set_backlight(lcd, 1);
break;
}
} else if (event == LCDPAGE_EVENT_ENTER) { case LCDPAGE_EVENT_ENTER:
lcd_trigger_backlight(lcd, 1, 15); lcd_set_backlight(lcd, 1);
break;
} else if (event != LCDPAGE_EVENT_UPDATE) { case LCDPAGE_EVENT_BACKLIGHT:
case LCDPAGE_EVENT_EXIT:
return 0; return 0;
default:
break;
} }
char line1_ok[] = "FAN(OK): TEMP:"; char line1_ok[] = "FAN(OK): TEMP:";

15
qnapd.c
View File

@ -26,9 +26,10 @@
#include <signal.h> #include <signal.h>
#include "configfile.h" #include "configfile.h"
#include "disktimeout.h" #include "diskwatch.h"
#include "event.h" #include "event.h"
#include "lcd.h" #include "lcd.h"
#include "lcdpage.h"
#include "logging.h" #include "logging.h"
#include "pic.h" #include "pic.h"
#include "pidfile.h" #include "pidfile.h"
@ -38,6 +39,8 @@
#define DEFAULT_LOGFILE "qnapd.log" #define DEFAULT_LOGFILE "qnapd.log"
#define DEFAULT_PIDFILE "qnapd.pid" #define DEFAULT_PIDFILE "qnapd.pid"
#define LCD_TIMEOUT 15
static struct option opts[] = { static struct option opts[] = {
{ "config", 1, 0, 'c' }, { "config", 1, 0, 'c' },
{ "debug", 0, 0, 'd' }, { "debug", 0, 0, 'd' },
@ -140,7 +143,11 @@ int main(int argc, char *argv[])
do { do {
const char *devicename = config_get_string("global", "lcddevice", NULL); const char *devicename = config_get_string("global", "lcddevice", NULL);
if (devicename != NULL) { if (devicename != NULL) {
lcd = lcd_open(devicename); int lcdtimeout;
config_get_int("global", "lcdtimeout", &lcdtimeout, LCD_TIMEOUT);
lcd = lcd_open(devicename, lcdtimeout);
if (lcd == NULL) { if (lcd == NULL) {
break; break;
} }
@ -158,14 +165,14 @@ int main(int argc, char *argv[])
} }
} }
if (disktimeout_init() < 0) if (diskwatch_init(lcd) < 0)
break; break;
/* exited on restart / SIGUSR1 */ /* exited on restart / SIGUSR1 */
event_loop(check_restart, NULL, NULL); event_loop(check_restart, NULL, NULL);
} while (0); } while (0);
disktimeout_exit(); diskwatch_exit();
if (pic != NULL) { if (pic != NULL) {
pic_close(pic); pic_close(pic);

View File

@ -5,11 +5,14 @@
#lcddevice dummy #lcddevice dummy
lcdtimeout 15
pidfile qnapd.pid pidfile qnapd.pid
logfile qnapd.log logfile qnapd.log
[disktimeout] [diskwatch]
check_interval 60 check_interval 60
hddtemp_server 127.0.0.1:7634
#disk /dev/sda,7200 #disk /dev/sda,7200
#disk /dev/sdb,7200 #disk /dev/sdb,7200