comparison 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
comparison
equal deleted inserted replaced
113:e7b786c42ca0 114:3eccf1ef4853
32 #include <sys/ipc.h> 32 #include <sys/ipc.h>
33 #include <sys/msg.h> 33 #include <sys/msg.h>
34 #include "pt1_dev.h" 34 #include "pt1_dev.h"
35 #include "tssplitter_lite.h" 35 #include "tssplitter_lite.h"
36 36
37 #define MAX_RETRY (2)
38
37 /* type definitions */ 39 /* type definitions */
38 typedef int boolean; 40 typedef int boolean;
39 41
40 typedef struct thread_data { 42 typedef struct thread_data {
41 int ch; 43 int ch;
44 ISDB_T_FREQ_CONV_TABLE *table; 46 ISDB_T_FREQ_CONV_TABLE *table;
45 } thread_data; 47 } thread_data;
46 48
47 /* globals */ 49 /* globals */
48 boolean f_exit = FALSE; 50 boolean f_exit = FALSE;
51 boolean use_bell = FALSE;
49 52
50 /* prototypes */ 53 /* prototypes */
51 int tune(char *channel, thread_data *tdata, char *device); 54 int tune(char *channel, thread_data *tdata, char *device);
52 int close_tuner(thread_data *tdata); 55 int close_tuner(thread_data *tdata);
53 56
54 /* signal handler */ 57 void
55 void 58 cleanup(thread_data *tdata)
56 handler(int dummy)
57 { 59 {
58 f_exit = TRUE; 60 f_exit = TRUE;
61 }
62
63 /* will be signal handler thread */
64 void *
65 process_signals(void *data)
66 {
67 sigset_t waitset;
68 int sig;
69 thread_data *tdata = (thread_data *)data;
70
71 sigemptyset(&waitset);
72 sigaddset(&waitset, SIGINT);
73 sigaddset(&waitset, SIGTERM);
74 sigaddset(&waitset, SIGUSR1);
75
76 sigwait(&waitset, &sig);
77
78 switch(sig) {
79 case SIGINT:
80 fprintf(stderr, "\nSIGINT received. cleaning up...\n");
81 cleanup(tdata);
82 break;
83 case SIGTERM:
84 fprintf(stderr, "\nSIGTERM received. cleaning up...\n");
85 cleanup(tdata);
86 break;
87 case SIGUSR1: /* normal exit*/
88 cleanup(tdata);
89 break;
90 }
91
92 return NULL; /* dummy */
93 }
94
95 void
96 init_signal_handlers(pthread_t *signal_thread, thread_data *tdata)
97 {
98 sigset_t blockset;
99
100 sigemptyset(&blockset);
101 sigaddset(&blockset, SIGINT);
102 sigaddset(&blockset, SIGTERM);
103 sigaddset(&blockset, SIGUSR1);
104
105 if(pthread_sigmask(SIG_BLOCK, &blockset, NULL))
106 fprintf(stderr, "pthread_sigmask() failed.\n");
107
108 pthread_create(signal_thread, NULL, process_signals, tdata);
59 } 109 }
60 110
61 /* lookup frequency conversion table*/ 111 /* lookup frequency conversion table*/
62 ISDB_T_FREQ_CONV_TABLE * 112 ISDB_T_FREQ_CONV_TABLE *
63 searchrecoff(char *channel) 113 searchrecoff(char *channel)
77 } 127 }
78 128
79 void 129 void
80 show_usage(char *cmd) 130 show_usage(char *cmd)
81 { 131 {
82 fprintf(stderr, "Usage: \n%s [--device devicefile] [--lnb voltage] channel\n", cmd); 132 fprintf(stderr, "Usage: \n%s [--device devicefile] [--lnb voltage] [--bell] channel\n", cmd);
83 fprintf(stderr, "\n"); 133 fprintf(stderr, "\n");
84 } 134 }
85 135
86 void 136 void
87 show_options(void) 137 show_options(void)
88 { 138 {
89 fprintf(stderr, "Options:\n"); 139 fprintf(stderr, "Options:\n");
90 fprintf(stderr, "--device devicefile: Specify devicefile to use\n"); 140 fprintf(stderr, "--device devicefile: Specify devicefile to use\n");
91 fprintf(stderr, "--lnb voltage: Specify LNB voltage (0, 11, 15)\n"); 141 fprintf(stderr, "--lnb voltage: Specify LNB voltage (0, 11, 15)\n");
142 fprintf(stderr, "--bell: Notify signal quality by bell\n");
92 fprintf(stderr, "--help: Show this help\n"); 143 fprintf(stderr, "--help: Show this help\n");
93 fprintf(stderr, "--version: Show version\n"); 144 fprintf(stderr, "--version: Show version\n");
94 fprintf(stderr, "--list: Show channel list\n"); 145 fprintf(stderr, "--list: Show channel list\n");
95 } 146 }
96 147
176 afLevelTable[(sigbuf[0] >> 4) + 0x01U] * fMixRate; 227 afLevelTable[(sigbuf[0] >> 4) + 0x01U] * fMixRate;
177 } 228 }
178 } 229 }
179 230
180 void 231 void
232 do_bell(int bell)
233 {
234 int i;
235 for(i=0; i < bell; i++) {
236 fprintf(stderr, "\a");
237 usleep(400000);
238 }
239 }
240
241 void
181 calc_cn(int fd, int type) 242 calc_cn(int fd, int type)
182 { 243 {
183 int rc ; 244 int rc;
184 double P ; 245 double P;
185 double CNR; 246 double CNR;
247 int bell = 0;
186 248
187 if(ioctl(fd, GET_SIGNAL_STRENGTH, &rc) < 0) { 249 if(ioctl(fd, GET_SIGNAL_STRENGTH, &rc) < 0) {
188 fprintf(stderr, "Tuner Select Error\n"); 250 fprintf(stderr, "Tuner Select Error\n");
189 return ; 251 return ;
190 } 252 }
195 (0.0398 * P * P) + (0.5491 * P)+3.0965; 257 (0.0398 * P * P) + (0.5491 * P)+3.0965;
196 } 258 }
197 else { 259 else {
198 CNR = getsignal_isdb_s(rc); 260 CNR = getsignal_isdb_s(rc);
199 } 261 }
262
263 if(CNR >= 30.0)
264 bell = 3;
265 else if(CNR >= 15.0 && CNR < 30.0)
266 bell = 2;
267 else if(CNR < 15.0)
268 bell = 1;
269
200 fprintf(stderr, "\rC/N = %fdB", CNR); 270 fprintf(stderr, "\rC/N = %fdB", CNR);
271 if(use_bell)
272 do_bell(bell);
201 } 273 }
202 274
203 int 275 int
204 tune(char *channel, thread_data *tdata, char *device) 276 tune(char *channel, thread_data *tdata, char *device)
205 { 277 {
219 freq.slot = tdata->table->add_freq; 291 freq.slot = tdata->table->add_freq;
220 292
221 /* open tuner */ 293 /* open tuner */
222 /* case 1: specified tuner device */ 294 /* case 1: specified tuner device */
223 if(device) { 295 if(device) {
224 fprintf(stderr, "device = %s\n", device);
225 tdata->tfd = open(device, O_RDONLY); 296 tdata->tfd = open(device, O_RDONLY);
226 if(tdata->tfd < 0) { 297 if(tdata->tfd < 0) {
227 fprintf(stderr, "Cannot open tuner device: %s\n", device); 298 fprintf(stderr, "Cannot open tuner device: %s\n", device);
228 return 1; 299 return 1;
229 } 300 }
234 fprintf(stderr, "Power on LNB failed: %s\n", device); 305 fprintf(stderr, "Power on LNB failed: %s\n", device);
235 } 306 }
236 } 307 }
237 308
238 /* tune to specified channel */ 309 /* tune to specified channel */
239 if(ioctl(tdata->tfd, SET_CHANNEL, &freq) < 0) { 310 while(ioctl(tdata->tfd, SET_CHANNEL, &freq) < 0) {
240 close(tdata->tfd); 311 if(f_exit) {
241 fprintf(stderr, "Cannot tune to the specified channel: %s\n", device); 312 close_tuner(tdata);
242 return 1; 313 return 1;
243 } 314 }
244 else { 315 fprintf(stderr, "No signal. Still trying: %s\n", device);
245 tdata->ch = atoi(channel); 316 }
246 } 317
318 fprintf(stderr, "device = %s\n", device);
319 tdata->ch = atoi(channel);
247 } 320 }
248 else { 321 else {
249 /* case 2: loop around available devices */ 322 /* case 2: loop around available devices */
250 if(tdata->table->type == CHTYPE_SATELLITE) { 323 if(tdata->table->type == CHTYPE_SATELLITE) {
251 tuner = bsdev; 324 tuner = bsdev;
255 tuner = isdb_t_dev; 328 tuner = isdb_t_dev;
256 num_devs = NUM_ISDB_T_DEV; 329 num_devs = NUM_ISDB_T_DEV;
257 } 330 }
258 331
259 for(lp = 0; lp < num_devs; lp++) { 332 for(lp = 0; lp < num_devs; lp++) {
333 int count = 0;
334
260 tdata->tfd = open(tuner[lp], O_RDONLY); 335 tdata->tfd = open(tuner[lp], O_RDONLY);
261 if(tdata->tfd >= 0) { 336 if(tdata->tfd >= 0) {
262 /* power on LNB */ 337 /* power on LNB */
263 if(tdata->table->type == CHTYPE_SATELLITE) { 338 if(tdata->table->type == CHTYPE_SATELLITE) {
264 if(ioctl(tdata->tfd, LNB_ENABLE, tdata->lnb) < 0) { 339 if(ioctl(tdata->tfd, LNB_ENABLE, tdata->lnb) < 0) {
265 fprintf(stderr, "Warning: Power on LNB failed: %s\n", tuner[lp]); 340 fprintf(stderr, "Warning: Power on LNB failed: %s\n", tuner[lp]);
266 } 341 }
267 } 342 }
268 343
269 /* tune to specified channel */ 344 /* tune to specified channel */
270 if(ioctl(tdata->tfd, SET_CHANNEL, &freq) < 0) { 345 while(ioctl(tdata->tfd, SET_CHANNEL, &freq) < 0 &&
271 close(tdata->tfd); 346 count < MAX_RETRY) {
272 tdata->tfd = -1; 347 if(f_exit) {
348 close_tuner(tdata);
349 return 1;
350 }
351 fprintf(stderr, "No signal. Still trying: %s\n", tuner[lp]);
352 count++;
353 }
354
355 if(count >= MAX_RETRY) {
356 close_tuner(tdata);
357 count = 0;
273 continue; 358 continue;
274 } 359 }
275 360
276 fprintf(stderr, "device = %s\n", tuner[lp]); 361 fprintf(stderr, "device = %s\n", tuner[lp]);
277 break; /* found suitable tuner */ 362 break; /* found suitable tuner */
294 int 379 int
295 close_tuner(thread_data *tdata) 380 close_tuner(thread_data *tdata)
296 { 381 {
297 int rv = 0; 382 int rv = 0;
298 383
384 if(tdata->tfd == -1)
385 return rv;
386
299 if(tdata->table->type == CHTYPE_SATELLITE) { 387 if(tdata->table->type == CHTYPE_SATELLITE) {
300 if(ioctl(tdata->tfd, LNB_DISABLE, 0) < 0) { 388 if(ioctl(tdata->tfd, LNB_DISABLE, 0) < 0) {
301 rv = 1; 389 rv = 1;
302 } 390 }
303 } 391 }
304 close(tdata->tfd); 392 close(tdata->tfd);
393 tdata->tfd = -1;
305 394
306 return rv; 395 return rv;
307 } 396 }
308 397
309 int 398 int
310 main(int argc, char **argv) 399 main(int argc, char **argv)
311 { 400 {
401 pthread_t signal_thread;
312 static thread_data tdata; 402 static thread_data tdata;
313 int result; 403 int result;
314 int option_index; 404 int option_index;
315 struct option long_options[] = { 405 struct option long_options[] = {
406 { "bell", 1, NULL, 'b'},
316 { "LNB", 1, NULL, 'n'}, 407 { "LNB", 1, NULL, 'n'},
317 { "lnb", 1, NULL, 'n'}, 408 { "lnb", 1, NULL, 'n'},
318 { "device", 1, NULL, 'd'}, 409 { "device", 1, NULL, 'd'},
319 { "help", 0, NULL, 'h'}, 410 { "help", 0, NULL, 'h'},
320 { "version", 0, NULL, 'v'}, 411 { "version", 0, NULL, 'v'},
324 415
325 char *device = NULL; 416 char *device = NULL;
326 int val; 417 int val;
327 char *voltage[] = {"0V", "11V", "15V"}; 418 char *voltage[] = {"0V", "11V", "15V"};
328 419
329 while((result = getopt_long(argc, argv, "br:smn:ua:p:d:hvli:", 420 while((result = getopt_long(argc, argv, "bhvln:d:",
330 long_options, &option_index)) != -1) { 421 long_options, &option_index)) != -1) {
331 switch(result) { 422 switch(result) {
423 case 'b':
424 use_bell = TRUE;
425 break;
332 case 'h': 426 case 'h':
333 fprintf(stderr, "\n"); 427 fprintf(stderr, "\n");
334 show_usage(argv[0]); 428 show_usage(argv[0]);
335 fprintf(stderr, "\n"); 429 fprintf(stderr, "\n");
336 show_options(); 430 show_options();
374 fprintf(stderr, "channel must be specified!\n"); 468 fprintf(stderr, "channel must be specified!\n");
375 fprintf(stderr, "Try '%s --help' for more information.\n", argv[0]); 469 fprintf(stderr, "Try '%s --help' for more information.\n", argv[0]);
376 return 1; 470 return 1;
377 } 471 }
378 472
379 /* add signal handler */ 473 /* spawn signal handler thread */
380 signal(SIGTERM, handler); 474 init_signal_handlers(&signal_thread, &tdata);
381 475
382 /* tune */ 476 /* tune */
383 if(tune(argv[optind], &tdata, device) != 0) 477 if(tune(argv[optind], &tdata, device) != 0)
384 return 1; 478 return 1;
385 479
389 /* show signal strength */ 483 /* show signal strength */
390 calc_cn(tdata.tfd, tdata.table->type); 484 calc_cn(tdata.tfd, tdata.table->type);
391 sleep(1); 485 sleep(1);
392 } 486 }
393 487
488 /* wait for signal thread */
489 pthread_kill(signal_thread, SIGUSR1);
490 pthread_join(signal_thread, NULL);
491
394 /* close tuner */ 492 /* close tuner */
395 if(close_tuner(&tdata) != 0) 493 if(close_tuner(&tdata) != 0)
396 return 1; 494 return 1;
397 495
398 return 0; 496 return 0;