#include #include #include #include #include #include "config.h" #include "url.h" #include "http.h" #include "asf.h" #include "stream.h" #include "network.h" int data_length = 0; int packet_length1; int media_padding; int to_skip = 0; #ifdef __CYGWIN__ typedef unsigned char uint8_t; typedef unsigned int uint32_t; typedef unsigned long long int uint64_t; #else #include #endif #define BUF_SIZE 102400 int checknum =1; typedef struct { uint8_t buf[BUF_SIZE]; int num_bytes; } command_t; int seq_num; int num_stream_ids; int stream_ids[20]; int output_fh; int store_data(int s, int size, char *buffer) { // printf("data_length %d, media_padding %d, size %d \n", data_length, media_padding, size ); if(data_length >= size) { if (!get_data (s, buffer, size)) { printf ("media data read failed\n"); return 0; } data_length -= size; return size; } else { int temp_size, media_temp_padding; if(data_length) { if (!get_data (s, buffer, data_length)) { printf ("media data read failed\n"); return 0; } } if(media_padding) { if(media_padding > size - data_length) { memset(buffer+data_length,0,(size - data_length)); media_padding -= (size - data_length); data_length = 0; return size; } else { memset(buffer+data_length,0,media_padding); media_temp_padding = media_padding; media_padding = 0; temp_size =data_length; data_length = 0; return (temp_size + media_temp_padding); } } temp_size = data_length; data_length = 0; return temp_size; } } static void put_32 (command_t *cmd, uint32_t value) { cmd->buf[cmd->num_bytes ] = value % 256; value = value >> 8; cmd->buf[cmd->num_bytes+1] = value % 256 ; value = value >> 8; cmd->buf[cmd->num_bytes+2] = value % 256 ; value = value >> 8; cmd->buf[cmd->num_bytes+3] = value % 256 ; cmd->num_bytes += 4; } static uint32_t get_32 (unsigned char *cmd, int offset) { uint32_t ret; ret = cmd[offset] ; ret |= cmd[offset+1]<<8 ; ret |= cmd[offset+2]<<16 ; ret |= cmd[offset+3]<<24 ; return ret; } static void send_command (int s, int command, uint32_t switches, uint32_t extra, int length, char *data) { command_t cmd; int len8; int i; len8 = (length + (length%8)) / 8; cmd.num_bytes = 0; put_32 (&cmd, 0x00000001); /* start sequence */ put_32 (&cmd, 0xB00BFACE); /* #-)) */ put_32 (&cmd, length + 32); put_32 (&cmd, 0x20534d4d); /* protocol type "MMS " */ put_32 (&cmd, len8 + 4); put_32 (&cmd, seq_num); seq_num++; put_32 (&cmd, 0x0); /* unknown */ put_32 (&cmd, 0x0); put_32 (&cmd, len8+2); put_32 (&cmd, 0x00030000 | command); /* dir | command */ put_32 (&cmd, switches); put_32 (&cmd, extra); memcpy (&cmd.buf[48], data, length); if (write (s, cmd.buf, length+48) != (length+48)) { printf ("write error\n"); } /* printf ("\n***************************************************\ncommand sent, %d bytes\n", length+48); printf ("start sequence %08x\n", get_32 (cmd.buf, 0)); printf ("command id %08x\n", get_32 (cmd.buf, 4)); printf ("length %8x \n", get_32 (cmd.buf, 8)); printf ("len8 %8x \n", get_32 (cmd.buf, 16)); printf ("sequence # %08x\n", get_32 (cmd.buf, 20)); printf ("len8 (II) %8x \n", get_32 (cmd.buf, 32)); printf ("dir | comm %08x\n", get_32 (cmd.buf, 36)); printf ("switches %08x\n", get_32 (cmd.buf, 40)); printf ("ascii contents>"); for (i=48; i<(length+48); i+=2) { unsigned char c = cmd.buf[i]; if ((c>=32) && (c<=128)) printf ("%c", c); else printf ("."); } printf ("\n"); printf ("complete hexdump of package follows:\n"); for (i=0; i<(length+48); i++) { unsigned char c = cmd.buf[i]; printf ("%02x", c); if ((i % 16) == 15) printf ("\n"); if ((i % 2) == 1) printf (" "); } printf ("\n"); */ } static void string_utf16(char *dest, char *src, int len) { int i; memset (dest, 0, 1000); for (i=0; i=32) && (c<128)) printf ("%c", c); else printf (" %02x ", c); } printf ("\n"); */ } static void get_answer (int s) { char data[BUF_SIZE]; int command = 0x1b; while (command == 0x1b) { int len; len = read (s, data, BUF_SIZE) ; if (!len) { printf ("\nalert! eof\n"); return; } print_answer (data, len); command = get_32 (data, 36) & 0xFFFF; if (command == 0x1b) send_command (s, 0x1b, 0, 0, 0, data); } } static int get_data (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; if (len != 0) { // printf ("[%d/%d]", total, count); fflush (stdout); } } return 1; } static int get_header (int s, uint8_t *header, streaming_ctrl_t *streaming_ctrl) { unsigned char pre_header[8]; int i, header_len; header_len = 0; while (1) { if (!get_data (s, pre_header, 8)) { printf ("pre-header read failed\n"); return 0; } // printf("stage 1\n"); // for (i=0; i<8; i++) // printf ("pre_header[%d] = %02x (%d)\n", // i, pre_header[i], pre_header[i]); if (pre_header[4] == 0x02) { int packet_len; packet_len = (pre_header[7] << 8 | pre_header[6]) - 8; // printf ("asf header packet detected, len=%d\n", packet_len); if (!get_data (s, &header[header_len], packet_len)) { printf ("header data read failed\n"); return 0; } header_len += packet_len; if ( (header[header_len-1] == 1) && (header[header_len-2]==1)) { if( streaming_bufferize( streaming_ctrl, header, header_len )<0 ) { return -1; } // strncpy(stream->buffer,stream->streaming_ctrl->buffer,header_len); // stream->buf_len=header_len; // write (output_fh, header, header_len); // printf ("get header packet finished\n"); return (header_len); } } else { int packet_len, command; char data[BUF_SIZE]; if (!get_data (s, &packet_len, 4)) { printf ("packet_len read failed\n"); return 0; } packet_len = get_32 (&packet_len, 0) + 4; // printf ("command packet detected, len=%d\n", // packet_len); if (!get_data (s, data, packet_len)) { printf ("command data read failed\n"); return 0; } command = get_32 (data, 24) & 0xFFFF; // printf ("command: %02x\n", command); if (command == 0x1b) send_command (s, 0x1b, 0, 0, 0, data); } // printf ("get header packet succ\n"); } } int interp_header (uint8_t *header, int header_len) { int i; int packet_length; /* * parse header */ i = 30; while (istreaming_ctrl->url->protocol, 10 ); if( !strncasecmp( proto_s, "mms", 3) && strncasecmp( proto_s, "mmst", 4) ) { printf("Trying ASF/UDP...\n"); //fd = asf_mmsu_streaming_start( stream ); if( fd!=-1 ) return fd; printf(" ===> ASF/UDP failed\n"); } if( !strncasecmp( proto_s, "mms", 3) ) { printf("Trying ASF/TCP...\n"); fd = asf_mmst_streaming_start( stream ); if( fd!=-1 ) return fd; printf(" ===> ASF/TCP failed\n"); } if( !strncasecmp( proto_s, "http", 4) || // !strncasecmp( proto_s, "mms", 3) || !strncasecmp( proto_s, "http_proxy", 10) ) { printf("Trying ASF/HTTP...\n"); fd = asf_http_streaming_start( stream ); if( fd!=-1 ) return fd; printf(" ===> ASF/HTTP failed\n"); } printf("Unknown protocol: %s\n", proto_s ); return -1; } int asf_streaming(ASF_stream_chunck_t *stream_chunck, int *drop_packet ) { /* printf("ASF stream chunck size=%d\n", stream_chunck->size); printf("length: %d\n", length ); printf("0x%02X\n", stream_chunck->type ); */ if( drop_packet!=NULL ) *drop_packet = 0; if( stream_chunck->size<8 ) { printf("Ahhhh, stream_chunck size is too small: %d\n", stream_chunck->size); return -1; } if( stream_chunck->size!=stream_chunck->size_confirm ) { printf("size_confirm mismatch!: %d %d\n", stream_chunck->size, stream_chunck->size_confirm); return -1; } /* printf(" type: 0x%02X\n", stream_chunck->type ); printf(" size: %d (0x%02X)\n", stream_chunck->size, stream_chunck->size ); printf(" sequence_number: 0x%04X\n", stream_chunck->sequence_number ); printf(" unknown: 0x%02X\n", stream_chunck->unknown ); printf(" size_confirm: 0x%02X\n", stream_chunck->size_confirm ); */ switch(stream_chunck->type) { case 0x4324: // $C Clear ASF configuration printf("=====> Clearing ASF stream configuration!\n"); if( drop_packet!=NULL ) *drop_packet = 1; return stream_chunck->size; break; case 0x4424: // $D Data follows // printf("=====> Data follows\n"); break; case 0x4524: // $E Transfer complete printf("=====> Transfer complete\n"); if( drop_packet!=NULL ) *drop_packet = 1; return stream_chunck->size; break; case 0x4824: // $H ASF header chunk follows printf("=====> ASF header chunk follows\n"); break; default: printf("=====> Unknown stream type 0x%x\n", stream_chunck->type ); } return stream_chunck->size+4; } static int asf_streaming_parse_header(int fd, streaming_ctrl_t* streaming_ctrl) { ASF_header_t asfh; ASF_obj_header_t objh; ASF_file_header_t fileh; ASF_stream_header_t streamh; ASF_stream_chunck_t chunk; asf_http_streaming_ctrl_t* asf_ctrl = (asf_http_streaming_ctrl_t*) streaming_ctrl->data; char* buffer=NULL, *chunk_buffer=NULL; int i,r,size,pos = 0; int buffer_size = 0; int chunk_size2read = 0; if(asf_ctrl == NULL) return -1; // The ASF header can be in several network chunks. For example if the content description // is big, the ASF header will be split in 2 network chunk. // So we need to retrieve all the chunk before starting to parse the header. do { for( r=0; r < sizeof(ASF_stream_chunck_t) ; ) { i = nop_streaming_read(fd,((char*)&chunk)+r,sizeof(ASF_stream_chunck_t) - r,streaming_ctrl); if(i <= 0) return -1; r += i; } size = asf_streaming( &chunk, &r) - sizeof(ASF_stream_chunck_t); if(r) printf("Warning : drop header ????\n"); if(size < 0){ printf("Error while parsing chunk header\n"); return -1; } if (chunk.type != 0x4824) { printf("Don't got a header as first chunk !!!!\n"); return -1; } buffer = (char*) malloc(size+buffer_size); if(buffer == NULL) { printf("Error can't allocate %d bytes buffer\n",size+buffer_size); return -1; } if( chunk_buffer!=NULL ) { memcpy( buffer, chunk_buffer, buffer_size ); free( chunk_buffer ); } chunk_buffer = buffer; buffer += buffer_size; buffer_size += size; for(r = 0; r < size;) { i = nop_streaming_read(fd,buffer+r,size-r,streaming_ctrl); if(i < 0) { printf("Error while reading network stream\n"); return -1; } r += i; } if( chunk_size2read==0 ) { if(size < (int)sizeof(asfh)) { printf("Error chunk is too small\n"); return -1; } else printf("Got chunk\n"); memcpy(&asfh,buffer,sizeof(asfh)); le2me_ASF_header_t(&asfh); chunk_size2read = asfh.objh.size; printf("Size 2 read=%d\n", chunk_size2read); } } while( buffer_size 256) { printf("Error sub chunks number is invalid\n"); return -1; } pos += sizeof(asfh); while(size - pos >= (int)sizeof(objh)) { memcpy(&objh,buffer+pos,sizeof(objh)); le2me_ASF_obj_header_t(&objh); switch(ASF_LOAD_GUID_PREFIX(objh.guid)) { case 0x8CABDCA1 : // File header pos += sizeof(objh); memcpy(&fileh,buffer + pos,sizeof(fileh)); le2me_ASF_file_header_t(&fileh); /* if(fileh.packetsize != fileh.packetsize2) { printf("Error packetsize check don't match\n"); return -1; } */ asf_ctrl->packet_size = fileh.max_packet_size; // before playing. // preroll: time in ms to bufferize before playing streaming_ctrl->prebuffer_size = (unsigned int)((double)((double)fileh.preroll/1000)*((double)fileh.max_bitrate/8)); pos += sizeof(fileh); break; case 0xB7DC0791 : // stream header pos += sizeof(objh); memcpy(&streamh,buffer + pos,sizeof(streamh)); le2me_ASF_stream_header_t(&streamh); pos += sizeof(streamh) + streamh.type_size; switch(ASF_LOAD_GUID_PREFIX(streamh.type)) { case 0xF8699E40 : // audio stream if(asf_ctrl->audio_streams == NULL){ asf_ctrl->audio_streams = (int*)malloc(sizeof(int)); asf_ctrl->n_audio = 1; } else { asf_ctrl->n_audio++; asf_ctrl->audio_streams = (int*)realloc(asf_ctrl->audio_streams, asf_ctrl->n_audio*sizeof(int)); } asf_ctrl->audio_streams[asf_ctrl->n_audio-1] = streamh.stream_no; pos += streamh.stream_size; break; case 0xBC19EFC0 : // video stream if(asf_ctrl->video_streams == NULL){ asf_ctrl->video_streams = (int*)malloc(sizeof(int)); asf_ctrl->n_video = 1; } else { asf_ctrl->n_video++; asf_ctrl->video_streams = (int*)realloc(asf_ctrl->video_streams, asf_ctrl->n_video*sizeof(int)); } asf_ctrl->video_streams[asf_ctrl->n_video-1] = streamh.stream_no; break; } break; default : pos += objh.size; break; } } free(buffer); return 1; } int asf_mmst_streaming_read( int fd, char *buffer, int size, streaming_ctrl_t *stream_ctrl ) { uint8_t asf_header[8192]; int asf_header_len, packet_length; int len = 0; if( stream_ctrl->buffer_size!=0 ) { int buffer_len = stream_ctrl->buffer_size-stream_ctrl->buffer_pos; len = (sizebuffer)+(stream_ctrl->buffer_pos), len ); stream_ctrl->buffer_pos += len; if( stream_ctrl->buffer_pos>=stream_ctrl->buffer_size ) { free( stream_ctrl->buffer ); stream_ctrl->buffer = NULL; stream_ctrl->buffer_size = 0; stream_ctrl->buffer_pos = 0; } } if( lendata; while(1) { if (rest == 0 && waiting == 0) { read = 0; while(read < (int)sizeof(ASF_stream_chunck_t)){ int r = nop_streaming_read( fd, ((char*)&chunk) + read, sizeof(ASF_stream_chunck_t)-read, streaming_ctrl ); if(r <= 0){ if( r < 0) printf("Error while reading chunk header\n"); return -1; } read += r; } chunk_size = asf_streaming( &chunk, &drop_chunk ); if(chunk_size < 0) { printf("Error while parsing chunk header\n"); return -1; } chunk_size -= sizeof(ASF_stream_chunck_t); if(chunk.type != 0x4824 && (!drop_chunk)) { if (asf_http_ctrl->packet_size < chunk_size) { printf("Error chunk_size > packet_size\n"); return -1; } waiting = asf_http_ctrl->packet_size; } else { waiting = chunk_size; } } else if (rest){ chunk_size = rest; rest = 0; } read = 0; if ( waiting >= chunk_size) { if (chunk_size > size){ rest = chunk_size - size; chunk_size = size; } while(read < chunk_size) { int got = nop_streaming_read( fd,buffer+read,chunk_size-read,streaming_ctrl ); if(got <= 0) { if(got < 0) printf("Error while reading chunk\n"); return -1; } read += got; } waiting -= read; if (drop_chunk) continue; } if (rest == 0 && waiting > 0 && size-read > 0) { int s = MIN(waiting,size-read); memset(buffer+read,0,s); waiting -= s; read += s; } break; } return read; } int asf_http_streaming_seek( int fd, off_t pos, streaming_ctrl_t *streaming_ctrl ) { return -1; } int asf_header_check( HTTP_header_t *http_hdr ) { ASF_obj_header_t *objh; if( http_hdr==NULL ) return -1; if( http_hdr->body==NULL || http_hdr->body_sizebody; if( ASF_LOAD_GUID_PREFIX(objh->guid)==0x75B22630 ) return 0; return -1; } int asf_http_streaming_type(char *content_type, char *features, HTTP_header_t *http_hdr ) { if( content_type==NULL ) return ASF_Unknown_e; if( !strcasecmp(content_type, "application/octet-stream") ) { if( features==NULL ) { printf("=====> ASF Prerecorded\n"); return ASF_Prerecorded_e; } else if( strstr(features, "broadcast")) { printf("=====> ASF Live stream\n"); return ASF_Live_e; } else { printf("=====> ASF Prerecorded\n"); return ASF_Prerecorded_e; } } else { // Ok in a perfect world, web servers should be well configured // so we could used mime type to know the stream type, // but guess what? All of them are not well configured. // So we have to check for an asf header :(, but it works :p if( http_hdr->body_size>sizeof(ASF_obj_header_t) ) { if( asf_header_check( http_hdr )==0 ) { printf("=====> ASF Plain text\n"); return ASF_PlainText_e; } else { printf("=====> ASF Redirector\n"); return ASF_Redirector_e; } } else { if( (!strcasecmp(content_type, "audio/x-ms-wax")) || (!strcasecmp(content_type, "audio/x-ms-wma")) || (!strcasecmp(content_type, "video/x-ms-asf")) || (!strcasecmp(content_type, "video/x-ms-afs")) || (!strcasecmp(content_type, "video/x-ms-wvx")) || (!strcasecmp(content_type, "video/x-ms-wmv")) || (!strcasecmp(content_type, "video/x-ms-wma")) ) { printf("=====> ASF Redirector\n"); return ASF_Redirector_e; } else if( !strcasecmp(content_type, "text/plain") ) { printf("=====> ASF Plain text\n"); return ASF_PlainText_e; } else { printf("=====> ASF unknown content-type: %s\n", content_type ); return ASF_Unknown_e; } } } return ASF_Unknown_e; } HTTP_header_t * asf_http_request(streaming_ctrl_t *streaming_ctrl) { HTTP_header_t *http_hdr; URL_t *url = NULL; URL_t *server_url = NULL; asf_http_streaming_ctrl_t *asf_http_ctrl; char str[250]; char *ptr; int i,as = -1,vs = -1; int offset_hi=0, offset_lo=0, length=0; int asf_nb_stream=0; // Sanity check if( streaming_ctrl==NULL ) return NULL; url = streaming_ctrl->url; asf_http_ctrl = (asf_http_streaming_ctrl_t*)streaming_ctrl->data; if( url==NULL || asf_http_ctrl==NULL ) return NULL; // Common header for all requests. http_hdr = http_new_header(); http_set_field( http_hdr, "Accept: */*" ); http_set_field( http_hdr, "User-Agent: NSPlayer/4.1.0.3856" ); // Check if we are using a proxy if( !strcasecmp( url->protocol, "http_proxy" ) ) { server_url = url_new( (url->file)+1 ); if( server_url==NULL ) { printf("Invalid proxy URL\n"); http_free( http_hdr ); return NULL; } http_set_uri( http_hdr, server_url->url ); sprintf( str, "Host: %s:%d", server_url->hostname, server_url->port ); url_free( server_url ); } else { http_set_uri( http_hdr, url->file ); sprintf( str, "Host: %s:%d", url->hostname, url->port ); } http_set_field( http_hdr, str ); http_set_field( http_hdr, "Pragma: xClientGUID={c77e7400-738a-11d2-9add-0020af0a3278}" ); sprintf(str, "Pragma: no-cache,rate=1.000000,stream-time=0,stream-offset=%u:%u,request-context=%d,max-duration=%u", offset_hi, offset_lo, asf_http_ctrl->request, length ); http_set_field( http_hdr, str ); switch( asf_http_ctrl->streaming_type ) { case ASF_Live_e: case ASF_Prerecorded_e: http_set_field( http_hdr, "Pragma: xPlayStrm=1" ); ptr = str; ptr += sprintf( ptr, "Pragma: stream-switch-entry="); if(asf_http_ctrl->n_audio > 0) { if(audio_id > 0) { for( i=0; in_audio ; i++ ) { if(asf_http_ctrl->audio_streams[i] == audio_id) { as = audio_id; break; } } } if(as < 0) { if(audio_id > 0) printf("Audio stream %d don't exist\n", as); as = asf_http_ctrl->audio_streams[0]; } ptr += sprintf(ptr, " ffff:%d:0",as); asf_nb_stream++; } if(asf_http_ctrl->n_video > 0) { if(video_id > 0) { for( i=0; in_video ; i++ ) { if(asf_http_ctrl->video_streams[i] == video_id) { vs = video_id; break; } } } if(vs < 0) { if(video_id > 0) printf("Video stream %d don't exist\n",vs); vs = asf_http_ctrl->video_streams[0]; } ptr += sprintf( ptr, " ffff:%d:0",vs); asf_nb_stream++; } http_set_field( http_hdr, str ); sprintf( str, "Pragma: stream-switch-count=%d", asf_nb_stream ); http_set_field( http_hdr, str ); break; case ASF_Redirector_e: break; case ASF_Unknown_e: // First request goes here. break; default: printf("Unknown asf stream type\n"); } http_set_field( http_hdr, "Connection: Close" ); http_build_request( http_hdr ); return http_hdr; } int asf_http_parse_response( HTTP_header_t *http_hdr ) { char *content_type, *pragma; char features[64] = "\0"; int len; if( http_response_parse(http_hdr)<0 ) { printf("Failed to parse HTTP response\n"); return -1; } if( http_hdr->status_code!=200 ) { printf("Server return %d:%s\n", http_hdr->status_code, http_hdr->reason_phrase); return -1; } content_type = http_get_field( http_hdr, "Content-Type"); //printf("Content-Type: [%s]\n", content_type); pragma = http_get_field( http_hdr, "Pragma"); while( pragma!=NULL ) { char *comma_ptr=NULL; char *end; //printf("Pragma: [%s]\n", pragma ); // The pragma line can get severals attributes // separeted with a comma ','. do { if( !strncasecmp( pragma, "features=", 9) ) { pragma += 9; end = strstr( pragma, "," ); if( end==NULL ) { int s = strlen(pragma); if(s > sizeof(features)) { // printf("ASF HTTP PARSE WARNING : Pragma %s cuted from %d bytes to %d\n",pragma,s,sizeof(features)); len = sizeof(features); } else { len = s; } } else { len = MIN(end-pragma,sizeof(features)); } strncpy( features, pragma, len ); features[len]='\0'; break; } comma_ptr = strstr( pragma, "," ); if( comma_ptr!=NULL ) { pragma = comma_ptr+1; if( pragma[0]==' ' ) pragma++; } } while( comma_ptr!=NULL ); pragma = http_get_next_field( http_hdr ); } return asf_http_streaming_type( content_type, features, http_hdr ); } int asf_mmst_streaming_start(stream_t *stream) { struct sockaddr_in sa; struct hostent *hp; char str[1024]; char data[1024]; uint8_t asf_header[8192]; int asf_header_len; int len, i, packet_length; char host[256]; char *path, *url, *file, *cp; URL_t *url1 = stream->streaming_ctrl->url; int s = stream->fd; /* parse url */ // if( !strcasecmp( url1->protocol, "http_proxy" ) ) { // if( url1->port==0 ) url1->port = 8080; // } else { // if( url1->port==0 ) url1->port = 1755; // } // printf("url1->hostname %s, url1->port %d \n",url1->hostname, url1->port); // printf ("host : >%s<\n", host); // path = strchr(&url[6], '/') +1; path = strchr(url1->file,'/') + 1; // printf ("path : >%s<\n", path); url1->port=1755; s = connect2Server( url1->hostname, url1->port ); printf ("connected\n"); /* cmd1 */ sprintf (str, "\034\003NSPlayer/7.0.0.1956; {33715801-BAB3-9D85-24E9-03B90328270A}; Host: %s", host); string_utf16 (data, str, strlen(str)+2); send_command (s, 1, 0, 0x0004000b, strlen(str) * 2+8, data); len = read (s, data, BUF_SIZE) ; if (len) print_answer (data, len); /* cmd2 */ string_utf16 (&data[8], "\002\000\\\\192.168.0.129\\TCP\\1037\0000", 28); memset (data, 0, 8); send_command (s, 2, 0, 0, 28*2+8, data); len = read (s, data, BUF_SIZE) ; if (len) print_answer (data, len); /* 0x5 */ string_utf16 (&data[8], path, strlen(path)); memset (data, 0, 8); send_command (s, 5, 0, 0, strlen(path)*2+12, data); get_answer (s); /* 0x15 */ memset (data, 0, 40); data[32] = 2; send_command (s, 0x15, 1, 0, 40, data); num_stream_ids = 0; /* get_headers(s, asf_header); */ asf_header_len = get_header (s, asf_header, stream->streaming_ctrl); // printf("---------------------------------- asf_header %d\n",asf_header); packet_length = interp_header (asf_header, asf_header_len); /* 0x33 */ memset (data, 0, 40); for (i=1; ifd = s; stream->streaming_ctrl->streaming_read = asf_mmst_streaming_read; stream->streaming_ctrl->streaming_seek = asf_http_streaming_seek; stream->streaming_ctrl->buffering = 1; stream->streaming_ctrl->status = streaming_playing_e; // stream->streaming_ctrl->prebuffer_size = (unsigned int) 5000; stream->streaming_ctrl->buffering = 1; packet_length1 = packet_length; // printf("+++++++++++++++++ packet_length %d, packet_length1 %d", packet_length, packet_length1 ); return 0; } int asf_http_streaming_start( stream_t *stream ) { HTTP_header_t *http_hdr=NULL; URL_t *url_next=NULL; URL_t *url = stream->streaming_ctrl->url; asf_http_streaming_ctrl_t *asf_http_ctrl; ASF_StreamType_e streaming_type; char buffer[BUFFER_SIZE]; int i, ret; int fd = stream->fd; int done; asf_http_ctrl = (asf_http_streaming_ctrl_t*)malloc(sizeof(asf_http_streaming_ctrl_t)); if( asf_http_ctrl==NULL ) { printf("Memory allocation failed\n"); return -1; } asf_http_ctrl->streaming_type = ASF_Unknown_e; asf_http_ctrl->request = 1; asf_http_ctrl->audio_streams = asf_http_ctrl->video_streams = NULL; asf_http_ctrl->n_audio = asf_http_ctrl->n_video = 0; stream->streaming_ctrl->data = (void*)asf_http_ctrl; do { done = 1; if( fd>0 ) close( fd ); if( !strcasecmp( url->protocol, "http_proxy" ) ) { if( url->port==0 ) url->port = 8080; } else { if( url->port==0 ) url->port = 80; } printf("url->port %d \n",url->port); fd = connect2Server( url->hostname, url->port ); if( fd<0 ) return -1; http_hdr = asf_http_request( stream->streaming_ctrl ); if( verbose>0 ) { printf("Request [%s]\n", http_hdr->buffer ); } for(i=0; i < http_hdr->buffer_size ; ) { int r = write( fd, http_hdr->buffer+i, http_hdr->buffer_size-i ); if(r <0) { printf("Socket write error : %s\n",strerror(errno)); return -1; } i += r; } http_free( http_hdr ); http_hdr = http_new_header(); do { i = read( fd, buffer, BUFFER_SIZE ); //printf("read: %d\n", i ); if( i<0 ) { perror("read"); http_free( http_hdr ); return -1; } http_response_append( http_hdr, buffer, i ); } while( !http_is_header_entire( http_hdr ) ); if( verbose>0 ) { http_hdr->buffer[http_hdr->buffer_size]='\0'; printf("Response [%s]\n", http_hdr->buffer ); } streaming_type = asf_http_parse_response(http_hdr); if( streaming_type<0 ) { printf("Failed to parse header\n"); http_free( http_hdr ); return -1; } asf_http_ctrl->streaming_type = streaming_type; switch( streaming_type ) { case ASF_Live_e: case ASF_Prerecorded_e: case ASF_PlainText_e: if( http_hdr->body_size>0 ) { if( streaming_bufferize( stream->streaming_ctrl, http_hdr->body, http_hdr->body_size )<0 ) { http_free( http_hdr ); return -1; } } if( asf_http_ctrl->request==1 ) { if( streaming_type!=ASF_PlainText_e ) { // First request, we only got the ASF header. ret = asf_streaming_parse_header(fd,stream->streaming_ctrl); if(ret < 0) return -1; if(asf_http_ctrl->n_audio == 0 && asf_http_ctrl->n_video == 0) { printf("No stream found\n"); return -1; } asf_http_ctrl->request++; done = 0; } else { done = 1; } } break; case ASF_Redirector_e: if( http_hdr->body_size>0 ) { if( streaming_bufferize( stream->streaming_ctrl, http_hdr->body, http_hdr->body_size )<0 ) { http_free( http_hdr ); return -1; } } stream->type = STREAMTYPE_PLAYLIST; done = 1; break; case ASF_Unknown_e: default: printf("Unknown ASF streaming type\n"); close(fd); http_free( http_hdr ); return -1; } // Check if we got a redirect. } while(!done); stream->fd = fd; if( streaming_type==ASF_PlainText_e || streaming_type==ASF_Redirector_e ) { stream->streaming_ctrl->streaming_read = nop_streaming_read; stream->streaming_ctrl->streaming_seek = nop_streaming_seek; } else { stream->streaming_ctrl->streaming_read = asf_http_streaming_read; stream->streaming_ctrl->streaming_seek = asf_http_streaming_seek; stream->streaming_ctrl->buffering = 1; } stream->streaming_ctrl->status = streaming_playing_e; http_free( http_hdr ); return 0; }