Dependencies:   MQTT

main.cpp

Committer:
carptj
Date:
2019-11-27
Revision:
0:f945f1ae269b
Child:
1:7a2d97a8800e

File content as of revision 0:f945f1ae269b:

/* mbed Microcontroller Library
 * Copyright (c) 2018 ARM Limited
 * SPDX-License-Identifier: Apache-2.0
 */

#include "mbed.h"
#include "MQTTNetwork.h"
#include "MQTTClient.h"
#include "MQTTmbed.h"

 
Serial pc (USBTX, USBRX);

/*
    This function sets up the wifi module and connects it to the SSID 
    configured in the configuration file. It also prints out the MAC address 
    of the module, which is needed if you are trying to use campus wifi.
    This function returns NULL if there are any issues.
*/
WiFiInterface* setup_wifi() {
    // Get a handle to the WiFi module
    WiFiInterface* wifi = WiFiInterface::get_default_instance();
    
    // Connect the module to the wifi, based on the SSID and password 
    // specified in the mbed_app.json configuration file
    // If you are using AirPennNet-Device, this will not succeed until the MAC
    // address (printed shortly after this) is registered
    pc.printf("Connecting to wifi\r\n");
    int rc = wifi->connect(MBED_CONF_APP_WIFI_SSID, MBED_CONF_APP_WIFI_PASSWORD, NSAPI_SECURITY_WPA_WPA2);
    
    // Print out the MAC address of the wifi module. The MAC address is 
    // needed to register the device with AirPennNet-Device, so that you
    // can use the campus wifi
    pc.printf("MAC Address: ");
    pc.printf(wifi->get_mac_address());
    pc.printf("\r\n");
    
    if (rc != 0) {
        pc.printf("Problem connecting to wifi\r\n");   
        return NULL;
    } else {
        pc.printf("Wifi connected\r\n");  
    }
      
    return wifi;
}

/*
    This function creates the MQTT client and connects it to the MQTT broker
    that we have setup for the course. If there are any errors with the 
    connection, it will return NULL
*/
MQTT::Client<MQTTNetwork, Countdown>* setup_mqtt(MQTTNetwork &network) {
    // the hostname and port point to a Google Cloud MQTT server we setup for
    // this project
    const char* hostname = "34.68.206.11";
    int port = 1883;
    
    // Create the underlying network connection to the MQTT server
    pc.printf("Connecting to %s:%d\r\n", hostname, port);
    int rc = network.connect(hostname, port);
    if (rc != 0) {
        pc.printf("There was an error with the TCP connect: %d\r\n", rc);
        return NULL;
    }
    
    pc.printf("Connected to %s:%d\r\n", hostname, port);
        
    // Connect the MQTT client to the server
    MQTT::Client<MQTTNetwork, Countdown>* client = new MQTT::Client<MQTTNetwork, Countdown>(network);
    rc = client->connect();
    if (rc != 0) {
        pc.printf("There was an error with the MQTT connect: %d\r\n", rc);
        return NULL;
    }
    
    pc.printf("MQTT connect successful!\r\n");
    
    return client;
}

/*
    This function is the callback for when a message is received from the 
    MQTT broker. You register different callback functions with different
    topic subscriptions
*/
void message_arrived(MQTT::MessageData& md)
{
    MQTT::Message &message = md.message;
    pc.printf("Message arrived: qos %d, retained %d, dup %d, packetid %d\r\n", message.qos, message.retained, message.dup, message.id);
    pc.printf("Payload %.*s\r\n", message.payloadlen, (char*)message.payload);
}

/*
    This function sends a message to the test topic. It returns a value of 
    -1 if there is an issue
*/
int send_message(MQTT::Client<MQTTNetwork, Countdown>* client) {
    pc.printf("Sending a message!\r\n");
    MQTT::Message message;
 
    char buf[100];
    sprintf(buf, "Hello World!  This is a test message!\r\n");
    message.qos = MQTT::QOS1;
    message.retained = false;
    message.dup = false;
    message.payload = (void*)buf;
    message.payloadlen = strlen(buf)+1;
    int rc = client->publish("MQTT_test", message);
    
    if (rc != 0) {
        return -1;   
    } else {
        pc.printf("Message sent!\r\n");
        return 0;
    }
}

int main() {
    WiFiInterface* wifi = setup_wifi();
    
    // There was a problem connecting the wifi, so exit
    if (wifi == NULL) {
        return -1;   
    }
    
    // Create the network object needed by the MQTT client
    MQTTNetwork network(wifi);
    
    MQTT::Client<MQTTNetwork, Countdown>* client = setup_mqtt(network);
    
    // There was a problem connecting the MQTT client, so exit
    if (client == NULL) {
        return -1;   
    }
    
    // Subscribe to a topic / register a callback
    char* topic = "MQTT_test";
    pc.printf("Subscribing to topic %s\r\n", topic);
    int rc = client->subscribe(topic, MQTT::QOS1, message_arrived);
    if (rc != 0) {
        pc.printf("There was a problem subscribing: %d\r\n", rc);
        
        client->disconnect();
        return -1;
    } else {
        pc.printf("Subscribed!\r\n");
    }
    
    rc = send_message(client);
    if (rc != 0) {
        pc.printf("There was a problem sending the message: %d\r\n", rc);
        
        client->disconnect();
        return -1;
    }
    
    // Wait a second to make sure there is time for the message to be sent and received
    // before disconnecting the client. "yield" is needed to poll outstanding messages 
    // and call the appropriate callbacks
    client->yield(1000);
    
    pc.printf("Congratulations. WiFi and MQTT has been correctly setup (assuming you saw your message)\r\n");
    client->disconnect();
    
    return 1;
    
}