mbed.org implementation of the abstract SmartREST library for the Cumulocity Platform SmartREST protocol.
Dependents: MbedSmartRestMain MbedSmartRestMain
Diff: SmartRest.cpp
- Revision:
- 0:099f76422485
- Child:
- 1:9a11a331e340
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SmartRest.cpp Thu Jul 03 20:38:04 2014 +0200 @@ -0,0 +1,164 @@ +/* + * SmartRest.cpp + * + * Created on: Nov 1, 2013 + * * Authors: Vincent Wochnik <v.wochnik@gmail.com> + * + * Copyright (c) 2013 Cumulocity GmbH + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "SmartRest.h" +#include <stdlib.h> +#include <string.h> + +SmartRest::SmartRest(AbstractClient& client, const char *identifier) : _client(client), _identifier(identifier) +{ + _source = NULL; + _mogid[0] = 0; +} + +int8_t SmartRest::send(DataGenerator& generator) +{ + uint8_t res; + + res = beginRequest(); + if (res != SMARTREST_SUCCESS) + return res; + + _client.sendData(generator); + return awaitResponse(); +} + +int8_t SmartRest::receive(ParsedRecord& record) +{ + uint8_t res; + + if (_source == NULL) + return SMARTREST_INTERNAL_ERROR; + + res = _parser.readFrom(*_source, record); + + switch (res) { + case PARSER_SUCCESS: + return SMARTREST_SUCCESS; + case PARSER_END_OF_RESPONSE: + return SMARTREST_END_OF_RESPONSE; + case PARSER_TIMEOUT_ERROR: + return SMARTREST_TIMEOUT_ERROR; + } + return SMARTREST_INTERNAL_ERROR; +} + +int8_t SmartRest::bootstrap(DataGenerator& generator) +{ + ParsedRecord record; + int8_t ret; + + ret = beginRequest(); + if (ret != SMARTREST_SUCCESS) + return ret; + ret = awaitResponse(); + if (ret != SMARTREST_SUCCESS) + return ret; + ret = receive(record); + if (ret != SMARTREST_SUCCESS) + return ret; + if (!record) { + return SMARTREST_INTERNAL_ERROR; + } + stop(); + + if (setMoGid(record)) + return SMARTREST_SUCCESS; + + if (record.value(0).integerValue() != 40) + return SMARTREST_INTERNAL_ERROR; + + ret = send(generator); + if (ret != SMARTREST_SUCCESS) + return ret; + ret = receive(record); + if (ret != SMARTREST_SUCCESS) + return ret; + stop(); + + if (!setMoGid(record)) + return SMARTREST_INTERNAL_ERROR; + + return SMARTREST_SUCCESS; +} + +void SmartRest::stop() +{ + _source = NULL; + _client.stop(); +} + +uint8_t SmartRest::beginRequest() +{ + int res; + + res = _client.beginRequest(); + if (res == CLIENT_CONNECTION_ERROR) { + return SMARTREST_CONNECTION_FAILED; + } else if (res != CLIENT_OK) { + return SMARTREST_INTERNAL_ERROR; + } + if (strlen(_mogid)) { + if (_client.sendIdentifier(_mogid) != CLIENT_OK) + return SMARTREST_INTERNAL_ERROR; + } else { + if (_client.sendIdentifier(_identifier) != CLIENT_OK) + return SMARTREST_INTERNAL_ERROR; + } + return SMARTREST_SUCCESS; +} + +uint8_t SmartRest::awaitResponse() +{ + if ((_client.endRequest() != CLIENT_OK) || + (_client.awaitResponse() != CLIENT_OK)) + return SMARTREST_INTERNAL_ERROR; + _source = &_client.receiveData(); + return SMARTREST_SUCCESS; +} + +bool SmartRest::setMoGid(ParsedRecord& record) +{ + const char *mogid; + + *_mogid = 0; + if ((record.values() < 2) || (record.value(0).integerValue() != 20)) + return false; + + if ((record.value(1).valueType() != VALUE_INTEGER) || + (record.value(1).integerValue() <= 0)) + return false; + + mogid = record.rawValue(1); + if (strlen(mogid)+1 > sizeof(_mogid)) + return false; + + strcpy(_mogid, mogid); + + return true; +}