blob: b8a6bf2f1e7b3b3853bd122c02513c3e7d2fc0c2 [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
397void CPocketPJDlg::OnCallState()
398{
399 pjsua_call_info ci;
400
401 pjsua_call_get_info(0, &ci);
402
403 switch (ci.state) {
404 case PJSIP_INV_STATE_NULL: /**< Before INVITE is sent or received */
405 break;
406 case PJSIP_INV_STATE_CALLING: /**< After INVITE is sent */
407 PopUp_Show(POPUP_CALL, "Calling..", ci.remote_info.ptr, "",
408 "", "Hangup", 0);
409 break;
410 case PJSIP_INV_STATE_INCOMING: /**< After INVITE is received. */
411 PopUp_Show(POPUP_CALL, "Incoming call..", ci.remote_info.ptr, "",
412 "Answer", "Hangup", 0);
413 pjsua_call_answer(0, 180, NULL, NULL);
Benny Prijono36e76ef2008-08-13 13:56:24 +0000414 if (m_Cfg.m_AutoAnswer)
415 OnPopUpButton(1);
Benny Prijono5d9c16f2008-02-22 23:38:47 +0000416 break;
417 case PJSIP_INV_STATE_EARLY: /**< After response with To tag. */
418 case PJSIP_INV_STATE_CONNECTING:/**< After 2xx is sent/received. */
419 case PJSIP_INV_STATE_CONFIRMED: /**< After ACK is sent/received. */
420 {
421 CString stateText = ci.state_text.ptr;
422 PopUp_Modify(POPUP_CALL, POPUP_EL_TITLE3, stateText);
423 }
424 break;
425 case PJSIP_INV_STATE_DISCONNECTED:/**< Session is terminated. */
426 PopUp_Modify(POPUP_CALL, POPUP_EL_TITLE3, "Disconnected");
427 PopUp_Hide(POPUP_CALL);
428 break;
429 }
430}
431
432void CPocketPJDlg::on_call_state(pjsua_call_id call_id, pjsip_event *e)
433{
Nanang Izzuddin2e4f03f2009-04-27 19:18:38 +0000434 PJ_UNUSED_ARG(e);
435 PJ_UNUSED_ARG(call_id);
436
Benny Prijono5d9c16f2008-02-22 23:38:47 +0000437 theDlg->OnCallState();
438}
439
440void CPocketPJDlg::on_call_media_state(pjsua_call_id call_id)
441{
442 pjsua_call_info call_info;
443
444 pjsua_call_get_info(call_id, &call_info);
445 if (call_info.media_status == PJSUA_CALL_MEDIA_ACTIVE) {
446 pjsua_conf_connect(call_info.conf_slot, 0);
447 pjsua_conf_connect(0, call_info.conf_slot);
448 }
449}
450
451void CPocketPJDlg::on_incoming_call(pjsua_acc_id acc_id, pjsua_call_id call_id,
452 pjsip_rx_data *rdata)
453{
Nanang Izzuddin2e4f03f2009-04-27 19:18:38 +0000454 PJ_UNUSED_ARG(acc_id);
455 PJ_UNUSED_ARG(call_id);
456 PJ_UNUSED_ARG(rdata);
Benny Prijono5d9c16f2008-02-22 23:38:47 +0000457}
458
459void CPocketPJDlg::OnRegState()
460{
461 pjsua_acc_info ai;
462 pjsua_acc_get_info(m_PjsuaAccId, &ai);
463
464 CString acc_text = m_Cfg.m_User + _T("@") + m_Cfg.m_Domain;
465
466 if (ai.expires>0 && ai.status/100==2) {
467 /* Registration success */
468 HBITMAP old = m_BtnAcc.SetBitmap(::LoadBitmap(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_ONLINE)) );
Nanang Izzuddin2e4f03f2009-04-27 19:18:38 +0000469 PJ_UNUSED_ARG(old);
Benny Prijono5d9c16f2008-02-22 23:38:47 +0000470 acc_text += " (OK)";
471 m_AccId.SetWindowText(acc_text);
Benny Prijono5d9c16f2008-02-22 23:38:47 +0000472 } else if (ai.status/100 != 2) {
473 acc_text += " (err)";
474 Error(_T("SIP registration error"), PJSIP_ERRNO_FROM_SIP_STATUS(ai.status));
475 m_AccId.SetWindowText(acc_text);
Benny Prijono5d9c16f2008-02-22 23:38:47 +0000476 }
Benny Prijono5796dca2008-02-23 00:24:44 +0000477 PopUp_Hide(POPUP_REGISTRATION);
Benny Prijono5d9c16f2008-02-22 23:38:47 +0000478}
479
480void CPocketPJDlg::on_reg_state(pjsua_acc_id acc_id)
481{
Nanang Izzuddin2e4f03f2009-04-27 19:18:38 +0000482 PJ_UNUSED_ARG(acc_id);
483
Benny Prijono5d9c16f2008-02-22 23:38:47 +0000484 theDlg->OnRegState();
485}
486
487void CPocketPJDlg::on_buddy_state(pjsua_buddy_id buddy_id)
488{
Nanang Izzuddin2e4f03f2009-04-27 19:18:38 +0000489 PJ_UNUSED_ARG(buddy_id);
490
Benny Prijono5d9c16f2008-02-22 23:38:47 +0000491 theDlg->RedrawBuddyList();
492}
493
494void CPocketPJDlg::on_pager(pjsua_call_id call_id, const pj_str_t *from,
495 const pj_str_t *to, const pj_str_t *contact,
496 const pj_str_t *mime_type, const pj_str_t *text)
497{
Nanang Izzuddin2e4f03f2009-04-27 19:18:38 +0000498 PJ_UNUSED_ARG(call_id);
499 PJ_UNUSED_ARG(from);
500 PJ_UNUSED_ARG(to);
501 PJ_UNUSED_ARG(contact);
502 PJ_UNUSED_ARG(mime_type);
503 PJ_UNUSED_ARG(text);
Benny Prijono5d9c16f2008-02-22 23:38:47 +0000504}
505
506/////////////////////////////////////////////////////////////////////////////
507// CPocketPJDlg message handlers
508
509BOOL CPocketPJDlg::OnInitDialog()
510{
511 CDialog::OnInitDialog();
512
513 // Set the icon for this dialog. The framework does this automatically
514 // when the application's main window is not a dialog
515 SetIcon(m_hIcon, TRUE); // Set big icon
516 SetIcon(m_hIcon, FALSE); // Set small icon
517
518 CenterWindow(GetDesktopWindow()); // center to the hpc screen
519
520 // TODO: Add extra initialization here
521
522 m_Cfg.LoadRegistry();
523 //ShowWindow(SW_SHOW);
524 m_AccId.SetWindowText(m_Cfg.m_User);
525
526 CImageList *il = new CImageList;
527 VERIFY(il->Create(16, 16, ILC_COLOR|ILC_MASK, 2, 4));
528
529 CBitmap *bmp = new CBitmap;
530 bmp->LoadBitmap(MAKEINTRESOURCE(IDB_BLANK));
531 il->Add(bmp, RGB(255,255,255));
532 bmp = new CBitmap;
533 bmp->LoadBitmap(MAKEINTRESOURCE(IDB_ONLINE));
534 il->Add(bmp, RGB(255,255,255));
535
536 m_BuddyList.SetImageList(il, LVSIL_SMALL);
537
538 if (m_Cfg.m_Domain.GetLength()==0 || Restart() == FALSE) {
539 for (;;) {
540 CSettingsDlg dlg(m_Cfg);
541 if (dlg.DoModal() != IDOK) {
542 EndDialog(IDOK);
543 return TRUE;
544 }
545
546 m_Cfg.SaveRegistry();
547
548 if (Restart())
549 break;
550 }
551 }
552
553 RedrawBuddyList();
554 return TRUE; // return TRUE unless you set the focus to a control
555}
556
557
558
559void CPocketPJDlg::OnBtnAcc()
560{
561 CMenu menu;
562 VERIFY(menu.LoadMenu(IDR_ACC_MENU));
563 CMenu* pPopup = menu.GetSubMenu(0);
564 ASSERT(pPopup != NULL);
565
566 RECT r;
567 m_BtnAcc.GetWindowRect(&r);
568 pPopup->TrackPopupMenu(TPM_LEFTALIGN, r.left+4, r.top+4, this);
569}
570
571void CPocketPJDlg::OnBtnAction()
572{
573 CMenu menu;
574 VERIFY(menu.LoadMenu(IDR_URI_MENU));
575 CMenu* pPopup = menu.GetSubMenu(0);
576 ASSERT(pPopup != NULL);
577
578 RECT r;
579 this->m_BtnUrlAction.GetWindowRect(&r);
580 pPopup->TrackPopupMenu(TPM_LEFTALIGN, r.left+4, r.top+4, this);
581}
582
583void CPocketPJDlg::OnSettings()
584{
585 for (;;) {
586 CSettingsDlg dlg(m_Cfg);
587 if (dlg.DoModal() != IDOK) {
588 return;
589 }
590
591 m_Cfg.SaveRegistry();
592
593 if (Restart())
594 break;
595 }
596}
597
598void CPocketPJDlg::OnOK()
599{
600 if (AfxMessageBox(_T("Quit PocketPJ?"), MB_YESNO)==IDYES) {
601 KillTimer(TIMER_ID);
602 PopUp_Show(POPUP_REGISTRATION, "", "Shutting down..", "", "", "", 0);
603 pjsua_destroy();
604 CDialog::OnOK();
605 PopUp_Hide(POPUP_REGISTRATION);
606 m_Cfg.SaveRegistry();
607 return;
608 }
609}
610
611void CPocketPJDlg::OnTimer(UINT nIDEvent)
612{
613 pjsua_handle_events(10);
614 CDialog::OnTimer(nIDEvent);
615}
616
617int CPocketPJDlg::FindBuddyInPjsua(const CString &Uri)
618{
619 char uri[80];
620 pjsua_buddy_id id[128];
621 unsigned i, count = PJ_ARRAY_SIZE(id);
622
623 if (pjsua_enum_buddies(id, &count) != PJ_SUCCESS)
624 return PJSUA_INVALID_ID;
625 if (count==0)
626 return PJSUA_INVALID_ID;
627
628 pj_unicode_to_ansi((LPCTSTR)Uri, Uri.GetLength(), uri, sizeof(uri));
629
630 for (i=0; i<count; ++i) {
631 pjsua_buddy_info bi;
632 pjsua_buddy_get_info(id[i], &bi);
633 if (pj_strcmp2(&bi.uri, uri)==0)
634 return i;
635 }
636
637 return PJSUA_INVALID_ID;
638}
639
640int CPocketPJDlg::FindBuddyInCfg(const CString &uri)
641{
642 int i;
643 for (i=0; i<m_Cfg.m_BuddyList.GetSize(); ++i) {
644 if (m_Cfg.m_BuddyList.GetAt(0) == uri) {
645 return i;
646 }
647 }
648 return -1;
649}
650
651void CPocketPJDlg::RedrawBuddyList()
652{
653 int i;
654
655 m_BuddyList.DeleteAllItems();
656
657 for (i=0; i<m_Cfg.m_BuddyList.GetSize(); ++i) {
658 int isOnline;
659 int id;
660
661 id = FindBuddyInPjsua(m_Cfg.m_BuddyList.GetAt(i));
662 if (id != PJSUA_INVALID_ID) {
663 pjsua_buddy_info bi;
664 pjsua_buddy_get_info(id, &bi);
665 isOnline = (bi.status == PJSUA_BUDDY_STATUS_ONLINE);
666 } else {
667 isOnline = 0;
668 }
669
670 LVITEM lvi;
671 memset(&lvi, 0, sizeof(lvi));
672 lvi.mask = LVIF_TEXT | LVIF_IMAGE;
673 lvi.iItem = i;
674 lvi.iImage = isOnline;
675 lvi.pszText = (LPTSTR)(LPCTSTR)m_Cfg.m_BuddyList.GetAt(i);
676
677 m_BuddyList.InsertItem(&lvi);
678 }
679}
680
681void CPocketPJDlg::OnUriCall()
682{
683 char tmp[120];
684 CString uri;
685 pj_status_t status;
686
687 m_Url.GetWindowText(uri);
688 pj_unicode_to_ansi((LPCTSTR)uri, uri.GetLength(), tmp, sizeof(tmp));
689 if ((status=pjsua_verify_sip_url(tmp)) != PJ_SUCCESS) {
690 Error("The URL is not valid SIP URL", status);
691 return;
692 }
693
694 pj_str_t dest_uri = pj_str(tmp);
695 pjsua_call_id call_id;
696
697 status = pjsua_call_make_call(m_PjsuaAccId, &dest_uri, 0, NULL, NULL, &call_id);
698
699 if (status != PJ_SUCCESS)
700 Error("Unable to make call", status);
701}
702
703void CPocketPJDlg::OnUriAddBuddy()
704{
705 int i;
706 char tmp[120];
707 CString uri;
708 pj_status_t status;
709
710 m_Url.GetWindowText(uri);
711 pj_unicode_to_ansi((LPCTSTR)uri, uri.GetLength(), tmp, sizeof(tmp));
712 if ((status=pjsua_verify_sip_url(tmp)) != PJ_SUCCESS) {
713 Error("The URL is not valid SIP URL", status);
714 return;
715 }
716
717 for (i=0; i<m_Cfg.m_BuddyList.GetSize(); ++i) {
718 if (m_Cfg.m_BuddyList.GetAt(0) == uri) {
719 AfxMessageBox(_T("The URI is already in the buddy list"));
720 return;
721 }
722 }
723
724 m_Cfg.m_BuddyList.Add(uri);
725 RedrawBuddyList();
726}
727
728void CPocketPJDlg::OnUriDelBuddy()
729{
730 CString uri;
731
732 m_Url.GetWindowText(uri);
733 int i = FindBuddyInCfg(uri);
734 if (i<0) {
735 /* Buddy not found */
736 return;
737 }
738
739 m_Cfg.m_BuddyList.RemoveAt(i);
740 RedrawBuddyList();
741 AfxMessageBox(_T("Buddy " + uri + " deleted"));
742}
743
744void CPocketPJDlg::OnAccOnline()
745{
746 pjsua_acc_set_online_status(m_PjsuaAccId, PJ_TRUE);
747 m_BtnAcc.SetBitmap(::LoadBitmap(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_ONLINE)) );
748}
749
750void CPocketPJDlg::OnAccInvisible()
751{
752 pjsua_acc_set_online_status(m_PjsuaAccId, PJ_FALSE);
753 m_BtnAcc.SetBitmap(::LoadBitmap(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_INVISIBLE)) );
754}
755
756void CPocketPJDlg::OnPopUpButton(int btnNo)
757{
758 if (btnNo == 1) {
759 pjsua_call_answer(0, 200, NULL, 0);
760 PopUp_Modify(POPUP_CALL, POPUP_EL_BUTTON1, "");
761 } else if (btnNo == 2) {
762 // Hangup button
763 PopUp_Modify(POPUP_CALL, POPUP_EL_TITLE2, "Hang up..");
764 PopUp_Modify(POPUP_CALL, POPUP_EL_TITLE3, "");
765 pjsua_call_hangup(0, PJSIP_SC_DECLINE, 0, 0);
766 }
767}
768
769void CPocketPJDlg::OnClickBuddyList(NMHDR* pNMHDR, LRESULT* pResult)
770{
771 POSITION pos = m_BuddyList.GetFirstSelectedItemPosition();
Nanang Izzuddin2e4f03f2009-04-27 19:18:38 +0000772
773 PJ_UNUSED_ARG(pNMHDR);
774
Benny Prijono5d9c16f2008-02-22 23:38:47 +0000775 if (pos != NULL) {
776 int iItem = m_BuddyList.GetNextSelectedItem(pos);
777 CString uri = m_BuddyList.GetItemText(iItem, 0);
778 m_Url.SetWindowText(uri);
779 }
780 *pResult = 0;
781}