SecureDweet is a dweet.io library that works on HTTPS protocol using SecureHttpClient library. It'll be able to fetch or listen to Dweet APIs and JSON messages.

Committer:
faheem_chaudhary
Date:
Mon Aug 22 18:37:13 2016 +0000
Revision:
0:b30bbf6fe90d
First-cut library code check-in.  No guarantees to work.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
faheem_chaudhary 0:b30bbf6fe90d 1 /*
faheem_chaudhary 0:b30bbf6fe90d 2 * SecureDweet.h
faheem_chaudhary 0:b30bbf6fe90d 3 *
faheem_chaudhary 0:b30bbf6fe90d 4 * Created on: Aug 15, 2016
faheem_chaudhary 0:b30bbf6fe90d 5 * Author: Faheem Inayat
faheem_chaudhary 0:b30bbf6fe90d 6 * Created for: Renesas Electronics America HQ, Santa Clara, CA, USA
faheem_chaudhary 0:b30bbf6fe90d 7 *
faheem_chaudhary 0:b30bbf6fe90d 8 * Copyright (c) 2016 Renesas Electronics America (REA) and Faheem Inayat
faheem_chaudhary 0:b30bbf6fe90d 9 */
faheem_chaudhary 0:b30bbf6fe90d 10 /*
faheem_chaudhary 0:b30bbf6fe90d 11 * MIT License
faheem_chaudhary 0:b30bbf6fe90d 12 *
faheem_chaudhary 0:b30bbf6fe90d 13 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
faheem_chaudhary 0:b30bbf6fe90d 14 * and associated documentation files (the "Software"), to deal in the Software without restriction,
faheem_chaudhary 0:b30bbf6fe90d 15 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
faheem_chaudhary 0:b30bbf6fe90d 16 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
faheem_chaudhary 0:b30bbf6fe90d 17 * furnished to do so, subject to the following conditions:
faheem_chaudhary 0:b30bbf6fe90d 18 *
faheem_chaudhary 0:b30bbf6fe90d 19 * The above copyright notice and this permission notice shall be included in all copies or
faheem_chaudhary 0:b30bbf6fe90d 20 * substantial portions of the Software.
faheem_chaudhary 0:b30bbf6fe90d 21 *
faheem_chaudhary 0:b30bbf6fe90d 22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
faheem_chaudhary 0:b30bbf6fe90d 23 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
faheem_chaudhary 0:b30bbf6fe90d 24 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
faheem_chaudhary 0:b30bbf6fe90d 25 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
faheem_chaudhary 0:b30bbf6fe90d 26 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
faheem_chaudhary 0:b30bbf6fe90d 27 */
faheem_chaudhary 0:b30bbf6fe90d 28
faheem_chaudhary 0:b30bbf6fe90d 29 #include "SecureDweet.h"
faheem_chaudhary 0:b30bbf6fe90d 30 #include "Json.h"
faheem_chaudhary 0:b30bbf6fe90d 31
faheem_chaudhary 0:b30bbf6fe90d 32 #if 0
faheem_chaudhary 0:b30bbf6fe90d 33 //Enable debug
faheem_chaudhary 0:b30bbf6fe90d 34 #include <cstdio>
faheem_chaudhary 0:b30bbf6fe90d 35 #define logInfo(x, ...) do{std::fprintf(stdout,"%s:%s:%s| [SecureDweet:INFO] "x"\r\n", __FILE__, __func__, __LINE__,##__VA_ARGS__);std::fflush(stdout);}while(0)
faheem_chaudhary 0:b30bbf6fe90d 36 #define logWarning(x, ...) do{std::fprintf(stdout,"%s:%s:%s| [SecureDweet:WARN] "x"\r\n", __FILE__, __func__, __LINE__,##__VA_ARGS__);std::fflush(stdout);}while(0)
faheem_chaudhary 0:b30bbf6fe90d 37 #define logError(x, ...) do{std::fprintf(stdout,"%s:%s:%s| [SecureDweet:ERROR] "x"\r\n", __FILE__, __func__, __LINE__,##__VA_ARGS__);std::fflush(stdout);}while(0)
faheem_chaudhary 0:b30bbf6fe90d 38 #else
faheem_chaudhary 0:b30bbf6fe90d 39 //Disable debug
faheem_chaudhary 0:b30bbf6fe90d 40 #define logInfo(x, ...)
faheem_chaudhary 0:b30bbf6fe90d 41 #endif
faheem_chaudhary 0:b30bbf6fe90d 42
faheem_chaudhary 0:b30bbf6fe90d 43 #define logWarning(x, ...)
faheem_chaudhary 0:b30bbf6fe90d 44 #define logError(x, ...)
faheem_chaudhary 0:b30bbf6fe90d 45
faheem_chaudhary 0:b30bbf6fe90d 46 #define HTTP_BUFFER_SIZE 1024
faheem_chaudhary 0:b30bbf6fe90d 47 #define HTTP_CLIENT_DEFAULT_TIMEOUT 300000
faheem_chaudhary 0:b30bbf6fe90d 48
faheem_chaudhary 0:b30bbf6fe90d 49 #define DWEET_URL_GET_LATEST "https://dweet.io/get/latest/dweet/for/"
faheem_chaudhary 0:b30bbf6fe90d 50 #define DWEET_URL_GET_LISTEN_TO "https://dweet.io/listen/for/dweets/from/"
faheem_chaudhary 0:b30bbf6fe90d 51 #define DWEET_KEY_PARAM_NAME "?key="
faheem_chaudhary 0:b30bbf6fe90d 52
faheem_chaudhary 0:b30bbf6fe90d 53 const char KEEP_ALIVE_HEADER [] = "Connection: Keep-Alive\r\nKeep-Alive: timeout=300, max=50\r\n";
faheem_chaudhary 0:b30bbf6fe90d 54
faheem_chaudhary 0:b30bbf6fe90d 55 SecureDweet::SecureDweet ( IDweetParser * _device, const char * _thingName, const char * _readKey,
faheem_chaudhary 0:b30bbf6fe90d 56 const char * _writeKey )
faheem_chaudhary 0:b30bbf6fe90d 57 : device ( _device ), thingName ( _thingName ), readKey ( _readKey ), writeKey ( _writeKey )
faheem_chaudhary 0:b30bbf6fe90d 58 {
faheem_chaudhary 0:b30bbf6fe90d 59 size_t thingNameLength = strlen ( thingName );
faheem_chaudhary 0:b30bbf6fe90d 60 size_t keyLength = 0;
faheem_chaudhary 0:b30bbf6fe90d 61
faheem_chaudhary 0:b30bbf6fe90d 62 if ( writeKey != NULL )
faheem_chaudhary 0:b30bbf6fe90d 63 {
faheem_chaudhary 0:b30bbf6fe90d 64 keyLength = ( strlen ( writeKey ) + strlen ( DWEET_KEY_PARAM_NAME ) );
faheem_chaudhary 0:b30bbf6fe90d 65 }
faheem_chaudhary 0:b30bbf6fe90d 66 else if ( readKey != NULL )
faheem_chaudhary 0:b30bbf6fe90d 67 {
faheem_chaudhary 0:b30bbf6fe90d 68 keyLength = ( strlen ( readKey ) + strlen ( DWEET_KEY_PARAM_NAME ) );
faheem_chaudhary 0:b30bbf6fe90d 69 }
faheem_chaudhary 0:b30bbf6fe90d 70
faheem_chaudhary 0:b30bbf6fe90d 71 {
faheem_chaudhary 0:b30bbf6fe90d 72 size_t lastestUrlLength = strlen ( DWEET_URL_GET_LATEST ) + thingNameLength + keyLength;
faheem_chaudhary 0:b30bbf6fe90d 73 latestUrl = new char [ lastestUrlLength + 1 ];
faheem_chaudhary 0:b30bbf6fe90d 74 int written = sprintf ( latestUrl, "%s%s", DWEET_URL_GET_LATEST, thingName );
faheem_chaudhary 0:b30bbf6fe90d 75 if ( writeKey != NULL )
faheem_chaudhary 0:b30bbf6fe90d 76 {
faheem_chaudhary 0:b30bbf6fe90d 77 sprintf ( latestUrl + written, "%s%s", DWEET_KEY_PARAM_NAME, writeKey );
faheem_chaudhary 0:b30bbf6fe90d 78 }
faheem_chaudhary 0:b30bbf6fe90d 79 else if ( readKey != NULL )
faheem_chaudhary 0:b30bbf6fe90d 80 {
faheem_chaudhary 0:b30bbf6fe90d 81 sprintf ( latestUrl + written, "%s%s", DWEET_KEY_PARAM_NAME, readKey );
faheem_chaudhary 0:b30bbf6fe90d 82 }
faheem_chaudhary 0:b30bbf6fe90d 83 }
faheem_chaudhary 0:b30bbf6fe90d 84
faheem_chaudhary 0:b30bbf6fe90d 85 {
faheem_chaudhary 0:b30bbf6fe90d 86 size_t listenUrlLength = strlen ( DWEET_URL_GET_LISTEN_TO ) + thingNameLength + keyLength;
faheem_chaudhary 0:b30bbf6fe90d 87 listenUrl = new char [ listenUrlLength + 1 ];
faheem_chaudhary 0:b30bbf6fe90d 88 int written = sprintf ( listenUrl, "%s%s", DWEET_URL_GET_LISTEN_TO, thingName );
faheem_chaudhary 0:b30bbf6fe90d 89 if ( writeKey != NULL )
faheem_chaudhary 0:b30bbf6fe90d 90 {
faheem_chaudhary 0:b30bbf6fe90d 91 sprintf ( listenUrl + written, "%s%s", DWEET_KEY_PARAM_NAME, writeKey );
faheem_chaudhary 0:b30bbf6fe90d 92 }
faheem_chaudhary 0:b30bbf6fe90d 93 else if ( readKey != NULL )
faheem_chaudhary 0:b30bbf6fe90d 94 {
faheem_chaudhary 0:b30bbf6fe90d 95 sprintf ( listenUrl + written, "%s%s", DWEET_KEY_PARAM_NAME, readKey );
faheem_chaudhary 0:b30bbf6fe90d 96 }
faheem_chaudhary 0:b30bbf6fe90d 97 }
faheem_chaudhary 0:b30bbf6fe90d 98
faheem_chaudhary 0:b30bbf6fe90d 99 httpClient = new SecureHttpClient ();
faheem_chaudhary 0:b30bbf6fe90d 100 httpClient->setChunkDataListener ( this );
faheem_chaudhary 0:b30bbf6fe90d 101 httpRxBuffer = new char[ HTTP_BUFFER_SIZE + 1];
faheem_chaudhary 0:b30bbf6fe90d 102 httpText = new HttpText ( httpRxBuffer, HTTP_BUFFER_SIZE );
faheem_chaudhary 0:b30bbf6fe90d 103
faheem_chaudhary 0:b30bbf6fe90d 104 // httpClient -> setPeerVerification ( VERIFY_PEER );
faheem_chaudhary 0:b30bbf6fe90d 105 // // Explicitly set the ROOT certificates for dweet.io
faheem_chaudhary 0:b30bbf6fe90d 106 // if ( httpClient -> addRootCACertificate ( sslCertificates ) != HTTP_OK ){
faheem_chaudhary 0:b30bbf6fe90d 107 // logError ( "loading SSL certificates failed" );
faheem_chaudhary 0:b30bbf6fe90d 108 // }
faheem_chaudhary 0:b30bbf6fe90d 109
faheem_chaudhary 0:b30bbf6fe90d 110 listeningFlag = false;
faheem_chaudhary 0:b30bbf6fe90d 111
faheem_chaudhary 0:b30bbf6fe90d 112 }
faheem_chaudhary 0:b30bbf6fe90d 113
faheem_chaudhary 0:b30bbf6fe90d 114 SecureDweet::SecureDweet ( const SecureDweet & )
faheem_chaudhary 0:b30bbf6fe90d 115 : device ( NULL ), thingName ( NULL ), readKey ( NULL ), writeKey ( NULL )
faheem_chaudhary 0:b30bbf6fe90d 116 {
faheem_chaudhary 0:b30bbf6fe90d 117 latestUrl = NULL;
faheem_chaudhary 0:b30bbf6fe90d 118 listenUrl = NULL;
faheem_chaudhary 0:b30bbf6fe90d 119 httpClient = NULL;
faheem_chaudhary 0:b30bbf6fe90d 120 httpRxBuffer = NULL;
faheem_chaudhary 0:b30bbf6fe90d 121 httpText = NULL;
faheem_chaudhary 0:b30bbf6fe90d 122 listeningFlag = false;
faheem_chaudhary 0:b30bbf6fe90d 123 }
faheem_chaudhary 0:b30bbf6fe90d 124
faheem_chaudhary 0:b30bbf6fe90d 125 SecureDweet::~SecureDweet ()
faheem_chaudhary 0:b30bbf6fe90d 126 {
faheem_chaudhary 0:b30bbf6fe90d 127 delete [] latestUrl;
faheem_chaudhary 0:b30bbf6fe90d 128 delete [] listenUrl;
faheem_chaudhary 0:b30bbf6fe90d 129 delete httpClient;
faheem_chaudhary 0:b30bbf6fe90d 130 delete[] httpRxBuffer;
faheem_chaudhary 0:b30bbf6fe90d 131 delete httpText;
faheem_chaudhary 0:b30bbf6fe90d 132 }
faheem_chaudhary 0:b30bbf6fe90d 133
faheem_chaudhary 0:b30bbf6fe90d 134 void SecureDweet::fetchLatestDweet ()
faheem_chaudhary 0:b30bbf6fe90d 135 {
faheem_chaudhary 0:b30bbf6fe90d 136 httpClient->setHeader ( NULL );
faheem_chaudhary 0:b30bbf6fe90d 137 HttpResult res = httpClient->get ( latestUrl, httpText, HTTP_CLIENT_DEFAULT_TIMEOUT );
faheem_chaudhary 0:b30bbf6fe90d 138
faheem_chaudhary 0:b30bbf6fe90d 139 if ( res != HTTP_OK )
faheem_chaudhary 0:b30bbf6fe90d 140 {
faheem_chaudhary 0:b30bbf6fe90d 141 logError ( "HTTP GET failed [%d][%s]", res, httpRxBuffer );
faheem_chaudhary 0:b30bbf6fe90d 142 }
faheem_chaudhary 0:b30bbf6fe90d 143 else
faheem_chaudhary 0:b30bbf6fe90d 144 {
faheem_chaudhary 0:b30bbf6fe90d 145 logInfo ( "Got response:\r\n%s", httpRxBuffer );
faheem_chaudhary 0:b30bbf6fe90d 146 device->parseJsonData ( httpRxBuffer );
faheem_chaudhary 0:b30bbf6fe90d 147 }
faheem_chaudhary 0:b30bbf6fe90d 148 }
faheem_chaudhary 0:b30bbf6fe90d 149
faheem_chaudhary 0:b30bbf6fe90d 150 void SecureDweet::chunkRead ( IHttpDataIn * pDataIn )
faheem_chaudhary 0:b30bbf6fe90d 151 {
faheem_chaudhary 0:b30bbf6fe90d 152 if ( pDataIn != NULL ) {
faheem_chaudhary 0:b30bbf6fe90d 153 int chunkDataSize = 0;
faheem_chaudhary 0:b30bbf6fe90d 154 int valuesExtracted = sscanf ( httpRxBuffer, "%x", &chunkDataSize );
faheem_chaudhary 0:b30bbf6fe90d 155 if ( valuesExtracted == 1 ) // Reading exactly one number
faheem_chaudhary 0:b30bbf6fe90d 156 {
faheem_chaudhary 0:b30bbf6fe90d 157 // Max Chunk Size is 32-bit (4 Hex Digits). Parse it!
faheem_chaudhary 0:b30bbf6fe90d 158 char hexNumber [ 7 ];
faheem_chaudhary 0:b30bbf6fe90d 159 int hexNumberLength = sprintf ( hexNumber, "%X\n\r", chunkDataSize );
faheem_chaudhary 0:b30bbf6fe90d 160 char * lastCr = strrchr ( httpRxBuffer + hexNumberLength, '\n' );
faheem_chaudhary 0:b30bbf6fe90d 161 if ( lastCr != NULL )
faheem_chaudhary 0:b30bbf6fe90d 162 {
faheem_chaudhary 0:b30bbf6fe90d 163 int bufferLength = (int) ( lastCr - ( httpRxBuffer + hexNumberLength ) ) - 1;
faheem_chaudhary 0:b30bbf6fe90d 164
faheem_chaudhary 0:b30bbf6fe90d 165 if ( bufferLength == chunkDataSize ) // There's a possibility that the chunk is complete now. Try to pass it
faheem_chaudhary 0:b30bbf6fe90d 166 {
faheem_chaudhary 0:b30bbf6fe90d 167 Json::unescape (httpRxBuffer + hexNumberLength);
faheem_chaudhary 0:b30bbf6fe90d 168 logInfo("Got chunked response:\r\n%s", httpRxBuffer + hexNumberLength );
faheem_chaudhary 0:b30bbf6fe90d 169 device->parseJsonData (httpRxBuffer + hexNumberLength );
faheem_chaudhary 0:b30bbf6fe90d 170
faheem_chaudhary 0:b30bbf6fe90d 171 pDataIn -> writeReset();
faheem_chaudhary 0:b30bbf6fe90d 172 }
faheem_chaudhary 0:b30bbf6fe90d 173 else if ( bufferLength > chunkDataSize ) // Something is messed up, just clean up the buffer
faheem_chaudhary 0:b30bbf6fe90d 174 {
faheem_chaudhary 0:b30bbf6fe90d 175 pDataIn -> writeReset();
faheem_chaudhary 0:b30bbf6fe90d 176 }
faheem_chaudhary 0:b30bbf6fe90d 177 }
faheem_chaudhary 0:b30bbf6fe90d 178 }
faheem_chaudhary 0:b30bbf6fe90d 179 }
faheem_chaudhary 0:b30bbf6fe90d 180 }
faheem_chaudhary 0:b30bbf6fe90d 181
faheem_chaudhary 0:b30bbf6fe90d 182 void SecureDweet::listenToDweet()
faheem_chaudhary 0:b30bbf6fe90d 183 {
faheem_chaudhary 0:b30bbf6fe90d 184 listeningFlag = true;
faheem_chaudhary 0:b30bbf6fe90d 185 while ( listeningFlag == true )
faheem_chaudhary 0:b30bbf6fe90d 186 {
faheem_chaudhary 0:b30bbf6fe90d 187 httpClient -> setHeader(KEEP_ALIVE_HEADER);
faheem_chaudhary 0:b30bbf6fe90d 188 httpClient -> get (listenUrl, httpText, HTTP_CLIENT_DEFAULT_TIMEOUT);
faheem_chaudhary 0:b30bbf6fe90d 189 httpClient -> setHeader(NULL);
faheem_chaudhary 0:b30bbf6fe90d 190 }
faheem_chaudhary 0:b30bbf6fe90d 191 }
faheem_chaudhary 0:b30bbf6fe90d 192
faheem_chaudhary 0:b30bbf6fe90d 193 void SecureDweet::stopListentingToDweet ()
faheem_chaudhary 0:b30bbf6fe90d 194 {
faheem_chaudhary 0:b30bbf6fe90d 195 listeningFlag = false;
faheem_chaudhary 0:b30bbf6fe90d 196 }
faheem_chaudhary 0:b30bbf6fe90d 197
faheem_chaudhary 0:b30bbf6fe90d 198