Matthew Goldsmith
/
cis441projMS2b
CIS441 Proj MS 2b
Communication.cpp@16:cb7cbf2cc23b, 2019-12-13 (annotated)
- Committer:
- kchen7
- Date:
- Fri Dec 13 22:14:27 2019 +0000
- Revision:
- 16:cb7cbf2cc23b
- Parent:
- 15:1d611d264a1f
final version;
Who changed what in which revision?
User | Revision | Line number | New 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 | 16:cb7cbf2cc23b | 84 | printf("UPDATE MESSAGE ARRIVED\r\n"); |
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; |
kchen7 | 15:1d611d264a1f | 90 | if(payload[4] != 'x') { |
mwgold | 4:ef8866873df5 | 91 | speed = speed * 10 + payload[4] - 48; |
mwgold | 4:ef8866873df5 | 92 | } |
mwgold | 4:ef8866873df5 | 93 | Road::road_in_use(NULL)->update_car_speed(id, speed); |
mwgold | 4:ef8866873df5 | 94 | } |
mwgold | 4:ef8866873df5 | 95 | |
mwgold | 4:ef8866873df5 | 96 | //callback for sync messages |
mwgold | 4:ef8866873df5 | 97 | void Communication::sync_message_arrived(MQTT::MessageData& md) |
mwgold | 4:ef8866873df5 | 98 | { |
mwgold | 4:ef8866873df5 | 99 | MQTT::Message &message = md.message; |
mwgold | 4:ef8866873df5 | 100 | char* payload = (char*)message.payload; |
kchen7 | 12:ade22f4681af | 101 | //printf("%s\r\n", payload); |
mwgold | 4:ef8866873df5 | 102 | if (strcmp (Communication::mac_address(NULL), payload) != 0) { |
kchen7 | 12:ade22f4681af | 103 | //printf("not matching address\r\n"); |
kchen7 | 12:ade22f4681af | 104 | Road::ready(1); |
mwgold | 4:ef8866873df5 | 105 | } |
mwgold | 4:ef8866873df5 | 106 | } |
mwgold | 4:ef8866873df5 | 107 | |
mwgold | 4:ef8866873df5 | 108 | //initialize the client |
mwgold | 4:ef8866873df5 | 109 | int Communication::init() { |
mwgold | 4:ef8866873df5 | 110 | WiFiInterface* wifi = setup_wifi(); |
mwgold | 4:ef8866873df5 | 111 | |
mwgold | 4:ef8866873df5 | 112 | // There was a problem connecting the wifi, so exit |
mwgold | 4:ef8866873df5 | 113 | if (wifi == NULL) { |
mwgold | 4:ef8866873df5 | 114 | return -1; |
mwgold | 4:ef8866873df5 | 115 | } |
mwgold | 4:ef8866873df5 | 116 | |
mwgold | 4:ef8866873df5 | 117 | Communication::mac_address(wifi->get_mac_address()); |
mwgold | 4:ef8866873df5 | 118 | |
mwgold | 4:ef8866873df5 | 119 | // Create the network object needed by the MQTT client |
kchen7 | 7:15c2ed6e5162 | 120 | MQTTNetwork* network = (MQTTNetwork*)malloc(sizeof(MQTTNetwork)); |
kchen7 | 7:15c2ed6e5162 | 121 | new (network) MQTTNetwork(wifi); |
kchen7 | 7:15c2ed6e5162 | 122 | //MQTTNetwork network(wifi); |
kchen7 | 7:15c2ed6e5162 | 123 | Communication::client(setup_mqtt(*network)); |
mwgold | 4:ef8866873df5 | 124 | |
mwgold | 4:ef8866873df5 | 125 | // There was a problem connecting the MQTT client, so exit |
mwgold | 4:ef8866873df5 | 126 | if (Communication::client(NULL) == NULL) { |
mwgold | 4:ef8866873df5 | 127 | return -1; |
mwgold | 4:ef8866873df5 | 128 | } |
kchen7 | 15:1d611d264a1f | 129 | char* update_topic; |
kchen7 | 15:1d611d264a1f | 130 | if (strcmp(Communication::mac_address(NULL), "2c:3a:e8:0b:7b:21") == 0) { |
kchen7 | 15:1d611d264a1f | 131 | update_topic = "Chen_Goldsmith_Update/2c:3a:e8:0b:7b:21"; |
kchen7 | 15:1d611d264a1f | 132 | } else { |
kchen7 | 15:1d611d264a1f | 133 | update_topic = "Chen_Goldsmith_Update/dc:4f:22:51:24:20"; |
kchen7 | 15:1d611d264a1f | 134 | } |
kchen7 | 15:1d611d264a1f | 135 | printf("%s\r\n", update_topic); |
mwgold | 4:ef8866873df5 | 136 | int rc = Communication::client(NULL)->subscribe(update_topic, MQTT::QOS1, update_message_arrived); |
mwgold | 4:ef8866873df5 | 137 | if (rc != 0) { |
kchen7 | 12:ade22f4681af | 138 | printf("Failed subscribe updates\r\n"); |
mwgold | 4:ef8866873df5 | 139 | return -1; |
mwgold | 4:ef8866873df5 | 140 | } |
mwgold | 4:ef8866873df5 | 141 | char* sync_topic = "Chen_Goldsmith_Sync"; |
mwgold | 4:ef8866873df5 | 142 | rc = Communication::client(NULL)->subscribe(sync_topic, MQTT::QOS1, sync_message_arrived); |
mwgold | 4:ef8866873df5 | 143 | if (rc != 0) { |
kchen7 | 12:ade22f4681af | 144 | printf("Failed subscribe sync\r\n"); |
mwgold | 4:ef8866873df5 | 145 | return -1; |
mwgold | 4:ef8866873df5 | 146 | } |
mwgold | 4:ef8866873df5 | 147 | |
kchen7 | 7:15c2ed6e5162 | 148 | printf("Successfully subscribed, init() returning 1\n"); |
mwgold | 4:ef8866873df5 | 149 | return 1; |
mwgold | 4:ef8866873df5 | 150 | } |
mwgold | 4:ef8866873df5 | 151 | |
mwgold | 4:ef8866873df5 | 152 | int Communication::publish_car_info(int id, int pos, int speed) { |
mwgold | 8:c40e805eecba | 153 | MQTT::Message message; |
mwgold | 4:ef8866873df5 | 154 | |
mwgold | 4:ef8866873df5 | 155 | char* topic = "Chen_Goldsmith_Car_Info"; |
mwgold | 8:c40e805eecba | 156 | char buf[50]; |
kchen7 | 7:15c2ed6e5162 | 157 | const char* mac = Communication::mac_address(NULL); |
mwgold | 8:c40e805eecba | 158 | sprintf(buf, "%d, %d, %d, %s", id, pos, speed, mac); |
mwgold | 8:c40e805eecba | 159 | int rc = Communication::client(NULL)->publish(topic, (char*) buf, strlen(buf), MQTT::QOS1); |
mwgold | 4:ef8866873df5 | 160 | |
mwgold | 4:ef8866873df5 | 161 | if (rc != 0) { |
mwgold | 4:ef8866873df5 | 162 | return -1; |
mwgold | 4:ef8866873df5 | 163 | } else { |
mwgold | 4:ef8866873df5 | 164 | return 0; |
mwgold | 4:ef8866873df5 | 165 | } |
mwgold | 4:ef8866873df5 | 166 | } |
mwgold | 4:ef8866873df5 | 167 | |
mwgold | 4:ef8866873df5 | 168 | int Communication::publish_road_ready() { |
mwgold | 4:ef8866873df5 | 169 | MQTT::Message message; |
mwgold | 4:ef8866873df5 | 170 | |
mwgold | 4:ef8866873df5 | 171 | char* topic = "Chen_Goldsmith_Sync"; |
mwgold | 4:ef8866873df5 | 172 | char buf[100]; |
mwgold | 4:ef8866873df5 | 173 | sprintf(buf, "%s", Communication::mac_address(NULL)); |
mwgold | 4:ef8866873df5 | 174 | int rc = Communication::client(NULL)->publish(topic, (char*) buf, strlen(buf)+1, MQTT::QOS1); |
mwgold | 4:ef8866873df5 | 175 | if (rc != 0) { |
mwgold | 4:ef8866873df5 | 176 | return -1; |
mwgold | 4:ef8866873df5 | 177 | } else { |
kchen7 | 12:ade22f4681af | 178 | printf("successful publish: ready\r\n"); |
mwgold | 4:ef8866873df5 | 179 | return 0; |
mwgold | 4:ef8866873df5 | 180 | } |
mwgold | 4:ef8866873df5 | 181 | } |
mwgold | 4:ef8866873df5 | 182 | |
kchen7 | 13:2c12f60bd10a | 183 | void Communication::yield(int time) { |
kchen7 | 13:2c12f60bd10a | 184 | Communication::client(NULL)->yield(time); |
kchen7 | 11:2ab3397b6e30 | 185 | } |
kchen7 | 11:2ab3397b6e30 | 186 | |
mwgold | 4:ef8866873df5 | 187 | void Communication::disconnect() { |
mwgold | 4:ef8866873df5 | 188 | Communication::client(NULL)->disconnect(); |
mwgold | 4:ef8866873df5 | 189 | } |