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_host/host_protocol_host.h" 18 19 #include <inttypes.h> 20 #include <string.h> 21 22 #include "chre_host/log.h" 23 24 using flatbuffers::FlatBufferBuilder; 25 using flatbuffers::Offset; 26 27 // Aliased for consistency with the way these symbols are referenced in 28 // CHRE-side code 29 namespace fbs = ::chre::fbs; 30 31 namespace android { 32 namespace chre { 33 34 const char *getStringFromByteVector(const std::vector<int8_t>& vec) { 35 constexpr int8_t kNullChar = static_cast<int8_t>('\0'); 36 const char *str = nullptr; 37 38 // Check that the vector is present, non-empty, and null-terminated 39 if (vec.size() > 0 && vec[vec.size() - 1] == kNullChar) { 40 str = reinterpret_cast<const char *>(vec.data()); 41 } 42 43 return str; 44 } 45 46 bool HostProtocolHost::decodeMessageFromChre( 47 const void *message, size_t messageLen, IChreMessageHandlers& handlers) { 48 bool success = verifyMessage(message, messageLen); 49 if (success) { 50 std::unique_ptr<fbs::MessageContainerT> container = 51 fbs::UnPackMessageContainer(message); 52 fbs::ChreMessageUnion& msg = container->message; 53 54 switch (container->message.type) { 55 case fbs::ChreMessage::NanoappMessage: 56 handlers.handleNanoappMessage(*msg.AsNanoappMessage()); 57 break; 58 59 case fbs::ChreMessage::HubInfoResponse: 60 handlers.handleHubInfoResponse(*msg.AsHubInfoResponse()); 61 break; 62 63 case fbs::ChreMessage::NanoappListResponse: 64 handlers.handleNanoappListResponse(*msg.AsNanoappListResponse()); 65 break; 66 67 case fbs::ChreMessage::LoadNanoappResponse: 68 handlers.handleLoadNanoappResponse(*msg.AsLoadNanoappResponse()); 69 break; 70 71 case fbs::ChreMessage::UnloadNanoappResponse: 72 handlers.handleUnloadNanoappResponse(*msg.AsUnloadNanoappResponse()); 73 break; 74 75 case fbs::ChreMessage::DebugDumpData: 76 handlers.handleDebugDumpData(*msg.AsDebugDumpData()); 77 break; 78 79 case fbs::ChreMessage::DebugDumpResponse: 80 handlers.handleDebugDumpResponse(*msg.AsDebugDumpResponse()); 81 break; 82 83 default: 84 LOGW("Got invalid/unexpected message type %" PRIu8, 85 static_cast<uint8_t>(msg.type)); 86 success = false; 87 } 88 } 89 90 return success; 91 } 92 93 void HostProtocolHost::encodeHubInfoRequest(FlatBufferBuilder& builder) { 94 auto request = fbs::CreateHubInfoRequest(builder); 95 finalize(builder, fbs::ChreMessage::HubInfoRequest, request.Union()); 96 } 97 98 void HostProtocolHost::encodeFragmentedLoadNanoappRequest( 99 flatbuffers::FlatBufferBuilder& builder, 100 const FragmentedLoadRequest& request) { 101 encodeLoadNanoappRequest( 102 builder, request.transactionId, request.appId, request.appVersion, 103 request.targetApiVersion, request.binary, request.fragmentId, 104 request.appTotalSizeBytes); 105 } 106 107 void HostProtocolHost::encodeNanoappListRequest(FlatBufferBuilder& builder) { 108 auto request = fbs::CreateNanoappListRequest(builder); 109 finalize(builder, fbs::ChreMessage::NanoappListRequest, request.Union()); 110 } 111 112 void HostProtocolHost::encodeUnloadNanoappRequest( 113 FlatBufferBuilder& builder, uint32_t transactionId, uint64_t appId, 114 bool allowSystemNanoappUnload) { 115 auto request = fbs::CreateUnloadNanoappRequest( 116 builder, transactionId, appId, allowSystemNanoappUnload); 117 finalize(builder, fbs::ChreMessage::UnloadNanoappRequest, request.Union()); 118 } 119 120 void HostProtocolHost::encodeTimeSyncMessage(FlatBufferBuilder& builder, 121 int64_t offset) { 122 auto request = fbs::CreateTimeSyncMessage(builder, offset); 123 finalize(builder, fbs::ChreMessage::TimeSyncMessage, request.Union()); 124 } 125 126 void HostProtocolHost::encodeDebugDumpRequest(FlatBufferBuilder& builder) { 127 auto request = fbs::CreateDebugDumpRequest(builder); 128 finalize(builder, fbs::ChreMessage::DebugDumpRequest, request.Union()); 129 } 130 131 bool HostProtocolHost::extractHostClientIdAndType( 132 const void *message, size_t messageLen, uint16_t *hostClientId, 133 ::chre::fbs::ChreMessage *messageType) { 134 bool success = false; 135 if (hostClientId != nullptr && messageType != nullptr) { 136 success = verifyMessage(message, messageLen); 137 138 if (success) { 139 const fbs::MessageContainer *container = fbs::GetMessageContainer(message); 140 // host_addr guaranteed to be non-null via verifyMessage (it's a required 141 // field) 142 *hostClientId = container->host_addr()->client_id(); 143 *messageType = container->message_type(); 144 } 145 } 146 147 return success; 148 } 149 150 bool HostProtocolHost::mutateHostClientId(void *message, size_t messageLen, 151 uint16_t hostClientId) { 152 bool success = verifyMessage(message, messageLen); 153 154 if (!success) { 155 LOGE("Message verification failed - can't mutate host ID"); 156 } else { 157 fbs::MessageContainer *container = fbs::GetMutableMessageContainer(message); 158 // host_addr guaranteed to be non-null via verifyMessage (it's a required 159 // field) 160 container->mutable_host_addr()->mutate_client_id(hostClientId); 161 success = true; 162 } 163 164 return success; 165 } 166 167 void HostProtocolHost::encodeLoadNanoappRequest( 168 FlatBufferBuilder& builder, uint32_t transactionId, uint64_t appId, 169 uint32_t appVersion, uint32_t targetApiVersion, 170 const std::vector<uint8_t>& nanoappBinary, uint32_t fragmentId, 171 size_t appTotalSizeBytes) { 172 auto appBinary = builder.CreateVector(nanoappBinary); 173 auto request = fbs::CreateLoadNanoappRequest( 174 builder, transactionId, appId, appVersion, targetApiVersion, appBinary, 175 fragmentId, appTotalSizeBytes); 176 finalize(builder, fbs::ChreMessage::LoadNanoappRequest, request.Union()); 177 } 178 179 } // namespace chre 180 } // namespace android 181