sdp.c revision a93a1f58a8763fa69172980b98e3d24720c1136e
a93a1f58a8763fa69172980b98e3d24720c1136egm * CDDL HEADER START
a93a1f58a8763fa69172980b98e3d24720c1136egm * The contents of this file are subject to the terms of the
a93a1f58a8763fa69172980b98e3d24720c1136egm * Common Development and Distribution License (the "License").
a93a1f58a8763fa69172980b98e3d24720c1136egm * You may not use this file except in compliance with the License.
a93a1f58a8763fa69172980b98e3d24720c1136egm * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
a93a1f58a8763fa69172980b98e3d24720c1136egm * See the License for the specific language governing permissions
a93a1f58a8763fa69172980b98e3d24720c1136egm * and limitations under the License.
a93a1f58a8763fa69172980b98e3d24720c1136egm * When distributing Covered Code, include this CDDL HEADER in each
a93a1f58a8763fa69172980b98e3d24720c1136egm * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
a93a1f58a8763fa69172980b98e3d24720c1136egm * If applicable, add the following below this CDDL HEADER, with the
a93a1f58a8763fa69172980b98e3d24720c1136egm * fields enclosed by brackets "[]" replaced with your own identifying
a93a1f58a8763fa69172980b98e3d24720c1136egm * information: Portions Copyright [yyyy] [name of copyright owner]
a93a1f58a8763fa69172980b98e3d24720c1136egm * CDDL HEADER END
a93a1f58a8763fa69172980b98e3d24720c1136egm * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
a93a1f58a8763fa69172980b98e3d24720c1136egm * Use is subject to license terms.
a93a1f58a8763fa69172980b98e3d24720c1136egm#pragma ident "%Z%%M% %I% %E% SMI"
a93a1f58a8763fa69172980b98e3d24720c1136egm * Contains implementation of various interfaces exported by library
a93a1f58a8763fa69172980b98e3d24720c1136egm#define FIELD_EQUALS_CRLF_LEN 4 /* first two characters and CRLF */
a93a1f58a8763fa69172980b98e3d24720c1136egm } else { \
a93a1f58a8763fa69172980b98e3d24720c1136egm } else { \
a93a1f58a8763fa69172980b98e3d24720c1136egm wrote = snprintf(buf, len, "i=%s%s", (m_info), COMMP_CRLF); \
a93a1f58a8763fa69172980b98e3d24720c1136egm } else { \
a93a1f58a8763fa69172980b98e3d24720c1136egm } else { \
a93a1f58a8763fa69172980b98e3d24720c1136egm } else { \
a93a1f58a8763fa69172980b98e3d24720c1136egm return (NULL); \
a93a1f58a8763fa69172980b98e3d24720c1136egm return (NULL); \
a93a1f58a8763fa69172980b98e3d24720c1136egm return (NULL); \
a93a1f58a8763fa69172980b98e3d24720c1136egm return (NULL); \
a93a1f58a8763fa69172980b98e3d24720c1136egm len += snprintf(buf, 1, "%d", (m_conn)->c_addrcount) + 1; \
a93a1f58a8763fa69172980b98e3d24720c1136egm * Given a media list and media name ("audio", "video", et al), it searches
a93a1f58a8763fa69172980b98e3d24720c1136egm * the list for that media. Returns NULL if media not present.
a93a1f58a8763fa69172980b98e3d24720c1136egm if (media == NULL || name == NULL || (strlen(name) == 0)) {
a93a1f58a8763fa69172980b98e3d24720c1136egm * Given a attribute list and name of the attribute ("rtpmap", "fmtp", et al),
a93a1f58a8763fa69172980b98e3d24720c1136egm * this API searches the list for that attribute. Returns NULL if not found.
a93a1f58a8763fa69172980b98e3d24720c1136egm if (attr == NULL || name == NULL || (strlen(name) == 0)) {
a93a1f58a8763fa69172980b98e3d24720c1136egm * Given a media list and a format number, this API will return the rtpmap
a93a1f58a8763fa69172980b98e3d24720c1136egm * attribute matching the format number.
a93a1f58a8763fa69172980b98e3d24720c1136egmsdp_find_media_rtpmap(sdp_media_t *media, const char *format)
a93a1f58a8763fa69172980b98e3d24720c1136egm if (media == NULL || format == NULL || (strlen(format) == 0)) {
a93a1f58a8763fa69172980b98e3d24720c1136egm * Adds origin field to the session.
a93a1f58a8763fa69172980b98e3d24720c1136egm * o=<username> <sess-id> <sess-version> <nettype> <addrtype> <unicast-address>
a93a1f58a8763fa69172980b98e3d24720c1136egmsdp_add_origin(sdp_session_t *session, const char *name, uint64_t id,
a93a1f58a8763fa69172980b98e3d24720c1136egm const char *address)
a93a1f58a8763fa69172980b98e3d24720c1136egm if (session == NULL || name == NULL || nettype == NULL ||
a93a1f58a8763fa69172980b98e3d24720c1136egm if ((ret = commp_add_str(&origin->o_username, name, strlen(name))) != 0)
a93a1f58a8763fa69172980b98e3d24720c1136egm * Adds session name field to the session.
a93a1f58a8763fa69172980b98e3d24720c1136egm * s=<session name>
a93a1f58a8763fa69172980b98e3d24720c1136egm return (commp_add_str(&session->s_name, name, strlen(name)));
a93a1f58a8763fa69172980b98e3d24720c1136egm * Adds session information field to the session or media section of SDP.
a93a1f58a8763fa69172980b98e3d24720c1136egm * i=<session description>
a93a1f58a8763fa69172980b98e3d24720c1136egmsdp_add_information(char **information, const char *value)
a93a1f58a8763fa69172980b98e3d24720c1136egm return (commp_add_str(information, value, strlen(value)));
a93a1f58a8763fa69172980b98e3d24720c1136egm * Adds uri field to the session.
a93a1f58a8763fa69172980b98e3d24720c1136egm return (commp_add_str(&session->s_uri, uri, strlen(uri)));
a93a1f58a8763fa69172980b98e3d24720c1136egm * Adds email address field to the session.
a93a1f58a8763fa69172980b98e3d24720c1136egm * e=<email-address>
a93a1f58a8763fa69172980b98e3d24720c1136egm if (session == NULL || email == NULL || (strlen(email) == 0))
a93a1f58a8763fa69172980b98e3d24720c1136egm return (add_value_to_list(&session->s_email, email, strlen(email),
a93a1f58a8763fa69172980b98e3d24720c1136egm * Adds phone number field to the session.
a93a1f58a8763fa69172980b98e3d24720c1136egm * p=<phone-number>
a93a1f58a8763fa69172980b98e3d24720c1136egm if (session == NULL || phone == NULL || (strlen(phone) == 0))
a93a1f58a8763fa69172980b98e3d24720c1136egm return (add_value_to_list(&session->s_phone, phone, strlen(phone),
a93a1f58a8763fa69172980b98e3d24720c1136egm * Adds connection field to the session or media section of SDP
a93a1f58a8763fa69172980b98e3d24720c1136egm * c=<nettype> <addrtype> <connection-address>[/ttl]/<number of addresses>
a93a1f58a8763fa69172980b98e3d24720c1136egmsdp_add_connection(sdp_conn_t **conn, const char *nettype, const char *addrtype,
a93a1f58a8763fa69172980b98e3d24720c1136egm if (conn == NULL || nettype == NULL || addrtype == NULL ||
a93a1f58a8763fa69172980b98e3d24720c1136egm if ((ret = commp_add_str(&new_conn->c_addrtype, addrtype,
a93a1f58a8763fa69172980b98e3d24720c1136egm * Adds bandwidth field to the session or media section of SDP.
a93a1f58a8763fa69172980b98e3d24720c1136egm * b=<bwtype>:<bandwidth>
a93a1f58a8763fa69172980b98e3d24720c1136egmsdp_add_bandwidth(sdp_bandwidth_t **bw, const char *type, uint64_t value)
a93a1f58a8763fa69172980b98e3d24720c1136egm if ((ret = commp_add_str(&new_bw->b_type, type, strlen(type))) != 0) {
a93a1f58a8763fa69172980b98e3d24720c1136egm * Adds time field to the session
a93a1f58a8763fa69172980b98e3d24720c1136egm * t=<start-time> <stop-time>
a93a1f58a8763fa69172980b98e3d24720c1136egmsdp_add_time(sdp_session_t *session, uint64_t starttime, uint64_t stoptime,
a93a1f58a8763fa69172980b98e3d24720c1136egm return (0);
a93a1f58a8763fa69172980b98e3d24720c1136egm * Adds repeat field to the time structure of session
a93a1f58a8763fa69172980b98e3d24720c1136egm * r=<repeat interval> <active duration> <offsets from start-time>
a93a1f58a8763fa69172980b98e3d24720c1136egmsdp_add_repeat(sdp_time_t *time, uint64_t interval, uint64_t duration,
a93a1f58a8763fa69172980b98e3d24720c1136egm const char *offset)
a93a1f58a8763fa69172980b98e3d24720c1136egm if ((ret = sdp_str_to_list(&new_repeat->r_offset, offset,
a93a1f58a8763fa69172980b98e3d24720c1136egm * Adds time zone field to the session
a93a1f58a8763fa69172980b98e3d24720c1136egm * z=<adjustment time> <offset> <adjustment time> <offset> ....
a93a1f58a8763fa69172980b98e3d24720c1136egmsdp_add_zone(sdp_session_t *session, uint64_t time, const char *offset)
a93a1f58a8763fa69172980b98e3d24720c1136egm * Adds key field to session or media section of SDP.
a93a1f58a8763fa69172980b98e3d24720c1136egm * k=<method>
a93a1f58a8763fa69172980b98e3d24720c1136egm * k=<method>:<encryption key>
a93a1f58a8763fa69172980b98e3d24720c1136egmsdp_add_key(sdp_key_t **key, const char *method, const char *enckey)
a93a1f58a8763fa69172980b98e3d24720c1136egm * Adds attribute field to session or media section of SDP.
a93a1f58a8763fa69172980b98e3d24720c1136egm * a=<attribute>
a93a1f58a8763fa69172980b98e3d24720c1136egm * a=<attribute>:<value>
a93a1f58a8763fa69172980b98e3d24720c1136egmsdp_add_attribute(sdp_attr_t **attr, const char *name, const char *value)
a93a1f58a8763fa69172980b98e3d24720c1136egm if ((ret = commp_add_str(&new_attr->a_name, name, strlen(name))) != 0)
a93a1f58a8763fa69172980b98e3d24720c1136egm * Adds media field to the session.
a93a1f58a8763fa69172980b98e3d24720c1136egm * m=<media> <port>[/portcount] <proto> <fmt> ...
a93a1f58a8763fa69172980b98e3d24720c1136egmsdp_add_media(sdp_session_t *session, const char *name, uint_t port,
a93a1f58a8763fa69172980b98e3d24720c1136egm int portcount, const char *protocol, const char *fmt, sdp_media_t **media)
a93a1f58a8763fa69172980b98e3d24720c1136egm if (session == NULL || name == NULL || protocol == NULL ||
a93a1f58a8763fa69172980b98e3d24720c1136egm if ((ret = commp_add_str(&new_media->m_name, name, strlen(name))) != 0)
a93a1f58a8763fa69172980b98e3d24720c1136egm return (0);
a93a1f58a8763fa69172980b98e3d24720c1136egm * This internal API is required by sdp_session_to_str(). It determines the
a93a1f58a8763fa69172980b98e3d24720c1136egm * length of buffer that is required to hold the session. Since the RFC does
a93a1f58a8763fa69172980b98e3d24720c1136egm * not limit the size of various sub-fields in the field. We need to scan
a93a1f58a8763fa69172980b98e3d24720c1136egm * through the structure to determine the length.
a93a1f58a8763fa69172980b98e3d24720c1136egm len += snprintf(buf, 1, "%llu", session->s_origin->o_id) + 1;
a93a1f58a8763fa69172980b98e3d24720c1136egm len += snprintf(buf, 1, "%llu", session->s_origin->o_version)
a93a1f58a8763fa69172980b98e3d24720c1136egm len += strlen((char *)list->value) + FIELD_EQUALS_CRLF_LEN;
a93a1f58a8763fa69172980b98e3d24720c1136egm len += strlen((char *)list->value) + FIELD_EQUALS_CRLF_LEN;
a93a1f58a8763fa69172980b98e3d24720c1136egm * Given a session structure it clones (deep copy) and returns the cloned copy
a93a1f58a8763fa69172980b98e3d24720c1136egm new_sess->sdp_session_version = session->sdp_session_version;
a93a1f58a8763fa69172980b98e3d24720c1136egm if (origin != NULL && (sdp_add_origin(new_sess, origin->o_username,
a93a1f58a8763fa69172980b98e3d24720c1136egm origin->o_id, origin->o_version, origin->o_nettype, origin->
a93a1f58a8763fa69172980b98e3d24720c1136egm if (session->s_name != NULL && sdp_add_name(new_sess, session->
a93a1f58a8763fa69172980b98e3d24720c1136egm if (session->s_info != NULL && sdp_add_information(&new_sess->
a93a1f58a8763fa69172980b98e3d24720c1136egm if (session->s_uri != NULL && sdp_add_uri(new_sess, session->
a93a1f58a8763fa69172980b98e3d24720c1136egm if (sdp_add_zone(new_sess, zone->z_time, zone->z_offset) != 0)
a93a1f58a8763fa69172980b98e3d24720c1136egm if (sdp_list_to_str(media->m_format, &format, B_TRUE) != 0)
a93a1f58a8763fa69172980b98e3d24720c1136egm * should i check if individual members are NULL, if not snprintf
a93a1f58a8763fa69172980b98e3d24720c1136egm * will core dump.
a93a1f58a8763fa69172980b98e3d24720c1136egm * Given a session structure, this API converts it into character
a93a1f58a8763fa69172980b98e3d24720c1136egm * buffer, which will be used as a payload later on.
a93a1f58a8763fa69172980b98e3d24720c1136egmsdp_session_to_str(const sdp_session_t *session, int *error)
a93a1f58a8763fa69172980b98e3d24720c1136egm wrote = snprintf(buf, len, "v=%d%s", session->s_version, COMMP_CRLF);
a93a1f58a8763fa69172980b98e3d24720c1136egm origin->o_nettype, origin->o_addrtype, origin->o_address,
a93a1f58a8763fa69172980b98e3d24720c1136egm wrote = snprintf(buf, len, "e=%s%s", (char *)list->value,
a93a1f58a8763fa69172980b98e3d24720c1136egm wrote = snprintf(buf, len, "p=%s%s", (char *)list->value,
a93a1f58a8763fa69172980b98e3d24720c1136egm wrote = snprintf(buf, len, "t=%llu %llu%s", time->t_start,
a93a1f58a8763fa69172980b98e3d24720c1136egm * Given a session structure and the field ('v', 'o', 's', et al), this API
a93a1f58a8763fa69172980b98e3d24720c1136egm * deletes the corresponding structure element. It frees the memory and sets the
a93a1f58a8763fa69172980b98e3d24720c1136egm * pointer to NULL
a93a1f58a8763fa69172980b98e3d24720c1136egmsdp_delete_all_field(sdp_session_t *session, const char field)
a93a1f58a8763fa69172980b98e3d24720c1136egm switch (field) {
a93a1f58a8763fa69172980b98e3d24720c1136egm return (0);
a93a1f58a8763fa69172980b98e3d24720c1136egm * Given a media structure and the field ('i', 'b', 'c', et al), this API
a93a1f58a8763fa69172980b98e3d24720c1136egm * deletes the corresponding structure element. It frees the memory and sets
a93a1f58a8763fa69172980b98e3d24720c1136egm * the pointer to NULL.
a93a1f58a8763fa69172980b98e3d24720c1136egmsdp_delete_all_media_field(sdp_media_t *media, const char field)
a93a1f58a8763fa69172980b98e3d24720c1136egm switch (field) {
a93a1f58a8763fa69172980b98e3d24720c1136egm return (0);
a93a1f58a8763fa69172980b98e3d24720c1136egm * Given a media list and the media, this API deletes that media from the
a93a1f58a8763fa69172980b98e3d24720c1136egm * list. It frees the memory corresponding to that media.
a93a1f58a8763fa69172980b98e3d24720c1136egmsdp_delete_media(sdp_media_t **l_media, sdp_media_t *media)
a93a1f58a8763fa69172980b98e3d24720c1136egm if (l_media == NULL || *l_media == NULL || media == NULL)
a93a1f58a8763fa69172980b98e3d24720c1136egm return (0);
a93a1f58a8763fa69172980b98e3d24720c1136egm * Given an attribute list and an attribute, this API deletes that attribue
a93a1f58a8763fa69172980b98e3d24720c1136egm * from the list. It frees the memory corresponding to that attribute.
a93a1f58a8763fa69172980b98e3d24720c1136egmsdp_delete_attribute(sdp_attr_t **l_attr, sdp_attr_t *attr)
a93a1f58a8763fa69172980b98e3d24720c1136egm return (0);
a93a1f58a8763fa69172980b98e3d24720c1136egm * Allocates a new sdp session structure and assigns a version number to it.
a93a1f58a8763fa69172980b98e3d24720c1136egm * Currently one version is defined and it is 1. This will be useful in future
a93a1f58a8763fa69172980b98e3d24720c1136egm * in the unlikely need to change the structure.