A client for the SmartREST protocol from Cumulocity.
Fork of MbedSmartRest by
MbedClient.cpp
- Committer:
- vwochnik
- Date:
- 2014-05-26
- Revision:
- 18:f76f9ae79195
- Parent:
- 14:dc3f8dd5c02b
File content as of revision 18:f76f9ae79195:
#include "MbedClient.h" #include <stdlib.h> #include <string.h> #include "b64.h" #include "mbed.h" MbedClient::MbedClient(const char* host, uint16_t port, const char* username, const char* password) : _host(host), _port(port), _username(username), _password(password), _filter(_source), _source(_sock), _sink(_sock), _sock() { _state = MBED_STATE_INIT; } MbedClient::~MbedClient() { } uint8_t MbedClient::beginRequest() { if (_state != MBED_STATE_INIT) return CLIENT_INTERNAL_ERROR; if (_sock.connect(_host, _port) < 0) { stop(); return CLIENT_CONNECTION_ERROR; } if ((!send("POST /s HTTP/1.0\r\n")) || (!send("Host: ")) || (!send(_host)) || (!send("\r\n"))) return CLIENT_CONNECTION_ERROR; if ((strlen(_username) > 0) && (strlen(_password) > 0)) { if (!sendBasicAuth()) return CLIENT_CONNECTION_ERROR; } _state = MBED_STATE_IN_REQUEST; return CLIENT_OK; } uint8_t MbedClient::sendIdentifier(const char* identifier) { if (_state != MBED_STATE_IN_REQUEST) return CLIENT_INTERNAL_ERROR; if ((identifier != NULL) && (strlen(identifier) != 0)) { if ((!send("X-Id: ")) || (!send(identifier)) || (!send("\r\n"))) return CLIENT_CONNECTION_ERROR; } _state = MBED_STATE_SENT_ID; return CLIENT_OK; } uint8_t MbedClient::sendData(DataGenerator& generator) { size_t len; char lenstr[8]; if ((_state != MBED_STATE_IN_REQUEST) && (_state != MBED_STATE_SENT_ID)) return CLIENT_INTERNAL_ERROR; len = generator.writtenLength(); snprintf(lenstr, 8, "%ld", len); if ((!send("Content-Length: ")) || (!send(lenstr)) || (!send("\r\n\r\n"))) return CLIENT_CONNECTION_ERROR; if (generator.writeTo(_sink) != len) { stop(); return CLIENT_CONNECTION_ERROR; } _state = MBED_STATE_SENT_DATA; return CLIENT_OK; } uint8_t MbedClient::endRequest() { if ((_state != MBED_STATE_IN_REQUEST) && (_state != MBED_STATE_SENT_ID) && (_state != MBED_STATE_SENT_DATA)) return CLIENT_INTERNAL_ERROR; if (_state != MBED_STATE_SENT_DATA) { // send end of headers if (!send("\r\n")) return CLIENT_CONNECTION_ERROR; } if (!_sink.flush()) { stop(); return CLIENT_CONNECTION_ERROR; } _state = MBED_STATE_REQ_COMPLETE; return CLIENT_OK; } uint8_t MbedClient::awaitResponse() { if (_state != MBED_STATE_REQ_COMPLETE) return CLIENT_INTERNAL_ERROR; if ((_filter.readStatus() != 200) || (!_filter.skipHeaders())) { stop(); return CLIENT_CONNECTION_ERROR; } _state = MBED_STATE_RECVD_RESPONSE; return CLIENT_OK; } AbstractDataSource& MbedClient::receiveData() { return _filter; } void MbedClient::stop() { _sock.close(); _source.reset(); _sink.reset(); _filter.reset(); _state = MBED_STATE_INIT; } bool MbedClient::send(const char *str) { if (_sink.write(str) != strlen(str)) { stop(); return false; } return true; } bool MbedClient::sendBasicAuth() { size_t ul, pl; unsigned char input[3]; unsigned char output[5]; int inputOffset = 0; if (!send("Authorization: Basic ")) return false; ul = strlen(_username); pl = strlen(_password); for (int i = 0; i < (ul+1+pl); i++) { if (i < ul) input[inputOffset++] = _username[i]; else if (i == ul) input[inputOffset++] = ':'; else input[inputOffset++] = _password[i-(ul+1)]; if ((inputOffset == 3) || (i == ul+pl)) { b64_encode(input, inputOffset, output, 4); output[4] = '\0'; if (!send((char*)output)) return false; inputOffset = 0; } } if (!send("\r\n")) return false; return true; }