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