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