1 /*
2 Copyright (c) 2010-2019 Roger Light <roger@atchoo.org>
3 
4 All rights reserved. This program and the accompanying materials
5 are made available under the terms of the Eclipse Public License 2.0
6 and Eclipse Distribution License v1.0 which accompany this distribution.
7 
8 The Eclipse Public License is available at
9    https://www.eclipse.org/legal/epl-2.0/
10 and the Eclipse Distribution License is available at
11   http://www.eclipse.org/org/documents/edl-v10.php.
12 
13 Contributors:
14    Roger Light - initial implementation and documentation.
15 */
16 
17 #include <cstdlib>
18 #include <mosquitto.h>
19 #include <mosquittopp.h>
20 
21 #define UNUSED(A) (void)(A)
22 
23 namespace mosqpp {
24 
on_connect_wrapper(struct mosquitto * mosq,void * userdata,int rc)25 static void on_connect_wrapper(struct mosquitto *mosq, void *userdata, int rc)
26 {
27 	class mosquittopp *m = (class mosquittopp *)userdata;
28 
29 	UNUSED(mosq);
30 
31 	m->on_connect(rc);
32 }
33 
on_connect_with_flags_wrapper(struct mosquitto * mosq,void * userdata,int rc,int flags)34 static void on_connect_with_flags_wrapper(struct mosquitto *mosq, void *userdata, int rc, int flags)
35 {
36 	class mosquittopp *m = (class mosquittopp *)userdata;
37 	UNUSED(mosq);
38 	m->on_connect_with_flags(rc, flags);
39 }
40 
on_disconnect_wrapper(struct mosquitto * mosq,void * userdata,int rc)41 static void on_disconnect_wrapper(struct mosquitto *mosq, void *userdata, int rc)
42 {
43 	class mosquittopp *m = (class mosquittopp *)userdata;
44 	UNUSED(mosq);
45 	m->on_disconnect(rc);
46 }
47 
on_publish_wrapper(struct mosquitto * mosq,void * userdata,int mid)48 static void on_publish_wrapper(struct mosquitto *mosq, void *userdata, int mid)
49 {
50 	class mosquittopp *m = (class mosquittopp *)userdata;
51 	UNUSED(mosq);
52 	m->on_publish(mid);
53 }
54 
on_message_wrapper(struct mosquitto * mosq,void * userdata,const struct mosquitto_message * message)55 static void on_message_wrapper(struct mosquitto *mosq, void *userdata, const struct mosquitto_message *message)
56 {
57 	class mosquittopp *m = (class mosquittopp *)userdata;
58 	UNUSED(mosq);
59 	m->on_message(message);
60 }
61 
on_subscribe_wrapper(struct mosquitto * mosq,void * userdata,int mid,int qos_count,const int * granted_qos)62 static void on_subscribe_wrapper(struct mosquitto *mosq, void *userdata, int mid, int qos_count, const int *granted_qos)
63 {
64 	class mosquittopp *m = (class mosquittopp *)userdata;
65 	UNUSED(mosq);
66 	m->on_subscribe(mid, qos_count, granted_qos);
67 }
68 
on_unsubscribe_wrapper(struct mosquitto * mosq,void * userdata,int mid)69 static void on_unsubscribe_wrapper(struct mosquitto *mosq, void *userdata, int mid)
70 {
71 	class mosquittopp *m = (class mosquittopp *)userdata;
72 	UNUSED(mosq);
73 	m->on_unsubscribe(mid);
74 }
75 
76 
on_log_wrapper(struct mosquitto * mosq,void * userdata,int level,const char * str)77 static void on_log_wrapper(struct mosquitto *mosq, void *userdata, int level, const char *str)
78 {
79 	class mosquittopp *m = (class mosquittopp *)userdata;
80 	UNUSED(mosq);
81 	m->on_log(level, str);
82 }
83 
lib_version(int * major,int * minor,int * revision)84 int lib_version(int *major, int *minor, int *revision)
85 {
86 	if(major) *major = LIBMOSQUITTO_MAJOR;
87 	if(minor) *minor = LIBMOSQUITTO_MINOR;
88 	if(revision) *revision = LIBMOSQUITTO_REVISION;
89 	return LIBMOSQUITTO_VERSION_NUMBER;
90 }
91 
lib_init()92 int lib_init()
93 {
94 	return mosquitto_lib_init();
95 }
96 
lib_cleanup()97 int lib_cleanup()
98 {
99 	return mosquitto_lib_cleanup();
100 }
101 
strerror(int mosq_errno)102 const char* strerror(int mosq_errno)
103 {
104 	return mosquitto_strerror(mosq_errno);
105 }
106 
connack_string(int connack_code)107 const char* connack_string(int connack_code)
108 {
109 	return mosquitto_connack_string(connack_code);
110 }
111 
sub_topic_tokenise(const char * subtopic,char *** topics,int * count)112 int sub_topic_tokenise(const char *subtopic, char ***topics, int *count)
113 {
114 	return mosquitto_sub_topic_tokenise(subtopic, topics, count);
115 }
116 
sub_topic_tokens_free(char *** topics,int count)117 int sub_topic_tokens_free(char ***topics, int count)
118 {
119 	return mosquitto_sub_topic_tokens_free(topics, count);
120 }
121 
topic_matches_sub(const char * sub,const char * topic,bool * result)122 int topic_matches_sub(const char *sub, const char *topic, bool *result)
123 {
124 	return mosquitto_topic_matches_sub(sub, topic, result);
125 }
126 
validate_utf8(const char * str,int len)127 int validate_utf8(const char *str, int len)
128 {
129 	return mosquitto_validate_utf8(str, len);
130 }
131 
subscribe_simple(struct mosquitto_message ** messages,int msg_count,bool retained,const char * topic,int qos,const char * host,int port,const char * client_id,int keepalive,bool clean_session,const char * username,const char * password,const struct libmosquitto_will * will,const struct libmosquitto_tls * tls)132 int subscribe_simple(
133 		struct mosquitto_message **messages,
134 		int msg_count,
135 		bool retained,
136 		const char *topic,
137 		int qos,
138 		const char *host,
139 		int port,
140 		const char *client_id,
141 		int keepalive,
142 		bool clean_session,
143 		const char *username,
144 		const char *password,
145 		const struct libmosquitto_will *will,
146 		const struct libmosquitto_tls *tls)
147 {
148 	return mosquitto_subscribe_simple(
149 			messages, msg_count, retained,
150 			topic, qos,
151 			host, port, client_id, keepalive, clean_session,
152 			username, password,
153 			will, tls);
154 }
155 
subscribe_callback(int (* callback)(struct mosquitto *,void *,const struct mosquitto_message *),void * userdata,const char * topic,int qos,const char * host,int port,const char * client_id,int keepalive,bool clean_session,const char * username,const char * password,const struct libmosquitto_will * will,const struct libmosquitto_tls * tls)156 mosqpp_EXPORT int subscribe_callback(
157 		int (*callback)(struct mosquitto *, void *, const struct mosquitto_message *),
158 		void *userdata,
159 		const char *topic,
160 		int qos,
161 		const char *host,
162 		int port,
163 		const char *client_id,
164 		int keepalive,
165 		bool clean_session,
166 		const char *username,
167 		const char *password,
168 		const struct libmosquitto_will *will,
169 		const struct libmosquitto_tls *tls)
170 {
171 	return mosquitto_subscribe_callback(
172 			callback, userdata,
173 			topic, qos,
174 			host, port, client_id, keepalive, clean_session,
175 			username, password,
176 			will, tls);
177 }
178 
179 
mosquittopp(const char * id,bool clean_session)180 mosquittopp::mosquittopp(const char *id, bool clean_session)
181 {
182 	m_mosq = mosquitto_new(id, clean_session, this);
183 	mosquitto_connect_callback_set(m_mosq, on_connect_wrapper);
184 	mosquitto_connect_with_flags_callback_set(m_mosq, on_connect_with_flags_wrapper);
185 	mosquitto_disconnect_callback_set(m_mosq, on_disconnect_wrapper);
186 	mosquitto_publish_callback_set(m_mosq, on_publish_wrapper);
187 	mosquitto_message_callback_set(m_mosq, on_message_wrapper);
188 	mosquitto_subscribe_callback_set(m_mosq, on_subscribe_wrapper);
189 	mosquitto_unsubscribe_callback_set(m_mosq, on_unsubscribe_wrapper);
190 	mosquitto_log_callback_set(m_mosq, on_log_wrapper);
191 }
192 
~mosquittopp()193 mosquittopp::~mosquittopp()
194 {
195 	mosquitto_destroy(m_mosq);
196 }
197 
reinitialise(const char * id,bool clean_session)198 int mosquittopp::reinitialise(const char *id, bool clean_session)
199 {
200 	int rc;
201 	rc = mosquitto_reinitialise(m_mosq, id, clean_session, this);
202 	if(rc == MOSQ_ERR_SUCCESS){
203 		mosquitto_connect_callback_set(m_mosq, on_connect_wrapper);
204 		mosquitto_connect_with_flags_callback_set(m_mosq, on_connect_with_flags_wrapper);
205 		mosquitto_disconnect_callback_set(m_mosq, on_disconnect_wrapper);
206 		mosquitto_publish_callback_set(m_mosq, on_publish_wrapper);
207 		mosquitto_message_callback_set(m_mosq, on_message_wrapper);
208 		mosquitto_subscribe_callback_set(m_mosq, on_subscribe_wrapper);
209 		mosquitto_unsubscribe_callback_set(m_mosq, on_unsubscribe_wrapper);
210 		mosquitto_log_callback_set(m_mosq, on_log_wrapper);
211 	}
212 	return rc;
213 }
214 
connect(const char * host,int port,int keepalive)215 int mosquittopp::connect(const char *host, int port, int keepalive)
216 {
217 	return mosquitto_connect(m_mosq, host, port, keepalive);
218 }
219 
connect(const char * host,int port,int keepalive,const char * bind_address)220 int mosquittopp::connect(const char *host, int port, int keepalive, const char *bind_address)
221 {
222 	return mosquitto_connect_bind(m_mosq, host, port, keepalive, bind_address);
223 }
224 
connect_async(const char * host,int port,int keepalive)225 int mosquittopp::connect_async(const char *host, int port, int keepalive)
226 {
227 	return mosquitto_connect_async(m_mosq, host, port, keepalive);
228 }
229 
connect_async(const char * host,int port,int keepalive,const char * bind_address)230 int mosquittopp::connect_async(const char *host, int port, int keepalive, const char *bind_address)
231 {
232 	return mosquitto_connect_bind_async(m_mosq, host, port, keepalive, bind_address);
233 }
234 
reconnect()235 int mosquittopp::reconnect()
236 {
237 	return mosquitto_reconnect(m_mosq);
238 }
239 
reconnect_async()240 int mosquittopp::reconnect_async()
241 {
242 	return mosquitto_reconnect_async(m_mosq);
243 }
244 
disconnect()245 int mosquittopp::disconnect()
246 {
247 	return mosquitto_disconnect(m_mosq);
248 }
249 
socket()250 int mosquittopp::socket()
251 {
252 	return mosquitto_socket(m_mosq);
253 }
254 
will_set(const char * topic,int payloadlen,const void * payload,int qos,bool retain)255 int mosquittopp::will_set(const char *topic, int payloadlen, const void *payload, int qos, bool retain)
256 {
257 	return mosquitto_will_set(m_mosq, topic, payloadlen, payload, qos, retain);
258 }
259 
will_clear()260 int mosquittopp::will_clear()
261 {
262 	return mosquitto_will_clear(m_mosq);
263 }
264 
username_pw_set(const char * username,const char * password)265 int mosquittopp::username_pw_set(const char *username, const char *password)
266 {
267 	return mosquitto_username_pw_set(m_mosq, username, password);
268 }
269 
publish(int * mid,const char * topic,int payloadlen,const void * payload,int qos,bool retain)270 int mosquittopp::publish(int *mid, const char *topic, int payloadlen, const void *payload, int qos, bool retain)
271 {
272 	return mosquitto_publish(m_mosq, mid, topic, payloadlen, payload, qos, retain);
273 }
274 
reconnect_delay_set(unsigned int reconnect_delay,unsigned int reconnect_delay_max,bool reconnect_exponential_backoff)275 void mosquittopp::reconnect_delay_set(unsigned int reconnect_delay, unsigned int reconnect_delay_max, bool reconnect_exponential_backoff)
276 {
277 	mosquitto_reconnect_delay_set(m_mosq, reconnect_delay, reconnect_delay_max, reconnect_exponential_backoff);
278 }
279 
max_inflight_messages_set(unsigned int max_inflight_messages)280 int mosquittopp::max_inflight_messages_set(unsigned int max_inflight_messages)
281 {
282 	return mosquitto_max_inflight_messages_set(m_mosq, max_inflight_messages);
283 }
284 
message_retry_set(unsigned int message_retry)285 void mosquittopp::message_retry_set(unsigned int message_retry)
286 {
287 	mosquitto_message_retry_set(m_mosq, message_retry);
288 }
289 
subscribe(int * mid,const char * sub,int qos)290 int mosquittopp::subscribe(int *mid, const char *sub, int qos)
291 {
292 	return mosquitto_subscribe(m_mosq, mid, sub, qos);
293 }
294 
unsubscribe(int * mid,const char * sub)295 int mosquittopp::unsubscribe(int *mid, const char *sub)
296 {
297 	return mosquitto_unsubscribe(m_mosq, mid, sub);
298 }
299 
loop(int timeout,int max_packets)300 int mosquittopp::loop(int timeout, int max_packets)
301 {
302 	return mosquitto_loop(m_mosq, timeout, max_packets);
303 }
304 
loop_misc()305 int mosquittopp::loop_misc()
306 {
307 	return mosquitto_loop_misc(m_mosq);
308 }
309 
loop_read(int max_packets)310 int mosquittopp::loop_read(int max_packets)
311 {
312 	return mosquitto_loop_read(m_mosq, max_packets);
313 }
314 
loop_write(int max_packets)315 int mosquittopp::loop_write(int max_packets)
316 {
317 	return mosquitto_loop_write(m_mosq, max_packets);
318 }
319 
loop_forever(int timeout,int max_packets)320 int mosquittopp::loop_forever(int timeout, int max_packets)
321 {
322 	return mosquitto_loop_forever(m_mosq, timeout, max_packets);
323 }
324 
loop_start()325 int mosquittopp::loop_start()
326 {
327 	return mosquitto_loop_start(m_mosq);
328 }
329 
loop_stop(bool force)330 int mosquittopp::loop_stop(bool force)
331 {
332 	return mosquitto_loop_stop(m_mosq, force);
333 }
334 
want_write()335 bool mosquittopp::want_write()
336 {
337 	return mosquitto_want_write(m_mosq);
338 }
339 
opts_set(enum mosq_opt_t option,void * value)340 int mosquittopp::opts_set(enum mosq_opt_t option, void *value)
341 {
342 	return mosquitto_opts_set(m_mosq, option, value);
343 }
344 
threaded_set(bool threaded)345 int mosquittopp::threaded_set(bool threaded)
346 {
347 	return mosquitto_threaded_set(m_mosq, threaded);
348 }
349 
user_data_set(void * userdata)350 void mosquittopp::user_data_set(void *userdata)
351 {
352 	mosquitto_user_data_set(m_mosq, userdata);
353 }
354 
socks5_set(const char * host,int port,const char * username,const char * password)355 int mosquittopp::socks5_set(const char *host, int port, const char *username, const char *password)
356 {
357 	return mosquitto_socks5_set(m_mosq, host, port, username, password);
358 }
359 
360 
tls_set(const char * cafile,const char * capath,const char * certfile,const char * keyfile,int (* pw_callback)(char * buf,int size,int rwflag,void * userdata))361 int mosquittopp::tls_set(const char *cafile, const char *capath, const char *certfile, const char *keyfile, int (*pw_callback)(char *buf, int size, int rwflag, void *userdata))
362 {
363 	return mosquitto_tls_set(m_mosq, cafile, capath, certfile, keyfile, pw_callback);
364 }
365 
tls_opts_set(int cert_reqs,const char * tls_version,const char * ciphers)366 int mosquittopp::tls_opts_set(int cert_reqs, const char *tls_version, const char *ciphers)
367 {
368 	return mosquitto_tls_opts_set(m_mosq, cert_reqs, tls_version, ciphers);
369 }
370 
tls_insecure_set(bool value)371 int mosquittopp::tls_insecure_set(bool value)
372 {
373 	return mosquitto_tls_insecure_set(m_mosq, value);
374 }
375 
tls_psk_set(const char * psk,const char * identity,const char * ciphers)376 int mosquittopp::tls_psk_set(const char *psk, const char *identity, const char *ciphers)
377 {
378 	return mosquitto_tls_psk_set(m_mosq, psk, identity, ciphers);
379 }
380 
381 }
382