• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 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 "host_protocol_host_v4.h"
18 
19 #include <chre_host/host_protocol_host.h>
20 
21 #include "permissions_util.h"
22 
23 namespace android::hardware::contexthub::common::implementation {
24 
25 using ::chre::fbs::ChreMessage;
26 using ::chre::fbs::EndpointId;
27 using ::chre::fbs::EndpointInfo;
28 using ::chre::fbs::MessageDeliveryStatus;
29 using ::chre::fbs::MessageHub;
30 using ::chre::fbs::MessageHubDetails;
31 using ::chre::fbs::Reason;
32 using ::flatbuffers::FlatBufferBuilder;
33 using ::flatbuffers::Offset;
34 using ::flatbuffers::Vector;
35 
36 using AidlContextHubInfo =
37     ::aidl::android::hardware::contexthub::ContextHubInfo;
38 using AidlVendorHubInfo = ::aidl::android::hardware::contexthub::VendorHubInfo;
39 using AidlErrorCode = ::aidl::android::hardware::contexthub::ErrorCode;
40 using AidlRpcFormat = ::aidl::android::hardware::contexthub::Service::RpcFormat;
41 
encodeGetMessageHubsAndEndpointsRequest(FlatBufferBuilder & builder)42 void HostProtocolHostV4::encodeGetMessageHubsAndEndpointsRequest(
43     FlatBufferBuilder &builder) {
44   auto msg = ::chre::fbs::CreateGetMessageHubsAndEndpointsRequest(builder);
45   finalize(builder, ChreMessage::GetMessageHubsAndEndpointsRequest,
46            msg.Union());
47 }
48 
encodeGetMessageHubsAndEndpointsResponse(FlatBufferBuilder & builder,const std::vector<AidlHubInfo> & hubs,const std::vector<AidlEndpointInfo> & endpoints)49 void HostProtocolHostV4::encodeGetMessageHubsAndEndpointsResponse(
50     FlatBufferBuilder &builder, const std::vector<AidlHubInfo> &hubs,
51     const std::vector<AidlEndpointInfo> &endpoints) {
52   std::vector<Offset<MessageHub>> fbsHubs;
53   fbsHubs.reserve(hubs.size());
54   for (const auto &hub : hubs)
55     fbsHubs.push_back(aidlToFbsMessageHub(builder, hub));
56   std::vector<Offset<EndpointInfo>> fbsEndpoints;
57   for (const auto &endpoint : endpoints)
58     fbsEndpoints.push_back(aidlToFbsEndpointInfo(builder, endpoint));
59   auto hubsVector = builder.CreateVector(fbsHubs);
60   auto endpointsVector = builder.CreateVector(fbsEndpoints);
61   auto msg = ::chre::fbs::CreateGetMessageHubsAndEndpointsResponse(
62       builder, hubsVector, endpointsVector);
63   finalize(builder, ChreMessage::GetMessageHubsAndEndpointsResponse,
64            msg.Union());
65 }
66 
encodeRegisterMessageHub(FlatBufferBuilder & builder,const AidlHubInfo & info)67 void HostProtocolHostV4::encodeRegisterMessageHub(FlatBufferBuilder &builder,
68                                                   const AidlHubInfo &info) {
69   auto msg = ::chre::fbs::CreateRegisterMessageHub(
70       builder, aidlToFbsMessageHub(builder, info));
71   finalize(builder, ChreMessage::RegisterMessageHub, msg.Union());
72 }
73 
encodeUnregisterMessageHub(FlatBufferBuilder & builder,int64_t id)74 void HostProtocolHostV4::encodeUnregisterMessageHub(FlatBufferBuilder &builder,
75                                                     int64_t id) {
76   auto msg = ::chre::fbs::CreateUnregisterMessageHub(builder, id);
77   finalize(builder, ChreMessage::UnregisterMessageHub, msg.Union());
78 }
79 
encodeRegisterEndpoint(FlatBufferBuilder & builder,const AidlEndpointInfo & info)80 void HostProtocolHostV4::encodeRegisterEndpoint(FlatBufferBuilder &builder,
81                                                 const AidlEndpointInfo &info) {
82   auto msg = ::chre::fbs::CreateRegisterEndpoint(
83       builder, aidlToFbsEndpointInfo(builder, info));
84   finalize(builder, ChreMessage::RegisterEndpoint, msg.Union());
85 }
86 
encodeUnregisterEndpoint(FlatBufferBuilder & builder,const AidlEndpointId & id)87 void HostProtocolHostV4::encodeUnregisterEndpoint(FlatBufferBuilder &builder,
88                                                   const AidlEndpointId &id) {
89   auto msg = ::chre::fbs::CreateUnregisterEndpoint(
90       builder, aidlToFbsEndpointId(builder, id));
91   finalize(builder, ChreMessage::UnregisterEndpoint, msg.Union());
92 }
93 
encodeOpenEndpointSessionRequest(FlatBufferBuilder & builder,int64_t hostHubId,uint16_t sessionId,const AidlEndpointId & initiator,const AidlEndpointId & destination,const std::optional<std::string> & serviceDescriptor)94 void HostProtocolHostV4::encodeOpenEndpointSessionRequest(
95     FlatBufferBuilder &builder, int64_t hostHubId, uint16_t sessionId,
96     const AidlEndpointId &initiator, const AidlEndpointId &destination,
97     const std::optional<std::string> &serviceDescriptor) {
98   Offset<Vector<int8_t>> descriptorVector =
99       serviceDescriptor
100           ? addStringAsByteVector(builder, serviceDescriptor->c_str())
101           : 0;
102   auto msg = ::chre::fbs::CreateOpenEndpointSessionRequest(
103       builder, hostHubId, sessionId, aidlToFbsEndpointId(builder, initiator),
104       aidlToFbsEndpointId(builder, destination), descriptorVector);
105   finalize(builder, ChreMessage::OpenEndpointSessionRequest, msg.Union());
106 }
107 
encodeEndpointSessionOpened(FlatBufferBuilder & builder,int64_t hostHubId,uint16_t sessionId)108 void HostProtocolHostV4::encodeEndpointSessionOpened(FlatBufferBuilder &builder,
109                                                      int64_t hostHubId,
110                                                      uint16_t sessionId) {
111   auto msg =
112       ::chre::fbs::CreateEndpointSessionOpened(builder, hostHubId, sessionId);
113   finalize(builder, ChreMessage::EndpointSessionOpened, msg.Union());
114 }
115 
encodeEndpointSessionClosed(FlatBufferBuilder & builder,int64_t hostHubId,uint16_t sessionId,AidlReason reason)116 void HostProtocolHostV4::encodeEndpointSessionClosed(FlatBufferBuilder &builder,
117                                                      int64_t hostHubId,
118                                                      uint16_t sessionId,
119                                                      AidlReason reason) {
120   auto msg = ::chre::fbs::CreateEndpointSessionClosed(
121       builder, hostHubId, sessionId, static_cast<Reason>(reason));
122   finalize(builder, ChreMessage::EndpointSessionClosed, msg.Union());
123 }
124 
encodeEndpointSessionMessage(FlatBufferBuilder & builder,int64_t hostHubId,uint16_t sessionId,const AidlMessage & message)125 void HostProtocolHostV4::encodeEndpointSessionMessage(
126     FlatBufferBuilder &builder, int64_t hostHubId, uint16_t sessionId,
127     const AidlMessage &message) {
128   auto msg = ::chre::fbs::CreateEndpointSessionMessage(
129       builder, hostHubId, sessionId, message.type,
130       androidToChrePermissions(message.permissions),
131       builder.CreateVector(message.content), message.flags,
132       message.sequenceNumber);
133   finalize(builder, ChreMessage::EndpointSessionMessage, msg.Union());
134 }
135 
encodeEndpointSessionMessageDeliveryStatus(FlatBufferBuilder & builder,int64_t hostHubId,uint16_t sessionId,const AidlMessageDeliveryStatus & status)136 void HostProtocolHostV4::encodeEndpointSessionMessageDeliveryStatus(
137     FlatBufferBuilder &builder, int64_t hostHubId, uint16_t sessionId,
138     const AidlMessageDeliveryStatus &status) {
139   auto fbsStatus = ::chre::fbs::CreateMessageDeliveryStatus(
140       builder, status.messageSequenceNumber,
141       static_cast<int8_t>(status.errorCode));
142   auto msg = ::chre::fbs::CreateEndpointSessionMessageDeliveryStatus(
143       builder, hostHubId, sessionId, fbsStatus);
144   finalize(builder, ChreMessage::EndpointSessionMessageDeliveryStatus,
145            msg.Union());
146 }
147 
148 namespace {
149 
stringFromBytes(const std::vector<int8_t> & bytes)150 std::string stringFromBytes(const std::vector<int8_t> &bytes) {
151   auto *cStr = ::android::chre::getStringFromByteVector(bytes);
152   return cStr ? std::string(cStr) : std::string();
153 }
154 
155 }  // namespace
156 
decodeGetMessageHubsAndEndpointsResponse(const::chre::fbs::GetMessageHubsAndEndpointsResponseT & msg,std::vector<AidlHubInfo> & hubs,std::vector<AidlEndpointInfo> & endpoints)157 void HostProtocolHostV4::decodeGetMessageHubsAndEndpointsResponse(
158     const ::chre::fbs::GetMessageHubsAndEndpointsResponseT &msg,
159     std::vector<AidlHubInfo> &hubs, std::vector<AidlEndpointInfo> &endpoints) {
160   for (const auto &hub : msg.hubs) hubs.push_back(fbsMessageHubToAidl(*hub));
161   for (const auto &endpoint : msg.endpoints)
162     endpoints.push_back(fbsEndpointInfoToAidl(*endpoint));
163 }
164 
decodeRegisterMessageHub(const::chre::fbs::RegisterMessageHubT & msg,AidlHubInfo & info)165 void HostProtocolHostV4::decodeRegisterMessageHub(
166     const ::chre::fbs::RegisterMessageHubT &msg, AidlHubInfo &info) {
167   info = fbsMessageHubToAidl(*msg.hub);
168 }
169 
decodeUnregisterMessageHub(const::chre::fbs::UnregisterMessageHubT & msg,int64_t & id)170 void HostProtocolHostV4::decodeUnregisterMessageHub(
171     const ::chre::fbs::UnregisterMessageHubT &msg, int64_t &id) {
172   id = msg.id;
173 }
174 
decodeRegisterEndpoint(const::chre::fbs::RegisterEndpointT & msg,AidlEndpointInfo & info)175 void HostProtocolHostV4::decodeRegisterEndpoint(
176     const ::chre::fbs::RegisterEndpointT &msg, AidlEndpointInfo &info) {
177   info = fbsEndpointInfoToAidl(*msg.endpoint);
178 }
179 
decodeAddServiceToEndpoint(const::chre::fbs::AddServiceToEndpointT & msg,AidlEndpointId & id,AidlService & service)180 void HostProtocolHostV4::decodeAddServiceToEndpoint(
181     const ::chre::fbs::AddServiceToEndpointT &msg, AidlEndpointId &id,
182     AidlService &service) {
183   id = fbsEndpointIdToAidl(*msg.endpoint);
184   service.format = static_cast<AidlRpcFormat>(msg.service->format);
185   service.serviceDescriptor = stringFromBytes(msg.service->descriptor);
186   service.majorVersion = msg.service->major_version;
187   service.minorVersion = msg.service->minor_version;
188 }
189 
decodeEndpointReady(const::chre::fbs::EndpointReadyT & msg,AidlEndpointId & id)190 void HostProtocolHostV4::decodeEndpointReady(
191     const ::chre::fbs::EndpointReadyT &msg, AidlEndpointId &id) {
192   id = fbsEndpointIdToAidl(*msg.endpoint);
193 }
194 
decodeUnregisterEndpoint(const::chre::fbs::UnregisterEndpointT & msg,AidlEndpointId & id)195 void HostProtocolHostV4::decodeUnregisterEndpoint(
196     const ::chre::fbs::UnregisterEndpointT &msg, AidlEndpointId &id) {
197   id = fbsEndpointIdToAidl(*msg.endpoint);
198 }
199 
decodeOpenEndpointSessionRequest(const::chre::fbs::OpenEndpointSessionRequestT & msg,int64_t & hubId,uint16_t & sessionId,AidlEndpointId & hostEndpoint,AidlEndpointId & embeddedEndpoint,std::optional<std::string> & serviceDescriptor)200 void HostProtocolHostV4::decodeOpenEndpointSessionRequest(
201     const ::chre::fbs::OpenEndpointSessionRequestT &msg, int64_t &hubId,
202     uint16_t &sessionId, AidlEndpointId &hostEndpoint,
203     AidlEndpointId &embeddedEndpoint,
204     std::optional<std::string> &serviceDescriptor) {
205   hubId = msg.host_hub_id;
206   sessionId = msg.session_id;
207   hostEndpoint = fbsEndpointIdToAidl(*msg.toEndpoint);
208   embeddedEndpoint = fbsEndpointIdToAidl(*msg.fromEndpoint);
209   auto *serviceCStr =
210       ::android::chre::getStringFromByteVector(msg.serviceDescriptor);
211   if (serviceCStr) serviceDescriptor = std::string(serviceCStr);
212 }
213 
decodeEndpointSessionOpened(const::chre::fbs::EndpointSessionOpenedT & msg,int64_t & hubId,uint16_t & sessionId)214 void HostProtocolHostV4::decodeEndpointSessionOpened(
215     const ::chre::fbs::EndpointSessionOpenedT &msg, int64_t &hubId,
216     uint16_t &sessionId) {
217   hubId = msg.host_hub_id;
218   sessionId = msg.session_id;
219 }
220 
decodeEndpointSessionClosed(const::chre::fbs::EndpointSessionClosedT & msg,int64_t & hubId,uint16_t & sessionId,AidlReason & reason)221 void HostProtocolHostV4::decodeEndpointSessionClosed(
222     const ::chre::fbs::EndpointSessionClosedT &msg, int64_t &hubId,
223     uint16_t &sessionId, AidlReason &reason) {
224   hubId = msg.host_hub_id;
225   sessionId = msg.session_id;
226   reason = static_cast<AidlReason>(msg.reason);
227 }
228 
decodeEndpointSessionMessage(const::chre::fbs::EndpointSessionMessageT & msg,int64_t & hubId,uint16_t & sessionId,AidlMessage & message)229 void HostProtocolHostV4::decodeEndpointSessionMessage(
230     const ::chre::fbs::EndpointSessionMessageT &msg, int64_t &hubId,
231     uint16_t &sessionId, AidlMessage &message) {
232   hubId = msg.host_hub_id;
233   sessionId = msg.session_id;
234   message = {.flags = static_cast<int32_t>(msg.flags),
235              .sequenceNumber = static_cast<int32_t>(msg.sequence_number),
236              .permissions = chreToAndroidPermissions(msg.permissions),
237              .type = static_cast<int32_t>(msg.type),
238              .content = msg.data};
239 }
240 
decodeEndpointSessionMessageDeliveryStatus(const::chre::fbs::EndpointSessionMessageDeliveryStatusT & msg,int64_t & hubId,uint16_t & sessionId,AidlMessageDeliveryStatus & status)241 void HostProtocolHostV4::decodeEndpointSessionMessageDeliveryStatus(
242     const ::chre::fbs::EndpointSessionMessageDeliveryStatusT &msg,
243     int64_t &hubId, uint16_t &sessionId, AidlMessageDeliveryStatus &status) {
244   hubId = msg.host_hub_id;
245   sessionId = msg.session_id;
246   status = {.messageSequenceNumber =
247                 static_cast<int32_t>(msg.status->message_sequence_number),
248             .errorCode = static_cast<AidlErrorCode>(msg.status->error_code)};
249 }
250 
aidlToFbsMessageHub(FlatBufferBuilder & builder,const AidlHubInfo & info)251 Offset<MessageHub> HostProtocolHostV4::aidlToFbsMessageHub(
252     FlatBufferBuilder &builder, const AidlHubInfo &info) {
253   MessageHubDetails detailsEnum;
254   Offset<void> detailsUnion;
255   switch (info.hubDetails.getTag()) {
256     case AidlHubInfo::HubDetails::Tag::contextHubInfo: {
257       detailsEnum = MessageHubDetails::HubInfoResponse;
258       const auto &contextHub =
259           info.hubDetails.get<AidlHubInfo::HubDetails::Tag::contextHubInfo>();
260       uint32_t chrePlatformVersion =
261           (static_cast<uint32_t>(contextHub.chreApiMajorVersion) << 24) |
262           (static_cast<uint32_t>(contextHub.chreApiMinorVersion) << 16) |
263           static_cast<uint32_t>(contextHub.chrePatchVersion);
264       detailsUnion =
265           ::chre::fbs::CreateHubInfoResponse(
266               builder, addStringAsByteVector(builder, contextHub.name.c_str()),
267               addStringAsByteVector(builder, contextHub.vendor.c_str()),
268               addStringAsByteVector(builder, contextHub.toolchain.c_str()),
269               /*platform_version=*/0, /*toolchain_version=*/0,
270               contextHub.peakMips,
271               /*stopped_power=*/0.0f, /*sleep_power=*/0.0f, /*peak_power=*/0.0f,
272               contextHub.maxSupportedMessageLengthBytes,
273               contextHub.chrePlatformId, chrePlatformVersion,
274               contextHub.supportsReliableMessages)
275               .Union();
276     } break;
277     case AidlHubInfo::HubDetails::Tag::vendorHubInfo: {
278       detailsEnum = MessageHubDetails::VendorHubInfo;
279       const auto &vendorHub =
280           info.hubDetails.get<AidlHubInfo::HubDetails::Tag::vendorHubInfo>();
281       detailsUnion =
282           ::chre::fbs::CreateVendorHubInfo(
283               builder, addStringAsByteVector(builder, vendorHub.name.c_str()),
284               vendorHub.version, /*extended_info=*/0)
285               .Union();
286     } break;
287   }
288   return ::chre::fbs::CreateMessageHub(builder, info.hubId, detailsEnum,
289                                        detailsUnion);
290 }
291 
fbsMessageHubToAidl(const::chre::fbs::MessageHubT & hub)292 AidlHubInfo HostProtocolHostV4::fbsMessageHubToAidl(
293     const ::chre::fbs::MessageHubT &hub) {
294   AidlHubInfo info{.hubId = hub.id};
295   if (hub.details.type == MessageHubDetails::HubInfoResponse) {
296     const auto &fbsContextHub = *hub.details.AsHubInfoResponse();
297     AidlContextHubInfo contextHub = {
298         .name = stringFromBytes(fbsContextHub.name),
299         .vendor = stringFromBytes(fbsContextHub.vendor),
300         .toolchain = stringFromBytes(fbsContextHub.toolchain),
301         .peakMips = fbsContextHub.peak_mips,
302         .maxSupportedMessageLengthBytes =
303             static_cast<int32_t>(fbsContextHub.max_msg_len),
304         .chrePlatformId = static_cast<int64_t>(fbsContextHub.platform_id),
305         .chreApiMajorVersion = static_cast<int8_t>(
306             (fbsContextHub.chre_platform_version >> 24) & 0xff),
307         .chreApiMinorVersion = static_cast<int8_t>(
308             (fbsContextHub.chre_platform_version >> 16) & 0xff),
309         .chrePatchVersion =
310             static_cast<char16_t>(fbsContextHub.chre_platform_version & 0xffff),
311         .supportsReliableMessages = fbsContextHub.supports_reliable_messages};
312     info.hubDetails = AidlHubInfo::HubDetails(std::move(contextHub));
313   } else {
314     const auto &fbsVendorHub = *hub.details.AsVendorHubInfo();
315     AidlVendorHubInfo vendorHub = {
316         .name = stringFromBytes(fbsVendorHub.name),
317         .version = static_cast<int32_t>(fbsVendorHub.version)};
318     info.hubDetails = AidlHubInfo::HubDetails(std::move(vendorHub));
319   }
320   return info;
321 }
322 
aidlToFbsEndpointInfo(FlatBufferBuilder & builder,const AidlEndpointInfo & info)323 Offset<EndpointInfo> HostProtocolHostV4::aidlToFbsEndpointInfo(
324     FlatBufferBuilder &builder, const AidlEndpointInfo &info) {
325   std::vector<Offset<::chre::fbs::Service>> services;
326   for (const auto &service : info.services) {
327     services.push_back(::chre::fbs::CreateService(
328         builder, static_cast<::chre::fbs::RpcFormat>(service.format),
329         addStringAsByteVector(builder, service.serviceDescriptor.c_str()),
330         service.majorVersion, service.minorVersion));
331   }
332   auto servicesVector = builder.CreateVector(services);
333   return ::chre::fbs::CreateEndpointInfo(
334       builder, aidlToFbsEndpointId(builder, info.id),
335       static_cast<::chre::fbs::EndpointType>(info.type),
336       addStringAsByteVector(builder, info.name.c_str()), info.version,
337       androidToChrePermissions(info.requiredPermissions), servicesVector);
338 }
339 
fbsEndpointInfoToAidl(const::chre::fbs::EndpointInfoT & endpoint)340 AidlEndpointInfo HostProtocolHostV4::fbsEndpointInfoToAidl(
341     const ::chre::fbs::EndpointInfoT &endpoint) {
342   AidlEndpointInfo info = {
343       .id = fbsEndpointIdToAidl(*endpoint.id),
344       .type = static_cast<AidlEndpointInfo::EndpointType>(endpoint.type),
345       .name = stringFromBytes(endpoint.name),
346       .version = static_cast<int32_t>(endpoint.version),
347       .requiredPermissions =
348           chreToAndroidPermissions(endpoint.required_permissions)};
349   for (const auto &service : endpoint.services) {
350     info.services.push_back(
351         {.format = static_cast<AidlRpcFormat>(service->format),
352          .serviceDescriptor = stringFromBytes(service->descriptor),
353          .majorVersion = static_cast<int32_t>(service->major_version),
354          .minorVersion = static_cast<int32_t>(service->minor_version)});
355   }
356   return info;
357 }
358 
aidlToFbsEndpointId(FlatBufferBuilder & builder,const AidlEndpointId & id)359 Offset<EndpointId> HostProtocolHostV4::aidlToFbsEndpointId(
360     FlatBufferBuilder &builder, const AidlEndpointId &id) {
361   return ::chre::fbs::CreateEndpointId(builder, id.hubId, id.id);
362 }
363 
fbsEndpointIdToAidl(const::chre::fbs::EndpointIdT & endpoint)364 AidlEndpointId HostProtocolHostV4::fbsEndpointIdToAidl(
365     const ::chre::fbs::EndpointIdT &endpoint) {
366   return AidlEndpointId{.id = endpoint.id, .hubId = endpoint.hubId};
367 }
368 
369 }  // namespace android::hardware::contexthub::common::implementation
370