mbed.org implementation of the abstract SmartREST library for the Cumulocity Platform SmartREST protocol.

Dependents:   MbedSmartRestMain MbedSmartRestMain

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SmartRest.cpp Source File

SmartRest.cpp

00001 /*
00002  * SmartRest.cpp
00003  *
00004  * Created on: Nov 1, 2013
00005  * * Authors: Vincent Wochnik <v.wochnik@gmail.com>
00006  *
00007  * Copyright (c) 2013 Cumulocity GmbH
00008  *
00009  * Permission is hereby granted, free of charge, to any person obtaining
00010  * a copy of this software and associated documentation files (the
00011  * "Software"), to deal in the Software without restriction, including
00012  * without limitation the rights to use, copy, modify, merge, publish,
00013  * distribute, sublicense, and/or sell copies of the Software, and to
00014  * permit persons to whom the Software is furnished to do so, subject to
00015  * the following conditions:
00016  *
00017  * The above copyright notice and this permission notice shall be
00018  * included in all copies or substantial portions of the Software.
00019  *
00020  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00021  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00022  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00023  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00024  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00025  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00026  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00027  */
00028 
00029 #include "SmartRest.h"
00030 #include <stdlib.h>
00031 #include <string.h>
00032 
00033 
00034 /*-------------------------------------------------------------------------*/
00035 SmartRest::SmartRest(AbstractClient& client, const char *identifier) :
00036     _client(client),
00037     _identifier(identifier)
00038 {
00039     _source = NULL;
00040     _mogid[0] = 0;
00041 }
00042 /*-------------------------------------------------------------------------*/
00043 uint8_t SmartRest::setAuthorization(const char *username, const char *password)
00044 {
00045     uint8_t res;
00046 
00047     res = _client.setAuthorization(username, password);
00048     if (res != CLIENT_OK)
00049         return SMARTREST_INTERNAL_ERROR;
00050     return SMARTREST_SUCCESS;
00051 }
00052 /*-------------------------------------------------------------------------*/
00053 #ifdef SMARTREST_TRANSACTIONAL
00054 /*-------------------------------------------------------------------------*/
00055 uint8_t SmartRest::request(const DataGenerator& generator, const char *overrideIdentifier)
00056 {
00057     uint8_t res;
00058 
00059     res = send(generator, overrideIdentifier);
00060     stop();
00061     return res;
00062 }
00063 /*-------------------------------------------------------------------------*/
00064 uint8_t SmartRest::request(const DataGenerator& generator, Aggregator& aggregator, const char *overrideIdentifier)
00065 {
00066     uint8_t res;
00067 
00068     if (!aggregator.managed())
00069         return SMARTREST_INTERNAL_ERROR;
00070 
00071     res = send(generator, overrideIdentifier);
00072     if (res != SMARTREST_SUCCESS)
00073     {
00074         stop();
00075         return res;
00076     }
00077 
00078     ParsedRecord recvd;
00079     while ((res = receive(recvd)) == SMARTREST_SUCCESS)
00080     {
00081         if (!aggregator.add(recvd))
00082             return SMARTREST_INTERNAL_ERROR;
00083     }
00084 
00085     stop();
00086     if (res == SMARTREST_END_OF_RESPONSE)
00087         return SMARTREST_SUCCESS;
00088     return res;
00089 }
00090 /*-------------------------------------------------------------------------*/
00091 #endif  // SMARTREST_TRANSACTIONAL
00092 /*-------------------------------------------------------------------------*/
00093 uint8_t SmartRest::bootstrap(const DataGenerator& generator)
00094 {
00095     ParsedRecord record;
00096     int8_t ret;
00097 
00098     ret = beginRequest(NULL, NULL);
00099     if (ret != SMARTREST_SUCCESS)
00100         return ret;
00101     ret = awaitResponse();
00102     if (ret != SMARTREST_SUCCESS)
00103         return ret;
00104     ret = receive(record);
00105     if (ret != SMARTREST_SUCCESS)
00106         return ret;
00107     if (!record)
00108     {
00109         return SMARTREST_INTERNAL_ERROR;
00110     }
00111     stop();
00112 
00113     if (setMoGid(record))
00114         return SMARTREST_SUCCESS;
00115 
00116     if (record.value(0).integerValue() != 40)
00117         return SMARTREST_INTERNAL_ERROR;
00118 
00119     ret = send(generator, NULL);
00120     if (ret != SMARTREST_SUCCESS)
00121         return ret;
00122     ret = receive(record);
00123     if (ret != SMARTREST_SUCCESS)
00124         return ret;
00125     stop();
00126 
00127     if (!setMoGid(record))
00128         return SMARTREST_INTERNAL_ERROR;
00129 
00130     return SMARTREST_SUCCESS;
00131 }
00132 /*-------------------------------------------------------------------------*/
00133 uint8_t SmartRest::send(const DataGenerator& generator, const char *overrideIdentifier)
00134 {
00135     uint8_t res;
00136 
00137     res = beginRequest(NULL, overrideIdentifier);
00138     if (res != SMARTREST_SUCCESS)
00139         return res;
00140 
00141     _client.sendData(generator);
00142     return awaitResponse();
00143 }
00144 /*-------------------------------------------------------------------------*/
00145 uint8_t SmartRest::stream(const char *uri, const Record& record, const char *overrideIdentifier)
00146 {
00147     uint8_t res;
00148 
00149     res = beginRequest(uri, overrideIdentifier);
00150     if (res != SMARTREST_SUCCESS)
00151         return res;
00152 
00153     _client.sendData(record);
00154     return awaitResponse();
00155 }
00156 /*-------------------------------------------------------------------------*/
00157 uint8_t SmartRest::receive(ParsedRecord& record)
00158 {
00159     uint8_t res;
00160 
00161     if (_source == NULL)
00162         return SMARTREST_INTERNAL_ERROR;
00163 
00164     res = _parser.readFrom(*_source, record);
00165 
00166     switch (res)
00167     {
00168         case PARSER_SUCCESS:
00169             return SMARTREST_SUCCESS;
00170         case PARSER_END_OF_RESPONSE:
00171             return SMARTREST_END_OF_RESPONSE;
00172         case PARSER_TIMEOUT_ERROR:
00173             return SMARTREST_TIMEOUT_ERROR;
00174     }
00175     return SMARTREST_INTERNAL_ERROR;
00176 }
00177 /*-------------------------------------------------------------------------*/
00178 void SmartRest::stop()
00179 {
00180     _source = NULL;
00181     _client.stop();
00182 }
00183 /*-------------------------------------------------------------------------*/
00184 const char * SmartRest::getIdentifier()
00185 {
00186     if (*_mogid)
00187         return _mogid;
00188     return _identifier;
00189 }
00190 /*-------------------------------------------------------------------------*/
00191 uint8_t SmartRest::beginRequest(const char *uri, const char *overrideIdentifier)
00192 {
00193     int res;
00194 
00195     if (uri != NULL)
00196     {
00197         res = _client.beginStream(uri);
00198     }
00199     else
00200     {
00201         res = _client.beginRequest();
00202     }
00203 
00204     if (res == CLIENT_CONNECTION_ERROR)
00205     {
00206         return SMARTREST_CONNECTION_FAILED;
00207     }
00208     else if (res != CLIENT_OK)
00209     {
00210         return SMARTREST_INTERNAL_ERROR;
00211     }
00212     if (overrideIdentifier != NULL)
00213     {
00214         if (_client.sendIdentifier(overrideIdentifier) != CLIENT_OK)
00215             return SMARTREST_INTERNAL_ERROR;
00216     }
00217     else
00218     {
00219         if (_client.sendIdentifier(getIdentifier()) != CLIENT_OK)
00220             return SMARTREST_INTERNAL_ERROR;
00221     }
00222     return SMARTREST_SUCCESS;
00223 }
00224 /*-------------------------------------------------------------------------*/
00225 uint8_t SmartRest::awaitResponse()
00226 {
00227     if ((_client.endRequest() != CLIENT_OK) ||
00228             (_client.awaitResponse() != CLIENT_OK))
00229         return SMARTREST_INTERNAL_ERROR;
00230     _source = &_client.receiveData();
00231     return SMARTREST_SUCCESS;
00232 }
00233 /*-------------------------------------------------------------------------*/
00234 bool SmartRest::setMoGid(ParsedRecord& record)
00235 {
00236     const char *mogid;
00237 
00238     *_mogid = 0;
00239     if ((record.values() < 2) || (record.value(0).integerValue() != 20))
00240         return false;
00241 
00242     if ((record.value(1).valueType() != VALUE_INTEGER) ||
00243             (record.value(1).integerValue() <= 0))
00244         return false;
00245 
00246     mogid = record.rawValue(1);
00247     if (strlen(mogid)+1 > sizeof(_mogid))
00248         return false;
00249 
00250     strcpy(_mogid, mogid);
00251 
00252     return true;
00253 }
00254 /*-------------------------------------------------------------------------*/