/**
 *@file sr_net_mqtt.h
 *@brief MQTT协议抽象接口
 *@details 提供MQTT协议相关枚举、结构体、API声明
 *@copyright Copyright (c) 2024 lierda. All rights reserved.
 *@author Lierda-RDC
 *@date 2024-04-01
 *@example ZhaoyangSDK\example\component\net_mqtt_example.c
 */


#ifndef _SR_NET_MQTT_H
#define _SR_NET_MQTT_H


#include <sr_net_adapter.h>

#define MQTT_TOPIC_MAX_LEN    128       /*!<MQTT主题最大缓存长度*/
#define MQTT_PAYLOAD_MAX_LEN  256       /*!<MQTT PAYLOAD最大缓存长度*/
#define MQTT_MAX_PACKET_ID    65535     /*!<MQTT最大报文ID*/

#define SUB_FAIL              0x80      /*!<MQTT 订阅订阅失败响应码*/

/*!<MQTTC结构体别名*/
typedef struct SR_MQTT_CLIENT  SR_MQTT_CLIENT_T;


/*!<MQTT 消息质量*/
typedef enum QoS 
{ 
	QOS0 = 0u, 
	QOS1 = 1u, 
	QOS2 = 2u, 
	
}SR_MQTT_QOS_E;




#define MQTT_CONNECT_DATA_INIT     {SR_NULL,SR_NULL,SR_NULL,60,1,0,SR_NULL,SR_NULL,0,0}

/*!<MQTT CONNECT默认链接参数*/
#define SR_MQTT_CONNECT_DATA_INIT  MQTT_CONNECT_DATA_INIT
 

/*!<MQTT CONNECT连接参数结构体*/
typedef struct SR_MQTT_CONN_PARAMS
{
  char *clientID;             /*!<*client id */        
  char *username;             /*!<*账户名*/  
  char *password;             /*!<*密码*/         
  unsigned short keepAlive;   /*!<*保活时间 */  
  unsigned char cleansession; /*!<*清除会话标识 */        
  unsigned char willFlag;     /*!<*遗嘱启用标识 */      
  char * willTopic;           /*!<*遗嘱主题 */   
  char *willMessage;          /*!<*遗嘱消息 */ 
  unsigned char willRetained;           
  unsigned char willQos;      /*!<*遗嘱消息质量 */           

} SR_MQTT_CONN_PARAMS_T;


/**  
* @brief MQTT初始化参数结构体
*/
typedef struct SR_MQTT_INIT_PARAMS
{
    char *serverIP;       /*!<服务器地址*/
    uint16_t serverPort;  /*!<服务器端口*/

#if  0
	SR_MQTT_CONN_PARAMS_T ConnParams;

    
	uint32_t sendBufSize;   //发送buf大小
	uint32_t recvBufSize;    //接收buf大小
	void (*online_callback)(SR_MQTT_CLIENT_T *mqttc);   //mqtt连接成功通知回调
    void (*offline_callback)(SR_MQTT_CLIENT_T *mqttc);  //mqtt离线通知回调
	//void (*default_message_handlers) (SR_MQTT_CLIENT_T *, message_data *);   //mqtt PUBLISH报文默认的接收回调
	
	uint16_t connectTimeout;    //连接超时时间
	uint16_t reconnectTimeout;  //重连超时
	uint16_t keepliveTime;      //keeplive时间 *
	uint16_t keepliveCount;     //keeplive重试次数
	uint16_t messageTimeout;    //消息超时，对SUBSCRIBE/UNSUBSCRIBE/PUBLISH报文起作用
#endif
	
}SR_MQTT_INIT_PARAMS_T;


