1 /*
2  * Copyright 2020 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 "dumpsys/reflection_schema.h"
18 
19 #include <bluetooth/log.h>
20 
21 #include <string>
22 
23 #include "bundler_schema_generated.h"
24 #include "flatbuffers/flatbuffers.h"
25 #include "flatbuffers/idl.h"
26 #include "os/log.h"
27 
28 using namespace bluetooth;
29 
ReflectionSchema(const std::string & pre_bundled_schema)30 dumpsys::ReflectionSchema::ReflectionSchema(const std::string& pre_bundled_schema)
31     : pre_bundled_schema_(pre_bundled_schema) {
32   bundled_schema_ = flatbuffers::GetRoot<bluetooth::dumpsys::BundledSchema>(pre_bundled_schema_.data());
33   log::assert_that(bundled_schema_ != nullptr, "assert failed: bundled_schema_ != nullptr");
34 }
35 
GetNumberOfBundledSchemas() const36 int dumpsys::ReflectionSchema::GetNumberOfBundledSchemas() const {
37   return bundled_schema_->map()->size();
38 }
39 
GetTitle() const40 std::string dumpsys::ReflectionSchema::GetTitle() const {
41   return bundled_schema_->title()->str();
42 }
43 
GetRootName() const44 std::string dumpsys::ReflectionSchema::GetRootName() const {
45   return bundled_schema_->root_name()->str();
46 }
47 
GetRootReflectionSchema() const48 const reflection::Schema* dumpsys::ReflectionSchema::GetRootReflectionSchema() const {
49   return FindInReflectionSchema(GetRootName());
50 }
51 
FindInReflectionSchema(const std::string & name) const52 const reflection::Schema* dumpsys::ReflectionSchema::FindInReflectionSchema(const std::string& name) const {
53   const flatbuffers::Vector<flatbuffers::Offset<bluetooth::dumpsys::BundledSchemaMap>>* map = bundled_schema_->map();
54 
55   for (auto it = map->cbegin(); it != map->cend(); ++it) {
56     if (it->name()->str() == name) {
57       flatbuffers::Verifier verifier(reinterpret_cast<const uint8_t*>(it->data()->Data()), it->data()->size());
58       if (!reflection::VerifySchemaBuffer(verifier)) {
59         log::warn("Unable to verify schema buffer name:{}", name);
60         return nullptr;
61       }
62       return reflection::GetSchema(it->data()->Data());
63     }
64   }
65   return nullptr;
66 }
67 
PrintReflectionSchema() const68 void dumpsys::ReflectionSchema::PrintReflectionSchema() const {
69   const flatbuffers::Vector<flatbuffers::Offset<bluetooth::dumpsys::BundledSchemaMap>>* map = bundled_schema_->map();
70   log::info(
71       "Bundled schema title:{} root_name:{}",
72       bundled_schema_->title()->c_str(),
73       bundled_schema_->root_name()->c_str());
74   for (auto it = map->cbegin(); it != map->cend(); ++it) {
75     log::info("schema:{}", it->name()->c_str());
76   }
77 }
78 
VerifyReflectionSchema() const79 bool dumpsys::ReflectionSchema::VerifyReflectionSchema() const {
80   const flatbuffers::Vector<flatbuffers::Offset<bluetooth::dumpsys::BundledSchemaMap>>* map = bundled_schema_->map();
81 
82   for (auto it = map->cbegin(); it != map->cend(); ++it) {
83     flatbuffers::Verifier verifier(reinterpret_cast<const uint8_t*>(it->data()->Data()), it->data()->size());
84     if (!reflection::VerifySchemaBuffer(verifier)) {
85       return false;
86     }
87   }
88   return true;
89 }
90