Package: qcontrol Version: 0.4.2-1 Severity: wishlist Hi Frans,
Can you please add support for the QNAP TS-119 and TS-219. I've attached a patch. -- Martin Michlmayr http://www.cyrius.com/
diff -u qcontrol-0.4.2/Makefile qcontrol-0.4.2/Makefile --- qcontrol-0.4.2/Makefile +++ qcontrol-0.4.2/Makefile @@ -1,7 +1,7 @@ CFLAGS=-Os -Wall -I /usr/include/lua5.1 LDFLAGS=-llua5.1 -lpthread LDFLAGS_UDEB=-lpthread -lm -ldl -SOURCES=qcontrol.c ts209.c ts409.c evdev.c +SOURCES=qcontrol.c ts209.c ts219.c ts409.c evdev.c OBJECTS=$(SOURCES:.c=.o) EXECUTABLE=qcontrol diff -u qcontrol-0.4.2/debian/qcontrol.1 qcontrol-0.4.2/debian/qcontrol.1 --- qcontrol-0.4.2/debian/qcontrol.1 +++ qcontrol-0.4.2/debian/qcontrol.1 @@ -1,7 +1,7 @@ .TH QCONTROL 1 "2008-08-10" "Debian Project" "" .SH NAME -qcontrol \- Hardware control for QNAP TS-109, TS-209 and TS-409 +qcontrol \- Hardware control for QNAP Turbo Station .SH SYNOPSIS \fBqcontrol\fB -d @@ -18,8 +18,9 @@ therefore advised when using qcontrol as a real daemon to monitor and control a device. .PP -Currently supported devices are the QNAP TS-109, QNAP TS-209 and QNAP -TS-409, but support for additional devices may be added in future releases. +Currently supported devices are the QNAP TS-109, QNAP TS-119, QNAP TS-209, +QNAP TS-219, QNAP TS-409 and QNAP TS-409U, but support for additional +devices may be added in future releases. .SH BASIC USAGE First a control process needs to be started that opens a socket through @@ -65,7 +66,7 @@ will alternate between green and red instead of on and off. .IP "\fBpowerled\fP" -Controls the power led (not available on TS-409). +Controls the power led (not available on TS-409 and TS-409U). Values: off | on | 1hz | 2hz diff -u qcontrol-0.4.2/debian/README.Debian qcontrol-0.4.2/debian/README.Debian --- qcontrol-0.4.2/debian/README.Debian +++ qcontrol-0.4.2/debian/README.Debian @@ -6,7 +6,7 @@ background. Because of the missing daemon mode, the functionality to monitor temperature -and control fan speed (TS-209/409) has been disabled in the config file. +and control fan speed (TS-209/219/409) has been disabled in the config file. See the original config file in ./examples/ for how it could be done. This Debian package includes an init script that will change the leds and diff -u qcontrol-0.4.2/debian/qcontrol.postinst qcontrol-0.4.2/debian/qcontrol.postinst --- qcontrol-0.4.2/debian/qcontrol.postinst +++ qcontrol-0.4.2/debian/qcontrol.postinst @@ -7,6 +7,8 @@ case $device in "QNAP TS-109/TS-209") ln -s qcontrol/ts209.lua /etc/qcontrol.conf ;; + "QNAP TS-119/TS-219") + ln -s qcontrol/ts219.lua /etc/qcontrol.conf ;; "QNAP TS-409") ln -s qcontrol/ts409.lua /etc/qcontrol.conf ;; esac diff -u qcontrol-0.4.2/debian/control qcontrol-0.4.2/debian/control --- qcontrol-0.4.2/debian/control +++ qcontrol-0.4.2/debian/control @@ -9,7 +9,7 @@ Package: qcontrol Architecture: arm armel Depends: ${shlibs:Depends}, ${misc:Depends} -Description: hardware control for QNAP TS-109, TS-209 and TS-409 +Description: hardware control for QNAP Turbo Station devices Allows to send commands to the microcontroller of supported devices, for example to change leds or sound a buzzer. . @@ -17,7 +17,8 @@ presses or temperature, with events triggering actions defined in the configuration file. . - Supported devices at this time are the QNAP TS-109, TS-209 and TS409 + Supported devices at this time are the QNAP TS-109, TS-119, TS-209 + TS-219, TS-409 and TS-409U. but the code is extensible so more devices may be added in future releases. . @@ -30,3 +31,3 @@ XC-Package-Type: udeb -Description: hardware control for QNAP TS-109, TS-209 and TS-409 +Description: hardware control for QNAP Turbo Station devices Allows to change status leds or sound the buzzer of supported devices. diff -u qcontrol-0.4.2/debian/init.d qcontrol-0.4.2/debian/init.d --- qcontrol-0.4.2/debian/init.d +++ qcontrol-0.4.2/debian/init.d @@ -8,7 +8,7 @@ # Should-Stop: # Default-Start: 2 3 4 5 # Default-Stop: 0 6 -# Short-Description: Change status leds for QNAP TS-109/TS-209/TS-409 +# Short-Description: Change status leds for QNAP TS-109/TS-119/TS-209/TS-219/TS-409 ### END INIT INFO PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin @@ -70,7 +70,7 @@ device=$(grep "Hardware[[:space:]]*:" /proc/cpuinfo 2>/dev/null | \ head -n1 | sed "s/^[^:]*: //") case $device in - "QNAP TS-109/TS-209") + "QNAP TS-109/TS-209" | "QNAP TS-119/TS-219") test_event_dev || exit 0 if pid=$(qcontrol_start); then log_action_msg "System boot completed" @@ -111,7 +111,7 @@ device=$(grep "Hardware[[:space:]]*:" /proc/cpuinfo 2>/dev/null | \ head -n1 | sed "s/^[^:]*: //") case $device in - "QNAP TS-109/TS-209") + "QNAP TS-109/TS-209" | "QNAP TS-119/TS-219") test_event_dev || exit 0 if pid=$(qcontrol_start); then log_action_msg "Preparing for shutdown" diff -u qcontrol-0.4.2/debian/udeb/qcommand qcontrol-0.4.2/debian/udeb/qcommand --- qcontrol-0.4.2/debian/udeb/qcommand +++ qcontrol-0.4.2/debian/udeb/qcommand @@ -7,7 +7,7 @@ device=$(grep "Hardware[[:space:]]*:" /proc/cpuinfo 2>/dev/null | \ head -n1 | sed "s/^[^:]*: //") case $device in - "QNAP TS-109/TS-209" | "QNAP TS-409") + "QNAP TS-109/TS-209" | "QNAP TS-119/TS-219" | "QNAP TS-409") # Success or continue [ "$1" = "-t" ] && exit 0 || true ;; *) diff -u qcontrol-0.4.2/debian/udeb/debian-installer-startup.d/S99qcontrol qcontrol-0.4.2/debian/udeb/debian-installer-startup.d/S99qcontrol --- qcontrol-0.4.2/debian/udeb/debian-installer-startup.d/S99qcontrol +++ qcontrol-0.4.2/debian/udeb/debian-installer-startup.d/S99qcontrol @@ -6,6 +6,8 @@ case $device in "QNAP TS-109/TS-209") mv /etc/qcontrol/ts209.lua /etc/qcontrol.conf ;; + "QNAP TS-119/TS-219") + mv /etc/qcontrol/ts219.lua /etc/qcontrol.conf ;; "QNAP TS-409") mv /etc/qcontrol/ts409.lua /etc/qcontrol.conf ;; esac only in patch2: unchanged: --- qcontrol-0.4.2.orig/qcontrol.c +++ qcontrol-0.4.2/qcontrol.c @@ -54,11 +54,13 @@ struct piccommand **commands; extern struct picmodule ts209_module; +extern struct picmodule ts219_module; extern struct picmodule ts409_module; extern struct picmodule evdev_module; struct picmodule *modules[] = { &ts209_module, + &ts219_module, &ts409_module, &evdev_module, NULL only in patch2: unchanged: --- qcontrol-0.4.2.orig/ts219.c +++ qcontrol-0.4.2/ts219.c @@ -0,0 +1,341 @@ +/* + * Copyright (C) 2007-2008 Byron Bradley (byron.bbrad...@gmail.com) + * Copyright (C) 2008, 2009 Martin Michlmayr (t...@cyrius.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <fcntl.h> +#include <lua.h> +#include <lualib.h> +#include <lauxlib.h> +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <termios.h> +#include <unistd.h> +#include <linux/input.h> + +#include "picmodule.h" + +static int serial; +static struct termios oldtio, newtio; +static pthread_t ts219_thread; + +static int serial_read(char *buf, int len) +{ + int err; + + err = read(serial, buf, len); + buf[err] = 0; + + return err; +} + +static int serial_write(char *buf, int len) +{ + int err; + + err = write(serial, buf, len); + + return err; +} + +int ts219_read_serial_events() +{ + char buf[100]; + int err = serial_read(buf, 100); + if (err < 0) + return err; + switch (buf[0]) { + case 0x40: + call_function("power_button", "%d", 3); + break; + case 0x73: + case 0x75: + case 0x77: + case 0x79: + call_function("fan_error", ""); + break; + case 0x74: + case 0x76: + case 0x78: + case 0x7a: + call_function("fan_normal", ""); + break; + case 0x80 ... 0x8f: /* 0 - 15 */ + case 0x90 ... 0x9f: /* 16 - 31 */ + case 0xa0 ... 0xaf: /* 32 - 47 */ + case 0xb0 ... 0xbf: /* 48 - 63 */ + case 0xc0 ... 0xc6: /* 64 - 70 */ + call_function("temp", "%d", buf[0] - 128); + break; + case 0x38: /* 71 - 79 */ + call_function("temp", "%d", 75); + break; + case 0x39: /* 80 or higher */ + call_function("temp", "%d", 80); + break; + default: + fprintf(stderr, "(PIC 0x%x) unknown command from PIC\n", buf[0]); + } + + return -1; +} + +static void *serial_poll(void *tmp) +{ + int err; + fd_set rset; + + FD_ZERO(&rset); + FD_SET(serial, &rset); + + for (;;) { + err = select(serial + 1, &rset, NULL, NULL, NULL); + if (err <= 0) { + FD_SET(serial, &rset); + continue; + } + ts219_read_serial_events(); + FD_SET(serial, &rset); + } + + return NULL; +} + +static int set_nonblock(int fd) +{ + int flags = fcntl(fd, F_GETFL, 0); + if (flags < 0) + flags = 0; + return fcntl(fd, F_SETFL, flags | O_NONBLOCK); +} + +static int serial_open(char *device) +{ + char buf[100]; + int err; + + if ((serial = open(device , O_RDWR)) < 0) { + sprintf(buf, "Failed to open %s", device); + perror(buf); + return -1; + } + err = set_nonblock(serial); + if (err < 0) { + perror("Error setting nonblock"); + return -1; + } + + tcgetattr(serial, &oldtio); + memset(&newtio, 0, sizeof(newtio)); + + newtio.c_iflag |= IGNBRK; + newtio.c_lflag &= ~(ISIG | ICANON | ECHO); + newtio.c_cflag = B19200 | CS8 | CLOCAL | CREAD; + newtio.c_cc[VMIN] = 1; + newtio.c_cc[VTIME] = 0; + cfsetospeed(&newtio, B19200); + cfsetispeed(&newtio, B19200); + + err = tcsetattr(serial, TCSANOW, &newtio); + if (err < 0) { + sprintf(buf, "Failed to set attributes for %s", device); + perror(buf); + return -1; + } + + return 0; +} + +static void serial_close() +{ + tcsetattr(serial, TCSANOW, &oldtio); + close(serial); +} + +static int ts219_powerled(int argc, const char **argv) +{ + char code = 0; + + if (argc != 1) + return -1; + + if (strcmp(argv[0], "on") == 0) + code = 0x4d; + else if (strcmp(argv[0], "1hz") == 0) + code = 0x4e; + else if (strcmp(argv[0], "2hz") == 0) + code = 0x4c; + else if (strcmp(argv[0], "off") == 0) + code = 0x4b; + else + return -1; + + return serial_write(&code, 1); + return 0; +} + +static int ts219_statusled(int argc, const char **argv) +{ + char code = 0; + + if (argc != 1) + return -1; + + if (strcmp(argv[0], "red2hz") == 0) + code = 0x54; + else if (strcmp(argv[0], "green2hz") == 0) + code = 0x55; + else if (strcmp(argv[0], "greenon") == 0) + code = 0x56; + else if (strcmp(argv[0], "redon") == 0) + code = 0x57; + else if (strcmp(argv[0], "greenred2hz") == 0) + code = 0x58; + else if (strcmp(argv[0], "off") == 0) + code = 0x59; + else if (strcmp(argv[0], "green1hz") == 0) + code = 0x5a; + else if (strcmp(argv[0], "red1hz") == 0) + code = 0x5b; + else if (strcmp(argv[0], "greenred1hz") == 0) + code = 0x5c; + else + return -1; + + return serial_write(&code, 1); + return 0; +} + +static int ts219_buzz(int argc, const char **argv) +{ + char code = 0; + + if (argc != 1) + return -1; + + if (strcmp(argv[0], "short") == 0) + code = 0x50; + else if (strcmp(argv[0], "long") == 0) + code = 0x51; + else + return -1; + + return serial_write(&code, 1); + return 0; +} + +static int ts219_fanspeed(int argc, const char **argv) +{ + char code = 0; + + if (argc != 1) + return -1; + + if (strcmp(argv[0], "stop") == 0) + code = 0x30; + else if (strcmp(argv[0], "silence") == 0) + code = 0x31; + else if (strcmp(argv[0], "low") == 0) + code = 0x32; + else if (strcmp(argv[0], "medium") == 0) + code = 0x33; + else if (strcmp(argv[0], "high") == 0) + code = 0x34; + else if (strcmp(argv[0], "full") == 0) + code = 0x35; + else + return -1; + + return serial_write(&code, 1); + return 0; +} + +static int ts219_usbled(int argc, const char **argv) +{ + char code = 0; + + if (argc != 1) + return -1; + + if (strcmp(argv[0], "on") == 0) + code = 0x60; + else if (strcmp(argv[0], "8hz") == 0) + code = 0x61; + else if (strcmp(argv[0], "off") == 0) + code = 0x62; + else + return -1; + + return serial_write(&code, 1); + return 0; +} + +int ts219_init(int argc, const char **argv) +{ + int err; + + if (argc > 0) { + printf("%s: module does not take any arguments\n", __func__); + return -1; + } + + err = serial_open("/dev/ttyS1"); + if (err < 0) + return err; + + err = register_command("statusled", + "Change the status LED", + "Change the status LED, options are:\n" + "\tred2hz\n\tgreen2hz\n\tgreenon\n\tredon\n" + "\tgreenred2hz\n\toff\n\tgreen1hz\n\tred1hz\n", + ts219_statusled); + err = register_command("powerled", + "Change the power LED", + "Change the power LED, options are:\n" + "\ton\n\toff\n\t1hz\n\t2hz\n", + ts219_powerled); + err = register_command("buzzer", + "Buzz", + "Buzz, options are:\n" + "\tshort\n\tlong\n", + ts219_buzz); + err = register_command("fanspeed", + "Set the fanspeed", + "Set the fanspeed, options are:\n" + "\tstop\n\tsilence\n\tlow\n\tmedium\n" + "\thigh\n\tfull\n", + ts219_fanspeed); + err = register_command("usbled", + "Set the usbled", + "Set the usbled, options are:\n" + "\ton\n\t8hz\n\toff\n", + ts219_usbled); + + return pthread_create(&ts219_thread, NULL, serial_poll, NULL); +} + +void ts219_exit(void) +{ + serial_close(); +} + +struct picmodule ts219_module = { + .name = "ts219", + .init = ts219_init, + .exit = ts219_exit, +}; only in patch2: unchanged: --- qcontrol-0.4.2.orig/debian/configs/ts219.lua +++ qcontrol-0.4.2/debian/configs/ts219.lua @@ -0,0 +1,39 @@ +--[[ + Debian configuration file for qcontrol (LUA syntax) + Supports both QNAP TS-119 and TS-219. +--]] + +register("ts219") + +-- Requires CONFIG_KEYBOARD_GPIO enabled in the kernel and +-- the kernel module gpio_keys to be loaded. +register("evdev", "/dev/input/by-path/platform-gpio-keys-event-", + 408, "restart_button", + 133, "media_button") + +function power_button( time ) + os.execute("poweroff") +end + +function restart_button( time ) + os.execute("reboot") +end + +function media_button( time ) + piccmd("usbled", "8hz") +end + +--[[ + Fan and temperature control are left disabled until qcontrol + gets a proper daemon mode. + Empty functions are needed to avoid errors. +--]] +function fan_error( ) +end + +function fan_normal( ) +end + +function temp( temp ) + print("ts219 temperature:", temp) +end