mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 10:47:18 +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
This commit is contained in:
		
				
					committed by
					
						 Friendly Automation
						Friendly Automation
					
				
			
			
				
	
			
			
			
						parent
						
							1bbcb98558
						
					
				
				
					commit
					4e602a1afe
				
			| @@ -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