1*4d7e907cSAndroid Build Coastguard Worker /*
2*4d7e907cSAndroid Build Coastguard Worker * Copyright (C) 2021 The Android Open Source Project
3*4d7e907cSAndroid Build Coastguard Worker *
4*4d7e907cSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*4d7e907cSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*4d7e907cSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*4d7e907cSAndroid Build Coastguard Worker *
8*4d7e907cSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*4d7e907cSAndroid Build Coastguard Worker *
10*4d7e907cSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*4d7e907cSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*4d7e907cSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*4d7e907cSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*4d7e907cSAndroid Build Coastguard Worker * limitations under the License.
15*4d7e907cSAndroid Build Coastguard Worker */
16*4d7e907cSAndroid Build Coastguard Worker
17*4d7e907cSAndroid Build Coastguard Worker #include "contexthub-impl/ContextHub.h"
18*4d7e907cSAndroid Build Coastguard Worker
19*4d7e907cSAndroid Build Coastguard Worker #ifndef LOG_TAG
20*4d7e907cSAndroid Build Coastguard Worker #define LOG_TAG "CHRE"
21*4d7e907cSAndroid Build Coastguard Worker #endif
22*4d7e907cSAndroid Build Coastguard Worker
23*4d7e907cSAndroid Build Coastguard Worker #include <inttypes.h>
24*4d7e907cSAndroid Build Coastguard Worker #include <log/log.h>
25*4d7e907cSAndroid Build Coastguard Worker
26*4d7e907cSAndroid Build Coastguard Worker using ::ndk::ScopedAStatus;
27*4d7e907cSAndroid Build Coastguard Worker
28*4d7e907cSAndroid Build Coastguard Worker namespace aidl::android::hardware::contexthub {
29*4d7e907cSAndroid Build Coastguard Worker
30*4d7e907cSAndroid Build Coastguard Worker namespace {
31*4d7e907cSAndroid Build Coastguard Worker
32*4d7e907cSAndroid Build Coastguard Worker constexpr uint64_t kMockVendorHubId = 0x1234567812345678;
33*4d7e907cSAndroid Build Coastguard Worker constexpr uint64_t kMockVendorHub2Id = 0x0EADBEEFDEADBEEF;
34*4d7e907cSAndroid Build Coastguard Worker
35*4d7e907cSAndroid Build Coastguard Worker // Mock endpoints for the default implementation.
36*4d7e907cSAndroid Build Coastguard Worker // These endpoints just echo back any messages sent to them.
37*4d7e907cSAndroid Build Coastguard Worker constexpr size_t kMockEndpointCount = 4;
38*4d7e907cSAndroid Build Coastguard Worker const EndpointInfo kMockEndpointInfos[kMockEndpointCount] = {
39*4d7e907cSAndroid Build Coastguard Worker {
40*4d7e907cSAndroid Build Coastguard Worker .id = {.hubId = kMockVendorHubId, .id = UINT64_C(0x1)},
41*4d7e907cSAndroid Build Coastguard Worker .type = EndpointInfo::EndpointType::GENERIC,
42*4d7e907cSAndroid Build Coastguard Worker .name = "Mock Endpoint 1",
43*4d7e907cSAndroid Build Coastguard Worker .version = 1,
44*4d7e907cSAndroid Build Coastguard Worker },
45*4d7e907cSAndroid Build Coastguard Worker {
46*4d7e907cSAndroid Build Coastguard Worker .id = {.hubId = kMockVendorHubId, .id = UINT64_C(0x2)},
47*4d7e907cSAndroid Build Coastguard Worker .type = EndpointInfo::EndpointType::GENERIC,
48*4d7e907cSAndroid Build Coastguard Worker .name = "Mock Endpoint 2",
49*4d7e907cSAndroid Build Coastguard Worker .version = 2,
50*4d7e907cSAndroid Build Coastguard Worker },
51*4d7e907cSAndroid Build Coastguard Worker {
52*4d7e907cSAndroid Build Coastguard Worker .id = {.hubId = kMockVendorHub2Id, .id = UINT64_C(0x1)},
53*4d7e907cSAndroid Build Coastguard Worker .type = EndpointInfo::EndpointType::GENERIC,
54*4d7e907cSAndroid Build Coastguard Worker .name = "Mock Endpoint 3",
55*4d7e907cSAndroid Build Coastguard Worker .version = 1,
56*4d7e907cSAndroid Build Coastguard Worker },
57*4d7e907cSAndroid Build Coastguard Worker {
58*4d7e907cSAndroid Build Coastguard Worker .id = {.hubId = kMockVendorHub2Id, .id = UINT64_C(0x2)},
59*4d7e907cSAndroid Build Coastguard Worker .type = EndpointInfo::EndpointType::GENERIC,
60*4d7e907cSAndroid Build Coastguard Worker .name = "Mock Endpoint 4",
61*4d7e907cSAndroid Build Coastguard Worker .version = 2,
62*4d7e907cSAndroid Build Coastguard Worker },
63*4d7e907cSAndroid Build Coastguard Worker };
64*4d7e907cSAndroid Build Coastguard Worker
65*4d7e907cSAndroid Build Coastguard Worker } // anonymous namespace
66*4d7e907cSAndroid Build Coastguard Worker
getContextHubs(std::vector<ContextHubInfo> * out_contextHubInfos)67*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus ContextHub::getContextHubs(std::vector<ContextHubInfo>* out_contextHubInfos) {
68*4d7e907cSAndroid Build Coastguard Worker ContextHubInfo hub = {};
69*4d7e907cSAndroid Build Coastguard Worker hub.name = "Mock Context Hub";
70*4d7e907cSAndroid Build Coastguard Worker hub.vendor = "AOSP";
71*4d7e907cSAndroid Build Coastguard Worker hub.toolchain = "n/a";
72*4d7e907cSAndroid Build Coastguard Worker hub.id = kMockHubId;
73*4d7e907cSAndroid Build Coastguard Worker hub.peakMips = 1;
74*4d7e907cSAndroid Build Coastguard Worker hub.maxSupportedMessageLengthBytes = 4096;
75*4d7e907cSAndroid Build Coastguard Worker hub.chrePlatformId = UINT64_C(0x476f6f6754000000);
76*4d7e907cSAndroid Build Coastguard Worker hub.chreApiMajorVersion = 1;
77*4d7e907cSAndroid Build Coastguard Worker hub.chreApiMinorVersion = 6;
78*4d7e907cSAndroid Build Coastguard Worker hub.supportsReliableMessages = false;
79*4d7e907cSAndroid Build Coastguard Worker
80*4d7e907cSAndroid Build Coastguard Worker out_contextHubInfos->push_back(hub);
81*4d7e907cSAndroid Build Coastguard Worker
82*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::ok();
83*4d7e907cSAndroid Build Coastguard Worker }
84*4d7e907cSAndroid Build Coastguard Worker
85*4d7e907cSAndroid Build Coastguard Worker // We don't expose any nanoapps for the default impl, therefore all nanoapp-related APIs fail.
loadNanoapp(int32_t,const NanoappBinary &,int32_t)86*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus ContextHub::loadNanoapp(int32_t /* in_contextHubId */,
87*4d7e907cSAndroid Build Coastguard Worker const NanoappBinary& /* in_appBinary */,
88*4d7e907cSAndroid Build Coastguard Worker int32_t /* in_transactionId */) {
89*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
90*4d7e907cSAndroid Build Coastguard Worker }
91*4d7e907cSAndroid Build Coastguard Worker
unloadNanoapp(int32_t,int64_t,int32_t)92*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus ContextHub::unloadNanoapp(int32_t /* in_contextHubId */, int64_t /* in_appId */,
93*4d7e907cSAndroid Build Coastguard Worker int32_t /* in_transactionId */) {
94*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
95*4d7e907cSAndroid Build Coastguard Worker }
96*4d7e907cSAndroid Build Coastguard Worker
disableNanoapp(int32_t,int64_t,int32_t)97*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus ContextHub::disableNanoapp(int32_t /* in_contextHubId */, int64_t /* in_appId */,
98*4d7e907cSAndroid Build Coastguard Worker int32_t /* in_transactionId */) {
99*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
100*4d7e907cSAndroid Build Coastguard Worker }
101*4d7e907cSAndroid Build Coastguard Worker
enableNanoapp(int32_t,int64_t,int32_t)102*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus ContextHub::enableNanoapp(int32_t /* in_contextHubId */, int64_t /* in_appId */,
103*4d7e907cSAndroid Build Coastguard Worker int32_t /* in_transactionId */) {
104*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
105*4d7e907cSAndroid Build Coastguard Worker }
106*4d7e907cSAndroid Build Coastguard Worker
onSettingChanged(Setting,bool)107*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus ContextHub::onSettingChanged(Setting /* in_setting */, bool /*in_enabled */) {
108*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::ok();
109*4d7e907cSAndroid Build Coastguard Worker }
110*4d7e907cSAndroid Build Coastguard Worker
queryNanoapps(int32_t in_contextHubId)111*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus ContextHub::queryNanoapps(int32_t in_contextHubId) {
112*4d7e907cSAndroid Build Coastguard Worker if (in_contextHubId == kMockHubId && mCallback != nullptr) {
113*4d7e907cSAndroid Build Coastguard Worker std::vector<NanoappInfo> nanoapps;
114*4d7e907cSAndroid Build Coastguard Worker mCallback->handleNanoappInfo(nanoapps);
115*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::ok();
116*4d7e907cSAndroid Build Coastguard Worker } else {
117*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
118*4d7e907cSAndroid Build Coastguard Worker }
119*4d7e907cSAndroid Build Coastguard Worker }
120*4d7e907cSAndroid Build Coastguard Worker
getPreloadedNanoappIds(int32_t,std::vector<int64_t> * out_preloadedNanoappIds)121*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus ContextHub::getPreloadedNanoappIds(int32_t /* in_contextHubId */,
122*4d7e907cSAndroid Build Coastguard Worker std::vector<int64_t>* out_preloadedNanoappIds) {
123*4d7e907cSAndroid Build Coastguard Worker if (out_preloadedNanoappIds == nullptr) {
124*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
125*4d7e907cSAndroid Build Coastguard Worker }
126*4d7e907cSAndroid Build Coastguard Worker
127*4d7e907cSAndroid Build Coastguard Worker for (uint64_t i = 0; i < 10; ++i) {
128*4d7e907cSAndroid Build Coastguard Worker out_preloadedNanoappIds->push_back(i);
129*4d7e907cSAndroid Build Coastguard Worker }
130*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::ok();
131*4d7e907cSAndroid Build Coastguard Worker }
132*4d7e907cSAndroid Build Coastguard Worker
onNanSessionStateChanged(const NanSessionStateUpdate &)133*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus ContextHub::onNanSessionStateChanged(const NanSessionStateUpdate& /*in_update*/) {
134*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::ok();
135*4d7e907cSAndroid Build Coastguard Worker }
136*4d7e907cSAndroid Build Coastguard Worker
registerCallback(int32_t in_contextHubId,const std::shared_ptr<IContextHubCallback> & in_cb)137*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus ContextHub::registerCallback(int32_t in_contextHubId,
138*4d7e907cSAndroid Build Coastguard Worker const std::shared_ptr<IContextHubCallback>& in_cb) {
139*4d7e907cSAndroid Build Coastguard Worker if (in_contextHubId == kMockHubId) {
140*4d7e907cSAndroid Build Coastguard Worker mCallback = in_cb;
141*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::ok();
142*4d7e907cSAndroid Build Coastguard Worker } else {
143*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
144*4d7e907cSAndroid Build Coastguard Worker }
145*4d7e907cSAndroid Build Coastguard Worker }
146*4d7e907cSAndroid Build Coastguard Worker
sendMessageToHub(int32_t in_contextHubId,const ContextHubMessage &)147*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus ContextHub::sendMessageToHub(int32_t in_contextHubId,
148*4d7e907cSAndroid Build Coastguard Worker const ContextHubMessage& /* in_message */) {
149*4d7e907cSAndroid Build Coastguard Worker if (in_contextHubId == kMockHubId) {
150*4d7e907cSAndroid Build Coastguard Worker // Return true here to indicate that the HAL has accepted the message.
151*4d7e907cSAndroid Build Coastguard Worker // Successful delivery of the message to a nanoapp should be handled at
152*4d7e907cSAndroid Build Coastguard Worker // a higher level protocol.
153*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::ok();
154*4d7e907cSAndroid Build Coastguard Worker } else {
155*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
156*4d7e907cSAndroid Build Coastguard Worker }
157*4d7e907cSAndroid Build Coastguard Worker }
158*4d7e907cSAndroid Build Coastguard Worker
setTestMode(bool enable)159*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus ContextHub::setTestMode(bool enable) {
160*4d7e907cSAndroid Build Coastguard Worker if (enable) {
161*4d7e907cSAndroid Build Coastguard Worker std::unique_lock<std::mutex> lock(mEndpointMutex);
162*4d7e907cSAndroid Build Coastguard Worker mEndpoints.clear();
163*4d7e907cSAndroid Build Coastguard Worker mEndpointSessions.clear();
164*4d7e907cSAndroid Build Coastguard Worker mEndpointCallback = nullptr;
165*4d7e907cSAndroid Build Coastguard Worker }
166*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::ok();
167*4d7e907cSAndroid Build Coastguard Worker }
168*4d7e907cSAndroid Build Coastguard Worker
onHostEndpointConnected(const HostEndpointInfo & in_info)169*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus ContextHub::onHostEndpointConnected(const HostEndpointInfo& in_info) {
170*4d7e907cSAndroid Build Coastguard Worker mConnectedHostEndpoints.insert(in_info.hostEndpointId);
171*4d7e907cSAndroid Build Coastguard Worker
172*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::ok();
173*4d7e907cSAndroid Build Coastguard Worker }
174*4d7e907cSAndroid Build Coastguard Worker
onHostEndpointDisconnected(char16_t in_hostEndpointId)175*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus ContextHub::onHostEndpointDisconnected(char16_t in_hostEndpointId) {
176*4d7e907cSAndroid Build Coastguard Worker if (mConnectedHostEndpoints.count(in_hostEndpointId) > 0) {
177*4d7e907cSAndroid Build Coastguard Worker mConnectedHostEndpoints.erase(in_hostEndpointId);
178*4d7e907cSAndroid Build Coastguard Worker }
179*4d7e907cSAndroid Build Coastguard Worker
180*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::ok();
181*4d7e907cSAndroid Build Coastguard Worker }
182*4d7e907cSAndroid Build Coastguard Worker
sendMessageDeliveryStatusToHub(int32_t,const MessageDeliveryStatus &)183*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus ContextHub::sendMessageDeliveryStatusToHub(
184*4d7e907cSAndroid Build Coastguard Worker int32_t /* in_contextHubId */,
185*4d7e907cSAndroid Build Coastguard Worker const MessageDeliveryStatus& /* in_messageDeliveryStatus */) {
186*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
187*4d7e907cSAndroid Build Coastguard Worker }
188*4d7e907cSAndroid Build Coastguard Worker
getHubs(std::vector<HubInfo> * _aidl_return)189*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus ContextHub::getHubs(std::vector<HubInfo>* _aidl_return) {
190*4d7e907cSAndroid Build Coastguard Worker if (_aidl_return == nullptr) {
191*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
192*4d7e907cSAndroid Build Coastguard Worker }
193*4d7e907cSAndroid Build Coastguard Worker
194*4d7e907cSAndroid Build Coastguard Worker ContextHubInfo hub = {};
195*4d7e907cSAndroid Build Coastguard Worker hub.name = "Mock Context Hub";
196*4d7e907cSAndroid Build Coastguard Worker hub.vendor = "AOSP";
197*4d7e907cSAndroid Build Coastguard Worker hub.toolchain = "n/a";
198*4d7e907cSAndroid Build Coastguard Worker hub.id = kMockHubId;
199*4d7e907cSAndroid Build Coastguard Worker hub.peakMips = 1;
200*4d7e907cSAndroid Build Coastguard Worker hub.maxSupportedMessageLengthBytes = 4096;
201*4d7e907cSAndroid Build Coastguard Worker hub.chrePlatformId = UINT64_C(0x476f6f6754000000);
202*4d7e907cSAndroid Build Coastguard Worker hub.chreApiMajorVersion = 1;
203*4d7e907cSAndroid Build Coastguard Worker hub.chreApiMinorVersion = 6;
204*4d7e907cSAndroid Build Coastguard Worker hub.supportsReliableMessages = false;
205*4d7e907cSAndroid Build Coastguard Worker
206*4d7e907cSAndroid Build Coastguard Worker HubInfo hubInfo1 = {};
207*4d7e907cSAndroid Build Coastguard Worker hubInfo1.hubId = hub.chrePlatformId;
208*4d7e907cSAndroid Build Coastguard Worker hubInfo1.hubDetails = HubInfo::HubDetails::make<HubInfo::HubDetails::Tag::contextHubInfo>(hub);
209*4d7e907cSAndroid Build Coastguard Worker
210*4d7e907cSAndroid Build Coastguard Worker VendorHubInfo vendorHub = {};
211*4d7e907cSAndroid Build Coastguard Worker vendorHub.name = "Mock Vendor Hub";
212*4d7e907cSAndroid Build Coastguard Worker vendorHub.version = 42;
213*4d7e907cSAndroid Build Coastguard Worker
214*4d7e907cSAndroid Build Coastguard Worker HubInfo hubInfo2 = {};
215*4d7e907cSAndroid Build Coastguard Worker hubInfo2.hubId = kMockVendorHubId;
216*4d7e907cSAndroid Build Coastguard Worker hubInfo2.hubDetails =
217*4d7e907cSAndroid Build Coastguard Worker HubInfo::HubDetails::make<HubInfo::HubDetails::Tag::vendorHubInfo>(vendorHub);
218*4d7e907cSAndroid Build Coastguard Worker
219*4d7e907cSAndroid Build Coastguard Worker VendorHubInfo vendorHub2 = {};
220*4d7e907cSAndroid Build Coastguard Worker vendorHub2.name = "Mock Vendor Hub 2";
221*4d7e907cSAndroid Build Coastguard Worker vendorHub2.version = 24;
222*4d7e907cSAndroid Build Coastguard Worker
223*4d7e907cSAndroid Build Coastguard Worker HubInfo hubInfo3 = {};
224*4d7e907cSAndroid Build Coastguard Worker hubInfo3.hubId = kMockVendorHub2Id;
225*4d7e907cSAndroid Build Coastguard Worker hubInfo3.hubDetails =
226*4d7e907cSAndroid Build Coastguard Worker HubInfo::HubDetails::make<HubInfo::HubDetails::Tag::vendorHubInfo>(vendorHub2);
227*4d7e907cSAndroid Build Coastguard Worker
228*4d7e907cSAndroid Build Coastguard Worker _aidl_return->push_back(hubInfo1);
229*4d7e907cSAndroid Build Coastguard Worker _aidl_return->push_back(hubInfo2);
230*4d7e907cSAndroid Build Coastguard Worker _aidl_return->push_back(hubInfo3);
231*4d7e907cSAndroid Build Coastguard Worker
232*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::ok();
233*4d7e907cSAndroid Build Coastguard Worker };
234*4d7e907cSAndroid Build Coastguard Worker
getEndpoints(std::vector<EndpointInfo> * _aidl_return)235*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus ContextHub::getEndpoints(std::vector<EndpointInfo>* _aidl_return) {
236*4d7e907cSAndroid Build Coastguard Worker if (_aidl_return == nullptr) {
237*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
238*4d7e907cSAndroid Build Coastguard Worker }
239*4d7e907cSAndroid Build Coastguard Worker
240*4d7e907cSAndroid Build Coastguard Worker Service echoService;
241*4d7e907cSAndroid Build Coastguard Worker echoService.format = Service::RpcFormat::CUSTOM;
242*4d7e907cSAndroid Build Coastguard Worker echoService.serviceDescriptor = "ECHO";
243*4d7e907cSAndroid Build Coastguard Worker echoService.majorVersion = 1;
244*4d7e907cSAndroid Build Coastguard Worker echoService.minorVersion = 0;
245*4d7e907cSAndroid Build Coastguard Worker
246*4d7e907cSAndroid Build Coastguard Worker for (const EndpointInfo& endpoint : kMockEndpointInfos) {
247*4d7e907cSAndroid Build Coastguard Worker EndpointInfo endpointWithService(endpoint);
248*4d7e907cSAndroid Build Coastguard Worker endpointWithService.services.push_back(echoService);
249*4d7e907cSAndroid Build Coastguard Worker _aidl_return->push_back(std::move(endpointWithService));
250*4d7e907cSAndroid Build Coastguard Worker }
251*4d7e907cSAndroid Build Coastguard Worker
252*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::ok();
253*4d7e907cSAndroid Build Coastguard Worker };
254*4d7e907cSAndroid Build Coastguard Worker
registerEndpoint(const EndpointInfo & in_endpoint)255*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus ContextHub::registerEndpoint(const EndpointInfo& in_endpoint) {
256*4d7e907cSAndroid Build Coastguard Worker std::unique_lock<std::mutex> lock(mEndpointMutex);
257*4d7e907cSAndroid Build Coastguard Worker
258*4d7e907cSAndroid Build Coastguard Worker for (const EndpointInfo& endpoint : mEndpoints) {
259*4d7e907cSAndroid Build Coastguard Worker if ((endpoint.id.id == in_endpoint.id.id && endpoint.id.hubId == in_endpoint.id.hubId) ||
260*4d7e907cSAndroid Build Coastguard Worker endpoint.name == in_endpoint.name) {
261*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
262*4d7e907cSAndroid Build Coastguard Worker }
263*4d7e907cSAndroid Build Coastguard Worker }
264*4d7e907cSAndroid Build Coastguard Worker mEndpoints.push_back(in_endpoint);
265*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::ok();
266*4d7e907cSAndroid Build Coastguard Worker };
267*4d7e907cSAndroid Build Coastguard Worker
unregisterEndpoint(const EndpointInfo & in_endpoint)268*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus ContextHub::unregisterEndpoint(const EndpointInfo& in_endpoint) {
269*4d7e907cSAndroid Build Coastguard Worker std::unique_lock<std::mutex> lock(mEndpointMutex);
270*4d7e907cSAndroid Build Coastguard Worker
271*4d7e907cSAndroid Build Coastguard Worker for (auto it = mEndpoints.begin(); it != mEndpoints.end(); ++it) {
272*4d7e907cSAndroid Build Coastguard Worker if (it->id.id == in_endpoint.id.id && it->id.hubId == in_endpoint.id.hubId) {
273*4d7e907cSAndroid Build Coastguard Worker mEndpoints.erase(it);
274*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::ok();
275*4d7e907cSAndroid Build Coastguard Worker }
276*4d7e907cSAndroid Build Coastguard Worker }
277*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
278*4d7e907cSAndroid Build Coastguard Worker };
279*4d7e907cSAndroid Build Coastguard Worker
registerEndpointCallback(const std::shared_ptr<IEndpointCallback> & in_callback)280*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus ContextHub::registerEndpointCallback(
281*4d7e907cSAndroid Build Coastguard Worker const std::shared_ptr<IEndpointCallback>& in_callback) {
282*4d7e907cSAndroid Build Coastguard Worker std::unique_lock<std::mutex> lock(mEndpointMutex);
283*4d7e907cSAndroid Build Coastguard Worker
284*4d7e907cSAndroid Build Coastguard Worker mEndpointCallback = in_callback;
285*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::ok();
286*4d7e907cSAndroid Build Coastguard Worker };
287*4d7e907cSAndroid Build Coastguard Worker
requestSessionIdRange(int32_t in_size,std::vector<int32_t> * _aidl_return)288*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus ContextHub::requestSessionIdRange(int32_t in_size,
289*4d7e907cSAndroid Build Coastguard Worker std::vector<int32_t>* _aidl_return) {
290*4d7e907cSAndroid Build Coastguard Worker constexpr int32_t kMaxSize = 1024;
291*4d7e907cSAndroid Build Coastguard Worker if (in_size > kMaxSize || _aidl_return == nullptr) {
292*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
293*4d7e907cSAndroid Build Coastguard Worker }
294*4d7e907cSAndroid Build Coastguard Worker
295*4d7e907cSAndroid Build Coastguard Worker {
296*4d7e907cSAndroid Build Coastguard Worker std::lock_guard<std::mutex> lock(mEndpointMutex);
297*4d7e907cSAndroid Build Coastguard Worker mMaxValidSessionId = in_size;
298*4d7e907cSAndroid Build Coastguard Worker }
299*4d7e907cSAndroid Build Coastguard Worker
300*4d7e907cSAndroid Build Coastguard Worker _aidl_return->push_back(0);
301*4d7e907cSAndroid Build Coastguard Worker _aidl_return->push_back(in_size);
302*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::ok();
303*4d7e907cSAndroid Build Coastguard Worker };
304*4d7e907cSAndroid Build Coastguard Worker
openEndpointSession(int32_t in_sessionId,const EndpointId & in_destination,const EndpointId & in_initiator,const std::optional<std::string> & in_serviceDescriptor)305*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus ContextHub::openEndpointSession(
306*4d7e907cSAndroid Build Coastguard Worker int32_t in_sessionId, const EndpointId& in_destination, const EndpointId& in_initiator,
307*4d7e907cSAndroid Build Coastguard Worker const std::optional<std::string>& in_serviceDescriptor) {
308*4d7e907cSAndroid Build Coastguard Worker // We are not calling onCloseEndpointSession on failure because the remote endpoints (our
309*4d7e907cSAndroid Build Coastguard Worker // mock endpoints) always accept the session.
310*4d7e907cSAndroid Build Coastguard Worker
311*4d7e907cSAndroid Build Coastguard Worker std::shared_ptr<IEndpointCallback> callback = nullptr;
312*4d7e907cSAndroid Build Coastguard Worker {
313*4d7e907cSAndroid Build Coastguard Worker std::unique_lock<std::mutex> lock(mEndpointMutex);
314*4d7e907cSAndroid Build Coastguard Worker if (in_sessionId > mMaxValidSessionId) {
315*4d7e907cSAndroid Build Coastguard Worker ALOGE("openEndpointSession: session ID %" PRId32 " is invalid", in_sessionId);
316*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
317*4d7e907cSAndroid Build Coastguard Worker }
318*4d7e907cSAndroid Build Coastguard Worker
319*4d7e907cSAndroid Build Coastguard Worker for (const EndpointSession& session : mEndpointSessions) {
320*4d7e907cSAndroid Build Coastguard Worker bool sessionAlreadyExists =
321*4d7e907cSAndroid Build Coastguard Worker (session.initiator == in_destination && session.peer == in_initiator) ||
322*4d7e907cSAndroid Build Coastguard Worker (session.peer == in_destination && session.initiator == in_initiator);
323*4d7e907cSAndroid Build Coastguard Worker if (sessionAlreadyExists) {
324*4d7e907cSAndroid Build Coastguard Worker ALOGD("openEndpointSession: session ID %" PRId32 " already exists", in_sessionId);
325*4d7e907cSAndroid Build Coastguard Worker return (session.sessionId == in_sessionId &&
326*4d7e907cSAndroid Build Coastguard Worker session.serviceDescriptor == in_serviceDescriptor)
327*4d7e907cSAndroid Build Coastguard Worker ? ScopedAStatus::ok()
328*4d7e907cSAndroid Build Coastguard Worker : ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
329*4d7e907cSAndroid Build Coastguard Worker } else if (session.sessionId == in_sessionId) {
330*4d7e907cSAndroid Build Coastguard Worker ALOGE("openEndpointSession: session ID %" PRId32 " is invalid: endpoint mismatch",
331*4d7e907cSAndroid Build Coastguard Worker in_sessionId);
332*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
333*4d7e907cSAndroid Build Coastguard Worker }
334*4d7e907cSAndroid Build Coastguard Worker }
335*4d7e907cSAndroid Build Coastguard Worker
336*4d7e907cSAndroid Build Coastguard Worker // Verify the initiator and destination are valid endpoints
337*4d7e907cSAndroid Build Coastguard Worker bool initiatorIsValid = findEndpoint(in_initiator, mEndpoints.begin(), mEndpoints.end());
338*4d7e907cSAndroid Build Coastguard Worker if (!initiatorIsValid) {
339*4d7e907cSAndroid Build Coastguard Worker ALOGE("openEndpointSession: initiator %" PRIu64 ":%" PRIu64 " is invalid",
340*4d7e907cSAndroid Build Coastguard Worker in_initiator.id, in_initiator.hubId);
341*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
342*4d7e907cSAndroid Build Coastguard Worker }
343*4d7e907cSAndroid Build Coastguard Worker bool destinationIsValid = findEndpoint(in_destination, &kMockEndpointInfos[0],
344*4d7e907cSAndroid Build Coastguard Worker &kMockEndpointInfos[kMockEndpointCount]);
345*4d7e907cSAndroid Build Coastguard Worker if (!destinationIsValid) {
346*4d7e907cSAndroid Build Coastguard Worker ALOGE("openEndpointSession: destination %" PRIu64 ":%" PRIu64 " is invalid",
347*4d7e907cSAndroid Build Coastguard Worker in_destination.id, in_destination.hubId);
348*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
349*4d7e907cSAndroid Build Coastguard Worker }
350*4d7e907cSAndroid Build Coastguard Worker
351*4d7e907cSAndroid Build Coastguard Worker mEndpointSessions.push_back({
352*4d7e907cSAndroid Build Coastguard Worker .sessionId = in_sessionId,
353*4d7e907cSAndroid Build Coastguard Worker .initiator = in_initiator,
354*4d7e907cSAndroid Build Coastguard Worker .peer = in_destination,
355*4d7e907cSAndroid Build Coastguard Worker .serviceDescriptor = in_serviceDescriptor,
356*4d7e907cSAndroid Build Coastguard Worker });
357*4d7e907cSAndroid Build Coastguard Worker
358*4d7e907cSAndroid Build Coastguard Worker if (mEndpointCallback != nullptr) {
359*4d7e907cSAndroid Build Coastguard Worker callback = mEndpointCallback;
360*4d7e907cSAndroid Build Coastguard Worker }
361*4d7e907cSAndroid Build Coastguard Worker }
362*4d7e907cSAndroid Build Coastguard Worker
363*4d7e907cSAndroid Build Coastguard Worker if (callback != nullptr) {
364*4d7e907cSAndroid Build Coastguard Worker callback->onEndpointSessionOpenComplete(in_sessionId);
365*4d7e907cSAndroid Build Coastguard Worker }
366*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::ok();
367*4d7e907cSAndroid Build Coastguard Worker };
368*4d7e907cSAndroid Build Coastguard Worker
sendMessageToEndpoint(int32_t in_sessionId,const Message & in_msg)369*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus ContextHub::sendMessageToEndpoint(int32_t in_sessionId, const Message& in_msg) {
370*4d7e907cSAndroid Build Coastguard Worker bool foundSession = false;
371*4d7e907cSAndroid Build Coastguard Worker std::shared_ptr<IEndpointCallback> callback = nullptr;
372*4d7e907cSAndroid Build Coastguard Worker {
373*4d7e907cSAndroid Build Coastguard Worker std::unique_lock<std::mutex> lock(mEndpointMutex);
374*4d7e907cSAndroid Build Coastguard Worker
375*4d7e907cSAndroid Build Coastguard Worker for (const EndpointSession& session : mEndpointSessions) {
376*4d7e907cSAndroid Build Coastguard Worker if (session.sessionId == in_sessionId) {
377*4d7e907cSAndroid Build Coastguard Worker foundSession = true;
378*4d7e907cSAndroid Build Coastguard Worker break;
379*4d7e907cSAndroid Build Coastguard Worker }
380*4d7e907cSAndroid Build Coastguard Worker }
381*4d7e907cSAndroid Build Coastguard Worker
382*4d7e907cSAndroid Build Coastguard Worker if (mEndpointCallback != nullptr) {
383*4d7e907cSAndroid Build Coastguard Worker callback = mEndpointCallback;
384*4d7e907cSAndroid Build Coastguard Worker }
385*4d7e907cSAndroid Build Coastguard Worker }
386*4d7e907cSAndroid Build Coastguard Worker
387*4d7e907cSAndroid Build Coastguard Worker if (!foundSession) {
388*4d7e907cSAndroid Build Coastguard Worker ALOGE("sendMessageToEndpoint: session ID %" PRId32 " is invalid", in_sessionId);
389*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
390*4d7e907cSAndroid Build Coastguard Worker }
391*4d7e907cSAndroid Build Coastguard Worker
392*4d7e907cSAndroid Build Coastguard Worker if (callback != nullptr) {
393*4d7e907cSAndroid Build Coastguard Worker if (in_msg.flags & Message::FLAG_REQUIRES_DELIVERY_STATUS) {
394*4d7e907cSAndroid Build Coastguard Worker MessageDeliveryStatus msgStatus = {};
395*4d7e907cSAndroid Build Coastguard Worker msgStatus.messageSequenceNumber = in_msg.sequenceNumber;
396*4d7e907cSAndroid Build Coastguard Worker msgStatus.errorCode = ErrorCode::OK;
397*4d7e907cSAndroid Build Coastguard Worker callback->onMessageDeliveryStatusReceived(in_sessionId, msgStatus);
398*4d7e907cSAndroid Build Coastguard Worker }
399*4d7e907cSAndroid Build Coastguard Worker
400*4d7e907cSAndroid Build Coastguard Worker // Echo the message back
401*4d7e907cSAndroid Build Coastguard Worker callback->onMessageReceived(in_sessionId, in_msg);
402*4d7e907cSAndroid Build Coastguard Worker }
403*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::ok();
404*4d7e907cSAndroid Build Coastguard Worker };
405*4d7e907cSAndroid Build Coastguard Worker
sendMessageDeliveryStatusToEndpoint(int32_t,const MessageDeliveryStatus &)406*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus ContextHub::sendMessageDeliveryStatusToEndpoint(
407*4d7e907cSAndroid Build Coastguard Worker int32_t /* in_sessionId */, const MessageDeliveryStatus& /* in_msgStatus */) {
408*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::ok();
409*4d7e907cSAndroid Build Coastguard Worker };
410*4d7e907cSAndroid Build Coastguard Worker
closeEndpointSession(int32_t in_sessionId,Reason)411*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus ContextHub::closeEndpointSession(int32_t in_sessionId, Reason /* in_reason */) {
412*4d7e907cSAndroid Build Coastguard Worker std::unique_lock<std::mutex> lock(mEndpointMutex);
413*4d7e907cSAndroid Build Coastguard Worker
414*4d7e907cSAndroid Build Coastguard Worker for (auto it = mEndpointSessions.begin(); it != mEndpointSessions.end(); ++it) {
415*4d7e907cSAndroid Build Coastguard Worker if (it->sessionId == in_sessionId) {
416*4d7e907cSAndroid Build Coastguard Worker mEndpointSessions.erase(it);
417*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::ok();
418*4d7e907cSAndroid Build Coastguard Worker }
419*4d7e907cSAndroid Build Coastguard Worker }
420*4d7e907cSAndroid Build Coastguard Worker ALOGE("closeEndpointSession: session ID %" PRId32 " is invalid", in_sessionId);
421*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
422*4d7e907cSAndroid Build Coastguard Worker };
423*4d7e907cSAndroid Build Coastguard Worker
endpointSessionOpenComplete(int32_t)424*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus ContextHub::endpointSessionOpenComplete(int32_t /* in_sessionId */) {
425*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::ok();
426*4d7e907cSAndroid Build Coastguard Worker };
427*4d7e907cSAndroid Build Coastguard Worker
428*4d7e907cSAndroid Build Coastguard Worker } // namespace aidl::android::hardware::contexthub
429