CIS441 Proj MS 2b

Dependencies:   TextLCD MQTT

Committer:
kchen7
Date:
Fri Dec 13 19:37:24 2019 +0000
Revision:
13:2c12f60bd10a
Parent:
12:ade22f4681af
Child:
15:1d611d264a1f
pushing an update;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mwgold 4:ef8866873df5 1 #include "Communication.h"
mwgold 4:ef8866873df5 2
mwgold 4:ef8866873df5 3 MQTT::Client<MQTTNetwork, Countdown>* Communication::client(MQTT::Client<MQTTNetwork, Countdown>* new_client) {
kchen7 7:15c2ed6e5162 4 static MQTT::Client<MQTTNetwork, Countdown>* client = NULL;
mwgold 4:ef8866873df5 5 if (new_client != NULL) {
mwgold 4:ef8866873df5 6 client = new_client;
mwgold 4:ef8866873df5 7 }
mwgold 4:ef8866873df5 8 return client;
mwgold 4:ef8866873df5 9 }
mwgold 4:ef8866873df5 10
mwgold 4:ef8866873df5 11 const char* Communication::mac_address(const char* new_add) {
mwgold 4:ef8866873df5 12 static const char* mac_address = NULL;
mwgold 4:ef8866873df5 13 if (new_add != NULL) {
mwgold 4:ef8866873df5 14 mac_address = new_add;
mwgold 4:ef8866873df5 15 }
kchen7 7:15c2ed6e5162 16 //printf("mac_address %s\n", mac_address);
mwgold 4:ef8866873df5 17 return mac_address;
mwgold 4:ef8866873df5 18 }
mwgold 4:ef8866873df5 19
mwgold 4:ef8866873df5 20 Communication::Communication() {}
mwgold 4:ef8866873df5 21
mwgold 4:ef8866873df5 22 /*
mwgold 4:ef8866873df5 23 This function sets up the wifi module and connects it to the SSID
mwgold 4:ef8866873df5 24 configured in the configuration file. It also prints out the MAC address
mwgold 4:ef8866873df5 25 of the module, which is needed if you are trying to use campus wifi.
mwgold 4:ef8866873df5 26 This function returns NULL if there are any issues.
mwgold 4:ef8866873df5 27 */
mwgold 4:ef8866873df5 28 WiFiInterface* Communication::setup_wifi() {
mwgold 4:ef8866873df5 29 // Get a handle to the WiFi module
mwgold 4:ef8866873df5 30 WiFiInterface* wifi = WiFiInterface::get_default_instance();
mwgold 4:ef8866873df5 31
mwgold 4:ef8866873df5 32 // Connect the module to the wifi, based on the SSID and password
mwgold 4:ef8866873df5 33 // specified in the mbed_app.json configuration file
mwgold 4:ef8866873df5 34 // If you are using AirPennNet-Device, this will not succeed until the MAC
mwgold 4:ef8866873df5 35 // address (printed shortly after this) is registered
kchen7 7:15c2ed6e5162 36 printf("Connecting to wifi\r\n");
mwgold 4:ef8866873df5 37 int rc = wifi->connect(MBED_CONF_APP_WIFI_SSID, MBED_CONF_APP_WIFI_PASSWORD, NSAPI_SECURITY_WPA_WPA2);
mwgold 4:ef8866873df5 38
mwgold 4:ef8866873df5 39 if (rc != 0) {
kchen7 7:15c2ed6e5162 40 printf("Problem connecting to wifi\r\n");
mwgold 4:ef8866873df5 41 return NULL;
mwgold 4:ef8866873df5 42 }
kchen7 7:15c2ed6e5162 43 printf("Wifi connected\r\n");
mwgold 4:ef8866873df5 44 return wifi;
mwgold 4:ef8866873df5 45 }
mwgold 4:ef8866873df5 46
mwgold 4:ef8866873df5 47 /*
mwgold 4:ef8866873df5 48 This function creates the MQTT client and connects it to the MQTT broker
mwgold 4:ef8866873df5 49 that we have setup for the course. If there are any errors with the
mwgold 4:ef8866873df5 50 connection, it will return NULL
mwgold 4:ef8866873df5 51 */
mwgold 4:ef8866873df5 52 MQTT::Client<MQTTNetwork, Countdown>* Communication::setup_mqtt(MQTTNetwork &network) {
mwgold 4:ef8866873df5 53 // the hostname and port point to a Google Cloud MQTT server we setup for
mwgold 4:ef8866873df5 54 // this project
mwgold 4:ef8866873df5 55 const char* hostname = "34.68.206.11";
mwgold 4:ef8866873df5 56 int port = 1883;
mwgold 4:ef8866873df5 57
mwgold 4:ef8866873df5 58 // Create the underlying network connection to the MQTT server
kchen7 7:15c2ed6e5162 59 printf("Connecting to %s:%d\r\n", hostname, port);
mwgold 4:ef8866873df5 60 int rc = network.connect(hostname, port);
mwgold 4:ef8866873df5 61 if (rc != 0) {
kchen7 7:15c2ed6e5162 62 printf("There was an error with the TCP connect: %d\r\n", rc);
mwgold 4:ef8866873df5 63 return NULL;
mwgold 4:ef8866873df5 64 }
mwgold 4:ef8866873df5 65
kchen7 7:15c2ed6e5162 66 printf("Connected to %s:%d\r\n", hostname, port);
kchen7 7:15c2ed6e5162 67
mwgold 4:ef8866873df5 68 // Connect the MQTT client to the server
mwgold 4:ef8866873df5 69 MQTT::Client<MQTTNetwork, Countdown>* client = new MQTT::Client<MQTTNetwork, Countdown>(network);
mwgold 4:ef8866873df5 70 rc = client->connect();
mwgold 4:ef8866873df5 71 if (rc != 0) {
kchen7 7:15c2ed6e5162 72 printf("There was an error with the MQTT connect: %d\r\n", rc);
mwgold 4:ef8866873df5 73 return NULL;
mwgold 4:ef8866873df5 74 }
kchen7 7:15c2ed6e5162 75
kchen7 7:15c2ed6e5162 76 printf("MQTT connect successful!\r\n");
mwgold 4:ef8866873df5 77
mwgold 4:ef8866873df5 78 return client;
mwgold 4:ef8866873df5 79 }
mwgold 4:ef8866873df5 80
mwgold 4:ef8866873df5 81 //callback for update/control messages
mwgold 4:ef8866873df5 82 void Communication::update_message_arrived(MQTT::MessageData& md)
mwgold 4:ef8866873df5 83 {
kchen7 12:ade22f4681af 84 printf("UPDATE MESSAGE ARRIVED");
mwgold 4:ef8866873df5 85 MQTT::Message &message = md.message;
mwgold 4:ef8866873df5 86 char* payload = (char*)message.payload;
mwgold 9:f5981ced0b47 87 printf("%s\r\n", payload);
mwgold 4:ef8866873df5 88 int id = payload[0] - 48;
mwgold 4:ef8866873df5 89 int speed = payload[3] - 48;
mwgold 4:ef8866873df5 90 if(message.payloadlen > 3) {
mwgold 4:ef8866873df5 91 speed = speed * 10 + payload[4] - 48;
mwgold 4:ef8866873df5 92 }
mwgold 4:ef8866873df5 93
mwgold 4:ef8866873df5 94 Road::road_in_use(NULL)->update_car_speed(id, speed);
mwgold 4:ef8866873df5 95 }
mwgold 4:ef8866873df5 96
mwgold 4:ef8866873df5 97 //callback for sync messages
mwgold 4:ef8866873df5 98 void Communication::sync_message_arrived(MQTT::MessageData& md)
mwgold 4:ef8866873df5 99 {
mwgold 4:ef8866873df5 100 MQTT::Message &message = md.message;
mwgold 4:ef8866873df5 101 char* payload = (char*)message.payload;
kchen7 12:ade22f4681af 102 //printf("%s\r\n", payload);
mwgold 4:ef8866873df5 103 if (strcmp (Communication::mac_address(NULL), payload) != 0) {
kchen7 12:ade22f4681af 104 //printf("not matching address\r\n");
kchen7 12:ade22f4681af 105 Road::ready(1);
mwgold 4:ef8866873df5 106 }
mwgold 4:ef8866873df5 107 }
mwgold 4:ef8866873df5 108
mwgold 4:ef8866873df5 109 //initialize the client
mwgold 4:ef8866873df5 110 int Communication::init() {
mwgold 4:ef8866873df5 111 WiFiInterface* wifi = setup_wifi();
mwgold 4:ef8866873df5 112
mwgold 4:ef8866873df5 113 // There was a problem connecting the wifi, so exit
mwgold 4:ef8866873df5 114 if (wifi == NULL) {
mwgold 4:ef8866873df5 115 return -1;
mwgold 4:ef8866873df5 116 }
mwgold 4:ef8866873df5 117
mwgold 4:ef8866873df5 118 Communication::mac_address(wifi->get_mac_address());
mwgold 4:ef8866873df5 119
mwgold 4:ef8866873df5 120 // Create the network object needed by the MQTT client
kchen7 7:15c2ed6e5162 121 MQTTNetwork* network = (MQTTNetwork*)malloc(sizeof(MQTTNetwork));
kchen7 7:15c2ed6e5162 122 new (network) MQTTNetwork(wifi);
kchen7 7:15c2ed6e5162 123 //MQTTNetwork network(wifi);
kchen7 7:15c2ed6e5162 124 Communication::client(setup_mqtt(*network));
mwgold 4:ef8866873df5 125
mwgold 4:ef8866873df5 126 // There was a problem connecting the MQTT client, so exit
mwgold 4:ef8866873df5 127 if (Communication::client(NULL) == NULL) {
mwgold 4:ef8866873df5 128 return -1;
mwgold 4:ef8866873df5 129 }
mwgold 4:ef8866873df5 130
mwgold 4:ef8866873df5 131 // Subscribe to topics / register callbacks
mwgold 4:ef8866873df5 132 char buf[100];
mwgold 4:ef8866873df5 133 sprintf(buf, "Chen_Goldsmith_Update/%s", Communication::mac_address(NULL));
mwgold 4:ef8866873df5 134 char* update_topic = (char*) buf;
mwgold 4:ef8866873df5 135 int rc = Communication::client(NULL)->subscribe(update_topic, MQTT::QOS1, update_message_arrived);
mwgold 4:ef8866873df5 136 if (rc != 0) {
kchen7 12:ade22f4681af 137 printf("Failed subscribe updates\r\n");
mwgold 4:ef8866873df5 138 return -1;
mwgold 4:ef8866873df5 139 }
mwgold 4:ef8866873df5 140 char* sync_topic = "Chen_Goldsmith_Sync";
mwgold 4:ef8866873df5 141 rc = Communication::client(NULL)->subscribe(sync_topic, MQTT::QOS1, sync_message_arrived);
mwgold 4:ef8866873df5 142 if (rc != 0) {
kchen7 12:ade22f4681af 143 printf("Failed subscribe sync\r\n");
mwgold 4:ef8866873df5 144 return -1;
mwgold 4:ef8866873df5 145 }
mwgold 4:ef8866873df5 146
kchen7 7:15c2ed6e5162 147 printf("Successfully subscribed, init() returning 1\n");
mwgold 4:ef8866873df5 148 return 1;
mwgold 4:ef8866873df5 149 }
mwgold 4:ef8866873df5 150
mwgold 4:ef8866873df5 151 int Communication::publish_car_info(int id, int pos, int speed) {
mwgold 8:c40e805eecba 152 MQTT::Message message;
mwgold 4:ef8866873df5 153
mwgold 4:ef8866873df5 154 char* topic = "Chen_Goldsmith_Car_Info";
mwgold 8:c40e805eecba 155 char buf[50];
kchen7 7:15c2ed6e5162 156 const char* mac = Communication::mac_address(NULL);
mwgold 8:c40e805eecba 157 sprintf(buf, "%d, %d, %d, %s", id, pos, speed, mac);
mwgold 8:c40e805eecba 158 int rc = Communication::client(NULL)->publish(topic, (char*) buf, strlen(buf), MQTT::QOS1);
mwgold 4:ef8866873df5 159
mwgold 4:ef8866873df5 160 if (rc != 0) {
mwgold 4:ef8866873df5 161 return -1;
mwgold 4:ef8866873df5 162 } else {
mwgold 4:ef8866873df5 163 return 0;
mwgold 4:ef8866873df5 164 }
mwgold 4:ef8866873df5 165 }
mwgold 4:ef8866873df5 166
mwgold 4:ef8866873df5 167 int Communication::publish_road_ready() {
mwgold 4:ef8866873df5 168 MQTT::Message message;
mwgold 4:ef8866873df5 169
mwgold 4:ef8866873df5 170 char* topic = "Chen_Goldsmith_Sync";
mwgold 4:ef8866873df5 171 char buf[100];
mwgold 4:ef8866873df5 172 sprintf(buf, "%s", Communication::mac_address(NULL));
mwgold 4:ef8866873df5 173 int rc = Communication::client(NULL)->publish(topic, (char*) buf, strlen(buf)+1, MQTT::QOS1);
mwgold 4:ef8866873df5 174 if (rc != 0) {
mwgold 4:ef8866873df5 175 return -1;
mwgold 4:ef8866873df5 176 } else {
kchen7 12:ade22f4681af 177 printf("successful publish: ready\r\n");
mwgold 4:ef8866873df5 178 return 0;
mwgold 4:ef8866873df5 179 }
mwgold 4:ef8866873df5 180 }
mwgold 4:ef8866873df5 181
kchen7 13:2c12f60bd10a 182 void Communication::yield(int time) {
kchen7 13:2c12f60bd10a 183 Communication::client(NULL)->yield(time);
kchen7 11:2ab3397b6e30 184 }
kchen7 11:2ab3397b6e30 185
mwgold 4:ef8866873df5 186 void Communication::disconnect() {
mwgold 4:ef8866873df5 187 Communication::client(NULL)->disconnect();
mwgold 4:ef8866873df5 188 }