Giter Site home page Giter Site logo

go-ble / ble Goto Github PK

View Code? Open in Web Editor NEW

This project forked from moogle19/ble

298.0 298.0 107.0 540 KB

Bluetooth Low Energy for Linux / macOS

License: BSD 3-Clause "New" or "Revised" License

Go 99.92% Makefile 0.08%
ble bluetooth bluetooth-low-energy go golang linux macos macosx

ble's People

Contributors

abferm avatar andrerenaud avatar armaanhammer avatar cbrake avatar ccollins476ad avatar chenkaie avatar deadprogram avatar dnesting avatar estutzenberger avatar fopina avatar hasty avatar huguesb avatar jacobrosenthal avatar jaracil avatar jlubawy avatar lassiheikkila avatar markdrayton avatar memoos avatar mfiumara avatar moogle19 avatar orangenpresse avatar panzerdev avatar peterhellberg avatar quasilyte avatar rkjdid avatar roylee17 avatar syoder avatar xibz avatar yoffy avatar zappl004 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

ble's Issues

LE Extended Support (coded phy)

Hello,

It's more a question than an Issue. For a project, I have to implement a Long-range (coded-PHY ) protocol support.
I've started to add this feature, but I just want to know if some of you have already worked on that?
or if one has interests to help me on this task?

Thank you

Bugs in blesh

blesh uses code like this:

