Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ sudo udevadm control --reload-rules && sudo udevadm trigger

| Device | Platform | sidetone | battery | notification sound | lights | inactive time | chatmix | voice prompts | rotate to mute | equalizer preset | equalizer | parametric equalizer | microphone mute led brightness | microphone volume | volume limiter | bluetooth when powered on | bluetooth call volume | microphone noise filter | sidetone status |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| Logitech ASTRO A50 Gen 4 | All | x | x | | | | x | | | x | x | x | | x | | | | x | x |
| Logitech ASTRO A50 Gen 5 | All | x | x | | x | | x | | | | | x | | | | | | x | |
| Logitech G522 LIGHTSPEED | All | x | x | | | x | | | | | | | x | | | | | | |
| Logitech G533 | All | x | x | | | x | | | | | | | | | | | | | |
Expand Down
17 changes: 12 additions & 5 deletions cli/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,7 @@ class HIDConnection {

HIDConnection(HIDConnection&& other) noexcept
: handle_(other.handle_)
, device_(other.device_)
, path_(std::move(other.path_))
{
other.handle_ = nullptr;
Expand All @@ -393,6 +394,7 @@ class HIDConnection {
{
if (this != &other) {
close();
device_ = other.device_;
handle_ = other.handle_;
path_ = std::move(other.path_);
other.handle_ = nullptr;
Expand All @@ -403,14 +405,15 @@ class HIDConnection {
[[nodiscard]] bool isOpen() const { return handle_ != nullptr; }
[[nodiscard]] hid_device* get() const { return handle_; }

bool open(const std::string& new_path)
bool open(const std::string& new_path, const HIDDevice* device)
{
if (path_ == new_path && handle_)
if (path_ == new_path && handle_ && device_ == device)
return true;
close();
handle_ = hid_open_path(new_path.c_str());
if (handle_) {
path_ = new_path;
device_ = device;
path_ = new_path;
return true;
}
return false;
Expand All @@ -419,14 +422,18 @@ class HIDConnection {
void close()
{
if (handle_) {
if (device_) {
device_->onConnectionClosed(handle_);
}
hid_close(handle_);
handle_ = nullptr;
}
path_.clear();
}

private:
hid_device* handle_ = nullptr;
hid_device* handle_ = nullptr;
const HIDDevice* device_ = nullptr;
std::string path_;
};

Expand Down Expand Up @@ -548,7 +555,7 @@ hid_device* connectForCapability(HIDConnection& conn, const HIDDevice* device, u
if (!hid_path)
return nullptr;

return conn.open(*hid_path) ? conn.get() : nullptr;
return conn.open(*hid_path, device) ? conn.get() : nullptr;
}

// Convert FeatureOutput to FeatureResult for output formatting
Expand Down
2 changes: 2 additions & 0 deletions lib/device_registry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

// Logitech devices
#include "devices/logitech_astro_a50.hpp"
#include "devices/logitech_astro_a50_gen4.hpp"

// Logitech devices with HIDPPDevice protocol template
#include "devices/logitech_g432.hpp"
Expand Down Expand Up @@ -107,6 +108,7 @@ void DeviceRegistry::initialize()
// Each device is managed by a unique_ptr for automatic cleanup

// Logitech devices
registerDevice(std::make_unique<LogitechAstroA50Gen4>());
registerDevice(std::make_unique<LogitechAstroA50>());

// Logitech devices (using HIDPPDevice protocol template)
Expand Down
9 changes: 9 additions & 0 deletions lib/devices/hid_device.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,15 @@ class HIDDevice {
return { .usagepage = 0, .usageid = 0, .interface_id = 0 };
}

/**
* @brief Release per-connection protocol state when a HID handle is closed.
*
* Optional. Devices that keep per-handle state recover on their own if this is
* skipped; calling it before hid_close() avoids a bounded delay on the next
* request if the handle address is reused.
*/
virtual void onConnectionClosed(hid_device* /*device_handle*/) const { }

/**
* @brief Get equalizer presets count
*/
Expand Down
Loading