Skip to content

Instantly share code, notes, and snippets.

@sterwill
Created June 4, 2017 20:52
Show Gist options
  • Save sterwill/91d67f4878008864f941d786c5604e46 to your computer and use it in GitHub Desktop.
Save sterwill/91d67f4878008864f941d786c5604e46 to your computer and use it in GitHub Desktop.
Demonstrates a lock-up with the Feather M0 + ATWINC1500 + SSL at high read speeds
// Demonstrates a slowdown/hang on the Feather M0 + ATWINC1500 that
// happens when sending more than a few bytes at a time on an SSL connection
// that's receiving data at medium-high speed. This issue only seems to
// affect connections over SSL/TLS. Plain TCP connections don't seem to
// exhibit this problem (or perhaps there's less overhead so the buffers
// aren't as full so often).
//
// To reproduce this problem you'll need to run a program on a server that the
// Feather can reach that accepts SSL/TLS connections and sends an endless
// stream of data to clients. OpenSSL's "s_server" program can do this easily,
// so pick a server where the OpenSSL tools are installed.
//
// Steps to reproduce:
//
// 1. Generate an SSL certificate and private key on your server; save them
// in PEM format
// 2. Install the SSL certificate you generated to the Feather M0's firmware
// so it's trusted; if you used a certificate in step 1 that was signed by
// a CA that the Feather already trusts, you can skip this step
// 3. Run a command like this on your server:
//
// yes "this is a test" | tr "\n" " " | openssl s_server -cert your-cert.pem -key your-key.pem -debug -accept 1234
//
// 4. Customize this program; set the wifi SSID, passphrase, server
// host and port to point to where you have the OpenSSL "s_server" running
// 5. Install this program on your Feather M0 + ATWINC1500 and watch the
// serial monitor
//
// With my setup, the server being 43 ms away from the client (round-trip),
// the lockup usually happens within 30 seconds. Sometimes the program hangs
// while sending for a few seconds, but later recovers, just to hang for several
// minutes later.
//
// License: CC0
// To the extent possible under law, Shaw Terwilliger has waived all copyright
// and related or neighboring rights to this program. This work is published
// from: United States.
#include <WiFi101.h>
#define WIFI_SSID "your ssid here"
#define WIFI_PASSPHRASE "your passphrase"
// Point at a host and port that will feed you endless bytes.
#define TCP_HOST "server.example.com"
#define TCP_PORT 1234
// Number of bytes to write each second; higher numbers hang the controller quicker.
#define BYTES_TO_WRITE 200
// Buffer > MTU (~1400) to allow for full packet reads
static uint8_t buf[2000];
static WiFiClient client;
static uint32_t last_write_at = 0;
static uint16_t writes = 0;
static uint32_t bytes_read_since_last_write = 0;
void setup() {
Serial.begin(115200);
Serial.println();
Serial.println("started");
// Pins for Feather M0
WiFi.setPins(8, 7, 4, 2);
WiFi.begin(WIFI_SSID, WIFI_PASSPHRASE);
Serial.print("wifi... ");
while (WiFi.status() != WL_CONNECTED) {}
Serial.println(" connected");
}
void loop() {
// Get connected
if (!client.connected()) {
Serial.print("ssl... ");
if (!client.connectSSL(TCP_HOST, TCP_PORT)) {
Serial.println(" failed");
return;
}
Serial.println(" connected");
}
uint32_t now = millis();
// Read as much as we can.
int bytes_read = client.read(buf, sizeof(buf));
if (bytes_read > 0) {
bytes_read_since_last_write += bytes_read;
}
// Print status and send some data every once in a while.
if (now - last_write_at > 1000) {
Serial.print(++writes, DEC);
Serial.print(": read ");
Serial.print(bytes_read_since_last_write, DEC);
Serial.print(" bytes/s, writing ");
Serial.print(BYTES_TO_WRITE, DEC);
Serial.print(" bytes... ");
for (uint16_t i = 0; i < BYTES_TO_WRITE; i++) {
client.write('x');
}
Serial.println(" done.");
last_write_at = now;
bytes_read_since_last_write = 0;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment