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 3420 : CallbackWrapper() noexcept {} 143 : 144 : // Create and initialize a wrapper to given callback. 145 3525 : CallbackWrapper(TFunc&& func, const char* filename, uint32_t linum) noexcept 146 3525 : : cb_(std::forward<TFunc>(func)) 147 3525 : , file_(filename) 148 3525 : , linum_(linum) 149 3525 : {} 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 27664 : CallbackWrapper(const std::shared_ptr<CallbackWrapperBase>& p) noexcept 155 27664 : { 156 27664 : if (p) { 157 8749 : auto other = (CallbackWrapper<TProto>*) p.get(); 158 : 159 8749 : cb_ = other->cb_; 160 8749 : file_ = other->file_; 161 8749 : linum_ = other->linum_; 162 : } 163 27664 : } 164 : 165 : // Return user-callback reference. 166 : // The returned std::function can be null-initialized if no callback 167 : // has been set. 168 8126 : constexpr const TFunc& operator*() const noexcept { return cb_; } 169 : 170 : // Return boolean true value if a non-null callback has been set 171 27664 : 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)}](auto&&... args) -> decltype(fun(std::forward<decltype(args)>(args)...)) { 196 : post([fun {std::move(fun)}, forwardArgs = std::make_tuple(std::move(args)...)]() mutable { 197 : std::apply(std::move(fun), std::move(forwardArgs)); 198 : }); 199 : }; 200 : } 201 : 202 : public: 203 : const char* file_; 204 : uint32_t linum_; 205 : 206 : // Empty wrapper: no callback associated. 207 : // Used to initialize internal callback arrays. 208 : SerializedCallbackWrapper() noexcept {} 209 : 210 : // Create and initialize a wrapper to given callback. 211 : SerializedCallbackWrapper(TFunc&& func, const char* filename, uint32_t linum) noexcept 212 : : file_(filename) 213 : , linum_(linum) 214 : { 215 : cb_ = ioContextWrapper(func); 216 : } 217 : 218 : // Create and initialize a wrapper from a generic CallbackWrapperBase 219 : // shared pointer. 220 : // Note: the given callback is copied into internal storage. 221 : SerializedCallbackWrapper(const std::shared_ptr<CallbackWrapperBase>& p) noexcept 222 : { 223 : if (p) { 224 : auto other = (CallbackWrapper<TProto>*) p.get(); 225 : 226 : cb_ = ioContextWrapper(other.cb_); 227 : file_ = other->file_; 228 : linum_ = other->linum_; 229 : } 230 : } 231 : 232 : // Return user-callback reference. 233 : // The returned std::function can be null-initialized if no callback 234 : // has been set. 235 : constexpr const TFunc& operator*() const noexcept { return cb_; } 236 : 237 : // Return boolean true value if a non-null callback has been set 238 : constexpr explicit operator bool() const noexcept { return static_cast<bool>(cb_); } 239 : }; 240 : 241 : /** 242 : * Return an exportable callback object. 243 : * This object is a std::pair of a string and a CallbackWrapperBase shared_ptr. 244 : * This last wraps given callback in a ABI-compatible way. 245 : * Note: this version accepts callbacks as rvalue only. 246 : */ 247 : template<typename Ts> 248 : std::pair<std::string, std::shared_ptr<CallbackWrapperBase>> 249 3525 : exportable_callback(std::function<typename Ts::cb_type>&& func, 250 : const char* file = CURRENT_FILENAME(), 251 : uint32_t linum = CURRENT_LINE()) 252 : { 253 : return std::make_pair((const std::string&) Ts::name, 254 : std::make_shared<CallbackWrapper<typename Ts::cb_type>>( 255 3525 : std::forward<std::function<typename Ts::cb_type>>(func), file, linum)); 256 : } 257 : 258 : template<typename Ts> 259 : std::pair<std::string, std::shared_ptr<CallbackWrapperBase>> 260 : exportable_serialized_callback(std::function<typename Ts::cb_type>&& func, 261 : const char* file = CURRENT_FILENAME(), 262 : uint32_t linum = CURRENT_LINE()) 263 : { 264 : return std::make_pair((const std::string&) Ts::name, 265 : std::make_shared<SerializedCallbackWrapper<typename Ts::cb_type>>( 266 : std::forward<std::function<typename Ts::cb_type>>(func), file, linum)); 267 : } 268 : 269 : LIBJAMI_PUBLIC void registerSignalHandlers(const std::map<std::string, std::shared_ptr<CallbackWrapperBase>>&); 270 : LIBJAMI_PUBLIC void unregisterSignalHandlers(); 271 : 272 : using MediaMap = std::map<std::string, std::string>; 273 : 274 : } // namespace libjami 275 : 276 : #endif /* LIBJAMI_H */