Created
June 4, 2017 20:52
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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