Git Product home page Git Product logo

go-bluetooth's Introduction

go-bluetooth

Go bluetooth API for Linux-based Bluez DBus interface.

GoDoc

Bluez API versioning

The version on master tracks Ubuntu bluetoothd version (v5.64). There are dedicated branches/tags with various version

See branches for available versions.

Features

The library is a wrapper to the Bluez DBus API and some high level API to ease the interaction.

High level features supported:

  • Client code generation from bluez documentation
  • Shell wrappers for rfkill, btmgmt, hciconfig, hcitool
  • An hci socket basic API (inspired by go-ble/ble)
  • Expose bluetooth service from go code [unstable]
  • Pairing and authentication support (via agent)
  • Beaconing send & receive (iBeacon and Eddystone)
  • Mesh API support (since v5.53)

Todo

  • Generate dbus-compatible XML from documentation
  • Generate mock service to test the library against

Using this library

Want to add your project? Please, add it to the README.md and open a PR!

Running examples

Examples are available in _examples folder.

cd _examples
go run main.go
# print available example commands
# Example discovery
go run main.go discovery

Development setup

  1. Clone the repository

git clone https://github.com/muka/go-bluetooth.git

  1. Retrieve the bluetooth API and generate GO code
make bluez/init bluez/checkout gen/clean gen/run

Code generation

To generate code for a new version of bluez use the command

BLUEZ_VERSION=5.65 make gen/clean gen

Change to a version available in bluez. Note that generated code may be broken or incomplete and the generation script may need fine tuning.

How generation works

The code structure follow this pattern:

  • ./api contains wrappers for the DBus Api
  • ./bluez contains the actual implementation, generated from the bluez documentation

Use make gen to re-generate go sources. There is also a commodity bluez JSON file available in the root folder for reference.

Generated code has gen_ prefix. If an API file exists with the same filename but without the prefix, generation will be skipped for that API.

Requirements

The library is tested with

  • golang 1.17.5
  • bluez bluetooth v5.50, v5.54, v5.60

Development notes

  • Inspect a service ObjectManager

    dbus-send --system --print-reply --dest=go.bluetooth /hci0/apps/0 org.freedesktop.DBus.ObjectManager.GetManagedObjects
  • Retrieve char properties

    dbus-send --system --print-reply --dest=go.bluetooth /hci0/apps/0/service000003e8/char0  org.freedesktop.DBus.Properties.GetAll string:org.bluez.GattCharacteristic1
    
  • Give access to hciconfig to any user and avoid sudo (may have security implications)

    sudo setcap 'cap_net_raw,cap_net_admin+eip' `which hciconfig`
    
  • Monitor Bluetooth activity

    sudo btmon

  • Monitor DBus activity

    sudo dbus-monitor --system "type=error"

  • Start bluetoothd with experimental features and verbose debug messages make bluetoothd

  • Enable LE advertisement (on a single pc ensure to use at least 2x bluetooth adapter)

      sudo btmgmt -i 0 power off
      sudo btmgmt -i 0 name "my go app"
      sudo btmgmt -i 0 le on    
      sudo btmgmt -i 0 connectable on
      sudo btmgmt -i 0 advertising on
      sudo btmgmt -i 0 power on
    

References

License

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

go-bluetooth's People

Contributors

1am avatar andig avatar avanha avatar aykevl avatar benjaminbartels avatar cuu avatar davidknezic avatar feresey avatar fermuch avatar gbrayut avatar ghouscht avatar gtintika avatar james-lawrence avatar jeromesancho avatar lc-spxl avatar mrmstn avatar muesli avatar muka avatar niziak avatar organswithoutbodies avatar packetdancer avatar phommel avatar rachelblackman avatar sam-mathews avatar saurabh-zededa avatar shigmas avatar skast96 avatar suapapa avatar svenschwermer avatar vladius25 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

go-bluetooth's Issues

Beaconing support

Investigate and priovide implementation / examples of how to detect beacons (ibeacon, eddystone)

interface conversion issue with the emitter

while fetching sensor data:-
panic: interface conversion: interface {} is devices.SensorTagDataEvent, not api.DataEvent

goroutine 31 [running]:
main.ConnectAndFetchSensorDetailAndData.func1(0x75a180, 0xc4201e96c0)
/home/saurabh/examples/sensortag/adpater.go:147 +0x1f7
created by github.com/muka/go-bluetooth/emitter.loop
/home/saurabh/.go/src/github.com/muka/go-bluetooth/emitter/events.go:59 +0x205
exit status 2

Adapter1 AdressType field for bluez 5.49

Hi,

I'm currently using your code as reference for my own project.
First things first, this repo is great for everybody who's trying to find a simple way to interface with Bluez DBus API from native Go code (I'm currently wrapping Bluez-tools binaries to achieve my goals and this repo is a awesome guide to get rid of this).

Doing some tests I recognized that the GetProperties method of Adapter1 errors on Bluez 5.49.

This is because the AddressType field is missing in the respective struct and reflective casting of the map fails.

