/* * Adds media field to the session. * m=<media> <port>[/portcount] <proto> <fmt> ... */ int sdp_add_media(sdp_session_t *session, const char *name, uint_t port, int portcount, const char *protocol, const char *fmt, sdp_media_t **media) { sdp_media_t *tmp; sdp_media_t *new_media; int ret = 0; if (media != NULL) *media = NULL; if (session == NULL || name == NULL || protocol == NULL || portcount <= 0 || fmt == NULL) { return (EINVAL); } new_media = calloc(1, sizeof (sdp_media_t)); if (new_media == NULL) { return (ENOMEM); } new_media->m_session = session; new_media->m_port = port; new_media->m_portcount = portcount; if ((ret = commp_add_str(&new_media->m_name, name, strlen(name))) != 0) goto err_ret; if ((ret = commp_add_str(&new_media->m_proto, protocol, strlen(protocol))) != 0) { goto err_ret; } if ((ret = sdp_str_to_list(&new_media->m_format, fmt, strlen(fmt), B_TRUE)) != 0) { goto err_ret; } tmp = session->s_media; if (tmp == NULL) { session->s_media = new_media; } else { while (tmp->m_next != NULL) tmp = tmp->m_next; tmp->m_next = new_media; } if (media != NULL) *media = new_media; return (0); err_ret: sdp_free_media(new_media); return (ret); }
/* * Given a media list and the media, this API deletes that media from the * list. It frees the memory corresponding to that media. */ int sdp_delete_media(sdp_media_t **l_media, sdp_media_t *media) { sdp_media_t *cur; sdp_media_t *prev; if (l_media == NULL || *l_media == NULL || media == NULL) return (EINVAL); cur = *l_media; prev = NULL; while (cur != NULL && cur != media) { prev = cur; cur = cur->m_next; } if (cur == NULL) return (EINVAL); if (cur == *l_media) *l_media = cur->m_next; else prev->m_next = cur->m_next; cur->m_next = NULL; sdp_free_media(cur); return (0); }
void sdp_free(sdp *session) { sdp_media *media, *cmedia; sdp_attribute *attr, *cattr; sdp_repeat *repeat, *crepeat; if(session->username != NULL) xfree(session->username); if(session->session_id != NULL) xfree(session->session_id); if(session->network != NULL) sdp_free_network(session->network); if(session->name != NULL) xfree(session->name); if(session->information != NULL) xfree(session->information); if(session->uri != NULL) xfree(session->uri); if(session->email != NULL) xfree(session->email); if(session->phone != NULL) xfree(session->phone); if(session->bandwidth_modifier != NULL) sdp_free_bandwidth_modifier(session->bandwidth_modifier); if(session->timezones != NULL) xfree(session->timezones); if(session->encryption != NULL) sdp_free_encryption(session->encryption); repeat = session->repeats; while(repeat != NULL) { crepeat = repeat; repeat = repeat->next; sdp_free_repeat(crepeat); } attr = session->attributes; while(attr != NULL) { cattr = attr; attr = attr->next; sdp_free_attribute(cattr); } media = session->media; while(media != NULL) { cmedia = media; media = media->next; sdp_free_media(cmedia); } if(session->original != NULL) xfree(session->original); xfree(session); }
/* * media-field (m=) * %x6d "=" media SP port ["/" integer] SP proto 1*(SP fmt) CRLF */ static sdp_media_t * sdp_parse_media(sdp_session_t *session, const char *begin, const char *end, uint_t *p_error) { const char *current; const char *fake_end; sdp_media_t *new_media; sdp_media_t *tmp; if (*begin++ != COMMP_EQUALS) { *p_error |= SDP_MEDIA_ERROR; return (NULL); } new_media = calloc(1, sizeof (sdp_media_t)); if (new_media == NULL) { *p_error |= SDP_MEMORY_ERROR; return (NULL); } new_media->m_session = session; /* Get media name */ current = begin; if (commp_find_token(&begin, ¤t, end, COMMP_SP, B_FALSE) != 0) { goto err_ret; } else { COMMP_COPY_STR(new_media->m_name, begin, current - begin); if (new_media->m_name == NULL) { sdp_free_media(new_media); *p_error |= SDP_MEMORY_ERROR; return (NULL); } } /* Get port */ begin = ++current; if (commp_find_token(&begin, ¤t, end, COMMP_SP, B_FALSE) != 0) goto err_ret; fake_end = current; current = begin; if (commp_find_token(&begin, ¤t, fake_end, COMMP_SLASH, B_FALSE) != 0) { goto err_ret; } if (commp_atoui(begin, current, &new_media->m_port) != 0) goto err_ret; /* Get portcount */ if (*current == COMMP_SLASH) { begin = ++current; if (commp_find_token(&begin, ¤t, fake_end, COMMP_SP, B_FALSE) != 0) { goto err_ret; } if (commp_atoi(begin, current, &new_media->m_portcount) != 0) goto err_ret; } else { new_media->m_portcount = 1; } /* Get Protocol */ begin = ++current; if (commp_find_token(&begin, ¤t, end, COMMP_SP, B_FALSE) != 0) { goto err_ret; } else { COMMP_COPY_STR(new_media->m_proto, begin, current - begin); if (new_media->m_proto == NULL) { sdp_free_media(new_media); *p_error |= SDP_MEMORY_ERROR; return (NULL); } } ++current; /* Get format list */ if (current >= end) goto err_ret; while (current < end) { begin = current; if (commp_find_token(&begin, ¤t, end, COMMP_SP, B_FALSE) != 0) { goto err_ret; } if (add_value_to_list(&new_media->m_format, begin, current - begin, B_TRUE) != 0) { sdp_free_media(new_media); *p_error |= SDP_MEMORY_ERROR; return (NULL); } ++current; } /* check for trailing white space character. */ if (isspace(*(end - 1))) goto err_ret; /* Assign new media to the media list */ tmp = session->s_media; if (tmp == NULL) { session->s_media = new_media; } else { while (tmp->m_next != NULL) tmp = tmp->m_next; tmp->m_next = new_media; } return (new_media); err_ret: *p_error |= SDP_MEDIA_ERROR; sdp_free_media(new_media); return (NULL); }
/* * Given a session structure and the field ('v', 'o', 's', et al), this API * deletes the corresponding structure element. It frees the memory and sets the * pointer to NULL */ int sdp_delete_all_field(sdp_session_t *session, const char field) { if (session == NULL) return (EINVAL); switch (field) { case SDP_ORIGIN_FIELD: sdp_free_origin(session->s_origin); session->s_origin = NULL; break; case SDP_NAME_FIELD: free(session->s_name); session->s_name = NULL; break; case SDP_INFO_FIELD: free(session->s_info); session->s_info = NULL; break; case SDP_URI_FIELD: free(session->s_uri); session->s_uri = NULL; break; case SDP_EMAIL_FIELD: sdp_free_list(session->s_email); session->s_email = NULL; break; case SDP_PHONE_FIELD: sdp_free_list(session->s_phone); session->s_phone = NULL; break; case SDP_CONNECTION_FIELD: sdp_free_connection(session->s_conn); session->s_conn = NULL; break; case SDP_BANDWIDTH_FIELD: sdp_free_bandwidth(session->s_bw); session->s_bw = NULL; break; case SDP_TIME_FIELD: sdp_free_time(session->s_time); session->s_time = NULL; break; case SDP_ZONE_FIELD: sdp_free_zone(session->s_zone); session->s_zone = NULL; break; case SDP_KEY_FIELD: sdp_free_key(session->s_key); session->s_key = NULL; break; case SDP_ATTRIBUTE_FIELD: sdp_free_attribute(session->s_attr); session->s_attr = NULL; break; case SDP_MEDIA_FIELD: sdp_free_media(session->s_media); session->s_media = NULL; break; default: return (EINVAL); } return (0); }