예제 #1
0
/*
 * send SETUP requst. 2 setups for multiple streams.
 * return value ...     what rtsp_recv_header returned
 */
static int real_rtsp_setup(struct stream_t *stream,struct rmff_header_t *rmff_header)
{
    struct rtsp_ctrl_t *rtsp_ctrl = stream->stream_ctrl->rtsp_ctrl;
    struct rtsp_header_t *rtsp_hdr = NULL;
    char *buffer = (char *)xmalloc(BUFSIZE_1K);
    int ret = 0;
    char challenge2[64];
    char checksum[34];
    
    rtsp_hdr = new_rtsp_header_with_standard_fields(rtsp_ctrl);
    
    real_calc_challenge2_and_checksum(rtsp_ctrl->challenge,challenge2,checksum);
  
    snprintf(buffer,BUFSIZE_1K - 1,"RealChallenge2: %s, sd=%s",
	     challenge2,checksum);
    rtsp_set_field(rtsp_hdr,buffer);
    snprintf(buffer,BUFSIZE_1K - 1,"If-Match: %s",rtsp_ctrl->etag);
    rtsp_set_field(rtsp_hdr,buffer);
    rtsp_set_field(rtsp_hdr,"RDTFeatureLevel: 2");
    rtsp_set_field(rtsp_hdr,real_transport);
    snprintf(buffer,BUFSIZE_1K - 1,"%s/streamid=0",rtsp_ctrl->mrl);
    rtsp_request_setup(rtsp_hdr,buffer);
    rtsp_send_request_and_free(stream,rtsp_hdr);
    
    /* receive message for SETUP */
    ret = rtsp_recv_header_ignore_message(stream);
    
    
    /*
      send messages if multiple stream exists (max is 2 streams anyways...)
    */
    if(rmff_header->prop->num_streams > 1) {
	rtsp_hdr = new_rtsp_header_with_standard_fields(rtsp_ctrl);

	rtsp_set_field(rtsp_hdr,real_transport);
	snprintf(buffer,BUFSIZE_1K - 1,"If-Match: %s",rtsp_ctrl->etag);
	rtsp_set_field(rtsp_hdr,buffer);
	snprintf(buffer,BUFSIZE_1K - 1,"%s/streamid=1",rtsp_ctrl->mrl);
	rtsp_request_setup(rtsp_hdr,buffer);
    
	rtsp_send_request_and_free(stream,rtsp_hdr);
	
	/* receive message for SETUP */
	ret = rtsp_recv_header_ignore_message(stream);
    }
    
    free(buffer);
    return ret; 
}
예제 #2
0
/*
 * send OPTIONS request, this is used as very first trial to server
 * we will need rtsp_hdr later, so return that.
 * return value:   -1: failure   status_code: success, rtsp_hdr_ret(malloc)
 */
int real_rtsp_options(struct stream_t *stream,struct rtsp_header_t **rtsp_hdr_ret)
{
    int ret = 0;
    struct rtsp_ctrl_t *rtsp_ctrl = stream->stream_ctrl->rtsp_ctrl;
    struct rtsp_header_t *rtsp_hdr = NULL;
    char *options_uri = NULL;
    int options_uri_len = 0;

    /* default is rtsp-real (becasue OPTIONS req is supported) */
    rtsp_hdr = new_rtsp_header_with_standard_fields(rtsp_ctrl);
    
    rtsp_set_field(rtsp_hdr,real_useragent);
    rtsp_set_field(rtsp_hdr,"GUID: 00000000-0000-0000-0000-000000000000");
    rtsp_set_field(rtsp_hdr,real_clientid);  
    rtsp_set_field(rtsp_hdr,"Pragma: initiate-session");
    rtsp_set_field(rtsp_hdr,"RegionData: 0");
    rtsp_set_field(rtsp_hdr,real_clientchallenge);
    rtsp_set_field(rtsp_hdr,real_companyid);
    rtsp_set_field(rtsp_hdr,real_playerstarttime);
    
    
    options_uri_len = strlen(stream->serverinfo->host) + 20;
    options_uri = (char *)xmalloc(options_uri_len);
    snprintf(options_uri,options_uri_len,"rtsp://%s:%i",
	     stream->serverinfo->host,stream->serverinfo->port);
    
    rtsp_request_options(rtsp_hdr,options_uri);
    rtsp_send_request_and_free(stream,rtsp_hdr);
    
    rtsp_hdr = new_rtsp_header();
    ret = rtsp_recv_header(stream,rtsp_hdr);
    if(ret < 0) {
	goto failed;
    }

    *rtsp_hdr_ret = rtsp_hdr;
    
    if(options_uri) free(options_uri);
    return ret;

  failed:
    if(rtsp_hdr)    free_rtsp_header(rtsp_hdr);
    if(options_uri) free(options_uri);
    *rtsp_hdr_ret = NULL;
    return -1;
}
예제 #3
0
파일: rtsp.c 프로젝트: clkao/msdl
void rtsp_streaming_close(struct stream_t *stream)
{
    if(stream == NULL) return;
    
    /* TEARDOWN */
    if(stream->stream_ctrl->status == STREAMING_DOWNLOADING || 
       stream->stream_ctrl->status == STREAMING_FINISHED) {
	struct rtsp_header_t *rtsp_hdr;
	int ret;
	/* send teardown request to make server happier. */
	rtsp_hdr = new_rtsp_header_with_standard_fields(stream->stream_ctrl->rtsp_ctrl);
	rtsp_request_teardown(rtsp_hdr,stream->stream_ctrl->rtsp_ctrl->mrl);
	ret = rtsp_send_request_and_free(stream,rtsp_hdr);
    }
  
    if(stream->netsock->sock > 0) { /* valid socket --> close */
	close(stream->netsock->sock);
    }
    
    free_rtsp_ctrl_t(stream->stream_ctrl->rtsp_ctrl);
    streaming_close_common(stream);
}
예제 #4
0
/*
 * send SET_PARAMETER, with stream choosing subscribe.
 * return value ...     what rtsp_recv_header returned
 */
