Files
freeswitch/src/switch_console.c
T
Anthony Minessale 0d23976f2a Insane amounts of yucky satanic code to make transfer and that kind of thing work.
Transfers work better when both legs of the call live in thier own channel eg bridged calls
A -> B where you want a to make B -> C

when you route a call to an IVR or playback app you are not really bridging you have
A all alone executing the script so it's hard to transfer that.

I do have it aparently working but it's goofy and you are better off
putting your IVR on it's own switch so they are all inbound calls
then you have A -> B -> IVR
now A can happily transfer B who can stay on line with IVR without stopping
the execution.  You can also accomplish this by calling in a loop back to the same box
if you dont want to have 2 boxes.


Also the beginning effort at bridging calls with no media is here
set this magic variable in your dialplan to convince mod_sofia
to pass A's sdp as it's own to B and return B's sdp back to A on 200 or 183

<action application="set" data="no_media=true"/>
<action application="bridge" data="sofia/id@host.com"/>

You will need a new sofia tarball for this version


There is a bunch of other odds and ends added like a function or 2 etc
Oh,

And don't be suprised if it introduces all kinds of bugs!



git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@2992 d0543943-73ff-0310-b7d9-9358b9ac24b2
2006-10-06 22:39:49 +00:00

261 lines
6.6 KiB
C

/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005/2006, Anthony Minessale II <anthmct@yahoo.com>
*
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
*
* The Initial Developer of the Original Code is
* Anthony Minessale II <anthmct@yahoo.com>
* Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Anthony Minessale II <anthmct@yahoo.com>
*
*
* switch_console.c -- Simple Console
*
*/
#include <switch.h>
#include <switch_console.h>
#include <switch_version.h>
#define CMD_BUFLEN 1024;
SWITCH_DECLARE(switch_status_t) switch_console_stream_write(switch_stream_handle_t *handle, char *fmt, ...)
{
va_list ap;
char *buf = handle->data;
char *end = handle->end;
int ret = 0;
char *data;
if (handle->data_len >= handle->data_size) {
return SWITCH_STATUS_FALSE;
}
va_start(ap, fmt);
#ifdef HAVE_VASPRINTF
ret = vasprintf(&data, fmt, ap);
#else
if ((data = (char *) malloc(2048))) {
vsnprintf(data, 2048, fmt, ap);
}
#endif
va_end(ap);
if (data) {
switch_size_t remaining = handle->data_size - handle->data_len;
switch_size_t need = strlen(data) + 1;
if ((remaining < need) && handle->alloc_len) {
switch_size_t new_len;
if (need < handle->alloc_chunk) {
need = handle->alloc_chunk;
}
new_len = handle->data_size + need;
if ((handle->data = realloc(handle->data, new_len))) {
handle->data_size = handle->alloc_len = new_len;
buf = handle->data;
remaining = handle->data_size - handle->data_len;
handle->end = (uint8_t *)(handle->data) + handle->data_len;
end = handle->end;
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
free(data);
return SWITCH_STATUS_FALSE;
}
}
if (remaining < need) {
ret = -1;
} else {
ret = 0;
snprintf(end, remaining, "%s", data);
handle->data_len = strlen(buf);
handle->end = (uint8_t *)(handle->data) + handle->data_len;
}
free(data);
}
return ret ? SWITCH_STATUS_FALSE : SWITCH_STATUS_SUCCESS;
}
static int switch_console_process(char *cmd)
{
char *arg = NULL;
switch_stream_handle_t stream = {0};
if (!strcmp(cmd, "shutdown") || !strcmp(cmd, "...")) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Bye!\n");
return 0;
}
if (!strcmp(cmd, "version")) {
switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_CONSOLE, "FreeSwitch Version %s\n", SWITCH_VERSION_FULL);
return 1;
}
if (!strcmp(cmd, "help")) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE,
"\n"
"Valid Commands:\n\n"
"version\n" "help - umm yeah..\n" "shutdown - stop the program\n\n");
return 1;
}
if ((arg = strchr(cmd, '\r')) != 0 || (arg = strchr(cmd, '\n')) != 0 ) {
*arg = '\0';
arg = NULL;
}
if ((arg = strchr(cmd, ' ')) != 0) {
*arg++ = '\0';
}
SWITCH_STANDARD_STREAM(stream);
if (stream.data) {
if (switch_api_execute(cmd, arg, NULL, &stream) == SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_CONSOLE, "API CALL [%s(%s)] output:\n%s\n", cmd, arg ? arg : "", stream.data);
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Unknown Command: %s\n", cmd);
}
free(stream.data);
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error!\n");
}
return 1;
}
SWITCH_DECLARE(void) switch_console_printf(switch_text_channel_t channel, char *file, const char *func, int line,
char *fmt, ...)
{
char *data = NULL;
int ret = 0;
va_list ap;
FILE *handle;
char *filep = switch_cut_path(file);
va_start(ap, fmt);
handle = switch_core_data_channel(channel);
#ifdef HAVE_VASPRINTF
ret = vasprintf(&data, fmt, ap);
#else
data = (char *) malloc(2048);
vsnprintf(data, 2048, fmt, ap);
#endif
va_end(ap);
if (ret == -1) {
fprintf(stderr, "Memory Error\n");
} else {
char date[80] = "";
if (channel == SWITCH_CHANNEL_ID_LOG_CLEAN) {
fprintf(handle, "%s", data);
} else {
switch_size_t retsize;
switch_time_exp_t tm;
switch_event_t *event;
switch_time_exp_lt(&tm, switch_time_now());
switch_strftime(date, &retsize, sizeof(date), "%Y-%m-%d %T", &tm);
if (channel == SWITCH_CHANNEL_ID_LOG) {
fprintf(handle, "[%d] %s %s:%d %s() %s", (int) getpid(), date, filep, line, func, data);
}
else if (channel == SWITCH_CHANNEL_ID_EVENT &&
switch_event_running() == SWITCH_STATUS_SUCCESS &&
switch_event_create(&event, SWITCH_EVENT_LOG) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Log-Data", "%s", data);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Log-File", "%s", filep);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Log-Function", "%s", func);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Log-Line", "%d", line);
switch_event_fire(&event);
}
}
}
if(data) {
free(data);
}
fflush(handle);
}
SWITCH_DECLARE(void) switch_console_loop(void)
{
char hostname[256];
char cmd[2048];
uint32_t activity = 1, running = 1;
switch_size_t x = 0;
gethostname(hostname, sizeof(hostname));
while(running) {
uint32_t arg;
fd_set rfds, efds;
struct timeval tv = {0, 20000};
switch_core_session_ctl(SCSC_CHECK_RUNNING, &arg);
if (!arg) {
break;
}
if (activity) {
switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_CONSOLE, "\nfreeswitch@%s> ", hostname);
}
#ifdef _MSC_VER
//Microsofts macros don't pass their own compilers warnings.
#pragma warning(push)
#pragma warning(disable: 4127 4389)
#endif
FD_ZERO(&rfds);
FD_ZERO(&efds);
FD_SET(fileno(stdin), &rfds);
FD_SET(fileno(stdin), &efds);
activity = select(fileno(stdin)+1, &rfds, NULL, &efds, &tv);
#ifdef _MSC_VER
#pragma warning(pop)
#endif
if (activity == 0) {
fflush(stdout);
continue;
}
memset(&cmd, 0, sizeof(cmd));
for (x = 0; x < (sizeof(cmd)-1); x++) {
cmd[x] = (char) getchar();
if (cmd[x] == '\n') {
cmd[x] = '\0';
break;
}
}
if (cmd[0]) {
running = switch_console_process(cmd);
}
}
}