gobot.io/x/gobot/v2@v2.1.0/platforms/ble/serial_port.go (about)

     1  package ble
     2  
     3  import "sync"
     4  
     5  // SerialPort is a implementation of serial over Bluetooth LE
     6  // Inspired by https://github.com/monteslu/ble-serial by @monteslu
     7  type SerialPort struct {
     8  	address string
     9  	rid     string
    10  	tid     string
    11  	client  *ClientAdaptor
    12  
    13  	// buffer of responseData and mutex to protect it
    14  	responseData  []byte
    15  	responseMutex sync.Mutex
    16  }
    17  
    18  // NewSerialPort returns a new serial over Bluetooth LE connection
    19  func NewSerialPort(address string, rid string, tid string) *SerialPort {
    20  	return &SerialPort{address: address, rid: rid, tid: tid}
    21  }
    22  
    23  // Open opens a connection to a BLE serial device
    24  func (p *SerialPort) Open() (err error) {
    25  	p.client = NewClientAdaptor(p.address)
    26  
    27  	err = p.client.Connect()
    28  
    29  	// subscribe to response notifications
    30  	p.client.Subscribe(p.rid, func(data []byte, e error) {
    31  		p.responseMutex.Lock()
    32  		p.responseData = append(p.responseData, data...)
    33  		p.responseMutex.Unlock()
    34  	})
    35  	return
    36  }
    37  
    38  // Read reads bytes from BLE serial port connection
    39  func (p *SerialPort) Read(b []byte) (n int, err error) {
    40  	if len(p.responseData) == 0 {
    41  		return
    42  	}
    43  
    44  	p.responseMutex.Lock()
    45  	n = len(b)
    46  	if len(p.responseData) < n {
    47  		n = len(p.responseData)
    48  	}
    49  	copy(b, p.responseData[:n])
    50  
    51  	if len(p.responseData) > n {
    52  		p.responseData = p.responseData[n:]
    53  	} else {
    54  		p.responseData = nil
    55  	}
    56  	p.responseMutex.Unlock()
    57  
    58  	return
    59  }
    60  
    61  // Write writes to the BLE serial port connection
    62  func (p *SerialPort) Write(b []byte) (n int, err error) {
    63  	err = p.client.WriteCharacteristic(p.tid, b)
    64  	n = len(b)
    65  	return
    66  }
    67  
    68  // Close closes the BLE serial port connection
    69  func (p *SerialPort) Close() (err error) {
    70  	p.client.Disconnect()
    71  	return
    72  }
    73  
    74  // Address returns the BLE address
    75  func (p *SerialPort) Address() string {
    76  	return p.address
    77  }