1*84e33947SAndroid Build Coastguard Worker /*
2*84e33947SAndroid Build Coastguard Worker * Copyright (C) 2020 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 #include <cstdlib>
18*84e33947SAndroid Build Coastguard Worker #include <fstream>
19*84e33947SAndroid Build Coastguard Worker
20*84e33947SAndroid Build Coastguard Worker #include "chre_host/fbs_daemon_base.h"
21*84e33947SAndroid Build Coastguard Worker #include "chre_host/log.h"
22*84e33947SAndroid Build Coastguard Worker #include "chre_host/napp_header.h"
23*84e33947SAndroid Build Coastguard Worker
24*84e33947SAndroid Build Coastguard Worker #include <json/json.h>
25*84e33947SAndroid Build Coastguard Worker
26*84e33947SAndroid Build Coastguard Worker #ifdef CHRE_DAEMON_METRIC_ENABLED
27*84e33947SAndroid Build Coastguard Worker #include <aidl/android/frameworks/stats/IStats.h>
28*84e33947SAndroid Build Coastguard Worker #include <android/binder_manager.h>
29*84e33947SAndroid Build Coastguard Worker #include <android_chre_flags.h>
30*84e33947SAndroid Build Coastguard Worker #include <chre_atoms_log.h>
31*84e33947SAndroid Build Coastguard Worker #endif // CHRE_DAEMON_METRIC_ENABLED
32*84e33947SAndroid Build Coastguard Worker
33*84e33947SAndroid Build Coastguard Worker // Aliased for consistency with the way these symbols are referenced in
34*84e33947SAndroid Build Coastguard Worker // CHRE-side code
35*84e33947SAndroid Build Coastguard Worker namespace fbs = ::chre::fbs;
36*84e33947SAndroid Build Coastguard Worker
37*84e33947SAndroid Build Coastguard Worker namespace android {
38*84e33947SAndroid Build Coastguard Worker namespace chre {
39*84e33947SAndroid Build Coastguard Worker
40*84e33947SAndroid Build Coastguard Worker #ifdef CHRE_DAEMON_METRIC_ENABLED
41*84e33947SAndroid Build Coastguard Worker using ::aidl::android::frameworks::stats::IStats;
42*84e33947SAndroid Build Coastguard Worker using ::aidl::android::frameworks::stats::VendorAtom;
43*84e33947SAndroid Build Coastguard Worker using ::aidl::android::frameworks::stats::VendorAtomValue;
44*84e33947SAndroid Build Coastguard Worker using ::android::chre::Atoms::ChreHalNanoappLoadFailed;
45*84e33947SAndroid Build Coastguard Worker #endif // CHRE_DAEMON_METRIC_ENABLED
46*84e33947SAndroid Build Coastguard Worker
sendNanoappLoad(uint64_t appId,uint32_t appVersion,uint32_t appTargetApiVersion,const std::string & appBinaryName,uint32_t transactionId)47*84e33947SAndroid Build Coastguard Worker bool FbsDaemonBase::sendNanoappLoad(uint64_t appId, uint32_t appVersion,
48*84e33947SAndroid Build Coastguard Worker uint32_t appTargetApiVersion,
49*84e33947SAndroid Build Coastguard Worker const std::string &appBinaryName,
50*84e33947SAndroid Build Coastguard Worker uint32_t transactionId) {
51*84e33947SAndroid Build Coastguard Worker flatbuffers::FlatBufferBuilder builder;
52*84e33947SAndroid Build Coastguard Worker HostProtocolHost::encodeLoadNanoappRequestForFile(
53*84e33947SAndroid Build Coastguard Worker builder, transactionId, appId, appVersion, appTargetApiVersion,
54*84e33947SAndroid Build Coastguard Worker appBinaryName.c_str());
55*84e33947SAndroid Build Coastguard Worker
56*84e33947SAndroid Build Coastguard Worker bool success = sendMessageToChre(
57*84e33947SAndroid Build Coastguard Worker kHostClientIdDaemon, builder.GetBufferPointer(), builder.GetSize());
58*84e33947SAndroid Build Coastguard Worker
59*84e33947SAndroid Build Coastguard Worker if (!success) {
60*84e33947SAndroid Build Coastguard Worker LOGE("Failed to send nanoapp filename.");
61*84e33947SAndroid Build Coastguard Worker } else {
62*84e33947SAndroid Build Coastguard Worker Transaction transaction = {
63*84e33947SAndroid Build Coastguard Worker .transactionId = transactionId,
64*84e33947SAndroid Build Coastguard Worker .nanoappId = appId,
65*84e33947SAndroid Build Coastguard Worker };
66*84e33947SAndroid Build Coastguard Worker mPreloadedNanoappPendingTransactions.push(transaction);
67*84e33947SAndroid Build Coastguard Worker }
68*84e33947SAndroid Build Coastguard Worker
69*84e33947SAndroid Build Coastguard Worker return success;
70*84e33947SAndroid Build Coastguard Worker }
71*84e33947SAndroid Build Coastguard Worker
sendTimeSync(bool logOnError)72*84e33947SAndroid Build Coastguard Worker bool FbsDaemonBase::sendTimeSync(bool logOnError) {
73*84e33947SAndroid Build Coastguard Worker bool success = false;
74*84e33947SAndroid Build Coastguard Worker int64_t timeOffset = getTimeOffset(&success);
75*84e33947SAndroid Build Coastguard Worker
76*84e33947SAndroid Build Coastguard Worker if (success) {
77*84e33947SAndroid Build Coastguard Worker flatbuffers::FlatBufferBuilder builder(64);
78*84e33947SAndroid Build Coastguard Worker HostProtocolHost::encodeTimeSyncMessage(builder, timeOffset);
79*84e33947SAndroid Build Coastguard Worker success = sendMessageToChre(kHostClientIdDaemon, builder.GetBufferPointer(),
80*84e33947SAndroid Build Coastguard Worker builder.GetSize());
81*84e33947SAndroid Build Coastguard Worker
82*84e33947SAndroid Build Coastguard Worker if (!success && logOnError) {
83*84e33947SAndroid Build Coastguard Worker LOGE("Failed to deliver time sync message from host to CHRE");
84*84e33947SAndroid Build Coastguard Worker }
85*84e33947SAndroid Build Coastguard Worker }
86*84e33947SAndroid Build Coastguard Worker
87*84e33947SAndroid Build Coastguard Worker return success;
88*84e33947SAndroid Build Coastguard Worker }
89*84e33947SAndroid Build Coastguard Worker
sendMessageToChre(uint16_t clientId,void * data,size_t length)90*84e33947SAndroid Build Coastguard Worker bool FbsDaemonBase::sendMessageToChre(uint16_t clientId, void *data,
91*84e33947SAndroid Build Coastguard Worker size_t length) {
92*84e33947SAndroid Build Coastguard Worker bool success = false;
93*84e33947SAndroid Build Coastguard Worker if (!HostProtocolHost::mutateHostClientId(data, length, clientId)) {
94*84e33947SAndroid Build Coastguard Worker LOGE("Couldn't set host client ID in message container!");
95*84e33947SAndroid Build Coastguard Worker } else {
96*84e33947SAndroid Build Coastguard Worker LOGV("Delivering message from host (size %zu)", length);
97*84e33947SAndroid Build Coastguard Worker getLogger().dump(static_cast<const uint8_t *>(data), length);
98*84e33947SAndroid Build Coastguard Worker success = doSendMessage(data, length);
99*84e33947SAndroid Build Coastguard Worker }
100*84e33947SAndroid Build Coastguard Worker
101*84e33947SAndroid Build Coastguard Worker return success;
102*84e33947SAndroid Build Coastguard Worker }
103*84e33947SAndroid Build Coastguard Worker
onMessageReceived(const unsigned char * messageBuffer,size_t messageLen)104*84e33947SAndroid Build Coastguard Worker void FbsDaemonBase::onMessageReceived(const unsigned char *messageBuffer,
105*84e33947SAndroid Build Coastguard Worker size_t messageLen) {
106*84e33947SAndroid Build Coastguard Worker getLogger().dump(messageBuffer, messageLen);
107*84e33947SAndroid Build Coastguard Worker
108*84e33947SAndroid Build Coastguard Worker uint16_t hostClientId;
109*84e33947SAndroid Build Coastguard Worker fbs::ChreMessage messageType;
110*84e33947SAndroid Build Coastguard Worker if (!HostProtocolHost::extractHostClientIdAndType(
111*84e33947SAndroid Build Coastguard Worker messageBuffer, messageLen, &hostClientId, &messageType)) {
112*84e33947SAndroid Build Coastguard Worker LOGW("Failed to extract host client ID from message - sending broadcast");
113*84e33947SAndroid Build Coastguard Worker hostClientId = ::chre::kHostClientIdUnspecified;
114*84e33947SAndroid Build Coastguard Worker }
115*84e33947SAndroid Build Coastguard Worker
116*84e33947SAndroid Build Coastguard Worker std::unique_ptr<fbs::MessageContainerT> container =
117*84e33947SAndroid Build Coastguard Worker fbs::UnPackMessageContainer(messageBuffer);
118*84e33947SAndroid Build Coastguard Worker
119*84e33947SAndroid Build Coastguard Worker if (messageType == fbs::ChreMessage::LogMessage) {
120*84e33947SAndroid Build Coastguard Worker const auto *logMessage = container->message.AsLogMessage();
121*84e33947SAndroid Build Coastguard Worker const std::vector<int8_t> &logData = logMessage->buffer;
122*84e33947SAndroid Build Coastguard Worker
123*84e33947SAndroid Build Coastguard Worker getLogger().log(reinterpret_cast<const uint8_t *>(logData.data()),
124*84e33947SAndroid Build Coastguard Worker logData.size());
125*84e33947SAndroid Build Coastguard Worker } else if (messageType == fbs::ChreMessage::LogMessageV2) {
126*84e33947SAndroid Build Coastguard Worker const auto *logMessage = container->message.AsLogMessageV2();
127*84e33947SAndroid Build Coastguard Worker const std::vector<int8_t> &logDataBuffer = logMessage->buffer;
128*84e33947SAndroid Build Coastguard Worker const auto *logData =
129*84e33947SAndroid Build Coastguard Worker reinterpret_cast<const uint8_t *>(logDataBuffer.data());
130*84e33947SAndroid Build Coastguard Worker uint32_t numLogsDropped = logMessage->num_logs_dropped;
131*84e33947SAndroid Build Coastguard Worker getLogger().logV2(logData, logDataBuffer.size(), numLogsDropped);
132*84e33947SAndroid Build Coastguard Worker } else if (messageType == fbs::ChreMessage::TimeSyncRequest) {
133*84e33947SAndroid Build Coastguard Worker sendTimeSync(true /* logOnError */);
134*84e33947SAndroid Build Coastguard Worker } else if (messageType == fbs::ChreMessage::LowPowerMicAccessRequest) {
135*84e33947SAndroid Build Coastguard Worker configureLpma(true /* enabled */);
136*84e33947SAndroid Build Coastguard Worker } else if (messageType == fbs::ChreMessage::LowPowerMicAccessRelease) {
137*84e33947SAndroid Build Coastguard Worker configureLpma(false /* enabled */);
138*84e33947SAndroid Build Coastguard Worker } else if (messageType == fbs::ChreMessage::MetricLog) {
139*84e33947SAndroid Build Coastguard Worker #ifdef CHRE_DAEMON_METRIC_ENABLED
140*84e33947SAndroid Build Coastguard Worker const auto *metricMsg = container->message.AsMetricLog();
141*84e33947SAndroid Build Coastguard Worker handleMetricLog(metricMsg);
142*84e33947SAndroid Build Coastguard Worker #endif // CHRE_DAEMON_METRIC_ENABLED
143*84e33947SAndroid Build Coastguard Worker } else if (messageType == fbs::ChreMessage::NanConfigurationRequest) {
144*84e33947SAndroid Build Coastguard Worker handleNanConfigurationRequest(
145*84e33947SAndroid Build Coastguard Worker container->message.AsNanConfigurationRequest());
146*84e33947SAndroid Build Coastguard Worker } else if (messageType == fbs::ChreMessage::NanoappTokenDatabaseInfo) {
147*84e33947SAndroid Build Coastguard Worker // TODO(b/242760291): Use this info to map nanoapp log detokenizers with
148*84e33947SAndroid Build Coastguard Worker // instance ID in log message parser.
149*84e33947SAndroid Build Coastguard Worker } else if (hostClientId == kHostClientIdDaemon) {
150*84e33947SAndroid Build Coastguard Worker handleDaemonMessage(messageBuffer);
151*84e33947SAndroid Build Coastguard Worker } else if (hostClientId == ::chre::kHostClientIdUnspecified) {
152*84e33947SAndroid Build Coastguard Worker mServer.sendToAllClients(messageBuffer, static_cast<size_t>(messageLen));
153*84e33947SAndroid Build Coastguard Worker } else {
154*84e33947SAndroid Build Coastguard Worker mServer.sendToClientById(messageBuffer, static_cast<size_t>(messageLen),
155*84e33947SAndroid Build Coastguard Worker hostClientId);
156*84e33947SAndroid Build Coastguard Worker }
157*84e33947SAndroid Build Coastguard Worker }
158*84e33947SAndroid Build Coastguard Worker
handleDaemonMessage(const uint8_t * message)159*84e33947SAndroid Build Coastguard Worker void FbsDaemonBase::handleDaemonMessage(const uint8_t *message) {
160*84e33947SAndroid Build Coastguard Worker std::unique_ptr<fbs::MessageContainerT> container =
161*84e33947SAndroid Build Coastguard Worker fbs::UnPackMessageContainer(message);
162*84e33947SAndroid Build Coastguard Worker if (container->message.type != fbs::ChreMessage::LoadNanoappResponse) {
163*84e33947SAndroid Build Coastguard Worker LOGE("Invalid message from CHRE directed to daemon");
164*84e33947SAndroid Build Coastguard Worker } else {
165*84e33947SAndroid Build Coastguard Worker const auto *response = container->message.AsLoadNanoappResponse();
166*84e33947SAndroid Build Coastguard Worker if (mPreloadedNanoappPendingTransactions.empty()) {
167*84e33947SAndroid Build Coastguard Worker LOGE("Received nanoapp load response with no pending load");
168*84e33947SAndroid Build Coastguard Worker } else if (mPreloadedNanoappPendingTransactions.front().transactionId !=
169*84e33947SAndroid Build Coastguard Worker response->transaction_id) {
170*84e33947SAndroid Build Coastguard Worker LOGE("Received nanoapp load response with ID %" PRIu32
171*84e33947SAndroid Build Coastguard Worker " expected transaction id %" PRIu32,
172*84e33947SAndroid Build Coastguard Worker response->transaction_id,
173*84e33947SAndroid Build Coastguard Worker mPreloadedNanoappPendingTransactions.front().transactionId);
174*84e33947SAndroid Build Coastguard Worker } else {
175*84e33947SAndroid Build Coastguard Worker if (!response->success) {
176*84e33947SAndroid Build Coastguard Worker LOGE("Received unsuccessful nanoapp load response with ID %" PRIu32,
177*84e33947SAndroid Build Coastguard Worker mPreloadedNanoappPendingTransactions.front().transactionId);
178*84e33947SAndroid Build Coastguard Worker
179*84e33947SAndroid Build Coastguard Worker #ifdef CHRE_DAEMON_METRIC_ENABLED
180*84e33947SAndroid Build Coastguard Worker if (!mMetricsReporter.logNanoappLoadFailed(
181*84e33947SAndroid Build Coastguard Worker mPreloadedNanoappPendingTransactions.front().nanoappId,
182*84e33947SAndroid Build Coastguard Worker ChreHalNanoappLoadFailed::TYPE_PRELOADED,
183*84e33947SAndroid Build Coastguard Worker ChreHalNanoappLoadFailed::REASON_ERROR_GENERIC)) {
184*84e33947SAndroid Build Coastguard Worker LOGE("Could not log the nanoapp load failed metric");
185*84e33947SAndroid Build Coastguard Worker }
186*84e33947SAndroid Build Coastguard Worker #endif // CHRE_DAEMON_METRIC_ENABLED
187*84e33947SAndroid Build Coastguard Worker }
188*84e33947SAndroid Build Coastguard Worker mPreloadedNanoappPendingTransactions.pop();
189*84e33947SAndroid Build Coastguard Worker }
190*84e33947SAndroid Build Coastguard Worker }
191*84e33947SAndroid Build Coastguard Worker }
192*84e33947SAndroid Build Coastguard Worker
193*84e33947SAndroid Build Coastguard Worker } // namespace chre
194*84e33947SAndroid Build Coastguard Worker } // namespace android
195