Ring Daemon 16.0.0
Loading...
Searching...
No Matches
account.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 2004-2025 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#pragma once
18
19#ifdef HAVE_CONFIG_H
20#include "config.h"
21#endif
22
23#include "client/ring_signal.h"
25#include "noncopyable.h"
26#include "config/serializable.h"
27#include "registration_states.h"
28#include "im/message_engine.h"
29#include "media/media_codec.h"
31#include "logger.h"
32#include "compiler_intrinsics.h" // include the "UNUSED" macro
33#include "call_set.h"
34#include "account_config.h"
35
36#include <dhtnet/ip_utils.h>
37#include <dhtnet/upnp/upnp_control.h>
38
39#include <functional>
40#include <string>
41#include <vector>
42#include <memory>
43#include <map>
44#include <set>
45#include <random>
46#include <stdexcept>
47#include <atomic>
48#include <mutex>
49#include <chrono>
50
51namespace Json {
52class Value;
53}
54
55namespace dht {
56namespace crypto {
57struct Certificate;
58}
59}
60
61namespace jami {
62static constexpr uint64_t JAMI_ID_MAX_VAL = 9007199254740992;
63constexpr static const char RINGDIR[] = "ringtones";
64
65class Call;
67
68class VoipLinkException : public std::runtime_error
69{
70public:
71 VoipLinkException(const std::string& str = "")
72 : std::runtime_error("VoipLinkException occurred: " + str)
73 {}
74};
75
83class Account : public std::enable_shared_from_this<Account>
84{
85public:
86 Account(const std::string& accountID);
87
91 virtual ~Account();
92
97 void hangupCalls();
98
99 virtual std::unique_ptr<AccountConfig> buildConfig() const = 0;
100
101 void setConfig(std::unique_ptr<AccountConfig>&& config)
102 {
103 std::lock_guard lock(configurationMutex_);
104 config_ = std::move(config);
105 loadConfig();
106 }
107
111 virtual void loadConfig();
112
113 const AccountConfig& config() const
114 {
115 if (config_)
116 return *config_;
117 else
118 throw std::runtime_error("Account doesn't have a configuration");
119 }
120
121 inline void editConfig(std::function<void(AccountConfig& config)>&& edit)
122 {
123 std::lock_guard lock(configurationMutex_);
124 edit(*config_);
125 saveConfig();
126 }
127
128 virtual void saveConfig() const;
129
130 void setAccountDetails(const std::map<std::string, std::string>& details)
131 {
132 std::lock_guard lock(configurationMutex_);
133 if (not config_)
135 config_->fromMap(details);
136 loadConfig();
137 saveConfig();
138 }
139
140 std::map<std::string, std::string> getAccountDetails() const
141 {
142 std::lock_guard lock(configurationMutex_);
143 return config().toMap();
144 }
145
146 virtual std::map<std::string, std::string> getVolatileAccountDetails() const;
147
148 virtual std::string getFromUri() const = 0;
149
154 inline const std::string& getAccountID() const { return accountID_; }
155
156 virtual std::string_view getAccountType() const = 0;
157
158 const std::filesystem::path& getPath() const { return idPath_; }
159
163 virtual bool isIP2IP() const { return false; }
164
169 virtual void doRegister() = 0;
170
175 virtual void doUnregister(bool forceShutdownConnections = false) = 0;
176
178
186 virtual std::shared_ptr<Call> newOutgoingCall(std::string_view toUrl,
187 const std::vector<libjami::MediaMap>& mediaList)
188 = 0;
189
194 virtual uint64_t sendTextMessage(const std::string& /*to*/,
195 const std::string& /*deviceId*/,
196 const std::map<std::string, std::string>& /*payloads*/,
197 uint64_t /*refreshToken*/ = 0,
198 bool /*onlyConnected*/ = false)
199 {
200 return 0;
201 }
202
203 virtual void setIsComposing(const std::string& /*conversationUri*/, bool /*isWriting*/) {};
204
205 virtual bool setMessageDisplayed(const std::string& /*conversationUri*/,
206 const std::string& /*messageId*/,
207 int /*status*/)
208 {
209 return false;
210 };
211
212 virtual std::vector<libjami::Message> getLastMessages(const uint64_t& /*base_timestamp*/)
213 {
214 return {};
215 }
216
217 virtual std::map<std::string, std::string> getNearbyPeers() const { return {}; }
218
219 virtual void updateProfile(const std::string& /*displayName*/, const std::string& /*avatar*/, const std::string& /*fileType*/, int32_t /*flag*/) = 0;
220
221 std::map<std::string, std::string> getProfileVcard() const;
222
227 {
229 }
230
231 virtual bool cancelMessage(uint64_t /*id*/) { return false; }
232
233 virtual bool setPushNotificationToken(const std::string& pushDeviceToken = "")
234 {
235 std::lock_guard lock(configurationMutex_);
236 if (config_ && config_->deviceKey != pushDeviceToken) {
237 config_->deviceKey = pushDeviceToken;
238 saveConfig();
239 return true;
240 }
241 return false;
242 }
243
244 virtual bool setPushNotificationTopic(const std::string& topic = "")
245 {
246 std::lock_guard lock(configurationMutex_);
247 if (config_ && config_->notificationTopic != topic) {
248 config_->notificationTopic = topic;
249 saveConfig();
250 return true;
251 }
252 return false;
253 }
254
255 virtual bool setPushNotificationConfig(const std::map<std::string, std::string>& data);
256
261 bool isEnabled() const { return config().enabled; }
262
263 void setEnabled(bool enable)
264 {
265 config_->enabled = enable;
266 // Update the UPnP controller to make sure it's in the correct state since this
267 // depends on whether the account is enabled or not (in particular, we don't want
268 // disabled accounts to generate UPnP activity).
270 }
271
276 bool isActive() const noexcept { return active_; }
277
278 void setActive(bool active) noexcept { active_ = active; }
279
280 bool isUsable() const { return config().enabled and active_; }
281
282 void enableVideo(bool enable)
283 {
285 }
286 bool isVideoEnabled() const { return config().videoEnabled; }
287
292 virtual void setRegistrationState(RegistrationState state,
293 int detail_code = 0,
294 const std::string& detail_str = {});
295
296 const std::string& getUsername() const { return config().username; }
297 const std::string& getHostname() const { return config().hostname; }
298 const std::string& getAlias() const { return config().alias; }
299
300 static std::vector<unsigned> getDefaultCodecsId();
301 static std::map<std::string, std::string> getDefaultCodecDetails(const unsigned& codecId);
302
303 /* Accessor to data structures
304 * @return The list that reflects the user's choice
305 */
306 std::vector<unsigned> getActiveCodecs(MediaType mediaType = MEDIA_ALL) const;
307 bool hasActiveCodec(MediaType mediaType) const;
308
313 virtual void setActiveCodecs(const std::vector<unsigned>& list);
314 std::shared_ptr<SystemCodecInfo> searchCodecById(unsigned codecId, MediaType mediaType);
315 std::vector<std::shared_ptr<SystemCodecInfo>> getActiveAccountCodecInfoList(
316 MediaType mediaType) const;
317 std::shared_ptr<SystemCodecInfo> searchCodecByPayload(unsigned payload, MediaType mediaType);
318
319 std::filesystem::path getRingtonePath() const { return ringtonePath_; }
320 bool getRingtoneEnabled() const { return config().ringtoneEnabled; }
321 std::string getDisplayName() const { return config().displayName; }
322 std::string getMailBox() const { return config().mailbox; }
323
324 bool isRendezVous() const { return config().isRendezVous; }
327 {
329 }
330 bool isReadReceiptEnabled() const { return config().sendReadReceipt; }
331 bool isComposingEnabled() const { return config().sendComposing; }
332
337 bool getUPnPActive() const;
338
343 dhtnet::IpAddr getUPnPIpAddress() const;
344
349 mutable std::mt19937_64 rand;
350
354 virtual void connectivityChanged() {};
355
356 virtual bool handleMessage(const std::shared_ptr<dht::crypto::Certificate>& /*cert*/,
357 const std::string& /*from*/,
358 const std::pair<std::string, std::string>& /*message*/)
359 {
360 return false;
361 };
362
366 void loadDefaultCodecs();
367
368 void setCodecActive(unsigned codecId);
369
370 void setCodecInactive(unsigned codecId);
371
375 const std::string& getUserAgentName();
376
377 std::set<std::string> getDefaultModerators() const { return config().defaultModerators; }
378
379 void addDefaultModerator(const std::string& peerURI);
380 void removeDefaultModerator(const std::string& peerURI);
381
383 bool isAllModerators() const { return config().allModeratorsEnabled; }
384
385 // Enable/disable ICE for media
387 void enableIceForMedia(bool enable) { iceForMediaEnabled_ = enable; }
388
389 // Enable/disable generation of empty offers
390 bool isEmptyOffersEnabled() const { return false; }
391
392 // Check if a Daemon version (typically peer's version) satisfies the
393 // minimum required version. This check is typically used to disable a
394 // feature if it's not backward compatible with the peer's version.
395 static bool meetMinimumRequiredVersion(const std::vector<unsigned>& jamiVersion,
396 const std::vector<unsigned>& minRequiredVersion);
397
398 // Enable/disable compliancy with RFC-5245 for component IDs format.
399 // The ICE component IDs are enumerated relative to the SDP session,
400 // i.e., starts from 1 and incremented for each component.
401 // However, RFC-5245 requires that the ICE component IDs are enumerated
402 // relative to the media stream, e.g., component IDs 1 and 2 for audio,
403 // and component IDs 1 and 2 for video. This non-conformity can cause
404 // inter-operability issues.
405 // When the compliancy feature is enabled, the component ID in the
406 // generated SDP will be compliant to RFC-5245. This feature should be
407 // enabled only when the peer is compliant to RFC-5245 as well.
408 // The current version is able to correctly parse both formats.
409 // This feature is needed for backward compatiblity, and should be removed
410 // once the backward compatibility is no more required.
414
415 std::shared_ptr<Call> getCall(const std::string& callId) const
416 {
417 return callSet_.getCall(callId);
418 }
419 std::vector<std::string> getCallList() const { return callSet_.getCallIds(); }
420 std::shared_ptr<Conference> getConference(const std::string& confId) const
421 {
422 return callSet_.getConference(confId);
423 }
424 std::vector<std::string> getConferenceList() const { return callSet_.getConferenceIds(); }
425 void attach(const std::shared_ptr<Call>& call) { callSet_.add(call); }
426 bool detach(const std::shared_ptr<Call>& call) { return callSet_.remove(call); }
427 void attach(const std::shared_ptr<Conference>& conf) { callSet_.add(conf); }
428 bool removeConference(const std::string& confId)
429 {
430 auto result = callSet_.removeConference(confId);
431 if (result)
433 return result;
434 }
435
436public:
437 // virtual methods that has to be implemented by concrete classes
442 virtual void flush() {/* nothing to do here - overload */};
443
444private:
446
450 CallSet callSet_;
451
452protected:
453 virtual void updateUpnpController();
454
455 std::unique_ptr<AccountConfig> config_ {};
456
457 friend class ConfigurationTest;
458
459 static const std::string DEFAULT_USER_AGENT;
460
461 static std::string mapStateNumberToString(RegistrationState state);
462
466 static std::string getDefaultUserAgent();
467
471 const std::string accountID_;
472
473 mutable std::recursive_mutex configurationMutex_ {};
474
480 bool active_ {true};
481
482 /*
483 * The general, protocol neutral registration
484 * state of the account
485 */
487
491 std::shared_ptr<SystemCodecContainer> systemCodecContainer_;
495 std::vector<std::shared_ptr<SystemCodecInfo>> accountCodecInfoList_;
496
500 std::filesystem::path idPath_ {};
501
505 std::filesystem::path ringtonePath_;
506
510 mutable std::mutex upnp_mtx {};
511 std::shared_ptr<dhtnet::upnp::Controller> upnpCtrl_;
512
519
523 std::shared_ptr<SystemCodecInfo> searchCodecByName(const std::string& name, MediaType mediaType);
524 std::vector<unsigned> getAccountCodecInfoIdList(MediaType mediaType) const;
525 void setAllCodecsActive(MediaType mediaType, bool active);
526 void sortCodec();
527};
528
529static inline std::ostream&
530operator<<(std::ostream& os, const Account& acc)
531{
532 os << "[Account " << acc.getAccountID() << "] ";
533 return os;
534}
535
536} // namespace jami
virtual std::string getFromUri() const =0
virtual ~Account()
Virtual destructor.
Definition account.cpp:79
std::string getDisplayName() const
Definition account.h:321
bool isEnabled() const
Tell if the account is enable or not.
Definition account.h:261
RegistrationState getRegistrationState() const
Definition account.h:177
bool iceCompIdRfc5245Compliant_
Definition account.h:514
void enableIceCompIdRfc5245Compliance(bool enable)
Definition account.h:412
virtual bool setPushNotificationConfig(const std::map< std::string, std::string > &data)
Definition account.cpp:466
bool hasActiveCodec(MediaType mediaType) const
Definition account.cpp:200
virtual void flush()
This method is called to request removal of possible account traces on the system,...
Definition account.h:442
bool removeConference(const std::string &confId)
Definition account.h:428
friend class ConfigurationTest
Definition account.h:457
virtual void doRegister()=0
Register the account.
virtual void setIsComposing(const std::string &, bool)
Definition account.h:203
virtual void updateUpnpController()
Definition account.cpp:89
void loadDefaultCodecs()
Helper function used to load the default codec order from the codec factory.
Definition account.cpp:131
std::shared_ptr< SystemCodecInfo > searchCodecById(unsigned codecId, MediaType mediaType)
Definition account.cpp:317
void enableIceForMedia(bool enable)
Definition account.h:387
static std::vector< unsigned > getDefaultCodecsId()
Definition account.cpp:264
std::vector< std::shared_ptr< SystemCodecInfo > > accountCodecInfoList_
Vector containing all account codecs (set of system codecs with custom parameters)
Definition account.h:495
const std::string & getAccountID() const
Get the account ID.
Definition account.h:154
virtual std::string_view getAccountType() const =0
void setCodecInactive(unsigned codecId)
Definition account.cpp:405
void attach(const std::shared_ptr< Conference > &conf)
Definition account.h:427
virtual void setRegistrationState(RegistrationState state, int detail_code=0, const std::string &detail_str={})
Set the registration state of the specified link.
Definition account.cpp:108
bool isReadReceiptEnabled() const
Definition account.h:330
std::vector< unsigned > getActiveCodecs(MediaType mediaType=MEDIA_ALL) const
Definition account.cpp:356
virtual void updateProfile(const std::string &, const std::string &, const std::string &, int32_t)=0
void setEnabled(bool enable)
Definition account.h:263
std::vector< std::string > getConferenceList() const
Definition account.h:424
static std::string getDefaultUserAgent()
Build the user-agent string.
Definition account.cpp:435
virtual void setActiveCodecs(const std::vector< unsigned > &list)
Update both the codec order structure and the codec string used for SDP offer and configuration respe...
Definition account.cpp:209
const std::string accountID_
Account ID are assign in constructor and shall not changed.
Definition account.h:471
virtual void connectivityChanged()
Inform the account that the network status has changed.
Definition account.h:354
static bool meetMinimumRequiredVersion(const std::vector< unsigned > &jamiVersion, const std::vector< unsigned > &minRequiredVersion)
Definition account.cpp:453
std::shared_ptr< SystemCodecInfo > searchCodecByName(const std::string &name, MediaType mediaType)
private account codec searching functions
Definition account.cpp:330
bool isRendezVous() const
Definition account.h:324
RegistrationState registrationState_
Definition account.h:486
std::mt19937_64 rand
Random generator engine Logical account state shall never rely on the state of the random generator.
Definition account.h:349
void setActive(bool active) noexcept
Definition account.h:278
virtual bool cancelMessage(uint64_t)
Definition account.h:231
virtual std::map< std::string, std::string > getNearbyPeers() const
Definition account.h:217
virtual void doUnregister(bool forceShutdownConnections=false)=0
Unregister the account.
bool isAllModerators() const
Definition account.h:383
void enableVideo(bool enable)
Definition account.h:282
const std::string & getUsername() const
Definition account.h:296
std::map< std::string, std::string > getAccountDetails() const
Definition account.h:140
bool isIceCompIdRfc5245Compliant() const
Definition account.h:411
std::filesystem::path idPath_
path to account
Definition account.h:500
bool detach(const std::shared_ptr< Call > &call)
Definition account.h:426
bool isEmptyOffersEnabled() const
Definition account.h:390
bool isUsable() const
Definition account.h:280
std::shared_ptr< SystemCodecContainer > systemCodecContainer_
Vector containing all system codecs (with default parameters)
Definition account.h:491
std::filesystem::path getRingtonePath() const
Definition account.h:319
std::shared_ptr< Call > getCall(const std::string &callId) const
Definition account.h:415
bool isComposingEnabled() const
Definition account.h:331
void addDefaultModerator(const std::string &peerURI)
Definition account.cpp:441
bool isActive() const noexcept
Tell if the account is activated (can currently be used).
Definition account.h:276
static std::string mapStateNumberToString(RegistrationState state)
Definition account.cpp:238
virtual std::map< std::string, std::string > getVolatileAccountDetails() const
Definition account.cpp:179
std::vector< std::shared_ptr< SystemCodecInfo > > getActiveAccountCodecInfoList(MediaType mediaType) const
Definition account.cpp:414
std::shared_ptr< Conference > getConference(const std::string &confId) const
Definition account.h:420
std::vector< unsigned > getAccountCodecInfoIdList(MediaType mediaType) const
Definition account.cpp:370
std::mutex upnp_mtx
UPnP IGD controller and the mutex to access it.
Definition account.h:510
bool iceForMediaEnabled_
Definition account.h:513
void removeDefaultModerator(const std::string &peerURI)
Definition account.cpp:447
virtual im::MessageStatus getMessageStatus(uint64_t) const
Return the status corresponding to the token.
Definition account.h:226
virtual std::vector< libjami::Message > getLastMessages(const uint64_t &)
Definition account.h:212
static const std::string DEFAULT_USER_AGENT
Definition account.h:459
std::map< std::string, std::string > getProfileVcard() const
Definition account.cpp:186
std::unique_ptr< AccountConfig > config_
Definition account.h:455
bool isIceForMediaEnabled() const
Definition account.h:386
dhtnet::IpAddr getUPnPIpAddress() const
Get the UPnP IP (external router) address.
Definition account.cpp:291
std::recursive_mutex configurationMutex_
Definition account.h:473
std::string getMailBox() const
Definition account.h:322
virtual std::unique_ptr< AccountConfig > buildConfig() const =0
const std::filesystem::path & getPath() const
Definition account.h:158
virtual bool isIP2IP() const
Returns true if this is the IP2IP account.
Definition account.h:163
bool autoLoadConversations_
Auto load conversations when creatinf convModule()
Definition account.h:518
std::set< std::string > getDefaultModerators() const
Definition account.h:377
bool isLocalModeratorsEnabled() const
Definition account.h:382
bool getRingtoneEnabled() const
Definition account.h:320
virtual bool handleMessage(const std::shared_ptr< dht::crypto::Certificate > &, const std::string &, const std::pair< std::string, std::string > &)
Definition account.h:356
const std::string & getUserAgentName()
Get the user-agent.
Definition account.cpp:429
virtual bool setMessageDisplayed(const std::string &, const std::string &, int)
Definition account.h:205
void editConfig(std::function< void(AccountConfig &config)> &&edit)
Definition account.h:121
virtual bool setPushNotificationTopic(const std::string &topic="")
Definition account.h:244
bool isAutoAnswerEnabled() const
Definition account.h:325
void setConfig(std::unique_ptr< AccountConfig > &&config)
Definition account.h:101
const std::string & getAlias() const
Definition account.h:298
void setCodecActive(unsigned codecId)
Definition account.cpp:396
void enableAutoLoadConversations(bool enable)
Definition account.h:413
void hangupCalls()
Free all ressources related to this account.
Definition account.cpp:82
bool getUPnPActive() const
returns whether or not UPnP is enabled and active ie: if it is able to make port mappings
Definition account.cpp:304
const AccountConfig & config() const
Definition account.h:113
std::shared_ptr< SystemCodecInfo > searchCodecByPayload(unsigned payload, MediaType mediaType)
Definition account.cpp:343
std::vector< std::string > getCallList() const
Definition account.h:419
virtual std::shared_ptr< Call > newOutgoingCall(std::string_view toUrl, const std::vector< libjami::MediaMap > &mediaList)=0
Create a new outgoing call.
bool active_
Tells if the account is active now.
Definition account.h:480
bool isVideoEnabled() const
Definition account.h:286
virtual uint64_t sendTextMessage(const std::string &, const std::string &, const std::map< std::string, std::string > &, uint64_t=0, bool=false)
If supported, send a text message from this account.
Definition account.h:194
std::filesystem::path ringtonePath_
Ringtone .au file used for this account.
Definition account.h:505
void attach(const std::shared_ptr< Call > &call)
Definition account.h:425
static std::map< std::string, std::string > getDefaultCodecDetails(const unsigned &codecId)
Definition account.cpp:270
void setAllCodecsActive(MediaType mediaType, bool active)
Definition account.cpp:385
virtual void saveConfig() const
Definition account.cpp:173
virtual bool setPushNotificationToken(const std::string &pushDeviceToken="")
Definition account.h:233
bool isDenySecondCallEnabled() const
Definition account.h:326
const std::string & getHostname() const
Definition account.h:297
virtual void loadConfig()
Load the settings in this account.
Definition account.cpp:155
std::shared_ptr< dhtnet::upnp::Controller > upnpCtrl_
Definition account.h:511
void setAccountDetails(const std::map< std::string, std::string > &details)
Definition account.h:130
void sortCodec()
Definition account.cpp:229
bool remove(const std::shared_ptr< Call > &call)
Definition call_set.h:55
std::vector< std::string > getCallIds() const
Definition call_set.h:66
void add(const std::shared_ptr< Call > &call)
Definition call_set.h:45
std::vector< std::string > getConferenceIds() const
Definition call_set.h:86
std::shared_ptr< Conference > getConference(const std::string &conferenceId) const
Definition call_set.h:38
bool removeConference(const std::string &confId)
Definition call_set.h:60
std::shared_ptr< Call > getCall(const std::string &callId) const
Definition call_set.h:32
VoipLinkException(const std::string &str="")
Definition account.h:71
Definition account.h:51
Definition account.h:55
RegistrationState
Contains all the Registration states for an account can be in.
void emitSignal(Args... args)
Definition ring_signal.h:64
static constexpr const char RINGDIR[]
Definition account.h:63
@ MEDIA_ALL
Definition media_codec.h:49
static constexpr uint64_t JAMI_ID_MAX_VAL
Definition account.h:62
static std::ostream & operator<<(std::ostream &os, const Account &acc)
Definition account.h:530
Simple macro to hide class' copy constructor and assignment operator.
#define NON_COPYABLE(ClassName)
Definition noncopyable.h:30
bool ringtoneEnabled
Play ringtone when receiving a call.
bool enabled
True if the account is enabled.
std::string alias
A user-defined name for this account.
std::string hostname
SIP hostname (SIP account) or DHT bootstrap nodes (Jami account)
bool autoAnswerEnabled
If true, automatically answer calls to this account.
std::set< std::string > defaultModerators
bool denySecondCallEnabled
If true, automatically deny new calls when already in one call to this account.
virtual std::map< std::string, std::string > toMap() const
std::string mailbox
Account mail box.
bool sendReadReceipt
If true, send displayed status (and emit to the client)
bool isRendezVous
If true mix calls into a conference.
std::string displayName
Display name when calling.
bool videoEnabled
Allows user to temporarily disable video calling.
bool sendComposing
If true, send composing status (and emit to the client)