// Copyright (C) 2020 Timotej Šiškovič
// SPDX-License-Identifier: GPL-3.0-only
//
// This program is free software: you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the Free Software Foundation, version 3.
//
// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with this program.
// If not, see .
#ifndef MQTT_WSS_CLIENT_H
#define MQTT_WSS_CLIENT_H
#include
#include //size_t
#include "mqtt_wss_log.h"
#include "common_public.h"
// All OK call me at your earliest convinience
#define MQTT_WSS_OK 0
/* All OK, poll timeout you requested when calling mqtt_wss_service expired - you might want to know if timeout
* happened or we got some data or handle same as MQTT_WSS_OK
*/
#define MQTT_WSS_OK_TO 1
// Connection was closed by remote
#define MQTT_WSS_ERR_CONN_DROP -1
// Error in MQTT protocol (e.g. malformed packet)
#define MQTT_WSS_ERR_PROTO_MQTT -2
// Error in WebSocket protocol (e.g. malformed packet)
#define MQTT_WSS_ERR_PROTO_WS -3
#define MQTT_WSS_ERR_TX_BUF_TOO_SMALL -4
#define MQTT_WSS_ERR_RX_BUF_TOO_SMALL -5
#define MQTT_WSS_ERR_TOO_BIG_FOR_SERVER -6
// if client was initialized with MQTT 3 but MQTT 5 feature
// was requested by user of library
#define MQTT_WSS_ERR_CANT_DO -8
typedef struct mqtt_wss_client_struct *mqtt_wss_client;
typedef void (*msg_callback_fnc_t)(const char *topic, const void *msg, size_t msglen, int qos);
/* Creates new instance of MQTT over WSS. Doesn't start connection.
* @param log_prefix this is prefix to be used when logging to discern between multiple
* mqtt_wss instances. Can be NULL.
* @param log_callback is function pointer to fnc to be called when mqtt_wss wants
* to log. This allows plugging this library into your own logging system/solution.
* If NULL STDOUT/STDERR will be used.
* @param msg_callback is function pointer to function which will be called
* when application level message arrives from broker (for subscribed topics).
* Can be NULL if you are not interested about incoming messages.
* @param puback_callback is function pointer to function to be called when QOS1 Publish
* is acknowledged by server
*/
mqtt_wss_client mqtt_wss_new(const char *log_prefix,
mqtt_wss_log_callback_t log_callback,
msg_callback_fnc_t msg_callback,
void (*puback_callback)(uint16_t packet_id));
void mqtt_wss_set_max_buf_size(mqtt_wss_client client, size_t size);
void mqtt_wss_destroy(mqtt_wss_client client);
struct mqtt_connect_params;
struct mqtt_wss_proxy;
#define MQTT_WSS_SSL_CERT_CHECK_FULL 0x00
#define MQTT_WSS_SSL_ALLOW_SELF_SIGNED 0x01
#define MQTT_WSS_SSL_DONT_CHECK_CERTS 0x08
/* Will block until the MQTT over WSS connection is established or return error
* @param client mqtt_wss_client which should connect
* @param host to connect to (where MQTT over WSS server is listening)
* @param port to connect to (where MQTT over WSS server is listening)
* @param mqtt_params pointer to mqtt_connect_params structure which contains MQTT credentials and settings
* @param ssl_flags parameters for OpenSSL, 0=MQTT_WSS_SSL_CERT_CHECK_FULL
*/
int mqtt_wss_connect(mqtt_wss_client client, char *host, int port, struct mqtt_connect_params *mqtt_params, int ssl_flags, struct mqtt_wss_proxy *proxy);
int mqtt_wss_service(mqtt_wss_client client, int timeout_ms);
void mqtt_wss_disconnect(mqtt_wss_client client, int timeout_ms);
// we redefine this instead of using MQTT-C flags as in future
// we want to support different MQTT implementations if needed
enum mqtt_wss_publish_flags {
MQTT_WSS_PUB_QOS0 = 0x0,
MQTT_WSS_PUB_QOS1 = 0x1,
MQTT_WSS_PUB_QOS2 = 0x2,
MQTT_WSS_PUB_QOSMASK = 0x3,
MQTT_WSS_PUB_RETAIN = 0x4
};
struct mqtt_connect_params {
const char *clientid;
const char *username;
const char *password;
const char *will_topic;
const void *will_msg;
enum mqtt_wss_publish_flags will_flags;
size_t will_msg_len;
int keep_alive;
int drop_on_publish_fail;
};
enum mqtt_wss_proxy_type {
MQTT_WSS_DIRECT = 0,
MQTT_WSS_PROXY_HTTP
};
struct mqtt_wss_proxy {
enum mqtt_wss_proxy_type type;
const char *host;
int port;
const char *username;
const char *password;
};
/* TODO!!! update the description
* Publishes MQTT message and gets message id
* @param client mqtt_wss_client which should transfer the message
* @param topic MQTT topic to publish message to (0 terminated C string)
* @param msg Message to be published (no need for 0 termination)
* @param msg_len Length of the message to be published
* @param publish_flags see enum mqtt_wss_publish_flags e.g. (MQTT_WSS_PUB_QOS1 | MQTT_WSS_PUB_RETAIN)
* @param packet_id is 16 bit unsigned int representing ID that can be used to pair with PUBACK callback
* for usages where application layer wants to know which messages are delivered when
* @return Returns 0 on success
*/
int mqtt_wss_publish5(mqtt_wss_client client,
char *topic,
free_fnc_t topic_free,
void *msg,
free_fnc_t msg_free,
size_t msg_len,
uint8_t publish_flags,
uint16_t *packet_id);
int mqtt_wss_set_topic_alias(mqtt_wss_client client, const char *topic);
/* Subscribes to MQTT topic
* @param client mqtt_wss_client which should do the subscription
* @param topic MQTT topic to subscribe to
* @param max_qos_level maximum QOS level that broker can send to us on this subscription
* @return Returns 0 on success
*/
int mqtt_wss_subscribe(mqtt_wss_client client, char *topic, int max_qos_level);
struct mqtt_wss_stats {
uint64_t bytes_tx;
uint64_t bytes_rx;
#ifdef MQTT_WSS_CPUSTATS
uint64_t time_keepalive;
uint64_t time_read_socket;
uint64_t time_write_socket;
uint64_t time_process_websocket;
uint64_t time_process_mqtt;
#endif
struct mqtt_ng_stats mqtt;
};
struct mqtt_wss_stats mqtt_wss_get_stats(mqtt_wss_client client);
#ifdef MQTT_WSS_DEBUG
#include
void mqtt_wss_set_SSL_CTX_keylog_cb(mqtt_wss_client client, void (*ssl_ctx_keylog_cb)(const SSL *ssl, const char *line));
#endif
#endif /* MQTT_WSS_CLIENT_H */