nut n honey
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@9591 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
parent
fb61897971
commit
eac4e3e10a
|
@ -163,6 +163,9 @@ SWITCH_DECLARE(switch_rtp_t *) switch_rtp_new(const char *rx_host,
|
|||
*/
|
||||
SWITCH_DECLARE(switch_status_t) switch_rtp_set_remote_address(switch_rtp_t *rtp_session, const char *host, switch_port_t port, const char **err);
|
||||
|
||||
SWITCH_DECLARE(char *) switch_rtp_get_remote_host(switch_rtp_t *rtp_session);
|
||||
SWITCH_DECLARE(switch_port_t) switch_rtp_get_remote_port(switch_rtp_t *rtp_session);
|
||||
|
||||
SWITCH_DECLARE(void) switch_rtp_set_max_missed_packets(switch_rtp_t *rtp_session, uint32_t max);
|
||||
|
||||
/*!
|
||||
|
|
|
@ -110,6 +110,7 @@ SWITCH_BEGIN_EXTERN_C
|
|||
#define SWITCH_PATH_SEPARATOR "/"
|
||||
#endif
|
||||
#define SWITCH_URL_SEPARATOR "://"
|
||||
#define SWITCH_BYPASS_MEDIA_AFTER_BRIDGE_VARIABLE "bypass_media_after_bridge"
|
||||
#define SWITCH_READ_RESULT_VARIABLE "read_result"
|
||||
#define SWITCH_COPY_XML_CDR_VARIABLE "copy_xml_cdr"
|
||||
#define SWITCH_CURRENT_APPLICATION_VARIABLE "current_application"
|
||||
|
|
|
@ -114,7 +114,9 @@ static switch_status_t sofia_on_routing(switch_core_session_t *session)
|
|||
private_object_t *tech_pvt = (private_object_t *) switch_core_session_get_private(session);
|
||||
switch_assert(tech_pvt != NULL);
|
||||
|
||||
switch_clear_flag_locked(tech_pvt, TFLAG_SIP_HOLD);
|
||||
if (!switch_test_flag(tech_pvt, TFLAG_HOLD_LOCK)) {
|
||||
switch_clear_flag_locked(tech_pvt, TFLAG_SIP_HOLD);
|
||||
}
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s SOFIA ROUTING\n", switch_channel_get_name(switch_core_session_get_channel(session)));
|
||||
|
||||
|
@ -127,7 +129,9 @@ static switch_status_t sofia_on_reset(switch_core_session_t *session)
|
|||
private_object_t *tech_pvt = (private_object_t *) switch_core_session_get_private(session);
|
||||
switch_assert(tech_pvt != NULL);
|
||||
|
||||
switch_clear_flag_locked(tech_pvt, TFLAG_SIP_HOLD);
|
||||
if (!switch_test_flag(tech_pvt, TFLAG_HOLD_LOCK)) {
|
||||
switch_clear_flag_locked(tech_pvt, TFLAG_SIP_HOLD);
|
||||
}
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s SOFIA RESET\n", switch_channel_get_name(switch_core_session_get_channel(session)));
|
||||
|
||||
|
@ -140,7 +144,9 @@ static switch_status_t sofia_on_hibernate(switch_core_session_t *session)
|
|||
private_object_t *tech_pvt = switch_core_session_get_private(session);
|
||||
switch_assert(tech_pvt != NULL);
|
||||
|
||||
switch_clear_flag_locked(tech_pvt, TFLAG_SIP_HOLD);
|
||||
if (!switch_test_flag(tech_pvt, TFLAG_HOLD_LOCK)) {
|
||||
switch_clear_flag_locked(tech_pvt, TFLAG_SIP_HOLD);
|
||||
}
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s SOFIA HIBERNATE\n", switch_channel_get_name(switch_core_session_get_channel(session)));
|
||||
|
||||
|
@ -152,7 +158,9 @@ static switch_status_t sofia_on_execute(switch_core_session_t *session)
|
|||
private_object_t *tech_pvt = (private_object_t *) switch_core_session_get_private(session);
|
||||
switch_assert(tech_pvt != NULL);
|
||||
|
||||
switch_clear_flag_locked(tech_pvt, TFLAG_SIP_HOLD);
|
||||
if (!switch_test_flag(tech_pvt, TFLAG_HOLD_LOCK)) {
|
||||
switch_clear_flag_locked(tech_pvt, TFLAG_SIP_HOLD);
|
||||
}
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s SOFIA EXECUTE\n", switch_channel_get_name(switch_core_session_get_channel(session)));
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
|
|
|
@ -190,7 +190,7 @@ typedef enum {
|
|||
TFLAG_VAD_IN = (1 << 11),
|
||||
TFLAG_VAD_OUT = (1 << 12),
|
||||
TFLAG_VAD = (1 << 13),
|
||||
TFLAG_USE_ME = (1 << 14),
|
||||
TFLAG_3PCC = (1 << 14),
|
||||
TFLAG_READY = (1 << 15),
|
||||
TFLAG_REINVITE = (1 << 16),
|
||||
TFLAG_REFER = (1 << 17),
|
||||
|
@ -205,7 +205,8 @@ typedef enum {
|
|||
TFLAG_VIDEO = (1 << 26),
|
||||
TFLAG_TPORT_LOG = (1 << 27),
|
||||
TFLAG_SENT_UPDATE = (1 << 28),
|
||||
TFLAG_PROXY_MEDIA = (1 << 29)
|
||||
TFLAG_PROXY_MEDIA = (1 << 29),
|
||||
TFLAG_HOLD_LOCK = (1 << 30)
|
||||
} TFLAGS;
|
||||
|
||||
struct mod_sofia_globals {
|
||||
|
@ -302,6 +303,12 @@ typedef enum {
|
|||
PRES_TYPE_PASSIVE = 2
|
||||
} sofia_presence_type_t;
|
||||
|
||||
typedef enum {
|
||||
MEDIA_OPT_NONE = 0,
|
||||
MEDIA_OPT_MEDIA_ON_HOLD = (1 << 0),
|
||||
MEDIA_OPT_BYPASS_AFTER_ATT_XFER = (1 << 1)
|
||||
} sofia_media_options_t;
|
||||
|
||||
struct sofia_profile {
|
||||
int debug;
|
||||
char *name;
|
||||
|
@ -376,6 +383,7 @@ struct sofia_profile {
|
|||
uint32_t nat_acl_count;
|
||||
int rport_level;
|
||||
sofia_presence_type_t pres_type;
|
||||
sofia_media_options_t media_options;
|
||||
};
|
||||
|
||||
struct private_object {
|
||||
|
@ -487,6 +495,7 @@ struct private_object {
|
|||
char *remote_ip;
|
||||
int remote_port;
|
||||
int got_bye;
|
||||
int hold_laps;
|
||||
};
|
||||
|
||||
struct callback_t {
|
||||
|
@ -687,3 +696,4 @@ switch_status_t reconfig_sofia(sofia_profile_t *profile);
|
|||
void sofia_glue_del_gateway(sofia_gateway_t *gp);
|
||||
void sofia_reg_send_reboot(sofia_profile_t *profile, const char *user, const char *host, const char *contact, const char *user_agent);
|
||||
void sofia_glue_restart_all_profiles(void);
|
||||
void sofia_glue_toggle_hold(private_object_t *tech_pvt, int sendonly);
|
||||
|
|
|
@ -1591,6 +1591,12 @@ switch_status_t config_sofia(int reload, char *profile_name)
|
|||
profile->mflags &= ~MFLAG_REFER;
|
||||
} else if (!strcasecmp(var, "disable-register") && switch_true(val)) {
|
||||
profile->mflags &= ~MFLAG_REGISTER;
|
||||
} else if (!strcasecmp(var, "media-option")) {
|
||||
if (!strcasecmp(val, "resume-media-on-hold")) {
|
||||
profile->media_options |= MEDIA_OPT_MEDIA_ON_HOLD;
|
||||
} else if (!strcasecmp(val, "bypass-media-after-att-xfer")) {
|
||||
profile->media_options |= MEDIA_OPT_BYPASS_AFTER_ATT_XFER;
|
||||
}
|
||||
} else if (!strcasecmp(var, "manage-presence")) {
|
||||
if (!strcasecmp(val, "passive")) {
|
||||
profile->pres_type = PRES_TYPE_PASSIVE;
|
||||
|
@ -2144,6 +2150,50 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/* Pure black magic, if you can't understand this code you are lucky.........*/
|
||||
void *SWITCH_THREAD_FUNC media_on_hold_thread_run(switch_thread_t *thread, void *obj)
|
||||
{
|
||||
switch_core_session_t *other_session = NULL, *session = (switch_core_session_t *) obj;
|
||||
const char *uuid;
|
||||
|
||||
if (switch_core_session_read_lock(session) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
private_object_t *tech_pvt = switch_core_session_get_private(session);
|
||||
|
||||
if ((uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE)) && (other_session = switch_core_session_locate(uuid))) {
|
||||
if (switch_core_session_compare(session, other_session)) {
|
||||
switch_set_flag_locked(tech_pvt, TFLAG_HOLD_LOCK);
|
||||
switch_ivr_media(switch_core_session_get_uuid(other_session), SMF_REBRIDGE);
|
||||
|
||||
if (tech_pvt->rtp_session) {
|
||||
switch_rtp_clear_flag(tech_pvt->rtp_session, SWITCH_RTP_FLAG_AUTOADJ);
|
||||
}
|
||||
|
||||
sofia_glue_toggle_hold(tech_pvt, 1);
|
||||
switch_core_session_rwunlock(other_session);
|
||||
}
|
||||
}
|
||||
|
||||
switch_core_session_rwunlock(session);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void launch_media_on_hold(switch_core_session_t *session)
|
||||
{
|
||||
switch_thread_t *thread;
|
||||
switch_threadattr_t *thd_attr = NULL;
|
||||
|
||||
switch_threadattr_create(&thd_attr, switch_core_session_get_pool(session));
|
||||
switch_threadattr_detach_set(thd_attr, 1);
|
||||
switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
|
||||
switch_threadattr_priority_increase(thd_attr);
|
||||
switch_thread_create(&thread, thd_attr, media_on_hold_thread_run, session, switch_core_session_get_pool(session));
|
||||
}
|
||||
|
||||
|
||||
static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
|
||||
char const *phrase,
|
||||
nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
|
||||
|
@ -2348,6 +2398,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
|
|||
switch_ivr_uuid_bridge(br_a, br_b);
|
||||
switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "ATTENDED_TRANSFER");
|
||||
switch_clear_flag_locked(tech_pvt, TFLAG_SIP_HOLD);
|
||||
switch_clear_flag_locked(tech_pvt, TFLAG_HOLD_LOCK);
|
||||
switch_channel_hangup(channel, SWITCH_CAUSE_ATTENDED_TRANSFER);
|
||||
} else {
|
||||
switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "ATTENDED_TRANSFER_ERROR");
|
||||
|
@ -2377,6 +2428,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
|
|||
switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "RECEIVED_NOSDP");
|
||||
sofia_glue_tech_choose_port(tech_pvt, 0);
|
||||
sofia_glue_set_local_sdp(tech_pvt, NULL, 0, NULL, 0);
|
||||
switch_set_flag_locked(tech_pvt, TFLAG_3PCC);
|
||||
switch_channel_set_state(channel, CS_HIBERNATE);
|
||||
nua_respond(tech_pvt->nh, SIP_200_OK,
|
||||
SIPTAG_CONTACT_STR(tech_pvt->profile->url),
|
||||
|
@ -2404,13 +2456,55 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
|
|||
sdp_parser_t *parser;
|
||||
sdp_session_t *sdp;
|
||||
uint8_t match = 0, is_ok = 1;
|
||||
tech_pvt->hold_laps = 0;
|
||||
|
||||
if (r_sdp) {
|
||||
if (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
|
||||
|
||||
if ((uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE))
|
||||
&& (other_session = switch_core_session_locate(uuid))) {
|
||||
switch_core_session_message_t msg = { 0 };
|
||||
|
||||
if (profile->media_options & MEDIA_OPT_MEDIA_ON_HOLD) {
|
||||
tech_pvt->hold_laps = 1;
|
||||
switch_channel_set_variable(channel, SWITCH_R_SDP_VARIABLE, r_sdp);
|
||||
switch_channel_clear_flag(channel, CF_PROXY_MODE);
|
||||
tech_pvt->local_sdp_str = NULL;
|
||||
|
||||
if (!switch_channel_media_ready(channel)) {
|
||||
if (!switch_channel_test_flag(tech_pvt->channel, CF_OUTBOUND)) {
|
||||
//const char *r_sdp = switch_channel_get_variable(channel, SWITCH_R_SDP_VARIABLE);
|
||||
|
||||
tech_pvt->num_codecs = 0;
|
||||
sofia_glue_tech_prepare_codecs(tech_pvt);
|
||||
if (sofia_glue_tech_media(tech_pvt, r_sdp) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "CODEC NEGOTIATION ERROR");
|
||||
status = SWITCH_STATUS_FALSE;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!switch_rtp_ready(tech_pvt->rtp_session)) {
|
||||
sofia_glue_tech_prepare_codecs(tech_pvt);
|
||||
if ((status = sofia_glue_tech_choose_port(tech_pvt, 0)) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
sofia_glue_set_local_sdp(tech_pvt, NULL, 0, NULL, 1);
|
||||
|
||||
nua_respond(tech_pvt->nh, SIP_200_OK,
|
||||
SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
|
||||
SOATAG_USER_SDP_STR(tech_pvt->local_sdp_str),
|
||||
SOATAG_REUSE_REJECTED(1),
|
||||
SOATAG_ORDERED_USER(1), SOATAG_AUDIO_AUX("cn telephone-event"), NUTAG_INCLUDE_EXTRA_SDP(1), TAG_END());
|
||||
launch_media_on_hold(session);
|
||||
|
||||
switch_core_session_rwunlock(other_session);
|
||||
goto done;
|
||||
}
|
||||
|
||||
msg.message_id = SWITCH_MESSAGE_INDICATE_MEDIA_REDIRECT;
|
||||
msg.from = __FILE__;
|
||||
msg.string_arg = (char *) r_sdp;
|
||||
|
@ -2559,7 +2653,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
|
|||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "RTP Error!\n");
|
||||
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
||||
}
|
||||
if (switch_channel_get_state(channel) == CS_HIBERNATE) {
|
||||
if (switch_channel_get_state(channel) == CS_HIBERNATE && switch_test_flag(tech_pvt, TFLAG_3PCC)) {
|
||||
switch_set_flag_locked(tech_pvt, TFLAG_READY);
|
||||
switch_channel_set_state(channel, CS_INIT);
|
||||
switch_set_flag(tech_pvt, TFLAG_SDP);
|
||||
|
@ -2800,7 +2894,13 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t
|
|||
switch_str_nil(br_b));
|
||||
|
||||
if (br_a && br_b) {
|
||||
switch_core_session_t *new_b_session = NULL, *a_session = NULL;
|
||||
switch_core_session_t *new_b_session = NULL, *a_session = NULL, *tmp = NULL;
|
||||
|
||||
if ((profile->media_options & MEDIA_OPT_BYPASS_AFTER_ATT_XFER) && (tmp = switch_core_session_locate(br_b))) {
|
||||
switch_channel_t *tchannel = switch_core_session_get_channel(tmp);
|
||||
switch_channel_set_variable(tchannel, SWITCH_BYPASS_MEDIA_AFTER_BRIDGE_VARIABLE, "true");
|
||||
switch_core_session_rwunlock(tmp);
|
||||
}
|
||||
|
||||
switch_ivr_uuid_bridge(br_b, br_a);
|
||||
switch_channel_set_variable(channel_b, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "ATTENDED_TRANSFER");
|
||||
|
@ -2808,17 +2908,19 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t
|
|||
NUTAG_SUBSTATE(nua_substate_terminated), SIPTAG_PAYLOAD_STR("SIP/2.0 200 OK"), SIPTAG_EVENT_STR(etmp), TAG_END());
|
||||
|
||||
switch_clear_flag_locked(b_tech_pvt, TFLAG_SIP_HOLD);
|
||||
switch_clear_flag_locked(tech_pvt, TFLAG_HOLD_LOCK);
|
||||
switch_ivr_park_session(b_session);
|
||||
new_b_session = switch_core_session_locate(br_b);
|
||||
a_session = switch_core_session_locate(br_a);
|
||||
sofia_info_send_sipfrag(a_session, new_b_session);
|
||||
|
||||
if (new_b_session) {
|
||||
switch_core_session_rwunlock(new_b_session);
|
||||
}
|
||||
|
||||
if (a_session) {
|
||||
switch_core_session_rwunlock(a_session);
|
||||
}
|
||||
//switch_channel_hangup(channel_b, SWITCH_CAUSE_ATTENDED_TRANSFER);
|
||||
} else {
|
||||
if (!br_a && !br_b) {
|
||||
switch_set_flag_locked(tech_pvt, TFLAG_NOHUP);
|
||||
|
|
|
@ -858,7 +858,7 @@ switch_status_t sofia_glue_tech_proxy_remote_addr(private_object_t *tech_pvt)
|
|||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "VIDEO RTP CHANGING DEST TO: [%s:%d]\n",
|
||||
tech_pvt->remote_sdp_video_ip, tech_pvt->remote_sdp_video_port);
|
||||
if (!sofia_test_pflag(tech_pvt->profile, PFLAG_DISABLE_RTP_AUTOADJ) &&
|
||||
if (!sofia_test_pflag(tech_pvt->profile, PFLAG_DISABLE_RTP_AUTOADJ) && !switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MODE) &&
|
||||
!((val = switch_channel_get_variable(tech_pvt->channel, "disable_rtp_auto_adjust")) && switch_true(val))) {
|
||||
/* Reactivate the NAT buster flag. */
|
||||
switch_rtp_set_flag(tech_pvt->video_rtp_session, SWITCH_RTP_FLAG_AUTOADJ);
|
||||
|
@ -1749,12 +1749,18 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f
|
|||
}
|
||||
|
||||
if (tech_pvt->rtp_session && switch_test_flag(tech_pvt, TFLAG_REINVITE)) {
|
||||
const char *ip = switch_channel_get_variable(tech_pvt->channel, SWITCH_LOCAL_MEDIA_IP_VARIABLE);
|
||||
const char *port = switch_channel_get_variable(tech_pvt->channel, SWITCH_LOCAL_MEDIA_PORT_VARIABLE);
|
||||
//const char *ip = switch_channel_get_variable(tech_pvt->channel, SWITCH_LOCAL_MEDIA_IP_VARIABLE);
|
||||
//const char *port = switch_channel_get_variable(tech_pvt->channel, SWITCH_LOCAL_MEDIA_PORT_VARIABLE);
|
||||
char *remote_host = switch_rtp_get_remote_host(tech_pvt->rtp_session);
|
||||
switch_port_t remote_port = switch_rtp_get_remote_port(tech_pvt->rtp_session);
|
||||
|
||||
if (ip && port && !strcmp(ip, tech_pvt->adv_sdp_audio_ip) && atoi(port) == tech_pvt->remote_sdp_audio_port) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Audio params are unchanged.\n");
|
||||
if (remote_host && remote_port && !strcmp(remote_host, tech_pvt->remote_sdp_audio_ip) && remote_port == tech_pvt->remote_sdp_audio_port) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Audio params are unchanged for %s.\n", switch_channel_get_name(tech_pvt->channel));
|
||||
goto video;
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Audio params changed for %s from %s:%d to %s:%d\n",
|
||||
switch_channel_get_name(tech_pvt->channel),
|
||||
remote_host, remote_port, tech_pvt->remote_sdp_audio_ip, tech_pvt->remote_sdp_audio_port);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1944,7 +1950,7 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f
|
|||
sofia_glue_tech_choose_video_port(tech_pvt, 1);
|
||||
}
|
||||
|
||||
if (!sofia_test_pflag(tech_pvt->profile, PFLAG_DISABLE_RTP_AUTOADJ) &&
|
||||
if (!sofia_test_pflag(tech_pvt->profile, PFLAG_DISABLE_RTP_AUTOADJ) && !switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MODE) &&
|
||||
!((val = switch_channel_get_variable(tech_pvt->channel, "disable_rtp_auto_adjust")) && switch_true(val))) {
|
||||
flags = (switch_rtp_flag_t) (SWITCH_RTP_FLAG_USE_TIMER | SWITCH_RTP_FLAG_AUTOADJ |
|
||||
SWITCH_RTP_FLAG_DATAWAIT | SWITCH_RTP_FLAG_NOBLOCK | SWITCH_RTP_FLAG_RAW_WRITE);
|
||||
|
@ -2042,6 +2048,71 @@ switch_status_t sofia_glue_tech_media(private_object_t *tech_pvt, const char *r_
|
|||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
void sofia_glue_toggle_hold(private_object_t *tech_pvt, int sendonly)
|
||||
{
|
||||
if (sendonly && switch_channel_test_flag(tech_pvt->channel, CF_ANSWERED)) {
|
||||
if (!switch_test_flag(tech_pvt, TFLAG_SIP_HOLD)) {
|
||||
const char *stream;
|
||||
|
||||
switch_set_flag_locked(tech_pvt, TFLAG_SIP_HOLD);
|
||||
switch_channel_presence(tech_pvt->channel, "unknown", "hold", NULL);
|
||||
|
||||
if (tech_pvt->max_missed_hold_packets) {
|
||||
switch_rtp_set_max_missed_packets(tech_pvt->rtp_session, tech_pvt->max_missed_hold_packets);
|
||||
}
|
||||
|
||||
if (!(stream = switch_channel_get_variable(tech_pvt->channel, SWITCH_HOLD_MUSIC_VARIABLE))) {
|
||||
stream = tech_pvt->profile->hold_music;
|
||||
}
|
||||
|
||||
if (stream && switch_is_moh(stream)) {
|
||||
if (!strcasecmp(stream, "indicate_hold")) {
|
||||
switch_channel_set_flag(tech_pvt->channel, CF_SUSPEND);
|
||||
switch_channel_set_flag(tech_pvt->channel, CF_HOLD);
|
||||
switch_ivr_hold_uuid(switch_channel_get_variable(tech_pvt->channel, SWITCH_SIGNAL_BOND_VARIABLE), NULL, 0);
|
||||
} else {
|
||||
switch_ivr_broadcast(switch_channel_get_variable(tech_pvt->channel, SWITCH_SIGNAL_BOND_VARIABLE), stream, SMF_ECHO_ALEG | SMF_LOOP);
|
||||
switch_yield(250000);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (switch_test_flag(tech_pvt, TFLAG_HOLD_LOCK)) {
|
||||
switch_set_flag(tech_pvt, TFLAG_SIP_HOLD);
|
||||
}
|
||||
|
||||
switch_clear_flag_locked(tech_pvt, TFLAG_HOLD_LOCK);
|
||||
|
||||
if (switch_test_flag(tech_pvt, TFLAG_SIP_HOLD)) {
|
||||
const char *uuid;
|
||||
switch_core_session_t *b_session;
|
||||
|
||||
switch_yield(250000);
|
||||
|
||||
if (tech_pvt->max_missed_packets) {
|
||||
switch_rtp_set_max_missed_packets(tech_pvt->rtp_session, tech_pvt->max_missed_packets);
|
||||
}
|
||||
|
||||
if ((uuid = switch_channel_get_variable(tech_pvt->channel, SWITCH_SIGNAL_BOND_VARIABLE)) && (b_session = switch_core_session_locate(uuid))) {
|
||||
switch_channel_t *b_channel = switch_core_session_get_channel(b_session);
|
||||
|
||||
if (switch_channel_test_flag(tech_pvt->channel, CF_HOLD)) {
|
||||
switch_ivr_unhold(b_session);
|
||||
switch_channel_clear_flag(tech_pvt->channel, CF_SUSPEND);
|
||||
switch_channel_clear_flag(tech_pvt->channel, CF_HOLD);
|
||||
} else {
|
||||
switch_channel_stop_broadcast(b_channel);
|
||||
switch_channel_wait_for_flag(b_channel, CF_BROADCAST, SWITCH_FALSE, 5000, NULL);
|
||||
}
|
||||
switch_core_session_rwunlock(b_session);
|
||||
}
|
||||
|
||||
switch_clear_flag_locked(tech_pvt, TFLAG_SIP_HOLD);
|
||||
switch_channel_presence(tech_pvt->channel, "unknown", "unhold", NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, sdp_session_t *sdp)
|
||||
{
|
||||
uint8_t match = 0;
|
||||
|
@ -2093,60 +2164,9 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, sdp_session_t *
|
|||
}
|
||||
}
|
||||
|
||||
if (sendonly && switch_channel_test_flag(channel, CF_ANSWERED)) {
|
||||
if (!switch_test_flag(tech_pvt, TFLAG_SIP_HOLD)) {
|
||||
const char *stream;
|
||||
|
||||
switch_set_flag_locked(tech_pvt, TFLAG_SIP_HOLD);
|
||||
switch_channel_presence(tech_pvt->channel, "unknown", "hold", NULL);
|
||||
|
||||
if (tech_pvt->max_missed_hold_packets) {
|
||||
switch_rtp_set_max_missed_packets(tech_pvt->rtp_session, tech_pvt->max_missed_hold_packets);
|
||||
}
|
||||
|
||||
if (!(stream = switch_channel_get_variable(tech_pvt->channel, SWITCH_HOLD_MUSIC_VARIABLE))) {
|
||||
stream = tech_pvt->profile->hold_music;
|
||||
}
|
||||
|
||||
if (stream && switch_is_moh(stream)) {
|
||||
if (!strcasecmp(stream, "indicate_hold")) {
|
||||
switch_channel_set_flag(tech_pvt->channel, CF_SUSPEND);
|
||||
switch_channel_set_flag(tech_pvt->channel, CF_HOLD);
|
||||
switch_ivr_hold_uuid(switch_channel_get_variable(tech_pvt->channel, SWITCH_SIGNAL_BOND_VARIABLE), NULL, 0);
|
||||
} else {
|
||||
switch_ivr_broadcast(switch_channel_get_variable(tech_pvt->channel, SWITCH_SIGNAL_BOND_VARIABLE), stream, SMF_ECHO_ALEG | SMF_LOOP);
|
||||
switch_yield(250000);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (switch_test_flag(tech_pvt, TFLAG_SIP_HOLD)) {
|
||||
const char *uuid;
|
||||
switch_core_session_t *b_session;
|
||||
|
||||
switch_yield(250000);
|
||||
|
||||
if (tech_pvt->max_missed_packets) {
|
||||
switch_rtp_set_max_missed_packets(tech_pvt->rtp_session, tech_pvt->max_missed_packets);
|
||||
}
|
||||
|
||||
if ((uuid = switch_channel_get_variable(tech_pvt->channel, SWITCH_SIGNAL_BOND_VARIABLE)) && (b_session = switch_core_session_locate(uuid))) {
|
||||
switch_channel_t *b_channel = switch_core_session_get_channel(b_session);
|
||||
|
||||
if (switch_channel_test_flag(tech_pvt->channel, CF_HOLD)) {
|
||||
switch_ivr_unhold(b_session);
|
||||
switch_channel_clear_flag(tech_pvt->channel, CF_SUSPEND);
|
||||
switch_channel_clear_flag(tech_pvt->channel, CF_HOLD);
|
||||
} else {
|
||||
switch_channel_stop_broadcast(b_channel);
|
||||
switch_channel_wait_for_flag(b_channel, CF_BROADCAST, SWITCH_FALSE, 5000, NULL);
|
||||
}
|
||||
switch_core_session_rwunlock(b_session);
|
||||
}
|
||||
|
||||
switch_clear_flag_locked(tech_pvt, TFLAG_SIP_HOLD);
|
||||
switch_channel_presence(tech_pvt->channel, "unknown", "unhold", NULL);
|
||||
}
|
||||
if (!tech_pvt->hold_laps) {
|
||||
tech_pvt->hold_laps++;
|
||||
sofia_glue_toggle_hold(tech_pvt, sendonly);
|
||||
}
|
||||
|
||||
for (m = sdp->sdp_media; m; m = m->m_next) {
|
||||
|
|
|
@ -103,8 +103,8 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj)
|
|||
switch_codec_t silence_codec = { 0 };
|
||||
switch_frame_t silence_frame = { 0 };
|
||||
int16_t silence_data[SWITCH_RECOMMENDED_BUFFER_SIZE/2] = { 0 };
|
||||
const char *silence_var;
|
||||
int silence_val = 0;
|
||||
const char *silence_var, *var;
|
||||
int silence_val = 0, bypass_media_after_bridge = 0;
|
||||
#ifdef SWITCH_VIDEO_IN_THREADS
|
||||
struct vid_helper vh = { 0 };
|
||||
uint32_t vid_launch = 0;
|
||||
|
@ -141,6 +141,11 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj)
|
|||
goto end_of_bridge_loop;
|
||||
}
|
||||
|
||||
if ((var = switch_channel_get_variable(chan_a, SWITCH_BYPASS_MEDIA_AFTER_BRIDGE_VARIABLE)) && switch_true(var)) {
|
||||
bypass_media_after_bridge = 1;
|
||||
switch_channel_set_variable(chan_a, SWITCH_BYPASS_MEDIA_AFTER_BRIDGE_VARIABLE, NULL);
|
||||
}
|
||||
|
||||
if ((silence_var = switch_channel_get_variable(chan_a, "bridge_generate_comfort_noise"))) {
|
||||
switch_codec_t *read_codec = NULL;
|
||||
|
||||
|
@ -234,6 +239,11 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj)
|
|||
}
|
||||
#endif
|
||||
|
||||
if (loop_count > 50 && bypass_media_after_bridge) {
|
||||
switch_ivr_nomedia(switch_core_session_get_uuid(session_a), SMF_REBRIDGE);
|
||||
bypass_media_after_bridge = 0;
|
||||
}
|
||||
|
||||
/* if 1 channel has DTMF pass it to the other */
|
||||
while (switch_channel_has_dtmf(chan_a)) {
|
||||
switch_dtmf_t dtmf = { 0, 0 };
|
||||
|
|
|
@ -166,6 +166,7 @@ struct switch_rtp {
|
|||
char *ice_user;
|
||||
char *user_ice;
|
||||
char *timer_name;
|
||||
char *remote_host_str;
|
||||
switch_time_t last_stun;
|
||||
uint32_t samples_per_interval;
|
||||
uint32_t conf_samples_per_interval;
|
||||
|
@ -597,6 +598,17 @@ SWITCH_DECLARE(void) switch_rtp_set_max_missed_packets(switch_rtp_t *rtp_session
|
|||
rtp_session->max_missed_packets = max;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(char *) switch_rtp_get_remote_host(switch_rtp_t *rtp_session)
|
||||
{
|
||||
return switch_strlen_zero(rtp_session->remote_host_str) ? "0.0.0.0" : rtp_session->remote_host_str;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_port_t) switch_rtp_get_remote_port(switch_rtp_t *rtp_session)
|
||||
{
|
||||
return rtp_session->remote_port;
|
||||
}
|
||||
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_rtp_set_remote_address(switch_rtp_t *rtp_session, const char *host, switch_port_t port, const char **err)
|
||||
{
|
||||
switch_sockaddr_t *remote_addr;
|
||||
|
@ -611,6 +623,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_set_remote_address(switch_rtp_t *rtp_
|
|||
switch_mutex_lock(rtp_session->write_mutex);
|
||||
|
||||
rtp_session->remote_addr = remote_addr;
|
||||
rtp_session->remote_host_str = switch_core_strdup(rtp_session->pool, host);
|
||||
rtp_session->remote_port = port;
|
||||
|
||||
if (rtp_session->sock_input &&
|
||||
|
|
Loading…
Reference in New Issue