Documentation
¶
Overview ¶
Package gatt provides a Bluetooth Low Energy gatt implementation.
Gatt (Generic Attribute Profile) is the protocol used to write BLE peripherals (servers) and centrals (clients).
STATUS ¶
This package is a work in progress. The API will change.
As a peripheral, you can create services, characteristics, and descriptors, advertise, accept connections, and handle requests. As a central, you can scan, connect, discover services, and make requests.
SETUP ¶
gatt supports both Linux and OS X.
On Linux: To gain complete and exclusive control of the HCI device, gatt uses HCI_CHANNEL_USER (introduced in Linux v3.14) instead of HCI_CHANNEL_RAW. Those who must use an older kernel may patch in these relevant commits from Marcel Holtmann:
Bluetooth: Introduce new HCI socket channel for user operation Bluetooth: Introduce user channel flag for HCI devices Bluetooth: Refactor raw socket filter into more readable code
Note that because gatt uses HCI_CHANNEL_USER, once gatt has opened the device no other program may access it.
Before starting a gatt program, make sure that your BLE device is down:
sudo hciconfig sudo hciconfig hci0 down # or whatever hci device you want to use
If you have BlueZ 5.14+ (or aren't sure), stop the built-in bluetooth server, which interferes with gatt, e.g.:
sudo service bluetooth stop
Because gatt programs administer network devices, they must either be run as root, or be granted appropriate capabilities:
sudo <executable> # OR sudo setcap 'cap_net_raw,cap_net_admin=eip' <executable> <executable>
USAGE
# Start a simple server. sudo go run example/server.go # Discover surrounding peripherals. sudo go run example/discoverer.go # Connect to and explorer a peripheral device. sudo go run example/explorer.go <peripheral ID>
See the server.go, discoverer.go, and explorer.go in the examples/ directory for writing server or client programs that run on Linux and OS X.
Users, especially on Linux platforms, seeking finer-grained control over the devices can see the examples/server_lnx.go for the usage of Option, which are platform specific.
See the rest of the docs for other options and finer-grained control.
Note that some BLE central devices, particularly iOS, may aggressively cache results from previous connections. If you change your services or characteristics, you may need to reboot the other device to pick up the changes. This is a common source of confusion and apparent bugs. For an OS X central, see http://stackoverflow.com/questions/20553957.
REFERENCES ¶
gatt started life as a port of bleno, to which it is indebted: https://github.com/sandeepmistry/bleno. If you are having problems with gatt, particularly around installation, issues filed with bleno might also be helpful references.
To try out your GATT server, it is useful to experiment with a generic BLE client. LightBlue is a good choice. It is available free for both iOS and OS X.
Index ¶
- Constants
- Variables
- func NewResponseWriter(capacity int) *responseWriter
- func NewSimDeviceClient(service *Service, advertisedName string) *simDevice
- func UUIDContains(s []UUID, u UUID) bool
- type AdvPacket
- func (a *AdvPacket) AppendField(typ byte, b []byte) *AdvPacket
- func (a *AdvPacket) AppendFlags(f byte) *AdvPacket
- func (a *AdvPacket) AppendManufacturerData(id uint16, b []byte) *AdvPacket
- func (a *AdvPacket) AppendName(n string) *AdvPacket
- func (a *AdvPacket) AppendUUIDFit(uu []UUID) bool
- func (a *AdvPacket) Bytes() [31]byte
- func (a *AdvPacket) Len() int
- type Advertisement
- type AttrECode
- type Central
- type Characteristic
- func (c *Characteristic) AddDescriptor(u UUID) *Descriptor
- func (c *Characteristic) Descriptor() *Descriptor
- func (c *Characteristic) Descriptors() []*Descriptor
- func (c *Characteristic) EndHandle() uint16
- func (c *Characteristic) GetNotifyHandler() NotifyHandler
- func (c *Characteristic) GetReadHandler() ReadHandler
- func (c *Characteristic) GetWriteHandler() WriteHandler
- func (c *Characteristic) Handle() uint16
- func (c *Characteristic) HandleNotify(h NotifyHandler)
- func (c *Characteristic) HandleNotifyFunc(f func(ctx context.Context, r Request, n Notifier))
- func (c *Characteristic) HandleRead(h ReadHandler)
- func (c *Characteristic) HandleReadFunc(f func(ctx context.Context, resp ResponseWriter, req *ReadRequest))
- func (c *Characteristic) HandleWrite(h WriteHandler)
- func (c *Characteristic) HandleWriteFunc(f func(ctx context.Context, r Request, data []byte) (status byte))
- func (c *Characteristic) Name() string
- func (c *Characteristic) Properties() Property
- func (c *Characteristic) Service() *Service
- func (c *Characteristic) SetDescriptor(cccd *Descriptor)
- func (c *Characteristic) SetDescriptors(descs []*Descriptor)
- func (c *Characteristic) SetEndHandle(endh uint16)
- func (c *Characteristic) SetHandle(h uint16)
- func (c *Characteristic) SetVHandle(vh uint16)
- func (c *Characteristic) SetValue(b []byte)
- func (c *Characteristic) UUID() UUID
- func (c *Characteristic) VHandle() uint16
- type Descriptor
- func (d *Descriptor) Characteristic() *Characteristic
- func (d *Descriptor) Handle() uint16
- func (d *Descriptor) HandleRead(h ReadHandler)
- func (d *Descriptor) HandleReadFunc(f func(ctx context.Context, resp ResponseWriter, req *ReadRequest))
- func (d *Descriptor) HandleWrite(h WriteHandler)
- func (d *Descriptor) HandleWriteFunc(f func(ctx context.Context, r Request, data []byte) (status byte))
- func (d *Descriptor) Name() string
- func (d *Descriptor) SetHandle(h uint16)
- func (d *Descriptor) SetStringValue(s string)
- func (d *Descriptor) SetValue(b []byte)
- func (d *Descriptor) UUID() UUID
- type Device
- type DeviceHandler
- func (h *DeviceHandler) CentralConnected() func(context.Context, Central)
- func (h *DeviceHandler) CentralDisconnected() func(context.Context, Central)
- func (h *DeviceHandler) PeripheralConnected() func(context.Context, Peripheral, error)
- func (h *DeviceHandler) PeripheralDisconnected() func(context.Context, Peripheral, error)
- func (h *DeviceHandler) PeripheralDiscovered() func(context.Context, Peripheral, *Advertisement, int)
- func (h *DeviceHandler) SetCentralConnected(f func(context.Context, Central))
- func (h *DeviceHandler) SetCentralDisconnected(f func(context.Context, Central))
- func (h *DeviceHandler) SetPeripheralConnected(f func(context.Context, Peripheral, error))
- func (h *DeviceHandler) SetPeripheralDisconnected(f func(context.Context, Peripheral, error))
- func (h *DeviceHandler) SetPeripheralDiscovered(f func(context.Context, Peripheral, *Advertisement, int))
- func (h *DeviceHandler) SetStateChanged(f func(context.Context, Device, State))
- func (h *DeviceHandler) StateChanged() func(context.Context, Device, State)
- type Flags
- type Handler
- func CentralConnected(f func(context.Context, Central)) Handler
- func CentralDisconnected(f func(context.Context, Central)) Handler
- func PeripheralConnected(f func(context.Context, Peripheral, error)) Handler
- func PeripheralDisconnected(f func(context.Context, Peripheral, error)) Handler
- func PeripheralDiscovered(f func(context.Context, Peripheral, *Advertisement, int)) Handler
- type Notifier
- type NotifyHandler
- type NotifyHandlerFunc
- type Option
- func LnxDeviceID(n int, chk bool) Option
- func LnxMaxConnections(n int) Option
- func LnxSendHCIRawCommand(ctx context.Context, c cmd.CmdParam, resp io.Writer) Option
- func LnxSetAdvertisingData(c *cmd.LESetAdvertisingData) Option
- func LnxSetAdvertisingEnable(ctx context.Context, en bool) Option
- func LnxSetAdvertisingParameters(c *cmd.LESetAdvertisingParameters) Option
- func LnxSetScanResponseData(c *cmd.LESetScanResponseData) Option
- func LnxSetScanningParameters(c *cmd.LESetScanParameters) Option
- type Peripheral
- type Property
- type ReadHandler
- type ReadHandlerFunc
- type ReadRequest
- type Request
- type ResponseWriter
- type Service
- func (s *Service) AddCharacteristic(u UUID) *Characteristic
- func (s *Service) Characteristics() []*Characteristic
- func (s *Service) EndHandle() uint16
- func (s *Service) Handle() uint16
- func (s *Service) Name() string
- func (s *Service) SetCharacteristics(chars []*Characteristic)
- func (s *Service) SetEndHandle(endh uint16)
- func (s *Service) SetHandle(h uint16)
- func (s *Service) UUID() UUID
- type ServiceData
- type State
- type UUID
- type WriteHandler
- type WriteHandlerFunc
Examples ¶
Constants ¶
const ( StatusSuccess = 0 StatusInvalidOffset = 1 StatusUnexpectedError = 2 )
Supported statuses for GATT characteristic read/write operations. These correspond to att constants in the BLE spec
const (
DefaultMTU = 1024
)
const MaxEIRPacketLength = 31
MaxEIRPacketLength is the maximum allowed AdvertisingPacket and ScanResponsePacket length.
Variables ¶
var AttrECodeName = map[AttrECode]string{ AttrECodeSuccess: "success", AttrECodeInvalidHandle: "invalid handle", AttrECodeReadNotPerm: "read not permitted", AttrECodeWriteNotPerm: "write not permitted", AttrECodeInvalidPDU: "invalid PDU", AttrECodeAuthentication: "insufficient authentication", AttrECodeReqNotSupp: "request not supported", AttrECodeInvalidOffset: "invalid offset", AttrECodeAuthorization: "insufficient authorization", AttrECodePrepQueueFull: "prepare queue full", AttrECodeAttrNotFound: "attribute not found", AttrECodeAttrNotLong: "attribute not long", AttrECodeInsuffEncrKeySize: "insufficient encryption key size", AttrECodeInvalAttrValueLen: "invalid attribute value length", AttrECodeUnlikely: "unlikely error", AttrECodeInsuffEnc: "insufficient encryption", AttrECodeUnsuppGrpType: "unsupported group type", AttrECodeInsuffResources: "insufficient resources", }
var CompanyIdents = map[uint16]string{}/* 2302 elements not displayed */
ref. https://www.bluetooth.com/specifications/assigned-numbers/company-identifiers
var ErrEIRPacketTooLong = errors.New("max packet length is 31")
ErrEIRPacketTooLong is the error returned when an AdvertisingPacket or ScanResponsePacket is too long.
var (
ErrInvalidLength = errors.New("invalid length")
)
var ErrMethodNotSupported = errors.New("method not supported")
Functions ¶
func NewResponseWriter ¶
func NewResponseWriter(capacity int) *responseWriter
NewResponseWriter creates a ResponseWriter with the given capacity. Exported for use by external backend packages (e.g. android/jni).
func NewSimDeviceClient ¶
func UUIDContains ¶
UUIDContains returns a boolean reporting whether u is in the slice s.
Types ¶
type AdvPacket ¶
type AdvPacket struct {
// contains filtered or unexported fields
}
AdvPacket is an utility to help crafting advertisment or scan response data.
func (*AdvPacket) AppendField ¶
AppendField appends a BLE advertising packet field. TODO: refuse to append field if it'd make the packet too long.
func (*AdvPacket) AppendFlags ¶
AppendFlags appends a flag field to the packet.
func (*AdvPacket) AppendManufacturerData ¶
AppendManufacturerData appends a manufacturer data field to the packet.
func (*AdvPacket) AppendName ¶
AppendFlags appends a name field to the packet. If the name fits in the space, it will be append as a complete name field, otherwise a short name field.
func (*AdvPacket) AppendUUIDFit ¶
AppendUUIDFit appends a BLE advertised service UUID packet field if it fits in the packet, and reports whether the UUID fit.
type Advertisement ¶
type Advertisement struct {
LocalName string
Flags Flags
CompanyID uint16
Company string
ManufacturerData []byte
ServiceData []ServiceData
Services []UUID
OverflowService []UUID
TxPowerLevel int
Connectable bool
SolicitedService []UUID
Raw []byte
}
This is borrowed from core bluetooth. Embedded/Linux folks might be interested in more details.
type AttrECode ¶
type AttrECode byte
const ( AttrECodeSuccess AttrECode = 0x00 // Success AttrECodeInvalidHandle AttrECode = 0x01 // The attribute handle given was not valid on this server. AttrECodeReadNotPerm AttrECode = 0x02 // The attribute cannot be read. AttrECodeWriteNotPerm AttrECode = 0x03 // The attribute cannot be written. AttrECodeInvalidPDU AttrECode = 0x04 // The attribute PDU was invalid. AttrECodeAuthentication AttrECode = 0x05 // The attribute requires authentication before it can be read or written. AttrECodeReqNotSupp AttrECode = 0x06 // Attribute server does not support the request received from the client. AttrECodeInvalidOffset AttrECode = 0x07 // Offset specified was past the end of the attribute. AttrECodeAuthorization AttrECode = 0x08 // The attribute requires authorization before it can be read or written. AttrECodePrepQueueFull AttrECode = 0x09 // Too many prepare writes have been queued. AttrECodeAttrNotFound AttrECode = 0x0a // No attribute found within the given attribute handle range. AttrECodeAttrNotLong AttrECode = 0x0b // The attribute cannot be read or written using the Read Blob Request. AttrECodeInsuffEncrKeySize AttrECode = 0x0c // The Encryption Key Size used for encrypting this link is insufficient. AttrECodeInvalAttrValueLen AttrECode = 0x0d // The attribute value length is invalid for the operation. AttrECodeUnlikely AttrECode = 0x0e // The attribute request that was requested has encountered an error that was unlikely, and therefore could not be completed as requested. AttrECodeInsuffEnc AttrECode = 0x0f // The attribute requires encryption before it can be read or written. AttrECodeUnsuppGrpType AttrECode = 0x10 // The attribute type is not a supported grouping attribute as defined by a higher layer specification. AttrECodeInsuffResources AttrECode = 0x11 // Insufficient Resources to complete the request. )
type Central ¶
type Central interface {
ID() string // ID returns platform specific ID of the remote central device.
Close() error // Close disconnects the connection.
MTU() int // MTU returns the current connection mtu.
}
Central is the interface that represent a remote central device.
type Characteristic ¶
type Characteristic struct {
// contains filtered or unexported fields
}
A Characteristic is a BLE characteristic.
func NewCharacteristic ¶
NewCharacteristic creates and returns a Characteristic.
func (*Characteristic) AddDescriptor ¶
func (c *Characteristic) AddDescriptor(u UUID) *Descriptor
AddDescriptor adds a descriptor to a characteristic. AddDescriptor panics if the characteristic already contains another descriptor with the same UUID.
func (*Characteristic) Descriptor ¶
func (c *Characteristic) Descriptor() *Descriptor
Descriptor returns the Descriptor of the characteristic.
func (*Characteristic) Descriptors ¶
func (c *Characteristic) Descriptors() []*Descriptor
Descriptors returns the contained descriptors of this characteristic.
func (*Characteristic) EndHandle ¶
func (c *Characteristic) EndHandle() uint16
EndHandle returns the End Handle of the characteristic.
func (*Characteristic) GetNotifyHandler ¶
func (c *Characteristic) GetNotifyHandler() NotifyHandler
func (*Characteristic) GetReadHandler ¶
func (c *Characteristic) GetReadHandler() ReadHandler
func (*Characteristic) GetWriteHandler ¶
func (c *Characteristic) GetWriteHandler() WriteHandler
func (*Characteristic) Handle ¶
func (c *Characteristic) Handle() uint16
Handle returns the Handle of the characteristic.
func (*Characteristic) HandleNotify ¶
func (c *Characteristic) HandleNotify(h NotifyHandler)
HandleNotify makes the characteristic support notify requests, and routes notification requests to h. HandleNotify must be called before the containing service is added to a server.
func (*Characteristic) HandleNotifyFunc ¶
func (c *Characteristic) HandleNotifyFunc(f func(ctx context.Context, r Request, n Notifier))
HandleNotifyFunc calls HandleNotify(NotifyHandlerFunc(f)).
func (*Characteristic) HandleRead ¶
func (c *Characteristic) HandleRead(h ReadHandler)
HandleRead makes the characteristic support read requests, and routes read requests to h. HandleRead must be called before the containing service is added to a server. HandleRead panics if the characteristic has been configured with a static value.
func (*Characteristic) HandleReadFunc ¶
func (c *Characteristic) HandleReadFunc(f func(ctx context.Context, resp ResponseWriter, req *ReadRequest))
HandleReadFunc calls HandleRead(ReadHandlerFunc(f)).
func (*Characteristic) HandleWrite ¶
func (c *Characteristic) HandleWrite(h WriteHandler)
HandleWrite makes the characteristic support write and write-no-response requests, and routes write requests to h. The WriteHandler does not differentiate between write and write-no-response requests; it is handled automatically. HandleWrite must be called before the containing service is added to a server.
func (*Characteristic) HandleWriteFunc ¶
func (c *Characteristic) HandleWriteFunc(f func(ctx context.Context, r Request, data []byte) (status byte))
HandleWriteFunc calls HandleWrite(WriteHandlerFunc(f)).
func (*Characteristic) Name ¶
func (c *Characteristic) Name() string
Name returns the specified name of the characteristic. If the UUID is not assigned, Name returns empty string.
func (*Characteristic) Properties ¶
func (c *Characteristic) Properties() Property
Properties returns the properties of this characteristic.
func (*Characteristic) Service ¶
func (c *Characteristic) Service() *Service
Service returns the containing service of this characteristic.
func (*Characteristic) SetDescriptor ¶
func (c *Characteristic) SetDescriptor(cccd *Descriptor)
SetDescriptor sets the Descriptor of the characteristic.
func (*Characteristic) SetDescriptors ¶
func (c *Characteristic) SetDescriptors(descs []*Descriptor)
SetDescriptors sets the list of Descriptor of the characteristic.
func (*Characteristic) SetEndHandle ¶
func (c *Characteristic) SetEndHandle(endh uint16)
SetEndHandle sets the End Handle of the characteristic.
func (*Characteristic) SetHandle ¶
func (c *Characteristic) SetHandle(h uint16)
SetHandle sets the Handle of the characteristic.
func (*Characteristic) SetVHandle ¶
func (c *Characteristic) SetVHandle(vh uint16)
SetVHandle sets the Value Handle of the characteristic.
func (*Characteristic) SetValue ¶
func (c *Characteristic) SetValue(b []byte)
SetValue makes the characteristic support read requests, and returns a static value. SetValue must be called before the containing service is added to a server. SetValue panics if the characteristic has been configured with a ReadHandler.
func (*Characteristic) UUID ¶
func (c *Characteristic) UUID() UUID
UUID returns the UUID of the characteristic.
func (*Characteristic) VHandle ¶
func (c *Characteristic) VHandle() uint16
VHandle returns the Value Handle of the characteristic.
type Descriptor ¶
type Descriptor struct {
// contains filtered or unexported fields
}
Descriptor is a BLE descriptor
func NewDescriptor ¶
func NewDescriptor(u UUID, h uint16, char *Characteristic) *Descriptor
NewDescriptor creates and returns a Descriptor.
func (*Descriptor) Characteristic ¶
func (d *Descriptor) Characteristic() *Characteristic
Characteristic returns the containing characteristic of the descriptor.
func (*Descriptor) Handle ¶
func (d *Descriptor) Handle() uint16
Handle returns the Handle of the descriptor.
func (*Descriptor) HandleRead ¶
func (d *Descriptor) HandleRead(h ReadHandler)
HandleRead makes the descriptor support read requests, and routes read requests to h. HandleRead must be called before the containing service is added to a server. HandleRead panics if the descriptor has been configured with a static value.
func (*Descriptor) HandleReadFunc ¶
func (d *Descriptor) HandleReadFunc(f func(ctx context.Context, resp ResponseWriter, req *ReadRequest))
HandleReadFunc calls HandleRead(ReadHandlerFunc(f)).
func (*Descriptor) HandleWrite ¶
func (d *Descriptor) HandleWrite(h WriteHandler)
HandleWrite makes the descriptor support write and write-no-response requests, and routes write requests to h. The WriteHandler does not differentiate between write and write-no-response requests; it is handled automatically. HandleWrite must be called before the containing service is added to a server.
func (*Descriptor) HandleWriteFunc ¶
func (d *Descriptor) HandleWriteFunc(f func(ctx context.Context, r Request, data []byte) (status byte))
HandleWriteFunc calls HandleWrite(WriteHandlerFunc(f)).
func (*Descriptor) Name ¶
func (d *Descriptor) Name() string
Name returns the specified name of the descriptor. If the UUID is not assigned, returns an empty string.
func (*Descriptor) SetHandle ¶
func (d *Descriptor) SetHandle(h uint16)
SetHandle sets the Handle of the descriptor.
func (*Descriptor) SetStringValue ¶
func (d *Descriptor) SetStringValue(s string)
SetStringValue makes the descriptor support read requests, and returns a static value. SetStringValue must be called before the containing service is added to a server. SetStringValue panics if the descriptor has already configured with a ReadHandler.
func (*Descriptor) SetValue ¶
func (d *Descriptor) SetValue(b []byte)
SetValue makes the descriptor support read requests, and returns a static value. SetValue must be called before the containing service is added to a server. SetValue panics if the descriptor has already configured with a ReadHandler.
type Device ¶
type Device interface {
ID() int
Start(ctx context.Context, stateChanged func(context.Context, Device, State)) error
// Stop calls OS specific close calls
Stop() error
// Advertise advertise AdvPacket
Advertise(ctx context.Context, a *AdvPacket) error
// AdvertiseNameAndServices advertises device name, and specified service UUIDs.
// It tres to fit the UUIDs in the advertising packet as much as possible.
// If name doesn't fit in the advertising packet, it will be put in scan response.
AdvertiseNameAndServices(ctx context.Context, name string, ss []UUID) error
AdvertiseNameAndIBeaconData(ctx context.Context, name string, b []byte) error
// AdvertiseIBeaconData advertise iBeacon with given manufacturer data.
AdvertiseIBeaconData(ctx context.Context, b []byte) error
// AdvertisingIBeacon advertises iBeacon with specified parameters.
AdvertiseIBeacon(ctx context.Context, u UUID, major, minor uint16, pwr int8) error
// StopAdvertising stops advertising.
StopAdvertising(ctx context.Context) error
// RemoveAllServices removes all services that are currently in the database.
RemoveAllServices(ctx context.Context) error
// Add Service add a service to database.
AddService(ctx context.Context, s *Service) error
// SetServices set the specified service to the database.
// It removes all currently added services, if any.
SetServices(ctx context.Context, ss []*Service) error
// Scan discovers surrounding remote peripherals that have the Service UUID specified in ss.
// If ss is set to nil, all devices scanned are reported.
// dup specifies weather duplicated advertisement should be reported or not.
// When a remote peripheral is discovered, the PeripheralDiscovered Handler is called.
Scan(ctx context.Context, ss []UUID, dup bool) error
// StopScanning stops scanning.
StopScanning() error
// Connect connects to a remote peripheral.
Connect(ctx context.Context, p Peripheral)
// CancelConnection disconnects a remote peripheral.
CancelConnection(ctx context.Context, p Peripheral)
// Handle registers the specified handlers.
Handle(ctx context.Context, h ...Handler)
// Option sets the options specified.
Option(o ...Option) error
}
Device defines the interface for a BLE device. Since an interface can't define fields(properties). To implement the callback support for certain events, deviceHandler is defined and implementation of Device on different platforms should embed it in order to keep have keep compatible in API level. Package users can use the Handler to set these handlers.
type DeviceHandler ¶
type DeviceHandler struct {
// contains filtered or unexported fields
}
DeviceHandler provides exported access to device callbacks for external backend packages. External packages (e.g. android backends in separate modules) can embed DeviceHandler in their device types to satisfy the deviceHandlerProvider interface.
func (*DeviceHandler) CentralConnected ¶
func (h *DeviceHandler) CentralConnected() func(context.Context, Central)
CentralConnected returns the current central-connected callback, or nil if not set.
func (*DeviceHandler) CentralDisconnected ¶
func (h *DeviceHandler) CentralDisconnected() func(context.Context, Central)
CentralDisconnected returns the current central-disconnected callback, or nil if not set.
func (*DeviceHandler) PeripheralConnected ¶
func (h *DeviceHandler) PeripheralConnected() func(context.Context, Peripheral, error)
PeripheralConnected returns the current peripheral-connected callback, or nil if not set.
func (*DeviceHandler) PeripheralDisconnected ¶
func (h *DeviceHandler) PeripheralDisconnected() func(context.Context, Peripheral, error)
PeripheralDisconnected returns the current peripheral-disconnected callback, or nil if not set.
func (*DeviceHandler) PeripheralDiscovered ¶
func (h *DeviceHandler) PeripheralDiscovered() func(context.Context, Peripheral, *Advertisement, int)
PeripheralDiscovered returns the current peripheral-discovered callback, or nil if not set.
func (*DeviceHandler) SetCentralConnected ¶
func (h *DeviceHandler) SetCentralConnected(f func(context.Context, Central))
SetCentralConnected sets the central-connected callback.
func (*DeviceHandler) SetCentralDisconnected ¶
func (h *DeviceHandler) SetCentralDisconnected(f func(context.Context, Central))
SetCentralDisconnected sets the central-disconnected callback.
func (*DeviceHandler) SetPeripheralConnected ¶
func (h *DeviceHandler) SetPeripheralConnected(f func(context.Context, Peripheral, error))
SetPeripheralConnected sets the peripheral-connected callback.
func (*DeviceHandler) SetPeripheralDisconnected ¶
func (h *DeviceHandler) SetPeripheralDisconnected(f func(context.Context, Peripheral, error))
SetPeripheralDisconnected sets the peripheral-disconnected callback.
func (*DeviceHandler) SetPeripheralDiscovered ¶
func (h *DeviceHandler) SetPeripheralDiscovered(f func(context.Context, Peripheral, *Advertisement, int))
SetPeripheralDiscovered sets the peripheral-discovered callback.
func (*DeviceHandler) SetStateChanged ¶
func (h *DeviceHandler) SetStateChanged(f func(context.Context, Device, State))
SetStateChanged sets the state-changed callback.
func (*DeviceHandler) StateChanged ¶
func (h *DeviceHandler) StateChanged() func(context.Context, Device, State)
StateChanged returns the current state-changed callback, or nil if not set.
type Handler ¶
A Handler is a self-referential function, which registers the options specified. See http://commandcenter.blogspot.com.au/2014/01/self-referential-functions-and-design.html for more discussion.
func CentralConnected ¶
CentralConnected returns a Handler, which sets the specified function to be called when a device connects to the server.
func CentralDisconnected ¶
CentralDisconnected returns a Handler, which sets the specified function to be called when a device disconnects from the server.
func PeripheralConnected ¶
func PeripheralConnected(f func(context.Context, Peripheral, error)) Handler
PeripheralConnected returns a Handler, which sets the specified function to be called when a remote peripheral device connects.
func PeripheralDisconnected ¶
func PeripheralDisconnected(f func(context.Context, Peripheral, error)) Handler
PeripheralDisconnected returns a Handler, which sets the specified function to be called when a remote peripheral device disconnects.
func PeripheralDiscovered ¶
func PeripheralDiscovered(f func(context.Context, Peripheral, *Advertisement, int)) Handler
PeripheralDiscovered returns a Handler, which sets the specified function to be called when a remote peripheral device is found during scan procedure.
type Notifier ¶
type Notifier interface {
// Write sends data to the central.
Write(data []byte) (int, error)
// Done reports whether the central has requested not to
// receive any more notifications with this notifier.
Done() bool
// Cap returns the maximum number of bytes that may be sent
// in a single notification.
Cap() int
}
A Notifier provides a means for a GATT server to send notifications about value changes to a connected device. Notifiers are provided by NotifyHandlers.
type NotifyHandler ¶
A NotifyHandler handles GATT notification requests. Notifications can be sent using the provided notifier.
type NotifyHandlerFunc ¶
NotifyHandlerFunc is an adapter to allow the use of ordinary functions as NotifyHandlers. If f is a function with the appropriate signature, NotifyHandlerFunc(f) is a NotifyHandler that calls f.
func (NotifyHandlerFunc) ServeNotify ¶
func (f NotifyHandlerFunc) ServeNotify(ctx context.Context, r Request, n Notifier)
ServeNotify calls f(r, n).
type Option ¶
An Option is a self-referential function, which sets the option specified. Most Options are platform-specific, which gives more fine-grained control over the device at a cost of losing portability. See http://commandcenter.blogspot.com.au/2014/01/self-referential-functions-and-design.html for more discussion.
func LnxDeviceID ¶
LnxDeviceID specifies which HCI device to use. If n is set to -1, all the available HCI devices will be probed. If chk is set to true, LnxDeviceID checks the LE support in the feature list of the HCI device. This is to filter devices that does not support LE. In case some LE driver that doesn't correctly set the LE support in its feature list, user can turn off the check. This option can only be used with NewDevice on Linux implementation.
Example ¶
NewDevice(context.Background(), LnxDeviceID(-1, true)) // Can only be used with NewDevice.
func LnxMaxConnections ¶
LnxMaxConnections is an optional parameter. If set, it overrides the default max connections supported. This option can only be used with NewDevice on Linux implementation.
Example ¶
NewDevice(context.Background(), LnxMaxConnections(1)) // Can only be used with NewDevice.
func LnxSendHCIRawCommand ¶
LnxSendHCIRawCommand sends a raw command to the HCI device This option can be used with NewDevice or Option on Linux implementation.
Example (CustomCommand) ¶
ctx := context.Background()
// customCmd implements cmd.CmdParam as a fake vendor command.
//
// type customCmd struct{ ConnectionHandle uint16 }
//
// func (c customCmd) Opcode() int { return 0xFC01 }
// func (c customCmd) Len() int { return 3 }
// func (c customCmd) Marshal(b []byte) {
// []byte{
// byte(c.ConnectionHandle),
// byte(c.ConnectionHandle >> 8),
// 0xff,
// }
// }
// Send a custom vendor command without checking response.
c := &customCmd{ConnectionHandle: 0x40}
d, _ := NewDevice(context.Background())
d.Option(LnxSendHCIRawCommand(ctx, c, nil)) // Can only be used with Option
Example (PredefinedCommand) ¶
ctx := context.Background()
// Send a predefined command of cmd package.
c := &cmd.LESetScanResponseData{
ScanResponseDataLength: 8,
ScanResponseData: [31]byte{0x07, 0x09, 'G', 'o', 'p', 'h', 'e', 'r'},
}
resp := bytes.NewBuffer(nil)
d, _ := NewDevice(context.Background())
d.Option(LnxSendHCIRawCommand(ctx, c, resp)) // Can only be used with Option
// Check the return status
if resp.Bytes()[0] != 0x00 {
// Handle errors
}
func LnxSetAdvertisingData ¶
func LnxSetAdvertisingData(c *cmd.LESetAdvertisingData) Option
LnxSetAdvertisingData sets the advertising data to the HCI device. This option can be used with NewDevice or Option on Linux implementation.
Example ¶
// Manually crafting an advertising packet with a type field, and a service uuid - 0xFE01.
o := LnxSetAdvertisingData(&cmd.LESetAdvertisingData{
AdvertisingDataLength: 6,
AdvertisingData: [31]byte{0x02, 0x01, 0x06, 0x03, 0x01, 0xFE},
})
d, _ := NewDevice(context.Background(), o) // Can be used with NewDevice.
d.Option(o) // Or dynamically with Option.
func LnxSetAdvertisingEnable ¶
LnxSetAdvertisingEnable sets the advertising data to the HCI device. This option can be used with Option on Linux implementation.
Example ¶
ctx := context.Background() d, _ := NewDevice(context.Background()) d.Option(LnxSetAdvertisingEnable(ctx, true)) // Can only be used with Option.
func LnxSetAdvertisingParameters ¶
func LnxSetAdvertisingParameters(c *cmd.LESetAdvertisingParameters) Option
LnxSetAdvertisingParameters sets the advertising parameters to the HCI device. This option can be used with NewDevice or Option on Linux implementation.
Example ¶
o := LnxSetAdvertisingParameters(&cmd.LESetAdvertisingParameters{
AdvertisingIntervalMin: 0x800, // [0x0800]: 0.625 ms * 0x0800 = 1280.0 ms
AdvertisingIntervalMax: 0x800, // [0x0800]: 0.625 ms * 0x0800 = 1280.0 ms
AdvertisingType: 0x00, // [0x00]: ADV_IND, 0x01: DIRECT(HIGH), 0x02: SCAN, 0x03: NONCONN, 0x04: DIRECT(LOW)
OwnAddressType: 0x00, // [0x00]: public, 0x01: random
DirectAddressType: 0x00, // [0x00]: public, 0x01: random
DirectAddress: [6]byte{}, // Public or Random Address of the device to be connected
AdvertisingChannelMap: 0x7, // [0x07] 0x01: ch37, 0x02: ch38, 0x04: ch39
AdvertisingFilterPolicy: 0x00,
})
d, _ := NewDevice(context.Background(), o) // Can be used with NewDevice.
d.Option(o) // Or dynamically with Option.
func LnxSetScanResponseData ¶
func LnxSetScanResponseData(c *cmd.LESetScanResponseData) Option
LnxSetScanResponseData sets the scan response data to the HXI device. This option can be used with NewDevice or Option on Linux implementation.
Example ¶
// Manually crafting a scan response data packet with a name field.
o := LnxSetScanResponseData(&cmd.LESetScanResponseData{
ScanResponseDataLength: 8,
ScanResponseData: [31]byte{0x07, 0x09, 'G', 'o', 'p', 'h', 'e', 'r'},
})
d, _ := NewDevice(context.Background(), o)
d.Option(o)
func LnxSetScanningParameters ¶
func LnxSetScanningParameters(c *cmd.LESetScanParameters) Option
LnxSetScanningParameters sets the scanning parameters to the HCI device. This option can be used with NewDevice or Option on Linux implementation.
type Peripheral ¶
type Peripheral interface {
// Device returns the underlying device.
Device() Device
// ID is the platform specific unique ID of the remote peripheral, e.g. MAC for Linux, Peripheral UUID for MacOS.
ID() string
// Name returns the name of the remote peripheral.
// This can be the advertised name, if exists, or the GAP device name, which takes priority
Name() string
// Services returns the services of the remote peripheral which has been discovered.
Services(ctx context.Context) []*Service
// DiscoverServices discover the specified services of the remote peripheral.
// If the specified services is set to nil, all the available services of the remote peripheral are returned.
DiscoverServices(ctx context.Context, s []UUID) ([]*Service, error)
// DiscoverIncludedServices discovers the specified included services of a service.
// If the specified services is set to nil, all the included services of the service are returned.
DiscoverIncludedServices(ctx context.Context, ss []UUID, s *Service) ([]*Service, error)
// DiscoverCharacteristics discovers the specified characteristics of a service.
// If the specified characteristics is set to nil, all the characteristic of the service are returned.
DiscoverCharacteristics(ctx context.Context, c []UUID, s *Service) ([]*Characteristic, error)
// DiscoverDescriptors discovers the descriptors of a characteristic.
// If the specified descriptors is set to nil, all the descriptors of the characteristic are returned.
DiscoverDescriptors(ctx context.Context, d []UUID, c *Characteristic) ([]*Descriptor, error)
// ReadCharacteristic retrieves the value of a specified characteristic.
ReadCharacteristic(ctx context.Context, c *Characteristic) ([]byte, error)
// ReadLongCharacteristic retrieves the value of a specified characteristic that is longer than the
// MTU.
ReadLongCharacteristic(ctx context.Context, c *Characteristic) ([]byte, error)
// ReadDescriptor retrieves the value of a specified characteristic descriptor.
ReadDescriptor(ctx context.Context, d *Descriptor) ([]byte, error)
// WriteCharacteristic writes the value of a characteristic.
WriteCharacteristic(ctx context.Context, c *Characteristic, b []byte, noResp bool) error
// WriteDescriptor writes the value of a characteristic descriptor.
WriteDescriptor(ctx context.Context, d *Descriptor, b []byte) error
Subscribe(vh uint16, f func(*Characteristic, []byte, error))
// SetNotifyValue sets notifications for the value of a specified characteristic.
SetNotifyValue(ctx context.Context, c *Characteristic, f func(*Characteristic, []byte, error)) error
// SetIndicateValue sets indications for the value of a specified characteristic.
SetIndicateValue(ctx context.Context, c *Characteristic, f func(*Characteristic, []byte, error)) error
// ReadRSSI retrieves the current RSSI value for the remote peripheral.
ReadRSSI(ctx context.Context) int
// SetMTU sets the mtu for the remote peripheral.
SetMTU(ctx context.Context, mtu uint16) error
}
Peripheral is the interface that represent a remote peripheral device.
type Property ¶
type Property int
const ( CharBroadcast Property = 0x01 // may be broadcasted CharRead Property = 0x02 // may be read CharWriteNR Property = 0x04 // may be written to, with no reply CharWrite Property = 0x08 // may be written to, with a reply CharNotify Property = 0x10 // supports notifications CharIndicate Property = 0x20 // supports Indications CharSignedWrite Property = 0x40 // supports signed write CharExtended Property = 0x80 // supports extended properties )
Characteristic property flags (spec 3.3.3.1)
type ReadHandler ¶
type ReadHandler interface {
ServeRead(ctx context.Context, resp ResponseWriter, req *ReadRequest)
}
A ReadHandler handles GATT read requests.
type ReadHandlerFunc ¶
type ReadHandlerFunc func(ctx context.Context, resp ResponseWriter, req *ReadRequest)
ReadHandlerFunc is an adapter to allow the use of ordinary functions as ReadHandlers. If f is a function with the appropriate signature, ReadHandlerFunc(f) is a ReadHandler that calls f.
func (ReadHandlerFunc) ServeRead ¶
func (f ReadHandlerFunc) ServeRead(ctx context.Context, resp ResponseWriter, req *ReadRequest)
ServeRead returns f(r, maxLen, offset).
type ReadRequest ¶
type ReadRequest struct {
Request
Cap int // maximum allowed reply length
Offset int // request value offset
}
A ReadRequest is a characteristic read request from a connected device.
type Request ¶
type Request struct {
Central Central
}
A Request is the context for a request from a connected central device. TODO: Replace this with more general context, such as: http://godoc.org/golang.org/x/net/context
type ResponseWriter ¶
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
A Service is a BLE service.
func NewService ¶
NewService creates and initialize a new Service using u as it's UUID.
func (*Service) AddCharacteristic ¶
func (s *Service) AddCharacteristic(u UUID) *Characteristic
AddCharacteristic adds a characteristic to a service. AddCharacteristic panics if the service already contains another characteristic with the same UUID.
func (*Service) Characteristics ¶
func (s *Service) Characteristics() []*Characteristic
Characteristic returns the contained characteristic of this service.
func (*Service) Name ¶
Name returns the specified name of the service according to its UUID. If the UUID is not assigned, Name returns an empty string.
func (*Service) SetCharacteristics ¶
func (s *Service) SetCharacteristics(chars []*Characteristic)
SetCharacteristics sets the Characteristics of the service.
func (*Service) SetEndHandle ¶
SetEndHandle sets the End Handle of the service.
type ServiceData ¶
FIXME: check the unmarshalling of this data structure.
type UUID ¶
type UUID struct {
// contains filtered or unexported fields
}
A UUID is a BLE UUID.
func MustParseUUID ¶
MustParseUUID parses a standard-format UUID string, like ParseUUID, but panics in case of error.
func ParseUUID ¶
ParseUUID parses a standard-format UUID string, such as "1800" or "34DA3AD1-7110-41A1-B1EF-4430F509CDE7".
type WriteHandler ¶
type WriteHandler interface {
ServeWrite(ctx context.Context, r Request, data []byte) (status byte)
}
A WriteHandler handles GATT write requests. Write and WriteNR requests are presented identically; the server will ensure that a response is sent if appropriate.
type WriteHandlerFunc ¶
WriteHandlerFunc is an adapter to allow the use of ordinary functions as WriteHandlers. If f is a function with the appropriate signature, WriteHandlerFunc(f) is a WriteHandler that calls f.
func (WriteHandlerFunc) ServeWrite ¶
ServeWrite returns f(r, data).
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
binder/cmd/test-binder
command
|
|
|
examples
|
|
|
option
Package option wraps the platform specific options to help users creating cross-platform programs.
|
Package option wraps the platform specific options to help users creating cross-platform programs. |
|
service
Package service provides a collection of sample services for demonstrating purpose.
|
Package service provides a collection of sample services for demonstrating purpose. |