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 #include "rust/topshim/btav_sink/btav_sink_shim.h"
18
19 #include <memory>
20
21 #include "include/hardware/bluetooth.h"
22 #include "rust/cxx.h"
23 #include "src/profiles/a2dp.rs.h"
24 #include "types/raw_address.h"
25
26 namespace rusty = ::bluetooth::topshim::rust;
27
28 namespace bluetooth {
29 namespace topshim {
30 namespace rust {
31 namespace internal {
32 static A2dpSinkIntf* g_a2dp_sink_if;
33
to_rust_error(const btav_error_t & error)34 static A2dpError to_rust_error(const btav_error_t& error) {
35 A2dpError a2dp_error = {
36 .status = error.status,
37 .error_code = error.error_code,
38 .error_msg = error.error_msg.value_or(""),
39 };
40 return a2dp_error;
41 }
42
connection_state_cb(const RawAddress & addr,btav_connection_state_t state,const btav_error_t & error)43 static void connection_state_cb(
44 const RawAddress& addr, btav_connection_state_t state, const btav_error_t& error) {
45 A2dpError a2dp_error = to_rust_error(error);
46 rusty::sink_connection_state_callback(addr, state, a2dp_error);
47 }
audio_state_cb(const RawAddress & addr,btav_audio_state_t state)48 static void audio_state_cb(const RawAddress& addr, btav_audio_state_t state) {
49 rusty::sink_audio_state_callback(addr, state);
50 }
audio_config_cb(const RawAddress & addr,uint32_t sample_rate,uint8_t channel_count)51 static void audio_config_cb(const RawAddress& addr, uint32_t sample_rate, uint8_t channel_count) {
52 rusty::sink_audio_config_callback(addr, sample_rate, channel_count);
53 }
54
55 btav_sink_callbacks_t g_a2dp_sink_callbacks = {
56 sizeof(btav_sink_callbacks_t),
57 connection_state_cb,
58 audio_state_cb,
59 audio_config_cb,
60 };
61 } // namespace internal
62
~A2dpSinkIntf()63 A2dpSinkIntf::~A2dpSinkIntf() {
64 // TODO
65 }
66
GetA2dpSinkProfile(const unsigned char * btif)67 std::unique_ptr<A2dpSinkIntf> GetA2dpSinkProfile(const unsigned char* btif) {
68 if (internal::g_a2dp_sink_if) std::abort();
69
70 const bt_interface_t* btif_ = reinterpret_cast<const bt_interface_t*>(btif);
71
72 auto a2dp_sink = std::make_unique<A2dpSinkIntf>(
73 reinterpret_cast<const btav_sink_interface_t*>(btif_->get_profile_interface("a2dp_sink")));
74 internal::g_a2dp_sink_if = a2dp_sink.get();
75 return a2dp_sink;
76 }
77
init() const78 int A2dpSinkIntf::init() const {
79 return intf_->init(&internal::g_a2dp_sink_callbacks, 1);
80 }
81
connect(RawAddress addr) const82 int A2dpSinkIntf::connect(RawAddress addr) const {
83 return intf_->connect(addr);
84 }
85
disconnect(RawAddress addr) const86 int A2dpSinkIntf::disconnect(RawAddress addr) const {
87 return intf_->disconnect(addr);
88 }
89
set_active_device(RawAddress addr) const90 int A2dpSinkIntf::set_active_device(RawAddress addr) const {
91 return intf_->set_active_device(addr);
92 }
93
cleanup() const94 void A2dpSinkIntf::cleanup() const {
95 // TODO: Implement.
96 }
97
98 } // namespace rust
99 } // namespace topshim
100 } // namespace bluetooth
101