1*84e33947SAndroid Build Coastguard Worker /*
2*84e33947SAndroid Build Coastguard Worker * Copyright (C) 2017 The Android Open Source Project
3*84e33947SAndroid Build Coastguard Worker *
4*84e33947SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*84e33947SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*84e33947SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*84e33947SAndroid Build Coastguard Worker *
8*84e33947SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*84e33947SAndroid Build Coastguard Worker *
10*84e33947SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*84e33947SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*84e33947SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*84e33947SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*84e33947SAndroid Build Coastguard Worker * limitations under the License.
15*84e33947SAndroid Build Coastguard Worker */
16*84e33947SAndroid Build Coastguard Worker
17*84e33947SAndroid Build Coastguard Worker #ifndef FARF_MEDIUM
18*84e33947SAndroid Build Coastguard Worker #define FARF_MEDIUM 1
19*84e33947SAndroid Build Coastguard Worker #endif
20*84e33947SAndroid Build Coastguard Worker
21*84e33947SAndroid Build Coastguard Worker #include "HAP_farf.h"
22*84e33947SAndroid Build Coastguard Worker #include "timer.h"
23*84e33947SAndroid Build Coastguard Worker
24*84e33947SAndroid Build Coastguard Worker #include "chre/core/event_loop_manager.h"
25*84e33947SAndroid Build Coastguard Worker #include "chre/core/host_comms_manager.h"
26*84e33947SAndroid Build Coastguard Worker #include "chre/core/settings.h"
27*84e33947SAndroid Build Coastguard Worker #include "chre/platform/fatal_error.h"
28*84e33947SAndroid Build Coastguard Worker #include "chre/platform/log.h"
29*84e33947SAndroid Build Coastguard Worker #include "chre/platform/memory.h"
30*84e33947SAndroid Build Coastguard Worker #include "chre/platform/shared/host_protocol_chre.h"
31*84e33947SAndroid Build Coastguard Worker #include "chre/platform/shared/nanoapp_load_manager.h"
32*84e33947SAndroid Build Coastguard Worker #ifdef CHRE_USE_BUFFERED_LOGGING
33*84e33947SAndroid Build Coastguard Worker #include "chre/platform/shared/log_buffer_manager.h"
34*84e33947SAndroid Build Coastguard Worker #endif
35*84e33947SAndroid Build Coastguard Worker #include "chre/platform/slpi/fastrpc.h"
36*84e33947SAndroid Build Coastguard Worker #include "chre/platform/slpi/power_control_util.h"
37*84e33947SAndroid Build Coastguard Worker #include "chre/platform/system_time.h"
38*84e33947SAndroid Build Coastguard Worker #include "chre/platform/system_timer.h"
39*84e33947SAndroid Build Coastguard Worker #include "chre/util/flatbuffers/helpers.h"
40*84e33947SAndroid Build Coastguard Worker #include "chre/util/macros.h"
41*84e33947SAndroid Build Coastguard Worker #include "chre/util/nested_data_ptr.h"
42*84e33947SAndroid Build Coastguard Worker #include "chre/util/system/fixed_size_blocking_queue.h"
43*84e33947SAndroid Build Coastguard Worker #include "chre/util/unique_ptr.h"
44*84e33947SAndroid Build Coastguard Worker #include "chre_api/chre/version.h"
45*84e33947SAndroid Build Coastguard Worker
46*84e33947SAndroid Build Coastguard Worker #include <inttypes.h>
47*84e33947SAndroid Build Coastguard Worker #include <limits.h>
48*84e33947SAndroid Build Coastguard Worker
49*84e33947SAndroid Build Coastguard Worker namespace chre {
50*84e33947SAndroid Build Coastguard Worker
51*84e33947SAndroid Build Coastguard Worker namespace {
52*84e33947SAndroid Build Coastguard Worker
53*84e33947SAndroid Build Coastguard Worker constexpr size_t kOutboundQueueSize = 32;
54*84e33947SAndroid Build Coastguard Worker
55*84e33947SAndroid Build Coastguard Worker //! The last time a time sync request message has been sent.
56*84e33947SAndroid Build Coastguard Worker //! TODO: Make this a member of HostLinkBase
57*84e33947SAndroid Build Coastguard Worker Nanoseconds gLastTimeSyncRequestNanos(0);
58*84e33947SAndroid Build Coastguard Worker
59*84e33947SAndroid Build Coastguard Worker struct NanoappListData {
60*84e33947SAndroid Build Coastguard Worker ChreFlatBufferBuilder *builder;
61*84e33947SAndroid Build Coastguard Worker DynamicVector<NanoappListEntryOffset> nanoappEntries;
62*84e33947SAndroid Build Coastguard Worker uint16_t hostClientId;
63*84e33947SAndroid Build Coastguard Worker };
64*84e33947SAndroid Build Coastguard Worker
65*84e33947SAndroid Build Coastguard Worker enum class PendingMessageType {
66*84e33947SAndroid Build Coastguard Worker Shutdown,
67*84e33947SAndroid Build Coastguard Worker NanoappMessageToHost,
68*84e33947SAndroid Build Coastguard Worker HubInfoResponse,
69*84e33947SAndroid Build Coastguard Worker NanoappListResponse,
70*84e33947SAndroid Build Coastguard Worker LoadNanoappResponse,
71*84e33947SAndroid Build Coastguard Worker UnloadNanoappResponse,
72*84e33947SAndroid Build Coastguard Worker DebugDumpData,
73*84e33947SAndroid Build Coastguard Worker DebugDumpResponse,
74*84e33947SAndroid Build Coastguard Worker TimeSyncRequest,
75*84e33947SAndroid Build Coastguard Worker LowPowerMicAccessRequest,
76*84e33947SAndroid Build Coastguard Worker LowPowerMicAccessRelease,
77*84e33947SAndroid Build Coastguard Worker EncodedLogMessage,
78*84e33947SAndroid Build Coastguard Worker SelfTestResponse,
79*84e33947SAndroid Build Coastguard Worker MetricLog,
80*84e33947SAndroid Build Coastguard Worker NanConfigurationRequest,
81*84e33947SAndroid Build Coastguard Worker };
82*84e33947SAndroid Build Coastguard Worker
83*84e33947SAndroid Build Coastguard Worker struct PendingMessage {
PendingMessagechre::__anon98ca9eb40111::PendingMessage84*84e33947SAndroid Build Coastguard Worker PendingMessage(PendingMessageType msgType, uint16_t hostClientId) {
85*84e33947SAndroid Build Coastguard Worker type = msgType;
86*84e33947SAndroid Build Coastguard Worker data.hostClientId = hostClientId;
87*84e33947SAndroid Build Coastguard Worker }
88*84e33947SAndroid Build Coastguard Worker
PendingMessagechre::__anon98ca9eb40111::PendingMessage89*84e33947SAndroid Build Coastguard Worker PendingMessage(PendingMessageType msgType,
90*84e33947SAndroid Build Coastguard Worker const MessageToHost *msgToHost = nullptr) {
91*84e33947SAndroid Build Coastguard Worker type = msgType;
92*84e33947SAndroid Build Coastguard Worker data.msgToHost = msgToHost;
93*84e33947SAndroid Build Coastguard Worker }
94*84e33947SAndroid Build Coastguard Worker
PendingMessagechre::__anon98ca9eb40111::PendingMessage95*84e33947SAndroid Build Coastguard Worker PendingMessage(PendingMessageType msgType, ChreFlatBufferBuilder *builder) {
96*84e33947SAndroid Build Coastguard Worker type = msgType;
97*84e33947SAndroid Build Coastguard Worker data.builder = builder;
98*84e33947SAndroid Build Coastguard Worker }
99*84e33947SAndroid Build Coastguard Worker
100*84e33947SAndroid Build Coastguard Worker PendingMessageType type;
101*84e33947SAndroid Build Coastguard Worker union {
102*84e33947SAndroid Build Coastguard Worker const MessageToHost *msgToHost;
103*84e33947SAndroid Build Coastguard Worker uint16_t hostClientId;
104*84e33947SAndroid Build Coastguard Worker ChreFlatBufferBuilder *builder;
105*84e33947SAndroid Build Coastguard Worker } data;
106*84e33947SAndroid Build Coastguard Worker };
107*84e33947SAndroid Build Coastguard Worker
108*84e33947SAndroid Build Coastguard Worker struct UnloadNanoappCallbackData {
109*84e33947SAndroid Build Coastguard Worker uint64_t appId;
110*84e33947SAndroid Build Coastguard Worker uint32_t transactionId;
111*84e33947SAndroid Build Coastguard Worker uint16_t hostClientId;
112*84e33947SAndroid Build Coastguard Worker bool allowSystemNanoappUnload;
113*84e33947SAndroid Build Coastguard Worker };
114*84e33947SAndroid Build Coastguard Worker
115*84e33947SAndroid Build Coastguard Worker /**
116*84e33947SAndroid Build Coastguard Worker * @see buildAndEnqueueMessage()
117*84e33947SAndroid Build Coastguard Worker */
118*84e33947SAndroid Build Coastguard Worker typedef void(MessageBuilderFunction)(ChreFlatBufferBuilder &builder,
119*84e33947SAndroid Build Coastguard Worker void *cookie);
120*84e33947SAndroid Build Coastguard Worker
121*84e33947SAndroid Build Coastguard Worker FixedSizeBlockingQueue<PendingMessage, kOutboundQueueSize> gOutboundQueue;
122*84e33947SAndroid Build Coastguard Worker
copyToHostBuffer(const ChreFlatBufferBuilder & builder,unsigned char * buffer,size_t bufferSize,unsigned int * messageLen)123*84e33947SAndroid Build Coastguard Worker int copyToHostBuffer(const ChreFlatBufferBuilder &builder,
124*84e33947SAndroid Build Coastguard Worker unsigned char *buffer, size_t bufferSize,
125*84e33947SAndroid Build Coastguard Worker unsigned int *messageLen) {
126*84e33947SAndroid Build Coastguard Worker uint8_t *data = builder.GetBufferPointer();
127*84e33947SAndroid Build Coastguard Worker size_t size = builder.GetSize();
128*84e33947SAndroid Build Coastguard Worker int result;
129*84e33947SAndroid Build Coastguard Worker
130*84e33947SAndroid Build Coastguard Worker if (size > bufferSize) {
131*84e33947SAndroid Build Coastguard Worker LOGE("Encoded structure size %zu too big for host buffer %zu; dropping",
132*84e33947SAndroid Build Coastguard Worker size, bufferSize);
133*84e33947SAndroid Build Coastguard Worker result = CHRE_FASTRPC_ERROR;
134*84e33947SAndroid Build Coastguard Worker } else {
135*84e33947SAndroid Build Coastguard Worker memcpy(buffer, data, size);
136*84e33947SAndroid Build Coastguard Worker *messageLen = size;
137*84e33947SAndroid Build Coastguard Worker result = CHRE_FASTRPC_SUCCESS;
138*84e33947SAndroid Build Coastguard Worker }
139*84e33947SAndroid Build Coastguard Worker
140*84e33947SAndroid Build Coastguard Worker return result;
141*84e33947SAndroid Build Coastguard Worker }
142*84e33947SAndroid Build Coastguard Worker
143*84e33947SAndroid Build Coastguard Worker /**
144*84e33947SAndroid Build Coastguard Worker * Wrapper function to enqueue a message on the outbound message queue. All
145*84e33947SAndroid Build Coastguard Worker * outgoing message to the host must be called through this function.
146*84e33947SAndroid Build Coastguard Worker *
147*84e33947SAndroid Build Coastguard Worker * @param message The message to send to host.
148*84e33947SAndroid Build Coastguard Worker *
149*84e33947SAndroid Build Coastguard Worker * @return true if the message was successfully added to the queue.
150*84e33947SAndroid Build Coastguard Worker */
enqueueMessage(PendingMessage message)151*84e33947SAndroid Build Coastguard Worker bool enqueueMessage(PendingMessage message) {
152*84e33947SAndroid Build Coastguard Worker // Vote for big image temporarily when waking up the main thread waiting for
153*84e33947SAndroid Build Coastguard Worker // the message
154*84e33947SAndroid Build Coastguard Worker bool voteSuccess = slpiForceBigImage();
155*84e33947SAndroid Build Coastguard Worker bool success = gOutboundQueue.push(message);
156*84e33947SAndroid Build Coastguard Worker
157*84e33947SAndroid Build Coastguard Worker // Remove the vote only if we successfully made a big image transition
158*84e33947SAndroid Build Coastguard Worker if (voteSuccess) {
159*84e33947SAndroid Build Coastguard Worker slpiRemoveBigImageVote();
160*84e33947SAndroid Build Coastguard Worker }
161*84e33947SAndroid Build Coastguard Worker
162*84e33947SAndroid Build Coastguard Worker return success;
163*84e33947SAndroid Build Coastguard Worker }
164*84e33947SAndroid Build Coastguard Worker
165*84e33947SAndroid Build Coastguard Worker /**
166*84e33947SAndroid Build Coastguard Worker * Helper function that takes care of the boilerplate for allocating a
167*84e33947SAndroid Build Coastguard Worker * ChreFlatBufferBuilder on the heap and adding it to the outbound message
168*84e33947SAndroid Build Coastguard Worker * queue.
169*84e33947SAndroid Build Coastguard Worker *
170*84e33947SAndroid Build Coastguard Worker * @param msgType Identifies the message while in the outboud queue
171*84e33947SAndroid Build Coastguard Worker * @param initialBufferSize Number of bytes to reserve when first allocating the
172*84e33947SAndroid Build Coastguard Worker * ChreFlatBufferBuilder
173*84e33947SAndroid Build Coastguard Worker * @param buildMsgFunc Synchronous callback used to encode the FlatBuffer
174*84e33947SAndroid Build Coastguard Worker * message. Will not be invoked if allocation fails.
175*84e33947SAndroid Build Coastguard Worker * @param cookie Opaque pointer that will be passed through to buildMsgFunc
176*84e33947SAndroid Build Coastguard Worker *
177*84e33947SAndroid Build Coastguard Worker * @return true if the message was successfully added to the queue
178*84e33947SAndroid Build Coastguard Worker */
buildAndEnqueueMessage(PendingMessageType msgType,size_t initialBufferSize,MessageBuilderFunction * msgBuilder,void * cookie)179*84e33947SAndroid Build Coastguard Worker bool buildAndEnqueueMessage(PendingMessageType msgType,
180*84e33947SAndroid Build Coastguard Worker size_t initialBufferSize,
181*84e33947SAndroid Build Coastguard Worker MessageBuilderFunction *msgBuilder, void *cookie) {
182*84e33947SAndroid Build Coastguard Worker bool pushed = false;
183*84e33947SAndroid Build Coastguard Worker
184*84e33947SAndroid Build Coastguard Worker auto builder = MakeUnique<ChreFlatBufferBuilder>(initialBufferSize);
185*84e33947SAndroid Build Coastguard Worker if (builder.isNull()) {
186*84e33947SAndroid Build Coastguard Worker LOGE("Couldn't allocate memory for message type %d",
187*84e33947SAndroid Build Coastguard Worker static_cast<int>(msgType));
188*84e33947SAndroid Build Coastguard Worker } else {
189*84e33947SAndroid Build Coastguard Worker msgBuilder(*builder, cookie);
190*84e33947SAndroid Build Coastguard Worker
191*84e33947SAndroid Build Coastguard Worker // TODO: if this fails, ideally we should block for some timeout until
192*84e33947SAndroid Build Coastguard Worker // there's space in the queue
193*84e33947SAndroid Build Coastguard Worker if (!enqueueMessage(PendingMessage(msgType, builder.get()))) {
194*84e33947SAndroid Build Coastguard Worker LOGE("Couldn't push message type %d to outbound queue",
195*84e33947SAndroid Build Coastguard Worker static_cast<int>(msgType));
196*84e33947SAndroid Build Coastguard Worker } else {
197*84e33947SAndroid Build Coastguard Worker builder.release();
198*84e33947SAndroid Build Coastguard Worker pushed = true;
199*84e33947SAndroid Build Coastguard Worker }
200*84e33947SAndroid Build Coastguard Worker }
201*84e33947SAndroid Build Coastguard Worker
202*84e33947SAndroid Build Coastguard Worker return pushed;
203*84e33947SAndroid Build Coastguard Worker }
204*84e33947SAndroid Build Coastguard Worker
205*84e33947SAndroid Build Coastguard Worker /**
206*84e33947SAndroid Build Coastguard Worker * FlatBuffer message builder callback used with handleNanoappListRequest()
207*84e33947SAndroid Build Coastguard Worker */
buildNanoappListResponse(ChreFlatBufferBuilder & builder,void * cookie)208*84e33947SAndroid Build Coastguard Worker void buildNanoappListResponse(ChreFlatBufferBuilder &builder, void *cookie) {
209*84e33947SAndroid Build Coastguard Worker auto nanoappAdderCallback = [](const Nanoapp *nanoapp, void *data) {
210*84e33947SAndroid Build Coastguard Worker auto *cbData = static_cast<NanoappListData *>(data);
211*84e33947SAndroid Build Coastguard Worker HostProtocolChre::addNanoappListEntry(
212*84e33947SAndroid Build Coastguard Worker *(cbData->builder), cbData->nanoappEntries, nanoapp->getAppId(),
213*84e33947SAndroid Build Coastguard Worker nanoapp->getAppVersion(), true /*enabled*/, nanoapp->isSystemNanoapp(),
214*84e33947SAndroid Build Coastguard Worker nanoapp->getAppPermissions(), nanoapp->getRpcServices());
215*84e33947SAndroid Build Coastguard Worker };
216*84e33947SAndroid Build Coastguard Worker
217*84e33947SAndroid Build Coastguard Worker // Add a NanoappListEntry to the FlatBuffer for each nanoapp
218*84e33947SAndroid Build Coastguard Worker auto *cbData = static_cast<NanoappListData *>(cookie);
219*84e33947SAndroid Build Coastguard Worker cbData->builder = &builder;
220*84e33947SAndroid Build Coastguard Worker EventLoop &eventLoop = EventLoopManagerSingleton::get()->getEventLoop();
221*84e33947SAndroid Build Coastguard Worker eventLoop.forEachNanoapp(nanoappAdderCallback, cbData);
222*84e33947SAndroid Build Coastguard Worker HostProtocolChre::finishNanoappListResponse(builder, cbData->nanoappEntries,
223*84e33947SAndroid Build Coastguard Worker cbData->hostClientId);
224*84e33947SAndroid Build Coastguard Worker }
225*84e33947SAndroid Build Coastguard Worker
handleUnloadNanoappCallback(SystemCallbackType,UniquePtr<UnloadNanoappCallbackData> && data)226*84e33947SAndroid Build Coastguard Worker void handleUnloadNanoappCallback(SystemCallbackType /*type*/,
227*84e33947SAndroid Build Coastguard Worker UniquePtr<UnloadNanoappCallbackData> &&data) {
228*84e33947SAndroid Build Coastguard Worker auto msgBuilder = [](ChreFlatBufferBuilder &builder, void *cookie) {
229*84e33947SAndroid Build Coastguard Worker auto *cbData = static_cast<UnloadNanoappCallbackData *>(cookie);
230*84e33947SAndroid Build Coastguard Worker
231*84e33947SAndroid Build Coastguard Worker bool success = false;
232*84e33947SAndroid Build Coastguard Worker uint16_t instanceId;
233*84e33947SAndroid Build Coastguard Worker EventLoop &eventLoop = EventLoopManagerSingleton::get()->getEventLoop();
234*84e33947SAndroid Build Coastguard Worker if (!eventLoop.findNanoappInstanceIdByAppId(cbData->appId, &instanceId)) {
235*84e33947SAndroid Build Coastguard Worker LOGE("Couldn't unload app ID 0x%016" PRIx64 ": not found", cbData->appId);
236*84e33947SAndroid Build Coastguard Worker } else {
237*84e33947SAndroid Build Coastguard Worker success =
238*84e33947SAndroid Build Coastguard Worker eventLoop.unloadNanoapp(instanceId, cbData->allowSystemNanoappUnload);
239*84e33947SAndroid Build Coastguard Worker }
240*84e33947SAndroid Build Coastguard Worker
241*84e33947SAndroid Build Coastguard Worker HostProtocolChre::encodeUnloadNanoappResponse(
242*84e33947SAndroid Build Coastguard Worker builder, cbData->hostClientId, cbData->transactionId, success);
243*84e33947SAndroid Build Coastguard Worker };
244*84e33947SAndroid Build Coastguard Worker
245*84e33947SAndroid Build Coastguard Worker constexpr size_t kInitialBufferSize = 52;
246*84e33947SAndroid Build Coastguard Worker buildAndEnqueueMessage(PendingMessageType::UnloadNanoappResponse,
247*84e33947SAndroid Build Coastguard Worker kInitialBufferSize, msgBuilder, data.get());
248*84e33947SAndroid Build Coastguard Worker }
249*84e33947SAndroid Build Coastguard Worker
generateMessageToHost(const MessageToHost * msgToHost,unsigned char * buffer,size_t bufferSize,unsigned int * messageLen)250*84e33947SAndroid Build Coastguard Worker int generateMessageToHost(const MessageToHost *msgToHost, unsigned char *buffer,
251*84e33947SAndroid Build Coastguard Worker size_t bufferSize, unsigned int *messageLen) {
252*84e33947SAndroid Build Coastguard Worker // TODO: ideally we'd construct our flatbuffer directly in the
253*84e33947SAndroid Build Coastguard Worker // host-supplied buffer
254*84e33947SAndroid Build Coastguard Worker constexpr size_t kFixedSizePortion = 88;
255*84e33947SAndroid Build Coastguard Worker ChreFlatBufferBuilder builder(msgToHost->message.size() + kFixedSizePortion);
256*84e33947SAndroid Build Coastguard Worker HostProtocolChre::encodeNanoappMessage(
257*84e33947SAndroid Build Coastguard Worker builder, msgToHost->appId, msgToHost->toHostData.messageType,
258*84e33947SAndroid Build Coastguard Worker msgToHost->toHostData.hostEndpoint, msgToHost->message.data(),
259*84e33947SAndroid Build Coastguard Worker msgToHost->message.size(), msgToHost->toHostData.appPermissions,
260*84e33947SAndroid Build Coastguard Worker msgToHost->toHostData.messagePermissions, msgToHost->toHostData.wokeHost);
261*84e33947SAndroid Build Coastguard Worker
262*84e33947SAndroid Build Coastguard Worker int result = copyToHostBuffer(builder, buffer, bufferSize, messageLen);
263*84e33947SAndroid Build Coastguard Worker
264*84e33947SAndroid Build Coastguard Worker auto &hostCommsManager =
265*84e33947SAndroid Build Coastguard Worker EventLoopManagerSingleton::get()->getHostCommsManager();
266*84e33947SAndroid Build Coastguard Worker hostCommsManager.onMessageToHostComplete(msgToHost);
267*84e33947SAndroid Build Coastguard Worker
268*84e33947SAndroid Build Coastguard Worker return result;
269*84e33947SAndroid Build Coastguard Worker }
270*84e33947SAndroid Build Coastguard Worker
generateHubInfoResponse(uint16_t hostClientId,unsigned char * buffer,size_t bufferSize,unsigned int * messageLen)271*84e33947SAndroid Build Coastguard Worker int generateHubInfoResponse(uint16_t hostClientId, unsigned char *buffer,
272*84e33947SAndroid Build Coastguard Worker size_t bufferSize, unsigned int *messageLen) {
273*84e33947SAndroid Build Coastguard Worker constexpr size_t kInitialBufferSize = 192;
274*84e33947SAndroid Build Coastguard Worker
275*84e33947SAndroid Build Coastguard Worker constexpr char kHubName[] = "CHRE on SLPI";
276*84e33947SAndroid Build Coastguard Worker constexpr char kVendor[] = "Google";
277*84e33947SAndroid Build Coastguard Worker constexpr char kToolchain[] =
278*84e33947SAndroid Build Coastguard Worker "Hexagon Tools 8.x (clang " STRINGIFY(__clang_major__) "." STRINGIFY(
279*84e33947SAndroid Build Coastguard Worker __clang_minor__) "." STRINGIFY(__clang_patchlevel__) ")";
280*84e33947SAndroid Build Coastguard Worker constexpr uint32_t kLegacyPlatformVersion = 0;
281*84e33947SAndroid Build Coastguard Worker constexpr uint32_t kLegacyToolchainVersion =
282*84e33947SAndroid Build Coastguard Worker ((__clang_major__ & 0xFF) << 24) | ((__clang_minor__ & 0xFF) << 16) |
283*84e33947SAndroid Build Coastguard Worker (__clang_patchlevel__ & 0xFFFF);
284*84e33947SAndroid Build Coastguard Worker constexpr float kPeakMips = 350;
285*84e33947SAndroid Build Coastguard Worker constexpr float kStoppedPower = 0;
286*84e33947SAndroid Build Coastguard Worker constexpr float kSleepPower = 1;
287*84e33947SAndroid Build Coastguard Worker constexpr float kPeakPower = 15;
288*84e33947SAndroid Build Coastguard Worker
289*84e33947SAndroid Build Coastguard Worker // Note that this may execute prior to EventLoopManager::lateInit() completing
290*84e33947SAndroid Build Coastguard Worker ChreFlatBufferBuilder builder(kInitialBufferSize);
291*84e33947SAndroid Build Coastguard Worker HostProtocolChre::encodeHubInfoResponse(
292*84e33947SAndroid Build Coastguard Worker builder, kHubName, kVendor, kToolchain, kLegacyPlatformVersion,
293*84e33947SAndroid Build Coastguard Worker kLegacyToolchainVersion, kPeakMips, kStoppedPower, kSleepPower,
294*84e33947SAndroid Build Coastguard Worker kPeakPower, chreGetMessageToHostMaxSize(), chreGetPlatformId(),
295*84e33947SAndroid Build Coastguard Worker chreGetVersion(), hostClientId, /* supportsReliableMessage= */ false);
296*84e33947SAndroid Build Coastguard Worker
297*84e33947SAndroid Build Coastguard Worker return copyToHostBuffer(builder, buffer, bufferSize, messageLen);
298*84e33947SAndroid Build Coastguard Worker }
299*84e33947SAndroid Build Coastguard Worker
generateMessageFromBuilder(ChreFlatBufferBuilder * builder,unsigned char * buffer,size_t bufferSize,unsigned int * messageLen,bool isEncodedLogMessage)300*84e33947SAndroid Build Coastguard Worker int generateMessageFromBuilder(ChreFlatBufferBuilder *builder,
301*84e33947SAndroid Build Coastguard Worker unsigned char *buffer, size_t bufferSize,
302*84e33947SAndroid Build Coastguard Worker unsigned int *messageLen,
303*84e33947SAndroid Build Coastguard Worker bool isEncodedLogMessage) {
304*84e33947SAndroid Build Coastguard Worker CHRE_ASSERT(builder != nullptr);
305*84e33947SAndroid Build Coastguard Worker int result = copyToHostBuffer(*builder, buffer, bufferSize, messageLen);
306*84e33947SAndroid Build Coastguard Worker
307*84e33947SAndroid Build Coastguard Worker #ifdef CHRE_USE_BUFFERED_LOGGING
308*84e33947SAndroid Build Coastguard Worker if (isEncodedLogMessage && LogBufferManagerSingleton::isInitialized()) {
309*84e33947SAndroid Build Coastguard Worker LogBufferManagerSingleton::get()->onLogsSentToHost();
310*84e33947SAndroid Build Coastguard Worker }
311*84e33947SAndroid Build Coastguard Worker #else
312*84e33947SAndroid Build Coastguard Worker UNUSED_VAR(isEncodedLogMessage);
313*84e33947SAndroid Build Coastguard Worker #endif
314*84e33947SAndroid Build Coastguard Worker
315*84e33947SAndroid Build Coastguard Worker builder->~ChreFlatBufferBuilder();
316*84e33947SAndroid Build Coastguard Worker memoryFree(builder);
317*84e33947SAndroid Build Coastguard Worker return result;
318*84e33947SAndroid Build Coastguard Worker }
319*84e33947SAndroid Build Coastguard Worker
sendDebugDumpData(uint16_t hostClientId,const char * debugStr,size_t debugStrSize)320*84e33947SAndroid Build Coastguard Worker void sendDebugDumpData(uint16_t hostClientId, const char *debugStr,
321*84e33947SAndroid Build Coastguard Worker size_t debugStrSize) {
322*84e33947SAndroid Build Coastguard Worker struct DebugDumpMessageData {
323*84e33947SAndroid Build Coastguard Worker uint16_t hostClientId;
324*84e33947SAndroid Build Coastguard Worker const char *debugStr;
325*84e33947SAndroid Build Coastguard Worker size_t debugStrSize;
326*84e33947SAndroid Build Coastguard Worker };
327*84e33947SAndroid Build Coastguard Worker
328*84e33947SAndroid Build Coastguard Worker auto msgBuilder = [](ChreFlatBufferBuilder &builder, void *cookie) {
329*84e33947SAndroid Build Coastguard Worker const auto *data = static_cast<const DebugDumpMessageData *>(cookie);
330*84e33947SAndroid Build Coastguard Worker HostProtocolChre::encodeDebugDumpData(builder, data->hostClientId,
331*84e33947SAndroid Build Coastguard Worker data->debugStr, data->debugStrSize);
332*84e33947SAndroid Build Coastguard Worker };
333*84e33947SAndroid Build Coastguard Worker
334*84e33947SAndroid Build Coastguard Worker constexpr size_t kFixedSizePortion = 52;
335*84e33947SAndroid Build Coastguard Worker DebugDumpMessageData data;
336*84e33947SAndroid Build Coastguard Worker data.hostClientId = hostClientId;
337*84e33947SAndroid Build Coastguard Worker data.debugStr = debugStr;
338*84e33947SAndroid Build Coastguard Worker data.debugStrSize = debugStrSize;
339*84e33947SAndroid Build Coastguard Worker buildAndEnqueueMessage(PendingMessageType::DebugDumpData,
340*84e33947SAndroid Build Coastguard Worker kFixedSizePortion + debugStrSize, msgBuilder, &data);
341*84e33947SAndroid Build Coastguard Worker }
342*84e33947SAndroid Build Coastguard Worker
sendDebugDumpResponse(uint16_t hostClientId,bool success,uint32_t dataCount)343*84e33947SAndroid Build Coastguard Worker void sendDebugDumpResponse(uint16_t hostClientId, bool success,
344*84e33947SAndroid Build Coastguard Worker uint32_t dataCount) {
345*84e33947SAndroid Build Coastguard Worker struct DebugDumpResponseData {
346*84e33947SAndroid Build Coastguard Worker uint16_t hostClientId;
347*84e33947SAndroid Build Coastguard Worker bool success;
348*84e33947SAndroid Build Coastguard Worker uint32_t dataCount;
349*84e33947SAndroid Build Coastguard Worker };
350*84e33947SAndroid Build Coastguard Worker
351*84e33947SAndroid Build Coastguard Worker auto msgBuilder = [](ChreFlatBufferBuilder &builder, void *cookie) {
352*84e33947SAndroid Build Coastguard Worker const auto *data = static_cast<const DebugDumpResponseData *>(cookie);
353*84e33947SAndroid Build Coastguard Worker HostProtocolChre::encodeDebugDumpResponse(builder, data->hostClientId,
354*84e33947SAndroid Build Coastguard Worker data->success, data->dataCount);
355*84e33947SAndroid Build Coastguard Worker };
356*84e33947SAndroid Build Coastguard Worker
357*84e33947SAndroid Build Coastguard Worker constexpr size_t kInitialSize = 52;
358*84e33947SAndroid Build Coastguard Worker DebugDumpResponseData data;
359*84e33947SAndroid Build Coastguard Worker data.hostClientId = hostClientId;
360*84e33947SAndroid Build Coastguard Worker data.success = success;
361*84e33947SAndroid Build Coastguard Worker data.dataCount = dataCount;
362*84e33947SAndroid Build Coastguard Worker buildAndEnqueueMessage(PendingMessageType::DebugDumpResponse, kInitialSize,
363*84e33947SAndroid Build Coastguard Worker msgBuilder, &data);
364*84e33947SAndroid Build Coastguard Worker }
365*84e33947SAndroid Build Coastguard Worker
sendSelfTestResponse(uint16_t hostClientId,bool success)366*84e33947SAndroid Build Coastguard Worker void sendSelfTestResponse(uint16_t hostClientId, bool success) {
367*84e33947SAndroid Build Coastguard Worker struct SelfTestResponseData {
368*84e33947SAndroid Build Coastguard Worker uint16_t hostClientId;
369*84e33947SAndroid Build Coastguard Worker bool success;
370*84e33947SAndroid Build Coastguard Worker };
371*84e33947SAndroid Build Coastguard Worker
372*84e33947SAndroid Build Coastguard Worker auto msgBuilder = [](ChreFlatBufferBuilder &builder, void *cookie) {
373*84e33947SAndroid Build Coastguard Worker const auto *data = static_cast<const SelfTestResponseData *>(cookie);
374*84e33947SAndroid Build Coastguard Worker HostProtocolChre::encodeSelfTestResponse(builder, data->hostClientId,
375*84e33947SAndroid Build Coastguard Worker data->success);
376*84e33947SAndroid Build Coastguard Worker };
377*84e33947SAndroid Build Coastguard Worker
378*84e33947SAndroid Build Coastguard Worker constexpr size_t kInitialSize = 52;
379*84e33947SAndroid Build Coastguard Worker SelfTestResponseData data;
380*84e33947SAndroid Build Coastguard Worker data.hostClientId = hostClientId;
381*84e33947SAndroid Build Coastguard Worker data.success = success;
382*84e33947SAndroid Build Coastguard Worker buildAndEnqueueMessage(PendingMessageType::SelfTestResponse, kInitialSize,
383*84e33947SAndroid Build Coastguard Worker msgBuilder, &data);
384*84e33947SAndroid Build Coastguard Worker }
385*84e33947SAndroid Build Coastguard Worker
386*84e33947SAndroid Build Coastguard Worker /**
387*84e33947SAndroid Build Coastguard Worker * Sends a request to the host for a time sync message.
388*84e33947SAndroid Build Coastguard Worker */
sendTimeSyncRequest()389*84e33947SAndroid Build Coastguard Worker void sendTimeSyncRequest() {
390*84e33947SAndroid Build Coastguard Worker auto msgBuilder = [](ChreFlatBufferBuilder &builder, void *cookie) {
391*84e33947SAndroid Build Coastguard Worker HostProtocolChre::encodeTimeSyncRequest(builder);
392*84e33947SAndroid Build Coastguard Worker };
393*84e33947SAndroid Build Coastguard Worker
394*84e33947SAndroid Build Coastguard Worker constexpr size_t kInitialSize = 52;
395*84e33947SAndroid Build Coastguard Worker buildAndEnqueueMessage(PendingMessageType::TimeSyncRequest, kInitialSize,
396*84e33947SAndroid Build Coastguard Worker msgBuilder, nullptr);
397*84e33947SAndroid Build Coastguard Worker
398*84e33947SAndroid Build Coastguard Worker gLastTimeSyncRequestNanos = SystemTime::getMonotonicTime();
399*84e33947SAndroid Build Coastguard Worker }
400*84e33947SAndroid Build Coastguard Worker
setTimeSyncRequestTimer(Nanoseconds delay)401*84e33947SAndroid Build Coastguard Worker void setTimeSyncRequestTimer(Nanoseconds delay) {
402*84e33947SAndroid Build Coastguard Worker static SystemTimer sTimeSyncRequestTimer;
403*84e33947SAndroid Build Coastguard Worker static bool sTimeSyncRequestTimerInitialized = false;
404*84e33947SAndroid Build Coastguard Worker
405*84e33947SAndroid Build Coastguard Worker // Check for timer init since this method might be called before CHRE
406*84e33947SAndroid Build Coastguard Worker // init is called.
407*84e33947SAndroid Build Coastguard Worker if (!sTimeSyncRequestTimerInitialized) {
408*84e33947SAndroid Build Coastguard Worker if (!sTimeSyncRequestTimer.init()) {
409*84e33947SAndroid Build Coastguard Worker FATAL_ERROR("Failed to initialize time sync request timer.");
410*84e33947SAndroid Build Coastguard Worker } else {
411*84e33947SAndroid Build Coastguard Worker sTimeSyncRequestTimerInitialized = true;
412*84e33947SAndroid Build Coastguard Worker }
413*84e33947SAndroid Build Coastguard Worker }
414*84e33947SAndroid Build Coastguard Worker if (sTimeSyncRequestTimer.isActive()) {
415*84e33947SAndroid Build Coastguard Worker sTimeSyncRequestTimer.cancel();
416*84e33947SAndroid Build Coastguard Worker }
417*84e33947SAndroid Build Coastguard Worker auto callback = [](void * /* data */) { sendTimeSyncRequest(); };
418*84e33947SAndroid Build Coastguard Worker if (!sTimeSyncRequestTimer.set(callback, nullptr /* data */, delay)) {
419*84e33947SAndroid Build Coastguard Worker LOGE("Failed to set time sync request timer.");
420*84e33947SAndroid Build Coastguard Worker }
421*84e33947SAndroid Build Coastguard Worker }
422*84e33947SAndroid Build Coastguard Worker
423*84e33947SAndroid Build Coastguard Worker /**
424*84e33947SAndroid Build Coastguard Worker * Helper function that prepares a nanoapp that can be loaded into the system
425*84e33947SAndroid Build Coastguard Worker * from a file stored on disk.
426*84e33947SAndroid Build Coastguard Worker *
427*84e33947SAndroid Build Coastguard Worker * @param hostClientId the ID of client that originated this transaction
428*84e33947SAndroid Build Coastguard Worker * @param transactionId the ID of the transaction
429*84e33947SAndroid Build Coastguard Worker * @param appId the ID of the app to load
430*84e33947SAndroid Build Coastguard Worker * @param appVersion the version of the app to load
431*84e33947SAndroid Build Coastguard Worker * @param targetApiVersion the API version this nanoapp is targeted for
432*84e33947SAndroid Build Coastguard Worker * @param appFilename Null-terminated ASCII string containing the file name that
433*84e33947SAndroid Build Coastguard Worker * contains the app binary to be loaded.
434*84e33947SAndroid Build Coastguard Worker *
435*84e33947SAndroid Build Coastguard Worker * @return A valid pointer to a nanoapp that can be loaded into the system. A
436*84e33947SAndroid Build Coastguard Worker * nullptr if the preparation process fails.
437*84e33947SAndroid Build Coastguard Worker */
handleLoadNanoappFile(uint16_t hostClientId,uint32_t transactionId,uint64_t appId,uint32_t appVersion,uint32_t targetApiVersion,const char * appFilename)438*84e33947SAndroid Build Coastguard Worker UniquePtr<Nanoapp> handleLoadNanoappFile(uint16_t hostClientId,
439*84e33947SAndroid Build Coastguard Worker uint32_t transactionId, uint64_t appId,
440*84e33947SAndroid Build Coastguard Worker uint32_t appVersion,
441*84e33947SAndroid Build Coastguard Worker uint32_t targetApiVersion,
442*84e33947SAndroid Build Coastguard Worker const char *appFilename) {
443*84e33947SAndroid Build Coastguard Worker LOGD("Load nanoapp request for app ID 0x%016" PRIx64 " ver 0x%" PRIx32
444*84e33947SAndroid Build Coastguard Worker " target API 0x%08" PRIx32 " (txnId %" PRIu32 " client %" PRIu16 ")",
445*84e33947SAndroid Build Coastguard Worker appId, appVersion, targetApiVersion, transactionId, hostClientId);
446*84e33947SAndroid Build Coastguard Worker
447*84e33947SAndroid Build Coastguard Worker auto nanoapp = MakeUnique<Nanoapp>();
448*84e33947SAndroid Build Coastguard Worker
449*84e33947SAndroid Build Coastguard Worker if (nanoapp.isNull()) {
450*84e33947SAndroid Build Coastguard Worker LOG_OOM();
451*84e33947SAndroid Build Coastguard Worker } else if (!nanoapp->setAppInfo(appId, appVersion, appFilename,
452*84e33947SAndroid Build Coastguard Worker targetApiVersion) ||
453*84e33947SAndroid Build Coastguard Worker !nanoapp->isLoaded()) {
454*84e33947SAndroid Build Coastguard Worker nanoapp.reset(nullptr);
455*84e33947SAndroid Build Coastguard Worker }
456*84e33947SAndroid Build Coastguard Worker
457*84e33947SAndroid Build Coastguard Worker return nanoapp;
458*84e33947SAndroid Build Coastguard Worker }
459*84e33947SAndroid Build Coastguard Worker
460*84e33947SAndroid Build Coastguard Worker /**
461*84e33947SAndroid Build Coastguard Worker * FastRPC method invoked by the host to block on messages
462*84e33947SAndroid Build Coastguard Worker *
463*84e33947SAndroid Build Coastguard Worker * @param buffer Output buffer to populate with message data
464*84e33947SAndroid Build Coastguard Worker * @param bufferLen Size of the buffer, in bytes
465*84e33947SAndroid Build Coastguard Worker * @param messageLen Output parameter to populate with the size of the message
466*84e33947SAndroid Build Coastguard Worker * in bytes upon success
467*84e33947SAndroid Build Coastguard Worker *
468*84e33947SAndroid Build Coastguard Worker * @return 0 on success, nonzero on failure
469*84e33947SAndroid Build Coastguard Worker */
chre_slpi_get_message_to_host(unsigned char * buffer,int bufferLen,unsigned int * messageLen)470*84e33947SAndroid Build Coastguard Worker extern "C" int chre_slpi_get_message_to_host(unsigned char *buffer,
471*84e33947SAndroid Build Coastguard Worker int bufferLen,
472*84e33947SAndroid Build Coastguard Worker unsigned int *messageLen) {
473*84e33947SAndroid Build Coastguard Worker CHRE_ASSERT(buffer != nullptr);
474*84e33947SAndroid Build Coastguard Worker CHRE_ASSERT(bufferLen > 0);
475*84e33947SAndroid Build Coastguard Worker CHRE_ASSERT(messageLen != nullptr);
476*84e33947SAndroid Build Coastguard Worker int result = CHRE_FASTRPC_ERROR;
477*84e33947SAndroid Build Coastguard Worker
478*84e33947SAndroid Build Coastguard Worker if (bufferLen <= 0 || buffer == nullptr || messageLen == nullptr) {
479*84e33947SAndroid Build Coastguard Worker // Note that we can't use regular logs here as they can result in sending
480*84e33947SAndroid Build Coastguard Worker // a message, leading to an infinite loop if the error is persistent
481*84e33947SAndroid Build Coastguard Worker FARF(FATAL, "Invalid buffer size %d or bad pointers (buf %d len %d)",
482*84e33947SAndroid Build Coastguard Worker bufferLen, (buffer == nullptr), (messageLen == nullptr));
483*84e33947SAndroid Build Coastguard Worker } else {
484*84e33947SAndroid Build Coastguard Worker size_t bufferSize = static_cast<size_t>(bufferLen);
485*84e33947SAndroid Build Coastguard Worker PendingMessage pendingMsg = gOutboundQueue.pop();
486*84e33947SAndroid Build Coastguard Worker
487*84e33947SAndroid Build Coastguard Worker switch (pendingMsg.type) {
488*84e33947SAndroid Build Coastguard Worker case PendingMessageType::Shutdown:
489*84e33947SAndroid Build Coastguard Worker result = CHRE_FASTRPC_ERROR_SHUTTING_DOWN;
490*84e33947SAndroid Build Coastguard Worker break;
491*84e33947SAndroid Build Coastguard Worker
492*84e33947SAndroid Build Coastguard Worker case PendingMessageType::NanoappMessageToHost:
493*84e33947SAndroid Build Coastguard Worker result = generateMessageToHost(pendingMsg.data.msgToHost, buffer,
494*84e33947SAndroid Build Coastguard Worker bufferSize, messageLen);
495*84e33947SAndroid Build Coastguard Worker break;
496*84e33947SAndroid Build Coastguard Worker
497*84e33947SAndroid Build Coastguard Worker case PendingMessageType::HubInfoResponse:
498*84e33947SAndroid Build Coastguard Worker result = generateHubInfoResponse(pendingMsg.data.hostClientId, buffer,
499*84e33947SAndroid Build Coastguard Worker bufferSize, messageLen);
500*84e33947SAndroid Build Coastguard Worker break;
501*84e33947SAndroid Build Coastguard Worker
502*84e33947SAndroid Build Coastguard Worker case PendingMessageType::NanoappListResponse:
503*84e33947SAndroid Build Coastguard Worker case PendingMessageType::LoadNanoappResponse:
504*84e33947SAndroid Build Coastguard Worker case PendingMessageType::UnloadNanoappResponse:
505*84e33947SAndroid Build Coastguard Worker case PendingMessageType::DebugDumpData:
506*84e33947SAndroid Build Coastguard Worker case PendingMessageType::DebugDumpResponse:
507*84e33947SAndroid Build Coastguard Worker case PendingMessageType::TimeSyncRequest:
508*84e33947SAndroid Build Coastguard Worker case PendingMessageType::LowPowerMicAccessRequest:
509*84e33947SAndroid Build Coastguard Worker case PendingMessageType::LowPowerMicAccessRelease:
510*84e33947SAndroid Build Coastguard Worker case PendingMessageType::EncodedLogMessage:
511*84e33947SAndroid Build Coastguard Worker case PendingMessageType::SelfTestResponse:
512*84e33947SAndroid Build Coastguard Worker case PendingMessageType::MetricLog:
513*84e33947SAndroid Build Coastguard Worker case PendingMessageType::NanConfigurationRequest:
514*84e33947SAndroid Build Coastguard Worker result = generateMessageFromBuilder(
515*84e33947SAndroid Build Coastguard Worker pendingMsg.data.builder, buffer, bufferSize, messageLen,
516*84e33947SAndroid Build Coastguard Worker pendingMsg.type == PendingMessageType::EncodedLogMessage);
517*84e33947SAndroid Build Coastguard Worker break;
518*84e33947SAndroid Build Coastguard Worker
519*84e33947SAndroid Build Coastguard Worker default:
520*84e33947SAndroid Build Coastguard Worker CHRE_ASSERT_LOG(false, "Unexpected pending message type");
521*84e33947SAndroid Build Coastguard Worker }
522*84e33947SAndroid Build Coastguard Worker }
523*84e33947SAndroid Build Coastguard Worker
524*84e33947SAndroid Build Coastguard Worker // Opportunistically send a time sync message (1 hour period threshold)
525*84e33947SAndroid Build Coastguard Worker constexpr Seconds kOpportunisticTimeSyncPeriod = Seconds(60 * 60 * 1);
526*84e33947SAndroid Build Coastguard Worker if (SystemTime::getMonotonicTime() >
527*84e33947SAndroid Build Coastguard Worker gLastTimeSyncRequestNanos + kOpportunisticTimeSyncPeriod) {
528*84e33947SAndroid Build Coastguard Worker sendTimeSyncRequest();
529*84e33947SAndroid Build Coastguard Worker }
530*84e33947SAndroid Build Coastguard Worker
531*84e33947SAndroid Build Coastguard Worker return result;
532*84e33947SAndroid Build Coastguard Worker }
533*84e33947SAndroid Build Coastguard Worker
534*84e33947SAndroid Build Coastguard Worker /**
535*84e33947SAndroid Build Coastguard Worker * FastRPC method invoked by the host to send a message to the system
536*84e33947SAndroid Build Coastguard Worker *
537*84e33947SAndroid Build Coastguard Worker * @param buffer
538*84e33947SAndroid Build Coastguard Worker * @param size
539*84e33947SAndroid Build Coastguard Worker *
540*84e33947SAndroid Build Coastguard Worker * @return 0 on success, nonzero on failure
541*84e33947SAndroid Build Coastguard Worker */
chre_slpi_deliver_message_from_host(const unsigned char * message,int messageLen)542*84e33947SAndroid Build Coastguard Worker extern "C" int chre_slpi_deliver_message_from_host(const unsigned char *message,
543*84e33947SAndroid Build Coastguard Worker int messageLen) {
544*84e33947SAndroid Build Coastguard Worker CHRE_ASSERT(message != nullptr);
545*84e33947SAndroid Build Coastguard Worker CHRE_ASSERT(messageLen > 0);
546*84e33947SAndroid Build Coastguard Worker int result = CHRE_FASTRPC_ERROR;
547*84e33947SAndroid Build Coastguard Worker
548*84e33947SAndroid Build Coastguard Worker if (message == nullptr || messageLen <= 0) {
549*84e33947SAndroid Build Coastguard Worker LOGE("Got null or invalid size (%d) message from host", messageLen);
550*84e33947SAndroid Build Coastguard Worker } else if (!HostProtocolChre::decodeMessageFromHost(
551*84e33947SAndroid Build Coastguard Worker message, static_cast<size_t>(messageLen))) {
552*84e33947SAndroid Build Coastguard Worker LOGE("Failed to decode/handle message");
553*84e33947SAndroid Build Coastguard Worker } else {
554*84e33947SAndroid Build Coastguard Worker result = CHRE_FASTRPC_SUCCESS;
555*84e33947SAndroid Build Coastguard Worker }
556*84e33947SAndroid Build Coastguard Worker
557*84e33947SAndroid Build Coastguard Worker return result;
558*84e33947SAndroid Build Coastguard Worker }
559*84e33947SAndroid Build Coastguard Worker
560*84e33947SAndroid Build Coastguard Worker } // anonymous namespace
561*84e33947SAndroid Build Coastguard Worker
sendDebugDumpResultToHost(uint16_t hostClientId,const char * debugStr,size_t debugStrSize,bool complete,uint32_t dataCount)562*84e33947SAndroid Build Coastguard Worker void sendDebugDumpResultToHost(uint16_t hostClientId, const char *debugStr,
563*84e33947SAndroid Build Coastguard Worker size_t debugStrSize, bool complete,
564*84e33947SAndroid Build Coastguard Worker uint32_t dataCount) {
565*84e33947SAndroid Build Coastguard Worker if (debugStrSize > 0) {
566*84e33947SAndroid Build Coastguard Worker sendDebugDumpData(hostClientId, debugStr, debugStrSize);
567*84e33947SAndroid Build Coastguard Worker }
568*84e33947SAndroid Build Coastguard Worker
569*84e33947SAndroid Build Coastguard Worker if (complete) {
570*84e33947SAndroid Build Coastguard Worker sendDebugDumpResponse(hostClientId, true /*success*/, dataCount);
571*84e33947SAndroid Build Coastguard Worker }
572*84e33947SAndroid Build Coastguard Worker }
573*84e33947SAndroid Build Coastguard Worker
flushMessagesSentByNanoapp(uint64_t)574*84e33947SAndroid Build Coastguard Worker void HostLink::flushMessagesSentByNanoapp(uint64_t /*appId*/) {
575*84e33947SAndroid Build Coastguard Worker // TODO: this is not completely safe since it's timer-based, but should work
576*84e33947SAndroid Build Coastguard Worker // well enough for the initial implementation. To be fully safe, we'd need
577*84e33947SAndroid Build Coastguard Worker // some synchronization with the thread that runs
578*84e33947SAndroid Build Coastguard Worker // chre_slpi_get_message_to_host(), e.g. a mutex that is held by that thread
579*84e33947SAndroid Build Coastguard Worker // prior to calling pop() and only released after onMessageToHostComplete
580*84e33947SAndroid Build Coastguard Worker // would've been called. If we acquire that mutex here, and hold it while
581*84e33947SAndroid Build Coastguard Worker // purging any messages sent by the nanoapp in the queue, we can be certain
582*84e33947SAndroid Build Coastguard Worker // that onMessageToHostComplete will not be called after this function returns
583*84e33947SAndroid Build Coastguard Worker // for messages sent by that nanoapp
584*84e33947SAndroid Build Coastguard Worker flushOutboundQueue();
585*84e33947SAndroid Build Coastguard Worker
586*84e33947SAndroid Build Coastguard Worker // One extra sleep to try to ensure that any messages popped just before
587*84e33947SAndroid Build Coastguard Worker // checking empty() are fully processed before we return
588*84e33947SAndroid Build Coastguard Worker constexpr time_timetick_type kFinalDelayUsec = 10000;
589*84e33947SAndroid Build Coastguard Worker timer_sleep(kFinalDelayUsec, T_USEC, true /* non_deferrable */);
590*84e33947SAndroid Build Coastguard Worker }
591*84e33947SAndroid Build Coastguard Worker
sendMessage(const MessageToHost * message)592*84e33947SAndroid Build Coastguard Worker bool HostLink::sendMessage(const MessageToHost *message) {
593*84e33947SAndroid Build Coastguard Worker return enqueueMessage(
594*84e33947SAndroid Build Coastguard Worker PendingMessage(PendingMessageType::NanoappMessageToHost, message));
595*84e33947SAndroid Build Coastguard Worker }
596*84e33947SAndroid Build Coastguard Worker
sendMessageDeliveryStatus(uint32_t,uint8_t)597*84e33947SAndroid Build Coastguard Worker bool HostLink::sendMessageDeliveryStatus(uint32_t /* messageSequenceNumber */,
598*84e33947SAndroid Build Coastguard Worker uint8_t /* errorCode */) {
599*84e33947SAndroid Build Coastguard Worker return false;
600*84e33947SAndroid Build Coastguard Worker }
601*84e33947SAndroid Build Coastguard Worker
sendMetricLog(uint32_t metricId,const uint8_t * encodedMetric,size_t encodedMetricLen)602*84e33947SAndroid Build Coastguard Worker bool HostLink::sendMetricLog(uint32_t metricId, const uint8_t *encodedMetric,
603*84e33947SAndroid Build Coastguard Worker size_t encodedMetricLen) {
604*84e33947SAndroid Build Coastguard Worker struct MetricLogData {
605*84e33947SAndroid Build Coastguard Worker uint32_t metricId;
606*84e33947SAndroid Build Coastguard Worker const uint8_t *encodedMetric;
607*84e33947SAndroid Build Coastguard Worker size_t encodedMetricLen;
608*84e33947SAndroid Build Coastguard Worker };
609*84e33947SAndroid Build Coastguard Worker
610*84e33947SAndroid Build Coastguard Worker MetricLogData data;
611*84e33947SAndroid Build Coastguard Worker data.metricId = metricId;
612*84e33947SAndroid Build Coastguard Worker data.encodedMetric = encodedMetric;
613*84e33947SAndroid Build Coastguard Worker data.encodedMetricLen = encodedMetricLen;
614*84e33947SAndroid Build Coastguard Worker
615*84e33947SAndroid Build Coastguard Worker auto msgBuilder = [](ChreFlatBufferBuilder &builder, void *cookie) {
616*84e33947SAndroid Build Coastguard Worker const auto *data = static_cast<const MetricLogData *>(cookie);
617*84e33947SAndroid Build Coastguard Worker HostProtocolChre::encodeMetricLog(
618*84e33947SAndroid Build Coastguard Worker builder, data->metricId, data->encodedMetric, data->encodedMetricLen);
619*84e33947SAndroid Build Coastguard Worker };
620*84e33947SAndroid Build Coastguard Worker
621*84e33947SAndroid Build Coastguard Worker constexpr size_t kInitialSize = 52;
622*84e33947SAndroid Build Coastguard Worker buildAndEnqueueMessage(PendingMessageType::MetricLog, kInitialSize,
623*84e33947SAndroid Build Coastguard Worker msgBuilder, &data);
624*84e33947SAndroid Build Coastguard Worker return true;
625*84e33947SAndroid Build Coastguard Worker }
626*84e33947SAndroid Build Coastguard Worker
flushOutboundQueue()627*84e33947SAndroid Build Coastguard Worker bool HostLinkBase::flushOutboundQueue() {
628*84e33947SAndroid Build Coastguard Worker int waitCount = 5;
629*84e33947SAndroid Build Coastguard Worker
630*84e33947SAndroid Build Coastguard Worker FARF(MEDIUM, "Draining message queue");
631*84e33947SAndroid Build Coastguard Worker while (!gOutboundQueue.empty() && waitCount-- > 0) {
632*84e33947SAndroid Build Coastguard Worker timer_sleep(kPollingIntervalUsec, T_USEC, true /* non_deferrable */);
633*84e33947SAndroid Build Coastguard Worker }
634*84e33947SAndroid Build Coastguard Worker
635*84e33947SAndroid Build Coastguard Worker return (waitCount >= 0);
636*84e33947SAndroid Build Coastguard Worker }
637*84e33947SAndroid Build Coastguard Worker
sendLogMessage(const uint8_t * logMessage,size_t logMessageSize)638*84e33947SAndroid Build Coastguard Worker void HostLinkBase::sendLogMessage(const uint8_t *logMessage,
639*84e33947SAndroid Build Coastguard Worker size_t logMessageSize) {
640*84e33947SAndroid Build Coastguard Worker struct LogMessageData {
641*84e33947SAndroid Build Coastguard Worker const uint8_t *logMsg;
642*84e33947SAndroid Build Coastguard Worker size_t logMsgSize;
643*84e33947SAndroid Build Coastguard Worker };
644*84e33947SAndroid Build Coastguard Worker
645*84e33947SAndroid Build Coastguard Worker LogMessageData logMessageData;
646*84e33947SAndroid Build Coastguard Worker
647*84e33947SAndroid Build Coastguard Worker logMessageData.logMsg = logMessage;
648*84e33947SAndroid Build Coastguard Worker logMessageData.logMsgSize = logMessageSize;
649*84e33947SAndroid Build Coastguard Worker
650*84e33947SAndroid Build Coastguard Worker auto msgBuilder = [](ChreFlatBufferBuilder &builder, void *cookie) {
651*84e33947SAndroid Build Coastguard Worker const auto *data = static_cast<const LogMessageData *>(cookie);
652*84e33947SAndroid Build Coastguard Worker HostProtocolChre::encodeLogMessages(builder, data->logMsg,
653*84e33947SAndroid Build Coastguard Worker data->logMsgSize);
654*84e33947SAndroid Build Coastguard Worker };
655*84e33947SAndroid Build Coastguard Worker
656*84e33947SAndroid Build Coastguard Worker constexpr size_t kInitialSize = 128;
657*84e33947SAndroid Build Coastguard Worker buildAndEnqueueMessage(PendingMessageType::EncodedLogMessage, kInitialSize,
658*84e33947SAndroid Build Coastguard Worker msgBuilder, &logMessageData);
659*84e33947SAndroid Build Coastguard Worker }
660*84e33947SAndroid Build Coastguard Worker
sendLogMessageV2(const uint8_t * logMessage,size_t logMessageSize,uint32_t numLogsDropped)661*84e33947SAndroid Build Coastguard Worker void HostLinkBase::sendLogMessageV2(const uint8_t *logMessage,
662*84e33947SAndroid Build Coastguard Worker size_t logMessageSize,
663*84e33947SAndroid Build Coastguard Worker uint32_t numLogsDropped) {
664*84e33947SAndroid Build Coastguard Worker struct LogMessageData {
665*84e33947SAndroid Build Coastguard Worker const uint8_t *logMsg;
666*84e33947SAndroid Build Coastguard Worker size_t logMsgSize;
667*84e33947SAndroid Build Coastguard Worker uint32_t numLogsDropped;
668*84e33947SAndroid Build Coastguard Worker };
669*84e33947SAndroid Build Coastguard Worker
670*84e33947SAndroid Build Coastguard Worker LogMessageData logMessageData{logMessage, logMessageSize, numLogsDropped};
671*84e33947SAndroid Build Coastguard Worker
672*84e33947SAndroid Build Coastguard Worker auto msgBuilder = [](ChreFlatBufferBuilder &builder, void *cookie) {
673*84e33947SAndroid Build Coastguard Worker const auto *data = static_cast<const LogMessageData *>(cookie);
674*84e33947SAndroid Build Coastguard Worker HostProtocolChre::encodeLogMessagesV2(
675*84e33947SAndroid Build Coastguard Worker builder, data->logMsg, data->logMsgSize, data->numLogsDropped);
676*84e33947SAndroid Build Coastguard Worker };
677*84e33947SAndroid Build Coastguard Worker
678*84e33947SAndroid Build Coastguard Worker constexpr size_t kInitialSize = 128;
679*84e33947SAndroid Build Coastguard Worker buildAndEnqueueMessage(PendingMessageType::EncodedLogMessage, kInitialSize,
680*84e33947SAndroid Build Coastguard Worker msgBuilder, &logMessageData);
681*84e33947SAndroid Build Coastguard Worker }
682*84e33947SAndroid Build Coastguard Worker
sendNanConfiguration(bool enable)683*84e33947SAndroid Build Coastguard Worker void HostLinkBase::sendNanConfiguration(bool enable) {
684*84e33947SAndroid Build Coastguard Worker auto msgBuilder = [](ChreFlatBufferBuilder &builder, void *cookie) {
685*84e33947SAndroid Build Coastguard Worker const auto *data = static_cast<const bool *>(cookie);
686*84e33947SAndroid Build Coastguard Worker HostProtocolChre::encodeNanConfigurationRequest(builder, *data);
687*84e33947SAndroid Build Coastguard Worker };
688*84e33947SAndroid Build Coastguard Worker
689*84e33947SAndroid Build Coastguard Worker constexpr size_t kInitialSize = 48;
690*84e33947SAndroid Build Coastguard Worker buildAndEnqueueMessage(PendingMessageType::NanConfigurationRequest,
691*84e33947SAndroid Build Coastguard Worker kInitialSize, msgBuilder, &enable);
692*84e33947SAndroid Build Coastguard Worker }
693*84e33947SAndroid Build Coastguard Worker
shutdown()694*84e33947SAndroid Build Coastguard Worker void HostLinkBase::shutdown() {
695*84e33947SAndroid Build Coastguard Worker // Push a null message so the blocking call in chre_slpi_get_message_to_host()
696*84e33947SAndroid Build Coastguard Worker // returns and the host can exit cleanly. If the queue is full, try again to
697*84e33947SAndroid Build Coastguard Worker // avoid getting stuck (no other new messages should be entering the queue at
698*84e33947SAndroid Build Coastguard Worker // this time). Don't wait too long as the host-side binary may have died in
699*84e33947SAndroid Build Coastguard Worker // a state where it's not blocked in chre_slpi_get_message_to_host().
700*84e33947SAndroid Build Coastguard Worker int retryCount = 5;
701*84e33947SAndroid Build Coastguard Worker FARF(MEDIUM, "Shutting down host link");
702*84e33947SAndroid Build Coastguard Worker while (!enqueueMessage(PendingMessage(PendingMessageType::Shutdown)) &&
703*84e33947SAndroid Build Coastguard Worker --retryCount > 0) {
704*84e33947SAndroid Build Coastguard Worker timer_sleep(kPollingIntervalUsec, T_USEC, true /* non_deferrable */);
705*84e33947SAndroid Build Coastguard Worker }
706*84e33947SAndroid Build Coastguard Worker
707*84e33947SAndroid Build Coastguard Worker if (retryCount <= 0) {
708*84e33947SAndroid Build Coastguard Worker // Don't use LOGE, as it may involve trying to send a message
709*84e33947SAndroid Build Coastguard Worker FARF(ERROR,
710*84e33947SAndroid Build Coastguard Worker "No room in outbound queue for shutdown message and host not "
711*84e33947SAndroid Build Coastguard Worker "draining queue!");
712*84e33947SAndroid Build Coastguard Worker } else {
713*84e33947SAndroid Build Coastguard Worker // We were able to push the shutdown message. Wait for the queue to
714*84e33947SAndroid Build Coastguard Worker // completely flush before returning.
715*84e33947SAndroid Build Coastguard Worker if (!flushOutboundQueue()) {
716*84e33947SAndroid Build Coastguard Worker FARF(ERROR, "Host took too long to drain outbound queue; exiting anyway");
717*84e33947SAndroid Build Coastguard Worker } else {
718*84e33947SAndroid Build Coastguard Worker FARF(MEDIUM, "Finished draining queue");
719*84e33947SAndroid Build Coastguard Worker }
720*84e33947SAndroid Build Coastguard Worker }
721*84e33947SAndroid Build Coastguard Worker }
722*84e33947SAndroid Build Coastguard Worker
sendAudioRequest()723*84e33947SAndroid Build Coastguard Worker void sendAudioRequest() {
724*84e33947SAndroid Build Coastguard Worker auto msgBuilder = [](ChreFlatBufferBuilder &builder, void *cookie) {
725*84e33947SAndroid Build Coastguard Worker HostProtocolChre::encodeLowPowerMicAccessRequest(builder);
726*84e33947SAndroid Build Coastguard Worker };
727*84e33947SAndroid Build Coastguard Worker
728*84e33947SAndroid Build Coastguard Worker constexpr size_t kInitialSize = 32;
729*84e33947SAndroid Build Coastguard Worker buildAndEnqueueMessage(PendingMessageType::LowPowerMicAccessRequest,
730*84e33947SAndroid Build Coastguard Worker kInitialSize, msgBuilder, nullptr);
731*84e33947SAndroid Build Coastguard Worker }
732*84e33947SAndroid Build Coastguard Worker
sendAudioRelease()733*84e33947SAndroid Build Coastguard Worker void sendAudioRelease() {
734*84e33947SAndroid Build Coastguard Worker auto msgBuilder = [](ChreFlatBufferBuilder &builder, void *cookie) {
735*84e33947SAndroid Build Coastguard Worker HostProtocolChre::encodeLowPowerMicAccessRelease(builder);
736*84e33947SAndroid Build Coastguard Worker };
737*84e33947SAndroid Build Coastguard Worker
738*84e33947SAndroid Build Coastguard Worker constexpr size_t kInitialSize = 32;
739*84e33947SAndroid Build Coastguard Worker buildAndEnqueueMessage(PendingMessageType::LowPowerMicAccessRelease,
740*84e33947SAndroid Build Coastguard Worker kInitialSize, msgBuilder, nullptr);
741*84e33947SAndroid Build Coastguard Worker }
742*84e33947SAndroid Build Coastguard Worker
sendFragmentResponse(uint16_t hostClientId,uint32_t transactionId,uint32_t fragmentId,bool success)743*84e33947SAndroid Build Coastguard Worker void HostMessageHandlers::sendFragmentResponse(uint16_t hostClientId,
744*84e33947SAndroid Build Coastguard Worker uint32_t transactionId,
745*84e33947SAndroid Build Coastguard Worker uint32_t fragmentId,
746*84e33947SAndroid Build Coastguard Worker bool success) {
747*84e33947SAndroid Build Coastguard Worker struct FragmentedLoadInfoResponse {
748*84e33947SAndroid Build Coastguard Worker uint16_t hostClientId;
749*84e33947SAndroid Build Coastguard Worker uint32_t transactionId;
750*84e33947SAndroid Build Coastguard Worker uint32_t fragmentId;
751*84e33947SAndroid Build Coastguard Worker bool success;
752*84e33947SAndroid Build Coastguard Worker };
753*84e33947SAndroid Build Coastguard Worker
754*84e33947SAndroid Build Coastguard Worker auto msgBuilder = [](ChreFlatBufferBuilder &builder, void *cookie) {
755*84e33947SAndroid Build Coastguard Worker auto *cbData = static_cast<FragmentedLoadInfoResponse *>(cookie);
756*84e33947SAndroid Build Coastguard Worker HostProtocolChre::encodeLoadNanoappResponse(
757*84e33947SAndroid Build Coastguard Worker builder, cbData->hostClientId, cbData->transactionId, cbData->success,
758*84e33947SAndroid Build Coastguard Worker cbData->fragmentId);
759*84e33947SAndroid Build Coastguard Worker };
760*84e33947SAndroid Build Coastguard Worker
761*84e33947SAndroid Build Coastguard Worker FragmentedLoadInfoResponse response = {
762*84e33947SAndroid Build Coastguard Worker .hostClientId = hostClientId,
763*84e33947SAndroid Build Coastguard Worker .transactionId = transactionId,
764*84e33947SAndroid Build Coastguard Worker .fragmentId = fragmentId,
765*84e33947SAndroid Build Coastguard Worker .success = success,
766*84e33947SAndroid Build Coastguard Worker };
767*84e33947SAndroid Build Coastguard Worker constexpr size_t kInitialBufferSize = 48;
768*84e33947SAndroid Build Coastguard Worker buildAndEnqueueMessage(PendingMessageType::LoadNanoappResponse,
769*84e33947SAndroid Build Coastguard Worker kInitialBufferSize, msgBuilder, &response);
770*84e33947SAndroid Build Coastguard Worker }
771*84e33947SAndroid Build Coastguard Worker
handleNanoappMessage(uint64_t appId,uint32_t messageType,uint16_t hostEndpoint,const void * messageData,size_t messageDataLen,bool isReliable,uint32_t messageSequenceNumber)772*84e33947SAndroid Build Coastguard Worker void HostMessageHandlers::handleNanoappMessage(
773*84e33947SAndroid Build Coastguard Worker uint64_t appId, uint32_t messageType, uint16_t hostEndpoint,
774*84e33947SAndroid Build Coastguard Worker const void *messageData, size_t messageDataLen, bool isReliable,
775*84e33947SAndroid Build Coastguard Worker uint32_t messageSequenceNumber) {
776*84e33947SAndroid Build Coastguard Worker LOGD("Parsed nanoapp message from host: app ID 0x%016" PRIx64
777*84e33947SAndroid Build Coastguard Worker ", endpoint "
778*84e33947SAndroid Build Coastguard Worker "0x%" PRIx16 ", msgType %" PRIu32 ", payload size %zu",
779*84e33947SAndroid Build Coastguard Worker appId, hostEndpoint, messageType, messageDataLen);
780*84e33947SAndroid Build Coastguard Worker
781*84e33947SAndroid Build Coastguard Worker HostCommsManager &manager =
782*84e33947SAndroid Build Coastguard Worker EventLoopManagerSingleton::get()->getHostCommsManager();
783*84e33947SAndroid Build Coastguard Worker manager.sendMessageToNanoappFromHost(appId, messageType, hostEndpoint,
784*84e33947SAndroid Build Coastguard Worker messageData, messageDataLen, isReliable,
785*84e33947SAndroid Build Coastguard Worker messageSequenceNumber);
786*84e33947SAndroid Build Coastguard Worker }
787*84e33947SAndroid Build Coastguard Worker
handleMessageDeliveryStatus(uint32_t,uint8_t)788*84e33947SAndroid Build Coastguard Worker void HostMessageHandlers::handleMessageDeliveryStatus(
789*84e33947SAndroid Build Coastguard Worker uint32_t /* messageSequenceNumber */, uint8_t /* errorCode */) {}
790*84e33947SAndroid Build Coastguard Worker
handleHubInfoRequest(uint16_t hostClientId)791*84e33947SAndroid Build Coastguard Worker void HostMessageHandlers::handleHubInfoRequest(uint16_t hostClientId) {
792*84e33947SAndroid Build Coastguard Worker // We generate the response in the context of chre_slpi_get_message_to_host
793*84e33947SAndroid Build Coastguard Worker LOGD("Hub info request from client ID %" PRIu16, hostClientId);
794*84e33947SAndroid Build Coastguard Worker enqueueMessage(
795*84e33947SAndroid Build Coastguard Worker PendingMessage(PendingMessageType::HubInfoResponse, hostClientId));
796*84e33947SAndroid Build Coastguard Worker }
797*84e33947SAndroid Build Coastguard Worker
handleNanoappListRequest(uint16_t hostClientId)798*84e33947SAndroid Build Coastguard Worker void HostMessageHandlers::handleNanoappListRequest(uint16_t hostClientId) {
799*84e33947SAndroid Build Coastguard Worker auto callback = [](uint16_t /*type*/, void *data, void * /*extraData*/) {
800*84e33947SAndroid Build Coastguard Worker uint16_t cbHostClientId = NestedDataPtr<uint16_t>(data);
801*84e33947SAndroid Build Coastguard Worker
802*84e33947SAndroid Build Coastguard Worker NanoappListData cbData = {};
803*84e33947SAndroid Build Coastguard Worker cbData.hostClientId = cbHostClientId;
804*84e33947SAndroid Build Coastguard Worker
805*84e33947SAndroid Build Coastguard Worker size_t expectedNanoappCount =
806*84e33947SAndroid Build Coastguard Worker EventLoopManagerSingleton::get()->getEventLoop().getNanoappCount();
807*84e33947SAndroid Build Coastguard Worker if (!cbData.nanoappEntries.reserve(expectedNanoappCount)) {
808*84e33947SAndroid Build Coastguard Worker LOG_OOM();
809*84e33947SAndroid Build Coastguard Worker } else {
810*84e33947SAndroid Build Coastguard Worker constexpr size_t kFixedOverhead = 48;
811*84e33947SAndroid Build Coastguard Worker constexpr size_t kPerNanoappSize = 32;
812*84e33947SAndroid Build Coastguard Worker size_t initialBufferSize =
813*84e33947SAndroid Build Coastguard Worker (kFixedOverhead + expectedNanoappCount * kPerNanoappSize);
814*84e33947SAndroid Build Coastguard Worker
815*84e33947SAndroid Build Coastguard Worker buildAndEnqueueMessage(PendingMessageType::NanoappListResponse,
816*84e33947SAndroid Build Coastguard Worker initialBufferSize, buildNanoappListResponse,
817*84e33947SAndroid Build Coastguard Worker &cbData);
818*84e33947SAndroid Build Coastguard Worker }
819*84e33947SAndroid Build Coastguard Worker };
820*84e33947SAndroid Build Coastguard Worker
821*84e33947SAndroid Build Coastguard Worker LOGD("Nanoapp list request from client ID %" PRIu16, hostClientId);
822*84e33947SAndroid Build Coastguard Worker EventLoopManagerSingleton::get()->deferCallback(
823*84e33947SAndroid Build Coastguard Worker SystemCallbackType::NanoappListResponse,
824*84e33947SAndroid Build Coastguard Worker NestedDataPtr<uint16_t>(hostClientId), callback);
825*84e33947SAndroid Build Coastguard Worker }
826*84e33947SAndroid Build Coastguard Worker
handleLoadNanoappRequest(uint16_t hostClientId,uint32_t transactionId,uint64_t appId,uint32_t appVersion,uint32_t appFlags,uint32_t targetApiVersion,const void * buffer,size_t bufferLen,const char * appFileName,uint32_t fragmentId,size_t appBinaryLen,bool respondBeforeStart)827*84e33947SAndroid Build Coastguard Worker void HostMessageHandlers::handleLoadNanoappRequest(
828*84e33947SAndroid Build Coastguard Worker uint16_t hostClientId, uint32_t transactionId, uint64_t appId,
829*84e33947SAndroid Build Coastguard Worker uint32_t appVersion, uint32_t appFlags, uint32_t targetApiVersion,
830*84e33947SAndroid Build Coastguard Worker const void *buffer, size_t bufferLen, const char *appFileName,
831*84e33947SAndroid Build Coastguard Worker uint32_t fragmentId, size_t appBinaryLen, bool respondBeforeStart) {
832*84e33947SAndroid Build Coastguard Worker if (appFileName == nullptr) {
833*84e33947SAndroid Build Coastguard Worker loadNanoappData(hostClientId, transactionId, appId, appVersion, appFlags,
834*84e33947SAndroid Build Coastguard Worker targetApiVersion, buffer, bufferLen, fragmentId,
835*84e33947SAndroid Build Coastguard Worker appBinaryLen, respondBeforeStart);
836*84e33947SAndroid Build Coastguard Worker return;
837*84e33947SAndroid Build Coastguard Worker }
838*84e33947SAndroid Build Coastguard Worker
839*84e33947SAndroid Build Coastguard Worker UniquePtr<Nanoapp> pendingNanoapp =
840*84e33947SAndroid Build Coastguard Worker handleLoadNanoappFile(hostClientId, transactionId, appId, appVersion,
841*84e33947SAndroid Build Coastguard Worker targetApiVersion, appFileName);
842*84e33947SAndroid Build Coastguard Worker
843*84e33947SAndroid Build Coastguard Worker if (!pendingNanoapp.isNull()) {
844*84e33947SAndroid Build Coastguard Worker auto cbData = MakeUnique<LoadNanoappCallbackData>();
845*84e33947SAndroid Build Coastguard Worker if (cbData.isNull()) {
846*84e33947SAndroid Build Coastguard Worker LOG_OOM();
847*84e33947SAndroid Build Coastguard Worker } else {
848*84e33947SAndroid Build Coastguard Worker cbData->transactionId = transactionId;
849*84e33947SAndroid Build Coastguard Worker cbData->hostClientId = hostClientId;
850*84e33947SAndroid Build Coastguard Worker cbData->appId = appId;
851*84e33947SAndroid Build Coastguard Worker cbData->fragmentId = fragmentId;
852*84e33947SAndroid Build Coastguard Worker cbData->nanoapp = std::move(pendingNanoapp);
853*84e33947SAndroid Build Coastguard Worker
854*84e33947SAndroid Build Coastguard Worker // Note that if this fails, we'll generate the error response in
855*84e33947SAndroid Build Coastguard Worker // the normal deferred callback
856*84e33947SAndroid Build Coastguard Worker EventLoopManagerSingleton::get()->deferCallback(
857*84e33947SAndroid Build Coastguard Worker SystemCallbackType::FinishLoadingNanoapp, std::move(cbData),
858*84e33947SAndroid Build Coastguard Worker finishLoadingNanoappCallback);
859*84e33947SAndroid Build Coastguard Worker }
860*84e33947SAndroid Build Coastguard Worker }
861*84e33947SAndroid Build Coastguard Worker }
862*84e33947SAndroid Build Coastguard Worker
handleUnloadNanoappRequest(uint16_t hostClientId,uint32_t transactionId,uint64_t appId,bool allowSystemNanoappUnload)863*84e33947SAndroid Build Coastguard Worker void HostMessageHandlers::handleUnloadNanoappRequest(
864*84e33947SAndroid Build Coastguard Worker uint16_t hostClientId, uint32_t transactionId, uint64_t appId,
865*84e33947SAndroid Build Coastguard Worker bool allowSystemNanoappUnload) {
866*84e33947SAndroid Build Coastguard Worker LOGD("Unload nanoapp request (txnID %" PRIu32 ") for appId 0x%016" PRIx64
867*84e33947SAndroid Build Coastguard Worker " system %d",
868*84e33947SAndroid Build Coastguard Worker transactionId, appId, allowSystemNanoappUnload);
869*84e33947SAndroid Build Coastguard Worker auto cbData = MakeUnique<UnloadNanoappCallbackData>();
870*84e33947SAndroid Build Coastguard Worker if (cbData == nullptr) {
871*84e33947SAndroid Build Coastguard Worker LOG_OOM();
872*84e33947SAndroid Build Coastguard Worker } else {
873*84e33947SAndroid Build Coastguard Worker cbData->appId = appId;
874*84e33947SAndroid Build Coastguard Worker cbData->transactionId = transactionId;
875*84e33947SAndroid Build Coastguard Worker cbData->hostClientId = hostClientId;
876*84e33947SAndroid Build Coastguard Worker cbData->allowSystemNanoappUnload = allowSystemNanoappUnload;
877*84e33947SAndroid Build Coastguard Worker
878*84e33947SAndroid Build Coastguard Worker EventLoopManagerSingleton::get()->deferCallback(
879*84e33947SAndroid Build Coastguard Worker SystemCallbackType::HandleUnloadNanoapp, std::move(cbData),
880*84e33947SAndroid Build Coastguard Worker handleUnloadNanoappCallback);
881*84e33947SAndroid Build Coastguard Worker }
882*84e33947SAndroid Build Coastguard Worker }
883*84e33947SAndroid Build Coastguard Worker
handleTimeSyncMessage(int64_t offset)884*84e33947SAndroid Build Coastguard Worker void HostMessageHandlers::handleTimeSyncMessage(int64_t offset) {
885*84e33947SAndroid Build Coastguard Worker SystemTime::setEstimatedHostTimeOffset(offset);
886*84e33947SAndroid Build Coastguard Worker
887*84e33947SAndroid Build Coastguard Worker // Schedule a time sync request since offset may drift
888*84e33947SAndroid Build Coastguard Worker constexpr Seconds kClockDriftTimeSyncPeriod =
889*84e33947SAndroid Build Coastguard Worker Seconds(60 * 60 * 6); // 6 hours
890*84e33947SAndroid Build Coastguard Worker setTimeSyncRequestTimer(kClockDriftTimeSyncPeriod);
891*84e33947SAndroid Build Coastguard Worker }
892*84e33947SAndroid Build Coastguard Worker
handleDebugDumpRequest(uint16_t hostClientId)893*84e33947SAndroid Build Coastguard Worker void HostMessageHandlers::handleDebugDumpRequest(uint16_t hostClientId) {
894*84e33947SAndroid Build Coastguard Worker if (!chre::EventLoopManagerSingleton::get()
895*84e33947SAndroid Build Coastguard Worker ->getDebugDumpManager()
896*84e33947SAndroid Build Coastguard Worker .onDebugDumpRequested(hostClientId)) {
897*84e33947SAndroid Build Coastguard Worker LOGE("Couldn't trigger debug dump process");
898*84e33947SAndroid Build Coastguard Worker sendDebugDumpResponse(hostClientId, false /*success*/, 0 /*dataCount*/);
899*84e33947SAndroid Build Coastguard Worker }
900*84e33947SAndroid Build Coastguard Worker }
901*84e33947SAndroid Build Coastguard Worker
handleSettingChangeMessage(fbs::Setting setting,fbs::SettingState state)902*84e33947SAndroid Build Coastguard Worker void HostMessageHandlers::handleSettingChangeMessage(fbs::Setting setting,
903*84e33947SAndroid Build Coastguard Worker fbs::SettingState state) {
904*84e33947SAndroid Build Coastguard Worker Setting chreSetting;
905*84e33947SAndroid Build Coastguard Worker bool chreSettingEnabled;
906*84e33947SAndroid Build Coastguard Worker if (HostProtocolChre::getSettingFromFbs(setting, &chreSetting) &&
907*84e33947SAndroid Build Coastguard Worker HostProtocolChre::getSettingEnabledFromFbs(state, &chreSettingEnabled)) {
908*84e33947SAndroid Build Coastguard Worker EventLoopManagerSingleton::get()->getSettingManager().postSettingChange(
909*84e33947SAndroid Build Coastguard Worker chreSetting, chreSettingEnabled);
910*84e33947SAndroid Build Coastguard Worker }
911*84e33947SAndroid Build Coastguard Worker }
912*84e33947SAndroid Build Coastguard Worker
handleSelfTestRequest(uint16_t hostClientId)913*84e33947SAndroid Build Coastguard Worker void HostMessageHandlers::handleSelfTestRequest(uint16_t hostClientId) {
914*84e33947SAndroid Build Coastguard Worker // TODO(b/182201569): Run test
915*84e33947SAndroid Build Coastguard Worker bool success = true;
916*84e33947SAndroid Build Coastguard Worker sendSelfTestResponse(hostClientId, success);
917*84e33947SAndroid Build Coastguard Worker }
918*84e33947SAndroid Build Coastguard Worker
handlePulseRequest()919*84e33947SAndroid Build Coastguard Worker void HostMessageHandlers::handlePulseRequest() {}
920*84e33947SAndroid Build Coastguard Worker
handleNanConfigurationUpdate(bool enabled)921*84e33947SAndroid Build Coastguard Worker void HostMessageHandlers::handleNanConfigurationUpdate(bool enabled) {
922*84e33947SAndroid Build Coastguard Worker #ifdef CHRE_WIFI_NAN_SUPPORT_ENABLED
923*84e33947SAndroid Build Coastguard Worker EventLoopManagerSingleton::get()
924*84e33947SAndroid Build Coastguard Worker ->getWifiRequestManager()
925*84e33947SAndroid Build Coastguard Worker .updateNanAvailability(enabled);
926*84e33947SAndroid Build Coastguard Worker #else
927*84e33947SAndroid Build Coastguard Worker UNUSED_VAR(enabled);
928*84e33947SAndroid Build Coastguard Worker #endif // CHRE_WIFI_NAN_SUPPORT_ENABLED
929*84e33947SAndroid Build Coastguard Worker }
930*84e33947SAndroid Build Coastguard Worker
handleBtSocketOpen(uint16_t,uint64_t,const char *,uint64_t,uint64_t,uint32_t,uint32_t,uint32_t,uint32_t,uint32_t,uint32_t,uint32_t,uint32_t,uint32_t,uint32_t)931*84e33947SAndroid Build Coastguard Worker void HostMessageHandlers::handleBtSocketOpen(
932*84e33947SAndroid Build Coastguard Worker uint16_t /* hostClientId */, uint64_t /* socketId */,
933*84e33947SAndroid Build Coastguard Worker const char * /* name */, uint64_t /* endpointId */, uint64_t /* hubId */,
934*84e33947SAndroid Build Coastguard Worker uint32_t /* aclConnectionHandle */, uint32_t /* localCid */,
935*84e33947SAndroid Build Coastguard Worker uint32_t /* remoteCid */, uint32_t /* psm */, uint32_t /* localMtu */,
936*84e33947SAndroid Build Coastguard Worker uint32_t /* remoteMtu */, uint32_t /* localMps */, uint32_t /* remoteMps */,
937*84e33947SAndroid Build Coastguard Worker uint32_t /* initialRxCredits */, uint32_t /* initialTxCredits */) {
938*84e33947SAndroid Build Coastguard Worker LOGE("BT Socket offload not supported");
939*84e33947SAndroid Build Coastguard Worker }
940*84e33947SAndroid Build Coastguard Worker
941*84e33947SAndroid Build Coastguard Worker } // namespace chre
942