1/*
2 * Copyright (C) 2022 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 "cellular_call_hisysevent.h"
17
18#include <securec.h>
19
20#include "call_manager_errors.h"
21#include "telephony_errors.h"
22#include "telephony_log_wrapper.h"
23
24namespace OHOS {
25namespace Telephony {
26// EVENT
27static constexpr const char *CALL_INCOMING_FAILED_EVENT = "CALL_INCOMING_FAILED";
28static constexpr const char *CALL_DIAL_FAILED_EVENT = "CALL_DIAL_FAILED";
29static constexpr const char *CALL_ANSWER_FAILED_EVENT = "CALL_ANSWER_FAILED";
30static constexpr const char *CALL_HANGUP_FAILED_EVENT = "CALL_HANGUP_FAILED";
31static constexpr const char *DIAL_EVENT = "DIAL";
32static constexpr const char *ANSWER_EVENT = "ANSWER";
33static constexpr const char *HANG_UP_EVENT = "HANG_UP";
34static constexpr const char *CALL_END_EXCEPTION_EVENT = "CALL_END_EXCEPTION";
35static constexpr const char *FOUNDATION_RESTART_EVENT = "FOUNDATION_RESTART";
36static constexpr const char *VONR_SWITCH_STATE_EVENT = "VONR_SWITCH_STATE";
37static constexpr const char *CALL_MODE_SEND_REQUEST_EVENT = "CALL_MODE_SEND_REQUEST";
38static constexpr const char *CALL_MODE_SEND_RESPONSE_EVENT = "CALL_MODE_SEND_RESPONSE";
39static constexpr const char *CALL_MODE_RECEIVE_RESPONSE_EVENT = "CALL_MODE_RECEIVE_RESPONSE";
40static constexpr const char *CALL_MODE_RECEIVE_REQUEST_EVENT = "CALL_MODE_RECEIVE_REQUEST";
41
42// KEY
43static constexpr const char *MODULE_NAME_KEY = "MODULE";
44static constexpr const char *SLOT_ID_KEY = "SLOT_ID";
45static constexpr const char *CALL_ID_KEY = "CALL_ID";
46static constexpr const char *CALL_TYPE_KEY = "CALL_TYPE";
47static constexpr const char *VIDEO_STATE_KEY = "VIDEO_STATE";
48static constexpr const char *RESULT_KEY = "RESULT";
49static constexpr const char *FAIL_CAUSE_KEY = "FAIL_CAUSE";
50static constexpr const char *ERROR_TYPE_KEY = "ERROR_TYPE";
51static constexpr const char *ERROR_MSG_KEY = "ERROR_MSG";
52static constexpr const char *RESTART_COUNT_KEY = "RESTART_COUNT";
53static constexpr const char *SWITCH_KEY = "SWITCH_KEY";
54
55// VALUE
56static constexpr const char *CELLULAR_CALL_MODULE = "CELLULAR_CALL";
57static const int32_t INVALID_VALUE = -1;
58static const int32_t CS_CALL_TYPE = 0;
59static const int32_t IMS_CALL_TYPE = 1;
60static const int32_t VOICE_TYPE = 0;
61static const int32_t VIDEO_TYPE = 1;
62
63void CellularCallHiSysEvent::WriteFoundationRestartFaultEvent(const int32_t count)
64{
65    HiWriteFaultEvent(FOUNDATION_RESTART_EVENT, RESTART_COUNT_KEY, count);
66}
67
68void CellularCallHiSysEvent::WriteCallEndBehaviorEvent(const int32_t slotId, const int32_t cause)
69{
70    HiWriteBehaviorEvent(CALL_END_EXCEPTION_EVENT, SLOT_ID_KEY, slotId, FAIL_CAUSE_KEY, cause);
71}
72
73void CellularCallHiSysEvent::WriteDialCallBehaviorEvent(
74    const CallBehaviorParameterInfo &info, const CallResponseResult &result)
75{
76    int32_t type = 0;
77    if (info.callType == CS_CALL_TYPE && info.videoState == VOICE_TYPE) {
78        type = static_cast<int32_t>(DialCallType::CS_VOICE_DIAL);
79    } else if (info.callType == IMS_CALL_TYPE && info.videoState == VOICE_TYPE) {
80        type = static_cast<int32_t>(DialCallType::IMS_VOICE_DIAL);
81    } else if (info.callType == IMS_CALL_TYPE && info.videoState == VIDEO_TYPE) {
82        type = static_cast<int32_t>(DialCallType::IMS_VIDEO_DIAL);
83    } else {
84        TELEPHONY_LOGE("WriteDialCallBehaviorEvent callType is out of range!");
85        return;
86    }
87    HiWriteBehaviorEvent(
88        DIAL_EVENT, SLOT_ID_KEY, info.slotId, CALL_TYPE_KEY, type, RESULT_KEY, static_cast<int32_t>(result));
89}
90
91void CellularCallHiSysEvent::WriteHangUpCallBehaviorEvent(
92    const CallBehaviorParameterInfo &info, const CallResponseResult &result)
93{
94    int32_t type = 0;
95    if (info.callType == CS_CALL_TYPE && info.videoState == VOICE_TYPE) {
96        type = static_cast<int32_t>(HangUpCallType::CS_VOICE_CALL);
97    } else if (info.callType == IMS_CALL_TYPE && info.videoState == VOICE_TYPE) {
98        type = static_cast<int32_t>(HangUpCallType::IMS_VOICE_CALL);
99    } else if (info.callType == IMS_CALL_TYPE && info.videoState == VIDEO_TYPE) {
100        type = static_cast<int32_t>(HangUpCallType::IMS_VIDEO_CALL);
101    } else {
102        TELEPHONY_LOGE("WriteHangUpCallBehaviorEvent callType is out of range!");
103        return;
104    }
105    HiWriteBehaviorEvent(
106        HANG_UP_EVENT, SLOT_ID_KEY, info.slotId, CALL_TYPE_KEY, type, RESULT_KEY, static_cast<int32_t>(result));
107}
108
109void CellularCallHiSysEvent::WriteAnswerCallBehaviorEvent(
110    const CallBehaviorParameterInfo &info, const CallResponseResult &result)
111{
112    int32_t type = 0;
113    if (info.incomingCallType == IMS_CALL_TYPE && info.incomingVideoState == VOICE_TYPE &&
114        info.callType == IMS_CALL_TYPE && info.videoState == VOICE_TYPE) {
115        type = static_cast<int32_t>(AnswerCallType::IMS_VOICE_ANSWER);
116    } else if (info.incomingCallType == IMS_CALL_TYPE && info.incomingVideoState == VIDEO_TYPE &&
117               info.callType == IMS_CALL_TYPE && info.videoState == VOICE_TYPE) {
118        type = static_cast<int32_t>(AnswerCallType::IMS_VIDEO_TO_VOICE_ANSWER);
119    } else if (info.incomingCallType == IMS_CALL_TYPE && info.incomingVideoState == VIDEO_TYPE &&
120               info.callType == IMS_CALL_TYPE && info.videoState == VIDEO_TYPE) {
121        type = static_cast<int32_t>(AnswerCallType::IMS_VIDEO_TO_VIDEO_ANSWER);
122    } else if (info.incomingCallType == CS_CALL_TYPE && info.incomingVideoState == VOICE_TYPE &&
123               info.callType == CS_CALL_TYPE && info.videoState == VOICE_TYPE) {
124        type = static_cast<int32_t>(AnswerCallType::CS_VOICE_ANSWER);
125    } else {
126        TELEPHONY_LOGE("WriteAnswerCallBehaviorEvent callType is out of range!");
127        return;
128    }
129    HiWriteBehaviorEvent(
130        ANSWER_EVENT, SLOT_ID_KEY, info.slotId, CALL_TYPE_KEY, type, RESULT_KEY, static_cast<int32_t>(result));
131}
132
133void CellularCallHiSysEvent::WriteIncomingCallFaultEvent(const int32_t slotId, const int32_t callType,
134    const int32_t videoState, const int32_t errCode, const std::string &desc)
135{
136    CallErrorCode value = CallErrorCode::CALL_ERROR_NONE;
137    if (ErrorCodeConversion(errCode, value)) {
138        HiWriteFaultEvent(CALL_INCOMING_FAILED_EVENT, MODULE_NAME_KEY, CELLULAR_CALL_MODULE, SLOT_ID_KEY, slotId,
139            CALL_TYPE_KEY, callType, VIDEO_STATE_KEY, videoState, ERROR_TYPE_KEY, static_cast<int32_t>(value),
140            ERROR_MSG_KEY, desc);
141    } else {
142        HiWriteFaultEvent(CALL_INCOMING_FAILED_EVENT, MODULE_NAME_KEY, CELLULAR_CALL_MODULE, SLOT_ID_KEY, slotId,
143            CALL_TYPE_KEY, callType, VIDEO_STATE_KEY, videoState, ERROR_TYPE_KEY, errCode, ERROR_MSG_KEY, desc);
144    }
145}
146
147void CellularCallHiSysEvent::WriteDialCallFaultEvent(const int32_t slotId, const int32_t callType,
148    const int32_t videoState, const int32_t errorCode, const std::string &desc)
149{
150    CallErrorCode value = CallErrorCode::CALL_ERROR_NONE;
151    if (ErrorCodeConversion(errorCode, value)) {
152        HiWriteFaultEvent(CALL_DIAL_FAILED_EVENT, MODULE_NAME_KEY, CELLULAR_CALL_MODULE, SLOT_ID_KEY, slotId,
153            CALL_TYPE_KEY, callType, VIDEO_STATE_KEY, videoState, ERROR_TYPE_KEY, static_cast<int32_t>(value),
154            ERROR_MSG_KEY, desc);
155    } else {
156        HiWriteFaultEvent(CALL_DIAL_FAILED_EVENT, MODULE_NAME_KEY, CELLULAR_CALL_MODULE, SLOT_ID_KEY, slotId,
157            CALL_TYPE_KEY, callType, VIDEO_STATE_KEY, videoState, ERROR_TYPE_KEY, errorCode, ERROR_MSG_KEY, desc);
158    }
159}
160
161void CellularCallHiSysEvent::WriteAnswerCallFaultEvent(const int32_t slotId, const int32_t callId,
162    const int32_t videoState, const int32_t errorCode, const std::string &desc)
163{
164    CallErrorCode value = CallErrorCode::CALL_ERROR_NONE;
165    if (ErrorCodeConversion(errorCode, value)) {
166        HiWriteFaultEvent(CALL_ANSWER_FAILED_EVENT, MODULE_NAME_KEY, CELLULAR_CALL_MODULE, SLOT_ID_KEY, slotId,
167            CALL_ID_KEY, callId, VIDEO_STATE_KEY, videoState, ERROR_TYPE_KEY, static_cast<int32_t>(value),
168            ERROR_MSG_KEY, desc);
169    } else {
170        HiWriteFaultEvent(CALL_ANSWER_FAILED_EVENT, MODULE_NAME_KEY, CELLULAR_CALL_MODULE, SLOT_ID_KEY, slotId,
171            CALL_ID_KEY, callId, VIDEO_STATE_KEY, videoState, ERROR_TYPE_KEY, errorCode, ERROR_MSG_KEY, desc);
172    }
173}
174
175void CellularCallHiSysEvent::WriteHangUpFaultEvent(
176    const int32_t slotId, const int32_t callId, const int32_t errorCode, const std::string &desc)
177{
178    CallErrorCode value = CallErrorCode::CALL_ERROR_NONE;
179    if (ErrorCodeConversion(errorCode, value)) {
180        HiWriteFaultEvent(CALL_HANGUP_FAILED_EVENT, MODULE_NAME_KEY, CELLULAR_CALL_MODULE, SLOT_ID_KEY, slotId,
181            CALL_ID_KEY, callId, ERROR_TYPE_KEY, static_cast<int32_t>(value), ERROR_MSG_KEY, desc);
182    } else {
183        HiWriteFaultEvent(CALL_HANGUP_FAILED_EVENT, MODULE_NAME_KEY, CELLULAR_CALL_MODULE, SLOT_ID_KEY, slotId,
184            CALL_ID_KEY, callId, ERROR_TYPE_KEY, errorCode, ERROR_MSG_KEY, desc);
185    }
186}
187
188void CellularCallHiSysEvent::WriteVoNRSwitchChangeEvent(const int32_t enable)
189{
190    HiWriteBehaviorEvent(VONR_SWITCH_STATE_EVENT, SWITCH_KEY, enable);
191}
192
193void CellularCallHiSysEvent::WriteImsCallModeBehaviorEvent(
194    const CallModeBehaviorType type, const CallBehaviorParameterInfo &info, const int32_t requestResult)
195{
196    std::string imsCallModeEvent = "";
197    switch (type) {
198        case CallModeBehaviorType::SEND_REQUEST_EVENT:
199            imsCallModeEvent = CALL_MODE_SEND_REQUEST_EVENT;
200            break;
201        case CallModeBehaviorType::SEND_RESPONSE_EVENT:
202            imsCallModeEvent = CALL_MODE_SEND_RESPONSE_EVENT;
203            break;
204        case CallModeBehaviorType::RECEIVE_REQUEST_EVENT:
205            imsCallModeEvent = CALL_MODE_RECEIVE_REQUEST_EVENT;
206            break;
207        case CallModeBehaviorType::RECEIVE_RESPONSE_EVENT:
208            imsCallModeEvent = CALL_MODE_RECEIVE_RESPONSE_EVENT;
209            break;
210        default:
211            break;
212    }
213    if (requestResult == INVALID_VALUE) {
214        HiWriteBehaviorEvent(imsCallModeEvent, MODULE_NAME_KEY, CELLULAR_CALL_MODULE, SLOT_ID_KEY, info.slotId,
215            CALL_TYPE_KEY, info.callType, VIDEO_STATE_KEY, info.videoState);
216    } else {
217        HiWriteBehaviorEvent(imsCallModeEvent, MODULE_NAME_KEY, CELLULAR_CALL_MODULE, SLOT_ID_KEY, info.slotId,
218            CALL_TYPE_KEY, info.callType, VIDEO_STATE_KEY, info.videoState, RESULT_KEY, requestResult);
219    }
220}
221
222int32_t CellularCallHiSysEvent::ErrorCodeConversion(const int32_t errCode, CallErrorCode &eventValue)
223{
224    if (CallDataErrorCodeConversion(errCode, eventValue) || CallInterfaceErrorCodeConversion(errCode, eventValue) ||
225        TelephonyErrorCodeConversion(errCode, eventValue)) {
226        return true;
227    }
228    return false;
229}
230
231int32_t CellularCallHiSysEvent::TelephonyErrorCodeConversion(const int32_t errCode, CallErrorCode &eventValue)
232{
233    switch (errCode) {
234        case static_cast<int32_t>(TELEPHONY_ERR_LOCAL_PTR_NULL):
235            eventValue = CallErrorCode::CALL_ERROR_CALL_LOCAL_PTR_NULL;
236            break;
237        case static_cast<int32_t>(TELEPHONY_ERR_ARGUMENT_INVALID):
238            eventValue = CallErrorCode::CALL_ERROR_ARGUMENT_INVALID;
239            break;
240        case static_cast<int32_t>(TELEPHONY_ERR_IPC_CONNECT_STUB_FAIL):
241            eventValue = CallErrorCode::CALL_ERROR_IPC_CONNECT_STUB_FAIL;
242            break;
243        case static_cast<int32_t>(TELEPHONY_ERR_WRITE_DESCRIPTOR_TOKEN_FAIL):
244            eventValue = CallErrorCode::CALL_ERROR_IPC_WRITE_DESCRIPTOR_TOKEN_FAIL;
245            break;
246        case static_cast<int32_t>(TELEPHONY_ERR_WRITE_DATA_FAIL):
247            eventValue = CallErrorCode::CALL_ERROR_IPC_WRITE_DATA_FAIL;
248            break;
249        case static_cast<int32_t>(TELEPHONY_ERR_PERMISSION_ERR):
250            eventValue = CallErrorCode::CALL_ERROR_PERMISSION_ERR;
251            break;
252        case static_cast<int32_t>(TELEPHONY_ERR_MEMSET_FAIL):
253            eventValue = CallErrorCode::CALL_ERROR_MEMSET_FAIL;
254            break;
255        case static_cast<int32_t>(TELEPHONY_ERR_MEMCPY_FAIL):
256            eventValue = CallErrorCode::CALL_ERROR_MEMCPY_FAIL;
257            break;
258        default:
259            return false;
260    }
261
262    return true;
263}
264
265int32_t CellularCallHiSysEvent::CallDataErrorCodeConversion(const int32_t errCode, CallErrorCode &eventValue)
266{
267    switch (errCode) {
268        case static_cast<int32_t>(CALL_ERR_INVALID_SLOT_ID):
269            eventValue = CallErrorCode::CALL_ERROR_INVALID_SLOT_ID;
270            break;
271        case static_cast<int32_t>(CALL_ERR_INVALID_CALLID):
272            eventValue = CallErrorCode::CALL_ERROR_INVALID_CALLID;
273            break;
274        case static_cast<int32_t>(CALL_ERR_PHONE_NUMBER_EMPTY):
275            eventValue = CallErrorCode::CALL_ERROR_PHONE_NUMBER_EMPTY;
276            break;
277        case static_cast<int32_t>(CALL_ERR_NUMBER_OUT_OF_RANGE):
278            eventValue = CallErrorCode::CALL_ERROR_NUMBER_OUT_OF_RANGE;
279            break;
280        case static_cast<int32_t>(CALL_ERR_UNSUPPORTED_NETWORK_TYPE):
281            eventValue = CallErrorCode::CALL_ERROR_UNSUPPORTED_NETWORK_TYPE;
282            break;
283        case static_cast<int32_t>(CALL_ERR_INVALID_DIAL_SCENE):
284            eventValue = CallErrorCode::CALL_ERROR_INVALID_DIAL_SCENE;
285            break;
286        case static_cast<int32_t>(CALL_ERR_INVALID_VIDEO_STATE):
287            eventValue = CallErrorCode::CALL_ERROR_INVALID_VIDEO_STATE;
288            break;
289        case static_cast<int32_t>(CALL_ERR_UNKNOW_DIAL_TYPE):
290            eventValue = CallErrorCode::CALL_ERROR_UNKNOW_DIAL_TYPE;
291            break;
292        case static_cast<int32_t>(CALL_ERR_UNKNOW_CALL_TYPE):
293            eventValue = CallErrorCode::CALL_ERROR_UNKNOW_CALL_TYPE;
294            break;
295        case static_cast<int32_t>(CALL_ERR_CALL_OBJECT_IS_NULL):
296            eventValue = CallErrorCode::CALL_ERROR_CALL_OBJECT_IS_NULL;
297            break;
298        default:
299            return false;
300    }
301    return true;
302}
303
304int32_t CellularCallHiSysEvent::CallInterfaceErrorCodeConversion(const int32_t errCode, CallErrorCode &eventValue)
305{
306    switch (errCode) {
307        case static_cast<int32_t>(CALL_ERR_DIAL_IS_BUSY):
308            eventValue = CallErrorCode::CALL_ERROR_DIAL_IS_BUSY;
309            break;
310        case static_cast<int32_t>(CALL_ERR_ILLEGAL_CALL_OPERATION):
311            eventValue = CallErrorCode::CALL_ERROR_ILLEGAL_CALL_OPERATION;
312            break;
313        case static_cast<int32_t>(CALL_ERR_PHONE_CALLSTATE_NOTIFY_FAILED):
314            eventValue = CallErrorCode::CALL_ERROR_PHONE_CALLSTATE_NOTIFY_FAILED;
315            break;
316        case static_cast<int32_t>(CALL_ERR_SYSTEM_EVENT_HANDLE_FAILURE):
317            eventValue = CallErrorCode::CALL_ERROR_SYSTEM_EVENT_HANDLE_FAILURE;
318            break;
319        case static_cast<int32_t>(CALL_ERR_CALL_COUNTS_EXCEED_LIMIT):
320            eventValue = CallErrorCode::CALL_ERROR_CALL_COUNTS_EXCEED_LIMIT;
321            break;
322        case static_cast<int32_t>(CALL_ERR_GET_RADIO_STATE_FAILED):
323            eventValue = CallErrorCode::CALL_ERROR_GET_RADIO_STATE_FAILED;
324            break;
325        default:
326            return false;
327    }
328
329    return true;
330}
331
332void CellularCallHiSysEvent::SetCallParameterInfo(
333    const int32_t slotId, const int32_t callType, const int32_t videoState)
334{
335    dfxSlotId_ = slotId;
336    dfxCallType_ = callType;
337    dfxVideoState_ = videoState;
338}
339
340void CellularCallHiSysEvent::SetIncomingCallParameterInfo(
341    const int32_t incomingCallType, const int32_t incomingVideoState)
342{
343    dfxIncomingCallType_ = incomingCallType;
344    dfxIncomingVideoState_ = incomingVideoState;
345}
346
347void CellularCallHiSysEvent::GetCallParameterInfo(CallBehaviorParameterInfo &info)
348{
349    info.slotId = dfxSlotId_;
350    info.callType = dfxCallType_;
351    info.videoState = dfxVideoState_;
352    info.incomingCallType = dfxIncomingCallType_;
353    info.incomingVideoState = dfxIncomingVideoState_;
354}
355
356void CellularCallHiSysEvent::SetIncomingStartTime()
357{
358    incomingStartTime_ =
359        std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch())
360            .count();
361}
362
363void CellularCallHiSysEvent::JudgingIncomingTimeOut(
364    const int32_t slotId, const int32_t callType, const int32_t videoState)
365{
366    int64_t incomingEndTime =
367        std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch())
368            .count();
369    if ((incomingEndTime - incomingStartTime_) > NORMAL_INCOMING_TIME) {
370        WriteIncomingCallFaultEvent(slotId, callType, videoState,
371            static_cast<int32_t>(CallErrorCode::CALL_ERROR_INCOMING_TIME_OUT),
372            "incoming time out " + std::to_string(incomingStartTime_ - incomingEndTime));
373    }
374}
375
376void CellularCallHiSysEvent::SetCallForwardingInfo(const int32_t slotId, const bool enable, const std::string &number)
377{
378    callForwardingSlotId_ = slotId;
379    callForwardingEnable_ = enable;
380    callForwardingNumber_ = number;
381}
382
383void CellularCallHiSysEvent::GetCallForwardingInfo(CallForwardingInfo &info)
384{
385    info.slotId = callForwardingSlotId_;
386    info.enable = callForwardingEnable_;
387
388    if (callForwardingNumber_.length() > static_cast<size_t>(maxNumberLen)) {
389        return;
390    }
391    size_t cpyLen = callForwardingNumber_.length() + 1;
392    if (cpyLen > static_cast<size_t>(maxNumberLen + 1)) {
393        return;
394    }
395    if (strcpy_s(info.number, cpyLen, callForwardingNumber_.c_str()) != EOK) {
396        TELEPHONY_LOGE("strcpy_s fail.");
397        return;
398    }
399}
400} // namespace Telephony
401} // namespace OHOS
402