muka / go-bluetooth

Golang bluetooth client based on bluez DBus interfaces

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Example with authorization

jon4hz opened this issue · comments

Hi!
I'm trying to connect to a flipper zero using this library and I'm having some difficulties because the flipper requires a pin for pairing. This is the first time I'm tinkering around with bluetooth so I'm probably doing every wrong that can be done wrong xD.
I was wondering if there is a working example on how to connect a device that requires authorization. All the examples I could find so far didn't seem to cover that.

Hi, what you need is probably a customized version of an agent. I do not think there is an example here but maybe you could find one checking the bluez documentation.

Hi,
I have recently stumbled upon the same doubt while taking a look to the code implemented by a colleague.
What I understood is that he actually wrote a custom agent (almost identical to agent_simple.go) just to modify RequestPasskey() while apparently it would have been enough just to call <SimpleAgent>.SetPassKey() before calling <Device1>.Pair()

To verify my assumption, I modified our code and did some tests with devices that require authorization. Everything worked properly.
Therefore I would suggest adding a comment in agent.go.

Anyway I would have a doubt .
Indeed I am not sure if <SimpleAgent>.SetPassKey() can be used if the application is connecting to multiple devices at the same time.

In our app we use multiple go routines that can potentially connect to multiple devices at the same time.
To do that, at the moment we are calling a function similar to the following one from different go routines (one per discovered device up to a certain limit).

func connect(dev *device.Device1, ag *agent.SimpleAgent, a *adapter.Adapter1, gatewayMac string) error {
	deviceMac := props.Address
	props, err := dev.GetProperties()
	if err != nil {
		return fmt.Errorf("device %s - failed to load properties. Error: %s", deviceMac, err)
	}

	if props.Connected {
		log.Debugf("Device %s - already connected", deviceMac)
		return nil
	}
	passkey := 1234 // You can calculate the passkey dinamically depending on the UUIDs, on the MAC of the device, ...

	ag.SetPassKey(passkey)
	if !props.Paired || !props.Trusted {
		err := dev.Pair()
		if err != nil {
			return fmt.Errorf("device %s - pairing failed. Error: %s", deviceMac, err)
		}
	}
	if !props.Connected {
		err = dev.Connect()
		if err != nil {
			return fmt.Errorf("device %s - connect failed. Error: %s", deviceMac, err)
		}
	}
	return nil
}

Now I wonder if our use of <SimpleAgent>.SetPassKey() , <Device1>.Pair() and <Device1>.Connect() is correct or if they are not designed to be called from different go routines running concurrently.

Thank you, would you mind to provide a PR with improvements and eventually an example in the _examples folder ?

I admit I never stumble upon this parallel use case. Every Device should be an autonomous instance (thus isolated from the other) but I may be wrong. Let me know your findings.

Ok, I will provide a PR, probably just to update the examples, in the coming days.