1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "chre/platform/shared/host_protocol_chre.h"
18 
19 #include <inttypes.h>
20 #include <string.h>
21 
22 #include "chre/platform/log.h"
23 #include "chre/platform/shared/host_messages_generated.h"
24 
25 using flatbuffers::FlatBufferBuilder;
26 using flatbuffers::Offset;
27 using flatbuffers::Vector;
28 
29 namespace chre {
30 
decodeMessageFromHost(const void * message,size_t messageLen)31 bool HostProtocolChre::decodeMessageFromHost(const void *message,
32                                              size_t messageLen) {
33   bool success = verifyMessage(message, messageLen);
34   if (!success) {
35     LOGE("Dropping invalid/corrupted message from host (length %zu)",
36          messageLen);
37   } else {
38     const fbs::MessageContainer *container = fbs::GetMessageContainer(message);
39     uint16_t hostClientId = container->host_addr()->client_id();
40 
41     switch (container->message_type()) {
42       case fbs::ChreMessage::NanoappMessage: {
43         const auto *nanoappMsg = static_cast<const fbs::NanoappMessage *>(
44             container->message());
45         // Required field; verifier ensures that this is not null (though it
46         // may be empty)
47         const flatbuffers::Vector<uint8_t> *msgData = nanoappMsg->message();
48         HostMessageHandlers::handleNanoappMessage(
49             nanoappMsg->app_id(), nanoappMsg->message_type(),
50             nanoappMsg->host_endpoint(), msgData->data(), msgData->size());
51         break;
52       }
53 
54       case fbs::ChreMessage::HubInfoRequest:
55         HostMessageHandlers::handleHubInfoRequest(hostClientId);
56         break;
57 
58       case fbs::ChreMessage::NanoappListRequest:
59         HostMessageHandlers::handleNanoappListRequest(hostClientId);
60         break;
61 
62       case fbs::ChreMessage::LoadNanoappRequest: {
63         const auto *request = static_cast<const fbs::LoadNanoappRequest *>(
64             container->message());
65         const flatbuffers::Vector<uint8_t> *appBinary = request->app_binary();
66         HostMessageHandlers::handleLoadNanoappRequest(
67             hostClientId, request->transaction_id(), request->app_id(),
68             request->app_version(), request->target_api_version(),
69             appBinary->data(), appBinary->size());
70         break;
71       }
72 
73       default:
74         LOGW("Got invalid/unexpected message type %" PRIu8,
75              static_cast<uint8_t>(container->message_type()));
76         success = false;
77     }
78   }
79 
80   return success;
81 }
82 
encodeHubInfoResponse(FlatBufferBuilder & builder,const char * name,const char * vendor,const char * toolchain,uint32_t legacyPlatformVersion,uint32_t legacyToolchainVersion,float peakMips,float stoppedPower,float sleepPower,float peakPower,uint32_t maxMessageLen,uint64_t platformId,uint32_t version,uint16_t hostClientId)83 void HostProtocolChre::encodeHubInfoResponse(
84     FlatBufferBuilder& builder, const char *name, const char *vendor,
85     const char *toolchain, uint32_t legacyPlatformVersion,
86     uint32_t legacyToolchainVersion, float peakMips, float stoppedPower,
87     float sleepPower, float peakPower, uint32_t maxMessageLen,
88     uint64_t platformId, uint32_t version, uint16_t hostClientId) {
89   auto nameOffset = addStringAsByteVector(builder, name);
90   auto vendorOffset = addStringAsByteVector(builder, vendor);
91   auto toolchainOffset = addStringAsByteVector(builder, toolchain);
92 
93   auto response = fbs::CreateHubInfoResponse(
94       builder, nameOffset, vendorOffset, toolchainOffset, legacyPlatformVersion,
95       legacyToolchainVersion, peakMips, stoppedPower, sleepPower, peakPower,
96       maxMessageLen, platformId, version);
97   finalize(builder, fbs::ChreMessage::HubInfoResponse, response.Union(),
98            hostClientId);
99 }
100 
addNanoappListEntry(FlatBufferBuilder & builder,DynamicVector<Offset<fbs::NanoappListEntry>> & offsetVector,uint64_t appId,uint32_t appVersion,bool enabled,bool isSystemNanoapp)101 void HostProtocolChre::addNanoappListEntry(
102     FlatBufferBuilder& builder,
103     DynamicVector<Offset<fbs::NanoappListEntry>>& offsetVector,
104     uint64_t appId, uint32_t appVersion, bool enabled, bool isSystemNanoapp) {
105   auto offset = fbs::CreateNanoappListEntry(
106       builder, appId, appVersion, enabled, isSystemNanoapp);
107   if (!offsetVector.push_back(offset)) {
108     LOGE("Couldn't push nanoapp list entry offset!");
109   }
110 }
111 
finishNanoappListResponse(FlatBufferBuilder & builder,DynamicVector<Offset<fbs::NanoappListEntry>> & offsetVector,uint16_t hostClientId)112 void HostProtocolChre::finishNanoappListResponse(
113     FlatBufferBuilder& builder,
114     DynamicVector<Offset<fbs::NanoappListEntry>>& offsetVector,
115     uint16_t hostClientId) {
116   auto vectorOffset = builder.CreateVector<Offset<fbs::NanoappListEntry>>(
117       offsetVector);
118   auto response = fbs::CreateNanoappListResponse(builder, vectorOffset);
119   finalize(builder, fbs::ChreMessage::NanoappListResponse, response.Union(),
120            hostClientId);
121 }
122 
encodeLoadNanoappResponse(flatbuffers::FlatBufferBuilder & builder,uint16_t hostClientId,uint32_t transactionId,bool success)123 void HostProtocolChre::encodeLoadNanoappResponse(
124     flatbuffers::FlatBufferBuilder& builder, uint16_t hostClientId,
125     uint32_t transactionId, bool success) {
126   auto response = fbs::CreateLoadNanoappResponse(builder, transactionId,
127                                                  success);
128   finalize(builder, fbs::ChreMessage::LoadNanoappResponse, response.Union(),
129            hostClientId);
130 }
131 
132 }  // namespace chre
133