Skip to content

Commit f663374

Browse files
Making MqttClient inherit from MqttClientInterface
1 parent a580a9d commit f663374

File tree

2 files changed

+173
-34
lines changed

2 files changed

+173
-34
lines changed

src/MqttClient.cpp

Lines changed: 129 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,98 @@ int MqttClient::messageRetain() const
171171
return -1;
172172
}
173173

174+
void MqttClient::setClient(arduino::Client* client) {
175+
if(_client != nullptr && _client->connected()) {
176+
// TODO if the current client is connected we cannot perform the change, first call disconnect
177+
return;
178+
}
179+
180+
_client = client;
181+
}
182+
183+
void MqttClient::setReceiveCallback(MqttReceiveCallback cbk) {
184+
_cbk = cbk;
185+
}
186+
187+
class MqttReadStream: public IStream {
188+
public:
189+
MqttReadStream(MqttClient& ref, int available)
190+
: ref(ref), _available(available) { }
191+
192+
size_t readBytes(uint8_t* buf, size_t s) override {
193+
size_t to_read = s < _available ? s : _available;
194+
to_read = ref.readBytes(buf, to_read);
195+
_available -= to_read;
196+
return to_read;
197+
}
198+
199+
int available() override { return _available; }
200+
201+
int read() override {
202+
if(_available > 0) {
203+
_available--;
204+
return ref.read();
205+
} else {
206+
return -1; // TODO return proper error code
207+
}
208+
}
209+
private:
210+
MqttClient& ref;
211+
int _available;
212+
};
213+
214+
class ArduinoMqttOStream: public MqttOStream {
215+
public:
216+
// TODO change pointer to reference, since it won't change
217+
ArduinoMqttOStream(MqttClient &ref, error_t err=0)
218+
: MqttOStream(err), ref(ref) { }// TODO replace err default value with success
219+
220+
~ArduinoMqttOStream() {
221+
ref.endMessage();
222+
}
223+
224+
size_t write(uint8_t a) override {
225+
if(rc == 1) {
226+
return ref.write(a);
227+
}
228+
return 0;
229+
}
230+
231+
size_t write(const uint8_t *buffer, size_t size) override {
232+
if(rc == 1) {
233+
return ref.write(buffer, size);
234+
}
235+
return 0;
236+
}
237+
238+
int availableForWrite() override { return 0; }
239+
240+
private:
241+
MqttClient& ref;
242+
};
243+
244+
245+
error_t MqttClient::publish(Topic t, uint8_t payload[], size_t size, MqttQos qos, MqttPublishFlag flags) {
246+
int error = this->beginMessage(t, (flags & RetainEnabled) == RetainEnabled, qos, (flags & DupEnabled) == DupEnabled);
247+
248+
if(error == 0) { // TODO replace this with a proper enum value
249+
return error;
250+
}
251+
252+
int res = this->write(payload, size);
253+
this->endMessage();
254+
255+
return res;
256+
}
257+
258+
MqttOStream&& MqttClient::publish(Topic t, MqttQos qos, MqttPublishFlag flags) {
259+
int error = this->beginMessage(
260+
t, (flags & RetainEnabled) == RetainEnabled,
261+
static_cast<uint8_t>(qos), (flags & DupEnabled) == DupEnabled);
262+
263+
return std::move(ArduinoMqttOStream(*this, error));
264+
}
265+
174266
int MqttClient::beginMessage(const char* topic, unsigned long size, bool retain, uint8_t qos, bool dup)
175267
{
176268
_txMessageTopic = topic;
@@ -259,6 +351,20 @@ int MqttClient::endMessage()
259351
return 1;
260352
}
261353

354+
void MqttClient::setWill(
355+
Topic willTopic, const uint8_t* will_message, size_t will_size, MqttQos qos, MqttPublishFlag flags) {
356+
int error = this->beginWill(willTopic, (flags & RetainEnabled) == RetainEnabled, qos, (flags & DupEnabled) == DupEnabled);
357+
358+
if(error == 0) { // TODO replace this with a proper enum value
359+
return;
360+
}
361+
362+
int res = this->write(will_message, will_size);
363+
this->endWill();
364+
365+
return;
366+
}
367+
262368
int MqttClient::beginWill(const char* topic, unsigned short size, bool retain, uint8_t qos)
263369
{
264370
int topicLength = strlen(topic);
@@ -314,7 +420,12 @@ int MqttClient::endWill()
314420
return 1;
315421
}
316422

317-
int MqttClient::subscribe(const char* topic, uint8_t qos)
423+
error_t MqttClient::subscribe(Topic topic, MqttQos qos)
424+
{
425+
return subscribe(topic, qos);
426+
}
427+
428+
error_t MqttClient::subscribe(Topic topic, uint8_t qos)
318429
{
319430
int topicLength = strlen(topic);
320431
int remainingLength = topicLength + 5;
@@ -362,12 +473,12 @@ int MqttClient::subscribe(const char* topic, uint8_t qos)
362473
return 0;
363474
}
364475

