mirror of
https://github.com/signalwire/freeswitch.git
synced 2026-10-28 06:04:20 +00:00
Merge branch 'master' into smgmaster
This commit is contained in:
commit
8c7a6cc110
26 files changed
+537
-238
No files matched your search
+4
-1
@@ -21,7 +21,7 @@ $(OUR_MODULES) $(OUR_CLEAN_MODULES) $(OUR_INSTALL_MODULES) $(OUR_UNINSTALL_MODUL
|
||||
fi ; \
|
||||
fi ; \
|
||||
if test -z "$$target" ; then target="all" ; fi ; \
|
||||
if ! test -f $$moddir/$$modname.c && ! test -f $$moddir/$$modname.cpp ; \
|
||||
if ! test -f $$moddir/$$modname.c && ! test -f $$moddir/$$modname.cpp && test $$modname != "mod_com_g729" ; \
|
||||
then echo ; echo "WARNING $$modname is not a valid FreeSWITCH module dir, skipping it..." ; else \
|
||||
echo ;\
|
||||
echo making $$target $$modname ;\
|
||||
@@ -35,6 +35,9 @@ $(OUR_MODULES) $(OUR_CLEAN_MODULES) $(OUR_INSTALL_MODULES) $(OUR_UNINSTALL_MODUL
|
||||
fi; \
|
||||
test -z "$$fail" ;
|
||||
|
||||
mod_com_g729-activate:
|
||||
cd $(switch_builddir)/src/mod/codecs/mod_com_g729 && $(MAKE) $(AM_MAKEFLAGS) activate
|
||||
|
||||
.DEFAULT:
|
||||
@if test -z "`echo $@ | grep all`"; then $(MAKE) $(AM_MAKEFLAGS) $@-all ; else echo Unknown target `echo $@ | sed -e 's|-all||'`; exit 1; fi
|
||||
|
||||
|
||||
@@ -1384,6 +1384,8 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa
|
||||
switch_event_add_header(ovars, SWITCH_STACK_BOTTOM, "cc_agent", "%s", h->agent_name);
|
||||
switch_event_add_header(ovars, SWITCH_STACK_BOTTOM, "cc_agent_type", "%s", h->agent_type);
|
||||
switch_event_add_header(ovars, SWITCH_STACK_BOTTOM, "ignore_early_media", "true");
|
||||
/* Force loopback to remain live, if not, the loop will detect the actual channel to gone */
|
||||
switch_event_add_header(ovars, SWITCH_STACK_BOTTOM, "loopback_bowout", "false");
|
||||
|
||||
t_agent_called = switch_epoch_time_now(NULL);
|
||||
dialstr = switch_mprintf("%s", h->originate_string);
|
||||
@@ -2080,6 +2082,32 @@ void *SWITCH_THREAD_FUNC cc_member_thread_run(switch_thread_t *thread, void *obj
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct moh_dtmf_helper {
|
||||
const char *queue_name;
|
||||
char dtmf;
|
||||
};
|
||||
|
||||
static switch_status_t moh_on_dtmf(switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen) {
|
||||
struct moh_dtmf_helper *h = (struct moh_dtmf_helper *) buf;
|
||||
|
||||
switch (itype) {
|
||||
case SWITCH_INPUT_TYPE_DTMF:
|
||||
{
|
||||
/* Just laywork for people who want to get some DTMF actions */
|
||||
switch_dtmf_t *dtmf = (switch_dtmf_t *) input;
|
||||
if (strchr("#", dtmf->digit)) {
|
||||
h->dtmf = dtmf->digit;
|
||||
return SWITCH_STATUS_BREAK;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#define CC_DESC "callcenter"
|
||||
#define CC_USAGE "queue_name"
|
||||
|
||||
@@ -2226,8 +2254,6 @@ SWITCH_STANDARD_APP(callcenter_function)
|
||||
switch_thread_create(&thread, thd_attr, cc_member_thread_run, h, h->pool);
|
||||
|
||||
/* Playback MOH */
|
||||
/* TODO Add DTMF callback support */
|
||||
/* TODO add MOH infitite loop */
|
||||
if (cc_moh_override) {
|
||||
cur_moh = switch_core_session_strdup(member_session, cc_moh_override);
|
||||
} else {
|
||||
@@ -2237,6 +2263,12 @@ SWITCH_STANDARD_APP(callcenter_function)
|
||||
|
||||
while (switch_channel_ready(member_channel)) {
|
||||
switch_input_args_t args = { 0 };
|
||||
struct moh_dtmf_helper ht;
|
||||
|
||||
ht.dtmf = '\0';
|
||||
args.input_callback = moh_on_dtmf;
|
||||
args.buf = (void *) &ht;
|
||||
args.buflen = sizeof(h);
|
||||
|
||||
/* An agent was found, time to exit and let the bridge do it job */
|
||||
if ((agent_uuid = switch_channel_get_variable(member_channel, "cc_agent_uuid"))) {
|
||||
@@ -2260,6 +2292,8 @@ SWITCH_STANDARD_APP(callcenter_function)
|
||||
switch_ivr_collect_digits_callback(session, &args, 0, 0);
|
||||
}
|
||||
|
||||
switch_yield(1000);
|
||||
|
||||
}
|
||||
|
||||
/* Stop Member Thread */
|
||||
|
||||
@@ -45,6 +45,149 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load);
|
||||
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_commands_shutdown);
|
||||
SWITCH_MODULE_DEFINITION(mod_commands, mod_commands_load, mod_commands_shutdown, NULL);
|
||||
|
||||
|
||||
struct cb_helper {
|
||||
uint32_t row_process;
|
||||
switch_stream_handle_t *stream;
|
||||
};
|
||||
|
||||
static int url_callback(void *pArg, int argc, char **argv, char **columnNames)
|
||||
{
|
||||
struct cb_helper *cb = (struct cb_helper *) pArg;
|
||||
|
||||
cb->row_process++;
|
||||
|
||||
if (!zstr(argv[0])) {
|
||||
cb->stream->write_function(cb->stream, "%s,", argv[0]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static switch_status_t select_url(const char *user,
|
||||
const char *domain,
|
||||
const char *concat,
|
||||
const char *exclude_contact,
|
||||
switch_stream_handle_t *stream)
|
||||
{
|
||||
struct cb_helper cb;
|
||||
char *sql, *errmsg = NULL;
|
||||
switch_core_flag_t cflags = switch_core_flags();
|
||||
switch_cache_db_handle_t *db = NULL;
|
||||
|
||||
if (!(cflags & SCF_USE_SQL)) {
|
||||
stream->write_function(stream, "-ERR SQL DISABLED NO DATA AVAILABLE!\n");
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (switch_core_db_handle(&db) != SWITCH_STATUS_SUCCESS) {
|
||||
stream->write_function(stream, "%s", "-ERR Databse Error!\n");
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
cb.row_process = 0;
|
||||
cb.stream = stream;
|
||||
|
||||
if (exclude_contact) {
|
||||
sql = switch_mprintf("select url, '%q' "
|
||||
"from registrations where user='%q' and realm='%q' "
|
||||
"and url not like '%%%s%%'", (concat != NULL) ? concat : "", user, domain, exclude_contact);
|
||||
} else {
|
||||
sql = switch_mprintf("select url, '%q' "
|
||||
"from registrations where user='%q' and realm='%q'",
|
||||
(concat != NULL) ? concat : "", user, domain);
|
||||
}
|
||||
|
||||
switch_assert(sql);
|
||||
switch_cache_db_execute_sql_callback(db, sql, url_callback, &cb, &errmsg);
|
||||
|
||||
if (errmsg) {
|
||||
stream->write_function(stream, "-ERR SQL Error [%s]\n", errmsg);
|
||||
free(errmsg);
|
||||
errmsg = NULL;
|
||||
}
|
||||
|
||||
switch_safe_free(sql);
|
||||
|
||||
if (db) {
|
||||
switch_cache_db_release_db_handle(&db);
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
SWITCH_STANDARD_API(reg_url_function)
|
||||
{
|
||||
char *data;
|
||||
char *user = NULL;
|
||||
char *domain = NULL, *dup_domain = NULL;
|
||||
char *concat = NULL;
|
||||
const char *exclude_contact = NULL;
|
||||
char *reply = "error/facility_not_subscribed";
|
||||
switch_stream_handle_t mystream = { 0 };
|
||||
|
||||
|
||||
if (!cmd) {
|
||||
stream->write_function(stream, "%s", "");
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (session) {
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
exclude_contact = switch_channel_get_variable(channel, "sip_exclude_contact");
|
||||
}
|
||||
|
||||
|
||||
data = strdup(cmd);
|
||||
switch_assert(data);
|
||||
|
||||
user = data;
|
||||
|
||||
if ((domain = strchr(user, '@'))) {
|
||||
*domain++ = '\0';
|
||||
if ((concat = strchr(domain, '/'))) {
|
||||
*concat++ = '\0';
|
||||
}
|
||||
} else {
|
||||
if ((concat = strchr(user, '/'))) {
|
||||
*concat++ = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
if (zstr(domain)) {
|
||||
dup_domain = switch_core_get_variable_dup("domain");
|
||||
domain = dup_domain;
|
||||
}
|
||||
|
||||
if (!user) goto end;
|
||||
|
||||
|
||||
SWITCH_STANDARD_STREAM(mystream);
|
||||
switch_assert(mystream.data);
|
||||
|
||||
select_url(user, domain, concat, exclude_contact, &mystream);
|
||||
reply = mystream.data;
|
||||
|
||||
|
||||
end:
|
||||
|
||||
if (zstr(reply)) {
|
||||
reply = "error/user_not_registered";
|
||||
} else if (end_of(reply) == ',') {
|
||||
end_of(reply) = '\0';
|
||||
}
|
||||
|
||||
stream->write_function(stream, "%s", reply);
|
||||
reply = NULL;
|
||||
|
||||
switch_safe_free(mystream.data);
|
||||
|
||||
switch_safe_free(data);
|
||||
switch_safe_free(dup_domain);
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
SWITCH_STANDARD_API(banner_function)
|
||||
{
|
||||
stream->write_function(stream, "%s", switch_core_banner());
|
||||
@@ -3738,6 +3881,14 @@ SWITCH_STANDARD_API(show_function)
|
||||
as = argv[3];
|
||||
}
|
||||
}
|
||||
} else if (!strcasecmp(command, "registrations")) {
|
||||
sprintf(sql, "select * from registrations where hostname='%s'", hostname);
|
||||
if (argv[1] && !strcasecmp(argv[1], "count")) {
|
||||
holder.justcount = 1;
|
||||
if (argv[3] && !strcasecmp(argv[2], "as")) {
|
||||
as = argv[3];
|
||||
}
|
||||
}
|
||||
} else if (!strcasecmp(command, "channels") && argv[1] && !strcasecmp(argv[1], "like")) {
|
||||
if (argv[2]) {
|
||||
char *p;
|
||||
@@ -4890,6 +5041,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load)
|
||||
SWITCH_ADD_API(commands_api_interface, "tone_detect", "Start Tone Detection on a channel", tone_detect_session_function, TONE_DETECT_SYNTAX);
|
||||
SWITCH_ADD_API(commands_api_interface, "unload", "Unload Module", unload_function, UNLOAD_SYNTAX);
|
||||
SWITCH_ADD_API(commands_api_interface, "unsched_api", "Unschedule an api command", unsched_api_function, UNSCHED_SYNTAX);
|
||||
SWITCH_ADD_API(commands_api_interface, "reg_url", "", reg_url_function, "<user>@<realm>");
|
||||
SWITCH_ADD_API(commands_api_interface, "url_decode", "url decode a string", url_decode_function, "<string>");
|
||||
SWITCH_ADD_API(commands_api_interface, "url_encode", "url encode a string", url_encode_function, "<string>");
|
||||
SWITCH_ADD_API(commands_api_interface, "user_data", "find user data", user_data_function, "<user>@<domain> [var|param|attr] <name>");
|
||||
@@ -5000,6 +5152,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load)
|
||||
switch_console_set_complete("add show management");
|
||||
switch_console_set_complete("add show modules");
|
||||
switch_console_set_complete("add show nat_map");
|
||||
switch_console_set_complete("add show registrations");
|
||||
switch_console_set_complete("add show say");
|
||||
switch_console_set_complete("add show timer");
|
||||
switch_console_set_complete("add shutdown");
|
||||
|
||||
@@ -120,6 +120,11 @@ static switch_status_t tts_commandline_speech_close(switch_speech_handle_t *sh,
|
||||
tts_commandline_t *info = (tts_commandline_t *) sh->private_info;
|
||||
assert(info != NULL);
|
||||
|
||||
if (switch_test_flag(info->fh, SWITCH_FILE_OPEN)) {
|
||||
switch_core_file_close(info->fh);
|
||||
unlink(info->file);
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -130,6 +135,11 @@ static switch_status_t tts_commandline_speech_feed_tts(switch_speech_handle_t *s
|
||||
|
||||
assert(info != NULL);
|
||||
|
||||
if (switch_test_flag(info->fh, SWITCH_FILE_OPEN)) {
|
||||
switch_core_file_close(info->fh);
|
||||
unlink(info->file);
|
||||
}
|
||||
|
||||
message = switch_core_strdup(sh->memory_pool, globals.command);
|
||||
|
||||
tmp = switch_util_quote_shell_arg(text);
|
||||
@@ -152,7 +162,7 @@ static switch_status_t tts_commandline_speech_feed_tts(switch_speech_handle_t *s
|
||||
}
|
||||
|
||||
if (switch_core_file_open(info->fh, info->file, 0, //number_of_channels,
|
||||
0, //samples_per_second,
|
||||
info->rate, //samples_per_second,
|
||||
SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to open file: %s\n", info->file);
|
||||
return SWITCH_STATUS_FALSE;
|
||||
@@ -171,11 +181,14 @@ static switch_status_t tts_commandline_speech_read_tts(switch_speech_handle_t *s
|
||||
assert(info != NULL);
|
||||
|
||||
if (switch_core_file_read(info->fh, data, &my_datalen) != SWITCH_STATUS_SUCCESS) {
|
||||
*datalen = my_datalen * 2;
|
||||
switch_core_file_close(info->fh);
|
||||
unlink(info->file);
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
*datalen = my_datalen * 2;
|
||||
if (datalen == 0) {
|
||||
switch_core_file_close(info->fh);
|
||||
unlink(info->file);
|
||||
return SWITCH_STATUS_BREAK;
|
||||
} else {
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
include $(top_srcdir)/build/modmake.rulesam
|
||||
|
||||
MODNAME=mod_com_g729
|
||||
VERSION=193
|
||||
|
||||
if ISLINUX
|
||||
|
||||
G729INSTALLER = $(top_srcdir)/libs/fsg729-$(VERSION)-installer
|
||||
LICSERVER=/usr/sbin/freeswitch_licence_server
|
||||
VALIDATOR=$(bindir)/validator
|
||||
MOD=$(moddir)/mod_com_g729.so
|
||||
BUILT_SOURCES = $(G729INSTALLER)
|
||||
|
||||
install: $(LICSERVER) $(VALIDATOR) $(MOD)
|
||||
|
||||
$(LICSERVER) $(VALIDATOR) $(MOD): $(G729INSTALLER)
|
||||
$(SHELL) $(G729INSTALLER) $(bindir) $(moddir) nobanner
|
||||
$(ECHO)
|
||||
$(ECHO)
|
||||
$(ECHO) Now you can activate your license by running $(MAKE) mod_com_g729-activate
|
||||
$(ECHO)
|
||||
$(ECHO)
|
||||
|
||||
$(G729INSTALLER):
|
||||
rm -f $(top_srcdir)/libs/fsg729-*-installer*
|
||||
$(GETG729) fsg729-$(VERSION)-installer
|
||||
chmod 755 $(G729INSTALLER)
|
||||
|
||||
clean:
|
||||
rm -f $(top_srcdir)/libs/fsg729-*-installer*
|
||||
rm -rf /tmp/fsg729
|
||||
|
||||
activate: $(LICSERVER) $(VALIDATOR) $(MOD)
|
||||
$(VALIDATOR)
|
||||
|
||||
uninstall: clean
|
||||
rm -f $(LICSERVER) $(VALIDATOR) $(MOD)
|
||||
|
||||
endif
|
||||
@@ -1366,7 +1366,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
|
||||
if (s && !strcmp(s, "off")) {
|
||||
s = NULL;
|
||||
}
|
||||
switch_rtp_debug_jitter_buffer(tech_pvt->rtp_session, s);
|
||||
status = switch_rtp_debug_jitter_buffer(tech_pvt->rtp_session, s);
|
||||
goto end;
|
||||
}
|
||||
|
||||
@@ -3314,6 +3314,7 @@ static int contact_callback(void *pArg, int argc, char **argv, char **columnName
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sql2str_callback(void *pArg, int argc, char **argv, char **columnNames)
|
||||
{
|
||||
struct cb_helper_sql2str *cbt = (struct cb_helper_sql2str *) pArg;
|
||||
|
||||
@@ -877,6 +877,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
|
||||
const char *agent = "unknown";
|
||||
const char *pres_on_reg = NULL;
|
||||
int send_pres = 0;
|
||||
int is_tls = 0, is_tcp = 0;
|
||||
|
||||
delete_subs = sofia_test_pflag(profile, PFLAG_DEL_SUBS_ON_REG);
|
||||
|
||||
@@ -944,8 +945,6 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
|
||||
char *path_encoded = NULL;
|
||||
int path_encoded_len = 0;
|
||||
const char *proto = "sip";
|
||||
int is_tls = 0, is_tcp = 0;
|
||||
|
||||
|
||||
if (switch_stristr("transport=tls", sip->sip_contact->m_url->url_params)) {
|
||||
is_tls += 1;
|
||||
@@ -1292,6 +1291,8 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
|
||||
char guess_ip4[256];
|
||||
const char *username = "unknown";
|
||||
const char *realm = reg_host;
|
||||
char *url = NULL;
|
||||
char *contact = NULL;
|
||||
|
||||
if (auth_params) {
|
||||
username = switch_event_get_header(auth_params, "sip_auth_username");
|
||||
@@ -1327,7 +1328,15 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
|
||||
|
||||
switch_find_local_ip(guess_ip4, sizeof(guess_ip4), NULL, AF_INET);
|
||||
|
||||
contact = sofia_glue_get_url_from_contact(contact_str, 1);
|
||||
url = switch_mprintf("sofia/%q/sip:%q", profile->name, sofia_glue_strip_proto(contact));
|
||||
|
||||
switch_core_add_registration(to_user, reg_host, call_id, url, (long) switch_epoch_time_now(NULL) + (long) exptime + 60,
|
||||
network_ip, network_port_c, is_tls ? "tls" : is_tcp ? "tcp" : "udp");
|
||||
|
||||
switch_safe_free(url);
|
||||
switch_safe_free(contact);
|
||||
|
||||
sql = switch_mprintf("insert into sip_registrations "
|
||||
"(call_id,sip_user,sip_host,presence_hosts,contact,status,rpid,expires,"
|
||||
"user_agent,server_user,server_host,profile_name,hostname,network_ip,network_port,sip_username,sip_realm,"
|
||||
@@ -1534,6 +1543,8 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
|
||||
}
|
||||
}
|
||||
} else {
|
||||
switch_core_del_registration(to_user, reg_host, call_id);
|
||||
|
||||
if (switch_event_create_subclass(&s_event, SWITCH_EVENT_CUSTOM, MY_EVENT_UNREGISTER) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile-name", profile->name);
|
||||
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "from-user", to_user);
|
||||
|
||||
@@ -1783,6 +1783,7 @@ static switch_status_t parse_command(listener_t *listener, switch_event_t **even
|
||||
switch_mutex_lock(listener->filter_mutex);
|
||||
if (!listener->filters) {
|
||||
switch_event_create_plain(&listener->filters, SWITCH_EVENT_CLONE);
|
||||
switch_clear_flag(listener->filters, EF_UNIQ_HEADERS);
|
||||
}
|
||||
|
||||
if (!strcasecmp(header_name, "delete") && header_val) {
|
||||
|
||||
Reference in new issue
Block a user