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