LOM2M  0.8.0
mqttBinding.h
Go to the documentation of this file.
1 /*
2  Copyright (c) 2013-2021 LAAS-CNRS (www.laas.fr)
3  7 Colonel Roche 31077 Toulouse - France
4 
5  The use of this source code requires an agreement with the CNRS.
6 
7  Initial Contributors:
8  David Gauchard, Guillaume Garzone, Thierry Monteil.
9 */
10 
11 #ifndef LOM2M_MQTT_BINDING_H
12 #define LOM2M_MQTT_BINDING_H
13 
14 #include "configuration.h"
15 
16 #if MQTTS_BINDING
17 
18 #include "RequestPrimitive.h"
19 #include "ResponsePrimitive.h"
20 #include <ESP8266WiFi.h>
21 #include <PubSubClient.h>
22 
23 extern PubSubClient* MQTT_CLIENT;
24 
25 class MqttTopic;
26 struct MQTTBuffer;
27 
35 bool
36 mqtt_setup(WiFiClientSecure* espClient);
37 
47 void
48 mqtt_reconnect(WiFiClientSecure* espClient, PubSubClient* client, bool loop = true);
49 
56 bool
57 mqtt_send_request(PubSubClient& client, RequestPrimitive& req, MqttTopic& mqttTopic);
58 
65 bool
66 mqtt_send_response(PubSubClient& client, ResponsePrimitive& resp, MqttTopic& mqttTopic);
67 
76 void
77 mqtt_callback(char* topic, byte* payload, unsigned int length);
78 
79 struct MQTTBuffer
80 {
83  {
84  requestPrimitiveBuffer.clear();
86  }
87 
88 protected:
89  std::list<RequestPrimitive*> requestPrimitiveBuffer;
90  std::list<ResponsePrimitive*> responsePrimitiveBuffer;
91 
92 public:
94  {
95  if (!mqttBufferInstance)
96  {
97  mqttBufferInstance = arduino_new(MQTTBuffer);
98  }
99  return mqttBufferInstance;
100  }
102  {
103  requestPrimitiveBuffer.clear();
104  }
106  {
107  responsePrimitiveBuffer.clear();
108  }
110  {
111 #if TARGET_UNIX
112  try
113  {
114 #endif
115  requestPrimitiveBuffer.push_back(request);
116 #if TARGET_UNIX
117  }
118  catch (const std::exception& e)
119  {
120  Serial.println("ERROR occured while adding request primitive to mqtt buffer");
121  Serial.println(e.what());
122  return false;
123  }
124 #endif
125  return true;
126  }
128  {
129 #if TARGET_UNIX
130  try
131  {
132 #endif
134 #if TARGET_UNIX
135  }
136  catch (const std::exception& e)
137  {
138  Serial.println("ERROR occured while adding response primitive to mqtt buffer");
139  Serial.println(e.what());
140  return false;
141  }
142 #endif
143  return true;
144  }
145 
147  {
148  if (responsePrimitiveBuffer.empty())
149  {
150  return nullptr;
151  }
152  else
153  {
155  return res;
156  }
157  }
159 
161  {
162  if (requestPrimitiveBuffer.empty())
163  {
164  return nullptr;
165  }
166  else
167  {
169  requestPrimitiveBuffer.pop_front();
170  return req;
171  }
172  }
173  ResponsePrimitive* getPendingResponse(const String& requestID, const String& from = emptyString);
174 };
175 
177 {
178 public:
184  static void sendRequest(RequestPrimitive& request, ResponsePrimitive* response);
194  static void processFirstPendingRequest();
195 };
196 
201 {
202 protected:
203  String m_source;
204  String m_target;
206  bool m_req;
207  bool m_resp;
208 
209 public:
210  void init()
211  {
214  m_req = false;
215  m_resp = false;
216  m_contentType = "json";
217  }
219  {
220  this->init();
221  }
222  const String& getContentType()
223  {
224  return this->m_contentType;
225  }
226  void setContentType(const String& m_contentType)
227  {
228  this->m_contentType = m_contentType;
229  }
230  bool parseTopic(char* topicChar)
231  {
232  String topicString = String(topicChar);
233  return parseTopicString(topicString);
234  }
235 
236  bool parseTopicString(String& topic)
237  {
238 #if DEBUG
239  Serial.println("Parsing topic: ");
240  Serial.println(topic.c_str());
241 #endif
242 
243  if (!topic.startsWith(CONF_MQTTS_GENERIC_REQ_TOPIC_BASE) && !topic.startsWith(CONF_MQTTS_GENERIC_RESP_TOPIC_BASE))
244  {
245  return false;
246  }
247 
248  setRequestFlag(topic);
249  setResponseFlag(topic);
250 
251  int member = 0;
252  for (int sl, idx = 0; idx < (int)topic.length(); idx = sl + 1)
253  {
254  sl = topic.indexOf('/', idx);
255  if (sl < 0)
256  {
257  sl = topic.length(); //break;
258  }
259  if (sl <= idx + 1)
260  {
261  //idx = sl;
262  if (sl < topic.length() - 1)
263  {
264  continue;
265  }
266  }
267 
268  String name = topic.substring(idx, sl);
269 #if DEBUG
270  Serial.print("Member: ");
271  Serial.print(member);
272  Serial.print(", name: ");
273  Serial.println(name.c_str());
274 #endif
275  if (member == 2)
276  {
277  m_source = name;
278  }
279  else if (member == 3)
280  {
281  m_target = name;
282  }
283  else if (member == 4)
284  {
285  if (name.equalsIgnoreCase(F("json")))
286  {
287  m_contentType = F("application/json");
288  }
289  else
290  {
291  m_contentType = name;
292  }
293  }
294 
295  member++;
296  }
297  if (member < 5)
298  {
299  this->init();
300  return false;
301  }
302  else
303  {
304  return true;
305  }
306  }
307 
308  void setTargetFromUri(const String& uri)
309  {
310  for (int sl, idx = 0; idx < (int)uri.length(); idx = sl + 1)
311  {
312  sl = uri.indexOf('/', idx);
313  if (sl < 0)
314  {
315  sl = uri.length(); //break;
316  }
317  if (sl <= idx + 1)
318  {
319  //idx = sl;
320  if (sl < uri.length() - 1)
321  {
322  continue;
323  }
324  }
325 
326  String target = uri.substring(idx, sl);
327  if (target.equals("~"))
328  {
329  continue;
330  }
331  else
332  {
333 #if DEBUG
334  Serial.print("target ID: ");
335  Serial.println(target.c_str());
336 #endif
337  this->m_target = target;
338  break;
339  }
340  }
341  }
342 
343  void setRequestFlag(String& topic)
344  {
345  if (topic.startsWith(CONF_MQTTS_GENERIC_REQ_TOPIC_BASE))
346  {
347  m_req = true;
348  }
349  }
350 
351  void setResponseFlag(String& topic)
352  {
353  if (topic.startsWith(CONF_MQTTS_GENERIC_RESP_TOPIC_BASE))
354  {
355  m_resp = true;
356  }
357  }
358 
360  {
361  m_req = true;
362  m_resp = false;
363  }
365  {
366  m_resp = true;
367  m_req = false;
368  }
370  {
371  m_req = false;
372  }
374  {
375  m_resp = false;
376  }
377 
378  const String& getSource()
379  {
380  return m_source;
381  }
382 
383  const String& getTarget()
384  {
385  return m_target;
386  }
387 
388  bool isRequest()
389  {
390  return m_req;
391  }
392  bool isResponse()
393  {
394  return m_resp;
395  }
396 
397  void setSource(const String& source)
398  {
399  m_source = source;
400  }
401  void setTarget(const String& target)
402  {
403  m_target = target;
404  }
405 
407  {
408  String topic = "";
409  if (m_req)
410  {
411  topic += String(CONF_MQTTS_GENERIC_REQ_TOPIC_BASE);
412  }
413  else if (m_resp)
414  {
415  topic += String(CONF_MQTTS_GENERIC_RESP_TOPIC_BASE);
416  }
417  else
418  {
419  return emptyString;
420  }
421  topic += m_source + "/" + m_target + String(CONF_MQTTS_GENERIC_TOPIC_END);
422  return topic;
423  }
424 };
425 
426 #endif // MQTTS_BINDING
427 
428 #endif // LOM2M_MQTT_BINDING_H
ResponsePrimitive * response
Definition: Notify.cpp:100
const String emptyString
Definition: mqttBinding.h:177
static void sendRequest(RequestPrimitive &request, ResponsePrimitive *response)
Definition: mqttBinding.cpp:391
static void processFirstPendingRequest()
Definition: mqttBinding.cpp:285
static void sendResponse(ResponsePrimitive &response)
Definition: mqttBinding.h:201
void enableResponseFlag()
Definition: mqttBinding.h:364
void enableRequestFlag()
Definition: mqttBinding.h:359
bool parseTopicString(String &topic)
Definition: mqttBinding.h:236
void disableResponseFlag()
Definition: mqttBinding.h:373
bool m_req
Definition: mqttBinding.h:206
String m_source
Definition: mqttBinding.h:203
bool parseTopic(char *topicChar)
Definition: mqttBinding.h:230
void setContentType(const String &m_contentType)
Definition: mqttBinding.h:226
bool m_resp
Definition: mqttBinding.h:207
void setTarget(const String &target)
Definition: mqttBinding.h:401
const String & getSource()
Definition: mqttBinding.h:378
bool isResponse()
Definition: mqttBinding.h:392
String m_contentType
Definition: mqttBinding.h:205
String getTopicAsString()
Definition: mqttBinding.h:406
const String & getTarget()
Definition: mqttBinding.h:383
bool isRequest()
Definition: mqttBinding.h:388
String m_target
Definition: mqttBinding.h:204
void disableRequestFlag()
Definition: mqttBinding.h:369
void setTargetFromUri(const String &uri)
Definition: mqttBinding.h:308
void setResponseFlag(String &topic)
Definition: mqttBinding.h:351
void init()
Definition: mqttBinding.h:210
const String & getContentType()
Definition: mqttBinding.h:222
void setSource(const String &source)
Definition: mqttBinding.h:397
void setRequestFlag(String &topic)
Definition: mqttBinding.h:343
MqttTopic()
Definition: mqttBinding.h:218
Definition: RequestPrimitive.h:41
Definition: ResponsePrimitive.h:49
#define CONF_MQTTS_GENERIC_REQ_TOPIC_BASE
Definition: configuration.h:108
#define CONF_MQTTS_GENERIC_RESP_TOPIC_BASE
Definition: configuration.h:109
#define CONF_MQTTS_GENERIC_TOPIC_END
Definition: configuration.h:110
WiFiClientSecure * espClient
Definition: lom2m-server-base.h:54
void loop()
Definition: lom2m-server-base.h:261
MqttTopic mqttTopic
Definition: mqttBinding.cpp:191
bool mqtt_send_response(PubSubClient &client, ResponsePrimitive &resp, MqttTopic &mqttTopic)
Definition: mqttBinding.cpp:327
void mqtt_reconnect(WiFiClientSecure *espClient, PubSubClient *client, bool loop=true)
Definition: mqttBinding.cpp:140
bool mqtt_send_request(PubSubClient &client, RequestPrimitive &req, MqttTopic &mqttTopic)
PubSubClient * MQTT_CLIENT
Definition: mqttBinding.cpp:26
bool mqtt_setup(WiFiClientSecure *espClient)
Definition: mqttBinding.cpp:47
void mqtt_callback(char *topic, byte *payload, unsigned int length)
Definition: mqttBinding.cpp:194
Definition: mqttBinding.h:80
void clearRequestBuffer()
Definition: mqttBinding.h:101
void clearResponseBuffer()
Definition: mqttBinding.h:105
RequestPrimitive * getPendingRequest()
Definition: mqttBinding.h:160
std::list< ResponsePrimitive * > responsePrimitiveBuffer
Definition: mqttBinding.h:90
bool addRequestPrimitive(RequestPrimitive *request)
Definition: mqttBinding.h:109
ResponsePrimitive * getPendingResponse()
Definition: mqttBinding.h:146
void pendingResponseProcessed()
static MQTTBuffer * getInstance()
Definition: mqttBinding.h:93
MQTTBuffer()
Definition: mqttBinding.h:82
static MQTTBuffer * mqttBufferInstance
Definition: mqttBinding.h:81
bool addResponsePrimitive(ResponsePrimitive *response)
Definition: mqttBinding.h:127
std::list< RequestPrimitive * > requestPrimitiveBuffer
Definition: mqttBinding.h:89