Connecting a Multi-Tech Systems Dragonfly™ to Twilio's Sync for IoT Quickstart. Blink a dev board LED.

Dependencies:   MQTT MbedJSONValue mbed mtsas

Fork of DragonflyMQTT by miao zhicheng

Code to connect a Multi-Tech® MultiConnect® Dragonfly™ to Twilio's Sync for IoT: https://www.twilio.com/docs/api/devices

Uses MQTT over TLS and subscribes to a topic where you can control an LED. See also our Quickstart using this code, here: https://www.twilio.com/docs/quickstart/sync-iot/mqtt-multi-tech-multiconnect-dragonfly-sync-iot

Committer:
miaotwilio
Date:
Tue May 09 13:16:48 2017 +0000
Revision:
0:b32fa0c757d7
Child:
1:5a896191c3c4
working prototype without CA validation

Who changed what in which revision?

UserRevisionLine numberNew contents of line
miaotwilio 0:b32fa0c757d7 1 #include <cyassl/ctaocrypt/types.h>
miaotwilio 0:b32fa0c757d7 2 #include "TlsMQTTClient.hpp"
miaotwilio 0:b32fa0c757d7 3
miaotwilio 0:b32fa0c757d7 4 TlsMQTTClient::TlsMQTTClient() :
miaotwilio 0:b32fa0c757d7 5 tcp(NULL), ctx(NULL), ssl(NULL),
miaotwilio 0:b32fa0c757d7 6 mqttClient(new MQTTClient(*this)) {
miaotwilio 0:b32fa0c757d7 7 }
miaotwilio 0:b32fa0c757d7 8
miaotwilio 0:b32fa0c757d7 9 int TlsMQTTClient::connect(const char* host, const int port,
miaotwilio 0:b32fa0c757d7 10 const char* certificates,
miaotwilio 0:b32fa0c757d7 11 MQTTPacket_connectData& options) {
miaotwilio 0:b32fa0c757d7 12 cleanupTransport();
miaotwilio 0:b32fa0c757d7 13
miaotwilio 0:b32fa0c757d7 14 // create TCP transport
miaotwilio 0:b32fa0c757d7 15 tcp = new TCPSocketConnection();
miaotwilio 0:b32fa0c757d7 16 if (tcp->connect(host, port)) {
miaotwilio 0:b32fa0c757d7 17 logError("tcp connection failed");
miaotwilio 0:b32fa0c757d7 18 goto fail;
miaotwilio 0:b32fa0c757d7 19 }
miaotwilio 0:b32fa0c757d7 20
miaotwilio 0:b32fa0c757d7 21 // setup SSL context
miaotwilio 0:b32fa0c757d7 22 ctx = CyaSSL_CTX_new((CYASSL_METHOD *)CyaSSLv23_client_method());
miaotwilio 0:b32fa0c757d7 23 { //Localize pMethod array for less overall memory time-use
miaotwilio 0:b32fa0c757d7 24 SSLMethod peerMethod = certificates != NULL ? (SSLMethod)(VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT) : VERIFY_NONE;
miaotwilio 0:b32fa0c757d7 25 std::string pMethod;
miaotwilio 0:b32fa0c757d7 26 if(peerMethod == VERIFY_NONE) {
miaotwilio 0:b32fa0c757d7 27 pMethod = "not verify peer";
miaotwilio 0:b32fa0c757d7 28 } else if (peerMethod == VERIFY_PEER) {
miaotwilio 0:b32fa0c757d7 29 pMethod = "verify peer if certificates available";
miaotwilio 0:b32fa0c757d7 30 //Load the CA certificate(s) (If using multiple, concatenate them in the buffer being passed)
miaotwilio 0:b32fa0c757d7 31 if (SSL_SUCCESS != CyaSSL_CTX_load_verify_buffer(ctx, (const unsigned char*)certificates, strlen(certificates), SSL_FILETYPE_PEM)) {
miaotwilio 0:b32fa0c757d7 32 logError("unable to load root certificates");
miaotwilio 0:b32fa0c757d7 33 goto fail;
miaotwilio 0:b32fa0c757d7 34 }
miaotwilio 0:b32fa0c757d7 35 }
miaotwilio 0:b32fa0c757d7 36 logDebug("SSL connection set to %s", pMethod.c_str());
miaotwilio 0:b32fa0c757d7 37 CyaSSL_CTX_set_verify(ctx, peerMethod, 0); //SSL_VERIFY_FAIL_IF_NO_PEER_CERT, VERIFY_NONE, SSL_VERIFY_PEER
miaotwilio 0:b32fa0c757d7 38 }
miaotwilio 0:b32fa0c757d7 39
miaotwilio 0:b32fa0c757d7 40 // setup SSL operations
miaotwilio 0:b32fa0c757d7 41 ssl = CyaSSL_new(ctx);
miaotwilio 0:b32fa0c757d7 42
miaotwilio 0:b32fa0c757d7 43 CyaSSL_SetIOReadCtx(ssl, this);
miaotwilio 0:b32fa0c757d7 44 CyaSSL_SetIORecv(ctx, ioRecv);
miaotwilio 0:b32fa0c757d7 45 CyaSSL_SetIOWriteCtx(ssl, this);
miaotwilio 0:b32fa0c757d7 46 CyaSSL_SetIOSend(ctx, ioSend);
miaotwilio 0:b32fa0c757d7 47
miaotwilio 0:b32fa0c757d7 48 // SSL connect
miaotwilio 0:b32fa0c757d7 49 {
miaotwilio 0:b32fa0c757d7 50 int ret = CyaSSL_connect(ssl);
miaotwilio 0:b32fa0c757d7 51
miaotwilio 0:b32fa0c757d7 52 if (ret != SSL_SUCCESS) {
miaotwilio 0:b32fa0c757d7 53 logError("SSL_connect failed");
miaotwilio 0:b32fa0c757d7 54 int err = CyaSSL_get_error(ssl, ret);
miaotwilio 0:b32fa0c757d7 55 char data[CYASSL_MAX_ERROR_SZ];
miaotwilio 0:b32fa0c757d7 56 char data_new[CYASSL_MAX_ERROR_SZ];
miaotwilio 0:b32fa0c757d7 57 strcpy(data_new, CyaSSL_ERR_error_string(err, data));
miaotwilio 0:b32fa0c757d7 58 if(!strcmp(data,data_new)) {
miaotwilio 0:b32fa0c757d7 59 logError("Error code [%d] is [%s]\r\n", err, data);
miaotwilio 0:b32fa0c757d7 60 } else {
miaotwilio 0:b32fa0c757d7 61 logError("Failed to get error code [%d], Reason: [%s]\r\n", err, data_new);
miaotwilio 0:b32fa0c757d7 62 }
miaotwilio 0:b32fa0c757d7 63 goto fail;
miaotwilio 0:b32fa0c757d7 64 }
miaotwilio 0:b32fa0c757d7 65 }
miaotwilio 0:b32fa0c757d7 66
miaotwilio 0:b32fa0c757d7 67 return mqttClient->connect(options);
miaotwilio 0:b32fa0c757d7 68
miaotwilio 0:b32fa0c757d7 69 fail:
miaotwilio 0:b32fa0c757d7 70 cleanupTransport() ;
miaotwilio 0:b32fa0c757d7 71 return MQTT::FAILURE;
miaotwilio 0:b32fa0c757d7 72 }
miaotwilio 0:b32fa0c757d7 73
miaotwilio 0:b32fa0c757d7 74 int TlsMQTTClient::publish(const char* topicName, MQTT::Message& message) {
miaotwilio 0:b32fa0c757d7 75 return mqttClient->publish(topicName, message);
miaotwilio 0:b32fa0c757d7 76 }
miaotwilio 0:b32fa0c757d7 77
miaotwilio 0:b32fa0c757d7 78 int TlsMQTTClient::publish(const char* topicName, void* payload, size_t payloadlen, enum MQTT::QoS qos, bool retained) {
miaotwilio 0:b32fa0c757d7 79 return mqttClient->publish(topicName, payload, payloadlen, qos, retained);
miaotwilio 0:b32fa0c757d7 80 }
miaotwilio 0:b32fa0c757d7 81
miaotwilio 0:b32fa0c757d7 82 int TlsMQTTClient::publish(const char* topicName, void* payload, size_t payloadlen, unsigned short& id, enum MQTT::QoS qos, bool retained) {
miaotwilio 0:b32fa0c757d7 83 return mqttClient->publish(topicName, payload, payloadlen, id, qos, retained);
miaotwilio 0:b32fa0c757d7 84 }
miaotwilio 0:b32fa0c757d7 85
miaotwilio 0:b32fa0c757d7 86 int TlsMQTTClient::subscribe(const char* topicFilter, enum MQTT::QoS qos, MessageHandler mh) {
miaotwilio 0:b32fa0c757d7 87 return mqttClient->subscribe(topicFilter, qos, mh);
miaotwilio 0:b32fa0c757d7 88 }
miaotwilio 0:b32fa0c757d7 89
miaotwilio 0:b32fa0c757d7 90 int TlsMQTTClient::unsubscribe(const char* topicFilter) {
miaotwilio 0:b32fa0c757d7 91 return mqttClient->unsubscribe(topicFilter);
miaotwilio 0:b32fa0c757d7 92 }
miaotwilio 0:b32fa0c757d7 93
miaotwilio 0:b32fa0c757d7 94 int TlsMQTTClient::disconnect() {
miaotwilio 0:b32fa0c757d7 95 int r = mqttClient->disconnect();
miaotwilio 0:b32fa0c757d7 96 cleanupTransport();
miaotwilio 0:b32fa0c757d7 97 return r;
miaotwilio 0:b32fa0c757d7 98 }
miaotwilio 0:b32fa0c757d7 99
miaotwilio 0:b32fa0c757d7 100 int TlsMQTTClient::yield(unsigned long timeout_ms) {
miaotwilio 0:b32fa0c757d7 101 return mqttClient->yield(timeout_ms);
miaotwilio 0:b32fa0c757d7 102 }
miaotwilio 0:b32fa0c757d7 103
miaotwilio 0:b32fa0c757d7 104 bool TlsMQTTClient::isConnected() {
miaotwilio 0:b32fa0c757d7 105 return mqttClient->isConnected();
miaotwilio 0:b32fa0c757d7 106 }
miaotwilio 0:b32fa0c757d7 107
miaotwilio 0:b32fa0c757d7 108 void TlsMQTTClient::cleanupTransport() {
miaotwilio 0:b32fa0c757d7 109 if (ssl) {
miaotwilio 0:b32fa0c757d7 110 logTrace("freeing ssl");
miaotwilio 0:b32fa0c757d7 111 CyaSSL_free(ssl) ;
miaotwilio 0:b32fa0c757d7 112 ssl = NULL ;
miaotwilio 0:b32fa0c757d7 113 }
miaotwilio 0:b32fa0c757d7 114 if (ctx) {
miaotwilio 0:b32fa0c757d7 115 logTrace("freeing ssl ctx");
miaotwilio 0:b32fa0c757d7 116 CyaSSL_CTX_free(ctx) ;
miaotwilio 0:b32fa0c757d7 117 ctx = NULL ;
miaotwilio 0:b32fa0c757d7 118 }
miaotwilio 0:b32fa0c757d7 119 if (tcp) {
miaotwilio 0:b32fa0c757d7 120 if (tcp->is_connected()) {
miaotwilio 0:b32fa0c757d7 121 logTrace("disconnect tcp");
miaotwilio 0:b32fa0c757d7 122 tcp->close();
miaotwilio 0:b32fa0c757d7 123 }
miaotwilio 0:b32fa0c757d7 124 logTrace("freeing tcp");
miaotwilio 0:b32fa0c757d7 125 delete tcp;
miaotwilio 0:b32fa0c757d7 126 tcp = NULL;
miaotwilio 0:b32fa0c757d7 127 }
miaotwilio 0:b32fa0c757d7 128 }
miaotwilio 0:b32fa0c757d7 129
miaotwilio 0:b32fa0c757d7 130 TlsMQTTClient::~TlsMQTTClient() {
miaotwilio 0:b32fa0c757d7 131 cleanupTransport();
miaotwilio 0:b32fa0c757d7 132 delete mqttClient;
miaotwilio 0:b32fa0c757d7 133 }
miaotwilio 0:b32fa0c757d7 134
miaotwilio 0:b32fa0c757d7 135 int TlsMQTTClient::read(unsigned char* data, int max, int timeout) {
miaotwilio 0:b32fa0c757d7 136 return CyaSSL_read(ssl, data, max);
miaotwilio 0:b32fa0c757d7 137 }
miaotwilio 0:b32fa0c757d7 138
miaotwilio 0:b32fa0c757d7 139 int TlsMQTTClient::write(const unsigned char* data, int length, int timeout) {
miaotwilio 0:b32fa0c757d7 140 return CyaSSL_write(ssl, data, length);
miaotwilio 0:b32fa0c757d7 141 }
miaotwilio 0:b32fa0c757d7 142
miaotwilio 0:b32fa0c757d7 143 int TlsMQTTClient::ioRecv(CYASSL* ssl, char *buf, int sz, void *ctx) {
miaotwilio 0:b32fa0c757d7 144 TlsMQTTClient* thiz = (TlsMQTTClient*) ctx;
miaotwilio 0:b32fa0c757d7 145 return thiz->tcp->receive(buf, sz);
miaotwilio 0:b32fa0c757d7 146 }
miaotwilio 0:b32fa0c757d7 147
miaotwilio 0:b32fa0c757d7 148 int TlsMQTTClient::ioSend(CYASSL* ssl, char *buf, int sz, void *ctx) {
miaotwilio 0:b32fa0c757d7 149 TlsMQTTClient* thiz = (TlsMQTTClient*) ctx;
miaotwilio 0:b32fa0c757d7 150 return thiz->tcp->send(buf, sz);
miaotwilio 0:b32fa0c757d7 151 }