Could be that this field isn't present in older Bluez versions you support, but it seems you have to distinguish between Bluez versions to get casting to internal structs future proof.

Thanks for this nice project!

Cheers Mame82

Flutter mobile app

Flutter and golang can communicate over grpc well now.

So was thinking of making a flutter app for this.

What do people think ?

Flutter works on desktop and mobile.
It would talk to a raspberry pi in your house over grpc localhost.
That's my plan anyway.

I guess naming your Bluetooth devices and saving the mapping of the device name to the device Bluetooth ID would be an obvious need.

Pairing can be done on the raspberry pi and shown in your mobile etc. So you don't have to pair your phones with all your devices.

Also can use autocert and a tunnel so you can access everything remotely.

If anyone has other needs chime in !

interface conversion issue for luxometer

while running the example code I am facing this issue
//(running on ubuntu 16.04)
panic: interface conversion: interface {} is devices.LuxometerSensor, not *devices.LuxometerSensor

goroutine 1 [running]:
github.com/muka/go-bluetooth/devices.newLuxometerSensor(0xc4202e2680, 0xc4204099c0, 0x0, 0x0)
/home/saurabh/.go/src/github.com/muka/go-bluetooth/devices/sensortag_luxometer.go:62 +0x1ff
github.com/muka/go-bluetooth/devices.NewSensorTag(0xc4202b9a70, 0x1, 0x1, 0xc4203189d0)
/home/saurabh/.go/src/github.com/muka/go-bluetooth/devices/sensortag.go:231 +0x450
main.ConnectAndFetchSensorDetailAndData(0xc4202e52e0, 0x11, 0x659e0b, 0xb)
/home/saurabh/examples/sensortag/adpater.go:93 +0x1ed
main.SensorTag()
/home/saurabh/examples/sensortag/adpater.go:61 +0x7eb
main.main()
/home/saurabh/examples/sensortag/adpater.go:24 +0x89
exit status 2

getting nil in device properties

i am getting run time error while discovering sensors.....

2017/06/16 03:51:41 Loaded devices %d [{/org/bluez/hci0/dev_B0_B4_48_D2_30_85 0x106d9160 map[]}]
2017/06/16 03:51:41 device: {/org/bluez/hci0/dev_B0_B4_48_D2_30_85 0x106d9160 map[]}
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x180a04]

goroutine 3 [running]:
main.filterDevice(0x10639f2c, 0x106e61b0)
/home/Embs1PSL/github/DistributedEdgeIoT/src/securiot-ble/watch_changes.go:166 +0x2c
main.loadDevices(0x10670900)
/home/Embs1PSL/github/DistributedEdgeIoT/src/securiot-ble/watch_changes.go:156 +0x2d8
main.deviceIsCached(0x2b49d0)
/home/Embs1PSL/github/DistributedEdgeIoT/src/securiot-ble/watch_changes.go:140 +0x94
main.discoverDevices(0x1d8679, 0x4)
/home/Embs1PSL/github/DistributedEdgeIoT/src/securiot-ble/watch_changes.go:112 +0x14
main.waitAdapter()
/home/Embs1PSL/github/DistributedEdgeIoT/src/securiot-ble/watch_changes.go:103 +0x274
created by main.discoverDevice
/home/Embs1PSL/github/DistributedEdgeIoT/src/securiot-ble/watch_changes.go:74 +0x54
exit status 2

Creating Eddystone Beacon

Hello,

I am looking to create an Eddystone URL beacon using BlueZ DBus API. It looks like this library has some support for this. However, I am new to the Go language and am rather intimidated by the empty text editor in front of me. Is it possible for you to give me some guidance on getting started with an example for this?

An example of the information required for "org.bluez.LEAdvertisement1"
Type = "broadcast"
ServiceUUIDs = "FEAA"
ServiceData = map[string[13]int] {"FEAA": [16 0 1 98 108 117 101 116 111 111 116 104 7]}
IncludeTxPower = false

The DBus object path for the above then needs to be passed to method RegisterAdvertisement on interface "org.bluez.AdvertisementManager1"

Any pointers in getting started with this would be appreciated.

Thanks.

Example code does not work any more

$ go run watch_changes.go 
# command-line-arguments
./watch_changes.go:84: cannot use func literal (type func(emitter.Event)) as type *emitter.Callback in argument to emitter.On
./watch_changes.go:115: cannot use func literal (type func(emitter.Event)) as type *emitter.Callback in argument to api.On
./watch_changes.go:170: cannot use func literal (type func(emitter.Event)) as type *emitter.Callback in argument to dev.On
./watch_changes.go:232: undefined: api.RefreshManagerState
./watch_changes.go:240: undefined: err
./watch_changes.go:241: undefined: err
./watch_changes.go:242: undefined: err

One of the problems I come across when trying code from examples

Any way to issue a "Powered" command?

Hello,

I'm looking for a way to issue the "Powered" command (from the "Set Powered Command" section in mgmt-api.txt). Is there a way to issue a Powered on, Powered off with the current API?

Thanks.

Reading GATT Characteristic data from dbus

