Skip to content

[CM-123] Vernemq rebased #8

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Aug 31, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 75 additions & 9 deletions examples/MKR1000_Cloud_Blink/MKR1000_Cloud_Blink.ino
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
#include <WiFi101.h>
#include <WiFi101.h> // change to WiFiNINA.h if you are using the MKR WiFi 1010 or MKR Vidor 4000
#include <ArduinoCloudV2.h>

#include "arduino_secrets.h"

#define TIMEOUT 7000

///////please enter your sensitive data in the Secret tab/arduino_secrets.h
char ssid[] = SECRET_SSID; // your network SSID (name)
char pass[] = SECRET_PASS; // your network password (use for WPA, or use as key for WEP)
int status = WL_IDLE_STATUS; // the WiFi radio's status
String cloudSerialBuffer = ""; // the string used to compose network messages from the received characters

WiFiClient wifiClient;

Expand All @@ -16,9 +19,8 @@ unsigned long getTime() {
void setup() {
//Initialize serial and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
int timeout = millis() + TIMEOUT;
while (!Serial && (millis() < timeout)) {}

// check for the presence of the shield:
if (WiFi.status() == WL_NO_SHIELD) {
Expand All @@ -33,42 +35,106 @@ void setup() {
}

// attempt to connect to WiFi network:
while (status != WL_CONNECTED) {
int attempts = 0;
while (status != WL_CONNECTED && attempts < 6) {
Serial.print("Attempting to connect to WPA SSID: ");
Serial.println(ssid);
// Connect to WPA/WPA2 network:
status = WiFi.begin(ssid, pass);

// wait 10 seconds for connection:
delay(10000);
attempts++;
}

if (status != WL_CONNECTED) {
Serial.println("Failed to connect to Wifi!");
while (true);
}

// you're connected now, so print out the data:
Serial.print("You're connected to the network");

Serial.println();
Serial.println("Attempting to connect to Arduino Cloud ...");
Serial.println("Attempting to connect to Arduino Cloud");

ArduinoCloud.onGetTime(getTime);
if (!ArduinoCloud.connect()) {

attempts = 0;
while (!ArduinoCloud.connect() && attempts < 10) {
Serial.print(".");
attempts++;
}

if (attempts >= 10) {
Serial.println("Failed to connect to Arduino Cloud!");
while (1);
}

Serial.println("Successfully connected to Arduino Cloud :)");

CloudSerial.begin(9600);
CloudSerial.print("I'm ready for blinking!\n");
}

void loop() {
ArduinoCloud.poll();

// check if there is something waiting to be read
if (CloudSerial.available()) {
Serial.write(CloudSerial.read());
char character = CloudSerial.read();
cloudSerialBuffer += character;

// if a \n character has been received, there should be a complete command inside cloudSerialBuffer
if (character == '\n') {
manageString();
}
}
else // if there is nothing to read, it could be that the last command didn't end with a '\n'. Check.
{
manageString();
}

// Just to be able to simulate the board responses through the serial monitor
if (Serial.available()) {
CloudSerial.write(Serial.read());
}
}

void manageString() {
// Don't proceed if the string is empty
if (cloudSerialBuffer.equals("")) return;

// Remove whitespaces
cloudSerialBuffer.trim();

// Make it uppercase;
cloudSerialBuffer.toUpperCase();

if (cloudSerialBuffer.equals("ON")) {
digitalWrite(6, HIGH);
}
if (cloudSerialBuffer.equals("OFF")) {
digitalWrite(6, LOW);
}

sendString(cloudSerialBuffer);

// Reset cloudSerialBuffer
cloudSerialBuffer = "";
}

// sendString sends a string to the Arduino Cloud.
void sendString(String stringToSend) {
// send the characters one at a time
char lastSentChar = 0;
for (int i = 0; i < stringToSend.length(); i++) {
lastSentChar = stringToSend.charAt(i);
CloudSerial.write(lastSentChar);
}

// if the last sent character wasn't a '\n' add it
if (lastSentChar != '\n') {
CloudSerial.write('\n');
}
}
17 changes: 10 additions & 7 deletions examples/utility/Provisioning/Provisioning.ino
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <ArduinoBearSSL.h>
#include <ArduinoECCX08.h>

const bool DEBUG = true;
const int keySlot = 0;
const int compressedCertSlot = 10;
const int serialNumberAndAuthorityKeyIdentifierSlot = 11;
Expand Down Expand Up @@ -55,7 +56,8 @@ void setup() {
while (1);
}

ECCX08Cert.setSubjectCommonName(ECCX08.serialNumber());
String thingId = promptAndReadLine("Please enter the thing id: ");
ECCX08Cert.setSubjectCommonName(thingId);

String csr = ECCX08Cert.endCSR();

Expand All @@ -68,7 +70,6 @@ void setup() {
Serial.println();
Serial.println(csr);

String thingId = promptAndReadLine("Please enter the thing id: ");
String issueYear = promptAndReadLine("Please enter the issue year of the certificate (2000 - 2031): ");
String issueMonth = promptAndReadLine("Please enter the issue month of the certificate (1 - 12): ");
String issueDay = promptAndReadLine("Please enter the issue day of the certificate (1 - 31): ");
Expand All @@ -78,9 +79,6 @@ void setup() {
String authorityKeyIdentifier = promptAndReadLine("Please enter the certificates authority key identifier: ");
String signature = promptAndReadLine("Please enter the certificates signature: ");

serialNumber.toUpperCase();
signature.toUpperCase();

byte thingIdBytes[72];
byte serialNumberBytes[16];
byte authorityKeyIdentifierBytes[20];
Expand Down Expand Up @@ -130,6 +128,10 @@ void setup() {
while (1);
}

if (!DEBUG) {
return;
}

Serial.println("Compressed cert = ");

const byte* certData = ECCX08Cert.bytes();
Expand Down Expand Up @@ -179,8 +181,9 @@ String readLine() {
return line;
}

void hexStringToBytes(const String& in, byte out[], int length) {
void hexStringToBytes(String& in, byte out[], int length) {
int inLength = in.length();
in.toUpperCase();
int outLength = 0;

for (int i = 0; i < inLength && outLength < length; i += 2) {
Expand All @@ -190,6 +193,6 @@ void hexStringToBytes(const String& in, byte out[], int length) {
byte highByte = (highChar <= '9') ? (highChar - '0') : (highChar + 10 - 'A');
byte lowByte = (lowChar <= '9') ? (lowChar - '0') : (lowChar + 10 - 'A');

out[outLength++] = (highByte << 4) | lowByte;
out[outLength++] = (highByte << 4) | (lowByte & 0xF);
}
}
83 changes: 74 additions & 9 deletions src/ArduinoCloud.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

#include "ArduinoCloudV2.h"

const static char server[] = "a19g5nbe27wn47.iot.us-east-1.amazonaws.com"; //"xxxxxxxxxxxxxx.iot.xx-xxxx-x.amazonaws.com";
const static char server[] = "mqtts-sa.iot.oniudra.cc";

const static int keySlot = 0;
const static int compressedCertSlot = 10;
Expand All @@ -14,7 +14,8 @@ const static int thingIdSlot = 12;

ArduinoCloudClass::ArduinoCloudClass() :
_bearSslClient(NULL),
_mqttClient(256)
// Size of the receive buffer
_mqttClient(MQTT_BUFFER_SIZE)
{
}

Expand Down Expand Up @@ -42,7 +43,7 @@ int ArduinoCloudClass::begin(Client& net)
return 0;
}

ECCX08Cert.setSubjectCommonName(ECCX08.serialNumber());
ECCX08Cert.setSubjectCommonName(_id);
ECCX08Cert.setIssuerCountryName("US");
ECCX08Cert.setIssuerOrganizationName("Arduino LLC US");
ECCX08Cert.setIssuerOrganizationalUnitName("IT");
Expand All @@ -58,31 +59,95 @@ int ArduinoCloudClass::begin(Client& net)
_bearSslClient = new BearSSLClient(net);
_bearSslClient->setEccSlot(keySlot, ECCX08Cert.bytes(), ECCX08Cert.length());

_mqttClient.onMessageAdvanced(ArduinoCloudClass::onMessage);
_mqttClient.begin(server, 8883, *_bearSslClient);

_stdoutTopic = "$aws/things/" + _id + "/stdout";
_stdinTopic = "$aws/things/" + _id + "/stdin";
// Begin function for the MQTTClient
mqttClientBegin(*_bearSslClient);

return 1;
}

// private class method used to initialize mqttClient class member. (called in the begin class method)
void ArduinoCloudClass::mqttClientBegin(Client& net)
{
// MQTT topics definition
_stdoutTopic = "/a/d/" + _id + "/s/o";
_stdinTopic = "/a/d/" + _id + "/s/i";

// use onMessage as callback for received mqtt messages
_mqttClient.onMessageAdvanced(ArduinoCloudClass::onMessage);
_mqttClient.begin(server, 8883, net);

// Set MQTT connection options
_mqttClient.setOptions(mqttOpt.keepAlive, mqttOpt.cleanSession, mqttOpt.timeout);
}

int ArduinoCloudClass::connect()
{
// Username: device id
// Password: empty
if (!_mqttClient.connect(_id.c_str())) {
return 0;
}

_mqttClient.subscribe(_stdinTopic);

return 1;
}

bool ArduinoCloudClass::disconnect()
{
return _mqttClient.disconnect();
}

void ArduinoCloudClass::poll()
{
// If user call poll() without parameters use the default ones
poll(MAX_RETRIES, RECONNECTION_TIMEOUT);
}

bool ArduinoCloudClass::mqttReconnect(int maxRetries, int timeout)
{
// Counter for reconnection retries
int retries = 0;
unsigned long start = millis();

// Check for MQTT broker connection, of if maxReties limit is reached
// if MQTTClient is connected , simply do nothing and retun true
while(!_mqttClient.connected() && (retries++ < maxRetries) && (millis() - start < timeout)) {

// Get last MTTQClient error, (a common error may be a buffer overflow)
lwmqtt_err_t err = _mqttClient.lastError();

// try establish the MQTT broker connection
connect();
}

// It was impossible to establish a connection, return
if ((retries == maxRetries) || (millis() - start >= timeout))
return false;

return true;
}

void ArduinoCloudClass::poll(int reconnectionMaxRetries, int reconnectionTimeoutMs)
{
// Method's argument controls
int maxRetries = (reconnectionMaxRetries > 0) ? reconnectionMaxRetries : MAX_RETRIES;
int timeout = (reconnectionTimeoutMs > 0) ? reconnectionTimeoutMs : RECONNECTION_TIMEOUT;

// If the reconnect() culd not establish the connection, return the control to the user sketch
if (!mqttReconnect(maxRetries, timeout))
return;

// MTTQClient connected!, poll() used to retrieve data from MQTT broker
_mqttClient.loop();
}

void ArduinoCloudClass::reconnect(Client& net)
{
// Initialize again the MQTTClient, otherwise it would not be able to receive messages through its callback
mqttClientBegin(net);
connect();
}

void ArduinoCloudClass::onGetTime(unsigned long(*callback)(void))
{
ArduinoBearSSL.onGetTime(callback);
Expand Down
Loading