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

📄 rtsp_util.c

📁 网络MPEG4IP流媒体开发源代码
💻 C
字号:
/* * 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_util.c - mixture of various utilities needed for rtsp client */#include "rtsp_private.h"static int rtsp_debug_level = LOG_ALERT;static error_msg_func_t rtsp_error_msg = NULL;/* * Ugh - a global variable for the loglevel. * We probably want to enhance this to pass a function vector as well. */void rtsp_set_loglevel (int loglevel){  rtsp_debug_level = loglevel;}void rtsp_set_error_func (error_msg_func_t func){  rtsp_error_msg = func;}/* * rtsp_debug() * Display rtsp debug information.  Probably want to hook this into * a rtsp_client, and enhance it to do file, console, and user routine * output. */void rtsp_debug (int loglevel, const char *fmt, ...){  //struct timeval thistime;  va_list ap;  //char buffer[80];  if (loglevel <= rtsp_debug_level) {    if (rtsp_error_msg != NULL) {      va_start(ap, fmt);      (rtsp_error_msg)(loglevel, "librtsp", fmt, ap);      va_end(ap);    }  }}void free_session_info (rtsp_session_t *session){  CHECK_AND_FREE(session->session);  CHECK_AND_FREE(session->url);  free(session);}/* * clear_decode_response() * Frees memory associated with that structure and clears it. */void clear_decode_response (rtsp_decode_t *resp){  CHECK_AND_FREE(resp->retresp);  CHECK_AND_FREE(resp->body);  CHECK_AND_FREE(resp->accept);  CHECK_AND_FREE(resp->accept_encoding);  CHECK_AND_FREE(resp->accept_language);  CHECK_AND_FREE(resp->allow_public);  CHECK_AND_FREE(resp->authorization);  CHECK_AND_FREE(resp->bandwidth);  CHECK_AND_FREE(resp->blocksize);  CHECK_AND_FREE(resp->cache_control);  CHECK_AND_FREE(resp->content_base);  CHECK_AND_FREE(resp->content_encoding);  CHECK_AND_FREE(resp->content_language);  CHECK_AND_FREE(resp->content_location);  CHECK_AND_FREE(resp->content_type);  CHECK_AND_FREE(resp->cookie);  CHECK_AND_FREE(resp->date);  CHECK_AND_FREE(resp->expires);  CHECK_AND_FREE(resp->from);  CHECK_AND_FREE(resp->if_modified_since);  CHECK_AND_FREE(resp->last_modified);  CHECK_AND_FREE(resp->location);  CHECK_AND_FREE(resp->proxy_authenticate);  CHECK_AND_FREE(resp->proxy_require);  CHECK_AND_FREE(resp->range);  CHECK_AND_FREE(resp->referer);  CHECK_AND_FREE(resp->require);  CHECK_AND_FREE(resp->retry_after);  CHECK_AND_FREE(resp->rtp_info);  CHECK_AND_FREE(resp->scale);  CHECK_AND_FREE(resp->server);  CHECK_AND_FREE(resp->session);  CHECK_AND_FREE(resp->speed);  CHECK_AND_FREE(resp->transport);  CHECK_AND_FREE(resp->unsupported);  CHECK_AND_FREE(resp->user_agent);  CHECK_AND_FREE(resp->via);  CHECK_AND_FREE(resp->www_authenticate);  resp->content_length = 0;  resp->cseq = 0;  resp->close_connection = FALSE;}/* * free_decode_response() * frees memory associated with response, along with response. */void free_decode_response (rtsp_decode_t *decode){  if (decode != NULL) {    clear_decode_response(decode);    free(decode);  }}/* * rtsp_set_and_decode_url() * will decode the url, make sure it matches RTSP url information, * pulls out the server name and port, then gets the server address */int rtsp_dissect_url (rtsp_client_t *rptr, const char *url){  const char *uptr;  const char *nextslash, *nextcolon, *rightbracket;  int hostlen;    if (rptr->url != NULL || rptr->server_name != NULL) {    return (EEXIST);  }  uptr = url;  rptr->url = strdup(url);  if (strncmp("rtsp://", url, strlen("rtsp://")) == 0) {    rptr->useTCP = TRUE;    uptr += strlen("rtsp://");#if 0  } else if (strncmp("rtspu://", url, strlen("rtspu:")) == 0) {    uptr += strlen("rtspu://");#endif  } else {    return(-1);  }  rptr->port = 554;  rightbracket = NULL;  if (*uptr == '[') {    uptr++; // don't include the '['    rightbracket = strchr(uptr, ']');    if (rightbracket != NULL) {      // literal IPv6 address      if (rightbracket[1] == ':') {	nextcolon = rightbracket + 1;      } else	nextcolon = NULL;      nextslash = strchr(rightbracket, '/');    } else {      return (EINVAL);    }  } else {  nextslash = strchr(uptr, '/');  nextcolon = strchr(uptr, ':');  }  if (nextslash != NULL || nextcolon != NULL) {    if (nextcolon != NULL &&	(nextcolon < nextslash || nextslash == NULL)) {      hostlen = nextcolon - uptr;      // have a port number      nextcolon++;      rptr->port = 0;      while (isdigit(*nextcolon)) {	rptr->port *= 10;	rptr->port += *nextcolon - '0';	nextcolon++;      }      if (rptr->port == 0 || (*nextcolon != '/' && *nextcolon != '\0')) {	return (EINVAL);      }    } else {      // no port number      hostlen = nextslash - uptr;	    }    if (rightbracket != NULL) {       hostlen--;    }    if (hostlen == 0) {      return (EINVAL);    }    rptr->server_name = malloc(hostlen + 1);    if (rptr->server_name == NULL) {      return (ENOMEM);    }    memcpy(rptr->server_name, uptr, hostlen);    rptr->server_name[hostlen] = '\0';  } else {    if (*uptr == '\0') {      return (EINVAL);    }    rptr->server_name = strdup(uptr);    if (rptr->server_name == NULL) {      return (ENOMEM);    }    if (rightbracket != NULL) {      rptr->server_name[strlen(rptr->server_name) - 1] = '\0';    }  }  return (0);}/* * rtsp_setup_redirect() * Sets up URLs, does the connect for redirects.  Need to handle * 300 case (multiple choices).  Imagine that if we had that, we'd just * loop through the body until we found a server that we could connect * with. */int rtsp_setup_redirect (rtsp_client_t *info){  rtsp_decode_t *decode;  int ret;  if (info->decode_response == NULL)    return (-1);  info->redirect_count++;  if (info->redirect_count > 5)     return (-1);  decode = info->decode_response;  if (decode->location == NULL)    return (-1);    if (info->orig_url == NULL) {    info->orig_url = info->url;    info->url = NULL;  } else {    CHECK_AND_FREE(info->url);  }  CHECK_AND_FREE(info->server_name);  rtsp_close_socket(info);  ret = rtsp_dissect_url(info, decode->location);  if (ret != 0) return (ret);    return (rtsp_create_socket(info));}/* return last occurrence of needle in haystack */static const char *my_strrstr (const char *haystack, const char *needle){   int needle_len = strlen(needle);   int haystack_len = strlen(haystack);   haystack_len -= needle_len;   while (haystack_len >= 0) {     if (strncmp(haystack + haystack_len, needle, needle_len) == 0) {        return (haystack + haystack_len);     }     haystack_len--;   }   return (NULL);}/*  * removes the overlap between the base_url and the control_string * the base_url will never contain /trackID= x, so remove it * Example: rm_rtsp_overlap("rtsp://www.blah.com/foo", "foo/trackId=2") *          will return "rtsp://www.blah.com/foo/trackId=2" */static char *rm_rtsp_overlap (const char *control_string, const char *base_url){  char *str = NULL;  uint32_t cblen = 0;   char *file_ptr = strrchr(control_string, '/');   if (file_ptr != NULL && file_ptr != control_string) {    char *path = NULL;    char *last_path_in_base = NULL;	uint32_t control_len = strlen(control_string);	uint32_t file_len = strlen(file_ptr);	uint32_t last_path_len = 0;    /* path will contain control str without /trackID = x at the end */    path = (char *)malloc(control_len - file_len + 1);    if (path == NULL)       exit(EXIT_FAILURE);    strncpy (path, control_string, control_len - file_len);    path[control_len - file_len] = '\0';    last_path_in_base = strdup(my_strrstr(base_url, path));	if (last_path_in_base != NULL) 	  last_path_len = strlen(last_path_in_base);    if (last_path_in_base == NULL 		|| last_path_len != strlen(path)) {	  /* couldn't find path in base url or isn't at end of base url */      free(path);	  free(last_path_in_base);      return ((char *)NULL);    } 	else {	  /* make sure there is one and only one '/' between the base url       * and the control string */      cblen = strlen(base_url) - last_path_len;      if (*control_string != '/') {        cblen +=1;      }      str = (char *)malloc(cblen + control_len +1);      if (str == NULL)         exit(EXIT_FAILURE);      /* copy base_url up to last occurrence of path */      strncpy(str, base_url, cblen);      str[cblen] = '\0';      strcat(str, control_string);      free(path);    }	free(last_path_in_base);  }  return ((char *)str);}/*  * attempts to match the session url with   * content_base/url or session_name/url * if content base and url overlap, or if session_name and  * url overlap, remove the overlap and attempt to match again * return 1 if matched, 0 otherwise */int rtsp_is_url_my_stream (rtsp_session_t *session,			   const char *url,			   const char *content_base,			   const char *session_name){   char *session_url = session->url;  const char *end;  int is_match = 0;  end = my_strrstr(session_url, url);   if (end != NULL  || strcmp(url,"*") == 0) {    if (strncmp(session_url, content_base,		strlen(session_url) - strlen(end)) == 0	|| strncmp(session_url, session_name, 		   strlen(session_url) - strlen(end)) == 0) {      is_match = 1;    }    else {      /* url isn't contained in the session_url */      /* check if there is an overlap */      char *str1 = rm_rtsp_overlap(url, content_base);      char *str2 = rm_rtsp_overlap(url, session_name);      if ((str1 != NULL && strcmp(session_url, str1) == 0 )	  || (str2 != NULL && strcmp(session_url, str2) == 0))	is_match = 1;      CHECK_AND_FREE(str1);      CHECK_AND_FREE(str2);    }  }  return (is_match);}struct in_addr get_server_ip_address (rtsp_session_t *session){  return session->parent->server_addr;}

⌨️ 快捷键说明

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