Line data Source code
1 : /*
2 : * Copyright (C) 2004-2024 Savoir-faire Linux Inc.
3 : *
4 : * Author: Yan Morin <yan.morin@savoirfairelinux.com>
5 : * Author: Laurielle Lea <laurielle.lea@savoirfairelinux.com>
6 : * Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
7 : * Author: Guillaume Carmel-Archambault <guillaume.carmel-archambault@savoirfairelinux.com>
8 : * Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
9 : * Author: Tristan Matthews <tristan.matthews@savoirfairelinux.com>
10 : * Author: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>
11 : * Author: Aline Gondim Santos <aline.gondimsantos@savoirfairelinux.com>
12 : *
13 : * This program is free software; you can redistribute it and/or modify
14 : * it under the terms of the GNU General Public License as published by
15 : * the Free Software Foundation; either version 3 of the License, or
16 : * (at your option) any later version.
17 : *
18 : * This program is distributed in the hope that it will be useful,
19 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 : * GNU General Public License for more details.
22 : *
23 : * You should have received a copy of the GNU General Public License
24 : * along with this program; if not, write to the Free Software
25 : * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 : */
27 :
28 : #pragma once
29 :
30 : #ifdef HAVE_CONFIG_H
31 : #include "config.h"
32 : #endif
33 :
34 : #include "account_factory.h"
35 : #include "call_factory.h"
36 : #include "preferences.h"
37 : #include "media/audio/audiolayer.h"
38 : #include "scheduled_executor.h"
39 : #include "gittransport.h"
40 : #include <dhtnet/certstore.h>
41 :
42 : #include <algorithm>
43 : #include <atomic>
44 : #include <functional>
45 : #include <map>
46 : #include <memory>
47 : #include <optional>
48 : #include <string>
49 : #include <vector>
50 :
51 : #include "trace-tools.h"
52 :
53 : namespace asio {
54 : class io_context;
55 : }
56 :
57 : namespace dhtnet {
58 : class ChannelSocket;
59 : class IceTransportFactory;
60 : } // namespace dhtnet
61 :
62 : namespace jami {
63 : namespace video {
64 : class SinkClient;
65 : class VideoGenerator;
66 : } // namespace video
67 : class RingBufferPool;
68 : struct VideoManager;
69 : class Conference;
70 : class AudioLoop;
71 : class JamiAccount;
72 : class SIPVoIPLink;
73 : class JamiPluginManager;
74 :
75 : /** Manager (controller) of daemon */
76 : // TODO LIBJAMI_PUBLIC only if tests
77 : class LIBJAMI_TESTABLE Manager
78 : {
79 : private:
80 : std::mt19937_64 rand_;
81 :
82 : public:
83 : // TODO LIBJAMI_PUBLIC only if tests
84 : static LIBJAMI_TESTABLE Manager& instance();
85 :
86 : void setAutoAnswer(bool enable);
87 :
88 : /**
89 : * General preferences configuration
90 : */
91 : Preferences preferences;
92 :
93 : /**
94 : * Voip related preferences
95 : */
96 : VoipPreference voipPreferences;
97 :
98 : /**
99 : * Audio preferences
100 : */
101 : AudioPreference audioPreference;
102 :
103 : #ifdef ENABLE_PLUGIN
104 : /**
105 : * Plugin preferences
106 : */
107 : PluginPreferences pluginPreferences;
108 : #endif
109 :
110 : #ifdef ENABLE_VIDEO
111 : /**
112 : * Video preferences
113 : */
114 : VideoPreferences videoPreferences;
115 : #endif
116 :
117 : // Manager should not be accessed until initialized.
118 : // FIXME this is an evil hack!
119 : static std::atomic_bool initialized;
120 :
121 : #if TARGET_OS_IOS
122 : static bool isIOSExtension;
123 : #endif
124 :
125 : static bool syncOnRegister;
126 :
127 : static bool autoLoad;
128 :
129 : /**
130 : * Initialisation of thread (sound) and map.
131 : * Init a new VoIPLink, audio codec and audio driver.
132 : */
133 : void init(const std::filesystem::path& config_file, libjami::InitFlag flags);
134 :
135 : /*
136 : * Terminate all threads and exit DBus loop
137 : */
138 : void finish() noexcept;
139 :
140 : void monitor(bool continuous);
141 :
142 : std::vector<std::map<std::string, std::string>> getConnectionList(
143 : const std::string& accountId, const std::string& conversationId);
144 : std::vector<std::map<std::string, std::string>> getChannelList(const std::string& accountId,
145 : const std::string& connectionId);
146 :
147 : /**
148 : * Accessor to audiodriver.
149 : * it's multi-thread and use mutex internally
150 : * @return AudioLayer* The audio layer object
151 : */
152 : std::shared_ptr<AudioLayer> getAudioDriver();
153 :
154 591 : inline std::unique_ptr<AudioDeviceGuard> startAudioStream(AudioDeviceType stream)
155 : {
156 591 : return std::make_unique<AudioDeviceGuard>(*this, stream);
157 : }
158 :
159 : /**
160 : * Place a new call
161 : * @param accountId the user's account ID
162 : * @param callee the callee's ID/URI. Depends on the account type.
163 : * Refer to placeCall/placeCallWithMedia documentations.
164 : * @param mediaList a list of medias to include
165 : * @return the call ID on success, empty string otherwise
166 : */
167 : std::string outgoingCall(const std::string& accountId,
168 : const std::string& callee,
169 : const std::vector<libjami::MediaMap>& mediaList = {});
170 :
171 : /**
172 : * Functions which occur with a user's action
173 : * Answer the call
174 : * @param callId
175 : */
176 : bool answerCall(const std::string& accountId,
177 : const std::string& callId,
178 : const std::vector<libjami::MediaMap>& mediaList = {});
179 : bool answerCall(Call& call, const std::vector<libjami::MediaMap>& mediaList = {});
180 :
181 : /**
182 : * Handle incoming call and notify user
183 : * @param accountId an account id
184 : * @param call A call pointer
185 : */
186 : void incomingCall(const std::string& accountId, Call& call);
187 :
188 : /**
189 : * Functions which occur with a user's action
190 : * Hangup the call
191 : * @param accountId
192 : * @param callId The call identifier
193 : */
194 : bool hangupCall(const std::string& accountId, const std::string& callId);
195 :
196 : /**
197 : * Functions which occur with a user's action
198 : * Hangup the conference (hangup every participants)
199 : * @param id The call identifier
200 : */
201 : bool hangupConference(const std::string& accountId, const std::string& confId);
202 :
203 : /**
204 : * Functions which occur with a user's action
205 : * Put the call on hold
206 : * @param accountId
207 : * @param callId The call identifier
208 : */
209 : bool onHoldCall(const std::string& accountId, const std::string& callId);
210 :
211 : /**
212 : * Functions which occur with a user's action
213 : * Put the call off hold
214 : * @param accountId
215 : * @param id The call identifier
216 : */
217 : bool offHoldCall(const std::string& accountId, const std::string& callId);
218 :
219 : /**
220 : * Functions which occur with a user's action
221 : * Transfer the call
222 : * @param id The call identifier
223 : * @param to The recipient of the transfer
224 : */
225 : bool transferCall(const std::string& accountId, const std::string& id, const std::string& to);
226 :
227 : /**
228 : * Notify the client the transfer is successful
229 : */
230 : void transferSucceeded();
231 :
232 : /**
233 : * Notify the client that the transfer failed
234 : */
235 : void transferFailed();
236 :
237 : /**
238 : * Functions which occur with a user's action
239 : * Refuse the call
240 : * @param id The call identifier
241 : */
242 : bool refuseCall(const std::string& accountId, const std::string& id);
243 :
244 : /**
245 : * Hold every participant to a conference
246 : * @param the conference id
247 : */
248 : bool holdConference(const std::string& accountId, const std::string& confId);
249 :
250 : /**
251 : * Unhold all conference participants
252 : * @param the conference id
253 : */
254 : bool unHoldConference(const std::string& accountId, const std::string& confId);
255 :
256 : /**
257 : * Add a participant to a conference
258 : * @param the call id
259 : * @param the conference id
260 : */
261 : bool addParticipant(const std::string& accountId,
262 : const std::string& callId,
263 : const std::string& account2Id,
264 : const std::string& confId);
265 : bool addParticipant(Call& call, Conference& conference);
266 : void bindCallToConference(Call& call, Conference& conf);
267 :
268 : /**
269 : * Bind the main participant to a conference (mainly called on a double click action)
270 : * @param the conference id
271 : */
272 : bool addMainParticipant(const std::string& accountId, const std::string& confId);
273 :
274 : /**
275 : * Join two participants to create a conference
276 : * @param the fist call id
277 : * @param the second call id
278 : */
279 : bool joinParticipant(const std::string& accountId,
280 : const std::string& callId1,
281 : const std::string& account2Id,
282 : const std::string& callId2,
283 : bool attached = true);
284 :
285 : /**
286 : * Create a conference from a list of participant
287 : * @param A vector containing the list of participant
288 : */
289 : void createConfFromParticipantList(const std::string& accountId,
290 : const std::vector<std::string>&);
291 :
292 : /**
293 : * Detach a participant from a conference, put the call on hold, do not hangup it
294 : * @param call id
295 : * @param the current call id
296 : */
297 : bool detachParticipant(const std::string& callId);
298 :
299 : /**
300 : * Detach the local participant from curent conference.
301 : * Remote participants are placed in hold.
302 : */
303 : bool detachLocalParticipant(const std::shared_ptr<Conference>& conf = {});
304 :
305 : /**
306 : * Remove the conference participant from a conference
307 : * @param call id
308 : */
309 : void removeParticipant(Call& call);
310 :
311 : /**
312 : * Join two conference together into one unique conference
313 : */
314 : bool joinConference(const std::string& accountId,
315 : const std::string& confId1,
316 : const std::string& account2Id,
317 : const std::string& confId2);
318 :
319 : void addAudio(Call& call);
320 :
321 : void removeAudio(Call& call);
322 :
323 : /**
324 : * Save config to file
325 : */
326 : void saveConfig();
327 : void saveConfig(const std::shared_ptr<Account>& acc);
328 :
329 : /**
330 : * Play a ringtone
331 : */
332 : void playTone();
333 :
334 : /**
335 : * Play a special ringtone ( BUSY ) if there's at least one message on the voice mail
336 : */
337 : void playToneWithMessage();
338 :
339 : /**
340 : * Acts on the audio streams and audio files
341 : */
342 : void stopTone();
343 :
344 : /**
345 : * Notify the user that the recipient of the call has answered and the put the
346 : * call in Current state
347 : * @param id The call identifier
348 : */
349 : void peerAnsweredCall(Call& call);
350 :
351 : /**
352 : * Rings back because the outgoing call is ringing and the put the
353 : * call in Ringing state
354 : * @param id The call identifier
355 : */
356 : void peerRingingCall(Call& call);
357 :
358 : /**
359 : * Put the call in Hungup state, remove the call from the list
360 : * @param id The call identifier
361 : */
362 : void peerHungupCall(Call& call);
363 :
364 : /**
365 : * Notify the client with an incoming message
366 : * @param accountId The account identifier
367 : * @param callId The call to send the message
368 : * @param messages A map if mime type as key and mime payload as value
369 : */
370 : void incomingMessage(const std::string& accountId,
371 : const std::string& callId,
372 : const std::string& from,
373 : const std::map<std::string, std::string>& messages);
374 :
375 : /**
376 : * Send a new text message to the call, if participate to a conference, send to all participant.
377 : * @param accountId
378 : * @param callId The call to send the message
379 : * @param message A list of pair of mime types and payloads
380 : * @param from The sender of this message (could be another participant of a conference)
381 : */
382 : void sendCallTextMessage(const std::string& accountId,
383 : const std::string& callID,
384 : const std::map<std::string, std::string>& messages,
385 : const std::string& from,
386 : bool isMixed);
387 :
388 : /**
389 : * ConfigurationManager - Send registration request
390 : * @param accountId The account to register/unregister
391 : * @param enable The flag for the type of registration
392 : * false for unregistration request
393 : * true for registration request
394 : */
395 : void sendRegister(const std::string& accountId, bool enable);
396 :
397 : uint64_t sendTextMessage(const std::string& accountID,
398 : const std::string& to,
399 : const std::map<std::string, std::string>& payloads,
400 : bool fromPlugin = false,
401 : bool onlyConnected = false);
402 :
403 : int getMessageStatus(uint64_t id) const;
404 : int getMessageStatus(const std::string& accountID, uint64_t id) const;
405 :
406 : /**
407 : * Get account list
408 : * @return std::vector<std::string> A list of accoundIDs
409 : */
410 : std::vector<std::string> getAccountList() const;
411 :
412 : /**
413 : * Set the account order in the config file
414 : */
415 : void setAccountsOrder(const std::string& order);
416 :
417 : /**
418 : * Retrieve details about a given account
419 : * @param accountID The account identifier
420 : * @return std::map< std::string, std::string > The account details
421 : */
422 : std::map<std::string, std::string> getAccountDetails(const std::string& accountID) const;
423 :
424 : /**
425 : * Retrieve volatile details such as recent registration errors
426 : * @param accountID The account identifier
427 : * @return std::map< std::string, std::string > The account volatile details
428 : */
429 : std::map<std::string, std::string> getVolatileAccountDetails(const std::string& accountID) const;
430 :
431 : /**
432 : * Get list of calls (internal subcalls are filter-out)
433 : * @return std::vector<std::string> A list of call IDs (without subcalls)
434 : */
435 : std::vector<std::string> getCallList() const;
436 :
437 : /**
438 : * Save the details of an existing account, given the account ID
439 : * This will load the configuration map with the given data.
440 : * It will also register/unregister links where the 'Enabled' switched.
441 : * @param accountID The account identifier
442 : * @param details The account parameters
443 : */
444 : void setAccountDetails(const std::string& accountID,
445 : const std::map<std::string, ::std::string>& details);
446 :
447 : void setAccountActive(const std::string& accountID, bool active, bool shutdownConnections);
448 : void loadAccountAndConversation(const std::string& accountId,
449 : bool loadAll,
450 : const std::string& convId);
451 :
452 : std::mt19937_64 getSeededRandomEngine();
453 :
454 : /**
455 : * Return a new random accountid that is not present in the list
456 : * @return A brand new accountid
457 : */
458 : std::string getNewAccountId();
459 :
460 : /**
461 : * Add a new account, and give it a new account ID automatically
462 : * @param details The new account parameters
463 : * @param accountId optionnal predetermined accountid to use
464 : * @return The account Id given to the new account
465 : */
466 : std::string addAccount(const std::map<std::string, std::string>& details,
467 : const std::string& accountId = {});
468 :
469 : /**
470 : * Delete an existing account, unregister VoIPLink associated, and
471 : * purge from configuration.
472 : * If 'flush' argument is true, filesystem entries are also removed.
473 : * @param accountID The account unique ID
474 : */
475 : void removeAccount(const std::string& accountID, bool flush = false);
476 :
477 : void removeAccounts();
478 :
479 : /**
480 : * Set input audio plugin
481 : * @param audioPlugin The audio plugin
482 : */
483 : void setAudioPlugin(const std::string& audioPlugin);
484 :
485 : /**
486 : * Set audio device
487 : * @param index The index of the soundcard
488 : * @param the type of stream, either PLAYBACK, CAPTURE, RINGTONE
489 : */
490 : void setAudioDevice(int index, AudioDeviceType streamType);
491 :
492 : void startAudio();
493 :
494 : /**
495 : * Get list of supported audio output device
496 : * @return std::vector<std::string> A list of the audio devices supporting playback
497 : */
498 : std::vector<std::string> getAudioOutputDeviceList();
499 :
500 : /**
501 : * Get list of supported audio input device
502 : * @return std::vector<std::string> A list of the audio devices supporting capture
503 : */
504 : std::vector<std::string> getAudioInputDeviceList();
505 :
506 : /**
507 : * Get string array representing integer indexes of output, input, and ringtone device
508 : * @return std::vector<std::string> A list of the current audio devices
509 : */
510 : std::vector<std::string> getCurrentAudioDevicesIndex();
511 :
512 : /**
513 : * Get index of an audio device
514 : * @param name The string description of an audio device
515 : * @return int His index
516 : */
517 : int getAudioInputDeviceIndex(const std::string& name);
518 : int getAudioOutputDeviceIndex(const std::string& name);
519 :
520 : /**
521 : * Get current alsa plugin
522 : * @return std::string The Alsa plugin
523 : */
524 : std::string getCurrentAudioOutputPlugin() const;
525 :
526 : /**
527 : * Get the noise reduction engine state from
528 : * the current audio layer.
529 : */
530 : std::string getNoiseSuppressState() const;
531 :
532 : /**
533 : * Set the noise reduction engine state in the current
534 : * audio layer.
535 : */
536 : void setNoiseSuppressState(const std::string& state);
537 :
538 : bool isAGCEnabled() const;
539 : void setAGCState(bool enabled);
540 :
541 : /**
542 : * Get is always recording functionality
543 : */
544 : bool getIsAlwaysRecording() const;
545 :
546 : /**
547 : * Set is always recording functionality, every calls will then be set in RECORDING mode
548 : * once answered
549 : */
550 : void setIsAlwaysRecording(bool isAlwaysRec);
551 :
552 : /**
553 : * Set recording on / off
554 : * Start recording
555 : * @param id The call identifier
556 : * Returns true if the call was set to record
557 : */
558 : bool toggleRecordingCall(const std::string& accountId, const std::string& id);
559 :
560 : /**
561 : * Start playback fo a recorded file if and only if audio layer is not already started.
562 : * @param File path of the file to play
563 : */
564 : bool startRecordedFilePlayback(const std::string&);
565 :
566 : void recordingPlaybackSeek(const double value);
567 :
568 : /**
569 : * Stop playback of recorded file
570 : */
571 : void stopRecordedFilePlayback();
572 :
573 : /**
574 : * Set the maximum number of days to keep in the history
575 : * @param calls The number of days
576 : */
577 : void setHistoryLimit(int days);
578 :
579 : /**
580 : * Get the maximum number of days to keep in the history
581 : * @return double The number of days
582 : */
583 : int getHistoryLimit() const;
584 :
585 : /**
586 : * Set ringing timeout (number of seconds after which a call will
587 : * enter BUSY state if not answered).
588 : * @param timeout in seconds
589 : */
590 : void setRingingTimeout(int timeout);
591 :
592 : /**
593 : * Get ringing timeout (number of seconds after which a call will
594 : * enter BUSY state if not answered).
595 : * @return timeout in seconds
596 : */
597 : int getRingingTimeout() const;
598 :
599 : /**
600 : * Get the audio manager
601 : * @return int The audio manager
602 : * "alsa"
603 : * "pulseaudio"
604 : */
605 : std::string getAudioManager() const;
606 :
607 : /**
608 : * Set the audio manager
609 : * @return true if api is now in use, false otherwise
610 : */
611 : bool setAudioManager(const std::string& api);
612 :
613 : /**
614 : * Callback called when the audio layer initialised with its
615 : * preferred format.
616 : */
617 : AudioFormat hardwareAudioFormatChanged(AudioFormat format);
618 :
619 : /**
620 : * Should be called by any component dealing with an external
621 : * audio source, indicating the format used so the mixer format
622 : * can be eventually adapted.
623 : * @returns the new format used by the main buffer.
624 : */
625 : AudioFormat audioFormatUsed(AudioFormat format);
626 :
627 : /**
628 : * Handle audio sounds heard by a caller while they wait for their
629 : * connection to a called party to be completed.
630 : */
631 : void ringback();
632 :
633 : /**
634 : * Handle played music when an incoming call occurs
635 : */
636 : void playRingtone(const std::string& accountID);
637 :
638 : /**
639 : * Handle played music when a congestion occurs
640 : */
641 : void congestion();
642 :
643 : /**
644 : * Play the dtmf-associated sound
645 : * @param code The pressed key
646 : */
647 : void playDtmf(char code);
648 :
649 : /**
650 : * Handle played sound when a call can not be conpleted because of a busy recipient
651 : */
652 : void callBusy(Call& call);
653 :
654 : /**
655 : * Handle played sound when a failure occurs
656 : */
657 : void callFailure(Call& call);
658 :
659 : /**
660 : * Retrieve the current telephone tone
661 : * @return AudioLoop* The audio tone or 0 if no tone (init before calling this function)
662 : */
663 : std::shared_ptr<AudioLoop> getTelephoneTone();
664 :
665 : /**
666 : * Retrieve the current telephone file
667 : * @return AudioLoop* The audio file or 0 if the wav is stopped
668 : */
669 : std::shared_ptr<AudioLoop> getTelephoneFile();
670 :
671 : /**
672 : * @return true is there is one or many incoming call waiting
673 : * new call, not answered or refused
674 : */
675 : bool incomingCallsWaiting();
676 :
677 : /**
678 : * Get the current call
679 : * @return std::shared_ptr<Call> A call shared pointer (could be empty)
680 : */
681 : std::shared_ptr<Call> getCurrentCall() const;
682 :
683 : /**
684 : * Get the current call id
685 : * @return std::string The call id or ""
686 : */
687 : const std::string& getCurrentCallId() const;
688 :
689 : /**
690 : * Check if a call is the current one
691 : * @param call the new call
692 : * @return bool True if the call is the current
693 : */
694 : bool isCurrentCall(const Call& call) const;
695 :
696 : /**
697 : * Load the accounts order set by the user from the jamirc config file
698 : * @return std::vector<std::string> A vector containing the account ID's
699 : */
700 : std::vector<std::string_view> loadAccountOrder() const;
701 :
702 : /**
703 : * Load the account map from configuration
704 : */
705 : int loadAccountMap(const YAML::Node& node);
706 :
707 : /**
708 : * Get the Call referred by callID. If the Call does not exist, return
709 : * empty std::shared_ptr<Call> instance
710 : */
711 : std::shared_ptr<Call> getCallFromCallID(const std::string& callID) const;
712 :
713 : /**
714 : * Return a pointer to the instance of the RingBufferPool
715 : */
716 : RingBufferPool& getRingBufferPool();
717 :
718 : /**
719 : * Tell if there is a current call processed
720 : * @return bool True if there is a current call
721 : */
722 : bool hasCurrentCall() const;
723 :
724 : /**
725 : * Get an account pointer, looks for account of type T
726 : * @param accountID account ID to get
727 : * @return std::shared_ptr<Account> Shared pointer on an Account instance or nullptr if not found
728 : */
729 : template<class T = Account>
730 18700 : inline std::shared_ptr<T> getAccount(std::string_view accountId) const
731 : {
732 18700 : return accountFactory.getAccount<T>(accountId);
733 : }
734 :
735 : /**
736 : * Get a list of account pointers of type T (baseclass Account)
737 : * @return a sorted vector of all accounts of type T
738 : */
739 : template<class T = Account>
740 2955 : std::vector<std::shared_ptr<T>> getAllAccounts() const
741 : {
742 2955 : const auto& account_order = loadAccountOrder();
743 2955 : const auto& all_accounts = accountFactory.getAllAccounts<T>();
744 2955 : std::vector<std::shared_ptr<T>> accountList;
745 2955 : accountList.reserve(all_accounts.size());
746 8247 : for (const auto& id : account_order) {
747 10584 : if (auto acc = accountFactory.getAccount<T>(id))
748 5292 : accountList.emplace_back(std::move(acc));
749 : }
750 8296 : for (auto& account : all_accounts) {
751 5341 : if (std::find(accountList.begin(), accountList.end(), account) == accountList.end())
752 49 : accountList.emplace_back(std::move(account));
753 : }
754 5910 : return accountList;
755 2955 : }
756 :
757 : template<class T = Account>
758 2831 : std::size_t accountCount() const
759 : {
760 2831 : return accountFactory.accountCount<T>();
761 : }
762 :
763 : template<class T>
764 : inline std::shared_ptr<T> findAccount(const std::function<bool(const std::shared_ptr<T>&)>& pred)
765 : {
766 : for (const auto& account : getAllAccounts<T>()) {
767 : if (pred(account))
768 : return account;
769 : }
770 : return {};
771 : }
772 :
773 : // only used by test framework
774 : bool hasAccount(const std::string& accountID);
775 :
776 : /**
777 : * Send registration for all enabled accounts
778 : */
779 : void registerAccounts();
780 :
781 : /**
782 : * Send registration for one account
783 : */
784 : void registerAccount(const std::string& accountID, const std::string& convId = {});
785 :
786 : /**
787 : * Send unregister for all enabled accounts
788 : */
789 : void unregisterAccounts();
790 :
791 : /**
792 : * Create a new outgoing call
793 : * @param toUrl Destination address
794 : * @param accountId local account
795 : * @param mediaList the list of medias
796 : * @return A (shared) pointer of Call class type.
797 : * @note This function raises VoipLinkException() on error.
798 : */
799 : std::shared_ptr<Call> newOutgoingCall(std::string_view toUrl,
800 : const std::string& accountId,
801 : const std::vector<libjami::MediaMap>& mediaList);
802 :
803 : CallFactory callFactory;
804 :
805 : const std::shared_ptr<dhtnet::IceTransportFactory>& getIceTransportFactory();
806 :
807 : std::shared_ptr<asio::io_context> ioContext() const;
808 : std::shared_ptr<dhtnet::upnp::UPnPContext> upnpContext() const;
809 :
810 : ScheduledExecutor& scheduler();
811 : std::shared_ptr<Task> scheduleTask(std::function<void()>&& task,
812 : std::chrono::steady_clock::time_point when,
813 : const char* filename = CURRENT_FILENAME(),
814 : uint32_t linum = CURRENT_LINE());
815 :
816 : std::shared_ptr<Task> scheduleTaskIn(std::function<void()>&& task,
817 : std::chrono::steady_clock::duration timeout,
818 : const char* filename = CURRENT_FILENAME(),
819 : uint32_t linum = CURRENT_LINE());
820 :
821 : std::map<std::string, std::string> getNearbyPeers(const std::string& accountID);
822 :
823 : #ifdef ENABLE_VIDEO
824 : /**
825 : * Create a new SinkClient instance, store it in an internal cache as a weak_ptr
826 : * and return it as a shared_ptr. If a SinkClient is already stored for the given id,
827 : * this method returns this instance.
828 : * @param id SinkClient identifier as a string. Default is empty.
829 : * @param mixer true if the SinkCient is the sink of a VideoMixer node. Default is false.
830 : * @return share_ptr<SinkClient> A shared pointer on the created instance.
831 : */
832 : std::shared_ptr<video::SinkClient> createSinkClient(const std::string& id = "",
833 : bool mixer = false);
834 :
835 : /**
836 : * Create a SinkClient instance for each participant in a conference, store it in an internal
837 : * cache as a weak_ptr and populates sinksMap with sink ids and shared_ptrs.
838 : * @param callId
839 : * @param infos ConferenceInfos that will create the sinks
840 : * @param videoStream the the VideoFrameActiveWriter to which the sinks should be attached
841 : * @param sinksMap A map between sink ids and the respective shared pointer.
842 : */
843 : void createSinkClients(
844 : const std::string& callId,
845 : const ConfInfo& infos,
846 : const std::vector<std::shared_ptr<video::VideoFrameActiveWriter>>& videoStreams,
847 : std::map<std::string, std::shared_ptr<video::SinkClient>>& sinksMap,
848 : const std::string& accountId = "");
849 :
850 : /**
851 : * Return an existing SinkClient instance as a shared_ptr associated to the given identifier.
852 : * Return an empty shared_ptr (nullptr) if nothing found.
853 : * @param id SinkClient identifier as a string.
854 : * @return share_ptr<SinkClient> A shared pointer on the found instance. Empty if not found.
855 : */
856 : std::shared_ptr<video::SinkClient> getSinkClient(const std::string& id);
857 :
858 : #endif // ENABLE_VIDEO
859 : VideoManager& getVideoManager() const;
860 :
861 : std::atomic<unsigned> dhtLogLevel {0}; // default = disable
862 : AccountFactory accountFactory;
863 :
864 : std::vector<libjami::Message> getLastMessages(const std::string& accountID,
865 : const uint64_t& base_timestamp);
866 :
867 : SIPVoIPLink& sipVoIPLink() const;
868 : #ifdef ENABLE_PLUGIN
869 : JamiPluginManager& getJamiPluginManager() const;
870 : #endif
871 : /**
872 : * Return current git socket used for a conversation
873 : * @param accountId Related account
874 : * @param deviceId Related device
875 : * @param conversationId Related conversation
876 : * @return std::optional<std::weak_ptr<ChannelSocket>> the related socket
877 : */
878 : std::shared_ptr<dhtnet::ChannelSocket> gitSocket(const std::string_view accountId,
879 : const std::string_view deviceId,
880 : const std::string_view conversationId);
881 :
882 : void setDefaultModerator(const std::string& accountID, const std::string& peerURI, bool state);
883 : std::vector<std::string> getDefaultModerators(const std::string& accountID);
884 : void enableLocalModerators(const std::string& accountID, bool state);
885 : bool isLocalModeratorsEnabled(const std::string& accountID);
886 : void setAllModerators(const std::string& accountID, bool allModerators);
887 : bool isAllModerators(const std::string& accountID);
888 :
889 : void insertGitTransport(git_smart_subtransport* tr, std::unique_ptr<P2PSubTransport>&& sub);
890 : void eraseGitTransport(git_smart_subtransport* tr);
891 :
892 : dhtnet::tls::CertificateStore& certStore(const std::string& accountId) const;
893 :
894 : private:
895 : Manager();
896 : ~Manager();
897 : friend class AudioDeviceGuard;
898 :
899 : // Data members
900 : struct ManagerPimpl;
901 : std::unique_ptr<ManagerPimpl> pimpl_;
902 : };
903 :
904 : class AudioDeviceGuard
905 : {
906 : public:
907 : AudioDeviceGuard(Manager& manager, AudioDeviceType type);
908 : ~AudioDeviceGuard();
909 :
910 : private:
911 : Manager& manager_;
912 : const AudioDeviceType type_;
913 : };
914 :
915 : // Helper to install a callback to be called once by the main event loop
916 : template<typename Callback>
917 : static void
918 81481 : runOnMainThread(Callback&& cb,
919 : const char* filename = CURRENT_FILENAME(),
920 : uint32_t linum = CURRENT_LINE())
921 : {
922 162963 : Manager::instance().scheduler().run([cb = std::forward<Callback>(cb)]() mutable { cb(); },
923 : filename,
924 : linum);
925 81484 : }
926 :
927 : } // namespace jami
|