365-
int MqttClient::subscribe(const String& topic, uint8_t qos)
476+
error_t MqttClient::subscribe(const String& topic, MqttQos qos)
366477
{
367478
return subscribe(topic.c_str(), qos);
368479
}
369480

370-
int MqttClient::unsubscribe(const char* topic)
481+
error_t MqttClient::unsubscribe(Topic topic)
371482
{
372483
int topicLength = strlen(topic);
373484
int remainingLength = topicLength + 4;
@@ -565,16 +676,19 @@ void MqttClient::poll()
565676
} else {
566677
_rxState = MQTT_CLIENT_RX_STATE_READ_PUBLISH_PAYLOAD;
567678

568-
if (_onMessage) {
679+
if(_cbk) {
680+
MqttReadStream stream(*this, _rxLength);
681+
_cbk(_rxMessageTopic.c_str(), stream);
682+
} else if (_onMessage) {
569683
#ifdef MQTT_CLIENT_STD_FUNCTION_CALLBACK
570684
_onMessage(this,_rxLength);
571685
#else
572686
_onMessage(_rxLength);
573687
#endif
688+
}
574689

575-
if (_rxLength == 0) {
576-
_rxState = MQTT_CLIENT_RX_STATE_READ_TYPE;
577-
}
690+
if ((_onMessage || _cbk) && _rxLength == 0) {
691+
_rxState = MQTT_CLIENT_RX_STATE_READ_TYPE;
578692
}
579693
}
580694
}
@@ -592,7 +706,10 @@ void MqttClient::poll()
592706

593707
_rxState = MQTT_CLIENT_RX_STATE_READ_PUBLISH_PAYLOAD;
594708

595-
if (_onMessage) {
709+
if(_cbk) {
710+
MqttReadStream stream(*this, _rxLength);
711+
_cbk(_rxMessageTopic.c_str(), stream);
712+
} else if (_onMessage) {
596713
#ifdef MQTT_CLIENT_STD_FUNCTION_CALLBACK
597714
_onMessage(this,_rxLength);
598715
#else
@@ -647,12 +764,12 @@ void MqttClient::poll()
647764
}
648765
}
649766

650-
int MqttClient::connect(IPAddress ip, uint16_t port)
767+
error_t MqttClient::connect(IPAddress ip, uint16_t port)
651768
{
652769
return connect(ip, NULL, port);
653770
}
654771

655-
int MqttClient::connect(const char *host, uint16_t port)
772+
error_t MqttClient::connect(const char *host, uint16_t port)
656773
{
657774
return connect((uint32_t)0, host, port);
658775
}
@@ -833,7 +950,7 @@ int MqttClient::subscribeQoS() const
833950
return _subscribeQos;
834951
}
835952

