Skip to content

Commit

Permalink
Merge pull request #63 from rigado/fix/srAppend
Browse files Browse the repository at this point in the history
Fix scan response append for manufacturer data
  • Loading branch information
estutzenberger authored May 11, 2022
2 parents b692255 + 8c134ae commit 3e34352
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 2 deletions.
1 change: 1 addition & 0 deletions adv.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ type Advertisement interface {

ToMap() (map[string]interface{}, error)
Data() []byte
SrData() []byte
}

var AdvertisementMapKeys = struct {
Expand Down
7 changes: 7 additions & 0 deletions linux/hci/adv.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,13 @@ func (a *Advertisement) Data() []byte {
return v
}

// SrData returns the scan response data of the packet.
// This is linux specific
func (a *Advertisement) SrData() []byte {
v, _ := a.srDataWErr()
return v
}

// ScanResponse returns the scan response of the packet, if it presents.
// This is linux specific.
func (a *Advertisement) ScanResponse() []byte {
Expand Down
8 changes: 8 additions & 0 deletions linux/hci/adv_werr.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,14 @@ func (a *Advertisement) dataWErr() ([]byte, error) {
return a.e.DataWErr(a.i)
}

func (a *Advertisement) srDataWErr() ([]byte, error) {
//no scan response data available
if a.sr == nil {
return nil, nil
}
return a.e.DataWErr(a.sr.i)
}

func (a *Advertisement) scanResponseWErr() ([]byte, error) {
if a.sr == nil {
return nil, nil
Expand Down
25 changes: 23 additions & 2 deletions parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,8 @@ func Parse(pdu []byte) (map[string]interface{}, error) {

start := i + 2
end := start + length - 1
bytes := pdu[start:end]
bytes := make([]byte, len(pdu[start:end]))
copy(bytes, pdu[start:end])
dec, ok := pduDecodeMap[typ]
if ok && len(bytes) != 0 {
//have min length?
Expand Down Expand Up @@ -277,7 +278,7 @@ func Parse(pdu []byte) (map[string]interface{}, error) {
m[dec.key] = msd
} else {
//we already checked for min length so just copy
m[dec.key] = bytes
writeOrAppendBytes(m, dec.key, bytes)
}
}

Expand All @@ -286,3 +287,23 @@ func Parse(pdu []byte) (map[string]interface{}, error) {

return m, nil
}

func writeOrAppendBytes(m map[string]interface{}, key string, data []byte) {
if _, ok := m[key]; !ok {
m[key] = data
} else {
if d, ok := m[key].([]byte); ok {
if key == keys.mfgdata {
//mfg data contains the company id again in the scan response
//strip that out
data = data[2:]
}
d = append(d, data...)
m[key] = d
} else {
//just overwrite it if the data type is wrong
m[key] = data
}

}
}
62 changes: 62 additions & 0 deletions parser/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,68 @@ func Test_FieldCombo(t *testing.T) {
}
}

func Test_SpiltFields(t *testing.T) {
u128 := []byte{0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3}
md := []byte{1, 2, 3, 4, 5, 6, 7, 8}

p := testPdu{}
p.add(types.flags, []byte{0x12})
p.add(types.uuid16comp, []byte{1, 2, 3, 4})
p.add(types.uuid128comp, u128)
p.add(types.mfgdata, md)
p.add(types.svc16, []byte{1, 2, 3, 4, 5, 6, 7})

md2 := []byte{0xc5, 0, 10, 11, 12, 13, 14, 15}
sr := testPdu{}
sr.add(types.mfgdata, md2)

//mimic behavior of call to new packet
allBytes := append(p.bytes(), sr.bytes()...)

m, err := Parse(allBytes)
if err != nil {
t.Fatal(err)
}

var v, exp interface{}
t.Log(m)

// check flags
exp = []byte{0x12}
v = m[keys.flags]
if !reflect.DeepEqual(v, exp) {
t.Fatalf("have %v (%T), want %v (%T)", v, v, exp, exp)
}

// check services
exp = []ble.UUID{
ble.UUID16(0x0201),
ble.UUID16(0x0403),
ble.UUID(u128),
}

v = m[keys.services]
if !reflect.DeepEqual(v, exp) {
t.Fatalf("have %v (%T), want %v (%T)", v, v, exp, exp)
}

// check mfg
exp = append(md, md2[2:]...)
v = m[keys.mfgdata]
if !reflect.DeepEqual(v, exp) {
t.Fatalf("have %v (%T), want %v (%T)", v, v, exp, exp)
}

// check svc data
exp = map[string]interface{}{
"0201": []interface{}{[]byte{3, 4, 5, 6, 7}},
}
v = m[keys.serviceData]
if !reflect.DeepEqual(v, exp) {
t.Fatalf("have %v (%T), want %v (%T)", v, v, exp, exp)
}
}

func Test_ParseErrors(t *testing.T) {
// missing a byte on uuid128
u128bad := []byte{0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3}
Expand Down

0 comments on commit 3e34352

Please sign in to comment.