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 150 : CallFactory::getNewCallID() const 27 : { 28 150 : std::string random_id; 29 : do { 30 150 : random_id = std::to_string(std::uniform_int_distribution<uint64_t>(1, JAMI_ID_MAX_VAL)(rand_)); 31 150 : } while (hasCall(random_id)); 32 150 : return random_id; 33 0 : } 34 : 35 : std::shared_ptr<SIPCall> 36 139 : CallFactory::newSipCall(const std::shared_ptr<SIPAccountBase>& account, 37 : Call::CallType type, 38 : const std::vector<libjami::MediaMap>& mediaList) 39 : { 40 139 : if (not allowNewCall_) { 41 0 : JAMI_WARN("Creation of new calls is not allowed"); 42 0 : return {}; 43 : } 44 : 45 139 : std::lock_guard lk(callMapsMutex_); 46 139 : auto id = getNewCallID(); 47 139 : auto call = std::make_shared<SIPCall>(account, id, type, mediaList); 48 139 : callMaps_[call->getLinkType()].emplace(id, call); 49 139 : account->attach(call); 50 139 : return call; 51 139 : } 52 : 53 : void 54 37 : CallFactory::forbid() 55 : { 56 37 : allowNewCall_ = false; 57 37 : } 58 : 59 : void 60 149 : CallFactory::removeCall(Call& call) 61 : { 62 149 : std::lock_guard lk(callMapsMutex_); 63 : 64 149 : const auto& id = call.getCallId(); 65 149 : JAMI_DBG("Removing call %s", id.c_str()); 66 149 : auto& map = callMaps_.at(call.getLinkType()); 67 149 : map.erase(id); 68 149 : JAMI_DBG("Remaining %zu call", map.size()); 69 149 : } 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 150 : CallFactory::hasCall(const std::string& id) const 84 : { 85 150 : std::lock_guard lk(callMapsMutex_); 86 : 87 288 : for (const auto& item : callMaps_) { 88 138 : const auto& map = item.second; 89 138 : if (map.find(id) != map.cend()) 90 0 : return true; 91 : } 92 : 93 150 : return false; 94 150 : } 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 38 : CallFactory::clear() 111 : { 112 38 : std::lock_guard lk(callMapsMutex_); 113 38 : callMaps_.clear(); 114 38 : } 115 : 116 : std::shared_ptr<Call> 117 542 : CallFactory::getCall(const std::string& id) const 118 : { 119 542 : std::lock_guard lk(callMapsMutex_); 120 : 121 560 : for (const auto& item : callMaps_) { 122 541 : const auto& map = item.second; 123 541 : const auto& iter = map.find(id); 124 541 : if (iter != map.cend()) 125 523 : return iter->second; 126 : } 127 : 128 19 : return nullptr; 129 542 : } 130 : 131 : std::vector<std::shared_ptr<Call>> 132 132 : CallFactory::getAllCalls() const 133 : { 134 132 : std::lock_guard lk(callMapsMutex_); 135 132 : std::vector<std::shared_ptr<Call>> v; 136 : 137 236 : for (const auto& itemmap : callMaps_) { 138 104 : const auto& map = itemmap.second; 139 104 : v.reserve(v.size() + map.size()); 140 435 : for (const auto& item : map) 141 331 : v.push_back(item.second); 142 : } 143 : 144 264 : return v; 145 132 : } 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 37 : CallFactory::callCount() const 164 : { 165 37 : std::lock_guard lk(callMapsMutex_); 166 37 : std::size_t count = 0; 167 : 168 46 : for (const auto& itemmap : callMaps_) 169 9 : count += itemmap.second.size(); 170 : 171 37 : return count; 172 37 : } 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 31 : CallFactory::empty(Call::LinkType link) const 185 : { 186 31 : std::lock_guard lk(callMapsMutex_); 187 : 188 31 : const auto* const map = getMap_(link); 189 62 : return !map or map->empty(); 190 31 : } 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