Merge remote branch 'fsorig/master'

This commit is contained in:
Moises Silva 2011-02-10 10:15:15 -05:00
commit 46215605f4
7 changed files with 94 additions and 37 deletions

View File

@ -25,7 +25,7 @@
<param name="colorize-console" value="true"/>
<!-- minimum idle CPU before refusing calls -->
<param name="min-idle-cpu" value="25"/>
<!--<param name="min-idle-cpu" value="25"/>-->
<!--
Max number of sessions to allow at any given time.

View File

@ -2743,10 +2743,9 @@ static ftdm_status_t ftdmchan_activate_dtmf_buffer(ftdm_channel_t *ftdmchan)
if (!ftdmchan->dtmf_buffer) {
if (ftdm_buffer_create(&ftdmchan->dtmf_buffer, 1024, 3192, 0) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_ERROR, "Failed to allocate DTMF Buffer!\n");
snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "buffer error");
return FTDM_FAIL;
} else {
ftdm_log(FTDM_LOG_DEBUG, "Created DTMF Buffer!\n");
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Created DTMF buffer\n");
}
}
@ -3588,8 +3587,17 @@ static FIO_READ_FUNCTION(ftdm_raw_read)
return status;
}
static ftdm_status_t handle_dtmf(ftdm_channel_t *ftdmchan, ftdm_size_t datalen)
/* This function takes care of automatically generating DTMF or FSK tones when needed */
static ftdm_status_t handle_tone_generation(ftdm_channel_t *ftdmchan, ftdm_size_t datalen)
{
/*
* datalen: size in bytes of the chunk of data the user requested to read (this function
* is called from the ftdm_channel_read function)
* dblen: size currently in use in any of the tone generation buffers (data available in the buffer)
* gen_dtmf_buffer: buffer holding the raw ASCII digits that the user requested to generate
* dtmf_buffer: raw linear tone data generated by teletone to be written to the devices
* fsk_buffer: raw linear FSK modulated data for caller id
*/
ftdm_buffer_t *buffer = NULL;
ftdm_size_t dblen = 0;
int wrote = 0;
@ -3604,7 +3612,7 @@ static ftdm_status_t handle_dtmf(ftdm_channel_t *ftdmchan, ftdm_size_t datalen)
}
if (ftdm_buffer_read(ftdmchan->gen_dtmf_buffer, digits, dblen) && !ftdm_strlen_zero_buf(digits)) {
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Generating DTMF [%s]\n", digits);
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Generating DTMF [%s]\n", digits);
cur = digits;
@ -3618,7 +3626,7 @@ static ftdm_status_t handle_dtmf(ftdm_channel_t *ftdmchan, ftdm_size_t datalen)
ftdm_buffer_write(ftdmchan->dtmf_buffer, ftdmchan->tone_session.buffer, wrote * 2);
x++;
} else {
ftdm_log(FTDM_LOG_ERROR, "%d:%d Problem Adding DTMF SEQ [%s]\n", ftdmchan->span_id, ftdmchan->chan_id, digits);
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Problem adding DTMF sequence [%s]\n", digits);
return FTDM_FAIL;
}
}
@ -3631,6 +3639,7 @@ static ftdm_status_t handle_dtmf(ftdm_channel_t *ftdmchan, ftdm_size_t datalen)
if (!ftdmchan->buffer_delay || --ftdmchan->buffer_delay == 0) {
/* time to pick a buffer, either the dtmf or fsk buffer */
if (ftdmchan->dtmf_buffer && (dblen = ftdm_buffer_inuse(ftdmchan->dtmf_buffer))) {
buffer = ftdmchan->dtmf_buffer;
} else if (ftdmchan->fsk_buffer && (dblen = ftdm_buffer_inuse(ftdmchan->fsk_buffer))) {
@ -3638,22 +3647,41 @@ static ftdm_status_t handle_dtmf(ftdm_channel_t *ftdmchan, ftdm_size_t datalen)
}
}
/* if we picked a buffer, time to read from it and write the linear data to the device */
if (buffer) {
ftdm_size_t dlen = datalen;
uint8_t auxbuf[1024];
/* we initialize dlen to datalen, which is the size in bytes the
* user wants to read (typically chunks of 160 bytes, 20ms G.711) */
ftdm_size_t dlen = datalen;
ftdm_size_t len, br, max = sizeof(auxbuf);
/* if the codec is not linear, then data is really twice as much cuz
tone generation is done in linear (we assume anything different than linear is G.711) */
if (ftdmchan->native_codec != FTDM_CODEC_SLIN) {
dlen *= 2;
}
/* we do not expect the user chunks to be bigger than auxbuf */
ftdm_assert(dlen <= sizeof(auxbuf), "Unexpected size for user data chunk size\n");
/* dblen is the size in use for dtmf_buffer or fsk_buffer, and dlen is the size
* of the read chunks of the user, we pick the smaller one */
len = dblen > dlen ? dlen : dblen;
/* we can't read more than the size of our auxiliary buffer */
ftdm_assert((len <= sizeof(auxbuf)), "Unexpected size to read into auxbuf\n");
br = ftdm_buffer_read(buffer, auxbuf, len);
/* the amount read can't possibly be bigger than what we requested */
ftdm_assert((br <= len), "Unexpected size read from tone generation buffer\n");
/* if we read less than the chunk size, we must fill in with silence the rest */
if (br < dlen) {
memset(auxbuf + br, 0, dlen - br);
}
/* finally we convert to the native format for the channel if necessary */
if (ftdmchan->native_codec != FTDM_CODEC_SLIN) {
if (ftdmchan->native_codec == FTDM_CODEC_ULAW) {
fio_slin2ulaw(auxbuf, max, &dlen);
@ -3662,6 +3690,7 @@ static ftdm_status_t handle_dtmf(ftdm_channel_t *ftdmchan, ftdm_size_t datalen)
}
}
/* write the tone to the channel */
return ftdm_raw_write(ftdmchan, auxbuf, &dlen);
}
@ -3741,7 +3770,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_read(ftdm_channel_t *ftdmchan, void *data
rdata[i] = ftdmchan->rxgain_table[rdata[i]];
}
}
handle_dtmf(ftdmchan, *datalen);
handle_tone_generation(ftdmchan, *datalen);
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_TRANSCODE) && ftdmchan->effective_codec != ftdmchan->native_codec) {
if (ftdmchan->native_codec == FTDM_CODEC_ULAW && ftdmchan->effective_codec == FTDM_CODEC_SLIN) {
@ -3938,7 +3967,8 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_write(ftdm_channel_t *ftdmchan, void *dat
if (!ftdmchan->buffer_delay &&
((ftdmchan->dtmf_buffer && ftdm_buffer_inuse(ftdmchan->dtmf_buffer)) ||
(ftdmchan->fsk_buffer && ftdm_buffer_inuse(ftdmchan->fsk_buffer)))) {
/* read size writing DTMF ATM */
/* generating some kind of tone at the moment (see handle_tone_generation),
* we ignore user data ... */
goto done;
}

View File

@ -401,13 +401,14 @@ static switch_status_t conference_outcall(conference_obj_t *conference,
char *bridgeto, uint32_t timeout,
char *flags,
char *cid_name,
char *cid_num,
char *cid_num,
char *profile,
switch_call_cause_t *cause,
switch_call_cause_t *cancel_cause);
static switch_status_t conference_outcall_bg(conference_obj_t *conference,
char *conference_name,
switch_core_session_t *session, char *bridgeto, uint32_t timeout, const char *flags, const char *cid_name,
const char *cid_num, const char *call_uuid, switch_call_cause_t *cancel_cause);
const char *cid_num, const char *call_uuid, const char *profile, switch_call_cause_t *cancel_cause);
SWITCH_STANDARD_APP(conference_function);
static void launch_conference_thread(conference_obj_t *conference);
static void launch_conference_video_thread(conference_obj_t *conference);
@ -2410,6 +2411,7 @@ static void conference_loop_output(conference_member_t *member)
const char *cid_num = switch_channel_get_variable(channel, "conference_auto_outcall_caller_id_number");
const char *toval = switch_channel_get_variable(channel, "conference_auto_outcall_timeout");
const char *flags = switch_channel_get_variable(channel, "conference_auto_outcall_flags");
const char *profile = switch_channel_get_variable(channel, "conference_auto_outcall_profile");
const char *ann = switch_channel_get_variable(channel, "conference_auto_outcall_announce");
const char *prefix = switch_channel_get_variable(channel, "conference_auto_outcall_prefix");
int to = 60;
@ -2441,7 +2443,7 @@ static void conference_loop_output(conference_member_t *member)
char *dial_str = switch_mprintf("%s%s", switch_str_nil(prefix), argv[x]);
switch_assert(dial_str);
conference_outcall_bg(member->conference, NULL, NULL, dial_str, to, switch_str_nil(flags), cid_name, cid_num, NULL,
&member->conference->cancel_cause);
profile, &member->conference->cancel_cause);
switch_safe_free(dial_str);
}
switch_safe_free(cpstr);
@ -4264,9 +4266,9 @@ static switch_status_t conf_api_sub_dial(conference_obj_t *conference, switch_st
}
if (conference) {
conference_outcall(conference, NULL, NULL, argv[2], 60, NULL, argv[4], argv[3], &cause, NULL);
conference_outcall(conference, NULL, NULL, argv[2], 60, NULL, argv[4], argv[3], NULL, &cause, NULL);
} else {
conference_outcall(NULL, argv[0], NULL, argv[2], 60, NULL, argv[4], argv[3], &cause, NULL);
conference_outcall(NULL, argv[0], NULL, argv[2], 60, NULL, argv[4], argv[3], NULL, &cause, NULL);
}
stream->write_function(stream, "Call Requested: result: [%s]\n", switch_channel_cause2str(cause));
@ -4289,9 +4291,9 @@ static switch_status_t conf_api_sub_bgdial(conference_obj_t *conference, switch_
switch_uuid_format(uuid_str, &uuid);
if (conference) {
conference_outcall_bg(conference, NULL, NULL, argv[2], 60, NULL, argv[4], argv[3], uuid_str, NULL);
conference_outcall_bg(conference, NULL, NULL, argv[2], 60, NULL, argv[4], argv[3], uuid_str, NULL, NULL);
} else {
conference_outcall_bg(NULL, argv[0], NULL, argv[2], 60, NULL, argv[4], argv[3], uuid_str, NULL);
conference_outcall_bg(NULL, argv[0], NULL, argv[2], 60, NULL, argv[4], argv[3], uuid_str, NULL, NULL);
}
stream->write_function(stream, "OK Job-UUID: %s\n", uuid_str);
@ -4807,7 +4809,8 @@ static switch_status_t conference_outcall(conference_obj_t *conference,
switch_core_session_t *session,
char *bridgeto, uint32_t timeout,
char *flags, char *cid_name,
char *cid_num,
char *cid_num,
char *profile,
switch_call_cause_t *cause,
switch_call_cause_t *cancel_cause)
{
@ -4817,6 +4820,7 @@ static switch_status_t conference_outcall(conference_obj_t *conference,
switch_channel_t *caller_channel = NULL;
char appdata[512];
int rdlock = 0;
switch_bool_t have_flags = SWITCH_FALSE;
*cause = SWITCH_CAUSE_NORMAL_CLEARING;
@ -4902,13 +4906,16 @@ static switch_status_t conference_outcall(conference_obj_t *conference,
status = SWITCH_STATUS_MEMERR;
goto done;
}
/* add them to the conference */
if (flags && strcasecmp(flags, "none")) {
switch_snprintf(appdata, sizeof(appdata), "%s+flags{%s}", conference_name, flags);
switch_caller_extension_add_application(peer_session, extension, (char *) global_app_name, appdata);
} else {
switch_caller_extension_add_application(peer_session, extension, (char *) global_app_name, conference_name);
have_flags = SWITCH_TRUE;
}
/* add them to the conference */
switch_snprintf(appdata, sizeof(appdata), "%s%s%s%s%s%s", conference_name,
profile?"@":"", profile?profile:"",
have_flags?"+flags{":"", have_flags?flags:"", have_flags?"}":"");
switch_caller_extension_add_application(peer_session, extension, (char *) global_app_name, appdata);
switch_channel_set_caller_extension(peer_channel, extension);
switch_channel_set_state(peer_channel, CS_EXECUTE);
@ -4940,6 +4947,7 @@ struct bg_call {
char *cid_num;
char *conference_name;
char *uuid;
char *profile;
switch_call_cause_t *cancel_cause;
switch_memory_pool_t *pool;
};
@ -4953,7 +4961,7 @@ static void *SWITCH_THREAD_FUNC conference_outcall_run(switch_thread_t *thread,
switch_event_t *event;
conference_outcall(call->conference, call->conference_name,
call->session, call->bridgeto, call->timeout, call->flags, call->cid_name, call->cid_num, &cause, call->cancel_cause);
call->session, call->bridgeto, call->timeout, call->flags, call->cid_name, call->cid_num, call->profile, &cause, call->cancel_cause);
if (call->conference && test_eflag(call->conference, EFLAG_BGDIAL_RESULT) &&
switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
@ -4969,6 +4977,7 @@ static void *SWITCH_THREAD_FUNC conference_outcall_run(switch_thread_t *thread,
switch_safe_free(call->cid_num);
switch_safe_free(call->conference_name);
switch_safe_free(call->uuid);
switch_safe_free(call->profile);
if (call->pool) {
switch_core_destroy_memory_pool(&call->pool);
}
@ -4981,7 +4990,7 @@ static void *SWITCH_THREAD_FUNC conference_outcall_run(switch_thread_t *thread,
static switch_status_t conference_outcall_bg(conference_obj_t *conference,
char *conference_name,
switch_core_session_t *session, char *bridgeto, uint32_t timeout, const char *flags, const char *cid_name,
const char *cid_num, const char *call_uuid, switch_call_cause_t *cancel_cause)
const char *cid_num, const char *call_uuid, const char *profile, switch_call_cause_t *cancel_cause)
{
struct bg_call *call = NULL;
switch_thread_t *thread;
@ -5025,6 +5034,10 @@ static switch_status_t conference_outcall_bg(conference_obj_t *conference,
call->uuid = strdup(call_uuid);
}
if (profile) {
call->profile = strdup(profile);
}
switch_threadattr_create(&thd_attr, pool);
switch_threadattr_detach_set(thd_attr, 1);
switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
@ -5750,7 +5763,7 @@ SWITCH_STANDARD_APP(conference_function)
/* if we're using "bridge:" make an outbound call and bridge it in */
if (!zstr(bridgeto) && strcasecmp(bridgeto, "none")) {
switch_call_cause_t cause;
if (conference_outcall(conference, NULL, session, bridgeto, 60, NULL, NULL, NULL, &cause, NULL) != SWITCH_STATUS_SUCCESS) {
if (conference_outcall(conference, NULL, session, bridgeto, 60, NULL, NULL, NULL, NULL, &cause, NULL) != SWITCH_STATUS_SUCCESS) {
goto done;
}
} else {

View File

@ -1864,6 +1864,7 @@ SWITCH_STANDARD_APP(att_xfer_function)
if (switch_ivr_originate(session, &peer_session, &cause, data, 0, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL)
!= SWITCH_STATUS_SUCCESS || !peer_session) {
switch_channel_set_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE, bond);
goto end;
}
@ -1878,6 +1879,7 @@ SWITCH_STANDARD_APP(att_xfer_function)
if (zstr(bond) && switch_channel_down(peer_channel)) {
switch_core_session_rwunlock(peer_session);
switch_channel_set_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE, bond);
goto end;
}

View File

@ -1011,6 +1011,11 @@ typedef struct msg_cnt_callback msg_cnt_callback_t;
static int message_count_callback(void *pArg, int argc, char **argv, char **columnNames)
{
msg_cnt_callback_t *cbt = (msg_cnt_callback_t *) pArg;
if (argc < 3 || zstr(argv[0]) || zstr(argv[1]) || zstr(argv[2])) {
return -1;
}
if (atoi(argv[0]) == 1) { /* UnRead */
if (!strcasecmp(argv[1], "A_URGENT")) { /* Urgent */
cbt->total_new_urgent_messages = atoi(argv[2]);
@ -1263,7 +1268,7 @@ static void message_count(vm_profile_t *profile, const char *id_in, const char *
{
char msg_count[80] = "";
msg_cnt_callback_t cbt = { 0 };
char sql[256];
char *sql;
char *myid = NULL;
@ -1277,15 +1282,20 @@ static void message_count(vm_profile_t *profile, const char *id_in, const char *
myid = resolve_id(id_in, domain_name, "message-count");
switch_snprintf(sql, sizeof(sql), "select 1, read_flags, count(read_epoch) from voicemail_msgs where "
"username='%s' and domain='%s' and in_folder='%s' "
"and read_epoch=0 group by read_flags union select 0, read_flags, count(read_epoch) from voicemail_msgs where username='%s' "
"and domain='%s' and in_folder='%s' and read_epoch<>0 group by read_flags;",
myid, domain_name, myfolder, myid, domain_name, myfolder);
sql = switch_mprintf(
"select 1, read_flags, count(read_epoch) from voicemail_msgs where "
"username='%q' and domain='%q' and in_folder='%q' and read_epoch=0 "
"group by read_flags "
"union "
"select 0, read_flags, count(read_epoch) from voicemail_msgs where "
"username='%q' and domain='%q' and in_folder='%q' and read_epoch<>0 "
"group by read_flags;",
myid, domain_name, myfolder,
myid, domain_name, myfolder);
vm_execute_sql_callback(profile, profile->mutex, sql, message_count_callback, &cbt);
free(sql);
*total_new_messages = cbt.total_new_messages + cbt.total_new_urgent_messages;
*total_new_urgent_messages = cbt.total_new_urgent_messages;

View File

@ -1363,7 +1363,7 @@ static switch_status_t speech_channel_stop(speech_channel_t *schannel)
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "(%s) %s stopped\n", schannel->name, speech_channel_type_to_string(schannel->type));
} else if (schannel->state == SPEECH_CHANNEL_DONE) {
speech_channel_set_state(schannel, SPEECH_CHANNEL_READY);
speech_channel_set_state_unlocked(schannel, SPEECH_CHANNEL_READY);
}
done:

View File

@ -3458,7 +3458,7 @@ SWITCH_STANDARD_API(sofia_contact_function)
{
char *data;
char *user = NULL;
char *domain = NULL;
char *domain = NULL, *dup_domain = NULL;
char *concat = NULL;
char *profile_name = NULL;
char *p;
@ -3501,7 +3501,8 @@ SWITCH_STANDARD_API(sofia_contact_function)
}
if (zstr(domain)) {
domain = switch_core_get_variable_pdup("domain", switch_core_session_get_pool(session));
dup_domain = switch_core_get_variable_dup("domain");
domain = dup_domain;
}
if (!user) goto end;
@ -3567,6 +3568,7 @@ SWITCH_STANDARD_API(sofia_contact_function)
switch_safe_free(mystream.data);
switch_safe_free(data);
switch_safe_free(dup_domain);
return SWITCH_STATUS_SUCCESS;
}