[asterisk-commits] trunk r28168 - in /trunk: channels/chan_sip.c configs/sip.conf.sample

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Thu May 18 07:07:47 MST 2006


Author: file
Date: Thu May 18 09:07:46 2006
New Revision: 28168

URL: http://svn.digium.com/view/asterisk?rev=28168&view=rev
Log:
Allow contexts in regexten so that extensions can be added to multiple contexts when peer registers (issue #6869 reported by and created by Marquis)

Modified:
    trunk/channels/chan_sip.c
    trunk/configs/sip.conf.sample

Modified: trunk/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/trunk/channels/chan_sip.c?rev=28168&r1=28167&r2=28168&view=diff
==============================================================================
--- trunk/channels/chan_sip.c (original)
+++ trunk/channels/chan_sip.c Thu May 18 09:07:46 2006
@@ -1942,17 +1942,30 @@
 static void register_peer_exten(struct sip_peer *peer, int onoff)
 {
 	char multi[256];
-	char *stringp, *ext;
+	char *stringp, *ext, *context;
 	if (!ast_strlen_zero(global_regcontext)) {
 
 		ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
 		stringp = multi;
 		while((ext = strsep(&stringp, "&"))) {
+ 			if((context = strchr(ext, '@'))) {
+				context++;
+				if (!ast_context_find(context)) {
+					ast_log(LOG_WARNING, "Context %s must exist in regcontext!\n", context);
+					continue;
+				}
+				ext = strsep(&ext, "@");
+				if (onoff)
+					ast_add_extension(context, 1, ext, 1, NULL, NULL, "Noop",					  ast_strdup(peer->name), free, "SIP");
+				else
+					ast_context_remove_extension(context, ext, 1, NULL);
+			} else {
 			if (onoff)
 				ast_add_extension(global_regcontext, 1, ext, 1, NULL, NULL, "Noop",
 						  ast_strdup(peer->name), free, "SIP");
 			else
 				ast_context_remove_extension(global_regcontext, ext, 1, NULL);
+			}
 		}
 	}
 }
@@ -8103,6 +8116,32 @@
 		return "invite";
 	else
 		return "no";
+}
+
+/*! \brief cleanup_stale_contexts:  Destroy disused contexts between reloads
+	Only used in reload_config so the code for regcontext doesn't get ugly
+*/
+static void cleanup_stale_contexts(char *new, char *old)
+{
+	char *oldcontext, *newcontext, *stalecontext, *stringp, newlist[AST_MAX_CONTEXT];
+
+	while ((oldcontext = strsep(&old, "&"))) {
+		stalecontext = '\0';
+		ast_copy_string(newlist, new, sizeof(newlist));
+		stringp = newlist;
+		while ((newcontext = strsep(&stringp, "&"))) {
+			if (strcmp(newcontext, oldcontext) == 0) {
+				/* This is not the context you're looking for */
+				stalecontext = '\0';
+				break;
+			} else if (strcmp(newcontext, oldcontext)) {
+				stalecontext = oldcontext;
+			}
+			
+		}
+		if (stalecontext)
+			ast_context_destroy(ast_context_find(stalecontext), "SIP");
+	}
 }
 
 /*! \brief  sip_prune_realtime: Remove temporary realtime objects from memory (CLI) */
@@ -13197,7 +13236,8 @@
 	struct sip_peer *peer;
 	struct sip_user *user;
 	struct ast_hostent ahp;
-	char *cat;
+	char *cat, *stringp, *context, *oldregcontext;
+	char newcontexts[AST_MAX_CONTEXT], oldcontexts[AST_MAX_CONTEXT];
 	struct hostent *hp;
 	int format;
 	char iabuf[INET_ADDRSTRLEN];
@@ -13216,6 +13256,10 @@
 		return -1;
 	}
 	
+	/* Initialize copy of current global_regcontext for later use in removing stale contexts */
+	ast_copy_string(oldcontexts, global_regcontext, sizeof(oldcontexts));
+	oldregcontext = oldcontexts;
+
 	/* Clear all flags before setting default values */
 	/* Preserve debugging settings for console */
 	ast_copy_flags(&debugflag, &global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
@@ -13361,10 +13405,16 @@
 		} else if (!strcasecmp(v->name, "language")) {
 			ast_copy_string(default_language, v->value, sizeof(default_language));
 		} else if (!strcasecmp(v->name, "regcontext")) {
+			ast_copy_string(newcontexts, v->value, sizeof(newcontexts));
+			stringp = newcontexts;
+			/* Let's remove any contexts that are no longer defined in regcontext */
+			cleanup_stale_contexts(stringp, oldregcontext);
+			/* Create contexts if they don't exist already */
+			while ((context = strsep(&stringp, "&"))) {
+				if (!ast_context_find(context))
+					ast_context_create(NULL, context,"SIP");
+			}
 			ast_copy_string(global_regcontext, v->value, sizeof(global_regcontext));
-			/* Create context if it doesn't exist already */
-			if (!ast_context_find(global_regcontext))
-				ast_context_create(NULL, global_regcontext, "SIP");
 		} else if (!strcasecmp(v->name, "callerid")) {
 			ast_copy_string(default_callerid, v->value, sizeof(default_callerid));
 		} else if (!strcasecmp(v->name, "fromdomain")) {

Modified: trunk/configs/sip.conf.sample
URL: http://svn.digium.com/view/asterisk/trunk/configs/sip.conf.sample?rev=28168&r1=28167&r2=28168&view=diff
==============================================================================
--- trunk/configs/sip.conf.sample (original)
+++ trunk/configs/sip.conf.sample Thu May 18 09:07:46 2006
@@ -139,9 +139,12 @@
 ;
 ; If regcontext is specified, Asterisk will dynamically create and destroy a
 ; NoOp priority 1 extension for a given peer who registers or unregisters with
-; us.  The actual extension is the 'regexten' parameter of the registering
-; peer or its name if 'regexten' is not provided.  More than one regexten may
-; be supplied if they are separated by '&'.  Patterns may be used in regexten.
+; us.  Multiple contexts may be specified by separating them with '&'. The 
+; actual extension is the 'regexten' parameter of the registering peer or its
+; name if 'regexten' is not provided.  If more than one context is provided,
+; the context must be specified within regexten by appending the desired
+; context after '@'.  More than one regexten may be supplied if they are 
+; separated by '&'.  Patterns may be used in regexten.
 ;
 ;regcontext=sipregistrations
 ;



More information about the asterisk-commits mailing list