[Redbutton-devel] SF.net SVN: redbutton: [27] redbutton-browser/trunk
Brought to you by:
skilvington
|
From: <ski...@us...> - 2006-03-25 14:20:17
|
Revision: 27 Author: skilvington Date: 2006-03-25 06:19:43 -0800 (Sat, 25 Mar 2006) ViewCVS: http://svn.sourceforge.net/redbutton/?rev=27&view=rev Log Message: ----------- keep the connection to the backend open Modified Paths: -------------- redbutton-browser/trunk/MHEGBackend.c redbutton-browser/trunk/MHEGBackend.h redbutton-download/trunk/command.c redbutton-download/trunk/command.h redbutton-download/trunk/listen.c redbutton-download/trunk/stream.c redbutton-download/trunk/stream.h redbutton-download/trunk/utils.c redbutton-download/trunk/utils.h Modified: redbutton-browser/trunk/MHEGBackend.c =================================================================== --- redbutton-browser/trunk/MHEGBackend.c 2006-03-25 10:43:15 UTC (rev 26) +++ redbutton-browser/trunk/MHEGBackend.c 2006-03-25 14:19:43 UTC (rev 27) @@ -45,7 +45,7 @@ static int parse_addr(char *, struct in_addr *, in_port_t *); static int get_host_addr(char *, struct in_addr *); -static FILE *remote_command(MHEGBackend *, char *); +static FILE *remote_command(MHEGBackend *, bool, char *); static unsigned int remote_response(FILE *); static char *external_filename(MHEGBackend *, OctetString *); @@ -61,6 +61,9 @@ b->addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); b->addr.sin_port = htons(DEFAULT_REMOTE_PORT); + /* no connection to the backend yet */ + b->be_sock = NULL; + if(remote) { /* backend is on a different host, srg_loc is the remote host[:port] */ @@ -83,6 +86,11 @@ void MHEGBackend_fini(MHEGBackend *b) { + /* send quit command */ + if(b->be_sock != NULL + && remote_command(b, true, "quit\n") != NULL) + fclose(b->be_sock); + return; } @@ -142,23 +150,30 @@ /* * send the given command to the remote backend + * if reuse is true, reuse the existing connection to the backend * returns a socket FILE to read the response from * returns NULL if it can't contact the backend */ static FILE * -remote_command(MHEGBackend *t, char *cmd) +remote_command(MHEGBackend *t, bool reuse, char *cmd) { int sock; FILE *file; - /* connect to the backend */ + /* can we use the existing connection */ + if(reuse && t->be_sock != NULL) + { + fputs(cmd, t->be_sock); + return t->be_sock; + } + + /* need to connect to the backend */ if((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { error("Unable to create backend socket: %s", strerror(errno)); return NULL; } - if(connect(sock, (struct sockaddr *) &t->addr, sizeof(struct sockaddr_in)) < 0) { error("Unable to connect to backend: %s", strerror(errno)); @@ -178,6 +193,10 @@ close(sock); } + /* remember it if we need to reuse it */ + if(reuse) + t->be_sock = file; + return file; } @@ -342,13 +361,11 @@ snprintf(cmd, sizeof(cmd), "check %s\n", MHEGEngine_absoluteFilename(name)); - if((sock = remote_command(t, cmd)) == NULL) + if((sock = remote_command(t, true, cmd)) == NULL) return false; exists = (remote_response(sock) == BACKEND_RESPONSE_OK); - fclose(sock); - return exists; } @@ -368,7 +385,7 @@ snprintf(cmd, sizeof(cmd), "file %s\n", MHEGEngine_absoluteFilename(name)); - if((sock = remote_command(t, cmd)) == NULL) + if((sock = remote_command(t, true, cmd)) == NULL) return false; /* if it exists, read the file size */ @@ -377,7 +394,6 @@ || sscanf(cmd, "Length %u", &size) != 1) { error("Unable to load '%.*s'", name->size, name->data); - fclose(sock); return false; } @@ -390,8 +406,6 @@ while(!feof(sock) && nread < size) nread += fread(out->data + nread, 1, size - nread, sock); - fclose(sock); - /* did we read it all */ if(nread < size) { @@ -422,7 +436,7 @@ snprintf(cmd, sizeof(cmd), "file %s\n", MHEGEngine_absoluteFilename(name)); - if((sock = remote_command(t, cmd)) == NULL) + if((sock = remote_command(t, true, cmd)) == NULL) return NULL; /* if it exists, read the file size */ @@ -430,7 +444,6 @@ || fgets(cmd, sizeof(cmd), sock) == NULL || sscanf(cmd, "Length %u", &size) != 1) { - fclose(sock); return NULL; } @@ -449,8 +462,6 @@ size -= nread; } - fclose(sock); - /* rewind the file */ if(out != NULL) rewind(out); @@ -490,7 +501,8 @@ else snprintf(cmd, sizeof(cmd), "vstream %d\n", *video_tag); - if((sock = remote_command(t, cmd)) == NULL) + /* false => create a new connection to the backend */ + if((sock = remote_command(t, false, cmd)) == NULL) return NULL; /* did it work */ Modified: redbutton-browser/trunk/MHEGBackend.h =================================================================== --- redbutton-browser/trunk/MHEGBackend.h 2006-03-25 10:43:15 UTC (rev 26) +++ redbutton-browser/trunk/MHEGBackend.h 2006-03-25 14:19:43 UTC (rev 27) @@ -16,6 +16,7 @@ { char *base_dir; /* local Service Gateway root directory */ struct sockaddr_in addr; /* remote backend IP and port */ + FILE *be_sock; /* connection to remote backend */ /* function pointers */ struct MHEGBackendFns { Modified: redbutton-download/trunk/command.c =================================================================== --- redbutton-download/trunk/command.c 2006-03-25 10:43:15 UTC (rev 26) +++ redbutton-download/trunk/command.c 2006-03-25 14:19:43 UTC (rev 27) @@ -19,35 +19,35 @@ #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 **); +bool cmd_astream(struct listen_data *, FILE *, int, char **); +bool cmd_avstream(struct listen_data *, FILE *, int, char **); +bool cmd_check(struct listen_data *, FILE *, int, char **); +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_vstream(struct listen_data *, FILE *, int, char **); static struct { char *name; char *args; - bool (*proc)(struct listen_data *, int, int, char **); + bool (*proc)(struct listen_data *, FILE *, int, char **); 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" }, + { "exit", "", cmd_quit, "close the connection" }, { "file", "<ContentReference>", cmd_file, "Retrieve the given file from the carousel" }, { "help", "", cmd_help, "List available commands" }, - { "quit", "", cmd_quit, "Kill the programme" }, + { "quit", "", cmd_quit, "close the connection" }, { "vstream", "<ComponentTag>", cmd_vstream, "Stream the given video component tag" }, { 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") +#define SEND_RESPONSE(RC, MESSAGE) fputs(#RC " " MESSAGE "\n", client) /* internal routines */ char *external_filename(struct listen_data *, char *); @@ -55,11 +55,11 @@ /* * process the given command - * return true if we should quit the programme + * return true if we should close the connection */ bool -process_command(struct listen_data *listen_data, int client_sock, char *cmd) +process_command(struct listen_data *listen_data, FILE *client, char *cmd) { int argc; char *argv[ARGV_MAX]; @@ -102,7 +102,7 @@ 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); + return (command[i].proc)(listen_data, client, argc, argv); } SEND_RESPONSE(500, "Unrecognised command"); @@ -113,10 +113,10 @@ /* * the commands * listen_data is global data needed by listener commands - * client_sock is where any response data should go + * client 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 + * return true if we should close the connection */ #define CHECK_USAGE(ARGC, SYNTAX) \ @@ -135,7 +135,7 @@ */ bool -cmd_astream(struct listen_data *listen_data, int client_sock, int argc, char *argv[]) +cmd_astream(struct listen_data *listen_data, FILE *client, int argc, char *argv[]) { struct carousel *car = listen_data->carousel; int tag; @@ -174,16 +174,17 @@ /* tell the client what PID the component tag resolved to */ snprintf(hdr, sizeof(hdr), "AudioPID %u\n", pid); - write_string(client_sock, hdr); + fputs(hdr, client); - /* shovel the transport stream down client_sock until the client closes it or we get an error */ - stream_ts(ts_fd, client_sock); + /* shovel the transport stream to client until the client closes or we get an error */ + stream_ts(ts_fd, client); /* clean up */ close(ts_fd); close(audio_fd); - return false; + /* close the connection */ + return true; } /* @@ -195,7 +196,7 @@ */ bool -cmd_vstream(struct listen_data *listen_data, int client_sock, int argc, char *argv[]) +cmd_vstream(struct listen_data *listen_data, FILE *client, int argc, char *argv[]) { struct carousel *car = listen_data->carousel; int tag; @@ -234,16 +235,17 @@ /* tell the client what PID the component tag resolved to */ snprintf(hdr, sizeof(hdr), "VideoPID %u\n", pid); - write_string(client_sock, hdr); + fputs(hdr, client); /* shovel the transport stream down client_sock until the client closes it or we get an error */ - stream_ts(ts_fd, client_sock); + stream_ts(ts_fd, client); /* clean up */ close(ts_fd); close(video_fd); - return false; + /* close the connection */ + return true; } /* @@ -255,7 +257,7 @@ */ bool -cmd_avstream(struct listen_data *listen_data, int client_sock, int argc, char *argv[]) +cmd_avstream(struct listen_data *listen_data, FILE *client, int argc, char *argv[]) { struct carousel *car = listen_data->carousel; int audio_tag; @@ -310,17 +312,18 @@ /* 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); + fputs(hdr, client); /* shovel the transport stream down client_sock until the client closes it or we get an error */ - stream_ts(ts_fd, client_sock); + stream_ts(ts_fd, client); /* clean up */ close(ts_fd); close(audio_fd); close(video_fd); - return false; + /* close the connection */ + return true; } /* @@ -330,7 +333,7 @@ */ bool -cmd_check(struct listen_data *listen_data, int client_sock, int argc, char *argv[]) +cmd_check(struct listen_data *listen_data, FILE *client, int argc, char *argv[]) { char *filename; FILE *file; @@ -363,7 +366,7 @@ */ bool -cmd_file(struct listen_data *listen_data, int client_sock, int argc, char *argv[]) +cmd_file(struct listen_data *listen_data, FILE *client, int argc, char *argv[]) { char *filename; FILE *file; @@ -400,14 +403,14 @@ /* send the file length */ snprintf(hdr, sizeof(hdr), "Length %ld\n", size); - write_string(client_sock, hdr); + fputs(hdr, client); /* send the file contents */ left = size; while(left > 0) { nread = fread(buff, 1, sizeof(buff), file); - write_all(client_sock, buff, nread); + fwrite(buff, 1, nread, client); left -= nread; } @@ -421,7 +424,7 @@ */ bool -cmd_help(struct listen_data *listen_data, int client_sock, int argc, char *argv[]) +cmd_help(struct listen_data *listen_data, FILE *client, int argc, char *argv[]) { int i; char name_args[64]; @@ -433,7 +436,7 @@ { 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); + fputs(help_line, client); } return false; @@ -444,7 +447,7 @@ */ bool -cmd_quit(struct listen_data *listen_data, int client_sock, int argc, char *argv[]) +cmd_quit(struct listen_data *listen_data, FILE *client, int argc, char *argv[]) { return true; } Modified: redbutton-download/trunk/command.h =================================================================== --- redbutton-download/trunk/command.h 2006-03-25 10:43:15 UTC (rev 26) +++ redbutton-download/trunk/command.h 2006-03-25 14:19:43 UTC (rev 27) @@ -7,6 +7,6 @@ #include "listen.h" -bool process_command(struct listen_data *, int, char *); +bool process_command(struct listen_data *, FILE *, char *); #endif Modified: redbutton-download/trunk/listen.c =================================================================== --- redbutton-download/trunk/listen.c 2006-03-25 10:43:15 UTC (rev 26) +++ redbutton-download/trunk/listen.c 2006-03-25 14:19:43 UTC (rev 27) @@ -25,7 +25,7 @@ /* internal functions */ static int get_host_addr(char *, struct in_addr *); -static bool handle_connection(struct listen_data *, int, struct sockaddr_in *); +static void handle_connection(struct listen_data *, int, struct sockaddr_in *); static void dead_child(int); /* @@ -117,7 +117,6 @@ fd_set read_fds; socklen_t addr_len; struct sockaddr_in client_addr; - bool quit; /* * fork: @@ -189,10 +188,8 @@ { /* child */ close(listen_sock); - quit = handle_connection(listen_data, accept_sock, &client_addr); + handle_connection(listen_data, accept_sock, &client_addr); close(accept_sock); -/* TODO */ -if(quit) printf("TODO: QUIT\n"); /* use _exit in child so stdio etc don't clean up twice */ _exit(EXIT_SUCCESS); } @@ -213,31 +210,44 @@ * handle a connection from a remote rb-browser */ -static bool +static void handle_connection(struct listen_data *listen_data, int client_sock, struct sockaddr_in *client_addr) { + FILE *client; char cmd[1024]; - ssize_t nread; - bool quit = false; + size_t len; + bool quit; 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) + if((client = fdopen(client_sock, "r+")) == NULL) + return; + + /* read commands from the client */ + quit = false; + while(!feof(client) && !quit) { - /* \0 terminate the buffer */ - cmd[nread] = '\0'; - /* strip off any trailing \n */ - nread --; - while(nread > 0 && (cmd[nread] == '\n' || cmd[nread] == '\r')) - cmd[nread--] = '\0'; - /* process the command */ - quit = process_command(listen_data, client_sock, cmd); + if(fgets(cmd, sizeof(cmd), client) == NULL) + { + quit = true; + } + else + { + /* strip off any trailing \n */ + len = strlen(cmd); + len = (len > 0) ? len -1 : len; + while(len > 0 && (cmd[len] == '\n' || cmd[len] == '\r')) + cmd[len--] = '\0'; + /* process the command */ + quit = process_command(listen_data, client, cmd); + } } + fclose(client); + printf("Connection from %s:%d closed\n", inet_ntoa(client_addr->sin_addr), ntohs(client_addr->sin_port)); - return quit; + return; } static void Modified: redbutton-download/trunk/stream.c =================================================================== --- redbutton-download/trunk/stream.c 2006-03-25 10:43:15 UTC (rev 26) +++ redbutton-download/trunk/stream.c 2006-03-25 14:19:43 UTC (rev 27) @@ -44,20 +44,20 @@ static unsigned char _ts_buf[8 * 1024]; void -stream_ts(int ts_fd, int client_sock) +stream_ts(int ts_fd, FILE *client) { ssize_t nread; - ssize_t nwritten; + size_t nwritten; do { nread = read(ts_fd, _ts_buf, sizeof(_ts_buf)); if(nread > 0) - nwritten = write(client_sock, _ts_buf, nread); + nwritten = fwrite(_ts_buf, 1, nread, client); else nwritten = nread; } - while(nread == nwritten); + while(!feof(client) && nread == nwritten); return; } Modified: redbutton-download/trunk/stream.h =================================================================== --- redbutton-download/trunk/stream.h 2006-03-25 10:43:15 UTC (rev 26) +++ redbutton-download/trunk/stream.h 2006-03-25 14:19:43 UTC (rev 27) @@ -5,11 +5,12 @@ #ifndef __STREAM_H__ #define __STREAM_H__ +#include <stdio.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); +void stream_ts(int, FILE *); #endif /* __STREAM_H__ */ Modified: redbutton-download/trunk/utils.c =================================================================== --- redbutton-download/trunk/utils.c 2006-03-25 10:43:15 UTC (rev 26) +++ redbutton-download/trunk/utils.c 2006-03-25 14:19:43 UTC (rev 27) @@ -31,46 +31,6 @@ #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) */ Modified: redbutton-download/trunk/utils.h =================================================================== --- redbutton-download/trunk/utils.h 2006-03-25 10:43:15 UTC (rev 26) +++ redbutton-download/trunk/utils.h 2006-03-25 14:19:43 UTC (rev 27) @@ -37,9 +37,6 @@ /* 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); - 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. |