- CitrineOS core extracted (CSMS OCPP 2.0.1) - OpenOCPP extracted (firmware OCPP 1.6J/2.0.1) - ShapeShifter library installed (pip install -e) - ShapeShifter specification extracted - EVerest extracted TODO updated with progress
123 lines
3.5 KiB
C++
123 lines
3.5 KiB
C++
// SPDX-License-Identifier: Apache-2.0
|
|
// Copyright 2020 - 2026 Pionix GmbH and Contributors to EVerest
|
|
#include "charge_bridge/utilities/string.hpp"
|
|
#include <charge_bridge/discovery.hpp>
|
|
#include <charge_bridge/utilities/logging.hpp>
|
|
#include <everest/io/event/fd_event_handler.hpp>
|
|
#include <type_traits>
|
|
|
|
namespace charge_bridge {
|
|
|
|
namespace {
|
|
std::string to_string(discovery_device_type val) {
|
|
switch (val) {
|
|
case discovery_device_type::CB_EV:
|
|
return "CB-CCS-EV-LU";
|
|
|
|
case discovery_device_type::CB_EVSE:
|
|
return "CB-CCS-EVSE-LU";
|
|
default:
|
|
return "INVALID";
|
|
}
|
|
}
|
|
|
|
bool is_cb_match(std::string const& board_type, discovery_device_type discriminator) {
|
|
auto result = board_type == to_string(discriminator);
|
|
return result;
|
|
}
|
|
|
|
} // namespace
|
|
|
|
const std::string discovery::discovery_id = "_chargebridge._udp.local";
|
|
|
|
discovery::discovery(discovery_device_type type) : m_type(type) {
|
|
using namespace std::chrono_literals;
|
|
m_timer.set_timeout(1s);
|
|
|
|
for (auto const& item : everest::lib::io::socket::get_all_interaces()) {
|
|
add_client(item.name);
|
|
}
|
|
}
|
|
|
|
discovery::discovery(discovery_device_type type, std::set<std::string> const& interfaces, bool excluding) :
|
|
m_type(type) {
|
|
using namespace std::chrono_literals;
|
|
m_timer.set_timeout(1s);
|
|
|
|
for (auto const& item : everest::lib::io::socket::get_all_interaces()) {
|
|
if (not interfaces.empty()) {
|
|
if (interfaces.count(item.name) == 1 and excluding) {
|
|
continue;
|
|
}
|
|
if (interfaces.count(item.name) == 0 and not excluding) {
|
|
continue;
|
|
}
|
|
}
|
|
std::cout << " using interface: " << item.name << std::endl;
|
|
add_client(item.name);
|
|
}
|
|
}
|
|
|
|
void discovery::add_client(std::string const& interface) {
|
|
auto client = std::make_unique<everest::lib::io::mdns::mdns_client>(interface);
|
|
client->set_rx_handler([&](auto const& data, auto&) {
|
|
auto discovery = everest::lib::io::mdns::parse_mdns_packet(data.buffer);
|
|
if (discovery.has_value()) {
|
|
if (m_registry.update(discovery.value())) {
|
|
query_registry();
|
|
}
|
|
}
|
|
});
|
|
m_mdns.push_back(std::move(client));
|
|
}
|
|
|
|
void discovery::query_registry() {
|
|
auto obj = m_registry.get();
|
|
for (auto const& [key, value] : obj) {
|
|
if (not utilities::string_ends_with(key, discovery_id)) {
|
|
continue;
|
|
}
|
|
if (not value.txt.count("board_type") or not is_cb_match(value.txt.at("board_type"), m_type)) {
|
|
continue;
|
|
}
|
|
if (not m_on_discover) {
|
|
continue;
|
|
}
|
|
m_on_discover(value.ip);
|
|
return;
|
|
}
|
|
}
|
|
|
|
void discovery::set_discovery_callback(discovery_cb const& cb) {
|
|
m_on_discover = cb;
|
|
}
|
|
|
|
bool discovery::register_events(everest::lib::io::event::fd_event_handler& handler) {
|
|
auto result = true;
|
|
for (auto& item : m_mdns) {
|
|
if (item) {
|
|
result = handler.register_event_handler(item.get()) && result;
|
|
}
|
|
}
|
|
handler.register_event_handler(&m_timer, [&](auto) {
|
|
for (auto& item : m_mdns) {
|
|
item->get_raw_handler()->query(discovery_id);
|
|
}
|
|
});
|
|
|
|
return result;
|
|
}
|
|
|
|
bool discovery::unregister_events(everest::lib::io::event::fd_event_handler& handler) {
|
|
auto result = true;
|
|
for (auto& item : m_mdns) {
|
|
if (item) {
|
|
result = handler.unregister_event_handler(item.get()) && result;
|
|
}
|
|
}
|
|
handler.unregister_event_handler(&m_timer);
|
|
return result;
|
|
}
|
|
|
|
} // namespace charge_bridge
|