[Asterisk-Dev] Evaluating trailing numbers in extensions.conf

Harald Milz hm at seneca.muc.de
Wed Mar 16 00:14:15 MST 2005


Eric Liedtke <e at musinghalfwit.org> wrote:
> I had a similiar situation , I had my local * server registering to
> another, and if I left off the part where he has /sip then all calls
> came in destined for the s extension. I solved this by simply adding my
> number at the end of the registration request, then ${EXTEN} actually
> contained the dialed number I wanted to use.

I'm adding a personal answer to Eric here. Maybe my point was not fully
understood yet, or maybe I did not explain it right. 

On Tue, Mar 15, 2005 at 04:43:00PM -0600, Eric Liedtke wrote:
> What do you mean when you refer to the "trailing numbers"? I see below
> that it matched on the 4981XXXXX301 extension which forwarded the call

081XX-XXX301 is my official sipgate DID (you get only one DID per
person at sipgate). I would like to be able to append a 2-digit number
like 11 to access my ISDN PBX directly. Sipgate (as it seems, SER)
actually appends these additional digits to the SIP address (i.e. they
send sip:4981XXXXX30111 in this case). But if I use /4981XXXXX301 (or any
other string) in the register line, only this exact character string is
sent to the extension, and nothing else, so the additional digits are not
visible within the extension. If I don't append an explicit extension
to the register string, the call is routed to the "s" extension, which
does not see any called number either because EXTEN will be "s". (at
least in all the experiments I made)

As it seems there is no official way to access the full SIP address -
that we are sent in the To: header - with EXTEN, MACRO_EXTEN or anything
else. There are only very few places within the source code where it is
available, and this is where I added my CALLEDNUM patch.

Would the maintainers please consider this patch for inclusion in the CVS?
It doesn't break anything as far as I can see but it helps a lot of people
in similar situations. I'll attach it here for convenience. 

You use the patch as follows. 

sip.conf:

[general]
context = from-sip
register => 7509301:XXXXXX at sipgate.de/sip


extensions.conf:

[from-sip]
; the official DID is 12 digits but we clip only 11 digits off to 
; catch the case where people only dial the official DID
; this avoids an empty string sent to [to-isdn]
exten => sip,1,Goto(to-isdn,${CALLEDNUM:11},1)

[to-isdn]
; official DID (or rather, its LSD) is routed to ISDN PBX extension #11
exten => 1,1,Dial(Zap/g1/11,30,r)
; calls containing additional digits are routed to the
; matching ISDN PBX extensions 11 through 18. Driver: zaphfc
exten => _11[1-8],1,Dial(Zap/g1/${EXTEN:1},30,r)
exten => _11[1-8],2,Congestion
exten => _11[1-8],102,Busy

It's as easy as that. I have yet to determine what happens if people call
me via SIP.  For now, I just want to replace PSTN calls. 


PS: At the moment I access my ISDN PBX via an internal S0 so that I route
calls to internal ISDN PBX extensions (11 through 18). As soon as I
reconfigure everything to zaphfc-NT, I will send the ISDN PBX fantasy MSNs
so that the whole idea still works. Each internal extension in the ISDN PBX
must then have their individual MSNs. Again - I use my ISDN PBX only as an
8-way ISDN-analog adapter then because I want to keep my DECT phones. 




---------------------------------- snip ----------------------------------

diff -ur asterisk-ORIG/channels/chan_sip.c asterisk/channels/chan_sip.c
--- asterisk-ORIG/channels/chan_sip.c	2005-03-12 22:28:53.513437000 +0100
+++ asterisk/channels/chan_sip.c	2005-03-13 13:24:53.707682831 +0100
@@ -231,7 +231,6 @@
 
 static struct ast_codec_pref prefs;
 
-
 /* sip_request: The data grabbed from the UDP socket */
 struct sip_request {
 	char *rlPart1; 		/* SIP Method Name or "SIP/2.0" protocol version */
@@ -360,6 +359,7 @@
 	char tohost[AST_MAX_EXTENSION];		/* Host we should put in the "to" field */
 	char language[MAX_LANGUAGE];		/* Default language for this call */
 	char musicclass[MAX_LANGUAGE];          /* Music on Hold class */
+	char callednum[256];			/* The number we were called with */
 	char rdnis[256];			/* Referring DNIS */
 	char theirtag[256];			/* Their tag */
 	char username[256];			/* [user] name */
@@ -626,6 +626,7 @@
 static int sip_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
 static int sip_senddigit(struct ast_channel *ast, char digit);
 static int sip_sendtext(struct ast_channel *ast, char *text);
+static char *get_callednum(struct sip_request *req); 
 
 static const struct ast_channel_tech sip_tech = {
 	.type = channeltype,
@@ -2176,6 +2177,9 @@
 		if (!ast_strlen_zero(i->callid)) {
 			pbx_builtin_setvar_helper(tmp, "SIPCALLID", i->callid);
 		}
+		if (!ast_strlen_zero(i->callednum)) {
+			pbx_builtin_setvar_helper(tmp, "CALLEDNUM", i->callednum);
+		}
 		ast_setstate(tmp, state);
 		if (state != AST_STATE_DOWN) {
 			if (ast_pbx_start(tmp)) {
@@ -8492,6 +8496,29 @@
 	return 0;
 }
 
+
+
+static char *get_callednum(struct sip_request *req) {
+
+	char *tmp, *p, *q;
+
+	tmp = get_header(req, "To");
+	p = strstr(tmp, "sip:");	/* find sip: */
+	if (p == NULL) return ""; 	/* nothing found, strange */
+	p += 4;				/* points now at start of number */
+	/* do we have a @ or ; at all, ever ? */
+	q = strstr(p, "@");		/* find the @ */
+	if (q == NULL) 
+		q = strstr(p, ";");	/* or a ; */
+	if (q != NULL) 
+		*q = '\0';		/* and end the string */
+	return p;
+
+}
+
+
+
+
 /*--- sipsock_read: Read data from SIP socket ---*/
 /*    Successful messages is connected to SIP call and forwarded to handle_request() */
 static int sipsock_read(int *id, int fd, short events, void *ignore)
@@ -8534,6 +8561,11 @@
 	ast_mutex_lock(&netlock);
 	p = find_call(&req, &sin);
 	if (p) {
+		/* determine the called number (if we were called from the PSTN) */
+		strncpy (p->callednum, get_callednum(&req), sizeof(p->callednum));
+		if (debug) 
+			ast_verbose("\nTo-Header: %s\ncalled number: %s\n", 
+					get_header(&req, "To"), p->callednum);
 		/* Go ahead and lock the owner if it has one -- we may need it */
 		if (p->owner && ast_mutex_trylock(&p->owner->lock)) {
 			ast_log(LOG_DEBUG, "Failed to grab lock, trying again...\n");



-- 
Self Test for Paranoia:
	You know you have it when you can't think of anything that's
your own fault.



More information about the asterisk-dev mailing list