Sample code for connecting u-blox c027 to AerCloud

Dependencies:   C027_Support_AerCloud HTTPClient_AerCloud mbed

Fork of HTTPClient_Cellular_HelloWorld by u-blox

Committer:
mchowla
Date:
Fri Nov 14 01:29:08 2014 +0000
Revision:
14:fcdfdd37affe
Parent:
12:955439e7166f
Fix issue where SIM always looked unprovisioned; Add line feeds to console messages so they print cleanly on the console

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ycaer 12:955439e7166f 1 // Copyright 2014 Aeris Communications Inc
ycaer 12:955439e7166f 2 //
ycaer 12:955439e7166f 3 // Licensed under the Apache License, Version 2.0 (the "License");
ycaer 12:955439e7166f 4 // you may not use this file except in compliance with the License.
ycaer 12:955439e7166f 5 // You may obtain a copy of the License at
ycaer 12:955439e7166f 6 //
ycaer 12:955439e7166f 7 // http://www.apache.org/licenses/LICENSE-2.0
ycaer 12:955439e7166f 8 //
ycaer 12:955439e7166f 9 // Unless required by applicable law or agreed to in writing, software
ycaer 12:955439e7166f 10 // distributed under the License is distributed on an "AS IS" BASIS,
ycaer 12:955439e7166f 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
ycaer 12:955439e7166f 12 // See the License for the specific language governing permissions and
ycaer 12:955439e7166f 13 // limitations under the License.
ycaer 12:955439e7166f 14
ycaer 12:955439e7166f 15 //
ycaer 12:955439e7166f 16 // AerCloud sample code for the u-blox C027 board
ycaer 12:955439e7166f 17 // Details on the C027: http://developer.mbed.org/platforms/u-blox-C027/
ycaer 12:955439e7166f 18 // Details on AerCloud: http://www.aeris.com/technology/aercloud/
ycaer 12:955439e7166f 19 // AerCloud Developer Forum: https://developer.aeris.com/
ycaer 12:955439e7166f 20 //
ycaer 12:955439e7166f 21 // Sample writes latitude, longitude, altitude, speed & GPS time to an AerCloud container
ycaer 12:955439e7166f 22 //
ycaer 12:955439e7166f 23 // Dependencies:
ycaer 12:955439e7166f 24 // mbed HTTP Client Libary
ycaer 12:955439e7166f 25 // C027_Support Library
ycaer 12:955439e7166f 26 // mbed Library
ycaer 12:955439e7166f 27 //
ycaer 12:955439e7166f 28 // To get the sample running, you'll need to fill in the following parameters below
ycaer 12:955439e7166f 29 // Your cellular provider's APN: APN
ycaer 12:955439e7166f 30 // AerCloud API Key: AC_APIKEY
ycaer 12:955439e7166f 31 // AerCloud Account ID: acId
ycaer 12:955439e7166f 32 // AerCloud Container: AC_CONTAINER
ycaer 12:955439e7166f 33 //
ycaer 12:955439e7166f 34 // and you'll also need to create an AerCloud contianer with the schema
ycaer 12:955439e7166f 35 // described below
ycaer 12:955439e7166f 36 //
ycaer 12:955439e7166f 37
donatien 0:0e0debc29569 38 #include "mbed.h"
donatien 0:0e0debc29569 39 #include "HTTPClient.h"
ycaer 12:955439e7166f 40 #include "GPS.h"
ycaer 12:955439e7166f 41
ycaer 12:955439e7166f 42 #include "MDM.h"
mazgch 6:6ff6061a0f76 43
mazgch 6:6ff6061a0f76 44 //------------------------------------------------------------------------------------
ycaer 12:955439e7166f 45 // Connectivity Parameters
mazgch 6:6ff6061a0f76 46 //------------------------------------------------------------------------------------
ycaer 12:955439e7166f 47
ycaer 12:955439e7166f 48 //! Aeris SIM does not use PIN
mazgch 3:412a526d7054 49 #define SIMPIN NULL
ycaer 12:955439e7166f 50
ycaer 12:955439e7166f 51 //! The APN of your Aeris SIM
ycaer 12:955439e7166f 52 // You can find the APN for your SIM at https://aerport.aeris.com
mchowla 14:fcdfdd37affe 53 #define APN "_INSERT_YOUR_APN_HERE_"
ycaer 12:955439e7166f 54
ycaer 12:955439e7166f 55 //! User name and password are not required to use Aeris APN
mazgch 3:412a526d7054 56 #define USERNAME NULL
ycaer 12:955439e7166f 57
ycaer 12:955439e7166f 58 //! User name and password are not required to use Aeris APN
mazgch 3:412a526d7054 59 #define PASSWORD NULL
ycaer 12:955439e7166f 60
ycaer 12:955439e7166f 61
ycaer 12:955439e7166f 62 // ------------------------------------------------------------------------------------
ycaer 12:955439e7166f 63 // AerCloud Paramers
ycaer 12:955439e7166f 64 // ------------------------------------------------------------------------------------
ycaer 12:955439e7166f 65
ycaer 12:955439e7166f 66 // AerCloud BASE URL
ycaer 12:955439e7166f 67 #define AC_BASE "http://api.aercloud.aeris.com/v1"
ycaer 12:955439e7166f 68
ycaer 12:955439e7166f 69 //! AerCloud API Key
mchowla 14:fcdfdd37affe 70 // You can find your api key at https://aerport.aeris.com"
mchowla 14:fcdfdd37affe 71 #define AC_APIKEY "_INSERT_YOUR_AERCLOUD_API_KEY_HERE_"
ycaer 12:955439e7166f 72
ycaer 12:955439e7166f 73 //! Aercloud Account Id
ycaer 12:955439e7166f 74 // You can find your account id at https://aerport.aeris.com
ycaer 12:955439e7166f 75 int acId = 1;
ycaer 12:955439e7166f 76
ycaer 12:955439e7166f 77 // AerCloud Container
ycaer 12:955439e7166f 78 // The name of the AerCloud Container to write data into
mchowla 14:fcdfdd37affe 79 #define AC_CONTAINER "C027_Sample" // Example Container
ycaer 12:955439e7166f 80
ycaer 12:955439e7166f 81 //------------------------------------------------------------------------------------
ycaer 12:955439e7166f 82 // AerCloud SCL (Device) Data Model
ycaer 12:955439e7166f 83 // ------------------------------------------------------------------------------------
ycaer 12:955439e7166f 84 //
ycaer 12:955439e7166f 85 // Code assumes an AerCloud Data Model with the following fields
ycaer 12:955439e7166f 86 //
ycaer 12:955439e7166f 87 // Altitude DOUBLE GPS altitude
ycaer 12:955439e7166f 88 // Speed DOUBLE GPS speed
ycaer 12:955439e7166f 89 // VSLat STRING GPS latitude
ycaer 12:955439e7166f 90 // VSLong STRING GPS longitude
ycaer 12:955439e7166f 91 // GPSTime DOUBLE Raw GPS time
ycaer 12:955439e7166f 92 // GPSDate DOUBLE Raw GPS Date
ycaer 12:955439e7166f 93 // SCLID INT AerCloud Device Identifier (i.e. IMEI)
ycaer 12:955439e7166f 94 //
ycaer 12:955439e7166f 95
mazgch 6:6ff6061a0f76 96 //------------------------------------------------------------------------------------
mazgch 3:412a526d7054 97
donatien 1:d263603373ac 98 char str[512];
ycaer 12:955439e7166f 99 char simImei[16];
ycaer 12:955439e7166f 100
mchowla 14:fcdfdd37affe 101 const char* HttpResultToString(HTTPResult r) {
mchowla 14:fcdfdd37affe 102 switch(r) {
mchowla 14:fcdfdd37affe 103 case HTTP_PROCESSING:
mchowla 14:fcdfdd37affe 104 return "HTTP_PROCESSING";
mchowla 14:fcdfdd37affe 105 case HTTP_PARSE:
mchowla 14:fcdfdd37affe 106 return "HTTP_PARSE";
mchowla 14:fcdfdd37affe 107 case HTTP_DNS:
mchowla 14:fcdfdd37affe 108 return "HTTP_DNS";
mchowla 14:fcdfdd37affe 109 case HTTP_PRTCL:
mchowla 14:fcdfdd37affe 110 return "HTTP_PRTCL";
mchowla 14:fcdfdd37affe 111 case HTTP_NOTFOUND:
mchowla 14:fcdfdd37affe 112 return "HTTP_NOTFOUND - 404";
mchowla 14:fcdfdd37affe 113 case HTTP_REFUSED:
mchowla 14:fcdfdd37affe 114 return "HTTP_REFUSED - 403";
mchowla 14:fcdfdd37affe 115 case HTTP_ERROR:
mchowla 14:fcdfdd37affe 116 return "HTTP_ERROR";
mchowla 14:fcdfdd37affe 117 case HTTP_TIMEOUT:
mchowla 14:fcdfdd37affe 118 return "HTTP_TIMEOUT";
mchowla 14:fcdfdd37affe 119 case HTTP_CONN:
mchowla 14:fcdfdd37affe 120 return "HTTP_CONN";
mchowla 14:fcdfdd37affe 121 case HTTP_CLOSED:
mchowla 14:fcdfdd37affe 122 return "HTTP_CLOSED";
mchowla 14:fcdfdd37affe 123 // case HTTP_OK:
mchowla 14:fcdfdd37affe 124 // return "HTTP_OK";
mchowla 14:fcdfdd37affe 125 }
mchowla 14:fcdfdd37affe 126
mchowla 14:fcdfdd37affe 127 return "UNKNOWN ERROR CODE";
mchowla 14:fcdfdd37affe 128 }
donatien 1:d263603373ac 129
donatien 0:0e0debc29569 130 int main()
donatien 0:0e0debc29569 131 {
ycaer 12:955439e7166f 132 bool simProvisioned = false;
ycaer 12:955439e7166f 133 int ret;
ycaer 12:955439e7166f 134 char buf[512] = "";
ycaer 12:955439e7166f 135 int itn = 580;
ycaer 12:955439e7166f 136 const int wait = 100;
ycaer 12:955439e7166f 137 double lastLat = 0, lastLong = 0, lastAlt = 0, lastSpeed = 0, lastTime = 0, lastDate = 0;
ycaer 12:955439e7166f 138 bool abort = false;
ycaer 12:955439e7166f 139
ycaer 12:955439e7166f 140 GPSI2C gps;
ycaer 12:955439e7166f 141
mchowla 14:fcdfdd37affe 142 printf("GPS object created\r\n");
mazgch 5:a18ddbfd70c9 143 // turn on the supplies of the Modem
mazgch 3:412a526d7054 144 MDMSerial mdm;
mchowla 14:fcdfdd37affe 145 printf("Modem object created\r\n");
sam_grove 11:101705d43c92 146 //mdm.setDebug(4); // enable this for debugging issues
ycaer 12:955439e7166f 147 if (!mdm.connect(SIMPIN, APN,USERNAME,PASSWORD)) {
mchowla 14:fcdfdd37affe 148 printf("Unabled to connect to the network.\r\n");
mazgch 4:7fd97087e573 149 return -1;
ycaer 12:955439e7166f 150 }
mazgch 4:7fd97087e573 151 HTTPClient http;
mazgch 8:eea979594a37 152
ycaer 12:955439e7166f 153 //get SIM IMEI
ycaer 12:955439e7166f 154 mdm.getIMEI(simImei);
mchowla 14:fcdfdd37affe 155 printf("Requesting provision info for IMEI %s\r\n",simImei);
ycaer 12:955439e7166f 156
ycaer 12:955439e7166f 157 // Check if SIM is provisioned in AerCloud
mchowla 14:fcdfdd37affe 158 printf("\r\nIs the SIM provisioned? ");
ycaer 12:955439e7166f 159 char url[512];
ycaer 12:955439e7166f 160 snprintf(url, sizeof(url), "%s/%d/scls/%s?apiKey=%s", AC_BASE, acId, simImei, AC_APIKEY);
ycaer 12:955439e7166f 161 ret = http.get(url, str, 128);
mchowla 14:fcdfdd37affe 162 if (ret == HTTP_OK)
donatien 0:0e0debc29569 163 {
ycaer 12:955439e7166f 164 // We're already provisioned
mchowla 14:fcdfdd37affe 165 printf("Yes\r\n");
mchowla 14:fcdfdd37affe 166 printf("Page fetched successfully - read %d characters\r\n", strlen(str));
mchowla 14:fcdfdd37affe 167 printf("Result: %s\r\n", str);
ycaer 12:955439e7166f 168 simProvisioned = true;
mazgch 4:7fd97087e573 169 }
mazgch 4:7fd97087e573 170 else
mazgch 4:7fd97087e573 171 {
mchowla 14:fcdfdd37affe 172 printf("No\r\n");
mchowla 14:fcdfdd37affe 173 printf("Error - ret = %d - HTTP return code = %d\r\n", ret, http.getHTTPResponseCode());
ycaer 12:955439e7166f 174 //SIM is not provisioned. trying to provision it...
ycaer 12:955439e7166f 175 char url[512];
ycaer 12:955439e7166f 176 snprintf(url, sizeof(url), "%s/%d/scls?apiKey=%s", AC_BASE, acId, AC_APIKEY);
ycaer 12:955439e7166f 177
ycaer 12:955439e7166f 178 snprintf(str, sizeof(str), "{\"sclId\":\"%s\"}\0",simImei);
ycaer 12:955439e7166f 179 HTTPText outText(str);
ycaer 12:955439e7166f 180 HTTPText inText(str, 512);
ycaer 12:955439e7166f 181 ret = http.post(url, outText, &inText);
ycaer 12:955439e7166f 182 if (!ret)
ycaer 12:955439e7166f 183 {
mchowla 14:fcdfdd37affe 184 printf("Executed POST successfully - read %d characters\r\n", strlen(str));
mchowla 14:fcdfdd37affe 185 printf("Result: %s\r\n", str);
ycaer 12:955439e7166f 186 simProvisioned = true;
ycaer 12:955439e7166f 187 }
ycaer 12:955439e7166f 188 else
ycaer 12:955439e7166f 189 {
ycaer 12:955439e7166f 190 if(http.getHTTPResponseCode() == 200)
ycaer 12:955439e7166f 191 simProvisioned = true;
mchowla 14:fcdfdd37affe 192 printf("Error - ret = %d - HTTP return code = %d\r\n", ret, http.getHTTPResponseCode());
ycaer 12:955439e7166f 193 }
mazgch 4:7fd97087e573 194 }
donatien 2:270e2d0bb85a 195
ycaer 12:955439e7166f 196 //POST data to containers if SIM has been successfully provisioned
ycaer 12:955439e7166f 197 if(simProvisioned)
mazgch 4:7fd97087e573 198 {
ycaer 12:955439e7166f 199 //Read GPS
ycaer 12:955439e7166f 200 while (!abort)
ycaer 12:955439e7166f 201 {
ycaer 12:955439e7166f 202 while ((ret = gps.getMessage(buf, sizeof(buf))) > 0)
ycaer 12:955439e7166f 203 {
ycaer 12:955439e7166f 204 int len = LENGTH(ret);
ycaer 12:955439e7166f 205 if ((PROTOCOL(ret) == GPSParser::NMEA) && (len > 6))
ycaer 12:955439e7166f 206 {
ycaer 12:955439e7166f 207 if (!strncmp("$GPGLL", buf, 6))
ycaer 12:955439e7166f 208 {
ycaer 12:955439e7166f 209 //Get Lat/Long
ycaer 12:955439e7166f 210 double la = 0, lo = 0;
ycaer 12:955439e7166f 211 char ch;
ycaer 12:955439e7166f 212 if (gps.getNmeaAngle(1,buf,len,la) &&
ycaer 12:955439e7166f 213 gps.getNmeaAngle(3,buf,len,lo) &&
ycaer 12:955439e7166f 214 gps.getNmeaItem(6,buf,len,ch) && ch == 'A')
ycaer 12:955439e7166f 215 {
ycaer 12:955439e7166f 216 lastLat = la;
ycaer 12:955439e7166f 217 lastLong = lo;
ycaer 12:955439e7166f 218 }
ycaer 12:955439e7166f 219 }
ycaer 12:955439e7166f 220 else if (!strncmp("$GPGGA", buf, 6))
ycaer 12:955439e7166f 221 {
ycaer 12:955439e7166f 222 //Get Altitude
ycaer 12:955439e7166f 223 double a = 0;
ycaer 12:955439e7166f 224 if (gps.getNmeaItem(9,buf,len,a)) // altitude msl [m]
ycaer 12:955439e7166f 225 {
ycaer 12:955439e7166f 226 lastAlt = a;
ycaer 12:955439e7166f 227 }
ycaer 12:955439e7166f 228 }
ycaer 12:955439e7166f 229 else if (!strncmp("$GPVTG", buf, 6))
ycaer 12:955439e7166f 230 {
ycaer 12:955439e7166f 231 //Get Speed
ycaer 12:955439e7166f 232 double s = 0;
ycaer 12:955439e7166f 233 if (gps.getNmeaItem(7,buf,len,s)) // speed [km/h]
ycaer 12:955439e7166f 234 {
ycaer 12:955439e7166f 235 lastSpeed = s;
ycaer 12:955439e7166f 236 }
ycaer 12:955439e7166f 237 }
ycaer 12:955439e7166f 238 else if (!strncmp("$GPRMC", buf, 6))
ycaer 12:955439e7166f 239 {
ycaer 12:955439e7166f 240 //Get Timestamp
ycaer 12:955439e7166f 241 double fixTime = 0;
ycaer 12:955439e7166f 242 double fixDate = 0;
ycaer 12:955439e7166f 243
ycaer 12:955439e7166f 244 if (gps.getNmeaItem(1,buf,len,fixTime)) // speed [km/h]
ycaer 12:955439e7166f 245 {
ycaer 12:955439e7166f 246 lastTime = fixTime;
ycaer 12:955439e7166f 247 }
ycaer 12:955439e7166f 248 if (gps.getNmeaItem(9,buf,len,fixDate)) // speed [km/h]
ycaer 12:955439e7166f 249 {
ycaer 12:955439e7166f 250 lastDate = fixDate;
ycaer 12:955439e7166f 251 }
ycaer 12:955439e7166f 252 // printf("time: %f\n Date:%f\n", lastTime, lastDate);
ycaer 12:955439e7166f 253 }
ycaer 12:955439e7166f 254 }
ycaer 12:955439e7166f 255 }
ycaer 12:955439e7166f 256 wait_ms(wait);
ycaer 12:955439e7166f 257 itn++;
ycaer 12:955439e7166f 258 //post every 60 seconds
ycaer 12:955439e7166f 259 if(itn == 590)
ycaer 12:955439e7166f 260 {
ycaer 12:955439e7166f 261 // POST data to AerCLoud
ycaer 12:955439e7166f 262 char url[512];
ycaer 12:955439e7166f 263 snprintf(url, sizeof(url), "%s/%d/scls/%s/containers/%s/contentInstances?apiKey=%s", AC_BASE, acId, simImei, AC_CONTAINER, AC_APIKEY);
ycaer 12:955439e7166f 264
ycaer 12:955439e7166f 265 sprintf(str,"{\"VSLat\": %.5f, \"VSLong\": %.5f, \"Altitude\": %.5f, \"Speed\":%.5f, \"GPSTime\":%.5f, \"GPSDate\":%.5f, \"SCLID\":\"%s\"}", lastLat, lastLong, lastAlt, lastSpeed, lastTime, lastDate, simImei);
ycaer 12:955439e7166f 266 HTTPText outText(str);
ycaer 12:955439e7166f 267 HTTPText inText(str, 512);
mchowla 14:fcdfdd37affe 268 printf("\r\nPost acquired data...\r\n");
ycaer 12:955439e7166f 269 ret = http.post(url, outText, &inText);
mchowla 14:fcdfdd37affe 270 if (ret == HTTP_OK)
ycaer 12:955439e7166f 271 {
mchowla 14:fcdfdd37affe 272 printf("Executed POST successfully - read %d characters\r\n", strlen(str));
mchowla 14:fcdfdd37affe 273 printf("Result: %s\r\n", str);
ycaer 12:955439e7166f 274 }
ycaer 12:955439e7166f 275 else
ycaer 12:955439e7166f 276 {
mchowla 14:fcdfdd37affe 277 printf("Error - ret = %d (%s), - HTTP return code = %d\r\n", ret, HttpResultToString((HTTPResult)ret), http.getHTTPResponseCode());
ycaer 12:955439e7166f 278 }
ycaer 12:955439e7166f 279 itn = 0;
ycaer 12:955439e7166f 280 }
ycaer 12:955439e7166f 281 }
ycaer 12:955439e7166f 282 gps.powerOff();
ycaer 12:955439e7166f 283 } else {
mchowla 14:fcdfdd37affe 284 printf("SIM is not provisioned.\r\n");
donatien 2:270e2d0bb85a 285 }
mazgch 4:7fd97087e573 286
mazgch 4:7fd97087e573 287
mazgch 4:7fd97087e573 288 mdm.disconnect();
mazgch 3:412a526d7054 289 mdm.powerOff();
mazgch 6:6ff6061a0f76 290
ycaer 12:955439e7166f 291 return 0;
donatien 0:0e0debc29569 292 }
ycaer 12:955439e7166f 293