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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include <mbed.h>
00002 #include <mtsas.h>
00003 #include <ssl.h>
00004 #include <MbedJSONValue.h>
00005 #include <string>
00006 #include "MTSCellularManager.hpp"
00007 #include "TlsMQTTClient.hpp"
00008 #include "certificates.hpp"
00009 
00010 /* 
00011  *  Sync Settings
00012  *  
00013  *  Enter a Sync Key & Password, your document unique name, 
00014  *  and the device name
00015  */
00016 char* sync_key                          = "KYXXXXXXXXXXXXXXXXXXXX";
00017 char* sync_password                     = "SECRET_HERE";
00018 char* sync_document                     = "sync/docs/BoardLED";
00019 char* sync_device_name                  = "MultiConnect Dragonfly";
00020 
00021 /* Sync server and MQTT setup; you probably don't have to change these. */
00022 const char* mqtt_server                 = "mqtt-sync.us1.twilio.com";
00023 const uint16_t mqtt_port                = 8883;
00024 const uint16_t maxMQTTpackageSize       = 512;
00025 
00026 TlsMQTTClient client = TlsMQTTClient();
00027 DigitalOut led(D7);
00028 DigitalOut bc_nce(PB_2);
00029 const uint8_t MQTT_HEARTBEAT = 15;
00030 
00031 /* 
00032  * Our Twilio Connected Devices message handling callback.  This is passed as a 
00033  * callback function when we subscribe to the document, and any messages will 
00034  * appear here.
00035  */
00036 void callback(MQTT::MessageData& data) 
00037 {
00038     if (data.message.payloadlen > maxMQTTpackageSize) {
00039         return;
00040     }
00041     char buf[maxMQTTpackageSize + 1];
00042     strncpy(buf, (char*)data.message.payload, data.message.payloadlen);
00043     buf[data.message.payloadlen] = '\0';
00044     
00045     logDebug("Received new update %s", buf);
00046     /* JSON Parse 'led' */
00047     MbedJSONValue parser;
00048     parse(parser, buf);
00049     
00050     /* The parser will segfault and reset the board if "led" isn't contained. */
00051     if (parser.hasMember("led")) {
00052         std::string led_str;
00053         led_str = parser["led"].get<std::string>();
00054         
00055         if (led_str.compare("ON") == 0) {
00056             logDebug("Turning LED ON");
00057             led = 0; // Active LOW
00058         } else {
00059             logDebug("Turning LED OFF");
00060             led = 1; // Active LOW
00061         }
00062     }
00063 }
00064 
00065 
00066 /* 
00067  * This function connects to Sync via MQTT. We connect using the key, password, 
00068  * and device name defined as constants above, and checks the server
00069  * certificate.
00070  * 
00071  * If everything works, we subscribe to the document topic and return.
00072  */
00073 void connect_mqtt()
00074 {
00075     MQTTPacket_connectData conn_data = MQTTPacket_connectData_initializer;
00076     conn_data.clientID.cstring = sync_device_name;
00077     conn_data.username.cstring = sync_key;
00078     conn_data.password.cstring = sync_password;
00079     int rc = client.connect(
00080         mqtt_server, 
00081         mqtt_port, 
00082         MQTT_GATEWAY_PROD_ROOT_CA_PEM, 
00083         conn_data
00084     );
00085     logInfo("MQTT connect result: %d", rc);
00086     
00087     rc = client.subscribe(
00088         "sync/docs/BoardLED", 
00089         MQTT::QOS1, 
00090         callback
00091     );
00092     logInfo("MQTT subscription result: %d", rc);
00093 }
00094 
00095 
00096 /* 
00097  * Very basic device loop - all we do is reconnect when disconnected
00098  */
00099 void loop()
00100 {
00101     if (client.isConnected()) {
00102         client.yield(MQTT_HEARTBEAT/2.0);
00103         wait(MQTT_HEARTBEAT);
00104     } else {
00105         wait(MQTT_HEARTBEAT*10);
00106         connect_mqtt();
00107     }
00108     
00109     // Here's an example of publishing from the MultiConnect Dragonfly.
00110     // Uncomment until the end of the function to send a 'msg' back to Sync
00111     // every 5 cycles through the loop! (5*MQTT_HEARTBEAT seconds)
00112     /*
00113     static uint32_t ticks = 0;
00114     MQTT::Message message;
00115     char buf[maxMQTTpackageSize] = "{\"msg\":\"Ahoy!\",\"led\":\"ON\"}";
00116     message.qos = MQTT::QOS1;
00117     message.payload = (void*)buf;
00118     message.payloadlen = strlen(buf) + 1;
00119     if (ticks++ > 4) {
00120             logInfo("Sending ON message to Twilio!");
00121             client.publish(
00122                     sync_document, 
00123                     message
00124             );
00125             ticks = 0;
00126     }
00127     */
00128 }
00129 
00130 
00131 /* 
00132  * In main, we configure our LEDs, connect to Twilio Programmable Wireless,
00133  * and initialize CyaSSL. We then connect our MQTT client for the first time.
00134  *
00135  * When done, we pass control to the MQTT loop, which handles yield()s.
00136  */
00137 int main() 
00138 {
00139     led = 1;  // Active LOW
00140     bc_nce = 1;
00141     Serial debug(USBTX, USBRX);
00142     debug.baud(115200);
00143     mts::MTSLog::setLogLevel(mts::MTSLog::TRACE_LEVEL);
00144 
00145     // Be sure your SIM is registered in the Twilio console.
00146     // https://www.twilio.com/console/wireless/sims/
00147     logInfo("Initializing Twilio Programmable Wireless");
00148     MTSCellularManager cellularManager("wireless.twilio.com");   
00149     if (! cellularManager.init()) {
00150         while (true) {
00151             logError("failed to initialize cellular radio"); wait(10);  
00152         }
00153     }
00154     CyaSSL_Init();
00155     connect_mqtt();
00156 
00157     /* We're done; pass off control to the loop */
00158     while (1) {
00159        loop();
00160     }
00161 }