Skip to content

Commit a5133db

Browse files
added Mqtt client Interface definition
1 parent d2f5935 commit a5133db

File tree

1 file changed

+140
-0
lines changed

1 file changed

+140
-0
lines changed

src/MqttInterface.h

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
#pragma once
2+
#include <functional>
3+
#include <Client.h>
4+
5+
// The Idea for this section of the library is to allow the usage of different implementation for Mqtt Clients
6+
// while preserving the possibility of having an Arduino standardized interface for Mqtt protocol
7+
// One should implement MqttClientInterface and provide a way to instantiate the implementation
8+
9+
// namespace arduino { // namespace net { namespace mqtt {
10+
typedef int error_t; // TODO move this to be generally available
11+
12+
class IStream {
13+
public:
14+
virtual ~IStream() = default;
15+
16+
virtual int available() = 0;
17+
virtual int read() = 0;
18+
// virtual int peek() = 0;
19+
virtual size_t readBytes(uint8_t *buffer, size_t length) = 0; // read chars from stream into buffer
20+
};
21+
22+
class MqttOStream { // if OStream becomes available in arduino core api, we still need to extend its definition
23+
public:
24+
MqttOStream(error_t rc=0): rc(rc) {}
25+
virtual ~MqttOStream() = default;
26+
27+
virtual size_t write(uint8_t) = 0;
28+
virtual size_t write(const uint8_t *buffer, size_t size) = 0;
29+
virtual int availableForWrite() = 0;
30+
31+
const error_t rc;
32+
};
33+
34+
using Topic = const char* const;
35+
36+
// for incoming published messages
37+
using MqttReceiveCallback = std::function<void(Topic, IStream&)>;
38+
39+
// TODO MQTT 5.0 stuff
40+
41+
// TODO define callback for mqtt events. one should be the default, but the user can always change it
42+
43+
// copied from zephyr
44+
// enum mqtt_conn_return_code: error_t {
45+
// /** Connection accepted. */
46+
// MQTT_CONNECTION_ACCEPTED = 0x00,
47+
48+
// /** The Server does not support the level of the MQTT protocol
49+
// * requested by the Client.
50+
// */
51+
// MQTT_UNACCEPTABLE_PROTOCOL_VERSION = 0x01,
52+
53+
// /** The Client identifier is correct UTF-8 but not allowed by the
54+
// * Server.
55+
// */
56+
// MQTT_IDENTIFIER_REJECTED = 0x02,
57+
58+
// /** The Network Connection has been made but the MQTT service is
59+
// * unavailable.
60+
// */
61+
// MQTT_SERVER_UNAVAILABLE = 0x03,
62+
63+
// /** The data in the user name or password is malformed. */
64+
// MQTT_BAD_USER_NAME_OR_PASSWORD = 0x04,
65+
66+
// /** The Client is not authorized to connect. */
67+
// MQTT_NOT_AUTHORIZED = 0x05
68+
// };
69+
70+
constexpr error_t NotImplementedError= -0x100; // TODO define a proper value
71+
72+
enum MqttQos: uint8_t {
73+
MqttQos0 = 0, // At Most once
74+
MqttQos1 = 1, // At least once
75+
MqttQos2 = 2, // Exactly once
76+
};
77+
78+
typedef uint8_t MqttPublishFlag;
79+
enum MqttPublishFlags: MqttPublishFlag {
80+
None = 0,
81+
RetainEnabled = 1,
82+
DupEnabled = 2,
83+
};
84+
85+
// TODO define mqtt version
86+
87+
constexpr MqttQos QosDefault = MqttQos0;
88+
// constexpr size_t MqttClientIdMaxLength = 256;
89+
constexpr size_t MqttClientIdMaxLength = 40;
90+
91+
// TODO it shouldn't be called client, since it is not an arduino client
92+
class MqttClientInterface {
93+
public:
94+
virtual ~MqttClientInterface() = default;
95+
96+
virtual error_t connect(IPAddress ip, uint16_t port) = 0;
97+
virtual error_t connect(const char *host, uint16_t port) = 0; // TODO should host be string instead of c-string?
98+
virtual void disconnect() = 0;
99+
100+
virtual error_t subscribe(Topic t, MqttQos qos = QosDefault) = 0;
101+
102+
virtual error_t publish(
103+
Topic t, uint8_t payload[],
104+
size_t size, MqttQos qos = QosDefault,
105+
MqttPublishFlag flags = MqttPublishFlags::None) = 0;
106+
107+
/**
108+
* Publish method for publishing messages in "streaming mode", meaning that
109+
* they can outsize the available ram. The OStream returned handles the lifecycle of
110+
* an mqtt Message, from the opening header to its termaination.
111+
* The concrete OStream is defined by the implementation
112+
*/
113+
virtual MqttOStream&& publish(
114+
Topic t, MqttQos qos = QosDefault,
115+
MqttPublishFlag flags = MqttPublishFlags::None) = 0;
116+
117+
virtual error_t unsubscribe(Topic t) = 0;
118+
virtual void poll() = 0;
119+
virtual error_t ping() = 0;
120+
121+
virtual void setReceiveCallback(MqttReceiveCallback cbk) = 0;
122+
123+
// nullptr means generate it randomly
124+
virtual void setId(const char* client_id = nullptr) = 0;
125+
126+
// password may be null, if username is null password won't be used
127+
virtual void setUsernamePassword(const char* username, const char* password=nullptr) = 0;
128+
129+
virtual void setWill(
130+
Topic willTopic, const uint8_t* will_message,
131+
size_t will_size, MqttQos qos=QosDefault,
132+
MqttPublishFlag flags = MqttPublishFlags::None) = 0;
133+
134+
virtual void setClient(arduino::Client*) = 0;
135+
136+
// FIXME the following definition may cause errors since one can easily pass a context dependent object
137+
// virtual void setClient(Client&) = 0;
138+
// Could this be a better solution?
139+
// virtual void setClient(Client&&) = 0;
140+
};

0 commit comments

Comments
 (0)