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 }