Merge branch 'master' of git.freeswitch.org:freeswitch

This commit is contained in:
Moises Silva
2010-10-01 07:07:12 -04:00
325 changed files with 24933 additions and 4354 deletions
+2
View File
@@ -233,6 +233,8 @@ struct switch_runtime {
switch_profile_timer_t *profile_timer;
double profile_time;
double min_idle_time;
int sql_buffer_len;
int max_sql_buffer_len;
};
extern struct switch_runtime runtime;
+3
View File
@@ -91,7 +91,10 @@
#include <Ws2tcpip.h>
#pragma warning(pop)
#else
/* work around for warnings in vs 2010 */
#pragma warning (disable:6386)
#include <Ws2tcpip.h>
#pragma warning (default:6386)
#endif
#else
#include <strings.h>
+1 -1
View File
@@ -38,7 +38,7 @@
/**
* @defgroup config Config File Parser
* @ingroup core1
* This module implements a basic interface and file format parser it may be depricated in favor of database entries
* This module implements a basic interface and file format parser it may be deprecated in favor of database entries
* or expanded to tie to external handlers in the future as necessary.
* <pre>
*
+4 -1
View File
@@ -1339,12 +1339,15 @@ SWITCH_DECLARE(switch_status_t) switch_core_timer_destroy(switch_timer_t *timer)
\param pool the memory pool to use
\return SWITCH_STATUS_SUCCESS if the handle is allocated
*/
SWITCH_DECLARE(switch_status_t) switch_core_codec_init(switch_codec_t *codec,
#define switch_core_codec_init(_codec, _codec_name, _fmtp, _rate, _ms, _channels, _flags, _codec_settings, _pool) \
switch_core_codec_init_with_bitrate(_codec, _codec_name, _fmtp, _rate, _ms, _channels, 0, _flags, _codec_settings, _pool)
SWITCH_DECLARE(switch_status_t) switch_core_codec_init_with_bitrate(switch_codec_t *codec,
const char *codec_name,
const char *fmtp,
uint32_t rate,
int ms,
int channels,
uint32_t bitrate,
uint32_t flags, const switch_codec_settings_t *codec_settings, switch_memory_pool_t *pool);
SWITCH_DECLARE(switch_status_t) switch_core_codec_copy(switch_codec_t *codec, switch_codec_t *new_codec, switch_memory_pool_t *pool);
+3 -2
View File
@@ -292,7 +292,8 @@ SWITCH_DECLARE(void) consoleCleanLog(char *msg);
SWITCH_DECLARE(int) transfer(char *extension, char *dialplan = NULL, char *context = NULL);
SWITCH_DECLARE(char *) read(int min_digits, int max_digits, const char *prompt_audio_file, int timeout, const char *valid_terminators);
SWITCH_DECLARE(char *) read(int min_digits, int max_digits,
const char *prompt_audio_file, int timeout, const char *valid_terminators, int digit_timeout = 0);
/** \brief Play a file into channel and collect dtmfs
*
@@ -306,7 +307,7 @@ SWITCH_DECLARE(void) consoleCleanLog(char *msg);
int max_digits,
int max_tries,
int timeout, char *terminators, char *audio_files, char *bad_input_audio_files,
char *digits_regex, const char *var_name = NULL);
char *digits_regex, const char *var_name = NULL, int digit_timeout = 0);
/** \brief Play a file that resides on disk into the channel
*
+8 -2
View File
@@ -369,7 +369,8 @@ SWITCH_DECLARE(switch_status_t) switch_play_and_get_digits(switch_core_session_t
const char *audio_file,
const char *bad_input_audio_file,
const char *var_name, char *digit_buffer, uint32_t digit_buffer_length,
const char *digits_regex);
const char *digits_regex,
uint32_t digit_timeout);
SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text_handle(switch_core_session_t *session,
switch_speech_handle_t *sh,
@@ -804,7 +805,12 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_read(switch_core_session_t *session,
uint32_t max_digits,
const char *prompt_audio_file,
const char *var_name,
char *digit_buffer, switch_size_t digit_buffer_length, uint32_t timeout, const char *valid_terminators);
char *digit_buffer,
switch_size_t digit_buffer_length,
uint32_t timeout,
const char *valid_terminators,
uint32_t digit_timeout);
SWITCH_DECLARE(switch_status_t) switch_ivr_block_dtmf_session(switch_core_session_t *session);
SWITCH_DECLARE(switch_status_t) switch_ivr_unblock_dtmf_session(switch_core_session_t *session);
+1 -1
View File
@@ -92,7 +92,7 @@ SWITCH_BEGIN_EXTERN_C
\brief Initilize the module backend and load all the modules
\return SWITCH_STATUS_SUCCESS when complete
*/
SWITCH_DECLARE(switch_status_t) switch_loadable_module_init(void);
SWITCH_DECLARE(switch_status_t) switch_loadable_module_init(switch_bool_t autoload);
/*!
\brief Shutdown the module backend and call the shutdown routine in all loaded modules
+16 -35
View File
@@ -570,42 +570,23 @@ struct switch_directory_handle {
void *private_info;
};
/* nobody has more setting than speex so we will let them set the standard */
/*! \brief Various codec settings (currently only relevant to speex) */
struct switch_codec_settings {
/*! desired quality */
int quality;
/*! desired complexity */
int complexity;
/*! desired enhancement */
int enhancement;
/*! desired vad level */
int vad;
/*! desired vbr level */
int vbr;
/*! desired vbr quality */
float vbr_quality;
/*! desired abr level */
int abr;
/*! desired dtx setting */
int dtx;
/*! desired preprocessor settings */
int preproc;
/*! preprocessor vad settings */
int pp_vad;
/*! preprocessor gain control settings */
int pp_agc;
/*! preprocessor gain level */
float pp_agc_level;
/*! preprocessor denoise level */
int pp_denoise;
/*! preprocessor dereverb settings */
int pp_dereverb;
/*! preprocessor dereverb decay level */
float pp_dereverb_decay;
/*! preprocessor dereverb level */
float pp_dereverb_level;
int unused;
};
/*! an abstract handle of a fmtp parsed by codec */
struct switch_codec_fmtp {
/*! actual samples transferred per second for those who are not moron g722 RFC writers */
uint32_t actual_samples_per_second;
/*! bits transferred per second */
int bits_per_second;
/*! number of microseconds of media in one packet (ptime * 1000) */
int microseconds_per_packet;
/*! private data for the codec module to store handle specific info */
void *private_info;
};
/*! an abstract handle to a codec module */
@@ -618,8 +599,6 @@ struct switch_codec {
char *fmtp_in;
/*! fmtp line for local sdp */
char *fmtp_out;
/*! codec settings for this handle */
switch_codec_settings_t codec_settings;
/*! flags to modify behaviour */
uint32_t flags;
/*! the handle's memory pool */
@@ -678,6 +657,8 @@ struct switch_codec_interface {
const char *interface_name;
/*! a list of codec implementations related to the codec */
switch_codec_implementation_t *implementations;
/*! function to decode a codec fmtp parameters */
switch_core_codec_fmtp_parse_func_t parse_fmtp;
uint32_t codec_id;
switch_thread_rwlock_t *rwlock;
int refs;
+1
View File
@@ -449,6 +449,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_stun_ping(switch_rtp_t *rtp_
SWITCH_DECLARE(void) switch_rtp_intentional_bugs(switch_rtp_t *rtp_session, switch_rtp_bug_flag_t bugs);
SWITCH_DECLARE(switch_rtp_stats_t *) switch_rtp_get_stats(switch_rtp_t *rtp_session, switch_memory_pool_t *pool);
SWITCH_DECLARE(switch_byte_t) switch_rtp_check_auto_adj(switch_rtp_t *rtp_session);
/*!
\}
+13 -3
View File
@@ -255,7 +255,8 @@ typedef enum {
SCF_USE_CLOCK_RT = (1 << 10),
SCF_VERBOSE_EVENTS = (1 << 11),
SCF_USE_WIN32_MONOTONIC = (1 << 12),
SCF_AUTO_SCHEMAS = (1 << 13)
SCF_AUTO_SCHEMAS = (1 << 13),
SCF_MINIMAL = (1 << 14)
} switch_core_flag_enum_t;
typedef uint32_t switch_core_flag_t;
@@ -479,9 +480,16 @@ typedef struct {
switch_size_t flush_packet_count;
} switch_rtp_numbers_t;
typedef struct {
uint32_t packet_count;
uint32_t octet_count;
} switch_rtcp_numbers_t;
typedef struct {
switch_rtp_numbers_t inbound;
switch_rtp_numbers_t outbound;
switch_rtcp_numbers_t rtcp;
} switch_rtp_stats_t;
typedef enum {
@@ -762,9 +770,9 @@ typedef struct {
const char *T38FaxUdpEC;
const char *T38VendorInfo;
const char *remote_ip;
uint32_t remote_port;
uint16_t remote_port;
const char *local_ip;
uint32_t local_port;
uint16_t local_port;
} switch_t38_options_t;
/*!
@@ -1580,6 +1588,7 @@ typedef struct switch_core_thread_session switch_core_thread_session_t;
typedef struct switch_codec_implementation switch_codec_implementation_t;
typedef struct switch_buffer switch_buffer_t;
typedef struct switch_codec_settings switch_codec_settings_t;
typedef struct switch_codec_fmtp switch_codec_fmtp_t;
typedef struct switch_odbc_handle switch_odbc_handle_t;
typedef struct switch_io_routines switch_io_routines_t;
@@ -1638,6 +1647,7 @@ typedef switch_status_t (*switch_core_codec_decode_func_t) (switch_codec_t *code
void *decoded_data, uint32_t *decoded_data_len, uint32_t *decoded_rate, unsigned int *flag);
typedef switch_status_t (*switch_core_codec_init_func_t) (switch_codec_t *, switch_codec_flag_t, const switch_codec_settings_t *codec_settings);
typedef switch_status_t (*switch_core_codec_fmtp_parse_func_t) (const char *fmtp, switch_codec_fmtp_t *codec_fmtp);
typedef switch_status_t (*switch_core_codec_destroy_func_t) (switch_codec_t *);
+47 -1
View File
@@ -139,6 +139,9 @@ static inline char *switch_strchr_strict(const char *in, char find, const char *
#define switch_is_valid_rate(_tmp) (_tmp == 8000 || _tmp == 12000 || _tmp == 16000 || _tmp == 24000 || _tmp == 32000 || _tmp == 11025 || _tmp == 22050 || _tmp == 44100 || _tmp == 48000)
#ifdef _MSC_VER
#pragma warning(disable:6011)
#endif
static inline int switch_string_has_escaped_data(const char *in)
{
const char *i = strchr(in, '\\');
@@ -153,6 +156,9 @@ static inline int switch_string_has_escaped_data(const char *in)
return 0;
}
#ifdef _MSC_VER
#pragma warning(default:6011)
#endif
SWITCH_DECLARE(switch_status_t) switch_b64_encode(unsigned char *in, switch_size_t ilen, unsigned char *out, switch_size_t olen);
SWITCH_DECLARE(switch_size_t) switch_b64_decode(char *in, char *out, switch_size_t olen);
@@ -171,6 +177,23 @@ static inline switch_bool_t switch_is_digit_string(const char *s)
return SWITCH_TRUE;
}
static inline uint32_t switch_known_bitrate(switch_payload_t payload)
{
switch(payload) {
case 0: /* PCMU */ return 64000;
case 3: /* GSM */ return 13200;
case 4: /* G723 */ return 6300;
case 7: /* LPC */ return 2400;
case 8: /* PCMA */ return 64000;
case 9: /* G722 */ return 64000;
case 18: /* G729 */ return 8000;
default: break;
}
return 0;
}
SWITCH_DECLARE(switch_size_t) switch_fd_read_line(int fd, char *buf, switch_size_t len);
@@ -353,7 +376,16 @@ switch_mutex_unlock(obj->flag_mutex);
#define switch_set_string(_dst, _src) switch_copy_string(_dst, _src, sizeof(_dst))
static inline char *switch_sanitize_number(char *number)
static inline uint32_t switch_default_ptime(const char *name, uint32_t number)
{
if (!strcasecmp(name, "G723")) {
return 30;
}
return 20;
}
static inline char *switch_sanitize_number(char *number)
{
char *p = number, *q;
char warp[] = "/:";
@@ -455,6 +487,9 @@ static inline char *switch_safe_strdup(const char *it)
}
#ifdef _MSC_VER
#pragma warning(disable:6011)
#endif
static inline char *switch_lc_strdup(const char *it)
{
char *dup;
@@ -487,6 +522,9 @@ static inline char *switch_uc_strdup(const char *it)
return NULL;
}
#ifdef _MSC_VER
#pragma warning(default:6011)
#endif
/*!
@@ -680,7 +718,15 @@ SWITCH_DECLARE(switch_bool_t) switch_network_list_validate_ip_token(switch_netwo
SWITCH_DECLARE(int) switch_inet_pton(int af, const char *src, void *dst);
SWITCH_DECLARE(const char *) switch_dow_int2str(int val);
SWITCH_DECLARE(int) switch_dow_str2int(const char *exp);
SWITCH_DECLARE(int) switch_dow_cmp(const char *exp, int val);
SWITCH_DECLARE(int) switch_number_cmp(const char *exp, int val);
SWITCH_DECLARE(int) switch_tod_cmp(const char *exp, int val);
SWITCH_DECLARE(int) switch_fulldate_cmp(const char *exp, switch_time_t *ts);
SWITCH_DECLARE(void) switch_split_date(const char *exp, int *year, int *month, int *day);
SWITCH_DECLARE(void) switch_split_time(const char *exp, int *hour, int *min, int *sec);
/*!
\brief Split a user@domain string as user and domain
+1
View File
@@ -331,6 +331,7 @@ SWITCH_DECLARE(switch_xml_t) switch_xml_open_root(_In_ uint8_t reload, _Out_ con
///\return SWITCH_STATUS_SUCCESS if successful
SWITCH_DECLARE(switch_status_t) switch_xml_init(_In_ switch_memory_pool_t *pool, _Out_ const char **err);
SWITCH_DECLARE(switch_status_t) switch_xml_reload(const char **err);
SWITCH_DECLARE(switch_status_t) switch_xml_destroy(void);
@@ -1259,7 +1259,7 @@ static switch_status_t load_config(void)
if (!strcasecmp(var, "debug")) {
globals.debug = atoi(val);
} else if (!strcasecmp(var, "odbc-dsn")) {
globals.odbc_dsn = strdup(switch_xml_attr(param, "odbc-dsn"));
globals.odbc_dsn = strdup(val);
if (!zstr(globals.odbc_dsn)) {
if ((globals.odbc_user = strchr(globals.odbc_dsn, ':'))) {
@@ -1498,7 +1498,7 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa
/* Update Agents Items */
/* Do not remove uuid of the agent if we are a standby agent */
sql = switch_mprintf("UPDATE agents SET %q last_bridge_end = %ld, talk_time = talk_time + (%ld-last_bridge_start) WHERE name = '%q' AND system = '%q';"
sql = switch_mprintf("UPDATE agents SET %s last_bridge_end = %ld, talk_time = talk_time + (%ld-last_bridge_start) WHERE name = '%q' AND system = '%q';"
, (strcasecmp(h->agent_type, CC_AGENT_TYPE_UUID_STANDBY)?"uuid = '',":""), (long) switch_epoch_time_now(NULL), (long) switch_epoch_time_now(NULL), h->agent_name, h->agent_system);
cc_execute_sql(NULL, sql, NULL);
switch_safe_free(sql);
@@ -2675,9 +2675,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_callcenter_load)
{
switch_application_interface_t *app_interface;
switch_api_interface_t *api_interface;
/* connect my internal structure to the blank pointer passed to me */
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
switch_status_t status;
memset(&globals, 0, sizeof(globals));
globals.pool = pool;
@@ -2685,11 +2683,16 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_callcenter_load)
switch_core_hash_init(&globals.queue_hash, globals.pool);
switch_mutex_init(&globals.mutex, SWITCH_MUTEX_NESTED, globals.pool);
if ((status = load_config()) != SWITCH_STATUS_SUCCESS) {
return status;
}
switch_mutex_lock(globals.mutex);
globals.running = 1;
switch_mutex_unlock(globals.mutex);
load_config();
/* connect my internal structure to the blank pointer passed to me */
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
if (!AGENT_DISPATCH_THREAD_STARTED) {
cc_agent_dispatch_thread_start();
@@ -135,7 +135,7 @@ SWITCH_STANDARD_API(nat_map_function)
switch_bool_t sticky = SWITCH_FALSE;
if (!cmd) {
goto error;
goto usage;
}
if (!switch_nat_is_initialized()) {
@@ -147,9 +147,8 @@ SWITCH_STANDARD_API(nat_map_function)
switch_assert(mydata);
argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
if (argc < 1) {
goto error;
goto usage;
}
if (argv[0] && switch_stristr("status", argv[0])) {
tmp = switch_nat_status();
@@ -197,6 +196,10 @@ SWITCH_STANDARD_API(nat_map_function)
error:
stream->write_function(stream, "false");
goto ok;
usage:
stream->write_function(stream, "USAGE: nat_map [status|reinit|republish] | [add|del] <port> [tcp|udp] [sticky]");
ok:
@@ -605,11 +608,12 @@ SWITCH_STANDARD_API(in_group_function)
SWITCH_STANDARD_API(user_data_function)
{
switch_xml_t x_domain, xml = NULL, x_user = NULL, x_param, x_params;
switch_xml_t x_domain, xml = NULL, x_user = NULL, x_group = NULL, x_param, x_params;
int argc;
char *mydata = NULL, *argv[3], *key = NULL, *type = NULL, *user, *domain;
char delim = ' ';
const char *container = "params", *elem = "param";
const char *result = NULL;
switch_event_t *params = NULL;
if (zstr(cmd) || !(mydata = strdup(cmd))) {
@@ -637,10 +641,10 @@ SWITCH_STANDARD_API(user_data_function)
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "domain", domain);
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "type", type);
if (key && type && switch_xml_locate_user("id", user, domain, NULL, &xml, &x_domain, &x_user, NULL, params) == SWITCH_STATUS_SUCCESS) {
if (key && type && switch_xml_locate_user("id", user, domain, NULL, &xml, &x_domain, &x_user, &x_group, params) == SWITCH_STATUS_SUCCESS) {
if (!strcmp(type, "attr")) {
const char *attr = switch_xml_attr_soft(x_user, key);
stream->write_function(stream, "%s", attr);
result = attr;
goto end;
}
@@ -649,33 +653,45 @@ SWITCH_STANDARD_API(user_data_function)
elem = "variable";
}
if ((x_params = switch_xml_child(x_user, container))) {
for (x_param = switch_xml_child(x_params, elem); x_param; x_param = x_param->next) {
const char *var = switch_xml_attr(x_param, "name");
const char *val = switch_xml_attr(x_param, "value");
if (var && val && !strcasecmp(var, key)) {
stream->write_function(stream, "%s", val);
goto end;
}
}
}
if ((x_params = switch_xml_child(x_domain, container))) {
for (x_param = switch_xml_child(x_params, elem); x_param; x_param = x_param->next) {
const char *var = switch_xml_attr(x_param, "name");
const char *val = switch_xml_attr(x_param, "value");
if (var && val && !strcasecmp(var, key)) {
stream->write_function(stream, "%s", val);
goto end;
result = val;
}
}
}
if (x_group && (x_params = switch_xml_child(x_group, container))) {
for (x_param = switch_xml_child(x_params, elem); x_param; x_param = x_param->next) {
const char *var = switch_xml_attr(x_param, "name");
const char *val = switch_xml_attr(x_param, "value");
if (var && val && !strcasecmp(var, key)) {
result = val;
}
}
}
if ((x_params = switch_xml_child(x_user, container))) {
for (x_param = switch_xml_child(x_params, elem); x_param; x_param = x_param->next) {
const char *var = switch_xml_attr(x_param, "name");
const char *val = switch_xml_attr(x_param, "value");
if (var && val && !strcasecmp(var, key)) {
result = val;
}
}
}
}
end:
if (result) {
stream->write_function(stream, "%s", result);
}
switch_xml_free(xml);
switch_safe_free(mydata);
switch_event_destroy(&params);
@@ -1049,7 +1065,7 @@ SWITCH_STANDARD_API(url_encode_function)
int len = 0;
if (!zstr(cmd)) {
len = (strlen(cmd) * 3) + 1;
len = (int)(strlen(cmd) * 3) + 1;
switch_zmalloc(data, len);
switch_url_encode(cmd, data, len);
reply = data;
@@ -1166,17 +1182,18 @@ SWITCH_STANDARD_API(xml_locate_function)
SWITCH_STANDARD_API(reload_acl_function)
{
const char *err;
switch_xml_t xml_root;
if (cmd && !strcmp(cmd, "reloadxml")) {
if ((xml_root = switch_xml_open_root(1, &err))) {
switch_xml_free(xml_root);
}
if (cmd && !strcasecmp(cmd, "reloadxml")) {
stream->write_function(stream, "This option is deprecated, we now always reloadxml.\n");
}
if (switch_xml_reload(&err) == SWITCH_STATUS_SUCCESS) {
switch_load_network_lists(SWITCH_TRUE);
stream->write_function(stream, "+OK acl reloaded\n");
} else {
stream->write_function(stream, "-Error [%s]\n", err);
}
switch_load_network_lists(SWITCH_TRUE);
stream->write_function(stream, "+OK acl reloaded\n");
return SWITCH_STATUS_SUCCESS;
}
@@ -1374,7 +1391,7 @@ SWITCH_STANDARD_API(cond_function)
argc = switch_separate_string(mydata, ':', argv, (sizeof(argv) / sizeof(argv[0])));
if (argc != 3) {
if (! (argc >= 2 && argc <= 3)) {
goto error;
}
@@ -1451,7 +1468,12 @@ SWITCH_STANDARD_API(cond_function)
}
switch_safe_free(s_a);
switch_safe_free(s_b);
stream->write_function(stream, "%s", is_true ? argv[1] : argv[2]);
if ((argc == 2 && !is_true)) {
stream->write_function(stream, "");
} else {
stream->write_function(stream, "%s", is_true ? argv[1] : argv[2]);
}
goto ok;
}
@@ -1720,6 +1742,10 @@ SWITCH_STANDARD_API(load_function)
return SWITCH_STATUS_SUCCESS;
}
if (switch_xml_reload(&err) == SWITCH_STATUS_SUCCESS) {
stream->write_function(stream, "+OK Reloading XML\n");
}
if (switch_loadable_module_load_module((char *) SWITCH_GLOBAL_dirs.mod_dir, (char *) cmd, SWITCH_TRUE, &err) == SWITCH_STATUS_SUCCESS) {
stream->write_function(stream, "+OK\n");
} else {
@@ -1814,6 +1840,10 @@ SWITCH_STANDARD_API(reload_function)
stream->write_function(stream, "-ERR unloading module [%s]\n", err);
}
if (switch_xml_reload(&err) == SWITCH_STATUS_SUCCESS) {
stream->write_function(stream, "+OK Reloading XML\n");
}
if (switch_loadable_module_load_module((char *) SWITCH_GLOBAL_dirs.mod_dir, (char *) cmd, SWITCH_TRUE, &err) == SWITCH_STATUS_SUCCESS) {
stream->write_function(stream, "+OK module loaded\n");
} else {
@@ -1825,13 +1855,9 @@ SWITCH_STANDARD_API(reload_function)
SWITCH_STANDARD_API(reload_xml_function)
{
const char *err;
switch_xml_t xml_root;
if ((xml_root = switch_xml_open_root(1, &err))) {
switch_xml_free(xml_root);
}
const char *err = "";
switch_xml_reload(&err);
stream->write_function(stream, "+OK [%s]\n", err);
return SWITCH_STATUS_SUCCESS;
@@ -3022,7 +3048,7 @@ SWITCH_STANDARD_API(xml_wrap_api_function)
if (mystream.data) {
if (encoded) {
elen = (int) strlen(mystream.data) * 3;
elen = (int) strlen(mystream.data) * 3 + 1;
edata = malloc(elen);
switch_assert(edata != NULL);
memset(edata, 0, elen);
@@ -4040,7 +4066,7 @@ SWITCH_STANDARD_API(uuid_dump_function)
return SWITCH_STATUS_SUCCESS;
}
#define GLOBAL_SETVAR_SYNTAX "<var> <value> [<value2>]"
#define GLOBAL_SETVAR_SYNTAX "<var>=<value> [=<value2>]"
SWITCH_STANDARD_API(global_setvar_function)
{
char *mycmd = NULL, *argv[3] = { 0 };
@@ -4192,7 +4218,7 @@ SWITCH_STANDARD_API(escape_function)
return SWITCH_STATUS_SUCCESS;
}
len = strlen(cmd) * 2;
len = (int)strlen(cmd) * 2;
mycmd = malloc(len);
stream->write_function(stream, "%s", switch_escape_string(cmd, mycmd, len));
@@ -4551,7 +4577,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load)
SWITCH_ADD_API(commands_api_interface, "originate", "Originate a Call", originate_function, ORIGINATE_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "pause", "Pause", pause_function, PAUSE_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "regex", "Eval a regex", regex_function, "<data>|<pattern>[|<subst string>]");
SWITCH_ADD_API(commands_api_interface, "reloadacl", "Reload ACL", reload_acl_function, "[reloadxml]");
SWITCH_ADD_API(commands_api_interface, "reloadacl", "Reload ACL", reload_acl_function, "");
SWITCH_ADD_API(commands_api_interface, "reload", "Reload Module", reload_function, UNLOAD_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "reloadxml", "Reload XML", reload_xml_function, "");
SWITCH_ADD_API(commands_api_interface, "replace", "replace a string", replace_function, "<data>|<string1>|<string2>");
@@ -99,7 +99,7 @@ typedef enum {
CALLER_CONTROL_DEAF_MUTE,
CALLER_CONTROL_ENERGY_UP,
CALLER_CONTROL_ENERGY_EQU_CONF,
CALLER_CONTROL_ENERGEY_DN,
CALLER_CONTROL_ENERGY_DN,
CALLER_CONTROL_VOL_TALK_UP,
CALLER_CONTROL_VOL_TALK_ZERO,
CALLER_CONTROL_VOL_TALK_DN,
@@ -121,7 +121,7 @@ typedef struct conference_member conference_member_t;
struct call_list {
char *string;
int itteration;
int iteration;
struct call_list *next;
};
typedef struct call_list call_list_t;
@@ -717,7 +717,7 @@ static switch_status_t conference_add_member(conference_obj_t *conference, confe
if (call_list) {
char saymsg[1024];
switch_snprintf(saymsg, sizeof(saymsg), "Auto Calling %d parties", call_list->itteration);
switch_snprintf(saymsg, sizeof(saymsg), "Auto Calling %d parties", call_list->iteration);
conference_member_say(member, saymsg, 0);
} else {
if (zstr(conference->special_announce)) {
@@ -1012,7 +1012,7 @@ static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, v
uint8_t *file_frame;
uint8_t *async_file_frame;
int16_t *bptr;
int x = 0;
uint32_t x = 0;
int32_t z = 0;
int member_score_sum = 0;
int divisor = 0;
@@ -2298,7 +2298,7 @@ static caller_control_fn_table_t ccfntbl[] = {
{"deaf mute", "*", CALLER_CONTROL_DEAF_MUTE, conference_loop_fn_deafmute_toggle},
{"energy up", "9", CALLER_CONTROL_ENERGY_UP, conference_loop_fn_energy_up},
{"energy equ", "8", CALLER_CONTROL_ENERGY_EQU_CONF, conference_loop_fn_energy_equ_conf},
{"energy dn", "7", CALLER_CONTROL_ENERGEY_DN, conference_loop_fn_energy_dn},
{"energy dn", "7", CALLER_CONTROL_ENERGY_DN, conference_loop_fn_energy_dn},
{"vol talk up", "3", CALLER_CONTROL_VOL_TALK_UP, conference_loop_fn_volume_talk_up},
{"vol talk zero", "2", CALLER_CONTROL_VOL_TALK_ZERO, conference_loop_fn_volume_talk_zero},
{"vol talk dn", "1", CALLER_CONTROL_VOL_TALK_DN, conference_loop_fn_volume_talk_dn},
@@ -3733,7 +3733,7 @@ static switch_status_t conf_api_sub_list(conference_obj_t *conference, switch_st
static switch_xml_t add_x_tag(switch_xml_t x_member, const char *name, const char *value, int off)
{
switch_size_t dlen = strlen(value) * 3;
switch_size_t dlen = strlen(value) * 3 + 1;
char *data;
switch_xml_t x_tag;
@@ -5199,9 +5199,9 @@ SWITCH_STANDARD_APP(conference_auto_function)
np->string = switch_core_session_strdup(session, data);
if (call_list) {
np->next = call_list;
np->itteration = call_list->itteration + 1;
np->iteration = call_list->iteration + 1;
} else {
np->itteration = 1;
np->iteration = 1;
}
call_list = np;
}
@@ -393,7 +393,7 @@ static dir_profile_t *load_profile(const char *profile_name)
profile_set_config(profile);
/* Add the params to the event structure */
count = switch_event_import_xml(switch_xml_child(x_profile, "param"), "name", "value", &event);
count = (int)switch_event_import_xml(switch_xml_child(x_profile, "param"), "name", "value", &event);
if (switch_xml_config_parse_event(event, count, SWITCH_FALSE, profile->config) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to process configuration\n");
@@ -611,7 +611,7 @@ static switch_status_t on_dtmf(switch_core_session_t *session, void *input, swit
}
if (strlen(cbr->digits) < sizeof(cbr->digits) - 2) {
int at = strlen(cbr->digits);
int at = (int)strlen(cbr->digits);
cbr->digits[at++] = dtmf->digit;
cbr->digits[at] = '\0';
} else {
@@ -649,25 +649,25 @@ static switch_status_t listen_entry(switch_core_session_t *session, dir_profile_
if (zstr_buf(buf)) {
switch_snprintf(macro, sizeof(macro), "phrase:%s:%d", DIR_RESULT_ITEM, cbt->want + 1);
switch_ivr_read(session, 0, 1, macro, NULL, buf, sizeof(buf), 1, profile->terminator_key);
switch_ivr_read(session, 0, 1, macro, NULL, buf, sizeof(buf), 1, profile->terminator_key, 0);
}
if (!zstr_buf(recorded_name) && zstr_buf(buf)) {
switch_ivr_read(session, 0, 1, recorded_name, NULL, buf, sizeof(buf), 1, profile->terminator_key);
switch_ivr_read(session, 0, 1, recorded_name, NULL, buf, sizeof(buf), 1, profile->terminator_key, 0);
}
if (zstr_buf(recorded_name) && zstr_buf(buf)) {
switch_snprintf(macro, sizeof(macro), "phrase:%s:%s", DIR_RESULT_SAY_NAME, cbt->fullname);
switch_ivr_read(session, 0, 1, macro, NULL, buf, sizeof(buf), 1, profile->terminator_key);
switch_ivr_read(session, 0, 1, macro, NULL, buf, sizeof(buf), 1, profile->terminator_key, 0);
}
if (cbt->exten_visible && zstr_buf(buf)) {
switch_snprintf(macro, sizeof(macro), "phrase:%s:%s", DIR_RESULT_AT, cbt->extension);
switch_ivr_read(session, 0, 1, macro, NULL, buf, sizeof(buf), 1, profile->terminator_key);
switch_ivr_read(session, 0, 1, macro, NULL, buf, sizeof(buf), 1, profile->terminator_key, 0);
}
if (zstr_buf(buf)) {
switch_snprintf(macro, sizeof(macro), "phrase:%s:%c,%c,%c,%c", DIR_RESULT_MENU, *profile->select_name_key, *profile->next_key, *profile->prev_key,
*profile->new_search_key);
switch_ivr_read(session, 0, 1, macro, NULL, buf, sizeof(buf), profile->digit_timeout, profile->terminator_key);
switch_ivr_read(session, 0, 1, macro, NULL, buf, sizeof(buf), profile->digit_timeout, profile->terminator_key, 0);
}
if (!zstr_buf(buf)) {
@@ -884,6 +884,18 @@ SWITCH_STANDARD_APP(directory_function)
if (strcasecmp(profile->search_order, "last_name")) {
s_param.search_by_last_name = 0;
}
{
const char *var_search_order = switch_channel_get_variable(channel, "directory_search_order");
if (var_search_order) {
if (!strcasecmp(var_search_order, "first_name")) {
s_param.search_by_last_name = 0;
} else {
s_param.search_by_last_name = 1;
}
}
}
attempts = profile->max_menu_attempt;
s_param.try_again = 1;
while (switch_channel_ready(channel) && (s_param.try_again && attempts-- > 0)) {
+26 -6
View File
@@ -1712,10 +1712,11 @@ SWITCH_STANDARD_APP(att_xfer_function)
SWITCH_STANDARD_APP(read_function)
{
char *mydata;
char *argv[6] = { 0 };
char *argv[7] = { 0 };
int argc;
int32_t min_digits = 0;
int32_t max_digits = 0;
uint32_t digit_timeout = 0;
int timeout = 1000;
char digit_buffer[128] = "";
const char *prompt_audio_file = NULL;
@@ -1751,6 +1752,13 @@ SWITCH_STANDARD_APP(read_function)
valid_terminators = argv[5];
}
if (argc > 6) {
digit_timeout = atoi(argv[6]);
if (digit_timeout < 0) {
digit_timeout = 0;
}
}
if (min_digits <= 1) {
min_digits = 1;
}
@@ -1767,17 +1775,19 @@ SWITCH_STANDARD_APP(read_function)
valid_terminators = "#";
}
switch_ivr_read(session, min_digits, max_digits, prompt_audio_file, var_name, digit_buffer, sizeof(digit_buffer), timeout, valid_terminators);
switch_ivr_read(session, min_digits, max_digits, prompt_audio_file, var_name, digit_buffer, sizeof(digit_buffer), timeout, valid_terminators,
digit_timeout);
}
SWITCH_STANDARD_APP(play_and_get_digits_function)
{
char *mydata;
char *argv[9] = { 0 };
char *argv[10] = { 0 };
int argc;
int32_t min_digits = 0;
int32_t max_digits = 0;
int32_t max_tries = 0;
uint32_t digit_timeout = 0;
int timeout = 1000;
char digit_buffer[128] = "";
const char *prompt_audio_file = NULL;
@@ -1827,6 +1837,14 @@ SWITCH_STANDARD_APP(play_and_get_digits_function)
digits_regex = argv[8];
}
if (argc > 9) {
digit_timeout = atoi(argv[9]);
if (digit_timeout < 0) {
digit_timeout = 0;
}
}
if (min_digits <= 1) {
min_digits = 1;
}
@@ -1844,7 +1862,7 @@ SWITCH_STANDARD_APP(play_and_get_digits_function)
}
switch_play_and_get_digits(session, min_digits, max_digits, max_tries, timeout, valid_terminators,
prompt_audio_file, bad_input_audio_file, var_name, digit_buffer, sizeof(digit_buffer), digits_regex);
prompt_audio_file, bad_input_audio_file, var_name, digit_buffer, sizeof(digit_buffer), digits_regex, digit_timeout);
}
#define SAY_SYNTAX "<module_name> <say_type> <say_method> [<say_gender>] <text>"
@@ -3367,9 +3385,11 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
SWITCH_ADD_APP(app_interface, "endless_playback", "Playback File Endlessly", "Endlessly Playback a file to the channel",
endless_playback_function, "<path>", SAF_NONE);
SWITCH_ADD_APP(app_interface, "att_xfer", "Attended Transfer", "Attended Transfer", att_xfer_function, "<channel_url>", SAF_NONE);
SWITCH_ADD_APP(app_interface, "read", "Read Digits", "Read Digits", read_function, "<min> <max> <file> <var_name> <timeout> <terminators>", SAF_NONE);
SWITCH_ADD_APP(app_interface, "read", "Read Digits", "Read Digits", read_function,
"<min> <max> <file> <var_name> <timeout> <terminators> <digit_timeout>", SAF_NONE);
SWITCH_ADD_APP(app_interface, "play_and_get_digits", "Play and get Digits", "Play and get Digits",
play_and_get_digits_function, "<min> <max> <tries> <timeout> <terminators> <file> <invalid_file> <var_name> <regexp>", SAF_NONE);
play_and_get_digits_function,
"<min> <max> <tries> <timeout> <terminators> <file> <invalid_file> <var_name> <regexp> [<digit_timeout>]", SAF_NONE);
SWITCH_ADD_APP(app_interface, "stop_record_session", "Stop Record Session", STOP_SESS_REC_DESC, stop_record_session_function, "<path>", SAF_NONE);
SWITCH_ADD_APP(app_interface, "record_session", "Record Session", SESS_REC_DESC, record_session_function, "<path> [+<timeout>]", SAF_MEDIA_TAP);
SWITCH_ADD_APP(app_interface, "record", "Record File", "Record a file from the channels input", record_function,
+35 -38
View File
@@ -439,7 +439,7 @@ static switch_status_t moh_on_dtmf(switch_core_session_t *session, void *input,
#define check_string(s) if (!zstr(s) && !strcasecmp(s, "undef")) { s = NULL; }
static int node_consumer_wait_count(fifo_node_t *node)
static int node_caller_count(fifo_node_t *node)
{
int i, len = 0;
@@ -458,7 +458,7 @@ static void node_remove_uuid(fifo_node_t *node, const char *uuid)
fifo_queue_popfly(node->fifo_list[i], uuid);
}
if (!node_consumer_wait_count(node)) {
if (!node_caller_count(node)) {
node->start_waiting = 0;
}
@@ -513,7 +513,6 @@ static switch_status_t caller_read_frame_callback(switch_core_session_t *session
if (match_key(caller_exit_key, *buf)) {
cd->abort = 1;
return SWITCH_STATUS_FALSE;
switch_channel_set_variable(channel, "fifo_caller_exit_key", (char *)buf);
}
cd->next = switch_epoch_time_now(NULL) + cd->freq;
cd->index++;
@@ -875,7 +874,7 @@ static void do_unbridge(switch_core_session_t *consumer_session, switch_core_ses
char *sql;
switch_event_t *event;
switch_channel_clear_app_flag(consumer_channel, FIFO_APP_BRIDGE_TAG);
switch_channel_clear_app_flag_key(__FILE__, consumer_channel, FIFO_APP_BRIDGE_TAG);
switch_channel_set_variable(consumer_channel, "fifo_bridged", NULL);
ts = switch_micro_time_now();
@@ -989,7 +988,7 @@ static switch_status_t messagehook (switch_core_session_t *session, switch_core_
goto end;
}
switch_channel_set_app_flag(consumer_channel, FIFO_APP_BRIDGE_TAG);
switch_channel_set_app_flag_key(__FILE__, consumer_channel, FIFO_APP_BRIDGE_TAG);
switch_channel_set_variable(consumer_channel, "fifo_bridged", "true");
switch_channel_set_variable(consumer_channel, "fifo_manual_bridge", "true");
@@ -1683,7 +1682,7 @@ static void find_consumers(fifo_node_t *node)
switch(node->outbound_strategy) {
case NODE_STRATEGY_ENTERPRISE:
{
int need = node_consumer_wait_count(node);
int need = node_caller_count(node);
if (node->outbound_per_cycle && node->outbound_per_cycle < need) {
need = node->outbound_per_cycle;
@@ -1753,7 +1752,7 @@ static void *SWITCH_THREAD_FUNC node_thread_run(switch_thread_t *thread, void *o
if ((node = (fifo_node_t *) val)) {
if (node->outbound_priority == 0) node->outbound_priority = 5;
if (node->has_outbound && node->ready && !node->busy && node->outbound_priority == cur_priority) {
ppl_waiting = node_consumer_wait_count(node);
ppl_waiting = node_caller_count(node);
consumer_total = node->consumer_count;
idle_consumers = node_idle_consumers(node);
@@ -1831,7 +1830,7 @@ static void check_cancel(fifo_node_t *node)
return;
}
ppl_waiting = node_consumer_wait_count(node);
ppl_waiting = node_caller_count(node);
if (node->ring_consumer_count > 0 && ppl_waiting < 1) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Outbound call count (%d) exceeds required value for queue %s (%d), "
@@ -1855,7 +1854,7 @@ static void send_presence(fifo_node_t *node)
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", "park");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", node->name);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from", node->name);
if ((wait_count = node_consumer_wait_count(node)) > 0) {
if ((wait_count = node_caller_count(node)) > 0) {
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "status", "Active (%d waiting)", wait_count);
} else {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "status", "Idle");
@@ -1990,6 +1989,11 @@ static void dec_use_count(switch_core_session_t *session, switch_bool_t send_eve
if ((outbound_id = switch_channel_get_variable(channel, "fifo_outbound_uuid"))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s untracking call on uuid %s!\n", switch_channel_get_name(channel), outbound_id);
sql = switch_mprintf("delete from fifo_bridge where consumer_uuid='%q'", switch_core_session_get_uuid(session));
fifo_execute_sql(sql, globals.sql_mutex);
switch_safe_free(sql);
del_bridge_call(outbound_id);
sql = switch_mprintf("update fifo_outbound set use_count=use_count-1, stop_time=%ld, next_avail=%ld + lag + 1 where use_count > 0 and uuid='%q'",
now, now, outbound_id);
@@ -2043,7 +2047,7 @@ SWITCH_STANDARD_APP(fifo_track_call_function)
add_bridge_call(data);
switch_channel_set_app_flag(channel, FIFO_APP_TRACKING);
switch_channel_set_app_flag_key(__FILE__, channel, FIFO_APP_TRACKING);
switch_channel_set_variable(channel, "fifo_outbound_uuid", data);
switch_channel_set_variable(channel, "fifo_track_call", "true");
@@ -2296,7 +2300,6 @@ SWITCH_STANDARD_APP(fifo_function)
switch_channel_answer(channel);
switch_thread_rwlock_wrlock(node->rwlock);
node->caller_count++;
if ((pri = switch_channel_get_variable(channel, "fifo_priority"))) {
p = atoi(pri);
@@ -2306,7 +2309,7 @@ SWITCH_STANDARD_APP(fifo_function)
p = MAX_PRI - 1;
}
if (!node_consumer_wait_count(node)) {
if (!node_caller_count(node)) {
node->start_waiting = switch_micro_time_now();
}
@@ -2343,7 +2346,7 @@ SWITCH_STANDARD_APP(fifo_function)
switch_channel_set_variable(channel, "fifo_timestamp", date);
switch_channel_set_variable(channel, "fifo_serviced_uuid", NULL);
switch_channel_set_app_flag(channel, FIFO_APP_BRIDGE_TAG);
switch_channel_set_app_flag_key(__FILE__, channel, FIFO_APP_BRIDGE_TAG);
if (chime_list) {
char *list_dup = switch_core_session_strdup(session, chime_list);
@@ -2416,10 +2419,10 @@ SWITCH_STANDARD_APP(fifo_function)
}
}
switch_channel_clear_app_flag(channel, FIFO_APP_BRIDGE_TAG);
abort:
switch_channel_clear_app_flag_key(__FILE__, channel, FIFO_APP_BRIDGE_TAG);
abort:
fifo_caller_del(switch_core_session_get_uuid(session));
if (!aborted && switch_channel_ready(channel)) {
@@ -2442,7 +2445,6 @@ SWITCH_STANDARD_APP(fifo_function)
switch_mutex_lock(globals.mutex);
switch_thread_rwlock_wrlock(node->rwlock);
node_remove_uuid(node, uuid);
node->caller_count--;
switch_thread_rwlock_unlock(node->rwlock);
send_presence(node);
check_cancel(node);
@@ -2583,7 +2585,7 @@ SWITCH_STANDARD_APP(fifo_function)
continue;
}
if ((waiting = node_consumer_wait_count(node))) {
if ((waiting = node_caller_count(node))) {
if (!importance || node->importance > importance) {
if (strat == STRAT_WAITING_LONGER) {
@@ -2671,7 +2673,7 @@ SWITCH_STANDARD_APP(fifo_function)
}
}
if (pop && !node_consumer_wait_count(node)) {
if (pop && !node_caller_count(node)) {
switch_thread_rwlock_wrlock(node->rwlock);
node->start_waiting = 0;
switch_thread_rwlock_unlock(node->rwlock);
@@ -2775,7 +2777,8 @@ SWITCH_STANDARD_APP(fifo_function)
switch_channel_set_flag(other_channel, CF_BREAK);
while (switch_channel_ready(channel) && switch_channel_ready(other_channel) && switch_channel_test_app_flag(other_channel, FIFO_APP_BRIDGE_TAG)) {
while (switch_channel_ready(channel) && switch_channel_ready(other_channel) &&
switch_channel_test_app_flag(other_channel, FIFO_APP_BRIDGE_TAG)) {
status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
if (!SWITCH_READ_ACCEPTABLE(status)) {
break;
@@ -2787,9 +2790,6 @@ SWITCH_STANDARD_APP(fifo_function)
const char *arg = switch_channel_get_variable(other_channel, "current_application_data");
switch_caller_extension_t *extension = NULL;
switch_thread_rwlock_wrlock(node->rwlock);
node->caller_count--;
switch_thread_rwlock_unlock(node->rwlock);
send_presence(node);
check_cancel(node);
@@ -2955,9 +2955,6 @@ SWITCH_STANDARD_APP(fifo_function)
switch_channel_set_variable(other_channel, "fifo_status", "DONE");
switch_channel_set_variable(other_channel, "fifo_timestamp", date);
switch_thread_rwlock_wrlock(node->rwlock);
node->caller_count--;
switch_thread_rwlock_unlock(node->rwlock);
send_presence(node);
check_cancel(node);
switch_core_session_rwunlock(other_session);
@@ -3070,7 +3067,7 @@ SWITCH_STANDARD_APP(fifo_function)
done:
switch_mutex_lock(globals.mutex);
if (node && node->ready == FIFO_DELAY_DESTROY && node->consumer_count == 0 && node->caller_count == 0) {
if (node && node->ready == FIFO_DELAY_DESTROY && node->consumer_count == 0 && node_caller_count(node) == 0) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "%s removed.\n", node->name);
switch_core_hash_delete(globals.fifo_hash, node->name);
switch_thread_rwlock_wrlock(node->rwlock);
@@ -3085,7 +3082,7 @@ SWITCH_STANDARD_APP(fifo_function)
switch_mutex_unlock(globals.mutex);
switch_channel_clear_app_flag(channel, FIFO_APP_BRIDGE_TAG);
switch_channel_clear_app_flag_key(__FILE__, channel, FIFO_APP_BRIDGE_TAG);
switch_core_media_bug_resume(session);
@@ -3505,9 +3502,9 @@ static void list_node(fifo_node_t *node, switch_xml_t x_report, int *off, int ve
switch_xml_set_attr_d(x_fifo, "name", node->name);
switch_snprintf(tmp, sizeof(buffer), "%d", node->consumer_count);
switch_xml_set_attr_d(x_fifo, "consumer_count", tmp);
switch_snprintf(tmp, sizeof(buffer), "%d", node->caller_count);
switch_snprintf(tmp, sizeof(buffer), "%d", node_caller_count(node));
switch_xml_set_attr_d(x_fifo, "caller_count", tmp);
switch_snprintf(tmp, sizeof(buffer), "%d", node_consumer_wait_count(node));
switch_snprintf(tmp, sizeof(buffer), "%d", node_caller_count(node));
switch_xml_set_attr_d(x_fifo, "waiting_count", tmp);
switch_snprintf(tmp, sizeof(buffer), "%u", node->importance);
switch_xml_set_attr_d(x_fifo, "importance", tmp);
@@ -3569,7 +3566,7 @@ void node_dump(switch_stream_handle_t *stream)
node->outbound_priority,
node->busy,
node->ready,
node_consumer_wait_count(node)
node_caller_count(node)
);
}
@@ -3687,9 +3684,9 @@ SWITCH_STANDARD_API(fifo_api_function)
for (hi = switch_hash_first(NULL, globals.fifo_hash); hi; hi = switch_hash_next(hi)) {
switch_hash_this(hi, &var, NULL, &val);
node = (fifo_node_t *) val;
len = node_consumer_wait_count(node);
len = node_caller_count(node);
switch_thread_rwlock_wrlock(node->rwlock);
stream->write_function(stream, "%s:%d:%d:%d\n", (char *) var, node->consumer_count, node->caller_count, len);
stream->write_function(stream, "%s:%d:%d:%d\n", (char *) var, node->consumer_count, node_caller_count(node), len);
switch_thread_rwlock_unlock(node->rwlock);
x++;
}
@@ -3698,9 +3695,9 @@ SWITCH_STANDARD_API(fifo_api_function)
stream->write_function(stream, "none\n");
}
} else if ((node = switch_core_hash_find(globals.fifo_hash, argv[1]))) {
len = node_consumer_wait_count(node);
len = node_caller_count(node);
switch_thread_rwlock_wrlock(node->rwlock);
stream->write_function(stream, "%s:%d:%d:%d\n", argv[1], node->consumer_count, node->caller_count, len);
stream->write_function(stream, "%s:%d:%d:%d\n", argv[1], node->consumer_count, node_caller_count(node), len);
switch_thread_rwlock_unlock(node->rwlock);
} else {
stream->write_function(stream, "none\n");
@@ -3710,7 +3707,7 @@ SWITCH_STANDARD_API(fifo_api_function)
for (hi = switch_hash_first(NULL, globals.fifo_hash); hi; hi = switch_hash_next(hi)) {
switch_hash_this(hi, &var, NULL, &val);
node = (fifo_node_t *) val;
len = node_consumer_wait_count(node);
len = node_caller_count(node);
switch_thread_rwlock_wrlock(node->rwlock);
stream->write_function(stream, "%s:%d\n", (char *) var, node->has_outbound);
switch_thread_rwlock_unlock(node->rwlock);
@@ -3721,7 +3718,7 @@ SWITCH_STANDARD_API(fifo_api_function)
stream->write_function(stream, "none\n");
}
} else if ((node = switch_core_hash_find(globals.fifo_hash, argv[1]))) {
len = node_consumer_wait_count(node);
len = node_caller_count(node);
switch_thread_rwlock_wrlock(node->rwlock);
stream->write_function(stream, "%s:%d\n", argv[1], node->has_outbound);
switch_thread_rwlock_unlock(node->rwlock);
@@ -4072,7 +4069,7 @@ static switch_status_t load_config(int reload, int del_all)
continue;
}
if (node_consumer_wait_count(node) || node->consumer_count || node_idle_consumers(node)) {
if (node_caller_count(node) || node->consumer_count || node_idle_consumers(node)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "%s removal delayed, still in use.\n", node->name);
node->ready = FIFO_DELAY_DESTROY;
} else {
+4 -3
View File
@@ -852,7 +852,8 @@ static void do_config(switch_bool_t reload)
const char *username = switch_xml_attr(x_list, "username");
const char *password = switch_xml_attr(x_list, "password");
const char *szinterval = switch_xml_attr(x_list, "interval");
int port = 0, interval = 0;
uint16_t port = 0;
int interval = 0;
limit_remote_t *remote;
switch_threadattr_t *thd_attr = NULL;
@@ -866,7 +867,7 @@ static void do_config(switch_bool_t reload)
}
if (!zstr(szport)) {
port = atoi(szport);
port = (uint16_t)atoi(szport);
}
if (!zstr(szinterval)) {
@@ -949,7 +950,7 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_hash_shutdown)
/* Kill remote connections, destroy needs a wrlock so we unlock after finding a pointer */
while(remote_clean) {
void *val;
const void *key;
const void *key = NULL;
switch_ssize_t keylen;
limit_remote_t *item = NULL;
+2 -3
View File
@@ -167,7 +167,7 @@ static const char *do_cid(switch_memory_pool_t *pool, const char *cid, const cha
switch_channel_t *channel = NULL;
if (!zstr(cid)) {
len = strlen(cid);
len = (uint32_t)strlen(cid);
} else {
goto done;
}
@@ -506,7 +506,7 @@ static char *expand_digits(switch_memory_pool_t *pool, char *digits, switch_bool
int digit_len;
SWITCH_STANDARD_STREAM(dig_stream);
digit_len = strlen(digits);
digit_len = (int)strlen(digits);
digits_copy = switch_core_strdup(pool, digits);
for (n = digit_len; n > 0; n--) {
@@ -1571,7 +1571,6 @@ SWITCH_STANDARD_APP(lcr_app_function)
switch_channel_set_variable(channel, vbuf, cur_route->carrier_name);
switch_snprintf(vbuf, sizeof(vbuf), "lcr_codec_%d", cnt);
switch_channel_set_variable(channel, vbuf, cur_route->codec);
cnt++;
if (cur_route->next) {
if (routes.profile->enable_sip_redir) {
dig_stream.write_function(&dig_stream, "%s,", cur_route->dialstring);
@@ -419,10 +419,10 @@ static switch_status_t do_billing(switch_core_session_t *session)
billaccount = switch_channel_get_variable(channel, "nibble_account");
if (!zstr(switch_channel_get_variable(channel, "nobal_amt"))) {
nobal_amt = atof(switch_channel_get_variable(channel, "nobal_amt"));
nobal_amt = (float)atof(switch_channel_get_variable(channel, "nobal_amt"));
}
if (!zstr(switch_channel_get_variable(channel, "lowbal_amt"))) {
lowbal_amt = atof(switch_channel_get_variable(channel, "lowbal_amt"));
lowbal_amt = (float)atof(switch_channel_get_variable(channel, "lowbal_amt"));
}
/* Return if there's no billing information on this session */
@@ -549,8 +549,8 @@ static switch_status_t do_config(void)
if (id == -1) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unable to add tone_descriptor: %s, tone: %s. (too many tones)\n", name, tone_name);
return SWITCH_STATUS_FALSE;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Adding tone_descriptor: %s, tone: %s(%d)\n", name, tone_name, id);}
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Adding tone_descriptor: %s, tone: %s(%d)\n", name, tone_name, id);
/* add elements to tone */
for (element = switch_xml_child(tone, "element"); element; element = switch_xml_next(element)) {
const char *freq1_attr = switch_xml_attr(element, "freq1");
@@ -74,6 +74,8 @@ static struct {
char header[50];
char *prepend_string;
char *spool;
switch_thread_cond_t *cond;
switch_mutex_t *cond_mutex;
} globals;
struct pvt_s {
@@ -118,27 +120,34 @@ static struct {
int thread_running;
} t38_state_list;
static void wake_thread(int force)
{
if (force) {
switch_thread_cond_signal(globals.cond);
return;
}
if (switch_mutex_trylock(globals.cond_mutex) == SWITCH_STATUS_SUCCESS) {
switch_thread_cond_signal(globals.cond);
switch_mutex_unlock(globals.cond_mutex);
}
}
static int add_pvt(pvt_t *pvt)
{
int r = 0;
uint32_t sanity = 50;
switch_mutex_lock(t38_state_list.mutex);
if (!t38_state_list.thread_running) {
launch_timer_thread();
while(--sanity && !t38_state_list.thread_running) {
switch_yield(10000);
}
}
switch_mutex_unlock(t38_state_list.mutex);
if (t38_state_list.thread_running) {
switch_mutex_lock(t38_state_list.mutex);
pvt->next = t38_state_list.head;
t38_state_list.head = pvt;
switch_mutex_unlock(t38_state_list.mutex);
r = 1;
wake_thread(0);
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error launching thread\n");
}
return r;
@@ -151,9 +160,9 @@ static int del_pvt(pvt_t *del_pvt)
pvt_t *p, *l = NULL;
int r = 0;
if (!t38_state_list.thread_running) goto end;
switch_mutex_lock(t38_state_list.mutex);
for (p = t38_state_list.head; p; p = p->next) {
if (p == del_pvt) {
if (l) {
@@ -163,34 +172,38 @@ static int del_pvt(pvt_t *del_pvt)
}
p->next = NULL;
r = 1;
goto end;
break;
}
l = p;
}
end:
switch_mutex_unlock(t38_state_list.mutex);
return r;
wake_thread(0);
return r;
}
static void *SWITCH_THREAD_FUNC timer_thread_run(switch_thread_t *thread, void *obj)
{
switch_timer_t timer = { 0 };
pvt_t *pvt;
int samples = 240;
int ms = 30;
int samples = 160;
int ms = 20;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "timer thread started.\n");
switch_mutex_lock(t38_state_list.mutex);
t38_state_list.thread_running = 1;
switch_mutex_unlock(t38_state_list.mutex);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "FAX timer thread started.\n");
if (switch_core_timer_init(&timer, "soft", ms, samples, NULL) != SWITCH_STATUS_SUCCESS) {
return NULL;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "timer init failed.\n");
goto end;
}
t38_state_list.thread_running = 1;
switch_mutex_lock(globals.cond_mutex);
while(t38_state_list.thread_running) {
@@ -198,7 +211,9 @@ static void *SWITCH_THREAD_FUNC timer_thread_run(switch_thread_t *thread, void *
if (!t38_state_list.head) {
switch_mutex_unlock(t38_state_list.mutex);
goto end;
switch_thread_cond_wait(globals.cond, globals.cond_mutex);
switch_core_timer_sync(&timer);
continue;
}
for (pvt = t38_state_list.head; pvt; pvt = pvt->next) {
@@ -211,13 +226,20 @@ static void *SWITCH_THREAD_FUNC timer_thread_run(switch_thread_t *thread, void *
switch_core_timer_next(&timer);
}
switch_mutex_unlock(globals.cond_mutex);
end:
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "timer thread ended.\n");
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "FAX timer thread ended.\n");
switch_mutex_lock(t38_state_list.mutex);
t38_state_list.thread_running = 0;
switch_core_timer_destroy(&timer);
switch_mutex_unlock(t38_state_list.mutex);
if (timer.timer_interface) {
switch_core_timer_destroy(&timer);
}
return NULL;
}
@@ -468,49 +490,61 @@ static switch_status_t spanfax_init(pvt_t *pvt, transport_mode_t trans_mode)
}
break;
case T38_MODE:
if (pvt->t38_state == NULL) {
pvt->t38_state = (t38_terminal_state_t *) switch_core_session_alloc(pvt->session, sizeof(t38_terminal_state_t));
}
if (pvt->t38_state == NULL) {
return SWITCH_STATUS_FALSE;
}
if (pvt->udptl_state == NULL) {
pvt->udptl_state = (udptl_state_t *) switch_core_session_alloc(pvt->session, sizeof(udptl_state_t));
}
if (pvt->udptl_state == NULL) {
t38_terminal_free(pvt->t38_state);
pvt->t38_state = NULL;
return SWITCH_STATUS_FALSE;
}
{
switch_core_session_message_t msg = { 0 };
/* add to timer thread processing */
add_pvt(pvt);
if (pvt->t38_state == NULL) {
pvt->t38_state = (t38_terminal_state_t *) switch_core_session_alloc(pvt->session, sizeof(t38_terminal_state_t));
}
if (pvt->t38_state == NULL) {
return SWITCH_STATUS_FALSE;
}
if (pvt->udptl_state == NULL) {
pvt->udptl_state = (udptl_state_t *) switch_core_session_alloc(pvt->session, sizeof(udptl_state_t));
}
if (pvt->udptl_state == NULL) {
t38_terminal_free(pvt->t38_state);
pvt->t38_state = NULL;
return SWITCH_STATUS_FALSE;
}
t38 = pvt->t38_state;
t30 = t38_terminal_get_t30_state(t38);
memset(t38, 0, sizeof(t38_terminal_state_t));
if (t38_terminal_init(t38, pvt->caller, t38_tx_packet_handler, pvt) == NULL) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot initialize my T.38 structs\n");
return SWITCH_STATUS_FALSE;
}
pvt->t38_core = t38_terminal_get_t38_core_state(pvt->t38_state);
if (udptl_init(pvt->udptl_state, UDPTL_ERROR_CORRECTION_REDUNDANCY, 3, 3,
(udptl_rx_packet_handler_t *) t38_core_rx_ifp_packet, (void *) pvt->t38_core) == NULL) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot initialize my UDPTL structs\n");
return SWITCH_STATUS_FALSE;
}
msg.from = __FILE__;
msg.message_id = SWITCH_MESSAGE_INDICATE_UDPTL_MODE;
switch_core_session_receive_message(pvt->session, &msg);
t38 = pvt->t38_state;
t30 = t38_terminal_get_t30_state(t38);
/* add to timer thread processing */
if (!add_pvt(pvt)) {
if (channel) {
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
}
}
span_log_set_message_handler(&t38->logging, spanfax_log_message);
span_log_set_message_handler(&t30->logging, spanfax_log_message);
memset(t38, 0, sizeof(t38_terminal_state_t));
if (t38_terminal_init(t38, pvt->caller, t38_tx_packet_handler, pvt) == NULL) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot initialize my T.38 structs\n");
return SWITCH_STATUS_FALSE;
}
pvt->t38_core = t38_terminal_get_t38_core_state(pvt->t38_state);
if (udptl_init(pvt->udptl_state, UDPTL_ERROR_CORRECTION_REDUNDANCY, 3, 3,
(udptl_rx_packet_handler_t *) t38_core_rx_ifp_packet, (void *) pvt->t38_core) == NULL) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot initialize my UDPTL structs\n");
return SWITCH_STATUS_FALSE;
}
span_log_set_message_handler(&t38->logging, spanfax_log_message);
span_log_set_message_handler(&t30->logging, spanfax_log_message);
if (pvt->verbose) {
span_log_set_level(&t38->logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
span_log_set_level(&t30->logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
}
if (pvt->verbose) {
span_log_set_level(&t38->logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
span_log_set_level(&t30->logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
}
}
break;
case T38_GATEWAY_MODE:
if (pvt->t38_gateway_state == NULL) {
@@ -757,9 +791,9 @@ static t38_mode_t negotiate_t38(pvt_t *pvt)
t38_options->T38FaxRateManagement = "transferredTCF";
t38_options->T38FaxMaxBuffer = 2000;
t38_options->T38FaxMaxDatagram = LOCAL_FAX_MAX_DATAGRAM;
if (strcasecmp(t38_options->T38FaxUdpEC, "t38UDPRedundancy") == 0
||
strcasecmp(t38_options->T38FaxUdpEC, "t38UDPFEC") == 0) {
if (!zstr(t38_options->T38FaxUdpEC) &&
(strcasecmp(t38_options->T38FaxUdpEC, "t38UDPRedundancy") == 0 ||
strcasecmp(t38_options->T38FaxUdpEC, "t38UDPFEC") == 0)) {
t38_options->T38FaxUdpEC = "t38UDPRedundancy";
} else {
t38_options->T38FaxUdpEC = NULL;
@@ -818,6 +852,12 @@ static t38_mode_t request_t38(pvt_t *pvt)
insist = globals.enable_t38_insist;
}
if ((t38_options = switch_channel_get_private(channel, "t38_options"))) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING,
"%s already has T.38 data\n", switch_channel_get_name(channel));
enabled = 0;
}
if (enabled) {
t38_options = switch_core_session_alloc(session, sizeof(*t38_options));
@@ -960,6 +1000,7 @@ void mod_spandsp_fax_process_fax(switch_core_session_t *session, const char *dat
switch_frame_t write_frame = { 0 };
switch_codec_implementation_t read_impl = { 0 };
int16_t *buf = NULL;
uint32_t req_counter = 0;
switch_core_session_get_read_impl(session, &read_impl);
@@ -1075,10 +1116,11 @@ void mod_spandsp_fax_process_fax(switch_core_session_t *session, const char *dat
switch_ivr_sleep(session, 250, SWITCH_TRUE, NULL);
/* If you have the means, I highly recommend picking one up. ...*/
request_t38(pvt);
if (pvt->app_mode == FUNCTION_TX) {
req_counter = 100;
} else {
req_counter = 50;
}
while (switch_channel_ready(channel)) {
int tx = 0;
@@ -1122,6 +1164,13 @@ void mod_spandsp_fax_process_fax(switch_core_session_t *session, const char *dat
break;
case T38_MODE_UNKNOWN:
{
if (req_counter) {
if (!--req_counter) {
/* If you have the means, I highly recommend picking one up. ...*/
request_t38(pvt);
}
}
if (switch_channel_test_app_flag_key("T38", channel, CF_APP_T38)) {
if (negotiate_t38(pvt) == T38_MODE_NEGOTIATED) {
/* is is safe to call this again, it was already called above in AUDIO_MODE */
@@ -1145,8 +1194,6 @@ void mod_spandsp_fax_process_fax(switch_core_session_t *session, const char *dat
//switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "READ %d udptl bytes\n", read_frame->packetlen);
udptl_rx_packet(pvt->udptl_state, read_frame->packet, read_frame->packetlen);
}
}
continue;
@@ -1282,6 +1329,8 @@ void mod_spandsp_fax_event_handler(switch_event_t *event)
void mod_spandsp_fax_load(switch_memory_pool_t *pool)
{
uint32_t sanity = 200;
memset(&globals, 0, sizeof(globals));
memset(&t38_state_list, 0, sizeof(t38_state_list));
@@ -1289,6 +1338,9 @@ void mod_spandsp_fax_load(switch_memory_pool_t *pool)
switch_mutex_init(&globals.mutex, SWITCH_MUTEX_NESTED, globals.pool);
switch_mutex_init(&t38_state_list.mutex, SWITCH_MUTEX_NESTED, globals.pool);
switch_mutex_init(&globals.cond_mutex, SWITCH_MUTEX_NESTED, globals.pool);
switch_thread_cond_create(&globals.cond, globals.pool);
globals.enable_t38 = 1;
globals.total_sessions = 0;
@@ -1301,10 +1353,22 @@ void mod_spandsp_fax_load(switch_memory_pool_t *pool)
strncpy(globals.header, "SpanDSP Fax Header", sizeof(globals.header) - 1);
load_configuration(0);
launch_timer_thread();
while(--sanity && !t38_state_list.thread_running) {
switch_yield(20000);
}
}
void mod_spandsp_fax_shutdown(void)
{
switch_status_t tstatus = SWITCH_STATUS_SUCCESS;
t38_state_list.thread_running = 0;
wake_thread(1);
switch_thread_join(&tstatus, t38_state_list.thread);
memset(&globals, 0, sizeof(globals));
}
@@ -1659,8 +1723,8 @@ static switch_status_t t38_gateway_on_reset(switch_core_session_t *session)
switch_channel_clear_flag(channel, CF_REDIRECT);
if (switch_channel_test_app_flag(channel, CF_APP_TAGGED)) {
switch_channel_clear_app_flag(channel, CF_APP_TAGGED);
if (switch_channel_test_app_flag_key("T38", channel, CF_APP_TAGGED)) {
switch_channel_clear_app_flag_key("T38", channel, CF_APP_TAGGED);
switch_channel_set_state(channel, CS_CONSUME_MEDIA);
} else {
switch_channel_set_state(channel, CS_SOFT_EXECUTE);
@@ -1697,6 +1761,9 @@ switch_bool_t t38_gateway_start(switch_core_session_t *session, const char *app,
switch_channel_set_variable(channel, "t38_peer", switch_core_session_get_uuid(other_session));
switch_channel_set_variable(other_channel, "t38_peer", switch_core_session_get_uuid(session));
switch_channel_set_variable(peer ? other_channel : channel, "t38_gateway_format", "audio");
switch_channel_set_variable(peer ? channel : other_channel, "t38_gateway_format", "udptl");
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s starting gateway mode to %s\n",
switch_channel_get_name(peer ? channel : other_channel),
@@ -1709,8 +1776,8 @@ switch_bool_t t38_gateway_start(switch_core_session_t *session, const char *app,
switch_channel_add_state_handler(channel, &t38_gateway_state_handlers);
switch_channel_add_state_handler(other_channel, &t38_gateway_state_handlers);
switch_channel_set_app_flag(peer ? channel : other_channel, CF_APP_TAGGED);
switch_channel_clear_app_flag(peer ? other_channel : channel, CF_APP_TAGGED);
switch_channel_set_app_flag_key("T38", peer ? channel : other_channel, CF_APP_TAGGED);
switch_channel_clear_app_flag_key("T38", peer ? other_channel : channel, CF_APP_TAGGED);
switch_channel_set_flag(channel, CF_REDIRECT);
switch_channel_set_state(channel, CS_RESET);
+4 -4
View File
@@ -93,7 +93,7 @@ static int encode_length(uint8_t *buf, int *len, int value)
if (value < 0x80) {
/* 1 octet */
buf[(*len)++] = value;
buf[(*len)++] = (uint8_t)value;
return value;
}
if (value < 0x4000) {
@@ -106,7 +106,7 @@ static int encode_length(uint8_t *buf, int *len, int value)
/* Fragmentation */
multiplier = (value < 0x10000) ? (value >> 14) : 4;
/* Set the first 2 bits of the octet */
buf[(*len)++] = 0xC0 | multiplier;
buf[(*len)++] = (uint8_t) (0xC0 | multiplier);
return multiplier << 14;
}
@@ -419,10 +419,10 @@ int udptl_build_packet(udptl_state_t *s, uint8_t buf[], const uint8_t msg[], int
/* Span is defined as an inconstrained integer, which it dumb. It will only
ever be a small value. Treat it as such. */
buf[len++] = 1;
buf[len++] = span;
buf[len++] = (uint8_t)span;
/* The number of entries is defined as a length, but will only ever be a small
value. Treat it as such. */
buf[len++] = entries;
buf[len++] = (uint8_t)entries;
for (m = 0; m < entries; m++) {
/* Make an XOR'ed entry the maximum length */
limit = (entry + m) & UDPTL_BUF_MASK;
@@ -203,7 +203,7 @@ SWITCH_STANDARD_APP(valet_parking_function)
}
do {
status = switch_ivr_read(session, min, max, prompt, NULL, dtmf_buf, sizeof(dtmf_buf), to, "#");
status = switch_ivr_read(session, min, max, prompt, NULL, dtmf_buf, sizeof(dtmf_buf), to, "#", 0);
} while (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_FALSE);
if (status == SWITCH_STATUS_SUCCESS) {
@@ -824,7 +824,8 @@ static switch_status_t control_playback(switch_core_session_t *session, void *in
if (!cc->noexit
&& (dtmf->digit == *cc->profile->delete_file_key || dtmf->digit == *cc->profile->save_file_key
|| dtmf->digit == *cc->profile->prev_msg_key || dtmf->digit == *cc->profile->next_msg_key
|| dtmf->digit == *cc->profile->terminator_key || dtmf->digit == *cc->profile->skip_info_key)) {
|| dtmf->digit == *cc->profile->terminator_key || dtmf->digit == *cc->profile->skip_info_key
|| dtmf->digit == *cc->profile->email_key || dtmf->digit == *cc->profile->forward_key)) {
*cc->buf = dtmf->digit;
return SWITCH_STATUS_BREAK;
}
@@ -1421,6 +1422,7 @@ static switch_status_t listen_file(switch_core_session_t *session, vm_profile_t
char cid_buf[1024] = "";
if (switch_channel_ready(channel)) {
const char *vm_announce_cid = NULL;
switch_snprintf(cid_buf, sizeof(cid_buf), "%s|%s", cbt->cid_number, cbt->cid_name);
@@ -1428,7 +1430,13 @@ static switch_status_t listen_file(switch_core_session_t *session, vm_profile_t
msg.string_arg = cid_buf;
msg.message_id = SWITCH_MESSAGE_INDICATE_DISPLAY;
switch_core_session_receive_message(session, &msg);
if (!zstr(cbt->cid_number) && (vm_announce_cid = switch_channel_get_variable(channel, "vm_announce_cid"))) {
switch_ivr_play_file(session, NULL, vm_announce_cid, NULL);
switch_ivr_sleep(session, 500, SWITCH_TRUE, NULL);
switch_ivr_say(session, cbt->cid_number, NULL, "name_spelled", "pronounced", NULL, NULL);
}
args.input_callback = cancel_on_dtmf;
switch_snprintf(key_buf, sizeof(key_buf), "%s:%s:%s:%s:%s:%s%s%s", profile->listen_file_key, profile->save_file_key,
@@ -1523,7 +1531,7 @@ static switch_status_t listen_file(switch_core_session_t *session, vm_profile_t
vm_cc[0] = '\0';
TRY_CODE(switch_ivr_read
(session, 0, sizeof(vm_cc), macro_buf, NULL, vm_cc, sizeof(vm_cc), profile->digit_timeout, profile->terminator_key));
(session, 0, sizeof(vm_cc), macro_buf, NULL, vm_cc, sizeof(vm_cc), profile->digit_timeout, profile->terminator_key, 0));
cmd = switch_core_session_sprintf(session, "%s@%s %s %s '%s'", vm_cc, cbt->domain, new_file_path, cbt->cid_number, cbt->cid_name);
@@ -1987,7 +1995,7 @@ static void voicemail_check_main(switch_core_session_t *session, vm_profile_t *p
switch_xml_t xx_user, xx_domain, xx_domain_root;
switch_snprintf(macro, sizeof(macro), "phrase:%s:%s", VM_ENTER_PASS_MACRO, profile->terminator_key);
TRY_CODE(switch_ivr_read(session, 0, 255, macro, NULL, buf, sizeof(buf), 10000, profile->terminator_key));
TRY_CODE(switch_ivr_read(session, 0, 255, macro, NULL, buf, sizeof(buf), 10000, profile->terminator_key, 0));
sql = switch_mprintf("update voicemail_prefs set password='%s' where username='%s' and domain='%s'", buf, myid, domain_name);
vm_execute_sql(profile, sql, profile->mutex);
switch_safe_free(file_path);
@@ -2686,23 +2694,29 @@ static switch_status_t voicemail_inject(const char *data, switch_core_session_t
if ((domain = strchr(user, '@'))) {
*domain++ = '\0';
} else {
domain = user;
}
if ((profile_name = strchr(domain, '@'))) {
*profile_name++ = '\0';
} else {
profile_name = domain;
if ((profile_name = strchr(domain, '@'))) {
*profile_name++ = '\0';
} else {
profile_name = domain;
}
}
if (switch_stristr("group=", user)) {
user += 6;
isgroup++;
} else if (user == domain) {
} else if (switch_stristr("domain=", user)) {
user += 7;
domain = user;
profile_name = domain;
isall++;
}
if (zstr(domain)) {
domain = switch_core_get_variable("domain");
profile_name = domain;
}
if (!(user && domain)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid syntax [%s][%s]\n", switch_str_nil(user), switch_str_nil(domain));
status = SWITCH_STATUS_FALSE;
@@ -2746,6 +2760,7 @@ static switch_status_t voicemail_inject(const char *data, switch_core_session_t
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Cannot locate domain %s\n", domain);
status = SWITCH_STATUS_FALSE;
switch_event_destroy(&my_params);
profile_rwunlock(profile);
goto end;
}
@@ -3164,7 +3179,7 @@ static switch_status_t voicemail_leave_main(switch_core_session_t *session, vm_p
switch_event_destroy(&vars);
if (status == SWITCH_STATUS_SUCCESS) {
if ((vm_cc = switch_channel_get_variable(channel, "vm_cc"))) {
char *cmd = switch_core_session_sprintf(session, "%s %s %s %s %s@%s %s",
char *cmd = switch_core_session_sprintf(session, "%s %s %s '%s' %s@%s %s",
vm_cc, file_path, caller_id_number, caller_id_name, id, domain_name, read_flags);
if (voicemail_inject(cmd, session) == SWITCH_STATUS_SUCCESS) {
@@ -3670,7 +3685,7 @@ static int web_callback(void *pArg, int argc, char **argv, char **columnNames)
const char *fmt = "%a, %e %b %Y %T %z";
char heard[80];
char title_b4[128] = "";
char title_aft[128 * 3] = "";
char title_aft[128 * 3 + 1] = "";
if (argc > 0) {
l_created = switch_time_make(atol(argv[0]), 0);
@@ -3961,7 +3976,7 @@ static void do_web(vm_profile_t *profile, const char *user_in, const char *domai
}
}
#define VM_INJECT_USAGE "[group=]<box> <sound_file> [<cid_num>] [<cid_name>]"
#define VM_INJECT_USAGE "[group=<group>[@domain]|domain=<domain>|<box>[@<domain>]] <sound_file> [<cid_num>] [<cid_name>]"
SWITCH_STANDARD_API(voicemail_inject_api_function)
{
if (voicemail_inject(cmd, session) == SWITCH_STATUS_SUCCESS) {
+1 -1
View File
@@ -2724,7 +2724,7 @@ static switch_status_t recog_asr_open(switch_asr_handle_t *ah, const char *codec
name++;
name = switch_core_sprintf(ah->memory_pool, "%s ASR-%d", name, speech_channel_number);
} else {
name = switch_core_sprintf(ah->memory_pool, "ASR-%d", name, speech_channel_number);
name = switch_core_sprintf(ah->memory_pool, "ASR-%d", speech_channel_number);
}
/* Allocate the channel */
+111 -57
View File
@@ -98,11 +98,8 @@ typedef enum {
AMR_DTX_ENABLED
} amr_dtx_t;
struct amr_context {
void *encoder_state;
void *decoder_state;
switch_byte_t enc_modes;
switch_byte_t enc_mode;
/*! \brief Various codec settings */
struct amr_codec_settings {
int dtx_mode;
uint32_t change_period;
switch_byte_t max_ptime;
@@ -110,6 +107,24 @@ struct amr_context {
switch_byte_t channels;
switch_byte_t flags;
};
typedef struct amr_codec_settings amr_codec_settings_t;
static amr_codec_settings_t default_codec_settings = {
/*.dtx_mode */ AMR_DTX_ENABLED,
/*.change_period */ 0,
/*.max_ptime */ 0,
/*.ptime */ 0,
/*.channels */ 0,
/*.flags */ 0,
};
struct amr_context {
void *encoder_state;
void *decoder_state;
switch_byte_t enc_modes;
switch_byte_t enc_mode;
};
#define AMR_DEFAULT_BITRATE AMR_BITRATE_1220
@@ -117,6 +132,88 @@ static struct {
switch_byte_t default_bitrate;
} globals;
static switch_status_t switch_amr_fmtp_parse(const char *fmtp, switch_codec_fmtp_t *codec_fmtp)
{
if (codec_fmtp) {
amr_codec_settings_t *codec_settings = NULL;
if (codec_fmtp->private_info) {
codec_settings = codec_fmtp->private_info;
memcpy(codec_settings, &default_codec_settings, sizeof(*codec_settings));
}
if (fmtp) {
int x, argc;
char *argv[10];
char *fmtp_dup = strdup(fmtp);
switch_assert(fmtp_dup);
argc = switch_separate_string((char *) fmtp_dup, ';', argv, (sizeof(argv) / sizeof(argv[0])));
for (x = 0; x < argc; x++) {
char *data = argv[x];
char *arg;
switch_assert(data);
while (*data == ' ') {
data++;
}
if ((arg = strchr(data, '='))) {
*arg++ = '\0';
/*
if (!strcasecmp(data, "bitrate")) {
bit_rate = atoi(arg);
}
*/
if (codec_settings) {
if (!strcasecmp(data, "octet-align")) {
if (atoi(arg)) {
switch_set_flag(codec_settings, AMR_OPT_OCTET_ALIGN);
}
} else if (!strcasecmp(data, "mode-change-neighbor")) {
if (atoi(arg)) {
switch_set_flag(codec_settings, AMR_OPT_MODE_CHANGE_NEIGHBOR);
}
} else if (!strcasecmp(data, "crc")) {
if (atoi(arg)) {
switch_set_flag(codec_settings, AMR_OPT_CRC);
}
} else if (!strcasecmp(data, "robust-sorting")) {
if (atoi(arg)) {
switch_set_flag(codec_settings, AMR_OPT_ROBUST_SORTING);
}
} else if (!strcasecmp(data, "interveaving")) {
if (atoi(arg)) {
switch_set_flag(codec_settings, AMR_OPT_INTERLEAVING);
}
} else if (!strcasecmp(data, "mode-change-period")) {
codec_settings->change_period = atoi(arg);
} else if (!strcasecmp(data, "ptime")) {
codec_settings->ptime = (switch_byte_t) atoi(arg);
} else if (!strcasecmp(data, "channels")) {
codec_settings->channels = (switch_byte_t) atoi(arg);
} else if (!strcasecmp(data, "maxptime")) {
codec_settings->max_ptime = (switch_byte_t) atoi(arg);
} else if (!strcasecmp(data, "mode-set")) {
int y, m_argc;
char *m_argv[7];
m_argc = switch_separate_string(arg, ',', m_argv, (sizeof(m_argv) / sizeof(m_argv[0])));
for (y = 0; y < m_argc; y++) {
codec_settings->enc_modes |= (1 << atoi(m_argv[y]));
}
} else if (!strcasecmp(data, "dtx")) {
codec_settings->dtx_mode = (atoi(arg)) ? AMR_DTX_ENABLED : AMR_DTX_DISABLED;
}
}
}
}
free(fmtp_dup);
}
//codec_fmtp->bits_per_second = bit_rate;
return SWITCH_STATUS_SUCCESS;
}
return SWITCH_STATUS_FALSE;
}
#endif
static switch_status_t switch_amr_init(switch_codec_t *codec, switch_codec_flag_t flags, const switch_codec_settings_t *codec_settings)
@@ -128,7 +225,10 @@ static switch_status_t switch_amr_init(switch_codec_t *codec, switch_codec_flag_
}
return SWITCH_STATUS_SUCCESS;
#else
struct amr_context *context = NULL;
switch_codec_fmtp_t codec_fmtp;
amr_codec_settings_t amr_codec_settings;
int encoding, decoding;
int x, i, argc;
char *argv[10];
@@ -141,58 +241,9 @@ static switch_status_t switch_amr_init(switch_codec_t *codec, switch_codec_flag_
return SWITCH_STATUS_FALSE;
} else {
context->dtx_mode = AMR_DTX_ENABLED;
if (codec->fmtp_in) {
argc = switch_separate_string(codec->fmtp_in, ';', argv, (sizeof(argv) / sizeof(argv[0])));
for (x = 0; x < argc; x++) {
char *data = argv[x];
char *arg;
while (*data && *data == ' ') {
data++;
}
if ((arg = strchr(data, '='))) {
*arg++ = '\0';
if (!strcasecmp(data, "octet-align")) {
if (atoi(arg)) {
switch_set_flag(context, AMR_OPT_OCTET_ALIGN);
}
} else if (!strcasecmp(data, "mode-change-neighbor")) {
if (atoi(arg)) {
switch_set_flag(context, AMR_OPT_MODE_CHANGE_NEIGHBOR);
}
} else if (!strcasecmp(data, "crc")) {
if (atoi(arg)) {
switch_set_flag(context, AMR_OPT_CRC);
}
} else if (!strcasecmp(data, "robust-sorting")) {
if (atoi(arg)) {
switch_set_flag(context, AMR_OPT_ROBUST_SORTING);
}
} else if (!strcasecmp(data, "interveaving")) {
if (atoi(arg)) {
switch_set_flag(context, AMR_OPT_INTERLEAVING);
}
} else if (!strcasecmp(data, "mode-change-period")) {
context->change_period = atoi(arg);
} else if (!strcasecmp(data, "ptime")) {
context->ptime = (switch_byte_t) atoi(arg);
} else if (!strcasecmp(data, "channels")) {
context->channels = (switch_byte_t) atoi(arg);
} else if (!strcasecmp(data, "maxptime")) {
context->max_ptime = (switch_byte_t) atoi(arg);
} else if (!strcasecmp(data, "mode-set")) {
int y, m_argc;
char *m_argv[7];
m_argc = switch_separate_string(arg, ',', m_argv, (sizeof(m_argv) / sizeof(m_argv[0])));
for (y = 0; y < m_argc; y++) {
context->enc_modes |= (1 << atoi(m_argv[y]));
}
} else if (!strcasecmp(data, "dtx")) {
context->dtx_mode = (atoi(arg)) ? AMR_DTX_ENABLED : AMR_DTX_DISABLED;
}
}
}
}
memset(&codec_fmtp, '\0', sizeof(struct switch_codec_fmtp));
codec_fmtp.private_info = &amr_codec_settings;
switch_amr_fmtp_parse(codec->fmtp_in, &codec_fmtp);
if (context->enc_modes) {
for (i = 7; i > -1; i++) {
@@ -321,6 +372,9 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_amr_load)
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
SWITCH_ADD_CODEC(codec_interface, "AMR");
#ifndef AMR_PASSTHROUGH
codec_interface->parse_fmtp = switch_amr_fmtp_parse;
#endif
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
96, /* the IANA code number */
"AMR", /* the IANA code name */
+14
View File
@@ -0,0 +1,14 @@
BASE=../../../..
CODEC2_DIR=$(switch_srcdir)/libs/libcodec2
CODEC2_BUILDDIR=$(switch_builddir)/libs/libcodec2
CODEC2LA=$(CODEC2_BUILDDIR)/src/libcodec2.la
LOCAL_CFLAGS=-I$(CODEC2_DIR)/include -I$(CODEC2_BUILDDIR)/src
LOCAL_LIBADD=$(CODEC2LA)
include $(BASE)/build/modmake.rules
$(CODEC2LA): $(CODEC2_DIR) $(CODEC2_DIR)/.update
cd $(CODEC2_BUILDDIR) && $(MAKE)
$(TOUCH_TARGET)
+264
View File
@@ -0,0 +1,264 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is FreeSWITCH Modular Media Switching Software Library
*
* The Initial Developer of the Original Code is
* Brian West <brian@freeswitch.org>
* Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Mathieu Rene <mrene@avgs.ca>
*
* mod_codec2 -- FreeSWITCH CODEC2 Module
*
*/
#include <switch.h>
#include <codec2.h>
/* Uncomment to log input/output data for debugging
#define LOG_DATA
#define CODEC2_DEBUG
*/
#ifdef CODEC2_DEBUG
#define codec2_assert(_x) switch_assert(_x)
#else
#define codec2_assert(_x)
#endif
SWITCH_MODULE_LOAD_FUNCTION(mod_codec2_load);
SWITCH_MODULE_DEFINITION(mod_codec2, mod_codec2_load, NULL, NULL);
struct codec2_context {
void *encoder;
void *decoder;
#ifdef LOG_DATA
FILE *encoder_in;
FILE *encoder_out;
FILE *encoder_out_unpacked;
FILE *decoder_in;
FILE *decoder_in_unpacked;
FILE *decoder_out;
#endif
};
#ifdef LOG_DATA
static int c2_count = 0;
#endif
static switch_status_t switch_codec2_init(switch_codec_t *codec, switch_codec_flag_t flags, const switch_codec_settings_t *codec_settings)
{
uint32_t encoding, decoding;
struct codec2_context *context = NULL;
encoding = (flags & SWITCH_CODEC_FLAG_ENCODE);
decoding = (flags & SWITCH_CODEC_FLAG_DECODE);
if (!(encoding || decoding)) {
return SWITCH_STATUS_FALSE;
}
if (!(context = switch_core_alloc(codec->memory_pool, sizeof(*context)))) {
return SWITCH_STATUS_FALSE;
}
if (encoding) {
context->encoder = codec2_create();
}
if (decoding) {
context->decoder = codec2_create();
}
codec->private_info = context;
#ifdef LOG_DATA
{
int c = c2_count++;
char buf[1024];
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Logging as /tmp/c2-%d-*\n", c);
if (encoding) {
snprintf(buf, sizeof(buf), "/tmp/c2-%d-enc-in", c);
context->encoder_in = fopen(buf, "w");
snprintf(buf, sizeof(buf), "/tmp/c2-%d-enc-out", c);
context->encoder_out = fopen(buf, "w");
snprintf(buf, sizeof(buf), "/tmp/c2-%d-enc-out-unpacked", c);
context->encoder_out_unpacked = fopen(buf, "w");
}
if (decoding) {
snprintf(buf, sizeof(buf), "/tmp/c2-%d-dec-in", c);
context->decoder_in = fopen(buf, "w");
snprintf(buf, sizeof(buf), "/tmp/c2-%d-dec-out", c);
context->decoder_out = fopen(buf, "w");
snprintf(buf, sizeof(buf), "/tmp/c2-%d-dec-out-unpacked", c);
context->decoder_in_unpacked = fopen(buf, "w");
}
}
#endif
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t switch_codec2_encode(switch_codec_t *codec, switch_codec_t *other_codec,
void *decoded_data,
uint32_t decoded_data_len,
uint32_t decoded_rate,
void *encoded_data,
uint32_t *encoded_data_len,
uint32_t *encoded_rate,
unsigned int *flag)
{
struct codec2_context *context = codec->private_info;
codec2_assert(decoded_data_len == CODEC2_SAMPLES_PER_FRAME * 2);
#ifdef LOG_DATA
fwrite(decoded_data, decoded_data_len, 1, context->encoder_in);
fflush(context->encoder_in);
#endif
codec2_encode(context->encoder, encoded_data, decoded_data);
#ifdef LOG_DATA
fwrite(encode_buf, sizeof(encode_buf), 1, context->encoder_out_unpacked);
fflush(context->encoder_out_unpacked);
fwrite(encoded_data, 8, 1, context->encoder_out);
fflush(context->encoder_out);
#endif
*encoded_data_len = 8;
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t switch_codec2_decode(switch_codec_t *codec,
switch_codec_t *other_codec,
void *encoded_data,
uint32_t encoded_data_len,
uint32_t encoded_rate,
void *decoded_data,
uint32_t *decoded_data_len,
uint32_t *decoded_rate,
unsigned int *flag)
{
struct codec2_context *context = codec->private_info;
codec2_assert(encoded_data_len == 8 /* aligned to 8 */);
#ifdef LOG_DATA
fwrite(encoded_data, encoded_data_len, 1, context->decoder_in);
fflush(context->decoder_in);
fwrite(bits, sizeof(bits), 1, context->decoder_in_unpacked);
fflush(context->decoder_in_unpacked);
#endif
codec2_decode(context->decoder, decoded_data, encoded_data);
#ifdef LOG_DATA
fwrite(decoded_data, CODEC2_SAMPLES_PER_FRAME, 2, context->decoder_out);
fflush(context->decoder_out);
#endif
*decoded_data_len = CODEC2_SAMPLES_PER_FRAME * 2; /* 160 samples */
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t switch_codec2_destroy(switch_codec_t *codec)
{
struct codec2_context *context = codec->private_info;
codec2_destroy(context->encoder);
codec2_destroy(context->decoder);
context->encoder = NULL;
context->decoder = NULL;
#ifdef LOG_DATA
if (context->encoder_in) {
fclose(context->encoder_in);
}
if (context->encoder_out) {
fclose(context->encoder_out);
}
if (context->encoder_out_unpacked) {
fclose(context->encoder_out_unpacked);
}
if (context->decoder_in) {
fclose(context->decoder_in);
}
if (context->decoder_in_unpacked) {
fclose(context->decoder_in_unpacked);
}
if (context->decoder_out) {
fclose(context->decoder_out);
}
#endif
return SWITCH_STATUS_SUCCESS;
}
SWITCH_MODULE_LOAD_FUNCTION(mod_codec2_load)
{
switch_codec_interface_t *codec_interface;
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
SWITCH_ADD_CODEC(codec_interface, "CODEC2 2550bps");
switch_core_codec_add_implementation(pool, codec_interface,
SWITCH_CODEC_TYPE_AUDIO,
111,
"CODEC2",
NULL,
8000, /* samples/sec */
8000, /* samples/sec */
2550, /* bps */
20000, /* ptime */
CODEC2_SAMPLES_PER_FRAME, /* samples decoded */
CODEC2_SAMPLES_PER_FRAME*2, /* bytes decoded */
0, /* bytes encoded */
1, /* channels */
1, /* frames/packet */
switch_codec2_init,
switch_codec2_encode,
switch_codec2_decode,
switch_codec2_destroy);
return SWITCH_STATUS_SUCCESS;
}
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4:
*/
+22 -20
View File
@@ -40,6 +40,27 @@ struct ilbc_context {
ilbc_decode_state_t decoder_object;
};
static switch_status_t switch_ilbc_fmtp_parse(const char *fmtp, switch_codec_fmtp_t *codec_fmtp)
{
if (codec_fmtp) {
char *mode = NULL;
int codec_ms = 0;
memset(codec_fmtp, '\0', sizeof(struct switch_codec_fmtp));
if (fmtp && (mode = strstr(fmtp, "mode=")) && (mode + 5)) {
codec_ms = atoi(mode + 5);
}
if (!codec_ms) {
/* default to 30 when no mode is defined for ilbc ONLY */
codec_ms = 30;
}
codec_fmtp->microseconds_per_packet = (codec_ms * 1000);
return SWITCH_STATUS_SUCCESS;
}
return SWITCH_STATUS_FALSE;
}
static switch_status_t switch_ilbc_init(switch_codec_t *codec, switch_codec_flag_t flags, const switch_codec_settings_t *codec_settings)
{
struct ilbc_context *context;
@@ -51,26 +72,6 @@ static switch_status_t switch_ilbc_init(switch_codec_t *codec, switch_codec_flag
return SWITCH_STATUS_FALSE;
}
if (codec->fmtp_in) {
int x, argc;
char *argv[10];
argc = switch_separate_string(codec->fmtp_in, ';', argv, (sizeof(argv) / sizeof(argv[0])));
for (x = 0; x < argc; x++) {
char *data = argv[x];
char *arg;
switch_assert(data);
while (*data == ' ') {
data++;
}
if ((arg = strchr(data, '='))) {
*arg++ = '\0';
if (!strcasecmp(data, "mode")) {
mode = atoi(arg);
}
}
}
}
codec->fmtp_out = switch_core_sprintf(codec->memory_pool, "mode=%d", mode);
if (encoding) {
@@ -136,6 +137,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_ilbc_load)
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
SWITCH_ADD_CODEC(codec_interface, "iLBC");
codec_interface->parse_fmtp = switch_ilbc_fmtp_parse;
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
98, /* the IANA code number */
+123 -76
View File
@@ -41,6 +41,22 @@ SWITCH_MODULE_DEFINITION(mod_silk, mod_silk_load, NULL, NULL);
#define MAX_LBRR_DELAY 2
#define MAX_FRAME_LENGTH 480
/*! \brief Various codec settings */
struct silk_codec_settings {
SKP_int useinbandfec;
SKP_int usedtx;
SKP_int maxaveragebitrate;
SKP_int plpct;
};
typedef struct silk_codec_settings silk_codec_settings_t;
static silk_codec_settings_t default_codec_settings = {
/*.useinbandfec */ 0,
/*.usedtx */ 0,
/*.maxaveragebitrate */ 0,
/*.plpct */ 10, // 10% for now
};
struct silk_context {
SKP_SILK_SDK_EncControlStruct encoder_object;
SKP_SILK_SDK_DecControlStruct decoder_object;
@@ -48,12 +64,105 @@ struct silk_context {
void *dec_state;
};
static switch_status_t switch_silk_fmtp_parse(const char *fmtp, switch_codec_fmtp_t *codec_fmtp)
{
if (codec_fmtp) {
silk_codec_settings_t *codec_settings = NULL;
if (codec_fmtp->private_info) {
codec_settings = codec_fmtp->private_info;
memcpy(codec_settings, &default_codec_settings, sizeof(*codec_settings));
}
if (fmtp) {
int x, argc;
char *argv[10];
char *fmtp_dup = strdup(fmtp);
switch_assert(fmtp_dup);
argc = switch_separate_string(fmtp_dup, ';', argv, (sizeof(argv) / sizeof(argv[0])));
for (x = 0; x < argc; x++) {
char *data = argv[x];
char *arg;
switch_assert(data);
while (*data == ' ') {
data++;
}
if ((arg = strchr(data, '='))) {
*arg++ = '\0';
if (codec_settings) {
if (!strcasecmp(data, "useinbandfec")) {
if (switch_true(arg)) {
codec_settings->useinbandfec = 1;
}
}
if (!strcasecmp(data, "usedtx")) {
if (switch_true(arg)) {
codec_settings->usedtx = 1;
}
}
if (!strcasecmp(data, "maxaveragebitrate")) {
codec_settings->maxaveragebitrate = atoi(arg);
switch(codec_fmtp->actual_samples_per_second) {
case 8000:
{
if(codec_settings->maxaveragebitrate < 6000 || codec_settings->maxaveragebitrate > 20000) {
codec_settings->maxaveragebitrate = 20000;
}
break;
}
case 12000:
{
if(codec_settings->maxaveragebitrate < 7000 || codec_settings->maxaveragebitrate > 25000) {
codec_settings->maxaveragebitrate = 25000;
}
break;
}
case 16000:
{
if(codec_settings->maxaveragebitrate < 8000 || codec_settings->maxaveragebitrate > 30000) {
codec_settings->maxaveragebitrate = 30000;
}
break;
}
case 24000:
{
if(codec_settings->maxaveragebitrate < 12000 || codec_settings->maxaveragebitrate > 40000) {
codec_settings->maxaveragebitrate = 40000;
}
break;
}
default:
/* this should never happen but 20000 is common among all rates */
codec_settings->maxaveragebitrate = 20000;
break;
}
}
}
}
}
free(fmtp_dup);
}
//codec_fmtp->bits_per_second = bit_rate;
return SWITCH_STATUS_SUCCESS;
}
return SWITCH_STATUS_FALSE;
}
static switch_status_t switch_silk_init(switch_codec_t *codec,
switch_codec_flag_t freeswitch_flags,
const switch_codec_settings_t *codec_settings)
{
struct silk_context *context = NULL;
SKP_int useinbandfec = 0, usedtx = 0, maxaveragebitrate = 0, plpct =0;
switch_codec_fmtp_t codec_fmtp;
silk_codec_settings_t silk_codec_settings;
SKP_int32 encSizeBytes;
SKP_int32 decSizeBytes;
int encoding = (freeswitch_flags & SWITCH_CODEC_FLAG_ENCODE);
@@ -62,78 +171,15 @@ static switch_status_t switch_silk_init(switch_codec_t *codec,
if (!(encoding || decoding) || (!(context = switch_core_alloc(codec->memory_pool, sizeof(*context))))) {
return SWITCH_STATUS_FALSE;
}
if (codec->fmtp_in) {
int x, argc;
char *argv[10];
argc = switch_separate_string(codec->fmtp_in, ';', argv, (sizeof(argv) / sizeof(argv[0])));
for (x = 0; x < argc; x++) {
char *data = argv[x];
char *arg;
switch_assert(data);
while (*data == ' ') {
data++;
}
if ((arg = strchr(data, '='))) {
*arg++ = '\0';
if (!strcasecmp(data, "useinbandfec")) {
if (switch_true(arg)) {
useinbandfec = 1;
plpct = 10;// 10% for now
}
}
if (!strcasecmp(data, "usedtx")) {
if (switch_true(arg)) {
usedtx = 1;
}
}
if (!strcasecmp(data, "maxaveragebitrate")) {
maxaveragebitrate = atoi(arg);
switch(codec->implementation->actual_samples_per_second) {
case 8000:
{
if(maxaveragebitrate < 6000 || maxaveragebitrate > 20000) {
maxaveragebitrate = 20000;
}
break;
}
case 12000:
{
if(maxaveragebitrate < 7000 || maxaveragebitrate > 25000) {
maxaveragebitrate = 25000;
}
break;
}
case 16000:
{
if(maxaveragebitrate < 8000 || maxaveragebitrate > 30000) {
maxaveragebitrate = 30000;
}
break;
}
case 24000:
{
if(maxaveragebitrate < 12000 || maxaveragebitrate > 40000) {
maxaveragebitrate = 40000;
}
break;
}
default:
/* this should never happen but 20000 is common among all rates */
maxaveragebitrate = 20000;
break;
}
}
}
}
}
memset(&codec_fmtp, '\0', sizeof(struct switch_codec_fmtp));
codec_fmtp.private_info = &silk_codec_settings;
switch_silk_fmtp_parse(codec->fmtp_in, &codec_fmtp);
codec->fmtp_out = switch_core_sprintf(codec->memory_pool, "useinbandfec=%s; usedtx=%s; maxaveragebitrate=%d",
useinbandfec ? "1" : "0",
usedtx ? "1" : "0",
maxaveragebitrate ? maxaveragebitrate : codec->implementation->bits_per_second);
silk_codec_settings.useinbandfec ? "1" : "0",
silk_codec_settings.usedtx ? "1" : "0",
silk_codec_settings.maxaveragebitrate ? silk_codec_settings.maxaveragebitrate : codec->implementation->bits_per_second);
if (encoding) {
if (SKP_Silk_SDK_Get_Encoder_Size(&encSizeBytes)) {
@@ -148,11 +194,11 @@ static switch_status_t switch_silk_init(switch_codec_t *codec,
context->encoder_object.sampleRate = codec->implementation->actual_samples_per_second;
context->encoder_object.packetSize = codec->implementation->samples_per_packet;
context->encoder_object.useInBandFEC = useinbandfec;
context->encoder_object.useInBandFEC = silk_codec_settings.useinbandfec;
context->encoder_object.complexity = 0;
context->encoder_object.bitRate = maxaveragebitrate ? maxaveragebitrate : codec->implementation->bits_per_second;
context->encoder_object.useDTX = usedtx;
context->encoder_object.packetLossPercentage = plpct;;
context->encoder_object.bitRate = silk_codec_settings.maxaveragebitrate ? silk_codec_settings.maxaveragebitrate : codec->implementation->bits_per_second;
context->encoder_object.useDTX = silk_codec_settings.usedtx;
context->encoder_object.packetLossPercentage = silk_codec_settings.plpct;
}
if (decoding) {
@@ -174,7 +220,7 @@ static switch_status_t switch_silk_init(switch_codec_t *codec,
static switch_status_t switch_silk_destroy(switch_codec_t *codec)
{
codec->private_info = NULL;
codec->private_info = NULL;
return SWITCH_STATUS_SUCCESS;
}
@@ -299,6 +345,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_silk_load)
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
SWITCH_ADD_CODEC(codec_interface, "SILK");
codec_interface->parse_fmtp = switch_silk_fmtp_parse;
switch_core_codec_add_implementation(pool, codec_interface,
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
117, /* the IANA code number */
+56 -20
View File
@@ -47,6 +47,40 @@ struct siren_context {
g722_1_encode_state_t encoder_object;
};
static switch_status_t switch_siren_fmtp_parse(const char *fmtp, switch_codec_fmtp_t *codec_fmtp)
{
if (codec_fmtp) {
int bit_rate = 0;
memset(codec_fmtp, '\0', sizeof(struct switch_codec_fmtp));
if (fmtp) {
int x, argc;
char *argv[10];
char *fmtp_dup = strdup(fmtp);
switch_assert(fmtp_dup);
argc = switch_separate_string(fmtp_dup, ';', argv, (sizeof(argv) / sizeof(argv[0])));
for (x = 0; x < argc; x++) {
char *data = argv[x];
char *arg;
switch_assert(data);
while (*data == ' ') {
data++;
}
if ((arg = strchr(data, '='))) {
*arg++ = '\0';
if (!strcasecmp(data, "bitrate")) {
bit_rate = atoi(arg);
}
}
}
free(fmtp_dup);
}
codec_fmtp->bits_per_second = bit_rate;
return SWITCH_STATUS_SUCCESS;
}
return SWITCH_STATUS_FALSE;
}
static switch_status_t switch_siren_init(switch_codec_t *codec, switch_codec_flag_t flags, const switch_codec_settings_t *codec_settings)
{
struct siren_context *context = NULL;
@@ -58,26 +92,6 @@ static switch_status_t switch_siren_init(switch_codec_t *codec, switch_codec_fla
return SWITCH_STATUS_FALSE;
}
if (codec->fmtp_in) {
int x, argc;
char *argv[10];
argc = switch_separate_string(codec->fmtp_in, ';', argv, (sizeof(argv) / sizeof(argv[0])));
for (x = 0; x < argc; x++) {
char *data = argv[x];
char *arg;
switch_assert(data);
while (*data == ' ') {
data++;
}
if ((arg = strchr(data, '='))) {
*arg++ = '\0';
if (!strcasecmp(data, "bitrate")) {
bit_rate = atoi(arg);
}
}
}
}
codec->fmtp_out = switch_core_sprintf(codec->memory_pool, "bitrate=%d", bit_rate);
if (encoding) {
@@ -145,6 +159,28 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_siren_load)
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
SWITCH_ADD_CODEC(codec_interface, "Polycom(R) G722.1/G722.1C");
codec_interface->parse_fmtp = switch_siren_fmtp_parse;
spf = 320, bpf = 640;
for (count = 3; count > 0; count--) {
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
107, /* the IANA code number */
"G7221", /* the IANA code name */
"bitrate=24000", /* default fmtp to send (can be overridden by the init function) */
16000, /* samples transferred per second */
16000, /* actual samples transferred per second */
24000, /* bits transferred per second */
mpf * count, /* number of microseconds per frame */
spf * count, /* number of samples per frame */
bpf * count, /* number of bytes per frame decompressed */
0, /* number of bytes per frame compressed */
1, /* number of channels represented */
1, /* number of frames per network packet */
switch_siren_init, /* function to initialize a codec handle using this implementation */
switch_siren_encode, /* function to encode raw data into encoded data */
switch_siren_decode, /* function to decode encoded data into raw data */
switch_siren_destroy); /* deinitalize a codec handle using this implementation */
}
spf = 320, bpf = 640;
for (count = 3; count > 0; count--) {
+123 -30
View File
@@ -37,7 +37,46 @@
SWITCH_MODULE_LOAD_FUNCTION(mod_speex_load);
SWITCH_MODULE_DEFINITION(mod_speex, mod_speex_load, NULL, NULL);
static switch_codec_settings_t default_codec_settings = {
/* nobody has more setting than speex so we will let them set the standard */
/*! \brief Various codec settings (currently only relevant to speex) */
struct speex_codec_settings {
/*! desired quality */
int quality;
/*! desired complexity */
int complexity;
/*! desired enhancement */
int enhancement;
/*! desired vad level */
int vad;
/*! desired vbr level */
int vbr;
/*! desired vbr quality */
float vbr_quality;
/*! desired abr level */
int abr;
/*! desired dtx setting */
int dtx;
/*! desired preprocessor settings */
int preproc;
/*! preprocessor vad settings */
int pp_vad;
/*! preprocessor gain control settings */
int pp_agc;
/*! preprocessor gain level */
float pp_agc_level;
/*! preprocessor denoise level */
int pp_denoise;
/*! preprocessor dereverb settings */
int pp_dereverb;
/*! preprocessor dereverb decay level */
float pp_dereverb_decay;
/*! preprocessor dereverb level */
float pp_dereverb_level;
};
typedef struct speex_codec_settings speex_codec_settings_t;
static speex_codec_settings_t default_codec_settings = {
/*.quality */ 5,
/*.complexity */ 5,
/*.enhancement */ 1,
@@ -58,6 +97,7 @@ static switch_codec_settings_t default_codec_settings = {
struct speex_context {
switch_codec_t *codec;
speex_codec_settings_t codec_settings;
unsigned int flags;
/* Encoder */
@@ -74,6 +114,56 @@ struct speex_context {
int decoder_mode;
};
static switch_status_t switch_speex_fmtp_parse(const char *fmtp, switch_codec_fmtp_t *codec_fmtp)
{
if (codec_fmtp) {
speex_codec_settings_t *codec_settings = NULL;
if (codec_fmtp->private_info) {
codec_settings = codec_fmtp->private_info;
memcpy(codec_settings, &default_codec_settings, sizeof(*codec_settings));
}
if (fmtp) {
int x, argc;
char *argv[10];
char *fmtp_dup = strdup(fmtp);
switch_assert(fmtp_dup);
argc = switch_separate_string(fmtp_dup, ';', argv, (sizeof(argv) / sizeof(argv[0])));
for (x = 0; x < argc; x++) {
char *data = argv[x];
char *arg;
switch_assert(data);
while (*data == ' ') {
data++;
}
if ((arg = strchr(data, '='))) {
*arg++ = '\0';
/*
if (!strcasecmp(data, "bitrate")) {
bit_rate = atoi(arg);
}
*/
/*
if (codec_settings) {
if (!strcasecmp(data, "vad")) {
bit_rate = atoi(arg);
}
}
*/
}
}
free(fmtp_dup);
}
/*codec_fmtp->bits_per_second = bit_rate;*/
return SWITCH_STATUS_SUCCESS;
}
return SWITCH_STATUS_FALSE;
}
static switch_status_t switch_speex_init(switch_codec_t *codec, switch_codec_flag_t flags, const switch_codec_settings_t *codec_settings)
{
struct speex_context *context = NULL;
@@ -82,16 +172,18 @@ static switch_status_t switch_speex_init(switch_codec_t *codec, switch_codec_fla
encoding = (flags & SWITCH_CODEC_FLAG_ENCODE);
decoding = (flags & SWITCH_CODEC_FLAG_DECODE);
if (!codec_settings) {
codec_settings = &default_codec_settings;
}
memcpy(&codec->codec_settings, codec_settings, sizeof(codec->codec_settings));
if (!(encoding || decoding) || ((context = switch_core_alloc(codec->memory_pool, sizeof(*context))) == 0)) {
return SWITCH_STATUS_FALSE;
} else {
const SpeexMode *mode = NULL;
switch_codec_fmtp_t codec_fmtp;
speex_codec_settings_t codec_settings;
memset(&codec_fmtp, '\0', sizeof(struct switch_codec_fmtp));
codec_fmtp.private_info = &codec_settings;
switch_speex_fmtp_parse(codec->fmtp_in, &codec_fmtp);
memcpy(&context->codec_settings, &codec_settings, sizeof(context->codec_settings));
context->codec = codec;
if (codec->implementation->actual_samples_per_second == 8000) {
@@ -110,41 +202,41 @@ static switch_status_t switch_speex_init(switch_codec_t *codec, switch_codec_fla
speex_bits_init(&context->encoder_bits);
context->encoder_state = speex_encoder_init(mode);
speex_encoder_ctl(context->encoder_state, SPEEX_GET_FRAME_SIZE, &context->encoder_frame_size);
speex_encoder_ctl(context->encoder_state, SPEEX_SET_COMPLEXITY, &codec->codec_settings.complexity);
if (codec->codec_settings.preproc) {
speex_encoder_ctl(context->encoder_state, SPEEX_SET_COMPLEXITY, &context->codec_settings.complexity);
if (context->codec_settings.preproc) {
context->pp = speex_preprocess_state_init(context->encoder_frame_size, codec->implementation->actual_samples_per_second);
speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_VAD, &codec->codec_settings.pp_vad);
speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_AGC, &codec->codec_settings.pp_agc);
speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_AGC_LEVEL, &codec->codec_settings.pp_agc_level);
speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_DENOISE, &codec->codec_settings.pp_denoise);
speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_DEREVERB, &codec->codec_settings.pp_dereverb);
speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_DEREVERB_DECAY, &codec->codec_settings.pp_dereverb_decay);
speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_DEREVERB_LEVEL, &codec->codec_settings.pp_dereverb_level);
speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_VAD, &context->codec_settings.pp_vad);
speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_AGC, &context->codec_settings.pp_agc);
speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_AGC_LEVEL, &context->codec_settings.pp_agc_level);
speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_DENOISE, &context->codec_settings.pp_denoise);
speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_DEREVERB, &context->codec_settings.pp_dereverb);
speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_DEREVERB_DECAY, &context->codec_settings.pp_dereverb_decay);
speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_DEREVERB_LEVEL, &context->codec_settings.pp_dereverb_level);
}
if (!codec->codec_settings.abr && !codec->codec_settings.vbr) {
speex_encoder_ctl(context->encoder_state, SPEEX_SET_QUALITY, &codec->codec_settings.quality);
if (codec->codec_settings.vad) {
speex_encoder_ctl(context->encoder_state, SPEEX_SET_VAD, &codec->codec_settings.vad);
if (!context->codec_settings.abr && !context->codec_settings.vbr) {
speex_encoder_ctl(context->encoder_state, SPEEX_SET_QUALITY, &context->codec_settings.quality);
if (context->codec_settings.vad) {
speex_encoder_ctl(context->encoder_state, SPEEX_SET_VAD, &context->codec_settings.vad);
}
}
if (codec->codec_settings.vbr) {
speex_encoder_ctl(context->encoder_state, SPEEX_SET_VBR, &codec->codec_settings.vbr);
speex_encoder_ctl(context->encoder_state, SPEEX_SET_VBR_QUALITY, &codec->codec_settings.vbr_quality);
if (context->codec_settings.vbr) {
speex_encoder_ctl(context->encoder_state, SPEEX_SET_VBR, &context->codec_settings.vbr);
speex_encoder_ctl(context->encoder_state, SPEEX_SET_VBR_QUALITY, &context->codec_settings.vbr_quality);
}
if (codec->codec_settings.abr) {
speex_encoder_ctl(context->encoder_state, SPEEX_SET_ABR, &codec->codec_settings.abr);
if (context->codec_settings.abr) {
speex_encoder_ctl(context->encoder_state, SPEEX_SET_ABR, &context->codec_settings.abr);
}
if (codec->codec_settings.dtx) {
speex_encoder_ctl(context->encoder_state, SPEEX_SET_DTX, &codec->codec_settings.dtx);
if (context->codec_settings.dtx) {
speex_encoder_ctl(context->encoder_state, SPEEX_SET_DTX, &context->codec_settings.dtx);
}
}
if (decoding) {
speex_bits_init(&context->decoder_bits);
context->decoder_state = speex_decoder_init(mode);
if (codec->codec_settings.enhancement) {
speex_decoder_ctl(context->decoder_state, SPEEX_SET_ENH, &codec->codec_settings.enhancement);
if (context->codec_settings.enhancement) {
speex_decoder_ctl(context->decoder_state, SPEEX_SET_ENH, &context->codec_settings.enhancement);
}
}
@@ -178,7 +270,7 @@ static switch_status_t switch_speex_encode(switch_codec_t *codec,
if (is_speech) {
is_speech = speex_encode_int(context->encoder_state, buf, &context->encoder_bits)
|| !context->codec->codec_settings.dtx;
|| !context->codec_settings.dtx;
} else {
speex_bits_pack(&context->encoder_bits, 0, 5);
}
@@ -270,6 +362,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_speex_load)
/* connect my internal structure to the blank pointer passed to me */
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
SWITCH_ADD_CODEC(codec_interface, "Speex");
codec_interface->parse_fmtp = switch_speex_fmtp_parse;
for (counta = 1; counta <= 3; counta++) {
for (countb = 1; countb > 0; countb--) {
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
+1
View File
@@ -1,3 +1,4 @@
fix crashes on FSH323Connection calls in on_hangup routine in different threads.
move PTrace level set to FSH323EndPoint::Initialise
partially apply patch from from Peter Olsson, Remove UnLock() when TryLock() failed and DEBUG_RTP_PACKETS directive.
apply changes from mod_h323-patch.diff by Peter Olsson.
+19 -5
View File
@@ -24,7 +24,7 @@
*
* mod_h323.cpp -- H323 endpoint
*
* Version 0.0.55
* Version 0.0.56
*/
//#define DEBUG_RTP_PACKETS
@@ -747,6 +747,17 @@ FSH323Connection::~FSH323Connection()
// switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,"------------->h323_mutex_unlock\n");
}
void FSH323Connection::AttachSignalChannel(const PString & token,
H323Transport * channel,
PBoolean answeringCall)
{
h323_private_t *tech_pvt = (h323_private_t *) switch_core_session_get_private(m_fsSession);
tech_pvt->token = strdup((const char *)token);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,"---------->token = %s [%p]\n",(const char *)token,this);
H323Connection::AttachSignalChannel(token,channel,answeringCall);
}
void FSH323Connection::OnSetLocalCapabilities()
{
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,"======>FSH323Connection::OnSetLocalCapabilities() [%p]\n",this);
@@ -2321,8 +2332,9 @@ static switch_status_t on_hangup(switch_core_session_t *session)
switch_channel_t *channel = switch_core_session_get_channel(session);
h323_private_t *tech_pvt = (h323_private_t *) switch_core_session_get_private(session);
FSH323Connection *me = tech_pvt->me;
FSH323EndPoint & ep = h323_process->GetH323EndPoint();
tech_pvt->me = NULL;
if (me) {
if (me->m_rtp_resetting == 1) {
switch_core_session_unlock_codec_read(session);
@@ -2340,12 +2352,12 @@ static switch_status_t on_hangup(switch_core_session_t *session)
me->CloseAllLogicalChannels(false);
me->Unlock();
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,"----->%s\n",(const char *)(me->GetCallToken()));
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,"----->%s\n",(const char *)(tech_pvt->token));
Q931::CauseValues cause = (Q931::CauseValues)switch_channel_get_cause_q850(channel);
int trylock = me->TryLock();
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,"-----> () = %d\n",trylock);
if (trylock == 1) {
const PString currentToken(me->GetCallToken());
const PString currentToken(tech_pvt->token);
FSH323Connection *connection = (FSH323Connection *)me->GetEndPoint()->FindConnectionWithLock(currentToken);
if (connection) {
connection->Unlock();
@@ -2356,8 +2368,10 @@ static switch_status_t on_hangup(switch_core_session_t *session)
} else if (trylock == -1) {
/* Failed to lock - just go on */
}
const PString currentToken(tech_pvt->token);
me->SetQ931Cause(cause);
me->ClearCallSynchronous(NULL, H323TranslateToCallEndReason(cause, UINT_MAX));
// me->ClearCallSynchronous(NULL, H323TranslateToCallEndReason(cause, UINT_MAX));
ep.ClearCall(currentToken, H323TranslateToCallEndReason(cause, UINT_MAX));
// switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,"------------->h323_mutex_lock\n");
// switch_mutex_lock(tech_pvt->h323_mutex);
}
+6 -1
View File
@@ -184,6 +184,7 @@ typedef struct {
switch_mutex_t *h323_io_mutex;
FSH323Connection *me;
char *token;
} h323_private_t;
#define DECLARE_CALLBACK0(name) \
@@ -306,7 +307,11 @@ class FSH323Connection:public H323Connection {
unsigned callReference, switch_caller_profile_t *outbound_profile,
switch_core_session_t *fsSession, switch_channel_t *fsChannel);
~FSH323Connection();
virtual void AttachSignalChannel(
const PString & token,
H323Transport * channel,
PBoolean answeringCall
);
virtual H323Channel *CreateRealTimeLogicalChannel(const H323Capability & capability,
H323Channel::Directions dir,
unsigned sessionID, const H245_H2250LogicalChannelParameters * param, RTP_QOS * rtpqos = NULL);
@@ -52,7 +52,8 @@ typedef enum {
TFLAG_BRIDGE = (1 << 4),
TFLAG_BOWOUT = (1 << 5),
TFLAG_BLEG = (1 << 6),
TFLAG_APP = (1 << 7)
TFLAG_APP = (1 << 7),
TFLAG_BOWOUT_USED = (1 << 8)
} TFLAGS;
struct private_object {
@@ -635,7 +636,7 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc
tech_pvt = switch_core_session_get_private(session);
switch_assert(tech_pvt != NULL);
if (switch_test_flag(frame, SFF_CNG) || switch_test_flag(tech_pvt, TFLAG_CNG) || switch_test_flag(tech_pvt, TFLAG_BOWOUT)) {
if (switch_test_flag(frame, SFF_CNG) || switch_test_flag(tech_pvt, TFLAG_CNG) || (switch_test_flag(tech_pvt, TFLAG_BOWOUT) && switch_test_flag(tech_pvt, TFLAG_BOWOUT_USED))) {
return SWITCH_STATUS_SUCCESS;
}
@@ -662,6 +663,9 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc
switch_clear_flag_locked(tech_pvt, TFLAG_WRITE);
switch_clear_flag_locked(tech_pvt->other_tech_pvt, TFLAG_WRITE);
switch_set_flag_locked(tech_pvt, TFLAG_BOWOUT_USED);
switch_set_flag_locked(tech_pvt->other_tech_pvt, TFLAG_BOWOUT_USED);
if (a_uuid && b_uuid) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
"%s detected bridge on both ends, attempting direct connection.\n", switch_channel_get_name(channel));
+72 -20
View File
@@ -1343,19 +1343,6 @@ static switch_status_t kill_listener(listener_t *listener, void *pvt)
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t kill_expired_listener(listener_t *listener, void *pvt)
{
switch_event_t *event = NULL;
if(listener->expire_time < switch_epoch_time_now(NULL)) {
/* skinny::expire event */
skinny_device_event(listener, &event, SWITCH_EVENT_CUSTOM, SKINNY_EVENT_EXPIRE);
switch_event_fire(&event);
return kill_listener(listener, pvt);
}
return SWITCH_STATUS_SUCCESS;
}
switch_status_t keepalive_listener(listener_t *listener, void *pvt)
{
skinny_profile_t *profile;
@@ -1414,6 +1401,13 @@ static void *SWITCH_THREAD_FUNC listener_run(switch_thread_t *thread, void *obj)
case SWITCH_STATUS_TIMEOUT:
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Communication Time Out with %s:%d.\n",
listener->remote_ip, listener->remote_port);
if(listener->expire_time < switch_epoch_time_now(NULL)) {
switch_event_t *event = NULL;
/* skinny::expire event */
skinny_device_event(listener, &event, SWITCH_EVENT_CUSTOM, SKINNY_EVENT_EXPIRE);
switch_event_fire(&event);
}
break;
default:
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Communication Error with %s:%d.\n",
@@ -1917,9 +1911,57 @@ static switch_status_t load_skinny_config(void)
return SWITCH_STATUS_SUCCESS;
}
static void skinny_heartbeat_event_handler(switch_event_t *event)
static void skinny_user_to_device_event_handler(switch_event_t *event)
{
walk_listeners(kill_expired_listener, NULL);
char *profile_name = switch_event_get_header_nil(event, "Skinny-Profile-Name");
skinny_profile_t *profile;
if ((profile = skinny_find_profile(profile_name))) {
char *device_name = switch_event_get_header_nil(event, "Skinny-Device-Name");
uint32_t device_instance = atoi(switch_event_get_header_nil(event, "Skinny-Station-Instance"));
listener_t *listener = NULL;
skinny_profile_find_listener_by_device_name_and_instance(profile, device_name, device_instance, &listener);
if(listener) {
uint32_t message_type = atoi(switch_event_get_header_nil(event, "Skinny-UserToDevice-Message-Id"));
uint32_t application_id = atoi(switch_event_get_header_nil(event, "Skinny-UserToDevice-Application-Id"));
uint32_t line_instance = atoi(switch_event_get_header_nil(event, "Skinny-UserToDevice-Line-Instance"));
uint32_t call_id = atoi(switch_event_get_header_nil(event, "Skinny-UserToDevice-Call-Id"));
uint32_t transaction_id = atoi(switch_event_get_header_nil(event, "Skinny-UserToDevice-Transaction-Id"));
uint32_t data_length = atoi(switch_event_get_header_nil(event, "Skinny-UserToDevice-Data-Length"));
uint32_t sequence_flag = atoi(switch_event_get_header_nil(event, "Skinny-UserToDevice-Sequence-Flag"));
uint32_t display_priority = atoi(switch_event_get_header_nil(event, "Skinny-UserToDevice-Display-Priority"));
uint32_t conference_id = atoi(switch_event_get_header_nil(event, "Skinny-UserToDevice-Conference-Id"));
uint32_t app_instance_id = atoi(switch_event_get_header_nil(event, "Skinny-UserToDevice-App-Instance-Id"));
uint32_t routing_id = atoi(switch_event_get_header_nil(event, "Skinny-UserToDevice-Routing-Id"));
char *data = switch_event_get_body(event);
if (message_type == 0) {
message_type = skinny_str2message_type(switch_event_get_header_nil(event, "Skinny-UserToDevice-Message-Id-String"));
}
switch(message_type) {
case USER_TO_DEVICE_DATA_MESSAGE:
data_length = strlen(data); /* we ignore data_length sent */
send_data(listener, message_type,
application_id, line_instance, call_id, transaction_id, data_length,
data);
case USER_TO_DEVICE_DATA_VERSION1_MESSAGE:
data_length = strlen(data); /* we ignore data_length sent */
send_extended_data(listener, message_type,
application_id, line_instance, call_id, transaction_id, data_length,
sequence_flag, display_priority, conference_id, app_instance_id, routing_id,
data);
break;
default:
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
"Incorrect message type %s (%d).\n", skinny_message_type2str(message_type), message_type);
}
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
"Device %s:%d in profile '%s' not found.\n", device_name, device_instance, profile_name);
}
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
"Profile '%s' not found.\n", profile_name);
}
}
static void skinny_call_state_event_handler(switch_event_t *event)
@@ -2129,10 +2171,6 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_skinny_load)
return SWITCH_STATUS_TERM;
}
/* bind to events */
if ((switch_event_bind_removable(modname, SWITCH_EVENT_HEARTBEAT, NULL, skinny_heartbeat_event_handler, NULL, &globals.heartbeat_node) != SWITCH_STATUS_SUCCESS)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Couldn't bind our heartbeat handler!\n");
/* Not such severe to prevent loading */
}
if ((switch_event_bind_removable(modname, SWITCH_EVENT_CUSTOM, SKINNY_EVENT_CALL_STATE, skinny_call_state_event_handler, NULL, &globals.call_state_node) != SWITCH_STATUS_SUCCESS)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind our call_state handler!\n");
return SWITCH_STATUS_TERM;
@@ -2145,6 +2183,10 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_skinny_load)
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Couldn't bind our trap handler!\n");
/* Not such severe to prevent loading */
}
if ((switch_event_bind_removable(modname, SWITCH_EVENT_CUSTOM, SKINNY_EVENT_USER_TO_DEVICE, skinny_user_to_device_event_handler, NULL, &globals.user_to_device_node) != SWITCH_STATUS_SUCCESS)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind our user_to_device handler!\n");
/* Not such severe to prevent loading */
}
/* reserve events */
if (switch_event_reserve_subclass(SKINNY_EVENT_REGISTER) != SWITCH_STATUS_SUCCESS) {
@@ -2167,6 +2209,14 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_skinny_load)
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", SKINNY_EVENT_CALL_STATE);
return SWITCH_STATUS_TERM;
}
if (switch_event_reserve_subclass(SKINNY_EVENT_USER_TO_DEVICE) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", SKINNY_EVENT_USER_TO_DEVICE);
return SWITCH_STATUS_TERM;
}
if (switch_event_reserve_subclass(SKINNY_EVENT_DEVICE_TO_USER) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", SKINNY_EVENT_DEVICE_TO_USER);
return SWITCH_STATUS_TERM;
}
/* connect my internal structure to the blank pointer passed to me */
*module_interface = switch_loadable_module_create_module_interface(globals.pool, modname);
@@ -2205,7 +2255,7 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_skinny_shutdown)
skinny_api_unregister();
/* release events */
switch_event_unbind(&globals.heartbeat_node);
switch_event_unbind(&globals.user_to_device_node);
switch_event_unbind(&globals.call_state_node);
switch_event_unbind(&globals.message_waiting_node);
switch_event_unbind(&globals.trap_node);
@@ -2214,6 +2264,8 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_skinny_shutdown)
switch_event_free_subclass(SKINNY_EVENT_EXPIRE);
switch_event_free_subclass(SKINNY_EVENT_ALARM);
switch_event_free_subclass(SKINNY_EVENT_CALL_STATE);
switch_event_free_subclass(SKINNY_EVENT_USER_TO_DEVICE);
switch_event_free_subclass(SKINNY_EVENT_DEVICE_TO_USER);
switch_mutex_lock(mutex);
+3 -1
View File
@@ -43,13 +43,15 @@
#define SKINNY_EVENT_EXPIRE "skinny::expire"
#define SKINNY_EVENT_ALARM "skinny::alarm"
#define SKINNY_EVENT_CALL_STATE "skinny::call_state"
#define SKINNY_EVENT_USER_TO_DEVICE "skinny::user_to_device"
#define SKINNY_EVENT_DEVICE_TO_USER "skinny::device_to_user"
struct skinny_globals {
int running;
switch_memory_pool_t *pool;
switch_mutex_t *mutex;
switch_hash_t *profile_hash;
switch_event_node_t *heartbeat_node;
switch_event_node_t *user_to_device_node;
switch_event_node_t *call_state_node;
switch_event_node_t *message_waiting_node;
switch_event_node_t *trap_node;
+69
View File
@@ -366,6 +366,62 @@ static switch_status_t skinny_api_cmd_profile_device_send_reset_message(const ch
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t skinny_api_cmd_profile_device_send_data(const char *profile_name, const char *device_name, const char *message_type, char *params, const char *body, switch_stream_handle_t *stream)
{
skinny_profile_t *profile;
if ((profile = skinny_find_profile(profile_name))) {
listener_t *listener = NULL;
skinny_profile_find_listener_by_device_name(profile, device_name, &listener);
if(listener) {
switch_event_t *event = NULL;
char *argv[64] = { 0 };
int argc = 0;
int x = 0;
/* skinny::user_to_device event */
skinny_device_event(listener, &event, SWITCH_EVENT_CUSTOM, SKINNY_EVENT_USER_TO_DEVICE);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-UserToDevice-Message-Id-String", "%s", message_type);
argc = switch_separate_string(params, ';', argv, (sizeof(argv) / sizeof(argv[0])));
for (x = 0; x < argc; x++) {
char *var_name, *var_value = NULL;
var_name = argv[x];
if (var_name && (var_value = strchr(var_name, '='))) {
*var_value++ = '\0';
}
if (zstr(var_name)) {
stream->write_function(stream, "-ERR No variable specified\n");
} else {
char *tmp = switch_mprintf("Skinny-UserToDevice-%s", var_name);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, tmp, "%s", var_value);
switch_safe_free(tmp);
/*
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-UserToDevice-Application-Id", "%d", request->data.extended_data.application_id);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-UserToDevice-Line-Instance", "%d", request->data.extended_data.line_instance);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-UserToDevice-Call-Id", "%d", request->data.extended_data.call_id);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-UserToDevice-Transaction-Id", "%d", request->data.extended_data.transaction_id);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-UserToDevice-Data-Length", "%d", request->data.extended_data.data_length);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-UserToDevice-Sequence-Flag", "%d", request->data.extended_data.sequence_flag);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-UserToDevice-Display-Priority", "%d", request->data.extended_data.display_priority);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-UserToDevice-Conference-Id", "%d", request->data.extended_data.conference_id);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-UserToDevice-App-Instance-Id", "%d", request->data.extended_data.app_instance_id);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-UserToDevice-Routing-Id", "%d", request->data.extended_data.routing_id);
*/
}
}
switch_event_add_body(event, "%s", body);
switch_event_fire(&event);
stream->write_function(stream, "+OK\n");
} else {
stream->write_function(stream, "Listener not found!\n");
}
} else {
stream->write_function(stream, "Profile not found!\n");
}
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t skinny_api_cmd_profile_set(const char *profile_name, const char *name, const char *value, switch_stream_handle_t *stream)
{
skinny_profile_t *profile;
@@ -403,6 +459,7 @@ SWITCH_STANDARD_API(skinny_function)
"skinny profile <profile_name> device <device_name> send SetLampMessage <stimulus> <instance> <lamp_mode>\n"
"skinny profile <profile_name> device <device_name> send SetSpeakerModeMessage <speaker_mode>\n"
"skinny profile <profile_name> device <device_name> send CallStateMessage <call_state> <line_instance> <call_id>\n"
"skinny profile <profile_name> device <device_name> send <UserToDeviceDataMessage|UserToDeviceDataVersion1Message> [ <param>=<value>;... ] <data>\n"
"skinny profile <profile_name> set <name> <value>\n"
"--------------------------------------------------------------------------------\n";
if (session) {
@@ -465,6 +522,16 @@ SWITCH_STANDARD_API(skinny_function)
status = skinny_api_cmd_profile_device_send_reset_message(argv[1], argv[3], argv[6], stream);
}
break;
case USER_TO_DEVICE_DATA_MESSAGE:
case USER_TO_DEVICE_DATA_VERSION1_MESSAGE:
if(argc == 8) {
/* <UserToDeviceDataMessage|UserToDeviceDataVersion1Message> [ <param>=<value>;... ] <data> */
status = skinny_api_cmd_profile_device_send_data(argv[1], argv[3], argv[5], argv[6], argv[7], stream);
} else if(argc == 7) {
/* <UserToDeviceDataMessage|UserToDeviceDataVersion1Message> <data> */
status = skinny_api_cmd_profile_device_send_data(argv[1], argv[3], argv[5], "", argv[6], stream);
}
break;
default:
stream->write_function(stream, "Unhandled message %s\n", argv[5]);
}
@@ -495,6 +562,8 @@ switch_status_t skinny_api_register(switch_loadable_module_interface_t **module_
switch_console_set_complete("add skinny profile ::skinny::list_profiles device ::skinny::list_devices send SetLampMessage ::skinny::list_stimuli ::skinny::list_stimulus_instances ::skinny::list_stimulus_modes");
switch_console_set_complete("add skinny profile ::skinny::list_profiles device ::skinny::list_devices send SetSpeakerModeMessage ::skinny::list_speaker_modes");
switch_console_set_complete("add skinny profile ::skinny::list_profiles device ::skinny::list_devices send CallStateMessage ::skinny::list_call_states ::skinny::list_line_instances ::skinny::list_call_ids");
switch_console_set_complete("add skinny profile ::skinny::list_profiles device ::skinny::list_devices send UserToDeviceDataMessage");
switch_console_set_complete("add skinny profile ::skinny::list_profiles device ::skinny::list_devices send UserToDeviceDataVersion1Message");
switch_console_set_complete("add skinny profile ::skinny::list_profiles set ::skinny::list_settings");
switch_console_add_complete_func("::skinny::list_profiles", skinny_api_list_profiles);
@@ -135,6 +135,10 @@ switch_status_t skinny_read_packet(listener_t *listener, skinny_message_t **req)
status = switch_socket_recv(listener->sock, ptr, &mlen);
if (listener->expire_time && listener->expire_time < switch_epoch_time_now(NULL)) {
return SWITCH_STATUS_TIMEOUT;
}
if (!listener_is_ready(listener)) {
break;
}
@@ -898,6 +902,68 @@ switch_status_t send_reset(listener_t *listener, uint32_t reset_type)
return skinny_send_reply(listener, message);
}
switch_status_t send_data(listener_t *listener, uint32_t message_type,
uint32_t application_id,
uint32_t line_instance,
uint32_t call_id,
uint32_t transaction_id,
uint32_t data_length,
const char *data)
{
skinny_message_t *message;
switch_assert(data_length == strlen(data));
/* data_length should be a multiple of 4 */
if ((data_length % 4) != 0) {
data_length = (data_length / 4 + 1) * 4;
}
message = switch_core_alloc(listener->pool, 12+sizeof(message->data.data)+data_length-1);
message->type = message_type;
message->length = 4 + sizeof(message->data.data)+data_length-1;
message->data.data.application_id = application_id;
message->data.data.line_instance = line_instance;
message->data.data.call_id = call_id;
message->data.data.transaction_id = transaction_id;
message->data.data.data_length = data_length;
strncpy(message->data.data.data, data, data_length);
return skinny_send_reply(listener, message);
}
switch_status_t send_extended_data(listener_t *listener, uint32_t message_type,
uint32_t application_id,
uint32_t line_instance,
uint32_t call_id,
uint32_t transaction_id,
uint32_t data_length,
uint32_t sequence_flag,
uint32_t display_priority,
uint32_t conference_id,
uint32_t app_instance_id,
uint32_t routing_id,
const char *data)
{
skinny_message_t *message;
switch_assert(data_length == strlen(data));
/* data_length should be a multiple of 4 */
if ((data_length % 4) != 0) {
data_length = (data_length / 4 + 1) * 4;
}
message = switch_core_alloc(listener->pool, 12+sizeof(message->data.extended_data)+data_length-1);
message->type = message_type;
message->length = 4 + sizeof(message->data.extended_data)+data_length-1;
message->data.extended_data.application_id = application_id;
message->data.extended_data.line_instance = line_instance;
message->data.extended_data.call_id = call_id;
message->data.extended_data.transaction_id = transaction_id;
message->data.extended_data.data_length = data_length;
message->data.extended_data.sequence_flag = sequence_flag;
message->data.extended_data.display_priority = display_priority;
message->data.extended_data.conference_id = conference_id;
message->data.extended_data.app_instance_id = app_instance_id;
message->data.extended_data.routing_id = routing_id;
strncpy(message->data.extended_data.data, data, data_length);
return skinny_send_reply(listener, message);
}
switch_status_t skinny_perform_send_reply(listener_t *listener, const char *file, const char *func, int line, skinny_message_t *reply)
{
char *ptr;
+85 -2
View File
@@ -174,6 +174,21 @@ struct PACKED register_available_lines_message {
uint32_t count;
};
/* DeviceToUserDataMessage */
#define DEVICE_TO_USER_DATA_MESSAGE 0x002E
struct PACKED data_message {
uint32_t application_id;
uint32_t line_instance;
uint32_t call_id;
uint32_t transaction_id;
uint32_t data_length;
char data[1];
};
/* DeviceToUserDataResponseMessage */
#define DEVICE_TO_USER_DATA_RESPONSE_MESSAGE 0x002F
/* See struct PACKED data_message */
/* ServiceUrlStatReqMessage */
#define SERVICE_URL_STAT_REQ_MESSAGE 0x0033
struct PACKED service_url_stat_req_message {
@@ -186,6 +201,26 @@ struct PACKED feature_stat_req_message {
uint32_t feature_index;
};
/* DeviceToUserDataVersion1Message */
#define DEVICE_TO_USER_DATA_VERSION1_MESSAGE 0x0041
struct PACKED extended_data_message {
uint32_t application_id;
uint32_t line_instance;
uint32_t call_id;
uint32_t transaction_id;
uint32_t data_length;
uint32_t sequence_flag;
uint32_t display_priority;
uint32_t conference_id;
uint32_t app_instance_id;
uint32_t routing_id;
char data[1];
};
/* DeviceToUserDataResponseVersion1Message */
#define DEVICE_TO_USER_DATA_RESPONSE_VERSION1_MESSAGE 0x0042
/* See struct PACKED extended_data_message */
/* RegisterAckMessage */
#define REGISTER_ACK_MESSAGE 0x0081
struct PACKED register_ack_message {
@@ -479,6 +514,10 @@ struct PACKED dialed_number_message {
uint32_t call_id;
};
/* UserToDeviceDataMessage */
#define USER_TO_DEVICE_DATA_MESSAGE 0x011E
/* See struct PACKED data_message */
/* FeatureStatMessage */
#define FEATURE_STAT_RES_MESSAGE 0x011F
struct PACKED feature_stat_res_message {
@@ -504,6 +543,10 @@ struct PACKED service_url_stat_res_message {
char display_name[40];
};
/* UserToDeviceDataVersion1Message */
#define USER_TO_DEVICE_DATA_VERSION1_MESSAGE 0x013F
/* See struct PACKED extended_data_message */
/*****************************************************************************/
/* SKINNY MESSAGE */
/*****************************************************************************/
@@ -512,6 +555,7 @@ struct PACKED service_url_stat_res_message {
#define SKINNY_MESSAGE_MAXSIZE 1000
union skinny_data {
/* no data for KEEP_ALIVE_MESSAGE */
struct register_message reg;
struct port_message port;
struct keypad_button_message keypad_button;
@@ -520,14 +564,25 @@ union skinny_data {
struct on_hook_message on_hook;
struct speed_dial_stat_req_message speed_dial_req;
struct line_stat_req_message line_req;
/* no data for CONFIG_STAT_REQ_MESSAGE */
/* no data for TIME_DATE_REQ_MESSAGE */
/* no data for BUTTON_TEMPLATE_REQ_MESSAGE */
/* no data for VERSION_REQ_MESSAGE */
struct capabilities_res_message cap_res;
struct alarm_message alarm;
struct open_receive_channel_ack_message open_receive_channel_ack;
/* no data for SOFT_KEY_SET_REQ_MESSAGE */
struct soft_key_event_message soft_key_event;
struct service_url_stat_req_message service_url_req;
struct feature_stat_req_message feature_req;
/* no data for UNREGISTER_MESSAGE */
/* no data for SOFT_KEY_TEMPLATE_REQ_MESSAGE */
struct headset_status_message headset_status;
struct register_available_lines_message reg_lines;
/* see field "data" for DEVICE_TO_USER_DATA_MESSAGE */
/* see field "data" for DEVICE_TO_USER_DATA_RESPONSE_MESSAGE */
struct service_url_stat_req_message service_url_req;
struct feature_stat_req_message feature_req;
/* see field "extended_data" for DEVICE_TO_USER_DATA_VERSION1_MESSAGE */
/* see field "extended_data" for DEVICE_TO_USER_DATA_RESPONSE_VERSION1_MESSAGE */
struct register_ack_message reg_ack;
struct start_tone_message start_tone;
struct stop_tone_message stop_tone;
@@ -543,8 +598,10 @@ union skinny_data {
struct define_time_date_message define_time_date;
struct button_template_message button_template;
struct version_message version;
/* no data for CAPABILITIES_REQ_MESSAGE */
struct register_reject_message reg_rej;
struct reset_message reset;
/* no data for KEEP_ALIVE_ACK_MESSAGE */
struct open_receive_channel_message open_receive_channel;
struct close_receive_channel_message close_receive_channel;
struct soft_key_template_res_message soft_key_template;
@@ -557,9 +614,14 @@ union skinny_data {
struct unregister_ack_message unregister_ack;
struct back_space_req_message back_space_req;
struct dialed_number_message dialed_number;
/* see field "data" for USER_TO_DEVICE_DATA_MESSAGE */
struct feature_stat_res_message feature_res;
struct display_pri_notify_message display_pri_notify;
struct service_url_stat_res_message service_url_res;
/* see field "extended_data" for USER_TO_DEVICE_DATA_VERSION1_MESSAGE */
struct data_message data;
struct extended_data_message extended_data;
uint16_t as_uint16;
char as_char;
@@ -777,6 +839,27 @@ switch_status_t send_display_pri_notify(listener_t *listener,
switch_status_t send_reset(listener_t *listener,
uint32_t reset_type);
switch_status_t send_data(listener_t *listener, uint32_t message_type,
uint32_t application_id,
uint32_t line_instance,
uint32_t call_id,
uint32_t transaction_id,
uint32_t data_length,
const char *data);
switch_status_t send_extended_data(listener_t *listener, uint32_t message_type,
uint32_t application_id,
uint32_t line_instance,
uint32_t call_id,
uint32_t transaction_id,
uint32_t data_length,
uint32_t sequence_flag,
uint32_t display_priority,
uint32_t conference_id,
uint32_t app_instance_id,
uint32_t routing_id,
const char *data);
#endif /* _SKINNY_PROTOCOL_H */
/* For Emacs:
@@ -1864,6 +1864,33 @@ switch_status_t skinny_handle_register_available_lines_message(listener_t *liste
return SWITCH_STATUS_SUCCESS;
}
switch_status_t skinny_handle_data_message(listener_t *listener, skinny_message_t *request)
{
switch_event_t *event = NULL;
char *tmp = NULL;
skinny_check_data_length(request, sizeof(request->data.data));
skinny_check_data_length(request, sizeof(request->data.data) + request->data.data.data_length - 1);
/* skinny::device_to_user event */
skinny_device_event(listener, &event, SWITCH_EVENT_CUSTOM, SKINNY_EVENT_DEVICE_TO_USER);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Message-Id", "%d", request->type);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Message-Id-String", "%s", skinny_message_type2str(request->type));
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Application-Id", "%d", request->data.data.application_id);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Line-Instance", "%d", request->data.data.line_instance);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Call-Id", "%d", request->data.data.call_id);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Transaction-Id", "%d", request->data.data.transaction_id);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Data-Length", "%d", request->data.data.data_length);
/* Ensure that the body is null-terminated */
tmp = malloc(request->data.data.data_length + 1);
memcpy(tmp, request->data.data.data, request->data.data.data_length);
tmp[request->data.data.data_length] = '\0';
switch_event_add_body(event, "%s", tmp);
switch_safe_free(tmp);
switch_event_fire(&event);
return SWITCH_STATUS_SUCCESS;
}
switch_status_t skinny_handle_service_url_stat_request(listener_t *listener, skinny_message_t *request)
{
skinny_message_t *message;
@@ -1904,6 +1931,38 @@ switch_status_t skinny_handle_feature_stat_request(listener_t *listener, skinny_
return SWITCH_STATUS_SUCCESS;
}
switch_status_t skinny_handle_extended_data_message(listener_t *listener, skinny_message_t *request)
{
switch_event_t *event = NULL;
char *tmp = NULL;
skinny_check_data_length(request, sizeof(request->data.extended_data));
skinny_check_data_length(request, sizeof(request->data.extended_data)+request->data.extended_data.data_length-1);
/* skinny::device_to_user event */
skinny_device_event(listener, &event, SWITCH_EVENT_CUSTOM, SKINNY_EVENT_DEVICE_TO_USER);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Message-Id", "%d", request->type);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Message-Id-String", "%s", skinny_message_type2str(request->type));
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Application-Id", "%d", request->data.extended_data.application_id);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Line-Instance", "%d", request->data.extended_data.line_instance);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Call-Id", "%d", request->data.extended_data.call_id);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Transaction-Id", "%d", request->data.extended_data.transaction_id);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Data-Length", "%d", request->data.extended_data.data_length);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Sequence-Flag", "%d", request->data.extended_data.sequence_flag);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Display-Priority", "%d", request->data.extended_data.display_priority);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Conference-Id", "%d", request->data.extended_data.conference_id);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-App-Instance-Id", "%d", request->data.extended_data.app_instance_id);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Routing-Id", "%d", request->data.extended_data.routing_id);
/* Ensure that the body is null-terminated */
tmp = malloc(request->data.data.data_length + 1);
memcpy(tmp, request->data.data.data, request->data.data.data_length);
tmp[request->data.data.data_length] = '\0';
switch_event_add_body(event, "%s", tmp);
switch_safe_free(tmp);
switch_event_fire(&event);
return SWITCH_STATUS_SUCCESS;
}
switch_status_t skinny_handle_request(listener_t *listener, skinny_message_t *request)
{
if (listener->profile->debug >= 10 || request->type != KEEP_ALIVE_MESSAGE) {
@@ -1961,10 +2020,18 @@ switch_status_t skinny_handle_request(listener_t *listener, skinny_message_t *re
return skinny_headset_status_message(listener, request);
case REGISTER_AVAILABLE_LINES_MESSAGE:
return skinny_handle_register_available_lines_message(listener, request);
case DEVICE_TO_USER_DATA_MESSAGE:
return skinny_handle_data_message(listener, request);
case DEVICE_TO_USER_DATA_RESPONSE_MESSAGE:
return skinny_handle_data_message(listener, request);
case SERVICE_URL_STAT_REQ_MESSAGE:
return skinny_handle_service_url_stat_request(listener, request);
case FEATURE_STAT_REQ_MESSAGE:
return skinny_handle_feature_stat_request(listener, request);
case DEVICE_TO_USER_DATA_VERSION1_MESSAGE:
return skinny_handle_extended_data_message(listener, request);
case DEVICE_TO_USER_DATA_RESPONSE_VERSION1_MESSAGE:
return skinny_handle_extended_data_message(listener, request);
default:
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
"Unhandled request %s (type=%x,length=%d).\n", skinny_message_type2str(request->type), request->type, request->length);
+8 -2
View File
@@ -55,10 +55,14 @@ struct skinny_table SKINNY_MESSAGE_TYPES[] = {
{"SoftKeyEventMessage", SOFT_KEY_EVENT_MESSAGE},
{"UnregisterMessage", UNREGISTER_MESSAGE},
{"SoftKeyTemplateReqMessage", SOFT_KEY_TEMPLATE_REQ_MESSAGE},
{"ServiceUrlStatReqMessage", SERVICE_URL_STAT_REQ_MESSAGE},
{"FeatureStatReqMessage", FEATURE_STAT_REQ_MESSAGE},
{"HeadsetStatusMessage", HEADSET_STATUS_MESSAGE},
{"RegisterAvailableLinesMessage", REGISTER_AVAILABLE_LINES_MESSAGE},
{"DeviceToUserDataMessage", DEVICE_TO_USER_DATA_MESSAGE},
{"DeviceToUserDataResponseMessage", DEVICE_TO_USER_DATA_RESPONSE_MESSAGE},
{"ServiceUrlStatReqMessage", SERVICE_URL_STAT_REQ_MESSAGE},
{"FeatureStatReqMessage", FEATURE_STAT_REQ_MESSAGE},
{"DeviceToUserDataVersion1Message", DEVICE_TO_USER_DATA_VERSION1_MESSAGE},
{"DeviceToUserDataResponseVersion1Message", DEVICE_TO_USER_DATA_RESPONSE_VERSION1_MESSAGE},
{"RegisterAckMessage", REGISTER_ACK_MESSAGE},
{"StartToneMessage", START_TONE_MESSAGE},
{"StopToneMessage", STOP_TONE_MESSAGE},
@@ -90,9 +94,11 @@ struct skinny_table SKINNY_MESSAGE_TYPES[] = {
{"UnregisterAckMessage", UNREGISTER_ACK_MESSAGE},
{"BackSpaceReqMessage", BACK_SPACE_REQ_MESSAGE},
{"DialedNumberMessage", DIALED_NUMBER_MESSAGE},
{"UserToDeviceDataMessage", USER_TO_DEVICE_DATA_MESSAGE},
{"FeatureResMessage", FEATURE_STAT_RES_MESSAGE},
{"DisplayPriNotifyMessage", DISPLAY_PRI_NOTIFY_MESSAGE},
{"ServiceUrlStatMessage", SERVICE_URL_STAT_RES_MESSAGE},
{"UserToDeviceDataVersion1Message", USER_TO_DEVICE_DATA_VERSION1_MESSAGE},
{NULL, 0}
};
SKINNY_DECLARE_ID2STR(skinny_message_type2str, SKINNY_MESSAGE_TYPES, "UnknownMessage")
+1 -1
View File
@@ -87,7 +87,7 @@ uint32_t func(const char *str)\
}
extern struct skinny_table SKINNY_MESSAGE_TYPES[59];
extern struct skinny_table SKINNY_MESSAGE_TYPES[65];
const char *skinny_message_type2str(uint32_t id);
uint32_t skinny_str2message_type(const char *str);
#define SKINNY_PUSH_MESSAGE_TYPES SKINNY_DECLARE_PUSH_MATCH(SKINNY_MESSAGE_TYPES)
+107 -58
View File
@@ -85,6 +85,10 @@ static switch_status_t sofia_on_init(switch_core_session_t *session)
sofia_glue_tech_absorb_sdp(tech_pvt);
}
if (sofia_test_flag(tech_pvt, TFLAG_RECOVERING) || sofia_test_flag(tech_pvt, TFLAG_RECOVERING_BRIDGE)) {
sofia_set_flag(tech_pvt, TFLAG_RECOVERED);
}
if (sofia_test_flag(tech_pvt, TFLAG_OUTBOUND) || sofia_test_flag(tech_pvt, TFLAG_RECOVERING)) {
const char *var;
@@ -717,6 +721,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
TAG_IF(sticky, NUTAG_PROXY(tech_pvt->record_route)),
TAG_IF(cid, SIPTAG_HEADER_STR(cid)),
NUTAG_SESSION_TIMER(session_timeout),
TAG_IF(session_timeout, NUTAG_SESSION_REFRESHER(nua_remote_refresher)),
SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
SIPTAG_CALL_INFO_STR(switch_channel_get_variable(tech_pvt->channel, SOFIA_SIP_HEADER_PREFIX "call_info")),
SOATAG_USER_SDP_STR(tech_pvt->local_sdp_str),
@@ -732,6 +737,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
TAG_IF(sticky, NUTAG_PROXY(tech_pvt->record_route)),
TAG_IF(cid, SIPTAG_HEADER_STR(cid)),
NUTAG_SESSION_TIMER(session_timeout),
TAG_IF(session_timeout, NUTAG_SESSION_REFRESHER(nua_remote_refresher)),
SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
SIPTAG_CALL_INFO_STR(switch_channel_get_variable(tech_pvt->channel, SOFIA_SIP_HEADER_PREFIX "call_info")),
SIPTAG_CONTENT_TYPE_STR("application/sdp"),
@@ -1232,7 +1238,12 @@ static void start_udptl(private_object_t *tech_pvt, switch_t38_options_t *t38_op
switch_rtp_udptl_mode(tech_pvt->rtp_session);
if (remote_host && remote_port && !strcmp(remote_host, t38_options->remote_ip) && remote_port == t38_options->remote_port) {
if (!t38_options || !t38_options->remote_ip) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "No remote address\n");
return;
}
if (remote_host && remote_port && remote_port == t38_options->remote_port && !strcmp(remote_host, t38_options->remote_ip)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Remote address:port [%s:%d] has not changed.\n",
t38_options->remote_ip, t38_options->remote_port);
return;
@@ -1471,12 +1482,11 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
switch (msg->message_id) {
case SWITCH_MESSAGE_INDICATE_VIDEO_REFRESH_REQ:
{
const char *pl =
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n"
" <media_control>\r\n"
" <vc_primitive>\r\n"
" <to_encoder>\r\n"
" <picture_fast_update>\r\n" " </picture_fast_update>\r\n" " </to_encoder>\r\n" " </vc_primitive>\r\n" " </media_control>\r\n";
const char *pl = "<media_control><vc_primitive><to_encoder><picture_fast_update/></to_encoder></vc_primitive></media_control>";
if (!zstr(msg->string_arg)) {
pl = msg->string_arg;
}
nua_info(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("application/media_control+xml"), SIPTAG_PAYLOAD_STR(pl), TAG_END());
@@ -1765,7 +1775,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
nua_update(tech_pvt->nh,
TAG_IF(!zstr_buf(message), SIPTAG_HEADER_STR(message)),
TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), TAG_END());
} else if ((ua && (switch_stristr("cisco", ua)))) {
} else if (0 && (ua && (switch_stristr("cisco", ua)))) {
snprintf(message, sizeof(message), "P-Asserted-Identity: \"%s\" <sip:%s@%s>", name, number, tech_pvt->profile->sipip);
sofia_set_flag_locked(tech_pvt, TFLAG_UPDATING_DISPLAY);
@@ -2005,6 +2015,9 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
switch_t38_options_t *t38_options = switch_channel_get_private(tech_pvt->channel, "t38_options");
if (t38_options) {
sofia_glue_set_image_sdp(tech_pvt, t38_options, 0);
if (switch_rtp_ready(tech_pvt->rtp_session)) {
switch_rtp_udptl_mode(tech_pvt->rtp_session);
}
}
} else {
sofia_glue_tech_set_local_sdp(tech_pvt, sdp, SWITCH_TRUE);
@@ -2090,6 +2103,9 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
break;
case SWITCH_MESSAGE_INDICATE_ANSWER:
status = sofia_answer_channel(session);
if (switch_channel_test_flag(tech_pvt->channel, CF_VIDEO)) {
sofia_glue_build_vid_refresh_message(session, NULL);
}
break;
case SWITCH_MESSAGE_INDICATE_PROGRESS:
{
@@ -2315,7 +2331,7 @@ static int show_reg_callback(void *pArg, int argc, char **argv, char **columnNam
switch_time_t etime = atoi(argv[6]);
switch_size_t retsize;
exp_secs = etime - now;
exp_secs = (int)(etime - now);
switch_time_exp_lt(&tm, switch_time_from_sec(etime));
switch_strftime_nocheck(exp_buf, &retsize, sizeof(exp_buf), "%Y-%m-%d %T", &tm);
}
@@ -2355,7 +2371,7 @@ static int show_reg_callback_xml(void *pArg, int argc, char **argv, char **colum
switch_time_t etime = atoi(argv[6]);
switch_size_t retsize;
exp_secs = etime - now;
exp_secs = (int)(etime - now);
switch_time_exp_lt(&tm, switch_time_from_sec(etime));
switch_strftime_nocheck(exp_buf, &retsize, sizeof(exp_buf), "%Y-%m-%d %T", &tm);
}
@@ -2422,7 +2438,7 @@ static switch_status_t cmd_status(char **argv, int argc, switch_stream_handle_t
ob_failed += gp->ob_failed_calls;
ob += gp->ob_calls;
stream->write_function(stream, "%25s\t%32s\t%s\t%ld/%ld\t%ld/%ld",
stream->write_function(stream, "%25s\t%32s\t%s\t%u/%u\t%u/%u",
pkey, gp->register_to, sofia_state_names[gp->state],
gp->ib_failed_calls, gp->ib_calls, gp->ob_failed_calls, gp->ob_calls);
@@ -2441,8 +2457,8 @@ static switch_status_t cmd_status(char **argv, int argc, switch_stream_handle_t
}
switch_mutex_unlock(mod_sofia_globals.hash_mutex);
stream->write_function(stream, "%s\n", line);
stream->write_function(stream, "%d gateway%s: Inound(Failed/Total): %ld/%ld,"
"Outbound(Failed/Total):%ld/%ld\n", c, c == 1 ? "" : "s", ib_failed, ib, ob_failed, ob);
stream->write_function(stream, "%d gateway%s: Inbound(Failed/Total): %u/%u,"
"Outbound(Failed/Total):%u/%u\n", c, c == 1 ? "" : "s", ib_failed, ib, ob_failed, ob);
return SWITCH_STATUS_SUCCESS;
}
@@ -2471,10 +2487,10 @@ static switch_status_t cmd_status(char **argv, int argc, switch_stream_handle_t
stream->write_function(stream, "PingState\t%d/%d/%d\n", gp->ping_min, gp->ping_count, gp->ping_max);
stream->write_function(stream, "State \t%s\n", sofia_state_names[gp->state]);
stream->write_function(stream, "Status \t%s%s\n", status_names[gp->status], gp->pinging ? " (ping)" : "");
stream->write_function(stream, "CallsIN \t%d\n", gp->ib_calls);
stream->write_function(stream, "CallsOUT\t%d\n", gp->ob_calls);
stream->write_function(stream, "FailedCallsIN\t%d\n", gp->ib_failed_calls);
stream->write_function(stream, "FailedCallsOUT\t%d\n", gp->ob_failed_calls);
stream->write_function(stream, "CallsIN \t%u\n", gp->ib_calls);
stream->write_function(stream, "CallsOUT\t%u\n", gp->ob_calls);
stream->write_function(stream, "FailedCallsIN\t%u\n", gp->ib_failed_calls);
stream->write_function(stream, "FailedCallsOUT\t%u\n", gp->ob_failed_calls);
stream->write_function(stream, "%s\n", line);
sofia_reg_release_gateway(gp);
} else {
@@ -2483,7 +2499,7 @@ static switch_status_t cmd_status(char **argv, int argc, switch_stream_handle_t
} else if (!strcasecmp(argv[0], "profile")) {
struct cb_helper cb;
char *sql = NULL;
int x = 0;
uint32_t x = 0;
cb.row_process = 0;
@@ -2548,10 +2564,10 @@ static switch_status_t cmd_status(char **argv, int argc, switch_stream_handle_t
if (profile->max_registrations_perext > 0) {
stream->write_function(stream, "MAX-REG-PEREXT \t%d\n", profile->max_registrations_perext);
}
stream->write_function(stream, "CALLS-IN \t%d\n", profile->ib_calls);
stream->write_function(stream, "FAILED-CALLS-IN \t%d\n", profile->ib_failed_calls);
stream->write_function(stream, "CALLS-OUT \t%d\n", profile->ob_calls);
stream->write_function(stream, "FAILED-CALLS-OUT \t%d\n", profile->ob_failed_calls);
stream->write_function(stream, "CALLS-IN \t%u\n", profile->ib_calls);
stream->write_function(stream, "FAILED-CALLS-IN \t%u\n", profile->ib_failed_calls);
stream->write_function(stream, "CALLS-OUT \t%u\n", profile->ob_calls);
stream->write_function(stream, "FAILED-CALLS-OUT \t%u\n", profile->ob_failed_calls);
}
stream->write_function(stream, "\nRegistrations:\n%s\n", line);
@@ -2697,10 +2713,10 @@ static void xml_gateway_status(sofia_gateway_t *gp, switch_stream_handle_t *stre
stream->write_function(stream, " <pingfreq>%d</pingfreq>\n", gp->ping_freq);
stream->write_function(stream, " <state>%s</state>\n", sofia_state_names[gp->state]);
stream->write_function(stream, " <status>%s%s</status>\n", status_names[gp->status], gp->pinging ? " (ping)" : "");
stream->write_function(stream, " <calls-in>%d</calls-in>\n", gp->ib_calls);
stream->write_function(stream, " <calls-out>%d</calls-out>\n", gp->ob_calls);
stream->write_function(stream, " <failed-calls-in>%d</failed-calls-in>\n", gp->ib_failed_calls);
stream->write_function(stream, " <failed-calls-out>%d</failed-calls-out>\n", gp->ob_failed_calls);
stream->write_function(stream, " <calls-in>%u</calls-in>\n", gp->ib_calls);
stream->write_function(stream, " <calls-out>%u</calls-out>\n", gp->ob_calls);
stream->write_function(stream, " <failed-calls-in>%u</failed-calls-in>\n", gp->ib_failed_calls);
stream->write_function(stream, " <failed-calls-out>%u</failed-calls-out>\n", gp->ob_failed_calls);
if (gp->state == REG_STATE_FAILED || gp->state == REG_STATE_TRYING) {
time_t now = switch_epoch_time_now(NULL);
@@ -2763,7 +2779,7 @@ static switch_status_t cmd_xml_status(char **argv, int argc, switch_stream_handl
} else if (!strcasecmp(argv[0], "profile")) {
struct cb_helper cb;
char *sql = NULL;
int x = 0;
uint32_t x = 0;
cb.row_process = 0;
@@ -2819,10 +2835,10 @@ static switch_status_t cmd_xml_status(char **argv, int argc, switch_stream_handl
stream->write_function(stream, " <user-agent-filter>%s</user-agent-filter>\n", switch_str_nil(profile->user_agent_filter));
stream->write_function(stream, " <max-registrations-per-extension>%d</max-registrations-per-extension>\n",
profile->max_registrations_perext);
stream->write_function(stream, " <calls-in>%d</calls-in>\n", profile->ib_calls);
stream->write_function(stream, " <calls-out>%d</calls-out>\n", profile->ob_calls);
stream->write_function(stream, " <failed-calls-in>%d</failed-calls-in>\n", profile->ib_failed_calls);
stream->write_function(stream, " <failed-calls-out>%d</failed-calls-out>\n", profile->ob_failed_calls);
stream->write_function(stream, " <calls-in>%u</calls-in>\n", profile->ib_calls);
stream->write_function(stream, " <calls-out>%u</calls-out>\n", profile->ob_calls);
stream->write_function(stream, " <failed-calls-in>%u</failed-calls-in>\n", profile->ib_failed_calls);
stream->write_function(stream, " <failed-calls-out>%u</failed-calls-out>\n", profile->ob_failed_calls);
stream->write_function(stream, " </profile-info>\n");
}
stream->write_function(stream, " <registrations>\n");
@@ -2951,7 +2967,6 @@ static switch_status_t cmd_profile(char **argv, int argc, switch_stream_handle_t
sofia_profile_t *profile = NULL;
char *profile_name = argv[0];
const char *err;
switch_xml_t xml_root;
if (argc < 2) {
stream->write_function(stream, "Invalid Args!\n");
@@ -2959,12 +2974,10 @@ static switch_status_t cmd_profile(char **argv, int argc, switch_stream_handle_t
}
if (!strcasecmp(argv[1], "start")) {
if (argc > 2 && !strcasecmp(argv[2], "reloadxml")) {
if ((xml_root = switch_xml_open_root(1, &err))) {
switch_xml_free(xml_root);
}
stream->write_function(stream, "Reload XML [%s]\n", err);
}
switch_xml_reload(&err);
stream->write_function(stream, "Reload XML [%s]\n", err);
if (config_sofia(1, argv[0]) == SWITCH_STATUS_SUCCESS) {
stream->write_function(stream, "%s started successfully\n", argv[0]);
} else {
@@ -3039,12 +3052,8 @@ static switch_status_t cmd_profile(char **argv, int argc, switch_stream_handle_t
if (!strcasecmp(argv[1], "rescan")) {
if (argc > 2 && !strcasecmp(argv[2], "reloadxml")) {
if ((xml_root = switch_xml_open_root(1, &err))) {
switch_xml_free(xml_root);
}
stream->write_function(stream, "Reload XML [%s]\n", err);
}
switch_xml_reload(&err);
stream->write_function(stream, "Reload XML [%s]\n", err);
if (reconfig_sofia(profile) == SWITCH_STATUS_SUCCESS) {
stream->write_function(stream, "+OK scan complete\n");
@@ -3141,12 +3150,8 @@ static switch_status_t cmd_profile(char **argv, int argc, switch_stream_handle_t
profile->name, rsec, remain, remain == 1 ? "" : "s");
} else {
if (argc > 2 && !strcasecmp(argv[2], "reloadxml")) {
if ((xml_root = switch_xml_open_root(1, &err))) {
switch_xml_free(xml_root);
}
stream->write_function(stream, "Reload XML [%s]\n", err);
}
switch_xml_reload(&err);
stream->write_function(stream, "Reload XML [%s]\n", err);
if (!strcasecmp(argv[1], "stop")) {
sofia_clear_pflag_locked(profile, PFLAG_RUNNING);
@@ -3171,6 +3176,21 @@ static switch_status_t cmd_profile(char **argv, int argc, switch_stream_handle_t
goto done;
}
if (!strcasecmp(argv[1], "gwlist")) {
int up = 1;
if (argc > 2) {
if (!strcasecmp(argv[2], "down")) {
up = 0;
}
}
sofia_glue_gateway_list(profile, stream, up);
goto done;
}
stream->write_function(stream, "-ERR Unknown command!\n");
done:
@@ -3487,7 +3507,7 @@ SWITCH_STANDARD_API(sofia_function)
const char *usage_string = "USAGE:\n"
"--------------------------------------------------------------------------------\n"
"sofia help\n"
"sofia profile <profile_name> [[start|stop|restart|rescan] [reloadxml]|"
"sofia profile <profile_name> [[start|stop|restart|rescan]|"
"flush_inbound_reg [<call_id>] [reboot]|"
"[register|unregister] [<gateway name>|all]|"
"killgw <gateway name>|"
@@ -3497,6 +3517,7 @@ SWITCH_STANDARD_API(sofia_function)
"sofia status|xmlstatus gateway <name>\n"
"sofia loglevel <all|default|tport|iptsec|nea|nta|nth_client|nth_server|nua|soa|sresolv|stun> [0-9]\n"
"sofia tracelevel <console|alert|crit|err|warning|notice|info|debug>\n"
"sofa global siptrace [on|off]\n"
"--------------------------------------------------------------------------------\n";
if (session) {
@@ -3552,6 +3573,26 @@ SWITCH_STANDARD_API(sofia_function)
} else if (!strcasecmp(argv[0], "help")) {
stream->write_function(stream, "%s", usage_string);
goto done;
} else if (!strcasecmp(argv[0], "global")) {
int on = -1;
if (argc > 1) {
if (!strcasecmp(argv[1], "siptrace")) {
if (argc > 2) {
on = switch_true(argv[2]);
}
}
}
if (on != -1) {
sofia_glue_global_siptrace(on);
stream->write_function(stream, "+OK Global siptrace %s", on ? "on" : "off");
} else {
stream->write_function(stream, "-ERR Usage: siptrace on|off");
}
goto done;
} else if (!strcasecmp(argv[0], "recover")) {
if (argv[1] && !strcasecmp(argv[1], "flush")) {
sofia_glue_recover(SWITCH_TRUE);
@@ -4353,7 +4394,8 @@ static void general_event_handler(switch_event_t *event)
switch_mutex_lock(mod_sofia_globals.hash_mutex);
if (mod_sofia_globals.profile_hash) {
for (hi = switch_hash_first(NULL, mod_sofia_globals.profile_hash); hi; hi = switch_hash_next(hi)) {
int rb = 0, x = 0;
int rb = 0;
uint32_t x = 0;
switch_hash_this(hi, &var, NULL, &val);
if ((profile = (sofia_profile_t *) val) && profile->auto_restart) {
if (!strcmp(profile->sipip, old_ip4)) {
@@ -4623,15 +4665,19 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load)
switch_console_set_complete("add sofia help");
switch_console_set_complete("add sofia status");
switch_console_set_complete("add sofia xmlstatus");
switch_console_set_complete("add sofia loglevel");
switch_console_set_complete("add sofia tracelevel");
switch_console_set_complete("add sofia loglevel ::[all:default:tport:iptsec:nea:nta:nth_client:nth_server:nua:soa:sresolv:stun ::[0:1:2:3:4:5:6:7:8:9");
switch_console_set_complete("add sofia tracelevel ::[console:alert:crit:err:warning:notice:info:debug");
switch_console_set_complete("add sofia global siptrace ::[on:off");
switch_console_set_complete("add sofia profile");
switch_console_set_complete("add sofia profile restart all");
switch_console_set_complete("add sofia profile ::sofia::list_profiles start reloadxml");
switch_console_set_complete("add sofia profile ::sofia::list_profiles stop reloadxml");
switch_console_set_complete("add sofia profile ::sofia::list_profiles rescan reloadxml");
switch_console_set_complete("add sofia profile ::sofia::list_profiles restart reloadxml");
switch_console_set_complete("add sofia profile ::sofia::list_profiles start");
switch_console_set_complete("add sofia profile ::sofia::list_profiles stop");
switch_console_set_complete("add sofia profile ::sofia::list_profiles rescan");
switch_console_set_complete("add sofia profile ::sofia::list_profiles restart");
switch_console_set_complete("add sofia profile ::sofia::list_profiles flush_inbound_reg");
switch_console_set_complete("add sofia profile ::sofia::list_profiles register ::sofia::list_profile_gateway");
@@ -4640,6 +4686,9 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load)
switch_console_set_complete("add sofia profile ::sofia::list_profiles siptrace on");
switch_console_set_complete("add sofia profile ::sofia::list_profiles siptrace off");
switch_console_set_complete("add sofia profile ::sofia::list_profiles gwlist up");
switch_console_set_complete("add sofia profile ::sofia::list_profiles gwlist down");
switch_console_set_complete("add sofia status profile ::sofia::list_profiles");
switch_console_set_complete("add sofia status profile ::sofia::list_profiles reg");
switch_console_set_complete("add sofia status gateway ::sofia::list_gateways");
+10
View File
@@ -106,6 +106,7 @@ typedef struct private_object private_object_t;
#define SOFIA_CRYPTO_MANDATORY_VARIABLE "sip_crypto_mandatory"
#define FREESWITCH_SUPPORT "update_display"
#include <switch_stun.h>
#include <sofia-sip/nua.h>
#include <sofia-sip/sip_status.h>
#include <sofia-sip/sdp.h>
@@ -199,6 +200,7 @@ typedef enum {
PFLAG_DISABLE_NAPTR,
PFLAG_AUTOFLUSH,
PFLAG_NAT_OPTIONS_PING,
PFLAG_ALL_REG_OPTIONS_PING,
PFLAG_AUTOFIX_TIMING,
PFLAG_MESSAGE_QUERY_ON_REGISTER,
PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER,
@@ -218,6 +220,7 @@ typedef enum {
PFLAG_T38_PASSTHRU,
PFLAG_CID_IN_1XX,
PFLAG_IN_DIALOG_CHAT,
PFLAG_DEL_SUBS_ON_REG,
/* No new flags below this line */
PFLAG_MAX
} PFLAGS;
@@ -275,6 +278,7 @@ typedef enum {
TFLAG_RECOVERING,
TFLAG_RECOVERING_BRIDGE,
TFLAG_T38_PASSTHRU,
TFLAG_RECOVERED,
/* No new flags below this line */
TFLAG_MAX
} TFLAGS;
@@ -574,6 +578,7 @@ struct private_object {
switch_codec_t read_codec;
switch_codec_t write_codec;
uint32_t codec_ms;
uint32_t bitrate;
switch_caller_profile_t *caller_profile;
uint32_t timestamp_send;
switch_rtp_t *rtp_session;
@@ -939,6 +944,7 @@ switch_status_t sofia_glue_tech_set_video_codec(private_object_t *tech_pvt, int
const char *sofia_glue_strip_proto(const char *uri);
switch_status_t reconfig_sofia(sofia_profile_t *profile);
void sofia_glue_del_gateway(sofia_gateway_t *gp);
void sofia_glue_gateway_list(sofia_profile_t *profile, switch_stream_handle_t *stream, int up);
void sofia_glue_del_every_gateway(sofia_profile_t *profile);
void sofia_reg_send_reboot(sofia_profile_t *profile, const char *user, const char *host, const char *contact, const char *user_agent,
const char *network_ip);
@@ -1008,3 +1014,7 @@ char *sofia_glue_get_multipart(switch_core_session_t *session, const char *prefi
void sofia_glue_tech_simplify(private_object_t *tech_pvt);
switch_console_callback_match_t *sofia_reg_find_reg_url_multi(sofia_profile_t *profile, const char *user, const char *host);
switch_bool_t sofia_glue_profile_exists(const char *key);
void sofia_glue_global_siptrace(switch_bool_t on);
void sofia_glue_proxy_codec(switch_core_session_t *session, const char *r_sdp);
switch_status_t sofia_glue_sdp_map(const char *r_sdp, switch_event_t **fmtp, switch_event_t **pt);
void sofia_glue_build_vid_refresh_message(switch_core_session_t *session, const char *pl);
+1 -1
View File
@@ -785,7 +785,7 @@ int dig_addr(struct dig *dig,
char const *tport2 = NULL;
sres_record_t **answers1 = NULL, **answers2 = NULL;
unsigned count1 = 0, count2 = 0, tcount = 0;
int type1 = 0, type2 = 0, family1 = 0, family2 = 0;
uint16_t type1 = 0, type2 = 0, family1 = 0, family2 = 0;
if (dig->ip6 > dig->ip4) {
type1 = sres_type_aaaa, family1 = AF_INET6;
+157 -34
View File
@@ -1225,7 +1225,7 @@ static void sofia_perform_profile_start_failure(sofia_profile_t *profile, char *
#define sofia_profile_start_failure(p, xp) sofia_perform_profile_start_failure(p, xp, __FILE__, __LINE__)
#define SQLLEN 1024 * 64
#define SQLLEN 1024 * 1024
void *SWITCH_THREAD_FUNC sofia_profile_worker_thread_run(switch_thread_t *thread, void *obj)
{
sofia_profile_t *profile = (sofia_profile_t *) obj;
@@ -1233,11 +1233,12 @@ void *SWITCH_THREAD_FUNC sofia_profile_worker_thread_run(switch_thread_t *thread
uint32_t gateway_loops = 0;
int loops = 0;
uint32_t qsize;
void *pop;
void *pop = NULL;
int loop_count = 0;
switch_size_t sql_len = SQLLEN;
switch_size_t sql_len = 1024 * 32;
char *tmp, *sqlbuf = NULL;
char *sql = NULL;
if (sofia_test_pflag(profile, PFLAG_SQL_IN_TRANS)) {
sqlbuf = (char *) malloc(sql_len);
}
@@ -1253,37 +1254,43 @@ void *SWITCH_THREAD_FUNC sofia_profile_worker_thread_run(switch_thread_t *thread
while ((mod_sofia_globals.running == 1 && sofia_test_pflag(profile, PFLAG_RUNNING)) || qsize) {
if (sofia_test_pflag(profile, PFLAG_SQL_IN_TRANS)) {
if (qsize > 0 && (qsize >= 1024 || ++loop_count >= profile->trans_timeout)) {
if (qsize > 0 && (qsize >= 1024 || ++loop_count >= (int)profile->trans_timeout)) {
switch_size_t newlen;
uint32_t itterations = 0;
uint32_t iterations = 0;
switch_size_t len = 0;
switch_mutex_lock(profile->ireg_mutex);
//sofia_glue_actually_execute_sql(profile, "begin;\n", NULL);
while (switch_queue_trypop(profile->sql_queue, &pop) == SWITCH_STATUS_SUCCESS && pop) {
char *sql = (char *) pop;
while (sql || (switch_queue_trypop(profile->sql_queue, &pop) == SWITCH_STATUS_SUCCESS && pop)) {
if (!sql) sql = (char *) pop;
newlen = strlen(sql) + 2;
iterations++;
if (newlen + 10 < SQLLEN) {
itterations++;
if (len + newlen + 10 > sql_len) {
sql_len = len + 10 + SQLLEN;
if (len + newlen + 10 > sql_len) {
switch_size_t new_mlen = len + newlen + 10 + 10240;
if (new_mlen < SQLLEN) {
sql_len = new_mlen;
if (!(tmp = realloc(sqlbuf, sql_len))) {
abort();
break;
}
sqlbuf = tmp;
} else {
goto skip;
}
sprintf(sqlbuf + len, "%s;\n", sql);
len += newlen;
}
free(pop);
sprintf(sqlbuf + len, "%s;\n", sql);
len += newlen;
free(sql);
sql = NULL;
}
skip:
//printf("TRANS:\n%s\n", sqlbuf);
sofia_glue_actually_execute_sql_trans(profile, sqlbuf, NULL);
//sofia_glue_actually_execute_sql(profile, "commit;\n", NULL);
@@ -2258,6 +2265,12 @@ switch_status_t reconfig_sofia(sofia_profile_t *profile)
} else {
sofia_clear_pflag(profile, PFLAG_PASS_CALLEE_ID);
}
} else if (!strcasecmp(var, "delete-subs-on-register")) {
if (switch_true(val)) {
sofia_set_pflag(profile, PFLAG_DEL_SUBS_ON_REG);
} else {
sofia_clear_pflag(profile, PFLAG_DEL_SUBS_ON_REG);
}
} else if (!strcasecmp(var, "in-dialog-chat")) {
if (switch_true(val)) {
sofia_set_pflag(profile, PFLAG_IN_DIALOG_CHAT);
@@ -2305,12 +2318,6 @@ switch_status_t reconfig_sofia(sofia_profile_t *profile)
} else {
sofia_clear_pflag(profile, PFLAG_FORWARD_MWI_NOTIFY);
}
} else if (!strcasecmp(var, "forward-unsolicited-mwi-notify")) {
if (switch_true(val)) {
sofia_set_pflag(profile, PFLAG_FORWARD_MWI_NOTIFY);
} else {
sofia_clear_pflag(profile, PFLAG_FORWARD_MWI_NOTIFY);
}
} else if (!strcasecmp(var, "t38-passthru")) {
if (switch_true(val)) {
sofia_set_pflag(profile, PFLAG_T38_PASSTHRU);
@@ -2549,6 +2556,12 @@ switch_status_t reconfig_sofia(sofia_profile_t *profile)
} else {
sofia_clear_pflag(profile, PFLAG_NAT_OPTIONS_PING);
}
} else if (!strcasecmp(var, "all-reg-options-ping")) {
if (switch_true(val)) {
sofia_set_pflag(profile, PFLAG_ALL_REG_OPTIONS_PING);
} else {
sofia_clear_pflag(profile, PFLAG_ALL_REG_OPTIONS_PING);
}
} else if (!strcasecmp(var, "inbound-codec-negotiation")) {
if (!strcasecmp(val, "greedy")) {
sofia_set_pflag(profile, PFLAG_GREEDY);
@@ -2860,7 +2873,7 @@ switch_status_t config_sofia(int reload, char *profile_name)
goto done;
}
profile->trans_timeout = 500;
profile->trans_timeout = 100;
profile->auto_rtp_bugs = RTP_BUG_CISCO_SKIP_MARK_BIT_2833;// | RTP_BUG_SONUS_SEND_INVALID_TIMESTAMP_2833;
@@ -2920,6 +2933,12 @@ switch_status_t config_sofia(int reload, char *profile_name)
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ODBC IS NOT AVAILABLE!\n");
}
} else if (!strcasecmp(var, "forward-unsolicited-mwi-notify")) {
if (switch_true(val)) {
sofia_set_pflag(profile, PFLAG_FORWARD_MWI_NOTIFY);
} else {
sofia_clear_pflag(profile, PFLAG_FORWARD_MWI_NOTIFY);
}
} else if (!strcasecmp(var, "user-agent-string")) {
profile->user_agent = switch_core_strdup(profile->pool, val);
} else if (!strcasecmp(var, "auto-restart")) {
@@ -2936,6 +2955,12 @@ switch_status_t config_sofia(int reload, char *profile_name)
} else {
sofia_clear_pflag(profile, PFLAG_IN_DIALOG_CHAT);
}
} else if (!strcasecmp(var, "delete-subs-on-register")) {
if (switch_true(val)) {
sofia_set_pflag(profile, PFLAG_DEL_SUBS_ON_REG);
} else {
sofia_clear_pflag(profile, PFLAG_DEL_SUBS_ON_REG);
}
} else if (!strcasecmp(var, "t38-passthru")) {
if (switch_true(val)) {
sofia_set_pflag(profile, PFLAG_T38_PASSTHRU);
@@ -3303,6 +3328,12 @@ switch_status_t config_sofia(int reload, char *profile_name)
} else {
sofia_clear_pflag(profile, PFLAG_NAT_OPTIONS_PING);
}
} else if (!strcasecmp(var, "all-options-ping")) {
if (switch_true(val)) {
sofia_set_pflag(profile, PFLAG_ALL_REG_OPTIONS_PING);
} else {
sofia_clear_pflag(profile, PFLAG_ALL_REG_OPTIONS_PING);
}
} else if (!strcasecmp(var, "inbound-codec-negotiation")) {
if (!strcasecmp(val, "greedy")) {
sofia_set_pflag(profile, PFLAG_GREEDY);
@@ -3914,6 +3945,23 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status
}
}
#if 0
if (status == 200 && switch_channel_test_flag(channel, CF_PROXY_MEDIA) &&
sip->sip_payload && sip->sip_payload->pl_data && !strcasecmp(tech_pvt->iananame, "PROXY")) {
switch_core_session_t *other_session;
sofia_glue_proxy_codec(session, sip->sip_payload->pl_data);
if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) {
if (switch_core_session_compare(session, other_session)) {
sofia_glue_proxy_codec(other_session, sip->sip_payload->pl_data);
}
switch_core_session_rwunlock(other_session);
}
}
#endif
if ((status == 180 || status == 183 || status == 200)) {
const char *x_freeswitch_support;
@@ -3940,7 +3988,7 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status
}
if (channel && sip && (status == 300 || status == 302 || status == 305) && switch_channel_test_flag(channel, CF_OUTBOUND)) {
if (channel && sip && (status == 300 || status == 301 || status == 302 || status == 305) && switch_channel_test_flag(channel, CF_OUTBOUND)) {
sip_contact_t *p_contact = sip->sip_contact;
int i = 0;
char var_name[80];
@@ -4090,7 +4138,8 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status
}
}
if (tech_pvt && tech_pvt->remote_sdp_str && switch_stristr("m=image", tech_pvt->remote_sdp_str)) {
if (sip->sip_payload && sip->sip_payload->pl_data && switch_stristr("m=image", sip->sip_payload->pl_data)) {
has_t38 = 1;
}
@@ -4118,6 +4167,36 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status
if (status == 200 && sofia_test_flag(tech_pvt, TFLAG_T38_PASSTHRU) && has_t38) {
if (sip->sip_payload && sip->sip_payload->pl_data) {
switch_t38_options_t *t38_options = sofia_glue_extract_t38_options(session, sip->sip_payload->pl_data);
char *remote_host = switch_rtp_get_remote_host(tech_pvt->rtp_session);
switch_port_t remote_port = switch_rtp_get_remote_port(tech_pvt->rtp_session);
char tmp[32] = "";
tech_pvt->remote_sdp_audio_ip = switch_core_session_strdup(tech_pvt->session, t38_options->remote_ip);
tech_pvt->remote_sdp_audio_port = t38_options->remote_port;
if (remote_host && remote_port && !strcmp(remote_host, tech_pvt->remote_sdp_audio_ip) &&
remote_port == tech_pvt->remote_sdp_audio_port) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG,
"Audio params are unchanged for %s.\n",
switch_channel_get_name(tech_pvt->channel));
} else {
const char *err = NULL;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG,
"Audio params changed for %s from %s:%d to %s:%d\n",
switch_channel_get_name(tech_pvt->channel),
remote_host, remote_port, tech_pvt->remote_sdp_audio_ip, tech_pvt->remote_sdp_audio_port);
switch_snprintf(tmp, sizeof(tmp), "%d", tech_pvt->remote_sdp_audio_port);
switch_channel_set_variable(tech_pvt->channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE, tech_pvt->remote_sdp_audio_ip);
switch_channel_set_variable(tech_pvt->channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE, tmp);
if (switch_rtp_set_remote_address(tech_pvt->rtp_session, tech_pvt->remote_sdp_audio_ip,
tech_pvt->remote_sdp_audio_port, 0, SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR, "AUDIO RTP REPORTS ERROR: [%s]\n", err);
switch_channel_hangup(channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION);
}
}
if (t38_options) {
sofia_glue_copy_t38_options(t38_options, other_session);
@@ -4145,16 +4224,13 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status
}
if (status == 200 && sofia_test_flag(tech_pvt, TFLAG_T38_PASSTHRU) && has_t38) {
switch_core_session_receive_message(other_session, msg);
if (switch_rtp_ready(tech_pvt->rtp_session) && switch_rtp_ready(other_tech_pvt->rtp_session)) {
switch_rtp_udptl_mode(tech_pvt->rtp_session);
switch_rtp_udptl_mode(other_tech_pvt->rtp_session);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Activating T38 Passthru\n");
}
} else {
switch_core_session_queue_message(other_session, msg);
}
switch_core_session_queue_message(other_session, msg);
switch_core_session_rwunlock(other_session);
}
@@ -4374,7 +4450,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
if (ss_state == nua_callstate_terminated) {
if ((status == 300 || status == 302 || status == 305) && session) {
if ((status == 300 || status == 301 || status == 302 || status == 305) && session) {
channel = switch_core_session_get_channel(session);
tech_pvt = switch_core_session_get_private(session);
@@ -4447,6 +4523,8 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
}
}
state_process:
switch ((enum nua_callstate) ss_state) {
@@ -4521,7 +4599,20 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
}
break;
case nua_callstate_completing:
nua_ack(nh, TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), TAG_END());
{
if (sofia_test_pflag(profile, PFLAG_TRACK_CALLS)) {
const char *invite_full_via = switch_channel_get_variable(tech_pvt->channel, "sip_invite_full_via");
const char *invite_route_uri = switch_channel_get_variable(tech_pvt->channel, "sip_invite_route_uri");
nua_ack(nh,
TAG_IF(!zstr(invite_full_via), SIPTAG_VIA_STR(invite_full_via)),
TAG_IF(!zstr(invite_route_uri), SIPTAG_ROUTE_STR(invite_route_uri)),
TAG_END());
} else {
nua_ack(nh, TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), TAG_END());
}
}
goto done;
case nua_callstate_received:
if (!sofia_test_flag(tech_pvt, TFLAG_SDP)) {
@@ -4912,6 +5003,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
sofia_set_flag_locked(tech_pvt, TFLAG_ANS);
sofia_set_flag(tech_pvt, TFLAG_SDP);
switch_channel_mark_answered(channel);
if (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
if ((uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE))
&& (other_session = switch_core_session_locate(uuid))) {
@@ -4932,6 +5024,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
sofia_set_flag_locked(tech_pvt, TFLAG_ANS);
sofia_set_flag_locked(tech_pvt, TFLAG_SDP);
switch_channel_mark_answered(channel);
if (switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
if (sofia_glue_activate_rtp(tech_pvt, 0) != SWITCH_STATUS_SUCCESS) {
goto done;
@@ -5037,6 +5130,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
}
done:
if ((enum nua_callstate) ss_state == nua_callstate_ready && channel && session && tech_pvt) {
sofia_glue_tech_simplify(tech_pvt);
@@ -5188,7 +5282,6 @@ nua_handle_t *sofia_global_nua_handle_by_replaces(sip_replaces_t *replaces)
}
void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, switch_core_session_t *session, sip_t const *sip, tagi_t tags[])
{
/* Incoming refer */
@@ -5761,7 +5854,17 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t
if (sip && sip->sip_content_type && sip->sip_content_type->c_type && sip->sip_content_type->c_subtype &&
sip->sip_payload && sip->sip_payload->pl_data) {
if (!strncasecmp(sip->sip_content_type->c_type, "application", 11) && !strcasecmp(sip->sip_content_type->c_subtype, "dtmf-relay")) {
if (!strncasecmp(sip->sip_content_type->c_type, "application", 11) && !strcasecmp(sip->sip_content_type->c_subtype, "media_control+xml")) {
switch_core_session_t *other_session;
if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) {
sofia_glue_build_vid_refresh_message(other_session, sip->sip_payload->pl_data);
switch_core_session_rwunlock(other_session);
} else {
sofia_glue_build_vid_refresh_message(session, sip->sip_payload->pl_data);
}
} else if (!strncasecmp(sip->sip_content_type->c_type, "application", 11) && !strcasecmp(sip->sip_content_type->c_subtype, "dtmf-relay")) {
/* Try and find signal information in the payload */
if ((signal_ptr = switch_stristr("Signal=", sip->sip_payload->pl_data))) {
int tmp;
@@ -5901,6 +6004,26 @@ void sofia_handle_sip_i_reinvite(switch_core_session_t *session,
{
char *call_info = NULL;
if (session && profile && sip && sofia_test_pflag(profile, PFLAG_TRACK_CALLS)) {
switch_channel_t *channel = switch_core_session_get_channel(session);
private_object_t *tech_pvt = (private_object_t *) switch_core_session_get_private(session);
char network_ip[80];
int network_port = 0;
char via_space[2048];
char branch[16] = "";
sofia_glue_get_addr(nua_current_request(nua), network_ip, sizeof(network_ip), &network_port);
switch_stun_random_string(branch, sizeof(branch) - 1, "0123456789abcdef");
switch_snprintf(via_space, sizeof(via_space), "SIP/2.0/UDP %s;rport=%d;branch=%s", network_ip, network_port, branch);
switch_channel_set_variable(channel, "sip_full_via", via_space);
switch_channel_set_variable_printf(channel, "sip_network_port", "%d", network_port);
switch_channel_set_variable_printf(channel, "sip_recieved_port", "%d", network_port);
switch_channel_set_variable_printf(channel, "sip_via_rport", "%d", network_port);
sofia_glue_tech_track(tech_pvt->profile, session);
}
if (sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)) {
switch_channel_t *channel = switch_core_session_get_channel(session);
if (channel && sip->sip_call_info) {
File diff suppressed because it is too large Load Diff
+15 -3
View File
@@ -1442,7 +1442,7 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char *
op = switch_event_get_header(helper->event, "Caller-Callee-ID-Number");
}
if (!op) {
if (zstr(op)) {
op = switch_event_get_header(helper->event, "Caller-Destination-Number");
}
@@ -1452,7 +1452,7 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char *
if (!strcmp(astate, "early")) {
if (zstr(op)) {
switch_snprintf(status_line, sizeof(status_line), "%s %s", what, status);
switch_snprintf(status_line, sizeof(status_line), "%sing", what);
} else {
switch_snprintf(status_line, sizeof(status_line), "%s %s", what, op);
}
@@ -1983,12 +1983,20 @@ void sofia_presence_handle_sip_i_subscribe(int status,
is_nat = NULL;
}
if (zstr(contact_host)) {
is_nat = "No contact host";
}
if (is_nat) {
contact_host = network_ip;
switch_snprintf(new_port, sizeof(new_port), ":%d", network_port);
port = NULL;
}
if (zstr(contact_host)) {
nua_respond(nh, 481, "INVALID SUBSCRIPTION", TAG_END());
return;
}
if (port) {
switch_snprintf(new_port, sizeof(new_port), ":%s", port);
@@ -2043,7 +2051,11 @@ void sofia_presence_handle_sip_i_subscribe(int status,
from_host = "n/a";
}
exp_delta = profile->force_subscription_expires ? profile->force_subscription_expires : (sip->sip_expires ? sip->sip_expires->ex_delta : 3600);
if ((exp_delta = sip->sip_expires ? sip->sip_expires->ex_delta : 3600)) {
if (profile->force_subscription_expires) {
exp_delta = profile->force_subscription_expires;
}
}
if (exp_delta) {
exp_abs = (long) switch_epoch_time_now(NULL) + exp_delta;
+134 -124
View File
@@ -438,11 +438,14 @@ int sofia_reg_nat_callback(void *pArg, int argc, char **argv, char **columnNames
switch_snprintf(to, sizeof(to), "sip:%s@%s", argv[1], argv[2]);
dst = sofia_glue_get_destination(argv[3]);
switch_assert(dst);
nh = nua_handle(profile->nua, NULL, SIPTAG_FROM_STR(profile->url), SIPTAG_TO_STR(to), NUTAG_URL(dst->contact), SIPTAG_CONTACT_STR(profile->url),
TAG_END());
nua_handle_bind(nh, &mod_sofia_globals.destroy_private);
nua_options(nh, TAG_IF(dst->route_uri, NUTAG_PROXY(dst->route_uri)), TAG_IF(dst->route, SIPTAG_ROUTE_STR(dst->route)), TAG_END());
nua_options(nh,
NTATAG_SIP_T2(5000),
NTATAG_SIP_T4(10000),
TAG_IF(dst->route_uri, NUTAG_PROXY(dst->route_uri)), TAG_IF(dst->route, SIPTAG_ROUTE_STR(dst->route)), TAG_END());
sofia_glue_free_destination(dst);
@@ -514,7 +517,7 @@ int sofia_reg_del_callback(void *pArg, int argc, char **argv, char **columnNames
switch_event_fire(&s_event);
}
if (switch_event_create(&s_event, SWITCH_EVENT_PRESENCE_OUT) == SWITCH_STATUS_SUCCESS) {
if (switch_event_create(&s_event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "rpid", "away");
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "login", profile->url);
@@ -637,15 +640,14 @@ void sofia_reg_check_expire(sofia_profile_t *profile, time_t now, int reboot)
}
sofia_glue_actually_execute_sql(profile, sql, NULL);
if (now) {
switch_snprintf(sql, sizeof(sql),
"select call_id from sip_subscriptions where (expires = -1 or (expires > 0 and expires <= %ld)) and hostname='%s'", (long) now,
mod_sofia_globals.hostname);
} else {
switch_snprintf(sql, sizeof(sql), "select call_id from sip_subscriptions where expires >= -1 and hostname='%s'", mod_sofia_globals.hostname);
switch_snprintf(sql, sizeof(sql), "select sub_to_user,sub_to_host,call_id from sip_subscriptions where expires >= -1 and hostname='%s'",
mod_sofia_globals.hostname);
}
sofia_glue_execute_sql_callback(profile, NULL, sql, sofia_sub_del_callback, profile);
@@ -670,13 +672,21 @@ void sofia_reg_check_expire(sofia_profile_t *profile, time_t now, int reboot)
sofia_glue_actually_execute_sql(profile, sql, NULL);
if (now && sofia_test_pflag(profile, PFLAG_NAT_OPTIONS_PING)) {
switch_snprintf(sql, sizeof(sql), "select call_id,sip_user,sip_host,contact,status,rpid,"
"expires,user_agent,server_user,server_host,profile_name"
" from sip_registrations where (status like '%%AUTO-NAT%%' "
"or status like '%%UDP-NAT%%') and hostname='%s'", mod_sofia_globals.hostname);
sofia_glue_execute_sql_callback(profile, NULL, sql, sofia_reg_nat_callback, profile);
if (now) {
if (sofia_test_pflag(profile, PFLAG_ALL_REG_OPTIONS_PING)) {
switch_snprintf(sql, sizeof(sql), "select call_id,sip_user,sip_host,contact,status,rpid,"
"expires,user_agent,server_user,server_host,profile_name"
" from sip_registrations where hostname='%s'", mod_sofia_globals.hostname);
sofia_glue_execute_sql_callback(profile, NULL, sql, sofia_reg_nat_callback, profile);
} else if (sofia_test_pflag(profile, PFLAG_NAT_OPTIONS_PING)) {
switch_snprintf(sql, sizeof(sql), "select call_id,sip_user,sip_host,contact,status,rpid,"
"expires,user_agent,server_user,server_host,profile_name"
" from sip_registrations where (status like '%%NAT%%' "
"or contact like '%%fs_nat=yes%%') and hostname='%s'", mod_sofia_globals.hostname);
sofia_glue_execute_sql_callback(profile, NULL, sql, sofia_reg_nat_callback, profile);
}
}
switch_mutex_unlock(profile->ireg_mutex);
@@ -810,6 +820,10 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
switch_event_t *auth_params = NULL;
int r = 0;
long reg_count = 0;
int delete_subs;
const char *agent = "unknown";
delete_subs = sofia_test_pflag(profile, PFLAG_DEL_SUBS_ON_REG);
/* all callers must confirm that sip, sip->sip_request and sip->sip_contact are not NULL */
switch_assert(sip != NULL && sip->sip_contact != NULL && sip->sip_request != NULL);
@@ -826,6 +840,10 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
to = sip->sip_to;
from = sip->sip_from;
if (sip->sip_user_agent) {
agent = sip->sip_user_agent->g_string;
}
if (from) {
from_user = from->a_url->url_user;
from_host = from->a_url->url_host;
@@ -913,7 +931,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
if (sip->sip_path) {
path_val = sip_header_as_string(nua_handle_home(nh), (void *) sip->sip_path);
path_encoded_len = (strlen(path_val) * 3) + 1;
path_encoded_len = (int)(strlen(path_val) * 3) + 1;
switch_zmalloc(path_encoded, path_encoded_len);
switch_copy_string(path_encoded, ";fs_path=", 10);
switch_url_encode(path_val, path_encoded + 9, path_encoded_len - 9);
@@ -926,7 +944,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
switch_snprintf(my_contact_str, sizeof(my_contact_str), "sip:%s@%s:%d", contact->m_url->url_user, url_ip, network_port);
}
path_encoded_len = (strlen(my_contact_str) * 3) + 1;
path_encoded_len = (int)(strlen(my_contact_str) * 3) + 1;
switch_zmalloc(path_encoded, path_encoded_len);
switch_copy_string(path_encoded, ";fs_path=", 10);
@@ -1135,7 +1153,6 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
}
if (exptime) {
const char *agent = "dunno";
char guess_ip4[256];
const char *username = "unknown";
const char *realm = reg_host;
@@ -1145,19 +1162,15 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
realm = switch_event_get_header(auth_params, "sip_auth_realm");
}
if (sip->sip_user_agent) {
agent = sip->sip_user_agent->g_string;
}
if (multi_reg) {
#ifdef DEL_SUBS
if (reg_count == 1) {
sql = switch_mprintf("delete from sip_subscriptions where sip_user='%q' and sip_host='%q' and contact='%q'",
to_user, sub_host, contact_str);
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
if (delete_subs) {
if (reg_count == 1) {
sql = switch_mprintf("delete from sip_subscriptions where sip_user='%q' and sip_host='%q' and contact='%q'",
to_user, sub_host, contact_str);
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
}
}
#endif
if (multi_reg_contact) {
@@ -1167,10 +1180,10 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
sql = switch_mprintf("delete from sip_registrations where call_id='%q'", call_id);
}
} else {
#ifdef DEL_SUBS
sql = switch_mprintf("delete from sip_subscriptions where sip_user='%q' and sip_host='%q'", to_user, sub_host);
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
#endif
if (delete_subs) {
sql = switch_mprintf("delete from sip_subscriptions where sip_user='%q' and sip_host='%q'", to_user, sub_host);
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
}
sql = switch_mprintf("delete from sip_registrations where sip_user='%q' and sip_host='%q'", to_user, reg_host);
}
switch_mutex_lock(profile->ireg_mutex);
@@ -1185,7 +1198,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
"mwi_user,mwi_host, orig_server_host, orig_hostname) "
"values ('%q','%q', '%q','%q','%q','%q', '%q', %ld, '%q', '%q', '%q', '%q', '%q', '%q', '%q','%q','%q','%q','%q','%q','%q')",
call_id, to_user, reg_host, profile->presence_hosts ? profile->presence_hosts : reg_host,
contact_str, reg_desc, rpid, (long) switch_epoch_time_now(NULL) + (long) exptime * 2,
contact_str, reg_desc, rpid, (long) switch_epoch_time_now(NULL) + (long) exptime + 60,
agent, from_user, guess_ip4, profile->name, mod_sofia_globals.hostname, network_ip, network_port_c, username, realm,
mwi_user, mwi_host, guess_ip4, mod_sofia_globals.hostname);
@@ -1290,16 +1303,16 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
if ((p = strchr(icontact + 4, ':'))) {
*p = '\0';
}
#ifdef DEL_SUBS
if (multi_reg_contact) {
sql =
switch_mprintf("delete from sip_subscriptions where sip_user='%q' and sip_host='%q' and contact='%q'", to_user, sub_host, contact_str);
} else {
sql = switch_mprintf("delete from sip_subscriptions where call_id='%q'", call_id);
}
if (delete_subs) {
if (multi_reg_contact) {
sql =
switch_mprintf("delete from sip_subscriptions where sip_user='%q' and sip_host='%q' and contact='%q'", to_user, sub_host, contact_str);
} else {
sql = switch_mprintf("delete from sip_subscriptions where call_id='%q'", call_id);
}
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
#endif
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
}
if (multi_reg_contact) {
sql =
@@ -1312,11 +1325,11 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
switch_safe_free(icontact);
} else {
#ifdef DEL_SUBS
if ((sql = switch_mprintf("delete from sip_subscriptions where sip_user='%q' and sip_host='%q'", to_user, sub_host))) {
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
if (delete_subs) {
if ((sql = switch_mprintf("delete from sip_subscriptions where sip_user='%q' and sip_host='%q'", to_user, sub_host))) {
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
}
}
#endif
if ((sql = switch_mprintf("delete from sip_registrations where sip_user='%q' and sip_host='%q'", to_user, reg_host))) {
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
}
@@ -2110,7 +2123,8 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
if (auth_acl) {
if (!switch_check_network_list_ip(ip, auth_acl)) {
int network_ip_is_proxy = 0, x = 0;
int network_ip_is_proxy = 0;
uint32_t x = 0;
char *last_acl = NULL;
if (profile->proxy_acl_count == 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "IP %s Rejected by user acl [%s] and no proxy acl present\n", ip, auth_acl);
@@ -2207,7 +2221,7 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
if (max_registrations_perext > 0 && (sip && sip->sip_contact && (sip->sip_contact->m_expires == NULL || atol(sip->sip_contact->m_expires) > 0))) {
/* if expires is null still process */
/* expires == 0 means the phone is going to unregiser, so don't count against max */
int count = 0;
uint32_t count = 0;
call_id = sip->sip_call_id->i_id;
switch_assert(call_id);
@@ -2292,9 +2306,9 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
switch_event_add_header_string(*v_event, SWITCH_STACK_BOTTOM, "mwi-account", mwi_account);
}
if ((uparams = switch_xml_child(user, "params"))) {
if ((dparams = switch_xml_child(domain, "params"))) {
xparams_type[i] = 0;
xparams[i++] = uparams;
xparams[i++] = dparams;
}
if (group && (gparams = switch_xml_child(group, "params"))) {
@@ -2302,102 +2316,98 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
xparams[i++] = gparams;
}
if ((dparams = switch_xml_child(domain, "params"))) {
if ((uparams = switch_xml_child(user, "params"))) {
xparams_type[i] = 0;
xparams[i++] = dparams;
}
if ((uparams = switch_xml_child(user, "variables"))) {
xparams_type[i] = 1;
xparams[i++] = uparams;
}
if (group && (gparams = switch_xml_child(group, "variables"))) {
xparams_type[i] = 1;
xparams[i++] = gparams;
}
if ((dparams = switch_xml_child(domain, "variables"))) {
xparams_type[i] = 1;
xparams[i++] = dparams;
}
if (group && (gparams = switch_xml_child(group, "variables"))) {
xparams_type[i] = 1;
xparams[i++] = gparams;
}
if ((uparams = switch_xml_child(user, "variables"))) {
xparams_type[i] = 1;
xparams[i++] = uparams;
}
if (i <= 6) {
int j = 0;
const char *gw_val = NULL;
for (j = 0; j < i; j++) {
for (param = switch_xml_child(xparams[j], (xparams_type[j] ? "variable" : "param")); param; param = param->next) {
const char *var = switch_xml_attr_soft(param, "name");
const char *val = switch_xml_attr_soft(param, "value");
sofia_gateway_t *gateway_ptr = NULL;
if (!zstr(var) && !zstr(val) && (xparams_type[j] == 1 || !strncasecmp(var, "sip-", 4) || !strcasecmp(var, "register-gateway"))) {
if (!switch_event_get_header(*v_event, var)) {
if (profile->debug) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "event_add_header -> '%s' = '%s'\n", var, val);
}
switch_event_add_header_string(*v_event, SWITCH_STACK_BOTTOM, var, val);
} else {
continue;
if (profile->debug) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "event_add_header -> '%s' = '%s'\n", var, val);
}
if (!strcasecmp(var, "register-gateway")) {
if (!strcasecmp(val, "all")) {
switch_xml_t gateways_tag, gateway_tag;
if ((gateways_tag = switch_xml_child(user, "gateways"))) {
for (gateway_tag = switch_xml_child(gateways_tag, "gateway"); gateway_tag; gateway_tag = gateway_tag->next) {
char *name = (char *) switch_xml_attr_soft(gateway_tag, "name");
if (zstr(name)) {
name = "anonymous";
}
if ((gateway_ptr = sofia_reg_find_gateway(name))) {
reg_state_t ostate = gateway_ptr->state;
gateway_ptr->retry = 0;
if (exptime) {
gateway_ptr->state = REG_STATE_UNREGED;
} else {
gateway_ptr->state = REG_STATE_UNREGISTER;
}
if (ostate != gateway_ptr->state) {
sofia_reg_fire_custom_gateway_state_event(gateway_ptr, 0, NULL);
}
sofia_reg_release_gateway(gateway_ptr);
}
}
}
} else {
int x, argc;
char *mydata, *argv[50];
mydata = strdup(val);
switch_assert(mydata != NULL);
argc = switch_separate_string(mydata, ',', argv, (sizeof(argv) / sizeof(argv[0])));
for (x = 0; x < argc; x++) {
if ((gateway_ptr = sofia_reg_find_gateway((char *) argv[x]))) {
reg_state_t ostate = gateway_ptr->state;
gateway_ptr->retry = 0;
if (exptime) {
gateway_ptr->state = REG_STATE_UNREGED;
} else {
gateway_ptr->state = REG_STATE_UNREGISTER;
}
if (ostate != gateway_ptr->state) {
sofia_reg_fire_custom_gateway_state_event(gateway_ptr, 0, NULL);
}
sofia_reg_release_gateway(gateway_ptr);
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Gateway '%s' not found.\n", argv[x]);
}
}
free(mydata);
switch_event_add_header_string(*v_event, SWITCH_STACK_BOTTOM, var, val);
}
}
}
if ((gw_val = switch_event_get_header(*v_event, "register-gateway"))) {
sofia_gateway_t *gateway_ptr = NULL;
if (!strcasecmp(gw_val, "all")) {
switch_xml_t gateways_tag, gateway_tag;
if ((gateways_tag = switch_xml_child(user, "gateways"))) {
for (gateway_tag = switch_xml_child(gateways_tag, "gateway"); gateway_tag; gateway_tag = gateway_tag->next) {
char *name = (char *) switch_xml_attr_soft(gateway_tag, "name");
if (zstr(name)) {
name = "anonymous";
}
if ((gateway_ptr = sofia_reg_find_gateway(name))) {
reg_state_t ostate = gateway_ptr->state;
gateway_ptr->retry = 0;
if (exptime) {
gateway_ptr->state = REG_STATE_UNREGED;
} else {
gateway_ptr->state = REG_STATE_UNREGISTER;
}
if (ostate != gateway_ptr->state) {
sofia_reg_fire_custom_gateway_state_event(gateway_ptr, 0, NULL);
}
sofia_reg_release_gateway(gateway_ptr);
}
}
}
} else {
int x, argc;
char *mydata, *argv[50];
mydata = strdup(gw_val);
switch_assert(mydata != NULL);
argc = switch_separate_string(mydata, ',', argv, (sizeof(argv) / sizeof(argv[0])));
for (x = 0; x < argc; x++) {
if ((gateway_ptr = sofia_reg_find_gateway((char *) argv[x]))) {
reg_state_t ostate = gateway_ptr->state;
gateway_ptr->retry = 0;
if (exptime) {
gateway_ptr->state = REG_STATE_UNREGED;
} else {
gateway_ptr->state = REG_STATE_UNREGISTER;
}
if (ostate != gateway_ptr->state) {
sofia_reg_fire_custom_gateway_state_event(gateway_ptr, 0, NULL);
}
sofia_reg_release_gateway(gateway_ptr);
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Gateway '%s' not found.\n", argv[x]);
}
}
free(mydata);
}
}
}
@@ -2486,7 +2496,7 @@ sofia_gateway_t *sofia_reg_find_gateway_by_realm__(const char *file, const char
switch_mutex_lock(mod_sofia_globals.hash_mutex);
for (hi = switch_hash_first(NULL, mod_sofia_globals.gateway_hash); hi; hi = switch_hash_next(hi)) {
switch_hash_this(hi, &var, NULL, &val);
if ((gateway = (sofia_gateway_t *) val) && gateway->register_realm && !strcasecmp(gateway->register_realm, key)) {
if (key && (gateway = (sofia_gateway_t *) val) && gateway->register_realm && !strcasecmp(gateway->register_realm, key)) {
break;
} else {
gateway = NULL;
+1 -1
View File
@@ -1100,7 +1100,7 @@ static int web_callback(void *pArg, int argc, char **argv, char **columnNames)
{
struct holder *holder = (struct holder *) pArg;
char title_b4[128] = "";
char title_aft[128 * 3] = "";
char title_aft[128 * 3 + 1] = "";
char *mp3, *m3u;
/*
@@ -213,12 +213,12 @@ public class CoreSession {
return freeswitchJNI.CoreSession_transfer(swigCPtr, this, extension, dialplan, context);
}
public String read(int min_digits, int max_digits, String prompt_audio_file, int timeout, String valid_terminators) {
return freeswitchJNI.CoreSession_read(swigCPtr, this, min_digits, max_digits, prompt_audio_file, timeout, valid_terminators);
public String read(int min_digits, int max_digits, String prompt_audio_file, int timeout, String valid_terminators, int digit_timeout) {
return freeswitchJNI.CoreSession_read(swigCPtr, this, min_digits, max_digits, prompt_audio_file, timeout, valid_terminators, digit_timeout);
}
public String playAndGetDigits(int min_digits, int max_digits, int max_tries, int timeout, String terminators, String audio_files, String bad_input_audio_files, String digits_regex, String var_name) {
return freeswitchJNI.CoreSession_playAndGetDigits(swigCPtr, this, min_digits, max_digits, max_tries, timeout, terminators, audio_files, bad_input_audio_files, digits_regex, var_name);
public String playAndGetDigits(int min_digits, int max_digits, int max_tries, int timeout, String terminators, String audio_files, String bad_input_audio_files, String digits_regex, String var_name, int digit_timeout) {
return freeswitchJNI.CoreSession_playAndGetDigits(swigCPtr, this, min_digits, max_digits, max_tries, timeout, terminators, audio_files, bad_input_audio_files, digits_regex, var_name, digit_timeout);
}
public int streamFile(String file, int starting_sample_count) {
@@ -125,8 +125,8 @@ class freeswitchJNI {
public final static native String CoreSession_getDigits__SWIG_0(long jarg1, CoreSession jarg1_, int jarg2, String jarg3, int jarg4);
public final static native String CoreSession_getDigits__SWIG_1(long jarg1, CoreSession jarg1_, int jarg2, String jarg3, int jarg4, int jarg5);
public final static native int CoreSession_transfer(long jarg1, CoreSession jarg1_, String jarg2, String jarg3, String jarg4);
public final static native String CoreSession_read(long jarg1, CoreSession jarg1_, int jarg2, int jarg3, String jarg4, int jarg5, String jarg6);
public final static native String CoreSession_playAndGetDigits(long jarg1, CoreSession jarg1_, int jarg2, int jarg3, int jarg4, int jarg5, String jarg6, String jarg7, String jarg8, String jarg9, String jarg10);
public final static native String CoreSession_read(long jarg1, CoreSession jarg1_, int jarg2, int jarg3, String jarg4, int jarg5, String jarg6, int jarg7);
public final static native String CoreSession_playAndGetDigits(long jarg1, CoreSession jarg1_, int jarg2, int jarg3, int jarg4, int jarg5, String jarg6, String jarg7, String jarg8, String jarg9, String jarg10, int jarg11);
public final static native int CoreSession_streamFile(long jarg1, CoreSession jarg1_, String jarg2, int jarg3);
public final static native int CoreSession_sleep(long jarg1, CoreSession jarg1_, int jarg2, int jarg3);
public final static native int CoreSession_flushEvents(long jarg1, CoreSession jarg1_);
@@ -2405,7 +2405,7 @@ SWIGEXPORT jint JNICALL Java_org_freeswitch_swig_freeswitchJNI_CoreSession_1tran
}
SWIGEXPORT jstring JNICALL Java_org_freeswitch_swig_freeswitchJNI_CoreSession_1read(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2, jint jarg3, jstring jarg4, jint jarg5, jstring jarg6) {
SWIGEXPORT jstring JNICALL Java_org_freeswitch_swig_freeswitchJNI_CoreSession_1read(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2, jint jarg3, jstring jarg4, jint jarg5, jstring jarg6, jint jarg7) {
jstring jresult = 0 ;
CoreSession *arg1 = (CoreSession *) 0 ;
int arg2 ;
@@ -2413,6 +2413,7 @@ SWIGEXPORT jstring JNICALL Java_org_freeswitch_swig_freeswitchJNI_CoreSession_1r
char *arg4 = (char *) 0 ;
int arg5 ;
char *arg6 = (char *) 0 ;
int arg7 = (int) 0 ;
char *result = 0 ;
(void)jenv;
@@ -2432,7 +2433,8 @@ SWIGEXPORT jstring JNICALL Java_org_freeswitch_swig_freeswitchJNI_CoreSession_1r
arg6 = (char *)jenv->GetStringUTFChars(jarg6, 0);
if (!arg6) return 0;
}
result = (char *)(arg1)->read(arg2,arg3,(char const *)arg4,arg5,(char const *)arg6);
arg7 = (int)jarg7;
result = (char *)(arg1)->read(arg2,arg3,(char const *)arg4,arg5,(char const *)arg6,arg7);
if(result) jresult = jenv->NewStringUTF((const char *)result);
if (arg4) jenv->ReleaseStringUTFChars(jarg4, (const char *)arg4);
if (arg6) jenv->ReleaseStringUTFChars(jarg6, (const char *)arg6);
@@ -2440,7 +2442,7 @@ SWIGEXPORT jstring JNICALL Java_org_freeswitch_swig_freeswitchJNI_CoreSession_1r
}
SWIGEXPORT jstring JNICALL Java_org_freeswitch_swig_freeswitchJNI_CoreSession_1playAndGetDigits(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2, jint jarg3, jint jarg4, jint jarg5, jstring jarg6, jstring jarg7, jstring jarg8, jstring jarg9, jstring jarg10) {
SWIGEXPORT jstring JNICALL Java_org_freeswitch_swig_freeswitchJNI_CoreSession_1playAndGetDigits(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2, jint jarg3, jint jarg4, jint jarg5, jstring jarg6, jstring jarg7, jstring jarg8, jstring jarg9, jstring jarg10, jint jarg11) {
jstring jresult = 0 ;
CoreSession *arg1 = (CoreSession *) 0 ;
int arg2 ;
@@ -2452,6 +2454,7 @@ SWIGEXPORT jstring JNICALL Java_org_freeswitch_swig_freeswitchJNI_CoreSession_1p
char *arg8 = (char *) 0 ;
char *arg9 = (char *) 0 ;
char *arg10 = (char *) NULL ;
int arg11 = (int) 0 ;
char *result = 0 ;
(void)jenv;
@@ -2487,7 +2490,8 @@ SWIGEXPORT jstring JNICALL Java_org_freeswitch_swig_freeswitchJNI_CoreSession_1p
arg10 = (char *)jenv->GetStringUTFChars(jarg10, 0);
if (!arg10) return 0;
}
result = (char *)(arg1)->playAndGetDigits(arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,(char const *)arg10);
arg11 = (int)jarg11;
result = (char *)(arg1)->playAndGetDigits(arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,(char const *)arg10,arg11);
if(result) jresult = jenv->NewStringUTF((const char *)result);
if (arg6) jenv->ReleaseStringUTFChars(jarg6, (const char *)arg6);
if (arg7) jenv->ReleaseStringUTFChars(jarg7, (const char *)arg7);
+9 -2
View File
@@ -19,8 +19,15 @@
/* Lua function typemap */
%typemap(in,checkfn="lua_isfunction") SWIGLUA_FN
%{ $1.L=L; $1.idx=$input; %}
%typemap(in, checkfn = "lua_isfunction") SWIGLUA_FN {
$1.L = L;
$1.idx = $input;
}
%typemap(default) SWIGLUA_FN {
SWIGLUA_FN default_swiglua_fn = { 0 };
$1 = default_swiglua_fn;
}
%ignore SwitchToMempool;
+8 -3
View File
@@ -367,10 +367,15 @@ int Dbh::query_callback(void *pArg, int argc, char **argv, char **cargv)
bool Dbh::query(char *sql, SWIGLUA_FN lua_fun)
{
if (connected) {
if (switch_cache_db_execute_sql_callback(dbh, sql, query_callback, &lua_fun, NULL) == SWITCH_STATUS_SUCCESS) {
return true;
if (lua_fun.L) {
if (switch_cache_db_execute_sql_callback(dbh, sql, query_callback, &lua_fun, NULL) == SWITCH_STATUS_SUCCESS) {
return true;
}
} else { /* if no lua_fun arg is passed from Lua, an empty initialized struct will be sent - see freeswitch.i */
if (switch_cache_db_execute_sql(dbh, sql, NULL) == SWITCH_STATUS_SUCCESS) {
return true;
}
}
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "no workie workie :(\n");
return false;
}
+1 -1
View File
@@ -588,7 +588,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_lua_load)
SWITCH_ADD_API(api_interface, "luarun", "run a script", luarun_api_function, "<script>");
SWITCH_ADD_API(api_interface, "lua", "run a script as an api function", lua_api_function, "<script>");
SWITCH_ADD_APP(app_interface, "lua", "Launch LUA ivr", "Run a lua ivr on a channel", lua_function, "<script>", SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "lua", "Launch LUA ivr", "Run a lua ivr on a channel", lua_function, "<script>", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SWITCH_ADD_DIALPLAN(dp_interface, "LUA", lua_dialplan_hunt);
+28 -7
View File
@@ -5175,15 +5175,17 @@ static int _wrap_CoreSession_read(lua_State* L) {
char *arg4 = (char *) 0 ;
int arg5 ;
char *arg6 = (char *) 0 ;
int arg7 = (int) 0 ;
char *result = 0 ;
SWIG_check_num_args("read",6,6)
SWIG_check_num_args("read",6,7)
if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("read",1,"CoreSession *");
if(!lua_isnumber(L,2)) SWIG_fail_arg("read",2,"int");
if(!lua_isnumber(L,3)) SWIG_fail_arg("read",3,"int");
if(!lua_isstring(L,4)) SWIG_fail_arg("read",4,"char const *");
if(!lua_isnumber(L,5)) SWIG_fail_arg("read",5,"int");
if(!lua_isstring(L,6)) SWIG_fail_arg("read",6,"char const *");
if(lua_gettop(L)>=7 && !lua_isnumber(L,7)) SWIG_fail_arg("read",7,"int");
if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_CoreSession,0))){
SWIG_fail_ptr("CoreSession_read",1,SWIGTYPE_p_CoreSession);
@@ -5194,7 +5196,10 @@ static int _wrap_CoreSession_read(lua_State* L) {
arg4 = (char *)lua_tostring(L, 4);
arg5 = (int)lua_tonumber(L, 5);
arg6 = (char *)lua_tostring(L, 6);
result = (char *)(arg1)->read(arg2,arg3,(char const *)arg4,arg5,(char const *)arg6);
if(lua_gettop(L)>=7){
arg7 = (int)lua_tonumber(L, 7);
}
result = (char *)(arg1)->read(arg2,arg3,(char const *)arg4,arg5,(char const *)arg6,arg7);
SWIG_arg=0;
lua_pushstring(L,(const char*)result); SWIG_arg++;
return SWIG_arg;
@@ -5219,9 +5224,10 @@ static int _wrap_CoreSession_playAndGetDigits(lua_State* L) {
char *arg8 = (char *) 0 ;
char *arg9 = (char *) 0 ;
char *arg10 = (char *) NULL ;
int arg11 = (int) 0 ;
char *result = 0 ;
SWIG_check_num_args("playAndGetDigits",9,10)
SWIG_check_num_args("playAndGetDigits",9,11)
if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("playAndGetDigits",1,"CoreSession *");
if(!lua_isnumber(L,2)) SWIG_fail_arg("playAndGetDigits",2,"int");
if(!lua_isnumber(L,3)) SWIG_fail_arg("playAndGetDigits",3,"int");
@@ -5232,6 +5238,7 @@ static int _wrap_CoreSession_playAndGetDigits(lua_State* L) {
if(!lua_isstring(L,8)) SWIG_fail_arg("playAndGetDigits",8,"char *");
if(!lua_isstring(L,9)) SWIG_fail_arg("playAndGetDigits",9,"char *");
if(lua_gettop(L)>=10 && !lua_isstring(L,10)) SWIG_fail_arg("playAndGetDigits",10,"char const *");
if(lua_gettop(L)>=11 && !lua_isnumber(L,11)) SWIG_fail_arg("playAndGetDigits",11,"int");
if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_CoreSession,0))){
SWIG_fail_ptr("CoreSession_playAndGetDigits",1,SWIGTYPE_p_CoreSession);
@@ -5248,7 +5255,10 @@ static int _wrap_CoreSession_playAndGetDigits(lua_State* L) {
if(lua_gettop(L)>=10){
arg10 = (char *)lua_tostring(L, 10);
}
result = (char *)(arg1)->playAndGetDigits(arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,(char const *)arg10);
if(lua_gettop(L)>=11){
arg11 = (int)lua_tonumber(L, 11);
}
result = (char *)(arg1)->playAndGetDigits(arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,(char const *)arg10,arg11);
SWIG_arg=0;
lua_pushstring(L,(const char*)result); SWIG_arg++;
return SWIG_arg;
@@ -7191,17 +7201,28 @@ static int _wrap_Dbh_query(lua_State* L) {
SWIGLUA_FN arg3 ;
bool result;
SWIG_check_num_args("query",3,3)
{
SWIGLUA_FN default_swiglua_fn = {
0
};
arg3 = default_swiglua_fn;
}
SWIG_check_num_args("query",2,3)
if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("query",1,"LUA::Dbh *");
if(!lua_isstring(L,2)) SWIG_fail_arg("query",2,"char *");
if(!lua_isfunction(L,3)) SWIG_fail_arg("query",3,"SWIGLUA_FN");
if(lua_gettop(L)>=3 && !lua_isfunction(L,3)) SWIG_fail_arg("query",3,"SWIGLUA_FN");
if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_LUA__Dbh,0))){
SWIG_fail_ptr("Dbh_query",1,SWIGTYPE_p_LUA__Dbh);
}
arg2 = (char *)lua_tostring(L, 2);
(&arg3)->L=L; (&arg3)->idx=3;
if(lua_gettop(L)>=3){
{
(&arg3)->L = L;
(&arg3)->idx = 3;
}
}
result = (bool)(arg1)->query(arg2,arg3);
SWIG_arg=0;
lua_pushboolean(L,(int)(result==true)); SWIG_arg++;
+4 -1
View File
@@ -193,7 +193,10 @@ char * SWIG_csharp_string_callback(const char * str) {
%include switch_core_db.h
%include switch_regex.h
%include switch_core.h
//%include switch_loadable_module.h // todo: Sort out some linking issues
%ignore switch_module_runtime;
%ignore switch_module_load;
%ignore switch_module_shutdown;
%include switch_loadable_module.h // note: Above three ignore lines sort out some linking issues
%include switch_console.h // Has unsupported varargs functions
%include switch_utils.h
%include switch_caller.h
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+30 -6
View File
@@ -6637,6 +6637,7 @@ XS(_wrap_CoreSession_read) {
char *arg4 = (char *) 0 ;
int arg5 ;
char *arg6 = (char *) 0 ;
int arg7 = (int) 0 ;
char *result = 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
@@ -6652,11 +6653,13 @@ XS(_wrap_CoreSession_read) {
int res6 ;
char *buf6 = 0 ;
int alloc6 = 0 ;
int val7 ;
int ecode7 = 0 ;
int argvi = 0;
dXSARGS;
if ((items < 6) || (items > 6)) {
SWIG_croak("Usage: CoreSession_read(self,min_digits,max_digits,prompt_audio_file,timeout,valid_terminators);");
if ((items < 6) || (items > 7)) {
SWIG_croak("Usage: CoreSession_read(self,min_digits,max_digits,prompt_audio_file,timeout,valid_terminators,digit_timeout);");
}
res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_CoreSession, 0 | 0 );
if (!SWIG_IsOK(res1)) {
@@ -6688,7 +6691,14 @@ XS(_wrap_CoreSession_read) {
SWIG_exception_fail(SWIG_ArgError(res6), "in method '" "CoreSession_read" "', argument " "6"" of type '" "char const *""'");
}
arg6 = reinterpret_cast< char * >(buf6);
result = (char *)(arg1)->read(arg2,arg3,(char const *)arg4,arg5,(char const *)arg6);
if (items > 6) {
ecode7 = SWIG_AsVal_int SWIG_PERL_CALL_ARGS_2(ST(6), &val7);
if (!SWIG_IsOK(ecode7)) {
SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "CoreSession_read" "', argument " "7"" of type '" "int""'");
}
arg7 = static_cast< int >(val7);
}
result = (char *)(arg1)->read(arg2,arg3,(char const *)arg4,arg5,(char const *)arg6,arg7);
ST(argvi) = SWIG_FromCharPtr((const char *)result); argvi++ ;
@@ -6696,6 +6706,7 @@ XS(_wrap_CoreSession_read) {
if (alloc4 == SWIG_NEWOBJ) delete[] buf4;
if (alloc6 == SWIG_NEWOBJ) delete[] buf6;
XSRETURN(argvi);
fail:
@@ -6704,6 +6715,7 @@ XS(_wrap_CoreSession_read) {
if (alloc4 == SWIG_NEWOBJ) delete[] buf4;
if (alloc6 == SWIG_NEWOBJ) delete[] buf6;
SWIG_croak_null();
}
}
@@ -6721,6 +6733,7 @@ XS(_wrap_CoreSession_playAndGetDigits) {
char *arg8 = (char *) 0 ;
char *arg9 = (char *) 0 ;
char *arg10 = (char *) NULL ;
int arg11 = (int) 0 ;
char *result = 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
@@ -6747,11 +6760,13 @@ XS(_wrap_CoreSession_playAndGetDigits) {
int res10 ;
char *buf10 = 0 ;
int alloc10 = 0 ;
int val11 ;
int ecode11 = 0 ;
int argvi = 0;
dXSARGS;
if ((items < 9) || (items > 10)) {
SWIG_croak("Usage: CoreSession_playAndGetDigits(self,min_digits,max_digits,max_tries,timeout,terminators,audio_files,bad_input_audio_files,digits_regex,var_name);");
if ((items < 9) || (items > 11)) {
SWIG_croak("Usage: CoreSession_playAndGetDigits(self,min_digits,max_digits,max_tries,timeout,terminators,audio_files,bad_input_audio_files,digits_regex,var_name,digit_timeout);");
}
res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_CoreSession, 0 | 0 );
if (!SWIG_IsOK(res1)) {
@@ -6805,7 +6820,14 @@ XS(_wrap_CoreSession_playAndGetDigits) {
}
arg10 = reinterpret_cast< char * >(buf10);
}
result = (char *)(arg1)->playAndGetDigits(arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,(char const *)arg10);
if (items > 10) {
ecode11 = SWIG_AsVal_int SWIG_PERL_CALL_ARGS_2(ST(10), &val11);
if (!SWIG_IsOK(ecode11)) {
SWIG_exception_fail(SWIG_ArgError(ecode11), "in method '" "CoreSession_playAndGetDigits" "', argument " "11"" of type '" "int""'");
}
arg11 = static_cast< int >(val11);
}
result = (char *)(arg1)->playAndGetDigits(arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,(char const *)arg10,arg11);
ST(argvi) = SWIG_FromCharPtr((const char *)result); argvi++ ;
@@ -6817,6 +6839,7 @@ XS(_wrap_CoreSession_playAndGetDigits) {
if (alloc8 == SWIG_NEWOBJ) delete[] buf8;
if (alloc9 == SWIG_NEWOBJ) delete[] buf9;
if (alloc10 == SWIG_NEWOBJ) delete[] buf10;
XSRETURN(argvi);
fail:
@@ -6829,6 +6852,7 @@ XS(_wrap_CoreSession_playAndGetDigits) {
if (alloc8 == SWIG_NEWOBJ) delete[] buf8;
if (alloc9 == SWIG_NEWOBJ) delete[] buf9;
if (alloc10 == SWIG_NEWOBJ) delete[] buf10;
SWIG_croak_null();
}
}
@@ -7025,6 +7025,7 @@ SWIGINTERN PyObject *_wrap_CoreSession_read(PyObject *SWIGUNUSEDPARM(self), PyOb
char *arg4 = (char *) 0 ;
int arg5 ;
char *arg6 = (char *) 0 ;
int arg7 = (int) 0 ;
char *result = 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
@@ -7040,14 +7041,17 @@ SWIGINTERN PyObject *_wrap_CoreSession_read(PyObject *SWIGUNUSEDPARM(self), PyOb
int res6 ;
char *buf6 = 0 ;
int alloc6 = 0 ;
int val7 ;
int ecode7 = 0 ;
PyObject * obj0 = 0 ;
PyObject * obj1 = 0 ;
PyObject * obj2 = 0 ;
PyObject * obj3 = 0 ;
PyObject * obj4 = 0 ;
PyObject * obj5 = 0 ;
PyObject * obj6 = 0 ;
if (!PyArg_ParseTuple(args,(char *)"OOOOOO:CoreSession_read",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5)) SWIG_fail;
if (!PyArg_ParseTuple(args,(char *)"OOOOOO|O:CoreSession_read",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CoreSession, 0 | 0 );
if (!SWIG_IsOK(res1)) {
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CoreSession_read" "', argument " "1"" of type '" "CoreSession *""'");
@@ -7078,7 +7082,14 @@ SWIGINTERN PyObject *_wrap_CoreSession_read(PyObject *SWIGUNUSEDPARM(self), PyOb
SWIG_exception_fail(SWIG_ArgError(res6), "in method '" "CoreSession_read" "', argument " "6"" of type '" "char const *""'");
}
arg6 = reinterpret_cast< char * >(buf6);
result = (char *)(arg1)->read(arg2,arg3,(char const *)arg4,arg5,(char const *)arg6);
if (obj6) {
ecode7 = SWIG_AsVal_int(obj6, &val7);
if (!SWIG_IsOK(ecode7)) {
SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "CoreSession_read" "', argument " "7"" of type '" "int""'");
}
arg7 = static_cast< int >(val7);
}
result = (char *)(arg1)->read(arg2,arg3,(char const *)arg4,arg5,(char const *)arg6,arg7);
resultobj = SWIG_FromCharPtr((const char *)result);
if (alloc4 == SWIG_NEWOBJ) delete[] buf4;
if (alloc6 == SWIG_NEWOBJ) delete[] buf6;
@@ -7102,6 +7113,7 @@ SWIGINTERN PyObject *_wrap_CoreSession_playAndGetDigits(PyObject *SWIGUNUSEDPARM
char *arg8 = (char *) 0 ;
char *arg9 = (char *) 0 ;
char *arg10 = (char *) NULL ;
int arg11 = (int) 0 ;
char *result = 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
@@ -7128,6 +7140,8 @@ SWIGINTERN PyObject *_wrap_CoreSession_playAndGetDigits(PyObject *SWIGUNUSEDPARM
int res10 ;
char *buf10 = 0 ;
int alloc10 = 0 ;
int val11 ;
int ecode11 = 0 ;
PyObject * obj0 = 0 ;
PyObject * obj1 = 0 ;
PyObject * obj2 = 0 ;
@@ -7138,8 +7152,9 @@ SWIGINTERN PyObject *_wrap_CoreSession_playAndGetDigits(PyObject *SWIGUNUSEDPARM
PyObject * obj7 = 0 ;
PyObject * obj8 = 0 ;
PyObject * obj9 = 0 ;
PyObject * obj10 = 0 ;
if (!PyArg_ParseTuple(args,(char *)"OOOOOOOOO|O:CoreSession_playAndGetDigits",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6,&obj7,&obj8,&obj9)) SWIG_fail;
if (!PyArg_ParseTuple(args,(char *)"OOOOOOOOO|OO:CoreSession_playAndGetDigits",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6,&obj7,&obj8,&obj9,&obj10)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CoreSession, 0 | 0 );
if (!SWIG_IsOK(res1)) {
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CoreSession_playAndGetDigits" "', argument " "1"" of type '" "CoreSession *""'");
@@ -7192,7 +7207,14 @@ SWIGINTERN PyObject *_wrap_CoreSession_playAndGetDigits(PyObject *SWIGUNUSEDPARM
}
arg10 = reinterpret_cast< char * >(buf10);
}
result = (char *)(arg1)->playAndGetDigits(arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,(char const *)arg10);
if (obj10) {
ecode11 = SWIG_AsVal_int(obj10, &val11);
if (!SWIG_IsOK(ecode11)) {
SWIG_exception_fail(SWIG_ArgError(ecode11), "in method '" "CoreSession_playAndGetDigits" "', argument " "11"" of type '" "int""'");
}
arg11 = static_cast< int >(val11);
}
result = (char *)(arg1)->playAndGetDigits(arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,(char const *)arg10,arg11);
resultobj = SWIG_FromCharPtr((const char *)result);
if (alloc6 == SWIG_NEWOBJ) delete[] buf6;
if (alloc7 == SWIG_NEWOBJ) delete[] buf7;
+1 -1
View File
@@ -264,7 +264,7 @@ static switch_status_t my_on_reporting(switch_core_session_t *session)
if (globals.encode == ENCODING_TEXTXML) {
headers = curl_slist_append(headers, "Content-Type: text/xml");
} else if (globals.encode) {
switch_size_t need_bytes = strlen(xml_text) * 3;
switch_size_t need_bytes = strlen(xml_text) * 3 + 1;
xml_text_escaped = malloc(need_bytes);
switch_assert(xml_text_escaped);
@@ -275,7 +275,6 @@ static abyss_bool is_authorized(const TSession * r, const char *command)
err = 686;
status = "EXECUTION OF SPECIFIED API COMMAND NOT PERMITTED IN USER ACCOUNT";
if (!user_attributes(user, domain_name, NULL, NULL, NULL, &allowed_commands)) {
goto end;
@@ -305,11 +304,6 @@ static abyss_bool is_authorized(const TSession * r, const char *command)
if (!ok) {
ResponseStatus(r, err);
if (status) {
ResponseError2(r, status);
} else {
ResponseError(r);
}
}
+4 -23
View File
@@ -271,13 +271,12 @@ int main(int argc, char *argv[])
switch_size_t pid_len, old_pid_len;
const char *err = NULL; /* error value for return from freeswitch initialization */
#ifndef WIN32
int bf = 0;
int nf = 0; /* TRUE if we are running in nofork mode */
char *runas_user = NULL;
char *runas_group = NULL;
#else
int win32_service = 0;
#endif
int nf = 0; /* TRUE if we are running in nofork mode */
int nc = 0; /* TRUE if we are running in noconsole mode */
pid_t pid = 0;
int i, x;
@@ -329,7 +328,6 @@ int main(int argc, char *argv[])
"\t-monotonic-clock -- use monotonic clock as timer source\n"
#else
"\t-nf -- no forking\n"
"\t-bf -- block until fully started, then fork\n"
"\t-u [user] -- specify user to switch to\n" "\t-g [group] -- specify group to switch to\n"
#endif
"\t-help -- this message\n" "\t-version -- print the version and exit\n"
@@ -463,11 +461,6 @@ int main(int argc, char *argv[])
known_opt++;
}
if (local_argv[x] && !strcmp(local_argv[x], "-bf")) {
bf++;
known_opt++;
}
if (local_argv[x] && !strcmp(local_argv[x], "-version")) {
fprintf(stdout, "FreeSWITCH version: %s\n", SWITCH_VERSION_FULL);
return 0;
@@ -530,14 +523,8 @@ int main(int argc, char *argv[])
}
if (local_argv[x] && !strcmp(local_argv[x], "-nc")) {
if (!nf) {
nc++;
known_opt++;
} else {
/* The flags -nc and -nf are mutually exclusive. Ignoring -nc. */
nc = 0;
known_opt++;
}
nc++;
known_opt++;
}
if (local_argv[x] && !strcmp(local_argv[x], "-c")) {
@@ -698,7 +685,7 @@ int main(int argc, char *argv[])
#ifdef WIN32
FreeConsole();
#else
if (!nf && !bf) {
if (!nf) {
daemonize();
}
#endif
@@ -813,12 +800,6 @@ int main(int argc, char *argv[])
return 255;
}
#ifndef WIN32
if(bf) {
daemonize();
}
#endif
switch_core_runtime_loop(nc);
destroy_status = switch_core_destroy();
+13 -6
View File
@@ -1291,19 +1291,24 @@ SWITCH_DECLARE(int) switch_channel_test_private_flag(switch_channel_t *channel,
SWITCH_DECLARE(void) switch_channel_set_app_flag_key(const char *key, switch_channel_t *channel, uint32_t flags)
{
uint32_t *flagp = NULL;
switch_byte_t new = 0;
switch_assert(channel != NULL);
switch_mutex_lock(channel->flag_mutex);
if (channel->app_flag_hash) {
flagp = switch_core_hash_find(channel->app_flag_hash, key);
} else {
if (!channel->app_flag_hash) {
switch_core_hash_init(&channel->app_flag_hash, switch_core_session_get_pool(channel->session));
new++;
}
if (new || !(flagp = switch_core_hash_find(channel->app_flag_hash, key))) {
flagp = switch_core_session_alloc(channel->session, sizeof(uint32_t));
switch_core_hash_insert(channel->app_flag_hash, key, flagp);
}
if (flagp) *flagp |= flags;
switch_assert(flagp);
*flagp |= flags;
switch_mutex_unlock(channel->flag_mutex);
}
@@ -1829,6 +1834,7 @@ SWITCH_DECLARE(void) switch_channel_event_set_basic_data(switch_channel_t *chann
if (impl.iananame) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-Read-Codec-Name", impl.iananame);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Channel-Read-Codec-Rate", "%u", impl.actual_samples_per_second);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Channel-Read-Codec-Bit-Rate", "%d", impl.bits_per_second);
}
switch_core_session_get_write_impl(channel->session, &impl);
@@ -1836,6 +1842,7 @@ SWITCH_DECLARE(void) switch_channel_event_set_basic_data(switch_channel_t *chann
if (impl.iananame) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-Write-Codec-Name", impl.iananame);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Channel-Write-Codec-Rate", "%u", impl.actual_samples_per_second);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Channel-Write-Codec-Bit-Rate", "%d", impl.bits_per_second);
}
/* Index Caller's Profile */
+23 -2
View File
@@ -483,9 +483,29 @@ static int comp_callback(void *pArg, int argc, char **argv, char **columnNames)
return -1;
}
if (!zstr(target) && *target == ':' && *(target + 1) == ':' && *(target + 2) == '[') {
char *p = target + 3, *list = NULL;
if (p) {
char *argv[100] = { 0 };
char *r_argv[1] = { 0 }, *r_cols[1] = {0};
list = strdup(p);
argc = switch_separate_string(list, ':', argv, (sizeof(argv) / sizeof(argv[0])));
for (i = 0; (int)i < argc; i++) {
if (!cur || !strncmp(argv[i], cur, strlen(cur))) {
r_argv[0] = argv[i];
comp_callback(h, 1, r_argv, r_cols);
}
}
switch_safe_free(list);
}
return 0;
}
if (!zstr(target) && *target == ':' && *(target + 1) == ':') {
char *r_argv[1] = { 0 }, *r_cols[1] = {
0};
char *r_argv[1] = { 0 }, *r_cols[1] = {0};
switch_console_callback_match_t *matches;
if (switch_console_run_complete_func(target, str, cur, &matches) == SWITCH_STATUS_SUCCESS) {
switch_console_callback_match_node_t *m;
@@ -797,6 +817,7 @@ SWITCH_DECLARE(unsigned char) switch_console_complete(const char *line, const ch
}
stream.write_function(&stream, " and hostname='%s' order by a%d", switch_core_get_variable("hostname"), h.words + 1);
switch_cache_db_execute_sql_callback(db, stream.data, comp_callback, &h, &errmsg);
if (errmsg) {
+37 -2
View File
@@ -1222,7 +1222,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_init(switch_core_flag_t flags, switc
}
runtime.runlevel++;
runtime.sql_buffer_len = 1024 * 32;
runtime.max_sql_buffer_len = 1024 * 1024;
runtime.dummy_cng_frame.data = runtime.dummy_data;
runtime.dummy_cng_frame.datalen = sizeof(runtime.dummy_data);
runtime.dummy_cng_frame.buflen = sizeof(runtime.dummy_data);
@@ -1315,6 +1316,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_init(switch_core_flag_t flags, switc
switch_log_init(runtime.memory_pool, runtime.colorize_console);
if (flags & SCF_MINIMAL) return SWITCH_STATUS_SUCCESS;
runtime.tipping_point = 5000;
runtime.timer_affinity = -1;
@@ -1438,6 +1441,37 @@ static void switch_load_core_config(const char *file)
if (tmp > -1 && tmp < 11) {
switch_core_session_ctl(SCSC_DEBUG_LEVEL, &tmp);
}
} else if (!strcasecmp(var, "sql-buffer-len")) {
int tmp = atoi(val);
if (end_of(val) == 'k') {
tmp *= 1024;
} else if (end_of(val) == 'm') {
tmp *= (1024 * 1024);
}
if (tmp >= 32000 && tmp < 10500000) {
runtime.sql_buffer_len = tmp;
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "sql-buffer-len: Value is not within rage 32k to 10m\n");
}
} else if (!strcasecmp(var, "max-sql-buffer-len")) {
int tmp = atoi(val);
if (end_of(val) == 'k') {
tmp *= 1024;
} else if (end_of(val) == 'm') {
tmp *= (1024 * 1024);
}
if (tmp < runtime.sql_buffer_len) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Value is not larger than sql-buffer-len\n");
} else if (tmp >= 32000 && tmp < 10500000) {
runtime.sql_buffer_len = tmp;
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "max-sql-buffer-len: Value is not within rage 32k to 10m\n");
}
} else if (!strcasecmp(var, "auto-create-schemas")) {
if (switch_true(val)) {
switch_set_flag((&runtime), SCF_AUTO_SCHEMAS);
@@ -1594,7 +1628,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_init_and_modload(switch_core_flag_t
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Bringing up environment.\n");
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Loading Modules.\n");
if (switch_loadable_module_init() != SWITCH_STATUS_SUCCESS) {
if (switch_loadable_module_init(SWITCH_TRUE) != SWITCH_STATUS_SUCCESS) {
*err = "Cannot load modules";
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Error: %s\n", *err);
return SWITCH_STATUS_GENERR;
@@ -1902,6 +1936,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_destroy(void)
switch_scheduler_task_thread_stop();
switch_rtp_shutdown();
if (switch_test_flag((&runtime), SCF_USE_AUTO_NAT)) {
switch_nat_shutdown();
}
+6 -4
View File
@@ -165,6 +165,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_set_read_codec(switch_core_s
switch_channel_event_set_data(session->channel, event);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "channel-read-codec-name", session->read_impl.iananame);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "channel-read-codec-rate", "%d", session->read_impl.actual_samples_per_second);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "channel-read-codec-bit-rate", "%d", session->read_impl.bits_per_second);
if (session->read_impl.actual_samples_per_second != session->read_impl.samples_per_second) {
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "channel-reported-read-codec-rate", "%d", session->read_impl.samples_per_second);
}
@@ -317,6 +318,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_set_write_codec(switch_core_
switch_channel_event_set_data(session->channel, event);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-Write-Codec-Name", session->write_impl.iananame);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Channel-Write-Codec-Rate", "%d", session->write_impl.actual_samples_per_second);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Channel-Write-codec-bit-rate", "%d", session->write_impl.bits_per_second);
if (session->write_impl.actual_samples_per_second != session->write_impl.samples_per_second) {
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Channel-Reported-Write-Codec-Rate", "%d",
session->write_impl.actual_samples_per_second);
@@ -494,8 +496,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_codec_copy(switch_codec_t *codec, sw
return SWITCH_STATUS_SUCCESS;
}
SWITCH_DECLARE(switch_status_t) switch_core_codec_init(switch_codec_t *codec, const char *codec_name, const char *fmtp,
uint32_t rate, int ms, int channels, uint32_t flags,
SWITCH_DECLARE(switch_status_t) switch_core_codec_init_with_bitrate(switch_codec_t *codec, const char *codec_name, const char *fmtp,
uint32_t rate, int ms, int channels, uint32_t bitrate, uint32_t flags,
const switch_codec_settings_t *codec_settings, switch_memory_pool_t *pool)
{
switch_codec_interface_t *codec_interface;
@@ -519,7 +521,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_codec_init(switch_codec_t *codec, co
/* If no specific codec interval is requested opt for 20ms above all else because lots of stuff assumes it */
if (!ms) {
for (iptr = codec_interface->implementations; iptr; iptr = iptr->next) {
if ((!rate || rate == iptr->samples_per_second) &&
if ((!rate || rate == iptr->samples_per_second) && (!bitrate || bitrate == (uint32_t)iptr->bits_per_second) &&
(20 == (iptr->microseconds_per_packet / 1000)) && (!channels || channels == iptr->number_of_channels)) {
implementation = iptr;
goto found;
@@ -529,7 +531,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_codec_init(switch_codec_t *codec, co
/* Either looking for a specific interval or there was no interval specified and there wasn't one @20ms available */
for (iptr = codec_interface->implementations; iptr; iptr = iptr->next) {
if ((!rate || rate == iptr->samples_per_second) &&
if ((!rate || rate == iptr->samples_per_second) && (!bitrate || bitrate == (uint32_t)iptr->bits_per_second) &&
(!ms || ms == (iptr->microseconds_per_packet / 1000)) && (!channels || channels == iptr->number_of_channels)) {
implementation = iptr;
break;
+1 -1
View File
@@ -173,7 +173,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_perform_file_open(const char *file,
}
if (fh->samplerate && rate && fh->samplerate != rate) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Sample rate doesn't match\n");
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "File %s sample rate %d doesn't match requested rate %d\n", file_path, fh->samplerate, rate);
if ((flags & SWITCH_FILE_FLAG_READ)) {
fh->samplerate = rate;
}
+118 -65
View File
@@ -34,8 +34,7 @@
#include <switch.h>
#include "private/switch_core_pvt.h"
#define SQLLEN 32768
//*#define DEBUG_SQL 1
static struct {
switch_cache_db_handle_t *event_db;
@@ -43,11 +42,15 @@ static struct {
switch_memory_pool_t *memory_pool;
switch_event_node_t *event_node;
switch_thread_t *thread;
switch_thread_t *db_thread;
int thread_running;
int db_thread_running;
switch_bool_t manage;
switch_mutex_t *io_mutex;
switch_mutex_t *dbh_mutex;
switch_hash_t *dbh_hash;
switch_thread_cond_t *cond;
switch_mutex_t *cond_mutex;
} sql_manager;
@@ -346,7 +349,7 @@ SWITCH_DECLARE(switch_status_t) _switch_cache_db_get_db_handle(switch_cache_db_h
{
if (!switch_odbc_available()) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failure! OBDC NOT AVAILABLE!\n");
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failure! ODBC NOT AVAILABLE!\n");
goto end;
}
@@ -464,6 +467,19 @@ static switch_status_t switch_cache_db_execute_sql_real(switch_cache_db_handle_t
return status;
}
static void wake_thread(int force)
{
if (force) {
switch_thread_cond_signal(sql_manager.cond);
return;
}
if (switch_mutex_trylock(sql_manager.cond_mutex) == SWITCH_STATUS_SUCCESS) {
switch_thread_cond_signal(sql_manager.cond);
switch_mutex_unlock(sql_manager.cond_mutex);
}
}
/**
OMFG you cruel bastards. Who chooses 64k as a max buffer len for a sql statement, have you ever heard of transactions?
**/
@@ -539,7 +555,7 @@ SWITCH_DECLARE(switch_status_t) switch_cache_db_execute_sql(switch_cache_db_hand
switch (dbh->type) {
default:
{
status = switch_cache_db_execute_sql_chunked(dbh, (char *) sql, SQLLEN, err);
status = switch_cache_db_execute_sql_chunked(dbh, (char *) sql, 32768, err);
}
break;
}
@@ -846,30 +862,40 @@ SWITCH_DECLARE(switch_bool_t) switch_cache_db_test_reactive(switch_cache_db_hand
}
static void *SWITCH_THREAD_FUNC switch_core_sql_db_thread(switch_thread_t *thread, void *obj)
{
int sec = 0;
sql_manager.db_thread_running = 1;
while (sql_manager.db_thread_running == 1) {
if (++sec == SQL_CACHE_TIMEOUT) {
sql_close(switch_epoch_time_now(NULL));
wake_thread(1);
sec = 0;
}
switch_yield(1000);
}
return NULL;
}
static void *SWITCH_THREAD_FUNC switch_core_sql_thread(switch_thread_t *thread, void *obj)
{
void *pop;
uint32_t itterations = 0;
uint8_t trans = 0, nothing_in_queue = 0;
uint32_t target = 100000;
switch_size_t len = 0, sql_len = SQLLEN;
char *sqlbuf = (char *) malloc(sql_len);
void *pop = NULL;
uint32_t iterations = 0;
uint8_t trans = 0;
uint32_t target = 20000;
switch_size_t len = 0, sql_len = runtime.sql_buffer_len;
char *tmp, *sqlbuf = (char *) malloc(sql_len);
char *sql = NULL;
switch_size_t newlen;
int lc = 0;
uint32_t loops = 0, sec = 0;
uint32_t l1 = 1000;
uint32_t sanity = 120;
int item_remained = 0;
switch_assert(sqlbuf);
if (!sql_manager.manage) {
l1 = 10;
}
while (!sql_manager.event_db) {
if (switch_core_db_handle(&sql_manager.event_db) == SWITCH_STATUS_SUCCESS && sql_manager.event_db)
break;
@@ -883,83 +909,91 @@ static void *SWITCH_THREAD_FUNC switch_core_sql_thread(switch_thread_t *thread,
return NULL;
}
sql_manager.thread_running = 1;
switch_mutex_lock(sql_manager.cond_mutex);
while (sql_manager.thread_running == 1) {
if (++loops == l1) {
if (++sec == SQL_CACHE_TIMEOUT) {
sql_close(switch_epoch_time_now(NULL));
sec = 0;
}
loops = 0;
}
if (!sql_manager.manage) {
switch_yield(100000);
continue;
}
//printf("SIZE %d %d\n", switch_queue_size(sql_manager.sql_queue[0]), switch_queue_size(sql_manager.sql_queue[1]));
if (item_remained || switch_queue_trypop(sql_manager.sql_queue[0], &pop) == SWITCH_STATUS_SUCCESS ||
if (sql || switch_queue_trypop(sql_manager.sql_queue[0], &pop) == SWITCH_STATUS_SUCCESS ||
switch_queue_trypop(sql_manager.sql_queue[1], &pop) == SWITCH_STATUS_SUCCESS) {
if (item_remained) {
item_remained = 0;
} else {
sql = (char *) pop;
}
if (!sql) sql = (char *) pop;
if (sql) {
newlen = strlen(sql) + 2;
if (itterations == 0) {
if (iterations == 0) {
trans = 1;
}
/* ignore abnormally large strings sql strings as potential buffer overflow */
if (newlen < SQLLEN) {
itterations++;
if (len + newlen > sql_len) {
int new_mlen = len + newlen + 10240;
if (len + newlen < sql_len) {
sprintf(sqlbuf + len, "%s;\n", sql);
len += newlen;
if (new_mlen < runtime.max_sql_buffer_len) {
sql_len = new_mlen;
#ifdef DEBUG_SQL
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT,
"REALLOC %ld %d %d\n", (long int)sql_len, switch_queue_size(sql_manager.sql_queue[0]),
switch_queue_size(sql_manager.sql_queue[1]));
#endif
if (!(tmp = realloc(sqlbuf, sql_len))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "SQL thread ending on mem err\n");
abort();
break;
}
sqlbuf = tmp;
} else {
item_remained = 1;
#ifdef DEBUG_SQL
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT,
"SAVE %d %d\n", switch_queue_size(sql_manager.sql_queue[0]), switch_queue_size(sql_manager.sql_queue[1]));
#endif
goto skip;
}
}
if (!item_remained) {
free(sql);
}
iterations++;
sprintf(sqlbuf + len, "%s;\n", sql);
len += newlen;
free(sql);
sql = NULL;
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "SQL thread ending\n");
break;
}
} else {
nothing_in_queue = 1;
}
if ((item_remained || (trans && ((itterations == target) || (nothing_in_queue && ++lc >= 500)))) &&
(sql_manager.event_db->native_handle.core_db_dbh)) {
skip:
lc = sql ? 1 : 0 + switch_queue_size(sql_manager.sql_queue[0]) + switch_queue_size(sql_manager.sql_queue[1]);
if (trans && iterations && (iterations > target || !lc)) {
#ifdef DEBUG_SQL
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT,
"RUN %d %d %d\n", switch_queue_size(sql_manager.sql_queue[0]), switch_queue_size(sql_manager.sql_queue[1]), iterations);
#endif
if (switch_cache_db_persistant_execute_trans(sql_manager.event_db, sqlbuf, 1) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "SQL thread unable to commit transaction, records lost!\n");
}
itterations = 0;
#ifdef DEBUG_SQL
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "DONE\n");
#endif
iterations = 0;
trans = 0;
nothing_in_queue = 0;
len = 0;
*sqlbuf = '\0';
lc = 0;
switch_yield(400000);
}
if (nothing_in_queue) {
switch_cond_next();
lc = sql ? 1 : 0 + switch_queue_size(sql_manager.sql_queue[0]) + switch_queue_size(sql_manager.sql_queue[1]);
if (!lc) {
switch_thread_cond_wait(sql_manager.cond, sql_manager.cond_mutex);
}
}
switch_mutex_unlock(sql_manager.cond_mutex);
while (switch_queue_trypop(sql_manager.sql_queue[0], &pop) == SWITCH_STATUS_SUCCESS) {
free(pop);
}
@@ -1108,11 +1142,13 @@ static void core_event_handler(switch_event_t *event)
case SWITCH_EVENT_CODEC:
new_sql() =
switch_mprintf
("update channels set read_codec='%q',read_rate='%q',write_codec='%q',write_rate='%q' where uuid='%q' and hostname='%q'",
("update channels set read_codec='%q',read_rate='%q',read_bit_rate='%q',write_codec='%q',write_rate='%q',write_bit_rate='%q' where uuid='%q' and hostname='%q'",
switch_event_get_header_nil(event, "channel-read-codec-name"),
switch_event_get_header_nil(event, "channel-read-codec-rate"),
switch_event_get_header_nil(event, "channel-read-codec-bit-rate"),
switch_event_get_header_nil(event, "channel-write-codec-name"),
switch_event_get_header_nil(event, "channel-write-codec-rate"),
switch_event_get_header_nil(event, "channel-write-codec-bit-rate"),
switch_event_get_header_nil(event, "unique-id"), switch_core_get_variable("hostname"));
break;
case SWITCH_EVENT_CHANNEL_HOLD:
@@ -1389,6 +1425,7 @@ static void core_event_handler(switch_event_t *event)
switch_queue_push(sql_manager.sql_queue[0], sql[i]);
}
sql[i] = NULL;
wake_thread(1);
}
}
}
@@ -1436,8 +1473,10 @@ static char create_channels_sql[] =
" context VARCHAR(128),\n"
" read_codec VARCHAR(128),\n"
" read_rate VARCHAR(32),\n"
" read_bit_rate VARCHAR(32),\n"
" write_codec VARCHAR(128),\n"
" write_rate VARCHAR(32),\n"
" write_bit_rate VARCHAR(32),\n"
" secure VARCHAR(32),\n"
" hostname VARCHAR(256),\n"
" presence_id VARCHAR(4096),\n"
@@ -1505,12 +1544,16 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_
{
switch_threadattr_t *thd_attr;
switch_cache_db_handle_t *dbh;
uint32_t sanity = 400;
sql_manager.memory_pool = pool;
sql_manager.manage = manage;
switch_mutex_init(&sql_manager.dbh_mutex, SWITCH_MUTEX_NESTED, sql_manager.memory_pool);
switch_mutex_init(&sql_manager.io_mutex, SWITCH_MUTEX_NESTED, sql_manager.memory_pool);
switch_mutex_init(&sql_manager.cond_mutex, SWITCH_MUTEX_NESTED, sql_manager.memory_pool);
switch_thread_cond_create(&sql_manager.cond, sql_manager.memory_pool);
switch_core_hash_init(&sql_manager.dbh_hash, sql_manager.memory_pool);
@@ -1574,7 +1617,7 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_
case SCDB_TYPE_ODBC:
{
char *err;
switch_cache_db_test_reactive(dbh, "select call_uuid from channels", "DROP TABLE channels", create_channels_sql);
switch_cache_db_test_reactive(dbh, "select call_uuid, read_bit_rate from channels", "DROP TABLE channels", create_channels_sql);
switch_cache_db_test_reactive(dbh, "select call_uuid from calls", "DROP TABLE calls", create_calls_sql);
switch_cache_db_test_reactive(dbh, "select ikey from interfaces", "DROP TABLE interfaces", create_interfaces_sql);
switch_cache_db_test_reactive(dbh, "select hostname from tasks", "DROP TABLE tasks", create_tasks_sql);
@@ -1636,9 +1679,12 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_
switch_threadattr_create(&thd_attr, sql_manager.memory_pool);
switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
switch_thread_create(&sql_manager.thread, thd_attr, switch_core_sql_thread, NULL, sql_manager.memory_pool);
if (sql_manager.manage) {
switch_thread_create(&sql_manager.thread, thd_attr, switch_core_sql_thread, NULL, sql_manager.memory_pool);
}
switch_thread_create(&sql_manager.db_thread, thd_attr, switch_core_sql_db_thread, NULL, sql_manager.memory_pool);
while (!sql_manager.thread_running) {
while (sql_manager.manage && !sql_manager.thread_running && --sanity) {
switch_yield(10000);
}
@@ -1659,12 +1705,19 @@ void switch_core_sqldb_stop(void)
switch_queue_push(sql_manager.sql_queue[0], NULL);
switch_queue_push(sql_manager.sql_queue[1], NULL);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Waiting for unfinished SQL transactions\n");
wake_thread(1);
}
sql_manager.thread_running = -1;
switch_thread_join(&st, sql_manager.thread);
}
if (sql_manager.thread && sql_manager.db_thread_running) {
sql_manager.db_thread_running = -1;
switch_thread_join(&st, sql_manager.db_thread);
}
switch_cache_db_flush_handles();
sql_close(0);
+8 -4
View File
@@ -775,7 +775,8 @@ SWITCH_DECLARE(char *) CoreSession::read(int min_digits,
int max_digits,
const char *prompt_audio_file,
int timeout,
const char *valid_terminators)
const char *valid_terminators,
int digit_timeout)
{
this_check((char *)"");
sanity_check((char *)"");
@@ -792,7 +793,8 @@ SWITCH_DECLARE(char *) CoreSession::read(int min_digits,
}
begin_allow_threads();
switch_ivr_read(session, min_digits, max_digits, prompt_audio_file, NULL, dtmf_buf, sizeof(dtmf_buf), timeout, valid_terminators);
switch_ivr_read(session, min_digits, max_digits, prompt_audio_file, NULL, dtmf_buf,
sizeof(dtmf_buf), timeout, valid_terminators, (uint32_t)digit_timeout);
end_allow_threads();
return dtmf_buf;
@@ -806,7 +808,8 @@ SWITCH_DECLARE(char *) CoreSession::playAndGetDigits(int min_digits,
char *audio_files,
char *bad_input_audio_files,
char *digits_regex,
const char *var_name)
const char *var_name,
int digit_timeout)
{
switch_status_t status;
sanity_check((char *)"");
@@ -824,7 +827,8 @@ SWITCH_DECLARE(char *) CoreSession::playAndGetDigits(int min_digits,
var_name,
dtmf_buf,
sizeof(dtmf_buf),
digits_regex);
digits_regex,
(uint32_t) digit_timeout);
end_allow_threads();
return dtmf_buf;
+1 -1
View File
@@ -274,7 +274,7 @@ static void *SWITCH_THREAD_FUNC switch_event_dispatch_thread(switch_thread_t *th
switch_mutex_lock(EVENT_QUEUE_MUTEX);
EVENT_DISPATCH_QUEUE_RUNNING[my_id] = 1;
EVENT_DISPATCH_QUEUE_RUNNING[my_id] = 0;
THREAD_COUNT--;
switch_mutex_unlock(EVENT_QUEUE_MUTEX);
+13 -4
View File
@@ -876,7 +876,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_collect_digits_callback(switch_core_s
switch_time_t abs_started = 0, digit_started = 0;
uint32_t abs_elapsed = 0, digit_elapsed = 0;
if (!args || !args->input_callback) {
if (!args) {
return SWITCH_STATUS_GENERR;
}
@@ -917,6 +917,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_collect_digits_callback(switch_core_s
if (switch_channel_has_dtmf(channel)) {
if (!args->input_callback && !args->buf) {
status = SWITCH_STATUS_BREAK;
break;
}
switch_channel_dequeue_dtmf(channel, &dtmf);
status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen);
if (digit_timeout) {
@@ -1417,13 +1421,13 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_session_transfer(switch_core_session_
if (profile->callee_id_name) {
switch_channel_set_variable(channel, "pre_transfer_caller_id_name", new_profile->caller_id_name);
new_profile->caller_id_name = switch_core_strdup(new_profile->pool, profile->callee_id_name);
profile->callee_id_name = NULL;
profile->callee_id_name = SWITCH_BLANK_STRING;
}
if (profile->callee_id_number) {
switch_channel_set_variable(channel, "pre_transfer_caller_id_number", new_profile->caller_id_number);
new_profile->caller_id_number = switch_core_strdup(new_profile->pool, profile->callee_id_number);
profile->callee_id_number = NULL;
profile->callee_id_number = SWITCH_BLANK_STRING;
}
}
@@ -1841,7 +1845,7 @@ SWITCH_DECLARE(int) switch_ivr_set_xml_chan_vars(switch_xml_t xml, switch_channe
for (; hi; hi = hi->next) {
if (!zstr(hi->name) && !zstr(hi->value) && ((variable = switch_xml_add_child_d(xml, hi->name, off++)))) {
char *data;
switch_size_t dlen = strlen(hi->value) * 3;
switch_size_t dlen = strlen(hi->value) * 3 + 1;
if ((data = malloc(dlen))) {
memset(data, 0, dlen);
@@ -2175,6 +2179,7 @@ SWITCH_DECLARE(void) switch_ivr_delay_echo(switch_core_session_t *session, uint3
if ((jb_frame = stfu_n_read_a_frame(jb))) {
write_frame.data = jb_frame->data;
write_frame.datalen = (uint32_t) jb_frame->dlen;
write_frame.buflen = (uint32_t) jb_frame->dlen;
status = switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0);
if (!SWITCH_READ_ACCEPTABLE(status)) {
break;
@@ -2256,6 +2261,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_say(switch_core_session_t *session,
goto done;
}
if (!module_name) {
module_name = chan_lang;
}
if (!(sound_path = (char *) switch_xml_attr(language, "sound-path"))) {
sound_path = (char *) switch_xml_attr(language, "sound_path");
}
+18 -4
View File
@@ -214,12 +214,11 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_menu_init(switch_ivr_menu_t ** new_me
SWITCH_DECLARE(switch_status_t) switch_ivr_menu_bind_action(switch_ivr_menu_t *menu, switch_ivr_action_t ivr_action, const char *arg, const char *bind)
{
switch_ivr_menu_action_t *action;
switch_ivr_menu_action_t *action, *ap;
uint32_t len;
if ((action = switch_core_alloc(menu->pool, sizeof(*action)))) {
action->bind = switch_core_strdup(menu->pool, bind);
action->next = menu->actions;
action->arg = switch_core_strdup(menu->pool, arg);
if (*action->bind == '/') {
action->re = 1;
@@ -230,7 +229,14 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_menu_bind_action(switch_ivr_menu_t *m
}
}
action->ivr_action = ivr_action;
if (menu->actions) {
for(ap = menu->actions; ap && ap->next; ap = ap->next);
ap->next = action;
} else {
menu->actions = action;
}
return SWITCH_STATUS_SUCCESS;
}
@@ -240,13 +246,13 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_menu_bind_action(switch_ivr_menu_t *m
SWITCH_DECLARE(switch_status_t) switch_ivr_menu_bind_function(switch_ivr_menu_t *menu,
switch_ivr_menu_action_function_t *function, const char *arg, const char *bind)
{
switch_ivr_menu_action_t *action;
switch_ivr_menu_action_t *action, *ap;
uint32_t len;
if ((action = switch_core_alloc(menu->pool, sizeof(*action)))) {
action->bind = switch_core_strdup(menu->pool, bind);
action->next = menu->actions;
action->arg = switch_core_strdup(menu->pool, arg);
if (*action->bind == '/') {
action->re = 1;
} else {
@@ -255,8 +261,16 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_menu_bind_function(switch_ivr_menu_t
menu->inlen = len;
}
}
action->function = function;
if (menu->actions) {
for(ap = menu->actions; ap && ap->next; ap = ap->next);
ap->next = action;
} else {
menu->actions = action;
}
return SWITCH_STATUS_SUCCESS;
}
+17 -1
View File
@@ -212,7 +212,7 @@ static void *SWITCH_THREAD_FUNC collect_thread_run(switch_thread_t *thread, void
status = switch_ivr_read(collect->session,
len,
len,
collect->file, NULL, buf, sizeof(buf), collect->confirm_timeout, NULL);
collect->file, NULL, buf, sizeof(buf), collect->confirm_timeout, NULL, 0);
if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK && status != SWITCH_STATUS_TOO_SMALL) {
@@ -2595,6 +2595,22 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
if ((inner_var_count =
switch_separate_string(var_array[x], '=',
inner_var_array, (sizeof(inner_var_array) / sizeof(inner_var_array[0])))) == 2) {
/* this is stupid but necessary: if the value begins with ^^ take the very next char as a delim,
increment the string to start the next char after that and replace every instance of the delim with a , */
if (*inner_var_array[1] == '^' && *(inner_var_array[1] + 1) == '^') {
char *iv;
char d = 0;
inner_var_array[1] += 2;
d = *inner_var_array[1]++;
if (d) {
for(iv = inner_var_array[1]; iv && *iv; iv++) {
if (*iv == d) *iv = ',';
}
}
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "local variable string %d = [%s=%s]\n",
x, inner_var_array[0], inner_var_array[1]);
+13 -4
View File
@@ -1645,7 +1645,12 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_read(switch_core_session_t *session,
uint32_t max_digits,
const char *prompt_audio_file,
const char *var_name,
char *digit_buffer, switch_size_t digit_buffer_length, uint32_t timeout, const char *valid_terminators)
char *digit_buffer,
switch_size_t digit_buffer_length,
uint32_t timeout,
const char *valid_terminators,
uint32_t digit_timeout)
{
switch_channel_t *channel;
switch_input_args_t args = { 0 };
@@ -1696,7 +1701,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_read(switch_core_session_t *session,
if ((min_digits && len < min_digits) || len < max_digits) {
args.buf = digit_buffer + len;
args.buflen = (uint32_t) (digit_buffer_length - len);
status = switch_ivr_collect_digits_count(session, digit_buffer, digit_buffer_length, max_digits, valid_terminators, &tb[0], timeout, 0, 0);
status = switch_ivr_collect_digits_count(session, digit_buffer, digit_buffer_length, max_digits, valid_terminators, &tb[0],
len ? digit_timeout : timeout, digit_timeout, 0);
}
@@ -1745,7 +1751,10 @@ SWITCH_DECLARE(switch_status_t) switch_play_and_get_digits(switch_core_session_t
const char *prompt_audio_file,
const char *bad_input_audio_file,
const char *var_name,
char *digit_buffer, uint32_t digit_buffer_length, const char *digits_regex)
char *digit_buffer,
uint32_t digit_buffer_length,
const char *digits_regex,
uint32_t digit_timeout)
{
switch_channel_t *channel = switch_core_session_get_channel(session);
@@ -1755,7 +1764,7 @@ SWITCH_DECLARE(switch_status_t) switch_play_and_get_digits(switch_core_session_t
memset(digit_buffer, 0, digit_buffer_length);
switch_channel_flush_dtmf(channel);
status = switch_ivr_read(session, min_digits, max_digits, prompt_audio_file, var_name,
digit_buffer, digit_buffer_length, timeout, valid_terminators);
digit_buffer, digit_buffer_length, timeout, valid_terminators, digit_timeout);
if (status == SWITCH_STATUS_TIMEOUT && strlen(digit_buffer) >= min_digits) {
status = SWITCH_STATUS_SUCCESS;
}
+44 -15
View File
@@ -183,8 +183,9 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable
if (load_interface) {
for (impl = ptr->implementations; impl; impl = impl->next) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE,
"Adding Codec '%s' (%s) %dhz %dms\n",
impl->iananame, ptr->interface_name, impl->actual_samples_per_second, impl->microseconds_per_packet / 1000);
"Adding Codec %s %d %s %dhz %dms %dbps\n",
impl->iananame, impl->ianacode,
ptr->interface_name, impl->actual_samples_per_second, impl->microseconds_per_packet / 1000, impl->bits_per_second);
if (!switch_core_hash_find(loadable_modules.codec_hash, impl->iananame)) {
switch_core_hash_insert(loadable_modules.codec_hash, impl->iananame, (const void *) ptr);
}
@@ -515,8 +516,9 @@ static switch_status_t switch_loadable_module_unprocess(switch_loadable_module_t
if (load_interface) {
for (impl = ptr->implementations; impl; impl = impl->next) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE,
"Deleting Codec '%s' (%s) %dhz %dms\n",
impl->iananame, ptr->interface_name, impl->actual_samples_per_second, impl->microseconds_per_packet / 1000);
"Deleting Codec %s %d %s %dhz %dms\n",
impl->iananame, impl->ianacode,
ptr->interface_name, impl->actual_samples_per_second, impl->microseconds_per_packet / 1000);
switch_core_session_hupall_matching_var("read_codec", impl->iananame, SWITCH_CAUSE_MANAGER_REQUEST);
switch_core_session_hupall_matching_var("write_codec", impl->iananame, SWITCH_CAUSE_MANAGER_REQUEST);
if (switch_core_hash_find(loadable_modules.codec_hash, impl->iananame)) {
@@ -1218,7 +1220,7 @@ static void switch_loadable_module_path_init()
}
#endif
SWITCH_DECLARE(switch_status_t) switch_loadable_module_init()
SWITCH_DECLARE(switch_status_t) switch_loadable_module_init(switch_bool_t autoload)
{
apr_finfo_t finfo = { 0 };
@@ -1268,6 +1270,8 @@ SWITCH_DECLARE(switch_status_t) switch_loadable_module_init()
switch_core_hash_init_nocase(&loadable_modules.dialplan_hash, loadable_modules.pool);
switch_mutex_init(&loadable_modules.mutex, SWITCH_MUTEX_NESTED, loadable_modules.pool);
if (!autoload) return SWITCH_STATUS_SUCCESS;
switch_loadable_module_load_module("", "CORE_SOFTTIMER_MODULE", SWITCH_FALSE, &err);
switch_loadable_module_load_module("", "CORE_PCM_MODULE", SWITCH_FALSE, &err);
@@ -1277,6 +1281,7 @@ SWITCH_DECLARE(switch_status_t) switch_loadable_module_init()
for (ld = switch_xml_child(mods, "load"); ld; ld = ld->next) {
switch_bool_t global = SWITCH_FALSE;
const char *val = switch_xml_attr_soft(ld, "module");
const char *path = switch_xml_attr_soft(ld, "path");
const char *critical = switch_xml_attr_soft(ld, "critical");
const char *sglobal = switch_xml_attr_soft(ld, "global");
if (zstr(val) || (strchr(val, '.') && !strstr(val, ext) && !strstr(val, EXT))) {
@@ -1285,7 +1290,10 @@ SWITCH_DECLARE(switch_status_t) switch_loadable_module_init()
}
global = switch_true(sglobal);
if (switch_loadable_module_load_module_ex((char *) SWITCH_GLOBAL_dirs.mod_dir, (char *) val, SWITCH_FALSE, global, &err) == SWITCH_STATUS_FALSE) {
if (path && zstr(path)) {
path = SWITCH_GLOBAL_dirs.mod_dir;
}
if (switch_loadable_module_load_module_ex((char *) path, (char *) val, SWITCH_FALSE, global, &err) == SWITCH_STATUS_FALSE) {
if (critical && switch_true(critical)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load critical module '%s', abort()\n", val);
abort();
@@ -1307,13 +1315,18 @@ SWITCH_DECLARE(switch_status_t) switch_loadable_module_init()
for (ld = switch_xml_child(mods, "load"); ld; ld = ld->next) {
switch_bool_t global = SWITCH_FALSE;
const char *val = switch_xml_attr_soft(ld, "module");
const char *path = switch_xml_attr_soft(ld, "path");
const char *sglobal = switch_xml_attr_soft(ld, "global");
if (zstr(val) || (strchr(val, '.') && !strstr(val, ext) && !strstr(val, EXT))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Invalid extension for %s\n", val);
continue;
}
global = switch_true(sglobal);
switch_loadable_module_load_module_ex((char *) SWITCH_GLOBAL_dirs.mod_dir, (char *) val, SWITCH_FALSE, global, &err);
if (path && zstr(path)) {
path = SWITCH_GLOBAL_dirs.mod_dir;
}
switch_loadable_module_load_module_ex((char *) path, (char *) val, SWITCH_FALSE, global, &err);
count++;
}
}
@@ -1546,13 +1559,16 @@ SWITCH_DECLARE(int) switch_loadable_module_get_codecs(const switch_codec_impleme
for (hi = switch_hash_first(NULL, loadable_modules.codec_hash); hi; hi = switch_hash_next(hi)) {
switch_hash_this(hi, NULL, NULL, &val);
codec_interface = (switch_codec_interface_t *) val;
/* Look for a 20ms implementation because it's the safest choice */
/* Look for the default ptime of the codec because it's the safest choice */
for (imp = codec_interface->implementations; imp; imp = imp->next) {
uint32_t default_ptime = switch_default_ptime(imp->iananame, imp->ianacode);
if (lock && imp->microseconds_per_packet != lock) {
continue;
}
if (imp->microseconds_per_packet / 1000 == 20) {
if (imp->microseconds_per_packet / 1000 == (int)default_ptime) {
array[i++] = imp;
goto found;
}
@@ -1586,7 +1602,7 @@ SWITCH_DECLARE(int) switch_loadable_module_get_codecs_sorted(const switch_codec_
for (x = 0; x < preflen; x++) {
char *cur, *last = NULL, *next = NULL, *name, *p, buf[256];
uint32_t interval = 0, rate = 0;
uint32_t interval = 0, rate = 0, bit = 0;
switch_copy_string(buf, prefs[x], sizeof(buf));
last = name = next = cur = buf;
@@ -1606,21 +1622,24 @@ SWITCH_DECLARE(int) switch_loadable_module_get_codecs_sorted(const switch_codec_
interval = atoi(cur);
} else if ((strchr(cur, 'k') || strchr(cur, 'h'))) {
rate = atoi(cur);
} else if (strchr(cur, 'b')) {
bit = atoi(cur);
}
}
cur = next;
}
if ((codec_interface = switch_loadable_module_get_codec_interface(name)) != 0) {
/* If no specific codec interval is requested opt for 20ms above all else because lots of stuff assumes it */
/* If no specific codec interval is requested opt for the default above all else because lots of stuff assumes it */
for (imp = codec_interface->implementations; imp; imp = imp->next) {
uint32_t default_ptime = switch_default_ptime(imp->iananame, imp->ianacode);
if (imp->codec_type != SWITCH_CODEC_TYPE_VIDEO) {
if (lock && imp->microseconds_per_packet != lock) {
continue;
}
if ((!interval && (uint32_t) (imp->microseconds_per_packet / 1000) != 20) ||
if ((!interval && (uint32_t) (imp->microseconds_per_packet / 1000) != default_ptime) ||
(interval && (uint32_t) (imp->microseconds_per_packet / 1000) != interval)) {
continue;
}
@@ -1628,6 +1647,11 @@ SWITCH_DECLARE(int) switch_loadable_module_get_codecs_sorted(const switch_codec_
if (((!rate && (uint32_t) imp->samples_per_second != 8000) || (rate && (uint32_t) imp->samples_per_second != rate))) {
continue;
}
if (bit && (uint32_t) imp->bits_per_second != bit) {
continue;
}
}
@@ -1636,7 +1660,7 @@ SWITCH_DECLARE(int) switch_loadable_module_get_codecs_sorted(const switch_codec_
}
/* Either looking for a specific interval or there was no interval specified and there wasn't one @20ms available */
/* Either looking for a specific interval or there was no interval specified and there wasn't one at the default ptime available */
for (imp = codec_interface->implementations; imp; imp = imp->next) {
if (imp->codec_type != SWITCH_CODEC_TYPE_VIDEO) {
@@ -1651,6 +1675,11 @@ SWITCH_DECLARE(int) switch_loadable_module_get_codecs_sorted(const switch_codec_
if (rate && (uint32_t) imp->samples_per_second != rate) {
continue;
}
if (bit && (uint32_t) imp->bits_per_second != bit) {
continue;
}
}
array[i++] = imp;
+1 -1
View File
@@ -690,7 +690,7 @@ SWITCH_DECLARE(void) switch_nat_late_init(void)
{
if (nat_globals_perm.running == 1) {
switch_scheduler_add_task(switch_epoch_time_now(NULL) + NAT_REFRESH_INTERVAL, switch_nat_republish_sched, "nat_republish", "core", 0, NULL,
SSHF_NONE);
SSHF_OWN_THREAD);
}
}
+1 -1
View File
@@ -215,7 +215,7 @@ SWITCH_DECLARE(switch_status_t) switch_regex_match_partial(const char *target, c
if (match_count > 0) {
*partial = 0;
return SWITCH_STATUS_SUCCESS;
} else if (match_count == PCRE_ERROR_PARTIAL) {
} else if (match_count == PCRE_ERROR_PARTIAL || match_count == PCRE_ERROR_BADPARTIAL) {
/* yes it is already set, but the code is clearer this way */
*partial = 1;
return SWITCH_STATUS_SUCCESS;
+28 -3
View File
@@ -239,6 +239,7 @@ struct switch_rtp {
#endif
switch_time_t send_time;
switch_byte_t auto_adj_used;
};
struct switch_rtcp_senderinfo {
@@ -662,6 +663,10 @@ SWITCH_DECLARE(void) switch_rtp_shutdown(void)
const void *var;
void *val;
if (!global_init) {
return;
}
switch_mutex_lock(port_lock);
for (hi = switch_hash_first(NULL, alloc_hash); hi; hi = switch_hash_next(hi)) {
@@ -1619,6 +1624,10 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_jitter_buffer(switch_rtp_t *
SWITCH_DECLARE(switch_status_t) switch_rtp_activate_rtcp(switch_rtp_t *rtp_session, int send_rate, switch_port_t remote_port)
{
const char *err = NULL;
if (!rtp_session->ms_per_packet) {
return SWITCH_STATUS_FALSE;
}
switch_set_flag(rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP);
@@ -2191,6 +2200,9 @@ static switch_status_t read_rtcp_packet(switch_rtp_t *rtp_session, switch_size_t
rtp_session->rtcp_fresh_frame = 1;
rtp_session->stats.rtcp.packet_count += sr->pc;
rtp_session->stats.rtcp.octet_count += sr->oc;
/* sender report */
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10,"Received a SR with %d report blocks, " \
"length in words = %d, " \
@@ -2301,6 +2313,10 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
pt = 20000;
}
if ((io_flags & SWITCH_IO_FLAG_NOBLOCK)) {
pt = 0;
}
poll_status = switch_poll(rtp_session->read_pollfd, 1, &fdr, pt);
if (rtp_session->dtmf_data.out_digit_dur > 0) {
do_2833(rtp_session);
@@ -2326,7 +2342,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
}
}
if (rtp_session->dtmf_data.out_digit_dur == 0 || switch_test_flag(rtp_session, SWITCH_RTP_FLAG_VIDEO)) {
if ((!(io_flags & SWITCH_IO_FLAG_NOBLOCK)) && (rtp_session->dtmf_data.out_digit_dur == 0 || switch_test_flag(rtp_session, SWITCH_RTP_FLAG_VIDEO))) {
return_cng_frame();
}
}
@@ -2349,6 +2365,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
if ((other_session = switch_core_session_locate(uuid))) {
switch_channel_t *other_channel = switch_core_session_get_channel(other_session);
if ((other_rtp_session = switch_channel_get_private(other_channel, "__rtcp_audio_rtp_session")) &&
other_rtp_session->rtcp_sock_output &&
switch_test_flag(other_rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP)) {
*other_rtp_session->rtcp_send_msg.body = *rtp_session->rtcp_recv_msg.body;
@@ -2519,13 +2536,14 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
switch_channel_set_variable(channel, "remote_media_port", adj_port);
switch_channel_set_variable(channel, "rtp_auto_adjust", "true");
}
rtp_session->auto_adj_used = 1;
switch_rtp_set_remote_address(rtp_session, tx_host, switch_sockaddr_get_port(rtp_session->from_addr), 0, SWITCH_FALSE, &err);
switch_clear_flag_locked(rtp_session, SWITCH_RTP_FLAG_AUTOADJ);
}
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Correct ip/port confirmed.\n");
switch_clear_flag_locked(rtp_session, SWITCH_RTP_FLAG_AUTOADJ);
rtp_session->auto_adj_used = 0;
}
}
@@ -2865,6 +2883,12 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
return ret;
}
SWITCH_DECLARE(switch_byte_t) switch_rtp_check_auto_adj(switch_rtp_t *rtp_session)
{
return rtp_session->auto_adj_used;
}
SWITCH_DECLARE(switch_size_t) switch_rtp_has_dtmf(switch_rtp_t *rtp_session)
{
switch_size_t has = 0;
@@ -3429,7 +3453,8 @@ static int rtp_common_write(switch_rtp_t *rtp_session,
rtp_session->last_write_ts = this_ts;
if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP) && !switch_test_flag(rtp_session, SWITCH_RTP_FLAG_RTCP_PASSTHRU) &&
if (rtp_session->rtcp_sock_output &&
switch_test_flag(rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP) && !switch_test_flag(rtp_session, SWITCH_RTP_FLAG_RTCP_PASSTHRU) &&
rtp_session->rtcp_interval && (rtp_session->stats.outbound.packet_count % rtp_session->rtcp_interval) == 0) {
struct switch_rtcp_senderinfo* sr = (struct switch_rtcp_senderinfo*)rtp_session->rtcp_send_msg.body;
+250
View File
@@ -2090,6 +2090,137 @@ SWITCH_DECLARE(char *) switch_url_decode(char *s)
return s;
}
SWITCH_DECLARE(void) switch_split_time(const char *exp, int *hour, int *min, int *sec)
{
char *dup = strdup(exp);
char *shour = NULL;
char *smin = NULL;
char *ssec = NULL;
switch_assert(dup);
shour = dup;
if ((smin=strchr(dup, ':'))) {
*smin++ = '\0';
if ((ssec=strchr(smin, ':'))) {
*ssec++ = '\0';
} else {
ssec = "00";
}
if (hour && shour) {
*hour = atol(shour);
}
if (min && smin) {
*min = atol(smin);
}
if (sec && ssec) {
*sec = atol(ssec);
}
}
switch_safe_free(dup);
return;
}
SWITCH_DECLARE(void) switch_split_date(const char *exp, int *year, int *month, int *day)
{
char *dup = strdup(exp);
char *syear = NULL;
char *smonth = NULL;
char *sday = NULL;
switch_assert(dup);
syear = dup;
if ((smonth=strchr(dup, '-'))) {
*smonth++ = '\0';
if ((sday=strchr(smonth, '-'))) {
*sday++ = '\0';
if (year && syear) {
*year = atol(syear);
}
if (month && smonth) {
*month = atol(smonth);
}
if (day && sday) {
*day = atol(sday);
}
}
}
switch_safe_free(dup);
return;
}
/* Ex exp value "2009-10-10 14:33:22~2009-11-10 17:32:31" */
SWITCH_DECLARE(int) switch_fulldate_cmp(const char *exp, switch_time_t *ts)
{
char *dup = strdup(exp);
char *sStart;
char *sEnd;
char *sDate;
char *sTime;
switch_time_t tsStart;
switch_time_t tsEnd;
switch_assert(dup);
sStart = dup;
if ((sEnd=strchr(dup, '~'))) {
*sEnd++ = '\0';
sDate = sStart;
if ((sTime=strchr(sStart, ' '))) {
struct tm tmTmp;
int year, month, day;
int hour, min, sec;
*sTime++ = '\0';
switch_split_date(sDate, &year, &month, &day);
switch_split_time(sTime, &hour, &min, &sec);
tmTmp.tm_year = year;
tmTmp.tm_mon = month;
tmTmp.tm_mday = day;
tmTmp.tm_hour = hour;
tmTmp.tm_min = min;
tmTmp.tm_sec = sec;
tmTmp.tm_isdst = 0;
tsStart = mktime(&tmTmp);
sDate = sEnd;
if ((sTime=strchr(sEnd, ' '))) {
struct tm tmTmp;
int year, month, day;
int hour, min, sec;
*sTime++ = '\0';
switch_split_date(sDate, &year, &month, &day);
switch_split_time(sTime, &hour, &min, &sec);
tmTmp.tm_year = year;
tmTmp.tm_mon = month;
tmTmp.tm_mday = day;
tmTmp.tm_hour = hour;
tmTmp.tm_min = min;
tmTmp.tm_sec = sec;
tmTmp.tm_isdst = 0;
tsEnd = mktime(&tmTmp);
if (tsStart <= *ts && tsEnd > *ts) {
switch_safe_free(dup);
return 1;
}
}
}
}
switch_safe_free(dup);
return 0;
}
/* Written by Marc Espie, public domain */
#define SWITCH_CTYPE_NUM_CHARS 256
@@ -2335,6 +2466,82 @@ SWITCH_DECLARE(int) switch_isxdigit(int c)
return (c < 0 ? 0 : c > 255 ? 0 : ((_switch_ctype_ + 1)[(unsigned char) c] & (_N | _X)));
}
static const char *DOW[] = {
"sat",
"sun",
"mon",
"tue",
"wed",
"thu",
"fri",
"sat",
"sun",
NULL
};
SWITCH_DECLARE(const char *) switch_dow_int2str(int val) {
if (val >= sizeof(DOW) / sizeof (const char*)) {
return NULL;
}
return DOW[val];
}
SWITCH_DECLARE(int) switch_dow_str2int(const char *exp) {
int ret = -1;
int x = -1;
for (x = 0;; x++) {
if (!DOW[x]) {
break;
}
if (!strcasecmp(DOW[x], exp)) {
ret = x;
break;
}
}
return ret;
}
SWITCH_DECLARE(int) switch_dow_cmp(const char *exp, int val)
{
char *dup = strdup(exp);
char *p_start;
char *p_end;
int ret = 0;
int start, end;
switch_assert(dup);
p_start = dup;
if ((p_end=strchr(dup, '-'))) {
*p_end++ = '\0';
} else {
p_end = p_start;
}
if (strlen(p_start) == 3) {
start = switch_dow_str2int(p_start);
} else {
start = atol(p_start);
}
if (strlen(p_end) == 3) {
end = switch_dow_str2int(p_end);
} else {
end = atol(p_end);
}
/* Following used for this example : mon-sat = 2-0, so we need to make 0(sat) + 7 */
if (end < start) {
end += 7;
}
if (start != -1 && end != -1 && val >= start && val <= end) {
ret = 1;
}
switch_safe_free(dup);
return ret;
}
SWITCH_DECLARE(int) switch_number_cmp(const char *exp, int val)
{
char *p;
@@ -2375,6 +2582,49 @@ SWITCH_DECLARE(int) switch_number_cmp(const char *exp, int val)
}
SWITCH_DECLARE(int) switch_tod_cmp(const char *exp, int val)
{
char *dup = strdup(exp);
char *minh;
char *minm;
char *mins;
char *maxh;
char *maxm;
char *maxs;
switch_assert(dup);
minh = dup;
if ((minm=strchr(dup, ':'))) {
*minm++ = '\0';
if ((maxh=strchr(minm, '-'))) {
if ((maxm=strchr(maxh, ':'))) {
*maxh++ = '\0';
*maxm++ = '\0';
/* Check if min/max seconds are present */
if ((mins=strchr(minm, ':'))) {
*mins++ = '\0';
} else {
mins = "00";
}
if ((maxs=strchr(maxm, ':'))) {
*maxs++ = '\0';
} else {
maxs = "00";
}
if (val >= (atol(minh) * 60 * 60) + (atol(minm) * 60) + atol(mins) && val < (atol(maxh) * 60 * 60) + (atol(maxm) * 60) + atol(maxs)) {
switch_safe_free(dup);
return 1;
}
}
}
}
switch_safe_free(dup);
return 0;
}
SWITCH_DECLARE(int) switch_split_user_domain(char *in, char **user, char **domain)
{
char *p = NULL, *h = NULL, *u = in;
+34 -2
View File
@@ -2039,6 +2039,18 @@ SWITCH_DECLARE(switch_xml_t) switch_xml_open_root(uint8_t reload, const char **e
return r;
}
SWITCH_DECLARE(switch_status_t) switch_xml_reload(const char **err)
{
switch_xml_t xml_root;
if ((xml_root = switch_xml_open_root(1, err))) {
switch_xml_free(xml_root);
return SWITCH_STATUS_SUCCESS;
}
return SWITCH_STATUS_GENERR;
}
SWITCH_DECLARE(switch_status_t) switch_xml_init(switch_memory_pool_t *pool, const char **err)
{
switch_xml_t xml;
@@ -2640,6 +2652,7 @@ SWITCH_DECLARE(switch_xml_t) switch_xml_cut(switch_xml_t xml)
SWITCH_DECLARE(int) switch_xml_std_datetime_check(switch_xml_t xcond) {
const char *xdt = switch_xml_attr(xcond, "date-time");
const char *xyear = switch_xml_attr(xcond, "year");
const char *xyday = switch_xml_attr(xcond, "yday");
const char *xmon = switch_xml_attr(xcond, "mon");
@@ -2650,6 +2663,7 @@ SWITCH_DECLARE(int) switch_xml_std_datetime_check(switch_xml_t xcond) {
const char *xhour = switch_xml_attr(xcond, "hour");
const char *xminute = switch_xml_attr(xcond, "minute");
const char *xminday = switch_xml_attr(xcond, "minute-of-day");
const char *xtod = switch_xml_attr(xcond, "time-of-day");
switch_time_t ts = switch_micro_time_now();
int time_match = -1;
@@ -2657,6 +2671,15 @@ SWITCH_DECLARE(int) switch_xml_std_datetime_check(switch_xml_t xcond) {
switch_time_exp_lt(&tm, ts);
if (time_match && xdt) {
char tmpdate[80];
switch_size_t retsize;
switch_strftime(tmpdate, &retsize, sizeof(tmpdate), "%Y-%m-%d %H:%M:%S", &tm);
time_match = switch_fulldate_cmp(xdt, &ts);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
"XML DateTime Check: date time[%s] =~ %s (%s)\n", tmpdate, xdt, time_match ? "PASS" : "FAIL");
}
if (time_match && xyear) {
int test = tm.tm_year + 1900;
time_match = switch_number_cmp(xyear, test);
@@ -2710,9 +2733,9 @@ SWITCH_DECLARE(int) switch_xml_std_datetime_check(switch_xml_t xcond) {
if (time_match && xwday) {
int test = tm.tm_wday + 1;
time_match = switch_number_cmp(xwday, test);
time_match = switch_dow_cmp(xwday, test);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9,
"XML DateTime Check: day of week[%d] =~ %s (%s)\n", test, xwday, time_match ? "PASS" : "FAIL");
"XML DateTime Check: day of week[%s] =~ %s (%s)\n", switch_dow_int2str(test), xwday, time_match ? "PASS" : "FAIL");
}
if (time_match && xhour) {
int test = tm.tm_hour;
@@ -2735,6 +2758,15 @@ SWITCH_DECLARE(int) switch_xml_std_datetime_check(switch_xml_t xcond) {
"XML DateTime Check: minute of day[%d] =~ %s (%s)\n", test, xminday, time_match ? "PASS" : "FAIL");
}
if (time_match && xtod) {
int test = (tm.tm_hour * 60 * 60) + (tm.tm_min * 60) + tm.tm_sec;
char tmpdate[10];
switch_snprintf(tmpdate, 6, "%d:%d:%d", tm.tm_hour, tm.tm_min, tm.tm_sec);
time_match = switch_tod_cmp(xtod, test);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9,
"XML DateTime Check: time of day[%s] =~ %s (%s)\n", tmpdate, xtod, time_match ? "PASS" : "FAIL");
}
return time_match;
}
+193
View File
@@ -0,0 +1,193 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
*
* The Initial Developer of the Original Code is
* Anthony Minessale II <anthm@freeswitch.org>
* Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Anthony Minessale II <anthm@freeswitch.org>
* Michael Jerris <mike@jerris.com>
* Pawel Pierscionek <pawel@voiceworks.pl>
* Bret McDanel <trixter AT 0xdecafbad.com>
*
*
* tone2wav.c -- Generate a .wav from teletone spec
*
*/
#ifndef _XOPEN_SOURCE
#define _XOPEN_SOURCE 600
#endif
#ifndef WIN32
#ifdef HAVE_SETRLIMIT
#include <sys/resource.h>
#endif
#endif
#include <switch.h>
#include <switch_version.h>
/* Picky compiler */
#ifdef __ICC
#pragma warning (disable:167)
#endif
static int teletone_handler(teletone_generation_session_t *ts, teletone_tone_map_t *map)
{
switch_file_handle_t *fh = (switch_file_handle_t *) ts->user_data;
int wrote;
switch_size_t len;
wrote = teletone_mux_tones(ts, map);
len = wrote;
if (switch_core_file_write(fh, ts->buffer, &len) != SWITCH_STATUS_SUCCESS) {
return -1;
}
return 0;
}
#define fail() r = 255; goto end
/* the main application entry point */
int main(int argc, char *argv[])
{
teletone_generation_session_t ts;
int file_flags = SWITCH_FILE_FLAG_WRITE | SWITCH_FILE_DATA_SHORT;
int r = 0;
int rate = 8000;
char *file = NULL, *script = NULL;
switch_file_handle_t fh = { 0 };
const char *err = NULL;
switch_bool_t verbose = SWITCH_FALSE;
int i = 0, c = 1, help = 0;
for(i = 1; i < argc; i++) {
if (!strstr(argv[i], "-")) break;
if (!strcmp(argv[i], "-v")) {
verbose = SWITCH_TRUE;
}
if (!strcmp(argv[i], "-s")) {
c = 2;
}
if (!strcmp(argv[i], "-h")) {
help = 1;
}
if (!strncmp(argv[i], "-R", 2)) {
char *p = argv[i] + 2;
if (p) {
int tmp = atoi(p);
if (tmp > 0) {
rate = tmp;
}
}
}
}
if (argc - i != 2 || help) {
char *app = NULL;
if (!help) printf("Invalid input!\n");
if ((app = strrchr(argv[0], '/'))) {
app++;
} else {
app = argv[0];
}
printf("USAGE: %s [options] <file> <tones>\n", app);
printf("================================================================================\n");
printf("Options:\n"
"-s\t\tStereo\n"
"-h\t\tHelp\n"
"-R<rate>\tSet Rate (8000,16000,32000,48000) etc.\n"
"-v\t\tVerbose Logging\n"
"<file>\t\tAny file supported by libsndfile\n"
"<tones>\t\tA valid teletone script http://wiki.freeswitch.org/wiki/TGML"
"\n\n\n"
);
return 255;
}
file = argv[i];
script = argv[i+1];
if (switch_core_init(SCF_MINIMAL, verbose, &err) != SWITCH_STATUS_SUCCESS) {
printf("Cannot init core [%s]\n", err);
fail();
}
switch_loadable_module_init(SWITCH_FALSE);
if (switch_loadable_module_load_module((char *) SWITCH_GLOBAL_dirs.mod_dir, (char *) "mod_sndfile", SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) {
printf("Cannot init mod_sndfile [%s]\n", err);
fail();
}
if (switch_core_file_open(&fh, file, c, rate, file_flags, NULL) != SWITCH_STATUS_SUCCESS) {
printf("Cannot open file %s\n", file);
fail();
}
teletone_init_session(&ts, 0, teletone_handler, &fh);
ts.rate = rate;
ts.channels = c;
ts.duration = 250 * (rate / 1000 / c);
ts.wait = 50 * (rate / 1000 / c);
if (verbose) {
ts.debug = 10;
ts.debug_stream = stdout;
}
teletone_run(&ts, script);
teletone_destroy_session(&ts);
switch_core_file_close(&fh);
printf("File: %s generated.....\n\nPlease support:\nFreeSWITCH http://www.freeswitch.org\nClueCon http://www.cluecon.com\n", file);
end:
switch_core_destroy();
return r;
}
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4:
*/