~noskcaj/ubuntu/saucy/sflphone/merge-1.2.3-2

« back to all changes in this revision

Viewing changes to daemon/src/sip/sipvoiplink.cpp

  • Committer: Package Import Robot
  • Author(s): Mark Purcell
  • Date: 2012-05-19 21:46:37 UTC
  • mfrom: (1.1.7)
  • Revision ID: package-import@ubuntu.com-20120519214637-la8rbrford5kj6m3
Tags: 1.1.0-1
* New upstream release 
  - Fixes "FTBFS with libccrtp-dev/2.0.2 from experimental" (Closes: #663282)
* NEW Maintainer: Debian VoIP Team - Thanks Francois for your work.
  - (Closes: #665789: O: sflphone -- SIP and IAX2 compatible VoIP phone)
* Added Build-Depends: libdbus-c++-bin
* Add gcc47-fixes.patch

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 *  Copyright (C) 2004, 2005, 2006, 2008, 2009, 2010 Savoir-Faire Linux Inc.
3
 
 *
4
3
 *  Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
5
4
 *  Author: Yun Liu <yun.liu@savoirfairelinux.com>
6
5
 *  Author: Pierre-Luc Bacon <pierre-luc.bacon@savoirfairelinux.com>
36
35
#include "config.h"
37
36
#endif
38
37
 
 
38
#include "sip_utils.h"
 
39
 
39
40
#include "sipvoiplink.h"
40
 
 
 
41
#include "array_size.h"
41
42
#include "manager.h"
 
43
#include "logger.h"
42
44
 
43
45
#include "sip/sdp.h"
44
46
#include "sipcall.h"
45
47
#include "sipaccount.h"
46
48
#include "eventthread.h"
47
49
#include "sdes_negotiator.h"
 
50
#include "array_size.h"
48
51
 
49
52
#include "dbus/dbusmanager.h"
50
53
#include "dbus/callmanager.h"
 
54
#include "dbus/configurationmanager.h"
51
55
 
52
 
#include "hooks/urlhook.h"
53
56
#include "im/instant_messaging.h"
54
57
 
55
58
#include "audio/audiolayer.h"
57
60
#include "pjsip/sip_endpoint.h"
58
61
#include "pjsip/sip_transport_tls.h"
59
62
#include "pjsip/sip_uri.h"
60
 
#include <pjnath.h>
 
63
#include "pjnath.h"
61
64
 
62
65
#include <netinet/in.h>
63
66
#include <arpa/nameser.h>
 
67
#include <arpa/inet.h>
64
68
#include <resolv.h>
65
69
#include <istream>
66
70
#include <utility> // for std::pair
67
71
 
68
 
#include <sys/types.h>
69
 
#include <sys/socket.h>
70
 
#include <sys/ioctl.h>
71
 
#include <linux/if.h>
72
 
 
73
72
#include <map>
74
73
 
75
74
using namespace sfl;
76
75
 
 
76
SIPVoIPLink *SIPVoIPLink::instance_ = 0;
 
77
bool SIPVoIPLink::destroyed_ = false;
 
78
 
77
79
namespace {
78
80
 
79
 
static pjsip_transport *localUDPTransport_ = NULL; /** The default transport (5060) */
80
 
 
81
81
/** A map to retreive SFLphone internal call id
82
82
 *  Given a SIP call ID (usefull for transaction sucha as transfer)*/
83
83
static std::map<std::string, std::string> transferCallID;
91
91
 */
92
92
void setCallMediaLocal(SIPCall* call, const std::string &localIP);
93
93
 
94
 
/**
95
 
 * Helper function to parser header from incoming sip messages
96
 
 */
97
 
std::string fetchHeaderValue(pjsip_msg *msg, const std::string &field);
98
 
 
99
94
static pj_caching_pool pool_cache, *cp_ = &pool_cache;
100
95
static pj_pool_t *pool_;
101
96
static pjsip_endpoint *endpt_;
102
97
static pjsip_module mod_ua_;
103
 
static pj_thread_t *thread;
 
98
static pj_thread_t *thread_;
104
99
 
105
 
void sdp_media_update_cb(pjsip_inv_session *inv, pj_status_t status UNUSED);
 
100
void sdp_media_update_cb(pjsip_inv_session *inv, pj_status_t status);
106
101
void sdp_request_offer_cb(pjsip_inv_session *inv, const pjmedia_sdp_session *offer);
107
102
void sdp_create_offer_cb(pjsip_inv_session *inv, pjmedia_sdp_session **p_offer);
108
103
void invite_session_state_changed_cb(pjsip_inv_session *inv, pjsip_event *e);
110
105
void transaction_state_changed_cb(pjsip_inv_session *inv, pjsip_transaction *tsx, pjsip_event *e);
111
106
void registration_cb(pjsip_regc_cbparam *param);
112
107
pj_bool_t transaction_request_cb(pjsip_rx_data *rdata);
113
 
pj_bool_t transaction_response_cb(pjsip_rx_data *rdata UNUSED) ;
 
108
pj_bool_t transaction_response_cb(pjsip_rx_data *rdata) ;
114
109
 
115
110
void transfer_client_cb(pjsip_evsub *sub, pjsip_event *event);
116
111
 
126
121
 */
127
122
void onCallTransfered(pjsip_inv_session *inv, pjsip_rx_data *rdata);
128
123
 
129
 
std::string getSIPLocalIP()
130
 
{
131
 
    pj_sockaddr ip_addr;
132
 
 
133
 
    if (pj_gethostip(pj_AF_INET(), &ip_addr) == PJ_SUCCESS)
134
 
        return pj_inet_ntoa(ip_addr.ipv4.sin_addr);
135
 
    else  {
136
 
        ERROR("SIPVoIPLink: Could not get local IP");
137
 
        return "";
138
 
    }
139
 
}
140
 
 
141
 
pjsip_route_hdr *createRouteSet(const std::string &route, pj_pool_t *hdr_pool)
142
 
{
143
 
    int port = 0;
144
 
    std::string host;
145
 
 
146
 
    size_t found = route.find(":");
147
 
 
148
 
    if (found != std::string::npos) {
149
 
        host = route.substr(0, found);
150
 
        port = atoi(route.substr(found + 1, route.length()).c_str());
151
 
    } else
152
 
        host = route;
153
 
 
154
 
    pjsip_route_hdr *route_set = pjsip_route_hdr_create(hdr_pool);
155
 
    pjsip_route_hdr *routing = pjsip_route_hdr_create(hdr_pool);
156
 
    pjsip_sip_uri *url = pjsip_sip_uri_create(hdr_pool, 0);
157
 
    routing->name_addr.uri = (pjsip_uri*) url;
158
 
    pj_strdup2(hdr_pool, &url->host, host.c_str());
159
 
    url->port = port;
160
 
 
161
 
    pj_list_push_back(route_set, pjsip_hdr_clone(hdr_pool, routing));
162
 
 
163
 
    return route_set;
164
 
}
165
 
 
166
124
void handleIncomingOptions(pjsip_rx_data *rdata)
167
125
{
168
126
    pjsip_tx_data *tdata;
174
132
    const pjsip_hdr *cap_hdr = hdr; \
175
133
    if (cap_hdr) \
176
134
    pjsip_msg_add_hdr (tdata->msg, (pjsip_hdr*) pjsip_hdr_clone (tdata->pool, cap_hdr)); \
177
 
} while(0)
 
135
} while (0)
178
136
#define ADD_CAP(cap) ADD_HDR(pjsip_endpt_get_capability(endpt_, cap, NULL));
179
137
 
180
138
    ADD_CAP(PJSIP_H_ALLOW);
207
165
         * ACK for a 2xx response must be send using this method.
208
166
         */
209
167
        pjsip_tx_data *tdata;
210
 
        pjsip_dlg_create_request(dlg, &pjsip_ack_method, rdata->msg_info.cseq->cseq, &tdata);
211
 
        pjsip_dlg_send_request(dlg, tdata, -1, NULL);
 
168
        if (rdata->msg_info.cseq) {
 
169
            pjsip_dlg_create_request(dlg, &pjsip_ack_method, rdata->msg_info.cseq->cseq, &tdata);
 
170
            pjsip_dlg_send_request(dlg, tdata, -1, NULL);
 
171
        }
212
172
    }
213
173
 
214
174
    return PJ_SUCCESS;
215
175
}
216
176
 
217
 
std::string parseDisplayName(const char * buffer)
218
 
{
219
 
    const char* from_header = strstr(buffer, "From: ");
220
 
 
221
 
    if (!from_header)
222
 
        return "";
223
 
 
224
 
    std::string temp(from_header);
225
 
    size_t begin_displayName = temp.find("\"") + 1;
226
 
    size_t end_displayName = temp.rfind("\"");
227
 
    std::string displayName(temp.substr(begin_displayName, end_displayName - begin_displayName));
228
 
 
229
 
    static const size_t MAX_DISPLAY_NAME_SIZE = 25;
230
 
    if (displayName.size() > MAX_DISPLAY_NAME_SIZE)
231
 
        return "";
232
 
 
233
 
    return displayName;
234
 
}
235
 
 
236
 
void stripSipUriPrefix(std::string& sipUri)
237
 
{
238
 
    // Remove sip: prefix
239
 
    static const char SIP_PREFIX[] = "sip:";
240
 
    size_t found = sipUri.find(SIP_PREFIX);
241
 
 
242
 
    if (found != std::string::npos)
243
 
        sipUri.erase(found, found + (sizeof SIP_PREFIX) - 1);
244
 
 
245
 
    found = sipUri.find("@");
246
 
 
247
 
    if (found != std::string::npos)
248
 
        sipUri.erase(found);
249
 
}
250
 
 
251
177
pj_bool_t transaction_request_cb(pjsip_rx_data *rdata)
252
178
{
 
179
    if (!rdata or !rdata->msg_info.msg) {
 
180
        ERROR("rx_data is NULL");
 
181
        return false;
 
182
    }
253
183
    pjsip_method *method = &rdata->msg_info.msg->line.req.method;
 
184
    if (!method) {
 
185
        ERROR("method is NULL");
 
186
        return false;
 
187
    }
254
188
 
255
189
    if (method->id == PJSIP_ACK_METHOD && pjsip_rdata_get_dlg(rdata))
256
190
        return true;
257
191
 
 
192
    if (!rdata->msg_info.to or !rdata->msg_info.from) {
 
193
        ERROR("NULL from/to fields");
 
194
        return false;
 
195
    }
258
196
    pjsip_sip_uri *sip_to_uri = (pjsip_sip_uri *) pjsip_uri_get_uri(rdata->msg_info.to->uri);
259
197
    pjsip_sip_uri *sip_from_uri = (pjsip_sip_uri *) pjsip_uri_get_uri(rdata->msg_info.from->uri);
 
198
    if (!sip_to_uri or !sip_from_uri) {
 
199
        ERROR("NULL uri");
 
200
        return false;
 
201
    }
260
202
    std::string userName(sip_to_uri->user.ptr, sip_to_uri->user.slen);
261
203
    std::string server(sip_from_uri->host.ptr, sip_from_uri->host.slen);
262
204
    std::string account_id(Manager::instance().getAccountIdFromNameAndServer(userName, server));
263
205
 
264
 
    std::string displayName(parseDisplayName(rdata->msg_info.msg_buf));
 
206
    std::string displayName(sip_utils::parseDisplayName(rdata->msg_info.msg_buf));
265
207
 
 
208
    pjsip_msg_body *body = rdata->msg_info.msg->body;
266
209
    if (method->id == PJSIP_OTHER_METHOD) {
267
210
        pj_str_t *str = &method->name;
268
211
        std::string request(str->ptr, str->slen);
269
212
 
270
 
        if (request.find("NOTIFY") != (size_t)-1) {
271
 
            int voicemail;
272
 
 
273
 
            if (sscanf((const char*)rdata->msg_info.msg->body->data, "Voice-Message: %d/", &voicemail) == 1 && voicemail != 0)
274
 
                Manager::instance().startVoiceMessageNotification(account_id, voicemail);
 
213
        if (request.find("NOTIFY") != std::string::npos) {
 
214
            if (body and body->data) {
 
215
                int voicemail = 0;
 
216
                int ret = sscanf((const char*) body->data, "Voice-Message: %d/", &voicemail);
 
217
                if (ret == 1 and voicemail != 0)
 
218
                    Manager::instance().startVoiceMessageNotification(account_id, voicemail);
 
219
            }
275
220
        }
276
221
 
277
222
        pjsip_endpt_respond_stateless(endpt_, rdata, PJSIP_SC_OK, NULL, NULL, NULL);
278
 
 
279
223
        return true;
280
224
    } else if (method->id == PJSIP_OPTIONS_METHOD) {
281
225
        handleIncomingOptions(rdata);
288
232
    SIPAccount *account = dynamic_cast<SIPAccount *>(Manager::instance().getAccount(account_id));
289
233
 
290
234
    pjmedia_sdp_session *r_sdp;
291
 
    pjsip_msg_body *body = rdata->msg_info.msg->body;
292
235
 
293
236
    if (!body || pjmedia_sdp_parse(rdata->tp_info.pool, (char*) body->data, body->len, &r_sdp) != PJ_SUCCESS)
294
237
        r_sdp = NULL;
308
251
        return true;
309
252
    }
310
253
 
311
 
    if (Manager::instance().hookPreference.getSipEnabled()) {
312
 
        std::string header_value(fetchHeaderValue(rdata->msg_info.msg, Manager::instance().hookPreference.getUrlSipField()));
313
 
        UrlHook::runAction(Manager::instance().hookPreference.getUrlCommand(), header_value);
314
 
    }
 
254
    Manager::instance().hookPreference.runHook(rdata->msg_info.msg);
315
255
 
316
256
    SIPCall* call = new SIPCall(Manager::instance().getNewCallID(), Call::INCOMING, cp_);
317
257
    Manager::instance().associateCallToAccount(call->getCallId(), account_id);
318
258
 
319
259
    // May use the published address as well
320
 
    std::string addrToUse = SIPVoIPLink::instance()->getInterfaceAddrFromName(account->getLocalInterface());
 
260
    std::string addrToUse = SipTransport::getInterfaceAddrFromName(account->getLocalInterface());
321
261
    std::string addrSdp = account->isStunEnabled()
322
262
                          ? account->getPublishedAddress()
323
263
                          : addrToUse;
324
264
 
325
 
    pjsip_tpselector *tp = SIPVoIPLink::instance()->initTransportSelector(account->transport_, call->getMemoryPool());
 
265
    pjsip_tpselector *tp = SIPVoIPLink::instance()->sipTransport.initTransportSelector(account->transport_, call->getMemoryPool());
326
266
 
327
267
    if (addrToUse == "0.0.0.0")
328
 
        addrToUse = getSIPLocalIP();
 
268
        addrToUse = SipTransport::getSIPLocalIP();
329
269
 
330
270
    if (addrSdp == "0.0.0.0")
331
271
        addrSdp = addrToUse;
332
272
 
333
273
    char tmp[PJSIP_MAX_URL_SIZE];
334
 
    int length = pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, sip_from_uri, tmp, PJSIP_MAX_URL_SIZE);
335
 
    std::string peerNumber(tmp, length);
336
 
    stripSipUriPrefix(peerNumber);
 
274
    size_t length = pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, sip_from_uri, tmp, PJSIP_MAX_URL_SIZE);
 