if u := curr.profile.Find(ble.NewCharacteristic(curr.uuid)); u != nil {

However, u != nil will be true always, even if FindCharacteristic returns nil(!), due to typed nil.

ble.Connect Mac OS X Mogave

Hi,

Problem

Does someone try to connect to a peripheral using
ble.Connect(ctx context.Context, f AdvFilter) (Client, error)
on Mogave (beta 10.14)
On my side the AdvFilter is never called.

Test Environement

On High Sierra the AdvFilter is called correctly and I'm able to filter peripherals and connect to the choosen one.
On Mogave AdvFilter is never called. then timeout based on context provided

Both environment are the same (except for OS Version).

  • go 1.11 darwin/amd64
  • Same BLE Device to connect to
  • Same room (same RF Interferences)

Best

Data race

When running with "-race" data races are detected.

To replicate just run this example code with "-race" flag:

package main

import (
	"context"
	"flag"
	"fmt"
	"log"
	"time"

	"github.com/go-ble/ble"
	"github.com/go-ble/ble/examples/lib/dev"
	"github.com/pkg/errors"
)

var (
	device = flag.String("device", "default", "implementation of ble")
	du     = flag.Duration("du", 5*time.Second, "scanning duration")
	dup    = flag.Bool("dup", true, "allow duplicate reported")
)

func main() {
	flag.Parse()

	d, err := dev.NewDevice(*device)
	if err != nil {
		log.Fatalf("can't new device : %s", err)
	}
	ble.SetDefaultDevice(d)

	// Scan for specified durantion, or until interrupted by user.
	fmt.Printf("Scanning for %s...\n", *du)
	ctx := ble.WithSigHandler(context.WithTimeout(context.Background(), *du))
	chkErr(ble.Scan(ctx, *dup, advHandler, nil))
}

func advHandler(a ble.Advertisement) {
	if a.Connectable() {
		fmt.Printf("[%s] C %3d:", a.Addr(), a.RSSI())
	} else {
		fmt.Printf("[%s] N %3d:", a.Addr(), a.RSSI())
	}
	comma := ""
	if len(a.LocalName()) > 0 {
		fmt.Printf(" Name: %s", a.LocalName())
		comma = ","
	}
	if len(a.Services()) > 0 {
		fmt.Printf("%s Svcs: %v", comma, a.Services())
		comma = ","
	}
	if len(a.ManufacturerData()) > 0 {
		fmt.Printf("%s MD: %X", comma, a.ManufacturerData())
	}
	fmt.Printf("\n")
}

func chkErr(err error) {
	switch errors.Cause(err) {
	case nil:
	case context.DeadlineExceeded:
		fmt.Printf("done\n")
	case context.Canceled:
		fmt.Printf("canceled\n")
	default:
		log.Fatalf(err.Error())
	}
}

skt: unsupported event packet: then panic

After some time (days) of running ble.Scan, it crashes:

2020/09/20 03:35:07 skt: unsupported event packet: 18 A4 C1 38 A2 6F 07 00 B0 40
 56 0B 9E 29 C1 3E 1B 02 01 00 00 FD 20 E2 CD 69 C8 0F 02 01 1A 0B FF 4C 00 09 06 03 24 C0 A8 00 05 B1 3E 0C 02 01 04 00 FD 20 E2 CD 69 C8 00 B0 3E 1B 02 01 00 00 FD 20 E2 CD 69 C8 0F 02 01 1A 0B FF 4C 00 09 06 03 24 C0 A8 00 05 B2 3E 1D 02 01 00 00 07 6F A2 38 C1 A4 11 10 16 1A 18 A4 C1 38 A2 6F 07 00 B0 40 56 0B 9E 29 C0 3E 18 02 01 04 00 07 6F A2 38 C1 A4 0C 0B 09 41 54 43 5F 41 32 36 46 30 37 C0 3E 1D 02 01 00 00 63 3D F1 38 C1 A4 11 10 16 1A 18 A4 C1 38 F1 3D
2020/09/20 03:35:07 skt: unsupported event packet: 63 00
2020/09/20 03:35:08 skt: unsupported event packet: 09 06 03 24 C0 A8 00 05
2020/09/20 03:35:09 skt: unsupported event packet: B2 3E 0C 02 01 04 00 FD 20 E2 CD 69 C8 00 B1 3E 1B 02 01 00 00 FD 20 E2 CD 69 C8 0F 02 01 1A 0B FF 4C 00 09 06 03 24 C0 A8 00 05 B2 3E 1D 02 01 00 00 63 3D F1 38 C1 A4 11 10 16 1A 18 A4 C1 38
2020/09/20 03:35:10 skt: unsupported event packet: F1 3D 63 00 FF 36 61 0C 06 90 C7 3E 18 02 01 04 00 63 3D F1 38 C1 A4 0C 0B 09 41 54 43 5F 46 31 33 44 36 33 C7 3E 1B 02 01 00 00 FD 20 E2 CD 69 C8 0F 02 01 1A 0B FF 4C 00 09 06 03 24 C0 A8
2020/09/20 03:35:10 skt: unsupported event packet: 00 05 B0 3E 1D 02 01
2020/09/20 03:35:10 skt: unsupported event packet: 00 00
2020/09/20 03:35:11 skt: unsupported event packet: 07 6F A2 38 C1 A4 11 10 16 1A 18 A4 C1 38 A2 6F 07 00 B0 40 56 0B 9E 29 BE 3E 1D 02 01 00 00 63 3D F1 38 C1 A4 11 10 16 1A 18 A4 C1 38 F1 3D 63 00 FF 36 61 0C 06 90 D5 3E 1B 02 01 00 00 FD 20 E2 CD 69 C8 0F 02 01 1A 0B FF 4C 00 09 06 03 24 C0 A8 00 05 B0 3E 1B 02 01 00 00 FD 20 E2 CD 69 C8 0F 02 01 1A 0B FF 4C 00 09 06 03 24 C0 A8 00 05
2020/09/20 03:35:14 skt: unsupported event packet: B0 3E 1A 02 01 00 01 8F 54 EB 8B 62 4E 0E 02 01 06 0A FF 4C 00 10 05 01 18 11 58 45 B0 3E 1B 02 01 00 00 FD 20 E2 CD 69 C8 0F 02 01 1A 0B FF 4C 00 09 06 03 24 C0 A8 00 05 B1 3E 1D 02 01 00 00
...
...
panic: runtime error: index out of range [1] with length 0

goroutine 19 [running]:
encoding/binary.littleEndian.Uint16(...)
        /usr/lib/go/src/encoding/binary/binary.go:53
github.com/go-ble/ble/linux/hci/evt.CommandStatus.CommandOpcode(...)
        /home/leah/.go/pkg/mod/github.com/go-ble/[email protected]/linux/hci/evt/evt_gen.go:62
github.com/go-ble/ble/linux/hci.(*HCI).handleCommandStatus(0xc00007fd40, 0xc000025a9b, 0x2, 0x2, 0xc000082300, 0xc00004de58)
        /home/leah/.go/pkg/mod/github.com/go-ble/[email protected]/linux/hci/hci.go:465 +0x26f
github.com/go-ble/ble/linux/hci.(*HCI).handleEvt(0xc00007fd40, 0xc000025a99, 0x4, 0x4, 0x44ea16, 0xc000025a98)
        /home/leah/.go/pkg/mod/github.com/go-ble/[email protected]/linux/hci/hci.go:371 +0x25a
github.com/go-ble/ble/linux/hci.(*HCI).handlePkt(0xc00007fd40, 0xc000025a98, 0x5, 0x5, 0xc000025a98, 0x0)
        /home/leah/.go/pkg/mod/github.com/go-ble/[email protected]/linux/hci/hci.go:343 +0x2b9
github.com/go-ble/ble/linux/hci.(*HCI).sktLoop(0xc00007fd40)
        /home/leah/.go/pkg/mod/github.com/go-ble/[email protected]/linux/hci/hci.go:311 +0x150
created by github.com/go-ble/ble/linux/hci.(*HCI).Init
        /home/leah/.go/pkg/mod/github.com/go-ble/[email protected]/linux/hci/hci.go:153 +0x54a

Cannot connect after ~4 connections.

Running on Ubuntu 18.04, although the same issue appears on Ubuntu 16 Core
I've found an issue in an app I'm writing, where I scan the Bluetooth devices in range, filter out any devices that are not the sensors I'm interested in, then connect to each in turn in order to obtain information from them. After 4 successful connections connections lock up in Scan it seems.

I've modified the main function in examples/basic/explorer to distill the issue into something that I hope makes sense. This will connect to the first few devices, then it will never come out of dev.NewDevice(...)

func main() {
	flag.Parse()
	d, err := dev.NewDevice(*device)
	if err != nil {
		log.Fatalf("can't new device : %s", err)
	}
	ble.SetDefaultDevice(d)

	addresses := []string{"c1:85:1f:60:83:f8", "c7:7f:04:8d:ee:59", "c9:35:97:07:94:e1", "e6:2d:89:8c:49:6c", "e6:bd:57:4e:20:df", "e9:1e:0e:18:d0:92", "eb:d6:c9:6c:ef:87", "ed:24:62:72:24:9b", "f4:64:fb:60:22:cb"}

	for _, a := range addresses {
		filter := filter(a)
		ctx := ble.WithSigHandler(context.WithTimeout(context.Background(), *sd))
		cln, err := ble.Connect(ctx, filter)
		if err != nil {
			log.Fatalf("can't connect : %s", err)
		}
		done := make(chan struct{})
		go func() {
			<-cln.Disconnected()
			fmt.Printf("[ %s ] is disconnected \n", cln.Addr())
			close(done)
		}()
		fmt.Printf("Discovering profile...\n")
		_, err = cln.DiscoverProfile(true)
		if err != nil {
			log.Fatalf("can't discover profile: %s", err)
		}
		// Disconnect the connection. (On OS X, this might take a while.)
		fmt.Printf("Disconnecting [ %s ]... (this might take up to few seconds on OS X)\n", cln.Addr())
		cln.CancelConnection()
		<-done
	}
}

scanner can't bind hci0

I'm getting an error running the scanner example app as root on debian:

Is it not possible to have other unix processes connected to hci at the same time as this library? I'm trying to build an application that just scans and connects to periphials, but there are other apps using the hci0 as well for connecting to other periphials via bluetooth as well.

2018/04/20 07:29:59 can't new device : can't init hci: no devices available: (hci0: can't bind socket to hci user channel: invalid argument)

Mojave blues...

I know the Mac version is no longer being maintained, but I have a Gobot project I am working on in Mojave and I'm keen to keep this library going on Mac if I can help maintain it. Problem is that I'm on brick number 1 of this road that it seems many before me trod the entire thing to get through High Sierra.

Where I sit right now is with a utsname.Release of 18.6.0 on my Mac along with bluetoothd v6.0.12. I have the following unknown XPC IDs and am not entirely sure how to start digging in to help myself here. Any guidance from those battle-hardened souls who swore this off after High Sierra?

2019/06/21 12:49:39 Unhandled event: xpc.Dict{"kCBMsgArgs":xpc.Dict{"kCBAdvDataDeviceAddress":[]uint8{0x65, 0x1f, 0xe4, 0xce, 0x20, 0xd0}}, "kCBMsgId":38}
2019/06/21 12:49:39 Unhandled event: xpc.Dict{"kCBMsgArgs":xpc.Dict{"kCBAdvDataDeviceAddress":[]uint8{0x65, 0x1f, 0xe4, 0xce, 0x20, 0xd0}}, "kCBMsgId":38}
2019/06/21 13:00:15 Unhandled event: xpc.Dict{"kCBMsgArgs":xpc.Dict{"kCBMsgArgATTMTU":23, "kCBMsgArgDeviceUUID":xpc.UUID{0xcd, 0xff, 0xd7, 0x42, 0xca, 0x56, 0x4a, 0x36, 0x92, 0x5b, 0xbe, 0x12, 0xc6, 0xfb, 0x8e, 0x43}}, "kCBMsgId":67}
2019/06/21 13:00:15 Unhandled event: xpc.Dict{"kCBMsgArgs":xpc.Dict{"kCBMsgArgATTMTU":23, "kCBMsgArgDeviceUUID":xpc.UUID{0xcd, 0xff, 0xd7, 0x42, 0xca, 0x56, 0x4a, 0x36, 0x92, 0x5b, 0xbe, 0x12, 0xc6, 0xfb, 0x8e, 0x43}}, "kCBMsgId":67}
2019/06/21 13:00:16 Unhandled event: xpc.Dict{"kCBMsgArgs":xpc.Dict{"kCBMsgArgConnectionInterval":18, "kCBMsgArgConnectionLatency":0, "kCBMsgArgDeviceUUID":xpc.UUID{0xcd, 0xff, 0xd7, 0x42, 0xca, 0x56, 0x4a, 0x36, 0x92, 0x5b, 0xbe, 0x12, 0xc6, 0xfb, 0x8e, 0x43}, "kCBMsgArgSupervisionTimeout":175}, "kCBMsgId":70}
2019/06/21 13:00:16 Unhandled event: xpc.Dict{"kCBMsgArgs":xpc.Dict{"kCBMsgArgConnectionInterval":18, "kCBMsgArgConnectionLatency":0, "kCBMsgArgDeviceUUID":xpc.UUID{0xcd, 0xff, 0xd7, 0x42, 0xca, 0x56, 0x4a, 0x36, 0x92, 0x5b, 0xbe, 0x12, 0xc6, 0xfb, 0x8e, 0x43}, "kCBMsgArgSupervisionTimeout":175}, "kCBMsgId":70}

The *darwin.Device type does not implement ble.DeviceOption

Support for macOS was broken with the addition of the SetConnectedHandler and SetDisconnectedHandler methods to the ble.DeviceOption interface.

Iโ€™m aware that macOS isnโ€™t actively maintained, but I thought it might be a good idea for it to at least compile.

(By doing something along these lines)

diff --git a/darwin/option.go b/darwin/option.go
index 1d86b7c..27d324f 100644
--- a/darwin/option.go
+++ b/darwin/option.go
@@ -5,8 +5,19 @@ import (
        "time"

        "github.com/go-ble/ble/linux/hci/cmd"
+       "github.com/go-ble/ble/linux/hci/evt"
 )

+// SetConnectedHandler sets handler to be called when new connection is established.
+func (d *Device) SetConnectedHandler(f func(evt.LEConnectionComplete)) error {
+       return errors.New("Not supported")
+}
+
+// SetDisconnectedHandler sets handler to be called on disconnect.
+func (d *Device) SetDisconnectedHandler(f func(evt.DisconnectionComplete)) error {
+       return errors.New("Not supported")
+}
+
 // SetPeripheralRole configures the device to perform Peripheral tasks.
 func (d *Device) SetPeripheralRole() error {
        d.role = 1

Unfortunately it seem like this doesnโ€™t actually make this project work under macOS, so another idea would be to just remove the darwin package from this repo.

Leaking goroutines in Conn.recombine()?

I have a small app to poll Xiaomi temperature sensors using go-ble. It's leaking goroutines in Conn.recombine(). As seen from pprof:

goroutine profile: total 110
99 @ 0x4a078 0x173d8 0x170cc 0x373e00 0x37bf94 0x7c740
#	0x373dff	github.com/go-ble/ble/linux/hci.(*Conn).recombine+0x3b	/home/mark/go/pkg/mod/github.com/go-ble/[email protected]/linux/hci/conn.go:254
#	0x37bf93	github.com/go-ble/ble/linux/hci.newConn.func1+0x1b	/home/mark/go/pkg/mod/github.com/go-ble/[email protected]/linux/hci/conn.go:92

Any suggestions on what's up here? It's very possible I am doing something wrong here with contexts or whatever (I'm pretty new to Go) but no amount of fiddling/studying the code has fixed the situation.

Bluetooth device dissapears after ~8 connections

Im seeing an issue on my (CentOS 7) device with example server in the repo.

Running the server and using the LightBlue iOS App to connect and disconnect. After 7-9 times, bluettooth device dissapears.
I dont see anything in the logs for the reason.

Has anyone else seen this problem? Are there any restrictions to the number of connections one can have in total?

SMP "Just Works"

I see that the smp.go is the same as the original fork so this doesn't support any pairing feature ?
I would like to use just works noinputkeydisplay

System requirements?

Does this library require installing any Bluetooth packages on Linux or Mac? Eg apt-get install bluetooth/bluez on Ubuntu?

disconnect event problem

Hi @moogle19

This is in regards to the commit:
moogle19@619ee1f#diff-b4cc0f5fcbe12994ce01c868ee39ec66

Please note that changing c.param.Role comparison from roleSlave to roleMaster in this commit breaks the following scenario for me:

  • PC1 to PC2 connection (using two regular USB dongles), where PC1 is the Master (client), PC2 is the Slave (peripheral)
  • PC1 connects to PC2, reads / writes something on PC2, and disconnects from PC2
  • After disconnection, PC2 receives the handleDisconnectionComplete event
  • PC2 checks to see the role code, which is 1 (Slave), not 0 (Master).
  • Because of this PC2 does not send the HCI advertising re-enable command, and it is subsequently unable to receive new connections after the one initial connection.

Feature Request: WriteLongCharacteristic

Client.WriteLongCharacteristic() is not implemented, and there are bugs in Client.PrepareWrite() and Client.ExecuteWrite().

I have implemented the function and the fixes.

I'm submitting a pull request

hci.go: undefined: log

How to reproduce this issue:

[test@gm ~]$ go get github.com/apache/mynewt-mcumgr-cli/mcumgr
# github.com/go-ble/ble/linux/hci
go/src/github.com/go-ble/ble/linux/hci/hci.go:316:5: undefined: log

Unhandled event packet: HCI_EV_ROLE_CHANGE (0x12) (Linux)

Using this for some passive BLE monitoring under Linux and I've seen the following error:

can't accept: skt: unsupported event packet: 12 16 95 FE 50 20 AA 01 64 92 85 DC A8 65 4C 0A 10 01 53 AD 3E 23 02 01

followed by massive memory usage (up from 100s of K to 30G+) before the OOM killer kicks in. This appears to be an HCI_EV_ROLE_CHANGE event from the kernel.

Unhandled events - OSX High Sierra

So, my last PR notwithstanding, there are still some additional ID under OS X "High Sierra" that need to be implemented.

Here is a log from a recent user:

2017/11/05 15:29:15 Unhandled event: xpc.Dict{"kCBMsgId":57, "kCBMsgArgs":xpc.Dict{"kCBMsgArgDeviceUUID":xpc.UUID{0x74, 0xfd, 0xa, 0xa, 0x3d, 0x80, 0x48, 0xa7, 0xb1, 0xd0, 0xd, 0x8e, 0xd9, 0xe8, 0xcf, 0xc1}, "kCBMsgArgATTMTU":23}}
2017/11/05 15:29:15 Unhandled event: xpc.Dict{"kCBMsgId":57, "kCBMsgArgs":xpc.Dict{"kCBMsgArgATTMTU":23, "kCBMsgArgDeviceUUID":xpc.UUID{0x74, 0xfd, 0xa, 0xa, 0x3d, 0x80, 0x48, 0xa7, 0xb1, 0xd0, 0xd, 0x8e, 0xd9, 0xe8, 0xcf, 0xc1}}}
2017/11/05 15:29:15 Unhandled event: xpc.Dict{"kCBMsgId":60, "kCBMsgArgs":xpc.Dict{"kCBMsgArgConnectionInterval":18, "kCBMsgArgConnectionLatency":0, "kCBMsgArgSupervisionTimeout":175, "kCBMsgArgDeviceUUID":xpc.UUID{0x74, 0xfd, 0xa, 0xa, 0x3d, 0x80, 0x48, 0xa7, 0xb1, 0xd0, 0xd, 0x8e, 0xd9, 0xe8, 0xcf, 0xc1}}}
2017/11/05 15:29:15 Unhandled event: xpc.Dict{"kCBMsgArgs":xpc.Dict{"kCBMsgArgSupervisionTimeout":175, "kCBMsgArgDeviceUUID":xpc.UUID{0x74, 0xfd, 0xa, 0xa, 0x3d, 0x80, 0x48, 0xa7, 0xb1, 0xd0, 0xd, 0x8e, 0xd9, 0xe8, 0xcf, 0xc1}, "kCBMsgArgConnectionInterval":18, "kCBMsgArgConnectionLatency":0}, "kCBMsgId":60}

Anyone have a link to where we can obtain docs on the latest ID mapping?

Also @moogle19 I like your latest updated cmd mapping in your own fork, please merge that into this fork so if/when I find the proper IDs I can add them in the same way.

Increase MTU for Linux GATT server

I'm running the server example on an ARM embedded system equipped with Linux and to test it I sent some data through Renesas GATTBrowser on an Android device.
The example has been slightly modified to print the received data (below the interesting part of the code):

func f(req ble.Request, rsp ble.ResponseWriter) {
	fmt.Println(string(req.Data()))
}

func main() {
	// ...
	testSvc := ble.NewService(lib.TestSvcUUID)
	testSvc.AddCharacteristic(lib.NewCountChar())
	ch := lib.NewEchoChar()
	ch.HandleWrite(ble.WriteHandlerFunc(f))
	testSvc.AddCharacteristic(ch)
	// ...

I saw that the payload is always truncated to 20 bytes, no matter how many bytes I send from the Android device.
Is there a way to change the MTU or maybe enable some sort of chunking?

Thank you in advance!

how do i connect multiple devices at the same time?

i try two method.
one is one ble adapter to connect with two ble device,but the Dial is error .
another is two ble adapter ,and two ble device .i use linux.Newdevice to create Client use hci0 and hci1 ,but still fail.
what should i do?

Scan response processing

I think there may be an issue with the way scan response data is reported. I think the processing of the scan response is correct. When advertising data is requested, a new packet of advertising data is generated from both the advertising payload and scan response payload.

I'm still working through the code, but I think if some UUIDs show up in the advertising packet and some show up in the scan response, they do not get combined into a single list of UUIDs. This happens because the advertising packet bytes and scan response bytes are packed together into one long packet.

However, when the UUIDs are requested, the search stops after finding the first set of UUIDs.

if b := p.Field(someUUID128); b != nil {
	u = uuidList(u, b, 16)
}

if b := p.Field(allUUID128); b != nil {
	u = uuidList(u, b, 16)
}

Field() returns a slice containing the first occurrence of either someUUID128 or allUUID128. Since this slice is only the first occurrence, the next UUID in the packet (perhaps in the scan response) is never processed. Either Field() needs to scan the entire packet for all field occurrences and merge them together or functions that may potentially have multiple results need to scan the whole packet (such as UUIDS(). I think for now, I may work around this by making a different Fields() function that returns where it is at in the overall packet.

Thoughts on other ways to handle this?

Cannot have multiple clients - because ble advertisements stop?

Hi. I am using code similar to examples/basic/server/main.go. When ble.AdvertiseNameAndServices() is called, advertisements start broadcasting and clients can connect by picking them up. But advertisements do stop while a client is connected. As a result no other clients are able to connect. Is it possible to let the broadcasts continue while a client is connected? Should it (then) be possible to support multiple clients in parallel?

No customized service could be found while running examples/basic/server/main.go

As mentioned above, a testservice with charactertistics of "count" and "echo" can not been found while running the example code in examples/basic/server/main.go.

I built the code under macos with the following command:

$ GOOS=linux GOARCH=arm go build

and, then i scped it to the arm board, and execute the command:

# ./server

Did i use the code wrong? or something else?

Any hint is greatly appreciated!

Hanging on ble.Connect

I'm trying to search for and connect to a BLE device (from a Pi) in a loop w/ a connect timeout, and it always eventually hangs with the below goroutine trace.

The connect is being called with a timeout context:

ctx := ble.WithSigHandler(context.WithTimeout(context.Background(), time.Second*5))
cln, err := ble.Connect(ctx, pm5.filterAdvert)
goroutine 27 [chan receive, 26 minutes]:
github.com/go-ble/ble.Connect(0x5ec7dc, 0x17eea08, 0x1900998, 0x1, 0x1, 0x1900940, 0x5ec7dc)
        /home/pi/go/pkg/mod/github.com/go-ble/[email protected]/gatt.go:147 +0x1a4
<truncated>


goroutine 1083 [syscall, 26 minutes]:
syscall.Syscall(0x3, 0x7, 0x1876000, 0x1000, 0x469ce4, 0x17ee608, 0x0)
        /usr/local/go/src/syscall/asm_linux_arm.s:14 +0x8
golang.org/x/sys/unix.read(0x7, 0x1876000, 0x1000, 0x1000, 0x1876000, 0x7, 0x15b4668)
        /home/pi/go/pkg/mod/golang.org/x/[email protected]/unix/zsyscall_linux.go:1242 +0x40
golang.org/x/sys/unix.Read(...)
        /home/pi/go/pkg/mod/golang.org/x/[email protected]/unix/syscall_unix.go:157
github.com/go-ble/ble/linux/hci/socket.(*Socket).Read(0x17ee600, 0x1876000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
        /home/pi/go/pkg/mod/github.com/go-ble/[email protected]/linux/hci/socket/socket.go:123 +0x50
github.com/go-ble/ble/linux/hci.(*HCI).sktLoop(0x1504240)
        /home/pi/go/pkg/mod/github.com/go-ble/[email protected]/linux/hci/hci.go:300 +0x90
created by github.com/go-ble/ble/linux/hci.(*HCI).Init
        /home/pi/go/pkg/mod/github.com/go-ble/[email protected]/linux/hci/hci.go:153 +0x4cc

goroutine 1084 [select, 26 minutes]:
github.com/go-ble/ble/linux/hci.(*HCI).Accept(0x1504240, 0x16f20c0, 0x4, 0x1, 0x16f20c0)
        /home/pi/go/pkg/mod/github.com/go-ble/[email protected]/linux/hci/gap.go:185 +0xac
github.com/go-ble/ble/linux.loop(0x1504240, 0x17dc200, 0x203)
        /home/pi/go/pkg/mod/github.com/go-ble/[email protected]/linux/device.go:55 +0x1c
created by github.com/go-ble/ble/linux.NewDeviceWithNameAndHandler
        /home/pi/go/pkg/mod/github.com/go-ble/[email protected]/linux/device.go:48 +0x230

Get MAC address of hci

d, err := dev.NewDevice("hci0")

Does this API allow me to get the hardware address of the interface itself?

explorer: 'can't connect : can't scan: context deadline exceeded'

I built the explorer example in ble/examples/basic/explorer, and I am getting this output when running it:
Scanning for 5s... 2018/07/05 23:40:22 can't connect : can't scan: context deadline exceeded
I am running this on RPi3 with Raspbian OS:
Linux raspberrypi 4.9.59-v7+ #1047 SMP Sun Oct 29 12:19:23 GMT 2017 armv7l GNU/Linux
and my bluez is: 5.43

I was running this example because I have been building a BLE Adapter for my golang project; and I am getting this error every time the program runs my BLE code:
can't scan: default device is not set

Again, this is on a Raspbian system that has been updated to the latest version available and using a Raspberry Pi 3.

Hang on High Sierra caused by receiving two evtPeripheralConnected events

I'm trying to use this package on High Sierra (macOS 10.13.5) and I get hangs when connecting to a peripheral device because I receive two evtPeripheralConnected events from ble.Connect when only one is expected. This causes the program to hang because Device.HandleXpcEvent tries to write to the connection channel which then blocks because no one is waiting to receive on that channel.

A workaround is to make the connection channel buffered (chConn: make(chan *conn, 1),), but does anyone have an idea of why we receive two of these events?

The following program can be used to try and reproduce the issue:

package main

import (
	"context"
	"flag"
	"fmt"
	"os"

	"github.com/go-ble/ble"
	"github.com/go-ble/ble/darwin"
)

func filterDeviceName(deviceName string) func(a ble.Advertisement) bool {
	return func(a ble.Advertisement) bool {
		return a.LocalName() == deviceName
	}
}

func main() {
	flag.Parse()

	if flag.NArg() == 0 {
		fatal("Must provide a device name.\n")
	}

	deviceName := flag.Arg(0)

	// Create and set default BLE device
	dev, err := darwin.NewDevice()
	if err != nil {
		fatalf("Error creating BLE device: %v\n", err)
	}
	ble.SetDefaultDevice(dev)

	// Connect to the device
	infof("Connecting to device '%s'\n", deviceName)
	client, err := ble.Connect(context.Background(), filterDeviceName(deviceName))
	if err != nil {
		fatalf("Error dialing device: %v\n", err)
	}

	// Discover services
	services, err := client.DiscoverServices(nil)
	if err != nil {
		fatalf("Error discovering services: %v\n", err)
	}

	info("Services:\n")
	for i, s := range services {
		infof("  %d) %+v\n", i, s)

		// Discover characteristics
		chars, err := client.DiscoverCharacteristics(nil, s)
		if err != nil {
			fatalf("Error discovering characteristics: %v\n", err)
		}

		for j, c := range chars {
			infof("    %d) %+v\n", j, c)
		}
	}

	client.CancelConnection()
}

func fatal(s string) {
	info(s)
	os.Exit(1)
}

func fatalf(format string, args ...interface{}) {
	infof(format, args...)
	os.Exit(1)
}

func info(s string) {
	fmt.Fprint(os.Stderr, s)
}

func infof(format string, args ...interface{}) {
	fmt.Fprintf(os.Stderr, format, args...)
}

Scan returns before AdvHandler calls are completed

github.com/go-ble/ble v0.0.0-20200407180624-067514cd6e24 
go version go1.14.2 linux/amd64
(running on different arch) Linux kw3 4.19.97-v7l+ #1294 SMP Thu Jan 30 13:21:14 GMT 2020 armv7l GNU/Linux

Reproduce (code sample below):

  1. Call Scan with a context that expires or is cancelled
  2. Provide Scan an AdvHandler implementation that is slow
  3. Observe that AdvHandler will continue to be called after Scan returns

It is usually expected that functions that take callbacks will not return until the callbacks have returned and no further callbacks made. It looks like there's some asynchronous "start scanning"/"stop scanning" stuff happening behind the scenes and there should probably be an intentional wait in there (or abandon calls that haven't been made yet).

package main                                                                                                                                           
                                                                                                                                                       
import (                                                                                                                                               
    "context"                                                                                                                                          
    "fmt"                                                                                                                                              
    "log"                                                                                                                                              
    "sync/atomic"                                                                                                                                      
    "time"                                                                                                                                             
                                                                                                                                                       
    "github.com/go-ble/ble"                                                                                                                            
    "github.com/go-ble/ble/linux"                                                                                                                      
)                                                                                                                                                      
                                                                                                                                                       
func main() {                                                                                                                                          
    dev, err := linux.NewDevice()                                                                                                                      
    if err != nil {                                                                                                                                    
        log.Fatal(err)                                                                                                                                 
    }                                                                                                                                                  
                                                                                                                                                       
    ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)                                                                            
    defer cancel()                                                                                                                                     
                                                                                                                                                       
    var counter int32                                                                                                                                  
    dev.Scan(ctx, true, func(adv ble.Advertisement) {                                                                                                  
        time.Sleep(100 * time.Millisecond)  // enough to trigger                                                                                               
        atomic.AddInt32(&counter, 1)                                                                                                                   
    })                                                                                                                                                 
    a := atomic.LoadInt32(&counter)                                                                                                                    
    time.Sleep(1 * time.Second)                                                                                                                        
    b := atomic.LoadInt32(&counter)                                                                                                                    
    if a != b {                                                                                                                                        
        fmt.Printf("saw an extra %d calls to AdvHandler\n", b-a)                                                                                       
    } else {                                                                                                                                           
        fmt.Println("no problem")                                                                                                                      
    }                                                                                                                                                  
}

Output:

saw an extra 7 calls to AdvHandler

This creates problems if, for instance, the AdvHandler is trying to send messages on a channel, and you close the channel after Scan returns.

Support to mips?

Hi,

Thanks for the library. I am trying to run this on MIPS based platform with bluez-util v 5.49. When it's initiating, it can't create a new device and fails with file descriptor in bad state error when it makes first ioctl call. I made sure I am not running any other Bluetooth daemon at the backend(hciconfig hci0 down;service bluetoothd stop;dbus stop). But when I enable dbus, I can use bluetoothctl/hcitool utility to discover Bluetooth devices around me. Am I missing any dependency which I can add to fix this? I am sure anything ioctl(uintptr(fd), <CMD>, uintptr(id)) is failing with file descriptor in bad state

Thanks,
Aditya

Proper way to use Dial?

Hi,

I am trying to use the API - Dial in this way:
(Mostly scratched from the example but I hard-coded the MAC address to check if it works.)

ctx = ble.WithSigHandler(
    context.WithTimeout(context.Background(), *bt.durationString))
addr := ble.NewAddr("7d:3f:75:5c:09:50")
client, err := ble.Dial(ctx, addr)

The error I got is:

can't dial: connection canceled

Maybe the format of the MAC might not be the right way or the usage of API. However, I can confirm that the BLE device is working in general with other apps (nRF connect app specifically).

If the doc can be updated for the dial API, it would be helpful.

Thanks,


PS - the environment:

  • OS: Raspbian OS Buster
  • Kernel: Linux 4.19.75-v7l+ #1270 SMP Tue Sep 24 18:51:41 BST 2019 armv7l GNU/Linux
  • Go version used for build: 1.13
  • Module version: github.com/go-ble/ble v0.0.0-20190521171521-147700f13610

send page request to ble device

thanks for supporting this!
I have device that in undiscovered mode (it goes to it after paired to some device) i know it mac address and want to send page request to get info (i need only RSSI) how can i do that?

Reading a characteristic or descriptor value returns the value but does not update the object

When discovering services and characteristics for services, the service struct's characteristic array is updated as characteristics are discovered.

However, when reading a characteristic or descriptor value, the objects value member is not updated. The value is only returned from the function. It seems like the library should also update the value for characteristics and descriptors after reading them. This is of course assuming a non-error response from HCI.

I can make the updates and submit a PR if this change seems meaningful. The code I am referring to is:

linux/gatt/client.go

// ReadCharacteristic reads a characteristic value from a server. [Vol 3, Part G, 4.8.1]
func (p *Client) ReadCharacteristic(c *ble.Characteristic) ([]byte, error) {
	p.Lock()
	defer p.Unlock()
	return p.ac.Read(c.ValueHandle)
}

// ReadDescriptor reads a characteristic descriptor from a server. [Vol 3, Part G, 4.12.1]
func (p *Client) ReadDescriptor(d *ble.Descriptor) ([]byte, error) {
	p.Lock()
	defer p.Unlock()
	return p.ac.Read(d.Handle)
}

Closing a client connection without hciDev.Stop()?

I'm looking for a way to close a client connection when running gatt server with linux hci device.

Is there a way to cleanly do this without closing device's main socket?

My purpouse is to terminate an inactive connection.

Thanks

Client.Name() always returns "" on Linux

After doing a successful Dial, the client.Name() method always returns "", even though the peripheral is advertising a name. As far as I can see, the name field in the Client struct is never set.

Unhandled Exception: GATT exception, status 133 (GATT_ERROR)

Worked with this lib for the last few months using the commit 147700f From May 21, 2019

The stack is a flutter mobile app that communicate with a raspberry pi 3+

After upgrading to the latest I started to receive disconnections and the following error at the flutter console:

E/flutter ( 2776): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: Exception: GenericFailure(code: CharacteristicValueUpdateError.unknown, message: "GATT exception from MAC='XX:XX:XX:XX:XX:XX', status 133 (GATT_ERROR), type BleGattOperation{description='CHARACTERISTIC_READ'}. (Look up status 0x85 here https://android.googlesource.com/platform/external/bluetooth/bluedroid/+/android-5.1.0_r1/stack/include/gatt_api.h)")

To pin point the faulty commit I started to roll back this library and found out that the disconnections start after using commit 15dbdb1 Jan 17, 2020.

So now I am using commit 5ba052e Jan 10, 2020 and it behave well.

Let me know if you need any more information.

build instructions?

Hi

I have never heard of go...

  • I am on gentoo, so I installed go.
  • then cloned this repo
  • cd ble
    what now?
    I tried
  • go install
  • go build

both gave me error:

option.go:6:2: cannot find package "github.com/go-ble/ble/linux/hci/cmd" in any of:
        /usr/lib/go/src/github.com/go-ble/ble/linux/hci/cmd (from $GOROOT)
        /home/p/go/src/github.com/go-ble/ble/linux/hci/cmd (from $GOPATH)
gatt.go:9:2: cannot find package "github.com/pkg/errors" in any of:
        /usr/lib/go/src/github.com/pkg/errors (from $GOROOT)
        /home/p/go/src/github.com/pkg/errors (from $GOPATH)

Dial - Context with timeout

If I call the dial function with a context that times out, this timeout does not appear to be applied within the Dial function. The Dial function in hci.go relies on a dialerTmo struct field. Is there a proper way to time out a connect request?

If not, then I propose the timeout be pulled via the Context Deadline function. This should probably override the timeout specified by dialerTmo and then set it back upon exiting the function.

Thoughts? Perhaps I missed something elsewhere in the code. I'm happy to made the adjustments and file a PR.

is there a way to stop advertising?

My use of this package is with the AdvertiseNameAndServices function. I would also like some way to stop advertising those services, and I don't see a clear way to do it.
I tried ble.Stop() and device.Stop(), as well as calling the cancel func in the context. Nothing appeared to work, and I was still able to connect to and read the characteristic.

Any ideas?

ps- working from revision e78417b

Advertisement.LocalName() returns empty string if Name is sent in scan response

I'm working with a BLE beacon (Teltonika EYE Beacon) which sends LocalName in scan response.
It seems like go-ble/ble only reads the name from the initial advertisement packet.

I don't know if its desired behaviour to make this change, but reading the name from scan response is a fairly minor change:

Existing code (https://github.com/go-ble/ble/blob/master/linux/hci/adv.go#L54-L57):

// LocalName returns the LocalName of the remote peripheral.
func (a *Advertisement) LocalName() string {
	return a.packets().LocalName()
}

Proposed code:

// LocalName returns the LocalName of the remote peripheral.
func (a *Advertisement) LocalName() string {
	if a.packets().LocalName() != "" {
		return a.packets().LocalName()
	}

	if a.sr != nil && a.sr.LocalName() != "" {
		return a.sr.LocalName()
	}

	return ""
}

Please let me know if you would like me to make a proper PR about this change to integrate it to this library.

Concurrent map read/write in hci.go

fatal error: concurrent map read and map write

goroutine 67 [running]:
runtime.throw(0x4a5701, 0x21)
	/usr/local/Cellar/go/1.10.2/libexec/src/runtime/panic.go:616 +0x60 fp=0x10e8ae3c sp=0x10e8ae30 pc=0x3b364
runtime.mapaccess2_fast32(0x426160, 0x10d5c0c0, 0x2009, 0x10e22900, 0x40)
	/usr/local/Cellar/go/1.10.2/libexec/src/runtime/hashmap_fast.go:61 +0x1b0 fp=0x10e8ae4c sp=0x10e8ae3c pc=0x19f4c
github.com/go-ble/ble/linux/hci.(*HCI).handleCommandComplete(0x10ddc000, 0x10c1cdf3, 0x4, 0x4, 0x2, 0x3ea8c)
	/Users/kevin/go/src/github.com/go-ble/ble/linux/hci/hci.go:415 +0x13c fp=0x10e8ae9c sp=0x10e8ae4c pc=0x2e9eec
github.com/go-ble/ble/linux/hci.(*HCI).(github.com/go-ble/ble/linux/hci.handleCommandComplete)-fm(0x10c1cdf3, 0x4, 0x4, 0x10c7c11c, 0x43754)
	/Users/kevin/go/src/github.com/go-ble/ble/linux/hci/hci.go:121 +0x34 fp=0x10e8aeb8 sp=0x10e8ae9c pc=0x2ed7e8
github.com/go-ble/ble/linux/hci.(*HCI).handleEvt(0x10ddc000, 0x10c1cdf1, 0x6, 0x6, 0x10c2393c, 0x10d800f0)
	/Users/kevin/go/src/github.com/go-ble/ble/linux/hci/hci.go:334 +0x1f0 fp=0x10e8af10 sp=0x10e8aeb8 pc=0x2e96c4
github.com/go-ble/ble/linux/hci.(*HCI).handlePkt(0x10ddc000, 0x10c1cdf0, 0x7, 0x7, 0x7, 0x7)
	/Users/kevin/go/src/github.com/go-ble/ble/linux/hci/hci.go:306 +0x238 fp=0x10e8af88 sp=0x10e8af10 pc=0x2e91f8
github.com/go-ble/ble/linux/hci.(*HCI).sktLoop(0x10ddc000)
	/Users/kevin/go/src/github.com/go-ble/ble/linux/hci/hci.go:277 +0x124 fp=0x10e8afe4 sp=0x10e8af88 pc=0x2e8cc0
runtime.goexit()
	/usr/local/Cellar/go/1.10.2/libexec/src/runtime/asm_arm.s:1015 +0x4 fp=0x10e8afe4 sp=0x10e8afe4 pc=0x6575c
created by github.com/go-ble/ble/linux/hci.(*HCI).Init
	/Users/kevin/go/src/github.com/go-ble/ble/linux/hci/hci.go:147 +0x4d0

goroutine 1 [select]:
main.mainLoop(0x10e22200, 0x10e4e3c0, 0x10e4e400, 0x10e4e440, 0x10e74600, 0x4, 0x0, 0x0)
	/Users/kevin/go/src/zahlz.com/core/zahlzbox/cmd/indoor/main.go:133 +0x188
main.main()
	/Users/kevin/go/src/zahlz.com/core/zahlzbox/cmd/indoor/main.go:115 +0x3f0

goroutine 5 [syscall]:
os/signal.signal_recv(0x0)
	/usr/local/Cellar/go/1.10.2/libexec/src/runtime/sigqueue.go:139 +0x130
os/signal.loop()
	/usr/local/Cellar/go/1.10.2/libexec/src/os/signal/signal_unix.go:22 +0x14
created by os/signal.init.0
	/usr/local/Cellar/go/1.10.2/libexec/src/os/signal/signal_unix.go:28 +0x30

goroutine 26 [select]:
github.com/go-ble/ble/linux/hci.(*HCI).Accept(0x10ddc000, 0x0, 0x0, 0x0, 0x0)
	/Users/kevin/go/src/github.com/go-ble/ble/linux/hci/gap.go:185 +0x108
github.com/go-ble/ble/linux.loop(0x10ddc000, 0x10d18460, 0x203)
	/Users/kevin/go/src/github.com/go-ble/ble/linux/device.go:52 +0x1c
created by github.com/go-ble/ble/linux.NewDeviceWithNameAndHandler
	/Users/kevin/go/src/github.com/go-ble/ble/linux/device.go:45 +0xbc

goroutine 50 [IO wait]:
internal/poll.runtime_pollWait(0xf7eecec0, 0x72, 0x10ee2400)
	/usr/local/Cellar/go/1.10.2/libexec/src/runtime/netpoll.go:173 +0x44
internal/poll.(*pollDesc).wait(0x10de0154, 0x72, 0xffffff00, 0x4faf28, 0x6d00f0)
	/usr/local/Cellar/go/1.10.2/libexec/src/internal/poll/fd_poll_runtime.go:85 +0x8c
internal/poll.(*pollDesc).waitRead(0x10de0154, 0x10ee2400, 0x400, 0x400)
	/usr/local/Cellar/go/1.10.2/libexec/src/internal/poll/fd_poll_runtime.go:90 +0x2c
internal/poll.(*FD).Read(0x10de0140, 0x10ee2400, 0x400, 0x400, 0x0, 0x0, 0x0)
	/usr/local/Cellar/go/1.10.2/libexec/src/internal/poll/fd_unix.go:157 +0x148
net.(*netFD).Read(0x10de0140, 0x10ee2400, 0x400, 0x400, 0x93e04, 0x10ef8288, 0xeb768)
	/usr/local/Cellar/go/1.10.2/libexec/src/net/fd_unix.go:202 +0x38
net.(*conn).Read(0x10d94388, 0x10ee2400, 0x400, 0x400, 0x0, 0x0, 0x0)
	/usr/local/Cellar/go/1.10.2/libexec/src/net/net.go:176 +0x58
crypto/tls.(*block).readFromUntil(0x10d747e0, 0xf7e6c050, 0x10d94388, 0x5, 0x10d94388, 0x10ef8288)
	/usr/local/Cellar/go/1.10.2/libexec/src/crypto/tls/conn.go:493 +0x78
crypto/tls.(*Conn).readRecord(0x10ede000, 0x4b8317, 0x10ede0a0, 0x0)
	/usr/local/Cellar/go/1.10.2/libexec/src/crypto/tls/conn.go:595 +0x9c
crypto/tls.(*Conn).Read(0x10ede000, 0x10e4d000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
	/usr/local/Cellar/go/1.10.2/libexec/src/crypto/tls/conn.go:1156 +0xcc
bufio.(*Reader).fill(0x10c7e1e0)
	/usr/local/Cellar/go/1.10.2/libexec/src/bufio/bufio.go:100 +0x104
bufio.(*Reader).Peek(0x10c7e1e0, 0x2, 0xea468, 0xea48c, 0x5d, 0x8, 0xe7e14)
	/usr/local/Cellar/go/1.10.2/libexec/src/bufio/bufio.go:132 +0x28
github.com/gorilla/websocket.(*Conn).read(0x10ea0210, 0x2, 0x2, 0xe8584, 0x10c781b0, 0x4207a8, 0x10ef8290)
	/Users/kevin/go/src/github.com/gorilla/websocket/conn_read.go:12 +0x28
github.com/gorilla/websocket.(*Conn).advanceFrame(0x10ea0210, 0x10e860e0, 0x8, 0x10e4e42c)
	/Users/kevin/go/src/github.com/gorilla/websocket/conn.go:689 +0x60
github.com/gorilla/websocket.(*Conn).NextReader(0x10ea0210, 0x10d66030, 0x4, 0x10e4e400, 0x10e6df98, 0x1)
	/Users/kevin/go/src/github.com/gorilla/websocket/conn.go:844 +0x68
github.com/gorilla/websocket.(*Conn).ReadMessage(0x10ea0210, 0x4a2509, 0x1c, 0x0, 0x0, 0x0, 0x0)
	/Users/kevin/go/src/github.com/gorilla/websocket/conn.go:921 +0x1c
zahlz.com/core/boxmgmt/client.readUpdates(0x10ea0210, 0x10e4e3c0, 0x10e4e400, 0x0, 0x0)
	/Users/kevin/go/src/zahlz.com/core/boxmgmt/client/client.go:66 +0x50
zahlz.com/core/boxmgmt/client.(*Client).Run(0x10d94330, 0x10e4e3c0, 0x10e4e400, 0x10e4e440)
	/Users/kevin/go/src/zahlz.com/core/boxmgmt/client/client.go:55 +0x104
created by main.main
	/Users/kevin/go/src/zahlz.com/core/zahlzbox/cmd/indoor/main.go:90 +0x2c8

goroutine 25 [IO wait]:
internal/poll.runtime_pollWait(0xf7eecf40, 0x72, 0x0)
	/usr/local/Cellar/go/1.10.2/libexec/src/runtime/netpoll.go:173 +0x44
internal/poll.(*pollDesc).wait(0x10c7c064, 0x72, 0xc3d00, 0x0, 0x0)
	/usr/local/Cellar/go/1.10.2/libexec/src/internal/poll/fd_poll_runtime.go:85 +0x8c
internal/poll.(*pollDesc).waitRead(0x10c7c064, 0xffffff00, 0x0, 0x0)
	/usr/local/Cellar/go/1.10.2/libexec/src/internal/poll/fd_poll_runtime.go:90 +0x2c
internal/poll.(*FD).Accept(0x10c7c050, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
	/usr/local/Cellar/go/1.10.2/libexec/src/internal/poll/fd_unix.go:372 +0x174
net.(*netFD).accept(0x10c7c050, 0x10d92038, 0x1, 0x1)
	/usr/local/Cellar/go/1.10.2/libexec/src/net/fd_unix.go:238 +0x20
net.(*TCPListener).accept(0x10d92040, 0x4fb678, 0x10d5c020, 0xc)
	/usr/local/Cellar/go/1.10.2/libexec/src/net/tcpsock_posix.go:136 +0x20
net.(*TCPListener).Accept(0x10d92040, 0x3, 0x10d1c040, 0xc, 0x4fc3d8)
	/usr/local/Cellar/go/1.10.2/libexec/src/net/tcpsock.go:259 +0x3c
zahlz.com/core/opi/server.(*Server).ListenAndServe(0x10d18140, 0x4a13b5, 0x1b)
	/Users/kevin/go/src/zahlz.com/core/opi/server/server.go:42 +0x118
main.applyConfig.func1(0x10c1c150, 0xc)
	/Users/kevin/go/src/zahlz.com/core/zahlzbox/cmd/indoor/config.go:95 +0x94
created by main.applyConfig
	/Users/kevin/go/src/zahlz.com/core/zahlzbox/cmd/indoor/config.go:93 +0x370

goroutine 68 [chan receive]:
github.com/go-ble/ble/linux/hci.(*HCI).send(0x10ddc000, 0x4fc038, 0x10ddc020, 0x1514b8, 0x10d5c1c8, 0xffffffff, 0x0, 0x1)
	/Users/kevin/go/src/github.com/go-ble/ble/linux/hci/hci.go:242 +0xb4
github.com/go-ble/ble/linux/hci.(*HCI).Send(0x10ddc000, 0x4fc038, 0x10ddc020, 0x0, 0x0, 0x10d22701, 0x10d50001)
	/Users/kevin/go/src/github.com/go-ble/ble/linux/hci/hci.go:224 +0x2c
github.com/go-ble/ble/linux/hci.(*HCI).StopAdvertising(0x10ddc000, 0x0, 0x10de00a0)
	/Users/kevin/go/src/github.com/go-ble/ble/linux/hci/gap.go:176 +0x40
github.com/go-ble/ble/linux.(*Device).Advertise(0x10c0c7e8, 0x4fceb8, 0x10d5c1c0, 0x4fe1a8, 0x10de00a0, 0x10d227c0, 0x0)
	/Users/kevin/go/src/github.com/go-ble/ble/linux/device.go:110 +0x84
zahlz.com/core/zable.(*Server).advertise(0x10c7c0a0, 0x4fceb8, 0x10d5c1c0)
	/Users/kevin/go/src/zahlz.com/core/zable/server.go:306 +0x1f0
created by zahlz.com/core/zable.(*Server).Advertise
	/Users/kevin/go/src/zahlz.com/core/zable/server.go:287 +0x134

goroutine 70 [select]:
github.com/go-ble/ble/linux/hci.(*HCI).send(0x10ddc000, 0x4fc1b8, 0x10ddc043, 0x10c1cdcd, 0x1, 0x1, 0x2e752c, 0x10ddc04c)
	/Users/kevin/go/src/github.com/go-ble/ble/linux/hci/hci.go:258 +0x350
github.com/go-ble/ble/linux/hci.(*HCI).Send(0x10ddc000, 0x4fc1b8, 0x10ddc043, 0x0, 0x0, 0x0, 0x0)
	/Users/kevin/go/src/github.com/go-ble/ble/linux/hci/hci.go:224 +0x2c
github.com/go-ble/ble/linux/hci.(*HCI).SetAdvertisement(0x10ddc000, 0x10e1c540, 0x1f, 0x1f, 0x10e1c560, 0x8, 0x1f, 0xf7f486c8, 0x48)
	/Users/kevin/go/src/github.com/go-ble/ble/linux/hci/gap.go:261 +0x100
github.com/go-ble/ble/linux/hci.(*HCI).AdvertiseAdv(0x10ddc000, 0x4fe1a8, 0x10dde140, 0x10fc4601, 0x10dde140)
	/Users/kevin/go/src/github.com/go-ble/ble/linux/hci/gap.go:80 +0x260
github.com/go-ble/ble/linux.(*Device).Advertise(0x10c0c7e8, 0x4fceb8, 0x10d5c5a0, 0x4fe1a8, 0x10dde140, 0x10fc4620, 0x0)
	/Users/kevin/go/src/github.com/go-ble/ble/linux/device.go:106 +0x30
zahlz.com/core/zable.(*Server).advertise(0x10c7c0a0, 0x4fceb8, 0x10d5c5a0)
	/Users/kevin/go/src/zahlz.com/core/zable/server.go:306 +0x1f0
created by zahlz.com/core/zable.(*Server).SetManufacturerData
	/Users/kevin/go/src/zahlz.com/core/zable/server.go:201 +0x1dc

goroutine 71 [select]:
github.com/go-ble/ble/linux/hci.(*HCI).send(0x10ddc000, 0x4fc1b8, 0x10ddc043, 0x10c1cde6, 0x1, 0x1, 0x2e752c, 0x10ddc04c)
	/Users/kevin/go/src/github.com/go-ble/ble/linux/hci/hci.go:258 +0x350
github.com/go-ble/ble/linux/hci.(*HCI).Send(0x10ddc000, 0x4fc1b8, 0x10ddc043, 0x0, 0x0, 0x0, 0x0)
	/Users/kevin/go/src/github.com/go-ble/ble/linux/hci/hci.go:224 +0x2c
github.com/go-ble/ble/linux/hci.(*HCI).SetAdvertisement(0x10ddc000, 0x10ed0f00, 0x1f, 0x1f, 0x10ed0f20, 0x8, 0x1f, 0xf7f48000, 0x48)
	/Users/kevin/go/src/github.com/go-ble/ble/linux/hci/gap.go:261 +0x100
github.com/go-ble/ble/linux/hci.(*HCI).AdvertiseAdv(0x10ddc000, 0x4fe1a8, 0x10dc8190, 0x10d61c01, 0x10dc8190)
	/Users/kevin/go/src/github.com/go-ble/ble/linux/hci/gap.go:80 +0x260
github.com/go-ble/ble/linux.(*Device).Advertise(0x10c0c7e8, 0x4fceb8, 0x10d5c5e0, 0x4fe1a8, 0x10dc8190, 0x10d61cd0, 0x0)
	/Users/kevin/go/src/github.com/go-ble/ble/linux/device.go:106 +0x30
zahlz.com/core/zable.(*Server).advertise(0x10c7c0a0, 0x4fceb8, 0x10d5c5e0)
	/Users/kevin/go/src/zahlz.com/core/zable/server.go:306 +0x1f0
created by zahlz.com/core/zable.(*Server).SetManufacturerData
	/Users/kevin/go/src/zahlz.com/core/zable/server.go:201 +0x1dc

Goroutine does not release

Modify code
agtt.go 136 line
ch := make(chan Advertisement) => ch := make(chan Advertisement,1)

Why change it like this ๏ผŸ
Because if not, goroutine will not be released

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.