int fs_switch_ivr_session_transfer(switch_core_session_t *session, char *extension, char *dialplan, char *context) { switch_status_t status; status = switch_ivr_session_transfer(session, extension, dialplan, context); return status == SWITCH_STATUS_SUCCESS ? 1 : 0; }
SWITCH_DECLARE(int) CoreSession::transfer(char *extension, char *dialplan, char *context) { switch_status_t status; this_check(-1); sanity_check(-1); begin_allow_threads(); status = switch_ivr_session_transfer(session, extension, dialplan, context); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "transfer result: %d\n", status); end_allow_threads(); return status == SWITCH_STATUS_SUCCESS ? 1 : 0; }
static void transfer_call(switch_core_session_t *session, char *destination) { char *argv[4] = { 0 }; const char *uuid; switch_channel_t *channel = switch_core_session_get_channel(session); char *mydup; if (!destination) { return; } mydup = strdup(destination); switch_assert(mydup); switch_separate_string(mydup, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); /* Find the uuid of our B leg. If it exists, transfer it first */ if ((uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE))) { switch_core_session_t *b_session; /* Get info on the B leg */ if ((b_session = switch_core_session_locate(uuid))) { /* Make sure we are in the media path on B leg */ switch_ivr_media(uuid, SMF_REBRIDGE); /* Transfer the B leg */ switch_ivr_session_transfer(b_session, argv[0], argv[1], argv[2]); switch_core_session_rwunlock(b_session); } } /* Make sure we are in the media path on A leg */ uuid = switch_core_session_get_uuid(session); switch_ivr_media(uuid, SMF_REBRIDGE); /* Transfer the A leg */ switch_ivr_session_transfer(session, argv[0], argv[1], argv[2]); free(mydup); }
void conference_loop_transfer(conference_member_t *member, caller_control_action_t *action) { char *exten = NULL; char *dialplan = "XML"; char *context = "default"; char *argv[3] = { 0 }; int argc; char *mydata = NULL; switch_event_t *event; if (test_eflag(member->conference, EFLAG_DTMF) && switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) { conference_member_add_event_data(member, event); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "transfer"); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Dialplan", action->expanded_data); switch_event_fire(&event); } conference_utils_member_clear_flag_locked(member, MFLAG_RUNNING); if ((mydata = switch_core_session_strdup(member->session, action->expanded_data))) { if ((argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) { if (argc > 0) { exten = argv[0]; } if (argc > 1) { dialplan = argv[1]; } if (argc > 2) { context = argv[2]; } } else { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session), SWITCH_LOG_ERROR, "Empty transfer string [%s]\n", (char *) action->expanded_data); goto done; } } else { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session), SWITCH_LOG_ERROR, "Unable to allocate memory to duplicate transfer data.\n"); goto done; } switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session), SWITCH_LOG_INFO, "Transfering to: %s, %s, %s\n", exten, dialplan, context); switch_ivr_session_transfer(member->session, exten, dialplan, context); done: return; }
static switch_status_t channel_receive_message(switch_core_session_t *session, switch_core_session_message_t *msg) { switch_channel_t *channel; loopback_private_t *tech_pvt; int done = 1, pass = 0; switch_core_session_t *other_session; channel = switch_core_session_get_channel(session); switch_assert(channel != NULL); tech_pvt = switch_core_session_get_private(session); switch_assert(tech_pvt != NULL); switch (msg->message_id) { case SWITCH_MESSAGE_INDICATE_ANSWER: if (tech_pvt->other_channel && !switch_test_flag(tech_pvt, TFLAG_OUTBOUND)) { switch_channel_mark_answered(tech_pvt->other_channel); } break; case SWITCH_MESSAGE_INDICATE_PROGRESS: if (tech_pvt->other_channel && !switch_test_flag(tech_pvt, TFLAG_OUTBOUND)) { switch_channel_mark_pre_answered(tech_pvt->other_channel); } break; case SWITCH_MESSAGE_INDICATE_RINGING: if (tech_pvt->other_channel && !switch_test_flag(tech_pvt, TFLAG_OUTBOUND)) { switch_channel_mark_ring_ready(tech_pvt->other_channel); } break; case SWITCH_MESSAGE_INDICATE_BRIDGE: { switch_set_flag_locked(tech_pvt, TFLAG_BRIDGE); } break; case SWITCH_MESSAGE_INDICATE_UNBRIDGE: { switch_clear_flag_locked(tech_pvt, TFLAG_BRIDGE); } break; default: done = 0; break; } switch (msg->message_id) { case SWITCH_MESSAGE_INDICATE_BRIDGE: case SWITCH_MESSAGE_INDICATE_UNBRIDGE: case SWITCH_MESSAGE_INDICATE_AUDIO_SYNC: { done = 1; switch_set_flag(tech_pvt, TFLAG_CLEAR); switch_set_flag(tech_pvt->other_tech_pvt, TFLAG_CLEAR); switch_core_timer_sync(&tech_pvt->timer); switch_core_timer_sync(&tech_pvt->other_tech_pvt->timer); } break; default: break; } switch (msg->message_id) { case SWITCH_MESSAGE_INDICATE_DISPLAY: if (tech_pvt->other_channel) { if (switch_test_flag(tech_pvt, TFLAG_BLEG)) { if (!zstr(msg->string_array_arg[0])) { switch_channel_set_profile_var(tech_pvt->other_channel, "caller_id_name", msg->string_array_arg[0]); } if (!zstr(msg->string_array_arg[1])) { switch_channel_set_profile_var(tech_pvt->other_channel, "caller_id_number", msg->string_array_arg[1]); } } else { if (!zstr(msg->string_array_arg[0])) { switch_channel_set_profile_var(tech_pvt->other_channel, "callee_id_name", msg->string_array_arg[0]); } if (!zstr(msg->string_array_arg[1])) { switch_channel_set_profile_var(tech_pvt->other_channel, "callee_id_number", msg->string_array_arg[1]); } } pass = 1; } break; case SWITCH_MESSAGE_INDICATE_DEFLECT: { pass = 0; if (!zstr(msg->string_arg) && switch_core_session_get_partner(tech_pvt->other_session, &other_session) == SWITCH_STATUS_SUCCESS) { char *ext = switch_core_session_strdup(other_session, msg->string_arg); char *context = NULL, *dp = NULL; if ((context = strchr(ext, ' '))) { *context++ = '\0'; if ((dp = strchr(context, ' '))) { *dp++ = '\0'; } } switch_ivr_session_transfer(other_session, ext, context, dp); switch_core_session_rwunlock(other_session); } } break; default: break; } if (!done && tech_pvt->other_session && (pass || switch_test_flag(tech_pvt, TFLAG_RUNNING_APP))) { switch_status_t r = SWITCH_STATUS_FALSE; if (switch_core_session_get_partner(tech_pvt->other_session, &other_session) == SWITCH_STATUS_SUCCESS) { r = switch_core_session_receive_message(other_session, msg); switch_core_session_rwunlock(other_session); } return r; } return SWITCH_STATUS_SUCCESS; }
void conference_event_mod_channel_handler(const char *event_channel, cJSON *json, const char *key, switch_event_channel_id_t id) { cJSON *data, *addobj = NULL; const char *action = NULL; char *value = NULL; cJSON *jid = 0; char *conference_name = strdup(event_channel + 15); char cid[32] = ""; char *p; switch_stream_handle_t stream = { 0 }; char *exec = NULL; cJSON *msg, *jdata, *jvalue; char *argv[10] = {0}; int argc = 0; if (conference_name && (p = strchr(conference_name, '@'))) { *p = '\0'; } if ((data = cJSON_GetObjectItem(json, "data"))) { action = cJSON_GetObjectCstr(data, "command"); if ((jid = cJSON_GetObjectItem(data, "id"))) { if (jid->valueint) { switch_snprintf(cid, sizeof(cid), "%d", jid->valueint); } else if (!zstr(jid->valuestring)) { switch_snprintf(cid, sizeof(cid), "%s", jid->valuestring); } } if ((jvalue = cJSON_GetObjectItem(data, "value"))) { if (jvalue->type == cJSON_Array) { int i; argc = cJSON_GetArraySize(jvalue); if (argc > 10) argc = 10; for (i = 0; i < argc; i++) { cJSON *str = cJSON_GetArrayItem(jvalue, i); if (str->type == cJSON_String) { argv[i] = str->valuestring; } } } else if (jvalue->type == cJSON_String) { value = jvalue->valuestring; argv[argc++] = value; } } } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "conf %s CMD %s [%s] %s\n", conference_name, key, action, cid); if (zstr(action)) { goto end; } SWITCH_STANDARD_STREAM(stream); if (!strcasecmp(action, "kick")) { exec = switch_mprintf("%s %s %s", conference_name, action, cid); } else if (!strcasecmp(action, "mute") || !strcasecmp(action, "unmute") || !strcasecmp(action, "tmute") || !strcasecmp(action, "vmute") || !strcasecmp(action, "unvmute") || !strcasecmp(action, "tvmute")) { if (argv[0]) { exec = switch_mprintf("%s %s %s %s", conference_name, action, cid, argv[0]); } else { exec = switch_mprintf("%s %s %s", conference_name, action, cid); } } else if (!strcasecmp(action, "volume_in") || !strcasecmp(action, "volume_out") || !strcasecmp(action, "vid-res-id") || !strcasecmp(action, "vid-floor") || !strcasecmp(action, "vid-layer") || !strcasecmp(action, "vid-canvas") || !strcasecmp(action, "vid-watching-canvas") || !strcasecmp(action, "vid-banner")) { exec = switch_mprintf("%s %s %s %s", conference_name, action, cid, argv[0]); } else if (!strcasecmp(action, "play") || !strcasecmp(action, "stop")) { exec = switch_mprintf("%s %s %s", conference_name, action, argv[0]); } else if (!strcasecmp(action, "recording") || !strcasecmp(action, "vid-layout") || !strcasecmp(action, "vid-write-png")) { if (!argv[1]) { argv[1] = "all"; } exec = switch_mprintf("%s %s %s %s", conference_name, action, argv[0], argv[1]); } else if (!strcasecmp(action, "transfer")) { conference_member_t *member; conference_obj_t *conference; if (cid[0] == '\0') { stream.write_function(&stream, "-ERR Call transfer requires id"); goto end; } exec = switch_mprintf("%s %s %s", argv[0], switch_str_nil(argv[1]), switch_str_nil(argv[2])); stream.write_function(&stream, "+OK Call transferred to %s", argv[0]); if ((conference = conference_find(conference_name, NULL))) { if ((member = conference_member_get(conference, atoi(cid)))) { switch_ivr_session_transfer(member->session, argv[0], argv[1], argv[2]); switch_thread_rwlock_unlock(member->rwlock); } switch_thread_rwlock_unlock(conference->rwlock); } goto end; } else if (!strcasecmp(action, "list-videoLayouts")) { switch_hash_index_t *hi; void *val; const void *vvar; cJSON *array = cJSON_CreateArray(); conference_obj_t *conference = NULL; if ((conference = conference_find(conference_name, NULL))) { switch_mutex_lock(conference_globals.setup_mutex); if (conference->layout_hash) { for (hi = switch_core_hash_first(conference->layout_hash); hi; hi = switch_core_hash_next(&hi)) { switch_core_hash_this(hi, &vvar, NULL, &val); cJSON_AddItemToArray(array, cJSON_CreateString((char *)vvar)); } } if (conference->layout_group_hash) { for (hi = switch_core_hash_first(conference->layout_group_hash); hi; hi = switch_core_hash_next(&hi)) { char *name; switch_core_hash_this(hi, &vvar, NULL, &val); name = switch_mprintf("group:%s", (char *)vvar); cJSON_AddItemToArray(array, cJSON_CreateString(name)); free(name); } } switch_mutex_unlock(conference_globals.setup_mutex); switch_thread_rwlock_unlock(conference->rwlock); } addobj = array; } if (exec) { conference_api_main_real(exec, NULL, &stream); } end: msg = cJSON_CreateObject(); jdata = json_add_child_obj(msg, "data", NULL); cJSON_AddItemToObject(msg, "eventChannel", cJSON_CreateString(event_channel)); cJSON_AddItemToObject(jdata, "action", cJSON_CreateString("response")); if (addobj) { cJSON_AddItemToObject(jdata, "conf-command", cJSON_CreateString(action)); cJSON_AddItemToObject(jdata, "response", cJSON_CreateString("OK")); cJSON_AddItemToObject(jdata, "responseData", addobj); } else if (exec) { cJSON_AddItemToObject(jdata, "conf-command", cJSON_CreateString(exec)); cJSON_AddItemToObject(jdata, "response", cJSON_CreateString((char *)stream.data)); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ALERT,"RES [%s][%s]\n", exec, (char *)stream.data); } else { cJSON_AddItemToObject(jdata, "error", cJSON_CreateString("Invalid Command")); } switch_event_channel_broadcast(event_channel, &msg, __FILE__, conference_globals.event_channel_id); switch_safe_free(stream.data); switch_safe_free(exec); switch_safe_free(conference_name); }