Freeswitch-trunk
Threads by month
- ----- 2026 -----
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- 14172 discussions
[commit] r13885 - in freeswitch/trunk/scripts/contrib/ledr/mod_xml_odbc: . xml_odbc_templates
by FreeSWITCH SVN 21 Jun '09
by FreeSWITCH SVN 21 Jun '09
21 Jun '09
Author: ledr
Date: Sun Jun 21 09:21:22 2009
New Revision: 13885
Log:
Created templating based on sql queries to generate XML - not finished yet
Added:
freeswitch/trunk/scripts/contrib/ledr/mod_xml_odbc/xml_odbc_templates/
freeswitch/trunk/scripts/contrib/ledr/mod_xml_odbc/xml_odbc_templates/console.conf.xml
freeswitch/trunk/scripts/contrib/ledr/mod_xml_odbc/xml_odbc_templates/dialplan.xml
freeswitch/trunk/scripts/contrib/ledr/mod_xml_odbc/xml_odbc_templates/directory.xml
Modified:
freeswitch/trunk/scripts/contrib/ledr/mod_xml_odbc/mod_xml_odbc.c
freeswitch/trunk/scripts/contrib/ledr/mod_xml_odbc/structure.sql
freeswitch/trunk/scripts/contrib/ledr/mod_xml_odbc/xml_odbc.conf.xml
Modified: freeswitch/trunk/scripts/contrib/ledr/mod_xml_odbc/mod_xml_odbc.c
==============================================================================
--- freeswitch/trunk/scripts/contrib/ledr/mod_xml_odbc/mod_xml_odbc.c (original)
+++ freeswitch/trunk/scripts/contrib/ledr/mod_xml_odbc/mod_xml_odbc.c Sun Jun 21 09:21:22 2009
@@ -38,7 +38,10 @@
#endif
typedef enum {
- XML_ODBC_DIRECTORY
+ XML_ODBC_CONFIG = 0,
+ XML_ODBC_DIRECTORY = 0,
+ XML_ODBC_DIALPLAN = 0,
+ XML_ODBC_PHRASE = 0
} xml_odbc_query_type_t;
SWITCH_MODULE_LOAD_FUNCTION(mod_xml_odbc_load);
@@ -47,7 +50,31 @@
static switch_bool_t debug = SWITCH_FALSE;
-#define XML_ODBC_SYNTAX "[debug_on|debug_off]"
+static switch_status_t xml_odbc_render_template(char *template, switch_hash_t *hash, switch_xml_t xml_out, int *off);
+static switch_status_t xml_odbc_render_tag(switch_xml_t xml_in, switch_hash_t *hash, switch_xml_t xml_out, int *off);
+
+#define XML_ODBC_SYNTAX "[debug_on|debug_off|render_template]"
+
+static int logi = 0;
+static void logger(char *str)
+{
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "DEBUG[%i] [%s]\n", ++logi, str);
+}
+
+static struct {
+ char *dbname;
+ char *odbc_dsn;
+ char *template;
+ switch_xml_t templates_tag;
+ switch_mutex_t *mutex;
+ switch_memory_pool_t *pool;
+#ifdef SWITCH_HAVE_ODBC
+ switch_odbc_handle_t *master_odbc;
+#else
+ void *filler1;
+#endif
+} globals;
+
SWITCH_STANDARD_API(xml_odbc_function)
{
@@ -63,6 +90,16 @@
debug = SWITCH_TRUE;
} else if (!strcasecmp(cmd, "debug_off")) {
debug = SWITCH_FALSE;
+ } else if (!strcasecmp(cmd, "render_template")) {
+// TODO make it configurable what themplate is rendered instead of static "not_found"
+ int off = 0;
+ switch_xml_t xml_out = NULL;
+ switch_hash_t *hash;
+ if (switch_core_hash_init(&hash, globals.pool) != SWITCH_STATUS_SUCCESS) {
+// need_vars_map = -1; // does it need to be freed ? :)
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Can't init params hash!\n");
+ }
+ xml_odbc_render_template("not_found", hash, xml_out, &off);
} else {
goto usage;
}
@@ -80,122 +117,152 @@
char *bindings;
} xml_binding_t;
-static struct {
- char *dbname;
- char *odbc_dsn;
- char *query_domain_key_user;
- char *query_domain_params;
- char *query_domain_variables;
- char *query_user_attrs;
- char *query_user_params;
- char *query_user_variables;
- char *query_groups;
- switch_mutex_t *mutex;
- switch_memory_pool_t *pool;
-#ifdef SWITCH_HAVE_ODBC
- switch_odbc_handle_t *master_odbc;
-#else
- void *filler1;
-#endif
-} globals;
-typedef struct did_uid_helper {
- char *domain_id;
- char *user_id;
-} did_uid_helper_t;
+typedef struct xml_odbc_query_helper {
+ switch_xml_t xml_in;
+ switch_xml_t xml_out;
+ int *off;
+ switch_hash_t *hash;
+} xml_odbc_query_helper_t;
-static int did_uid_callback(void *pArg, int argc, char **argv, char **columnNames)
+
+static int xml_odbc_query_callback(void *pArg, int argc, char **argv, char **columnName)
{
- did_uid_helper_t *h = (did_uid_helper_t *) pArg;
+ xml_odbc_query_helper_t *qh = (xml_odbc_query_helper_t *) pArg;
+ switch_xml_t xml_in_tmp;
+ int i;
+
+ /* set all columnName/argv key/value pairs in qh->hash */
+ for (i = 0; i < argc; i++) {
+ switch_core_hash_insert(qh->hash, columnName[i], argv[i]); // does a hash insert overwrite old entries ?
+ }
- h->domain_id = strdup(argv[0]);
- h->user_id = strdup(argv[1]);
+ /* render all xml children */
+ for (xml_in_tmp = qh->xml_in->child; xml_in_tmp; xml_in_tmp = xml_in_tmp->ordered) {
+ xml_odbc_render_tag(xml_in_tmp, qh->hash, qh->xml_out, qh->off);
+ }
return 0;
}
-static int set_xml_attr_callback(void *pArg, int argc, char **argv, char **columnNames)
+
+static switch_status_t xml_odbc_render_tag(switch_xml_t xml_in, switch_hash_t *hash, switch_xml_t xml_out, int *off)
{
- switch_xml_t *xml = (switch_xml_t *) pArg;
- switch_xml_set_attr_d(*xml, argv[0], argv[1]);
- return 0;
-}
+ switch_xml_t xml_in_tmp = NULL;
+ int i;
-typedef struct xml_helper {
- switch_xml_t xml;
- char *str;
- int off;
-} xml_helper_t;
+ xml_odbc_query_helper_t query_helper;
-static int add_xml_child_with_nvpair_callback(void *pArg, int argc, char **argv, char **columnNames)
-{
- xml_helper_t *h = (xml_helper_t *) pArg;
- switch_xml_t xml = NULL;
+ if (!strcasecmp(xml_in->name, "xml-odbc-do")) {
+ char *name = NULL;
+ char *value = NULL;
+ char *zero_rows_break_to = NULL;
+ char *no_template_break_to = NULL;
+
+ name = (char *) switch_xml_attr_soft(xml_in, "name");
+ value = (char *) switch_xml_attr_soft(xml_in, "value");
+ zero_rows_break_to = (char *) switch_xml_attr_soft(xml_in, "on-zero-rows-break-to");
+ no_template_break_to = (char *) switch_xml_attr_soft(xml_in, "on-no-template-break-to");
+
+ if (!strcasecmp(name, "break-to") && !switch_strlen_zero(value)) { // WHAT TO DO WITH FURTHER RENDERING LOWER ON THE STACK ?!?!?!
+ xml_out = NULL;
+ off = 0; // <- ?
+ if (xml_odbc_render_template(value, hash, xml_out, off) == SWITCH_STATUS_FALSE) {
+ if (!switch_strlen_zero(no_template_break_to)) {
+ xml_odbc_render_template(no_template_break_to, hash, xml_out, off);
+ }
+ }
+ } else if (!strcasecmp(name, "query") && !switch_strlen_zero(value)) {
+ // do an auto expasion on value to replace all ${foo} parts based on switch_hash_t hash
+ query_helper.xml_in = xml_in;
+ query_helper.xml_out = xml_out;
+ query_helper.off = off;
+ query_helper.hash = hash;
+ if (switch_odbc_handle_callback_exec(globals.master_odbc, value, xml_odbc_query_callback, &query_helper) == SWITCH_ODBC_SUCCESS) {
+ // nothing
+ } else if (!switch_strlen_zero(zero_rows_break_to)) { // if zero rows returned then switch_odbc_handle_callback_exec != SWITCH_ODBC_SUCCESS ???
+ xml_out = NULL;
+ off = 0; // <- ?
+ xml_odbc_render_template(zero_rows_break_to, hash, xml_out, off);
+ }
+ }
- if ((xml = switch_xml_add_child_d(h->xml, h->str, h->off++))) {
- switch_xml_set_attr_d(xml, "name", argv[0]);
- switch_xml_set_attr_d(xml, "value", argv[1]);
- }
+ } else {
- return 0;
-}
+ /* set name if current root node */
+ if (switch_strlen_zero(xml_out->name)) { // I should match here on off instead of on name == "" ?
+ xml_out->name = strdup(xml_in->name);
+
+ /* or create a child */
+ } else if (!(xml_out = switch_xml_add_child_d(xml_out, xml_in->name, *off++))) {
+ return SWITCH_STATUS_FALSE;
+ }
-static int add_xml_group_and_user_callback(void *pArg, int argc, char **argv, char **columnName)
-{
- xml_helper_t *h = (xml_helper_t *) pArg;
- switch_xml_t xml = NULL;
+//SWITCH_DECLARE(void *) switch_core_hash_find(_In_ switch_hash_t *hash, _In_z_ const char *key);
+logger((char *)switch_core_hash_find(hash, "domain"));
- if ((xml = switch_xml_add_child_d(h->xml, "group", h->off++))) {
- switch_xml_set_attr_d(xml, "name", argv[0]);
- if ((xml = switch_xml_add_child_d(xml, "users", h->off++))) {
- if ((xml = switch_xml_add_child_d(xml, "user", h->off++))) {
- switch_xml_set_attr_d(xml, "id", h->str);
- switch_xml_set_attr_d(xml, "type", "pointer");
- }
+ /* copy all attrs */
+ for (i = 0; xml_in->attr[i]; i+=2) {
+ // do an auto expasion on attr[i+1] to replace all ${foo} parts based on switch_hash_t hash
+ switch_xml_set_attr(xml_out, xml_in->attr[i], xml_in->attr[i+1]);
+ }
+
+ /* copy all children and render them */
+ for (xml_in_tmp = xml_in->child; xml_in_tmp; xml_in_tmp = xml_in_tmp->ordered) {
+ xml_odbc_render_tag(xml_in_tmp, hash, xml_out, off);
}
+
}
- return 0;
+ return SWITCH_STATUS_SUCCESS;
}
-static int xml_odbc_result_not_found(switch_xml_t xml, int *off)
+
+static switch_status_t xml_odbc_render_template(char *template_name, switch_hash_t *hash, switch_xml_t xml_out, int *off)
{
- switch_xml_t sub = NULL;
+ switch_xml_t template_tag = NULL, sub_tag = NULL;
- if ((sub = switch_xml_add_child_d(xml, "section", *off++))) {
- switch_xml_set_attr_d(sub, "name", "result");
- if ((sub = switch_xml_add_child_d(sub, "result", *off++))) {
- switch_xml_set_attr_d(sub, "status", "not found");
+ for (template_tag = switch_xml_child(globals.templates_tag, "template"); template_tag; template_tag = template_tag->next) {
+ char *template_tag_name = (char*) switch_xml_attr_soft(template_tag, "name");
+ if (!strcmp(template_tag_name, template_name)) {
+ for (sub_tag = template_tag->child; sub_tag; sub_tag = sub_tag->ordered) {
+ xml_odbc_render_tag(sub_tag, hash, xml_out, off);
+ return SWITCH_STATUS_SUCCESS;
+ }
}
}
-
- return 0;
+ return SWITCH_STATUS_FALSE;
}
+
static switch_xml_t xml_odbc_search(const char *section, const char *tag_name, const char *key_name, const char *key_value, switch_event_t *params, void *user_data)
{
xml_binding_t *binding = (xml_binding_t *) user_data;
switch_event_header_t *hi;
- switch_xml_t xml = NULL, sub = NULL, sub2 = NULL, sub3 = NULL;
-
- char *dir_user = NULL, *dir_domain = NULL, *dir_key = NULL;
- char *sql;
-
- int off = 0, ret = 1;
+ switch_xml_t xml_out = NULL;
+ if ((xml_out = switch_xml_new(""))) {
+ //switch_xml_set_attr_d(xml_out, "type", "freeswitch/xml");
+ }
xml_odbc_query_type_t query_type;
- did_uid_helper_t pdata;
- xml_helper_t pdata2;
+ switch_hash_t *hash;
+
+ int off = 0, ret = 1;
if (!binding) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No bindings... sorry bud returning now\n");
return NULL;
}
-
- if (!strcmp(section, "directory")) {
+ if (!strcmp(section, "configuration")) {
+ query_type = XML_ODBC_CONFIG;
+ } else if (!strcmp(section, "directory")) {
query_type = XML_ODBC_DIRECTORY;
+ } else if (!strcmp(section, "dialplan")) {
+ query_type = XML_ODBC_DIALPLAN;
+ } else if (!strcmp(section, "phrases")) {
+ query_type = XML_ODBC_PHRASE;
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid section\n");
return NULL;
@@ -203,147 +270,29 @@
if (params) {
if ((hi = params->headers)) {
- for (; hi; hi = hi->next) {
- switch (query_type) {
- case XML_ODBC_DIRECTORY:
-
-//switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "DEBUG in xml_odbc_search with header name=[%s], value=[%s]\n", hi->name, hi->value);
- if (!strcmp(hi->name, "user")) {
- dir_user = strdup(hi->value);
- } else if (!strcmp(hi->name, "domain")) {
- dir_domain = strdup(hi->value);
- } else if (!strcmp(hi->name, "key")) {
- dir_key = strdup(hi->value);
- }
- break;
- }
+ /* initialize hash */
+ if (switch_core_hash_init(&hash, globals.pool) != SWITCH_STATUS_SUCCESS) {
+// need_vars_map = -1; // does it need to be freed ? :)
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Can't init params hash!\n");
}
- switch (query_type) {
- case XML_ODBC_DIRECTORY:
- //if (dir_user && dir_domain) {
- if (dir_domain) {
- if ((xml = switch_xml_new("document"))) {
- switch_xml_set_attr_d(xml, "type", "freeswitch/xml");
-
- if (!dir_user) {
-// sql = switch_mprintf("SELECT count(*) FROM dir_domains WHERE name = '%q';", dir_domain);
-// if (switch_odbc_handle_callback_exec(globals.master_odbc, sql, count_callback, &pdata10741) == SWITCH_ODBC_SUCCESS) {
-// TODO: Factor out the domain search thing (with params and variables) from below, and call it from here as well..
-// xml_odbc_result_not_found(xml, &off);
-// } else {
- xml_odbc_result_not_found(xml, &off);
-// }
-
- } else {
- sql = switch_mprintf(globals.query_domain_key_user, dir_domain, dir_key, dir_user);
- if (switch_odbc_handle_callback_exec(globals.master_odbc, sql, did_uid_callback, &pdata) == SWITCH_ODBC_SUCCESS) {
- if (!pdata.domain_id || !pdata.user_id) {
- xml_odbc_result_not_found(xml, &off);
-
- } else {
- if ((sub = switch_xml_add_child_d(xml, "section", off++))) {
- switch_xml_set_attr_d(sub, "name", "directory");
-
- if ((sub = switch_xml_add_child_d(sub, "domain", off++))) {
- switch_xml_set_attr_d(sub, "name", dir_domain);
-
- if ((sub2 = switch_xml_add_child_d(sub, "params", off++))) {
- sql = switch_mprintf(globals.query_domain_params, pdata.domain_id);
- pdata2.xml = sub2;
- pdata2.off = off;
- pdata2.str = "param";
- if (switch_odbc_handle_callback_exec(globals.master_odbc, sql, add_xml_child_with_nvpair_callback, &pdata2) == SWITCH_ODBC_SUCCESS) {
- }
- }
-
- if ((sub2 = switch_xml_add_child_d(sub, "variables", off++))) {
- sql = switch_mprintf(globals.query_domain_variables, pdata.domain_id);
- pdata2.xml = sub2;
- pdata2.off = off;
- pdata2.str = "variable";
- if (switch_odbc_handle_callback_exec(globals.master_odbc, sql, add_xml_child_with_nvpair_callback, &pdata2) == SWITCH_ODBC_SUCCESS) {
- }
- }
-
- if ((sub = switch_xml_add_child_d(sub, "groups", off++))) {
-
- if ((sub2 = switch_xml_add_child_d(sub, "group", off++))) {
- switch_xml_set_attr_d(sub2, "name", "default");
-
- if ((sub2 = switch_xml_add_child_d(sub2, "users", off++))) {
-
- if ((sub2 = switch_xml_add_child_d(sub2, "user", off++))) {
-
- sql = switch_mprintf(globals.query_user_attrs, pdata.user_id);
- if (switch_odbc_handle_callback_exec(globals.master_odbc, sql, set_xml_attr_callback, &sub2)) {
- }
-
- if ((sub3 = switch_xml_add_child_d(sub2, "params", off++))) {
- sql = switch_mprintf(globals.query_user_params, pdata.user_id);
- pdata2.xml = sub3;
- pdata2.off = off;
- pdata2.str = "param";
- if (switch_odbc_handle_callback_exec(globals.master_odbc, sql, add_xml_child_with_nvpair_callback, &pdata2) == SWITCH_ODBC_SUCCESS) {
- }
- }
-
- if ((sub3 = switch_xml_add_child_d(sub2, "variables", off++))) {
- sql = switch_mprintf(globals.query_user_variables, pdata.user_id);
- pdata2.xml = sub3;
- pdata2.off = off;
- pdata2.str = "variable";
- if (switch_odbc_handle_callback_exec(globals.master_odbc, sql, add_xml_child_with_nvpair_callback, &pdata2) == SWITCH_ODBC_SUCCESS) {
- }
- }
-
- }
-
- }
-
- }
-
- sql = switch_mprintf(globals.query_groups, pdata.user_id);
- pdata2.xml = sub;
- pdata2.off = off;
- pdata2.str = dir_user;
- if (switch_odbc_handle_callback_exec(globals.master_odbc, sql, add_xml_group_and_user_callback, &pdata2) == SWITCH_ODBC_SUCCESS) {
- }
-
- }
- }
- }
- }
- }
- }
- }
-
- if (debug == SWITCH_TRUE) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Debug dump of XML generated:\n%s", switch_xml_toxml(xml, SWITCH_FALSE));
- }
-
- free(dir_user);
- dir_user = NULL;
-
- free(dir_key);
- dir_key = NULL;
-
- free(dir_domain);
- dir_domain = NULL;
-
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
- "Something bad happened during the query construction phase likely exten(%s) or domain(%s) is null\n", dir_user, dir_domain);
- goto cleanup;
+ for (; hi; hi = hi->next) {
+ if (debug == SWITCH_TRUE) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "DEBUG in xml_odbc_search, header [%s]=[%s]\n", hi->name, hi->value);
}
- break;
+ switch_core_hash_insert(hash, hi->name, hi->value); // prefix with 'h_' to avoid collision with keys returned by SELECT's ?
}
- } else {
- goto cleanup;
+ xml_odbc_render_template(globals.template, hash, xml_out, &off); // TODO globals.template should be replace with something specific for this section
}
+ } else {
+ goto cleanup;
+ }
+
+ if (debug == SWITCH_TRUE) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Debug dump of XML generated:\n%s", switch_xml_toxml(xml_out, SWITCH_FALSE));
}
ret = 0;
@@ -351,26 +300,28 @@
cleanup:
if (ret) {
- switch_xml_free(xml);
+ switch_xml_free(xml_out);
return NULL;
}
- return xml;
+ return xml_out;
}
+
static switch_status_t do_config()
{
char *cf = "xml_odbc.conf";
- switch_xml_t cfg, xml, bindings_tag, binding_tag, param;
+ switch_xml_t cfg, xml, bindings_tag, binding_tag, templates_tag, param;
xml_binding_t *binding = NULL;
- //switch_core_db_t *db;
switch_status_t status = SWITCH_STATUS_SUCCESS;
char *odbc_user = NULL;
char *odbc_pass = NULL;
char *sql = NULL;
+logger("X");
+
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;
@@ -381,6 +332,13 @@
goto done;
}
+ if (!(templates_tag = switch_xml_child(cfg, "templates"))) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing <templates> tag!\n");
+ goto done;
+ }
+
+ globals.templates_tag = templates_tag;
+
for (binding_tag = switch_xml_child(bindings_tag, "binding"); binding_tag; binding_tag = binding_tag->next) {
char *bname = (char*) switch_xml_attr_soft(binding_tag, "name");
@@ -399,20 +357,8 @@
*odbc_pass++ = '\0';
}
}
- } else if (!strcasecmp(var, "query-domain-key-user") && !switch_strlen_zero(val)) {
- globals.query_domain_key_user = strdup(val);
- } else if (!strcasecmp(var, "query-domain-params") && !switch_strlen_zero(val)) {
- globals.query_domain_params = strdup(val);
- } else if (!strcasecmp(var, "query-domain-variables") && !switch_strlen_zero(val)) {
- globals.query_domain_variables = strdup(val);
- } else if (!strcasecmp(var, "query-user-attrs") && !switch_strlen_zero(val)) {
- globals.query_user_attrs = strdup(val);
- } else if (!strcasecmp(var, "query-user-params") && !switch_strlen_zero(val)) {
- globals.query_user_params = strdup(val);
- } else if (!strcasecmp(var, "query-user-variables") && !switch_strlen_zero(val)) {
- globals.query_user_variables = strdup(val);
- } else if (!strcasecmp(var, "query-groups") && !switch_strlen_zero(val)) {
- globals.query_groups = strdup(val);
+ } else if (!strcasecmp(var, "template") && !switch_strlen_zero(val)) {
+ globals.template = strdup(val);
}
}
@@ -459,6 +405,7 @@
return status;
}
+
SWITCH_MODULE_LOAD_FUNCTION(mod_xml_odbc_load)
{
@@ -480,6 +427,7 @@
SWITCH_ADD_API(xml_odbc_api_interface, "xml_odbc", "XML ODBC", xml_odbc_function, XML_ODBC_SYNTAX);
switch_console_set_complete("add xml_odbc debug_on");
switch_console_set_complete("add xml_odbc debug_off");
+ switch_console_set_complete("add xml_odbc render_template");
if (do_config() != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to load xml_odbc config file\n");
@@ -490,11 +438,13 @@
return SWITCH_STATUS_SUCCESS;
}
+
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_xml_odbc_shutdown)
{
return SWITCH_STATUS_SUCCESS;
}
+
/* For Emacs:
* Local Variables:
* mode:c
@@ -503,5 +453,5 @@
* c-basic-offset:4
* End:
* For VIM:
- * vim:set softtabstop=4 shiftwidth=4 tabstop=4:
+* vim:set softtabstop=4 shiftwidth=4 tabstop=4:
*/
Modified: freeswitch/trunk/scripts/contrib/ledr/mod_xml_odbc/structure.sql
==============================================================================
--- freeswitch/trunk/scripts/contrib/ledr/mod_xml_odbc/structure.sql (original)
+++ freeswitch/trunk/scripts/contrib/ledr/mod_xml_odbc/structure.sql Sun Jun 21 09:21:22 2009
@@ -39,21 +39,19 @@
CREATE TABLE `dir_users` (
`id` INT NOT NULL AUTO_INCREMENT,
`dir_domain_id` INT NOT NULL,
+ `enabled` TINYINT(1) NOT NULL,
+ `username` VARCHAR(255) NOT NULL,
+ `cidr` VARCHAR(255),
+ `mailbox` VARCHAR(255),
+ `number-alias` VARCHAR(255),
PRIMARY KEY (`id`),
+ KEY `dir_users_username` (`username`),
+ KEY `dir_users_cidr` (`cidr`),
+ KEY `dir_users_mailbox` (`mailbox`),
+ KEY `dir_users_number-alias` (`number-alias`),
FOREIGN KEY (`dir_domain_id`) REFERENCES `dir_domains` (`id`)
);
-CREATE TABLE `dir_user_attrs` (
- `id` INT NOT NULL AUTO_INCREMENT,
- `dir_user_id` INT NOT NULL,
- `name` VARCHAR(255) NOT NULL,
- `value` VARCHAR(255) NOT NULL,
- PRIMARY KEY (`id`),
- FOREIGN KEY (`dir_user_id`) REFERENCES `dir_users` (`id`),
- KEY `dir_user_attrs_name` (`name`),
- KEY `dir_user_attrs_value` (`value`)
-);
-
CREATE TABLE `dir_user_params` (
`id` INT NOT NULL AUTO_INCREMENT,
`dir_user_id` INT NOT NULL,
Modified: freeswitch/trunk/scripts/contrib/ledr/mod_xml_odbc/xml_odbc.conf.xml
==============================================================================
--- freeswitch/trunk/scripts/contrib/ledr/mod_xml_odbc/xml_odbc.conf.xml (original)
+++ freeswitch/trunk/scripts/contrib/ledr/mod_xml_odbc/xml_odbc.conf.xml Sun Jun 21 09:21:22 2009
@@ -1,35 +1,97 @@
<configuration name="xml_odbc.conf" description="XML ODBC Configuration">
+
<bindings>
+<!--
+ <binding name="configuration">
+ <param name="odbc-dsn" value="freeswitch:freeswitch:secret"/>
+ <param name="template" value="configuration"/>
+ </binding>
+-->
<binding name="directory">
<param name="odbc-dsn" value="freeswitch:freeswitch:secret"/>
+ <!-- <param name="template" value="directory"/> -->
+ <!-- <param name="template" value="not_found"/> -->
+ <param name="template" value="someuser"/>
+ </binding>
+<!--
+ <binding name="dialplan">
+ <param name="odbc-dsn" value="freeswitch:freeswitch:secret"/>
+ <param name="template" value="dialplan"/>
+ </binding>
- <param name="query-domain-key-user" value="SELECT
- dir_domains.id AS domain_id,
- dir_users.id AS user_id
- FROM
- dir_domains,
- dir_users,
- dir_user_attrs
- WHERE
- dir_domains.name = '%q' AND
- dir_user_attrs.name = '%q' AND
- dir_user_attrs.value = '%q' AND
- dir_domains.id = dir_users.dir_domain_id AND
- dir_users.id = dir_user_attrs.dir_user_id;"/>
-
- <param name="query-domain-params" value="SELECT name, value FROM dir_domain_params WHERE dir_domain_id = '%q';"/>
-
- <param name="query-domain-variables" value="SELECT name, value FROM dir_domain_variables WHERE dir_domain_id = '%q';"/>
-
- <param name="query-user-attrs" value="SELECT name, value FROM dir_user_attrs WHERE dir_user_id = '%q';"/>
+ <binding name="phrases">
+ <param name="odbc-dsn" value="freeswitch:freeswitch:secret"/>
+ <param name="template" value="phrases"/>
+ </binding>
+-->
+ </bindings>
- <param name="query-user-params" value="SELECT name, value FROM dir_user_params WHERE dir_user_id = '%q';"/>
+ <templates>
- <param name="query-user-variables" value="SELECT name, value FROM dir_user_variables WHERE dir_user_id = '%q';"/>
+ <template name="configuration">
+ <xml-odbc-do name="break-to" value="${section}" on-no-template-break-to="simple_configuration"/>
+ </template>
+
+ <template name="simple_configuration">
+ <document type="freeswitch/xml"> <!-- should this tag be automatically rendered first on xml_out and left out here ? -->
+ <configuration name="${section}">
+ <settings>
+ <xml-odbc-do name="query" value="
+ SELECT
+ name, value
+ FROM
+ cnf_settings
+ WHERE
+ hostname = '${hostname}' AND
+ section = '${section}';">
+ <param name="${name}" value="${value}"/>
+ </xml-odbc-do>
+ </settings>
+ </configuration>
+ </document>
+ </template>
+
+ <template name="not_found">
+ <document type="freeswitch/xml">
+ <section name="result">
+ <result status="not found"/>
+ </section>
+ </document>
+ </template>
+
+ <template name="someuser">
+ <document type="freeswitch/xml">
+ <section name="directory">
+ <domain name="${domain}">
+ <params>
+ <param name="some_domain_param" value="some_domain_value"/>
+ </params>
+ <variables>
+ </variables>
+ <groups>
+ <group name="default">
+ <users>
+ <user id="someuser" mailbox="leon(a)toyos.nl" cidr="" number-alias="0031320227470">
+ <params>
+ <param name="password" value="secret"/>
+ </params>
+ <variables>
+ <variable name="accountcode" value="1234"/>
+ </variables>
+ </user>
+ </users>
+ </group>
+ <group name="prepay">
+ <user id="someuser" type="pointer"/>
+ </group>
+ </groups>
+ </domain>
+ </section>
+ </document>
+ </template>
+
+ <X-PRE-PROCESS cmd="include" data="xml_odbc_templates/*.xml"/>
- <param name="query-groups" value="SELECT dir_groups.name FROM dir_groups, dir_groups_users
- WHERE dir_groups_users.dir_user_id = '%q' AND dir_groups_users.dir_group_id = dir_groups.id;"/>
+ </templates>
- </binding>
- </bindings>
</configuration>
Added: freeswitch/trunk/scripts/contrib/ledr/mod_xml_odbc/xml_odbc_templates/console.conf.xml
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/ledr/mod_xml_odbc/xml_odbc_templates/console.conf.xml Sun Jun 21 09:21:22 2009
@@ -0,0 +1,31 @@
+<include>
+ <template name="console.conf">
+ <document type="freeswitch/xml">
+ <configuration name="console.conf" description="Console Logger">
+ <mappings>
+ <xml-odbc-do name="query" value="
+ SELECT
+ name, value
+ FROM
+ cnf_console_mappings
+ WHERE
+ hostname = '${hostname}';">
+ <mapping name="${name}" value="${value}"/>
+ </xml-odbc-do>
+ </mappings>
+ <settings>
+ <xml-odbc-do name="query" value="
+ SELECT
+ name, value
+ FROM
+ cnf_settings
+ WHERE
+ hostname = '${hostname}' AND
+ section = '${section}';">
+ <param name="${name}" value="${value}"/>
+ </xml-odbc-do>
+ </settings>
+ </configuration>
+ </document>
+ </template>
+</include>
Added: freeswitch/trunk/scripts/contrib/ledr/mod_xml_odbc/xml_odbc_templates/dialplan.xml
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/ledr/mod_xml_odbc/xml_odbc_templates/dialplan.xml Sun Jun 21 09:21:22 2009
@@ -0,0 +1,17 @@
+<include> <!-- NOT FINISHED ! -->
+ <template name="dialplan">
+ <document type="freeswitch/xml">
+ <xml-odbc-do name="query" on-zero-rows-break-to="not_found" value="
+ SELECT * FROM dialplan WHERE dialed_number='${dialed_number}';"/>
+ <section name="dialplan" description="RE Dial Plan For FreeSwitch">
+ <context name="default">
+ <extension name="test9">
+ <condition field="destination_number" expression="^83789$">
+ <action application="bridge" data="iax/guest(a)conference.freeswitch.org/888"/>
+ </condition>
+ </extension>
+ </context>
+ </section>
+ </document>
+ </template>
+</include>
Added: freeswitch/trunk/scripts/contrib/ledr/mod_xml_odbc/xml_odbc_templates/directory.xml
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/ledr/mod_xml_odbc/xml_odbc_templates/directory.xml Sun Jun 21 09:21:22 2009
@@ -0,0 +1,91 @@
+<include>
+ <template name="directory">
+ <document type="freeswitch/xml">
+ <xml-odbc-do name="query" on-zero-rows-break-to="not_found" value="
+ SELECT
+ dir_domains.id AS domain_id,
+ dir_users.id AS user_id,
+ dir_users.username,
+ dir_users.cidr,
+ dir_users.mailbox,
+ dir_users.number-alias
+ FROM
+ dir_domains,
+ dir_users
+ WHERE
+ dir_users.${key} = '${value}' AND
+ dir_domains.name = '${domain_name}' AND
+ dir_users.domain_id = dir_domains.id AND
+ dir_users.enabled = 1;"/>
+ <section name="directory">
+ <domain name="${domain_name}">
+ <params>
+ <xml-odbc-do name="query" value="
+ SELECT
+ name, value
+ FROM
+ dir_domain_params
+ WHERE
+ dir_domain_id = '${domain_id}';">
+ <param name="${name}" value="${value}"/>
+ </xml-odbc-do>
+ </params>
+ <variables>
+ <xml-odbc-do name="query" value="
+ SELECT
+ name, value
+ FROM
+ dir_domain_variables
+ WHERE
+ dir_domain_id = '${domain_id}';">
+ <variable name="${name}" value="${value}"/>
+ </xml-odbc-do>
+ </variables>
+ <groups>
+ <group name="default">
+ <users>
+ <user id="${username}" mailbox="${mailbox}" cidr="${cidr}" number-alias="${number-alias}">
+ <params>
+ <xml-odbc-do name="query" on-zero-rows-break-to="not_found" value="
+ SELECT
+ name, value
+ FROM
+ dir_domain_params
+ WHERE
+ dir_domain_id = '${domain_id}';">
+ <param name="${name}" value="${value}"/>
+ </xml-odbc-do>
+ </params>
+ <variables>
+ <xml-odbc-do name="query" value="
+ SELECT
+ name, value
+ FROM
+ dir_domain_params
+ WHERE
+ dir_domain_id = '${domain_id}';">
+ <variable name="${name}" value="${value}"/>
+ </xml-odbc-do>
+ </variables>
+ </user>
+ </users>
+ </group>
+ <xml-odbc-do name="query" value="
+ SELECT
+ name AS group_name
+ FROM
+ dir_groups,
+ dir_groups_users
+ WHERE
+ dir_groups_users.dir_group_id
+ dir_user_id = '${user_id}';">
+ <group name="${group_name}">
+ <user id="${username}" type="pointer"/>
+ </group>
+ </xml-odbc-do>
+ </groups>
+ </domain>
+ </section>
+ </document>
+ </template>
+</include>
1
0
20 Jun '09
Author: mrene
Date: Sat Jun 20 14:55:30 2009
New Revision: 13884
Log:
mod_voicemail: implement reload in non-blocking way
Modified:
freeswitch/trunk/src/mod/applications/mod_voicemail/mod_voicemail.c
Modified: freeswitch/trunk/src/mod/applications/mod_voicemail/mod_voicemail.c
==============================================================================
--- freeswitch/trunk/src/mod/applications/mod_voicemail/mod_voicemail.c (original)
+++ freeswitch/trunk/src/mod/applications/mod_voicemail/mod_voicemail.c Sat Jun 20 14:55:30 2009
@@ -67,6 +67,9 @@
VM_DATE_NEVER
} date_location_t;
+typedef enum {
+ PFLAG_DESTROY = 1 << 0
+} vm_flags_t;
#define VM_PROFILE_CONFIGITEM_COUNT 100
@@ -137,6 +140,7 @@
switch_bool_t auto_playback_recordings;
switch_thread_rwlock_t *rwlock;
switch_memory_pool_t *pool;
+ uint32_t flags;
switch_xml_config_item_t config[VM_PROFILE_CONFIGITEM_COUNT];
switch_xml_config_string_options_t config_str_pool;
@@ -259,8 +263,19 @@
NULL
};
+static void free_profile(vm_profile_t *profile)
+{
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Destroying Profile %s\n", profile->name);
+#ifdef SWITCH_HAVE_ODBC
+ if (profile->odbc_dsn && profile->master_odbc) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Closing ODBC Database! %s\n", profile->name);
+ switch_odbc_handle_destroy(&profile->master_odbc);
+ }
+#endif
+ switch_core_destroy_memory_pool(&profile->pool);
+}
-static void destroy_profile(const char *profile_name)
+static void destroy_profile(const char *profile_name, switch_bool_t block)
{
vm_profile_t *profile = NULL;
switch_mutex_lock(globals.mutex);
@@ -270,21 +285,23 @@
switch_mutex_unlock(globals.mutex);
if (!profile) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Profile %s\n", profile_name);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "[%s] Invalid Profile\n", profile_name);
return;
}
- /* wait readers */
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Waiting for write lock (Profile %s)\n", profile->name);
- switch_thread_rwlock_wrlock(profile->rwlock);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Destroying Profile %s\n", profile->name);
-#ifdef SWITCH_HAVE_ODBC
- if (profile->odbc_dsn && profile->master_odbc) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Closing ODBC Database! %s\n", profile->name);
- switch_odbc_handle_destroy(&profile->master_odbc);
+ if (block) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "[%s] Waiting for write lock\n", profile->name);
+ switch_thread_rwlock_wrlock(profile->rwlock);
+ } else {
+ if (switch_thread_rwlock_trywrlock(profile->rwlock) != SWITCH_STATUS_SUCCESS) {
+ /* Lock failed, set the destroy flag so it'll be destroyed whenever its not in use anymore */
+ switch_set_flag(profile, PFLAG_DESTROY);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "[%s] Profile is in use, memory will be freed whenever its not longer in use\n", profile->name);
+ return;
+ }
}
-#endif
- switch_core_destroy_memory_pool(&profile->pool);
+
+ free_profile(profile);
}
@@ -312,8 +329,6 @@
switch_assert(profile);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "In %s newvalue=%s\n", __SWITCH_FUNC__, newvalue);
-
if (callback_type == CONFIG_LOAD || callback_type == CONFIG_RELOAD)
{
char *email_headers = NULL, *email_body = NULL;
@@ -350,8 +365,6 @@
vm_profile_t *profile = (vm_profile_t*)item->data;
switch_assert(profile);
-
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "In %s newvalue=%s\n", __SWITCH_FUNC__, newvalue);
if (callback_type == CONFIG_LOAD || callback_type == CONFIG_RELOAD)
{
@@ -389,8 +402,6 @@
vm_profile_t *profile = (vm_profile_t*)item->data;
switch_assert(profile);
-
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "In %s newvalue=%s\n", __SWITCH_FUNC__, newvalue);
if (callback_type == CONFIG_LOAD || callback_type == CONFIG_RELOAD)
{
@@ -756,7 +767,6 @@
switch_core_hash_insert(globals.profile_hash, profile->name, profile);
}
-
end:
if (xml) {
switch_xml_free(xml);
@@ -775,6 +785,8 @@
profile = load_profile(profile_name);
}
if (profile) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "[%s] rwlock\n", profile->name);
+
switch_thread_rwlock_rdlock(profile->rwlock);
}
switch_mutex_unlock(globals.mutex);
@@ -782,6 +794,16 @@
return profile;
}
+static void profile_rwunlock(vm_profile_t *profile)
+{
+ switch_thread_rwlock_unlock(profile->rwlock);
+ if (switch_test_flag(profile, PFLAG_DESTROY)) {
+ if (switch_thread_rwlock_tryrdlock(profile->rwlock) == SWITCH_STATUS_SUCCESS) {
+ free_profile(profile);
+ }
+ }
+}
+
static switch_status_t load_config(void)
{
@@ -2713,7 +2735,7 @@
status = SWITCH_STATUS_FALSE;
}
}
- switch_thread_rwlock_unlock(profile->rwlock);
+ profile_rwunlock(profile);
switch_core_destroy_memory_pool(&pool);
@@ -3147,7 +3169,7 @@
voicemail_leave_main(session, profile, domain_name, id);
}
- switch_thread_rwlock_unlock(profile->rwlock);
+ profile_rwunlock(profile);
}
@@ -3196,7 +3218,7 @@
if ((profile = get_profile(profilename))) {
message_count(profile, id, domain, "inbox", &total_new_messages, &total_saved_messages,
&total_new_urgent_messages, &total_saved_urgent_messages);
- switch_thread_rwlock_unlock(profile->rwlock);
+ profile_rwunlock(profile);
} else {
stream->write_function(stream, "-ERR No such profile\n");
goto done;
@@ -3815,16 +3837,16 @@
stream->write_function(stream, "Reload XML [%s]\n", err);
}
if ((profile = get_profile(argv[1]))) {
- switch_thread_rwlock_unlock(profile->rwlock);
+ profile_rwunlock(profile);
}
stream->write_function(stream, "+OK load complete\n");
goto done;
} else if (argc > 1 && !strcasecmp(argv[0], "unload")) {
- destroy_profile(argv[1]);
+ destroy_profile(argv[1], SWITCH_FALSE);
stream->write_function(stream, "+OK unload complete\n");
goto done;
} else if (argc > 1 && !strcasecmp(argv[0], "reload")) {
- destroy_profile(argv[1]);
+ destroy_profile(argv[1], SWITCH_FALSE);
if (argc > 2 && !strcasecmp(argv[2], "reloadxml")) {
if ((xml_root = switch_xml_open_root(1, &err))) {
switch_xml_free(xml_root);
@@ -3832,7 +3854,7 @@
stream->write_function(stream, "Reload XML [%s]\n", err);
}
if ((profile = get_profile(argv[1]))) {
- switch_thread_rwlock_unlock(profile->rwlock);
+ profile_rwunlock(profile);
}
stream->write_function(stream, "+OK reload complete\n");
goto done;
@@ -3905,7 +3927,7 @@
do_rss(profile, user, domain, host, port, uri, stream);
}
- switch_thread_rwlock_unlock(profile->rwlock);
+ profile_rwunlock(profile);
goto done;
error:
1
0
[commit] r13883 - in freeswitch/trunk/src/mod/applications: mod_cidlookup mod_memcache
by FreeSWITCH SVN 20 Jun '09
by FreeSWITCH SVN 20 Jun '09
20 Jun '09
Author: rupa
Date: Sat Jun 20 09:09:35 2009
New Revision: 13883
Log:
MODAPP-292
del with changed config api in rev 13878
Modified:
freeswitch/trunk/src/mod/applications/mod_cidlookup/mod_cidlookup.c
freeswitch/trunk/src/mod/applications/mod_memcache/mod_memcache.c
Modified: freeswitch/trunk/src/mod/applications/mod_cidlookup/mod_cidlookup.c
==============================================================================
--- freeswitch/trunk/src/mod/applications/mod_cidlookup/mod_cidlookup.c (original)
+++ freeswitch/trunk/src/mod/applications/mod_cidlookup/mod_cidlookup.c Sat Jun 20 09:09:35 2009
@@ -100,7 +100,7 @@
static switch_event_node_t *reload_xml_event = NULL;
-static switch_status_t config_callback_dsn(switch_xml_config_item_t *data, 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;
#ifdef SWITCH_HAVE_ODBC
@@ -115,7 +115,7 @@
}
if ((callback_type == CONFIG_LOAD || callback_type == CONFIG_RELOAD) && changed) {
- odbc_dsn = strdup(*((char**)data->ptr));
+ odbc_dsn = strdup(newvalue);
if(switch_strlen_zero(odbc_dsn)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "No local database defined.\n");
Modified: freeswitch/trunk/src/mod/applications/mod_memcache/mod_memcache.c
==============================================================================
--- freeswitch/trunk/src/mod/applications/mod_memcache/mod_memcache.c (original)
+++ freeswitch/trunk/src/mod/applications/mod_memcache/mod_memcache.c Sat Jun 20 09:09:35 2009
@@ -55,18 +55,18 @@
static switch_event_node_t *NODE = NULL;
-static switch_status_t config_callback_memcached(switch_xml_config_item_t *data, 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;
memcached_st *newmemcached = NULL;
memcached_st *oldmemcached = NULL;
- char *memcached_str = NULL;
+ const char *memcached_str = NULL;
memcached_return rc;
unsigned int servercount;
if ((callback_type == CONFIG_LOAD || callback_type == CONFIG_RELOAD) && changed) {
- memcached_str = *((char**)data->ptr);
+ memcached_str = newvalue;
/* initialize main ptr */
memcached_server = memcached_servers_parse(memcached_str);
1
0
Author: mikej
Date: Fri Jun 19 22:53:06 2009
New Revision: 13882
Log:
build: fix automake warnings about underquoted definitions in apr macros (FSBUILD-175)
Modified:
freeswitch/trunk/libs/apr/build/apr_hints.m4
freeswitch/trunk/libs/apr/build/apr_network.m4
freeswitch/trunk/libs/apr/build/apr_threads.m4
Modified: freeswitch/trunk/libs/apr/build/apr_hints.m4
==============================================================================
--- freeswitch/trunk/libs/apr/build/apr_hints.m4 (original)
+++ freeswitch/trunk/libs/apr/build/apr_hints.m4 Fri Jun 19 22:53:06 2009
@@ -35,7 +35,7 @@
dnl Generally, we force the setting of CC, and add flags
dnl to CFLAGS, CPPFLAGS, LIBS and LDFLAGS.
dnl
-AC_DEFUN(APR_PRELOAD, [
+AC_DEFUN([APR_PRELOAD], [
if test "x$apr_preload_done" != "xyes" ; then
apr_preload_done="yes"
@@ -431,7 +431,7 @@
dnl
dnl Allows us to provide a default choice of compiler which
dnl the user can override.
-AC_DEFUN(APR_CC_HINTS, [
+AC_DEFUN([APR_CC_HINTS], [
case "$host" in
*-apple-aux3*)
APR_SETIFNULL(CC, [gcc])
Modified: freeswitch/trunk/libs/apr/build/apr_network.m4
==============================================================================
--- freeswitch/trunk/libs/apr/build/apr_network.m4 (original)
+++ freeswitch/trunk/libs/apr/build/apr_network.m4 Fri Jun 19 22:53:06 2009
@@ -25,7 +25,7 @@
dnl can't use getaddrinfo() because we can't get strings
dnl describing the error codes.
dnl
-AC_DEFUN(APR_CHECK_WORKING_GETADDRINFO,[
+AC_DEFUN([APR_CHECK_WORKING_GETADDRINFO],[
AC_CACHE_CHECK(for working getaddrinfo, ac_cv_working_getaddrinfo,[
AC_TRY_RUN( [
#ifdef HAVE_NETDB_H
@@ -74,7 +74,7 @@
])
dnl Check whether the AI_ADDRCONFIG flag can be used with getaddrinfo
-AC_DEFUN(APR_CHECK_GETADDRINFO_ADDRCONFIG, [
+AC_DEFUN([APR_CHECK_GETADDRINFO_ADDRCONFIG], [
AC_CACHE_CHECK(for working AI_ADDRCONFIG, apr_cv_gai_addrconfig, [
AC_TRY_RUN([
#ifdef HAVE_NETDB_H
@@ -110,7 +110,7 @@
dnl
dnl check for working getnameinfo()
dnl
-AC_DEFUN(APR_CHECK_WORKING_GETNAMEINFO,[
+AC_DEFUN([APR_CHECK_WORKING_GETNAMEINFO],[
AC_CACHE_CHECK(for working getnameinfo, ac_cv_working_getnameinfo,[
AC_TRY_RUN( [
#ifdef HAVE_NETDB_H
@@ -165,7 +165,7 @@
dnl
dnl check for negative error codes for getaddrinfo()
dnl
-AC_DEFUN(APR_CHECK_NEGATIVE_EAI,[
+AC_DEFUN([APR_CHECK_NEGATIVE_EAI],[
AC_CACHE_CHECK(for negative error codes for getaddrinfo, ac_cv_negative_eai,[
AC_TRY_RUN( [
#ifdef HAVE_NETDB_H
@@ -197,7 +197,7 @@
dnl
dnl Note that this test is executed too early to see if we have all of
dnl the headers.
-AC_DEFUN(APR_CHECK_GETHOSTBYNAME_R_STYLE,[
+AC_DEFUN([APR_CHECK_GETHOSTBYNAME_R_STYLE],[
dnl Try and compile a glibc2 gethostbyname_r piece of code, and set the
dnl style of the routines to glibc2 on success
@@ -257,7 +257,7 @@
dnl
dnl see if TCP_NODELAY setting is inherited from listening sockets
dnl
-AC_DEFUN(APR_CHECK_TCP_NODELAY_INHERITED,[
+AC_DEFUN([APR_CHECK_TCP_NODELAY_INHERITED],[
AC_CACHE_CHECK(if TCP_NODELAY setting is inherited from listening sockets, ac_cv_tcp_nodelay_inherited,[
AC_TRY_RUN( [
#include <stdio.h>
@@ -425,7 +425,7 @@
dnl
dnl see if O_NONBLOCK setting is inherited from listening sockets
dnl
-AC_DEFUN(APR_CHECK_O_NONBLOCK_INHERITED,[
+AC_DEFUN([APR_CHECK_O_NONBLOCK_INHERITED],[
AC_CACHE_CHECK(if O_NONBLOCK setting is inherited from listening sockets, ac_cv_o_nonblock_inherited,[
AC_TRY_RUN( [
#include <stdio.h>
@@ -538,7 +538,7 @@
dnl
dnl check for socklen_t, fall back to unsigned int
dnl
-AC_DEFUN(APR_CHECK_SOCKLEN_T,[
+AC_DEFUN([APR_CHECK_SOCKLEN_T],[
AC_CACHE_CHECK(for socklen_t, ac_cv_socklen_t,[
AC_TRY_COMPILE([
#ifdef HAVE_SYS_TYPES_H
@@ -562,7 +562,7 @@
])
-AC_DEFUN(APR_CHECK_INET_ADDR,[
+AC_DEFUN([APR_CHECK_INET_ADDR],[
AC_CACHE_CHECK(for inet_addr, ac_cv_func_inet_addr,[
AC_TRY_COMPILE([
#ifdef HAVE_SYS_TYPES_H
@@ -588,7 +588,7 @@
])
-AC_DEFUN(APR_CHECK_INET_NETWORK,[
+AC_DEFUN([APR_CHECK_INET_NETWORK],[
AC_CACHE_CHECK(for inet_network, ac_cv_func_inet_network,[
AC_TRY_COMPILE([
#ifdef HAVE_SYS_TYPES_H
@@ -614,7 +614,7 @@
])
dnl Check for presence of struct sockaddr_storage.
-AC_DEFUN(APR_CHECK_SOCKADDR_STORAGE,[
+AC_DEFUN([APR_CHECK_SOCKADDR_STORAGE],[
AC_CACHE_CHECK(for sockaddr_storage, apr_cv_define_sockaddr_storage,[
AC_TRY_COMPILE([
#ifdef HAVE_SYS_TYPES_H
@@ -636,7 +636,7 @@
])
dnl Check for presence of struct sockaddr_in6.
-AC_DEFUN(APR_CHECK_SOCKADDR_IN6,[
+AC_DEFUN([APR_CHECK_SOCKADDR_IN6],[
AC_CACHE_CHECK(for sockaddr_in6, ac_cv_define_sockaddr_in6,[
AC_TRY_COMPILE([
#ifdef HAVE_SYS_TYPES_H
@@ -664,7 +664,7 @@
dnl
dnl APR_H_ERRNO_COMPILE_CHECK
dnl
-AC_DEFUN(APR_H_ERRNO_COMPILE_CHECK,[
+AC_DEFUN([APR_H_ERRNO_COMPILE_CHECK],[
if test x$1 != x; then
CPPFLAGS="-D$1 $CPPFLAGS"
fi
@@ -750,7 +750,7 @@
dnl
dnl checks which flags are necessary for <netdb.h> to define h_errno
dnl
-AC_DEFUN(APR_CHECK_H_ERRNO_FLAG,[
+AC_DEFUN([APR_CHECK_H_ERRNO_FLAG],[
AC_MSG_CHECKING([for h_errno in netdb.h])
AC_CACHE_VAL(ac_cv_h_errno_cppflags,[
APR_H_ERRNO_COMPILE_CHECK
@@ -778,7 +778,7 @@
])
-AC_DEFUN(APR_EBCDIC,[
+AC_DEFUN([APR_EBCDIC],[
AC_CACHE_CHECK([whether system uses EBCDIC],ac_cv_ebcdic,[
AC_TRY_RUN( [
int main(void) {
Modified: freeswitch/trunk/libs/apr/build/apr_threads.m4
==============================================================================
--- freeswitch/trunk/libs/apr/build/apr_threads.m4 (original)
+++ freeswitch/trunk/libs/apr/build/apr_threads.m4 Fri Jun 19 22:53:06 2009
@@ -26,7 +26,7 @@
dnl pthreads is not available.
dnl Turn off warnings if we're using gcc.
dnl
-AC_DEFUN(APR_CHECK_PTHREADS_H, [
+AC_DEFUN([APR_CHECK_PTHREADS_H], [
if test "$GCC" = "yes"; then
SAVE_FL="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS -w"
@@ -41,7 +41,7 @@
dnl
dnl APR_CHECK_PTHREAD_GETSPECIFIC_TWO_ARGS
dnl
-AC_DEFUN(APR_CHECK_PTHREAD_GETSPECIFIC_TWO_ARGS, [
+AC_DEFUN([APR_CHECK_PTHREAD_GETSPECIFIC_TWO_ARGS], [
AC_CACHE_CHECK(whether pthread_getspecific takes two arguments, ac_cv_pthread_getspecific_two_args,[
AC_TRY_COMPILE([
#include <pthread.h>
@@ -65,7 +65,7 @@
dnl
dnl APR_CHECK_PTHREAD_ATTR_GETDETACHSTATE_ONE_ARG
dnl
-AC_DEFUN(APR_CHECK_PTHREAD_ATTR_GETDETACHSTATE_ONE_ARG, [
+AC_DEFUN([APR_CHECK_PTHREAD_ATTR_GETDETACHSTATE_ONE_ARG], [
AC_CACHE_CHECK(whether pthread_attr_getdetachstate takes one argument, ac_cv_pthread_attr_getdetachstate_one_arg,[
AC_TRY_COMPILE([
#include <pthread.h>
@@ -91,7 +91,7 @@
dnl Try running a program which uses pthreads, executing the
dnl actions-if-success commands on success.
dnl
-AC_DEFUN(APR_PTHREADS_TRY_RUN, [
+AC_DEFUN([APR_PTHREADS_TRY_RUN], [
AC_TRY_RUN( [
#include <pthread.h>
#include <stddef.h>
@@ -122,7 +122,7 @@
dnl Try to find a way to enable POSIX threads. Sets the
dnl pthreads_working variable to "yes" on success.
dnl
-AC_DEFUN(APR_PTHREADS_CHECK,[
+AC_DEFUN([APR_PTHREADS_CHECK],[
AC_CACHE_CHECK([for CFLAGS needed for pthreads], [apr_cv_pthreads_cflags],
[apr_ptc_cflags=$CFLAGS
@@ -182,12 +182,12 @@
dnl the checks for threading support so that they can restored if the
dnl result is not what the caller wanted.
dnl
-AC_DEFUN(APR_PTHREADS_CHECK_SAVE, [
+AC_DEFUN([APR_PTHREADS_CHECK_SAVE], [
apr_pthsv_CFLAGS="$CFLAGS"
apr_pthsv_LIBS="$LIBS"
])dnl
-AC_DEFUN(APR_PTHREADS_CHECK_RESTORE, [
+AC_DEFUN([APR_PTHREADS_CHECK_RESTORE], [
CFLAGS="$apr_pthsv_CFLAGS"
LIBS="$apr_pthsv_LIBS"
])dnl
@@ -195,7 +195,7 @@
dnl
dnl APR_CHECK_SIGWAIT_ONE_ARG
dnl
-AC_DEFUN(APR_CHECK_SIGWAIT_ONE_ARG,[
+AC_DEFUN([APR_CHECK_SIGWAIT_ONE_ARG],[
AC_CACHE_CHECK(whether sigwait takes one argument,ac_cv_sigwait_one_arg,[
AC_TRY_COMPILE([
#if defined(__NETBSD__) || defined(DARWIN)
1
0
[commit] r13881 - in freeswitch/trunk/libs/unimrcp: . build/vsprops plugins/mrcp-pocketsphinx plugins/mrcp-pocketsphinx/src
by FreeSWITCH SVN 20 Jun '09
by FreeSWITCH SVN 20 Jun '09
20 Jun '09
Author: brian
Date: Fri Jun 19 22:40:46 2009
New Revision: 13881
Log:
Author: achaloyan <achaloyan@f001bc3a-424a-0410-80a0-a715b8f413a8>
Date: Fri Jun 19 19:14:14 2009 +0000
svn-id: https://unimrcp.googlecode.com/svn/trunk@996 f001bc3a-424a-0410-80a0-a715b8f413a8
Added:
freeswitch/trunk/libs/unimrcp/build/vsprops/pocketsphinx.vsprops
freeswitch/trunk/libs/unimrcp/plugins/mrcp-pocketsphinx/
freeswitch/trunk/libs/unimrcp/plugins/mrcp-pocketsphinx/Makefile.am
freeswitch/trunk/libs/unimrcp/plugins/mrcp-pocketsphinx/mrcppocketsphinx.vcproj
freeswitch/trunk/libs/unimrcp/plugins/mrcp-pocketsphinx/src/
freeswitch/trunk/libs/unimrcp/plugins/mrcp-pocketsphinx/src/mrcp_pocketsphinx.c
Modified:
freeswitch/trunk/libs/unimrcp/.update
Modified: freeswitch/trunk/libs/unimrcp/.update
==============================================================================
--- freeswitch/trunk/libs/unimrcp/.update (original)
+++ freeswitch/trunk/libs/unimrcp/.update Fri Jun 19 22:40:46 2009
@@ -1 +1 @@
-Tue Jun 16 17:36:06 CDT 2009
+Fri Jun 19 22:39:34 CDT 2009
Added: freeswitch/trunk/libs/unimrcp/build/vsprops/pocketsphinx.vsprops
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/unimrcp/build/vsprops/pocketsphinx.vsprops Fri Jun 19 22:40:46 2009
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="windows-1251"?>
+<VisualStudioPropertySheet
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="pocketsphinx"
+ InheritedPropertySheets="$(ProjectDir)..\..\build\vsprops\unibase.vsprops"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""$(PocketSphinxDir)\include";"$(SphinxBaseDir)\include""
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="sphinxbase.lib pocketsphinx.lib"
+ AdditionalLibraryDirectories=""$(PocketSphinxDir)\bin\$(ConfigurationName)";"$(SphinxBaseDir)\lib\$(ConfigurationName)""
+ />
+ <UserMacro
+ Name="PocketSphinxDir"
+ Value="$(LibRootDir)libs\pocketsphinx"
+ />
+ <UserMacro
+ Name="SphinxBaseDir"
+ Value="$(LibRootDir)libs\sphinxbase"
+ />
+</VisualStudioPropertySheet>
Added: freeswitch/trunk/libs/unimrcp/plugins/mrcp-pocketsphinx/Makefile.am
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/unimrcp/plugins/mrcp-pocketsphinx/Makefile.am Fri Jun 19 22:40:46 2009
@@ -0,0 +1,16 @@
+MAINTAINERCLEANFILES = Makefile.in
+
+INCLUDES = -Iinclude \
+ -I$(top_srcdir)/libs/mrcp-engine/include \
+ -I$(top_srcdir)/libs/mrcp/include \
+ -I$(top_srcdir)/libs/mrcp/message/include \
+ -I$(top_srcdir)/libs/mrcp/control/include \
+ -I$(top_srcdir)/libs/mrcp/resources/include \
+ -I$(top_srcdir)/libs/mpf/include \
+ -I$(top_srcdir)/libs/apr-toolkit/include \
+ $(UNIMRCP_APR_INCLUDES) $(UNIMRCP_APU_INCLUDES)
+
+plugin_LTLIBRARIES = mrcppocketsphinx.la
+
+mrcppocketsphinx_la_SOURCES = src/mrcp_pocketsphinx.c.c
+mrcppocketsphinx_la_LDFLAGS = -module $(PLUGIN_LT_VERSION)
Added: freeswitch/trunk/libs/unimrcp/plugins/mrcp-pocketsphinx/mrcppocketsphinx.vcproj
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/unimrcp/plugins/mrcp-pocketsphinx/mrcppocketsphinx.vcproj Fri Jun 19 22:40:46 2009
@@ -0,0 +1,165 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="mrcppocketsphinx"
+ ProjectGUID="{3C614AE8-B611-4D43-A9AF-1CAA440A9F69}"
+ RootNamespace="mrcppocketsphinx"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(ProjectDir)..\..\build\vsprops\unidebug.vsprops;$(ProjectDir)..\..\build\vsprops\pocketsphinx.vsprops;$(ProjectDir)..\..\build\vsprops\unimrcpplugin.vsprops"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="include"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(ProjectDir)..\..\build\vsprops\unirelease.vsprops;$(ProjectDir)..\..\build\vsprops\pocketsphinx.vsprops;$(ProjectDir)..\..\build\vsprops\unimrcpplugin.vsprops"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="include"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="include"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ </Filter>
+ <Filter
+ Name="src"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ >
+ <File
+ RelativePath=".\src\mrcp_pocketsphinx.c"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
Added: freeswitch/trunk/libs/unimrcp/plugins/mrcp-pocketsphinx/src/mrcp_pocketsphinx.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/unimrcp/plugins/mrcp-pocketsphinx/src/mrcp_pocketsphinx.c Fri Jun 19 22:40:46 2009
@@ -0,0 +1,232 @@
+/*
+ * Copyright 2008 Arsen Chaloyan
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Some mandatory rules for plugin implementation.
+ * 1. Each plugin MUST contain the following function as an entry point of the plugin
+ * MRCP_PLUGIN_DECLARE(mrcp_resource_engine_t*) mrcp_plugin_create(apr_pool_t *pool)
+ * 2. One and only one response MUST be sent back to the received request.
+ * 3. Methods (callbacks) of the MRCP engine channel MUST not block.
+ * (asynch response can be sent from the context of other thread)
+ * 4. Methods (callbacks) of the MPF engine stream MUST not block.
+ */
+
+#include "mrcp_resource_engine.h"
+#include "mrcp_recog_resource.h"
+#include "mrcp_recog_header.h"
+#include "mrcp_generic_header.h"
+#include "mrcp_message.h"
+#include "mpf_activity_detector.h"
+#include "apt_log.h"
+
+
+typedef struct pocketsphinx_engine_t pocketsphinx_engine_t;
+typedef struct pocketsphinx_recognizer_t pocketsphinx_recognizer_t;
+
+/** Declaration of recognizer engine methods */
+static apt_bool_t pocketsphinx_engine_destroy(mrcp_resource_engine_t *engine);
+static apt_bool_t pocketsphinx_engine_open(mrcp_resource_engine_t *engine);
+static apt_bool_t pocketsphinx_engine_close(mrcp_resource_engine_t *engine);
+static mrcp_engine_channel_t* pocketsphinx_recognizer_create(mrcp_resource_engine_t *engine, apr_pool_t *pool);
+
+static const struct mrcp_engine_method_vtable_t engine_vtable = {
+ pocketsphinx_engine_destroy,
+ pocketsphinx_engine_open,
+ pocketsphinx_engine_close,
+ pocketsphinx_recognizer_create
+};
+
+
+/** Declaration of recognizer channel methods */
+static apt_bool_t pocketsphinx_recognizer_destroy(mrcp_engine_channel_t *channel);
+static apt_bool_t pocketsphinx_recognizer_open(mrcp_engine_channel_t *channel);
+static apt_bool_t pocketsphinx_recognizer_close(mrcp_engine_channel_t *channel);
+static apt_bool_t pocketsphinx_recognizer_request_process(mrcp_engine_channel_t *channel, mrcp_message_t *request);
+
+static const struct mrcp_engine_channel_method_vtable_t channel_vtable = {
+ pocketsphinx_recognizer_destroy,
+ pocketsphinx_recognizer_open,
+ pocketsphinx_recognizer_close,
+ pocketsphinx_recognizer_request_process
+};
+
+/** Declaration of recognizer audio stream methods */
+static apt_bool_t pocketsphinx_stream_destroy(mpf_audio_stream_t *stream);
+static apt_bool_t pocketsphinx_stream_open(mpf_audio_stream_t *stream);
+static apt_bool_t pocketsphinx_stream_close(mpf_audio_stream_t *stream);
+static apt_bool_t pocketsphinx_stream_write(mpf_audio_stream_t *stream, const mpf_frame_t *frame);
+
+static const mpf_audio_stream_vtable_t audio_stream_vtable = {
+ pocketsphinx_stream_destroy,
+ NULL,
+ NULL,
+ NULL,
+ pocketsphinx_stream_open,
+ pocketsphinx_stream_close,
+ pocketsphinx_stream_write
+};
+
+/** Declaration of pocketsphinx engine */
+struct pocketsphinx_engine_t {
+ mrcp_resource_engine_t *base;
+};
+
+/** Declaration of pocketsphinx recognizer */
+struct pocketsphinx_recognizer_t {
+ /** Back pointer to engine */
+ pocketsphinx_engine_t *engine;
+ /** Engine channel base */
+ mrcp_engine_channel_t *channel;
+};
+
+/** Declare this macro to use log routine of the server, plugin is loaded from */
+MRCP_PLUGIN_LOGGER_IMPLEMENT
+
+
+/** Create pocketsphinx engine (engine is an aggregation of recognizers) */
+MRCP_PLUGIN_DECLARE(mrcp_resource_engine_t*) mrcp_plugin_create(apr_pool_t *pool)
+{
+ pocketsphinx_engine_t *engine = apr_palloc(pool,sizeof(pocketsphinx_engine_t));
+
+ /* create resource engine base */
+ engine->base = mrcp_resource_engine_create(
+ MRCP_RECOGNIZER_RESOURCE, /* MRCP resource identifier */
+ engine, /* object to associate */
+ &engine_vtable, /* virtual methods table of resource engine */
+ pool); /* pool to allocate memory from */
+ return engine->base;
+}
+
+static apt_bool_t pocketsphinx_engine_destroy(mrcp_resource_engine_t *engine)
+{
+ return TRUE;
+}
+
+static apt_bool_t pocketsphinx_engine_open(mrcp_resource_engine_t *engine)
+{
+ return TRUE;
+}
+
+static apt_bool_t pocketsphinx_engine_close(mrcp_resource_engine_t *engine)
+{
+ return TRUE;
+}
+
+/** Create pocketsphinx recognizer */
+static mrcp_engine_channel_t* pocketsphinx_recognizer_create(mrcp_resource_engine_t *engine, apr_pool_t *pool)
+{
+ mrcp_engine_channel_t *channel;
+ pocketsphinx_recognizer_t *recognizer = apr_palloc(pool,sizeof(pocketsphinx_recognizer_t));
+
+ /* create engine channel base */
+ channel = mrcp_engine_sink_channel_create(
+ engine, /* resource engine */
+ &channel_vtable, /* virtual methods table of engine channel */
+ &audio_stream_vtable, /* virtual methods table of audio stream */
+ recognizer, /* object to associate */
+ NULL, /* codec descriptor might be NULL by default */
+ pool); /* pool to allocate memory from */
+
+ recognizer->channel = channel;
+ return channel;
+}
+
+/** Destroy engine channel */
+static apt_bool_t pocketsphinx_recognizer_destroy(mrcp_engine_channel_t *channel)
+{
+ return TRUE;
+}
+
+/** Open engine channel (asynchronous response MUST be sent)*/
+static apt_bool_t pocketsphinx_recognizer_open(mrcp_engine_channel_t *channel)
+{
+ return mrcp_engine_channel_open_respond(channel,TRUE);
+}
+
+/** Close engine channel (asynchronous response MUST be sent)*/
+static apt_bool_t pocketsphinx_recognizer_close(mrcp_engine_channel_t *channel)
+{
+ return mrcp_engine_channel_close_respond(channel);
+}
+
+
+/** Process RECOGNIZE request */
+static apt_bool_t pocketsphinx_recognize(pocketsphinx_recognizer_t *recognizer, mrcp_message_t *request, mrcp_message_t *response)
+{
+ return TRUE;
+}
+
+/** Process STOP request */
+static apt_bool_t pocketsphinx_stop(pocketsphinx_recognizer_t *recognizer, mrcp_message_t *request, mrcp_message_t *response)
+{
+ return TRUE;
+}
+
+static apt_bool_t pocketsphinx_recognizer_request_process(mrcp_engine_channel_t *channel, mrcp_message_t *request)
+{
+ pocketsphinx_recognizer_t *recognizer = channel->method_obj;
+ apt_bool_t processed = FALSE;
+ mrcp_message_t *response = mrcp_response_create(request,request->pool);
+ switch(request->start_line.method_id) {
+ case RECOGNIZER_SET_PARAMS:
+ break;
+ case RECOGNIZER_GET_PARAMS:
+ break;
+ case RECOGNIZER_DEFINE_GRAMMAR:
+ break;
+ case RECOGNIZER_RECOGNIZE:
+ processed = pocketsphinx_recognize(recognizer,request,response);
+ break;
+ case RECOGNIZER_GET_RESULT:
+ break;
+ case RECOGNIZER_START_INPUT_TIMERS:
+ break;
+ case RECOGNIZER_STOP:
+ processed = pocketsphinx_stop(recognizer,request,response);
+ break;
+ default:
+ break;
+ }
+ if(processed == FALSE) {
+ /* send asynchronous response for not handled request */
+ mrcp_engine_channel_message_send(channel,response);
+ }
+ return TRUE;
+}
+
+
+
+
+
+static apt_bool_t pocketsphinx_stream_destroy(mpf_audio_stream_t *stream)
+{
+ return TRUE;
+}
+
+static apt_bool_t pocketsphinx_stream_open(mpf_audio_stream_t *stream)
+{
+ return TRUE;
+}
+
+static apt_bool_t pocketsphinx_stream_close(mpf_audio_stream_t *stream)
+{
+ return TRUE;
+}
+
+static apt_bool_t pocketsphinx_stream_write(mpf_audio_stream_t *stream, const mpf_frame_t *frame)
+{
+ return TRUE;
+}
1
0
20 Jun '09
Author: brian
Date: Fri Jun 19 22:39:54 2009
New Revision: 13880
Log:
Author: achaloyan <achaloyan@f001bc3a-424a-0410-80a0-a715b8f413a8>
Date: Fri Jun 19 18:11:47 2009 +0000
Fixed L16 encode/decode
svn-id: https://unimrcp.googlecode.com/svn/trunk@995
Author: achaloyan <achaloyan@f001bc3a-424a-0410-80a0-a715b8f413a8>
Date: Fri Jun 19 18:10:49 2009 +0000
Make decision whether to set decoder before and encoder after the bridge based on codec vtable (even linear codec such as L16 has encoder and decoder)
svn-id: https://unimrcp.googlecode.com/svn/trunk@994
Author: achaloyan <achaloyan@f001bc3a-424a-0410-80a0-a715b8f413a8>
Date: Fri Jun 19 17:24:00 2009 +0000
Added missing #include for BYTEFUNC (fixed compilation undr gcc)
svn-id: https://unimrcp.googlecode.com/svn/trunk@993
Modified:
freeswitch/trunk/libs/unimrcp/libs/mpf/src/mpf_codec_linear.c
freeswitch/trunk/libs/unimrcp/libs/mpf/src/mpf_context.c
Modified: freeswitch/trunk/libs/unimrcp/libs/mpf/src/mpf_codec_linear.c
==============================================================================
--- freeswitch/trunk/libs/unimrcp/libs/mpf/src/mpf_codec_linear.c (original)
+++ freeswitch/trunk/libs/unimrcp/libs/mpf/src/mpf_codec_linear.c Fri Jun 19 22:39:54 2009
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#define APR_WANT_BYTEFUNC
+#include <apr_want.h>
#include "mpf_codec.h"
/* linear 16-bit PCM (host horder) */
@@ -40,12 +42,12 @@
apr_uint32_t i;
const short *buf_in = frame_in->buffer;
short *buf_out = frame_out->buffer;
+ apr_size_t samples = frame_in->size / sizeof(short);
frame_out->size = frame_in->size;
- for(i=0; i<frame_in->size; ) {
+ for(i=0; i<samples; i++) {
buf_out[i] = htons(buf_in[i]);
- i += sizeof(short);
}
return TRUE;
@@ -56,12 +58,12 @@
apr_uint32_t i;
const short *buf_in = frame_in->buffer;
short *buf_out = frame_out->buffer;
+ apr_size_t samples = frame_in->size / sizeof(short);
frame_out->size = frame_in->size;
- for(i=0; i<frame_in->size; ) {
+ for(i=0; i<samples; i++) {
buf_out[i] = ntohs(buf_in[i]);
- i += sizeof(short);
}
return TRUE;
Modified: freeswitch/trunk/libs/unimrcp/libs/mpf/src/mpf_context.c
==============================================================================
--- freeswitch/trunk/libs/unimrcp/libs/mpf/src/mpf_context.c (original)
+++ freeswitch/trunk/libs/unimrcp/libs/mpf/src/mpf_context.c Fri Jun 19 22:39:54 2009
@@ -208,12 +208,12 @@
object = mpf_null_bridge_create(source,sink,context->pool);
}
else {
- if(rx_codec->attribs->bits_per_samples != BITS_PER_SAMPLE) {
+ if(rx_codec->vtable && rx_codec->vtable->decode) {
/* set decoder before bridge */
mpf_audio_stream_t *decoder = mpf_decoder_create(source,context->pool);
source = decoder;
}
- if(tx_codec->attribs->bits_per_samples != BITS_PER_SAMPLE) {
+ if(tx_codec->vtable && tx_codec->vtable->encode) {
/* set encoder after bridge */
mpf_audio_stream_t *encoder = mpf_encoder_create(sink,context->pool);
sink = encoder;
1
0
Author: mrene
Date: Fri Jun 19 22:37:15 2009
New Revision: 13879
Log:
Implement new config parser in mod_voicemail
Modified:
freeswitch/trunk/src/include/switch_xml_config.h
freeswitch/trunk/src/switch_xml_config.c
Modified: freeswitch/trunk/src/include/switch_xml_config.h
==============================================================================
--- freeswitch/trunk/src/include/switch_xml_config.h (original)
+++ freeswitch/trunk/src/include/switch_xml_config.h Fri Jun 19 22:37:15 2009
@@ -106,20 +106,9 @@
#define SWITCH_CONFIG_SET_ITEM(_item, _key, _type, _flags, _ptr, _defaultvalue, _data, _syntax, _helptext) switch_config_perform_set_item(&(_item), _key, _type, _flags, _ptr, (void*)(_defaultvalue), _data, NULL, _syntax, _helptext)
#define SWITCH_CONFIG_SET_ITEM_CALLBACK(_item, _key, _type, _flags, _ptr, _defaultvalue, _data, _function, _syntax, _helptext) switch_config_perform_set_item(&(_item), _key, _type, _flags, _ptr, (void*)(_defaultvalue), _data, _function, _syntax, _helptext)
-inline void switch_config_perform_set_item(switch_xml_config_item_t *item, const char *key, switch_xml_config_type_t type, int flags, void *ptr,
- const void* defaultvalue, void *data, switch_xml_config_callback_t function, const char *syntax, const char *helptext)
-{
- item->key = key;
- item->type = type;
- item->flags = flags;
- item->ptr = ptr;
- item->defaultvalue = defaultvalue;
- item->data = data;
- item->function = function;
- item->syntax = syntax;
- item->helptext = helptext;
-}
-
+SWITCH_DECLARE(void) switch_config_perform_set_item(switch_xml_config_item_t *item, const char *key, switch_xml_config_type_t type, int flags, void *ptr,
+ const void* defaultvalue, void *data, switch_xml_config_callback_t function, const char *syntax, const char *helptext);
+
/*!
* \brief Gets the int representation of an enum
* \param enum_options the switch_xml_config_enum_item_t array for this enum
Modified: freeswitch/trunk/src/switch_xml_config.c
==============================================================================
--- freeswitch/trunk/src/switch_xml_config.c (original)
+++ freeswitch/trunk/src/switch_xml_config.c Fri Jun 19 22:37:15 2009
@@ -425,6 +425,22 @@
}
}
+
+SWITCH_DECLARE(void) switch_config_perform_set_item(switch_xml_config_item_t *item, const char *key, switch_xml_config_type_t type, int flags, void *ptr,
+ const void* defaultvalue, void *data, switch_xml_config_callback_t function, const char *syntax, const char *helptext)
+{
+ item->key = key;
+ item->type = type;
+ item->flags = flags;
+ item->ptr = ptr;
+ item->defaultvalue = defaultvalue;
+ item->data = data;
+ item->function = function;
+ item->syntax = syntax;
+ item->helptext = helptext;
+}
+
+
/* For Emacs:
* Local Variables:
* mode:c
1
0
[commit] r13878 - in freeswitch/trunk/src: . include mod/applications/mod_limit
by FreeSWITCH SVN 20 Jun '09
by FreeSWITCH SVN 20 Jun '09
20 Jun '09
Author: mrene
Date: Fri Jun 19 22:32:29 2009
New Revision: 13878
Log:
Implement new config parser in mod_voicemail
Modified:
freeswitch/trunk/src/include/switch_console.h
freeswitch/trunk/src/include/switch_core.h
freeswitch/trunk/src/include/switch_xml_config.h
freeswitch/trunk/src/mod/applications/mod_limit/mod_limit.c
freeswitch/trunk/src/switch_console.c
freeswitch/trunk/src/switch_ivr_async.c
freeswitch/trunk/src/switch_xml_config.c
Modified: freeswitch/trunk/src/include/switch_console.h
==============================================================================
--- freeswitch/trunk/src/include/switch_console.h (original)
+++ freeswitch/trunk/src/include/switch_console.h Fri Jun 19 22:32:29 2009
@@ -74,6 +74,8 @@
SWITCH_DECLARE_NONSTD(switch_status_t) switch_console_stream_write(switch_stream_handle_t *handle, const char *fmt, ...) PRINTF_FUNCTION(2, 3);
#endif
+SWITCH_DECLARE(switch_status_t) switch_stream_write_file_contents(switch_stream_handle_t *stream, const char *path);
+
SWITCH_END_EXTERN_C
#endif
/* For Emacs:
Modified: freeswitch/trunk/src/include/switch_core.h
==============================================================================
--- freeswitch/trunk/src/include/switch_core.h (original)
+++ freeswitch/trunk/src/include/switch_core.h Fri Jun 19 22:32:29 2009
@@ -134,7 +134,7 @@
\param session the session to add the bug to
\param callback a callback for events
\param user_data arbitrary user data
- \param stop_time absolute time at which the bug is automatically removed
+ \param stop_time absolute time at which the bug is automatically removed (or 0)
\param flags flags to choose the stream
\param new_bug pointer to assign new bug to
\return SWITCH_STATUS_SUCCESS if the operation was a success
Modified: freeswitch/trunk/src/include/switch_xml_config.h
==============================================================================
--- freeswitch/trunk/src/include/switch_xml_config.h (original)
+++ freeswitch/trunk/src/include/switch_xml_config.h Fri Jun 19 22:32:29 2009
@@ -81,21 +81,21 @@
CONFIG_REQUIRED = (1 << 1)
} switch_config_flags_t;
-typedef switch_status_t (*switch_xml_config_callback_t)(switch_xml_config_item_t *data, switch_config_callback_type_t callback_type, switch_bool_t changed);
+typedef switch_status_t (*switch_xml_config_callback_t)(switch_xml_config_item_t *item, const char *newvalue, switch_config_callback_type_t callback_type, switch_bool_t changed);
/*!
* \brief A configuration instruction read by switch_xml_config_parse
*/
struct switch_xml_config_item {
- const char *key; /*< The key of the element, or NULL to indicate the end of the list */
+ const char *key; /*< The key of the element, or NULL to indicate the end of the list */
switch_xml_config_type_t type; /*< The type of variable */
- int flags; /*< True if the var can be changed on reload */
+ int flags; /*< True if the var can be changed on reload */
void *ptr; /*< Ptr to the var to be changed */
- const void *defaultvalue; /*< Default value */
+ const void *defaultvalue; /*< Default value */
void *data; /*< Custom data (depending on the type) */
switch_xml_config_callback_t function; /*< Callback to be called after the var is parsed */
- const char *syntax; /*< Optional syntax documentation for this setting */
- const char *helptext; /*< Optional documentation text for this setting */
+ const char *syntax; /*< Optional syntax documentation for this setting */
+ const char *helptext; /*< Optional documentation text for this setting */
};
#define SWITCH_CONFIG_ITEM(_key, _type, _flags, _ptr, _defaultvalue, _data, _syntax, _helptext) { _key, _type, _flags, _ptr, (void*)_defaultvalue, (void*)_data, NULL, _syntax, _helptext }
@@ -103,26 +103,22 @@
#define SWITCH_CONFIG_ITEM_CALLBACK(_key, _type, _flags, _ptr, _defaultvalue, _function, _functiondata, _syntax, _helptext) { _key, _type, _flags, _ptr, (void*)_defaultvalue, _functiondata, _function, _syntax, _helptext }
#define SWITCH_CONFIG_ITEM_END() { NULL, SWITCH_CONFIG_LAST, 0, NULL, NULL, NULL, NULL, NULL, NULL }
-#define SWITCH_CONFIG_SET_ITEM(_item, _key, _type, _flags, _ptr, _defaultvalue, _data, _syntax, _helptext) \
- _item.key = _key; \
- _item.type = _type; \
- _item.flags = _flags; \
- _item.ptr = _ptr; \
- _item.defaultvalue = (void*)_defaultvalue; \
- _item.data = (void*)_data; \
- _item.syntax = _syntax; \
- _item.helptext = _helptext
-
-#define SWITCH_CONFIG_SET_ITEM_CALLBACK(_item, _key, _type, _flags, _ptr, _defaultvalue, _function, _syntax, _helptext) \
- _item.key = _key; \
- _item.type = _type; \
- _item.flags = _flags; \
- _item.ptr = ptr; \
- _item.defaultvalue = (void*)_defaultvalue; \
- _item.data = (void*)_data; \
- _item.function = _function \
- _item.syntax = _syntax; \
- _item.helptext = _helptext
+#define SWITCH_CONFIG_SET_ITEM(_item, _key, _type, _flags, _ptr, _defaultvalue, _data, _syntax, _helptext) switch_config_perform_set_item(&(_item), _key, _type, _flags, _ptr, (void*)(_defaultvalue), _data, NULL, _syntax, _helptext)
+#define SWITCH_CONFIG_SET_ITEM_CALLBACK(_item, _key, _type, _flags, _ptr, _defaultvalue, _data, _function, _syntax, _helptext) switch_config_perform_set_item(&(_item), _key, _type, _flags, _ptr, (void*)(_defaultvalue), _data, _function, _syntax, _helptext)
+
+inline void switch_config_perform_set_item(switch_xml_config_item_t *item, const char *key, switch_xml_config_type_t type, int flags, void *ptr,
+ const void* defaultvalue, void *data, switch_xml_config_callback_t function, const char *syntax, const char *helptext)
+{
+ item->key = key;
+ item->type = type;
+ item->flags = flags;
+ item->ptr = ptr;
+ item->defaultvalue = defaultvalue;
+ item->data = data;
+ item->function = function;
+ item->syntax = syntax;
+ item->helptext = helptext;
+}
/*!
* \brief Gets the int representation of an enum
Modified: freeswitch/trunk/src/mod/applications/mod_limit/mod_limit.c
==============================================================================
--- freeswitch/trunk/src/mod/applications/mod_limit/mod_limit.c (original)
+++ freeswitch/trunk/src/mod/applications/mod_limit/mod_limit.c Fri Jun 19 22:32:29 2009
@@ -376,7 +376,6 @@
/* Remove handler */
switch_core_event_hook_remove_state_change(session, hash_state_handler);
-
switch_mutex_unlock(globals.limit_hash_mutex);
}
Modified: freeswitch/trunk/src/switch_console.c
==============================================================================
--- freeswitch/trunk/src/switch_console.c (original)
+++ freeswitch/trunk/src/switch_console.c Fri Jun 19 22:32:29 2009
@@ -162,6 +162,30 @@
return ret ? SWITCH_STATUS_FALSE : SWITCH_STATUS_SUCCESS;
}
+SWITCH_DECLARE(switch_status_t) switch_stream_write_file_contents(switch_stream_handle_t *stream, const char *path)
+{
+ char *dpath = NULL;
+ int fd;
+ switch_status_t status = SWITCH_STATUS_FALSE;
+
+ if (!switch_is_file_path(path)) {
+ dpath = switch_mprintf("%s%s%s", SWITCH_GLOBAL_dirs.conf_dir, SWITCH_PATH_SEPARATOR, path);
+ path = dpath;
+ }
+
+ if ((fd = open(path, O_RDONLY)) > -1) {
+ char buf[2048] = { 0 };
+ while (switch_fd_read_line(fd, buf, sizeof(buf))) {
+ stream->write_function(stream, "%s", buf);
+ }
+ close(fd);
+ status = SWITCH_STATUS_SUCCESS;
+ }
+
+ switch_safe_free(dpath);
+ return status;
+}
+
static int alias_callback(void *pArg, int argc, char **argv, char **columnNames)
{
char **r = (char **) pArg;
Modified: freeswitch/trunk/src/switch_ivr_async.c
==============================================================================
--- freeswitch/trunk/src/switch_ivr_async.c (original)
+++ freeswitch/trunk/src/switch_ivr_async.c Fri Jun 19 22:32:29 2009
@@ -392,10 +392,6 @@
return SWITCH_STATUS_GENERR;
}
- if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) {
- return SWITCH_STATUS_FALSE;
- }
-
if (limit) {
to = switch_epoch_time_now(NULL) + limit;
}
Modified: freeswitch/trunk/src/switch_xml_config.c
==============================================================================
--- freeswitch/trunk/src/switch_xml_config.c (original)
+++ freeswitch/trunk/src/switch_xml_config.c Fri Jun 19 22:32:29 2009
@@ -142,8 +142,9 @@
const char *value = switch_event_get_header(event, item->key);
switch_bool_t changed = SWITCH_FALSE;
switch_xml_config_callback_t callback = (switch_xml_config_callback_t)item->function;
+ void *ptr = item->ptr;
- switch_assert(item->ptr);
+ //switch_assert(ptr);
if (value) {
matched_count++;
@@ -162,7 +163,7 @@
case SWITCH_CONFIG_INT:
{
switch_xml_config_int_options_t *int_options = (switch_xml_config_int_options_t*)item->data;
- int *dest = (int*)item->ptr;
+ int *dest = (int*)ptr;
int intval;
if (value) {
if (switch_is_number(value)) {
@@ -229,7 +230,7 @@
if (string_options->length > 0) {
/* We have a preallocated buffer */
- char *dest = (char*)item->ptr;
+ char *dest = (char*)ptr;
if (newstring) {
if (strncasecmp(dest, newstring, string_options->length)) {
@@ -244,7 +245,7 @@
}
} else if (string_options->pool) {
/* Pool-allocated buffer */
- char **dest = (char**)item->ptr;
+ char **dest = (char**)ptr;
if (newstring) {
if (!*dest || strcmp(*dest, newstring)) {
@@ -258,7 +259,7 @@
}
} else {
/* Dynamically allocated buffer */
- char **dest = (char**)item->ptr;
+ char **dest = (char**)ptr;
if (newstring) {
if (!*dest || strcmp(*dest, newstring)) {
@@ -277,7 +278,7 @@
break;
case SWITCH_CONFIG_BOOL:
{
- switch_bool_t *dest = (switch_bool_t*)item->ptr;
+ switch_bool_t *dest = (switch_bool_t*)ptr;
switch_bool_t newval = SWITCH_FALSE;
if (value && switch_true(value)) {
@@ -305,7 +306,7 @@
case SWITCH_CONFIG_ENUM:
{
switch_xml_config_enum_item_t *enum_options = (switch_xml_config_enum_item_t*)item->data;
- int *dest = (int*)item->ptr;
+ int *dest = (int*)ptr;
int newval = 0;
switch_status_t lookup_result = SWITCH_STATUS_SUCCESS;
@@ -329,7 +330,7 @@
break;
case SWITCH_CONFIG_FLAG:
{
- int32_t *dest = (int32_t*)item->ptr;
+ int32_t *dest = (int32_t*)ptr;
int index = (int)(intptr_t)item->data;
int8_t currentval = (int8_t)!!(*dest & index);
int8_t newval = 0;
@@ -352,7 +353,7 @@
break;
case SWITCH_CONFIG_FLAGARRAY:
{
- int8_t *dest = (int8_t*)item->ptr;
+ int8_t *dest = (int8_t*)ptr;
unsigned int index = (unsigned int)(intptr_t)item->data;
int8_t newval = value ? !!switch_true(value) : (int8_t)((intptr_t)item->defaultvalue);
if (dest[index] != newval) {
@@ -368,7 +369,7 @@
}
if (callback) {
- callback(item, (reload ? CONFIG_RELOAD : CONFIG_LOAD), changed);
+ callback(item, value, (reload ? CONFIG_RELOAD : CONFIG_LOAD), changed);
}
}
@@ -418,7 +419,7 @@
}
if (callback) {
- callback(item, CONFIG_SHUTDOWN, SWITCH_FALSE);
+ callback(item, NULL, CONFIG_SHUTDOWN, SWITCH_FALSE);
}
}
1
0
[commit] r13877 - freeswitch/trunk/src/mod/event_handlers/mod_event_multicast
by FreeSWITCH SVN 20 Jun '09
by FreeSWITCH SVN 20 Jun '09
20 Jun '09
Author: mikej
Date: Fri Jun 19 22:29:55 2009
New Revision: 13877
Log:
trivial build fix (FSBUILD-174)
Modified:
freeswitch/trunk/src/mod/event_handlers/mod_event_multicast/mod_event_multicast.c
Modified: freeswitch/trunk/src/mod/event_handlers/mod_event_multicast/mod_event_multicast.c
==============================================================================
--- freeswitch/trunk/src/mod/event_handlers/mod_event_multicast/mod_event_multicast.c (original)
+++ freeswitch/trunk/src/mod/event_handlers/mod_event_multicast/mod_event_multicast.c Fri Jun 19 22:29:55 2009
@@ -178,7 +178,7 @@
switch_core_hash_destroy(&globals.event_hash);
globals.event_hash = NULL;
switch_core_hash_init(&globals.event_hash, module_pool);
- bzero(globals.event_list, SWITCH_EVENT_ALL);
+ memset(globals.event_list, 0, SWITCH_EVENT_ALL);
if (load_config() != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to reload config file\n");
} else {
@@ -221,7 +221,7 @@
len = strlen(packet) + sizeof(globals.host_hash) + strlen((char*) MAGIC);
#endif
buf = malloc(len + 1);
- bzero(buf, len + 1);
+ memset(buf, 0, len + 1);
switch_assert(buf);
memcpy(buf, &globals.host_hash, sizeof(globals.host_hash));
1
0
20 Jun '09
Author: mrene
Date: Fri Jun 19 22:29:43 2009
New Revision: 13876
Log:
Implement new config parser in mod_voicemail
Modified:
freeswitch/trunk/src/mod/applications/mod_voicemail/mod_voicemail.c
Modified: freeswitch/trunk/src/mod/applications/mod_voicemail/mod_voicemail.c
==============================================================================
--- freeswitch/trunk/src/mod/applications/mod_voicemail/mod_voicemail.c (original)
+++ freeswitch/trunk/src/mod/applications/mod_voicemail/mod_voicemail.c Fri Jun 19 22:29:43 2009
@@ -67,6 +67,9 @@
VM_DATE_NEVER
} date_location_t;
+
+#define VM_PROFILE_CONFIGITEM_COUNT 100
+
struct vm_profile {
char *name;
char *dbname;
@@ -134,6 +137,9 @@
switch_bool_t auto_playback_recordings;
switch_thread_rwlock_t *rwlock;
switch_memory_pool_t *pool;
+
+ switch_xml_config_item_t config[VM_PROFILE_CONFIGITEM_COUNT];
+ switch_xml_config_string_options_t config_str_pool;
};
typedef struct vm_profile vm_profile_t;
@@ -281,10 +287,305 @@
switch_core_destroy_memory_pool(&profile->pool);
}
+
+/* Static buffer, 2 bytes */
+static switch_xml_config_string_options_t config_dtmf = { NULL, 2, "[0-9#\\*]" };
+static switch_xml_config_string_options_t config_login_keys = { NULL, 16, "[0-9#\\*]*" };
+static switch_xml_config_string_options_t config_file_ext = { NULL, 10, NULL };
+static switch_xml_config_int_options_t config_int_0_10000 = { SWITCH_TRUE, 0, SWITCH_TRUE, 10000 };
+static switch_xml_config_int_options_t config_int_0_1000 = { SWITCH_TRUE, 0, SWITCH_TRUE, 1000 };
+static switch_xml_config_int_options_t config_int_digit_timeout = { SWITCH_TRUE, 0, SWITCH_TRUE, 30000 };
+static switch_xml_config_int_options_t config_int_max_logins = { SWITCH_TRUE, 0, SWITCH_TRUE, 10 };
+static switch_xml_config_int_options_t config_int_ht_0 = { SWITCH_TRUE, 0 };
+
+static switch_xml_config_enum_item_t config_play_date_announcement[] = {
+ { "first", VM_DATE_FIRST },
+ { "last", VM_DATE_LAST },
+ { "never", VM_DATE_NEVER },
+ { NULL, 0 }
+};
+
+
+static switch_status_t vm_config_email_callback(switch_xml_config_item_t *item, const char *newvalue, switch_config_callback_type_t callback_type, switch_bool_t changed)
+{
+ vm_profile_t *profile = (vm_profile_t*)item->data;
+
+ switch_assert(profile);
+
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "In %s newvalue=%s\n", __SWITCH_FUNC__, newvalue);
+
+ if (callback_type == CONFIG_LOAD || callback_type == CONFIG_RELOAD)
+ {
+ char *email_headers = NULL, *email_body = NULL;
+ if (newvalue) {
+ switch_stream_handle_t stream;
+ SWITCH_STANDARD_STREAM(stream);
+ if (switch_stream_write_file_contents(&stream, newvalue) == SWITCH_STATUS_SUCCESS) {
+ email_headers = switch_core_strdup(profile->pool, stream.data);
+ if ((email_body = strstr(email_headers, "\n\n"))) {
+ *email_body = '\0';
+ email_body += 2;
+ } else if ((email_body = strstr(email_headers, "\r\n\r\n"))) {
+ *email_body = '\0';
+ email_body += 4;
+ }
+ }
+
+ free(stream.data);
+ }
+
+ if (email_headers) {
+ profile->email_headers = email_headers;
+ }
+ if (email_body) {
+ profile->email_body = email_body;
+ }
+ }
+
+ return SWITCH_STATUS_SUCCESS;
+}
+
+static switch_status_t vm_config_notify_callback(switch_xml_config_item_t *item, const char *newvalue, switch_config_callback_type_t callback_type, switch_bool_t changed)
+{
+ vm_profile_t *profile = (vm_profile_t*)item->data;
+
+ switch_assert(profile);
+
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "In %s newvalue=%s\n", __SWITCH_FUNC__, newvalue);
+
+ if (callback_type == CONFIG_LOAD || callback_type == CONFIG_RELOAD)
+ {
+ char *email_headers = NULL, *email_body = NULL;
+ if (newvalue) {
+ switch_stream_handle_t stream;
+ SWITCH_STANDARD_STREAM(stream);
+ if (switch_stream_write_file_contents(&stream, newvalue) == SWITCH_STATUS_SUCCESS) {
+ email_headers = switch_core_strdup(profile->pool, stream.data);
+ if ((email_body = strstr(email_headers, "\n\n"))) {
+ *email_body = '\0';
+ email_body += 2;
+ } else if ((email_body = strstr(email_headers, "\r\n\r\n"))) {
+ *email_body = '\0';
+ email_body += 4;
+ }
+ }
+
+ free(stream.data);
+ }
+
+ if (email_headers) {
+ profile->notify_email_headers = email_headers;
+ }
+ if (email_body) {
+ profile->notify_email_body = email_body;
+ }
+ }
+
+ return SWITCH_STATUS_SUCCESS;
+}
+
+static switch_status_t vm_config_web_callback(switch_xml_config_item_t *item, const char *newvalue, switch_config_callback_type_t callback_type, switch_bool_t changed)
+{
+ vm_profile_t *profile = (vm_profile_t*)item->data;
+
+ switch_assert(profile);
+
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "In %s newvalue=%s\n", __SWITCH_FUNC__, newvalue);
+
+ if (callback_type == CONFIG_LOAD || callback_type == CONFIG_RELOAD)
+ {
+ char *web_head = NULL, *web_tail = NULL;
+ if (newvalue) {
+ switch_stream_handle_t stream;
+ SWITCH_STANDARD_STREAM(stream);
+ if (switch_stream_write_file_contents(&stream, newvalue) == SWITCH_STATUS_SUCCESS) {
+ web_head = switch_core_strdup(profile-> pool, stream.data);
+
+ if ((web_tail = strstr(web_head, "<!break>\n"))) {
+ *web_tail = '\0';
+ web_tail += 9;
+ } else if ((web_tail = strstr(web_head, "<!break>\r\n"))) {
+ *web_tail = '\0';
+ web_tail += 10;
+ }
+ }
+
+ free(stream.data);
+ }
+
+ if (web_head) {
+ profile->web_head= web_head;
+ }
+
+ if (web_tail) {
+ profile->web_tail = web_tail;
+ }
+ }
+
+ return SWITCH_STATUS_SUCCESS;
+}
+
+static switch_status_t vm_config_validate_samplerate(switch_xml_config_item_t *item, const char *newvalue, switch_config_callback_type_t callback_type, switch_bool_t changed)
+{
+ if ((callback_type == CONFIG_LOAD || callback_type == CONFIG_RELOAD) && newvalue) {
+ int val = *(int*)item->ptr;
+ if (!switch_is_valid_rate(val)) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid samplerate %s\n", newvalue);
+ return SWITCH_STATUS_FALSE;
+ }
+ }
+
+ return SWITCH_STATUS_SUCCESS;
+}
+
+/*!
+ * \brief Sets the profile's configuration instructions
+ */
+vm_profile_t *profile_set_config(vm_profile_t *profile)
+{
+ int i = 0;
+
+ profile->config_str_pool.pool = profile->pool;
+
+ /*
+ SWITCH _CONFIG_SET_ITEM(item, "key", type, flags,
+ pointer, default, options, help_syntax, help_description)
+ */
+
+ /* DTMFs */
+ SWITCH_CONFIG_SET_ITEM(profile->config[i++], "terminator-key", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
+ &profile->terminator_key, "#", &config_dtmf, NULL, NULL);
+ SWITCH_CONFIG_SET_ITEM(profile->config[i++], "play-new-messages-key", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
+ &profile->play_new_messages_key, "1", &config_dtmf, NULL, NULL);
+ SWITCH_CONFIG_SET_ITEM(profile->config[i++], "play-saved-messages-key", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
+ &profile->play_saved_messages_key, "2", &config_dtmf, NULL, NULL);
+ SWITCH_CONFIG_SET_ITEM(profile->config[i++], "login-keys", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
+ &profile->login_keys, "0", &config_login_keys, NULL, NULL);
+ SWITCH_CONFIG_SET_ITEM(profile->config[i++], "main-menu-key", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
+ &profile->main_menu_key, "0", &config_dtmf, NULL, NULL);
+ SWITCH_CONFIG_SET_ITEM(profile->config[i++], "skip-greet-key", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
+ &profile->skip_greet_key, "#", &config_dtmf, NULL, NULL);
+ SWITCH_CONFIG_SET_ITEM(profile->config[i++], "config-menu-key", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
+ &profile->config_menu_key, "5", &config_dtmf, NULL, NULL);
+ SWITCH_CONFIG_SET_ITEM(profile->config[i++], "record-greeting-key", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
+ &profile->record_greeting_key, "1", &config_dtmf, NULL, NULL);
+ SWITCH_CONFIG_SET_ITEM(profile->config[i++], "choose-greeting-key", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
+ &profile->choose_greeting_key, "2", &config_dtmf, NULL, NULL);
+ SWITCH_CONFIG_SET_ITEM(profile->config[i++], "record-name-key", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
+ &profile->record_name_key, "3", &config_dtmf, NULL, NULL);
+ SWITCH_CONFIG_SET_ITEM(profile->config[i++], "change-pass-key", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
+ &profile->change_pass_key, "6", &config_dtmf, NULL, NULL);
+ SWITCH_CONFIG_SET_ITEM(profile->config[i++], "record-file-key", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
+ &profile->record_file_key, "3", &config_dtmf, NULL, NULL);
+ SWITCH_CONFIG_SET_ITEM(profile->config[i++], "listen-file-key", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
+ &profile->listen_file_key, "1", &config_dtmf, NULL, NULL);
+ SWITCH_CONFIG_SET_ITEM(profile->config[i++], "save-file-key", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
+ &profile->save_file_key, "2", &config_dtmf, NULL, NULL);
+ SWITCH_CONFIG_SET_ITEM(profile->config[i++], "delete-file-key", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
+ &profile->delete_file_key, "7", &config_dtmf, NULL, NULL);
+ SWITCH_CONFIG_SET_ITEM(profile->config[i++], "undelete-file-key", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
+ &profile->undelete_file_key, "8", &config_dtmf, NULL, NULL);
+ SWITCH_CONFIG_SET_ITEM(profile->config[i++], "email-key", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
+ &profile->email_key, "4", &config_dtmf, NULL, NULL);
+ SWITCH_CONFIG_SET_ITEM(profile->config[i++], "callback-key", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
+ &profile->callback_key, "5", &config_dtmf, NULL, NULL);
+ SWITCH_CONFIG_SET_ITEM(profile->config[i++], "pause-key", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
+ &profile->pause_key, "0", &config_dtmf, NULL, NULL);
+ SWITCH_CONFIG_SET_ITEM(profile->config[i++], "restart-key", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
+ &profile->restart_key, "1", &config_dtmf, NULL, NULL);
+ SWITCH_CONFIG_SET_ITEM(profile->config[i++], "ff-key", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
+ &profile->ff_key, "6", &config_dtmf, NULL, NULL);
+ SWITCH_CONFIG_SET_ITEM(profile->config[i++], "rew-key", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
+ &profile->rew_key, "4", &config_dtmf, NULL, NULL);
+ SWITCH_CONFIG_SET_ITEM(profile->config[i++], "urgent-key", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
+ &profile->urgent_key, "*", &config_dtmf, NULL, NULL);
+ SWITCH_CONFIG_SET_ITEM(profile->config[i++], "operator-key", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
+ &profile->operator_key, "", &config_dtmf, NULL, NULL);
+ SWITCH_CONFIG_SET_ITEM(profile->config[i++], "operator-extension", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
+ &profile->operator_ext, "", NULL, NULL, NULL);
+ SWITCH_CONFIG_SET_ITEM(profile->config[i++], "vmain-key", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
+ &profile->vmain_key, "", &config_dtmf, NULL, NULL);
+ SWITCH_CONFIG_SET_ITEM(profile->config[i++], "vmain-extension", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
+ &profile->vmain_ext, "", &profile->config_str_pool, NULL, NULL);
+ SWITCH_CONFIG_SET_ITEM(profile->config[i++], "forward-key", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
+ &profile->forward_key, "8", &config_dtmf, NULL, NULL);
+ SWITCH_CONFIG_SET_ITEM(profile->config[i++], "prepend-key", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
+ &profile->prepend_key, "1", &config_dtmf, NULL, NULL);
+
+ /* Other settings */
+ SWITCH_CONFIG_SET_ITEM(profile->config[i++], "file-extension", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
+ &profile->file_ext, "wav", &config_file_ext, NULL, NULL);
+ SWITCH_CONFIG_SET_ITEM(profile->config[i++], "record-title", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
+ &profile->record_title, "FreeSWITCH Voicemail", &profile->config_str_pool, NULL, NULL);
+ SWITCH_CONFIG_SET_ITEM(profile->config[i++], "record-comment", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
+ &profile->record_comment, "FreeSWITCH Voicemail", &profile->config_str_pool, NULL, NULL);
+ SWITCH_CONFIG_SET_ITEM(profile->config[i++], "record-copyright", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
+ &profile->record_copyright, "http://www.freeswitch.org", &profile->config_str_pool, NULL, NULL);
+ SWITCH_CONFIG_SET_ITEM(profile->config[i++], "operator-ext", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
+ &profile->operator_ext, "", &profile->config_str_pool, NULL, NULL);
+
+ SWITCH_CONFIG_SET_ITEM(profile->config[i++], "tone-spec", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
+ &profile->tone_spec, "%(1000, 0, 640)", &profile->config_str_pool, NULL, NULL);
+ SWITCH_CONFIG_SET_ITEM(profile->config[i++], "storage-dir", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
+ &profile->storage_dir, "", &profile->config_str_pool, NULL, NULL);
+ SWITCH_CONFIG_SET_ITEM(profile->config[i++], "callback-dialplan", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
+ &profile->callback_dialplan, "XML", &profile->config_str_pool, NULL, NULL);
+ SWITCH_CONFIG_SET_ITEM(profile->config[i++], "callback-context", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
+ &profile->callback_context, "default", &profile->config_str_pool, NULL, NULL);
+
+ SWITCH_CONFIG_SET_ITEM(profile->config[i++], "notify-email-body", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
+ &profile->notify_email_body, "default", &profile->config_str_pool, NULL, NULL);
+ SWITCH_CONFIG_SET_ITEM(profile->config[i++], "notify-email-headers", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
+ &profile->notify_email_headers, "default", &profile->config_str_pool, NULL, NULL);
+
+ SWITCH_CONFIG_SET_ITEM(profile->config[i++], "play-date-announcement", SWITCH_CONFIG_ENUM, CONFIG_RELOADABLE,
+ &profile->play_date_announcement, VM_DATE_FIRST, &config_play_date_announcement, NULL, NULL);
+
+ SWITCH_CONFIG_SET_ITEM(profile->config[i++], "digit-timeout", SWITCH_CONFIG_INT, CONFIG_RELOADABLE,
+ &profile->digit_timeout, 10000, &config_int_digit_timeout, NULL, NULL);
+ SWITCH_CONFIG_SET_ITEM(profile->config[i++], "max-login-attempts", SWITCH_CONFIG_INT, CONFIG_RELOADABLE,
+ &profile->max_login_attempts, 3, &config_int_max_logins, NULL, NULL);
+ SWITCH_CONFIG_SET_ITEM(profile->config[i++], "min-record-len", SWITCH_CONFIG_INT, CONFIG_RELOADABLE,
+ &profile->min_record_len, 3, &config_int_0_10000, "seconds", NULL);
+ SWITCH_CONFIG_SET_ITEM(profile->config[i++], "max-record-len", SWITCH_CONFIG_INT, CONFIG_RELOADABLE,
+ &profile->max_record_len, 300, &config_int_0_1000, "seconds", NULL);
+ SWITCH_CONFIG_SET_ITEM(profile->config[i++], "max-retries", SWITCH_CONFIG_INT, CONFIG_RELOADABLE,
+ &profile->max_retries, 3, &config_int_ht_0, NULL, NULL);
+ SWITCH_CONFIG_SET_ITEM(profile->config[i++], "record-silence-threshold", SWITCH_CONFIG_INT, CONFIG_RELOADABLE,
+ &profile->record_threshold, 200, &config_int_0_10000, NULL, NULL);
+ SWITCH_CONFIG_SET_ITEM(profile->config[i++], "record-silence-hits", SWITCH_CONFIG_INT, CONFIG_RELOADABLE,
+ &profile->record_silence_hits, 2, &config_int_0_1000, NULL, NULL);
+ SWITCH_CONFIG_SET_ITEM_CALLBACK(profile->config[i++], "record-sample-rate", SWITCH_CONFIG_INT, CONFIG_RELOADABLE,
+ &profile->record_sample_rate, 8000, NULL, vm_config_validate_samplerate, NULL, NULL);
+
+ SWITCH_CONFIG_SET_ITEM(profile->config[i++], "email_headers", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
+ &profile->email_headers, NULL, &profile->config_str_pool, NULL, NULL);
+ SWITCH_CONFIG_SET_ITEM(profile->config[i++], "email_body", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
+ &profile->email_body, NULL, &profile->config_str_pool, NULL, NULL);
+ SWITCH_CONFIG_SET_ITEM(profile->config[i++], "email_email-from", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
+ &profile->email_from, NULL, &profile->config_str_pool, NULL, NULL);
+ SWITCH_CONFIG_SET_ITEM(profile->config[i++], "email_date-fmt", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
+ &profile->date_fmt, "%A, %B %d %Y, %I %M %p", &profile->config_str_pool, NULL, NULL);
+ SWITCH_CONFIG_SET_ITEM(profile->config[i++], "odbc-dsn", SWITCH_CONFIG_STRING, 0,
+ &profile->odbc_dsn, NULL, &profile->config_str_pool, NULL, NULL);
+ SWITCH_CONFIG_SET_ITEM_CALLBACK(profile->config[i++], "email_template-file", SWITCH_CONFIG_CUSTOM, CONFIG_RELOADABLE,
+ NULL, NULL, profile, vm_config_email_callback, NULL, NULL);
+ SWITCH_CONFIG_SET_ITEM_CALLBACK(profile->config[i++], "email_notify-template-file", SWITCH_CONFIG_CUSTOM, CONFIG_RELOADABLE,
+ NULL, NULL, profile, vm_config_notify_callback, NULL, NULL);
+ SWITCH_CONFIG_SET_ITEM_CALLBACK(profile->config[i++], "web-template-file", SWITCH_CONFIG_CUSTOM, CONFIG_RELOADABLE,
+ NULL, NULL, profile, vm_config_web_callback, NULL, NULL);
+
+ switch_assert(i < VM_PROFILE_CONFIGITEM_COUNT);
+
+ return profile;
+
+}
+
static vm_profile_t * load_profile(const char *profile_name)
{
vm_profile_t *profile = NULL;
- switch_xml_t x_profiles, x_profile, x_email, param, cfg, xml;
+ switch_xml_t x_profiles, x_profile, cfg, xml, x_email, param;
+ switch_event_t *event = NULL;
if (!(xml = switch_xml_open_cfg(global_cf, &cfg, NULL))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", global_cf);
@@ -296,388 +597,67 @@
if ((x_profile = switch_xml_find_child(x_profiles, "profile", "name", profile_name))) {
switch_memory_pool_t *pool;
- char *odbc_dsn = NULL, *odbc_user = NULL, *odbc_pass = NULL;
- char *terminator_key = "#";
- char *play_new_messages_key = "1";
- char *play_saved_messages_key = "2";
-
- char *login_keys = "0";
- char *main_menu_key = "0";
- char *skip_greet_key = "#";
- char *config_menu_key = "5";
- char *record_greeting_key = "1";
- char *choose_greeting_key = "2";
- char *record_name_key = "3";
- char *change_pass_key = "6";
-
- char *record_file_key = "3";
- char *listen_file_key = "1";
- char *save_file_key = "2";
- char *delete_file_key = "7";
- char *undelete_file_key = "8";
- char *email_key = "4";
- char *callback_key = "5";
- char *pause_key = "0";
- char *restart_key = "1";
- char *ff_key = "6";
- char *rew_key = "4";
- char *urgent_key = "*";
- char *operator_key = "";
- char *operator_ext = "";
- char *vmain_key = "";
- char *vmain_ext = "";
- char *forward_key = "8";
- char *prepend_key = "1";
- char *tone_spec = "%(1000, 0, 640)";
- char *file_ext = "wav";
- char *storage_dir = "";
- char *callback_dialplan = "XML";
- char *callback_context = "default";
- char *email_body = NULL;
- char *email_headers = NULL;
- char *notify_email_body = NULL;
- char *notify_email_headers = NULL;
- char *email_from = "";
- char *date_fmt = "%A, %B %d %Y, %I %M %p";
- date_location_t play_date_announcement = VM_DATE_FIRST;
- char *web_head = NULL;
- char *web_tail = NULL;
- uint32_t record_threshold = 200;
- uint32_t record_silence_hits = 2;
- uint32_t record_sample_rate = 0;
-
- char *record_title = "FreeSWITCH Voicemail";
- char *record_comment = "FreeSWITCH Voicemail";
- char *record_copyright = "http://www.freeswitch.org";
-
- switch_bool_t auto_playback_recordings = SWITCH_TRUE;
-
- switch_core_db_t *db;
- uint32_t timeout = 10000, max_login_attempts = 3, max_record_len = 300, min_record_len = 3, max_retries = 3;
- int x;
-
- db = NULL;
+ switch_core_db_t *db = NULL;
+ int x, count;
if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Pool Failure\n");
goto end;
}
- if (!(profile = switch_core_alloc(pool, sizeof(*profile)))) {
+ if (!(profile = switch_core_alloc(pool, sizeof(vm_profile_t)))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Alloc Failure\n");
switch_core_destroy_memory_pool(&pool);
- goto end;
+ goto end;
}
profile->pool = pool;
- switch_thread_rwlock_create(&profile->rwlock, pool);
- profile->name = switch_core_strdup(pool, profile_name);
+ profile_set_config(profile);
+
+ /* Add the params to the event structure */
+ count = switch_event_import_xml(switch_xml_child(x_profile, "param"), "name", "value", &event);
+ /* Take care of the custom config structure */
if ((x_email = switch_xml_child(x_profile, "email"))) {
if ((param = switch_xml_child(x_email, "body"))) {
- email_body = switch_core_strdup(profile->pool, param->txt);
+ switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "email_body", param->txt);
}
-
if ((param = switch_xml_child(x_email, "headers"))) {
- email_headers = switch_core_strdup(profile->pool, param->txt);
+ switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "email_headers", param->txt);
}
-
+
for (param = switch_xml_child(x_email, "param"); param; param = param->next) {
char *var, *val;
-
- var = (char *) switch_xml_attr_soft(param, "name");
- val = (char *) switch_xml_attr_soft(param, "value");
-
- if (!strcasecmp(var, "date-fmt") && !switch_strlen_zero(val)) {
- date_fmt = val;
- } else if (!strcasecmp(var, "email-from") && !switch_strlen_zero(val)) {
- email_from = val;
- } else if (!strcasecmp(var, "template-file") && !switch_strlen_zero(val)) {
- switch_stream_handle_t stream = { 0 };
- int fd;
- char *dpath = NULL;
- char *path;
-
- if (switch_is_file_path(val)) {
- path = val;
- } else {
- dpath = switch_mprintf("%s%s%s", SWITCH_GLOBAL_dirs.conf_dir, SWITCH_PATH_SEPARATOR, val);
- path = dpath;
- }
-
- if ((fd = open(path, O_RDONLY)) > -1) {
- char buf[2048];
- SWITCH_STANDARD_STREAM(stream);
- while (switch_fd_read_line(fd, buf, sizeof(buf))) {
- stream.write_function(&stream, "%s", buf);
- }
- close(fd);
- email_headers = switch_core_strdup(pool, stream.data);
- switch_safe_free(stream.data);
- if ((email_body = strstr(email_headers, "\n\n"))) {
- *email_body = '\0';
- email_body += 2;
- } else if ((email_body = strstr(email_headers, "\r\n\r\n"))) {
- *email_body = '\0';
- email_body += 4;
- }
- }
- switch_safe_free(dpath);
- } else if (!strcasecmp(var, "notify-template-file") && !switch_strlen_zero(val)) {
- switch_stream_handle_t stream = { 0 };
- int fd;
- char *dpath = NULL;
- char *path;
-
- if (switch_is_file_path(val)) {
- path = val;
- } else {
- dpath = switch_mprintf("%s%s%s", SWITCH_GLOBAL_dirs.conf_dir, SWITCH_PATH_SEPARATOR, val);
- path = dpath;
- }
-
- if ((fd = open(path, O_RDONLY)) > -1) {
- char buf[2048];
- SWITCH_STANDARD_STREAM(stream);
- while (switch_fd_read_line(fd, buf, sizeof(buf))) {
- stream.write_function(&stream, "%s", buf);
- }
- close(fd);
- notify_email_headers = switch_core_strdup(pool, stream.data);
- switch_safe_free(stream.data);
- if ((notify_email_body = strstr(notify_email_headers, "\n\n"))) {
- *notify_email_body = '\0';
- notify_email_body += 2;
- } else if ((notify_email_body = strstr(notify_email_headers, "\r\n\r\n"))) {
- *notify_email_body = '\0';
- notify_email_body += 4;
- }
- }
- switch_safe_free(dpath);
+ char buf[2048];
+
+ if ((var = (char *) switch_xml_attr_soft(param, "name")) &&
+ (val = (char *) switch_xml_attr_soft(param, "value"))) {
+ switch_snprintf(buf, 2048, "email_%s", var);
+ switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, buf, val);
}
}
}
- for (param = switch_xml_child(x_profile, "param"); param; param = param->next) {
- char *var, *val;
-
- var = (char *) switch_xml_attr_soft(param, "name");
- val = (char *) switch_xml_attr_soft(param, "value");
-
- if (!strcasecmp(var, "terminator-key") && !switch_strlen_zero(val)) {
- terminator_key = val;
- } else if (!strcasecmp(var, "web-template-file") && !switch_strlen_zero(val)) {
- switch_stream_handle_t stream = { 0 };
- int fd;
- char *dpath = NULL;
- char *path;
-
- if (switch_is_file_path(val)) {
- path = val;
- } else {
- dpath = switch_mprintf("%s%s%s", SWITCH_GLOBAL_dirs.conf_dir, SWITCH_PATH_SEPARATOR, val);
- path = dpath;
- }
+
+ if (switch_xml_config_parse_event(event, count, SWITCH_FALSE, profile->config) != SWITCH_STATUS_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to process configuration\n");
+ switch_core_destroy_memory_pool(&pool);
+ goto end;
+ }
+
+ switch_thread_rwlock_create(&profile->rwlock, pool);
+ profile->name = switch_core_strdup(pool, profile_name);
- if ((fd = open(path, O_RDONLY)) > -1) {
- char buf[2048];
- SWITCH_STANDARD_STREAM(stream);
- while (switch_fd_read_line(fd, buf, sizeof(buf))) {
- stream.write_function(&stream, "%s", buf);
- }
- close(fd);
- web_head = switch_core_strdup(pool, stream.data);
- switch_safe_free(stream.data);
-
- if ((web_tail = strstr(web_head, "<!break>\n"))) {
- *web_tail = '\0';
- web_tail += 9;
- } else if ((web_tail = strstr(web_head, "<!break>\r\n"))) {
- *web_tail = '\0';
- web_tail += 10;
- }
- }
- switch_safe_free(dpath);
- } else if (!strcasecmp(var, "play-new-messages-key") && !switch_strlen_zero(val)) {
- play_new_messages_key = val;
- } else if (!strcasecmp(var, "play-saved-messages-key") && !switch_strlen_zero(val)) {
- play_saved_messages_key = val;
- } else if (!strcasecmp(var, "login-keys") && !switch_strlen_zero(val)) {
- login_keys = val;
- } else if (!strcasecmp(var, "main-menu-key") && !switch_strlen_zero(val)) {
- main_menu_key = val;
- } else if (!strcasecmp(var, "skip-greet-key") && val && (!*val || is_dtmf(*val))) {
- skip_greet_key = val;
- } else if (!strcasecmp(var, "config-menu-key") && !switch_strlen_zero(val)) {
- config_menu_key = val;
- } else if (!strcasecmp(var, "record-greeting-key") && !switch_strlen_zero(val)) {
- record_greeting_key = val;
- } else if (!strcasecmp(var, "choose-greeting-key") && !switch_strlen_zero(val)) {
- choose_greeting_key = val;
- } else if (!strcasecmp(var, "record-name-key") && !switch_strlen_zero(val)) {
- record_name_key = val;
- } else if (!strcasecmp(var, "change-pass-key") && !switch_strlen_zero(val)) {
- change_pass_key = val;
- } else if (!strcasecmp(var, "listen-file-key") && !switch_strlen_zero(val)) {
- listen_file_key = val;
- } else if (!strcasecmp(var, "save-file-key") && !switch_strlen_zero(val)) {
- save_file_key = val;
- } else if (!strcasecmp(var, "delete-file-key") && !switch_strlen_zero(val)) {
- delete_file_key = val;
- } else if (!strcasecmp(var, "undelete-file-key") && !switch_strlen_zero(val)) {
- undelete_file_key = val;
- } else if (!strcasecmp(var, "email-key") && !switch_strlen_zero(val)) {
- email_key = val;
- } else if (!strcasecmp(var, "callback-key") && !switch_strlen_zero(val)) {
- callback_key = val;
- } else if (!strcasecmp(var, "pause-key") && !switch_strlen_zero(val)) {
- pause_key = val;
- } else if (!strcasecmp(var, "restart-key") && !switch_strlen_zero(val)) {
- restart_key = val;
- } else if (!strcasecmp(var, "ff-key") && !switch_strlen_zero(val)) {
- ff_key = val;
- } else if (!strcasecmp(var, "rew-key") && !switch_strlen_zero(val)) {
- rew_key = val;
- } else if (!strcasecmp(var, "urgent-key") && !switch_strlen_zero(val)) {
- urgent_key = val;
- } else if (!strcasecmp(var, "operator-key") && !switch_strlen_zero(val)) {
- operator_key = val;
- } else if (!strcasecmp(var, "operator-extension") && !switch_strlen_zero(val)) {
- operator_ext = val;
- } else if (!strcasecmp(var, "vmain-key") && !switch_strlen_zero(val)) {
- vmain_key = val;
- } else if (!strcasecmp(var, "forward-key") && !switch_strlen_zero(val)) {
- forward_key = val;
- } else if (!strcasecmp(var, "prepend-key") && !switch_strlen_zero(val)) {
- prepend_key = val;
- } else if (!strcasecmp(var, "vmain-extension") && !switch_strlen_zero(val)) {
- vmain_ext = val;
- } else if (!strcasecmp(var, "storage-dir") && !switch_strlen_zero(val)) {
- storage_dir = val;
- } else if (!strcasecmp(var, "callback-dialplan") && !switch_strlen_zero(val)) {
- callback_dialplan = val;
- } else if (!strcasecmp(var, "callback-context") && !switch_strlen_zero(val)) {
- callback_context = val;
- } else if (!strcasecmp(var, "file-extension") && !switch_strlen_zero(val)) {
- file_ext = val;
- } else if (!strcasecmp(var, "play-date-announcement") && !switch_strlen_zero(val)) {
- if (!strcmp("last", val)) {
- play_date_announcement = VM_DATE_LAST;
- } else if (!strcmp("never", val)) {
- play_date_announcement = VM_DATE_NEVER;
- }
- } else if (!strcasecmp(var, "record-title") && !switch_strlen_zero(val)) {
- record_title = val;
- } else if (!strcasecmp(var, "record-comment") && !switch_strlen_zero(val)) {
- record_comment = val;
- } else if (!strcasecmp(var, "record-copyright") && !switch_strlen_zero(val)) {
- record_copyright = val;
- } else if (!strcasecmp(var, "record-silence-threshold")) {
- int tmp = 0;
- if (!switch_strlen_zero(val)) {
- tmp = atoi(val);
- }
- if (tmp >= 0 && tmp <= 10000) {
- record_threshold = tmp;
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid threshold value [%s] must be between 0 and 10000 ms\n", val);
- }
- } else if (!strcasecmp(var, "record-sample-rate")) {
- int tmp = 0;
- if (!switch_strlen_zero(val)) {
- tmp = atoi(val);
- }
- if (switch_is_valid_rate(tmp)) {
- record_sample_rate = tmp;
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid samplerate %s\n", val);
- }
- } else if (!strcasecmp(var, "record-silence-hits")) {
- int tmp = 0;
- if (!switch_strlen_zero(val)) {
- tmp = atoi(val);
- }
- if (tmp >= 0 && tmp <= 1000) {
- record_silence_hits = tmp;
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid threshold value [%s] must be between 0 and 1000 ms\n", val);
- }
- } else if (!strcasecmp(var, "tone-spec") && !switch_strlen_zero(val)) {
- tone_spec = val;
- } else if (!strcasecmp(var, "digit-timeout")) {
- int tmp = 0;
- if (!switch_strlen_zero(val)) {
- tmp = atoi(val);
- }
- if (tmp >= 1000 && tmp <= 30000) {
- timeout = tmp;
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid timeout value [%s] must be between 1000 and 30000 ms\n", val);
- }
- } else if (!strcasecmp(var, "max-login-attempts")) {
- int tmp = 0;
- if (!switch_strlen_zero(val)) {
- tmp = atoi(val);
- }
- if (tmp > 0 && tmp < 11) {
- max_login_attempts = tmp;
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid attempts [%s] must be between 1 and 10 ms\n", val);
- }
- } else if (!strcasecmp(var, "min-record-len")) {
- int tmp = 0;
- if (!switch_strlen_zero(val)) {
- tmp = atoi(val);
- }
- if (tmp > 0 && tmp < 10000) {
- min_record_len = tmp;
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid record length [%s] must be between 1 and 10000s\n", val);
- }
- } else if (!strcasecmp(var, "max-record-len")) {
- int tmp = 0;
- if (!switch_strlen_zero(val)) {
- tmp = atoi(val);
+ if (!switch_strlen_zero(profile->odbc_dsn)) {
+ if ((profile->odbc_user = strchr(profile->odbc_dsn, ':'))) {
+ *(profile->odbc_user++) = '\0';
+ if ((profile->odbc_pass = strchr(profile->odbc_user, ':'))) {
+ *(profile->odbc_pass++) = '\0';
}
- if (tmp > 0 && tmp < 10000) {
- max_record_len = tmp;
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid record length [%s] must be between 1 and 10000s\n", val);
- }
- } else if (!strcasecmp(var, "max-retries")) {
- int tmp = 0;
- if (!switch_strlen_zero(val)) {
- tmp = atoi(val);
- }
- if (tmp > 0) {
- max_retries = tmp;
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid max-retires value [%s] must be higher than 0\n", val);
- }
- } else if (!strcasecmp(var, "odbc-dsn") && !switch_strlen_zero(val)) {
-#ifdef SWITCH_HAVE_ODBC
- odbc_dsn = switch_core_strdup(profile->pool, val);
- if ((odbc_user = strchr(odbc_dsn, ':'))) {
- *odbc_user++ = '\0';
- if ((odbc_pass = strchr(odbc_user, ':'))) {
- *odbc_pass++ = '\0';
- }
- }
-#else
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ODBC IS NOT AVAILABLE!\n");
-#endif
- } else if (!strcasecmp(var, "auto-playback-recordings")){
- auto_playback_recordings = switch_true(val);
}
}
- if (!switch_strlen_zero(odbc_dsn) && !switch_strlen_zero(odbc_user) && !switch_strlen_zero(odbc_pass)) {
- profile->odbc_dsn = odbc_dsn;
- profile->odbc_user = odbc_user;
- profile->odbc_pass = odbc_pass;
- } else {
- profile->dbname = switch_core_sprintf(profile->pool, "voicemail_%s", profile_name);
- }
+ profile->dbname = switch_core_sprintf(profile->pool, "voicemail_%s", profile_name);
if (profile->odbc_dsn) {
#ifdef SWITCH_HAVE_ODBC
if (!(profile->master_odbc = switch_odbc_handle_new(profile->odbc_dsn, profile->odbc_user, profile->odbc_pass))) {
@@ -770,70 +750,8 @@
switch_core_db_close(db);
}
- profile->web_head = web_head;
- profile->web_tail = web_tail;
- profile->email_body = email_body;
- profile->email_headers = email_headers;
- if (notify_email_headers) {
- profile->notify_email_body = notify_email_body;
- profile->notify_email_headers = notify_email_headers;
- } else {
- profile->notify_email_body = email_body;
- profile->notify_email_headers = email_headers;
- }
- profile->email_from = switch_core_strdup(profile->pool, email_from);
- profile->date_fmt = switch_core_strdup(profile->pool, date_fmt);
- profile->play_date_announcement = play_date_announcement;
-
- profile->digit_timeout = timeout;
- profile->max_login_attempts = max_login_attempts;
- profile->min_record_len = min_record_len;
- profile->max_record_len = max_record_len;
- profile->max_retries = max_retries;
- *profile->terminator_key = *terminator_key;
- *profile->play_new_messages_key = *play_new_messages_key;
- *profile->play_saved_messages_key = *play_saved_messages_key;
- switch_set_string(profile->login_keys, login_keys);
- *profile->main_menu_key = *main_menu_key;
- *profile->skip_greet_key = *skip_greet_key;
- *profile->config_menu_key = *config_menu_key;
- *profile->record_greeting_key = *record_greeting_key;
- *profile->choose_greeting_key = *choose_greeting_key;
- *profile->record_name_key = *record_name_key;
- *profile->change_pass_key = *change_pass_key;
- *profile->record_file_key = *record_file_key;
- *profile->listen_file_key = *listen_file_key;
- *profile->save_file_key = *save_file_key;
- *profile->delete_file_key = *delete_file_key;
- *profile->undelete_file_key = *undelete_file_key;
- *profile->email_key = *email_key;
- *profile->callback_key = *callback_key;
- *profile->pause_key = *pause_key;
- *profile->restart_key = *restart_key;
- *profile->ff_key = *ff_key;
- *profile->rew_key = *rew_key;
- *profile->urgent_key = *urgent_key;
- *profile->operator_key = *operator_key;
- *profile->vmain_key = *vmain_key;
- *profile->forward_key = *forward_key;
- *profile->prepend_key = *prepend_key;
- profile->record_threshold = record_threshold;
- profile->record_silence_hits = record_silence_hits;
- profile->record_sample_rate = record_sample_rate;
- profile->auto_playback_recordings = auto_playback_recordings;
- profile->operator_ext = switch_core_strdup(profile->pool, operator_ext);
- profile->vmain_ext = switch_core_strdup(profile->pool, vmain_ext);
- profile->storage_dir = switch_core_strdup(profile->pool, storage_dir);
- profile->tone_spec = switch_core_strdup(profile->pool, tone_spec);
- profile->callback_dialplan = switch_core_strdup(profile->pool, callback_dialplan);
- profile->callback_context = switch_core_strdup(profile->pool, callback_context);
- profile->record_title = switch_core_strdup(profile->pool, record_title);
- profile->record_comment = switch_core_strdup(profile->pool, record_comment);
- profile->record_copyright = switch_core_strdup(profile->pool, record_copyright);
- switch_copy_string(profile->file_ext, file_ext, sizeof(profile->file_ext));
switch_mutex_init(&profile->mutex, SWITCH_MUTEX_NESTED, profile->pool);
-
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Added Profile %s\n", profile->name);
switch_core_hash_insert(globals.profile_hash, profile->name, profile);
}
@@ -850,7 +768,7 @@
static vm_profile_t * get_profile(const char *profile_name)
{
- vm_profile_t *profile;
+ vm_profile_t *profile = NULL;
switch_mutex_lock(globals.mutex);
if (!(profile = switch_core_hash_find(globals.profile_hash, profile_name))) {
@@ -893,7 +811,7 @@
load_profile(switch_xml_attr_soft(x_profile, "name"));
}
}
- switch_mutex_unlock(globals.mutex);
+ switch_mutex_unlock(globals.mutex);
switch_xml_free(xml);
return SWITCH_STATUS_SUCCESS;
@@ -3287,7 +3205,7 @@
/* Kept for backwards-compatibility */
switch_hash_index_t *hi;
switch_mutex_lock(globals.mutex);
- for (hi = switch_hash_first(NULL, globals.profile_hash); hi; hi = switch_hash_next(hi)) {
+ if ((hi = switch_hash_first(NULL, globals.profile_hash))) {
void *val;
switch_hash_this(hi, NULL, NULL, &val);
profile = (vm_profile_t *) val;
1
0