xref: /aosp_15_r20/system/chre/host/common/host_protocol_host.cc (revision 84e339476a462649f82315436d70fd732297a399)
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_host/host_protocol_host.h"
18 
19 #include <inttypes.h>
20 #include <string.h>
21 
22 #include "chre_host/log.h"
23 
24 using flatbuffers::FlatBufferBuilder;
25 using flatbuffers::Offset;
26 
27 // Aliased for consistency with the way these symbols are referenced in
28 // CHRE-side code
29 namespace fbs = ::chre::fbs;
30 
31 namespace android {
32 namespace chre {
33 
34 // This is similar to getStringFromByteVector in host_protocol_chre.h. Ensure
35 // that method's implementation is kept in sync with this.
getStringFromByteVector(const std::vector<int8_t> & vec)36 const char *getStringFromByteVector(const std::vector<int8_t> &vec) {
37   constexpr int8_t kNullChar = static_cast<int8_t>('\0');
38   const char *str = nullptr;
39 
40   // Check that the vector is present, non-empty, and null-terminated
41   if (vec.size() > 0 && vec[vec.size() - 1] == kNullChar) {
42     str = reinterpret_cast<const char *>(vec.data());
43   }
44 
45   return str;
46 }
47 
decodeMessageFromChre(const void * message,size_t messageLen,IChreMessageHandlers & handlers)48 bool HostProtocolHost::decodeMessageFromChre(const void *message,
49                                              size_t messageLen,
50                                              IChreMessageHandlers &handlers) {
51   bool success = verifyMessage(message, messageLen);
52   if (success) {
53     std::unique_ptr<fbs::MessageContainerT> container =
54         fbs::UnPackMessageContainer(message);
55     fbs::ChreMessageUnion &msg = container->message;
56 
57     switch (container->message.type) {
58       case fbs::ChreMessage::NanoappMessage:
59         handlers.handleNanoappMessage(*msg.AsNanoappMessage());
60         break;
61 
62       case fbs::ChreMessage::HubInfoResponse:
63         handlers.handleHubInfoResponse(*msg.AsHubInfoResponse());
64         break;
65 
66       case fbs::ChreMessage::NanoappListResponse:
67         handlers.handleNanoappListResponse(*msg.AsNanoappListResponse());
68         break;
69 
70       case fbs::ChreMessage::LoadNanoappResponse:
71         handlers.handleLoadNanoappResponse(*msg.AsLoadNanoappResponse());
72         break;
73 
74       case fbs::ChreMessage::UnloadNanoappResponse:
75         handlers.handleUnloadNanoappResponse(*msg.AsUnloadNanoappResponse());
76         break;
77 
78       case fbs::ChreMessage::DebugDumpData:
79         handlers.handleDebugDumpData(*msg.AsDebugDumpData());
80         break;
81 
82       case fbs::ChreMessage::DebugDumpResponse:
83         handlers.handleDebugDumpResponse(*msg.AsDebugDumpResponse());
84         break;
85 
86       case fbs::ChreMessage::SelfTestResponse:
87         handlers.handleSelfTestResponse(*msg.AsSelfTestResponse());
88         break;
89 
90       default:
91         success = handlers.handleContextHubV4Message(msg);
92     }
93   }
94 
95   return success;
96 }
97 
encodeHubInfoRequest(FlatBufferBuilder & builder)98 void HostProtocolHost::encodeHubInfoRequest(FlatBufferBuilder &builder) {
99   auto request = fbs::CreateHubInfoRequest(builder);
100   finalize(builder, fbs::ChreMessage::HubInfoRequest, request.Union());
101 }
102 
encodeDebugConfiguration(FlatBufferBuilder & builder)103 void HostProtocolHost::encodeDebugConfiguration(FlatBufferBuilder &builder) {
104 #ifdef CHRE_HEALTH_MONITOR_CHECK_CRASH
105   auto request = fbs::CreateDebugConfiguration(builder, true);
106 #else
107   auto request = fbs::CreateDebugConfiguration(builder, false);
108 #endif  // CHRE_HEALTH_MONITOR_CHECK_CRASH
109   finalize(builder, fbs::ChreMessage::DebugConfiguration, request.Union());
110 }
111 
encodeFragmentedLoadNanoappRequest(flatbuffers::FlatBufferBuilder & builder,const FragmentedLoadRequest & request,bool respondBeforeStart)112 void HostProtocolHost::encodeFragmentedLoadNanoappRequest(
113     flatbuffers::FlatBufferBuilder &builder,
114     const FragmentedLoadRequest &request, bool respondBeforeStart) {
115   encodeLoadNanoappRequestForBinary(
116       builder, request.transactionId, request.appId, request.appVersion,
117       request.appFlags, request.targetApiVersion, request.binary,
118       request.fragmentId, request.appTotalSizeBytes, respondBeforeStart);
119 }
120 
encodeNanoappListRequest(FlatBufferBuilder & builder)121 void HostProtocolHost::encodeNanoappListRequest(FlatBufferBuilder &builder) {
122   auto request = fbs::CreateNanoappListRequest(builder);
123   finalize(builder, fbs::ChreMessage::NanoappListRequest, request.Union());
124 }
125 
encodeUnloadNanoappRequest(FlatBufferBuilder & builder,uint32_t transactionId,uint64_t appId,bool allowSystemNanoappUnload)126 void HostProtocolHost::encodeUnloadNanoappRequest(
127     FlatBufferBuilder &builder, uint32_t transactionId, uint64_t appId,
128     bool allowSystemNanoappUnload) {
129   auto request = fbs::CreateUnloadNanoappRequest(builder, transactionId, appId,
130                                                  allowSystemNanoappUnload);
131   finalize(builder, fbs::ChreMessage::UnloadNanoappRequest, request.Union());
132 }
133 
encodeTimeSyncMessage(FlatBufferBuilder & builder,int64_t offset)134 void HostProtocolHost::encodeTimeSyncMessage(FlatBufferBuilder &builder,
135                                              int64_t offset) {
136   auto request = fbs::CreateTimeSyncMessage(builder, offset);
137   finalize(builder, fbs::ChreMessage::TimeSyncMessage, request.Union());
138 }
139 
encodeDebugDumpRequest(FlatBufferBuilder & builder)140 void HostProtocolHost::encodeDebugDumpRequest(FlatBufferBuilder &builder) {
141   auto request = fbs::CreateDebugDumpRequest(builder);
142   finalize(builder, fbs::ChreMessage::DebugDumpRequest, request.Union());
143 }
144 
extractHostClientIdAndType(const void * message,size_t messageLen,uint16_t * hostClientId,::chre::fbs::ChreMessage * messageType)145 bool HostProtocolHost::extractHostClientIdAndType(
146     const void *message, size_t messageLen, uint16_t *hostClientId,
147     ::chre::fbs::ChreMessage *messageType) {
148   bool success = false;
149   if (hostClientId != nullptr && messageType != nullptr) {
150     success = verifyMessage(message, messageLen);
151 
152     if (success) {
153       const fbs::MessageContainer *container =
154           fbs::GetMessageContainer(message);
155       // host_addr guaranteed to be non-null via verifyMessage (it's a required
156       // field)
157       *hostClientId = container->host_addr()->client_id();
158       *messageType = container->message_type();
159     }
160   }
161 
162   return success;
163 }
164 
mutateHostClientId(void * message,size_t messageLen,uint16_t hostClientId)165 bool HostProtocolHost::mutateHostClientId(void *message, size_t messageLen,
166                                           uint16_t hostClientId) {
167   bool success = verifyMessage(message, messageLen);
168 
169   if (!success) {
170     LOGE("Message verification failed - can't mutate host ID");
171   } else {
172     fbs::MessageContainer *container = fbs::GetMutableMessageContainer(message);
173     // host_addr guaranteed to be non-null via verifyMessage (it's a required
174     // field)
175     container->mutable_host_addr()->mutate_client_id(hostClientId);
176     success = true;
177   }
178 
179   return success;
180 }
181 
encodeLoadNanoappRequestForBinary(FlatBufferBuilder & builder,uint32_t transactionId,uint64_t appId,uint32_t appVersion,uint32_t appFlags,uint32_t targetApiVersion,const std::vector<uint8_t> & nanoappBinary,uint32_t fragmentId,size_t appTotalSizeBytes,bool respondBeforeStart)182 void HostProtocolHost::encodeLoadNanoappRequestForBinary(
183     FlatBufferBuilder &builder, uint32_t transactionId, uint64_t appId,
184     uint32_t appVersion, uint32_t appFlags, uint32_t targetApiVersion,
185     const std::vector<uint8_t> &nanoappBinary, uint32_t fragmentId,
186     size_t appTotalSizeBytes, bool respondBeforeStart) {
187   auto appBinary = builder.CreateVector(nanoappBinary);
188   auto request = fbs::CreateLoadNanoappRequest(
189       builder, transactionId, appId, appVersion, targetApiVersion, appBinary,
190       fragmentId, appTotalSizeBytes, 0 /* app_binary_file_name */, appFlags,
191       respondBeforeStart);
192   finalize(builder, fbs::ChreMessage::LoadNanoappRequest, request.Union());
193 }
194 
encodeLoadNanoappRequestForFile(flatbuffers::FlatBufferBuilder & builder,uint32_t transactionId,uint64_t appId,uint32_t appVersion,uint32_t targetApiVersion,const char * nanoappBinaryName)195 void HostProtocolHost::encodeLoadNanoappRequestForFile(
196     flatbuffers::FlatBufferBuilder &builder, uint32_t transactionId,
197     uint64_t appId, uint32_t appVersion, uint32_t targetApiVersion,
198     const char *nanoappBinaryName) {
199   const std::vector<uint8_t> emptyAppBinary;
200   auto appBinary = builder.CreateVector(emptyAppBinary);
201   auto appBinaryName = addStringAsByteVector(builder, nanoappBinaryName);
202   auto request = fbs::CreateLoadNanoappRequest(
203       builder, transactionId, appId, appVersion, targetApiVersion, appBinary,
204       0 /* fragmentId */, 0 /* appTotalSizeBytes */, appBinaryName);
205   finalize(builder, fbs::ChreMessage::LoadNanoappRequest, request.Union());
206 }
207 
encodeSettingChangeNotification(flatbuffers::FlatBufferBuilder & builder,::chre::fbs::Setting setting,::chre::fbs::SettingState newState)208 void HostProtocolHost::encodeSettingChangeNotification(
209     flatbuffers::FlatBufferBuilder &builder, ::chre::fbs::Setting setting,
210     ::chre::fbs::SettingState newState) {
211   auto notification =
212       fbs::CreateSettingChangeMessage(builder, setting, newState);
213   finalize(builder, fbs::ChreMessage::SettingChangeMessage,
214            notification.Union());
215 }
216 
encodeSelfTestRequest(flatbuffers::FlatBufferBuilder & builder)217 void HostProtocolHost::encodeSelfTestRequest(
218     flatbuffers::FlatBufferBuilder &builder) {
219   auto request = fbs::CreateSelfTestRequest(builder);
220   finalize(builder, fbs::ChreMessage::SelfTestRequest, request.Union());
221 }
222 
encodeHostEndpointConnected(flatbuffers::FlatBufferBuilder & builder,uint16_t hostEndpointId,uint8_t type,const std::string & packageName,const std::string & attributionTag)223 void HostProtocolHost::encodeHostEndpointConnected(
224     flatbuffers::FlatBufferBuilder &builder, uint16_t hostEndpointId,
225     uint8_t type, const std::string &packageName,
226     const std::string &attributionTag) {
227   std::vector<int8_t> packageNameVec(packageName.begin(), packageName.end());
228   packageNameVec.push_back('\0');
229   std::vector<int8_t> attributionTagVec(attributionTag.begin(),
230                                         attributionTag.end());
231   attributionTagVec.push_back('\0');
232 
233   auto message = fbs::CreateHostEndpointConnectedDirect(
234       builder, hostEndpointId, type, &packageNameVec, &attributionTagVec);
235   finalize(builder, fbs::ChreMessage::HostEndpointConnected, message.Union());
236 }
237 
encodeHostEndpointDisconnected(flatbuffers::FlatBufferBuilder & builder,uint16_t hostEndpointId)238 void HostProtocolHost::encodeHostEndpointDisconnected(
239     flatbuffers::FlatBufferBuilder &builder, uint16_t hostEndpointId) {
240   auto message = fbs::CreateHostEndpointDisconnected(builder, hostEndpointId);
241   finalize(builder, fbs::ChreMessage::HostEndpointDisconnected,
242            message.Union());
243 }
244 
encodeNanconfigurationUpdate(flatbuffers::FlatBufferBuilder & builder,bool nanEnabled)245 void HostProtocolHost::encodeNanconfigurationUpdate(
246     flatbuffers::FlatBufferBuilder &builder, bool nanEnabled) {
247   auto message = fbs::CreateNanConfigurationUpdate(builder, nanEnabled);
248   finalize(builder, fbs::ChreMessage::NanConfigurationUpdate, message.Union());
249 }
250 
encodePulseRequest(FlatBufferBuilder & builder)251 void HostProtocolHost::encodePulseRequest(FlatBufferBuilder &builder) {
252   auto message = fbs::CreatePulseRequest(builder);
253   finalize(builder, fbs::ChreMessage::PulseRequest, message.Union());
254 }
255 
256 }  // namespace chre
257 }  // namespace android
258