/* * Adds repeat field to the time structure of session * r=<repeat interval> <active duration> <offsets from start-time> */ int sdp_add_repeat(sdp_time_t *time, uint64_t interval, uint64_t duration, const char *offset) { sdp_repeat_t *tmp; sdp_repeat_t *new_repeat; int ret = 0; if (time == NULL || offset == NULL) return (EINVAL); new_repeat = calloc(1, sizeof (sdp_repeat_t)); if (new_repeat == NULL) return (ENOMEM); new_repeat->r_interval = interval; new_repeat->r_duration = duration; if ((ret = sdp_str_to_list(&new_repeat->r_offset, offset, strlen(offset), B_FALSE)) != 0) { goto err_ret; } tmp = time->t_repeat; if (tmp == NULL) { time->t_repeat = new_repeat; } else { while (tmp->r_next != NULL) tmp = tmp->r_next; tmp->r_next = new_repeat; } return (ret); err_ret: sdp_free_repeat(new_repeat); return (ret); }
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); }
/* * repeat-fields (r=) * Not stand-alone. One or more repeat field appear after time field. * %x72 "=" repeat-interval SP typed-time 1*(SP typed-time) * repeat-interval = POS-DIGIT *DIGIT [fixed-len-time-unit] * typed-time = 1*DIGIT [fixed-len-time-unit] * fixed-len-time-unit = %x64 / %x68 / %x6d / %x73 */ static void sdp_parse_repeat(sdp_time_t *time, const char *begin, const char *end, uint_t *p_error) { const char *current; sdp_repeat_t *repeat; sdp_repeat_t *new_repeat; int ret; if (*begin++ != COMMP_EQUALS) { *p_error |= SDP_REPEAT_TIME_ERROR; return; } /* * A time field should be present before this field can occur, if * time is NULL then repeat field has occured before time field and * hence fields are out of order. */ if (time == NULL) return; /* * Get the latest time field and associate this repeat field * with it. */ while (time->t_next != NULL) time = time->t_next; new_repeat = calloc(1, sizeof (sdp_repeat_t)); if (new_repeat == NULL) { *p_error |= SDP_MEMORY_ERROR; return; } /* * for a given time field, there could be several repeat fields * add the new repeat field at the end of it. */ repeat = time->t_repeat; if (repeat == NULL) { time->t_repeat = new_repeat; } else { while (repeat->r_next != NULL) repeat = repeat->r_next; repeat->r_next = new_repeat; } /* * Populate the elements of sdp_repeat. * Get time-interval */ current = begin; if (commp_find_token(&begin, ¤t, end, COMMP_SP, B_FALSE) != 0) goto err_ret; if (commp_time_to_secs(begin, current, &new_repeat->r_interval) != 0) goto err_ret; /* Get duration. It could be the last sub-field */ begin = ++current; if (commp_find_token(&begin, ¤t, end, COMMP_SP, B_FALSE) != 0) goto err_ret; if (commp_time_to_secs(begin, current, &new_repeat->r_duration) != 0) goto err_ret; ++current; /* Get offsets into sdp_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 ((ret = add_value_to_list(&new_repeat->r_offset, begin, current - begin, B_FALSE)) != 0) { if (ret == ENOMEM) { *p_error |= SDP_MEMORY_ERROR; return; } else { goto err_ret; } } ++current; } /* check for trailing white space character. */ if (isspace(*(end - 1))) goto err_ret; return; err_ret: *p_error |= SDP_REPEAT_TIME_ERROR; if (repeat != NULL) repeat->r_next = NULL; else time->t_repeat = NULL; sdp_free_repeat(new_repeat); }