/* * attribute-fields (a=) * *(%x61 "=" attribute CRLF) * attribute = (att-field ":" att-value) / att-field * att-field = token * att-value = byte-string */ static void sdp_parse_attribute(sdp_attr_t **attr, const char *begin, const char *end, uint_t *p_error) { const char *current; sdp_attr_t *new_attr; sdp_attr_t *tmp; if (*begin++ != COMMP_EQUALS) { *p_error |= SDP_ATTRIBUTE_ERROR; return; } new_attr = calloc(1, sizeof (sdp_attr_t)); if (new_attr == NULL) { *p_error |= SDP_MEMORY_ERROR; return; } /* Get Attribute Name */ current = begin; if (commp_find_token(&begin, ¤t, end, COMMP_COLON, B_FALSE) != 0) { goto err_ret; } else { COMMP_COPY_STR(new_attr->a_name, begin, current - begin); if (new_attr->a_name == NULL) { sdp_free_attribute(new_attr); *p_error |= SDP_MEMORY_ERROR; return; } } /* Get Attribute Value */ if (*current == COMMP_COLON) { ++current; if (current == end) goto err_ret; COMMP_COPY_STR(new_attr->a_value, current, end - current); if (new_attr->a_value == NULL) { sdp_free_attribute(new_attr); *p_error |= SDP_MEMORY_ERROR; return; } } if (*attr == NULL) { *attr = new_attr; } else { tmp = *attr; while (tmp->a_next != NULL) tmp = tmp->a_next; tmp->a_next = new_attr; } return; err_ret: *p_error |= SDP_ATTRIBUTE_ERROR; sdp_free_attribute(new_attr); }
void sdp_free_media(sdp_media *media) { sdp_attribute *attr, *cattr; xfree(media->name); if(media->network != NULL) sdp_free_network(media->network); xfree(media->transport); xfree(media->format_list); if(media->information != NULL) xfree(media->information); if(media->bandwidth_modifier != NULL) sdp_free_bandwidth_modifier(media->bandwidth_modifier); if(media->encryption != NULL) sdp_free_encryption(media->encryption); attr = media->attributes; while(attr != NULL) { cattr = attr; attr = attr->next; sdp_free_attribute(cattr); } xfree(media); }
/* * Adds attribute field to session or media section of SDP. * a=<attribute> * a=<attribute>:<value> */ int sdp_add_attribute(sdp_attr_t **attr, const char *name, const char *value) { sdp_attr_t *tmp; sdp_attr_t *new_attr; int ret = 0; if (attr == NULL || name == NULL) return (EINVAL); new_attr = calloc(1, sizeof (sdp_attr_t)); if (new_attr == NULL) return (ENOMEM); if ((ret = commp_add_str(&new_attr->a_name, name, strlen(name))) != 0) goto err_ret; if (value != NULL) { if ((ret = commp_add_str(&new_attr->a_value, value, strlen(value))) != 0) { goto err_ret; } } tmp = *attr; if (tmp == NULL) { *attr = new_attr; } else { while (tmp->a_next != NULL) tmp = tmp->a_next; tmp->a_next = new_attr; } return (ret); err_ret: sdp_free_attribute(new_attr); return (ret); }
/* * Given a media structure and the field ('i', 'b', 'c', et al), this API * deletes the corresponding structure element. It frees the memory and sets * the pointer to NULL. */ int sdp_delete_all_media_field(sdp_media_t *media, const char field) { if (media == NULL) return (EINVAL); switch (field) { case SDP_INFO_FIELD: free(media->m_info); media->m_info = NULL; break; case SDP_CONNECTION_FIELD: sdp_free_connection(media->m_conn); media->m_conn = NULL; break; case SDP_BANDWIDTH_FIELD: sdp_free_bandwidth(media->m_bw); media->m_bw = NULL; break; case SDP_KEY_FIELD: sdp_free_key(media->m_key); media->m_key = NULL; break; case SDP_ATTRIBUTE_FIELD: sdp_free_attribute(media->m_attr); media->m_attr = NULL; break; default: return (EINVAL); } return (0); }
/* * Given an attribute list and an attribute, this API deletes that attribue * from the list. It frees the memory corresponding to that attribute. */ int sdp_delete_attribute(sdp_attr_t **l_attr, sdp_attr_t *attr) { sdp_attr_t *cur; sdp_attr_t *prev; if (l_attr == NULL || *l_attr == NULL || attr == NULL) return (EINVAL); cur = *l_attr; prev = NULL; while (cur != NULL && cur != attr) { prev = cur; cur = cur->a_next; } if (cur == NULL) return (EINVAL); if (cur == *l_attr) *l_attr = cur->a_next; else prev->a_next = cur->a_next; cur->a_next = NULL; sdp_free_attribute(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); }
/* * 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); }