mirror of
https://github.com/signalwire/freeswitch.git
synced 2026-07-23 12:42:02 +00:00
improve voicemail
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@6399 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
@@ -158,6 +158,7 @@ struct switch_media_bug {
|
||||
struct switch_runtime {
|
||||
switch_time_t initiated;
|
||||
switch_hash_t *global_vars;
|
||||
switch_hash_t *mime_types;
|
||||
switch_memory_pool_t *memory_pool;
|
||||
const switch_state_handler_table_t *state_handlers[SWITCH_MAX_STATE_HANDLERS];
|
||||
int state_handler_index;
|
||||
|
||||
@@ -1494,6 +1494,9 @@ SWITCH_DECLARE(void) switch_core_set_globals(void);
|
||||
SWITCH_DECLARE(uint8_t) switch_core_session_compare(switch_core_session_t *a, switch_core_session_t *b);
|
||||
|
||||
|
||||
SWITCH_DECLARE(const char *) switch_core_mime_ext2type(const char *ext);
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_mime_add_type(const char *type, const char *ext);
|
||||
|
||||
SWITCH_DECLARE(switch_loadable_module_interface_t *) switch_loadable_module_create_module_interface(switch_memory_pool_t *pool, const char *name);
|
||||
SWITCH_DECLARE(void *) switch_loadable_module_create_interface(switch_loadable_module_interface_t *mod, switch_module_interface_name_t iname);
|
||||
SWITCH_DECLARE(switch_time_t) switch_timestamp_now(void);
|
||||
|
||||
@@ -69,6 +69,8 @@ static inline switch_bool_t switch_is_digit_string(const char *s) {
|
||||
return SWITCH_TRUE;
|
||||
}
|
||||
|
||||
switch_size_t switch_fd_read_line(int fd, char *buf, switch_size_t len);
|
||||
|
||||
/*!
|
||||
\brief Evaluate the truthfullness of a string expression
|
||||
\param expr a string expression
|
||||
|
||||
@@ -95,6 +95,7 @@ struct vm_profile {
|
||||
switch_mutex_t *mutex;
|
||||
uint32_t record_threshold;
|
||||
uint32_t record_silence_hits;
|
||||
uint32_t record_sample_rate;
|
||||
#ifdef SWITCH_HAVE_ODBC
|
||||
switch_odbc_handle_t *master_odbc;
|
||||
#else
|
||||
@@ -208,8 +209,8 @@ static switch_bool_t vm_execute_sql_callback(vm_profile_t *profile,
|
||||
|
||||
static char vm_sql[] =
|
||||
"CREATE TABLE voicemail_data (\n"
|
||||
" created_epoch INTEGER(8),\n"
|
||||
" read_epoch INTEGER(8),\n"
|
||||
" created_epoch INTEGER,\n"
|
||||
" read_epoch INTEGER,\n"
|
||||
" user VARCHAR(255),\n"
|
||||
" domain VARCHAR(255),\n"
|
||||
" uuid VARCHAR(255),\n"
|
||||
@@ -217,6 +218,7 @@ static char vm_sql[] =
|
||||
" cid_number VARCHAR(255),\n"
|
||||
" in_folder VARCHAR(255),\n"
|
||||
" file_path VARCHAR(255),\n"
|
||||
" message_len INTEGER,\n"
|
||||
" flags VARCHAR(255),\n"
|
||||
" read_flags VARCHAR(255)\n"
|
||||
");\n";
|
||||
@@ -301,6 +303,7 @@ static switch_status_t load_config(void)
|
||||
char *date_fmt = "%A, %B %d %Y, %I %M %p";
|
||||
uint32_t record_threshold = 200;
|
||||
uint32_t record_silence_hits = 2;
|
||||
uint32_t record_sample_rate = 0;
|
||||
|
||||
switch_core_db_t *db;
|
||||
uint32_t timeout = 10000, max_login_attempts = 3, max_record_len = 300;
|
||||
@@ -398,6 +401,16 @@ static switch_status_t load_config(void)
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "invalid threshold value [%s] must be between 0 and 10000 ms\n", val);
|
||||
}
|
||||
} else if (!strcasecmp(var, "record-sample-rate")) {
|
||||
int tmp = 0;
|
||||
if (!switch_strlen_zero(val)) {
|
||||
tmp = atoi(val);
|
||||
}
|
||||
if (tmp == 8000 || tmp == 16000 || tmp == 32000 || tmp == 11025 || tmp == 22050 || tmp == 44100) {
|
||||
record_sample_rate = tmp;
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "invalid samplerate %s\n", val);
|
||||
}
|
||||
} else if (!strcasecmp(var, "record-silence-hits")) {
|
||||
int tmp = 0;
|
||||
if (!switch_strlen_zero(val)) {
|
||||
@@ -481,13 +494,20 @@ static switch_status_t load_config(void)
|
||||
}
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Connected ODBC DSN: %s\n", profile->odbc_dsn);
|
||||
switch_odbc_handle_exec(profile->master_odbc, vm_sql, NULL);
|
||||
switch_odbc_handle_exec(profile->master_odbc, vm_pref_sql, NULL);
|
||||
if (switch_odbc_handle_exec(profile->master_odbc, "select count(message_len) from voicemail_data", NULL) != SWITCH_ODBC_SUCCESS) {
|
||||
switch_odbc_handle_exec(profile->master_odbc, "drop table voicemail_data", NULL);
|
||||
switch_odbc_handle_exec(profile->master_odbc, vm_sql, NULL);
|
||||
}
|
||||
|
||||
if (switch_odbc_handle_exec(profile->master_odbc, "select count(user) from voicemail_prefs", NULL) != SWITCH_ODBC_SUCCESS) {
|
||||
switch_odbc_handle_exec(profile->master_odbc, "drop table voicemail_data", NULL);
|
||||
switch_odbc_handle_exec(profile->master_odbc, vm_pref_sql, NULL);
|
||||
}
|
||||
} else {
|
||||
#endif
|
||||
if ((db = switch_core_db_open_file(profile->dbname))) {
|
||||
switch_core_db_test_reactive(db, "select * from voicemail_data", NULL, vm_sql);
|
||||
switch_core_db_test_reactive(db, "select * from voicemail_prefs", NULL, vm_pref_sql);
|
||||
switch_core_db_test_reactive(db, "select count(message_len) from voicemail_data", "drop table voicemail_data", vm_sql);
|
||||
switch_core_db_test_reactive(db, "select count(user) from voicemail_prefs", "drop table voicemail_data", vm_pref_sql);
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot Open SQL Database!\n");
|
||||
continue;
|
||||
@@ -527,6 +547,7 @@ static switch_status_t load_config(void)
|
||||
*profile->operator_key = *operator_key;
|
||||
profile->record_threshold = record_threshold;
|
||||
profile->record_silence_hits = record_silence_hits;
|
||||
profile->record_sample_rate = record_sample_rate;
|
||||
|
||||
profile->operator_ext = switch_core_strdup(globals.pool, operator_ext);
|
||||
profile->storage_dir = switch_core_strdup(globals.pool, storage_dir);
|
||||
@@ -783,7 +804,7 @@ typedef enum {
|
||||
static uint32_t DEFAULT_DIR_PERMS = SWITCH_FPROT_UREAD | SWITCH_FPROT_UWRITE | SWITCH_FPROT_UEXECUTE | SWITCH_FPROT_GREAD | SWITCH_FPROT_GEXECUTE;
|
||||
|
||||
|
||||
static switch_status_t create_file(switch_core_session_t *session, vm_profile_t *profile, char *macro_name, char *file_path)
|
||||
static switch_status_t create_file(switch_core_session_t *session, vm_profile_t *profile, char *macro_name, char *file_path, uint32_t *message_len)
|
||||
{
|
||||
switch_channel_t *channel;
|
||||
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
||||
@@ -792,19 +813,13 @@ static switch_status_t create_file(switch_core_session_t *session, vm_profile_t
|
||||
char term;
|
||||
char input[10] = "" , key_buf[80] = "";
|
||||
cc_t cc = { 0 };
|
||||
|
||||
switch_codec_t *read_codec;
|
||||
channel = switch_core_session_get_channel(session);
|
||||
assert(channel != NULL);
|
||||
|
||||
read_codec = switch_core_session_get_read_codec(session);
|
||||
|
||||
while(switch_channel_ready(channel)) {
|
||||
|
||||
|
||||
switch_channel_set_variable(channel, "RECORD_COMMENT", macro_name);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
snprintf(key_buf, sizeof(key_buf), "%s:%s:%s",
|
||||
profile->listen_file_key,
|
||||
@@ -820,9 +835,9 @@ static switch_status_t create_file(switch_core_session_t *session, vm_profile_t
|
||||
memset(&fh, 0, sizeof(fh));
|
||||
fh.thresh = profile->record_threshold;
|
||||
fh.silence_hits = profile->record_silence_hits;
|
||||
|
||||
|
||||
fh.samplerate = profile->record_sample_rate;
|
||||
switch_ivr_record_file(session, &fh, file_path, &args, profile->max_record_len);
|
||||
*message_len = fh.sample_count / read_codec->implementation->actual_samples_per_second;
|
||||
status = SWITCH_STATUS_SUCCESS;
|
||||
|
||||
play_file:
|
||||
@@ -873,6 +888,7 @@ struct listen_callback {
|
||||
char cid_number[255];
|
||||
char in_folder[255];
|
||||
char file_path[255];
|
||||
char message_len[255];
|
||||
char flags[255];
|
||||
char read_flags[255];
|
||||
char *email;
|
||||
@@ -899,8 +915,9 @@ static int listen_callback(void *pArg, int argc, char **argv, char **columnNames
|
||||
switch_copy_string(cbt->cid_number, argv[6], 255);
|
||||
switch_copy_string(cbt->in_folder, argv[7], 255);
|
||||
switch_copy_string(cbt->file_path, argv[8], 255);
|
||||
switch_copy_string(cbt->flags, argv[9], 255);
|
||||
switch_copy_string(cbt->read_flags, argv[10], 255);
|
||||
switch_copy_string(cbt->message_len, argv[9], 255);
|
||||
switch_copy_string(cbt->flags, argv[10], 255);
|
||||
switch_copy_string(cbt->read_flags, argv[11], 255);
|
||||
|
||||
|
||||
return -1;
|
||||
@@ -1024,7 +1041,7 @@ static switch_status_t listen_file(switch_core_session_t *session, vm_profile_t
|
||||
if (!strcmp(input, profile->email_key) && !switch_strlen_zero(cbt->email)) {
|
||||
switch_event_t *event;
|
||||
char *from;
|
||||
char *headers;
|
||||
char *headers, *header_string;
|
||||
char *body;
|
||||
int priority = 3;
|
||||
switch_size_t retsize;
|
||||
@@ -1035,12 +1052,14 @@ static switch_status_t listen_file(switch_core_session_t *session, vm_profile_t
|
||||
int total_saved_messages = 0;
|
||||
int total_new_urgent_messages = 0;
|
||||
int total_saved_urgent_messages = 0;
|
||||
|
||||
int32_t message_len = 0;
|
||||
char *p;
|
||||
|
||||
if (!strcasecmp(cbt->read_flags, URGENT_FLAG_STRING)) {
|
||||
priority = 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
message_count(profile, cbt->user, cbt->domain, cbt->in_folder, &total_new_messages, &total_saved_messages,
|
||||
&total_new_urgent_messages, &total_saved_urgent_messages);
|
||||
|
||||
@@ -1065,8 +1084,10 @@ static switch_status_t listen_file(switch_core_session_t *session, vm_profile_t
|
||||
switch_channel_set_variable(channel, "voicemail_time", date);
|
||||
snprintf(tmp,sizeof(tmp), "%d", priority);
|
||||
switch_channel_set_variable(channel, "voicemail_priority", tmp);
|
||||
|
||||
|
||||
message_len = atoi(cbt->message_len);
|
||||
switch_channel_set_variable(channel, "voicemail_message_len", cbt->message_len);
|
||||
switch_channel_set_variable(channel, "voicemail_email", cbt->email);
|
||||
|
||||
if(switch_strlen_zero(profile->email_headers)) {
|
||||
from = switch_core_session_sprintf(session, "%s@%s", cbt->user, cbt->domain);
|
||||
} else {
|
||||
@@ -1081,6 +1102,15 @@ static switch_status_t listen_file(switch_core_session_t *session, vm_profile_t
|
||||
headers = switch_channel_expand_variables(channel,profile->email_headers);
|
||||
}
|
||||
|
||||
p = headers + (strlen(headers) - 1);
|
||||
if (*p == '\n') {
|
||||
if (*(p-1) == '\r') {
|
||||
p--;
|
||||
}
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
header_string = switch_core_session_sprintf(session, "%s\nX-Voicemail-Length: %u", headers, message_len);
|
||||
|
||||
if (switch_event_create(&event, SWITCH_EVENT_MESSAGE) == SWITCH_STATUS_SUCCESS) {
|
||||
/* this isnt done? it was in the other place
|
||||
@@ -1097,7 +1127,7 @@ static switch_status_t listen_file(switch_core_session_t *session, vm_profile_t
|
||||
body = switch_channel_expand_variables(channel,profile->email_body);
|
||||
}
|
||||
|
||||
switch_simple_email(cbt->email, from, headers, body, cbt->file_path);
|
||||
switch_simple_email(cbt->email, from, header_string, body, cbt->file_path);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Sending message to %s\n", cbt->email);
|
||||
switch_safe_free(body);
|
||||
TRY_CODE(switch_ivr_phrase_macro(session, VM_ACK_MACRO, "emailed", NULL, NULL));
|
||||
@@ -1295,6 +1325,8 @@ static void voicemail_check_main(switch_core_session_t *session, const char *pro
|
||||
callback_t cbt = { 0 };
|
||||
char msg_count[80] = "";
|
||||
cc_t cc = { 0 };
|
||||
uint32_t message_len = 0;
|
||||
|
||||
cbt.buf = msg_count;
|
||||
cbt.len = sizeof(msg_count);
|
||||
sql = switch_mprintf("select count(*) from voicemail_prefs where user='%q' and domain = '%q'", myid, domain_name);
|
||||
@@ -1362,7 +1394,7 @@ static void voicemail_check_main(switch_core_session_t *session, const char *pro
|
||||
TRY_CODE(switch_ivr_phrase_macro(session, VM_CHOOSE_GREETING_FAIL_MACRO, NULL, NULL, NULL));
|
||||
} else {
|
||||
file_path = switch_mprintf("%s%sgreeting_%d.%s", dir_path, SWITCH_PATH_SEPARATOR, num, profile->file_ext);
|
||||
TRY_CODE(create_file(session, profile, VM_RECORD_GREETING_MACRO, file_path));
|
||||
TRY_CODE(create_file(session, profile, VM_RECORD_GREETING_MACRO, file_path, &message_len));
|
||||
sql = switch_mprintf("update voicemail_prefs set greeting_path='%s' where user='%s' and domain='%s'", file_path, myid, domain_name);
|
||||
vm_execute_sql(profile, sql, profile->mutex);
|
||||
switch_safe_free(sql);
|
||||
@@ -1371,7 +1403,7 @@ static void voicemail_check_main(switch_core_session_t *session, const char *pro
|
||||
|
||||
} else if (!strcmp(input, profile->record_name_key)) {
|
||||
file_path = switch_mprintf("%s%srecorded_name.%s", dir_path, SWITCH_PATH_SEPARATOR, profile->file_ext);
|
||||
TRY_CODE(create_file(session, profile, VM_RECORD_NAME_MACRO, file_path));
|
||||
TRY_CODE(create_file(session, profile, VM_RECORD_NAME_MACRO, file_path, &message_len));
|
||||
sql = switch_mprintf("update voicemail_prefs set name_path='%s' where user='%s' and domain='%s'", file_path, myid, domain_name);
|
||||
vm_execute_sql(profile, sql, profile->mutex);
|
||||
switch_safe_free(file_path);
|
||||
@@ -1585,6 +1617,12 @@ static switch_status_t voicemail_leave_main(switch_core_session_t *session, cons
|
||||
char buf[2];
|
||||
char *greet_path = NULL;
|
||||
const char *voicemail_greeting_number = NULL;
|
||||
uint32_t message_len = 0;
|
||||
switch_time_exp_t tm;
|
||||
char date[80] = "";
|
||||
switch_size_t retsize;
|
||||
switch_time_t ts = switch_timestamp_now();
|
||||
char *dbuf = NULL;
|
||||
|
||||
memset(&cbt, 0, sizeof(cbt));
|
||||
if (!(profile = switch_core_hash_find(globals.profile_hash, profile_name))) {
|
||||
@@ -1732,8 +1770,19 @@ static switch_status_t voicemail_leave_main(switch_core_session_t *session, cons
|
||||
cc.noexit = 1;
|
||||
args.buf = &cc;
|
||||
|
||||
dbuf = switch_mprintf("%s (%s)", caller_profile->caller_id_name, caller_profile->caller_id_number);
|
||||
switch_channel_set_variable(channel, "RECORD_ARTIST", dbuf);
|
||||
free(dbuf);
|
||||
|
||||
status = create_file(session, profile, VM_RECORD_MESSAGE_MACRO, file_path);
|
||||
switch_time_exp_lt(&tm, ts);
|
||||
switch_strftime(date, &retsize, sizeof(date), "%Y-%m-%d %T", &tm);
|
||||
switch_channel_set_variable(channel, "RECORD_DATE", date);
|
||||
switch_channel_set_variable(channel, "RECORD_SOFTWARE", "FreeSWITCH");
|
||||
switch_channel_set_variable(channel, "RECORD_TITLE", "FreeSWITCH Voicemail");
|
||||
switch_channel_set_variable(channel, "RECORD_COMMENT", "FreeSWITCH Voicemail");
|
||||
switch_channel_set_variable(channel, "RECORD_COPYRIGHT", "http://www.freeswitch.org");
|
||||
|
||||
status = create_file(session, profile, VM_RECORD_MESSAGE_MACRO, file_path, &message_len);
|
||||
|
||||
if ((status == SWITCH_STATUS_SUCCESS || status == SWITCH_STATUS_BREAK) && switch_channel_ready(channel)) {
|
||||
char input[10] = "", key_buf[80] = "", term = 0;
|
||||
@@ -1761,8 +1810,9 @@ static switch_status_t voicemail_leave_main(switch_core_session_t *session, cons
|
||||
int total_new_urgent_messages = 0;
|
||||
int total_saved_urgent_messages = 0;
|
||||
|
||||
usql = switch_mprintf("insert into voicemail_data values(%ld,0,'%q','%q','%q','%q','%q','%q','%q','','%q')", (long)time(NULL),
|
||||
id, domain_name, uuid, caller_profile->caller_id_name, caller_profile->caller_id_number, myfolder, file_path, read_flags);
|
||||
usql = switch_mprintf("insert into voicemail_data values(%ld,0,'%q','%q','%q','%q','%q','%q','%q','%u','','%q')", (long)time(NULL),
|
||||
id, domain_name, uuid, caller_profile->caller_id_name, caller_profile->caller_id_number,
|
||||
myfolder, file_path, message_len, read_flags);
|
||||
vm_execute_sql(profile, usql, profile->mutex);
|
||||
switch_safe_free(usql);
|
||||
|
||||
@@ -1788,6 +1838,7 @@ static switch_status_t voicemail_leave_main(switch_core_session_t *session, cons
|
||||
char *from;
|
||||
char *body;
|
||||
char *headers;
|
||||
char *header_string;
|
||||
switch_size_t retsize;
|
||||
switch_time_exp_t tm;
|
||||
char date[80] = "";
|
||||
@@ -1796,7 +1847,8 @@ static switch_status_t voicemail_leave_main(switch_core_session_t *session, cons
|
||||
int total_saved_messages = 0;
|
||||
int total_new_urgent_messages = 0;
|
||||
int total_saved_urgent_messages = 0;
|
||||
|
||||
char *p;
|
||||
|
||||
message_count(profile, id, domain_name, myfolder, &total_new_messages, &total_saved_messages,
|
||||
&total_new_urgent_messages, &total_saved_urgent_messages);
|
||||
|
||||
@@ -1821,25 +1873,39 @@ static switch_status_t voicemail_leave_main(switch_core_session_t *session, cons
|
||||
switch_channel_set_variable(channel, "voicemail_time", date);
|
||||
snprintf(tmp,sizeof(tmp), "%d", priority);
|
||||
switch_channel_set_variable(channel, "voicemail_priority", tmp);
|
||||
switch_channel_set_variable(channel, "voicemail_email", email_vm);
|
||||
|
||||
snprintf(tmp,sizeof(tmp), "%d", message_len);
|
||||
switch_channel_set_variable(channel, "voicemail_message_len", tmp);
|
||||
|
||||
if(switch_strlen_zero(profile->email_from)) {
|
||||
if (switch_strlen_zero(profile->email_from)) {
|
||||
from = switch_core_session_sprintf(session, "%s@%s", id, domain_name);
|
||||
} else {
|
||||
from = switch_channel_expand_variables(channel, profile->email_headers);
|
||||
}
|
||||
|
||||
if(switch_strlen_zero(profile->email_headers)) {
|
||||
headers = switch_core_session_sprintf(session, "From: FreeSWITCH mod_voicemail <%s@%s>\nSubject: Voicemail from %s %s\nX-Priority: %d",
|
||||
if (switch_strlen_zero(profile->email_headers)) {
|
||||
headers = switch_core_session_sprintf(session,
|
||||
"From: FreeSWITCH mod_voicemail <%s@%s>\n"
|
||||
"Subject: Voicemail from %s %s\nX-Priority: %d",
|
||||
id, domain_name,
|
||||
caller_profile->caller_id_name,
|
||||
caller_profile->caller_id_number,
|
||||
priority);
|
||||
} else {
|
||||
headers = switch_channel_expand_variables(channel,profile->email_headers);
|
||||
headers = switch_channel_expand_variables(channel, profile->email_headers);
|
||||
}
|
||||
|
||||
p = headers + (strlen(headers) - 1);
|
||||
|
||||
if (*p == '\n') {
|
||||
if (*(p-1) == '\r') {
|
||||
p--;
|
||||
}
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
header_string = switch_core_session_sprintf(session, "%s\nX-Voicemail-Length: %u", headers, message_len);
|
||||
|
||||
|
||||
if (switch_event_create(&event, SWITCH_EVENT_MESSAGE) == SWITCH_STATUS_SUCCESS) {
|
||||
@@ -1847,22 +1913,22 @@ static switch_status_t voicemail_leave_main(switch_core_session_t *session, cons
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Message-Type", "voicemail");
|
||||
switch_event_fire(&event);
|
||||
}
|
||||
if(!switch_strlen_zero(profile->email_headers)) {
|
||||
if (!switch_strlen_zero(profile->email_headers)) {
|
||||
body = switch_mprintf("Voicemail from %s %s",
|
||||
caller_profile->caller_id_name, caller_profile->caller_id_number);
|
||||
} else {
|
||||
body = switch_channel_expand_variables(channel,profile->email_body);
|
||||
}
|
||||
|
||||
if(email_attach) {
|
||||
switch_simple_email(email_vm, from, headers, body, file_path);
|
||||
if (email_attach) {
|
||||
switch_simple_email(email_vm, from, header_string, body, file_path);
|
||||
} else {
|
||||
switch_simple_email(email_vm, from, headers, body, NULL);
|
||||
switch_simple_email(email_vm, from, header_string, body, NULL);
|
||||
}
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Sending message to %s\n", email_vm);
|
||||
switch_safe_free(body);
|
||||
if(email_delete) {
|
||||
if (email_delete) {
|
||||
unlink(file_path);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -237,6 +237,7 @@ static switch_status_t local_stream_file_read(switch_file_handle_t *handle, void
|
||||
*len = need / 2;
|
||||
}
|
||||
switch_mutex_unlock(context->audio_mutex);
|
||||
handle->sample_count += *len;
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -65,6 +65,7 @@ struct shout_context {
|
||||
uint8_t thread_running;
|
||||
uint8_t shout_init;
|
||||
uint32_t prebuf;
|
||||
int lame_ready;
|
||||
};
|
||||
|
||||
typedef struct shout_context shout_context_t;
|
||||
@@ -91,6 +92,7 @@ static inline void free_context(shout_context_t * context)
|
||||
}
|
||||
|
||||
lame_mp3_tags_fid(context->gfp, context->fp);
|
||||
|
||||
fclose(context->fp);
|
||||
context->fp = NULL;
|
||||
}
|
||||
@@ -576,19 +578,23 @@ static switch_status_t shout_file_open(switch_file_handle_t *handle, const char
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!handle->handler) {
|
||||
id3tag_init(context->gfp);
|
||||
id3tag_v2_only(context->gfp);
|
||||
id3tag_pad_v2(context->gfp);
|
||||
|
||||
}
|
||||
|
||||
lame_set_num_channels(context->gfp, handle->channels);
|
||||
lame_set_in_samplerate(context->gfp, handle->samplerate);
|
||||
lame_set_brate(context->gfp, 64);
|
||||
lame_set_brate(context->gfp, 24);
|
||||
lame_set_mode(context->gfp, 3);
|
||||
lame_set_quality(context->gfp, 2); /* 2=high 5 = medium 7=low */
|
||||
|
||||
|
||||
lame_set_errorf(context->gfp, log_error);
|
||||
lame_set_debugf(context->gfp, log_debug);
|
||||
lame_set_msgf(context->gfp, log_msg);
|
||||
|
||||
lame_init_params(context->gfp);
|
||||
lame_print_config(context->gfp);
|
||||
|
||||
if (handle->handler) {
|
||||
if (switch_buffer_create_dynamic(&context->audio_buffer, MY_BLOCK_SIZE, MY_BUF_LEN, 0) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error!\n");
|
||||
@@ -674,7 +680,7 @@ static switch_status_t shout_file_open(switch_file_handle_t *handle, const char
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (shout_set_audio_info(context->shout, "bitrate", "64000") != SHOUTERR_SUCCESS) {
|
||||
if (shout_set_audio_info(context->shout, "bitrate", "24000") != SHOUTERR_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error setting user: %s\n", shout_get_error(context->shout));
|
||||
goto error;
|
||||
}
|
||||
@@ -780,6 +786,8 @@ static switch_status_t shout_file_read(switch_file_handle_t *handle, void *data,
|
||||
*len = bytes / sizeof(int16_t);
|
||||
}
|
||||
|
||||
handle->sample_count += *len;
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -817,6 +825,13 @@ static switch_status_t shout_file_write(switch_file_handle_t *handle, void *data
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
} else {
|
||||
|
||||
if (!context->lame_ready) {
|
||||
lame_init_params(context->gfp);
|
||||
lame_print_config(context->gfp);
|
||||
context->lame_ready = 1;
|
||||
}
|
||||
|
||||
if ((rlen = lame_encode_buffer(context->gfp, audio, NULL, nsamples, mp3buf, sizeof(mp3buf))) < 0) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "MP3 encode error %d!\n", rlen);
|
||||
return SWITCH_STATUS_FALSE;
|
||||
@@ -828,26 +843,63 @@ static switch_status_t shout_file_write(switch_file_handle_t *handle, void *data
|
||||
}
|
||||
}
|
||||
|
||||
handle->sample_count += *len;
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static switch_status_t shout_file_set_string(switch_file_handle_t *handle, switch_audio_col_t col, const char *string)
|
||||
{
|
||||
shout_context_t *context = handle->private_info;
|
||||
|
||||
switch_status_t status = SWITCH_STATUS_FALSE;
|
||||
|
||||
if (!context->shout) {
|
||||
switch (col) {
|
||||
case SWITCH_AUDIO_COL_STR_TITLE:
|
||||
id3tag_set_title(context->gfp, string);
|
||||
break;
|
||||
case SWITCH_AUDIO_COL_STR_COMMENT:
|
||||
id3tag_set_comment(context->gfp, string);
|
||||
break;
|
||||
case SWITCH_AUDIO_COL_STR_ARTIST:
|
||||
id3tag_set_artist(context->gfp, string);
|
||||
break;
|
||||
case SWITCH_AUDIO_COL_STR_DATE:
|
||||
id3tag_set_year(context->gfp, string);
|
||||
break;
|
||||
case SWITCH_AUDIO_COL_STR_SOFTWARE:
|
||||
break;
|
||||
id3tag_set_album(context->gfp, string);
|
||||
case SWITCH_AUDIO_COL_STR_COPYRIGHT:
|
||||
id3tag_set_genre(context->gfp, string);
|
||||
break;
|
||||
default:
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Value Ignored\n");
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
switch (col) {
|
||||
case SWITCH_AUDIO_COL_STR_TITLE:
|
||||
if (shout_set_name(context->shout, string) != SHOUTERR_SUCCESS) {
|
||||
if (shout_set_name(context->shout, string) == SHOUTERR_SUCCESS) {
|
||||
status = SWITCH_STATUS_SUCCESS;
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error setting name: %s\n", shout_get_error(context->shout));
|
||||
}
|
||||
break;
|
||||
case SWITCH_AUDIO_COL_STR_COMMENT:
|
||||
if (shout_set_url(context->shout, string) != SHOUTERR_SUCCESS) {
|
||||
if (shout_set_url(context->shout, string) == SHOUTERR_SUCCESS) {
|
||||
status = SWITCH_STATUS_SUCCESS;
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error setting name: %s\n", shout_get_error(context->shout));
|
||||
}
|
||||
break;
|
||||
case SWITCH_AUDIO_COL_STR_ARTIST:
|
||||
if (shout_set_description(context->shout, string) != SHOUTERR_SUCCESS) {
|
||||
if (shout_set_description(context->shout, string) == SHOUTERR_SUCCESS) {
|
||||
status = SWITCH_STATUS_SUCCESS;
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error setting name: %s\n", shout_get_error(context->shout));
|
||||
}
|
||||
break;
|
||||
@@ -855,7 +907,8 @@ static switch_status_t shout_file_set_string(switch_file_handle_t *handle, switc
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Value Ignored\n");
|
||||
break;
|
||||
}
|
||||
return SWITCH_STATUS_FALSE;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static switch_status_t shout_file_get_string(switch_file_handle_t *handle, switch_audio_col_t col, const char **string)
|
||||
|
||||
@@ -205,6 +205,8 @@ static switch_status_t sndfile_file_read(switch_file_handle_t *handle, void *dat
|
||||
*len = (size_t) sf_readf_int(context->handle, (int *) data, inlen);
|
||||
}
|
||||
|
||||
handle->sample_count += *len;
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -227,6 +229,8 @@ static switch_status_t sndfile_file_write(switch_file_handle_t *handle, void *da
|
||||
*len = (size_t) sf_writef_int(context->handle, (int *) data, inlen);
|
||||
}
|
||||
|
||||
handle->sample_count += *len;
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
+85
-2
@@ -549,6 +549,87 @@ SWITCH_DECLARE(void) switch_core_runtime_loop(int bg)
|
||||
}
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(const char *) switch_core_mime_ext2type(const char *ext)
|
||||
{
|
||||
return (const char *) switch_core_hash_find(runtime.mime_types, ext);
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_mime_add_type(const char *type, const char *ext)
|
||||
{
|
||||
const char *check = (const char *) switch_core_hash_find(runtime.mime_types, ext);
|
||||
switch_status_t status = SWITCH_STATUS_FALSE;
|
||||
|
||||
assert(type);
|
||||
assert(ext);
|
||||
|
||||
if (!check) {
|
||||
char *ptype = switch_core_permanent_strdup(type);
|
||||
char *ext_list = strdup(ext);
|
||||
int argc = 0;
|
||||
char *argv[20] = { 0 };
|
||||
int x;
|
||||
|
||||
assert(ext_list);
|
||||
|
||||
if ((argc = switch_separate_string(ext_list, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) {
|
||||
|
||||
for (x = 0; x < argc; x++) {
|
||||
switch_core_hash_insert(runtime.mime_types, argv[x], ptype);
|
||||
}
|
||||
|
||||
status = SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
free(ext_list);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void load_mime_types(void)
|
||||
{
|
||||
char *cf = "mime.types";
|
||||
int fd = -1;
|
||||
char line_buf[1024] = "";
|
||||
char *mime_path = NULL;
|
||||
|
||||
mime_path = switch_mprintf("%s/%s", SWITCH_GLOBAL_dirs.conf_dir, cf);
|
||||
assert(mime_path);
|
||||
|
||||
if (!(fd = open(mime_path, O_RDONLY))) {
|
||||
return;
|
||||
}
|
||||
|
||||
while((switch_fd_read_line(fd, line_buf, sizeof(line_buf)))) {
|
||||
char *p;
|
||||
char *type = line_buf;
|
||||
|
||||
if (*line_buf == '#') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((p = strchr(line_buf, '\r')) || (p = strchr(line_buf, '\n'))) {
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
if ((p = strchr(type, '\t')) || (p = strchr(type, ' '))) {
|
||||
*p++ = '\0';
|
||||
|
||||
while(*p == ' ' || *p == '\t') {
|
||||
p++;
|
||||
}
|
||||
|
||||
switch_core_mime_add_type(type, p);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (fd > -1) {
|
||||
close(fd);
|
||||
fd = -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_init(const char *console, switch_core_flag_t flags, const char **err)
|
||||
{
|
||||
@@ -578,6 +659,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_init(const char *console, switch_cor
|
||||
switch_core_set_globals();
|
||||
switch_core_session_init(runtime.memory_pool);
|
||||
switch_core_hash_init(&runtime.global_vars, runtime.memory_pool);
|
||||
switch_core_hash_init(&runtime.mime_types, runtime.memory_pool);
|
||||
load_mime_types();
|
||||
runtime.flags = flags;
|
||||
runtime.sps_total = 30;
|
||||
|
||||
@@ -591,8 +674,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_init(const char *console, switch_cor
|
||||
apr_terminate();
|
||||
return SWITCH_STATUS_MEMERR;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if ((xml = switch_xml_open_cfg("switch.conf", &cfg, NULL))) {
|
||||
switch_xml_t settings, param;
|
||||
|
||||
@@ -918,6 +1000,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_destroy(void)
|
||||
|
||||
|
||||
switch_core_hash_destroy(&runtime.global_vars);
|
||||
switch_core_hash_destroy(&runtime.mime_types);
|
||||
|
||||
if (runtime.memory_pool) {
|
||||
apr_pool_destroy(runtime.memory_pool);
|
||||
|
||||
+34
-11
@@ -348,6 +348,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se
|
||||
const char *vval;
|
||||
time_t start = 0;
|
||||
uint32_t org_silence_hits = 0;
|
||||
switch_audio_resampler_t *resampler = NULL;
|
||||
int16_t resamp_out[2048];
|
||||
|
||||
if (!fh) {
|
||||
fh = &lfh;
|
||||
@@ -360,13 +362,27 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se
|
||||
assert(read_codec != NULL);
|
||||
|
||||
fh->channels = read_codec->implementation->number_of_channels;
|
||||
fh->samplerate = read_codec->implementation->actual_samples_per_second;
|
||||
|
||||
if (fh->samplerate) {
|
||||
if (fh->samplerate != read_codec->implementation->actual_samples_per_second) {
|
||||
if (switch_resample_create(&resampler,
|
||||
read_codec->implementation->actual_samples_per_second,
|
||||
read_codec->implementation->actual_samples_per_second * 20,
|
||||
fh->samplerate,
|
||||
fh->samplerate * 20,
|
||||
switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Unable to create resampler!\n");
|
||||
return SWITCH_STATUS_GENERR;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
fh->samplerate = read_codec->implementation->actual_samples_per_second;
|
||||
}
|
||||
|
||||
if (switch_core_file_open(fh,
|
||||
file,
|
||||
read_codec->implementation->number_of_channels,
|
||||
read_codec->implementation->actual_samples_per_second,
|
||||
fh->channels,
|
||||
fh->samplerate,
|
||||
SWITCH_FILE_FLAG_WRITE | SWITCH_FILE_DATA_SHORT, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
||||
switch_core_session_reset(session);
|
||||
@@ -539,7 +555,17 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se
|
||||
|
||||
if (!switch_test_flag(fh, SWITCH_FILE_PAUSE)) {
|
||||
len = (switch_size_t) read_frame->datalen / 2;
|
||||
if (switch_core_file_write(fh, read_frame->data, &len) != SWITCH_STATUS_SUCCESS) {
|
||||
int16_t *data = read_frame->data;
|
||||
|
||||
if (resampler) {
|
||||
resampler->from_len = switch_short_to_float(read_frame->data, resampler->from, (int) len);
|
||||
resampler->to_len = switch_resample_process(resampler, resampler->from, resampler->from_len, resampler->to, resampler->to_size, 0);
|
||||
switch_float_to_short(resampler->to, resamp_out, read_frame->datalen);
|
||||
len = resampler->to_len;
|
||||
data = resamp_out;
|
||||
}
|
||||
|
||||
if (switch_core_file_write(fh, data, &len) != SWITCH_STATUS_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -609,28 +635,25 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_gentones(switch_core_session_t *sessi
|
||||
}
|
||||
|
||||
for(;;) {
|
||||
switch_status_t status = switch_core_session_read_frame(session, &read_frame, 1000, 0);
|
||||
|
||||
switch_status_t status;
|
||||
|
||||
if (!switch_channel_ready(channel)) {
|
||||
status = SWITCH_STATUS_FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (switch_channel_test_flag(channel, CF_BREAK)) {
|
||||
switch_channel_clear_flag(channel, CF_BREAK);
|
||||
status = SWITCH_STATUS_BREAK;
|
||||
break;
|
||||
}
|
||||
|
||||
status = switch_core_session_read_frame(session, &read_frame, 1000, 0);
|
||||
|
||||
if (!SWITCH_READ_ACCEPTABLE(status)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (read_frame->datalen < 2 || switch_test_flag(read_frame, SFF_CNG)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (args && (args->read_frame_callback)) {
|
||||
if (args->read_frame_callback(session, read_frame, args->user_data) != SWITCH_STATUS_SUCCESS) {
|
||||
break;
|
||||
|
||||
+34
-2
@@ -35,6 +35,28 @@
|
||||
#endif
|
||||
#include "private/switch_core_pvt.h"
|
||||
|
||||
|
||||
switch_size_t switch_fd_read_line(int fd, char *buf, switch_size_t len)
|
||||
{
|
||||
char c, *p;
|
||||
int cur;
|
||||
switch_size_t total = 0;
|
||||
|
||||
p = buf;
|
||||
while (total + sizeof(c) < len && (cur = read(fd, &c, sizeof(c))) > 0) {
|
||||
total += cur;
|
||||
*p++ = c;
|
||||
if (c == '\r' || c == '\n') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*p++ = '\0';
|
||||
return total;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static const char switch_b64_table[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
#define B64BUFFLEN 1024
|
||||
SWITCH_DECLARE(switch_status_t) switch_b64_encode(unsigned char *in, switch_size_t ilen, unsigned char *out, switch_size_t olen)
|
||||
@@ -85,7 +107,7 @@ static int write_buf(int fd, const char *buf)
|
||||
SWITCH_DECLARE(switch_bool_t) switch_simple_email(const char *to, const char *from, const char *headers, const char *body, const char *file)
|
||||
{
|
||||
char *bound = "XXXX_boundary_XXXX";
|
||||
char *mime_type = "audio/x-WAV";
|
||||
const char *mime_type = "audio/inline";
|
||||
char filename[80], buf[B64BUFFLEN];
|
||||
int fd = 0, ifd = 0;
|
||||
int x = 0, y = 0, bytes = 0, ilen = 0;
|
||||
@@ -127,6 +149,16 @@ SWITCH_DECLARE(switch_bool_t) switch_simple_email(const char *to, const char *fr
|
||||
|
||||
if (file) {
|
||||
const char *filename = switch_cut_path(file);
|
||||
const char *new_type;
|
||||
char *ext;
|
||||
|
||||
if ((ext = strrchr(filename, '.'))) {
|
||||
ext++;
|
||||
if ((new_type = switch_core_mime_ext2type(ext))) {
|
||||
mime_type = new_type;
|
||||
}
|
||||
}
|
||||
|
||||
snprintf(buf, B64BUFFLEN,
|
||||
"\n\n--%s\nContent-Type: %s; name=\"%s\"\n"
|
||||
"Content-Transfer-Encoding: base64\n"
|
||||
@@ -188,7 +220,7 @@ SWITCH_DECLARE(switch_bool_t) switch_simple_email(const char *to, const char *fr
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to execute command: %s\n", buf);
|
||||
}
|
||||
|
||||
unlink(filename);
|
||||
//unlink(filename);
|
||||
|
||||
|
||||
if (file) {
|
||||
|
||||
+1
-20
@@ -878,25 +878,6 @@ SWITCH_DECLARE(switch_xml_t) switch_xml_parse_fd(int fd)
|
||||
return &root->xml;
|
||||
}
|
||||
|
||||
static switch_size_t read_line(int fd, char *buf, switch_size_t len)
|
||||
{
|
||||
char c, *p;
|
||||
int cur;
|
||||
switch_size_t total = 0;
|
||||
|
||||
p = buf;
|
||||
while (total + sizeof(c) < len && (cur = read(fd, &c, sizeof(c))) > 0) {
|
||||
total += cur;
|
||||
*p++ = c;
|
||||
if (c == '\n') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*p++ = '\0';
|
||||
return total;
|
||||
}
|
||||
|
||||
static char *expand_vars(char *buf, char *ebuf, switch_size_t elen, switch_size_t *newlen)
|
||||
{
|
||||
char *var, *val;
|
||||
@@ -999,7 +980,7 @@ static int preprocess(const char *cwd, const char *file, int write_fd, int rleve
|
||||
return -1;
|
||||
}
|
||||
|
||||
while ((cur = read_line(read_fd, buf, sizeof(buf))) > 0) {
|
||||
while ((cur = switch_fd_read_line(read_fd, buf, sizeof(buf))) > 0) {
|
||||
char *arg, *e;
|
||||
char *bp = expand_vars(buf, ebuf, sizeof(ebuf), &cur);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user