Skip to content

Commit 314ca89

Browse files
authored
Winrt full support (#266)
windows: full functionality
1 parent 6b08161 commit 314ca89

8 files changed

+427
-5
lines changed

Makefile

+2
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ smoketest-windows:
5858
GOOS=windows go build -o /tmp/go-build-discard ./examples/scanner
5959
GOOS=windows go build -o /tmp/go-build-discard ./examples/discover
6060
GOOS=windows go build -o /tmp/go-build-discard ./examples/heartrate-monitor
61+
GOOS=windows go build -o /tmp/go-build-discard ./examples/advertisement
62+
GOOS=windows go build -o /tmp/go-build-discard ./examples/heartrate
6163

6264
smoketest-macos:
6365
# Test on macos.

adapter_windows.go

+8
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package bluetooth
22

33
import (
4+
"errors"
45
"fmt"
56

67
"github.com/go-ole/go-ole"
@@ -13,6 +14,8 @@ type Adapter struct {
1314
watcher *advertisement.BluetoothLEAdvertisementWatcher
1415

1516
connectHandler func(device Device, connected bool)
17+
18+
defaultAdvertisement *Advertisement
1619
}
1720

1821
// DefaultAdapter is the default adapter on the system.
@@ -56,3 +59,8 @@ func awaitAsyncOperation(asyncOperation *foundation.IAsyncOperation, genericPara
5659
}
5760
return nil
5861
}
62+
63+
func (a *Adapter) Address() (MACAddress, error) {
64+
// TODO: get mac address
65+
return MACAddress{}, errors.New("not implemented")
66+
}

gap_windows.go

+102
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,108 @@ type Address struct {
1818
MACAddress
1919
}
2020

21+
type Advertisement struct {
22+
advertisement *advertisement.BluetoothLEAdvertisement
23+
publisher *advertisement.BluetoothLEAdvertisementPublisher
24+
}
25+
26+
// DefaultAdvertisement returns the default advertisement instance but does not
27+
// configure it.
28+
func (a *Adapter) DefaultAdvertisement() *Advertisement {
29+
if a.defaultAdvertisement == nil {
30+
a.defaultAdvertisement = &Advertisement{}
31+
}
32+
33+
return a.defaultAdvertisement
34+
}
35+
36+
// Configure this advertisement.
37+
// on Windows we're only able to set "Manufacturer Data" for advertisements.
38+
// https://learn.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.advertisement.bluetoothleadvertisementpublisher?view=winrt-22621#remarks
39+
// following this c# source for this implementation: https://github.com/microsoft/Windows-universal-samples/blob/main/Samples/BluetoothAdvertisement/cs/Scenario2_Publisher.xaml.cs
40+
// adding service data / localname leads to errors when starting the advertisement.
41+
func (a *Advertisement) Configure(options AdvertisementOptions) error {
42+
// we can only advertise manufacturer / company data on windows, so no need to continue if we have none
43+
if len(options.ManufacturerData) == 0 {
44+
return nil
45+
}
46+
47+
if a.publisher != nil {
48+
a.publisher.Release()
49+
}
50+
51+
if a.advertisement != nil {
52+
a.advertisement.Release()
53+
}
54+
55+
pub, err := advertisement.NewBluetoothLEAdvertisementPublisher()
56+
if err != nil {
57+
return err
58+
}
59+
60+
a.publisher = pub
61+
62+
ad, err := a.publisher.GetAdvertisement()
63+
if err != nil {
64+
return err
65+
}
66+
67+
a.advertisement = ad
68+
69+
vec, err := ad.GetManufacturerData()
70+
if err != nil {
71+
return err
72+
}
73+
74+
for _, optManData := range options.ManufacturerData {
75+
writer, err := streams.NewDataWriter()
76+
if err != nil {
77+
return err
78+
}
79+
defer writer.Release()
80+
81+
err = writer.WriteBytes(uint32(len(optManData.Data)), optManData.Data)
82+
if err != nil {
83+
return err
84+
}
85+
86+
buf, err := writer.DetachBuffer()
87+
if err != nil {
88+
return err
89+
}
90+
91+
manData, err := advertisement.BluetoothLEManufacturerDataCreate(optManData.CompanyID, buf)
92+
if err != nil {
93+
return err
94+
}
95+
96+
if err = vec.Append(unsafe.Pointer(&manData.IUnknown.RawVTable)); err != nil {
97+
return err
98+
}
99+
}
100+
101+
return nil
102+
}
103+
104+
// Start advertisement. May only be called after it has been configured.
105+
func (a *Advertisement) Start() error {
106+
// publisher will be present if we actually have manufacturer data to advertise.
107+
if a.publisher != nil {
108+
return a.publisher.Start()
109+
}
110+
111+
return nil
112+
}
113+
114+
// Stop advertisement. May only be called after it has been started.
115+
func (a *Advertisement) Stop() error {
116+
if a.publisher != nil {
117+
return a.publisher.Stop()
118+
}
119+
120+
return nil
121+
}
122+
21123
// Scan starts a BLE scan. It is stopped by a call to StopScan. A common pattern
22124
// is to cancel the scan when a particular device has been found.
23125
func (a *Adapter) Scan(callback func(*Adapter, ScanResult)) (err error) {

gatts.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ type Service struct {
77
Characteristics []CharacteristicConfig
88
}
99

10+
type WriteEvent = func(client Connection, offset int, value []byte)
11+
1012
// CharacteristicConfig contains some parameters for the configuration of a
1113
// single characteristic.
1214
//
@@ -17,7 +19,7 @@ type CharacteristicConfig struct {
1719
UUID
1820
Value []byte
1921
Flags CharacteristicPermissions
20-
WriteEvent func(client Connection, offset int, value []byte)
22+
WriteEvent WriteEvent
2123
}
2224

2325
// CharacteristicPermissions lists a number of basic permissions/capabilities

gatts_other.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//go:build !linux
1+
//go:build !linux && !windows
22

33
package bluetooth
44

0 commit comments

Comments
 (0)