• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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