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:
Mon Mar 23 19:13:52 2015 +0000
Revision:
1:2d299b96dc79
Parent:
0:562ad81d9dd4
Child:
2:cdfc629d20fa
updated example to be fully functional.; Made program easier to read, added more explanation of some functions, updated libraries to be current release ones.

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