/** Compare two session descriptions */ int sdp_session_cmp(sdp_session_t const *a, sdp_session_t const *b) { int rv; sdp_bandwidth_t const *ab, *bb; sdp_attribute_t const *aa, *ba; sdp_media_t const *am, *bm; if ((rv = (a != NULL) - (b != NULL))) return rv; if (a == b) return 0; if ((rv = (a->sdp_version[0] - b->sdp_version[0]))) return rv; if ((rv = sdp_origin_cmp(a->sdp_origin, b->sdp_origin))) return rv; if ((rv = su_strcmp(a->sdp_subject, b->sdp_subject))) return rv; if ((rv = su_strcmp(a->sdp_information, b->sdp_information))) return rv; if ((rv = su_strcmp(a->sdp_uri, b->sdp_uri))) return rv; if ((rv = sdp_list_cmp(a->sdp_emails, b->sdp_emails))) return rv; if ((rv = sdp_list_cmp(a->sdp_phones, b->sdp_phones))) return rv; if ((rv = sdp_connection_cmp(a->sdp_connection, b->sdp_connection))) return rv; for (ab = a->sdp_bandwidths, bb = b->sdp_bandwidths; ab || bb; ab = ab->b_next, bb = bb->b_next) if ((rv = sdp_bandwidth_cmp(a->sdp_bandwidths, b->sdp_bandwidths))) return rv; if ((rv = sdp_time_cmp(a->sdp_time, b->sdp_time))) return rv; if ((rv = sdp_key_cmp(a->sdp_key, b->sdp_key))) return rv; for (aa = a->sdp_attributes, ba = b->sdp_attributes; aa || bb; aa = aa->a_next, ba = ba->a_next) if ((rv = sdp_attribute_cmp(aa, ba))) return rv; for (am = a->sdp_media, bm = b->sdp_media; am || bm; am = am->m_next, bm = bm->m_next) if ((rv = sdp_media_cmp(am, bm))) return rv; return 0; }
/** Compare @SecurityVerify header with @SecurityServer header. */ int sip_security_verify_compare(sip_security_server_t const *s, sip_security_verify_t const *v, msg_param_t *return_d_ver) { size_t i, j; int retval, digest; msg_param_t const *s_params, *v_params, empty[] = { NULL }; if (return_d_ver) *return_d_ver = NULL; if (s == NULL) return 0; for (;;s = s->sa_next, v = v->sa_next) { if (s == NULL || v == NULL) return (s == NULL) - (v == NULL); if ((retval = su_strcmp(s->sa_mec, v->sa_mec))) return retval; digest = su_casematch(s->sa_mec, "Digest"); s_params = s->sa_params, v_params = v->sa_params; if (digest && s_params == NULL && v_params != NULL) s_params = empty; if (s_params == NULL || v_params == NULL) { if ((retval = (s_params == NULL) - (v_params == NULL))) return retval; continue; } for (i = 0, j = 0;; i++, j++) { if (digest && v_params[j] && su_casenmatch(v_params[j], "d-ver=", 6)) { if (return_d_ver) *return_d_ver = v_params[j] + strlen("d-ver="); j++; } retval = su_strcmp(s_params[i], v_params[j]); if (retval || s_params[i] == NULL || v_params[j] == NULL) break; } if (retval) return retval; } }
/** Compare two attribute (a=) fields */ int sdp_attribute_cmp(sdp_attribute_t const *a, sdp_attribute_t const *b) { int rv; if (a == b) return 0; if ((a != NULL) != (b != NULL)) return (a != NULL) < (b != NULL) ? -1 : 1; if ((rv = su_strcmp(a->a_name, b->a_name))) return rv; return su_strcmp(a->a_value, b->a_value); }
/** Compare two rtpmap structures. */ int sdp_rtpmap_cmp(sdp_rtpmap_t const *a, sdp_rtpmap_t const *b) { int rv; if (a == b) return 0; if ((a != NULL) != (b != NULL)) return (a != NULL) < (b != NULL) ? -1 : 1; if (a->rm_pt != b->rm_pt) return a->rm_pt < b->rm_pt ? -1 : 1; /* Case insensitive encoding */ if ((rv = su_strcmp(a->rm_encoding, b->rm_encoding))) return rv; /* Rate */ if (a->rm_rate != b->rm_rate) return a->rm_rate < b->rm_rate ? -1 : 1; { char const *a_param = "1", *b_param = "1"; if (a->rm_params) a_param = a->rm_params; if (b->rm_params) b_param = b->rm_params; rv = su_strcasecmp(a_param, b_param); if (rv) return rv; } return su_strcasecmp(a->rm_fmtp, b->rm_fmtp); }
/** Compare two key (k=) fields */ int sdp_key_cmp(sdp_key_t const *a, sdp_key_t const *b) { int rv; if (a == b) return 0; if ((a != NULL) != (b != NULL)) return (a != NULL) < (b != NULL) ? -1 : 1; if (a->k_method != b->k_method) return a->k_method < b->k_method ? -1 : 1; if (a->k_method == sdp_key_x && (rv = su_strcmp(a->k_method_name, b->k_method_name))) return rv; return su_strcmp(a->k_material, b->k_material); }
/** Compare two lists. */ int sdp_list_cmp(sdp_list_t const *a, sdp_list_t const *b) { int rv; for (;a || b; a = a->l_next, b = b->l_next) { if (a == b) return 0; if ((a != NULL) != (b != NULL)) return (a != NULL) < (b != NULL) ? -1 : 1; if ((rv = su_strcmp(a->l_text, b->l_text))) return rv; } return 0; }
/** Compare two media (m=) fields */ int sdp_media_cmp(sdp_media_t const *a, sdp_media_t const *b) { int rv; sdp_connection_t const *ac, *bc; sdp_bandwidth_t const *ab, *bb; sdp_rtpmap_t const *arm, *brm; sdp_attribute_t const *aa, *ba; if (a == b) return 0; if ((rv = (a != NULL) - (b != NULL))) return rv; if (a->m_type != b->m_type) return a->m_type < b->m_type ? -1 : 1; if (a->m_type == sdp_media_x) if ((rv = su_strcmp(a->m_type_name, b->m_type_name))) return rv; if (a->m_port != b->m_port) return a->m_port < b->m_port ? -1 : 1; if (a->m_port == 0 /* && b->m_port == 0 */) /* Ignore transport protocol and media list if media has been rejected */ return 0; if (a->m_number_of_ports != b->m_number_of_ports) return a->m_number_of_ports < b->m_number_of_ports ? -1 : 1; if (a->m_proto != b->m_proto) return a->m_proto < b->m_proto ? -1 : 1; if (a->m_proto == sdp_proto_x) if ((rv = su_strcmp(a->m_proto_name, b->m_proto_name))) return rv; if (a->m_mode != b->m_mode) return a->m_mode < b->m_mode ? -1 : 1; for (arm = a->m_rtpmaps, brm = b->m_rtpmaps; arm || brm; arm = arm->rm_next, brm = brm->rm_next) if ((rv = sdp_rtpmap_cmp(arm, brm))) return rv; if ((rv = sdp_list_cmp(a->m_format, b->m_format))) return rv; if ((rv = su_strcmp(a->m_information, b->m_information))) return rv; for (ac = a->m_connections, bc = b->m_connections; ac || bc; ac = ac->c_next, bc = bc->c_next) if ((rv = sdp_connection_cmp(ac, bc))) return rv; for (ab = a->m_bandwidths, bb = b->m_bandwidths; ab || bb; ab = ab->b_next, bb = bb->b_next) if ((rv = sdp_bandwidth_cmp(a->m_bandwidths, b->m_bandwidths))) return rv; if ((rv = sdp_key_cmp(a->m_key, b->m_key))) return rv; for (aa = a->m_attributes, ba = b->m_attributes; aa || bb; aa = aa->a_next, ba = ba->a_next) if ((rv = sdp_attribute_cmp(aa, ba))) return rv; return 0; }