Thread: [Redbutton-devel] SF.net SVN: redbutton: [5] redbutton-download/trunk
Brought to you by:
skilvington
|
From: <ski...@us...> - 2006-03-01 16:05:42
|
Revision: 5 Author: skilvington Date: 2006-03-01 08:05:30 -0800 (Wed, 01 Mar 2006) ViewCVS: http://svn.sourceforge.net/redbutton/?rev=5&view=rev Log Message: ----------- allow rb-download to listen for commands from rb-browser Modified Paths: -------------- redbutton-download/trunk/Makefile redbutton-download/trunk/TODO redbutton-download/trunk/rb-download.c redbutton-download/trunk/utils.c redbutton-download/trunk/utils.h Added Paths: ----------- redbutton-download/trunk/command.c redbutton-download/trunk/command.h redbutton-download/trunk/listen.c redbutton-download/trunk/listen.h Modified: redbutton-download/trunk/Makefile =================================================================== --- redbutton-download/trunk/Makefile 2006-03-01 10:26:41 UTC (rev 4) +++ redbutton-download/trunk/Makefile 2006-03-01 16:05:30 UTC (rev 5) @@ -4,6 +4,8 @@ OBJS= rb-download.o \ list.o \ findmheg.o \ + listen.o \ + command.o \ assoc.o \ carousel.o \ module.o \ Modified: redbutton-download/trunk/TODO =================================================================== --- redbutton-download/trunk/TODO 2006-03-01 10:26:41 UTC (rev 4) +++ redbutton-download/trunk/TODO 2006-03-01 16:05:30 UTC (rev 5) @@ -1,3 +1,5 @@ +replace TRUE/FALSE with stdbool + work out why this happened on BBC1 once: read: Value too large for defined data type Unable to read PID Added: redbutton-download/trunk/command.c =================================================================== --- redbutton-download/trunk/command.c (rev 0) +++ redbutton-download/trunk/command.c 2006-03-01 16:05:30 UTC (rev 5) @@ -0,0 +1,185 @@ +/* + * command.c + */ + +#include <stdio.h> +#include <string.h> +#include <stdbool.h> + +#include "command.h" +#include "utils.h" + +/* max number of args that can be passed to a command (arbitrary) */ +#define ARGV_MAX 10 + +/* the commands */ +bool cmd_file(struct listen_data *, int, int, char **); +bool cmd_help(struct listen_data *, int, int, char **); +bool cmd_quit(struct listen_data *, int, int, char **); + +static struct +{ + char *name; + char *args; + bool (*proc)(struct listen_data *, int, int, char **); + char *help; +} command[] = +{ + { "exit", "", cmd_quit, "Kill the programme" }, + { "file", "<ContentReference>", cmd_file, "Retrieve the given file from the carousel" }, + { "help", "", cmd_help, "List available commands" }, + { "quit", "", cmd_quit, "Kill the programme" }, + { NULL, NULL, NULL, NULL } +}; + +/* + * process the given command + * return true if we should quit the programme + */ + +bool +process_command(struct listen_data *listen_data, int client_sock, char *cmd) +{ + int argc; + char *argv[ARGV_MAX]; + char term; + unsigned int cmd_len; + int i; + + /* chop it into words, complicated by quoting */ + argc = 0; + while(argc < ARGV_MAX && *cmd != '\0') + { + argv[argc++] = cmd; + /* do we need to find the next space, or the next quote */ + if(*cmd == '\'' || *cmd == '"') + { + term = *cmd; + /* remove/skip the opening quote */ + argv[argc-1] ++; + cmd ++; + } + else + { + /* stop at the next space */ + term = ' '; + } + /* find the next terminating character */ + while(*cmd != term && *cmd != '\0') + cmd ++; + /* if this is not the end, skip to the start of the next word */ + if(*cmd != '\0') + { + /* terminate the last word */ + *cmd = '\0'; + /* move onto the next non-space character */ + cmd = skip_ws(cmd + 1); + } + } + + cmd_len = strlen(argv[0]); + for(i=0; command[i].name != NULL; i++) + { + if(strncmp(argv[0], command[i].name, cmd_len) == 0) + return (command[i].proc)(listen_data, client_sock, argc, argv); + } + + write_string(client_sock, "500 Unrecognised command\n"); + + return false; +} + +/* + * the commands + * listen_data is global data needed by listener commands + * client_sock is where any response data should go + * argc is the number of arguments passed to it + * argv[0] is the command name (or the abreviation the user used) + * return true if we should quit the programme + */ + +/* + * file <ContentReference> + * send the given file down client_sock + * ContentReference should be absolute, ie start with "~//" + */ + +bool +cmd_file(struct listen_data *listen_data, int client_sock, int argc, char *argv[]) +{ + char *filename; + FILE *file; + size_t nread; + char buff[1024 * 8]; + + if(argc != 2) + { + write_string(client_sock, "500 Syntax: file <ContentReference>\n"); + return false; + } + + filename = argv[1]; + + /* is ContentReference absolute */ + if(strlen(filename) < 3 || strncmp(filename, "~//", 3) != 0) + { + write_string(client_sock, "500 ContentReference is not absolute\n"); + return false; + } + + /* strip off the ~// prefix */ + filename += 3; + + if((file = fopen(filename, "r")) == NULL) + { + write_string(client_sock, "404 Not found\n"); + return false; + } + + write_string(client_sock, "200 OK\n"); + + do + { + nread = fread(buff, 1, sizeof(buff), file); + write_all(client_sock, buff, nread); + } + while(nread == sizeof(buff)); + + fclose(file); + + return false; +} + +/* + * help + */ + +bool +cmd_help(struct listen_data *listen_data, int client_sock, int argc, char *argv[]) +{ + int i; + char name_args[64]; + char help_line[128]; + + write_string(client_sock, "200 OK\n"); + + for(i=0; command[i].name != NULL; i++) + { + snprintf(name_args, sizeof(name_args), "%s %s", command[i].name, command[i].args); + snprintf(help_line, sizeof(help_line), "%-30s %s\n", name_args, command[i].help); + write_string(client_sock, help_line); + } + + return false; +} + +/* + * quit + */ + +bool +cmd_quit(struct listen_data *listen_data, int client_sock, int argc, char *argv[]) +{ + return true; +} + Added: redbutton-download/trunk/command.h =================================================================== --- redbutton-download/trunk/command.h (rev 0) +++ redbutton-download/trunk/command.h 2006-03-01 16:05:30 UTC (rev 5) @@ -0,0 +1,12 @@ +/* + * command.h + */ + +#ifndef __COMMAND_H__ +#define __COMMAND_H__ + +#include "listen.h" + +bool process_command(struct listen_data *, int, char *); + +#endif Added: redbutton-download/trunk/listen.c =================================================================== --- redbutton-download/trunk/listen.c (rev 0) +++ redbutton-download/trunk/listen.c 2006-03-01 16:05:30 UTC (rev 5) @@ -0,0 +1,249 @@ +/* + * listen.c + */ + +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <ctype.h> +#include <string.h> +#include <signal.h> +#include <stdbool.h> +#include <errno.h> +#include <netdb.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <sys/types.h> +#include <sys/wait.h> + +#include "command.h" +#include "utils.h" + +/* listen() backlog, 5 is max for BSD apparently */ +#define BACKLOG 5 + +/* internal functions */ +static int get_host_addr(char *, struct in_addr *); + +static bool handle_connection(struct listen_data *, int, struct sockaddr_in *); +static void dead_child(int); + +/* + * extract the IP addr and port number from a string in one of these forms: + * host:port + * ip-addr:port + * host + * ip-addr + * port + * if the string is NULL, or the host or the port are not defined in the string, + * the corresponding param passed to this routine is not changed + * ip and port are both returned in network byte order + * returns -1 on error (can't resolve host name) + */ + +int +parse_addr(char *str, struct in_addr *ip, in_port_t *port) +{ + char *p; + int ishost; + + /* easy case */ + if(str == NULL) + return 0; + + if((p = strchr(str, ':')) != NULL) + { + /* its either host:port or ip:port */ + *(p++) = '\0'; + if(get_host_addr(str, ip) < 0) + return -1; + *port = htons(atoi(p)); + /* reconstruct the string */ + *(--p) = ':'; + } + else + { + /* its either host, ip, or port */ + /* all digits => a port number */ + ishost = 0; + for(p=str; *p && !ishost; p++) + ishost = !isdigit(*p); + if(ishost) + { + if(get_host_addr(str, ip) < 0) + return -1; + } + else + { + *port = htons(atoi(str)); + } + } + + return 0; +} + +/* + * puts the IP address associated with the given host into output buffer + * host can be a.b.c.d or a host name + * returns 0 if successful, -1 on error + */ + +static int +get_host_addr(char *host, struct in_addr *output) +{ + struct hostent *he; + int error = 0; + + if(((he = gethostbyname(host)) != NULL) && (he->h_addrtype == AF_INET)) + memcpy(output, he->h_addr, sizeof(struct in_addr)); + else + error = -1; + + return error; +} + +/* + * start a process to listen on the given interface for commands from a remote rb-browser + */ + +void +start_listener(struct listen_data *listen_data) +{ + struct sigaction action; + pid_t child; + int sockopt; + int listen_sock; + int accept_sock; + fd_set read_fds; + socklen_t addr_len; + struct sockaddr_in client_addr; + bool quit; + + /* + * fork: + * the parent listens for commands, + * the child returns and downloads the carousel + */ + + /* don't let our children become zombies */ + action.sa_handler = dead_child; + sigemptyset(&action.sa_mask); + action.sa_flags = 0; + if(sigaction(SIGCHLD, &action, NULL) < 0) + fatal("signal: SIGCHLD: %s", strerror(errno)); + + /* if we can't fork it's probably best to kill ourselves*/ + if((child = fork()) < 0) + fatal("fork: %s", strerror(errno)); + /* child returns */ + else if(child == 0) + return; + /* parent continues */ + + /* listen on the given ip:port */ + printf("Listening on %s:%u\n", inet_ntoa(listen_data->addr.sin_addr), ntohs(listen_data->addr.sin_port)); + + if((listen_sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) + fatal("socket: %s", strerror(errno)); + + /* in case someones already using it */ + sockopt = 1; + if(setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &sockopt, sizeof(sockopt)) < 0) + fatal("setsockopt: SO_REUSEADDR: %s", strerror(errno)); + + if(bind(listen_sock, (struct sockaddr *) &listen_data->addr, sizeof(struct sockaddr_in)) < 0) + fatal("bind: %s", strerror(errno)); + + if(listen(listen_sock, BACKLOG) < 0) + fatal("listen: %s", strerror(errno)); + + /* listen for connections */ + while(true) + { + FD_ZERO(&read_fds); + FD_SET(listen_sock, &read_fds); + if(select(listen_sock + 1, &read_fds, NULL, NULL, NULL) < 0) + { + /* could have been interupted by SIGCHLD */ + if(errno != EINTR) + error("select: %s", strerror(errno)); + continue; + } + /* check select didnt fuck up */ + if(!FD_ISSET(listen_sock, &read_fds)) + continue; + addr_len = sizeof(client_addr); + if((accept_sock = accept(listen_sock, (struct sockaddr *) &client_addr, &addr_len)) < 0) + { + /* we get ECONNABORTED in Linux if we're being SYN scanned */ + error("accept: %s", strerror(errno)); + continue; + } + /* fork off a child to handle it */ + if((child = fork()) < 0) + { + /* if we can't fork it's probably best to kill ourselves*/ + fatal("fork: %s", strerror(errno)); + } + else if(child == 0) + { + /* child */ + close(listen_sock); + quit = handle_connection(listen_data, accept_sock, &client_addr); + close(accept_sock); +/* TODO */ +if(quit) printf("QUIT!!!\n"); + exit(EXIT_SUCCESS); + } + else + { + /* parent */ + close(accept_sock); + } + } + + /* we never get here */ + close(listen_sock); + + return; +} + +/* + * handle a connection from a remote rb-browser + */ + +static bool +handle_connection(struct listen_data *listen_data, int client_sock, struct sockaddr_in *client_addr) +{ + char cmd[1024]; + ssize_t nread; + bool quit = false; + + printf("Connection from %s:%d\n", inet_ntoa(client_addr->sin_addr), ntohs(client_addr->sin_port)); + + /* read the command from the client */ + if((nread = read(client_sock, cmd, sizeof(cmd)-1)) > 0) + { + /* \0 terminate the buffer */ + cmd[nread] = '\0'; + /* strip off an trailing \n (only needed when testing with telnet etc) */ + nread --; + while(nread > 0 && (cmd[nread] == '\n' || cmd[nread] == '\r')) + cmd[nread--] = '\0'; + /* process the command */ + quit = process_command(listen_data, client_sock, cmd); + } + + printf("Connection from %s:%d closed\n", inet_ntoa(client_addr->sin_addr), ntohs(client_addr->sin_port)); + + return quit; +} + +static void +dead_child(int signo) +{ + if(signo == SIGCHLD) + wait(NULL); + + return; +} Added: redbutton-download/trunk/listen.h =================================================================== --- redbutton-download/trunk/listen.h (rev 0) +++ redbutton-download/trunk/listen.h 2006-03-01 16:05:30 UTC (rev 5) @@ -0,0 +1,19 @@ +/* + * listen.h + */ + +#ifndef __LISTEN_H__ +#define __LISTEN_H__ + +#include <netinet/in.h> + +struct listen_data +{ + struct sockaddr_in addr; /* ip:port to listen on */ +}; + +int parse_addr(char *, struct in_addr *, in_port_t *); + +void start_listener(struct listen_data *); + +#endif Modified: redbutton-download/trunk/rb-download.c =================================================================== --- redbutton-download/trunk/rb-download.c 2006-03-01 10:26:41 UTC (rev 4) +++ redbutton-download/trunk/rb-download.c 2006-03-01 16:05:30 UTC (rev 5) @@ -1,5 +1,5 @@ /* - * rb-download [-d <demux_device>] [-b <base_dir>] [-t <timeout>] [-c <carousel_id>] [<service_id>] + * rb-download [-d <demux_device>] [-b <base_dir>] [-t <timeout>] [-l[<listen-addr>]] [-c <carousel_id>] [<service_id>] * * Download the DVB Object Carousel for the given channel onto the local hard disc * files will be stored under the current dir if no -b option is given @@ -7,6 +7,17 @@ * if no service_id is given, a list of possible channels (and their service_id) is printed * the carousel ID is normally read from the PMT, use -c to explicitly set it * + * the default timeout is 10 seconds + * if no DSMCC data is read after this time, it is assumed none is being broadcast + * + * if -l is given, rb-download listens on the network for commands from a remote rb-browser + * the default IP to listen on is 0.0.0.0 (ie all interfaces), the default TCP port is 10101 + * listen-addr should be given in the form "host:port", where host defaults to 0.0.0.0 and port defaults to 10101 + * eg, to listen on a different port, do "-l8080" + * to only listen on the loop back, do "-l127.0.0.1" or on a different port too, do "-l127.0.0.1:8080" + * NOTE: because -l may or may not take an argument, you must not put a space between the -l and the value + * (otherwise, "rb-download -l 1234", is ambiguous - listen on port 1234 or use service_id 1234?) + * * the file structure will be: * ./services/<service_id> * this is a symlink to the root of the carousel @@ -17,7 +28,7 @@ */ /* - * Copyright (C) 2005, Simon Kilvington + * Copyright (C) 2005, 2006, Simon Kilvington * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -39,11 +50,14 @@ #include <stdio.h> #include <stdlib.h> #include <stdint.h> +#include <stdbool.h> #include <errno.h> +#include <netinet/in.h> #include "list.h" #include "findmheg.h" #include "carousel.h" +#include "listen.h" #include "utils.h" /* DVB demux device */ @@ -52,6 +66,10 @@ /* seconds before we assume no DSMCC data is available on this PID */ #define DEFAULT_TIMEOUT 10 +/* default listen address */ +#define DEFAULT_LISTEN_ADDR INADDR_ANY +#define DEFAULT_LISTEN_PORT 10101 + void usage(char *); int @@ -60,12 +78,14 @@ char *prog_name = argv[0]; char *device = DEFAULT_DEVICE; unsigned int timeout = DEFAULT_TIMEOUT; + bool listen = false; + struct listen_data listen_data; int carousel_id = -1; uint16_t service_id; struct carousel *car; int arg; - while((arg = getopt(argc, argv, "d:b:t:c:")) != EOF) + while((arg = getopt(argc, argv, "d:b:t:l::c:")) != EOF) { switch(arg) { @@ -82,6 +102,16 @@ timeout = strtoul(optarg, NULL, 0); break; + case 'l': + listen = true; + /* default values */ + listen_data.addr.sin_addr.s_addr = htonl(DEFAULT_LISTEN_ADDR); + listen_data.addr.sin_port = htons(DEFAULT_LISTEN_PORT); + /* optarg is NULL if no value is given, parse_addr can't fail with NULL */ + if(parse_addr(optarg, &listen_data.addr.sin_addr, &listen_data.addr.sin_port) < 0) + fatal("Unable to resolve host %s", optarg); + break; + case 'c': carousel_id = strtoul(optarg, NULL, 0); break; @@ -101,6 +131,8 @@ service_id = strtoul(argv[optind], NULL, 0); car = find_mheg(device, timeout, service_id, carousel_id); printf("Carousel ID=%u\n", car->carousel_id); + if(listen) + start_listener(&listen_data); load_carousel(car); } else @@ -114,6 +146,11 @@ void usage(char *prog_name) { - fatal("Usage: %s [-d <demux_device>] [-b <base_dir>] [-t <timeout>] [-c carousel_id] [<service_id>]", prog_name); + fatal("Usage: %s [-d <demux_device>] " + "[-b <base_dir>] " + "[-t <timeout>] " + "[-l[<listen-addr>]] " + "[-c carousel_id] " + "[<service_id>]", prog_name); } Modified: redbutton-download/trunk/utils.c =================================================================== --- redbutton-download/trunk/utils.c 2006-03-01 10:26:41 UTC (rev 4) +++ redbutton-download/trunk/utils.c 2006-03-01 16:05:30 UTC (rev 5) @@ -20,13 +20,76 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <stdarg.h> +#include <string.h> #include <ctype.h> +#include <errno.h> #include "utils.h" +/* + * write the given string (ie upto \0) to the given fd + */ + +void +write_string(int fd, const char *str) +{ + write_all(fd, str, strlen(str)); + + return; +} + +/* + * guarantee writing count bytes from buf to fd + * W. Richard Stevens + */ + +void +write_all(int fd, const void *buf, size_t count) +{ + size_t nwritten; + const char *buf_ptr; + + buf_ptr = buf; + while(count > 0) + { + if((nwritten = write(fd, buf_ptr, count)) < 0) + { + if(errno == EINTR || errno == EAGAIN) + nwritten = 0; + else + fatal("write: %s\n", strerror(errno)); + } + count -= nwritten; + buf_ptr += nwritten; + } + + return; +} + +/* + * move str to the next non-white space character (or the end of the string) + */ + +char * +skip_ws(char *str) +{ + if(str == NULL) + return NULL; + + while(*str != '\0' && isspace((int) *str)) + str ++; + + return str; +} + +/* + * returns a single ASCII char for the values 0-15 + */ + char hex_digit(uint8_t val) { Modified: redbutton-download/trunk/utils.h =================================================================== --- redbutton-download/trunk/utils.h 2006-03-01 10:26:41 UTC (rev 4) +++ redbutton-download/trunk/utils.h 2006-03-01 16:05:30 UTC (rev 5) @@ -36,6 +36,11 @@ #define MAX(a, b) ((a) > (b) ? (a) : (b)) #endif +void write_string(int, const char *); +void write_all(int, const void *, size_t); + +char *skip_ws(char *); + char hex_digit(uint8_t); void *safe_malloc(size_t); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <ski...@us...> - 2006-03-01 16:32:41
|
Revision: 6 Author: skilvington Date: 2006-03-01 08:32:29 -0800 (Wed, 01 Mar 2006) ViewCVS: http://svn.sourceforge.net/redbutton/?rev=6&view=rev Log Message: ----------- replace TRUE/FALSE with stdbool Modified Paths: -------------- redbutton-download/trunk/TODO redbutton-download/trunk/carousel.c redbutton-download/trunk/findmheg.c redbutton-download/trunk/module.c redbutton-download/trunk/module.h redbutton-download/trunk/utils.h Modified: redbutton-download/trunk/TODO =================================================================== --- redbutton-download/trunk/TODO 2006-03-01 16:05:30 UTC (rev 5) +++ redbutton-download/trunk/TODO 2006-03-01 16:32:29 UTC (rev 6) @@ -1,5 +1,3 @@ -replace TRUE/FALSE with stdbool - work out why this happened on BBC1 once: read: Value too large for defined data type Unable to read PID Modified: redbutton-download/trunk/carousel.c =================================================================== --- redbutton-download/trunk/carousel.c 2006-03-01 16:05:30 UTC (rev 5) +++ redbutton-download/trunk/carousel.c 2006-03-01 16:32:29 UTC (rev 6) @@ -22,6 +22,7 @@ #include <stdio.h> #include <stdint.h> +#include <stdbool.h> #include <netinet/in.h> #include "carousel.h" @@ -34,14 +35,14 @@ load_carousel(struct carousel *car) { unsigned char *table; - int done; + bool done; /* no modules yet */ car->nmodules = 0; car->modules = NULL; /* see what the next DSMCC table is */ - done = FALSE; + done = false; do { struct dsmccMessageHeader *dsmcc; @@ -114,7 +115,7 @@ if(car->got_dsi) return; - car->got_dsi = TRUE; + car->got_dsi = true; elementary_pid = process_biop_service_gateway_info(car->service_id, &car->assoc, DSI_privateDataByte(dsi), ntohs(dsi->privateDataLength)); Modified: redbutton-download/trunk/findmheg.c =================================================================== --- redbutton-download/trunk/findmheg.c 2006-03-01 16:05:30 UTC (rev 5) +++ redbutton-download/trunk/findmheg.c 2006-03-01 16:32:29 UTC (rev 6) @@ -22,6 +22,7 @@ #include <stdio.h> #include <stdint.h> +#include <stdbool.h> #include <netinet/in.h> #include "carousel.h" @@ -68,7 +69,7 @@ uint16_t section_length; uint16_t offset; uint16_t map_pid = 0; - int found; + bool found; unsigned char *pmt; uint8_t stream_type; uint16_t elementary_pid; @@ -90,7 +91,7 @@ _car.npids = 0; _car.pids = NULL; /* no modules loaded yet */ - _car.got_dsi = FALSE; + _car.got_dsi = false; _car.nmodules = 0; _car.modules = NULL; @@ -101,7 +102,7 @@ section_length = 3 + (((pat[1] & 0x0f) << 8) + pat[2]); /* find the PMT for this service_id */ - found = FALSE; + found = false; offset = 8; /* -4 for the CRC at the end */ while((offset < (section_length - 4)) && !found) @@ -109,7 +110,7 @@ if((pat[offset] << 8) + pat[offset+1] == service_id) { map_pid = ((pat[offset+2] & 0x1f) << 8) + pat[offset+3]; - found = TRUE; + found = true; } else { Modified: redbutton-download/trunk/module.c =================================================================== --- redbutton-download/trunk/module.c 2006-03-01 16:05:30 UTC (rev 5) +++ redbutton-download/trunk/module.c 2006-03-01 16:32:29 UTC (rev 6) @@ -22,6 +22,7 @@ #include <stdio.h> #include <string.h> +#include <stdbool.h> #include <zlib.h> #include <netinet/in.h> @@ -77,8 +78,8 @@ mod->block_size = ntohs(dii->blockSize); mod->nblocks = (ntohl(diimod->moduleSize) + mod->block_size - 1) / mod->block_size; mod->blocks_left = mod->nblocks; - mod->got_block = safe_malloc(mod->nblocks); - bzero(mod->got_block, mod->nblocks); + mod->got_block = safe_malloc(mod->nblocks * sizeof(bool)); + bzero(mod->got_block, mod->nblocks * sizeof(bool)); mod->size = ntohl(diimod->moduleSize); mod->data = safe_malloc(mod->size); @@ -126,7 +127,7 @@ if(mod->got_block[block]) return; - mod->got_block[block] = TRUE; + mod->got_block[block] = true; memcpy(mod->data + (block * mod->block_size), data, length); mod->blocks_left --; Modified: redbutton-download/trunk/module.h =================================================================== --- redbutton-download/trunk/module.h 2006-03-01 16:05:30 UTC (rev 5) +++ redbutton-download/trunk/module.h 2006-03-01 16:32:29 UTC (rev 6) @@ -24,6 +24,7 @@ #define __MODULE_H__ #include <stdint.h> +#include <stdbool.h> #include "dsmcc.h" #include "assoc.h" @@ -45,7 +46,7 @@ uint16_t block_size; uint16_t nblocks; uint32_t blocks_left; /* number of blocks left to download */ - unsigned char *got_block; /* which blocks we have downloaded so far */ + bool *got_block; /* which blocks we have downloaded so far */ uint32_t size; /* size of the file */ unsigned char *data; /* the actual file data */ }; @@ -61,7 +62,7 @@ struct assoc assoc; /* map stream_id's to elementary_pid's */ int32_t npids; /* PIDs we are reading data from */ struct pid_fds *pids; /* array, npids in length */ - int got_dsi; /* TRUE if we have downloaded the DSI */ + bool got_dsi; /* true if we have downloaded the DSI */ uint32_t nmodules; /* modules we have/are downloading */ struct module *modules; /* array, nmodules in length */ }; Modified: redbutton-download/trunk/utils.h =================================================================== --- redbutton-download/trunk/utils.h 2006-03-01 16:05:30 UTC (rev 5) +++ redbutton-download/trunk/utils.h 2006-03-01 16:32:29 UTC (rev 6) @@ -27,11 +27,6 @@ #include <stdarg.h> #include <stdint.h> -#ifndef FALSE -#define FALSE 0 -#define TRUE 1 -#endif - #ifndef MAX #define MAX(a, b) ((a) > (b) ? (a) : (b)) #endif This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <ski...@us...> - 2006-03-02 11:12:08
|
Revision: 7 Author: skilvington Date: 2006-03-02 03:11:58 -0800 (Thu, 02 Mar 2006) ViewCVS: http://svn.sourceforge.net/redbutton/?rev=7&view=rev Log Message: ----------- canonicalise ContentReferences passed to rb-download Modified Paths: -------------- redbutton-download/trunk/command.c redbutton-download/trunk/listen.h redbutton-download/trunk/rb-download.c Modified: redbutton-download/trunk/command.c =================================================================== --- redbutton-download/trunk/command.c 2006-03-01 16:32:29 UTC (rev 6) +++ redbutton-download/trunk/command.c 2006-03-02 11:11:58 UTC (rev 7) @@ -7,12 +7,14 @@ #include <stdbool.h> #include "command.h" +#include "fs.h" #include "utils.h" /* max number of args that can be passed to a command (arbitrary) */ #define ARGV_MAX 10 /* the commands */ +bool cmd_check(struct listen_data *, int, int, char **); bool cmd_file(struct listen_data *, int, int, char **); bool cmd_help(struct listen_data *, int, int, char **); bool cmd_quit(struct listen_data *, int, int, char **); @@ -25,13 +27,21 @@ char *help; } command[] = { - { "exit", "", cmd_quit, "Kill the programme" }, - { "file", "<ContentReference>", cmd_file, "Retrieve the given file from the carousel" }, - { "help", "", cmd_help, "List available commands" }, - { "quit", "", cmd_quit, "Kill the programme" }, + { "check", "<ContentReference>", cmd_check, "Check if the given file exists on the carousel" }, + { "exit", "", cmd_quit, "Kill the programme" }, + { "file", "<ContentReference>", cmd_file, "Retrieve the given file from the carousel" }, + { "help", "", cmd_help, "List available commands" }, + { "quit", "", cmd_quit, "Kill the programme" }, { NULL, NULL, NULL, NULL } }; +/* send an OK/error code etc response down client_sock */ +#define SEND_RESPONSE(RC, MESSAGE) write_string(client_sock, #RC " " MESSAGE "\n") + +/* internal routines */ +char *external_filename(struct listen_data *, char *); +char *canonical_filename(char *); + /* * process the given command * return true if we should quit the programme @@ -84,7 +94,7 @@ return (command[i].proc)(listen_data, client_sock, argc, argv); } - write_string(client_sock, "500 Unrecognised command\n"); + SEND_RESPONSE(500, "Unrecognised command"); return false; } @@ -98,7 +108,47 @@ * return true if we should quit the programme */ +#define CHECK_USAGE(ARGC, SYNTAX) \ +if(argc != ARGC) \ +{ \ + SEND_RESPONSE(500, "Syntax: " SYNTAX); \ + return false; \ +} + /* + * check <ContentReference> + * check if the given file is on the carousel + * ContentReference should be absolute, ie start with "~//" + */ + +bool +cmd_check(struct listen_data *listen_data, int client_sock, int argc, char *argv[]) +{ + char *filename; + FILE *file; + + CHECK_USAGE(2, "check <ContentReference>"); + + if((filename = external_filename(listen_data, argv[1])) == NULL) + { + SEND_RESPONSE(500, "Invalid ContentReference"); + return false; + } + + if((file = fopen(filename, "r")) != NULL) + { + fclose(file); + SEND_RESPONSE(200, "OK"); + } + else + { + SEND_RESPONSE(404, "Not found"); + } + + return false; +} + +/* * file <ContentReference> * send the given file down client_sock * ContentReference should be absolute, ie start with "~//" @@ -112,32 +162,23 @@ size_t nread; char buff[1024 * 8]; - if(argc != 2) - { - write_string(client_sock, "500 Syntax: file <ContentReference>\n"); - return false; - } + CHECK_USAGE(2, "file <ContentReference>"); - filename = argv[1]; - - /* is ContentReference absolute */ - if(strlen(filename) < 3 || strncmp(filename, "~//", 3) != 0) + if((filename = external_filename(listen_data, argv[1])) == NULL) { - write_string(client_sock, "500 ContentReference is not absolute\n"); + SEND_RESPONSE(500, "Invalid ContentReference"); return false; } - /* strip off the ~// prefix */ - filename += 3; - if((file = fopen(filename, "r")) == NULL) { - write_string(client_sock, "404 Not found\n"); + SEND_RESPONSE(404, "Not found"); return false; } - write_string(client_sock, "200 OK\n"); + SEND_RESPONSE(200, "OK"); + /* send the file contents */ do { nread = fread(buff, 1, sizeof(buff), file); @@ -161,7 +202,7 @@ char name_args[64]; char help_line[128]; - write_string(client_sock, "200 OK\n"); + SEND_RESPONSE(200, "OK"); for(i=0; command[i].name != NULL; i++) { @@ -183,3 +224,86 @@ return true; } +/* + * return a filename that can be used to load the given ContentReference from the filesystem + * returns a static string that will be overwritten by the next call to this routine + * returns NULL if the ContentReference is invalid (does not start with ~// or has too many .. components) + */ + +static char _external[PATH_MAX]; + +char * +external_filename(struct listen_data *listen_data, char *cref) +{ + char *canon_cref; + + /* is ContentReference absolute */ + if(strlen(cref) < 3 || strncmp(cref, "~//", 3) != 0) + return NULL; + + /* strip off the ~// prefix, and canonicalise the reference */ + canon_cref = canonical_filename(cref + 3); + + /* if the canonical name starts with "../", it is invalid */ + if(strncmp(canon_cref, "../", 3) == 0) + return NULL; + + /* create the carousel filename, ie prepend the servive gateway directory */ + snprintf(_external, sizeof(_external), "%s/%u/%s", SERVICES_DIR, listen_data->carousel->service_id, canon_cref); + + return _external; +} + +/* + * return a string that recursively removes all sequences of the form '/x/../' in path + * returns a static string that will be overwritten by the next call to this routine + */ + +static char _canon[PATH_MAX]; + +char * +canonical_filename(char *path) +{ + char *start; + char *slash; + size_t len; + + /* copy path into the output buffer */ + strncpy(_canon, path, sizeof(_canon)); + /* just in case */ + _canon[sizeof(_canon)-1] = '\0'; + + /* keep removing "/x/../" until there are none left */ + start = _canon; + while(true) + { + /* find the start of the first path component that is not "../" */ + while(strncmp(start, "../", 3) == 0) + start += 3; + /* find the next slash in the path */ + slash = start; + while(*slash != '/' && *slash != '\0') + slash ++; + /* no more slashes => nothing left to do */ + if(*slash == '\0') + return _canon; + /* if the next path component is "../", eat the previous one */ + if(strncmp(slash, "/../", 4) == 0) + { + /* include \0 terminator */ + len = strlen(start) + 1; + memmove(start, slash + 4, len - ((slash - start) + 4)); + /* restart the search */ + start = _canon; + } + else + { + /* move to the next component */ + start = slash + 1; + } + } + + /* not reached */ + return NULL; +} + Modified: redbutton-download/trunk/listen.h =================================================================== --- redbutton-download/trunk/listen.h 2006-03-01 16:32:29 UTC (rev 6) +++ redbutton-download/trunk/listen.h 2006-03-02 11:11:58 UTC (rev 7) @@ -7,9 +7,12 @@ #include <netinet/in.h> +#include "module.h" + struct listen_data { struct sockaddr_in addr; /* ip:port to listen on */ + struct carousel *carousel; /* carousel we are downloading */ }; int parse_addr(char *, struct in_addr *, in_port_t *); Modified: redbutton-download/trunk/rb-download.c =================================================================== --- redbutton-download/trunk/rb-download.c 2006-03-01 16:32:29 UTC (rev 6) +++ redbutton-download/trunk/rb-download.c 2006-03-02 11:11:58 UTC (rev 7) @@ -132,7 +132,10 @@ car = find_mheg(device, timeout, service_id, carousel_id); printf("Carousel ID=%u\n", car->carousel_id); if(listen) + { + listen_data.carousel = car; start_listener(&listen_data); + } load_carousel(car); } else This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <ski...@us...> - 2006-03-03 12:11:48
|
Revision: 12 Author: skilvington Date: 2006-03-03 04:11:41 -0800 (Fri, 03 Mar 2006) ViewCVS: http://svn.sourceforge.net/redbutton/?rev=12&view=rev Log Message: ----------- find default video and audio PIDs Modified Paths: -------------- redbutton-download/trunk/findmheg.c redbutton-download/trunk/module.h redbutton-download/trunk/rb-download.c Modified: redbutton-download/trunk/findmheg.c =================================================================== --- redbutton-download/trunk/findmheg.c 2006-03-02 17:11:17 UTC (rev 11) +++ redbutton-download/trunk/findmheg.c 2006-03-03 12:11:41 UTC (rev 12) @@ -37,10 +37,13 @@ /* Programme Map Section */ #define TID_PMT 0x02 -/* stream_type we are interested in */ +/* stream_types we are interested in */ +#define STREAM_TYPE_VIDEO 0x02 +#define STREAM_TYPE_AUDIO 0x03 #define STREAM_TYPE_ISO13818_6_B 0x0b /* descriptors we want */ +#define TAG_LANGUAGE_DESCRIPTOR 0x0a #define TAG_CAROUSEL_ID_DESCRIPTOR 0x13 #define TAG_STREAM_ID_DESCRIPTOR 0x52 @@ -55,6 +58,12 @@ uint8_t component_tag; }; +struct language_descriptor +{ + char language_code[3]; + uint8_t audio_type; +} __attribute__((__packed__)); + /* * fills in a struct carousel based on the given service_id * returns a ptr to a static struct that will be overwritten be the next call to this routine @@ -85,6 +94,9 @@ /* unknown */ _car.carousel_id = 0; + _car.audio_pid = 0; + _car.video_pid = 0; + _car.current_pid = 0; /* map between stream_id_descriptors and elementary_PIDs */ init_assoc(&_car.assoc); /* no PIDs yet */ @@ -135,8 +147,7 @@ offset += 2 + info_length; /* - * find the carousel_identification_descriptor - * and the stream_identification_descriptor + * find the Descriptor Tags we are interested in */ while(offset < (section_length - 4)) { @@ -144,6 +155,10 @@ offset += 1; elementary_pid = ((pmt[offset] & 0x1f) << 8) + pmt[offset+1]; offset += 2; + /* is it the default video stream for this service */ + if(stream_type == STREAM_TYPE_VIDEO) + _car.video_pid = elementary_pid; + /* read the descriptors */ info_length = ((pmt[offset] & 0x0f) << 8) + pmt[offset+1]; offset += 2; while(info_length != 0) @@ -171,6 +186,14 @@ // printf("pid=0x%x component_tag=0x%x\n", elementary_pid, component_tag); add_assoc(&_car.assoc, elementary_pid, desc->component_tag); } + else if(desc_tag == TAG_LANGUAGE_DESCRIPTOR && stream_type == STREAM_TYPE_AUDIO) + { + struct language_descriptor *desc; + desc = (struct language_descriptor *) &pmt[offset]; + /* only remember the normal audio stream (not visually impaired stream) */ + if(desc->audio_type == 0) + _car.audio_pid = elementary_pid; + } offset += desc_length; info_length -= desc_length; } Modified: redbutton-download/trunk/module.h =================================================================== --- redbutton-download/trunk/module.h 2006-03-02 17:11:17 UTC (rev 11) +++ redbutton-download/trunk/module.h 2006-03-03 12:11:41 UTC (rev 12) @@ -58,6 +58,8 @@ unsigned int timeout; /* timeout for the demux device */ uint16_t service_id; uint32_t carousel_id; + uint16_t audio_pid; /* PID of default audio stream for this service_id */ + uint16_t video_pid; /* PID of default video stream for this service_id */ uint16_t current_pid; /* PID we downloaded the last table from */ struct assoc assoc; /* map stream_id's to elementary_pid's */ int32_t npids; /* PIDs we are reading data from */ Modified: redbutton-download/trunk/rb-download.c =================================================================== --- redbutton-download/trunk/rb-download.c 2006-03-02 17:11:17 UTC (rev 11) +++ redbutton-download/trunk/rb-download.c 2006-03-03 12:11:41 UTC (rev 12) @@ -131,6 +131,8 @@ service_id = strtoul(argv[optind], NULL, 0); car = find_mheg(device, timeout, service_id, carousel_id); printf("Carousel ID=%u\n", car->carousel_id); + printf("Video PID=%u\n", car->video_pid); + printf("Audio PID=%u\n", car->audio_pid); if(listen) { listen_data.carousel = car; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <ski...@us...> - 2006-03-15 12:39:26
|
Revision: 17 Author: skilvington Date: 2006-03-15 04:39:15 -0800 (Wed, 15 Mar 2006) ViewCVS: http://svn.sourceforge.net/redbutton/?rev=17&view=rev Log Message: ----------- replace -d option with -a Modified Paths: -------------- redbutton-download/trunk/findmheg.c redbutton-download/trunk/findmheg.h redbutton-download/trunk/list.c redbutton-download/trunk/list.h redbutton-download/trunk/module.h redbutton-download/trunk/rb-download.c redbutton-download/trunk/table.c redbutton-download/trunk/utils.h Modified: redbutton-download/trunk/findmheg.c =================================================================== --- redbutton-download/trunk/findmheg.c 2006-03-04 14:42:35 UTC (rev 16) +++ redbutton-download/trunk/findmheg.c 2006-03-15 12:39:15 UTC (rev 17) @@ -72,7 +72,7 @@ static struct carousel _car; struct carousel * -find_mheg(char *device, unsigned int timeout, uint16_t service_id, int carousel_id) +find_mheg(unsigned int adapter, unsigned int timeout, uint16_t service_id, int carousel_id) { unsigned char *pat; uint16_t section_length; @@ -88,7 +88,8 @@ uint16_t component_tag; /* carousel data we know so far */ - _car.device = device; + snprintf(_car.demux_device, sizeof(_car.demux_device), DEMUX_DEVICE, adapter); + snprintf(_car.dvr_device, sizeof(_car.dvr_device), DVR_DEVICE, adapter); _car.timeout = timeout; _car.service_id = service_id; @@ -108,7 +109,7 @@ _car.modules = NULL; /* get the PAT */ - if((pat = read_table(device, PID_PAT, TID_PAT, timeout)) == NULL) + if((pat = read_table(_car.demux_device, PID_PAT, TID_PAT, timeout)) == NULL) fatal("Unable to read PAT"); section_length = 3 + (((pat[1] & 0x0f) << 8) + pat[2]); @@ -136,7 +137,7 @@ // printf("programme_map_PID: 0x%x\n", map_pid); /* get the PMT */ - if((pmt = read_table(device, map_pid, TID_PMT, timeout)) == NULL) + if((pmt = read_table(_car.demux_device, map_pid, TID_PMT, timeout)) == NULL) fatal("Unable to read PMT"); section_length = 3 + (((pmt[1] & 0x0f) << 8) + pmt[2]); Modified: redbutton-download/trunk/findmheg.h =================================================================== --- redbutton-download/trunk/findmheg.h 2006-03-04 14:42:35 UTC (rev 16) +++ redbutton-download/trunk/findmheg.h 2006-03-15 12:39:15 UTC (rev 17) @@ -25,7 +25,7 @@ #include <stdint.h> -struct carousel *find_mheg(char *, unsigned int, uint16_t, int); +struct carousel *find_mheg(unsigned int, unsigned int, uint16_t, int); #endif /* __FINDMHEG_H__ */ Modified: redbutton-download/trunk/list.c =================================================================== --- redbutton-download/trunk/list.c 2006-03-04 14:42:35 UTC (rev 16) +++ redbutton-download/trunk/list.c 2006-03-15 12:39:15 UTC (rev 17) @@ -21,20 +21,22 @@ */ #include <stdio.h> +#include <limits.h> #include "table.h" #include "utils.h" /* PID and TID we want */ -#define PID_SDT 0x0011 +#define PID_SDT 0x0011 #define TID_SDS 0x42 /* service_descriptor tag */ #define TAG_SERVICE_DESCRIPTOR 0x48 void -list_channels(char *device, unsigned int timeout) +list_channels(unsigned int adapter, unsigned int timeout) { + char demux_dev[PATH_MAX]; unsigned char *sds; uint16_t size; uint16_t offset; @@ -44,12 +46,14 @@ uint8_t desc_length; uint8_t name_len; + snprintf(demux_dev, sizeof(demux_dev), DEMUX_DEVICE, adapter); + printf("Channels on this mutiplex:\n\n"); printf("ID\tChannel\n"); printf("==\t=======\n"); /* grab the Service Description Section table */ - if((sds = read_table(device, PID_SDT, TID_SDS, timeout)) == NULL) + if((sds = read_table(demux_dev, PID_SDT, TID_SDS, timeout)) == NULL) fatal("Unable to read SDT"); /* 12 bit section_length field */ Modified: redbutton-download/trunk/list.h =================================================================== --- redbutton-download/trunk/list.h 2006-03-04 14:42:35 UTC (rev 16) +++ redbutton-download/trunk/list.h 2006-03-15 12:39:15 UTC (rev 17) @@ -23,7 +23,7 @@ #ifndef __LIST_H__ #define __LIST_H__ -void list_channels(char *, unsigned int); +void list_channels(unsigned int, unsigned int); #endif /* __LIST_H__ */ Modified: redbutton-download/trunk/module.h =================================================================== --- redbutton-download/trunk/module.h 2006-03-04 14:42:35 UTC (rev 16) +++ redbutton-download/trunk/module.h 2006-03-15 12:39:15 UTC (rev 17) @@ -25,6 +25,7 @@ #include <stdint.h> #include <stdbool.h> +#include <limits.h> #include "dsmcc.h" #include "assoc.h" @@ -54,8 +55,9 @@ /* the whole carousel */ struct carousel { - char *device; /* demux device */ - unsigned int timeout; /* timeout for the demux device */ + char demux_device[PATH_MAX]; /* demux device path */ + char dvr_device[PATH_MAX]; /* dvr device path */ + unsigned int timeout; /* timeout for the DVB devices */ uint16_t service_id; uint32_t carousel_id; uint16_t audio_pid; /* PID of default audio stream for this service_id */ Modified: redbutton-download/trunk/rb-download.c =================================================================== --- redbutton-download/trunk/rb-download.c 2006-03-04 14:42:35 UTC (rev 16) +++ redbutton-download/trunk/rb-download.c 2006-03-15 12:39:15 UTC (rev 17) @@ -1,5 +1,5 @@ /* - * rb-download [-d <demux_device>] [-b <base_dir>] [-t <timeout>] [-l[<listen-addr>]] [-c <carousel_id>] [<service_id>] + * rb-download [-a <adapter>] [-b <base_dir>] [-t <timeout>] [-l[<listen-addr>]] [-c <carousel_id>] [<service_id>] * * Download the DVB Object Carousel for the given channel onto the local hard disc * files will be stored under the current dir if no -b option is given @@ -10,6 +10,11 @@ * the default timeout is 10 seconds * if no DSMCC data is read after this time, it is assumed none is being broadcast * + * the DVB devices used will be: + * /dev/dvb/adapter0/demux0 + * /dev/dvb/adapter0/dvr0 + * use the -a option to change the adapter number (eg "-a 1" will use /dev/dvb/adapter1/demux0 etc) + * * if -l is given, rb-download listens on the network for commands from a remote rb-browser * the default IP to listen on is 0.0.0.0 (ie all interfaces), the default TCP port is 10101 * listen-addr should be given in the form "host:port", where host defaults to 0.0.0.0 and port defaults to 10101 @@ -60,9 +65,6 @@ #include "listen.h" #include "utils.h" -/* DVB demux device */ -#define DEFAULT_DEVICE "/dev/dvb/adapter0/demux0" - /* seconds before we assume no DSMCC data is available on this PID */ #define DEFAULT_TIMEOUT 10 @@ -76,7 +78,7 @@ main(int argc, char *argv[]) { char *prog_name = argv[0]; - char *device = DEFAULT_DEVICE; + unsigned int adapter = 0; unsigned int timeout = DEFAULT_TIMEOUT; bool listen = false; struct listen_data listen_data; @@ -85,12 +87,12 @@ struct carousel *car; int arg; - while((arg = getopt(argc, argv, "d:b:t:l::c:")) != EOF) + while((arg = getopt(argc, argv, "a:b:t:l::c:")) != EOF) { switch(arg) { - case 'd': - device = optarg; + case 'a': + adapter = strtoul(optarg, NULL, 0); break; case 'b': @@ -124,12 +126,12 @@ if(argc == optind) { - list_channels(device, timeout); + list_channels(adapter, timeout); } else if(argc - optind == 1) { service_id = strtoul(argv[optind], NULL, 0); - car = find_mheg(device, timeout, service_id, carousel_id); + car = find_mheg(adapter, timeout, service_id, carousel_id); printf("Carousel ID=%u\n", car->carousel_id); printf("Video PID=%u\n", car->video_pid); printf("Audio PID=%u\n", car->audio_pid); @@ -151,7 +153,7 @@ void usage(char *prog_name) { - fatal("Usage: %s [-d <demux_device>] " + fatal("Usage: %s [-a <adapter>] " "[-b <base_dir>] " "[-t <timeout>] " "[-l[<listen-addr>]] " Modified: redbutton-download/trunk/table.c =================================================================== --- redbutton-download/trunk/table.c 2006-03-04 14:42:35 UTC (rev 16) +++ redbutton-download/trunk/table.c 2006-03-15 12:39:15 UTC (rev 17) @@ -163,7 +163,7 @@ } if(fd == -1) { - error("Timeout reading %s", car->device); + error("Timeout reading %s", car->demux_device); return NULL; } /* read the table */ @@ -205,8 +205,8 @@ fds->pid = pid; /* open an fd to read the DSMCC control tables (DSI and DII) */ - if((fds->fd_ctrl = open(car->device, O_RDWR)) < 0) - fatal("open '%s': %s", car->device, strerror(errno)); + if((fds->fd_ctrl = open(car->demux_device, O_RDWR)) < 0) + fatal("open '%s': %s", car->demux_device, strerror(errno)); /* set the table filter */ memset(&sctFilterParams, 0, sizeof(sctFilterParams)); @@ -219,8 +219,8 @@ fatal("ioctl DMX_SET_FILTER: %s", strerror(errno)); /* open an fd to read the DSMCC data table (DDB) */ - if((fds->fd_data = open(car->device, O_RDWR)) < 0) - fatal("open '%s': %s", car->device, strerror(errno)); + if((fds->fd_data = open(car->demux_device, O_RDWR)) < 0) + fatal("open '%s': %s", car->demux_device, strerror(errno)); /* set the table filter */ memset(&sctFilterParams, 0, sizeof(sctFilterParams)); Modified: redbutton-download/trunk/utils.h =================================================================== --- redbutton-download/trunk/utils.h 2006-03-04 14:42:35 UTC (rev 16) +++ redbutton-download/trunk/utils.h 2006-03-15 12:39:15 UTC (rev 17) @@ -31,6 +31,12 @@ #define MAX(a, b) ((a) > (b) ? (a) : (b)) #endif +/* DVB demux device - %u is card number */ +#define DEMUX_DEVICE "/dev/dvb/adapter%u/demux0" + +/* DVB dvr device - %u is card number */ +#define DVR_DEVICE "/dev/dvb/adapter%u/dvr0" + void write_string(int, const char *); void write_all(int, const void *, size_t); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <ski...@us...> - 2006-03-15 14:21:34
|
Revision: 18 Author: skilvington Date: 2006-03-15 06:21:25 -0800 (Wed, 15 Mar 2006) ViewCVS: http://svn.sourceforge.net/redbutton/?rev=18&view=rev Log Message: ----------- allow rb-download to stream audio and video to rb-browser Modified Paths: -------------- redbutton-download/trunk/Makefile redbutton-download/trunk/command.c Added Paths: ----------- redbutton-download/trunk/stream.c redbutton-download/trunk/stream.h Modified: redbutton-download/trunk/Makefile =================================================================== --- redbutton-download/trunk/Makefile 2006-03-15 12:39:15 UTC (rev 17) +++ redbutton-download/trunk/Makefile 2006-03-15 14:21:25 UTC (rev 18) @@ -6,6 +6,7 @@ findmheg.o \ listen.o \ command.o \ + stream.o \ assoc.o \ carousel.o \ module.o \ Modified: redbutton-download/trunk/command.c =================================================================== --- redbutton-download/trunk/command.c 2006-03-15 12:39:15 UTC (rev 17) +++ redbutton-download/trunk/command.c 2006-03-15 14:21:25 UTC (rev 18) @@ -2,22 +2,30 @@ * command.c */ +#include <unistd.h> #include <stdio.h> #include <string.h> #include <stdbool.h> +#include <stdint.h> +#include <fcntl.h> #include "command.h" +#include "assoc.h" #include "fs.h" +#include "stream.h" #include "utils.h" /* max number of args that can be passed to a command (arbitrary) */ #define ARGV_MAX 10 /* the commands */ +bool cmd_astream(struct listen_data *, int, int, char **); +bool cmd_avstream(struct listen_data *, int, int, char **); bool cmd_check(struct listen_data *, int, int, char **); bool cmd_file(struct listen_data *, int, int, char **); bool cmd_help(struct listen_data *, int, int, char **); bool cmd_quit(struct listen_data *, int, int, char **); +bool cmd_vstream(struct listen_data *, int, int, char **); static struct { @@ -27,11 +35,14 @@ char *help; } command[] = { + { "astream", "<ComponentTag>", cmd_astream, "Stream the given audio component tag" }, + { "avstream", "<AudioTag> <VideoTag>", cmd_avstream, "Stream the given audio and video component tags" }, { "check", "<ContentReference>", cmd_check, "Check if the given file exists on the carousel" }, { "exit", "", cmd_quit, "Kill the programme" }, { "file", "<ContentReference>", cmd_file, "Retrieve the given file from the carousel" }, { "help", "", cmd_help, "List available commands" }, { "quit", "", cmd_quit, "Kill the programme" }, + { "vstream", "<ComponentTag>", cmd_vstream, "Stream the given video component tag" }, { NULL, NULL, NULL, NULL } }; @@ -116,6 +127,203 @@ } /* + * astream <tag> + * send the given audio stream down the connection + * the tag should be an association/component_tag number as found in the PMT + * the tag is converted to a PID and that PID is sent as a MPEG Transport Stream down the connection + * if tag is -1, the default audio stream for the current service_id is sent + */ + +bool +cmd_astream(struct listen_data *listen_data, int client_sock, int argc, char *argv[]) +{ + struct carousel *car = listen_data->carousel; + int tag; + uint16_t pid; + int audio_fd; + int ts_fd; + char hdr[64]; + + CHECK_USAGE(1, "astream <ComponentTag>"); + + tag = strtol(argv[1], NULL, 0); + + /* map the tag to a PID, or use the default */ + if(tag == -1) + pid = car->audio_pid; + else + pid = stream2pid(&car->assoc, tag); + + /* add the PID to the demux device */ + if((audio_fd = add_demux_filter(car->demux_device, pid, DMX_PES_AUDIO)) < 0) + { + SEND_RESPONSE(500, "Unable to open audio PID"); + return false; + } + + /* we can now read a transport stream from the dvr device */ + if((ts_fd = open(car->dvr_device, O_RDONLY | O_NONBLOCK)) < 0) + { + SEND_RESPONSE(500, "Unable to open DVB device"); + close(audio_fd); + return false; + } + + /* send the OK code */ + SEND_RESPONSE(200, "OK"); + + /* tell the client what PID the component tag resolved to */ + snprintf(hdr, sizeof(hdr), "AudioPID %u\n", pid); + write_string(client_sock, hdr); + + /* shovel the transport stream down client_sock until the client closes it or we get an error */ + stream_ts(ts_fd, client_sock); + + /* clean up */ + close(ts_fd); + close(audio_fd); + + return false; +} + +/* + * vstream <tag> + * send the given video stream down the connection + * the tag should be an association/component_tag number as found in the PMT + * the tag is converted to a PID and that PID is sent as a MPEG Transport Stream down the connection + * if tag is -1, the default video stream for the current service_id is sent + */ + +bool +cmd_vstream(struct listen_data *listen_data, int client_sock, int argc, char *argv[]) +{ + struct carousel *car = listen_data->carousel; + int tag; + uint16_t pid; + int video_fd; + int ts_fd; + char hdr[64]; + + CHECK_USAGE(1, "vstream <ComponentTag>"); + + tag = strtol(argv[1], NULL, 0); + + /* map the tag to a PID, or use the default */ + if(tag == -1) + pid = car->video_pid; + else + pid = stream2pid(&car->assoc, tag); + + /* add the PID to the demux device */ + if((video_fd = add_demux_filter(car->demux_device, pid, DMX_PES_VIDEO)) < 0) + { + SEND_RESPONSE(500, "Unable to open video PID"); + return false; + } + + /* we can now read a transport stream from the dvr device */ + if((ts_fd = open(car->dvr_device, O_RDONLY | O_NONBLOCK)) < 0) + { + SEND_RESPONSE(500, "Unable to open DVB device"); + close(video_fd); + return false; + } + + /* send the OK code */ + SEND_RESPONSE(200, "OK"); + + /* tell the client what PID the component tag resolved to */ + snprintf(hdr, sizeof(hdr), "VideoPID %u\n", pid); + write_string(client_sock, hdr); + + /* shovel the transport stream down client_sock until the client closes it or we get an error */ + stream_ts(ts_fd, client_sock); + + /* clean up */ + close(ts_fd); + close(video_fd); + + return false; +} + +/* + * avstream <audio_tag> <video_tag> + * send the given audio and video streams down the connection + * the tags should be association/component_tag numbers as found in the PMT + * the tags are converted to PIDs and those PIDs are sent as a MPEG Transport Stream down the connection + * if a tag is -1, the default audio or video stream for the current service_id is sent + */ + +bool +cmd_avstream(struct listen_data *listen_data, int client_sock, int argc, char *argv[]) +{ + struct carousel *car = listen_data->carousel; + int audio_tag; + int video_tag; + uint16_t audio_pid; + uint16_t video_pid; + int audio_fd; + int video_fd; + int ts_fd; + char hdr[64]; + + CHECK_USAGE(2, "avstream <AudioTag> <VideoTag>"); + + audio_tag = strtol(argv[1], NULL, 0); + video_tag = strtol(argv[2], NULL, 0); + + /* map the tags to PIDs, or use the defaults */ + if(audio_tag == -1) + audio_pid = car->audio_pid; + else + audio_pid = stream2pid(&car->assoc, audio_tag); + + if(video_tag == -1) + video_pid = car->video_pid; + else + video_pid = stream2pid(&car->assoc, video_tag); + + /* add the PIDs to the demux device */ + if((audio_fd = add_demux_filter(car->demux_device, audio_pid, DMX_PES_AUDIO)) < 0) + { + SEND_RESPONSE(500, "Unable to open audio PID"); + return false; + } + if((video_fd = add_demux_filter(car->demux_device, video_pid, DMX_PES_VIDEO)) < 0) + { + SEND_RESPONSE(500, "Unable to open video PID"); + close(audio_fd); + return false; + } + + /* we can now read a transport stream from the dvr device */ + if((ts_fd = open(car->dvr_device, O_RDONLY | O_NONBLOCK)) < 0) + { + SEND_RESPONSE(500, "Unable to open DVB device"); + close(audio_fd); + close(video_fd); + return false; + } + + /* send the OK code */ + SEND_RESPONSE(200, "OK"); + + /* tell the client what PIDs the component tags resolved to */ + snprintf(hdr, sizeof(hdr), "AudioPID %u VideoPID %u\n", audio_pid, video_pid); + write_string(client_sock, hdr); + + /* shovel the transport stream down client_sock until the client closes it or we get an error */ + stream_ts(ts_fd, client_sock); + + /* clean up */ + close(ts_fd); + close(audio_fd); + close(video_fd); + + return false; +} + +/* * check <ContentReference> * check if the given file is on the carousel * ContentReference should be absolute, ie start with "~//" Added: redbutton-download/trunk/stream.c =================================================================== --- redbutton-download/trunk/stream.c (rev 0) +++ redbutton-download/trunk/stream.c 2006-03-15 14:21:25 UTC (rev 18) @@ -0,0 +1,62 @@ +/* + * stream.c + */ + +#include <unistd.h> +#include <string.h> +#include <fcntl.h> +#include <errno.h> +#include <sys/ioctl.h> + +#include "stream.h" +#include "utils.h" + +int +add_demux_filter(char *demux_dev, uint16_t pid, dmx_pes_type_t pes_type) +{ + int fd; + struct dmx_pes_filter_params pes_filter; + + if((fd = open(demux_dev, O_RDWR)) < 0) + { + error("open '%s': %s", demux_dev, strerror(errno)); + return -1; + } + + bzero(&pes_filter, sizeof(pes_filter)); + pes_filter.input = DMX_IN_FRONTEND; + pes_filter.output = DMX_OUT_TS_TAP; + pes_filter.flags = DMX_IMMEDIATE_START; + pes_filter.pid = pid; + pes_filter.pes_type = pes_type; + + if(ioctl(fd, DMX_SET_PES_FILTER, &pes_filter) < 0) + { + error("ioctl DMX_SET_PES_FILTER: %s", strerror(errno)); + close(fd); + return -1; + } + + return fd; +} + +/* don't want it on the stack */ +unsigned char _ts_buf[8 * 1024]; + +void +stream_ts(int ts_fd, int client_sock) +{ + ssize_t nread; + ssize_t nwritten; + + do + { + nread = read(ts_fd, _ts_buf, sizeof(_ts_buf)); + if(nread > 0) + nwritten = write(client_sock, _ts_buf, nread); + } + while(nread > 0 && nread == nwritten); + + return; +} + Added: redbutton-download/trunk/stream.h =================================================================== --- redbutton-download/trunk/stream.h (rev 0) +++ redbutton-download/trunk/stream.h 2006-03-15 14:21:25 UTC (rev 18) @@ -0,0 +1,15 @@ +/* + * stream.h + */ + +#ifndef __STREAM_H__ +#define __STREAM_H__ + +#include <stdint.h> +#include <linux/dvb/dmx.h> + +int add_demux_filter(char *, uint16_t, dmx_pes_type_t); + +void stream_ts(int, int); + +#endif /* __STREAM_H__ */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <ski...@us...> - 2006-06-24 08:56:09
|
Revision: 123 Author: skilvington Date: 2006-06-24 01:55:47 -0700 (Sat, 24 Jun 2006) ViewCVS: http://svn.sourceforge.net/redbutton/?rev=123&view=rev Log Message: ----------- add -v (verbose) flag Modified Paths: -------------- redbutton-download/trunk/TODO redbutton-download/trunk/biop.c redbutton-download/trunk/carousel.c redbutton-download/trunk/findmheg.c redbutton-download/trunk/fs.c redbutton-download/trunk/list.c redbutton-download/trunk/listen.c redbutton-download/trunk/module.c redbutton-download/trunk/rb-download.c redbutton-download/trunk/utils.c redbutton-download/trunk/utils.h Modified: redbutton-download/trunk/TODO =================================================================== --- redbutton-download/trunk/TODO 2006-06-22 09:06:51 UTC (rev 122) +++ redbutton-download/trunk/TODO 2006-06-24 08:55:47 UTC (rev 123) @@ -9,8 +9,6 @@ be able to read from a file -have a verbose flag - use a linked list of modules rather than an array in struct carousel => easier to delete/add modules Modified: redbutton-download/trunk/biop.c =================================================================== --- redbutton-download/trunk/biop.c 2006-06-22 09:06:51 UTC (rev 122) +++ redbutton-download/trunk/biop.c 2006-06-24 08:55:47 UTC (rev 123) @@ -47,8 +47,8 @@ struct biop_sequence file; char *dirname; -// printf("full BIOP, size=%u\n", size); -// hexdump((unsigned char *) data, size); + vverbose("Whole BIOP, size=%u", size); + vhexdump((unsigned char *) data, size); /* * we may get 0, 1 or more BIOP messages in a single block @@ -65,53 +65,53 @@ || data->message_type != BIOP_MSG_TYPE) fatal("Invalid BIOP header"); size = biop_uint32(data->byte_order, data->message_size); -// printf("BIOP message_size=%u\n", size); + vverbose("BIOP message_size=%u", size); if(bytes_left < sizeof(struct BIOPMessageHeader) + size) fatal("Not enough BIOP data"); /* process MessageSubHeader */ subhdr = ((unsigned char *) data) + sizeof(struct BIOPMessageHeader); -// hexdump(subhdr, size); + vhexdump(subhdr, size); subhdr += biop_sequence255(subhdr, &key); -// printf("objectKey:\n"); -// hexdump(key.data, key.size); + vverbose("objectKey:"); + vhexdump(key.data, key.size); subhdr += biop_sequence(data->byte_order, subhdr, &kind); -// printf("objectKind: '%.*s'\n", kind.size, kind.data); + vverbose("objectKind: '%.*s'", kind.size, kind.data); subhdr += biop_sequence65535(data->byte_order, subhdr, &info); -// printf("objectInfo:\n"); -// hexdump(info.data, info.size); + vverbose("objectInfo:"); + vhexdump(info.data, info.size); subhdr += biop_sequence255(subhdr, &service_context); -// printf("serviceContextList:\n"); -// hexdump(service_context.data, service_context.size); + vverbose("serviceContextList:"); + vhexdump(service_context.data, service_context.size); subhdr += biop_sequence(data->byte_order, subhdr, &body); -// printf("messageBody: %u bytes\n", body.size); + vverbose("messageBody: %u bytes", body.size); /* decode the message body, based on the objectKind field */ if(strcmp(kind.data, BIOP_DIR) == 0) { /* a directory */ - printf("DSM::Directory\n"); + verbose("DSM::Directory"); dirname = make_dir(kind.data, car->current_pid, mod->download_id, mod->module_id, key.data, key.size); process_biop_dir(data->byte_order, dirname, car, body.data, body.size); } else if(strcmp(kind.data, BIOP_SERVICEGATEWAY) == 0) { /* the service gateway is the root directory */ - printf("DSM::ServiceGateway\n"); + verbose("DSM::ServiceGateway"); dirname = make_dir(kind.data, car->current_pid, mod->download_id, mod->module_id, key.data, key.size); process_biop_dir(data->byte_order, dirname, car, body.data, body.size); } else if(strcmp(kind.data, BIOP_FILE) == 0) { /* a file */ - printf("DSM::File\n"); + verbose("DSM::File"); (void) biop_sequence(data->byte_order, body.data, &file); -// hexdump(file.data, file.size); + vhexdump(file.data, file.size); save_file(kind.data, car->current_pid, mod->download_id, mod->module_id, key.data, key.size, file.data, file.size); } else if(strcmp(kind.data, BIOP_STREAM) == 0) { /* a stream */ - printf("DSM::Stream\n"); -// hexdump(body.data, body.size); + verbose("DSM::Stream"); + vhexdump(body.data, body.size); /* * just save it for now * could parse the Taps to make it easier for the browser @@ -121,8 +121,8 @@ else if(strcmp(kind.data, BIOP_STREAMEVENT) == 0) { /* a stream event */ - printf("BIOP::StreamEvent\n"); -// hexdump(body.data, body.size); + verbose("BIOP::StreamEvent"); + vhexdump(body.data, body.size); /* * just save it for now * could parse it to make it easier for the browser @@ -161,28 +161,28 @@ nbindings = biop_uint16(byte_order, *((uint16_t *) data)); data += 2; -// printf("binding_count: %u\n", nbindings); + vverbose("binding_count: %u", nbindings); for(i=0; i<nbindings; i++) { -// printf(" binding %u\n", i); + vverbose(" binding %u", i); nnames = *data; data += 1; -// printf(" nameComponents: %u\n", nnames); + vverbose(" nameComponents: %u", nnames); /* only expecting 1 name, so just use the last one */ for(j=0; j<nnames; j++) { data += biop_sequence255(data, &name); -// printf(" name %u: '%.*s'\n", j, name.size, name.data); + vverbose(" name %u: '%.*s'", j, name.size, name.data); data += biop_sequence255(data, &kind); -// printf(" kind %u: '%.*s'\n", j, kind.size, kind.data); + vverbose(" kind %u: '%.*s'", j, kind.size, kind.data); } /* bindingType */ type = *data; data += 1; -// printf(" bindingType: %u\n", type); + vverbose(" bindingType: %u", type); /* objectRef */ -// printf(" objectRef:\n"); + vverbose(" objectRef:"); data += process_iop_ior(byte_order, data, &ior); /* make sure we are downloading the PID with this file on */ pid = stream2pid(&car->assoc, ior.association_tag); @@ -196,8 +196,8 @@ add_dir_entry(dirname, name.data, name.size, kind.data, pid, ior.carousel_id, ior.module_id, ior.key.data, ior.key.size); /* objectInfo */ data += biop_sequence65535(byte_order, data, &info); -// printf(" objectInfo:\n"); -// hexdump(info.data, info.size); + vverbose(" objectInfo:"); + vhexdump(info.data, info.size); } return; @@ -213,8 +213,8 @@ struct biop_iop_ior ior; uint16_t elementary_pid; - printf("BIOP::ServiceGatewayInfo\n"); -// hexdump(data, size); + verbose("BIOP::ServiceGatewayInfo"); + vhexdump(data, size); data += process_iop_ior(BIOP_BIGENDIAN, data, &ior); @@ -244,23 +244,23 @@ uint8_t taps_count; uint32_t transaction_id; -// printf("IOP::IOR\n"); + vverbose("IOP::IOR"); /* typeId - "dir\0", "fil\0", etc */ data += biop_sequence(byte_order, data, &type); -// printf(" typeId: '%.*s'\n", type.size, type.data); + vverbose(" typeId: '%.*s'", type.size, type.data); nprofiles = biop_uint32(byte_order, *((uint32_t *) data)); data += 4; -// printf(" taggedProfiles_count: %u\n", nprofiles); + vverbose(" taggedProfiles_count: %u", nprofiles); for(i=0; i<nprofiles; i++) { -// printf(" IOP::taggedProfile %u\n", i); + vverbose(" IOP::taggedProfile %u", i); tag = biop_uint32(byte_order, *((uint32_t *) data)); data += 4; data += biop_sequence(byte_order, data, &profile); if(tag == TAG_BIOP) { -// printf(" BIOPProfileBody:\n"); + vverbose(" BIOPProfileBody:"); /* profile_data_byte_order */ profile_bo = *(profile.data); profile.data += 1; @@ -275,11 +275,11 @@ /* carouselId */ ior->carousel_id = biop_uint32(profile_bo, *((uint32_t *) profile.data)); profile.data += 4; -// printf(" carouselId: %u\n", ior->carousel_id); + vverbose(" carouselId: %u", ior->carousel_id); /* moduleId */ ior->module_id = biop_uint16(profile_bo, *((uint32_t *) profile.data)); profile.data += 2; -// printf(" moduleId: %u\n", ior->module_id); + vverbose(" moduleId: %u", ior->module_id); /* BIOP version */ if(profile.data[0] != BIOP_VSN_MAJOR || profile.data[1] != BIOP_VSN_MINOR) @@ -287,30 +287,30 @@ profile.data += 2; /* objectKey */ profile.data += biop_sequence255(profile.data, &ior->key); -// printf(" objectKey: '%.*s'\n", ior->key.size, ior->key.data); -// hexdump(ior->key.data, ior->key.size); + vverbose(" objectKey: '%.*s'", ior->key.size, ior->key.data); + vhexdump(ior->key.data, ior->key.size); /* DSM::ConnBinder */ if(biop_uint32(profile_bo, *((uint32_t *) profile.data)) != TAG_ConnBinder) fatal("Expecting DSM::ConnBinder"); profile.data += 4; -// printf(" DSM::ConnBinder\n"); + vverbose(" DSM::ConnBinder"); /* component_data_length = *profile.data */ profile.data += 1; taps_count = *profile.data; profile.data += 1; -// printf(" taps_count: %u\n", taps_count); + vverbose(" taps_count: %u", taps_count); if(taps_count > 0) { -// printf(" BIOP::Tap\n"); + vverbose(" BIOP::Tap"); /* id = biop_uint16(profile_bo, *((uint16_t *) profile.data)) */ profile.data += 2; if(biop_uint16(profile_bo, *((uint16_t *) profile.data)) != BIOP_DELIVERY_PARA_USE) fatal("Expecting BIOP_DELIVERY_PARA_USE"); profile.data += 2; -// printf(" use: BIOP_DELIVERY_PARA_USE\n"); + vverbose(" use: BIOP_DELIVERY_PARA_USE"); ior->association_tag = biop_uint16(profile_bo, *((uint16_t *) profile.data)); profile.data += 2; -// printf(" association_tag: %u\n", ior->association_tag); + vverbose(" association_tag: %u", ior->association_tag); if(*profile.data != SELECTOR_TYPE_MESSAGE_LEN) fatal("Expecting selector_length %u", SELECTOR_TYPE_MESSAGE_LEN); profile.data += 1; @@ -319,7 +319,7 @@ profile.data += 2; transaction_id = biop_uint32(profile_bo, *((uint32_t *) profile.data)); profile.data += 4; -// printf(" transaction_id: %u\n", transaction_id); + vverbose(" transaction_id: %u", transaction_id); } } else if(tag == TAG_LITE_OPTIONS) Modified: redbutton-download/trunk/carousel.c =================================================================== --- redbutton-download/trunk/carousel.c 2006-06-22 09:06:51 UTC (rev 122) +++ redbutton-download/trunk/carousel.c 2006-06-24 08:55:47 UTC (rev 123) @@ -59,7 +59,7 @@ else if(ntohs(dsmcc->messageId) == DSMCC_MSGID_DDB) process_ddb(car, (struct DownloadDataBlock *) dsmccMessage(dsmcc), ntohl(dsmcc->transactionId), DDB_blockDataLength(dsmcc)); else - printf("Unknown DSMCC messageId: 0x%x\n", ntohs(dsmcc->messageId)); + error("Unknown DSMCC messageId: 0x%x", ntohs(dsmcc->messageId)); } } while(!done); @@ -73,27 +73,25 @@ unsigned int nmodules; unsigned int i; - printf("DownloadInfoIndication\n"); -// printf("transactionId: %u\n", transactionId); -// printf("downloadId: %u\n", ntohl(dii->downloadId)); + verbose("DownloadInfoIndication"); + vverbose("transactionId: %u", transactionId); + vverbose("downloadId: %u", ntohl(dii->downloadId)); nmodules = DII_numberOfModules(dii); -// printf("numberOfModules: %u\n", nmodules); + vverbose("numberOfModules: %u", nmodules); for(i=0; i<nmodules; i++) { struct DIIModule *mod; mod = DII_module(dii, i); -// printf("Module %u\n", i); -// printf(" moduleId: %u\n", ntohs(mod->moduleId)); -// printf(" moduleVersion: %u\n", mod->moduleVersion); -// printf(" moduleSize: %u\n", ntohl(mod->moduleSize)); + vverbose("Module %u", i); + vverbose(" moduleId: %u", ntohs(mod->moduleId)); + vverbose(" moduleVersion: %u", mod->moduleVersion); + vverbose(" moduleSize: %u", ntohl(mod->moduleSize)); if(find_module(car, ntohs(mod->moduleId), mod->moduleVersion, ntohl(dii->downloadId)) == NULL) add_module(car, dii, mod); } -// printf("\n"); - return; } @@ -102,7 +100,7 @@ { uint16_t elementary_pid; - printf("DownloadServerInitiate\n"); + verbose("DownloadServerInitiate"); /* * BBC1 (for example) just broadcasts a DSI @@ -122,8 +120,6 @@ /* make sure we are downloading data from the PID the DSI refers to */ add_dsmcc_pid(car, elementary_pid); -// printf("\n"); - return; } @@ -133,22 +129,20 @@ unsigned char *block; struct module *mod; - printf("DownloadDataBlock\n"); -// printf("downloadId: %u\n", downloadId); + verbose("DownloadDataBlock"); -// printf("moduleId: %u\n", ntohs(ddb->moduleId)); -// printf("moduleVersion: %u\n", ddb->moduleVersion); -// printf("blockNumber: %u\n", ntohs(ddb->blockNumber)); + vverbose("downloadId: %u", downloadId); + vverbose("moduleId: %u", ntohs(ddb->moduleId)); + vverbose("moduleVersion: %u", ddb->moduleVersion); + vverbose("blockNumber: %u", ntohs(ddb->blockNumber)); -// printf("blockLength: %u\n", blockLength); + vverbose("blockLength: %u", blockLength); block = DDB_blockDataByte(ddb); -// hexdump(block, blockLength); + vhexdump(block, blockLength); if((mod = find_module(car, ntohs(ddb->moduleId), ddb->moduleVersion, downloadId)) != NULL) download_block(car, mod, ntohs(ddb->blockNumber), block, blockLength); -// printf("\n"); - return; } Modified: redbutton-download/trunk/findmheg.c =================================================================== --- redbutton-download/trunk/findmheg.c 2006-06-22 09:06:51 UTC (rev 122) +++ redbutton-download/trunk/findmheg.c 2006-06-24 08:55:47 UTC (rev 123) @@ -151,7 +151,7 @@ if(!found) fatal("Unable to find programme_map_PID for service_id %u", service_id); -// printf("programme_map_PID: 0x%x\n", map_pid); + vverbose("programme_map_PID: 0x%x", map_pid); /* get the PMT */ if((pmt = read_table(_car.demux_device, map_pid, TID_PMT, timeout)) == NULL) @@ -196,7 +196,7 @@ { _car.carousel_id = ntohl(desc->carousel_id); add_dsmcc_pid(&_car, elementary_pid); -// printf("pid=0x%x carousel_id=%u\n", elementary_pid, _car.carousel_id); + vverbose("pid=0x%x carousel_id=%u", elementary_pid, _car.carousel_id); } } else if(desc_tag == TAG_STREAM_ID_DESCRIPTOR) @@ -204,7 +204,7 @@ struct stream_id_descriptor *desc; desc = (struct stream_id_descriptor *) &pmt[offset]; component_tag = desc->component_tag; -// printf("pid=0x%x component_tag=0x%x\n", elementary_pid, component_tag); + vverbose("pid=0x%x component_tag=0x%x", elementary_pid, component_tag); add_assoc(&_car.assoc, elementary_pid, desc->component_tag, stream_type); } else if(desc_tag == TAG_LANGUAGE_DESCRIPTOR && is_audio_stream(stream_type)) Modified: redbutton-download/trunk/fs.c =================================================================== --- redbutton-download/trunk/fs.c 2006-06-22 09:06:51 UTC (rev 122) +++ redbutton-download/trunk/fs.c 2006-06-24 08:55:47 UTC (rev 123) @@ -88,7 +88,7 @@ fclose(f); - printf("Created file '%s'\n", filename); + verbose("Created file '%s'", filename); return; } @@ -127,7 +127,7 @@ if(symlink(realfile, linkfile) < 0 && errno != EEXIST) fatal("Unable to create link '%s' to '%s': %s", linkfile, realfile, strerror(errno)); - printf("Added service root '%s' -> '%s'\n", linkfile, realfile); + verbose("Added service root '%s' -> '%s'", linkfile, realfile); return; } @@ -157,7 +157,7 @@ if(mkdir(_dirname, 0755) < 0 && errno != EEXIST) fatal("Unable to create directory '%s': %s", _dirname, strerror(errno)); - printf("Created directory '%s'\n", _dirname); + verbose("Created directory '%s'", _dirname); return _dirname; } @@ -189,7 +189,7 @@ if(symlink(realfile, linkfile) < 0) fatal("Unable to create link '%s' to '%s': %s", linkfile, realfile, strerror(errno)); - printf("Added directory entry '%s' -> '%s'\n", linkfile, realfile); + verbose("Added directory entry '%s' -> '%s'", linkfile, realfile); return; } Modified: redbutton-download/trunk/list.c =================================================================== --- redbutton-download/trunk/list.c 2006-06-22 09:06:51 UTC (rev 122) +++ redbutton-download/trunk/list.c 2006-06-24 08:55:47 UTC (rev 123) @@ -92,8 +92,8 @@ } else { -// printf("desc_tag: %u\n", desc_tag); -// hexdump(&sds[offset], desc_length); + vverbose("desc_tag: %u", desc_tag); + vhexdump(&sds[offset], desc_length); offset += desc_length; } desc_loop_length -= desc_length; Modified: redbutton-download/trunk/listen.c =================================================================== --- redbutton-download/trunk/listen.c 2006-06-22 09:06:51 UTC (rev 122) +++ redbutton-download/trunk/listen.c 2006-06-24 08:55:47 UTC (rev 123) @@ -140,7 +140,7 @@ /* parent continues */ /* listen on the given ip:port */ - printf("Listening on %s:%u\n", inet_ntoa(listen_data->addr.sin_addr), ntohs(listen_data->addr.sin_port)); + verbose("Listening on %s:%u", inet_ntoa(listen_data->addr.sin_addr), ntohs(listen_data->addr.sin_port)); if((listen_sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) fatal("socket: %s", strerror(errno)); @@ -218,7 +218,7 @@ size_t len; bool quit; - printf("Connection from %s:%d\n", inet_ntoa(client_addr->sin_addr), ntohs(client_addr->sin_port)); + verbose("Connection from %s:%d", inet_ntoa(client_addr->sin_addr), ntohs(client_addr->sin_port)); if((client = fdopen(client_sock, "r+")) == NULL) return; @@ -245,7 +245,7 @@ fclose(client); - printf("Connection from %s:%d closed\n", inet_ntoa(client_addr->sin_addr), ntohs(client_addr->sin_port)); + verbose("Connection from %s:%d closed", inet_ntoa(client_addr->sin_addr), ntohs(client_addr->sin_port)); return; } Modified: redbutton-download/trunk/module.c =================================================================== --- redbutton-download/trunk/module.c 2006-06-22 09:06:51 UTC (rev 122) +++ redbutton-download/trunk/module.c 2006-06-24 08:55:47 UTC (rev 123) @@ -83,7 +83,7 @@ mod->size = ntohl(diimod->moduleSize); mod->data = safe_malloc(mod->size); - printf("add_module: nmodules=%u module=%u size=%u\n", car->nmodules, mod->module_id, mod->size); + verbose("add_module: nmodules=%u module=%u size=%u", car->nmodules, mod->module_id, mod->size); return mod; } @@ -132,18 +132,18 @@ mod->blocks_left --; - printf("download_block: module=%u block=%u left=%u\n", mod->module_id, block, mod->blocks_left); + verbose("download_block: module=%u block=%u left=%u", mod->module_id, block, mod->blocks_left); /* have we got it all yet */ if(mod->blocks_left == 0) { - printf("got module %u (size=%u)\n", mod->module_id, mod->size); + verbose("got module %u (size=%u)", mod->module_id, mod->size); /* if it doesn't start with 'BIOP' assume it is compressed */ if(strncmp(mod->data, BIOP_MAGIC_STR, BIOP_MAGIC_LEN) != 0) { -// hexdump(mod->data, mod->size); + vhexdump(mod->data, mod->size); uncompress_module(mod); - printf("uncompressed size=%u\n", mod->size); + verbose("uncompressed size=%u", mod->size); } process_biop(car, mod, (struct BIOPMessageHeader *) mod->data, mod->size); /* we can free the data now, keep got_block so we don't download it again */ Modified: redbutton-download/trunk/rb-download.c =================================================================== --- redbutton-download/trunk/rb-download.c 2006-06-22 09:06:51 UTC (rev 122) +++ redbutton-download/trunk/rb-download.c 2006-06-24 08:55:47 UTC (rev 123) @@ -1,5 +1,5 @@ /* - * rb-download [-a <adapter>] [-b <base_dir>] [-t <timeout>] [-l[<listen-addr>]] [-c <carousel_id>] [<service_id>] + * rb-download [-v] [-a <adapter>] [-b <base_dir>] [-t <timeout>] [-l[<listen-addr>]] [-c <carousel_id>] [<service_id>] * * Download the DVB Object Carousel for the given channel onto the local hard disc * files will be stored under the current dir if no -b option is given @@ -23,6 +23,8 @@ * NOTE: because -l may or may not take an argument, you must not put a space between the -l and the value * (otherwise, "rb-download -l 1234", is ambiguous - listen on port 1234 or use service_id 1234?) * + * -v is verbose/debug mode, use more v's for more verbosity + * * the file structure will be: * ./services/<service_id> * this is a symlink to the root of the carousel @@ -72,6 +74,8 @@ #define DEFAULT_LISTEN_ADDR INADDR_ANY #define DEFAULT_LISTEN_PORT 10101 +static int _verbose = 0; + void usage(char *); int @@ -87,7 +91,7 @@ struct carousel *car; int arg; - while((arg = getopt(argc, argv, "a:b:t:l::c:")) != EOF) + while((arg = getopt(argc, argv, "a:b:t:l::c:v")) != EOF) { switch(arg) { @@ -118,6 +122,10 @@ carousel_id = strtoul(optarg, NULL, 0); break; + case 'v': + _verbose ++; + break; + default: usage(prog_name); break; @@ -132,9 +140,9 @@ { service_id = strtoul(argv[optind], NULL, 0); car = find_mheg(adapter, timeout, service_id, carousel_id); - printf("Carousel ID=%u\n", car->carousel_id); - printf("Video PID=%u\n", car->video_pid); - printf("Audio PID=%u\n", car->audio_pid); + verbose("Carousel ID=%u", car->carousel_id); + verbose("Video PID=%u", car->video_pid); + verbose("Audio PID=%u", car->audio_pid); if(listen) { listen_data.carousel = car; @@ -151,9 +159,51 @@ } void +verbose(char *message, ...) +{ + va_list ap; + + if(_verbose) + { + va_start(ap, message); + vprintf(message, ap); + printf("\n"); + va_end(ap); + } + + return; +} + +void +vverbose(char *message, ...) +{ + va_list ap; + + if(_verbose > 1) + { + va_start(ap, message); + vprintf(message, ap); + printf("\n"); + va_end(ap); + } + + return; +} + +void +vhexdump(unsigned char *data, size_t nbytes) +{ + if(_verbose > 1) + hexdump(data, nbytes); + + return; +} + +void usage(char *prog_name) { - fatal("Usage: %s [-a <adapter>] " + fatal("Usage: %s [-v] " + "[-a <adapter>] " "[-b <base_dir>] " "[-t <timeout>] " "[-l[<listen-addr>]] " Modified: redbutton-download/trunk/utils.c =================================================================== --- redbutton-download/trunk/utils.c 2006-06-22 09:06:51 UTC (rev 122) +++ redbutton-download/trunk/utils.c 2006-06-24 08:55:47 UTC (rev 123) @@ -110,12 +110,12 @@ void error(char *message, ...) { - va_list ap; + va_list ap; - va_start(ap, message); - vfprintf(stderr, message, ap); + va_start(ap, message); + vfprintf(stderr, message, ap); fprintf(stderr, "\n"); - va_end(ap); + va_end(ap); return; } @@ -123,12 +123,12 @@ void fatal(char *message, ...) { - va_list ap; + va_list ap; - va_start(ap, message); - vfprintf(stderr, message, ap); + va_start(ap, message); + vfprintf(stderr, message, ap); fprintf(stderr, "\n"); - va_end(ap); + va_end(ap); exit(EXIT_FAILURE); } Modified: redbutton-download/trunk/utils.h =================================================================== --- redbutton-download/trunk/utils.h 2006-06-22 09:06:51 UTC (rev 122) +++ redbutton-download/trunk/utils.h 2006-06-24 08:55:47 UTC (rev 123) @@ -50,5 +50,10 @@ void error(char *, ...); void fatal(char *, ...); +/* in rb-download.c */ +void verbose(char *, ...); +void vverbose(char *, ...); +void vhexdump(unsigned char *, size_t); + #endif /* __UTILS_H__ */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <ski...@us...> - 2006-11-07 16:40:23
|
Revision: 152
http://svn.sourceforge.net/redbutton/?rev=152&view=rev
Author: skilvington
Date: 2006-11-07 08:40:18 -0800 (Tue, 07 Nov 2006)
Log Message:
-----------
allow compiling on Dreambox (define HAVE_DREAMBOX_HARDWARE), patch from Lorenzo Pallara
Modified Paths:
--------------
redbutton-download/trunk/biop.c
redbutton-download/trunk/table.c
redbutton-download/trunk/utils.h
Modified: redbutton-download/trunk/biop.c
===================================================================
--- redbutton-download/trunk/biop.c 2006-11-07 15:07:56 UTC (rev 151)
+++ redbutton-download/trunk/biop.c 2006-11-07 16:40:18 UTC (rev 152)
@@ -23,6 +23,7 @@
#include <stdio.h>
#include <string.h>
#include <limits.h>
+#include <arpa/inet.h>
#include "biop.h"
#include "fs.h"
Modified: redbutton-download/trunk/table.c
===================================================================
--- redbutton-download/trunk/table.c 2006-11-07 15:07:56 UTC (rev 151)
+++ redbutton-download/trunk/table.c 2006-11-07 16:40:18 UTC (rev 152)
@@ -30,7 +30,13 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
+
+#if defined(HAVE_DREAMBOX_HARDWARE)
+#include <ost/dmx.h>
+#define dmx_sct_filter_params dmxSctFilterParams
+#else
#include <linux/dvb/dmx.h>
+#endif
#include "dsmcc.h"
#include "carousel.h"
Modified: redbutton-download/trunk/utils.h
===================================================================
--- redbutton-download/trunk/utils.h 2006-11-07 15:07:56 UTC (rev 151)
+++ redbutton-download/trunk/utils.h 2006-11-07 16:40:18 UTC (rev 152)
@@ -32,10 +32,18 @@
#endif
/* DVB demux device - %u is card number */
+#if defined(HAVE_DREAMBOX_HARDWARE)
+#define DEMUX_DEVICE "/dev/dvb/card%u/demux0"
+#else
#define DEMUX_DEVICE "/dev/dvb/adapter%u/demux0"
+#endif
/* DVB dvr device - %u is card number */
+#if defined(HAVE_DREAMBOX_HARDWARE)
+#define DVR_DEVICE "/dev/dvb/card%u/dvr0"
+#else
#define DVR_DEVICE "/dev/dvb/adapter%u/dvr0"
+#endif
char *skip_ws(char *);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ski...@us...> - 2006-12-30 19:43:37
|
Revision: 164
http://svn.sourceforge.net/redbutton/?rev=164&view=rev
Author: skilvington
Date: 2006-12-30 11:43:31 -0800 (Sat, 30 Dec 2006)
Log Message:
-----------
make sure we download the DSI from the boot PID
Modified Paths:
--------------
redbutton-download/trunk/carousel.c
redbutton-download/trunk/findmheg.c
redbutton-download/trunk/module.h
Modified: redbutton-download/trunk/carousel.c
===================================================================
--- redbutton-download/trunk/carousel.c 2006-12-22 15:08:40 UTC (rev 163)
+++ redbutton-download/trunk/carousel.c 2006-12-30 19:43:31 UTC (rev 164)
@@ -102,17 +102,12 @@
verbose("DownloadServerInitiate");
- /*
- * BBC1 (for example) just broadcasts a DSI
- * the DSI points to a carousel on the BBCi elementary_pid
- * so, to access the carousel for BBC1 we have to read from the BBCi PID
- * but, when we read the BBCi PID we will download the BBCi DSI
- * we don't want the BBCi DSI to overwrite our original BBC1 DSI
- * so only download the first DSI we find (ie before we read from to BBCi)
- */
- if(car->got_dsi)
+ /* only download the DSI from the boot PID */
+ if(car->current_pid != car->boot_pid
+ || car->got_dsi)
return;
+ /* TODO: check for updated version */
car->got_dsi = true;
elementary_pid = process_biop_service_gateway_info(car->service_id, &car->assoc, DSI_privateDataByte(dsi), ntohs(dsi->privateDataLength));
Modified: redbutton-download/trunk/findmheg.c
===================================================================
--- redbutton-download/trunk/findmheg.c 2006-12-22 15:08:40 UTC (rev 163)
+++ redbutton-download/trunk/findmheg.c 2006-12-30 19:43:31 UTC (rev 164)
@@ -195,6 +195,7 @@
if(carousel_id == -1 || carousel_id == (ntohl(desc->carousel_id)))
{
_car.carousel_id = ntohl(desc->carousel_id);
+ _car.boot_pid = elementary_pid;
add_dsmcc_pid(&_car, elementary_pid);
vverbose("PID=%u carousel_id=%u", elementary_pid, _car.carousel_id);
}
Modified: redbutton-download/trunk/module.h
===================================================================
--- redbutton-download/trunk/module.h 2006-12-22 15:08:40 UTC (rev 163)
+++ redbutton-download/trunk/module.h 2006-12-30 19:43:31 UTC (rev 164)
@@ -60,6 +60,7 @@
unsigned int timeout; /* timeout for the DVB devices */
uint16_t service_id;
uint32_t carousel_id;
+ uint16_t boot_pid; /* PID containing DSI */
uint16_t audio_pid; /* PID of default audio stream for this service_id */
uint8_t audio_type; /* type ID of default audio stream */
uint16_t video_pid; /* PID of default video stream for this service_id */
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ski...@us...> - 2007-01-12 14:59:31
|
Revision: 176
http://svn.sourceforge.net/redbutton/?rev=176&view=rev
Author: skilvington
Date: 2007-01-12 06:59:27 -0800 (Fri, 12 Jan 2007)
Log Message:
-----------
allow remote backends to retune (only to services on the current frequency)
Modified Paths:
--------------
redbutton-download/trunk/TODO
redbutton-download/trunk/command.c
redbutton-download/trunk/listen.c
redbutton-download/trunk/module.h
redbutton-download/trunk/table.c
Modified: redbutton-download/trunk/TODO
===================================================================
--- redbutton-download/trunk/TODO 2007-01-11 17:59:20 UTC (rev 175)
+++ redbutton-download/trunk/TODO 2007-01-12 14:59:27 UTC (rev 176)
@@ -1,3 +1,6 @@
+need to kill all existing command connections on retune
+(listen_data->carousel is stale for them)
+
got an "Out of memory" error when doing avstream and video changed size
(start of C4 news)
can't see how avstream can cause an out of memory error
Modified: redbutton-download/trunk/command.c
===================================================================
--- redbutton-download/trunk/command.c 2007-01-11 17:59:20 UTC (rev 175)
+++ redbutton-download/trunk/command.c 2007-01-12 14:59:27 UTC (rev 176)
@@ -8,6 +8,7 @@
#include <stdbool.h>
#include <stdint.h>
#include <fcntl.h>
+#include <signal.h>
#include "command.h"
#include "assoc.h"
@@ -26,6 +27,7 @@
bool cmd_file(struct listen_data *, FILE *, int, char **);
bool cmd_help(struct listen_data *, FILE *, int, char **);
bool cmd_quit(struct listen_data *, FILE *, int, char **);
+bool cmd_retune(struct listen_data *, FILE *, int, char **);
bool cmd_vstream(struct listen_data *, FILE *, int, char **);
static struct
@@ -44,6 +46,7 @@
{ "file", "<ContentReference>", cmd_file, "Retrieve the given file from the carousel" },
{ "help", "", cmd_help, "List available commands" },
{ "quit", "", cmd_quit, "Close the connection" },
+ { "retune", "<ServiceID>", cmd_retune, "Start downloading the carousel from ServiceID" },
{ "vstream", "<ComponentTag>", cmd_vstream, "Stream the given video component tag" },
{ NULL, NULL, NULL, NULL }
};
@@ -504,6 +507,38 @@
}
/*
+ * retune <ServiceID>
+ * stop downloading the current carousel
+ * start downloading the carousel on the given ServiceID
+ */
+
+bool
+cmd_retune(struct listen_data *listen_data, FILE *client, int argc, char *argv[])
+{
+ struct carousel *car = listen_data->carousel;
+ unsigned int service_id;
+ union sigval value;
+
+
+ CHECK_USAGE(2, "retune <ServiceID>");
+
+ service_id = strtoul(argv[1], NULL, 0);
+
+ /* do we need to retune */
+ if(service_id != car->service_id)
+ {
+ /* send a SIGHUP to the main listener process */
+ value.sival_int = service_id;
+ sigqueue(getppid(), SIGHUP, value);
+ }
+
+ SEND_RESPONSE(200, "OK");
+
+ /* need to close the connection as this process now has stale listen_data->carousel */
+ return true;
+}
+
+/*
* help
*/
Modified: redbutton-download/trunk/listen.c
===================================================================
--- redbutton-download/trunk/listen.c 2007-01-11 17:59:20 UTC (rev 175)
+++ redbutton-download/trunk/listen.c 2007-01-12 14:59:27 UTC (rev 176)
@@ -28,9 +28,21 @@
static int get_host_addr(char *, struct in_addr *);
static void handle_connection(struct listen_data *, int, struct sockaddr_in *);
+
static void dead_child(int);
+static void hup_handler(int, siginfo_t *, void *);
/*
+ * we have a main process that listens for commands on the network
+ * each time a new command is received a new process is forked to handle it
+ * the main process also has a child downloading the carousel
+ * to retune, the command processing process sends a SIGHUP to the main process
+ * the siginfo contains the new service_id
+ * this variable is set by the SIGHUP handler from the siginfo, -1 => no retune needed
+ */
+static volatile int retune_id = -1;
+
+/*
* extract the IP addr and port number from a string in one of these forms:
* host:port
* ip-addr:port
@@ -131,6 +143,13 @@
/* fork off a child to download the carousel */
listen_data.carousel = start_downloader(adapter, timeout, service_id, carousel_id);
+ /* catch SIGHUP - tells us to retune */
+ action.sa_sigaction = hup_handler;
+ sigemptyset(&action.sa_mask);
+ action.sa_flags = SA_SIGINFO;
+ if(sigaction(SIGHUP, &action, NULL) < 0)
+ fatal("signal: SIGHUP: %s", strerror(errno));
+
/* listen on the given ip:port */
verbose("Listening on %s:%u", inet_ntoa(listen_addr->sin_addr), ntohs(listen_addr->sin_port));
@@ -151,11 +170,21 @@
/* listen for connections */
while(true)
{
+ /* do we need to retune */
+ if(retune_id != -1)
+ {
+ verbose("Retune to service_id %d", retune_id);
+ /* kill the current downloader process and start a new one */
+ kill(listen_data.carousel->downloader, SIGKILL);
+ listen_data.carousel = start_downloader(adapter, timeout, retune_id, -1);
+ retune_id = -1;
+ }
+ /* listen for a connection */
FD_ZERO(&read_fds);
FD_SET(listen_sock, &read_fds);
if(select(listen_sock + 1, &read_fds, NULL, NULL, NULL) < 0)
{
- /* could have been interupted by SIGCHLD */
+ /* could have been interupted by SIGCHLD or SIGHUP */
if(errno != EINTR)
error("select: %s", strerror(errno));
continue;
@@ -270,6 +299,9 @@
load_carousel(car);
/* parent continues */
+ /* remember the PID of the downloader process so we can kill it on retune */
+ car->downloader = child;
+
return car;
}
@@ -281,3 +313,13 @@
return;
}
+
+static void
+hup_handler(int signo, siginfo_t *info, void *ctx)
+{
+ if(signo == SIGHUP)
+ retune_id = info->si_value.sival_int;
+
+ return;
+}
+
Modified: redbutton-download/trunk/module.h
===================================================================
--- redbutton-download/trunk/module.h 2007-01-11 17:59:20 UTC (rev 175)
+++ redbutton-download/trunk/module.h 2007-01-12 14:59:27 UTC (rev 176)
@@ -26,6 +26,7 @@
#include <stdint.h>
#include <stdbool.h>
#include <limits.h>
+#include <sys/types.h>
#include "dsmcc.h"
#include "assoc.h"
@@ -58,6 +59,7 @@
char demux_device[PATH_MAX]; /* demux device path */
char dvr_device[PATH_MAX]; /* dvr device path */
unsigned int timeout; /* timeout for the DVB devices */
+ pid_t downloader; /* ID of the process downloading the carousel */
uint16_t service_id;
uint32_t carousel_id;
uint16_t boot_pid; /* PID containing DSI */
Modified: redbutton-download/trunk/table.c
===================================================================
--- redbutton-download/trunk/table.c 2007-01-11 17:59:20 UTC (rev 175)
+++ redbutton-download/trunk/table.c 2007-01-12 14:59:27 UTC (rev 176)
@@ -84,12 +84,14 @@
timeout.tv_usec = 0;
do
{
- _buf[0] = 0;
+ _buf[0] = 0xff; /* we never want table ID 0xff */
FD_ZERO(&readfds);
FD_SET(fd_data, &readfds);
if(select(fd_data + 1, &readfds, NULL, NULL, &timeout) < 0)
{
- error("select: %s", strerror(errno));
+ if(errno == EINTR)
+ continue;
+ error("read_table: select: %s", strerror(errno));
close(fd_data);
return NULL;
}
@@ -147,7 +149,7 @@
/* wait for some data to be ready */
if(select(max + 1, &readfds, NULL, NULL, &timeout) < 0)
{
- error("select: %s", strerror(errno));
+ error("read_dsmcc_tables: select: %s", strerror(errno));
return NULL;
}
/* see which fd is ready */
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ski...@us...> - 2007-04-24 10:24:55
|
Revision: 289
http://svn.sourceforge.net/redbutton/?rev=289&view=rev
Author: skilvington
Date: 2007-04-24 03:24:53 -0700 (Tue, 24 Apr 2007)
Log Message:
-----------
cache the SDT
Modified Paths:
--------------
redbutton-download/trunk/findmheg.c
redbutton-download/trunk/list.c
redbutton-download/trunk/table.c
redbutton-download/trunk/table.h
Modified: redbutton-download/trunk/findmheg.c
===================================================================
--- redbutton-download/trunk/findmheg.c 2007-04-24 09:57:13 UTC (rev 288)
+++ redbutton-download/trunk/findmheg.c 2007-04-24 10:24:53 UTC (rev 289)
@@ -30,16 +30,8 @@
#include "findmheg.h"
#include "table.h"
#include "assoc.h"
-#include "cache.h"
#include "utils.h"
-/* Programme Association Table and Section */
-#define PID_PAT 0x0000
-#define TID_PAT 0x00
-
-/* Programme Map Section */
-#define TID_PMT 0x02
-
/* stream_types we are interested in */
#define STREAM_TYPE_VIDEO_MPEG2 0x02
#define STREAM_TYPE_AUDIO_MPEG1 0x03
@@ -83,8 +75,6 @@
static struct avstreams *find_current_avstreams(struct carousel *, int, int);
static struct avstreams *find_service_avstreams(struct carousel *, int, int, int);
-static bool read_pat(char *, unsigned int, unsigned char *);
-static bool read_pmt(char *, uint16_t, unsigned int, unsigned char *);
bool
is_audio_stream(uint8_t stream_type)
@@ -409,89 +399,3 @@
return &_streams;
}
-/*
- * output buffer must be at least MAX_TABLE_LEN bytes
- * returns false if it timesout
- */
-
-static bool
-read_pat(char *demux, unsigned int timeout, unsigned char *out)
-{
- /* is it in the cache */
- if(cache_load("pat", out))
- return true;
-
- /* read it from the DVB card */
- if(!read_table(demux, PID_PAT, TID_PAT, timeout, out))
- {
- error("Unable to read PAT");
- return false;
- }
-
- /* cache it */
- cache_save("pat", out);
-
- return true;
-}
-
-/*
- * output buffer must be at least MAX_TABLE_LEN bytes
- * returns false if it timesout
- */
-
-static bool
-read_pmt(char *demux, uint16_t service_id, unsigned int timeout, unsigned char *out)
-{
- char cache_item[PATH_MAX];
- unsigned char pat[MAX_TABLE_LEN];
- uint16_t section_length;
- uint16_t offset;
- uint16_t map_pid = 0;
- bool found;
- bool rc;
-
- /* is it in the cache */
- snprintf(cache_item, sizeof(cache_item), "pmt-%u", service_id);
- if(cache_load(cache_item, out))
- return true;
-
- /* get the PAT */
- if(!read_pat(demux, timeout, pat))
- return false;
-
- section_length = 3 + (((pat[1] & 0x0f) << 8) + pat[2]);
-
- /* find the PMT for this service_id */
- found = false;
- offset = 8;
- /* -4 for the CRC at the end */
- while((offset < (section_length - 4)) && !found)
- {
- if((pat[offset] << 8) + pat[offset+1] == service_id)
- {
- map_pid = ((pat[offset+2] & 0x1f) << 8) + pat[offset+3];
- found = true;
- }
- else
- {
- offset += 4;
- }
- }
-
- if(!found)
- fatal("Unable to find PMT PID for service_id %u", service_id);
-
- vverbose("PMT PID: %u", map_pid);
-
- /* get the PMT */
- rc = read_table(demux, map_pid, TID_PMT, timeout, out);
-
- /* cache it */
- if(rc)
- cache_save(cache_item, out);
- else
- error("Unable to read PMT");
-
- return rc;
-}
-
Modified: redbutton-download/trunk/list.c
===================================================================
--- redbutton-download/trunk/list.c 2007-04-24 09:57:13 UTC (rev 288)
+++ redbutton-download/trunk/list.c 2007-04-24 10:24:53 UTC (rev 289)
@@ -26,10 +26,6 @@
#include "table.h"
#include "utils.h"
-/* PID and TID we want */
-#define PID_SDT 0x0011
-#define TID_SDS 0x42
-
/* service_descriptor tag */
#define TAG_SERVICE_DESCRIPTOR 0x48
@@ -37,7 +33,7 @@
list_channels(unsigned int adapter, unsigned int timeout)
{
char demux_dev[PATH_MAX];
- unsigned char sds[MAX_TABLE_LEN];
+ unsigned char sdt[MAX_TABLE_LEN];
uint16_t size;
uint16_t offset;
uint16_t service_id;
@@ -52,29 +48,29 @@
printf("ID\tChannel\n");
printf("==\t=======\n");
- /* grab the Service Description Section table */
- if(!read_table(demux_dev, PID_SDT, TID_SDS, timeout, sds))
+ /* grab the Service Description Table */
+ if(!read_sdt(demux_dev, timeout, sdt))
fatal("Unable to read SDT");
/* 12 bit section_length field */
- size = 3 + (((sds[1] & 0x0f) << 8) + sds[2]);
+ size = 3 + (((sdt[1] & 0x0f) << 8) + sdt[2]);
/* loop through the services */
offset = 11;
/* -4 for the CRC at the end */
while(offset < (size - 4))
{
- service_id = (sds[offset] << 8) + sds[offset+1];
+ service_id = (sdt[offset] << 8) + sdt[offset+1];
printf("%u\t", service_id);
/* move on to the descriptors */
offset += 3;
- desc_loop_length = ((sds[offset] & 0x0f) << 8) + sds[offset+1];
+ desc_loop_length = ((sdt[offset] & 0x0f) << 8) + sdt[offset+1];
offset += 2;
/* find the service_descriptor tag */
while(desc_loop_length != 0)
{
- desc_tag = sds[offset];
- desc_length = sds[offset+1];
+ desc_tag = sdt[offset];
+ desc_length = sdt[offset+1];
offset += 2;
desc_loop_length -= 2;
if(desc_tag == TAG_SERVICE_DESCRIPTOR)
@@ -82,18 +78,18 @@
/* service_type = sds[offset]; */
offset += 1;
/* service_provider_name */
- name_len = sds[offset];
+ name_len = sdt[offset];
offset += 1 + name_len;
/* service_name */
- name_len = sds[offset];
+ name_len = sdt[offset];
offset += 1;
- printf("%.*s\n", name_len, &sds[offset]);
+ printf("%.*s\n", name_len, &sdt[offset]);
offset += name_len;
}
else
{
vverbose("desc_tag: %u", desc_tag);
- vhexdump(&sds[offset], desc_length);
+ vhexdump(&sdt[offset], desc_length);
offset += desc_length;
}
desc_loop_length -= desc_length;
Modified: redbutton-download/trunk/table.c
===================================================================
--- redbutton-download/trunk/table.c 2007-04-24 09:57:13 UTC (rev 288)
+++ redbutton-download/trunk/table.c 2007-04-24 10:24:53 UTC (rev 289)
@@ -42,8 +42,20 @@
#include "dsmcc.h"
#include "carousel.h"
#include "biop.h"
+#include "cache.h"
#include "utils.h"
+/* Programme Association Table PID and TID */
+#define PID_PAT 0x0000
+#define TID_PAT 0x00
+
+/* Programme Map Table TID */
+#define TID_PMT 0x02
+
+/* Service Description Table PID and TID */
+#define PID_SDT 0x0011
+#define TID_SDT 0x42
+
/* DSMCC table ID's we want */
#define TID_DSMCC_CONTROL 0x3b /* DSI or DII */
#define TID_DSMCC_DATA 0x3c /* DDB */
@@ -54,6 +66,117 @@
*/
bool
+read_pat(char *demux, unsigned int timeout, unsigned char *out)
+{
+ /* is it in the cache */
+ if(cache_load("pat", out))
+ return true;
+
+ /* read it from the DVB card */
+ if(!read_table(demux, PID_PAT, TID_PAT, timeout, out))
+ {
+ error("Unable to read PAT");
+ return false;
+ }
+
+ /* cache it */
+ cache_save("pat", out);
+
+ return true;
+}
+
+/*
+ * output buffer must be at least MAX_TABLE_LEN bytes
+ * returns false if it timesout
+ */
+
+bool
+read_pmt(char *demux, uint16_t service_id, unsigned int timeout, unsigned char *out)
+{
+ char cache_item[PATH_MAX];
+ unsigned char pat[MAX_TABLE_LEN];
+ uint16_t section_length;
+ uint16_t offset;
+ uint16_t map_pid = 0;
+ bool found;
+ bool rc;
+
+ /* is it in the cache */
+ snprintf(cache_item, sizeof(cache_item), "pmt-%u", service_id);
+ if(cache_load(cache_item, out))
+ return true;
+
+ /* get the PAT */
+ if(!read_pat(demux, timeout, pat))
+ return false;
+
+ section_length = 3 + (((pat[1] & 0x0f) << 8) + pat[2]);
+
+ /* find the PMT for this service_id */
+ found = false;
+ offset = 8;
+ /* -4 for the CRC at the end */
+ while((offset < (section_length - 4)) && !found)
+ {
+ if((pat[offset] << 8) + pat[offset+1] == service_id)
+ {
+ map_pid = ((pat[offset+2] & 0x1f) << 8) + pat[offset+3];
+ found = true;
+ }
+ else
+ {
+ offset += 4;
+ }
+ }
+
+ if(!found)
+ fatal("Unable to find PMT PID for service_id %u", service_id);
+
+ vverbose("PMT PID: %u", map_pid);
+
+ /* get the PMT */
+ rc = read_table(demux, map_pid, TID_PMT, timeout, out);
+
+ /* cache it */
+ if(rc)
+ cache_save(cache_item, out);
+ else
+ error("Unable to read PMT");
+
+ return rc;
+}
+
+/*
+ * output buffer must be at least MAX_TABLE_LEN bytes
+ * returns false if it timesout
+ */
+
+bool
+read_sdt(char *demux, unsigned int timeout, unsigned char *out)
+{
+ /* is it in the cache */
+ if(cache_load("sdt", out))
+ return true;
+
+ /* read it from the DVB card */
+ if(!read_table(demux, PID_SDT, TID_SDT, timeout, out))
+ {
+ error("Unable to read SDT");
+ return false;
+ }
+
+ /* cache it */
+ cache_save("sdt", out);
+
+ return true;
+}
+
+/*
+ * output buffer must be at least MAX_TABLE_LEN bytes
+ * returns false if it timesout
+ */
+
+bool
read_table(char *device, uint16_t pid, uint8_t tid, unsigned int secs, unsigned char *out)
{
int fd_data;
Modified: redbutton-download/trunk/table.h
===================================================================
--- redbutton-download/trunk/table.h 2007-04-24 09:57:13 UTC (rev 288)
+++ redbutton-download/trunk/table.h 2007-04-24 10:24:53 UTC (rev 289)
@@ -31,6 +31,10 @@
/* max size of a DVB table */
#define MAX_TABLE_LEN 4096
+bool read_pat(char *, unsigned int, unsigned char *);
+bool read_pmt(char *, uint16_t, unsigned int, unsigned char *);
+bool read_sdt(char *, unsigned int, unsigned char *);
+
bool read_table(char *, uint16_t, uint8_t, unsigned int, unsigned char *);
bool read_dsmcc_tables(struct carousel *, unsigned char *);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ski...@us...> - 2007-04-24 10:38:55
|
Revision: 290
http://svn.sourceforge.net/redbutton/?rev=290&view=rev
Author: skilvington
Date: 2007-04-24 03:38:53 -0700 (Tue, 24 Apr 2007)
Log Message:
-----------
find the original_network_id
Modified Paths:
--------------
redbutton-download/trunk/command.c
redbutton-download/trunk/findmheg.c
redbutton-download/trunk/module.h
Modified: redbutton-download/trunk/command.c
===================================================================
--- redbutton-download/trunk/command.c 2007-04-24 10:24:53 UTC (rev 289)
+++ redbutton-download/trunk/command.c 2007-04-24 10:38:53 UTC (rev 290)
@@ -815,11 +815,8 @@
SEND_RESPONSE(200, "OK");
-/* TODO */
-printf("TODO: cmd_service network_id\n");
+ fprintf(client, "dvb://%x..%x\n", car->network_id, car->service_id);
- fprintf(client, "dvb://..%x\n", car->service_id);
-
return false;
}
Modified: redbutton-download/trunk/findmheg.c
===================================================================
--- redbutton-download/trunk/findmheg.c 2007-04-24 10:24:53 UTC (rev 289)
+++ redbutton-download/trunk/findmheg.c 2007-04-24 10:38:53 UTC (rev 290)
@@ -101,6 +101,7 @@
find_mheg(unsigned int adapter, unsigned int timeout, uint16_t service_id, int carousel_id)
{
unsigned char pmt[MAX_TABLE_LEN];
+ unsigned char *sdt = pmt;
uint16_t section_length;
uint16_t offset;
uint8_t stream_type;
@@ -119,6 +120,7 @@
_car.service_id = service_id;
/* unknown */
+ _car.network_id = 0;
_car.carousel_id = 0;
_car.boot_pid = 0;
_car.audio_pid = 0;
@@ -136,6 +138,12 @@
_car.nmodules = 0;
_car.modules = NULL;
+ /* find the original_network_id from the SDT */
+ if(!read_sdt(_car.demux_device, timeout, sdt))
+ fatal("Unable to read SDT");
+ _car.network_id = (sdt[8] << 8) + sdt[9];
+ vverbose("original_network_id=%u", _car.network_id);
+
/* get the PMT */
if(!read_pmt(_car.demux_device, service_id, timeout, pmt))
fatal("Unable to read PMT");
Modified: redbutton-download/trunk/module.h
===================================================================
--- redbutton-download/trunk/module.h 2007-04-24 10:24:53 UTC (rev 289)
+++ redbutton-download/trunk/module.h 2007-04-24 10:38:53 UTC (rev 290)
@@ -60,8 +60,9 @@
char dvr_device[PATH_MAX]; /* dvr device path */
unsigned int timeout; /* timeout for the DVB devices */
pid_t downloader; /* ID of the process downloading the carousel */
- uint16_t service_id;
- uint32_t carousel_id;
+ uint16_t network_id; /* Original Network ID */
+ uint16_t service_id; /* Service ID we are downloading the carousel from */
+ uint32_t carousel_id; /* Carousel ID we are downloading */
uint16_t boot_pid; /* PID containing DSI */
uint16_t audio_pid; /* PID of default audio stream for this service_id */
uint8_t audio_type; /* type ID of default audio stream */
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ski...@us...> - 2007-04-25 09:44:41
|
Revision: 291
http://svn.sourceforge.net/redbutton/?rev=291&view=rev
Author: skilvington
Date: 2007-04-25 02:44:10 -0700 (Wed, 25 Apr 2007)
Log Message:
-----------
don't kill the downloader if a module is corrupt, try to download it again
Modified Paths:
--------------
redbutton-download/trunk/biop.c
redbutton-download/trunk/biop.h
redbutton-download/trunk/module.c
Modified: redbutton-download/trunk/biop.c
===================================================================
--- redbutton-download/trunk/biop.c 2007-04-24 10:38:53 UTC (rev 290)
+++ redbutton-download/trunk/biop.c 2007-04-25 09:44:10 UTC (rev 291)
@@ -33,9 +33,10 @@
/*
* split the module into separate BIOP messages
+ * returns false if the format is invalid
*/
-void
+bool
process_biop(struct carousel *car, struct module *mod, struct BIOPMessageHeader *data, uint32_t size)
{
uint32_t bytes_left;
@@ -64,11 +65,17 @@
|| data->biop_version.major != BIOP_VSN_MAJOR
|| data->biop_version.minor != BIOP_VSN_MINOR
|| data->message_type != BIOP_MSG_TYPE)
- fatal("Invalid BIOP header");
+ {
+ error("Invalid BIOP header");
+ return false;
+ }
size = biop_uint32(data->byte_order, data->message_size);
vverbose("BIOP message_size=%u", size);
if(bytes_left < sizeof(struct BIOPMessageHeader) + size)
- fatal("Not enough BIOP data");
+ {
+ error("Not enough BIOP data");
+ return false;
+ }
/* process MessageSubHeader */
subhdr = ((unsigned char *) data) + sizeof(struct BIOPMessageHeader);
vhexdump(subhdr, size);
@@ -132,14 +139,14 @@
}
else
{
- fatal("Unknown BIOP object: '%.*s'", kind.size, kind.data);
+ error("Ignoring unknown BIOP object: '%.*s'", kind.size, kind.data);
}
/* move onto the next */
data = (struct BIOPMessageHeader *) (((unsigned char *) data) + sizeof(struct BIOPMessageHeader) + size);
bytes_left -= sizeof(struct BIOPMessageHeader) + size;
}
- return;
+ return true;
}
/*
Modified: redbutton-download/trunk/biop.h
===================================================================
--- redbutton-download/trunk/biop.h 2007-04-24 10:38:53 UTC (rev 290)
+++ redbutton-download/trunk/biop.h 2007-04-25 09:44:10 UTC (rev 291)
@@ -100,7 +100,7 @@
};
/* functions */
-void process_biop(struct carousel *, struct module *, struct BIOPMessageHeader *, uint32_t);
+bool process_biop(struct carousel *, struct module *, struct BIOPMessageHeader *, uint32_t);
void process_biop_dir(uint8_t, char *, struct carousel *, unsigned char *, uint32_t);
uint32_t process_iop_ior(uint8_t, unsigned char *, struct biop_iop_ior *);
uint16_t process_biop_service_gateway_info(uint16_t, struct assoc *, unsigned char *, uint16_t);
Modified: redbutton-download/trunk/module.c
===================================================================
--- redbutton-download/trunk/module.c 2007-04-24 10:38:53 UTC (rev 290)
+++ redbutton-download/trunk/module.c 2007-04-25 09:44:10 UTC (rev 291)
@@ -145,11 +145,20 @@
uncompress_module(mod);
verbose("uncompressed size=%u", mod->size);
}
- process_biop(car, mod, (struct BIOPMessageHeader *) mod->data, mod->size);
- /* we can free the data now, keep got_block so we don't download it again */
- safe_free(mod->data);
- /* delete_module may safe_free it again */
- mod->data = NULL;
+ if(process_biop(car, mod, (struct BIOPMessageHeader *) mod->data, mod->size))
+ {
+ /* we can free the data now, keep got_block so we don't download it again */
+ safe_free(mod->data);
+ /* delete_module may safe_free it again */
+ mod->data = NULL;
+ }
+ else
+ {
+ /* failed to process it, try downloading it again */
+ mod->blocks_left = mod->nblocks;
+ /* assumes false == 0 */
+ bzero(mod->got_block, mod->nblocks * sizeof(bool));
+ }
}
return;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ski...@us...> - 2006-03-02 17:11:27
|
Revision: 11 Author: skilvington Date: 2006-03-02 09:11:17 -0800 (Thu, 02 Mar 2006) ViewCVS: http://svn.sourceforge.net/redbutton/?rev=11&view=rev Log Message: ----------- retry reading demux device after EOVERFLOW errors Modified Paths: -------------- redbutton-download/trunk/TODO redbutton-download/trunk/table.c Modified: redbutton-download/trunk/TODO =================================================================== --- redbutton-download/trunk/TODO 2006-03-02 17:10:15 UTC (rev 10) +++ redbutton-download/trunk/TODO 2006-03-02 17:11:17 UTC (rev 11) @@ -1,7 +1,3 @@ -work out why this happened on BBC1 once: -read: Value too large for defined data type -Unable to read PID - have a verbose flag use a linked list of modules rather than an array in struct carousel @@ -11,9 +7,6 @@ => need to download again if it gets bigger (we currently just look at the module version, is this enough?) -what happens when you change channel? -(kill -9 and restart with the new programme_number?) - create carousels/PID/CID dir in add_dsmcc_pid() (may need to use carousels/<assoc_tag> as stream2pid may return 0) Modified: redbutton-download/trunk/table.c =================================================================== --- redbutton-download/trunk/table.c 2006-03-02 17:10:15 UTC (rev 10) +++ redbutton-download/trunk/table.c 2006-03-02 17:11:17 UTC (rev 11) @@ -169,8 +169,12 @@ /* read the table */ if((n = read(fd, _buf, sizeof(_buf))) < 0) { + /* + * may get EOVERFLOW if we don't read quick enough, + * so just report it and have another go + */ error("read: %s", strerror(errno)); - return NULL; + _buf[0] = 0; } } while(_buf[0] != TID_DSMCC_CONTROL && _buf[0] != TID_DSMCC_DATA); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <ski...@us...> - 2006-03-15 16:03:36
|
Revision: 21 Author: skilvington Date: 2006-03-15 08:03:26 -0800 (Wed, 15 Mar 2006) ViewCVS: http://svn.sourceforge.net/redbutton/?rev=21&view=rev Log Message: ----------- open audio and video streams in blocking mode Modified Paths: -------------- redbutton-download/trunk/command.c redbutton-download/trunk/stream.c Modified: redbutton-download/trunk/command.c =================================================================== --- redbutton-download/trunk/command.c 2006-03-15 14:47:18 UTC (rev 20) +++ redbutton-download/trunk/command.c 2006-03-15 16:03:26 UTC (rev 21) @@ -162,7 +162,7 @@ } /* we can now read a transport stream from the dvr device */ - if((ts_fd = open(car->dvr_device, O_RDONLY | O_NONBLOCK)) < 0) + if((ts_fd = open(car->dvr_device, O_RDONLY)) < 0) { SEND_RESPONSE(500, "Unable to open DVB device"); close(audio_fd); @@ -222,7 +222,7 @@ } /* we can now read a transport stream from the dvr device */ - if((ts_fd = open(car->dvr_device, O_RDONLY | O_NONBLOCK)) < 0) + if((ts_fd = open(car->dvr_device, O_RDONLY)) < 0) { SEND_RESPONSE(500, "Unable to open DVB device"); close(video_fd); @@ -297,7 +297,7 @@ } /* we can now read a transport stream from the dvr device */ - if((ts_fd = open(car->dvr_device, O_RDONLY | O_NONBLOCK)) < 0) + if((ts_fd = open(car->dvr_device, O_RDONLY)) < 0) { SEND_RESPONSE(500, "Unable to open DVB device"); close(audio_fd); Modified: redbutton-download/trunk/stream.c =================================================================== --- redbutton-download/trunk/stream.c 2006-03-15 14:47:18 UTC (rev 20) +++ redbutton-download/trunk/stream.c 2006-03-15 16:03:26 UTC (rev 21) @@ -54,8 +54,10 @@ nread = read(ts_fd, _ts_buf, sizeof(_ts_buf)); if(nread > 0) nwritten = write(client_sock, _ts_buf, nread); + else + nwritten = nread; } - while(nread > 0 && nread == nwritten); + while(nread == nwritten); return; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <ski...@us...> - 2007-01-07 11:16:20
|
Revision: 165
http://svn.sourceforge.net/redbutton/?rev=165&view=rev
Author: skilvington
Date: 2007-01-07 03:16:12 -0800 (Sun, 07 Jan 2007)
Log Message:
-----------
use data_broadcast_id_descriptor to find boot PID
Modified Paths:
--------------
redbutton-download/trunk/findmheg.c
redbutton-download/trunk/rb-download.c
Modified: redbutton-download/trunk/findmheg.c
===================================================================
--- redbutton-download/trunk/findmheg.c 2006-12-30 19:43:31 UTC (rev 164)
+++ redbutton-download/trunk/findmheg.c 2007-01-07 11:16:12 UTC (rev 165)
@@ -44,9 +44,10 @@
#define STREAM_TYPE_ISO13818_6_B 0x0b
/* descriptors we want */
-#define TAG_LANGUAGE_DESCRIPTOR 0x0a
-#define TAG_CAROUSEL_ID_DESCRIPTOR 0x13
-#define TAG_STREAM_ID_DESCRIPTOR 0x52
+#define TAG_LANGUAGE_DESCRIPTOR 0x0a
+#define TAG_CAROUSEL_ID_DESCRIPTOR 0x13
+#define TAG_STREAM_ID_DESCRIPTOR 0x52
+#define TAG_DATA_BROADCAST_ID_DESCRIPTOR 0x66
/* bits of the descriptors we care about */
struct carousel_id_descriptor
@@ -65,6 +66,17 @@
uint8_t audio_type;
} __attribute__((__packed__));
+struct data_broadcast_id_descriptor
+{
+ uint16_t data_broadcast_id;
+ uint16_t application_type_code;
+ uint8_t boot_priority_hint;
+} __attribute__((__packed__));
+
+/* data_broadcast_id_descriptor values we want */
+#define DATA_BROADCAST_ID 0x0106
+#define APPLICATION_TYPE_CODE 0x0101
+
bool
is_audio_stream(uint8_t stream_type)
{
@@ -101,6 +113,8 @@
uint8_t desc_tag;
uint8_t desc_length;
uint16_t component_tag;
+ int desc_boot_pid;
+ int desc_carousel_id;
/* carousel data we know so far */
snprintf(_car.demux_device, sizeof(_car.demux_device), DEMUX_DEVICE, adapter);
@@ -110,6 +124,7 @@
/* unknown */
_car.carousel_id = 0;
+ _car.boot_pid = 0;
_car.audio_pid = 0;
_car.audio_type = 0;
_car.video_pid = 0;
@@ -179,6 +194,9 @@
_car.video_pid = elementary_pid;
_car.video_type = stream_type;
}
+ /* it's not the boot PID yet */
+ desc_boot_pid = -1;
+ desc_carousel_id = -1;
/* read the descriptors */
info_length = ((pmt[offset] & 0x0f) << 8) + pmt[offset+1];
offset += 2;
@@ -188,17 +206,35 @@
desc_length = pmt[offset+1];
offset += 2;
info_length -= 2;
- if(desc_tag == TAG_CAROUSEL_ID_DESCRIPTOR)
+ /* ignore boot PID if we explicitly chose a carousel ID */
+ if(desc_tag == TAG_DATA_BROADCAST_ID_DESCRIPTOR && carousel_id == -1)
{
+ struct data_broadcast_id_descriptor *desc;
+ desc = (struct data_broadcast_id_descriptor *) &pmt[offset];
+ if(ntohs(desc->data_broadcast_id) == DATA_BROADCAST_ID
+ && ntohs(desc->application_type_code) == APPLICATION_TYPE_CODE)
+ {
+ desc_boot_pid = elementary_pid;
+ vverbose("PID=%u boot_priority_hint=%u", elementary_pid, desc->boot_priority_hint);
+ }
+ else
+ {
+ vverbose("PID=%u data_broadcast_id=0x%x", elementary_pid, ntohs(desc->data_broadcast_id));
+ vhexdump(&pmt[offset], desc_length);
+ }
+ }
+ else if(desc_tag == TAG_CAROUSEL_ID_DESCRIPTOR)
+ {
struct carousel_id_descriptor *desc;
desc = (struct carousel_id_descriptor *) &pmt[offset];
if(carousel_id == -1 || carousel_id == (ntohl(desc->carousel_id)))
{
- _car.carousel_id = ntohl(desc->carousel_id);
- _car.boot_pid = elementary_pid;
- add_dsmcc_pid(&_car, elementary_pid);
- vverbose("PID=%u carousel_id=%u", elementary_pid, _car.carousel_id);
+ /* if we chose this carousel, set the boot PID */
+ if(carousel_id != -1)
+ desc_boot_pid = elementary_pid;
+ desc_carousel_id = ntohl(desc->carousel_id);
}
+ vverbose("PID=%u carousel_id=%u", elementary_pid, ntohl(desc->carousel_id));
}
else if(desc_tag == TAG_STREAM_ID_DESCRIPTOR)
{
@@ -227,6 +263,14 @@
offset += desc_length;
info_length -= desc_length;
}
+ /* is it the boot PID */
+ if(desc_boot_pid != -1)
+ {
+ vverbose("Set boot_pid=%u carousel_id=%u", desc_boot_pid, desc_carousel_id);
+ _car.carousel_id = desc_carousel_id;
+ _car.boot_pid = desc_boot_pid;
+ add_dsmcc_pid(&_car, desc_boot_pid);
+ }
}
/* did we find a DSM-CC stream */
Modified: redbutton-download/trunk/rb-download.c
===================================================================
--- redbutton-download/trunk/rb-download.c 2006-12-30 19:43:31 UTC (rev 164)
+++ redbutton-download/trunk/rb-download.c 2007-01-07 11:16:12 UTC (rev 165)
@@ -141,6 +141,7 @@
service_id = strtoul(argv[optind], NULL, 0);
car = find_mheg(adapter, timeout, service_id, carousel_id);
verbose("Carousel ID=%u", car->carousel_id);
+ verbose("Boot PID=%u", car->boot_pid);
verbose("Video PID=%u", car->video_pid);
verbose("Audio PID=%u", car->audio_pid);
if(listen)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ski...@us...> - 2007-01-11 16:34:55
|
Revision: 173
http://svn.sourceforge.net/redbutton/?rev=173&view=rev
Author: skilvington
Date: 2007-01-11 08:34:52 -0800 (Thu, 11 Jan 2007)
Log Message:
-----------
always listen for remote rb-browsers, also some reordering to make retuning possible
Modified Paths:
--------------
redbutton-download/trunk/listen.c
redbutton-download/trunk/listen.h
redbutton-download/trunk/rb-download.c
Modified: redbutton-download/trunk/listen.c
===================================================================
--- redbutton-download/trunk/listen.c 2007-01-11 11:10:32 UTC (rev 172)
+++ redbutton-download/trunk/listen.c 2007-01-11 16:34:52 UTC (rev 173)
@@ -17,6 +17,8 @@
#include <sys/wait.h>
#include "command.h"
+#include "findmheg.h"
+#include "carousel.h"
#include "utils.h"
/* listen() backlog, 5 is max for BSD apparently */
@@ -107,23 +109,18 @@
*/
void
-start_listener(struct listen_data *listen_data)
+start_listener(struct sockaddr_in *listen_addr, unsigned int adapter, unsigned int timeout, uint16_t service_id, int carousel_id)
{
+ struct listen_data listen_data;
struct sigaction action;
- pid_t child;
int sockopt;
int listen_sock;
int accept_sock;
fd_set read_fds;
socklen_t addr_len;
struct sockaddr_in client_addr;
+ pid_t child;
- /*
- * fork:
- * the parent listens for commands,
- * the child returns and downloads the carousel
- */
-
/* don't let our children become zombies */
action.sa_handler = dead_child;
sigemptyset(&action.sa_mask);
@@ -131,16 +128,11 @@
if(sigaction(SIGCHLD, &action, NULL) < 0)
fatal("signal: SIGCHLD: %s", strerror(errno));
- /* if we can't fork it's probably best to kill ourselves*/
- if((child = fork()) < 0)
- fatal("fork: %s", strerror(errno));
- /* child returns */
- else if(child == 0)
- return;
- /* parent continues */
+ /* fork off a child to download the carousel */
+ listen_data.carousel = start_downloader(adapter, timeout, service_id, carousel_id);
/* listen on the given ip:port */
- verbose("Listening on %s:%u", inet_ntoa(listen_data->addr.sin_addr), ntohs(listen_data->addr.sin_port));
+ verbose("Listening on %s:%u", inet_ntoa(listen_addr->sin_addr), ntohs(listen_addr->sin_port));
if((listen_sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
fatal("socket: %s", strerror(errno));
@@ -150,7 +142,7 @@
if(setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &sockopt, sizeof(sockopt)) < 0)
fatal("setsockopt: SO_REUSEADDR: %s", strerror(errno));
- if(bind(listen_sock, (struct sockaddr *) &listen_data->addr, sizeof(struct sockaddr_in)) < 0)
+ if(bind(listen_sock, (struct sockaddr *) listen_addr, sizeof(struct sockaddr_in)) < 0)
fatal("bind: %s", strerror(errno));
if(listen(listen_sock, BACKLOG) < 0)
@@ -188,7 +180,7 @@
{
/* child */
close(listen_sock);
- handle_connection(listen_data, accept_sock, &client_addr);
+ handle_connection(&listen_data, accept_sock, &client_addr);
close(accept_sock);
/* use _exit in child so stdio etc don't clean up twice */
_exit(EXIT_SUCCESS);
@@ -250,6 +242,37 @@
return;
}
+struct carousel *
+start_downloader(unsigned int adapter, unsigned int timeout, uint16_t service_id, int carousel_id)
+{
+ struct carousel *car;
+ pid_t child;
+
+ /* find the MHEG PIDs */
+ car = find_mheg(adapter, timeout, service_id, carousel_id);
+
+ verbose("Carousel ID=%u", car->carousel_id);
+ verbose("Boot PID=%u", car->boot_pid);
+ verbose("Video PID=%u", car->video_pid);
+ verbose("Audio PID=%u", car->audio_pid);
+
+ /*
+ * fork:
+ * the parent listens for commands,
+ * the child downloads the carousel
+ */
+
+ /* if we can't fork it's probably best to kill ourselves*/
+ if((child = fork()) < 0)
+ fatal("fork: %s", strerror(errno));
+ /* child downloads the carousel until killed by parent */
+ else if(child == 0)
+ load_carousel(car);
+ /* parent continues */
+
+ return car;
+}
+
static void
dead_child(int signo)
{
Modified: redbutton-download/trunk/listen.h
===================================================================
--- redbutton-download/trunk/listen.h 2007-01-11 11:10:32 UTC (rev 172)
+++ redbutton-download/trunk/listen.h 2007-01-11 16:34:52 UTC (rev 173)
@@ -11,12 +11,12 @@
struct listen_data
{
- struct sockaddr_in addr; /* ip:port to listen on */
struct carousel *carousel; /* carousel we are downloading */
};
int parse_addr(char *, struct in_addr *, in_port_t *);
-void start_listener(struct listen_data *);
+void start_listener(struct sockaddr_in *, unsigned int, unsigned int, uint16_t, int);
+struct carousel *start_downloader(unsigned int, unsigned int, uint16_t, int);
#endif
Modified: redbutton-download/trunk/rb-download.c
===================================================================
--- redbutton-download/trunk/rb-download.c 2007-01-11 11:10:32 UTC (rev 172)
+++ redbutton-download/trunk/rb-download.c 2007-01-11 16:34:52 UTC (rev 173)
@@ -1,5 +1,5 @@
/*
- * rb-download [-v] [-a <adapter>] [-b <base_dir>] [-t <timeout>] [-l[<listen-addr>]] [-c <carousel_id>] [<service_id>]
+ * rb-download [-v] [-a <adapter>] [-b <base_dir>] [-t <timeout>] [-l <listen_addr>] [-c <carousel_id>] [<service_id>]
*
* Download the DVB Object Carousel for the given channel onto the local hard disc
* files will be stored under the current dir if no -b option is given
@@ -15,13 +15,12 @@
* /dev/dvb/adapter0/dvr0
* use the -a option to change the adapter number (eg "-a 1" will use /dev/dvb/adapter1/demux0 etc)
*
- * if -l is given, rb-download listens on the network for commands from a remote rb-browser
+ * rb-download listens on the network for commands from a remote rb-browser
* the default IP to listen on is 0.0.0.0 (ie all interfaces), the default TCP port is 10101
- * listen-addr should be given in the form "host:port", where host defaults to 0.0.0.0 and port defaults to 10101
- * eg, to listen on a different port, do "-l8080"
- * to only listen on the loop back, do "-l127.0.0.1" or on a different port too, do "-l127.0.0.1:8080"
- * NOTE: because -l may or may not take an argument, you must not put a space between the -l and the value
- * (otherwise, "rb-download -l 1234", is ambiguous - listen on port 1234 or use service_id 1234?)
+ * the -l option changes the default IP and port
+ * listen_addr should be given in the form "host:port", where host defaults to 0.0.0.0 and port defaults to 10101
+ * eg, to listen on a different port, do "-l 8080"
+ * to only listen on the loop back, do "-l 127.0.0.1" or on a different port too, do "-l 127.0.0.1:8080"
*
* -v is verbose/debug mode, use more v's for more verbosity
*
@@ -35,7 +34,7 @@
*/
/*
- * Copyright (C) 2005, 2006, Simon Kilvington
+ * Copyright (C) 2005, 2006, 2007, Simon Kilvington
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -82,16 +81,21 @@
main(int argc, char *argv[])
{
char *prog_name = argv[0];
- unsigned int adapter = 0;
- unsigned int timeout = DEFAULT_TIMEOUT;
- bool listen = false;
- struct listen_data listen_data;
- int carousel_id = -1;
+ unsigned int adapter;
+ unsigned int timeout;
+ struct sockaddr_in listen_addr;
+ int carousel_id;
uint16_t service_id;
- struct carousel *car;
int arg;
- while((arg = getopt(argc, argv, "a:b:t:l::c:v")) != EOF)
+ /* default values */
+ adapter = 0;
+ timeout = DEFAULT_TIMEOUT;
+ listen_addr.sin_addr.s_addr = htonl(DEFAULT_LISTEN_ADDR);
+ listen_addr.sin_port = htons(DEFAULT_LISTEN_PORT);
+ carousel_id = -1; /* read it from the PMT */
+
+ while((arg = getopt(argc, argv, "a:b:t:l:c:v")) != EOF)
{
switch(arg)
{
@@ -109,12 +113,7 @@
break;
case 'l':
- listen = true;
- /* default values */
- listen_data.addr.sin_addr.s_addr = htonl(DEFAULT_LISTEN_ADDR);
- listen_data.addr.sin_port = htons(DEFAULT_LISTEN_PORT);
- /* optarg is NULL if no value is given, parse_addr can't fail with NULL */
- if(parse_addr(optarg, &listen_data.addr.sin_addr, &listen_data.addr.sin_port) < 0)
+ if(parse_addr(optarg, &listen_addr.sin_addr, &listen_addr.sin_port) < 0)
fatal("Unable to resolve host %s", optarg);
break;
@@ -139,17 +138,7 @@
else if(argc - optind == 1)
{
service_id = strtoul(argv[optind], NULL, 0);
- car = find_mheg(adapter, timeout, service_id, carousel_id);
- verbose("Carousel ID=%u", car->carousel_id);
- verbose("Boot PID=%u", car->boot_pid);
- verbose("Video PID=%u", car->video_pid);
- verbose("Audio PID=%u", car->audio_pid);
- if(listen)
- {
- listen_data.carousel = car;
- start_listener(&listen_data);
- }
- load_carousel(car);
+ start_listener(&listen_addr, adapter, timeout, service_id, carousel_id);
}
else
{
@@ -207,7 +196,7 @@
"[-a <adapter>] "
"[-b <base_dir>] "
"[-t <timeout>] "
- "[-l[<listen-addr>]] "
+ "[-l <listen_addr>] "
"[-c carousel_id] "
"[<service_id>]", prog_name);
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ski...@us...> - 2007-01-18 22:22:35
|
Revision: 181
http://svn.sourceforge.net/redbutton/?rev=181&view=rev
Author: skilvington
Date: 2007-01-18 14:22:31 -0800 (Thu, 18 Jan 2007)
Log Message:
-----------
allow backend to retune to different frequencies (only works for DVB-T at present)
Modified Paths:
--------------
redbutton-download/trunk/Makefile
redbutton-download/trunk/TODO
redbutton-download/trunk/listen.c
redbutton-download/trunk/rb-download.c
redbutton-download/trunk/utils.h
Added Paths:
-----------
redbutton-download/trunk/channels.c
redbutton-download/trunk/channels.h
Modified: redbutton-download/trunk/Makefile
===================================================================
--- redbutton-download/trunk/Makefile 2007-01-17 12:32:41 UTC (rev 180)
+++ redbutton-download/trunk/Makefile 2007-01-18 22:22:31 UTC (rev 181)
@@ -16,6 +16,7 @@
dsmcc.o \
biop.o \
fs.o \
+ channels.o \
utils.o
LIBS=-lz
Modified: redbutton-download/trunk/TODO
===================================================================
--- redbutton-download/trunk/TODO 2007-01-17 12:32:41 UTC (rev 180)
+++ redbutton-download/trunk/TODO 2007-01-18 22:22:31 UTC (rev 181)
@@ -5,9 +5,6 @@
(start of C4 news)
can't see how avstream can cause an out of memory error
-Sky Teletext - can't find PIDs for tags 1 and 2
-(need to read the component_tag descriptors for *all* service_id's on the MUX)
-
look into new splice() and tee() syscalls in 2.6.17 kernel for avstream
be able to read from a file
Added: redbutton-download/trunk/channels.c
===================================================================
--- redbutton-download/trunk/channels.c (rev 0)
+++ redbutton-download/trunk/channels.c 2007-01-18 22:22:31 UTC (rev 181)
@@ -0,0 +1,296 @@
+/*
+ * channels.c
+ */
+
+/*
+ * Copyright (C) 2007, Simon Kilvington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <limits.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <linux/dvb/frontend.h>
+
+#include "utils.h"
+
+/* internal functions */
+static struct dvb_frontend_parameters *get_tune_params(uint16_t);
+
+static FILE *_channels = NULL;
+
+/*
+ * if filename is NULL, it searches for:
+ * ~/channels.conf
+ * /etc/channels.conf
+ */
+
+bool
+init_channels_conf(char *filename)
+{
+ char *home;
+ char pathname[PATH_MAX];
+
+ if(_channels != NULL)
+ fatal("init_channels_conf: already initialised");
+
+ if(filename == NULL)
+ {
+ if((home = getenv("HOME")) != NULL)
+ {
+ snprintf(pathname, sizeof(pathname), "%s/channels.conf", home);
+ verbose("Trying to open %s", pathname);
+ _channels = fopen(pathname, "r");
+ }
+ if(_channels == NULL)
+ {
+ verbose("Trying to open /etc/channels.conf");
+ _channels = fopen("/etc/channels.conf", "r");
+ }
+ }
+ else
+ {
+ verbose("Trying to open %s", filename);
+ _channels = fopen(filename, "r");
+ }
+
+ return (_channels != NULL);
+}
+
+/*
+ * map strings to frontend enum values
+ * based on tzap utility in linuxtv dvb-apps package
+ */
+struct param
+{
+ char *name;
+ int value;
+};
+
+static const struct param inversion_list[] =
+{
+ { "INVERSION_OFF", INVERSION_OFF },
+ { "INVERSION_ON", INVERSION_ON },
+ { "INVERSION_AUTO", INVERSION_AUTO }
+};
+
+static const struct param bw_list[] =
+{
+ { "BANDWIDTH_6_MHZ", BANDWIDTH_6_MHZ },
+ { "BANDWIDTH_7_MHZ", BANDWIDTH_7_MHZ },
+ { "BANDWIDTH_8_MHZ", BANDWIDTH_8_MHZ }
+};
+
+static const struct param fec_list[] =
+{
+ { "FEC_1_2", FEC_1_2 },
+ { "FEC_2_3", FEC_2_3 },
+ { "FEC_3_4", FEC_3_4 },
+ { "FEC_4_5", FEC_4_5 },
+ { "FEC_5_6", FEC_5_6 },
+ { "FEC_6_7", FEC_6_7 },
+ { "FEC_7_8", FEC_7_8 },
+ { "FEC_8_9", FEC_8_9 },
+ { "FEC_AUTO", FEC_AUTO },
+ { "FEC_NONE", FEC_NONE }
+};
+
+static const struct param guard_list[] =
+{
+ {"GUARD_INTERVAL_1_16", GUARD_INTERVAL_1_16},
+ {"GUARD_INTERVAL_1_32", GUARD_INTERVAL_1_32},
+ {"GUARD_INTERVAL_1_4", GUARD_INTERVAL_1_4},
+ {"GUARD_INTERVAL_1_8", GUARD_INTERVAL_1_8}
+};
+
+static const struct param hierarchy_list[] =
+{
+ { "HIERARCHY_1", HIERARCHY_1 },
+ { "HIERARCHY_2", HIERARCHY_2 },
+ { "HIERARCHY_4", HIERARCHY_4 },
+ { "HIERARCHY_NONE", HIERARCHY_NONE }
+};
+
+static const struct param constellation_list[] =
+{
+ { "QPSK", QPSK },
+ { "QAM_128", QAM_128 },
+ { "QAM_16", QAM_16 },
+ { "QAM_256", QAM_256 },
+ { "QAM_32", QAM_32 },
+ { "QAM_64", QAM_64 }
+};
+
+static const struct param transmissionmode_list[] =
+{
+ { "TRANSMISSION_MODE_2K", TRANSMISSION_MODE_2K },
+ { "TRANSMISSION_MODE_8K", TRANSMISSION_MODE_8K },
+};
+
+#define LIST_SIZE(x) (sizeof(x) / sizeof(struct param))
+
+static int
+str2enum(char *str, const struct param *map, int map_size)
+{
+ while(map_size >= 0)
+ {
+ map_size --;
+ if(strcmp(str, map[map_size].name) == 0)
+ return map[map_size].value;
+ }
+
+ fatal("Invalid parameter '%s' in channels.conf file", str);
+
+ /* not reached */
+ return -1;
+}
+
+/*
+ * return the params needed to tune to the given service_id
+ * the data is read from the channels.conf file
+ * returns NULL if the service_id is not found
+ */
+
+static struct dvb_frontend_parameters _params;
+
+static struct dvb_frontend_parameters *
+get_tune_params(uint16_t service_id)
+{
+ char line[1024];
+ unsigned int freq;
+ char inv[32];
+ char bw[32];
+ char hp[32];
+ char lp[32];
+ char qam[32];
+ char trans[32];
+ char gi[32];
+ char hier[32];
+ unsigned int id;
+ int len;
+
+ bzero(&_params, sizeof(_params));
+
+ verbose("Searching channels.conf for service_id %u", service_id);
+
+ rewind(_channels);
+ while(!feof(_channels))
+ {
+ if(fgets(line, sizeof(line), _channels) == NULL
+ || sscanf(line, "%*[^:]:%u:%32[^:]:%32[^:]:%32[^:]:%32[^:]:%32[^:]:%32[^:]:%32[^:]:%32[^:]:%*[^:]:%*[^:]:%u", &freq, inv, bw, hp, lp, qam, trans, gi, hier, &id) != 10
+ || id != service_id)
+ continue;
+ /* chop off trailing \n */
+ len = strlen(line) - 1;
+ while(len >= 0 && line[len] == '\n')
+ line[len--] = '\0';
+ verbose("%s", line);
+ _params.frequency = freq;
+ _params.inversion = str2enum(inv, inversion_list, LIST_SIZE(inversion_list));
+ _params.u.ofdm.bandwidth = str2enum(bw, bw_list, LIST_SIZE(bw_list));
+ _params.u.ofdm.code_rate_HP = str2enum(hp, fec_list, LIST_SIZE(fec_list));
+ _params.u.ofdm.code_rate_LP = str2enum(lp, fec_list, LIST_SIZE(fec_list));
+ _params.u.ofdm.constellation = str2enum(qam, constellation_list, LIST_SIZE(constellation_list));
+ _params.u.ofdm.transmission_mode = str2enum(trans, transmissionmode_list, LIST_SIZE(transmissionmode_list));
+ _params.u.ofdm.guard_interval = str2enum(gi, guard_list, LIST_SIZE(guard_list));
+ _params.u.ofdm.hierarchy_information = str2enum(hier, hierarchy_list, LIST_SIZE(hierarchy_list));
+ return &_params;
+ }
+
+ return NULL;
+}
+
+/*
+ * retune to the frequency the given service_id is on
+ */
+
+bool
+tune_service_id(unsigned int adapter, unsigned int timeout, uint16_t service_id)
+{
+ char fe_dev[PATH_MAX];
+ struct dvb_frontend_info fe_info;
+ struct dvb_frontend_parameters current_params;
+ struct dvb_frontend_parameters *needed_params;
+ struct dvb_frontend_event event;
+ bool lock;
+ /* need to keep the frontend device open to stop it untuning itself */
+ /* TODO: fix this hack */
+ static int fe_fd = -1;
+
+ vverbose("Getting frontend info");
+
+ /* see what we are currently tuned to */
+ snprintf(fe_dev, sizeof(fe_dev), FE_DEVICE, adapter);
+ /*
+ * need O_RDWR if you want to tune, O_RDONLY is okay for getting info
+ * if someone else is using the frontend, we can only open O_RDONLY
+ * => we can still download data, but just not retune
+ */
+ if(fe_fd != -1)
+ close(fe_fd);
+ if((fe_fd = open(fe_dev, O_RDONLY | O_NONBLOCK)) < 0)
+ fatal("open '%s': %s", fe_dev, strerror(errno));
+
+ if(ioctl(fe_fd, FE_GET_INFO, &fe_info) < 0)
+ fatal("ioctl FE_GET_INFO: %s", strerror(errno));
+
+ if(fe_info.type != FE_OFDM)
+ fatal("TODO: Only able to tune DVB-T devices at present");
+
+ if(ioctl(fe_fd, FE_GET_FRONTEND, ¤t_params) < 0)
+ fatal("ioctl FE_GET_FRONTEND: %s", strerror(errno));
+
+ /* find the tuning params for the service */
+ if((needed_params = get_tune_params(service_id)) == NULL)
+ fatal("service_id %u not found in channels.conf file", service_id);
+
+ /* are we already tuned to the right frequency */
+ vverbose("Current frequency %u; needed %u", current_params.frequency, needed_params->frequency);
+ if(current_params.frequency != needed_params->frequency)
+ {
+ verbose("Retuning to frequency %u", needed_params->frequency);
+ close(fe_fd);
+ if((fe_fd = open(fe_dev, O_RDWR | O_NONBLOCK)) < 0)
+ fatal("open '%s': %s", fe_dev, strerror(errno));
+ /* empty event queue */
+ while(ioctl(fe_fd, FE_GET_EVENT, &event) >= 0)
+ ; /* do nothing */
+ /* tune in */
+ if(ioctl(fe_fd, FE_SET_FRONTEND, needed_params) < 0)
+ fatal("ioctl FE_GET_FRONTEND: %s", strerror(errno));
+ /* wait for lock */
+ vverbose("Waiting for tuner to lock on");
+ /* TODO: use timeout value here */
+ lock = false;
+ while(!lock)
+ {
+ if(ioctl(fe_fd, FE_GET_EVENT, &event) >= 0)
+ lock = event.status & FE_HAS_LOCK;
+ }
+ vverbose("Retuned");
+ }
+
+ return true;
+}
+
+
Added: redbutton-download/trunk/channels.h
===================================================================
--- redbutton-download/trunk/channels.h (rev 0)
+++ redbutton-download/trunk/channels.h 2007-01-18 22:22:31 UTC (rev 181)
@@ -0,0 +1,34 @@
+/*
+ * channels.h
+ */
+
+/*
+ * Copyright (C) 2007, Simon Kilvington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __CHANNELS_H__
+#define __CHANNELS_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+
+bool init_channels_conf(char *);
+
+bool tune_service_id(unsigned int, unsigned int, uint16_t);
+
+#endif /* __CHANNELS_H__ */
+
Modified: redbutton-download/trunk/listen.c
===================================================================
--- redbutton-download/trunk/listen.c 2007-01-17 12:32:41 UTC (rev 180)
+++ redbutton-download/trunk/listen.c 2007-01-18 22:22:31 UTC (rev 181)
@@ -19,6 +19,7 @@
#include "command.h"
#include "findmheg.h"
#include "carousel.h"
+#include "channels.h"
#include "utils.h"
/* listen() backlog, 5 is max for BSD apparently */
@@ -276,6 +277,9 @@
{
struct carousel *car;
pid_t child;
+
+ /* retune if needed */
+ tune_service_id(adapter, timeout, service_id);
/* find the MHEG PIDs */
car = find_mheg(adapter, timeout, service_id, carousel_id);
Modified: redbutton-download/trunk/rb-download.c
===================================================================
--- redbutton-download/trunk/rb-download.c 2007-01-17 12:32:41 UTC (rev 180)
+++ redbutton-download/trunk/rb-download.c 2007-01-18 22:22:31 UTC (rev 181)
@@ -1,5 +1,5 @@
/*
- * rb-download [-v] [-a <adapter>] [-b <base_dir>] [-t <timeout>] [-l <listen_addr>] [-c <carousel_id>] [<service_id>]
+ * rb-download [-v] [-a <adapter>] [-b <base_dir>] [-t <timeout>] [-f <channels_file>] [-l <listen_addr>] [-c <carousel_id>] [<service_id>]
*
* Download the DVB Object Carousel for the given channel onto the local hard disc
* files will be stored under the current dir if no -b option is given
@@ -15,6 +15,12 @@
* /dev/dvb/adapter0/dvr0
* use the -a option to change the adapter number (eg "-a 1" will use /dev/dvb/adapter1/demux0 etc)
*
+ * rb-download needs a "channels.conf" file which gives tuning parameters for service_id's
+ * channels.conf files can be generated by the "scan" utility in the dvb-apps package at www.linuxtv.org
+ * if not specified with -f, rb-download will search for:
+ * ~/channels.conf
+ * /etc/channels.conf
+ *
* rb-download listens on the network for commands from a remote rb-browser
* the default IP to listen on is 0.0.0.0 (ie all interfaces), the default TCP port is 10101
* the -l option changes the default IP and port
@@ -64,6 +70,7 @@
#include "findmheg.h"
#include "carousel.h"
#include "listen.h"
+#include "channels.h"
#include "utils.h"
/* seconds before we assume no DSMCC data is available on this PID */
@@ -82,7 +89,9 @@
{
char *prog_name = argv[0];
unsigned int adapter;
+ char *base_dir;
unsigned int timeout;
+ char *channels_file;
struct sockaddr_in listen_addr;
int carousel_id;
uint16_t service_id;
@@ -90,12 +99,14 @@
/* default values */
adapter = 0;
+ base_dir = NULL;
timeout = DEFAULT_TIMEOUT;
+ channels_file = NULL;
listen_addr.sin_addr.s_addr = htonl(DEFAULT_LISTEN_ADDR);
listen_addr.sin_port = htons(DEFAULT_LISTEN_PORT);
carousel_id = -1; /* read it from the PMT */
- while((arg = getopt(argc, argv, "a:b:t:l:c:v")) != EOF)
+ while((arg = getopt(argc, argv, "a:b:f:t:l:c:v")) != EOF)
{
switch(arg)
{
@@ -104,10 +115,14 @@
break;
case 'b':
- if(chdir(optarg) < 0)
- fatal("Unable to cd to '%s': %s", optarg, strerror(errno));
+ /* don't chdir yet, in case we have a relative -f param */
+ base_dir = optarg;
break;
+ case 'f':
+ channels_file = optarg;
+ break;
+
case 't':
timeout = strtoul(optarg, NULL, 0);
break;
@@ -131,6 +146,15 @@
}
}
+ /* initialise channels.conf */
+ if(!init_channels_conf(channels_file))
+ fatal("Unable to parse channels.conf file");
+
+ /* do we need to change the base directory */
+ if(base_dir != NULL
+ && chdir(base_dir) < 0)
+ fatal("Unable to cd to '%s': %s", base_dir, strerror(errno));
+
if(argc == optind)
{
list_channels(adapter, timeout);
@@ -196,6 +220,7 @@
"[-a <adapter>] "
"[-b <base_dir>] "
"[-t <timeout>] "
+ "[-f <channels_file>] "
"[-l <listen_addr>] "
"[-c carousel_id] "
"[<service_id>]", prog_name);
Modified: redbutton-download/trunk/utils.h
===================================================================
--- redbutton-download/trunk/utils.h 2007-01-17 12:32:41 UTC (rev 180)
+++ redbutton-download/trunk/utils.h 2007-01-18 22:22:31 UTC (rev 181)
@@ -45,6 +45,13 @@
#define DVR_DEVICE "/dev/dvb/adapter%u/dvr0"
#endif
+/* DVB frontend device - %u is card number */
+#if defined(HAVE_DREAMBOX_HARDWARE)
+#define FE_DEVICE "/dev/dvb/card%u/frontend0"
+#else
+#define FE_DEVICE "/dev/dvb/adapter%u/frontend0"
+#endif
+
char *skip_ws(char *);
char hex_digit(uint8_t);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ski...@us...> - 2007-01-26 16:34:15
|
Revision: 197
http://svn.sourceforge.net/redbutton/?rev=197&view=rev
Author: skilvington
Date: 2007-01-26 08:33:59 -0800 (Fri, 26 Jan 2007)
Log Message:
-----------
not a fatal error if you have no channels.conf file - you just can't retune
Modified Paths:
--------------
redbutton-download/trunk/channels.c
redbutton-download/trunk/listen.c
redbutton-download/trunk/rb-download.c
Modified: redbutton-download/trunk/channels.c
===================================================================
--- redbutton-download/trunk/channels.c 2007-01-24 20:16:21 UTC (rev 196)
+++ redbutton-download/trunk/channels.c 2007-01-26 16:33:59 UTC (rev 197)
@@ -189,6 +189,12 @@
unsigned int id;
int len;
+ if(_channels == NULL)
+ {
+ verbose("No channels.conf file available");
+ return NULL;
+ }
+
bzero(&_params, sizeof(_params));
verbose("Searching channels.conf for service_id %u", service_id);
@@ -262,7 +268,10 @@
/* find the tuning params for the service */
if((needed_params = get_tune_params(service_id)) == NULL)
- fatal("service_id %u not found in channels.conf file", service_id);
+ {
+ error("service_id %u not found in channels.conf file", service_id);
+ return false;
+ }
/* TODO */
/* if no-one was using the frontend when we open it
Modified: redbutton-download/trunk/listen.c
===================================================================
--- redbutton-download/trunk/listen.c 2007-01-24 20:16:21 UTC (rev 196)
+++ redbutton-download/trunk/listen.c 2007-01-26 16:33:59 UTC (rev 197)
@@ -279,7 +279,8 @@
pid_t child;
/* retune if needed */
- tune_service_id(adapter, timeout, service_id);
+ if(!tune_service_id(adapter, timeout, service_id))
+ error("Unable to retune; let's hope you're already tuned to the right frequency...");
/* find the MHEG PIDs */
car = find_mheg(adapter, timeout, service_id, carousel_id);
Modified: redbutton-download/trunk/rb-download.c
===================================================================
--- redbutton-download/trunk/rb-download.c 2007-01-24 20:16:21 UTC (rev 196)
+++ redbutton-download/trunk/rb-download.c 2007-01-26 16:33:59 UTC (rev 197)
@@ -148,7 +148,7 @@
/* initialise channels.conf */
if(!init_channels_conf(channels_file))
- fatal("Unable to parse channels.conf file");
+ error("Unable to open channels.conf file");
/* do we need to change the base directory */
if(base_dir != NULL
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ski...@us...> - 2007-02-19 13:17:36
|
Revision: 224
http://svn.sourceforge.net/redbutton/?rev=224&view=rev
Author: skilvington
Date: 2007-02-19 05:17:28 -0800 (Mon, 19 Feb 2007)
Log Message:
-----------
caller provides output buffer when reading DVB tables
Modified Paths:
--------------
redbutton-download/trunk/TODO
redbutton-download/trunk/carousel.c
redbutton-download/trunk/findmheg.c
redbutton-download/trunk/list.c
redbutton-download/trunk/table.c
redbutton-download/trunk/table.h
Modified: redbutton-download/trunk/TODO
===================================================================
--- redbutton-download/trunk/TODO 2007-02-18 14:37:15 UTC (rev 223)
+++ redbutton-download/trunk/TODO 2007-02-19 13:17:28 UTC (rev 224)
@@ -1,5 +1,4 @@
cache PAT and PMTs
-also, better if caller provides output buffer for tables
need to kill all existing command connections on retune
(listen_data->carousel is stale for them)
Modified: redbutton-download/trunk/carousel.c
===================================================================
--- redbutton-download/trunk/carousel.c 2007-02-18 14:37:15 UTC (rev 223)
+++ redbutton-download/trunk/carousel.c 2007-02-19 13:17:28 UTC (rev 224)
@@ -34,7 +34,7 @@
void
load_carousel(struct carousel *car)
{
- unsigned char *table;
+ unsigned char table[MAX_TABLE_LEN];
bool done;
/* no modules yet */
@@ -46,7 +46,7 @@
do
{
struct dsmccMessageHeader *dsmcc;
- if((table = read_dsmcc_tables(car)) == NULL)
+ if(!read_dsmcc_tables(car, table))
fatal("Unable to read PID");
dsmcc = (struct dsmccMessageHeader *) &table[8];
if(dsmcc->protocolDiscriminator == DSMCC_PROTOCOL
Modified: redbutton-download/trunk/findmheg.c
===================================================================
--- redbutton-download/trunk/findmheg.c 2007-02-18 14:37:15 UTC (rev 223)
+++ redbutton-download/trunk/findmheg.c 2007-02-19 13:17:28 UTC (rev 224)
@@ -81,7 +81,7 @@
static struct avstreams *find_current_avstreams(struct carousel *, int, int);
static struct avstreams *find_service_avstreams(struct carousel *, int, int, int);
-static unsigned char *read_pmt(char *, uint16_t, unsigned int);
+static bool read_pmt(char *, uint16_t, unsigned int, unsigned char *);
bool
is_audio_stream(uint8_t stream_type)
@@ -107,7 +107,7 @@
struct carousel *
find_mheg(unsigned int adapter, unsigned int timeout, uint16_t service_id, int carousel_id)
{
- unsigned char *pmt;
+ unsigned char pmt[MAX_TABLE_LEN];
uint16_t section_length;
uint16_t offset;
uint8_t stream_type;
@@ -144,7 +144,7 @@
_car.modules = NULL;
/* get the PMT */
- if((pmt = read_pmt(_car.demux_device, service_id, timeout)) == NULL)
+ if(!read_pmt(_car.demux_device, service_id, timeout, pmt))
fatal("Unable to read PMT");
section_length = 3 + (((pmt[1] & 0x0f) << 8) + pmt[2]);
@@ -302,7 +302,7 @@
static struct avstreams *
find_service_avstreams(struct carousel *car, int service_id, int audio_tag, int video_tag)
{
- unsigned char *pmt;
+ unsigned char pmt[MAX_TABLE_LEN];
uint16_t section_length;
uint16_t offset;
uint8_t stream_type;
@@ -318,7 +318,7 @@
bzero(&_streams, sizeof(_streams));
/* get the PMT */
- if((pmt = read_pmt(car->demux_device, service_id, car->timeout)) == NULL)
+ if(!read_pmt(car->demux_device, service_id, car->timeout, pmt))
fatal("Unable to read PMT");
section_length = 3 + (((pmt[1] & 0x0f) << 8) + pmt[2]);
@@ -400,21 +400,26 @@
return &_streams;
}
-static unsigned char *
-read_pmt(char *demux, uint16_t service_id, unsigned int timeout)
+/*
+ * output buffer must be at least MAX_TABLE_LEN bytes
+ * returns false if it timesout
+ */
+
+bool
+read_pmt(char *demux, uint16_t service_id, unsigned int timeout, unsigned char *out)
{
- unsigned char *pat;
+ unsigned char pat[MAX_TABLE_LEN];
uint16_t section_length;
uint16_t offset;
uint16_t map_pid = 0;
bool found;
- unsigned char *pmt;
+ bool rc;
/* get the PAT */
- if((pat = read_table(_car.demux_device, PID_PAT, TID_PAT, timeout)) == NULL)
+ if(!read_table(_car.demux_device, PID_PAT, TID_PAT, timeout, pat))
{
error("Unable to read PAT");
- return NULL;
+ return false;
}
section_length = 3 + (((pat[1] & 0x0f) << 8) + pat[2]);
@@ -442,9 +447,10 @@
vverbose("PMT PID: %u", map_pid);
/* get the PMT */
- if((pmt = read_table(_car.demux_device, map_pid, TID_PMT, timeout)) == NULL)
+ rc = read_table(_car.demux_device, map_pid, TID_PMT, timeout, out);
+ if(!rc)
error("Unable to read PMT");
- return pmt;
+ return rc;
}
Modified: redbutton-download/trunk/list.c
===================================================================
--- redbutton-download/trunk/list.c 2007-02-18 14:37:15 UTC (rev 223)
+++ redbutton-download/trunk/list.c 2007-02-19 13:17:28 UTC (rev 224)
@@ -37,7 +37,7 @@
list_channels(unsigned int adapter, unsigned int timeout)
{
char demux_dev[PATH_MAX];
- unsigned char *sds;
+ unsigned char sds[MAX_TABLE_LEN];
uint16_t size;
uint16_t offset;
uint16_t service_id;
@@ -53,7 +53,7 @@
printf("==\t=======\n");
/* grab the Service Description Section table */
- if((sds = read_table(demux_dev, PID_SDT, TID_SDS, timeout)) == NULL)
+ if(!read_table(demux_dev, PID_SDT, TID_SDS, timeout, sds))
fatal("Unable to read SDT");
/* 12 bit section_length field */
Modified: redbutton-download/trunk/table.c
===================================================================
--- redbutton-download/trunk/table.c 2007-02-18 14:37:15 UTC (rev 223)
+++ redbutton-download/trunk/table.c 2007-02-19 13:17:28 UTC (rev 224)
@@ -38,21 +38,23 @@
#include <linux/dvb/dmx.h>
#endif
+#include "table.h"
#include "dsmcc.h"
#include "carousel.h"
#include "biop.h"
#include "utils.h"
-#define MAX_TABLE_LEN 4096
-
/* DSMCC table ID's we want */
#define TID_DSMCC_CONTROL 0x3b /* DSI or DII */
#define TID_DSMCC_DATA 0x3c /* DDB */
-static unsigned char _buf[MAX_TABLE_LEN];
+/*
+ * output buffer must be at least MAX_TABLE_LEN bytes
+ * returns false if it timesout
+ */
-unsigned char *
-read_table(char *device, uint16_t pid, uint8_t tid, unsigned int secs)
+bool
+read_table(char *device, uint16_t pid, uint8_t tid, unsigned int secs, unsigned char *out)
{
int fd_data;
struct dmx_sct_filter_params sctFilterParams;
@@ -63,7 +65,7 @@
if((fd_data = open(device, O_RDWR)) < 0)
{
error("open '%s': %s", device, strerror(errno));
- return NULL;
+ return false;
}
memset(&sctFilterParams, 0, sizeof(sctFilterParams));
@@ -77,14 +79,15 @@
{
error("ioctl DMX_SET_FILTER: %s", strerror(errno));
close(fd_data);
- return NULL;
+ return false;
}
timeout.tv_sec = secs;
timeout.tv_usec = 0;
do
{
- _buf[0] = 0xff; /* we never want table ID 0xff */
+ /* we check for out[0]==tid to see if we read the table */
+ out[0] = ~tid;
FD_ZERO(&readfds);
FD_SET(fd_data, &readfds);
if(select(fd_data + 1, &readfds, NULL, NULL, &timeout) < 0)
@@ -93,36 +96,38 @@
continue;
error("read_table: select: %s", strerror(errno));
close(fd_data);
- return NULL;
+ return false;
}
if(FD_ISSET(fd_data, &readfds))
{
- if((n = read(fd_data, _buf, sizeof(_buf))) < 0)
+ if((n = read(fd_data, out, MAX_TABLE_LEN)) < 0)
{
error("read: %s", strerror(errno));
close(fd_data);
- return NULL;
+ return false;
}
}
else
{
error("Timeout reading %s", device);
close(fd_data);
- return NULL;
+ return false;
}
}
- while(_buf[0] != tid);
+ while(out[0] != tid);
-// printf("PID: 0x%x table_id: 0x%x length: %d bytes\n", pid, _buf[0], n);
-// hexdump(_buf, n);
-
close(fd_data);
- return _buf;
+ return true;
}
-unsigned char *
-read_dsmcc_tables(struct carousel *car)
+/*
+ * output buffer must be at least MAX_TABLE_LEN bytes
+ * returns false if it timesout
+ */
+
+bool
+read_dsmcc_tables(struct carousel *car, unsigned char *out)
{
struct timeval timeout;
unsigned int i;
@@ -135,7 +140,7 @@
timeout.tv_usec = 0;
do
{
- _buf[0] = 0;
+ out[0] = 0;
/* work out the max fd number and set the fds we want to read from */
max = 0;
FD_ZERO(&readfds);
@@ -150,7 +155,7 @@
if(select(max + 1, &readfds, NULL, NULL, &timeout) < 0)
{
error("read_dsmcc_tables: select: %s", strerror(errno));
- return NULL;
+ return false;
}
/* see which fd is ready */
fd = -1;
@@ -172,25 +177,22 @@
if(fd == -1)
{
error("Timeout reading %s", car->demux_device);
- return NULL;
+ return false;
}
/* read the table */
- if((n = read(fd, _buf, sizeof(_buf))) < 0)
+ if((n = read(fd, out, MAX_TABLE_LEN)) < 0)
{
/*
* may get EOVERFLOW if we don't read quick enough,
* so just report it and have another go
*/
error("read: %s", strerror(errno));
- _buf[0] = 0;
+ out[0] = 0;
}
}
- while(_buf[0] != TID_DSMCC_CONTROL && _buf[0] != TID_DSMCC_DATA);
+ while(out[0] != TID_DSMCC_CONTROL && out[0] != TID_DSMCC_DATA);
-// printf("PID: 0x%x table_id: 0x%x length: %d bytes\n", car->current_pid, _buf[0], n);
-// hexdump(_buf, n);
-
- return _buf;
+ return out;
}
void
Modified: redbutton-download/trunk/table.h
===================================================================
--- redbutton-download/trunk/table.h 2007-02-18 14:37:15 UTC (rev 223)
+++ redbutton-download/trunk/table.h 2007-02-19 13:17:28 UTC (rev 224)
@@ -24,13 +24,17 @@
#define __TABLE_H__
#include <stdint.h>
+#include <stdbool.h>
#include "module.h"
-unsigned char *read_table(char *, uint16_t, uint8_t, unsigned int);
+/* max size of a DVB table */
+#define MAX_TABLE_LEN 4096
-unsigned char *read_dsmcc_tables(struct carousel *);
+bool read_table(char *, uint16_t, uint8_t, unsigned int, unsigned char *);
+bool read_dsmcc_tables(struct carousel *, unsigned char *);
+
void add_dsmcc_pid(struct carousel *, uint16_t);
#endif /* __TABLE_H__ */
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|