1/*
2 * Copyright (C) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "cs_conference.h"
17
18#include <string>
19#include <string_ex.h>
20#include <list>
21
22#include "call_base.h"
23#include "call_object_manager.h"
24#include "call_manager_errors.h"
25#include "telephony_log_wrapper.h"
26#include "call_manager_inner_type.h"
27
28namespace OHOS {
29namespace Telephony {
30CsConference::CsConference() : ConferenceBase()
31{
32    conferenceType_ = CallType::TYPE_CS;
33    maxSubCallLimits_ = CS_CONFERENCE_MAX_CALLS_CNT;
34    // get from configuration file
35#ifdef ABILITY_CONFIG_SUPPORT
36    maxSubCallLimits_ = GetConfig(CS_CONFERENCE_SUB_CALL_LIMITS);
37#endif
38}
39
40CsConference::~CsConference() {}
41
42int32_t CsConference::JoinToConference(int32_t callId)
43{
44    std::lock_guard<std::mutex> lock(conferenceMutex_);
45    if (state_ != CONFERENCE_STATE_CREATING && state_ != CONFERENCE_STATE_ACTIVE &&
46        state_ != CONFERENCE_STATE_LEAVING && state_ != CONFERENCE_STATE_HOLDING) {
47        TELEPHONY_LOGE("the current conference status does not allow CombineConference");
48        return CALL_ERR_ILLEGAL_CALL_OPERATION;
49    }
50    subCallIdSet_.insert(callId);
51    state_ = CONFERENCE_STATE_ACTIVE;
52    oldState_ = state_;
53    beginTime_ = time(nullptr);
54    return TELEPHONY_SUCCESS;
55}
56
57int32_t CsConference::LeaveFromConference(int32_t callId)
58{
59    std::lock_guard<std::mutex> lock(conferenceMutex_);
60    if (subCallIdSet_.find(callId) != subCallIdSet_.end()) {
61        subCallIdSet_.erase(callId);
62        if (mainCallId_ == callId) {
63            mainCallId_ = *subCallIdSet_.begin();
64        }
65    } else {
66        TELEPHONY_LOGE("leave conference failed, callId %{public}d not in conference", callId);
67        return CALL_ERR_CONFERENCE_SEPERATE_FAILED;
68    }
69    if (subCallIdSet_.empty()) {
70        mainCallId_ = ERR_ID;
71        state_ = CONFERENCE_STATE_IDLE;
72        oldState_ = state_;
73        beginTime_ = 0;
74    }
75    return TELEPHONY_SUCCESS;
76}
77
78int32_t CsConference::HoldConference(int32_t callId)
79{
80    std::lock_guard<std::mutex> lock(conferenceMutex_);
81    if (state_ == CONFERENCE_STATE_HOLDING) {
82        TELEPHONY_LOGI("HoldConference success");
83        return TELEPHONY_SUCCESS;
84    }
85    if (subCallIdSet_.find(callId) == subCallIdSet_.end()) {
86        TELEPHONY_LOGE("separate conference failed, callId %{public}d not in conference", callId);
87        return CALL_ERR_CONFERENCE_SEPERATE_FAILED;
88    }
89    if (subCallIdSet_.empty()) {
90        mainCallId_ = ERR_ID;
91        state_ = CONFERENCE_STATE_IDLE;
92        oldState_ = state_;
93        beginTime_ = 0;
94        return CALL_ERR_CONFERENCE_SEPERATE_FAILED;
95    }
96    state_ = CONFERENCE_STATE_HOLDING;
97    oldState_ = state_;
98    return TELEPHONY_SUCCESS;
99}
100
101int32_t CsConference::CanCombineConference()
102{
103    std::lock_guard<std::mutex> lock(conferenceMutex_);
104    if (subCallIdSet_.size() >= maxSubCallLimits_) {
105        TELEPHONY_LOGE("there is %{public}zu calls in the conference yet!", subCallIdSet_.size());
106        return CALL_ERR_CONFERENCE_CALL_EXCEED_LIMIT;
107    }
108    return TELEPHONY_SUCCESS;
109}
110
111int32_t CsConference::CanSeparateConference()
112{
113    std::lock_guard<std::mutex> lock(conferenceMutex_);
114    if (subCallIdSet_.empty()) {
115        TELEPHONY_LOGE("no call is currently in the conference!");
116        return CALL_ERR_CONFERENCE_NOT_EXISTS;
117    }
118    if (state_ != CONFERENCE_STATE_ACTIVE) {
119        TELEPHONY_LOGE("call is not active!");
120        return CALL_ERR_CONFERENCE_CALL_IS_NOT_ACTIVE;
121    }
122    return TELEPHONY_SUCCESS;
123}
124
125int32_t CsConference::CanKickOutFromConference()
126{
127    std::lock_guard<std::mutex> lock(conferenceMutex_);
128    if (subCallIdSet_.empty()) {
129        TELEPHONY_LOGE("no call is currently in the conference!");
130        return CALL_ERR_CONFERENCE_NOT_EXISTS;
131    }
132    return TELEPHONY_SUCCESS;
133}
134} // namespace Telephony
135} // namespace OHOS
136