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
22 #include "chre/platform/log.h"
23 #include "chre/platform/shared/host_messages_generated.h"
24
25 using flatbuffers::FlatBufferBuilder;
26 using flatbuffers::Offset;
27 using flatbuffers::Vector;
28
29 namespace chre {
30
decodeMessageFromHost(const void * message,size_t messageLen)31 bool HostProtocolChre::decodeMessageFromHost(const void *message,
32 size_t messageLen) {
33 bool success = verifyMessage(message, messageLen);
34 if (!success) {
35 LOGE("Dropping invalid/corrupted message from host (length %zu)",
36 messageLen);
37 } else {
38 const fbs::MessageContainer *container = fbs::GetMessageContainer(message);
39 uint16_t hostClientId = container->host_addr()->client_id();
40
41 switch (container->message_type()) {
42 case fbs::ChreMessage::NanoappMessage: {
43 const auto *nanoappMsg = static_cast<const fbs::NanoappMessage *>(
44 container->message());
45 // Required field; verifier ensures that this is not null (though it
46 // may be empty)
47 const flatbuffers::Vector<uint8_t> *msgData = nanoappMsg->message();
48 HostMessageHandlers::handleNanoappMessage(
49 nanoappMsg->app_id(), nanoappMsg->message_type(),
50 nanoappMsg->host_endpoint(), msgData->data(), msgData->size());
51 break;
52 }
53
54 case fbs::ChreMessage::HubInfoRequest:
55 HostMessageHandlers::handleHubInfoRequest(hostClientId);
56 break;
57
58 case fbs::ChreMessage::NanoappListRequest:
59 HostMessageHandlers::handleNanoappListRequest(hostClientId);
60 break;
61
62 case fbs::ChreMessage::LoadNanoappRequest: {
63 const auto *request = static_cast<const fbs::LoadNanoappRequest *>(
64 container->message());
65 const flatbuffers::Vector<uint8_t> *appBinary = request->app_binary();
66 HostMessageHandlers::handleLoadNanoappRequest(
67 hostClientId, request->transaction_id(), request->app_id(),
68 request->app_version(), request->target_api_version(),
69 appBinary->data(), appBinary->size());
70 break;
71 }
72
73 default:
74 LOGW("Got invalid/unexpected message type %" PRIu8,
75 static_cast<uint8_t>(container->message_type()));
76 success = false;
77 }
78 }
79
80 return success;
81 }
82
encodeHubInfoResponse(FlatBufferBuilder & 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)83 void HostProtocolChre::encodeHubInfoResponse(
84 FlatBufferBuilder& builder, const char *name, const char *vendor,
85 const char *toolchain, uint32_t legacyPlatformVersion,
86 uint32_t legacyToolchainVersion, float peakMips, float stoppedPower,
87 float sleepPower, float peakPower, uint32_t maxMessageLen,
88 uint64_t platformId, uint32_t version, uint16_t hostClientId) {
89 auto nameOffset = addStringAsByteVector(builder, name);
90 auto vendorOffset = addStringAsByteVector(builder, vendor);
91 auto toolchainOffset = addStringAsByteVector(builder, toolchain);
92
93 auto response = fbs::CreateHubInfoResponse(
94 builder, nameOffset, vendorOffset, toolchainOffset, legacyPlatformVersion,
95 legacyToolchainVersion, peakMips, stoppedPower, sleepPower, peakPower,
96 maxMessageLen, platformId, version);
97 finalize(builder, fbs::ChreMessage::HubInfoResponse, response.Union(),
98 hostClientId);
99 }
100
addNanoappListEntry(FlatBufferBuilder & builder,DynamicVector<Offset<fbs::NanoappListEntry>> & offsetVector,uint64_t appId,uint32_t appVersion,bool enabled,bool isSystemNanoapp)101 void HostProtocolChre::addNanoappListEntry(
102 FlatBufferBuilder& builder,
103 DynamicVector<Offset<fbs::NanoappListEntry>>& offsetVector,
104 uint64_t appId, uint32_t appVersion, bool enabled, bool isSystemNanoapp) {
105 auto offset = fbs::CreateNanoappListEntry(
106 builder, appId, appVersion, enabled, isSystemNanoapp);
107 if (!offsetVector.push_back(offset)) {
108 LOGE("Couldn't push nanoapp list entry offset!");
109 }
110 }
111
finishNanoappListResponse(FlatBufferBuilder & builder,DynamicVector<Offset<fbs::NanoappListEntry>> & offsetVector,uint16_t hostClientId)112 void HostProtocolChre::finishNanoappListResponse(
113 FlatBufferBuilder& builder,
114 DynamicVector<Offset<fbs::NanoappListEntry>>& offsetVector,
115 uint16_t hostClientId) {
116 auto vectorOffset = builder.CreateVector<Offset<fbs::NanoappListEntry>>(
117 offsetVector);
118 auto response = fbs::CreateNanoappListResponse(builder, vectorOffset);
119 finalize(builder, fbs::ChreMessage::NanoappListResponse, response.Union(),
120 hostClientId);
121 }
122
encodeLoadNanoappResponse(flatbuffers::FlatBufferBuilder & builder,uint16_t hostClientId,uint32_t transactionId,bool success)123 void HostProtocolChre::encodeLoadNanoappResponse(
124 flatbuffers::FlatBufferBuilder& builder, uint16_t hostClientId,
125 uint32_t transactionId, bool success) {
126 auto response = fbs::CreateLoadNanoappResponse(builder, transactionId,
127 success);
128 finalize(builder, fbs::ChreMessage::LoadNanoappResponse, response.Union(),
129 hostClientId);
130 }
131
132 } // namespace chre
133