mosquitto/lib/helpers.c

220 lines
4.9 KiB
C
Raw Normal View History

2016-01-26 09:26:17 +00:00
/*
Copyright (c) 2016-2020 Roger Light <roger@atchoo.org>
2016-01-26 09:26:17 +00:00
All rights reserved. This program and the accompanying materials
2020-11-25 17:34:21 +00:00
are made available under the terms of the Eclipse Public License 2.0
2016-01-26 09:26:17 +00:00
and Eclipse Distribution License v1.0 which accompany this distribution.
The Eclipse Public License is available at
2020-11-25 17:34:21 +00:00
https://www.eclipse.org/legal/epl-2.0/
2016-01-26 09:26:17 +00:00
and the Eclipse Distribution License is available at
http://www.eclipse.org/org/documents/edl-v10.php.
SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
2020-12-01 18:21:59 +00:00
2016-01-26 09:26:17 +00:00
Contributors:
Roger Light - initial implementation and documentation.
*/
#include "config.h"
2016-01-26 09:26:17 +00:00
#include <errno.h>
#include <stdbool.h>
#include "mosquitto.h"
#include "mosquitto_internal.h"
2016-01-26 17:00:08 +00:00
struct userdata__callback {
2016-01-26 09:26:17 +00:00
const char *topic;
2016-01-26 17:00:08 +00:00
int (*callback)(struct mosquitto *, void *, const struct mosquitto_message *);
void *userdata;
int qos;
};
struct userdata__simple {
2016-01-26 09:26:17 +00:00
struct mosquitto_message *messages;
int max_msg_count;
int message_count;
2016-01-26 17:10:54 +00:00
bool want_retained;
2016-01-26 09:26:17 +00:00
};
2016-01-26 17:00:08 +00:00
static void on_connect(struct mosquitto *mosq, void *obj, int rc)
2016-01-26 09:26:17 +00:00
{
2016-01-26 17:00:08 +00:00
struct userdata__callback *userdata = obj;
2016-01-26 09:26:17 +00:00
2019-03-13 14:11:50 +00:00
UNUSED(rc);
2016-01-26 09:26:17 +00:00
mosquitto_subscribe(mosq, NULL, userdata->topic, userdata->qos);
}
2016-01-26 17:00:08 +00:00
static void on_message_callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message)
2016-01-26 09:26:17 +00:00
{
2016-01-26 17:00:08 +00:00
int rc;
struct userdata__callback *userdata = obj;
rc = userdata->callback(mosq, userdata->userdata, message);
if(rc){
mosquitto_disconnect(mosq);
}
}
static int on_message_simple(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message)
{
struct userdata__simple *userdata = obj;
2016-01-26 09:26:17 +00:00
int rc;
if(userdata->max_msg_count == 0){
2016-01-26 17:00:08 +00:00
return 0;
2016-01-26 09:26:17 +00:00
}
2016-01-26 17:10:54 +00:00
/* Don't process stale retained messages if 'want_retained' was false */
if(!userdata->want_retained && message->retain){
2016-01-26 17:00:08 +00:00
return 0;
2016-01-26 09:26:17 +00:00
}
userdata->max_msg_count--;
rc = mosquitto_message_copy(&userdata->messages[userdata->message_count], message);
if(rc){
2016-01-26 17:00:08 +00:00
return rc;
}
2016-01-26 09:26:17 +00:00
userdata->message_count++;
if(userdata->max_msg_count == 0){
mosquitto_disconnect(mosq);
}
2016-01-26 17:00:08 +00:00
return 0;
2016-01-26 09:26:17 +00:00
}
libmosq_EXPORT int mosquitto_subscribe_simple(
struct mosquitto_message **messages,
int msg_count,
2016-01-26 17:10:54 +00:00
bool want_retained,
2016-01-26 09:26:17 +00:00
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)
{
2016-01-26 17:00:08 +00:00
struct userdata__simple userdata;
2016-01-26 09:26:17 +00:00
int rc;
int i;
2016-01-26 09:26:17 +00:00
if(!topic || msg_count < 1 || !messages){
return MOSQ_ERR_INVAL;
}
*messages = NULL;
2020-10-17 00:23:08 +00:00
userdata.messages = calloc(sizeof(struct mosquitto_message), (size_t)msg_count);
2016-01-26 09:26:17 +00:00
if(!userdata.messages){
return MOSQ_ERR_NOMEM;
}
userdata.message_count = 0;
2016-01-26 17:00:08 +00:00
userdata.max_msg_count = msg_count;
2016-01-26 17:10:54 +00:00
userdata.want_retained = want_retained;
2016-01-26 09:26:17 +00:00
rc = mosquitto_subscribe_callback(
on_message_simple, &userdata,
2016-01-26 17:00:08 +00:00
topic, qos,
host, port,
client_id, keepalive, clean_session,
username, password,
will, tls);
if(!rc && userdata.max_msg_count == 0){
*messages = userdata.messages;
return MOSQ_ERR_SUCCESS;
}else{
for(i=0; i<msg_count; i++){
mosquitto_message_free_contents(&userdata.messages[i]);
}
2016-01-26 09:26:17 +00:00
free(userdata.messages);
userdata.messages = NULL;
2016-01-26 17:00:08 +00:00
return rc;
}
}
2016-01-26 17:00:08 +00:00
libmosq_EXPORT int mosquitto_subscribe_callback(
int (*callback)(struct mosquitto *, void *, const struct mosquitto_message *),
void *userdata,
2016-01-26 17:00:08 +00:00
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)
{
struct mosquitto *mosq;
struct userdata__callback cb_userdata;
int rc;
if(!callback || !topic){
return MOSQ_ERR_INVAL;
}
cb_userdata.topic = topic;
cb_userdata.qos = qos;
cb_userdata.userdata = userdata;
cb_userdata.callback = callback;
mosq = mosquitto_new(client_id, clean_session, &cb_userdata);
if(!mosq){
2016-01-26 09:26:17 +00:00
return MOSQ_ERR_NOMEM;
}
if(will){
rc = mosquitto_will_set(mosq, will->topic, will->payloadlen, will->payload, will->qos, will->retain);
if(rc){
mosquitto_destroy(mosq);
return rc;
}
}
if(username){
rc = mosquitto_username_pw_set(mosq, username, password);
if(rc){
mosquitto_destroy(mosq);
return rc;
}
}
if(tls){
rc = mosquitto_tls_set(mosq, tls->cafile, tls->capath, tls->certfile, tls->keyfile, tls->pw_callback);
if(rc){
mosquitto_destroy(mosq);
return rc;
}
rc = mosquitto_tls_opts_set(mosq, tls->cert_reqs, tls->tls_version, tls->ciphers);
if(rc){
mosquitto_destroy(mosq);
return rc;
}
}
mosquitto_connect_callback_set(mosq, on_connect);
2016-01-26 17:00:08 +00:00
mosquitto_message_callback_set(mosq, on_message_callback);
2016-01-26 09:26:17 +00:00
rc = mosquitto_connect(mosq, host, port, keepalive);
if(rc){
mosquitto_destroy(mosq);
return rc;
}
rc = mosquitto_loop_forever(mosq, -1, 1);
mosquitto_destroy(mosq);
2020-01-23 10:55:49 +00:00
return rc;
2016-01-26 09:26:17 +00:00
}