From 0cab7a71309b71ac321fb3e25fbea287af7322a9 Mon Sep 17 00:00:00 2001 From: fabio Date: Wed, 4 Dec 2019 16:20:32 +0100 Subject: [PATCH 01/21] split lib for TCP and Lora connections --- .gitignore | 1 + src/ArduinoIoTCloud.h | 182 ++++++-------- src/ArduinoIoTCloudLPWAN.cpp | 200 +++++++++++++++ src/ArduinoIoTCloudLPWAN.h | 61 +++++ src/ArduinoIoTCloudTCP.cpp | 446 ++++++++++++++++++++++++++++++++++ src/ArduinoIoTCloudTCP.h | 143 +++++++++++ src/ArduinoIoTCloud_Defines.h | 7 + src/CloudSerial.h | 13 +- 8 files changed, 939 insertions(+), 114 deletions(-) create mode 100644 src/ArduinoIoTCloudLPWAN.cpp create mode 100644 src/ArduinoIoTCloudLPWAN.h create mode 100644 src/ArduinoIoTCloudTCP.cpp create mode 100644 src/ArduinoIoTCloudTCP.h diff --git a/.gitignore b/.gitignore index 6e260c5ef..65731e42a 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ *~ .vscode *.orig +.vs \ No newline at end of file diff --git a/src/ArduinoIoTCloud.h b/src/ArduinoIoTCloud.h index 98129ffe5..f3715611a 100644 --- a/src/ArduinoIoTCloud.h +++ b/src/ArduinoIoTCloud.h @@ -20,28 +20,19 @@ #include -#ifdef BOARD_HAS_ECCX08 - #include -#elif defined(BOARD_ESP) - #include -#endif + #include -#include + #include -#include -#include "types/CloudWrapperBool.h" +#include "types/CloudWrapperBool.h" #include "types/CloudWrapperFloat.h" #include "types/CloudWrapperInt.h" #include "types/CloudWrapperString.h" -#include "utility/NTPUtils.h" + #include "CloudSerial.h" -static char const DEFAULT_BROKER_ADDRESS_SECURE_AUTH[] = "mqtts-sa.iot.arduino.cc"; -static uint16_t const DEFAULT_BROKER_PORT_SECURE_AUTH = 8883; -static char const DEFAULT_BROKER_ADDRESS_USER_PASS_AUTH[] = "mqtts-up.iot.arduino.cc"; -static uint16_t const DEFAULT_BROKER_PORT_USER_PASS_AUTH = 8884; typedef enum { READ = 0x01, @@ -49,12 +40,6 @@ typedef enum { READWRITE = READ | WRITE } permissionType; -// Declaration of the struct for the mqtt connection options -typedef struct { - int keepAlive; - bool cleanSession; - int timeout; -} mqttConnectionOptions; enum class ArduinoIoTConnectionStatus { IDLE, @@ -78,59 +63,40 @@ enum class ArduinoIoTCloudEvent { typedef void (*CallbackFunc)(void); typedef void (*OnCloudEventCallback)(void * /* arg */); +/************************************************* + Pure Virtual Class Definition +**************************************************/ class ArduinoIoTCloudClass { public: - ArduinoIoTCloudClass(); - ~ArduinoIoTCloudClass(); - - #ifdef BOARD_HAS_ECCX08 - int begin(ConnectionHandler &connection, String brokerAddress = DEFAULT_BROKER_ADDRESS_SECURE_AUTH, uint16_t brokerPort = DEFAULT_BROKER_PORT_SECURE_AUTH); - #else - int begin(ConnectionHandler &connection, String brokerAddress = DEFAULT_BROKER_ADDRESS_USER_PASS_AUTH, uint16_t brokerPort = DEFAULT_BROKER_PORT_USER_PASS_AUTH); - #endif - int begin(Client &net, String brokerAddress = DEFAULT_BROKER_ADDRESS_SECURE_AUTH, uint16_t brokerPort = DEFAULT_BROKER_PORT_SECURE_AUTH); - // Class constant declaration - static const int MQTT_TRANSMIT_BUFFER_SIZE = 256; - static const int TIMEOUT_FOR_LASTVALUES_SYNC = 10000; - - int connect(); - bool disconnect(); - - inline void update() { - update(NULL); - } - inline void update(int const reconnectionMaxRetries, int const reconnectionTimeoutMs) __attribute__((deprecated)) { - update(NULL); - } - void update(CallbackFunc onSyncCompleteCallback) __attribute__((deprecated)); /* Attention: Function is deprecated - use 'addCallback(ArduinoIoTCloudConnectionEvent::SYNC, &onSync)' for adding a onSyncCallback instead */ + static const int TIMEOUT_FOR_LASTVALUES_SYNC = 10000; + /*Public Virtual Functions*/ + virtual int connect() = 0; + virtual bool disconnect() = 0; - int connected(); - // Clean up existing Mqtt connection, create a new one and initialize it - int reconnect(Client& /* net */); + virtual void update() = 0; + virtual void update(int const reconnectionMaxRetries, int const reconnectionTimeoutMs) __attribute__((deprecated)) = 0; + virtual void update(CallbackFunc onSyncCompleteCallback) __attribute__((deprecated)) = 0; /* Attention: Function is deprecated - use 'addCallback(ArduinoIoTCloudConnectionEvent::SYNC, &onSync)' for adding a onSyncCallback instead */ + + virtual int connected() = 0; + + virtual void connectionCheck() = 0; + + virtual void printDebugInfo() = 0; inline void setThingId(String const thing_id) { _thing_id = thing_id; }; - #ifdef BOARD_ESP - inline void setBoardId(String const device_id) { - _device_id = device_id; - } - inline void setSecretDeviceKey(String const password) { - _password = password; - } - #endif + inline String getThingId() const { return _thing_id; }; - inline String getDeviceId() const { - return _device_id; - }; - inline ConnectionHandler * getConnection() { - return _connection; - } -#define addProperty( v, ...) addPropertyReal(v, #v, __VA_ARGS__) + inline String getDeviceId() const { + return _device_id; + }; + + #define addProperty( v, ...) addPropertyReal(v, #v, __VA_ARGS__) static unsigned long const DEFAULT_MIN_TIME_BETWEEN_UPDATES_MILLIS = 500; /* Data rate throttled to 2 Hz */ @@ -183,76 +149,68 @@ class ArduinoIoTCloudClass { return Thing.addPropertyReal(*p, name, permission); } - void connectionCheck(); - String getBrokerAddress() { - return _brokerAddress; - } - uint16_t getBrokerPort() { - return _brokerPort; - } - void printDebugInfo(); - void addCallback(ArduinoIoTCloudEvent const event, OnCloudEventCallback callback); + void addCallback(ArduinoIoTCloudEvent const event, OnCloudEventCallback callback) { + switch (event) { + case ArduinoIoTCloudEvent::SYNC: _on_sync_event_callback = callback; break; + case ArduinoIoTCloudEvent::CONNECT: _on_connect_event_callback = callback; break; + case ArduinoIoTCloudEvent::DISCONNECT: _on_disconnect_event_callback = callback; break; + } + }; protected: - friend class CloudSerialClass; - int writeStdout(const byte data[], int length); - int writeProperties(const byte data[], int length); - int writeShadowOut(const byte data[], int length); - - // Used to initialize MQTTClient - void mqttClientBegin(); - // Function in charge of perform MQTT reconnection, basing on class parameters(retries,and timeout) - bool mqttReconnect(int const maxRetries, int const timeout); - // Used to retrieve last values from _shadowTopicIn - void requestLastValue(); + + virtual int writeStdout(const byte data[], int length) = 0; + virtual int writeProperties(const byte data[], int length) = 0; + virtual int writeShadowOut(const byte data[], int length) = 0; + + + ArduinoIoTConnectionStatus getIoTStatus() { return _iotStatus; } - private: ArduinoIoTConnectionStatus _iotStatus = ArduinoIoTConnectionStatus::IDLE; - ConnectionHandler * _connection; - static void onMessage(int length); - void handleMessage(int length); - ArduinoIoTSynchronizationStatus _syncStatus = ArduinoIoTSynchronizationStatus::SYNC_STATUS_SYNCHRONIZED; + - void sendPropertiesToCloud(); + + ArduinoIoTSynchronizationStatus _syncStatus = ArduinoIoTSynchronizationStatus::SYNC_STATUS_SYNCHRONIZED; - String _device_id, _thing_id, _brokerAddress; - uint16_t _brokerPort; + + String _device_id, _thing_id; + ArduinoCloudThing Thing; - - #ifdef BOARD_HAS_ECCX08 - BearSSLClient *_sslClient; - #elif defined(BOARD_ESP) - WiFiClientSecure *_sslClient; - String _password; - #endif - - MqttClient *_mqttClient; + int _lastSyncRequestTickTime; - - // Class attribute to define MTTQ topics 2 for stdIn/out and 2 for data, in order to avoid getting previous pupblished payload - String _stdinTopic; - String _stdoutTopic; - String _shadowTopicOut; - String _shadowTopicIn; - String _dataTopicOut; - String _dataTopicIn; - String _otaTopic; - Client *_net; - OnCloudEventCallback _on_sync_event_callback, _on_connect_event_callback, _on_disconnect_event_callback; - static void execCloudEventCallback(OnCloudEventCallback & callback, void * callback_arg); - static void printConnectionStatus(ArduinoIoTConnectionStatus status); + static void execCloudEventCallback(OnCloudEventCallback & callback, void * callback_arg) { + if (callback) { + (*callback)(callback_arg); + } + } + static void printConnectionStatus(ArduinoIoTConnectionStatus status) { + switch (status) { + case ArduinoIoTConnectionStatus::IDLE: Debug.print(DBG_INFO, "Arduino IoT Cloud Connection status: IDLE"); break; + case ArduinoIoTConnectionStatus::ERROR: Debug.print(DBG_ERROR, "Arduino IoT Cloud Connection status: ERROR"); break; + case ArduinoIoTConnectionStatus::CONNECTING: Debug.print(DBG_INFO, "Arduino IoT Cloud Connection status: CONNECTING"); break; + case ArduinoIoTConnectionStatus::RECONNECTING: Debug.print(DBG_INFO, "Arduino IoT Cloud Connection status: RECONNECTING"); break; + case ArduinoIoTConnectionStatus::CONNECTED: Debug.print(DBG_INFO, "Arduino IoT Cloud Connection status: CONNECTED"); break; + case ArduinoIoTConnectionStatus::DISCONNECTED: Debug.print(DBG_ERROR, "Arduino IoT Cloud Connection status: DISCONNECTED"); break; + } + } }; - -extern ArduinoIoTCloudClass ArduinoCloud; +#if defined(ARDUINO_SAMD_MKRGSM1400) || defined(ARDUINO_SAMD_MKRWIFI1010) || \ + defined(ARDUINO_SAMD_MKR1000) || defined(ARDUINO_SAMD_NANO_33_IOT) +#include "ArduinoIoTCloudTCP.h" +extern ArduinoIoTCloudTCP ArduinoCloud; +#elif defined(ARDUINO_SAMD_MKR1300) || defined(ARDUINO_SAMD_MKR1310) +//#include "ArduinoIoTCloudLPWAN.h" +//extern ArduinoIoTCloudLPWAN ArduinoCloud; +#endif #endif diff --git a/src/ArduinoIoTCloudLPWAN.cpp b/src/ArduinoIoTCloudLPWAN.cpp new file mode 100644 index 000000000..803e3c864 --- /dev/null +++ b/src/ArduinoIoTCloudLPWAN.cpp @@ -0,0 +1,200 @@ +/* + This file is part of ArduinoIoTCloud. + + Copyright 2019 ARDUINO SA (http://www.arduino.cc/) + + This software is released under the GNU General Public License version 3, + which covers the main part of arduino-cli. + The terms of this license can be found at: + https://www.gnu.org/licenses/gpl-3.0.en.html + + You can be released from the requirements of the above licenses by purchasing + a commercial license. Buying such a license is mandatory if you want to modify or + otherwise use the software for commercial activities involving the Arduino + software without disclosing the source code of your own applications. To purchase + a commercial license, send an email to license@arduino.cc. +*/ + +#include + +ArduinoIoTCloudLPWAN::ArduinoIoTCloudLPWAN() : + _connection(NULL) +{ + _thing_id = ""; + _lastSyncRequestTickTime = 0; + _on_sync_event_callback(NULL); + _on_connect_event_callback(NULL); + _on_disconnect_event_callback(NULL); + _device_id = ""; +} + +ArduinoIoTCloudLPWAN::~ArduinoIoTCloudLPWAN() { +} + +int ArduinoIoTCloudLPWAN::connect() +{ + _connection->connect(); + return _connection->getStatus(); +} + +bool ArduinoIoTCloudLPWAN::disconnect() +{ + _connection->disconnect(); + return true; +} + +int ArduinoIoTCloudLPWAN::connected() +{ + return _connection->getStatus(); +} + +int ArduinoIoTCloudLPWAN::begin(LPWANConnectionHandler& connection) +{ + _connection = &connection; + _connection->init(); + Thing.begin(); + return 1; +} + +void ArduinoIoTCloudLPWAN::update(CallbackFunc onSyncCompleteCallback) { + // Check if a primitive property wrapper is locally changed + Thing.updateTimestampOnLocallyChangedProperties(); + + connectionCheck(); + + if (_iotStatus != ArduinoIoTConnectionStatus::CONNECTED) { + return; + } + + if (_connection->available()) { + uint8_t msgBuf[DEFAULT_CBOR_LORA_MSG_SIZE]; + uint8_t i = 0; + while (_connection->available()) { + msgBuf[i++] = _connection->read(); + } + + CloudSerial.appendStdin(msgBuf, sizeof(msgBuf)); + + Thing.decode(msgBuf, sizeof(msgBuf)); + } + + + + + sendPropertiesToCloud(); + + + if (onSyncCompleteCallback != NULL) { + (*onSyncCompleteCallback)(); + } + execCloudEventCallback(_on_sync_event_callback, 0 /* callback_arg */); + +} + +void ArduinoIoTCloudLPWAN::connectionCheck() { + if (_connection != NULL) { + + _connection->check(); + + if (_connection->getStatus() != NetworkConnectionState::CONNECTED) { + if (_iotStatus == ArduinoIoTConnectionStatus::CONNECTED) { + _iotStatus = ArduinoIoTConnectionStatus::DISCONNECTED; + printConnectionStatus(_iotStatus); + } + return; + } + } + + switch (_iotStatus) { + case ArduinoIoTConnectionStatus::IDLE: { + _iotStatus = ArduinoIoTConnectionStatus::CONNECTING; + printConnectionStatus(_iotStatus); + } + break; + case ArduinoIoTConnectionStatus::ERROR: { + _iotStatus = ArduinoIoTConnectionStatus::RECONNECTING; + printConnectionStatus(_iotStatus); + } + break; + case ArduinoIoTConnectionStatus::CONNECTED: { + if (_connection->getStatus() != NetworkConnectionState::CONNECTED) { + _iotStatus = ArduinoIoTConnectionStatus::DISCONNECTED; + printConnectionStatus(_iotStatus); + execCloudEventCallback(_on_disconnect_event_callback, 0 /* callback_arg - e.g. could be error code casted to void * */); + } + } + break; + case ArduinoIoTConnectionStatus::DISCONNECTED: { + _iotStatus = ArduinoIoTConnectionStatus::RECONNECTING; + printConnectionStatus(_iotStatus); + } + break; + case ArduinoIoTConnectionStatus::RECONNECTING: { + int const ret_code = connect(); + Debug.print(DBG_INFO, "ArduinoCloud.reconnect()"); + if (ret_code == NetworkConnectionState::INIT) { + _iotStatus = ArduinoIoTConnectionStatus::IDLE; + } + else { + _iotStatus = ArduinoIoTConnectionStatus::ERROR; + } + + /*int const ret_code_reconnect = reconnect(*_net); + Debug.print(DBG_INFO, "ArduinoCloud.reconnect(): %d", ret_code_reconnect); + if (ret_code_reconnect == CONNECT_SUCCESS) { + _iotStatus = ArduinoIoTConnectionStatus::CONNECTED; + printConnectionStatus(_iotStatus); + execCloudEventCallback(_on_connect_event_callback, 0 callback_arg ); + CloudSerial.begin(9600); + CloudSerial.println("Hello from Cloud Serial!"); + }*/ + } + break; + case ArduinoIoTConnectionStatus::CONNECTING: { + int const net_status = _connection->getStatus(); + Debug.print(DBG_VERBOSE, "ArduinoCloud.connect(): %d", net_status); + if (net_status == NetworkConnectionState::CONNECTED) { + _iotStatus = ArduinoIoTConnectionStatus::CONNECTED; + printConnectionStatus(_iotStatus); + execCloudEventCallback(_on_connect_event_callback, 0 /* callback_arg */); + CloudSerial.begin(9600); + CloudSerial.println("Hello from Cloud Serial!"); + } + + } + break; + } +} + +void ArduinoIoTCloudLPWAN::printDebugInfo() { + Debug.print(DBG_INFO, "***** Arduino IoT Cloud LPWAN- configuration info *****"); + Debug.print(DBG_INFO, "Device ID: %s", getDeviceId().c_str()); + Debug.print(DBG_INFO, "Thing ID: %s", getThingId().c_str()); + +} + + +int ArduinoIoTCloudLPWAN::writeProperties(const byte data[], int length) { + _connection->write(data, length); + + return 1; +} + +int ArduinoIoTCloudLPWAN::writeStdout(const byte data[], int length) { + _connection->write(data, length); + return 1; +} + +int ArduinoIoTCloudLPWAN::writeShadowOut(const byte data[], int length) { + _connection->write(data, length); + return 1; +} + +void ArduinoIoTCloudLPWAN::sendPropertiesToCloud() { + uint8_t data[DEFAULT_CBOR_LORA_MSG_SIZE]; + int const length = Thing.encode(data, sizeof(data)); + if (length > 0) { + writeProperties(data, length); + } +} +ArduinoIoTCloudLPWAN ArduinoCloud; diff --git a/src/ArduinoIoTCloudLPWAN.h b/src/ArduinoIoTCloudLPWAN.h new file mode 100644 index 000000000..eec116f38 --- /dev/null +++ b/src/ArduinoIoTCloudLPWAN.h @@ -0,0 +1,61 @@ +/* + This file is part of ArduinoIoTCloud. + + Copyright 2019 ARDUINO SA (http://www.arduino.cc/) + + This software is released under the GNU General Public License version 3, + which covers the main part of arduino-cli. + The terms of this license can be found at: + https://www.gnu.org/licenses/gpl-3.0.en.html + + You can be released from the requirements of the above licenses by purchasing + a commercial license. Buying such a license is mandatory if you want to modify or + otherwise use the software for commercial activities involving the Arduino + software without disclosing the source code of your own applications. To purchase + a commercial license, send an email to license@arduino.cc. +*/ + +#ifndef ARDUINO_IOT_CLOUD_LPWAN_H +#define ARDUINO_IOT_CLOUD_LPWAN_H + +#include +#include + +static uint8_t const DEFAULT_CBOR_LORA_MSG_SIZE = 255; + +class ArduinoIoTCloudLPWAN : public ArduinoIoTCloudClass { + public: + ArduinoIoTCloudLPWAN(); + ~ArduinoIoTCloudLPWAN(); + int connect(); + bool disconnect(); + int connected(); + inline void update() { + update(NULL); + } + inline void update(int const reconnectionMaxRetries, int const reconnectionTimeoutMs) __attribute__((deprecated)) { + update(NULL); + } + void update(CallbackFunc onSyncCompleteCallback) __attribute__((deprecated)); + void connectionCheck(); + void printDebugInfo(); + int begin(LPWANConnectionHandler& connection); + inline LPWANConnectionHandler* getConnection() { + return _connection; + } + + + protected: + friend class CloudSerialClass; + int writeStdout(const byte data[], int length); + int writeProperties(const byte data[], int length); + int writeShadowOut(const byte data[], int length); + + private: + LPWANConnectionHandler* _connection; + +}; + +extern ArduinoIoTCloudLPWAN ArduinoCloud; + +#endif \ No newline at end of file diff --git a/src/ArduinoIoTCloudTCP.cpp b/src/ArduinoIoTCloudTCP.cpp new file mode 100644 index 000000000..945e40097 --- /dev/null +++ b/src/ArduinoIoTCloudTCP.cpp @@ -0,0 +1,446 @@ +/* + This file is part of ArduinoIoTCloud. + + Copyright 2019 ARDUINO SA (http://www.arduino.cc/) + + This software is released under the GNU General Public License version 3, + which covers the main part of arduino-cli. + The terms of this license can be found at: + https://www.gnu.org/licenses/gpl-3.0.en.html + + You can be released from the requirements of the above licenses by purchasing + a commercial license. Buying such a license is mandatory if you want to modify or + otherwise use the software for commercial activities involving the Arduino + software without disclosing the source code of your own applications. To purchase + a commercial license, send an email to license@arduino.cc. +*/ +#include +#ifdef BOARD_HAS_ECCX08 +#include "utility/ECCX08Cert.h" +#include "utility/BearSSLTrustAnchor.h" +#include +#endif + +#ifdef ARDUINO_ARCH_SAMD +#include +RTCZero rtc; +#endif + +#ifdef BOARD_HAS_ECCX08 +const static int keySlot = 0; +const static int compressedCertSlot = 10; +const static int serialNumberAndAuthorityKeyIdentifierSlot = 11; +const static int deviceIdSlot = 12; +#endif + +const static int CONNECT_SUCCESS = 1; +const static int CONNECT_FAILURE = 0; +const static int CONNECT_FAILURE_SUBSCRIBE = -1; + +static unsigned long getTime() { + if (!ArduinoCloud.getConnection()) { + return 0; + } + TcpIpConnectionHandler * connection = ArduinoCloud.getConnection(); + unsigned long time = connection->getTime(); + Debug.print(DBG_DEBUG, "NTP time: %lu", time); + if (!NTPUtils::isTimeValid(time)) { + Debug.print(DBG_ERROR, "Bogus NTP time from API, fallback to UDP method"); + time = NTPUtils(connection->getUDP()).getTime(); + } +#ifdef ARDUINO_ARCH_SAMD + rtc.setEpoch(time); +#endif + return time; +} + +ArduinoIoTCloudTCP::ArduinoIoTCloudTCP(): + _connection(NULL), + + _sslClient(NULL), +#ifdef BOARD_ESP + _password(""), +#endif + _mqttClient(NULL), + + _stdinTopic(""), + _stdoutTopic(""), + _shadowTopicOut(""), + _shadowTopicIn(""), + _dataTopicOut(""), + _dataTopicIn(""), + _otaTopic("") + { + _thing_id=""; + _lastSyncRequestTickTime=0; + _on_sync_event_callback(NULL); + _on_connect_event_callback(NULL); + _on_disconnect_event_callback(NULL); + _device_id=""; +} + + +ArduinoIoTCloudTCP::~ArduinoIoTCloudTCP() { + if (_mqttClient) { + delete _mqttClient; + _mqttClient = NULL; + } + + if (_sslClient) { + delete _sslClient; + _sslClient = NULL; + } +} + +int ArduinoIoTCloudTCP::begin(TcpIpConnectionHandler & connection, String brokerAddress, uint16_t brokerPort) { + _connection = &connection; + _brokerAddress = brokerAddress; + _brokerPort = brokerPort; +#ifdef ARDUINO_ARCH_SAMD + rtc.begin(); +#endif + return begin(_connection->getClient(), _brokerAddress, _brokerPort); +} + +int ArduinoIoTCloudTCP::begin(Client& net, String brokerAddress, uint16_t brokerPort) { + + _net = &net; + // store the broker address as class member + _brokerAddress = brokerAddress; + _brokerPort = brokerPort; + +#ifdef BOARD_HAS_ECCX08 + byte deviceIdBytes[72]; + if (!ECCX08.begin()) { + Debug.print(DBG_ERROR, "Cryptography processor failure. Make sure you have a compatible board."); + return 0; + } + + if (!ECCX08.readSlot(deviceIdSlot, deviceIdBytes, sizeof(deviceIdBytes))) { + Debug.print(DBG_ERROR, "Cryptography processor read failure."); + return 0; + } + _device_id = (char*)deviceIdBytes; + + if (!ECCX08Cert.beginReconstruction(keySlot, compressedCertSlot, serialNumberAndAuthorityKeyIdentifierSlot)) { + Debug.print(DBG_ERROR, "Cryptography certificate reconstruction failure."); + return 0; + } + + ECCX08Cert.setSubjectCommonName(_device_id); + ECCX08Cert.setIssuerCountryName("US"); + ECCX08Cert.setIssuerOrganizationName("Arduino LLC US"); + ECCX08Cert.setIssuerOrganizationalUnitName("IT"); + ECCX08Cert.setIssuerCommonName("Arduino"); + + if (!ECCX08Cert.endReconstruction()) { + Debug.print(DBG_ERROR, "Cryptography certificate reconstruction failure."); + return 0; + } + + ArduinoBearSSL.onGetTime(getTime); +#endif /* BOARD_HAS_ECCX08 */ + + if (_sslClient) { + delete _sslClient; + _sslClient = NULL; + } + +#ifdef BOARD_HAS_ECCX08 + if (_connection != NULL) { + _sslClient = new BearSSLClient(_connection->getClient(), ArduinoIoTCloudTrustAnchor, ArduinoIoTCloudTrustAnchor_NUM); + } + else { + _sslClient = new BearSSLClient(*_net, ArduinoIoTCloudTrustAnchor, ArduinoIoTCloudTrustAnchor_NUM); + } + _sslClient->setEccSlot(keySlot, ECCX08Cert.bytes(), ECCX08Cert.length()); +#elif defined(BOARD_ESP) + _sslClient = new WiFiClientSecure(); + _sslClient->setInsecure(); +#endif + + _mqttClient = new MqttClient(*_sslClient); + +#ifdef BOARD_ESP + _mqttClient->setUsernamePassword(_device_id, _password); +#endif + + mqttClientBegin(); + + Thing.begin(); + return 1; +} + +// private class method used to initialize mqttClient class member. (called in the begin class method) +void ArduinoIoTCloudTCP::mqttClientBegin() { + // MQTT topics definition + _stdoutTopic = "/a/d/" + _device_id + "/s/o"; + _stdinTopic = "/a/d/" + _device_id + "/s/i"; + if (_thing_id == "") { + _dataTopicIn = "/a/d/" + _device_id + "/e/i"; + _dataTopicOut = "/a/d/" + _device_id + "/e/o"; + } + else { + _dataTopicIn = "/a/t/" + _thing_id + "/e/i"; + _dataTopicOut = "/a/t/" + _thing_id + "/e/o"; + _shadowTopicIn = "/a/t/" + _thing_id + "/shadow/i"; + _shadowTopicOut = "/a/t/" + _thing_id + "/shadow/o"; + } + + // use onMessage as callback for received mqtt messages + _mqttClient->onMessage(ArduinoIoTCloudTCP::onMessage); + _mqttClient->setKeepAliveInterval(30 * 1000); + _mqttClient->setConnectionTimeout(1500); + _mqttClient->setId(_device_id.c_str()); +} + + +int ArduinoIoTCloudTCP::connect() { + + if (!_mqttClient->connect(_brokerAddress.c_str(), _brokerPort)) { + return CONNECT_FAILURE; + } + if (_mqttClient->subscribe(_stdinTopic) == 0) { + return CONNECT_FAILURE_SUBSCRIBE; + } + if (_mqttClient->subscribe(_dataTopicIn) == 0) { + return CONNECT_FAILURE_SUBSCRIBE; + } + if (_shadowTopicIn != "") { + if (_mqttClient->subscribe(_shadowTopicIn) == 0) { + return CONNECT_FAILURE_SUBSCRIBE; + } + + _syncStatus = ArduinoIoTSynchronizationStatus::SYNC_STATUS_WAIT_FOR_CLOUD_VALUES; + _lastSyncRequestTickTime = 0; + } + + return CONNECT_SUCCESS; +} + + +bool ArduinoIoTCloudTCP::disconnect() { + _mqttClient->stop(); + + return true; +} + +void ArduinoIoTCloudTCP::update(CallbackFunc onSyncCompleteCallback) { + // Check if a primitive property wrapper is locally changed + Thing.updateTimestampOnLocallyChangedProperties(); + + connectionCheck(); + + if (_iotStatus != ArduinoIoTConnectionStatus::CONNECTED) { + return; + } + + // MTTQClient connected!, poll() used to retrieve data from MQTT broker + _mqttClient->poll(); + + switch (_syncStatus) { + case ArduinoIoTSynchronizationStatus::SYNC_STATUS_SYNCHRONIZED: { + sendPropertiesToCloud(); + } + break; + case ArduinoIoTSynchronizationStatus::SYNC_STATUS_WAIT_FOR_CLOUD_VALUES: { + if (millis() - _lastSyncRequestTickTime > TIMEOUT_FOR_LASTVALUES_SYNC) { + requestLastValue(); + _lastSyncRequestTickTime = millis(); + } + } + break; + case ArduinoIoTSynchronizationStatus::SYNC_STATUS_VALUES_PROCESSED: { + if (onSyncCompleteCallback != NULL) { + (*onSyncCompleteCallback)(); + } + execCloudEventCallback(_on_sync_event_callback, 0 /* callback_arg */); + _syncStatus = ArduinoIoTSynchronizationStatus::SYNC_STATUS_SYNCHRONIZED; + } + break; + } +} + + + +void ArduinoIoTCloudTCP::sendPropertiesToCloud() { + uint8_t data[MQTT_TRANSMIT_BUFFER_SIZE]; + int const length = Thing.encode(data, sizeof(data)); + if (length > 0) { + writeProperties(data, length); + } +} + + +int ArduinoIoTCloudTCP::reconnect(Client& /* net */) { + if (_mqttClient->connected()) { + _mqttClient->stop(); + } + + // Connect to the broker + return connect(); +} + + +int ArduinoIoTCloudTCP::connected() { + return _mqttClient->connected(); +} + +int ArduinoIoTCloudTCP::writeProperties(const byte data[], int length) { + if (!_mqttClient->beginMessage(_dataTopicOut, length, false, 0)) { + return 0; + } + + if (!_mqttClient->write(data, length)) { + return 0; + } + + if (!_mqttClient->endMessage()) { + return 0; + } + + return 1; +} + +int ArduinoIoTCloudTCP::writeStdout(const byte data[], int length) { + if (!_mqttClient->beginMessage(_stdoutTopic, length, false, 0)) { + return 0; + } + + if (!_mqttClient->write(data, length)) { + return 0; + } + + if (!_mqttClient->endMessage()) { + return 0; + } + + return 1; +} + +int ArduinoIoTCloudTCP::writeShadowOut(const byte data[], int length) { + if (!_mqttClient->beginMessage(_shadowTopicOut, length, false, 0)) { + return 0; + } + + if (!_mqttClient->write(data, length)) { + return 0; + } + + if (!_mqttClient->endMessage()) { + return 0; + } + + return 1; +} + +void ArduinoIoTCloudTCP::onMessage(int length) { + ArduinoCloud.handleMessage(length); +} + +void ArduinoIoTCloudTCP::handleMessage(int length) { + String topic = _mqttClient->messageTopic(); + + byte bytes[length]; + + for (int i = 0; i < length; i++) { + bytes[i] = _mqttClient->read(); + } + + if (_stdinTopic == topic) { + CloudSerial.appendStdin((uint8_t*)bytes, length); + } + if (_dataTopicIn == topic) { + Thing.decode((uint8_t*)bytes, length); + } + if ((_shadowTopicIn == topic) && _syncStatus == ArduinoIoTSynchronizationStatus::SYNC_STATUS_WAIT_FOR_CLOUD_VALUES) { + Thing.decode((uint8_t*)bytes, length, true); + sendPropertiesToCloud(); + _syncStatus = ArduinoIoTSynchronizationStatus::SYNC_STATUS_VALUES_PROCESSED; + } +} + +void ArduinoIoTCloudTCP::requestLastValue() { + // Send the getLastValues CBOR message to the cloud + // [{0: "r:m", 3: "getLastValues"}] = 81 A2 00 63 72 3A 6D 03 6D 67 65 74 4C 61 73 74 56 61 6C 75 65 73 + // Use http://cbor.me to easily generate CBOR encoding + const uint8_t CBOR_REQUEST_LAST_VALUE_MSG[] = { 0x81, 0xA2, 0x00, 0x63, 0x72, 0x3A, 0x6D, 0x03, 0x6D, 0x67, 0x65, 0x74, 0x4C, 0x61, 0x73, 0x74, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x73 }; + writeShadowOut(CBOR_REQUEST_LAST_VALUE_MSG, sizeof(CBOR_REQUEST_LAST_VALUE_MSG)); +} + +void ArduinoIoTCloudTCP::connectionCheck() { + + if (_connection != NULL) { + + _connection->check(); + + if (_connection->getStatus() != NetworkConnectionState::CONNECTED) { + if (_iotStatus == ArduinoIoTConnectionStatus::CONNECTED) { + _iotStatus = ArduinoIoTConnectionStatus::DISCONNECTED; + printConnectionStatus(_iotStatus); + } + return; + } + } + + switch (_iotStatus) { + case ArduinoIoTConnectionStatus::IDLE: { + _iotStatus = ArduinoIoTConnectionStatus::CONNECTING; + printConnectionStatus(_iotStatus); + } + break; + case ArduinoIoTConnectionStatus::ERROR: { + _iotStatus = ArduinoIoTConnectionStatus::RECONNECTING; + printConnectionStatus(_iotStatus); + } + break; + case ArduinoIoTConnectionStatus::CONNECTED: { + if (!_mqttClient->connected()) { + _iotStatus = ArduinoIoTConnectionStatus::DISCONNECTED; + printConnectionStatus(_iotStatus); + execCloudEventCallback(_on_disconnect_event_callback, 0 /* callback_arg - e.g. could be error code casted to void * */); + } + } + break; + case ArduinoIoTConnectionStatus::DISCONNECTED: { + _iotStatus = ArduinoIoTConnectionStatus::RECONNECTING; + printConnectionStatus(_iotStatus); + } + break; + case ArduinoIoTConnectionStatus::RECONNECTING: { + int const ret_code_reconnect = reconnect(*_net); + Debug.print(DBG_INFO, "ArduinoCloud.reconnect(): %d", ret_code_reconnect); + if (ret_code_reconnect == CONNECT_SUCCESS) { + _iotStatus = ArduinoIoTConnectionStatus::CONNECTED; + printConnectionStatus(_iotStatus); + execCloudEventCallback(_on_connect_event_callback, 0 /* callback_arg */); + CloudSerial.begin(9600); + CloudSerial.println("Hello from Cloud Serial!"); + } + } + break; + case ArduinoIoTConnectionStatus::CONNECTING: { + int const ret_code_connect = connect(); + Debug.print(DBG_VERBOSE, "ArduinoCloud.connect(): %d", ret_code_connect); + if (ret_code_connect == CONNECT_SUCCESS) { + _iotStatus = ArduinoIoTConnectionStatus::CONNECTED; + printConnectionStatus(_iotStatus); + execCloudEventCallback(_on_connect_event_callback, 0 /* callback_arg */); + CloudSerial.begin(9600); + CloudSerial.println("Hello from Cloud Serial!"); + } + else if (ret_code_connect == CONNECT_FAILURE_SUBSCRIBE) { + Debug.print(DBG_INFO, "ERROR - Please verify your THING ID"); + } + } + break; + } +} + +void ArduinoIoTCloudTCP::printDebugInfo() { + Debug.print(DBG_INFO, "***** Arduino IoT Cloud - configuration info *****"); + Debug.print(DBG_INFO, "Device ID: %s", getDeviceId().c_str()); + Debug.print(DBG_INFO, "Thing ID: %s", getThingId().c_str()); + Debug.print(DBG_INFO, "MQTT Broker: %s:%d", _brokerAddress.c_str(), _brokerPort); +} +ArduinoIoTCloudTCP ArduinoCloud; \ No newline at end of file diff --git a/src/ArduinoIoTCloudTCP.h b/src/ArduinoIoTCloudTCP.h new file mode 100644 index 000000000..32139c812 --- /dev/null +++ b/src/ArduinoIoTCloudTCP.h @@ -0,0 +1,143 @@ +/* + This file is part of ArduinoIoTCloud. + + Copyright 2019 ARDUINO SA (http://www.arduino.cc/) + + This software is released under the GNU General Public License version 3, + which covers the main part of arduino-cli. + The terms of this license can be found at: + https://www.gnu.org/licenses/gpl-3.0.en.html + + You can be released from the requirements of the above licenses by purchasing + a commercial license. Buying such a license is mandatory if you want to modify or + otherwise use the software for commercial activities involving the Arduino + software without disclosing the source code of your own applications. To purchase + a commercial license, send an email to license@arduino.cc. +*/ + +#ifndef ARDUINO_IOT_CLOUD_TCP_H +#define ARDUINO_IOT_CLOUD_TCP_H + +#include +#include + +#ifdef BOARD_HAS_ECCX08 / +#include +#elif defined(BOARD_ESP) +#include +#endif + +#include + +#include "utility/NTPUtils.h" + + +static char const DEFAULT_BROKER_ADDRESS_SECURE_AUTH[] = "mqtts-sa.iot.arduino.cc"; +static uint16_t const DEFAULT_BROKER_PORT_SECURE_AUTH = 8883; +static char const DEFAULT_BROKER_ADDRESS_USER_PASS_AUTH[] = "mqtts-up.iot.arduino.cc"; +static uint16_t const DEFAULT_BROKER_PORT_USER_PASS_AUTH = 8884; + +// Declaration of the struct for the mqtt connection options +typedef struct { + int keepAlive; + bool cleanSession; + int timeout; +} mqttConnectionOptions; + + +class ArduinoIoTCloudTCP: public ArduinoIoTCloudClass +{ + public: + ArduinoIoTCloudTCP(); + ~ArduinoIoTCloudTCP(); + int connect(); + bool disconnect(); + int connected(); + inline void update() { + update(NULL); + } + inline void update(int const reconnectionMaxRetries, int const reconnectionTimeoutMs) __attribute__((deprecated)) { + update(NULL); + } + void update(CallbackFunc onSyncCompleteCallback) __attribute__((deprecated)); + void connectionCheck(); + void printDebugInfo(); + #ifdef BOARD_HAS_ECCX08 + int begin(TcpIpConnectionHandler & connection, String brokerAddress = DEFAULT_BROKER_ADDRESS_SECURE_AUTH, uint16_t brokerPort = DEFAULT_BROKER_PORT_SECURE_AUTH); + #else + int begin(TcpIpConnectionHandler & connection, String brokerAddress = DEFAULT_BROKER_ADDRESS_USER_PASS_AUTH, uint16_t brokerPort = DEFAULT_BROKER_PORT_USER_PASS_AUTH); + #endif + int begin(Client& net, String brokerAddress = DEFAULT_BROKER_ADDRESS_SECURE_AUTH, uint16_t brokerPort = DEFAULT_BROKER_PORT_SECURE_AUTH); + // Class constant declaration + static const int MQTT_TRANSMIT_BUFFER_SIZE = 256; + + #ifdef BOARD_ESP + inline void setBoardId(String const device_id) { + _device_id = device_id; + } + inline void setSecretDeviceKey(String const password) { + _password = password; + } + #endif + + inline TcpIpConnectionHandler * getConnection() { + return _connection; + } + + String getBrokerAddress() { + return _brokerAddress; + } + uint16_t getBrokerPort() { + return _brokerPort; + } + + // Clean up existing Mqtt connection, create a new one and initialize it + int reconnect(Client& /* net */); + + protected: + friend class CloudSerialClass; + // Used to initialize MQTTClient + void mqttClientBegin(); + // Function in charge of perform MQTT reconnection, basing on class parameters(retries,and timeout) + bool mqttReconnect(int const maxRetries, int const timeout); + // Used to retrieve last values from _shadowTopicIn + int writeStdout(const byte data[], int length); + int writeProperties(const byte data[], int length); + int writeShadowOut(const byte data[], int length); + + void requestLastValue(); + + private: + TcpIpConnectionHandler * _connection; + String _brokerAddress; + uint16_t _brokerPort; + + #ifdef BOARD_HAS_ECCX08 + BearSSLClient* _sslClient; + #elif defined(BOARD_ESP) + WiFiClientSecure* _sslClient; + String _password; + #endif + + MqttClient* _mqttClient; + + // Class attribute to define MTTQ topics 2 for stdIn/out and 2 for data, in order to avoid getting previous pupblished payload + String _stdinTopic; + String _stdoutTopic; + String _shadowTopicOut; + String _shadowTopicIn; + String _dataTopicOut; + String _dataTopicIn; + String _otaTopic; + Client* _net; + + static void onMessage(int length); + + void handleMessage(int length); + + void sendPropertiesToCloud(); +}; + +extern ArduinoIoTCloudTCP ArduinoCloud; + +#endif \ No newline at end of file diff --git a/src/ArduinoIoTCloud_Defines.h b/src/ArduinoIoTCloud_Defines.h index 7b99f11b5..29d6a4cc8 100644 --- a/src/ArduinoIoTCloud_Defines.h +++ b/src/ArduinoIoTCloud_Defines.h @@ -22,6 +22,13 @@ defined(ARDUINO_SAMD_MKR1000) || defined(ARDUINO_SAMD_NANO_33_IOT) || \ defined(ARDUINO_SAMD_MKRNB1500) #define BOARD_HAS_ECCX08 + #define HAS_TCP +#endif + + + +#if defined(ARDUINO_SAMD_MKR1300) || defined(ARDUINO_SAMD_MKR1310) +// TODO set BOARD_HAS_LORA #endif #if defined(ARDUINO_ESP8266_ESP12) || defined(ARDUINO_ARCH_ESP32) || defined(ESP8266) diff --git a/src/CloudSerial.h b/src/CloudSerial.h index b27811e52..4c9cef3d3 100644 --- a/src/CloudSerial.h +++ b/src/CloudSerial.h @@ -28,7 +28,11 @@ #define CLOUD_SERIAL_TX_BUFFER_SIZE 64 #define CLOUD_SERIAL_RX_BUFFER_SIZE 512 -class ArduinoIoTCloudClass; +#ifdef HAS_TCP +class ArduinoIoTCloudTCP; +#else +class ArduinoIoTCloudLPWAN; +#endif class CloudSerialClass : public Stream { public: @@ -48,7 +52,12 @@ class CloudSerialClass : public Stream { operator bool(); protected: - friend class ArduinoIoTCloudClass; + #ifdef HAS_TCP + friend class ArduinoIoTCloudTCP; + #else + friend class ArduinoIoTCloudLPWAN; + #endif + void appendStdin(const uint8_t *buffer, size_t size); From 2dd49c0b563e0f5eda2dc47afb04e93c1e6cdaef Mon Sep 17 00:00:00 2001 From: fabio Date: Thu, 5 Dec 2019 16:16:42 +0100 Subject: [PATCH 02/21] Lora working --- src/ArduinoIoTCloud.h | 27 +++++++++++++++------------ src/ArduinoIoTCloudLPWAN.cpp | 32 +++++++++++++------------------- src/ArduinoIoTCloudLPWAN.h | 6 +++++- src/ArduinoIoTCloudTCP.cpp | 12 +++++++++--- src/ArduinoIoTCloudTCP.h | 5 +++++ src/ArduinoIoTCloud_Defines.h | 7 +++---- src/CloudSerial.cpp | 3 +++ src/CloudSerial.h | 14 +++++--------- 8 files changed, 58 insertions(+), 48 deletions(-) diff --git a/src/ArduinoIoTCloud.h b/src/ArduinoIoTCloud.h index f3715611a..124984136 100644 --- a/src/ArduinoIoTCloud.h +++ b/src/ArduinoIoTCloud.h @@ -177,16 +177,17 @@ class ArduinoIoTCloudClass { ArduinoIoTSynchronizationStatus _syncStatus = ArduinoIoTSynchronizationStatus::SYNC_STATUS_SYNCHRONIZED; - String _device_id, _thing_id; + String _device_id = ""; + String _thing_id = ""; ArduinoCloudThing Thing; - int _lastSyncRequestTickTime; + int _lastSyncRequestTickTime = 0; - OnCloudEventCallback _on_sync_event_callback, - _on_connect_event_callback, - _on_disconnect_event_callback; + OnCloudEventCallback _on_sync_event_callback = NULL; + OnCloudEventCallback _on_connect_event_callback = NULL; + OnCloudEventCallback _on_disconnect_event_callback = NULL; static void execCloudEventCallback(OnCloudEventCallback & callback, void * callback_arg) { if (callback) { @@ -204,13 +205,15 @@ class ArduinoIoTCloudClass { } } }; -#if defined(ARDUINO_SAMD_MKRGSM1400) || defined(ARDUINO_SAMD_MKRWIFI1010) || \ - defined(ARDUINO_SAMD_MKR1000) || defined(ARDUINO_SAMD_NANO_33_IOT) -#include "ArduinoIoTCloudTCP.h" -extern ArduinoIoTCloudTCP ArduinoCloud; -#elif defined(ARDUINO_SAMD_MKR1300) || defined(ARDUINO_SAMD_MKR1310) -//#include "ArduinoIoTCloudLPWAN.h" -//extern ArduinoIoTCloudLPWAN ArduinoCloud; + +#if defined(ARDUINO_SAMD_MKRGSM1400) || defined(ARDUINO_SAMD_MKRWIFI1010) || defined(ARDUINO_SAMD_MKR1000) || defined(ARDUINO_SAMD_NANO_33_IOT) + //#error HAS_TCP + #include "ArduinoIoTCloudTCP.h" + extern ArduinoIoTCloudTCP ArduinoCloud; +#elif defined(ARDUINO_SAMD_MKRWAN1300) || defined(ARDUINO_SAMD_MKRWAN1310) + //#error HAS_LORA + #include "ArduinoIoTCloudLPWAN.h" + //extern ArduinoIoTCloudLPWAN ArduinoCloud; #endif #endif diff --git a/src/ArduinoIoTCloudLPWAN.cpp b/src/ArduinoIoTCloudLPWAN.cpp index 803e3c864..c5499f0db 100644 --- a/src/ArduinoIoTCloudLPWAN.cpp +++ b/src/ArduinoIoTCloudLPWAN.cpp @@ -15,17 +15,19 @@ a commercial license, send an email to license@arduino.cc. */ +#if defined(ARDUINO_SAMD_MKRWAN1300) || defined(ARDUINO_SAMD_MKRWAN1310) + #include ArduinoIoTCloudLPWAN::ArduinoIoTCloudLPWAN() : _connection(NULL) { - _thing_id = ""; + /*_thing_id = ""; _lastSyncRequestTickTime = 0; _on_sync_event_callback(NULL); _on_connect_event_callback(NULL); _on_disconnect_event_callback(NULL); - _device_id = ""; + _device_id = "";*/ } ArduinoIoTCloudLPWAN::~ArduinoIoTCloudLPWAN() { @@ -34,7 +36,8 @@ ArduinoIoTCloudLPWAN::~ArduinoIoTCloudLPWAN() { int ArduinoIoTCloudLPWAN::connect() { _connection->connect(); - return _connection->getStatus(); + int state = _connection->getStatus() == NetworkConnectionState::INIT ? 1 : 0; + return state; } bool ArduinoIoTCloudLPWAN::disconnect() @@ -45,7 +48,8 @@ bool ArduinoIoTCloudLPWAN::disconnect() int ArduinoIoTCloudLPWAN::connected() { - return _connection->getStatus(); + int state = _connection->getStatus() == NetworkConnectionState::INIT ? 1 : 0; + return state; } int ArduinoIoTCloudLPWAN::begin(LPWANConnectionHandler& connection) @@ -73,8 +77,6 @@ void ArduinoIoTCloudLPWAN::update(CallbackFunc onSyncCompleteCallback) { msgBuf[i++] = _connection->read(); } - CloudSerial.appendStdin(msgBuf, sizeof(msgBuf)); - Thing.decode(msgBuf, sizeof(msgBuf)); } @@ -132,33 +134,22 @@ void ArduinoIoTCloudLPWAN::connectionCheck() { case ArduinoIoTConnectionStatus::RECONNECTING: { int const ret_code = connect(); Debug.print(DBG_INFO, "ArduinoCloud.reconnect()"); - if (ret_code == NetworkConnectionState::INIT) { + if (ret_code == 1) { _iotStatus = ArduinoIoTConnectionStatus::IDLE; } else { _iotStatus = ArduinoIoTConnectionStatus::ERROR; } - /*int const ret_code_reconnect = reconnect(*_net); - Debug.print(DBG_INFO, "ArduinoCloud.reconnect(): %d", ret_code_reconnect); - if (ret_code_reconnect == CONNECT_SUCCESS) { - _iotStatus = ArduinoIoTConnectionStatus::CONNECTED; - printConnectionStatus(_iotStatus); - execCloudEventCallback(_on_connect_event_callback, 0 callback_arg ); - CloudSerial.begin(9600); - CloudSerial.println("Hello from Cloud Serial!"); - }*/ } break; case ArduinoIoTConnectionStatus::CONNECTING: { - int const net_status = _connection->getStatus(); + NetworkConnectionState net_status = _connection->getStatus(); Debug.print(DBG_VERBOSE, "ArduinoCloud.connect(): %d", net_status); if (net_status == NetworkConnectionState::CONNECTED) { _iotStatus = ArduinoIoTConnectionStatus::CONNECTED; printConnectionStatus(_iotStatus); execCloudEventCallback(_on_connect_event_callback, 0 /* callback_arg */); - CloudSerial.begin(9600); - CloudSerial.println("Hello from Cloud Serial!"); } } @@ -197,4 +188,7 @@ void ArduinoIoTCloudLPWAN::sendPropertiesToCloud() { writeProperties(data, length); } } +//#error MULTIPLE_DEFINITION ArduinoIoTCloudLPWAN ArduinoCloud; + +#endif \ No newline at end of file diff --git a/src/ArduinoIoTCloudLPWAN.h b/src/ArduinoIoTCloudLPWAN.h index eec116f38..c3a6bef88 100644 --- a/src/ArduinoIoTCloudLPWAN.h +++ b/src/ArduinoIoTCloudLPWAN.h @@ -18,6 +18,8 @@ #ifndef ARDUINO_IOT_CLOUD_LPWAN_H #define ARDUINO_IOT_CLOUD_LPWAN_H +//#ifdef defined(ARDUINO_SAMD_MKRWAN1300) || defined(ARDUINO_SAMD_MKRWAN1310) + #include #include @@ -46,16 +48,18 @@ class ArduinoIoTCloudLPWAN : public ArduinoIoTCloudClass { protected: - friend class CloudSerialClass; int writeStdout(const byte data[], int length); int writeProperties(const byte data[], int length); int writeShadowOut(const byte data[], int length); private: LPWANConnectionHandler* _connection; + void sendPropertiesToCloud(); }; extern ArduinoIoTCloudLPWAN ArduinoCloud; +//#endif + #endif \ No newline at end of file diff --git a/src/ArduinoIoTCloudTCP.cpp b/src/ArduinoIoTCloudTCP.cpp index 945e40097..93f3834c1 100644 --- a/src/ArduinoIoTCloudTCP.cpp +++ b/src/ArduinoIoTCloudTCP.cpp @@ -14,6 +14,8 @@ software without disclosing the source code of your own applications. To purchase a commercial license, send an email to license@arduino.cc. */ +#if defined(ARDUINO_SAMD_MKRGSM1400) || defined(ARDUINO_SAMD_MKRWIFI1010) || defined(ARDUINO_SAMD_MKR1000) || defined(ARDUINO_SAMD_NANO_33_IOT) + #include #ifdef BOARD_HAS_ECCX08 #include "utility/ECCX08Cert.h" @@ -71,12 +73,12 @@ ArduinoIoTCloudTCP::ArduinoIoTCloudTCP(): _dataTopicIn(""), _otaTopic("") { - _thing_id=""; + /*_thing_id=""; _lastSyncRequestTickTime=0; _on_sync_event_callback(NULL); _on_connect_event_callback(NULL); _on_disconnect_event_callback(NULL); - _device_id=""; + _device_id="";*/ } @@ -443,4 +445,8 @@ void ArduinoIoTCloudTCP::printDebugInfo() { Debug.print(DBG_INFO, "Thing ID: %s", getThingId().c_str()); Debug.print(DBG_INFO, "MQTT Broker: %s:%d", _brokerAddress.c_str(), _brokerPort); } -ArduinoIoTCloudTCP ArduinoCloud; \ No newline at end of file + +//#error DEFINING_ARDUINOCLOUD2 +ArduinoIoTCloudTCP ArduinoCloud; + +#endif \ No newline at end of file diff --git a/src/ArduinoIoTCloudTCP.h b/src/ArduinoIoTCloudTCP.h index 32139c812..dc09e56ac 100644 --- a/src/ArduinoIoTCloudTCP.h +++ b/src/ArduinoIoTCloudTCP.h @@ -18,6 +18,9 @@ #ifndef ARDUINO_IOT_CLOUD_TCP_H #define ARDUINO_IOT_CLOUD_TCP_H +//#ifdef defined(ARDUINO_SAMD_MKRGSM1400) || defined(ARDUINO_SAMD_MKRWIFI1010) || defined(ARDUINO_SAMD_MKR1000) || defined(ARDUINO_SAMD_NANO_33_IOT) + + #include #include @@ -140,4 +143,6 @@ class ArduinoIoTCloudTCP: public ArduinoIoTCloudClass extern ArduinoIoTCloudTCP ArduinoCloud; +//#endif + #endif \ No newline at end of file diff --git a/src/ArduinoIoTCloud_Defines.h b/src/ArduinoIoTCloud_Defines.h index 29d6a4cc8..c4ef0253a 100644 --- a/src/ArduinoIoTCloud_Defines.h +++ b/src/ArduinoIoTCloud_Defines.h @@ -23,12 +23,11 @@ defined(ARDUINO_SAMD_MKRNB1500) #define BOARD_HAS_ECCX08 #define HAS_TCP + //#error HAS_TCP_SET #endif - - -#if defined(ARDUINO_SAMD_MKR1300) || defined(ARDUINO_SAMD_MKR1310) -// TODO set BOARD_HAS_LORA +#if defined(ARDUINO_SAMD_MKRWAN1300) || defined(ARDUINO_SAMD_MKRWAN1310) + #define HAS_LORA #endif #if defined(ARDUINO_ESP8266_ESP12) || defined(ARDUINO_ARCH_ESP32) || defined(ESP8266) diff --git a/src/CloudSerial.cpp b/src/CloudSerial.cpp index 19f380a76..88097711a 100644 --- a/src/CloudSerial.cpp +++ b/src/CloudSerial.cpp @@ -14,6 +14,7 @@ software without disclosing the source code of your own applications. To purchase a commercial license, send an email to license@arduino.cc. */ +#if defined(ARDUINO_SAMD_MKRGSM1400) || defined(ARDUINO_SAMD_MKRWIFI1010) || defined(ARDUINO_SAMD_MKR1000) || defined(ARDUINO_SAMD_NANO_33_IOT) || defined(ARDUINO_ESP8266_ESP12) || defined(ARDUINO_ARCH_ESP32) || defined(ESP8266) #include "ArduinoIoTCloud.h" #include "CloudSerial.h" @@ -86,3 +87,5 @@ void CloudSerialClass::appendStdin(const uint8_t *buffer, size_t size) { } CloudSerialClass CloudSerial; + +#endif \ No newline at end of file diff --git a/src/CloudSerial.h b/src/CloudSerial.h index 4c9cef3d3..8232e12a9 100644 --- a/src/CloudSerial.h +++ b/src/CloudSerial.h @@ -28,11 +28,9 @@ #define CLOUD_SERIAL_TX_BUFFER_SIZE 64 #define CLOUD_SERIAL_RX_BUFFER_SIZE 512 -#ifdef HAS_TCP + class ArduinoIoTCloudTCP; -#else -class ArduinoIoTCloudLPWAN; -#endif + class CloudSerialClass : public Stream { public: @@ -52,11 +50,9 @@ class CloudSerialClass : public Stream { operator bool(); protected: - #ifdef HAS_TCP - friend class ArduinoIoTCloudTCP; - #else - friend class ArduinoIoTCloudLPWAN; - #endif + + friend class ArduinoIoTCloudTCP; + void appendStdin(const uint8_t *buffer, size_t size); From 0d14d572dce6ae425b588da420b2fea3031f9f47 Mon Sep 17 00:00:00 2001 From: fabio Date: Fri, 6 Dec 2019 11:45:27 +0100 Subject: [PATCH 03/21] add property tag --- src/ArduinoIoTCloud.h | 80 +++++++++++++++++++++++++++--------- src/ArduinoIoTCloudLPWAN.cpp | 2 +- 2 files changed, 62 insertions(+), 20 deletions(-) diff --git a/src/ArduinoIoTCloud.h b/src/ArduinoIoTCloud.h index 124984136..0609481df 100644 --- a/src/ArduinoIoTCloud.h +++ b/src/ArduinoIoTCloud.h @@ -100,7 +100,11 @@ class ArduinoIoTCloudClass { static unsigned long const DEFAULT_MIN_TIME_BETWEEN_UPDATES_MILLIS = 500; /* Data rate throttled to 2 Hz */ - void addPropertyReal(ArduinoCloudProperty& property, String name, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(ArduinoCloudProperty& property) = CLOUD_WINS) { + void addPropertyReal(ArduinoCloudProperty & property, String name, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS) { + addPropertyReal( property, name, -1, permission_type, seconds, fn, minDelta, synFn); + } + + void addPropertyReal( ArduinoCloudProperty& property, String name, int tag, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(ArduinoCloudProperty& property) = CLOUD_WINS ) { Permission permission = Permission::ReadWrite; if (permission_type == READ) { permission = Permission::Read; @@ -111,42 +115,80 @@ class ArduinoIoTCloudClass { } if (seconds == ON_CHANGE) { - Thing.addPropertyReal(property, name, permission).publishOnChange(minDelta, DEFAULT_MIN_TIME_BETWEEN_UPDATES_MILLIS).onUpdate(fn).onSync(synFn); + Thing.addPropertyReal(property, name, permission, tag).publishOnChange(minDelta, DEFAULT_MIN_TIME_BETWEEN_UPDATES_MILLIS).onUpdate(fn).onSync(synFn); } else { - Thing.addPropertyReal(property, name, permission).publishEvery(seconds).onUpdate(fn).onSync(synFn); + Thing.addPropertyReal(property, name, permission, tag).publishEvery(seconds).onUpdate(fn).onSync(synFn); } } - void addPropertyReal(bool& property, String name, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS) { + + void addPropertyReal(bool& property, String name, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS) { + addPropertyReal( property, name, -1, permission_type, seconds, fn, minDelta, synFn); + } + + void addPropertyReal( bool& property, String name, int tag, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS) { ArduinoCloudProperty *p = new CloudWrapperBool(property); - addPropertyReal(*p, name, permission_type, seconds, fn, minDelta, synFn); + addPropertyReal(*p, name, tag, permission_type, seconds, fn, minDelta, synFn); } - ArduinoCloudProperty& addPropertyReal(bool& property, String name, Permission const permission) { + ArduinoCloudProperty& addPropertyReal(bool& property, String name, Permission const permission) { + return addPropertyReal(property, name, -1, permission); + } + ArduinoCloudProperty& addPropertyReal(bool& property, String name, int tag, Permission const permission) { ArduinoCloudProperty *p = new CloudWrapperBool(property); - return Thing.addPropertyReal(*p, name, permission); + return Thing.addPropertyReal(*p, name, permission, tag); } - void addPropertyReal(float& property, String name, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS) { + + void addPropertyReal(float& property, String name, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS) { + addPropertyReal(property, name, -1, permission_type, seconds, fn, minDelta, synFn); + } + + void addPropertyReal( float& property, String name, int tag, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS) { ArduinoCloudProperty *p = new CloudWrapperFloat(property); - addPropertyReal(*p, name, permission_type, seconds, fn, minDelta, synFn); + addPropertyReal(*p, name, tag, permission_type, seconds, fn, minDelta, synFn); } - ArduinoCloudProperty& addPropertyReal(float& property, String name, Permission const permission) { + + ArduinoCloudProperty& addPropertyReal(float& property, String name, Permission const permission) { + return addPropertyReal( property, name, -1, permission); + } + + ArduinoCloudProperty& addPropertyReal( float& property, String name, int tag, Permission const permission ) { ArduinoCloudProperty *p = new CloudWrapperFloat(property); - return Thing.addPropertyReal(*p, name, permission); + return Thing.addPropertyReal(*p, name, permission, tag); } - void addPropertyReal(int& property, String name, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS) { + + void addPropertyReal(int& property, String name, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS) { + addPropertyReal(property, name, -1, permission_type, seconds,fn,minDelta,synFn); + } + + void addPropertyReal( int& property, String name, int tag, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS) { ArduinoCloudProperty *p = new CloudWrapperInt(property); - addPropertyReal(*p, name, permission_type, seconds, fn, minDelta, synFn); + addPropertyReal(*p, name, tag, permission_type, seconds, fn, minDelta, synFn); } - ArduinoCloudProperty& addPropertyReal(int& property, String name, Permission const permission) { + + ArduinoCloudProperty& addPropertyReal(int& property, String name, Permission const permission) { + return addPropertyReal(property, name, -1, permission); + } + + ArduinoCloudProperty& addPropertyReal( int& property, String name, int tag, Permission const permission) { ArduinoCloudProperty *p = new CloudWrapperInt(property); - return Thing.addPropertyReal(*p, name, permission); + return Thing.addPropertyReal(*p, name, permission, tag); } - void addPropertyReal(String& property, String name, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS) { + + void addPropertyReal(String& property, String name, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS) { + addPropertyReal( property, name, -1, permission_type, seconds, fn, minDelta, synFn); + } + + void addPropertyReal( String& property, String name, int tag, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS) { ArduinoCloudProperty *p = new CloudWrapperString(property); - addPropertyReal(*p, name, permission_type, seconds, fn, minDelta, synFn); + addPropertyReal(*p, name, tag, permission_type, seconds, fn, minDelta, synFn); } - ArduinoCloudProperty& addPropertyReal(String& property, String name, Permission const permission) { + + ArduinoCloudProperty& addPropertyReal(String& property, String name, Permission const permission) { + return addPropertyReal(property, name, -1, permission); + } + + ArduinoCloudProperty& addPropertyReal(String& property, String name, int tag, Permission const permission) { ArduinoCloudProperty *p = new CloudWrapperString(property); - return Thing.addPropertyReal(*p, name, permission); + return Thing.addPropertyReal(*p, name, permission, tag); } void addCallback(ArduinoIoTCloudEvent const event, OnCloudEventCallback callback) { diff --git a/src/ArduinoIoTCloudLPWAN.cpp b/src/ArduinoIoTCloudLPWAN.cpp index c5499f0db..d2fe3f788 100644 --- a/src/ArduinoIoTCloudLPWAN.cpp +++ b/src/ArduinoIoTCloudLPWAN.cpp @@ -183,7 +183,7 @@ int ArduinoIoTCloudLPWAN::writeShadowOut(const byte data[], int length) { void ArduinoIoTCloudLPWAN::sendPropertiesToCloud() { uint8_t data[DEFAULT_CBOR_LORA_MSG_SIZE]; - int const length = Thing.encode(data, sizeof(data)); + int const length = Thing.encode(data, sizeof(data), true); if (length > 0) { writeProperties(data, length); } From 564ded85137c761839333d478599e0574b95f49c Mon Sep 17 00:00:00 2001 From: fabio Date: Fri, 6 Dec 2019 17:24:23 +0100 Subject: [PATCH 04/21] add retry --- src/ArduinoIoTCloudLPWAN.cpp | 32 +++++++++++++++++++++++++++----- src/ArduinoIoTCloudLPWAN.h | 27 ++++++++++++++++++++++++++- 2 files changed, 53 insertions(+), 6 deletions(-) diff --git a/src/ArduinoIoTCloudLPWAN.cpp b/src/ArduinoIoTCloudLPWAN.cpp index d2fe3f788..104d2708f 100644 --- a/src/ArduinoIoTCloudLPWAN.cpp +++ b/src/ArduinoIoTCloudLPWAN.cpp @@ -52,10 +52,13 @@ int ArduinoIoTCloudLPWAN::connected() return state; } -int ArduinoIoTCloudLPWAN::begin(LPWANConnectionHandler& connection) +int ArduinoIoTCloudLPWAN::begin(LPWANConnectionHandler& connection, bool retry) { _connection = &connection; _connection->init(); + _retryEnable = retry; + _maxNumRetry = 5; + _intervalRetry = 1000; Thing.begin(); return 1; } @@ -166,18 +169,37 @@ void ArduinoIoTCloudLPWAN::printDebugInfo() { int ArduinoIoTCloudLPWAN::writeProperties(const byte data[], int length) { - _connection->write(data, length); - + int retcode = _connection->write(data, length); + int i = 0; + while (_retryEnable && retcode < 0 && i < _maxNumRetry) { + delay(_intervalRetry); + retcode = _connection->write(data, length); + i++; + } + return 1; } int ArduinoIoTCloudLPWAN::writeStdout(const byte data[], int length) { - _connection->write(data, length); + int retcode = _connection->write(data, length); + int i = 0; + while (_retryEnable && retcode < 0 && i < _maxNumRetry) { + delay(_intervalRetry); + retcode = _connection->write(data, length); + i++; + } + return 1; } int ArduinoIoTCloudLPWAN::writeShadowOut(const byte data[], int length) { - _connection->write(data, length); + int retcode = _connection->write(data, length); + int i = 0; + while (_retryEnable && retcode < 0 && i < _maxNumRetry) { + delay(_intervalRetry); + retcode = _connection->write(data, length); + i++; + } return 1; } diff --git a/src/ArduinoIoTCloudLPWAN.h b/src/ArduinoIoTCloudLPWAN.h index c3a6bef88..0c1d19cd2 100644 --- a/src/ArduinoIoTCloudLPWAN.h +++ b/src/ArduinoIoTCloudLPWAN.h @@ -41,11 +41,33 @@ class ArduinoIoTCloudLPWAN : public ArduinoIoTCloudClass { void update(CallbackFunc onSyncCompleteCallback) __attribute__((deprecated)); void connectionCheck(); void printDebugInfo(); - int begin(LPWANConnectionHandler& connection); + int begin(LPWANConnectionHandler& connection, bool retry = false); inline LPWANConnectionHandler* getConnection() { return _connection; } + bool isRetryEnabled() { + return _retryEnable; + } + + void enableRetry(bool val) { + _retryEnable = val; + } + + int getMaxRetry() { + return _maxNumRetry; + } + void setMaxRetry(int val) { + _maxNumRetry = val; + } + + long getIntervalRetry() { + return _intervalRetry; + } + + void setIntervalRetry(long val) { + _intervalRetry = val; + } protected: int writeStdout(const byte data[], int length); @@ -55,6 +77,9 @@ class ArduinoIoTCloudLPWAN : public ArduinoIoTCloudClass { private: LPWANConnectionHandler* _connection; void sendPropertiesToCloud(); + bool _retryEnable; + int _maxNumRetry; + long _intervalRetry; }; From a37f8cca052bf90774a1fef32be14734d14683b4 Mon Sep 17 00:00:00 2001 From: fabik111 Date: Mon, 9 Dec 2019 18:05:45 +0100 Subject: [PATCH 05/21] delete not used cpp --- src/ArduinoIoTCloud.cpp | 460 ---------------------------------------- 1 file changed, 460 deletions(-) delete mode 100644 src/ArduinoIoTCloud.cpp diff --git a/src/ArduinoIoTCloud.cpp b/src/ArduinoIoTCloud.cpp deleted file mode 100644 index 56653f6c4..000000000 --- a/src/ArduinoIoTCloud.cpp +++ /dev/null @@ -1,460 +0,0 @@ -/* - This file is part of ArduinoIoTCloud. - - Copyright 2019 ARDUINO SA (http://www.arduino.cc/) - - This software is released under the GNU General Public License version 3, - which covers the main part of arduino-cli. - The terms of this license can be found at: - https://www.gnu.org/licenses/gpl-3.0.en.html - - You can be released from the requirements of the above licenses by purchasing - a commercial license. Buying such a license is mandatory if you want to modify or - otherwise use the software for commercial activities involving the Arduino - software without disclosing the source code of your own applications. To purchase - a commercial license, send an email to license@arduino.cc. -*/ - -#include - -#ifdef BOARD_HAS_ECCX08 - #include "utility/ECCX08Cert.h" - #include "utility/BearSSLTrustAnchor.h" - #include -#endif - -#ifdef ARDUINO_ARCH_SAMD - #include - RTCZero rtc; -#endif - -#ifdef BOARD_HAS_ECCX08 - const static int keySlot = 0; - const static int compressedCertSlot = 10; - const static int serialNumberAndAuthorityKeyIdentifierSlot = 11; - const static int deviceIdSlot = 12; -#endif - -const static int CONNECT_SUCCESS = 1; -const static int CONNECT_FAILURE = 0; -const static int CONNECT_FAILURE_SUBSCRIBE = -1; - -static unsigned long getTime() { - if (!ArduinoCloud.getConnection()) { - return 0; - } - ConnectionHandler * connection = ArduinoCloud.getConnection(); - unsigned long time = connection->getTime(); - Debug.print(DBG_DEBUG, "NTP time: %lu", time); - if (!NTPUtils::isTimeValid(time)) { - Debug.print(DBG_ERROR, "Bogus NTP time from API, fallback to UDP method"); - time = NTPUtils(connection->getUDP()).getTime(); - } - #ifdef ARDUINO_ARCH_SAMD - rtc.setEpoch(time); - #endif - return time; -} - -ArduinoIoTCloudClass::ArduinoIoTCloudClass() : - _connection(NULL), - _thing_id(""), - _sslClient(NULL), - #ifdef BOARD_ESP - _password(""), - #endif - _mqttClient(NULL), - _lastSyncRequestTickTime(0), - _stdinTopic(""), - _stdoutTopic(""), - _shadowTopicOut(""), - _shadowTopicIn(""), - _dataTopicOut(""), - _dataTopicIn(""), - _otaTopic(""), - _on_sync_event_callback(NULL), - _on_connect_event_callback(NULL), - _on_disconnect_event_callback(NULL), - _device_id("") {} - -ArduinoIoTCloudClass::~ArduinoIoTCloudClass() { - if (_mqttClient) { - delete _mqttClient; - _mqttClient = NULL; - } - - if (_sslClient) { - delete _sslClient; - _sslClient = NULL; - } -} - -int ArduinoIoTCloudClass::begin(ConnectionHandler & connection, String brokerAddress, uint16_t brokerPort) { - _connection = &connection; - _brokerAddress = brokerAddress; - _brokerPort = brokerPort; - #ifdef ARDUINO_ARCH_SAMD - rtc.begin(); - #endif - return begin(_connection->getClient(), _brokerAddress, _brokerPort); -} - -int ArduinoIoTCloudClass::begin(Client& net, String brokerAddress, uint16_t brokerPort) { - - _net = &net; - // store the broker address as class member - _brokerAddress = brokerAddress; - _brokerPort = brokerPort; - - #ifdef BOARD_HAS_ECCX08 - byte deviceIdBytes[72]; - if (!ECCX08.begin()) { - Debug.print(DBG_ERROR, "Cryptography processor failure. Make sure you have a compatible board."); - return 0; - } - - if (!ECCX08.readSlot(deviceIdSlot, deviceIdBytes, sizeof(deviceIdBytes))) { - Debug.print(DBG_ERROR, "Cryptography processor read failure."); - return 0; - } - _device_id = (char *)deviceIdBytes; - - if (!ECCX08Cert.beginReconstruction(keySlot, compressedCertSlot, serialNumberAndAuthorityKeyIdentifierSlot)) { - Debug.print(DBG_ERROR, "Cryptography certificate reconstruction failure."); - return 0; - } - - ECCX08Cert.setSubjectCommonName(_device_id); - ECCX08Cert.setIssuerCountryName("US"); - ECCX08Cert.setIssuerOrganizationName("Arduino LLC US"); - ECCX08Cert.setIssuerOrganizationalUnitName("IT"); - ECCX08Cert.setIssuerCommonName("Arduino"); - - if (!ECCX08Cert.endReconstruction()) { - Debug.print(DBG_ERROR, "Cryptography certificate reconstruction failure."); - return 0; - } - - ArduinoBearSSL.onGetTime(getTime); - #endif /* BOARD_HAS_ECCX08 */ - - if (_sslClient) { - delete _sslClient; - _sslClient = NULL; - } - - #ifdef BOARD_HAS_ECCX08 - if (_connection != NULL) { - _sslClient = new BearSSLClient(_connection->getClient(), ArduinoIoTCloudTrustAnchor, ArduinoIoTCloudTrustAnchor_NUM); - } else { - _sslClient = new BearSSLClient(*_net, ArduinoIoTCloudTrustAnchor, ArduinoIoTCloudTrustAnchor_NUM); - } - _sslClient->setEccSlot(keySlot, ECCX08Cert.bytes(), ECCX08Cert.length()); - #elif defined(BOARD_ESP) - _sslClient = new WiFiClientSecure(); - _sslClient->setInsecure(); - #endif - - _mqttClient = new MqttClient(*_sslClient); - - #ifdef BOARD_ESP - _mqttClient->setUsernamePassword(_device_id, _password); - #endif - - mqttClientBegin(); - - Thing.begin(); - return 1; -} - -// private class method used to initialize mqttClient class member. (called in the begin class method) -void ArduinoIoTCloudClass::mqttClientBegin() { - // MQTT topics definition - _stdoutTopic = "/a/d/" + _device_id + "/s/o"; - _stdinTopic = "/a/d/" + _device_id + "/s/i"; - if (_thing_id == "") { - _dataTopicIn = "/a/d/" + _device_id + "/e/i"; - _dataTopicOut = "/a/d/" + _device_id + "/e/o"; - } else { - _dataTopicIn = "/a/t/" + _thing_id + "/e/i"; - _dataTopicOut = "/a/t/" + _thing_id + "/e/o"; - _shadowTopicIn = "/a/t/" + _thing_id + "/shadow/i"; - _shadowTopicOut = "/a/t/" + _thing_id + "/shadow/o"; - } - - // use onMessage as callback for received mqtt messages - _mqttClient->onMessage(ArduinoIoTCloudClass::onMessage); - _mqttClient->setKeepAliveInterval(30 * 1000); - _mqttClient->setConnectionTimeout(1500); - _mqttClient->setId(_device_id.c_str()); -} - -int ArduinoIoTCloudClass::connect() { - - if (!_mqttClient->connect(_brokerAddress.c_str(), _brokerPort)) { - return CONNECT_FAILURE; - } - if (_mqttClient->subscribe(_stdinTopic) == 0) { - return CONNECT_FAILURE_SUBSCRIBE; - } - if (_mqttClient->subscribe(_dataTopicIn) == 0) { - return CONNECT_FAILURE_SUBSCRIBE; - } - if (_shadowTopicIn != "") { - if (_mqttClient->subscribe(_shadowTopicIn) == 0) { - return CONNECT_FAILURE_SUBSCRIBE; - } - - _syncStatus = ArduinoIoTSynchronizationStatus::SYNC_STATUS_WAIT_FOR_CLOUD_VALUES; - _lastSyncRequestTickTime = 0; - } - - return CONNECT_SUCCESS; -} - -bool ArduinoIoTCloudClass::disconnect() { - _mqttClient->stop(); - - return true; -} - -void ArduinoIoTCloudClass::update(CallbackFunc onSyncCompleteCallback) { - // Check if a primitive property wrapper is locally changed - Thing.updateTimestampOnLocallyChangedProperties(); - - connectionCheck(); - - if (_iotStatus != ArduinoIoTConnectionStatus::CONNECTED) { - return; - } - - // MTTQClient connected!, poll() used to retrieve data from MQTT broker - _mqttClient->poll(); - - switch (_syncStatus) { - case ArduinoIoTSynchronizationStatus::SYNC_STATUS_SYNCHRONIZED: { - sendPropertiesToCloud(); - } - break; - case ArduinoIoTSynchronizationStatus::SYNC_STATUS_WAIT_FOR_CLOUD_VALUES: { - if (millis() - _lastSyncRequestTickTime > TIMEOUT_FOR_LASTVALUES_SYNC) { - requestLastValue(); - _lastSyncRequestTickTime = millis(); - } - } - break; - case ArduinoIoTSynchronizationStatus::SYNC_STATUS_VALUES_PROCESSED: { - if (onSyncCompleteCallback != NULL) { - (*onSyncCompleteCallback)(); - } - execCloudEventCallback(_on_sync_event_callback, 0 /* callback_arg */); - _syncStatus = ArduinoIoTSynchronizationStatus::SYNC_STATUS_SYNCHRONIZED; - } - break; - } -} - -void ArduinoIoTCloudClass::sendPropertiesToCloud() { - uint8_t data[MQTT_TRANSMIT_BUFFER_SIZE]; - int const length = Thing.encode(data, sizeof(data)); - if (length > 0) { - writeProperties(data, length); - } -} - -int ArduinoIoTCloudClass::reconnect(Client& /* net */) { - if (_mqttClient->connected()) { - _mqttClient->stop(); - } - - // Connect to the broker - return connect(); -} - -int ArduinoIoTCloudClass::connected() { - return _mqttClient->connected(); -} - -int ArduinoIoTCloudClass::writeProperties(const byte data[], int length) { - if (!_mqttClient->beginMessage(_dataTopicOut, length, false, 0)) { - return 0; - } - - if (!_mqttClient->write(data, length)) { - return 0; - } - - if (!_mqttClient->endMessage()) { - return 0; - } - - return 1; -} - -int ArduinoIoTCloudClass::writeStdout(const byte data[], int length) { - if (!_mqttClient->beginMessage(_stdoutTopic, length, false, 0)) { - return 0; - } - - if (!_mqttClient->write(data, length)) { - return 0; - } - - if (!_mqttClient->endMessage()) { - return 0; - } - - return 1; -} - -int ArduinoIoTCloudClass::writeShadowOut(const byte data[], int length) { - if (!_mqttClient->beginMessage(_shadowTopicOut, length, false, 0)) { - return 0; - } - - if (!_mqttClient->write(data, length)) { - return 0; - } - - if (!_mqttClient->endMessage()) { - return 0; - } - - return 1; -} - -void ArduinoIoTCloudClass::onMessage(int length) { - ArduinoCloud.handleMessage(length); -} - -void ArduinoIoTCloudClass::handleMessage(int length) { - String topic = _mqttClient->messageTopic(); - - byte bytes[length]; - - for (int i = 0; i < length; i++) { - bytes[i] = _mqttClient->read(); - } - - if (_stdinTopic == topic) { - CloudSerial.appendStdin((uint8_t*)bytes, length); - } - if (_dataTopicIn == topic) { - Thing.decode((uint8_t*)bytes, length); - } - if ((_shadowTopicIn == topic) && _syncStatus == ArduinoIoTSynchronizationStatus::SYNC_STATUS_WAIT_FOR_CLOUD_VALUES) { - Thing.decode((uint8_t*)bytes, length, true); - sendPropertiesToCloud(); - _syncStatus = ArduinoIoTSynchronizationStatus::SYNC_STATUS_VALUES_PROCESSED; - } -} - -void ArduinoIoTCloudClass::requestLastValue() { - // Send the getLastValues CBOR message to the cloud - // [{0: "r:m", 3: "getLastValues"}] = 81 A2 00 63 72 3A 6D 03 6D 67 65 74 4C 61 73 74 56 61 6C 75 65 73 - // Use http://cbor.me to easily generate CBOR encoding - const uint8_t CBOR_REQUEST_LAST_VALUE_MSG[] = { 0x81, 0xA2, 0x00, 0x63, 0x72, 0x3A, 0x6D, 0x03, 0x6D, 0x67, 0x65, 0x74, 0x4C, 0x61, 0x73, 0x74, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x73 }; - writeShadowOut(CBOR_REQUEST_LAST_VALUE_MSG, sizeof(CBOR_REQUEST_LAST_VALUE_MSG)); -} - -void ArduinoIoTCloudClass::connectionCheck() { - - if (_connection != NULL) { - - _connection->check(); - - if (_connection->getStatus() != NetworkConnectionState::CONNECTED) { - if (_iotStatus == ArduinoIoTConnectionStatus::CONNECTED) { - _iotStatus = ArduinoIoTConnectionStatus::DISCONNECTED; - printConnectionStatus(_iotStatus); - } - return; - } - } - - switch (_iotStatus) { - case ArduinoIoTConnectionStatus::IDLE: { - _iotStatus = ArduinoIoTConnectionStatus::CONNECTING; - printConnectionStatus(_iotStatus); - } - break; - case ArduinoIoTConnectionStatus::ERROR: { - _iotStatus = ArduinoIoTConnectionStatus::RECONNECTING; - printConnectionStatus(_iotStatus); - } - break; - case ArduinoIoTConnectionStatus::CONNECTED: { - if (!_mqttClient->connected()) { - _iotStatus = ArduinoIoTConnectionStatus::DISCONNECTED; - printConnectionStatus(_iotStatus); - execCloudEventCallback(_on_disconnect_event_callback, 0 /* callback_arg - e.g. could be error code casted to void * */); - } - } - break; - case ArduinoIoTConnectionStatus::DISCONNECTED: { - _iotStatus = ArduinoIoTConnectionStatus::RECONNECTING; - printConnectionStatus(_iotStatus); - } - break; - case ArduinoIoTConnectionStatus::RECONNECTING: { - int const ret_code_reconnect = reconnect(*_net); - Debug.print(DBG_INFO, "ArduinoCloud.reconnect(): %d", ret_code_reconnect); - if (ret_code_reconnect == CONNECT_SUCCESS) { - _iotStatus = ArduinoIoTConnectionStatus::CONNECTED; - printConnectionStatus(_iotStatus); - execCloudEventCallback(_on_connect_event_callback, 0 /* callback_arg */); - CloudSerial.begin(9600); - CloudSerial.println("Hello from Cloud Serial!"); - } - } - break; - case ArduinoIoTConnectionStatus::CONNECTING: { - int const ret_code_connect = connect(); - Debug.print(DBG_VERBOSE, "ArduinoCloud.connect(): %d", ret_code_connect); - if (ret_code_connect == CONNECT_SUCCESS) { - _iotStatus = ArduinoIoTConnectionStatus::CONNECTED; - printConnectionStatus(_iotStatus); - execCloudEventCallback(_on_connect_event_callback, 0 /* callback_arg */); - CloudSerial.begin(9600); - CloudSerial.println("Hello from Cloud Serial!"); - } else if (ret_code_connect == CONNECT_FAILURE_SUBSCRIBE) { - Debug.print(DBG_INFO, "ERROR - Please verify your THING ID"); - } - } - break; - } -} - -void ArduinoIoTCloudClass::printDebugInfo() { - Debug.print(DBG_INFO, "***** Arduino IoT Cloud - configuration info *****"); - Debug.print(DBG_INFO, "Device ID: %s", getDeviceId().c_str()); - Debug.print(DBG_INFO, "Thing ID: %s", getThingId().c_str()); - Debug.print(DBG_INFO, "MQTT Broker: %s:%d", _brokerAddress.c_str(), _brokerPort); -} - -void ArduinoIoTCloudClass::addCallback(ArduinoIoTCloudEvent const event, OnCloudEventCallback callback) { - switch (event) { - case ArduinoIoTCloudEvent::SYNC: _on_sync_event_callback = callback; break; - case ArduinoIoTCloudEvent::CONNECT: _on_connect_event_callback = callback; break; - case ArduinoIoTCloudEvent::DISCONNECT: _on_disconnect_event_callback = callback; break; - } -} - -void ArduinoIoTCloudClass::execCloudEventCallback(OnCloudEventCallback & callback, void * callback_arg) { - if (callback) { - (*callback)(callback_arg); - } -} - -void ArduinoIoTCloudClass::printConnectionStatus(ArduinoIoTConnectionStatus status) { - switch (status) { - case ArduinoIoTConnectionStatus::IDLE: Debug.print(DBG_INFO, "Arduino IoT Cloud Connection status: IDLE"); break; - case ArduinoIoTConnectionStatus::ERROR: Debug.print(DBG_ERROR, "Arduino IoT Cloud Connection status: ERROR"); break; - case ArduinoIoTConnectionStatus::CONNECTING: Debug.print(DBG_INFO, "Arduino IoT Cloud Connection status: CONNECTING"); break; - case ArduinoIoTConnectionStatus::RECONNECTING: Debug.print(DBG_INFO, "Arduino IoT Cloud Connection status: RECONNECTING"); break; - case ArduinoIoTConnectionStatus::CONNECTED: Debug.print(DBG_INFO, "Arduino IoT Cloud Connection status: CONNECTED"); break; - case ArduinoIoTConnectionStatus::DISCONNECTED: Debug.print(DBG_ERROR, "Arduino IoT Cloud Connection status: DISCONNECTED"); break; - } -} - -ArduinoIoTCloudClass ArduinoCloud; From 8ffff4629505ae24c01351fd847f8fdda994d5e9 Mon Sep 17 00:00:00 2001 From: fabio Date: Tue, 10 Dec 2019 09:59:10 +0100 Subject: [PATCH 06/21] code finalized --- src/ArduinoIoTCloud.h | 4 +--- src/ArduinoIoTCloudLPWAN.cpp | 12 ++---------- src/ArduinoIoTCloudLPWAN.h | 3 --- src/ArduinoIoTCloudTCP.cpp | 10 +--------- src/ArduinoIoTCloudTCP.h | 3 --- src/ArduinoIoTCloud_Defines.h | 1 - 6 files changed, 4 insertions(+), 29 deletions(-) diff --git a/src/ArduinoIoTCloud.h b/src/ArduinoIoTCloud.h index 0609481df..4fbfcd8bd 100644 --- a/src/ArduinoIoTCloud.h +++ b/src/ArduinoIoTCloud.h @@ -249,13 +249,11 @@ class ArduinoIoTCloudClass { }; #if defined(ARDUINO_SAMD_MKRGSM1400) || defined(ARDUINO_SAMD_MKRWIFI1010) || defined(ARDUINO_SAMD_MKR1000) || defined(ARDUINO_SAMD_NANO_33_IOT) - //#error HAS_TCP #include "ArduinoIoTCloudTCP.h" extern ArduinoIoTCloudTCP ArduinoCloud; #elif defined(ARDUINO_SAMD_MKRWAN1300) || defined(ARDUINO_SAMD_MKRWAN1310) - //#error HAS_LORA #include "ArduinoIoTCloudLPWAN.h" - //extern ArduinoIoTCloudLPWAN ArduinoCloud; + extern ArduinoIoTCloudLPWAN ArduinoCloud; #endif #endif diff --git a/src/ArduinoIoTCloudLPWAN.cpp b/src/ArduinoIoTCloudLPWAN.cpp index 104d2708f..cc32b7d5f 100644 --- a/src/ArduinoIoTCloudLPWAN.cpp +++ b/src/ArduinoIoTCloudLPWAN.cpp @@ -20,15 +20,7 @@ #include ArduinoIoTCloudLPWAN::ArduinoIoTCloudLPWAN() : - _connection(NULL) -{ - /*_thing_id = ""; - _lastSyncRequestTickTime = 0; - _on_sync_event_callback(NULL); - _on_connect_event_callback(NULL); - _on_disconnect_event_callback(NULL); - _device_id = "";*/ -} + _connection(NULL){} ArduinoIoTCloudLPWAN::~ArduinoIoTCloudLPWAN() { } @@ -210,7 +202,7 @@ void ArduinoIoTCloudLPWAN::sendPropertiesToCloud() { writeProperties(data, length); } } -//#error MULTIPLE_DEFINITION + ArduinoIoTCloudLPWAN ArduinoCloud; #endif \ No newline at end of file diff --git a/src/ArduinoIoTCloudLPWAN.h b/src/ArduinoIoTCloudLPWAN.h index 0c1d19cd2..b221e7270 100644 --- a/src/ArduinoIoTCloudLPWAN.h +++ b/src/ArduinoIoTCloudLPWAN.h @@ -18,8 +18,6 @@ #ifndef ARDUINO_IOT_CLOUD_LPWAN_H #define ARDUINO_IOT_CLOUD_LPWAN_H -//#ifdef defined(ARDUINO_SAMD_MKRWAN1300) || defined(ARDUINO_SAMD_MKRWAN1310) - #include #include @@ -85,6 +83,5 @@ class ArduinoIoTCloudLPWAN : public ArduinoIoTCloudClass { extern ArduinoIoTCloudLPWAN ArduinoCloud; -//#endif #endif \ No newline at end of file diff --git a/src/ArduinoIoTCloudTCP.cpp b/src/ArduinoIoTCloudTCP.cpp index 93f3834c1..6bd0039b8 100644 --- a/src/ArduinoIoTCloudTCP.cpp +++ b/src/ArduinoIoTCloudTCP.cpp @@ -72,14 +72,7 @@ ArduinoIoTCloudTCP::ArduinoIoTCloudTCP(): _dataTopicOut(""), _dataTopicIn(""), _otaTopic("") - { - /*_thing_id=""; - _lastSyncRequestTickTime=0; - _on_sync_event_callback(NULL); - _on_connect_event_callback(NULL); - _on_disconnect_event_callback(NULL); - _device_id="";*/ -} + {} ArduinoIoTCloudTCP::~ArduinoIoTCloudTCP() { @@ -446,7 +439,6 @@ void ArduinoIoTCloudTCP::printDebugInfo() { Debug.print(DBG_INFO, "MQTT Broker: %s:%d", _brokerAddress.c_str(), _brokerPort); } -//#error DEFINING_ARDUINOCLOUD2 ArduinoIoTCloudTCP ArduinoCloud; #endif \ No newline at end of file diff --git a/src/ArduinoIoTCloudTCP.h b/src/ArduinoIoTCloudTCP.h index dc09e56ac..41f5da24c 100644 --- a/src/ArduinoIoTCloudTCP.h +++ b/src/ArduinoIoTCloudTCP.h @@ -18,8 +18,6 @@ #ifndef ARDUINO_IOT_CLOUD_TCP_H #define ARDUINO_IOT_CLOUD_TCP_H -//#ifdef defined(ARDUINO_SAMD_MKRGSM1400) || defined(ARDUINO_SAMD_MKRWIFI1010) || defined(ARDUINO_SAMD_MKR1000) || defined(ARDUINO_SAMD_NANO_33_IOT) - #include #include @@ -143,6 +141,5 @@ class ArduinoIoTCloudTCP: public ArduinoIoTCloudClass extern ArduinoIoTCloudTCP ArduinoCloud; -//#endif #endif \ No newline at end of file diff --git a/src/ArduinoIoTCloud_Defines.h b/src/ArduinoIoTCloud_Defines.h index c4ef0253a..7c2810adf 100644 --- a/src/ArduinoIoTCloud_Defines.h +++ b/src/ArduinoIoTCloud_Defines.h @@ -23,7 +23,6 @@ defined(ARDUINO_SAMD_MKRNB1500) #define BOARD_HAS_ECCX08 #define HAS_TCP - //#error HAS_TCP_SET #endif #if defined(ARDUINO_SAMD_MKRWAN1300) || defined(ARDUINO_SAMD_MKRWAN1310) From 55995401ee6e6d81385292a812d14dd1aaf6644b Mon Sep 17 00:00:00 2001 From: fabio Date: Tue, 10 Dec 2019 17:25:22 +0100 Subject: [PATCH 07/21] fix extern variable --- src/ArduinoIoTCloud.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ArduinoIoTCloud.h b/src/ArduinoIoTCloud.h index 4fbfcd8bd..ee1ed62ce 100644 --- a/src/ArduinoIoTCloud.h +++ b/src/ArduinoIoTCloud.h @@ -250,10 +250,10 @@ class ArduinoIoTCloudClass { #if defined(ARDUINO_SAMD_MKRGSM1400) || defined(ARDUINO_SAMD_MKRWIFI1010) || defined(ARDUINO_SAMD_MKR1000) || defined(ARDUINO_SAMD_NANO_33_IOT) #include "ArduinoIoTCloudTCP.h" - extern ArduinoIoTCloudTCP ArduinoCloud; + #elif defined(ARDUINO_SAMD_MKRWAN1300) || defined(ARDUINO_SAMD_MKRWAN1310) #include "ArduinoIoTCloudLPWAN.h" - extern ArduinoIoTCloudLPWAN ArduinoCloud; + #endif #endif From 1ad815804f1725d220801860e399137d3c319a46 Mon Sep 17 00:00:00 2001 From: fabio Date: Tue, 10 Dec 2019 18:10:06 +0100 Subject: [PATCH 08/21] apply Astyle --- src/ArduinoIoTCloud.h | 160 ++++----- src/ArduinoIoTCloudLPWAN.cpp | 293 ++++++++-------- src/ArduinoIoTCloudLPWAN.h | 110 +++--- src/ArduinoIoTCloudTCP.cpp | 653 +++++++++++++++++------------------ src/ArduinoIoTCloudTCP.h | 195 ++++++----- 5 files changed, 701 insertions(+), 710 deletions(-) diff --git a/src/ArduinoIoTCloud.h b/src/ArduinoIoTCloud.h index ee1ed62ce..e757cbef1 100644 --- a/src/ArduinoIoTCloud.h +++ b/src/ArduinoIoTCloud.h @@ -25,7 +25,7 @@ #include #include -#include "types/CloudWrapperBool.h" +#include "types/CloudWrapperBool.h" #include "types/CloudWrapperFloat.h" #include "types/CloudWrapperInt.h" #include "types/CloudWrapperString.h" @@ -69,8 +69,8 @@ typedef void (*OnCloudEventCallback)(void * /* arg */); class ArduinoIoTCloudClass { public: - static const int TIMEOUT_FOR_LASTVALUES_SYNC = 10000; - /*Public Virtual Functions*/ + static const int TIMEOUT_FOR_LASTVALUES_SYNC = 10000; + /*Public Virtual Functions*/ virtual int connect() = 0; virtual bool disconnect() = 0; @@ -79,32 +79,32 @@ class ArduinoIoTCloudClass { virtual void update(CallbackFunc onSyncCompleteCallback) __attribute__((deprecated)) = 0; /* Attention: Function is deprecated - use 'addCallback(ArduinoIoTCloudConnectionEvent::SYNC, &onSync)' for adding a onSyncCallback instead */ virtual int connected() = 0; - - virtual void connectionCheck() = 0; - virtual void printDebugInfo() = 0; + virtual void connectionCheck() = 0; + + virtual void printDebugInfo() = 0; inline void setThingId(String const thing_id) { _thing_id = thing_id; }; - + inline String getThingId() const { return _thing_id; }; - inline String getDeviceId() const { - return _device_id; - }; + inline String getDeviceId() const { + return _device_id; + }; - #define addProperty( v, ...) addPropertyReal(v, #v, __VA_ARGS__) +#define addProperty( v, ...) addPropertyReal(v, #v, __VA_ARGS__) static unsigned long const DEFAULT_MIN_TIME_BETWEEN_UPDATES_MILLIS = 500; /* Data rate throttled to 2 Hz */ - void addPropertyReal(ArduinoCloudProperty & property, String name, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS) { - addPropertyReal( property, name, -1, permission_type, seconds, fn, minDelta, synFn); - } + void addPropertyReal(ArduinoCloudProperty & property, String name, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS) { + addPropertyReal(property, name, -1, permission_type, seconds, fn, minDelta, synFn); + } - void addPropertyReal( ArduinoCloudProperty& property, String name, int tag, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(ArduinoCloudProperty& property) = CLOUD_WINS ) { + void addPropertyReal(ArduinoCloudProperty& property, String name, int tag, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(ArduinoCloudProperty& property) = CLOUD_WINS) { Permission permission = Permission::ReadWrite; if (permission_type == READ) { permission = Permission::Read; @@ -121,70 +121,70 @@ class ArduinoIoTCloudClass { } } - void addPropertyReal(bool& property, String name, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS) { - addPropertyReal( property, name, -1, permission_type, seconds, fn, minDelta, synFn); - } + void addPropertyReal(bool& property, String name, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS) { + addPropertyReal(property, name, -1, permission_type, seconds, fn, minDelta, synFn); + } - void addPropertyReal( bool& property, String name, int tag, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS) { + void addPropertyReal(bool& property, String name, int tag, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS) { ArduinoCloudProperty *p = new CloudWrapperBool(property); addPropertyReal(*p, name, tag, permission_type, seconds, fn, minDelta, synFn); } - ArduinoCloudProperty& addPropertyReal(bool& property, String name, Permission const permission) { - return addPropertyReal(property, name, -1, permission); - } + ArduinoCloudProperty& addPropertyReal(bool& property, String name, Permission const permission) { + return addPropertyReal(property, name, -1, permission); + } ArduinoCloudProperty& addPropertyReal(bool& property, String name, int tag, Permission const permission) { ArduinoCloudProperty *p = new CloudWrapperBool(property); return Thing.addPropertyReal(*p, name, permission, tag); } - void addPropertyReal(float& property, String name, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS) { - addPropertyReal(property, name, -1, permission_type, seconds, fn, minDelta, synFn); - } + void addPropertyReal(float& property, String name, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS) { + addPropertyReal(property, name, -1, permission_type, seconds, fn, minDelta, synFn); + } - void addPropertyReal( float& property, String name, int tag, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS) { + void addPropertyReal(float& property, String name, int tag, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS) { ArduinoCloudProperty *p = new CloudWrapperFloat(property); addPropertyReal(*p, name, tag, permission_type, seconds, fn, minDelta, synFn); } - ArduinoCloudProperty& addPropertyReal(float& property, String name, Permission const permission) { - return addPropertyReal( property, name, -1, permission); - } + ArduinoCloudProperty& addPropertyReal(float& property, String name, Permission const permission) { + return addPropertyReal(property, name, -1, permission); + } - ArduinoCloudProperty& addPropertyReal( float& property, String name, int tag, Permission const permission ) { + ArduinoCloudProperty& addPropertyReal(float& property, String name, int tag, Permission const permission) { ArduinoCloudProperty *p = new CloudWrapperFloat(property); return Thing.addPropertyReal(*p, name, permission, tag); } - void addPropertyReal(int& property, String name, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS) { - addPropertyReal(property, name, -1, permission_type, seconds,fn,minDelta,synFn); - } + void addPropertyReal(int& property, String name, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS) { + addPropertyReal(property, name, -1, permission_type, seconds, fn, minDelta, synFn); + } - void addPropertyReal( int& property, String name, int tag, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS) { + void addPropertyReal(int& property, String name, int tag, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS) { ArduinoCloudProperty *p = new CloudWrapperInt(property); addPropertyReal(*p, name, tag, permission_type, seconds, fn, minDelta, synFn); } - ArduinoCloudProperty& addPropertyReal(int& property, String name, Permission const permission) { - return addPropertyReal(property, name, -1, permission); - } + ArduinoCloudProperty& addPropertyReal(int& property, String name, Permission const permission) { + return addPropertyReal(property, name, -1, permission); + } - ArduinoCloudProperty& addPropertyReal( int& property, String name, int tag, Permission const permission) { + ArduinoCloudProperty& addPropertyReal(int& property, String name, int tag, Permission const permission) { ArduinoCloudProperty *p = new CloudWrapperInt(property); - return Thing.addPropertyReal(*p, name, permission, tag); + return Thing.addPropertyReal(*p, name, permission, tag); } - void addPropertyReal(String& property, String name, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS) { - addPropertyReal( property, name, -1, permission_type, seconds, fn, minDelta, synFn); - } + void addPropertyReal(String& property, String name, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS) { + addPropertyReal(property, name, -1, permission_type, seconds, fn, minDelta, synFn); + } - void addPropertyReal( String& property, String name, int tag, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS) { + void addPropertyReal(String& property, String name, int tag, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS) { ArduinoCloudProperty *p = new CloudWrapperString(property); addPropertyReal(*p, name, tag, permission_type, seconds, fn, minDelta, synFn); } - ArduinoCloudProperty& addPropertyReal(String& property, String name, Permission const permission) { - return addPropertyReal(property, name, -1, permission); - } + ArduinoCloudProperty& addPropertyReal(String& property, String name, Permission const permission) { + return addPropertyReal(property, name, -1, permission); + } ArduinoCloudProperty& addPropertyReal(String& property, String name, int tag, Permission const permission) { ArduinoCloudProperty *p = new CloudWrapperString(property); @@ -192,68 +192,68 @@ class ArduinoIoTCloudClass { } void addCallback(ArduinoIoTCloudEvent const event, OnCloudEventCallback callback) { - switch (event) { - case ArduinoIoTCloudEvent::SYNC: _on_sync_event_callback = callback; break; - case ArduinoIoTCloudEvent::CONNECT: _on_connect_event_callback = callback; break; - case ArduinoIoTCloudEvent::DISCONNECT: _on_disconnect_event_callback = callback; break; - } - }; + switch (event) { + case ArduinoIoTCloudEvent::SYNC: _on_sync_event_callback = callback; break; + case ArduinoIoTCloudEvent::CONNECT: _on_connect_event_callback = callback; break; + case ArduinoIoTCloudEvent::DISCONNECT: _on_disconnect_event_callback = callback; break; + } + }; protected: - + virtual int writeStdout(const byte data[], int length) = 0; virtual int writeProperties(const byte data[], int length) = 0; virtual int writeShadowOut(const byte data[], int length) = 0; - - + + ArduinoIoTConnectionStatus getIoTStatus() { return _iotStatus; } ArduinoIoTConnectionStatus _iotStatus = ArduinoIoTConnectionStatus::IDLE; - - + + ArduinoIoTSynchronizationStatus _syncStatus = ArduinoIoTSynchronizationStatus::SYNC_STATUS_SYNCHRONIZED; - - String _device_id = ""; - String _thing_id = ""; - + + String _device_id = ""; + String _thing_id = ""; + ArduinoCloudThing Thing; - + int _lastSyncRequestTickTime = 0; - OnCloudEventCallback _on_sync_event_callback = NULL; - OnCloudEventCallback _on_connect_event_callback = NULL; - OnCloudEventCallback _on_disconnect_event_callback = NULL; + OnCloudEventCallback _on_sync_event_callback = NULL; + OnCloudEventCallback _on_connect_event_callback = NULL; + OnCloudEventCallback _on_disconnect_event_callback = NULL; static void execCloudEventCallback(OnCloudEventCallback & callback, void * callback_arg) { - if (callback) { - (*callback)(callback_arg); - } - } + if (callback) { + (*callback)(callback_arg); + } + } static void printConnectionStatus(ArduinoIoTConnectionStatus status) { - switch (status) { - case ArduinoIoTConnectionStatus::IDLE: Debug.print(DBG_INFO, "Arduino IoT Cloud Connection status: IDLE"); break; - case ArduinoIoTConnectionStatus::ERROR: Debug.print(DBG_ERROR, "Arduino IoT Cloud Connection status: ERROR"); break; - case ArduinoIoTConnectionStatus::CONNECTING: Debug.print(DBG_INFO, "Arduino IoT Cloud Connection status: CONNECTING"); break; - case ArduinoIoTConnectionStatus::RECONNECTING: Debug.print(DBG_INFO, "Arduino IoT Cloud Connection status: RECONNECTING"); break; - case ArduinoIoTConnectionStatus::CONNECTED: Debug.print(DBG_INFO, "Arduino IoT Cloud Connection status: CONNECTED"); break; - case ArduinoIoTConnectionStatus::DISCONNECTED: Debug.print(DBG_ERROR, "Arduino IoT Cloud Connection status: DISCONNECTED"); break; - } - } + switch (status) { + case ArduinoIoTConnectionStatus::IDLE: Debug.print(DBG_INFO, "Arduino IoT Cloud Connection status: IDLE"); break; + case ArduinoIoTConnectionStatus::ERROR: Debug.print(DBG_ERROR, "Arduino IoT Cloud Connection status: ERROR"); break; + case ArduinoIoTConnectionStatus::CONNECTING: Debug.print(DBG_INFO, "Arduino IoT Cloud Connection status: CONNECTING"); break; + case ArduinoIoTConnectionStatus::RECONNECTING: Debug.print(DBG_INFO, "Arduino IoT Cloud Connection status: RECONNECTING"); break; + case ArduinoIoTConnectionStatus::CONNECTED: Debug.print(DBG_INFO, "Arduino IoT Cloud Connection status: CONNECTED"); break; + case ArduinoIoTConnectionStatus::DISCONNECTED: Debug.print(DBG_ERROR, "Arduino IoT Cloud Connection status: DISCONNECTED"); break; + } + } }; #if defined(ARDUINO_SAMD_MKRGSM1400) || defined(ARDUINO_SAMD_MKRWIFI1010) || defined(ARDUINO_SAMD_MKR1000) || defined(ARDUINO_SAMD_NANO_33_IOT) #include "ArduinoIoTCloudTCP.h" - + #elif defined(ARDUINO_SAMD_MKRWAN1300) || defined(ARDUINO_SAMD_MKRWAN1310) #include "ArduinoIoTCloudLPWAN.h" - + #endif #endif diff --git a/src/ArduinoIoTCloudLPWAN.cpp b/src/ArduinoIoTCloudLPWAN.cpp index cc32b7d5f..ed5af2d36 100644 --- a/src/ArduinoIoTCloudLPWAN.cpp +++ b/src/ArduinoIoTCloudLPWAN.cpp @@ -20,187 +20,182 @@ #include ArduinoIoTCloudLPWAN::ArduinoIoTCloudLPWAN() : - _connection(NULL){} + _connection(NULL) {} ArduinoIoTCloudLPWAN::~ArduinoIoTCloudLPWAN() { } -int ArduinoIoTCloudLPWAN::connect() -{ - _connection->connect(); - int state = _connection->getStatus() == NetworkConnectionState::INIT ? 1 : 0; - return state; +int ArduinoIoTCloudLPWAN::connect() { + _connection->connect(); + int state = _connection->getStatus() == NetworkConnectionState::INIT ? 1 : 0; + return state; } -bool ArduinoIoTCloudLPWAN::disconnect() -{ - _connection->disconnect(); - return true; +bool ArduinoIoTCloudLPWAN::disconnect() { + _connection->disconnect(); + return true; } -int ArduinoIoTCloudLPWAN::connected() -{ - int state = _connection->getStatus() == NetworkConnectionState::INIT ? 1 : 0; - return state; +int ArduinoIoTCloudLPWAN::connected() { + int state = _connection->getStatus() == NetworkConnectionState::INIT ? 1 : 0; + return state; } -int ArduinoIoTCloudLPWAN::begin(LPWANConnectionHandler& connection, bool retry) -{ - _connection = &connection; - _connection->init(); - _retryEnable = retry; - _maxNumRetry = 5; - _intervalRetry = 1000; - Thing.begin(); - return 1; +int ArduinoIoTCloudLPWAN::begin(LPWANConnectionHandler& connection, bool retry) { + _connection = &connection; + _connection->init(); + _retryEnable = retry; + _maxNumRetry = 5; + _intervalRetry = 1000; + Thing.begin(); + return 1; } void ArduinoIoTCloudLPWAN::update(CallbackFunc onSyncCompleteCallback) { - // Check if a primitive property wrapper is locally changed - Thing.updateTimestampOnLocallyChangedProperties(); - - connectionCheck(); - - if (_iotStatus != ArduinoIoTConnectionStatus::CONNECTED) { - return; - } - - if (_connection->available()) { - uint8_t msgBuf[DEFAULT_CBOR_LORA_MSG_SIZE]; - uint8_t i = 0; - while (_connection->available()) { - msgBuf[i++] = _connection->read(); - } - - Thing.decode(msgBuf, sizeof(msgBuf)); - } - - - - - sendPropertiesToCloud(); - - - if (onSyncCompleteCallback != NULL) { - (*onSyncCompleteCallback)(); - } - execCloudEventCallback(_on_sync_event_callback, 0 /* callback_arg */); - + // Check if a primitive property wrapper is locally changed + Thing.updateTimestampOnLocallyChangedProperties(); + + connectionCheck(); + + if (_iotStatus != ArduinoIoTConnectionStatus::CONNECTED) { + return; + } + + if (_connection->available()) { + uint8_t msgBuf[DEFAULT_CBOR_LORA_MSG_SIZE]; + uint8_t i = 0; + while (_connection->available()) { + msgBuf[i++] = _connection->read(); + } + + Thing.decode(msgBuf, sizeof(msgBuf)); + } + + + + + sendPropertiesToCloud(); + + + if (onSyncCompleteCallback != NULL) { + (*onSyncCompleteCallback)(); + } + execCloudEventCallback(_on_sync_event_callback, 0 /* callback_arg */); + } void ArduinoIoTCloudLPWAN::connectionCheck() { - if (_connection != NULL) { - - _connection->check(); - - if (_connection->getStatus() != NetworkConnectionState::CONNECTED) { - if (_iotStatus == ArduinoIoTConnectionStatus::CONNECTED) { - _iotStatus = ArduinoIoTConnectionStatus::DISCONNECTED; - printConnectionStatus(_iotStatus); - } - return; - } - } - - switch (_iotStatus) { - case ArduinoIoTConnectionStatus::IDLE: { - _iotStatus = ArduinoIoTConnectionStatus::CONNECTING; - printConnectionStatus(_iotStatus); - } - break; - case ArduinoIoTConnectionStatus::ERROR: { - _iotStatus = ArduinoIoTConnectionStatus::RECONNECTING; - printConnectionStatus(_iotStatus); - } - break; - case ArduinoIoTConnectionStatus::CONNECTED: { - if (_connection->getStatus() != NetworkConnectionState::CONNECTED) { - _iotStatus = ArduinoIoTConnectionStatus::DISCONNECTED; - printConnectionStatus(_iotStatus); - execCloudEventCallback(_on_disconnect_event_callback, 0 /* callback_arg - e.g. could be error code casted to void * */); - } - } - break; - case ArduinoIoTConnectionStatus::DISCONNECTED: { - _iotStatus = ArduinoIoTConnectionStatus::RECONNECTING; - printConnectionStatus(_iotStatus); - } - break; - case ArduinoIoTConnectionStatus::RECONNECTING: { - int const ret_code = connect(); - Debug.print(DBG_INFO, "ArduinoCloud.reconnect()"); - if (ret_code == 1) { - _iotStatus = ArduinoIoTConnectionStatus::IDLE; - } - else { - _iotStatus = ArduinoIoTConnectionStatus::ERROR; - } - - } - break; - case ArduinoIoTConnectionStatus::CONNECTING: { - NetworkConnectionState net_status = _connection->getStatus(); - Debug.print(DBG_VERBOSE, "ArduinoCloud.connect(): %d", net_status); - if (net_status == NetworkConnectionState::CONNECTED) { - _iotStatus = ArduinoIoTConnectionStatus::CONNECTED; - printConnectionStatus(_iotStatus); - execCloudEventCallback(_on_connect_event_callback, 0 /* callback_arg */); - } - - } - break; - } + if (_connection != NULL) { + + _connection->check(); + + if (_connection->getStatus() != NetworkConnectionState::CONNECTED) { + if (_iotStatus == ArduinoIoTConnectionStatus::CONNECTED) { + _iotStatus = ArduinoIoTConnectionStatus::DISCONNECTED; + printConnectionStatus(_iotStatus); + } + return; + } + } + + switch (_iotStatus) { + case ArduinoIoTConnectionStatus::IDLE: { + _iotStatus = ArduinoIoTConnectionStatus::CONNECTING; + printConnectionStatus(_iotStatus); + } + break; + case ArduinoIoTConnectionStatus::ERROR: { + _iotStatus = ArduinoIoTConnectionStatus::RECONNECTING; + printConnectionStatus(_iotStatus); + } + break; + case ArduinoIoTConnectionStatus::CONNECTED: { + if (_connection->getStatus() != NetworkConnectionState::CONNECTED) { + _iotStatus = ArduinoIoTConnectionStatus::DISCONNECTED; + printConnectionStatus(_iotStatus); + execCloudEventCallback(_on_disconnect_event_callback, 0 /* callback_arg - e.g. could be error code casted to void * */); + } + } + break; + case ArduinoIoTConnectionStatus::DISCONNECTED: { + _iotStatus = ArduinoIoTConnectionStatus::RECONNECTING; + printConnectionStatus(_iotStatus); + } + break; + case ArduinoIoTConnectionStatus::RECONNECTING: { + int const ret_code = connect(); + Debug.print(DBG_INFO, "ArduinoCloud.reconnect()"); + if (ret_code == 1) { + _iotStatus = ArduinoIoTConnectionStatus::IDLE; + } else { + _iotStatus = ArduinoIoTConnectionStatus::ERROR; + } + + } + break; + case ArduinoIoTConnectionStatus::CONNECTING: { + NetworkConnectionState net_status = _connection->getStatus(); + Debug.print(DBG_VERBOSE, "ArduinoCloud.connect(): %d", net_status); + if (net_status == NetworkConnectionState::CONNECTED) { + _iotStatus = ArduinoIoTConnectionStatus::CONNECTED; + printConnectionStatus(_iotStatus); + execCloudEventCallback(_on_connect_event_callback, 0 /* callback_arg */); + } + + } + break; + } } void ArduinoIoTCloudLPWAN::printDebugInfo() { - Debug.print(DBG_INFO, "***** Arduino IoT Cloud LPWAN- configuration info *****"); - Debug.print(DBG_INFO, "Device ID: %s", getDeviceId().c_str()); - Debug.print(DBG_INFO, "Thing ID: %s", getThingId().c_str()); - + Debug.print(DBG_INFO, "***** Arduino IoT Cloud LPWAN- configuration info *****"); + Debug.print(DBG_INFO, "Device ID: %s", getDeviceId().c_str()); + Debug.print(DBG_INFO, "Thing ID: %s", getThingId().c_str()); + } int ArduinoIoTCloudLPWAN::writeProperties(const byte data[], int length) { - int retcode = _connection->write(data, length); - int i = 0; - while (_retryEnable && retcode < 0 && i < _maxNumRetry) { - delay(_intervalRetry); - retcode = _connection->write(data, length); - i++; - } - - return 1; + int retcode = _connection->write(data, length); + int i = 0; + while (_retryEnable && retcode < 0 && i < _maxNumRetry) { + delay(_intervalRetry); + retcode = _connection->write(data, length); + i++; + } + + return 1; } int ArduinoIoTCloudLPWAN::writeStdout(const byte data[], int length) { - int retcode = _connection->write(data, length); - int i = 0; - while (_retryEnable && retcode < 0 && i < _maxNumRetry) { - delay(_intervalRetry); - retcode = _connection->write(data, length); - i++; - } - - return 1; + int retcode = _connection->write(data, length); + int i = 0; + while (_retryEnable && retcode < 0 && i < _maxNumRetry) { + delay(_intervalRetry); + retcode = _connection->write(data, length); + i++; + } + + return 1; } int ArduinoIoTCloudLPWAN::writeShadowOut(const byte data[], int length) { - int retcode = _connection->write(data, length); - int i = 0; - while (_retryEnable && retcode < 0 && i < _maxNumRetry) { - delay(_intervalRetry); - retcode = _connection->write(data, length); - i++; - } - return 1; + int retcode = _connection->write(data, length); + int i = 0; + while (_retryEnable && retcode < 0 && i < _maxNumRetry) { + delay(_intervalRetry); + retcode = _connection->write(data, length); + i++; + } + return 1; } void ArduinoIoTCloudLPWAN::sendPropertiesToCloud() { - uint8_t data[DEFAULT_CBOR_LORA_MSG_SIZE]; - int const length = Thing.encode(data, sizeof(data), true); - if (length > 0) { - writeProperties(data, length); - } + uint8_t data[DEFAULT_CBOR_LORA_MSG_SIZE]; + int const length = Thing.encode(data, sizeof(data), true); + if (length > 0) { + writeProperties(data, length); + } } ArduinoIoTCloudLPWAN ArduinoCloud; diff --git a/src/ArduinoIoTCloudLPWAN.h b/src/ArduinoIoTCloudLPWAN.h index b221e7270..b44ade2f6 100644 --- a/src/ArduinoIoTCloudLPWAN.h +++ b/src/ArduinoIoTCloudLPWAN.h @@ -24,61 +24,61 @@ static uint8_t const DEFAULT_CBOR_LORA_MSG_SIZE = 255; class ArduinoIoTCloudLPWAN : public ArduinoIoTCloudClass { - public: - ArduinoIoTCloudLPWAN(); - ~ArduinoIoTCloudLPWAN(); - int connect(); - bool disconnect(); - int connected(); - inline void update() { - update(NULL); - } - inline void update(int const reconnectionMaxRetries, int const reconnectionTimeoutMs) __attribute__((deprecated)) { - update(NULL); - } - void update(CallbackFunc onSyncCompleteCallback) __attribute__((deprecated)); - void connectionCheck(); - void printDebugInfo(); - int begin(LPWANConnectionHandler& connection, bool retry = false); - inline LPWANConnectionHandler* getConnection() { - return _connection; - } - bool isRetryEnabled() { - return _retryEnable; - } - - void enableRetry(bool val) { - _retryEnable = val; - } - - int getMaxRetry() { - return _maxNumRetry; - } - - void setMaxRetry(int val) { - _maxNumRetry = val; - } - - long getIntervalRetry() { - return _intervalRetry; - } - - void setIntervalRetry(long val) { - _intervalRetry = val; - } - - protected: - int writeStdout(const byte data[], int length); - int writeProperties(const byte data[], int length); - int writeShadowOut(const byte data[], int length); - - private: - LPWANConnectionHandler* _connection; - void sendPropertiesToCloud(); - bool _retryEnable; - int _maxNumRetry; - long _intervalRetry; - + public: + ArduinoIoTCloudLPWAN(); + ~ArduinoIoTCloudLPWAN(); + int connect(); + bool disconnect(); + int connected(); + inline void update() { + update(NULL); + } + inline void update(int const reconnectionMaxRetries, int const reconnectionTimeoutMs) __attribute__((deprecated)) { + update(NULL); + } + void update(CallbackFunc onSyncCompleteCallback) __attribute__((deprecated)); + void connectionCheck(); + void printDebugInfo(); + int begin(LPWANConnectionHandler& connection, bool retry = false); + inline LPWANConnectionHandler* getConnection() { + return _connection; + } + bool isRetryEnabled() { + return _retryEnable; + } + + void enableRetry(bool val) { + _retryEnable = val; + } + + int getMaxRetry() { + return _maxNumRetry; + } + + void setMaxRetry(int val) { + _maxNumRetry = val; + } + + long getIntervalRetry() { + return _intervalRetry; + } + + void setIntervalRetry(long val) { + _intervalRetry = val; + } + + protected: + int writeStdout(const byte data[], int length); + int writeProperties(const byte data[], int length); + int writeShadowOut(const byte data[], int length); + + private: + LPWANConnectionHandler* _connection; + void sendPropertiesToCloud(); + bool _retryEnable; + int _maxNumRetry; + long _intervalRetry; + }; extern ArduinoIoTCloudLPWAN ArduinoCloud; diff --git a/src/ArduinoIoTCloudTCP.cpp b/src/ArduinoIoTCloudTCP.cpp index 6bd0039b8..35fcfb886 100644 --- a/src/ArduinoIoTCloudTCP.cpp +++ b/src/ArduinoIoTCloudTCP.cpp @@ -18,21 +18,21 @@ #include #ifdef BOARD_HAS_ECCX08 -#include "utility/ECCX08Cert.h" -#include "utility/BearSSLTrustAnchor.h" -#include + #include "utility/ECCX08Cert.h" + #include "utility/BearSSLTrustAnchor.h" + #include #endif #ifdef ARDUINO_ARCH_SAMD -#include -RTCZero rtc; + #include + RTCZero rtc; #endif #ifdef BOARD_HAS_ECCX08 -const static int keySlot = 0; -const static int compressedCertSlot = 10; -const static int serialNumberAndAuthorityKeyIdentifierSlot = 11; -const static int deviceIdSlot = 12; + const static int keySlot = 0; + const static int compressedCertSlot = 10; + const static int serialNumberAndAuthorityKeyIdentifierSlot = 11; + const static int deviceIdSlot = 12; #endif const static int CONNECT_SUCCESS = 1; @@ -40,403 +40,400 @@ const static int CONNECT_FAILURE = 0; const static int CONNECT_FAILURE_SUBSCRIBE = -1; static unsigned long getTime() { - if (!ArduinoCloud.getConnection()) { - return 0; - } - TcpIpConnectionHandler * connection = ArduinoCloud.getConnection(); - unsigned long time = connection->getTime(); - Debug.print(DBG_DEBUG, "NTP time: %lu", time); - if (!NTPUtils::isTimeValid(time)) { - Debug.print(DBG_ERROR, "Bogus NTP time from API, fallback to UDP method"); - time = NTPUtils(connection->getUDP()).getTime(); - } -#ifdef ARDUINO_ARCH_SAMD - rtc.setEpoch(time); -#endif - return time; + if (!ArduinoCloud.getConnection()) { + return 0; + } + TcpIpConnectionHandler * connection = ArduinoCloud.getConnection(); + unsigned long time = connection->getTime(); + Debug.print(DBG_DEBUG, "NTP time: %lu", time); + if (!NTPUtils::isTimeValid(time)) { + Debug.print(DBG_ERROR, "Bogus NTP time from API, fallback to UDP method"); + time = NTPUtils(connection->getUDP()).getTime(); + } + #ifdef ARDUINO_ARCH_SAMD + rtc.setEpoch(time); + #endif + return time; } ArduinoIoTCloudTCP::ArduinoIoTCloudTCP(): - _connection(NULL), - - _sslClient(NULL), -#ifdef BOARD_ESP - _password(""), -#endif - _mqttClient(NULL), - - _stdinTopic(""), - _stdoutTopic(""), - _shadowTopicOut(""), - _shadowTopicIn(""), - _dataTopicOut(""), - _dataTopicIn(""), - _otaTopic("") - {} + _connection(NULL), + + _sslClient(NULL), + #ifdef BOARD_ESP + _password(""), + #endif + _mqttClient(NULL), + + _stdinTopic(""), + _stdoutTopic(""), + _shadowTopicOut(""), + _shadowTopicIn(""), + _dataTopicOut(""), + _dataTopicIn(""), + _otaTopic("") +{} ArduinoIoTCloudTCP::~ArduinoIoTCloudTCP() { - if (_mqttClient) { - delete _mqttClient; - _mqttClient = NULL; - } - - if (_sslClient) { - delete _sslClient; - _sslClient = NULL; - } + if (_mqttClient) { + delete _mqttClient; + _mqttClient = NULL; + } + + if (_sslClient) { + delete _sslClient; + _sslClient = NULL; + } } int ArduinoIoTCloudTCP::begin(TcpIpConnectionHandler & connection, String brokerAddress, uint16_t brokerPort) { - _connection = &connection; - _brokerAddress = brokerAddress; - _brokerPort = brokerPort; -#ifdef ARDUINO_ARCH_SAMD - rtc.begin(); -#endif - return begin(_connection->getClient(), _brokerAddress, _brokerPort); + _connection = &connection; + _brokerAddress = brokerAddress; + _brokerPort = brokerPort; + #ifdef ARDUINO_ARCH_SAMD + rtc.begin(); + #endif + return begin(_connection->getClient(), _brokerAddress, _brokerPort); } int ArduinoIoTCloudTCP::begin(Client& net, String brokerAddress, uint16_t brokerPort) { - _net = &net; - // store the broker address as class member - _brokerAddress = brokerAddress; - _brokerPort = brokerPort; - -#ifdef BOARD_HAS_ECCX08 - byte deviceIdBytes[72]; - if (!ECCX08.begin()) { - Debug.print(DBG_ERROR, "Cryptography processor failure. Make sure you have a compatible board."); - return 0; - } - - if (!ECCX08.readSlot(deviceIdSlot, deviceIdBytes, sizeof(deviceIdBytes))) { - Debug.print(DBG_ERROR, "Cryptography processor read failure."); - return 0; - } - _device_id = (char*)deviceIdBytes; - - if (!ECCX08Cert.beginReconstruction(keySlot, compressedCertSlot, serialNumberAndAuthorityKeyIdentifierSlot)) { - Debug.print(DBG_ERROR, "Cryptography certificate reconstruction failure."); - return 0; - } - - ECCX08Cert.setSubjectCommonName(_device_id); - ECCX08Cert.setIssuerCountryName("US"); - ECCX08Cert.setIssuerOrganizationName("Arduino LLC US"); - ECCX08Cert.setIssuerOrganizationalUnitName("IT"); - ECCX08Cert.setIssuerCommonName("Arduino"); - - if (!ECCX08Cert.endReconstruction()) { - Debug.print(DBG_ERROR, "Cryptography certificate reconstruction failure."); - return 0; - } - - ArduinoBearSSL.onGetTime(getTime); -#endif /* BOARD_HAS_ECCX08 */ - - if (_sslClient) { - delete _sslClient; - _sslClient = NULL; - } - -#ifdef BOARD_HAS_ECCX08 - if (_connection != NULL) { - _sslClient = new BearSSLClient(_connection->getClient(), ArduinoIoTCloudTrustAnchor, ArduinoIoTCloudTrustAnchor_NUM); - } - else { - _sslClient = new BearSSLClient(*_net, ArduinoIoTCloudTrustAnchor, ArduinoIoTCloudTrustAnchor_NUM); - } - _sslClient->setEccSlot(keySlot, ECCX08Cert.bytes(), ECCX08Cert.length()); -#elif defined(BOARD_ESP) - _sslClient = new WiFiClientSecure(); - _sslClient->setInsecure(); -#endif - - _mqttClient = new MqttClient(*_sslClient); - -#ifdef BOARD_ESP - _mqttClient->setUsernamePassword(_device_id, _password); -#endif - - mqttClientBegin(); - - Thing.begin(); - return 1; + _net = &net; + // store the broker address as class member + _brokerAddress = brokerAddress; + _brokerPort = brokerPort; + + #ifdef BOARD_HAS_ECCX08 + byte deviceIdBytes[72]; + if (!ECCX08.begin()) { + Debug.print(DBG_ERROR, "Cryptography processor failure. Make sure you have a compatible board."); + return 0; + } + + if (!ECCX08.readSlot(deviceIdSlot, deviceIdBytes, sizeof(deviceIdBytes))) { + Debug.print(DBG_ERROR, "Cryptography processor read failure."); + return 0; + } + _device_id = (char*)deviceIdBytes; + + if (!ECCX08Cert.beginReconstruction(keySlot, compressedCertSlot, serialNumberAndAuthorityKeyIdentifierSlot)) { + Debug.print(DBG_ERROR, "Cryptography certificate reconstruction failure."); + return 0; + } + + ECCX08Cert.setSubjectCommonName(_device_id); + ECCX08Cert.setIssuerCountryName("US"); + ECCX08Cert.setIssuerOrganizationName("Arduino LLC US"); + ECCX08Cert.setIssuerOrganizationalUnitName("IT"); + ECCX08Cert.setIssuerCommonName("Arduino"); + + if (!ECCX08Cert.endReconstruction()) { + Debug.print(DBG_ERROR, "Cryptography certificate reconstruction failure."); + return 0; + } + + ArduinoBearSSL.onGetTime(getTime); + #endif /* BOARD_HAS_ECCX08 */ + + if (_sslClient) { + delete _sslClient; + _sslClient = NULL; + } + + #ifdef BOARD_HAS_ECCX08 + if (_connection != NULL) { + _sslClient = new BearSSLClient(_connection->getClient(), ArduinoIoTCloudTrustAnchor, ArduinoIoTCloudTrustAnchor_NUM); + } else { + _sslClient = new BearSSLClient(*_net, ArduinoIoTCloudTrustAnchor, ArduinoIoTCloudTrustAnchor_NUM); + } + _sslClient->setEccSlot(keySlot, ECCX08Cert.bytes(), ECCX08Cert.length()); + #elif defined(BOARD_ESP) + _sslClient = new WiFiClientSecure(); + _sslClient->setInsecure(); + #endif + + _mqttClient = new MqttClient(*_sslClient); + + #ifdef BOARD_ESP + _mqttClient->setUsernamePassword(_device_id, _password); + #endif + + mqttClientBegin(); + + Thing.begin(); + return 1; } // private class method used to initialize mqttClient class member. (called in the begin class method) void ArduinoIoTCloudTCP::mqttClientBegin() { - // MQTT topics definition - _stdoutTopic = "/a/d/" + _device_id + "/s/o"; - _stdinTopic = "/a/d/" + _device_id + "/s/i"; - if (_thing_id == "") { - _dataTopicIn = "/a/d/" + _device_id + "/e/i"; - _dataTopicOut = "/a/d/" + _device_id + "/e/o"; - } - else { - _dataTopicIn = "/a/t/" + _thing_id + "/e/i"; - _dataTopicOut = "/a/t/" + _thing_id + "/e/o"; - _shadowTopicIn = "/a/t/" + _thing_id + "/shadow/i"; - _shadowTopicOut = "/a/t/" + _thing_id + "/shadow/o"; - } - - // use onMessage as callback for received mqtt messages - _mqttClient->onMessage(ArduinoIoTCloudTCP::onMessage); - _mqttClient->setKeepAliveInterval(30 * 1000); - _mqttClient->setConnectionTimeout(1500); - _mqttClient->setId(_device_id.c_str()); + // MQTT topics definition + _stdoutTopic = "/a/d/" + _device_id + "/s/o"; + _stdinTopic = "/a/d/" + _device_id + "/s/i"; + if (_thing_id == "") { + _dataTopicIn = "/a/d/" + _device_id + "/e/i"; + _dataTopicOut = "/a/d/" + _device_id + "/e/o"; + } else { + _dataTopicIn = "/a/t/" + _thing_id + "/e/i"; + _dataTopicOut = "/a/t/" + _thing_id + "/e/o"; + _shadowTopicIn = "/a/t/" + _thing_id + "/shadow/i"; + _shadowTopicOut = "/a/t/" + _thing_id + "/shadow/o"; + } + + // use onMessage as callback for received mqtt messages + _mqttClient->onMessage(ArduinoIoTCloudTCP::onMessage); + _mqttClient->setKeepAliveInterval(30 * 1000); + _mqttClient->setConnectionTimeout(1500); + _mqttClient->setId(_device_id.c_str()); } int ArduinoIoTCloudTCP::connect() { - if (!_mqttClient->connect(_brokerAddress.c_str(), _brokerPort)) { - return CONNECT_FAILURE; - } - if (_mqttClient->subscribe(_stdinTopic) == 0) { - return CONNECT_FAILURE_SUBSCRIBE; - } - if (_mqttClient->subscribe(_dataTopicIn) == 0) { - return CONNECT_FAILURE_SUBSCRIBE; - } - if (_shadowTopicIn != "") { - if (_mqttClient->subscribe(_shadowTopicIn) == 0) { - return CONNECT_FAILURE_SUBSCRIBE; - } - - _syncStatus = ArduinoIoTSynchronizationStatus::SYNC_STATUS_WAIT_FOR_CLOUD_VALUES; - _lastSyncRequestTickTime = 0; - } - - return CONNECT_SUCCESS; + if (!_mqttClient->connect(_brokerAddress.c_str(), _brokerPort)) { + return CONNECT_FAILURE; + } + if (_mqttClient->subscribe(_stdinTopic) == 0) { + return CONNECT_FAILURE_SUBSCRIBE; + } + if (_mqttClient->subscribe(_dataTopicIn) == 0) { + return CONNECT_FAILURE_SUBSCRIBE; + } + if (_shadowTopicIn != "") { + if (_mqttClient->subscribe(_shadowTopicIn) == 0) { + return CONNECT_FAILURE_SUBSCRIBE; + } + + _syncStatus = ArduinoIoTSynchronizationStatus::SYNC_STATUS_WAIT_FOR_CLOUD_VALUES; + _lastSyncRequestTickTime = 0; + } + + return CONNECT_SUCCESS; } bool ArduinoIoTCloudTCP::disconnect() { - _mqttClient->stop(); + _mqttClient->stop(); - return true; + return true; } void ArduinoIoTCloudTCP::update(CallbackFunc onSyncCompleteCallback) { - // Check if a primitive property wrapper is locally changed - Thing.updateTimestampOnLocallyChangedProperties(); - - connectionCheck(); - - if (_iotStatus != ArduinoIoTConnectionStatus::CONNECTED) { - return; - } - - // MTTQClient connected!, poll() used to retrieve data from MQTT broker - _mqttClient->poll(); - - switch (_syncStatus) { - case ArduinoIoTSynchronizationStatus::SYNC_STATUS_SYNCHRONIZED: { - sendPropertiesToCloud(); - } - break; - case ArduinoIoTSynchronizationStatus::SYNC_STATUS_WAIT_FOR_CLOUD_VALUES: { - if (millis() - _lastSyncRequestTickTime > TIMEOUT_FOR_LASTVALUES_SYNC) { - requestLastValue(); - _lastSyncRequestTickTime = millis(); - } - } - break; - case ArduinoIoTSynchronizationStatus::SYNC_STATUS_VALUES_PROCESSED: { - if (onSyncCompleteCallback != NULL) { - (*onSyncCompleteCallback)(); - } - execCloudEventCallback(_on_sync_event_callback, 0 /* callback_arg */); - _syncStatus = ArduinoIoTSynchronizationStatus::SYNC_STATUS_SYNCHRONIZED; - } - break; - } + // Check if a primitive property wrapper is locally changed + Thing.updateTimestampOnLocallyChangedProperties(); + + connectionCheck(); + + if (_iotStatus != ArduinoIoTConnectionStatus::CONNECTED) { + return; + } + + // MTTQClient connected!, poll() used to retrieve data from MQTT broker + _mqttClient->poll(); + + switch (_syncStatus) { + case ArduinoIoTSynchronizationStatus::SYNC_STATUS_SYNCHRONIZED: { + sendPropertiesToCloud(); + } + break; + case ArduinoIoTSynchronizationStatus::SYNC_STATUS_WAIT_FOR_CLOUD_VALUES: { + if (millis() - _lastSyncRequestTickTime > TIMEOUT_FOR_LASTVALUES_SYNC) { + requestLastValue(); + _lastSyncRequestTickTime = millis(); + } + } + break; + case ArduinoIoTSynchronizationStatus::SYNC_STATUS_VALUES_PROCESSED: { + if (onSyncCompleteCallback != NULL) { + (*onSyncCompleteCallback)(); + } + execCloudEventCallback(_on_sync_event_callback, 0 /* callback_arg */); + _syncStatus = ArduinoIoTSynchronizationStatus::SYNC_STATUS_SYNCHRONIZED; + } + break; + } } void ArduinoIoTCloudTCP::sendPropertiesToCloud() { - uint8_t data[MQTT_TRANSMIT_BUFFER_SIZE]; - int const length = Thing.encode(data, sizeof(data)); - if (length > 0) { - writeProperties(data, length); - } + uint8_t data[MQTT_TRANSMIT_BUFFER_SIZE]; + int const length = Thing.encode(data, sizeof(data)); + if (length > 0) { + writeProperties(data, length); + } } int ArduinoIoTCloudTCP::reconnect(Client& /* net */) { - if (_mqttClient->connected()) { - _mqttClient->stop(); - } + if (_mqttClient->connected()) { + _mqttClient->stop(); + } - // Connect to the broker - return connect(); + // Connect to the broker + return connect(); } int ArduinoIoTCloudTCP::connected() { - return _mqttClient->connected(); + return _mqttClient->connected(); } int ArduinoIoTCloudTCP::writeProperties(const byte data[], int length) { - if (!_mqttClient->beginMessage(_dataTopicOut, length, false, 0)) { - return 0; - } + if (!_mqttClient->beginMessage(_dataTopicOut, length, false, 0)) { + return 0; + } - if (!_mqttClient->write(data, length)) { - return 0; - } + if (!_mqttClient->write(data, length)) { + return 0; + } - if (!_mqttClient->endMessage()) { - return 0; - } + if (!_mqttClient->endMessage()) { + return 0; + } - return 1; + return 1; } int ArduinoIoTCloudTCP::writeStdout(const byte data[], int length) { - if (!_mqttClient->beginMessage(_stdoutTopic, length, false, 0)) { - return 0; - } + if (!_mqttClient->beginMessage(_stdoutTopic, length, false, 0)) { + return 0; + } - if (!_mqttClient->write(data, length)) { - return 0; - } + if (!_mqttClient->write(data, length)) { + return 0; + } - if (!_mqttClient->endMessage()) { - return 0; - } + if (!_mqttClient->endMessage()) { + return 0; + } - return 1; + return 1; } int ArduinoIoTCloudTCP::writeShadowOut(const byte data[], int length) { - if (!_mqttClient->beginMessage(_shadowTopicOut, length, false, 0)) { - return 0; - } + if (!_mqttClient->beginMessage(_shadowTopicOut, length, false, 0)) { + return 0; + } - if (!_mqttClient->write(data, length)) { - return 0; - } + if (!_mqttClient->write(data, length)) { + return 0; + } - if (!_mqttClient->endMessage()) { - return 0; - } + if (!_mqttClient->endMessage()) { + return 0; + } - return 1; + return 1; } void ArduinoIoTCloudTCP::onMessage(int length) { - ArduinoCloud.handleMessage(length); + ArduinoCloud.handleMessage(length); } void ArduinoIoTCloudTCP::handleMessage(int length) { - String topic = _mqttClient->messageTopic(); - - byte bytes[length]; - - for (int i = 0; i < length; i++) { - bytes[i] = _mqttClient->read(); - } - - if (_stdinTopic == topic) { - CloudSerial.appendStdin((uint8_t*)bytes, length); - } - if (_dataTopicIn == topic) { - Thing.decode((uint8_t*)bytes, length); - } - if ((_shadowTopicIn == topic) && _syncStatus == ArduinoIoTSynchronizationStatus::SYNC_STATUS_WAIT_FOR_CLOUD_VALUES) { - Thing.decode((uint8_t*)bytes, length, true); - sendPropertiesToCloud(); - _syncStatus = ArduinoIoTSynchronizationStatus::SYNC_STATUS_VALUES_PROCESSED; - } + String topic = _mqttClient->messageTopic(); + + byte bytes[length]; + + for (int i = 0; i < length; i++) { + bytes[i] = _mqttClient->read(); + } + + if (_stdinTopic == topic) { + CloudSerial.appendStdin((uint8_t*)bytes, length); + } + if (_dataTopicIn == topic) { + Thing.decode((uint8_t*)bytes, length); + } + if ((_shadowTopicIn == topic) && _syncStatus == ArduinoIoTSynchronizationStatus::SYNC_STATUS_WAIT_FOR_CLOUD_VALUES) { + Thing.decode((uint8_t*)bytes, length, true); + sendPropertiesToCloud(); + _syncStatus = ArduinoIoTSynchronizationStatus::SYNC_STATUS_VALUES_PROCESSED; + } } void ArduinoIoTCloudTCP::requestLastValue() { - // Send the getLastValues CBOR message to the cloud - // [{0: "r:m", 3: "getLastValues"}] = 81 A2 00 63 72 3A 6D 03 6D 67 65 74 4C 61 73 74 56 61 6C 75 65 73 - // Use http://cbor.me to easily generate CBOR encoding - const uint8_t CBOR_REQUEST_LAST_VALUE_MSG[] = { 0x81, 0xA2, 0x00, 0x63, 0x72, 0x3A, 0x6D, 0x03, 0x6D, 0x67, 0x65, 0x74, 0x4C, 0x61, 0x73, 0x74, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x73 }; - writeShadowOut(CBOR_REQUEST_LAST_VALUE_MSG, sizeof(CBOR_REQUEST_LAST_VALUE_MSG)); + // Send the getLastValues CBOR message to the cloud + // [{0: "r:m", 3: "getLastValues"}] = 81 A2 00 63 72 3A 6D 03 6D 67 65 74 4C 61 73 74 56 61 6C 75 65 73 + // Use http://cbor.me to easily generate CBOR encoding + const uint8_t CBOR_REQUEST_LAST_VALUE_MSG[] = { 0x81, 0xA2, 0x00, 0x63, 0x72, 0x3A, 0x6D, 0x03, 0x6D, 0x67, 0x65, 0x74, 0x4C, 0x61, 0x73, 0x74, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x73 }; + writeShadowOut(CBOR_REQUEST_LAST_VALUE_MSG, sizeof(CBOR_REQUEST_LAST_VALUE_MSG)); } void ArduinoIoTCloudTCP::connectionCheck() { - if (_connection != NULL) { - - _connection->check(); - - if (_connection->getStatus() != NetworkConnectionState::CONNECTED) { - if (_iotStatus == ArduinoIoTConnectionStatus::CONNECTED) { - _iotStatus = ArduinoIoTConnectionStatus::DISCONNECTED; - printConnectionStatus(_iotStatus); - } - return; - } - } - - switch (_iotStatus) { - case ArduinoIoTConnectionStatus::IDLE: { - _iotStatus = ArduinoIoTConnectionStatus::CONNECTING; - printConnectionStatus(_iotStatus); - } - break; - case ArduinoIoTConnectionStatus::ERROR: { - _iotStatus = ArduinoIoTConnectionStatus::RECONNECTING; - printConnectionStatus(_iotStatus); - } - break; - case ArduinoIoTConnectionStatus::CONNECTED: { - if (!_mqttClient->connected()) { - _iotStatus = ArduinoIoTConnectionStatus::DISCONNECTED; - printConnectionStatus(_iotStatus); - execCloudEventCallback(_on_disconnect_event_callback, 0 /* callback_arg - e.g. could be error code casted to void * */); - } - } - break; - case ArduinoIoTConnectionStatus::DISCONNECTED: { - _iotStatus = ArduinoIoTConnectionStatus::RECONNECTING; - printConnectionStatus(_iotStatus); - } - break; - case ArduinoIoTConnectionStatus::RECONNECTING: { - int const ret_code_reconnect = reconnect(*_net); - Debug.print(DBG_INFO, "ArduinoCloud.reconnect(): %d", ret_code_reconnect); - if (ret_code_reconnect == CONNECT_SUCCESS) { - _iotStatus = ArduinoIoTConnectionStatus::CONNECTED; - printConnectionStatus(_iotStatus); - execCloudEventCallback(_on_connect_event_callback, 0 /* callback_arg */); - CloudSerial.begin(9600); - CloudSerial.println("Hello from Cloud Serial!"); - } - } - break; - case ArduinoIoTConnectionStatus::CONNECTING: { - int const ret_code_connect = connect(); - Debug.print(DBG_VERBOSE, "ArduinoCloud.connect(): %d", ret_code_connect); - if (ret_code_connect == CONNECT_SUCCESS) { - _iotStatus = ArduinoIoTConnectionStatus::CONNECTED; - printConnectionStatus(_iotStatus); - execCloudEventCallback(_on_connect_event_callback, 0 /* callback_arg */); - CloudSerial.begin(9600); - CloudSerial.println("Hello from Cloud Serial!"); - } - else if (ret_code_connect == CONNECT_FAILURE_SUBSCRIBE) { - Debug.print(DBG_INFO, "ERROR - Please verify your THING ID"); - } - } - break; - } + if (_connection != NULL) { + + _connection->check(); + + if (_connection->getStatus() != NetworkConnectionState::CONNECTED) { + if (_iotStatus == ArduinoIoTConnectionStatus::CONNECTED) { + _iotStatus = ArduinoIoTConnectionStatus::DISCONNECTED; + printConnectionStatus(_iotStatus); + } + return; + } + } + + switch (_iotStatus) { + case ArduinoIoTConnectionStatus::IDLE: { + _iotStatus = ArduinoIoTConnectionStatus::CONNECTING; + printConnectionStatus(_iotStatus); + } + break; + case ArduinoIoTConnectionStatus::ERROR: { + _iotStatus = ArduinoIoTConnectionStatus::RECONNECTING; + printConnectionStatus(_iotStatus); + } + break; + case ArduinoIoTConnectionStatus::CONNECTED: { + if (!_mqttClient->connected()) { + _iotStatus = ArduinoIoTConnectionStatus::DISCONNECTED; + printConnectionStatus(_iotStatus); + execCloudEventCallback(_on_disconnect_event_callback, 0 /* callback_arg - e.g. could be error code casted to void * */); + } + } + break; + case ArduinoIoTConnectionStatus::DISCONNECTED: { + _iotStatus = ArduinoIoTConnectionStatus::RECONNECTING; + printConnectionStatus(_iotStatus); + } + break; + case ArduinoIoTConnectionStatus::RECONNECTING: { + int const ret_code_reconnect = reconnect(*_net); + Debug.print(DBG_INFO, "ArduinoCloud.reconnect(): %d", ret_code_reconnect); + if (ret_code_reconnect == CONNECT_SUCCESS) { + _iotStatus = ArduinoIoTConnectionStatus::CONNECTED; + printConnectionStatus(_iotStatus); + execCloudEventCallback(_on_connect_event_callback, 0 /* callback_arg */); + CloudSerial.begin(9600); + CloudSerial.println("Hello from Cloud Serial!"); + } + } + break; + case ArduinoIoTConnectionStatus::CONNECTING: { + int const ret_code_connect = connect(); + Debug.print(DBG_VERBOSE, "ArduinoCloud.connect(): %d", ret_code_connect); + if (ret_code_connect == CONNECT_SUCCESS) { + _iotStatus = ArduinoIoTConnectionStatus::CONNECTED; + printConnectionStatus(_iotStatus); + execCloudEventCallback(_on_connect_event_callback, 0 /* callback_arg */); + CloudSerial.begin(9600); + CloudSerial.println("Hello from Cloud Serial!"); + } else if (ret_code_connect == CONNECT_FAILURE_SUBSCRIBE) { + Debug.print(DBG_INFO, "ERROR - Please verify your THING ID"); + } + } + break; + } } void ArduinoIoTCloudTCP::printDebugInfo() { - Debug.print(DBG_INFO, "***** Arduino IoT Cloud - configuration info *****"); - Debug.print(DBG_INFO, "Device ID: %s", getDeviceId().c_str()); - Debug.print(DBG_INFO, "Thing ID: %s", getThingId().c_str()); - Debug.print(DBG_INFO, "MQTT Broker: %s:%d", _brokerAddress.c_str(), _brokerPort); + Debug.print(DBG_INFO, "***** Arduino IoT Cloud - configuration info *****"); + Debug.print(DBG_INFO, "Device ID: %s", getDeviceId().c_str()); + Debug.print(DBG_INFO, "Thing ID: %s", getThingId().c_str()); + Debug.print(DBG_INFO, "MQTT Broker: %s:%d", _brokerAddress.c_str(), _brokerPort); } ArduinoIoTCloudTCP ArduinoCloud; diff --git a/src/ArduinoIoTCloudTCP.h b/src/ArduinoIoTCloudTCP.h index 41f5da24c..84e9eaed0 100644 --- a/src/ArduinoIoTCloudTCP.h +++ b/src/ArduinoIoTCloudTCP.h @@ -23,14 +23,14 @@ #include #ifdef BOARD_HAS_ECCX08 / -#include + #include #elif defined(BOARD_ESP) -#include + #include #endif -#include +#include -#include "utility/NTPUtils.h" +#include "utility/NTPUtils.h" static char const DEFAULT_BROKER_ADDRESS_SECURE_AUTH[] = "mqtts-sa.iot.arduino.cc"; @@ -40,103 +40,102 @@ static uint16_t const DEFAULT_BROKER_PORT_USER_PASS_AUTH = 8884; // Declaration of the struct for the mqtt connection options typedef struct { - int keepAlive; - bool cleanSession; - int timeout; + int keepAlive; + bool cleanSession; + int timeout; } mqttConnectionOptions; -class ArduinoIoTCloudTCP: public ArduinoIoTCloudClass -{ - public: - ArduinoIoTCloudTCP(); - ~ArduinoIoTCloudTCP(); - int connect(); - bool disconnect(); - int connected(); - inline void update() { - update(NULL); - } - inline void update(int const reconnectionMaxRetries, int const reconnectionTimeoutMs) __attribute__((deprecated)) { - update(NULL); - } - void update(CallbackFunc onSyncCompleteCallback) __attribute__((deprecated)); - void connectionCheck(); - void printDebugInfo(); - #ifdef BOARD_HAS_ECCX08 - int begin(TcpIpConnectionHandler & connection, String brokerAddress = DEFAULT_BROKER_ADDRESS_SECURE_AUTH, uint16_t brokerPort = DEFAULT_BROKER_PORT_SECURE_AUTH); - #else - int begin(TcpIpConnectionHandler & connection, String brokerAddress = DEFAULT_BROKER_ADDRESS_USER_PASS_AUTH, uint16_t brokerPort = DEFAULT_BROKER_PORT_USER_PASS_AUTH); - #endif - int begin(Client& net, String brokerAddress = DEFAULT_BROKER_ADDRESS_SECURE_AUTH, uint16_t brokerPort = DEFAULT_BROKER_PORT_SECURE_AUTH); - // Class constant declaration - static const int MQTT_TRANSMIT_BUFFER_SIZE = 256; - - #ifdef BOARD_ESP - inline void setBoardId(String const device_id) { - _device_id = device_id; - } - inline void setSecretDeviceKey(String const password) { - _password = password; - } - #endif - - inline TcpIpConnectionHandler * getConnection() { - return _connection; - } - - String getBrokerAddress() { - return _brokerAddress; - } - uint16_t getBrokerPort() { - return _brokerPort; - } - - // Clean up existing Mqtt connection, create a new one and initialize it - int reconnect(Client& /* net */); - - protected: - friend class CloudSerialClass; - // Used to initialize MQTTClient - void mqttClientBegin(); - // Function in charge of perform MQTT reconnection, basing on class parameters(retries,and timeout) - bool mqttReconnect(int const maxRetries, int const timeout); - // Used to retrieve last values from _shadowTopicIn - int writeStdout(const byte data[], int length); - int writeProperties(const byte data[], int length); - int writeShadowOut(const byte data[], int length); - - void requestLastValue(); - - private: - TcpIpConnectionHandler * _connection; - String _brokerAddress; - uint16_t _brokerPort; - - #ifdef BOARD_HAS_ECCX08 - BearSSLClient* _sslClient; - #elif defined(BOARD_ESP) - WiFiClientSecure* _sslClient; - String _password; - #endif - - MqttClient* _mqttClient; - - // Class attribute to define MTTQ topics 2 for stdIn/out and 2 for data, in order to avoid getting previous pupblished payload - String _stdinTopic; - String _stdoutTopic; - String _shadowTopicOut; - String _shadowTopicIn; - String _dataTopicOut; - String _dataTopicIn; - String _otaTopic; - Client* _net; - - static void onMessage(int length); - - void handleMessage(int length); - - void sendPropertiesToCloud(); +class ArduinoIoTCloudTCP: public ArduinoIoTCloudClass { + public: + ArduinoIoTCloudTCP(); + ~ArduinoIoTCloudTCP(); + int connect(); + bool disconnect(); + int connected(); + inline void update() { + update(NULL); + } + inline void update(int const reconnectionMaxRetries, int const reconnectionTimeoutMs) __attribute__((deprecated)) { + update(NULL); + } + void update(CallbackFunc onSyncCompleteCallback) __attribute__((deprecated)); + void connectionCheck(); + void printDebugInfo(); + #ifdef BOARD_HAS_ECCX08 + int begin(TcpIpConnectionHandler & connection, String brokerAddress = DEFAULT_BROKER_ADDRESS_SECURE_AUTH, uint16_t brokerPort = DEFAULT_BROKER_PORT_SECURE_AUTH); + #else + int begin(TcpIpConnectionHandler & connection, String brokerAddress = DEFAULT_BROKER_ADDRESS_USER_PASS_AUTH, uint16_t brokerPort = DEFAULT_BROKER_PORT_USER_PASS_AUTH); + #endif + int begin(Client& net, String brokerAddress = DEFAULT_BROKER_ADDRESS_SECURE_AUTH, uint16_t brokerPort = DEFAULT_BROKER_PORT_SECURE_AUTH); + // Class constant declaration + static const int MQTT_TRANSMIT_BUFFER_SIZE = 256; + + #ifdef BOARD_ESP + inline void setBoardId(String const device_id) { + _device_id = device_id; + } + inline void setSecretDeviceKey(String const password) { + _password = password; + } + #endif + + inline TcpIpConnectionHandler * getConnection() { + return _connection; + } + + String getBrokerAddress() { + return _brokerAddress; + } + uint16_t getBrokerPort() { + return _brokerPort; + } + + // Clean up existing Mqtt connection, create a new one and initialize it + int reconnect(Client& /* net */); + + protected: + friend class CloudSerialClass; + // Used to initialize MQTTClient + void mqttClientBegin(); + // Function in charge of perform MQTT reconnection, basing on class parameters(retries,and timeout) + bool mqttReconnect(int const maxRetries, int const timeout); + // Used to retrieve last values from _shadowTopicIn + int writeStdout(const byte data[], int length); + int writeProperties(const byte data[], int length); + int writeShadowOut(const byte data[], int length); + + void requestLastValue(); + + private: + TcpIpConnectionHandler * _connection; + String _brokerAddress; + uint16_t _brokerPort; + + #ifdef BOARD_HAS_ECCX08 + BearSSLClient* _sslClient; + #elif defined(BOARD_ESP) + WiFiClientSecure* _sslClient; + String _password; + #endif + + MqttClient* _mqttClient; + + // Class attribute to define MTTQ topics 2 for stdIn/out and 2 for data, in order to avoid getting previous pupblished payload + String _stdinTopic; + String _stdoutTopic; + String _shadowTopicOut; + String _shadowTopicIn; + String _dataTopicOut; + String _dataTopicIn; + String _otaTopic; + Client* _net; + + static void onMessage(int length); + + void handleMessage(int length); + + void sendPropertiesToCloud(); }; extern ArduinoIoTCloudTCP ArduinoCloud; From 98434018b1e5943483c38844ea82d19420e4a17f Mon Sep 17 00:00:00 2001 From: fabio Date: Tue, 10 Dec 2019 18:12:47 +0100 Subject: [PATCH 09/21] fix astyle --- src/CloudSerial.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/CloudSerial.h b/src/CloudSerial.h index 8232e12a9..5d53465a9 100644 --- a/src/CloudSerial.h +++ b/src/CloudSerial.h @@ -51,9 +51,9 @@ class CloudSerialClass : public Stream { protected: - friend class ArduinoIoTCloudTCP; + friend class ArduinoIoTCloudTCP; + - void appendStdin(const uint8_t *buffer, size_t size); From fa7ae710365aa06cb49a5ecc6139a8b61ae510a1 Mon Sep 17 00:00:00 2001 From: mirkokurt Date: Wed, 11 Dec 2019 15:55:57 +0100 Subject: [PATCH 10/21] Add RTCZero to ArduinoIoTCloudLPWAN --- src/ArduinoIoTCloudLPWAN.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/ArduinoIoTCloudLPWAN.cpp b/src/ArduinoIoTCloudLPWAN.cpp index ed5af2d36..6f05a15e8 100644 --- a/src/ArduinoIoTCloudLPWAN.cpp +++ b/src/ArduinoIoTCloudLPWAN.cpp @@ -19,6 +19,11 @@ #include +#ifdef ARDUINO_ARCH_SAMD + #include + RTCZero rtc; +#endif + ArduinoIoTCloudLPWAN::ArduinoIoTCloudLPWAN() : _connection(NULL) {} From 5cf8e503d883733ee40e125f665165121e09bd20 Mon Sep 17 00:00:00 2001 From: fabio Date: Wed, 18 Dec 2019 12:01:09 +0100 Subject: [PATCH 11/21] refactor addpropertyReal methods --- src/ArduinoIoTCloud.cpp | 133 +++++++++++++++++++++++++++++++++++++ src/ArduinoIoTCloud.h | 120 ++++++--------------------------- src/ArduinoIoTCloudTCP.cpp | 12 ++-- 3 files changed, 160 insertions(+), 105 deletions(-) create mode 100644 src/ArduinoIoTCloud.cpp diff --git a/src/ArduinoIoTCloud.cpp b/src/ArduinoIoTCloud.cpp new file mode 100644 index 000000000..bd72ee437 --- /dev/null +++ b/src/ArduinoIoTCloud.cpp @@ -0,0 +1,133 @@ +/* + This file is part of ArduinoIoTCloud. + + Copyright 2019 ARDUINO SA (http://www.arduino.cc/) + + This software is released under the GNU General Public License version 3, + which covers the main part of arduino-cli. + The terms of this license can be found at: + https://www.gnu.org/licenses/gpl-3.0.en.html + + You can be released from the requirements of the above licenses by purchasing + a commercial license. Buying such a license is mandatory if you want to modify or + otherwise use the software for commercial activities involving the Arduino + software without disclosing the source code of your own applications. To purchase + a commercial license, send an email to license@arduino.cc. +*/ + +#include + +void ArduinoIoTCloudClass::addPropertyReal(ArduinoCloudProperty& property, String name, permissionType permission_type, long seconds, void(*fn)(void), float minDelta, void(*synFn)(ArduinoCloudProperty & property)) { + addPropertyReal(property, name, -1, permission_type, seconds, fn, minDelta, synFn); +} + +void ArduinoIoTCloudClass::addPropertyReal(ArduinoCloudProperty& property, String name, int tag, permissionType permission_type, long seconds, void(*fn)(void), float minDelta, void(*synFn)(ArduinoCloudProperty & property)) { + Permission permission = Permission::ReadWrite; + if (permission_type == READ) { + permission = Permission::Read; + } else if (permission_type == WRITE) { + permission = Permission::Write; + } else { + permission = Permission::ReadWrite; + } + + if (seconds == ON_CHANGE) { + Thing.addPropertyReal(property, name, permission, tag).publishOnChange(minDelta, DEFAULT_MIN_TIME_BETWEEN_UPDATES_MILLIS).onUpdate(fn).onSync(synFn); + } else { + Thing.addPropertyReal(property, name, permission, tag).publishEvery(seconds).onUpdate(fn).onSync(synFn); + } +} + +void ArduinoIoTCloudClass::addPropertyReal(bool& property, String name, permissionType permission_type, long seconds, void(*fn)(void), float minDelta, void(*synFn)(ArduinoCloudProperty & property)) { + addPropertyReal(property, name, -1, permission_type, seconds, fn, minDelta, synFn); +} + +void ArduinoIoTCloudClass::addPropertyReal(bool& property, String name, int tag, permissionType permission_type, long seconds, void(*fn)(void), float minDelta, void(*synFn)(ArduinoCloudProperty & property)) { + ArduinoCloudProperty* p = new CloudWrapperBool(property); + addPropertyReal(*p, name, tag, permission_type, seconds, fn, minDelta, synFn); +} +ArduinoCloudProperty& ArduinoIoTCloudClass::addPropertyReal(bool& property, String name, Permission const permission) { + return addPropertyReal(property, name, -1, permission); +} +ArduinoCloudProperty& ArduinoIoTCloudClass::addPropertyReal(bool& property, String name, int tag, Permission const permission) { + ArduinoCloudProperty* p = new CloudWrapperBool(property); + return Thing.addPropertyReal(*p, name, permission, tag); +} + +void ArduinoIoTCloudClass::addPropertyReal(float& property, String name, permissionType permission_type, long seconds, void(*fn)(void), float minDelta, void(*synFn)(ArduinoCloudProperty & property)) { + addPropertyReal(property, name, -1, permission_type, seconds, fn, minDelta, synFn); +} + +void ArduinoIoTCloudClass::addPropertyReal(float& property, String name, int tag, permissionType permission_type, long seconds, void(*fn)(void), float minDelta, void(*synFn)(ArduinoCloudProperty & property)) { + ArduinoCloudProperty* p = new CloudWrapperFloat(property); + addPropertyReal(*p, name, tag, permission_type, seconds, fn, minDelta, synFn); +} + +ArduinoCloudProperty& ArduinoIoTCloudClass::addPropertyReal(float& property, String name, Permission const permission) { + return addPropertyReal(property, name, -1, permission); +} + +ArduinoCloudProperty& ArduinoIoTCloudClass::addPropertyReal(float& property, String name, int tag, Permission const permission) { + ArduinoCloudProperty* p = new CloudWrapperFloat(property); + return Thing.addPropertyReal(*p, name, permission, tag); +} + +void ArduinoIoTCloudClass::addPropertyReal(int& property, String name, permissionType permission_type, long seconds, void(*fn)(void), float minDelta, void(*synFn)(ArduinoCloudProperty & property)) { + addPropertyReal(property, name, -1, permission_type, seconds, fn, minDelta, synFn); +} + +void ArduinoIoTCloudClass::addPropertyReal(int& property, String name, int tag, permissionType permission_type, long seconds, void(*fn)(void), float minDelta, void(*synFn)(ArduinoCloudProperty & property)) { + ArduinoCloudProperty* p = new CloudWrapperInt(property); + addPropertyReal(*p, name, tag, permission_type, seconds, fn, minDelta, synFn); +} + +ArduinoCloudProperty& ArduinoIoTCloudClass::addPropertyReal(int& property, String name, Permission const permission) { + return addPropertyReal(property, name, -1, permission); +} + +ArduinoCloudProperty& ArduinoIoTCloudClass::addPropertyReal(int& property, String name, int tag, Permission const permission) { + ArduinoCloudProperty* p = new CloudWrapperInt(property); + return Thing.addPropertyReal(*p, name, permission, tag); +} + +void ArduinoIoTCloudClass::addPropertyReal(String& property, String name, permissionType permission_type, long seconds, void(*fn)(void), float minDelta, void(*synFn)(ArduinoCloudProperty & property)) { + addPropertyReal(property, name, -1, permission_type, seconds, fn, minDelta, synFn); +} + +void ArduinoIoTCloudClass::addPropertyReal(String& property, String name, int tag, permissionType permission_type, long seconds, void(*fn)(void), float minDelta, void(*synFn)(ArduinoCloudProperty & property)) { + ArduinoCloudProperty* p = new CloudWrapperString(property); + addPropertyReal(*p, name, tag, permission_type, seconds, fn, minDelta, synFn); +} + +ArduinoCloudProperty& ArduinoIoTCloudClass::addPropertyReal(String& property, String name, Permission const permission) { + return addPropertyReal(property, name, -1, permission); +} + +ArduinoCloudProperty& ArduinoIoTCloudClass::addPropertyReal(String& property, String name, int tag, Permission const permission) { + ArduinoCloudProperty* p = new CloudWrapperString(property); + return Thing.addPropertyReal(*p, name, permission, tag); +} + +void ArduinoIoTCloudClass::addCallback(ArduinoIoTCloudEvent const event, OnCloudEventCallback callback) { + switch (event) { + case ArduinoIoTCloudEvent::SYNC: _on_sync_event_callback = callback; break; + case ArduinoIoTCloudEvent::CONNECT: _on_connect_event_callback = callback; break; + case ArduinoIoTCloudEvent::DISCONNECT: _on_disconnect_event_callback = callback; break; + } +}; + +void ArduinoIoTCloudClass::execCloudEventCallback(OnCloudEventCallback& callback, void* callback_arg) { + if (callback) { + (*callback)(callback_arg); + } +} +void ArduinoIoTCloudClass::printConnectionStatus(ArduinoIoTConnectionStatus status) { + switch (status) { + case ArduinoIoTConnectionStatus::IDLE: Debug.print(DBG_INFO, "Arduino IoT Cloud Connection status: IDLE"); break; + case ArduinoIoTConnectionStatus::ERROR: Debug.print(DBG_ERROR, "Arduino IoT Cloud Connection status: ERROR"); break; + case ArduinoIoTConnectionStatus::CONNECTING: Debug.print(DBG_INFO, "Arduino IoT Cloud Connection status: CONNECTING"); break; + case ArduinoIoTConnectionStatus::RECONNECTING: Debug.print(DBG_INFO, "Arduino IoT Cloud Connection status: RECONNECTING"); break; + case ArduinoIoTConnectionStatus::CONNECTED: Debug.print(DBG_INFO, "Arduino IoT Cloud Connection status: CONNECTED"); break; + case ArduinoIoTConnectionStatus::DISCONNECTED: Debug.print(DBG_ERROR, "Arduino IoT Cloud Connection status: DISCONNECTED"); break; + } +} \ No newline at end of file diff --git a/src/ArduinoIoTCloud.h b/src/ArduinoIoTCloud.h index e757cbef1..fdc372deb 100644 --- a/src/ArduinoIoTCloud.h +++ b/src/ArduinoIoTCloud.h @@ -100,104 +100,39 @@ class ArduinoIoTCloudClass { static unsigned long const DEFAULT_MIN_TIME_BETWEEN_UPDATES_MILLIS = 500; /* Data rate throttled to 2 Hz */ - void addPropertyReal(ArduinoCloudProperty & property, String name, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS) { - addPropertyReal(property, name, -1, permission_type, seconds, fn, minDelta, synFn); - } + void addPropertyReal(ArduinoCloudProperty& property, String name, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS); - void addPropertyReal(ArduinoCloudProperty& property, String name, int tag, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(ArduinoCloudProperty& property) = CLOUD_WINS) { - Permission permission = Permission::ReadWrite; - if (permission_type == READ) { - permission = Permission::Read; - } else if (permission_type == WRITE) { - permission = Permission::Write; - } else { - permission = Permission::ReadWrite; - } - - if (seconds == ON_CHANGE) { - Thing.addPropertyReal(property, name, permission, tag).publishOnChange(minDelta, DEFAULT_MIN_TIME_BETWEEN_UPDATES_MILLIS).onUpdate(fn).onSync(synFn); - } else { - Thing.addPropertyReal(property, name, permission, tag).publishEvery(seconds).onUpdate(fn).onSync(synFn); - } - } + void addPropertyReal(ArduinoCloudProperty& property, String name, int tag, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS); - void addPropertyReal(bool& property, String name, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS) { - addPropertyReal(property, name, -1, permission_type, seconds, fn, minDelta, synFn); - } + void addPropertyReal(bool& property, String name, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS); + void addPropertyReal(bool& property, String name, int tag, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS); + ArduinoCloudProperty& addPropertyReal(bool& property, String name, Permission const permission); + ArduinoCloudProperty& addPropertyReal(bool& property, String name, int tag, Permission const permission); - void addPropertyReal(bool& property, String name, int tag, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS) { - ArduinoCloudProperty *p = new CloudWrapperBool(property); - addPropertyReal(*p, name, tag, permission_type, seconds, fn, minDelta, synFn); - } - ArduinoCloudProperty& addPropertyReal(bool& property, String name, Permission const permission) { - return addPropertyReal(property, name, -1, permission); - } - ArduinoCloudProperty& addPropertyReal(bool& property, String name, int tag, Permission const permission) { - ArduinoCloudProperty *p = new CloudWrapperBool(property); - return Thing.addPropertyReal(*p, name, permission, tag); - } + void addPropertyReal(float& property, String name, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS); - void addPropertyReal(float& property, String name, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS) { - addPropertyReal(property, name, -1, permission_type, seconds, fn, minDelta, synFn); - } + void addPropertyReal(float& property, String name, int tag, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS); - void addPropertyReal(float& property, String name, int tag, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS) { - ArduinoCloudProperty *p = new CloudWrapperFloat(property); - addPropertyReal(*p, name, tag, permission_type, seconds, fn, minDelta, synFn); - } + ArduinoCloudProperty& addPropertyReal(float& property, String name, Permission const permission); - ArduinoCloudProperty& addPropertyReal(float& property, String name, Permission const permission) { - return addPropertyReal(property, name, -1, permission); - } + ArduinoCloudProperty& addPropertyReal(float& property, String name, int tag, Permission const permission); - ArduinoCloudProperty& addPropertyReal(float& property, String name, int tag, Permission const permission) { - ArduinoCloudProperty *p = new CloudWrapperFloat(property); - return Thing.addPropertyReal(*p, name, permission, tag); - } + void addPropertyReal(int& property, String name, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS); - void addPropertyReal(int& property, String name, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS) { - addPropertyReal(property, name, -1, permission_type, seconds, fn, minDelta, synFn); - } + void addPropertyReal(int& property, String name, int tag, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS); - void addPropertyReal(int& property, String name, int tag, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS) { - ArduinoCloudProperty *p = new CloudWrapperInt(property); - addPropertyReal(*p, name, tag, permission_type, seconds, fn, minDelta, synFn); - } + ArduinoCloudProperty& addPropertyReal(int& property, String name, Permission const permission); - ArduinoCloudProperty& addPropertyReal(int& property, String name, Permission const permission) { - return addPropertyReal(property, name, -1, permission); - } + ArduinoCloudProperty& addPropertyReal(int& property, String name, int tag, Permission const permission); - ArduinoCloudProperty& addPropertyReal(int& property, String name, int tag, Permission const permission) { - ArduinoCloudProperty *p = new CloudWrapperInt(property); - return Thing.addPropertyReal(*p, name, permission, tag); - } + void addPropertyReal(String& property, String name, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS); + void addPropertyReal(String& property, String name, int tag, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS); + ArduinoCloudProperty& addPropertyReal(String& property, String name, Permission const permission); - void addPropertyReal(String& property, String name, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS) { - addPropertyReal(property, name, -1, permission_type, seconds, fn, minDelta, synFn); - } + ArduinoCloudProperty& addPropertyReal(String& property, String name, int tag, Permission const permission); - void addPropertyReal(String& property, String name, int tag, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS) { - ArduinoCloudProperty *p = new CloudWrapperString(property); - addPropertyReal(*p, name, tag, permission_type, seconds, fn, minDelta, synFn); - } + void addCallback(ArduinoIoTCloudEvent const event, OnCloudEventCallback callback); - ArduinoCloudProperty& addPropertyReal(String& property, String name, Permission const permission) { - return addPropertyReal(property, name, -1, permission); - } - - ArduinoCloudProperty& addPropertyReal(String& property, String name, int tag, Permission const permission) { - ArduinoCloudProperty *p = new CloudWrapperString(property); - return Thing.addPropertyReal(*p, name, permission, tag); - } - - void addCallback(ArduinoIoTCloudEvent const event, OnCloudEventCallback callback) { - switch (event) { - case ArduinoIoTCloudEvent::SYNC: _on_sync_event_callback = callback; break; - case ArduinoIoTCloudEvent::CONNECT: _on_connect_event_callback = callback; break; - case ArduinoIoTCloudEvent::DISCONNECT: _on_disconnect_event_callback = callback; break; - } - }; protected: @@ -231,21 +166,8 @@ class ArduinoIoTCloudClass { OnCloudEventCallback _on_connect_event_callback = NULL; OnCloudEventCallback _on_disconnect_event_callback = NULL; - static void execCloudEventCallback(OnCloudEventCallback & callback, void * callback_arg) { - if (callback) { - (*callback)(callback_arg); - } - } - static void printConnectionStatus(ArduinoIoTConnectionStatus status) { - switch (status) { - case ArduinoIoTConnectionStatus::IDLE: Debug.print(DBG_INFO, "Arduino IoT Cloud Connection status: IDLE"); break; - case ArduinoIoTConnectionStatus::ERROR: Debug.print(DBG_ERROR, "Arduino IoT Cloud Connection status: ERROR"); break; - case ArduinoIoTConnectionStatus::CONNECTING: Debug.print(DBG_INFO, "Arduino IoT Cloud Connection status: CONNECTING"); break; - case ArduinoIoTConnectionStatus::RECONNECTING: Debug.print(DBG_INFO, "Arduino IoT Cloud Connection status: RECONNECTING"); break; - case ArduinoIoTConnectionStatus::CONNECTED: Debug.print(DBG_INFO, "Arduino IoT Cloud Connection status: CONNECTED"); break; - case ArduinoIoTConnectionStatus::DISCONNECTED: Debug.print(DBG_ERROR, "Arduino IoT Cloud Connection status: DISCONNECTED"); break; - } - } + static void execCloudEventCallback(OnCloudEventCallback& callback, void* callback_arg); + static void printConnectionStatus(ArduinoIoTConnectionStatus status); }; #if defined(ARDUINO_SAMD_MKRGSM1400) || defined(ARDUINO_SAMD_MKRWIFI1010) || defined(ARDUINO_SAMD_MKR1000) || defined(ARDUINO_SAMD_NANO_33_IOT) diff --git a/src/ArduinoIoTCloudTCP.cpp b/src/ArduinoIoTCloudTCP.cpp index 35fcfb886..7d53ada9c 100644 --- a/src/ArduinoIoTCloudTCP.cpp +++ b/src/ArduinoIoTCloudTCP.cpp @@ -29,15 +29,15 @@ #endif #ifdef BOARD_HAS_ECCX08 - const static int keySlot = 0; - const static int compressedCertSlot = 10; + const static int keySlot = 0; + const static int compressedCertSlot = 10; const static int serialNumberAndAuthorityKeyIdentifierSlot = 11; - const static int deviceIdSlot = 12; + const static int deviceIdSlot = 12; #endif -const static int CONNECT_SUCCESS = 1; -const static int CONNECT_FAILURE = 0; -const static int CONNECT_FAILURE_SUBSCRIBE = -1; +const static int CONNECT_SUCCESS = 1; +const static int CONNECT_FAILURE = 0; +const static int CONNECT_FAILURE_SUBSCRIBE = -1; static unsigned long getTime() { if (!ArduinoCloud.getConnection()) { From 94e6fc55a36c63f3ba423180715f831f2c260b07 Mon Sep 17 00:00:00 2001 From: fabio Date: Thu, 19 Dec 2019 10:37:46 +0100 Subject: [PATCH 12/21] fix formatting --- src/ArduinoIoTCloud.cpp | 12 ++++++------ src/ArduinoIoTCloud.h | 6 +++--- src/ArduinoIoTCloudLPWAN.cpp | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/ArduinoIoTCloud.cpp b/src/ArduinoIoTCloud.cpp index bd72ee437..1556c2a12 100644 --- a/src/ArduinoIoTCloud.cpp +++ b/src/ArduinoIoTCloud.cpp @@ -110,8 +110,8 @@ ArduinoCloudProperty& ArduinoIoTCloudClass::addPropertyReal(String& property, St void ArduinoIoTCloudClass::addCallback(ArduinoIoTCloudEvent const event, OnCloudEventCallback callback) { switch (event) { - case ArduinoIoTCloudEvent::SYNC: _on_sync_event_callback = callback; break; - case ArduinoIoTCloudEvent::CONNECT: _on_connect_event_callback = callback; break; + case ArduinoIoTCloudEvent::SYNC: _on_sync_event_callback = callback; break; + case ArduinoIoTCloudEvent::CONNECT: _on_connect_event_callback = callback; break; case ArduinoIoTCloudEvent::DISCONNECT: _on_disconnect_event_callback = callback; break; } }; @@ -123,11 +123,11 @@ void ArduinoIoTCloudClass::execCloudEventCallback(OnCloudEventCallback& callback } void ArduinoIoTCloudClass::printConnectionStatus(ArduinoIoTConnectionStatus status) { switch (status) { - case ArduinoIoTConnectionStatus::IDLE: Debug.print(DBG_INFO, "Arduino IoT Cloud Connection status: IDLE"); break; + case ArduinoIoTConnectionStatus::IDLE: Debug.print(DBG_INFO, "Arduino IoT Cloud Connection status: IDLE"); break; case ArduinoIoTConnectionStatus::ERROR: Debug.print(DBG_ERROR, "Arduino IoT Cloud Connection status: ERROR"); break; - case ArduinoIoTConnectionStatus::CONNECTING: Debug.print(DBG_INFO, "Arduino IoT Cloud Connection status: CONNECTING"); break; - case ArduinoIoTConnectionStatus::RECONNECTING: Debug.print(DBG_INFO, "Arduino IoT Cloud Connection status: RECONNECTING"); break; - case ArduinoIoTConnectionStatus::CONNECTED: Debug.print(DBG_INFO, "Arduino IoT Cloud Connection status: CONNECTED"); break; + case ArduinoIoTConnectionStatus::CONNECTING: Debug.print(DBG_INFO, "Arduino IoT Cloud Connection status: CONNECTING"); break; + case ArduinoIoTConnectionStatus::RECONNECTING: Debug.print(DBG_INFO, "Arduino IoT Cloud Connection status: RECONNECTING"); break; + case ArduinoIoTConnectionStatus::CONNECTED: Debug.print(DBG_INFO, "Arduino IoT Cloud Connection status: CONNECTED"); break; case ArduinoIoTConnectionStatus::DISCONNECTED: Debug.print(DBG_ERROR, "Arduino IoT Cloud Connection status: DISCONNECTED"); break; } } \ No newline at end of file diff --git a/src/ArduinoIoTCloud.h b/src/ArduinoIoTCloud.h index fdc372deb..2d198dd18 100644 --- a/src/ArduinoIoTCloud.h +++ b/src/ArduinoIoTCloud.h @@ -162,11 +162,11 @@ class ArduinoIoTCloudClass { int _lastSyncRequestTickTime = 0; - OnCloudEventCallback _on_sync_event_callback = NULL; - OnCloudEventCallback _on_connect_event_callback = NULL; + OnCloudEventCallback _on_sync_event_callback = NULL; + OnCloudEventCallback _on_connect_event_callback = NULL; OnCloudEventCallback _on_disconnect_event_callback = NULL; - static void execCloudEventCallback(OnCloudEventCallback& callback, void* callback_arg); + static void execCloudEventCallback(OnCloudEventCallback & callback, void * callback_arg); static void printConnectionStatus(ArduinoIoTConnectionStatus status); }; diff --git a/src/ArduinoIoTCloudLPWAN.cpp b/src/ArduinoIoTCloudLPWAN.cpp index 6f05a15e8..a9fc76b36 100644 --- a/src/ArduinoIoTCloudLPWAN.cpp +++ b/src/ArduinoIoTCloudLPWAN.cpp @@ -32,7 +32,7 @@ ArduinoIoTCloudLPWAN::~ArduinoIoTCloudLPWAN() { int ArduinoIoTCloudLPWAN::connect() { _connection->connect(); - int state = _connection->getStatus() == NetworkConnectionState::INIT ? 1 : 0; + const int state = _connection->getStatus() == NetworkConnectionState::INIT ? 1 : 0; return state; } From f12499cbc4cca3006860ecd5be539ce1b981bb8d Mon Sep 17 00:00:00 2001 From: fabio Date: Thu, 19 Dec 2019 16:10:09 +0100 Subject: [PATCH 13/21] update cloudserial #ifdef --- src/CloudSerial.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/CloudSerial.cpp b/src/CloudSerial.cpp index 88097711a..9522f9bce 100644 --- a/src/CloudSerial.cpp +++ b/src/CloudSerial.cpp @@ -14,7 +14,10 @@ software without disclosing the source code of your own applications. To purchase a commercial license, send an email to license@arduino.cc. */ -#if defined(ARDUINO_SAMD_MKRGSM1400) || defined(ARDUINO_SAMD_MKRWIFI1010) || defined(ARDUINO_SAMD_MKR1000) || defined(ARDUINO_SAMD_NANO_33_IOT) || defined(ARDUINO_ESP8266_ESP12) || defined(ARDUINO_ARCH_ESP32) || defined(ESP8266) +#include "ArduinoIoTCloud_Defines.h" +#ifndef HAS_LORA + +//defined(ARDUINO_SAMD_MKRGSM1400) || defined(ARDUINO_SAMD_MKRWIFI1010) || defined(ARDUINO_SAMD_MKR1000) || defined(ARDUINO_SAMD_NANO_33_IOT) || defined(ARDUINO_ESP8266_ESP12) || defined(ARDUINO_ARCH_ESP32) || defined(ESP8266) #include "ArduinoIoTCloud.h" #include "CloudSerial.h" From 9ada633a15bd38d23d93e5b2f32c6eddc27bd9d6 Mon Sep 17 00:00:00 2001 From: fabio Date: Thu, 19 Dec 2019 16:16:55 +0100 Subject: [PATCH 14/21] delete comment CloudSerial --- src/CloudSerial.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/CloudSerial.cpp b/src/CloudSerial.cpp index 9522f9bce..72622adfe 100644 --- a/src/CloudSerial.cpp +++ b/src/CloudSerial.cpp @@ -17,8 +17,6 @@ #include "ArduinoIoTCloud_Defines.h" #ifndef HAS_LORA -//defined(ARDUINO_SAMD_MKRGSM1400) || defined(ARDUINO_SAMD_MKRWIFI1010) || defined(ARDUINO_SAMD_MKR1000) || defined(ARDUINO_SAMD_NANO_33_IOT) || defined(ARDUINO_ESP8266_ESP12) || defined(ARDUINO_ARCH_ESP32) || defined(ESP8266) - #include "ArduinoIoTCloud.h" #include "CloudSerial.h" From c2a03b9d0018805dbd4b03f22f3013b35283cf84 Mon Sep 17 00:00:00 2001 From: fabio Date: Fri, 20 Dec 2019 16:00:55 +0100 Subject: [PATCH 15/21] change ifdef conditions --- src/ArduinoIoTCloud.h | 4 ++-- src/ArduinoIoTCloudLPWAN.cpp | 4 ++-- src/ArduinoIoTCloudTCP.cpp | 3 ++- src/ArduinoIoTCloud_Defines.h | 1 + 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/ArduinoIoTCloud.h b/src/ArduinoIoTCloud.h index 2d198dd18..b5702aa98 100644 --- a/src/ArduinoIoTCloud.h +++ b/src/ArduinoIoTCloud.h @@ -170,10 +170,10 @@ class ArduinoIoTCloudClass { static void printConnectionStatus(ArduinoIoTConnectionStatus status); }; -#if defined(ARDUINO_SAMD_MKRGSM1400) || defined(ARDUINO_SAMD_MKRWIFI1010) || defined(ARDUINO_SAMD_MKR1000) || defined(ARDUINO_SAMD_NANO_33_IOT) +#ifdef HAS_TCP #include "ArduinoIoTCloudTCP.h" -#elif defined(ARDUINO_SAMD_MKRWAN1300) || defined(ARDUINO_SAMD_MKRWAN1310) +#elif defined(HAS_LORA) #include "ArduinoIoTCloudLPWAN.h" #endif diff --git a/src/ArduinoIoTCloudLPWAN.cpp b/src/ArduinoIoTCloudLPWAN.cpp index a9fc76b36..be01b27f6 100644 --- a/src/ArduinoIoTCloudLPWAN.cpp +++ b/src/ArduinoIoTCloudLPWAN.cpp @@ -14,8 +14,8 @@ software without disclosing the source code of your own applications. To purchase a commercial license, send an email to license@arduino.cc. */ - -#if defined(ARDUINO_SAMD_MKRWAN1300) || defined(ARDUINO_SAMD_MKRWAN1310) +#include "ArduinoIoTCloud_Defines.h" +#ifdef HAS_LORA #include diff --git a/src/ArduinoIoTCloudTCP.cpp b/src/ArduinoIoTCloudTCP.cpp index 7d53ada9c..3db419853 100644 --- a/src/ArduinoIoTCloudTCP.cpp +++ b/src/ArduinoIoTCloudTCP.cpp @@ -14,8 +14,9 @@ software without disclosing the source code of your own applications. To purchase a commercial license, send an email to license@arduino.cc. */ -#if defined(ARDUINO_SAMD_MKRGSM1400) || defined(ARDUINO_SAMD_MKRWIFI1010) || defined(ARDUINO_SAMD_MKR1000) || defined(ARDUINO_SAMD_NANO_33_IOT) +#include "ArduinoIoTCloud_Defines.h" +#ifdef HAS_TCP #include #ifdef BOARD_HAS_ECCX08 #include "utility/ECCX08Cert.h" diff --git a/src/ArduinoIoTCloud_Defines.h b/src/ArduinoIoTCloud_Defines.h index 7c2810adf..da6775cca 100644 --- a/src/ArduinoIoTCloud_Defines.h +++ b/src/ArduinoIoTCloud_Defines.h @@ -31,6 +31,7 @@ #if defined(ARDUINO_ESP8266_ESP12) || defined(ARDUINO_ARCH_ESP32) || defined(ESP8266) #define BOARD_ESP + #define HAS_TCP #endif #endif /* ARDUINO_IOT_CLOUD_DEFINES_H_ */ From 776e405806a72d9f6166cf2a320a6f7a3b217f1e Mon Sep 17 00:00:00 2001 From: Alexander Entinger Date: Thu, 16 Jan 2020 16:38:37 +0100 Subject: [PATCH 16/21] Adding CI build for MKRWAN1310 (probably ArduinoIoTCloud_LED_switch/ArduinoIoTCloud_Travis_CI need to be updated too in order to support MKRWAN boards --- .travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 8c2f3b895..1a2895f63 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,6 +7,8 @@ matrix: - BOARD="arduino:samd:mkrwifi1010" - env: - BOARD="arduino:samd:mkrgsm1400" + - env: + - BOARD="arduino:samd:mkrwan1300" - env: - BOARD="esp8266:esp8266:huzzah" - env: @@ -82,7 +84,7 @@ install: - ln -s $PWD $HOME/Arduino/libraries/. script: - | - if [ "$BOARD" == "arduino:samd:mkr1000" ] || [ "$BOARD" == "arduino:samd:mkrwifi1010" ] || [ "$BOARD" == "arduino:samd:mkrgsm1400" ]; then + if [ "$BOARD" == "arduino:samd:mkr1000" ] || [ "$BOARD" == "arduino:samd:mkrwifi1010" ] || [ "$BOARD" == "arduino:samd:mkrgsm1400" ] || [ "$BOARD" == "arduino:samd:mkrwan1300" ]; then buildExampleSketch ArduinoIoTCloud_LED_switch; buildExampleSketch ArduinoIoTCloud_Travis_CI; buildExampleUtilitySketch Provisioning; From 4254e4748ec26752ef425875e943caae92a95fcf Mon Sep 17 00:00:00 2001 From: fabio Date: Fri, 17 Jan 2020 14:02:53 +0100 Subject: [PATCH 17/21] edit sketch for lora boards --- .travis.yml | 1 + .../ArduinoIoTCloud_LED_switch.ino | 9 +++-- .../arduino_secrets.h | 6 +++ .../thingProperties.h | 13 ++++++- .../ArduinoIoTCloud_Travis_CI.ino | 1 + .../arduino_secrets.h | 7 ++++ .../thingProperties.h | 39 ++++++++++++++++++- 7 files changed, 68 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1a2895f63..6374f1531 100644 --- a/.travis.yml +++ b/.travis.yml @@ -71,6 +71,7 @@ before_install: - installLibrary arduino-libraries/ArduinoBearSSL - installLibrary arduino-libraries/ArduinoMqttClient - installLibrary arduino-libraries/MKRGSM + - installLibrary arduino-libraries/MKRWAN - installLibrary arduino-libraries/RTCZero - installLibrary arduino-libraries/WiFi101 - installLibrary arduino-libraries/WiFiNINA diff --git a/examples/ArduinoIoTCloud_LED_switch/ArduinoIoTCloud_LED_switch.ino b/examples/ArduinoIoTCloud_LED_switch/ArduinoIoTCloud_LED_switch.ino index 090e8e045..b1b435382 100644 --- a/examples/ArduinoIoTCloud_LED_switch/ArduinoIoTCloud_LED_switch.ino +++ b/examples/ArduinoIoTCloud_LED_switch/ArduinoIoTCloud_LED_switch.ino @@ -6,14 +6,15 @@ When you flip the switch in the Cloud dashboard the onboard LED lights gets turned ON or OFF. IMPORTANT: - This sketch will work with both WiFi and GSM enabled boards supported by Arduino IoT Cloud. - By default, settings for WiFi are chosen. If you prefer to use a GSM board take a look at thingProperties.h arduino_secrets.h, - to make sure you uncomment what's needed and comment incompatible instructions. + This sketch will work with WiFi, GSM and Lora enabled boards supported by Arduino IoT Cloud. + On a LoRa board, if it is configuered as a class A device (default and preferred option), values from Cloud dashboard are received + only after a value is sent to Cloud. This sketch is compatible with: - MKR 1000 - MKR WIFI 1010 - MKR GSM 1400 + - MKR WAN 1300/1310 */ #include "arduino_secrets.h" #include "thingProperties.h" @@ -30,7 +31,7 @@ void setup() { // initProperties takes care of connecting your sketch variables to the ArduinoIoTCloud object initProperties(); - // tell ArduinoIoTCloud to use our WiFi connection + // tell ArduinoIoTCloud to use right connection handler ArduinoCloud.begin(ArduinoIoTPreferredConnection); /* diff --git a/examples/ArduinoIoTCloud_LED_switch/arduino_secrets.h b/examples/ArduinoIoTCloud_LED_switch/arduino_secrets.h index 87593f2dd..9a5f514b9 100644 --- a/examples/ArduinoIoTCloud_LED_switch/arduino_secrets.h +++ b/examples/ArduinoIoTCloud_LED_switch/arduino_secrets.h @@ -13,3 +13,9 @@ #define SECRET_LOGIN "" #define SECRET_PASS "" #endif + +/* MKR WAN 1300/1310 */ +#if defined(BOARD_HAS_LORA) + #define SECRET_APP_EUI "" + #define SECRET_APP_KEY "" +#endif diff --git a/examples/ArduinoIoTCloud_LED_switch/thingProperties.h b/examples/ArduinoIoTCloud_LED_switch/thingProperties.h index a04fe7c00..04d75e2ce 100644 --- a/examples/ArduinoIoTCloud_LED_switch/thingProperties.h +++ b/examples/ArduinoIoTCloud_LED_switch/thingProperties.h @@ -3,6 +3,7 @@ #if defined(BOARD_HAS_WIFI) #elif defined(BOARD_HAS_GSM) +#elif defined(BOARD_HAS_LORA) #else #error "Arduino IoT Cloud currently only supports MKR1000, MKR WiFi 1010 and MKR GSM 1400" #endif @@ -18,12 +19,20 @@ int potentiometer; void initProperties() { ArduinoCloud.setThingId(THING_ID); - ArduinoCloud.addProperty(led, READWRITE, ON_CHANGE, onLedChange); - ArduinoCloud.addProperty(potentiometer, READ, ON_CHANGE); + #if defined(BOARD_HAS_WIFI) || defined(BOARD_HAS_GSM) + ArduinoCloud.addProperty(led, READWRITE, ON_CHANGE, onLedChange); + ArduinoCloud.addProperty(potentiometer, READ, ON_CHANGE); + #elif defined(BOARD_HAS_LORA) + ArduinoCloud.addProperty(led, 1, READWRITE, ON_CHANGE, onLedChange); + ArduinoCloud.addProperty(potentiometer, 2, READ, ON_CHANGE); + #endif + } #if defined(BOARD_HAS_WIFI) WiFiConnectionHandler ArduinoIoTPreferredConnection(SECRET_SSID, SECRET_PASS); #elif defined(BOARD_HAS_GSM) GSMConnectionHandler ArduinoIoTPreferredConnection(SECRET_PIN, SECRET_APN, SECRET_LOGIN, SECRET_PASS); +#elif defined(BOARD_HAS_LORA) + LoRaConnectionHandler ArduinoIoTPreferredConnection(SECRET_APP_EUI, SECRET_APP_KEY, _lora_band::EU868, _lora_class::CLASS_A ); #endif diff --git a/examples/ArduinoIoTCloud_Travis_CI/ArduinoIoTCloud_Travis_CI.ino b/examples/ArduinoIoTCloud_Travis_CI/ArduinoIoTCloud_Travis_CI.ino index 3385d8fb4..bcb46b680 100644 --- a/examples/ArduinoIoTCloud_Travis_CI/ArduinoIoTCloud_Travis_CI.ino +++ b/examples/ArduinoIoTCloud_Travis_CI/ArduinoIoTCloud_Travis_CI.ino @@ -7,6 +7,7 @@ - MKR 1000 - MKR WIFI 1010 - MKR GSM 1400 + - MKR WAN 1300/1310 */ #include "arduino_secrets.h" diff --git a/examples/ArduinoIoTCloud_Travis_CI/arduino_secrets.h b/examples/ArduinoIoTCloud_Travis_CI/arduino_secrets.h index 87593f2dd..fd08461a0 100644 --- a/examples/ArduinoIoTCloud_Travis_CI/arduino_secrets.h +++ b/examples/ArduinoIoTCloud_Travis_CI/arduino_secrets.h @@ -13,3 +13,10 @@ #define SECRET_LOGIN "" #define SECRET_PASS "" #endif + +/* MKR WAN 1300/1310 */ +#if defined(BOARD_HAS_LORA) + #define SECRET_APP_EUI "" + #define SECRET_APP_KEY "" +#endif + diff --git a/examples/ArduinoIoTCloud_Travis_CI/thingProperties.h b/examples/ArduinoIoTCloud_Travis_CI/thingProperties.h index 05f981cce..c41375759 100644 --- a/examples/ArduinoIoTCloud_Travis_CI/thingProperties.h +++ b/examples/ArduinoIoTCloud_Travis_CI/thingProperties.h @@ -7,8 +7,9 @@ #if defined(BOARD_HAS_WIFI) #elif defined(BOARD_HAS_GSM) +#elif defined(BOARD_HAS_LORA) #else - #error "Arduino IoT Cloud currently only supports MKR1000, MKR WiFi 1010 and MKR GSM 1400" + #error "Arduino IoT Cloud currently only supports MKR1000, MKR WiFi 1010, MKR GSM 1400 and MKR WAN 1300/1310" #endif /****************************************************************************** @@ -57,6 +58,8 @@ String str_property_8; WiFiConnectionHandler ArduinoIoTPreferredConnection(SECRET_SSID, SECRET_PASS); #elif defined(BOARD_HAS_GSM) GSMConnectionHandler ArduinoIoTPreferredConnection(SECRET_PIN, SECRET_APN, SECRET_LOGIN, SECRET_PASS); +#elif defined(BOARD_HAS_LORA) + LoRaConnectionHandler ArduinoIoTPreferredConnection(SECRET_APP_EUI, SECRET_APP_KEY,EU868); #endif /****************************************************************************** @@ -71,7 +74,7 @@ void onStringPropertyChange(); /****************************************************************************** FUNCTIONS ******************************************************************************/ - +#if defined(BOARD_HAS_WIFI) || defined(BOARD_HAS_GSM) void initProperties() { ArduinoCloud.setThingId(THING_ID); @@ -101,3 +104,35 @@ void initProperties() { ArduinoCloud.addProperty(str_property_7, Permission::ReadWrite).publishEvery(1 * SECONDS).onSync(CLOUD_WINS); ArduinoCloud.addProperty(str_property_8, Permission::ReadWrite).publishEvery(1 * SECONDS).onSync(DEVICE_WINS); } + +#elif defined(BOARD_HAS_LORA) +void initProperties() { + ArduinoCloud.setThingId(THING_ID); + + ArduinoCloud.addProperty(bool_property_1, 1, READWRITE, 1 * SECONDS); + ArduinoCloud.addProperty(int_property_1, 2, READ, 2 * MINUTES); + ArduinoCloud.addProperty(float_property_1, 3, WRITE, 3 * HOURS); + ArduinoCloud.addProperty(str_property_1, 4, READWRITE, 4 * DAYS); + + ArduinoCloud.addProperty(bool_property_2, 5, Permission::ReadWrite).publishEvery(1 * SECONDS); + ArduinoCloud.addProperty(int_property_2, 6, Permission::Read).publishEvery(1 * MINUTES); + ArduinoCloud.addProperty(float_property_2, 7, Permission::Write).publishEvery(3 * HOURS); + ArduinoCloud.addProperty(str_property_2, 8, Permission::ReadWrite).publishEvery(4 * DAYS); + + ArduinoCloud.addProperty(int_property_3, 9, READWRITE, ON_CHANGE); /* Default 'minDelta' = 0 */ + ArduinoCloud.addProperty(int_property_4, 10, READWRITE, ON_CHANGE, onIntPropertyChange); /* Default 'minDelta' = 0 */ + ArduinoCloud.addProperty(int_property_5, 11, READWRITE, ON_CHANGE, 0 /* onIntPropertyChange */, MIN_DELTA_INT_PROPERTY); + ArduinoCloud.addProperty(int_property_6, 12, READWRITE, ON_CHANGE, onIntPropertyChange, MIN_DELTA_INT_PROPERTY); + + ArduinoCloud.addProperty(float_property_3, 13, Permission::ReadWrite).publishOnChange(MIN_DELTA_FLOAT_PROPERTY); + ArduinoCloud.addProperty(float_property_4, 14, Permission::ReadWrite).publishOnChange(MIN_DELTA_FLOAT_PROPERTY).onUpdate(onFloatPropertyChange); + + ArduinoCloud.addProperty(str_property_3, 15, READWRITE, 1 * SECONDS, 0 /* onStringPropertyChange */, 0.0 /* 'minDelta' */, MOST_RECENT_WINS); + ArduinoCloud.addProperty(str_property_4, 16, READWRITE, 1 * SECONDS, 0 /* onStringPropertyChange */, 0.0 /* 'minDelta' */, CLOUD_WINS); + ArduinoCloud.addProperty(str_property_5, 17, READWRITE, 1 * SECONDS, 0 /* onStringPropertyChange */, 0.0 /* 'minDelta' */, DEVICE_WINS); + + ArduinoCloud.addProperty(str_property_6, 18, Permission::ReadWrite).publishEvery(1 * SECONDS).onSync(MOST_RECENT_WINS); + ArduinoCloud.addProperty(str_property_7, 19, Permission::ReadWrite).publishEvery(1 * SECONDS).onSync(CLOUD_WINS); + ArduinoCloud.addProperty(str_property_8, 20, Permission::ReadWrite).publishEvery(1 * SECONDS).onSync(DEVICE_WINS); +} +#endif From 3284b6457188da4623a059e0468da2d8d1321ade Mon Sep 17 00:00:00 2001 From: fabio Date: Fri, 17 Jan 2020 15:13:20 +0100 Subject: [PATCH 18/21] fix Astyle --- examples/ArduinoIoTCloud_LED_switch/thingProperties.h | 10 +++++----- examples/ArduinoIoTCloud_Travis_CI/thingProperties.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/ArduinoIoTCloud_LED_switch/thingProperties.h b/examples/ArduinoIoTCloud_LED_switch/thingProperties.h index 04d75e2ce..10f13bd4f 100644 --- a/examples/ArduinoIoTCloud_LED_switch/thingProperties.h +++ b/examples/ArduinoIoTCloud_LED_switch/thingProperties.h @@ -20,11 +20,11 @@ int potentiometer; void initProperties() { ArduinoCloud.setThingId(THING_ID); #if defined(BOARD_HAS_WIFI) || defined(BOARD_HAS_GSM) - ArduinoCloud.addProperty(led, READWRITE, ON_CHANGE, onLedChange); - ArduinoCloud.addProperty(potentiometer, READ, ON_CHANGE); + ArduinoCloud.addProperty(led, READWRITE, ON_CHANGE, onLedChange); + ArduinoCloud.addProperty(potentiometer, READ, ON_CHANGE); #elif defined(BOARD_HAS_LORA) - ArduinoCloud.addProperty(led, 1, READWRITE, ON_CHANGE, onLedChange); - ArduinoCloud.addProperty(potentiometer, 2, READ, ON_CHANGE); + ArduinoCloud.addProperty(led, 1, READWRITE, ON_CHANGE, onLedChange); + ArduinoCloud.addProperty(potentiometer, 2, READ, ON_CHANGE); #endif } @@ -34,5 +34,5 @@ void initProperties() { #elif defined(BOARD_HAS_GSM) GSMConnectionHandler ArduinoIoTPreferredConnection(SECRET_PIN, SECRET_APN, SECRET_LOGIN, SECRET_PASS); #elif defined(BOARD_HAS_LORA) - LoRaConnectionHandler ArduinoIoTPreferredConnection(SECRET_APP_EUI, SECRET_APP_KEY, _lora_band::EU868, _lora_class::CLASS_A ); + LoRaConnectionHandler ArduinoIoTPreferredConnection(SECRET_APP_EUI, SECRET_APP_KEY, _lora_band::EU868, _lora_class::CLASS_A); #endif diff --git a/examples/ArduinoIoTCloud_Travis_CI/thingProperties.h b/examples/ArduinoIoTCloud_Travis_CI/thingProperties.h index c41375759..5f31fd386 100644 --- a/examples/ArduinoIoTCloud_Travis_CI/thingProperties.h +++ b/examples/ArduinoIoTCloud_Travis_CI/thingProperties.h @@ -59,7 +59,7 @@ String str_property_8; #elif defined(BOARD_HAS_GSM) GSMConnectionHandler ArduinoIoTPreferredConnection(SECRET_PIN, SECRET_APN, SECRET_LOGIN, SECRET_PASS); #elif defined(BOARD_HAS_LORA) - LoRaConnectionHandler ArduinoIoTPreferredConnection(SECRET_APP_EUI, SECRET_APP_KEY,EU868); + LoRaConnectionHandler ArduinoIoTPreferredConnection(SECRET_APP_EUI, SECRET_APP_KEY, EU868); #endif /****************************************************************************** From a2970eb900247198d4f2132cbd37ef10c39dca46 Mon Sep 17 00:00:00 2001 From: fabio Date: Fri, 17 Jan 2020 15:52:39 +0100 Subject: [PATCH 19/21] fix codespell config for WAN --- extras/codespell-ignore-words-list.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/extras/codespell-ignore-words-list.txt b/extras/codespell-ignore-words-list.txt index e69de29bb..8f72ffef0 100644 --- a/extras/codespell-ignore-words-list.txt +++ b/extras/codespell-ignore-words-list.txt @@ -0,0 +1 @@ +WAN \ No newline at end of file From c20684be3a2c61a8c1cc4e9e1274b54e4ba3cab1 Mon Sep 17 00:00:00 2001 From: Alexander Entinger Date: Mon, 27 Jan 2020 14:21:22 +0100 Subject: [PATCH 20/21] There is no need to build 'Provisioning.ino' for MKRWAN 1310 --- .travis.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 6374f1531..68ff08503 100644 --- a/.travis.yml +++ b/.travis.yml @@ -85,11 +85,16 @@ install: - ln -s $PWD $HOME/Arduino/libraries/. script: - | - if [ "$BOARD" == "arduino:samd:mkr1000" ] || [ "$BOARD" == "arduino:samd:mkrwifi1010" ] || [ "$BOARD" == "arduino:samd:mkrgsm1400" ] || [ "$BOARD" == "arduino:samd:mkrwan1300" ]; then + if [ "$BOARD" == "arduino:samd:mkr1000" ] || [ "$BOARD" == "arduino:samd:mkrwifi1010" ] || [ "$BOARD" == "arduino:samd:mkrgsm1400" ]; then buildExampleSketch ArduinoIoTCloud_LED_switch; buildExampleSketch ArduinoIoTCloud_Travis_CI; buildExampleUtilitySketch Provisioning; fi + - | + if [ "$BOARD" == "arduino:samd:mkrwan1300" ]; then + buildExampleSketch ArduinoIoTCloud_LED_switch; + buildExampleSketch ArduinoIoTCloud_Travis_CI; + fi - | if [ "$BOARD" == "arduino:samd:mkr1000" ] || [ "$BOARD" == "arduino:samd:mkrwifi1010" ]; then buildExampleSketch WiFi_Cloud_Blink; From 103bfdefcef76137839029c84dfdea4378d8e6a8 Mon Sep 17 00:00:00 2001 From: Alexander Entinger Date: Mon, 27 Jan 2020 14:34:38 +0100 Subject: [PATCH 21/21] WAN must be written in lowercase in order to be correctly ignored (see codespell help for details) --- extras/codespell-ignore-words-list.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extras/codespell-ignore-words-list.txt b/extras/codespell-ignore-words-list.txt index 8f72ffef0..e49ad4874 100644 --- a/extras/codespell-ignore-words-list.txt +++ b/extras/codespell-ignore-words-list.txt @@ -1 +1 @@ -WAN \ No newline at end of file +wan