/* * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "chre/platform/shared/host_protocol_chre.h" #include #include #include "chre/platform/log.h" #include "chre/platform/shared/host_messages_generated.h" using flatbuffers::FlatBufferBuilder; using flatbuffers::Offset; using flatbuffers::Vector; namespace chre { bool HostProtocolChre::decodeMessageFromHost(const void *message, size_t messageLen) { bool success = verifyMessage(message, messageLen); if (!success) { LOGE("Dropping invalid/corrupted message from host (length %zu)", messageLen); } else { const fbs::MessageContainer *container = fbs::GetMessageContainer(message); uint16_t hostClientId = container->host_addr()->client_id(); switch (container->message_type()) { case fbs::ChreMessage::NanoappMessage: { const auto *nanoappMsg = static_cast( container->message()); // Required field; verifier ensures that this is not null (though it // may be empty) const flatbuffers::Vector *msgData = nanoappMsg->message(); HostMessageHandlers::handleNanoappMessage( nanoappMsg->app_id(), nanoappMsg->message_type(), nanoappMsg->host_endpoint(), msgData->data(), msgData->size()); break; } case fbs::ChreMessage::HubInfoRequest: HostMessageHandlers::handleHubInfoRequest(hostClientId); break; case fbs::ChreMessage::NanoappListRequest: HostMessageHandlers::handleNanoappListRequest(hostClientId); break; case fbs::ChreMessage::LoadNanoappRequest: { const auto *request = static_cast( container->message()); const flatbuffers::Vector *appBinary = request->app_binary(); HostMessageHandlers::handleLoadNanoappRequest( hostClientId, request->transaction_id(), request->app_id(), request->app_version(), request->target_api_version(), appBinary->data(), appBinary->size()); break; } default: LOGW("Got invalid/unexpected message type %" PRIu8, static_cast(container->message_type())); success = false; } } return success; } void HostProtocolChre::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) { auto nameOffset = addStringAsByteVector(builder, name); auto vendorOffset = addStringAsByteVector(builder, vendor); auto toolchainOffset = addStringAsByteVector(builder, toolchain); auto response = fbs::CreateHubInfoResponse( builder, nameOffset, vendorOffset, toolchainOffset, legacyPlatformVersion, legacyToolchainVersion, peakMips, stoppedPower, sleepPower, peakPower, maxMessageLen, platformId, version); finalize(builder, fbs::ChreMessage::HubInfoResponse, response.Union(), hostClientId); } void HostProtocolChre::addNanoappListEntry( FlatBufferBuilder& builder, DynamicVector>& offsetVector, uint64_t appId, uint32_t appVersion, bool enabled, bool isSystemNanoapp) { auto offset = fbs::CreateNanoappListEntry( builder, appId, appVersion, enabled, isSystemNanoapp); if (!offsetVector.push_back(offset)) { LOGE("Couldn't push nanoapp list entry offset!"); } } void HostProtocolChre::finishNanoappListResponse( FlatBufferBuilder& builder, DynamicVector>& offsetVector, uint16_t hostClientId) { auto vectorOffset = builder.CreateVector>( offsetVector); auto response = fbs::CreateNanoappListResponse(builder, vectorOffset); finalize(builder, fbs::ChreMessage::NanoappListResponse, response.Union(), hostClientId); } void HostProtocolChre::encodeLoadNanoappResponse( flatbuffers::FlatBufferBuilder& builder, uint16_t hostClientId, uint32_t transactionId, bool success) { auto response = fbs::CreateLoadNanoappResponse(builder, transactionId, success); finalize(builder, fbs::ChreMessage::LoadNanoappResponse, response.Union(), hostClientId); } } // namespace chre