Benny Prijono | 5d9c16f | 2008-02-22 23:38:47 +0000 | [diff] [blame] | 1 | // PocketPJDlg.cpp : implementation file |
| 2 | // |
| 3 | |
| 4 | #include "stdafx.h" |
| 5 | #include "PocketPJ.h" |
| 6 | #include "PocketPJDlg.h" |
| 7 | #include <iphlpapi.h> |
| 8 | |
| 9 | #ifdef _DEBUG |
| 10 | #define new DEBUG_NEW |
| 11 | #undef THIS_FILE |
| 12 | static char THIS_FILE[] = __FILE__; |
| 13 | #endif |
| 14 | |
| 15 | #define TIMER_ID 101 |
| 16 | static CPocketPJDlg *theDlg; |
| 17 | |
| 18 | ///////////////////////////////////////////////////////////////////////////// |
| 19 | // CPocketPJDlg dialog |
| 20 | |
| 21 | CPocketPJDlg::CPocketPJDlg(CWnd* pParent /*=NULL*/) |
| 22 | : CDialog(CPocketPJDlg::IDD, pParent), m_PopUp(NULL) |
| 23 | { |
| 24 | //{{AFX_DATA_INIT(CPocketPJDlg) |
| 25 | // NOTE: the ClassWizard will add member initialization here |
| 26 | //}}AFX_DATA_INIT |
| 27 | // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 |
| 28 | m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); |
| 29 | |
| 30 | theDlg = this; |
| 31 | |
| 32 | m_PopUp = new CPopUpWnd(this); |
| 33 | m_PopUp->Hide(); |
| 34 | |
| 35 | unsigned i; |
| 36 | m_PopUpCount = 0; |
| 37 | for (i=0; i<POPUP_MAX_TYPE; ++i) { |
| 38 | m_PopUpState[i] = FALSE; |
| 39 | } |
| 40 | } |
| 41 | |
| 42 | void CPocketPJDlg::DoDataExchange(CDataExchange* pDX) |
| 43 | { |
| 44 | CDialog::DoDataExchange(pDX); |
| 45 | //{{AFX_DATA_MAP(CPocketPJDlg) |
| 46 | DDX_Control(pDX, IDC_URL, m_Url); |
| 47 | DDX_Control(pDX, IDC_BUDDY_LIST, m_BuddyList); |
| 48 | DDX_Control(pDX, IDC_BTN_ACTION, m_BtnUrlAction); |
| 49 | DDX_Control(pDX, IDC_BTN_ACC, m_BtnAcc); |
| 50 | DDX_Control(pDX, IDC_ACC_ID, m_AccId); |
| 51 | //}}AFX_DATA_MAP |
| 52 | } |
| 53 | |
| 54 | BEGIN_MESSAGE_MAP(CPocketPJDlg, CDialog) |
| 55 | //{{AFX_MSG_MAP(CPocketPJDlg) |
| 56 | ON_BN_CLICKED(IDC_BTN_ACC, OnBtnAcc) |
| 57 | ON_BN_CLICKED(IDC_BTN_ACTION, OnBtnAction) |
| 58 | ON_COMMAND(IDC_ACC_SETTINGS, OnSettings) |
| 59 | ON_COMMAND(IDC_URI_CALL, OnUriCall) |
| 60 | ON_WM_TIMER() |
| 61 | ON_COMMAND(IDC_URI_ADD_BUDDY, OnUriAddBuddy) |
| 62 | ON_COMMAND(IDC_URI_DEL_BUDDY, OnUriDelBuddy) |
| 63 | ON_COMMAND(IDC_ACC_ONLINE, OnAccOnline) |
| 64 | ON_COMMAND(IDC_ACC_INVISIBLE, OnAccInvisible) |
| 65 | ON_NOTIFY(NM_CLICK, IDC_BUDDY_LIST, OnClickBuddyList) |
| 66 | //}}AFX_MSG_MAP |
| 67 | END_MESSAGE_MAP() |
| 68 | |
| 69 | |
| 70 | void CPocketPJDlg::Error(const CString &title, pj_status_t rc) |
| 71 | { |
| 72 | char errmsg[PJ_ERR_MSG_SIZE]; |
| 73 | wchar_t werrmsg[PJ_ERR_MSG_SIZE]; |
| 74 | |
| 75 | pj_strerror(rc, errmsg, sizeof(errmsg)); |
| 76 | pj_ansi_to_unicode(errmsg, strlen(errmsg), werrmsg, PJ_ARRAY_SIZE(werrmsg)); |
| 77 | |
| 78 | AfxMessageBox(title + _T(": ") + werrmsg); |
| 79 | } |
| 80 | |
| 81 | BOOL CPocketPJDlg::Restart() |
| 82 | { |
Benny Prijono | 36e76ef | 2008-08-13 13:56:24 +0000 | [diff] [blame] | 83 | unsigned i; |
Benny Prijono | 5d9c16f | 2008-02-22 23:38:47 +0000 | [diff] [blame] | 84 | pj_status_t status; |
| 85 | |
| 86 | char ver[80]; |
| 87 | sprintf(ver, "PocketPJ/%s", pj_get_version()); |
| 88 | |
| 89 | ShowWindow(SW_SHOW); |
| 90 | PopUp_Show(POPUP_REGISTRATION, ver, |
| 91 | "Starting up....", "", "", "", 0); |
| 92 | |
| 93 | KillTimer(TIMER_ID); |
| 94 | |
| 95 | // Destroy first. |
| 96 | PopUp_Modify(POPUP_REGISTRATION, POPUP_EL_TITLE3, "Cleaning up.."); |
| 97 | pjsua_destroy(); |
| 98 | |
| 99 | m_BtnAcc.SetBitmap(::LoadBitmap(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_OFFLINE)) ); |
| 100 | UpdateWindow(); |
| 101 | |
| 102 | |
| 103 | // Create |
| 104 | PopUp_Show(POPUP_REGISTRATION, ver, |
| 105 | "Starting up....", "Creating stack..", "", "", 0); |
| 106 | |
| 107 | status = pjsua_create(); |
| 108 | if (status != PJ_SUCCESS) { |
| 109 | Error(_T("Error in creating library"), status); |
| 110 | PopUp_Hide(POPUP_REGISTRATION); |
| 111 | return FALSE; |
| 112 | } |
| 113 | |
| 114 | pjsua_config cfg; |
| 115 | pjsua_logging_config log_cfg; |
| 116 | pjsua_media_config media_cfg; |
| 117 | |
| 118 | pjsua_config_default(&cfg); |
| 119 | cfg.max_calls = 1; |
| 120 | cfg.thread_cnt = 0; |
| 121 | cfg.user_agent = pj_str(ver); |
| 122 | |
| 123 | cfg.cb.on_call_state = &on_call_state; |
| 124 | cfg.cb.on_call_media_state = &on_call_media_state; |
| 125 | cfg.cb.on_incoming_call = &on_incoming_call; |
| 126 | cfg.cb.on_reg_state = &on_reg_state; |
| 127 | cfg.cb.on_buddy_state = &on_buddy_state; |
| 128 | cfg.cb.on_pager = &on_pager; |
| 129 | |
| 130 | /* Configure nameserver */ |
| 131 | char nameserver[60]; |
| 132 | { |
| 133 | FIXED_INFO fi; |
Benny Prijono | 981e59e | 2009-12-29 15:33:13 +0000 | [diff] [blame] | 134 | PIP_ADDR_STRING pDNS = NULL; |
Benny Prijono | 5d9c16f | 2008-02-22 23:38:47 +0000 | [diff] [blame] | 135 | ULONG len = sizeof(fi); |
| 136 | CString err; |
| 137 | |
| 138 | PopUp_Modify(POPUP_REGISTRATION, POPUP_EL_TITLE3, "Retrieving network parameters.."); |
| 139 | if (GetNetworkParams(&fi, &len) != ERROR_SUCCESS) { |
| 140 | err = _T("Info: Error querying network parameters. You must configure DNS server."); |
Benny Prijono | 981e59e | 2009-12-29 15:33:13 +0000 | [diff] [blame] | 141 | } else if (fi.CurrentDnsServer) { |
| 142 | pDNS = fi.CurrentDnsServer; |
| 143 | } else if (fi.DnsServerList.IpAddress.String[0] != 0) { |
| 144 | pDNS = &fi.DnsServerList; |
| 145 | } else { |
Benny Prijono | 5d9c16f | 2008-02-22 23:38:47 +0000 | [diff] [blame] | 146 | err = _T("Info: DNS server not configured. You must configure DNS server."); |
| 147 | } |
| 148 | |
| 149 | if (err.GetLength()) { |
| 150 | if (m_Cfg.m_DNS.GetLength()) { |
| 151 | pj_unicode_to_ansi((LPCTSTR)m_Cfg.m_DNS, m_Cfg.m_DNS.GetLength(), |
| 152 | nameserver, sizeof(nameserver)); |
| 153 | cfg.nameserver_count = 1; |
| 154 | cfg.nameserver[0] = pj_str(nameserver); |
| 155 | } else { |
| 156 | AfxMessageBox(err); |
| 157 | pjsua_destroy(); |
| 158 | PopUp_Hide(POPUP_REGISTRATION); |
| 159 | return FALSE; |
| 160 | } |
| 161 | } else { |
Benny Prijono | 981e59e | 2009-12-29 15:33:13 +0000 | [diff] [blame] | 162 | strcpy(nameserver, pDNS->IpAddress.String); |
Benny Prijono | 5d9c16f | 2008-02-22 23:38:47 +0000 | [diff] [blame] | 163 | cfg.nameserver_count = 1; |
| 164 | cfg.nameserver[0] = pj_str(nameserver); |
| 165 | } |
| 166 | } |
| 167 | |
| 168 | char tmp_stun[80]; |
| 169 | if (m_Cfg.m_UseStun) { |
| 170 | pj_unicode_to_ansi((LPCTSTR)m_Cfg.m_StunSrv, m_Cfg.m_StunSrv.GetLength(), |
| 171 | tmp_stun, sizeof(tmp_stun)); |
| 172 | cfg.stun_host = pj_str(tmp_stun); |
| 173 | } |
| 174 | |
| 175 | pjsua_logging_config_default(&log_cfg); |
Benny Prijono | 981e59e | 2009-12-29 15:33:13 +0000 | [diff] [blame] | 176 | log_cfg.msg_logging = PJ_TRUE; |
Benny Prijono | 5d9c16f | 2008-02-22 23:38:47 +0000 | [diff] [blame] | 177 | log_cfg.log_filename = pj_str("\\PocketPJ.TXT"); |
| 178 | |
| 179 | pjsua_media_config_default(&media_cfg); |
| 180 | media_cfg.clock_rate = 8000; |
| 181 | media_cfg.audio_frame_ptime = 40; |
| 182 | media_cfg.ec_tail_len = 0; |
| 183 | media_cfg.ilbc_mode = 30; |
| 184 | media_cfg.max_media_ports = 8; |
Nanang Izzuddin | c91cd64 | 2009-05-06 18:59:31 +0000 | [diff] [blame] | 185 | // use default quality setting |
| 186 | //media_cfg.quality = 5; |
Benny Prijono | 5d9c16f | 2008-02-22 23:38:47 +0000 | [diff] [blame] | 187 | media_cfg.thread_cnt = 1; |
| 188 | media_cfg.enable_ice = m_Cfg.m_UseIce; |
Benny Prijono | 36e76ef | 2008-08-13 13:56:24 +0000 | [diff] [blame] | 189 | media_cfg.no_vad = !m_Cfg.m_VAD; |
Benny Prijono | 4d3eed1 | 2008-03-11 13:18:48 +0000 | [diff] [blame] | 190 | |
| 191 | if (m_Cfg.m_EchoSuppress) { |
| 192 | media_cfg.ec_options = PJMEDIA_ECHO_SIMPLE; |
| 193 | media_cfg.ec_tail_len = m_Cfg.m_EcTail; |
| 194 | } |
| 195 | |
Benny Prijono | 5d9c16f | 2008-02-22 23:38:47 +0000 | [diff] [blame] | 196 | // Init |
| 197 | PopUp_Modify(POPUP_REGISTRATION, POPUP_EL_TITLE3, "Initializing.."); |
| 198 | status = pjsua_init(&cfg, &log_cfg, &media_cfg); |
| 199 | if (status != PJ_SUCCESS) { |
| 200 | Error(_T("Error initializing library"), status); |
| 201 | pjsua_destroy(); |
| 202 | PopUp_Hide(POPUP_REGISTRATION); |
| 203 | return FALSE; |
| 204 | } |
| 205 | |
| 206 | // Create one UDP transport |
Benny Prijono | 36e76ef | 2008-08-13 13:56:24 +0000 | [diff] [blame] | 207 | PopUp_Modify(POPUP_REGISTRATION, POPUP_EL_TITLE3, "Adding UDP transport.."); |
Benny Prijono | 5d9c16f | 2008-02-22 23:38:47 +0000 | [diff] [blame] | 208 | pjsua_transport_id transport_id; |
| 209 | pjsua_transport_config udp_cfg; |
| 210 | |
| 211 | pjsua_transport_config_default(&udp_cfg); |
| 212 | udp_cfg.port = 0; |
| 213 | status = pjsua_transport_create(PJSIP_TRANSPORT_UDP, |
| 214 | &udp_cfg, &transport_id); |
| 215 | if (status != PJ_SUCCESS) { |
| 216 | Error(_T("Error creating UDP transport"), status); |
| 217 | pjsua_destroy(); |
| 218 | PopUp_Hide(POPUP_REGISTRATION); |
| 219 | return FALSE; |
| 220 | } |
| 221 | |
Benny Prijono | 981e59e | 2009-12-29 15:33:13 +0000 | [diff] [blame] | 222 | // Always instantiate TCP to support auto-switching to TCP when |
| 223 | // packet is larger than 1300 bytes. If TCP is disabled when |
| 224 | // no auto-switching will occur |
| 225 | if (1) { |
Benny Prijono | 36e76ef | 2008-08-13 13:56:24 +0000 | [diff] [blame] | 226 | // Create one TCP transport |
| 227 | PopUp_Modify(POPUP_REGISTRATION, POPUP_EL_TITLE3, "Adding TCP transport.."); |
| 228 | pjsua_transport_id transport_id; |
| 229 | pjsua_transport_config tcp_cfg; |
| 230 | |
| 231 | pjsua_transport_config_default(&tcp_cfg); |
| 232 | tcp_cfg.port = 0; |
| 233 | status = pjsua_transport_create(PJSIP_TRANSPORT_TCP, |
| 234 | &tcp_cfg, &transport_id); |
| 235 | if (status != PJ_SUCCESS) { |
| 236 | Error(_T("Error creating TCP transport"), status); |
| 237 | pjsua_destroy(); |
| 238 | PopUp_Hide(POPUP_REGISTRATION); |
| 239 | return FALSE; |
| 240 | } |
| 241 | } |
| 242 | |
Benny Prijono | 5d9c16f | 2008-02-22 23:38:47 +0000 | [diff] [blame] | 243 | // Adjust codecs priority |
| 244 | pj_str_t tmp; |
Benny Prijono | 36e76ef | 2008-08-13 13:56:24 +0000 | [diff] [blame] | 245 | pjsua_codec_set_priority(pj_cstr(&tmp, "*"), 0); |
| 246 | for (i=0; i<(unsigned)m_Cfg.m_Codecs.GetSize(); ++i) { |
| 247 | CString codec = m_Cfg.m_Codecs.GetAt(i); |
| 248 | char tmp_nam[80]; |
Benny Prijono | 5d9c16f | 2008-02-22 23:38:47 +0000 | [diff] [blame] | 249 | |
Benny Prijono | 36e76ef | 2008-08-13 13:56:24 +0000 | [diff] [blame] | 250 | pj_unicode_to_ansi((LPCTSTR)codec, codec.GetLength(), |
| 251 | tmp_nam, sizeof(tmp_nam)); |
Nanang Izzuddin | 2e4f03f | 2009-04-27 19:18:38 +0000 | [diff] [blame] | 252 | pjsua_codec_set_priority(pj_cstr(&tmp, tmp_nam), (pj_uint8_t)(200-i)); |
Benny Prijono | 36e76ef | 2008-08-13 13:56:24 +0000 | [diff] [blame] | 253 | } |
Benny Prijono | 5d9c16f | 2008-02-22 23:38:47 +0000 | [diff] [blame] | 254 | |
| 255 | // Start! |
| 256 | PopUp_Modify(POPUP_REGISTRATION, POPUP_EL_TITLE3, "Starting.."); |
| 257 | status = pjsua_start(); |
| 258 | if (status != PJ_SUCCESS) { |
| 259 | Error(_T("Error starting library"), status); |
| 260 | pjsua_destroy(); |
| 261 | PopUp_Hide(POPUP_REGISTRATION); |
| 262 | return FALSE; |
| 263 | } |
| 264 | |
| 265 | // Add account |
| 266 | PopUp_Modify(POPUP_REGISTRATION, POPUP_EL_TITLE3, "Adding account.."); |
| 267 | char domain[80], username[80], passwd[80]; |
| 268 | char id[80], reg_uri[80]; |
| 269 | pjsua_acc_config acc_cfg; |
| 270 | |
| 271 | pj_unicode_to_ansi((LPCTSTR)m_Cfg.m_Domain, m_Cfg.m_Domain.GetLength(), |
| 272 | domain, sizeof(domain)); |
| 273 | pj_unicode_to_ansi((LPCTSTR)m_Cfg.m_User, m_Cfg.m_User.GetLength(), |
| 274 | username, sizeof(username)); |
| 275 | pj_unicode_to_ansi((LPCTSTR)m_Cfg.m_Password, m_Cfg.m_Password.GetLength(), |
| 276 | passwd, sizeof(passwd)); |
| 277 | |
| 278 | snprintf(id, sizeof(id), "<sip:%s@%s>", username, domain); |
| 279 | snprintf(reg_uri, sizeof(reg_uri), "sip:%s", domain); |
| 280 | |
| 281 | pjsua_acc_config_default(&acc_cfg); |
| 282 | acc_cfg.id = pj_str(id); |
| 283 | acc_cfg.reg_uri = pj_str(reg_uri); |
| 284 | acc_cfg.cred_count = 1; |
| 285 | acc_cfg.cred_info[0].scheme = pj_str("Digest"); |
| 286 | acc_cfg.cred_info[0].realm = pj_str("*"); |
| 287 | acc_cfg.cred_info[0].username = pj_str(username); |
| 288 | acc_cfg.cred_info[0].data_type = 0; |
| 289 | acc_cfg.cred_info[0].data = pj_str(passwd); |
| 290 | |
Nanang Izzuddin | 51b1e55 | 2008-09-16 15:15:45 +0000 | [diff] [blame] | 291 | #if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0) |
Benny Prijono | 9b86257 | 2008-05-22 10:49:42 +0000 | [diff] [blame] | 292 | acc_cfg.use_srtp = (m_Cfg.m_UseSrtp ? PJMEDIA_SRTP_OPTIONAL : PJMEDIA_SRTP_DISABLED); |
Benny Prijono | 5d9c16f | 2008-02-22 23:38:47 +0000 | [diff] [blame] | 293 | acc_cfg.srtp_secure_signaling = 0; |
Nanang Izzuddin | 51b1e55 | 2008-09-16 15:15:45 +0000 | [diff] [blame] | 294 | #endif |
| 295 | |
Benny Prijono | 5d9c16f | 2008-02-22 23:38:47 +0000 | [diff] [blame] | 296 | acc_cfg.publish_enabled = m_Cfg.m_UsePublish; |
| 297 | |
Benny Prijono | 36e76ef | 2008-08-13 13:56:24 +0000 | [diff] [blame] | 298 | char route[80]; |
| 299 | if (m_Cfg.m_TCP) { |
| 300 | snprintf(route, sizeof(route), "<sip:%s;lr;transport=tcp>", domain); |
| 301 | acc_cfg.proxy[acc_cfg.proxy_cnt++] = pj_str(route); |
| 302 | } else { |
| 303 | snprintf(route, sizeof(route), "<sip:%s;lr>", domain); |
| 304 | acc_cfg.proxy[acc_cfg.proxy_cnt++] = pj_str(route); |
| 305 | } |
| 306 | |
Benny Prijono | 5d9c16f | 2008-02-22 23:38:47 +0000 | [diff] [blame] | 307 | status = pjsua_acc_add(&acc_cfg, PJ_TRUE, &m_PjsuaAccId); |
| 308 | if (status != PJ_SUCCESS) { |
| 309 | Error(_T("Invalid account settings"), status); |
| 310 | pjsua_destroy(); |
| 311 | PopUp_Hide(POPUP_REGISTRATION); |
| 312 | return FALSE; |
| 313 | } |
| 314 | |
| 315 | CString acc_text = m_Cfg.m_User + _T("@") + m_Cfg.m_Domain; |
| 316 | m_AccId.SetWindowText(acc_text); |
| 317 | |
| 318 | PopUp_Modify(POPUP_REGISTRATION, POPUP_EL_TITLE1, acc_text); |
| 319 | PopUp_Modify(POPUP_REGISTRATION, POPUP_EL_TITLE2, "Registering.."); |
| 320 | PopUp_Modify(POPUP_REGISTRATION, POPUP_EL_TITLE3, ""); |
| 321 | |
| 322 | SetTimer(TIMER_ID, 100, NULL); |
| 323 | return TRUE; |
| 324 | } |
| 325 | |
| 326 | |
| 327 | void CPocketPJDlg::PopUp_Show( PopUpType type, |
| 328 | const CString& title1, |
| 329 | const CString& title2, |
| 330 | const CString& title3, |
| 331 | const CString& btn1, |
| 332 | const CString& btn2, |
| 333 | unsigned userData) |
| 334 | { |
Nanang Izzuddin | 2e4f03f | 2009-04-27 19:18:38 +0000 | [diff] [blame] | 335 | PJ_UNUSED_ARG(userData); |
| 336 | |
Benny Prijono | 5d9c16f | 2008-02-22 23:38:47 +0000 | [diff] [blame] | 337 | if (!m_PopUpState[type]) |
| 338 | ++m_PopUpCount; |
| 339 | |
| 340 | m_PopUpState[type] = TRUE; |
| 341 | |
| 342 | m_PopUpContent[type].m_Title1 = title1; |
| 343 | m_PopUpContent[type].m_Title2 = title2; |
| 344 | m_PopUpContent[type].m_Title3 = title3; |
| 345 | m_PopUpContent[type].m_Btn1 = btn1; |
| 346 | m_PopUpContent[type].m_Btn2 = btn2; |
| 347 | |
| 348 | m_PopUp->SetContent(m_PopUpContent[type]); |
| 349 | m_PopUp->Show(); |
| 350 | } |
| 351 | |
| 352 | void CPocketPJDlg::PopUp_Modify(PopUpType type, |
| 353 | PopUpElement el, |
| 354 | const CString& text) |
| 355 | { |
| 356 | switch (el) { |
| 357 | case POPUP_EL_TITLE1: |
| 358 | m_PopUpContent[type].m_Title1 = text; |
| 359 | break; |
| 360 | case POPUP_EL_TITLE2: |
| 361 | m_PopUpContent[type].m_Title2 = text; |
| 362 | break; |
| 363 | case POPUP_EL_TITLE3: |
| 364 | m_PopUpContent[type].m_Title3 = text; |
| 365 | break; |
| 366 | case POPUP_EL_BUTTON1: |
| 367 | m_PopUpContent[type].m_Btn1 = text; |
| 368 | break; |
| 369 | case POPUP_EL_BUTTON2: |
| 370 | m_PopUpContent[type].m_Btn1 = text; |
| 371 | break; |
| 372 | } |
| 373 | |
| 374 | m_PopUp->SetContent(m_PopUpContent[type]); |
| 375 | } |
| 376 | |
| 377 | void CPocketPJDlg::PopUp_Hide(PopUpType type) |
| 378 | { |
| 379 | if (m_PopUpState[type]) |
| 380 | --m_PopUpCount; |
| 381 | |
| 382 | m_PopUpState[type] = FALSE; |
| 383 | |
| 384 | if (m_PopUpCount == 0) { |
| 385 | m_PopUp->Hide(); |
| 386 | UpdateWindow(); |
| 387 | } else { |
| 388 | for (int i=POPUP_MAX_TYPE-1; i>=0; --i) { |
| 389 | if (m_PopUpState[i]) { |
| 390 | m_PopUp->SetContent(m_PopUpContent[i]); |
| 391 | break; |
| 392 | } |
| 393 | } |
| 394 | } |
| 395 | } |
| 396 | |
Benny Prijono | 3614fbc | 2010-01-25 17:38:07 +0000 | [diff] [blame] | 397 | void CPocketPJDlg::OnIncomingCall() |
| 398 | { |
| 399 | pjsua_call_info ci; |
| 400 | |
| 401 | pjsua_call_get_info(0, &ci); |
| 402 | |
| 403 | PopUp_Show(POPUP_CALL, "Incoming call..", ci.remote_info.ptr, "", |
| 404 | "Answer", "Hangup", 0); |
| 405 | pjsua_call_answer(0, 180, NULL, NULL); |
| 406 | if (m_Cfg.m_AutoAnswer) |
| 407 | OnPopUpButton(1); |
| 408 | } |
| 409 | |
Benny Prijono | 5d9c16f | 2008-02-22 23:38:47 +0000 | [diff] [blame] | 410 | void CPocketPJDlg::OnCallState() |
| 411 | { |
| 412 | pjsua_call_info ci; |
| 413 | |
| 414 | pjsua_call_get_info(0, &ci); |
| 415 | |
| 416 | switch (ci.state) { |
| 417 | case PJSIP_INV_STATE_NULL: /**< Before INVITE is sent or received */ |
| 418 | break; |
| 419 | case PJSIP_INV_STATE_CALLING: /**< After INVITE is sent */ |
| 420 | PopUp_Show(POPUP_CALL, "Calling..", ci.remote_info.ptr, "", |
| 421 | "", "Hangup", 0); |
| 422 | break; |
| 423 | case PJSIP_INV_STATE_INCOMING: /**< After INVITE is received. */ |
Benny Prijono | 3614fbc | 2010-01-25 17:38:07 +0000 | [diff] [blame] | 424 | OnIncomingCall(); |
Benny Prijono | 5d9c16f | 2008-02-22 23:38:47 +0000 | [diff] [blame] | 425 | break; |
| 426 | case PJSIP_INV_STATE_EARLY: /**< After response with To tag. */ |
| 427 | case PJSIP_INV_STATE_CONNECTING:/**< After 2xx is sent/received. */ |
| 428 | case PJSIP_INV_STATE_CONFIRMED: /**< After ACK is sent/received. */ |
| 429 | { |
| 430 | CString stateText = ci.state_text.ptr; |
| 431 | PopUp_Modify(POPUP_CALL, POPUP_EL_TITLE3, stateText); |
| 432 | } |
| 433 | break; |
| 434 | case PJSIP_INV_STATE_DISCONNECTED:/**< Session is terminated. */ |
| 435 | PopUp_Modify(POPUP_CALL, POPUP_EL_TITLE3, "Disconnected"); |
| 436 | PopUp_Hide(POPUP_CALL); |
| 437 | break; |
| 438 | } |
| 439 | } |
| 440 | |
| 441 | void CPocketPJDlg::on_call_state(pjsua_call_id call_id, pjsip_event *e) |
| 442 | { |
Nanang Izzuddin | 2e4f03f | 2009-04-27 19:18:38 +0000 | [diff] [blame] | 443 | PJ_UNUSED_ARG(e); |
| 444 | PJ_UNUSED_ARG(call_id); |
| 445 | |
Benny Prijono | 5d9c16f | 2008-02-22 23:38:47 +0000 | [diff] [blame] | 446 | theDlg->OnCallState(); |
| 447 | } |
| 448 | |
| 449 | void CPocketPJDlg::on_call_media_state(pjsua_call_id call_id) |
| 450 | { |
| 451 | pjsua_call_info call_info; |
| 452 | |
| 453 | pjsua_call_get_info(call_id, &call_info); |
| 454 | if (call_info.media_status == PJSUA_CALL_MEDIA_ACTIVE) { |
| 455 | pjsua_conf_connect(call_info.conf_slot, 0); |
| 456 | pjsua_conf_connect(0, call_info.conf_slot); |
| 457 | } |
| 458 | } |
| 459 | |
| 460 | void CPocketPJDlg::on_incoming_call(pjsua_acc_id acc_id, pjsua_call_id call_id, |
| 461 | pjsip_rx_data *rdata) |
| 462 | { |
Nanang Izzuddin | 2e4f03f | 2009-04-27 19:18:38 +0000 | [diff] [blame] | 463 | PJ_UNUSED_ARG(acc_id); |
| 464 | PJ_UNUSED_ARG(call_id); |
| 465 | PJ_UNUSED_ARG(rdata); |
Benny Prijono | 3614fbc | 2010-01-25 17:38:07 +0000 | [diff] [blame] | 466 | |
| 467 | theDlg->OnIncomingCall(); |
Benny Prijono | 5d9c16f | 2008-02-22 23:38:47 +0000 | [diff] [blame] | 468 | } |
| 469 | |
| 470 | void CPocketPJDlg::OnRegState() |
| 471 | { |
| 472 | pjsua_acc_info ai; |
| 473 | pjsua_acc_get_info(m_PjsuaAccId, &ai); |
| 474 | |
| 475 | CString acc_text = m_Cfg.m_User + _T("@") + m_Cfg.m_Domain; |
| 476 | |
| 477 | if (ai.expires>0 && ai.status/100==2) { |
| 478 | /* Registration success */ |
| 479 | HBITMAP old = m_BtnAcc.SetBitmap(::LoadBitmap(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_ONLINE)) ); |
Nanang Izzuddin | 2e4f03f | 2009-04-27 19:18:38 +0000 | [diff] [blame] | 480 | PJ_UNUSED_ARG(old); |
Benny Prijono | 5d9c16f | 2008-02-22 23:38:47 +0000 | [diff] [blame] | 481 | acc_text += " (OK)"; |
| 482 | m_AccId.SetWindowText(acc_text); |
Benny Prijono | 5d9c16f | 2008-02-22 23:38:47 +0000 | [diff] [blame] | 483 | } else if (ai.status/100 != 2) { |
| 484 | acc_text += " (err)"; |
| 485 | Error(_T("SIP registration error"), PJSIP_ERRNO_FROM_SIP_STATUS(ai.status)); |
| 486 | m_AccId.SetWindowText(acc_text); |
Benny Prijono | 5d9c16f | 2008-02-22 23:38:47 +0000 | [diff] [blame] | 487 | } |
Benny Prijono | 5796dca | 2008-02-23 00:24:44 +0000 | [diff] [blame] | 488 | PopUp_Hide(POPUP_REGISTRATION); |
Benny Prijono | 5d9c16f | 2008-02-22 23:38:47 +0000 | [diff] [blame] | 489 | } |
| 490 | |
| 491 | void CPocketPJDlg::on_reg_state(pjsua_acc_id acc_id) |
| 492 | { |
Nanang Izzuddin | 2e4f03f | 2009-04-27 19:18:38 +0000 | [diff] [blame] | 493 | PJ_UNUSED_ARG(acc_id); |
| 494 | |
Benny Prijono | 5d9c16f | 2008-02-22 23:38:47 +0000 | [diff] [blame] | 495 | theDlg->OnRegState(); |
| 496 | } |
| 497 | |
| 498 | void CPocketPJDlg::on_buddy_state(pjsua_buddy_id buddy_id) |
| 499 | { |
Nanang Izzuddin | 2e4f03f | 2009-04-27 19:18:38 +0000 | [diff] [blame] | 500 | PJ_UNUSED_ARG(buddy_id); |
| 501 | |
Benny Prijono | 5d9c16f | 2008-02-22 23:38:47 +0000 | [diff] [blame] | 502 | theDlg->RedrawBuddyList(); |
| 503 | } |
| 504 | |
| 505 | void CPocketPJDlg::on_pager(pjsua_call_id call_id, const pj_str_t *from, |
| 506 | const pj_str_t *to, const pj_str_t *contact, |
| 507 | const pj_str_t *mime_type, const pj_str_t *text) |
| 508 | { |
Nanang Izzuddin | 2e4f03f | 2009-04-27 19:18:38 +0000 | [diff] [blame] | 509 | PJ_UNUSED_ARG(call_id); |
| 510 | PJ_UNUSED_ARG(from); |
| 511 | PJ_UNUSED_ARG(to); |
| 512 | PJ_UNUSED_ARG(contact); |
| 513 | PJ_UNUSED_ARG(mime_type); |
| 514 | PJ_UNUSED_ARG(text); |
Benny Prijono | 5d9c16f | 2008-02-22 23:38:47 +0000 | [diff] [blame] | 515 | } |
| 516 | |
| 517 | ///////////////////////////////////////////////////////////////////////////// |
| 518 | // CPocketPJDlg message handlers |
| 519 | |
| 520 | BOOL CPocketPJDlg::OnInitDialog() |
| 521 | { |
| 522 | CDialog::OnInitDialog(); |
| 523 | |
| 524 | // Set the icon for this dialog. The framework does this automatically |
| 525 | // when the application's main window is not a dialog |
| 526 | SetIcon(m_hIcon, TRUE); // Set big icon |
| 527 | SetIcon(m_hIcon, FALSE); // Set small icon |
| 528 | |
| 529 | CenterWindow(GetDesktopWindow()); // center to the hpc screen |
| 530 | |
| 531 | // TODO: Add extra initialization here |
| 532 | |
| 533 | m_Cfg.LoadRegistry(); |
| 534 | //ShowWindow(SW_SHOW); |
| 535 | m_AccId.SetWindowText(m_Cfg.m_User); |
| 536 | |
| 537 | CImageList *il = new CImageList; |
| 538 | VERIFY(il->Create(16, 16, ILC_COLOR|ILC_MASK, 2, 4)); |
| 539 | |
| 540 | CBitmap *bmp = new CBitmap; |
| 541 | bmp->LoadBitmap(MAKEINTRESOURCE(IDB_BLANK)); |
| 542 | il->Add(bmp, RGB(255,255,255)); |
| 543 | bmp = new CBitmap; |
| 544 | bmp->LoadBitmap(MAKEINTRESOURCE(IDB_ONLINE)); |
| 545 | il->Add(bmp, RGB(255,255,255)); |
| 546 | |
| 547 | m_BuddyList.SetImageList(il, LVSIL_SMALL); |
| 548 | |
| 549 | if (m_Cfg.m_Domain.GetLength()==0 || Restart() == FALSE) { |
| 550 | for (;;) { |
| 551 | CSettingsDlg dlg(m_Cfg); |
| 552 | if (dlg.DoModal() != IDOK) { |
| 553 | EndDialog(IDOK); |
| 554 | return TRUE; |
| 555 | } |
| 556 | |
| 557 | m_Cfg.SaveRegistry(); |
| 558 | |
| 559 | if (Restart()) |
| 560 | break; |
| 561 | } |
| 562 | } |
| 563 | |
| 564 | RedrawBuddyList(); |
| 565 | return TRUE; // return TRUE unless you set the focus to a control |
| 566 | } |
| 567 | |
| 568 | |
| 569 | |
| 570 | void CPocketPJDlg::OnBtnAcc() |
| 571 | { |
| 572 | CMenu menu; |
| 573 | VERIFY(menu.LoadMenu(IDR_ACC_MENU)); |
| 574 | CMenu* pPopup = menu.GetSubMenu(0); |
| 575 | ASSERT(pPopup != NULL); |
| 576 | |
| 577 | RECT r; |
| 578 | m_BtnAcc.GetWindowRect(&r); |
| 579 | pPopup->TrackPopupMenu(TPM_LEFTALIGN, r.left+4, r.top+4, this); |
| 580 | } |
| 581 | |
| 582 | void CPocketPJDlg::OnBtnAction() |
| 583 | { |
| 584 | CMenu menu; |
| 585 | VERIFY(menu.LoadMenu(IDR_URI_MENU)); |
| 586 | CMenu* pPopup = menu.GetSubMenu(0); |
| 587 | ASSERT(pPopup != NULL); |
| 588 | |
| 589 | RECT r; |
| 590 | this->m_BtnUrlAction.GetWindowRect(&r); |
| 591 | pPopup->TrackPopupMenu(TPM_LEFTALIGN, r.left+4, r.top+4, this); |
| 592 | } |
| 593 | |
| 594 | void CPocketPJDlg::OnSettings() |
| 595 | { |
| 596 | for (;;) { |
| 597 | CSettingsDlg dlg(m_Cfg); |
| 598 | if (dlg.DoModal() != IDOK) { |
| 599 | return; |
| 600 | } |
| 601 | |
| 602 | m_Cfg.SaveRegistry(); |
| 603 | |
| 604 | if (Restart()) |
| 605 | break; |
| 606 | } |
| 607 | } |
| 608 | |
| 609 | void CPocketPJDlg::OnOK() |
| 610 | { |
| 611 | if (AfxMessageBox(_T("Quit PocketPJ?"), MB_YESNO)==IDYES) { |
| 612 | KillTimer(TIMER_ID); |
| 613 | PopUp_Show(POPUP_REGISTRATION, "", "Shutting down..", "", "", "", 0); |
| 614 | pjsua_destroy(); |
| 615 | CDialog::OnOK(); |
| 616 | PopUp_Hide(POPUP_REGISTRATION); |
| 617 | m_Cfg.SaveRegistry(); |
| 618 | return; |
| 619 | } |
| 620 | } |
| 621 | |
| 622 | void CPocketPJDlg::OnTimer(UINT nIDEvent) |
| 623 | { |
| 624 | pjsua_handle_events(10); |
| 625 | CDialog::OnTimer(nIDEvent); |
| 626 | } |
| 627 | |
| 628 | int CPocketPJDlg::FindBuddyInPjsua(const CString &Uri) |
| 629 | { |
| 630 | char uri[80]; |
| 631 | pjsua_buddy_id id[128]; |
| 632 | unsigned i, count = PJ_ARRAY_SIZE(id); |
| 633 | |
| 634 | if (pjsua_enum_buddies(id, &count) != PJ_SUCCESS) |
| 635 | return PJSUA_INVALID_ID; |
| 636 | if (count==0) |
| 637 | return PJSUA_INVALID_ID; |
| 638 | |
| 639 | pj_unicode_to_ansi((LPCTSTR)Uri, Uri.GetLength(), uri, sizeof(uri)); |
| 640 | |
| 641 | for (i=0; i<count; ++i) { |
| 642 | pjsua_buddy_info bi; |
| 643 | pjsua_buddy_get_info(id[i], &bi); |
| 644 | if (pj_strcmp2(&bi.uri, uri)==0) |
| 645 | return i; |
| 646 | } |
| 647 | |
| 648 | return PJSUA_INVALID_ID; |
| 649 | } |
| 650 | |
| 651 | int CPocketPJDlg::FindBuddyInCfg(const CString &uri) |
| 652 | { |
| 653 | int i; |
| 654 | for (i=0; i<m_Cfg.m_BuddyList.GetSize(); ++i) { |
| 655 | if (m_Cfg.m_BuddyList.GetAt(0) == uri) { |
| 656 | return i; |
| 657 | } |
| 658 | } |
| 659 | return -1; |
| 660 | } |
| 661 | |
| 662 | void CPocketPJDlg::RedrawBuddyList() |
| 663 | { |
| 664 | int i; |
| 665 | |
| 666 | m_BuddyList.DeleteAllItems(); |
| 667 | |
| 668 | for (i=0; i<m_Cfg.m_BuddyList.GetSize(); ++i) { |
| 669 | int isOnline; |
| 670 | int id; |
| 671 | |
| 672 | id = FindBuddyInPjsua(m_Cfg.m_BuddyList.GetAt(i)); |
| 673 | if (id != PJSUA_INVALID_ID) { |
| 674 | pjsua_buddy_info bi; |
| 675 | pjsua_buddy_get_info(id, &bi); |
| 676 | isOnline = (bi.status == PJSUA_BUDDY_STATUS_ONLINE); |
| 677 | } else { |
| 678 | isOnline = 0; |
| 679 | } |
| 680 | |
| 681 | LVITEM lvi; |
| 682 | memset(&lvi, 0, sizeof(lvi)); |
| 683 | lvi.mask = LVIF_TEXT | LVIF_IMAGE; |
| 684 | lvi.iItem = i; |
| 685 | lvi.iImage = isOnline; |
| 686 | lvi.pszText = (LPTSTR)(LPCTSTR)m_Cfg.m_BuddyList.GetAt(i); |
| 687 | |
| 688 | m_BuddyList.InsertItem(&lvi); |
| 689 | } |
| 690 | } |
| 691 | |
| 692 | void CPocketPJDlg::OnUriCall() |
| 693 | { |
| 694 | char tmp[120]; |
| 695 | CString uri; |
| 696 | pj_status_t status; |
| 697 | |
| 698 | m_Url.GetWindowText(uri); |
| 699 | pj_unicode_to_ansi((LPCTSTR)uri, uri.GetLength(), tmp, sizeof(tmp)); |
| 700 | if ((status=pjsua_verify_sip_url(tmp)) != PJ_SUCCESS) { |
| 701 | Error("The URL is not valid SIP URL", status); |
| 702 | return; |
| 703 | } |
| 704 | |
| 705 | pj_str_t dest_uri = pj_str(tmp); |
| 706 | pjsua_call_id call_id; |
| 707 | |
| 708 | status = pjsua_call_make_call(m_PjsuaAccId, &dest_uri, 0, NULL, NULL, &call_id); |
| 709 | |
| 710 | if (status != PJ_SUCCESS) |
| 711 | Error("Unable to make call", status); |
| 712 | } |
| 713 | |
| 714 | void CPocketPJDlg::OnUriAddBuddy() |
| 715 | { |
| 716 | int i; |
| 717 | char tmp[120]; |
| 718 | CString uri; |
| 719 | pj_status_t status; |
| 720 | |
| 721 | m_Url.GetWindowText(uri); |
| 722 | pj_unicode_to_ansi((LPCTSTR)uri, uri.GetLength(), tmp, sizeof(tmp)); |
| 723 | if ((status=pjsua_verify_sip_url(tmp)) != PJ_SUCCESS) { |
| 724 | Error("The URL is not valid SIP URL", status); |
| 725 | return; |
| 726 | } |
| 727 | |
| 728 | for (i=0; i<m_Cfg.m_BuddyList.GetSize(); ++i) { |
| 729 | if (m_Cfg.m_BuddyList.GetAt(0) == uri) { |
| 730 | AfxMessageBox(_T("The URI is already in the buddy list")); |
| 731 | return; |
| 732 | } |
| 733 | } |
| 734 | |
| 735 | m_Cfg.m_BuddyList.Add(uri); |
| 736 | RedrawBuddyList(); |
| 737 | } |
| 738 | |
| 739 | void CPocketPJDlg::OnUriDelBuddy() |
| 740 | { |
| 741 | CString uri; |
| 742 | |
| 743 | m_Url.GetWindowText(uri); |
| 744 | int i = FindBuddyInCfg(uri); |
| 745 | if (i<0) { |
| 746 | /* Buddy not found */ |
| 747 | return; |
| 748 | } |
| 749 | |
| 750 | m_Cfg.m_BuddyList.RemoveAt(i); |
| 751 | RedrawBuddyList(); |
| 752 | AfxMessageBox(_T("Buddy " + uri + " deleted")); |
| 753 | } |
| 754 | |
| 755 | void CPocketPJDlg::OnAccOnline() |
| 756 | { |
| 757 | pjsua_acc_set_online_status(m_PjsuaAccId, PJ_TRUE); |
| 758 | m_BtnAcc.SetBitmap(::LoadBitmap(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_ONLINE)) ); |
| 759 | } |
| 760 | |
| 761 | void CPocketPJDlg::OnAccInvisible() |
| 762 | { |
| 763 | pjsua_acc_set_online_status(m_PjsuaAccId, PJ_FALSE); |
| 764 | m_BtnAcc.SetBitmap(::LoadBitmap(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_INVISIBLE)) ); |
| 765 | } |
| 766 | |
| 767 | void CPocketPJDlg::OnPopUpButton(int btnNo) |
| 768 | { |
| 769 | if (btnNo == 1) { |
| 770 | pjsua_call_answer(0, 200, NULL, 0); |
| 771 | PopUp_Modify(POPUP_CALL, POPUP_EL_BUTTON1, ""); |
| 772 | } else if (btnNo == 2) { |
| 773 | // Hangup button |
| 774 | PopUp_Modify(POPUP_CALL, POPUP_EL_TITLE2, "Hang up.."); |
| 775 | PopUp_Modify(POPUP_CALL, POPUP_EL_TITLE3, ""); |
| 776 | pjsua_call_hangup(0, PJSIP_SC_DECLINE, 0, 0); |
| 777 | } |
| 778 | } |
| 779 | |
| 780 | void CPocketPJDlg::OnClickBuddyList(NMHDR* pNMHDR, LRESULT* pResult) |
| 781 | { |
| 782 | POSITION pos = m_BuddyList.GetFirstSelectedItemPosition(); |
Nanang Izzuddin | 2e4f03f | 2009-04-27 19:18:38 +0000 | [diff] [blame] | 783 | |
| 784 | PJ_UNUSED_ARG(pNMHDR); |
| 785 | |
Benny Prijono | 5d9c16f | 2008-02-22 23:38:47 +0000 | [diff] [blame] | 786 | if (pos != NULL) { |
| 787 | int iItem = m_BuddyList.GetNextSelectedItem(pos); |
| 788 | CString uri = m_BuddyList.GetItemText(iItem, 0); |
| 789 | m_Url.SetWindowText(uri); |
| 790 | } |
| 791 | *pResult = 0; |
| 792 | } |