Mercurial > pt1.oyama
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; |