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