提交 ed100f44 authored 作者: Anthony Minessale's avatar Anthony Minessale

add group concept

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@10917 d0543943-73ff-0310-b7d9-9358b9ac24b2
上级 d5100bc5
...@@ -142,6 +142,7 @@ SWITCH_DECLARE(switch_xml_t) switch_xml_child(switch_xml_t xml, const char *name ...@@ -142,6 +142,7 @@ SWITCH_DECLARE(switch_xml_t) switch_xml_child(switch_xml_t xml, const char *name
///\param value the value ///\param value the value
///\return an xml node or NULL ///\return an xml node or NULL
SWITCH_DECLARE(switch_xml_t) switch_xml_find_child(switch_xml_t node, const char *childname, const char *attrname, const char *value); SWITCH_DECLARE(switch_xml_t) switch_xml_find_child(switch_xml_t node, const char *childname, const char *attrname, const char *value);
SWITCH_DECLARE(switch_xml_t) switch_xml_find_child_multi(switch_xml_t node, const char *childname, ...);
///\brief returns the next tag of the same name in the same section and depth or NULL ///\brief returns the next tag of the same name in the same section and depth or NULL
///\ if not found ///\ if not found
...@@ -334,11 +335,20 @@ SWITCH_DECLARE(switch_status_t) switch_xml_locate(const char *section, ...@@ -334,11 +335,20 @@ SWITCH_DECLARE(switch_status_t) switch_xml_locate(const char *section,
switch_event_t *params); switch_event_t *params);
SWITCH_DECLARE(switch_status_t) switch_xml_locate_domain(const char *domain_name, switch_event_t *params, switch_xml_t *root, switch_xml_t *domain); SWITCH_DECLARE(switch_status_t) switch_xml_locate_domain(const char *domain_name, switch_event_t *params, switch_xml_t *root, switch_xml_t *domain);
SWITCH_DECLARE(switch_status_t) switch_xml_locate_group(const char *group_name,
const char *domain_name,
switch_xml_t *root,
switch_xml_t *domain,
switch_xml_t *group,
switch_event_t *params);
SWITCH_DECLARE(switch_status_t) switch_xml_locate_user(const char *key, SWITCH_DECLARE(switch_status_t) switch_xml_locate_user(const char *key,
const char *user_name, const char *user_name,
const char *domain_name, const char *domain_name,
const char *ip, const char *ip,
switch_xml_t *root, switch_xml_t *domain, switch_xml_t *user, switch_event_t *params); switch_xml_t *root, switch_xml_t *domain, switch_xml_t *user, switch_xml_t *ingroup,
switch_event_t *params);
///\brief open a config in the core registry ///\brief open a config in the core registry
///\param file_path the name of the config section e.g. modules.conf ///\param file_path the name of the config section e.g. modules.conf
......
...@@ -77,6 +77,245 @@ SWITCH_STANDARD_API(time_test_function) ...@@ -77,6 +77,245 @@ SWITCH_STANDARD_API(time_test_function)
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
} }
SWITCH_STANDARD_API(group_call_function)
{
char *domain;
char *group_name = NULL;
char *flags;
int ok = 0;
switch_channel_t *channel = NULL;
char *fp = NULL;
const char *call_delim = ",";
if (switch_strlen_zero(cmd)) {
goto end;
}
if (session) {
channel = switch_core_session_get_channel(session);
}
group_name = strdup(cmd);
switch_assert(group_name);
if ((flags = strchr(group_name, '+'))) {
*flags++ = '\0';
for (fp = flags; fp && *fp; fp++) {
switch(*fp) {
case 'F':
call_delim = "|";
break;
case 'A':
call_delim = ",";
break;
default:
break;
}
}
}
domain = strchr(group_name, '@');
if (domain) {
*domain++ = '\0';
} else {
domain = switch_core_get_variable("domain");
}
if (!switch_strlen_zero(domain)) {
switch_xml_t xml, x_domain, x_group;
switch_event_t *params;
switch_stream_handle_t dstream = { 0 };
SWITCH_STANDARD_STREAM(dstream);
switch_event_create(&params, SWITCH_EVENT_REQUEST_PARAMS);
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "group", group_name);
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "domain", domain);
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "action", "group_call");
if (switch_xml_locate_group(group_name, domain, &xml, &x_domain, &x_group, params) == SWITCH_STATUS_SUCCESS) {
switch_xml_t x_user, x_users, x_param, x_params;
if ((x_users = switch_xml_child(x_group, "users"))) {
ok++;
for(x_user = switch_xml_child(x_users, "user"); x_user; x_user = x_user->next) {
const char *id = switch_xml_attr_soft(x_user, "id");
const char *dest = NULL;
char *d_dest = NULL;
if ((x_params = switch_xml_child(x_domain, "params"))) {
for (x_param = switch_xml_child(x_params, "param"); x_param; x_param = x_param->next) {
const char *var = switch_xml_attr(x_param, "name");
const char *val = switch_xml_attr(x_param, "value");
if (!strcasecmp(var, "group-dial-string")) {
dest = val;
break;
}
if (!strcasecmp(var, "dial-string")) {
dest = val;
}
}
}
if ((x_params = switch_xml_child(x_group, "params"))) {
for (x_param = switch_xml_child(x_params, "param"); x_param; x_param = x_param->next) {
const char *var = switch_xml_attr(x_param, "name");
const char *val = switch_xml_attr(x_param, "value");
if (!strcasecmp(var, "group-dial-string")) {
dest = val;
break;
}
if (!strcasecmp(var, "dial-string")) {
dest = val;
}
}
}
if ((x_params = switch_xml_child(x_user, "params"))) {
for (x_param = switch_xml_child(x_params, "param"); x_param; x_param = x_param->next) {
const char *var = switch_xml_attr(x_param, "name");
const char *val = switch_xml_attr(x_param, "value");
if (!strcasecmp(var, "group-dial-string")) {
dest = val;
break;
}
if (!strcasecmp(var, "dial-string")) {
dest = val;
}
}
}
if (dest) {
if (channel) {
switch_channel_set_variable(channel, "dialed_group", group_name);
switch_channel_set_variable(channel, "dialed_user", id);
switch_channel_set_variable(channel, "dialed_domain", domain);
d_dest = switch_channel_expand_variables(channel, dest);
} else {
switch_event_del_header(params, "dialed_user");
switch_event_del_header(params, "dialed_group");
switch_event_del_header(params, "dialed_domain");
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "dialed_user", id);
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "dialed_group", group_name);
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "dialed_domain", domain);
d_dest = switch_event_expand_headers(params, dest);
}
} else {
d_dest = switch_mprintf("user/%s@%s", id, domain);
}
if (d_dest) {
if (!switch_stristr("error/", d_dest)) {
dstream.write_function(&dstream, "%s%s", d_dest, call_delim);
}
if (d_dest != dest) {
free(d_dest);
}
}
}
if (ok && dstream.data) {
char *data = (char *) dstream.data;
char c = end_of(data);
char *p;
if (c == ',' || c == '|') {
end_of(data) = '\0';
}
for (p = data; p && *p; p++) {
if (*p == '{') {
*p = '[';
} else if (*p == '}') {
*p = ']';
}
}
stream->write_function(stream, "%s", data);
free(dstream.data);
} else {
ok = 0;
}
}
switch_xml_free(xml);
}
switch_event_destroy(&params);
}
end:
switch_safe_free(group_name);
if (!ok) {
stream->write_function(stream, "error/NO_ROUTE_DESTINATION");
}
return SWITCH_STATUS_SUCCESS;
}
SWITCH_STANDARD_API(in_group_function)
{
switch_xml_t x_domain, xml = NULL, x_user = NULL, x_group;
int argc;
char *mydata = NULL, *argv[2], *user, *domain;
char delim = ',';
switch_event_t *params = NULL;
const char *rval = "false";
char *group;
if (switch_strlen_zero(cmd) || !(mydata = strdup(cmd))) {
goto end;
}
if ((argc = switch_separate_string(mydata, delim, argv, (sizeof(argv) / sizeof(argv[0])))) < 2) {
goto end;
}
user = argv[0];
group = argv[1];
if ((domain = strchr(user, '@'))) {
*domain++ = '\0';
} else {
domain = switch_core_get_variable("domain");
}
switch_event_create(&params, SWITCH_EVENT_REQUEST_PARAMS);
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "user", user);
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "domain", domain);
if (switch_xml_locate_group(group, domain, &xml, &x_domain, &x_group, params) == SWITCH_STATUS_SUCCESS) {
switch_xml_t x_users;
if ((x_users = switch_xml_child(x_group, "users"))) {
if ((x_user = switch_xml_find_child(x_users, "user", "id", user))) {
rval = "true";
}
}
}
end:
stream->write_function(stream, "%s", rval);
switch_xml_free(xml);
free(mydata);
switch_event_destroy(&params);
return SWITCH_STATUS_SUCCESS;
}
SWITCH_STANDARD_API(user_data_function) SWITCH_STANDARD_API(user_data_function)
{ {
switch_xml_t x_domain, xml = NULL, x_user = NULL, x_param, x_params; switch_xml_t x_domain, xml = NULL, x_user = NULL, x_param, x_params;
...@@ -111,7 +350,7 @@ SWITCH_STANDARD_API(user_data_function) ...@@ -111,7 +350,7 @@ SWITCH_STANDARD_API(user_data_function)
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "type", type); switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "type", type);
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "key", key); switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "key", key);
if (key && type && switch_xml_locate_user("id", user, domain, NULL, &xml, &x_domain, &x_user, params) == SWITCH_STATUS_SUCCESS) { if (key && type && switch_xml_locate_user("id", user, domain, NULL, &xml, &x_domain, &x_user, NULL, params) == SWITCH_STATUS_SUCCESS) {
if (!strcmp(type, "attr")) { if (!strcmp(type, "attr")) {
const char *attr = switch_xml_attr_soft(x_user, key); const char *attr = switch_xml_attr_soft(x_user, key);
stream->write_function(stream, "%s", attr); stream->write_function(stream, "%s", attr);
...@@ -201,7 +440,7 @@ static switch_status_t _find_user(const char *cmd, switch_core_session_t *sessio ...@@ -201,7 +440,7 @@ static switch_status_t _find_user(const char *cmd, switch_core_session_t *sessio
goto end; goto end;
} }
if (switch_xml_locate_user(key, user, domain, NULL, &xml, &x_domain, &x_user, NULL) != SWITCH_STATUS_SUCCESS) { if (switch_xml_locate_user(key, user, domain, NULL, &xml, &x_domain, &x_user, NULL, NULL) != SWITCH_STATUS_SUCCESS) {
err = "can't find user"; err = "can't find user";
goto end; goto end;
} }
...@@ -2940,6 +3179,9 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load) ...@@ -2940,6 +3179,9 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load)
switch_api_interface_t *commands_api_interface; switch_api_interface_t *commands_api_interface;
*module_interface = switch_loadable_module_create_module_interface(pool, modname); *module_interface = switch_loadable_module_create_module_interface(pool, modname);
SWITCH_ADD_API(commands_api_interface, "group_call", "Generate a dial string to call a group", group_call_function, "<group>[@<domain>]");
SWITCH_ADD_API(commands_api_interface, "in_group", "determine if a user is in a group", in_group_function, "<user>[@<domain>] <group_name>");
SWITCH_ADD_API(commands_api_interface, "uuid_flush_dtmf", "Flush dtmf on a given uuid", uuid_flush_dtmf_function, "<uuid>"); SWITCH_ADD_API(commands_api_interface, "uuid_flush_dtmf", "Flush dtmf on a given uuid", uuid_flush_dtmf_function, "<uuid>");
SWITCH_ADD_API(commands_api_interface, "md5", "md5", md5_function, "<data>"); SWITCH_ADD_API(commands_api_interface, "md5", "md5", md5_function, "<data>");
SWITCH_ADD_API(commands_api_interface, "hupall", "hupall", hupall_api_function, "<cause> [<var> <value>]"); SWITCH_ADD_API(commands_api_interface, "hupall", "hupall", hupall_api_function, "<cause> [<var> <value>]");
......
...@@ -2002,6 +2002,108 @@ static switch_call_cause_t error_outgoing_channel(switch_core_session_t *session ...@@ -2002,6 +2002,108 @@ static switch_call_cause_t error_outgoing_channel(switch_core_session_t *session
return cause; return cause;
} }
/* fake chan_group */
switch_endpoint_interface_t *group_endpoint_interface;
static switch_call_cause_t group_outgoing_channel(switch_core_session_t *session,
switch_event_t *var_event,
switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags);
switch_io_routines_t group_io_routines = {
/*.outgoing_channel */ group_outgoing_channel
};
static switch_call_cause_t group_outgoing_channel(switch_core_session_t *session,
switch_event_t *var_event,
switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags)
{
char *group;
switch_call_cause_t cause;
char *template = NULL, *dest = NULL;
switch_originate_flag_t myflags = SOF_NONE;
char *cid_name_override = NULL;
char *cid_num_override = NULL;
const char *var;
unsigned int timelimit = 60;
char *domain = NULL;
switch_channel_t *new_channel = NULL;
group = strdup(outbound_profile->destination_number);
if (!group) goto done;
if ((domain = strchr(group, '@'))) {
*domain++ = '\0';
} else {
domain = switch_core_get_variable("domain");
}
if (!domain) {
goto done;
}
template = switch_mprintf("${group_call(%s@%s)}", group, domain);
if (session) {
switch_channel_t *channel = switch_core_session_get_channel(session);
dest = switch_channel_expand_variables(channel, template);
if ((var = switch_channel_get_variable(channel, SWITCH_CALL_TIMEOUT_VARIABLE))) {
timelimit = atoi(var);
}
} else if (var_event) {
dest = switch_event_expand_headers(var_event, template);
}
if (!dest) {
goto done;
}
if (var_event) {
cid_name_override = switch_event_get_header(var_event, "origination_caller_id_name");
cid_num_override = switch_event_get_header(var_event, "origination_caller_id_number");
if ((var = switch_event_get_header(var_event, SWITCH_CALL_TIMEOUT_VARIABLE))) {
timelimit = atoi(var);
}
}
if ((flags & SOF_FORKED_DIAL)) {
myflags |= SOF_NOBLOCK;
}
if (switch_ivr_originate(session, new_session, &cause, dest, timelimit, NULL,
cid_name_override, cid_num_override, NULL, var_event, myflags) == SWITCH_STATUS_SUCCESS) {
const char *context;
switch_caller_profile_t *cp;
new_channel = switch_core_session_get_channel(*new_session);
if ((context = switch_channel_get_variable(new_channel, "group_context"))) {
if ((cp = switch_channel_get_caller_profile(new_channel))) {
cp->context = switch_core_strdup(cp->pool, context);
}
}
switch_core_session_rwunlock(*new_session);
}
done:
if (dest && dest != template) {
switch_safe_free(dest);
}
switch_safe_free(template);
if (cause == SWITCH_CAUSE_NONE) {
cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
}
return cause;
}
/* fake chan_user */ /* fake chan_user */
switch_endpoint_interface_t *user_endpoint_interface; switch_endpoint_interface_t *user_endpoint_interface;
static switch_call_cause_t user_outgoing_channel(switch_core_session_t *session, static switch_call_cause_t user_outgoing_channel(switch_core_session_t *session,
...@@ -2017,7 +2119,7 @@ static switch_call_cause_t user_outgoing_channel(switch_core_session_t *session, ...@@ -2017,7 +2119,7 @@ static switch_call_cause_t user_outgoing_channel(switch_core_session_t *session,
switch_caller_profile_t *outbound_profile, switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags) switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags)
{ {
switch_xml_t x_domain = NULL, xml = NULL, x_user = NULL, x_param, x_params; switch_xml_t x_domain = NULL, xml = NULL, x_user = NULL, x_group = NULL, x_param, x_params;
char *user = NULL, *domain = NULL; char *user = NULL, *domain = NULL;
const char *dest = NULL; const char *dest = NULL;
static switch_call_cause_t cause = SWITCH_CAUSE_NONE; static switch_call_cause_t cause = SWITCH_CAUSE_NONE;
...@@ -2030,20 +2132,24 @@ static switch_call_cause_t user_outgoing_channel(switch_core_session_t *session, ...@@ -2030,20 +2132,24 @@ static switch_call_cause_t user_outgoing_channel(switch_core_session_t *session,
user = strdup(outbound_profile->destination_number); user = strdup(outbound_profile->destination_number);
if (!user) if (!user) goto done;
goto done;
if (!(domain = strchr(user, '@'))) { if ((domain = strchr(user, '@'))) {
*domain++ = '\0';
} else {
domain = switch_core_get_variable("domain");
}
if (!domain) {
goto done; goto done;
} }
*domain++ = '\0';
switch_event_create(&params, SWITCH_EVENT_REQUEST_PARAMS); switch_event_create(&params, SWITCH_EVENT_REQUEST_PARAMS);
switch_assert(params); switch_assert(params);
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "as_channel", "true"); switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "as_channel", "true");
if (switch_xml_locate_user("id", user, domain, NULL, &xml, &x_domain, &x_user, params) != SWITCH_STATUS_SUCCESS) { if (switch_xml_locate_user("id", user, domain, NULL, &xml, &x_domain, &x_user, &x_group, params) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Can't find user [%s@%s]\n", user, domain); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Can't find user [%s@%s]\n", user, domain);
cause = SWITCH_CAUSE_SUBSCRIBER_ABSENT; cause = SWITCH_CAUSE_SUBSCRIBER_ABSENT;
goto done; goto done;
...@@ -2061,6 +2167,18 @@ static switch_call_cause_t user_outgoing_channel(switch_core_session_t *session, ...@@ -2061,6 +2167,18 @@ static switch_call_cause_t user_outgoing_channel(switch_core_session_t *session,
} }
} }
if ((x_params = switch_xml_child(x_group, "params"))) {
for (x_param = switch_xml_child(x_params, "param"); x_param; x_param = x_param->next) {
const char *var = switch_xml_attr(x_param, "name");
const char *val = switch_xml_attr(x_param, "value");
if (!strcasecmp(var, "dial-string")) {
dest = val;
break;
}
}
}
if ((x_params = switch_xml_child(x_user, "params"))) { if ((x_params = switch_xml_child(x_user, "params"))) {
for (x_param = switch_xml_child(x_params, "param"); x_param; x_param = x_param->next) { for (x_param = switch_xml_child(x_params, "param"); x_param; x_param = x_param->next) {
const char *var = switch_xml_attr(x_param, "name"); const char *var = switch_xml_attr(x_param, "name");
...@@ -2107,6 +2225,9 @@ static switch_call_cause_t user_outgoing_channel(switch_core_session_t *session, ...@@ -2107,6 +2225,9 @@ static switch_call_cause_t user_outgoing_channel(switch_core_session_t *session,
switch_event_dup(&event, var_event); switch_event_dup(&event, var_event);
switch_event_del_header(event, "dialer_user"); switch_event_del_header(event, "dialer_user");
switch_event_del_header(event, "dialer_domain"); switch_event_del_header(event, "dialer_domain");
if ((var = switch_event_get_header(var_event, SWITCH_CALL_TIMEOUT_VARIABLE))) {
timelimit = atoi(var);
}
} else { } else {
switch_event_create(&event, SWITCH_EVENT_REQUEST_PARAMS); switch_event_create(&event, SWITCH_EVENT_REQUEST_PARAMS);
switch_assert(event); switch_assert(event);
...@@ -2318,6 +2439,10 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load) ...@@ -2318,6 +2439,10 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
error_endpoint_interface->interface_name = "error"; error_endpoint_interface->interface_name = "error";
error_endpoint_interface->io_routines = &error_io_routines; error_endpoint_interface->io_routines = &error_io_routines;
group_endpoint_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_ENDPOINT_INTERFACE);
group_endpoint_interface->interface_name = "group";
group_endpoint_interface->io_routines = &group_io_routines;
user_endpoint_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_ENDPOINT_INTERFACE); user_endpoint_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_ENDPOINT_INTERFACE);
user_endpoint_interface->interface_name = "user"; user_endpoint_interface->interface_name = "user";
user_endpoint_interface->io_routines = &user_io_routines; user_endpoint_interface->io_routines = &user_io_routines;
......
...@@ -1888,7 +1888,7 @@ static void voicemail_check_main(switch_core_session_t *session, const char *pro ...@@ -1888,7 +1888,7 @@ static void voicemail_check_main(switch_core_session_t *session, const char *pro
switch_channel_event_set_data(channel, params); switch_channel_event_set_data(channel, params);
if (switch_xml_locate_user("id", myid, domain_name, switch_channel_get_variable(channel, "network_addr"), if (switch_xml_locate_user("id", myid, domain_name, switch_channel_get_variable(channel, "network_addr"),
&xx_domain_root, &xx_domain, &xx_user, params) == SWITCH_STATUS_SUCCESS) { &xx_domain_root, &xx_domain, &xx_user, NULL, params) == SWITCH_STATUS_SUCCESS) {
switch_xml_free(xx_domain_root); switch_xml_free(xx_domain_root);
} }
...@@ -1981,7 +1981,7 @@ static void voicemail_check_main(switch_core_session_t *session, const char *pro ...@@ -1981,7 +1981,7 @@ static void voicemail_check_main(switch_core_session_t *session, const char *pro
if (switch_xml_locate_user("id", myid, domain_name, switch_channel_get_variable(channel, "network_addr"), if (switch_xml_locate_user("id", myid, domain_name, switch_channel_get_variable(channel, "network_addr"),
&x_domain_root, &x_domain, &x_user, params) != SWITCH_STATUS_SUCCESS) { &x_domain_root, &x_domain, &x_user, NULL, params) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Can't find user [%s@%s]\n", myid, domain_name); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Can't find user [%s@%s]\n", myid, domain_name);
ok = 0; ok = 0;
} }
...@@ -2679,7 +2679,7 @@ static switch_status_t voicemail_leave_main(switch_core_session_t *session, cons ...@@ -2679,7 +2679,7 @@ static switch_status_t voicemail_leave_main(switch_core_session_t *session, cons
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "mailbox", id); switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "mailbox", id);
if (switch_xml_locate_user("id", id, domain_name, switch_channel_get_variable(channel, "network_addr"), if (switch_xml_locate_user("id", id, domain_name, switch_channel_get_variable(channel, "network_addr"),
&x_domain_root, &x_domain, &x_user, params) == SWITCH_STATUS_SUCCESS) { &x_domain_root, &x_domain, &x_user, NULL, params) == SWITCH_STATUS_SUCCESS) {
if ((x_params = switch_xml_child(x_user, "params"))) { if ((x_params = switch_xml_child(x_user, "params"))) {
for (x_param = switch_xml_child(x_params, "param"); x_param; x_param = x_param->next) { for (x_param = switch_xml_child(x_params, "param"); x_param; x_param = x_param->next) {
const char *var = switch_xml_attr_soft(x_param, "name"); const char *var = switch_xml_attr_soft(x_param, "name");
......
...@@ -1394,7 +1394,7 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile, sip_authorization_t co ...@@ -1394,7 +1394,7 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile, sip_authorization_t co
const char *a1_hash = NULL; const char *a1_hash = NULL;
char *sql; char *sql;
char *mailbox = NULL; char *mailbox = NULL;
switch_xml_t domain, xml = NULL, user, param, uparams, dparams; switch_xml_t domain, xml = NULL, user, param, uparams, dparams, group, gparams = NULL;
char hexdigest[2 * SU_MD5_DIGEST_SIZE + 1] = ""; char hexdigest[2 * SU_MD5_DIGEST_SIZE + 1] = "";
char *domain_name = NULL; char *domain_name = NULL;
switch_event_t *params = NULL; switch_event_t *params = NULL;
...@@ -1529,7 +1529,7 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile, sip_authorization_t co ...@@ -1529,7 +1529,7 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile, sip_authorization_t co
} }
if (switch_xml_locate_user("id", switch_strlen_zero(username) ? "nobody" : username, if (switch_xml_locate_user("id", switch_strlen_zero(username) ? "nobody" : username,
domain_name, ip, &xml, &domain, &user, params) != SWITCH_STATUS_SUCCESS) { domain_name, ip, &xml, &domain, &user, &group, params) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Can't find user [%s@%s]\n" switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Can't find user [%s@%s]\n"
"You must define a domain called '%s' in your directory and add a user with the id=\"%s\" attribute\n" "You must define a domain called '%s' in your directory and add a user with the id=\"%s\" attribute\n"
"and you must configure your device to use the proper domain in it's authentication credentials.\n" "and you must configure your device to use the proper domain in it's authentication credentials.\n"
...@@ -1545,6 +1545,9 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile, sip_authorization_t co ...@@ -1545,6 +1545,9 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile, sip_authorization_t co
dparams = switch_xml_child(domain, "params"); dparams = switch_xml_child(domain, "params");
uparams = switch_xml_child(user, "params"); uparams = switch_xml_child(user, "params");
if (group) {
gparams = switch_xml_child(group, "params");
}
if (!(dparams || uparams)) { if (!(dparams || uparams)) {
ret = AUTH_OK; ret = AUTH_OK;
...@@ -1575,6 +1578,30 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile, sip_authorization_t co ...@@ -1575,6 +1578,30 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile, sip_authorization_t co
} }
} }
if (gparams) {
for (param = switch_xml_child(gparams, "param"); param; param = param->next) {
const char *var = switch_xml_attr_soft(param, "name");
const char *val = switch_xml_attr_soft(param, "value");
if (!strcasecmp(var, "sip-forbid-register") && switch_true(val)) {
ret = AUTH_FORBIDDEN;
goto end;
}
if (!strcasecmp(var, "password")) {
passwd = val;
}
if (!strcasecmp(var, "auth-acl")) {
auth_acl = val;
}
if (!strcasecmp(var, "a1-hash")) {
a1_hash = val;
}
}
}
if (uparams) { if (uparams) {
for (param = switch_xml_child(uparams, "param"); param; param = param->next) { for (param = switch_xml_child(uparams, "param"); param; param = param->next) {
const char *var = switch_xml_attr_soft(param, "name"); const char *var = switch_xml_attr_soft(param, "name");
...@@ -1670,7 +1697,7 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile, sip_authorization_t co ...@@ -1670,7 +1697,7 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile, sip_authorization_t co
switch_event_create(v_event, SWITCH_EVENT_REQUEST_PARAMS); switch_event_create(v_event, SWITCH_EVENT_REQUEST_PARAMS);
} }
if (v_event && *v_event) { if (v_event && *v_event) {
switch_xml_t xparams[2]; switch_xml_t xparams[3];
int i = 0; int i = 0;
switch_event_add_header_string(*v_event, SWITCH_STACK_BOTTOM, "sip_mailbox", mailbox); switch_event_add_header_string(*v_event, SWITCH_STACK_BOTTOM, "sip_mailbox", mailbox);
...@@ -1684,11 +1711,15 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile, sip_authorization_t co ...@@ -1684,11 +1711,15 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile, sip_authorization_t co
xparams[i++] = dparams; xparams[i++] = dparams;
} }
if (group && (gparams = switch_xml_child(group, "variables"))) {
xparams[i++] = gparams;
}
if ((uparams = switch_xml_child(user, "variables"))) { if ((uparams = switch_xml_child(user, "variables"))) {
xparams[i++] = uparams; xparams[i++] = uparams;
} }
if (dparams || uparams) { if (i <= 3) {
int j = 0; int j = 0;
for (j = 0; j < i; j++) { for (j = 0; j < i; j++) {
......
...@@ -206,7 +206,7 @@ static abyss_bool http_directory_auth(TSession * r, char *domain_name) ...@@ -206,7 +206,7 @@ static abyss_bool http_directory_auth(TSession * r, char *domain_name)
switch_assert(params); switch_assert(params);
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "mailbox", "check"); switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "mailbox", "check");
if (switch_xml_locate_user("id", user, domain_name, NULL, &x_domain_root, &x_domain, &x_user, params) != SWITCH_STATUS_SUCCESS) { if (switch_xml_locate_user("id", user, domain_name, NULL, &x_domain_root, &x_domain, &x_user, NULL, params) != SWITCH_STATUS_SUCCESS) {
switch_event_destroy(&params); switch_event_destroy(&params);
goto fail; goto fail;
} }
......
...@@ -1920,7 +1920,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_say(switch_core_session_t *session, c ...@@ -1920,7 +1920,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_say(switch_core_session_t *session, c
SWITCH_DECLARE(switch_status_t) switch_ivr_set_user(switch_core_session_t *session, const char *data) SWITCH_DECLARE(switch_status_t) switch_ivr_set_user(switch_core_session_t *session, const char *data)
{ {
switch_xml_t x_domain, xml = NULL, x_user, x_param, x_params; switch_xml_t x_domain, xml = NULL, x_user, x_param, x_params, x_group = NULL;
char *user, *mailbox, *domain; char *user, *mailbox, *domain;
switch_channel_t *channel = switch_core_session_get_channel(session); switch_channel_t *channel = switch_core_session_get_channel(session);
switch_status_t status = SWITCH_STATUS_FALSE; switch_status_t status = SWITCH_STATUS_FALSE;
...@@ -1937,7 +1937,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_set_user(switch_core_session_t *sessi ...@@ -1937,7 +1937,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_set_user(switch_core_session_t *sessi
*domain++ = '\0'; *domain++ = '\0';
if (switch_xml_locate_user("id", user, domain, NULL, &xml, &x_domain, &x_user, NULL) != SWITCH_STATUS_SUCCESS) { if (switch_xml_locate_user("id", user, domain, NULL, &xml, &x_domain, &x_user, &x_group, NULL) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "can't find user [%s@%s]\n", user, domain); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "can't find user [%s@%s]\n", user, domain);
goto done; goto done;
} }
...@@ -1959,6 +1959,17 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_set_user(switch_core_session_t *sessi ...@@ -1959,6 +1959,17 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_set_user(switch_core_session_t *sessi
} }
} }
if (x_group && (x_params = switch_xml_child(x_group, "variables"))) {
for (x_param = switch_xml_child(x_params, "variable"); x_param; x_param = x_param->next) {
const char *var = switch_xml_attr(x_param, "name");
const char *val = switch_xml_attr(x_param, "value");
if (var && val) {
switch_channel_set_variable(channel, var, val);
}
}
}
if ((x_params = switch_xml_child(x_user, "variables"))) { if ((x_params = switch_xml_child(x_user, "variables"))) {
for (x_param = switch_xml_child(x_params, "variable"); x_param; x_param = x_param->next) { for (x_param = switch_xml_child(x_params, "variable"); x_param; x_param = x_param->next) {
const char *var = switch_xml_attr(x_param, "name"); const char *var = switch_xml_attr(x_param, "name");
......
...@@ -300,6 +300,62 @@ SWITCH_DECLARE(switch_xml_t) switch_xml_find_child(switch_xml_t node, const char ...@@ -300,6 +300,62 @@ SWITCH_DECLARE(switch_xml_t) switch_xml_find_child(switch_xml_t node, const char
return p; return p;
} }
SWITCH_DECLARE(switch_xml_t) switch_xml_find_child_multi(switch_xml_t node, const char *childname, ...)
{
switch_xml_t p = NULL;
const char *names[256] = {0};
const char *vals[256] = {0};
int x, i = 0;
va_list ap;
const char *attrname, *value;
va_start(ap, childname);
while(i < 255) {
if ((attrname = va_arg(ap, const char *))) {
value = va_arg(ap, const char *);
}
if (attrname && value) {
names[i] = attrname;
vals[i] = value;
} else {
break;
}
i++;
}
va_end(ap);
if (!(childname && i)) {
return node;
}
for (p = switch_xml_child(node, childname); p; p = p->next) {
for (x = 0; x < i; x++) {
if (names[x] && vals[x]) {
const char *aname = switch_xml_attr(p, names[x]);
if (aname) {
if (*vals[x] == '!') {
const char *sval = vals[x] + 1;
if (sval && strcasecmp(aname, sval)) {
goto done;
}
} else {
if (!strcasecmp(aname, vals[x])) {
goto done;
}
}
}
}
}
}
done:
return p;
}
// returns the first child tag with the given name or NULL if not found // returns the first child tag with the given name or NULL if not found
SWITCH_DECLARE(switch_xml_t) switch_xml_child(switch_xml_t xml, const char *name) SWITCH_DECLARE(switch_xml_t) switch_xml_child(switch_xml_t xml, const char *name)
{ {
...@@ -1528,6 +1584,93 @@ SWITCH_DECLARE(switch_status_t) switch_xml_locate_domain(const char *domain_name ...@@ -1528,6 +1584,93 @@ SWITCH_DECLARE(switch_status_t) switch_xml_locate_domain(const char *domain_name
return status; return status;
} }
SWITCH_DECLARE(switch_status_t) switch_xml_locate_group(const char *group_name,
const char *domain_name,
switch_xml_t *root,
switch_xml_t *domain,
switch_xml_t *group,
switch_event_t *params)
{
switch_status_t status = SWITCH_STATUS_FALSE;
switch_event_t *my_params = NULL;
switch_xml_t groups = NULL;
*root = NULL;
*group = NULL;
*domain = NULL;
if (!params) {
switch_event_create(&my_params, SWITCH_EVENT_REQUEST_PARAMS);
switch_assert(my_params);
params = my_params;
}
if (group_name) {
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "group_name", group_name);
}
if (domain_name) {
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "domain", domain_name);
}
if ((status = switch_xml_locate_domain(domain_name, params, root, domain)) != SWITCH_STATUS_SUCCESS) {
goto end;
}
status = SWITCH_STATUS_FALSE;
if ((groups = switch_xml_child(*domain, "groups"))) {
if ((*group = switch_xml_find_child(groups, "group", "name", group_name))) {
status = SWITCH_STATUS_SUCCESS;
}
}
end:
if (my_params) {
switch_event_destroy(&my_params);
}
return status;
}
static switch_status_t find_user_in_tag(switch_xml_t tag, const char *ip, const char *user_name, const char *key, switch_event_t *params, switch_xml_t *user)
{
const char *type = "!pointer";
const char *val;
if (params && (val = switch_event_get_header(params, "user_type"))) {
if (!strcasecmp(val, "any")) {
type = NULL;
} else {
type = val;
}
}
if (ip) {
if ((*user = switch_xml_find_child_multi(tag, "user", "ip", ip, "type", type, NULL))) {
return SWITCH_STATUS_SUCCESS;
}
}
if (user_name) {
if (params && switch_event_get_header(params, (char *) "mailbox")) {
if ((*user = switch_xml_find_child_multi(tag, "user", "mailbox", user_name, "type", type, NULL))) {
return SWITCH_STATUS_SUCCESS;
}
}
if ((*user = switch_xml_find_child_multi(tag, "user", key, user_name, "type", type, NULL))) {
return SWITCH_STATUS_SUCCESS;
}
}
return SWITCH_STATUS_FALSE;
}
SWITCH_DECLARE(switch_status_t) switch_xml_locate_user(const char *key, SWITCH_DECLARE(switch_status_t) switch_xml_locate_user(const char *key,
const char *user_name, const char *user_name,
const char *domain_name, const char *domain_name,
...@@ -1535,11 +1678,13 @@ SWITCH_DECLARE(switch_status_t) switch_xml_locate_user(const char *key, ...@@ -1535,11 +1678,13 @@ SWITCH_DECLARE(switch_status_t) switch_xml_locate_user(const char *key,
switch_xml_t *root, switch_xml_t *root,
switch_xml_t *domain, switch_xml_t *domain,
switch_xml_t *user, switch_xml_t *user,
switch_xml_t *ingroup,
switch_event_t *params) switch_event_t *params)
{ {
switch_status_t status = SWITCH_STATUS_FALSE; switch_status_t status = SWITCH_STATUS_FALSE;
switch_event_t *my_params = NULL; switch_event_t *my_params = NULL, *search_params = NULL;
switch_xml_t group = NULL, groups = NULL, users = NULL;
*root = NULL; *root = NULL;
*user = NULL; *user = NULL;
*domain = NULL; *domain = NULL;
...@@ -1570,26 +1715,27 @@ SWITCH_DECLARE(switch_status_t) switch_xml_locate_user(const char *key, ...@@ -1570,26 +1715,27 @@ SWITCH_DECLARE(switch_status_t) switch_xml_locate_user(const char *key,
status = SWITCH_STATUS_FALSE; status = SWITCH_STATUS_FALSE;
if (ip) { if (params != my_params) {
if ((*user = switch_xml_find_child(*domain, "user", "ip", ip))) { search_params = params;
status = SWITCH_STATUS_SUCCESS; }
goto end;
}
}
if (user_name) { if ((groups = switch_xml_child(*domain, "groups"))) {
if (params != my_params && switch_event_get_header(params, (char *) "mailbox")) { for (group = switch_xml_child(groups, "group"); group; group = group->next) {
if ((*user = switch_xml_find_child(*domain, "user", "mailbox", user_name))) { if ((users = switch_xml_child(group, "users"))) {
status = SWITCH_STATUS_SUCCESS; if ((status = find_user_in_tag(users, ip, user_name, key, params, user)) == SWITCH_STATUS_SUCCESS) {
goto end; if (ingroup) {
*ingroup = group;
}
break;
}
} }
} }
}
if ((*user = switch_xml_find_child(*domain, "user", key, user_name))) { if (status != SWITCH_STATUS_SUCCESS) {
status = SWITCH_STATUS_SUCCESS; status = find_user_in_tag(*domain, ip, user_name, key, params, user);
goto end;
}
} }
end: end:
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论