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) } }