00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <ortp/telephonyevents.h>
00021 #include "utils.h"
00022 #include "rtpsession_priv.h"
00023 #include <ortp/ortp.h>
00024
00025 PayloadType payload_type_telephone_event={
00026 PAYLOAD_AUDIO_PACKETIZED,
00027 8000,
00028 0,
00029 NULL,
00030 0,
00031 0,
00032 "telephone-event",
00033 0
00034 };
00035
00043 int rtp_session_telephone_events_supported(RtpSession *session)
00044 {
00045
00046 session->snd.telephone_events_pt=rtp_profile_get_payload_number_from_mime(session->snd.profile,"telephone-event");
00047 session->rcv.telephone_events_pt=rtp_profile_get_payload_number_from_mime(session->rcv.profile,"telephone-event");
00048
00049 return session->snd.telephone_events_pt;
00050 }
00051
00052
00060 int rtp_session_send_telephone_events_supported(RtpSession *session)
00061 {
00062
00063 session->snd.telephone_events_pt=rtp_profile_get_payload_number_from_mime(session->snd.profile,"telephone-event");
00064
00065 return session->snd.telephone_events_pt;
00066 }
00067 int rtp_session_recv_telephone_events_supported(RtpSession *session)
00075 {
00076
00077 session->rcv.telephone_events_pt=rtp_profile_get_payload_number_from_mime(session->rcv.profile,"telephone-event");
00078
00079 return session->snd.telephone_events_pt;
00080 }
00081
00082
00095 mblk_t *rtp_session_create_telephone_event_packet(RtpSession *session, int start)
00096 {
00097 mblk_t *mp;
00098 rtp_header_t *rtp;
00099
00100 return_val_if_fail(session->snd.telephone_events_pt!=-1,NULL);
00101
00102 mp=allocb(RTP_FIXED_HEADER_SIZE+TELEPHONY_EVENTS_ALLOCATED_SIZE,BPRI_MED);
00103 if (mp==NULL) return NULL;
00104 rtp=(rtp_header_t*)mp->b_rptr;
00105 rtp->version = 2;
00106 rtp->markbit=start;
00107 rtp->padbit = 0;
00108 rtp->extbit = 0;
00109 rtp->cc = 0;
00110 rtp->ssrc = session->snd.ssrc;
00111
00112
00113
00114
00115 rtp->paytype=session->snd.telephone_events_pt;
00116
00117
00118 mp->b_wptr+=RTP_FIXED_HEADER_SIZE;
00119 return mp;
00120 }
00121
00122
00136 int rtp_session_add_telephone_event(RtpSession *session,
00137 mblk_t *packet, uint8_t event, int end, uint8_t volume, uint16_t duration)
00138 {
00139 mblk_t *mp=packet;
00140 telephone_event_t *event_hdr;
00141
00142
00143
00144 while(mp->b_cont!=NULL) mp=mp->b_cont;
00145
00146 if ( ( mp->b_wptr) >= (mp->b_datap->db_lim)){
00147 mblk_t *newm=allocb(TELEPHONY_EVENTS_ALLOCATED_SIZE,BPRI_MED);
00148 mp->b_cont=newm;
00149 mp=mp->b_cont;
00150 }
00151 if (mp==NULL) return -1;
00152 event_hdr=(telephone_event_t*)mp->b_wptr;
00153 event_hdr->event=event;
00154 event_hdr->R=0;
00155 event_hdr->E=end;
00156 event_hdr->volume=volume;
00157 event_hdr->duration=htons(duration);
00158 mp->b_wptr+=sizeof(telephone_event_t);
00159 return 0;
00160 }
00172 int rtp_session_send_dtmf(RtpSession *session, char dtmf, uint32_t userts)
00173 {
00174 return rtp_session_send_dtmf2(session, dtmf, userts, 480);
00175 }
00176
00186 int rtp_session_send_dtmf2(RtpSession *session, char dtmf, uint32_t userts, int duration)
00187 {
00188 mblk_t *m1,*m2,*m3;
00189 int tev_type;
00190 int durationtier = duration/3;
00191
00192
00193 switch (dtmf){
00194 case '1':
00195 tev_type=TEV_DTMF_1;
00196 break;
00197 case '2':
00198 tev_type=TEV_DTMF_2;
00199 break;
00200 case '3':
00201 tev_type=TEV_DTMF_3;
00202 break;
00203 case '4':
00204 tev_type=TEV_DTMF_4;
00205 break;
00206 case '5':
00207 tev_type=TEV_DTMF_5;
00208 break;
00209 case '6':
00210 tev_type=TEV_DTMF_6;
00211 break;
00212 case '7':
00213 tev_type=TEV_DTMF_7;
00214 break;
00215 case '8':
00216 tev_type=TEV_DTMF_8;
00217 break;
00218 case '9':
00219 tev_type=TEV_DTMF_9;
00220 break;
00221 case '*':
00222 tev_type=TEV_DTMF_STAR;
00223 break;
00224 case '0':
00225 tev_type=TEV_DTMF_0;
00226 break;
00227 case '#':
00228 tev_type=TEV_DTMF_POUND;
00229 break;
00230
00231 case 'A':
00232 case 'a':
00233 tev_type=TEV_DTMF_A;
00234 break;
00235
00236
00237 case 'B':
00238 case 'b':
00239 tev_type=TEV_DTMF_B;
00240 break;
00241
00242 case 'C':
00243 case 'c':
00244 tev_type=TEV_DTMF_C;
00245 break;
00246
00247 case 'D':
00248 case 'd':
00249 tev_type=TEV_DTMF_D;
00250 break;
00251
00252 case '!':
00253 tev_type=TEV_FLASH;
00254 break;
00255
00256
00257 default:
00258 ortp_warning("Bad dtmf: %c.",dtmf);
00259 return -1;
00260 }
00261
00262 m1=rtp_session_create_telephone_event_packet(session,1);
00263 if (m1==NULL) return -1;
00264 rtp_session_add_telephone_event(session,m1,tev_type,0,10,durationtier);
00265
00266 m2=rtp_session_create_telephone_event_packet(session,0);
00267 if (m2==NULL) return -1;
00268 rtp_session_add_telephone_event(session,m2,tev_type,0,10, durationtier+durationtier);
00269
00270
00271 m3=rtp_session_create_telephone_event_packet(session,0);
00272 if (m3==NULL) return -1;
00273 rtp_session_add_telephone_event(session,m3,tev_type,1,10,duration);
00274
00275
00276 rtp_session_sendm_with_ts(session,m1,userts);
00277 rtp_session_sendm_with_ts(session,m2,userts+durationtier);
00278
00279 m1=copymsg(m3);
00280 m2=copymsg(m3);
00281
00282
00283
00284
00285
00286
00287
00288
00289 rtp_session_sendm_with_ts(session,m3,userts+durationtier+durationtier);
00290 rtp_session_sendm_with_ts(session,m1,userts+durationtier+durationtier);
00291 rtp_session_sendm_with_ts(session,m2,userts+durationtier+durationtier);
00292 return 0;
00293 }
00294
00295
00304 int rtp_session_read_telephone_event(RtpSession *session,
00305 mblk_t *packet,telephone_event_t **tab)
00306 {
00307 int datasize;
00308 int num;
00309 int i;
00310 telephone_event_t *tev;
00311 rtp_header_t *hdr=(rtp_header_t*)packet->b_rptr;
00312 return_val_if_fail(packet->b_cont!=NULL,-1);
00313 if (hdr->paytype!=session->rcv.telephone_events_pt) return 0;
00314 datasize=msgdsize(packet);
00315 tev=*tab=(telephone_event_t*)packet->b_cont->b_rptr;
00316
00317 num=datasize/sizeof(telephone_event_t);
00318 for (i=0;i<num;i++)
00319 {
00320 tev[i].duration=ntohs(tev[i].duration);
00321 }
00322 return num;
00323 }
00324
00325 static void notify_tev(RtpSession *session, telephone_event_t *event){
00326 OrtpEvent *ev;
00327 OrtpEventData *evd;
00328 rtp_signal_table_emit2(&session->on_telephone_event,(long)(long)event[0].event);
00329 if (session->eventqs!=NULL){
00330 ev=ortp_event_new(ORTP_EVENT_TELEPHONE_EVENT);
00331 evd=ortp_event_get_data(ev);
00332 evd->packet=dupmsg(session->current_tev);
00333 evd->info.telephone_event=event[0].event;
00334 rtp_session_dispatch_event(session,ev);
00335 }
00336 }
00337
00338 static void notify_events_ended(RtpSession *session, telephone_event_t *events, int num){
00339 int i;
00340 for (i=0;i<num;i++){
00341 if (events[i].E==1){
00342 notify_tev(session, &events[i]);
00343 }
00344 }
00345 }
00346
00347
00348 void rtp_session_check_telephone_events(RtpSession *session, mblk_t *m0)
00349 {
00350 telephone_event_t *events,*evbuf;
00351 int num;
00352 int i;
00353 mblk_t *mp;
00354 rtp_header_t *hdr;
00355 mblk_t *cur_tev;
00356
00357 hdr=(rtp_header_t*)m0->b_rptr;
00358 mp=m0->b_cont;
00359
00360 num=((int)(mp->b_wptr-mp->b_rptr))/sizeof(telephone_event_t);
00361 events=(telephone_event_t*)mp->b_rptr;
00362
00363
00364 if (hdr->markbit==1)
00365 {
00366
00367 if (session->current_tev!=NULL) {
00368 freemsg(session->current_tev);
00369 session->current_tev=NULL;
00370 }
00371 session->current_tev=copymsg(m0);
00372
00373 notify_events_ended(session,events,num);
00374 }
00375
00376 cur_tev=session->current_tev;
00377 if (cur_tev!=NULL)
00378 {
00379
00380 if (((rtp_header_t*)cur_tev->b_rptr)->timestamp==
00381 ((rtp_header_t*)m0->b_rptr)->timestamp)
00382 {
00383 evbuf=(telephone_event_t*)cur_tev->b_cont;
00384 for (i=0;i<num;i++)
00385 {
00386 if (events[i].E==1)
00387 {
00388
00389 if (evbuf[i].E==0){
00390 evbuf[i].E=1;
00391
00392 notify_tev(session,&events[i]);
00393 }
00394 }
00395 }
00396 }
00397 else
00398 {
00399
00400 if (session->current_tev!=NULL) {
00401 freemsg(session->current_tev);
00402 session->current_tev=NULL;
00403 }
00404 session->current_tev=dupmsg(m0);
00405 }
00406 }
00407 else
00408 {
00409
00410
00411
00412 session->current_tev=copymsg(m0);
00413
00414 notify_events_ended(session,events,num);
00415 }
00416 }