Matthew Goldsmith / Mbed OS cis441projMS2b

Dependencies:   TextLCD MQTT

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Communication.cpp Source File

Communication.cpp

00001 #include "Communication.h"
00002 
00003 MQTT::Client<MQTTNetwork, Countdown>* Communication::client(MQTT::Client<MQTTNetwork, Countdown>* new_client) {
00004     static MQTT::Client<MQTTNetwork, Countdown>* client = NULL;
00005     if (new_client != NULL) {
00006         client = new_client;
00007     }
00008     return client;
00009 }
00010 
00011 const char* Communication::mac_address(const char* new_add) {
00012     static const char* mac_address = NULL;
00013     if (new_add != NULL) {
00014         mac_address = new_add;
00015     }
00016     //printf("mac_address %s\n", mac_address); 
00017     return mac_address;
00018 }
00019 
00020 Communication::Communication() {}
00021 
00022 /*
00023     This function sets up the wifi module and connects it to the SSID 
00024     configured in the configuration file. It also prints out the MAC address 
00025     of the module, which is needed if you are trying to use campus wifi.
00026     This function returns NULL if there are any issues.
00027 */
00028 WiFiInterface* Communication::setup_wifi() {
00029     // Get a handle to the WiFi module
00030     WiFiInterface* wifi = WiFiInterface::get_default_instance();
00031     
00032     // Connect the module to the wifi, based on the SSID and password 
00033     // specified in the mbed_app.json configuration file
00034     // If you are using AirPennNet-Device, this will not succeed until the MAC
00035     // address (printed shortly after this) is registered
00036     printf("Connecting to wifi\r\n");
00037     int rc = wifi->connect(MBED_CONF_APP_WIFI_SSID, MBED_CONF_APP_WIFI_PASSWORD, NSAPI_SECURITY_WPA_WPA2);
00038     
00039     if (rc != 0) {
00040         printf("Problem connecting to wifi\r\n");  
00041         return NULL;
00042     }
00043     printf("Wifi connected\r\n");  
00044     return wifi;
00045 }
00046 
00047 /*
00048     This function creates the MQTT client and connects it to the MQTT broker
00049     that we have setup for the course. If there are any errors with the 
00050     connection, it will return NULL
00051 */
00052 MQTT::Client<MQTTNetwork, Countdown>* Communication::setup_mqtt(MQTTNetwork &network) {
00053     // the hostname and port point to a Google Cloud MQTT server we setup for
00054     // this project
00055     const char* hostname = "34.68.206.11";
00056     int port = 1883;
00057     
00058     // Create the underlying network connection to the MQTT server
00059     printf("Connecting to %s:%d\r\n", hostname, port); 
00060     int rc = network.connect(hostname, port);
00061     if (rc != 0) {
00062         printf("There was an error with the TCP connect: %d\r\n", rc);
00063         return NULL;
00064     }
00065             
00066     printf("Connected to %s:%d\r\n", hostname, port);
00067 
00068     // Connect the MQTT client to the server
00069     MQTT::Client<MQTTNetwork, Countdown>* client = new MQTT::Client<MQTTNetwork, Countdown>(network);
00070     rc = client->connect();
00071     if (rc != 0) {
00072         printf("There was an error with the MQTT connect: %d\r\n", rc);
00073         return NULL;
00074     }
00075     
00076     printf("MQTT connect successful!\r\n");
00077         
00078     return client;
00079 }
00080 
00081 //callback for update/control messages
00082 void Communication::update_message_arrived(MQTT::MessageData& md)
00083 {
00084     printf("UPDATE MESSAGE ARRIVED\r\n"); 
00085     MQTT::Message &message = md.message;
00086     char* payload = (char*)message.payload;
00087     printf("%s\r\n", payload);
00088     int id = payload[0] - 48;
00089     int speed = payload[3] - 48;
00090     if(payload[4] != 'x') {
00091         speed = speed * 10 + payload[4] - 48;
00092     }
00093     Road::road_in_use(NULL)->update_car_speed(id, speed);
00094 }
00095 
00096 //callback for sync messages
00097 void Communication::sync_message_arrived(MQTT::MessageData& md)
00098 {
00099     MQTT::Message &message = md.message;
00100     char* payload = (char*)message.payload;
00101     //printf("%s\r\n", payload);
00102     if (strcmp (Communication::mac_address(NULL), payload) != 0) {
00103         //printf("not matching address\r\n");
00104         Road::ready(1);
00105     }
00106 }
00107 
00108 //initialize the client
00109 int Communication::init() {
00110     WiFiInterface* wifi = setup_wifi();
00111     
00112     // There was a problem connecting the wifi, so exit
00113     if (wifi == NULL) {
00114         return -1;   
00115     }
00116     
00117     Communication::mac_address(wifi->get_mac_address());
00118     
00119     // Create the network object needed by the MQTT client
00120     MQTTNetwork* network = (MQTTNetwork*)malloc(sizeof(MQTTNetwork)); 
00121     new (network) MQTTNetwork(wifi); 
00122     //MQTTNetwork network(wifi);
00123     Communication::client(setup_mqtt(*network));
00124     
00125     // There was a problem connecting the MQTT client, so exit
00126     if (Communication::client(NULL) == NULL) {
00127         return -1;   
00128     }
00129     char* update_topic; 
00130     if (strcmp(Communication::mac_address(NULL), "2c:3a:e8:0b:7b:21") == 0) {
00131         update_topic = "Chen_Goldsmith_Update/2c:3a:e8:0b:7b:21"; 
00132     } else {
00133         update_topic =  "Chen_Goldsmith_Update/dc:4f:22:51:24:20"; 
00134     } 
00135     printf("%s\r\n", update_topic); 
00136     int rc = Communication::client(NULL)->subscribe(update_topic, MQTT::QOS1, update_message_arrived);
00137     if (rc != 0) {
00138         printf("Failed subscribe updates\r\n"); 
00139         return -1;
00140     }
00141     char* sync_topic = "Chen_Goldsmith_Sync";
00142     rc = Communication::client(NULL)->subscribe(sync_topic, MQTT::QOS1, sync_message_arrived);
00143     if (rc != 0) {
00144         printf("Failed subscribe sync\r\n"); 
00145         return -1;
00146     }
00147     
00148     printf("Successfully subscribed, init() returning 1\n"); 
00149     return 1;
00150 }
00151 
00152 int Communication::publish_car_info(int id, int pos, int speed) {
00153     MQTT::Message message;
00154  
00155     char* topic = "Chen_Goldsmith_Car_Info";
00156     char buf[50];
00157     const char* mac = Communication::mac_address(NULL); 
00158     sprintf(buf, "%d, %d, %d, %s", id, pos, speed, mac);
00159     int rc = Communication::client(NULL)->publish(topic, (char*) buf, strlen(buf), MQTT::QOS1);
00160     
00161     if (rc != 0) {
00162         return -1;   
00163     } else {
00164         return 0;
00165     }
00166 }
00167 
00168 int Communication::publish_road_ready() {
00169     MQTT::Message message;
00170  
00171     char* topic = "Chen_Goldsmith_Sync";
00172     char buf[100];
00173     sprintf(buf, "%s", Communication::mac_address(NULL));
00174     int rc = Communication::client(NULL)->publish(topic, (char*) buf, strlen(buf)+1, MQTT::QOS1);
00175     if (rc != 0) {
00176         return -1;   
00177     } else {
00178         printf("successful publish: ready\r\n");
00179         return 0;
00180     }
00181 }
00182 
00183 void Communication::yield(int time) {
00184     Communication::client(NULL)->yield(time); 
00185 }
00186 
00187 void Communication::disconnect() {
00188     Communication::client(NULL)->disconnect();
00189 }