#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;
}
#include "YouToo.h"
#include "YouTooDlg.h"
#define WAIT_TIMER 200
#define REG_TIMER
bool build_media(int local_port, const char *remote_ip,
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)
{
}