Mercurial > pt1
comparison recpt1/recpt1.c @ 16:ecb85bde67b1
added signal handler to perform cleaning up when it receives a signal.
author | Yoshiki Yazawa <yaz@honeyplanet.jp> |
---|---|
date | Wed, 25 Feb 2009 02:35:36 +0900 |
parents | 1b0883b02b4f |
children | 52c7c7c64ba6 |
comparison
equal
deleted
inserted
replaced
15:1b0883b02b4f | 16:ecb85bde67b1 |
---|---|
7 #include <string.h> | 7 #include <string.h> |
8 #include <pthread.h> | 8 #include <pthread.h> |
9 #include <math.h> | 9 #include <math.h> |
10 #include <unistd.h> | 10 #include <unistd.h> |
11 #include <getopt.h> | 11 #include <getopt.h> |
12 #include <signal.h> | |
12 | 13 |
13 #include <netdb.h> | 14 #include <netdb.h> |
14 #include <arpa/inet.h> | 15 #include <arpa/inet.h> |
15 #include <netinet/in.h> | 16 #include <netinet/in.h> |
16 | 17 |
39 ISDB_T_FREQ_CONV_TABLE * | 40 ISDB_T_FREQ_CONV_TABLE * |
40 searchrecoff(char *channel) | 41 searchrecoff(char *channel) |
41 { | 42 { |
42 int lp; | 43 int lp; |
43 | 44 |
44 for(lp = 0; isdb_t_conv_table[lp].parm_freq != NULL; lp++){ | 45 for(lp = 0; isdb_t_conv_table[lp].parm_freq != NULL; lp++) { |
45 /* return entry number in the table when strings match and | 46 /* return entry number in the table when strings match and |
46 * lengths are same. */ | 47 * lengths are same. */ |
47 if((memcmp(isdb_t_conv_table[lp].parm_freq, channel, | 48 if((memcmp(isdb_t_conv_table[lp].parm_freq, channel, |
48 strlen(channel)) == 0) && | 49 strlen(channel)) == 0) && |
49 (strlen(channel) == strlen(isdb_t_conv_table[lp].parm_freq))){ | 50 (strlen(channel) == strlen(isdb_t_conv_table[lp].parm_freq))) { |
50 return &isdb_t_conv_table[lp]; | 51 return &isdb_t_conv_table[lp]; |
51 } | 52 } |
52 } | 53 } |
53 return NULL; | 54 return NULL; |
54 } | 55 } |
192 if(use_udp && sfd != -1) { | 193 if(use_udp && sfd != -1) { |
193 sendto(sfd, dbuf.data, dbuf.size, 0, | 194 sendto(sfd, dbuf.data, dbuf.size, 0, |
194 addr, sizeof(struct sockaddr_in)); | 195 addr, sizeof(struct sockaddr_in)); |
195 } | 196 } |
196 free(buf); | 197 free(buf); |
197 } else { | 198 } |
199 else { | |
198 if(use_udp && sfd != -1) { | 200 if(use_udp && sfd != -1) { |
199 sendto(sfd, sbuf.data, sbuf.size, 0, | 201 sendto(sfd, sbuf.data, sbuf.size, 0, |
200 addr, sizeof(struct sockaddr_in)); | 202 addr, sizeof(struct sockaddr_in)); |
201 } | 203 } |
202 free(buf); | 204 free(buf); |
246 if(use_udp && sfd != -1) { | 248 if(use_udp && sfd != -1) { |
247 sendto(sfd, dbuf.data, dbuf.size, 0, | 249 sendto(sfd, dbuf.data, dbuf.size, 0, |
248 addr, sizeof(struct sockaddr_in)); | 250 addr, sizeof(struct sockaddr_in)); |
249 } | 251 } |
250 free(buf); | 252 free(buf); |
251 } else { | 253 } |
254 else { | |
252 write(wfd, sbuf.data, sbuf.size); | 255 write(wfd, sbuf.data, sbuf.size); |
253 | 256 |
254 if(use_udp && sfd != -1) { | 257 if(use_udp && sfd != -1) { |
255 sendto(sfd, sbuf.data, sbuf.size, 0, | 258 sendto(sfd, sbuf.data, sbuf.size, 0, |
256 addr, sizeof(struct sockaddr_in)); | 259 addr, sizeof(struct sockaddr_in)); |
353 memset(sigbuf, '\0', sizeof(sigbuf)); | 356 memset(sigbuf, '\0', sizeof(sigbuf)); |
354 sigbuf[0] = (((signal & 0xFF00) >> 8) & 0XFF); | 357 sigbuf[0] = (((signal & 0xFF00) >> 8) & 0XFF); |
355 sigbuf[1] = (signal & 0xFF); | 358 sigbuf[1] = (signal & 0xFF); |
356 | 359 |
357 /* calculate signal level */ | 360 /* calculate signal level */ |
358 if(sigbuf[0] <= 0x10U){ | 361 if(sigbuf[0] <= 0x10U) { |
359 /* clipped maximum */ | 362 /* clipped maximum */ |
360 return 24.07f; | 363 return 24.07f; |
361 } else if (sigbuf[0] >= 0xB0U) { | 364 } |
365 else if (sigbuf[0] >= 0xB0U) { | |
362 /* clipped minimum */ | 366 /* clipped minimum */ |
363 return 0.0f; | 367 return 0.0f; |
364 } else { | 368 } |
369 else { | |
365 /* linear interpolation */ | 370 /* linear interpolation */ |
366 const float fMixRate = | 371 const float fMixRate = |
367 (float)(((unsigned short)(sigbuf[0] & 0x0FU) << 8) | | 372 (float)(((unsigned short)(sigbuf[0] & 0x0FU) << 8) | |
368 (unsigned short)sigbuf[0]) / 4096.0f; | 373 (unsigned short)sigbuf[0]) / 4096.0f; |
369 return afLevelTable[sigbuf[0] >> 4] * (1.0f - fMixRate) + | 374 return afLevelTable[sigbuf[0] >> 4] * (1.0f - fMixRate) + |
386 if(type == CHTYPE_GROUND) { | 391 if(type == CHTYPE_GROUND) { |
387 P = log10(5505024/(double)rc) * 10; | 392 P = log10(5505024/(double)rc) * 10; |
388 CNR = (0.000024 * P * P * P * P) - (0.0016 * P * P * P) + | 393 CNR = (0.000024 * P * P * P * P) - (0.0016 * P * P * P) + |
389 (0.0398 * P * P) + (0.5491 * P)+3.0965; | 394 (0.0398 * P * P) + (0.5491 * P)+3.0965; |
390 printf("Signal=%fdB\n", CNR); | 395 printf("Signal=%fdB\n", CNR); |
391 } else { | 396 } |
397 else { | |
392 CNR = getsignal_isdb_s(rc); | 398 CNR = getsignal_isdb_s(rc); |
393 printf("Signal=%fdB\n", CNR); | 399 printf("Signal=%fdB\n", CNR); |
394 } | 400 } |
401 } | |
402 | |
403 void | |
404 cleanup(int tfd) | |
405 { | |
406 /* stop recording */ | |
407 ioctl(tfd, STOP_REC, 0); | |
408 | |
409 /* restore LNB state */ | |
410 #if 0 | |
411 if(ptr->type == CHTYPE_SATELLITE) { | |
412 if(ioctl(tfd, LNB_DISABLE, 0) < 0) { | |
413 return 0 ; | |
414 } | |
415 } | |
416 #endif | |
417 /* xxx really need mutex? */ | |
418 f_exit = TRUE; | |
419 } | |
420 | |
421 /* will be signal handler thread */ | |
422 void * | |
423 process_signals(void *data) | |
424 { | |
425 sigset_t waitset; | |
426 int sig; | |
427 int tfd = *(int *)data; | |
428 | |
429 sigemptyset(&waitset); | |
430 sigaddset(&waitset, SIGINT); | |
431 sigaddset(&waitset, SIGTERM); | |
432 | |
433 sigwait(&waitset, &sig); | |
434 | |
435 switch(sig) { | |
436 case SIGINT: | |
437 fprintf(stderr, "\nSIGINT received. cleaning up...\n"); | |
438 cleanup(tfd); | |
439 break; | |
440 case SIGTERM: | |
441 fprintf(stderr, "\nSIGTERM received. cleaning up...\n"); | |
442 cleanup(tfd); | |
443 break; | |
444 } | |
445 | |
446 return NULL; /* dummy */ | |
447 } | |
448 | |
449 void | |
450 init_signal_handlers(pthread_t *signal_thread, int tfd) | |
451 { | |
452 sigset_t blockset; | |
453 static int tunerfd; | |
454 | |
455 tunerfd = tfd; | |
456 | |
457 sigemptyset(&blockset); | |
458 sigaddset(&blockset, SIGINT); | |
459 sigaddset(&blockset, SIGTERM); | |
460 | |
461 if(pthread_sigmask(SIG_BLOCK, &blockset, NULL)) | |
462 fprintf(stderr, "pthread_sigmask() failed.\n"); | |
463 | |
464 pthread_create(signal_thread, NULL, process_signals, &tunerfd); | |
395 } | 465 } |
396 | 466 |
397 int | 467 int |
398 main(int argc, char **argv) | 468 main(int argc, char **argv) |
399 { | 469 { |
402 int recsec; | 472 int recsec; |
403 int indefinite = FALSE; | 473 int indefinite = FALSE; |
404 time_t start_time, cur_time; | 474 time_t start_time, cur_time; |
405 FREQUENCY freq; | 475 FREQUENCY freq; |
406 ISDB_T_FREQ_CONV_TABLE *ptr; | 476 ISDB_T_FREQ_CONV_TABLE *ptr; |
407 pthread_t dequeue_threads; | 477 pthread_t dequeue_thread; |
478 pthread_t signal_thread; | |
408 QUEUE_T *p_queue = create_queue(MAX_QUEUE); | 479 QUEUE_T *p_queue = create_queue(MAX_QUEUE); |
409 BUFSZ *bufptr; | 480 BUFSZ *bufptr; |
410 decoder *dec = NULL; | 481 decoder *dec = NULL; |
411 thread_data tdata; | 482 thread_data tdata; |
412 decoder_options dopt = { | 483 decoder_options dopt = { |
510 if(tfd >= 0) { | 581 if(tfd >= 0) { |
511 break; | 582 break; |
512 } | 583 } |
513 } | 584 } |
514 if(tfd < 0) { | 585 if(tfd < 0) { |
515 fprintf(stderr, "Device Open Error\n"); | 586 fprintf(stderr, "Cannot open tuner\n"); |
516 return 1; | 587 return 1; |
517 } | 588 } |
518 } else { | 589 } |
590 else { | |
519 for(lp = 0; lp < 2; lp++) { | 591 for(lp = 0; lp < 2; lp++) { |
520 tfd = open(isdb_t_dev[lp], O_RDONLY); | 592 tfd = open(isdb_t_dev[lp], O_RDONLY); |
521 if(tfd >= 0) { | 593 if(tfd >= 0) { |
522 break; | 594 break; |
523 } | 595 } |
524 } | 596 } |
525 if(tfd < 0) { | 597 if(tfd < 0) { |
526 fprintf(stderr, "Device Open Error\n"); | 598 fprintf(stderr, "Cannot open tuner\n"); |
527 return 1; | 599 return 1; |
528 } | 600 } |
529 } | 601 } |
530 | 602 |
531 /* get recsec */ | 603 /* get recsec */ |
535 | 607 |
536 /* initialize decoder */ | 608 /* initialize decoder */ |
537 if(use_b25) { | 609 if(use_b25) { |
538 dec = b25_startup(&dopt); | 610 dec = b25_startup(&dopt); |
539 if(!dec) { | 611 if(!dec) { |
540 fprintf(stderr, "cannot start b25 decoder\n"); | 612 fprintf(stderr, "Could not start b25 decoder\n"); |
541 fprintf(stderr, "fall back to encrypted recording\n"); | 613 fprintf(stderr, "Fall back to encrypted recording\n"); |
542 use_b25 = 0; | 614 use_b25 = 0; |
543 } | 615 } |
544 } | 616 } |
545 | 617 |
546 /* initialize udp connection */ | 618 /* initialize udp connection */ |
567 | 639 |
568 /* open output file */ | 640 /* open output file */ |
569 if(!fileless) { | 641 if(!fileless) { |
570 wfd = open(argv[optind + 2], (O_RDWR | O_CREAT | O_TRUNC), 0666); | 642 wfd = open(argv[optind + 2], (O_RDWR | O_CREAT | O_TRUNC), 0666); |
571 if(wfd < 0) { | 643 if(wfd < 0) { |
572 fprintf(stderr, "Output File Open Error(%s)\n", argv[optind + 2]); | 644 fprintf(stderr, "Could not open output file(%s)\n", argv[optind + 2]); |
573 return 1; | 645 return 1; |
574 } | 646 } |
575 } | 647 } |
576 if(ptr->type == CHTYPE_SATELLITE){ | 648 if(ptr->type == CHTYPE_SATELLITE) { |
577 if(ioctl(tfd, LNB_ENABLE, 0) < 0){ | 649 if(ioctl(tfd, LNB_ENABLE, 0) < 0) { |
578 return 0 ; | 650 return 0 ; |
579 } | 651 } |
580 } | 652 } |
581 | 653 |
582 if(ioctl(tfd, SET_CHANNEL, &freq) < 0) { | 654 if(ioctl(tfd, SET_CHANNEL, &freq) < 0) { |
583 fprintf(stderr, "Tuner Select Error\n"); | 655 fprintf(stderr, "Could not tune to the specified channel\n"); |
584 calc_cn(tfd, ptr->type); | 656 calc_cn(tfd, ptr->type); |
585 return 1; | 657 return 1; |
586 } | 658 } |
587 calc_cn(tfd, ptr->type); | 659 calc_cn(tfd, ptr->type); |
660 | |
661 /* init signal handler thread */ | |
662 init_signal_handlers(&signal_thread, tfd); | |
588 | 663 |
589 /* make reader thread */ | 664 /* make reader thread */ |
590 tdata.queue = p_queue; | 665 tdata.queue = p_queue; |
591 tdata.decoder = dec; | 666 tdata.decoder = dec; |
592 tdata.wfd = wfd; | 667 tdata.wfd = wfd; |
593 tdata.sock_data = sdata; | 668 tdata.sock_data = sdata; |
594 pthread_create(&dequeue_threads, NULL, write_func, &tdata); | 669 pthread_create(&dequeue_thread, NULL, write_func, &tdata); |
595 | 670 |
596 /* start recording */ | 671 /* start recording */ |
597 if(ioctl(tfd, START_REC, 0) < 0) { | 672 if(ioctl(tfd, START_REC, 0) < 0) { |
598 fprintf(stderr, "Tuner Start Error\n"); | 673 fprintf(stderr, "Tuner could not start recording\n"); |
599 return 1; | 674 return 1; |
600 } | 675 } |
676 | |
677 fprintf(stderr, "Recording...\n"); | |
601 | 678 |
602 time(&start_time); | 679 time(&start_time); |
603 | 680 |
604 /* read from tuner */ | 681 /* read from tuner */ |
605 while(1) { | 682 while(1) { |
683 if(f_exit) | |
684 break; | |
606 time(&cur_time); | 685 time(&cur_time); |
607 bufptr = malloc(sizeof(BUFSZ)); | 686 bufptr = malloc(sizeof(BUFSZ)); |
608 bufptr->size = read(tfd, bufptr->buffer, MAX_READ_SIZE); | 687 bufptr->size = read(tfd, bufptr->buffer, MAX_READ_SIZE); |
609 if(bufptr->size <= 0) { | 688 if(bufptr->size <= 0) { |
610 if((cur_time - start_time) >= recsec && !indefinite) { | 689 if((cur_time - start_time) >= recsec && !indefinite) { |
611 f_exit = TRUE; | 690 f_exit = TRUE; |
612 enqueue(p_queue, NULL); | 691 enqueue(p_queue, NULL); |
613 break; | 692 break; |
614 } else { | 693 } |
694 else { | |
615 continue; | 695 continue; |
616 } | 696 } |
617 } | 697 } |
618 enqueue(p_queue, bufptr); | 698 enqueue(p_queue, bufptr); |
619 | 699 |
632 enqueue(p_queue, bufptr); | 712 enqueue(p_queue, bufptr); |
633 } | 713 } |
634 break; | 714 break; |
635 } | 715 } |
636 } | 716 } |
717 | |
637 /* close tuner */ | 718 /* close tuner */ |
638 if(ptr->type == CHTYPE_SATELLITE){ | 719 if(ptr->type == CHTYPE_SATELLITE) { |
639 if(ioctl(tfd, LNB_DISABLE, 0) < 0){ | 720 if(ioctl(tfd, LNB_DISABLE, 0) < 0) { |
640 return 0 ; | 721 return 0 ; |
641 } | 722 } |
642 } | 723 } |
643 close(tfd); | 724 close(tfd); |
644 | 725 |
645 /* wait reader thread */ | 726 /* wait reader thread */ |
646 pthread_join(dequeue_threads, NULL); | 727 pthread_join(dequeue_thread, NULL); |
728 fprintf(stderr, "dequeue_thread joined\n"); | |
729 | |
730 pthread_join(signal_thread, NULL); | |
731 fprintf(stderr, "signal_thread joined\n"); | |
732 | |
733 /* relase queue */ | |
647 destroy_queue(p_queue); | 734 destroy_queue(p_queue); |
648 | 735 |
649 /* close socket */ | 736 /* free socket data */ |
650 if(use_udp) { | 737 free(sdata); |
651 close(sdata->sfd); | |
652 free(sdata); | |
653 } | |
654 | 738 |
655 /* release decoder */ | 739 /* release decoder */ |
656 if(use_b25) { | 740 if(use_b25) { |
657 b25_shutdown(dec); | 741 b25_shutdown(dec); |
658 } | 742 } |
659 | 743 |
744 fprintf(stderr, "leaving main\n"); | |
745 | |
660 return 0; | 746 return 0; |
661 } | 747 } |