mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 02:37:10 +00:00 
			
		
		
		
	chan_pjsip: Add PJSIPHangup dialplan app and manager action
See UserNote below.
Exposed the existing Hangup AMI action in manager.c so we can use
all of it's channel search and AMI protocol handling without
duplicating that code in dialplan_functions.c.
Added a lookup function to res_pjsip.c that takes in the
string represenation of the pjsip_status_code enum and returns
the actual status code.  I.E.  ast_sip_str2rc("DECLINE") returns
603.  This allows the caller to specify PJSIPHangup(decline) in
the dialplan, just like Hangup(call_rejected).
Also extracted the XML documentation to its own file since it was
almost as large as the code itself.
UserNote: A new dialplan app PJSIPHangup and AMI action allows you
to hang up an unanswered incoming PJSIP call with a specific SIP
response code in the 400 -> 699 range.
(cherry picked from commit 9a93ce0409)
			
			
This commit is contained in:
		
				
					committed by
					
						 Asterisk Development Team
						Asterisk Development Team
					
				
			
			
				
	
			
			
			
						parent
						
							311ae80860
						
					
				
				
					commit
					d8f1be3b81
				
			
							
								
								
									
										112
									
								
								res/res_pjsip.c
									
									
									
									
									
								
							
							
						
						
									
										112
									
								
								res/res_pjsip.c
									
									
									
									
									
								
							| @@ -3618,6 +3618,118 @@ const int ast_sip_hangup_sip2cause(int cause) | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| struct response_code_map { | ||||
| 	int code; | ||||
| 	const char *long_name; | ||||
| 	const char *short_name; | ||||
| }; | ||||
|  | ||||
| /* | ||||
|  * This map was generated from sip_msg.h with | ||||
|  * | ||||
|  * sed -n -r -e 's/^\s+(PJSIP_SC_([^ =]+))\s*=\s*[0-9]+,/{ \1, "\1", "\2" },/gp' \ | ||||
|  *     third-party/pjproject/source/pjsip/include/pjsip/sip_msg.h | ||||
|  * | ||||
|  */ | ||||
| static const struct response_code_map rc_map[] = { | ||||
| 	{ PJSIP_SC_NULL, "PJSIP_SC_NULL", "NULL" }, | ||||
| 	{ PJSIP_SC_TRYING, "PJSIP_SC_TRYING", "TRYING" }, | ||||
| 	{ PJSIP_SC_RINGING, "PJSIP_SC_RINGING", "RINGING" }, | ||||
| 	{ PJSIP_SC_CALL_BEING_FORWARDED, "PJSIP_SC_CALL_BEING_FORWARDED", "CALL_BEING_FORWARDED" }, | ||||
| 	{ PJSIP_SC_QUEUED, "PJSIP_SC_QUEUED", "QUEUED" }, | ||||
| 	{ PJSIP_SC_PROGRESS, "PJSIP_SC_PROGRESS", "PROGRESS" }, | ||||
| 	{ PJSIP_SC_EARLY_DIALOG_TERMINATED, "PJSIP_SC_EARLY_DIALOG_TERMINATED", "EARLY_DIALOG_TERMINATED" }, | ||||
| 	{ PJSIP_SC_OK, "PJSIP_SC_OK", "OK" }, | ||||
| 	{ PJSIP_SC_ACCEPTED, "PJSIP_SC_ACCEPTED", "ACCEPTED" }, | ||||
| 	{ PJSIP_SC_NO_NOTIFICATION, "PJSIP_SC_NO_NOTIFICATION", "NO_NOTIFICATION" }, | ||||
| 	{ PJSIP_SC_MULTIPLE_CHOICES, "PJSIP_SC_MULTIPLE_CHOICES", "MULTIPLE_CHOICES" }, | ||||
| 	{ PJSIP_SC_MOVED_PERMANENTLY, "PJSIP_SC_MOVED_PERMANENTLY", "MOVED_PERMANENTLY" }, | ||||
| 	{ PJSIP_SC_MOVED_TEMPORARILY, "PJSIP_SC_MOVED_TEMPORARILY", "MOVED_TEMPORARILY" }, | ||||
| 	{ PJSIP_SC_USE_PROXY, "PJSIP_SC_USE_PROXY", "USE_PROXY" }, | ||||
| 	{ PJSIP_SC_ALTERNATIVE_SERVICE, "PJSIP_SC_ALTERNATIVE_SERVICE", "ALTERNATIVE_SERVICE" }, | ||||
| 	{ PJSIP_SC_BAD_REQUEST, "PJSIP_SC_BAD_REQUEST", "BAD_REQUEST" }, | ||||
| 	{ PJSIP_SC_UNAUTHORIZED, "PJSIP_SC_UNAUTHORIZED", "UNAUTHORIZED" }, | ||||
| 	{ PJSIP_SC_PAYMENT_REQUIRED, "PJSIP_SC_PAYMENT_REQUIRED", "PAYMENT_REQUIRED" }, | ||||
| 	{ PJSIP_SC_FORBIDDEN, "PJSIP_SC_FORBIDDEN", "FORBIDDEN" }, | ||||
| 	{ PJSIP_SC_NOT_FOUND, "PJSIP_SC_NOT_FOUND", "NOT_FOUND" }, | ||||
| 	{ PJSIP_SC_METHOD_NOT_ALLOWED, "PJSIP_SC_METHOD_NOT_ALLOWED", "METHOD_NOT_ALLOWED" }, | ||||
| 	{ PJSIP_SC_NOT_ACCEPTABLE, "PJSIP_SC_NOT_ACCEPTABLE", "NOT_ACCEPTABLE" }, | ||||
| 	{ PJSIP_SC_PROXY_AUTHENTICATION_REQUIRED, "PJSIP_SC_PROXY_AUTHENTICATION_REQUIRED", "PROXY_AUTHENTICATION_REQUIRED" }, | ||||
| 	{ PJSIP_SC_REQUEST_TIMEOUT, "PJSIP_SC_REQUEST_TIMEOUT", "REQUEST_TIMEOUT" }, | ||||
| 	{ PJSIP_SC_CONFLICT, "PJSIP_SC_CONFLICT", "CONFLICT" }, | ||||
| 	{ PJSIP_SC_GONE, "PJSIP_SC_GONE", "GONE" }, | ||||
| 	{ PJSIP_SC_LENGTH_REQUIRED, "PJSIP_SC_LENGTH_REQUIRED", "LENGTH_REQUIRED" }, | ||||
| 	{ PJSIP_SC_CONDITIONAL_REQUEST_FAILED, "PJSIP_SC_CONDITIONAL_REQUEST_FAILED", "CONDITIONAL_REQUEST_FAILED" }, | ||||
| 	{ PJSIP_SC_REQUEST_ENTITY_TOO_LARGE, "PJSIP_SC_REQUEST_ENTITY_TOO_LARGE", "REQUEST_ENTITY_TOO_LARGE" }, | ||||
| 	{ PJSIP_SC_REQUEST_URI_TOO_LONG, "PJSIP_SC_REQUEST_URI_TOO_LONG", "REQUEST_URI_TOO_LONG" }, | ||||
| 	{ PJSIP_SC_UNSUPPORTED_MEDIA_TYPE, "PJSIP_SC_UNSUPPORTED_MEDIA_TYPE", "UNSUPPORTED_MEDIA_TYPE" }, | ||||
| 	{ PJSIP_SC_UNSUPPORTED_URI_SCHEME, "PJSIP_SC_UNSUPPORTED_URI_SCHEME", "UNSUPPORTED_URI_SCHEME" }, | ||||
| 	{ PJSIP_SC_UNKNOWN_RESOURCE_PRIORITY, "PJSIP_SC_UNKNOWN_RESOURCE_PRIORITY", "UNKNOWN_RESOURCE_PRIORITY" }, | ||||
| 	{ PJSIP_SC_BAD_EXTENSION, "PJSIP_SC_BAD_EXTENSION", "BAD_EXTENSION" }, | ||||
| 	{ PJSIP_SC_EXTENSION_REQUIRED, "PJSIP_SC_EXTENSION_REQUIRED", "EXTENSION_REQUIRED" }, | ||||
| 	{ PJSIP_SC_SESSION_TIMER_TOO_SMALL, "PJSIP_SC_SESSION_TIMER_TOO_SMALL", "SESSION_TIMER_TOO_SMALL" }, | ||||
| 	{ PJSIP_SC_INTERVAL_TOO_BRIEF, "PJSIP_SC_INTERVAL_TOO_BRIEF", "INTERVAL_TOO_BRIEF" }, | ||||
| 	{ PJSIP_SC_BAD_LOCATION_INFORMATION, "PJSIP_SC_BAD_LOCATION_INFORMATION", "BAD_LOCATION_INFORMATION" }, | ||||
| 	{ PJSIP_SC_USE_IDENTITY_HEADER, "PJSIP_SC_USE_IDENTITY_HEADER", "USE_IDENTITY_HEADER" }, | ||||
| 	{ PJSIP_SC_PROVIDE_REFERRER_HEADER, "PJSIP_SC_PROVIDE_REFERRER_HEADER", "PROVIDE_REFERRER_HEADER" }, | ||||
| 	{ PJSIP_SC_FLOW_FAILED, "PJSIP_SC_FLOW_FAILED", "FLOW_FAILED" }, | ||||
| 	{ PJSIP_SC_ANONIMITY_DISALLOWED, "PJSIP_SC_ANONIMITY_DISALLOWED", "ANONIMITY_DISALLOWED" }, | ||||
| 	{ PJSIP_SC_BAD_IDENTITY_INFO, "PJSIP_SC_BAD_IDENTITY_INFO", "BAD_IDENTITY_INFO" }, | ||||
| 	{ PJSIP_SC_UNSUPPORTED_CERTIFICATE, "PJSIP_SC_UNSUPPORTED_CERTIFICATE", "UNSUPPORTED_CERTIFICATE" }, | ||||
| 	{ PJSIP_SC_INVALID_IDENTITY_HEADER, "PJSIP_SC_INVALID_IDENTITY_HEADER", "INVALID_IDENTITY_HEADER" }, | ||||
| 	{ PJSIP_SC_FIRST_HOP_LACKS_OUTBOUND_SUPPORT, "PJSIP_SC_FIRST_HOP_LACKS_OUTBOUND_SUPPORT", "FIRST_HOP_LACKS_OUTBOUND_SUPPORT" }, | ||||
| 	{ PJSIP_SC_MAX_BREADTH_EXCEEDED, "PJSIP_SC_MAX_BREADTH_EXCEEDED", "MAX_BREADTH_EXCEEDED" }, | ||||
| 	{ PJSIP_SC_BAD_INFO_PACKAGE, "PJSIP_SC_BAD_INFO_PACKAGE", "BAD_INFO_PACKAGE" }, | ||||
| 	{ PJSIP_SC_CONSENT_NEEDED, "PJSIP_SC_CONSENT_NEEDED", "CONSENT_NEEDED" }, | ||||
| 	{ PJSIP_SC_TEMPORARILY_UNAVAILABLE, "PJSIP_SC_TEMPORARILY_UNAVAILABLE", "TEMPORARILY_UNAVAILABLE" }, | ||||
| 	{ PJSIP_SC_CALL_TSX_DOES_NOT_EXIST, "PJSIP_SC_CALL_TSX_DOES_NOT_EXIST", "CALL_TSX_DOES_NOT_EXIST" }, | ||||
| 	{ PJSIP_SC_LOOP_DETECTED, "PJSIP_SC_LOOP_DETECTED", "LOOP_DETECTED" }, | ||||
| 	{ PJSIP_SC_TOO_MANY_HOPS, "PJSIP_SC_TOO_MANY_HOPS", "TOO_MANY_HOPS" }, | ||||
| 	{ PJSIP_SC_ADDRESS_INCOMPLETE, "PJSIP_SC_ADDRESS_INCOMPLETE", "ADDRESS_INCOMPLETE" }, | ||||
| 	{ PJSIP_SC_BUSY_HERE, "PJSIP_SC_BUSY_HERE", "BUSY_HERE" }, | ||||
| 	{ PJSIP_SC_REQUEST_TERMINATED, "PJSIP_SC_REQUEST_TERMINATED", "REQUEST_TERMINATED" }, | ||||
| 	{ PJSIP_SC_NOT_ACCEPTABLE_HERE, "PJSIP_SC_NOT_ACCEPTABLE_HERE", "NOT_ACCEPTABLE_HERE" }, | ||||
| 	{ PJSIP_SC_BAD_EVENT, "PJSIP_SC_BAD_EVENT", "BAD_EVENT" }, | ||||
| 	{ PJSIP_SC_REQUEST_UPDATED, "PJSIP_SC_REQUEST_UPDATED", "REQUEST_UPDATED" }, | ||||
| 	{ PJSIP_SC_REQUEST_PENDING, "PJSIP_SC_REQUEST_PENDING", "REQUEST_PENDING" }, | ||||
| 	{ PJSIP_SC_UNDECIPHERABLE, "PJSIP_SC_UNDECIPHERABLE", "UNDECIPHERABLE" }, | ||||
| 	{ PJSIP_SC_SECURITY_AGREEMENT_NEEDED, "PJSIP_SC_SECURITY_AGREEMENT_NEEDED", "SECURITY_AGREEMENT_NEEDED" }, | ||||
| 	{ PJSIP_SC_INTERNAL_SERVER_ERROR, "PJSIP_SC_INTERNAL_SERVER_ERROR", "INTERNAL_SERVER_ERROR" }, | ||||
| 	{ PJSIP_SC_NOT_IMPLEMENTED, "PJSIP_SC_NOT_IMPLEMENTED", "NOT_IMPLEMENTED" }, | ||||
| 	{ PJSIP_SC_BAD_GATEWAY, "PJSIP_SC_BAD_GATEWAY", "BAD_GATEWAY" }, | ||||
| 	{ PJSIP_SC_SERVICE_UNAVAILABLE, "PJSIP_SC_SERVICE_UNAVAILABLE", "SERVICE_UNAVAILABLE" }, | ||||
| 	{ PJSIP_SC_SERVER_TIMEOUT, "PJSIP_SC_SERVER_TIMEOUT", "SERVER_TIMEOUT" }, | ||||
| 	{ PJSIP_SC_VERSION_NOT_SUPPORTED, "PJSIP_SC_VERSION_NOT_SUPPORTED", "VERSION_NOT_SUPPORTED" }, | ||||
| 	{ PJSIP_SC_MESSAGE_TOO_LARGE, "PJSIP_SC_MESSAGE_TOO_LARGE", "MESSAGE_TOO_LARGE" }, | ||||
| 	{ PJSIP_SC_PUSH_NOTIFICATION_SERVICE_NOT_SUPPORTED, "PJSIP_SC_PUSH_NOTIFICATION_SERVICE_NOT_SUPPORTED", "PUSH_NOTIFICATION_SERVICE_NOT_SUPPORTED" }, | ||||
| 	{ PJSIP_SC_PRECONDITION_FAILURE, "PJSIP_SC_PRECONDITION_FAILURE", "PRECONDITION_FAILURE" }, | ||||
| 	{ PJSIP_SC_BUSY_EVERYWHERE, "PJSIP_SC_BUSY_EVERYWHERE", "BUSY_EVERYWHERE" }, | ||||
| 	{ PJSIP_SC_DECLINE, "PJSIP_SC_DECLINE", "DECLINE" }, | ||||
| 	{ PJSIP_SC_DOES_NOT_EXIST_ANYWHERE, "PJSIP_SC_DOES_NOT_EXIST_ANYWHERE", "DOES_NOT_EXIST_ANYWHERE" }, | ||||
| 	{ PJSIP_SC_NOT_ACCEPTABLE_ANYWHERE, "PJSIP_SC_NOT_ACCEPTABLE_ANYWHERE", "NOT_ACCEPTABLE_ANYWHERE" }, | ||||
| 	{ PJSIP_SC_UNWANTED, "PJSIP_SC_UNWANTED", "UNWANTED" }, | ||||
| 	{ PJSIP_SC_REJECTED, "PJSIP_SC_REJECTED", "REJECTED" }, | ||||
| }; | ||||
|  | ||||
| int ast_sip_str2rc(const char *name) | ||||
| { | ||||
| 	int i; | ||||
|  | ||||
| 	if (ast_strlen_zero(name)) { | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	for (i = 0; i < ARRAY_LEN(rc_map); i++) { | ||||
| 		if (strcasecmp(rc_map[i].short_name, name) == 0 || | ||||
| 			strcasecmp(rc_map[i].long_name, name) == 0) { | ||||
| 			return rc_map[i].code; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return -1; | ||||
| } | ||||
|  | ||||
|  | ||||
| #ifdef TEST_FRAMEWORK | ||||
| AST_TEST_DEFINE(xml_sanitization_end_null) | ||||
| { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user