I'm running the service example on Ubuntu 17.10. The Bluetooth part works great. When I write data from my phone, I see it in the dbus-monitor (sudo dbus-monitor --system).

	method call time=1525902804.851076 sender=:1.2 -> destination=:1.90 serial=117 path=/org/bluez/example/service/service1/char1; interface=org.bluez.GattCharacteristic1; member=WriteValue
	   array of bytes "hello"
	   array [
	      dict entry(
	         string "device"
	         variant             object path "/org/bluez/hci0/dev_61_E0_93_AC_98_E7"
	      )
	   ]
	signal time=1525902804.852227 sender=:1.90 -> destination=(null destination) serial=18 path=/org/bluez/example/service/service1/char1; interface=org.freedesktop.DBus.Properties; member=PropertiesChanged
	   string "org.bluez.GattCharacteristic1"
	   array [
	      dict entry(
	         string "Value"
	         variant             array of bytes "hello"
	      )
	   ]
	   array [
	   ]

The problem is I don't know how to read the PropertiesChanged notification for /org/bluez/example/service/service1/char1 from DBus.

I created a similar example with python-bluezero. Using pydbus, I'm able to read the Bluetooth data when my phone updates a characteristic.

    # python
	from pydbus import SystemBus, Variant
	from gi.repository import GLib

	bus = SystemBus()
	proxy = bus.get('ukBaz.bluezero', '/ukBaz/bluezero/service0001/char0001')
	proxy.onPropertiesChanged = print
	GLib.MainLoop().run()

I'm trying to use the same Python client to read data from the go-bluetooth sample but I don't know which bus name. org.bluez and go.bluetooth don't work.

	proxy = bus.get(BUS_NAME, '/org/bluez/example/service/service1/char1')

Any suggestions on which bus name to use?

build failed ๏ผš undefined xxx

โ— ~ ยป cd $GOPATH/src/github.com/muka/go-bluetooth && make build
CGO_ENABLED=0 go build -o go-bluetooth ./main.go
hw/linux/hci/hci.go:7:9: undefined: socket.Down
hw/linux/hci/hci.go:12:9: undefined: socket.Up
hw/linux/hci/hci.go:17:9: undefined: socket.List

Nil pointer dereference on dbus channel

Hey @muka

Have you seen this runtime error before? I seem to get it from time to time when initializing multiple devices.

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x8 pc=0x19f600]

goroutine 1 [running]:
gatt/vendor/github.com/muka/go-bluetooth/bluez/profile.(*GattCharacteristic1).Register(0x0, 0x11, 0x11cb3d20, 0x1)
	/Users/jaredwolff/go/src/gatt/vendor/github.com/muka/go-bluetooth/bluez/profile/GattCharacteristic1.go:81 +0x14
main.(*Thingy).notify(0x1184e570, 0x11d0e900, 0x24, 0x11c94780, 0x1, 0x11d0e900)

Failed to import go-bluetooth due to go-debug not found

Hi

I tried to import this repo by command: dep ensure -add github.com/muka/go-bluetooth, and I got below errors.

Fetching sources...

Solving failure:
	(1) failed to list versions for https://github.com/tj/go-debug: remote: Repository not found.
fatal: repository 'https://github.com/tj/go-debug/' not found
: exit status 128
	(2) failed to list versions for ssh://[email protected]/tj/go-debug: ERROR: Repository not found.
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
: exit status 128
	(3) failed to list versions for git://github.com/tj/go-debug: fatal: remote error:
  Repository not found.
: exit status 128
	(4) failed to list versions for http://github.com/tj/go-debug: remote: Repository not found.
fatal: repository 'https://github.com/tj/go-debug/' not found
: exit status 128

Data race (api.(*Device).watchProperties / reflect.Value.Set())

Hello.
This is my first approach to write something in golang, so maybe I'm using your library in wrong way.

I've enabled filtered scanning for advertisement with duplicated advertisement enabled, so I'm receiving each advertisement.
Bluez signals changes on device for every advertisement. And the change set contains two changes at time (RSSI and ManufacturerData fields).
In this specified case (two changes at once), for loop in api.(*Device).watchProperties is processing changes one by one and emits PropertyChangedEvent.

Problem is that this emited event from first change is concurrently processed and my callback is called, when api.(*Device).watchProperties is still in for loop.
In my callback I want to read some other device properties, this is a moment where golang race detector complains (because api.(*Device).watchProperties is modifying device properties and in another routine my callback also want to do something with device properties)

Any way I can connect to the device without waiting for discover service?

If I know device-id do I always have to wait while discover service will find that device?
I.E. do I need to do all the time:

        devices, err := api.GetDevices()
	if err != nil {
		log.Errorf("GetDevices: %s", err)
		return
	}

	log.Info(devices)

	for i, v := range devices {
		path := strings.Replace(devMac, ":", "_", -1)
		if strings.Contains(v.Path, path) {
			log.Info(i, v.Path)
			log.Info("Pairing...")
			err := v.Pair()
			if err == nil {
				log.Info("Pair succeed,Connecting...")
				setTrusted(dev_mac_path)
				v.Connect()
			} else {
				log.Error("Pair failed:", err)
			}
		}
	}

