mirror of
https://github.com/bettercap/bettercap
synced 2025-08-20 05:23:19 -07:00
fix: fixed a bug in the gatt library which prevented ble.recon/ble.enum to work multiple times (fixes #471)
This commit is contained in:
parent
f68957b769
commit
120db4db3d
7 changed files with 75 additions and 13 deletions
4
Gopkg.lock
generated
4
Gopkg.lock
generated
|
@ -27,7 +27,7 @@
|
|||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:c309b41787813f80ec393023471014b0be16346bba6e16bf5fa01ce1d310a4ea"
|
||||
digest = "1:a2c142e6c2aa1c71796c748bbe42d224e23d6638fd5b3ae153e70a4b08a8da4e"
|
||||
name = "github.com/bettercap/gatt"
|
||||
packages = [
|
||||
".",
|
||||
|
@ -40,7 +40,7 @@
|
|||
"xpc",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "1353e80bee488dc02d1f7e42759c1352492bf18b"
|
||||
revision = "277ee0d0ef94d26e3190252c59fa34dde0df4f26"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
|
|
|
@ -6,7 +6,6 @@ package ble
|
|||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
golog "log"
|
||||
"time"
|
||||
|
||||
|
@ -15,6 +14,8 @@ import (
|
|||
"github.com/bettercap/bettercap/session"
|
||||
|
||||
"github.com/bettercap/gatt"
|
||||
|
||||
"github.com/evilsocket/islazy/str"
|
||||
)
|
||||
|
||||
type BLERecon struct {
|
||||
|
@ -126,15 +127,25 @@ func (mod *BLERecon) isEnumerating() bool {
|
|||
return mod.currDevice != nil
|
||||
}
|
||||
|
||||
type dummyWriter struct {
|
||||
mod *BLERecon
|
||||
}
|
||||
|
||||
func (w dummyWriter) Write(p []byte) (n int, err error) {
|
||||
w.mod.Debug("[gatt.log] %s", str.Trim(string(p)))
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
func (mod *BLERecon) Configure() (err error) {
|
||||
if mod.Running() {
|
||||
return session.ErrAlreadyStarted
|
||||
} else if mod.gattDevice == nil {
|
||||
mod.Debug("initializing device ...")
|
||||
|
||||
// hey Paypal GATT library, could you please just STFU?!
|
||||
golog.SetOutput(ioutil.Discard)
|
||||
golog.SetFlags(0)
|
||||
golog.SetOutput(dummyWriter{mod})
|
||||
if mod.gattDevice, err = gatt.NewDevice(defaultBLEClientOptions...); err != nil {
|
||||
mod.Debug("error while creating new gatt device: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -162,7 +173,17 @@ func (mod *BLERecon) Start() error {
|
|||
|
||||
mod.Info("stopping scan ...")
|
||||
|
||||
mod.gattDevice.StopScanning()
|
||||
if mod.currDevice != nil && mod.currDevice.Device != nil && mod.gattDevice != nil {
|
||||
mod.Debug("resetting connection with %v", mod.currDevice.Device)
|
||||
mod.gattDevice.CancelConnection(mod.currDevice.Device)
|
||||
}
|
||||
|
||||
mod.Debug("stopping device")
|
||||
if err := mod.gattDevice.Stop(); err != nil {
|
||||
mod.Warning("error while stopping device: %v", err)
|
||||
} else {
|
||||
mod.Debug("gatt device closed")
|
||||
}
|
||||
|
||||
mod.done <- true
|
||||
})
|
||||
|
@ -172,6 +193,9 @@ func (mod *BLERecon) Stop() error {
|
|||
return mod.SetRunning(false, func() {
|
||||
mod.quit <- true
|
||||
<-mod.done
|
||||
mod.Debug("module stopped, cleaning state")
|
||||
mod.gattDevice = nil
|
||||
mod.setCurrentDevice(nil)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -15,8 +15,12 @@ func (mod *BLERecon) onStateChanged(dev gatt.Device, s gatt.State) {
|
|||
if mod.currDevice == nil {
|
||||
mod.Info("starting discovery ...")
|
||||
dev.Scan([]gatt.UUID{}, true)
|
||||
} else {
|
||||
mod.Debug("current device was not cleaned: %v", mod.currDevice)
|
||||
}
|
||||
case gatt.StatePoweredOff:
|
||||
mod.Debug("resetting device instance")
|
||||
mod.gattDevice.StopScanning()
|
||||
mod.setCurrentDevice(nil)
|
||||
mod.gattDevice = nil
|
||||
|
||||
|
@ -51,6 +55,7 @@ func (mod *BLERecon) onPeriphConnected(p gatt.Peripheral, err error) {
|
|||
defer func(per gatt.Peripheral) {
|
||||
mod.Info("disconnecting from %s ...", per.ID())
|
||||
per.Device().CancelConnection(per)
|
||||
mod.setCurrentDevice(nil)
|
||||
}(p)
|
||||
|
||||
mod.Session.Events.Add("ble.device.connected", mod.currDevice)
|
||||
|
|
8
vendor/github.com/bettercap/gatt/linux/device.go
generated
vendored
8
vendor/github.com/bettercap/gatt/linux/device.go
generated
vendored
|
@ -22,6 +22,7 @@ type device struct {
|
|||
func newDevice(n int, chk bool) (*device, error) {
|
||||
fd, err := socket.Socket(socket.AF_BLUETOOTH, syscall.SOCK_RAW, socket.BTPROTO_HCI)
|
||||
if err != nil {
|
||||
log.Printf("could not create AF_BLUETOOTH raw socket")
|
||||
return nil, err
|
||||
}
|
||||
if n != -1 {
|
||||
|
@ -30,13 +31,17 @@ func newDevice(n int, chk bool) (*device, error) {
|
|||
|
||||
req := devListRequest{devNum: hciMaxDevices}
|
||||
if err := gioctl.Ioctl(uintptr(fd), hciGetDeviceList, uintptr(unsafe.Pointer(&req))); err != nil {
|
||||
log.Printf("hciGetDeviceList failed")
|
||||
return nil, err
|
||||
}
|
||||
log.Printf("got %d devices", req.devNum)
|
||||
for i := 0; i < int(req.devNum); i++ {
|
||||
d, err := newSocket(fd, i, chk)
|
||||
if err == nil {
|
||||
log.Printf("dev: %s opened", d.name)
|
||||
return d, err
|
||||
} else {
|
||||
log.Printf("error while opening device %d: %v", i, err)
|
||||
}
|
||||
}
|
||||
return nil, errors.New("no supported devices available")
|
||||
|
@ -45,6 +50,7 @@ func newDevice(n int, chk bool) (*device, error) {
|
|||
func newSocket(fd, n int, chk bool) (*device, error) {
|
||||
i := hciDevInfo{id: uint16(n)}
|
||||
if err := gioctl.Ioctl(uintptr(fd), hciGetDeviceInfo, uintptr(unsafe.Pointer(&i))); err != nil {
|
||||
log.Printf("hciGetDeviceInfo failed")
|
||||
return nil, err
|
||||
}
|
||||
name := string(i.name[:])
|
||||
|
@ -61,6 +67,7 @@ func newSocket(fd, n int, chk bool) (*device, error) {
|
|||
}
|
||||
log.Printf("dev: %s reset", name)
|
||||
if err := gioctl.Ioctl(uintptr(fd), hciResetDevice, uintptr(n)); err != nil {
|
||||
log.Printf("hciResetDevice failed")
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
@ -105,5 +112,6 @@ func (d device) Write(b []byte) (int, error) {
|
|||
}
|
||||
|
||||
func (d device) Close() error {
|
||||
log.Printf("linux.device.Close()")
|
||||
return syscall.Close(d.fd)
|
||||
}
|
||||
|
|
35
vendor/github.com/bettercap/gatt/linux/hci.go
generated
vendored
35
vendor/github.com/bettercap/gatt/linux/hci.go
generated
vendored
|
@ -26,7 +26,8 @@ type HCI struct {
|
|||
bufCnt chan struct{}
|
||||
bufSize int
|
||||
|
||||
pool *util.BytePool
|
||||
pool *util.BytePool
|
||||
loopDone chan bool
|
||||
|
||||
maxConn int
|
||||
connsmu *sync.Mutex
|
||||
|
@ -68,7 +69,8 @@ func NewHCI(devID int, chk bool, maxConn int) (*HCI, error) {
|
|||
bufCnt: make(chan struct{}, 15-1),
|
||||
bufSize: 27,
|
||||
|
||||
pool: util.NewBytePool(4096, 16),
|
||||
pool: util.NewBytePool(4096, 16),
|
||||
loopDone: make(chan bool),
|
||||
|
||||
maxConn: maxConn,
|
||||
connsmu: &sync.Mutex{},
|
||||
|
@ -89,9 +91,15 @@ func NewHCI(devID int, chk bool, maxConn int) (*HCI, error) {
|
|||
}
|
||||
|
||||
func (h *HCI) Close() error {
|
||||
log.Printf("hci.Close()")
|
||||
h.pool.Put(nil)
|
||||
<-h.loopDone
|
||||
log.Printf("mainLoop exited")
|
||||
for _, c := range h.conns {
|
||||
log.Printf("closing connection %v", c)
|
||||
c.Close()
|
||||
}
|
||||
log.Printf("closing %v", h.d)
|
||||
return h.d.Close()
|
||||
}
|
||||
|
||||
|
@ -151,7 +159,10 @@ func (h *HCI) Connect(pd *PlatData) error {
|
|||
}
|
||||
|
||||
func (h *HCI) CancelConnection(pd *PlatData) error {
|
||||
return pd.Conn.Close()
|
||||
if pd != nil && pd.Conn != nil {
|
||||
return pd.Conn.Close()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *HCI) SendRawCommand(c cmd.CmdParam) ([]byte, error) {
|
||||
|
@ -166,19 +177,33 @@ func btoi(b bool) uint8 {
|
|||
}
|
||||
|
||||
func (h *HCI) mainLoop() {
|
||||
log.Printf("hci.mainLoop started")
|
||||
defer func() {
|
||||
h.loopDone <- true
|
||||
}()
|
||||
|
||||
for {
|
||||
// log.Printf("hci.mainLoop pool.Get")
|
||||
b := h.pool.Get()
|
||||
if b == nil {
|
||||
log.Printf("got nil buffer, breaking mainLoop")
|
||||
break
|
||||
}
|
||||
// log.Printf("hci.mainLoop Read(%d)", len(b))
|
||||
n, err := h.d.Read(b)
|
||||
if err != nil {
|
||||
fmt.Sprintf("mainloop err: %v\n", err)
|
||||
log.Printf("mainloop err: %v", err)
|
||||
return
|
||||
}
|
||||
if n == 0 {
|
||||
println("mainLoop failed to read")
|
||||
log.Printf("mainLoop failed to read")
|
||||
return
|
||||
}
|
||||
|
||||
// log.Printf("hci.mainLoop -> handlePacket")
|
||||
h.handlePacket(b, n)
|
||||
}
|
||||
log.Printf("hci.mainLoop stopped")
|
||||
}
|
||||
|
||||
func (h *HCI) handlePacket(buf []byte, n int) {
|
||||
|
|
2
vendor/github.com/bettercap/gatt/linux/l2cap.go
generated
vendored
2
vendor/github.com/bettercap/gatt/linux/l2cap.go
generated
vendored
|
@ -156,7 +156,7 @@ func (c *conn) Close() error {
|
|||
defer h.connsmu.Unlock()
|
||||
_, found := h.conns[hh]
|
||||
if !found {
|
||||
// log.Printf("l2conn: 0x%04x already disconnected", hh)
|
||||
log.Printf("l2conn: 0x%04x already disconnected", hh)
|
||||
return nil
|
||||
}
|
||||
if err, _ := h.c.Send(cmd.Disconnect{ConnectionHandle: hh, Reason: 0x13}); err != nil {
|
||||
|
|
2
vendor/github.com/bettercap/gatt/peripheral_linux.go
generated
vendored
2
vendor/github.com/bettercap/gatt/peripheral_linux.go
generated
vendored
|
@ -407,7 +407,6 @@ func (p *peripheral) loop() {
|
|||
if rspOp == attRspFor[reqOp] || (rspOp == attOpError && r[1] == reqOp) {
|
||||
req.rspc <- r
|
||||
break
|
||||
|
||||
}
|
||||
log.Printf("Request 0x%02x got a mismatched response: 0x%02x", reqOp, rspOp)
|
||||
p.l2c.Write(attErrorRsp(rspOp, 0x0000, AttEcodeReqNotSupp))
|
||||
|
@ -434,6 +433,7 @@ func (p *peripheral) loop() {
|
|||
copy(b, buf)
|
||||
|
||||
if (b[0] != attOpHandleNotify) && (b[0] != attOpHandleInd) {
|
||||
log.Printf("response 0x%x", b[0])
|
||||
rspc <- b
|
||||
continue
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue