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 "getcallrestriction_fuzzer.h"
17
18#include <cstddef>
19#include <cstdint>
20#include <fuzzer/FuzzedDataProvider.h>
21#define private public
22#include "addcellularcalltoken_fuzzer.h"
23#include "cellular_call_service.h"
24#include "securec.h"
25#include "system_ability_definition.h"
26
27using namespace OHOS::Telephony;
28namespace OHOS {
29static bool g_isInited = false;
30constexpr int32_t SLOT_NUM = 2;
31constexpr int32_t VEDIO_STATE_NUM = 2;
32constexpr int32_t BOOL_NUM = 2;
33constexpr int32_t OFFSET_SIZE = 11;
34constexpr size_t MAX_NUMBER_LEN = 99;
35
36bool IsServiceInited()
37{
38    if (!g_isInited) {
39        DelayedSingleton<CellularCallService>::GetInstance()->OnStart();
40    }
41    if (!g_isInited && (static_cast<int32_t>(DelayedSingleton<CellularCallService>::GetInstance()->state_) ==
42                           static_cast<int32_t>(ServiceRunningState::STATE_RUNNING))) {
43        g_isInited = true;
44    }
45    return g_isInited;
46}
47
48void OnRemoteRequest(const uint8_t *data, size_t size)
49{
50    if (!IsServiceInited()) {
51        return;
52    }
53
54    MessageParcel dataMessageParcel;
55    if (!dataMessageParcel.WriteInterfaceToken(CellularCallStub::GetDescriptor())) {
56        return;
57    }
58    int32_t maxSize = static_cast<int32_t>(size) + OFFSET_SIZE;
59    dataMessageParcel.WriteInt32(maxSize);
60    dataMessageParcel.WriteBuffer(data, size);
61    dataMessageParcel.RewindRead(0);
62    uint32_t code = static_cast<uint32_t>(size);
63    MessageParcel reply;
64    MessageOption option;
65    DelayedSingleton<CellularCallService>::GetInstance()->OnRemoteRequest(code, dataMessageParcel, reply, option);
66}
67
68void UnRegisterCallManagerCallBack(const uint8_t *data, size_t size)
69{
70    if (!IsServiceInited()) {
71        return;
72    }
73
74    int32_t maxSize = static_cast<int32_t>(size);
75    MessageParcel dataMessageParcel;
76    dataMessageParcel.WriteInt32(maxSize);
77    dataMessageParcel.WriteBuffer(data, size);
78    dataMessageParcel.RewindRead(0);
79    MessageParcel reply;
80    DelayedSingleton<CellularCallService>::GetInstance()->OnUnRegisterCallBackInner(dataMessageParcel, reply);
81}
82
83void IsEmergencyPhoneNumber(const uint8_t *data, size_t size)
84{
85    if (!IsServiceInited()) {
86        return;
87    }
88
89    int32_t errorCode = static_cast<int32_t>(size);
90    std::string phoneNum(reinterpret_cast<const char *>(data), size);
91    MessageParcel dataMessageParcel;
92    dataMessageParcel.WriteInt32(errorCode);
93    dataMessageParcel.WriteString(phoneNum);
94    dataMessageParcel.RewindRead(0);
95    MessageParcel reply;
96    DelayedSingleton<CellularCallService>::GetInstance()->OnIsEmergencyPhoneNumberInner(dataMessageParcel, reply);
97}
98
99void HangUpAllConnection(const uint8_t *data, size_t size)
100{
101    if (!IsServiceInited()) {
102        return;
103    }
104
105    int32_t maxSize = static_cast<int32_t>(size);
106    MessageParcel dataMessageParcel;
107    dataMessageParcel.WriteInt32(maxSize);
108    dataMessageParcel.WriteBuffer(data, size);
109    dataMessageParcel.RewindRead(0);
110    MessageParcel reply;
111    DelayedSingleton<CellularCallService>::GetInstance()->OnHangUpAllConnectionInner(dataMessageParcel, reply);
112}
113
114void SetReadyToCall(const uint8_t *data, size_t size)
115{
116    if (!IsServiceInited()) {
117        return;
118    }
119
120    int32_t slotId = static_cast<int32_t>(size);
121    int32_t callType = static_cast<int32_t>(size % SLOT_NUM);
122    bool isReadyToCall = static_cast<bool>(size % SLOT_NUM);
123    MessageParcel dataMessageParcel;
124    dataMessageParcel.WriteInt32(slotId);
125    dataMessageParcel.WriteInt32(callType);
126    dataMessageParcel.WriteBool(isReadyToCall);
127    dataMessageParcel.RewindRead(0);
128    MessageParcel reply;
129    DelayedSingleton<CellularCallService>::GetInstance()->OnSetReadyToCallInner(dataMessageParcel, reply);
130}
131
132void StartRtt(const uint8_t *data, size_t size)
133{
134    if (!IsServiceInited()) {
135        return;
136    }
137
138    std::string msg(reinterpret_cast<const char *>(data), size);
139    MessageParcel dataMessageParcel;
140    dataMessageParcel.WriteString(msg);
141    dataMessageParcel.RewindRead(0);
142    MessageParcel reply;
143    DelayedSingleton<CellularCallService>::GetInstance()->OnStartRttInner(dataMessageParcel, reply);
144}
145
146void StopRtt(const uint8_t *data, size_t size)
147{
148    if (!IsServiceInited()) {
149        return;
150    }
151
152    MessageParcel dataMessageParcel;
153    dataMessageParcel.WriteBuffer(data, size);
154    dataMessageParcel.RewindRead(0);
155    MessageParcel reply;
156    DelayedSingleton<CellularCallService>::GetInstance()->OnStopRttInner(dataMessageParcel, reply);
157}
158
159void GetCallTransferInfo(const uint8_t *data, size_t size)
160{
161    if (!IsServiceInited()) {
162        return;
163    }
164
165    int32_t type = static_cast<int32_t>(size);
166    MessageParcel dataMessageParcel;
167    dataMessageParcel.WriteInt32(type);
168    dataMessageParcel.WriteBuffer(data, size);
169    dataMessageParcel.RewindRead(0);
170    MessageParcel reply;
171    DelayedSingleton<CellularCallService>::GetInstance()->OnGetCallTransferInner(dataMessageParcel, reply);
172}
173
174void GetCallWaiting(const uint8_t *data, size_t size)
175{
176    if (!IsServiceInited()) {
177        return;
178    }
179
180    MessageParcel dataMessageParcel;
181    dataMessageParcel.WriteBuffer(data, size);
182    dataMessageParcel.RewindRead(0);
183    MessageParcel reply;
184    DelayedSingleton<CellularCallService>::GetInstance()->OnGetCallWaitingInner(dataMessageParcel, reply);
185}
186
187void SetCallWaiting(const uint8_t *data, size_t size)
188{
189    if (!IsServiceInited()) {
190        return;
191    }
192
193    int32_t activate = static_cast<int32_t>(size % BOOL_NUM);
194    MessageParcel dataMessageParcel;
195    dataMessageParcel.WriteBool(activate);
196    dataMessageParcel.RewindRead(0);
197    MessageParcel reply;
198    DelayedSingleton<CellularCallService>::GetInstance()->OnSetCallWaitingInner(dataMessageParcel, reply);
199}
200
201void GetCallRestriction(const uint8_t *data, size_t size)
202{
203    if (!IsServiceInited()) {
204        return;
205    }
206
207    int32_t facType = static_cast<int32_t>(size);
208    MessageParcel dataMessageParcel;
209    dataMessageParcel.WriteInt32(facType);
210    dataMessageParcel.WriteBuffer(data, size);
211    dataMessageParcel.RewindRead(0);
212    MessageParcel reply;
213    DelayedSingleton<CellularCallService>::GetInstance()->OnGetCallRestrictionInner(dataMessageParcel, reply);
214}
215
216void SetCallRestrictionPassword(const uint8_t *data, size_t size)
217{
218    if (!IsServiceInited()) {
219        return;
220    }
221
222    int32_t slotId = static_cast<int32_t>(size % SLOT_NUM);
223    int32_t facType = static_cast<int32_t>(size);
224    MessageParcel dataMessageParcel;
225    dataMessageParcel.WriteInt32(slotId);
226    dataMessageParcel.WriteInt32(facType);
227    dataMessageParcel.WriteBuffer(data, size);
228    dataMessageParcel.RewindRead(0);
229    MessageParcel reply;
230    DelayedSingleton<CellularCallService>::GetInstance()->OnSetCallRestrictionPasswordInner(dataMessageParcel, reply);
231}
232
233void Dial(const uint8_t *data, size_t size)
234{
235    if (!IsServiceInited()) {
236        return;
237    }
238
239    int32_t maxSize = static_cast<int32_t>(size);
240    int32_t slotId = static_cast<int32_t>(size % SLOT_NUM);
241    int32_t callId = static_cast<int32_t>(size);
242    int32_t accountId = static_cast<int32_t>(size);
243    int32_t videoState = static_cast<int32_t>(size % VEDIO_STATE_NUM);
244    int32_t index = static_cast<int32_t>(size);
245    std::string telNum = "000000000";
246    std::string tempNum(reinterpret_cast<const char *>(data), size);
247    if (strlen(tempNum.c_str()) <= MAX_NUMBER_LEN) {
248        telNum = tempNum;
249    }
250    size_t length = strlen(telNum.c_str()) + 1;
251    CellularCallInfo callInfo;
252    callInfo.slotId = slotId;
253    callInfo.callId = callId;
254    callInfo.accountId = accountId;
255    callInfo.videoState = videoState;
256    callInfo.index = index;
257    if (strcpy_s(callInfo.phoneNum, length, telNum.c_str()) != EOK) {
258        return;
259    }
260    MessageParcel dataMessageParcel;
261    dataMessageParcel.WriteInt32(maxSize);
262    dataMessageParcel.WriteRawData(static_cast<const void *>(&callInfo), sizeof(CellularCallInfo));
263    dataMessageParcel.RewindRead(0);
264    MessageParcel reply;
265    DelayedSingleton<CellularCallService>::GetInstance()->OnDialInner(dataMessageParcel, reply);
266}
267
268void InviteToConference(const uint8_t *data, size_t size)
269{
270    if (!IsServiceInited()) {
271        return;
272    }
273
274    std::string number(reinterpret_cast<const char *>(data), size);
275    std::vector<std::string> numberList;
276    numberList.push_back(number);
277    MessageParcel dataMessageParcel;
278    dataMessageParcel.WriteStringVector(numberList);
279    dataMessageParcel.RewindRead(0);
280    MessageParcel reply;
281    DelayedSingleton<CellularCallService>::GetInstance()->OnInviteToConferenceInner(dataMessageParcel, reply);
282}
283
284void KickOutFromConference(const uint8_t *data, size_t size)
285{
286    if (!IsServiceInited()) {
287        return;
288    }
289
290    int32_t maxSize = static_cast<int32_t>(size);
291    int32_t slotId = static_cast<int32_t>(size % SLOT_NUM);
292    int32_t callId = static_cast<int32_t>(size);
293    int32_t accountId = static_cast<int32_t>(size);
294    int32_t videoState = static_cast<int32_t>(size % VEDIO_STATE_NUM);
295    int32_t index = static_cast<int32_t>(size);
296    std::string telNum = "000000000";
297    std::string tempNum(reinterpret_cast<const char *>(data), size);
298    if (strlen(tempNum.c_str()) <= MAX_NUMBER_LEN) {
299        telNum = tempNum;
300    }
301    size_t length = strlen(telNum.c_str()) + 1;
302    CellularCallInfo callInfo;
303    callInfo.slotId = slotId;
304    callInfo.callId = callId;
305    callInfo.accountId = accountId;
306    callInfo.videoState = videoState;
307    callInfo.index = index;
308    if (strcpy_s(callInfo.phoneNum, length, telNum.c_str()) != EOK) {
309        return;
310    }
311    MessageParcel dataMessageParcel;
312    dataMessageParcel.WriteInt32(maxSize);
313    dataMessageParcel.WriteRawData(static_cast<const void *>(&callInfo), sizeof(CellularCallInfo));
314    dataMessageParcel.RewindRead(0);
315    MessageParcel reply;
316    DelayedSingleton<CellularCallService>::GetInstance()->OnKickOutFromConferenceInner(dataMessageParcel, reply);
317}
318
319void doFuzzCellularCallService_1(const uint8_t *data, size_t size)
320{
321    auto cellularCallService = DelayedSingleton<CellularCallService>::GetInstance();
322    cellularCallService->OnStart();
323    FuzzedDataProvider fdp(data, size);
324    uint32_t code = fdp.ConsumeIntegralInRange<uint32_t>(1, 20);
325    if (fdp.remaining_bytes() == 0) {
326        return;
327    }
328    std::u16string service_token = u"OHOS.Telephony.CellularCallInterface";
329    MessageOption option;
330    MessageParcel dataParcel;
331    MessageParcel replyParcel;
332    std::vector<uint8_t> subData =
333        fdp.ConsumeBytes<uint8_t>(fdp.ConsumeIntegralInRange<size_t>(0, fdp.remaining_bytes()));
334    dataParcel.WriteInterfaceToken(service_token);
335    dataParcel.WriteBuffer(subData.data(), subData.size());
336    cellularCallService->OnRemoteRequest(code, dataParcel, replyParcel, option);
337}
338
339void doFuzzCellularCallService_2(const uint8_t *data, size_t size)
340{
341    auto cellularCallService = DelayedSingleton<CellularCallService>::GetInstance();
342    cellularCallService->OnStart();
343    FuzzedDataProvider fdp(data, size);
344    uint32_t code = fdp.ConsumeIntegralInRange<uint32_t>(100, 105);
345    if (fdp.remaining_bytes() == 0) {
346        return;
347    }
348    std::u16string service_token = u"OHOS.Telephony.CellularCallInterface";
349    MessageOption option;
350    MessageParcel dataParcel;
351    MessageParcel replyParcel;
352    std::vector<uint8_t> subData =
353        fdp.ConsumeBytes<uint8_t>(fdp.ConsumeIntegralInRange<size_t>(0, fdp.remaining_bytes()));
354    dataParcel.WriteInterfaceToken(service_token);
355    dataParcel.WriteBuffer(subData.data(), subData.size());
356    cellularCallService->OnRemoteRequest(code, dataParcel, replyParcel, option);
357}
358
359void doFuzzCellularCallService_3(const uint8_t *data, size_t size)
360{
361    auto cellularCallService = DelayedSingleton<CellularCallService>::GetInstance();
362    cellularCallService->OnStart();
363    FuzzedDataProvider fdp(data, size);
364    uint32_t code = fdp.ConsumeIntegralInRange<uint32_t>(200, 208);
365    if (fdp.remaining_bytes() == 0) {
366        return;
367    }
368    std::u16string service_token = u"OHOS.Telephony.CellularCallInterface";
369    MessageOption option;
370    MessageParcel dataParcel;
371    MessageParcel replyParcel;
372    std::vector<uint8_t> subData =
373        fdp.ConsumeBytes<uint8_t>(fdp.ConsumeIntegralInRange<size_t>(0, fdp.remaining_bytes()));
374    dataParcel.WriteInterfaceToken(service_token);
375    dataParcel.WriteBuffer(subData.data(), subData.size());
376    cellularCallService->OnRemoteRequest(code, dataParcel, replyParcel, option);
377}
378
379void doFuzzCellularCallService_4(const uint8_t *data, size_t size)
380{
381    auto cellularCallService = DelayedSingleton<CellularCallService>::GetInstance();
382    cellularCallService->OnStart();
383    FuzzedDataProvider fdp(data, size);
384    uint32_t code = fdp.ConsumeIntegralInRange<uint32_t>(300, 312);
385    if (fdp.remaining_bytes() == 0) {
386        return;
387    }
388    std::u16string service_token = u"OHOS.Telephony.CellularCallInterface";
389    MessageOption option;
390    MessageParcel dataParcel;
391    MessageParcel replyParcel;
392    std::vector<uint8_t> subData =
393        fdp.ConsumeBytes<uint8_t>(fdp.ConsumeIntegralInRange<size_t>(0, fdp.remaining_bytes()));
394    dataParcel.WriteInterfaceToken(service_token);
395    dataParcel.WriteBuffer(subData.data(), subData.size());
396    cellularCallService->OnRemoteRequest(code, dataParcel, replyParcel, option);
397}
398
399void doFuzzCellularCallService_5(const uint8_t *data, size_t size)
400{
401    auto cellularCallService = DelayedSingleton<CellularCallService>::GetInstance();
402    cellularCallService->OnStart();
403    FuzzedDataProvider fdp(data, size);
404    uint32_t code = fdp.ConsumeIntegralInRange<uint32_t>(400, 407);
405    if (fdp.remaining_bytes() == 0) {
406        return;
407    }
408    std::u16string service_token = u"OHOS.Telephony.CellularCallInterface";
409    MessageOption option;
410    MessageParcel dataParcel;
411    MessageParcel replyParcel;
412    std::vector<uint8_t> subData =
413        fdp.ConsumeBytes<uint8_t>(fdp.ConsumeIntegralInRange<size_t>(0, fdp.remaining_bytes()));
414    dataParcel.WriteInterfaceToken(service_token);
415    dataParcel.WriteBuffer(subData.data(), subData.size());
416    cellularCallService->OnRemoteRequest(code, dataParcel, replyParcel, option);
417}
418
419void DoSomethingInterestingWithMyAPI(const uint8_t *data, size_t size)
420{
421    if (data == nullptr || size == 0) {
422        return;
423    }
424
425    OnRemoteRequest(data, size);
426    UnRegisterCallManagerCallBack(data, size);
427    IsEmergencyPhoneNumber(data, size);
428    HangUpAllConnection(data, size);
429    SetReadyToCall(data, size);
430    StartRtt(data, size);
431    StopRtt(data, size);
432    GetCallTransferInfo(data, size);
433    GetCallWaiting(data, size);
434    SetCallWaiting(data, size);
435    GetCallRestriction(data, size);
436    SetCallRestrictionPassword(data, size);
437    Dial(data, size);
438    InviteToConference(data, size);
439    KickOutFromConference(data, size);
440    doFuzzCellularCallService_1(data, size);
441    doFuzzCellularCallService_2(data, size);
442    doFuzzCellularCallService_3(data, size);
443    doFuzzCellularCallService_4(data, size);
444    doFuzzCellularCallService_5(data, size);
445    return;
446}
447} // namespace OHOS
448
449/* Fuzzer entry point */
450extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
451{
452    OHOS::AddCellularCallTokenFuzzer token;
453    /* Run your code on data */
454    OHOS::DoSomethingInterestingWithMyAPI(data, size);
455    return 0;
456}
457