Home | History | Annotate | Download | only in shared
      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