1
0
mirror of https://github.com/hybridgroup/gobot.git synced 2025-04-26 13:48:49 +08:00
hybridgroup.gobot/drivers/ble/serial_port.go

85 lines
1.9 KiB
Go

package ble
import (
"sync"
"gobot.io/x/gobot/v2"
)
// SerialPortDriver is a implementation of serial over Bluetooth LE
// Inspired by https://github.com/monteslu/ble-serial by @monteslu
type SerialPortDriver struct {
*Driver
rid string
tid string
// buffer of responseData and mutex to protect it
responseData []byte
responseMutex sync.Mutex
}
// NewSerialPortDriver returns a new serial over Bluetooth LE connection
func NewSerialPortDriver(a gobot.BLEConnector, rid string, tid string, opts ...OptionApplier) *SerialPortDriver {
d := &SerialPortDriver{
Driver: NewDriver(a, "BleSerial", nil, nil, opts...),
rid: rid,
tid: tid,
}
return d
}
// Open opens a connection to a BLE serial device
func (p *SerialPortDriver) Open() error {
if err := p.Adaptor().Connect(); err != nil {
return err
}
// subscribe to response notifications
return p.Adaptor().Subscribe(p.rid, func(data []byte) {
p.responseMutex.Lock()
defer p.responseMutex.Unlock()
p.responseData = append(p.responseData, data...)
})
}
// Read reads bytes from BLE serial port connection
func (p *SerialPortDriver) Read(b []byte) (int, error) {
p.responseMutex.Lock()
defer p.responseMutex.Unlock()
if len(p.responseData) == 0 {
return 0, nil
}
n := len(b)
if len(p.responseData) < n {
n = len(p.responseData)
}
copy(b, p.responseData[:n])
if len(p.responseData) > n {
p.responseData = p.responseData[n:]
} else {
p.responseData = nil
}
return n, nil
}
// Write writes to the BLE serial port connection
func (p *SerialPortDriver) Write(b []byte) (int, error) {
err := p.Adaptor().WriteCharacteristic(p.tid, b)
n := len(b)
return n, err
}
// Close closes the BLE serial port connection
func (p *SerialPortDriver) Close() error {
return p.Adaptor().Disconnect()
}
// Address returns the BLE address
func (p *SerialPortDriver) Address() string {
return p.Adaptor().Address()
}