5#ifndef PICOSCENES_PLATFORM_SDRFRONTENDHARDWAREINFORMATION_HXX
6#define PICOSCENES_PLATFORM_SDRFRONTENDHARDWAREINFORMATION_HXX
12#include "PicoScenesCommons.hxx"
54 [](
const auto& iface) { return iface.isPrimary; });
80 std::vector<std::shared_ptr<SDRFrontEndProfile>>
frontends{};
89 PicoScenesDeviceType
deviceType{PicoScenesDeviceType::Unknown};
90 PicoScenesDeviceSubtype
deviceSubtype{PicoScenesDeviceSubtype::Unknown};
117 if (!interface.ipAddress.empty() && !
inverseMap.contains(interface.ipAddress)) {
136 std::vector<SDRMainBoardInfo> allBoards{
boardInfo};
154 throw std::out_of_range(
"Board index out of range");
559 std::ostringstream info;
563 size_t maxWidth = 100;
566 info <<
"\n" << std::string(maxWidth,
'*') <<
"\n";
569 for (
size_t i = 0; i < boards.size(); i++) {
570 const auto& board = boards[i];
571 info <<
"* Board " << i <<
": " << board.name
572 <<
" [Serial: " << board.serial
573 <<
", Model: " << board.model
574 <<
", FPGA: " << board.fpgaImage
575 <<
", Subtype: " << DeviceSubtype2String(board.deviceSubtype) <<
"]\n";
578 const auto& conn = board.connectionProfile;
585 for (
const auto& eth : conn.ethernetInterfaces) {
586 info <<
"* Interface: " << eth.hostInterfaceName
587 <<
"=" << eth.ipAddress <<
" Speed=" << eth.linkSpeed / 1000 <<
"GbE MTU=" << eth.MTU <<
"\n";
593 info <<
"*" << std::string(maxWidth-2,
'-') <<
"\n";
595 info <<
"* Supported Master Clock Rates: [";
596 if (!masterClockRates.empty()) {
597 auto minRate = *std::min_element(masterClockRates.begin(), masterClockRates.end()) / 1e6;
598 auto maxRate = *std::max_element(masterClockRates.begin(), masterClockRates.end()) / 1e6;
599 info << minRate <<
" MHz, " << maxRate <<
" MHz";
602 info <<
"* Available Channel #: Tx (Transmit)=";
604 if (txChannels.empty()) {
608 for (
size_t chIndex = 0; chIndex < txChannels.size(); ++chIndex) {
609 info << (chIndex == 0 ?
"" :
", ") <<
static_cast<int>(txChannels[chIndex]);
613 info <<
", and Rx (Receive)=";
615 if (rxChannels.empty()) {
619 for (
size_t chIndex = 0; chIndex < rxChannels.size(); ++chIndex) {
620 info << (chIndex == 0 ?
"" :
", ") <<
static_cast<int>(rxChannels[chIndex]);
627 info <<
"*" << std::string(maxWidth-2,
'-') <<
"\n";
630 info <<
"* <Motherboard -> Channel # (Tx/Rx) -> Tx/Rx FrontEnd -> Available Antennas> Mapping: \n";
637 auto getMboardInfo = [&](
const std::string& frontendSerial) -> std::string {
638 for (
const auto& db : daughterboards) {
639 for (
const auto& fe : db.frontends) {
640 if (fe->serialNumber == frontendSerial) {
641 return fe->motherboardSerial +
" (" +
642 DeviceSubtype2String(board.deviceSubtype) +
")";
649 for (
size_t i = 0; i < txChannels.size(); i++) {
650 uint8_t ch = txChannels[i];
656 std::string frontendSerial;
658 if (std::find(profile->txChannelNumber.begin(), profile->txChannelNumber.end(), ch) != profile->txChannelNumber.end()) {
659 frontendSerial = profile->serialNumber;
665 info << getMboardInfo(frontendSerial) <<
" -> ";
668 info << static_cast<int>(ch) <<
" (Tx) -> ";
671 bool foundFrontend =
false;
673 if (std::find(profile->txChannelNumber.begin(), profile->txChannelNumber.end(), ch) != profile->txChannelNumber.end()) {
674 info << profile->serialNumber;
675 if (!profile->frontendHardwareModel.empty()) {
676 info <<
" (" << profile->frontendHardwareModel <<
")";
678 foundFrontend =
true;
682 if (!foundFrontend) {
689 if (supportedAnts.empty()) {
692 for (
size_t j = 0; j < supportedAnts.size(); j++) {
693 if (supportedAnts[j].empty()) {
696 info << supportedAnts[j];
698 if (j < supportedAnts.size() - 1) {
707 for (
size_t i = 0; i < rxChannels.size(); i++) {
708 uint8_t ch = rxChannels[i];
714 std::string frontendSerial;
716 if (std::find(profile->rxChannelNumber.begin(), profile->rxChannelNumber.end(), ch) != profile->rxChannelNumber.end()) {
717 frontendSerial = profile->serialNumber;
723 info << getMboardInfo(frontendSerial) <<
" -> ";
726 info << static_cast<int>(ch) <<
" (Rx) -> ";
729 bool foundFrontend =
false;
731 if (std::find(profile->rxChannelNumber.begin(), profile->rxChannelNumber.end(), ch) != profile->rxChannelNumber.end()) {
732 info << profile->serialNumber;
733 if (!profile->frontendHardwareModel.empty()) {
734 info <<
" (" << profile->frontendHardwareModel <<
")";
736 foundFrontend =
true;
740 if (!foundFrontend) {
747 if (supportedAnts.empty()) {
750 for (
size_t j = 0; j < supportedAnts.size(); j++) {
751 if (supportedAnts[j].empty()) {
754 info << supportedAnts[j];
756 if (j < supportedAnts.size() - 1) {
765 info <<
"*" << std::string(maxWidth-2,
'-') <<
"\n";
768 info <<
"* Channel Capabilities:\n";
771 for (
size_t i = 0; i < txChannels.size(); i++) {
772 uint8_t ch = txChannels[i];
773 info <<
"* # " <<
static_cast<int>(ch) <<
" (Tx):\n";
776 info <<
"* Gain -> " << std::fixed << std::setprecision(1)
781 info <<
"* Carrier Frequency -> " << std::fixed << std::setprecision(1)
786 info <<
"* Sampling Rate -> " << std::fixed << std::setprecision(2)
793 for (
size_t i = 0; i < rxChannels.size(); i++) {
794 uint8_t ch = rxChannels[i];
795 info <<
"* # " <<
static_cast<int>(ch) <<
" (Rx):\n";
798 info <<
"* Gain -> " << std::fixed << std::setprecision(1)
803 info <<
"* Carrier Frequency -> " << std::fixed << std::setprecision(1)
808 info <<
"* Sampling Rate -> " << std::fixed << std::setprecision(2)
814 info <<
"* AGC -> Supported\n";
816 info <<
"* AGC -> Not Supported\n";
821 info << std::string(maxWidth,
'*') <<
"\n";
std::string combinationIdentifier
SDRConnectionType connectionType
std::vector< SDREthernetConnectionInterface > ethernetInterfaces
bool isDualConnection() const
uint8_t deviceIndexInCombination
uint8_t combinedDeviceCount
SDRDeviceCombinationType combinationType
const SDREthernetConnectionInterface * getPrimaryInterface() const
std::vector< std::shared_ptr< SDRFrontEndProfile > > frontends
std::string hostInterfaceName
std::string hostPortAddress
std::vector< uint8_t > rxChannelNumber
std::string frontendHardwareModel
std::vector< uint8_t > txChannelNumber
std::string motherboardSerial
std::map< std::string, std::string > inverseMap
PicoScenesDeviceType deviceType
std::vector< SDRMainBoardInfo > otherBoards
SDRConnectionProfile connectionProfile
void merge(const SDRMainBoardInfo &other)
size_t getTotalBoardCount() const
PicoScenesDeviceSubtype deviceSubtype