1/*
2 * Copyright (c) 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 "imscallback_fuzzer.h"
17
18#include <cstddef>
19#include <cstdint>
20#define private public
21#include "addcellularcalltoken_fuzzer.h"
22#include "cellular_call_service.h"
23#include "ims_call_callback_stub.h"
24#include "ims_call_client.h"
25#include "ims_call_proxy.h"
26#include "securec.h"
27#include "system_ability_definition.h"
28#include "telephony_types.h"
29
30using namespace OHOS::Telephony;
31namespace OHOS {
32static bool g_isInited = false;
33constexpr int32_t SLOT_NUM = 2;
34constexpr int32_t BOOL_NUM = 2;
35constexpr int32_t SERIAL_NUM = 3;
36constexpr int32_t ERROR_NUM = 15;
37constexpr int32_t TYPE_NUM = 5;
38constexpr int32_t CALL_INDEX_NUM = 8;
39constexpr int32_t REQUEST_NUM = 6;
40constexpr int32_t VIDEO_CALL_EVENT_NUM = 4;
41
42bool IsServiceInited()
43{
44    auto service = DelayedSingleton<CellularCallService>::GetInstance();
45    if (service == nullptr) {
46        return g_isInited;
47    }
48    if (service->state_ != ServiceRunningState::STATE_RUNNING) {
49        service->state_ = ServiceRunningState::STATE_RUNNING;
50    }
51    if (!g_isInited && service->state_ == ServiceRunningState::STATE_RUNNING) {
52        g_isInited = true;
53    }
54    return g_isInited;
55}
56
57void OnRemoteRequest(const uint8_t *data, size_t size)
58{
59    MessageParcel dataMessageParcel;
60    if (!dataMessageParcel.WriteInterfaceToken(ImsCallCallbackStub::GetDescriptor())) {
61        return;
62    }
63    int32_t slotId = ERROR_NUM;
64    dataMessageParcel.WriteInt32(slotId);
65    uint32_t code = static_cast<uint32_t>(size);
66    MessageParcel reply;
67    MessageOption option;
68    DelayedSingleton<ImsCallCallbackStub>::GetInstance()->OnRemoteRequest(code, dataMessageParcel, reply, option);
69}
70
71void TestImsCallCallbackFunction(const uint8_t *data, size_t size, sptr<ImsCallCallbackStub> &stub)
72{
73    int32_t slotId = ERROR_NUM;
74    RadioResponseInfo rilRadioResponse;
75    rilRadioResponse.flag = static_cast<int32_t>(size % BOOL_NUM);
76    rilRadioResponse.serial = static_cast<int32_t>(size % SERIAL_NUM);
77    rilRadioResponse.error = static_cast<ErrType>(size % ERROR_NUM);
78    rilRadioResponse.type = static_cast<ResponseTypes>(size % TYPE_NUM);
79    MessageParcel answerData;
80    MessageParcel answerReply;
81    answerData.WriteInt32(slotId);
82    stub->OnAnswerResponseInner(answerData, answerReply);
83
84    MessageParcel dialData;
85    MessageParcel dialReply;
86    dialData.WriteInt32(slotId);
87    stub->OnDialResponseInner(dialData, dialReply);
88
89    MessageParcel hangupData;
90    MessageParcel hangupReply;
91    hangupData.WriteInt32(slotId);
92    stub->OnHangUpResponseInner(hangupData, hangupReply);
93
94    MessageParcel rejectData;
95    MessageParcel rejectReply;
96    rejectData.WriteInt32(slotId);
97    stub->OnRejectResponseInner(rejectData, rejectReply);
98
99    MessageParcel sendDtmfData;
100    MessageParcel sendDtmfReply;
101    sendDtmfData.WriteInt32(slotId);
102    sendDtmfData.WriteRawData((const void *)&rilRadioResponse, sizeof(RadioResponseInfo));
103    stub->OnSendDtmfResponseInner(sendDtmfData, sendDtmfReply);
104
105    MessageParcel startDtmfData;
106    MessageParcel startDtmfReply;
107    startDtmfData.WriteInt32(slotId);
108    startDtmfData.WriteRawData((const void *)&rilRadioResponse, sizeof(RadioResponseInfo));
109    stub->OnStartDtmfResponseInner(startDtmfData, startDtmfReply);
110
111    MessageParcel stopDtmfData;
112    MessageParcel stopDtmfReply;
113    stopDtmfData.WriteInt32(slotId);
114    stopDtmfData.WriteRawData((const void *)&rilRadioResponse, sizeof(RadioResponseInfo));
115    stub->OnStopDtmfResponseInner(stopDtmfData, stopDtmfReply);
116
117    MessageParcel imsCallsData;
118    MessageParcel imsCallsReply;
119    slotId = ERROR_NUM;
120    imsCallsData.WriteInt32(slotId);
121    imsCallsData.WriteRawData((const void *)&rilRadioResponse, sizeof(RadioResponseInfo));
122    stub->OnGetImsCallsDataResponseInner(imsCallsData, imsCallsReply);
123}
124
125void TestImsCallCallbackExFunction(const uint8_t *data, size_t size, sptr<ImsCallCallbackStub> &stub)
126{
127    int32_t slotId = ERROR_NUM;
128    std::string number(reinterpret_cast<const char *>(data), size);
129    MessageParcel muteData;
130    MessageParcel muteReply;
131    MuteControlResponse muteResponse;
132    muteResponse.result = static_cast<int32_t>(size % BOOL_NUM);
133    muteResponse.value = static_cast<int32_t>(size % BOOL_NUM);
134    muteData.WriteInt32(slotId);
135    muteData.WriteRawData((const void *)&muteResponse, sizeof(MuteControlResponse));
136    stub->OnSetMuteResponseInner(muteData, muteReply);
137
138    MessageParcel ringData;
139    MessageParcel ringReply;
140    RingbackVoice ringback;
141    ringback.status = static_cast<int32_t>(size % BOOL_NUM);
142    ringData.WriteInt32(slotId);
143    ringData.WriteRawData((const void *)&ringback, sizeof(RingbackVoice));
144    stub->OnCallRingBackReportInner(ringData, ringReply);
145
146    MessageParcel callData;
147    MessageParcel callReply;
148    callData.WriteInt32(slotId);
149    stub->OnCallStateChangeReportInner(callData, callReply);
150
151    MessageParcel failData;
152    MessageParcel failReply;
153    DisconnectedDetails details;
154    details.reason = static_cast<DisconnectedReason>(size);
155    details.message = number;
156    slotId = ERROR_NUM;
157    failData.WriteInt32(slotId);
158    failData.WriteInt32(static_cast<int32_t>(details.reason));
159    failData.WriteString(details.message);
160    stub->OnLastCallFailReasonResponseInner(failData, failReply);
161}
162
163void TestImsConfigCallbackFunction(const uint8_t *data, size_t size, sptr<ImsCallCallbackStub> &stub)
164{
165    int32_t slotId = ERROR_NUM;
166    RadioResponseInfo rilRadioResponse;
167    rilRadioResponse.flag = static_cast<int32_t>(size % BOOL_NUM);
168    rilRadioResponse.serial = static_cast<int32_t>(size % SERIAL_NUM);
169    rilRadioResponse.error = static_cast<ErrType>(size % ERROR_NUM);
170    rilRadioResponse.type = static_cast<ResponseTypes>(size % TYPE_NUM);
171
172    MessageParcel setImsSwitchData;
173    MessageParcel setImsSwitchReply;
174    setImsSwitchData.WriteInt32(slotId);
175    setImsSwitchData.WriteRawData((const void *)&rilRadioResponse, sizeof(RadioResponseInfo));
176    stub->OnSetImsSwitchResponseInner(setImsSwitchData, setImsSwitchReply);
177
178    MessageParcel holdCallData;
179    MessageParcel holdCallReply;
180    holdCallData.WriteInt32(slotId);
181    stub->OnHoldCallResponseInner(holdCallData, holdCallReply);
182
183    MessageParcel switchCallData;
184    MessageParcel switchCallReply;
185    switchCallData.WriteInt32(slotId);
186    stub->OnSwitchCallResponseInner(switchCallData, switchCallReply);
187
188    MessageParcel unholdData;
189    MessageParcel unholdReply;
190    unholdData.WriteInt32(slotId);
191    stub->OnUnHoldCallResponseInner(unholdData, unholdReply);
192
193    MessageParcel getImsSwitchData;
194    MessageParcel getImsSwitchReply;
195    getImsSwitchData.WriteInt32(slotId);
196    getImsSwitchData.WriteRawData((const void *)&rilRadioResponse, sizeof(RadioResponseInfo));
197    stub->OnGetImsSwitchResponseInner(getImsSwitchData, getImsSwitchReply);
198}
199
200void WriteSsResult(MessageParcel &in, SsBaseResult &ssResult, const int32_t action, const int32_t state, size_t size)
201{
202    ssResult.index = static_cast<int32_t>(size % SERIAL_NUM);
203    ssResult.result = static_cast<int32_t>(size % BOOL_NUM);
204    ssResult.reason = static_cast<int32_t>(size);
205    in.WriteInt32(ssResult.index);
206    in.WriteInt32(ssResult.result);
207    in.WriteInt32(ssResult.reason);
208    in.WriteString(ssResult.message);
209    in.WriteInt32(action);
210    in.WriteInt32(state);
211}
212
213void TestImsUTCallbackFunction(const uint8_t *data, size_t size, sptr<ImsCallCallbackStub> &stub)
214{
215    int32_t slotId = static_cast<int32_t>(size % SLOT_NUM);
216    std::string number(reinterpret_cast<const char *>(data), size);
217
218    SsBaseResult normalResult;
219    normalResult.index = static_cast<int32_t>(size % SERIAL_NUM);
220    normalResult.result = static_cast<int32_t>(size % BOOL_NUM);
221    normalResult.reason = static_cast<int32_t>(size);
222    normalResult.message = number;
223
224    MessageParcel mData;
225    MessageParcel mReply;
226    mData.WriteInt32(slotId);
227    mData.WriteInt32(normalResult.index);
228    mData.WriteInt32(normalResult.result);
229    mData.WriteInt32(normalResult.reason);
230    mData.WriteString(normalResult.message);
231    stub->OnSetCallRestrictionResponseInner(mData, mReply);
232    stub->OnSetCallTransferResponseInner(mData, mReply);
233    stub->OnSetCallWaitingResponseInner(mData, mReply);
234    stub->OnSetClipResponseInner(mData, mReply);
235    stub->OnSetClirResponseInner(mData, mReply);
236    stub->OnSetColpResponseInner(mData, mReply);
237    stub->OnSetColrResponseInner(mData, mReply);
238
239    MessageParcel crData;
240    MessageParcel crReply;
241    CallRestrictionResult crResult;
242    crResult.result.message = number;
243    crResult.status = static_cast<int32_t>(size % BOOL_NUM);
244    crResult.classCw = static_cast<int32_t>(size);
245    crData.WriteInt32(slotId);
246    WriteSsResult(crData, crResult.result, crResult.status, crResult.classCw, size);
247    stub->OnGetCallRestrictionResponseInner(crData, crReply);
248
249    MessageParcel cwData;
250    MessageParcel cwReply;
251    CallWaitResult cwResult;
252    cwResult.result.message = number;
253    cwResult.status = static_cast<int32_t>(size % BOOL_NUM);
254    cwResult.classCw = static_cast<int32_t>(size);
255    cwData.WriteInt32(slotId);
256    WriteSsResult(cwData, cwResult.result, cwResult.status, cwResult.classCw, size);
257    stub->OnGetCallWaitingResponseInner(cwData, cwReply);
258
259    MessageParcel clipData;
260    MessageParcel clipReply;
261    GetClipResult clipResult;
262    clipResult.result.message = number;
263    clipResult.clipStat = static_cast<int32_t>(size);
264    clipResult.action = static_cast<int32_t>(size);
265    clipData.WriteInt32(slotId);
266    WriteSsResult(clipData, clipResult.result, clipResult.action, clipResult.clipStat, size);
267    stub->OnGetClipResponseInner(clipData, clipReply);
268}
269
270void TestUTCallbackFunction(const uint8_t *data, size_t size, sptr<ImsCallCallbackStub> &stub)
271{
272    int32_t slotId = static_cast<int32_t>(size % SLOT_NUM);
273    std::string number(reinterpret_cast<const char *>(data), size);
274
275    MessageParcel clirData;
276    MessageParcel clirReply;
277    GetClirResult clirResult;
278    clirResult.result.message = number;
279    clirResult.clirStat = static_cast<int32_t>(size);
280    clirResult.action = static_cast<int32_t>(size);
281    clirData.WriteInt32(slotId);
282    WriteSsResult(clirData, clirResult.result, clirResult.action, clirResult.clirStat, size);
283    stub->OnGetClirResponseInner(clirData, clirReply);
284
285    MessageParcel colpData;
286    MessageParcel colpReply;
287    GetColpResult colpResult;
288    colpResult.result.message = number;
289    colpResult.colpStat = static_cast<int32_t>(size);
290    colpResult.action = static_cast<int32_t>(size);
291    colpData.WriteInt32(slotId);
292    WriteSsResult(colpData, colpResult.result, colpResult.action, colpResult.colpStat, size);
293    stub->OnGetColpResponseInner(colpData, colpReply);
294
295    MessageParcel colrData;
296    MessageParcel colrReply;
297    GetColrResult colrResult;
298    colrResult.result.message = number;
299    colrResult.colrStat = static_cast<int32_t>(size);
300    colrResult.action = static_cast<int32_t>(size);
301    colrData.WriteInt32(slotId);
302    WriteSsResult(colrData, colrResult.result, colrResult.action, colrResult.colrStat, size);
303    stub->OnGetColrResponseInner(colrData, colrReply);
304}
305
306void TestCFCallbackFunction(const uint8_t *data, size_t size, sptr<ImsCallCallbackStub> &stub)
307{
308    int32_t slotId = static_cast<int32_t>(size % SLOT_NUM);
309    std::string number(reinterpret_cast<const char *>(data), size);
310    MessageParcel cfData;
311    MessageParcel cfReply;
312    SsBaseResult normalResult;
313    CallForwardQueryResult cfCall;
314    normalResult.message = number;
315    int32_t callSize = 1;
316    int32_t flag = static_cast<int32_t>(size % BOOL_NUM);
317    cfCall.serial = static_cast<int32_t>(size % SERIAL_NUM);
318    cfCall.result = static_cast<int32_t>(size % BOOL_NUM);
319    cfCall.status = static_cast<int32_t>(size % BOOL_NUM);
320    cfCall.classx = static_cast<int32_t>(size);
321    cfCall.number = number;
322    cfCall.type = static_cast<int32_t>(size);
323    cfCall.reason = static_cast<int32_t>(size);
324
325    cfData.WriteInt32(slotId);
326    WriteSsResult(cfData, normalResult, callSize, flag, size);
327    cfData.WriteInt32(callSize);
328
329    if (!cfData.WriteInt32(cfCall.serial) || !cfData.WriteInt32(cfCall.result) || !cfData.WriteInt32(cfCall.status) ||
330        !cfData.WriteInt32(cfCall.classx) || !cfData.WriteString(cfCall.number) || !cfData.WriteInt32(cfCall.type) ||
331        !cfData.WriteInt32(cfCall.reason) || !cfData.WriteInt32(cfCall.time) || !cfData.WriteInt32(cfCall.startHour) ||
332        !cfData.WriteInt32(cfCall.startMinute) || !cfData.WriteInt32(cfCall.endHour) ||
333        !cfData.WriteInt32(cfCall.endMinute)) {
334        return;
335    }
336    stub->OnGetCallTransferResponseInner(cfData, cfReply);
337}
338
339void TestICCbWithCallMediaModeRequestReport(const uint8_t *data, size_t size, sptr<ImsCallCallbackStub> &stub)
340{
341    int32_t slotId = static_cast<int32_t>(size % SLOT_NUM);
342    MessageParcel callMediaModeRequestData;
343    MessageParcel callMediaModeRequestReply;
344    ImsCallModeReceiveInfo callModeRequest;
345    callModeRequest.callIndex = static_cast<int32_t>(size % CALL_INDEX_NUM);
346    callModeRequest.result = static_cast<ImsCallModeRequestResult>(size % REQUEST_NUM);
347    callModeRequest.callType = static_cast<ImsCallType>(size % TYPE_NUM);
348    callMediaModeRequestData.WriteInt32(slotId);
349    callMediaModeRequestData.WriteRawData((const void *)&callModeRequest, sizeof(ImsCallModeReceiveInfo));
350    stub->OnReceiveUpdateCallMediaModeRequestInner(callMediaModeRequestData, callMediaModeRequestReply);
351}
352
353void TestICCbWithCallMediaModeResponseReport(const uint8_t *data, size_t size, sptr<ImsCallCallbackStub> &stub)
354{
355    int32_t slotId = static_cast<int32_t>(size % SLOT_NUM);
356    MessageParcel callMediaModeResponseData;
357    MessageParcel callMediaModeResponseReply;
358    ImsCallModeReceiveInfo callModeResponse;
359    callModeResponse.callIndex = static_cast<int32_t>(size % CALL_INDEX_NUM);
360    callModeResponse.result = static_cast<ImsCallModeRequestResult>(size % REQUEST_NUM);
361    callModeResponse.callType = static_cast<ImsCallType>(size % TYPE_NUM);
362    callMediaModeResponseData.WriteInt32(slotId);
363    callMediaModeResponseData.WriteRawData((const void *)&callModeResponse, sizeof(ImsCallModeReceiveInfo));
364    stub->OnReceiveUpdateCallMediaModeResponseInner(callMediaModeResponseData, callMediaModeResponseReply);
365}
366
367void TestICCbWithCallSessionEventChanged(const uint8_t *data, size_t size, sptr<ImsCallCallbackStub> &stub)
368{
369    int32_t slotId = static_cast<int32_t>(size % SLOT_NUM);
370    MessageParcel callSessionData;
371    MessageParcel callSessionReply;
372    ImsCallSessionEventInfo callSessionEventInfo;
373    callSessionEventInfo.callIndex = static_cast<int32_t>(size % CALL_INDEX_NUM);
374    callSessionEventInfo.eventType = static_cast<VideoCallEventType>(size % VIDEO_CALL_EVENT_NUM);
375    callSessionData.WriteInt32(slotId);
376    callSessionData.WriteRawData((const void *)&callSessionEventInfo, sizeof(ImsCallSessionEventInfo));
377    stub->OnCallSessionEventChangedInner(callSessionData, callSessionReply);
378}
379
380void TestICCbWithPeerDimensionsChanged(const uint8_t *data, size_t size, sptr<ImsCallCallbackStub> &stub)
381{
382    int32_t slotId = static_cast<int32_t>(size % SLOT_NUM);
383    MessageParcel callPeerDimensionsData;
384    MessageParcel callPeerDimensionsReply;
385    ImsCallPeerDimensionsInfo callPeerDimensionsInfo;
386    callPeerDimensionsInfo.callIndex = static_cast<int32_t>(size % CALL_INDEX_NUM);
387    callPeerDimensionsInfo.width = static_cast<int32_t>(size);
388    callPeerDimensionsInfo.height = static_cast<int32_t>(size);
389    callPeerDimensionsData.WriteInt32(slotId);
390    callPeerDimensionsData.WriteRawData((const void *)&callPeerDimensionsInfo, sizeof(ImsCallPeerDimensionsInfo));
391    stub->OnPeerDimensionsChangedInner(callPeerDimensionsData, callPeerDimensionsReply);
392}
393
394void TestICCbWithCallDataUsageChanged(const uint8_t *data, size_t size, sptr<ImsCallCallbackStub> &stub)
395{
396    int32_t slotId = static_cast<int32_t>(size % SLOT_NUM);
397    MessageParcel callDataUsageIData;
398    MessageParcel callDataUsageIReply;
399    ImsCallDataUsageInfo callDataUsageInfo;
400    callDataUsageInfo.callIndex = static_cast<int32_t>(size % CALL_INDEX_NUM);
401    callDataUsageInfo.dataUsage = static_cast<int64_t>(size);
402    callDataUsageIData.WriteInt32(slotId);
403    callDataUsageIData.WriteRawData((const void *)&callDataUsageInfo, sizeof(ImsCallDataUsageInfo));
404    stub->OnCallDataUsageChangedInner(callDataUsageIData, callDataUsageIReply);
405}
406
407void TestICCbWithCameraCapabilitiesChanged(const uint8_t *data, size_t size, sptr<ImsCallCallbackStub> &stub)
408{
409    int32_t slotId = static_cast<int32_t>(size % SLOT_NUM);
410    MessageParcel cameraCapabilitiesData;
411    MessageParcel cameraCapabilitiesReply;
412    CameraCapabilitiesInfo cameraCapabilitiesInfo;
413    cameraCapabilitiesInfo.callIndex = static_cast<int32_t>(size % CALL_INDEX_NUM);
414    cameraCapabilitiesInfo.width = static_cast<int32_t>(size);
415    cameraCapabilitiesInfo.height = static_cast<int32_t>(size);
416    cameraCapabilitiesData.WriteInt32(slotId);
417    cameraCapabilitiesData.WriteRawData((const void *)&cameraCapabilitiesInfo, sizeof(CameraCapabilitiesInfo));
418    stub->OnCameraCapabilitiesChangedInner(cameraCapabilitiesData, cameraCapabilitiesReply);
419}
420
421void DoSomethingInterestingWithMyAPI(const uint8_t *data, size_t size)
422{
423    if (data == nullptr || size == 0) {
424        return;
425    }
426
427    if (!IsServiceInited()) {
428        return;
429    }
430
431    sptr<ImsCallCallbackStub> stub = (std::make_unique<ImsCallCallbackStub>()).release();
432    if (stub == nullptr) {
433        return;
434    }
435
436    OnRemoteRequest(data, size);
437    TestImsCallCallbackFunction(data, size, stub);
438    TestImsCallCallbackExFunction(data, size, stub);
439    TestImsConfigCallbackFunction(data, size, stub);
440    TestImsUTCallbackFunction(data, size, stub);
441    TestUTCallbackFunction(data, size, stub);
442    TestCFCallbackFunction(data, size, stub);
443    // IMS video call callback test(ICCb: ImsCallCallback)
444    TestICCbWithCallMediaModeRequestReport(data, size, stub);
445    TestICCbWithCallMediaModeResponseReport(data, size, stub);
446    TestICCbWithCallSessionEventChanged(data, size, stub);
447    TestICCbWithPeerDimensionsChanged(data, size, stub);
448    TestICCbWithCallDataUsageChanged(data, size, stub);
449    TestICCbWithCameraCapabilitiesChanged(data, size, stub);
450}
451} // namespace OHOS
452
453/* Fuzzer entry point */
454extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
455{
456    OHOS::AddCellularCallTokenFuzzer token;
457    /* Run your code on data */
458    OHOS::DoSomethingInterestingWithMyAPI(data, size);
459    return 0;
460}
461