diff --git a/src/ringdht/ringaccount.cpp b/src/ringdht/ringaccount.cpp index f295d6dd9ba8bd0f0cc982292041f5f95c095239..cc7a0930926f102ff3ed2777b3a60759d91f365a 100644 --- a/src/ringdht/ringaccount.cpp +++ b/src/ringdht/ringaccount.cpp @@ -1133,7 +1133,10 @@ RingAccount::matches(const std::string &userName, const std::string &server) con std::string RingAccount::getFromUri() const { - return "<sip:" + dht_.getId().toString() + "@ring.dht>"; + const std::string uri = "<sip:" + dht_.getId().toString() + "@ring.dht>"; + if (not displayName_.empty()) + return "\"" + displayName_ + "\" " + uri; + return uri; } std::string RingAccount::getToUri(const std::string& to) const diff --git a/src/sip/sip_utils.cpp b/src/sip/sip_utils.cpp index 2ff159d575d938a44e830c605d49cd5141e91911..c37674050f050665be547dc5b77fe799b8e8a2b3 100644 --- a/src/sip/sip_utils.cpp +++ b/src/sip/sip_utils.cpp @@ -101,58 +101,36 @@ createRouteSet(const std::string &route, pj_pool_t *hdr_pool) return route_set; } -// FIXME: replace with regex std::string -parseDisplayName(const char * buffer) +parseDisplayName(const pjsip_name_addr* sip_name_addr) { - // Start in From: in short and long form - const char* from_header = strstr(buffer, "\nFrom: "); - if (!from_header) - from_header = strstr(buffer, "\nf: "); - if (!from_header) - return ""; + if (not sip_name_addr->display.ptr or not sip_name_addr->display.slen) + return {}; - std::string temp(from_header); - - // Cut at end of line - temp = temp.substr(0, temp.find("\n", 1)); - - size_t begin_displayName = temp.find("\""); - size_t end_displayName; - if (begin_displayName != std::string::npos) { - // parse between quotes - end_displayName = temp.find("\"", begin_displayName + 1); - if (end_displayName == std::string::npos) - return ""; - } else { - // parse without quotes - end_displayName = temp.find("<"); - if (end_displayName != std::string::npos) { - begin_displayName = temp.find_first_not_of(" ", temp.find(":")); - if (begin_displayName == std::string::npos) - return ""; - - // omit trailing/leading spaces - begin_displayName++; - end_displayName--; - if (end_displayName == begin_displayName) - return ""; - } else { - return ""; - } - } - - std::string displayName = temp.substr(begin_displayName + 1, - end_displayName - begin_displayName - 1); + std::string displayName {sip_name_addr->display.ptr, + static_cast<size_t>(sip_name_addr->display.slen)}; // Filter out invalid UTF-8 characters to avoid getting kicked from D-Bus - if (not utf8_validate(displayName)) { + if (not utf8_validate(displayName)) return utf8_make_valid(displayName); - } return displayName; } +std::string +parseDisplayName(const pjsip_from_hdr* header) +{ + // PJSIP return a pjsip_name_addr for To, From and Contact headers + return parseDisplayName(reinterpret_cast<pjsip_name_addr*>(header->uri)); +} + +std::string +parseDisplayName(const pjsip_contact_hdr* header) +{ + // PJSIP return a pjsip_name_addr for To, From and Contact headers + return parseDisplayName(reinterpret_cast<pjsip_name_addr*>(header->uri)); +} + void stripSipUriPrefix(std::string& sipUri) { diff --git a/src/sip/sip_utils.h b/src/sip/sip_utils.h index aa5df501f966ab027d578ad1bc18b74cd8ba2d9e..51030aea7816f3ea38e65e1b6148e4c9f6e866af 100644 --- a/src/sip/sip_utils.h +++ b/src/sip/sip_utils.h @@ -73,7 +73,9 @@ createRouteSet(const std::string &route, pj_pool_t *hdr_pool); void stripSipUriPrefix(std::string& sipUri); -std::string parseDisplayName(const char * buffer); +std::string parseDisplayName(const pjsip_name_addr* sip_name_addr); +std::string parseDisplayName(const pjsip_from_hdr* header); +std::string parseDisplayName(const pjsip_contact_hdr* header); std::string getHostFromUri(const std::string& sipUri); diff --git a/src/sip/sipaccount.cpp b/src/sip/sipaccount.cpp index 0331e5821a269020d0cc5856e21eece464c66d01..83f7791e20bc77da1b99b4f1038fd5482b24196b 100644 --- a/src/sip/sipaccount.cpp +++ b/src/sip/sipaccount.cpp @@ -1355,7 +1355,10 @@ std::string SIPAccount::getFromUri() const hostname = IpAddr(hostname).toString(false, true); #endif - return "<" + scheme + username + "@" + hostname + transport + ">"; + const std::string uri = "<" + scheme + username + "@" + hostname + transport + ">"; + if (not displayName_.empty()) + return "\"" + displayName_ + "\" " + uri; + return uri; } std::string SIPAccount::getToUri(const std::string& username) const diff --git a/src/sip/sipvoiplink.cpp b/src/sip/sipvoiplink.cpp index 1953497cb9b82721f9707fd308c14662d3025cbb..347a682d1a05340b25eb612c4461bfaf9a745cba 100644 --- a/src/sip/sipvoiplink.cpp +++ b/src/sip/sipvoiplink.cpp @@ -194,14 +194,16 @@ transaction_request_cb(pjsip_rx_data *rdata) RING_ERR("Missing From, To or Via fields"); return PJ_FALSE; } - const pjsip_sip_uri *sip_to_uri = (pjsip_sip_uri *) pjsip_uri_get_uri(rdata->msg_info.to->uri); - const pjsip_sip_uri *sip_from_uri = (pjsip_sip_uri *) pjsip_uri_get_uri(rdata->msg_info.from->uri); + + const auto sip_to_uri = reinterpret_cast<pjsip_sip_uri*>(pjsip_uri_get_uri(rdata->msg_info.to->uri)); + const auto sip_from_uri = reinterpret_cast<pjsip_sip_uri*>(pjsip_uri_get_uri(rdata->msg_info.from->uri)); const pjsip_host_port& sip_via = rdata->msg_info.via->sent_by; if (!sip_to_uri or !sip_from_uri or !sip_via.host.ptr) { RING_ERR("NULL uri"); return PJ_FALSE; } + std::string toUsername(sip_to_uri->user.ptr, sip_to_uri->user.slen); std::string toHost(sip_to_uri->host.ptr, sip_to_uri->host.slen); std::string viaHostname(sip_via.host.ptr, sip_via.host.slen); @@ -225,7 +227,6 @@ transaction_request_cb(pjsip_rx_data *rdata) } const auto& account_id = account->getAccountID(); - auto peerDisplayName = sip_utils::parseDisplayName(rdata->msg_info.msg_buf); pjsip_msg_body *body = rdata->msg_info.msg->body; if (method->id == PJSIP_OTHER_METHOD) { @@ -286,7 +287,6 @@ transaction_request_cb(pjsip_rx_data *rdata) return PJ_FALSE; } - if (not remote_user.empty() and not remote_hostname.empty()) peerNumber = remote_user + "@" + remote_hostname; @@ -324,6 +324,16 @@ transaction_request_cb(pjsip_rx_data *rdata) /* fallback on local address */ if (not addrSdp) addrSdp = addrToUse; + // Try to obtain display name from From: header first, fallback on Contact: + auto peerDisplayName = sip_utils::parseDisplayName(rdata->msg_info.from); + if (peerDisplayName.empty()) { + if (auto hdr = static_cast<const pjsip_contact_hdr*>(pjsip_msg_find_hdr(rdata->msg_info.msg, + PJSIP_H_CONTACT, + nullptr))) { + peerDisplayName = sip_utils::parseDisplayName(hdr); + } + } + call->setState(Call::ConnectionState::PROGRESSING); call->setPeerNumber(peerNumber); call->setPeerDisplayName(peerDisplayName);