836-
int MqttClient::connect(IPAddress ip, const char* host, uint16_t port)
953+
error_t MqttClient::connect(IPAddress ip, const char* host, uint16_t port)
837954
{
838955
if (clientConnected()) {
839956
_client->stop();
@@ -1041,7 +1158,7 @@ void MqttClient::pubcomp(uint16_t id)
10411158
endPacket();
10421159
}
10431160

1044-
void MqttClient::ping()
1161+
error_t MqttClient::ping()
10451162
{
10461163
uint8_t packetBuffer[2];
10471164

src/MqttClient.h

Lines changed: 44 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
#define _MQTT_CLIENT_H_
2222

2323
#include <Arduino.h>
24-
#include <Client.h>
24+
#include "MqttInterface.h"
2525

2626
#define MQTT_CONNECTION_REFUSED -2
2727
#define MQTT_CONNECTION_TIMEOUT -1
@@ -41,9 +41,9 @@
4141

4242
namespace arduino {
4343

44-
class MqttClient : public Client {
44+
class MqttClient : public MqttClientInterface, public Client {
4545
public:
46-
MqttClient(Client* client);
46+
MqttClient(Client* client=nullptr);
4747
MqttClient(Client& client);
4848
virtual ~MqttClient();
4949

@@ -55,34 +55,55 @@ class MqttClient : public Client {
5555
void onMessage(void(*)(int));
5656
#endif
5757

58+
error_t publish(
59+
Topic t, uint8_t payload[],
60+
size_t size, MqttQos qos = QosDefault,
61+
MqttPublishFlag flags = MqttPublishFlags::None);
62+
63+
MqttOStream&& publish(
64+
Topic t, MqttQos qos = QosDefault,
65+
MqttPublishFlag flags = MqttPublishFlags::None);
66+
67+
error_t ping() override;
68+
69+
void setReceiveCallback(MqttReceiveCallback cbk);
70+
71+
void setWill(
72+
Topic willTopic, const uint8_t* will_message,
73+
size_t will_size, MqttQos qos=QosDefault,
74+
MqttPublishFlag flags = MqttPublishFlags::None) override;
75+
76+
void setClient(arduino::Client*) override;
77+
5878
int parseMessage();
5979
String messageTopic() const;
6080
int messageDup() const;
6181
int messageQoS() const;
6282
int messageRetain() const;
6383

64-
int beginMessage(const char* topic, unsigned long size, bool retain = false, uint8_t qos = 0, bool dup = false);
65-
int beginMessage(const String& topic, unsigned long size, bool retain = false, uint8_t qos = 0, bool dup = false);
66-
int beginMessage(const char* topic, bool retain = false, uint8_t qos = 0, bool dup = false);
67-
int beginMessage(const String& topic, bool retain = false, uint8_t qos = 0, bool dup = false);
84+
int beginMessage(const char* topic, unsigned long size, bool retain = false, uint8_t qos = QosDefault, bool dup = false);
85+
int beginMessage(const String& topic, unsigned long size, bool retain = false, uint8_t qos = QosDefault, bool dup = false);
86+
int beginMessage(const char* topic, bool retain = false, uint8_t qos = QosDefault, bool dup = false);
87+
int beginMessage(const String& topic, bool retain = false, uint8_t qos = QosDefault, bool dup = false);
6888
int endMessage();
6989

70-
int beginWill(const char* topic, unsigned short size, bool retain, uint8_t qos);
71-
int beginWill(const String& topic, unsigned short size, bool retain, uint8_t qos);
72-
int beginWill(const char* topic, bool retain, uint8_t qos);
73-
int beginWill(const String& topic, bool retain, uint8_t qos);
90+
int beginWill(const char* topic, unsigned short size, bool retain, uint8_t qos = QosDefault);
91+
int beginWill(const String& topic, unsigned short size, bool retain, uint8_t qos = QosDefault);
92+
int beginWill(const char* topic, bool retain, uint8_t qos = QosDefault);
93+
int beginWill(const String& topic, bool retain, uint8_t qos = QosDefault);
7494
int endWill();
7595

76-
int subscribe(const char* topic, uint8_t qos = 0);
77-
int subscribe(const String& topic, uint8_t qos = 0);
78-
int unsubscribe(const char* topic);
79-
int unsubscribe(const String& topic);
96+
error_t subscribe(Topic topic, MqttQos qos = QosDefault) override;
97+
error_t subscribe(Topic topic, uint8_t qos = QosDefault);
98+
error_t subscribe(const String& topic, MqttQos qos = QosDefault);
99+
error_t unsubscribe(Topic topic) override;
100+
error_t unsubscribe(const String& topic);
80101

81-
void poll();
102+
void poll() override;
82103

83104
// from Client
84-
virtual int connect(IPAddress ip, uint16_t port = 1883);
85-
virtual int connect(const char *host, uint16_t port = 1883);
105+
error_t connect(IPAddress ip, uint16_t port = 1883) override;
106+
error_t connect(const char *host, uint16_t port = 1883) override;
86107
#ifdef ESP8266
87108
virtual int connect(const IPAddress& ip, uint16_t port) { return 0; }; /* ESP8266 core defines this pure virtual in Client.h */
88109
#endif
@@ -97,10 +118,10 @@ class MqttClient : public Client {
97118
virtual uint8_t connected();
98119
virtual operator bool();
99120

100-
void setId(const char* id);
121+
void setId(const char* id) override;
101122
void setId(const String& id);
102123

103-
void setUsernamePassword(const char* username, const char* password);
124+
void setUsernamePassword(const char* username, const char* password) override;
104125
void setUsernamePassword(const String& username, const String& password);
105126

106127
void setCleanSession(bool cleanSession);
@@ -123,8 +144,7 @@ class MqttClient : public Client {
123144
void pubrec(uint16_t id);
124145
void pubrel(uint16_t id);
125146
void pubcomp(uint16_t id);
126-
void ping();
127-
void disconnect();
147+
void disconnect() override;
128148

129149
int beginPacket(uint8_t type, uint8_t flags, size_t length, uint8_t* buffer);
130150
int writeString(const char* s, uint16_t length);
@@ -197,6 +217,8 @@ class MqttClient : public Client {
197217
uint16_t _willBufferIndex;
198218
size_t _willMessageIndex;
199219
uint8_t _willFlags;
220+
221+
MqttReceiveCallback _cbk;
200222
};
201223
}
202224

0 commit comments

Comments
 (0)