Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

BLE Notifications Not Received on Windows #312

Open
dirong opened this issue Dec 22, 2024 · 0 comments
Open

BLE Notifications Not Received on Windows #312

dirong opened this issue Dec 22, 2024 · 0 comments
Labels

Comments

@dirong
Copy link

dirong commented Dec 22, 2024

I encountered an issue to receiving BLE notifications. The code below works perfectly on macOS, but on Windows, notifications from my BLE device are not received.

package main

import (
	"encoding/hex"
	"runtime"
	"time"
	"tinygo.org/x/bluetooth"
)

var adapter = bluetooth.DefaultAdapter

func main() {
	// Enable BLE interface.
	must("enable BLE stack", adapter.Enable())

	var foundDevice bluetooth.ScanResult

	// Start scanning.
	println("scanning...")
	err := adapter.Scan(func(adapter *bluetooth.Adapter, device bluetooth.ScanResult) {
		if len(device.AdvertisementPayload.ManufacturerData()) > 0 && device.AdvertisementPayload.ManufacturerData()[0].CompanyID == 0xXXXX {
			println("found device:", device.Address.String(), device.RSSI, hex.EncodeToString(device.AdvertisementPayload.ManufacturerData()[0].Data))
			foundDevice = device
			// Stop the scan.
			err := adapter.StopScan()
			if err != nil {
				// Unlikely, but we can't recover from this.
				println("failed to stop the scan:", err.Error())
			}
		}
	})
	if name := foundDevice.LocalName(); name == "" {
		print("	Connecting to ", foundDevice.Address.String(), "...")
		println()
	} else {
		print("	Connecting to ", name, " (", foundDevice.Address.String(), ")...")
		println()
	}

	device, err := adapter.Connect(foundDevice.Address, bluetooth.ConnectionParams{})
	if err != nil {
		println("Failed to connect:", err.Error())
		return
	}

	defer device.Disconnect()

	println("Discovering service...")
	targetUUID, err := bluetooth.ParseUUID("XXXXX")
	if err != nil {
		println("Failed to parse service UUID:", err.Error())
		return
	}
	services, err := device.DiscoverServices([]bluetooth.UUID{targetUUID})
	if err != nil {
		println("Failed to discover the service:", err.Error())
		return
	}
	service := services[0]
	chars, err := service.DiscoverCharacteristics([]bluetooth.UUID{parseUUIDForce("XXXXX"), parseUUIDForce("XXXXX")})
	if err != nil {
		println("Failed to discover RX and TX characteristics:", err.Error())
		return
	}
	var sensorCharacteristic = chars[0]
	var collectorCharacteristic = chars[1]
	err = sensorCharacteristic.EnableNotifications(func(value []byte) {
		println("Sensor Received:", hex.EncodeToString(value))
	})
	if err != nil {
		println("Failed to enable sensor notifications:", err.Error())
		return
	}
	err = collectorCharacteristic.EnableNotifications(func(value []byte) {
		println("Collector Received:", hex.EncodeToString(value))
	})
	if err != nil {
		println("Failed to enable collector notifications:", err.Error())
		return
	}
	println("Enabled notifications for sensor and collector characteristics")
	println("Writing to collector characteristic with AliveFrame")
	message, err := hex.DecodeString("some bytes")
	writeWithoutResponse, err := collectorCharacteristic.WriteWithoutResponse(message)
	if err != nil {
		return
	}
	println("Write #1: ", writeWithoutResponse)
	message, err = hex.DecodeString("some bytes")
	writeWithoutResponse, err = collectorCharacteristic.WriteWithoutResponse(message)
	if err != nil {
		return
	}
	println("Write #2: ", writeWithoutResponse)
	message, err = hex.DecodeString("some bytes")
	writeWithoutResponse, err = collectorCharacteristic.WriteWithoutResponse(message)
	if err != nil {
		return
	}
	println("Write #3: ", writeWithoutResponse)
	writeWithoutResponse, err = collectorCharacteristic.WriteWithoutResponse([]byte{0x0F})
	if err != nil {
		println("Write ERROR: ", err)
	}
	must("start scan", err)

	select {}
}

func parseUUIDForce(s string) bluetooth.UUID {
	uuid, err := bluetooth.ParseUUID(s)
	if err != nil {
		panic(err)
	}
	return uuid
}

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

Could this issue be related to how Windows handles BLE notifications? Are there any known issues with Windows BLE stack integration?

@dirong dirong changed the title BLE Notifications Not Received on Windows Using BLE Notifications Not Received on Windows Dec 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants