blob: 87caf19b084129a345c840cf8dea3bd21a09f725 [file] [log] [blame]
Benny Prijono5d9c16f2008-02-22 23:38:47 +00001// 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
12static char THIS_FILE[] = __FILE__;
13#endif
14
15#define TIMER_ID 101
16static CPocketPJDlg *theDlg;
17
18/////////////////////////////////////////////////////////////////////////////
19// CPocketPJDlg dialog
20
21CPocketPJDlg::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
42void 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
54BEGIN_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
67END_MESSAGE_MAP()
68
69
70void 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
81BOOL CPocketPJDlg::Restart()
82{
Benny Prijono36e76ef2008-08-13 13:56:24 +000083 unsigned i;
Benny Prijono5d9c16f2008-02-22 23:38:47 +000084 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 Prijono981e59e2009-12-29 15:33:13 +0000134 PIP_ADDR_STRING pDNS = NULL;
Benny Prijono5d9c16f2008-02-22 23:38:47 +0000135 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 Prijono981e59e2009-12-29 15:33:13 +0000141 } else if (fi.CurrentDnsServer) {
142 pDNS = fi.CurrentDnsServer;
143 } else if (fi.DnsServerList.IpAddress.String[0] != 0) {
144 pDNS = &fi.DnsServerList;
145 } else {
Benny Prijono5d9c16f2008-02-22 23:38:47 +0000146 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 Prijono981e59e2009-12-29 15:33:13 +0000162 strcpy(nameserver, pDNS->IpAddress.String);
Benny Prijono5d9c16f2008-02-22 23:38:47 +0000163 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 Prijono981e59e2009-12-29 15:33:13 +0000176 log_cfg.msg_logging = PJ_TRUE;
Benny Prijono5d9c16f2008-02-22 23:38:47 +0000177 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 Izzuddinc91cd642009-05-06 18:59:31 +0000185 // use default quality setting
186 //media_cfg.quality = 5;
Benny Prijono5d9c16f2008-02-22 23:38:47 +0000187 media_cfg.thread_cnt = 1;
188 media_cfg.enable_ice = m_Cfg.m_UseIce;
Benny Prijono36e76ef2008-08-13 13:56:24 +0000189 media_cfg.no_vad = !m_Cfg.m_VAD;
Benny Prijono4d3eed12008-03-11 13:18:48 +0000190
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 Prijono5d9c16f2008-02-22 23:38:47 +0000196 // 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 Prijono36e76ef2008-08-13 13:56:24 +0000207 PopUp_Modify(POPUP_REGISTRATION, POPUP_EL_TITLE3, "Adding UDP transport..");
Benny Prijono5d9c16f2008-02-22 23:38:47 +0000208 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 Prijono981e59e2009-12-29 15:33:13 +0000222 // 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 Prijono36e76ef2008-08-13 13:56:24 +0000226 // 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 Prijono5d9c16f2008-02-22 23:38:47 +0000243 // Adjust codecs priority
244 pj_str_t tmp;
Benny Prijono36e76ef2008-08-13 13:56:24 +0000245 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 Prijono5d9c16f2008-02-22 23:38:47 +0000249
Benny Prijono36e76ef2008-08-13 13:56:24 +0000250 pj_unicode_to_ansi((LPCTSTR)codec, codec.GetLength(),
251 tmp_nam, sizeof(tmp_nam));
Nanang Izzuddin2e4f03f2009-04-27 19:18:38 +0000252 pjsua_codec_set_priority(pj_cstr(&tmp, tmp_nam), (pj_uint8_t)(200-i));
Benny Prijono36e76ef2008-08-13 13:56:24 +0000253 }
Benny Prijono5d9c16f2008-02-22 23:38:47 +0000254
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 Izzuddin51b1e552008-09-16 15:15:45 +0000291#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
Benny Prijono9b862572008-05-22 10:49:42 +0000292 acc_cfg.use_srtp = (m_Cfg.m_UseSrtp ? PJMEDIA_SRTP_OPTIONAL : PJMEDIA_SRTP_DISABLED);
Benny Prijono5d9c16f2008-02-22 23:38:47 +0000293 acc_cfg.srtp_secure_signaling = 0;
Nanang Izzuddin51b1e552008-09-16 15:15:45 +0000294#endif
295
Benny Prijono5d9c16f2008-02-22 23:38:47 +0000296 acc_cfg.publish_enabled = m_Cfg.m_UsePublish;
297
Benny Prijono36e76ef2008-08-13 13:56:24 +0000298 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 Prijono5d9c16f2008-02-22 23:38:47 +0000307 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
327void 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 Izzuddin2e4f03f2009-04-27 19:18:38 +0000335 PJ_UNUSED_ARG(userData);
336
Benny Prijono5d9c16f2008-02-22 23:38:47 +0000337 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
352void 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
377void 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 Prijono3614fbc2010-01-25 17:38:07 +0000397void 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 Prijono5d9c16f2008-02-22 23:38:47 +0000410void 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 Prijono3614fbc2010-01-25 17:38:07 +0000424 OnIncomingCall();
Benny Prijono5d9c16f2008-02-22 23:38:47 +0000425 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
441void CPocketPJDlg::on_call_state(pjsua_call_id call_id, pjsip_event *e)
442{
Nanang Izzuddin2e4f03f2009-04-27 19:18:38 +0000443 PJ_UNUSED_ARG(e);
444 PJ_UNUSED_ARG(call_id);
445
Benny Prijono5d9c16f2008-02-22 23:38:47 +0000446 theDlg->OnCallState();
447}
448
449void 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
460void CPocketPJDlg::on_incoming_call(pjsua_acc_id acc_id, pjsua_call_id call_id,
461 pjsip_rx_data *rdata)
462{
Nanang Izzuddin2e4f03f2009-04-27 19:18:38 +0000463 PJ_UNUSED_ARG(acc_id);
464 PJ_UNUSED_ARG(call_id);
465 PJ_UNUSED_ARG(rdata);
Benny Prijono3614fbc2010-01-25 17:38:07 +0000466
467 theDlg->OnIncomingCall();
Benny Prijono5d9c16f2008-02-22 23:38:47 +0000468}
469
470void 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 Izzuddin2e4f03f2009-04-27 19:18:38 +0000480 PJ_UNUSED_ARG(old);
Benny Prijono5d9c16f2008-02-22 23:38:47 +0000481 acc_text += " (OK)";
482 m_AccId.SetWindowText(acc_text);
Benny Prijono5d9c16f2008-02-22 23:38:47 +0000483 } 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 Prijono5d9c16f2008-02-22 23:38:47 +0000487 }
Benny Prijono5796dca2008-02-23 00:24:44 +0000488 PopUp_Hide(POPUP_REGISTRATION);
Benny Prijono5d9c16f2008-02-22 23:38:47 +0000489}
490
491void CPocketPJDlg::on_reg_state(pjsua_acc_id acc_id)
492{
Nanang Izzuddin2e4f03f2009-04-27 19:18:38 +0000493 PJ_UNUSED_ARG(acc_id);
494
Benny Prijono5d9c16f2008-02-22 23:38:47 +0000495 theDlg->OnRegState();
496}
497
498void CPocketPJDlg::on_buddy_state(pjsua_buddy_id buddy_id)
499{
Nanang Izzuddin2e4f03f2009-04-27 19:18:38 +0000500 PJ_UNUSED_ARG(buddy_id);
501
Benny Prijono5d9c16f2008-02-22 23:38:47 +0000502 theDlg->RedrawBuddyList();
503}
504
505void 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 Izzuddin2e4f03f2009-04-27 19:18:38 +0000509 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 Prijono5d9c16f2008-02-22 23:38:47 +0000515}
516
517/////////////////////////////////////////////////////////////////////////////
518// CPocketPJDlg message handlers
519
520BOOL 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
570void 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
582void 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
594void 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
609void 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
622void CPocketPJDlg::OnTimer(UINT nIDEvent)
623{
624 pjsua_handle_events(10);
625 CDialog::OnTimer(nIDEvent);
626}
627
628int 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
651int 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
662void 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
692void 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
714void 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
739void 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
755void CPocketPJDlg::OnAccOnline()
756{
757 pjsua_acc_set_online_status(m_PjsuaAccId, PJ_TRUE);
758 m_BtnAcc.SetBitmap(::LoadBitmap(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_ONLINE)) );
759}
760
761void CPocketPJDlg::OnAccInvisible()
762{
763 pjsua_acc_set_online_status(m_PjsuaAccId, PJ_FALSE);
764 m_BtnAcc.SetBitmap(::LoadBitmap(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_INVISIBLE)) );
765}
766
767void 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
780void CPocketPJDlg::OnClickBuddyList(NMHDR* pNMHDR, LRESULT* pResult)
781{
782 POSITION pos = m_BuddyList.GetFirstSelectedItemPosition();
Nanang Izzuddin2e4f03f2009-04-27 19:18:38 +0000783
784 PJ_UNUSED_ARG(pNMHDR);
785
Benny Prijono5d9c16f2008-02-22 23:38:47 +0000786 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}