Line data Source code
1 : /* 2 : * Copyright (C) 2004-2024 Savoir-faire Linux Inc. 3 : * 4 : * Author: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com> 5 : * 6 : * This program is free software; you can redistribute it and/or modify 7 : * it under the terms of the GNU General Public License as published by 8 : * the Free Software Foundation; either version 3 of the License, or 9 : * (at your option) any later version. 10 : * 11 : * This program is distributed in the hope that it will be useful, 12 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 : * GNU General Public License for more details. 15 : * 16 : * You should have received a copy of the GNU General Public License 17 : * along with this program; if not, write to the Free Software 18 : * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 : */ 20 : 21 : #include <stdexcept> 22 : 23 : #include "call_factory.h" 24 : #include "sip/sipcall.h" 25 : #include "sip/sipaccountbase.h" 26 : #include "string_utils.h" 27 : 28 : namespace jami { 29 : 30 : // generate something like 7ea037947eb9fb2f 31 : std::string 32 440 : CallFactory::getNewCallID() const 33 : { 34 440 : std::string random_id; 35 : do { 36 880 : random_id = std::to_string( 37 880 : std::uniform_int_distribution<uint64_t>(1, JAMI_ID_MAX_VAL)(rand_)); 38 440 : } while (hasCall(random_id)); 39 440 : return random_id; 40 0 : } 41 : 42 : std::shared_ptr<SIPCall> 43 406 : CallFactory::newSipCall(const std::shared_ptr<SIPAccountBase>& account, 44 : Call::CallType type, 45 : const std::vector<libjami::MediaMap>& mediaList) 46 : { 47 406 : if (not allowNewCall_) { 48 0 : JAMI_WARN("Creation of new calls is not allowed"); 49 0 : return {}; 50 : } 51 : 52 406 : std::lock_guard lk(callMapsMutex_); 53 406 : auto id = getNewCallID(); 54 406 : auto call = std::make_shared<SIPCall>(account, id, type, mediaList); 55 406 : callMaps_[call->getLinkType()].emplace(id, call); 56 406 : account->attach(call); 57 406 : return call; 58 406 : } 59 : 60 : void 61 38 : CallFactory::forbid() 62 : { 63 38 : allowNewCall_ = false; 64 38 : } 65 : 66 : void 67 420 : CallFactory::removeCall(Call& call) 68 : { 69 420 : std::lock_guard lk(callMapsMutex_); 70 : 71 420 : const auto& id = call.getCallId(); 72 420 : JAMI_DBG("Removing call %s", id.c_str()); 73 420 : auto& map = callMaps_.at(call.getLinkType()); 74 420 : map.erase(id); 75 420 : JAMI_DBG("Remaining %zu call", map.size()); 76 420 : } 77 : 78 : void 79 0 : CallFactory::removeCall(const std::string& id) 80 : { 81 0 : std::lock_guard lk(callMapsMutex_); 82 : 83 0 : if (auto call = getCall(id)) { 84 0 : removeCall(*call); 85 : } else 86 0 : JAMI_ERR("No call with ID %s", id.c_str()); 87 0 : } 88 : 89 : bool 90 440 : CallFactory::hasCall(const std::string& id) const 91 : { 92 440 : std::lock_guard lk(callMapsMutex_); 93 : 94 867 : for (const auto& item : callMaps_) { 95 427 : const auto& map = item.second; 96 427 : if (map.find(id) != map.cend()) 97 0 : return true; 98 : } 99 : 100 440 : return false; 101 440 : } 102 : 103 : bool 104 0 : CallFactory::empty() const 105 : { 106 0 : std::lock_guard lk(callMapsMutex_); 107 : 108 0 : for (const auto& item : callMaps_) { 109 0 : if (not item.second.empty()) 110 0 : return false; 111 : } 112 : 113 0 : return true; 114 0 : } 115 : 116 : void 117 39 : CallFactory::clear() 118 : { 119 39 : std::lock_guard lk(callMapsMutex_); 120 39 : callMaps_.clear(); 121 39 : } 122 : 123 : std::shared_ptr<Call> 124 1532 : CallFactory::getCall(const std::string& id) const 125 : { 126 1532 : std::lock_guard lk(callMapsMutex_); 127 : 128 1552 : for (const auto& item : callMaps_) { 129 1532 : const auto& map = item.second; 130 1532 : const auto& iter = map.find(id); 131 1532 : if (iter != map.cend()) 132 1512 : return iter->second; 133 : } 134 : 135 20 : return nullptr; 136 1532 : } 137 : 138 : std::vector<std::shared_ptr<Call>> 139 336 : CallFactory::getAllCalls() const 140 : { 141 336 : std::lock_guard lk(callMapsMutex_); 142 336 : std::vector<std::shared_ptr<Call>> v; 143 : 144 647 : for (const auto& itemmap : callMaps_) { 145 311 : const auto& map = itemmap.second; 146 311 : v.reserve(v.size() + map.size()); 147 1794 : for (const auto& item : map) 148 1483 : v.push_back(item.second); 149 : } 150 : 151 672 : return v; 152 336 : } 153 : 154 : std::vector<std::string> 155 0 : CallFactory::getCallIDs() const 156 : { 157 0 : std::vector<std::string> v; 158 : 159 0 : for (const auto& item : callMaps_) { 160 0 : const auto& map = item.second; 161 0 : for (const auto& it : map) 162 0 : v.push_back(it.first); 163 : } 164 : 165 0 : v.shrink_to_fit(); 166 0 : return v; 167 0 : } 168 : 169 : std::size_t 170 38 : CallFactory::callCount() const 171 : { 172 38 : std::lock_guard lk(callMapsMutex_); 173 38 : std::size_t count = 0; 174 : 175 51 : for (const auto& itemmap : callMaps_) 176 13 : count += itemmap.second.size(); 177 : 178 38 : return count; 179 38 : } 180 : 181 : bool 182 0 : CallFactory::hasCall(const std::string& id, Call::LinkType link) const 183 : { 184 0 : std::lock_guard lk(callMapsMutex_); 185 : 186 0 : auto const map = getMap_(link); 187 0 : return map and map->find(id) != map->cend(); 188 0 : } 189 : 190 : bool 191 33 : CallFactory::empty(Call::LinkType link) const 192 : { 193 33 : std::lock_guard lk(callMapsMutex_); 194 : 195 33 : const auto map = getMap_(link); 196 66 : return !map or map->empty(); 197 33 : } 198 : 199 : std::shared_ptr<Call> 200 2 : CallFactory::getCall(const std::string& id, Call::LinkType link) const 201 : { 202 2 : std::lock_guard lk(callMapsMutex_); 203 : 204 2 : const auto map = getMap_(link); 205 2 : if (!map) 206 0 : return nullptr; 207 : 208 2 : const auto& it = map->find(id); 209 2 : if (it == map->cend()) 210 0 : return nullptr; 211 : 212 2 : return it->second; 213 2 : } 214 : 215 : std::vector<std::shared_ptr<Call>> 216 0 : CallFactory::getAllCalls(Call::LinkType link) const 217 : { 218 0 : std::lock_guard lk(callMapsMutex_); 219 0 : std::vector<std::shared_ptr<Call>> v; 220 : 221 0 : const auto map = getMap_(link); 222 0 : if (map) { 223 0 : for (const auto& it : *map) 224 0 : v.push_back(it.second); 225 : } 226 : 227 0 : v.shrink_to_fit(); 228 0 : return v; 229 0 : } 230 : 231 : std::vector<std::string> 232 0 : CallFactory::getCallIDs(Call::LinkType link) const 233 : { 234 0 : std::lock_guard lk(callMapsMutex_); 235 0 : std::vector<std::string> v; 236 : 237 0 : const auto map = getMap_(link); 238 0 : if (map) { 239 0 : for (const auto& it : *map) 240 0 : v.push_back(it.first); 241 : } 242 : 243 0 : v.shrink_to_fit(); 244 0 : return v; 245 0 : } 246 : 247 : std::size_t 248 0 : CallFactory::callCount(Call::LinkType link) const 249 : { 250 0 : std::lock_guard lk(callMapsMutex_); 251 : 252 0 : const auto map = getMap_(link); 253 0 : if (!map) 254 0 : return 0; 255 : 256 0 : return map->size(); 257 0 : } 258 : 259 : } // namespace jami