275
    std::string peerNumber(tmp, std::min(length, sizeof tmp));
 
276
    sip_utils::stripSipUriPrefix(peerNumber);
337
277
 
338
278
    call->setConnectionState(Call::PROGRESSING);
339
279
    call->setPeerNumber(peerNumber);
344
284
 
345
285
    call->getLocalSDP()->setLocalIP(addrSdp);
346
286
 
347
 
    call->getAudioRtp().initAudioRtpConfig();
348
 
    call->getAudioRtp().initAudioSymmetricRtpSession();
 
287
    call->getAudioRtp().initConfig();
 
288
    call->getAudioRtp().initSession();
349
289
 
350
 
    if (rdata->msg_info.msg->body) {
 
290
    if (body) {
351
291
        char sdpbuffer[1000];
352
 
        int len = rdata->msg_info.msg->body->print_body(rdata->msg_info.msg->body, sdpbuffer, sizeof sdpbuffer);
 
292
        int len = body->print_body(body, sdpbuffer, sizeof sdpbuffer);
353
293
 
354
294
        if (len == -1) // error
355
295
            len = 0;
356
296
 
357
 
        std::string sdpoffer(sdpbuffer, len);
 
297
        std::string sdpoffer(sdpbuffer, std::min(len, (int) sizeof sdpbuffer));
358
298
        size_t start = sdpoffer.find("a=crypto:");
359
299
 
360
300
        // Found crypto header in SDP
362
302
            CryptoOffer crypto_offer;
363
303
            crypto_offer.push_back(std::string(sdpoffer.substr(start, (sdpoffer.size() - start) - 1)));
364
304
 
365
 
            std::vector<sfl::CryptoSuiteDefinition>localCapabilities;
 
305
            const size_t size = ARRAYSIZE(sfl::CryptoSuites);
 
306
            std::vector<sfl::CryptoSuiteDefinition> localCapabilities(size);
366
307
 
367
 
            for (int i = 0; i < 3; i++)
368
 
                localCapabilities.push_back(sfl::CryptoSuites[i]);
 
308
            std::copy(sfl::CryptoSuites, sfl::CryptoSuites + size,
 
309
                      localCapabilities.begin());
369
310
 
370
311
            sfl::SdesNegotiator sdesnego(localCapabilities, crypto_offer);
371
312
 
378
319
 
379
320
    call->getLocalSDP()->receiveOffer(r_sdp, account->getActiveCodecs());
380
321
 
381
 
    sfl::Codec* audiocodec = Manager::instance().audioCodecFactory.instantiateCodec(PAYLOAD_CODEC_ULAW);
382
 
    call->getAudioRtp().start(static_cast<sfl::AudioCodec *>(audiocodec));
 
322
    sfl::AudioCodec* ac = dynamic_cast<sfl::AudioCodec*>(Manager::instance().audioCodecFactory.instantiateCodec(PAYLOAD_CODEC_ULAW));
 
323
    if (!ac) {
 
324
        ERROR("Could not instantiate codec");
 
325
        delete call;
 
326
        return false;
 
327
    }
 
328
    call->getAudioRtp().start(ac);
383
329
 
384
330
    pjsip_dialog* dialog;
385
331
 
393
339
 
394
340
    PJ_ASSERT_RETURN(pjsip_dlg_set_transport(dialog, tp) == PJ_SUCCESS, 1);
395
341
 
 
342
    if (!call->inv) {
 
343
        ERROR("Call invite is not initialized");
 
344
        delete call;
 
345
        return false;
 
346
    }
 
347
 
396
348
    call->inv->mod_data[mod_ua_.id] = call;
397
349
 
398
350
    // Check whether Replaces header is present in the request and process accordingly.
425
377
 
426
378
        call->setConnectionState(Call::RINGING);
427
379
 
428
 
        Manager::instance().incomingCall(call, account_id);
 
380
        Manager::instance().incomingCall(*call, account_id);
429
381
        Manager::instance().getAccountLink(account_id)->addCall(call);
430
382
    }
431
383
 
435
387
 
436
388
/*************************************************************************************************/
437
389
 
438
 
SIPVoIPLink::SIPVoIPLink() : transportMap_(), evThread_(new EventThread(this))
 
390
SIPVoIPLink::SIPVoIPLink() : sipTransport(endpt_, cp_, pool_), evThread_(this)
439
391
{
440
392
#define TRY(ret) do { \
441
393
    if (ret != PJ_SUCCESS) \
442
394
    throw VoipLinkException(#ret " failed"); \
443
 
} while(0)
 
395
} while (0)
444
396
 
445
397
    srand(time(NULL)); // to get random number for RANDOM_PORT
446
398
 
447
399
    TRY(pj_init());
448
400
    TRY(pjlib_util_init());
449
401
    // From 0 (min) to 6 (max)
450
 
    pj_log_set_level(Logger::getDebugMode() ? 6 : 0);
 
402
    // pj_log_set_level(Logger::getDebugMode() ? 6 : 0);
 
403
    pj_log_set_level(0);
451
404
    TRY(pjnath_init());
452
405
 
453
406
    pj_caching_pool_init(cp_, &pj_pool_factory_default_policy, 0);
458
411
 
459
412
    TRY(pjsip_endpt_create(&cp_->factory, pj_gethostname()->ptr, &endpt_));
460
413
 
461
 
    if (getSIPLocalIP().empty())
 
414
    sipTransport.setEndpoint(endpt_);
 
415
    sipTransport.setCachingPool(cp_);
 
416
    sipTransport.setPool(pool_);
 
417
 
 
418
    if (SipTransport::getSIPLocalIP().empty())
462
419
        throw VoipLinkException("UserAgent: Unable to determine network capabilities");
463
420
 
464
421
    TRY(pjsip_tsx_layer_init_module(endpt_));
498
455
    static const pj_str_t accepted = { (char*) "application/sdp", 15 };
499
456
    pjsip_endpt_add_capability(endpt_, &mod_ua_, PJSIP_H_ACCEPT, NULL, 1, &accepted);
500
457
 
501
 
    DEBUG("UserAgent: pjsip version %s for %s initialized", pj_get_version(), PJ_OS_NAME);
 
458
    DEBUG("pjsip version %s for %s initialized", pj_get_version(), PJ_OS_NAME);
502
459
 
503
460
    TRY(pjsip_replaces_init_module(endpt_));
504
461
#undef TRY
505
462
 
506
 
    evThread_->start();
 
463
    handlingEvents_ = true;
 
464
    evThread_.start();
507
465
}
508
466
 
509
467
SIPVoIPLink::~SIPVoIPLink()
510
468
{
511
 
    delete evThread_;
512
 
    pj_thread_join(thread);
513
 
    pj_thread_destroy(thread);
 
469
    const int MAX_TIMEOUT_ON_LEAVING = 5;
 
470
    for (int timeout = 0; pjsip_tsx_layer_get_tsx_count() and timeout < MAX_TIMEOUT_ON_LEAVING; timeout++)
 
471
        sleep(1);
 
472
 
 
473
    handlingEvents_ = false;
 
474
    if (thread_) {
 
475
        pj_thread_join(thread_);
 
476
        pj_thread_destroy(thread_);
 
477
        DEBUG("PJ thread destroy finished");
 
478
        thread_ = 0;
 
479
    }
514
480
 
515
481
    const pj_time_val tv = {0, 10};
516
482
    pjsip_endpt_handle_events(endpt_, &tv);
524
490
 
525
491
SIPVoIPLink* SIPVoIPLink::instance()
526
492
{
527
 
    static SIPVoIPLink* instance = NULL;
528
 
 
529
 
    if (!instance)
530
 
        instance = new SIPVoIPLink;
531
 
 
532
 
    return instance;
533
 
}
534
 
 
535
 
void SIPVoIPLink::init() {}
536
 
 
537
 
void SIPVoIPLink::terminate() {}
538
 
 
539
 
void
540
 
SIPVoIPLink::getEvent()
 
493
    assert(!destroyed_);
 
494
    if (!instance_)
 
495
        instance_ = new SIPVoIPLink;
 
496
    return instance_;
 
497
}
 
498
 
 
499
void SIPVoIPLink::destroy()
 
500
{
 
501
    delete instance_;
 
502
    destroyed_ = true;
 
503
    instance_ = 0;
 
504
}
 
505
 
 
506
// Called from EventThread::run (not main thread)
 
507
bool SIPVoIPLink::getEvent()
541
508
{
542
509
    static pj_thread_desc desc;
543
510
 
544
511
    // We have to register the external thread so it could access the pjsip frameworks
545
 
    if (!pj_thread_is_registered())
546
 
        pj_thread_register(NULL, desc, &thread);
 
512
    if (!pj_thread_is_registered()) {
 
513
        DEBUG("Registering thread");
 
514
        pj_thread_register(NULL, desc, &thread_);
 
515
    }
547
516
 
548
517
    static const pj_time_val timeout = {0, 10};
549
518
    pjsip_endpt_handle_events(endpt_, &timeout);
 
519
    return handlingEvents_;
550
520
}
551
521
 
