antplusbridge/cmd/bridge/main.go

89 lines
2.1 KiB
Go

package main
import (
"encoding/binary"
"fmt"
"os/exec"
"time"
"github.com/google/gousb"
"tinygo.org/x/bluetooth"
)
func oldMain() {
var vendorId gousb.ID = 0x0fcf
var productId gousb.ID = 0x1008
var deviceNumber uint32 = 3001
listenForAntDevice(vendorId, productId, deviceNumber)
fmt.Println("channel closed")
}
var adapter = bluetooth.DefaultAdapter
func main() {
exec.Command("hciconfig", "hci0", "down").Run()
exec.Command("hciconfig", "hci0", "up").Run()
must(adapter.Enable())
var powerChar bluetooth.Characteristic
must(adapter.AddService(&bluetooth.Service{
UUID: bluetooth.New16BitUUID(0x1818),
Characteristics: []bluetooth.CharacteristicConfig{
{
UUID: bluetooth.New16BitUUID(0x2A65), // Cycling Power Feature
Flags: bluetooth.CharacteristicReadPermission,
Value: []byte{0, 0, 0, 0},
},
{
UUID: bluetooth.New16BitUUID(0x2A63), // Cycling Power Measurement
Flags: bluetooth.CharacteristicNotifyPermission,
Handle: &powerChar,
},
},
}))
must(adapter.DefaultAdvertisement().Configure(bluetooth.AdvertisementOptions{
LocalName: "LinuxAntBtBridge",
ServiceUUIDs: []bluetooth.UUID{bluetooth.New16BitUUID(0x1818)},
}))
must(adapter.DefaultAdvertisement().Start())
fmt.Println("BLE advertising...")
var crankRevs uint16
var lastCrankEventTime uint16
for {
sec := time.Now().Second()
watts := uint16(100 + sec)
rpm := uint16(50 + sec)
// advance crank event time based on rpm
// time between crank events = 1024*60/rpm ticks
crankEventInterval := uint16(1024 * 60 / rpm)
lastCrankEventTime += crankEventInterval
crankRevs++
// flags: bit 5 = crank revolution data present
payload := make([]byte, 8)
binary.LittleEndian.PutUint16(payload[0:], 0x20)
binary.LittleEndian.PutUint16(payload[2:], watts)
binary.LittleEndian.PutUint16(payload[4:], crankRevs)
binary.LittleEndian.PutUint16(payload[6:], lastCrankEventTime)
powerChar.Write(payload)
fmt.Printf("watts: %d rpm: %d crankRevs: %d eventTime: %d\n", watts, rpm, crankRevs, lastCrankEventTime)
time.Sleep(time.Second)
}
}
func must(err error) {
if err != nil {
panic(err)
}
}