blob: befe9197069fce2dd2ccb54982db39e6aa4a997e [file] [log] [blame]
#include <fidl/my.config.lib/cpp/wire.h>
#include <fidl/my.config.lib/cpp/wire_types.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::RecordInspect(inspect::Node* node) {
node->RecordBool("my_flag", this->my_flag());
node->RecordInt("my_int16", this->my_int16());
node->RecordInt("my_int32", this->my_int32());
node->RecordInt("my_int64", this->my_int64());
node->RecordInt("my_int8", this->my_int8());
node->RecordString("my_string", this->my_string());
node->RecordUint("my_uint16", this->my_uint16());
node->RecordUint("my_uint32", this->my_uint32());
node->RecordUint("my_uint64", this->my_uint64());
node->RecordUint("my_uint8", this->my_uint8());
auto my_vector_of_flag_array_ = node->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_array_.Set(i, this->my_vector_of_flag()[i]);
}
node->Record(std::move(my_vector_of_flag_array_));
auto my_vector_of_int16_array_ = node->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_array_.Set(i, this->my_vector_of_int16()[i]);
}
node->Record(std::move(my_vector_of_int16_array_));
auto my_vector_of_int32_array_ = node->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_array_.Set(i, this->my_vector_of_int32()[i]);
}
node->Record(std::move(my_vector_of_int32_array_));
auto my_vector_of_int64_array_ = node->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_array_.Set(i, this->my_vector_of_int64()[i]);
}
node->Record(std::move(my_vector_of_int64_array_));
auto my_vector_of_int8_array_ = node->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_array_.Set(i, this->my_vector_of_int8()[i]);
}
node->Record(std::move(my_vector_of_int8_array_));
auto my_vector_of_string_array_ = node->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_array_.Set(i, ref);
}
node->Record(std::move(my_vector_of_string_array_));
auto my_vector_of_uint16_array_ = node->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_array_.Set(i, this->my_vector_of_uint16()[i]);
}
node->Record(std::move(my_vector_of_uint16_array_));
auto my_vector_of_uint32_array_ = node->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_array_.Set(i, this->my_vector_of_uint32()[i]);
}
node->Record(std::move(my_vector_of_uint32_array_));
auto my_vector_of_uint64_array_ = node->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_array_.Set(i, this->my_vector_of_uint64()[i]);
}
node->Record(std::move(my_vector_of_uint64_array_));
auto my_vector_of_uint8_array_ = node->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_array_.Set(i, this->my_vector_of_uint8()[i]);
}
node->Record(std::move(my_vector_of_uint8_array_));
}
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::TakeFromStartupHandle() noexcept {
// Get the VMO containing FIDL config
zx_handle_t config_vmo_handle =
zx_take_startup_handle(PA_VMO_COMPONENT_CONFIG);
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