[Freeswitch-svn] [commit] r10917 - in freeswitch/trunk/src: . include mod/applications/mod_commands mod/applications/mod_dptools mod/applications/mod_voicemail mod/endpoints/mod_sofia mod/xml_int/mod_xml_rpc

FreeSWITCH SVN anthm at freeswitch.org
Tue Dec 23 09:36:51 PST 2008


Author: anthm
Date: Tue Dec 23 12:36:50 2008
New Revision: 10917

Log:
add group concept

Modified:
   freeswitch/trunk/src/include/switch_xml.h
   freeswitch/trunk/src/mod/applications/mod_commands/mod_commands.c
   freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c
   freeswitch/trunk/src/mod/applications/mod_voicemail/mod_voicemail.c
   freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_reg.c
   freeswitch/trunk/src/mod/xml_int/mod_xml_rpc/mod_xml_rpc.c
   freeswitch/trunk/src/switch_ivr.c
   freeswitch/trunk/src/switch_xml.c

Modified: freeswitch/trunk/src/include/switch_xml.h
==============================================================================
--- freeswitch/trunk/src/include/switch_xml.h	(original)
+++ freeswitch/trunk/src/include/switch_xml.h	Tue Dec 23 12:36:50 2008
@@ -142,6 +142,7 @@
 ///\param value the value
 ///\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_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
 ///\ if not found
@@ -334,11 +335,20 @@
 												  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_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,
 													   const char *user_name,
 													   const char *domain_name,
 													   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
 ///\param file_path the name of the config section e.g. modules.conf

Modified: freeswitch/trunk/src/mod/applications/mod_commands/mod_commands.c
==============================================================================
--- freeswitch/trunk/src/mod/applications/mod_commands/mod_commands.c	(original)
+++ freeswitch/trunk/src/mod/applications/mod_commands/mod_commands.c	Tue Dec 23 12:36:50 2008
@@ -77,6 +77,245 @@
 	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_xml_t x_domain, xml = NULL, x_user = NULL, x_param, x_params;
@@ -111,7 +350,7 @@
 	switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "type", type);
 	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")) {
 			const char *attr = switch_xml_attr_soft(x_user, key);
 			stream->write_function(stream, "%s", attr);
@@ -201,7 +440,7 @@
 		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";
 		goto end;
 	}
@@ -2940,6 +3179,9 @@
 	switch_api_interface_t *commands_api_interface;
 	*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, "md5", "md5", md5_function, "<data>");
 	SWITCH_ADD_API(commands_api_interface, "hupall", "hupall", hupall_api_function, "<cause> [<var> <value>]");

Modified: freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c
==============================================================================
--- freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c	(original)
+++ freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c	Tue Dec 23 12:36:50 2008
@@ -2002,6 +2002,108 @@
 	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 */
 switch_endpoint_interface_t *user_endpoint_interface;
 static switch_call_cause_t user_outgoing_channel(switch_core_session_t *session,
@@ -2017,7 +2119,7 @@
 												 switch_caller_profile_t *outbound_profile,
 												 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;
 	const char *dest = NULL;
 	static switch_call_cause_t cause = SWITCH_CAUSE_NONE;
@@ -2030,20 +2132,24 @@
 
 	user = strdup(outbound_profile->destination_number);
 
-	if (!user)
-		goto done;
+	if (!user) goto done;
 
-	if (!(domain = strchr(user, '@'))) {
+	if ((domain = strchr(user, '@'))) {
+		*domain++ = '\0';
+	} else {
+		domain = switch_core_get_variable("domain");
+	}
+	
+	if (!domain) {
 		goto done;
 	}
-
-	*domain++ = '\0';
+	
 
 	switch_event_create(&params, SWITCH_EVENT_REQUEST_PARAMS);
 	switch_assert(params);
 	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);
 		cause = SWITCH_CAUSE_SUBSCRIBER_ABSENT;
 		goto done;
@@ -2061,6 +2167,18 @@
 		}
 	}
 
+	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"))) {
 		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");
@@ -2107,6 +2225,9 @@
 				switch_event_dup(&event, var_event);
 				switch_event_del_header(event, "dialer_user");
 				switch_event_del_header(event, "dialer_domain");
+				if ((var = switch_event_get_header(var_event, SWITCH_CALL_TIMEOUT_VARIABLE))) {
+					timelimit = atoi(var);
+				}
 			} else {
 				switch_event_create(&event, SWITCH_EVENT_REQUEST_PARAMS);
 				switch_assert(event);
@@ -2318,6 +2439,10 @@
 	error_endpoint_interface->interface_name = "error";
 	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->interface_name = "user";
 	user_endpoint_interface->io_routines = &user_io_routines;

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	Tue Dec 23 12:36:50 2008
@@ -1888,7 +1888,7 @@
 					switch_channel_event_set_data(channel, params);
 					
 					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);
 					}
 
@@ -1981,7 +1981,7 @@
 					
 					
 					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);
 						ok = 0;
 					}
@@ -2679,7 +2679,7 @@
 		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"),
-								   &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"))) {
 				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");

Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_reg.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_reg.c	(original)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_reg.c	Tue Dec 23 12:36:50 2008
@@ -1394,7 +1394,7 @@
 	const char *a1_hash = NULL;
 	char *sql;
 	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 *domain_name = NULL;
 	switch_event_t *params = NULL;
@@ -1529,7 +1529,7 @@
 	}
 
 	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"
 						  "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"
@@ -1545,6 +1545,9 @@
 
 	dparams = switch_xml_child(domain, "params");
 	uparams = switch_xml_child(user, "params");
+	if (group) {
+		gparams = switch_xml_child(group, "params");
+	}
 
 	if (!(dparams || uparams)) {
 		ret = AUTH_OK;
@@ -1575,6 +1578,30 @@
 		}
 	}
 
+	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) {
 		for (param = switch_xml_child(uparams, "param"); param; param = param->next) {
 			const char *var = switch_xml_attr_soft(param, "name");
@@ -1670,7 +1697,7 @@
 			switch_event_create(v_event, SWITCH_EVENT_REQUEST_PARAMS);
 		}
 		if (v_event && *v_event) {
-			switch_xml_t xparams[2];
+			switch_xml_t xparams[3];
 			int i = 0;
 
 			switch_event_add_header_string(*v_event, SWITCH_STACK_BOTTOM, "sip_mailbox", mailbox);
@@ -1684,11 +1711,15 @@
 				xparams[i++] = dparams;
 			}
 
+			if (group && (gparams = switch_xml_child(group, "variables"))) {
+				xparams[i++] = gparams;
+			}
+
 			if ((uparams = switch_xml_child(user, "variables"))) {
 				xparams[i++] = uparams;
 			}
 
-			if (dparams || uparams) {
+			if (i <= 3) {
 				int j = 0;
 
 				for (j = 0; j < i; j++) {

Modified: freeswitch/trunk/src/mod/xml_int/mod_xml_rpc/mod_xml_rpc.c
==============================================================================
--- freeswitch/trunk/src/mod/xml_int/mod_xml_rpc/mod_xml_rpc.c	(original)
+++ freeswitch/trunk/src/mod/xml_int/mod_xml_rpc/mod_xml_rpc.c	Tue Dec 23 12:36:50 2008
@@ -206,7 +206,7 @@
 				switch_assert(params);
 				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);
 					goto fail;
 				}

Modified: freeswitch/trunk/src/switch_ivr.c
==============================================================================
--- freeswitch/trunk/src/switch_ivr.c	(original)
+++ freeswitch/trunk/src/switch_ivr.c	Tue Dec 23 12:36:50 2008
@@ -1920,7 +1920,7 @@
 
 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;
 	switch_channel_t *channel = switch_core_session_get_channel(session);
 	switch_status_t status = SWITCH_STATUS_FALSE;
@@ -1937,7 +1937,7 @@
 
 	*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);
 		goto done;
 	}
@@ -1959,6 +1959,17 @@
 		}
 	}
 
+	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"))) {
 		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");

Modified: freeswitch/trunk/src/switch_xml.c
==============================================================================
--- freeswitch/trunk/src/switch_xml.c	(original)
+++ freeswitch/trunk/src/switch_xml.c	Tue Dec 23 12:36:50 2008
@@ -300,6 +300,62 @@
 	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
 SWITCH_DECLARE(switch_xml_t) switch_xml_child(switch_xml_t xml, const char *name)
 {
@@ -1528,6 +1584,93 @@
 	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,
 													   const char *user_name,
 													   const char *domain_name, 
@@ -1535,11 +1678,13 @@
 													   switch_xml_t *root,
 													   switch_xml_t *domain,
 													   switch_xml_t *user,
+													   switch_xml_t *ingroup,
 													   switch_event_t *params)
 {
 	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;
 	*user = NULL;
 	*domain = NULL;
@@ -1570,26 +1715,27 @@
 	
 	status = SWITCH_STATUS_FALSE;
 
-	if (ip) {
-		if ((*user = switch_xml_find_child(*domain, "user", "ip", ip))) {
-			status = SWITCH_STATUS_SUCCESS;
-			goto end;
-		}
-	} 
+	if (params != my_params) {
+		search_params = params;
+	}
 
-	if (user_name) {
-		if (params != my_params && switch_event_get_header(params, (char *) "mailbox")) {
-			if ((*user = switch_xml_find_child(*domain, "user", "mailbox", user_name))) {
-				status = SWITCH_STATUS_SUCCESS;
-				goto end;
+	if ((groups = switch_xml_child(*domain, "groups"))) {
+		for (group = switch_xml_child(groups, "group"); group; group = group->next) {
+			if ((users = switch_xml_child(group, "users"))) {
+				if ((status = find_user_in_tag(users, ip, user_name, key, params, user)) == SWITCH_STATUS_SUCCESS) {
+					if (ingroup) {
+						*ingroup = group;
+					}
+					break;
+				}
 			}
 		}
+	}
 
-		if ((*user = switch_xml_find_child(*domain, "user", key, user_name))) {
-			status = SWITCH_STATUS_SUCCESS;
-			goto end;
-		}
+	if (status != SWITCH_STATUS_SUCCESS) {
+		status = find_user_in_tag(*domain, ip, user_name, key, params, user);
 	}
+	
 
  end:
 



More information about the Freeswitch-svn mailing list