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