diff options
-rw-r--r-- | heartbeatclient.c | 109 | ||||
-rw-r--r-- | openwrt/rhctl/Makefile | 2 | ||||
-rw-r--r-- | options.c | 8 | ||||
-rw-r--r-- | options.h | 1 |
4 files changed, 114 insertions, 6 deletions
diff --git a/heartbeatclient.c b/heartbeatclient.c index 82546b1..7c89248 100644 --- a/heartbeatclient.c +++ b/heartbeatclient.c @@ -38,7 +38,7 @@ int process_cmd(const char* cmd, int fd, cmd_t **cmd_q, client_t* client_lst, op return 0; } -int process_serial(read_buffer_t* buffer, int serial_fd, u_int32_t* time) +int process_serial(read_buffer_t* buffer, int serial_fd, u_int32_t* time, int led_pipe_fd) { log_printf(DEBUG, "received heartbeat data at %d 1/10 s", *time); @@ -73,7 +73,13 @@ int process_serial(read_buffer_t* buffer, int serial_fd, u_int32_t* time) if(strlen(buffer->buf)) { log_printf(INFO, "heartbeat: '%s'", buffer->buf); - *time = 0; + *time = 0; + if(led_pipe_fd >= 0) { + char buf = '1'; + ret = write(led_pipe_fd, &buf, 1); + if(ret == -1 && errno != EAGAIN) + log_printf(WARNING, "write to led process pipe returned with error: %s", strerror(errno)); + } } buffer->offset = 0; @@ -91,7 +97,7 @@ int process_serial(read_buffer_t* buffer, int serial_fd, u_int32_t* time) return ret; } -int main_loop(int serial_fd, int cmd_fd, options_t* opt) +int main_loop(int serial_fd, int cmd_fd, int led_pipe_fd, options_t* opt) { log_printf(NOTICE, "entering main loop"); @@ -164,7 +170,7 @@ int main_loop(int serial_fd, int cmd_fd, options_t* opt) } if(FD_ISSET(serial_fd, &tmpfds)) { - return_value = process_serial(&serial_buffer, serial_fd, &time); + return_value = process_serial(&serial_buffer, serial_fd, &time, led_pipe_fd); if(return_value) break; } @@ -185,6 +191,83 @@ int main_loop(int serial_fd, int cmd_fd, options_t* opt) return return_value; } +int led_process(int pipe_fd, int led_fd) +{ + struct timeval timeout; + char buf; + int ret; + + for(;;) { + ret = read(pipe_fd, &buf, 1); + if(ret == -1 && errno == EAGAIN) + continue; + else if(!ret || ret < 0) { + log_printf(ERROR, "led_process: read returned with error: %s", strerror(errno)); + break; + } + + buf = '1'; + ret = write(led_fd, &buf, 1); + if(ret == -1 && errno != EAGAIN) { + log_printf(ERROR, "led_process: write returned with error: %s", strerror(errno)); + break; + } + + timeout.tv_sec = 0; + timeout.tv_usec = 100000; + ret = select(0, NULL, NULL, NULL, &timeout); + if(ret == -1 && errno != EINTR) { + log_printf(ERROR, "led_process: select returned with error: %s", strerror(errno)); + break; + } + + buf = '0'; + ret = write(led_fd, &buf, 1); + if(ret == -1 && errno != EAGAIN) { + log_printf(ERROR, "led_process: write returned with error: %s", strerror(errno)); + break; + } + } + return -1; +} + +int start_led_process(options_t* opt) +{ + int pipefd[2]; + int led_fd; + pid_t cpid; + + led_fd = open(opt->led_filename_, O_WRONLY); + if(led_fd < 0) { + log_printf(ERROR, "led_process: open() failed: %s", strerror(errno)); + return -2; + } + + if (pipe(pipefd) == -1) { + log_printf(ERROR, "led_process: pipe() failed: %s", strerror(errno)); + close(led_fd); + return -2; + } + + cpid = fork(); + if (cpid == -1) { + log_printf(ERROR, "led_process: fork() failed: %s", strerror(errno)); + close(pipefd[0]); + close(pipefd[1]); + close(led_fd); + return -2; + } + + if (cpid == 0) { + close(pipefd[1]); + return led_process(pipefd[0], led_fd); + } + + close(pipefd[0]); + close(led_fd); + return pipefd[1]; +} + int main(int argc, char* argv[]) { log_init(); @@ -279,6 +362,22 @@ int main(int argc, char* argv[]) fclose(pid_file); } + int led_pipe_fd = -1; + if(opt.led_filename_) { + log_printf(NOTICE, "starting led blink process"); + led_pipe_fd = start_led_process(&opt); + if(led_pipe_fd == -1) { + options_clear(&opt); + log_close(); + exit(0); + } + if(led_pipe_fd < -1) { + options_clear(&opt); + log_close(); + exit(-1); + } + } + int cmd_fd = 0; int serial_fd = 0; for(;;) { @@ -294,7 +393,7 @@ int main(int argc, char* argv[]) if(ret) ret = 2; else - ret = main_loop(serial_fd, cmd_fd, &opt); + ret = main_loop(serial_fd, cmd_fd, led_pipe_fd, &opt); } } diff --git a/openwrt/rhctl/Makefile b/openwrt/rhctl/Makefile index e7124ff..cdf9681 100644 --- a/openwrt/rhctl/Makefile +++ b/openwrt/rhctl/Makefile @@ -18,7 +18,7 @@ PKG_RELEASE:=1 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=http://localhost/ -PKG_MD5SUM:=0db71d3155aa44e6027918a135a6becf +PKG_MD5SUM:=b641ecdf5c7461244ebfdc1d058031a6 PKG_INSTALL_DIR:=$(PKG_BUILD_DIR)/ipkg-install @@ -196,6 +196,7 @@ int options_parse(options_t* opt, int argc, char* argv[]) #ifdef OPT_HEARTBEATCLIENT PARSE_STRING_PARAM("-d","--device", opt->serial_dev_) PARSE_INT_PARAM("-t","--timeout", opt->timeout_) + PARSE_STRING_PARAM("-l","--led", opt->led_filename_) #endif else return i; @@ -325,6 +326,7 @@ void options_default(options_t* opt) /* heartbeatclient only */ opt->timeout_ = 15; + opt->led_filename_ = NULL; } void options_clear(options_t* opt) @@ -362,6 +364,10 @@ void options_clear(options_t* opt) /* serialclient only */ if(opt->type_) free(opt->type_); + +/* heartbeatcleint only */ + if(opt->led_filename_) + free(opt->led_filename_); } void options_print_usage() @@ -406,6 +412,7 @@ void options_print_usage() #ifdef OPT_HEARTBEATCLIENT printf(" [-d|--device] <tty> the tty to connect to e.g. /dev/ttyUSB0\n"); printf(" [-t|--timeout] <timeout> heartbeat timeout in tenths of a second e.g. 15 -> 1.5s\n"); + printf(" [-l|--led] <led filename> sysfs filename of led device to blink\n"); #endif } @@ -460,5 +467,6 @@ void options_print(options_t* opt) #ifdef OPT_HEARTBEATCLIENT printf("serial_dev: '%s'\n", opt->serial_dev_); printf("timeout: %d\n", opt->timeout_); + printf("led_filename: '%s'\n", opt->led_filename_); #endif } @@ -60,6 +60,7 @@ struct options_struct { /* heartbeatclient only */ u_int32_t timeout_; + char* led_filename_; }; typedef struct options_struct options_t; |