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(), 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