Ring Daemon
Loading...
Searching...
No Matches
call.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 2004-2026 Savoir-faire Linux Inc.
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17
18#pragma once
19
20#ifdef HAVE_CONFIG_H
21#include "config.h"
22#endif
23
24#include "conference.h"
25#include "media/recordable.h"
26#include "media/peerrecorder.h"
27#include "media/media_codec.h"
29
30#include <dhtnet/ip_utils.h>
31#include <asio/steady_timer.hpp>
32
33#include <mutex>
34#include <map>
35#include <memory>
36#include <vector>
37#include <set>
38#include <list>
39#include <functional>
40
41template<typename T>
42bool
43is_uninitialized(std::weak_ptr<T> const& weak)
44{
45 using wt = std::weak_ptr<T>;
46 return !weak.owner_before(wt {}) && !wt {}.owner_before(weak);
47}
48
49namespace jami {
50
51class VoIPLink;
52class Account;
53class AudioDeviceGuard;
54
55class Call;
56class Conference;
57
58using CallMap = std::map<std::string, std::shared_ptr<Call>>;
59
60namespace video {
61class VideoGenerator;
62}
63
64/*
65 * @file call.h
66 * @brief A call is the base class for protocol-based calls
67 */
68
69class Call : public Recordable, public PeerRecorder, public std::enable_shared_from_this<Call>
70{
71public:
83
90
91 enum class LinkType : uint8_t { GENERIC, SIP };
92
93 using SubcallSet = std::set<std::shared_ptr<Call>, std::owner_less<std::shared_ptr<Call>>>;
94 using OnReadyCb = std::function<void(bool)>;
95 using StateListenerCb = std::function<bool(CallState, ConnectionState, int)>;
96
102
103 virtual ~Call();
104
105 virtual LinkType getLinkType() const { return LinkType::GENERIC; }
106
111 const std::string& getCallId() const { return id_; }
112
117 std::shared_ptr<Conference> getConference() const { return conf_.lock(); }
119
120 std::weak_ptr<Account> getAccount() const { return account_; }
121 std::string getAccountId() const;
122
123 CallType getCallType() const { return type_; }
124
130 void setPeerNumber(const std::string& number) { peerNumber_ = number; }
131
137 const std::string& getPeerNumber() const { return peerNumber_; }
143 void setPeerDisplayName(const std::string& name) { peerDisplayName_ = name; }
144
150 const std::string& toUsername() const { return toUsername_; }
155 void toUsername(const std::string& username) { toUsername_ = username; }
156
162 const std::string& getPeerDisplayName() const { return peerDisplayName_; }
167 bool isIncoming() const { return type_ == CallType::INCOMING; }
168
175 bool setState(CallState call_state, signed code = 0);
176
184 bool setState(CallState call_state, ConnectionState cnx_state, signed code = 0);
185
192 bool setState(ConnectionState cnx_state, signed code = 0);
193
198 CallState getState() const;
199
205
206 std::string getStateStr() const;
207
209
210 virtual std::map<std::string, std::string> getDetails() const;
211
221 virtual void answer(const std::vector<libjami::MediaMap>& mediaList) = 0;
222
237 virtual bool checkMediaChangeRequest(const std::vector<libjami::MediaMap>& remoteMediaList) = 0;
238
244 virtual void handleMediaChangeRequest(const std::vector<libjami::MediaMap>& remoteMediaList) = 0;
245
257 virtual void answerMediaChangeRequest(const std::vector<libjami::MediaMap>& mediaList, bool isRemote = false) = 0;
262 virtual void hangup(int reason) = 0;
263
267 virtual void refuse() = 0;
268
273 virtual void transfer(const std::string& to) = 0;
274
280 virtual bool attendedTransfer(const std::string& to) = 0;
281
287 virtual bool hold(OnReadyCb&& cb) = 0;
288
294 virtual bool resume(OnReadyCb&& cb) = 0;
295
296 virtual void sendKeyframe(int streamIdx = -1) = 0;
297
301 virtual bool isIceEnabled() const = 0;
302
306 virtual void peerHungup();
307
311 virtual void removeCall(int code = 0);
312
317 virtual void updateRecState(bool state) = 0;
318
320 {
321 std::lock_guard lk {callMutex_};
322 stateChangedListeners_.emplace_back(std::move(listener));
323 }
324
329 void addSubCall(Call& call);
330
334 bool isSubcall() const
335 {
336 std::lock_guard lk {callMutex_};
337 return parent_ != nullptr;
338 }
339
343 std::chrono::milliseconds getCallDuration() const
344 {
345 return duration_start_ == time_point::min()
346 ? std::chrono::milliseconds::zero()
347 : std::chrono::duration_cast<std::chrono::milliseconds>(clock::now() - duration_start_);
348 }
349
350 // media management
351 virtual bool toggleRecording();
352
353 virtual std::vector<MediaAttribute> getMediaAttributeList() const = 0;
354
355 virtual std::map<std::string, bool> getAudioStreams() const = 0;
356
362 virtual std::map<std::string, bool> getRemoteAudioStreams() const = 0;
363
364#ifdef ENABLE_VIDEO
365 virtual void createSinks(ConfInfo& infos) = 0;
366#endif
367
368 virtual void switchInput(const std::string& = {}) {};
369
375 virtual void muteMedia(const std::string& mediaType, bool isMuted) = 0;
376
381 virtual void carryingDTMFdigits(char code) = 0;
382
388 virtual bool requestMediaChange(const std::vector<libjami::MediaMap>& mediaList) = 0;
389
394 virtual std::vector<libjami::MediaMap> currentMediaList() const = 0;
395
402 virtual void sendTextMessage(const std::map<std::string, std::string>& messages, const std::string& from) = 0;
403
404 void onTextMessage(std::map<std::string, std::string>&& messages);
405
406 virtual std::shared_ptr<SystemCodecInfo> getAudioCodec() const { return {}; }
407 virtual std::shared_ptr<SystemCodecInfo> getVideoCodec() const { return {}; }
408
409 virtual void restartMediaSender() = 0;
410
411 // Media status methods
412 virtual bool hasVideo() const = 0;
413 virtual bool isCaptureDeviceMuted(const MediaType& mediaType) const = 0;
414
420 void setConferenceInfo(const std::string& msg);
421
422 virtual void enterConference(std::shared_ptr<Conference> conference) = 0;
423 virtual void exitConference() = 0;
424
425 std::vector<std::map<std::string, std::string>> getConferenceInfos() const
426 {
428 }
429
430 std::unique_ptr<AudioDeviceGuard> audioGuard;
431 void sendConfOrder(const Json::Value& root);
432 void sendConfInfo(const std::string& json);
433 void resetConfInfo();
434
435 virtual void monitor() const = 0;
436
438
439protected:
440 using clock = std::chrono::steady_clock;
441 using time_point = clock::time_point;
442 virtual void merge(Call& scall);
443
449 Call(const std::shared_ptr<Account>& account, const std::string& id, Call::CallType type);
450
451 // TODO all these members are not protected against multi-thread access
452
453 const std::string id_ {};
454
456 mutable std::shared_ptr<Call> parent_;
457
460
461 using MsgList = std::list<std::pair<std::map<std::string, std::string>, std::string>>;
462
465
467 mutable std::recursive_mutex callMutex_ {};
468
469 mutable std::mutex confInfoMutex_ {};
470 mutable ConfInfo confInfo_ {};
471 time_point duration_start_ {time_point::min()};
472
473private:
474 bool validStateTransition(CallState newState);
475
476 void checkPendingIM();
477
478 void checkAudio();
479
480 void subcallStateChanged(Call&, Call::CallState, Call::ConnectionState, int code);
481
482 SubcallSet safePopSubcalls();
483
484 std::vector<StateListenerCb> stateChangedListeners_ {};
485
486protected:
488 std::weak_ptr<Conference> conf_ {};
489
492
494 std::weak_ptr<Account> account_;
495
498
501
502 std::string reason_ {};
503
505 bool isIPToIP_ {false};
506
508 std::string peerNumber_ {};
509
511 std::string peerDisplayName_ {};
512
514
517
520 std::string toUsername_ {};
521
522 asio::steady_timer timeoutTimer_;
523};
524
525// Helpers
526
530inline std::shared_ptr<Call>
532{
533 return call.shared_from_this();
534}
535
536} // namespace jami
bool is_uninitialized(std::weak_ptr< T > const &weak)
Definition call.h:43
std::string reason_
Definition call.h:502
virtual LinkType getLinkType() const
Definition call.h:105
asio::steady_timer timeoutTimer_
Definition call.h:522
int peerConfProtocol_
Supported conference protocol version.
Definition call.h:519
std::chrono::steady_clock clock
Definition call.h:440
virtual bool isIceEnabled() const =0
Check wether ICE is enabled for media.
void setPeerDisplayName(const std::string &name)
Set the display name (caller in ingoing) not protected by mutex (when created)
Definition call.h:143
void onTextMessage(std::map< std::string, std::string > &&messages)
Definition call.cpp:367
virtual void restartMediaSender()=0
MsgList pendingInMessages_
Definition call.h:516
virtual void switchInput(const std::string &={})
Definition call.h:368
virtual void exitConference()=0
const std::string & toUsername() const
Get "To" from the invite.
Definition call.h:150
virtual bool checkMediaChangeRequest(const std::vector< libjami::MediaMap > &remoteMediaList)=0
Check the media of an incoming media change request.
std::string peerNumber_
Number of the peer.
Definition call.h:508
const std::string & getCallId() const
Return a reference on the call id.
Definition call.h:111
virtual void carryingDTMFdigits(char code)=0
Send DTMF.
virtual void transfer(const std::string &to)=0
Transfer a call to specified URI.
virtual bool isCaptureDeviceMuted(const MediaType &mediaType) const =0
virtual bool requestMediaChange(const std::vector< libjami::MediaMap > &mediaList)=0
Make a change request of the current media with the provided media.
std::set< std::shared_ptr< Call >, std::owner_less< std::shared_ptr< Call > > > SubcallSet
Definition call.h:93
CallState getState() const
Get the call state of the call (protected by mutex)
Definition call.cpp:160
virtual void sendTextMessage(const std::map< std::string, std::string > &messages, const std::string &from)=0
Send a message to a call identified by its callid.
virtual void muteMedia(const std::string &mediaType, bool isMuted)=0
mute/unmute a media of a call
virtual void sendKeyframe(int streamIdx=-1)=0
std::function< void(bool)> OnReadyCb
Definition call.h:94
std::mutex confInfoMutex_
Definition call.h:469
void toUsername(const std::string &username)
Updated by sipvoiplink, corresponds to the "To" in the invite.
Definition call.h:155
virtual std::vector< libjami::MediaMap > currentMediaList() const =0
Retrieve current medias list.
virtual std::shared_ptr< SystemCodecInfo > getAudioCodec() const
Definition call.h:406
void addSubCall(Call &call)
Attach subcall to this instance.
Definition call.cpp:408
std::weak_ptr< Account > account_
Associate account ID.
Definition call.h:494
std::string getStateStr() const
Definition call.cpp:284
virtual void hangup(int reason)=0
Hang up the call.
virtual void monitor() const =0
ConnectionState
Tell where we're at with the call.
Definition call.h:82
clock::time_point time_point
Definition call.h:441
std::chrono::milliseconds getCallDuration() const
Definition call.h:343
virtual bool hold(OnReadyCb &&cb)=0
Hold call.
bool isConferenceParticipant() const
Definition call.h:118
ConnectionState getConnectionState() const
Get the connection state of the call (protected by mutex)
Definition call.cpp:153
CallType type_
Type of the call.
Definition call.h:491
std::shared_ptr< Conference > getConference() const
Return a reference on the conference id.
Definition call.h:117
void resetConfInfo()
Definition call.cpp:677
std::shared_ptr< Call > parent_
MultiDevice: list of attached subcall.
Definition call.h:456
bool isSubcall() const
Return true if this call instance is a subcall (internal call for multi-device handling)
Definition call.h:334
void sendConfOrder(const Json::Value &root)
Definition call.cpp:653
virtual void refuse()=0
Refuse incoming call.
virtual std::map< std::string, std::string > getDetails() const
Definition call.cpp:348
virtual void updateRecState(bool state)=0
Update recording state.
CallState
The Call State.
Definition call.h:89
bool isIncoming() const
Tell if the call is incoming.
Definition call.h:167
std::list< std::pair< std::map< std::string, std::string >, std::string > > MsgList
MultiDevice: message waiting to be sent (need a valid subcall)
Definition call.h:463
virtual void peerHungup()
Peer has hung up a call.
Definition call.cpp:400
virtual std::map< std::string, bool > getRemoteAudioStreams() const =0
Return a map of audio stream IDs to their remote (peer-side) muted state.
void setPeerNumber(const std::string &number)
Set the peer number (destination on outgoing) not protected by mutex (when created)
Definition call.h:130
virtual bool hasVideo() const =0
virtual void merge(Call &scall)
Replace current call data with ones from the given subcall.
Definition call.cpp:527
virtual void answer(const std::vector< libjami::MediaMap > &mediaList)=0
Answer a call with a list of media attributes.
virtual void removeCall(int code=0)
Definition call.cpp:130
std::string peerDisplayName_
Peer Display Name.
Definition call.h:511
ConfInfo confInfo_
Definition call.h:470
CallType getCallType() const
Definition call.h:123
std::weak_ptr< Conference > conf_
Unique conference ID, used exclusively in case of a conference.
Definition call.h:488
const std::string & getPeerNumber() const
Get the peer number (destination on outgoing) not protected by mutex (when created)
Definition call.h:137
void setIPToIP(bool IPToIP)
Definition call.h:208
SubcallSet subcalls_
Definition call.h:459
std::string getAccountId() const
Definition call.cpp:144
virtual std::shared_ptr< SystemCodecInfo > getVideoCodec() const
Definition call.h:407
CallType
This determines if the call originated from the local user (OUTGOING) or from some remote peer (INCOM...
Definition call.h:101
virtual bool toggleRecording()
This method must be implemented for this interface as calls and conferences have different behavior.
Definition call.cpp:341
MsgList pendingOutMessages_
Definition call.h:464
std::unique_ptr< AudioDeviceGuard > audioGuard
Definition call.h:430
void setConferenceInfo(const std::string &msg)
A Call can be in a conference.
Definition call.cpp:598
virtual void handleMediaChangeRequest(const std::vector< libjami::MediaMap > &remoteMediaList)=0
Process incoming media change request.
virtual std::vector< MediaAttribute > getMediaAttributeList() const =0
std::string toUsername_
Definition call.h:520
bool setState(CallState call_state, signed code=0)
Set the state of the call (protected by mutex)
Definition call.cpp:270
virtual bool resume(OnReadyCb &&cb)=0
Resume call from hold state.
const std::string id_
MultiDevice: parent call, nullptr otherwise. Access protected by callMutex_.
Definition call.h:453
CallState callState_
Inactive/Active/Hold/Busy/Error.
Definition call.h:500
ConnectionState connectionState_
Disconnected/Progressing/Trying/Ringing/Connected.
Definition call.h:497
const std::string & getPeerDisplayName() const
Get the peer display name (caller in ingoing) not protected by mutex (when created)
Definition call.h:162
virtual bool attendedTransfer(const std::string &to)=0
Attended transfer.
time_t timestamp_start_
MultiDevice: message received by subcall to merged yet.
Definition call.h:513
virtual void enterConference(std::shared_ptr< Conference > conference)=0
void sendConfInfo(const std::string &json)
Definition call.cpp:665
int conferenceProtocolVersion() const
Definition call.h:437
std::vector< std::map< std::string, std::string > > getConferenceInfos() const
Definition call.h:425
bool isIPToIP_
Direct IP-to-IP or classic call.
Definition call.h:505
std::weak_ptr< Account > getAccount() const
Definition call.h:120
virtual ~Call()
Definition call.cpp:127
virtual std::map< std::string, bool > getAudioStreams() const =0
virtual void answerMediaChangeRequest(const std::vector< libjami::MediaMap > &mediaList, bool isRemote=false)=0
Answer to a media update request.
time_point duration_start_
Definition call.h:471
void addStateListener(StateListenerCb &&listener)
Definition call.h:319
std::function< bool(CallState, ConnectionState, int)> StateListenerCb
Definition call.h:95
std::recursive_mutex callMutex_
Protect every attribute that can be changed by two threads.
Definition call.h:467
std::map< std::string, std::shared_ptr< Call > > CallMap
Definition call.h:58
void emitSignal(Args... args)
Definition jami_signal.h:64
std::shared_ptr< Call > getPtr(Call &call)
Obtain a shared smart pointer of instance.
Definition call.h:531
static bool is_uninitialized(std::weak_ptr< T > const &weak)
std::vector< std::map< std::string, std::string > > toVectorMapStringString() const