Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot connect to device #320

Open
ztolley opened this issue Jan 3, 2025 · 7 comments
Open

Cannot connect to device #320

ztolley opened this issue Jan 3, 2025 · 7 comments
Labels
question Further information is requested

Comments

@ztolley
Copy link

ztolley commented Jan 3, 2025

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.

@deadprogram
Copy link
Member

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 deadprogram added the question Further information is requested label Jan 4, 2025
@ztolley
Copy link
Author

ztolley commented Jan 5, 2025

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 :)

@temamagic
Copy link

temamagic commented Feb 7, 2025

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
Copy link

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.

@ztolley
Copy link
Author

ztolley commented Feb 8, 2025 via email

@ztolley
Copy link
Author

ztolley commented Feb 15, 2025

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
Copy link
Author

ztolley commented Feb 15, 2025

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants