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