~ubuntu-branches/ubuntu/trusty/sflphone/trusty

« back to all changes in this revision

Viewing changes to daemon/libs/pjproject-2.1.0/pjsip-apps/src/pocketpj/PocketPJDlg.cpp

  • Committer: Package Import Robot
  • Author(s): Mark Purcell
  • Date: 2014-01-28 18:23:36 UTC
  • mfrom: (4.3.4 sid)
  • Revision ID: package-import@ubuntu.com-20140128182336-jrsv0k9u6cawc068
Tags: 1.3.0-1
* New upstream release 
  - Fixes "New Upstream Release" (Closes: #735846)
  - Fixes "Ringtone does not stop" (Closes: #727164)
  - Fixes "[sflphone-kde] crash on startup" (Closes: #718178)
  - Fixes "sflphone GUI crashes when call is hung up" (Closes: #736583)
* Build-Depends: ensure GnuTLS 2.6
  - libucommon-dev (>= 6.0.7-1.1), libccrtp-dev (>= 2.0.6-3)
  - Fixes "FTBFS Build-Depends libgnutls{26,28}-dev" (Closes: #722040)
* Fix "boost 1.49 is going away" unversioned Build-Depends: (Closes: #736746)
* Add Build-Depends: libsndfile-dev, nepomuk-core-dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
{
 
83
    unsigned i;
 
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;
 
134
        PIP_ADDR_STRING pDNS = NULL;
 
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.");
 
141
        } else if (fi.CurrentDnsServer) {
 
142
            pDNS = fi.CurrentDnsServer;
 
143
        } else if (fi.DnsServerList.IpAddress.String[0] != 0) {
 
144
            pDNS = &fi.DnsServerList;
 
145
        } else {
 
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 {
 
162
            strcpy(nameserver, pDNS->IpAddress.String);
 
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);
 
176
    log_cfg.msg_logging = PJ_TRUE;
 
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;
 
185
    // use default quality setting
 
186
    //media_cfg.quality = 5;
 
187
    media_cfg.thread_cnt = 1;
 
188
    media_cfg.enable_ice = m_Cfg.m_UseIce;
 
189
    media_cfg.no_vad = !m_Cfg.m_VAD;
 
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
 
 
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
 
207
    PopUp_Modify(POPUP_REGISTRATION, POPUP_EL_TITLE3, "Adding UDP transport..");
 
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
 
 
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) {
 
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
 
 
243
    // Adjust codecs priority
 
244
    pj_str_t tmp;
 
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];
 
249
 
 
250
        pj_unicode_to_ansi((LPCTSTR)codec, codec.GetLength(),
 
251
                           tmp_nam, sizeof(tmp_nam));
 
252
        pjsua_codec_set_priority(pj_cstr(&tmp, tmp_nam), (pj_uint8_t)(200-i));
 
253
    }
 
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
 
 
291
#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
 
292
    acc_cfg.use_srtp = (m_Cfg.m_UseSrtp ? PJMEDIA_SRTP_OPTIONAL : PJMEDIA_SRTP_DISABLED);
 
293
    acc_cfg.srtp_secure_signaling = 0;
 
294
#endif
 
295
 
 
296
    acc_cfg.publish_enabled = m_Cfg.m_UsePublish;
 
297
    
 
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
 
 
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
{
 
335
    PJ_UNUSED_ARG(userData);
 
336
 
 
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
 
 
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
 
 
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.          */
 
424
        OnIncomingCall();
 
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
{
 
443
    PJ_UNUSED_ARG(e);
 
444
    PJ_UNUSED_ARG(call_id);
 
445
 
 
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
{
 
463
    PJ_UNUSED_ARG(acc_id);
 
464
    PJ_UNUSED_ARG(call_id);
 
465
    PJ_UNUSED_ARG(rdata);
 
466
 
 
467
    theDlg->OnIncomingCall();
 
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)) );
 
480
        PJ_UNUSED_ARG(old);
 
481
        acc_text += " (OK)";
 
482
        m_AccId.SetWindowText(acc_text);
 
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);
 
487
    }
 
488
    PopUp_Hide(POPUP_REGISTRATION);
 
489
}
 
490
 
 
491
void CPocketPJDlg::on_reg_state(pjsua_acc_id acc_id)
 
492
{
 
493
    PJ_UNUSED_ARG(acc_id);
 
494
 
 
495
    theDlg->OnRegState();
 
496
}
 
497
 
 
498
void CPocketPJDlg::on_buddy_state(pjsua_buddy_id buddy_id)
 
499
{
 
500
    PJ_UNUSED_ARG(buddy_id);
 
501
 
 
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
{
 
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);
 
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();
 
783
 
 
784
    PJ_UNUSED_ARG(pNMHDR);
 
785
 
 
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
}