sdp.c
来自「基于sip协议的网络电话源码」· C语言 代码 · 共 1,286 行 · 第 1/3 页
C
1,286 行
const pjmedia_sdp_rtpmap *rtpmap, pjmedia_sdp_attr **p_attr){ pjmedia_sdp_attr *attr; char tempbuf[128]; int len; /* Check arguments. */ PJ_ASSERT_RETURN(pool && rtpmap && p_attr, PJ_EINVAL); /* Check that mandatory attributes are specified. */ PJ_ASSERT_RETURN(rtpmap->enc_name.slen && rtpmap->clock_rate, PJMEDIA_SDP_EINRTPMAP); attr = pj_pool_alloc(pool, sizeof(pjmedia_sdp_attr)); PJ_ASSERT_RETURN(attr != NULL, PJ_ENOMEM); attr->name.ptr = "rtpmap"; attr->name.slen = 6; /* Format: ":pt enc_name/clock_rate[/param]" */ len = pj_ansi_snprintf(tempbuf, sizeof(tempbuf), "%.*s %.*s/%u%s%.*s", (int)rtpmap->pt.slen, rtpmap->pt.ptr, (int)rtpmap->enc_name.slen, rtpmap->enc_name.ptr, rtpmap->clock_rate, (rtpmap->param.slen ? "/" : ""), (int)rtpmap->param.slen, rtpmap->param.ptr); if (len < 1 || len > sizeof(tempbuf)) return PJMEDIA_SDP_ERTPMAPTOOLONG; attr->value.slen = len; attr->value.ptr = pj_pool_alloc(pool, attr->value.slen); pj_memcpy(attr->value.ptr, tempbuf, attr->value.slen); *p_attr = attr; return PJ_SUCCESS;}static int print_connection_info( pjmedia_sdp_conn *c, char *buf, int len){ int printed; printed = pj_ansi_snprintf(buf, len, "c=%.*s %.*s %.*s\r\n", (int)c->net_type.slen, c->net_type.ptr, (int)c->addr_type.slen, c->addr_type.ptr, (int)c->addr.slen, c->addr.ptr); if (printed < 1 || printed > len) return -1; return printed;}PJ_DEF(pjmedia_sdp_conn*) pjmedia_sdp_conn_clone (pj_pool_t *pool, const pjmedia_sdp_conn *rhs){ pjmedia_sdp_conn *c = pj_pool_alloc (pool, sizeof(pjmedia_sdp_conn)); if (!c) return NULL; if (!pj_strdup (pool, &c->net_type, &rhs->net_type)) return NULL; if (!pj_strdup (pool, &c->addr_type, &rhs->addr_type)) return NULL; if (!pj_strdup (pool, &c->addr, &rhs->addr)) return NULL; return c;}static pj_ssize_t print_attr(const pjmedia_sdp_attr *attr, char *buf, pj_size_t len){ char *p = buf; if ((int)len < attr->name.slen + attr->value.slen + 10) return -1; *p++ = 'a'; *p++ = '='; pj_memcpy(p, attr->name.ptr, attr->name.slen); p += attr->name.slen; if (attr->value.slen) { *p++ = ':'; pj_memcpy(p, attr->value.ptr, attr->value.slen); p += attr->value.slen; } *p++ = '\r'; *p++ = '\n'; return p-buf;}static int print_media_desc( pjmedia_sdp_media *m, char *buf, int len){ char *p = buf; char *end = buf+len; unsigned i; int printed; /* check length for the "m=" line. */ if (len < m->desc.media.slen+m->desc.transport.slen+12+24) { return -1; } *p++ = 'm'; /* m= */ *p++ = '='; pj_memcpy(p, m->desc.media.ptr, m->desc.media.slen); p += m->desc.media.slen; *p++ = ' '; printed = pj_utoa(m->desc.port, p); p += printed; if (m->desc.port_count > 1) { *p++ = '/'; printed = pj_utoa(m->desc.port_count, p); p += printed; } *p++ = ' '; pj_memcpy(p, m->desc.transport.ptr, m->desc.transport.slen); p += m->desc.transport.slen; for (i=0; i<m->desc.fmt_count; ++i) { *p++ = ' '; pj_memcpy(p, m->desc.fmt[i].ptr, m->desc.fmt[i].slen); p += m->desc.fmt[i].slen; } *p++ = '\r'; *p++ = '\n'; /* print connection info, if present. */ if (m->conn) { printed = print_connection_info(m->conn, p, end-p); if (printed < 0) { return -1; } p += printed; } /* print attributes. */ for (i=0; i<m->attr_count; ++i) { printed = print_attr(m->attr[i], p, end-p); if (printed < 0) { return -1; } p += printed; } return p-buf;}PJ_DEF(pjmedia_sdp_media*) pjmedia_sdp_media_clone( pj_pool_t *pool, const pjmedia_sdp_media *rhs){ unsigned int i; pjmedia_sdp_media *m = pj_pool_alloc (pool, sizeof(pjmedia_sdp_media)); PJ_ASSERT_RETURN(m != NULL, NULL); pj_strdup (pool, &m->desc.media, &rhs->desc.media); m->desc.port = rhs->desc.port; m->desc.port_count = rhs->desc.port_count; pj_strdup (pool, &m->desc.transport, &rhs->desc.transport); m->desc.fmt_count = rhs->desc.fmt_count; for (i=0; i<rhs->desc.fmt_count; ++i) pj_strdup(pool, &m->desc.fmt[i], &rhs->desc.fmt[i]); if (rhs->conn) { m->conn = pjmedia_sdp_conn_clone (pool, rhs->conn); PJ_ASSERT_RETURN(m->conn != NULL, NULL); } else { m->conn = NULL; } m->attr_count = rhs->attr_count; for (i=0; i < rhs->attr_count; ++i) { m->attr[i] = pjmedia_sdp_attr_clone (pool, rhs->attr[i]); PJ_ASSERT_RETURN(m->attr[i] != NULL, NULL); } return m;}PJ_DEF(pjmedia_sdp_attr*) pjmedia_sdp_media_find_attr(const pjmedia_sdp_media *m, const pj_str_t *name, const pj_str_t *fmt){ PJ_ASSERT_RETURN(m && name, NULL); return pjmedia_sdp_attr_find(m->attr_count, m->attr, name, fmt);}PJ_DEF(pjmedia_sdp_attr*) pjmedia_sdp_media_find_attr2(const pjmedia_sdp_media *m, const char *name, const pj_str_t *fmt){ PJ_ASSERT_RETURN(m && name, NULL); return pjmedia_sdp_attr_find2(m->attr_count, m->attr, name, fmt);}PJ_DEF(pj_status_t) pjmedia_sdp_media_add_attr( pjmedia_sdp_media *m, pjmedia_sdp_attr *attr){ return pjmedia_sdp_attr_add(&m->attr_count, m->attr, attr);}PJ_DEF(unsigned) pjmedia_sdp_media_remove_all_attr(pjmedia_sdp_media *m, const char *name){ return pjmedia_sdp_attr_remove_all(&m->attr_count, m->attr, name);}PJ_DEF(pj_status_t)pjmedia_sdp_media_remove_attr(pjmedia_sdp_media *m, pjmedia_sdp_attr *attr){ return pjmedia_sdp_attr_remove(&m->attr_count, m->attr, attr);}static int print_session(const pjmedia_sdp_session *ses, char *buf, pj_ssize_t len){ char *p = buf; char *end = buf+len; unsigned i; int printed; /* Check length for v= and o= lines. */ if (len < 5+ 2+ses->origin.user.slen+18+ ses->origin.net_type.slen+ses->origin.addr.slen + 2) { return -1; } /* SDP version (v= line) */ pj_memcpy(p, "v=0\r\n", 5); p += 5; /* Owner (o=) line. */ *p++ = 'o'; *p++ = '='; pj_memcpy(p, ses->origin.user.ptr, ses->origin.user.slen); p += ses->origin.user.slen; *p++ = ' '; printed = pj_utoa(ses->origin.id, p); p += printed; *p++ = ' '; printed = pj_utoa(ses->origin.version, p); p += printed; *p++ = ' '; pj_memcpy(p, ses->origin.net_type.ptr, ses->origin.net_type.slen); p += ses->origin.net_type.slen; *p++ = ' '; pj_memcpy(p, ses->origin.addr_type.ptr, ses->origin.addr_type.slen); p += ses->origin.addr_type.slen; *p++ = ' '; pj_memcpy(p, ses->origin.addr.ptr, ses->origin.addr.slen); p += ses->origin.addr.slen; *p++ = '\r'; *p++ = '\n'; /* Session name (s=) line. */ if ((end-p) < 8+ses->name.slen) { return -1; } *p++ = 's'; *p++ = '='; pj_memcpy(p, ses->name.ptr, ses->name.slen); p += ses->name.slen; *p++ = '\r'; *p++ = '\n'; /* Connection line (c=) if exist. */ if (ses->conn) { printed = print_connection_info(ses->conn, p, end-p); if (printed < 1) { return -1; } p += printed; } /* Time */ if ((end-p) < 24) { return -1; } *p++ = 't'; *p++ = '='; printed = pj_utoa(ses->time.start, p); p += printed; *p++ = ' '; printed = pj_utoa(ses->time.stop, p); p += printed; *p++ = '\r'; *p++ = '\n'; /* Print all attribute (a=) lines. */ for (i=0; i<ses->attr_count; ++i) { printed = print_attr(ses->attr[i], p, end-p); if (printed < 0) { return -1; } p += printed; } /* Print media (m=) lines. */ for (i=0; i<ses->media_count; ++i) { printed = print_media_desc(ses->media[i], p, end-p); if (printed < 0) { return -1; } p += printed; } return p-buf;}/****************************************************************************** * PARSERS */static void parse_version(pj_scanner *scanner, parse_context *ctx){ ctx->last_error = PJMEDIA_SDP_EINVER; /* check equal sign */ if (*(scanner->curptr+1) != '=') { on_scanner_error(scanner); return; } /* check version is 0 */ if (*(scanner->curptr+2) != '0') { on_scanner_error(scanner); return; } /* We've got what we're looking for, skip anything until newline */ pj_scan_skip_line(scanner);}static void parse_origin(pj_scanner *scanner, pjmedia_sdp_session *ses, parse_context *ctx){ pj_str_t str; ctx->last_error = PJMEDIA_SDP_EINORIGIN; /* check equal sign */ if (*(scanner->curptr+1) != '=') { on_scanner_error(scanner); return; } /* o= */ pj_scan_advance_n(scanner, 2, SKIP_WS); /* username. */ pj_scan_get_until_ch(scanner, ' ', &ses->origin.user); pj_scan_get_char(scanner); /* id */ pj_scan_get_until_ch(scanner, ' ', &str); ses->origin.id = pj_strtoul(&str); pj_scan_get_char(scanner); /* version */ pj_scan_get_until_ch(scanner, ' ', &str); ses->origin.version = pj_strtoul(&str); pj_scan_get_char(scanner); /* network-type */ pj_scan_get_until_ch(scanner, ' ', &ses->origin.net_type); pj_scan_get_char(scanner); /* addr-type */ pj_scan_get_until_ch(scanner, ' ', &ses->origin.addr_type); pj_scan_get_char(scanner); /* address */ pj_scan_get_until_chr(scanner, " \t\r", &ses->origin.addr); /* We've got what we're looking for, skip anything until newline */ pj_scan_skip_line(scanner);}static void parse_time(pj_scanner *scanner, pjmedia_sdp_session *ses, parse_context *ctx){ pj_str_t str; ctx->last_error = PJMEDIA_SDP_EINTIME; /* check equal sign */ if (*(scanner->curptr+1) != '=') { on_scanner_error(scanner); return; } /* t= */ pj_scan_advance_n(scanner, 2, SKIP_WS); /* start time */ pj_scan_get_until_ch(scanner, ' ', &str); ses->time.start = pj_strtoul(&str); pj_scan_get_char(scanner); /* stop time */ pj_scan_get_until_chr(scanner, " \t\r", &str); ses->time.stop = pj_strtoul(&str); /* We've got what we're looking for, skip anything until newline */ pj_scan_skip_line(scanner);}static void parse_generic_line(pj_scanner *scanner, pj_str_t *str, parse_context *ctx){
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?