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 do_telecast(switch_stream_handle_t *stream) { char *path_info = switch_event_get_header(stream->param_event, "http-path-info"); char *uuid = strdup(path_info + 4); switch_core_session_t *tsession; char *fname = "stream.mp3"; if ((fname = strchr(uuid, '/'))) { *fname++ = '\0'; } if (!(tsession = switch_core_session_locate(uuid))) { char *ref = switch_event_get_header(stream->param_event, "http-referer"); stream->write_function(stream, "Content-type: text/html\r\n\r\n<h2>Not Found!</h2>\n" "<META http-equiv=\"refresh\" content=\"1;URL=%s\">", ref); } else { switch_media_bug_t *bug = NULL; switch_buffer_t *buffer = NULL; switch_mutex_t *mutex; switch_channel_t *channel = switch_core_session_get_channel(tsession); lame_global_flags *gfp = NULL; switch_codec_implementation_t read_impl = { 0 }; switch_core_session_get_read_impl(tsession, &read_impl); if (switch_channel_test_flag(channel, CF_PROXY_MODE)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Stepping into media path so this will work!\n"); switch_ivr_media(uuid, SMF_REBRIDGE); } if (!(gfp = lame_init())) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not allocate lame\n"); goto end; } lame_set_num_channels(gfp, read_impl.number_of_channels); lame_set_in_samplerate(gfp, read_impl.actual_samples_per_second); lame_set_brate(gfp, 16 * (read_impl.actual_samples_per_second / 8000) * read_impl.number_of_channels); lame_set_mode(gfp, 3); lame_set_quality(gfp, 2); lame_set_errorf(gfp, log_error); lame_set_debugf(gfp, log_debug); lame_set_msgf(gfp, log_msg); lame_set_bWriteVbrTag(gfp, 0); lame_mp3_tags_fid(gfp, NULL); lame_init_params(gfp); lame_print_config(gfp); switch_mutex_init(&mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(tsession)); switch_buffer_create_dynamic(&buffer, 1024, 2048, 0); switch_buffer_add_mutex(buffer, mutex); if (switch_core_media_bug_add(tsession, "telecast", NULL, telecast_callback, buffer, 0, SMBF_READ_STREAM | SMBF_WRITE_STREAM | SMBF_READ_PING, &bug) != SWITCH_STATUS_SUCCESS) { goto end; } stream->write_function(stream, "Content-type: audio/mpeg\r\n" "Content-Disposition: inline; filename=\"%s\"\r\n\r\n", fname); while (switch_channel_ready(channel)) { unsigned char mp3buf[TC_BUFFER_SIZE] = ""; int rlen; uint8_t buf[1024]; switch_size_t bytes = 0; if (switch_buffer_inuse(buffer) >= 1024) { switch_buffer_lock(buffer); bytes = switch_buffer_read(buffer, buf, sizeof(buf)); switch_buffer_unlock(buffer); } else { if (!bytes) { switch_cond_next(); continue; } memset(buf, 0, bytes); } if ((rlen = lame_encode_buffer(gfp, (void *) buf, NULL, bytes / 2, mp3buf, sizeof(mp3buf))) < 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "MP3 encode error %d!\n", rlen); goto end; } if (rlen) { if (stream->raw_write_function(stream, mp3buf, rlen)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Disconnected\n"); goto end; } } } end: switch_safe_free(uuid); if (gfp) { lame_close(gfp); gfp = NULL; } if (bug) { switch_core_media_bug_remove(tsession, &bug); } if (buffer) { switch_buffer_destroy(&buffer); } switch_core_session_rwunlock(tsession); } }
static void switch_core_standard_on_routing(switch_core_session_t *session) { switch_dialplan_interface_t *dialplan_interface = NULL; switch_caller_profile_t *caller_profile; switch_caller_extension_t *extension = NULL; char *expanded = NULL; char *dpstr = NULL; switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Standard ROUTING\n", switch_channel_get_name(session->channel)); switch_channel_set_variable(session->channel, "call_uuid", switch_core_session_get_uuid(session)); if ((switch_channel_test_flag(session->channel, CF_ANSWERED) || switch_channel_test_flag(session->channel, CF_EARLY_MEDIA) || switch_channel_test_flag(session->channel, CF_SIGNAL_BRIDGE_TTL)) && switch_channel_test_flag(session->channel, CF_PROXY_MODE)) { switch_ivr_media(session->uuid_str, SMF_NONE); } if ((caller_profile = switch_channel_get_caller_profile(session->channel)) == 0) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't get profile!\n"); switch_channel_hangup(session->channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); return; } else { char *dp[25]; int argc, x, count = 0; if ((extension = switch_channel_get_queued_extension(session->channel))) { switch_channel_set_caller_extension(session->channel, extension); switch_channel_set_state(session->channel, CS_EXECUTE); goto end; } if (!zstr(caller_profile->dialplan)) { if ((dpstr = switch_core_session_strdup(session, caller_profile->dialplan))) { expanded = switch_channel_expand_variables(session->channel, dpstr); argc = switch_separate_string(expanded, ',', dp, (sizeof(dp) / sizeof(dp[0]))); for (x = 0; x < argc; x++) { char *dpname = dp[x]; char *dparg = NULL; if (dpname) { if ((dparg = strchr(dpname, ':'))) { *dparg++ = '\0'; } } else { continue; } if (!(dialplan_interface = switch_loadable_module_get_dialplan_interface(dpname))) { continue; } count++; extension = dialplan_interface->hunt_function(session, dparg, NULL); UNPROTECT_INTERFACE(dialplan_interface); if (extension) { switch_channel_set_caller_extension(session->channel, extension); switch_channel_set_state(session->channel, CS_EXECUTE); goto end; } } } } if (!count) { if (switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { if (switch_channel_test_flag(session->channel, CF_ANSWERED)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "No Dialplan on answered channel, changing state to HANGUP\n"); switch_channel_hangup(session->channel, SWITCH_CAUSE_NO_ROUTE_DESTINATION); } else { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "No Dialplan, changing state to CONSUME_MEDIA\n"); switch_channel_set_state(session->channel, CS_CONSUME_MEDIA); } goto end; } } } if (!extension) { if (switch_ivr_blind_transfer_ack(session, SWITCH_FALSE) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "No Route, Aborting\n"); switch_channel_hangup(session->channel, SWITCH_CAUSE_NO_ROUTE_DESTINATION); } } end: if (expanded && dpstr && expanded != dpstr) { free(expanded); } }