static int dialog_initialize_rtp(struct sip_pvt *dialog)
{
struct ast_sockaddr bindaddr_tmp;
+ struct ast_rtp_engine_ice *ice;
if (!sip_methods[dialog->method].need_rtp) {
return 0;
return -1;
}
+ if (!ast_test_flag(&dialog->flags[2], SIP_PAGE3_ICE_SUPPORT) && (ice = ast_rtp_instance_get_ice(dialog->rtp))) {
+ ice->stop(dialog->rtp);
+ }
+
if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT_ALWAYS) ||
(ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT) && (ast_format_cap_has_type(dialog->caps, AST_FORMAT_TYPE_VIDEO)))) {
if (!(dialog->vrtp = ast_rtp_instance_new(dialog->engine, sched, &bindaddr_tmp, NULL))) {
return -1;
}
+
+ if (!ast_test_flag(&dialog->flags[2], SIP_PAGE3_ICE_SUPPORT) && (ice = ast_rtp_instance_get_ice(dialog->vrtp))) {
+ ice->stop(dialog->vrtp);
+ }
+
ast_rtp_instance_set_timeout(dialog->vrtp, dialog->rtptimeout);
ast_rtp_instance_set_hold_timeout(dialog->vrtp, dialog->rtpholdtimeout);
ast_rtp_instance_set_keepalive(dialog->vrtp, dialog->rtpkeepalive);
if (!(dialog->trtp = ast_rtp_instance_new(dialog->engine, sched, &bindaddr_tmp, NULL))) {
return -1;
}
+
+ if (!ast_test_flag(&dialog->flags[2], SIP_PAGE3_ICE_SUPPORT) && (ice = ast_rtp_instance_get_ice(dialog->trtp))) {
+ ice->stop(dialog->trtp);
+ }
+
/* Do not timeout text as its not constant*/
ast_rtp_instance_set_keepalive(dialog->trtp, dialog->rtpkeepalive);
ast_verbose("Video is at %s\n", ast_sockaddr_stringify(&vdest));
}
- if (!doing_directmedia) {
+ if (!doing_directmedia && ast_test_flag(&p->flags[2], SIP_PAGE3_ICE_SUPPORT)) {
add_ice_to_sdp(p->vrtp, &a_video);
}
}
ast_verbose("Text is at %s\n", ast_sockaddr_stringify(&taddr));
}
- if (!doing_directmedia) {
+ if (!doing_directmedia && ast_test_flag(&p->flags[2], SIP_PAGE3_ICE_SUPPORT)) {
add_ice_to_sdp(p->trtp, &a_text);
}
}
if (min_text_packet_size)
ast_str_append(&a_text, 0, "a=ptime:%d\r\n", min_text_packet_size);
- if (!doing_directmedia) {
+ if (!doing_directmedia && ast_test_flag(&p->flags[2], SIP_PAGE3_ICE_SUPPORT)) {
add_ice_to_sdp(p->rtp, &a_audio);
}
ast_set2_flag(&peer->flags[2], ast_true(v->value), SIP_PAGE3_SNOM_AOC);
} else if (!strcasecmp(v->name, "avpf")) {
ast_set2_flag(&peer->flags[2], ast_true(v->value), SIP_PAGE3_USE_AVPF);
+ } else if (!strcasecmp(v->name, "icesupport")) {
+ ast_set2_flag(&peer->flags[2], ast_true(v->value), SIP_PAGE3_ICE_SUPPORT);
}
}
ast_set_flag(&global_flags[0], SIP_DTMF_RFC2833); /*!< Default DTMF setting: RFC2833 */
ast_set_flag(&global_flags[0], SIP_DIRECT_MEDIA); /*!< Allow re-invites */
ast_set_flag(&global_flags[2], SIP_PAGE3_NAT_AUTO_RPORT); /*!< Default to nat=auto_force_rport */
+ ast_set_flag(&global_flags[2], SIP_PAGE3_ICE_SUPPORT); /*!< Default to enabling ICE support */
ast_copy_string(default_engine, DEFAULT_ENGINE, sizeof(default_engine));
ast_copy_string(default_parkinglot, DEFAULT_PARKINGLOT, sizeof(default_parkinglot));
}
} else if (!strcasecmp(v->name, "snom_aoc_enabled")) {
ast_set2_flag(&global_flags[2], ast_true(v->value), SIP_PAGE3_SNOM_AOC);
+ } else if (!strcasecmp(v->name, "icesupport")) {
+ ast_set2_flag(&global_flags[2], ast_true(v->value), SIP_PAGE3_ICE_SUPPORT);
} else if (!strcasecmp(v->name, "parkinglot")) {
ast_copy_string(default_parkinglot, v->value, sizeof(default_parkinglot));
}
pj_ice_sess_change_role(rtp->ice, PJ_ICE_SESS_ROLE_CONTROLLING);
}
+static int ice_candidate_cmp(void *obj, void *arg, int flags)
+{
+ struct ast_rtp_engine_ice_candidate *candidate1 = obj, *candidate2 = arg;
+
+ if ((strcmp(candidate1->foundation, candidate2->foundation)) ||
+ (candidate1->id != candidate2->id) ||
+ (ast_sockaddr_cmp(&candidate1->address, &candidate2->address)) ||
+ (candidate1->type != candidate1->type)) {
+ return 0;
+ }
+
+ return CMP_MATCH | CMP_STOP;
+}
+
static void ast_rtp_ice_add_cand(struct ast_rtp *rtp, unsigned comp_id, unsigned transport_id, pj_ice_cand_type type, pj_uint16_t local_pref,
const pj_sockaddr_t *addr, const pj_sockaddr_t *base_addr, const pj_sockaddr_t *rel_addr, int addr_len)
{
pj_str_t foundation;
- struct ast_rtp_engine_ice_candidate *candidate;
+ struct ast_rtp_engine_ice_candidate *candidate, *existing;
char address[PJ_INET6_ADDRSTRLEN];
pj_thread_register_check();
pj_ice_calc_foundation(rtp->ice->pool, &foundation, type, addr);
- if (!rtp->local_candidates && !(rtp->local_candidates = ao2_container_alloc(1, NULL, NULL))) {
+ if (!rtp->local_candidates && !(rtp->local_candidates = ao2_container_alloc(1, NULL, ice_candidate_cmp))) {
return;
}
candidate->type = AST_RTP_ICE_CANDIDATE_TYPE_RELAYED;
}
+ if ((existing = ao2_find(rtp->local_candidates, candidate, OBJ_POINTER))) {
+ ao2_ref(existing, -1);
+ ao2_ref(candidate, -1);
+ return;
+ }
+
if (pj_ice_sess_add_cand(rtp->ice, comp_id, transport_id, type, local_pref, &foundation, addr, addr, rel_addr, addr_len, NULL) != PJ_SUCCESS) {
ao2_ref(candidate, -1);
return;