Ring Daemon
Loading...
Searching...
No Matches
account.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#pragma once
18
19#ifdef HAVE_CONFIG_H
20#include "config.h"
21#endif
22
23#include "client/jami_signal.h"
25#include "noncopyable.h"
26#include "registration_states.h"
27#include "im/message_engine.h"
28#include "media/media_codec.h"
29#include "call_set.h"
30#include "account_config.h"
31#include "vcard.h"
32
33#include <dhtnet/ip_utils.h>
34#include <dhtnet/upnp/upnp_control.h>
35
36#include <functional>
37#include <string>
38#include <vector>
39#include <memory>
40#include <map>
41#include <set>
42#include <random>
43#include <stdexcept>
44#include <mutex>
45
46namespace Json {
47class Value;
48}
49
50namespace dht {
51namespace crypto {
52struct Certificate;
53}
54} // namespace dht
55
56namespace jami {
57static constexpr uint64_t JAMI_ID_MAX_VAL = 9007199254740992;
58constexpr static const char RINGDIR[] = "ringtones";
59
60class Call;
62
63class VoipLinkException : public std::runtime_error
64{
65public:
66 VoipLinkException(const std::string& str = "")
67 : std::runtime_error("VoipLinkException occurred: " + str)
68 {}
69};
70
78class Account : public std::enable_shared_from_this<Account>
79{
80public:
81 Account(const std::string& accountID);
82
86 virtual ~Account();
87
92 void hangupCalls();
93
94 virtual std::unique_ptr<AccountConfig> buildConfig() const = 0;
95
96 void setConfig(std::unique_ptr<AccountConfig>&& config)
97 {
98 std::lock_guard lock(configurationMutex_);
99 config_ = std::move(config);
100 loadConfig();
101 }
102
106 virtual void loadConfig();
107
108 const AccountConfig& config() const
109 {
110 if (config_)
111 return *config_;
112 else
113 throw std::runtime_error("Account doesn't have a configuration");
114 }
115
116 inline void editConfig(std::function<void(AccountConfig& config)>&& edit)
117 {
118 std::lock_guard lock(configurationMutex_);
119 edit(*config_);
120 saveConfig();
121 }
122
123 virtual void saveConfig() const;
124
125 void setAccountDetails(const std::map<std::string, std::string>& details)
126 {
127 std::lock_guard lock(configurationMutex_);
128 if (not config_)
130 config_->fromMap(details);
131 loadConfig();
132 saveConfig();
133 }
134
135 std::map<std::string, std::string> getAccountDetails() const
136 {
137 std::lock_guard lock(configurationMutex_);
138 return config().toMap();
139 }
140
141 virtual std::map<std::string, std::string> getVolatileAccountDetails() const;
142
143 virtual std::string getFromUri() const = 0;
144
149 inline const std::string& getAccountID() const { return accountID_; }
150
151 virtual std::string_view getAccountType() const = 0;
152
153 const std::filesystem::path& getPath() const { return idPath_; }
154
158 virtual bool isIP2IP() const { return false; }
159
164 virtual void doRegister() = 0;
165
170 virtual void doUnregister(bool forceShutdownConnections = false) = 0;
171
173
181 virtual std::shared_ptr<Call> newOutgoingCall(std::string_view toUrl,
182 const std::vector<libjami::MediaMap>& mediaList)
183 = 0;
184
189 virtual uint64_t sendTextMessage(const std::string& /*to*/,
190 const std::string& /*deviceId*/,
191 const std::map<std::string, std::string>& /*payloads*/,
192 uint64_t /*refreshToken*/ = 0,
193 bool /*onlyConnected*/ = false)
194 {
195 return 0;
196 }
197
198 virtual void setIsComposing(const std::string& /*conversationUri*/, bool /*isWriting*/) {};
199
200 virtual bool setMessageDisplayed(const std::string& /*conversationUri*/,
201 const std::string& /*messageId*/,
202 int /*status*/)
203 {
204 return false;
205 };
206
207 virtual std::vector<libjami::Message> getLastMessages(const uint64_t& /*base_timestamp*/) { return {}; }
208
209 virtual std::map<std::string, std::string> getNearbyPeers() const { return {}; }
210
211 virtual void updateProfile(const std::string& /*displayName*/,
212 const std::string& /*avatar*/,
213 const std::string& /*fileType*/,
214 int32_t /*flag*/)
215 = 0;
216
218
223
224 virtual bool setPushNotificationToken(const std::string& pushDeviceToken = "")
225 {
226 std::lock_guard lock(configurationMutex_);
227 if (config_ && config_->deviceKey != pushDeviceToken) {
228 config_->deviceKey = pushDeviceToken;
229 saveConfig();
230 return true;
231 }
232 return false;
233 }
234
235 virtual bool setPushNotificationTopic(const std::string& topic = "")
236 {
237 std::lock_guard lock(configurationMutex_);
238 if (config_ && config_->notificationTopic != topic) {
239 config_->notificationTopic = topic;
240 saveConfig();
241 return true;
242 }
243 return false;
244 }
245
246 virtual bool setPushNotificationConfig(const std::map<std::string, std::string>& data);
247
252 bool isEnabled() const { return config().enabled; }
253
254 void setEnabled(bool enable)
255 {
256 config_->enabled = enable;
257 // Update the UPnP controller to make sure it's in the correct state since this
258 // depends on whether the account is enabled or not (in particular, we don't want
259 // disabled accounts to generate UPnP activity).
261 }
262
267 bool isActive() const noexcept { return active_; }
268
269 void setActive(bool active) noexcept { active_ = active; }
270
271 bool isUsable() const { return config().enabled and active_; }
272
273 void enableVideo(bool enable)
274 {
276 }
277 bool isVideoEnabled() const { return config().videoEnabled; }
278
283 virtual void setRegistrationState(RegistrationState state, int detail_code = 0, const std::string& detail_str = {});
284
285 const std::string& getUsername() const { return config().username; }
286 const std::string& getHostname() const { return config().hostname; }
287 const std::string& getAlias() const { return config().alias; }
288
289 static std::vector<unsigned> getDefaultCodecsId();
290 static std::map<std::string, std::string> getDefaultCodecDetails(const unsigned& codecId);
291
292 /* Accessor to data structures
293 * @return The list that reflects the user's choice
294 */
295 std::vector<unsigned> getActiveCodecs(MediaType mediaType = MEDIA_ALL) const;
296 bool hasActiveCodec(MediaType mediaType) const;
297
302 virtual void setActiveCodecs(const std::vector<unsigned>& list);
303 std::shared_ptr<SystemCodecInfo> searchCodecById(unsigned codecId, MediaType mediaType);
304 std::vector<std::shared_ptr<SystemCodecInfo>> getActiveAccountCodecInfoList(MediaType mediaType) const;
305 std::shared_ptr<SystemCodecInfo> searchCodecByPayload(unsigned payload, MediaType mediaType);
306
307 std::filesystem::path getRingtonePath() const { return ringtonePath_; }
308 bool getRingtoneEnabled() const { return config().ringtoneEnabled; }
309 std::string getDisplayName() const { return config().displayName; }
310 std::string getMailBox() const { return config().mailbox; }
311
312 bool isRendezVous() const { return config().isRendezVous; }
315 bool isReadReceiptEnabled() const { return config().sendReadReceipt; }
316 bool isComposingEnabled() const { return config().sendComposing; }
317
322 bool getUPnPActive() const;
323
328 dhtnet::IpAddr getUPnPIpAddress() const;
329
334 mutable std::mt19937_64 rand;
335
339 virtual void connectivityChanged() {};
340
341 virtual bool handleMessage(const std::shared_ptr<dht::crypto::Certificate>& /*cert*/,
342 const std::string& /*from*/,
343 const std::pair<std::string, std::string>& /*message*/)
344 {
345 return false;
346 };
347
351 void loadDefaultCodecs();
352
353 void setCodecActive(unsigned codecId);
354
355 void setCodecInactive(unsigned codecId);
356
360 const std::string& getUserAgentName();
361
362 std::set<std::string> getDefaultModerators() const { return config().defaultModerators; }
363
364 void addDefaultModerator(const std::string& peerURI);
365 void removeDefaultModerator(const std::string& peerURI);
366
368 bool isAllModerators() const { return config().allModeratorsEnabled; }
369
370 // Enable/disable ICE for media
372 void enableIceForMedia(bool enable) { iceForMediaEnabled_ = enable; }
373
374 // Enable/disable generation of empty offers
375 bool isEmptyOffersEnabled() const { return false; }
376
377 // Check if a Daemon version (typically peer's version) satisfies the
378 // minimum required version. This check is typically used to disable a
379 // feature if it's not backward compatible with the peer's version.
380 static bool meetMinimumRequiredVersion(const std::vector<unsigned>& jamiVersion,
381 const std::vector<unsigned>& minRequiredVersion);
382
383 // Enable/disable compliancy with RFC-5245 for component IDs format.
384 // The ICE component IDs are enumerated relative to the SDP session,
385 // i.e., starts from 1 and incremented for each component.
386 // However, RFC-5245 requires that the ICE component IDs are enumerated
387 // relative to the media stream, e.g., component IDs 1 and 2 for audio,
388 // and component IDs 1 and 2 for video. This non-conformity can cause
389 // inter-operability issues.
390 // When the compliancy feature is enabled, the component ID in the
391 // generated SDP will be compliant to RFC-5245. This feature should be
392 // enabled only when the peer is compliant to RFC-5245 as well.
393 // The current version is able to correctly parse both formats.
394 // This feature is needed for backward compatiblity, and should be removed
395 // once the backward compatibility is no more required.
399
400 std::shared_ptr<Call> getCall(const std::string& callId) const { return callSet_.getCall(callId); }
401 std::vector<std::string> getCallList() const { return callSet_.getCallIds(); }
402 std::shared_ptr<Conference> getConference(const std::string& confId) const
403 {
404 return callSet_.getConference(confId);
405 }
406 std::vector<std::string> getConferenceList() const { return callSet_.getConferenceIds(); }
407 void attach(const std::shared_ptr<Call>& call) { callSet_.add(call); }
408 bool detach(const std::shared_ptr<Call>& call) { return callSet_.remove(call); }
409 void attach(const std::shared_ptr<Conference>& conf) { callSet_.add(conf); }
410 bool removeConference(const std::string& confId)
411 {
412 auto result = callSet_.removeConference(confId);
413 if (result)
415 return result;
416 }
417
418public:
419 // virtual methods that has to be implemented by concrete classes
424 virtual void flush() { /* nothing to do here - overload */ };
425
426private:
428
432 CallSet callSet_;
433
434protected:
435 virtual void updateUpnpController();
436
437 std::unique_ptr<AccountConfig> config_ {};
438
439 friend class ConfigurationTest;
440
441 static const std::string DEFAULT_USER_AGENT;
442
443 static std::string mapStateNumberToString(RegistrationState state);
444
448 static std::string getDefaultUserAgent();
449
453 const std::string accountID_;
454
455 mutable std::recursive_mutex configurationMutex_ {};
456
462 bool active_ {true};
463
464 /*
465 * The general, protocol neutral registration
466 * state of the account
467 */
469
473 std::shared_ptr<SystemCodecContainer> systemCodecContainer_;
477 std::vector<std::shared_ptr<SystemCodecInfo>> accountCodecInfoList_;
478
482 std::filesystem::path idPath_ {};
483
487 std::filesystem::path ringtonePath_;
488
492 mutable std::mutex upnp_mtx {};
493 std::shared_ptr<dhtnet::upnp::Controller> upnpCtrl_;
494
501
505 std::shared_ptr<SystemCodecInfo> searchCodecByName(const std::string& name, MediaType mediaType);
506 std::vector<unsigned> getAccountCodecInfoIdList(MediaType mediaType) const;
507 void setAllCodecsActive(MediaType mediaType, bool active);
508 void sortCodec();
509};
510
511static inline std::ostream&
512operator<<(std::ostream& os, const Account& acc)
513{
514 os << "[Account " << acc.getAccountID() << "] ";
515 return os;
516}
517
518} // namespace jami
virtual std::string getFromUri() const =0
virtual ~Account()
Virtual destructor.
Definition account.cpp:74
std::string getDisplayName() const
Definition account.h:309
bool isEnabled() const
Tell if the account is enable or not.
Definition account.h:252
RegistrationState getRegistrationState() const
Definition account.h:172
bool iceCompIdRfc5245Compliant_
Definition account.h:496
void enableIceCompIdRfc5245Compliance(bool enable)
Definition account.h:397
virtual bool setPushNotificationConfig(const std::map< std::string, std::string > &data)
Definition account.cpp:459
bool hasActiveCodec(MediaType mediaType) const
Definition account.cpp:195
virtual void flush()
This method is called to request removal of possible account traces on the system,...
Definition account.h:424
bool removeConference(const std::string &confId)
Definition account.h:410
friend class ConfigurationTest
Definition account.h:439
virtual void doRegister()=0
Register the account.
virtual void setIsComposing(const std::string &, bool)
Definition account.h:198
virtual void updateUpnpController()
Definition account.cpp:84
void loadDefaultCodecs()
Helper function used to load the default codec order from the codec factory.
Definition account.cpp:124
std::shared_ptr< SystemCodecInfo > searchCodecById(unsigned codecId, MediaType mediaType)
Definition account.cpp:313
void enableIceForMedia(bool enable)
Definition account.h:372
static std::vector< unsigned > getDefaultCodecsId()
Definition account.cpp:260
std::vector< std::shared_ptr< SystemCodecInfo > > accountCodecInfoList_
Vector containing all account codecs (set of system codecs with custom parameters)
Definition account.h:477
const std::string & getAccountID() const
Get the account ID.
Definition account.h:149
virtual std::string_view getAccountType() const =0
void setCodecInactive(unsigned codecId)
Definition account.cpp:398
void attach(const std::shared_ptr< Conference > &conf)
Definition account.h:409
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:103
bool isReadReceiptEnabled() const
Definition account.h:315
std::vector< unsigned > getActiveCodecs(MediaType mediaType=MEDIA_ALL) const
Definition account.cpp:349
virtual void updateProfile(const std::string &, const std::string &, const std::string &, int32_t)=0
void setEnabled(bool enable)
Definition account.h:254
std::vector< std::string > getConferenceList() const
Definition account.h:406
static std::string getDefaultUserAgent()
Build the user-agent string.
Definition account.cpp:428
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:204
const std::string accountID_
Account ID are assign in constructor and shall not changed.
Definition account.h:453
virtual void connectivityChanged()
Inform the account that the network status has changed.
Definition account.h:339
static bool meetMinimumRequiredVersion(const std::vector< unsigned > &jamiVersion, const std::vector< unsigned > &minRequiredVersion)
Definition account.cpp:446
std::shared_ptr< SystemCodecInfo > searchCodecByName(const std::string &name, MediaType mediaType)
private account codec searching functions
Definition account.cpp:325
bool isRendezVous() const
Definition account.h:312
RegistrationState registrationState_
Definition account.h:468
std::mt19937_64 rand
Random generator engine Logical account state shall never rely on the state of the random generator.
Definition account.h:334
void setActive(bool active) noexcept
Definition account.h:269
virtual std::map< std::string, std::string > getNearbyPeers() const
Definition account.h:209
virtual void doUnregister(bool forceShutdownConnections=false)=0
Unregister the account.
bool isAllModerators() const
Definition account.h:368
void enableVideo(bool enable)
Definition account.h:273
const std::string & getUsername() const
Definition account.h:285
std::map< std::string, std::string > getAccountDetails() const
Definition account.h:135
bool isIceCompIdRfc5245Compliant() const
Definition account.h:396
std::filesystem::path idPath_
path to account
Definition account.h:482
bool detach(const std::shared_ptr< Call > &call)
Definition account.h:408
bool isEmptyOffersEnabled() const
Definition account.h:375
bool isUsable() const
Definition account.h:271
std::shared_ptr< SystemCodecContainer > systemCodecContainer_
Vector containing all system codecs (with default parameters)
Definition account.h:473
std::filesystem::path getRingtonePath() const
Definition account.h:307
std::shared_ptr< Call > getCall(const std::string &callId) const
Definition account.h:400
bool isComposingEnabled() const
Definition account.h:316
void addDefaultModerator(const std::string &peerURI)
Definition account.cpp:434
bool isActive() const noexcept
Tell if the account is activated (can currently be used).
Definition account.h:267
static std::string mapStateNumberToString(RegistrationState state)
Definition account.cpp:234
virtual std::map< std::string, std::string > getVolatileAccountDetails() const
Definition account.cpp:174
std::vector< std::shared_ptr< SystemCodecInfo > > getActiveAccountCodecInfoList(MediaType mediaType) const
Definition account.cpp:407
std::shared_ptr< Conference > getConference(const std::string &confId) const
Definition account.h:402
std::vector< unsigned > getAccountCodecInfoIdList(MediaType mediaType) const
Definition account.cpp:363
std::mutex upnp_mtx
UPnP IGD controller and the mutex to access it.
Definition account.h:492
bool iceForMediaEnabled_
Definition account.h:495
void removeDefaultModerator(const std::string &peerURI)
Definition account.cpp:440
virtual im::MessageStatus getMessageStatus(uint64_t) const
Return the status corresponding to the token.
Definition account.h:222
virtual std::vector< libjami::Message > getLastMessages(const uint64_t &)
Definition account.h:207
static const std::string DEFAULT_USER_AGENT
Definition account.h:441
std::unique_ptr< AccountConfig > config_
Definition account.h:437
bool isIceForMediaEnabled() const
Definition account.h:371
dhtnet::IpAddr getUPnPIpAddress() const
Get the UPnP IP (external router) address.
Definition account.cpp:287
std::recursive_mutex configurationMutex_
Definition account.h:455
std::string getMailBox() const
Definition account.h:310
virtual std::unique_ptr< AccountConfig > buildConfig() const =0
const std::filesystem::path & getPath() const
Definition account.h:153
virtual bool isIP2IP() const
Returns true if this is the IP2IP account.
Definition account.h:158
bool autoLoadConversations_
Auto load conversations when creatinf convModule()
Definition account.h:500
std::set< std::string > getDefaultModerators() const
Definition account.h:362
bool isLocalModeratorsEnabled() const
Definition account.h:367
bool getRingtoneEnabled() const
Definition account.h:308
virtual bool handleMessage(const std::shared_ptr< dht::crypto::Certificate > &, const std::string &, const std::pair< std::string, std::string > &)
Definition account.h:341
const std::string & getUserAgentName()
Get the user-agent.
Definition account.cpp:422
virtual bool setMessageDisplayed(const std::string &, const std::string &, int)
Definition account.h:200
void editConfig(std::function< void(AccountConfig &config)> &&edit)
Definition account.h:116
virtual bool setPushNotificationTopic(const std::string &topic="")
Definition account.h:235
bool isAutoAnswerEnabled() const
Definition account.h:313
void setConfig(std::unique_ptr< AccountConfig > &&config)
Definition account.h:96
const std::string & getAlias() const
Definition account.h:287
void setCodecActive(unsigned codecId)
Definition account.cpp:389
void enableAutoLoadConversations(bool enable)
Definition account.h:398
void hangupCalls()
Free all ressources related to this account.
Definition account.cpp:77
bool getUPnPActive() const
returns whether or not UPnP is enabled and active ie: if it is able to make port mappings
Definition account.cpp:300
const AccountConfig & config() const
Definition account.h:108
std::shared_ptr< SystemCodecInfo > searchCodecByPayload(unsigned payload, MediaType mediaType)
Definition account.cpp:337
std::vector< std::string > getCallList() const
Definition account.h:401
virtual std::shared_ptr< Call > newOutgoingCall(std::string_view toUrl, const std::vector< libjami::MediaMap > &mediaList)=0
Create a new outgoing call.
vCard::utils::VCardData getProfileVcard() const
Definition account.cpp:181
bool active_
Tells if the account is active now.
Definition account.h:462
bool isVideoEnabled() const
Definition account.h:277
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:189
std::filesystem::path ringtonePath_
Ringtone .au file used for this account.
Definition account.h:487
void attach(const std::shared_ptr< Call > &call)
Definition account.h:407
static std::map< std::string, std::string > getDefaultCodecDetails(const unsigned &codecId)
Definition account.cpp:266
void setAllCodecsActive(MediaType mediaType, bool active)
Definition account.cpp:378
virtual void saveConfig() const
Definition account.cpp:168
virtual bool setPushNotificationToken(const std::string &pushDeviceToken="")
Definition account.h:224
bool isDenySecondCallEnabled() const
Definition account.h:314
const std::string & getHostname() const
Definition account.h:286
virtual void loadConfig()
Load the settings in this account.
Definition account.cpp:148
std::shared_ptr< dhtnet::upnp::Controller > upnpCtrl_
Definition account.h:493
void setAccountDetails(const std::map< std::string, std::string > &details)
Definition account.h:125
void sortCodec()
Definition account.cpp:224
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:66
Definition account.h:46
Definition account.h:50
std::map< std::string, std::string, std::less<> > VCardData
Definition vcard.h:89
void emitSignal(Args... args)
Definition jami_signal.h:64
RegistrationState
Contains all the Registration states for an account can be in.
static constexpr const char RINGDIR[]
Definition account.h:58
static constexpr uint64_t JAMI_ID_MAX_VAL
Definition account.h:57
@ MEDIA_ALL
Definition media_codec.h:48
static std::ostream & operator<<(std::ostream &os, const Account &acc)
Definition account.h:512
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)