| // Copyright 2024 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. |
| |
| #include <fidl/fuchsia.component.decl/cpp/fidl.h> |
| #include <lib/driver/incoming/cpp/service_validator.h> |
| |
| namespace fdf { |
| |
| ServiceValidator::ServiceValidator(const std::vector<fuchsia_driver_framework::Offer>& offers) { |
| for (const auto& offer : offers) { |
| const fuchsia_component_decl::Offer* inner_offer = nullptr; |
| if (offer.Which() == fuchsia_driver_framework::Offer::Tag::kDriverTransport) { |
| inner_offer = &offer.driver_transport().value(); |
| } else if (offer.Which() == fuchsia_driver_framework::Offer::Tag::kZirconTransport) { |
| inner_offer = &offer.zircon_transport().value(); |
| } |
| |
| if (!inner_offer || inner_offer->Which() != fuchsia_component_decl::Offer::Tag::kService) { |
| continue; |
| } |
| |
| const fuchsia_component_decl::OfferService* service = &inner_offer->service().value(); |
| if (!service->renamed_instances().has_value()) { |
| continue; |
| } |
| |
| std::optional<std::unordered_set<std::string>> filter_set; |
| if (service->source_instance_filter().has_value()) { |
| filter_set.emplace(std::unordered_set<std::string>{}); |
| |
| for (const auto& instance_filter : service->source_instance_filter().value()) { |
| filter_set->insert(instance_filter); |
| } |
| } |
| |
| std::string service_name = service->target_name().value(); |
| for (const auto& instance : service->renamed_instances().value()) { |
| const std::string& instance_name = instance.target_name(); |
| |
| if (filter_set.has_value() && filter_set->find(instance_name) == filter_set->end()) { |
| continue; |
| } |
| |
| std::unordered_map<std::string, std::unordered_set<std::string>>* target_map; |
| if (offer.Which() == fuchsia_driver_framework::Offer::Tag::kDriverTransport) { |
| target_map = &instance_to_driver_service_mapping_; |
| } else if (offer.Which() == fuchsia_driver_framework::Offer::Tag::kZirconTransport) { |
| target_map = &instance_to_zircon_service_mapping_; |
| } else { |
| continue; |
| } |
| |
| if (target_map->find(instance_name) == target_map->end()) { |
| (*target_map)[instance_name] = std::unordered_set<std::string>(); |
| } |
| |
| (*target_map)[instance_name].insert(service_name); |
| } |
| } |
| } |
| |
| bool ServiceValidator::IsValidZirconServiceInstance(const std::string& service_name, |
| const std::string& instance) const { |
| auto entry = instance_to_zircon_service_mapping_.find(instance); |
| if (entry != instance_to_zircon_service_mapping_.end()) { |
| auto value = entry->second.find(service_name); |
| if (value != entry->second.end()) { |
| return true; |
| } |
| } |
| |
| return false; |
| } |
| |
| bool ServiceValidator::IsValidDriverServiceInstance(const std::string& service_name, |
| const std::string& instance) const { |
| auto entry = instance_to_driver_service_mapping_.find(instance); |
| if (entry != instance_to_driver_service_mapping_.end()) { |
| auto value = entry->second.find(service_name); |
| if (value != entry->second.end()) { |
| return true; |
| } |
| } |
| |
| return false; |
| } |
| |
| } // namespace fdf |