3131#undef write
3232#undef read
3333
34+ class WiFiClientRxBuffer {
35+ private:
36+ size_t _size;
37+ uint8_t *_buffer;
38+ size_t _pos;
39+ size_t _fill;
40+ int _fd;
41+ bool _failed;
42+
43+ size_t r_available ()
44+ {
45+ if (_fd < 0 ){
46+ return 0 ;
47+ }
48+ int count;
49+ int res = lwip_ioctl_r (_fd, FIONREAD, &count);
50+ if (res < 0 ) {
51+ _failed = true ;
52+ return 0 ;
53+ }
54+ return count;
55+ }
56+
57+ size_t fillBuffer ()
58+ {
59+ if (!_buffer){
60+ _buffer = (uint8_t *)malloc (_size);
61+ }
62+ if (_fill && _pos == _fill){
63+ _fill = 0 ;
64+ _pos = 0 ;
65+ }
66+ if (!_buffer || _size <= _fill || !r_available ()) {
67+ return 0 ;
68+ }
69+ int res = recv (_fd, _buffer + _fill, _size - _fill, MSG_DONTWAIT);
70+ if (res < 0 && errno != EWOULDBLOCK) {
71+ _failed = true ;
72+ return 0 ;
73+ }
74+ _fill += res;
75+ return res;
76+ }
77+
78+ public:
79+ WiFiClientRxBuffer (int fd, size_t size=1436 )
80+ :_size(size)
81+ ,_buffer(NULL )
82+ ,_pos(0 )
83+ ,_fill(0 )
84+ ,_fd(fd)
85+ ,_failed(false )
86+ {
87+ // _buffer = (uint8_t *)malloc(_size);
88+ }
89+
90+ ~WiFiClientRxBuffer ()
91+ {
92+ free (_buffer);
93+ }
94+
95+ bool failed (){
96+ return _failed;
97+ }
98+
99+ int read (uint8_t * dst, size_t len){
100+ if (!dst || !len || (_pos == _fill && !fillBuffer ())){
101+ return -1 ;
102+ }
103+ size_t a = _fill - _pos;
104+ if (len <= a || ((len - a) <= (_size - _fill) && fillBuffer () >= (len - a))){
105+ if (len == 1 ){
106+ *dst = _buffer[_pos];
107+ } else {
108+ memcpy (dst, _buffer + _pos, len);
109+ }
110+ _pos += len;
111+ return len;
112+ }
113+ size_t left = len;
114+ size_t toRead = a;
115+ uint8_t * buf = dst;
116+ memcpy (buf, _buffer + _pos, toRead);
117+ _pos += toRead;
118+ left -= toRead;
119+ buf += toRead;
120+ while (left){
121+ if (!fillBuffer ()){
122+ return len - left;
123+ }
124+ a = _fill - _pos;
125+ toRead = (a > left)?left:a;
126+ memcpy (buf, _buffer + _pos, toRead);
127+ _pos += toRead;
128+ left -= toRead;
129+ buf += toRead;
130+ }
131+ return len;
132+ }
133+
134+ int peek (){
135+ if (_pos == _fill && !fillBuffer ()){
136+ return -1 ;
137+ }
138+ return _buffer[_pos];
139+ }
140+
141+ size_t available (){
142+ return _fill - _pos + r_available ();
143+ }
144+ };
145+
34146class WiFiClientSocketHandle {
35147private:
36148 int sockfd;
@@ -58,6 +170,7 @@ WiFiClient::WiFiClient():_connected(false),next(NULL)
58170WiFiClient::WiFiClient (int fd):_connected(true ),next(NULL )
59171{
60172 clientSocketHandle.reset (new WiFiClientSocketHandle (fd));
173+ _rxBuffer.reset (new WiFiClientRxBuffer (fd));
61174}
62175
63176WiFiClient::~WiFiClient ()
@@ -69,13 +182,15 @@ WiFiClient & WiFiClient::operator=(const WiFiClient &other)
69182{
70183 stop ();
71184 clientSocketHandle = other.clientSocketHandle ;
185+ _rxBuffer = other._rxBuffer ;
72186 _connected = other._connected ;
73187 return *this ;
74188}
75189
76190void WiFiClient::stop ()
77191{
78192 clientSocketHandle = NULL ;
193+ _rxBuffer = NULL ;
79194 _connected = false ;
80195}
81196
@@ -100,6 +215,7 @@ int WiFiClient::connect(IPAddress ip, uint16_t port)
100215 return 0 ;
101216 }
102217 clientSocketHandle.reset (new WiFiClientSocketHandle (sockfd));
218+ _rxBuffer.reset (new WiFiClientRxBuffer (sockfd));
103219 _connected = true ;
104220 return 1 ;
105221}
@@ -260,11 +376,9 @@ size_t WiFiClient::write(Stream &stream)
260376
261377int WiFiClient::read (uint8_t *buf, size_t size)
262378{
263- if (!available ()) {
264- return -1 ;
265- }
266- int res = recv (fd (), buf, size, MSG_DONTWAIT);
267- if (res < 0 && errno != EWOULDBLOCK) {
379+ int res = -1 ;
380+ res = _rxBuffer->read (buf, size);
381+ if (_rxBuffer->failed ()) {
268382 log_e (" %d" , errno);
269383 stop ();
270384 }
@@ -273,31 +387,25 @@ int WiFiClient::read(uint8_t *buf, size_t size)
273387
274388int WiFiClient::peek ()
275389{
276- if (!available ()) {
277- return -1 ;
278- }
279- uint8_t data = 0 ;
280- int res = recv (fd (), &data, 1 , MSG_PEEK);
281- if (res < 0 && errno != EWOULDBLOCK) {
390+ int res = _rxBuffer->peek ();
391+ if (_rxBuffer->failed ()) {
282392 log_e (" %d" , errno);
283393 stop ();
284394 }
285- return data ;
395+ return res ;
286396}
287397
288398int WiFiClient::available ()
289399{
290400 if (!_connected) {
291401 return 0 ;
292402 }
293- int count;
294- int res = lwip_ioctl_r (fd (), FIONREAD, &count);
295- if (res < 0 ) {
403+ int res = _rxBuffer->available ();
404+ if (_rxBuffer->failed ()) {
296405 log_e (" %d" , errno);
297406 stop ();
298- return 0 ;
299407 }
300- return count ;
408+ return res ;
301409}
302410
303411// Though flushing means to send all pending data,
0 commit comments