Skip to content

Commit c9eafaf

Browse files
aykevldeadprogram
authored andcommitted
all: make Device a value instead of a pointer
This is a refactor that is necessary to make it easier to work with connected central devices on a SoftDevice.
1 parent 6e0df0e commit c9eafaf

12 files changed

+75
-62
lines changed

adapter_ninafw.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ type Adapter struct {
2121

2222
connectHandler func(device Address, connected bool)
2323

24-
connectedDevices []*Device
24+
connectedDevices []Device
2525
notificationsStarted bool
2626
}
2727

@@ -33,7 +33,7 @@ var DefaultAdapter = &Adapter{
3333
connectHandler: func(device Address, connected bool) {
3434
return
3535
},
36-
connectedDevices: make([]*Device, 0, maxConnections),
36+
connectedDevices: make([]Device, 0, maxConnections),
3737
}
3838

3939
// Enable configures the BLE stack. It must be called before any
@@ -185,7 +185,7 @@ func (a *Adapter) startNotifications() {
185185
}
186186

187187
d := a.findDevice(not.connectionHandle)
188-
if d == nil {
188+
if d.deviceInternal == nil {
189189
if _debug {
190190
println("no device found for handle", not.connectionHandle)
191191
}
@@ -212,7 +212,7 @@ func (a *Adapter) startNotifications() {
212212
}()
213213
}
214214

215-
func (a *Adapter) findDevice(handle uint16) *Device {
215+
func (a *Adapter) findDevice(handle uint16) Device {
216216
for _, d := range a.connectedDevices {
217217
if d.handle == handle {
218218
if _debug {
@@ -223,5 +223,5 @@ func (a *Adapter) findDevice(handle uint16) *Device {
223223
}
224224
}
225225

226-
return nil
226+
return Device{}
227227
}

examples/discover/main.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ func main() {
4343
}
4444
})
4545

46-
var device *bluetooth.Device
46+
var device bluetooth.Device
4747
select {
4848
case result := <-ch:
4949
device, err = adapter.Connect(result.Address, bluetooth.ConnectionParams{})

examples/heartrate-monitor/main.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ func main() {
5252
}
5353
})
5454

55-
var device *bluetooth.Device
55+
var device bluetooth.Device
5656
select {
5757
case result := <-ch:
5858
device, err = adapter.Connect(result.Address, bluetooth.ConnectionParams{})

gap_darwin.go

+17-11
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,10 @@ func (a *Adapter) StopScan() error {
8585

8686
// Device is a connection to a remote peripheral.
8787
type Device struct {
88+
*deviceInternal
89+
}
90+
91+
type deviceInternal struct {
8892
delegate *peripheralDelegate
8993

9094
cm cbgo.CentralManager
@@ -97,14 +101,14 @@ type Device struct {
97101
}
98102

99103
// Connect starts a connection attempt to the given peripheral device address.
100-
func (a *Adapter) Connect(address Address, params ConnectionParams) (*Device, error) {
104+
func (a *Adapter) Connect(address Address, params ConnectionParams) (Device, error) {
101105
uuid, err := cbgo.ParseUUID(address.UUID.String())
102106
if err != nil {
103-
return nil, err
107+
return Device{}, err
104108
}
105109
prphs := a.cm.RetrievePeripheralsWithIdentifiers([]cbgo.UUID{uuid})
106110
if len(prphs) == 0 {
107-
return nil, fmt.Errorf("Connect failed: no peer with address: %s", address.UUID.String())
111+
return Device{}, fmt.Errorf("Connect failed: no peer with address: %s", address.UUID.String())
108112
}
109113

110114
timeout := defaultConnectionTimeout
@@ -129,14 +133,16 @@ func (a *Adapter) Connect(address Address, params ConnectionParams) (*Device, er
129133

130134
// check if we have received a disconnected peripheral
131135
if p.State() == cbgo.PeripheralStateDisconnected {
132-
return nil, connectionError
136+
return Device{}, connectionError
133137
}
134138

135-
d := &Device{
136-
cm: a.cm,
137-
prph: p,
138-
servicesChan: make(chan error),
139-
charsChan: make(chan error),
139+
d := Device{
140+
&deviceInternal{
141+
cm: a.cm,
142+
prph: p,
143+
servicesChan: make(chan error),
144+
charsChan: make(chan error),
145+
},
140146
}
141147

142148
d.delegate = &peripheralDelegate{d: d}
@@ -162,7 +168,7 @@ func (a *Adapter) Connect(address Address, params ConnectionParams) (*Device, er
162168

163169
// Disconnect from the BLE device. This method is non-blocking and does not
164170
// wait until the connection is fully gone.
165-
func (d *Device) Disconnect() error {
171+
func (d Device) Disconnect() error {
166172
d.cm.CancelConnect(d.prph)
167173
return nil
168174
}
@@ -172,7 +178,7 @@ func (d *Device) Disconnect() error {
172178
type peripheralDelegate struct {
173179
cbgo.PeripheralDelegateBase
174180

175-
d *Device
181+
d Device
176182
}
177183

178184
// DidDiscoverServices is called when the services for a Peripheral

gap_linux.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -300,9 +300,9 @@ type Device struct {
300300
// Connect starts a connection attempt to the given peripheral device address.
301301
//
302302
// On Linux and Windows, the IsRandom part of the address is ignored.
303-
func (a *Adapter) Connect(address Address, params ConnectionParams) (*Device, error) {
303+
func (a *Adapter) Connect(address Address, params ConnectionParams) (Device, error) {
304304
devicePath := dbus.ObjectPath(string(a.adapter.Path()) + "/dev_" + strings.Replace(address.MAC.String(), ":", "_", -1))
305-
device := &Device{
305+
device := Device{
306306
device: a.bus.Object("org.bluez", devicePath),
307307
adapter: a,
308308
address: address,
@@ -321,15 +321,15 @@ func (a *Adapter) Connect(address Address, params ConnectionParams) (*Device, er
321321
// Read whether this device is already connected.
322322
connected, err := device.device.GetProperty("org.bluez.Device1.Connected")
323323
if err != nil {
324-
return nil, err
324+
return Device{}, err
325325
}
326326

327327
// Connect to the device, if not already connected.
328328
if !connected.Value().(bool) {
329329
// Start connecting (async).
330330
err := device.device.Call("org.bluez.Device1.Connect", 0).Err
331331
if err != nil {
332-
return nil, fmt.Errorf("bluetooth: failed to connect: %w", err)
332+
return Device{}, fmt.Errorf("bluetooth: failed to connect: %w", err)
333333
}
334334

335335
// Wait until the device has connected.
@@ -360,7 +360,7 @@ func (a *Adapter) Connect(address Address, params ConnectionParams) (*Device, er
360360

361361
// Disconnect from the BLE device. This method is non-blocking and does not
362362
// wait until the connection is fully gone.
363-
func (d *Device) Disconnect() error {
363+
func (d Device) Disconnect() error {
364364
// we don't call our cancel function here, instead we wait for the
365365
// property change in `watchForConnect` and cancel things then
366366
return d.device.Call("org.bluez.Device1.Disconnect", 0).Err

gap_ninafw.go

+22-15
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ type Address struct {
133133
}
134134

135135
// Connect starts a connection attempt to the given peripheral device address.
136-
func (a *Adapter) Connect(address Address, params ConnectionParams) (*Device, error) {
136+
func (a *Adapter) Connect(address Address, params ConnectionParams) (Device, error) {
137137
if _debug {
138138
println("Connect")
139139
}
@@ -145,14 +145,14 @@ func (a *Adapter) Connect(address Address, params ConnectionParams) (*Device, er
145145
if err := a.hci.leCreateConn(0x0060, 0x0030, 0x00,
146146
random, makeNINAAddress(address.MAC),
147147
0x00, 0x0006, 0x000c, 0x0000, 0x00c8, 0x0004, 0x0006); err != nil {
148-
return nil, err
148+
return Device{}, err
149149
}
150150

151151
// are we connected?
152152
start := time.Now().UnixNano()
153153
for {
154154
if err := a.hci.poll(); err != nil {
155-
return nil, err
155+
return Device{}, err
156156
}
157157

158158
if a.hci.connectData.connected {
@@ -163,15 +163,18 @@ func (a *Adapter) Connect(address Address, params ConnectionParams) (*Device, er
163163
random = true
164164
}
165165

166-
d := &Device{adapter: a,
167-
handle: a.hci.connectData.handle,
166+
d := Device{
168167
Address: Address{
169168
MACAddress{
170169
MAC: makeAddress(a.hci.connectData.peerBdaddr),
171170
isRandom: random},
172171
},
173-
mtu: defaultMTU,
174-
notificationRegistrations: make([]notificationRegistration, 0),
172+
deviceInternal: &deviceInternal{
173+
adapter: a,
174+
handle: a.hci.connectData.handle,
175+
mtu: defaultMTU,
176+
notificationRegistrations: make([]notificationRegistration, 0),
177+
},
175178
}
176179
a.connectedDevices = append(a.connectedDevices, d)
177180

@@ -189,10 +192,10 @@ func (a *Adapter) Connect(address Address, params ConnectionParams) (*Device, er
189192

190193
// cancel connection attempt that failed
191194
if err := a.hci.leCancelConn(); err != nil {
192-
return nil, err
195+
return Device{}, err
193196
}
194197

195-
return nil, ErrConnect
198+
return Device{}, ErrConnect
196199
}
197200

198201
type notificationRegistration struct {
@@ -202,28 +205,32 @@ type notificationRegistration struct {
202205

203206
// Device is a connection to a remote peripheral.
204207
type Device struct {
205-
adapter *Adapter
206208
Address Address
209+
*deviceInternal
210+
}
211+
212+
type deviceInternal struct {
213+
adapter *Adapter
207214
handle uint16
208215
mtu uint16
209216

210217
notificationRegistrations []notificationRegistration
211218
}
212219

213220
// Disconnect from the BLE device.
214-
func (d *Device) Disconnect() error {
221+
func (d Device) Disconnect() error {
215222
if _debug {
216223
println("Disconnect")
217224
}
218225
if err := d.adapter.hci.disconnect(d.handle); err != nil {
219226
return err
220227
}
221228

222-
d.adapter.connectedDevices = []*Device{}
229+
d.adapter.connectedDevices = []Device{}
223230
return nil
224231
}
225232

226-
func (d *Device) findNotificationRegistration(handle uint16) *notificationRegistration {
233+
func (d Device) findNotificationRegistration(handle uint16) *notificationRegistration {
227234
for _, n := range d.notificationRegistrations {
228235
if n.handle == handle {
229236
return &n
@@ -233,14 +240,14 @@ func (d *Device) findNotificationRegistration(handle uint16) *notificationRegist
233240
return nil
234241
}
235242

236-
func (d *Device) addNotificationRegistration(handle uint16, callback func([]byte)) {
243+
func (d Device) addNotificationRegistration(handle uint16, callback func([]byte)) {
237244
d.notificationRegistrations = append(d.notificationRegistrations,
238245
notificationRegistration{
239246
handle: handle,
240247
callback: callback,
241248
})
242249
}
243250

244-
func (d *Device) startNotifications() {
251+
func (d Device) startNotifications() {
245252
d.adapter.startNotifications()
246253
}

gap_nrf528xx-central.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ var connectionAttempt struct {
109109
// connection attempt at once and that the address parameter must have the
110110
// IsRandom bit set correctly. This bit is set correctly for scan results, so
111111
// you can reuse that address directly.
112-
func (a *Adapter) Connect(address Address, params ConnectionParams) (*Device, error) {
112+
func (a *Adapter) Connect(address Address, params ConnectionParams) (Device, error) {
113113
// Construct an address object as used in the SoftDevice.
114114
var addr C.ble_gap_addr_t
115115
addr.addr = makeSDAddress(address.MAC)
@@ -158,15 +158,15 @@ func (a *Adapter) Connect(address Address, params ConnectionParams) (*Device, er
158158
// This should be safe as long as Connect is not called concurrently. And
159159
// even then, it should catch most such race conditions.
160160
if connectionAttempt.state.Get() != 0 {
161-
return nil, errAlreadyConnecting
161+
return Device{}, errAlreadyConnecting
162162
}
163163
connectionAttempt.state.Set(1)
164164

165165
// Start the connection attempt. We'll get a signal in the event handler.
166166
errCode := C.sd_ble_gap_connect(&addr, &scanParams, &connectionParams, C.BLE_CONN_CFG_TAG_DEFAULT)
167167
if errCode != 0 {
168168
connectionAttempt.state.Set(0)
169-
return nil, Error(errCode)
169+
return Device{}, Error(errCode)
170170
}
171171

172172
// Wait until the connection is established.
@@ -179,13 +179,13 @@ func (a *Adapter) Connect(address Address, params ConnectionParams) (*Device, er
179179
connectionAttempt.state.Set(0)
180180

181181
// Connection has been established.
182-
return &Device{
182+
return Device{
183183
connectionHandle: connectionHandle,
184184
}, nil
185185
}
186186

187187
// Disconnect from the BLE device.
188-
func (d *Device) Disconnect() error {
188+
func (d Device) Disconnect() error {
189189
errCode := C.sd_ble_gap_disconnect(d.connectionHandle, C.BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION)
190190
if errCode != 0 {
191191
return Error(errCode)

0 commit comments

Comments
 (0)