* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "imsclient_fuzzer.h"
#include <cstddef>
#include <cstdint>
#define private public
#include "addcellularcalltoken_fuzzer.h"
#include "cellular_call_service.h"
#include "ims_call_client.h"
#include "ims_call_proxy.h"
#include "securec.h"
#include "surface_utils.h"
#include "system_ability_definition.h"
#include "fuzzer/FuzzedDataProvider.h"
using namespace OHOS::Telephony;
namespace OHOS {
static bool g_isInited = false;
constexpr int32_t SERVICE_STATE_RUNNING = 1;
constexpr int32_t IMS_CONFIG_ITEM_NUM = 2;
enum {
NUM_ONE = 1,
NUM_TWO,
NUM_THREE,
NUM_FOUR,
NUM_FIVE,
NUM_SIX,
NUM_SEVEN,
NUM_EIGHT,
};
bool IsServiceInited()
{
auto service = DelayedSingleton<CellularCallService>::GetInstance();
if (service == nullptr) {
return g_isInited;
}
if (service->GetServiceRunningState() != SERVICE_STATE_RUNNING) {
service->OnStart();
}
if (!g_isInited && service->GetServiceRunningState() == SERVICE_STATE_RUNNING) {
g_isInited = true;
}
return g_isInited;
}
void TestImsCallClientWithCallInfo(FuzzedDataProvider& provider, const std::shared_ptr<ImsCallClient> &imsCallClient)
{
ImsCallInfo callInfo;
if (memset_s(&callInfo, sizeof(struct ImsCallInfo), 0x00, sizeof(struct ImsCallInfo)) != EOK) {
return;
}
size_t maxSize = sizeof(callInfo.phoneNum) - 1;
size_t length = provider.ConsumeIntegralInRange<size_t>(0, maxSize);
std::string number = provider.ConsumeBytesAsString(length);
int32_t mode = provider.ConsumeIntegralInRange<int32_t>(0, NUM_TWO);
int32_t slotId = provider.ConsumeIntegralInRange<int32_t>(0, NUM_TWO);
int32_t videoState = provider.ConsumeIntegralInRange<int32_t>(0, NUM_THREE);
int32_t index = provider.ConsumeIntegralInRange<int32_t>(0, NUM_THREE);
const char *cDtmfCode = number.c_str();
if (strcpy_s(callInfo.phoneNum, sizeof(callInfo.phoneNum), number.c_str()) != EOK) {
return;
}
callInfo.slotId = slotId;
callInfo.videoState = videoState;
callInfo.index = index;
std::vector<std::string> numberList;
numberList.push_back(number);
imsCallClient->Dial(callInfo, static_cast<CLIRMode>(mode));
imsCallClient->HangUp(callInfo);
imsCallClient->Answer(callInfo);
imsCallClient->Reject(callInfo);
imsCallClient->RejectWithReason(callInfo, ImsRejectReason::USER_DECLINE);
imsCallClient->InviteToConference(slotId, numberList);
imsCallClient->KickOutFromConference(slotId, index);
imsCallClient->StartDtmf(slotId, *cDtmfCode, index);
imsCallClient->SendDtmf(slotId, *cDtmfCode, index);
imsCallClient->StopDtmf(slotId, index);
#ifdef SUPPORT_RTT_CALL
imsCallClient->UpdateImsRttCallMode(slotId, index, ImsRTTCallMode::LOCAL_REQUEST_UPGRADE);
#endif
imsCallClient->SetDomainPreferenceMode(slotId, mode);
imsCallClient->GetDomainPreferenceMode(slotId);
imsCallClient->SetImsSwitchStatus(slotId, mode);
imsCallClient->GetImsSwitchStatus(slotId);
imsCallClient->SetMute(slotId, mode);
imsCallClient->GetMute(slotId);
}
void TestImsCallClientWithSlotAndType(FuzzedDataProvider& provider,
const std::shared_ptr<ImsCallClient> &imsCallClient)
{
int32_t slotId = provider.ConsumeIntegralInRange<int32_t>(0, NUM_TWO);
int32_t index = provider.ConsumeIntegralInRange<int32_t>(0, NUM_EIGHT);
int32_t callType = provider.ConsumeIntegralInRange<int32_t>(0, NUM_TWO);
std::string info = provider.ConsumeRandomLengthString();
int32_t mode = provider.ConsumeIntegralInRange<int32_t>(0, NUM_SIX);
imsCallClient->HoldCall(slotId, callType);
imsCallClient->UnHoldCall(slotId, callType);
imsCallClient->SwitchCall(slotId, callType);
imsCallClient->CombineConference(slotId);
imsCallClient->GetImsCallsDataRequest(slotId, callType);
imsCallClient->GetLastCallFailReason(slotId);
imsCallClient->ControlCamera(slotId, index, info);
imsCallClient->SetPausePicture(slotId, index, info);
int len = static_cast<int>(info.length());
std::string subSurfaceId = info;
if (len >= 1) {
subSurfaceId = info.substr(0, 1);
}
if (subSurfaceId.empty() || subSurfaceId[0] < '0' || subSurfaceId[0] > '9') {
subSurfaceId = "";
imsCallClient->SetPreviewWindow(slotId, index, subSurfaceId, nullptr);
imsCallClient->SetDisplayWindow(slotId, index, subSurfaceId, nullptr);
} else {
uint64_t tmpSurfaceId = std::stoull(subSurfaceId);
auto surface = SurfaceUtils::GetInstance()->GetSurface(tmpSurfaceId);
imsCallClient->SetPreviewWindow(slotId, index, subSurfaceId, surface);
imsCallClient->SetDisplayWindow(slotId, index, subSurfaceId, surface);
}
imsCallClient->SetDeviceDirection(slotId, index, mode);
imsCallClient->SetCameraZoom(mode);
ImsCapabilityList imsCapabilityList;
ImsCapability capbility;
capbility.enable = mode;
capbility.imsCapabilityType = static_cast<ImsCapabilityType>(callType);
capbility.imsRadioTech = static_cast<ImsRegTech>(callType);
imsCapabilityList.imsCapabilities.push_back(capbility);
imsCallClient->UpdateImsCapabilities(slotId, imsCapabilityList);
}
void TestImsCallClientWithSettingFunction(FuzzedDataProvider& provider,
const std::shared_ptr<ImsCallClient> &imsCallClient)
{
CallTransferInfo transferInfo;
if (memset_s(&transferInfo, sizeof(struct CallTransferInfo), 0x00, sizeof(struct CallTransferInfo)) != EOK) {
return;
}
size_t maxSize = sizeof(transferInfo.transferNum) - 1;
size_t length = provider.ConsumeIntegralInRange<size_t>(0, maxSize);
std::string number = provider.ConsumeRandomLengthString(length);
int32_t mode = provider.ConsumeIntegralInRange<int32_t>(0, NUM_TWO);
int32_t slotId = provider.ConsumeIntegralInRange<int32_t>(0, NUM_TWO);
int32_t index = provider.ConsumeIntegralInRange<int32_t>(0, NUM_THREE);
int32_t item = provider.ConsumeIntegralInRange<int32_t>(0, IMS_CONFIG_ITEM_NUM);
int32_t value = provider.ConsumeIntegralInRange<int32_t>(0, NUM_FOUR);
int32_t type = provider.ConsumeIntegralInRange<int32_t>(0, NUM_FOUR);
imsCallClient->SetImsConfig(static_cast<ImsConfigItem>(item), number);
imsCallClient->SetImsConfig(static_cast<ImsConfigItem>(item), value);
imsCallClient->GetImsConfig(static_cast<ImsConfigItem>(item));
imsCallClient->SetImsFeatureValue(static_cast<FeatureType>(type), value);
imsCallClient->GetImsFeatureValue(static_cast<FeatureType>(type), value);
imsCallClient->SetClip(slotId, mode, index);
imsCallClient->GetClip(slotId, index);
imsCallClient->SetClir(slotId, mode, index);
imsCallClient->GetClir(slotId, index);
imsCallClient->SetCallWaiting(slotId, mode, type, index);
imsCallClient->GetCallWaiting(slotId, index);
imsCallClient->SetColr(slotId, mode, index);
imsCallClient->GetColr(slotId, index);
imsCallClient->SetColp(slotId, mode, index);
imsCallClient->GetColp(slotId, index);
if (strcpy_s(transferInfo.transferNum, sizeof(transferInfo.transferNum), number.c_str()) != EOK) {
return;
}
transferInfo.settingType = static_cast<CallTransferSettingType>(type);
transferInfo.type = static_cast<CallTransferType>(type);
imsCallClient->SetCallTransfer(slotId, transferInfo, type, index);
imsCallClient->GetCallTransfer(slotId, type, index);
imsCallClient->SetCallRestriction(slotId, number, mode, number, index);
imsCallClient->GetCallRestriction(slotId, number, index);
}
void TestImsCallClientWithCallMediaModeRequest(FuzzedDataProvider& provider,
const std::shared_ptr<ImsCallClient> &imsCallClient)
{
ImsCallInfo callInfo;
if (memset_s(&callInfo, sizeof(struct ImsCallInfo), 0x00, sizeof(struct ImsCallInfo)) != EOK) {
return;
}
size_t maxSize = sizeof(callInfo.phoneNum) - 1;
size_t length = provider.ConsumeIntegralInRange<size_t>(0, maxSize);
std::string number = provider.ConsumeRandomLengthString(length);
callInfo.slotId = provider.ConsumeIntegralInRange<int32_t>(0, NUM_TWO);
callInfo.videoState = provider.ConsumeIntegralInRange<int32_t>(0, NUM_TWO);
callInfo.index = provider.ConsumeIntegralInRange<int32_t>(0, NUM_EIGHT);
if (strcpy_s(callInfo.phoneNum, sizeof(callInfo.phoneNum), number.c_str()) != EOK) {
return;
}
ImsCallType callMode = static_cast<ImsCallType>(provider.ConsumeIntegralInRange<int32_t>(0, NUM_SIX));
imsCallClient->SendUpdateCallMediaModeRequest(callInfo, callMode);
}
void TestImsCallClientWithCallMediaModeResponse(FuzzedDataProvider& provider,
const std::shared_ptr<ImsCallClient> &imsCallClient)
{
ImsCallInfo callInfo;
if (memset_s(&callInfo, sizeof(struct ImsCallInfo), 0x00, sizeof(struct ImsCallInfo)) != EOK) {
return;
}
std::string number = provider.ConsumeRandomLengthString();
callInfo.slotId = provider.ConsumeIntegralInRange<int32_t>(0, NUM_TWO);
callInfo.videoState = provider.ConsumeIntegralInRange<int32_t>(0, NUM_TWO);
callInfo.index = provider.ConsumeIntegralInRange<int32_t>(0, NUM_EIGHT);
if (strcpy_s(callInfo.phoneNum, sizeof(callInfo.phoneNum), number.c_str()) != EOK) {
return;
}
ImsCallType callMode = static_cast<ImsCallType>(provider.ConsumeIntegralInRange<int32_t>(0, NUM_SIX));
imsCallClient->SendUpdateCallMediaModeResponse(callInfo, callMode);
}
void TestImsCallClientWithCancelCallUpgrade(FuzzedDataProvider& provider,
const std::shared_ptr<ImsCallClient> &imsCallClient)
{
int32_t slotId = provider.ConsumeIntegralInRange<int32_t>(0, NUM_TWO);
int32_t index = provider.ConsumeIntegralInRange<int32_t>(0, NUM_EIGHT);
imsCallClient->CancelCallUpgrade(slotId, index);
}
void TestImsCallClientWithRequestCameraCapabilities(FuzzedDataProvider& provider,
const std::shared_ptr<ImsCallClient> &imsCallClient)
{
int32_t slotId = provider.ConsumeIntegralInRange<int32_t>(0, NUM_TWO);
int32_t index = provider.ConsumeIntegralInRange<int32_t>(0, NUM_EIGHT);
imsCallClient->RequestCameraCapabilities(slotId, index);
}
void TestImsCallProxyWithCallInfo(FuzzedDataProvider& provider, const sptr<ImsCallInterface> &proxy)
{
ImsCallInfo callInfo;
if (memset_s(&callInfo, sizeof(struct ImsCallInfo), 0x00, sizeof(struct ImsCallInfo)) != EOK) {
return;
}
size_t maxSize = sizeof(callInfo.phoneNum) - 1;
size_t length = provider.ConsumeIntegralInRange<size_t>(0, maxSize);
std::string number = provider.ConsumeRandomLengthString(length);
int32_t mode = provider.ConsumeIntegralInRange<int32_t>(0, NUM_TWO);
int32_t slotId = provider.ConsumeIntegralInRange<int32_t>(0, NUM_TWO);
int32_t videoState = provider.ConsumeIntegralInRange<int32_t>(0, NUM_THREE);
int32_t index = provider.ConsumeIntegralInRange<int32_t>(0, NUM_THREE);
const char *cDtmfCode = number.c_str();
if (strcpy_s(callInfo.phoneNum, sizeof(callInfo.phoneNum), number.c_str()) != EOK) {
return;
}
callInfo.slotId = slotId;
callInfo.videoState = videoState;
callInfo.index = index;
std::vector<std::string> numberList;
numberList.push_back(number);
proxy->Dial(callInfo, static_cast<CLIRMode>(mode));
proxy->HangUp(callInfo);
proxy->Answer(callInfo);
proxy->RejectWithReason(callInfo, ImsRejectReason::USER_DECLINE);
proxy->InviteToConference(slotId, numberList);
proxy->KickOutFromConference(slotId, index);
proxy->StartDtmf(slotId, *cDtmfCode, index);
proxy->SendDtmf(slotId, *cDtmfCode, index);
proxy->StopDtmf(slotId, index);
#ifdef SUPPORT_RTT_CALL
proxy->UpdateImsRttCallMode(slotId, index, ImsRTTCallMode::LOCAL_REQUEST_UPGRADE);
#endif
proxy->SetDomainPreferenceMode(slotId, mode);
proxy->GetDomainPreferenceMode(slotId);
proxy->SetImsSwitchStatus(slotId, mode);
proxy->GetImsSwitchStatus(slotId);
proxy->SetMute(slotId, mode);
proxy->GetMute(slotId);
}
void TestImsCallProxyWithSlotAndType(FuzzedDataProvider& provider, const sptr<ImsCallInterface> &proxy)
{
int32_t slotId = provider.ConsumeIntegralInRange<int32_t>(0, NUM_TWO);
int32_t index = provider.ConsumeIntegralInRange<int32_t>(0, NUM_EIGHT);
int32_t callType = provider.ConsumeIntegralInRange<int32_t>(0, NUM_SIX);
std::string info = provider.ConsumeRandomLengthString();
int32_t mode = provider.ConsumeIntegralInRange<int32_t>(0, NUM_SIX);
proxy->HoldCall(slotId, callType);
proxy->UnHoldCall(slotId, callType);
proxy->SwitchCall(slotId, callType);
proxy->CombineConference(slotId);
proxy->GetImsCallsDataRequest(slotId, callType);
proxy->GetLastCallFailReason(slotId);
proxy->ControlCamera(slotId, index, info);
proxy->SetPausePicture(slotId, index, info);
int len = static_cast<int>(info.length());
std::string subSurfaceId = info;
if (len >= 1) {
subSurfaceId = info.substr(0, 1);
}
if (subSurfaceId.empty() || subSurfaceId[0] < '0' || subSurfaceId[0] > '9') {
subSurfaceId = "";
proxy->SetPreviewWindow(slotId, index, subSurfaceId, nullptr);
proxy->SetDisplayWindow(slotId, index, subSurfaceId, nullptr);
} else {
uint64_t tmpSurfaceId = std::stoull(subSurfaceId);
auto surface = SurfaceUtils::GetInstance()->GetSurface(tmpSurfaceId);
proxy->SetPreviewWindow(slotId, index, subSurfaceId, surface);
proxy->SetDisplayWindow(slotId, index, subSurfaceId, surface);
}
proxy->SetDeviceDirection(slotId, index, mode);
proxy->SetCameraZoom(mode);
ImsCapabilityList imsCapabilityList;
ImsCapability capbility;
capbility.enable = mode;
capbility.imsCapabilityType = static_cast<ImsCapabilityType>(callType);
capbility.imsRadioTech = static_cast<ImsRegTech>(callType);
imsCapabilityList.imsCapabilities.push_back(capbility);
proxy->UpdateImsCapabilities(slotId, imsCapabilityList);
}
void TestImsCallProxyWithSettingFunction(FuzzedDataProvider& provider, const sptr<ImsCallInterface> &proxy)
{
CallTransferInfo transferInfo;
if (memset_s(&transferInfo, sizeof(struct CallTransferInfo), 0x00, sizeof(struct CallTransferInfo)) != EOK) {
return;
}
size_t maxSize = sizeof(transferInfo.transferNum) - 1;
size_t length = provider.ConsumeIntegralInRange<size_t>(0, maxSize);
std::string number = provider.ConsumeRandomLengthString(length);
int32_t mode = provider.ConsumeIntegralInRange<int32_t>(0, NUM_TWO);
int32_t slotId = provider.ConsumeIntegralInRange<int32_t>(0, NUM_TWO);
int32_t index = provider.ConsumeIntegralInRange<int32_t>(0, NUM_THREE);
int32_t item = provider.ConsumeIntegralInRange<int32_t>(0, IMS_CONFIG_ITEM_NUM);
int32_t value = provider.ConsumeIntegralInRange<int32_t>(0, NUM_FOUR);
int32_t type = provider.ConsumeIntegralInRange<int32_t>(0, NUM_FOUR);
proxy->SetImsConfig(static_cast<ImsConfigItem>(item), number);
proxy->SetImsConfig(static_cast<ImsConfigItem>(item), value);
proxy->GetImsConfig(static_cast<ImsConfigItem>(item));
proxy->SetImsFeatureValue(static_cast<FeatureType>(type), value);
proxy->GetImsFeatureValue(static_cast<FeatureType>(type), value);
proxy->SetClip(slotId, mode, index);
proxy->GetClip(slotId, index);
proxy->SetClir(slotId, mode, index);
proxy->GetClir(slotId, index);
proxy->SetCallWaiting(slotId, mode, type, index);
proxy->GetCallWaiting(slotId, index);
proxy->SetColr(slotId, mode, index);
proxy->GetColr(slotId, index);
proxy->SetColp(slotId, mode, index);
proxy->GetColp(slotId, index);
if (strcpy_s(transferInfo.transferNum, sizeof(transferInfo.transferNum), number.c_str()) != EOK) {
return;
}
transferInfo.settingType = static_cast<CallTransferSettingType>(type);
transferInfo.type = static_cast<CallTransferType>(type);
proxy->SetCallTransfer(slotId, transferInfo, type, index);
proxy->GetCallTransfer(slotId, type, index);
proxy->SetCallRestriction(slotId, number, mode, number, index);
proxy->GetCallRestriction(slotId, number, index);
}
void TestImsCallProxyWithCallMediaModeRequest(FuzzedDataProvider& provider, const sptr<ImsCallInterface> &proxy)
{
ImsCallInfo callInfo;
if (memset_s(&callInfo, sizeof(struct ImsCallInfo), 0x00, sizeof(struct ImsCallInfo)) != EOK) {
return;
}
size_t maxSize = sizeof(callInfo.phoneNum) - 1;
size_t length = provider.ConsumeIntegralInRange<size_t>(0, maxSize);
std::string number = provider.ConsumeRandomLengthString(length);
callInfo.slotId = provider.ConsumeIntegralInRange<int32_t>(0, NUM_TWO);
callInfo.videoState = provider.ConsumeIntegralInRange<int32_t>(0, NUM_TWO);
callInfo.index = provider.ConsumeIntegralInRange<int32_t>(0, NUM_EIGHT);
if (strcpy_s(callInfo.phoneNum, sizeof(callInfo.phoneNum), number.c_str()) != EOK) {
return;
}
ImsCallType callType = static_cast<ImsCallType>(provider.ConsumeIntegralInRange<int32_t>(0, NUM_SIX));
proxy->SendUpdateCallMediaModeRequest(callInfo, callType);
}
void TestImsCallProxyWithCallMediaModeResponse(FuzzedDataProvider& provider, const sptr<ImsCallInterface> &proxy)
{
ImsCallInfo callInfo;
if (memset_s(&callInfo, sizeof(struct ImsCallInfo), 0x00, sizeof(struct ImsCallInfo)) != EOK) {
return;
}
size_t maxSize = sizeof(callInfo.phoneNum) - 1;
size_t length = provider.ConsumeIntegralInRange<size_t>(0, maxSize);
std::string number = provider.ConsumeRandomLengthString(length);
callInfo.slotId = provider.ConsumeIntegralInRange<int32_t>(0, NUM_TWO);
callInfo.videoState = provider.ConsumeIntegralInRange<int32_t>(0, NUM_TWO);
callInfo.index = provider.ConsumeIntegralInRange<int32_t>(0, NUM_EIGHT);
if (strcpy_s(callInfo.phoneNum, sizeof(callInfo.phoneNum), number.c_str()) != EOK) {
return;
}
ImsCallType callType = static_cast<ImsCallType>(provider.ConsumeIntegralInRange<int32_t>(0, NUM_SIX));
proxy->SendUpdateCallMediaModeResponse(callInfo, callType);
}
void TestImsCallProxyWithCancelCallUpgrade(FuzzedDataProvider& provider, const sptr<ImsCallInterface> &proxy)
{
int32_t slotId = provider.ConsumeIntegralInRange<int32_t>(0, NUM_TWO);
int32_t index = provider.ConsumeIntegralInRange<int32_t>(0, NUM_EIGHT);
proxy->CancelCallUpgrade(slotId, index);
}
void TestImsCallProxyWithRequestCameraCapabilities(FuzzedDataProvider& provider, const sptr<ImsCallInterface> &proxy)
{
int32_t slotId = provider.ConsumeIntegralInRange<int32_t>(0, NUM_TWO);
int32_t index = provider.ConsumeIntegralInRange<int32_t>(0, NUM_EIGHT);
proxy->RequestCameraCapabilities(slotId, index);
}
void DoSomethingInterestingWithMyAPI(FuzzedDataProvider& provider)
{
auto imsCallClient = DelayedSingleton<ImsCallClient>::GetInstance();
if (imsCallClient == nullptr) {
return;
}
if (!IsServiceInited()) {
return;
}
TestImsCallClientWithCallInfo(provider, imsCallClient);
TestImsCallClientWithSlotAndType(provider, imsCallClient);
TestImsCallClientWithSettingFunction(provider, imsCallClient);
TestImsCallClientWithCallMediaModeRequest(provider, imsCallClient);
TestImsCallClientWithCallMediaModeResponse(provider, imsCallClient);
TestImsCallClientWithCancelCallUpgrade(provider, imsCallClient);
TestImsCallClientWithRequestCameraCapabilities(provider, imsCallClient);
auto managerPtr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
if (managerPtr == nullptr) {
return;
}
auto remoteObjectPtr = managerPtr->CheckSystemAbility(TELEPHONY_IMS_SYS_ABILITY_ID);
if (remoteObjectPtr == nullptr) {
return;
}
sptr<ImsCallInterface> proxy = iface_cast<ImsCallInterface>(remoteObjectPtr);
if (proxy == nullptr) {
return;
}
TestImsCallProxyWithCallInfo(provider, proxy);
TestImsCallProxyWithSlotAndType(provider, proxy);
TestImsCallProxyWithSettingFunction(provider, proxy);
TestImsCallProxyWithCallMediaModeRequest(provider, proxy);
TestImsCallProxyWithCallMediaModeResponse(provider, proxy);
TestImsCallProxyWithCancelCallUpgrade(provider, proxy);
TestImsCallProxyWithRequestCameraCapabilities(provider, proxy);
proxy.clear();
proxy = nullptr;
}
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
OHOS::AddCellularCallTokenFuzzer token;
if (data == nullptr || size == 0) {
return 0;
}
FuzzedDataProvider provider(data, size);
OHOS::DoSomethingInterestingWithMyAPI(provider);
return 0;
}