⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtsp_command.c

📁 嵌入式系统中c程序实现了rtsp协议的基本内容
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * The contents of this file are subject to the Mozilla Public
 * License Version 1.1 (the "License"); you may not use this file
 * except in compliance with the License. You may obtain a copy of
 * the License at http://www.mozilla.org/MPL/
 * 
 * Software distributed under the License is distributed on an "AS
 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * rights and limitations under the License.
 * 
 * The Original Code is MPEG4IP.
 * 
 * The Initial Developer of the Original Code is Cisco Systems Inc.
 * Portions created by Cisco Systems Inc. are
 * Copyright (C) Cisco Systems Inc. 2000, 2001.  All Rights Reserved.
 * 
 * Contributor(s): 
 *              Bill May        wmay@cisco.com
 */
/*
 * rtsp_command.c - process API calls to send/receive rtsp commands
 */
 #include <string.h>
#include "rtsp_private.h"
#include "sdp.h"
#include "rtsp_client.h"

static const char *UserAgent = "STMicroelectronics RTSP 1.0";

 char* strdup(const  char* buf)
{
      char *tembuf=NULL;
	int len;
	len=strlen(buf)+1;
      tembuf= Rtsp_Malloc(len,__LINE__,__FILE__);
      memset(tembuf,0x00,len);
	memcpy(tembuf,buf,len-1);
	return tembuf;
}
/*
 * rtsp_build_common()
 * Builds a common header based on rtsp_command_t information.
 */
static int rtsp_build_common (char *buffer,
			      uint32_t maxlen,
			      uint32_t *at,
			      rtsp_client_t *info,
			      rtsp_command_t *cmd,
			      const char *session)
{
  int ret;

  /*
   * The below is ugly, but it will allow us to remove a lot of lines
   * of code.  SNPRINTF_CHECK makes sure (for this routine), that we
   * don't have more data in the buffer than allowed - it will return
   * an error code if that happens.
   */
#define SNPRINTF_CHECK(fmt, value) \
  ret = snprintf(buffer + *at, maxlen - *at, (fmt), (value)); \
  if (ret == -1) { \
    return (-1); \
  }\
  *at += ret;

  SNPRINTF_CHECK("CSeq: %u\r\n", info->next_cseq);
  if (info->cookie) {
    SNPRINTF_CHECK("Cookie: %s\r\n", info->cookie);
  }

  if (cmd && cmd->accept) {
    SNPRINTF_CHECK("Accept: %s\r\n", cmd->accept);
  }
  if (cmd && cmd->accept_encoding) {
    SNPRINTF_CHECK("Accept-Encoding: %s\r\n", cmd->accept_encoding);
  }
  if (cmd && cmd->accept_language) {
    SNPRINTF_CHECK("Accept-Language: %s\r\n", cmd->accept_language);
  }
  if (cmd && cmd->authorization) {
    SNPRINTF_CHECK("Authorization: %s\r\n", cmd->authorization);
  }
  if (cmd && cmd->bandwidth != 0) {
    SNPRINTF_CHECK("Bandwidth: %u\r\n", cmd->bandwidth);
  }
  if (cmd && cmd->blocksize != 0) {
    SNPRINTF_CHECK("Blocksize: %u\r\n", cmd->blocksize);
  }
  if (cmd && cmd->cachecontrol) {
    SNPRINTF_CHECK("Cache-Control: %s\r\n", cmd->cachecontrol);
  }
  if (cmd && cmd->conference) {
    SNPRINTF_CHECK("Conference: %s\r\n", cmd->conference);
  }
  if (cmd && cmd->from) {
    SNPRINTF_CHECK("From: %s\r\n", cmd->from);
  }
  if (cmd && cmd->proxyauth) {
    SNPRINTF_CHECK("Proxy-Authorization: %s\r\n", cmd->proxyauth);
  }
  if (cmd && cmd->proxyrequire) {
    SNPRINTF_CHECK("Proxy-Require: %s\r\n", cmd->proxyrequire);
  }
  if (cmd && cmd->range) {
    SNPRINTF_CHECK("Range: %s\r\n", cmd->range);
  }
  if (cmd && cmd->referer) {
    SNPRINTF_CHECK("Referer: %s\r\n", cmd->referer);
  }
  if (cmd && cmd->scale != 0.0) {
    SNPRINTF_CHECK("Scale: %g\r\n", cmd->scale);
  }
  if (session) {
    SNPRINTF_CHECK("Session: %s\r\n", session);
  } else if (cmd && cmd->session) {
    SNPRINTF_CHECK("Session: %s\r\n", cmd->session);
  }
  if (cmd && cmd->speed != 0.0) {
    SNPRINTF_CHECK("Speed: %g\r\n", cmd->speed);
  }
  if (cmd && cmd->transport) {
    SNPRINTF_CHECK("Transport: %s\r\n", cmd->transport);
  }
    
  SNPRINTF_CHECK("User-Agent: %s\r\n",
	      (cmd && cmd->useragent != NULL ?  cmd->useragent : UserAgent));
  if (cmd && cmd->User) {
    SNPRINTF_CHECK("%s", cmd->User);
  }
#undef SNPRINTF_CHECK
  return (0);
}

