Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions adapter_nrf51.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,10 +122,7 @@ func (a *Adapter) Address() (MACAddress, error) {

// Convert a C.ble_gap_addr_t to a MACAddress struct.
func makeMACAddress(addr C.ble_gap_addr_t) MACAddress {
return MACAddress{
MAC: makeAddress(addr.addr),
isRandom: addr.addr_type != 0,
}
return NewMACAddress(makeAddress(addr.addr), addr.addr_type != 0)
}

// Connect starts a connection attempt to the given peripheral device address.
Expand Down
5 changes: 1 addition & 4 deletions adapter_nrf528xx.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,7 @@ func (a *Adapter) Address() (MACAddress, error) {

// Convert a C.ble_gap_addr_t to a MACAddress struct.
func makeMACAddress(addr C.ble_gap_addr_t) MACAddress {
return MACAddress{
MAC: makeAddress(addr.addr),
isRandom: addr.bitfield_addr_type() != 0,
}
return NewMACAddress(makeAddress(addr.addr), addr.bitfield_addr_type() != 0)
}

// Always let the BLE stack pick the right PHY.
Expand Down
6 changes: 3 additions & 3 deletions att_hci.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ func (s *rawService) Read(p []byte) (int, error) {
binary.LittleEndian.PutUint16(p[4:], s.uuid.Get16Bit())
sz += 2
default:
uuid := s.uuid.bytes()
uuid := s.uuid.BytesLittleEndian()
copy(p[4:], uuid[:])
sz += 16
}
Expand Down Expand Up @@ -166,7 +166,7 @@ func (c *rawCharacteristic) Read(p []byte) (int, error) {
binary.LittleEndian.PutUint16(p[5:], c.uuid.Get16Bit())
sz += 2
default:
uuid := c.uuid.bytes()
uuid := c.uuid.BytesLittleEndian()
copy(p[5:], uuid[:])
sz += 16
}
Expand Down Expand Up @@ -232,7 +232,7 @@ func (a *rawAttribute) Read(p []byte) (int, error) {
binary.LittleEndian.PutUint16(p[sz:], a.uuid.Get16Bit())
sz += 2
default:
uuid := a.uuid.bytes()
uuid := a.uuid.BytesLittleEndian()
copy(p[sz:], uuid[:])
sz += 16
}
Expand Down
49 changes: 49 additions & 0 deletions ble.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package bluetooth

import "tinygo.org/x/bluetooth/ble"

// The core value types live in the ble subpackage, so that the protocol
// subpackages can use them without an import cycle. These are aliases, not new
// types, so bluetooth.UUID and ble.UUID are interchangeable.
type (
// UUID is a 16-bit, 32-bit, or 128-bit BLE UUID.
UUID = ble.UUID

// MAC represents a MAC address, in little endian format.
MAC = ble.MAC

// MACAddress contains a Bluetooth address which is a MAC address.
MACAddress = ble.MACAddress
)

// NewUUID returns a new 128-bit UUID for a 16 byte array in big endian order.
func NewUUID(uuid [16]byte) UUID { return ble.NewUUID(uuid) }

// New16BitUUID returns a new 128-bit UUID based on a 16-bit UUID.
func New16BitUUID(shortUUID uint16) UUID { return ble.New16BitUUID(shortUUID) }

// New32BitUUID returns a new 128-bit UUID based on a 32-bit UUID.
func New32BitUUID(shortUUID uint32) UUID { return ble.New32BitUUID(shortUUID) }

// ParseUUID parses the given UUID, which must be in one of the following
// forms: 0000, 00000000, or 00000000-0000-1000-8000-00805F9B34FB.
func ParseUUID(s string) (UUID, error) { return ble.ParseUUID(s) }

// UUIDFromBytes returns the UUID for a 16 byte array in little endian order.
func UUIDFromBytes(b [16]byte) UUID { return ble.UUIDFromBytes(b) }

// ParseMAC parses the given MAC address, which must be in
// 11:22:33:AA:BB:CC format.
func ParseMAC(s string) (MAC, error) { return ble.ParseMAC(s) }

// NewMACAddress returns a MACAddress for the given MAC, marked as random or
// public.
func NewMACAddress(mac MAC, random bool) MACAddress { return ble.NewMACAddress(mac, random) }

// The error values are aliased so that a comparison against the old name still
// holds.
var (
ErrInvalidMAC = ble.ErrInvalidMAC
ErrInvalidBinaryMac = ble.ErrInvalidBinaryMac
ErrInvalidBinaryUUID = ble.ErrInvalidBinaryUUID
)
9 changes: 9 additions & 0 deletions ble/ble.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Package ble holds the core Bluetooth Low Energy value types that are shared
// by the bluetooth package and its protocol subpackages.
//
// The bluetooth package aliases these types, so bluetooth.UUID and ble.UUID
// are the same type.
//
// This package is not yet stable. Its API can change until the module reaches
// version 1.0.
package ble
36 changes: 35 additions & 1 deletion mac.go → ble/mac.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package bluetooth
package ble

import (
"errors"
Expand Down Expand Up @@ -107,3 +107,37 @@ func (mac *MAC) UnmarshalBinary(data []byte) error {
func (mac MAC) AppendBinary(b []byte) ([]byte, error) {
return append(b, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]), nil
}

// MACAddress contains a Bluetooth address which is a MAC address.
type MACAddress struct {
// MAC address of the Bluetooth device.
MAC

isRandom bool
}

// NewMACAddress returns a MACAddress for the given MAC, marked as random or
// public.
func NewMACAddress(mac MAC, random bool) MACAddress {
return MACAddress{MAC: mac, isRandom: random}
}

// IsRandom if the address is randomly created.
func (mac MACAddress) IsRandom() bool {
return mac.isRandom
}

// SetRandom if is a random address.
func (mac *MACAddress) SetRandom(val bool) {
mac.isRandom = val
}

// Set the address
func (mac *MACAddress) Set(val string) {
m, err := ParseMAC(val)
if err != nil {
return
}

mac.MAC = m
}
2 changes: 1 addition & 1 deletion mac_test.go → ble/mac_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package bluetooth
package ble

import (
"bytes"
Expand Down
19 changes: 15 additions & 4 deletions uuid.go → ble/uuid.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package bluetooth
package ble

// This file implements 16-bit and 128-bit UUIDs as defined in the Bluetooth
// specification.
Expand Down Expand Up @@ -116,9 +116,9 @@ func (uuid UUID) BytesBigEndian() [16]byte {
}
}

// bytes returns a 16-byte array containing the raw UUID in little-endian
// BytesLittleEndian returns a 16 byte array with the raw UUID in little endian
// order.
func (uuid UUID) bytes() [16]byte {
func (uuid UUID) BytesLittleEndian() [16]byte {
return [16]byte{
0: byte(uuid.id[0]),
1: byte(uuid.id[0] >> 8),
Expand All @@ -142,7 +142,7 @@ func (uuid UUID) bytes() [16]byte {
// AppendBinary appends the bytes of the uuid in little-endian order to the
// given byte slice b.
func (uuid UUID) AppendBinary(b []byte) ([]byte, error) {
id := uuid.bytes()
id := uuid.BytesLittleEndian()
return append(b, id[:]...), nil
}

Expand Down Expand Up @@ -433,3 +433,14 @@ func (u *UUID) UnmarshalBinary(uuid []byte) error {
u.id[3] = uint32(uuid[12]) | uint32(uuid[13])<<8 | uint32(uuid[14])<<16 | uint32(uuid[15])<<24
return nil
}

// UUIDFromBytes returns the UUID for a 16 byte array in little endian order.
// It is the inverse of BytesLittleEndian.
func UUIDFromBytes(b [16]byte) UUID {
var uuid UUID
uuid.id[0] = uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
uuid.id[1] = uint32(b[4]) | uint32(b[5])<<8 | uint32(b[6])<<16 | uint32(b[7])<<24
uuid.id[2] = uint32(b[8]) | uint32(b[9])<<8 | uint32(b[10])<<16 | uint32(b[11])<<24
uuid.id[3] = uint32(b[12]) | uint32(b[13])<<8 | uint32(b[14])<<16 | uint32(b[15])<<24
return uuid
}
2 changes: 1 addition & 1 deletion uuid_test.go → ble/uuid_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package bluetooth
package ble

import (
"reflect"
Expand Down
34 changes: 3 additions & 31 deletions gap.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,34 +26,6 @@ const (
GAPAddressTypeRandomPrivateNonResolvable = 0x03
)

// MACAddress contains a Bluetooth address which is a MAC address.
type MACAddress struct {
// MAC address of the Bluetooth device.
MAC

isRandom bool
}

// IsRandom if the address is randomly created.
func (mac MACAddress) IsRandom() bool {
return mac.isRandom
}

// SetRandom if is a random address.
func (mac *MACAddress) SetRandom(val bool) {
mac.isRandom = val
}

// Set the address
func (mac *MACAddress) Set(val string) {
m, err := ParseMAC(val)
if err != nil {
return
}

mac.MAC = m
}

type AdvertisingType int

const (
Expand Down Expand Up @@ -351,7 +323,7 @@ func (buf *rawAdvertisementPayload) HasServiceUUID(uuid UUID) bool {
if len(b) == 0 {
b = buf.findField(0x06) // Incomplete List of 128-bit Service Class UUIDs
}
uuidBuf1 := uuid.bytes()
uuidBuf1 := uuid.BytesLittleEndian()
for i := 0; i < len(b)/16; i++ {
uuidBuf2 := b[i*16 : i*16+16]
match := true
Expand Down Expand Up @@ -588,7 +560,7 @@ func (buf *rawAdvertisementPayload) addServiceData(uuid UUID, data []byte) (ok b
// Add the data.
buf.data[buf.len+0] = byte(fieldLength - 1)
buf.data[buf.len+1] = 0x21
uuid_bytes := uuid.bytes()
uuid_bytes := uuid.BytesLittleEndian()
copy(buf.data[buf.len+2:], uuid_bytes[:])
copy(buf.data[buf.len+2+16:], data)
buf.len += uint8(fieldLength)
Expand Down Expand Up @@ -648,7 +620,7 @@ func (buf *rawAdvertisementPayload) addServiceUUID(uuid UUID) (ok bool) {
}
buf.data[buf.len+0] = 17 // length of field, including type
buf.data[buf.len+1] = 0x07 // type, 0x07 means "Complete List of 128-bit Service Class UUIDs"
rawUUID := uuid.bytes()
rawUUID := uuid.BytesLittleEndian()
copy(buf.data[buf.len+2:], rawUUID[:])
buf.len += 18
return true
Expand Down
25 changes: 9 additions & 16 deletions gap_hci.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func (a *Adapter) Scan(callback func(*Adapter, ScanResult)) error {
// Active scanning transmits, so the controller needs to know which of our
// own addresses to put in the SCAN_REQ.
localRandom := uint8(0)
if a.hci.address.isRandom {
if a.hci.address.IsRandom() {
localRandom = GAPAddressTypeRandomStatic
}

Expand Down Expand Up @@ -135,10 +135,7 @@ func (a *Adapter) Scan(callback func(*Adapter, ScanResult)) error {

callback(a, ScanResult{
Address: Address{
MACAddress{
MAC: makeAddress(a.hci.advData.peerBdaddr),
isRandom: random,
},
NewMACAddress(makeAddress(a.hci.advData.peerBdaddr), random),
},
RSSI: int16(a.hci.advData.rssi),
AdvertisementPayload: &advertisementFields{
Expand Down Expand Up @@ -192,11 +189,11 @@ func (a *Adapter) Connect(address Address, params ConnectionParams) (Device, err
}

peerRandom := uint8(0)
if address.isRandom {
if address.IsRandom() {
peerRandom = GAPAddressTypeRandomStatic
}
localRandom := uint8(0)
if a.hci.address.isRandom {
if a.hci.address.IsRandom() {
localRandom = GAPAddressTypeRandomStatic
}
if err := a.hci.leCreateConn(0x0060, // interval
Expand Down Expand Up @@ -226,15 +223,13 @@ func (a *Adapter) Connect(address Address, params ConnectionParams) (Device, err
defer a.hci.clearConnectData()

random := false
if address.isRandom {
if address.IsRandom() {
random = true
}

d := Device{
Address: Address{
MACAddress{
MAC: makeAddress(a.hci.connectData.peerBdaddr),
isRandom: random},
NewMACAddress(makeAddress(a.hci.connectData.peerBdaddr), random),
},
deviceInternal: &deviceInternal{
adapter: a,
Expand Down Expand Up @@ -401,7 +396,7 @@ func (a *Advertisement) Start() error {
typ := uint8(a.advertisementType)

localRandom := uint8(0)
if a.adapter.hci.address.isRandom {
if a.adapter.hci.address.IsRandom() {
localRandom = GAPAddressTypeRandomStatic
}

Expand Down Expand Up @@ -432,7 +427,7 @@ func (a *Advertisement) Start() error {
binary.LittleEndian.PutUint16(advertisingData[5:], uuid.Get16Bit())
case uuid.Is32Bit():
sz = 6
data := uuid.bytes()
data := uuid.BytesLittleEndian()
slices.Reverse(data[:])
copy(advertisingData[5:], data[:])
}
Expand Down Expand Up @@ -492,9 +487,7 @@ func (a *Advertisement) Start() error {

d := Device{
Address: Address{
MACAddress{
MAC: makeAddress(a.adapter.hci.connectData.peerBdaddr),
isRandom: random},
NewMACAddress(makeAddress(a.adapter.hci.connectData.peerBdaddr), random),
},
deviceInternal: &deviceInternal{
adapter: a.adapter,
Expand Down
2 changes: 1 addition & 1 deletion gap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ func TestServiceUUIDs(t *testing.T) {
raw string
expected []UUID
}
uuidBytes := ServiceUUIDAdafruitSound.bytes()
uuidBytes := ServiceUUIDAdafruitSound.BytesLittleEndian()
tests := []testCase{
{},
{
Expand Down
4 changes: 2 additions & 2 deletions gattc_hci.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ func (d Device) DiscoverServices(uuids []UUID) ([]DeviceService, error) {
}

for _, rawService := range cd.services {
if len(uuids) == 0 || rawService.uuid.isIn(uuids) {
if len(uuids) == 0 || uuidIn(rawService.uuid, uuids) {
foundServices[rawService.uuid] =
DeviceService{
device: d,
Expand Down Expand Up @@ -197,7 +197,7 @@ func (s DeviceService) DiscoverCharacteristics(uuids []UUID) ([]DeviceCharacteri
}

for _, rawCharacteristic := range cd.characteristics {
if len(uuids) == 0 || rawCharacteristic.uuid.isIn(uuids) {
if len(uuids) == 0 || uuidIn(rawCharacteristic.uuid, uuids) {
dc := DeviceCharacteristic{
service: &s,
uuid: rawCharacteristic.uuid,
Expand Down
4 changes: 2 additions & 2 deletions gattc_sd.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ func (d Device) DiscoverServices(uuids []UUID) ([]DeviceService, error) {
shortUUIDs = make([]C.ble_uuid_t, sz)
for i, uuid := range uuids {
var errCode C.uint32_t
shortUUIDs[i], errCode = uuid.shortUUID()
shortUUIDs[i], errCode = shortUUIDFor(uuid)
if errCode != 0 {
return nil, Error(errCode)
}
Expand Down Expand Up @@ -211,7 +211,7 @@ func (s DeviceService) DiscoverCharacteristics(uuids []UUID) ([]DeviceCharacteri
shortUUIDs = make([]C.ble_uuid_t, sz)
for i, uuid := range uuids {
var errCode C.uint32_t
shortUUIDs[i], errCode = uuid.shortUUID()
shortUUIDs[i], errCode = shortUUIDFor(uuid)
if errCode != 0 {
return nil, Error(errCode)
}
Expand Down
Loading
Loading