31
31
#undef write
32
32
#undef read
33
33
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
+
34
146
class WiFiClientSocketHandle {
35
147
private:
36
148
int sockfd;
@@ -58,6 +170,7 @@ WiFiClient::WiFiClient():_connected(false),next(NULL)
58
170
WiFiClient::WiFiClient (int fd):_connected(true ),next(NULL )
59
171
{
60
172
clientSocketHandle.reset (new WiFiClientSocketHandle (fd));
173
+ _rxBuffer.reset (new WiFiClientRxBuffer (fd));
61
174
}
62
175
63
176
WiFiClient::~WiFiClient ()
@@ -69,13 +182,15 @@ WiFiClient & WiFiClient::operator=(const WiFiClient &other)
69
182
{
70
183
stop ();
71
184
clientSocketHandle = other.clientSocketHandle ;
185
+ _rxBuffer = other._rxBuffer ;
72
186
_connected = other._connected ;
73
187
return *this ;
74
188
}
75
189
76
190
void WiFiClient::stop ()
77
191
{
78
192
clientSocketHandle = NULL ;
193
+ _rxBuffer = NULL ;
79
194
_connected = false ;
80
195
}
81
196
@@ -100,6 +215,7 @@ int WiFiClient::connect(IPAddress ip, uint16_t port)
100
215
return 0 ;
101
216
}
102
217
clientSocketHandle.reset (new WiFiClientSocketHandle (sockfd));
218
+ _rxBuffer.reset (new WiFiClientRxBuffer (sockfd));
103
219
_connected = true ;
104
220
return 1 ;
105
221
}
@@ -260,11 +376,9 @@ size_t WiFiClient::write(Stream &stream)
260
376
261
377
int WiFiClient::read (uint8_t *buf, size_t size)
262
378
{
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 ()) {
268
382
log_e (" %d" , errno);
269
383
stop ();
270
384
}
@@ -273,31 +387,25 @@ int WiFiClient::read(uint8_t *buf, size_t size)
273
387
274
388
int WiFiClient::peek ()
275
389
{
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 ()) {
282
392
log_e (" %d" , errno);
283
393
stop ();
284
394
}
285
- return data ;
395
+ return res ;
286
396
}
287
397
288
398
int WiFiClient::available ()
289
399
{
290
400
if (!_connected) {
291
401
return 0 ;
292
402
}
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 ()) {
296
405
log_e (" %d" , errno);
297
406
stop ();
298
- return 0 ;
299
407
}
300
- return count ;
408
+ return res ;
301
409
}
302
410
303
411
// Though flushing means to send all pending data,
0 commit comments