Easy repro of hard fault in TCP stack

I was experiencing some problems with TCPServer and TCPClient last night. Running the simple example from the spark docs was causing my core to go into the dreaded red, blinking SOS of death with a “hard fault” code.

I eventually figured out that I could always get the code to hit this hard fault by connecting to the core using the telnet protocol. However, when I use raw TCP the program executes just fine, with no crashes seen yet. The spark code I’m using is below. And I’m using putty as the client.

To be clear: I fully expect that connecting to this program using telnet should cause all kinds of weirdness since the telnet protocol includes extra goo along with the text. But I can’t see how this should cause a fault in the code sample. It really looks like a bug in the spark TCP code.

Anyway, it looks like there have been problems with the spark TCP stack for some time now, so I figured I’d post this in case it helps debugging – since it’s a very easy and straightforward way to repro a hard fault.

And… before anyone starts theorizing about how the code below might be causing the fault… I should point out that, when connecting to this using telnet, the spark never seems to send out anything after “Connected to Spark!” So it doesn’t look like it’s ever getting to the client.write(client.read()) loop.

#include "application.h"

TCPServer server = TCPServer(23);
TCPClient client;

char addr[16];

void setup()
{
  server.begin();
  IPAddress localIP = WiFi.localIP();
  sprintf(addr, "%u.%u.%u.%u", localIP[0], localIP[1], localIP[2], localIP[3]);
  Spark.variable("Address", addr, STRING);
}

void loop()
{
  client = server.available();

  if (client.connected()) {
    client.println("Connected to Spark!");
    client.println(WiFi.localIP());
    client.println(WiFi.subnetMask());
    client.println(WiFi.gatewayIP());
    client.println(WiFi.SSID());
    client.println(">");

    while (client.connected()) {
      while (client.available()) {
        client.write(client.read());
      }
    }
  }
}

Hi @gorsat

I cut and pasted your code into the IDE and downloaded it to a core. It works just fine for me.

What you are using to access the core? I used telnet 10.0.0.3 23 from the OS X command line. I get

$ telnet 10.0.0.3 23
Trying 10.0.0.3...
Connected to 10.0.0.3.
Escape character is '^]'.
Connected to Spark!
10.0.0.3
255.255.255.0
10.0.0.1
<my SSID here>
>
1234
1234
qwerty
qwerty
^]
telnet> quit
Connection closed.
$ 

I typed “1234” return and the core echoed 1234 return, etc. I tried closing and reopening the connection a couple of times to be sure.

Maybe the telnet client you are using is trying SSL or flooding the core in some way. I mention that because the client.write(client.read()) part of your code sends one packet per character right now on Spark, I believe.

I am not sure what is going on for you, but I think it has something to do with your test setup, not your core code. It is still a problem since the core should never gratuitously error out, but it is not as simple as your test case code makes it seem.

I’m using putty. It’s a pretty standard tool. Plain old telnet mode (no security) will cause my core to fault every time. But like I said, connecting via raw TCP works just fine. One of these days, if I get ambitious, build the firmware locally and hook up a debugger I’ll figure out what’s going on.