mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-04-25 20:19:36 +00:00
OMG this rocks
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@102 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
parent
86c1904cce
commit
c5174dbcc8
@ -55,7 +55,7 @@ SWITCH_DECLARE(switch_codec_interface *) loadable_module_get_codec_interface(cha
|
|||||||
SWITCH_DECLARE(switch_dialplan_interface *) loadable_module_get_dialplan_interface(char *name);
|
SWITCH_DECLARE(switch_dialplan_interface *) loadable_module_get_dialplan_interface(char *name);
|
||||||
SWITCH_DECLARE(switch_timer_interface *) loadable_module_get_timer_interface(char *name);
|
SWITCH_DECLARE(switch_timer_interface *) loadable_module_get_timer_interface(char *name);
|
||||||
SWITCH_DECLARE(switch_application_interface *) loadable_module_get_application_interface(char *name);
|
SWITCH_DECLARE(switch_application_interface *) loadable_module_get_application_interface(char *name);
|
||||||
SWITCH_DECLARE(switch_application_interface *) loadable_module_get_api_interface(char *name);
|
SWITCH_DECLARE(switch_api_interface *) loadable_module_get_api_interface(char *name);
|
||||||
SWITCH_DECLARE(int) loadable_module_get_codecs(switch_memory_pool *pool, switch_codec_interface **array, int arraylen);
|
SWITCH_DECLARE(int) loadable_module_get_codecs(switch_memory_pool *pool, switch_codec_interface **array, int arraylen);
|
||||||
SWITCH_DECLARE(int) loadable_module_get_codecs_sorted(switch_memory_pool *pool, switch_codec_interface **array, int arraylen, char **prefs, int preflen);
|
SWITCH_DECLARE(int) loadable_module_get_codecs_sorted(switch_memory_pool *pool, switch_codec_interface **array, int arraylen, char **prefs, int preflen);
|
||||||
SWITCH_DECLARE(void) loadable_module_shutdown(void);
|
SWITCH_DECLARE(void) loadable_module_shutdown(void);
|
||||||
|
@ -254,7 +254,7 @@ struct switch_application_interface {
|
|||||||
struct switch_api_interface {
|
struct switch_api_interface {
|
||||||
const char *interface_name;
|
const char *interface_name;
|
||||||
const char *desc;
|
const char *desc;
|
||||||
switch_status (*function)(char *in, char *out, size_t outlen);
|
switch_api_function function;
|
||||||
const struct switch_api_interface *next;
|
const struct switch_api_interface *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -165,6 +165,7 @@ typedef switch_status (*switch_kill_channel_hook)(switch_core_session *, int);
|
|||||||
typedef switch_status (*switch_waitfor_read_hook)(switch_core_session *, int);
|
typedef switch_status (*switch_waitfor_read_hook)(switch_core_session *, int);
|
||||||
typedef switch_status (*switch_waitfor_write_hook)(switch_core_session *, int);
|
typedef switch_status (*switch_waitfor_write_hook)(switch_core_session *, int);
|
||||||
typedef switch_status (*switch_send_dtmf_hook)(switch_core_session *, char *);
|
typedef switch_status (*switch_send_dtmf_hook)(switch_core_session *, char *);
|
||||||
|
typedef switch_status (*switch_api_function)(char *in, char *out, size_t outlen);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The pieces of apr we allow ppl to pass around between modules we typedef into our namespace and wrap all the functions
|
The pieces of apr we allow ppl to pass around between modules we typedef into our namespace and wrap all the functions
|
||||||
@ -183,6 +184,7 @@ typedef apr_pollfd_t switch_pollfd_t;
|
|||||||
typedef apr_pollset_t switch_pollset_t;
|
typedef apr_pollset_t switch_pollset_t;
|
||||||
typedef apr_file_t switch_file_t;
|
typedef apr_file_t switch_file_t;
|
||||||
typedef apr_thread_cond_t switch_thread_cond_t;
|
typedef apr_thread_cond_t switch_thread_cond_t;
|
||||||
|
typedef apr_hash_index_t switch_hash_index_t;
|
||||||
|
|
||||||
#define SWITCH_UNSPEC APR_UNSPEC
|
#define SWITCH_UNSPEC APR_UNSPEC
|
||||||
#define SWITCH_POLLIN APR_POLLIN
|
#define SWITCH_POLLIN APR_POLLIN
|
||||||
@ -255,6 +257,9 @@ typedef apr_thread_cond_t switch_thread_cond_t;
|
|||||||
#define switch_file_close apr_file_close
|
#define switch_file_close apr_file_close
|
||||||
#define switch_file_read apr_file_read
|
#define switch_file_read apr_file_read
|
||||||
#define switch_file_write apr_file_write
|
#define switch_file_write apr_file_write
|
||||||
|
#define switch_hash_first apr_hash_first
|
||||||
|
#define switch_hash_next apr_hash_next
|
||||||
|
#define switch_hash_this apr_hash_this
|
||||||
|
|
||||||
#define SWITCH_FOPEN_READ APR_FOPEN_READ
|
#define SWITCH_FOPEN_READ APR_FOPEN_READ
|
||||||
#define SWITCH_FOPEN_WRITE APR_FOPEN_WRITE
|
#define SWITCH_FOPEN_WRITE APR_FOPEN_WRITE
|
||||||
|
@ -69,7 +69,11 @@ static void *audio_bridge_thread(switch_thread *thread, void *obj)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (switch_channel_has_dtmf(chan_a)) {
|
||||||
|
char dtmf[128];
|
||||||
|
switch_channel_dequeue_dtmf(chan_a, dtmf, sizeof(dtmf));
|
||||||
|
switch_core_session_send_dtmf(session_b, dtmf);
|
||||||
|
}
|
||||||
if (switch_core_session_read_frame(session_a, &read_frame, -1) == SWITCH_STATUS_SUCCESS && read_frame->datalen) {
|
if (switch_core_session_read_frame(session_a, &read_frame, -1) == SWITCH_STATUS_SUCCESS && read_frame->datalen) {
|
||||||
if (switch_core_session_write_frame(session_b, read_frame, -1) != SWITCH_STATUS_SUCCESS) {
|
if (switch_core_session_write_frame(session_b, read_frame, -1) != SWITCH_STATUS_SUCCESS) {
|
||||||
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Bad Frame.... %d Bubye!\n", read_frame->datalen);
|
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Bad Frame.... %d Bubye!\n", read_frame->datalen);
|
||||||
@ -79,7 +83,6 @@ static void *audio_bridge_thread(switch_thread *thread, void *obj)
|
|||||||
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Bad Frame....Bubye!\n");
|
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Bad Frame....Bubye!\n");
|
||||||
data->running = -1;
|
data->running = -1;
|
||||||
}
|
}
|
||||||
//switch_yield(100);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch_channel_hangup(chan_b);
|
switch_channel_hangup(chan_b);
|
||||||
|
@ -87,26 +87,8 @@ struct private_object {
|
|||||||
switch_thread_cond_t *cond;
|
switch_thread_cond_t *cond;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void set_global_dialplan(char *dialplan)
|
SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_dialplan, globals.dialplan)
|
||||||
{
|
SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_codec_string, globals.codec_string)
|
||||||
if (globals.dialplan) {
|
|
||||||
free(globals.dialplan);
|
|
||||||
globals.dialplan = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
globals.dialplan = strdup(dialplan);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void set_global_codec_string(char *codec_string)
|
|
||||||
{
|
|
||||||
if (globals.codec_string) {
|
|
||||||
free(globals.codec_string);
|
|
||||||
globals.codec_string = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
globals.codec_string = strdup(codec_string);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static char *IAXNAMES[] = {"IAX_EVENT_CONNECT","IAX_EVENT_ACCEPT","IAX_EVENT_HANGUP","IAX_EVENT_REJECT","IAX_EVENT_VOICE",
|
static char *IAXNAMES[] = {"IAX_EVENT_CONNECT","IAX_EVENT_ACCEPT","IAX_EVENT_HANGUP","IAX_EVENT_REJECT","IAX_EVENT_VOICE",
|
||||||
@ -344,13 +326,13 @@ static switch_status channel_kill_channel(switch_core_session *session, int sig)
|
|||||||
|
|
||||||
static void iax_err_cb(const char *s)
|
static void iax_err_cb(const char *s)
|
||||||
{
|
{
|
||||||
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "%s", s);
|
switch_console_printf(SWITCH_CHANNEL_CONSOLE_CLEAN, "IAX ERR: %s", s);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void iax_out_cb(const char *s)
|
static void iax_out_cb(const char *s)
|
||||||
{
|
{
|
||||||
if (globals.debug) {
|
if (globals.debug) {
|
||||||
iax_err_cb(s);
|
switch_console_printf(SWITCH_CHANNEL_CONSOLE_CLEAN, "IAX INFO: %s", s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -788,6 +770,9 @@ SWITCH_MOD_DECLARE(switch_status) switch_module_runtime(void)
|
|||||||
|
|
||||||
load_config();
|
load_config();
|
||||||
|
|
||||||
|
if (globals.debug) {
|
||||||
|
iax_enable_debug();
|
||||||
|
}
|
||||||
if ((res = iax_init(globals.port) < 0)) {
|
if ((res = iax_init(globals.port) < 0)) {
|
||||||
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Error Binding Port!\n");
|
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Error Binding Port!\n");
|
||||||
return SWITCH_STATUS_TERM;
|
return SWITCH_STATUS_TERM;
|
||||||
|
@ -68,6 +68,8 @@ static struct {
|
|||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
int indev;
|
int indev;
|
||||||
int outdev;
|
int outdev;
|
||||||
|
int call_id;
|
||||||
|
switch_hash *call_hash;
|
||||||
} globals;
|
} globals;
|
||||||
|
|
||||||
struct private_object {
|
struct private_object {
|
||||||
@ -78,6 +80,7 @@ struct private_object {
|
|||||||
unsigned char databuf[1024];
|
unsigned char databuf[1024];
|
||||||
switch_core_session *session;
|
switch_core_session *session;
|
||||||
switch_caller_profile *caller_profile;
|
switch_caller_profile *caller_profile;
|
||||||
|
char call_id[50];
|
||||||
PaError err;
|
PaError err;
|
||||||
PABLIO_Stream *audio_in;
|
PABLIO_Stream *audio_in;
|
||||||
PABLIO_Stream *audio_out;
|
PABLIO_Stream *audio_out;
|
||||||
@ -101,6 +104,12 @@ static switch_status channel_outgoing_channel(switch_core_session *session, swit
|
|||||||
static switch_status channel_read_frame(switch_core_session *session, switch_frame **frame, int timeout, switch_io_flag flags);
|
static switch_status channel_read_frame(switch_core_session *session, switch_frame **frame, int timeout, switch_io_flag flags);
|
||||||
static switch_status channel_write_frame(switch_core_session *session, switch_frame *frame, int timeout, switch_io_flag flags);
|
static switch_status channel_write_frame(switch_core_session *session, switch_frame *frame, int timeout, switch_io_flag flags);
|
||||||
static switch_status channel_kill_channel(switch_core_session *session, int sig);
|
static switch_status channel_kill_channel(switch_core_session *session, int sig);
|
||||||
|
static int dump_info(void);
|
||||||
|
static switch_status load_config(void);
|
||||||
|
static int get_dev_by_name(char *name, int in);
|
||||||
|
static switch_status place_call(char *dest, char *out, size_t outlen);
|
||||||
|
static switch_status hup_call(char *callid, char *out, size_t outlen);
|
||||||
|
static switch_status call_info(char *callid, char *out, size_t outlen);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -175,6 +184,7 @@ static switch_status channel_on_hangup(switch_core_session *session)
|
|||||||
assert(tech_pvt != NULL);
|
assert(tech_pvt != NULL);
|
||||||
|
|
||||||
switch_clear_flag(tech_pvt, TFLAG_IO);
|
switch_clear_flag(tech_pvt, TFLAG_IO);
|
||||||
|
switch_core_hash_delete(globals.call_hash, tech_pvt->call_id);
|
||||||
|
|
||||||
switch_core_codec_destroy(&tech_pvt->read_codec);
|
switch_core_codec_destroy(&tech_pvt->read_codec);
|
||||||
switch_core_codec_destroy(&tech_pvt->write_codec);
|
switch_core_codec_destroy(&tech_pvt->write_codec);
|
||||||
@ -299,13 +309,11 @@ static switch_status channel_waitfor_write(switch_core_session *session, int ms)
|
|||||||
static switch_status channel_send_dtmf(switch_core_session *session, char *dtmf)
|
static switch_status channel_send_dtmf(switch_core_session *session, char *dtmf)
|
||||||
{
|
{
|
||||||
struct private_object *tech_pvt = NULL;
|
struct private_object *tech_pvt = NULL;
|
||||||
char *digit;
|
|
||||||
|
|
||||||
tech_pvt = switch_core_session_get_private(session);
|
tech_pvt = switch_core_session_get_private(session);
|
||||||
assert(tech_pvt != NULL);
|
assert(tech_pvt != NULL);
|
||||||
for(digit = dtmf; *digit; digit++) {
|
|
||||||
//XXX Do something...
|
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "DTMF ON CALL %s [%s]\n", tech_pvt->call_id, dtmf);
|
||||||
}
|
|
||||||
|
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -374,6 +382,27 @@ static switch_status channel_answer_channel(switch_core_session *session)
|
|||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct switch_api_interface channel_info_interface = {
|
||||||
|
/*.interface_name*/ "painfo",
|
||||||
|
/*.desc*/ "PortAudio Call Info",
|
||||||
|
/*.function*/ call_info,
|
||||||
|
/*.next*/ NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct switch_api_interface channel_hup_interface = {
|
||||||
|
/*.interface_name*/ "pahup",
|
||||||
|
/*.desc*/ "PortAudio Hangup Call",
|
||||||
|
/*.function*/ hup_call,
|
||||||
|
/*.next*/ &channel_info_interface
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct switch_api_interface channel_api_interface = {
|
||||||
|
/*.interface_name*/ "pacall",
|
||||||
|
/*.desc*/ "PortAudio Call",
|
||||||
|
/*.function*/ place_call,
|
||||||
|
/*.next*/ &channel_hup_interface
|
||||||
|
};
|
||||||
|
|
||||||
static const switch_event_handler_table channel_event_handlers = {
|
static const switch_event_handler_table channel_event_handlers = {
|
||||||
/*.on_init*/ channel_on_init,
|
/*.on_init*/ channel_on_init,
|
||||||
/*.on_ring*/ channel_on_ring,
|
/*.on_ring*/ channel_on_ring,
|
||||||
@ -408,13 +437,10 @@ static const switch_loadable_module_interface channel_module_interface = {
|
|||||||
/*.timer_interface*/ NULL,
|
/*.timer_interface*/ NULL,
|
||||||
/*.dialplan_interface*/ NULL,
|
/*.dialplan_interface*/ NULL,
|
||||||
/*.codec_interface*/ NULL,
|
/*.codec_interface*/ NULL,
|
||||||
/*.application_interface*/ NULL
|
/*.application_interface*/ NULL,
|
||||||
|
/*.api_interface*/ &channel_api_interface
|
||||||
};
|
};
|
||||||
|
|
||||||
static int dump_info(void);
|
|
||||||
static void make_call(char *dest);
|
|
||||||
static switch_status load_config(void);
|
|
||||||
static int get_dev_by_name(char *name, int in);
|
|
||||||
|
|
||||||
SWITCH_MOD_DECLARE(switch_status) switch_module_load(const switch_loadable_module_interface **interface, char *filename) {
|
SWITCH_MOD_DECLARE(switch_status) switch_module_load(const switch_loadable_module_interface **interface, char *filename) {
|
||||||
|
|
||||||
@ -423,9 +449,13 @@ SWITCH_MOD_DECLARE(switch_status) switch_module_load(const switch_loadable_modul
|
|||||||
return SWITCH_STATUS_TERM;
|
return SWITCH_STATUS_TERM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Pa_Initialize();
|
Pa_Initialize();
|
||||||
load_config();
|
load_config();
|
||||||
|
switch_core_hash_init(&globals.call_hash, module_pool);
|
||||||
|
|
||||||
dump_info();
|
dump_info();
|
||||||
|
|
||||||
/* connect my internal structure to the blank pointer passed to me */
|
/* connect my internal structure to the blank pointer passed to me */
|
||||||
*interface = &channel_module_interface;
|
*interface = &channel_module_interface;
|
||||||
|
|
||||||
@ -482,7 +512,7 @@ static switch_status load_config(void)
|
|||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
SWITCH_MOD_DECLARE(switch_status) switch_module_runtime(void)
|
SWITCH_MOD_DECLARE(switch_status) switch_module_runtime(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -490,7 +520,7 @@ SWITCH_MOD_DECLARE(switch_status) switch_module_runtime(void)
|
|||||||
make_call("8888");
|
make_call("8888");
|
||||||
return SWITCH_STATUS_TERM;
|
return SWITCH_STATUS_TERM;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
SWITCH_MOD_DECLARE(switch_status) switch_module_shutdown(void)
|
SWITCH_MOD_DECLARE(switch_status) switch_module_shutdown(void)
|
||||||
{
|
{
|
||||||
@ -582,12 +612,19 @@ error:
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void make_call(char *dest)
|
static switch_status place_call(char *dest, char *out, size_t outlen)
|
||||||
{
|
{
|
||||||
switch_core_session *session;
|
switch_core_session *session;
|
||||||
int sample_rate = 8000;
|
int sample_rate = 8000;
|
||||||
int codec_ms = 20;
|
int codec_ms = 20;
|
||||||
|
|
||||||
|
if (!dest) {
|
||||||
|
strncpy(out, "Usage: pacall <exten>", outlen - 1);
|
||||||
|
return SWITCH_STATUS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
strncpy(out, "FAIL", outlen - 1);
|
||||||
|
|
||||||
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "New Inbound Channel\n");
|
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "New Inbound Channel\n");
|
||||||
if ((session = switch_core_session_request(&channel_endpoint_interface, NULL))) {
|
if ((session = switch_core_session_request(&channel_endpoint_interface, NULL))) {
|
||||||
struct private_object *tech_pvt;
|
struct private_object *tech_pvt;
|
||||||
@ -600,7 +637,7 @@ static void make_call(char *dest)
|
|||||||
} else {
|
} else {
|
||||||
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Hey where is my memory pool?\n");
|
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Hey where is my memory pool?\n");
|
||||||
switch_core_session_destroy(&session);
|
switch_core_session_destroy(&session);
|
||||||
return;
|
return SWITCH_STATUS_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((tech_pvt->caller_profile = switch_caller_profile_new(session,
|
if ((tech_pvt->caller_profile = switch_caller_profile_new(session,
|
||||||
@ -624,7 +661,7 @@ static void make_call(char *dest)
|
|||||||
SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
|
SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
|
||||||
NULL) != SWITCH_STATUS_SUCCESS) {
|
NULL) != SWITCH_STATUS_SUCCESS) {
|
||||||
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Can't load codec?\n");
|
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Can't load codec?\n");
|
||||||
return;
|
return SWITCH_STATUS_FALSE;
|
||||||
} else {
|
} else {
|
||||||
if (switch_core_codec_init(&tech_pvt->write_codec,
|
if (switch_core_codec_init(&tech_pvt->write_codec,
|
||||||
"L16",
|
"L16",
|
||||||
@ -633,7 +670,7 @@ static void make_call(char *dest)
|
|||||||
SWITCH_CODEC_FLAG_ENCODE |SWITCH_CODEC_FLAG_DECODE, NULL) != SWITCH_STATUS_SUCCESS) {
|
SWITCH_CODEC_FLAG_ENCODE |SWITCH_CODEC_FLAG_DECODE, NULL) != SWITCH_STATUS_SUCCESS) {
|
||||||
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Can't load codec?\n");
|
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Can't load codec?\n");
|
||||||
switch_core_codec_destroy(&tech_pvt->read_codec);
|
switch_core_codec_destroy(&tech_pvt->read_codec);
|
||||||
return;
|
return SWITCH_STATUS_FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -654,12 +691,98 @@ static void make_call(char *dest)
|
|||||||
}
|
}
|
||||||
if (tech_pvt->err == paNoError) {
|
if (tech_pvt->err == paNoError) {
|
||||||
switch_channel_set_state(channel, CS_INIT);
|
switch_channel_set_state(channel, CS_INIT);
|
||||||
switch_core_session_thread_launch(session);
|
snprintf(tech_pvt->call_id, sizeof(tech_pvt->call_id), "%d", globals.call_id++);
|
||||||
|
switch_core_hash_insert(globals.call_hash, tech_pvt->call_id, tech_pvt);
|
||||||
|
switch_core_session_thread_launch(session);
|
||||||
|
snprintf(out, outlen, "SUCCESS: %s", tech_pvt->call_id);
|
||||||
|
return SWITCH_STATUS_SUCCESS;
|
||||||
} else {
|
} else {
|
||||||
switch_core_codec_destroy(&tech_pvt->read_codec);
|
switch_core_codec_destroy(&tech_pvt->read_codec);
|
||||||
switch_core_codec_destroy(&tech_pvt->write_codec);
|
switch_core_codec_destroy(&tech_pvt->write_codec);
|
||||||
switch_core_session_destroy(&session);
|
switch_core_session_destroy(&session);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return SWITCH_STATUS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static switch_status hup_call(char *callid, char *out, size_t outlen)
|
||||||
|
{
|
||||||
|
struct private_object *tech_pvt;
|
||||||
|
switch_channel *channel = NULL;
|
||||||
|
char tmp[50];
|
||||||
|
|
||||||
|
if (callid && !strcasecmp(callid, "last")) {
|
||||||
|
snprintf(tmp, sizeof(tmp), "%d", globals.call_id - 1);
|
||||||
|
callid = tmp;
|
||||||
|
}
|
||||||
|
if (!callid || !strcasecmp(callid, "all")) {
|
||||||
|
switch_hash_index_t* hi;
|
||||||
|
void *val;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
for (hi = apr_hash_first(module_pool, globals.call_hash); hi; hi = switch_hash_next(hi)) {
|
||||||
|
switch_hash_this(hi, NULL, NULL, &val);
|
||||||
|
tech_pvt = val;
|
||||||
|
channel = switch_core_session_get_channel(tech_pvt->session);
|
||||||
|
assert(channel != NULL);
|
||||||
|
switch_channel_hangup(channel);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(out, outlen, "HUNGUP: %d", i);
|
||||||
|
|
||||||
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((tech_pvt = switch_core_hash_find(globals.call_hash, callid))) {
|
||||||
|
|
||||||
|
channel = switch_core_session_get_channel(tech_pvt->session);
|
||||||
|
assert(channel != NULL);
|
||||||
|
|
||||||
|
switch_channel_hangup(channel);
|
||||||
|
strncpy(out, "OK", outlen - 1);
|
||||||
|
} else {
|
||||||
|
strncpy(out, "NO SUCH CALL", outlen - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void print_info(struct private_object *tech_pvt, char *out, size_t outlen)
|
||||||
|
{
|
||||||
|
switch_channel *channel = NULL;
|
||||||
|
channel = switch_core_session_get_channel(tech_pvt->session);
|
||||||
|
assert(channel != NULL);
|
||||||
|
|
||||||
|
snprintf(out, outlen, "CALL %s\t%s\t%s\t%s\t%s\n",
|
||||||
|
tech_pvt->call_id,
|
||||||
|
tech_pvt->caller_profile->caller_id_name,
|
||||||
|
tech_pvt->caller_profile->caller_id_number,
|
||||||
|
tech_pvt->caller_profile->destination_number,
|
||||||
|
switch_channel_get_name(channel));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static switch_status call_info(char *callid, char *out, size_t outlen)
|
||||||
|
{
|
||||||
|
struct private_object *tech_pvt;
|
||||||
|
char tmp[50];
|
||||||
|
switch_hash_index_t* hi;
|
||||||
|
void *val;
|
||||||
|
if (!callid || !strcasecmp(callid, "all")) {
|
||||||
|
for (hi = apr_hash_first(module_pool, globals.call_hash); hi; hi = switch_hash_next(hi)) {
|
||||||
|
switch_hash_this(hi, NULL, NULL, &val);
|
||||||
|
tech_pvt = val;
|
||||||
|
print_info(tech_pvt, out + strlen(out), outlen - strlen(out));
|
||||||
|
}
|
||||||
|
} else if ((tech_pvt = switch_core_hash_find(globals.call_hash, callid))) {
|
||||||
|
print_info(tech_pvt, out, outlen);
|
||||||
|
} else {
|
||||||
|
strncpy(out, "NO SUCH CALL", outlen - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
}
|
@ -33,6 +33,9 @@
|
|||||||
|
|
||||||
static int switch_console_process(char *cmd)
|
static int switch_console_process(char *cmd)
|
||||||
{
|
{
|
||||||
|
switch_api_interface *api;
|
||||||
|
char *arg = NULL;
|
||||||
|
|
||||||
#ifdef EMBED_PERL
|
#ifdef EMBED_PERL
|
||||||
const char *perlhelp = "perl - execute some perl. (print to STDERR if you want to see it.)\n";
|
const char *perlhelp = "perl - execute some perl. (print to STDERR if you want to see it.)\n";
|
||||||
#else
|
#else
|
||||||
@ -53,6 +56,17 @@ static int switch_console_process(char *cmd)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (arg = strchr(cmd, ' ')) {
|
||||||
|
*arg++ = '\0';
|
||||||
|
}
|
||||||
|
if ((api = loadable_module_get_api_interface(cmd))) {
|
||||||
|
char retbuf[512] = "";
|
||||||
|
switch_status status = api->function(arg, retbuf, sizeof(retbuf));
|
||||||
|
switch_console_printf(SWITCH_CHANNEL_CONSOLE_CLEAN, "API CALL [%s(%s)] output:\n%s\n", cmd, arg ? arg : "", retbuf);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef EMBED_PERL
|
#ifdef EMBED_PERL
|
||||||
if (!strncmp(cmd, "perl ", 5)) {
|
if (!strncmp(cmd, "perl ", 5)) {
|
||||||
cmd += 5;
|
cmd += 5;
|
||||||
|
@ -363,7 +363,7 @@ SWITCH_DECLARE(switch_application_interface *) loadable_module_get_application_i
|
|||||||
return switch_core_hash_find(loadable_modules.application_hash, name);
|
return switch_core_hash_find(loadable_modules.application_hash, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
SWITCH_DECLARE(switch_application_interface *) loadable_module_get_api_interface(char *name)
|
SWITCH_DECLARE(switch_api_interface *) loadable_module_get_api_interface(char *name)
|
||||||
{
|
{
|
||||||
return switch_core_hash_find(loadable_modules.api_hash, name);
|
return switch_core_hash_find(loadable_modules.api_hash, name);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user