Vergil Cola
/
MQTTGateway2
Fork of my original MQTTGateway
Embed:
(wiki syntax)
Show/hide line numbers
main.cpp
00001 /* mbed main.cpp to test a secure MQTT connection using MBED TLS library 00002 * Copyright (c) 2017 Vergil Perez Cola 00003 * 00004 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00005 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00006 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00007 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00008 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00009 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00010 * THE SOFTWARE. 00011 */ 00012 00013 /* * 00014 * @note This program is derived from the MQTT sample program. 00015 */ 00016 /** 00017 * @note To make this work with FRDM-K64F 00018 * @note PTA0 must be disconnected from the swd clk by cutting J11. 00019 * @note But to re-active SWD you need to put jumper header to J11 00020 * @note so that it can be re-connected by a jumper. 00021 */ 00022 00023 #include "mbed.h" 00024 #include "rtos.h" 00025 #include "XbeeMonitor.h" 00026 #include "easy-connect.h" 00027 #include "NTPClient.h" 00028 #include "SDBlockDevice.h" 00029 #include "FATFileSystem.h" 00030 #include "DownloadFile.h" 00031 #include "MQTTSManager.h" 00032 #include "WeatherInfo.h" 00033 #include "RadioCfg.h" 00034 #include "config.h" 00035 00036 #include <string> 00037 #include <sstream> 00038 00039 #if defined(ENABLE_LOGGING) 00040 #include "DigiLoggerMbedSerial.h" 00041 using namespace DigiLog; 00042 #endif 00043 00044 #if defined(TARGET_NUCLEO_L476RG) 00045 //SDBlockDevice sd(D11, D12, D13, D9); 00046 #else 00047 SDBlockDevice sd(PTE3, PTE1, PTE2, PTE4); 00048 #endif 00049 00050 #if !defined(TARGET_NUCLEO_L476RG) 00051 FATFileSystem fs("sd"); 00052 #endif 00053 00054 Serial pc(USBTX, USBRX, 115200); 00055 00056 Thread xbeeThd; 00057 00058 #if !defined(TARGET_NUCLEO_L476RG) 00059 static const char * radioconfigfile = "/sd/radioconfig.json"; 00060 #endif 00061 00062 /* List of trusted root CA certificates 00063 * currently only "letsencrypt", the CA for mbedhacks.com 00064 * 00065 * To add more than one root, just concatenate them. 00066 * 00067 * TODO: Move this certificate file onto the SD card. 00068 */ 00069 static const char SSL_CA_PEM[] = "-----BEGIN CERTIFICATE-----\n" 00070 "MIIFETCCA/mgAwIBAgISA2ktlb1Y6ap4GCH7dg3wS37XMA0GCSqGSIb3DQEBCwUA\n" 00071 "MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD\n" 00072 "ExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMzAeFw0xNzAzMDkwMTQ4MDBaFw0x\n" 00073 "NzA2MDcwMTQ4MDBaMBgxFjAUBgNVBAMTDW1iZWRoYWNrcy5jb20wggEiMA0GCSqG\n" 00074 "SIb3DQEBAQUAA4IBDwAwggEKAoIBAQC4ppYHlH8lfB7lkWOjMSnOJGaLtCBfz57I\n" 00075 "VVOd1Rngsz7nE5fg3joa7lkazRY1ZqtuC2UloS+4LYoQZX4Z887dhdug/TPA4J1A\n" 00076 "GppA4xVCb2kUFODMjZ2r4pMLp+MjFFMBaHrL4cgx/n4aJUB+N9Z+HW0p2Yr5TsOQ\n" 00077 "ghIOPkNxFr2q6klm49+BMUbO98hAwFwsIISLf6IbHM93gx1ltqkvb55N87ZM1hYH\n" 00078 "fkq+J+YqjleiLaqRN2MVlNMNfy9MDbqM5uCyGiWGtq8eiQLaWpZkxnA2MC5zPsO/\n" 00079 "fzEWiVjn2uazlXZ5xZwiK22KMxVasqWMitvETtmPOl9mocRbLQdxAgMBAAGjggIh\n" 00080 "MIICHTAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUF\n" 00081 "BwMCMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFCsgG+z1BTjrN3K+/tF0C4k818Yv\n" 00082 "MB8GA1UdIwQYMBaAFKhKamMEfd265tE5t6ZFZe/zqOyhMHAGCCsGAQUFBwEBBGQw\n" 00083 "YjAvBggrBgEFBQcwAYYjaHR0cDovL29jc3AuaW50LXgzLmxldHNlbmNyeXB0Lm9y\n" 00084 "Zy8wLwYIKwYBBQUHMAKGI2h0dHA6Ly9jZXJ0LmludC14My5sZXRzZW5jcnlwdC5v\n" 00085 "cmcvMCsGA1UdEQQkMCKCDW1iZWRoYWNrcy5jb22CEXd3dy5tYmVkaGFja3MuY29t\n" 00086 "MIH+BgNVHSAEgfYwgfMwCAYGZ4EMAQIBMIHmBgsrBgEEAYLfEwEBATCB1jAmBggr\n" 00087 "BgEFBQcCARYaaHR0cDovL2Nwcy5sZXRzZW5jcnlwdC5vcmcwgasGCCsGAQUFBwIC\n" 00088 "MIGeDIGbVGhpcyBDZXJ0aWZpY2F0ZSBtYXkgb25seSBiZSByZWxpZWQgdXBvbiBi\n" 00089 "eSBSZWx5aW5nIFBhcnRpZXMgYW5kIG9ubHkgaW4gYWNjb3JkYW5jZSB3aXRoIHRo\n" 00090 "ZSBDZXJ0aWZpY2F0ZSBQb2xpY3kgZm91bmQgYXQgaHR0cHM6Ly9sZXRzZW5jcnlw\n" 00091 "dC5vcmcvcmVwb3NpdG9yeS8wDQYJKoZIhvcNAQELBQADggEBABFH6YcvHh8foHeg\n" 00092 "NM7iR9HnYRqa5gSERcCtq6jm8PcTsAbsdQ/BNpIHK7AZSg2kk17kj+JFeyMuNJWq\n" 00093 "lmabV0dtzdC8ejp1d7hGb/HjuQ400th/QRayvyrDVzQPfCNyJ0C82Q2DFjeUgnqv\n" 00094 "oJMcV6i4ICW0boI7GUf7oeHCmrUEHKffAbeFvx3c85c39IHJEFa59UWj1linU/Tr\n" 00095 "g9i5AaSKB95d706u1XRA7WLV/Hu7yunhxEjlj33bfdifBb/ZLBd0LtrXPwtXi6E8\n" 00096 "r6obp+B+Ce89G7WEhdT9BX0ck1KTK+yP7uAC7tvvsiejxXOoCtVyBAumBJS7mRuv\n" 00097 "I5hmKgE=\n" 00098 "-----END CERTIFICATE-----\n" 00099 "-----BEGIN CERTIFICATE-----\n" 00100 "MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/\n" 00101 "MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT\n" 00102 "DkRTVCBSb290IENBIFgzMB4XDTE2MDMxNzE2NDA0NloXDTIxMDMxNzE2NDA0Nlow\n" 00103 "SjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxIzAhBgNVBAMT\n" 00104 "GkxldCdzIEVuY3J5cHQgQXV0aG9yaXR5IFgzMIIBIjANBgkqhkiG9w0BAQEFAAOC\n" 00105 "AQ8AMIIBCgKCAQEAnNMM8FrlLke3cl03g7NoYzDq1zUmGSXhvb418XCSL7e4S0EF\n" 00106 "q6meNQhY7LEqxGiHC6PjdeTm86dicbp5gWAf15Gan/PQeGdxyGkOlZHP/uaZ6WA8\n" 00107 "SMx+yk13EiSdRxta67nsHjcAHJyse6cF6s5K671B5TaYucv9bTyWaN8jKkKQDIZ0\n" 00108 "Z8h/pZq4UmEUEz9l6YKHy9v6Dlb2honzhT+Xhq+w3Brvaw2VFn3EK6BlspkENnWA\n" 00109 "a6xK8xuQSXgvopZPKiAlKQTGdMDQMc2PMTiVFrqoM7hD8bEfwzB/onkxEz0tNvjj\n" 00110 "/PIzark5McWvxI0NHWQWM6r6hCm21AvA2H3DkwIDAQABo4IBfTCCAXkwEgYDVR0T\n" 00111 "AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwfwYIKwYBBQUHAQEEczBxMDIG\n" 00112 "CCsGAQUFBzABhiZodHRwOi8vaXNyZy50cnVzdGlkLm9jc3AuaWRlbnRydXN0LmNv\n" 00113 "bTA7BggrBgEFBQcwAoYvaHR0cDovL2FwcHMuaWRlbnRydXN0LmNvbS9yb290cy9k\n" 00114 "c3Ryb290Y2F4My5wN2MwHwYDVR0jBBgwFoAUxKexpHsscfrb4UuQdf/EFWCFiRAw\n" 00115 "VAYDVR0gBE0wSzAIBgZngQwBAgEwPwYLKwYBBAGC3xMBAQEwMDAuBggrBgEFBQcC\n" 00116 "ARYiaHR0cDovL2Nwcy5yb290LXgxLmxldHNlbmNyeXB0Lm9yZzA8BgNVHR8ENTAz\n" 00117 "MDGgL6AthitodHRwOi8vY3JsLmlkZW50cnVzdC5jb20vRFNUUk9PVENBWDNDUkwu\n" 00118 "Y3JsMB0GA1UdDgQWBBSoSmpjBH3duubRObemRWXv86jsoTANBgkqhkiG9w0BAQsF\n" 00119 "AAOCAQEA3TPXEfNjWDjdGBX7CVW+dla5cEilaUcne8IkCJLxWh9KEik3JHRRHGJo\n" 00120 "uM2VcGfl96S8TihRzZvoroed6ti6WqEBmtzw3Wodatg+VyOeph4EYpr/1wXKtx8/\n" 00121 "wApIvJSwtmVi4MFU5aMqrSDE6ea73Mj2tcMyo5jMd6jmeWUHK8so/joWUoHOUgwu\n" 00122 "X4Po1QYz+3dszkDqMp4fklxBwXRsW10KXzPMTZ+sOPAveyxindmjkW8lGy+QsRlG\n" 00123 "PfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8saCbGS5jN2p8M+X+Q7UNKEkROb3N6\n" 00124 "KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg==\n" 00125 "-----END CERTIFICATE-----"; 00126 00127 const char * openweathermap_id = "1bfddd34faa0e0216769d688b0b0c743"; 00128 float lastTemperature; 00129 00130 #define BASIC_AUTH_USER "tinong" 00131 #define BASIC_AUTH_PASSWORD "tatay" 00132 00133 template <class T> 00134 std::string to_string (const T& t) 00135 { 00136 std::stringstream ss; 00137 ss << t; 00138 return ss.str(); 00139 } 00140 00141 00142 void UpdateWeatherInfo(NetworkInterface* network) 00143 { 00144 printf("Downloading weather information ...\r\n"); 00145 DownloadFile * wInfo = new DownloadFile(network); 00146 if (wInfo) 00147 { 00148 std::string url = "http://api.openweathermap.org/data/2.5/weather?q=Singapore,sg&appid="; 00149 url += openweathermap_id; 00150 printf("Getting weather from [%s]\r\n", url.c_str()); 00151 HttpResponse* result = wInfo->get_file(url.c_str()); 00152 if (result != NULL) 00153 { 00154 00155 std::string content = result->get_body_as_string(); 00156 00157 printf("\r\n========= Weather Info =============\r\n"); 00158 printf("%s\r\n", content.c_str()); 00159 printf("==============================\r\n"); 00160 00161 const char * weather = content.c_str(); 00162 WeatherInfo info; 00163 if ( parseweatherinfo(weather, info) == 0) 00164 { 00165 printf("Weather : %s\r\n", info.weather.c_str()); 00166 printf("Weather Icon : %s\r\n", info.icon.c_str()); 00167 printf("Current Temperature : %.2f\r\n", info.temperature - 273.15); 00168 printf("Current Pressure : %.2f\r\n", info.pressure); 00169 printf("Current Humidity : %.2f\r\n", info.humidity); 00170 00171 // TODO: process the information and send updates 00172 // to GUI 00173 lastTemperature = info.temperature - 273.15; 00174 } 00175 } 00176 00177 delete wInfo; 00178 } 00179 } 00180 00181 int main() 00182 { 00183 uint64_t radioID; 00184 int lasthour = 0; 00185 RadioCfg cfg; 00186 00187 #if !defined(TARGET_NUCLEO_L476RG) 00188 // Mount the SD card first! 00189 printf("Mounting the filesystem on \"/sd\". "); 00190 fs.mount(&sd); 00191 #endif 00192 00193 #if defined(ENABLE_LOGGING) 00194 new DigiLoggerMbedSerial(&pc, LogLevelInfo); 00195 #endif 00196 pc.printf("Initializing XbeeMonitor ...\r\n"); 00197 initXbeeMonitor(); 00198 // TODO: get XBee radio id 00199 // and request configuration settings 00200 // from the web. 00201 radioID = getXbeeId(); 00202 cfg.radioID = radioID; 00203 pc.printf("Radio ID : %llu\r\n", radioID); 00204 00205 pc.printf("Connecting to ethernet ...\r\n"); 00206 // Get the network interface via 00207 // easy connect 00208 NetworkInterface* network = easy_connect(true); 00209 if (!network) { 00210 return 1; 00211 } 00212 00213 pc.printf("IP Address : %s\r\n", network->get_ip_address()); 00214 pc.printf("MAC Address : %s\r\n", network->get_mac_address()); 00215 00216 time_t ctTime; 00217 ctTime = time(NULL); 00218 00219 printf("Getting coordinator info from the internet!...\r\n"); 00220 #if !defined(TARGET_NUCLEO_L476RG) 00221 DownloadFile * df = new DownloadFile(network, radioconfigfile, SSL_CA_PEM ); 00222 #else 00223 DownloadFile * df = new DownloadFile(network, NULL, SSL_CA_PEM ); 00224 #endif 00225 if (df) 00226 { 00227 std::string url = "https://www.mbedhacks.com/Garden/getconfig.php?id="; 00228 url += to_string(radioID); 00229 printf("Getting config from [%s]\r\n", url.c_str()); 00230 df->basic_auth(BASIC_AUTH_USER, BASIC_AUTH_PASSWORD); 00231 HttpResponse* result = df->get_file(url.c_str()); 00232 if (result != NULL) 00233 { 00234 #if defined(TARGET_NUCLEO_L476RG) 00235 std::string content = result->get_body_as_string();; 00236 #else 00237 std::string content = df->get_file_content(); 00238 #endif 00239 printf("\r\n==========================\r\n"); 00240 printf("%s\r\n", content.c_str()); 00241 printf("==============================\r\n"); 00242 00243 // TODO: pass the downloaded file to the RadioCfg 00244 if (parseradioconfig(content.c_str(), cfg) == 0) 00245 { 00246 cfg.debug(); 00247 } 00248 } 00249 delete df; 00250 } 00251 00252 NTPClient ntp(network, cfg.utc_offset); 00253 pc.printf("Initial System Time is: %s\r\n", ctime(&ctTime)); 00254 pc.printf("Trying to update time...\r\n"); 00255 if (ntp.setTime("0.pool.ntp.org") == 0) { 00256 00257 pc.printf("Set time successfully\r\n"); 00258 pc.printf("Updated time is : %s\r\n", ctime(&ctTime)); 00259 00260 pc.printf("Starting the Xbee manager thread ...\r\n"); 00261 xbeeThd.start(runXbeeMonitor); 00262 pc.printf("Starting MQTTS subscriber thread ...\r\n"); 00263 // Initialize MQTT 00264 mqttsInit(network, SSL_CA_PEM); 00265 if ( runMQTTS() != 0 ) 00266 pc.printf("Failed launching MQTT thread ...\r\n"); 00267 00268 while(true) { 00269 time_t currentTime; 00270 struct tm *localTime; 00271 00272 time( ¤tTime ); // Get the current time 00273 localTime = localtime( ¤tTime ); // Convert the current time to local time 00274 00275 // TODO: Update the weather information every hour ... 00276 if (lasthour != localTime->tm_hour ) 00277 //if (lasthour != localTime->tm_min ) 00278 { 00279 printf("An hour has passed!!! ...\r\n"); 00280 UpdateWeatherInfo(network); 00281 // Update ... 00282 //lasthour = localTime->tm_min; 00283 lasthour = localTime->tm_hour; 00284 } 00285 00286 Thread::wait(10000); 00287 } 00288 } 00289 else 00290 { 00291 pc.printf("Failed to setup time from NTP ...\r\n"); 00292 while(true) 00293 { 00294 Thread::wait(100); 00295 } 00296 } 00297 }
Generated on Tue Jul 12 2022 18:06:46 by 1.7.2