Or there are a way to connect to device without waiting while device will show up at api.GetDevices() ?

lets say:

dev := api.NewDevice(path)
dev.Connect()

?

RegisterAdvertisement dbus errors on bluez 5.50

I've managed to integrate go-bluetooth and run a GATT service on my Raspberry Pi 3 with Raspbian. (bluez 5.43)

Now I'm trying to get it to work on a yocto based image. (bluez 5.50)

However, during the call to RegisterAdvertisement some things don't seem to work properly, looking at the dbus logs:

error time=1552854045.795385 sender=org.freedesktop.DBus -> destination=:1.7 
error_name=org.freedesktop.DBus.Error.ServiceUnknown reply_serial=216
   string "The name :1.15 was not provided by any .service files"
method call time=1552854045.795651 sender=:1.7 -> destination=:1.15 serial=217 path=/org/bluez/advertisement/hci0; interface=org.freedesktop.DBus.ObjectManager; member=GetManagedObjects
error time=1552854045.795783 sender=:1.15 -> destination=:1.7 error_name=org.freedesktop.DBus.Error.UnknownInterface reply_serial=217
   string "Object does not implement the interface"
Full dbus log excerpt
method call time=1552854045.763240 sender=:1.15 -> destination=org.bluez serial=11 path=/org/bluez/hci0; interface=org.bluez.LEAdvertisingManager1; member=RegisterAdvertisement
   object path "/org/bluez/advertisement/hci0"
   array [
   ]
method call time=1552854045.767510 sender=:1.7 -> destination=org.freedesktop.DBus serial=211 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=GetNameOwner
   string ":1.15"
method return time=1552854045.767784 sender=org.freedesktop.DBus -> destination=:1.7 serial=132 reply_serial=211
   string ":1.15"
method call time=1552854045.767969 sender=:1.7 -> destination=org.freedesktop.DBus serial=212 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=AddMatch
   string "type='signal',sender=':1.15',path='/org/bluez/advertisement/hci0',interface='org.freedesktop.DBus.ObjectManager',member='InterfacesAdded'"
method return time=1552854045.768161 sender=org.freedesktop.DBus -> destination=:1.7 serial=133 reply_serial=212
method call time=1552854045.771002 sender=:1.7 -> destination=org.freedesktop.DBus serial=213 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=AddMatch
   string "type='signal',sender=':1.15',path='/org/bluez/advertisement/hci0',interface='org.freedesktop.DBus.ObjectManager',member='InterfacesRemoved'"
method return time=1552854045.771412 sender=org.freedesktop.DBus -> destination=:1.7 serial=134 reply_serial=213
method call time=1552854045.779049 sender=:1.7 -> destination=org.freedesktop.DBus serial=214 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=AddMatch
   string "type='signal',sender=':1.15',path_namespace='/org/bluez/advertisement/hci0'"
method return time=1552854045.779367 sender=org.freedesktop.DBus -> destination=:1.7 serial=135 reply_serial=214
method call time=1552854045.779492 sender=:1.7 -> destination=org.freedesktop.DBus serial=215 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=AddMatch
   string "type='signal',sender=':1.15',path='/org/bluez/advertisement/hci0',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged',arg0='org.bluez.LEAdvertisement1'"
method return time=1552854045.779680 sender=org.freedesktop.DBus -> destination=:1.7 serial=136 reply_serial=215
method call time=1552854045.793739 sender=:1.7 -> destination=org.freedesktop.DBus serial=216 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=StartServiceByName
   string ":1.15"
   uint32 0
error time=1552854045.795385 sender=org.freedesktop.DBus -> destination=:1.7 error_name=org.freedesktop.DBus.Error.ServiceUnknown reply_serial=216
   string "The name :1.15 was not provided by any .service files"
method call time=1552854045.795651 sender=:1.7 -> destination=:1.15 serial=217 path=/org/bluez/advertisement/hci0; interface=org.freedesktop.DBus.ObjectManager; member=GetManagedObjects
error time=1552854045.795783 sender=:1.15 -> destination=:1.7 error_name=org.freedesktop.DBus.Error.UnknownInterface reply_serial=217
   string "Object does not implement the interface"
method call time=1552854045.795967 sender=:1.7 -> destination=:1.15 serial=218 path=/org/bluez/advertisement/hci0; interface=org.freedesktop.DBus.Properties; member=GetAll
   string "org.bluez.LEAdvertisement1"

This is my code that triggers these errors: https://github.com/the-lightning-land/sweetd/pull/14/files#diff-2650556a5ae8d1b4833240d0c10b6238R175

Is it possible that something has changed in bluez between 5.43 and 5.50 that leads to the Object does not implement the interface error? Or could there be something else that might lead to this problem?

Help very appreciated!

Advertising multiple services failed

We are using the master branch from the go-bluetooth.
We have added the services as per the examples.
When we have only one service the code works fine and we can see our service in the ble-client app.
But as soon as we add another service in the same way and then we start advertising, we get error while registering the advertise.: RegisterAdvertisement, and application doesn't advertise anything.

In the module Application.go, inside function StartAdvertising -> RegisterAdvertisement, where we ultimately give a dbus call for register adv, which is failing.
Exact error message: Failed to parse advertisement
Can someone point out what is wrong or why would it happen?
It will be a great help.

Can't get package with go get

go get github.com/muka/go-bluetooth
# github.com/muka/go-bluetooth
/home/karol/go/src/github.com/muka/go-bluetooth/test.go:11: main redeclared in this block
	previous declaration at /home/karol/go/src/github.com/muka/go-bluetooth/main.go:10

"dbus: connection closed by user" when running discovery example

First time when I run the example, it works fine and scans available Bluetooth devices.
Second run (after stopping the app with Ctrl C) will print out following:

DEBU[0000] Reset bluetooth device
ERRO[0000] FlushDevices.RemoveDevice dbus: connection closed by user

I added a graceful exit to the example to ensure api.Exit() was called but I got the same issue.

I'm running on following environment:
bluez version 5.48
Ubuntu 18.04.1 LTS
Go version 1.12.5

After couple of minutes, the issue disappears for one run, but second run will cause the same issue.

Add support for digital and analog characteristics.

Hi,

It seems that currently digital and analog characteristics for automation IO service are not supported in go-bluetooth library.

While using automation IO service, we can have multiple digital and analog characteristics. Each digital and analog characteristic has UUID 0x2A56 and 0x2A58 respectively.

Problem is that, currently it is not possible to identify that which analog or digital characteristic has been changed. This is because, we have application callbacks where we use characteristic UUID to identify the characteristic that has been changed.

//GattWriteCallback A callback we can register to handle write requests
type GattWriteCallback func(app *Application, service_uuid string, charUUID string, value []byte) error

//GattDescriptorWriteCallback A callback we can register to handle descriptor write requests
type GattDescriptorWriteCallback func(app *Application, service_uuid string, charUUID string, descUUID string, value []byte) error

//GattReadCallback A callback we can register to handle read requests
type GattReadCallback func(app *Application, service_uuid string, charUUID string) ([]byte, error)

//GattDescriptorReadCallback A callback we can register to handle descriptor ead requests
type GattDescriptorReadCallback func(app *Application, service_uuid string, charUUID string, descUUID string) ([]byte, error)

To fix this problem, I think, dbus.ObjectPath can be used instead of UUIDs of service, characteristic and descriptor. DBus object paths are guaranteed to be unique.

That is,

type GattWriteCallback func(app *Application, srviceObjPath dbus.ObjectPath, charObjPath dbus.ObjectPath, value []byte) error

type GattReadCallback func(app *Application, srviceObjPath dbus.ObjectPath, charObjPath dbus.ObjectPath) ([]byte, error)

Examples

Hi,

I'm trying to get started with the examples but have run into an issue. The API relies on tj/go-debug which is either a private repo or no longer exists. Did it move somewhere else? Is there a way to work around this issue?

Thanks,

Eric

[Query] How to identify service/characteristics from events received

Hi,
I have enhanced your code to read multiple sensor data (e.g. humidity and Magnetometer/Accelerometer etc). I am getting following events for 2 services/characteristics :

Got update %v &{:1.3 /org/bluez/hci0/dev_A0_E6_F8_AD_23_04/service0037/char0038 org.freedesktop.DBus.Properties.PropertiesChanged [org.bluez.GattCharacteristic1 map[Value:@ay [0xe3, 0xfd, 0xa0, 0x2, 0x86, 0x0, 0x68, 0x2, 0xda, 0x1, 0x86, 0xef, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]] []]}

Got update %v &{:1.3 /org/bluez/hci0/dev_A0_E6_F8_AD_23_04/service0027/char0028 org.freedesktop.DBus.Properties.PropertiesChanged [org.bluez.GattCharacteristic1 map[Value:@ay [0xbe, 0xbe, 0xbe, 0xbe]] []]}

From these events, how do I identify different sensors?

Are these dbus channel per sensor type?

Works on raspberry pi ?

Am not sure the bluez works on raspberry pi ? Anyone know ?

Am about to buy 10 Bluetooth radiator thermostats and want to check that my raspberry will be enough.

Issues w/ org.bluez.Profile1 and org.bluez.ProfileManager1 code

I've been trying to get code using the Profile1 and ProfileManager1 helper functions and not having much luck. Sample code:

  "github.com/muka/go-bluetooth/bluez/profile/profile"
  "log"

)


func main() {

  _, err := profile.NewProfileManager1()
  if err != nil {
  	log.Fatal("error: ", err)
  }

}

Results in:

error: Properties.GetAll org.bluez.ProfileManager1: Method "GetAll" with signature "s" on interface "org.freedesktop.DBus.Properties" doesn't exist

I've had no issues implementing similar code in Python. Any ideas what I'm doing wrong?

Error when reading or setting a characteristic value

Hi,
I'm using a raspberry pi whith bluez 5.48 to run some examples. When I run the server example in services directory, the following error is show when I try to read or write, a characteristic value from a service:

Mar  9 21:56:59 raspberrypi bluetoothd[368]: src/device.c:gatt_debug() Read Req - handle: 0x000c
Mar  9 21:56:59 raspberrypi bluetoothd[368]: src/gatt-database.c:read_reply_cb() Failed to read value: org.freedesktop.DBus.Error.UnknownMethod: Unknown / invalid method
Mar  9 21:58:39 raspberrypi bluetoothd[368]: src/device.c:gatt_debug() Write Req - handle: 0x000c
Mar  9 21:58:39 raspberrypi bluetoothd[368]: src/gatt-database.c:write_reply_cb() Failed to write value: org.freedesktop.DBus.Error.UnknownMethod: Unknown / invalid method
Mar  9 21:58:39 raspberrypi bluetoothd[368]: src/device.c:gatt_debug() Read Req - handle: 0x000c
Mar  9 21:58:39 raspberrypi bluetoothd[368]: src/gatt-database.c:read_reply_cb() Failed to read value: org.freedesktop.DBus.Error.UnknownMethod: Unknown / invalid method

I'm using the lightblue application from iPhone, the log shows an error saying the method doesn't exist.
Do you know what does it means and how to solve it?
Thanks!

arch linux permission

Hi,

I tried the example named discovery on Arch Linux x64, latest go 1.10.2-2, with turned on and enabled bluetooth, with sudo. At first, it failed at

a := linux.NewBtMgmt(adapterID)
err = a.Reset()

with

DEBU[0000] Exec: [btmgmt --index hci0 power off]        
ERRO[0000] exit status 1

I'm pretty sure that it was because of a permission problem, because I tried the same thing in a console with sudo, and it works without an error. But I though it's not that much needed, so I commented it out, and tried again. It has read the cached devices correctly, but then it failed with:

INFO[0000] Discovered devices:                          
ERRO[0000] Resource Not Ready

I think that it's a permission error too. What do you think about this?

After reconnecting to a device events are emmited twice

Hi,

First of all, many thanks for the library! I have notice that one of my bluetooth devices may disconnect once in a while. Sometimes I'm able to reconnect to the device and when I do, I start to receive double notifications for all events.

What would be the correct way to reconnect to the device?

Documentation

  • Write api documentation and usage examples
  • Document how to use the parsing and generation api

Cannot find TemperatureConfig characteristic

I am trying to get temperature data form TI sensorTag with the help of tagAddress but i am facing the issue mentioned below.

var tagAddress = "B0:B4:48:D2:30:85"
dev, err := api.GetDeviceByAddress(tagAddress)
if err != nil {
panic(err)
}
log.Debug("dev ",dev)

if dev == nil {
	panic("Device not found")
}

err = dev.Connect()
if err != nil {
panic(err)
}
sensorTag, err := devices.NewSensorTag(dev)
if err != nil {
panic(err)
}

log.Debug("sensorTag: ",sensorTag)

var notifyTemperature = func(fn func(temperature float64)) {
	sensorTag.Temperature.StartNotify()
	select {}
}

notifyTemperature(func(t float64) {
	log.Debug("Temperature update: %f", t)
})

OUTPUT:-

2017/06/17 14:32:17 dev &{/org/bluez/hci0/dev_B0_B4_48_D2_30_85 0x10696e40 0x106e70f0 map[]}
panic: Cannot find TemperatureConfig characteristic F000AA02-0451-4000-B000-000000000000

goroutine 1 [running]:
main.SensorTagTemperatureExample()
/home/Embs1PSL/github/DistributedEdgeIoT/src/securiot-ble/sensortag_temperature.go:52 +0x3bc
main.main()
/home/Embs1PSL/github/DistributedEdgeIoT/src/securiot-ble/sensortag_temperature.go:19 +0x14
exit status 2

Agent example returns empty device list all the time

Just trying to run a simple example with an agent and I notice

	devices, err := api.GetDevices()
	if err != nil {
		log.Error("GetDevices", err)
		return
	}
	log.Info("devices", devices)

api.GetDevices() will always return an empty list
Any ideas why/what I might doing wrong?

and follow up question

	AGENT_PATH      = "/gameshell/bleagentgo"

where can I get bleagento? do I need to compile it myself and put into /gameshell/ folder?

build failed

../../muka/go-bluetooth/api/switch.go:18:38: undefined: linux.HCIConfig
../../muka/go-bluetooth/api/switch.go:19:9: undefined: linux.NewHCIConfig

Support battery level in bluez 5.48+

Starting in bluez 5.48, the battery level GATT is now exposed in dbus interface org.bluez.Battery1 (see https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc/battery-api.txt)

I can submit a PR implementing support for this (my initial idea was to add a profile.Battery1 struct and profile.Battery1Properties and then put those inside the api.Device and expose it with dev.GetBatteryProperties() etc.) but the one thing I'm not sure about is how to handle bluez versions less than 5.48 properly. Is there currently anywhere in the code-base where the bluez version is checked or stored so I could check if that exists when initializing an api.Device? It's also not clear to me that we can easily detect the version of bluez via dbus alone unfortunately so the best thing I can guess is just silently continue on creating the device if the Battery1 interface doesn't exist the first time we use that client.

BlueZ 5.46 error: No such field: NotifyAcquired in obj, No such field: WriteAcquired in obj

It looks like there is an issue trying to use this library with the latest version of BlueZ. I used your script to upgrade to version 5.46 so that I could use the new acquire-write and acquire-notify features. But now when I try using api.GetDeviceByAddress(deviceID) I get the following error messages:

root@GBRPI01:~/go/src/gitlab.com/gbrayut/rpi# go run cmd/ble-test/main.go
Starting BLE test app
hciconfig status: &linux.HCIConfigResult{Enabled:true, Address:"B8:27:EB:CF:0F:5B", Type:"Primary", Bus:"UART"}
panic: No such field: NotifyAcquired in obj

goroutine 1 [running]:
gitlab.com/gbrayut/rpi/vendor/github.com/muka/go-bluetooth/bluez/profile.NewGattCharacteristic1(0x11aea180, 0x3a, 0x11aea180)
        /home/gbray/go/src/gitlab.com/gbrayut/rpi/vendor/github.com/muka/go-bluetooth/bluez/profile/GattCharacteristic1.go:27 +0x1a4
gitlab.com/gbrayut/rpi/vendor/github.com/muka/go-bluetooth/api.(*Device).GetCharByUUID(0x11ab67c0, 0x11afaf90, 0x24, 0x0, 0x0, 0x70)
        /home/gbray/go/src/gitlab.com/gbrayut/rpi/vendor/github.com/muka/go-bluetooth/api/Device.go:256 +0x328
main.main()
        /home/gbray/go/src/gitlab.com/gbrayut/rpi/cmd/ble-test/main.go:59 +0x1a4
exit status 2


root@GBRPI01:~/go/src/gitlab.com/gbrayut/rpi# go run cmd/ble-test/main.go
Starting BLE test app
hciconfig status: &linux.HCIConfigResult{Enabled:true, Address:"B8:27:EB:CF:0F:5B", Type:"Primary", Bus:"UART"}
panic: No such field: WriteAcquired in obj

goroutine 1 [running]:
gitlab.com/gbrayut/rpi/vendor/github.com/muka/go-bluetooth/bluez/profile.NewGattCharacteristic1(0x1161c380, 0x3a, 0x1161c380)
        /home/gbray/go/src/gitlab.com/gbrayut/rpi/vendor/github.com/muka/go-bluetooth/bluez/profile/GattCharacteristic1.go:27 +0x1a4
gitlab.com/gbrayut/rpi/vendor/github.com/muka/go-bluetooth/api.(*Device).GetCharByUUID(0x11655360, 0x11616e40, 0x24, 0x0, 0x0, 0x70)
        /home/gbray/go/src/gitlab.com/gbrayut/rpi/vendor/github.com/muka/go-bluetooth/api/Device.go:256 +0x328
main.main()
        /home/gbray/go/src/gitlab.com/gbrayut/rpi/cmd/ble-test/main.go:59 +0x1a4
exit status 2

These seem to be from the new features in 5.46. I was able to add the two missing properties to GattCharacteristic1Properties in my vendor\github.com\muka\go-bluetooth\bluez\profile\GattCharacteristic1.go file and it started working again

// GattCharacteristic1Properties exposed properties for GattCharacteristic1
type GattCharacteristic1Properties struct {
	Value          []byte
	Notifying      bool
	NotifyAcquired bool
	WriteAcquired  bool
	Service        dbus.ObjectPath
	UUID           string
	Flags          []string
	Descriptors    []dbus.ObjectPath
}

Not sure if there is a way to make it backwards compatible or not, but just thought I would give you a heads up.

watch-agent for heart rate device

Hi
@muka any advice what should I do in order to read data from heart rate device?

I'm using your watch-agent example with few modifications

Problem:

  • I do have a lot of services and I don't know how to read data from it
  • I'm getting bunch of errors No such interface 'org.bluez.GattCharacteristic1' for profile.NewGattCharacteristic1(charEvent.DevicePath)

and currently i'm out of ideas how to fix them

$ go run cmd/console/main.go 
{"level":"debug","service":"heartrate","component":"discovery","time":"2019-02-22T13:14:04-08:00","message":"Reset bluetooth device"}

{"level":"info","service":"heartrate","component":"discovery","time":"2019-02-22T13:14:12-08:00","message":"name=TICKR 3988 addr=E7:BC:BE:49:92:0C rssi=-94"}
Found TICKR 3988 [addr:E7:BC:BE:49:92:0C], list profiles
Connecting device TICKR 3988


