97532eaed4
Signed-off-by: deadprogram <ron@hybridgroup.com>
130 lines
3.5 KiB
Go
130 lines
3.5 KiB
Go
package main
|
|
|
|
// This example implements a NUS (Nordic UART Service) client. See nusserver for
|
|
// details.
|
|
|
|
import (
|
|
"tinygo.org/x/bluetooth"
|
|
"tinygo.org/x/bluetooth/rawterm"
|
|
)
|
|
|
|
var (
|
|
serviceUUID = bluetooth.NewUUID([16]byte{0x6E, 0x40, 0x00, 0x01, 0xB5, 0xA3, 0xF3, 0x93, 0xE0, 0xA9, 0xE5, 0x0E, 0x24, 0xDC, 0xCA, 0x9E})
|
|
rxUUID = bluetooth.NewUUID([16]byte{0x6E, 0x40, 0x00, 0x02, 0xB5, 0xA3, 0xF3, 0x93, 0xE0, 0xA9, 0xE5, 0x0E, 0x24, 0xDC, 0xCA, 0x9E})
|
|
txUUID = bluetooth.NewUUID([16]byte{0x6E, 0x40, 0x00, 0x03, 0xB5, 0xA3, 0xF3, 0x93, 0xE0, 0xA9, 0xE5, 0x0E, 0x24, 0xDC, 0xCA, 0x9E})
|
|
)
|
|
|
|
var adapter = bluetooth.DefaultAdapter
|
|
|
|
func main() {
|
|
// Enable BLE interface.
|
|
err := adapter.Enable()
|
|
if err != nil {
|
|
println("could not enable the BLE stack:", err.Error())
|
|
return
|
|
}
|
|
|
|
// The address to connect to. Set during scanning and read afterwards.
|
|
var foundDevice bluetooth.ScanResult
|
|
|
|
// Scan for NUS peripheral.
|
|
println("Scanning...")
|
|
err = adapter.Scan(func(adapter *bluetooth.Adapter, result bluetooth.ScanResult) {
|
|
if !result.AdvertisementPayload.HasServiceUUID(serviceUUID) {
|
|
return
|
|
}
|
|
foundDevice = result
|
|
|
|
// 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 err != nil {
|
|
println("could not start a scan:", err.Error())
|
|
return
|
|
}
|
|
|
|
// Found a device: print this event.
|
|
if name := foundDevice.LocalName(); name == "" {
|
|
print("Connecting to ", foundDevice.Address.String(), "...")
|
|
println()
|
|
} else {
|
|
print("Connecting to ", name, " (", foundDevice.Address.String(), ")...")
|
|
println()
|
|
}
|
|
|
|
// Found a NUS peripheral. Connect to it.
|
|
device, err := adapter.Connect(foundDevice.Address, bluetooth.ConnectionParams{})
|
|
if err != nil {
|
|
println("Failed to connect:", err.Error())
|
|
return
|
|
}
|
|
|
|
// Connected. Look up the Nordic UART Service.
|
|
println("Discovering service...")
|
|
services, err := device.DiscoverServices([]bluetooth.UUID{serviceUUID})
|
|
if err != nil {
|
|
println("Failed to discover the Nordic UART Service:", err.Error())
|
|
return
|
|
}
|
|
service := services[0]
|
|
|
|
// Get the two characteristics present in this service.
|
|
chars, err := service.DiscoverCharacteristics([]bluetooth.UUID{rxUUID, txUUID})
|
|
if err != nil {
|
|
println("Failed to discover RX and TX characteristics:", err.Error())
|
|
return
|
|
}
|
|
rx := chars[0]
|
|
tx := chars[1]
|
|
|
|
// Enable notifications to receive incoming data.
|
|
err = tx.EnableNotifications(func(value []byte) {
|
|
for _, c := range value {
|
|
rawterm.Putchar(c)
|
|
}
|
|
})
|
|
if err != nil {
|
|
println("Failed to enable TX notifications:", err.Error())
|
|
return
|
|
}
|
|
|
|
println("Connected. Exit console using Ctrl-X.")
|
|
rawterm.Configure()
|
|
defer rawterm.Restore()
|
|
var line []byte
|
|
for {
|
|
ch := rawterm.Getchar()
|
|
line = append(line, ch)
|
|
|
|
// Send the current line to the central.
|
|
if ch == '\x18' {
|
|
// The user pressed Ctrl-X, exit the program.
|
|
break
|
|
} else if ch == '\n' {
|
|
sendbuf := line // copy buffer
|
|
// Reset the slice while keeping the buffer in place.
|
|
line = line[:0]
|
|
|
|
// Send the sendbuf after breaking it up in pieces.
|
|
for len(sendbuf) != 0 {
|
|
// Chop off up to 20 bytes from the sendbuf.
|
|
partlen := 20
|
|
if len(sendbuf) < 20 {
|
|
partlen = len(sendbuf)
|
|
}
|
|
part := sendbuf[:partlen]
|
|
sendbuf = sendbuf[partlen:]
|
|
// This performs a "write command" aka "write without response".
|
|
_, err := rx.WriteWithoutResponse(part)
|
|
if err != nil {
|
|
println("could not send:", err.Error())
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|