git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@90 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale 2005-12-06 21:25:56 +00:00
parent 935c23ca8b
commit 46b0e12a66
8 changed files with 127 additions and 9 deletions

View File

@ -90,6 +90,7 @@ SWITCH_DECLARE(switch_status) switch_core_session_write_frame(switch_core_sessio
SWITCH_DECLARE(switch_status) switch_core_session_kill_channel(switch_core_session *session, switch_signal sig); SWITCH_DECLARE(switch_status) switch_core_session_kill_channel(switch_core_session *session, switch_signal sig);
SWITCH_DECLARE(switch_status) switch_core_session_waitfor_read(switch_core_session *session, int timeout); SWITCH_DECLARE(switch_status) switch_core_session_waitfor_read(switch_core_session *session, int timeout);
SWITCH_DECLARE(switch_status) switch_core_session_waitfor_write(switch_core_session *session, int timeout); SWITCH_DECLARE(switch_status) switch_core_session_waitfor_write(switch_core_session *session, int timeout);
SWITCH_DECLARE(switch_status) switch_core_session_send_dtmf(switch_core_session *session, char *dtmf);
SWITCH_DECLARE(switch_status) switch_core_session_add_event_hook_outgoing(switch_core_session *session, switch_outgoing_channel_hook outgoing_channel); SWITCH_DECLARE(switch_status) switch_core_session_add_event_hook_outgoing(switch_core_session *session, switch_outgoing_channel_hook outgoing_channel);
SWITCH_DECLARE(switch_status) switch_core_session_add_event_hook_answer_channel(switch_core_session *session, switch_answer_channel_hook answer_channel); SWITCH_DECLARE(switch_status) switch_core_session_add_event_hook_answer_channel(switch_core_session *session, switch_answer_channel_hook answer_channel);
SWITCH_DECLARE(switch_status) switch_core_session_add_event_hook_read_frame(switch_core_session *session, switch_read_frame_hook read_frame); SWITCH_DECLARE(switch_status) switch_core_session_add_event_hook_read_frame(switch_core_session *session, switch_read_frame_hook read_frame);
@ -97,6 +98,7 @@ SWITCH_DECLARE(switch_status) switch_core_session_add_event_hook_write_frame(swi
SWITCH_DECLARE(switch_status) switch_core_session_add_event_hook_kill_channel(switch_core_session *session, switch_kill_channel_hook kill_channel); SWITCH_DECLARE(switch_status) switch_core_session_add_event_hook_kill_channel(switch_core_session *session, switch_kill_channel_hook kill_channel);
SWITCH_DECLARE(switch_status) switch_core_session_add_event_hook_waitfor_read(switch_core_session *session, switch_waitfor_read_hook waitfor_read); SWITCH_DECLARE(switch_status) switch_core_session_add_event_hook_waitfor_read(switch_core_session *session, switch_waitfor_read_hook waitfor_read);
SWITCH_DECLARE(switch_status) switch_core_session_add_event_hook_waitfor_write(switch_core_session *session, switch_waitfor_write_hook waitfor_write); SWITCH_DECLARE(switch_status) switch_core_session_add_event_hook_waitfor_write(switch_core_session *session, switch_waitfor_write_hook waitfor_write);
SWITCH_DECLARE(switch_status) switch_core_session_add_event_hook_send_dtmf(switch_core_session *session, switch_send_dtmf_hook send_dtmf);
SWITCH_DECLARE(switch_status) switch_core_codec_init(switch_codec *codec, char *codec_name, int rate, int ms, switch_codec_flag flags, const switch_codec_settings *codec_settings); SWITCH_DECLARE(switch_status) switch_core_codec_init(switch_codec *codec, char *codec_name, int rate, int ms, switch_codec_flag flags, const switch_codec_settings *codec_settings);
SWITCH_DECLARE(switch_status) switch_core_codec_encode(switch_codec *codec, SWITCH_DECLARE(switch_status) switch_core_codec_encode(switch_codec *codec,
switch_codec *other_codec, switch_codec *other_codec,

View File

@ -83,6 +83,11 @@ struct switch_io_event_hook_waitfor_write {
struct switch_io_event_hook_waitfor_write *next; struct switch_io_event_hook_waitfor_write *next;
}; };
struct switch_io_event_hook_send_dtmf {
switch_send_dtmf_hook send_dtmf;
struct switch_io_event_hook_send_dtmf *next;
};
struct switch_io_event_hooks { struct switch_io_event_hooks {
struct switch_io_event_hook_outgoing_channel *outgoing_channel; struct switch_io_event_hook_outgoing_channel *outgoing_channel;
struct switch_io_event_hook_answer_channel *answer_channel; struct switch_io_event_hook_answer_channel *answer_channel;
@ -91,6 +96,7 @@ struct switch_io_event_hooks {
struct switch_io_event_hook_kill_channel *kill_channel; struct switch_io_event_hook_kill_channel *kill_channel;
struct switch_io_event_hook_waitfor_read *waitfor_read; struct switch_io_event_hook_waitfor_read *waitfor_read;
struct switch_io_event_hook_waitfor_write *waitfor_write; struct switch_io_event_hook_waitfor_write *waitfor_write;
struct switch_io_event_hook_send_dtmf *send_dtmf;
}; };
struct switch_io_routines { struct switch_io_routines {
@ -101,6 +107,7 @@ struct switch_io_routines {
switch_status (*kill_channel)(switch_core_session *, int); switch_status (*kill_channel)(switch_core_session *, int);
switch_status (*waitfor_read)(switch_core_session *, int); switch_status (*waitfor_read)(switch_core_session *, int);
switch_status (*waitfor_write)(switch_core_session *, int); switch_status (*waitfor_write)(switch_core_session *, int);
switch_status (*send_dtmf)(switch_core_session *, char *);
}; };
/* /*

View File

@ -148,6 +148,7 @@ typedef struct switch_io_event_hook_write_frame switch_io_event_hook_write_frame
typedef struct switch_io_event_hook_kill_channel switch_io_event_hook_kill_channel; typedef struct switch_io_event_hook_kill_channel switch_io_event_hook_kill_channel;
typedef struct switch_io_event_hook_waitfor_read switch_io_event_hook_waitfor_read; typedef struct switch_io_event_hook_waitfor_read switch_io_event_hook_waitfor_read;
typedef struct switch_io_event_hook_waitfor_write switch_io_event_hook_waitfor_write; typedef struct switch_io_event_hook_waitfor_write switch_io_event_hook_waitfor_write;
typedef struct switch_io_event_hook_send_dtmf switch_io_event_hook_send_dtmf;
typedef struct switch_io_routines switch_io_routines; typedef struct switch_io_routines switch_io_routines;
typedef struct switch_io_event_hooks switch_io_event_hooks; typedef struct switch_io_event_hooks switch_io_event_hooks;
typedef struct switch_buffer switch_buffer; typedef struct switch_buffer switch_buffer;
@ -162,6 +163,7 @@ typedef switch_status (*switch_write_frame_hook)(switch_core_session *, switch_f
typedef switch_status (*switch_kill_channel_hook)(switch_core_session *, int); 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 *);
/* /*
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

View File

@ -353,9 +353,6 @@ static switch_status channel_write_frame(switch_core_session *session, switch_fr
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 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, "%s", s);
@ -591,6 +588,22 @@ static switch_status channel_waitfor_write(switch_core_session *session, int ms)
} }
static switch_status channel_send_dtmf(switch_core_session *session, char *dtmf)
{
struct private_object *tech_pvt = NULL;
char *digit;
tech_pvt = switch_core_session_get_private(session);
assert(tech_pvt != NULL);
if (tech_pvt->iax_session) {
for(digit = dtmf; *digit; digit++) {
iax_send_dtmf(tech_pvt->iax_session, *digit);
}
}
return SWITCH_STATUS_SUCCESS;
}
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)
{ {
switch_channel *channel = NULL; switch_channel *channel = NULL;
@ -674,7 +687,8 @@ static const switch_io_routines channel_io_routines = {
/*.write_frame*/ channel_write_frame, /*.write_frame*/ channel_write_frame,
/*.kill_channel*/ channel_kill_channel, /*.kill_channel*/ channel_kill_channel,
/*.waitfor_read*/ channel_waitfor_read, /*.waitfor_read*/ channel_waitfor_read,
/*.waitfor_write*/ channel_waitfor_write /*.waitfor_write*/ channel_waitfor_write,
/*.send_dtmf*/ channel_send_dtmf
}; };
static const switch_endpoint_interface channel_endpoint_interface = { static const switch_endpoint_interface channel_endpoint_interface = {
@ -938,6 +952,19 @@ SWITCH_MOD_DECLARE(switch_status) switch_module_runtime(void)
break; break;
case IAX_EVENT_REJECT: case IAX_EVENT_REJECT:
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Rejected call.\n"); switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Rejected call.\n");
break;
case IAX_EVENT_DTMF:
if ((tech_pvt = iax_get_private(iaxevent->session))) {
switch_channel *channel;
if ((channel = switch_core_session_get_channel(tech_pvt->session))) {
char str[2] = {iaxevent->subclass};
if (globals.debug) {
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "%s DTMF %s\n", str, switch_channel_get_name(channel));
}
switch_channel_queue_dtmf(channel, str);
}
}
break; break;
default: default:
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Don't know what to do with IAX event %d.\n", iaxevent->etype); switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Don't know what to do with IAX event %d.\n", iaxevent->etype);

View File

@ -43,6 +43,7 @@ void playback_function(switch_core_session *session, char *data)
switch_channel *channel; switch_channel *channel;
switch_file_t *fd; switch_file_t *fd;
char buf[960]; char buf[960];
char dtmf[128];
int interval = 0, samples = 0; int interval = 0, samples = 0;
size_t len = 0, ilen = 0; size_t len = 0, ilen = 0;
switch_frame write_frame; switch_frame write_frame;
@ -99,7 +100,25 @@ void playback_function(switch_core_session *session, char *data)
switch_core_service_session(session, &thread_session); switch_core_service_session(session, &thread_session);
ilen = len; ilen = len;
while(switch_channel_get_state(channel) == CS_EXECUTE) { while(switch_channel_get_state(channel) == CS_EXECUTE) {
if(switch_file_read(fd, buf, &ilen) != SWITCH_STATUS_SUCCESS) { int done = 0;
if (switch_channel_has_dtmf(channel)) {
switch_channel_dequeue_dtmf(channel, dtmf, sizeof(dtmf));
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "DTMF [%s]\n", dtmf);
switch (*dtmf) {
case '*':
done = 1;
break;
default:
break;
}
}
if (done) {
break;
}
if (switch_file_read(fd, buf, &ilen) != SWITCH_STATUS_SUCCESS) {
break; break;
} }

View File

@ -103,6 +103,7 @@ SWITCH_DECLARE(int) switch_buffer_read(switch_buffer *buffer, void *data, size_t
if (buffer->used < 1) { if (buffer->used < 1) {
buffer->used = 0;
return 0; return 0;
} else if (buffer->used >= datalen) { } else if (buffer->used >= datalen) {
reading = datalen; reading = datalen;
@ -112,7 +113,7 @@ SWITCH_DECLARE(int) switch_buffer_read(switch_buffer *buffer, void *data, size_t
memcpy(data, buffer->data, reading); memcpy(data, buffer->data, reading);
memmove(buffer->data, buffer->data + reading, buffer->datalen - reading); memmove(buffer->data, buffer->data + reading, buffer->datalen - reading);
buffer->used -= datalen; buffer->used -= reading;
//printf("o %d = %d\n", reading, buffer->used); //printf("o %d = %d\n", reading, buffer->used);
return (int)reading; return (int)reading;
} }

View File

@ -35,6 +35,7 @@ struct switch_channel {
time_t initiated; time_t initiated;
char *name; char *name;
switch_buffer *dtmf_buffer; switch_buffer *dtmf_buffer;
switch_mutex_t *dtmf_mutex;
switch_core_session *session; switch_core_session *session;
switch_channel_state state; switch_channel_state state;
switch_channel_flag flags; switch_channel_flag flags;
@ -63,7 +64,8 @@ SWITCH_DECLARE(switch_status) switch_channel_alloc(switch_channel **channel, swi
switch_core_hash_init(&(*channel)->variables, pool); switch_core_hash_init(&(*channel)->variables, pool);
switch_buffer_create(pool, &(*channel)->dtmf_buffer, 128); switch_buffer_create(pool, &(*channel)->dtmf_buffer, 128);
switch_mutex_init(&(*channel)->dtmf_mutex, SWITCH_MUTEX_NESTED, pool);
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
} }
@ -107,20 +109,31 @@ SWITCH_DECLARE(switch_status) switch_channel_get_raw_mode (switch_channel *chann
SWITCH_DECLARE(int) switch_channel_has_dtmf(switch_channel *channel) SWITCH_DECLARE(int) switch_channel_has_dtmf(switch_channel *channel)
{ {
int has;
assert(channel != NULL); assert(channel != NULL);
return switch_buffer_inuse(channel->dtmf_buffer); switch_mutex_lock(channel->dtmf_mutex);
has = switch_buffer_inuse(channel->dtmf_buffer);
switch_mutex_unlock(channel->dtmf_mutex);
return has;
} }
SWITCH_DECLARE(switch_status) switch_channel_queue_dtmf(switch_channel *channel, char *dtmf) SWITCH_DECLARE(switch_status) switch_channel_queue_dtmf(switch_channel *channel, char *dtmf)
{ {
switch_status status;
assert(channel != NULL); assert(channel != NULL);
switch_mutex_lock(channel->dtmf_mutex);
if (switch_buffer_inuse(channel->dtmf_buffer) + strlen(dtmf) > (size_t)switch_buffer_len(channel->dtmf_buffer)) { if (switch_buffer_inuse(channel->dtmf_buffer) + strlen(dtmf) > (size_t)switch_buffer_len(channel->dtmf_buffer)) {
switch_buffer_toss(channel->dtmf_buffer, strlen(dtmf)); switch_buffer_toss(channel->dtmf_buffer, strlen(dtmf));
} }
return switch_buffer_write(channel->dtmf_buffer, dtmf, strlen(dtmf));
status = switch_buffer_write(channel->dtmf_buffer, dtmf, strlen(dtmf));
switch_mutex_unlock(channel->dtmf_mutex);
return status;
} }
@ -129,9 +142,14 @@ SWITCH_DECLARE(int) switch_channel_dequeue_dtmf(switch_channel *channel, char *d
int bytes; int bytes;
assert(channel != NULL); assert(channel != NULL);
switch_mutex_lock(channel->dtmf_mutex);
if ((bytes = switch_buffer_read(channel->dtmf_buffer, dtmf, len)) > 0) { if ((bytes = switch_buffer_read(channel->dtmf_buffer, dtmf, len)) > 0) {
*(dtmf + bytes) = '\0'; *(dtmf + bytes) = '\0';
} }
switch_mutex_unlock(channel->dtmf_mutex);
return bytes; return bytes;
} }

View File

@ -816,6 +816,25 @@ SWITCH_DECLARE(switch_status) switch_core_session_waitfor_write(switch_core_sess
return status; return status;
} }
SWITCH_DECLARE(switch_status) switch_core_session_send_dtmf(switch_core_session *session, char *dtmf)
{
struct switch_io_event_hook_send_dtmf *ptr;
switch_status status = SWITCH_STATUS_FALSE;
if (session->endpoint_interface->io_routines->send_dtmf) {
if ((status = session->endpoint_interface->io_routines->send_dtmf(session, dtmf)) == SWITCH_STATUS_SUCCESS) {
for (ptr = session->event_hooks.send_dtmf; ptr ; ptr = ptr->next) {
if ((status = ptr->send_dtmf(session, dtmf)) != SWITCH_STATUS_SUCCESS) {
break;
}
}
}
}
return status;
}
SWITCH_DECLARE(switch_status) switch_core_session_add_event_hook_outgoing(switch_core_session *session, switch_outgoing_channel_hook outgoing_channel) SWITCH_DECLARE(switch_status) switch_core_session_add_event_hook_outgoing(switch_core_session *session, switch_outgoing_channel_hook outgoing_channel)
{ {
switch_io_event_hook_outgoing_channel *hook, *ptr; switch_io_event_hook_outgoing_channel *hook, *ptr;
@ -970,6 +989,29 @@ SWITCH_DECLARE(switch_status) switch_core_session_add_event_hook_waitfor_write(s
} }
SWITCH_DECLARE(switch_status) switch_core_session_add_event_hook_send_dtmf(switch_core_session *session, switch_send_dtmf_hook send_dtmf)
{
switch_io_event_hook_send_dtmf *hook, *ptr;
assert(send_dtmf != NULL);
if ((hook = switch_core_session_alloc(session, sizeof(*hook)))) {
hook->send_dtmf = send_dtmf;
if (!session->event_hooks.send_dtmf) {
session->event_hooks.send_dtmf = hook;
} else {
for(ptr = session->event_hooks.send_dtmf ; ptr && ptr->next; ptr = ptr->next);
ptr->next = hook;
}
return SWITCH_STATUS_SUCCESS;
}
return SWITCH_STATUS_MEMERR;
}
SWITCH_DECLARE(switch_status) switch_core_new_memory_pool(switch_memory_pool **pool) SWITCH_DECLARE(switch_status) switch_core_new_memory_pool(switch_memory_pool **pool)
{ {
assert(runtime.memory_pool != NULL); assert(runtime.memory_pool != NULL);