• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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 "chre/platform/shared/host_protocol_chre.h"
18 
19 #include <inttypes.h>
20 #include <string.h>
21 #include <cstdint>
22 
23 #include "chre/core/event_loop_manager.h"
24 #include "chre/core/host_endpoint_manager.h"
25 #include "chre/core/host_message_hub_manager.h"
26 #include "chre/platform/log.h"
27 #include "chre/platform/shared/fbs/host_messages_generated.h"
28 #include "chre/util/dynamic_vector.h"
29 #include "chre/util/macros.h"
30 #include "chre/util/system/message_common.h"
31 
32 using flatbuffers::Offset;
33 using flatbuffers::Vector;
34 
35 namespace chre {
36 
37 using message::EndpointId;
38 using message::EndpointInfo;
39 using message::EndpointType;
40 using message::MessageHubId;
41 using message::MessageHubInfo;
42 using message::Reason;
43 using message::RpcFormat;
44 using message::ServiceInfo;
45 using message::Session;
46 using message::SessionId;
47 
48 // This is similar to getStringFromByteVector in host_protocol_host.h. Ensure
49 // that method's implementation is kept in sync with this.
getStringFromByteVector(const flatbuffers::Vector<int8_t> * vec)50 const char *getStringFromByteVector(const flatbuffers::Vector<int8_t> *vec) {
51   constexpr int8_t kNullChar = static_cast<int8_t>('\0');
52   const char *str = nullptr;
53 
54   // Check that the vector is present, non-empty, and null-terminated
55   if (vec != nullptr && vec->size() > 0 &&
56       (*vec)[vec->size() - 1] == kNullChar) {
57     str = reinterpret_cast<const char *>(vec->Data());
58   }
59 
60   return str;
61 }
62 
63 #ifdef CHRE_MESSAGE_ROUTER_SUPPORT_ENABLED
64 namespace {
getHostHubManager()65 HostMessageHubManager &getHostHubManager() {
66   return EventLoopManagerSingleton::get()->getHostMessageHubManager();
67 }
68 }  // namespace
69 #endif  // CHRE_MESSAGE_ROUTER_SUPPORT_ENABLED
70 
decodeMessageFromHost(const void * message,size_t messageLen)71 bool HostProtocolChre::decodeMessageFromHost(const void *message,
72                                              size_t messageLen) {
73   bool success = verifyMessage(message, messageLen);
74   if (!success) {
75     LOGE("Dropping invalid/corrupted message from host (length %zu)",
76          messageLen);
77   } else {
78     const fbs::MessageContainer *container = fbs::GetMessageContainer(message);
79     uint16_t hostClientId = container->host_addr()->client_id();
80 
81     switch (container->message_type()) {
82       case fbs::ChreMessage::NanoappMessage: {
83         const auto *nanoappMsg =
84             static_cast<const fbs::NanoappMessage *>(container->message());
85         // Required field; verifier ensures that this is not null (though it
86         // may be empty)
87         const flatbuffers::Vector<uint8_t> *msgData = nanoappMsg->message();
88         HostMessageHandlers::handleNanoappMessage(
89             nanoappMsg->app_id(), nanoappMsg->message_type(),
90             nanoappMsg->host_endpoint(), msgData->data(), msgData->size(),
91             nanoappMsg->is_reliable(), nanoappMsg->message_sequence_number());
92         break;
93       }
94 
95       case fbs::ChreMessage::MessageDeliveryStatus: {
96         const auto *status = static_cast<const fbs::MessageDeliveryStatus *>(
97             container->message());
98         HostMessageHandlers::handleMessageDeliveryStatus(
99             status->message_sequence_number(), status->error_code());
100         break;
101       }
102 
103       case fbs::ChreMessage::HubInfoRequest:
104         HostMessageHandlers::handleHubInfoRequest(hostClientId);
105         break;
106 
107       case fbs::ChreMessage::NanoappListRequest:
108         HostMessageHandlers::handleNanoappListRequest(hostClientId);
109         break;
110 
111       case fbs::ChreMessage::LoadNanoappRequest: {
112         const auto *request =
113             static_cast<const fbs::LoadNanoappRequest *>(container->message());
114         const flatbuffers::Vector<uint8_t> *appBinary = request->app_binary();
115         const char *appBinaryFilename =
116             getStringFromByteVector(request->app_binary_file_name());
117         HostMessageHandlers::handleLoadNanoappRequest(
118             hostClientId, request->transaction_id(), request->app_id(),
119             request->app_version(), request->app_flags(),
120             request->target_api_version(), appBinary->data(), appBinary->size(),
121             appBinaryFilename, request->fragment_id(),
122             request->total_app_size(), request->respond_before_start());
123         break;
124       }
125 
126       case fbs::ChreMessage::UnloadNanoappRequest: {
127         const auto *request = static_cast<const fbs::UnloadNanoappRequest *>(
128             container->message());
129         HostMessageHandlers::handleUnloadNanoappRequest(
130             hostClientId, request->transaction_id(), request->app_id(),
131             request->allow_system_nanoapp_unload());
132         break;
133       }
134 
135       case fbs::ChreMessage::TimeSyncMessage: {
136         const auto *request =
137             static_cast<const fbs::TimeSyncMessage *>(container->message());
138         HostMessageHandlers::handleTimeSyncMessage(request->offset());
139         break;
140       }
141 
142       case fbs::ChreMessage::DebugDumpRequest:
143         HostMessageHandlers::handleDebugDumpRequest(hostClientId);
144         break;
145 
146       case fbs::ChreMessage::SettingChangeMessage: {
147         const auto *settingMessage =
148             static_cast<const fbs::SettingChangeMessage *>(
149                 container->message());
150         HostMessageHandlers::handleSettingChangeMessage(
151             settingMessage->setting(), settingMessage->state());
152         break;
153       }
154 
155       case fbs::ChreMessage::SelfTestRequest: {
156         HostMessageHandlers::handleSelfTestRequest(hostClientId);
157         break;
158       }
159 
160       case fbs::ChreMessage::HostEndpointConnected: {
161         const auto *connectedMessage =
162             static_cast<const fbs::HostEndpointConnected *>(
163                 container->message());
164         struct chreHostEndpointInfo info;
165         info.hostEndpointId = connectedMessage->host_endpoint();
166         info.hostEndpointType = connectedMessage->type();
167         if (strlen(reinterpret_cast<const char *>(
168                 connectedMessage->package_name()->data())) > 0) {
169           info.isNameValid = true;
170           memcpy(&info.packageName[0], connectedMessage->package_name()->data(),
171                  MIN(connectedMessage->package_name()->size(),
172                      CHRE_MAX_ENDPOINT_NAME_LEN));
173           info.packageName[CHRE_MAX_ENDPOINT_NAME_LEN - 1] = '\0';
174         } else {
175           info.isNameValid = false;
176         }
177         if (strlen(reinterpret_cast<const char *>(
178                 connectedMessage->attribution_tag()->data())) > 0) {
179           info.isTagValid = true;
180           memcpy(&info.attributionTag[0],
181                  connectedMessage->attribution_tag()->data(),
182                  MIN(connectedMessage->attribution_tag()->size(),
183                      CHRE_MAX_ENDPOINT_TAG_LEN));
184           info.attributionTag[CHRE_MAX_ENDPOINT_NAME_LEN - 1] = '\0';
185         } else {
186           info.isTagValid = false;
187         }
188 
189         EventLoopManagerSingleton::get()
190             ->getHostEndpointManager()
191             .postHostEndpointConnected(info);
192         break;
193       }
194 
195       case fbs::ChreMessage::HostEndpointDisconnected: {
196         const auto *disconnectedMessage =
197             static_cast<const fbs::HostEndpointDisconnected *>(
198                 container->message());
199         EventLoopManagerSingleton::get()
200             ->getHostEndpointManager()
201             .postHostEndpointDisconnected(disconnectedMessage->host_endpoint());
202         break;
203       }
204 
205       case fbs::ChreMessage::NanConfigurationUpdate: {
206         const auto *nanConfigUpdateMessage =
207             static_cast<const fbs::NanConfigurationUpdate *>(
208                 container->message());
209         HostMessageHandlers::handleNanConfigurationUpdate(
210             nanConfigUpdateMessage->enabled());
211         break;
212       }
213 
214       case fbs::ChreMessage::DebugConfiguration: {
215         const auto *debugConfiguration =
216             static_cast<const fbs::DebugConfiguration *>(container->message());
217         HostMessageHandlers::handleDebugConfiguration(debugConfiguration);
218         break;
219       }
220 
221       case fbs::ChreMessage::PulseRequest: {
222         HostMessageHandlers::handlePulseRequest();
223         break;
224       }
225 
226       case fbs::ChreMessage::BtSocketOpen: {
227         const auto *btSocketOpen =
228             static_cast<const fbs::BtSocketOpen *>(container->message());
229         if (btSocketOpen->channelInfo_type() !=
230             fbs::ChannelInfo::LeCocChannelInfo) {
231           LOGW("Unexpected BT Socket Open Channel Info Type %" PRIu8,
232                static_cast<uint8_t>(btSocketOpen->channelInfo_type()));
233         } else {
234           const auto *leCocChannelInfo =
235               static_cast<const fbs::LeCocChannelInfo *>(
236                   btSocketOpen->channelInfo());
237           const char *name = getStringFromByteVector(btSocketOpen->name());
238           HostMessageHandlers::handleBtSocketOpen(
239               static_cast<uint64_t>(btSocketOpen->hubId()),
240               BleL2capCocSocketData{
241                   .socketId = static_cast<uint64_t>(btSocketOpen->socketId()),
242                   .endpointId =
243                       static_cast<uint64_t>(btSocketOpen->endpointId()),
244                   .connectionHandle = static_cast<uint16_t>(
245                       btSocketOpen->aclConnectionHandle()),
246                   .hostClientId = hostClientId,
247                   .rxConfig =
248                       L2capCocConfig{.cid = static_cast<uint16_t>(
249                                          leCocChannelInfo->localCid()),
250                                      .mtu = static_cast<uint16_t>(
251                                          leCocChannelInfo->localMtu()),
252                                      .mps = static_cast<uint16_t>(
253                                          leCocChannelInfo->localMps()),
254                                      .credits = static_cast<uint16_t>(
255                                          leCocChannelInfo->initialRxCredits())},
256                   .txConfig =
257                       L2capCocConfig{.cid = static_cast<uint16_t>(
258                                          leCocChannelInfo->remoteCid()),
259                                      .mtu = static_cast<uint16_t>(
260                                          leCocChannelInfo->remoteMtu()),
261                                      .mps = static_cast<uint16_t>(
262                                          leCocChannelInfo->remoteMps()),
263                                      .credits = static_cast<uint16_t>(
264                                          leCocChannelInfo->initialTxCredits())},
265               },
266               name, static_cast<uint32_t>(leCocChannelInfo->psm()));
267           success = true;
268         }
269         break;
270       }
271 
272       case fbs::ChreMessage::BtSocketCapabilitiesRequest: {
273         HostMessageHandlers::handleBtSocketCapabilitiesRequest();
274         success = true;
275         break;
276       }
277 
278       case fbs::ChreMessage::BtSocketCloseResponse: {
279         const auto *btSocketCloseResponse =
280             static_cast<const fbs::BtSocketCloseResponse *>(
281                 container->message());
282         LOGD("Received BT Socket close response for socketId=%" PRIu64,
283              btSocketCloseResponse->socketId());
284         success = true;
285         break;
286       }
287 
288 #ifdef CHRE_MESSAGE_ROUTER_SUPPORT_ENABLED
289       case fbs::ChreMessage::GetMessageHubsAndEndpointsRequest:
290         getHostHubManager().reset();
291         break;
292 
293       case fbs::ChreMessage::RegisterMessageHub: {
294         const auto *msg =
295             static_cast<const fbs::RegisterMessageHub *>(container->message());
296         MessageHubInfo hub{.id = static_cast<MessageHubId>(msg->hub()->id())};
297         if (msg->hub()->details_type() ==
298             fbs::MessageHubDetails::VendorHubInfo) {
299           hub.name = getStringFromByteVector(
300               msg->hub()->details_as_VendorHubInfo()->name());
301         } else {
302           hub.name = getStringFromByteVector(
303               msg->hub()->details_as_HubInfoResponse()->name());
304         }
305         getHostHubManager().registerHub(hub);
306         break;
307       }
308 
309       case fbs::ChreMessage::UnregisterMessageHub: {
310         const auto *msg = static_cast<const fbs::UnregisterMessageHub *>(
311             container->message());
312         getHostHubManager().unregisterHub(msg->id());
313         break;
314       }
315 
316       case fbs::ChreMessage::RegisterEndpoint: {
317         const auto *fbsEndpoint =
318             static_cast<const fbs::RegisterEndpoint *>(container->message())
319                 ->endpoint();
320         auto *maybeName = getStringFromByteVector(fbsEndpoint->name());
321         EndpointInfo endpoint(fbsEndpoint->id()->id(),
322                               maybeName ? maybeName : "",
323                               fbsEndpoint->version(),
324                               static_cast<EndpointType>(fbsEndpoint->type()),
325                               fbsEndpoint->required_permissions());
326         DynamicVector<ServiceInfo> services;
327         if (fbsEndpoint->services() && fbsEndpoint->services()->size()) {
328           if (!services.reserve(fbsEndpoint->services()->size())) {
329             LOG_OOM();
330           } else {
331             for (const auto &service : *fbsEndpoint->services()) {
332               auto *serviceDescriptor =
333                   getStringFromByteVector(service->descriptor());
334               if (!serviceDescriptor) continue;
335               auto size = strlen(serviceDescriptor) + 1;
336               auto *buf = static_cast<char *>(memoryAlloc(size));
337               if (!buf) {
338                 LOG_OOM();
339                 break;
340               }
341               memcpy(buf, serviceDescriptor, size);
342               services.emplace_back(buf, service->major_version(),
343                                     service->minor_version(),
344                                     static_cast<RpcFormat>(service->format()));
345             }
346           }
347         }
348         getHostHubManager().registerEndpoint(fbsEndpoint->id()->hubId(),
349                                              endpoint, std::move(services));
350         break;
351       }
352 
353       case fbs::ChreMessage::UnregisterEndpoint: {
354         const auto *msg =
355             static_cast<const fbs::UnregisterEndpoint *>(container->message());
356         getHostHubManager().unregisterEndpoint(msg->endpoint()->hubId(),
357                                                msg->endpoint()->id());
358         break;
359       }
360 
361       case fbs::ChreMessage::OpenEndpointSessionRequest: {
362         const auto *msg = static_cast<const fbs::OpenEndpointSessionRequest *>(
363             container->message());
364         getHostHubManager().openSession(
365             msg->fromEndpoint()->hubId(), msg->fromEndpoint()->id(),
366             msg->toEndpoint()->hubId(), msg->toEndpoint()->id(),
367             msg->session_id(),
368             getStringFromByteVector(msg->serviceDescriptor()));
369         break;
370       }
371 
372       case fbs::ChreMessage::EndpointSessionOpened: {
373         const auto *msg = static_cast<const fbs::EndpointSessionOpened *>(
374             container->message());
375         getHostHubManager().ackSession(msg->host_hub_id(), msg->session_id());
376         break;
377       }
378 
379       case fbs::ChreMessage::EndpointSessionClosed: {
380         const auto *msg = static_cast<const fbs::EndpointSessionClosed *>(
381             container->message());
382         getHostHubManager().closeSession(msg->host_hub_id(), msg->session_id(),
383                                          static_cast<Reason>(msg->reason()));
384         break;
385       }
386 
387       case fbs::ChreMessage::EndpointSessionMessage: {
388         const auto *msg = static_cast<const fbs::EndpointSessionMessage *>(
389             container->message());
390         pw::span<const std::byte> data = {
391             reinterpret_cast<const std::byte *>(msg->data()->data()),
392             msg->data()->size()};
393         getHostHubManager().sendMessage(msg->host_hub_id(), msg->session_id(),
394                                         data, msg->type(), msg->permissions());
395         break;
396       }
397 
398 #endif  // CHRE_MESSAGE_ROUTER_SUPPORT_ENABLED
399 
400       default:
401         LOGW("Got invalid/unexpected message type %" PRIu8,
402              static_cast<uint8_t>(container->message_type()));
403         success = false;
404     }
405   }
406   return success;
407 }
408 
encodeHubInfoResponse(ChreFlatBufferBuilder & builder,const char * name,const char * vendor,const char * toolchain,uint32_t legacyPlatformVersion,uint32_t legacyToolchainVersion,float peakMips,float stoppedPower,float sleepPower,float peakPower,uint32_t maxMessageLen,uint64_t platformId,uint32_t version,uint16_t hostClientId,bool supportsReliableMessages)409 void HostProtocolChre::encodeHubInfoResponse(
410     ChreFlatBufferBuilder &builder, const char *name, const char *vendor,
411     const char *toolchain, uint32_t legacyPlatformVersion,
412     uint32_t legacyToolchainVersion, float peakMips, float stoppedPower,
413     float sleepPower, float peakPower, uint32_t maxMessageLen,
414     uint64_t platformId, uint32_t version, uint16_t hostClientId,
415     bool supportsReliableMessages) {
416   auto nameOffset = addStringAsByteVector(builder, name);
417   auto vendorOffset = addStringAsByteVector(builder, vendor);
418   auto toolchainOffset = addStringAsByteVector(builder, toolchain);
419 
420   auto response = fbs::CreateHubInfoResponse(
421       builder, nameOffset, vendorOffset, toolchainOffset, legacyPlatformVersion,
422       legacyToolchainVersion, peakMips, stoppedPower, sleepPower, peakPower,
423       maxMessageLen, platformId, version, supportsReliableMessages);
424   finalize(builder, fbs::ChreMessage::HubInfoResponse, response.Union(),
425            hostClientId);
426 }
427 
addNanoappListEntry(ChreFlatBufferBuilder & builder,DynamicVector<Offset<fbs::NanoappListEntry>> & offsetVector,uint64_t appId,uint32_t appVersion,bool enabled,bool isSystemNanoapp,uint32_t appPermissions,const DynamicVector<struct chreNanoappRpcService> & rpcServices)428 void HostProtocolChre::addNanoappListEntry(
429     ChreFlatBufferBuilder &builder,
430     DynamicVector<Offset<fbs::NanoappListEntry>> &offsetVector, uint64_t appId,
431     uint32_t appVersion, bool enabled, bool isSystemNanoapp,
432     uint32_t appPermissions,
433     const DynamicVector<struct chreNanoappRpcService> &rpcServices) {
434   DynamicVector<Offset<fbs::NanoappRpcService>> rpcServiceList;
435   for (const auto &service : rpcServices) {
436     Offset<fbs::NanoappRpcService> offsetService =
437         fbs::CreateNanoappRpcService(builder, service.id, service.version);
438     if (!rpcServiceList.push_back(offsetService)) {
439       LOGE("Couldn't push RPC service to list");
440     }
441   }
442 
443   auto vectorOffset =
444       builder.CreateVector<Offset<fbs::NanoappRpcService>>(rpcServiceList);
445   auto offset = fbs::CreateNanoappListEntry(builder, appId, appVersion, enabled,
446                                             isSystemNanoapp, appPermissions,
447                                             vectorOffset);
448 
449   if (!offsetVector.push_back(offset)) {
450     LOGE("Couldn't push nanoapp list entry offset!");
451   }
452 }
453 
finishNanoappListResponse(ChreFlatBufferBuilder & builder,DynamicVector<Offset<fbs::NanoappListEntry>> & offsetVector,uint16_t hostClientId)454 void HostProtocolChre::finishNanoappListResponse(
455     ChreFlatBufferBuilder &builder,
456     DynamicVector<Offset<fbs::NanoappListEntry>> &offsetVector,
457     uint16_t hostClientId) {
458   auto vectorOffset =
459       builder.CreateVector<Offset<fbs::NanoappListEntry>>(offsetVector);
460   auto response = fbs::CreateNanoappListResponse(builder, vectorOffset);
461   finalize(builder, fbs::ChreMessage::NanoappListResponse, response.Union(),
462            hostClientId);
463 }
464 
encodePulseResponse(ChreFlatBufferBuilder & builder)465 void HostProtocolChre::encodePulseResponse(ChreFlatBufferBuilder &builder) {
466   auto response = fbs::CreatePulseResponse(builder);
467   finalize(builder, fbs::ChreMessage::PulseResponse, response.Union());
468 }
469 
encodeLoadNanoappResponse(ChreFlatBufferBuilder & builder,uint16_t hostClientId,uint32_t transactionId,bool success,uint32_t fragmentId)470 void HostProtocolChre::encodeLoadNanoappResponse(ChreFlatBufferBuilder &builder,
471                                                  uint16_t hostClientId,
472                                                  uint32_t transactionId,
473                                                  bool success,
474                                                  uint32_t fragmentId) {
475   auto response = fbs::CreateLoadNanoappResponse(builder, transactionId,
476                                                  success, fragmentId);
477   finalize(builder, fbs::ChreMessage::LoadNanoappResponse, response.Union(),
478            hostClientId);
479 }
480 
encodeNanoappTokenDatabaseInfo(ChreFlatBufferBuilder & builder,uint16_t instanceId,uint64_t appId,uint32_t tokenDatabaseOffset,size_t tokenDatabaseSize)481 void HostProtocolChre::encodeNanoappTokenDatabaseInfo(
482     ChreFlatBufferBuilder &builder, uint16_t instanceId, uint64_t appId,
483     uint32_t tokenDatabaseOffset, size_t tokenDatabaseSize) {
484   auto response = fbs::CreateNanoappTokenDatabaseInfo(
485       builder, instanceId, appId, tokenDatabaseOffset, tokenDatabaseSize);
486   finalize(builder, fbs::ChreMessage::NanoappTokenDatabaseInfo,
487            response.Union());
488 }
489 
encodeUnloadNanoappResponse(ChreFlatBufferBuilder & builder,uint16_t hostClientId,uint32_t transactionId,bool success)490 void HostProtocolChre::encodeUnloadNanoappResponse(
491     ChreFlatBufferBuilder &builder, uint16_t hostClientId,
492     uint32_t transactionId, bool success) {
493   auto response =
494       fbs::CreateUnloadNanoappResponse(builder, transactionId, success);
495   finalize(builder, fbs::ChreMessage::UnloadNanoappResponse, response.Union(),
496            hostClientId);
497 }
498 
encodeLogMessages(ChreFlatBufferBuilder & builder,const uint8_t * logBuffer,size_t bufferSize)499 void HostProtocolChre::encodeLogMessages(ChreFlatBufferBuilder &builder,
500                                          const uint8_t *logBuffer,
501                                          size_t bufferSize) {
502   auto logBufferOffset = builder.CreateVector(
503       reinterpret_cast<const int8_t *>(logBuffer), bufferSize);
504   auto message = fbs::CreateLogMessage(builder, logBufferOffset);
505   finalize(builder, fbs::ChreMessage::LogMessage, message.Union());
506 }
507 
encodeLogMessagesV2(ChreFlatBufferBuilder & builder,const uint8_t * logBuffer,size_t bufferSize,uint32_t numLogsDropped)508 void HostProtocolChre::encodeLogMessagesV2(ChreFlatBufferBuilder &builder,
509                                            const uint8_t *logBuffer,
510                                            size_t bufferSize,
511                                            uint32_t numLogsDropped) {
512   auto logBufferOffset = builder.CreateVector(
513       reinterpret_cast<const int8_t *>(logBuffer), bufferSize);
514   auto message =
515       fbs::CreateLogMessageV2(builder, logBufferOffset, numLogsDropped);
516   finalize(builder, fbs::ChreMessage::LogMessageV2, message.Union());
517 }
518 
encodeDebugDumpData(ChreFlatBufferBuilder & builder,uint16_t hostClientId,const char * debugStr,size_t debugStrSize)519 void HostProtocolChre::encodeDebugDumpData(ChreFlatBufferBuilder &builder,
520                                            uint16_t hostClientId,
521                                            const char *debugStr,
522                                            size_t debugStrSize) {
523   auto debugStrOffset = builder.CreateVector(
524       reinterpret_cast<const int8_t *>(debugStr), debugStrSize);
525   auto message = fbs::CreateDebugDumpData(builder, debugStrOffset);
526   finalize(builder, fbs::ChreMessage::DebugDumpData, message.Union(),
527            hostClientId);
528 }
529 
encodeDebugDumpResponse(ChreFlatBufferBuilder & builder,uint16_t hostClientId,bool success,uint32_t dataCount)530 void HostProtocolChre::encodeDebugDumpResponse(ChreFlatBufferBuilder &builder,
531                                                uint16_t hostClientId,
532                                                bool success,
533                                                uint32_t dataCount) {
534   auto response = fbs::CreateDebugDumpResponse(builder, success, dataCount);
535   finalize(builder, fbs::ChreMessage::DebugDumpResponse, response.Union(),
536            hostClientId);
537 }
538 
encodeTimeSyncRequest(ChreFlatBufferBuilder & builder)539 void HostProtocolChre::encodeTimeSyncRequest(ChreFlatBufferBuilder &builder) {
540   auto request = fbs::CreateTimeSyncRequest(builder);
541   finalize(builder, fbs::ChreMessage::TimeSyncRequest, request.Union());
542 }
543 
encodeLowPowerMicAccessRequest(ChreFlatBufferBuilder & builder)544 void HostProtocolChre::encodeLowPowerMicAccessRequest(
545     ChreFlatBufferBuilder &builder) {
546   auto request = fbs::CreateLowPowerMicAccessRequest(builder);
547   finalize(builder, fbs::ChreMessage::LowPowerMicAccessRequest,
548            request.Union());
549 }
550 
encodeLowPowerMicAccessRelease(ChreFlatBufferBuilder & builder)551 void HostProtocolChre::encodeLowPowerMicAccessRelease(
552     ChreFlatBufferBuilder &builder) {
553   auto request = fbs::CreateLowPowerMicAccessRelease(builder);
554   finalize(builder, fbs::ChreMessage::LowPowerMicAccessRelease,
555            request.Union());
556 }
557 
encodeSelfTestResponse(ChreFlatBufferBuilder & builder,uint16_t hostClientId,bool success)558 void HostProtocolChre::encodeSelfTestResponse(ChreFlatBufferBuilder &builder,
559                                               uint16_t hostClientId,
560                                               bool success) {
561   auto response = fbs::CreateSelfTestResponse(builder, success);
562   finalize(builder, fbs::ChreMessage::SelfTestResponse, response.Union(),
563            hostClientId);
564 }
565 
encodeMetricLog(ChreFlatBufferBuilder & builder,uint32_t metricId,const uint8_t * encodedMsg,size_t metricSize)566 void HostProtocolChre::encodeMetricLog(ChreFlatBufferBuilder &builder,
567                                        uint32_t metricId,
568                                        const uint8_t *encodedMsg,
569                                        size_t metricSize) {
570   auto encodedMessage = builder.CreateVector(
571       reinterpret_cast<const int8_t *>(encodedMsg), metricSize);
572   auto message = fbs::CreateMetricLog(builder, metricId, encodedMessage);
573   finalize(builder, fbs::ChreMessage::MetricLog, message.Union());
574 }
575 
encodeNanConfigurationRequest(ChreFlatBufferBuilder & builder,bool enable)576 void HostProtocolChre::encodeNanConfigurationRequest(
577     ChreFlatBufferBuilder &builder, bool enable) {
578   auto request = fbs::CreateNanConfigurationRequest(builder, enable);
579   finalize(builder, fbs::ChreMessage::NanConfigurationRequest, request.Union());
580 }
581 
encodeBtSocketOpenResponse(ChreFlatBufferBuilder & builder,uint16_t hostClientId,uint64_t socketId,bool success,const char * reason)582 void HostProtocolChre::encodeBtSocketOpenResponse(
583     ChreFlatBufferBuilder &builder, uint16_t hostClientId, uint64_t socketId,
584     bool success, const char *reason) {
585   auto reasonOffset = addStringAsByteVector(builder, reason);
586   auto socketOpenResponse = fbs::CreateBtSocketOpenResponse(
587       builder, socketId,
588       success ? fbs::BtSocketOpenStatus::SUCCESS
589               : fbs::BtSocketOpenStatus::FAILURE,
590       reasonOffset);
591   finalize(builder, fbs::ChreMessage::BtSocketOpenResponse,
592            socketOpenResponse.Union(), hostClientId);
593 }
594 
encodeBtSocketClose(ChreFlatBufferBuilder & builder,uint16_t hostClientId,uint64_t socketId,const char * reason)595 void HostProtocolChre::encodeBtSocketClose(ChreFlatBufferBuilder &builder,
596                                            uint16_t hostClientId,
597                                            uint64_t socketId,
598                                            const char *reason) {
599   auto reasonOffset = addStringAsByteVector(builder, reason);
600   auto socketClose = fbs::CreateBtSocketClose(builder, socketId, reasonOffset);
601   finalize(builder, fbs::ChreMessage::BtSocketClose, socketClose.Union(),
602            hostClientId);
603 }
604 
encodeBtSocketGetCapabilitiesResponse(ChreFlatBufferBuilder & builder,uint32_t leCocNumberOfSupportedSockets,uint32_t leCocMtu,uint32_t rfcommNumberOfSupportedSockets,uint32_t rfcommMaxFrameSize)605 void HostProtocolChre::encodeBtSocketGetCapabilitiesResponse(
606     ChreFlatBufferBuilder &builder, uint32_t leCocNumberOfSupportedSockets,
607     uint32_t leCocMtu, uint32_t rfcommNumberOfSupportedSockets,
608     uint32_t rfcommMaxFrameSize) {
609   auto leCocCapabilities = fbs::CreateBtSocketLeCocCapabilities(
610       builder, leCocNumberOfSupportedSockets, leCocMtu);
611   auto rfcommCapabilities = fbs::CreateBtSocketRfcommCapabilities(
612       builder, rfcommNumberOfSupportedSockets, rfcommMaxFrameSize);
613   auto socketCapabilitiesResponse = fbs::CreateBtSocketCapabilitiesResponse(
614       builder, leCocCapabilities, rfcommCapabilities);
615   finalize(builder, fbs::ChreMessage::BtSocketCapabilitiesResponse,
616            socketCapabilitiesResponse.Union());
617 }
618 
getSettingFromFbs(fbs::Setting setting,Setting * chreSetting)619 bool HostProtocolChre::getSettingFromFbs(fbs::Setting setting,
620                                          Setting *chreSetting) {
621   bool success = true;
622   switch (setting) {
623     case fbs::Setting::LOCATION:
624       *chreSetting = Setting::LOCATION;
625       break;
626     case fbs::Setting::WIFI_AVAILABLE:
627       *chreSetting = Setting::WIFI_AVAILABLE;
628       break;
629     case fbs::Setting::AIRPLANE_MODE:
630       *chreSetting = Setting::AIRPLANE_MODE;
631       break;
632     case fbs::Setting::MICROPHONE:
633       *chreSetting = Setting::MICROPHONE;
634       break;
635     case fbs::Setting::BLE_AVAILABLE:
636       *chreSetting = Setting::BLE_AVAILABLE;
637       break;
638     default:
639       LOGE("Unknown setting %" PRIu8, static_cast<uint8_t>(setting));
640       success = false;
641   }
642 
643   return success;
644 }
645 
getSettingEnabledFromFbs(fbs::SettingState state,bool * chreSettingEnabled)646 bool HostProtocolChre::getSettingEnabledFromFbs(fbs::SettingState state,
647                                                 bool *chreSettingEnabled) {
648   bool success = true;
649   switch (state) {
650     case fbs::SettingState::DISABLED:
651       *chreSettingEnabled = false;
652       break;
653     case fbs::SettingState::ENABLED:
654       *chreSettingEnabled = true;
655       break;
656     default:
657       LOGE("Unknown state %" PRIu8, static_cast<uint8_t>(state));
658       success = false;
659   }
660 
661   return success;
662 }
663 
encodeGetMessageHubsAndEndpointsResponse(ChreFlatBufferBuilder & builder)664 void HostProtocolChre::encodeGetMessageHubsAndEndpointsResponse(
665     ChreFlatBufferBuilder &builder) {
666   auto msg = fbs::CreateGetMessageHubsAndEndpointsResponse(builder);
667   finalize(builder, fbs::ChreMessage::GetMessageHubsAndEndpointsResponse,
668            msg.Union());
669 }
670 
encodeRegisterMessageHub(ChreFlatBufferBuilder & builder,const MessageHubInfo & hub)671 void HostProtocolChre::encodeRegisterMessageHub(ChreFlatBufferBuilder &builder,
672                                                 const MessageHubInfo &hub) {
673   auto vendorHub = fbs::CreateVendorHubInfo(
674       builder, addStringAsByteVector(builder, hub.name));
675   auto fbsHub = fbs::CreateMessageHub(builder, hub.id,
676                                       fbs::MessageHubDetails::VendorHubInfo,
677                                       vendorHub.Union());
678   auto msg = fbs::CreateRegisterMessageHub(builder, fbsHub);
679   finalize(builder, fbs::ChreMessage::RegisterMessageHub, msg.Union());
680 }
681 
encodeUnregisterMessageHub(ChreFlatBufferBuilder & builder,MessageHubId id)682 void HostProtocolChre::encodeUnregisterMessageHub(
683     ChreFlatBufferBuilder &builder, MessageHubId id) {
684   auto msg = fbs::CreateUnregisterMessageHub(builder, id);
685   finalize(builder, fbs::ChreMessage::UnregisterMessageHub, msg.Union());
686 }
687 
encodeRegisterEndpoint(ChreFlatBufferBuilder & builder,MessageHubId hub,const EndpointInfo & endpoint)688 void HostProtocolChre::encodeRegisterEndpoint(ChreFlatBufferBuilder &builder,
689                                               MessageHubId hub,
690                                               const EndpointInfo &endpoint) {
691   auto id = fbs::CreateEndpointId(builder, hub, endpoint.id);
692   auto info = fbs::CreateEndpointInfo(
693       builder, id, static_cast<fbs::EndpointType>(endpoint.type),
694       addStringAsByteVector(builder, endpoint.name), endpoint.version,
695       endpoint.requiredPermissions);
696   auto msg = fbs::CreateRegisterEndpoint(builder, info);
697   finalize(builder, fbs::ChreMessage::RegisterEndpoint, msg.Union());
698 }
699 
encodeAddServiceToEndpoint(ChreFlatBufferBuilder & builder,MessageHubId hub,EndpointId endpoint,const ServiceInfo & service)700 void HostProtocolChre::encodeAddServiceToEndpoint(
701     ChreFlatBufferBuilder &builder, MessageHubId hub, EndpointId endpoint,
702     const ServiceInfo &service) {
703   auto id = fbs::CreateEndpointId(builder, hub, endpoint);
704   auto serviceDescriptor =
705       addStringAsByteVector(builder, service.serviceDescriptor);
706   auto fbsService = fbs::CreateService(
707       builder, static_cast<fbs::RpcFormat>(service.format), serviceDescriptor,
708       service.majorVersion, service.minorVersion);
709   auto msg = fbs::CreateAddServiceToEndpoint(builder, id, fbsService);
710   finalize(builder, fbs::ChreMessage::AddServiceToEndpoint, msg.Union());
711 }
712 
encodeEndpointReady(ChreFlatBufferBuilder & builder,MessageHubId hub,EndpointId endpoint)713 void HostProtocolChre::encodeEndpointReady(ChreFlatBufferBuilder &builder,
714                                            MessageHubId hub,
715                                            EndpointId endpoint) {
716   auto id = fbs::CreateEndpointId(builder, hub, endpoint);
717   auto msg = fbs::CreateEndpointReady(builder, id);
718   finalize(builder, fbs::ChreMessage::EndpointReady, msg.Union());
719 }
720 
encodeUnregisterEndpoint(ChreFlatBufferBuilder & builder,MessageHubId hub,EndpointId endpoint)721 void HostProtocolChre::encodeUnregisterEndpoint(ChreFlatBufferBuilder &builder,
722                                                 MessageHubId hub,
723                                                 EndpointId endpoint) {
724   auto id = fbs::CreateEndpointId(builder, hub, endpoint);
725   auto msg = fbs::CreateUnregisterEndpoint(builder, id);
726   finalize(builder, fbs::ChreMessage::UnregisterEndpoint, msg.Union());
727 }
728 
encodeOpenEndpointSessionRequest(ChreFlatBufferBuilder & builder,const Session & session)729 void HostProtocolChre::encodeOpenEndpointSessionRequest(
730     ChreFlatBufferBuilder &builder, const Session &session) {
731   auto fromEndpoint = fbs::CreateEndpointId(
732       builder, session.initiator.messageHubId, session.initiator.endpointId);
733   auto toEndpoint = fbs::CreateEndpointId(builder, session.peer.messageHubId,
734                                           session.peer.endpointId);
735   auto msg = fbs::CreateOpenEndpointSessionRequest(
736       builder, session.peer.messageHubId, session.sessionId, fromEndpoint,
737       toEndpoint, addStringAsByteVector(builder, session.serviceDescriptor));
738   finalize(builder, fbs::ChreMessage::OpenEndpointSessionRequest, msg.Union());
739 }
740 
encodeEndpointSessionOpened(ChreFlatBufferBuilder & builder,MessageHubId hub,SessionId session)741 void HostProtocolChre::encodeEndpointSessionOpened(
742     ChreFlatBufferBuilder &builder, MessageHubId hub, SessionId session) {
743   auto msg = fbs::CreateEndpointSessionOpened(builder, hub, session);
744   finalize(builder, fbs::ChreMessage::EndpointSessionOpened, msg.Union());
745 }
746 
encodeEndpointSessionClosed(ChreFlatBufferBuilder & builder,MessageHubId hub,SessionId session,Reason reason)747 void HostProtocolChre::encodeEndpointSessionClosed(
748     ChreFlatBufferBuilder &builder, MessageHubId hub, SessionId session,
749     Reason reason) {
750   auto msg = fbs::CreateEndpointSessionClosed(builder, hub, session,
751                                               static_cast<fbs::Reason>(reason));
752   finalize(builder, fbs::ChreMessage::EndpointSessionClosed, msg.Union());
753 }
754 
encodeEndpointSessionMessage(ChreFlatBufferBuilder & builder,MessageHubId hub,SessionId session,pw::UniquePtr<std::byte[]> && data,uint32_t type,uint32_t permissions)755 void HostProtocolChre::encodeEndpointSessionMessage(
756     ChreFlatBufferBuilder &builder, MessageHubId hub, SessionId session,
757     pw::UniquePtr<std::byte[]> &&data, uint32_t type, uint32_t permissions) {
758   auto dataVec = builder.CreateVector(reinterpret_cast<uint8_t *>(data.get()),
759                                       data.size());
760   auto msg = fbs::CreateEndpointSessionMessage(builder, hub, session, type,
761                                                permissions, dataVec);
762   finalize(builder, fbs::ChreMessage::EndpointSessionMessage, msg.Union());
763 }
764 
765 }  // namespace chre
766