static int real_rtsp_set_parameter(struct stream_t *stream,char *subscribe)
{
    struct rtsp_ctrl_t *rtsp_ctrl = stream->stream_ctrl->rtsp_ctrl;
    struct rtsp_header_t *rtsp_hdr = NULL;
    int ret = 0;
    
    rtsp_hdr = new_rtsp_header_with_standard_fields(rtsp_ctrl);
    rtsp_set_field(rtsp_hdr,subscribe);
    if(stream->dlopts->bandwidth) { /* when user specified bandwidth */
	char *buffer = (char *)xmalloc(BUFSIZE_1K);
	snprintf(buffer,BUFSIZE_1K - 1,
		 "SetDeliveryBandwidth: Bandwidth=%d;BackOff=0",stream->dlopts->bandwidth);
	rtsp_set_field(rtsp_hdr,buffer);
	free(buffer);
    }
    
    rtsp_request_set_parameter(rtsp_hdr,rtsp_ctrl->mrl);
    rtsp_send_request_and_free(stream,rtsp_hdr);
    ret = rtsp_recv_header_ignore_message(stream);

    return ret;
}
예제 #5
0
/*
 * send PLAY request
 * return value ...     what rtsp_recv_header returned
 */
static int real_rtsp_play(struct stream_t *stream)
{
    struct rtsp_ctrl_t *rtsp_ctrl = stream->stream_ctrl->rtsp_ctrl;
    struct rtsp_header_t *rtsp_hdr = NULL;
 
    char *field = NULL;
    int ret = 0;
    
    /* 
     * Sending part 
     */
    rtsp_hdr = new_rtsp_header_with_standard_fields(rtsp_ctrl);

    if(stream->dlopts->resume_download) {
	real_prepare_resuming(stream);
    }

    if(stream->dlopts->bandwidth) { /* when user specified bandwidth */
	char *buffer = (char *)xmalloc(BUFSIZE_1K);
	snprintf(buffer,BUFSIZE_1K - 1,
		 "Bandwidth: %d",stream->dlopts->bandwidth);
	rtsp_set_field(rtsp_hdr,buffer);
	free(buffer);
    }
    
    rtsp_set_range_field(rtsp_hdr,stream->dlopts->range);
    rtsp_set_speed_field(rtsp_hdr,stream->dlopts->speed);
    
    rtsp_request_play(rtsp_hdr,rtsp_ctrl->mrl);
  
    rtsp_send_request_and_free(stream,rtsp_hdr);
    
    
    /* 
     * Receiving part 
     */
    /* receive message for PLAY request */
    rtsp_hdr = new_rtsp_header();
    ret = rtsp_recv_header(stream,rtsp_hdr);
    
    if(!is_rtsp_response_ok(rtsp_hdr->status_code)) { 
	display(MSDL_ERR,"PLAY request returned: %d (%s)\n",
		rtsp_hdr->status_code,rtsp_hdr->reason_phrase);
	
	field = rtsp_get_field(rtsp_hdr,"Alert");
	if(field) {
	    while(*field == ' ') field++;
	    display(MSDL_ERR,"message from server --> %s\n",field);
	}
	free_rtsp_header(rtsp_hdr);
	goto failed;
    }

    /* display real speed (might differ from user requested) */
    if((field = rtsp_get_field(rtsp_hdr,"Speed")) != NULL) {    
	if(stream->dlopts->speed) {
	    while(*field == ' ') field++;
	    display(MSDL_NOR,"Speed: %s\n",field);
	}
    }
    if((field = rtsp_get_field(rtsp_hdr,"Range")) != NULL) {    
	if(stream->dlopts->range) {
	    while(*field == ' ') field++;
	    display(MSDL_NOR,"Range: %s\n",field);
	}
    }

    /* skip content-length bytes from network */
    rtsp_ignore_data_after_header(stream,rtsp_hdr);
    free_rtsp_header(rtsp_hdr);
    
    return ret;

  failed:
    return -1;
}
예제 #6
0
/*
 * send DESCRIBE request
 * return value:   -1: failure   status_code: success
 */