char data, props {/org/bluez/hci0/dev_E7_BC_BE_49_92_0C/service0008/char0009 /org/bluez/hci0/dev_E7_BC_BE_49_92_0C 0xc4200dd3b0 0} &{[] false false false /org/bluez/hci0/dev_E7_BC_BE_49_92_0C/service0008 00002a05-0000-1000-8000-00805f9b34fb [indicate] []}
service  2A05 
Found char  (2A05 : /org/bluez/hci0/dev_E7_BC_BE_49_92_0C/service0008/char0009)
char data, props {/org/bluez/hci0/dev_E7_BC_BE_49_92_0C/service0010/char0011 /org/bluez/hci0/dev_E7_BC_BE_49_92_0C 0xc4202ae380 0} &{[] false false false /org/bluez/hci0/dev_E7_BC_BE_49_92_0C/service0010 00002a29-0000-1000-8000-00805f9b34fb [read] []}
service  2A29 
Found char  (2A29 : /org/bluez/hci0/dev_E7_BC_BE_49_92_0C/service0010/char0011)
char data, props {/org/bluez/hci0/dev_E7_BC_BE_49_92_0C/service0010/char0013 /org/bluez/hci0/dev_E7_BC_BE_49_92_0C 0xc4202ae690 0} &{[] false false false /org/bluez/hci0/dev_E7_BC_BE_49_92_0C/service0010 00002a27-0000-1000-8000-00805f9b34fb [read] []}
service  2A27 
Found char  (2A27 : /org/bluez/hci0/dev_E7_BC_BE_49_92_0C/service0010/char0013)
char data, props {/org/bluez/hci0/dev_E7_BC_BE_49_92_0C/service0010/char0015 /org/bluez/hci0/dev_E7_BC_BE_49_92_0C 0xc4202d8690 0} &{[] false false false /org/bluez/hci0/dev_E7_BC_BE_49_92_0C/service0010 00002a26-0000-1000-8000-00805f9b34fb [read] []}
service  2A26 
Found char  (2A26 : /org/bluez/hci0/dev_E7_BC_BE_49_92_0C/service0010/char0015)
char data, props {/org/bluez/hci0/dev_E7_BC_BE_49_92_0C/service0017/char0018 /org/bluez/hci0/dev_E7_BC_BE_49_92_0C 0xc4202d89a0 0} &{[] false false false /org/bluez/hci0/dev_E7_BC_BE_49_92_0C/service0017 a026e002-0a7d-4ab3-97fa-f1500f9feb8b [write-without-response notify] []}
service  E002 
Found char  (E002 : /org/bluez/hci0/dev_E7_BC_BE_49_92_0C/service0017/char0018)
char data, props {/org/bluez/hci0/dev_E7_BC_BE_49_92_0C/service0017/char001b /org/bluez/hci0/dev_E7_BC_BE_49_92_0C 0xc420189490 0} &{[] false false false /org/bluez/hci0/dev_E7_BC_BE_49_92_0C/service0017 a026e004-0a7d-4ab3-97fa-f1500f9feb8b [notify] []}
service  E004 
Found char  (E004 : /org/bluez/hci0/dev_E7_BC_BE_49_92_0C/service0017/char001b)
char data, props {/org/bluez/hci0/dev_E7_BC_BE_49_92_0C/service001e/char001f /org/bluez/hci0/dev_E7_BC_BE_49_92_0C 0xc4200ddce0 0} &{[] false false false /org/bluez/hci0/dev_E7_BC_BE_49_92_0C/service001e a026e00a-0a7d-4ab3-97fa-f1500f9feb8b [write-without-response notify] []}
service  E00A 
Found char  (E00A : /org/bluez/hci0/dev_E7_BC_BE_49_92_0C/service001e/char001f)
char data, props {/org/bluez/hci0/dev_E7_BC_BE_49_92_0C/service0022/char0023 /org/bluez/hci0/dev_E7_BC_BE_49_92_0C 0xc420189ab0 0} &{[] false false false /org/bluez/hci0/dev_E7_BC_BE_49_92_0C/service0022 00002a37-0000-1000-8000-00805f9b34fb [notify] []}
service  2A37 
Found char  (2A37 : /org/bluez/hci0/dev_E7_BC_BE_49_92_0C/service0022/char0023)
char data, props {/org/bluez/hci0/dev_E7_BC_BE_49_92_0C/service0022/char0026 /org/bluez/hci0/dev_E7_BC_BE_49_92_0C 0xc420366000 0} &{[] false false false /org/bluez/hci0/dev_E7_BC_BE_49_92_0C/service0022 00002a38-0000-1000-8000-00805f9b34fb [read] []}
service  2A38 
Found char  (2A38 : /org/bluez/hci0/dev_E7_BC_BE_49_92_0C/service0022/char0026)
err:  No such interface 'org.bluez.GattCharacteristic1'
err:  No such interface 'org.bluez.GattCharacteristic1'
err:  No such interface 'org.bluez.GattCharacteristic1'
err:  No such interface 'org.bluez.GattCharacteristic1'
err:  No such interface 'org.bluez.GattCharacteristic1'
err:  No such interface 'org.bluez.GattCharacteristic1'
err:  No such interface 'org.bluez.GattCharacteristic1'
err:  No such interface 'org.bluez.GattCharacteristic1'
err:  No such interface 'org.bluez.GattCharacteristic1'

If you have any suggestions - that will be nice

thank you

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.