mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-03 03:20:57 +00:00
pbx_dundi: Add PJSIP support.
Adds PJSIP as a supported technology to DUNDi.
To facilitate this, we now allow an endpoint to be specified
for outgoing PJSIP calls. We also allow users to force a specific
channel technology for outgoing SIP-protocol calls.
ASTERISK-28109 #close
ASTERISK-28233 #close
Change-Id: I2e28e5a5d007bd49e3df113ad567b011103899bf
(cherry picked from commit b33f92cbb5
)
This commit is contained in:
committed by
Asterisk Development Team
parent
81a912f3ce
commit
99d17db963
@@ -75,6 +75,18 @@ autokill=yes
|
|||||||
; off by default due to performance impacts.
|
; off by default due to performance impacts.
|
||||||
;
|
;
|
||||||
;storehistory=yes
|
;storehistory=yes
|
||||||
|
;
|
||||||
|
; Channel technology to use for outgoing calls using SIP (Session Initiation Protocol).
|
||||||
|
; Options are 'SIP' for chan_sip and 'PJSIP' for chan_pjsip. Default is 'PJSIP'.
|
||||||
|
; If specified, all outgoing SIP calls using DUNDi will use the specified channel tech.
|
||||||
|
;
|
||||||
|
;outgoing_sip_tech=pjsip
|
||||||
|
;
|
||||||
|
; Name of endpoint from pjsip.conf to use for outgoing calls from this system,
|
||||||
|
; when using the PJSIP technology to complete a call to a SIP-based destination.
|
||||||
|
; (Required for PJSIP, since PJSIP calls must specify an endpoint explicitly).
|
||||||
|
;
|
||||||
|
;pjsip_outgoing_endpoint=outgoing
|
||||||
|
|
||||||
[mappings]
|
[mappings]
|
||||||
;
|
;
|
||||||
|
5
doc/CHANGES-staging/dundi.txt
Normal file
5
doc/CHANGES-staging/dundi.txt
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
Subject: DUNDi
|
||||||
|
|
||||||
|
DUNDi now supports chan_pjsip. Outgoing calls using
|
||||||
|
PJSIP require the pjsip_outgoing_endpoint option
|
||||||
|
to be set in dundi.conf.
|
@@ -59,6 +59,8 @@ enum {
|
|||||||
DUNDI_PROTO_SIP = 2,
|
DUNDI_PROTO_SIP = 2,
|
||||||
/*! ITU H.323 */
|
/*! ITU H.323 */
|
||||||
DUNDI_PROTO_H323 = 3,
|
DUNDI_PROTO_H323 = 3,
|
||||||
|
/*! PJSIP */
|
||||||
|
DUNDI_PROTO_PJSIP = 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@@ -236,6 +236,8 @@ static char *proto2str(int proto, char *buf, int bufsiz)
|
|||||||
case DUNDI_PROTO_H323:
|
case DUNDI_PROTO_H323:
|
||||||
strncpy(buf, "H.323", bufsiz - 1);
|
strncpy(buf, "H.323", bufsiz - 1);
|
||||||
break;
|
break;
|
||||||
|
case DUNDI_PROTO_PJSIP:
|
||||||
|
strncpy(buf, "PJSIP", bufsiz - 1);
|
||||||
default:
|
default:
|
||||||
snprintf(buf, bufsiz, "Unknown Proto(%d)", proto);
|
snprintf(buf, bufsiz, "Unknown Proto(%d)", proto);
|
||||||
}
|
}
|
||||||
|
@@ -208,6 +208,8 @@ static char phone[80];
|
|||||||
static char secretpath[80];
|
static char secretpath[80];
|
||||||
static char cursecret[80];
|
static char cursecret[80];
|
||||||
static char ipaddr[80];
|
static char ipaddr[80];
|
||||||
|
static int outgoing_sip_tech;
|
||||||
|
static char pjsip_outgoing_endpoint[80];
|
||||||
static time_t rotatetime;
|
static time_t rotatetime;
|
||||||
static dundi_eid empty_eid = { { 0, 0, 0, 0, 0, 0 } };
|
static dundi_eid empty_eid = { { 0, 0, 0, 0, 0, 0 } };
|
||||||
static int dundi_shutdown = 0;
|
static int dundi_shutdown = 0;
|
||||||
@@ -388,12 +390,14 @@ static char *tech2str(int tech)
|
|||||||
return "SIP";
|
return "SIP";
|
||||||
case DUNDI_PROTO_H323:
|
case DUNDI_PROTO_H323:
|
||||||
return "H323";
|
return "H323";
|
||||||
|
case DUNDI_PROTO_PJSIP:
|
||||||
|
return "PJSIP";
|
||||||
default:
|
default:
|
||||||
return "Unknown";
|
return "Unknown";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int str2tech(char *str)
|
static int str2tech(const char *str)
|
||||||
{
|
{
|
||||||
if (!strcasecmp(str, "IAX") || !strcasecmp(str, "IAX2"))
|
if (!strcasecmp(str, "IAX") || !strcasecmp(str, "IAX2"))
|
||||||
return DUNDI_PROTO_IAX;
|
return DUNDI_PROTO_IAX;
|
||||||
@@ -401,6 +405,8 @@ static int str2tech(char *str)
|
|||||||
return DUNDI_PROTO_SIP;
|
return DUNDI_PROTO_SIP;
|
||||||
else if (!strcasecmp(str, "H323"))
|
else if (!strcasecmp(str, "H323"))
|
||||||
return DUNDI_PROTO_H323;
|
return DUNDI_PROTO_H323;
|
||||||
|
else if (!strcasecmp(str, "PJSIP"))
|
||||||
|
return DUNDI_PROTO_PJSIP;
|
||||||
else
|
else
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -4836,7 +4842,6 @@ static int dundi_exec(struct ast_channel *chan, const char *context, const char
|
|||||||
int x=0;
|
int x=0;
|
||||||
char req[1024];
|
char req[1024];
|
||||||
const char *dundiargs;
|
const char *dundiargs;
|
||||||
struct ast_app *dial;
|
|
||||||
|
|
||||||
if (!strncasecmp(context, "macro-", 6)) {
|
if (!strncasecmp(context, "macro-", 6)) {
|
||||||
if (!chan) {
|
if (!chan) {
|
||||||
@@ -4874,13 +4879,42 @@ static int dundi_exec(struct ast_channel *chan, const char *context, const char
|
|||||||
if (x < res) {
|
if (x < res) {
|
||||||
/* Got a hit! */
|
/* Got a hit! */
|
||||||
dundiargs = pbx_builtin_getvar_helper(chan, "DUNDIDIALARGS");
|
dundiargs = pbx_builtin_getvar_helper(chan, "DUNDIDIALARGS");
|
||||||
snprintf(req, sizeof(req), "%s/%s,,%s", results[x].tech, results[x].dest,
|
/* Backwards compatibility with lookups using chan_sip even if we don't have it anymore:
|
||||||
S_OR(dundiargs, ""));
|
* At a protocol level, "SIP" will always be specified, but depending on our configuration,
|
||||||
dial = pbx_findapp("Dial");
|
* we will use the user-specified channel driver (from dundi.conf) to complete the call.
|
||||||
if (dial)
|
*/
|
||||||
res = pbx_exec(chan, dial, req);
|
if (!strcasecmp(results[x].tech, "SIP") || !strcasecmp(results[x].tech, "PJSIP")) {
|
||||||
} else
|
/* Only "SIP" is a valid technology for a DUNDi peer to communicate.
|
||||||
|
* But if they tell use to use "PJSIP" instead, just interpret it as if they said "SIP" instead. */
|
||||||
|
if (strcasecmp(results[x].tech, "SIP")) {
|
||||||
|
ast_log(LOG_WARNING, "%s cannot be specified by DUNDi peers (peer should use SIP for DUNDi lookups instead)\n", results[x].tech);
|
||||||
|
}
|
||||||
|
/* Use whatever we're configured to use for SIP protocol calls. */
|
||||||
|
results[x].techint = outgoing_sip_tech;
|
||||||
|
ast_copy_string(results[x].tech, tech2str(outgoing_sip_tech), sizeof(results[x].tech));
|
||||||
|
}
|
||||||
|
/* PJSIP requires an endpoint to be specified explicitly. */
|
||||||
|
if (outgoing_sip_tech == DUNDI_PROTO_PJSIP) {
|
||||||
|
char *number, *ip = ast_strdupa(results[x].dest);
|
||||||
|
if (!ast_strlen_zero(pjsip_outgoing_endpoint)) {
|
||||||
|
ast_log(LOG_WARNING, "PJSIP calls require an endpoint to be specified explicitly (use the pjsip_outgoing_endpoint option in dundi.conf)\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
/* Take IP/number and turn it into sip:number@IP */
|
||||||
|
if (ast_strlen_zero(ip)) {
|
||||||
|
ast_log(LOG_WARNING, "PJSIP destination is empty?\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
number = strsep(&ip, "/");
|
||||||
|
snprintf(req, sizeof(req), "%s/%s/sip:%s@%s,,%s", results[x].tech, pjsip_outgoing_endpoint, S_OR(number, ""), ip, S_OR(dundiargs, ""));
|
||||||
|
ast_debug(1, "Finalized PJSIP Dial: %s\n", req);
|
||||||
|
} else { /* SIP, or something else. */
|
||||||
|
snprintf(req, sizeof(req), "%s/%s,,%s", results[x].tech, results[x].dest, S_OR(dundiargs, ""));
|
||||||
|
}
|
||||||
|
res = ast_pbx_exec_application(chan, "Dial", req);
|
||||||
|
} else {
|
||||||
res = -1;
|
res = -1;
|
||||||
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4956,6 +4990,7 @@ static int set_config(char *config_file, struct ast_sockaddr *sin, int reload, s
|
|||||||
dundi_ttl = DUNDI_DEFAULT_TTL;
|
dundi_ttl = DUNDI_DEFAULT_TTL;
|
||||||
dundi_cache_time = DUNDI_DEFAULT_CACHE_TIME;
|
dundi_cache_time = DUNDI_DEFAULT_CACHE_TIME;
|
||||||
any_peer = NULL;
|
any_peer = NULL;
|
||||||
|
outgoing_sip_tech = DUNDI_PROTO_SIP;
|
||||||
|
|
||||||
AST_LIST_LOCK(&peers);
|
AST_LIST_LOCK(&peers);
|
||||||
|
|
||||||
@@ -5026,6 +5061,15 @@ static int set_config(char *config_file, struct ast_sockaddr *sin, int reload, s
|
|||||||
ast_copy_string(phone, v->value, sizeof(phone));
|
ast_copy_string(phone, v->value, sizeof(phone));
|
||||||
} else if (!strcasecmp(v->name, "storehistory")) {
|
} else if (!strcasecmp(v->name, "storehistory")) {
|
||||||
global_storehistory = ast_true(v->value);
|
global_storehistory = ast_true(v->value);
|
||||||
|
} else if (!strcasecmp(v->name, "outgoing_sip_tech")) {
|
||||||
|
int outgoing_tech = str2tech(v->value);
|
||||||
|
if (outgoing_tech != DUNDI_PROTO_SIP && outgoing_tech != DUNDI_PROTO_PJSIP) {
|
||||||
|
ast_log(LOG_WARNING, "outgoing_sip_tech must be SIP or PJSIP\n");
|
||||||
|
} else {
|
||||||
|
outgoing_sip_tech = outgoing_tech;
|
||||||
|
}
|
||||||
|
} else if (!strcasecmp(v->name, "pjsip_outgoing_endpoint")) {
|
||||||
|
ast_copy_string(pjsip_outgoing_endpoint, v->value, sizeof(pjsip_outgoing_endpoint));
|
||||||
} else if (!strcasecmp(v->name, "cachetime")) {
|
} else if (!strcasecmp(v->name, "cachetime")) {
|
||||||
if ((sscanf(v->value, "%30d", &x) == 1)) {
|
if ((sscanf(v->value, "%30d", &x) == 1)) {
|
||||||
dundi_cache_time = x;
|
dundi_cache_time = x;
|
||||||
|
Reference in New Issue
Block a user