Skip to content

Commit 88d7297

Browse files
committed
use new type AdvertismentDataElement for ManufacturerData also
1 parent e357a2a commit 88d7297

File tree

6 files changed

+45
-64
lines changed

6 files changed

+45
-64
lines changed

adapter_darwin.go

+8-8
Original file line numberDiff line numberDiff line change
@@ -141,30 +141,30 @@ func makeScanResult(prph cbgo.Peripheral, advFields cbgo.AdvFields, rssi int) Sc
141141
serviceUUIDs = append(serviceUUIDs, parsedUUID)
142142
}
143143

144-
var manufacturerData []ManufacturerDataElement
144+
var manufacturerData []AdvertismentDataElement
145145
if len(advFields.ManufacturerData) > 2 {
146146
// Note: CoreBluetooth seems to assume there can be only one
147147
// manufacturer data fields in an advertisement packet, while the
148148
// specification allows multiple such fields. See the Bluetooth Core
149149
// Specification Supplement, table 1.1:
150150
// https://www.bluetooth.com/specifications/css-11/
151-
manufacturerID := uint16(advFields.ManufacturerData[0])
152-
manufacturerID += uint16(advFields.ManufacturerData[1]) << 8
153-
manufacturerData = append(manufacturerData, ManufacturerDataElement{
154-
CompanyID: manufacturerID,
151+
manufacturerData = append(manufacturerData, AdvertismentDataElement
152+
UUID: New16BitUUID(uint16(advFields.ManufacturerData[0]) + uint16(advFields.ManufacturerData[1]) << 8),
155153
Data: advFields.ManufacturerData[2:],
156154
})
157155
}
158156

159-
serviceData := make(map[uint16][]byte)
157+
var serviceData []AdvertismentDataElement
160158
for _, svcData := range advFields.ServiceData {
161159
cbgoUUID := svcData.UUID
162160
uuid, err := ParseUUID(cbgoUUID.String())
163161
if err != nil || uuid.String() != cbgoUUID.String() {
164162
continue
165163
}
166-
svcID := uuid.Get16Bit()
167-
serviceData[svcID] = svcData.Data[:]
164+
serviceData = append(serviceData, AdvertismentDataElement{
165+
UUID: uuid,
166+
Data: svcData.Data[:]
167+
})
168168
}
169169

170170
// Peripheral UUID is randomized on macOS, which means to

examples/advertisement/main.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ func main() {
1313
adv := adapter.DefaultAdvertisement()
1414
must("config adv", adv.Configure(bluetooth.AdvertisementOptions{
1515
LocalName: "Go Bluetooth",
16-
ManufacturerData: []bluetooth.ManufacturerDataElement{
17-
{CompanyID: 0xffff, Data: []byte{0x01, 0x02}},
16+
ManufacturerData: []bluetooth.AdvertismentDataElement{
17+
{UUID: bluetooth.New16BitUUID(0xFFFF), Data: []byte{0x01, 0x02}},
1818
},
1919
}))
2020
must("start adv", adv.Start())

gap.go

+21-40
Original file line numberDiff line numberDiff line change
@@ -55,29 +55,19 @@ type AdvertisementOptions struct {
5555
Interval Duration
5656

5757
// ManufacturerData stores Advertising Data.
58-
ManufacturerData []ManufacturerDataElement
58+
ManufacturerData []AdvertismentDataElement
5959

6060
// ServiceData stores Advertising Data.
6161
ServiceData []AdvertismentDataElement
6262
}
6363

64-
// Manufacturer data that's part of an advertisement packet.
65-
type ManufacturerDataElement struct {
64+
// AdvertismentDataElement strores a uuid/byte-array pair used as ServiceData or ManufacturerData advertisment elements
65+
type AdvertismentDataElement struct {
66+
// service uuid or company uuid
6667
// The company ID, which must be one of the assigned company IDs.
6768
// The full list is in here:
6869
// https://www.bluetooth.com/specifications/assigned-numbers/
69-
// The list can also be viewed here:
70-
// https://bitbucket.org/bluetooth-SIG/public/src/main/assigned_numbers/company_identifiers/company_identifiers.yaml
7170
// The value 0xffff can also be used for testing.
72-
CompanyID uint16
73-
74-
// The value, which can be any value but can't be very large.
75-
Data []byte
76-
}
77-
78-
// AdvertismentDataElement strores a uuid/byte-array pair used as ServiceData or ManufacturerData advertisment elements
79-
type AdvertismentDataElement struct {
80-
// service uuid or company uuid
8171
// The list can also be viewed here:
8272
// https://bitbucket.org/bluetooth-SIG/public/src/main/assigned_numbers/company_identifiers/company_identifiers.yaml
8373
// https://bitbucket.org/bluetooth-SIG/public/src/main/assigned_numbers/uuids/service_uuids.yaml
@@ -139,7 +129,7 @@ type AdvertisementPayload interface {
139129

140130
// ManufacturerData returns a slice with all the manufacturer data present in the
141131
// advertising. It may be empty.
142-
ManufacturerData() []ManufacturerDataElement
132+
ManufacturerData() []AdvertismentDataElement
143133

144134
// ServiceData returns a slice with all the service data present in the
145135
// advertising. It may be empty.
@@ -158,7 +148,7 @@ type AdvertisementFields struct {
158148
ServiceUUIDs []UUID
159149

160150
// ManufacturerData is the manufacturer data of the advertisement.
161-
ManufacturerData []ManufacturerDataElement
151+
ManufacturerData []AdvertismentDataElement
162152

163153
// ServiceData is the service data of the advertisement.
164154
ServiceData []AdvertismentDataElement
@@ -195,7 +185,7 @@ func (p *advertisementFields) Bytes() []byte {
195185
}
196186

197187
// ManufacturerData returns the underlying ManufacturerData field.
198-
func (p *advertisementFields) ManufacturerData() []ManufacturerDataElement {
188+
func (p *advertisementFields) ManufacturerData() []AdvertismentDataElement {
199189
return p.AdvertisementFields.ManufacturerData
200190
}
201191

@@ -315,21 +305,12 @@ func (buf *rawAdvertisementPayload) HasServiceUUID(uuid UUID) bool {
315305
}
316306

317307
// ManufacturerData returns the manufacturer data in the advertisement payload.
318-
func (buf *rawAdvertisementPayload) ManufacturerData() []ManufacturerDataElement {
319-
var manufacturerData []ManufacturerDataElement
320-
for index := 0; index < int(buf.len)+4; index += int(buf.data[index]) + 1 {
321-
fieldLength := int(buf.data[index+0])
322-
if fieldLength < 3 {
323-
continue
324-
}
325-
fieldType := buf.data[index+1]
326-
if fieldType != 0xff {
327-
continue
328-
}
329-
key := uint16(buf.data[index+2]) | uint16(buf.data[index+3])<<8
330-
manufacturerData = append(manufacturerData, ManufacturerDataElement{
331-
CompanyID: key,
332-
Data: buf.data[index+4 : index+fieldLength+1],
308+
func (buf *rawAdvertisementPayload) ManufacturerData() []AdvertismentDataElement {
309+
var manufacturerData []AdvertismentDataElement
310+
for _, data := range buf.findAllFields(0xFF) {
311+
manufacturerData = append(manufacturerData, AdvertismentDataElement{
312+
UUID: New16BitUUID(uint16(data[0])+(uint16(data[1])<<8)),
313+
Data: data[2:],
333314
})
334315
}
335316
return manufacturerData
@@ -390,7 +371,7 @@ func (buf *rawAdvertisementPayload) addFromOptions(options AdvertisementOptions)
390371
}
391372

392373
for _, element := range options.ManufacturerData {
393-
if err := buf.addManufacturerData(element.CompanyID, element.Data); err != nil {
374+
if err := buf.addManufacturerData(element.UUID, element.Data); err != nil {
394375
return err
395376
}
396377
}
@@ -405,19 +386,19 @@ func (buf *rawAdvertisementPayload) addFromOptions(options AdvertisementOptions)
405386
}
406387

407388
// addManufacturerData adds manufacturer data ([]byte) entries to the advertisement payload.
408-
func (buf *rawAdvertisementPayload) addManufacturerData(key uint16, value []byte) (err error) {
389+
func (buf *rawAdvertisementPayload) addManufacturerData(uuid UUID, data []byte) (err error) {
409390
// Check whether the field can fit this manufacturer data.
410-
fieldLength := len(value) + 4
391+
fieldLength := 1 + 1 + 2 + len(data) // 1 byte length, 1 byte ad type, 2 bytes uuid, actual manufacturer data
411392
if int(buf.len)+fieldLength > len(buf.data) {
412393
return errAdvertisementPacketTooBig
413394
}
414395

415396
// Add the data.
416-
buf.data[buf.len+0] = uint8(fieldLength - 1)
417-
buf.data[buf.len+1] = 0xff
418-
buf.data[buf.len+2] = uint8(key)
419-
buf.data[buf.len+3] = uint8(key >> 8)
420-
copy(buf.data[buf.len+4:], value)
397+
buf.data[buf.len+0] = byte(fieldLength - 1)
398+
buf.data[buf.len+1] = 0xFF
399+
buf.data[buf.len+2] = byte(uuid.Get16Bit())
400+
buf.data[buf.len+3] = byte(uuid.Get16Bit() >> 8)
401+
copy(buf.data[buf.len+4:], data)
421402
buf.len += uint8(fieldLength)
422403

423404
return nil

gap_linux.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ func (a *Advertisement) Configure(options AdvertisementOptions) error {
6161
// Convert map[uint16][]byte to map[uint16]any because that's what BlueZ needs.
6262
manufacturerData := map[uint16]any{}
6363
for _, element := range options.ManufacturerData {
64-
manufacturerData[element.CompanyID] = element.Data
64+
manufacturerData[element.UUID.Get16Bit()] = element.Data
6565
}
6666

6767
// Build an org.bluez.LEAdvertisement1 object, to be exported over DBus.
@@ -279,12 +279,12 @@ func makeScanResult(props map[string]dbus.Variant) ScanResult {
279279
a := Address{MACAddress{MAC: addr}}
280280
a.SetRandom(props["AddressType"].Value().(string) == "random")
281281

282-
var manufacturerData []ManufacturerDataElement
282+
var manufacturerData []AdvertismentDataElement
283283
if mdata, ok := props["ManufacturerData"].Value().(map[uint16]dbus.Variant); ok {
284284
for k, v := range mdata {
285-
manufacturerData = append(manufacturerData, ManufacturerDataElement{
286-
CompanyID: k,
287-
Data: v.Value().([]byte),
285+
manufacturerData = append(manufacturerData, AdvertismentDataElement{
286+
UUID: New16BitUUID(k),
287+
Data: v.Value().([]byte),
288288
})
289289
}
290290
}

gap_test.go

+6-6
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@ func TestCreateAdvertisementPayload(t *testing.T) {
6060
raw: "\x02\x01\x06" + // flags
6161
"\a\xff\x34\x12asdf", // manufacturer data
6262
parsed: AdvertisementOptions{
63-
ManufacturerData: []ManufacturerDataElement{
64-
{0x1234, []byte("asdf")},
63+
ManufacturerData: []AdvertismentDataElement{
64+
{New16BitUUID(0x1234), []byte("asdf")},
6565
},
6666
},
6767
},
@@ -71,10 +71,10 @@ func TestCreateAdvertisementPayload(t *testing.T) {
7171
"\x05\xff\xff\xff\x03\x07" + // manufacturer data 2
7272
"\x03\xff\x11\x00", // manufacturer data 3
7373
parsed: AdvertisementOptions{
74-
ManufacturerData: []ManufacturerDataElement{
75-
{0x1234, []byte{5}},
76-
{0xffff, []byte{3, 7}},
77-
{0x0011, []byte{}},
74+
ManufacturerData: []AdvertismentDataElement{
75+
{New16BitUUID(0x1234), []byte{5}},
76+
{New16BitUUID(0xFFFF), []byte{3, 7}},
77+
{New16BitUUID(0x0011), []byte{}},
7878
},
7979
},
8080
},

gap_windows.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ func getScanResultFromArgs(args *advertisement.BluetoothLEAdvertisementReceivedE
114114
Address: adr,
115115
}
116116

117-
var manufacturerData []ManufacturerDataElement
117+
var manufacturerData []AdvertismentDataElement
118118
if winAdv, err := args.GetAdvertisement(); err == nil && winAdv != nil {
119119
vector, _ := winAdv.GetManufacturerData()
120120
size, _ := vector.GetSize()
@@ -123,8 +123,8 @@ func getScanResultFromArgs(args *advertisement.BluetoothLEAdvertisementReceivedE
123123
manData := (*advertisement.BluetoothLEManufacturerData)(element)
124124
companyID, _ := manData.GetCompanyId()
125125
buffer, _ := manData.GetData()
126-
manufacturerData = append(manufacturerData, ManufacturerDataElement{
127-
CompanyID: companyID,
126+
manufacturerData = append(manufacturerData, AdvertismentDataElement{
127+
UUID: New16BitUUID(companyID),
128128
Data: bufferToSlice(buffer),
129129
})
130130
}

0 commit comments

Comments
 (0)