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 : #ifndef LIBJAMI_H
18 : #define LIBJAMI_H
19 :
20 : #include "def.h"
21 :
22 : #include <vector>
23 : #include <functional>
24 : #include <string>
25 : #include <map>
26 : #include <memory>
27 : #include <type_traits>
28 : #include <filesystem>
29 :
30 : #include "trace-tools.h"
31 :
32 : namespace libjami {
33 :
34 : /* flags for initialization */
35 : enum InitFlag {
36 : LIBJAMI_FLAG_DEBUG = 1 << 0,
37 : LIBJAMI_FLAG_CONSOLE_LOG = 1 << 1,
38 : LIBJAMI_FLAG_SYSLOG = 1 << 3,
39 : LIBJAMI_FLAG_AUTOANSWER = 1 << 2,
40 : LIBJAMI_FLAG_IOS_EXTENSION = 1 << 4,
41 : LIBJAMI_FLAG_NO_LOCAL_AUDIO = 1 << 6,
42 : LIBJAMI_FLAG_NO_LOCAL_VIDEO = 1 << 7,
43 : LIBJAMI_FLAG_NO_LOCAL_MEDIA = LIBJAMI_FLAG_NO_LOCAL_AUDIO | LIBJAMI_FLAG_NO_LOCAL_VIDEO,
44 : LIBJAMI_FLAG_NO_AUTOSYNC = 1 << 8,
45 : LIBJAMI_FLAG_NO_AUTOLOAD = 1 << 9 // disable auto loading of accounts and conversations
46 : };
47 :
48 : /**
49 : * Return the library version as string.
50 : */
51 : LIBJAMI_PUBLIC const char* version() noexcept;
52 :
53 : /**
54 : * Return the target platform (OS) as a string.
55 : */
56 : LIBJAMI_PUBLIC std::string_view platform() noexcept;
57 :
58 : /**
59 : * Return the target architecture as a string.
60 : */
61 : LIBJAMI_PUBLIC std::string_view arch() noexcept;
62 :
63 : /**
64 : * Initialize globals, create underlaying daemon.
65 : *
66 : * @param flags Flags to customize this initialization
67 : * @returns true if initialization succeed else false.
68 : */
69 : LIBJAMI_PUBLIC bool init(enum InitFlag flags) noexcept;
70 :
71 : /**
72 : * Start asynchronously daemon created by init().
73 : * @returns true if daemon started successfully
74 : */
75 :
76 : LIBJAMI_PUBLIC bool start(const std::filesystem::path& config_file = {}) noexcept;
77 :
78 : /**
79 : * Stop and freeing any resource allocated by daemon
80 : */
81 : LIBJAMI_PUBLIC void fini() noexcept;
82 :
83 : LIBJAMI_PUBLIC bool initialized() noexcept;
84 :
85 : /**
86 : * Control log handlers.
87 : *
88 : * @param whom Log handler to control
89 : */
90 : LIBJAMI_PUBLIC void logging(const std::string& whom, const std::string& action) noexcept;
91 :
92 : /* External Callback Dynamic Utilities
93 : *
94 : * The library provides to users a way to be acknowledged
95 : * when daemon's objects have a state change.
96 : * The user is aware of this changement when the deamon calls
97 : * a user-given callback.
98 : * Daemon handles many of these callbacks, one per event type.
99 : * The user registers his callbacks using registerXXXXHandlers() functions.
100 : * As each callback has its own function signature,
101 : * to keep compatibility over releases we don't let user directly provides
102 : * his callbacks as it or through a structure.
103 : * This way brings ABI violation if we need to change the order
104 : * and/or the existence of any callback type.
105 : * Thus the user have to pass them using following template classes
106 : * and functions, that wraps user-callback in a generic and ABI-compatible way.
107 : */
108 :
109 : /* Generic class to transit user callbacks to daemon library.
110 : * Used conjointly with std::shared_ptr to hide the concrete class.
111 : * See CallbackWrapper template for details.
112 : */
113 : class LIBJAMI_PUBLIC CallbackWrapperBase
114 : {
115 : protected:
116 : // Because post() needs Manager, it should be defined in a .cpp
117 : // so not in a templated class.
118 : // Also we do not want this method to be public in the API.
119 : void post(std::function<void()> cb);
120 : };
121 :
122 : /* Concrete class of CallbackWrapperBase.
123 : * This class wraps callbacks of a specific signature.
124 : * Also used to obtain the user callback from a CallbackWrapperBase shared ptr.
125 : *
126 : * This class is CopyConstructible, CopyAssignable, MoveConstructible
127 : * and MoveAssignable.
128 : */
129 : template<typename TProto>
130 : class CallbackWrapper : public CallbackWrapperBase
131 : {
132 : private:
133 : using TFunc = std::function<TProto>;
134 : TFunc cb_; // The user-callback
135 :
136 : public:
137 : const char* file_;
138 : uint32_t linum_;
139 :
140 : // Empty wrapper: no callback associated.
141 : // Used to initialize internal callback arrays.
142 3627 : CallbackWrapper() noexcept {}
143 :
144 : // Create and initialize a wrapper to given callback.
145 2824 : CallbackWrapper(TFunc&& func, const char* filename, uint32_t linum) noexcept
146 2824 : : cb_(std::forward<TFunc>(func))
147 2824 : , file_(filename)
148 2824 : , linum_(linum)
149 2824 : {}
150 :
151 : // Create and initialize a wrapper from a generic CallbackWrapperBase
152 : // shared pointer.
153 : // Note: the given callback is copied into internal storage.
154 23438 : CallbackWrapper(const std::shared_ptr<CallbackWrapperBase>& p) noexcept
155 23438 : {
156 23438 : if (p) {
157 8203 : auto other = (CallbackWrapper<TProto>*) p.get();
158 :
159 8203 : cb_ = other->cb_;
160 8203 : file_ = other->file_;
161 8203 : linum_ = other->linum_;
162 : }
163 23438 : }
164 :
165 : // Return user-callback reference.
166 : // The returned std::function can be null-initialized if no callback
167 : // has been set.
168 7493 : constexpr const TFunc& operator*() const noexcept { return cb_; }
169 :
170 : // Return boolean true value if a non-null callback has been set
171 23438 : constexpr explicit operator bool() const noexcept { return static_cast<bool>(cb_); }
172 : };
173 :
174 : /* Concrete class of CallbackWrapperBase.
175 : * This class wraps callbacks of a specific signature.
176 : * Used to retrigger callbacks on a io context to avoid lock if signals cannot
177 : * be emitted while a method is called.
178 : * Also used to obtain the user callback from a CallbackWrapperBase shared ptr.
179 : *
180 : * This class is CopyConstructible, CopyAssignable, MoveConstructible
181 : * and MoveAssignable.
182 : */
183 : template<typename TProto>
184 : class SerializedCallbackWrapper : public CallbackWrapperBase
185 : {
186 : private:
187 : using TFunc = std::function<TProto>;
188 : TFunc cb_; // The user-callback
189 :
190 : // This is quite a ugly method used to transmit templated TFunc with their arguments in the
191 : // ioContext of the manager to avoid locks for signals.
192 : template<typename TCallback>
193 : auto ioContextWrapper(TCallback&& fun)
194 : {
195 : return [this, fun {std::move(fun)}](
196 : auto&&... args) -> decltype(fun(std::forward<decltype(args)>(args)...)) {
197 : post([fun {std::move(fun)},
198 : forwardArgs = std::make_tuple(std::move(args)...)]() mutable {
199 : std::apply(std::move(fun), std::move(forwardArgs));
200 : });
201 : };
202 : }
203 :
204 : public:
205 : const char* file_;
206 : uint32_t linum_;
207 :
208 : // Empty wrapper: no callback associated.
209 : // Used to initialize internal callback arrays.
210 : SerializedCallbackWrapper() noexcept {}
211 :
212 : // Create and initialize a wrapper to given callback.
213 : SerializedCallbackWrapper(TFunc&& func, const char* filename, uint32_t linum) noexcept
214 : : file_(filename)
215 : , linum_(linum)
216 : {
217 : cb_ = ioContextWrapper(func);
218 : }
219 :
220 : // Create and initialize a wrapper from a generic CallbackWrapperBase
221 : // shared pointer.
222 : // Note: the given callback is copied into internal storage.
223 : SerializedCallbackWrapper(const std::shared_ptr<CallbackWrapperBase>& p) noexcept
224 : {
225 : if (p) {
226 : auto other = (CallbackWrapper<TProto>*) p.get();
227 :
228 : cb_ = ioContextWrapper(other.cb_);
229 : file_ = other->file_;
230 : linum_ = other->linum_;
231 : }
232 : }
233 :
234 : // Return user-callback reference.
235 : // The returned std::function can be null-initialized if no callback
236 : // has been set.
237 : constexpr const TFunc& operator*() const noexcept { return cb_; }
238 :
239 : // Return boolean true value if a non-null callback has been set
240 : constexpr explicit operator bool() const noexcept { return static_cast<bool>(cb_); }
241 : };
242 :
243 : /**
244 : * Return an exportable callback object.
245 : * This object is a std::pair of a string and a CallbackWrapperBase shared_ptr.
246 : * This last wraps given callback in a ABI-compatible way.
247 : * Note: this version accepts callbacks as rvalue only.
248 : */
249 : template<typename Ts>
250 : std::pair<std::string, std::shared_ptr<CallbackWrapperBase>>
251 2824 : exportable_callback(std::function<typename Ts::cb_type>&& func,
252 : const char* file = CURRENT_FILENAME(),
253 : uint32_t linum = CURRENT_LINE())
254 : {
255 : return std::make_pair((const std::string&) Ts::name,
256 : std::make_shared<CallbackWrapper<typename Ts::cb_type>>(
257 2824 : std::forward<std::function<typename Ts::cb_type>>(func), file, linum));
258 : }
259 :
260 : template<typename Ts>
261 : std::pair<std::string, std::shared_ptr<CallbackWrapperBase>>
262 : exportable_serialized_callback(std::function<typename Ts::cb_type>&& func,
263 : const char* file = CURRENT_FILENAME(),
264 : uint32_t linum = CURRENT_LINE())
265 : {
266 : return std::make_pair((const std::string&) Ts::name,
267 : std::make_shared<SerializedCallbackWrapper<typename Ts::cb_type>>(
268 : std::forward<std::function<typename Ts::cb_type>>(func), file, linum));
269 : }
270 :
271 : LIBJAMI_PUBLIC void registerSignalHandlers(
272 : const std::map<std::string, std::shared_ptr<CallbackWrapperBase>>&);
273 : LIBJAMI_PUBLIC void unregisterSignalHandlers();
274 :
275 : using MediaMap = std::map<std::string, std::string>;
276 :
277 : } // namespace libjami
278 :
279 : #endif /* LIBJAMI_H */
|