Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
mqtt.cpp
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2018 ARM Limited 00003 * SPDX-License-Identifier: Apache-2.0 00004 */ 00005 00006 #include "mbed.h" 00007 #include "MQTTNetwork.h" 00008 #include "MQTTClient.h" 00009 #include "MQTTmbed.h" 00010 #include "mqtt.h" 00011 #include <assert.h> 00012 #include "AccCar.h" 00013 00014 // topics interested in 00015 #define POSITION_TOPIC "MQTT_Position0x25" 00016 #define CONTROL_TOPIC "MQTT_Control0x25" 00017 00018 #define DEBUG_MQTT 00019 00020 Serial mqtt_pc (USBTX, USBRX); 00021 00022 00023 // empty constructor 00024 mqtt::mqtt() 00025 { 00026 00027 } 00028 00029 /* 00030 This function sets up the wifi module and connects it to the SSID 00031 configured in the configuration file. It also prints out the MAC address 00032 of the module, which is needed if you are trying to use campus wifi. 00033 This function returns NULL if there are any issues. 00034 */ 00035 WiFiInterface* mqtt::setup_wifi() { 00036 // Get a handle to the WiFi module 00037 WiFiInterface* wifi = WiFiInterface::get_default_instance(); 00038 00039 // Connect the module to the wifi, based on the SSID and password 00040 // specified in the mbed_app.json configuration file 00041 // If you are using AirPennNet-Device, this will not succeed until the MAC 00042 // address (printed shortly after this) is registered 00043 mqtt_pc.printf("Connecting to wifi\r\n"); 00044 int rc = wifi->connect(MBED_CONF_APP_WIFI_SSID, MBED_CONF_APP_WIFI_PASSWORD, NSAPI_SECURITY_WPA_WPA2); 00045 00046 // Print out the MAC address of the wifi module. The MAC address is 00047 // needed to register the device with AirPennNet-Device, so that you 00048 // can use the campus wifi 00049 mqtt_pc.printf("MAC Address: "); 00050 mqtt_pc.printf(wifi->get_mac_address()); 00051 mqtt_pc.printf("\r\n"); 00052 00053 if (rc != 0) { 00054 mqtt_pc.printf("Problem connecting to wifi\r\n"); 00055 return NULL; 00056 } else { 00057 mqtt_pc.printf("Wifi connected\r\n"); 00058 } 00059 00060 return wifi; 00061 } 00062 00063 /* 00064 This function creates the MQTT client and connects it to the MQTT broker 00065 that we have setup for the course. If there are any errors with the 00066 connection, it will return NULL 00067 */ 00068 MQTT::Client<MQTTNetwork, Countdown>* mqtt::setup_mqtt(MQTTNetwork& network) { 00069 // the hostname and port point to a Google Cloud MQTT server we setup for 00070 // this project 00071 const char* hostname = "34.68.206.11"; 00072 int port = 1883; 00073 00074 // Create the underlying network connection to the MQTT server 00075 mqtt_pc.printf("Connecting to %s:%d\r\n", hostname, port); 00076 int rc = network.connect(hostname, port); 00077 if (rc != 0) { 00078 mqtt_pc.printf("There was an error with the TCP connect: %d\r\n", rc); 00079 return NULL; 00080 } 00081 00082 mqtt_pc.printf("Connected to %s:%d\r\n", hostname, port); 00083 00084 // Connect the MQTT client to the server 00085 MQTT::Client<MQTTNetwork, Countdown>* temp_client = new MQTT::Client<MQTTNetwork, Countdown>(network); 00086 rc = temp_client->connect(); 00087 if (rc != 0) { 00088 mqtt_pc.printf("There was an error with the MQTT connect: %d\r\n", rc); 00089 return NULL; 00090 } 00091 00092 mqtt_pc.printf("MQTT connect successful!\r\n"); 00093 00094 return temp_client; 00095 } 00096 00097 /* 00098 This function is the callback for when a message is received from the 00099 MQTT broker. You register different callback functions with different 00100 topic subscriptions 00101 */ 00102 void mqtt::control_message_arrived(MQTT::MessageData& md) 00103 { 00104 MQTT::Message &message = md.message; 00105 // make message 00106 control_msg_t* msg = new control_msg_t; 00107 assert(msg != NULL && message.payloadlen == sizeof(control_msg_t)); 00108 00109 // copy to our new pointer for some reason just taking the payload ptr is bad for mbed? 00110 memcpy(msg,message.payload,message.payloadlen); 00111 00112 #ifdef DEBUG_MQTT 00113 //mqtt_pc.printf("Message arrived: qos %d, retained %d, dup %d, packetid %d\r\n", message.qos, message.retained, message.dup, message.id); 00114 mqtt_pc.printf("speed %d id %d \r\n", msg->speed, msg->car_id); 00115 #endif 00116 00117 // add our message to the queue no fucking clue what happens internally to 00118 // the message memory 00119 mqtt::instance()->add_to_control_queue(msg->car_id,msg); 00120 00121 // free message 00122 delete msg; 00123 } 00124 00125 /* 00126 This function sends a message to the test topic. 00127 */ 00128 int mqtt::send_position_msg( position_msg_t* msg ) 00129 { 00130 assert(msg != NULL && client != NULL); 00131 00132 MQTT::Message message; 00133 00134 // might be safest to memcopy thius seems to work 00135 //memcpy(message.payload,msg,sizeof(position_msg_t)); 00136 message.payload = (void*)msg; 00137 message.payloadlen = sizeof(position_msg_t); 00138 message.qos = MQTT::QOS1; 00139 00140 #ifdef DEBUG_MQTT 00141 mqtt_pc.printf("Sending a message!\r\n"); 00142 #endif 00143 00144 int rc = client->publish(POSITION_TOPIC,message); 00145 assert(rc == 0); 00146 00147 client->yield(1000); 00148 return 0; 00149 } 00150 00151 void mqtt::bringup_network() { 00152 00153 // 00154 WiFiInterface* wifi = setup_wifi(); 00155 assert(wifi != NULL); 00156 00157 // Create the network object needed by the MQTT client 00158 new_network = new MQTTNetwork(wifi); 00159 00160 // get client 00161 client = setup_mqtt(*new_network); 00162 assert(client != NULL); 00163 00164 // Subscribe to a topic / register a callback 00165 mqtt_pc.printf("Subscribing to topic %s\r\n", CONTROL_TOPIC); 00166 int rc = client->subscribe(CONTROL_TOPIC, MQTT::QOS1, control_message_arrived); 00167 assert(rc == 0); 00168 00169 // make a road based of mqtt id 00170 mqtt_id = 0; 00171 if(strcmp(wifi->get_mac_address(),"2c:3a:e8:0b:75:06") == 0){ 00172 mqtt_id = 0; 00173 } 00174 else{ 00175 mqtt_id = 1; 00176 } 00177 00178 mqtt_pc.printf("Subscribed, Setup complete!\r\n"); 00179 } 00180 00181 00182 // manage callbacks from mqtt 00183 void mqtt::manage_network() 00184 { 00185 while(true) 00186 { 00187 // 00188 osEvent evt = position_queue.get(); 00189 assert(evt.status == osEventMessage); 00190 00191 // 00192 position_msg_t *message = (position_msg_t*)evt.value.p; 00193 send_position_msg(message); 00194 00195 // client->yield(100); 00196 } 00197 } 00198 00199 // 00200 // clean up goes here 00201 void mqtt::shutdown_network() 00202 { 00203 // 00204 mqtt_pc.printf("shutting down mbed\r\n"); 00205 00206 // 00207 client->disconnect(); 00208 delete new_network; 00209 00210 // 00211 thread->terminate(); 00212 delete thread; 00213 } 00214 00215 // launch network manager thread 00216 // responsible for pub sub 00217 void mqtt::setup_network() 00218 { 00219 // bring up network if anything bad happens we will assert and crash 00220 bringup_network(); 00221 00222 // create a new thread thats sole purpose in life is to call client yield 00223 // what a sad life for a thread 00224 // calling yield is necessary as we will not get any messages for the mqtt 00225 // serverwithout it 00226 thread = new Thread(); 00227 assert(thread != NULL); 00228 thread->start( callback(this,&mqtt::manage_network) ); 00229 00230 }
Generated on Wed Jul 13 2022 16:04:36 by
1.7.2