--- channels/chan_sip.c.orig 2004-08-08 12:15:02.000000000 -0500 +++ channels/chan_sip.c 2004-08-16 13:45:08.000000000 -0500 @@ -5,7 +5,7 @@ * * Copyright (C) 1999, Mark Spencer * - * Mark Spencer + * Mark Spencer * * This program is free software, distributed under the terms of * the GNU General Public License @@ -40,6 +40,7 @@ #include #include #include +#include #ifdef OSP_SUPPORT #include #endif @@ -198,8 +199,9 @@ static int videosupport = 0; static int global_dtmfmode = SIP_DTMF_RFC2833; /* DTMF mode default */ -static int recordhistory = 0; -static int global_promiscredir; +static int recordhistory = 0; /* Record SIP history */ +static int global_promiscredir; /* Promiscuos redirects */ +static int global_usereqphone; /* user=phone, default 0 */ static char global_musicclass[MAX_LANGUAGE] = ""; /* Global music on hold class */ static char global_realm[AST_MAX_EXTENSION] = "asterisk"; /* Default realm */ @@ -341,6 +343,7 @@ int stateid; int dialogver; int promiscredir; /* Promiscuous redirection */ + int usereqphone; /* Whether to use ;user=phone on outbound uri's */ int trustrpid; int progressinband; @@ -418,6 +421,7 @@ char md5secret[80]; char context[80]; /* JK02: peers need context too to allow parking etc */ char username[80]; + int usereqphone; char tohost[80]; char fromuser[80]; char fromdomain[80]; @@ -1298,6 +1302,7 @@ r->noncodeccapability &= ~AST_RTP_DTMF; } r->promiscredir = p->promiscredir; + r->usereqphone = p->usereqphone; strncpy(r->context, p->context,sizeof(r->context)-1); if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) && (!p->maxms || ((p->lastms > 0) && (p->lastms <= p->maxms)))) { @@ -3625,6 +3630,32 @@ char iabuf[INET_ADDRSTRLEN]; char cid[256]; char *l = default_callerid, *n=NULL; + int x; + char urioptions[256]; + + if (p->usereqphone) { + char onlydigits = 1; + x=0; + + /* Test p->username against allowed characters in AST_DIGIT_ANY + If it matches the allowed characters list, then sipuser = ";user=phone" + If not, then sipuser = "" + */ + /* + is allowed in first position in a tel: uri */ + if (p->username && p->username[0] == '+') + x=1; + + for (;xusername);x++) { + if (!strchr(AST_DIGIT_ANY, p->username[x])) { + onlydigits = 0; + break; + } + } + + /* If we have only digits, add ;user=phone to the uri */ + if (onlydigits) + strcpy(urioptions, ";user=phone"); + } snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", cmd); @@ -3655,14 +3686,14 @@ if (!ast_strlen_zero(p->username)) { if (ntohs(p->sa.sin_port) != DEFAULT_SIP_PORT) { - snprintf(invite, sizeof(invite), "sip:%s@%s:%d",p->username, p->tohost, ntohs(p->sa.sin_port)); + snprintf(invite, sizeof(invite), "sip:%s@%s:%d%s",p->username, p->tohost, ntohs(p->sa.sin_port), urioptions); } else { - snprintf(invite, sizeof(invite), "sip:%s@%s",p->username, p->tohost); + snprintf(invite, sizeof(invite), "sip:%s@%s%s",p->username, p->tohost, urioptions); } } else if (ntohs(p->sa.sin_port) != DEFAULT_SIP_PORT) { - snprintf(invite, sizeof(invite), "sip:%s:%d", p->tohost, ntohs(p->sa.sin_port)); + snprintf(invite, sizeof(invite), "sip:%s:%d%s", p->tohost, ntohs(p->sa.sin_port), urioptions); } else { - snprintf(invite, sizeof(invite), "sip:%s", p->tohost); + snprintf(invite, sizeof(invite), "sip:%s%s", p->tohost, urioptions); } strncpy(p->uri, invite, sizeof(p->uri) - 1); /* If there is a VXML URL append it to the SIP URL */ @@ -5305,6 +5336,7 @@ p->capability = peer->capability; p->jointcapability = peer->capability; p->promiscredir = peer->promiscredir; + p->usereqphone = peer->usereqphone; if (peer->dtmfmode) { p->dtmfmode = peer->dtmfmode; if (p->dtmfmode & SIP_DTMF_RFC2833) @@ -5578,6 +5610,7 @@ ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No")); ast_cli(fd, " CanReinvite : %s\n", (peer->canreinvite?"Yes":"No")); ast_cli(fd, " PromiscRedir : %s\n", (peer->promiscredir?"Yes":"No")); + ast_cli(fd, " UserEqPhone : %s\n", (peer->usereqphone?"Yes":"No")); /* - is enumerated */ ast_cli(fd, " DTMFmode : "); @@ -7987,6 +8020,7 @@ peer->canreinvite = global_canreinvite; peer->dtmfmode = global_dtmfmode; peer->promiscredir = global_promiscredir; + peer->usereqphone = global_usereqphone; peer->nat = global_nat; peer->rtptimeout = global_rtptimeout; peer->rtpholdtimeout = global_rtpholdtimeout; @@ -8047,6 +8081,7 @@ peer->addr.sin_family = AF_INET; peer->defaddr.sin_family = AF_INET; peer->expiry = expiry; + peer->usereqphone = global_usereqphone; } oldha = peer->ha; peer->ha = NULL; @@ -8084,6 +8119,8 @@ strncpy(peer->context, v->value, sizeof(peer->context)-1); else if (!strcasecmp(v->name, "fromdomain")) strncpy(peer->fromdomain, v->value, sizeof(peer->fromdomain)-1); + else if (!strcasecmp(v->name, "usereqphone")) + peer->usereqphone = ast_true(v->value); else if (!strcasecmp(v->name, "promiscredir")) peer->promiscredir = ast_true(v->value); else if (!strcasecmp(v->name, "fromuser")) @@ -8238,7 +8275,8 @@ global_dtmfmode = SIP_DTMF_RFC2833; global_promiscredir = 0; - + global_usereqphone = 0; + if (gethostname(ourhost, sizeof(ourhost))) { ast_log(LOG_WARNING, "Unable to get hostname, SIP disabled\n"); return 0; @@ -8287,6 +8325,8 @@ default_useragent); } else if (!strcasecmp(v->name, "relaxdtmf")) { relaxdtmf = ast_true(v->value); + } else if (!strcasecmp(v->name, "usereqphone")) { + global_usereqphone = ast_true(v->value); } else if (!strcasecmp(v->name, "promiscredir")) { global_promiscredir = ast_true(v->value); } else if (!strcasecmp(v->name, "dtmfmode")) {