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

📄 sdp.c

📁 Sofia SIP is an open-source SIP User-Agent library, compliant with the IETF RFC3261 specification.
💻 C
📖 第 1 页 / 共 4 页
字号:
  return 0;}/** Compare two media (m=) fields */int sdp_media_cmp(sdp_media_t const *a, sdp_media_t const *b){  int rv;   sdp_connection_t const *ac, *bc;  sdp_bandwidth_t const *ab, *bb;  sdp_rtpmap_t const *arm, *brm;  sdp_attribute_t const *aa, *ba;  if (a == b)    return 0;  if ((rv = (a != NULL) - (b != NULL)))     return rv;  if (a->m_type != b->m_type)    return a->m_type < b->m_type ? -1 : 1;  if (a->m_type == sdp_media_x)    if ((rv = str0cmp(a->m_type_name, b->m_type_name)))      return rv;  if (a->m_port != b->m_port)    return a->m_port < b->m_port ? -1 : 1;  if (a->m_port == 0 /* && b->m_port == 0 */)    /* Ignore transport protocol and media list if media has been rejected */    return 0;  if (a->m_number_of_ports != b->m_number_of_ports)    return a->m_number_of_ports < b->m_number_of_ports ? -1 : 1;  if (a->m_proto != b->m_proto)    return a->m_proto < b->m_proto ? -1 : 1;  if (a->m_proto == sdp_media_x)    if ((rv = str0cmp(a->m_proto_name, b->m_proto_name)))      return rv;  if (a->m_mode != b->m_mode)    return a->m_mode < b->m_mode ? -1 : 1;  for (arm = a->m_rtpmaps, brm = b->m_rtpmaps;        arm || brm;        arm = arm->rm_next, brm = brm->rm_next)    if ((rv = sdp_rtpmap_cmp(arm, brm)))      return rv;  if ((rv = sdp_list_cmp(a->m_format, b->m_format)))    return rv;  if ((rv = str0cmp(a->m_information, b->m_information)))    return rv;  for (ac = a->m_connections, bc = b->m_connections;        ac || bc;        ac = ac->c_next, bc = bc->c_next)  if ((rv = sdp_connection_cmp(ac, bc)))    return rv;  for (ab = a->m_bandwidths, bb = b->m_bandwidths;        ab || bb;        ab = ab->b_next, bb = bb->b_next)    if ((rv = sdp_bandwidth_cmp(a->m_bandwidths, b->m_bandwidths)))      return rv;  if ((rv = sdp_key_cmp(a->m_key, b->m_key)))    return rv;  for (aa = a->m_attributes, ba = b->m_attributes;        aa || bb;        aa = aa->a_next, ba = ba->a_next)    if ((rv = sdp_attribute_cmp(aa, ba)))      return rv;  return 0;}/* ---------------------------------------------------------------------- */sdp_connection_t *sdp_media_connections(sdp_media_t const *m){  if (m) {    if (m->m_connections)      return m->m_connections;    if (m->m_session)      return m->m_session->sdp_connection;  }  return NULL;}/* ---------------------------------------------------------------------- *//** Find named attribute from given list. */sdp_attribute_t *sdp_attribute_find(sdp_attribute_t const *a, char const *name){  for (; a; a = a->a_next) {    if (strcasecmp(a->a_name, name) == 0)      break;  }  return (sdp_attribute_t *)a;}/** Find named attribute from given lists (a or a2). */sdp_attribute_t *sdp_attribute_find2(sdp_attribute_t const *a, 				     sdp_attribute_t const *a2, 				     char const *name){  for (; a; a = a->a_next) {    if (strcasecmp(a->a_name, name) == 0)      break;  }  if (a == 0)    for (a = a2; a; a = a->a_next) {      if (strcasecmp(a->a_name, name) == 0)	break;    }  return (sdp_attribute_t *)a;}/** Get session mode from attribute list. */sdp_mode_t sdp_attribute_mode(sdp_attribute_t const *a, sdp_mode_t defmode){  for (; a; a = a->a_next) {    if (strcasecmp(a->a_name, "sendrecv") == 0)      return sdp_sendrecv;    if (strcasecmp(a->a_name, "inactive") == 0)      return sdp_inactive;    if (strcasecmp(a->a_name, "recvonly") == 0)      return sdp_recvonly;    if (strcasecmp(a->a_name, "sendonly") == 0)      return sdp_sendonly;  }  return defmode;}/** Convert session mode as #sdp_attribute_t structure. */sdp_attribute_t *sdp_attribute_by_mode(su_home_t *home, sdp_mode_t mode){  sdp_attribute_t *a;  char const *name;  if (mode == sdp_inactive)    name = "inactive";  else if (mode == sdp_sendonly)    name = "sendonly";  else if (mode == sdp_recvonly)    name = "recvonly";  else if (mode == sdp_sendrecv)    name = "sendrecv";  else    return NULL;    a = su_salloc(home, sizeof(*a));  if (a)    a->a_name = name;  return a;}/** Find a mapped attribute.  * * A mapped attribute has form 'a=<name>:<pt> <value>' where pt is a RTP * payload type, integer in range 0..127. For example, "a=atmmap" [@RFC3108] * is a mapped attribute. Note that common mapped attributes, "a=rtpmap" and * "a=fmtp" are already parsed as list of #sdp_rtpmap_t in #sdp_media_t. * * @param a pointer to first attribute in the list * @param name name of the attribute * @param pt payload type number (must be 0..127) * @param return_result return value parameter for mapped attribute value * * @return Pointer to a matching attribute structure, or NULL.  * * If a matching attribute is found, @a return_result will point to part of * the attribute after the payload type and whitespace. */sdp_attribute_t *sdp_attribute_mapped_find(sdp_attribute_t const *a,					   char const *name,					   int pt, char **return_result){  char pt_value[4];  size_t pt_len;  if (return_result)    *return_result = NULL;  if (0 > pt || pt > 127)    return NULL;  snprintf(pt_value, sizeof(pt_value), "%u", (unsigned)pt);  pt_len = strlen(pt_value);  for (; (a = sdp_attribute_find(a, name)); a = a->a_next) {    char const *value = a->a_value;    size_t wlen;    if (strncmp(value, pt_value, pt_len))      continue;    wlen = strspn(value + pt_len, " \t");    if (wlen == 0 || value[pt_len + wlen] == '\0')      continue;    if (return_result)      *return_result = (char *)value + pt_len + wlen;    return (sdp_attribute_t *)a;  }  return NULL;}/** Append a (list of) attribute(s) to a list of attributes. */void sdp_attribute_append(sdp_attribute_t **list, 			  sdp_attribute_t const *a){  assert(list);  if (list == NULL || a == NULL)    return;  for (;*list; list = &(*list)->a_next)    ;  *list = (sdp_attribute_t *)a;}/**Replace or append a attribute within a list of attributes.  * * @retval 1 if replaced existing attribute * @retval 0 if attribute was appended * @retval -1 upon an error */int sdp_attribute_replace(sdp_attribute_t **list, 			  sdp_attribute_t *a,			  sdp_attribute_t **return_replaced){  sdp_attribute_t *replaced;  assert(list);  if (return_replaced)    *return_replaced = NULL;  if (list == NULL || a == NULL)    return -1;  assert(a->a_name != NULL); assert(a->a_next == NULL);  for (; *list; list = &(*list)->a_next) {    if (strcasecmp((*list)->a_name, a->a_name) == 0)      break;  }  replaced = *list, *list = a;    if (replaced) {    a->a_next = replaced->a_next;    replaced->a_next = NULL;    if (return_replaced)      *return_replaced = replaced;    return 1;  }  return 0;}/** Remove a named attribute from a list of attributes. */sdp_attribute_t *sdp_attribute_remove(sdp_attribute_t **list, 				      char const *name){  sdp_attribute_t *a;  assert(list);  if (list == NULL)    return NULL;  if (name == NULL)    return NULL;  for (a = *list; a; list = &a->a_next, a = *list) {    if (strcasecmp(name, a->a_name) == 0)      break;  }  if (a) {    *list = a->a_next;    a->a_next = NULL;  }  return a;}/* Return 1 if m= line struct matches with given type and name */unsigned sdp_media_match(sdp_media_t const *m,			 sdp_media_e type,			 sdp_text_t *type_name,			 sdp_proto_e proto,			 sdp_text_t *proto_name){  if (m == NULL)    return 0;  if (type == sdp_media_any || m->m_type == sdp_media_any)    return 1;  if (type_name == NULL)    type_name = "";  if (type != m->m_type ||      (type == sdp_media_x && strcasecmp(m->m_type_name, type_name)))    return 0;  if (proto == sdp_proto_any || m->m_proto == sdp_proto_any)    return 1;  if (proto_name == NULL)    proto_name = "";  if (proto != m->m_proto ||      (proto == sdp_proto_x && strcasecmp(m->m_proto_name, proto_name)))    return 0;  return 1;}/* Return 1 if media type and protocol of m= line structs matches */unsigned sdp_media_match_with(sdp_media_t const *a,			      sdp_media_t const *b){  if (a == NULL || b == NULL)    return a == b;  if (a->m_type == sdp_media_any || b->m_type == sdp_media_any)    return 1;  if (a->m_type != b->m_type ||      (a->m_type == sdp_media_x &&       strcasecmp(b->m_type_name, a->m_type_name)))    return 0;  if (a->m_proto == sdp_proto_any || b->m_proto == sdp_proto_any)    return 1;  if (a->m_proto != b->m_proto ||      (a->m_proto == sdp_proto_x &&       strcasecmp(b->m_proto_name, a->m_proto_name)))    return 0;  return 1;}/** Count matching media lines in SDP. */unsigned sdp_media_count(sdp_session_t const *sdp,			 sdp_media_e type,			 sdp_text_t *type_name,			 sdp_proto_e proto,			 sdp_text_t *proto_name){  unsigned count = 0;  sdp_media_t const *m;  if (sdp != NULL)    for (m = sdp->sdp_media; m; m = m->m_next)      count += sdp_media_match(m, type, type_name, proto, proto_name);  return count;}/** Count matching media lines in SDP. */unsigned sdp_media_count_with(sdp_session_t const *sdp,			      sdp_media_t const *m0){  unsigned count = 0;  sdp_media_t const *m;  if (sdp != NULL)    for (m = sdp->sdp_media; m; m = m->m_next)      count += sdp_media_match_with(m, m0);  return count;}/** Return true if media uses RTP */int sdp_media_uses_rtp(sdp_media_t const *m){  return m &&    (m->m_proto == sdp_proto_rtp ||     m->m_proto == sdp_proto_srtp ||     (m->m_proto == sdp_proto_x && m->m_proto_name &&      strncasecmp(m->m_proto_name, "RTP/", 4) == 0));}/** Check if payload type, rtp rate and parameters match in rtpmaps*/int sdp_rtpmap_match(sdp_rtpmap_t const *a, sdp_rtpmap_t const *b){  char const *aparam, *bparam;  if (a == b)    return 1;  if (a == 0 || b == 0)    return 0;  if (a->rm_rate != b->rm_rate)    return 0;  if (strcasecmp(a->rm_encoding, b->rm_encoding))    return 0;  aparam = a->rm_params; bparam = b->rm_params;  if (aparam == bparam)    return 1;  if (!aparam) aparam = "1"; if (!bparam) bparam = "1";    if (strcasecmp(aparam, bparam))    return 0;  return 1;}/** Search for matching rtpmap from list. * * @note * The a=fmtp: for the codecs are not compared. */sdp_rtpmap_t *sdp_rtpmap_find_matching(sdp_rtpmap_t const *list,				       sdp_rtpmap_t const *rm){  char const *lparam, *rparam;  if (rm == NULL)    return NULL;  for (; list; list = list->rm_next) {    if (rm->rm_rate != list->rm_rate)      continue;    if (strcasecmp(rm->rm_encoding, list->rm_encoding) != 0)      continue;    lparam = rm->rm_params; rparam = list->rm_params;    if (lparam == rparam)      break;    if (!lparam) lparam = "1"; if (!rparam) rparam = "1";    if (strcasecmp(lparam, rparam))      continue;    break;  }  return (sdp_rtpmap_t *)list;}

⌨️ 快捷键说明

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