/*
 * rtsp_send_describe - send the describe info to a server
 */
int rtsp_send_describe (rtsp_client_t *info,
			rtsp_command_t *cmd,
			rtsp_decode_t **decode_result)
{
  char buffer[2048];
  uint32_t maxlen, buflen;
  int ret;
  rtsp_decode_t *decode;

  *decode_result = NULL;
  info->redirect_count = 0;

  do {
    maxlen = sizeof(buffer);
    buflen = snprintf(buffer, maxlen, "DESCRIBE %s RTSP/1.0\r\n", info->url);

    if (rtsp_build_common(buffer, maxlen, &buflen, info, cmd, NULL) == -1) {
      Rtsp_Printf("rtsp_build_common error!\n");
      return (RTSP_RESPONSE_RECV_ERROR);
    }
    
    ret = snprintf(buffer + buflen, maxlen - buflen, "\r\n");
    if (ret == -1) {
      return (RTSP_RESPONSE_RECV_ERROR);
    }
    buflen += ret;

   Rtsp_Printf( "Sending DESCRIBE %s\n", info->url);
  // Rtsp_Printf( buffer);

    ret = rtsp_send_and_get(info, buffer, buflen);
  
    Rtsp_Printf("ret = %d\n",ret);
	
    decode = info->decode_response;
    
    if (ret == RTSP_RESPONSE_GOOD) 
  {
     Rtsp_Printf( "DESCRIBE returned correctly\n");

      *decode_result = info->decode_response;
      info->decode_response = NULL;
      return (RTSP_RESPONSE_GOOD);
    } 
	else if (ret != RTSP_RESPONSE_REDIRECT) 
    {
      
     Rtsp_Printf( "DESCRIBE return code %d\n", ret);

      if (ret != RTSP_RESPONSE_RECV_ERROR &&
	  decode != NULL) {
	*decode_result = info->decode_response;
	info->decode_response = NULL;
	Rtsp_Printf( "Error code %s %s\n",
		   decode->retcode,
		   decode->retresp);
		   
      }
      return (ret);
    }
    /*
     * Handle this through the redirects
     */
  }  while (ret == RTSP_RESPONSE_REDIRECT);
  
  return (RTSP_RESPONSE_RECV_ERROR);
}

/*
 * rtsp_send_setup - When we get the describe, this will set up a
 * particular stream.  Use the session handle for all further commands for
 * the stream (play, pause, teardown).
 */
