/*
 * @Author: zhy
 * @Date: 2022-09-09 18:25:41
 * @LastEditors: zhanghongyang zhanghy@bmser.com
 * @LastEditTime: 2023-10-31 13:05:38
 * @Description: 
 */
#ifndef BMSER_MQTT_H
#define BMSER_MQTT_H
#include "mosquitto.h"

#ifdef __cplusplus
extern "C" {
#endif

#define MQTT_TOPIC_MAX_LEN		256
#define MQTT_CONNECT_PORT 		1883
#define MQTT_KEEP_ALIVE 		60
#define MQTT_QOS_LEVEL			2	// 默认的qos等级，注意不要删除，老代码会编不过
#define MQTT_QOS_LEVEL2			2
#define MQTT_QOS_LEVEL1			1
#define MQTT_QOS_LEVEL0			0

typedef int (*BMSER_MOSQ_MQTT_RECV_MSG_CB)(void* userdata, const struct mosquitto_message* message);
typedef int (*BMSER_MOSQ_MQTT_CONN_STATUS_CB)(int result);

#pragma pack(1)
typedef struct {
	BMSER_MOSQ_MQTT_RECV_MSG_CB recv_msg_cb;
	BMSER_MOSQ_MQTT_CONN_STATUS_CB recv_conn_status_cb;
} BMSER_MOSQ_MQTT_MSG_CB_MGR_S;
#pragma pack()

typedef int (*BMSER_MOSQ_MQTT_RECV_MSG_CB_NEW)(struct mosquitto* mosq, void* userdata, const struct mosquitto_message* message);
typedef int (*BMSER_MOSQ_MQTT_CONN_STATUS_CB_NEW)(struct mosquitto* mosq, int result);

#pragma pack(1)
typedef struct {
	BMSER_MOSQ_MQTT_RECV_MSG_CB_NEW recv_msg_cb;
	BMSER_MOSQ_MQTT_CONN_STATUS_CB_NEW recv_conn_status_cb;
} BMSER_MOSQ_MQTT_MSG_CB_MGR_NEW_S;
#pragma pack()


/**
 * @description: 创建mqtt会话 
 * @param {char*} id
 * @param {char*} ip
 * @param {int} port
 * @param {BMSER_MOSQ_MQTT_RECV_MSG_CB} msg_recv_cb
 * @return {*} 非空句柄:success, NULL:fail.
 */
struct mosquitto* bmser_mqtt_session_create(const char* id, const char* ip, int port, BMSER_MOSQ_MQTT_RECV_MSG_CB msg_recv_cb, BMSER_MOSQ_MQTT_CONN_STATUS_CB msg_conn_cb);

/**
 * @description: 创建mqtt会话新 新接口修改了传参方式，将回调函数封装成结构体传入，且回调函数中增加mosquitto句柄，可以通过回调函数知道是哪个连接
 * @param {char*} id
 * @param {char*} ip
 * @param {int} port
 * @param {BMSER_MOSQ_MQTT_MSG_CB_MGR_NEW_S} mgr_cb
 * @return {*} 非空句柄:success, NULL:fail.
 */
struct mosquitto* bmser_mqtt_session_create_new(const char* id, const char* ip, int port, BMSER_MOSQ_MQTT_MSG_CB_MGR_NEW_S *mgr_cb);

/**
 * @description: 停止mqtt会话
 * @return {*} 0:success, others:fail.
 */
int bmser_mqtt_session_stop(struct mosquitto* mosq);

/**
 * @description: 订阅mqtt topic
 * @param {char*} topic
 * @return {*} 0:success, others:fail.(注意错误返回值可能大于0)
 */
int bmser_mqtt_session_subscribe(struct mosquitto* mosq, const char* topic);

/**
 * @description: 发布mqtt消息，新业务使用bmser_mqtt_session_publish_raw_new接口
 * @param {mosquitto*} mosq
 * @param {char*} topic: MQTT主题
 * @param {void*} payload: MQTT payload
 * @param {int} len: MQTT payload 长度
 * @return {*} 0:success, others:fail. (注意错误返回值可能大于0)
 */
int bmser_mqtt_session_publish_raw(struct mosquitto* mosq, const char* topic, const void* payload, int len);

/**
 * @description: 发布mqtt消息，新业务使用此接口，替换bmser_mqtt_session_publish_raw接口，增加了QOS级别和retain传参
 * @param {mosquitto*} mosq
 * @param {char*} topic: MQTT主题
 * @param {void*} payload: MQTT payload
 * @param {int} len: MQTT payload 长度
 * @param {int} qos: MQTT QOS
 * @param {bool} retain: 服务器是否保留此消息，当前业务默认传false
 * @return {*} 0:success, others:fail. (注意错误返回值可能大于0)
 */
int bmser_mqtt_session_publish_raw_new(struct mosquitto* mosq, const char* topic, const void* payload, int len, int qos, bool retain);

/**
 * @description: mqtt会话重连
 * @param {mosquitto*} mosq
 * @return {*} 0:success, others:fail.(注意错误返回值可能大于0)
 */
int bmser_mqtt_session_reconnect(struct mosquitto* mosq);

#ifdef __cplusplus
}
#endif

#endif