static int real_rtsp_describe(struct stream_t *stream,char **description_ret)
{
    struct stream_ctrl_t *stream_ctrl = stream->stream_ctrl;
    struct rtsp_ctrl_t *rtsp_ctrl = stream_ctrl->rtsp_ctrl;
    struct rtsp_header_t *rtsp_hdr = NULL;

    char *description = NULL;
    char *buffer = (char *)xmalloc(BUFSIZE_1K);
    char *field = NULL;
    int len = 0;
    int ret = 0;
    
    rtsp_hdr = new_rtsp_header_with_standard_fields(rtsp_ctrl);
    rtsp_set_field(rtsp_hdr, "Accept: application/sdp");
    rtsp_set_field(rtsp_hdr, real_useragent);
    rtsp_set_field(rtsp_hdr, "Require: com.real.retain-entity-for-setup");
  
    snprintf(buffer,BUFSIZE_1K - 1,"Bandwidth: %u",stream_ctrl->bandwidth);
    rtsp_set_field(rtsp_hdr,buffer); 
  
    rtsp_set_field(rtsp_hdr, "Language: en-US");
    rtsp_set_field(rtsp_hdr, "RegionData: 0");
    rtsp_set_field(rtsp_hdr, real_clientid);
    rtsp_set_field(rtsp_hdr, "GUID: 00000000-0000-0000-0000-000000000000");
    rtsp_set_field(rtsp_hdr, "SupportsMaximumASMBandwidth: 1");
  
  
    rtsp_request_describe(rtsp_hdr,rtsp_ctrl->mrl);
    rtsp_send_request_and_free(stream,rtsp_hdr);
    
    rtsp_hdr = new_rtsp_header();
    ret = rtsp_recv_header(stream,rtsp_hdr);
    if(ret < 0) {
	free_rtsp_header(rtsp_hdr);
	goto failed;
    }
    
    /* NOT OK */
    if(!is_rtsp_response_ok(rtsp_hdr->status_code)) { 
	display(MSDL_ERR,"DESCRIBE request returned: %d (%s)\n",
		rtsp_hdr->status_code,rtsp_hdr->reason_phrase);
	
	field = rtsp_get_field(rtsp_hdr,"Alert");
	if(field) {
	    while(*field == ' ') field++;
	    display(MSDL_ERR,"message from server --> %s\n",field);
	}
	free_rtsp_header(rtsp_hdr);
	goto failed;
    }

    len = 0;
    /* Content-length must be present */
    if((field = rtsp_get_field(rtsp_hdr,"Content-length")) != NULL) {
	while(*field == ' ') field++;
	len = atoi(field);
    }
    else { /* no Content-length */
	display(MSDL_ERR,"warning: No Content-length in fields!!\n");
    }
  
    if((field = rtsp_get_field(rtsp_hdr,"ETag")) != NULL) {
	while(*field == ' ') field++;
	rtsp_ctrl->etag = strdup(field);
    }
    else {
	display(MSDL_ERR,"warning: No ETag!!\n");
	rtsp_ctrl->etag = NULL;
    }

    free_rtsp_header(rtsp_hdr);  
    
    /*
      copy description (sdp)
    */
    description = (char *)xmalloc(len + 1);
    if(read_data(stream,(uint8_t *)description,len) < 0) {
	goto failed;
    }
    description[len] = '\0';
  
    display(MSDL_DBG,"==================\n%s\n=(%d bytes)========\n",
	    description,(int)strlen(description));
    
    
    if(buffer) free(buffer);
    *description_ret = description;
    return ret;
    
  failed:
    if(description) free(description);
    if(buffer) free(buffer);
    *description_ret = NULL;
    return -1;
}