int rtsp_send_setup (rtsp_client_t *info,
		     const char *url,
		     rtsp_command_t *cmd,
		     rtsp_session_t **session_result,
		     rtsp_decode_t **decode_result,
		     int is_aggregate)
{
  char buffer[2048], *temp;
  uint32_t maxlen, buflen;
  int ret;
  rtsp_decode_t *decode;
  rtsp_session_t *sptr;
  
  *decode_result = NULL;
  *session_result = NULL;
  info->redirect_count = 0;

  if (cmd == NULL || cmd->transport == NULL) {
    return (RTSP_RESPONSE_MISSING_OR_BAD_PARAM);
  }

  if (strncmp(url, "rtsp://", strlen("rtsp://")) != 0) {
    return (RTSP_RESPONSE_BAD_URL);
  }

  temp = strchr(url + strlen("rtsp://"), '/');
  if (temp == NULL) {
    return (RTSP_RESPONSE_BAD_URL);
  }
  if (strncmp(url, info->url, temp - url) != 0) {
   Rtsp_Printf( "Bad url %s\n", url);
   Rtsp_Printf( "Should be %s\n", info->url);
    return (RTSP_RESPONSE_BAD_URL);
  }

  maxlen = sizeof(buffer);
  buflen = snprintf(buffer, maxlen, "SETUP %s RTSP/1.0\r\n", url);

  if (rtsp_build_common(buffer,
			maxlen,
			&buflen,
			info,
			cmd,
			is_aggregate ? info->session : NULL) == -1) {
    return (RTSP_RESPONSE_RECV_ERROR);
  }
    
  ret = snprintf(buffer + buflen, maxlen - buflen, "\r\n");
  if (ret == -1) {
    return (RTSP_RESPONSE_RECV_ERROR);
  }
  buflen += ret;

/* Rtsp_Printf( "Sending SETUP %s\n", url);
 Rtsp_Printf( buffer);
*/
  ret = rtsp_send_and_get(info, buffer, buflen);
  decode = info->decode_response;
    
  if (ret == RTSP_RESPONSE_GOOD) {
/*   Rtsp_Printf( "SETUP returned correctly\n");
*/
    *decode_result = info->decode_response;
    info->decode_response = NULL;
#ifndef IPTV_COMPATIBLE
    if ((*decode_result)->session == NULL) {
      return (RTSP_RESPONSE_BAD);
    }
#endif
    temp=strchr((*decode_result)->session,';');
      if(temp!=NULL)
      {
        int i=0;
        char *c=NULL;
        while ((*decode_result)->session[i]!=';'&& (*decode_result)->session[i]!='\0') i++;
        c = (char *)Rtsp_Malloc(i+1,__LINE__,__FILE__);
        strncpy(c,(*decode_result)->session,i);
        c[i]='\0';
        Rtsp_Free((*decode_result)->session,__LINE__,__FILE__);
        (*decode_result)->session=c;
      }
        if (is_aggregate && info->session != NULL) {
      if (strcmp(info->session, (*decode_result)->session) != 0) {
/*	Rtsp_Printf( "Session for %s returned different %s %s\n",
		   url, info->session, (*decode_result)->session);
*/		   
	return (RTSP_RESPONSE_BAD);
      }
    }
    sptr = info->session_list;
    while (sptr != NULL) {
      if (strcmp(sptr->url, url) == 0)
	break;
      sptr = sptr->next;
    }
    if (sptr == NULL) {
      sptr = (rtsp_session_t*)Rtsp_Malloc(sizeof(rtsp_session_t),__LINE__,__FILE__);
      if (sptr == NULL) {
	return (RTSP_RESPONSE_RECV_ERROR);
      }
      sptr->url = strdup( url);
      if ((*decode_result)->session != NULL)
	sptr->session =strdup((*decode_result)->session);
      else
	sptr->session = NULL;
      sptr->parent = info;
      sptr->next = info->session_list;
      info->session_list = sptr;
      if (is_aggregate && info->session == NULL)
	info->session = sptr->session;
    }
    *session_result = sptr;
    return (RTSP_RESPONSE_GOOD);
  } else {
/*   Rtsp_Printf( "SETUP return code %d\n", ret);
*/
    if (ret != RTSP_RESPONSE_RECV_ERROR &&
	decode != NULL) {
      *decode_result = info->decode_response;
      info->decode_response = NULL;
     Rtsp_Printf( "Error code %s %s\n",
		 decode->retcode,
		 decode->retresp);
    }
    return (ret);
  }
  
  return (RTSP_RESPONSE_RECV_ERROR);
}

/*
 * check_session - make sure that the session is correct for that command
 */
static int check_session (rtsp_session_t *session,
			   rtsp_command_t *cmd)
{
  rtsp_session_t *sptr;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -