示例#1
0
文件: rtsp.c 项目: clkao/msdl
/*
 * alloc new rtsp_header_t and set standard fields for send.
 * this function is purely for making code more readable.
 *
 * return value:  what rtsp_recv_header returned (status code: success  -1: failure)
 */
struct rtsp_header_t *new_rtsp_header_with_standard_fields(struct rtsp_ctrl_t *rtsp_ctrl)
{
    struct rtsp_header_t *rtsp_hdr;

    rtsp_hdr = new_rtsp_header();
    rtsp_set_standard_fields(rtsp_ctrl,rtsp_hdr);
    
    return rtsp_hdr;
}
示例#2
0
/*
 * process rtsp header coming among rtsp real media packet
 * 
 * return value:       status code ... normal proceed case
 *                               0 ... EOF packet (not possible)
 *                              -1 ... error
 */
static int real_process_header(struct stream_t *stream)
{
    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;
    int status_code = 0;
    int bodylen = 0;
    uint8_t *body = NULL;
    char *field = NULL;
    int got_cseq = 0;

    rtsp_hdr = new_rtsp_header();
    status_code = rtsp_recv_header(stream,rtsp_hdr);
    if(status_code < 0) {
	goto failed;
    }
    
    
    /* get content length data */
    if((field = rtsp_get_field(rtsp_hdr,"Content-length")) != NULL) {
	while(*field == ' ') field++;
	bodylen = atoi(field);	
	body = (uint8_t *)xmalloc(bodylen);
	bodylen = read_data(stream,body,bodylen);
    }
    /* get Cseq, for sending OK back */
    if((field = rtsp_get_field(rtsp_hdr,"Cseq")) != NULL) {
	while(*field == ' ') field++;
	got_cseq = atoi(field);	
    }


    if(!strncmp(rtsp_hdr->protocol,"RTSP",4)) { /* RTSP/1.0 200 OK , ignore this */
	/*
	  somehow RTSP message reply can be found among rdt messages.
	  send nothing.
	*/
	if(!got_cseq == rtsp_ctrl->cseq - 1) {
	    display(MSDL_DBG,"CSeq mismatch: expected %d, got %d",
		    rtsp_ctrl->cseq - 1,got_cseq);
	}
	/* DO NOT send RTSP OK */
    }
    else { /* not RTSP, whatever it is, send OK would be just fine  */
	rtsp_200ok(stream,got_cseq,rtsp_ctrl->session);
    }
    

    if(rtsp_hdr) free_rtsp_header(rtsp_hdr);      
    if(body)     free(body);
    return status_code;

  failed:
    if(body)     free(body);
    if(rtsp_hdr) free_rtsp_header(rtsp_hdr);
    return -1;
}
示例#3
0
文件: rtsp.c 项目: clkao/msdl
/*
 * receive rtsp header but ignore its message, etc..
 * this function is purely for making code more readable.
 *
 *       return value:  what rtsp_recv_header returned
 *                      -1 ... failed;
 */
int rtsp_recv_header_ignore_message(struct stream_t *stream)
{
    struct rtsp_header_t *rtsp_hdr = NULL;
    int ret = 0;

    
    rtsp_hdr = new_rtsp_header();
    ret = rtsp_recv_header(stream,rtsp_hdr);
    
    /* if content-length field, get all following data */
    if(rtsp_ignore_data_after_header(stream,rtsp_hdr) < 0) {
	return -1;
    }
    
    free_rtsp_header(rtsp_hdr);
    return ret;
}
示例#4
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;
}
示例#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;
}