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.
SecureDweet.cpp@0:b30bbf6fe90d, 2016-08-22 (annotated)
- 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?
User | Revision | Line number | New 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 |