diff --git a/acinclude.m4 b/acinclude.m4
index aeba17b5c3..58b5500a80 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -6,6 +6,7 @@ m4_include([build/config/ac_gcc_archflag.m4])
m4_include([build/config/ac_gcc_x86_cpuid.m4])
m4_include([build/config/ax_lib_mysql.m4])
m4_include([build/config/ax_check_java.m4])
+m4_include([build/config/uuid.m4])
m4_include([build/config/erlang.m4])
m4_include([build/config/odbc.m4])
m4_include([build/config/sched_setaffinity.m4])
diff --git a/build/config/uuid.m4 b/build/config/uuid.m4
new file mode 100644
index 0000000000..7f37c23c66
--- /dev/null
+++ b/build/config/uuid.m4
@@ -0,0 +1,17 @@
+AC_DEFUN([CHECK_LIBUUID],
+ [
+ PKG_CHECK_MODULES([LIBUUID], [uuid >= 1.41.2],
+ [LIBUUID_FOUND=yes], [LIBUUID_FOUND=no])
+ if test "$LIBUUID_FOUND" = "no" ; then
+ PKG_CHECK_MODULES([LIBUUID], [uuid],
+ [LIBUUID_FOUND=yes], [LIBUUID_FOUND=no])
+ if test "$LIBUUID_FOUND" = "no" ; then
+ AC_MSG_WARN([libuuid development package highly recommended!])
+ else
+ LIBUUID_INCLUDEDIR=$(pkg-config --variable=includedir uuid)
+ LIBUUID_CFLAGS+=" -I$LIBUUID_INCLUDEDIR/uuid "
+ fi
+ fi
+ AC_SUBST([LIBUUID_CFLAGS])
+ AC_SUBST([LIBUUID_LIBS])
+ ])
diff --git a/conf/rayo/autoload_configs/rayo.conf.xml b/conf/rayo/autoload_configs/rayo.conf.xml
index c8171569af..82adf96faa 100644
--- a/conf/rayo/autoload_configs/rayo.conf.xml
+++ b/conf/rayo/autoload_configs/rayo.conf.xml
@@ -17,10 +17,10 @@
-
+
-
-
+
+
@@ -49,8 +49,9 @@
-
-
+
+
+
diff --git a/configure.in b/configure.in
index 9307c958c9..d186eebc94 100644
--- a/configure.in
+++ b/configure.in
@@ -412,6 +412,10 @@ if test "x$enable_core_odbc_support" != "xno"; then
AC_CHECK_LIB([odbc], [SQLDisconnect],, AC_MSG_ERROR([no usable libodbc; please install unixodbc devel package or equivalent]))
fi
+CHECK_LIBUUID
+SWITCH_AM_LDFLAGS="$LIBUUID_LIBS $SWITCH_AM_LDFLAGS"
+SWITCH_AM_CFLAGS="$LIBUUID_CFLAGS $SWITCH_AM_CFLAGS"
+
AC_ARG_ENABLE(core-pgsql-support,
[AS_HELP_STRING([--enable-core-pgsql-support], [Compile with PGSQL Support])],,[enable_core_pgsql_support="no"])
AC_ARG_ENABLE(core-pgsql-pkgconfig,
diff --git a/debian/bootstrap.sh b/debian/bootstrap.sh
index b9776f14ac..03953b36c0 100755
--- a/debian/bootstrap.sh
+++ b/debian/bootstrap.sh
@@ -36,6 +36,7 @@ avoid_mods=(
xml_int/mod_xml_radius
)
avoid_mods_sid=(
+ languages/mod_java
)
avoid_mods_jessie=(
)
diff --git a/libs/curl/lib/strequal.h b/libs/curl/lib/strequal.h
index 6ec88d82d7..ce83d48aef 100644
--- a/libs/curl/lib/strequal.h
+++ b/libs/curl/lib/strequal.h
@@ -38,6 +38,6 @@ char *Curl_strcasestr(const char *haystack, const char *needle);
#ifndef HAVE_STRLCAT
#define strlcat(x,y,z) Curl_strlcat(x,y,z)
#endif
-size_t strlcat(char *dst, const char *src, size_t siz);
+//size_t strlcat(char *dst, const char *src, size_t siz);
#endif
diff --git a/libs/esl/src/esl.c b/libs/esl/src/esl.c
index d186665413..ede0675df0 100644
--- a/libs/esl/src/esl.c
+++ b/libs/esl/src/esl.c
@@ -1513,6 +1513,10 @@ ESL_DECLARE(esl_status_t) esl_send_recv_timed(esl_handle_t *handle, const char *
}
recv:
+
+ esl_event_safe_destroy(&handle->last_sr_event);
+
+ *handle->last_sr_reply = '\0';
status = esl_recv_event_timed(handle, ms, 0, &handle->last_sr_event);
diff --git a/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c b/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c
index fdeb67f4b9..8a537bb5e6 100644
--- a/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c
+++ b/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c
@@ -656,9 +656,6 @@ static void *ftdm_analog_em_channel_run(ftdm_thread_t *me, void *obj)
if (ftdmchan->state == FTDM_CHANNEL_STATE_UP) {
cas_bits = 0;
ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_CAS_BITS, &cas_bits);
- if (!(state_counter % 5000)) {
- ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "CAS bits: 0x%X\n", cas_bits);
- }
if (cas_bits == 0x0) {
cas_hangup += interval;
if (cas_hangup >= cas_hangup_ms) {
diff --git a/src/include/switch_core_media.h b/src/include/switch_core_media.h
index 5c083101a9..cfbe9921eb 100644
--- a/src/include/switch_core_media.h
+++ b/src/include/switch_core_media.h
@@ -292,7 +292,7 @@ SWITCH_DECLARE(stfu_instance_t *) switch_core_media_get_jb(switch_core_session_t
SWITCH_DECLARE(switch_rtp_stats_t *) switch_core_media_get_stats(switch_core_session_t *session, switch_media_type_t type, switch_memory_pool_t *pool);
-SWITCH_DECLARE(void) switch_core_media_set_sdp_codec_string(switch_core_session_t *session, const char *r_sdp);
+SWITCH_DECLARE(void) switch_core_media_set_sdp_codec_string(switch_core_session_t *session, const char *r_sdp, switch_sdp_type_t sdp_type);
SWITCH_DECLARE(void) switch_core_media_reset_autofix(switch_core_session_t *session, switch_media_type_t type);
SWITCH_DECLARE(void) switch_core_media_check_outgoing_proxy(switch_core_session_t *session, switch_core_session_t *o_session);
SWITCH_DECLARE(switch_status_t) switch_core_media_codec_chosen(switch_core_session_t *session, switch_media_type_t media);
@@ -305,6 +305,13 @@ SWITCH_DECLARE(void) switch_core_media_deinit(void);
SWITCH_DECLARE(void) switch_core_media_set_stats(switch_core_session_t *session);
SWITCH_DECLARE(void) switch_core_session_wake_video_thread(switch_core_session_t *session);
SWITCH_DECLARE(void) switch_core_session_clear_crypto(switch_core_session_t *session);
+
+SWITCH_DECLARE(switch_status_t) switch_core_session_get_payload_code(switch_core_session_t *session,
+ switch_media_type_t type,
+ const char *iananame,
+ switch_payload_t *ptP,
+ switch_payload_t *recv_ptP);
+
SWITCH_DECLARE(payload_map_t *) switch_core_media_add_payload_map(switch_core_session_t *session,
switch_media_type_t type,
const char *name,
diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c
index 55e681aa09..dd3d6bb4bb 100644
--- a/src/mod/applications/mod_conference/mod_conference.c
+++ b/src/mod/applications/mod_conference/mod_conference.c
@@ -6179,7 +6179,7 @@ static switch_status_t conf_api_sub_file_seek(conference_obj_t *conference, swit
step = 1000;
}
- samps = step * (conference->rate / 1000);
+ samps = step * (conference->fnode->fh.native_rate / 1000);
target = (int32_t)conference->fnode->fh.pos + samps;
if (target < 0) {
@@ -6190,7 +6190,7 @@ static switch_status_t conf_api_sub_file_seek(conference_obj_t *conference, swit
switch_core_file_seek(&conference->fnode->fh, &pos, target, SEEK_SET);
} else {
- samps = switch_atoui(argv[2]) * (conference->rate / 1000);
+ samps = switch_atoui(argv[2]) * (conference->fnode->fh.native_rate / 1000);
stream->write_function(stream, "+OK seek to position %d\n", samps);
switch_core_file_seek(&conference->fnode->fh, &pos, samps, SEEK_SET);
}
diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c
index 527de9b8fb..cd566c22bd 100644
--- a/src/mod/endpoints/mod_sofia/sofia.c
+++ b/src/mod/endpoints/mod_sofia/sofia.c
@@ -5118,8 +5118,12 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status
}
tech_pvt->mparams.last_sdp_str = NULL;
- if (!sofia_use_soa(tech_pvt) && sip->sip_payload && sip->sip_payload->pl_data) {
- tech_pvt->mparams.last_sdp_str = switch_core_session_strdup(session, sip->sip_payload->pl_data);
+ if (sip->sip_payload && sip->sip_payload->pl_data) {
+ switch_core_media_set_sdp_codec_string(session, sip->sip_payload->pl_data, SDP_TYPE_RESPONSE);
+
+ if (!sofia_use_soa(tech_pvt)) {
+ tech_pvt->mparams.last_sdp_str = switch_core_session_strdup(session, sip->sip_payload->pl_data);
+ }
}
@@ -5867,9 +5871,9 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Remote SDP:\n%s\n", r_sdp);
tech_pvt->mparams.remote_sdp_str = switch_core_session_strdup(session, r_sdp);
- if ((sofia_test_flag(tech_pvt, TFLAG_LATE_NEGOTIATION) || switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND)) {
- switch_core_media_set_sdp_codec_string(session, r_sdp);
- }
+ //if ((sofia_test_flag(tech_pvt, TFLAG_LATE_NEGOTIATION) || switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND)) {
+ // switch_core_media_set_sdp_codec_string(session, r_sdp, status < 200 ? SDP_TYPE_REQUEST : SDP_TYPE_RESPONSE);
+ //}
sofia_glue_pass_sdp(tech_pvt, (char *) r_sdp);
sofia_set_flag(tech_pvt, TFLAG_NEW_SDP);
@@ -7882,8 +7886,13 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia
const char *from_tag = "";
char *sql = NULL;
char *acl_context = NULL;
+ const char *r_sdp = NULL;
+
profile->ib_calls++;
+ if (sip->sip_payload && sip->sip_payload->pl_data) {
+ r_sdp = sip->sip_payload->pl_data;
+ }
if (!session || (sess_count >= sess_max || !sofia_test_pflag(profile, PFLAG_RUNNING))) {
nua_respond(nh, 503, "Maximum Calls In Progress", SIPTAG_RETRY_AFTER_STR("300"), TAG_END());
@@ -7910,6 +7919,12 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia
is_nat = "websockets";
}
+
+ if (r_sdp) {
+ switch_core_media_set_sdp_codec_string(session, r_sdp, SDP_TYPE_REQUEST);
+ }
+
+
if (sofia_test_pflag(profile, PFLAG_AGGRESSIVE_NAT_DETECTION)) {
if (sip && sip->sip_via) {
const char *port = sip->sip_via->v_port;
diff --git a/src/mod/event_handlers/mod_rayo/conf/autoload_configs/rayo.conf.xml b/src/mod/event_handlers/mod_rayo/conf/autoload_configs/rayo.conf.xml
index 3fdc772daf..dc90b519df 100644
--- a/src/mod/event_handlers/mod_rayo/conf/autoload_configs/rayo.conf.xml
+++ b/src/mod/event_handlers/mod_rayo/conf/autoload_configs/rayo.conf.xml
@@ -49,8 +49,9 @@
-
-
+
+
+
diff --git a/src/mod/event_handlers/mod_rayo/mod_rayo.c b/src/mod/event_handlers/mod_rayo/mod_rayo.c
index 88eb44b417..7dcd6738dc 100644
--- a/src/mod/event_handlers/mod_rayo/mod_rayo.c
+++ b/src/mod/event_handlers/mod_rayo/mod_rayo.c
@@ -135,11 +135,13 @@ struct rayo_call {
/** ID of joined party TODO this will be many mixers / calls */
const char *joined_id;
/** set if response needs to be sent to IQ request */
- const char *dial_id;
+ const char *dial_request_id;
/** channel destroy event */
switch_event_t *end_event;
/** True if ringing event sent to client */
int ringing_sent;
+ /** True if request to create this call failed */
+ int dial_request_failed;
};
/**
@@ -877,9 +879,9 @@ static void rayo_call_cleanup(struct rayo_actor *actor)
iks *revent;
iks *end;
- if (!event) {
+ if (!event || call->dial_request_failed) {
/* destroyed before FS session was created (in originate, for example) */
- return;
+ goto done;
}
revent = iks_new_presence("end", RAYO_NS,
@@ -941,6 +943,10 @@ static void rayo_call_cleanup(struct rayo_actor *actor)
RAYO_SEND_MESSAGE_DUP(actor, rayo_call_get_dcp_jid(call), revent);
}
+ iks_delete(revent);
+
+done:
+
/* lost the race: pending join failed... send IQ result to client now. */
if (call->pending_join_request) {
iks *request = call->pending_join_request;
@@ -950,8 +956,9 @@ static void rayo_call_cleanup(struct rayo_actor *actor)
iks_delete(call->pending_join_request);
}
- iks_delete(revent);
- switch_event_destroy(&event);
+ if (event) {
+ switch_event_destroy(&event);
+ }
switch_core_hash_destroy(&call->pcps);
}
@@ -1102,6 +1109,9 @@ static struct rayo_call *rayo_call_init(struct rayo_call *call, switch_memory_po
call->joined_id = NULL;
call->ringing_sent = 0;
call->pending_join_request = NULL;
+ call->dial_request_id = NULL;
+ call->end_event = NULL;
+ call->dial_request_failed = 0;
switch_core_hash_init(&call->pcps, pool);
switch_safe_free(call_jid);
@@ -2141,7 +2151,7 @@ static void *SWITCH_THREAD_FUNC rayo_dial_thread(switch_thread_t *thread, void *
/* create call and link to DCP */
call = rayo_call_create(NULL);
call->dcp_jid = switch_core_strdup(RAYO_POOL(call), dcp_jid);
- call->dial_id = iks_find_attrib(iq, "id");
+ call->dial_request_id = iks_find_attrib(iq, "id");
switch_log_printf(SWITCH_CHANNEL_UUID_LOG(rayo_call_get_uuid(call)), SWITCH_LOG_INFO, "%s has control of call\n", dcp_jid);
uuid = switch_core_strdup(dtdata->pool, rayo_call_get_uuid(call));
@@ -2245,27 +2255,63 @@ static void *SWITCH_THREAD_FUNC rayo_dial_thread(switch_thread_t *thread, void *
if (switch_api_execute("originate", stream.data, NULL, &api_stream) == SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid), SWITCH_LOG_DEBUG, "Got originate result: %s\n", (char *)api_stream.data);
+ switch_mutex_lock(RAYO_ACTOR(call)->mutex);
/* check for failure */
if (strncmp("+OK", api_stream.data, strlen("+OK"))) {
switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid), SWITCH_LOG_INFO, "Failed to originate call\n");
- if (call->dial_id) {
+ if (call->dial_request_id) {
+ call->dial_request_failed = 1;
+ call->dial_request_id = NULL;
+
/* map failure reason to iq error */
if (!strncmp("-ERR DESTINATION_OUT_OF_ORDER", api_stream.data, strlen("-ERR DESTINATION_OUT_OF_ORDER"))) {
- /* this -ERR is received when out of sessions */
- response = iks_new_error(iq, STANZA_ERROR_RESOURCE_CONSTRAINT);
+ /* out of sessions, typically */
+ response = iks_new_error_detailed(iq, STANZA_ERROR_RESOURCE_CONSTRAINT, (char *)api_stream.data);
+ } else if (!strncmp("-ERR USER_NOT_REGISTERED", api_stream.data, strlen("-ERR USER_NOT_REGISTERED"))) {
+ response = iks_new_error_detailed(iq, STANZA_ERROR_UNEXPECTED_REQUEST, (char *)api_stream.data);
+ } else if (!strncmp("-ERR EXCHANGE_ROUTING_ERROR", api_stream.data, strlen("-ERR EXCHANGE_ROUTING_ERROR"))) {
+ /* max forwards */
+ response = iks_new_error_detailed(iq, STANZA_ERROR_RESOURCE_CONSTRAINT, (char *)api_stream.data);
+ } else if (!strncmp("-ERR CHAN_NOT_IMPLEMENTED", api_stream.data, strlen("-ERR CHAN_NOT_IMPLEMENTED"))) {
+ /* unsupported endpoint type */
+ response = iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, (char *)api_stream.data);
+ } else if (!strncmp("-ERR INVALID_URL", api_stream.data, strlen("-ERR INVALID_URL"))) {
+ response = iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, (char *)api_stream.data);
+ } else if (!strncmp("-ERR INVALID_GATEWAY", api_stream.data, strlen("-ERR INVALID_GATEWAY"))) {
+ response = iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, (char *)api_stream.data);
+ } else if (!strncmp("-ERR INVALID_PROFILE", api_stream.data, strlen("-ERR INVALID_PROFILE"))) {
+ response = iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, (char *)api_stream.data);
+ } else if (!strncmp("-ERR SYSTEM_SHUTDOWN", api_stream.data, strlen("-ERR SYSTEM_SHUTDOWN"))) {
+ response = iks_new_error_detailed(iq, STANZA_ERROR_RESOURCE_CONSTRAINT, (char *)api_stream.data);
+ } else if (!strncmp("-ERR GATEWAY_DOWN", api_stream.data, strlen("-ERR GATEWAY_DOWN"))) {
+ response = iks_new_error_detailed(iq, STANZA_ERROR_RESOURCE_CONSTRAINT, (char *)api_stream.data);
+ } else if (!strncmp("-ERR INVALID_NUMBER_FORMAT", api_stream.data, strlen("-ERR INVALID_NUMBER_FORMAT"))) {
+ response = iks_new_error_detailed(iq, STANZA_ERROR_RESOURCE_CONSTRAINT, (char *)api_stream.data);
+ } else {
+ /* other unspecified error */
+ response = iks_new_error_detailed(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, (char *)api_stream.data);
}
}
}
- } else if (call->dial_id) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Failed to exec originate API\n");
- response = iks_new_error_detailed(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, "Failed to execute originate API");
+ switch_mutex_unlock(RAYO_ACTOR(call)->mutex);
+ } else {
+ switch_mutex_lock(RAYO_ACTOR(call)->mutex);
+ if (call->dial_request_id) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Failed to exec originate API\n");
+ call->dial_request_failed = 1;
+ call->dial_request_id = NULL;
+ response = iks_new_error_detailed(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, "Failed to execute originate API");
+ }
+ switch_mutex_unlock(RAYO_ACTOR(call)->mutex);
}
switch_safe_free(api_stream.data);
} else {
/* will only happen if misconfigured */
switch_log_printf(SWITCH_CHANNEL_UUID_LOG(rayo_call_get_uuid(call)), SWITCH_LOG_CRIT, "No dial gateway found for %s!\n", dial_to);
+ call->dial_request_failed = 1;
+ call->dial_request_id = NULL;
response = iks_new_error_detailed_printf(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, "No dial gateway found for %s!\n", dial_to);
goto done;
}
@@ -2719,21 +2765,27 @@ static void on_call_originate_event(struct rayo_client *rclient, switch_event_t
if (call && (session = switch_core_session_locate(uuid))) {
iks *response, *ref;
- switch_channel_set_private(switch_core_session_get_channel(session), "rayo_call_private", call);
+ switch_log_printf(SWITCH_CHANNEL_UUID_LOG(RAYO_ID(call)), SWITCH_LOG_DEBUG, "Got originate event\n");
+
+ switch_mutex_lock(RAYO_ACTOR(call)->mutex);
+ if (call->dial_request_id) {
+ switch_channel_set_private(switch_core_session_get_channel(session), "rayo_call_private", call);
+
+ /* send response to DCP */
+ response = iks_new("iq");
+ iks_insert_attrib(response, "from", RAYO_JID(globals.server));
+ iks_insert_attrib(response, "to", rayo_call_get_dcp_jid(call));
+ iks_insert_attrib(response, "id", call->dial_request_id);
+ iks_insert_attrib(response, "type", "result");
+ ref = iks_insert(response, "ref");
+ iks_insert_attrib(ref, "xmlns", RAYO_NS);
+
+ iks_insert_attrib_printf(ref, "uri", "xmpp:%s", RAYO_JID(call));
+ RAYO_SEND_MESSAGE(call, RAYO_JID(rclient), response);
+ call->dial_request_id = NULL;
+ }
+ switch_mutex_unlock(RAYO_ACTOR(call)->mutex);
switch_core_session_rwunlock(session);
-
- /* send response to DCP */
- response = iks_new("iq");
- iks_insert_attrib(response, "from", RAYO_JID(globals.server));
- iks_insert_attrib(response, "to", rayo_call_get_dcp_jid(call));
- iks_insert_attrib(response, "id", call->dial_id);
- iks_insert_attrib(response, "type", "result");
- ref = iks_insert(response, "ref");
- iks_insert_attrib(ref, "xmlns", RAYO_NS);
-
- iks_insert_attrib_printf(ref, "uri", "xmpp:%s", RAYO_JID(call));
- RAYO_SEND_MESSAGE(call, RAYO_JID(rclient), response);
- call->dial_id = NULL;
}
RAYO_UNLOCK(call);
}
@@ -2754,9 +2806,15 @@ static void on_call_end_event(switch_event_t *event)
switch_safe_free(event_str);
}
#endif
- switch_event_dup(&call->end_event, event);
- RAYO_UNLOCK(call); /* decrement ref from creation */
- RAYO_DESTROY(call);
+ switch_log_printf(SWITCH_CHANNEL_UUID_LOG(RAYO_ID(call)), SWITCH_LOG_DEBUG, "Got channel destroy event\n");
+
+ switch_mutex_lock(RAYO_ACTOR(call)->mutex);
+ if (!call->dial_request_id && !call->dial_request_failed) {
+ switch_event_dup(&call->end_event, event);
+ RAYO_DESTROY(call);
+ RAYO_UNLOCK(call); /* decrement ref from creation */
+ }
+ switch_mutex_unlock(RAYO_ACTOR(call)->mutex);
RAYO_UNLOCK(call); /* decrement this ref */
}
}
@@ -2796,9 +2854,9 @@ static void on_call_ringing_event(struct rayo_client *rclient, switch_event_t *e
switch_event_get_header(event, "variable_rayo_dcp_jid"));
call->ringing_sent = 1;
RAYO_SEND_MESSAGE(call, RAYO_JID(rclient), revent);
- RAYO_UNLOCK(call);
}
switch_mutex_unlock(RAYO_ACTOR(call)->mutex);
+ RAYO_UNLOCK(call);
}
}
}
diff --git a/src/switch_caller.c b/src/switch_caller.c
index fdd41a4dd7..f7a9e5d40a 100644
--- a/src/switch_caller.c
+++ b/src/switch_caller.c
@@ -313,6 +313,10 @@ SWITCH_DECLARE(void) switch_caller_profile_event_set_data(switch_caller_profile_
switch_snprintf(header_name, sizeof(header_name), "%s-Direction", prefix);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, header_name, caller_profile->direction == SWITCH_CALL_DIRECTION_INBOUND ?
"inbound" : "outbound");
+
+ switch_snprintf(header_name, sizeof(header_name), "%s-Logical-Direction", prefix);
+ switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, header_name, caller_profile->logical_direction == SWITCH_CALL_DIRECTION_INBOUND ?
+ "inbound" : "outbound");
if (!zstr(caller_profile->username)) {
switch_snprintf(header_name, sizeof(header_name), "%s-Username", prefix);
diff --git a/src/switch_core_media.c b/src/switch_core_media.c
index bbef0b79bd..eee0affc86 100644
--- a/src/switch_core_media.c
+++ b/src/switch_core_media.c
@@ -40,9 +40,9 @@
#include
#include
-SWITCH_DECLARE(switch_t38_options_t *) switch_core_media_process_udptl(switch_core_session_t *session, sdp_session_t *sdp, sdp_media_t *m);
-SWITCH_DECLARE(void) switch_core_media_find_zrtp_hash(switch_core_session_t *session, sdp_session_t *sdp);
-SWITCH_DECLARE(void) switch_core_media_set_r_sdp_codec_string(switch_core_session_t *session, const char *codec_string, sdp_session_t *sdp);
+static switch_t38_options_t * switch_core_media_process_udptl(switch_core_session_t *session, sdp_session_t *sdp, sdp_media_t *m);
+static void switch_core_media_find_zrtp_hash(switch_core_session_t *session, sdp_session_t *sdp);
+static void switch_core_media_set_r_sdp_codec_string(switch_core_session_t *session, const char *codec_string, sdp_session_t *sdp, switch_sdp_type_t sdp_type);
//#define GOOGLE_ICE
#define RTCP_MUX
@@ -162,6 +162,7 @@ struct switch_media_handle_s {
char *origin;
switch_mutex_t *mutex;
+ switch_mutex_t *sdp_mutex;
const switch_codec_implementation_t *negotiated_codecs[SWITCH_MAX_CODECS];
int num_negotiated_codecs;
@@ -262,7 +263,7 @@ SWITCH_DECLARE(const char *) switch_core_media_get_zrtp_hash(switch_core_session
}
-SWITCH_DECLARE(void) switch_core_media_find_zrtp_hash(switch_core_session_t *session, sdp_session_t *sdp)
+static void switch_core_media_find_zrtp_hash(switch_core_session_t *session, sdp_session_t *sdp)
{
switch_channel_t *channel = switch_core_session_get_channel(session);
switch_rtp_engine_t *audio_engine;
@@ -306,7 +307,7 @@ SWITCH_DECLARE(void) switch_core_media_find_zrtp_hash(switch_core_session_t *ses
}
-SWITCH_DECLARE(switch_t38_options_t *) switch_core_media_process_udptl(switch_core_session_t *session, sdp_session_t *sdp, sdp_media_t *m)
+static switch_t38_options_t * switch_core_media_process_udptl(switch_core_session_t *session, sdp_session_t *sdp, sdp_media_t *m)
{
switch_t38_options_t *t38_options = switch_channel_get_private(session->channel, "t38_options");
sdp_attribute_t *attr;
@@ -459,6 +460,53 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_process_t38_passthru(switch_co
}
+SWITCH_DECLARE(switch_status_t) switch_core_session_get_payload_code(switch_core_session_t *session,
+ switch_media_type_t type,
+ const char *iananame,
+ switch_payload_t *ptP,
+ switch_payload_t *recv_ptP)
+{
+ payload_map_t *pmap;
+ switch_media_handle_t *smh;
+ switch_rtp_engine_t *engine;
+ switch_payload_t pt = 0, recv_pt = 0;
+ int found = 0;
+
+ switch_assert(session);
+
+ if (!(smh = session->media_handle)) {
+ return SWITCH_STATUS_FALSE;
+ }
+
+ engine = &smh->engines[type];
+
+ switch_mutex_lock(smh->sdp_mutex);
+ for (pmap = engine->payload_map; pmap ; pmap = pmap->next) {
+
+ if (!pmap->allocated) continue;
+
+ if (!strcasecmp(pmap->iananame, iananame)) {
+ pt = pmap->pt;
+ recv_pt = pmap->recv_pt;
+ found++;
+ }
+ }
+ switch_mutex_unlock(smh->sdp_mutex);
+
+ if (found) {
+ if (ptP) {
+ *ptP = pt;
+ }
+ if (recv_ptP) {
+ *recv_ptP = recv_pt;
+ }
+ return SWITCH_STATUS_SUCCESS;
+ }
+
+ return SWITCH_STATUS_FALSE;
+
+}
+
SWITCH_DECLARE(payload_map_t *) switch_core_media_add_payload_map(switch_core_session_t *session,
switch_media_type_t type,
@@ -482,11 +530,11 @@ SWITCH_DECLARE(payload_map_t *) switch_core_media_add_payload_map(switch_core_se
engine = &smh->engines[type];
- switch_mutex_lock(smh->mutex);
+ switch_mutex_lock(smh->sdp_mutex);
for (pmap = engine->payload_map; pmap && pmap->allocated; pmap = pmap->next) {
- exists = (!strcasecmp(name, pmap->iananame) && rate == pmap->rate && pmap->ptime == ptime);
+ exists = (!strcasecmp(name, pmap->iananame) && (!pmap->rate || rate == pmap->rate) && (pmap->ptime || pmap->ptime == ptime));
if (exists) {
break;
@@ -495,17 +543,27 @@ SWITCH_DECLARE(payload_map_t *) switch_core_media_add_payload_map(switch_core_se
if (!exists) {
+ switch_ssize_t hlen = -1;
+
if (engine->payload_map && !engine->payload_map->allocated) {
pmap = engine->payload_map;
} else {
pmap = switch_core_alloc(session->pool, sizeof(*pmap));
}
- pmap->sdp_type = sdp_type;
pmap->type = type;
pmap->iananame = switch_core_strdup(session->pool, name);
pmap->rm_encoding = pmap->iananame;
+ pmap->hash = switch_ci_hashfunc_default(pmap->iananame, &hlen);
+ }
+
+ pmap->sdp_type = sdp_type;
+
+ if (ptime) {
pmap->ptime = ptime;
+ }
+
+ if (rate) {
pmap->rate = rate;
}
@@ -531,7 +589,7 @@ SWITCH_DECLARE(payload_map_t *) switch_core_media_add_payload_map(switch_core_se
}
}
- switch_mutex_unlock(smh->mutex);
+ switch_mutex_unlock(smh->sdp_mutex);
return pmap;
}
@@ -1141,6 +1199,7 @@ SWITCH_DECLARE(switch_status_t) switch_media_handle_create(switch_media_handle_t
switch_mutex_init(&session->media_handle->mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
+ switch_mutex_init(&session->media_handle->sdp_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO].ssrc =
(uint32_t) ((intptr_t) &session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO] + (uint32_t) time(NULL));
@@ -1635,7 +1694,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_frame(switch_core_session
/* search for payload type */
- switch_mutex_lock(smh->mutex);
+ switch_mutex_lock(smh->sdp_mutex);
for (pmap = engine->cur_payload_map; pmap; pmap = pmap->next) {
if (engine->read_frame.payload == pmap->recv_pt) {
engine->cur_payload_map = pmap;
@@ -1649,7 +1708,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_frame(switch_core_session
break;
}
}
- switch_mutex_unlock(smh->mutex);
+ switch_mutex_unlock(smh->sdp_mutex);
if (!engine->reset_codec) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING,
@@ -5606,10 +5665,10 @@ SWITCH_DECLARE(void)switch_core_media_set_local_sdp(switch_core_session_t *sessi
return;
}
- if (smh->mutex) switch_mutex_lock(smh->mutex);
+ if (smh->sdp_mutex) switch_mutex_lock(smh->sdp_mutex);
smh->mparams->local_sdp_str = dup ? switch_core_session_strdup(session, sdp_str) : (char *) sdp_str;
switch_channel_set_variable(session->channel, "rtp_local_sdp_str", smh->mparams->local_sdp_str);
- if (smh->mutex) switch_mutex_unlock(smh->mutex);
+ if (smh->sdp_mutex) switch_mutex_unlock(smh->sdp_mutex);
}
@@ -5643,6 +5702,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess
switch_media_handle_t *smh;
ice_t *ice_out;
int vp8 = 0;
+ int red = 0;
payload_map_t *pmap;
switch_assert(session);
@@ -5701,16 +5761,24 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess
smh->mparams->cng_pt = 0;
}
+
+
if (!smh->payload_space) {
int i;
+
smh->payload_space = 98;
if (sdp_type == SDP_TYPE_REQUEST) {
+ switch_core_session_t *orig_session = NULL;
+
+ switch_core_session_get_partner(session, &orig_session);
+
for (i = 0; i < smh->mparams->num_codecs; i++) {
const switch_codec_implementation_t *imp = smh->codecs[i];
-
+ switch_payload_t orig_pt = 0;
+
smh->ianacodes[i] = imp->ianacode;
if (smh->ianacodes[i] > 64) {
@@ -5721,7 +5789,15 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess
smh->mparams->cng_pt && use_cng && smh->mparams->cng_pt == smh->payload_space) {
smh->payload_space++;
}
- smh->ianacodes[i] = (switch_payload_t)smh->payload_space++;
+
+ if (orig_session &&
+ switch_core_session_get_payload_code(orig_session,
+ imp->codec_type == SWITCH_CODEC_TYPE_AUDIO ? SWITCH_MEDIA_TYPE_AUDIO : SWITCH_MEDIA_TYPE_VIDEO,
+ imp->iananame, &orig_pt, NULL) == SWITCH_STATUS_SUCCESS) {
+ smh->ianacodes[i] = orig_pt;
+ } else {
+ smh->ianacodes[i] = (switch_payload_t)smh->payload_space++;
+ }
}
@@ -5735,6 +5811,10 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess
SWITCH_FALSE);
}
+
+ if (orig_session) {
+ switch_core_session_rwunlock(orig_session);
+ }
}
}
@@ -5846,13 +5926,13 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess
if (switch_media_handle_test_media_flag(smh, SCMF_MULTI_ANSWER_AUDIO)) {
- switch_mutex_lock(smh->mutex);
+ switch_mutex_lock(smh->sdp_mutex);
for (pmap = a_engine->cur_payload_map; pmap && pmap->allocated; pmap = pmap->next) {
if (pmap->pt != a_engine->cur_payload_map->pt) {
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), " %d", pmap->pt);
}
}
- switch_mutex_unlock(smh->mutex);
+ switch_mutex_unlock(smh->sdp_mutex);
}
if ((smh->mparams->dtmf_type == DTMF_2833 || switch_media_handle_test_media_flag(smh, SCMF_LIBERAL_DTMF) ||
@@ -5886,7 +5966,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess
}
if (switch_media_handle_test_media_flag(smh, SCMF_MULTI_ANSWER_AUDIO)) {
- switch_mutex_lock(smh->mutex);
+ switch_mutex_lock(smh->sdp_mutex);
for (pmap = a_engine->cur_payload_map; pmap && pmap->allocated; pmap = pmap->next) {
if (pmap->pt != a_engine->cur_payload_map->pt) {
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtpmap:%d %s/%ld\n",
@@ -5894,7 +5974,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess
pmap->rate);
}
}
- switch_mutex_unlock(smh->mutex);
+ switch_mutex_unlock(smh->sdp_mutex);
}
@@ -6165,13 +6245,13 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), " %d", v_engine->cur_payload_map->agreed_pt);
if (switch_media_handle_test_media_flag(smh, SCMF_MULTI_ANSWER_VIDEO)) {
- switch_mutex_lock(smh->mutex);
+ switch_mutex_lock(smh->sdp_mutex);
for (pmap = v_engine->cur_payload_map; pmap && pmap->allocated; pmap = pmap->next) {
if (pmap->pt != v_engine->cur_payload_map->pt) {
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), " %d", pmap->pt);
}
}
- switch_mutex_unlock(smh->mutex);
+ switch_mutex_unlock(smh->sdp_mutex);
}
} else if (smh->mparams->num_codecs) {
@@ -6216,6 +6296,10 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess
vp8 = v_engine->cur_payload_map->pt;
}
+ if (!strcasecmp(v_engine->cur_payload_map->rm_encoding, "red")) {
+ red = v_engine->cur_payload_map->pt;
+ }
+
rate = v_engine->cur_payload_map->rm_rate;
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtpmap:%d %s/%ld\n",
v_engine->cur_payload_map->pt, v_engine->cur_payload_map->rm_encoding,
@@ -6247,7 +6331,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess
if (switch_media_handle_test_media_flag(smh, SCMF_MULTI_ANSWER_VIDEO)) {
- switch_mutex_lock(smh->mutex);
+ switch_mutex_lock(smh->sdp_mutex);
for (pmap = v_engine->cur_payload_map; pmap && pmap->allocated; pmap = pmap->next) {
if (pmap->pt != v_engine->cur_payload_map->pt) {
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtpmap:%d %s/%ld\n",
@@ -6255,7 +6339,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess
}
}
- switch_mutex_unlock(smh->mutex);
+ switch_mutex_unlock(smh->sdp_mutex);
}
@@ -6299,6 +6383,10 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess
vp8 = ianacode;
}
+ if (!strcasecmp(imp->iananame, "red")) {
+ red = ianacode;
+ }
+
if (channels > 1) {
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtpmap:%d %s/%d/%d\n", ianacode, imp->iananame,
imp->samples_per_second, channels);
@@ -6377,11 +6465,15 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "b=AS:%d\n", bw);
}
-
if (vp8) {
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf),
"a=rtcp-fb:%d ccm fir\n", vp8);
}
+
+ if (red) {
+ switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf),
+ "a=rtcp-fb:%d nack\n", vp8);
+ }
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ssrc:%u cname:%s\n", v_engine->ssrc, smh->cname);
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ssrc:%u msid:%s v0\n", v_engine->ssrc, smh->msid);
@@ -7619,7 +7711,7 @@ SWITCH_DECLARE(stfu_instance_t *) switch_core_media_get_jb(switch_core_session_t
//?
-SWITCH_DECLARE(void) switch_core_media_set_sdp_codec_string(switch_core_session_t *session, const char *r_sdp)
+SWITCH_DECLARE(void) switch_core_media_set_sdp_codec_string(switch_core_session_t *session, const char *r_sdp, switch_sdp_type_t sdp_type)
{
sdp_parser_t *parser;
sdp_session_t *sdp;
@@ -7635,7 +7727,7 @@ SWITCH_DECLARE(void) switch_core_media_set_sdp_codec_string(switch_core_session_
if ((parser = sdp_parse(NULL, r_sdp, (int) strlen(r_sdp), 0))) {
if ((sdp = sdp_session(parser))) {
- switch_core_media_set_r_sdp_codec_string(session, switch_core_media_get_codec_string(session), sdp);
+ switch_core_media_set_r_sdp_codec_string(session, switch_core_media_get_codec_string(session), sdp, sdp_type);
}
sdp_parser_free(parser);
@@ -7699,7 +7791,7 @@ static void add_audio_codec(sdp_rtpmap_t *map, int ptime, char *buf, switch_size
}
-SWITCH_DECLARE(void) switch_core_media_set_r_sdp_codec_string(switch_core_session_t *session, const char *codec_string, sdp_session_t *sdp)
+static void switch_core_media_set_r_sdp_codec_string(switch_core_session_t *session, const char *codec_string, sdp_session_t *sdp, switch_sdp_type_t sdp_type)
{
char buf[1024] = { 0 };
sdp_media_t *m;
@@ -7759,6 +7851,33 @@ SWITCH_DECLARE(void) switch_core_media_set_r_sdp_codec_string(switch_core_sessio
for (m = sdp->sdp_media; m; m = m->m_next) {
ptime = dptime;
+
+ if ((m->m_type == sdp_media_audio || m->m_type == sdp_media_video) && m->m_port) {
+ for (map = m->m_rtpmaps; map; map = map->rm_next) {
+ for (attr = m->m_attributes; attr; attr = attr->a_next) {
+ if (zstr(attr->a_name)) {
+ continue;
+ }
+ if (!strcasecmp(attr->a_name, "ptime") && attr->a_value) {
+ ptime = atoi(attr->a_value);
+ break;
+ }
+ }
+ switch_core_media_add_payload_map(session,
+ m->m_type == sdp_media_audio ? SWITCH_MEDIA_TYPE_AUDIO : SWITCH_MEDIA_TYPE_VIDEO,
+ map->rm_encoding,
+ sdp_type,
+ map->rm_pt,
+ map->rm_rate,
+ ptime,
+ SWITCH_FALSE);
+ }
+ }
+ }
+
+ for (m = sdp->sdp_media; m; m = m->m_next) {
+ ptime = dptime;
+
if (m->m_type == sdp_media_image && m->m_port) {
switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ",t38");
} else if (m->m_type == sdp_media_audio && m->m_port) {
diff --git a/src/switch_rtp.c b/src/switch_rtp.c
index a0e80013f0..aa296c95da 100644
--- a/src/switch_rtp.c
+++ b/src/switch_rtp.c
@@ -399,7 +399,6 @@ struct switch_rtp {
switch_core_session_t *session;
payload_map_t **pmaps;
payload_map_t *pmap_tail;
- int pmap_ttl;
#ifdef ENABLE_ZRTP
zrtp_session_t *zrtp_session;
@@ -6200,10 +6199,10 @@ SWITCH_DECLARE(int) switch_rtp_write_frame(switch_rtp_t *rtp_session, switch_fra
rtp_session->stats.outbound.packet_count++;
}
- if (frame->pmap && rtp_session->pmaps && *rtp_session->pmaps && rtp_session->pmap_ttl > 1) {
+ if (frame->pmap && rtp_session->pmaps && *rtp_session->pmaps) {
payload_map_t *pmap;
- switch_mutex_lock(rtp_session->flag_mutex);
+ switch_mutex_lock(rtp_session->flag_mutex);
for (pmap = *rtp_session->pmaps; pmap; pmap = pmap->next) {
if (pmap->hash == frame->pmap->hash && !strcmp(pmap->iananame, frame->pmap->iananame)) {
payload = pmap->recv_pt;