blob: 2e18b72db28068f8dd3c6f31bfd6cd2e479f24bb [file] [log] [blame]
// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SRC_DEVICES_MISC_DRIVERS_COMPAT_COMPOSITE_NODE_SPEC_UTIL_H_
#define SRC_DEVICES_MISC_DRIVERS_COMPAT_COMPOSITE_NODE_SPEC_UTIL_H_
#include <fidl/fuchsia.driver.framework/cpp/wire.h>
#include <lib/ddk/device.h>
zx::result<fuchsia_driver_framework::wire::BindRule> ConvertBindRuleToFidl(
fidl::AnyArena& allocator, bind_rule_t bind_rule) {
fuchsia_driver_framework::wire::NodePropertyKey property_key;
switch (bind_rule.key.key_type) {
case DEVICE_BIND_PROPERTY_KEY_INT: {
property_key =
fuchsia_driver_framework::wire::NodePropertyKey::WithIntValue(bind_rule.key.data.int_key);
break;
}
case DEVICE_BIND_PROPERTY_KEY_STRING: {
property_key = fuchsia_driver_framework::wire::NodePropertyKey::WithStringValue(
allocator, allocator, bind_rule.key.data.str_key);
break;
}
default: {
return zx::error(ZX_ERR_INVALID_ARGS);
}
}
auto bind_rule_values = fidl::VectorView<fuchsia_driver_framework::wire::NodePropertyValue>(
allocator, bind_rule.values_count);
for (size_t i = 0; i < bind_rule.values_count; i++) {
auto bind_rule_val = bind_rule.values[i];
switch (bind_rule_val.data_type) {
case ZX_DEVICE_PROPERTY_VALUE_INT: {
bind_rule_values[i] = fuchsia_driver_framework::wire::NodePropertyValue::WithIntValue(
bind_rule_val.data.int_value);
break;
}
case ZX_DEVICE_PROPERTY_VALUE_STRING: {
auto str_val =
fidl::ObjectView<fidl::StringView>(allocator, allocator, bind_rule_val.data.str_value);
bind_rule_values[i] =
fuchsia_driver_framework::wire::NodePropertyValue::WithStringValue(str_val);
break;
}
case ZX_DEVICE_PROPERTY_VALUE_BOOL: {
bind_rule_values[i] = fuchsia_driver_framework::wire::NodePropertyValue::WithBoolValue(
bind_rule_val.data.bool_value);
break;
}
case ZX_DEVICE_PROPERTY_VALUE_ENUM: {
auto enum_val =
fidl::ObjectView<fidl::StringView>(allocator, allocator, bind_rule_val.data.enum_value);
bind_rule_values[i] =
fuchsia_driver_framework::wire::NodePropertyValue::WithEnumValue(enum_val);
break;
}
default: {
return zx::error(ZX_ERR_INVALID_ARGS);
}
}
}
fuchsia_driver_framework::wire::Condition condition;
switch (bind_rule.condition) {
case DEVICE_BIND_RULE_CONDITION_ACCEPT: {
condition = fuchsia_driver_framework::wire::Condition::kAccept;
break;
}
case DEVICE_BIND_RULE_CONDITION_REJECT: {
condition = fuchsia_driver_framework::wire::Condition::kReject;
break;
}
default: {
return zx::error(ZX_ERR_INVALID_ARGS);
}
}
return zx::ok(fuchsia_driver_framework::wire::BindRule{
.key = property_key,
.condition = condition,
.values = bind_rule_values,
});
}
zx::result<fuchsia_driver_framework::wire::NodeProperty> ConvertBindPropToFidl(
fidl::AnyArena& allocator, const device_bind_prop_t& bind_prop) {
auto node_property = fuchsia_driver_framework::wire::NodeProperty{};
switch (bind_prop.key.key_type) {
case DEVICE_BIND_PROPERTY_KEY_INT: {
node_property.key =
fuchsia_driver_framework::wire::NodePropertyKey::WithIntValue(bind_prop.key.data.int_key);
break;
}
case DEVICE_BIND_PROPERTY_KEY_STRING: {
node_property.key = fuchsia_driver_framework::wire::NodePropertyKey::WithStringValue(
allocator, allocator, bind_prop.key.data.str_key);
break;
}
default: {
return zx::error(ZX_ERR_INVALID_ARGS);
}
}
switch (bind_prop.value.data_type) {
case ZX_DEVICE_PROPERTY_VALUE_INT: {
node_property.value = fuchsia_driver_framework::wire::NodePropertyValue::WithIntValue(
bind_prop.value.data.int_value);
break;
}
case ZX_DEVICE_PROPERTY_VALUE_STRING: {
node_property.value = fuchsia_driver_framework::wire::NodePropertyValue::WithStringValue(
allocator, allocator, bind_prop.value.data.str_value);
break;
}
case ZX_DEVICE_PROPERTY_VALUE_BOOL: {
node_property.value = fuchsia_driver_framework::wire::NodePropertyValue::WithBoolValue(
bind_prop.value.data.bool_value);
break;
}
case ZX_DEVICE_PROPERTY_VALUE_ENUM: {
node_property.value = fuchsia_driver_framework::wire::NodePropertyValue::WithEnumValue(
fidl::ObjectView<fidl::StringView>(allocator, allocator,
bind_prop.value.data.enum_value));
break;
}
default: {
return zx::error(ZX_ERR_INVALID_ARGS);
}
}
return zx::ok(node_property);
}
zx::result<fuchsia_driver_framework::wire::ParentSpec> ConvertNodeRepresentation(
fidl::AnyArena& allocator, parent_spec_t node) {
fidl::VectorView<fuchsia_driver_framework::wire::BindRule> bind_rules(allocator,
node.bind_rule_count);
for (size_t i = 0; i < node.bind_rule_count; i++) {
auto bind_rule_result = ConvertBindRuleToFidl(allocator, node.bind_rules[i]);
if (!bind_rule_result.is_ok()) {
return bind_rule_result.take_error();
}
bind_rules[i] = std::move(bind_rule_result.value());
}
fidl::VectorView<fuchsia_driver_framework::wire::NodeProperty> props(allocator,
node.property_count);
for (size_t i = 0; i < node.property_count; i++) {
auto prop_result = ConvertBindPropToFidl(allocator, node.properties[i]);
if (!prop_result.is_ok()) {
return prop_result.take_error();
}
props[i] = std::move(prop_result.value());
}
return zx::ok(fuchsia_driver_framework::wire::ParentSpec{
.bind_rules = bind_rules,
.properties = props,
});
}
#endif // SRC_DEVICES_MISC_DRIVERS_COMPAT_COMPOSITE_NODE_SPEC_UTIL_H_