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(), request->fragment_id(),
70 request->total_app_size());
71 break;
72 }
73
74 case fbs::ChreMessage::UnloadNanoappRequest: {
75 const auto *request = static_cast<const fbs::UnloadNanoappRequest *>(
76 container->message());
77 HostMessageHandlers::handleUnloadNanoappRequest(
78 hostClientId, request->transaction_id(), request->app_id(),
79 request->allow_system_nanoapp_unload());
80 break;
81 }
82
83 case fbs::ChreMessage::TimeSyncMessage: {
84 const auto *request = static_cast<const fbs::TimeSyncMessage *>(
85 container->message());
86 HostMessageHandlers::handleTimeSyncMessage(request->offset());
87 break;
88 }
89
90 case fbs::ChreMessage::DebugDumpRequest:
91 HostMessageHandlers::handleDebugDumpRequest(hostClientId);
92 break;
93
94 default:
95 LOGW("Got invalid/unexpected message type %" PRIu8,
96 static_cast<uint8_t>(container->message_type()));
97 success = false;
98 }
99 }
100
101 return success;
102 }
103
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)104 void HostProtocolChre::encodeHubInfoResponse(
105 FlatBufferBuilder& builder, const char *name, const char *vendor,
106 const char *toolchain, uint32_t legacyPlatformVersion,
107 uint32_t legacyToolchainVersion, float peakMips, float stoppedPower,
108 float sleepPower, float peakPower, uint32_t maxMessageLen,
109 uint64_t platformId, uint32_t version, uint16_t hostClientId) {
110 auto nameOffset = addStringAsByteVector(builder, name);
111 auto vendorOffset = addStringAsByteVector(builder, vendor);
112 auto toolchainOffset = addStringAsByteVector(builder, toolchain);
113
114 auto response = fbs::CreateHubInfoResponse(
115 builder, nameOffset, vendorOffset, toolchainOffset, legacyPlatformVersion,
116 legacyToolchainVersion, peakMips, stoppedPower, sleepPower, peakPower,
117 maxMessageLen, platformId, version);
118 finalize(builder, fbs::ChreMessage::HubInfoResponse, response.Union(),
119 hostClientId);
120 }
121
addNanoappListEntry(FlatBufferBuilder & builder,DynamicVector<Offset<fbs::NanoappListEntry>> & offsetVector,uint64_t appId,uint32_t appVersion,bool enabled,bool isSystemNanoapp)122 void HostProtocolChre::addNanoappListEntry(
123 FlatBufferBuilder& builder,
124 DynamicVector<Offset<fbs::NanoappListEntry>>& offsetVector,
125 uint64_t appId, uint32_t appVersion, bool enabled, bool isSystemNanoapp) {
126 auto offset = fbs::CreateNanoappListEntry(
127 builder, appId, appVersion, enabled, isSystemNanoapp);
128 if (!offsetVector.push_back(offset)) {
129 LOGE("Couldn't push nanoapp list entry offset!");
130 }
131 }
132
finishNanoappListResponse(FlatBufferBuilder & builder,DynamicVector<Offset<fbs::NanoappListEntry>> & offsetVector,uint16_t hostClientId)133 void HostProtocolChre::finishNanoappListResponse(
134 FlatBufferBuilder& builder,
135 DynamicVector<Offset<fbs::NanoappListEntry>>& offsetVector,
136 uint16_t hostClientId) {
137 auto vectorOffset = builder.CreateVector<Offset<fbs::NanoappListEntry>>(
138 offsetVector);
139 auto response = fbs::CreateNanoappListResponse(builder, vectorOffset);
140 finalize(builder, fbs::ChreMessage::NanoappListResponse, response.Union(),
141 hostClientId);
142 }
143
encodeLoadNanoappResponse(flatbuffers::FlatBufferBuilder & builder,uint16_t hostClientId,uint32_t transactionId,bool success,uint32_t fragmentId)144 void HostProtocolChre::encodeLoadNanoappResponse(
145 flatbuffers::FlatBufferBuilder& builder, uint16_t hostClientId,
146 uint32_t transactionId, bool success, uint32_t fragmentId) {
147 auto response = fbs::CreateLoadNanoappResponse(builder, transactionId,
148 success, fragmentId);
149 finalize(builder, fbs::ChreMessage::LoadNanoappResponse, response.Union(),
150 hostClientId);
151 }
152
encodeUnloadNanoappResponse(flatbuffers::FlatBufferBuilder & builder,uint16_t hostClientId,uint32_t transactionId,bool success)153 void HostProtocolChre::encodeUnloadNanoappResponse(
154 flatbuffers::FlatBufferBuilder& builder, uint16_t hostClientId,
155 uint32_t transactionId, bool success) {
156 auto response = fbs::CreateUnloadNanoappResponse(builder, transactionId,
157 success);
158 finalize(builder, fbs::ChreMessage::UnloadNanoappResponse, response.Union(),
159 hostClientId);
160 }
161
encodeLogMessages(flatbuffers::FlatBufferBuilder & builder,const char * logBuffer,size_t bufferSize)162 void HostProtocolChre::encodeLogMessages(
163 flatbuffers::FlatBufferBuilder& builder, const char *logBuffer,
164 size_t bufferSize) {
165 auto logBufferOffset = builder.CreateVector(
166 reinterpret_cast<const int8_t *>(logBuffer), bufferSize);
167 auto message = fbs::CreateLogMessage(builder, logBufferOffset);
168 finalize(builder, fbs::ChreMessage::LogMessage, message.Union());
169 }
170
encodeDebugDumpData(flatbuffers::FlatBufferBuilder & builder,uint16_t hostClientId,const char * debugStr,size_t debugStrSize)171 void HostProtocolChre::encodeDebugDumpData(
172 flatbuffers::FlatBufferBuilder& builder, uint16_t hostClientId,
173 const char *debugStr, size_t debugStrSize) {
174 auto debugStrOffset = builder.CreateVector(
175 reinterpret_cast<const int8_t *>(debugStr), debugStrSize);
176 auto message = fbs::CreateDebugDumpData(builder, debugStrOffset);
177 finalize(builder, fbs::ChreMessage::DebugDumpData, message.Union(),
178 hostClientId);
179 }
180
encodeDebugDumpResponse(flatbuffers::FlatBufferBuilder & builder,uint16_t hostClientId,bool success,uint32_t dataCount)181 void HostProtocolChre::encodeDebugDumpResponse(
182 flatbuffers::FlatBufferBuilder& builder, uint16_t hostClientId,
183 bool success, uint32_t dataCount) {
184 auto response = fbs::CreateDebugDumpResponse(builder, success, dataCount);
185 finalize(builder, fbs::ChreMessage::DebugDumpResponse, response.Union(),
186 hostClientId);
187 }
188
encodeTimeSyncRequest(flatbuffers::FlatBufferBuilder & builder)189 void HostProtocolChre::encodeTimeSyncRequest(
190 flatbuffers::FlatBufferBuilder& builder) {
191 auto request = fbs::CreateTimeSyncRequest(builder);
192 finalize(builder, fbs::ChreMessage::TimeSyncRequest, request.Union());
193 }
194
encodeLowPowerMicAccessRequest(flatbuffers::FlatBufferBuilder & builder)195 void HostProtocolChre::encodeLowPowerMicAccessRequest(
196 flatbuffers::FlatBufferBuilder& builder) {
197 auto request = fbs::CreateLowPowerMicAccessRequest(builder);
198 finalize(builder, fbs::ChreMessage::LowPowerMicAccessRequest,
199 request.Union());
200 }
201
encodeLowPowerMicAccessRelease(flatbuffers::FlatBufferBuilder & builder)202 void HostProtocolChre::encodeLowPowerMicAccessRelease(
203 flatbuffers::FlatBufferBuilder& builder) {
204 auto request = fbs::CreateLowPowerMicAccessRelease(builder);
205 finalize(builder, fbs::ChreMessage::LowPowerMicAccessRelease,
206 request.Union());
207 }
208
209 } // namespace chre
210