| // PocketPJDlg.cpp : implementation file |
| // |
| |
| #include "stdafx.h" |
| #include "PocketPJ.h" |
| #include "PocketPJDlg.h" |
| #include <iphlpapi.h> |
| |
| #ifdef _DEBUG |
| #define new DEBUG_NEW |
| #undef THIS_FILE |
| static char THIS_FILE[] = __FILE__; |
| #endif |
| |
| #define TIMER_ID 101 |
| static CPocketPJDlg *theDlg; |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| // CPocketPJDlg dialog |
| |
| CPocketPJDlg::CPocketPJDlg(CWnd* pParent /*=NULL*/) |
| : CDialog(CPocketPJDlg::IDD, pParent), m_PopUp(NULL) |
| { |
| //{{AFX_DATA_INIT(CPocketPJDlg) |
| // NOTE: the ClassWizard will add member initialization here |
| //}}AFX_DATA_INIT |
| // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 |
| m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); |
| |
| theDlg = this; |
| |
| m_PopUp = new CPopUpWnd(this); |
| m_PopUp->Hide(); |
| |
| unsigned i; |
| m_PopUpCount = 0; |
| for (i=0; i<POPUP_MAX_TYPE; ++i) { |
| m_PopUpState[i] = FALSE; |
| } |
| } |
| |
| void CPocketPJDlg::DoDataExchange(CDataExchange* pDX) |
| { |
| CDialog::DoDataExchange(pDX); |
| //{{AFX_DATA_MAP(CPocketPJDlg) |
| DDX_Control(pDX, IDC_URL, m_Url); |
| DDX_Control(pDX, IDC_BUDDY_LIST, m_BuddyList); |
| DDX_Control(pDX, IDC_BTN_ACTION, m_BtnUrlAction); |
| DDX_Control(pDX, IDC_BTN_ACC, m_BtnAcc); |
| DDX_Control(pDX, IDC_ACC_ID, m_AccId); |
| //}}AFX_DATA_MAP |
| } |
| |
| BEGIN_MESSAGE_MAP(CPocketPJDlg, CDialog) |
| //{{AFX_MSG_MAP(CPocketPJDlg) |
| ON_BN_CLICKED(IDC_BTN_ACC, OnBtnAcc) |
| ON_BN_CLICKED(IDC_BTN_ACTION, OnBtnAction) |
| ON_COMMAND(IDC_ACC_SETTINGS, OnSettings) |
| ON_COMMAND(IDC_URI_CALL, OnUriCall) |
| ON_WM_TIMER() |
| ON_COMMAND(IDC_URI_ADD_BUDDY, OnUriAddBuddy) |
| ON_COMMAND(IDC_URI_DEL_BUDDY, OnUriDelBuddy) |
| ON_COMMAND(IDC_ACC_ONLINE, OnAccOnline) |
| ON_COMMAND(IDC_ACC_INVISIBLE, OnAccInvisible) |
| ON_NOTIFY(NM_CLICK, IDC_BUDDY_LIST, OnClickBuddyList) |
| //}}AFX_MSG_MAP |
| END_MESSAGE_MAP() |
| |
| |
| void CPocketPJDlg::Error(const CString &title, pj_status_t rc) |
| { |
| char errmsg[PJ_ERR_MSG_SIZE]; |
| wchar_t werrmsg[PJ_ERR_MSG_SIZE]; |
| |
| pj_strerror(rc, errmsg, sizeof(errmsg)); |
| pj_ansi_to_unicode(errmsg, strlen(errmsg), werrmsg, PJ_ARRAY_SIZE(werrmsg)); |
| |
| AfxMessageBox(title + _T(": ") + werrmsg); |
| } |
| |
| BOOL CPocketPJDlg::Restart() |
| { |
| pj_status_t status; |
| |
| char ver[80]; |
| sprintf(ver, "PocketPJ/%s", pj_get_version()); |
| |
| ShowWindow(SW_SHOW); |
| PopUp_Show(POPUP_REGISTRATION, ver, |
| "Starting up....", "", "", "", 0); |
| |
| KillTimer(TIMER_ID); |
| |
| // Destroy first. |
| PopUp_Modify(POPUP_REGISTRATION, POPUP_EL_TITLE3, "Cleaning up.."); |
| pjsua_destroy(); |
| |
| m_BtnAcc.SetBitmap(::LoadBitmap(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_OFFLINE)) ); |
| UpdateWindow(); |
| |
| |
| // Create |
| PopUp_Show(POPUP_REGISTRATION, ver, |
| "Starting up....", "Creating stack..", "", "", 0); |
| |
| status = pjsua_create(); |
| if (status != PJ_SUCCESS) { |
| Error(_T("Error in creating library"), status); |
| PopUp_Hide(POPUP_REGISTRATION); |
| return FALSE; |
| } |
| |
| pjsua_config cfg; |
| pjsua_logging_config log_cfg; |
| pjsua_media_config media_cfg; |
| |
| pjsua_config_default(&cfg); |
| cfg.max_calls = 1; |
| cfg.thread_cnt = 0; |
| cfg.user_agent = pj_str(ver); |
| |
| cfg.cb.on_call_state = &on_call_state; |
| cfg.cb.on_call_media_state = &on_call_media_state; |
| cfg.cb.on_incoming_call = &on_incoming_call; |
| cfg.cb.on_reg_state = &on_reg_state; |
| cfg.cb.on_buddy_state = &on_buddy_state; |
| cfg.cb.on_pager = &on_pager; |
| |
| /* Configure nameserver */ |
| char nameserver[60]; |
| { |
| FIXED_INFO fi; |
| ULONG len = sizeof(fi); |
| CString err; |
| |
| PopUp_Modify(POPUP_REGISTRATION, POPUP_EL_TITLE3, "Retrieving network parameters.."); |
| if (GetNetworkParams(&fi, &len) != ERROR_SUCCESS) { |
| err = _T("Info: Error querying network parameters. You must configure DNS server."); |
| } else if (fi.CurrentDnsServer == NULL) { |
| err = _T("Info: DNS server not configured. You must configure DNS server."); |
| } |
| |
| if (err.GetLength()) { |
| if (m_Cfg.m_DNS.GetLength()) { |
| pj_unicode_to_ansi((LPCTSTR)m_Cfg.m_DNS, m_Cfg.m_DNS.GetLength(), |
| nameserver, sizeof(nameserver)); |
| cfg.nameserver_count = 1; |
| cfg.nameserver[0] = pj_str(nameserver); |
| } else { |
| AfxMessageBox(err); |
| pjsua_destroy(); |
| PopUp_Hide(POPUP_REGISTRATION); |
| return FALSE; |
| } |
| } else { |
| strcpy(nameserver, fi.CurrentDnsServer->IpAddress.String); |
| cfg.nameserver_count = 1; |
| cfg.nameserver[0] = pj_str(nameserver); |
| } |
| } |
| |
| char tmp_stun[80]; |
| if (m_Cfg.m_UseStun) { |
| pj_unicode_to_ansi((LPCTSTR)m_Cfg.m_StunSrv, m_Cfg.m_StunSrv.GetLength(), |
| tmp_stun, sizeof(tmp_stun)); |
| cfg.stun_host = pj_str(tmp_stun); |
| } |
| |
| pjsua_logging_config_default(&log_cfg); |
| log_cfg.log_filename = pj_str("\\PocketPJ.TXT"); |
| |
| pjsua_media_config_default(&media_cfg); |
| media_cfg.clock_rate = 8000; |
| media_cfg.audio_frame_ptime = 40; |
| media_cfg.ec_tail_len = 0; |
| media_cfg.ilbc_mode = 30; |
| media_cfg.max_media_ports = 8; |
| media_cfg.quality = 5; |
| media_cfg.thread_cnt = 1; |
| media_cfg.enable_ice = m_Cfg.m_UseIce; |
| |
| if (m_Cfg.m_EchoSuppress) { |
| media_cfg.ec_options = PJMEDIA_ECHO_SIMPLE; |
| media_cfg.ec_tail_len = m_Cfg.m_EcTail; |
| } |
| |
| // Init |
| PopUp_Modify(POPUP_REGISTRATION, POPUP_EL_TITLE3, "Initializing.."); |
| status = pjsua_init(&cfg, &log_cfg, &media_cfg); |
| if (status != PJ_SUCCESS) { |
| Error(_T("Error initializing library"), status); |
| pjsua_destroy(); |
| PopUp_Hide(POPUP_REGISTRATION); |
| return FALSE; |
| } |
| |
| // Create one UDP transport |
| PopUp_Modify(POPUP_REGISTRATION, POPUP_EL_TITLE3, "Add transport.."); |
| pjsua_transport_id transport_id; |
| pjsua_transport_config udp_cfg; |
| |
| pjsua_transport_config_default(&udp_cfg); |
| udp_cfg.port = 0; |
| status = pjsua_transport_create(PJSIP_TRANSPORT_UDP, |
| &udp_cfg, &transport_id); |
| if (status != PJ_SUCCESS) { |
| Error(_T("Error creating UDP transport"), status); |
| pjsua_destroy(); |
| PopUp_Hide(POPUP_REGISTRATION); |
| return FALSE; |
| } |
| |
| // Adjust codecs priority |
| pj_str_t tmp; |
| pjsua_codec_set_priority(pj_cstr(&tmp, "speex"), 0); |
| pjsua_codec_set_priority(pj_cstr(&tmp, "speex/8000"), 200); |
| pjsua_codec_set_priority(pj_cstr(&tmp, "GSM"), 180); |
| pjsua_codec_set_priority(pj_cstr(&tmp, "PCMU"), 160); |
| pjsua_codec_set_priority(pj_cstr(&tmp, "PCMA"), 150); |
| pjsua_codec_set_priority(pj_cstr(&tmp, "iLBC"), 0); |
| pjsua_codec_set_priority(pj_cstr(&tmp, "L16"), 0); |
| |
| |
| // Start! |
| PopUp_Modify(POPUP_REGISTRATION, POPUP_EL_TITLE3, "Starting.."); |
| status = pjsua_start(); |
| if (status != PJ_SUCCESS) { |
| Error(_T("Error starting library"), status); |
| pjsua_destroy(); |
| PopUp_Hide(POPUP_REGISTRATION); |
| return FALSE; |
| } |
| |
| // Add account |
| PopUp_Modify(POPUP_REGISTRATION, POPUP_EL_TITLE3, "Adding account.."); |
| char domain[80], username[80], passwd[80]; |
| char id[80], reg_uri[80]; |
| pjsua_acc_config acc_cfg; |
| |
| pj_unicode_to_ansi((LPCTSTR)m_Cfg.m_Domain, m_Cfg.m_Domain.GetLength(), |
| domain, sizeof(domain)); |
| pj_unicode_to_ansi((LPCTSTR)m_Cfg.m_User, m_Cfg.m_User.GetLength(), |
| username, sizeof(username)); |
| pj_unicode_to_ansi((LPCTSTR)m_Cfg.m_Password, m_Cfg.m_Password.GetLength(), |
| passwd, sizeof(passwd)); |
| |
| snprintf(id, sizeof(id), "<sip:%s@%s>", username, domain); |
| snprintf(reg_uri, sizeof(reg_uri), "sip:%s", domain); |
| |
| pjsua_acc_config_default(&acc_cfg); |
| acc_cfg.id = pj_str(id); |
| acc_cfg.reg_uri = pj_str(reg_uri); |
| acc_cfg.cred_count = 1; |
| acc_cfg.cred_info[0].scheme = pj_str("Digest"); |
| acc_cfg.cred_info[0].realm = pj_str("*"); |
| acc_cfg.cred_info[0].username = pj_str(username); |
| acc_cfg.cred_info[0].data_type = 0; |
| acc_cfg.cred_info[0].data = pj_str(passwd); |
| |
| acc_cfg.use_srtp = (m_Cfg.m_UseSrtp ? PJMEDIA_SRTP_OPTIONAL : PJMEDIA_SRTP_DISABLED); |
| acc_cfg.srtp_secure_signaling = 0; |
| acc_cfg.publish_enabled = m_Cfg.m_UsePublish; |
| |
| status = pjsua_acc_add(&acc_cfg, PJ_TRUE, &m_PjsuaAccId); |
| if (status != PJ_SUCCESS) { |
| Error(_T("Invalid account settings"), status); |
| pjsua_destroy(); |
| PopUp_Hide(POPUP_REGISTRATION); |
| return FALSE; |
| } |
| |
| CString acc_text = m_Cfg.m_User + _T("@") + m_Cfg.m_Domain; |
| m_AccId.SetWindowText(acc_text); |
| |
| PopUp_Modify(POPUP_REGISTRATION, POPUP_EL_TITLE1, acc_text); |
| PopUp_Modify(POPUP_REGISTRATION, POPUP_EL_TITLE2, "Registering.."); |
| PopUp_Modify(POPUP_REGISTRATION, POPUP_EL_TITLE3, ""); |
| |
| SetTimer(TIMER_ID, 100, NULL); |
| return TRUE; |
| } |
| |
| |
| void CPocketPJDlg::PopUp_Show( PopUpType type, |
| const CString& title1, |
| const CString& title2, |
| const CString& title3, |
| const CString& btn1, |
| const CString& btn2, |
| unsigned userData) |
| { |
| if (!m_PopUpState[type]) |
| ++m_PopUpCount; |
| |
| m_PopUpState[type] = TRUE; |
| |
| m_PopUpContent[type].m_Title1 = title1; |
| m_PopUpContent[type].m_Title2 = title2; |
| m_PopUpContent[type].m_Title3 = title3; |
| m_PopUpContent[type].m_Btn1 = btn1; |
| m_PopUpContent[type].m_Btn2 = btn2; |
| |
| m_PopUp->SetContent(m_PopUpContent[type]); |
| m_PopUp->Show(); |
| } |
| |
| void CPocketPJDlg::PopUp_Modify(PopUpType type, |
| PopUpElement el, |
| const CString& text) |
| { |
| switch (el) { |
| case POPUP_EL_TITLE1: |
| m_PopUpContent[type].m_Title1 = text; |
| break; |
| case POPUP_EL_TITLE2: |
| m_PopUpContent[type].m_Title2 = text; |
| break; |
| case POPUP_EL_TITLE3: |
| m_PopUpContent[type].m_Title3 = text; |
| break; |
| case POPUP_EL_BUTTON1: |
| m_PopUpContent[type].m_Btn1 = text; |
| break; |
| case POPUP_EL_BUTTON2: |
| m_PopUpContent[type].m_Btn1 = text; |
| break; |
| } |
| |
| m_PopUp->SetContent(m_PopUpContent[type]); |
| } |
| |
| void CPocketPJDlg::PopUp_Hide(PopUpType type) |
| { |
| if (m_PopUpState[type]) |
| --m_PopUpCount; |
| |
| m_PopUpState[type] = FALSE; |
| |
| if (m_PopUpCount == 0) { |
| m_PopUp->Hide(); |
| UpdateWindow(); |
| } else { |
| for (int i=POPUP_MAX_TYPE-1; i>=0; --i) { |
| if (m_PopUpState[i]) { |
| m_PopUp->SetContent(m_PopUpContent[i]); |
| break; |
| } |
| } |
| } |
| } |
| |
| void CPocketPJDlg::OnCallState() |
| { |
| pjsua_call_info ci; |
| |
| pjsua_call_get_info(0, &ci); |
| |
| switch (ci.state) { |
| case PJSIP_INV_STATE_NULL: /**< Before INVITE is sent or received */ |
| break; |
| case PJSIP_INV_STATE_CALLING: /**< After INVITE is sent */ |
| PopUp_Show(POPUP_CALL, "Calling..", ci.remote_info.ptr, "", |
| "", "Hangup", 0); |
| break; |
| case PJSIP_INV_STATE_INCOMING: /**< After INVITE is received. */ |
| PopUp_Show(POPUP_CALL, "Incoming call..", ci.remote_info.ptr, "", |
| "Answer", "Hangup", 0); |
| pjsua_call_answer(0, 180, NULL, NULL); |
| break; |
| case PJSIP_INV_STATE_EARLY: /**< After response with To tag. */ |
| case PJSIP_INV_STATE_CONNECTING:/**< After 2xx is sent/received. */ |
| case PJSIP_INV_STATE_CONFIRMED: /**< After ACK is sent/received. */ |
| { |
| CString stateText = ci.state_text.ptr; |
| PopUp_Modify(POPUP_CALL, POPUP_EL_TITLE3, stateText); |
| } |
| break; |
| case PJSIP_INV_STATE_DISCONNECTED:/**< Session is terminated. */ |
| PopUp_Modify(POPUP_CALL, POPUP_EL_TITLE3, "Disconnected"); |
| PopUp_Hide(POPUP_CALL); |
| break; |
| } |
| } |
| |
| void CPocketPJDlg::on_call_state(pjsua_call_id call_id, pjsip_event *e) |
| { |
| theDlg->OnCallState(); |
| } |
| |
| void CPocketPJDlg::on_call_media_state(pjsua_call_id call_id) |
| { |
| pjsua_call_info call_info; |
| |
| pjsua_call_get_info(call_id, &call_info); |
| if (call_info.media_status == PJSUA_CALL_MEDIA_ACTIVE) { |
| pjsua_conf_connect(call_info.conf_slot, 0); |
| pjsua_conf_connect(0, call_info.conf_slot); |
| } |
| } |
| |
| void CPocketPJDlg::on_incoming_call(pjsua_acc_id acc_id, pjsua_call_id call_id, |
| pjsip_rx_data *rdata) |
| { |
| } |
| |
| void CPocketPJDlg::OnRegState() |
| { |
| pjsua_acc_info ai; |
| pjsua_acc_get_info(m_PjsuaAccId, &ai); |
| |
| CString acc_text = m_Cfg.m_User + _T("@") + m_Cfg.m_Domain; |
| |
| if (ai.expires>0 && ai.status/100==2) { |
| /* Registration success */ |
| HBITMAP old = m_BtnAcc.SetBitmap(::LoadBitmap(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_ONLINE)) ); |
| acc_text += " (OK)"; |
| m_AccId.SetWindowText(acc_text); |
| } else if (ai.status/100 != 2) { |
| acc_text += " (err)"; |
| Error(_T("SIP registration error"), PJSIP_ERRNO_FROM_SIP_STATUS(ai.status)); |
| m_AccId.SetWindowText(acc_text); |
| } |
| PopUp_Hide(POPUP_REGISTRATION); |
| } |
| |
| void CPocketPJDlg::on_reg_state(pjsua_acc_id acc_id) |
| { |
| theDlg->OnRegState(); |
| } |
| |
| void CPocketPJDlg::on_buddy_state(pjsua_buddy_id buddy_id) |
| { |
| theDlg->RedrawBuddyList(); |
| } |
| |
| void CPocketPJDlg::on_pager(pjsua_call_id call_id, const pj_str_t *from, |
| const pj_str_t *to, const pj_str_t *contact, |
| const pj_str_t *mime_type, const pj_str_t *text) |
| { |
| } |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| // CPocketPJDlg message handlers |
| |
| BOOL CPocketPJDlg::OnInitDialog() |
| { |
| CDialog::OnInitDialog(); |
| |
| // Set the icon for this dialog. The framework does this automatically |
| // when the application's main window is not a dialog |
| SetIcon(m_hIcon, TRUE); // Set big icon |
| SetIcon(m_hIcon, FALSE); // Set small icon |
| |
| CenterWindow(GetDesktopWindow()); // center to the hpc screen |
| |
| // TODO: Add extra initialization here |
| |
| m_Cfg.LoadRegistry(); |
| //ShowWindow(SW_SHOW); |
| m_AccId.SetWindowText(m_Cfg.m_User); |
| |
| CImageList *il = new CImageList; |
| VERIFY(il->Create(16, 16, ILC_COLOR|ILC_MASK, 2, 4)); |
| |
| CBitmap *bmp = new CBitmap; |
| bmp->LoadBitmap(MAKEINTRESOURCE(IDB_BLANK)); |
| il->Add(bmp, RGB(255,255,255)); |
| bmp = new CBitmap; |
| bmp->LoadBitmap(MAKEINTRESOURCE(IDB_ONLINE)); |
| il->Add(bmp, RGB(255,255,255)); |
| |
| m_BuddyList.SetImageList(il, LVSIL_SMALL); |
| |
| if (m_Cfg.m_Domain.GetLength()==0 || Restart() == FALSE) { |
| for (;;) { |
| CSettingsDlg dlg(m_Cfg); |
| if (dlg.DoModal() != IDOK) { |
| EndDialog(IDOK); |
| return TRUE; |
| } |
| |
| m_Cfg.SaveRegistry(); |
| |
| if (Restart()) |
| break; |
| } |
| } |
| |
| RedrawBuddyList(); |
| return TRUE; // return TRUE unless you set the focus to a control |
| } |
| |
| |
| |
| void CPocketPJDlg::OnBtnAcc() |
| { |
| CMenu menu; |
| VERIFY(menu.LoadMenu(IDR_ACC_MENU)); |
| CMenu* pPopup = menu.GetSubMenu(0); |
| ASSERT(pPopup != NULL); |
| |
| RECT r; |
| m_BtnAcc.GetWindowRect(&r); |
| pPopup->TrackPopupMenu(TPM_LEFTALIGN, r.left+4, r.top+4, this); |
| } |
| |
| void CPocketPJDlg::OnBtnAction() |
| { |
| CMenu menu; |
| VERIFY(menu.LoadMenu(IDR_URI_MENU)); |
| CMenu* pPopup = menu.GetSubMenu(0); |
| ASSERT(pPopup != NULL); |
| |
| RECT r; |
| this->m_BtnUrlAction.GetWindowRect(&r); |
| pPopup->TrackPopupMenu(TPM_LEFTALIGN, r.left+4, r.top+4, this); |
| } |
| |
| void CPocketPJDlg::OnSettings() |
| { |
| for (;;) { |
| CSettingsDlg dlg(m_Cfg); |
| if (dlg.DoModal() != IDOK) { |
| return; |
| } |
| |
| m_Cfg.SaveRegistry(); |
| |
| if (Restart()) |
| break; |
| } |
| } |
| |
| void CPocketPJDlg::OnOK() |
| { |
| if (AfxMessageBox(_T("Quit PocketPJ?"), MB_YESNO)==IDYES) { |
| KillTimer(TIMER_ID); |
| PopUp_Show(POPUP_REGISTRATION, "", "Shutting down..", "", "", "", 0); |
| pjsua_destroy(); |
| CDialog::OnOK(); |
| PopUp_Hide(POPUP_REGISTRATION); |
| m_Cfg.SaveRegistry(); |
| return; |
| } |
| } |
| |
| void CPocketPJDlg::OnTimer(UINT nIDEvent) |
| { |
| pjsua_handle_events(10); |
| CDialog::OnTimer(nIDEvent); |
| } |
| |
| int CPocketPJDlg::FindBuddyInPjsua(const CString &Uri) |
| { |
| char uri[80]; |
| pjsua_buddy_id id[128]; |
| unsigned i, count = PJ_ARRAY_SIZE(id); |
| |
| if (pjsua_enum_buddies(id, &count) != PJ_SUCCESS) |
| return PJSUA_INVALID_ID; |
| if (count==0) |
| return PJSUA_INVALID_ID; |
| |
| pj_unicode_to_ansi((LPCTSTR)Uri, Uri.GetLength(), uri, sizeof(uri)); |
| |
| for (i=0; i<count; ++i) { |
| pjsua_buddy_info bi; |
| pjsua_buddy_get_info(id[i], &bi); |
| if (pj_strcmp2(&bi.uri, uri)==0) |
| return i; |
| } |
| |
| return PJSUA_INVALID_ID; |
| } |
| |
| int CPocketPJDlg::FindBuddyInCfg(const CString &uri) |
| { |
| int i; |
| for (i=0; i<m_Cfg.m_BuddyList.GetSize(); ++i) { |
| if (m_Cfg.m_BuddyList.GetAt(0) == uri) { |
| return i; |
| } |
| } |
| return -1; |
| } |
| |
| void CPocketPJDlg::RedrawBuddyList() |
| { |
| int i; |
| |
| m_BuddyList.DeleteAllItems(); |
| |
| for (i=0; i<m_Cfg.m_BuddyList.GetSize(); ++i) { |
| int isOnline; |
| int id; |
| |
| id = FindBuddyInPjsua(m_Cfg.m_BuddyList.GetAt(i)); |
| if (id != PJSUA_INVALID_ID) { |
| pjsua_buddy_info bi; |
| pjsua_buddy_get_info(id, &bi); |
| isOnline = (bi.status == PJSUA_BUDDY_STATUS_ONLINE); |
| } else { |
| isOnline = 0; |
| } |
| |
| LVITEM lvi; |
| memset(&lvi, 0, sizeof(lvi)); |
| lvi.mask = LVIF_TEXT | LVIF_IMAGE; |
| lvi.iItem = i; |
| lvi.iImage = isOnline; |
| lvi.pszText = (LPTSTR)(LPCTSTR)m_Cfg.m_BuddyList.GetAt(i); |
| |
| m_BuddyList.InsertItem(&lvi); |
| } |
| } |
| |
| void CPocketPJDlg::OnUriCall() |
| { |
| char tmp[120]; |
| CString uri; |
| pj_status_t status; |
| |
| m_Url.GetWindowText(uri); |
| pj_unicode_to_ansi((LPCTSTR)uri, uri.GetLength(), tmp, sizeof(tmp)); |
| if ((status=pjsua_verify_sip_url(tmp)) != PJ_SUCCESS) { |
| Error("The URL is not valid SIP URL", status); |
| return; |
| } |
| |
| pj_str_t dest_uri = pj_str(tmp); |
| pjsua_call_id call_id; |
| |
| status = pjsua_call_make_call(m_PjsuaAccId, &dest_uri, 0, NULL, NULL, &call_id); |
| |
| if (status != PJ_SUCCESS) |
| Error("Unable to make call", status); |
| } |
| |
| void CPocketPJDlg::OnUriAddBuddy() |
| { |
| int i; |
| char tmp[120]; |
| CString uri; |
| pj_status_t status; |
| |
| m_Url.GetWindowText(uri); |
| pj_unicode_to_ansi((LPCTSTR)uri, uri.GetLength(), tmp, sizeof(tmp)); |
| if ((status=pjsua_verify_sip_url(tmp)) != PJ_SUCCESS) { |
| Error("The URL is not valid SIP URL", status); |
| return; |
| } |
| |
| for (i=0; i<m_Cfg.m_BuddyList.GetSize(); ++i) { |
| if (m_Cfg.m_BuddyList.GetAt(0) == uri) { |
| AfxMessageBox(_T("The URI is already in the buddy list")); |
| return; |
| } |
| } |
| |
| m_Cfg.m_BuddyList.Add(uri); |
| RedrawBuddyList(); |
| } |
| |
| void CPocketPJDlg::OnUriDelBuddy() |
| { |
| CString uri; |
| |
| m_Url.GetWindowText(uri); |
| int i = FindBuddyInCfg(uri); |
| if (i<0) { |
| /* Buddy not found */ |
| return; |
| } |
| |
| m_Cfg.m_BuddyList.RemoveAt(i); |
| RedrawBuddyList(); |
| AfxMessageBox(_T("Buddy " + uri + " deleted")); |
| } |
| |
| void CPocketPJDlg::OnAccOnline() |
| { |
| pjsua_acc_set_online_status(m_PjsuaAccId, PJ_TRUE); |
| m_BtnAcc.SetBitmap(::LoadBitmap(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_ONLINE)) ); |
| } |
| |
| void CPocketPJDlg::OnAccInvisible() |
| { |
| pjsua_acc_set_online_status(m_PjsuaAccId, PJ_FALSE); |
| m_BtnAcc.SetBitmap(::LoadBitmap(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_INVISIBLE)) ); |
| } |
| |
| void CPocketPJDlg::OnPopUpButton(int btnNo) |
| { |
| if (btnNo == 1) { |
| pjsua_call_answer(0, 200, NULL, 0); |
| PopUp_Modify(POPUP_CALL, POPUP_EL_BUTTON1, ""); |
| } else if (btnNo == 2) { |
| // Hangup button |
| PopUp_Modify(POPUP_CALL, POPUP_EL_TITLE2, "Hang up.."); |
| PopUp_Modify(POPUP_CALL, POPUP_EL_TITLE3, ""); |
| pjsua_call_hangup(0, PJSIP_SC_DECLINE, 0, 0); |
| } |
| } |
| |
| void CPocketPJDlg::OnClickBuddyList(NMHDR* pNMHDR, LRESULT* pResult) |
| { |
| POSITION pos = m_BuddyList.GetFirstSelectedItemPosition(); |
| if (pos != NULL) { |
| int iItem = m_BuddyList.GetNextSelectedItem(pos); |
| CString uri = m_BuddyList.GetItemText(iItem, 0); |
| m_Url.SetWindowText(uri); |
| } |
| *pResult = 0; |
| } |