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);