1/*
2 * Copyright (C) 2021-2023 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 "bluetooth_call_stub.h"
17
18#include <string_ex.h>
19
20#include "call_manager_errors.h"
21#include "telephony_log_wrapper.h"
22
23#include "message_option.h"
24#include "message_parcel.h"
25#include "call_manager_utils.h"
26
27#include "call_control_manager.h"
28
29namespace OHOS {
30namespace Telephony {
31BluetoothCallStub::BluetoothCallStub()
32{
33    memberFuncMap_[static_cast<uint32_t>(BluetoothCallInterfaceCode::INTERFACE_BT_ANSWER_CALL)] =
34        [this](MessageParcel &data, MessageParcel &reply) { return OnAnswerCall(data, reply); };
35    memberFuncMap_[static_cast<uint32_t>(BluetoothCallInterfaceCode::INTERFACE_BT_REJECT_CALL)] =
36        [this](MessageParcel &data, MessageParcel &reply) { return OnRejectCall(data, reply); };
37    memberFuncMap_[static_cast<uint32_t>(BluetoothCallInterfaceCode::INTERFACE_BT_HOLD_CALL)] =
38        [this](MessageParcel &data, MessageParcel &reply) { return OnHoldCall(data, reply); };
39    memberFuncMap_[static_cast<uint32_t>(BluetoothCallInterfaceCode::INTERFACE_BT_UNHOLD_CALL)] =
40        [this](MessageParcel &data, MessageParcel &reply) { return OnUnHoldCall(data, reply); };
41    memberFuncMap_[static_cast<uint32_t>(BluetoothCallInterfaceCode::INTERFACE_BT_DISCONNECT_CALL)] =
42        [this](MessageParcel &data, MessageParcel &reply) { return OnHangUpCall(data, reply); };
43    memberFuncMap_[static_cast<uint32_t>(BluetoothCallInterfaceCode::INTERFACE_BT_GET_CALL_STATE)] =
44        [this](MessageParcel &data, MessageParcel &reply) { return OnGetBtCallState(data, reply); };
45    memberFuncMap_[static_cast<uint32_t>(BluetoothCallInterfaceCode::INTERFACE_BT_SWAP_CALL)] =
46        [this](MessageParcel &data, MessageParcel &reply) { return OnSwitchCall(data, reply); };
47    memberFuncMap_[static_cast<uint32_t>(BluetoothCallInterfaceCode::INTERFACE_BT_COMBINE_CONFERENCE)] =
48        [this](MessageParcel &data, MessageParcel &reply) { return OnCombineConference(data, reply); };
49    memberFuncMap_[static_cast<uint32_t>(BluetoothCallInterfaceCode::INTERFACE_BT_SEPARATE_CONFERENCE)] =
50        [this](MessageParcel &data, MessageParcel &reply) { return OnSeparateConference(data, reply); };
51    memberFuncMap_[static_cast<uint32_t>(BluetoothCallInterfaceCode::INTERFACE_BT_KICK_OUT_CONFERENCE)] =
52        [this](MessageParcel &data, MessageParcel &reply) { return OnKickOutFromConference(data, reply); };
53    memberFuncMap_[static_cast<uint32_t>(BluetoothCallInterfaceCode::INTERFACE_BT_START_DTMF)] =
54        [this](MessageParcel &data, MessageParcel &reply) { return OnStartDtmf(data, reply); };
55    memberFuncMap_[static_cast<uint32_t>(BluetoothCallInterfaceCode::INTERFACE_BT_STOP_DTMF)] =
56        [this](MessageParcel &data, MessageParcel &reply) { return OnStopDtmf(data, reply); };
57    memberFuncMap_[static_cast<uint32_t>(BluetoothCallInterfaceCode::INTERFACE_BT_GET_CURRENT_CALL_LIST)] =
58        [this](MessageParcel &data, MessageParcel &reply) { return OnGetCurrentCallList(data, reply); };
59}
60
61BluetoothCallStub::~BluetoothCallStub()
62{
63    memberFuncMap_.clear();
64}
65
66int32_t BluetoothCallStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply,
67    MessageOption &option)
68{
69    std::u16string myDescriptor = BluetoothCallStub::GetDescriptor();
70    std::u16string remoteDescriptor = data.ReadInterfaceToken();
71    if (myDescriptor != remoteDescriptor) {
72        TELEPHONY_LOGE("descriptor checked fail !");
73        return TELEPHONY_ERR_DESCRIPTOR_MISMATCH;
74    }
75    TELEPHONY_LOGI("OnReceived, cmd = %{public}u", code);
76    auto itFunc = memberFuncMap_.find(code);
77    if (itFunc != memberFuncMap_.end()) {
78        auto memberFunc = itFunc->second;
79        if (memberFunc != nullptr) {
80            return memberFunc(data, reply);
81        }
82    }
83    return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
84}
85
86int32_t BluetoothCallStub::OnAnswerCall(MessageParcel &data, MessageParcel &reply)
87{
88    int32_t result = AnswerCall();
89    TELEPHONY_LOGI("result:%{public}d", result);
90    if (!reply.WriteInt32(result)) {
91        TELEPHONY_LOGE("fail to write parcel");
92        return TELEPHONY_ERR_WRITE_REPLY_FAIL;
93    }
94    return result;
95}
96
97int32_t BluetoothCallStub::OnRejectCall(MessageParcel &data, MessageParcel &reply)
98{
99    int32_t result = RejectCall();
100    TELEPHONY_LOGI("result:%{public}d", result);
101    if (!reply.WriteInt32(result)) {
102        TELEPHONY_LOGE("fail to write parcel");
103        return TELEPHONY_ERR_WRITE_REPLY_FAIL;
104    }
105    return result;
106}
107
108int32_t BluetoothCallStub::OnHangUpCall(MessageParcel &data, MessageParcel &reply)
109{
110    int32_t result = HangUpCall();
111    TELEPHONY_LOGI("result:%{public}d", result);
112    if (!reply.WriteInt32(result)) {
113        TELEPHONY_LOGE("fail to write parcel");
114        return TELEPHONY_ERR_WRITE_REPLY_FAIL;
115    }
116    return result;
117}
118
119int32_t BluetoothCallStub::OnGetBtCallState(MessageParcel &data, MessageParcel &reply)
120{
121    int32_t result = GetCallState();
122    TELEPHONY_LOGI("result:%{public}d", result);
123    if (!reply.WriteInt32(result)) {
124        TELEPHONY_LOGE("fail to write parcel");
125        return TELEPHONY_ERR_WRITE_REPLY_FAIL;
126    }
127    return TELEPHONY_SUCCESS;
128}
129
130int32_t BluetoothCallStub::OnHoldCall(MessageParcel &data, MessageParcel &reply)
131{
132    int32_t result = HoldCall();
133    TELEPHONY_LOGI("result:%{public}d", result);
134    if (!reply.WriteInt32(result)) {
135        TELEPHONY_LOGE("fail to write parcel");
136        return TELEPHONY_ERR_WRITE_REPLY_FAIL;
137    }
138    return result;
139}
140
141int32_t BluetoothCallStub::OnUnHoldCall(MessageParcel &data, MessageParcel &reply)
142{
143    int32_t result = UnHoldCall();
144    TELEPHONY_LOGI("result:%{public}d", result);
145    if (!reply.WriteInt32(result)) {
146        TELEPHONY_LOGE("fail to write parcel");
147        return TELEPHONY_ERR_WRITE_REPLY_FAIL;
148    }
149    return result;
150}
151
152int32_t BluetoothCallStub::OnSwitchCall(MessageParcel &data, MessageParcel &reply)
153{
154    int32_t result = SwitchCall();
155    TELEPHONY_LOGI("result:%{public}d", result);
156    if (!reply.WriteInt32(result)) {
157        TELEPHONY_LOGE("fail to write parcel");
158        return TELEPHONY_ERR_WRITE_REPLY_FAIL;
159    }
160    return result;
161}
162
163int32_t BluetoothCallStub::OnCombineConference(MessageParcel &data, MessageParcel &reply)
164{
165    int32_t result = CombineConference();
166    TELEPHONY_LOGI("result:%{public}d", result);
167    if (!reply.WriteInt32(result)) {
168        TELEPHONY_LOGE("fail to write parcel");
169        return TELEPHONY_ERR_WRITE_REPLY_FAIL;
170    }
171    return TELEPHONY_SUCCESS;
172}
173
174int32_t BluetoothCallStub::OnSeparateConference(MessageParcel &data, MessageParcel &reply)
175{
176    int32_t result = SeparateConference();
177    TELEPHONY_LOGI("result:%{public}d", result);
178    if (!reply.WriteInt32(result)) {
179        TELEPHONY_LOGE("fail to write parcel");
180        return TELEPHONY_ERR_WRITE_REPLY_FAIL;
181    }
182    return TELEPHONY_SUCCESS;
183}
184
185int32_t BluetoothCallStub::OnKickOutFromConference(MessageParcel &data, MessageParcel &reply)
186{
187    int32_t result = KickOutFromConference();
188    TELEPHONY_LOGI("result:%{public}d", result);
189    if (!reply.WriteInt32(result)) {
190        TELEPHONY_LOGE("fail to write parcel");
191        return TELEPHONY_ERR_WRITE_REPLY_FAIL;
192    }
193    return TELEPHONY_SUCCESS;
194}
195
196int32_t BluetoothCallStub::OnStartDtmf(MessageParcel &data, MessageParcel &reply)
197{
198    int32_t result = TELEPHONY_ERR_FAIL;
199    char str = static_cast<char>(data.ReadInt8());
200    result = StartDtmf(str);
201    TELEPHONY_LOGI("result:%{public}d", result);
202    if (!reply.WriteInt32(result)) {
203        TELEPHONY_LOGE("fail to write parcel");
204        return TELEPHONY_ERR_WRITE_REPLY_FAIL;
205    }
206    return TELEPHONY_SUCCESS;
207}
208
209int32_t BluetoothCallStub::OnStopDtmf(MessageParcel &data, MessageParcel &reply)
210{
211    int32_t result = TELEPHONY_ERR_FAIL;
212    result = StopDtmf();
213    TELEPHONY_LOGI("result:%{public}d", result);
214    if (!reply.WriteInt32(result)) {
215        TELEPHONY_LOGE("fail to write parcel");
216        return TELEPHONY_ERR_WRITE_REPLY_FAIL;
217    }
218    return TELEPHONY_SUCCESS;
219}
220
221int32_t BluetoothCallStub::OnGetCurrentCallList(MessageParcel &data, MessageParcel &reply)
222{
223    int32_t slotId = data.ReadInt32();
224    std::vector<CallAttributeInfo> callVec = GetCurrentCallList(slotId);
225    reply.WriteInt32(callVec.size());
226    std::vector<CallAttributeInfo>::iterator it = callVec.begin();
227    for (; it != callVec.end(); ++it) {
228        CallManagerUtils::WriteCallAttributeInfo(*it, reply);
229    }
230    return TELEPHONY_SUCCESS;
231}
232} // namespace Telephony
233} // namespace OHOS
234