Skip to content

Commit

Permalink
fix: correct race condition from connection params in HCI implementat…
Browse files Browse the repository at this point in the history
…ion.

Basically it was responding by calling a function that retriggered asking to change the
parameters yet again. Yet we are not actually doing anything about this request at present.

Signed-off-by: deadprogram <[email protected]>
  • Loading branch information
deadprogram committed Jan 4, 2025
1 parent fb043fd commit 78869b0
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 17 deletions.
8 changes: 7 additions & 1 deletion att_hci.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ var (
ErrATTUnknown = errors.New("bluetooth: ATT unknown error")
ErrATTOp = errors.New("bluetooth: ATT OP error")
ErrATTUnknownConnection = errors.New("bluetooth: ATT unknown connection")
ErrATTAttributeNotFound = errors.New("bluetooth: ATT attribute not found")
)

const defaultTimeoutSeconds = 10
Expand Down Expand Up @@ -528,7 +529,12 @@ func (a *att) handleData(handle uint16, buf []byte) error {
println("att.handleData: attOpERROR", handle, cd.lastErrorOpcode, cd.lastErrorCode)
}

return ErrATTOp
switch cd.lastErrorCode {
case attErrorAttrNotFound:
return ErrATTAttributeNotFound
default:
return ErrATTOp
}

case attOpMTUReq:
if debug {
Expand Down
15 changes: 12 additions & 3 deletions gap_hci.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,18 @@ func (a *Adapter) Connect(address Address, params ConnectionParams) (Device, err
if address.isRandom {
random = 1
}
if err := a.hci.leCreateConn(0x0060, 0x0030, 0x00,
random, makeNINAAddress(address.MAC),
0x00, 0x0006, 0x000c, 0x0000, 0x00c8, 0x0004, 0x0006); err != nil {
if err := a.hci.leCreateConn(0x0060, // interval
0x0030, // window
0x00, // initiatorFilter
random, // peerBdaddrType
makeNINAAddress(address.MAC), // peerBdaddr
0x00, // ownBdaddrType
0x0006, // minInterval
0x000c, // maxInterval
0x0000, // latency
0x00c8, // supervisionTimeout
0x0004, // minCeLength
0x0006); err != nil { // maxCeLength
return Device{}, err
}

Expand Down
3 changes: 3 additions & 0 deletions gattc_hci.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ func (d Device) DiscoverServices(uuids []UUID) ([]DeviceService, error) {
for endHandle == uint16(0xffff) {
err := d.adapter.att.readByGroupReq(d.handle, startHandle, endHandle, gattServiceUUID)
if err != nil {
if err == ErrATTAttributeNotFound {
break
}
return nil, err
}

Expand Down
18 changes: 11 additions & 7 deletions hci.go
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ func (h *hci) processPacket() (bool, error) {
return false, nil
case h.pos >= hciACLLenPos+pktlen:
if debug {
println("hci acl data:", h.pos, hex.EncodeToString(h.buf[:hciACLLenPos+pktlen+1]))
println("hci acl data recv:", h.pos, hex.EncodeToString(h.buf[:hciACLLenPos+pktlen+1]))
}

h.pos = hciACLLenPos + pktlen + 1
Expand All @@ -280,7 +280,7 @@ func (h *hci) processPacket() (bool, error) {
return false, nil
case h.pos >= hciEvtLenPos+pktlen:
if debug {
println("hci event data:", h.pos, hex.EncodeToString(h.buf[:hciEvtLenPos+pktlen+1]))
println("hci event data recv:", h.pos, hex.EncodeToString(h.buf[:hciEvtLenPos+pktlen+1]))
}

h.pos = hciEvtLenPos + pktlen + 1
Expand All @@ -293,7 +293,7 @@ func (h *hci) processPacket() (bool, error) {
if h.pos > 3 {
pktlen := int(h.buf[3])
if debug {
println("hci synchronous data:", h.pos, pktlen, hex.EncodeToString(h.buf[:1+3+pktlen]))
println("hci synchronous data recv:", h.pos, pktlen, hex.EncodeToString(h.buf[:1+3+pktlen]))
}

// move to next packet
Expand All @@ -304,7 +304,7 @@ func (h *hci) processPacket() (bool, error) {

default:
if debug {
println("unknown packet data:", h.pos, h.end, hex.EncodeToString(h.buf[:h.pos]))
println("unknown packet data recv:", h.pos, h.end, hex.EncodeToString(h.buf[:h.pos]))
}
return true, ErrHCIUnknown
}
Expand Down Expand Up @@ -678,7 +678,11 @@ func (h *hci) handleEventData(buf []byte) error {
switch buf[2] {
case leMetaEventConnComplete, leMetaEventEnhancedConnectionComplete:
if debug {
println("leMetaEventConnComplete")
if buf[2] == leMetaEventConnComplete {
println("leMetaEventConnComplete", hex.EncodeToString(buf))
} else {
println("leMetaEventEnhancedConnectionComplete", hex.EncodeToString(buf))
}
}

h.connectData.connected = true
Expand All @@ -691,10 +695,10 @@ func (h *hci) handleEventData(buf []byte) error {
switch buf[2] {
case leMetaEventConnComplete:
h.connectData.interval = binary.LittleEndian.Uint16(buf[14:])
h.connectData.timeout = binary.LittleEndian.Uint16(buf[16:])
h.connectData.timeout = binary.LittleEndian.Uint16(buf[18:])
case leMetaEventEnhancedConnectionComplete:
h.connectData.interval = binary.LittleEndian.Uint16(buf[26:])
h.connectData.timeout = binary.LittleEndian.Uint16(buf[28:])
h.connectData.timeout = binary.LittleEndian.Uint16(buf[30:])
}

h.att.addConnection(h.connectData.handle)
Expand Down
11 changes: 5 additions & 6 deletions l2cap_hci.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ func (l *l2cap) addConnection(handle uint16, role uint8, interval, timeout uint1
return nil
}

if timeout == 0 {
timeout = 0x00c8
}

var b [12]byte
b[0] = connectionParamUpdateRequest
b[1] = 0x01
Expand Down Expand Up @@ -108,7 +112,7 @@ func (l *l2cap) handleData(handle uint16, buf []byte) error {

func (l *l2cap) handleParameterUpdateRequest(connectionHandle uint16, identifier uint8, data []byte) error {
if debug {
println("l2cap.handleParameterUpdateRequest:", connectionHandle, "data:", hex.EncodeToString(data))
println("l2cap.handleParameterUpdateRequest:", connectionHandle, "identifier:", identifier, "data:", hex.EncodeToString(data))
}

req := l2capConnectionParamReqPkt{}
Expand All @@ -130,11 +134,6 @@ func (l *l2cap) handleParameterUpdateRequest(connectionHandle uint16, identifier
return err
}

// valid so update connection parameters
if resp.value == 0 {
return l.hci.leConnUpdate(connectionHandle, req.minInterval, req.maxInterval, req.latency, req.timeout)
}

return nil
}

Expand Down

0 comments on commit 78869b0

Please sign in to comment.