refactor to avoid some potential issues with channels that are hungup instantly after being answered
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@4926 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
parent
ff44ce11cc
commit
eb2124ae32
|
@ -283,6 +283,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text(switch_core_session_t *ses
|
|||
\param cid_num_override override the caller id number
|
||||
\param caller_profile_override override the entire calling caller profile
|
||||
\return SWITCH_STATUS_SUCCESS if bleg is a running session.
|
||||
\note bleg will be read locked which must be unlocked with switch_core_session_rwunlock() before losing scope
|
||||
*/
|
||||
SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *session,
|
||||
switch_core_session_t **bleg,
|
||||
|
|
|
@ -39,7 +39,7 @@ static const char modname[] = "mod_bridgecall";
|
|||
static void audio_bridge_function(switch_core_session_t *session, char *data)
|
||||
{
|
||||
switch_channel_t *caller_channel;
|
||||
switch_core_session_t *peer_session;
|
||||
switch_core_session_t *peer_session = NULL;
|
||||
unsigned int timelimit = 60;
|
||||
char *var;
|
||||
uint8_t no_media_bridge = 0;
|
||||
|
@ -98,7 +98,7 @@ static void audio_bridge_function(switch_core_session_t *session, char *data)
|
|||
if (bad) {
|
||||
switch_channel_hangup(caller_channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
||||
switch_channel_hangup(peer_channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
||||
return;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -113,6 +113,10 @@ static void audio_bridge_function(switch_core_session_t *session, char *data)
|
|||
switch_ivr_multi_threaded_bridge(session, peer_session, NULL, NULL, NULL);
|
||||
}
|
||||
}
|
||||
end:
|
||||
if (peer_session) {
|
||||
switch_core_session_rwunlock(peer_session);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -590,7 +590,7 @@ static switch_status_t pause_function(char *cmd, switch_core_session_t *isession
|
|||
static switch_status_t originate_function(char *cmd, switch_core_session_t *isession, switch_stream_handle_t *stream)
|
||||
{
|
||||
switch_channel_t *caller_channel;
|
||||
switch_core_session_t *caller_session;
|
||||
switch_core_session_t *caller_session = NULL;
|
||||
char *argv[7] = { 0 };
|
||||
int i = 0, x, argc = 0;
|
||||
char *aleg, *exten, *dp, *context, *cid_name, *cid_num;
|
||||
|
@ -684,6 +684,10 @@ static switch_status_t originate_function(char *cmd, switch_core_session_t *ises
|
|||
stream->write_function(stream, "Created Session: %s\n", switch_core_session_get_uuid(caller_session));
|
||||
}
|
||||
|
||||
if (caller_session) {
|
||||
switch_core_session_rwunlock(caller_session);
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;;
|
||||
}
|
||||
|
||||
|
|
|
@ -3476,12 +3476,12 @@ static switch_status_t conference_outcall(conference_obj_t * conference,
|
|||
switch_core_session_t *session,
|
||||
char *bridgeto, uint32_t timeout, char *flags, char *cid_name, char *cid_num, switch_call_cause_t *cause)
|
||||
{
|
||||
switch_core_session_t *peer_session;
|
||||
switch_core_session_t *peer_session = NULL;
|
||||
switch_channel_t *peer_channel;
|
||||
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
||||
switch_channel_t *caller_channel = NULL;
|
||||
char appdata[512];
|
||||
|
||||
int rdlock = 0;
|
||||
|
||||
*cause = SWITCH_CAUSE_NORMAL_CLEARING;
|
||||
|
||||
|
@ -3498,7 +3498,7 @@ static switch_status_t conference_outcall(conference_obj_t * conference,
|
|||
|
||||
peer_channel = switch_core_session_get_channel(peer_session);
|
||||
assert(peer_channel != NULL);
|
||||
|
||||
rdlock = 1;
|
||||
goto callup;
|
||||
}
|
||||
|
||||
|
@ -3534,7 +3534,7 @@ static switch_status_t conference_outcall(conference_obj_t * conference,
|
|||
goto done;
|
||||
}
|
||||
|
||||
|
||||
rdlock = 1;
|
||||
peer_channel = switch_core_session_get_channel(peer_session);
|
||||
assert(peer_channel != NULL);
|
||||
|
||||
|
@ -3585,6 +3585,10 @@ static switch_status_t conference_outcall(conference_obj_t * conference,
|
|||
if (conference) {
|
||||
switch_thread_rwlock_unlock(conference->rwlock);
|
||||
}
|
||||
if (rdlock && peer_session) {
|
||||
switch_core_session_rwunlock(peer_session);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
|
|
@ -242,11 +242,6 @@ switch_status_t sofia_on_hangup(switch_core_session_t *session)
|
|||
|
||||
switch_clear_flag_locked(tech_pvt, TFLAG_IO);
|
||||
|
||||
if (tech_pvt->home) {
|
||||
su_home_unref(tech_pvt->home);
|
||||
tech_pvt->home = NULL;
|
||||
}
|
||||
|
||||
if (tech_pvt->sofia_private) {
|
||||
*tech_pvt->sofia_private->uuid = '\0';
|
||||
}
|
||||
|
@ -847,6 +842,7 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session
|
|||
sofia_glue_terminate_session(&nsession, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER, __LINE__);
|
||||
goto done;
|
||||
}
|
||||
switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(nsession));
|
||||
|
||||
data = switch_core_session_strdup(nsession, outbound_profile->destination_number);
|
||||
profile_name = data;
|
||||
|
|
|
@ -54,11 +54,6 @@ struct sofia_profile;
|
|||
typedef struct sofia_profile sofia_profile_t;
|
||||
#define NUA_MAGIC_T sofia_profile_t
|
||||
|
||||
struct sofia_private {
|
||||
char uuid[SWITCH_UUID_FORMATTED_LENGTH + 1];
|
||||
outbound_reg_t *gateway;
|
||||
};
|
||||
|
||||
typedef struct sofia_private sofia_private_t;
|
||||
|
||||
struct private_object;
|
||||
|
@ -85,6 +80,13 @@ typedef struct private_object private_object_t;
|
|||
#include <sofia-sip/nea.h>
|
||||
#include <sofia-sip/msg_addr.h>
|
||||
|
||||
struct sofia_private {
|
||||
char uuid[SWITCH_UUID_FORMATTED_LENGTH + 1];
|
||||
outbound_reg_t *gateway;
|
||||
su_home_t *home;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#define set_param(ptr,val) if (ptr) {free(ptr) ; ptr = NULL;} if (val) {ptr = strdup(val);}
|
||||
#define set_anchor(t,m) if (t->Anchor) {delete t->Anchor;} t->Anchor = new SipMessage(m);
|
||||
|
@ -305,7 +307,6 @@ struct private_object {
|
|||
switch_payload_t bcng_pt;
|
||||
nua_handle_t *nh;
|
||||
nua_handle_t *nh2;
|
||||
su_home_t *home;
|
||||
sip_contact_t *contact;
|
||||
};
|
||||
|
||||
|
@ -330,95 +331,95 @@ typedef enum {
|
|||
/*************************************************************************************************************************************************************/
|
||||
|
||||
|
||||
switch_status_t sofia_glue_activate_rtp(private_object_t * tech_pvt);
|
||||
switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt);
|
||||
|
||||
void sofia_glue_deactivate_rtp(private_object_t * tech_pvt);
|
||||
void sofia_glue_deactivate_rtp(private_object_t *tech_pvt);
|
||||
|
||||
void sofia_glue_set_local_sdp(private_object_t * tech_pvt, char *ip, uint32_t port, char *sr, int force);
|
||||
void sofia_glue_set_local_sdp(private_object_t *tech_pvt, char *ip, uint32_t port, char *sr, int force);
|
||||
|
||||
void sofia_glue_sofia_glue_tech_set_codecs(private_object_t * tech_pvt);
|
||||
void sofia_glue_sofia_glue_tech_set_codecs(private_object_t *tech_pvt);
|
||||
|
||||
void sofia_glue_attach_private(switch_core_session_t *session, sofia_profile_t * profile, private_object_t * tech_pvt, const char *channame);
|
||||
void sofia_glue_attach_private(switch_core_session_t *session, sofia_profile_t *profile, private_object_t *tech_pvt, const char *channame);
|
||||
|
||||
void sofia_glue_terminate_session(switch_core_session_t **session, switch_call_cause_t cause, int line);
|
||||
|
||||
switch_status_t sofia_glue_tech_choose_port(private_object_t * tech_pvt);
|
||||
switch_status_t sofia_glue_tech_choose_port(private_object_t *tech_pvt);
|
||||
|
||||
switch_status_t sofia_glue_do_invite(switch_core_session_t *session);
|
||||
|
||||
uint8_t negotiate_sdp(switch_core_session_t *session, sdp_session_t * sdp);
|
||||
uint8_t negotiate_sdp(switch_core_session_t *session, sdp_session_t *sdp);
|
||||
|
||||
void sofia_presence_establish_presence(sofia_profile_t * profile);
|
||||
void sofia_presence_establish_presence(sofia_profile_t *profile);
|
||||
|
||||
void sofia_handle_sip_i_state(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, tagi_t tags[]);
|
||||
nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[]);
|
||||
|
||||
|
||||
void sofia_handle_sip_i_refer(nua_t * nua, sofia_profile_t * profile, nua_handle_t * nh, switch_core_session_t *session, sip_t const *sip, tagi_t tags[]);
|
||||
void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, switch_core_session_t *session, sip_t const *sip, tagi_t tags[]);
|
||||
|
||||
void sofia_handle_sip_i_info(nua_t * nua, sofia_profile_t * profile, nua_handle_t * nh, switch_core_session_t *session, sip_t const *sip, tagi_t tags[]);
|
||||
void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, switch_core_session_t *session, sip_t const *sip, tagi_t tags[]);
|
||||
|
||||
void sofia_handle_sip_i_invite(nua_t * nua, sofia_profile_t * profile, nua_handle_t * nh, sofia_private_t * sofia_private, sip_t const *sip, tagi_t tags[]);
|
||||
void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[]);
|
||||
|
||||
void sofia_reg_handle_sip_i_register(nua_t * nua, sofia_profile_t * profile, nua_handle_t * nh, sofia_private_t * sofia_private, sip_t const *sip, tagi_t tags[]);
|
||||
void sofia_reg_handle_sip_i_register(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[]);
|
||||
|
||||
void sofia_event_callback(nua_event_t event,
|
||||
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, tagi_t tags[]);
|
||||
nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[]);
|
||||
|
||||
|
||||
void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t * thread, void *obj);
|
||||
void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void *obj);
|
||||
|
||||
void launch_sofia_profile_thread(sofia_profile_t * profile);
|
||||
void launch_sofia_profile_thread(sofia_profile_t *profile);
|
||||
|
||||
switch_status_t sofia_presence_chat_send(char *proto, char *from, char *to, char *subject, char *body, char *hint);
|
||||
void sofia_glue_tech_absorb_sdp(private_object_t * tech_pvt);
|
||||
switch_status_t sofia_glue_tech_media(private_object_t * tech_pvt, char *r_sdp);
|
||||
char *sofia_reg_find_reg_url(sofia_profile_t * profile, const char *user, const char *host, char *val, switch_size_t len);
|
||||
void sofia_glue_tech_absorb_sdp(private_object_t *tech_pvt);
|
||||
switch_status_t sofia_glue_tech_media(private_object_t *tech_pvt, char *r_sdp);
|
||||
char *sofia_reg_find_reg_url(sofia_profile_t *profile, const char *user, const char *host, char *val, switch_size_t len);
|
||||
void event_handler(switch_event_t *event);
|
||||
void sofia_presence_event_handler(switch_event_t *event);
|
||||
void sofia_presence_mwi_event_handler(switch_event_t *event);
|
||||
void sofia_presence_cancel(void);
|
||||
switch_status_t config_sofia(int reload);
|
||||
auth_res_t parse_auth(sofia_profile_t * profile, sip_authorization_t const *authorization, const char *regstr, char *np, size_t nplen);
|
||||
auth_res_t parse_auth(sofia_profile_t *profile, sip_authorization_t const *authorization, const char *regstr, char *np, size_t nplen);
|
||||
void sofia_reg_handle_sip_r_challenge(int status,
|
||||
char const *phrase,
|
||||
nua_t * nua, sofia_profile_t * profile, nua_handle_t * nh, switch_core_session_t *session, sip_t const *sip, tagi_t tags[]);
|
||||
nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, switch_core_session_t *session, sip_t const *sip, tagi_t tags[]);
|
||||
void sofia_reg_handle_sip_r_register(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, tagi_t tags[]);
|
||||
nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[]);
|
||||
void sofia_handle_sip_i_options(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, tagi_t tags[]);
|
||||
void sofia_presence_handle_sip_i_publish(nua_t * nua, sofia_profile_t * profile, nua_handle_t * nh, sofia_private_t * sofia_private, sip_t const *sip, tagi_t tags[]);
|
||||
nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[]);
|
||||
void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[]);
|
||||
void sofia_presence_handle_sip_i_message(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, tagi_t tags[]);
|
||||
nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[]);
|
||||
void sofia_presence_handle_sip_r_subscribe(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, tagi_t tags[]);
|
||||
nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[]);
|
||||
void sofia_presence_handle_sip_i_subscribe(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, tagi_t tags[]);
|
||||
nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[]);
|
||||
|
||||
sofia_profile_t *sofia_glue_find_profile(char *key);
|
||||
void sofia_glue_add_profile(char *key, sofia_profile_t * profile);
|
||||
void sofia_glue_add_profile(char *key, sofia_profile_t *profile);
|
||||
void sofia_glue_execute_sql(sofia_profile_t *profile, switch_bool_t master, char *sql, switch_mutex_t *mutex);
|
||||
void sofia_reg_check_expire(sofia_profile_t * profile, time_t now);
|
||||
void sofia_reg_check_gateway(sofia_profile_t * profile, time_t now);
|
||||
void sofia_reg_unregister(sofia_profile_t * profile);
|
||||
void sofia_reg_check_expire(sofia_profile_t *profile, time_t now);
|
||||
void sofia_reg_check_gateway(sofia_profile_t *profile, time_t now);
|
||||
void sofia_reg_unregister(sofia_profile_t *profile);
|
||||
switch_status_t sofia_glue_ext_address_lookup(char **ip, switch_port_t *port, char *sourceip, switch_memory_pool_t *pool);
|
||||
outbound_reg_t *sofia_reg_find_gateway(char *key);
|
||||
void sofia_reg_add_gateway(char *key, outbound_reg_t * gateway);
|
||||
void sofia_glue_pass_sdp(private_object_t * tech_pvt, char *sdp);
|
||||
void sofia_reg_add_gateway(char *key, outbound_reg_t *gateway);
|
||||
void sofia_glue_pass_sdp(private_object_t *tech_pvt, char *sdp);
|
||||
int sofia_glue_get_user_host(char *in, char **user, char **host);
|
||||
switch_call_cause_t sofia_glue_sip_cause_to_freeswitch(int status);
|
||||
void sofia_glue_do_xfer_invite(switch_core_session_t *session);
|
||||
uint8_t sofia_reg_handle_register(nua_t * nua, sofia_profile_t * profile, nua_handle_t * nh, sip_t const *sip, sofia_regtype_t regtype, char *key, uint32_t keylen);
|
||||
uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sip_t const *sip, sofia_regtype_t regtype, char *key, uint32_t keylen);
|
||||
const switch_endpoint_interface_t sofia_endpoint_interface;
|
||||
void sofia_presence_set_chat_hash(private_object_t * tech_pvt, sip_t const *sip);
|
||||
void sofia_presence_set_chat_hash(private_object_t *tech_pvt, sip_t const *sip);
|
||||
switch_status_t sofia_on_hangup(switch_core_session_t *session);
|
||||
char *sofia_glue_get_url_from_contact(char *buf, uint8_t to_dup);
|
||||
void sofia_presence_set_hash_key(char *hash_key, int32_t len, sip_t const *sip);
|
||||
|
|
|
@ -40,7 +40,7 @@ extern su_log_t tport_log[];
|
|||
void sofia_event_callback(nua_event_t event,
|
||||
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, tagi_t tags[])
|
||||
nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[])
|
||||
{
|
||||
struct private_object *tech_pvt = NULL;
|
||||
auth_res_t auth_res = AUTH_FORBIDDEN;
|
||||
|
@ -231,7 +231,7 @@ void event_handler(switch_event_t *event)
|
|||
|
||||
|
||||
|
||||
void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t * thread, void *obj)
|
||||
void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void *obj)
|
||||
{
|
||||
sofia_profile_t *profile = (sofia_profile_t *) obj;
|
||||
switch_memory_pool_t *pool;
|
||||
|
@ -357,7 +357,7 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t * thread, void
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void launch_sofia_profile_thread(sofia_profile_t * profile)
|
||||
void launch_sofia_profile_thread(sofia_profile_t *profile)
|
||||
{
|
||||
switch_thread_t *thread;
|
||||
switch_threadattr_t *thd_attr = NULL;
|
||||
|
@ -798,7 +798,7 @@ switch_status_t config_sofia(int reload)
|
|||
|
||||
void sofia_handle_sip_i_state(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, tagi_t tags[])
|
||||
nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[])
|
||||
{
|
||||
const char *l_sdp = NULL, *r_sdp = NULL;
|
||||
int offer_recv = 0, answer_recv = 0, offer_sent = 0, answer_sent = 0;
|
||||
|
@ -839,6 +839,8 @@ void sofia_handle_sip_i_state(int status,
|
|||
assert(tech_pvt != NULL);
|
||||
assert(tech_pvt->nh != NULL);
|
||||
|
||||
|
||||
|
||||
if (switch_channel_test_flag(channel, CF_NOMEDIA)) {
|
||||
switch_set_flag(tech_pvt, TFLAG_NOMEDIA);
|
||||
}
|
||||
|
@ -935,7 +937,7 @@ void sofia_handle_sip_i_state(int status,
|
|||
switch_core_session_thread_launch(session);
|
||||
goto done;
|
||||
} else {
|
||||
sdp_parser_t *parser = sdp_parse(tech_pvt->home, r_sdp, (int) strlen(r_sdp), 0);
|
||||
sdp_parser_t *parser = sdp_parse(tech_pvt->sofia_private->home, r_sdp, (int) strlen(r_sdp), 0);
|
||||
sdp_session_t *sdp;
|
||||
uint8_t match = 0;
|
||||
|
||||
|
@ -958,7 +960,7 @@ void sofia_handle_sip_i_state(int status,
|
|||
|
||||
switch_core_session_thread_launch(session);
|
||||
|
||||
if (replaces_str && (replaces = sip_replaces_make(tech_pvt->home, replaces_str))
|
||||
if (replaces_str && (replaces = sip_replaces_make(tech_pvt->sofia_private->home, replaces_str))
|
||||
&& (bnh = nua_handle_by_replaces(nua, replaces))) {
|
||||
sofia_private_t *b_private;
|
||||
|
||||
|
@ -1016,7 +1018,7 @@ void sofia_handle_sip_i_state(int status,
|
|||
if (switch_test_flag(tech_pvt, TFLAG_NOMEDIA)) {
|
||||
goto done;
|
||||
} else {
|
||||
sdp_parser_t *parser = sdp_parse(tech_pvt->home, r_sdp, (int) strlen(r_sdp), 0);
|
||||
sdp_parser_t *parser = sdp_parse(tech_pvt->sofia_private->home, r_sdp, (int) strlen(r_sdp), 0);
|
||||
sdp_session_t *sdp;
|
||||
uint8_t match = 0;
|
||||
|
||||
|
@ -1084,7 +1086,7 @@ void sofia_handle_sip_i_state(int status,
|
|||
}
|
||||
goto done;
|
||||
} else {
|
||||
sdp_parser_t *parser = sdp_parse(tech_pvt->home, r_sdp, (int) strlen(r_sdp), 0);
|
||||
sdp_parser_t *parser = sdp_parse(tech_pvt->sofia_private->home, r_sdp, (int) strlen(r_sdp), 0);
|
||||
sdp_session_t *sdp;
|
||||
uint8_t match = 0;
|
||||
|
||||
|
@ -1133,11 +1135,17 @@ void sofia_handle_sip_i_state(int status,
|
|||
}
|
||||
|
||||
if (tech_pvt->sofia_private) {
|
||||
if (sofia_private->home) {
|
||||
su_home_unref(sofia_private->home);
|
||||
}
|
||||
free(tech_pvt->sofia_private);
|
||||
tech_pvt->sofia_private = NULL;
|
||||
}
|
||||
tech_pvt->nh = NULL;
|
||||
} else if (sofia_private) {
|
||||
if (sofia_private->home) {
|
||||
su_home_unref(sofia_private->home);
|
||||
}
|
||||
free(sofia_private);
|
||||
}
|
||||
|
||||
|
@ -1157,7 +1165,7 @@ void sofia_handle_sip_i_state(int status,
|
|||
|
||||
|
||||
/*---------------------------------------*/
|
||||
void sofia_handle_sip_i_refer(nua_t * nua, sofia_profile_t * profile, nua_handle_t * nh, switch_core_session_t *session, sip_t const *sip, tagi_t tags[])
|
||||
void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, switch_core_session_t *session, sip_t const *sip, tagi_t tags[])
|
||||
{
|
||||
/* Incoming refer */
|
||||
sip_from_t const *from;
|
||||
|
@ -1213,7 +1221,7 @@ void sofia_handle_sip_i_refer(nua_t * nua, sofia_profile_t * profile, nua_handle
|
|||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error!\n");
|
||||
goto done;
|
||||
}
|
||||
if ((replaces = sip_replaces_make(tech_pvt->home, rep))
|
||||
if ((replaces = sip_replaces_make(tech_pvt->sofia_private->home, rep))
|
||||
&& (bnh = nua_handle_by_replaces(nua, replaces))) {
|
||||
sofia_private_t *b_private = NULL;
|
||||
private_object_t *b_tech_pvt = NULL;
|
||||
|
@ -1319,6 +1327,7 @@ void sofia_handle_sip_i_refer(nua_t * nua, sofia_profile_t * profile, nua_handle
|
|||
switch_set_flag_locked(tech_pvt, TFLAG_BYE);
|
||||
nua_notify(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("message/sipfrag"),
|
||||
NUTAG_SUBSTATE(nua_substate_terminated), SIPTAG_PAYLOAD_STR("SIP/2.0 200 OK"), SIPTAG_EVENT_STR(etmp), TAG_END());
|
||||
switch_core_session_rwunlock(tsession);
|
||||
} else {
|
||||
goto error;
|
||||
}
|
||||
|
@ -1396,7 +1405,7 @@ void sofia_handle_sip_i_refer(nua_t * nua, sofia_profile_t * profile, nua_handle
|
|||
}
|
||||
|
||||
|
||||
void sofia_handle_sip_i_info(nua_t * nua, sofia_profile_t * profile, nua_handle_t * nh, switch_core_session_t *session, sip_t const *sip, tagi_t tags[])
|
||||
void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, switch_core_session_t *session, sip_t const *sip, tagi_t tags[])
|
||||
{
|
||||
|
||||
//placeholder for string searching
|
||||
|
@ -1449,7 +1458,7 @@ void sofia_handle_sip_i_info(nua_t * nua, sofia_profile_t * profile, nua_handle_
|
|||
}
|
||||
|
||||
#define url_set_chanvars(session, url, varprefix) _url_set_chanvars(session, url, #varprefix "_user", #varprefix "_host", #varprefix "_port", #varprefix "_uri")
|
||||
const char *_url_set_chanvars(switch_core_session_t *session, url_t * url, const char *user_var,
|
||||
const char *_url_set_chanvars(switch_core_session_t *session, url_t *url, const char *user_var,
|
||||
const char *host_var, const char *port_var, const char *uri_var)
|
||||
{
|
||||
const char *user = NULL, *host = NULL, *port = NULL;
|
||||
|
@ -1484,7 +1493,7 @@ const char *_url_set_chanvars(switch_core_session_t *session, url_t * url, const
|
|||
return uri;
|
||||
}
|
||||
|
||||
void process_rpid(sip_unknown_t * un, private_object_t * tech_pvt)
|
||||
void process_rpid(sip_unknown_t *un, private_object_t *tech_pvt)
|
||||
{
|
||||
int argc, x, screen = 1;
|
||||
char *mydata, *argv[10] = { 0 };
|
||||
|
@ -1530,7 +1539,7 @@ void process_rpid(sip_unknown_t * un, private_object_t * tech_pvt)
|
|||
}
|
||||
}
|
||||
|
||||
void sofia_handle_sip_i_invite(nua_t * nua, sofia_profile_t * profile, nua_handle_t * nh, sofia_private_t * sofia_private, sip_t const *sip, tagi_t tags[])
|
||||
void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[])
|
||||
{
|
||||
switch_core_session_t *session = NULL;
|
||||
char key[128] = "";
|
||||
|
@ -1575,6 +1584,7 @@ void sofia_handle_sip_i_invite(nua_t * nua, sofia_profile_t * profile, nua_handl
|
|||
sofia_glue_terminate_session(&session, SWITCH_CAUSE_SWITCH_CONGESTION, __LINE__);
|
||||
return;
|
||||
}
|
||||
switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
|
||||
|
||||
if (!switch_strlen_zero(key)) {
|
||||
tech_pvt->key = switch_core_session_strdup(session, key);
|
||||
|
@ -1723,6 +1733,8 @@ void sofia_handle_sip_i_invite(nua_t * nua, sofia_profile_t * profile, nua_handl
|
|||
abort();
|
||||
}
|
||||
memset(tech_pvt->sofia_private, 0, sizeof(*tech_pvt->sofia_private));
|
||||
tech_pvt->sofia_private->home = su_home_new(sizeof(*tech_pvt->sofia_private->home));
|
||||
|
||||
switch_copy_string(tech_pvt->sofia_private->uuid, switch_core_session_get_uuid(session), sizeof(tech_pvt->sofia_private->uuid));
|
||||
nua_handle_bind(nh, tech_pvt->sofia_private);
|
||||
tech_pvt->nh = nh;
|
||||
|
@ -1730,7 +1742,7 @@ void sofia_handle_sip_i_invite(nua_t * nua, sofia_profile_t * profile, nua_handl
|
|||
|
||||
void sofia_handle_sip_i_options(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, tagi_t tags[])
|
||||
nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[])
|
||||
{
|
||||
nua_respond(nh, SIP_200_OK,
|
||||
//SOATAG_USER_SDP_STR(tech_pvt->local_sdp_str),
|
||||
|
|
|
@ -139,7 +139,7 @@ void sofia_glue_set_local_sdp(private_object_t *tech_pvt, char *ip, uint32_t por
|
|||
tech_pvt->local_sdp_str = switch_core_session_strdup(tech_pvt->session, buf);
|
||||
}
|
||||
|
||||
void sofia_glue_sofia_glue_tech_set_codecs(private_object_t * tech_pvt)
|
||||
void sofia_glue_sofia_glue_tech_set_codecs(private_object_t *tech_pvt)
|
||||
{
|
||||
switch_channel_t *channel;
|
||||
char *abs, *codec_string = NULL;
|
||||
|
@ -195,7 +195,7 @@ void sofia_glue_sofia_glue_tech_set_codecs(private_object_t * tech_pvt)
|
|||
}
|
||||
|
||||
|
||||
void sofia_glue_attach_private(switch_core_session_t *session, sofia_profile_t * profile, private_object_t * tech_pvt, const char *channame)
|
||||
void sofia_glue_attach_private(switch_core_session_t *session, sofia_profile_t *profile, private_object_t *tech_pvt, const char *channame)
|
||||
{
|
||||
switch_channel_t *channel;
|
||||
char name[256];
|
||||
|
@ -209,7 +209,7 @@ void sofia_glue_attach_private(switch_core_session_t *session, sofia_profile_t *
|
|||
|
||||
//switch_channel_set_flag(channel, CF_ACCEPT_CNG);
|
||||
|
||||
switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
|
||||
|
||||
switch_mutex_lock(tech_pvt->flag_mutex);
|
||||
tech_pvt->flags = profile->flags;
|
||||
switch_mutex_unlock(tech_pvt->flag_mutex);
|
||||
|
@ -227,8 +227,6 @@ void sofia_glue_attach_private(switch_core_session_t *session, sofia_profile_t *
|
|||
}
|
||||
|
||||
tech_pvt->session = session;
|
||||
tech_pvt->home = su_home_new(sizeof(*tech_pvt->home));
|
||||
|
||||
switch_core_session_set_private(session, tech_pvt);
|
||||
|
||||
|
||||
|
@ -288,7 +286,7 @@ switch_status_t sofia_glue_ext_address_lookup(char **ip, switch_port_t *port, ch
|
|||
}
|
||||
|
||||
|
||||
switch_status_t sofia_glue_tech_choose_port(private_object_t * tech_pvt)
|
||||
switch_status_t sofia_glue_tech_choose_port(private_object_t *tech_pvt)
|
||||
{
|
||||
char *ip = tech_pvt->profile->rtpip;
|
||||
switch_channel_t *channel;
|
||||
|
@ -428,6 +426,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
|
|||
abort();
|
||||
}
|
||||
memset(tech_pvt->sofia_private, 0, sizeof(*tech_pvt->sofia_private));
|
||||
tech_pvt->sofia_private->home = su_home_new(sizeof(*tech_pvt->sofia_private->home));
|
||||
switch_copy_string(tech_pvt->sofia_private->uuid, switch_core_session_get_uuid(session), sizeof(tech_pvt->sofia_private->uuid));
|
||||
nua_handle_bind(tech_pvt->nh, tech_pvt->sofia_private);
|
||||
|
||||
|
@ -530,7 +529,7 @@ void sofia_glue_do_xfer_invite(switch_core_session_t *session)
|
|||
|
||||
}
|
||||
|
||||
void sofia_glue_tech_absorb_sdp(private_object_t * tech_pvt)
|
||||
void sofia_glue_tech_absorb_sdp(private_object_t *tech_pvt)
|
||||
{
|
||||
switch_channel_t *channel;
|
||||
char *sdp_str;
|
||||
|
@ -544,7 +543,7 @@ void sofia_glue_tech_absorb_sdp(private_object_t * tech_pvt)
|
|||
sdp_media_t *m;
|
||||
sdp_connection_t *connection;
|
||||
|
||||
if ((parser = sdp_parse(tech_pvt->home, sdp_str, (int) strlen(sdp_str), 0))) {
|
||||
if ((parser = sdp_parse(tech_pvt->sofia_private->home, sdp_str, (int) strlen(sdp_str), 0))) {
|
||||
if ((sdp = sdp_session(parser))) {
|
||||
for (m = sdp->sdp_media; m; m = m->m_next) {
|
||||
if (m->m_type != sdp_media_audio) {
|
||||
|
@ -571,7 +570,7 @@ void sofia_glue_tech_absorb_sdp(private_object_t * tech_pvt)
|
|||
}
|
||||
}
|
||||
|
||||
void sofia_glue_deactivate_rtp(private_object_t * tech_pvt)
|
||||
void sofia_glue_deactivate_rtp(private_object_t *tech_pvt)
|
||||
{
|
||||
int loops = 0; //, sock = -1;
|
||||
if (switch_rtp_ready(tech_pvt->rtp_session)) {
|
||||
|
@ -583,7 +582,7 @@ void sofia_glue_deactivate_rtp(private_object_t * tech_pvt)
|
|||
}
|
||||
}
|
||||
|
||||
switch_status_t sofia_glue_tech_set_codec(private_object_t * tech_pvt, int force)
|
||||
switch_status_t sofia_glue_tech_set_codec(private_object_t *tech_pvt, int force)
|
||||
{
|
||||
switch_channel_t *channel;
|
||||
|
||||
|
@ -654,7 +653,7 @@ switch_status_t sofia_glue_tech_set_codec(private_object_t * tech_pvt, int force
|
|||
}
|
||||
|
||||
|
||||
switch_status_t sofia_glue_activate_rtp(private_object_t * tech_pvt)
|
||||
switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt)
|
||||
{
|
||||
int bw, ms;
|
||||
switch_channel_t *channel;
|
||||
|
@ -773,9 +772,9 @@ switch_status_t sofia_glue_activate_rtp(private_object_t * tech_pvt)
|
|||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
switch_status_t sofia_glue_tech_media(private_object_t * tech_pvt, char *r_sdp)
|
||||
switch_status_t sofia_glue_tech_media(private_object_t *tech_pvt, char *r_sdp)
|
||||
{
|
||||
sdp_parser_t *parser = sdp_parse(tech_pvt->home, r_sdp, (int) strlen(r_sdp), 0);
|
||||
sdp_parser_t *parser = sdp_parse(tech_pvt->sofia_private->home, r_sdp, (int) strlen(r_sdp), 0);
|
||||
sdp_session_t *sdp;
|
||||
uint8_t match = 0;
|
||||
switch_channel_t *channel = switch_core_session_get_channel(tech_pvt->session);
|
||||
|
@ -812,7 +811,7 @@ switch_status_t sofia_glue_tech_media(private_object_t * tech_pvt, char *r_sdp)
|
|||
|
||||
|
||||
|
||||
uint8_t negotiate_sdp(switch_core_session_t *session, sdp_session_t * sdp)
|
||||
uint8_t negotiate_sdp(switch_core_session_t *session, sdp_session_t *sdp)
|
||||
{
|
||||
uint8_t match = 0;
|
||||
switch_payload_t te = 0, cng_pt = 0;
|
||||
|
@ -1062,7 +1061,7 @@ switch_call_cause_t sofia_glue_sip_cause_to_freeswitch(int status)
|
|||
}
|
||||
|
||||
|
||||
void sofia_glue_pass_sdp(private_object_t * tech_pvt, char *sdp)
|
||||
void sofia_glue_pass_sdp(private_object_t *tech_pvt, char *sdp)
|
||||
{
|
||||
char *val;
|
||||
switch_channel_t *channel;
|
||||
|
@ -1120,7 +1119,7 @@ sofia_profile_t *sofia_glue_find_profile(char *key)
|
|||
return profile;
|
||||
}
|
||||
|
||||
void sofia_glue_add_profile(char *key, sofia_profile_t * profile)
|
||||
void sofia_glue_add_profile(char *key, sofia_profile_t *profile)
|
||||
{
|
||||
switch_mutex_lock(mod_sofia_globals.hash_mutex);
|
||||
switch_core_hash_insert(mod_sofia_globals.profile_hash, key, profile);
|
||||
|
|
|
@ -128,7 +128,7 @@ void sofia_presence_cancel(void)
|
|||
}
|
||||
}
|
||||
|
||||
void sofia_presence_establish_presence(sofia_profile_t * profile)
|
||||
void sofia_presence_establish_presence(sofia_profile_t *profile)
|
||||
{
|
||||
|
||||
if (sofia_glue_execute_sql_callback(profile, SWITCH_FALSE, profile->ireg_mutex,
|
||||
|
@ -612,7 +612,7 @@ static int sofia_presence_mwi_callback(void *pArg, int argc, char **argv, char *
|
|||
|
||||
void sofia_presence_handle_sip_i_subscribe(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, tagi_t tags[])
|
||||
nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[])
|
||||
{
|
||||
if (sip) {
|
||||
long exp, exp_raw;
|
||||
|
@ -792,12 +792,12 @@ void sofia_presence_handle_sip_i_subscribe(int status,
|
|||
|
||||
void sofia_presence_handle_sip_r_subscribe(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, tagi_t tags[])
|
||||
nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[])
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void sofia_presence_handle_sip_i_publish(nua_t * nua, sofia_profile_t * profile, nua_handle_t * nh, sofia_private_t * sofia_private, sip_t const *sip, tagi_t tags[])
|
||||
void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[])
|
||||
{
|
||||
if (sip) {
|
||||
sip_from_t const *from = sip->sip_from;
|
||||
|
@ -917,7 +917,7 @@ void sofia_presence_set_hash_key(char *hash_key, int32_t len, sip_t const *sip)
|
|||
|
||||
void sofia_presence_handle_sip_i_message(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, tagi_t tags[])
|
||||
nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[])
|
||||
{
|
||||
if (sip) {
|
||||
sip_from_t const *from = sip->sip_from;
|
||||
|
@ -1028,7 +1028,7 @@ void sofia_presence_handle_sip_i_message(int status,
|
|||
}
|
||||
}
|
||||
|
||||
void sofia_presence_set_chat_hash(private_object_t * tech_pvt, sip_t const *sip)
|
||||
void sofia_presence_set_chat_hash(private_object_t *tech_pvt, sip_t const *sip)
|
||||
{
|
||||
char hash_key[256] = "";
|
||||
char buf[512];
|
||||
|
@ -1038,7 +1038,7 @@ void sofia_presence_set_chat_hash(private_object_t * tech_pvt, sip_t const *sip)
|
|||
}
|
||||
|
||||
if (sofia_reg_find_reg_url(tech_pvt->profile, sip->sip_from->a_url->url_user, sip->sip_from->a_url->url_host, buf, sizeof(buf))) {
|
||||
tech_pvt->chat_from = sip_header_as_string(tech_pvt->home, (const sip_header_t *) sip->sip_to);
|
||||
tech_pvt->chat_from = sip_header_as_string(tech_pvt->sofia_private->home, (const sip_header_t *) sip->sip_to);
|
||||
tech_pvt->chat_to = switch_core_session_strdup(tech_pvt->session, buf);
|
||||
sofia_presence_set_hash_key(hash_key, sizeof(hash_key), sip);
|
||||
} else {
|
||||
|
|
|
@ -76,4 +76,8 @@ package fs_perl;
|
|||
|
||||
package fs_perl;
|
||||
|
||||
*FREESWITCH_PEN = *fs_perlc::FREESWITCH_PEN;
|
||||
*FREESWITCH_OID_PREFIX = *fs_perlc::FREESWITCH_OID_PREFIX;
|
||||
*FREESWITCH_ITAD = *fs_perlc::FREESWITCH_ITAD;
|
||||
*__EXTENSIONS__ = *fs_perlc::__EXTENSIONS__;
|
||||
1;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -81,7 +81,8 @@ typedef struct sm_loadable_module sm_loadable_module_t;
|
|||
|
||||
typedef enum {
|
||||
S_HUP = (1 << 0),
|
||||
S_FREE = (1 << 1)
|
||||
S_FREE = (1 << 1),
|
||||
S_RDLOCK = (1 << 2)
|
||||
} session_flag_t;
|
||||
|
||||
struct input_callback_state {
|
||||
|
@ -2146,7 +2147,7 @@ static JSBool session_originate(JSContext * cx, JSObject * obj, uintN argc, jsva
|
|||
}
|
||||
|
||||
jss->session = peer_session;
|
||||
jss->flags = 0;
|
||||
jss->flags = S_RDLOCK;
|
||||
|
||||
*rval = BOOLEAN_TO_JSVAL(JS_TRUE);
|
||||
|
||||
|
@ -2177,6 +2178,10 @@ static void session_destroy(JSContext * cx, JSObject * obj)
|
|||
switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
|
||||
}
|
||||
|
||||
if (jss->session && switch_test_flag(jss, S_RDLOCK)) {
|
||||
switch_core_session_rwunlock(jss->session);
|
||||
}
|
||||
|
||||
if (switch_test_flag(jss, S_FREE)) {
|
||||
free(jss);
|
||||
}
|
||||
|
|
|
@ -745,12 +745,12 @@ SWITCH_DECLARE(void) switch_channel_event_set_data(switch_channel_t *channel, sw
|
|||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Channel-Name", "%s", switch_channel_get_name(channel));
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Unique-ID", "%s", switch_core_session_get_uuid(channel->session));
|
||||
|
||||
if ((codec = switch_core_session_get_read_codec(channel->session))) {
|
||||
if ((codec = switch_core_session_get_read_codec(channel->session)) && codec->implementation) {
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Channel-Read-Codec-Name", "%s", switch_str_nil(codec->implementation->iananame));
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Channel-Read-Codec-Rate", "%u", codec->implementation->samples_per_second);
|
||||
}
|
||||
|
||||
if ((codec = switch_core_session_get_write_codec(channel->session))) {
|
||||
if ((codec = switch_core_session_get_write_codec(channel->session)) && codec->implementation) {
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Channel-Write-Codec-Name", "%s", switch_str_nil(codec->implementation->iananame));
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Channel-Write-Codec-Rate", "%u", codec->implementation->samples_per_second);
|
||||
}
|
||||
|
|
|
@ -34,16 +34,20 @@ static const switch_state_handler_table_t audio_bridge_peer_state_handlers;
|
|||
|
||||
/* Bridge Related Stuff*/
|
||||
/*********************************************************************************/
|
||||
struct audio_bridge_data {
|
||||
switch_core_session_t *session_a;
|
||||
switch_core_session_t *session_b;
|
||||
int running;
|
||||
struct switch_ivr_bridge_data {
|
||||
switch_core_session_t *session;
|
||||
char *b_uuid;
|
||||
int stream_id;
|
||||
switch_input_callback_function_t input_callback;
|
||||
void *session_data;
|
||||
};
|
||||
typedef struct switch_ivr_bridge_data switch_ivr_bridge_data_t;
|
||||
|
||||
|
||||
|
||||
static void *audio_bridge_thread(switch_thread_t * thread, void *obj)
|
||||
{
|
||||
switch_core_thread_session_t *his_thread, *data = obj;
|
||||
int *stream_id_p;
|
||||
switch_ivr_bridge_data_t *data = obj;
|
||||
int stream_id = 0, pre_b = 0, ans_a = 0, ans_b = 0, originator = 0;
|
||||
switch_input_callback_function_t input_callback;
|
||||
switch_core_session_message_t *message, msg = { 0 };
|
||||
|
@ -53,20 +57,15 @@ static void *audio_bridge_thread(switch_thread_t * thread, void *obj)
|
|||
switch_frame_t *read_frame;
|
||||
switch_core_session_t *session_a, *session_b;
|
||||
|
||||
assert(!thread || thread);
|
||||
|
||||
session_a = data->objs[0];
|
||||
session_b = data->objs[1];
|
||||
|
||||
stream_id_p = data->objs[2];
|
||||
input_callback = data->input_callback;
|
||||
user_data = data->objs[4];
|
||||
his_thread = data->objs[5];
|
||||
|
||||
if (stream_id_p) {
|
||||
stream_id = *stream_id_p;
|
||||
session_a = data->session;
|
||||
if (!(session_b = switch_core_session_locate(data->b_uuid))) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
input_callback = data->input_callback;
|
||||
user_data = data->session_data;
|
||||
stream_id = data->stream_id;
|
||||
|
||||
chan_a = switch_core_session_get_channel(session_a);
|
||||
chan_b = switch_core_session_get_channel(session_b);
|
||||
|
||||
|
@ -75,8 +74,6 @@ static void *audio_bridge_thread(switch_thread_t * thread, void *obj)
|
|||
pre_b = switch_channel_test_flag(chan_a, CF_EARLY_MEDIA);
|
||||
ans_b = switch_channel_test_flag(chan_b, CF_ANSWERED);
|
||||
}
|
||||
switch_core_session_read_lock(session_a);
|
||||
switch_core_session_read_lock(session_b);
|
||||
|
||||
switch_channel_set_flag(chan_a, CF_BRIDGED);
|
||||
|
||||
|
@ -85,10 +82,6 @@ static void *audio_bridge_thread(switch_thread_t * thread, void *obj)
|
|||
switch_status_t status;
|
||||
switch_event_t *event;
|
||||
|
||||
if (!(data->running > 0 && his_thread->running > 0)) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* if you really want to make sure it's not ready, test it twice because it might be just a break */
|
||||
if (!switch_channel_ready(chan_a) && !switch_channel_ready(chan_a)) {
|
||||
break;
|
||||
|
@ -99,10 +92,6 @@ static void *audio_bridge_thread(switch_thread_t * thread, void *obj)
|
|||
switch (b_state) {
|
||||
case CS_HANGUP:
|
||||
case CS_DONE:
|
||||
switch_mutex_lock(data->mutex);
|
||||
data->running = -1;
|
||||
switch_mutex_unlock(data->mutex);
|
||||
continue;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -129,9 +118,6 @@ static void *audio_bridge_thread(switch_thread_t * thread, void *obj)
|
|||
if (input_callback) {
|
||||
if (input_callback(session_a, dtmf, SWITCH_INPUT_TYPE_DTMF, user_data, 0) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s ended call via DTMF\n", switch_channel_get_name(chan_a));
|
||||
switch_mutex_lock(data->mutex);
|
||||
data->running = -1;
|
||||
switch_mutex_unlock(data->mutex);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -186,49 +172,40 @@ static void *audio_bridge_thread(switch_thread_t * thread, void *obj)
|
|||
if (switch_core_session_write_frame(session_b, read_frame, -1, stream_id) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "write: %s Bad Frame....[%u] Bubye!\n",
|
||||
switch_channel_get_name(chan_b), read_frame->datalen);
|
||||
switch_mutex_lock(data->mutex);
|
||||
data->running = -1;
|
||||
switch_mutex_unlock(data->mutex);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "read: %s Bad Frame.... Bubye!\n", switch_channel_get_name(chan_a));
|
||||
switch_mutex_lock(data->mutex);
|
||||
data->running = -1;
|
||||
switch_mutex_unlock(data->mutex);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch_core_session_kill_channel(session_b, SWITCH_SIG_BREAK);
|
||||
|
||||
msg.string_arg = data->b_uuid;
|
||||
msg.message_id = SWITCH_MESSAGE_INDICATE_UNBRIDGE;
|
||||
msg.from = __FILE__;
|
||||
switch_core_session_receive_message(session_a, &msg);
|
||||
|
||||
switch_channel_set_variable(chan_a, SWITCH_BRIDGE_VARIABLE, NULL);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "BRIDGE THREAD DONE [%s]\n", switch_channel_get_name(chan_a));
|
||||
|
||||
switch_channel_clear_flag(chan_a, CF_BRIDGED);
|
||||
switch_mutex_lock(data->mutex);
|
||||
data->running = 0;
|
||||
switch_mutex_unlock(data->mutex);
|
||||
|
||||
switch_core_session_rwunlock(session_a);
|
||||
switch_core_session_rwunlock(session_b);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static switch_status_t audio_bridge_on_loopback(switch_core_session_t *session)
|
||||
{
|
||||
switch_channel_t *channel = NULL;
|
||||
void *arg;
|
||||
switch_ivr_bridge_data_t *bd;
|
||||
|
||||
channel = switch_core_session_get_channel(session);
|
||||
assert(channel != NULL);
|
||||
|
||||
if ((arg = switch_channel_get_private(channel, "_bridge_"))) {
|
||||
if ((bd = (switch_ivr_bridge_data_t *) switch_channel_get_private(channel, "_bridge_"))) {
|
||||
switch_channel_set_private(channel, "_bridge_", NULL);
|
||||
audio_bridge_thread(NULL, (void *) arg);
|
||||
audio_bridge_thread(NULL, (void *) bd);
|
||||
} else {
|
||||
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
||||
}
|
||||
|
@ -516,13 +493,12 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_signal_bridge(switch_core_session_t *
|
|||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_ivr_multi_threaded_bridge(switch_core_session_t *session,
|
||||
switch_core_session_t *peer_session,
|
||||
switch_input_callback_function_t input_callback, void *session_data,
|
||||
void *peer_session_data)
|
||||
{
|
||||
switch_core_thread_session_t *this_audio_thread, *other_audio_thread;
|
||||
switch_ivr_bridge_data_t *a_leg, *b_leg;
|
||||
switch_channel_t *caller_channel, *peer_channel;
|
||||
int stream_id = 0;
|
||||
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
||||
|
@ -535,26 +511,20 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_multi_threaded_bridge(switch_core_ses
|
|||
peer_channel = switch_core_session_get_channel(peer_session);
|
||||
assert(peer_channel != NULL);
|
||||
|
||||
other_audio_thread = switch_core_session_alloc(peer_session, sizeof(switch_core_thread_session_t));
|
||||
this_audio_thread = switch_core_session_alloc(peer_session, sizeof(switch_core_thread_session_t));
|
||||
a_leg = switch_core_session_alloc(session, sizeof(*a_leg));
|
||||
b_leg = switch_core_session_alloc(peer_session, sizeof(*b_leg));
|
||||
|
||||
other_audio_thread->objs[0] = session;
|
||||
other_audio_thread->objs[1] = peer_session;
|
||||
other_audio_thread->objs[2] = &stream_id;
|
||||
other_audio_thread->input_callback = input_callback;
|
||||
other_audio_thread->objs[4] = session_data;
|
||||
other_audio_thread->objs[5] = this_audio_thread;
|
||||
other_audio_thread->running = 5;
|
||||
switch_mutex_init(&other_audio_thread->mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
|
||||
b_leg->session = peer_session;
|
||||
b_leg->b_uuid = switch_core_session_strdup(peer_session, switch_core_session_get_uuid(session));
|
||||
b_leg->stream_id = stream_id;
|
||||
b_leg->input_callback = input_callback;
|
||||
b_leg->session_data = session_data;
|
||||
|
||||
this_audio_thread->objs[0] = peer_session;
|
||||
this_audio_thread->objs[1] = session;
|
||||
this_audio_thread->objs[2] = &stream_id;
|
||||
this_audio_thread->input_callback = input_callback;
|
||||
this_audio_thread->objs[4] = peer_session_data;
|
||||
this_audio_thread->objs[5] = other_audio_thread;
|
||||
this_audio_thread->running = 2;
|
||||
switch_mutex_init(&this_audio_thread->mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(peer_session));
|
||||
a_leg->session = session;
|
||||
a_leg->b_uuid = switch_core_session_strdup(session, switch_core_session_get_uuid(peer_session));
|
||||
b_leg->stream_id = stream_id;
|
||||
b_leg->input_callback = input_callback;
|
||||
b_leg->session_data = peer_session_data;
|
||||
|
||||
switch_channel_add_state_handler(peer_channel, &audio_bridge_peer_state_handlers);
|
||||
|
||||
|
@ -579,54 +549,34 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_multi_threaded_bridge(switch_core_ses
|
|||
|
||||
msg.message_id = SWITCH_MESSAGE_INDICATE_BRIDGE;
|
||||
msg.from = __FILE__;
|
||||
msg.pointer_arg = session;
|
||||
msg.string_arg = switch_core_session_strdup(peer_session, switch_core_session_get_uuid(session));
|
||||
|
||||
switch_core_session_receive_message(peer_session, &msg);
|
||||
|
||||
if (!msg.pointer_arg) {
|
||||
if (switch_core_session_receive_message(peer_session, &msg) != SWITCH_STATUS_SUCCESS) {
|
||||
status = SWITCH_STATUS_FALSE;
|
||||
switch_core_session_rwunlock(peer_session);
|
||||
goto done;
|
||||
}
|
||||
|
||||
msg.pointer_arg = peer_session;
|
||||
switch_core_session_receive_message(session, &msg);
|
||||
|
||||
if (!msg.pointer_arg) {
|
||||
msg.string_arg = switch_core_session_strdup(session, switch_core_session_get_uuid(peer_session));
|
||||
if (switch_core_session_receive_message(session, &msg) != SWITCH_STATUS_SUCCESS) {
|
||||
status = SWITCH_STATUS_FALSE;
|
||||
switch_core_session_rwunlock(peer_session);
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
||||
switch_channel_set_private(peer_channel, "_bridge_", other_audio_thread);
|
||||
switch_channel_set_private(peer_channel, "_bridge_", b_leg);
|
||||
switch_channel_set_state(peer_channel, CS_LOOPBACK);
|
||||
audio_bridge_thread(NULL, (void *) this_audio_thread);
|
||||
audio_bridge_thread(NULL, (void *) a_leg);
|
||||
|
||||
if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_UNBRIDGE) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_channel_event_set_data(caller_channel, event);
|
||||
switch_event_fire(&event);
|
||||
}
|
||||
|
||||
this_audio_thread->objs[0] = NULL;
|
||||
this_audio_thread->objs[1] = NULL;
|
||||
this_audio_thread->objs[2] = NULL;
|
||||
this_audio_thread->input_callback = NULL;
|
||||
this_audio_thread->objs[4] = NULL;
|
||||
this_audio_thread->objs[5] = NULL;
|
||||
switch_mutex_lock(this_audio_thread->mutex);
|
||||
this_audio_thread->running = 0;
|
||||
switch_mutex_unlock(this_audio_thread->mutex);
|
||||
|
||||
switch_channel_clear_flag(caller_channel, CF_ORIGINATOR);
|
||||
|
||||
if (other_audio_thread->running > 0) {
|
||||
switch_mutex_lock(other_audio_thread->mutex);
|
||||
other_audio_thread->running = -1;
|
||||
switch_mutex_unlock(other_audio_thread->mutex);
|
||||
while (other_audio_thread->running) {
|
||||
switch_yield(1000);
|
||||
}
|
||||
while (switch_channel_get_state(peer_channel) == CS_LOOPBACK) {
|
||||
switch_yield(1000);
|
||||
}
|
||||
|
||||
switch_core_session_rwunlock(peer_session);
|
||||
|
|
|
@ -156,7 +156,7 @@ static void launch_collect_thread(struct key_collect *collect)
|
|||
|
||||
static uint8_t check_channel_status(switch_channel_t **peer_channels,
|
||||
switch_core_session_t **peer_sessions,
|
||||
uint32_t len, int32_t *idx, uint32_t * hups, char *file, char *key, uint8_t early_ok, uint8_t * ring_ready)
|
||||
uint32_t len, int32_t *idx, uint32_t * hups, char *file, char *key, uint8_t early_ok, uint8_t *ring_ready)
|
||||
{
|
||||
|
||||
uint32_t i;
|
||||
|
@ -901,6 +901,9 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
|
|||
if (!peer_channels[i]) {
|
||||
continue;
|
||||
}
|
||||
if (status == SWITCH_STATUS_SUCCESS && bleg && *bleg && *bleg == peer_sessions[i]) {
|
||||
continue;
|
||||
}
|
||||
switch_core_session_rwunlock(peer_sessions[i]);
|
||||
}
|
||||
|
||||
|
@ -912,5 +915,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
|
|||
outer_for:
|
||||
switch_safe_free(loop_data);
|
||||
switch_safe_free(odata);
|
||||
|
||||
if (bleg && status != SWITCH_STATUS_SUCCESS) {
|
||||
*bleg = NULL;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
|
|
@ -246,6 +246,7 @@ int fs_switch_ivr_originate(switch_core_session_t *session, switch_core_session_
|
|||
return;
|
||||
} else {
|
||||
switch_ivr_multi_threaded_bridge(session, peer_session, NULL, NULL, NULL);
|
||||
switch_core_session_rwunlock(peer_session);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue