From 5cab4fa7934d816792e9a2f985e61dcc4e80ea36 Mon Sep 17 00:00:00 2001 From: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com> Date: Tue, 14 Feb 2017 23:49:18 -0500 Subject: [PATCH] manager: refactor of joinParticipant method - decrease cyclomatic complexity of joinParticipant by factoring conference binding code and removing unneeded createConference method. - move the ConferenceCreated signal at the right place in the flow (i.e. last in sequence). Based on a proposition from zinspierre <zins.pierre@gmail.com> and al. in part of the course LOG8430 (Polytechnique Montreal). Thanks to them. Change-Id: I55203cc400496cd679c4f157d765aee0dec9c4f8 Reviewed-by: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com> --- src/manager.cpp | 120 +++++++++++++++++------------------------------- src/manager.h | 10 +--- 2 files changed, 45 insertions(+), 85 deletions(-) diff --git a/src/manager.cpp b/src/manager.cpp index c67858f57d..ccafe6ae34 100644 --- a/src/manager.cpp +++ b/src/manager.cpp @@ -804,24 +804,6 @@ Manager::refuseCall(const std::string& id) return true; } -std::shared_ptr<Conference> -Manager::createConference(const std::string& id1, const std::string& id2) -{ - RING_DBG("Create conference with call %s and %s", id1.c_str(), id2.c_str()); - - auto conf = std::make_shared<Conference>(); - - conf->add(id1); - conf->add(id2); - - // Add conference to map - conferenceMap_.insert(std::make_pair(conf->getConfID(), conf)); - - emitSignal<DRing::CallSignal::ConferenceCreated>(conf->getConfID()); - - return conf; -} - void Manager::removeConference(const std::string& conference_id) { @@ -1074,9 +1056,42 @@ Manager::getCallFromCallID(const std::string& callID) const return callFactory.getCall(callID); } +void +Manager::bindCallToConference(Call& call, Conference& conf) +{ + const auto& call_id = call.getCallId(); + const auto& conf_id = conf.getConfID(); + const auto& state = call.getStateStr(); + + // ensure that calls are only in one conference at a time + if (isConferenceParticipant(call_id)) + detachParticipant(call_id); + + RING_DBG("[call:%s] bind to conference %s (callState=%s)", + call_id.c_str(), conf_id.c_str(), state.c_str()); + + getRingBufferPool().unBindAll(call_id); + + conf.add(call_id); + call.setConfId(conf_id); + + if (state == "HOLD") { + conf.bindParticipant(call_id); + offHoldCall(call_id); + } else if (state == "INCOMING") { + conf.bindParticipant(call_id); + answerCall(call_id); + } else if (state == "CURRENT") { + conf.bindParticipant(call_id); + } else if (state == "INACTIVE") { + conf.bindParticipant(call_id); + answerCall(call_id); + } else + RING_WARN("[call:%s] call state %s not recognized for conference", call_id.c_str()); +} + bool -Manager::joinParticipant(const std::string& callId1, - const std::string& callId2) +Manager::joinParticipant(const std::string& callId1, const std::string& callId2) { if (callId1 == callId2) { RING_ERR("Cannot join participant %s to itself", callId1.c_str()); @@ -1097,71 +1112,20 @@ Manager::joinParticipant(const std::string& callId1, return false; } - // ensure that calls are only in one conference at a time - if (isConferenceParticipant(callId1)) - detachParticipant(callId1); - if (isConferenceParticipant(callId2)) - detachParticipant(callId2); - - std::map<std::string, std::string> call1Details(getCallDetails(callId1)); - std::map<std::string, std::string> call2Details(getCallDetails(callId2)); - - std::string current_call_id(getCurrentCallId()); - RING_DBG("Current Call ID %s", current_call_id.c_str()); - - // detach from the conference and switch to this conference + // detach/hold current active call if it's not a participant + auto current_call_id = getCurrentCallId(); if ((current_call_id != callId1) and (current_call_id != callId2)) { - // If currently in a conference if (isConference(current_call_id)) detachParticipant(RingBufferPool::DEFAULT_ID); else onHoldCall(current_call_id); // currently in a call } + auto conf = std::make_shared<Conference>(); - auto conf = createConference(callId1, callId2); - - call1->setConfId(conf->getConfID()); - getRingBufferPool().unBindAll(callId1); - - call2->setConfId(conf->getConfID()); - getRingBufferPool().unBindAll(callId2); - - // Process call1 according to its state - std::string call1_state_str(call1Details.find("CALL_STATE")->second); - RING_DBG("Process call %s state: %s", callId1.c_str(), call1_state_str.c_str()); - - if (call1_state_str == "HOLD") { - conf->bindParticipant(callId1); - offHoldCall(callId1); - } else if (call1_state_str == "INCOMING") { - conf->bindParticipant(callId1); - answerCall(callId1); - } else if (call1_state_str == "CURRENT") { - conf->bindParticipant(callId1); - } else if (call1_state_str == "INACTIVE") { - conf->bindParticipant(callId1); - answerCall(callId1); - } else - RING_WARN("Call state not recognized"); - - // Process call2 according to its state - std::string call2_state_str(call2Details.find("CALL_STATE")->second); - RING_DBG("Process call %s state: %s", callId2.c_str(), call2_state_str.c_str()); - - if (call2_state_str == "HOLD") { - conf->bindParticipant(callId2); - offHoldCall(callId2); - } else if (call2_state_str == "INCOMING") { - conf->bindParticipant(callId2); - answerCall(callId2); - } else if (call2_state_str == "CURRENT") { - conf->bindParticipant(callId2); - } else if (call2_state_str == "INACTIVE") { - conf->bindParticipant(callId2); - answerCall(callId2); - } else - RING_WARN("Call state not recognized"); + // Bind calls according to their state + bindCallToConference(*call1, *conf); + bindCallToConference(*call2, *conf); // Switch current call id to this conference switchCall(conf->getConfID()); @@ -1170,6 +1134,8 @@ Manager::joinParticipant(const std::string& callId1, // set recording sampling rate conf->setRecordingAudioFormat(ringbufferpool_->getInternalAudioFormat()); + conferenceMap_.insert(std::make_pair(conf->getConfID(), conf)); + emitSignal<DRing::CallSignal::ConferenceCreated>(conf->getConfID()); return true; } diff --git a/src/manager.h b/src/manager.h index aaaba6e92a..7c5227c489 100644 --- a/src/manager.h +++ b/src/manager.h @@ -237,14 +237,6 @@ class Manager { */ bool refuseCall(const std::string& id); - /** - * Create a new conference given two participant - * @param the first participant ID - * @param the second participant ID - */ - std::shared_ptr<Conference> - createConference(const std::string& id1, const std::string& id2); - /** * Delete this conference * @param the conference ID @@ -1079,6 +1071,8 @@ class Manager { #ifdef RING_VIDEO std::unique_ptr<VideoManager> videoManager_; #endif + + void bindCallToConference(Call& call, Conference& conf); }; // Helper to install a callback to be called once by the main event loop -- GitLab