• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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 "bluetooth_socket_fbs_hal.h"
18 
19 #include <cstdint>
20 #include <future>
21 
22 #include "chre/platform/shared/host_protocol_common.h"
23 #include "chre_host/generated/host_messages_generated.h"
24 #include "chre_host/host_protocol_host.h"
25 #include "chre_host/log.h"
26 #include "flatbuffers/flatbuffers.h"
27 
28 namespace aidl::android::hardware::bluetooth::socket::impl {
29 
30 using ::android::chre::getStringFromByteVector;
31 using ndk::ScopedAStatus;
32 
registerCallback(const std::shared_ptr<IBluetoothSocketCallback> & callback)33 ScopedAStatus BluetoothSocketFbsHal::registerCallback(
34     const std::shared_ptr<IBluetoothSocketCallback> &callback) {
35   mCallback = callback;
36   return ScopedAStatus::ok();
37 }
38 
getSocketCapabilities(SocketCapabilities * result)39 ScopedAStatus BluetoothSocketFbsHal::getSocketCapabilities(
40     SocketCapabilities *result) {
41   std::future<SocketCapabilities> future = mCapabilitiesPromise.get_future();
42 
43   flatbuffers::FlatBufferBuilder builder(64);
44   auto socketCapabilitiesRequest =
45       ::chre::fbs::CreateBtSocketCapabilitiesRequest(builder);
46   ::chre::HostProtocolCommon::finalize(
47       builder, ::chre::fbs::ChreMessage::BtSocketCapabilitiesRequest,
48       socketCapabilitiesRequest.Union());
49 
50   if (!mOffloadLinkAvailable) {
51     LOGE("BT Socket Offload Link not available");
52     return ScopedAStatus::fromServiceSpecificErrorWithMessage(
53         static_cast<int32_t>(STATUS_UNKNOWN_ERROR),
54         "BT offload link not available");
55   }
56 
57   if (!mOffloadLink->sendMessageToOffloadStack(builder.GetBufferPointer(),
58                                                builder.GetSize())) {
59     LOGE("Failed to send BT socket capabilities request message");
60     return ScopedAStatus::fromServiceSpecificErrorWithMessage(
61         static_cast<int32_t>(STATUS_UNKNOWN_ERROR),
62         "Failed to send BT socket message");
63   }
64 
65   std::future_status status = future.wait_for(std::chrono::seconds(5));
66   if (status != std::future_status::ready) {
67     LOGE("BT Socket capabilities request timed out");
68     return ScopedAStatus::fromServiceSpecificErrorWithMessage(
69         static_cast<int32_t>(STATUS_UNKNOWN_ERROR),
70         "BT socket capabilities request timed out");
71   }
72 
73   *result = future.get();
74   return ScopedAStatus::ok();
75 }
76 
opened(const SocketContext & context)77 ScopedAStatus BluetoothSocketFbsHal::opened(const SocketContext &context) {
78   LOGD("Host opened BT offload socket ID=%" PRIu64, context.socketId);
79   if (!mOffloadLinkAvailable) {
80     LOGE("BT Socket Offload Link not available");
81     return ScopedAStatus::fromServiceSpecificErrorWithMessage(
82         static_cast<int32_t>(STATUS_UNKNOWN_ERROR),
83         "BT offload link not available");
84   }
85   if (context.channelInfo.getTag() != ChannelInfo::Tag::leCocChannelInfo) {
86     LOGE("Got open request for unsupported socket type %" PRId32,
87          context.channelInfo.getTag());
88     sendOpenedCompleteMessage(context.socketId, Status::FAILURE,
89                               "Unsupported socket type");
90     return ScopedAStatus::ok();
91   }
92   flatbuffers::FlatBufferBuilder builder(1028);
93   auto socketName = ::chre::HostProtocolCommon::addStringAsByteVector(
94       builder, context.name.c_str());
95   const auto &socketChannelInfo =
96       context.channelInfo.get<ChannelInfo::Tag::leCocChannelInfo>();
97   auto leCocChannelInfo = ::chre::fbs::CreateLeCocChannelInfo(
98       builder, socketChannelInfo.localCid, socketChannelInfo.remoteCid,
99       socketChannelInfo.psm, socketChannelInfo.localMtu,
100       socketChannelInfo.remoteMtu, socketChannelInfo.localMps,
101       socketChannelInfo.remoteMps, socketChannelInfo.initialRxCredits,
102       socketChannelInfo.initialTxCredits);
103 
104   auto socketOpen = ::chre::fbs::CreateBtSocketOpen(
105       builder, context.socketId, socketName, context.aclConnectionHandle,
106       ::chre::fbs::ChannelInfo::LeCocChannelInfo, leCocChannelInfo.Union(),
107       context.endpointId.hubId, context.endpointId.id);
108   ::chre::HostProtocolCommon::finalize(
109       builder, ::chre::fbs::ChreMessage::BtSocketOpen, socketOpen.Union());
110 
111   if (!mOffloadLink->sendMessageToOffloadStack(builder.GetBufferPointer(),
112                                                builder.GetSize())) {
113     LOGE("Failed to send BT socket opened message");
114     return ScopedAStatus::fromServiceSpecificErrorWithMessage(
115         static_cast<int32_t>(STATUS_UNKNOWN_ERROR),
116         "Failed to send BT socket message");
117   }
118   return ScopedAStatus::ok();
119 }
120 
closed(int64_t socketId)121 ScopedAStatus BluetoothSocketFbsHal::closed(int64_t socketId) {
122   LOGD("Host closed BT offload socket ID=%" PRIu64, socketId);
123   if (!mOffloadLinkAvailable) {
124     LOGE("BT Socket Offload Link not available");
125     return ScopedAStatus::fromServiceSpecificErrorWithMessage(
126         static_cast<int32_t>(STATUS_UNKNOWN_ERROR),
127         "BT offload link not available");
128   }
129 
130   flatbuffers::FlatBufferBuilder builder(64);
131   auto socketCloseResponse =
132       ::chre::fbs::CreateBtSocketCloseResponse(builder, socketId);
133   ::chre::HostProtocolCommon::finalize(
134       builder, ::chre::fbs::ChreMessage::BtSocketCloseResponse,
135       socketCloseResponse.Union());
136 
137   if (!mOffloadLink->sendMessageToOffloadStack(builder.GetBufferPointer(),
138                                                builder.GetSize())) {
139     LOGE("Failed to send BT socket closed message");
140     return ScopedAStatus::fromServiceSpecificErrorWithMessage(
141         static_cast<int32_t>(STATUS_UNKNOWN_ERROR),
142         "Failed to send BT socket message");
143   }
144 
145   return ScopedAStatus::ok();
146 }
147 
handleMessageFromOffloadStack(const void * message,size_t length)148 void BluetoothSocketFbsHal::handleMessageFromOffloadStack(const void *message,
149                                                           size_t length) {
150   if (!chre::HostProtocolCommon::verifyMessage(message, length)) {
151     LOGE("Could not decode Bluetooth Socket message");
152   } else {
153     std::unique_ptr<chre::fbs::MessageContainerT> container =
154         chre::fbs::UnPackMessageContainer(message);
155     chre::fbs::ChreMessageUnion &msg = container->message;
156     switch (container->message.type) {
157       case chre::fbs::ChreMessage::BtSocketOpenResponse:
158         handleBtSocketOpenResponse(*msg.AsBtSocketOpenResponse());
159         break;
160 
161       case chre::fbs::ChreMessage::BtSocketClose:
162         handleBtSocketClose(*msg.AsBtSocketClose());
163         break;
164 
165       case chre::fbs::ChreMessage::BtSocketCapabilitiesResponse:
166         handleBtSocketCapabilitiesResponse(
167             *msg.AsBtSocketCapabilitiesResponse());
168         break;
169 
170       default:
171         LOGW("Got unexpected Bluetooth Socket message type %" PRIu8,
172              static_cast<uint8_t>(msg.type));
173         break;
174     }
175   }
176 }
177 
handleBtSocketOpenResponse(const::chre::fbs::BtSocketOpenResponseT & response)178 void BluetoothSocketFbsHal::handleBtSocketOpenResponse(
179     const ::chre::fbs::BtSocketOpenResponseT &response) {
180   std::string reason = std::string(getStringFromByteVector(response.reason));
181   LOGD("Got BT Socket open response, socket ID=%" PRIu64
182        ", status=%d, reason=%s",
183        response.socketId, response.status, reason.c_str());
184   sendOpenedCompleteMessage(
185       response.socketId,
186       response.status == ::chre::fbs::BtSocketOpenStatus::SUCCESS
187           ? Status::SUCCESS
188           : Status::FAILURE,
189       reason);
190 }
191 
handleBtSocketClose(const::chre::fbs::BtSocketCloseT & message)192 void BluetoothSocketFbsHal::handleBtSocketClose(
193     const ::chre::fbs::BtSocketCloseT &message) {
194   std::string reason = std::string(getStringFromByteVector(message.reason));
195   LOGD("Got BT Socket close, socket ID=%" PRIu64 ", reason=%s",
196        message.socketId, reason.c_str());
197   if (mCallback == nullptr) {
198     LOGE("Received socket close message with no registered callback");
199     return;
200   }
201   mCallback->close(message.socketId, reason);
202 }
203 
handleBtSocketCapabilitiesResponse(const::chre::fbs::BtSocketCapabilitiesResponseT & response)204 void BluetoothSocketFbsHal::handleBtSocketCapabilitiesResponse(
205     const ::chre::fbs::BtSocketCapabilitiesResponseT &response) {
206   LOGD("Got BT Socket capabilities response");
207   SocketCapabilities capabilities = {
208       .leCocCapabilities =
209           {
210               .numberOfSupportedSockets =
211                   response.leCocCapabilities->numberOfSupportedSockets,
212               .mtu = response.leCocCapabilities->mtu,
213           },
214       .rfcommCapabilities =
215           {
216               .numberOfSupportedSockets =
217                   response.rfcommCapabilities->numberOfSupportedSockets,
218               .maxFrameSize = response.rfcommCapabilities->maxFrameSize,
219           },
220   };
221   mCapabilitiesPromise.set_value(capabilities);
222 }
223 
sendOpenedCompleteMessage(int64_t socketId,Status status,std::string reason)224 void BluetoothSocketFbsHal::sendOpenedCompleteMessage(int64_t socketId,
225                                                       Status status,
226                                                       std::string reason) {
227   if (mCallback == nullptr) {
228     LOGE("Sending socket opened complete with no registered callback");
229     return;
230   }
231   mCallback->openedComplete(socketId, status, reason);
232 }
233 
234 }  // namespace aidl::android::hardware::bluetooth::socket::impl
235