@@ -22,6 +22,10 @@ ESP8266::ESP8266(PinName tx, PinName rx, Callback<void(SignalingAction, int)> si
22
22
{
23
23
_serial.baud (115200 );
24
24
_parser.debugOn (debug);
25
+
26
+ _in_server_mode = false ;
27
+ _ipd_packet = NULL ;
28
+ _global_socket_counter = 0 ;
25
29
}
26
30
27
31
int ESP8266::get_firmware_version ()
@@ -211,6 +215,8 @@ bool ESP8266::send(int id, const void *data, uint32_t amount)
211
215
212
216
void ESP8266::_packet_handler ()
213
217
{
218
+ if (_in_server_mode) return ;
219
+
214
220
int id;
215
221
uint32_t amount;
216
222
@@ -243,7 +249,10 @@ int32_t ESP8266::recv(int id, void *data, uint32_t amount)
243
249
{
244
250
bool exit_when_not_found = false ;
245
251
246
- bool is_incoming_socket = _incoming_socket_status[id];
252
+ // see if the underlying socket changed while in the recv() call
253
+ // if you don't do this check it might be that a CLOSED,CONNECT happens on the same esp8266 socket id
254
+ // and thus we associate the data with the wrong mbed TCPSocket
255
+ uint32_t incoming_socket_id = _incoming_socket_status[id];
247
256
248
257
while (true ) {
249
258
// check if any packets are ready for us
@@ -281,15 +290,15 @@ int32_t ESP8266::recv(int id, void *data, uint32_t amount)
281
290
// We know when it happens (due to monitoring the RX IRQ channel)
282
291
// but there's no way of signaling this thread and actually abort the request...
283
292
284
- if (is_incoming_socket ) {
293
+ if (incoming_socket_id > 0 ) {
285
294
int timeout = _parser.getTimeout ();
286
295
_parser.setTimeout (1000 );
287
296
288
297
if (!_parser.recv (" OK" )) {
289
298
_parser.setTimeout (timeout);
290
299
291
300
// socket gone
292
- if (! _incoming_socket_status[id]) return NSAPI_ERROR_NO_SOCKET;
301
+ if (incoming_socket_id != _incoming_socket_status[id]) return NSAPI_ERROR_NO_SOCKET;
293
302
294
303
// otherwise, just continue trying to get data...
295
304
continue ;
@@ -375,18 +384,36 @@ bool ESP8266::bind(const SocketAddress& address)
375
384
// attach to the serial
376
385
_serial.attach (callback (this , &ESP8266::attach_rx));
377
386
387
+ _in_server_mode = true ;
388
+
378
389
// and start the actual server
379
390
return _parser.send (" AT+CIPSERVER=1,%d" , address.get_port ())
380
391
&& _parser.recv (" OK" );
381
392
}
382
393
383
394
void ESP8266::process_command (char * cmd, size_t size) {
384
- if (size == 9 /* 0,CONNECT */
395
+ if (_ipd_packet) {
396
+ memcpy (_ipd_packet_data_ptr, cmd, size);
397
+ _ipd_packet_data_ptr += size;
398
+
399
+ _ipd_packet_data_ptr[0 ] = ' \r ' ;
400
+ _ipd_packet_data_ptr[1 ] = ' \n ' ;
401
+ _ipd_packet_data_ptr += 2 ;
402
+
403
+ if (_ipd_packet_data_ptr == ((char *)(_ipd_packet + 1 )) + _ipd_packet->len ) {
404
+ // append to packet list
405
+ *_packets_end = _ipd_packet;
406
+ _packets_end = &_ipd_packet->next ;
407
+
408
+ _ipd_packet = NULL ;
409
+ }
410
+ }
411
+ else if (size == 9 /* 0,CONNECT */
385
412
&& (cmd[0 ] >= ' 0' && cmd[0 ] <= ' 9' )
386
413
&& (cmd[1 ] == ' ,' )
387
414
&& (strcmp (&cmd[2 ], " CONNECT" ) == 0 )) {
388
415
389
- _incoming_socket_status[cmd[0 ] - ' 0' ] = true ;
416
+ _incoming_socket_status[cmd[0 ] - ' 0' ] = ++_global_socket_counter ;
390
417
391
418
_signalingCallback (ESP8266_SOCKET_CONNECT, cmd[0 ] - ' 0' );
392
419
}
@@ -395,10 +422,43 @@ void ESP8266::process_command(char* cmd, size_t size) {
395
422
&& (cmd[1 ] == ' ,' )
396
423
&& (strcmp (&cmd[2 ], " CLOSED" ) == 0 )) {
397
424
398
- _incoming_socket_status[cmd[0 ] - ' 0' ] = false ;
425
+ _incoming_socket_status[cmd[0 ] - ' 0' ] = 0 ;
399
426
400
427
_signalingCallback (ESP8266_SOCKET_CLOSE, cmd[0 ] - ' 0' );
401
428
}
429
+ else if (cmd[0 ] == ' +' && cmd[1 ] == ' I' && cmd[2 ] == ' P' && cmd[3 ] == ' D' ) {
430
+ int id = cmd[5 ] - ' 0' ;
431
+
432
+ // parse out the length param...
433
+ size_t length_ix = 6 ;
434
+ while (cmd[length_ix] != ' :' && length_ix < size) length_ix++;
435
+ char * temp_length_buff = (char *)calloc (length_ix - 7 + 1 , 1 );
436
+ if (!temp_length_buff) return ;
437
+ memcpy (temp_length_buff, cmd + 7 , length_ix - 7 );
438
+ int amount = atoi (temp_length_buff);
439
+
440
+ // alloc a new packet (and store it in a global var. we'll get the data for this packet straight after this msg)
441
+ _ipd_packet = (struct packet *)malloc (
442
+ sizeof (struct packet ) + amount);
443
+ if (!_ipd_packet) {
444
+ return ;
445
+ }
446
+
447
+ _ipd_packet->id = id;
448
+ _ipd_packet->len = amount;
449
+ _ipd_packet->next = 0 ;
450
+
451
+ _ipd_packet_data_ptr = (char *)(_ipd_packet + 1 );
452
+
453
+ size_t data_len = size - length_ix - 1 ;
454
+ memcpy (_ipd_packet_data_ptr, cmd + length_ix + 1 , data_len);
455
+ _ipd_packet_data_ptr += data_len;
456
+
457
+ // re-add the newline \r\n again...
458
+ _ipd_packet_data_ptr[0 ] = ' \r ' ;
459
+ _ipd_packet_data_ptr[1 ] = ' \n ' ;
460
+ _ipd_packet_data_ptr += 2 ;
461
+ }
402
462
free (cmd);
403
463
}
404
464
0 commit comments