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 "satelliteclient_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 "satellite_call_client.h"
24#include "satellite_call_proxy.h"
25#include "securec.h"
26#include "system_ability_definition.h"
27
28using namespace OHOS::Telephony;
29namespace OHOS {
30static bool g_isInited = false;
31constexpr int32_t SERVICE_STATE_RUNNING = 1;
32const uint32_t TELEPHONY_SATELLITE_SYS_ABILITY_ID = 4012;
33enum {
34    NUM_ONE = 1,
35    NUM_TWO,
36    NUM_THREE,
37    NUM_FOUR,
38    NUM_FIVE,
39    NUM_SIX,
40    NUM_SEVEN,
41    NUM_EIGHT,
42};
43
44bool IsServiceInited()
45{
46    auto service = DelayedSingleton<CellularCallService>::GetInstance();
47    if (service == nullptr) {
48        return g_isInited;
49    }
50    if (service->GetServiceRunningState() != SERVICE_STATE_RUNNING) {
51        service->OnStart();
52    }
53    if (!g_isInited && service->GetServiceRunningState() == SERVICE_STATE_RUNNING) {
54        g_isInited = true;
55    }
56    return g_isInited;
57}
58
59void TestSatelliteCallClientWithCallInfo(
60    const uint8_t *data, size_t size, const std::shared_ptr<SatelliteCallClient> &satelliteCallClient)
61{
62    SatelliteCallInfo callInfo;
63    if (memset_s(&callInfo, sizeof(struct SatelliteCallInfo), 0x00, sizeof(struct SatelliteCallInfo)) != EOK) {
64        return;
65    }
66    size_t length = std::min(static_cast<size_t>(sizeof(callInfo.phoneNum) - 1), size);
67    std::string number(reinterpret_cast<const char *>(data), length);
68    int32_t mode = static_cast<int32_t>(size % NUM_THREE);
69    int32_t slotId = static_cast<int32_t>(size % NUM_TWO);
70    int32_t index = static_cast<int32_t>(size % NUM_THREE);
71    if (strcpy_s(callInfo.phoneNum, sizeof(callInfo.phoneNum), number.c_str()) != EOK) {
72        return;
73    }
74    callInfo.slotId = slotId;
75    callInfo.index = index;
76    satelliteCallClient->Dial(callInfo, static_cast<CLIRMode>(mode));
77    satelliteCallClient->HangUp(slotId, index);
78    satelliteCallClient->Answer(slotId);
79    satelliteCallClient->Reject(slotId);
80
81    int32_t callType = static_cast<int32_t>(size % NUM_TWO);
82    satelliteCallClient->GetSatelliteCallsDataRequest(slotId, callType);
83}
84
85void TestSatelliteCallProxyWithCallInfo(const uint8_t *data, size_t size, const sptr<SatelliteCallInterface> &proxy)
86{
87    SatelliteCallInfo callInfo;
88    if (memset_s(&callInfo, sizeof(struct SatelliteCallInfo), 0x00, sizeof(struct SatelliteCallInfo)) != EOK) {
89        return;
90    }
91    size_t length = std::min(static_cast<size_t>(sizeof(callInfo.phoneNum) - 1), size);
92    std::string number(reinterpret_cast<const char *>(data), length);
93    int32_t mode = static_cast<int32_t>(size % NUM_THREE);
94    int32_t slotId = static_cast<int32_t>(size % NUM_TWO);
95    int32_t index = static_cast<int32_t>(size % NUM_THREE);
96    if (strcpy_s(callInfo.phoneNum, sizeof(callInfo.phoneNum), number.c_str()) != EOK) {
97        return;
98    }
99    callInfo.slotId = slotId;
100    callInfo.index = index;
101
102    proxy->Dial(callInfo, static_cast<CLIRMode>(mode));
103    proxy->HangUp(slotId, index);
104    proxy->Answer(slotId);
105    proxy->Reject(slotId);
106
107    proxy->GetSatelliteCallsDataRequest(slotId);
108}
109
110void DoSomethingInterestingWithMyAPI(const uint8_t *data, size_t size)
111{
112    if (data == nullptr || size == 0) {
113        return;
114    }
115    auto satelliteCallClient = DelayedSingleton<SatelliteCallClient>::GetInstance();
116    if (satelliteCallClient == nullptr) {
117        return;
118    }
119    if (!IsServiceInited()) {
120        return;
121    }
122    TestSatelliteCallClientWithCallInfo(data, size, satelliteCallClient);
123
124    auto managerPtr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
125    if (managerPtr == nullptr) {
126        return;
127    }
128    auto remoteObjectPtr = managerPtr->CheckSystemAbility(TELEPHONY_SATELLITE_SYS_ABILITY_ID);
129    if (remoteObjectPtr == nullptr) {
130        return;
131    }
132    sptr<SatelliteCallInterface> proxy = iface_cast<SatelliteCallInterface>(remoteObjectPtr);
133    if (proxy == nullptr) {
134        return;
135    }
136    TestSatelliteCallProxyWithCallInfo(data, size, proxy);
137    proxy.clear();
138    proxy = nullptr;
139}
140} // namespace OHOS
141
142/* Fuzzer entry point */
143extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
144{
145    OHOS::AddCellularCallTokenFuzzer token;
146    /* Run your code on data */
147    OHOS::DoSomethingInterestingWithMyAPI(data, size);
148    return 0;
149}
150