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 25using flatbuffers::FlatBufferBuilder; 26using flatbuffers::Offset; 27using flatbuffers::Vector; 28 29namespace chre { 30 31bool 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 83void 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 101void 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 112void 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 123void 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