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