cc3000 crashing on repeated request?

Adafruit Ethernet, Motor, Proto, Wave, Datalogger, GPS Shields - etc!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
vng
 
Posts: 9
Joined: Fri Jul 04, 2014 12:43 am

cc3000 crashing on repeated request?

Post by vng »

Hi everyone,

So I've managed to get my shield up and running, doing post request with basic http authentication. Everything works great. However, I realized my unit is crashing after 1 successful call to my server. So i started digging deeper:

Code: Select all

void postPointToServer(String data) {
  Serial.print("postPointToServer:");
  Serial.println(data);

  // Http Basic Authorization
  String auth_raw = serial + ":" + token;
  char auth_input[200];
  char auth_output[200];
  auth_raw.toCharArray(auth_input, auth_raw.length() + 1);
  base64_encode(auth_output, auth_input, auth_raw.length());

  Serial.println("1");
  Adafruit_CC3000_Client www = cc3000.connectTCP(ip, PORT);

  if (www.connected()) {
    www.fastrprint(F("POST ")); www.fastrprint(WEBPAGE); www.fastrprint(F(" HTTP/1.1\r\n"));
    www.fastrprint(F("Host: ")); www.fastrprint(WEBSITE); www.fastrprint(F("\r\n"));
    www.fastrprint(F("Authorization: Basic ")); www.fastrprint(auth_output); www.fastrprint(F("\r\n"));
    www.fastrprint(F("Content-Type: application/x-www-form-urlencoded")); www.fastrprint(F("\r\n"));

    char len_c[7];
    itoa(data.length(), len_c, 10);
    www.fastrprint(F("Content-Length: ")); www.fastrprint(len_c); www.fastrprint(F("\r\n"));

    // Extra empty line for post arguments
    www.fastrprint(F("\r\n"));

    char data_c[200];
    data.toCharArray(data_c, data.length() + 1);
    www.fastrprint(data_c); www.fastrprint(F("\r\n"));

    www.fastrprint(F("\r\n"));
    www.println();

    displayGreen();
    Serial.println("2");

  } else {
    Serial.println(F("Connection failed"));
    displayRed();
    www.close();
    return;
  }

  /* Read data until either the connection is closed, or the idle timeout is reached. */
  /*
  unsigned long lastRead = millis();
  while (www.connected() && (millis() - lastRead < IDLE_TIMEOUT_MS)) {
    while (www.available()) {
      char c = www.read();
      Serial.print(c);
      lastRead = millis();
    }
  }
  */

  Serial.println("3");
  www.close();
  Serial.println("4");
}
Note that I have commented the idle timeout bloc because I do not need to read anything from the server at this moment.

And this is what comes out in my serial.monitor:

Code: Select all

Free RAM: 6577
Initialization Complete
Wireless Connected!
DHCP Requested!
Setup Complete
getEC:*OK
getPH:3.36
postPointToServer:ec=*OK&ph=3.36
1
2
3
And then the program stalls. So clearly, http://www.close() is CRASHING my board.

Can an expert shed some light on this issue?
Last edited by vng on Tue Jul 15, 2014 10:16 pm, edited 1 time in total.

vng
 
Posts: 9
Joined: Fri Jul 04, 2014 12:43 am

Re: Something seems to be crashing my CC3000 board

Post by vng »

So I even dug a little deeper...

I downloaded the sample code, WebClient.ino and changed the loop function to the following:

Code: Select all

void loop() {
  Adafruit_CC3000_Client www = cc3000.connectTCP(ip, 80);
  if (www.connected()) {
    www.fastrprint(F("GET "));
    www.fastrprint(WEBPAGE);
    www.fastrprint(F(" HTTP/1.1\r\n"));
    www.fastrprint(F("Host: ")); www.fastrprint(WEBSITE); www.fastrprint(F("\r\n"));
    www.fastrprint(F("\r\n"));
    www.println();
  } else {
    Serial.println(F("Connection failed"));
  }

  Serial.println(F("-------------------------------------"));

  www.close();
  delay(5*1000);
}
This code works. It makes a request to the Adafruit server every 5 seconds and goes on forever.

Now that I have eliminated the possibility of hardware issue on my board, I am really not sure why http://www.close() is crashing my board.


I plan on POSTing to my server every 5 minutes.

vng
 
Posts: 9
Joined: Fri Jul 04, 2014 12:43 am

Re: Something seems to be crashing my CC3000 board

Post by vng »

And I forgot to add that if I commented out www.close() then Adafruit_CC3000_Client www = cc3000.connectTCP(ip, PORT); will halt indefinitely next loop.

User avatar
rw
 
Posts: 2
Joined: Tue Jun 24, 2014 10:25 am

Re: cc3000 crashing on repeated request?

Post by rw »

I've had a very similar problem.

Unless I added a delay of at least 1 second the application would hang, usually in the call to connectTCP. Even after adding a delay the application would eventually hang after minutes or hours.

In my case the solution was to add a "Connection: close" header to the request. After adding that I can remove the delay and the loop runs successfully forever.

I should add that I have a very recent copy of the Adafruit library and CC3000 firmware.

User avatar
adafruit_support_mike
 
Posts: 67446
Joined: Thu Feb 11, 2010 2:51 pm

Re: cc3000 crashing on repeated request?

Post by adafruit_support_mike »

Closing a TCP connection requires a 4-step handshaking process:

- The client emits a FIN packet saying it's ready to quit
- The server emits an ACK packet saying it's gotten the client's FIN packet
- The server emits a FIN packet saying it's ready to quit
- The client sends an ACK packet saying it's gotten the server's FIN packet

If those four steps don't happen, the system will keep the connection open.

Opening a TCP connection involves a similar handshake, which takes a certain amount of time to complete. That time is called 'connection latency', and can be longer than the time necessary to transmit the actual file. Webpages that use several external files (stylesheets, images, scripts) could rack up huge latency delays if they used a new TCP connection for each file.

To avoid that problem, HTTP/1.1 defaults to 'persistent connections' which allow multiple files to be requested/sent through the same connection.

With persistent connections, it's the client's job to tell the server when it wants to close the connection. If you don't include a "Connection: close" header in the request, the server will hold the TCP connection open on the assumption that the client will make another request after the current one.

User avatar
rw
 
Posts: 2
Joined: Tue Jun 24, 2014 10:25 am

Re: cc3000 crashing on repeated request?

Post by rw »

Thank you. That makes sense. In my case the responses are very short with no external references so the "Connection: close" header in the request seems reasonable. I'm finding that the it still doesn't run "forever" but does eventually hang when I push it very hard during testing. But it's much more reliable now. Perhaps there is a scenario where the handshake isn't completed leaving connections open, maybe a race condition.

User avatar
adafruit_support_mike
 
Posts: 67446
Joined: Thu Feb 11, 2010 2:51 pm

Re: cc3000 crashing on repeated request?

Post by adafruit_support_mike »

Try calling cc3000.checkConnected() before opening each new TCP connection.

Wifi connections are much more vulnerable to noise and interference than wired connections, so it isn't so much a question of "will I lose the radio link?" as "how long will it be before I lose the radio link?"

The code that opens a TCP connection assumes that the link-layer connection is there and working, so calling cc3000.connectTCP() when the radio link is dead leads to a hang.

To avoid that, test the link to make sure it's good before creating each new TCP connection. If the link is dead, call cc3000.reboot() and reconnect to your network before moving on.

Locked
Please be positive and constructive with your questions and comments.

Return to “Arduino Shields from Adafruit”