/**  
* @brief MQTTC 底层操作函数结构体
*/
typedef struct SR_MQTTC_OPS
{
  int (*mqttc_init)(SR_MQTT_CLIENT_T *mqttc,SR_MQTT_INIT_PARAMS_T *initParams);
	int (*mqttc_deinit)(SR_MQTT_CLIENT_T *mqttc);
	int (*mqttc_connect)(SR_MQTT_CLIENT_T *mqttc,SR_MQTT_CONN_PARAMS_T *connParams);
	int (*mqttc_disconnect)(SR_MQTT_CLIENT_T *mqttc);	
	int (*mqttc_publish)(SR_MQTT_CLIENT_T *mqttc, SR_MQTT_QOS_E qos,char *topic, char *msg,uint16_t msgLen);
	int (*mqttc_subscribe)(SR_MQTT_CLIENT_T *mqttc, char *topic,SR_MQTT_QOS_E qos);
	int (*mqttc_unsubscribe)(SR_MQTT_CLIENT_T *mqttc, char *topic);
    //int (*mqttc_isconnect)(SR_MQTT_CLIENT_T *mqttc);
}SR_MQTTC_OPS_T;

/**  
* @brief MQTT消息类型枚举
*/
typedef enum SR_MQTT_MSG_TYPE
{
  SR_MQTT_MSG_TYPE_CONNACK = 0,   
  SR_MQTT_MSG_TYPE_SUBACK,
  SR_MQTT_MSG_TYPE_UNSUBACK,
  SR_MQTT_MSG_TYPE_PUBLISH,

  SR_MQTT_MSG_TYPE_UNKNOW = 0xFF,
  
}SR_MQTT_MSG_TYPE_E;


/**  
* @brief MQTT消息结构体
*/
typedef struct SR_MQTT_MSG 
{
  SR_MQTT_MSG_TYPE_E msgType;  /*!<mqtt消息的报文类型*/  
  const uint8_t *topic;   		 /*!<主题*/   
  const uint8_t *payload; 		 /*!<数据*/     
  uint16_t topicLen;      		 /*!<主题长度*/
  uint16_t payloadLen;    		 /*!<数据长度*/   
  uint16_t packetId;      		 /*!<报文ID*/          		
}SR_MQTT_MSG_T;


#if 0
/**  
* @brief MQTT PUBLISH报文解析
*/
typedef struct mqttPubParse
{
  char topic[128];
  char payload[512];
  uint16_t topicLen;
  uint16_t payloadLen; 
  uint16_t packetId;                      		
}mqttPubParse_t;
#endif



/**  
* @brief mqtt事件类型
*/
typedef enum
{
  SR_MQTT_EVENT_CONN_OK = 0,  /*!< 平台连接成功 */  
  SR_MQTT_EVENT_DISCONNECT,   /*!< 断开连接 */
  
  SR_MQTT_EVENT_RECV_PUBLISH  /*!< 收到平台下行PUBLISH数据 */
}SR_MQTT_EVENT_E;



/**
* @brief MQTT事件通知回调函类型
* 
* @param[in] mqttc   MQTT Client指针
* @param[in] event   事件类型枚举
* @param[in] mqttMsg mqtt消息，里面携带数据
*
* @return 无
*/
typedef void (*MqttEventCb)(SR_MQTT_CLIENT_T *mqttc,SR_MQTT_EVENT_E event,SR_MQTT_MSG_T *mqttMsg);


/**  
* @brief 订阅回调列表
*/
typedef struct 
{
	char *topicFilter;    /*!< 主题过滤器，能区分主题的关键字符串 */
	void (*topicCb)(SR_MQTT_CLIENT_T *mqttc,  SR_MQTT_MSG_T *mqttMsg);  /*!< 主题回调处理函数 */

} SR_SUB_CB_TABLE_T;



/**  
* @brief MQTT Client 结构体
*/
typedef struct SR_MQTT_CLIENT
{ 
  SR_NET_ADP_T *adapter;           /*!< 网络适配器 */
  void *thirdData;                 /*!< 第三方平台私有数据，通常为控制句柄*/
  void *msgQueue;                  /*!< mqtt消息队列 */
  SR_MQTT_INIT_PARAMS_T initParams;/*!< 初始化参数 */
  unsigned int nextPacketId;       /*!< 报文ID */
  MqttEventCb eventCallback;       /*!< 事件通知回调 */ 

  SR_SUB_CB_TABLE_T  *table;       /*!< 订阅回调列表 */ 
  uint8_t tableSize;               /*!< 订阅回调列表的元素个数 */ 


}SR_MQTT_CLIENT_T;




