From 246b21952df20afbbf548feab718300e6087727a Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 28 Mar 2011 14:44:23 -0500 Subject: [PATCH] FS-3095 --comment-only This patch removes the existing conference transfer function and replaces it using the core transfer it also introduces a new tracking method where the same conference id is reserved for a particular member for the lifetime of the call allowing a user to transfer in and out of conferences and ivr and bridges etc and retain the same member id for the duration of that call --- .../mod_conference/mod_conference.c | 151 +++--------------- 1 file changed, 25 insertions(+), 126 deletions(-) diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index 0f5ea26e09..8103a39abc 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -4511,18 +4511,17 @@ static switch_status_t conf_api_sub_bgdial(conference_obj_t *conference, switch_ return SWITCH_STATUS_SUCCESS; } + + static switch_status_t conf_api_sub_transfer(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv) { switch_status_t ret_status = SWITCH_STATUS_SUCCESS; char *conf_name = NULL, *profile_name; switch_event_t *params = NULL; - conference_obj_t *new_conference = NULL; - int locked = 0; - switch_core_session_message_t msg = { 0 }; switch_assert(conference != NULL); switch_assert(stream != NULL); - + if (argc > 3 && !zstr(argv[2])) { int x; @@ -4539,124 +4538,21 @@ static switch_status_t conf_api_sub_transfer(conference_obj_t *conference, switc uint32_t id = atoi(argv[x]); switch_channel_t *channel; switch_event_t *event; - switch_xml_t cxml = NULL, cfg = NULL, profiles = NULL; - + char *xdest = NULL; + if (!id || !(member = conference_member_get(conference, id))) { stream->write_function(stream, "No Member %u in conference %s.\n", id, conference->name); continue; } channel = switch_core_session_get_channel(member->session); - - if (!new_conference) { - if (!locked) { - switch_mutex_lock(globals.setup_mutex); - locked = 1; - } - - if ((new_conference = conference_find(conf_name))) { - if (locked) { - switch_mutex_unlock(globals.setup_mutex); - locked = 0; - } - } - - if (!(new_conference = conference_find(conf_name))) { - /* build a new conference if it doesn't exist */ - switch_memory_pool_t *pool = NULL; - conf_xml_cfg_t xml_cfg = { 0 }; - - /* Setup a memory pool to use. */ - if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Pool Failure\n"); - switch_thread_rwlock_unlock(member->rwlock); - goto done; - } - - switch_event_create(¶ms, SWITCH_EVENT_REQUEST_PARAMS); - switch_assert(params); - switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "conf_name", conf_name); - switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "profile_name", profile_name); - switch_channel_event_set_data(channel, params); - - /* Open the config from the xml registry */ - if (!(cxml = switch_xml_open_cfg(global_cf_name, &cfg, params))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", global_cf_name); - switch_thread_rwlock_unlock(member->rwlock); - goto done; - } - - if ((profiles = switch_xml_child(cfg, "profiles"))) { - xml_cfg.profile = switch_xml_find_child(profiles, "profile", "name", profile_name); - } - - /* Create the conference object. */ - new_conference = conference_new(conf_name, xml_cfg, member->session, pool); - - /* Release the config registry handle */ - if (cxml) { - switch_xml_free(cxml); - cxml = NULL; - } - - if (!new_conference) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n"); - if (pool != NULL) { - switch_core_destroy_memory_pool(&pool); - } - switch_thread_rwlock_unlock(member->rwlock); - goto done; - } - - if (locked) { - switch_mutex_unlock(globals.setup_mutex); - locked = 0; - } - - /* Set the minimum number of members (once you go above it you cannot go below it) */ - new_conference->min = 1; - - /* Indicate the conference is dynamic */ - switch_set_flag_locked(new_conference, CFLAG_DYNAMIC); - - switch_mutex_lock(new_conference->mutex); - - /* Start the conference thread for this conference */ - launch_conference_thread(new_conference); - } else { - switch_mutex_lock(new_conference->mutex); - } - } - - /* move the member from the old conference to the new one */ - lock_member(member); - switch_thread_rwlock_unlock(member->rwlock); - - if (conference != new_conference) { - conference_del_member(conference, member); - conference_add_member(new_conference, member); - - if (conference->rate != new_conference->rate) { - if (setup_media(member, new_conference)) { - switch_clear_flag_locked(member, MFLAG_RUNNING); - } else { - switch_channel_set_app_flag(channel, CF_APP_TAGGED); - switch_set_flag_locked(member, MFLAG_RESTART); - } - } - } - - switch_channel_set_variable(channel, "last_transfered_conference", argv[2]); - - /* Sync the recovery data */ - msg.from = __FILE__; - msg.message_id = SWITCH_MESSAGE_INDICATE_RECOVERY_REFRESH; - switch_core_session_receive_message(member->session, &msg); - - unlock_member(member); + xdest = switch_core_session_sprintf(member->session, "conference:%s@%s", conf_name, profile_name); + switch_ivr_session_transfer(member->session, xdest, "inline", NULL); + + switch_channel_set_variable(channel, "last_transfered_conference", conf_name); stream->write_function(stream, "OK Member '%d' sent to conference %s.\n", member->id, argv[2]); - + /* tell them what happened */ if (test_eflag(conference, EFLAG_TRANSFER) && switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) { @@ -4666,30 +4562,23 @@ static switch_status_t conf_api_sub_transfer(conference_obj_t *conference, switc switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "transfer"); switch_event_fire(&event); } - } - if (new_conference) { - switch_mutex_unlock(new_conference->mutex); + switch_thread_rwlock_unlock(member->rwlock); } - } else { ret_status = SWITCH_STATUS_GENERR; } - done: - - if (locked) { - switch_mutex_unlock(globals.setup_mutex); - locked = 0; - } - if (params) { switch_event_destroy(¶ms); } + switch_safe_free(conf_name); + return ret_status; } + static switch_status_t conf_api_sub_record(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv) { switch_assert(conference != NULL); @@ -5621,6 +5510,7 @@ SWITCH_STANDARD_APP(conference_function) conf_xml_cfg_t xml_cfg = { 0 }; switch_event_t *params = NULL; int locked = 0; + uint32_t *mid; if (!switch_channel_test_app_flag_key("conf_silent", channel, CONF_SILENT_DONE) && (switch_channel_test_flag(channel, CF_RECOVERED) || switch_true(switch_channel_get_variable(channel, "conference_silent_entry")))) { @@ -5993,8 +5883,17 @@ SWITCH_STANDARD_APP(conference_function) goto done; } + + if (!(mid = switch_channel_get_private(channel, "__confmid"))) { + mid = switch_core_session_alloc(session, sizeof(*mid)); + *mid = next_member_id(); + switch_channel_set_private(channel, "__confmid", mid); + } + + switch_channel_set_variable_printf(channel, "conference_member_id", "%u", *mid); + /* Prepare MUTEXS */ - member.id = next_member_id(); + member.id = *mid; switch_mutex_init(&member.flag_mutex, SWITCH_MUTEX_NESTED, member.pool); switch_mutex_init(&member.write_mutex, SWITCH_MUTEX_NESTED, member.pool); switch_mutex_init(&member.read_mutex, SWITCH_MUTEX_NESTED, member.pool);