diff --git a/src/call.cpp b/src/call.cpp index 818caf9e261d7c6ee05a19b18a661d6636eae3ab..5dad17049d01c6ec625d93fe83778594ebbc9a04 100644 --- a/src/call.cpp +++ b/src/call.cpp @@ -84,7 +84,7 @@ Call::Call(Account& account, const std::string& id, Call::CallType type, , type_(type) , account_(account) { - setEarlyDetails(details); + updateDetails(details); addStateListener([this](UNUSED Call::CallState call_state, UNUSED Call::ConnectionState cnx_state, @@ -312,9 +312,9 @@ Call::toggleRecording() } void -Call::setEarlyDetails(const std::map<std::string, std::string>& details) +Call::updateDetails(const std::map<std::string, std::string>& details) { - auto iter = details.find(DRing::Call::Details::AUDIO_ONLY); + const auto& iter = details.find(DRing::Call::Details::AUDIO_ONLY); if (iter != std::end(details)) isAudioOnly_ = iter->second == TRUE_STR; } diff --git a/src/call.h b/src/call.h index 3194bf0f10ac3211fcb1bd83f53f9979a4934a0d..398ef83c2b452799c8990d2b16cf2546ee84a6a1 100644 --- a/src/call.h +++ b/src/call.h @@ -306,6 +306,15 @@ class Call : public Recordable, public std::enable_shared_from_this<Call> { virtual void restartMediaReceiver() = 0; + /** + * Update call details after creation. + * @param details to update + * + * /note No warranty to update any details, only some details can be modified. + * See the implementation for more ... details :-). + */ + void updateDetails(const std::map<std::string, std::string>& details); + protected: virtual void merge(Call& scall); @@ -339,8 +348,6 @@ class Call : public Recordable, public std::enable_shared_from_this<Call> { private: friend void hangupCallsIf(Call::SubcallSet, int, const std::function<bool(Call*)>&); - void setEarlyDetails(const std::map<std::string, std::string>& details); - bool validStateTransition(CallState newState); void checkPendingIM(); diff --git a/src/ringdht/ringaccount.cpp b/src/ringdht/ringaccount.cpp index 1f328cc331498b8b7067e114f13ae30c9264ab4f..88a21418187aec212d32f1245a4cb6187b054b83 100644 --- a/src/ringdht/ringaccount.cpp +++ b/src/ringdht/ringaccount.cpp @@ -304,12 +304,13 @@ RingAccount::flush() } std::shared_ptr<SIPCall> -RingAccount::newIncomingCall(const std::string& from) +RingAccount::newIncomingCall(const std::string& from, const std::map<std::string, std::string>& details) { std::lock_guard<std::mutex> lock(callsMutex_); auto call_it = pendingSipCalls_.begin(); while (call_it != pendingSipCalls_.end()) { auto call = call_it->call.lock(); + call->updateDetails(details); if (not call) { RING_WARN("newIncomingCall: discarding deleted call"); call_it = pendingSipCalls_.erase(call_it); diff --git a/src/ringdht/ringaccount.h b/src/ringdht/ringaccount.h index 7782ef9b2cae5900877a874fe53fe8115e564572..0bf67d84a81f43c0d56938b1d65111129a29999f 100644 --- a/src/ringdht/ringaccount.h +++ b/src/ringdht/ringaccount.h @@ -239,12 +239,13 @@ class RingAccount : public SIPAccountBase { /** * Create incoming SIPCall. * @param[in] from The origin of the call + * @param details use to set some specific details * @return std::shared_ptr<T> A shared pointer on the created call. * The type of this instance is given in template argument. * This type can be any base class of SIPCall class (included). */ virtual std::shared_ptr<SIPCall> - newIncomingCall(const std::string& from = {}) override; + newIncomingCall(const std::string& from, const std::map<std::string, std::string>& details = {}) override; virtual bool isTlsEnabled() const override { return true; diff --git a/src/sip/sipaccount.cpp b/src/sip/sipaccount.cpp index 6d11d8fcb0276ecf402c279048ebeec16991c31c..b388337fa2ce328f53b28ac05c5f8db31721d242 100644 --- a/src/sip/sipaccount.cpp +++ b/src/sip/sipaccount.cpp @@ -159,10 +159,13 @@ SIPAccount::~SIPAccount() } std::shared_ptr<SIPCall> -SIPAccount::newIncomingCall(const std::string& from UNUSED) +SIPAccount::newIncomingCall(const std::string& from UNUSED, const std::map<std::string, std::string>& details) { auto& manager = Manager::instance(); - return manager.callFactory.newCall<SIPCall, SIPAccount>(*this, manager.getNewCallID(), Call::CallType::INCOMING); + return manager.callFactory.newCall<SIPCall, SIPAccount>(*this, + manager.getNewCallID(), + Call::CallType::INCOMING, + details); } template <> diff --git a/src/sip/sipaccount.h b/src/sip/sipaccount.h index 8a6cecdb82d021f343f3ad90c5f53104cc1f0b0a..10f5f1d85602c08a937e29ef3f9256b2f77f0e2d 100644 --- a/src/sip/sipaccount.h +++ b/src/sip/sipaccount.h @@ -478,12 +478,13 @@ class SIPAccount : public SIPAccountBase { /** * Create incoming SIPCall. * @param[in] from The origin uri of the call + * @param details use to set some specific details * @return std::shared_ptr<T> A shared pointer on the created call. * The type of this instance is given in template argument. * This type can be any base class of SIPCall class (included). */ std::shared_ptr<SIPCall> - newIncomingCall(const std::string& from) override; + newIncomingCall(const std::string& from, const std::map<std::string, std::string>& details = {}) override; void onRegister(pjsip_regc_cbparam *param); diff --git a/src/sip/sipaccountbase.h b/src/sip/sipaccountbase.h index 67d5c4daf29feb5e2c828915d36873bbf754ae56..ed0302ea27eaf25b7738294810da356ffaed0d9b 100644 --- a/src/sip/sipaccountbase.h +++ b/src/sip/sipaccountbase.h @@ -126,12 +126,13 @@ public: /** * Create incoming SIPCall. * @param[in] id The ID of the call + * @param details use to set some specific details * @return std::shared_ptr<T> A shared pointer on the created call. * The type of this instance is given in template argument. * This type can be any base class of SIPCall class (included). */ virtual std::shared_ptr<SIPCall> - newIncomingCall(const std::string& from) = 0; + newIncomingCall(const std::string& from, const std::map<std::string, std::string>& details = {}) = 0; virtual bool isStunEnabled() const { return false; diff --git a/src/sip/sipvoiplink.cpp b/src/sip/sipvoiplink.cpp index 19a1ff03f1b07cfbc5baed644f37bd2579731ed7..d25b3a76276463e0da6e246abfb620157f4ec0f6 100644 --- a/src/sip/sipvoiplink.cpp +++ b/src/sip/sipvoiplink.cpp @@ -273,7 +273,17 @@ transaction_request_cb(pjsip_rx_data *rdata) Manager::instance().hookPreference.runHook(rdata->msg_info.msg); - auto call = account->newIncomingCall(remote_user); + bool hasVideo = false; + bool hasAudio = false; + auto pj_str_video = pj_str((char*) "video"); + auto pj_str_audio = pj_str((char*) "audio"); + for (decltype(r_sdp->media_count) i=0 ; i < r_sdp->media_count; i++) + if ( pj_strcmp(&r_sdp->media[i]->desc.media, &pj_str_video) == 0 ) + hasVideo = true; + else if ( pj_strcmp(&r_sdp->media[i]->desc.media, &pj_str_audio) == 0 ) + hasAudio = true; + + auto call = account->newIncomingCall(remote_user, {{"AUDIO_ONLY", ((not hasVideo and hasAudio) ? "true" : "false") }}); if (!call) { return PJ_FALSE; } @@ -333,7 +343,7 @@ transaction_request_cb(pjsip_rx_data *rdata) call->getSDP().receiveOffer(r_sdp, account->getActiveAccountCodecInfoList(MEDIA_AUDIO), - account->getActiveAccountCodecInfoList(account->isVideoEnabled() ? MEDIA_VIDEO : MEDIA_NONE), + account->getActiveAccountCodecInfoList(account->isVideoEnabled() and hasVideo ? MEDIA_VIDEO : MEDIA_NONE), account->getSrtpKeyExchange()); call->setRemoteSdp(r_sdp); @@ -434,7 +444,6 @@ transaction_request_cb(pjsip_rx_data *rdata) replacedCall->hangup(PJSIP_SC_OK); } - return PJ_FALSE; }