/**
* @brief 获取下个一报文的ID号，内部BSP适配使用
* 
* @param[in] mqttc  MQTT客户端对象指针
* 
* @return 报文ID
*/
int _GetNextPacketId(SR_MQTT_CLIENT_T *mqttc);


/***********************************************************MQTT抽象接口************************************************/
/**
* @brief 初始化MQTT客户端
* 
* @param[in] adp    网络适配器指针
* @param[in] mqttc      MQTT客户端对象指针
* @param[in] initParams MQTT初始化参数
* 
* @return 成功返回0，失败返回负值错误码
*/
int SR_NetMqttcInit(SR_NET_ADP_T *adp, SR_MQTT_CLIENT_T *mqttc,SR_MQTT_INIT_PARAMS_T *initParams);

/**
* @brief 去初始化MQTT客户端
* 
* @param[in] mqttc MQTT客户端对象指针
* 
* @return 成功返回0，失败返回负值错误码
*/
int SR_NetMqttcDeinit(SR_MQTT_CLIENT_T *mqttc);

/**
* @brief 连接MQTT服务器
* 
* @param[in] mqttc      MQTT客户端对象指针
* @param[in] connParams MQTT连接参数
* 
* @return 成功返回0，失败返回负值错误码
*/
int SR_NetMqttcConnect(SR_MQTT_CLIENT_T *mqttc, SR_MQTT_CONN_PARAMS_T *connParams);


/**
* @brief 断开与MQTT服务器的连接
* 
* @param[in] mqttc MQTT客户端对象指针
* 
* @return 成功返回0，失败返回负值错误码
*/
int SR_NetMqttcDisconnect(SR_MQTT_CLIENT_T *mqttc);

/**
* @brief 发布消息到MQTT服务器
* 
* @param[in] mqttc   MQTT客户端对象指针
* @param[in] qos     消息服务质量等级
* @param[in] topic   主题
* @param[in] msg     消息内容
* @param[in] msgLen  消息长度
* 
* @return 成功返回0，失败返回负值错误码
*/
int SR_NetMqttcPublish(SR_MQTT_CLIENT_T *mqttc, SR_MQTT_QOS_E qos,char *topic, char *msg,uint16_t msgLen);


/**
* @brief 订阅MQTT主题
* 
* @param[in] mqttc   MQTT客户端对象指针
* @param[in] topic   主题
* @param[in] qos     消息服务质量等级
* 
* @return 成功返回0，失败返回负值错误码
*/
int SR_NetMqttcSubscribe(SR_MQTT_CLIENT_T *mqttc, char *topic, SR_MQTT_QOS_E qos);

/**
* @brief 取消订阅MQTT主题
* 
* @param[in] mqttc   MQTT客户端对象指针
* @param[in] topic   主题
* 
* @return 成功返回0，失败返回负值错误码
*/
int SR_NetMqttcUnsub(SR_MQTT_CLIENT_T *mqttc,  char *topic); 



/**
* @brief 设置订阅主题的回调函数列表
* 
* @param[in] mqttc       MQTT客户端对象指针
* @param[in] table       订阅回调函数表
* @param[in] tableSize   函数表的大小
* 
* @return 成功返回0，失败返回负值错误码
*/
int SR_NetMqttcSetSubTable(SR_MQTT_CLIENT_T *mqttc, SR_SUB_CB_TABLE_T  *table,uint8_t tableSize);


/**
* @brief 设置MQTT事件的回调函数
* 
* @param[in] mqttc  MQTT客户端对象指针
* @param[in] cb     事件回调函数
* 
* @return 成功返回0，失败返回负值错误码
*/
int SR_NetMqttcSetEvtCb(SR_MQTT_CLIENT_T *mqttc,MqttEventCb cb);



#endif



