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(const std::string& accountId,
133 : 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 585 : inline std::unique_ptr<AudioDeviceGuard> startAudioStream(AudioDeviceType stream)
145 : {
146 585 : 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, 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, const std::map<std::string, std::string>& details);
434 :
435 : void setAccountActive(const std::string& accountID, bool active, bool shutdownConnections);
436 : void loadAccountAndConversation(const std::string& accountId, bool loadAll, const std::string& convId);
437 :
438 : std::mt19937_64 getSeededRandomEngine();
439 :
440 : /**
441 : * Return a new random accountid that is not present in the list
442 : * @return A brand new accountid
443 : */
444 : std::string getNewAccountId();
445 :
446 : /**
447 : * Add a new account, and give it a new account ID automatically
448 : * @param details The new account parameters
449 : * @param accountId optionnal predetermined accountid to use
450 : * @return The account Id given to the new account
451 : */
452 : std::string addAccount(const std::map<std::string, std::string>& details, const std::string& accountId = {});
453 :
454 : /**
455 : * Delete an existing account, unregister VoIPLink associated, and
456 : * purge from configuration.
457 : * If 'flush' argument is true, filesystem entries are also removed.
458 : * @param accountID The account unique ID
459 : */
460 : void removeAccount(const std::string& accountID, bool flush = false);
461 :
462 : void removeAccounts();
463 :
464 : /**
465 : * Set input audio plugin
466 : * @param audioPlugin The audio plugin
467 : */
468 : void setAudioPlugin(const std::string& audioPlugin);
469 :
470 : /**
471 : * Set audio device
472 : * @param index The index of the soundcard
473 : * @param the type of stream, either PLAYBACK, CAPTURE, RINGTONE
474 : */
475 : void setAudioDevice(int index, AudioDeviceType streamType);
476 :
477 : void startAudio();
478 :
479 : /**
480 : * Get list of supported audio output device
481 : * @return std::vector<std::string> A list of the audio devices supporting playback
482 : */
483 : std::vector<std::string> getAudioOutputDeviceList();
484 :
485 : /**
486 : * Get list of supported audio input device
487 : * @return std::vector<std::string> A list of the audio devices supporting capture
488 : */
489 : std::vector<std::string> getAudioInputDeviceList();
490 :
491 : /**
492 : * Get string array representing integer indexes of output, input, and ringtone device
493 : * @return std::vector<std::string> A list of the current audio devices
494 : */
495 : std::vector<std::string> getCurrentAudioDevicesIndex();
496 :
497 : /**
498 : * Get index of an audio device
499 : * @param name The string description of an audio device
500 : * @return int His index
501 : */
502 : int getAudioInputDeviceIndex(const std::string& name);
503 : int getAudioOutputDeviceIndex(const std::string& name);
504 :
505 : /**
506 : * Get current alsa plugin
507 : * @return std::string The Alsa plugin
508 : */
509 : std::string getCurrentAudioOutputPlugin() const;
510 :
511 : /**
512 : * Get the noise reduction engine state from
513 : * the current audio layer.
514 : */
515 : std::string getNoiseSuppressState() const;
516 :
517 : /**
518 : * Set the noise reduction engine state in the current
519 : * audio layer.
520 : */
521 : void setNoiseSuppressState(const std::string& state);
522 :
523 : /**
524 : * Get the echo cancellation engine state in
525 : * the current audio layer.
526 : * @return std::string The current state of echoCancel
527 : */
528 : std::string getEchoCancellationState() const;
529 :
530 : /**
531 : * Get the echo cancellation engine state from
532 : * the current audio layer.
533 : */
534 : void setEchoCancellationState(const std::string& state);
535 :
536 : /**
537 : * Get the voice activity detection engine state from
538 : * the current audio layer.
539 : * @return bool The current state of voice activity detection
540 : */
541 : bool getVoiceActivityDetectionState() const;
542 :
543 : /**
544 : * Set the voice activity detection engine state in the current
545 : * audio layer.
546 : */
547 : void setVoiceActivityDetectionState(bool state);
548 :
549 : bool isAGCEnabled() const;
550 : void setAGCState(bool enabled);
551 :
552 : /**
553 : * Get is always recording functionality
554 : */
555 : bool getIsAlwaysRecording() const;
556 :
557 : /**
558 : * Set is always recording functionality, every calls will then be set in RECORDING mode
559 : * once answered
560 : */
561 : void setIsAlwaysRecording(bool isAlwaysRec);
562 :
563 : /**
564 : * Set recording on / off
565 : * Start recording
566 : * @param id The call identifier
567 : * Returns true if the call was set to record
568 : */
569 : bool toggleRecordingCall(const std::string& accountId, const std::string& id);
570 :
571 : /**
572 : * Start playback fo a recorded file if and only if audio layer is not already started.
573 : * @param File path of the file to play
574 : */
575 : bool startRecordedFilePlayback(const std::string&);
576 :
577 : void recordingPlaybackSeek(const double value);
578 :
579 : /**
580 : * Stop playback of recorded file
581 : */
582 : void stopRecordedFilePlayback();
583 :
584 : /**
585 : * Set the maximum number of days to keep in the history
586 : * @param calls The number of days
587 : */
588 : void setHistoryLimit(int days);
589 :
590 : /**
591 : * Get the maximum number of days to keep in the history
592 : * @return double The number of days
593 : */
594 : int getHistoryLimit() const;
595 :
596 : /**
597 : * Set ringing timeout (number of seconds after which a call will
598 : * enter BUSY state if not answered).
599 : * @param timeout in seconds
600 : */
601 : void setRingingTimeout(int timeout);
602 :
603 : /**
604 : * Get ringing timeout (number of seconds after which a call will
605 : * enter BUSY state if not answered).
606 : * @return timeout in seconds
607 : */
608 : int getRingingTimeout() const;
609 :
610 : /**
611 : * Get the audio manager
612 : * @return int The audio manager
613 : * "alsa"
614 : * "pulseaudio"
615 : */
616 : std::string getAudioManager() const;
617 :
618 : /**
619 : * Set the audio manager
620 : * @return true if api is now in use, false otherwise
621 : */
622 : bool setAudioManager(const std::string& api);
623 :
624 : /**
625 : * Callback called when the audio layer initialised with its
626 : * preferred format.
627 : */
628 : AudioFormat hardwareAudioFormatChanged(AudioFormat format);
629 :
630 : /**
631 : * Should be called by any component dealing with an external
632 : * audio source, indicating the format used so the mixer format
633 : * can be eventually adapted.
634 : * @returns the new format used by the main buffer.
635 : */
636 : AudioFormat audioFormatUsed(AudioFormat format);
637 :
638 : /**
639 : * Handle audio sounds heard by a caller while they wait for their
640 : * connection to a called party to be completed.
641 : */
642 : void ringback();
643 :
644 : /**
645 : * Handle played music when an incoming call occurs
646 : */
647 : void playRingtone(const std::string& accountID);
648 :
649 : /**
650 : * Handle played music when a congestion occurs
651 : */
652 : void congestion();
653 :
654 : /**
655 : * Play the dtmf-associated sound
656 : * @param code The pressed key
657 : */
658 : void playDtmf(char code);
659 :
660 : /**
661 : * Handle played sound when a call is unable to be completed because of a busy recipient
662 : */
663 : void callBusy(Call& call);
664 :
665 : /**
666 : * Handle played sound when a failure occurs
667 : */
668 : void callFailure(Call& call);
669 :
670 : /**
671 : * Retrieve the current telephone tone
672 : * @return AudioLoop* The audio tone or 0 if no tone (init before calling this function)
673 : */
674 : std::shared_ptr<AudioLoop> getTelephoneTone();
675 :
676 : /**
677 : * Retrieve the current telephone file
678 : * @return AudioLoop* The audio file or 0 if the wav is stopped
679 : */
680 : std::shared_ptr<AudioLoop> getTelephoneFile();
681 :
682 : /**
683 : * @return true is there is one or many incoming call waiting
684 : * new call, not answered or refused
685 : */
686 : bool incomingCallsWaiting();
687 :
688 : /**
689 : * Get the current call
690 : * @return std::shared_ptr<Call> A call shared pointer (could be empty)
691 : */
692 : std::shared_ptr<Call> getCurrentCall() const;
693 :
694 : /**
695 : * Get the current call id
696 : * @return std::string The call id or ""
697 : */
698 : const std::string& getCurrentCallId() const;
699 :
700 : /**
701 : * Check if a call is the current one
702 : * @param call the new call
703 : * @return bool True if the call is the current
704 : */
705 : bool isCurrentCall(const Call& call) const;
706 :
707 : /**
708 : * Load the accounts order set by the user from the jamirc config file
709 : * @return std::vector<std::string> A vector containing the account ID's
710 : */
711 : std::vector<std::string_view> loadAccountOrder() const;
712 :
713 : /**
714 : * Load the account map from configuration
715 : */
716 : int loadAccountMap(const YAML::Node& node);
717 :
718 : /**
719 : * Get the Call referred by callID. If the Call does not exist, return
720 : * empty std::shared_ptr<Call> instance
721 : */
722 : std::shared_ptr<Call> getCallFromCallID(const std::string& callID) const;
723 :
724 : /**
725 : * Return a pointer to the instance of the RingBufferPool
726 : */
727 : RingBufferPool& getRingBufferPool();
728 :
729 : /**
730 : * Tell if there is a current call processed
731 : * @return bool True if there is a current call
732 : */
733 : bool hasCurrentCall() const;
734 :
735 : /**
736 : * Get an account pointer, looks for account of type T
737 : * @param accountID account ID to get
738 : * @return std::shared_ptr<Account> Shared pointer on an Account instance or nullptr if not found
739 : */
740 : template<class T = Account>
741 17932 : inline std::shared_ptr<T> getAccount(std::string_view accountId) const
742 : {
743 17932 : return accountFactory.getAccount<T>(accountId);
744 : }
745 :
746 : /**
747 : * Get a list of account pointers of type T (baseclass Account)
748 : * @return a sorted vector of all accounts of type T
749 : */
750 : template<class T = Account>
751 2940 : std::vector<std::shared_ptr<T>> getAllAccounts() const
752 : {
753 2940 : const auto& account_order = loadAccountOrder();
754 2940 : const auto& all_accounts = accountFactory.getAllAccounts<T>();
755 2940 : std::vector<std::shared_ptr<T>> accountList;
756 2940 : accountList.reserve(all_accounts.size());
757 8197 : for (const auto& id : account_order) {
758 10504 : if (auto acc = accountFactory.getAccount<T>(id))
759 5247 : accountList.emplace_back(std::move(acc));
760 : }
761 8236 : for (auto& account : all_accounts) {
762 5296 : if (std::find(accountList.begin(), accountList.end(), account) == accountList.end())
763 49 : accountList.emplace_back(std::move(account));
764 : }
765 5880 : return accountList;
766 2940 : }
767 :
768 : template<class T = Account>
769 2790 : std::size_t accountCount() const
770 : {
771 2790 : return accountFactory.accountCount<T>();
772 : }
773 :
774 : template<class T>
775 : inline std::shared_ptr<T> findAccount(const std::function<bool(const std::shared_ptr<T>&)>& pred)
776 : {
777 : for (const auto& account : getAllAccounts<T>()) {
778 : if (pred(account))
779 : return account;
780 : }
781 : return {};
782 : }
783 :
784 : // only used by test framework
785 : bool hasAccount(const std::string& accountID);
786 :
787 : /**
788 : * Send registration for all enabled accounts
789 : */
790 : void registerAccounts();
791 :
792 : /**
793 : * Send registration for one account
794 : */
795 : void registerAccount(const std::string& accountID, const std::string& convId = {});
796 :
797 : /**
798 : * Send unregister for all enabled accounts
799 : */
800 : void unregisterAccounts();
801 :
802 : /**
803 : * Create a new outgoing call
804 : * @param toUrl Destination address
805 : * @param accountId local account
806 : * @param mediaList the list of medias
807 : * @return A (shared) pointer of Call class type.
808 : * @note This function raises VoipLinkException() on error.
809 : */
810 : std::shared_ptr<Call> newOutgoingCall(std::string_view toUrl,
811 : const std::string& accountId,
812 : const std::vector<libjami::MediaMap>& mediaList);
813 :
814 : CallFactory callFactory;
815 :
816 : const std::shared_ptr<dhtnet::IceTransportFactory>& getIceTransportFactory();
817 :
818 : std::shared_ptr<asio::io_context> ioContext() const;
819 : std::shared_ptr<dhtnet::upnp::UPnPContext> upnpContext() const;
820 :
821 : ScheduledExecutor& scheduler();
822 : std::shared_ptr<Task> scheduleTask(std::function<void()>&& task,
823 : std::chrono::steady_clock::time_point when,
824 : const char* filename = CURRENT_FILENAME(),
825 : uint32_t linum = CURRENT_LINE());
826 :
827 : std::shared_ptr<Task> scheduleTaskIn(std::function<void()>&& task,
828 : std::chrono::steady_clock::duration timeout,
829 : const char* filename = CURRENT_FILENAME(),
830 : uint32_t linum = CURRENT_LINE());
831 :
832 : std::map<std::string, std::string> getNearbyPeers(const std::string& accountID);
833 :
834 : #ifdef ENABLE_VIDEO
835 : /**
836 : * Create a new SinkClient instance, store it in an internal cache as a weak_ptr
837 : * and return it as a shared_ptr. If a SinkClient is already stored for the given id,
838 : * this method returns this instance.
839 : * @param id SinkClient identifier as a string. Default is empty.
840 : * @param mixer true if the SinkCient is the sink of a VideoMixer node. Default is false.
841 : * @return share_ptr<SinkClient> A shared pointer on the created instance.
842 : */
843 : std::shared_ptr<video::SinkClient> createSinkClient(const std::string& id = "", bool mixer = false);
844 :
845 : /**
846 : * Create a SinkClient instance for each participant in a conference, store it in an internal
847 : * cache as a weak_ptr and populates sinksMap with sink ids and shared_ptrs.
848 : * @param callId
849 : * @param infos ConferenceInfos that will create the sinks
850 : * @param videoStream the the VideoFrameActiveWriter to which the sinks should be attached
851 : * @param sinksMap A map between sink ids and the respective shared pointer.
852 : */
853 : void createSinkClients(const std::string& callId,
854 : const ConfInfo& infos,
855 : const std::vector<std::shared_ptr<video::VideoFrameActiveWriter>>& videoStreams,
856 : std::map<std::string, std::shared_ptr<video::SinkClient>>& sinksMap,
857 : const std::string& accountId = "");
858 :
859 : /**
860 : * Return an existing SinkClient instance as a shared_ptr associated to the given identifier.
861 : * Return an empty shared_ptr (nullptr) if nothing found.
862 : * @param id SinkClient identifier as a string.
863 : * @return share_ptr<SinkClient> A shared pointer on the found instance. Empty if not found.
864 : */
865 : std::shared_ptr<video::SinkClient> getSinkClient(const std::string& id);
866 :
867 : #endif // ENABLE_VIDEO
868 : VideoManager* getVideoManager() const;
869 :
870 : unsigned dhtLogLevel {0}; // default = disable
871 : AccountFactory accountFactory;
872 :
873 : std::vector<libjami::Message> getLastMessages(const std::string& accountID, const uint64_t& base_timestamp);
874 :
875 : SIPVoIPLink& sipVoIPLink() const;
876 : #ifdef ENABLE_PLUGIN
877 : JamiPluginManager& getJamiPluginManager() const;
878 : #endif
879 : /**
880 : * Return current git socket used for a conversation
881 : * @param accountId Related account
882 : * @param deviceId Related device
883 : * @param conversationId Related conversation
884 : * @return std::optional<std::weak_ptr<ChannelSocket>> the related socket
885 : */
886 : std::shared_ptr<dhtnet::ChannelSocket> gitSocket(std::string_view accountId,
887 : std::string_view deviceId,
888 : std::string_view conversationId);
889 :
890 : void setDefaultModerator(const std::string& accountID, const std::string& peerURI, bool state);
891 : std::vector<std::string> getDefaultModerators(const std::string& accountID);
892 : void enableLocalModerators(const std::string& accountID, bool state);
893 : bool isLocalModeratorsEnabled(const std::string& accountID);
894 : void setAllModerators(const std::string& accountID, bool allModerators);
895 : bool isAllModerators(const std::string& accountID);
896 :
897 : void insertGitTransport(git_smart_subtransport* tr, std::unique_ptr<P2PSubTransport>&& sub);
898 : void eraseGitTransport(git_smart_subtransport* tr);
899 :
900 : dhtnet::tls::CertificateStore& certStore(const std::string& accountId) const;
901 :
902 : private:
903 : Manager();
904 : ~Manager();
905 : friend class AudioDeviceGuard;
906 :
907 : // Data members
908 : struct ManagerPimpl;
909 : std::unique_ptr<ManagerPimpl> pimpl_;
910 : };
911 :
912 : class AudioDeviceGuard
913 : {
914 : public:
915 : AudioDeviceGuard(Manager& manager, AudioDeviceType type);
916 : ~AudioDeviceGuard();
917 :
918 : private:
919 : Manager& manager_;
920 : const AudioDeviceType type_;
921 : };
922 :
923 : // Helper to install a callback to be called once by the main event loop
924 : template<typename Callback>
925 : static void
926 12298 : runOnMainThread(Callback&& cb)
927 : {
928 24581 : Manager::instance().scheduler().run([cb = std::forward<Callback>(cb)]() mutable { cb(); });
929 12298 : }
930 :
931 : } // namespace jami
|