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 #ifndef CHRE_WIFI_OFFLOAD_FLATBUFFERS_SERIALIZATION_H_ 18 #define CHRE_WIFI_OFFLOAD_FLATBUFFERS_SERIALIZATION_H_ 19 20 #include <cstring> 21 22 /** 23 * @file 24 * Serialize/deserialize API for messages passed between WifiOffload nanoapp 25 * and Offload HAL. 26 */ 27 28 #include "chre/apps/wifi_offload/wifi_offload.h" 29 30 #include "chre/apps/wifi_offload/scan_config.h" 31 #include "chre/apps/wifi_offload/scan_result.h" 32 #include "chre/apps/wifi_offload/scan_result_message.h" 33 #include "chre/apps/wifi_offload/scan_stats.h" 34 35 namespace wifi_offload { 36 namespace fbs { 37 38 constexpr size_t kInitialFlatBufferSize = 256; 39 40 /** 41 * Serializes the input object into a given buffer. 42 * 43 * @param stats/config/results object to be serialized 44 * @param buffer Buffer to hold the result of serialization. Caller is 45 * responsible for allocating enough buffer size to hold the serialized 46 * data. If buffer is not large enough, serialization will abort and 47 * buffer will stay unmodified. If set to null, serialize function will 48 * return the required buffer size to hold the serialized data. 49 * @param buffer_len Length of the buffer allocated by the caller 50 * 51 * @return zero if buffer is not big enough to hold the serialized data, 52 * otherwise size of serialized data in buffer. 53 */ 54 size_t Serialize(const wifi_offload::ScanStats &stats, uint8_t *buffer, 55 size_t buffer_len); 56 size_t Serialize(const wifi_offload::ScanConfig &config, uint8_t *buffer, 57 size_t buffer_len); 58 size_t Serialize(const wifi_offload::Vector<wifi_offload::ScanResult> &results, 59 uint8_t *buffer, size_t buffer_len); 60 61 /** 62 * Deserializes from buffer into a given output object. 63 * 64 * @param buffer Buffer that holds the serialized data 65 * @param buffer_len Length of buffer 66 * @param stats/config/results Pointer to the output object to hold the result 67 * of deserialization 68 * 69 * @return true if deserialized successfully, false otherwise 70 */ 71 bool Deserialize(const uint8_t *buffer, size_t buffer_len, 72 wifi_offload::ScanStats *stats); 73 bool Deserialize(const uint8_t *buffer, size_t buffer_len, 74 wifi_offload::ScanConfig *config); 75 bool Deserialize(const uint8_t *buffer, size_t buffer_len, 76 wifi_offload::Vector<wifi_offload::ScanResult> *results); 77 78 template <typename SerializeType> 79 size_t Serialize(const SerializeType &obj, uint8_t *out_buffer, 80 size_t out_buffer_len, const char *log_tag = "") { 81 flatbuffers::FlatBufferBuilder builder(kInitialFlatBufferSize); 82 const auto fbs_obj = obj.Serialize(&builder); 83 builder.Finish(fbs_obj); 84 85 const uint8_t *data = builder.GetBufferPointer(); 86 const size_t size = builder.GetSize(); 87 88 if (out_buffer == nullptr) { 89 LOGI("%s output buffer is null. Returning serialized size %zu.", log_tag, 90 size); 91 return size; 92 } 93 94 if (size > out_buffer_len) { 95 LOGE("Serialized %s size %zu too big for provided buffer %zu; dropping", 96 log_tag, size, out_buffer_len); 97 return 0; 98 } 99 100 std::memcpy(out_buffer, data, size); 101 LOGI("Serialized %s to buffer size %zu", log_tag, size); 102 return size; 103 } 104 105 template <typename SerializeType> 106 bool Deserialize(const uint8_t *in_buffer, size_t in_buffer_len, 107 SerializeType *obj, const char *log_tag = "") { 108 if (in_buffer == nullptr || in_buffer_len == 0) { 109 LOGE("%s deserialize buffer is null or has size zero.", log_tag); 110 return false; 111 } 112 113 if (obj == nullptr) { 114 LOGE("%s deserialize output pointer is null.", log_tag); 115 return false; 116 } 117 118 flatbuffers::Verifier verifier(in_buffer, in_buffer_len); 119 if (!verifier.VerifyBuffer<typename SerializeType::FbsType>(nullptr)) { 120 LOGE("Failed to verify %s deserialize buffer.", log_tag); 121 return false; 122 } 123 124 const auto fbs_obj = 125 flatbuffers::GetRoot<typename SerializeType::FbsType>(in_buffer); 126 if (fbs_obj == nullptr) { 127 LOGE("Deserialized %s object is null or has missing members.", log_tag); 128 return false; 129 } 130 131 return obj->Deserialize(*fbs_obj); 132 } 133 134 } // namespace fbs 135 } // namespace wifi_offload 136 137 #endif // CHRE_WIFI_OFFLOAD_FLATBUFFERS_SERIALIZATION_H_ 138