mirror of
https://github.com/hybridgroup/gobot.git
synced 2025-04-26 13:48:49 +08:00
85 lines
1.9 KiB
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()
|
|
}
|