552
522
void SIPVoIPLink::sendRegister(Account *a)
553
523
{
554
524
    SIPAccount *account = dynamic_cast<SIPAccount*>(a);
555
 
    createSipTransport(account);
 
525
 
 
526
    if (!account)
 
527
        throw VoipLinkException("SipVoipLink: Account is not SIPAccount");
 
528
    sipTransport.createSipTransport(*account);
556
529
 
557
530
    account->setRegister(true);
558
531
    account->setRegistrationState(Trying);
572
545
    std::string from(account->getFromUri());
573
546
    pj_str_t pjFrom = pj_str((char*) from.c_str());
574
547
 
575
 
    // Get the contact header for this account
576
 
    std::string contact(account->getContactHeader());
 
548
    // Get the received header
 
549
    std::string received(account->getReceivedParameter());
 
550
 
 
551
    // Get the contact header
 
552
    std::string contact = account->getContactHeader();
577
553
    pj_str_t pjContact = pj_str((char*) contact.c_str());
578
554
 
 
555
    if (!received.empty()) {
 
556
        // Set received parameter string to empty in order to avoid creating new transport for each register
 
557
        account->setReceivedParameter("");
 
558
        // Explicitely set the bound address port to 0 so that pjsip determine a random port by itself
 
559
        account->transport_= sipTransport.createUdpTransport(account->getLocalInterface(), 0, received, account->getRPort());
 
560
        account->setRPort(-1);
 
561
        if(account->transport_ == NULL) {
 
562
            ERROR("Could not create new udp transport with public address: %s:%d", received.c_str(), account->getLocalPort());
 
563
        }
 
564
    }
 
565
 
579
566
    if (pjsip_regc_init(regc, &pjSrv, &pjFrom, &pjFrom, 1, &pjContact, account->getRegistrationExpire()) != PJ_SUCCESS)
580
567
        throw VoipLinkException("Unable to initialize account registration structure");
581
568
 
582
 
    if (!account->getServiceRoute().empty())
583
 
        pjsip_regc_set_route_set(regc, createRouteSet(account->getServiceRoute(), pool_));
 
569
    if (not account->getServiceRoute().empty())
 
570
        pjsip_regc_set_route_set(regc, sip_utils::createRouteSet(account->getServiceRoute(), pool_));
584
571
 
585
572
    pjsip_regc_set_credentials(regc, account->getCredentialCount(), account->getCredInfo());
586
573
 
587
 
 
588
574
    pjsip_hdr hdr_list;
589
575
    pj_list_init(&hdr_list);
590
576
    std::string useragent(account->getUserAgentName());
595
581
    pj_list_push_back(&hdr_list, (pjsip_hdr*) h);
596
582
    pjsip_regc_add_headers(regc, &hdr_list);
597
583
 
598
 
 
599
584
    pjsip_tx_data *tdata;
600
585
 
601
586
    if (pjsip_regc_register(regc, PJ_TRUE, &tdata) != PJ_SUCCESS)
602
587
        throw VoipLinkException("Unable to initialize transaction data for account registration");
603
588
 
604
 
    if (pjsip_regc_set_transport(regc, initTransportSelector(account->transport_, pool_)) != PJ_SUCCESS)
 
589
    if (pjsip_regc_set_transport(regc, sipTransport.initTransportSelector(account->transport_, pool_)) != PJ_SUCCESS)
605
590
        throw VoipLinkException("Unable to set transport");
606
591
 
607
592
    // decrease transport's ref count, counter incrementation is managed when acquiring transport
620
605
 
621
606
    // start the periodic registration request based on Expire header
622
607
    // account determines itself if a keep alive is required
623
 
    account->startKeepAliveTimer();
 
608
    if(account->isKeepAliveEnabled())
 
609
        account->startKeepAliveTimer();
624
610
}
625
611
 
626
612
void SIPVoIPLink::sendUnregister(Account *a)
652
638
    account->setRegister(false);
653
639
}
654
640
 
655
 
void SIPVoIPLink::registerKeepAliveTimer(pj_timer_entry& timer, pj_time_val& delay)
 
641
void SIPVoIPLink::registerKeepAliveTimer(pj_timer_entry &timer, pj_time_val &delay)
656
642
{
657
 
    pj_status_t status;
658
 
 
659
 
    status = pjsip_endpt_schedule_timer(endpt_, &timer, &delay);
660
 
    if (status != PJ_SUCCESS)
661
 
        ERROR("Could not schedule new timer in pjsip endpoint");
 
643
    DEBUG("Register new keep alive timer %d with delay %d", timer.id, delay.sec);
 
644
 
 
645
    if (timer.id == -1)
 
646
        WARN("Timer already scheduled");
 
647
 
 
648
    switch (pjsip_endpt_schedule_timer(endpt_, &timer, &delay)) {
 
649
        case PJ_SUCCESS:
 
650
            break;
 
651
        default:
 
652
            ERROR("Could not schedule new timer in pjsip endpoint");
 
653
            /* fallthrough */
 
654
        case PJ_EINVAL:
 
655
            ERROR("Invalid timer or delay entry");
 
656
            break;
 
657
        case PJ_EINVALIDOP:
 
658
            ERROR("Invalid timer entry, maybe already scheduled");
 
659
            break;
 
660
    }
662
661
}
663
662
 
664
663
void SIPVoIPLink::cancelKeepAliveTimer(pj_timer_entry& timer)
666
665
    pjsip_endpt_cancel_timer(endpt_, &timer);
667
666
}
668
667
 
 
668
bool isValidIpAddress(const std::string &address)
 
669
{
 
670
    size_t pos = address.find(":");
 
671
    std::string address_without_port(address);
 
672
    if (pos != std::string::npos)
 
673
        address_without_port = address.substr(0, pos);
 
674
 
 
675
    DEBUG("Testing address %s", address_without_port.c_str());
 
676
    struct sockaddr_in sa;
 
677
    int result = inet_pton(AF_INET, address_without_port.data(), &(sa.sin_addr));
 
678
    return result != 0;
 
679
}
 
680
 
669
681
Call *SIPVoIPLink::newOutgoingCall(const std::string& id, const std::string& toUrl)
670
682
{
 
683
    DEBUG("New outgoing call to %s", toUrl.c_str());
 
684
    std::string toCpy = toUrl;
 
685
 
 
686
    sip_utils::stripSipUriPrefix(toCpy);
 
687
 
 
688
    bool IPToIP = isValidIpAddress(toCpy);
 
689
    Manager::instance().setIPToIPForCall(id, IPToIP);
 
690
 
 
691
    try {
 
692
        if (IPToIP) {
 
693
            Manager::instance().associateCallToAccount(id, SIPAccount::IP2IP_PROFILE);
 
694
            return SIPNewIpToIpCall(id, toUrl);
 
695
        }
 
696
        else {
 
697
            return newRegisteredAccountCall(id, toUrl);
 
698
        }
 
699
    }
 
700
    catch(...) {
 
701
        throw;
 
702
    }
 
703
}
 
704
 
 
705
Call *SIPVoIPLink::SIPNewIpToIpCall(const std::string& id, const std::string& to)
 
706
{
 
707
    DEBUG("New IP to IP call to %s", to.c_str());
 
708
 
 
709
    SIPAccount *account = Manager::instance().getIP2IPAccount();
 
710
 
 
711
    if (!account)
 
712
        throw VoipLinkException("Could not retrieve default account for IP2IP call");
 
713
 
 
714
    SIPCall *call = new SIPCall(id, Call::OUTGOING, cp_);
 
715
 
 
716
    call->setIPToIP(true);
 
717
    call->initRecFilename(to);
 
718
 
 
719
    std::string localAddress(SipTransport::getInterfaceAddrFromName(account->getLocalInterface()));
 
720
 
 
721
    if (localAddress == "0.0.0.0")
 
722
        localAddress = SipTransport::getSIPLocalIP();
 
723
 
 
724
    setCallMediaLocal(call, localAddress);
 
725
 
 
726
    std::string toUri = account->getToUri(to);
 
727
    call->setPeerNumber(toUri);
 
728
 
 
729
    sfl::AudioCodec* ac = dynamic_cast<sfl::AudioCodec*>(Manager::instance().audioCodecFactory.instantiateCodec(PAYLOAD_CODEC_ULAW));
 
730
 
 
731
    if (!ac) {
 
732
        delete call;
 
733
        throw VoipLinkException("Could not instantiate codec");
 
734
    }
 
735
    // Audio Rtp Session must be initialized before creating initial offer in SDP session
 
736
    // since SDES require crypto attribute.
 
737
    call->getAudioRtp().initConfig();
 
738
    call->getAudioRtp().initSession();
 
739
    call->getAudioRtp().initLocalCryptoInfo();
 
740
    call->getAudioRtp().start(ac);
 
741
 
 
742
    // Building the local SDP offer
 
743
    call->getLocalSDP()->setLocalIP(localAddress);
 
744
    call->getLocalSDP()->createOffer(account->getActiveCodecs());
 
745
 
 
746
    if (!SIPStartCall(call)) {
 
747
        delete call;
 
748
        throw VoipLinkException("Could not create new call");
 
749
    }
 
750
 
 
751
    return call;
 
752
}
 
753
 
 
754
Call *SIPVoIPLink::newRegisteredAccountCall(const std::string& id, const std::string& toUrl)
 
