207
165
* ACK for a 2xx response must be send using this method.
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);
214
174
return PJ_SUCCESS;
217
std::string parseDisplayName(const char * buffer)
219
const char* from_header = strstr(buffer, "From: ");
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));
229
static const size_t MAX_DISPLAY_NAME_SIZE = 25;
230
if (displayName.size() > MAX_DISPLAY_NAME_SIZE)
236
void stripSipUriPrefix(std::string& sipUri)
238
// Remove sip: prefix
239
static const char SIP_PREFIX[] = "sip:";
240
size_t found = sipUri.find(SIP_PREFIX);
242
if (found != std::string::npos)
243
sipUri.erase(found, found + (sizeof SIP_PREFIX) - 1);
245
found = sipUri.find("@");
247
if (found != std::string::npos)
251
177
pj_bool_t transaction_request_cb(pjsip_rx_data *rdata)
179
if (!rdata or !rdata->msg_info.msg) {
180
ERROR("rx_data is NULL");
253
183
pjsip_method *method = &rdata->msg_info.msg->line.req.method;
185
ERROR("method is NULL");
255
189
if (method->id == PJSIP_ACK_METHOD && pjsip_rdata_get_dlg(rdata))
192
if (!rdata->msg_info.to or !rdata->msg_info.from) {
193
ERROR("NULL from/to fields");
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) {
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));
264
std::string displayName(parseDisplayName(rdata->msg_info.msg_buf));
206
std::string displayName(sip_utils::parseDisplayName(rdata->msg_info.msg_buf));
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);
270
if (request.find("NOTIFY") != (size_t)-1) {
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) {
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);
277
222
pjsip_endpt_respond_stateless(endpt_, rdata, PJSIP_SC_OK, NULL, NULL, NULL);
280
224
} else if (method->id == PJSIP_OPTIONS_METHOD) {
281
225
handleIncomingOptions(rdata);
666
665
pjsip_endpt_cancel_timer(endpt_, &timer);
668
bool isValidIpAddress(const std::string &address)
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);
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));
669
681
Call *SIPVoIPLink::newOutgoingCall(const std::string& id, const std::string& toUrl)
683
DEBUG("New outgoing call to %s", toUrl.c_str());
684
std::string toCpy = toUrl;
686
sip_utils::stripSipUriPrefix(toCpy);
688
bool IPToIP = isValidIpAddress(toCpy);
689
Manager::instance().setIPToIPForCall(id, IPToIP);
693
Manager::instance().associateCallToAccount(id, SIPAccount::IP2IP_PROFILE);
694
return SIPNewIpToIpCall(id, toUrl);
697
return newRegisteredAccountCall(id, toUrl);
705
Call *SIPVoIPLink::SIPNewIpToIpCall(const std::string& id, const std::string& to)
707
DEBUG("New IP to IP call to %s", to.c_str());
709
SIPAccount *account = Manager::instance().getIP2IPAccount();
712
throw VoipLinkException("Could not retrieve default account for IP2IP call");
714
SIPCall *call = new SIPCall(id, Call::OUTGOING, cp_);
716
call->setIPToIP(true);
717
call->initRecFilename(to);
719
std::string localAddress(SipTransport::getInterfaceAddrFromName(account->getLocalInterface()));
721
if (localAddress == "0.0.0.0")
722
localAddress = SipTransport::getSIPLocalIP();
724
setCallMediaLocal(call, localAddress);
726
std::string toUri = account->getToUri(to);
727
call->setPeerNumber(toUri);
729
sfl::AudioCodec* ac = dynamic_cast<sfl::AudioCodec*>(Manager::instance().audioCodecFactory.instantiateCodec(PAYLOAD_CODEC_ULAW));
733
throw VoipLinkException("Could not instantiate codec");
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);
742
// Building the local SDP offer
743
call->getLocalSDP()->setLocalIP(localAddress);
744
call->getLocalSDP()->createOffer(account->getActiveCodecs());
746
if (!SIPStartCall(call)) {
748
throw VoipLinkException("Could not create new call");
754
Call *SIPVoIPLink::newRegisteredAccountCall(const std::string& id, const std::string& toUrl)
756
DEBUG("UserAgent: New registered account call to %s", toUrl.c_str());
671
758
SIPAccount *account = dynamic_cast<SIPAccount *>(Manager::instance().getAccount(Manager::instance().getAccountFromCall(id)));
673
760
if (account == NULL) // TODO: We should investigate how we could get rid of this error and create a IP2IP call instead
1171
bool SIPVoIPLink::SIPNewIpToIpCall(const std::string& id, const std::string& to)
1173
SIPAccount *account = dynamic_cast<SIPAccount *>(Manager::instance().getAccount(IP2IP_PROFILE));
1178
SIPCall *call = new SIPCall(id, Call::OUTGOING, cp_);
1179
call->setIPToIP(true);
1180
call->initRecFilename(to);
1182
std::string localAddress(getInterfaceAddrFromName(account->getLocalInterface()));
1184
if (localAddress == "0.0.0.0")
1185
localAddress = getSIPLocalIP();
1187
setCallMediaLocal(call, localAddress);
1189
std::string toUri = account->getToUri(to);
1190
call->setPeerNumber(toUri);
1192
sfl::Codec* audiocodec = Manager::instance().audioCodecFactory.instantiateCodec(PAYLOAD_CODEC_ULAW);
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));
1201
// Building the local SDP offer
1202
call->getLocalSDP()->setLocalIP(localAddress);
1203
call->getLocalSDP()->createOffer(account->getActiveCodecs());
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());
1215
std::string remoteAddr(toUri.substr(at + 1, trns - at - 1));
1217
if (toUri.find("sips:") != 1) {
1218
DEBUG("UserAgent: Error \"sips\" scheme required for TLS call");
1223
shutdownSipTransport(account);
1224
createTlsTransport(account, remoteAddr);
1226
if (!account->transport_) {
1232
if (!SIPStartCall(call)) {
1241
1270
///////////////////////////////////////////////////////////////////////////////
1242
1271
// Private functions
1243
1272
///////////////////////////////////////////////////////////////////////////////
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)
1247
return status == PJ_SUCCESS;
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)
1256
pj_status_t SIPVoIPLink::stunServerResolve(SIPAccount *account)
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_));
1261
static const pj_stun_sock_cb stun_sock_cb = {
1262
stun_sock_on_rx_data_cb,
1264
stun_sock_on_status_cb
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);
1270
pj_str_t stunServer = account->getStunServerName();
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);
1279
status = pj_stun_sock_start(stun_sock, &stunServer, account->getStunPort(), NULL);
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);
1292
void SIPVoIPLink::createDefaultSipUdpTransport()
1294
SIPAccount *account = dynamic_cast<SIPAccount *>(Manager::instance().getAccount(IP2IP_PROFILE));
1295
createUdpTransport(account);
1296
assert(account->transport_);
1298
localUDPTransport_ = account->transport_;
1301
void SIPVoIPLink::createTlsListener(SIPAccount *account, pjsip_tpfactory **listener)
1303
pj_sockaddr_in local_addr;
1304
pj_sockaddr_in_init(&local_addr, 0, 0);
1305
local_addr.sin_port = pj_htons(account->getTlsListenerPort());
1308
pj_cstr(&pjAddress, PJ_INADDR_ANY);
1309
pj_sockaddr_in_set_str_addr(&local_addr, &pjAddress);
1310
std::string localIP(getSIPLocalIP());
1312
pjsip_host_port a_name = {
1313
pj_str((char*) localIP.c_str()),
1317
pjsip_tls_transport_start(endpt_, account->getTlsSetting(), &local_addr, &a_name, 1, listener);
1321
void SIPVoIPLink::createTlsTransport(SIPAccount *account, std::string remoteAddr)
1324
pj_cstr(&remote, remoteAddr.c_str());
1326
pj_sockaddr_in rem_addr;
1327
pj_sockaddr_in_init(&rem_addr, &remote, (pj_uint16_t) DEFAULT_SIP_TLS_PORT);
1329
static pjsip_tpfactory *localTlsListener = NULL; /** The local tls listener */
1331
if (localTlsListener == NULL)
1332
createTlsListener(account, &localTlsListener);
1334
pjsip_endpt_acquire_transport(endpt_, PJSIP_TRANSPORT_TLS, &rem_addr,
1335
sizeof rem_addr, NULL, &account->transport_);
1339
void SIPVoIPLink::createSipTransport(SIPAccount *account)
1341
shutdownSipTransport(account);
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));
1350
createTlsTransport(account, remoteAddr);
1351
} else if (account->isStunEnabled())
1352
createStunTransport(account);
1354
createUdpTransport(account);
1356
if (!account->transport_) {
1357
// Could not create new transport, this transport may already exists
1358
account->transport_ = transportMap_[account->getLocalPort()];
1360
if (account->transport_)
1361
pjsip_transport_add_ref(account->transport_);
1363
account->transport_ = localUDPTransport_;
1364
account->setLocalPort(localUDPTransport_->local_name.port);
1369
void SIPVoIPLink::createUdpTransport(SIPAccount *account)
1371
std::string listeningAddress;
1372
pj_uint16_t listeningPort = account->getLocalPort();
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;
1379
if (account->getLocalInterface() == "default") {
1380
listeningAddress = getSIPLocalIP();
1381
bound_addr.sin_addr.s_addr = pj_htonl(PJ_INADDR_ANY);
1383
listeningAddress = getInterfaceAddrFromName(account->getLocalInterface());
1384
bound_addr.sin_addr = pj_inet_addr2(listeningAddress.c_str());
1387
if (!account->getPublishedSameasLocal()) {
1388
listeningAddress = account->getPublishedAddress();
1389
listeningPort = account->getPublishedPort();
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();
1397
if (listeningAddress.empty() or listeningPort == 0)
1400
const pjsip_host_port a_name = {
1401
pj_str((char*) listeningAddress.c_str()),
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
1408
if (account->transport_)
1409
transportMap_[account->getLocalPort()] = account->transport_;
1412
pjsip_tpselector *SIPVoIPLink::initTransportSelector(pjsip_transport *transport, pj_pool_t *tp_pool) const
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;
1423
void SIPVoIPLink::createStunTransport(SIPAccount *account)
1425
pj_str_t stunServer = account->getStunServerName();
1426
pj_uint16_t stunPort = account->getStunPort();
1428
if (stunServerResolve(account) != PJ_SUCCESS) {
1429
ERROR("Can't resolve STUN server");
1433
pj_sock_t sock = PJ_INVALID_SOCKET;
1435
pj_sockaddr_in boundAddr;
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);
1442
if (pj_sock_socket(pj_AF_INET(), pj_SOCK_DGRAM(), 0, &sock) != PJ_SUCCESS) {
1443
ERROR("Can't create or bind socket");
1447
// Query the mapped IP address and port on the 'outside' of the NAT
1448
pj_sockaddr_in pub_addr;
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);
1456
pjsip_host_port a_name = {
1457
pj_str(pj_inet_ntoa(pub_addr.sin_addr)),
1458
pj_ntohs(pub_addr.sin_port)
1461
std::string listeningAddress = std::string(a_name.host.ptr, a_name.host.slen);
1463
account->setPublishedAddress(listeningAddress);
1464
account->setPublishedPort(a_name.port);
1466
pjsip_udp_transport_attach2(endpt_, PJSIP_TRANSPORT_UDP, sock, &a_name, 1,
1467
&account->transport_);
1469
pjsip_tpmgr_dump_transports(pjsip_endpt_get_tpmgr(endpt_));
1473
void SIPVoIPLink::shutdownSipTransport(SIPAccount *account)
1475
if (account->transport_) {
1476
pjsip_transport_dec_ref(account->transport_);
1477
account->transport_ = NULL;
1481
void SIPVoIPLink::findLocalAddressFromTransport(pjsip_transport *transport, pjsip_transport_type_e transportType, std::string &addr, std::string &port) const
1483
// Initialize the sip port with the default SIP port
1484
std::stringstream ss;
1485
ss << DEFAULT_SIP_PORT;
1488
// Initialize the sip address with the hostname
1489
const pj_str_t *pjMachineName = pj_gethostname();
1490
addr = std::string(pjMachineName->ptr, pjMachineName->slen);
1492
// Update address and port with active transport
1494
ERROR("SIPVoIPLink: Transport is NULL in findLocalAddress, using local address %s:%s", addr.c_str(), port.c_str());
1498
// get the transport manager associated with the SIP enpoint
1499
pjsip_tpmgr *tpmgr = pjsip_endpt_get_tpmgr(endpt_);
1501
ERROR("SIPVoIPLink: Transport manager is NULL in findLocalAddress, using local address %s:%s", addr.c_str(), port.c_str());
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_);
1510
ERROR("SIPVoIPLink: Could not initialize transport selector, using local address %s:%s", addr.c_str(), port.c_str());
1514
pj_str_t localAddress = {0,0};
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());
1523
// Update local address based on the transport type
1524
addr = std::string(localAddress.ptr, localAddress.slen);
1526
// Fallback on local ip provided by pj_gethostip()
1527
if (addr == "0.0.0.0")
1528
addr = getSIPLocalIP();
1530
// Determine the local port based on transport information
1537
1275
int SIPSessionReinvite(SIPCall *call)
1539
pjsip_tx_data *tdata;
1541
1277
pjmedia_sdp_session *local_sdp = call->getLocalSDP()->getLocalSdpSession();
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);
1546
1282
return !PJ_SUCCESS;
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)
1551
1289
SIPCall *call = static_cast<SIPCall*>(inv->mod_data[mod_ua_.id]);
1553
1291
if (call == NULL)
1556
SIPVoIPLink *link = SIPVoIPLink::instance();
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;
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);
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()));
1885
1646
std::string recvContactPort = ss.str();
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);
1890
1651
bool updateContact = false;
1891
1652
std::string currentContactHeader = account->getContactHeader();
1893
1654
size_t foundHost = currentContactHeader.find(recvContactHost);
1894
if(foundHost == std::string::npos) {
1655
if (foundHost == std::string::npos)
1895
1656
updateContact = true;
1898
1658
size_t foundPort = currentContactHeader.find(recvContactPort);
1899
if(foundPort == std::string::npos) {
1659
if (foundPort == std::string::npos)
1900
1660
updateContact = true;
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);
1908
1667
pj_pool_release(pool);
1670
void lookForReceivedParameter(pjsip_regc_cbparam ¶m, SIPAccount &account)
1672
if (!param.rdata or !param.rdata->msg_info.via)
1674
pj_str_t receivedValue = param.rdata->msg_info.via->recvd_param;
1676
if (receivedValue.slen) {
1677
std::string publicIpFromReceived(receivedValue.ptr, receivedValue.slen);
1678
account.setReceivedParameter(publicIpFromReceived);
1681
account.setRPort(param.rdata->msg_info.via->rport_param);
1684
void processRegistrationError(SIPAccount &account, RegistrationState state)
1686
account.stopKeepAliveTimer();
1687
account.setRegistrationState(state);
1688
account.setRegister(false);
1689
SIPVoIPLink::instance()->sipTransport.shutdownSipTransport(account);
1911
1692
void registration_cb(pjsip_regc_cbparam *param)
1694
if (param == NULL) {
1695
ERROR("registration callback parameter is NULL");
1913
1699
SIPAccount *account = static_cast<SIPAccount *>(param->token);
1915
1700
if (account == NULL) {
1916
ERROR("SipVoipLink: account does'nt exist in registration callback");
1920
if (param == NULL) {
1921
ERROR("SipVoipLink: regsitration callback param is NULL");
1925
if(account->isContactUpdateEnabled()) {
1701
ERROR("account doesn't exist in registration callback");
1705
if (account->isContactUpdateEnabled())
1926
1706
update_contact_header(param, account);
1929
1708
const pj_str_t *description = pjsip_get_status_text(param->code);
1710
const std::string accountID = account->getAccountID();
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);
1938
1718
account->setRegistrationExpire(param->expiration);
1721
#define FAILURE_MESSAGE() ERROR("Could not register account %s with error %d", accountID.c_str(), param->code)
1941
1723
if (param->status != PJ_SUCCESS) {
1942
account->setRegistrationState(ErrorAuth);
1943
account->setRegister(false);
1945
SIPVoIPLink::instance()->shutdownSipTransport(account);
1725
processRegistrationError(*account, ErrorAuth);
1949
1729
if (param->code < 0 || param->code >= 300) {
1950
1730
switch (param->code) {
1952
account->setRegistrationState(ErrorConfStun);
1957
account->setRegistrationState(ErrorHost);
1963
account->setRegistrationState(ErrorAuth);
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
1737
processRegistrationError(*account, Error);
1739
case PJSIP_SC_SERVICE_UNAVAILABLE: // 503
1741
processRegistrationError(*account, ErrorHost);
1743
case PJSIP_SC_UNAUTHORIZED: // 401
1744
// Automatically answered by PJSIP
1745
account->registerVoIPLink();
1747
case PJSIP_SC_FORBIDDEN: // 403
1748
case PJSIP_SC_NOT_FOUND: // 404
1750
processRegistrationError(*account, ErrorAuth);
1752
case PJSIP_SC_REQUEST_TIMEOUT: // 408
1754
processRegistrationError(*account, ErrorHost);
1756
case PJSIP_SC_INTERVAL_TOO_BRIEF: // 423
1757
// Expiration Interval Too Brief
1967
1758
account->doubleRegistrationExpire();
1968
1759
account->registerVoIPLink();
1760
account->setRegister(false);
1762
case PJSIP_SC_NOT_ACCEPTABLE_ANYWHERE: // 606
1763
lookForReceivedParameter(*param, *account);
1764
account->setRegistrationState(ErrorNotAcceptable);
1765
account->registerVoIPLink();
1973
account->setRegistrationState(Error);
1769
processRegistrationError(*account, Error);
1977
account->setRegister(false);
1979
SIPVoIPLink::instance()->shutdownSipTransport(account);
1774
lookForReceivedParameter(*param, *account);
1982
1775
if (account->isRegistered())
1983
1776
account->setRegistrationState(Registered);
1985
1778
account->setRegistrationState(Unregistered);
1986
SIPVoIPLink::instance()->shutdownSipTransport(account);
1779
SIPVoIPLink::instance()->sipTransport.shutdownSipTransport(*account);
1783
#undef FAILURE_MESSAGE
1991
1786
void onCallTransfered(pjsip_inv_session *inv, pjsip_rx_data *rdata)