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 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 case fbs::ChreMessage::UnloadNanoappRequest: { 74 const auto *request = static_cast<const fbs::UnloadNanoappRequest *>( 75 container->message()); 76 HostMessageHandlers::handleUnloadNanoappRequest( 77 hostClientId, request->transaction_id(), request->app_id(), 78 request->allow_system_nanoapp_unload()); 79 break; 80 } 81 82 case fbs::ChreMessage::TimeSyncMessage: { 83 const auto *request = static_cast<const fbs::TimeSyncMessage *>( 84 container->message()); 85 HostMessageHandlers::handleTimeSyncMessage(request->offset()); 86 break; 87 } 88 89 case fbs::ChreMessage::DebugDumpRequest: 90 HostMessageHandlers::handleDebugDumpRequest(hostClientId); 91 break; 92 93 default: 94 LOGW("Got invalid/unexpected message type %" PRIu8, 95 static_cast<uint8_t>(container->message_type())); 96 success = false; 97 } 98 } 99 100 return success; 101 } 102 103 void HostProtocolChre::encodeHubInfoResponse( 104 FlatBufferBuilder& builder, const char *name, const char *vendor, 105 const char *toolchain, uint32_t legacyPlatformVersion, 106 uint32_t legacyToolchainVersion, float peakMips, float stoppedPower, 107 float sleepPower, float peakPower, uint32_t maxMessageLen, 108 uint64_t platformId, uint32_t version, uint16_t hostClientId) { 109 auto nameOffset = addStringAsByteVector(builder, name); 110 auto vendorOffset = addStringAsByteVector(builder, vendor); 111 auto toolchainOffset = addStringAsByteVector(builder, toolchain); 112 113 auto response = fbs::CreateHubInfoResponse( 114 builder, nameOffset, vendorOffset, toolchainOffset, legacyPlatformVersion, 115 legacyToolchainVersion, peakMips, stoppedPower, sleepPower, peakPower, 116 maxMessageLen, platformId, version); 117 finalize(builder, fbs::ChreMessage::HubInfoResponse, response.Union(), 118 hostClientId); 119 } 120 121 void HostProtocolChre::addNanoappListEntry( 122 FlatBufferBuilder& builder, 123 DynamicVector<Offset<fbs::NanoappListEntry>>& offsetVector, 124 uint64_t appId, uint32_t appVersion, bool enabled, bool isSystemNanoapp) { 125 auto offset = fbs::CreateNanoappListEntry( 126 builder, appId, appVersion, enabled, isSystemNanoapp); 127 if (!offsetVector.push_back(offset)) { 128 LOGE("Couldn't push nanoapp list entry offset!"); 129 } 130 } 131 132 void HostProtocolChre::finishNanoappListResponse( 133 FlatBufferBuilder& builder, 134 DynamicVector<Offset<fbs::NanoappListEntry>>& offsetVector, 135 uint16_t hostClientId) { 136 auto vectorOffset = builder.CreateVector<Offset<fbs::NanoappListEntry>>( 137 offsetVector); 138 auto response = fbs::CreateNanoappListResponse(builder, vectorOffset); 139 finalize(builder, fbs::ChreMessage::NanoappListResponse, response.Union(), 140 hostClientId); 141 } 142 143 void HostProtocolChre::encodeLoadNanoappResponse( 144 flatbuffers::FlatBufferBuilder& builder, uint16_t hostClientId, 145 uint32_t transactionId, bool success) { 146 auto response = fbs::CreateLoadNanoappResponse(builder, transactionId, 147 success); 148 finalize(builder, fbs::ChreMessage::LoadNanoappResponse, response.Union(), 149 hostClientId); 150 } 151 152 void HostProtocolChre::encodeUnloadNanoappResponse( 153 flatbuffers::FlatBufferBuilder& builder, uint16_t hostClientId, 154 uint32_t transactionId, bool success) { 155 auto response = fbs::CreateUnloadNanoappResponse(builder, transactionId, 156 success); 157 finalize(builder, fbs::ChreMessage::UnloadNanoappResponse, response.Union(), 158 hostClientId); 159 } 160 161 void HostProtocolChre::encodeLogMessages( 162 flatbuffers::FlatBufferBuilder& builder, const char *logBuffer, 163 size_t bufferSize) { 164 auto logBufferOffset = builder.CreateVector( 165 reinterpret_cast<const int8_t *>(logBuffer), bufferSize); 166 auto message = fbs::CreateLogMessage(builder, logBufferOffset); 167 finalize(builder, fbs::ChreMessage::LogMessage, message.Union()); 168 } 169 170 void HostProtocolChre::encodeDebugDumpData( 171 flatbuffers::FlatBufferBuilder& builder, uint16_t hostClientId, 172 const char *debugStr, size_t debugStrSize) { 173 auto debugStrOffset = builder.CreateVector( 174 reinterpret_cast<const int8_t *>(debugStr), debugStrSize); 175 auto message = fbs::CreateDebugDumpData(builder, debugStrOffset); 176 finalize(builder, fbs::ChreMessage::DebugDumpData, message.Union(), 177 hostClientId); 178 } 179 180 void HostProtocolChre::encodeDebugDumpResponse( 181 flatbuffers::FlatBufferBuilder& builder, uint16_t hostClientId, 182 bool success, uint32_t dataCount) { 183 auto response = fbs::CreateDebugDumpResponse(builder, success, dataCount); 184 finalize(builder, fbs::ChreMessage::DebugDumpResponse, response.Union(), 185 hostClientId); 186 } 187 188 void HostProtocolChre::encodeTimeSyncRequest( 189 flatbuffers::FlatBufferBuilder& builder) { 190 auto request = fbs::CreateTimeSyncRequest(builder); 191 finalize(builder, fbs::ChreMessage::TimeSyncRequest, request.Union()); 192 } 193 194 } // namespace chre 195