755
{
 
756
    DEBUG("UserAgent: New registered account call to %s", toUrl.c_str());
 
757
 
671
758
    SIPAccount *account = dynamic_cast<SIPAccount *>(Manager::instance().getAccount(Manager::instance().getAccountFromCall(id)));
672
759
 
673
760
    if (account == NULL) // TODO: We should investigate how we could get rid of this error and create a IP2IP call instead
675
762
 
676
763
    SIPCall* call = new SIPCall(id, Call::OUTGOING, cp_);
677
764
 
678
 
    // If toUri is not a well formated sip URI, use account information to process it
 
765
    // If toUri is not a well formatted sip URI, use account information to process it
679
766
    std::string toUri;
680
767
 
681
768
    if (toUrl.find("sip:") != std::string::npos or
685
772
        toUri = account->getToUri(toUrl);
686
773
 
687
774
    call->setPeerNumber(toUri);
688
 
    std::string localAddr(getInterfaceAddrFromName(account->getLocalInterface()));
 
775
    std::string localAddr(SipTransport::getInterfaceAddrFromName(account->getLocalInterface()));
689
776
 
690
777
    if (localAddr == "0.0.0.0")
691
 
        localAddr = getSIPLocalIP();
 
778
        localAddr = SipTransport::getSIPLocalIP();
692
779
 
693
780
    setCallMediaLocal(call, localAddr);
694
781
 
695
782
    // May use the published address as well
696
783
    std::string addrSdp = account->isStunEnabled() ?
697
784
    account->getPublishedAddress() :
698
 
    getInterfaceAddrFromName(account->getLocalInterface());
 
785
    SipTransport::getInterfaceAddrFromName(account->getLocalInterface());
699
786
 
700
787
    if (addrSdp == "0.0.0.0")
701
 
        addrSdp = getSIPLocalIP();
 
788
        addrSdp = SipTransport::getSIPLocalIP();
702
789
 
703
790
    // Initialize the session using ULAW as default codec in case of early media
704
791
    // The session should be ready to receive media once the first INVITE is sent, before
705
792
    // the session initialization is completed
706
 
    sfl::Codec* audiocodec = Manager::instance().audioCodecFactory.instantiateCodec(PAYLOAD_CODEC_ULAW);
 
793
    sfl::AudioCodec* ac = dynamic_cast<sfl::AudioCodec*>(Manager::instance().audioCodecFactory.instantiateCodec(PAYLOAD_CODEC_ULAW));
707
794
 
708
 
    if (audiocodec == NULL) {
 
795
    if (ac == NULL) {
709
796
        delete call;
710
797
        throw VoipLinkException("Could not instantiate codec for early media");
711
798
    }
712
799
 
713
800
    try {
714
 
        call->getAudioRtp().initAudioRtpConfig();
715
 
        call->getAudioRtp().initAudioSymmetricRtpSession();
 
801
        call->getAudioRtp().initConfig();
 
802
        call->getAudioRtp().initSession();
716
803
        call->getAudioRtp().initLocalCryptoInfo();
717
 
        call->getAudioRtp().start(static_cast<sfl::AudioCodec *>(audiocodec));
 
804
        call->getAudioRtp().start(ac);
718
805
    } catch (...) {
719
806
        delete call;
720
807
        throw VoipLinkException("Could not start rtp session for early media");
734
821
}
735
822
 
736
823
void
737
 
SIPVoIPLink::answer(Call *c)
 
824
SIPVoIPLink::answer(Call *call)
738
825
{
739
 
    SIPCall *call = dynamic_cast<SIPCall*>(c);
740
 
 
741
826
    if (!call)
742
827
        return;
743
 
 
744
 
    pjsip_tx_data *tdata;
745
 
 
746
 
    if (pjsip_inv_answer(call->inv, PJSIP_SC_OK, NULL, NULL, &tdata) != PJ_SUCCESS)
747
 
        throw VoipLinkException("Could not init invite request answer (200 OK)");
748
 
 
749
 
    if (pjsip_inv_send_msg(call->inv, tdata) != PJ_SUCCESS)
750
 
        throw VoipLinkException("Could not send invite request answer (200 OK)");
751
 
 
752
 
    call->setConnectionState(Call::CONNECTED);
753
 
    call->setState(Call::ACTIVE);
 
828
    call->answer();
754
829
}
755
830
 
756
831
void
771
846
 
772
847
    // Looks for sip routes
773
848
    if (not account->getServiceRoute().empty()) {
774
 
        pjsip_route_hdr *route_set = createRouteSet(account->getServiceRoute(), inv->pool);
 
849
        pjsip_route_hdr *route_set = sip_utils::createRouteSet(account->getServiceRoute(), inv->pool);
775
850
        pjsip_dlg_set_route_set(inv->dlg, route_set);
776
851
    }
777
852
 
821
896
{
822
897
    SIPCall *call = getSIPCall(id);
823
898
    call->setState(Call::HOLD);
 
899
    call->getAudioRtp().saveLocalContext();
824
900
    call->getAudioRtp().stop();
825
901
 
826
902
    Sdp *sdpSession = call->getLocalSDP();
853
929
            pl = sessionMedia->getPayloadType();
854
930
 
855
931
        // Create a new instance for this codec
856
 
        sfl::Codec* audiocodec = Manager::instance().audioCodecFactory.instantiateCodec(pl);
 
932
        sfl::AudioCodec* ac = dynamic_cast<sfl::AudioCodec*>(Manager::instance().audioCodecFactory.instantiateCodec(pl));
857
933
 
858
 
        if (audiocodec == NULL)
 
934
        if (ac == NULL)
859
935
            throw VoipLinkException("Could not instantiate codec");
860
936
 
861
 
        call->getAudioRtp().initAudioRtpConfig();
862
 
        call->getAudioRtp().initAudioSymmetricRtpSession();
863
 
        call->getAudioRtp().start(static_cast<sfl::AudioCodec *>(audiocodec));
 
937
        call->getAudioRtp().initConfig();
 
938
        call->getAudioRtp().initSession();
 
939
        call->getAudioRtp().restoreLocalContext();
 
940
        call->getAudioRtp().initLocalCryptoInfoOnOffHold();
 
941
        call->getAudioRtp().start(ac);
864
942
    } catch (const SdpException &e) {
865
 
        ERROR("UserAgent: Exception: %s", e.what());
 
943
        ERROR("%s", e.what());
866
944
    } catch (...) {
867
945
        throw VoipLinkException("Could not create audio rtp session");
868
946
    }
875
953
        call->setState(Call::ACTIVE);
876
954
}
877
955
 
878
 
void
879
 
SIPVoIPLink::sendTextMessage(sfl::InstantMessaging *module, const std::string& callID, const std::string& message, const std::string& from)
 
956
void SIPVoIPLink::sendTextMessage(const std::string &callID,
 
957
                                  const std::string &message,
 
958
                                  const std::string &from)
880
959
{
 
960
    using namespace sfl::InstantMessaging;
881
961
    SIPCall *call;
882
962
 
883
963
    try {
887
967
    }
888
968
 
889
969
    /* Send IM message */
890
 
    sfl::InstantMessaging::UriList list;
891
 
    sfl::InstantMessaging::UriEntry entry;
 
970
    UriList list;
 
971
    UriEntry entry;
892
972
    entry[sfl::IM_XML_URI] = std::string("\"" + from + "\"");  // add double quotes for xml formating
893
 
 
894
973
    list.push_front(entry);
895
 
 
896
 
    module->send_sip_message(call->inv, callID, module->appendUriList(message, list));
 
974
    send_sip_message(call->inv, callID, appendUriList(message, list));
897
975
}
898
976
 
899
977
bool
900
978
SIPVoIPLink::transferCommon(SIPCall *call, pj_str_t *dst)
901
979
{
 
980
    if (!call or !call->inv)
 
981
        return false;
 
982
 
902
983
    pjsip_evsub_user xfer_cb;
903
984
    pj_bzero(&xfer_cb, sizeof(xfer_cb));
904
985
    xfer_cb.on_evsub_state = &transfer_client_cb;
938
1019
SIPVoIPLink::transfer(const std::string& id, const std::string& to)
939
1020
{
940
1021
    SIPCall *call = getSIPCall(id);
 
1022
    if (call == NULL) {
 
1023
        ERROR("Could not find call %s", id.c_str());
 
1024
        return;
 
1025
    }
941
1026
    call->stopRecording();
942
1027
 
943
1028
    std::string account_id(Manager::instance().getAccountFromCall(id));
960
1045
 
961
1046
bool SIPVoIPLink::attendedTransfer(const std::string& id, const std::string& to)
962
1047
{
963
 
    pjsip_dialog *target_dlg = getSIPCall(to)->inv->dlg;
 
1048
    SIPCall *call = getSIPCall(to);
 
1049
    if (!call or !call->inv or !call->inv->dlg)
 
1050
        throw VoipLinkException("Couldn't get invite dialog");
 
1051
    pjsip_dialog *target_dlg = call->inv->dlg;
964
1052
    pjsip_uri *uri = (pjsip_uri*) pjsip_uri_get_uri(target_dlg->remote.info->uri);
965
1053
 
966
 
    char str_dest_buf[PJSIP_MAX_URL_SIZE*2] = { '<' };
 
1054
    char str_dest_buf[PJSIP_MAX_URL_SIZE * 2] = { '<' };
967
1055
    pj_str_t dst = { str_dest_buf, 1 };
968
1056
 
969
1057
    dst.slen += pjsip_uri_print(PJSIP_URI_IN_REQ_URI, uri, str_dest_buf+1, sizeof(str_dest_buf)-1);
988
1076
{
989
1077
    SIPCall *call = getSIPCall(id);
990
1078
 
991
 
    if (!call->isIncoming() or call->getConnectionState() == Call::CONNECTED)
 
1079
    if (!call or !call->isIncoming() or call->getConnectionState() == Call::CONNECTED or !call->inv)
992
1080
        return;
993
1081
 
994
1082
    call->getAudioRtp().stop();
995
1083
 
996
1084
    pjsip_tx_data *tdata;
997
 
 
998
1085
    if (pjsip_inv_end_session(call->inv, PJSIP_SC_DECLINE, NULL, &tdata) != PJ_SUCCESS)
999
1086
        return;
1000
1087
 
1017
1104
SIPVoIPLink::carryingDTMFdigits(const std::string& id, char code)
1018
1105
{
1019
1106
    std::string accountID(Manager::instance().getAccountFromCall(id));
1020
 
    SIPAccount *account = static_cast<SIPAccount*>(Manager::instance().getAccount(accountID));
 
1107
    SIPAccount *account = dynamic_cast<SIPAccount*>(Manager::instance().getAccount(accountID));
1021
1108
 
1022
1109
    if (account) {
1023
1110
        try {
1073
1160
    std::string id(Manager::instance().getAccountFromCall(call->getCallId()));
1074
1161
    SIPAccount *account = dynamic_cast<SIPAccount *>(Manager::instance().getAccount(id));
1075
1162
 
1076
 
    if (account == NULL)
 
1163
    if (account == NULL) {
 
1164
        ERROR("Account is NULL in SIPStartCall");
1077
1165
        return false;
 
1166
    }
1078
1167
 
1079
1168
    std::string toUri(call->getPeerNumber()); // expecting a fully well formed sip uri
1080
1169
 
1081
 
    // std::string address, port;
1082
 
    // findLocalAddressFromUri(toUri, account->transport_, address, port);
1083
 
 
1084
1170
    pj_str_t pjTo = pj_str((char*) toUri.c_str());
1085
1171
 
1086
1172
    // Create the from header
1093
1179
 
1094
1180
    pjsip_dialog *dialog = NULL;
1095
1181
 
1096
 
    if (pjsip_dlg_create_uac(pjsip_ua_instance(), &pjFrom, &pjContact, &pjTo, NULL, &dialog) != PJ_SUCCESS)
 
1182
    if (pjsip_dlg_create_uac(pjsip_ua_instance(), &pjFrom, &pjContact, &pjTo, NULL, &dialog) != PJ_SUCCESS) {
 
1183
        ERROR("Unable to sip create dialogs for user agent client");
1097
1184
        return false;
 
1185
    }
1098
1186
 
1099
 
    if (pjsip_inv_create_uac(dialog, call->getLocalSDP()->getLocalSdpSession(), 0, &call->inv) != PJ_SUCCESS)
 
1187
    if (pjsip_inv_create_uac(dialog, call->getLocalSDP()->getLocalSdpSession(), 0, &call->inv) != PJ_SUCCESS) {
 
1188
        ERROR("Unable to create invite session for user agent client");
1100
1189
        return false;
 
1190
    }
1101
1191
 
1102
1192
    if (not account->getServiceRoute().empty())
1103
 
        pjsip_dlg_set_route_set(dialog, createRouteSet(account->getServiceRoute(), call->inv->pool));
 
1193
        pjsip_dlg_set_route_set(dialog, sip_utils::createRouteSet(account->getServiceRoute(), call->inv->pool));
1104
1194
 
1105
 
    pjsip_auth_clt_set_credentials(&dialog->auth_sess, account->getCredentialCount(), account->getCredInfo());
 
1195
    if (pjsip_auth_clt_set_credentials(&dialog->auth_sess, account->getCredentialCount(), account->getCredInfo()) != PJ_SUCCESS) {
 
1196
        ERROR("Could not initiaize credential for invite session  authentication");
 
1197
        return false;
 
1198
    }
1106
1199
 
1107
1200
    call->inv->mod_data[mod_ua_.id] = call;
1108
1201
 
1109
1202
    pjsip_tx_data *tdata;
1110
1203
 
1111
 
    if (pjsip_inv_invite(call->inv, &tdata) != PJ_SUCCESS)
1112
 
        return false;
1113
 
 
1114
 
    pjsip_tpselector *tp = initTransportSelector(account->transport_, call->inv->pool);
1115
 
 
1116
 
    if (pjsip_dlg_set_transport(dialog, tp) != PJ_SUCCESS)
1117
 
        return false;
1118
 
 
1119
 
    if (pjsip_inv_send_msg(call->inv, tdata) != PJ_SUCCESS)
1120
 
        return false;
 
1204
    if (pjsip_inv_invite(call->inv, &tdata) != PJ_SUCCESS) {
 
1205
        ERROR("Could not initialize invite messager for this call");
 
1206
        return false;
 
1207
    }
 
1208
 
 
1209
    pjsip_tpselector *tp = sipTransport.initTransportSelector(account->transport_, call->inv->pool);
 
1210
 
 
1211
    if (pjsip_dlg_set_transport(dialog, tp) != PJ_SUCCESS) {
 
1212
        ERROR("Unable to associate transport fir invite session dialog");
 
1213
        return false;
 
1214
    }
 
1215
 
 
1216
    if (pjsip_inv_send_msg(call->inv, tdata) != PJ_SUCCESS) {
 
1217
        ERROR("Unable to send invite message for this call");
 
1218
        return false;
 
1219
    }
1121
1220
 
1122
1221
    call->setConnectionState(Call::PROGRESSING);
1123
1222
    call->setState(Call::ACTIVE);
1147
1246
}
1148
1247
 
1149
1248
void
1150
 
SIPVoIPLink::SIPCallAnswered(SIPCall *call, pjsip_rx_data *rdata UNUSED)
 
1249
SIPVoIPLink::SIPCallAnswered(SIPCall *call, pjsip_rx_data * /*rdata*/)
1151
1250
{
1152
1251
    if (call->getConnectionState() != Call::CONNECTED) {
1153
1252
        call->setConnectionState(Call::CONNECTED);
1168
1267
    return result;
1169
1268
}
1170
1269
 
1171
 
bool SIPVoIPLink::SIPNewIpToIpCall(const std::string& id, const std::string& to)
1172
 
{
1173
 
    SIPAccount *account = dynamic_cast<SIPAccount *>(Manager::instance().getAccount(IP2IP_PROFILE));
1174
 
 
1175
 
    if (!account)
1176
 
        return false;
1177
 
 
1178
 
    SIPCall *call = new SIPCall(id, Call::OUTGOING, cp_);
1179
 
    call->setIPToIP(true);
1180
 
    call->initRecFilename(to);
1181
 
 
1182
 
    std::string localAddress(getInterfaceAddrFromName(account->getLocalInterface()));
1183
 
 
1184
 
    if (localAddress == "0.0.0.0")
1185
 
        localAddress = getSIPLocalIP();
1186
 
 
1187
 
    setCallMediaLocal(call, localAddress);
1188
 
 
1189
 
    std::string toUri = account->getToUri(to);
1190
 
    call->setPeerNumber(toUri);
1191
 
 
1192
 
    sfl::Codec* audiocodec = Manager::instance().audioCodecFactory.instantiateCodec(PAYLOAD_CODEC_ULAW);
1193
 
 
1194
 
    // Audio Rtp Session must be initialized before creating initial offer in SDP session
1195
 
    // since SDES require crypto attribute.
1196
 
    call->getAudioRtp().initAudioRtpConfig();
1197
 
    call->getAudioRtp().initAudioSymmetricRtpSession();
1198
 
    call->getAudioRtp().initLocalCryptoInfo();
1199
 
    call->getAudioRtp().start(static_cast<sfl::AudioCodec *>(audiocodec));
1200
 
 
1201
 
    // Building the local SDP offer
1202
 
    call->getLocalSDP()->setLocalIP(localAddress);
1203
 
    call->getLocalSDP()->createOffer(account->getActiveCodecs());
1204
 
 
1205
 
    // Init TLS transport if enabled
1206
 
    if (account->isTlsEnabled()) {
1207
 
        size_t at = toUri.find("@");
1208
 
        size_t trns = toUri.find(";transport");
1209
 
        if (at == std::string::npos or trns == std::string::npos) {
1210
 
            ERROR("UserAgent: Error \"@\" or \";transport\" not in URI %s", toUri.c_str());
1211
 
            delete call;
1212
 
            return false;
1213
 
        }
1214
 
 
1215
 
        std::string remoteAddr(toUri.substr(at + 1, trns - at - 1));
1216
 
 
1217
 
        if (toUri.find("sips:") != 1) {
1218
 
            DEBUG("UserAgent: Error \"sips\" scheme required for TLS call");
1219
 
            delete call;
1220
 
            return false;
1221
 
        }
1222
 
 
1223
 
        shutdownSipTransport(account);
1224
 
        createTlsTransport(account, remoteAddr);
1225
 
 
1226
 
        if (!account->transport_) {
1227
 
            delete call;
1228
 
            return false;
1229
 
        }
1230
 
    }
1231
 
 
1232
 
    if (!SIPStartCall(call)) {
1233
 
        delete call;
1234
 
        return false;
1235
 
    }
1236
 
 
1237
 
    return true;
1238
 
}
1239
 
 
1240
 
 
1241
1270
///////////////////////////////////////////////////////////////////////////////
1242
1271
// Private functions
1243
1272
///////////////////////////////////////////////////////////////////////////////
1244
1273
 
1245
 
pj_bool_t stun_sock_on_status_cb(pj_stun_sock *stun_sock UNUSED, pj_stun_sock_op op UNUSED, pj_status_t status)
1246
 
{
1247
 
    return status == PJ_SUCCESS;
1248
 
}
1249
 
 
1250
 
pj_bool_t stun_sock_on_rx_data_cb(pj_stun_sock *stun_sock UNUSED, void *pkt UNUSED, unsigned pkt_len UNUSED, const pj_sockaddr_t *src_addr UNUSED, unsigned addr_len UNUSED)
1251
 
{
1252
 
    return PJ_TRUE;
1253
 
}
1254
 
 
1255
 
 
1256
 
pj_status_t SIPVoIPLink::stunServerResolve(SIPAccount *account)
1257
 
{
1258
 
    pj_stun_config stunCfg;
1259
 
    pj_stun_config_init(&stunCfg, &cp_->factory, 0, pjsip_endpt_get_ioqueue(endpt_), pjsip_endpt_get_timer_heap(endpt_));
1260
 
 
1261
 
    static const pj_stun_sock_cb stun_sock_cb = {
1262
 
        stun_sock_on_rx_data_cb,
1263
 
        NULL,
1264
 
        stun_sock_on_status_cb
1265
 
    };
1266
 
 
1267
 
    pj_stun_sock *stun_sock;
1268
 
    pj_status_t status = pj_stun_sock_create(&stunCfg, "stunresolve", pj_AF_INET(), &stun_sock_cb, NULL, NULL, &stun_sock);
1269
 
 
1270
 
    pj_str_t stunServer = account->getStunServerName();
1271
 
 
1272
 
    if (status != PJ_SUCCESS) {
1273
 
        char errmsg[PJ_ERR_MSG_SIZE];
1274
 
        pj_strerror(status, errmsg, sizeof(errmsg));
1275
 
        DEBUG("Error creating STUN socket for %.*s: %s", (int) stunServer.slen, stunServer.ptr, errmsg);
1276
 
        return status;
1277
 
    }
1278
 
 
1279
 
    status = pj_stun_sock_start(stun_sock, &stunServer, account->getStunPort(), NULL);
1280
 
 
1281
 
    if (status != PJ_SUCCESS) {
1282
 
        char errmsg[PJ_ERR_MSG_SIZE];
1283
 
        pj_strerror(status, errmsg, sizeof(errmsg));
1284
 
        DEBUG("Error starting STUN socket for %.*s: %s", (int) stunServer.slen, stunServer.ptr, errmsg);
1285
 
        pj_stun_sock_destroy(stun_sock);
1286
 
    }
1287
 
 
1288
 
    return status;
1289
 
}
1290
 
 
1291
 
 
1292
 
void SIPVoIPLink::createDefaultSipUdpTransport()
1293
 
{
1294
 
    SIPAccount *account = dynamic_cast<SIPAccount *>(Manager::instance().getAccount(IP2IP_PROFILE));
1295
 
    createUdpTransport(account);
1296
 
    assert(account->transport_);
1297
 
 
1298
 
    localUDPTransport_ = account->transport_;
1299
 
}
1300
 
 
1301
 
void SIPVoIPLink::createTlsListener(SIPAccount *account, pjsip_tpfactory **listener)
1302
 
{
1303
 
    pj_sockaddr_in local_addr;
1304
 
    pj_sockaddr_in_init(&local_addr, 0, 0);
1305
 
    local_addr.sin_port = pj_htons(account->getTlsListenerPort());
1306
 
 
1307
 
    pj_str_t pjAddress;
1308
 
    pj_cstr(&pjAddress, PJ_INADDR_ANY);
1309
 
    pj_sockaddr_in_set_str_addr(&local_addr, &pjAddress);
1310
 
    std::string localIP(getSIPLocalIP());
1311
 
 
1312
 
    pjsip_host_port a_name = {
1313
 
        pj_str((char*) localIP.c_str()),
1314
 
        local_addr.sin_port
1315
 
    };
1316
 
 
1317
 
    pjsip_tls_transport_start(endpt_, account->getTlsSetting(), &local_addr, &a_name, 1, listener);
1318
 
}
1319
 
 
1320
 
 
1321
 
void SIPVoIPLink::createTlsTransport(SIPAccount *account, std::string remoteAddr)
1322
 
{
1323
 
    pj_str_t remote;
1324
 
    pj_cstr(&remote, remoteAddr.c_str());
1325
 
 
1326
 
    pj_sockaddr_in rem_addr;
1327
 
    pj_sockaddr_in_init(&rem_addr, &remote, (pj_uint16_t) DEFAULT_SIP_TLS_PORT);
1328
 
 
1329
 
    static pjsip_tpfactory *localTlsListener = NULL; /** The local tls listener */
1330
 
 
1331
 
    if (localTlsListener == NULL)
1332
 
        createTlsListener(account, &localTlsListener);
1333
 
 
1334
 
    pjsip_endpt_acquire_transport(endpt_, PJSIP_TRANSPORT_TLS, &rem_addr,
1335
 
                                  sizeof rem_addr, NULL, &account->transport_);
1336
 
}
1337
 
 
1338
 
 
1339
 
void SIPVoIPLink::createSipTransport(SIPAccount *account)
1340
 
{
1341
 
    shutdownSipTransport(account);
1342
 
 
1343
 
    if (account->isTlsEnabled()) {
1344
 
        std::string remoteSipUri(account->getServerUri());
1345
 
        static const char SIPS_PREFIX[] = "<sips:";
1346
 
        size_t sips = remoteSipUri.find(SIPS_PREFIX) + (sizeof SIPS_PREFIX) - 1;
1347
 
        size_t trns = remoteSipUri.find(";transport");
1348
 
        std::string remoteAddr(remoteSipUri.substr(sips, trns-sips));
1349
 
 
1350
 
        createTlsTransport(account, remoteAddr);
1351
 
    } else if (account->isStunEnabled())
1352
 
        createStunTransport(account);
1353
 
    else
1354
 
        createUdpTransport(account);
1355
 
 
1356
 
    if (!account->transport_) {
1357
 
        // Could not create new transport, this transport may already exists
1358
 
        account->transport_ = transportMap_[account->getLocalPort()];
1359
 
 
1360
 
        if (account->transport_)
1361
 
            pjsip_transport_add_ref(account->transport_);
1362
 
        else {
1363
 
            account->transport_ = localUDPTransport_;
1364
 
            account->setLocalPort(localUDPTransport_->local_name.port);
1365
 
        }
1366
 
    }
1367
 
}
1368
 
 
1369
 
void SIPVoIPLink::createUdpTransport(SIPAccount *account)
1370
 
{
1371
 
    std::string listeningAddress;
1372
 
    pj_uint16_t listeningPort = account->getLocalPort();
1373
 
 
1374
 
    pj_sockaddr_in bound_addr;
1375
 
    pj_bzero(&bound_addr, sizeof(bound_addr));
1376
 
    bound_addr.sin_port = pj_htons(listeningPort);
1377
 
    bound_addr.sin_family = PJ_AF_INET;
1378
 
 
1379
 
    if (account->getLocalInterface() == "default") {
1380
 
        listeningAddress = getSIPLocalIP();
1381
 
        bound_addr.sin_addr.s_addr = pj_htonl(PJ_INADDR_ANY);
1382
 
    } else {
1383
 
        listeningAddress = getInterfaceAddrFromName(account->getLocalInterface());
1384
 
        bound_addr.sin_addr = pj_inet_addr2(listeningAddress.c_str());
1385
 
    }
1386
 
 
1387
 
    if (!account->getPublishedSameasLocal()) {
1388
 
        listeningAddress = account->getPublishedAddress();
1389
 
        listeningPort = account->getPublishedPort();
1390
 
    }
1391
 
 
1392
 
    // We must specify this here to avoid the IP2IP_PROFILE creating a
1393
 
    // transport with the name 0.0.0.0 appearing in the via header
1394
 
    if (account->getAccountID() == IP2IP_PROFILE)
1395
 
        listeningAddress = getSIPLocalIP();
1396
 
 
1397
 
    if (listeningAddress.empty() or listeningPort == 0)
1398
 
        return;
1399
 
 
1400
 
    const pjsip_host_port a_name = {
1401
 
        pj_str((char*) listeningAddress.c_str()),
1402
 
        listeningPort
1403
 
    };
1404
 
 
1405
 
    pjsip_udp_transport_start(endpt_, &bound_addr, &a_name, 1, &account->transport_);
1406
 
    pjsip_tpmgr_dump_transports(pjsip_endpt_get_tpmgr(endpt_)); // dump debug information to stdout
1407
 
 
1408
 
    if (account->transport_)
1409
 
        transportMap_[account->getLocalPort()] = account->transport_;
1410
 
}
1411
 
 
1412
 
pjsip_tpselector *SIPVoIPLink::initTransportSelector(pjsip_transport *transport, pj_pool_t *tp_pool) const
1413
 
{
1414
 
    assert(transport);
1415
 
    pjsip_tpselector *tp = (pjsip_tpselector *) pj_pool_zalloc(tp_pool, sizeof(pjsip_tpselector));
1416
 
    tp->type = PJSIP_TPSELECTOR_TRANSPORT;
1417
 
    tp->u.transport = transport;
1418
 
    return tp;
1419
 
}
1420
 
 
1421
 
 
1422
 
 
1423
 
void SIPVoIPLink::createStunTransport(SIPAccount *account)
1424
 
{
1425
 
    pj_str_t stunServer = account->getStunServerName();
1426
 
    pj_uint16_t stunPort = account->getStunPort();
1427
 
 
1428
 
    if (stunServerResolve(account) != PJ_SUCCESS) {
1429
 
        ERROR("Can't resolve STUN server");
1430
 
        return;
1431
 
    }
1432
 
 
1433
 
    pj_sock_t sock = PJ_INVALID_SOCKET;
1434
 
 
1435
 
    pj_sockaddr_in boundAddr;
1436
 
 
1437
 
    if (pj_sockaddr_in_init(&boundAddr, &stunServer, 0) != PJ_SUCCESS) {
1438
 
        ERROR("Can't initialize IPv4 socket on %*s:%i", stunServer.slen, stunServer.ptr, stunPort);
1439
 
        return;
1440
 
    }
1441
 
 
1442
 
    if (pj_sock_socket(pj_AF_INET(), pj_SOCK_DGRAM(), 0, &sock) != PJ_SUCCESS) {
1443
 
        ERROR("Can't create or bind socket");
1444
 
        return;
1445
 
    }
1446
 
 
1447
 
    // Query the mapped IP address and port on the 'outside' of the NAT
1448
 
    pj_sockaddr_in pub_addr;
1449
 
 
1450
 
    if (pjstun_get_mapped_addr(&cp_->factory, 1, &sock, &stunServer, stunPort, &stunServer, stunPort, &pub_addr) != PJ_SUCCESS) {
1451
 
        ERROR("Can't contact STUN server");
1452
 
        pj_sock_close(sock);
1453
 
        return;
1454
 
    }
1455
 
 
1456
 
    pjsip_host_port a_name = {
1457
 
        pj_str(pj_inet_ntoa(pub_addr.sin_addr)),
1458
 
        pj_ntohs(pub_addr.sin_port)
1459
 
    };
1460
 
 
1461
 
    std::string listeningAddress = std::string(a_name.host.ptr, a_name.host.slen);
1462
 
 
1463
 
    account->setPublishedAddress(listeningAddress);
1464
 
    account->setPublishedPort(a_name.port);
1465
 
 
1466
 
    pjsip_udp_transport_attach2(endpt_, PJSIP_TRANSPORT_UDP, sock, &a_name, 1,
1467
 
                                &account->transport_);
1468
 
 
1469
 
    pjsip_tpmgr_dump_transports(pjsip_endpt_get_tpmgr(endpt_));
1470
 
}
1471
 
 
1472
 
 
1473
 
void SIPVoIPLink::shutdownSipTransport(SIPAccount *account)
1474
 
{
1475
 
    if (account->transport_) {
1476
 
        pjsip_transport_dec_ref(account->transport_);
1477
 
        account->transport_ = NULL;
1478
 
    }
1479
 
}
1480
 
 
1481
 
void SIPVoIPLink::findLocalAddressFromTransport(pjsip_transport *transport, pjsip_transport_type_e transportType, std::string &addr, std::string &port) const
1482
 
{
1483
 
    // Initialize the sip port with the default SIP port
1484
 
    std::stringstream ss;
1485
 
    ss << DEFAULT_SIP_PORT;
1486
 
    port = ss.str();
1487
 
 
1488
 
    // Initialize the sip address with the hostname
1489
 
    const pj_str_t *pjMachineName = pj_gethostname();
1490
 
    addr = std::string(pjMachineName->ptr, pjMachineName->slen);
1491
 
 
1492
 
    // Update address and port with active transport
1493
 
    if (!transport) {
1494
 
        ERROR("SIPVoIPLink: Transport is NULL in findLocalAddress, using local address %s:%s", addr.c_str(), port.c_str());
1495
 
        return;
1496
 
    }
1497
 
 
1498
 
    // get the transport manager associated with the SIP enpoint
1499
 
    pjsip_tpmgr *tpmgr = pjsip_endpt_get_tpmgr(endpt_);
1500
 
    if (!tpmgr) {
1501
 
        ERROR("SIPVoIPLink: Transport manager is NULL in findLocalAddress, using local address %s:%s", addr.c_str(), port.c_str());
1502
 
        return;
1503
 
    }
1504
 
 
1505
 
    // initialize a transport selector
1506
 
    // TODO Need to determine why we exclude TLS here...
1507
 
    // if (transportType == PJSIP_TRANSPORT_UDP and transport_)
1508
 
    pjsip_tpselector *tp_sel = initTransportSelector(transport, pool_);
1509
 
    if (!tp_sel) {
1510
 
        ERROR("SIPVoIPLink: Could not initialize transport selector, using local address %s:%s", addr.c_str(), port.c_str());
1511
 
        return;
1512
 
    }
1513
 
 
1514
 
    pj_str_t localAddress = {0,0};
1515
 
    int i_port = 0;
1516
 
 
1517
 
    // Find the local address and port for this transport
1518
 
    if (pjsip_tpmgr_find_local_addr(tpmgr, pool_, transportType, tp_sel, &localAddress, &i_port) != PJ_SUCCESS) {
1519
 
        WARN("SIPVoIPLink: Could not retreive local address and port from transport, using %s:%s", addr.c_str(), port.c_str());
1520
 
        return;
1521
 
    }
1522
 
 
1523
 
    // Update local address based on the transport type
1524
 
    addr = std::string(localAddress.ptr, localAddress.slen);
1525
 
 
1526
 
    // Fallback on local ip provided by pj_gethostip()
1527
 
    if (addr == "0.0.0.0")
1528
 
        addr = getSIPLocalIP();
1529
 
 
1530
 
    // Determine the local port based on transport information
1531
 
    ss.str("");
1532
 
    ss << i_port;
1533
 
    port = ss.str();
1534
 
}
1535
 
 
1536
1274
namespace {
1537
1275
int SIPSessionReinvite(SIPCall *call)
1538
1276
{
1539
 
    pjsip_tx_data *tdata;
1540
 
 
1541
1277
    pjmedia_sdp_session *local_sdp = call->getLocalSDP()->getLocalSdpSession();
1542
 
 
 
1278
    pjsip_tx_data *tdata;
1543
1279
    if (local_sdp && pjsip_inv_reinvite(call->inv, NULL, local_sdp, &tdata) == PJ_SUCCESS)
1544
1280
        return pjsip_inv_send_msg(call->inv, tdata);
1545
1281
 
1546
1282
    return !PJ_SUCCESS;
1547
1283
}
1548
1284
 
1549
 
void invite_session_state_changed_cb(pjsip_inv_session *inv, pjsip_event *e)
 
1285
void invite_session_state_changed_cb(pjsip_inv_session *inv, pjsip_event *ev)
1550
1286
{
 
1287
    if (!inv)
 
1288
        return;
1551
1289
    SIPCall *call = static_cast<SIPCall*>(inv->mod_data[mod_ua_.id]);
1552
1290
 
1553
1291
    if (call == NULL)
1554
1292
        return;
1555
1293
 
1556
 
    SIPVoIPLink *link = SIPVoIPLink::instance();
1557
 
 
1558
 
    if (inv->state != PJSIP_INV_STATE_CONFIRMED) {
 
1294
    if (ev and inv->state != PJSIP_INV_STATE_CONFIRMED) {
1559
1295
        // Update UI with the current status code and description
1560
 
        pjsip_transaction * tsx = e->body.tsx_state.tsx;
 
1296
        pjsip_transaction * tsx = ev->body.tsx_state.tsx;
1561
1297
        int statusCode = tsx ? tsx->status_code : 404;
1562
1298
 
1563
1299
        if (statusCode) {
1564
1300
            const pj_str_t * description = pjsip_get_status_text(statusCode);
1565
 
            Manager::instance().getDbusManager()->getCallManager()->sipCallStateChanged(call->getCallId(), std::string(description->ptr, description->slen), statusCode);
 
1301
            std::string desc(description->ptr, description->slen);
 
1302
            CallManager *cm = Manager::instance().getDbusManager()->getCallManager();
 
1303
            cm->sipCallStateChanged(call->getCallId(), desc, statusCode);
1566
1304
        }
1567
1305
    }
1568
1306
 
1569
 
    if (inv->state == PJSIP_INV_STATE_EARLY and e->body.tsx_state.tsx->role == PJSIP_ROLE_UAC) {
 
1307
    SIPVoIPLink *link = SIPVoIPLink::instance();
 
1308
    if (inv->state == PJSIP_INV_STATE_EARLY and ev and ev->body.tsx_state.tsx and
 
1309
            ev->body.tsx_state.tsx->role == PJSIP_ROLE_UAC) {
1570
1310
        call->setConnectionState(Call::RINGING);
1571
1311
        Manager::instance().peerRingingCall(call->getCallId());
1572
 
    } else if (inv->state == PJSIP_INV_STATE_CONFIRMED) {
 
1312
    } else if (inv->state == PJSIP_INV_STATE_CONFIRMED and ev) {
1573
1313
        // After we sent or received a ACK - The connection is established
1574
 
        link->SIPCallAnswered(call, e->body.tsx_state.src.rdata);
 
1314
        link->SIPCallAnswered(call, ev->body.tsx_state.src.rdata);
1575
1315
    } else if (inv->state == PJSIP_INV_STATE_DISCONNECTED) {
1576
1316
        std::string accId(Manager::instance().getAccountFromCall(call->getCallId()));
1577
1317
 
1582
1322
                link->SIPCallClosed(call);
1583
1323
                break;
1584
1324
            case PJSIP_SC_DECLINE:
1585
 
 
1586
1325
                if (inv->role != PJSIP_ROLE_UAC)
1587
1326
                    break;
1588
1327
 
1604
1343
 
1605
1344
void sdp_request_offer_cb(pjsip_inv_session *inv, const pjmedia_sdp_session *offer)
1606
1345
{
1607
 
    SIPCall *call = (SIPCall*) inv->mod_data[mod_ua_.id ];
 
1346
    if (!inv)
 
1347
        return;
 
1348
    SIPCall *call = static_cast<SIPCall*>(inv->mod_data[mod_ua_.id]);
1608
1349
 
1609
1350
    if (!call)
1610
1351
        return;
1611
1352
 
1612
1353
    std::string accId(Manager::instance().getAccountFromCall(call->getCallId()));
1613
1354
    SIPAccount *account = dynamic_cast<SIPAccount *>(Manager::instance().getAccount(accId));
 
1355
    if (!account)
 
1356
        return;
1614
1357
 
1615
1358
    call->getLocalSDP()->receiveOffer(offer, account->getActiveCodecs());
1616
1359
    call->getLocalSDP()->startNegotiation();
1620
1363
 
1621
1364
void sdp_create_offer_cb(pjsip_inv_session *inv, pjmedia_sdp_session **p_offer)
1622
1365
{
 
1366
    if (!inv or !p_offer)
 
1367
        return;
1623
1368
    SIPCall *call = static_cast<SIPCall*>(inv->mod_data[mod_ua_.id]);
 
1369
    if (!call)
 
1370
        return;
1624
1371
    std::string accountid(Manager::instance().getAccountFromCall(call->getCallId()));
1625
1372
 
1626
1373
    SIPAccount *account = dynamic_cast<SIPAccount *>(Manager::instance().getAccount(accountid));
1627
1374
 
1628
 
    std::string localAddress(SIPVoIPLink::instance()->getInterfaceAddrFromName(account->getLocalInterface()));
 
1375
    std::string localAddress(SipTransport::getInterfaceAddrFromName(account->getLocalInterface()));
1629
1376
    std::string addrSdp(localAddress);
1630
1377
 
1631
1378
    if (localAddress == "0.0.0.0")
1632
 
        localAddress = getSIPLocalIP();
 
1379
        localAddress = SipTransport::getSIPLocalIP();
1633
1380
 
1634
1381
    if (addrSdp == "0.0.0.0")
1635
1382
        addrSdp = localAddress;
1645
1392
// This callback is called after SDP offer/answer session has completed.
1646
1393
void sdp_media_update_cb(pjsip_inv_session *inv, pj_status_t status)
1647
1394
{
1648
 
    const pjmedia_sdp_session *remote_sdp;
1649
 
    const pjmedia_sdp_session *local_sdp;
1650
 
 
 
1395
    if (!inv)
 
1396
        return;
1651
1397
    SIPCall *call = static_cast<SIPCall *>(inv->mod_data[mod_ua_.id]);
1652
1398
 
1653
1399
    if (call == NULL) {
1654
 
        DEBUG("UserAgent: Call declined by peer, SDP negotiation stopped");
 
1400
        DEBUG("Call declined by peer, SDP negotiation stopped");
1655
1401
        return;
1656
1402
    }
1657
1403
 
1658
1404
    if (status != PJ_SUCCESS) {
1659
 
        WARN("UserAgent: Error: while negotiating the offer");
 
1405
        WARN("Could not negotiate offer");
1660
1406
        SIPVoIPLink::instance()->hangup(call->getCallId());
1661
1407
        Manager::instance().callFailure(call->getCallId());
1662
1408
        return;
1663
1409
    }
1664
1410
 
1665
1411
    if (!inv->neg) {
1666
 
        WARN("UserAgent: Error: no negotiator for this session");
 
1412
        WARN("No negotiator for this session");
1667
1413
        return;
1668
1414
    }
1669
1415
 
1670
1416
    // Retreive SDP session for this call
1671
1417
    Sdp *sdpSession = call->getLocalSDP();
 
1418
    if (!sdpSession) {
 
1419
        ERROR("No SDP session");
 
1420
        return;
 
1421
    }
1672
1422
 
1673
1423
    // Get active session sessions
 
1424
    const pjmedia_sdp_session *remote_sdp;
1674
1425
    pjmedia_sdp_neg_get_active_remote(inv->neg, &remote_sdp);
 
1426
    const pjmedia_sdp_session *local_sdp;
1675
1427
    pjmedia_sdp_neg_get_active_local(inv->neg, &local_sdp);
1676
1428
 
1677
1429
    // Print SDP session
1678
1430
    char buffer[1000];
1679
1431
    memset(buffer, 0, sizeof buffer);
1680
 
    pjmedia_sdp_print(remote_sdp, buffer, 1000);
1681
 
    DEBUG("SDP: Remote active SDP Session:\n%s", buffer);
 
1432
    pjmedia_sdp_print(remote_sdp, buffer, sizeof buffer);
 
1433
    DEBUG("Remote active SDP Session:\n%s", buffer);
1682
1434
 
1683
 
    memset(buffer, 0, 1000);
1684
 
    pjmedia_sdp_print(local_sdp, buffer, 1000);
1685
 
    DEBUG("SDP: Local active SDP Session:\n%s", buffer);
 
1435
    memset(buffer, 0, sizeof buffer);
 
1436
    pjmedia_sdp_print(local_sdp, buffer, sizeof buffer);
 
1437
    DEBUG("Local active SDP Session:\n%s", buffer);
1686
1438
 
1687
1439
    // Set active SDP sessions
1688
1440
    sdpSession->setActiveRemoteSdpSession(remote_sdp);
1701
1453
    bool nego_success = false;
1702
1454
 
1703
1455
    if (!crypto_offer.empty()) {
1704
 
        std::vector<sfl::CryptoSuiteDefinition>localCapabilities;
 
1456
        std::vector<sfl::CryptoSuiteDefinition> localCapabilities;
1705
1457
 
1706
 
        for (int i = 0; i < 3; i++)
 
1458
        for (size_t i = 0; i < ARRAYSIZE(sfl::CryptoSuites); ++i)
1707
1459
            localCapabilities.push_back(sfl::CryptoSuites[i]);
1708
1460
 
1709
1461
        sfl::SdesNegotiator sdesnego(localCapabilities, crypto_offer);
1710
1462
 
1711
1463
        if (sdesnego.negotiate()) {
1712
 
            DEBUG("UserAgent: SDES negotiation successfull");
1713
1464
            nego_success = true;
1714
1465
 
1715
1466
            try {
1718
1469
 
1719
1470
            Manager::instance().getDbusManager()->getCallManager()->secureSdesOn(call->getCallId());
1720
1471
        } else {
 
1472
            ERROR("SDES negotiation failure");
1721
1473
            Manager::instance().getDbusManager()->getCallManager()->secureSdesOff(call->getCallId());
1722
1474
        }
1723
1475
    }
1724
 
 
1725
 
 
1726
 
    // We did not found any crypto context for this media, RTP fallback
 
1476
    else {
 
1477
        DEBUG("No crypto offer available");
 
1478
    }
 
1479
 
 
1480
    // We did not find any crypto context for this media, RTP fallback
1727
1481
    if (!nego_success && call->getAudioRtp().isSdesEnabled()) {
 
1482
        ERROR("Negotiation failed but SRTP is enabled, fallback on RTP");
1728
1483
        call->getAudioRtp().stop();
1729
1484
        call->getAudioRtp().setSrtpEnabled(false);
1730
1485
 
1731
1486
        std::string accountID = Manager::instance().getAccountFromCall(call->getCallId());
1732
1487
 
1733
 
        if (((SIPAccount *) Manager::instance().getAccount(accountID))->getSrtpFallback())
1734
 
            call->getAudioRtp().initAudioSymmetricRtpSession();
 
1488
        if (dynamic_cast<SIPAccount*>(Manager::instance().getAccount(accountID))->getSrtpFallback())
 
1489
            call->getAudioRtp().initSession();
1735
1490
    }
1736
1491
 
1737
 
    if (!sdpSession)
1738
 
        return;
1739
 
 
1740
1492
    sfl::AudioCodec *sessionMedia = sdpSession->getSessionMedia();
1741
1493
 
1742
1494
    if (!sessionMedia)
1750
1502
        int pl = sessionMedia->getPayloadType();
1751
1503
 
1752
1504
        if (pl != call->getAudioRtp().getSessionMedia()) {
1753
 
            sfl::Codec* audiocodec = Manager::instance().audioCodecFactory.instantiateCodec(pl);
1754
 
            call->getAudioRtp().updateSessionMedia(static_cast<sfl::AudioCodec *>(audiocodec));
 
1505
            sfl::AudioCodec *ac = dynamic_cast<sfl::AudioCodec*>(Manager::instance().audioCodecFactory.instantiateCodec(pl));
 
1506
            if (!ac)
 
1507
                throw std::runtime_error("Could not instantiate codec");
 
1508
            call->getAudioRtp().updateSessionMedia(ac);
1755
1509
        }
1756
1510
    } catch (const SdpException &e) {
1757
 
        ERROR("UserAgent: Exception: %s", e.what());
1758
 
    } catch (const std::exception& rtpException) {
1759
 
        ERROR("UserAgent: Exception: %s", rtpException.what());
 
1511
        ERROR("%s", e.what());
 
1512
    } catch (const std::exception &rtpException) {
 
1513
        ERROR("%s", rtpException.what());
1760
1514
    }
1761
1515
 
1762
1516
}
1763
1517
 
1764
 
void outgoing_request_forked_cb(pjsip_inv_session *inv UNUSED, pjsip_event *e UNUSED)
1765
 
{
1766
 
}
1767
 
 
1768
 
void transaction_state_changed_cb(pjsip_inv_session *inv UNUSED, pjsip_transaction *tsx, pjsip_event *e)
1769
 
{
1770
 
    assert(tsx);
1771
 
    assert(e);
1772
 
 
1773
 
    if (tsx->role != PJSIP_ROLE_UAS || tsx->state != PJSIP_TSX_STATE_TRYING)
 
1518
void outgoing_request_forked_cb(pjsip_inv_session * /*inv*/, pjsip_event * /*e*/)
 
1519
{}
 
1520
 
 
1521
void transaction_state_changed_cb(pjsip_inv_session * inv,
 
1522
                                  pjsip_transaction *tsx, pjsip_event *event)
 
1523
{
 
1524
    if (!tsx or !event or !inv or tsx->role != PJSIP_ROLE_UAS or
 
1525
            tsx->state != PJSIP_TSX_STATE_TRYING)
1774
1526
        return;
1775
1527
 
1776
 
    if (pjsip_method_cmp(&tsx->method, &pjsip_refer_method) ==0) {
1777
 
        onCallTransfered(inv, e->body.tsx_state.src.rdata);          /** Handle the refer method **/
 
1528
    // Handle the refer method
 
1529
    if (pjsip_method_cmp(&tsx->method, &pjsip_refer_method) == 0) {
 
1530
        onCallTransfered(inv, event->body.tsx_state.src.rdata);
1778
1531
        return;
1779
1532
    }
1780
1533
 
1781
1534
    pjsip_tx_data* t_data;
1782
1535
 
1783
 
    if (e->body.rx_msg.rdata) {
1784
 
        pjsip_rx_data *r_data = e->body.rx_msg.rdata;
 
1536
    if (event->body.rx_msg.rdata) {
 
1537
        pjsip_rx_data *r_data = event->body.rx_msg.rdata;
1785
1538
 
1786
1539
        if (r_data && r_data->msg_info.msg->line.req.method.id == PJSIP_OTHER_METHOD) {
1787
1540
            std::string request =  pjsip_rx_data_get_info(r_data);
1788
 
            DEBUG("UserAgent: %s", request.c_str());
 
1541
            DEBUG("%s", request.c_str());
1789
1542
 
1790
1543
            if (request.find("NOTIFY") == std::string::npos && request.find("INFO") != std::string::npos) {
1791
1544
                pjsip_dlg_create_response(inv->dlg, r_data, PJSIP_SC_OK, NULL, &t_data);
1795
1548
        }
1796
1549
    }
1797
1550
 
1798
 
    if (!e->body.tsx_state.src.rdata)
 
1551
    if (!event->body.tsx_state.src.rdata)
1799
1552
        return;
1800
1553
 
1801
1554
    // Incoming TEXT message
1802
1555
 
1803
1556
    // Get the message inside the transaction
1804
 
    pjsip_rx_data *r_data = e->body.tsx_state.src.rdata;
1805
 
    std::string formatedMessage = (char*) r_data->msg_info.msg->body->data;
 
1557
    pjsip_rx_data *r_data = event->body.tsx_state.src.rdata;
 
1558
    if (!r_data->msg_info.msg->body)
 
1559
        return;
 
1560
    const char *formattedMsgPtr = static_cast<const char*>(r_data->msg_info.msg->body->data);
 
1561
    if (!formattedMsgPtr)
 
1562
        return;
 
1563
    std::string formattedMessage(formattedMsgPtr, strlen(formattedMsgPtr));
1806
1564
 
1807
1565
    // Try to determine who is the recipient of the message
1808
1566
    SIPCall *call = static_cast<SIPCall *>(inv->mod_data[mod_ua_.id]);
1814
1572
    pjsip_dlg_create_response(inv->dlg, r_data, PJSIP_SC_OK, NULL, &t_data);
1815
1573
    pjsip_dlg_send_response(inv->dlg, tsx, t_data);
1816
1574
 
1817
 
    sfl::InstantMessaging *module = Manager::instance().getInstantMessageModule();
 
1575
    using namespace sfl::InstantMessaging;
1818
1576
 
1819
1577
    try {
1820
1578
        // retreive the recipient-list of this message
1821
 
        std::string urilist = module->findTextUriList(formatedMessage);
1822
 
        sfl::InstantMessaging::UriList list = module->parseXmlUriList(urilist);
 
1579
        std::string urilist = findTextUriList(formattedMessage);
 
1580
        UriList list = parseXmlUriList(urilist);
1823
1581
 
1824
1582
        // If no item present in the list, peer is considered as the sender
1825
1583
        std::string from;
1837
1595
        if (from[0] == '<' && from[from.size()-1] == '>')
1838
1596
            from = from.substr(1, from.size()-2);
1839
1597
 
1840
 
        Manager::instance().incomingMessage(call->getCallId(), from, module->findTextMessage(formatedMessage));
 
1598
        Manager::instance().incomingMessage(call->getCallId(), from, findTextMessage(formattedMessage));
1841
1599
 
1842
1600
    } catch (const sfl::InstantMessageException &except) {
1843
 
        ERROR("SipVoipLink: %s", except.what());
 
1601
        ERROR("%s", except.what());
1844
1602
    }
1845
1603
}
1846
1604
 
1847
1605
void update_contact_header(pjsip_regc_cbparam *param, SIPAccount *account)
1848
1606
{
1849
 
 
1850
1607
    SIPVoIPLink *siplink = dynamic_cast<SIPVoIPLink *>(account->getVoIPLink());
1851
 
    if(siplink == NULL) {
1852
 
        ERROR("SIPVoIPLink: Could not find voip link from account");
 
1608
    if (siplink == NULL) {
 
1609
        ERROR("Could not find voip link from account");
1853
1610
        return;
1854
1611
    }
1855
1612
 
1856
1613
    pj_pool_t *pool = pj_pool_create(&cp_->factory, "tmp", 512, 512, NULL);
1857
 
    if(pool == NULL) {
1858
 
        ERROR("SIPVoIPLink: Could not create temporary memory pool in transport header");
 
1614
    if (pool == NULL) {
 
1615
        ERROR("Could not create temporary memory pool in transport header");
1859
1616
        return;
1860
1617
    }
1861
1618
 
1862
 
    if (param->contact_cnt == 0) {
 
1619
    if (!param or param->contact_cnt == 0) {
1863
1620
        WARN("SIPVoIPLink: No contact header in registration callback");
1864
1621
        pj_pool_release(pool);
1865
1622
        return;
1866
1623
    }
1867
1624
 
1868
1625
    pjsip_contact_hdr *contact_hdr = param->contact[0];
 
1626
    if (!contact_hdr)
 
1627
        return;
1869
1628
 
1870
1629
    pjsip_sip_uri *uri = (pjsip_sip_uri*) contact_hdr->uri;
1871
1630
    if (uri == NULL) {
1872
 
        ERROR("SIPVoIPLink: Could not find uri in contact header");
 
1631
        ERROR("Could not find uri in contact header");
1873
1632
        pj_pool_release(pool);
1874
1633
        return;
1875
1634
    }
1876
1635
 
1877
1636
    // TODO: make this based on transport type
1878
1637
    // with pjsip_transport_get_default_port_for_type(tp_type);
1879
 
    if (uri->port == 0)
 
1638
    if (uri->port == 0) {
 
1639
        ERROR("Port is 0 in uri");
1880
1640
        uri->port = DEFAULT_SIP_PORT;
 
1641
    }
1881
1642
 
1882
1643
    std::string recvContactHost(uri->host.ptr, uri->host.slen);
1883
1644
    std::stringstream ss;
1885
1646
    std::string recvContactPort = ss.str();
1886
1647
 
1887
1648
    std::string currentAddress, currentPort;
1888
 
    siplink->findLocalAddressFromTransport(account->transport_, PJSIP_TRANSPORT_UDP, currentAddress, currentPort);
 
1649
    siplink->sipTransport.findLocalAddressFromTransport(account->transport_, PJSIP_TRANSPORT_UDP, currentAddress, currentPort);
1889
1650
 
1890
1651
    bool updateContact = false;
1891
1652
    std::string currentContactHeader = account->getContactHeader();
1892
1653
 
1893
1654
    size_t foundHost = currentContactHeader.find(recvContactHost);
1894
 
    if(foundHost == std::string::npos) {
 
1655
    if (foundHost == std::string::npos)
1895
1656
        updateContact = true;
1896
 
    }
1897
1657
 
1898
1658
    size_t foundPort = currentContactHeader.find(recvContactPort);
1899
 
    if(foundPort == std::string::npos) {
 
1659
    if (foundPort == std::string::npos)
1900
1660
        updateContact = true;
1901
 
    }
1902
1661
 
1903
 
    if(updateContact) {
1904
 
        DEBUG("SIPVoIPLink: Update contact header: %s:%s\n", recvContactHost.c_str(), recvContactPort.c_str());
 
1662
    if (updateContact) {
 
1663
        DEBUG("Update contact header: %s:%s\n", recvContactHost.c_str(), recvContactPort.c_str());
1905
1664
        account->setContactHeader(recvContactHost, recvContactPort);
1906
1665
        siplink->sendRegister(account);
1907
1666
    }
1908
1667
    pj_pool_release(pool);
1909
1668
}
1910
1669
 
 
1670
void lookForReceivedParameter(pjsip_regc_cbparam &param, SIPAccount &account)
 
1671
{
 
1672
    if (!param.rdata or !param.rdata->msg_info.via)
 
1673
        return;
 
1674
    pj_str_t receivedValue = param.rdata->msg_info.via->recvd_param;
 
1675
 
 
1676
    if (receivedValue.slen) {
 
1677
        std::string publicIpFromReceived(receivedValue.ptr, receivedValue.slen);
 
1678
        account.setReceivedParameter(publicIpFromReceived);
 
1679
    }
 
1680
 
 
1681
    account.setRPort(param.rdata->msg_info.via->rport_param);
 
1682
}
 
1683
 
 
1684
void processRegistrationError(SIPAccount &account, RegistrationState state)
 
1685
{
 
1686
    account.stopKeepAliveTimer();
 
1687
    account.setRegistrationState(state);
 
1688
    account.setRegister(false);
 
1689
    SIPVoIPLink::instance()->sipTransport.shutdownSipTransport(account);
 
1690
}
 
1691
 
1911
1692
void registration_cb(pjsip_regc_cbparam *param)
1912
1693
{
 
1694
    if (param == NULL) {
 
1695
        ERROR("registration callback parameter is NULL");
 
1696
        return;
 
1697
    }
 
1698
 
1913
1699
    SIPAccount *account = static_cast<SIPAccount *>(param->token);
1914
 
 
1915
1700
    if (account == NULL) {
1916
 
        ERROR("SipVoipLink: account does'nt exist in registration callback");
1917
 
        return;
1918
 
    }
1919
 
 
1920
 
    if (param == NULL) {
1921
 
        ERROR("SipVoipLink: regsitration callback param is NULL");
1922
 
        return;
1923
 
    }
1924
 
 
1925
 
    if(account->isContactUpdateEnabled()) {
 
1701
        ERROR("account doesn't exist in registration callback");
 
1702
        return;
 
1703
    }
 
1704
 
 
1705
    if (account->isContactUpdateEnabled())
1926
1706
        update_contact_header(param, account);
1927
 
    }
1928
1707
 
1929
1708
    const pj_str_t *description = pjsip_get_status_text(param->code);
1930
1709
 
 
1710
    const std::string accountID = account->getAccountID();
 
1711
 
1931
1712
    if (param->code && description) {
1932
1713
        std::string state(description->ptr, description->slen);
1933
 
        Manager::instance().getDbusManager()->getCallManager()->registrationStateChanged(account->getAccountID(), state, param->code);
 
1714
        Manager::instance().getDbusManager()->getCallManager()->registrationStateChanged(accountID, state, param->code);
1934
1715
        std::pair<int, std::string> details(param->code, state);
1935
1716
        // TODO: there id a race condition for this ressource when closing the application
1936
1717
        account->setRegistrationStateDetailed(details);
1937
 
 
1938
1718
        account->setRegistrationExpire(param->expiration);
1939
1719
    }
1940
1720
 
 
1721
#define FAILURE_MESSAGE() ERROR("Could not register account %s with error %d", accountID.c_str(), param->code)
 
1722
 
1941
1723
    if (param->status != PJ_SUCCESS) {
1942
 
        account->setRegistrationState(ErrorAuth);
1943
 
        account->setRegister(false);
1944
 
 
1945
 
        SIPVoIPLink::instance()->shutdownSipTransport(account);
 
1724
        FAILURE_MESSAGE();
 
1725
        processRegistrationError(*account, ErrorAuth);
1946
1726
        return;
1947
1727
    }
1948
1728
 
1949
1729
    if (param->code < 0 || param->code >= 300) {
1950
1730
        switch (param->code) {
1951
 
            case 606:
1952
 
                account->setRegistrationState(ErrorConfStun);
1953
 
                break;
1954
 
 
1955
 
            case 503:
1956
 
            case 408:
1957
 
                account->setRegistrationState(ErrorHost);
1958
 
                break;
1959
 
 
1960
 
            case 401:
1961
 
            case 403:
1962
 
            case 404:
1963
 
                account->setRegistrationState(ErrorAuth);
1964
 
                break;
1965
 
 
1966
 
            case 423: { // Expiration Interval Too Brief
 
1731
            case PJSIP_SC_MULTIPLE_CHOICES: // 300
 
1732
            case PJSIP_SC_MOVED_PERMANENTLY: // 301
 
1733
            case PJSIP_SC_MOVED_TEMPORARILY: // 302
 
1734
            case PJSIP_SC_USE_PROXY: // 305
 
1735
            case PJSIP_SC_ALTERNATIVE_SERVICE: // 380
 
1736
                FAILURE_MESSAGE();
 
1737
                processRegistrationError(*account, Error);
 
1738
                break;
 
1739
            case PJSIP_SC_SERVICE_UNAVAILABLE: // 503
 
1740
                FAILURE_MESSAGE();
 
1741
                processRegistrationError(*account, ErrorHost);
 
1742
                break;
 
1743
            case PJSIP_SC_UNAUTHORIZED: // 401
 
1744
                // Automatically answered by PJSIP
 
1745
                account->registerVoIPLink();
 
1746
                break;
 
1747
            case PJSIP_SC_FORBIDDEN: // 403
 
1748
            case PJSIP_SC_NOT_FOUND: // 404
 
1749
                FAILURE_MESSAGE();
 
1750
                processRegistrationError(*account, ErrorAuth);
 
1751
                break;
 
1752
            case PJSIP_SC_REQUEST_TIMEOUT: // 408
 
1753
                FAILURE_MESSAGE();
 
1754
                processRegistrationError(*account, ErrorHost);
 
1755
                break;
 
1756
            case PJSIP_SC_INTERVAL_TOO_BRIEF: // 423
 
1757
                // Expiration Interval Too Brief
1967
1758
                account->doubleRegistrationExpire();
1968
1759
                account->registerVoIPLink();
1969
 
            }
1970
 
            break;
1971
 
 
 
1760
                account->setRegister(false);
 
1761
                break;
 
1762
            case PJSIP_SC_NOT_ACCEPTABLE_ANYWHERE: // 606
 
1763
                lookForReceivedParameter(*param, *account);
 
1764
                account->setRegistrationState(ErrorNotAcceptable);
 
1765
                account->registerVoIPLink();
 
1766
                break;
1972
1767
            default:
1973
 
                account->setRegistrationState(Error);
 
1768
                FAILURE_MESSAGE();
 
1769
                processRegistrationError(*account, Error);
1974
1770
                break;
1975
1771
        }
1976
1772
 
1977
 
        account->setRegister(false);
1978
 
 
1979
 
        SIPVoIPLink::instance()->shutdownSipTransport(account);
1980
 
 
1981
1773
    } else {
 
1774
        lookForReceivedParameter(*param, *account);
1982
1775
        if (account->isRegistered())
1983
1776
            account->setRegistrationState(Registered);
1984
1777
        else {
1985
1778
            account->setRegistrationState(Unregistered);
1986
 
            SIPVoIPLink::instance()->shutdownSipTransport(account);
 
1779
            SIPVoIPLink::instance()->sipTransport.shutdownSipTransport(*account);
1987
1780
        }
1988
1781
    }
 
1782
 
 
1783
#undef FAILURE_MESSAGE
1989
1784
}
1990
1785
 
1991
1786
void onCallTransfered(pjsip_inv_session *inv, pjsip_rx_data *rdata)
2012
1807
{
2013
1808
    switch (pjsip_evsub_get_state(sub)) {
2014
1809
        case PJSIP_EVSUB_STATE_ACCEPTED:
 
1810
            if (!event)
 
1811
                return;
2015
1812
            pj_assert(event->type == PJSIP_EVENT_TSX_STATE && event->body.tsx_state.type == PJSIP_EVENT_RX_MSG);
2016
1813
            break;
2017
1814
 
2034
1831
 
2035
1832
            pjsip_status_line status_line = { 500, *pjsip_get_status_text(500) };
2036
1833
 
 
1834
            if (!r_data->msg_info.msg)
 
1835
                return;
2037
1836
            if (r_data->msg_info.msg->line.req.method.id == PJSIP_OTHER_METHOD and
2038
1837
                request.find("NOTIFY") != std::string::npos) {
2039
1838
                pjsip_msg_body *body = r_data->msg_info.msg->body;
2049
1848
                    return;
2050
1849
            }
2051
1850
 
 
1851
            if (r_data->msg_info.cid)
 
1852
                return;
2052
1853
            std::string transferID(r_data->msg_info.cid->id.ptr, r_data->msg_info.cid->id.slen);
2053
1854
            SIPCall *call = dynamic_cast<SIPCall *>(link->getCall(transferCallID[transferID]));
2054
1855
 
2055
1856
            if (!call)
2056
1857
                return;
2057
1858
 
2058
 
            if (status_line.code/100 == 2) {
 
1859
            if (status_line.code / 100 == 2) {
2059
1860
                pjsip_tx_data *tdata;
2060
1861
 
 
1862
                if (!call->inv)
 
1863
                    return;
2061
1864
                if (pjsip_inv_end_session(call->inv, PJSIP_SC_GONE, NULL, &tdata) == PJ_SUCCESS)
2062
1865
                    pjsip_inv_send_msg(call->inv, tdata);
2063
1866
 
2076
1879
{
2077
1880
    std::string account_id(Manager::instance().getAccountFromCall(call->getCallId()));
2078
1881
    SIPAccount *account = dynamic_cast<SIPAccount *>(Manager::instance().getAccount(account_id));
 
1882
    if (!account)
 
1883
        return;
2079
1884
 
2080
1885
    unsigned int callLocalAudioPort = ((rand() % 27250) + 5250) * 2;
2081
1886
 
2087
1892
    call->setLocalAudioPort(callLocalAudioPort);
2088
1893
    call->getLocalSDP()->setLocalPublishedAudioPort(callLocalExternAudioPort);
2089
1894
}
2090
 
 
2091
 
std::string fetchHeaderValue(pjsip_msg *msg, const std::string &field)
2092
 
{
2093
 
    pj_str_t name = pj_str((char*) field.c_str());
2094
 
 
2095
 
    pjsip_generic_string_hdr *hdr = static_cast<pjsip_generic_string_hdr*>(pjsip_msg_find_hdr_by_name(msg, &name, NULL));
2096
 
 
2097
 
    if (!hdr)
2098
 
        return "";
2099
 
 
2100
 
    std::string value(std::string(hdr->hvalue.ptr, hdr->hvalue.slen));
2101
 
 
2102
 
    size_t pos = value.find("\n");
2103
 
 
2104
 
    if (pos == std::string::npos)
2105
 
        return "";
2106
 
 
2107
 
    return value.substr(0, pos);
2108
 
}
2109
1895
} // end anonymous namespace
2110
 
 
2111
 
std::vector<std::string> SIPVoIPLink::getAllIpInterfaceByName()
2112
 
{
2113
 
    static ifreq ifreqs[20];
2114
 
    ifconf ifconf;
2115
 
 
2116
 
    std::vector<std::string> ifaceList;
2117
 
    ifaceList.push_back("default");
2118
 
 
2119
 
    ifconf.ifc_buf = (char*) (ifreqs);
2120
 
    ifconf.ifc_len = sizeof(ifreqs);
2121
 
 
2122
 
    int sock = socket(AF_INET,SOCK_STREAM,0);
2123
 
 
2124
 
    if (sock >= 0) {
2125
 
        if (ioctl(sock, SIOCGIFCONF, &ifconf) >= 0)
2126
 
            for (unsigned i = 0; i < ifconf.ifc_len / sizeof(ifreq); ++i)
2127
 
                ifaceList.push_back(std::string(ifreqs[i].ifr_name));
2128
 
 
2129
 
        close(sock);
2130
 
    }
2131
 
 
2132
 
    return ifaceList;
2133
 
}
2134
 
 
2135
 
std::string SIPVoIPLink::getInterfaceAddrFromName(const std::string &ifaceName)
2136
 
{
2137
 
    int fd = socket(AF_INET, SOCK_DGRAM,0);
2138
 
 
2139
 
    if (fd < 0) {
2140
 
        ERROR("UserAgent: Error: could not open socket: %m");
2141
 
        return "";
2142
 
    }
2143
 
 
2144
 
    ifreq ifr;
2145
 
    strcpy(ifr.ifr_name, ifaceName.c_str());
2146
 
    memset(&ifr.ifr_addr, 0, sizeof(ifr.ifr_addr));
2147
 
    ifr.ifr_addr.sa_family = AF_INET;
2148
 
 
2149
 
    ioctl(fd, SIOCGIFADDR, &ifr);
2150
 
    close(fd);
2151
 
 
2152
 
    sockaddr_in *saddr_in = (sockaddr_in *) &ifr.ifr_addr;
2153
 
    return inet_ntoa(saddr_in->sin_addr);
2154
 
}
2155
 
 
2156
 
std::vector<std::string> SIPVoIPLink::getAllIpInterface()
2157
 
{
2158
 
    pj_sockaddr addrList[16];
2159
 
    unsigned addrCnt = PJ_ARRAY_SIZE(addrList);
2160
 
 
2161
 
    std::vector<std::string> ifaceList;
2162
 
 
2163
 
    if (pj_enum_ip_interface(pj_AF_INET(), &addrCnt, addrList) == PJ_SUCCESS)
2164
 
        for (unsigned i = 0; i < addrCnt; i++) {
2165
 
            char addr[PJ_INET_ADDRSTRLEN];
2166
 
            pj_sockaddr_print(&addrList[i], addr, sizeof(addr), 0);
2167
 
            ifaceList.push_back(std::string(addr));
2168
 
        }
2169
 
 
2170
 
    return ifaceList;
2171
 
}