mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 18:55:19 +00:00 
			
		
		
		
	Merge "res_pjsip: Add DTMF INFO Failback mode"
This commit is contained in:
		
							
								
								
									
										4
									
								
								CHANGES
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								CHANGES
									
									
									
									
									
								
							| @@ -40,6 +40,10 @@ res_pjsip | ||||
|    whether to notify dialog-info state 'early' or 'confirmed' on Ringing | ||||
|    when already INUSE. | ||||
|  | ||||
|  * The endpoint option 'dtmf_mode' has a new option 'auto_dtmf' added. This | ||||
|    mode works similar to 'auto' except uses DTMF INFO as fallback instead of | ||||
|    INBAND. | ||||
|  | ||||
| res_agi | ||||
| ------------------ | ||||
|  * The EAGI() application will now look for a dialplan variable named | ||||
|   | ||||
| @@ -1960,6 +1960,12 @@ static int chan_pjsip_digit_begin(struct ast_channel *chan, char digit) | ||||
| 			return -1; | ||||
| 		} | ||||
|  | ||||
| 		ast_rtp_instance_dtmf_begin(media->rtp, digit); | ||||
| 		break; | ||||
| 	case AST_SIP_DTMF_AUTO_INFO: | ||||
| 		if (!media || !media->rtp || (ast_rtp_instance_dtmf_mode_get(media->rtp) == AST_RTP_DTMF_MODE_NONE)) { | ||||
| 			return -1; | ||||
| 		} | ||||
| 		ast_rtp_instance_dtmf_begin(media->rtp, digit); | ||||
| 		break; | ||||
| 	case AST_SIP_DTMF_NONE: | ||||
| @@ -2063,6 +2069,20 @@ static int chan_pjsip_digit_end(struct ast_channel *ast, char digit, unsigned in | ||||
| 	media = channel->session->active_media_state->default_session[AST_MEDIA_TYPE_AUDIO]; | ||||
|  | ||||
| 	switch (channel->session->endpoint->dtmf) { | ||||
| 	case AST_SIP_DTMF_AUTO_INFO: | ||||
| 	{ | ||||
| 		if (!media || !media->rtp) { | ||||
| 			return -1; | ||||
| 		} | ||||
| 		if (ast_rtp_instance_dtmf_mode_get(media->rtp) != AST_RTP_DTMF_MODE_NONE) { | ||||
| 			ast_debug(3, "Told to send end of digit on Auto-Info channel %s RFC4733 negotiated so using it.\n", ast_channel_name(ast)); | ||||
| 			ast_rtp_instance_dtmf_end_with_duration(media->rtp, digit, duration); | ||||
| 			break; | ||||
| 		} | ||||
| 		/* If RFC_4733 was not negotiated, fail through to the DTMF_INFO processing */ | ||||
| 		ast_debug(3, "Told to send end of digit on Auto-Info channel %s RFC4733 NOT negotiated using INFO instead.\n", ast_channel_name(ast)); | ||||
| 	} | ||||
|  | ||||
| 	case AST_SIP_DTMF_INFO: | ||||
| 	{ | ||||
| 		struct info_dtmf_data *dtmf_data = info_dtmf_data_alloc(channel->session, digit, duration); | ||||
| @@ -2104,6 +2124,7 @@ static int chan_pjsip_digit_end(struct ast_channel *ast, char digit, unsigned in | ||||
| 		ast_rtp_instance_dtmf_end_with_duration(media->rtp, digit, duration); | ||||
| 		break; | ||||
|  | ||||
|  | ||||
| 	case AST_SIP_DTMF_NONE: | ||||
| 		break; | ||||
| 	case AST_SIP_DTMF_INBAND: | ||||
|   | ||||
| @@ -0,0 +1,57 @@ | ||||
| """Add auto_info to endpoint dtmf_mode | ||||
|  | ||||
| Revision ID: 164abbd708c | ||||
| Revises: 86bb1efa278d | ||||
| Create Date: 2017-06-19 13:55:15.354706 | ||||
|  | ||||
| """ | ||||
|  | ||||
| # revision identifiers, used by Alembic. | ||||
| revision = '164abbd708c' | ||||
| down_revision = '86bb1efa278d' | ||||
|  | ||||
| from alembic import op | ||||
| import sqlalchemy as sa | ||||
|  | ||||
| OLD_ENUM = ['rfc4733', 'inband', 'info', 'auto'] | ||||
| NEW_ENUM = ['rfc4733', 'inband', 'info', 'auto', 'auto_info'] | ||||
|  | ||||
| old_type = sa.Enum(*OLD_ENUM, name='pjsip_dtmf_mode_values_v2') | ||||
| new_type = sa.Enum(*NEW_ENUM, name='pjsip_dtmf_mode_values_v3') | ||||
|  | ||||
| def upgrade(): | ||||
|     context = op.get_context() | ||||
|  | ||||
|     # Upgrading to this revision WILL clear your directmedia values. | ||||
|     if context.bind.dialect.name != 'postgresql': | ||||
|         op.alter_column('ps_endpoints', 'dtmf_mode', | ||||
|                         type_=new_type, | ||||
|                         existing_type=old_type) | ||||
|     else: | ||||
|         enum = ENUM('rfc4733', 'inband', 'info', 'auto', 'auto_info', | ||||
|                     name='pjsip_dtmf_mode_values_v3') | ||||
|         enum.create(op.get_bind(), checkfirst=False) | ||||
|  | ||||
|         op.execute('ALTER TABLE ps_endpoints ALTER COLUMN dtmf_mode TYPE' | ||||
|                    ' pjsip_dtmf_mode_values_v3 USING' | ||||
|                    ' dtmf_mode::text::pjsip_dtmf_mode_values_v3') | ||||
|  | ||||
|         ENUM(name="pjsip_dtmf_mode_values_v2").drop(op.get_bind(), checkfirst=False) | ||||
|  | ||||
| def downgrade(): | ||||
|     context = op.get_context() | ||||
|  | ||||
|     if context.bind.dialect.name != 'postgresql': | ||||
|         op.alter_column('ps_endpoints', 'dtmf_mode', | ||||
|                         type_=old_type, | ||||
|                         existing_type=new_type) | ||||
|     else: | ||||
|         enum = ENUM('rfc4733', 'inband', 'info', 'auto', | ||||
|                     name='pjsip_dtmf_mode_values_v2') | ||||
|         enum.create(op.get_bind(), checkfirst=False) | ||||
|  | ||||
|         op.execute('ALTER TABLE ps_endpoints ALTER COLUMN dtmf_mode TYPE' | ||||
|                    ' pjsip_dtmf_mode_values USING' | ||||
|                    ' dtmf_mode::text::pjsip_dtmf_mode_values_v2') | ||||
|  | ||||
|         ENUM(name="pjsip_dtmf_mode_values_v3").drop(op.get_bind(), checkfirst=False) | ||||
| @@ -365,6 +365,8 @@ enum ast_sip_dtmf_mode { | ||||
| 	AST_SIP_DTMF_INFO, | ||||
| 	/*! Use SIP 4733 if supported by the other side or INBAND if not */ | ||||
| 	AST_SIP_DTMF_AUTO, | ||||
| 	/*! Use SIP 4733 if supported by the other side or INFO DTMF (blech) if not */ | ||||
| 	AST_SIP_DTMF_AUTO_INFO, | ||||
| }; | ||||
|  | ||||
| /*! | ||||
|   | ||||
| @@ -229,6 +229,9 @@ | ||||
| 							<enum name="auto"> | ||||
| 								<para>DTMF is sent as RFC 4733 if the other side supports it or as INBAND if not.</para> | ||||
| 							</enum> | ||||
| 							<enum name="auto_info"> | ||||
| 								<para>DTMF is sent as RFC 4733 if the other side supports it or as SIP INFO if not.</para> | ||||
| 							</enum> | ||||
| 						</enumlist> | ||||
| 					</description> | ||||
| 				</configOption> | ||||
|   | ||||
| @@ -371,6 +371,8 @@ static int dtmf_handler(const struct aco_option *opt, struct ast_variable *var, | ||||
| 		endpoint->dtmf = AST_SIP_DTMF_RFC_4733; | ||||
| 	} else if (!strcasecmp(var->value, "inband")) { | ||||
| 		endpoint->dtmf = AST_SIP_DTMF_INBAND; | ||||
| 	} else if (!strcasecmp(var->value, "auto_info")) { | ||||
| 		endpoint->dtmf = AST_SIP_DTMF_AUTO_INFO; | ||||
| 	} else if (!strcasecmp(var->value, "info")) { | ||||
| 		endpoint->dtmf = AST_SIP_DTMF_INFO; | ||||
| 	} else if (!strcasecmp(var->value, "auto")) { | ||||
| @@ -397,6 +399,9 @@ static int dtmf_to_str(const void *obj, const intptr_t *args, char **buf) | ||||
| 		*buf = "info"; break; | ||||
| 	case AST_SIP_DTMF_AUTO : | ||||
| 		*buf = "auto"; break; | ||||
| 	case AST_SIP_DTMF_AUTO_INFO : | ||||
| 		*buf = "auto_info"; | ||||
| 		break; | ||||
| 	default: | ||||
| 		*buf = "none"; | ||||
| 	} | ||||
|   | ||||
| @@ -207,7 +207,7 @@ static int create_rtp(struct ast_sip_session *session, struct ast_sip_session_me | ||||
| 		ice->stop(session_media->rtp); | ||||
| 	} | ||||
|  | ||||
| 	if (session->endpoint->dtmf == AST_SIP_DTMF_RFC_4733 || session->endpoint->dtmf == AST_SIP_DTMF_AUTO) { | ||||
| 	if (session->endpoint->dtmf == AST_SIP_DTMF_RFC_4733 || session->endpoint->dtmf == AST_SIP_DTMF_AUTO || session->endpoint->dtmf == AST_SIP_DTMF_AUTO_INFO) { | ||||
| 		ast_rtp_instance_dtmf_mode_set(session_media->rtp, AST_RTP_DTMF_MODE_RFC2833); | ||||
| 		ast_rtp_instance_set_prop(session_media->rtp, AST_RTP_PROPERTY_DTMF, 1); | ||||
| 	} else if (session->endpoint->dtmf == AST_SIP_DTMF_INBAND) { | ||||
| @@ -296,6 +296,16 @@ static void get_codecs(struct ast_sip_session *session, const struct pjmedia_sdp | ||||
| 	if (!tel_event && (session->endpoint->dtmf == AST_SIP_DTMF_AUTO)) { | ||||
| 		ast_rtp_instance_dtmf_mode_set(session_media->rtp, AST_RTP_DTMF_MODE_INBAND); | ||||
| 	} | ||||
|  | ||||
| 	if (session->endpoint->dtmf == AST_SIP_DTMF_AUTO_INFO) { | ||||
| 		if  (tel_event) { | ||||
| 			ast_rtp_instance_dtmf_mode_set(session_media->rtp, AST_RTP_DTMF_MODE_RFC2833); | ||||
| 		} else { | ||||
| 			ast_rtp_instance_dtmf_mode_set(session_media->rtp, AST_RTP_DTMF_MODE_NONE); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
|  | ||||
| 	/* Get the packetization, if it exists */ | ||||
| 	if ((attr = pjmedia_sdp_media_find_attr2(stream, "ptime", NULL))) { | ||||
| 		unsigned long framing = pj_strtoul(pj_strltrim(&attr->value)); | ||||
| @@ -404,7 +414,8 @@ static int set_caps(struct ast_sip_session *session, | ||||
| 			ast_set_read_format(session->channel, ast_channel_readformat(session->channel)); | ||||
| 			ast_set_write_format(session->channel, ast_channel_writeformat(session->channel)); | ||||
| 		} | ||||
| 		if ((session->endpoint->dtmf == AST_SIP_DTMF_AUTO) | ||||
|  | ||||
| 		if ( ((session->endpoint->dtmf == AST_SIP_DTMF_AUTO) || (session->endpoint->dtmf == AST_SIP_DTMF_AUTO_INFO) ) | ||||
| 		    && (ast_rtp_instance_dtmf_mode_get(session_media->rtp) == AST_RTP_DTMF_MODE_RFC2833) | ||||
| 		    && (session->dsp)) { | ||||
| 			dsp_features = ast_dsp_get_features(session->dsp); | ||||
| @@ -1136,7 +1147,7 @@ static int create_outgoing_sdp_stream(struct ast_sip_session *session, struct as | ||||
| 	pj_str_t stmp; | ||||
| 	pjmedia_sdp_attr *attr; | ||||
| 	int index = 0; | ||||
| 	int noncodec = (session->endpoint->dtmf == AST_SIP_DTMF_RFC_4733 || session->endpoint->dtmf == AST_SIP_DTMF_AUTO) ? AST_RTP_DTMF : 0; | ||||
| 	int noncodec = (session->endpoint->dtmf == AST_SIP_DTMF_RFC_4733 || session->endpoint->dtmf == AST_SIP_DTMF_AUTO || session->endpoint->dtmf == AST_SIP_DTMF_AUTO_INFO) ? AST_RTP_DTMF : 0; | ||||
| 	int min_packet_size = 0, max_packet_size = 0; | ||||
| 	int rtp_code; | ||||
| 	RAII_VAR(struct ast_format_cap *, caps, NULL, ao2_cleanup); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user