From 0f8fc508b5907a8cff5a5751bc52e2c6d8e254f9 Mon Sep 17 00:00:00 2001 From: Alexis Couvreur Date: Tue, 17 Mar 2026 11:11:06 -0400 Subject: [PATCH 1/2] feat(gap): add ConnectionLatency in ConnectionParams These settings are alternatives for platforms that do not support settings the MinInterval and MaxInterval directly. --- gap.go | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/gap.go b/gap.go index e0c346a..1f93fc6 100644 --- a/gap.go +++ b/gap.go @@ -586,6 +586,19 @@ func (buf *rawAdvertisementPayload) addServiceUUID(uuid UUID) (ok bool) { } } +type ConnectionLatency uint8 + +const ( + // A latency setting that uses the default connection parameters of the system. + ConnectionLatencyDefault ConnectionLatency = 0 + // A latency setting indicating that prioritizes rapid communication over battery life. + ConnectionLatencyLow ConnectionLatency = 1 + // A latency setting that balances communication frequency and battery life. + ConnectionLatencyMedium ConnectionLatency = 2 + // A latency setting that prioritizes extending battery life over rapid communication. + ConnectionLatencyHigh ConnectionLatency = 3 +) + // ConnectionParams are used when connecting to a peripherals or when changing // the parameters of an active connection. type ConnectionParams struct { @@ -604,4 +617,14 @@ type ConnectionParams struct { // communication, the connection is considered lost. If no timeout is // specified, the timeout will be unchanged. Timeout Duration + + // Latency setting. This is a high-level setting that indicates whether the connection should + // prioritize rapid communication or battery life. + // + // Some platforms (e.g. Windows) may not support setting the connection parameters directly, + // but may support setting a latency level that corresponds to a set of connection parameters. + // In this case, the Latency field can be used to set the latency level instead of setting the connection parameters directly. + // + // If no latency is specified, the latency will be unchanged. + Latency ConnectionLatency } From 74b51a8eb69a7c82cde481cb924db6f62c9ea2f2 Mon Sep 17 00:00:00 2001 From: Alexis Couvreur Date: Tue, 17 Mar 2026 11:15:24 -0400 Subject: [PATCH 2/2] feat(windows): implement RequestConnectionParams using ConnectionLatency --- gap_windows.go | 34 +++++++++++++++++++++++++++++++--- go.mod | 2 +- go.sum | 2 ++ 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/gap_windows.go b/gap_windows.go index 171f96b..1c72333 100644 --- a/gap_windows.go +++ b/gap_windows.go @@ -433,13 +433,41 @@ func (d Device) Disconnect() error { // Whether or not the device will actually honor this, depends on the device and // on the specific parameters. // -// On Windows, this call doesn't do anything. +// On Windows, only the latency level can be set, since Windows does not support setting the connection parameters directly. +// If a latency level is specified, the corresponding latency level will be set on the connection. +// If no latency level is specified, the latency level will be left unchanged. func (d Device) RequestConnectionParams(params ConnectionParams) error { - // TODO: implement this using - // BluetoothLEDevice.RequestPreferredConnectionParameters. + pref, err := preferredConnectionParametersFromConnectionParams(params) + if err != nil { + return err + } + + // The user has requested a specific connection latency + if pref != nil { + _, err = d.device.RequestPreferredConnectionParameters(pref) + if err != nil { + return err + } + } + return nil } +func preferredConnectionParametersFromConnectionParams(params ConnectionParams) (*bluetooth.BluetoothLEPreferredConnectionParameters, error) { + switch params.Latency { + case ConnectionLatencyDefault: + return nil, nil + case ConnectionLatencyLow: + return bluetooth.BluetoothLEPreferredConnectionParametersGetThroughputOptimized() + case ConnectionLatencyMedium: + return bluetooth.BluetoothLEPreferredConnectionParametersGetBalanced() + case ConnectionLatencyHigh: + return bluetooth.BluetoothLEPreferredConnectionParametersGetPowerOptimized() + default: + return nil, fmt.Errorf("invalid latency value: %d", params.Latency) + } +} + // SetRandomAddress sets the random address to be used for advertising. func (a *Adapter) SetRandomAddress(mac MAC) error { return errors.ErrUnsupported diff --git a/go.mod b/go.mod index 6b79071..645592b 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.22.1 require ( github.com/go-ole/go-ole v1.2.6 github.com/godbus/dbus/v5 v5.1.0 - github.com/saltosystems/winrt-go v0.0.0-20240509164145-4f7860a3bd2b + github.com/saltosystems/winrt-go v0.0.0-20260309155547-a4512e2b5ee5 github.com/soypat/cyw43439 v0.0.0-20250505012923-830110c8f4af github.com/tinygo-org/cbgo v0.0.4 golang.org/x/crypto v0.12.0 diff --git a/go.sum b/go.sum index b7eeec2..f26d573 100644 --- a/go.sum +++ b/go.sum @@ -12,6 +12,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/saltosystems/winrt-go v0.0.0-20240509164145-4f7860a3bd2b h1:du3zG5fd8snsFN6RBoLA7fpaYV9ZQIsyH9snlk2Zvik= github.com/saltosystems/winrt-go v0.0.0-20240509164145-4f7860a3bd2b/go.mod h1:CIltaIm7qaANUIvzr0Vmz71lmQMAIbGJ7cvgzX7FMfA= +github.com/saltosystems/winrt-go v0.0.0-20260309155547-a4512e2b5ee5 h1:uWLD1I1ZF6JenjrTSB80JcHp/lXngoG5xuN8dT8Tbvg= +github.com/saltosystems/winrt-go v0.0.0-20260309155547-a4512e2b5ee5/go.mod h1:CIltaIm7qaANUIvzr0Vmz71lmQMAIbGJ7cvgzX7FMfA= github.com/sirupsen/logrus v1.5.0/go.mod h1:+F7Ogzej0PZc/94MaYx/nvG9jOFMD2osvC3s+Squfpo= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=