SSCMA-Micro CPP SDK  v2.0.0
SSCMA-Micro is a cross-platform machine learning inference framework designed for embedded devices.
mqtt.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include <cstdint>
4 #include <cstring>
5 #include <functional>
6 #include <string>
7 
8 #include "core/ma_core.h"
9 #include "porting/ma_porting.h"
10 #include "resource.hpp"
11 
12 static int32_t _mqtt_status = 0;
13 static ma_mqtt_config_t _mqtt_server_config{};
14 static ma_mqtt_topic_config_t _mqtt_topic_config{};
15 
16 #ifndef MA_HAS_NATTIVE_MQTT_SUPPORT
17  #define MA_HAS_NATTIVE_MQTT_SUPPORT 1
18 #endif
19 
20 #if MA_USE_EXTERNAL_WIFI_STATUS
21 extern volatile int _net_sta;
22 #endif
23 
24 namespace ma::server::callback {
25 
26 void getMqttPubsub(const std::vector<std::string>& argv, Transport& transport, Encoder& encoder) {
27  ma_err_t ret = MA_OK;
28 
29  MA_STORAGE_GET_ASTR(
30  static_resource->device->getStorage(), MA_STORAGE_KEY_MQTT_PUB_TOPIC, _mqtt_topic_config.pub_topic, "");
31  MA_STORAGE_GET_ASTR(
32  static_resource->device->getStorage(), MA_STORAGE_KEY_MQTT_SUB_TOPIC, _mqtt_topic_config.sub_topic, "");
33  MA_STORAGE_GET_POD(
34  static_resource->device->getStorage(), MA_STORAGE_KEY_MQTT_PUB_QOS, _mqtt_topic_config.pub_qos, 0);
35  MA_STORAGE_GET_POD(
36  static_resource->device->getStorage(), MA_STORAGE_KEY_MQTT_SUB_QOS, _mqtt_topic_config.sub_qos, 0);
37 
38  encoder.begin(MA_MSG_TYPE_RESP, ret, argv[0]);
39  encoder.write(_mqtt_topic_config);
40  encoder.end();
41  transport.send(reinterpret_cast<const char*>(encoder.data()), encoder.size());
42 }
43 
44 void configureMqttPubsub(const std::vector<std::string>& argv, Transport& transport, Encoder& encoder) {
45  ma_err_t ret = MA_OK;
46 
47  if (argv.size() < 5) {
48  ret = MA_EINVAL;
49  goto exit;
50  }
51 
52  std::strncpy(_mqtt_topic_config.pub_topic, argv[1].c_str(), MA_MQTT_MAX_TOPIC_LENGTH - 1);
53  std::strncpy(_mqtt_topic_config.sub_topic, argv[2].c_str(), MA_MQTT_MAX_TOPIC_LENGTH - 1);
54  _mqtt_topic_config.pub_qos = std::atoi(argv[3].c_str());
55  _mqtt_topic_config.sub_qos = std::atoi(argv[4].c_str());
56 
57  MA_STORAGE_SET_ASTR(
58  ret, static_resource->device->getStorage(), MA_STORAGE_KEY_MQTT_PUB_TOPIC, _mqtt_topic_config.pub_topic);
59  MA_STORAGE_SET_ASTR(
60  ret, static_resource->device->getStorage(), MA_STORAGE_KEY_MQTT_SUB_TOPIC, _mqtt_topic_config.sub_topic);
61  MA_STORAGE_SET_POD(
62  ret, static_resource->device->getStorage(), MA_STORAGE_KEY_MQTT_PUB_QOS, _mqtt_topic_config.pub_qos);
63  MA_STORAGE_SET_POD(
64  ret, static_resource->device->getStorage(), MA_STORAGE_KEY_MQTT_SUB_QOS, _mqtt_topic_config.sub_qos);
65 
66 exit:
67  encoder.begin(MA_MSG_TYPE_RESP, ret, argv[0]);
68  encoder.write(_mqtt_topic_config);
69  encoder.end();
70  transport.send(reinterpret_cast<const char*>(encoder.data()), encoder.size());
71 }
72 
73 void getMqttSta(const std::vector<std::string>& argv, Transport& transport, Encoder& encoder) {
74  ma_err_t ret = MA_OK;
75 
76  encoder.begin(MA_MSG_TYPE_RESP, ret, argv[0]);
77 #if MA_USE_EXTERNAL_WIFI_STATUS
78  _mqtt_status = (((uint8_t)_net_sta & 0xf) - 1) & 0b0110;
79 #endif
80  encoder.write("status", _mqtt_status);
81  encoder.end();
82  transport.send(reinterpret_cast<const char*>(encoder.data()), encoder.size());
83 }
84 
85 #if !MA_HAS_NATTIVE_MQTT_SUPPORT
86 void setMqttSta(const std::vector<std::string>& argv, Transport& transport, Encoder& encoder) {
87  ma_err_t ret = MA_OK;
88 
89  if (argv.size() < 2) {
90  ret = MA_EINVAL;
91  goto exit;
92  }
93 
94  _mqtt_status = std::atoi(argv[1].c_str());
95 
96 exit:
97  encoder.begin(MA_MSG_TYPE_RESP, ret, argv[0]);
98  encoder.write("status", _mqtt_status);
99  encoder.end();
100  transport.send(reinterpret_cast<const char*>(encoder.data()), encoder.size());
101 }
102 #endif
103 
104 void configureMqttServer(const std::vector<std::string>& argv, Transport& transport, Encoder& encoder) {
105  ma_err_t ret = MA_OK;
106 
107  if (argv.size() < 7) {
108  MA_LOGD(MA_TAG, "Invalid number of arguments %d", argv.size());
109  ret = MA_EINVAL;
110  goto exit;
111  }
112 
113  std::strncpy(_mqtt_server_config.host, argv[2].c_str(), MA_MQTT_MAX_BROKER_LENGTH - 1);
114  _mqtt_server_config.port = std::atoi(argv[3].c_str());
115  {
116  std::string client_id = argv[1];
117  if (client_id.empty()) {
118  using namespace std::string_literals;
119  client_id = std::string(PRODUCT_NAME_PREFIX) + "_"s + std::string(PRODUCT_NAME_SUFFIX) + "_"s +
120  static_resource->device->id();
121  }
122  std::strncpy(_mqtt_server_config.client_id, client_id.c_str(), MA_MQTT_MAX_CLIENT_ID_LENGTH - 1);
123  }
124  std::strncpy(_mqtt_server_config.username, argv[4].c_str(), MA_MQTT_MAX_USERNAME_LENGTH - 1);
125  std::strncpy(_mqtt_server_config.password, argv[5].c_str(), MA_MQTT_MAX_PASSWORD_LENGTH - 1);
126  _mqtt_server_config.use_ssl = std::atoi(argv[6].c_str());
127 
128  MA_STORAGE_SET_ASTR(ret, static_resource->device->getStorage(), MA_STORAGE_KEY_MQTT_HOST, _mqtt_server_config.host);
129  MA_STORAGE_SET_POD(ret, static_resource->device->getStorage(), MA_STORAGE_KEY_MQTT_PORT, _mqtt_server_config.port);
130  MA_STORAGE_SET_ASTR(
131  ret, static_resource->device->getStorage(), MA_STORAGE_KEY_MQTT_CLIENTID, _mqtt_server_config.client_id);
132  MA_STORAGE_SET_ASTR(
133  ret, static_resource->device->getStorage(), MA_STORAGE_KEY_MQTT_USER, _mqtt_server_config.username);
134  MA_STORAGE_SET_ASTR(
135  ret, static_resource->device->getStorage(), MA_STORAGE_KEY_MQTT_PWD, _mqtt_server_config.password);
136  MA_STORAGE_SET_POD(
137  ret, static_resource->device->getStorage(), MA_STORAGE_KEY_MQTT_SSL, _mqtt_server_config.use_ssl);
138 
139  {
140  using namespace std::string_literals;
141  std::string topic_prefix = "sscma/"s + std::string(MA_AT_API_VERSION) + "/"s;
142  topic_prefix += _mqtt_server_config.client_id;
143  auto tx = topic_prefix + "/tx"s;
144  auto rx = topic_prefix + "/rx"s;
145  std::strncpy(_mqtt_topic_config.pub_topic, tx.c_str(), MA_MQTT_MAX_TOPIC_LENGTH - 1);
146  std::strncpy(_mqtt_topic_config.sub_topic, rx.c_str(), MA_MQTT_MAX_TOPIC_LENGTH - 1);
147  }
148 
149  MA_STORAGE_SET_ASTR(
150  ret, static_resource->device->getStorage(), MA_STORAGE_KEY_MQTT_PUB_TOPIC, _mqtt_topic_config.pub_topic);
151  MA_STORAGE_SET_ASTR(
152  ret, static_resource->device->getStorage(), MA_STORAGE_KEY_MQTT_SUB_TOPIC, _mqtt_topic_config.sub_topic);
153 
154 exit:
155  encoder.begin(MA_MSG_TYPE_RESP, ret, argv[0]);
156  encoder.write(_mqtt_server_config);
157  encoder.end();
158  transport.send(reinterpret_cast<const char*>(encoder.data()), encoder.size());
159 }
160 
161 void getMqttConfig(const std::vector<std::string>& argv, Transport& transport, Encoder& encoder) {
162  ma_err_t ret = MA_OK;
163 
164  MA_STORAGE_GET_ASTR(static_resource->device->getStorage(), MA_STORAGE_KEY_MQTT_HOST, _mqtt_server_config.host, "");
165  MA_STORAGE_GET_POD(static_resource->device->getStorage(), MA_STORAGE_KEY_MQTT_PORT, _mqtt_server_config.port, 0);
166  MA_STORAGE_GET_ASTR(
167  static_resource->device->getStorage(), MA_STORAGE_KEY_MQTT_CLIENTID, _mqtt_server_config.client_id, "");
168  MA_STORAGE_GET_ASTR(
169  static_resource->device->getStorage(), MA_STORAGE_KEY_MQTT_USER, _mqtt_server_config.username, "");
170  MA_STORAGE_GET_ASTR(
171  static_resource->device->getStorage(), MA_STORAGE_KEY_MQTT_PWD, _mqtt_server_config.password, "");
172  MA_STORAGE_GET_POD(static_resource->device->getStorage(), MA_STORAGE_KEY_MQTT_SSL, _mqtt_server_config.use_ssl, 0);
173 
174  encoder.begin(MA_MSG_TYPE_RESP, ret, argv[0]);
175 #if MA_USE_EXTERNAL_WIFI_STATUS
176  _mqtt_status = (((uint8_t)_net_sta & 0xf) - 1) & 0b11;
177 #endif
178  if (std::strlen(_mqtt_server_config.host) < 1) {
179  _mqtt_status = 0;
180  }
181  encoder.write(_mqtt_server_config, (int*)&_mqtt_status);
182  encoder.end();
183  transport.send(reinterpret_cast<const char*>(encoder.data()), encoder.size());
184 }
185 
186 void configureMqttCA(const std::vector<std::string>& argv, Transport& transport, Encoder& encoder) {
187  ma_err_t ret = MA_OK;
188 
189  std::string ca_string;
190  size_t ca_hash = 0;
191 
192  if (argv.size() < 2) {
193  ret = MA_EINVAL;
194  goto exit;
195  }
196 
197  ca_string = ma::utils::base64_decode(argv[1]);
198  ca_hash = std::hash<std::string>{}(ca_string);
199 
200  MA_STORAGE_SET_STR(ret, static_resource->device->getStorage(), MA_STORAGE_KEY_MQTT_SSL_CA, ca_string);
201 
202 exit:
203  encoder.begin(MA_MSG_TYPE_RESP, ret, argv[0]);
204  encoder.write("hash", (uint64_t)ca_hash);
205  encoder.end();
206  transport.send(reinterpret_cast<const char*>(encoder.data()), encoder.size());
207 }
208 
209 void getMqttCA(const std::vector<std::string>& argv, Transport& transport, Encoder& encoder) {
210  ma_err_t ret = MA_OK;
211 
212  std::string b64ca;
213  {
214  std::string ca_string;
215  MA_STORAGE_GET_STR(static_resource->device->getStorage(), MA_STORAGE_KEY_MQTT_SSL_CA, ca_string, "");
216  int b64ca_len = ca_string.size() * 4 / 3 + 4;
217  b64ca.resize(b64ca_len + 1);
218  ma::utils::base64_encode(reinterpret_cast<const unsigned char*>(ca_string.c_str()),
219  ca_string.size(),
220  reinterpret_cast<char*>(b64ca.data()),
221  &b64ca_len);
222  b64ca[b64ca_len] = '\0';
223  }
224 
225  encoder.begin(MA_MSG_TYPE_RESP, ret, argv[0]);
226  encoder.write("ca", b64ca);
227  encoder.end();
228  transport.send(reinterpret_cast<const char*>(encoder.data()), encoder.size());
229 }
230 
231 } // namespace ma::server::callback
Definition: ma_codec_base.h:14
virtual ma_err_t end()=0
Encoder type for end.
virtual const void * data() const =0
Encoder type for get data.
virtual ma_err_t begin()=0
Encoder type for begin.
virtual ma_err_t write(const std::string &key, int8_t value)=0
Encoder type for write int8_t value.
virtual const size_t size() const =0
Encoder type for get size.
Definition: ma_transport.h:12
virtual size_t send(const char *data, size_t length) noexcept=0
#define MA_MQTT_MAX_PASSWORD_LENGTH
Definition: ma_config_internal.h:68
#define MA_MQTT_MAX_BROKER_LENGTH
Definition: ma_config_internal.h:52
#define MA_MQTT_MAX_CLIENT_ID_LENGTH
Definition: ma_config_internal.h:56
#define MA_MQTT_MAX_USERNAME_LENGTH
Definition: ma_config_internal.h:64
#define MA_MQTT_MAX_TOPIC_LENGTH
Definition: ma_config_internal.h:60
#define MA_LOGD(TAG,...)
Definition: ma_debug.h:79
#define MA_TAG
Definition: ma_debug.h:9
#define MA_STORAGE_KEY_MQTT_PWD
Definition: ma_definations.h:35
#define MA_STORAGE_KEY_MQTT_PUB_TOPIC
Definition: ma_definations.h:36
#define MA_STORAGE_KEY_MQTT_SSL_CA
Definition: ma_definations.h:41
#define MA_STORAGE_KEY_MQTT_PORT
Definition: ma_definations.h:32
#define MA_STORAGE_KEY_MQTT_SUB_TOPIC
Definition: ma_definations.h:38
#define MA_STORAGE_KEY_MQTT_CLIENTID
Definition: ma_definations.h:33
#define MA_STORAGE_KEY_MQTT_SSL
Definition: ma_definations.h:40
#define MA_STORAGE_KEY_MQTT_USER
Definition: ma_definations.h:34
#define MA_STORAGE_KEY_MQTT_HOST
Definition: ma_definations.h:31
#define MA_STORAGE_KEY_MQTT_PUB_QOS
Definition: ma_definations.h:37
#define MA_STORAGE_KEY_MQTT_SUB_QOS
Definition: ma_definations.h:39
@ MA_MSG_TYPE_RESP
Definition: ma_types.h:252
ma_err_t
Definition: ma_types.h:21
@ MA_OK
Definition: ma_types.h:23
@ MA_EINVAL
Definition: ma_types.h:28
#define MA_AT_API_VERSION
Definition: ma_version.h:8
Definition: algorithm.hpp:11
void configureMqttPubsub(const std::vector< std::string > &argv, Transport &transport, Encoder &encoder)
Definition: mqtt.hpp:44
void getMqttSta(const std::vector< std::string > &argv, Transport &transport, Encoder &encoder)
Definition: mqtt.hpp:73
void getMqttCA(const std::vector< std::string > &argv, Transport &transport, Encoder &encoder)
Definition: mqtt.hpp:209
void configureMqttServer(const std::vector< std::string > &argv, Transport &transport, Encoder &encoder)
Definition: mqtt.hpp:104
void getMqttPubsub(const std::vector< std::string > &argv, Transport &transport, Encoder &encoder)
Definition: mqtt.hpp:26
void configureMqttCA(const std::vector< std::string > &argv, Transport &transport, Encoder &encoder)
Definition: mqtt.hpp:186
void getMqttConfig(const std::vector< std::string > &argv, Transport &transport, Encoder &encoder)
Definition: mqtt.hpp:161
ma_err_t base64_encode(const unsigned char *in, int in_len, char *out, int *out_len)
Definition: ma_base64.cpp:41
std::string base64_decode(const std::string &in)
Definition: ma_base64.cpp:20
#define static_resource
Definition: resource.hpp:64
Definition: ma_types.h:314
char username[128]
Definition: ma_types.h:318
int16_t port
Definition: ma_types.h:316
int8_t use_ssl
Definition: ma_types.h:320
char client_id[128]
Definition: ma_types.h:317
char password[256]
Definition: ma_types.h:319
char host[128]
Definition: ma_types.h:315
Definition: ma_types.h:323
char sub_topic[128]
Definition: ma_types.h:325
char pub_topic[128]
Definition: ma_types.h:324
int8_t sub_qos
Definition: ma_types.h:327
int8_t pub_qos
Definition: ma_types.h:326