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