From ceb8bd80465a6ab03d7175f9da005f7d8a6ffaca Mon Sep 17 00:00:00 2001 From: deadprogram Date: Wed, 29 Jul 2026 19:54:36 +0200 Subject: [PATCH 1/2] ci: use go.mod file as minimum Go version for macOS tests Signed-off-by: deadprogram --- .github/workflows/macos.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 7ac2c16..8908485 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -16,12 +16,12 @@ jobs: name: macos-14 runs-on: macos-14 steps: + - name: Checkout + uses: actions/checkout@v6 - name: Install Go uses: actions/setup-go@v6 with: - go-version: '1.23.12' - - name: Checkout - uses: actions/checkout@v6 + go-version-file: 'go.mod' - name: Run unit tests run: go test - name: "Run macOS smoke tests" From bb0ba9559cde5e00a34b2327b0a063334fbf2dc5 Mon Sep 17 00:00:00 2001 From: deadprogram Date: Mon, 27 Jul 2026 13:25:03 +0200 Subject: [PATCH 2/2] espradio: add ESP32 BLE support using espradio VHCI transport Adds a new `espradio` build tag that wires the existing HCI stack up to the ESP32's virtual HCI controller via tinygo.org/x/espradio. The new Adapter calls espradio.BLEInit() and hands a VHCI-backed transport to newBLEStack(); for WiFi+BLE co-existence, espradio.Enable() should be called first. The shared HCI implementation files pick up the espradio build tag, and go.mod is updated for the espradio and drivers dependencies. Signed-off-by: deadprogram --- Makefile | 4 +++ adapter_espradio.go | 71 ++++++++++++++++++++++++++++++++++++++++ adapter_hci.go | 2 +- att_hci.go | 2 +- examples/scanner/main.go | 5 +++ gap_hci.go | 2 +- gattc_hci.go | 2 +- gatts_hci.go | 2 +- go.mod | 9 ++--- go.sum | 10 +++--- hci.go | 2 +- l2cap_hci.go | 2 +- uuid_hci.go | 2 +- 13 files changed, 99 insertions(+), 16 deletions(-) create mode 100644 adapter_espradio.go diff --git a/Makefile b/Makefile index c6fa21b..3342fde 100644 --- a/Makefile +++ b/Makefile @@ -58,6 +58,10 @@ smoketest-tinygo: @md5sum test.hex $(TINYGO) build -o test.uf2 -size=short -target=badger2040-w ./examples/advertisement @md5sum test.hex + $(TINYGO) build -o test.bin -size=short -target=xiao-esp32c3 ./examples/advertisement + @md5sum test.bin + $(TINYGO) build -o test.bin -size=short -target=xiao-esp32c3 ./examples/discover + @md5sum test.bin smoketest-linux: # Test on Linux. diff --git a/adapter_espradio.go b/adapter_espradio.go new file mode 100644 index 0000000..ef962c3 --- /dev/null +++ b/adapter_espradio.go @@ -0,0 +1,71 @@ +//go:build espradio + +package bluetooth + +import ( + "runtime" + + "tinygo.org/x/espradio" +) + +const maxConnections = 1 + +// Adapter represents the BLE adapter on the ESP32 via espradio VHCI transport. +type Adapter struct { + hciAdapter +} + +// DefaultAdapter is the default adapter on the current system. +// +// Make sure to call Enable() before using it to initialize the adapter. +var DefaultAdapter = &Adapter{ + hciAdapter: hciAdapter{ + isDefault: true, + connectHandler: func(device Device, connected bool) { + return + }, + connectedDevices: make([]Device, 0, maxConnections), + }, +} + +// Enable configures the BLE stack. It must be called before any +// Bluetooth-related calls (unless otherwise indicated). +// For WiFi+BLE co-existence, call espradio.Enable() first. +func (a *Adapter) Enable() error { + if err := espradio.BLEInit(); err != nil { + return err + } + + transport := &hciVHCI{} + + a.hci, a.att = newBLEStack(transport) + + a.enable() + + return nil +} + +// hciVHCI wraps espradio's BLE VHCI transport to implement the +// unexported hciTransport interface. +type hciVHCI struct { + t espradio.VHCITransport +} + +func (h *hciVHCI) startRead() { runtime.Gosched() } +func (h *hciVHCI) endRead() {} + +func (h *hciVHCI) Buffered() int { + return h.t.Buffered() +} + +func (h *hciVHCI) ReadByte() (byte, error) { + return h.t.ReadByte() +} + +func (h *hciVHCI) Read(buf []byte) (int, error) { + return h.t.Read(buf) +} + +func (h *hciVHCI) Write(buf []byte) (int, error) { + return h.t.Write(buf) +} diff --git a/adapter_hci.go b/adapter_hci.go index f36bc09..08b6c07 100644 --- a/adapter_hci.go +++ b/adapter_hci.go @@ -1,4 +1,4 @@ -//go:build hci || ninafw || cyw43439 +//go:build hci || ninafw || cyw43439 || espradio package bluetooth diff --git a/att_hci.go b/att_hci.go index 93b86d7..018becc 100644 --- a/att_hci.go +++ b/att_hci.go @@ -1,4 +1,4 @@ -//go:build hci || ninafw || cyw43439 +//go:build hci || ninafw || cyw43439 || espradio package bluetooth diff --git a/examples/scanner/main.go b/examples/scanner/main.go index 11ef2ad..d95d0b2 100644 --- a/examples/scanner/main.go +++ b/examples/scanner/main.go @@ -1,12 +1,17 @@ package main import ( + "time" + "tinygo.org/x/bluetooth" ) var adapter = bluetooth.DefaultAdapter func main() { + time.Sleep(time.Second) // wait for the system to initialize + println("Starting BLE") + // Enable BLE interface. must("enable BLE stack", adapter.Enable()) diff --git a/gap_hci.go b/gap_hci.go index c674b90..e7b8e2c 100644 --- a/gap_hci.go +++ b/gap_hci.go @@ -1,4 +1,4 @@ -//go:build hci || ninafw || cyw43439 +//go:build hci || ninafw || cyw43439 || espradio package bluetooth diff --git a/gattc_hci.go b/gattc_hci.go index 28df2c8..987f707 100644 --- a/gattc_hci.go +++ b/gattc_hci.go @@ -1,4 +1,4 @@ -//go:build hci || ninafw || cyw43439 +//go:build hci || ninafw || cyw43439 || espradio package bluetooth diff --git a/gatts_hci.go b/gatts_hci.go index 9f9dbb3..20cc01e 100644 --- a/gatts_hci.go +++ b/gatts_hci.go @@ -1,4 +1,4 @@ -//go:build hci || ninafw || cyw43439 +//go:build hci || ninafw || cyw43439 || espradio package bluetooth diff --git a/go.mod b/go.mod index 9563607..bf0ad3a 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module tinygo.org/x/bluetooth -go 1.23.8 +go 1.24.4 require ( github.com/go-ole/go-ole v1.2.6 @@ -9,7 +9,9 @@ require ( github.com/soypat/cyw43439 v0.1.0 github.com/tinygo-org/cbgo v0.0.4 golang.org/x/crypto v0.12.0 - tinygo.org/x/drivers v0.35.0 + golang.org/x/sys v0.11.0 + tinygo.org/x/drivers v0.35.1-0.20260604174950-1d695a231aef + tinygo.org/x/espradio v0.1.1-0.20260730102224-eccd37c7e46e tinygo.org/x/tinyfont v0.6.0 tinygo.org/x/tinyterm v0.5.0 ) @@ -17,10 +19,9 @@ require ( require ( github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/sirupsen/logrus v1.9.3 // indirect - github.com/soypat/lneto v0.1.0 // indirect + github.com/soypat/lneto v0.2.1 // indirect github.com/soypat/seqs v0.0.0-20250124201400-0d65bc7c1710 // indirect github.com/tinygo-org/pio v0.3.0 // indirect golang.org/x/exp v0.0.0-20241204233417-43b7b7cde48d // indirect - golang.org/x/sys v0.11.0 // indirect golang.org/x/term v0.11.0 // indirect ) diff --git a/go.sum b/go.sum index 18da4c5..0ade99b 100644 --- a/go.sum +++ b/go.sum @@ -17,8 +17,8 @@ github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/soypat/cyw43439 v0.1.0 h1:3Nyqg2LSndhCYgCr2VXuL2nn73vyaJXAnD02veMoLvA= github.com/soypat/cyw43439 v0.1.0/go.mod h1:R2uSILRwSPmcmmKy5Z0FtK4ypgiPf5YqK+F+IKmXqxc= -github.com/soypat/lneto v0.1.0 h1:VAHCJ33hvC3wDqhM0Vm7w0k6vwNsOCAsQ8XTrXJpS7I= -github.com/soypat/lneto v0.1.0/go.mod h1:g/8Lk+hIsMZydyWDJjK2YfsCuG6jA5mWCO6U+4S7w1U= +github.com/soypat/lneto v0.2.1 h1:o07lXylFCkRs4djA9PYrIf0oW+tMLjxO2/JbHv2XoK0= +github.com/soypat/lneto v0.2.1/go.mod h1:Be5PjwoYukvHFiUXxpYi8+ppH2F/gw/vjGBvFdv+Ti8= github.com/soypat/seqs v0.0.0-20250124201400-0d65bc7c1710 h1:Y9fBuiR/urFY/m76+SAZTxk2xAOS2n85f+H1CugajeA= github.com/soypat/seqs v0.0.0-20250124201400-0d65bc7c1710/go.mod h1:oCVCNGCHMKoBj97Zp9znLbQ1nHxpkmOY9X+UAGzOxc8= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -45,8 +45,10 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -tinygo.org/x/drivers v0.35.0 h1:cTK36tsI/S4Mg3hCPH0MBjV/ta7XKQ+wpvch4mVqgsE= -tinygo.org/x/drivers v0.35.0/go.mod h1:DQgKyHkB4G6IEOKVTAjApbKnWGwESN91EVJO+nMOE9Y= +tinygo.org/x/drivers v0.35.1-0.20260604174950-1d695a231aef h1:nG/qd6hSQonHse2l8DYUrCuJSiCfcFD9n8YMze8sVo0= +tinygo.org/x/drivers v0.35.1-0.20260604174950-1d695a231aef/go.mod h1:DQgKyHkB4G6IEOKVTAjApbKnWGwESN91EVJO+nMOE9Y= +tinygo.org/x/espradio v0.1.1-0.20260730102224-eccd37c7e46e h1:m5UUMZzkBAf6rDtoD9d8lzv6YJdXNGctE62clvhOgc8= +tinygo.org/x/espradio v0.1.1-0.20260730102224-eccd37c7e46e/go.mod h1:1l1bd9M8w8iXQ5eFfOlyPpZT+0l+DutBLxSYIHPj2mI= tinygo.org/x/tinyfont v0.6.0 h1:GibXDSFz6xrWnEDkDRo6vsbOyRw0MVj/eza3zNHMSHs= tinygo.org/x/tinyfont v0.6.0/go.mod h1:onflMSkpWl7r7j4MIqhPEVV39pn7yL4N3MOePl3G+G8= tinygo.org/x/tinyterm v0.5.0 h1:HusDSiTM290KzYM4+2X+ZfNM6Ll1yu13LpvIszlQE9M= diff --git a/hci.go b/hci.go index 08ad838..000d92d 100644 --- a/hci.go +++ b/hci.go @@ -1,4 +1,4 @@ -//go:build ninafw || hci || cyw43439 +//go:build ninafw || hci || cyw43439 || espradio package bluetooth diff --git a/l2cap_hci.go b/l2cap_hci.go index c4267ff..cdd90cf 100644 --- a/l2cap_hci.go +++ b/l2cap_hci.go @@ -1,4 +1,4 @@ -//go:build ninafw || hci || cyw43439 +//go:build ninafw || hci || cyw43439 || espradio package bluetooth diff --git a/uuid_hci.go b/uuid_hci.go index 2028706..7d52968 100644 --- a/uuid_hci.go +++ b/uuid_hci.go @@ -1,4 +1,4 @@ -//go:build hci || ninafw || cyw43439 +//go:build hci || ninafw || cyw43439 || espradio package bluetooth