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 : 18 : #include "call_factory.h" 19 : #include "sip/sipcall.h" 20 : #include "sip/sipaccountbase.h" 21 : 22 : namespace jami { 23 : 24 : // generate something like 7ea037947eb9fb2f 25 : std::string 26 401 : CallFactory::getNewCallID() const 27 : { 28 401 : std::string random_id; 29 : do { 30 401 : random_id = std::to_string(std::uniform_int_distribution<uint64_t>(1, JAMI_ID_MAX_VAL)(rand_)); 31 401 : } while (hasCall(random_id)); 32 401 : return random_id; 33 0 : } 34 : 35 : std::shared_ptr<SIPCall> 36 367 : CallFactory::newSipCall(const std::shared_ptr<SIPAccountBase>& account, 37 : Call::CallType type, 38 : const std::vector<libjami::MediaMap>& mediaList) 39 : { 40 367 : if (not allowNewCall_) { 41 0 : JAMI_WARN("Creation of new calls is not allowed"); 42 0 : return {}; 43 : } 44 : 45 367 : std::lock_guard lk(callMapsMutex_); 46 367 : auto id = getNewCallID(); 47 367 : auto call = std::make_shared<SIPCall>(account, id, type, mediaList); 48 367 : callMaps_[call->getLinkType()].emplace(id, call); 49 367 : account->attach(call); 50 367 : return call; 51 367 : } 52 : 53 : void 54 38 : CallFactory::forbid() 55 : { 56 38 : allowNewCall_ = false; 57 38 : } 58 : 59 : void 60 383 : CallFactory::removeCall(Call& call) 61 : { 62 383 : std::lock_guard lk(callMapsMutex_); 63 : 64 383 : const auto& id = call.getCallId(); 65 383 : JAMI_DBG("Removing call %s", id.c_str()); 66 383 : auto& map = callMaps_.at(call.getLinkType()); 67 383 : map.erase(id); 68 383 : JAMI_DBG("Remaining %zu call", map.size()); 69 383 : } 70 : 71 : void 72 0 : CallFactory::removeCall(const std::string& id) 73 : { 74 0 : std::lock_guard lk(callMapsMutex_); 75 : 76 0 : if (auto call = getCall(id)) { 77 0 : removeCall(*call); 78 : } else 79 0 : JAMI_ERR("No call with ID %s", id.c_str()); 80 0 : } 81 : 82 : bool 83 401 : CallFactory::hasCall(const std::string& id) const 84 : { 85 401 : std::lock_guard lk(callMapsMutex_); 86 : 87 789 : for (const auto& item : callMaps_) { 88 388 : const auto& map = item.second; 89 388 : if (map.find(id) != map.cend()) 90 0 : return true; 91 : } 92 : 93 401 : return false; 94 401 : } 95 : 96 : bool 97 0 : CallFactory::empty() const 98 : { 99 0 : std::lock_guard lk(callMapsMutex_); 100 : 101 0 : for (const auto& item : callMaps_) { 102 0 : if (not item.second.empty()) 103 0 : return false; 104 : } 105 : 106 0 : return true; 107 0 : } 108 : 109 : void 110 39 : CallFactory::clear() 111 : { 112 39 : std::lock_guard lk(callMapsMutex_); 113 39 : callMaps_.clear(); 114 39 : } 115 : 116 : std::shared_ptr<Call> 117 1532 : CallFactory::getCall(const std::string& id) const 118 : { 119 1532 : std::lock_guard lk(callMapsMutex_); 120 : 121 1608 : for (const auto& item : callMaps_) { 122 1531 : const auto& map = item.second; 123 1531 : const auto& iter = map.find(id); 124 1531 : if (iter != map.cend()) 125 1455 : return iter->second; 126 : } 127 : 128 77 : return nullptr; 129 1532 : } 130 : 131 : std::vector<std::shared_ptr<Call>> 132 315 : CallFactory::getAllCalls() const 133 : { 134 315 : std::lock_guard lk(callMapsMutex_); 135 315 : std::vector<std::shared_ptr<Call>> v; 136 : 137 602 : for (const auto& itemmap : callMaps_) { 138 287 : const auto& map = itemmap.second; 139 287 : v.reserve(v.size() + map.size()); 140 1666 : for (const auto& item : map) 141 1379 : v.push_back(item.second); 142 : } 143 : 144 630 : return v; 145 315 : } 146 : 147 : std::vector<std::string> 148 0 : CallFactory::getCallIDs() const 149 : { 150 0 : std::vector<std::string> v; 151 : 152 0 : for (const auto& item : callMaps_) { 153 0 : const auto& map = item.second; 154 0 : for (const auto& it : map) 155 0 : v.push_back(it.first); 156 : } 157 : 158 0 : v.shrink_to_fit(); 159 0 : return v; 160 0 : } 161 : 162 : std::size_t 163 38 : CallFactory::callCount() const 164 : { 165 38 : std::lock_guard lk(callMapsMutex_); 166 38 : std::size_t count = 0; 167 : 168 48 : for (const auto& itemmap : callMaps_) 169 10 : count += itemmap.second.size(); 170 : 171 38 : return count; 172 38 : } 173 : 174 : bool 175 0 : CallFactory::hasCall(const std::string& id, Call::LinkType link) const 176 : { 177 0 : std::lock_guard lk(callMapsMutex_); 178 : 179 0 : const auto* const map = getMap_(link); 180 0 : return map and map->find(id) != map->cend(); 181 0 : } 182 : 183 : bool 184 32 : CallFactory::empty(Call::LinkType link) const 185 : { 186 32 : std::lock_guard lk(callMapsMutex_); 187 : 188 32 : const auto* const map = getMap_(link); 189 64 : return !map or map->empty(); 190 32 : } 191 : 192 : std::shared_ptr<Call> 193 0 : CallFactory::getCall(const std::string& id, Call::LinkType link) const 194 : { 195 0 : std::lock_guard lk(callMapsMutex_); 196 : 197 0 : const auto* const map = getMap_(link); 198 0 : if (!map) 199 0 : return nullptr; 200 : 201 0 : const auto& it = map->find(id); 202 0 : if (it == map->cend()) 203 0 : return nullptr; 204 : 205 0 : return it->second; 206 0 : } 207 : 208 : std::vector<std::shared_ptr<Call>> 209 0 : CallFactory::getAllCalls(Call::LinkType link) const 210 : { 211 0 : std::lock_guard lk(callMapsMutex_); 212 0 : std::vector<std::shared_ptr<Call>> v; 213 : 214 0 : const auto* const map = getMap_(link); 215 0 : if (map) { 216 0 : for (const auto& it : *map) 217 0 : v.push_back(it.second); 218 : } 219 : 220 0 : v.shrink_to_fit(); 221 0 : return v; 222 0 : } 223 : 224 : std::vector<std::string> 225 0 : CallFactory::getCallIDs(Call::LinkType link) const 226 : { 227 0 : std::lock_guard lk(callMapsMutex_); 228 0 : std::vector<std::string> v; 229 : 230 0 : const auto* const map = getMap_(link); 231 0 : if (map) { 232 0 : for (const auto& it : *map) 233 0 : v.push_back(it.first); 234 : } 235 : 236 0 : v.shrink_to_fit(); 237 0 : return v; 238 0 : } 239 : 240 : std::size_t 241 0 : CallFactory::callCount(Call::LinkType link) const 242 : { 243 0 : std::lock_guard lk(callMapsMutex_); 244 : 245 0 : const auto* const map = getMap_(link); 246 0 : if (!map) 247 0 : return 0; 248 : 249 0 : return map->size(); 250 0 : } 251 : 252 : } // namespace jami