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 #include "chre/platform/android/host_link.h"
18*84e33947SAndroid Build Coastguard Worker
19*84e33947SAndroid Build Coastguard Worker #include "chre/core/event_loop_manager.h"
20*84e33947SAndroid Build Coastguard Worker #include "chre/platform/shared/host_protocol_common.h"
21*84e33947SAndroid Build Coastguard Worker #include "chre/util/flatbuffers/helpers.h"
22*84e33947SAndroid Build Coastguard Worker #include "chre/util/macros.h"
23*84e33947SAndroid Build Coastguard Worker #include "chre/util/nested_data_ptr.h"
24*84e33947SAndroid Build Coastguard Worker #include "chre_api/chre/version.h"
25*84e33947SAndroid Build Coastguard Worker #include "chre_host/generated/host_messages_generated.h"
26*84e33947SAndroid Build Coastguard Worker
27*84e33947SAndroid Build Coastguard Worker namespace chre {
28*84e33947SAndroid Build Coastguard Worker
29*84e33947SAndroid Build Coastguard Worker static_assert(sizeof(uint16_t) <= sizeof(void *),
30*84e33947SAndroid Build Coastguard Worker "Pointer must at least fit a u16 for passing the host client ID");
31*84e33947SAndroid Build Coastguard Worker
32*84e33947SAndroid Build Coastguard Worker /**
33*84e33947SAndroid Build Coastguard Worker * Assigns a vector the contents of a C-style, null-terminated string.
34*84e33947SAndroid Build Coastguard Worker *
35*84e33947SAndroid Build Coastguard Worker * @param vector The vector to assign with the contents of a string.
36*84e33947SAndroid Build Coastguard Worker * @param str The string to assign.
37*84e33947SAndroid Build Coastguard Worker */
setVectorToString(std::vector<int8_t> * vector,const char * str)38*84e33947SAndroid Build Coastguard Worker void setVectorToString(std::vector<int8_t> *vector, const char *str) {
39*84e33947SAndroid Build Coastguard Worker *vector = std::vector<int8_t>(str, str + strlen(str));
40*84e33947SAndroid Build Coastguard Worker }
41*84e33947SAndroid Build Coastguard Worker
42*84e33947SAndroid Build Coastguard Worker /**
43*84e33947SAndroid Build Coastguard Worker * Sends a message to the host given a hostClientId.
44*84e33947SAndroid Build Coastguard Worker *
45*84e33947SAndroid Build Coastguard Worker * @param message The message to send to the host.
46*84e33947SAndroid Build Coastguard Worker * @param hostClientId The host who made the original request for which this is
47*84e33947SAndroid Build Coastguard Worker * a reply.
48*84e33947SAndroid Build Coastguard Worker */
49*84e33947SAndroid Build Coastguard Worker template <typename T>
sendFlatbufferToHost(T & message,uint16_t hostClientId)50*84e33947SAndroid Build Coastguard Worker void sendFlatbufferToHost(T &message, uint16_t hostClientId) {
51*84e33947SAndroid Build Coastguard Worker static_assert(fbs::ChreMessageTraits<typename T::TableType>::enum_value !=
52*84e33947SAndroid Build Coastguard Worker fbs::ChreMessage::NONE,
53*84e33947SAndroid Build Coastguard Worker "Only works for message types supported by ChreMessageUnion");
54*84e33947SAndroid Build Coastguard Worker
55*84e33947SAndroid Build Coastguard Worker fbs::MessageContainerT container;
56*84e33947SAndroid Build Coastguard Worker container.message.Set(std::move(message));
57*84e33947SAndroid Build Coastguard Worker container.host_addr.reset(new fbs::HostAddress(hostClientId));
58*84e33947SAndroid Build Coastguard Worker
59*84e33947SAndroid Build Coastguard Worker ChreFlatBufferBuilder builder;
60*84e33947SAndroid Build Coastguard Worker auto containerOffset = CreateMessageContainer(builder, &container, nullptr);
61*84e33947SAndroid Build Coastguard Worker builder.Finish(containerOffset);
62*84e33947SAndroid Build Coastguard Worker
63*84e33947SAndroid Build Coastguard Worker SocketServerSingleton::get()->sendToClientById(
64*84e33947SAndroid Build Coastguard Worker builder.GetBufferPointer(), builder.GetSize(), hostClientId);
65*84e33947SAndroid Build Coastguard Worker }
66*84e33947SAndroid Build Coastguard Worker
67*84e33947SAndroid Build Coastguard Worker /**
68*84e33947SAndroid Build Coastguard Worker * Handles a message directed to a nanoapp from the system.
69*84e33947SAndroid Build Coastguard Worker *
70*84e33947SAndroid Build Coastguard Worker * @param message The message to deliver to a nanoapp.
71*84e33947SAndroid Build Coastguard Worker */
handleNanoappMessage(const fbs::NanoappMessageT & message)72*84e33947SAndroid Build Coastguard Worker void handleNanoappMessage(const fbs::NanoappMessageT &message) {
73*84e33947SAndroid Build Coastguard Worker LOGD("handleNanoappMessage");
74*84e33947SAndroid Build Coastguard Worker HostCommsManager &manager =
75*84e33947SAndroid Build Coastguard Worker EventLoopManagerSingleton::get()->getHostCommsManager();
76*84e33947SAndroid Build Coastguard Worker manager.sendMessageToNanoappFromHost(
77*84e33947SAndroid Build Coastguard Worker message.app_id, message.message_type, message.host_endpoint,
78*84e33947SAndroid Build Coastguard Worker message.message.data(), message.message.size());
79*84e33947SAndroid Build Coastguard Worker }
80*84e33947SAndroid Build Coastguard Worker
81*84e33947SAndroid Build Coastguard Worker /**
82*84e33947SAndroid Build Coastguard Worker * Handles a request for information about this context hub instance.
83*84e33947SAndroid Build Coastguard Worker *
84*84e33947SAndroid Build Coastguard Worker * @param hostClientId The client ID on the host making the request.
85*84e33947SAndroid Build Coastguard Worker */
handleHubInfoRequest(uint16_t hostClientId)86*84e33947SAndroid Build Coastguard Worker void handleHubInfoRequest(uint16_t hostClientId) {
87*84e33947SAndroid Build Coastguard Worker LOGD("handleHubInfoRequest");
88*84e33947SAndroid Build Coastguard Worker fbs::HubInfoResponseT response;
89*84e33947SAndroid Build Coastguard Worker setVectorToString(&response.name, "CHRE on Android");
90*84e33947SAndroid Build Coastguard Worker setVectorToString(&response.vendor, "Google");
91*84e33947SAndroid Build Coastguard Worker setVectorToString(
92*84e33947SAndroid Build Coastguard Worker &response.toolchain,
93*84e33947SAndroid Build Coastguard Worker "Android NDK API 26 (clang " STRINGIFY(__clang_major__) "." STRINGIFY(
94*84e33947SAndroid Build Coastguard Worker __clang_minor__) "." STRINGIFY(__clang_patchlevel__) ")");
95*84e33947SAndroid Build Coastguard Worker response.platform_version = 0;
96*84e33947SAndroid Build Coastguard Worker response.toolchain_version = ((__clang_major__ & 0xFF) << 24) |
97*84e33947SAndroid Build Coastguard Worker ((__clang_minor__ & 0xFF) << 16) |
98*84e33947SAndroid Build Coastguard Worker (__clang_patchlevel__ & 0xFFFF);
99*84e33947SAndroid Build Coastguard Worker response.peak_mips = 1000;
100*84e33947SAndroid Build Coastguard Worker response.stopped_power = 1000;
101*84e33947SAndroid Build Coastguard Worker response.sleep_power = 1000;
102*84e33947SAndroid Build Coastguard Worker response.peak_power = 10000;
103*84e33947SAndroid Build Coastguard Worker response.max_msg_len = CHRE_MESSAGE_TO_HOST_MAX_SIZE;
104*84e33947SAndroid Build Coastguard Worker response.platform_id = chreGetPlatformId();
105*84e33947SAndroid Build Coastguard Worker response.chre_platform_version = chreGetVersion();
106*84e33947SAndroid Build Coastguard Worker
107*84e33947SAndroid Build Coastguard Worker sendFlatbufferToHost(response, hostClientId);
108*84e33947SAndroid Build Coastguard Worker }
109*84e33947SAndroid Build Coastguard Worker
110*84e33947SAndroid Build Coastguard Worker /**
111*84e33947SAndroid Build Coastguard Worker * Handles a request from the host for a list of nanoapps.
112*84e33947SAndroid Build Coastguard Worker *
113*84e33947SAndroid Build Coastguard Worker * @param hostClientId The client ID on the host making the request.
114*84e33947SAndroid Build Coastguard Worker */
handleNanoappListRequest(uint16_t hostClientId)115*84e33947SAndroid Build Coastguard Worker void handleNanoappListRequest(uint16_t hostClientId) {
116*84e33947SAndroid Build Coastguard Worker auto callback = [](uint16_t /*type*/, void *data, void * /*extraData*/) {
117*84e33947SAndroid Build Coastguard Worker uint16_t cbHostClientId = NestedDataPtr<uint16_t>(data);
118*84e33947SAndroid Build Coastguard Worker
119*84e33947SAndroid Build Coastguard Worker auto nanoappAddCallback = [](const Nanoapp *nanoapp, void *data) {
120*84e33947SAndroid Build Coastguard Worker auto response = static_cast<fbs::NanoappListResponseT *>(data);
121*84e33947SAndroid Build Coastguard Worker auto nanoappListEntry =
122*84e33947SAndroid Build Coastguard Worker std::unique_ptr<fbs::NanoappListEntryT>(new fbs::NanoappListEntryT());
123*84e33947SAndroid Build Coastguard Worker nanoappListEntry->app_id = nanoapp->getAppId();
124*84e33947SAndroid Build Coastguard Worker nanoappListEntry->version = nanoapp->getAppVersion();
125*84e33947SAndroid Build Coastguard Worker nanoappListEntry->enabled = true;
126*84e33947SAndroid Build Coastguard Worker nanoappListEntry->is_system = nanoapp->isSystemNanoapp();
127*84e33947SAndroid Build Coastguard Worker nanoappListEntry->permissions = nanoapp->getAppPermissions();
128*84e33947SAndroid Build Coastguard Worker response->nanoapps.push_back(std::move(nanoappListEntry));
129*84e33947SAndroid Build Coastguard Worker };
130*84e33947SAndroid Build Coastguard Worker
131*84e33947SAndroid Build Coastguard Worker fbs::NanoappListResponseT response;
132*84e33947SAndroid Build Coastguard Worker EventLoop &eventLoop = EventLoopManagerSingleton::get()->getEventLoop();
133*84e33947SAndroid Build Coastguard Worker eventLoop.forEachNanoapp(nanoappAddCallback, &response);
134*84e33947SAndroid Build Coastguard Worker
135*84e33947SAndroid Build Coastguard Worker sendFlatbufferToHost(response, cbHostClientId);
136*84e33947SAndroid Build Coastguard Worker };
137*84e33947SAndroid Build Coastguard Worker
138*84e33947SAndroid Build Coastguard Worker LOGD("handleNanoappListRequest");
139*84e33947SAndroid Build Coastguard Worker EventLoopManagerSingleton::get()->deferCallback(
140*84e33947SAndroid Build Coastguard Worker SystemCallbackType::NanoappListResponse,
141*84e33947SAndroid Build Coastguard Worker NestedDataPtr<uint16_t>(hostClientId), callback);
142*84e33947SAndroid Build Coastguard Worker }
143*84e33947SAndroid Build Coastguard Worker
144*84e33947SAndroid Build Coastguard Worker /**
145*84e33947SAndroid Build Coastguard Worker * Handles a request to load a nanoapp.
146*84e33947SAndroid Build Coastguard Worker *
147*84e33947SAndroid Build Coastguard Worker * @param hostClientId The client ID on the host making the request.
148*84e33947SAndroid Build Coastguard Worker * @param loadRequest The details of the nanoapp load request.
149*84e33947SAndroid Build Coastguard Worker */
handleLoadNanoappRequest(uint16_t hostClientId,const fbs::LoadNanoappRequestT & loadRequest)150*84e33947SAndroid Build Coastguard Worker void handleLoadNanoappRequest(uint16_t hostClientId,
151*84e33947SAndroid Build Coastguard Worker const fbs::LoadNanoappRequestT &loadRequest) {
152*84e33947SAndroid Build Coastguard Worker LOGD("handleLoadNanoappRequest");
153*84e33947SAndroid Build Coastguard Worker }
154*84e33947SAndroid Build Coastguard Worker
155*84e33947SAndroid Build Coastguard Worker /**
156*84e33947SAndroid Build Coastguard Worker * Handles a request to unload a nanoapp.
157*84e33947SAndroid Build Coastguard Worker *
158*84e33947SAndroid Build Coastguard Worker * @param hostClientId The client ID on the host making the request.
159*84e33947SAndroid Build Coastguard Worker * @param unloadRequest The details of the nanoapp unload request.
160*84e33947SAndroid Build Coastguard Worker */
handleUnloadNanoappRequest(uint16_t hostClientId,const fbs::UnloadNanoappRequestT & unloadRequest)161*84e33947SAndroid Build Coastguard Worker void handleUnloadNanoappRequest(
162*84e33947SAndroid Build Coastguard Worker uint16_t hostClientId, const fbs::UnloadNanoappRequestT &unloadRequest) {
163*84e33947SAndroid Build Coastguard Worker LOGD("handleUnloadNanoappRequest");
164*84e33947SAndroid Build Coastguard Worker }
165*84e33947SAndroid Build Coastguard Worker
166*84e33947SAndroid Build Coastguard Worker /**
167*84e33947SAndroid Build Coastguard Worker * Handles a request for a debug dump.
168*84e33947SAndroid Build Coastguard Worker *
169*84e33947SAndroid Build Coastguard Worker * @param hostClientId The client OD on the host making the request.
170*84e33947SAndroid Build Coastguard Worker */
handleDebugDumpRequest(uint16_t hostClientId)171*84e33947SAndroid Build Coastguard Worker void handleDebugDumpRequest(uint16_t hostClientId) {
172*84e33947SAndroid Build Coastguard Worker LOGD("handleDebugDumpRequest");
173*84e33947SAndroid Build Coastguard Worker }
174*84e33947SAndroid Build Coastguard Worker
handleMessageFromHost(void * message,size_t length)175*84e33947SAndroid Build Coastguard Worker bool handleMessageFromHost(void *message, size_t length) {
176*84e33947SAndroid Build Coastguard Worker bool success = HostProtocolCommon::verifyMessage(message, length);
177*84e33947SAndroid Build Coastguard Worker if (success) {
178*84e33947SAndroid Build Coastguard Worker fbs::MessageContainerT container;
179*84e33947SAndroid Build Coastguard Worker fbs::GetMessageContainer(message)->UnPackTo(&container);
180*84e33947SAndroid Build Coastguard Worker uint16_t hostClientId = container.host_addr->client_id();
181*84e33947SAndroid Build Coastguard Worker switch (container.message.type) {
182*84e33947SAndroid Build Coastguard Worker case fbs::ChreMessage::NanoappMessage:
183*84e33947SAndroid Build Coastguard Worker handleNanoappMessage(*container.message.AsNanoappMessage());
184*84e33947SAndroid Build Coastguard Worker break;
185*84e33947SAndroid Build Coastguard Worker
186*84e33947SAndroid Build Coastguard Worker case fbs::ChreMessage::HubInfoRequest:
187*84e33947SAndroid Build Coastguard Worker handleHubInfoRequest(hostClientId);
188*84e33947SAndroid Build Coastguard Worker break;
189*84e33947SAndroid Build Coastguard Worker
190*84e33947SAndroid Build Coastguard Worker case fbs::ChreMessage::NanoappListRequest:
191*84e33947SAndroid Build Coastguard Worker handleNanoappListRequest(hostClientId);
192*84e33947SAndroid Build Coastguard Worker break;
193*84e33947SAndroid Build Coastguard Worker
194*84e33947SAndroid Build Coastguard Worker case fbs::ChreMessage::LoadNanoappRequest:
195*84e33947SAndroid Build Coastguard Worker handleLoadNanoappRequest(hostClientId,
196*84e33947SAndroid Build Coastguard Worker *container.message.AsLoadNanoappRequest());
197*84e33947SAndroid Build Coastguard Worker break;
198*84e33947SAndroid Build Coastguard Worker
199*84e33947SAndroid Build Coastguard Worker case fbs::ChreMessage::UnloadNanoappRequest:
200*84e33947SAndroid Build Coastguard Worker handleUnloadNanoappRequest(hostClientId,
201*84e33947SAndroid Build Coastguard Worker *container.message.AsUnloadNanoappRequest());
202*84e33947SAndroid Build Coastguard Worker break;
203*84e33947SAndroid Build Coastguard Worker
204*84e33947SAndroid Build Coastguard Worker case fbs::ChreMessage::DebugDumpRequest:
205*84e33947SAndroid Build Coastguard Worker handleDebugDumpRequest(hostClientId);
206*84e33947SAndroid Build Coastguard Worker break;
207*84e33947SAndroid Build Coastguard Worker
208*84e33947SAndroid Build Coastguard Worker default:
209*84e33947SAndroid Build Coastguard Worker LOGW("Got invalid/unexpected message type %" PRIu8,
210*84e33947SAndroid Build Coastguard Worker static_cast<uint8_t>(container.message.type));
211*84e33947SAndroid Build Coastguard Worker success = false;
212*84e33947SAndroid Build Coastguard Worker }
213*84e33947SAndroid Build Coastguard Worker }
214*84e33947SAndroid Build Coastguard Worker
215*84e33947SAndroid Build Coastguard Worker return success;
216*84e33947SAndroid Build Coastguard Worker }
217*84e33947SAndroid Build Coastguard Worker
218*84e33947SAndroid Build Coastguard Worker } // namespace chre
219