bluetooth icon indicating copy to clipboard operation
bluetooth copied to clipboard

Cannot connect to device

Open ztolley opened this issue 10 months ago • 7 comments
trafficstars

I have a BLE device that I've successfully scanned for and connected to in a simple diagnostic SwiftUI app, now I'm trying to talk to it from a command line app written in Go that will ultimately run on Linux.

I can scan for my device and read the advertised manufacturer data but when I try to connect (which should take no longer than 4-5 seconds) the code just sits there and never responds.

I've created a minimal example of what I'm doing:

package main

import (
	"fmt"

	"tinygo.org/x/bluetooth"
)

func main() {
	targetUUID := bluetooth.NewUUID([16]byte{0xb7, 0x31, 0x81, 0x0c, 0x26, 0x62, 0x8c, 0x80, 0x5f, 0x4f, 0xfa, 0x1f, 0x53, 0x3e, 0x9d, 0x11})

	Adapter := bluetooth.DefaultAdapter
	must("enable BLE stack", Adapter.Enable())

	fmt.Printf("Start scanning for devices\n")

	must("start scan", Adapter.Scan(func(adapter *bluetooth.Adapter, device bluetooth.ScanResult) {
		if device.HasServiceUUID(targetUUID) {
			fmt.Printf("Found device %s\nConnecting\n", device.Address.String())

			peripheral, err := Adapter.Connect(device.Address, bluetooth.ConnectionParams{})

			if err != nil {
				fmt.Printf("Failed to connect to device %s: %v\n", device.Address.String(), err)
				return
			}

			fmt.Printf("Connected to device %s\n", device.Address.String())
			peripheral.Disconnect()
			Adapter.StopScan()
		}
	}))

}

func must(action string, err error) {
	if err != nil {
		panic("failed to " + action + ": " + err.Error())
	}
}

When I run this the only output is:

Start scanning for devices
Found device bfc981a3-dd25-77a0-31af-04d7ff2d69b0
Connecting

Am I doing something fundamentally wrong?

I've also successfully connected to the same device using Rust/btleplug so I'm confident the device works.

ztolley avatar Jan 03 '25 22:01 ztolley

I would suggest look at the examples here https://github.com/tinygo-org/bluetooth/tree/release/examples/discover and here https://github.com/tinygo-org/bluetooth/tree/release/examples/heartrate-monitor for how to connect as a Central to a Peripheral.

Hope that helps!

deadprogram avatar Jan 04 '25 07:01 deadprogram

I tried those . I've done more testing and the problem seems to be only when running on Linux . Runs fine on Mac, in fact:

1: Run on linux, get unable to connect - Times out - bluetooth: failed to connect: le-connection-abort-by-local 2: Run same code on MacOS - The occasional connection failure but connects and I can read services, characteristics and read data 3: Run on linux again - Works fine.

After a while Linux stops working and I have to run it on the mac again

I suspect this is something to do with Bluez so feel free to close this ticket unless anyone out there has a clue why, otherwise I'll go to Stack Overflow :)

ztolley avatar Jan 05 '25 14:01 ztolley

I tried those I suspect this is something to do with Bluez so feel free to close this ticket unless anyone out there has a clue why, otherwise I'll go to Stack Overflow :)

Hi! Were you able to find out anything else? For example, I can't connect to a known device on my Mac in scan mode

for ex, i do like this:

err = adapter.Scan(onScan)
	if err != nil {
		log.Fatal("failed to register scan callback", zap.Error(err))
	}
func onScan(adapter *bluetooth.Adapter, scanDevice bluetooth.ScanResult) {
log.Info("found device, connecting")
	device, err := adapter.Connect(scanDevice.Address, bluetooth.ConnectionParams{})
	if err != nil {
		log.Error("failed to connect to device", zap.Error(err))
		return
	}

	log.Info("connected to device")
	log.Info("discovering services/characteristics")

	srvcs, err := device.DiscoverServices(nil)
....

I just get stuck on connecting and nothing happens

temamagic avatar Feb 07 '25 23:02 temamagic

It seems that in my case the problem was that I was trying to connect in scanning mode, but I had to stop scanning first.

temamagic avatar Feb 08 '25 02:02 temamagic

Oh that could be it , will try that today. I wasn’t aware there were modes

On Sat, 8 Feb 2025 at 02:59, Artem @.***> wrote:

It seems that in my case the problem was that I was trying to connect in scanning mode, but I had to stop scanning first.

— Reply to this email directly, view it on GitHub https://github.com/tinygo-org/bluetooth/issues/320#issuecomment-2644452019, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAANV6EVWWJJDVSYNHIXUXT2OVXIVAVCNFSM6AAAAABUSOHI6CVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDMNBUGQ2TEMBRHE . You are receiving this because you authored the thread.Message ID: @.***>

ztolley avatar Feb 08 '25 09:02 ztolley

Tried and failed :(

I used the heart rate monitor code as a base to prove if this would fix it or not and no joy.

var (
	adapter         = bluetooth.DefaultAdapter
	requiredAddress = "08:6B:D7:8F:10:BD"
)

func main() {
	must("enable BLE stack", adapter.Enable())
	ch := make(chan bluetooth.ScanResult, 1)

	println("scanning...")
	adapter.Scan(func(adapter *bluetooth.Adapter, result bluetooth.ScanResult) {
		if result.Address.String() == requiredAddress {
			println("found device:", result.Address.String(), result.RSSI)
			adapter.StopScan()
			ch <- result
		}
	})

	select {
	case result := <-ch:
		println("Connect to device:", result.Address.String())
		_, err := adapter.Connect(result.Address, bluetooth.ConnectionParams{})
		if err != nil {
			println(err.Error())
			return
		}

		println("connected to ", result.Address.String())
	}
}
enabling
scanning...
found device: 08:6B:D7:8F:10:BD -78
Connect to device: 08:6B:D7:8F:10:BD

As before, it says it just sits at 'Connecting' forever. I even tried adding parameters to tell it to timeout after 30 seconds but that doesn't appear to affect it.

ztolley avatar Feb 15 '25 16:02 ztolley

News Flash... it didn't work on a Raspberry Pi with Raspbian.. It Did Work Fedora on an AMD box.. there is hope

ztolley avatar Feb 15 '25 18:02 ztolley