
Example program demonstrating use of HTTP or HTTPS protocol over a cellular connection with httpbin.org using the MTSAS library. (Demonstrates GET,POST,basic-auth)
Revision 6:e5ea200c66c3, committed 2015-03-16
- Comitter:
- Vanger
- Date:
- Mon Mar 16 21:35:01 2015 +0000
- Parent:
- 5:931abf45fb92
- Child:
- 7:c477f2ab9624
- Commit message:
- Added example code for HTTPS connections. (Trusted certificates are stored in certs.h)
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/certs.h Mon Mar 16 21:35:01 2015 +0000 @@ -0,0 +1,62 @@ +/** Any non-root certificates will have no effect on the SSL client, but will + * use up extra space for their allocation into the certificate list. + * Methods for obtaining the Root CA certificate(s) for a website: + * 1. Open a browser to the target website using HTTPS. + * (These instructions are for Chrome, but should be similar for other browsers) + * Click on the lock icon at the beginning of the url, select the "connection" tab, + * and click the "certificate information" hyperlink. The browser will open a new window + * labeled "Certificate". Switch to the "Certification Path" tab, click the certificate + * closest to the top of the window, then click "View Certificate". This will open a new + * window labeled "Certificate" again. This time, click on the "Details" tab, then click + * "Copy to File". This will open a "Certificate Export Wizard". Click next, and choose the + * "Base-64 encoded X.509 (.CER)" option, then click next. Choose the name and location where + * you want to save the PEM formatted certificate, then click next, then finish. Open the file + * that was created and copy-paste the certificate into this certs.h file. Format the certificate + * data so that each line begins with " and is appended with \r\n" + * + * 2. Go to https://www.bluessl.com/en/ssltest and enter the website for which you wish to get the root CA + * certificates. Click the [Click here to download the public part of this certificate] button located + * underneath the certificates that label themselves as Root, or Root CA. The root CA certificate should + * self-signed, otherwise it is not the root CA certificate. Take the downloaded file, copy the data + * into this certs.h file, and format the data so that each line begins with " and is appended with \r\n" + * + * 3. Using openssl on linux: (Make sure you have openssl installed.) Run the command: openssl s_client + * -showcerts -connect <host>:<port> </dev/null + * Where <host> is the host name (www.google.com for example), and port is the port on which the connection + * will be made (usually 443). When the connection is made with the remote server, the last certificate(s) + * listed will be the Root CA certificate(s). Merely copy-paste those certificates into this certs.h file + * and format them with each line beginning with " and ending with \r\n" + * + */ + + +//Root Certificates +char CERTIFICATES[1547] = + + //Root certificate Authority for Httpbin.org + "-----BEGIN CERTIFICATE-----\r\n" + "MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU\r\n" + "MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs\r\n" + "IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290\r\n" + "MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux\r\n" + "FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h\r\n" + "bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v\r\n" + "dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt\r\n" + "H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9\r\n" + "uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX\r\n" + "mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX\r\n" + "a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN\r\n" + "E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0\r\n" + "WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD\r\n" + "VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0\r\n" + "Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU\r\n" + "cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx\r\n" + "IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN\r\n" + "AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH\r\n" + "YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5\r\n" + "6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC\r\n" + "Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX\r\n" + "c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a\r\n" + "mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ=\r\n" + "-----END CERTIFICATE-----\r\n" + ; \ No newline at end of file
--- a/main.cpp Mon Mar 16 18:41:09 2015 +0000 +++ b/main.cpp Mon Mar 16 21:35:01 2015 +0000 @@ -1,3 +1,13 @@ +/** For an unsecure HTTP example, just build as is. But, to use the + * HTTPS example, comment out the first main declaration and + * uncomment the second main declaration at the end of this file. + */ + +//Start of the HTTP code +///The example HTTP code sets up a connection to httpbin.org, +///sends a get request on the url: http://httpbin.org/get, +///then it sends a post request to the url: http://httpbin.org/post +///Please let us know if you have any questions/would like more examples. #include "mbed.h" #include "mtsas.h" @@ -13,37 +23,32 @@ char rbuf[4000]; //url strings for HTTP requests, httpbin.org is a public website for fielding test HTTP requests - string url, base_url = "http://httpbin.org:80", url_get = "/get"; + string url, base_url = "http://httpbin.org:80", url_get = "/get", url_post = "/post"; - /** STMicro Nucelo F401RE - * The supported jumper configurations of the MTSAS do not line up with - * the pin mapping of the Nucleo F401RE. Therefore, the MTSAS serial TX - * pin (JP8 Pin 2) must be manually jumped to Serial1 RX (Shield pin D2) - * and the MTSAS serial RX pin (JP9 Pin 2) pin must be manually jumped to - * Serial1 TX (Shield pin D8). - * Uncomment the following line to use the STMicro Nuceleo F401RE - */ + /// STMicro Nucelo F401RE + /// The supported jumper configurations of the MTSAS do not line up with + /// the pin mapping of the Nucleo F401RE. Therefore, the MTSAS serial TX + /// pin (JP8 Pin 2) must be manually jumped to Serial1 RX (Shield pin D2) + /// and the MTSAS serial RX pin (JP9 Pin 2) pin must be manually jumped to + /// Serial1 TX (Shield pin D8). + /// Uncomment the following line to use the STMicro Nuceleo F401RE MTSSerialFlowControl* io = new MTSSerialFlowControl(D8, D2, D3, D6); - /** Dragonfly - * To configure the serial pins for the Dragonfly board, use: - * RADIO_TX = pin PC_7, RADIO_RX = pin PC_6 - * RADIO_RTS = pin PB_10,RADIO_CTS = pin PB_12 - * Uncomment the following lines to use the Dragonfly board - */ + /// Dragonfly + /// To configure the serial pins for the Dragonfly board, use: + /// RADIO_TX = pin PC_7, RADIO_RX = pin PC_6 + /// RADIO_RTS = pin PB_10,RADIO_CTS = pin PB_12 + /// Uncomment the following lines to use the Dragonfly board //MTSSerialFlowControl* io = new MTSSerialFlowControl(PC_7, PC_6, PB_10, PB_12); - //reset_pin = NC; - /** Freescale KL46Z - * To configure the serial pins for the Freescale KL46Z board, use MTSAS jumper - * configuration B. Uncomment the following line to use the Freescale KL46Z board - */ + /// Freescale KL46Z + /// To configure the serial pins for the Freescale KL46Z board, use MTSAS jumper + /// configuration B. Uncomment the following line to use the Freescale KL46Z board //MTSSerialFlowControl* io = new MTSSerialFlowControl(D2, D9, D3, D6); - /** Freescale K64F - * To configure the serial pins for the Freescale K64F board, use MTSAS jumper - * configuration A. Uncomment the following line to use the Freescale K64F board - */ + /// Freescale K64F + /// To configure the serial pins for the Freescale K64F board, use MTSAS jumper + /// configuration A. Uncomment the following line to use the Freescale K64F board //MTSSerialFlowControl* io = new MTSSerialFlowControl(D1, D0, D3, D6); //Sets the baud rate for communicating with the radio @@ -94,7 +99,6 @@ //Send HTTP GET request for (int i = 0; i < 10; i++) { if(http->get(url.c_str(), receive, 5000) == HTTP_OK) { - http->get(url.c_str(), receive, 5000); logInfo("HTTP get succeeded\n%s", rbuf); break; } @@ -104,9 +108,247 @@ wait(1); } + //Format HTTP POST request + url = base_url + url_post; + + //Create data to send + char sbuf[60] = "Hello World! We are testing the MTSAS HTTP Example Program"; + HTTPText send = HTTPText(sbuf); + + //Send HTTP POST request + for (int i = 0; i < 10; i++) { + if(http->post(url.c_str(), send, receive, 5000) == HTTP_OK) { + logInfo("HTTP POST succeeded\n%s", rbuf); + break; + } + if (i >= 10) { + logError("HTTP POST failed"); + } + wait(1); + } + //Disconnect PPP link radio->disconnect(); logInfo("End of example code\n"); return 0; -} \ No newline at end of file +} +//End of the HTTP code + + +//Start of the HTTPS code +///The example HTTPS code sets up a secure connection to httpbin.org, +///sends a get request on the url: https://httpbin.org/get, +///then it sends a post request to the url: https://httpbin.org/post +///and finally it demonstrates a basic authentication with a get request +///to the url: https://httpin.org/basic-auth/Bob/123 +///Please let us know if you have any questions/would like more examples. +/* +#include "mbed.h" +#include "mtsas.h" +#include "certs.h" + +//Function to convert http int results to string messages +char * httpResToStr(HTTPResult res); + +int main(){ + + //Modify to match your apn if you are using an HSPA radio with a SIM card + const char APN[] = ""; + + //Sets the log level to INFO, higher log levels produce more log output. + //Possible levels: NONE, FATAL, ERROR, WARNING, INFO, DEBUG, TRACE + MTSLog::setLogLevel(MTSLog::INFO_LEVEL); + + //Receive buffer + char rbuf[4000]; + + //url strings for HTTPS requests, httpbin.org is a public website for fielding test HTTPS requests + string url, secure_url = "https://httpbin.org:443", url_get = "/get", url_auth = "/basic-auth", url_post = "/post"; + + /// STMicro Nucelo F401RE + /// The supported jumper configurations of the MTSAS do not line up with + /// the pin mapping of the Nucleo F401RE. Therefore, the MTSAS serial TX + /// pin (JP8 Pin 2) must be manually jumped to Serial1 RX (Shield pin D2) + /// and the MTSAS serial RX pin (JP9 Pin 2) pin must be manually jumped to + /// Serial1 TX (Shield pin D8). + /// Uncomment the following line to use the STMicro Nuceleo F401RE + MTSSerialFlowControl* io = new MTSSerialFlowControl(D8, D2, D3, D6); + + /// Dragonfly + /// To configure the serial pins for the Dragonfly board, use: + /// RADIO_TX = pin PC_7, RADIO_RX = pin PC_6 + /// RADIO_RTS = pin PB_10,RADIO_CTS = pin PB_12 + /// Uncomment the following lines to use the Dragonfly board + //MTSSerialFlowControl* io = new MTSSerialFlowControl(PC_7, PC_6, PB_10, PB_12); + + /// Freescale KL46Z + /// To configure the serial pins for the Freescale KL46Z board, use MTSAS jumper + /// configuration B. Uncomment the following line to use the Freescale KL46Z board + //MTSSerialFlowControl* io = new MTSSerialFlowControl(D2, D9, D3, D6); + + /// Freescale K64F + /// To configure the serial pins for the Freescale K64F board, use MTSAS jumper + /// configuration A. Uncomment the following line to use the Freescale K64F board + //MTSSerialFlowControl* io = new MTSSerialFlowControl(D1, D0, D3, D6); + + //Sets the baud rate for communicating with the radio + io->baud(115200); + + MTSLog::setLogLevel(MTSLog::TRACE_LEVEL); + + //Initialize radio configurations + Cellular* radio = CellularFactory::create(io); + if( ! radio) { + logFatal("Radio initialization failed"); + return 1; + } + + radio->configureSignals(D4,D7,RESET); + Transport::setTransport(radio); + + //Set radio APN + for (int i = 0; i < 10; i++) { + if (i >= 10) { + logFatal("Failed to set APN to %s", APN); + return 1; + } + if (radio->setApn(APN) == MTS_SUCCESS) { + logInfo("Successfully set APN to %s", APN); + break; + } else { + wait(1); + } + } + + //Establish PPP link + for (int i = 0; i < 10; i++) { + if (i >= 10) { + logError("Failed to establish PPP link"); + } + if (radio->connect() == true) { + logInfo("Successfully established PPP link"); + break; + } else { + wait(1); + } + } + + //Set up HTTP interface + HTTPClient* http = new HTTPClient(); + HTTPText* receive = new HTTPText(rbuf, 5000); + HTTPResult res; + + //Adds the root certificates for accepted websites to verify that + //the remote host is who it says it is. + //Instructions on obtaining the root certificate is included in certs.h + //(Basically, only load certificates of trusted websites) + //Certificates should be written in PEM format, starts with + //-----BEGIN CERTIFICATE----- and ends with -----END CERTIFICATE----- + //Each line in between must be less than 64 or less characters in length, + //and each line in the certificate must end with /r/n, ex: + //-----BEGIN CERTIFICATE-----\r\n + //923JNF0A7H43HA3F90JA3JMFGNM9A...\r\n + //9823HJ9F8HA8GF283H9A8JF901239...\r\n + //239F8A93HUF898AYU230FUA0239UF...\r\n + //98HAW9EFH98H9WE8\r\n + //-----END CERTIFICATE-----\r\n + res = http->addRootCACertificate(CERTIFICATES); + if(res != HTTP_OK) { + logError("Failed to load CERTIFICATES"); + } + + //Call with argument VERIFY_PEER to turn on SSL security (HTTPS) + //Default argument is VERIFY_NONE which operates as without SSL security (HTTP) + http->setPeerVerification(VERIFY_PEER); + + //Format HTTPS GET request + url = secure_url + url_get; + + //Send HTTPS GET request + for (int i = 0; i < 10; i++) { + if(http->get(url.c_str(), receive, 5000) == HTTP_OK) { + logInfo("HTTPS GET succeeded\n%s", rbuf); + break; + } + if (i >= 10) { + logError("HTTPS GET failed"); + } + wait(1); + } + + //Format HTTPS POST request + url = secure_url + url_post; + + //Create data to send + char sbuf[60] = "Hello World! We are testing the MTSAS HTTPS Example Program"; + HTTPText send = HTTPText(sbuf); + + //Send HTTPS POST request + for (int i = 0; i < 10; i++) { + if(http->post(url.c_str(), send, receive, 5000) == HTTP_OK) { + logInfo("HTTPS POST succeeded\n%s", rbuf); + break; + } + if (i >= 10) { + logError("HTTPS POST failed"); + } + wait(1); + } + + //Basic authentication test values, can be modified + //to any test username and password. Format for url_usr_pw: /<user>/<password> + string url_usr_pw = "/Bob/123"; + const char user[] = "Bob",pw[] = "123"; + + //Format HTTPS basic authentication GET request + url = secure_url + url_auth + url_usr_pw; + + res = http->basicAuth(user,pw); + logTrace("Set username and password?: %s",httpResToStr(res)); + + res = http->get(url.c_str(), receive); + if(res == HTTP_OK) { + logInfo("HTTPS Authenticated GET succeeded [%s]", rbuf); + } else { + logInfo("HTTPS Authenticated GET failed [%s]", httpResToStr(res)); + } + + res = http->basicAuth(NULL,NULL); + logTrace("Reset username and password?: %s",httpResToStr(res)); + + return 0; +} + +char * httpResToStr(HTTPResult res) { + switch(res) { + case HTTP_PROCESSING: + return "HTTP_PROCESSING"; + case HTTP_PARSE: + return "HTTP_PARSE"; + case HTTP_DNS: + return "HTTP_DNS"; + case HTTP_PRTCL: + return "HTTP_PRTCL"; + case HTTP_NOTFOUND: + return "HTTP_NOTFOUND"; + case HTTP_REFUSED: + return "HTTP_REFUSED"; + case HTTP_ERROR: + return "HTTP_ERROR"; + case HTTP_TIMEOUT: + return "HTTP_TIMEOUT"; + case HTTP_CONN: + return "HTTP_CONN"; + case HTTP_CLOSED: + return "HTTP_CLOSED"; + case HTTP_REDIRECT: + return "HTTP_REDIRECT"; + case HTTP_OK: + return "HTTP_OK"; + default: + return "HTTP Result unknown"; + } +} +//End of the HTTPS code +*/ \ No newline at end of file
--- a/mbed.bld Mon Mar 16 18:41:09 2015 +0000 +++ b/mbed.bld Mon Mar 16 21:35:01 2015 +0000 @@ -1,1 +1,1 @@ -http://mbed.org/users/mbed_official/code/mbed/builds/04dd9b1680ae \ No newline at end of file +http://mbed.org/users/mbed_official/code/mbed/builds/7e07b6fb45cf \ No newline at end of file