Skip to content

Commit c93d88d

Browse files
author
Paolo Calao
authored
Implement supervision timeout setting for peripherals (arduino-libraries#101)
Peripherals having the supervision timeout set will execute a parameter update request when some central tries to connect to them. Allowed supervisionTimeout value range: 0x000A to 0x0C80 Actual Timeout: (supervisionTimeout * 10 ms) Warning: supervision timeout in milliseconds shall be larger than : (1 + Connection_Latency) * Connection_Interval_Max * 2, where Connection_Interval_Max is given in milliseconds. Example scenario: - peripheral has supervision timeout set to 1000 -> (actual timeout = 1000 * 10ms) - central connects to the peripheral with a supervision timeout of 200. - peripheral execute a parameter update request, putting supervision timeout at 1000. - central eventually updates the connection parameters accordingly and sends a response containing the result of the update.
1 parent 86d8b51 commit c93d88d

File tree

4 files changed

+55
-20
lines changed

4 files changed

+55
-20
lines changed

src/local/BLELocalDevice.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,11 @@ void BLELocalDevice::setConnectionInterval(uint16_t minimumConnectionInterval, u
323323
L2CAPSignaling.setConnectionInterval(minimumConnectionInterval, maximumConnectionInterval);
324324
}
325325

326+
void BLELocalDevice::setSupervisionTimeout(uint16_t supervisionTimeout)
327+
{
328+
L2CAPSignaling.setSupervisionTimeout(supervisionTimeout);
329+
}
330+
326331
void BLELocalDevice::setConnectable(bool connectable)
327332
{
328333
GAP.setConnectable(connectable);

src/local/BLELocalDevice.h

+5
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,11 @@ class BLELocalDevice {
6969
virtual BLEDevice central();
7070
virtual BLEDevice available();
7171

72+
virtual void setAdvertisingInterval(uint16_t advertisingInterval);
73+
virtual void setConnectionInterval(uint16_t minimumConnectionInterval, uint16_t maximumConnectionInterval);
74+
virtual void setSupervisionTimeout(uint16_t supervisionTimeout);
75+
virtual void setConnectable(bool connectable);
76+
7277
virtual void setEventHandler(BLEDeviceEvent event, BLEDeviceEventHandler eventHandler);
7378

7479
virtual void setAdvertisingInterval(uint16_t advertisingInterval);

src/utility/L2CAPSignaling.cpp

+42-20
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@
2626

2727
L2CAPSignalingClass::L2CAPSignalingClass() :
2828
_minInterval(0),
29-
_maxInterval(0)
29+
_maxInterval(0),
30+
_supervisionTimeout(0)
3031
{
3132
}
3233

@@ -36,36 +37,46 @@ L2CAPSignalingClass::~L2CAPSignalingClass()
3637

3738
void L2CAPSignalingClass::addConnection(uint16_t handle, uint8_t role, uint8_t /*peerBdaddrType*/,
3839
uint8_t /*peerBdaddr*/[6], uint16_t interval,
39-
uint16_t /*latency*/, uint16_t /*supervisionTimeout*/,
40+
uint16_t /*latency*/, uint16_t supervisionTimeout,
4041
uint8_t /*masterClockAccuracy*/)
4142
{
4243
if (role != 1) {
4344
// ignore
4445
return;
4546
}
4647

47-
if (!_minInterval || !_maxInterval) {
48-
// no connection intervale to request
49-
return;
50-
}
48+
bool updateParameters = false;
49+
uint16_t updatedMinInterval = interval;
50+
uint16_t updatedMaxInterval = interval;
51+
uint16_t updatedSupervisionTimeout = supervisionTimeout;
5152

52-
if (interval >= _minInterval && interval <= _maxInterval) {
53-
// all good, within interval range
54-
return;
53+
if (_minInterval && _maxInterval) {
54+
if (interval < _minInterval || interval > _maxInterval) {
55+
updatedMinInterval = _minInterval;
56+
updatedMaxInterval = _maxInterval;
57+
updateParameters = true;
58+
}
5559
}
5660

57-
struct __attribute__ ((packed)) L2CAPConnectionParameterUpdateRequest {
58-
uint8_t code;
59-
uint8_t identifier;
60-
uint16_t length;
61-
uint16_t minInterval;
62-
uint16_t maxInterval;
63-
uint16_t latency;
64-
uint16_t supervisionTimeout;
65-
} request = { CONNECTION_PARAMETER_UPDATE_REQUEST, 0x01, 8,
66-
_minInterval, _maxInterval, 0x0000, 0x00c8 };
61+
if (_supervisionTimeout && supervisionTimeout != _supervisionTimeout) {
62+
updatedSupervisionTimeout = _supervisionTimeout;
63+
updateParameters = true;
64+
}
6765

68-
HCI.sendAclPkt(handle, SIGNALING_CID, sizeof(request), &request);
66+
if (updateParameters) {
67+
struct __attribute__ ((packed)) L2CAPConnectionParameterUpdateRequest {
68+
uint8_t code;
69+
uint8_t identifier;
70+
uint16_t length;
71+
uint16_t minInterval;
72+
uint16_t maxInterval;
73+
uint16_t latency;
74+
uint16_t supervisionTimeout;
75+
} request = { CONNECTION_PARAMETER_UPDATE_REQUEST, 0x01, 8,
76+
updatedMinInterval, updatedMaxInterval, 0x0000, updatedSupervisionTimeout };
77+
78+
HCI.sendAclPkt(handle, SIGNALING_CID, sizeof(request), &request);
79+
}
6980
}
7081

7182
void L2CAPSignalingClass::handleData(uint16_t connectionHandle, uint8_t dlen, uint8_t data[])
@@ -108,6 +119,11 @@ void L2CAPSignalingClass::setConnectionInterval(uint16_t minInterval, uint16_t m
108119
_maxInterval = maxInterval;
109120
}
110121

122+
void L2CAPSignalingClass::setSupervisionTimeout(uint16_t supervisionTimeout)
123+
{
124+
_supervisionTimeout = supervisionTimeout;
125+
}
126+
111127
void L2CAPSignalingClass::connectionParameterUpdateRequest(uint16_t handle, uint8_t identifier, uint8_t dlen, uint8_t data[])
112128
{
113129
struct __attribute__ ((packed)) L2CAPConnectionParameterUpdateRequest {
@@ -135,6 +151,12 @@ void L2CAPSignalingClass::connectionParameterUpdateRequest(uint16_t handle, uint
135151
}
136152
}
137153

154+
if (_supervisionTimeout) {
155+
if (request->supervisionTimeout != _supervisionTimeout) {
156+
response.value = 0x0001; // reject
157+
}
158+
}
159+
138160
HCI.sendAclPkt(handle, SIGNALING_CID, sizeof(response), &response);
139161

140162
if (response.value == 0x0000) {

src/utility/L2CAPSignaling.h

+3
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,16 @@ class L2CAPSignalingClass {
4040

4141
virtual void setConnectionInterval(uint16_t minInterval, uint16_t maxInterval);
4242

43+
virtual void setSupervisionTimeout(uint16_t supervisionTimeout);
44+
4345
private:
4446
virtual void connectionParameterUpdateRequest(uint16_t handle, uint8_t identifier, uint8_t dlen, uint8_t data[]);
4547
virtual void connectionParameterUpdateResponse(uint16_t handle, uint8_t identifier, uint8_t dlen, uint8_t data[]);
4648

4749
private:
4850
uint16_t _minInterval;
4951
uint16_t _maxInterval;
52+
uint16_t _supervisionTimeout;
5053
};
5154

5255
extern L2CAPSignalingClass& L2CAPSignaling;

0 commit comments

Comments
 (0)