more work
This commit is contained in:
parent
031b7e540d
commit
606a3306c5
@ -1,7 +0,0 @@
|
|||||||
#ifndef _DISKTIMEOUT_H_
|
|
||||||
#define _DISKTIMEOUT_H_
|
|
||||||
|
|
||||||
int disktimeout_exit(void);
|
|
||||||
int disktimeout_init(void);
|
|
||||||
|
|
||||||
#endif /* _DISKTIMEOUT_H_ */
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
entry = list_entry(dwatch->disk_list.next, struct disk_entry, list);
|
||||||
}
|
}
|
||||||
|
|
||||||
strncpy((char *)entry->device, tokens->field[0], sizeof(entry->device));
|
switch (event) {
|
||||||
|
case LCDPAGE_EVENT_BUTTON1:
|
||||||
|
if (entry->list.next == &dwatch->disk_list) {
|
||||||
|
entry = NULL;
|
||||||
|
return LCDPAGE_COMMAND_NEXT;
|
||||||
|
}
|
||||||
|
|
||||||
char *tmp;
|
entry = list_entry(entry->list.next, struct disk_entry, list);
|
||||||
entry->timeout = strtol(tokens->field[1], &tmp, 0);
|
lcd_set_backlight(lcd, 1);
|
||||||
if (*tmp != '\0' && !isspace(*tmp)) {
|
break;
|
||||||
log_print(LOG_WARN, "%s(): invalid timeout value '%s'", __FUNCTION__, tokens->field[1]);
|
|
||||||
free(entry);
|
case LCDPAGE_EVENT_ENTER:
|
||||||
return -1;
|
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;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
entry->flags = 0;
|
char line1[32];
|
||||||
entry->sectors_rd = 0;
|
char line2[32];
|
||||||
entry->sectors_wr = 0;
|
|
||||||
|
|
||||||
entry->timeout_event = event_add_timeout_ms(entry->timeout * 1000, diskto_timeout_cb, 0, (void *)entry);
|
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;
|
||||||
|
|
||||||
log_print(LOG_INFO, "disktimeout: watching '%s' (standby timeout: %ds)", entry->device, entry->timeout);
|
snprintf(line2, sizeof(line2), "RUN -%02d:%02d:%02d", hours, minutes, timeout);
|
||||||
list_add_tail(&entry->list, &disk_list);
|
}
|
||||||
return 0;
|
|
||||||
|
} 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);
|
entry->flags &= ~(F_STANDBY);
|
||||||
|
entry->standby_timeout = now + entry->timeout_sec;
|
||||||
|
|
||||||
/* device is not in standby mode, start timer */
|
/* drive is active, and timeout is up */
|
||||||
if (entry->timeout_event == NULL) {
|
} else if (now >= entry->standby_timeout) {
|
||||||
entry->timeout_event = event_add_timeout_ms(entry->timeout * 1000, diskto_timeout_cb, 0, (void *)entry);
|
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;
|
||||||
}
|
}
|
||||||
entry->flags &= ~(F_STANDBY);
|
|
||||||
}
|
|
||||||
|
|
||||||
} 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 diskwatch *dwatch = (struct diskwatch *)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) {
|
||||||
|
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;
|
struct disk_entry *entry, *tmp;
|
||||||
|
|
||||||
list_for_each_entry_safe(entry, tmp, &disk_list, list) {
|
list_for_each_entry_safe(entry, tmp, &dwatch->disk_list, list) {
|
||||||
if (entry->timeout_event != NULL) {
|
|
||||||
event_remove_timeout(entry->timeout_event);
|
|
||||||
entry->timeout_event = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
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
9
diskwatch.h
Normal 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_ */
|
169
lcd.c
169
lcd.c
@ -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,48 +506,51 @@ static int lcd_scroll_timeout_cb(int timerid, void *privdata)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void lcd_scroll_start(struct lcddev *dev)
|
||||||
|
{
|
||||||
|
if (dev->scroll_timeout != NULL) {
|
||||||
|
event_remove_timeout(dev->scroll_timeout);
|
||||||
|
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 lcd_setlines(struct lcddev *dev, const char *line1, const char *line2)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
int line_length[2] = { 0, 0 };
|
||||||
|
const char *line[2] = { line1, line2 };
|
||||||
|
|
||||||
for (i = 0; i < 2; i++) {
|
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) {
|
if (dev->line_data[i] != NULL) {
|
||||||
free((void *)dev->line_data[i]);
|
free((void *)dev->line_data[i]);
|
||||||
|
dev->line_data[i] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev->line_data[i] = NULL;
|
if (line[i] != NULL) {
|
||||||
dev->line_length[i] = 0;
|
dev->line_data[i] = strdup(line[i]);
|
||||||
}
|
|
||||||
|
|
||||||
if (line1 != NULL) {
|
|
||||||
dev->line_data[0] = strdup(line1);
|
|
||||||
|
|
||||||
if (dev->line_data[0] != NULL) {
|
|
||||||
dev->line_length[0] = strlen(line1);
|
|
||||||
}
|
}
|
||||||
}
|
dev->line_length[i] = line_length[i];
|
||||||
|
|
||||||
if (line2 != NULL) {
|
if (dev->backlight_enabled) {
|
||||||
dev->line_data[1] = strdup(line2);
|
lcd_setline(dev, i, dev->line_length[i], dev->line_data[i]);
|
||||||
|
|
||||||
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_pos = 0;
|
||||||
dev->scroll_timeout = event_add_timeout_ms(LCD_SCROLL_SPEED, lcd_scroll_timeout_cb, 0, dev);
|
lcd_scroll_start(dev);
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
if (dev->scroll_timeout != NULL) {
|
|
||||||
event_remove_timeout(dev->scroll_timeout);
|
|
||||||
dev->scroll_timeout = NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -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 */
|
||||||
dev->current_page->callback(dev, LCDPAGE_EVENT_EXIT, dev->current_page->privdata);
|
if (dev->update_timeout != NULL) {
|
||||||
dev->current_page = page;
|
event_remove_timeout(dev->update_timeout);
|
||||||
event = LCDPAGE_EVENT_ENTER;
|
dev->update_timeout = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if ((retval != 0x00) && (dev->backlight_enabled != 0)) {
|
/* remove scroll interval for next page */
|
||||||
dev->update_timeout = event_add_timeout_ms(retval, lcd_update_timeout_cb, 0, dev);
|
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 = page;
|
||||||
|
event = LCDPAGE_EVENT_ENTER;
|
||||||
|
|
||||||
|
/* retval is update interval */
|
||||||
|
} 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
7
lcd.h
@ -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_ */
|
||||||
|
51
lcdpage.c
51
lcdpage.c
@ -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:
|
||||||
subpage++;
|
lcd_set_backlight(dev, 1);
|
||||||
|
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:
|
||||||
return 0;
|
case LCDPAGE_EVENT_EXIT:
|
||||||
|
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:
|
||||||
subpage++;
|
lcd_set_backlight(dev, 1);
|
||||||
|
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:
|
||||||
return 0;
|
case LCDPAGE_EVENT_EXIT:
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (subpage) {
|
switch (subpage) {
|
||||||
|
9
lcdpage.h
Normal file
9
lcdpage.h
Normal 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_ */
|
33
pic.c
33
pic.c
@ -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) {
|
||||||
return LCDPAGE_COMMAND_NEXT;
|
case LCDPAGE_EVENT_BUTTON1:
|
||||||
|
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:
|
||||||
return 0;
|
case LCDPAGE_EVENT_EXIT:
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
char line1_ok[] = "FAN(OK): TEMP:";
|
char line1_ok[] = "FAN(OK): TEMP:";
|
||||||
|
15
qnapd.c
15
qnapd.c
@ -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);
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user