int rtp_payload_type_cmp(const struct rtp_payload_type *a, const struct rtp_payload_type *b) { if (a->payload_type != b->payload_type) return 1; if (a->clock_rate != b->clock_rate) return 1; if (a->channels != b->channels) return 1; if (str_cmp_str(&a->encoding_with_params, &b->encoding_with_params)) return 1; if (str_cmp_str(&a->format_parameters, &b->format_parameters)) return 1; return 0; }
// for one-time init only - better use rtp_get_rfc_payload_type(codec_def->rfc_payload_type) const struct rtp_payload_type *rtp_get_rfc_codec(const str *codec) { for (int i = 0; i < num_rfc_rtp_payload_types; i++) { if (!rfc_rtp_payload_types[i].encoding.s) continue; if (str_cmp_str(codec, &rfc_rtp_payload_types[i].encoding)) continue; return &rfc_rtp_payload_types[i]; } return NULL; }
/* called with the call lock held in W, hence agent doesn't need to be locked */ void ice_update(struct ice_agent *ag, struct stream_params *sp) { GList *l, *k; struct ice_candidate *cand, *dup; struct call_media *media; struct call *call; int recalc = 0; unsigned int comps; struct packet_stream *components[MAX_COMPONENTS], *ps; GQueue *candidates; if (!ag) return; atomic64_set(&ag->last_activity, poller_now); media = ag->media; call = media->call; __role_change(ag, MEDIA_ISSET(media, ICE_CONTROLLING)); if (sp) { /* check for ICE restarts */ if (ag->ufrag[0].s && sp->ice_ufrag.s && str_cmp_str(&ag->ufrag[0], &sp->ice_ufrag)) __ice_restart(ag); else if (ag->pwd[0].s && sp->ice_pwd.s && str_cmp_str(&ag->pwd[0], &sp->ice_pwd)) __ice_restart(ag); else if (ag->local_interface != media->interface) __ice_restart(ag); /* update remote info */ if (sp->ice_ufrag.s) call_str_cpy(call, &ag->ufrag[0], &sp->ice_ufrag); if (sp->ice_pwd.s) call_str_cpy(call, &ag->pwd[0], &sp->ice_pwd); candidates = &sp->ice_candidates; } else /* this is a dummy update in case rtcp-mux has changed */ candidates = &ag->remote_candidates; /* get our component streams */ ZERO(components); comps = 0; for (l = media->streams.head; l; l = l->next) components[comps++] = l->data; if (comps == 2 && MEDIA_ISSET(media, RTCP_MUX)) components[1] = NULL; comps = 0; for (l = candidates->head; l; l = l->next) { if (ag->remote_candidates.length >= MAX_ICE_CANDIDATES) { ilog(LOG_WARNING, "Maxmimum number of ICE candidates exceeded"); break; } cand = l->data; /* skip invalid */ if (!cand->component_id || cand->component_id > G_N_ELEMENTS(components)) continue; ps = components[cand->component_id - 1]; if (ps) /* only count active components */ comps = MAX(comps, cand->component_id); dup = g_hash_table_lookup(ag->candidate_hash, cand); if (!sp && dup) /* this isn't a real update, so only check pairings */ goto pair; /* check for duplicates */ if (dup) { /* if this is peer reflexive, we've learned it through STUN. * otherwise it's simply one we've seen before. */ if (dup->type == ICT_PRFLX) { ilog(LOG_DEBUG, "Replacing previously learned prflx ICE candidate with " STR_FORMAT":%lu", STR_FMT(&cand->foundation), cand->component_id); } else { /* if the new one has higher priority then the old one, then we * update it, otherwise we just drop it */ if (cand->priority <= dup->priority) { ilog(LOG_DEBUG, "Dropping new ICE candidate "STR_FORMAT" in favour of " STR_FORMAT":%lu", STR_FMT(&cand->foundation), STR_FMT(&dup->foundation), cand->component_id); continue; } ilog(LOG_DEBUG, "Replacing known ICE candidate "STR_FORMAT" with higher " "priority " STR_FORMAT":%lu", STR_FMT(&dup->foundation), STR_FMT(&cand->foundation), cand->component_id); } /* priority and foundation may change */ g_hash_table_remove(ag->foundation_hash, dup); recalc += __copy_cand(call, dup, cand); } else { ilog(LOG_DEBUG, "Learning new ICE candidate "STR_FORMAT":%lu", STR_FMT(&cand->foundation), cand->component_id); dup = g_slice_alloc(sizeof(*dup)); __copy_cand(call, dup, cand); g_hash_table_insert(ag->candidate_hash, dup, dup); g_queue_push_tail(&ag->remote_candidates, dup); } g_hash_table_insert(ag->foundation_hash, dup, dup); pair: if (!ps) continue; for (k = ag->local_interface->list.head; k; k = k->next) { /* skip duplicates here also */ if (__pair_lookup(ag, dup, k->data)) continue; __pair_candidate(k->data, ag, dup, ps); } } if (comps) ag->active_components = comps; if (!ag->active_components) { /* determine components for tricke-ice case */ comps = 2; if (!components[1]) comps = 1; ag->active_components = comps; } /* if we're here, we can start our ICE checks */ if (recalc) __recalc_pair_prios(ag); else __all_pairs_list(ag); if (comps) __do_ice_checks(ag); else __agent_shutdown(ag); }
gboolean str_equal(gconstpointer a, gconstpointer b) { return str_cmp_str((str *) a, (str *) b) == 0; }
/* from sipwise rtpengine */ static int str_equal(str a, str b) { return (str_cmp_str(a, b) == 0); }