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.
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