Dependencies:   MQTT

Committer:
carptj
Date:
Wed Nov 27 17:14:24 2019 +0000
Revision:
1:7a2d97a8800e
Parent:
0:f945f1ae269b
Child:
2:f10d6fecb345
Simplify publishing call.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
carptj 0:f945f1ae269b 1 /* mbed Microcontroller Library
carptj 0:f945f1ae269b 2 * Copyright (c) 2018 ARM Limited
carptj 0:f945f1ae269b 3 * SPDX-License-Identifier: Apache-2.0
carptj 0:f945f1ae269b 4 */
carptj 0:f945f1ae269b 5
carptj 0:f945f1ae269b 6 #include "mbed.h"
carptj 0:f945f1ae269b 7 #include "MQTTNetwork.h"
carptj 0:f945f1ae269b 8 #include "MQTTClient.h"
carptj 0:f945f1ae269b 9 #include "MQTTmbed.h"
carptj 0:f945f1ae269b 10
carptj 0:f945f1ae269b 11
carptj 0:f945f1ae269b 12 Serial pc (USBTX, USBRX);
carptj 0:f945f1ae269b 13
carptj 0:f945f1ae269b 14 /*
carptj 0:f945f1ae269b 15 This function sets up the wifi module and connects it to the SSID
carptj 0:f945f1ae269b 16 configured in the configuration file. It also prints out the MAC address
carptj 0:f945f1ae269b 17 of the module, which is needed if you are trying to use campus wifi.
carptj 0:f945f1ae269b 18 This function returns NULL if there are any issues.
carptj 0:f945f1ae269b 19 */
carptj 0:f945f1ae269b 20 WiFiInterface* setup_wifi() {
carptj 0:f945f1ae269b 21 // Get a handle to the WiFi module
carptj 0:f945f1ae269b 22 WiFiInterface* wifi = WiFiInterface::get_default_instance();
carptj 0:f945f1ae269b 23
carptj 0:f945f1ae269b 24 // Connect the module to the wifi, based on the SSID and password
carptj 0:f945f1ae269b 25 // specified in the mbed_app.json configuration file
carptj 0:f945f1ae269b 26 // If you are using AirPennNet-Device, this will not succeed until the MAC
carptj 0:f945f1ae269b 27 // address (printed shortly after this) is registered
carptj 0:f945f1ae269b 28 pc.printf("Connecting to wifi\r\n");
carptj 0:f945f1ae269b 29 int rc = wifi->connect(MBED_CONF_APP_WIFI_SSID, MBED_CONF_APP_WIFI_PASSWORD, NSAPI_SECURITY_WPA_WPA2);
carptj 0:f945f1ae269b 30
carptj 0:f945f1ae269b 31 // Print out the MAC address of the wifi module. The MAC address is
carptj 0:f945f1ae269b 32 // needed to register the device with AirPennNet-Device, so that you
carptj 0:f945f1ae269b 33 // can use the campus wifi
carptj 0:f945f1ae269b 34 pc.printf("MAC Address: ");
carptj 0:f945f1ae269b 35 pc.printf(wifi->get_mac_address());
carptj 0:f945f1ae269b 36 pc.printf("\r\n");
carptj 0:f945f1ae269b 37
carptj 0:f945f1ae269b 38 if (rc != 0) {
carptj 0:f945f1ae269b 39 pc.printf("Problem connecting to wifi\r\n");
carptj 0:f945f1ae269b 40 return NULL;
carptj 0:f945f1ae269b 41 } else {
carptj 0:f945f1ae269b 42 pc.printf("Wifi connected\r\n");
carptj 0:f945f1ae269b 43 }
carptj 0:f945f1ae269b 44
carptj 0:f945f1ae269b 45 return wifi;
carptj 0:f945f1ae269b 46 }
carptj 0:f945f1ae269b 47
carptj 0:f945f1ae269b 48 /*
carptj 0:f945f1ae269b 49 This function creates the MQTT client and connects it to the MQTT broker
carptj 0:f945f1ae269b 50 that we have setup for the course. If there are any errors with the
carptj 0:f945f1ae269b 51 connection, it will return NULL
carptj 0:f945f1ae269b 52 */
carptj 0:f945f1ae269b 53 MQTT::Client<MQTTNetwork, Countdown>* setup_mqtt(MQTTNetwork &network) {
carptj 0:f945f1ae269b 54 // the hostname and port point to a Google Cloud MQTT server we setup for
carptj 0:f945f1ae269b 55 // this project
carptj 0:f945f1ae269b 56 const char* hostname = "34.68.206.11";
carptj 0:f945f1ae269b 57 int port = 1883;
carptj 0:f945f1ae269b 58
carptj 0:f945f1ae269b 59 // Create the underlying network connection to the MQTT server
carptj 0:f945f1ae269b 60 pc.printf("Connecting to %s:%d\r\n", hostname, port);
carptj 0:f945f1ae269b 61 int rc = network.connect(hostname, port);
carptj 0:f945f1ae269b 62 if (rc != 0) {
carptj 0:f945f1ae269b 63 pc.printf("There was an error with the TCP connect: %d\r\n", rc);
carptj 0:f945f1ae269b 64 return NULL;
carptj 0:f945f1ae269b 65 }
carptj 0:f945f1ae269b 66
carptj 0:f945f1ae269b 67 pc.printf("Connected to %s:%d\r\n", hostname, port);
carptj 0:f945f1ae269b 68
carptj 0:f945f1ae269b 69 // Connect the MQTT client to the server
carptj 0:f945f1ae269b 70 MQTT::Client<MQTTNetwork, Countdown>* client = new MQTT::Client<MQTTNetwork, Countdown>(network);
carptj 0:f945f1ae269b 71 rc = client->connect();
carptj 0:f945f1ae269b 72 if (rc != 0) {
carptj 0:f945f1ae269b 73 pc.printf("There was an error with the MQTT connect: %d\r\n", rc);
carptj 0:f945f1ae269b 74 return NULL;
carptj 0:f945f1ae269b 75 }
carptj 0:f945f1ae269b 76
carptj 0:f945f1ae269b 77 pc.printf("MQTT connect successful!\r\n");
carptj 0:f945f1ae269b 78
carptj 0:f945f1ae269b 79 return client;
carptj 0:f945f1ae269b 80 }
carptj 0:f945f1ae269b 81
carptj 0:f945f1ae269b 82 /*
carptj 0:f945f1ae269b 83 This function is the callback for when a message is received from the
carptj 0:f945f1ae269b 84 MQTT broker. You register different callback functions with different
carptj 0:f945f1ae269b 85 topic subscriptions
carptj 0:f945f1ae269b 86 */
carptj 0:f945f1ae269b 87 void message_arrived(MQTT::MessageData& md)
carptj 0:f945f1ae269b 88 {
carptj 0:f945f1ae269b 89 MQTT::Message &message = md.message;
carptj 0:f945f1ae269b 90 pc.printf("Message arrived: qos %d, retained %d, dup %d, packetid %d\r\n", message.qos, message.retained, message.dup, message.id);
carptj 0:f945f1ae269b 91 pc.printf("Payload %.*s\r\n", message.payloadlen, (char*)message.payload);
carptj 0:f945f1ae269b 92 }
carptj 0:f945f1ae269b 93
carptj 0:f945f1ae269b 94 /*
carptj 0:f945f1ae269b 95 This function sends a message to the test topic. It returns a value of
carptj 0:f945f1ae269b 96 -1 if there is an issue
carptj 0:f945f1ae269b 97 */
carptj 1:7a2d97a8800e 98 int send_message(MQTT::Client<MQTTNetwork, Countdown>* client, char* topic) {
carptj 0:f945f1ae269b 99 pc.printf("Sending a message!\r\n");
carptj 0:f945f1ae269b 100 MQTT::Message message;
carptj 0:f945f1ae269b 101
carptj 0:f945f1ae269b 102 char buf[100];
carptj 0:f945f1ae269b 103 sprintf(buf, "Hello World! This is a test message!\r\n");
carptj 1:7a2d97a8800e 104 int rc = client->publish(topic, (char*) buf, strlen(buf)+1, MQTT::QOS1);
carptj 0:f945f1ae269b 105
carptj 0:f945f1ae269b 106 if (rc != 0) {
carptj 0:f945f1ae269b 107 return -1;
carptj 0:f945f1ae269b 108 } else {
carptj 0:f945f1ae269b 109 pc.printf("Message sent!\r\n");
carptj 0:f945f1ae269b 110 return 0;
carptj 0:f945f1ae269b 111 }
carptj 0:f945f1ae269b 112 }
carptj 0:f945f1ae269b 113
carptj 0:f945f1ae269b 114 int main() {
carptj 0:f945f1ae269b 115 WiFiInterface* wifi = setup_wifi();
carptj 0:f945f1ae269b 116
carptj 0:f945f1ae269b 117 // There was a problem connecting the wifi, so exit
carptj 0:f945f1ae269b 118 if (wifi == NULL) {
carptj 0:f945f1ae269b 119 return -1;
carptj 0:f945f1ae269b 120 }
carptj 0:f945f1ae269b 121
carptj 0:f945f1ae269b 122 // Create the network object needed by the MQTT client
carptj 0:f945f1ae269b 123 MQTTNetwork network(wifi);
carptj 0:f945f1ae269b 124
carptj 0:f945f1ae269b 125 MQTT::Client<MQTTNetwork, Countdown>* client = setup_mqtt(network);
carptj 0:f945f1ae269b 126
carptj 0:f945f1ae269b 127 // There was a problem connecting the MQTT client, so exit
carptj 0:f945f1ae269b 128 if (client == NULL) {
carptj 0:f945f1ae269b 129 return -1;
carptj 0:f945f1ae269b 130 }
carptj 0:f945f1ae269b 131
carptj 0:f945f1ae269b 132 // Subscribe to a topic / register a callback
carptj 0:f945f1ae269b 133 char* topic = "MQTT_test";
carptj 0:f945f1ae269b 134 pc.printf("Subscribing to topic %s\r\n", topic);
carptj 0:f945f1ae269b 135 int rc = client->subscribe(topic, MQTT::QOS1, message_arrived);
carptj 0:f945f1ae269b 136 if (rc != 0) {
carptj 0:f945f1ae269b 137 pc.printf("There was a problem subscribing: %d\r\n", rc);
carptj 0:f945f1ae269b 138
carptj 0:f945f1ae269b 139 client->disconnect();
carptj 0:f945f1ae269b 140 return -1;
carptj 0:f945f1ae269b 141 } else {
carptj 0:f945f1ae269b 142 pc.printf("Subscribed!\r\n");
carptj 0:f945f1ae269b 143 }
carptj 0:f945f1ae269b 144
carptj 1:7a2d97a8800e 145 rc = send_message(client, topic);
carptj 0:f945f1ae269b 146 if (rc != 0) {
carptj 0:f945f1ae269b 147 pc.printf("There was a problem sending the message: %d\r\n", rc);
carptj 0:f945f1ae269b 148
carptj 0:f945f1ae269b 149 client->disconnect();
carptj 0:f945f1ae269b 150 return -1;
carptj 0:f945f1ae269b 151 }
carptj 0:f945f1ae269b 152
carptj 0:f945f1ae269b 153 // Wait a second to make sure there is time for the message to be sent and received
carptj 0:f945f1ae269b 154 // before disconnecting the client. "yield" is needed to poll outstanding messages
carptj 0:f945f1ae269b 155 // and call the appropriate callbacks
carptj 0:f945f1ae269b 156 client->yield(1000);
carptj 0:f945f1ae269b 157
carptj 0:f945f1ae269b 158 pc.printf("Congratulations. WiFi and MQTT has been correctly setup (assuming you saw your message)\r\n");
carptj 0:f945f1ae269b 159 client->disconnect();
carptj 0:f945f1ae269b 160
carptj 0:f945f1ae269b 161 return 1;
carptj 0:f945f1ae269b 162
carptj 0:f945f1ae269b 163 }