Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 7e24147

Browse files
Merge pull request #402 from swnf/cordio-locks
Use locks to prevent race conditions in HCICordioTransport
2 parents 9263b3a + b14172f commit 7e24147

File tree

4 files changed

+41
-8
lines changed

4 files changed

+41
-8
lines changed

‎src/utility/HCI.cpp‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,20 +136,24 @@ void HCIClass::poll(unsigned long timeout)
136136
HCITransport.wait(timeout);
137137
}
138138

139+
HCITransport.lockForRead();
139140
while (HCITransport.available()) {
140141
byte b = HCITransport.read();
141142

142143
if (_recvIndex >= (int)sizeof(_recvBuffer)) {
143144
_recvIndex = 0;
144145
if (_debug) {
146+
HCITransport.unlockForRead();
145147
_debug->println("_recvBuffer overflow");
148+
HCITransport.lockForRead();
146149
}
147150
}
148151

149152
_recvBuffer[_recvIndex++] = b;
150153

151154
if (_recvBuffer[0] == HCI_ACLDATA_PKT) {
152155
if (_recvIndex > 5 && _recvIndex >= (5 + (_recvBuffer[3] + (_recvBuffer[4] << 8)))) {
156+
HCITransport.unlockForRead();
153157
if (_debug) {
154158
dumpPkt("HCI ACLDATA RX <- ", _recvIndex, _recvBuffer);
155159
}
@@ -164,9 +168,11 @@ void HCIClass::poll(unsigned long timeout)
164168
#ifdef ARDUINO_AVR_UNO_WIFI_REV2
165169
digitalWrite(NINA_RTS, LOW);
166170
#endif
171+
HCITransport.lockForRead();
167172
}
168173
} else if (_recvBuffer[0] == HCI_EVENT_PKT) {
169174
if (_recvIndex > 3 && _recvIndex >= (3 + _recvBuffer[2])) {
175+
HCITransport.unlockForRead();
170176
if (_debug) {
171177
dumpPkt("HCI EVENT RX <- ", _recvIndex, _recvBuffer);
172178
}
@@ -182,19 +188,23 @@ void HCIClass::poll(unsigned long timeout)
182188
#ifdef ARDUINO_AVR_UNO_WIFI_REV2
183189
digitalWrite(NINA_RTS, LOW);
184190
#endif
191+
HCITransport.lockForRead();
185192
}
186193
} else {
187194
_recvIndex = 0;
188195

189196
if (_debug) {
197+
HCITransport.unlockForRead();
190198
_debug->println(b, HEX);
199+
HCITransport.lockForRead();
191200
}
192201
}
193202
}
194203

195204
#ifdef ARDUINO_AVR_UNO_WIFI_REV2
196205
digitalWrite(NINA_RTS, HIGH);
197206
#endif
207+
HCITransport.unlockForRead();
198208
}
199209

200210
int HCIClass::reset()

‎src/utility/HCICordioTransport.cpp‎

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -254,8 +254,11 @@ void HCICordioTransportClass::end()
254254

255255
void HCICordioTransportClass::wait(unsigned long timeout)
256256
{
257-
if (available()) {
258-
return;
257+
{
258+
mbed::CriticalSectionLock critical_section;
259+
if (available()) {
260+
return;
261+
}
259262
}
260263

261264
// wait for handleRxData to signal
@@ -277,6 +280,14 @@ int HCICordioTransportClass::read()
277280
return _rxBuf.read_char();
278281
}
279282

283+
void HCICordioTransportClass::lockForRead() {
284+
mbed::CriticalSectionLock::enable();
285+
}
286+
287+
void HCICordioTransportClass::unlockForRead() {
288+
mbed::CriticalSectionLock::disable();
289+
}
290+
280291
size_t HCICordioTransportClass::write(const uint8_t* data, size_t length)
281292
{
282293
if (!_begun) {
@@ -299,13 +310,16 @@ size_t HCICordioTransportClass::write(const uint8_t* data, size_t length)
299310

300311
void HCICordioTransportClass::handleRxData(uint8_t* data, uint8_t len)
301312
{
302-
if (_rxBuf.availableForStore() < len) {
303-
// drop!
304-
return;
305-
}
313+
{
314+
mbed::CriticalSectionLock critical_section;
315+
if (_rxBuf.availableForStore() < len) {
316+
// drop!
317+
return;
318+
}
306319

307-
for (int i = 0; i < len; i++) {
308-
_rxBuf.store_char(data[i]);
320+
for (int i = 0; i < len; i++) {
321+
_rxBuf.store_char(data[i]);
322+
}
309323
}
310324

311325
bleEventFlags.set(0x01);

‎src/utility/HCICordioTransport.h‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ class HCICordioTransportClass : public HCITransportInterface {
4040
virtual int peek();
4141
virtual int read();
4242

43+
virtual void lockForRead() override;
44+
virtual void unlockForRead() override;
45+
4346
virtual size_t write(const uint8_t* data, size_t length);
4447

4548
private:

‎src/utility/HCITransport.h‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ class HCITransportInterface {
3333
virtual int peek() = 0;
3434
virtual int read() = 0;
3535

36+
// Some transports require a lock to use available/peek/read
37+
// These methods allow to keep the lock while reading an unknown number of bytes
38+
// These methods might disable interrupts. Only keep the lock as long as necessary.
39+
virtual void lockForRead() {}
40+
virtual void unlockForRead() {}
41+
3642
virtual size_t write(const uint8_t* data, size_t length) = 0;
3743
};
3844

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /