1 /*
2 * Copyright (C) 2021 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
18 #include <fuzzer/FuzzedDataProvider.h>
19
20 #include "audio_hal_interface/le_audio_software.h"
21 #include "osi/include/properties.h"
22
23 using ::bluetooth::audio::le_audio::LeAudioClientInterface;
24
25 constexpr int32_t kRandomStringLength = 256;
26
27 constexpr uint8_t kBitsPerSample[] = {16, 24, 32};
28
29 constexpr uint8_t kChannelCount[] = {1, 2};
30
31 constexpr uint32_t kSampleRates[] = {16000, 24000, 44100, 48000, 88200, 96000};
32
33 extern "C" {
android_get_exported_namespace(const char *)34 struct android_namespace_t* android_get_exported_namespace(const char*) { return nullptr; }
35 }
36
onResume(bool)37 bool onResume(bool) { return true; }
38
onSuspend(void)39 bool onSuspend(void) { return true; }
40
onMetadataUpdate(const source_metadata_v7_t &,bluetooth::le_audio::DsaMode)41 bool onMetadataUpdate(const source_metadata_v7_t&, bluetooth::le_audio::DsaMode) { return true; }
42
onSinkMetadataUpdate(const sink_metadata_v7_t &)43 bool onSinkMetadataUpdate(const sink_metadata_v7_t&) { return true; }
44
source_init_delayed(void)45 static void source_init_delayed(void) {}
46
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)47 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
48 FuzzedDataProvider fdp(data, size);
49 osi_property_set("persist.bluetooth.a2dp_offload.disabled",
50 fdp.PickValueInArray({"true", "false"}));
51 std::string name = fdp.ConsumeRandomLengthString(kRandomStringLength);
52 bluetooth::common::MessageLoopThread messageLoopThread(name);
53 messageLoopThread.StartUp();
54 messageLoopThread.DoInThread(FROM_HERE, base::BindOnce(&source_init_delayed));
55
56 LeAudioClientInterface* interface = LeAudioClientInterface::Get();
57
58 bluetooth::audio::le_audio::StreamCallbacks streamCb = {onResume, onSuspend, onMetadataUpdate,
59 onSinkMetadataUpdate};
60
61 if (!interface->IsSourceAcquired()) {
62 LeAudioClientInterface::Source* source = interface->GetSource(streamCb, &messageLoopThread);
63 if (source != nullptr) {
64 uint16_t delay = fdp.ConsumeIntegral<uint16_t>();
65 source->SetRemoteDelay(delay);
66 LeAudioClientInterface::PcmParameters params;
67 params.data_interval_us =
68 fdp.ConsumeIntegralInRange<uint32_t>(1000, std::numeric_limits<uint32_t>::max());
69 params.sample_rate = fdp.PickValueInArray(kSampleRates);
70 params.bits_per_sample = fdp.PickValueInArray(kBitsPerSample);
71 params.channels_count = fdp.PickValueInArray(kChannelCount);
72 source->SetPcmParameters(params);
73 source->StartSession();
74 source->StopSession();
75 source->Cleanup();
76 }
77 interface->ReleaseSource(source);
78 }
79
80 if (!interface->IsUnicastSinkAcquired()) {
81 LeAudioClientInterface::Sink* sink = interface->GetSink(streamCb, &messageLoopThread, false);
82 if (sink != nullptr) {
83 uint16_t delay = fdp.ConsumeIntegral<uint16_t>();
84 sink->SetRemoteDelay(delay);
85 LeAudioClientInterface::PcmParameters params;
86 params.data_interval_us =
87 fdp.ConsumeIntegralInRange<uint32_t>(1000, std::numeric_limits<uint32_t>::max());
88 params.sample_rate = fdp.PickValueInArray(kSampleRates);
89 params.bits_per_sample = fdp.PickValueInArray(kBitsPerSample);
90 params.channels_count = fdp.PickValueInArray(kChannelCount);
91 sink->SetPcmParameters(params);
92 sink->StartSession();
93 sink->StopSession();
94 sink->Cleanup();
95 }
96 interface->ReleaseSink(sink);
97 }
98
99 messageLoopThread.ShutDown();
100 return 0;
101 }
102