A client for the SmartREST protocol from Cumulocity.
Fork of MbedSmartRest by
MbedClient.cpp@18:f76f9ae79195, 2014-05-26 (annotated)
- Committer:
- vwochnik
- Date:
- Mon May 26 08:25:44 2014 +0000
- Revision:
- 18:f76f9ae79195
- Parent:
- 14:dc3f8dd5c02b
fix for bootstrapping
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
vwochnik | 3:ce2f116369bd | 1 | #include "MbedClient.h" |
vwochnik | 5:ab909221d22d | 2 | #include <stdlib.h> |
vwochnik | 13:e76920d5e1ec | 3 | #include <string.h> |
vwochnik | 13:e76920d5e1ec | 4 | #include "b64.h" |
vwochnik | 13:e76920d5e1ec | 5 | #include "mbed.h" |
vwochnik | 9:3bbb83e7cbfd | 6 | |
vwochnik | 13:e76920d5e1ec | 7 | MbedClient::MbedClient(const char* host, uint16_t port, const char* username, const char* password) |
vwochnik | 14:dc3f8dd5c02b | 8 | : _host(host), _port(port), _username(username), _password(password), _filter(_source), _source(_sock), _sink(_sock), _sock() |
vwochnik | 3:ce2f116369bd | 9 | { |
vwochnik | 13:e76920d5e1ec | 10 | _state = MBED_STATE_INIT; |
vwochnik | 5:ab909221d22d | 11 | } |
vwochnik | 5:ab909221d22d | 12 | |
vwochnik | 5:ab909221d22d | 13 | MbedClient::~MbedClient() |
vwochnik | 5:ab909221d22d | 14 | { |
vwochnik | 3:ce2f116369bd | 15 | } |
vwochnik | 3:ce2f116369bd | 16 | |
vwochnik | 3:ce2f116369bd | 17 | uint8_t MbedClient::beginRequest() |
vwochnik | 3:ce2f116369bd | 18 | { |
vwochnik | 13:e76920d5e1ec | 19 | if (_state != MBED_STATE_INIT) |
vwochnik | 5:ab909221d22d | 20 | return CLIENT_INTERNAL_ERROR; |
vwochnik | 13:e76920d5e1ec | 21 | |
vwochnik | 13:e76920d5e1ec | 22 | if (_sock.connect(_host, _port) < 0) { |
vwochnik | 13:e76920d5e1ec | 23 | stop(); |
vwochnik | 13:e76920d5e1ec | 24 | return CLIENT_CONNECTION_ERROR; |
vwochnik | 13:e76920d5e1ec | 25 | } |
vwochnik | 13:e76920d5e1ec | 26 | |
vwochnik | 13:e76920d5e1ec | 27 | if ((!send("POST /s HTTP/1.0\r\n")) || |
vwochnik | 13:e76920d5e1ec | 28 | (!send("Host: ")) || |
vwochnik | 13:e76920d5e1ec | 29 | (!send(_host)) || |
vwochnik | 13:e76920d5e1ec | 30 | (!send("\r\n"))) |
vwochnik | 13:e76920d5e1ec | 31 | return CLIENT_CONNECTION_ERROR; |
vwochnik | 13:e76920d5e1ec | 32 | |
vwochnik | 18:f76f9ae79195 | 33 | if ((strlen(_username) > 0) && (strlen(_password) > 0)) { |
vwochnik | 18:f76f9ae79195 | 34 | if (!sendBasicAuth()) |
vwochnik | 18:f76f9ae79195 | 35 | return CLIENT_CONNECTION_ERROR; |
vwochnik | 18:f76f9ae79195 | 36 | } |
vwochnik | 13:e76920d5e1ec | 37 | |
vwochnik | 13:e76920d5e1ec | 38 | _state = MBED_STATE_IN_REQUEST; |
vwochnik | 5:ab909221d22d | 39 | return CLIENT_OK; |
vwochnik | 3:ce2f116369bd | 40 | } |
vwochnik | 3:ce2f116369bd | 41 | |
vwochnik | 5:ab909221d22d | 42 | uint8_t MbedClient::sendIdentifier(const char* identifier) |
vwochnik | 3:ce2f116369bd | 43 | { |
vwochnik | 13:e76920d5e1ec | 44 | if (_state != MBED_STATE_IN_REQUEST) |
vwochnik | 5:ab909221d22d | 45 | return CLIENT_INTERNAL_ERROR; |
vwochnik | 13:e76920d5e1ec | 46 | |
vwochnik | 18:f76f9ae79195 | 47 | if ((identifier != NULL) && (strlen(identifier) != 0)) { |
vwochnik | 18:f76f9ae79195 | 48 | if ((!send("X-Id: ")) || |
vwochnik | 18:f76f9ae79195 | 49 | (!send(identifier)) || |
vwochnik | 18:f76f9ae79195 | 50 | (!send("\r\n"))) |
vwochnik | 18:f76f9ae79195 | 51 | return CLIENT_CONNECTION_ERROR; |
vwochnik | 18:f76f9ae79195 | 52 | } |
vwochnik | 13:e76920d5e1ec | 53 | |
vwochnik | 13:e76920d5e1ec | 54 | _state = MBED_STATE_SENT_ID; |
vwochnik | 5:ab909221d22d | 55 | return CLIENT_OK; |
vwochnik | 3:ce2f116369bd | 56 | } |
vwochnik | 3:ce2f116369bd | 57 | |
vwochnik | 3:ce2f116369bd | 58 | uint8_t MbedClient::sendData(DataGenerator& generator) |
vwochnik | 3:ce2f116369bd | 59 | { |
vwochnik | 14:dc3f8dd5c02b | 60 | size_t len; char lenstr[8]; |
vwochnik | 13:e76920d5e1ec | 61 | |
vwochnik | 13:e76920d5e1ec | 62 | if ((_state != MBED_STATE_IN_REQUEST) && (_state != MBED_STATE_SENT_ID)) |
vwochnik | 5:ab909221d22d | 63 | return CLIENT_INTERNAL_ERROR; |
vwochnik | 13:e76920d5e1ec | 64 | |
vwochnik | 14:dc3f8dd5c02b | 65 | len = generator.writtenLength(); |
vwochnik | 14:dc3f8dd5c02b | 66 | snprintf(lenstr, 8, "%ld", len); |
vwochnik | 14:dc3f8dd5c02b | 67 | |
vwochnik | 13:e76920d5e1ec | 68 | if ((!send("Content-Length: ")) || |
vwochnik | 14:dc3f8dd5c02b | 69 | (!send(lenstr)) || |
vwochnik | 13:e76920d5e1ec | 70 | (!send("\r\n\r\n"))) |
vwochnik | 13:e76920d5e1ec | 71 | return CLIENT_CONNECTION_ERROR; |
vwochnik | 13:e76920d5e1ec | 72 | |
vwochnik | 14:dc3f8dd5c02b | 73 | if (generator.writeTo(_sink) != len) { |
vwochnik | 13:e76920d5e1ec | 74 | stop(); |
vwochnik | 13:e76920d5e1ec | 75 | return CLIENT_CONNECTION_ERROR; |
vwochnik | 13:e76920d5e1ec | 76 | } |
vwochnik | 13:e76920d5e1ec | 77 | |
vwochnik | 13:e76920d5e1ec | 78 | _state = MBED_STATE_SENT_DATA; |
vwochnik | 5:ab909221d22d | 79 | return CLIENT_OK; |
vwochnik | 3:ce2f116369bd | 80 | } |
vwochnik | 3:ce2f116369bd | 81 | |
vwochnik | 3:ce2f116369bd | 82 | uint8_t MbedClient::endRequest() |
vwochnik | 3:ce2f116369bd | 83 | { |
vwochnik | 13:e76920d5e1ec | 84 | if ((_state != MBED_STATE_IN_REQUEST) && (_state != MBED_STATE_SENT_ID) && (_state != MBED_STATE_SENT_DATA)) |
vwochnik | 5:ab909221d22d | 85 | return CLIENT_INTERNAL_ERROR; |
vwochnik | 13:e76920d5e1ec | 86 | |
vwochnik | 13:e76920d5e1ec | 87 | if (_state != MBED_STATE_SENT_DATA) { |
vwochnik | 13:e76920d5e1ec | 88 | // send end of headers |
vwochnik | 13:e76920d5e1ec | 89 | if (!send("\r\n")) |
vwochnik | 13:e76920d5e1ec | 90 | return CLIENT_CONNECTION_ERROR; |
vwochnik | 13:e76920d5e1ec | 91 | } |
vwochnik | 13:e76920d5e1ec | 92 | |
vwochnik | 13:e76920d5e1ec | 93 | if (!_sink.flush()) { |
vwochnik | 13:e76920d5e1ec | 94 | stop(); |
vwochnik | 13:e76920d5e1ec | 95 | return CLIENT_CONNECTION_ERROR; |
vwochnik | 13:e76920d5e1ec | 96 | } |
vwochnik | 13:e76920d5e1ec | 97 | |
vwochnik | 13:e76920d5e1ec | 98 | _state = MBED_STATE_REQ_COMPLETE; |
vwochnik | 7:26524a6a04a1 | 99 | return CLIENT_OK; |
vwochnik | 3:ce2f116369bd | 100 | } |
vwochnik | 3:ce2f116369bd | 101 | |
vwochnik | 3:ce2f116369bd | 102 | uint8_t MbedClient::awaitResponse() |
vwochnik | 3:ce2f116369bd | 103 | { |
vwochnik | 13:e76920d5e1ec | 104 | if (_state != MBED_STATE_REQ_COMPLETE) |
vwochnik | 5:ab909221d22d | 105 | return CLIENT_INTERNAL_ERROR; |
vwochnik | 13:e76920d5e1ec | 106 | |
vwochnik | 14:dc3f8dd5c02b | 107 | if ((_filter.readStatus() != 200) || (!_filter.skipHeaders())) { |
vwochnik | 13:e76920d5e1ec | 108 | stop(); |
vwochnik | 5:ab909221d22d | 109 | return CLIENT_CONNECTION_ERROR; |
vwochnik | 13:e76920d5e1ec | 110 | } |
vwochnik | 13:e76920d5e1ec | 111 | |
vwochnik | 13:e76920d5e1ec | 112 | _state = MBED_STATE_RECVD_RESPONSE; |
vwochnik | 5:ab909221d22d | 113 | return CLIENT_OK; |
vwochnik | 3:ce2f116369bd | 114 | } |
vwochnik | 3:ce2f116369bd | 115 | |
vwochnik | 3:ce2f116369bd | 116 | AbstractDataSource& MbedClient::receiveData() |
vwochnik | 3:ce2f116369bd | 117 | { |
vwochnik | 14:dc3f8dd5c02b | 118 | return _filter; |
vwochnik | 3:ce2f116369bd | 119 | } |
vwochnik | 3:ce2f116369bd | 120 | |
vwochnik | 3:ce2f116369bd | 121 | void MbedClient::stop() |
vwochnik | 3:ce2f116369bd | 122 | { |
vwochnik | 13:e76920d5e1ec | 123 | _sock.close(); |
vwochnik | 13:e76920d5e1ec | 124 | _source.reset(); |
vwochnik | 13:e76920d5e1ec | 125 | _sink.reset(); |
vwochnik | 14:dc3f8dd5c02b | 126 | _filter.reset(); |
vwochnik | 13:e76920d5e1ec | 127 | _state = MBED_STATE_INIT; |
vwochnik | 13:e76920d5e1ec | 128 | } |
vwochnik | 13:e76920d5e1ec | 129 | |
vwochnik | 13:e76920d5e1ec | 130 | bool MbedClient::send(const char *str) |
vwochnik | 13:e76920d5e1ec | 131 | { |
vwochnik | 13:e76920d5e1ec | 132 | if (_sink.write(str) != strlen(str)) { |
vwochnik | 13:e76920d5e1ec | 133 | stop(); |
vwochnik | 13:e76920d5e1ec | 134 | return false; |
vwochnik | 13:e76920d5e1ec | 135 | } |
vwochnik | 13:e76920d5e1ec | 136 | return true; |
vwochnik | 3:ce2f116369bd | 137 | } |
vwochnik | 13:e76920d5e1ec | 138 | |
vwochnik | 13:e76920d5e1ec | 139 | bool MbedClient::sendBasicAuth() |
vwochnik | 13:e76920d5e1ec | 140 | { |
vwochnik | 13:e76920d5e1ec | 141 | size_t ul, pl; unsigned char input[3]; unsigned char output[5]; |
vwochnik | 13:e76920d5e1ec | 142 | int inputOffset = 0; |
vwochnik | 13:e76920d5e1ec | 143 | |
vwochnik | 13:e76920d5e1ec | 144 | if (!send("Authorization: Basic ")) |
vwochnik | 13:e76920d5e1ec | 145 | return false; |
vwochnik | 13:e76920d5e1ec | 146 | |
vwochnik | 13:e76920d5e1ec | 147 | ul = strlen(_username); |
vwochnik | 13:e76920d5e1ec | 148 | pl = strlen(_password); |
vwochnik | 13:e76920d5e1ec | 149 | |
vwochnik | 13:e76920d5e1ec | 150 | for (int i = 0; i < (ul+1+pl); i++) { |
vwochnik | 13:e76920d5e1ec | 151 | if (i < ul) |
vwochnik | 13:e76920d5e1ec | 152 | input[inputOffset++] = _username[i]; |
vwochnik | 13:e76920d5e1ec | 153 | else if (i == ul) |
vwochnik | 13:e76920d5e1ec | 154 | input[inputOffset++] = ':'; |
vwochnik | 13:e76920d5e1ec | 155 | else |
vwochnik | 13:e76920d5e1ec | 156 | input[inputOffset++] = _password[i-(ul+1)]; |
vwochnik | 13:e76920d5e1ec | 157 | |
vwochnik | 13:e76920d5e1ec | 158 | if ((inputOffset == 3) || (i == ul+pl)) { |
vwochnik | 13:e76920d5e1ec | 159 | b64_encode(input, inputOffset, output, 4); |
vwochnik | 13:e76920d5e1ec | 160 | output[4] = '\0'; |
vwochnik | 13:e76920d5e1ec | 161 | if (!send((char*)output)) |
vwochnik | 13:e76920d5e1ec | 162 | return false; |
vwochnik | 13:e76920d5e1ec | 163 | inputOffset = 0; |
vwochnik | 13:e76920d5e1ec | 164 | } |
vwochnik | 13:e76920d5e1ec | 165 | } |
vwochnik | 13:e76920d5e1ec | 166 | |
vwochnik | 13:e76920d5e1ec | 167 | if (!send("\r\n")) |
vwochnik | 13:e76920d5e1ec | 168 | return false; |
vwochnik | 13:e76920d5e1ec | 169 | return true; |
vwochnik | 13:e76920d5e1ec | 170 | } |