Mercurial > pt1.oyama
diff recpt1/recpt1.c @ 8:6da603afd363
added udp capability
author | Yoshiki Yazawa <yaz@honeyplanet.jp> |
---|---|
date | Mon, 23 Feb 2009 03:06:17 +0900 |
parents | 407af34cfbd9 |
children | 4615eaf04415 |
line wrap: on
line diff
--- a/recpt1/recpt1.c Tue Feb 17 11:52:26 2009 +0900 +++ b/recpt1/recpt1.c Mon Feb 23 03:06:17 2009 +0900 @@ -9,6 +9,10 @@ #include <unistd.h> #include <getopt.h> +#include <netdb.h> +#include <arpa/inet.h> +#include <netinet/in.h> + #include <sys/ioctl.h> #include "pt1_ioctl.h" @@ -18,10 +22,16 @@ /* globals */ int f_exit = FALSE; +typedef struct sock_data { + int sfd; /* socket fd */ + struct sockaddr_in addr; +} sock_data; + typedef struct thread_data { QUEUE_T *queue; decoder *decoder; - int fd; + int wfd; /* output file fd */ + sock_data *sock_data; } thread_data; /* lookup frequency conversion table*/ @@ -46,7 +56,7 @@ create_queue(size_t size) { QUEUE_T *p_queue; - int memsize = sizeof(QUEUE_T) + size * sizeof(BUFSZ); + int memsize = sizeof(QUEUE_T) + size * sizeof(BUFSZ); p_queue = (QUEUE_T*)calloc(memsize, sizeof(char)); @@ -104,7 +114,7 @@ BUFSZ * dequeue(QUEUE_T *p_queue) { - BUFSZ *buffer; + BUFSZ *buffer; pthread_mutex_lock(&p_queue->mutex); /* entered the critical section*/ @@ -139,12 +149,20 @@ thread_data *data = (thread_data *)p; QUEUE_T *p_queue = data->queue; decoder *dec = data->decoder; - int wfd = data->fd; + int wfd = data->wfd; int use_b25 = dec ? 1 : 0; - BUFSZ *buf; + int use_udp = data->sock_data ? 1 : 0; + int sfd = 0; + struct sockaddr *addr = NULL; + BUFSZ *buf; ARIB_STD_B25_BUFFER sbuf, dbuf; int code; + if(use_udp) { + sfd = data->sock_data->sfd; + addr = (struct sockaddr *)&data->sock_data->addr; + } + while(1) { buf = dequeue(p_queue); /* no entry in the queue */ @@ -165,9 +183,19 @@ break; } write(wfd, dbuf.data, dbuf.size); + + if(use_udp && sfd) { + sendto(sfd, dbuf.data, dbuf.size, 0, + addr, sizeof(struct sockaddr_in)); + } free(buf); } else { write(wfd, sbuf.data, sbuf.size); + + if(use_udp && sfd) { + sendto(sfd, sbuf.data, sbuf.size, 0, + addr, sizeof(struct sockaddr_in)); + } free(buf); } @@ -178,11 +206,18 @@ if(code < 0) { fprintf(stderr, "b25_finish failed\n"); close(wfd); + close(sfd); break; } write(wfd, dbuf.data, dbuf.size); + + if(use_udp && sfd) { + sendto(sfd, dbuf.data, dbuf.size, 0, + addr, sizeof(struct sockaddr_in)); + } } close(wfd); + close(sfd); break; } } @@ -190,10 +225,16 @@ return NULL; } +void +show_usage(char *cmd) +{ + fprintf(stderr, "Usage: %s [--b25 [--round N] [--strip] [--EMM]] [--udp hostname [--port port]] channel recsec destfile\n", cmd); +} + int main(int argc, char **argv) { - int fd, wfd; + int tfd, wfd; int lp; int recsec; time_t start_time, cur_time; @@ -204,9 +245,12 @@ BUFSZ *bufptr; decoder *dec = NULL; thread_data tdata; - decoder_options dopt; + decoder_options dopt = { + 4, /* round */ + 0, /* strip */ + 0 /* emm */ + }; - int use_b25 = 0; int result; int option_index; struct option long_options[] = { @@ -215,42 +259,55 @@ { "round", 1, NULL, 'r'}, { "strip", 0, NULL, 's'}, { "emm", 0, NULL, 'm'}, - { "EMM", 0, NULL, 'm'} + { "EMM", 0, NULL, 'm'}, + { "udp", 1, NULL, 'u'}, + { "port", 1, NULL, 'p'} }; - dopt.round = 4; - dopt.strip = 0; - dopt.emm = 0; + int use_b25 = 0; + int use_udp = 0; + char *host_to = NULL; + int port_to = 1234; + sock_data *sdata = NULL; - while((result = getopt_long(argc, argv, "br:sm", long_options, &option_index)) != -1) { + while((result = getopt_long(argc, argv, "br:sm" "u:p:", long_options, &option_index)) != -1) { switch(result) { case 'b': - use_b25 = 1; + use_b25 = 1; fprintf(stderr, "using B25...\n"); - break; + break; case 's': - dopt.strip = 1; + dopt.strip = 1; fprintf(stderr, "enable B25 strip\n"); - break; + break; case 'm': - dopt.emm = 1; + dopt.emm = 1; fprintf(stderr, "enable B25 emm processing\n"); - break; + break; case 'r': - dopt.round = atoi(optarg); + dopt.round = atoi(optarg); fprintf(stderr, "set round %d\n", dopt.round); break; case ':': fprintf(stderr, "%c needs value\n", result); break; case '?': - fprintf(stderr, "Usage: [--b25 [--round N] [--strip] [--EMM]] channel recsec destfile\n"); + show_usage(argv[0]); + break; + case 'u': + use_udp = 1; + host_to = optarg; + fprintf(stderr, "UDP destination address: %s\n", host_to); + break; + case 'p': + port_to = atoi(optarg); + fprintf(stderr, "UDP port: %d\n", port_to); break; } } - if(argc - optind < 3) { - printf("Usage %s: [--b25 [--round N] [--strip] [--EMM]] channel recsec destfile\n", argv[0]); + if(argc - optind < 3) { + show_usage(argv[0]); printf("channel =\n"); printf("151ch:BS朝日\n"); printf("161ch:BS-i\n"); @@ -267,39 +324,39 @@ printf("CS2-CS24:CSチャンネル\n"); return 1; } - ptr = searchrecoff(argv[optind]); - if(ptr == NULL){ - printf("Channel Select Error(%s)\n", argv[optind]); - return 1; - } + ptr = searchrecoff(argv[optind]); + if(ptr == NULL){ + printf("Channel Select Error(%s)\n", argv[optind]); + return 1; + } freq.frequencyno = ptr->set_freq; freq.slot = ptr->add_freq; if(ptr->type == CHTYPE_SATELLITE) { for(lp = 0; lp < 2; lp++) { - fd = open(bsdev[lp], O_RDONLY); - if(fd >= 0) { + tfd = open(bsdev[lp], O_RDONLY); + if(tfd >= 0) { break; } } - if(fd < 0) { + if(tfd < 0) { fprintf(stderr, "Device Open Error\n"); return 1; } } else { for(lp = 0; lp < 2; lp++) { - fd = open(isdb_t_dev[lp], O_RDONLY); - if(fd >= 0) { + tfd = open(isdb_t_dev[lp], O_RDONLY); + if(tfd >= 0) { break; } } - if(fd < 0) { + if(tfd < 0) { fprintf(stderr, "Device Open Error\n"); return 1; } } - recsec = atoi(argv[optind + 1]); + recsec = atoi(argv[optind + 1]); /* initialize decoder */ if(use_b25) { @@ -311,6 +368,28 @@ } } + /* initialize udp connection */ + if(use_udp) { + sdata = calloc(1, sizeof(sock_data)); + struct in_addr ia; + ia.s_addr = inet_addr(host_to); + if(ia.s_addr == INADDR_NONE) { + struct hostent *hoste = gethostbyname(host_to); + if(!hoste) { + perror("failed to get host by name"); + return 1; + } + ia.s_addr = *(in_addr_t*) (hoste->h_addr_list[0]); + } + sdata->addr.sin_family = AF_INET; + sdata->addr.sin_port = htons (port_to); + sdata->addr.sin_addr.s_addr = ia.s_addr; + if((sdata->sfd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { + perror("socket"); + return 1; + } + } + /* open output file */ wfd = open(argv[optind + 2], (O_RDWR | O_CREAT | O_TRUNC), 0666); if(wfd < 0) { @@ -318,7 +397,7 @@ return 1; } - if(ioctl(fd, SET_CHANNEL, &freq) < 0) { + if(ioctl(tfd, SET_CHANNEL, &freq) < 0) { fprintf(stderr, "Tuner Select Error\n"); return 1; } @@ -326,11 +405,12 @@ /* make reader thread */ tdata.queue = p_queue; tdata.decoder = dec; - tdata.fd = wfd; + tdata.wfd = wfd; + tdata.sock_data = sdata; pthread_create(&dequeue_threads, NULL, write_func, &tdata); /* start recording */ - if(ioctl(fd, START_REC, 0) < 0) { + if(ioctl(tfd, START_REC, 0) < 0) { fprintf(stderr, "Tuner Start Error\n"); return 1; } @@ -341,7 +421,7 @@ while(1) { time(&cur_time); bufptr = malloc(sizeof(BUFSZ)); - bufptr->size = read(fd, bufptr->buffer, MAX_READ_SIZE); + bufptr->size = read(tfd, bufptr->buffer, MAX_READ_SIZE); if(bufptr->size <= 0) { if((cur_time - start_time) >= recsec) { f_exit = TRUE; @@ -355,11 +435,11 @@ /* stop recording */ if((cur_time - start_time) >= recsec) { - ioctl(fd, STOP_REC, 0); + ioctl(tfd, STOP_REC, 0); /* read remaining data */ while(1) { bufptr = malloc(sizeof(BUFSZ)); - bufptr->size = read(fd, bufptr->buffer, MAX_READ_SIZE); + bufptr->size = read(tfd, bufptr->buffer, MAX_READ_SIZE); if(bufptr->size <= 0) { f_exit = TRUE; enqueue(p_queue, NULL); @@ -371,12 +451,18 @@ } } /* close tuner */ - close(fd); + close(tfd); /* wait reader thread */ pthread_join(dequeue_threads, NULL); destroy_queue(p_queue); + /* close socket */ + if(use_udp) { + close(sdata->sfd); + free(sdata); + } + /* release decoder */ if(use_b25) { b25_shutdown(dec);