blob: 28c68a8ee3e61971b92bfd5bbc7099feff81837c [file] [log] [blame]
#include <fidl/my.config.lib/cpp/wire.h>
#include <fidl/my.config.lib/cpp/wire_types.h>
#include <lib/fidl/llcpp/coding.h>
#include <lib/fidl/llcpp/message.h>
#include <lib/fidl/llcpp/traits.h>
#include <lib/zx/vmo.h>
#include <zircon/assert.h>
#include <zircon/process.h>
#include <zircon/processargs.h>
#include <zircon/status.h>
#include <zircon/syscalls.h>
#include <iostream>
#include <string>
#include <vector>
#include "cpp_elf_config_lib.h"
namespace cpp_elf_config_lib {
void Config::record_to_inspect(inspect::Inspector* inspector) {
inspect::Node inspect_config = inspector->GetRoot().CreateChild("config");
inspect_config.CreateBool("my_flag", this->my_flag(), inspector);
inspect_config.CreateInt("my_int16", this->my_int16(), inspector);
inspect_config.CreateInt("my_int32", this->my_int32(), inspector);
inspect_config.CreateInt("my_int64", this->my_int64(), inspector);
inspect_config.CreateInt("my_int8", this->my_int8(), inspector);
inspect_config.CreateString("my_string", this->my_string(), inspector);
inspect_config.CreateUint("my_uint16", this->my_uint16(), inspector);
inspect_config.CreateUint("my_uint32", this->my_uint32(), inspector);
inspect_config.CreateUint("my_uint64", this->my_uint64(), inspector);
inspect_config.CreateUint("my_uint8", this->my_uint8(), inspector);
auto my_vector_of_flag = inspect_config.CreateUintArray(
"my_vector_of_flag", this->my_vector_of_flag().size());
for (size_t i = 0; i < this->my_vector_of_flag().size(); i++) {
my_vector_of_flag.Set(i, this->my_vector_of_flag()[i]);
}
inspector->emplace(std::move(my_vector_of_flag));
auto my_vector_of_int16 = inspect_config.CreateIntArray(
"my_vector_of_int16", this->my_vector_of_int16().size());
for (size_t i = 0; i < this->my_vector_of_int16().size(); i++) {
my_vector_of_int16.Set(i, this->my_vector_of_int16()[i]);
}
inspector->emplace(std::move(my_vector_of_int16));
auto my_vector_of_int32 = inspect_config.CreateIntArray(
"my_vector_of_int32", this->my_vector_of_int32().size());
for (size_t i = 0; i < this->my_vector_of_int32().size(); i++) {
my_vector_of_int32.Set(i, this->my_vector_of_int32()[i]);
}
inspector->emplace(std::move(my_vector_of_int32));
auto my_vector_of_int64 = inspect_config.CreateIntArray(
"my_vector_of_int64", this->my_vector_of_int64().size());
for (size_t i = 0; i < this->my_vector_of_int64().size(); i++) {
my_vector_of_int64.Set(i, this->my_vector_of_int64()[i]);
}
inspector->emplace(std::move(my_vector_of_int64));
auto my_vector_of_int8 = inspect_config.CreateIntArray(
"my_vector_of_int8", this->my_vector_of_int8().size());
for (size_t i = 0; i < this->my_vector_of_int8().size(); i++) {
my_vector_of_int8.Set(i, this->my_vector_of_int8()[i]);
}
inspector->emplace(std::move(my_vector_of_int8));
auto my_vector_of_string = inspect_config.CreateStringArray(
"my_vector_of_string", this->my_vector_of_string().size());
for (size_t i = 0; i < this->my_vector_of_string().size(); i++) {
auto ref = std::string_view(this->my_vector_of_string()[i].data());
my_vector_of_string.Set(i, ref);
}
inspector->emplace(std::move(my_vector_of_string));
auto my_vector_of_uint16 = inspect_config.CreateUintArray(
"my_vector_of_uint16", this->my_vector_of_uint16().size());
for (size_t i = 0; i < this->my_vector_of_uint16().size(); i++) {
my_vector_of_uint16.Set(i, this->my_vector_of_uint16()[i]);
}
inspector->emplace(std::move(my_vector_of_uint16));
auto my_vector_of_uint32 = inspect_config.CreateUintArray(
"my_vector_of_uint32", this->my_vector_of_uint32().size());
for (size_t i = 0; i < this->my_vector_of_uint32().size(); i++) {
my_vector_of_uint32.Set(i, this->my_vector_of_uint32()[i]);
}
inspector->emplace(std::move(my_vector_of_uint32));
auto my_vector_of_uint64 = inspect_config.CreateUintArray(
"my_vector_of_uint64", this->my_vector_of_uint64().size());
for (size_t i = 0; i < this->my_vector_of_uint64().size(); i++) {
my_vector_of_uint64.Set(i, this->my_vector_of_uint64()[i]);
}
inspector->emplace(std::move(my_vector_of_uint64));
auto my_vector_of_uint8 = inspect_config.CreateUintArray(
"my_vector_of_uint8", this->my_vector_of_uint8().size());
for (size_t i = 0; i < this->my_vector_of_uint8().size(); i++) {
my_vector_of_uint8.Set(i, this->my_vector_of_uint8()[i]);
}
inspector->emplace(std::move(my_vector_of_uint8));
inspector->emplace(std::move(inspect_config));
}
std::ostream& operator<<(std::ostream& os, const Config& c) {
os << " my_flag: " << c.my_flag() << std::endl;
os << " my_int16: " << c.my_int16() << std::endl;
os << " my_int32: " << c.my_int32() << std::endl;
os << " my_int64: " << c.my_int64() << std::endl;
os << " my_int8: " << c.my_int8() << std::endl;
os << " my_string: " << c.my_string() << std::endl;
os << " my_uint16: " << c.my_uint16() << std::endl;
os << " my_uint32: " << c.my_uint32() << std::endl;
os << " my_uint64: " << c.my_uint64() << std::endl;
os << " my_uint8: " << c.my_uint8() << std::endl;
os << " my_vector_of_flag: [" << std::endl;
for (auto value : c.my_vector_of_flag()) {
os << " " << value << "," << std::endl;
}
os << "]" << std::endl;
os << " my_vector_of_int16: [" << std::endl;
for (auto value : c.my_vector_of_int16()) {
os << " " << value << "," << std::endl;
}
os << "]" << std::endl;
os << " my_vector_of_int32: [" << std::endl;
for (auto value : c.my_vector_of_int32()) {
os << " " << value << "," << std::endl;
}
os << "]" << std::endl;
os << " my_vector_of_int64: [" << std::endl;
for (auto value : c.my_vector_of_int64()) {
os << " " << value << "," << std::endl;
}
os << "]" << std::endl;
os << " my_vector_of_int8: [" << std::endl;
for (auto value : c.my_vector_of_int8()) {
os << " " << value << "," << std::endl;
}
os << "]" << std::endl;
os << " my_vector_of_string: [" << std::endl;
for (auto value : c.my_vector_of_string()) {
os << " " << value << "," << std::endl;
}
os << "]" << std::endl;
os << " my_vector_of_uint16: [" << std::endl;
for (auto value : c.my_vector_of_uint16()) {
os << " " << value << "," << std::endl;
}
os << "]" << std::endl;
os << " my_vector_of_uint32: [" << std::endl;
for (auto value : c.my_vector_of_uint32()) {
os << " " << value << "," << std::endl;
}
os << "]" << std::endl;
os << " my_vector_of_uint64: [" << std::endl;
for (auto value : c.my_vector_of_uint64()) {
os << " " << value << "," << std::endl;
}
os << "]" << std::endl;
os << " my_vector_of_uint8: [" << std::endl;
for (auto value : c.my_vector_of_uint8()) {
os << " " << value << "," << std::endl;
}
os << "]" << std::endl;
return os;
}
template <class T>
std::vector<T> from_vector_view(fidl::VectorView<T> v) {
size_t count = v.count();
std::vector<T> data(count);
for (size_t i = 0; i < count; i++) {
data[i] = v[i];
}
return data;
}
std::vector<std::string> from_vector_string_view(
fidl::VectorView<fidl::StringView> v) {
size_t count = v.count();
std::vector<std::string> data(count);
for (size_t i = 0; i < count; i++) {
data[i] = std::string(v[i].get());
}
return data;
}
Config Config::from_args() noexcept {
// Get the VMO containing FIDL config
zx_handle_t config_vmo_handle = zx_take_startup_handle(PA_CONFIG_VMO);
ZX_ASSERT_MSG(config_vmo_handle != ZX_HANDLE_INVALID,
"Could not obtain Config VMO Handle");
zx::vmo config_vmo(config_vmo_handle);
// Get the size of the VMO
uint64_t content_size_prop = 0;
zx_status_t status = config_vmo.get_prop_content_size(&content_size_prop);
ZX_ASSERT_MSG(status == ZX_OK, "Could not get content size of config VMO");
size_t vmo_content_size = static_cast<size_t>(content_size_prop);
// Checksum length must be correct
uint16_t checksum_length = 0;
status = config_vmo.read(&checksum_length, 0, 2);
ZX_ASSERT_MSG(status == ZX_OK,
"Could not read checksum length from config VMO");
// Verify Checksum
std::vector<uint8_t> checksum(checksum_length);
status = config_vmo.read(checksum.data(), 2, checksum_length);
ZX_ASSERT_MSG(status == ZX_OK, "Could not read checksum from config VMO");
std::vector<uint8_t> expected_checksum{
0xcd, 0x57, 0xb2, 0xa2, 0x89, 0xbb, 0xb6, 0x11, 0xcf, 0x81, 0x50,
0xec, 0x06, 0xc5, 0x06, 0x4c, 0x7c, 0xae, 0x79, 0x0f, 0xaa, 0x73,
0x0b, 0x6f, 0xa1, 0x02, 0xc3, 0x53, 0x7b, 0x94, 0xee, 0x1a};
ZX_ASSERT_MSG(checksum == expected_checksum,
"Invalid checksum for config VMO");
// Read the FIDL struct into memory
// Skip the checksum length + checksum + FIDL persistent header
// Align the struct pointer to 8 bytes (as required by FIDL)
size_t header = 2 + checksum_length + 8;
size_t fidl_struct_size = vmo_content_size - header;
std::unique_ptr<uint8_t[]> fidl_struct(new uint8_t[fidl_struct_size]);
status = config_vmo.read(fidl_struct.get(), header, fidl_struct_size);
ZX_ASSERT_MSG(status == ZX_OK, "Could not read FIDL struct from config VMO");
// TODO(https://fxbug.dev/100147) use fidl::Unpersist(header_and_struct_bytes)
// instead Decode the FIDL struct
fidl::unstable::DecodedMessage<::my_config_lib::wire::Config> decoded(
fidl::internal::WireFormatVersion::kV2, fidl_struct.get(),
static_cast<uint32_t>(fidl_struct_size));
ZX_ASSERT_MSG(decoded.ok(), "Could not decode Config FIDL structure");
::my_config_lib::wire::Config* fidl_config = decoded.PrimaryObject();
// Convert the configuration into a new struct
Config c{
{.my_flag = fidl_config->my_flag,
.my_int16 = fidl_config->my_int16,
.my_int32 = fidl_config->my_int32,
.my_int64 = fidl_config->my_int64,
.my_int8 = fidl_config->my_int8,
.my_string = std::string(fidl_config->my_string.get()),
.my_uint16 = fidl_config->my_uint16,
.my_uint32 = fidl_config->my_uint32,
.my_uint64 = fidl_config->my_uint64,
.my_uint8 = fidl_config->my_uint8,
.my_vector_of_flag = from_vector_view(fidl_config->my_vector_of_flag),
.my_vector_of_int16 = from_vector_view(fidl_config->my_vector_of_int16),
.my_vector_of_int32 = from_vector_view(fidl_config->my_vector_of_int32),
.my_vector_of_int64 = from_vector_view(fidl_config->my_vector_of_int64),
.my_vector_of_int8 = from_vector_view(fidl_config->my_vector_of_int8),
.my_vector_of_string =
from_vector_string_view(fidl_config->my_vector_of_string),
.my_vector_of_uint16 =
from_vector_view(fidl_config->my_vector_of_uint16),
.my_vector_of_uint32 =
from_vector_view(fidl_config->my_vector_of_uint32),
.my_vector_of_uint64 =
from_vector_view(fidl_config->my_vector_of_uint64),
.my_vector_of_uint8 =
from_vector_view(fidl_config->my_vector_of_uint8)}};
return c;
}
} // namespace cpp_elf_config_lib