使用eXsip和ORTP通话(一)

#include "stdafx.h"     
#include "YouToo.h"     
#include "YouTooDlg.h"     
     
#define WAIT_TIMER 200                   //事件检测时间间隔ms     
#define REG_TIMER   30*1000           //注册时间间隔ms     
     
bool build_media(int local_port, const char *remote_ip,       
                                 int remote_port, int payload, const char *fmtp, int jitter, bool ec, int bitrate);     
     
CYouTooDlg *dlg_wnd = NULL;     
     
AudioStream *audio = NULL;     
RtpProfile *profile = NULL;     
RtpSession *session = NULL;     
OrtpEvQueue *q = NULL;     

#ifdef _DEBUG     
#define new DEBUG_NEW     
#undef THIS_FILE     
static char THIS_FILE[] = __FILE__;     
#endif     

#define DEBUG_INFO debug_info->AddString     

UINT sip_ua_monitor(void *pArg)     
   
       bool ret = false;     
       char *payload_str;                                        
       char localip[128];     
       char tmp[4096];         

       CString dtmf_str;     
       char dtmf[50] = {0};       

       int reg_remain = REG_TIMER;       

       CYouTooDlg *pMainWnd = (CYouTooDlg *)pArg;     
       CListBox *debug_info = ((CListBox *)pMainWnd->GetDlgItem(IDC_INFO));       

       DEBUG_INFO("Event monitor for ua[c|s] start!");       

       eXosip_event_t *uac_e;                                
       osip_message_t *ack = NULL;                      
       osip_message_t *answer = NULL;                  

            
       sdp_message_t * msg_rsp = NULL;     
       sdp_connection_t * con_rsp = NULL;     
       sdp_media_t * md_rsp = NULL;     
     
            
       sdp_message_t * msg_req = NULL;     
       sdp_connection_t * con_req = NULL;     
       sdp_media_t * md_req = NULL;       

       char out_str[100] = {0};       

       eXosip_lock ();     
       eXosip_automatic_action();     
       eXosip_unlock ();       

       while(pMainWnd->doing)     
       {     
               eXosip_lock ();     
               uac_e = eXosip_event_wait (0, WAIT_TIMER);     
               eXosip_unlock ();       

               reg_remain = reg_remain - WAIT_TIMER;     
               if(reg_remain < 0)     
               {     
                       //超时,重新注册     
                       eXosip_lock ();     
                       eXosip_automatic_refresh();     
                       eXosip_unlock ();     
                       reg_remain = REG_TIMER;     
                       DEBUG_INFO("register timeout,retry!");     
               }     
     
               if(pMainWnd->dtmfing)     
               {                   
                       ((CEdit *)pMainWnd->GetDlgItem(IDC_DTMF_STR))->GetWindowText(dtmf_str);     
                       strcpy(dtmf, dtmf_str.GetBuffer(dtmf_str.GetLength()));       
     
                       for(int index=0; index<50; index++)     
                       {     
                               //依次读取字符     
                               if(dtmf[index] == '\0') break;     
                                     
                                    
                               eXosip_lock();     
                               audio_stream_send_dtmf(audio, dtmf[index]);     
                               eXosip_unlock();     
     
                               sprintf(out_str, "DTMF send <%c> OK!", dtmf[index]);     
                               DEBUG_INFO(out_str);     
                               Sleep(500);     
                       }       

                       pMainWnd->dtmfing = false;     
               }       

               if (uac_e == NULL)     
               {     
                       //DEBUG_INFO("nothing");     
                       continue;     
               }       

               eXosip_lock ();     
               eXosip_default_action(uac_e);          
               eXosip_unlock ();     
     
               if(NULL != uac_e->response)     
               {     
                       //UAC 消息处理前检查     
                       sprintf(out_str, "%d %s", uac_e->response->status_code, uac_e->response->reason_phrase);     
                       DEBUG_INFO(out_str);       
                       if(487 == uac_e->response->status_code)     
                       {     
                               pMainWnd->GetDlgItem(IDC_CALL_STATUS)->SetWindowText("(取消呼叫成功)");     
                               pMainWnd->GetDlgItem(IDC_DIAL)->EnableWindow(true);                                   
                               pMainWnd->GetDlgItem(IDC_HANG)->EnableWindow(false);     
                               continue;     
                       }       

                       if(480 == uac_e->response->status_code)     
                       {     
                               //480 无应答     
                               pMainWnd->GetDlgItem(IDC_DIAL)->EnableWindow(true);           
                               pMainWnd->GetDlgItem(IDC_ACCEPT)->EnableWindow(true);       
                               pMainWnd->GetDlgItem(IDC_HANG)->EnableWindow(false);                                 
                               pMainWnd->GetDlgItem(IDC_CALL_STATUS)->SetWindowText("(无应答)");     
                                     
                               //隐藏接通按钮显示呼叫按钮     
                               ((CButton *)pMainWnd->GetDlgItem(IDC_ACCEPT))->ShowWindow(SW_HIDE);     
                               ((CButton *)pMainWnd->GetDlgItem(IDC_DIAL))->ShowWindow(SW_SHOWNORMAL);     
                                     
                               pMainWnd->picked = false;     
                               pMainWnd->calling = false;     
                               pMainWnd->call_id = 0;     
                               pMainWnd->dialog_id = 0;                               
                               continue;     
                       }     
               }       

               if(NULL != uac_e->request)     
               {     
               }     
     
               if(NULL != uac_e->ack)     
               {     
               }     
                     
               switch (uac_e->type)     
               {     
                       case EXOSIP_CALL_SERVERFAILURE:     
                       case EXOSIP_CALL_RELEASED:     
                                    
                               pMainWnd->GetDlgItem(IDC_DIAL)->EnableWindow(true);           
                               pMainWnd->GetDlgItem(IDC_ACCEPT)->EnableWindow(true);       
                               pMainWnd->GetDlgItem(IDC_HANG)->EnableWindow(false);                                 
                               pMainWnd->GetDlgItem(IDC_CALL_STATUS)->SetWindowText("(对方或服务器正忙!)");     
                                     
                               //隐藏接通按钮显示呼叫按钮     
                               ((CButton *)pMainWnd->GetDlgItem(IDC_ACCEPT))->ShowWindow(SW_HIDE);     
                               ((CButton *)pMainWnd->GetDlgItem(IDC_DIAL))->ShowWindow(SW_SHOWNORMAL);     
                                     
                               pMainWnd->call_id = 0;     
                               pMainWnd->dialog_id = 0;     
                               pMainWnd->picked = false;     
                               pMainWnd->calling = false;     
                                     
                               DEBUG_INFO("Dest or Server Busy!");     
                               break;     
     
                            
                       case EXOSIP_CALL_INVITE:     
                               sprintf(out_str, "收到来自 %s 的呼叫!",uac_e->request->from->url->string);     
                               pMainWnd->GetDlgItem(IDC_CALL_STATUS)->SetWindowText(out_str);     
     
                               eXosip_lock ();     
                               eXosip_call_send_answer(uac_e->tid, 180, NULL);     
                               if(0 != eXosip_call_build_answer(uac_e->tid, 200, &answer))     
                               {     
                                       eXosip_call_send_answer(uac_e->tid, 603, NULL);     
                                       AfxMessageBox("error build answer!");     
                                       continue;     
                               }     
                               eXosip_unlock ();     
                                     
                               pMainWnd->call_id = uac_e->cid;                                    //供挂断电话上下文操作     
                               pMainWnd->dialog_id = uac_e->did;     
     
                                    
                               eXosip_guess_localip(AF_INET, localip, 128);     
                               snprintf (tmp, 4096,     
                                       "v=0\r\n"     
                                       "o=youtoo 1 1 IN IP4 %s\r\n"     
                                       "s=##youtoo demo\r\n"     
                                       "c=IN IP4 %s\r\n"     
                                       "t=0 0\r\n"     
                                       "m=audio %d RTP/AVP 0 8 101\r\n"     
                                       "a=rtpmap:0 PCMU/8000\r\n"     
                                       "a=rtpmap:8 PCMA/8000\r\n"     
                                       "a=rtpmap:101 telephone-event/8000\r\n"     
                                       "a=fmtp:101 0-15\r\n", localip, localip, pMainWnd->rtp_port);     
                                     
                               //设置回复的SDP消息体,下一步计划分析消息体     
                               eXosip_lock ();     
                               osip_message_set_body(answer, tmp, strlen(tmp));     
                               osip_message_set_content_type(answer, "application/sdp");     
                                     
                                    
                               msg_req = eXosip_get_remote_sdp(uac_e->did);     
                               con_req = eXosip_get_audio_connection(msg_req);     
                               md_req = eXosip_get_audio_media(msg_req);     
                               eXosip_unlock ();     
                                     
                                    
                                     
                               //隐藏呼叫按钮显示接听按钮     
                               ((CButton *)pMainWnd->GetDlgItem(IDC_ACCEPT))->ShowWindow(SW_SHOWNORMAL);     
                               ((CButton *)pMainWnd->GetDlgItem(IDC_DIAL))->ShowWindow(SW_HIDE);     
                               pMainWnd->GetDlgItem(IDC_HANG)->EnableWindow(true);     
     
                               pMainWnd->calling = true;     
     
                               while(!pMainWnd->picked)     
                               {     
                                       //未接通进入循环检测     
                                       Sleep(200);     
                               }     
     
                               eXosip_unlock ();     
                               eXosip_call_send_answer(uac_e->tid, 200, answer);     
                               eXosip_unlock ();     
     
                               DEBUG_INFO("200 ok 发送");     
                               break;     
     
                       case EXOSIP_CALL_CANCELLED:     
                                    
                               //隐藏接通按钮显示呼叫按钮     
                               ((CButton *)pMainWnd->GetDlgItem(IDC_ACCEPT))->ShowWindow(SW_HIDE);     
                               ((CButton *)pMainWnd->GetDlgItem(IDC_DIAL))->ShowWindow(SW_SHOWNORMAL);     
                                     
                               pMainWnd->call_id = 0;     
                               pMainWnd->dialog_id = 0;                               
                               pMainWnd->picked = false;     
                               pMainWnd->calling = false;     
                               pMainWnd->GetDlgItem(IDC_REG_STATUS)->SetWindowText("(已拒绝)");     
                               break;     
     
                       case EXOSIP_CALL_ACK:     
                                    
                               if(pMainWnd->calling)     
                               {     
                                            
                                       ret = build_media(pMainWnd->rtp_port, con_req->c_addr, atoi(md_req->m_port), 0, NULL, 0, 0, 0);     
                                       if(!ret)     
                                       {     
                                               AfxMessageBox("媒体建立失败,无法创建通话,请挂断!");     
                                               //pMainWnd->OnHang();     
                                       }                                   
                               }     
                               break;     
     
                            
                       case EXOSIP_REGISTRATION_SUCCESS:     
                               if(0 < uac_e->response->contacts.nb_elt)          
                               {     
                                       pMainWnd->GetDlgItem(IDC_REG_STATUS)->SetWindowText("(已登录)");     
                                       pMainWnd->GetDlgItem(IDC_REG)->EnableWindow(false);     
                                       pMainWnd->GetDlgItem(IDC_UNREG)->EnableWindow(true);     
     
                                       if(0 == pMainWnd->call_id)     
                                       {     
                                               //第一次手动注册成功时     
                                               pMainWnd->GetDlgItem(IDC_DIAL)->EnableWindow(true);     
                                       }     
                               }     
                               else     
                               {     
                                       pMainWnd->GetDlgItem(IDC_REG_STATUS)->SetWindowText("(已注销)");     
                                       pMainWnd->GetDlgItem(IDC_REG)->EnableWindow(true);     
                                       pMainWnd->GetDlgItem(IDC_UNREG)->EnableWindow(false);     
                                       pMainWnd->GetDlgItem(IDC_DIAL)->EnableWindow(false);     
                                       pMainWnd->GetDlgItem(IDC_HANG)->EnableWindow(false);     
                               }     
                               break;     
     
                       case EXOSIP_CALL_CLOSED:     
                               if(audio)       
                               {     
                                       //被动关闭媒体连接(远端触发)     
                                       eXosip_lock ();     
                                       audio_stream_stop(audio);     
                                             
                                       ortp_ev_queue_destroy(q);     
                                       rtp_profile_destroy(profile);     
                                       eXosip_unlock ();     
     
                                       audio = NULL;     
                                       q = NULL;     
                                       profile = NULL;     
                                       DEBUG_INFO("audio stream stoped!");     
                               }     
     
                               pMainWnd->GetDlgItem(IDC_CALL_STATUS)->SetWindowText("(对方已挂断)");     
                               pMainWnd->GetDlgItem(IDC_DIAL)->EnableWindow(true);           
                               pMainWnd->GetDlgItem(IDC_ACCEPT)->EnableWindow(true);       
                               pMainWnd->GetDlgItem(IDC_HANG)->EnableWindow(false);                                 
     
                               //隐藏接通按钮显示呼叫按钮     
                               ((CButton *)pMainWnd->GetDlgItem(IDC_ACCEPT))->ShowWindow(SW_HIDE);     
                               ((CButton *)pMainWnd->GetDlgItem(IDC_DIAL))->ShowWindow(SW_SHOWNORMAL);     
                                     
                               pMainWnd->call_id = 0;     
                               pMainWnd->dialog_id = 0;                               
                               pMainWnd->picked = false;     
                               pMainWnd->calling = false;     
                               break;     
                                     
                       case EXOSIP_CALL_PROCEEDING:     
                               pMainWnd->GetDlgItem(IDC_CALL_STATUS)->SetWindowText("(查找连接中..)");     
                               pMainWnd->GetDlgItem(IDC_DIAL)->EnableWindow(false);                                 
                               break;     
     
                       case EXOSIP_CALL_RINGING:     
                               pMainWnd->GetDlgItem(IDC_CALL_STATUS)->SetWindowText("(对方振铃)");     
                               pMainWnd->GetDlgItem(IDC_HANG)->EnableWindow(true);                           
                               pMainWnd->call_id = uac_e->cid;     
                               pMainWnd->dialog_id = uac_e->did;     
     
                                    
                               break;     
                                     
                       case EXOSIP_CALL_ANSWERED:     
                               //ring_stop(ring_p);                                     
                               pMainWnd->GetDlgItem(IDC_CALL_STATUS)->SetWindowText("(对方已接听)");     
                               pMainWnd->GetDlgItem(IDC_DIAL)->EnableWindow(false);                                 
                               pMainWnd->GetDlgItem(IDC_HANG)->EnableWindow(true);                   
                                     
                               pMainWnd->call_id = uac_e->cid;     
                               pMainWnd->dialog_id = uac_e->did;     
                                     
                               eXosip_lock ();     
                               eXosip_call_build_ack (uac_e->did, &ack);     
                               eXosip_call_send_ack (uac_e->did, ack);     
     
                                    
                               msg_rsp = eXosip_get_sdp_info(uac_e->response);     
                               con_rsp = eXosip_get_audio_connection(msg_rsp);     
                               md_rsp = eXosip_get_audio_media(msg_rsp);     
     
                                    
                               payload_str = (char *)osip_list_get(&md_rsp->m_payloads, 0);     
                               eXosip_unlock ();     
     
                                    
                               ret = build_media(pMainWnd->rtp_port, con_rsp->c_addr, atoi(md_rsp->m_port), atoi(payload_str), NULL, 0, 0, 0);     
                               if(!ret)     
                               {     
                                       AfxMessageBox("媒体建立失败,无法创建通话,请挂断!");     
                                       //pMainWnd->OnHang();     
                               }     
                               break;     
     
                       default:     
                               break;     
               }     
                     
               eXosip_event_free (uac_e);     
     
                    
               debug_info->SetCurSel(debug_info->GetCount()-1);     
       }     
             
       return 0;     
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值