diff --git a/source/BleSerial.cpp b/source/BleSerial.cpp index 6317014..a4f7e89 100644 --- a/source/BleSerial.cpp +++ b/source/BleSerial.cpp @@ -358,6 +358,21 @@ BleSerial::read ( return c; } +uint16_t +BleSerial::readBlocking( + void +) { + uint16_t c = static_cast(-1); + + if (available()) { + std::lock_guard lock(_q_lock); + c = _rx.front(); + _rx.pop(); + } + + return c; +} + void BleSerial::unlock ( void diff --git a/source/BleSerial.h b/source/BleSerial.h index a3bce74..250389a 100644 --- a/source/BleSerial.h +++ b/source/BleSerial.h @@ -170,6 +170,12 @@ public ref class BleSerial sealed : public IStream void ); + virtual + uint16_t + readBlocking( + void + ); + virtual void unlock ( diff --git a/source/BluetoothSerial.cpp b/source/BluetoothSerial.cpp index cf58845..abe9be7 100644 --- a/source/BluetoothSerial.cpp +++ b/source/BluetoothSerial.cpp @@ -110,7 +110,7 @@ BluetoothSerial::available( if (_current_load_operation->Status == Windows::Foundation::AsyncStatus::Error) { _connection_ready = false; - ConnectionLost(L"A fatal error has occurred in UsbSerial::read() and your connection has been lost."); + ConnectionLost(L"A fatal error has occurred in BluetoothSerial::available() and your connection has been lost."); return 0; } @@ -398,6 +398,35 @@ BluetoothSerial::read( return c; } +uint16_t +BluetoothSerial::readBlocking( + void +) +{ + uint16_t c = static_cast(-1); + + if (!_rx->UnconsumedBufferLength) + { + if (_current_load_operation->Status != Windows::Foundation::AsyncStatus::Started) + { + _current_load_operation = _rx->LoadAsync(MAX_READ_SIZE); + } + + create_task(_current_load_operation).wait(); + + if (_current_load_operation->Status == Windows::Foundation::AsyncStatus::Error) + { + _connection_ready = false; + ConnectionLost(L"A fatal error has occurred in BluetoothSerial::readBlocking() and your connection has been lost."); + return c; + } + } + + c = _rx->ReadByte(); + + return c; +} + void BluetoothSerial::unlock( void diff --git a/source/BluetoothSerial.h b/source/BluetoothSerial.h index 704cde4..51bdb4e 100644 --- a/source/BluetoothSerial.h +++ b/source/BluetoothSerial.h @@ -164,6 +164,12 @@ public ref class BluetoothSerial sealed : public IStream void ); + virtual + uint16_t + readBlocking( + void + ); + virtual void unlock( diff --git a/source/CurieBleSerial.h b/source/CurieBleSerial.h index 789cfdb..8fb7727 100644 --- a/source/CurieBleSerial.h +++ b/source/CurieBleSerial.h @@ -212,6 +212,14 @@ public ref class CurieBleSerial sealed : public IStream return _bleSerial->read(); } + virtual inline + uint16_t + readBlocking ( + void + ) { + return _bleSerial->readBlocking(); + } + virtual inline void unlock ( diff --git a/source/DfRobotBleSerial.h b/source/DfRobotBleSerial.h index 61bcbd8..a66bf68 100644 --- a/source/DfRobotBleSerial.h +++ b/source/DfRobotBleSerial.h @@ -212,6 +212,14 @@ public ref class DfRobotBleSerial sealed : public IStream return _bleSerial->read(); } + virtual inline + uint16_t + readBlocking ( + void + ) { + return _bleSerial->readBlocking(); + } + virtual inline void unlock ( diff --git a/source/IStream.h b/source/IStream.h index b707c1b..ea18ce9 100644 --- a/source/IStream.h +++ b/source/IStream.h @@ -227,6 +227,15 @@ public interface struct IStream void ) = 0; + /// + ///Attempts to read one byte once bytes are available + /// + virtual + uint16_t + readBlocking( + void + ) = 0; + /// ///Places one byte into the outbound queue. Data will not be sent until `flush()` is called explicitly. /// diff --git a/source/NetworkSerial.cpp b/source/NetworkSerial.cpp index f34fa22..52cb8fa 100644 --- a/source/NetworkSerial.cpp +++ b/source/NetworkSerial.cpp @@ -93,7 +93,7 @@ NetworkSerial::available( if (_current_load_operation->Status == Windows::Foundation::AsyncStatus::Error) { _connection_ready = false; - ConnectionLost(L"A fatal error has occurred in UsbSerial::read() and your connection has been lost."); + ConnectionLost(L"A fatal error has occurred in NetworkSerial::available() and your connection has been lost."); return 0; } @@ -338,6 +338,35 @@ NetworkSerial::read( return c; } +uint16_t +NetworkSerial::readBlocking( + void +) +{ + uint16_t c = static_cast(-1); + + if (!_rx->UnconsumedBufferLength) + { + if (_current_load_operation->Status != Windows::Foundation::AsyncStatus::Started) + { + _current_load_operation = _rx->LoadAsync(MAX_READ_SIZE); + } + + create_task(_current_load_operation).wait(); + + if (_current_load_operation->Status == Windows::Foundation::AsyncStatus::Error) + { + _connection_ready = false; + ConnectionLost(L"A fatal error has occurred in NetworkSerial::readBlocking() and your connection has been lost."); + return c; + } + } + + c = _rx->ReadByte(); + + return c; +} + void NetworkSerial::unlock( void diff --git a/source/NetworkSerial.h b/source/NetworkSerial.h index 30e6171..5bff0b7 100644 --- a/source/NetworkSerial.h +++ b/source/NetworkSerial.h @@ -158,6 +158,12 @@ public ref class NetworkSerial sealed : public IStream void ); + virtual + uint16_t + readBlocking( + void + ); + virtual void unlock( diff --git a/source/RedBearLabBleSerial.h b/source/RedBearLabBleSerial.h index f533723..afac2fd 100644 --- a/source/RedBearLabBleSerial.h +++ b/source/RedBearLabBleSerial.h @@ -212,6 +212,14 @@ public ref class RedBearLabBleSerial sealed : public IStream return _bleSerial->read(); } + virtual inline + uint16_t + readBlocking ( + void + ) { + return _bleSerial->readBlocking(); + } + virtual inline void unlock ( diff --git a/source/USBSerial.cpp b/source/USBSerial.cpp index 8f888ef..f92bc02 100644 --- a/source/USBSerial.cpp +++ b/source/USBSerial.cpp @@ -132,7 +132,7 @@ UsbSerial::available( if (_current_load_operation->Status == Windows::Foundation::AsyncStatus::Error) { _connection_ready = false; - ConnectionLost(L"A fatal error has occurred in UsbSerial::read() and your connection has been lost."); + ConnectionLost(L"A fatal error has occurred in UsbSerial::available() and your connection has been lost."); return 0; } @@ -392,17 +392,46 @@ UsbSerial::print( uint16_t UsbSerial::read( void - ) +) { uint16_t c = static_cast(-1); - if ( available() ) { + if (available()) { c = _rx->ReadByte(); } return c; } +uint16_t +UsbSerial::readBlocking( + void +) +{ + uint16_t c = static_cast(-1); + + if (!_rx->UnconsumedBufferLength) + { + if (_current_load_operation->Status != Windows::Foundation::AsyncStatus::Started) + { + _current_load_operation = _rx->LoadAsync(MAX_READ_SIZE); + } + + create_task(_current_load_operation).wait(); + + if (_current_load_operation->Status == Windows::Foundation::AsyncStatus::Error) + { + _connection_ready = false; + ConnectionLost(L"A fatal error has occurred in UsbSerial::readBlocking() and your connection has been lost."); + return c; + } + } + + c = _rx->ReadByte(); + + return c; +} + void UsbSerial::unlock( void diff --git a/source/USBSerial.h b/source/USBSerial.h index 14da0d4..14ddf2a 100644 --- a/source/USBSerial.h +++ b/source/USBSerial.h @@ -173,6 +173,12 @@ public ref class UsbSerial sealed : public IStream void ); + virtual + uint16_t + readBlocking( + void + ); + virtual void unlock(