A simple client that allows the user to send Json data to Axeda's IoT cloud using an SSL socket (with certificate verification).

Dependencies:   mbed

Only allows use of URLs, not IP addresses. Most CyaSSL errors are caused by incorrect certificates or failed certificate verification (188, 151, 155).

Committer:
Vanger
Date:
Wed Mar 25 18:19:55 2015 +0000
Revision:
3:677bdaf965ac
Parent:
2:cdfc629d20fa
mtsas library updated

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Vanger 0:562ad81d9dd4 1 #include "mbed.h"
Vanger 0:562ad81d9dd4 2 #include "mtsas.h"
Vanger 1:2d299b96dc79 3 #include "certs.h"
Vanger 0:562ad81d9dd4 4
Vanger 0:562ad81d9dd4 5 //Simple function that converts the HTTP result to a string
Vanger 0:562ad81d9dd4 6 //Ex: Result is 0, the string result will be "HTTP_OK"
Vanger 0:562ad81d9dd4 7 char * httpResToStr(HTTPResult res);
Vanger 0:562ad81d9dd4 8
Vanger 1:2d299b96dc79 9 /**Write the model for your device here.
Vanger 1:2d299b96dc79 10 * Can be located on the axeda developer toolbox device info page.
Vanger 1:2d299b96dc79 11 */
Vanger 1:2d299b96dc79 12 const string Modelstr = "";
Vanger 1:2d299b96dc79 13
Vanger 1:2d299b96dc79 14 /**Write the serial for your device here
Vanger 1:2d299b96dc79 15 * Can be located on the axeda developer toolbox device info page.
Vanger 1:2d299b96dc79 16 */
Vanger 1:2d299b96dc79 17 const string Serialstr = "";
Vanger 1:2d299b96dc79 18
Vanger 2:cdfc629d20fa 19 //Size of the http receive and send buffers
Vanger 2:cdfc629d20fa 20 const int BUFFER_SIZE = 2000;
Vanger 2:cdfc629d20fa 21
Vanger 2:cdfc629d20fa 22 //Destination url to send data to the axeda cloud from the device
Vanger 1:2d299b96dc79 23 const string base_url = "https://nucleus-connect.axeda.com/ammp/data/1/";
Vanger 1:2d299b96dc79 24
Vanger 0:562ad81d9dd4 25 int main(){
Vanger 0:562ad81d9dd4 26
Vanger 0:562ad81d9dd4 27 //Sets the log level to INFO, higher log levels produce more log output.
Vanger 0:562ad81d9dd4 28 //Possible levels: NONE, FATAL, ERROR, WARNING, INFO, DEBUG, TRACE
Vanger 0:562ad81d9dd4 29 MTSLog::setLogLevel(MTSLog::INFO_LEVEL);
Vanger 0:562ad81d9dd4 30
Vanger 1:2d299b96dc79 31 /**Root Certificate(s) of the remote server you want to connect to are listed in "certs.h"
Vanger 1:2d299b96dc79 32 * Make sure the certificates are in PEM format, contain \r\n to end each line,
Vanger 1:2d299b96dc79 33 * and if using multiple root CA certificates, just make multiple calls to the addRootCACertificate
Vanger 1:2d299b96dc79 34 * function for each root certificate you wish to add, or add them all as one concatenated string.
Vanger 1:2d299b96dc79 35 *
Vanger 1:2d299b96dc79 36 * Example certificate formatted correctly (length not to scale):
Vanger 1:2d299b96dc79 37 * -----BEGIN CERTIFICATE-----\r\n
Vanger 1:2d299b96dc79 38 * aosdfijaaosdfijaaosdfijaaosdfijaaosdfijaaosdfijaaosdfijaaosdfija\r\n
Vanger 1:2d299b96dc79 39 * afjklewijafliefhiszelifhlsfhilasihflihsalifhalhifliahlfihaslihfl\r\n
Vanger 1:2d299b96dc79 40 * fawefaewf==\r\n
Vanger 1:2d299b96dc79 41 * -----END CERTIFICATE-----\r\n
Vanger 1:2d299b96dc79 42 */
Vanger 0:562ad81d9dd4 43
Vanger 0:562ad81d9dd4 44 //Modify to match your apn if you are using an HSPA radio with a SIM card
Vanger 0:562ad81d9dd4 45 const char APN[] = "";
Vanger 0:562ad81d9dd4 46
Vanger 0:562ad81d9dd4 47 /** STMicro Nucelo F401RE
Vanger 0:562ad81d9dd4 48 * The supported jumper configurations of the MTSAS do not line up with
Vanger 0:562ad81d9dd4 49 * the pin mapping of the Nucleo F401RE. Therefore, the MTSAS serial TX
Vanger 0:562ad81d9dd4 50 * pin (JP8 Pin 2) must be manually jumped to Serial1 RX (Shield pin D2)
Vanger 0:562ad81d9dd4 51 * and the MTSAS serial RX pin (JP9 Pin 2) pin must be manually jumped to
Vanger 0:562ad81d9dd4 52 * Serial1 TX (Shield pin D8).
Vanger 0:562ad81d9dd4 53 * Uncomment the following line to use the STMicro Nuceleo F401RE
Vanger 0:562ad81d9dd4 54 */
Vanger 0:562ad81d9dd4 55 MTSSerialFlowControl* io = new MTSSerialFlowControl(D8, D2, D3, D6);
Vanger 0:562ad81d9dd4 56
Vanger 0:562ad81d9dd4 57 /** Freescale KL46Z
Vanger 0:562ad81d9dd4 58 * To configure the serial pins for the Freescale KL46Z board, use MTSAS jumper
Vanger 0:562ad81d9dd4 59 * configuration B. Uncomment the following line to use the Freescale KL46Z board
Vanger 0:562ad81d9dd4 60 */
Vanger 0:562ad81d9dd4 61 //MTSSerialFlowControl* io = new MTSSerialFlowControl(D2, D9, D3, D6);
Vanger 0:562ad81d9dd4 62
Vanger 0:562ad81d9dd4 63 /** Freescale K64F
Vanger 0:562ad81d9dd4 64 * To configure the serial pins for the Freescale K64F board, use MTSAS jumper
Vanger 0:562ad81d9dd4 65 * configuration A. Uncomment the following line to use the Freescale K64F board
Vanger 0:562ad81d9dd4 66 */
Vanger 0:562ad81d9dd4 67 //MTSSerialFlowControl* io = new MTSSerialFlowControl(D1, D0, D3, D6);
Vanger 0:562ad81d9dd4 68
Vanger 0:562ad81d9dd4 69 //Sets the baud rate for communicating with the radio
Vanger 0:562ad81d9dd4 70 io->baud(115200);
Vanger 0:562ad81d9dd4 71
Vanger 0:562ad81d9dd4 72 //Initialize radio configurations
Vanger 0:562ad81d9dd4 73 Cellular* radio = CellularFactory::create(io);
Vanger 0:562ad81d9dd4 74 if( ! radio) {
Vanger 0:562ad81d9dd4 75 logFatal("Radio initialization failed");
Vanger 0:562ad81d9dd4 76 return 1;
Vanger 0:562ad81d9dd4 77 }
Vanger 1:2d299b96dc79 78
Vanger 0:562ad81d9dd4 79 Transport::setTransport(radio);
Vanger 0:562ad81d9dd4 80
Vanger 0:562ad81d9dd4 81 //Set radio APN
Vanger 0:562ad81d9dd4 82 for (int i = 0; i < 10; i++) {
Vanger 0:562ad81d9dd4 83 if (i >= 10) {
Vanger 0:562ad81d9dd4 84 logError("Failed to set APN to %s", APN);
Vanger 0:562ad81d9dd4 85 }
Vanger 0:562ad81d9dd4 86 if (radio->setApn(APN) == MTS_SUCCESS) {
Vanger 0:562ad81d9dd4 87 logInfo("Successfully set APN to %s", APN);
Vanger 0:562ad81d9dd4 88 break;
Vanger 0:562ad81d9dd4 89 } else {
Vanger 0:562ad81d9dd4 90 wait(1);
Vanger 0:562ad81d9dd4 91 }
Vanger 0:562ad81d9dd4 92 }
Vanger 0:562ad81d9dd4 93
Vanger 0:562ad81d9dd4 94 //Establish PPP link
Vanger 0:562ad81d9dd4 95 for (int i = 0; i < 10; i++) {
Vanger 0:562ad81d9dd4 96 if (i >= 10) {
Vanger 0:562ad81d9dd4 97 logError("Failed to establish PPP link");
Vanger 0:562ad81d9dd4 98 }
Vanger 0:562ad81d9dd4 99 if (radio->connect() == true) {
Vanger 0:562ad81d9dd4 100 logInfo("Successfully established PPP link");
Vanger 0:562ad81d9dd4 101 break;
Vanger 0:562ad81d9dd4 102 } else {
Vanger 0:562ad81d9dd4 103 wait(1);
Vanger 0:562ad81d9dd4 104 }
Vanger 0:562ad81d9dd4 105 }
Vanger 0:562ad81d9dd4 106
Vanger 1:2d299b96dc79 107 //Create receive interface and buffer
Vanger 2:cdfc629d20fa 108 char rbuf[BUFFER_SIZE];
Vanger 0:562ad81d9dd4 109 HTTPText* receive = new HTTPText(rbuf, sizeof(rbuf));
Vanger 0:562ad81d9dd4 110
Vanger 1:2d299b96dc79 111 //Json output object, data must be in Json format, example data is input already:
Vanger 1:2d299b96dc79 112 //HTTPJson type merely sets the HTTP header to JSON type, nothing else is different from the HTTPText type
Vanger 2:cdfc629d20fa 113 char sbuf[BUFFER_SIZE] = "{\"data\":[{\"dataItems\":{\"mental_trauma\":1,\"physical_trauma\":2,\"emotional_trauma\":3}}]}\0";
Vanger 0:562ad81d9dd4 114 HTTPJson* send = new HTTPJson(sbuf);
Vanger 0:562ad81d9dd4 115
Vanger 0:562ad81d9dd4 116 //Create HTTP Client Instance
Vanger 0:562ad81d9dd4 117 HTTPClient* http = new HTTPClient();
Vanger 0:562ad81d9dd4 118 if( !http || !receive || !send) {
Vanger 1:2d299b96dc79 119 logFatal("Failed to instantiate client, send, or receive");
Vanger 0:562ad81d9dd4 120 return 1;
Vanger 0:562ad81d9dd4 121 }
Vanger 0:562ad81d9dd4 122
Vanger 1:2d299b96dc79 123 /**Certificates can all be loaded concurrently as one string with the certificates
Vanger 1:2d299b96dc79 124 * concatenated after one another if so desired. Otherwise, the example here shows
Vanger 1:2d299b96dc79 125 * loading the certificates one by one.
Vanger 1:2d299b96dc79 126 */
Vanger 0:562ad81d9dd4 127 logTrace("Loading certificate(s)");
Vanger 1:2d299b96dc79 128 HTTPResult res = http->addRootCACertificate(CERTIFICATE1);
Vanger 1:2d299b96dc79 129 if(res != HTTP_OK) {
Vanger 1:2d299b96dc79 130 logError("Failed to load CERTIFICATE1");
Vanger 1:2d299b96dc79 131 }
Vanger 1:2d299b96dc79 132
Vanger 1:2d299b96dc79 133 res = http->addRootCACertificate(CERTIFICATE2);
Vanger 0:562ad81d9dd4 134 if(res != HTTP_OK) {
Vanger 1:2d299b96dc79 135 logError("Failed to load CERTIFICATE2");
Vanger 1:2d299b96dc79 136 }
Vanger 1:2d299b96dc79 137
Vanger 1:2d299b96dc79 138 res = http->addRootCACertificate(CERTIFICATE3);
Vanger 1:2d299b96dc79 139 if(res != HTTP_OK) {
Vanger 1:2d299b96dc79 140 logError("Failed to load CERTIFICATE3");
Vanger 0:562ad81d9dd4 141 }
Vanger 0:562ad81d9dd4 142
Vanger 0:562ad81d9dd4 143 /**Set whether or not to verify the remote server's certificate
Vanger 1:2d299b96dc79 144 * VERIFY_NONE Sets the connection to be made using SSL protocol,
Vanger 1:2d299b96dc79 145 * but without remot peer verification using the loaded certificates.
Vanger 1:2d299b96dc79 146 * VERIFY_PEER Sets the connection to be made using SSL protocol,
Vanger 1:2d299b96dc79 147 * and to verify the peer using the loaded root certificates.
Vanger 0:562ad81d9dd4 148 */
Vanger 0:562ad81d9dd4 149 http->setPeerVerification(VERIFY_PEER);
Vanger 0:562ad81d9dd4 150
Vanger 1:2d299b96dc79 151 //URL for axeda.com device connection (includes path)
Vanger 1:2d299b96dc79 152 //Format: https://nucleus-connect.axeda.com/ammp/data/1/<MODEL_STRING_HERE>!<SERIAL_NUMBER_HERE>
Vanger 1:2d299b96dc79 153 string url = base_url + Modelstr + '!' + Serialstr;
Vanger 0:562ad81d9dd4 154
Vanger 0:562ad81d9dd4 155 logTrace("HTTPS POST Request with Certificate");
Vanger 0:562ad81d9dd4 156 res = http->post(url.c_str(), *send, receive);
Vanger 0:562ad81d9dd4 157 if(res == HTTP_OK) {
Vanger 0:562ad81d9dd4 158 logInfo("HTTPS POST succeeded");
Vanger 0:562ad81d9dd4 159 } else {
Vanger 0:562ad81d9dd4 160 logInfo("HTTPS POST failed [%s]", httpResToStr(res));
Vanger 0:562ad81d9dd4 161 }
Vanger 0:562ad81d9dd4 162
Vanger 0:562ad81d9dd4 163 return 0;
Vanger 0:562ad81d9dd4 164 }
Vanger 0:562ad81d9dd4 165
Vanger 0:562ad81d9dd4 166 //Simple error code to string function
Vanger 0:562ad81d9dd4 167 char * httpResToStr(HTTPResult res) {
Vanger 0:562ad81d9dd4 168 switch(res) {
Vanger 0:562ad81d9dd4 169 case HTTP_PROCESSING:
Vanger 0:562ad81d9dd4 170 return "HTTP_PROCESSING";
Vanger 0:562ad81d9dd4 171 case HTTP_PARSE:
Vanger 0:562ad81d9dd4 172 return "HTTP_PARSE";
Vanger 0:562ad81d9dd4 173 case HTTP_DNS:
Vanger 0:562ad81d9dd4 174 return "HTTP_DNS";
Vanger 0:562ad81d9dd4 175 case HTTP_PRTCL:
Vanger 0:562ad81d9dd4 176 return "HTTP_PRTCL";
Vanger 0:562ad81d9dd4 177 case HTTP_NOTFOUND:
Vanger 0:562ad81d9dd4 178 return "HTTP_NOTFOUND";
Vanger 0:562ad81d9dd4 179 case HTTP_REFUSED:
Vanger 0:562ad81d9dd4 180 return "HTTP_REFUSED";
Vanger 0:562ad81d9dd4 181 case HTTP_ERROR:
Vanger 0:562ad81d9dd4 182 return "HTTP_ERROR";
Vanger 0:562ad81d9dd4 183 case HTTP_TIMEOUT:
Vanger 0:562ad81d9dd4 184 return "HTTP_TIMEOUT";
Vanger 0:562ad81d9dd4 185 case HTTP_CONN:
Vanger 0:562ad81d9dd4 186 return "HTTP_CONN";
Vanger 0:562ad81d9dd4 187 case HTTP_CLOSED:
Vanger 0:562ad81d9dd4 188 return "HTTP_CLOSED";
Vanger 0:562ad81d9dd4 189 case HTTP_REDIRECT:
Vanger 0:562ad81d9dd4 190 return "HTTP_REDIRECT";
Vanger 0:562ad81d9dd4 191 case HTTP_OK:
Vanger 0:562ad81d9dd4 192 return "HTTP_OK";
Vanger 0:562ad81d9dd4 193 default:
Vanger 0:562ad81d9dd4 194 return "HTTP Result unknown";
Vanger 0:562ad81d9dd4 195 }
Vanger 0:562ad81d9dd4 196 }