xref: /aosp_15_r20/system/chre/platform/exynos/host_link.cc (revision 84e339476a462649f82315436d70fd732297a399)
1*84e33947SAndroid Build Coastguard Worker /*
2*84e33947SAndroid Build Coastguard Worker  * Copyright (C) 2022 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 "chre/platform/host_link.h"
18*84e33947SAndroid Build Coastguard Worker #include "chre/core/event_loop_manager.h"
19*84e33947SAndroid Build Coastguard Worker #include "chre/core/host_comms_manager.h"
20*84e33947SAndroid Build Coastguard Worker #include "chre/platform/shared/host_protocol_chre.h"
21*84e33947SAndroid Build Coastguard Worker #include "chre/platform/shared/nanoapp_load_manager.h"
22*84e33947SAndroid Build Coastguard Worker #include "chre/platform/system_time.h"
23*84e33947SAndroid Build Coastguard Worker #include "chre/platform/system_timer.h"
24*84e33947SAndroid Build Coastguard Worker #include "chre/util/flatbuffers/helpers.h"
25*84e33947SAndroid Build Coastguard Worker #include "chre/util/nested_data_ptr.h"
26*84e33947SAndroid Build Coastguard Worker #include "include/chre/target_platform/host_link_base.h"
27*84e33947SAndroid Build Coastguard Worker #include "mailbox.h"
28*84e33947SAndroid Build Coastguard Worker 
29*84e33947SAndroid Build Coastguard Worker // The delete operator is generated by the compiler but not actually called,
30*84e33947SAndroid Build Coastguard Worker // empty implementations are provided to avoid linker warnings.
operator delete(void *)31*84e33947SAndroid Build Coastguard Worker void operator delete(void * /*ptr*/) {}
operator delete(void *,size_t)32*84e33947SAndroid Build Coastguard Worker void operator delete(void * /*ptr*/, size_t /*sz*/) {}
33*84e33947SAndroid Build Coastguard Worker 
34*84e33947SAndroid Build Coastguard Worker namespace chre {
35*84e33947SAndroid Build Coastguard Worker namespace {
36*84e33947SAndroid Build Coastguard Worker 
37*84e33947SAndroid Build Coastguard Worker struct UnloadNanoappCallbackData {
38*84e33947SAndroid Build Coastguard Worker   uint64_t appId;
39*84e33947SAndroid Build Coastguard Worker   uint32_t transactionId;
40*84e33947SAndroid Build Coastguard Worker   uint16_t hostClientId;
41*84e33947SAndroid Build Coastguard Worker   bool allowSystemNanoappUnload;
42*84e33947SAndroid Build Coastguard Worker };
43*84e33947SAndroid Build Coastguard Worker 
getHostCommsManager()44*84e33947SAndroid Build Coastguard Worker inline HostCommsManager &getHostCommsManager() {
45*84e33947SAndroid Build Coastguard Worker   return EventLoopManagerSingleton::get()->getHostCommsManager();
46*84e33947SAndroid Build Coastguard Worker }
47*84e33947SAndroid Build Coastguard Worker 
setTimeSyncRequestTimer(Nanoseconds delay)48*84e33947SAndroid Build Coastguard Worker void setTimeSyncRequestTimer(Nanoseconds delay) {
49*84e33947SAndroid Build Coastguard Worker   static TimerHandle sHandle;
50*84e33947SAndroid Build Coastguard Worker   static bool sHandleInitialized;
51*84e33947SAndroid Build Coastguard Worker 
52*84e33947SAndroid Build Coastguard Worker   if (sHandleInitialized) {
53*84e33947SAndroid Build Coastguard Worker     EventLoopManagerSingleton::get()->cancelDelayedCallback(sHandle);
54*84e33947SAndroid Build Coastguard Worker   }
55*84e33947SAndroid Build Coastguard Worker 
56*84e33947SAndroid Build Coastguard Worker   auto callback = [](uint16_t /*type*/, void * /*data*/, void * /*extraData*/) {
57*84e33947SAndroid Build Coastguard Worker     HostLinkBase::sendTimeSyncRequest();
58*84e33947SAndroid Build Coastguard Worker   };
59*84e33947SAndroid Build Coastguard Worker   sHandle = EventLoopManagerSingleton::get()->setDelayedCallback(
60*84e33947SAndroid Build Coastguard Worker       SystemCallbackType::TimerSyncRequest, nullptr /*data*/, callback, delay);
61*84e33947SAndroid Build Coastguard Worker   sHandleInitialized = true;
62*84e33947SAndroid Build Coastguard Worker }
63*84e33947SAndroid Build Coastguard Worker 
64*84e33947SAndroid Build Coastguard Worker }  // anonymous namespace
65*84e33947SAndroid Build Coastguard Worker 
sendDebugDumpResultToHost(uint16_t,const char *,size_t,bool,uint32_t)66*84e33947SAndroid Build Coastguard Worker void sendDebugDumpResultToHost(uint16_t /*hostClientId*/,
67*84e33947SAndroid Build Coastguard Worker                                const char * /*debugStr*/,
68*84e33947SAndroid Build Coastguard Worker                                size_t /*debugStrSize*/, bool /*complete*/,
69*84e33947SAndroid Build Coastguard Worker                                uint32_t /*dataCount*/) {
70*84e33947SAndroid Build Coastguard Worker   // TODO(b/230134803): Implement this.
71*84e33947SAndroid Build Coastguard Worker }
72*84e33947SAndroid Build Coastguard Worker 
HostLinkBase()73*84e33947SAndroid Build Coastguard Worker HostLinkBase::HostLinkBase() {
74*84e33947SAndroid Build Coastguard Worker   int32_t rv = mailboxReadChre(mMsgBuffer, CHRE_MESSAGE_TO_HOST_MAX_SIZE,
75*84e33947SAndroid Build Coastguard Worker                                receive, this /*cookie*/);
76*84e33947SAndroid Build Coastguard Worker   CHRE_ASSERT_LOG((rv == 0),
77*84e33947SAndroid Build Coastguard Worker                   "Failed to register inbound message handler %" PRId32, rv);
78*84e33947SAndroid Build Coastguard Worker }
79*84e33947SAndroid Build Coastguard Worker 
receive(void * cookie,void * message,int messageLen)80*84e33947SAndroid Build Coastguard Worker void HostLinkBase::receive(void *cookie, void *message, int messageLen) {
81*84e33947SAndroid Build Coastguard Worker   auto *instance = static_cast<HostLinkBase *>(cookie);
82*84e33947SAndroid Build Coastguard Worker   // TODO(b/237819962): A crude way to initially determine daemon's up - set
83*84e33947SAndroid Build Coastguard Worker   // a flag on the first message received. This is temporary until a better
84*84e33947SAndroid Build Coastguard Worker   // way to do this is available.
85*84e33947SAndroid Build Coastguard Worker   instance->setInitialized(true);
86*84e33947SAndroid Build Coastguard Worker 
87*84e33947SAndroid Build Coastguard Worker   if (!HostProtocolChre::decodeMessageFromHost(message, messageLen)) {
88*84e33947SAndroid Build Coastguard Worker     LOGE("Failed to decode msg %p of len %zu", message, messageLen);
89*84e33947SAndroid Build Coastguard Worker   }
90*84e33947SAndroid Build Coastguard Worker }
91*84e33947SAndroid Build Coastguard Worker 
sendMessage(const MessageToHost * message)92*84e33947SAndroid Build Coastguard Worker bool HostLink::sendMessage(const MessageToHost *message) {
93*84e33947SAndroid Build Coastguard Worker   bool success = false;
94*84e33947SAndroid Build Coastguard Worker   if (isInitialized()) {
95*84e33947SAndroid Build Coastguard Worker     constexpr size_t kFixedReserveSize = 88;
96*84e33947SAndroid Build Coastguard Worker     ChreFlatBufferBuilder builder(message->message.size() + kFixedReserveSize);
97*84e33947SAndroid Build Coastguard Worker     HostProtocolChre::encodeNanoappMessage(
98*84e33947SAndroid Build Coastguard Worker         builder, message->appId, message->toHostData.messageType,
99*84e33947SAndroid Build Coastguard Worker         message->toHostData.hostEndpoint, message->message.data(),
100*84e33947SAndroid Build Coastguard Worker         message->message.size(), message->toHostData.appPermissions,
101*84e33947SAndroid Build Coastguard Worker         message->toHostData.messagePermissions, message->toHostData.wokeHost,
102*84e33947SAndroid Build Coastguard Worker         message->isReliable, message->messageSequenceNumber);
103*84e33947SAndroid Build Coastguard Worker     success = (send(builder.GetBufferPointer(), builder.GetSize()) == 0);
104*84e33947SAndroid Build Coastguard Worker 
105*84e33947SAndroid Build Coastguard Worker     // Only invoke on success as returning false from this method will cause
106*84e33947SAndroid Build Coastguard Worker     // core logic to do the appropriate cleanup.
107*84e33947SAndroid Build Coastguard Worker     if (success) {
108*84e33947SAndroid Build Coastguard Worker       EventLoopManagerSingleton::get()
109*84e33947SAndroid Build Coastguard Worker           ->getHostCommsManager()
110*84e33947SAndroid Build Coastguard Worker           .onMessageToHostComplete(message);
111*84e33947SAndroid Build Coastguard Worker     }
112*84e33947SAndroid Build Coastguard Worker   } else {
113*84e33947SAndroid Build Coastguard Worker     LOGW("Dropping outbound message: host link not initialized yet");
114*84e33947SAndroid Build Coastguard Worker   }
115*84e33947SAndroid Build Coastguard Worker   return success;
116*84e33947SAndroid Build Coastguard Worker }
117*84e33947SAndroid Build Coastguard Worker 
sendMessageDeliveryStatus(uint32_t,uint8_t)118*84e33947SAndroid Build Coastguard Worker bool HostLink::sendMessageDeliveryStatus(uint32_t /* messageSequenceNumber */,
119*84e33947SAndroid Build Coastguard Worker                                          uint8_t /* errorCode */) {
120*84e33947SAndroid Build Coastguard Worker   return false;
121*84e33947SAndroid Build Coastguard Worker }
122*84e33947SAndroid Build Coastguard Worker 
123*84e33947SAndroid Build Coastguard Worker // TODO(b/239096709): HostMessageHandlers member function implementations are
124*84e33947SAndroid Build Coastguard Worker // expected to be (mostly) identical for any platform that uses flatbuffers
125*84e33947SAndroid Build Coastguard Worker // to encode messages - refactor the host link to merge the multiple copies
126*84e33947SAndroid Build Coastguard Worker // we currently have.
handleNanoappMessage(uint64_t appId,uint32_t messageType,uint16_t hostEndpoint,const void *,size_t messageDataLen,bool,uint32_t)127*84e33947SAndroid Build Coastguard Worker void HostMessageHandlers::handleNanoappMessage(
128*84e33947SAndroid Build Coastguard Worker     uint64_t appId, uint32_t messageType, uint16_t hostEndpoint,
129*84e33947SAndroid Build Coastguard Worker     const void * /* messageData */, size_t messageDataLen,
130*84e33947SAndroid Build Coastguard Worker     bool /* isReliable */, uint32_t /* messageSequenceNumber */) {
131*84e33947SAndroid Build Coastguard Worker   LOGD("Parsed nanoapp message from host: app ID 0x%016" PRIx64
132*84e33947SAndroid Build Coastguard Worker        ", endpoint "
133*84e33947SAndroid Build Coastguard Worker        "0x%" PRIx16 ", msgType %" PRIu32 ", payload size %zu",
134*84e33947SAndroid Build Coastguard Worker        appId, hostEndpoint, messageType, messageDataLen);
135*84e33947SAndroid Build Coastguard Worker 
136*84e33947SAndroid Build Coastguard Worker   // TODO(b/230134803): Implement this.
137*84e33947SAndroid Build Coastguard Worker }
138*84e33947SAndroid Build Coastguard Worker 
handleMessageDeliveryStatus(uint32_t,uint8_t)139*84e33947SAndroid Build Coastguard Worker void HostMessageHandlers::handleMessageDeliveryStatus(
140*84e33947SAndroid Build Coastguard Worker     uint32_t /* messageSequenceNumber */, uint8_t /* errorCode */) {}
141*84e33947SAndroid Build Coastguard Worker 
handleHubInfoRequest(uint16_t)142*84e33947SAndroid Build Coastguard Worker void HostMessageHandlers::handleHubInfoRequest(uint16_t /* hostClientId */) {
143*84e33947SAndroid Build Coastguard Worker   // TODO(b/230134803): Implement this.
144*84e33947SAndroid Build Coastguard Worker }
145*84e33947SAndroid Build Coastguard Worker 
handleNanoappListRequest(uint16_t hostClientId)146*84e33947SAndroid Build Coastguard Worker void HostMessageHandlers::handleNanoappListRequest(uint16_t hostClientId) {
147*84e33947SAndroid Build Coastguard Worker   // TODO(b/230134803): Implement this.
148*84e33947SAndroid Build Coastguard Worker }
149*84e33947SAndroid Build Coastguard Worker 
handlePulseRequest()150*84e33947SAndroid Build Coastguard Worker void HostMessageHandlers::handlePulseRequest() {}
151*84e33947SAndroid Build Coastguard Worker 
sendFragmentResponse(uint16_t hostClientId,uint32_t transactionId,uint32_t fragmentId,bool success)152*84e33947SAndroid Build Coastguard Worker void HostMessageHandlers::sendFragmentResponse(uint16_t hostClientId,
153*84e33947SAndroid Build Coastguard Worker                                                uint32_t transactionId,
154*84e33947SAndroid Build Coastguard Worker                                                uint32_t fragmentId,
155*84e33947SAndroid Build Coastguard Worker                                                bool success) {
156*84e33947SAndroid Build Coastguard Worker   constexpr size_t kInitialBufferSize = 52;
157*84e33947SAndroid Build Coastguard Worker   ChreFlatBufferBuilder builder(kInitialBufferSize);
158*84e33947SAndroid Build Coastguard Worker   HostProtocolChre::encodeLoadNanoappResponse(
159*84e33947SAndroid Build Coastguard Worker       builder, hostClientId, transactionId, success, fragmentId);
160*84e33947SAndroid Build Coastguard Worker 
161*84e33947SAndroid Build Coastguard Worker   if (!getHostCommsManager().send(builder.GetBufferPointer(),
162*84e33947SAndroid Build Coastguard Worker                                   builder.GetSize())) {
163*84e33947SAndroid Build Coastguard Worker     LOGE("Failed to send fragment response for HostClientID: %" PRIx16
164*84e33947SAndroid Build Coastguard Worker          " , FragmentID: %" PRIx32 " transactionID: %" PRIx32,
165*84e33947SAndroid Build Coastguard Worker          hostClientId, fragmentId, transactionId);
166*84e33947SAndroid Build Coastguard Worker   }
167*84e33947SAndroid Build Coastguard Worker }
168*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)169*84e33947SAndroid Build Coastguard Worker void HostMessageHandlers::handleLoadNanoappRequest(
170*84e33947SAndroid Build Coastguard Worker     uint16_t hostClientId, uint32_t transactionId, uint64_t appId,
171*84e33947SAndroid Build Coastguard Worker     uint32_t appVersion, uint32_t appFlags, uint32_t targetApiVersion,
172*84e33947SAndroid Build Coastguard Worker     const void *buffer, size_t bufferLen, const char *appFileName,
173*84e33947SAndroid Build Coastguard Worker     uint32_t fragmentId, size_t appBinaryLen, bool respondBeforeStart) {
174*84e33947SAndroid Build Coastguard Worker   UNUSED_VAR(appFileName);
175*84e33947SAndroid Build Coastguard Worker 
176*84e33947SAndroid Build Coastguard Worker   loadNanoappData(hostClientId, transactionId, appId, appVersion, appFlags,
177*84e33947SAndroid Build Coastguard Worker                   targetApiVersion, buffer, bufferLen, fragmentId, appBinaryLen,
178*84e33947SAndroid Build Coastguard Worker                   respondBeforeStart);
179*84e33947SAndroid Build Coastguard Worker }
180*84e33947SAndroid Build Coastguard Worker 
handleUnloadNanoappRequest(uint16_t hostClientId,uint32_t transactionId,uint64_t appId,bool allowSystemNanoappUnload)181*84e33947SAndroid Build Coastguard Worker void HostMessageHandlers::handleUnloadNanoappRequest(
182*84e33947SAndroid Build Coastguard Worker     uint16_t hostClientId, uint32_t transactionId, uint64_t appId,
183*84e33947SAndroid Build Coastguard Worker     bool allowSystemNanoappUnload) {
184*84e33947SAndroid Build Coastguard Worker   LOGD("Unload nanoapp request from client %" PRIu16 " (txnID %" PRIu32
185*84e33947SAndroid Build Coastguard Worker        ") for appId 0x%016" PRIx64 " system %d",
186*84e33947SAndroid Build Coastguard Worker        hostClientId, transactionId, appId, allowSystemNanoappUnload);
187*84e33947SAndroid Build Coastguard Worker   // TODO(b/230134803): Implement this.
188*84e33947SAndroid Build Coastguard Worker }
189*84e33947SAndroid Build Coastguard Worker 
handleTimeSyncMessage(int64_t offset)190*84e33947SAndroid Build Coastguard Worker void HostMessageHandlers::handleTimeSyncMessage(int64_t offset) {
191*84e33947SAndroid Build Coastguard Worker   LOGD("Time sync msg received with offset %" PRId64, offset);
192*84e33947SAndroid Build Coastguard Worker 
193*84e33947SAndroid Build Coastguard Worker   SystemTime::setEstimatedHostTimeOffset(offset);
194*84e33947SAndroid Build Coastguard Worker 
195*84e33947SAndroid Build Coastguard Worker   // Schedule a time sync request since offset may drift
196*84e33947SAndroid Build Coastguard Worker   constexpr Seconds kClockDriftTimeSyncPeriod =
197*84e33947SAndroid Build Coastguard Worker       Seconds(60 * 60 * 6);  // 6 hours
198*84e33947SAndroid Build Coastguard Worker   setTimeSyncRequestTimer(kClockDriftTimeSyncPeriod);
199*84e33947SAndroid Build Coastguard Worker }
200*84e33947SAndroid Build Coastguard Worker 
handleDebugDumpRequest(uint16_t)201*84e33947SAndroid Build Coastguard Worker void HostMessageHandlers::handleDebugDumpRequest(uint16_t /* hostClientId */) {
202*84e33947SAndroid Build Coastguard Worker   // TODO(b/230134803): Implement this.
203*84e33947SAndroid Build Coastguard Worker }
204*84e33947SAndroid Build Coastguard Worker 
handleSettingChangeMessage(fbs::Setting setting,fbs::SettingState state)205*84e33947SAndroid Build Coastguard Worker void HostMessageHandlers::handleSettingChangeMessage(fbs::Setting setting,
206*84e33947SAndroid Build Coastguard Worker                                                      fbs::SettingState state) {
207*84e33947SAndroid Build Coastguard Worker   Setting chreSetting;
208*84e33947SAndroid Build Coastguard Worker   bool chreSettingEnabled;
209*84e33947SAndroid Build Coastguard Worker   if (HostProtocolChre::getSettingFromFbs(setting, &chreSetting) &&
210*84e33947SAndroid Build Coastguard Worker       HostProtocolChre::getSettingEnabledFromFbs(state, &chreSettingEnabled)) {
211*84e33947SAndroid Build Coastguard Worker     EventLoopManagerSingleton::get()->getSettingManager().postSettingChange(
212*84e33947SAndroid Build Coastguard Worker         chreSetting, chreSettingEnabled);
213*84e33947SAndroid Build Coastguard Worker   }
214*84e33947SAndroid Build Coastguard Worker }
215*84e33947SAndroid Build Coastguard Worker 
handleSelfTestRequest(uint16_t)216*84e33947SAndroid Build Coastguard Worker void HostMessageHandlers::handleSelfTestRequest(uint16_t /* hostClientId */) {
217*84e33947SAndroid Build Coastguard Worker   // TODO(b/230134803): Implement this.
218*84e33947SAndroid Build Coastguard Worker }
219*84e33947SAndroid Build Coastguard Worker 
handleNanConfigurationUpdate(bool)220*84e33947SAndroid Build Coastguard Worker void HostMessageHandlers::handleNanConfigurationUpdate(bool /* enabled */) {
221*84e33947SAndroid Build Coastguard Worker   LOGE("NAN unsupported.");
222*84e33947SAndroid Build Coastguard Worker }
223*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)224*84e33947SAndroid Build Coastguard Worker void HostMessageHandlers::handleBtSocketOpen(
225*84e33947SAndroid Build Coastguard Worker     uint16_t /* hostClientId */, uint64_t /* socketId */,
226*84e33947SAndroid Build Coastguard Worker     const char * /* name */, uint64_t /* endpointId */, uint64_t /* hubId */,
227*84e33947SAndroid Build Coastguard Worker     uint32_t /* aclConnectionHandle */, uint32_t /* localCid */,
228*84e33947SAndroid Build Coastguard Worker     uint32_t /* remoteCid */, uint32_t /* psm */, uint32_t /* localMtu */,
229*84e33947SAndroid Build Coastguard Worker     uint32_t /* remoteMtu */, uint32_t /* localMps */, uint32_t /* remoteMps */,
230*84e33947SAndroid Build Coastguard Worker     uint32_t /* initialRxCredits */, uint32_t /* initialTxCredits */) {
231*84e33947SAndroid Build Coastguard Worker   LOGE("BT Socket offload not supported");
232*84e33947SAndroid Build Coastguard Worker }
233*84e33947SAndroid Build Coastguard Worker 
234*84e33947SAndroid Build Coastguard Worker }  // namespace chre
235