184 lines
4.3 KiB
C++
184 lines
4.3 KiB
C++
#include "AdafruitIO.h"
|
|
|
|
AdafruitIO::AdafruitIO(){}
|
|
|
|
void AdafruitIO::connect(const char *user, const char *key)
|
|
{
|
|
|
|
_username = user;
|
|
_key = key;
|
|
|
|
_init();
|
|
|
|
}
|
|
|
|
void AdafruitIO::connect(const __FlashStringHelper *user, const __FlashStringHelper *key)
|
|
{
|
|
|
|
_username = (const char*)user;
|
|
_key = (const char*)key;
|
|
|
|
_init();
|
|
|
|
}
|
|
|
|
AdafruitIO_Feed* AdafruitIO::feed(const char* name)
|
|
{
|
|
return new AdafruitIO_Feed(this, name);
|
|
}
|
|
|
|
AdafruitIO_Feed* AdafruitIO::feed(const __FlashStringHelper *name)
|
|
{
|
|
return new AdafruitIO_Feed(this, name);
|
|
}
|
|
|
|
void AdafruitIO::_init()
|
|
{
|
|
|
|
// we have never pinged, so set last ping to now
|
|
_last_ping = millis();
|
|
|
|
// call child class connect
|
|
_connect();
|
|
|
|
// dynamically allocate memory for err topic
|
|
_err_topic = (char *)malloc(sizeof(char) * (strlen(_username) + strlen(AIO_ERROR_TOPIC) + 1));
|
|
|
|
if(_err_topic) {
|
|
|
|
// build error topic
|
|
strcpy(_err_topic, _username);
|
|
strcat(_err_topic, AIO_ERROR_TOPIC);
|
|
|
|
// setup error sub
|
|
_subscriptions[0] = new Adafruit_MQTT_Subscribe(_mqtt, _err_topic);
|
|
_mqtt->subscribe(_subscriptions[0]);
|
|
|
|
} else {
|
|
|
|
// malloc failed
|
|
_err_topic = 0;
|
|
|
|
}
|
|
|
|
// dynamically allocate memory for throttle topic
|
|
_throttle_topic = (char *)malloc(sizeof(char) * (strlen(_username) + strlen(AIO_THROTTLE_TOPIC) + 1));
|
|
|
|
if(_throttle_topic) {
|
|
|
|
// build throttle topic
|
|
strcpy(_throttle_topic, _username);
|
|
strcat(_throttle_topic, AIO_THROTTLE_TOPIC);
|
|
|
|
// setup throttle sub
|
|
_subscriptions[1] = new Adafruit_MQTT_Subscribe(_mqtt, _throttle_topic);
|
|
_mqtt->subscribe(_subscriptions[1]);
|
|
|
|
} else {
|
|
|
|
// malloc failed
|
|
_throttle_topic = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void AdafruitIO::setErrorHandler(SubscribeCallbackBufferType cb)
|
|
{
|
|
_subscriptions[0]->setCallback(cb);
|
|
_subscriptions[1]->setCallback(cb);
|
|
}
|
|
|
|
const __FlashStringHelper* AdafruitIO::statusText()
|
|
{
|
|
|
|
switch(_status) {
|
|
|
|
// CONNECTING
|
|
case AIO_IDLE: return F("Idle. Waiting for connect to be called...");
|
|
case AIO_NET_DISCONNECTED: return F("Network disconnected.");
|
|
case AIO_DISCONNECTED: return F("Disconnected from Adafruit IO.");
|
|
|
|
// FAILURE
|
|
case AIO_NET_CONNECT_FAILED: return F("Network connection failed.");
|
|
case AIO_CONNECT_FAILED: return F("Adafruit IO connection failed.");
|
|
case AIO_FINGERPRINT_INVALID: return F("Adafruit IO SSL fingerprint verification failed.");
|
|
case AIO_AUTH_FAILED: return F("Adafruit IO authentication failed.");
|
|
|
|
// SUCCESS
|
|
case AIO_NET_CONNECTED: return F("Network connected.");
|
|
case AIO_CONNECTED: return F("Adafruit IO connected.");
|
|
case AIO_CONNECTED_INSECURE: return F("Adafruit IO connected. **THIS CONNECTION IS INSECURE** SSL/TLS not supported for this platform.");
|
|
case AIO_FINGERPRINT_UNSUPPORTED: return F("Adafruit IO connected over SSL/TLS. Fingerprint verification unsupported.");
|
|
case AIO_FINGERPRINT_VALID: return F("Adafruit IO connected over SSL/TLS. Fingerprint valid.");
|
|
|
|
default: return F("Unknown status code");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void AdafruitIO::run()
|
|
{
|
|
|
|
// loop until we have a connection
|
|
while(mqttStatus() != AIO_CONNECTED){}
|
|
|
|
_mqtt->processPackets(1000);
|
|
|
|
// ping to keep connection alive if needed
|
|
if(millis() > (_last_ping + AIO_PING_INTERVAL)) {
|
|
_mqtt->ping();
|
|
_last_ping = millis();
|
|
}
|
|
|
|
}
|
|
|
|
aio_status_t AdafruitIO::status()
|
|
{
|
|
|
|
aio_status_t net_status = networkStatus();
|
|
|
|
// if we aren't connected, return network status
|
|
if(net_status != AIO_NET_CONNECTED) {
|
|
_status = net_status;
|
|
return _status;
|
|
}
|
|
|
|
// check mqtt status and return
|
|
_status = mqttStatus();
|
|
return _status;
|
|
|
|
}
|
|
|
|
aio_status_t AdafruitIO::mqttStatus()
|
|
{
|
|
|
|
// if the connection failed,
|
|
// return so we don't hammer IO
|
|
if(_status == AIO_CONNECT_FAILED)
|
|
return _status;
|
|
|
|
if(_mqtt->connected())
|
|
return AIO_CONNECTED;
|
|
|
|
switch(_mqtt->connect(_username, _key)) {
|
|
case 0:
|
|
return AIO_CONNECTED;
|
|
case 1: // invalid mqtt protocol
|
|
case 2: // client id rejected
|
|
case 4: // malformed user/pass
|
|
case 5: // unauthorized
|
|
case 7: // banned
|
|
case -1: // general failure
|
|
return AIO_CONNECT_FAILED;
|
|
case 3: // mqtt service unavailable
|
|
case 6: // throttled
|
|
// delay to prevent fast reconnects
|
|
delay(AIO_THROTTLE_RECONNECT_INTERVAL);
|
|
return AIO_DISCONNECTED;
|
|
default:
|
|
return AIO_DISCONNECTED;
|
|
}
|
|
|
|
}
|