|
9 | 9 | ) |
10 | 10 |
|
11 | 11 | var ( |
12 | | - errCannotSendWriteWithoutResponse = errors.New("bluetooth: cannot send write without response (buffer full)") |
13 | | - errTimeoutEnableNotifications = errors.New("timeout on EnableNotifications") |
| 12 | + errWriteWithoutResponseTimeout = errors.New("bluetooth: write without response timed out waiting for buffer space") |
| 13 | + errTimeoutEnableNotifications = errors.New("timeout on EnableNotifications") |
14 | 14 | ) |
15 | 15 |
|
16 | 16 | var ( |
@@ -243,13 +243,21 @@ func (c DeviceCharacteristic) Write(p []byte) (n int, err error) { |
243 | 243 | // WriteWithoutResponse replaces the characteristic value with a new value. The |
244 | 244 | // call will return before all data has been written. A limited number of such |
245 | 245 | // writes can be in flight at any given time. |
246 | | -// If the client is not ready to send write without response requests at this time (e.g. because the internal buffer is full), an error is returned. |
| 246 | +// If the peripheral's buffer is full, this method polls |
| 247 | +// CanSendWriteWithoutResponse every 15ms (one BLE connection interval) until |
| 248 | +// ready, with a 10-second timeout. |
247 | 249 | func (c DeviceCharacteristic) WriteWithoutResponse(p []byte) (int, error) { |
248 | | - if !c.service.device.prph.CanSendWriteWithoutResponse() { |
249 | | - return 0, errCannotSendWriteWithoutResponse |
| 250 | + dev := c.service.device |
| 251 | + |
| 252 | + deadline := time.Now().Add(10 * time.Second) |
| 253 | + for !dev.prph.CanSendWriteWithoutResponse() { |
| 254 | + if time.Now().After(deadline) { |
| 255 | + return 0, errWriteWithoutResponseTimeout |
| 256 | + } |
| 257 | + time.Sleep(15 * time.Millisecond) |
250 | 258 | } |
251 | 259 |
|
252 | | - c.service.device.prph.WriteCharacteristic(p, c.characteristic, false) |
| 260 | + dev.prph.WriteCharacteristic(p, c.characteristic, false) |
253 | 261 |
|
254 | 262 | return len(p), nil |
255 | 263 | } |
|
0 commit comments