From ac87680632b4fb6582d1391b042eff7f0305c0a2 Mon Sep 17 00:00:00 2001 From: samelian Date: Sun, 22 May 2011 20:12:04 +0000 Subject: [kdenetwork/kopete] added cmake support git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdenetwork@1233119 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- .../talk/third_party/ortp/telephonyevents.c | 338 +++++++++++++++++++++ 1 file changed, 338 insertions(+) create mode 100644 kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/telephonyevents.c (limited to 'kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/telephonyevents.c') diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/telephonyevents.c b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/telephonyevents.c new file mode 100644 index 00000000..884226ea --- /dev/null +++ b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/telephonyevents.c @@ -0,0 +1,338 @@ +/* + The oRTP library is an RTP (Realtime Transport Protocol - rfc1889) stack. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include + + +PayloadType telephone_event={ + PAYLOAD_AUDIO_PACKETIZED, /*type */ + 8000, /*clock rate */ + 0, /* bytes per sample N/A */ + NULL, /* zero pattern N/A*/ + 0, /*pattern_length N/A */ + 0, /* normal_bitrate */ + "telephone-event", + 0 /*flags */ +}; + +/* tell if the session supports telephony events. For this the telephony events payload_type + must be present in the rtp profile used by the session */ +/** + *rtp_session_telephone_events_supported: + *@session : a rtp session + * + * Tells whether telephony events payload type is supported within the context of the rtp + * session. + * + *Returns: the payload type number used for telephony events if found, -1 if not found. +**/ +gint rtp_session_telephone_events_supported(RtpSession *session) +{ + /* search for a telephony event payload in the current profile */ + session->telephone_events_pt=rtp_profile_get_payload_number_from_mime(session->profile,"telephone-event"); + return session->telephone_events_pt; +} + + +/** + *rtp_session_create_telephone_event_packet: + *@session: a rtp session. + *@start: boolean to indicate if the marker bit should be set. + * + * Allocates a new rtp packet to be used to add named telephony events. The application can use + * then rtp_session_add_telephone_event() to add named events to the packet. + * Finally the packet has to be sent with rtp_session_sendm_with_ts(). + * + *Returns: a message block containing the rtp packet if successfull, NULL if the rtp session + *cannot support telephony event (because the rtp profile it is bound to does not include + *a telephony event payload type). +**/ +mblk_t *rtp_session_create_telephone_event_packet(RtpSession *session, int start) +{ + mblk_t *mp; + rtp_header_t *rtp; + + g_return_val_if_fail(session->telephone_events_pt!=-1,NULL); + + mp=allocb(RTP_FIXED_HEADER_SIZE+TELEPHONY_EVENTS_ALLOCATED_SIZE,BPRI_MED); + if (mp==NULL) return NULL; + rtp=(rtp_header_t*)mp->b_rptr; + rtp->version = 2; + rtp->markbit=start; + rtp->padbit = 0; + rtp->extbit = 0; + rtp->cc = 0; + rtp->ssrc = session->send_ssrc; + /* timestamp set later, when packet is sended */ + /*seq number set later, when packet is sended */ + + /*set the payload type */ + rtp->paytype=session->telephone_events_pt; + + /*copy the payload */ + mp->b_wptr+=RTP_FIXED_HEADER_SIZE; + return mp; +} + + +/** + *rtp_session_add_telephone_event: + *@session: a rtp session. + *@packet: a rtp packet as a #mblk_t + *@event: the event type as described in rfc2833, ie one of the TEV_ macros. + *@end: boolean to indicate if the end bit should be set. (end of tone) + *@volume: the volume of the telephony tone, as described in rfc2833 + *@duration:the duration of the telephony tone, in timestamp unit. + * + * Adds a named telephony event to a rtp packet previously allocated using + * rtp_session_create_telephone_event_packet(). + * + *Returns 0 on success. +**/ +gint rtp_session_add_telephone_event(RtpSession *session, + mblk_t *packet, guchar event, gint end, guchar volume, guint16 duration) +{ + mblk_t *mp=packet; + telephone_event_t *event_hdr; + + + /* find the place where to add the new telephony event to the packet */ + while(mp->b_cont!=NULL) mp=mp->b_cont; + /* see if we need to allocate a new mblk_t */ + if ( (long)mp->b_wptr >= (long) mp->b_datap->db_lim){ + mblk_t *newm=allocb(TELEPHONY_EVENTS_ALLOCATED_SIZE,BPRI_MED); + mp->b_cont=newm; + mp=mp->b_cont; + } + if (mp==NULL) return -1; + event_hdr=(telephone_event_t*)mp->b_wptr; + event_hdr->event=event; + event_hdr->R=0; + event_hdr->E=end; + event_hdr->volume=volume; + event_hdr->duration=htons(duration); + mp->b_wptr+=sizeof(telephone_event_t); + 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; +} + +/** + *rtp_session_read_telephone_event: + *@session: a rtp session from which telephony events are received. + *@packet: a rtp packet as a mblk_t. + *@tab: the address of a pointer. + * + * Reads telephony events from a rtp packet. *@tab points to the beginning of the event buffer. + * + *Returns: the number of events in the packet if successfull, 0 if the packet did not + * contain telephony events. +**/ +gint rtp_session_read_telephone_event(RtpSession *session, + mblk_t *packet,telephone_event_t **tab) +{ + int datasize; + gint num; + int i; + telephone_event_t *tev; + rtp_header_t *hdr=(rtp_header_t*)packet->b_rptr; + g_return_val_if_fail(packet->b_cont!=NULL,-1); + if (hdr->paytype!=session->telephone_events_pt) return 0; /* this is not tel ev.*/ + datasize=msgdsize(packet); + tev=*tab=(telephone_event_t*)packet->b_cont->b_rptr; + /* convert from network to host order what should be */ + num=datasize/sizeof(telephone_event_t); + for (i=0;ion_telephone_event,(gpointer)(long)events[i].event); + } + } +} + +/* for high level telephony event callback */ +void rtp_session_check_telephone_events(RtpSession *session, mblk_t *m0) +{ + telephone_event_t *events,*evbuf; + int num; + int i; + mblk_t *mp; + rtp_header_t *hdr; + mblk_t *cur_tev; + + hdr=(rtp_header_t*)m0->b_rptr; + mp=m0->b_cont; + + num=(mp->b_wptr-mp->b_rptr)/sizeof(telephone_event_t); + events=(telephone_event_t*)mp->b_rptr; + + + if (hdr->markbit==1) + { + /* this is a start of new events. Store the event buffer for later use*/ + if (session->current_tev!=NULL) { + freemsg(session->current_tev); + session->current_tev=NULL; + } + session->current_tev=copymsg(m0); + /* handle the case where the events are short enough to end within the packet that has the marker bit*/ + notify_events_ended(session,events,num); + } + /* whatever there is a markbit set or not, we parse the packet and compare it to previously received one */ + cur_tev=session->current_tev; + if (cur_tev!=NULL) + { + /* first compare timestamp, they must be identical */ + if (((rtp_header_t*)cur_tev->b_rptr)->timestamp== + ((rtp_header_t*)m0->b_rptr)->timestamp) + { + evbuf=(telephone_event_t*)cur_tev->b_cont; + for (i=0;ion_telephone_event,(gpointer)(long)events[i].event); + } + } + } + } + else + { + /* timestamp are not identical: this is not the same events*/ + if (session->current_tev!=NULL) { + freemsg(session->current_tev); + session->current_tev=NULL; + } + session->current_tev=dupmsg(m0); + } + } + else + { + /* there is no pending events, but we did not received marked bit packet + either the sending implementation is not compliant, either it has been lost, + we must deal with it anyway.*/ + session->current_tev=copymsg(m0); + /* inform the application if there are tone ends */ + notify_events_ended(session,events,num); + } +} -- cgit v1.2.1