prototooth/examples/nusclient/main.go

130 regels
3.5 KiB
Go

package main
// This example implements a NUS (Nordic UART Service) client. See nusserver for
// details.
import (
"github.com/tinygo-org/bluetooth"
"github.com/tinygo-org/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())
}
}
}
}
}