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