diff --git a/.clang-tidy b/.clang-tidy index fd8c681..259c4e1 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -144,4 +144,10 @@ readability-static-accessed-through-instance, readability-static-definition-in-anonymous-namespace, readability-string-compare, readability-uniqueptr-delete-release, -readability-use-anyofallof' \ No newline at end of file +readability-use-anyofallof, +cppcoreguidelines-avoid-non-const-global-variables, +clang-analyzer-security.*, +cppcoreguidelines-pro-bounds-*, +cppcoreguidelines-pro-type-reinterpret-cast' + + diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..b510d65 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,40 @@ +# Dependabot configuration +# +# Automatically opens PRs to update pinned GitHub Actions SHAs whenever a new +# release is published. Combined with SHA pinning in ci.yml, this gives both +# immutability (the SHA cannot be moved) and automatic security updates (a PR +# is raised as soon as a new version is tagged upstream). +# +# References: +# https://docs.github.com/en/code-security/dependabot/dependabot-version-updates +# https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions#using-third-party-actions + +version: 2 +updates: + # ── GitHub Actions ──────────────────────────────────────────────────────── + - package-ecosystem: "github-actions" + # Dependabot scans every workflow file under .github/workflows/ + directory: "/" + schedule: + interval: "weekly" + day: "monday" + time: "07:00" + timezone: "UTC" + # Group all action bumps into a single PR so the diff is easy to review + groups: + github-actions: + patterns: + - "*" + # Only open PRs against main/master + target-branch: "main" + labels: + - "dependencies" + - "github-actions" + commit-message: + prefix: "ci" + include: "scope" + # Limit open PRs to avoid noise + open-pull-requests-limit: 5 + # Keep the version comment accurate even when SHA changes + versioning-strategy: "auto" + diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a8b65b0..b09f5a7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,12 +21,14 @@ jobs: actions: read steps: - name: Checkout code - uses: actions/checkout@v4 + # actions/checkout v4.2.2 — pinned to full SHA + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: submodules: recursive - name: Initialize CodeQL - uses: github/codeql-action/init@v3 + # github/codeql-action/init v4.32.6 — pinned to full SHA + uses: github/codeql-action/init@fb0994ef1c058010acf1efccff928b0a83b1ed54 # v4.32.6 with: languages: cpp queries: security-and-quality @@ -55,7 +57,8 @@ jobs: CXX: g++-14 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 + # github/codeql-action/analyze v4.32.6 — pinned to full SHA (was @v3, now consistent with init) + uses: github/codeql-action/analyze@fb0994ef1c058010acf1efccff928b0a83b1ed54 # v4.32.6 with: category: "/language:cpp" @@ -66,7 +69,8 @@ jobs: contents: read steps: - name: Checkout code - uses: actions/checkout@v4 + # actions/checkout v4.2.2 — pinned to full SHA + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Install clang-format run: | @@ -88,7 +92,8 @@ jobs: contents: read steps: - name: Checkout code - uses: actions/checkout@v4 + # actions/checkout v4.2.2 — pinned to full SHA + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: submodules: recursive @@ -98,7 +103,7 @@ jobs: wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | \ sudo tee /etc/apt/trusted.gpg.d/llvm.asc sudo add-apt-repository -y \ - 'deb http://apt.llvm.org/noble/ llvm-toolchain-noble-19 main' + 'deb https://apt.llvm.org/noble/ llvm-toolchain-noble-19 main' sudo apt-get update sudo apt-get install -y \ clang-19 \ @@ -179,7 +184,8 @@ jobs: - {cc: clang-19, cxx: clang++-19, name: llvm-19, stdlib: libc++} steps: - name: Checkout code - uses: actions/checkout@v4 + # actions/checkout v4.2.2 — pinned to full SHA + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: submodules: recursive @@ -202,7 +208,7 @@ jobs: wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | \ sudo tee /etc/apt/trusted.gpg.d/llvm.asc sudo add-apt-repository -y \ - 'deb http://apt.llvm.org/noble/ llvm-toolchain-noble-19 main' + 'deb https://apt.llvm.org/noble/ llvm-toolchain-noble-19 main' sudo apt-get update sudo apt-get install -y \ clang-19 \ @@ -257,7 +263,8 @@ jobs: ls -lh artifacts/ - name: Upload build artifacts - uses: actions/upload-artifact@v4 + # actions/upload-artifact v4.6.2 — pinned to full SHA + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: binaries-${{ matrix.compiler.name }} path: artifacts/* diff --git a/generate.sh b/generate.sh index cccbb73..33c256e 100755 --- a/generate.sh +++ b/generate.sh @@ -1,7 +1,41 @@ #!/bin/bash -ex PROXY=src/proxy -XML2CPP=$(find -iname sdbus-c++-xml2cpp) + +# fix — safe tool resolution (no unconstrained find) +# +# Previous code: XML2CPP=$(find -iname sdbus-c++-xml2cpp) +# Risk: an adversary who can plant a file named sdbus-c++-xml2cpp anywhere +# beneath the working directory (e.g., in a malicious submodule) would have it +# executed instead of the real code-generator. +# +# Strategy (ordered, most-specific first): +# 1. Known CMake build-tree path (cmake-build-debug or build). +# 2. The tool on PATH (installed system-wide or via the project's own install). +# 3. Abort with a clear error — never fall through to an untrusted location. +_find_xml2cpp() { + local candidates=( + "cmake-build-debug/third_party/sdbus-cpp/tools/sdbus-c++-xml2cpp" + "build/third_party/sdbus-cpp/tools/sdbus-c++-xml2cpp" + "cmake-build-release/third_party/sdbus-cpp/tools/sdbus-c++-xml2cpp" + ) + for candidate in "${candidates[@]}"; do + if [[ -x "${candidate}" ]]; then + echo "${candidate}" + return 0 + fi + done + # Fall back to a PATH lookup (e.g., system-installed package) + if command -v sdbus-c++-xml2cpp &>/dev/null; then + command -v sdbus-c++-xml2cpp + return 0 + fi + echo "ERROR: sdbus-c++-xml2cpp not found." \ + "Build the project first (cmake + ninja) or install sdbus-c++." >&2 + return 1 +} + +XML2CPP=$(_find_xml2cpp) mkdir -p ${PROXY}/org/bluez/{Adapter1,AgentManager,BatteryProviderManager1,Battery1,Device1,GattManager1,GattService1,GattCharacteristic1,GattDescriptor1,Input1,LEAdvertisingManager1,Media1,NetworkServer1,Profile1} |true @@ -147,3 +181,5 @@ mkdir -p ${PROXY}/org/ofono/{HandsfreeAudioManager,Manager} |true ${XML2CPP} --verbose --proxy=${PROXY}/org/ofono/HandsfreeAudioManager/handsfree_audio_manager_proxy.h interfaces/org/ofono/HandsfreeAudioManager/HandsfreeAudioManager.xml ${XML2CPP} --verbose --proxy=${PROXY}/org/ofono/Manager/manager_proxy.h interfaces/org/ofono/Manager/Manager.xml + +scripts/clang-format.sh src/proxy diff --git a/src/bluez/hidraw.hpp b/src/bluez/hidraw.hpp index bb3d1d9..01d9c94 100644 --- a/src/bluez/hidraw.hpp +++ b/src/bluez/hidraw.hpp @@ -23,6 +23,8 @@ #include #include +#include + #include #include #include @@ -32,6 +34,44 @@ #include "hexdump.hpp" +/// RAII wrapper for a POSIX file descriptor. +/// Automatically closes the fd when it goes out of scope, preventing leaks +/// on every error-path break/return/exception. +struct UniqueFd { + explicit UniqueFd(const int fd) noexcept : fd_(fd) {} + + ~UniqueFd() { + if (fd_ >= 0) { + ::close(fd_); + } + } + + // Non-copyable, movable + UniqueFd(const UniqueFd&) = delete; + UniqueFd& operator=(const UniqueFd&) = delete; + + UniqueFd(UniqueFd&& other) noexcept : fd_(other.fd_) { other.fd_ = -1; } + UniqueFd& operator=(UniqueFd&& other) noexcept { + if (this != &other) { + if (fd_ >= 0) { + ::close(fd_); + } + fd_ = other.fd_; + other.fd_ = -1; + } + return *this; + } + + /// Returns true if the fd is valid (>= 0). + [[nodiscard]] bool valid() const noexcept { return fd_ >= 0; } + + /// Returns the raw file descriptor. + [[nodiscard]] int get() const noexcept { return fd_; } + + private: + int fd_; +}; + class Hidraw { public: Hidraw() = default; @@ -47,17 +87,15 @@ class Hidraw { Hidraw(Hidraw&&) = delete; Hidraw& operator=(Hidraw&&) = delete; - void HidDevicesLock() { devices_mutex_.lock(); } - - void HidDevicesUnlock() { devices_mutex_.unlock(); } - - [[nodiscard]] bool HidDevicesContains(const std::string& key) const { - return devices_.contains(key); - } - - [[nodiscard]] const std::string& GetHidDevice( - const std::string& dev_key) const { - return devices_.at(dev_key); + /// Thread-safe lookup of a hidraw device by key. + /// Returns the device path string if found, or an empty string if not. + /// Internally uses std::scoped_lock — callers never touch the mutex directly. + [[nodiscard]] std::string FindHidDevice(const std::string& key) const { + std::scoped_lock lock(devices_mutex_); + if (const auto it = devices_.find(key); it != devices_.end()) { + return it->second; + } + return {}; } /** @@ -341,7 +379,7 @@ class Hidraw { static constexpr std::string DEV_NAME = "DEVNAME"; static constexpr std::string DEV_PATH = "DEVPATH"; - std::mutex devices_mutex_; + mutable std::mutex devices_mutex_; std::map devices_; }; diff --git a/src/bluez/horipad_steam/horipad_steam.cc b/src/bluez/horipad_steam/horipad_steam.cc index 7814459..d6dc8dc 100644 --- a/src/bluez/horipad_steam/horipad_steam.cc +++ b/src/bluez/horipad_steam/horipad_steam.cc @@ -150,14 +150,8 @@ void HoripadSteam::onInterfacesAdded( } if (!hidraw_device_key.empty()) { - std::string hidraw_device; - HidDevicesLock(); - if (HidDevicesContains(hidraw_device_key)) { - hidraw_device = GetHidDevice(hidraw_device_key); - } - HidDevicesUnlock(); - - if (!hidraw_device.empty()) { + if (const std::string hidraw_device = FindHidDevice(hidraw_device_key); + !hidraw_device.empty()) { LOG_INFO("Adding hidraw device: {}", hidraw_device_key); if (!input_reader_) { input_reader_ = std::make_unique(hidraw_device); diff --git a/src/bluez/horipad_steam/input_reader.cc b/src/bluez/horipad_steam/input_reader.cc index 8088beb..a7b8556 100644 --- a/src/bluez/horipad_steam/input_reader.cc +++ b/src/bluez/horipad_steam/input_reader.cc @@ -12,7 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include #include +#include #include #include @@ -45,17 +47,18 @@ InputReader::~InputReader() { InputReader::Task InputReader::read_input() { LOG_DEBUG("hidraw device: {}", device_); - const int fd = open(device_.c_str(), O_RDWR); + const UniqueFd fd(open(device_.c_str(), O_RDWR)); while (true) { - if (fd < 0) { + if (!fd.valid()) { LOG_ERROR("unable to open device"); break; } // Raw Info hidraw_devinfo raw_dev_info{}; - if (const auto res = ioctl(fd, HIDIOCGRAWINFO, &raw_dev_info); res < 0) { + if (const auto res = ioctl(fd.get(), HIDIOCGRAWINFO, &raw_dev_info); + res < 0) { LOG_ERROR("HIDIOCGRAWINFO"); break; } @@ -64,25 +67,27 @@ InputReader::Task InputReader::read_input() { LOG_INFO("Product ID: {:04X}", raw_dev_info.product); // Raw Name - char buf[256]{}; - auto res = ioctl(fd, HIDIOCGRAWNAME(sizeof(buf)), buf); + std::array buf{}; + auto res = ioctl(fd.get(), HIDIOCGRAWNAME(buf.size()), buf.data()); if (res < 0) { LOG_ERROR("HIDIOCGRAWNAME"); break; } - LOG_INFO("HID Name: {}", buf); + buf.back() = '\0'; // guarantee null-termination + LOG_INFO("HID Name: {}", buf.data()); // Raw Physical Location - res = ioctl(fd, HIDIOCGRAWPHYS(sizeof(buf)), buf); + res = ioctl(fd.get(), HIDIOCGRAWPHYS(buf.size()), buf.data()); if (res < 0) { LOG_ERROR("HIDIOCGRAWPHYS"); break; } - LOG_INFO("HID Physical Location: {}", buf); + buf.back() = '\0'; // guarantee null-termination + LOG_INFO("HID Physical Location: {}", buf.data()); // Report Descriptor Size int desc_size = 0; - res = ioctl(fd, HIDIOCGRDESCSIZE, &desc_size); + res = ioctl(fd.get(), HIDIOCGRDESCSIZE, &desc_size); if (res < 0) { LOG_ERROR("HIDIOCGRDESCSIZE"); break; @@ -92,7 +97,7 @@ InputReader::Task InputReader::read_input() { // Report Descriptor hidraw_report_descriptor rpt_desc{}; rpt_desc.size = desc_size; - res = ioctl(fd, HIDIOCGRDESC, &rpt_desc); + res = ioctl(fd.get(), HIDIOCGRDESC, &rpt_desc); if (res < 0) { LOG_ERROR("HIDIOCGRDESC"); break; @@ -100,43 +105,47 @@ InputReader::Task InputReader::read_input() { std::ostringstream os; os << "Report Descriptor\n"; - os << CustomHexdump<400, false>(rpt_desc.value, rpt_desc.size); + os << CustomHexdump<400, false>(std::data(rpt_desc.value), rpt_desc.size); LOG_INFO(os.str()); while (!stop_flag_) { - std::uint8_t buffer[sizeof(inputReport12_t)]; + std::array buffer{}; ssize_t result = 0; - if (result = read(fd, &buffer[0], sizeof(inputReport12_t)); result < 0) { + if (result = read(fd.get(), buffer.data(), buffer.size()); result < 0) { LOG_ERROR("read failed: {}", strerror(errno)); break; } if (raw_dev_info.product == 0x01ab || raw_dev_info.product == 0x0196) { - if (auto report_id = buffer[0]; report_id == 7) { - const auto* input_report07 = - reinterpret_cast(buffer); - PrintInputReport7(*input_report07); + if (const auto report_id = buffer.at(0); report_id == 7) { + inputReport07_t input_report07{}; + std::memcpy(&input_report07, buffer.data(), + std::min(sizeof(inputReport07_t), buffer.size())); + PrintInputReport7(input_report07); } else if (report_id == 10) { - const auto* input_report10 = - reinterpret_cast(buffer); - PrintInputReport10(*input_report10); + inputReport10_t input_report10{}; + std::memcpy(&input_report10, buffer.data(), + std::min(sizeof(inputReport10_t), buffer.size())); + PrintInputReport10(input_report10); } else if (report_id == 12) { - const auto* input_report12 = - reinterpret_cast(buffer); - PrintInputReport12(*input_report12); + inputReport12_t input_report12{}; + std::memcpy(&input_report12, buffer.data(), + std::min(sizeof(inputReport12_t), buffer.size())); + PrintInputReport12(input_report12); } else if (report_id == 14) { - const auto* input_report14 = - reinterpret_cast(buffer); - PrintInputReport14(*input_report14); + inputReport14_t input_report14{}; + std::memcpy(&input_report14, buffer.data(), + std::min(sizeof(inputReport14_t), buffer.size())); + PrintInputReport14(input_report14); } else { - LOG_ERROR("Unknown report id: {}", buffer[0]); + LOG_ERROR("Unknown report id: {}", report_id); } } } break; } - close(fd); + // fd is automatically closed by UniqueFd destructor stop(); co_return; // NOLINT(readability-static-accessed-through-instance) @@ -197,21 +206,21 @@ void InputReader::PrintInputReport7(const inputReport07_t& input_report07) { void InputReader::PrintInputReport10(const inputReport10_t& input_report10) { std::ostringstream os; - os << CustomHexdump<400, false>(input_report10.VEN_Gamepad0024, + os << CustomHexdump<400, false>(std::data(input_report10.VEN_Gamepad0024), sizeof(inputReport10_t)); LOG_INFO("Input Report 10: {}", os.str()); } void InputReader::PrintInputReport12(const inputReport12_t& input_report12) { std::ostringstream os; - os << CustomHexdump<400, false>(input_report12.VEN_Gamepad0022, + os << CustomHexdump<400, false>(std::data(input_report12.VEN_Gamepad0022), sizeof(inputReport10_t)); LOG_INFO("Input Report 10: {}", os.str()); } void InputReader::PrintInputReport14(const inputReport14_t& input_report14) { std::ostringstream os; - os << CustomHexdump<400, false>(input_report14.VEN_Gamepad0026, + os << CustomHexdump<400, false>(std::data(input_report14.VEN_Gamepad0026), sizeof(inputReport10_t)); LOG_INFO("Input Report 14: {}", os.str()); } diff --git a/src/bluez/ps5_dual_sense/dual_sense.cc b/src/bluez/ps5_dual_sense/dual_sense.cc index 1e59771..1b45f04 100644 --- a/src/bluez/ps5_dual_sense/dual_sense.cc +++ b/src/bluez/ps5_dual_sense/dual_sense.cc @@ -150,14 +150,8 @@ void DualSense::onInterfacesAdded( } if (!hidraw_device_key.empty()) { - std::string hidraw_device; - HidDevicesLock(); - if (HidDevicesContains(hidraw_device_key)) { - hidraw_device = GetHidDevice(hidraw_device_key); - } - HidDevicesUnlock(); - - if (!hidraw_device.empty()) { + if (const std::string hidraw_device = FindHidDevice(hidraw_device_key); + !hidraw_device.empty()) { LOG_INFO("Adding hidraw device: {}", hidraw_device_key); if (!input_reader_) { input_reader_ = std::make_unique(hidraw_device); diff --git a/src/bluez/ps5_dual_sense/input_reader.cc b/src/bluez/ps5_dual_sense/input_reader.cc index ae9d79c..5dee6fe 100644 --- a/src/bluez/ps5_dual_sense/input_reader.cc +++ b/src/bluez/ps5_dual_sense/input_reader.cc @@ -12,7 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include #include +#include +#include #include #include @@ -45,17 +48,18 @@ InputReader::~InputReader() { InputReader::Task InputReader::read_input() { LOG_DEBUG("hidraw device: {}", device_); - const int fd = open(device_.c_str(), O_RDWR); + const UniqueFd fd(open(device_.c_str(), O_RDWR)); while (true) { - if (fd < 0) { + if (!fd.valid()) { LOG_ERROR("unable to open device"); break; } // Raw Info hidraw_devinfo raw_dev_info{}; - if (const auto res = ioctl(fd, HIDIOCGRAWINFO, &raw_dev_info); res < 0) { + if (const auto res = ioctl(fd.get(), HIDIOCGRAWINFO, &raw_dev_info); + res < 0) { LOG_ERROR("HIDIOCGRAWINFO"); break; } @@ -64,25 +68,27 @@ InputReader::Task InputReader::read_input() { LOG_INFO("Product ID: {:04X}", raw_dev_info.product); // Raw Name - char buf[256]{}; - auto res = ioctl(fd, HIDIOCGRAWNAME(sizeof(buf)), buf); + std::array buf{}; + auto res = ioctl(fd.get(), HIDIOCGRAWNAME(buf.size()), buf.data()); if (res < 0) { LOG_ERROR("HIDIOCGRAWNAME"); break; } - LOG_INFO("HID Name: {}", buf); + buf.back() = '\0'; // guarantee null-termination + LOG_INFO("HID Name: {}", buf.data()); // Raw Physical Location - res = ioctl(fd, HIDIOCGRAWPHYS(sizeof(buf)), buf); + res = ioctl(fd.get(), HIDIOCGRAWPHYS(buf.size()), buf.data()); if (res < 0) { LOG_ERROR("HIDIOCGRAWPHYS"); break; } - LOG_INFO("HID Physical Location: {}", buf); + buf.back() = '\0'; // guarantee null-termination + LOG_INFO("HID Physical Location: {}", buf.data()); // Report Descriptor Size int desc_size = 0; - res = ioctl(fd, HIDIOCGRDESCSIZE, &desc_size); + res = ioctl(fd.get(), HIDIOCGRDESCSIZE, &desc_size); if (res < 0) { LOG_ERROR("HIDIOCGRDESCSIZE"); break; @@ -92,7 +98,7 @@ InputReader::Task InputReader::read_input() { // Report Descriptor hidraw_report_descriptor rpt_desc{}; rpt_desc.size = desc_size; - res = ioctl(fd, HIDIOCGRDESC, &rpt_desc); + res = ioctl(fd.get(), HIDIOCGRDESC, &rpt_desc); if (res < 0) { LOG_ERROR("HIDIOCGRDESC"); break; @@ -100,31 +106,33 @@ InputReader::Task InputReader::read_input() { std::ostringstream os; os << "Report Descriptor\n"; - os << CustomHexdump<400, false>(rpt_desc.value, rpt_desc.size); + os << CustomHexdump<400, false>(std::data(rpt_desc.value), rpt_desc.size); LOG_INFO(os.str()); // Get Features GetControllerCalibrationData( - fd, hw_cal_data_); // enables extended report for BT - GetControllerMacAll(fd, controller_and_host_mac_); - GetControllerVersion(fd, version_); + fd.get(), hw_cal_data_); // enables extended report for BT + GetControllerMacAll(fd.get(), controller_and_host_mac_); + GetControllerVersion(fd.get(), version_); while (!stop_flag_) { - std::uint8_t buffer[sizeof(USBGetStateData)]; + std::array buffer{}; ssize_t result = 0; - if (result = read(fd, &buffer[0], sizeof(USBGetStateData)); result < 0) { + if (result = read(fd.get(), buffer.data(), buffer.size()); result < 0) { LOG_ERROR("GetInputReport4 failed: {}", strerror(errno)); break; } if (raw_dev_info.product == 0x0CE6) { - auto report_id = buffer[0]; - if (report_id == 1) { - const auto& input_report01 = - reinterpret_cast(buffer); + if (const auto report_id = buffer.at(0); report_id == 1) { + USBGetStateData input_report01{}; + std::memcpy(&input_report01, buffer.data(), + std::min(sizeof(USBGetStateData), buffer.size())); PrintControllerStateUsb(input_report01, hw_cal_data_); } else if (report_id == 49) { - const auto& input_report31 = reinterpret_cast(buffer); + ReportIn31 input_report31{}; + std::memcpy(&input_report31, buffer.data(), + std::min(sizeof(ReportIn31), buffer.size())); if (input_report31.Data.HasHID) { LOG_INFO("[ReportIn31] Has HID"); PrintControllerStateUsb(input_report31.Data.State.StateData, @@ -140,7 +148,7 @@ InputReader::Task InputReader::read_input() { break; } - close(fd); + // fd is automatically closed by UniqueFd destructor stop(); co_return; // NOLINT(readability-static-accessed-through-instance) @@ -203,48 +211,48 @@ int InputReader::GetControllerCalibrationData( // Set gyroscope calibration and normalization parameters. const auto speed_2x = (cal_data.Data.gyro.speed_plus + cal_data.Data.gyro.speed_minus); - hw_cal_data.gyro[0].abs_code = ABS_RX; - hw_cal_data.gyro[0].bias = 0; - hw_cal_data.gyro[0].sens_numer = speed_2x * GYRO_RES_PER_DEG_S; - hw_cal_data.gyro[0].sens_denom = + std::get<0>(hw_cal_data.gyro).abs_code = ABS_RX; + std::get<0>(hw_cal_data.gyro).bias = 0; + std::get<0>(hw_cal_data.gyro).sens_numer = speed_2x * GYRO_RES_PER_DEG_S; + std::get<0>(hw_cal_data.gyro).sens_denom = abs(cal_data.Data.gyro.pitch_plus - cal_data.Data.gyro.pitch_bias) + abs(cal_data.Data.gyro.pitch_minus - cal_data.Data.gyro.pitch_bias); - hw_cal_data.gyro[1].abs_code = ABS_RY; - hw_cal_data.gyro[1].bias = 0; - hw_cal_data.gyro[1].sens_numer = speed_2x * GYRO_RES_PER_DEG_S; - hw_cal_data.gyro[1].sens_denom = + std::get<1>(hw_cal_data.gyro).abs_code = ABS_RY; + std::get<1>(hw_cal_data.gyro).bias = 0; + std::get<1>(hw_cal_data.gyro).sens_numer = speed_2x * GYRO_RES_PER_DEG_S; + std::get<1>(hw_cal_data.gyro).sens_denom = abs(cal_data.Data.gyro.yaw_plus - cal_data.Data.gyro.yaw_bias) + abs(cal_data.Data.gyro.yaw_minus - cal_data.Data.gyro.yaw_bias); - hw_cal_data.gyro[2].abs_code = ABS_RZ; - hw_cal_data.gyro[2].bias = 0; - hw_cal_data.gyro[2].sens_numer = speed_2x * GYRO_RES_PER_DEG_S; - hw_cal_data.gyro[2].sens_denom = + std::get<2>(hw_cal_data.gyro).abs_code = ABS_RZ; + std::get<2>(hw_cal_data.gyro).bias = 0; + std::get<2>(hw_cal_data.gyro).sens_numer = speed_2x * GYRO_RES_PER_DEG_S; + std::get<2>(hw_cal_data.gyro).sens_denom = abs(cal_data.Data.gyro.roll_plus - cal_data.Data.gyro.roll_bias) + abs(cal_data.Data.gyro.roll_minus - cal_data.Data.gyro.roll_bias); // Set accelerometer calibration and normalization parameters. auto range_2g = cal_data.Data.acc.x_plus - cal_data.Data.acc.x_minus; - hw_cal_data.accel[0].abs_code = ABS_X; - hw_cal_data.accel[0].bias = + std::get<0>(hw_cal_data.accel).abs_code = ABS_X; + std::get<0>(hw_cal_data.accel).bias = static_cast(cal_data.Data.acc.x_plus - range_2g / 2); - hw_cal_data.accel[0].sens_numer = 2 * ACC_RES_PER_G; - hw_cal_data.accel[0].sens_denom = range_2g; + std::get<0>(hw_cal_data.accel).sens_numer = 2 * ACC_RES_PER_G; + std::get<0>(hw_cal_data.accel).sens_denom = range_2g; range_2g = cal_data.Data.acc.y_plus - cal_data.Data.acc.y_minus; - hw_cal_data.accel[1].abs_code = ABS_Y; - hw_cal_data.accel[1].bias = + std::get<1>(hw_cal_data.accel).abs_code = ABS_Y; + std::get<1>(hw_cal_data.accel).bias = static_cast(cal_data.Data.acc.y_plus - range_2g / 2); - hw_cal_data.accel[1].sens_numer = 2 * ACC_RES_PER_G; - hw_cal_data.accel[1].sens_denom = range_2g; + std::get<1>(hw_cal_data.accel).sens_numer = 2 * ACC_RES_PER_G; + std::get<1>(hw_cal_data.accel).sens_denom = range_2g; range_2g = cal_data.Data.acc.z_plus - cal_data.Data.acc.z_minus; - hw_cal_data.accel[2].abs_code = ABS_Z; - hw_cal_data.accel[2].bias = + std::get<2>(hw_cal_data.accel).abs_code = ABS_Z; + std::get<2>(hw_cal_data.accel).bias = static_cast(cal_data.Data.acc.z_plus - range_2g / 2); - hw_cal_data.accel[2].sens_numer = 2 * ACC_RES_PER_G; - hw_cal_data.accel[2].sens_denom = range_2g; + std::get<2>(hw_cal_data.accel).sens_numer = 2 * ACC_RES_PER_G; + std::get<2>(hw_cal_data.accel).sens_denom = range_2g; // Sanity check gyro calibration data size_t i = 0; @@ -403,24 +411,31 @@ void InputReader::PrintControllerMacAll( LOG_INFO("Controller Mac All"); LOG_INFO("\tReport ID: 0x{:02X}", controller_and_host_mac.ReportID); + // Iterate in reverse (index 6..1) using a span to avoid non-const subscript. std::ostringstream os; os << "\tClient: "; - for (int i = 6; i; --i) { - os << std::hex << std::setw(2) << std::setfill('0') - << static_cast(controller_and_host_mac.ClientMac[i]); - if (i != 1) { - os << ":"; + { + const std::span client(controller_and_host_mac.ClientMac); + for (auto it = client.rbegin(); it != client.rend(); ++it) { + if (it != client.rbegin()) { + os << ":"; + } + os << std::hex << std::setw(2) << std::setfill('0') + << static_cast(*it); } } LOG_INFO(os.str()); os.clear(); os.str(""); os << "\tHost: "; - for (int i = 6; i; --i) { - os << std::hex << std::setw(2) << std::setfill('0') - << static_cast(controller_and_host_mac.HostMac[i]); - if (i != 1) { - os << ":"; + { + const std::span host(controller_and_host_mac.HostMac); + for (auto it = host.rbegin(); it != host.rend(); ++it) { + if (it != host.rbegin()) { + os << ":"; + } + os << std::hex << std::setw(2) << std::setfill('0') + << static_cast(*it); } } LOG_INFO(os.str()); @@ -430,8 +445,10 @@ void InputReader::PrintControllerVersion( ReportFeatureInVersion const& version) { LOG_INFO("Firmware Info"); LOG_INFO("\tReportID: 0x{:02X}", version.Data.ReportID); - LOG_INFO("\tBuildDate: {}", std::string_view(version.Data.BuildDate, 11)); - LOG_INFO("\tBuildTime: {}", std::string_view(version.Data.BuildTime, 8)); + LOG_INFO("\tBuildDate: {}", + std::string_view(std::data(version.Data.BuildDate), 11)); + LOG_INFO("\tBuildTime: {}", + std::string_view(std::data(version.Data.BuildTime), 8)); LOG_INFO("\tFwType: {}", version.Data.FwType); LOG_INFO("\tSwSeries: 0x{:04X}", version.Data.SwSeries); LOG_INFO("\tHardwareInfo: 0x{:08X}", version.Data.HardwareInfo); @@ -493,28 +510,28 @@ void InputReader::PrintControllerStateUsb( state.AngularVelocityY, state.AngularVelocityZ); auto gyro_x = mult_frac( - hw_cal_data.gyro[0].sens_numer, state.AngularVelocityX, - hw_cal_data.gyro[0].sens_denom); + std::get<0>(hw_cal_data.gyro).sens_numer, state.AngularVelocityX, + std::get<0>(hw_cal_data.gyro).sens_denom); auto gyro_y = mult_frac( - hw_cal_data.gyro[1].sens_numer, state.AngularVelocityY, - hw_cal_data.gyro[1].sens_denom); + std::get<1>(hw_cal_data.gyro).sens_numer, state.AngularVelocityY, + std::get<1>(hw_cal_data.gyro).sens_denom); auto gyro_z = mult_frac( - hw_cal_data.gyro[2].sens_numer, state.AngularVelocityZ, - hw_cal_data.gyro[2].sens_denom); + std::get<2>(hw_cal_data.gyro).sens_numer, state.AngularVelocityZ, + std::get<2>(hw_cal_data.gyro).sens_denom); LOG_INFO("\tAngularVelocity (Cal): {}, {}, {}", gyro_x, gyro_y, gyro_z); LOG_INFO("\tAccelerometer (Raw): {}, {}, {}", state.AccelerometerX, state.AccelerometerY, state.AccelerometerZ); auto acc_x = mult_frac( - hw_cal_data.accel[0].sens_numer, state.AccelerometerX, - hw_cal_data.accel[0].sens_denom); + std::get<0>(hw_cal_data.accel).sens_numer, state.AccelerometerX, + std::get<0>(hw_cal_data.accel).sens_denom); auto acc_y = mult_frac( - hw_cal_data.accel[1].sens_numer, state.AccelerometerY, - hw_cal_data.accel[1].sens_denom); + std::get<1>(hw_cal_data.accel).sens_numer, state.AccelerometerY, + std::get<1>(hw_cal_data.accel).sens_denom); auto acc_z = mult_frac( - hw_cal_data.accel[2].sens_numer, state.AccelerometerZ, - hw_cal_data.accel[2].sens_denom); + std::get<2>(hw_cal_data.accel).sens_numer, state.AccelerometerZ, + std::get<2>(hw_cal_data.accel).sens_denom); LOG_INFO("\tAccelerometer (Cal): {}, {}, {}", acc_x, acc_y, acc_z); LOG_INFO("\tSensorTimestamp: {}", state.SensorTimestamp); diff --git a/src/bluez/ps5_dual_sense/input_reader.h b/src/bluez/ps5_dual_sense/input_reader.h index 18d0cbb..65a52ab 100644 --- a/src/bluez/ps5_dual_sense/input_reader.h +++ b/src/bluez/ps5_dual_sense/input_reader.h @@ -15,6 +15,7 @@ #ifndef SRC_BLUEZ_XBOX_CONTROLLER_INPUT_READER_HPP_ #define SRC_BLUEZ_XBOX_CONTROLLER_INPUT_READER_HPP_ +#include #include #include @@ -50,8 +51,8 @@ class InputReader { }; struct HardwareCalibrationData { - CalibrationData gyro[3]; - CalibrationData accel[3]; + std::array gyro; + std::array accel; }; std::string device_; diff --git a/src/bluez/udev_monitor.hpp b/src/bluez/udev_monitor.hpp index d15fc9c..4c9638b 100644 --- a/src/bluez/udev_monitor.hpp +++ b/src/bluez/udev_monitor.hpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -30,6 +31,40 @@ #include +// --------------------------------------------------------------------------- +// RAII wrappers for libudev handles +// --------------------------------------------------------------------------- +struct UdevDeleter { + void operator()(udev* u) const noexcept { udev_unref(u); } +}; +using UdevPtr = std::unique_ptr; + +struct UdevMonitorDeleter { + void operator()(udev_monitor* m) const noexcept { udev_monitor_unref(m); } +}; +using UdevMonitorPtr = std::unique_ptr; + +struct UdevDeviceDeleter { + void operator()(udev_device* d) const noexcept { udev_device_unref(d); } +}; +using UdevDevicePtr = std::unique_ptr; + +/// Minimal RAII wrapper for an epoll file descriptor. +struct EpollFd { + explicit EpollFd(const int fd) noexcept : fd_(fd) {} + ~EpollFd() { + if (fd_ >= 0) + ::close(fd_); + } + EpollFd(const EpollFd&) = delete; + EpollFd& operator=(const EpollFd&) = delete; + [[nodiscard]] bool valid() const noexcept { return fd_ >= 0; } + [[nodiscard]] int get() const noexcept { return fd_; } + + private: + int fd_; +}; + class UdevMonitor { public: UdevMonitor(std::vector sub_systems, @@ -104,39 +139,39 @@ class UdevMonitor { std::thread worker_thread_; void run() { - const auto udev = udev_new(); + // RAII: udev context — automatically udev_unref'd on scope exit + const UdevPtr udev(udev_new()); if (!udev) { spdlog::error("Failed to create udev context"); is_running_ = false; return; } - const auto mon = udev_monitor_new_from_netlink(udev, "udev"); + // RAII: udev monitor — automatically udev_monitor_unref'd on scope exit + const UdevMonitorPtr mon(udev_monitor_new_from_netlink(udev.get(), "udev")); if (!mon) { spdlog::error("Failed to create udev monitor"); - udev_unref(udev); is_running_ = false; return; } for (const auto& sub_system : sub_systems_) { if (int res = udev_monitor_filter_add_match_subsystem_devtype( - mon, sub_system.c_str(), nullptr); + mon.get(), sub_system.c_str(), nullptr); res != 0) { spdlog::error( "udev_monitor_filter_add_match_subsystem_devtype failed on {} = {}", sub_system, res); } } - udev_monitor_enable_receiving(mon); - const auto fd = udev_monitor_get_fd(mon); + udev_monitor_enable_receiving(mon.get()); + const auto fd = udev_monitor_get_fd(mon.get()); - const int epoll_fd = epoll_create1(0); - if (epoll_fd == -1) { + // RAII: epoll fd — automatically closed on scope exit + const EpollFd epoll_fd(epoll_create1(0)); + if (!epoll_fd.valid()) { spdlog::error("Failed to create epoll: {} ({})", std::strerror(errno), errno); - udev_monitor_unref(mon); - udev_unref(udev); is_running_ = false; return; } @@ -144,30 +179,25 @@ class UdevMonitor { epoll_event ev{}; ev.events = EPOLLIN; ev.data.fd = fd; - if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &ev) == -1) { + if (epoll_ctl(epoll_fd.get(), EPOLL_CTL_ADD, fd, &ev) == -1) { spdlog::error("Failed to add udev fd to epoll: {} ({})", std::strerror(errno), errno); - close(epoll_fd); - udev_monitor_unref(mon); - udev_unref(udev); is_running_ = false; return; } ev.data.fd = pipe_fds_[0]; - if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, pipe_fds_[0], &ev) == -1) { + if (epoll_ctl(epoll_fd.get(), EPOLL_CTL_ADD, pipe_fds_[0], &ev) == -1) { spdlog::error("Failed to add pipe fd to epoll: {} ({})", std::strerror(errno), errno); - close(epoll_fd); - udev_monitor_unref(mon); - udev_unref(udev); is_running_ = false; return; } while (is_running_) { epoll_event events[2]; - const int triggered_event_count = epoll_wait(epoll_fd, events, 2, -1); + const int triggered_event_count = + epoll_wait(epoll_fd.get(), events, 2, -1); if (triggered_event_count == -1) { if (errno == EINTR) { continue; // Interrupted by signal, retry @@ -185,15 +215,13 @@ class UdevMonitor { } if (events[n].data.fd == fd) { - if (const auto dev = udev_monitor_receive_device(mon)) { + // RAII: device handle — automatically udev_device_unref'd + if (UdevDevicePtr dev(udev_monitor_receive_device(mon.get())); dev) { if (callback_) { - // Get device properties - these can return NULL - const char* action = udev_device_get_action(dev); - const char* devnode = udev_device_get_devnode(dev); - const char* subsystem = udev_device_get_subsystem(dev); + const char* action = udev_device_get_action(dev.get()); + const char* devnode = udev_device_get_devnode(dev.get()); + const char* subsystem = udev_device_get_subsystem(dev.get()); - // Only invoke callback if we have valid data - // Note: devnode can legitimately be NULL for some devices if (action && subsystem) { callback_(action, devnode, subsystem); } else { @@ -204,17 +232,13 @@ class UdevMonitor { subsystem ? subsystem : "null"); } } - udev_device_unref(dev); + // dev destructor calls udev_device_unref automatically } } } } - // Clean up resources in reverse order - close(epoll_fd); - udev_monitor_unref(mon); - udev_unref(udev); - + // All resources (epoll_fd, mon, udev) are released by their destructors. spdlog::debug("UdevMonitor worker thread exiting"); } }; diff --git a/src/bluez/xbox_controller/input_reader.cc b/src/bluez/xbox_controller/input_reader.cc index 5cc62f7..5cad45f 100644 --- a/src/bluez/xbox_controller/input_reader.cc +++ b/src/bluez/xbox_controller/input_reader.cc @@ -12,7 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include #include +#include +#include #include #include @@ -45,17 +48,18 @@ InputReader::~InputReader() { InputReader::Task InputReader::read_input() { LOG_DEBUG("hidraw device: {}", device_); - const int fd = open(device_.c_str(), O_RDWR); + const UniqueFd fd(open(device_.c_str(), O_RDWR)); while (true) { - if (fd < 0) { + if (!fd.valid()) { LOG_ERROR("unable to open device"); break; } // Raw Info hidraw_devinfo raw_dev_info{}; - if (const auto res = ioctl(fd, HIDIOCGRAWINFO, &raw_dev_info); res < 0) { + if (const auto res = ioctl(fd.get(), HIDIOCGRAWINFO, &raw_dev_info); + res < 0) { LOG_ERROR("HIDIOCGRAWINFO"); break; } @@ -64,25 +68,27 @@ InputReader::Task InputReader::read_input() { LOG_INFO("Product ID: {:04X}", raw_dev_info.product); // Raw Name - char buf[256]{}; - auto res = ioctl(fd, HIDIOCGRAWNAME(sizeof(buf)), buf); + std::array buf{}; + auto res = ioctl(fd.get(), HIDIOCGRAWNAME(buf.size()), buf.data()); if (res < 0) { LOG_ERROR("HIDIOCGRAWNAME"); break; } - LOG_INFO("HID Name: {}", buf); + buf.back() = '\0'; // guarantee null-termination + LOG_INFO("HID Name: {}", buf.data()); // Raw Physical Location - res = ioctl(fd, HIDIOCGRAWPHYS(sizeof(buf)), buf); + res = ioctl(fd.get(), HIDIOCGRAWPHYS(buf.size()), buf.data()); if (res < 0) { LOG_ERROR("HIDIOCGRAWPHYS"); break; } - LOG_INFO("HID Physical Location: {}", buf); + buf.back() = '\0'; // guarantee null-termination + LOG_INFO("HID Physical Location: {}", buf.data()); // Report Descriptor Size int desc_size = 0; - res = ioctl(fd, HIDIOCGRDESCSIZE, &desc_size); + res = ioctl(fd.get(), HIDIOCGRDESCSIZE, &desc_size); if (res < 0) { LOG_ERROR("HIDIOCGRDESCSIZE"); break; @@ -92,7 +98,7 @@ InputReader::Task InputReader::read_input() { // Report Descriptor hidraw_report_descriptor rpt_desc{}; rpt_desc.size = desc_size; - res = ioctl(fd, HIDIOCGRDESC, &rpt_desc); + res = ioctl(fd.get(), HIDIOCGRDESC, &rpt_desc); if (res < 0) { LOG_ERROR("HIDIOCGRDESC"); break; @@ -100,39 +106,39 @@ InputReader::Task InputReader::read_input() { std::ostringstream os; os << "Report Descriptor\n"; - os << CustomHexdump<400, false>(rpt_desc.value, rpt_desc.size); + os << CustomHexdump<400, false>(std::data(rpt_desc.value), rpt_desc.size); LOG_INFO(os.str()); while (!stop_flag_) { - std::uint8_t buffer[sizeof(inputReport01_t)]; + std::array buffer{}; ssize_t result = 0; - if (result = read(fd, &buffer[0], sizeof(inputReport01_t)); result < 0) { + if (result = read(fd.get(), buffer.data(), buffer.size()); result < 0) { LOG_ERROR("GetInputReport4 failed: {}", strerror(errno)); break; } if (raw_dev_info.product == 0x02FD) { - if (buffer[0] == 1) { - const auto* input_report01 = - reinterpret_cast(buffer); - PrintInputReport1(*input_report01); - } else if (buffer[0] == 2) { - const auto* input_report02 = - reinterpret_cast(buffer); - PrintInputReport2(*input_report02); - } else if (buffer[0] == 4) { - const auto* input_report04 = - reinterpret_cast(buffer); - PrintInputReport4(*input_report04); + if (const auto report_id = buffer.at(0); report_id == 1) { + inputReport01_t input_report01{}; + std::memcpy(&input_report01, buffer.data(), sizeof(inputReport01_t)); + PrintInputReport1(input_report01); + } else if (report_id == 2) { + inputReport02_t input_report02{}; + std::memcpy(&input_report02, buffer.data(), sizeof(inputReport02_t)); + PrintInputReport2(input_report02); + } else if (report_id == 4) { + inputReport04_t input_report04{}; + std::memcpy(&input_report04, buffer.data(), sizeof(inputReport04_t)); + PrintInputReport4(input_report04); } else { - LOG_ERROR("Unknown report id: {}", buffer[0]); + LOG_ERROR("Unknown report id: {}", report_id); } } } break; } - close(fd); + // fd is automatically closed by UniqueFd destructor stop(); co_return; // NOLINT(readability-static-accessed-through-instance) diff --git a/src/bluez/xbox_controller/xbox_controller.cc b/src/bluez/xbox_controller/xbox_controller.cc index 45d3726..a0c7a93 100644 --- a/src/bluez/xbox_controller/xbox_controller.cc +++ b/src/bluez/xbox_controller/xbox_controller.cc @@ -151,14 +151,8 @@ void XboxController::onInterfacesAdded( } if (!hidraw_device_key.empty()) { - std::string hidraw_device; - HidDevicesLock(); - if (HidDevicesContains(hidraw_device_key)) { - hidraw_device = GetHidDevice(hidraw_device_key); - } - HidDevicesUnlock(); - - if (!hidraw_device.empty()) { + if (const std::string hidraw_device = FindHidDevice(hidraw_device_key); + !hidraw_device.empty()) { LOG_INFO("Adding hidraw device: {}", hidraw_device_key); if (!input_reader_) { input_reader_ = std::make_unique(hidraw_device); diff --git a/src/proxy/fi/w1/wpa_supplicant1/wpa_supplicant1_proxy.h b/src/proxy/fi/w1/wpa_supplicant1/wpa_supplicant1_proxy.h index dd91138..577da82 100644 --- a/src/proxy/fi/w1/wpa_supplicant1/wpa_supplicant1_proxy.h +++ b/src/proxy/fi/w1/wpa_supplicant1/wpa_supplicant1_proxy.h @@ -3,27 +3,28 @@ * This file was automatically generated by sdbus-c++-xml2cpp; DO NOT EDIT! */ -#ifndef _sdbuscpp_src_proxy_fi_w1_wpa_supplicant1_wpa_supplicant1_proxy_h_proxy_H_ -#define _sdbuscpp_src_proxy_fi_w1_wpa_supplicant1_wpa_supplicant1_proxy_h_proxy_H_ +#ifndef __sdbuscpp__src_proxy_fi_w1_wpa_supplicant1_wpa_supplicant1_proxy_h__proxy__H__ +#define __sdbuscpp__src_proxy_fi_w1_wpa_supplicant1_wpa_supplicant1_proxy_h__proxy__H__ #include #include #include -namespace fi::w1 { +namespace fi { +namespace w1 { class wpa_supplicant1_proxy { public: - static constexpr auto INTERFACE_NAME = "fi.w1.wpa_supplicant1"; + static constexpr const char* INTERFACE_NAME = "fi.w1.wpa_supplicant1"; + + protected: + wpa_supplicant1_proxy(sdbus::IProxy& proxy) : m_proxy(proxy) {} wpa_supplicant1_proxy(const wpa_supplicant1_proxy&) = delete; wpa_supplicant1_proxy& operator=(const wpa_supplicant1_proxy&) = delete; wpa_supplicant1_proxy(wpa_supplicant1_proxy&&) = delete; wpa_supplicant1_proxy& operator=(wpa_supplicant1_proxy&&) = delete; - protected: - explicit wpa_supplicant1_proxy(sdbus::IProxy& proxy) : m_proxy(proxy) {} - ~wpa_supplicant1_proxy() = default; void registerProxy() { @@ -151,6 +152,7 @@ class wpa_supplicant1_proxy { sdbus::IProxy& m_proxy; }; -} // namespace fi::w1 +} // namespace w1 +} // namespace fi #endif diff --git a/src/proxy/org/bluez/Adapter1/adapter1_proxy.h b/src/proxy/org/bluez/Adapter1/adapter1_proxy.h index c895f9e..c6c56ec 100644 --- a/src/proxy/org/bluez/Adapter1/adapter1_proxy.h +++ b/src/proxy/org/bluez/Adapter1/adapter1_proxy.h @@ -3,26 +3,28 @@ * This file was automatically generated by sdbus-c++-xml2cpp; DO NOT EDIT! */ -#ifndef _sdbuscpp_src_proxy_org_bluez_Adapter1_adapter1_proxy_h_proxy_H_ -#define _sdbuscpp_src_proxy_org_bluez_Adapter1_adapter1_proxy_h_proxy_H_ +#ifndef __sdbuscpp__src_proxy_org_bluez_Adapter1_adapter1_proxy_h__proxy__H__ +#define __sdbuscpp__src_proxy_org_bluez_Adapter1_adapter1_proxy_h__proxy__H__ #include #include +#include -namespace org::bluez { +namespace org { +namespace bluez { class Adapter1_proxy { public: - static constexpr auto INTERFACE_NAME = "org.bluez.Adapter1"; + static constexpr const char* INTERFACE_NAME = "org.bluez.Adapter1"; + + protected: + Adapter1_proxy(sdbus::IProxy& proxy) : m_proxy(proxy) {} Adapter1_proxy(const Adapter1_proxy&) = delete; Adapter1_proxy& operator=(const Adapter1_proxy&) = delete; Adapter1_proxy(Adapter1_proxy&&) = delete; Adapter1_proxy& operator=(Adapter1_proxy&&) = delete; - protected: - explicit Adapter1_proxy(sdbus::IProxy& proxy) : m_proxy(proxy) {} - ~Adapter1_proxy() = default; void registerProxy() {} @@ -176,6 +178,7 @@ class Adapter1_proxy { sdbus::IProxy& m_proxy; }; -} // namespace org::bluez +} // namespace bluez +} // namespace org #endif diff --git a/src/proxy/org/bluez/AgentManager/agent_manager1_proxy.h b/src/proxy/org/bluez/AgentManager/agent_manager1_proxy.h index 117af3e..c0251dd 100644 --- a/src/proxy/org/bluez/AgentManager/agent_manager1_proxy.h +++ b/src/proxy/org/bluez/AgentManager/agent_manager1_proxy.h @@ -3,26 +3,28 @@ * This file was automatically generated by sdbus-c++-xml2cpp; DO NOT EDIT! */ -#ifndef _sdbuscpp_src_proxy_org_bluez_AgentManager_agent_manager1_proxy_h_proxy_H_ -#define _sdbuscpp_src_proxy_org_bluez_AgentManager_agent_manager1_proxy_h_proxy_H_ +#ifndef __sdbuscpp__src_proxy_org_bluez_AgentManager_agent_manager1_proxy_h__proxy__H__ +#define __sdbuscpp__src_proxy_org_bluez_AgentManager_agent_manager1_proxy_h__proxy__H__ #include #include +#include -namespace org::bluez { +namespace org { +namespace bluez { class AgentManager1_proxy { public: - static constexpr auto INTERFACE_NAME = "org.bluez.AgentManager1"; + static constexpr const char* INTERFACE_NAME = "org.bluez.AgentManager1"; + + protected: + AgentManager1_proxy(sdbus::IProxy& proxy) : m_proxy(proxy) {} AgentManager1_proxy(const AgentManager1_proxy&) = delete; AgentManager1_proxy& operator=(const AgentManager1_proxy&) = delete; AgentManager1_proxy(AgentManager1_proxy&&) = delete; AgentManager1_proxy& operator=(AgentManager1_proxy&&) = delete; - protected: - explicit AgentManager1_proxy(sdbus::IProxy& proxy) : m_proxy(proxy) {} - ~AgentManager1_proxy() = default; void registerProxy() {} @@ -51,6 +53,7 @@ class AgentManager1_proxy { sdbus::IProxy& m_proxy; }; -} // namespace org::bluez +} // namespace bluez +} // namespace org #endif diff --git a/src/proxy/org/bluez/Battery1/battery1_proxy.h b/src/proxy/org/bluez/Battery1/battery1_proxy.h index 3d2bb8a..c916645 100644 --- a/src/proxy/org/bluez/Battery1/battery1_proxy.h +++ b/src/proxy/org/bluez/Battery1/battery1_proxy.h @@ -3,26 +3,28 @@ * This file was automatically generated by sdbus-c++-xml2cpp; DO NOT EDIT! */ -#ifndef _sdbuscpp_src_proxy_org_bluez_Battery1_battery1_proxy_h_proxy_H_ -#define _sdbuscpp_src_proxy_org_bluez_Battery1_battery1_proxy_h_proxy_H_ +#ifndef __sdbuscpp__src_proxy_org_bluez_Battery1_battery1_proxy_h__proxy__H__ +#define __sdbuscpp__src_proxy_org_bluez_Battery1_battery1_proxy_h__proxy__H__ #include #include +#include -namespace org::bluez { +namespace org { +namespace bluez { class Battery1_proxy { public: - static constexpr auto INTERFACE_NAME = "org.bluez.Battery1"; + static constexpr const char* INTERFACE_NAME = "org.bluez.Battery1"; + + protected: + Battery1_proxy(sdbus::IProxy& proxy) : m_proxy(proxy) {} Battery1_proxy(const Battery1_proxy&) = delete; Battery1_proxy& operator=(const Battery1_proxy&) = delete; Battery1_proxy(Battery1_proxy&&) = delete; Battery1_proxy& operator=(Battery1_proxy&&) = delete; - protected: - explicit Battery1_proxy(sdbus::IProxy& proxy) : m_proxy(proxy) {} - ~Battery1_proxy() = default; void registerProxy() {} @@ -38,6 +40,7 @@ class Battery1_proxy { sdbus::IProxy& m_proxy; }; -} // namespace org::bluez +} // namespace bluez +} // namespace org #endif diff --git a/src/proxy/org/bluez/BatteryProviderManager1/battery_provider_manager1_proxy.h b/src/proxy/org/bluez/BatteryProviderManager1/battery_provider_manager1_proxy.h index e279298..29859cf 100644 --- a/src/proxy/org/bluez/BatteryProviderManager1/battery_provider_manager1_proxy.h +++ b/src/proxy/org/bluez/BatteryProviderManager1/battery_provider_manager1_proxy.h @@ -3,16 +3,23 @@ * This file was automatically generated by sdbus-c++-xml2cpp; DO NOT EDIT! */ -#ifndef _sdbuscpp_src_proxy_org_bluez_BatteryProviderManager1_battery_provider_manager1_proxy_h_proxy_H_ -#define _sdbuscpp_src_proxy_org_bluez_BatteryProviderManager1_battery_provider_manager1_proxy_h_proxy_H_ +#ifndef __sdbuscpp__src_proxy_org_bluez_BatteryProviderManager1_battery_provider_manager1_proxy_h__proxy__H__ +#define __sdbuscpp__src_proxy_org_bluez_BatteryProviderManager1_battery_provider_manager1_proxy_h__proxy__H__ #include +#include +#include -namespace org::bluez { +namespace org { +namespace bluez { class BatteryProviderManager1_proxy { public: - static constexpr auto INTERFACE_NAME = "org.bluez.BatteryProviderManager1"; + static constexpr const char* INTERFACE_NAME = + "org.bluez.BatteryProviderManager1"; + + protected: + BatteryProviderManager1_proxy(sdbus::IProxy& proxy) : m_proxy(proxy) {} BatteryProviderManager1_proxy(const BatteryProviderManager1_proxy&) = delete; BatteryProviderManager1_proxy& operator=( @@ -21,10 +28,6 @@ class BatteryProviderManager1_proxy { BatteryProviderManager1_proxy& operator=(BatteryProviderManager1_proxy&&) = delete; - protected: - explicit BatteryProviderManager1_proxy(sdbus::IProxy& proxy) - : m_proxy(proxy) {} - ~BatteryProviderManager1_proxy() = default; void registerProxy() {} @@ -46,6 +49,7 @@ class BatteryProviderManager1_proxy { sdbus::IProxy& m_proxy; }; -} // namespace org::bluez +} // namespace bluez +} // namespace org #endif diff --git a/src/proxy/org/bluez/Device1/device1_proxy.h b/src/proxy/org/bluez/Device1/device1_proxy.h index 6c23af0..17b3d62 100644 --- a/src/proxy/org/bluez/Device1/device1_proxy.h +++ b/src/proxy/org/bluez/Device1/device1_proxy.h @@ -3,26 +3,28 @@ * This file was automatically generated by sdbus-c++-xml2cpp; DO NOT EDIT! */ -#ifndef _sdbuscpp_src_proxy_org_bluez_Device1_device1_proxy_h_proxy_H_ -#define _sdbuscpp_src_proxy_org_bluez_Device1_device1_proxy_h_proxy_H_ +#ifndef __sdbuscpp__src_proxy_org_bluez_Device1_device1_proxy_h__proxy__H__ +#define __sdbuscpp__src_proxy_org_bluez_Device1_device1_proxy_h__proxy__H__ #include #include +#include -namespace org::bluez { +namespace org { +namespace bluez { class Device1_proxy { public: - static constexpr auto INTERFACE_NAME = "org.bluez.Device1"; + static constexpr const char* INTERFACE_NAME = "org.bluez.Device1"; + + protected: + Device1_proxy(sdbus::IProxy& proxy) : m_proxy(proxy) {} Device1_proxy(const Device1_proxy&) = delete; Device1_proxy& operator=(const Device1_proxy&) = delete; Device1_proxy(Device1_proxy&&) = delete; Device1_proxy& operator=(Device1_proxy&&) = delete; - protected: - explicit Device1_proxy(sdbus::IProxy& proxy) : m_proxy(proxy) {} - ~Device1_proxy() = default; void registerProxy() {} @@ -213,6 +215,7 @@ class Device1_proxy { sdbus::IProxy& m_proxy; }; -} // namespace org::bluez +} // namespace bluez +} // namespace org #endif diff --git a/src/proxy/org/bluez/GattCharacteristic1/gatt_characteristic1_proxy.h b/src/proxy/org/bluez/GattCharacteristic1/gatt_characteristic1_proxy.h index 3d4fccc..85e735c 100644 --- a/src/proxy/org/bluez/GattCharacteristic1/gatt_characteristic1_proxy.h +++ b/src/proxy/org/bluez/GattCharacteristic1/gatt_characteristic1_proxy.h @@ -3,18 +3,22 @@ * This file was automatically generated by sdbus-c++-xml2cpp; DO NOT EDIT! */ -#ifndef _sdbuscpp_src_proxy_org_bluez_GattCharacteristic1_gatt_characteristic1_proxy_h_proxy_H_ -#define _sdbuscpp_src_proxy_org_bluez_GattCharacteristic1_gatt_characteristic1_proxy_h_proxy_H_ +#ifndef __sdbuscpp__src_proxy_org_bluez_GattCharacteristic1_gatt_characteristic1_proxy_h__proxy__H__ +#define __sdbuscpp__src_proxy_org_bluez_GattCharacteristic1_gatt_characteristic1_proxy_h__proxy__H__ #include #include #include -namespace org::bluez { +namespace org { +namespace bluez { class GattCharacteristic1_proxy { public: - static constexpr auto INTERFACE_NAME = "org.bluez.GattCharacteristic1"; + static constexpr const char* INTERFACE_NAME = "org.bluez.GattCharacteristic1"; + + protected: + GattCharacteristic1_proxy(sdbus::IProxy& proxy) : m_proxy(proxy) {} GattCharacteristic1_proxy(const GattCharacteristic1_proxy&) = delete; GattCharacteristic1_proxy& operator=(const GattCharacteristic1_proxy&) = @@ -22,9 +26,6 @@ class GattCharacteristic1_proxy { GattCharacteristic1_proxy(GattCharacteristic1_proxy&&) = delete; GattCharacteristic1_proxy& operator=(GattCharacteristic1_proxy&&) = delete; - protected: - explicit GattCharacteristic1_proxy(sdbus::IProxy& proxy) : m_proxy(proxy) {} - ~GattCharacteristic1_proxy() = default; void registerProxy() {} @@ -122,6 +123,7 @@ class GattCharacteristic1_proxy { sdbus::IProxy& m_proxy; }; -} // namespace org::bluez +} // namespace bluez +} // namespace org #endif diff --git a/src/proxy/org/bluez/GattDescriptor1/gatt_descriptor1_proxy.h b/src/proxy/org/bluez/GattDescriptor1/gatt_descriptor1_proxy.h index a199890..86990c8 100644 --- a/src/proxy/org/bluez/GattDescriptor1/gatt_descriptor1_proxy.h +++ b/src/proxy/org/bluez/GattDescriptor1/gatt_descriptor1_proxy.h @@ -3,26 +3,28 @@ * This file was automatically generated by sdbus-c++-xml2cpp; DO NOT EDIT! */ -#ifndef _sdbuscpp_src_proxy_org_bluez_GattDescriptor1_gatt_descriptor1_proxy_h_proxy_H_ -#define _sdbuscpp_src_proxy_org_bluez_GattDescriptor1_gatt_descriptor1_proxy_h_proxy_H_ +#ifndef __sdbuscpp__src_proxy_org_bluez_GattDescriptor1_gatt_descriptor1_proxy_h__proxy__H__ +#define __sdbuscpp__src_proxy_org_bluez_GattDescriptor1_gatt_descriptor1_proxy_h__proxy__H__ #include #include +#include -namespace org::bluez { +namespace org { +namespace bluez { class GattDescriptor1_proxy { public: - static constexpr auto INTERFACE_NAME = "org.bluez.GattDescriptor1"; + static constexpr const char* INTERFACE_NAME = "org.bluez.GattDescriptor1"; + + protected: + GattDescriptor1_proxy(sdbus::IProxy& proxy) : m_proxy(proxy) {} GattDescriptor1_proxy(const GattDescriptor1_proxy&) = delete; GattDescriptor1_proxy& operator=(const GattDescriptor1_proxy&) = delete; GattDescriptor1_proxy(GattDescriptor1_proxy&&) = delete; GattDescriptor1_proxy& operator=(GattDescriptor1_proxy&&) = delete; - protected: - explicit GattDescriptor1_proxy(sdbus::IProxy& proxy) : m_proxy(proxy) {} - ~GattDescriptor1_proxy() = default; void registerProxy() {} @@ -68,6 +70,7 @@ class GattDescriptor1_proxy { sdbus::IProxy& m_proxy; }; -} // namespace org::bluez +} // namespace bluez +} // namespace org #endif diff --git a/src/proxy/org/bluez/GattManager1/gatt_manager1_proxy.h b/src/proxy/org/bluez/GattManager1/gatt_manager1_proxy.h index 5b0ab7d..e5fa471 100644 --- a/src/proxy/org/bluez/GattManager1/gatt_manager1_proxy.h +++ b/src/proxy/org/bluez/GattManager1/gatt_manager1_proxy.h @@ -3,26 +3,28 @@ * This file was automatically generated by sdbus-c++-xml2cpp; DO NOT EDIT! */ -#ifndef _sdbuscpp_src_proxy_org_bluez_GattManager1_gatt_manager1_proxy_h_proxy_H_ -#define _sdbuscpp_src_proxy_org_bluez_GattManager1_gatt_manager1_proxy_h_proxy_H_ +#ifndef __sdbuscpp__src_proxy_org_bluez_GattManager1_gatt_manager1_proxy_h__proxy__H__ +#define __sdbuscpp__src_proxy_org_bluez_GattManager1_gatt_manager1_proxy_h__proxy__H__ #include #include +#include -namespace org::bluez { +namespace org { +namespace bluez { class GattManager1_proxy { public: - static constexpr auto INTERFACE_NAME = "org.bluez.GattManager1"; + static constexpr const char* INTERFACE_NAME = "org.bluez.GattManager1"; + + protected: + GattManager1_proxy(sdbus::IProxy& proxy) : m_proxy(proxy) {} GattManager1_proxy(const GattManager1_proxy&) = delete; GattManager1_proxy& operator=(const GattManager1_proxy&) = delete; GattManager1_proxy(GattManager1_proxy&&) = delete; GattManager1_proxy& operator=(GattManager1_proxy&&) = delete; - protected: - explicit GattManager1_proxy(sdbus::IProxy& proxy) : m_proxy(proxy) {} - ~GattManager1_proxy() = default; void registerProxy() {} @@ -46,6 +48,7 @@ class GattManager1_proxy { sdbus::IProxy& m_proxy; }; -} // namespace org::bluez +} // namespace bluez +} // namespace org #endif diff --git a/src/proxy/org/bluez/GattService1/gatt_service1_proxy.h b/src/proxy/org/bluez/GattService1/gatt_service1_proxy.h index 41d5925..4a5d10b 100644 --- a/src/proxy/org/bluez/GattService1/gatt_service1_proxy.h +++ b/src/proxy/org/bluez/GattService1/gatt_service1_proxy.h @@ -3,26 +3,28 @@ * This file was automatically generated by sdbus-c++-xml2cpp; DO NOT EDIT! */ -#ifndef _sdbuscpp_src_proxy_org_bluez_GattService1_gatt_service1_proxy_h_proxy_H_ -#define _sdbuscpp_src_proxy_org_bluez_GattService1_gatt_service1_proxy_h_proxy_H_ +#ifndef __sdbuscpp__src_proxy_org_bluez_GattService1_gatt_service1_proxy_h__proxy__H__ +#define __sdbuscpp__src_proxy_org_bluez_GattService1_gatt_service1_proxy_h__proxy__H__ #include #include +#include -namespace org::bluez { +namespace org { +namespace bluez { class GattService1_proxy { public: - static constexpr auto INTERFACE_NAME = "org.bluez.GattService1"; + static constexpr const char* INTERFACE_NAME = "org.bluez.GattService1"; + + protected: + GattService1_proxy(sdbus::IProxy& proxy) : m_proxy(proxy) {} GattService1_proxy(const GattService1_proxy&) = delete; GattService1_proxy& operator=(const GattService1_proxy&) = delete; GattService1_proxy(GattService1_proxy&&) = delete; GattService1_proxy& operator=(GattService1_proxy&&) = delete; - protected: - explicit GattService1_proxy(sdbus::IProxy& proxy) : m_proxy(proxy) {} - ~GattService1_proxy() = default; void registerProxy() {} @@ -56,6 +58,7 @@ class GattService1_proxy { sdbus::IProxy& m_proxy; }; -} // namespace org::bluez +} // namespace bluez +} // namespace org #endif diff --git a/src/proxy/org/bluez/Input1/input_proxy.h b/src/proxy/org/bluez/Input1/input_proxy.h index d9623cd..9d5afbd 100644 --- a/src/proxy/org/bluez/Input1/input_proxy.h +++ b/src/proxy/org/bluez/Input1/input_proxy.h @@ -3,26 +3,28 @@ * This file was automatically generated by sdbus-c++-xml2cpp; DO NOT EDIT! */ -#ifndef _sdbuscpp_src_proxy_org_bluez_Input1_input_proxy_h_proxy_H_ -#define _sdbuscpp_src_proxy_org_bluez_Input1_input_proxy_h_proxy_H_ +#ifndef __sdbuscpp__src_proxy_org_bluez_Input1_input_proxy_h__proxy__H__ +#define __sdbuscpp__src_proxy_org_bluez_Input1_input_proxy_h__proxy__H__ #include #include +#include -namespace org::bluez { +namespace org { +namespace bluez { class Input1_proxy { public: - static constexpr auto INTERFACE_NAME = "org.bluez.Input1"; + static constexpr const char* INTERFACE_NAME = "org.bluez.Input1"; + + protected: + Input1_proxy(sdbus::IProxy& proxy) : m_proxy(proxy) {} Input1_proxy(const Input1_proxy&) = delete; Input1_proxy& operator=(const Input1_proxy&) = delete; Input1_proxy(Input1_proxy&&) = delete; Input1_proxy& operator=(Input1_proxy&&) = delete; - protected: - explicit Input1_proxy(sdbus::IProxy& proxy) : m_proxy(proxy) {} - ~Input1_proxy() = default; void registerProxy() {} @@ -38,6 +40,7 @@ class Input1_proxy { sdbus::IProxy& m_proxy; }; -} // namespace org::bluez +} // namespace bluez +} // namespace org #endif diff --git a/src/proxy/org/bluez/LEAdvertisingManager1/le_advertising_manager1_proxy.h b/src/proxy/org/bluez/LEAdvertisingManager1/le_advertising_manager1_proxy.h index 5f6dcc8..1079a63 100644 --- a/src/proxy/org/bluez/LEAdvertisingManager1/le_advertising_manager1_proxy.h +++ b/src/proxy/org/bluez/LEAdvertisingManager1/le_advertising_manager1_proxy.h @@ -3,17 +3,23 @@ * This file was automatically generated by sdbus-c++-xml2cpp; DO NOT EDIT! */ -#ifndef _sdbuscpp_src_proxy_org_bluez_LEAdvertisingManager1_le_advertising_manager1_proxy_h_proxy_H_ -#define _sdbuscpp_src_proxy_org_bluez_LEAdvertisingManager1_le_advertising_manager1_proxy_h_proxy_H_ +#ifndef __sdbuscpp__src_proxy_org_bluez_LEAdvertisingManager1_le_advertising_manager1_proxy_h__proxy__H__ +#define __sdbuscpp__src_proxy_org_bluez_LEAdvertisingManager1_le_advertising_manager1_proxy_h__proxy__H__ #include #include +#include -namespace org::bluez { +namespace org { +namespace bluez { class LEAdvertisingManager1_proxy { public: - static constexpr auto INTERFACE_NAME = "org.bluez.LEAdvertisingManager1"; + static constexpr const char* INTERFACE_NAME = + "org.bluez.LEAdvertisingManager1"; + + protected: + LEAdvertisingManager1_proxy(sdbus::IProxy& proxy) : m_proxy(proxy) {} LEAdvertisingManager1_proxy(const LEAdvertisingManager1_proxy&) = delete; LEAdvertisingManager1_proxy& operator=(const LEAdvertisingManager1_proxy&) = @@ -22,9 +28,6 @@ class LEAdvertisingManager1_proxy { LEAdvertisingManager1_proxy& operator=(LEAdvertisingManager1_proxy&&) = delete; - protected: - explicit LEAdvertisingManager1_proxy(sdbus::IProxy& proxy) : m_proxy(proxy) {} - ~LEAdvertisingManager1_proxy() = default; void registerProxy() {} @@ -73,6 +76,7 @@ class LEAdvertisingManager1_proxy { sdbus::IProxy& m_proxy; }; -} // namespace org::bluez +} // namespace bluez +} // namespace org #endif diff --git a/src/proxy/org/bluez/Media1/media1_proxy.h b/src/proxy/org/bluez/Media1/media1_proxy.h index 1370b16..4a6625a 100644 --- a/src/proxy/org/bluez/Media1/media1_proxy.h +++ b/src/proxy/org/bluez/Media1/media1_proxy.h @@ -3,26 +3,28 @@ * This file was automatically generated by sdbus-c++-xml2cpp; DO NOT EDIT! */ -#ifndef _sdbuscpp_src_proxy_org_bluez_Media1_media1_proxy_h_proxy_H_ -#define _sdbuscpp_src_proxy_org_bluez_Media1_media1_proxy_h_proxy_H_ +#ifndef __sdbuscpp__src_proxy_org_bluez_Media1_media1_proxy_h__proxy__H__ +#define __sdbuscpp__src_proxy_org_bluez_Media1_media1_proxy_h__proxy__H__ #include #include +#include -namespace org::bluez { +namespace org { +namespace bluez { class Media1_proxy { public: - static constexpr auto INTERFACE_NAME = "org.bluez.Media1"; + static constexpr const char* INTERFACE_NAME = "org.bluez.Media1"; + + protected: + Media1_proxy(sdbus::IProxy& proxy) : m_proxy(proxy) {} Media1_proxy(const Media1_proxy&) = delete; Media1_proxy& operator=(const Media1_proxy&) = delete; Media1_proxy(Media1_proxy&&) = delete; Media1_proxy& operator=(Media1_proxy&&) = delete; - protected: - explicit Media1_proxy(sdbus::IProxy& proxy) : m_proxy(proxy) {} - ~Media1_proxy() = default; void registerProxy() {} @@ -80,6 +82,7 @@ class Media1_proxy { sdbus::IProxy& m_proxy; }; -} // namespace org::bluez +} // namespace bluez +} // namespace org #endif diff --git a/src/proxy/org/bluez/NetworkServer1/network_server1_proxy.h b/src/proxy/org/bluez/NetworkServer1/network_server1_proxy.h index 9a21bab..a900de6 100644 --- a/src/proxy/org/bluez/NetworkServer1/network_server1_proxy.h +++ b/src/proxy/org/bluez/NetworkServer1/network_server1_proxy.h @@ -3,26 +3,28 @@ * This file was automatically generated by sdbus-c++-xml2cpp; DO NOT EDIT! */ -#ifndef _sdbuscpp_src_proxy_org_bluez_NetworkServer1_network_server1_proxy_h_proxy_H_ -#define _sdbuscpp_src_proxy_org_bluez_NetworkServer1_network_server1_proxy_h_proxy_H_ +#ifndef __sdbuscpp__src_proxy_org_bluez_NetworkServer1_network_server1_proxy_h__proxy__H__ +#define __sdbuscpp__src_proxy_org_bluez_NetworkServer1_network_server1_proxy_h__proxy__H__ #include #include +#include -namespace org::bluez { +namespace org { +namespace bluez { class NetworkServer1_proxy { public: - static constexpr auto INTERFACE_NAME = "org.bluez.NetworkServer1"; + static constexpr const char* INTERFACE_NAME = "org.bluez.NetworkServer1"; + + protected: + NetworkServer1_proxy(sdbus::IProxy& proxy) : m_proxy(proxy) {} NetworkServer1_proxy(const NetworkServer1_proxy&) = delete; NetworkServer1_proxy& operator=(const NetworkServer1_proxy&) = delete; NetworkServer1_proxy(NetworkServer1_proxy&&) = delete; NetworkServer1_proxy& operator=(NetworkServer1_proxy&&) = delete; - protected: - explicit NetworkServer1_proxy(sdbus::IProxy& proxy) : m_proxy(proxy) {} - ~NetworkServer1_proxy() = default; void registerProxy() {} @@ -44,6 +46,7 @@ class NetworkServer1_proxy { sdbus::IProxy& m_proxy; }; -} // namespace org::bluez +} // namespace bluez +} // namespace org #endif diff --git a/src/proxy/org/bluez/Profile1/profile1_proxy.h b/src/proxy/org/bluez/Profile1/profile1_proxy.h index d0a2e96..3890ea8 100644 --- a/src/proxy/org/bluez/Profile1/profile1_proxy.h +++ b/src/proxy/org/bluez/Profile1/profile1_proxy.h @@ -3,27 +3,28 @@ * This file was automatically generated by sdbus-c++-xml2cpp; DO NOT EDIT! */ -#ifndef _sdbuscpp_src_proxy_org_bluez_Profile1_profile1_proxy_h_proxy_H_ -#define _sdbuscpp_src_proxy_org_bluez_Profile1_profile1_proxy_h_proxy_H_ +#ifndef __sdbuscpp__src_proxy_org_bluez_Profile1_profile1_proxy_h__proxy__H__ +#define __sdbuscpp__src_proxy_org_bluez_Profile1_profile1_proxy_h__proxy__H__ #include #include #include -namespace org::bluez { +namespace org { +namespace bluez { class Profile1_proxy { public: - static constexpr auto INTERFACE_NAME = "org.bluez.Profile1"; + static constexpr const char* INTERFACE_NAME = "org.bluez.Profile1"; + + protected: + Profile1_proxy(sdbus::IProxy& proxy) : m_proxy(proxy) {} Profile1_proxy(const Profile1_proxy&) = delete; Profile1_proxy& operator=(const Profile1_proxy&) = delete; Profile1_proxy(Profile1_proxy&&) = delete; Profile1_proxy& operator=(Profile1_proxy&&) = delete; - protected: - explicit Profile1_proxy(sdbus::IProxy& proxy) : m_proxy(proxy) {} - ~Profile1_proxy() = default; void registerProxy() {} @@ -52,6 +53,7 @@ class Profile1_proxy { sdbus::IProxy& m_proxy; }; -} // namespace org::bluez +} // namespace bluez +} // namespace org #endif diff --git a/src/timedate1/main.cc b/src/timedate1/main.cc index 4e44ef7..f3bc4fa 100644 --- a/src/timedate1/main.cc +++ b/src/timedate1/main.cc @@ -14,6 +14,8 @@ #include "timedate1_client.h" +#include + #include "../utils/logging.h" #include "../utils/utils.h" @@ -23,19 +25,21 @@ int main() { Timedate1Client client(*connection); - std::future> futures[4]; - std::promise> promises[4]; + std::array>, 4> + futures; + std::array>, 4> + promises; for (int i = 0; i < 4; ++i) { - futures[i] = promises[i].get_future(); + futures.at(i) = promises.at(i).get_future(); client.GetAllAsync( Timedate1Client::INTERFACE_NAME, [&, i](std::optional error, std::map values) { if (!error) - promises[i].set_value(std::move(values)); + promises.at(i).set_value(std::move(values)); else - promises[i].set_exception(std::make_exception_ptr(*error)); + promises.at(i).set_exception(std::make_exception_ptr(*error)); }); } diff --git a/src/udisks2/udisks2_monitor_daemon.cc b/src/udisks2/udisks2_monitor_daemon.cc index 6effdf5..7771157 100644 --- a/src/udisks2/udisks2_monitor_daemon.cc +++ b/src/udisks2/udisks2_monitor_daemon.cc @@ -14,6 +14,8 @@ #include +#include +#include #include #include #include @@ -21,8 +23,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -50,7 +54,7 @@ class BlockDeviceWatcher sdbus::ObjectPath drivePath, DeviceReadyCallback callback) : ProxyInterfaces(connection, - sdbus::ServiceName(kInterfaceName), + sdbus::ServiceName(std::string{kInterfaceName}), objectPath), drive_path_(std::move(drivePath)), callback_(std::move(callback)), @@ -62,9 +66,10 @@ class BlockDeviceWatcher ~BlockDeviceWatcher() { unregisterProxy(); } private: - static constexpr char kInterfaceName[] = "org.freedesktop.UDisks2"; - static constexpr char kBlockInterface[] = "org.freedesktop.UDisks2.Block"; - static constexpr char kFilesystemInterface[] = + static constexpr std::string_view kInterfaceName = "org.freedesktop.UDisks2"; + static constexpr std::string_view kBlockInterface = + "org.freedesktop.UDisks2.Block"; + static constexpr std::string_view kFilesystemInterface = "org.freedesktop.UDisks2.Filesystem"; sdbus::ObjectPath drive_path_; @@ -76,7 +81,8 @@ class BlockDeviceWatcher const sdbus::InterfaceName& interfaceName, const std::map& changedProperties, const std::vector& invalidatedProperties) override { - if (const sdbus::InterfaceName blockInterfaceName(kBlockInterface); + if (const sdbus::InterfaceName blockInterfaceName( + std::string{kBlockInterface}); interfaceName == blockInterfaceName && !reported_) { // Check if IdUsage or other relevant properties changed const sdbus::PropertyName idUsageProp("IdUsage"); @@ -95,7 +101,8 @@ class BlockDeviceWatcher try { // Get block properties - const sdbus::InterfaceName blockInterfaceName(kBlockInterface); + const sdbus::InterfaceName blockInterfaceName( + std::string{kBlockInterface}); auto blockProps = GetAll(blockInterfaceName); // Check if this is a filesystem @@ -114,7 +121,7 @@ class BlockDeviceWatcher std::map filesystemProps; try { const sdbus::InterfaceName filesystemInterfaceName( - kFilesystemInterface); + std::string{kFilesystemInterface}); filesystemProps = GetAll(filesystemInterfaceName); hasFilesystem = true; } catch (...) { @@ -126,8 +133,8 @@ class BlockDeviceWatcher std::map driveProps; try { const auto driveProxy = sdbus::createProxy( - getProxy().getConnection(), sdbus::ServiceName(kInterfaceName), - drive_path_); + getProxy().getConnection(), + sdbus::ServiceName(std::string{kInterfaceName}), drive_path_); const sdbus::InterfaceName driveInterfaceName( "org.freedesktop.UDisks2.Drive"); driveProps = @@ -156,8 +163,8 @@ class RemovableDeviceMonitor final explicit RemovableDeviceMonitor(sdbus::IConnection& connection, DeviceReadyCallback callback) : ProxyInterfaces(connection, - sdbus::ServiceName(kInterfaceName), - sdbus::ObjectPath(kObjectPath)), + sdbus::ServiceName(std::string{kInterfaceName}), + sdbus::ObjectPath(std::string{kObjectPath})), callback_(std::move(callback)) { registerProxy(); @@ -173,8 +180,8 @@ class RemovableDeviceMonitor final ~RemovableDeviceMonitor() { unregisterProxy(); } private: - static constexpr auto kInterfaceName = "org.freedesktop.UDisks2"; - static constexpr auto kObjectPath = "/org/freedesktop/UDisks2"; + static constexpr std::string_view kInterfaceName = "org.freedesktop.UDisks2"; + static constexpr std::string_view kObjectPath = "/org/freedesktop/UDisks2"; DeviceReadyCallback callback_; std::map> watchers_; @@ -194,7 +201,7 @@ class RemovableDeviceMonitor final interfacesAndProperties) override { // Check if this is a Block device const sdbus::InterfaceName blockInterface("org.freedesktop.UDisks2.Block"); - auto blockIt = interfacesAndProperties.find(blockInterface); + const auto blockIt = interfacesAndProperties.find(blockInterface); if (blockIt == interfacesAndProperties.end()) { return; } @@ -215,9 +222,9 @@ class RemovableDeviceMonitor final // Check if the drive is removable try { - const auto driveProxy = - sdbus::createProxy(getProxy().getConnection(), - sdbus::ServiceName(kInterfaceName), drivePath); + const auto driveProxy = sdbus::createProxy( + getProxy().getConnection(), + sdbus::ServiceName(std::string{kInterfaceName}), drivePath); const sdbus::InterfaceName driveInterfaceName( "org.freedesktop.UDisks2.Drive"); @@ -250,7 +257,7 @@ class RemovableDeviceMonitor final void onInterfacesRemoved( const sdbus::ObjectPath& objectPath, const std::vector& interfaces) override { - // Clean up watcher when device is removed + // Clean up watcher when a device is removed const sdbus::InterfaceName blockInterface("org.freedesktop.UDisks2.Block"); for (const auto& interface : interfaces) { if (interface == blockInterface) { @@ -270,19 +277,24 @@ std::string byteArrayToString(const std::vector& bytes) { return ""; } // Remove trailing null bytes - size_t len = bytes.size(); - while (len > 0 && bytes[len - 1] == 0) { - --len; + auto end = bytes.cend(); + while (end != bytes.cbegin() && *(end - 1) == 0) { + --end; } - // Construct string from raw data and explicit size to avoid iterator - // arithmetic with mixed signed/unsigned types. - return {reinterpret_cast(bytes.data()), len}; + // Copy bytes into string without reinterpret_cast or subscript decay + std::string result; + result.reserve(static_cast(std::distance(bytes.cbegin(), end))); + for (auto it = bytes.cbegin(); it != end; ++it) { + result.push_back(std::bit_cast(*it)); + } + return result; } // Helper to format size in human-readable format std::string formatSize(const uint64_t bytes) { - constexpr const char* units[] = {"B", "KB", "MB", "GB", "TB"}; - constexpr int max_unit = std::size(units) - 1; + static constexpr std::array units{"B", "KB", "MB", "GB", + "TB"}; + static constexpr int max_unit = static_cast(units.size()) - 1; int unit = 0; auto size = static_cast(bytes); @@ -295,7 +307,8 @@ std::string formatSize(const uint64_t bytes) { } std::ostringstream oss; - oss << std::fixed << std::setprecision(2) << size << " " << units[unit]; + oss << std::fixed << std::setprecision(2) << size << " " + << units.at(static_cast(unit)); return oss.str(); } diff --git a/src/utils/logging.h b/src/utils/logging.h index 819d0b1..14d44dc 100644 --- a/src/utils/logging.h +++ b/src/utils/logging.h @@ -38,9 +38,11 @@ // SINGLE INCLUDE OF SPDLOG - ONLY LOCATION IN CODEBASE // ============================================================================ #include +#include #include #include #include +#include #include #include @@ -53,6 +55,107 @@ namespace logging_config { +// ============================================================================ +// INPUT VALIDATION +// ============================================================================ + +/** + * @brief Validate a log file path supplied via the LOG_FILE environment + * variable. + * + * Rejects values that could be used for path-traversal or other attacks: + * - Paths containing ".." components + * - Paths containing null bytes + * - Paths containing newline / carriage-return characters + * - Paths that start with '-' (would be misinterpreted as flags) + * + * @param path Candidate path string. + * @return true if the path is considered safe to use. + * @return false if the path is rejected; a warning is emitted. + */ +inline bool isLogFilePathSafe(const std::string& path) { + if (path.empty()) { + return true; // empty == "no file logging", always safe + } + + // Null bytes anywhere in the string + if (path.find('\0') != std::string::npos) { + spdlog::warn("LOG_FILE rejected: contains null byte"); + return false; + } + + // Newline / carriage-return (log-injection vector) + if (path.find('\n') != std::string::npos || + path.find('\r') != std::string::npos) { + spdlog::warn("LOG_FILE rejected: contains newline character"); + return false; + } + + // Leading dash (could be misinterpreted as a flag by some open() wrappers) + if (path.front() == '-') { + spdlog::warn("LOG_FILE rejected: starts with '-'"); + return false; + } + + // Path-traversal: reject any ".." component + // Walk the string looking for the sequence (/ | start) ".." (/ | end) + const std::string_view sv(path); + std::string_view::size_type pos = 0; + while (pos < sv.size()) { + // find the next slash or end + const auto slash = sv.find('/', pos); + const std::string_view component = + sv.substr(pos, slash == std::string_view::npos ? std::string_view::npos + : slash - pos); + if (component == "..") { + spdlog::warn("LOG_FILE rejected: path traversal component '..' detected"); + return false; + } + if (slash == std::string_view::npos) { + break; + } + pos = slash + 1; + } + + return true; +} + +/** + * @brief Validate a log pattern supplied via the LOG_PATTERN environment + * variable. + * + * spdlog patterns use %-prefixed tokens (e.g. %Y, %H, %l, %v). An attacker + * who controls the pattern string cannot trigger printf-style vulnerabilities + * (spdlog does not use printf internally), but an unexpected pattern can: + * - Cause spdlog to crash / behave unexpectedly with unknown tokens + * - Inject ANSI escape sequences or other control characters + * + * We allow only the printable ASCII characters that appear in typical spdlog + * patterns and reject any non-printable or non-ASCII byte. + * + * @param pattern Candidate pattern string. + * @return true if the pattern is considered safe. + * @return false if the pattern is rejected; a warning is emitted. + */ +inline bool isLogPatternSafe(const std::string& pattern) { + if (pattern.empty()) { + return true; // empty == use default, always safe + } + + for (const unsigned char ch : pattern) { + // Allow printable ASCII only (0x20–0x7E) plus tab (0x09) + if (ch != 0x09 && (ch < 0x20 || ch > 0x7E)) { + spdlog::warn( + "LOG_PATTERN rejected: contains non-printable or non-ASCII byte " + "(0x{:02X})", + static_cast(ch)); + return false; + } + } + + return true; +} + /** * @brief Get log level from the environment variable or default to info * @return spdlog::level::level_enum @@ -79,29 +182,68 @@ inline spdlog::level::level_enum getLogLevelFromEnv() { if (level == "off") return spdlog::level::off; + // Unknown value — fall back to info and warn the operator + spdlog::warn("LOG_LEVEL '{}' is not recognised; defaulting to 'info'", level); return spdlog::level::info; } /** - * @brief Check if file logging is enabled via an environment variable - * @return std::string path to a log file, empty string if disabled + * @brief Check if file logging is enabled via an environment variable. + * + * The path is validated by isLogFilePathSafe() before being returned. + * An unsafe path is treated the same as an absent variable (no file logging). + * + * @return std::string validated path to a log file, or empty string. */ inline std::string getLogFilePathFromEnv() { const char* log_file = std::getenv("LOG_FILE"); - return log_file ? std::string(log_file) : ""; + if (!log_file) { + return {}; + } + std::string path(log_file); + if (!isLogFilePathSafe(path)) { + // Warning already emitted by isLogFilePathSafe(); fall back to no file. + return {}; + } + return path; } /** * @brief Initialize logging with console and optional file output + * + * Finding 8 — SPDLOG_NO_EXCEPTIONS ON: with exceptions disabled spdlog routes + * internal errors (bad sink path, disk full, etc.) through its error handler + * instead of throwing. We install a custom handler that writes to stderr so + * that failures are never silently dropped. The handler is set *before* any + * sink is constructed so that even sink-construction failures are visible. + * * @param logger_name Name of the logger instance */ inline void initializeLogging(const std::string& logger_name = "default") { + // Install the error handler first so sink-construction failures are visible. + // This is the *only* reliable notification path when SPDLOG_NO_EXCEPTIONS ON. + spdlog::set_error_handler([](const std::string& msg) { + // Cannot use spdlog itself here (we may be inside spdlog). + // Write directly to stderr so the failure is always visible. + std::fprintf(stderr, "[spdlog error] %s\n", msg.c_str()); + }); + try { const auto level = getLogLevelFromEnv(); - auto log_file = getLogFilePathFromEnv(); - const char* pattern_str = std::getenv("LOG_PATTERN"); - const std::string pattern = pattern_str ? std::string(pattern_str) - : "[%Y-%m-%d %H:%M:%S.%e] [%l] %v"; + const auto log_file = getLogFilePathFromEnv(); + + // Validate LOG_PATTERN; fall back to the safe built-in default if unsafe. + static constexpr std::string_view kDefaultPattern = + "[%Y-%m-%d %H:%M:%S.%e] [%l] %v"; + const char* pattern_env = std::getenv("LOG_PATTERN"); + std::string pattern; + if (pattern_env) { + const std::string candidate(pattern_env); + pattern = isLogPatternSafe(candidate) ? candidate + : std::string(kDefaultPattern); + } else { + pattern = std::string(kDefaultPattern); + } const auto console_sink = std::make_shared(); @@ -131,6 +273,10 @@ inline void initializeLogging(const std::string& logger_name = "default") { spdlog::level::to_string_view(level), log_file.empty() ? "console only" : log_file); } catch (const spdlog::spdlog_ex& ex) { + // This branch is reached when SPDLOG_NO_EXCEPTIONS is OFF. + // Mirror the error-handler path so the failure is always on stderr. + std::fprintf(stderr, "[spdlog error] Log initialization failed: %s\n", + ex.what()); spdlog::error("Log initialization failed: {}", ex.what()); } } diff --git a/third_party/CMakeLists.txt b/third_party/CMakeLists.txt index a5e357d..c7a6100 100644 --- a/third_party/CMakeLists.txt +++ b/third_party/CMakeLists.txt @@ -15,6 +15,11 @@ install(TARGETS toolchain EXPORT sdbus-c++-targets) # # spdlog # +# Exceptions are disabled so spdlog's internal errors (bad sink path, disk +# full, etc.) are routed through its error-handler instead of being thrown. +# A custom spdlog::set_error_handler() is installed in src/utils/logging.h +# before any sink is constructed so these failures are always written to +# stderr rather than silently dropped. set(SPDLOG_NO_EXCEPTIONS ON) set(SPDLOG_NO_THREAD_ID ON) set(SPDLOG_BUILD_PIC ON)