I'm trying to use Tinygo Bluetooth to connect to a Timeflip v2 (https://github.com/DI-GROUP/TimeFlip.Docs/blob/master/Hardware/TimeFlip%20BLE%20protocol%20ver4_02.06.2020.md).
The API documentation says, that I need to login (which is a write to f1196f57-71a4-11e6-bdf4-0800200c9a66, followed by a read on f1196f53-71a4-11e6-bdf4-0800200c9a66 for checking the result of the login).
The only thing I see in TinyGo for DeviceCharacteristics is WriteWithoutResponse (https://pkg.go.dev/github.com/tinygo-org/bluetooth#DeviceCharacteristic.WriteWithoutResponse).
When I use this, it looks like having no affect on the result.
package main
import (
"log"
"strconv"
"tinygo.org/x/bluetooth"
)
var adapter = bluetooth.DefaultAdapter
const (
timeFlipService = "f1196f50-71a4-11e6-bdf4-0800200c9a66"
commandOutCharacteristic = "f1196f53-71a4-11e6-bdf4-0800200c9a66"
passwordCharacteristic = "f1196f57-71a4-11e6-bdf4-0800200c9a66"
)
func main() {
if err := adapter.Enable(); err != nil {
log.Fatalln(err)
}
ch := make(chan bluetooth.ScanResult, 1)
log.Println("scanning...")
if err := adapter.Scan(func(adapter *bluetooth.Adapter, device bluetooth.ScanResult) {
log.Println(device)
if device.LocalName() == "TimeFlip v2.0" {
log.Println("found timeflip")
if err := adapter.StopScan(); err != nil {
log.Println(err)
}
ch <- device
}
}); err != nil {
log.Fatalln(err)
}
var device *bluetooth.Device
select {
case result := <-ch:
var err error
device, err = adapter.Connect(result.Address, bluetooth.ConnectionParams{})
if err != nil {
log.Fatalln(err)
}
log.Println("connected to ", result.Address.String())
}
defer func() {
if err := device.Disconnect(); err != nil {
log.Println(err)
} else {
log.Println("disconnected")
}
}()
tfService, _ := bluetooth.ParseUUID(timeFlipService)
srvcs, err := device.DiscoverServices([]bluetooth.UUID{tfService})
if err != nil {
log.Fatalln(err)
}
buf := make([]byte, 20)
password, _ := bluetooth.ParseUUID(passwordCharacteristic)
cmdOut, _ := bluetooth.ParseUUID(commandOutCharacteristic)
for _, srvc := range srvcs {
log.Println("- service", srvc.UUID().String())
chars, err := srvc.DiscoverCharacteristics([]bluetooth.UUID{password, cmdOut})
if err != nil {
log.Println(err)
}
var pwChar bluetooth.DeviceCharacteristic
var cmdOutChar bluetooth.DeviceCharacteristic
for _, char := range chars {
log.Println("-- characteristic", char.UUID().String())
switch char.UUID() {
case password:
pwChar = char
case cmdOut:
cmdOutChar = char
}
}
rightPassword := []byte{0x30, 0x30, 0x30, 0x30, 0x30, 0x30}
_, err = pwChar.WriteWithoutResponse(rightPassword)
if err != nil {
log.Println(" ", err.Error())
}
n, err := cmdOutChar.Read(buf)
if err != nil {
log.Println(" ", err.Error())
} else {
log.Println(" data bytes", strconv.Itoa(n))
log.Println(" value =", buf[:n])
}
wrongPassword := []byte{0x30, 0x30, 0x30, 0x30, 0x30, 0x31}
_, err = pwChar.WriteWithoutResponse(wrongPassword)
if err != nil {
log.Println(" ", err.Error())
}
n, err = cmdOutChar.Read(buf)
if err != nil {
log.Println(" ", err.Error())
} else {
log.Println(" data bytes", strconv.Itoa(n))
log.Println(" value =", buf[:n])
}
}
}
results in
scanning...
{7A:05:BF:06:97:D6 -61 0xc00029c1e0}
{C6:D8:C0:F7:A7:3C -57 0xc00029c480}
found timeflip
connected to C6:D8:C0:F7:A7:3C
- service f1196f50-71a4-11e6-bdf4-0800200c9a66
-- characteristic f1196f57-71a4-11e6-bdf4-0800200c9a66
-- characteristic f1196f53-71a4-11e6-bdf4-0800200c9a66
data bytes 1
value = [1]
data bytes 1
value = [1]
disconnected
At least one of the results should be 0x02 (invalid password).
Could somebody give me a hint?