Example #1
0
static int send_dtmf(MSFilter * f, uint32_t timestamp_start)
{
	SenderData *d = (SenderData *) f->data;
	mblk_t *m1;
	int tev_type;

	/* create the first telephony event packet */
	switch (d->dtmf){
		case '1':
			tev_type=TEV_DTMF_1;
		break;
		case '2':
			tev_type=TEV_DTMF_2;
		break;
		case '3':
			tev_type=TEV_DTMF_3;
		break;
		case '4':
			tev_type=TEV_DTMF_4;
		break;
		case '5':
			tev_type=TEV_DTMF_5;
		break;
		case '6':
			tev_type=TEV_DTMF_6;
		break;
		case '7':
			tev_type=TEV_DTMF_7;
		break;
		case '8':
			tev_type=TEV_DTMF_8;
		break;
		case '9':
			tev_type=TEV_DTMF_9;
		break;
		case '*':
			tev_type=TEV_DTMF_STAR;
		break;
		case '0':
			tev_type=TEV_DTMF_0;
		break;
		case '#':
			tev_type=TEV_DTMF_POUND;
		break;

		case 'A':
		case 'a':
		  tev_type=TEV_DTMF_A;
		  break;


		case 'B':
		case 'b':
		  tev_type=TEV_DTMF_B;
		  break;

		case 'C':
		case 'c':
		  tev_type=TEV_DTMF_C;
		  break;

		case 'D':
		case 'd':
		  tev_type=TEV_DTMF_D;
		  break;

		case '!':
		  tev_type=TEV_FLASH;
		  break;


		default:
		ms_warning("Bad dtmf: %c.",d->dtmf);
		return -1;
	}


	
	m1=rtp_session_create_telephone_event_packet(d->session,timestamp_start==d->dtmf_ts_cur);
	
	if (m1==NULL) return -1;

	d->dtmf_ts_cur+=d->dtmf_ts_step;
	if (RTP_TIMESTAMP_IS_NEWER_THAN(d->dtmf_ts_cur, d->skip_until)) {
		//retransmit end of rtp dtmf event
		mblk_t *tmp;
		rtp_session_add_telephone_event(d->session,m1,tev_type,1,10,(d->dtmf_ts_cur-timestamp_start));
		tmp=copymsg(m1);
		rtp_session_sendm_with_ts(d->session,tmp,timestamp_start);
		d->session->rtp.snd_seq--;
		tmp=copymsg(m1);
		rtp_session_sendm_with_ts(d->session,tmp,timestamp_start);
		d->session->rtp.snd_seq--;
		rtp_session_sendm_with_ts(d->session,m1,timestamp_start);
		d->skip = FALSE;
		d->dtmf = 0;
		ms_message("Finished sending RFC2833 dtmf %c",d->dtmf);
	}else {
		rtp_session_add_telephone_event(d->session,m1,tev_type,0,10,(d->dtmf_ts_cur-timestamp_start));
		rtp_session_sendm_with_ts(d->session,m1,timestamp_start);
	}
	return 0;
}
/**
 * A variation of rtp_session_send_dtmf() with duration specified.
 *
 * @param session a rtp session
 * @param dtmf a character meaning the dtmf (ex: '1', '#' , '9' ...)
 * @param userts the timestamp
 * @param duration duration of the dtmf in timestamp units
 * @return 0 if successfull, -1 if the session cannot support telephony events or if the dtmf given as argument is not valid.
**/
int rtp_session_send_dtmf2(RtpSession *session, char dtmf, uint32_t userts, int duration)
{
	mblk_t *m1,*m2,*m3;
	int tev_type;
	int durationtier = duration/3;

	/* create the first telephony event packet */
	switch (dtmf){
		case '1':
			tev_type=TEV_DTMF_1;
		break;
		case '2':
			tev_type=TEV_DTMF_2;
		break;
		case '3':
			tev_type=TEV_DTMF_3;
		break;
		case '4':
			tev_type=TEV_DTMF_4;
		break;
		case '5':
			tev_type=TEV_DTMF_5;
		break;
		case '6':
			tev_type=TEV_DTMF_6;
		break;
		case '7':
			tev_type=TEV_DTMF_7;
		break;
		case '8':
			tev_type=TEV_DTMF_8;
		break;
		case '9':
			tev_type=TEV_DTMF_9;
		break;
		case '*':
			tev_type=TEV_DTMF_STAR;
		break;
		case '0':
			tev_type=TEV_DTMF_0;
		break;
		case '#':
			tev_type=TEV_DTMF_POUND;
		break;

		case 'A':
		case 'a':
		  tev_type=TEV_DTMF_A;
		  break;


		case 'B':
		case 'b':
		  tev_type=TEV_DTMF_B;
		  break;

		case 'C':
		case 'c':
		  tev_type=TEV_DTMF_C;
		  break;

		case 'D':
		case 'd':
		  tev_type=TEV_DTMF_D;
		  break;

		case '!':
		  tev_type=TEV_FLASH;
		  break;


		default:
		ortp_warning("Bad dtmf: %c.",dtmf);
		return -1;
	}

	m1=rtp_session_create_telephone_event_packet(session,1);
	if (m1==NULL) return -1;
	rtp_session_add_telephone_event(session,m1,tev_type,0,10,durationtier);
	/* create a second packet */
	m2=rtp_session_create_telephone_event_packet(session,0);
	if (m2==NULL) return -1;
	rtp_session_add_telephone_event(session,m2,tev_type,0,10, durationtier+durationtier);
		
	/* create a third and final packet */
	m3=rtp_session_create_telephone_event_packet(session,0);
	if (m3==NULL) return -1;
	rtp_session_add_telephone_event(session,m3,tev_type,1,10,duration);
	
	/* and now sends them */
	rtp_session_sendm_with_ts(session,m1,userts);
	rtp_session_sendm_with_ts(session,m2,userts);
	/* the last packet is sent three times in order to improve reliability*/
	m1=copymsg(m3);
	m2=copymsg(m3);
	/*			NOTE:			*/
	/* we need to copymsg() instead of dupmsg() because the buffers are modified when
	the packet is sended because of the host-to-network conversion of timestamp,ssrc, csrc, and
	seq number.
	*/
	rtp_session_sendm_with_ts(session,m3,userts);
	session->rtp.snd_seq--;
	rtp_session_sendm_with_ts(session,m1,userts);
	session->rtp.snd_seq--;
	rtp_session_sendm_with_ts(session,m2,userts);
	return 0;
}
/**
 *rtp_session_send_dtmf:
 *@session	: a rtp session
 *@dtmf		: a character meaning the dtmf (ex: '1', '#' , '9' ...)
 *@userts	: the timestamp
 *
 *	This functions creates telephony events packets for @dtmf and sends them.
 *	It uses rtp_session_create_telephone_event_packet() and
 *	rtp_session_add_telephone_event() to create them and finally
 *	rtp_session_sendm_with_ts() to send them.
 *
 *Returns:	0 if successfull, -1 if the session cannot support telephony events or if the dtmf
 *	given as argument is not valid.
**/
gint rtp_session_send_dtmf(RtpSession *session, gchar dtmf, guint32 userts)
{
	mblk_t *m1,*m2,*m3;
	int tev_type;
	/* create the first telephony event packet */
	switch (dtmf){
		case '1':
			tev_type=TEV_DTMF_1;
		break;
		case '2':
			tev_type=TEV_DTMF_2;
		break;
		case '3':
			tev_type=TEV_DTMF_3;
		break;
		case '4':
			tev_type=TEV_DTMF_4;
		break;
		case '5':
			tev_type=TEV_DTMF_5;
		break;
		case '6':
			tev_type=TEV_DTMF_6;
		break;
		case '7':
			tev_type=TEV_DTMF_7;
		break;
		case '8':
			tev_type=TEV_DTMF_8;
		break;
		case '9':
			tev_type=TEV_DTMF_9;
		break;
		case '*':
			tev_type=TEV_DTMF_STAR;
		break;
		case '0':
			tev_type=TEV_DTMF_0;
		break;
		case '#':
			tev_type=TEV_DTMF_POUND;
		break;
		default:
		g_warning("Bad dtmf: %c.",dtmf);
		return -1;
	}

	m1=rtp_session_create_telephone_event_packet(session,1);
	if (m1==NULL) return -1;
	rtp_session_add_telephone_event(session,m1,tev_type,0,0,160);
	/* create a second packet */
	m2=rtp_session_create_telephone_event_packet(session,0);
	if (m2==NULL) return -1;
	rtp_session_add_telephone_event(session,m2,tev_type,0,0,320);
		
	/* create a third and final packet */
	m3=rtp_session_create_telephone_event_packet(session,0);
	if (m3==NULL) return -1;
	rtp_session_add_telephone_event(session,m3,tev_type,1,0,480);
	
	/* and now sends them */
	rtp_session_sendm_with_ts(session,m1,userts);
	rtp_session_sendm_with_ts(session,m2,userts);
	/* the last packet is sent three times in order to improve reliability*/
	m1=copymsg(m3);
	m2=copymsg(m3);
	/*			NOTE:			*/
	/* we need to copymsg() instead of dupmsg() because the buffers are modified when
	the packet is sended because of the host-to-network conversion of timestamp,ssrc, csrc, and
	seq number.
	It could be avoided by making a copy of the buffer when sending physically the packet, but
	it add one more copy for every buffer.
	Using iomapped socket, it is possible to avoid the user to kernel copy.
	*/
	rtp_session_sendm_with_ts(session,m3,userts);
	rtp_session_sendm_with_ts(session,m1,userts);
	rtp_session_sendm_with_ts(session,m2,userts);
	return 0;
}