Local copy

Dependencies:   C12832_lcd ConfigFile EthernetInterface LM75B MMA7660 MQTTPacket mbed-rtos mbed

Fork of IBMIoTClientExampleForLPC1768 by Sam Danbury

src/QuickstartClient.cpp

Committer:
samdanbury
Date:
2014-06-23
Revision:
0:6276e9f72327
Child:
2:25ddff75a8c7

File content as of revision 0:6276e9f72327:

/*******************************************************************************
* Copyright (c) 2014 IBM Corporation and other Contributors.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors: Sam Danbury
* IBM - Initial Contribution
*******************************************************************************/

#include "QuickstartClient.h"

QuickstartClient::QuickstartClient(string mac) {
    connected = false;
    macAddress = mac;
    
    //Generate topic string from mac address
    memcpy(topic, "iot-1/d/", 8);
    memcpy(topic + 8, macAddress.c_str(), macAddress.size());
    memcpy(topic + 8 + macAddress.size(), "/evt/mbed-quickstart/json", 25);
    topic[8 + macAddress.size() + 25] = '\0';
    
    tryMqttConnect();
}

int QuickstartClient::reconnectDelay(int i) {
    if (i < 10) {
        return 3; //First 10 attempts try within 3 seconds
    } else if (i < 20) {
        return 60; //Next 10 attempts retry after every 1 minute
    } else {
        return 600; //After 20 attempts, retry every 10 minutes
    }
}

void QuickstartClient::tryMqttConnect() {
    int retryAttempt = 0;
    
    //Reinstantiate TCP socket connection object
    mysock = TCPSocketConnection();
    
    while (connected == false) {
        lcd.cls();
        lcd.locate(0,0);
        lcd.printf("Trying to connect...");
        
        //Based on number of connection attempts, determine timeout
        int connDelayTimeout = reconnectDelay(++retryAttempt);
        
        //Attempt to reconnect
        connect();
        
        //If connection was not established, continue retry
        if (connected == false) {
            wait(connDelayTimeout);
        } else {
            break;
        }
    }
}

void QuickstartClient::connect() {
    MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
    int  rc = 0;
    int  len = 0;
    char buf[200];
    int  buflen = sizeof(buf);
    
    //Connect to TCP socket
    mysock.connect(IBM_IOT_BROKER, IBM_IOT_PORT);
    
    //Construct clientId from mac address
    char clientId[23];
    memcpy(clientId, "quickstart:", 11);
    memcpy(clientId + 11, macAddress.c_str(), macAddress.size() + 1);
    
    //Set MQTT connect options
    data.clientID.cstring = clientId;
    data.keepAliveInterval = 20;
    data.cleansession = 1;
    data.MQTTVersion = 3;
    
    //Attempt MQTT connect
    len = MQTTSerialize_connect(buf, buflen, &data);
    rc = 0;
    while (rc < len) {
        int rc1 = mysock.send(buf, len);
        if (rc1 == -1) {
            connected = false;
            break;
        } else {
            rc += rc1;
        }
    }
    if (rc == len) {
        connected = true;
    }
}

void QuickstartClient::publish(string thePayload) {
    int  rc = 0;
    int  len = 0;
    char buf[250];
    int  buflen = sizeof(buf);
    
    MQTTString topicString = MQTTString_initializer;
    
    topicString.cstring = topic;
    
    //Convert payload from string to char array
    char* payload = new char [thePayload.length()+1];
    std::strcpy (payload, thePayload.c_str());
    int payloadlen = strlen(payload);
    
    //Attempt MQTT publish
    len = MQTTSerialize_publish(buf, buflen, 0, 0, 0, 0, topicString, payload, payloadlen);
    rc = 0;
    while (rc < len) {
        int rc1 = mysock.send(buf, len);
        if (rc1 == -1) {
            //If return code from MQTT publish is -1, attempt reconnect
            connected = false;
            tryMqttConnect();
            break;
        } else {
            rc += rc1;
        }
    }
    wait(0.2);
    
    if (payload) {
        delete payload;
    }
}