Mercurial > pt1
diff recpt1/checksignal.c @ 114:3eccf1ef4853
improve checksignal command:
- retries MAX_RETRY times when tuning fails. if device is specified, reties forever.
- notifies signal quality by audible beep.
author | Yoshiki Yazawa <yaz@honeyplanet.jp> |
---|---|
date | Fri, 19 Mar 2010 16:42:32 +0900 |
parents | e7b786c42ca0 |
children | 91e71df37095 |
line wrap: on
line diff
--- a/recpt1/checksignal.c Fri Mar 19 01:01:35 2010 +0900 +++ b/recpt1/checksignal.c Fri Mar 19 16:42:32 2010 +0900 @@ -34,6 +34,8 @@ #include "pt1_dev.h" #include "tssplitter_lite.h" +#define MAX_RETRY (2) + /* type definitions */ typedef int boolean; @@ -46,18 +48,66 @@ /* globals */ boolean f_exit = FALSE; +boolean use_bell = FALSE; /* prototypes */ int tune(char *channel, thread_data *tdata, char *device); int close_tuner(thread_data *tdata); -/* signal handler */ void -handler(int dummy) +cleanup(thread_data *tdata) { f_exit = TRUE; } +/* will be signal handler thread */ +void * +process_signals(void *data) +{ + sigset_t waitset; + int sig; + thread_data *tdata = (thread_data *)data; + + sigemptyset(&waitset); + sigaddset(&waitset, SIGINT); + sigaddset(&waitset, SIGTERM); + sigaddset(&waitset, SIGUSR1); + + sigwait(&waitset, &sig); + + switch(sig) { + case SIGINT: + fprintf(stderr, "\nSIGINT received. cleaning up...\n"); + cleanup(tdata); + break; + case SIGTERM: + fprintf(stderr, "\nSIGTERM received. cleaning up...\n"); + cleanup(tdata); + break; + case SIGUSR1: /* normal exit*/ + cleanup(tdata); + break; + } + + return NULL; /* dummy */ +} + +void +init_signal_handlers(pthread_t *signal_thread, thread_data *tdata) +{ + sigset_t blockset; + + sigemptyset(&blockset); + sigaddset(&blockset, SIGINT); + sigaddset(&blockset, SIGTERM); + sigaddset(&blockset, SIGUSR1); + + if(pthread_sigmask(SIG_BLOCK, &blockset, NULL)) + fprintf(stderr, "pthread_sigmask() failed.\n"); + + pthread_create(signal_thread, NULL, process_signals, tdata); +} + /* lookup frequency conversion table*/ ISDB_T_FREQ_CONV_TABLE * searchrecoff(char *channel) @@ -79,7 +129,7 @@ void show_usage(char *cmd) { - fprintf(stderr, "Usage: \n%s [--device devicefile] [--lnb voltage] channel\n", cmd); + fprintf(stderr, "Usage: \n%s [--device devicefile] [--lnb voltage] [--bell] channel\n", cmd); fprintf(stderr, "\n"); } @@ -89,6 +139,7 @@ fprintf(stderr, "Options:\n"); fprintf(stderr, "--device devicefile: Specify devicefile to use\n"); fprintf(stderr, "--lnb voltage: Specify LNB voltage (0, 11, 15)\n"); + fprintf(stderr, "--bell: Notify signal quality by bell\n"); fprintf(stderr, "--help: Show this help\n"); fprintf(stderr, "--version: Show version\n"); fprintf(stderr, "--list: Show channel list\n"); @@ -178,11 +229,22 @@ } void +do_bell(int bell) +{ + int i; + for(i=0; i < bell; i++) { + fprintf(stderr, "\a"); + usleep(400000); + } +} + +void calc_cn(int fd, int type) { - int rc ; - double P ; + int rc; + double P; double CNR; + int bell = 0; if(ioctl(fd, GET_SIGNAL_STRENGTH, &rc) < 0) { fprintf(stderr, "Tuner Select Error\n"); @@ -197,7 +259,17 @@ else { CNR = getsignal_isdb_s(rc); } + + if(CNR >= 30.0) + bell = 3; + else if(CNR >= 15.0 && CNR < 30.0) + bell = 2; + else if(CNR < 15.0) + bell = 1; + fprintf(stderr, "\rC/N = %fdB", CNR); + if(use_bell) + do_bell(bell); } int @@ -221,7 +293,6 @@ /* open tuner */ /* case 1: specified tuner device */ if(device) { - fprintf(stderr, "device = %s\n", device); tdata->tfd = open(device, O_RDONLY); if(tdata->tfd < 0) { fprintf(stderr, "Cannot open tuner device: %s\n", device); @@ -236,14 +307,16 @@ } /* tune to specified channel */ - if(ioctl(tdata->tfd, SET_CHANNEL, &freq) < 0) { - close(tdata->tfd); - fprintf(stderr, "Cannot tune to the specified channel: %s\n", device); - return 1; + while(ioctl(tdata->tfd, SET_CHANNEL, &freq) < 0) { + if(f_exit) { + close_tuner(tdata); + return 1; + } + fprintf(stderr, "No signal. Still trying: %s\n", device); } - else { - tdata->ch = atoi(channel); - } + + fprintf(stderr, "device = %s\n", device); + tdata->ch = atoi(channel); } else { /* case 2: loop around available devices */ @@ -257,6 +330,8 @@ } for(lp = 0; lp < num_devs; lp++) { + int count = 0; + tdata->tfd = open(tuner[lp], O_RDONLY); if(tdata->tfd >= 0) { /* power on LNB */ @@ -267,9 +342,19 @@ } /* tune to specified channel */ - if(ioctl(tdata->tfd, SET_CHANNEL, &freq) < 0) { - close(tdata->tfd); - tdata->tfd = -1; + while(ioctl(tdata->tfd, SET_CHANNEL, &freq) < 0 && + count < MAX_RETRY) { + if(f_exit) { + close_tuner(tdata); + return 1; + } + fprintf(stderr, "No signal. Still trying: %s\n", tuner[lp]); + count++; + } + + if(count >= MAX_RETRY) { + close_tuner(tdata); + count = 0; continue; } @@ -296,12 +381,16 @@ { int rv = 0; + if(tdata->tfd == -1) + return rv; + if(tdata->table->type == CHTYPE_SATELLITE) { if(ioctl(tdata->tfd, LNB_DISABLE, 0) < 0) { rv = 1; } } close(tdata->tfd); + tdata->tfd = -1; return rv; } @@ -309,10 +398,12 @@ int main(int argc, char **argv) { + pthread_t signal_thread; static thread_data tdata; int result; int option_index; struct option long_options[] = { + { "bell", 1, NULL, 'b'}, { "LNB", 1, NULL, 'n'}, { "lnb", 1, NULL, 'n'}, { "device", 1, NULL, 'd'}, @@ -326,9 +417,12 @@ int val; char *voltage[] = {"0V", "11V", "15V"}; - while((result = getopt_long(argc, argv, "br:smn:ua:p:d:hvli:", + while((result = getopt_long(argc, argv, "bhvln:d:", long_options, &option_index)) != -1) { switch(result) { + case 'b': + use_bell = TRUE; + break; case 'h': fprintf(stderr, "\n"); show_usage(argv[0]); @@ -376,8 +470,8 @@ return 1; } - /* add signal handler */ - signal(SIGTERM, handler); + /* spawn signal handler thread */ + init_signal_handlers(&signal_thread, &tdata); /* tune */ if(tune(argv[optind], &tdata, device) != 0) @@ -391,6 +485,10 @@ sleep(1); } + /* wait for signal thread */ + pthread_kill(signal_thread, SIGUSR1); + pthread_join(signal_thread, NULL); + /* close tuner */ if(close_tuner(&tdata) != 0) return 1;