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 0
00035 };
00036
00044 int rtp_session_telephone_events_supported(RtpSession *session)
00045 {
00046
00047 session->snd.telephone_events_pt=rtp_profile_get_payload_number_from_mime(session->snd.profile,"telephone-event");
00048 session->rcv.telephone_events_pt=rtp_profile_get_payload_number_from_mime(session->rcv.profile,"telephone-event");
00049
00050 return session->snd.telephone_events_pt;
00051 }
00052
00053
00061 int rtp_session_send_telephone_events_supported(RtpSession *session)
00062 {
00063
00064 session->snd.telephone_events_pt=rtp_profile_get_payload_number_from_mime(session->snd.profile,"telephone-event");
00065
00066 return session->snd.telephone_events_pt;
00067 }
00068 int rtp_session_recv_telephone_events_supported(RtpSession *session)
00076 {
00077
00078 session->rcv.telephone_events_pt=rtp_profile_get_payload_number_from_mime(session->rcv.profile,"telephone-event");
00079
00080 return session->snd.telephone_events_pt;
00081 }
00082
00083
00096 mblk_t *rtp_session_create_telephone_event_packet(RtpSession *session, int start)
00097 {
00098 mblk_t *mp;
00099 rtp_header_t *rtp;
00100
00101 return_val_if_fail(session->snd.telephone_events_pt!=-1,NULL);
00102
00103 mp=allocb(RTP_FIXED_HEADER_SIZE+TELEPHONY_EVENTS_ALLOCATED_SIZE,BPRI_MED);
00104 if (mp==NULL) return NULL;
00105 rtp=(rtp_header_t*)mp->b_rptr;
00106 rtp->version = 2;
00107 rtp->markbit=start;
00108 rtp->padbit = 0;
00109 rtp->extbit = 0;
00110 rtp->cc = 0;
00111 rtp->ssrc = session->snd.ssrc;
00112
00113
00114
00115
00116 rtp->paytype=session->snd.telephone_events_pt;
00117
00118
00119 mp->b_wptr+=RTP_FIXED_HEADER_SIZE;
00120 return mp;
00121 }
00122
00123
00137 int rtp_session_add_telephone_event(RtpSession *session,
00138 mblk_t *packet, uint8_t event, int end, uint8_t volume, uint16_t duration)
00139 {
00140 mblk_t *mp=packet;
00141 telephone_event_t *event_hdr;
00142
00143
00144
00145 while(mp->b_cont!=NULL) mp=mp->b_cont;
00146
00147 if ( ( mp->b_wptr) >= (mp->b_datap->db_lim)){
00148 mblk_t *newm=allocb(TELEPHONY_EVENTS_ALLOCATED_SIZE,BPRI_MED);
00149 mp->b_cont=newm;
00150 mp=mp->b_cont;
00151 }
00152 if (mp==NULL) return -1;
00153 event_hdr=(telephone_event_t*)mp->b_wptr;
00154 event_hdr->event=event;
00155 event_hdr->R=0;
00156 event_hdr->E=end;
00157 event_hdr->volume=volume;
00158 event_hdr->duration=htons(duration);
00159 mp->b_wptr+=sizeof(telephone_event_t);
00160 return 0;
00161 }
00173 int rtp_session_send_dtmf(RtpSession *session, char dtmf, uint32_t userts)
00174 {
00175 return rtp_session_send_dtmf2(session, dtmf, userts, 480);
00176 }
00177
00187 int rtp_session_send_dtmf2(RtpSession *session, char dtmf, uint32_t userts, int duration)
00188 {
00189 mblk_t *m1,*m2,*m3;
00190 int tev_type;
00191 int durationtier = duration/3;
00192
00193
00194 switch (dtmf){
00195 case '1':
00196 tev_type=TEV_DTMF_1;
00197 break;
00198 case '2':
00199 tev_type=TEV_DTMF_2;
00200 break;
00201 case '3':
00202 tev_type=TEV_DTMF_3;
00203 break;
00204 case '4':
00205 tev_type=TEV_DTMF_4;
00206 break;
00207 case '5':
00208 tev_type=TEV_DTMF_5;
00209 break;
00210 case '6':
00211 tev_type=TEV_DTMF_6;
00212 break;
00213 case '7':
00214 tev_type=TEV_DTMF_7;
00215 break;
00216 case '8':
00217 tev_type=TEV_DTMF_8;
00218 break;
00219 case '9':
00220 tev_type=TEV_DTMF_9;
00221 break;
00222 case '*':
00223 tev_type=TEV_DTMF_STAR;
00224 break;
00225 case '0':
00226 tev_type=TEV_DTMF_0;
00227 break;
00228 case '#':
00229 tev_type=TEV_DTMF_POUND;
00230 break;
00231
00232 case 'A':
00233 case 'a':
00234 tev_type=TEV_DTMF_A;
00235 break;
00236
00237
00238 case 'B':
00239 case 'b':
00240 tev_type=TEV_DTMF_B;
00241 break;
00242
00243 case 'C':
00244 case 'c':
00245 tev_type=TEV_DTMF_C;
00246 break;
00247
00248 case 'D':
00249 case 'd':
00250 tev_type=TEV_DTMF_D;
00251 break;
00252
00253 case '!':
00254 tev_type=TEV_FLASH;
00255 break;
00256
00257
00258 default:
00259 ortp_warning("Bad dtmf: %c.",dtmf);
00260 return -1;
00261 }
00262
00263 m1=rtp_session_create_telephone_event_packet(session,1);
00264 if (m1==NULL) return -1;
00265 rtp_session_add_telephone_event(session,m1,tev_type,0,10,durationtier);
00266
00267 m2=rtp_session_create_telephone_event_packet(session,0);
00268 if (m2==NULL) return -1;
00269 rtp_session_add_telephone_event(session,m2,tev_type,0,10, durationtier+durationtier);
00270
00271
00272 m3=rtp_session_create_telephone_event_packet(session,0);
00273 if (m3==NULL) return -1;
00274 rtp_session_add_telephone_event(session,m3,tev_type,1,10,duration);
00275
00276
00277 rtp_session_sendm_with_ts(session,m1,userts);
00278 rtp_session_sendm_with_ts(session,m2,userts);
00279
00280 m1=copymsg(m3);
00281 m2=copymsg(m3);
00282
00283
00284
00285
00286
00287 rtp_session_sendm_with_ts(session,m3,userts);
00288 session->rtp.snd_seq--;
00289 rtp_session_sendm_with_ts(session,m1,userts);
00290 session->rtp.snd_seq--;
00291 rtp_session_sendm_with_ts(session,m2,userts);
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=copymsg(m0);
00405 notify_events_ended(session,events,num);
00406 }
00407 }
00408 else
00409 {
00410
00411
00412
00413 session->current_tev=copymsg(m0);
00414
00415 notify_events_ended(session,events,num);
00416 }
00417 }