@@ -22,6 +22,10 @@ ESP8266::ESP8266(PinName tx, PinName rx, Callback<void(SignalingAction, int)> si
2222{
2323 _serial.baud (115200 );
2424 _parser.debugOn (debug);
25+
26+ _in_server_mode = false ;
27+ _ipd_packet = NULL ;
28+ _global_socket_counter = 0 ;
2529}
2630
2731int ESP8266::get_firmware_version ()
@@ -211,6 +215,8 @@ bool ESP8266::send(int id, const void *data, uint32_t amount)
211215
212216void ESP8266::_packet_handler ()
213217{
218+ if (_in_server_mode) return ;
219+
214220 int id;
215221 uint32_t amount;
216222
@@ -243,7 +249,10 @@ int32_t ESP8266::recv(int id, void *data, uint32_t amount)
243249{
244250 bool exit_when_not_found = false ;
245251
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];
247256
248257 while (true ) {
249258 // check if any packets are ready for us
@@ -281,15 +290,15 @@ int32_t ESP8266::recv(int id, void *data, uint32_t amount)
281290 // We know when it happens (due to monitoring the RX IRQ channel)
282291 // but there's no way of signaling this thread and actually abort the request...
283292
284- if (is_incoming_socket ) {
293+ if (incoming_socket_id > 0 ) {
285294 int timeout = _parser.getTimeout ();
286295 _parser.setTimeout (1000 );
287296
288297 if (!_parser.recv (" OK" )) {
289298 _parser.setTimeout (timeout);
290299
291300 // 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;
293302
294303 // otherwise, just continue trying to get data...
295304 continue ;
@@ -375,18 +384,36 @@ bool ESP8266::bind(const SocketAddress& address)
375384 // attach to the serial
376385 _serial.attach (callback (this , &ESP8266::attach_rx));
377386
387+ _in_server_mode = true ;
388+
378389 // and start the actual server
379390 return _parser.send (" AT+CIPSERVER=1,%d" , address.get_port ())
380391 && _parser.recv (" OK" );
381392}
382393
383394void 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 */
385412 && (cmd[0 ] >= ' 0' && cmd[0 ] <= ' 9' )
386413 && (cmd[1 ] == ' ,' )
387414 && (strcmp (&cmd[2 ], " CONNECT" ) == 0 )) {
388415
389- _incoming_socket_status[cmd[0 ] - ' 0' ] = true ;
416+ _incoming_socket_status[cmd[0 ] - ' 0' ] = ++_global_socket_counter ;
390417
391418 _signalingCallback (ESP8266_SOCKET_CONNECT, cmd[0 ] - ' 0' );
392419 }
@@ -395,10 +422,43 @@ void ESP8266::process_command(char* cmd, size_t size) {
395422 && (cmd[1 ] == ' ,' )
396423 && (strcmp (&cmd[2 ], " CLOSED" ) == 0 )) {
397424
398- _incoming_socket_status[cmd[0 ] - ' 0' ] = false ;
425+ _incoming_socket_status[cmd[0 ] - ' 0' ] = 0 ;
399426
400427 _signalingCallback (ESP8266_SOCKET_CLOSE, cmd[0 ] - ' 0' );
401428 }
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+ }
402462 free (cmd);
403463}
404464
0 commit comments