diff options
Diffstat (limited to 'src/input/mms.c')
-rw-r--r-- | src/input/mms.c | 180 |
1 files changed, 136 insertions, 44 deletions
diff --git a/src/input/mms.c b/src/input/mms.c index 3605e5cea..f62430971 100644 --- a/src/input/mms.c +++ b/src/input/mms.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: mms.c,v 1.11 2002/10/02 15:54:51 mroi Exp $ + * $Id: mms.c,v 1.12 2002/10/26 22:50:52 guenter Exp $ * * based on work from major mms * utility functions to handle communication with an mms server @@ -41,6 +41,7 @@ #include <stdlib.h> #include <time.h> +#include "xine_internal.h" #include "xineutils.h" #include "bswap.h" @@ -78,7 +79,7 @@ struct mms_s { char str[1024]; /* scratch buffer to built strings */ /* receive buffer */ - char buf[BUF_SIZE]; + uint8_t buf[BUF_SIZE]; int buf_size; int buf_read; @@ -95,6 +96,39 @@ struct mms_s { /* network/socket utility functions */ +static ssize_t read_timeout(int fd, void *buf, size_t count) { + + ssize_t ret, total; + int timeout; + + timeout = 30; total = 0; + + while (total < count) { + + while ( ((ret=read (fd, buf+total, count-total)) < 0) + && ( (errno == EINPROGRESS) || (errno == EAGAIN)) + && (timeout>0)) { + + sleep (1); +#ifdef LOG + printf ("mms: read in progress...%d, %d/%d\n", errno, total, count); +#endif + timeout--; + } + + if (ret<0) + return ret; + else + total += ret; + } + +#ifdef LOG + printf ("mms: read completed %d/%d\n", total, count); +#endif + + return total; +} + static int host_connect_attempt(struct in_addr ia, int port) { int s; @@ -106,6 +140,10 @@ static int host_connect_attempt(struct in_addr ia, int port) { return -1; } + /* put socket in non-blocking mode */ + + fcntl (s, F_SETFL, fcntl (s, F_GETFL) | O_NONBLOCK); + sin.sin_family = AF_INET; sin.sin_addr = ia; sin.sin_port = htons(port); @@ -157,17 +195,26 @@ static void put_32 (mms_t *this, uint32_t value) { } static int send_data (int s, char *buf, int len) { - int total; + int total, timeout; - total = 0; + total = 0; timeout = 30; while (total < len){ int n; n = write (s, &buf[total], len - total); + +#ifdef LOG + printf ("mms: sending data, %d of %d\n", n, len); +#endif + if (n > 0) total += n; - else if (n < 0 && errno != EAGAIN) - return total; + else if (n < 0) { + if ((timeout>0) && ((errno == EAGAIN) || (errno == EINPROGRESS))) { + sleep (1); timeout--; + } else + return -1; + } } return total; } @@ -300,19 +347,33 @@ static void print_answer (char *data, int len) { } -static void get_answer (mms_t *this) { +static int get_answer (mms_t *this) { int command = 0x1b; while (command == 0x1b) { - int len; + int len, length; - len = read (this->s, this->buf, BUF_SIZE) ; - if (!len) { + len = read_timeout (this->s, this->buf, 12); + if (len != 12) { printf ("\nalert! eof\n"); - return; + return 0; + } + + length = get_32 (this->buf, 8); + +#ifdef LOG + printf ("\n\npacket length: %d\n", length); +#endif + + len = read_timeout (this->s, this->buf+12, length+4) ; + if (len<=0) { + printf ("alert! eof\n"); + return 0; } + len += 12; + print_answer (this->buf, len); command = get_32 (this->buf, 36) & 0xFFFF; @@ -321,34 +382,20 @@ static void get_answer (mms_t *this) { send_command (this, 0x1b, 0, 0, 0); } + return 1; } static int receive (int s, char *buf, size_t count) { - ssize_t len, total; - - total = 0; - - while (total < count) { - len = read (s, &buf[total], count-total); - if (len < 0) { - perror ("read error:"); - return 0; - } - - total += len; - -#ifdef LOG - if (len != 0) { - printf ("[%d/%d]", total, count); - fflush (stdout); - } -#endif + ssize_t len; + len = read_timeout (s, buf, count); + if (len < 0) { + perror ("read error:"); + return 0; } - return 1; - + return len; } static void get_header (mms_t *this) { @@ -616,7 +663,22 @@ void mms_gen_guid(char guid[]) { guid[36] = '\0'; } -mms_t *mms_connect (const char *url_) { +static void report_progress (xine_stream_t *stream, int p) { + + xine_event_t event; + xine_progress_data_t prg; + + prg.description = _("Connecting MMS server..."); + prg.percent = p; + + event.type = XINE_EVENT_PROGRESS; + event.data = &prg; + event.data_length = sizeof (xine_progress_data_t); + + xine_event_send (stream, &event); +} + +mms_t *mms_connect (xine_stream_t *stream, const char *url_) { mms_t *this; char *url = NULL; char *url1 = NULL; @@ -629,6 +691,8 @@ mms_t *mms_connect (const char *url_) { if(!url_) return NULL; + report_progress (stream, 0); + url = strdup (url_); port = MMS_PORT; url1 = mms_connect_common(&s, &port, url, &host, &path, &file); @@ -638,6 +702,8 @@ mms_t *mms_connect (const char *url_) { return NULL; } + report_progress (stream, 10); + this = (mms_t*) malloc (sizeof (mms_t)); this->url = url; @@ -670,11 +736,16 @@ mms_t *mms_connect (const char *url_) { send_command (this, 1, 0, 0x0004000b, strlen(this->str) * 2 + 8); printf("libmms: before read \n"); - len = read (this->s, this->buf, BUF_SIZE) ; - if (len > 0) - print_answer (this->buf, len); - else + + if (!get_answer (this)) { printf ("libmms: read failed: %s\n", strerror(errno)); + close (this->s); + free (url); + free (this); + return NULL; + } + + report_progress (stream, 20); /* cmd2 */ @@ -682,9 +753,15 @@ mms_t *mms_connect (const char *url_) { memset (this->scmd_body, 0, 8); send_command (this, 2, 0, 0, 28 * 2 + 8); - len = read (this->s, this->buf, BUF_SIZE) ; - if (len) - print_answer (this->buf, len); + if (!get_answer (this)) { + printf ("libmms: read failed: %s\n", strerror(errno)); + close (this->s); + free (url); + free (this); + return NULL; + } + + report_progress (stream, 30); /* 0x5 */ @@ -694,20 +771,25 @@ mms_t *mms_connect (const char *url_) { get_answer (this); - /* 0x15 */ + report_progress (stream, 40); + /* 0x15 */ memset (this->scmd_body, 0, 40); this->scmd_body[32] = 2; send_command (this, 0x15, 1, 0, 40); + get_answer (this); + this->num_stream_ids = 0; get_header (this); interp_header (this); + report_progress (stream, 50); + /* 0x33 */ memset (this->scmd_body, 0, 40); @@ -725,6 +807,8 @@ mms_t *mms_connect (const char *url_) { get_answer (this); + report_progress (stream, 75); + /* 0x07 */ @@ -738,7 +822,12 @@ mms_t *mms_connect (const char *url_) { send_command (this, 0x07, 1, 0xFFFF | this->stream_ids[0] << 16, 24); + + report_progress (stream, 100); + +#ifdef LOG printf(" mms_connect: passed\n" ); +#endif return this; } @@ -752,9 +841,12 @@ static int get_media_packet (mms_t *this) { } #ifdef LOG - for (i = 0; i < 8; i++) - printf ("pre_header[%d] = %02x (%d)\n", - i, pre_header[i], pre_header[i]); + { + int i; + for (i = 0; i < 8; i++) + printf ("pre_header[%d] = %02x (%d)\n", + i, pre_header[i], pre_header[i]); + } #endif if (pre_header[4] == 0x04) { |