map/das-dn/third_party/AdsLib/RouterAccess.cpp
2024-12-09 09:41:04 +08:00

67 lines
1.8 KiB
C++

// SPDX-License-Identifier: MIT
/**
Copyright (c) 2021 - 2022 Beckhoff Automation GmbH & Co. KG
*/
#include "RouterAccess.h"
#include "Log.h"
#include "wrap_endian.h"
#include <array>
#include <iostream>
namespace Beckhoff
{
namespace Ads
{
std::ostream& operator<<(std::ostream& os, const SearchPciSlotResNew& slot)
{
return os << std::dec << Beckhoff::letoh(slot.leBusNumber) << ':' <<
Beckhoff::letoh(slot.leSlotNumber) << " @ 0x" <<
Beckhoff::letoh(slot.leBaseAddresses[0]);
}
RouterAccess::RouterAccess(const std::string& gw, const AmsNetId netid, const uint16_t port)
: device(gw, netid, port ? port : 1)
{}
bool RouterAccess::PciScan(const uint64_t pci_id, std::ostream& os) const
{
#define ROUTERADSGRP_ACCESS_HARDWARE 0x00000005
#define ROUTERADSOFFS_A_HW_SEARCHPCIBUS 0x00000003
SearchPciBusResNew res {};
uint32_t bytesRead;
const auto req = SearchPciBusReq {pci_id};
const auto status = device.ReadWriteReqEx2(
ROUTERADSGRP_ACCESS_HARDWARE,
ROUTERADSOFFS_A_HW_SEARCHPCIBUS,
sizeof(res), &res,
sizeof(req), &req,
&bytesRead
);
if (ADSERR_NOERR != status) {
LOG_ERROR(__FUNCTION__ << "(): failed with: 0x" << std::hex << status << '\n');
return false;
}
if (res.slot.size() < res.nFound()) {
LOG_WARN(__FUNCTION__
<< "(): data seems corrupt. Slot count 0x" << std::hex << res.nFound() << " exceeds maximum 0x" << res.slot.size() <<
" -> truncating\n");
}
auto limit = std::min<size_t>(res.slot.size(), res.nFound());
os << "PCI devices found: " << std::dec << limit << '\n';
for (const auto& slot: res.slot) {
if (!limit--) {
break;
}
os << slot << '\n';
}
return !os.good();
}
}
}