/* mqtt_client.h * * Copyright (C) 2006-2020 wolfSSL Inc. * * This file is part of wolfMQTT. * * wolfMQTT 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; either version 2 of the License, or * (at your option) any later version. * * wolfMQTT 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ /* Implementation by: David Garske * Based on specification for MQTT v3.1.1 * See http://mqtt.org/documentation for additional MQTT documentation. */ #ifndef WOLFMQTT_CLIENT_H #define WOLFMQTT_CLIENT_H #ifdef __cplusplus extern "C" { #endif #if !defined(WOLFMQTT_USER_SETTINGS) && !defined(USE_WINDOWS_API) /* If options.h is missing use the "./configure" script. Otherwise, copy * the template "wolfmqtt/options.h.in" into "wolfmqtt/options.h" */ // #include "wolfmqtt/options.h" #endif #include "wolfmqtt/mqtt_types.h" #include "wolfmqtt/mqtt_packet.h" #include "wolfmqtt/mqtt_socket.h" #define PRINT_BUFFER_SIZE 800 #if defined(WOLFMQTT_PROPERTY_CB) && !defined(WOLFMQTT_V5) #error "WOLFMQTT_V5 must be defined to use WOLFMQTT_PROPERTY_CB" #endif struct _MqttClient; /*! \brief Mqtt Message Callback * \discussion If the message payload is larger than the maximum RX buffer then this callback is called multiple times. If msg_new = 1 its a new message. The topc_name and topic_name length are only valid when msg_new = 1. If msg_new = 0 then we are receiving additional payload. Each callback populates the payload in MqttMessage.buffer. The MqttMessage.buffer_len is the size of the buffer payload. The MqttMessage.buffer_pos is the location in the total payload. The MqttMessage.total_len is the length of the complete payload message. If msg_done = 1 the entire publish payload has been received. * \param client Pointer to MqttClient structure * \param message Pointer to MqttMessage structure that has been initialized with the payload properties * \param msg_new If non-zero value then message is new and topic name / len is provided and valid. * \param msg_done If non-zero value then we have received the entire message and payload. * \return MQTT_CODE_SUCCESS to remain connected (other values will cause net disconnect - see enum MqttPacketResponseCodes) */ typedef int (*MqttMsgCb)(struct _MqttClient *client, MqttMessage *message, byte msg_new, byte msg_done); /*! \brief Mqtt Publish Callback * \discussion If the publish payload is larger than the maximum TX buffer then this callback is called multiple times. This callback is executed from within a call to MqttPublish. It is expected to provide a buffer and it's size and return >=0 for success. Each callback populates the payload in MqttPublish.buffer. The MqttPublish.buffer_len is the size of the buffer payload. The MqttPublish.total_len is the length of the complete payload message. * \param publish Pointer to MqttPublish structure * \return >= 0 Indicates success */ typedef int (*MqttPublishCb)(MqttPublish *publish); /* Client flags */ enum MqttClientFlags { MQTT_CLIENT_FLAG_IS_CONNECTED = 0x01, MQTT_CLIENT_FLAG_IS_TLS = 0x02, }; typedef enum _MqttPkStat { MQTT_PK_BEGIN, MQTT_PK_READ_HEAD, MQTT_PK_READ, } MqttPkStat; typedef struct _MqttPkRead { MqttPkStat stat; int header_len; int remain_len; int buf_len; } MqttPkRead; typedef struct _MqttSk { int pos; int len; } MqttSk; #ifdef WOLFMQTT_DISCONNECT_CB typedef int (*MqttDisconnectCb)(struct _MqttClient *client, int error_code, void *ctx); #endif #ifdef WOLFMQTT_PROPERTY_CB typedef int (*MqttPropertyCb)(struct _MqttClient *client, MqttProp *head, void *ctx); #endif #include "generic/list.h" typedef void (*MSG_CALLBACK)(MessageData *md); struct subscribe_topic { struct list_head entry; char *topic; MSG_CALLBACK cb; }; /* Client structure */ typedef struct _MqttClient { word32 flags; /* MqttClientFlags */ int cmd_timeout_ms; byte *tx_buf; int tx_buf_len; byte *rx_buf; int rx_buf_len; MqttNet *net; /* Pointer to network callbacks and context */ #ifdef ENABLE_MQTT_TLS MqttTls tls; /* WolfSSL context for TLS */ #endif MqttPkRead packet; MqttSk read; MqttSk write; MqttMsgCb msg_cb; MqttObject msg; /* generic incoming message used by MqttClient_WaitType */ #ifdef WOLFMQTT_SN SN_Object msgSN; #endif void *ctx; /* user supplied context for publish callbacks */ #ifdef WOLFMQTT_V5 word32 packet_sz_max; /* Server property */ byte max_qos; /* Server property */ byte retain_avail; /* Server property */ byte enable_eauth; /* Enhanced authentication */ byte protocol_level; #endif #ifdef WOLFMQTT_DISCONNECT_CB MqttDisconnectCb disconnect_cb; void *disconnect_ctx; #endif #ifdef WOLFMQTT_PROPERTY_CB MqttPropertyCb property_cb; void *property_ctx; #endif #ifdef WOLFMQTT_MULTITHREAD wm_Sem lockSend; wm_Sem lockRecv; wm_Sem lockClient; struct _MqttPendResp *firstPendResp; struct _MqttPendResp *lastPendResp; #endif struct subscribe_topic topic_head; //add: 订阅链表 word16 keep_alive_sec; } MqttClient; /* Application Interfaces */ /*! \brief Initializes the MqttClient structure * \param client Pointer to MqttClient structure (uninitialized is okay) * \param net Pointer to MqttNet structure that has been initialized with callback pointers and context * \param msgCb Pointer to message callback function * \param tx_buf Pointer to transmit buffer used during encoding * \param tx_buf_len Maximum length of the transmit buffer * \param rx_buf Pointer to receive buffer used during decoding * \param rx_buf_len Maximum length of the receive buffer * \param connect_timeout_ms Maximum command wait timeout in milliseconds * \return MQTT_CODE_SUCCESS or MQTT_CODE_ERROR_BAD_ARG (see enum MqttPacketResponseCodes) */ WOLFMQTT_API int MqttClient_Init( MqttClient *client, MqttNet *net, MqttMsgCb msg_cb, byte *tx_buf, int tx_buf_len, byte *rx_buf, int rx_buf_len, int cmd_timeout_ms); /*! \brief Cleans up resources allocated to the MqttClient structure * \param client Pointer to MqttClient structure * \return none */ WOLFMQTT_API void MqttClient_DeInit(MqttClient *client); #ifdef WOLFMQTT_DISCONNECT_CB /*! \brief Sets a disconnect callback with custom context * \param client Pointer to MqttClient structure (uninitialized is okay) * \param disCb Pointer to disconnect callback function * \param ctx Pointer to your own context * \return MQTT_CODE_SUCCESS or MQTT_CODE_ERROR_BAD_ARG (see enum MqttPacketResponseCodes) */ WOLFMQTT_API int MqttClient_SetDisconnectCallback( MqttClient *client, MqttDisconnectCb discb, void *ctx); #endif #ifdef WOLFMQTT_PROPERTY_CB /*! \brief Sets a property callback with custom context * \param client Pointer to MqttClient structure (uninitialized is okay) * \param propCb Pointer to property callback function * \param ctx Pointer to your own context * \return MQTT_CODE_SUCCESS or MQTT_CODE_ERROR_BAD_ARG (see enum MqttPacketResponseCodes) */ WOLFMQTT_API int MqttClient_SetPropertyCallback( MqttClient *client, MqttPropertyCb propCb, void *ctx); #endif /*! \brief Encodes and sends the MQTT Connect packet and waits for the Connect Acknowledgment packet * \discussion This is a blocking function that will wait for MqttNet.read * \param client Pointer to MqttClient structure * \param connect Pointer to MqttConnect structure initialized with connect parameters * \return MQTT_CODE_SUCCESS or MQTT_CODE_ERROR_* (see enum MqttPacketResponseCodes) */ WOLFMQTT_API int MqttClient_Connect( MqttClient *client, MqttConnect *connect); /*! \brief Encodes and sends the MQTT Publish packet and waits for the Publish response (if QoS > 0). If the total size of the payload is larger than the buffer size, it can be called successively to transmit the full payload. (if QoS > 0) * \discussion This is a blocking function that will wait for MqttNet.read * If QoS level = 1 then will wait for PUBLISH_ACK. * If QoS level = 2 then will wait for PUBLISH_REC then send PUBLISH_REL and wait for PUBLISH_COMP. * \param client Pointer to MqttClient structure * \param publish Pointer to MqttPublish structure initialized with message data * Note: MqttPublish and MqttMessage are same structure. * \return MQTT_CODE_SUCCESS or MQTT_CODE_ERROR_* (see enum MqttPacketResponseCodes) */ WOLFMQTT_API int MqttClient_Publish( MqttClient *client, MqttPublish *publish); /*! \brief Encodes and sends the MQTT Publish packet and waits for the Publish response (if QoS > 0). The callback function is used to copy the payload data, allowing the use of transmit buffers smaller than the total size of the payload. * \discussion This is a blocking function that will wait for MqttNet.read * If QoS level = 1 then will wait for PUBLISH_ACK. * If QoS level = 2 then will wait for PUBLISH_REC then send PUBLISH_REL and wait for PUBLISH_COMP. * \param client Pointer to MqttClient structure * \param publish Pointer to MqttPublish structure initialized with message data * Note: MqttPublish and MqttMessage are same structure. * \param pubCb Function pointer to callback routine * \return MQTT_CODE_SUCCESS or MQTT_CODE_ERROR_* (see enum MqttPacketResponseCodes) */ WOLFMQTT_API int MqttClient_Publish_ex( MqttClient *client, MqttPublish *publish, MqttPublishCb pubCb); /*! \brief Encodes and sends the MQTT Subscribe packet and waits for the Subscribe Acknowledgment packet * \discussion This is a blocking function that will wait for MqttNet.read * \param client Pointer to MqttClient structure * \param subscribe Pointer to MqttSubscribe structure initialized with subscription topic list and desired QoS. * \return MQTT_CODE_SUCCESS or MQTT_CODE_ERROR_* (see enum MqttPacketResponseCodes) */ WOLFMQTT_API int MqttClient_Subscribe( MqttClient *client, MqttSubscribe *subscribe); /*! \brief Encodes and sends the MQTT Unsubscribe packet and waits for the Unsubscribe Acknowledgment packet * \discussion This is a blocking function that will wait for MqttNet.read * \param client Pointer to MqttClient structure * \param unsubscribe Pointer to MqttUnsubscribe structure initialized with topic list. * \return MQTT_CODE_SUCCESS or MQTT_CODE_ERROR_* (see enum MqttPacketResponseCodes) */ WOLFMQTT_API int MqttClient_Unsubscribe( MqttClient *client, MqttUnsubscribe *unsubscribe); /*! \brief Encodes and sends the MQTT Ping Request packet and waits for the Ping Response packet * \discussion This is a blocking function that will wait for MqttNet.read * \param client Pointer to MqttClient structure * \return MQTT_CODE_SUCCESS or MQTT_CODE_ERROR_* (see enum MqttPacketResponseCodes) */ WOLFMQTT_API int MqttClient_Ping( MqttClient *client); WOLFMQTT_API int MqttClient_Ping_ex(MqttClient *client, MqttPing *ping); #ifdef WOLFMQTT_V5 /*! \brief Encodes and sends the MQTT Authentication Request packet and waits for the Ping Response packet * \discussion This is a blocking function that will wait for MqttNet.read * \param client Pointer to MqttClient structure * \param auth Pointer to MqttAuth structure * \return MQTT_CODE_SUCCESS or MQTT_CODE_ERROR_* (see enum MqttPacketResponseCodes) */ WOLFMQTT_API int MqttClient_Auth( MqttClient *client, MqttAuth *auth); /*! \brief Add a new property * \discussion Allocate a property structure and add it to the head of the list pointed to by head. To be used prior to calling packet command. * \param head Pointer-pointer to a property structure * \return MQTT_CODE_SUCCESS or MQTT_CODE_ERROR_BAD_ARG */ WOLFMQTT_API MqttProp *MqttClient_PropsAdd( MqttProp **head); /*! \brief Free property list * \discussion Deallocate the list pointed to by head. Must be used after the packet command that used MqttClient_Prop_Add. * \param head Pointer-pointer to a property structure * \return Pointer to newly allocated property structure or NULL */ WOLFMQTT_API void MqttClient_PropsFree( MqttProp *head); #endif /*! \brief Encodes and sends the MQTT Disconnect packet (no response) * \discussion This is a non-blocking function that will try and send using MqttNet.write * \param client Pointer to MqttClient structure * \return MQTT_CODE_SUCCESS or MQTT_CODE_ERROR_* (see enum MqttPacketResponseCodes) */ WOLFMQTT_API int MqttClient_Disconnect( MqttClient *client); /*! \brief Encodes and sends the MQTT Disconnect packet (no response) * \discussion This is a non-blocking function that will try and send using MqttNet.write * \param client Pointer to MqttClient structure * \param disconnect Pointer to MqttDisconnect structure. NULL is valid. * \return MQTT_CODE_SUCCESS or MQTT_CODE_ERROR_* (see enum MqttPacketResponseCodes) */ WOLFMQTT_API int MqttClient_Disconnect_ex( MqttClient *client, MqttDisconnect *disconnect); /*! \brief Waits for packets to arrive. Incoming publish messages will arrive via callback provided in MqttClient_Init. * \discussion This is a blocking function that will wait for MqttNet.read * \param client Pointer to MqttClient structure * \param timeout_ms Milliseconds until read timeout * \return MQTT_CODE_SUCCESS or MQTT_CODE_ERROR_* (see enum MqttPacketResponseCodes) */ WOLFMQTT_API int MqttClient_WaitMessage( MqttClient *client, int timeout_ms); /*! \brief Waits for packets to arrive. Incoming publish messages will arrive via callback provided in MqttClient_Init. * \discussion This is a blocking function that will wait for MqttNet.read * \param client Pointer to MqttClient structure * \param msg Pointer to MqttObject structure * \param timeout_ms Milliseconds until read timeout * \return MQTT_CODE_SUCCESS or MQTT_CODE_ERROR_* (see enum MqttPacketResponseCodes) */ WOLFMQTT_API int MqttClient_WaitMessage_ex( MqttClient *client, MqttObject *msg, int timeout_ms); /*! \brief Performs network connect with TLS (if use_tls is non-zero value) * \discussion Will perform the MqttTlsCb callback if use_tls is non-zero value * \param client Pointer to MqttClient structure * \param host Address of the broker server * \param port Optional custom port. If zero will use defaults * \param use_tls If non-zero value will connect with and use TLS for encryption of data * \param cb A function callback for configuration of the SSL context certificate checking * \return MQTT_CODE_SUCCESS or MQTT_CODE_ERROR_* (see enum MqttPacketResponseCodes) */ WOLFMQTT_API int MqttClient_NetConnect( MqttClient *client, const char *host, word16 port, int timeout_ms, int use_tls, MqttTlsCb cb); /*! \brief Performs a network disconnect * \param client Pointer to MqttClient structure * \return MQTT_CODE_SUCCESS or MQTT_CODE_ERROR_* (see enum MqttPacketResponseCodes) */ WOLFMQTT_API int MqttClient_NetDisconnect( MqttClient *client); /*! \brief Gets number version of connected protocol version * \param client Pointer to MqttClient structure * \return 4 (v3.1.1) or 5 (v5) */ WOLFMQTT_API int MqttClient_GetProtocolVersion(MqttClient *client); /*! \brief Gets string version of connected protocol version * \param client Pointer to MqttClient structure * \return String v3.1.1 or v5 */ WOLFMQTT_API const char *MqttClient_GetProtocolVersionString(MqttClient *client); #ifndef WOLFMQTT_NO_ERROR_STRINGS /*! \brief Performs lookup of the WOLFMQTT_API return values * \param return_code The return value from a WOLFMQTT_API function * \return String representation of the return code */ WOLFMQTT_API const char *MqttClient_ReturnCodeToString( int return_code); #else #define MqttClient_ReturnCodeToString(x) \ "not compiled in" #endif /* WOLFMQTT_NO_ERROR_STRINGS */ #ifdef WOLFMQTT_SN /*! \brief Encodes and sends the a message to search for a gateway and waits for the gateway info response message. * \discussion This is a blocking function that will wait for MqttNet.read * \param client Pointer to MqttClient structure * \param search Pointer to SN_SearchGW structure initialized with hop radius. * \return MQTT_CODE_SUCCESS or MQTT_CODE_ERROR_* (see enum MqttPacketResponseCodes) */ WOLFMQTT_API int SN_Client_SearchGW( MqttClient *client, SN_SearchGw *search); /*! \brief Encodes and sends the Connect packet and waits for the Connect Acknowledgment packet. If Will is enabled, then gateway prompts for LWT Topic and Message. * \discussion This is a blocking function that will wait for MqttNet.read * \param client Pointer to MqttClient structure * \param connect Pointer to SN_Connect structure initialized with connect parameters * \return MQTT_CODE_SUCCESS or MQTT_CODE_ERROR_* (see enum MqttPacketResponseCodes) */ WOLFMQTT_API int SN_Client_Connect( MqttClient *client, SN_Connect *connect); /*! \brief Encodes and sends the MQTT-SN Will Topic packet. If 'will' is non-NULL, first waits for the WillTopicReq and WillMsgReq packet before sending WillMsg. Sending a NULL 'will' indicates that the client wishes to delete the Will topic and the Will message stored in the server. * \discussion This is a blocking function that will wait for MqttNet.read * \param client Pointer to MqttClient structure * \param will Pointer to SN_Will structure initialized with topic and message parameters. NULL is valid. * \return MQTT_CODE_SUCCESS or MQTT_CODE_ERROR_* (see enum MqttPacketResponseCodes) */ WOLFMQTT_API int SN_Client_Will( MqttClient *client, SN_Will *will); /*! \brief Encodes and sends the MQTT-SN Will Topic Update packet. Sending a NULL 'will' indicates that the client wishes to delete the Will topic and the Will message stored in the server. * \discussion This is a blocking function that will wait for MqttNet.read * \param client Pointer to MqttClient structure * \param will Pointer to SN_Will structure initialized with topic and message parameters. NULL is valid. * \return MQTT_CODE_SUCCESS or MQTT_CODE_ERROR_* (see enum MqttPacketResponseCodes) */ WOLFMQTT_API int SN_Client_WillTopicUpdate(MqttClient *client, SN_Will *will); /*! \brief Encodes and sends the MQTT-SN Will Message Update packet. Sending a NULL 'will' indicates that the client wishes to delete the Will topic and the Will message stored in the server. * \discussion This is a blocking function that will wait for MqttNet.read * \param client Pointer to MqttClient structure * \param will Pointer to SN_Will structure initialized with topic and message parameters. NULL is valid. * \return MQTT_CODE_SUCCESS or MQTT_CODE_ERROR_* (see enum MqttPacketResponseCodes) */ WOLFMQTT_API int SN_Client_WillMsgUpdate(MqttClient *client, SN_Will *will); /*! \brief Encodes and sends the MQTT-SN Register packet and waits for the Register Acknowledge packet. The Register packet is sent by a client to a GW for requesting a topic id value for the included topic name. It is also sent by a GW to inform a client about the topic id value it has assigned to the included topic name. * \discussion This is a blocking function that will wait for MqttNet.read * \param client Pointer to MqttClient structure * \param regist Pointer to SN_Register structure * \return MQTT_CODE_SUCCESS or MQTT_CODE_ERROR_* (see enum MqttPacketResponseCodes) */ WOLFMQTT_API int SN_Client_Register( MqttClient *client, SN_Register *regist); /*! \brief Encodes and sends the MQTT-SN Publish packet and waits for the Publish response (if QoS > 0). * \discussion This is a blocking function that will wait for MqttNet.read * If QoS level = 1 then will wait for PUBLISH_ACK. * If QoS level = 2 then will wait for PUBLISH_REC then send PUBLISH_REL and wait for PUBLISH_COMP. * \param client Pointer to MqttClient structure * \param publish Pointer to SN_Publish structure initialized with message data * Note: SN_Publish and MqttMessage are same structure. * \return MQTT_CODE_SUCCESS or MQTT_CODE_ERROR_* (see enum MqttPacketResponseCodes) */ WOLFMQTT_API int SN_Client_Publish( MqttClient *client, SN_Publish *publish); /*! \brief Encodes and sends the MQTT-SN Subscribe packet and waits for the Subscribe Acknowledgment packet containing the assigned topic ID. * \discussion This is a blocking function that will wait for MqttNet.read * \param client Pointer to MqttClient structure * \param subscribe Pointer to SN_Subscribe structure initialized with subscription topic list and desired QoS. * \return MQTT_CODE_SUCCESS or MQTT_CODE_ERROR_* (see enum MqttPacketResponseCodes) */ WOLFMQTT_API int SN_Client_Subscribe( MqttClient *client, SN_Subscribe *subscribe); /*! \brief Encodes and sends the MQTT-SN Unsubscribe packet and waits for the Unsubscribe Acknowledgment packet * \discussion This is a blocking function that will wait for MqttNet.read * \param client Pointer to MqttClient structure * \param unsubscribe Pointer to SN_Unsubscribe structure initialized with topic ID. * \return MQTT_CODE_SUCCESS or MQTT_CODE_ERROR_* (see enum MqttPacketResponseCodes) */ WOLFMQTT_API int SN_Client_Unsubscribe( MqttClient *client, SN_Unsubscribe *unsubscribe); /*! \brief Encodes and sends the MQTT-SN Disconnect packet. Client may send the disconnect with a duration to indicate the client is entering the "asleep" state. * \discussion This is a non-blocking function that will try and send using MqttNet.write * \param client Pointer to MqttClient structure * \return MQTT_CODE_SUCCESS or MQTT_CODE_ERROR_* (see enum MqttPacketResponseCodes) */ WOLFMQTT_API int SN_Client_Disconnect( MqttClient *client); /*! \brief Encodes and sends the MQTT-SN Disconnect packet. Client may send the disconnect with a duration to indicate the client is entering the "asleep" state. * \discussion This is a non-blocking function that will try and send using MqttNet.write * \param client Pointer to MqttClient structure * \param disconnect Pointer to SN_Disconnect structure. NULL is valid. * \return MQTT_CODE_SUCCESS or MQTT_CODE_ERROR_* (see enum MqttPacketResponseCodes) */ WOLFMQTT_API int SN_Client_Disconnect_ex( MqttClient *client, SN_Disconnect *disconnect); /*! \brief Encodes and sends the MQTT-SN Ping Request packet and waits for the Ping Response packet. If client is in the "asleep" state and wants to notify the gateway that it is entering the "awake" state, it should add it's client ID to the ping request. * \discussion This is a blocking function that will wait for MqttNet.read * \param client Pointer to MqttClient structure * \param ping Pointer to SN_PingReq structure. NULL is valid. * \return MQTT_CODE_SUCCESS or MQTT_CODE_ERROR_* (see enum MqttPacketResponseCodes) */ WOLFMQTT_API int SN_Client_Ping( MqttClient *client, SN_PingReq *ping); /*! \brief Waits for packets to arrive. Incoming publish messages will arrive via callback provided in MqttClient_Init. * \discussion This is a blocking function that will wait for MqttNet.read * \param client Pointer to MqttClient structure * \param timeout_ms Milliseconds until read timeout * \return MQTT_CODE_SUCCESS or MQTT_CODE_ERROR_* (see enum MqttPacketResponseCodes) */ WOLFMQTT_API int SN_Client_WaitMessage( MqttClient *client, int timeout_ms); WOLFMQTT_API int SN_Client_WaitMessage_ex(MqttClient *client, SN_Object *packet_obj, int timeout_ms); #endif /* WOLFMQTT_SN */ #ifdef __cplusplus } /* extern "C" */ #endif /**************************兼容处理START********************************/ #if 1 /* MQTT Client state */ typedef enum _MQTTCtxState { WMQ_BEGIN = 0, WMQ_NET_INIT, WMQ_INIT, WMQ_TCP_CONN, WMQ_MQTT_CONN, WMQ_SUB, WMQ_PUB, WMQ_WAIT_MSG, WMQ_UNSUB, WMQ_DISCONNECT, WMQ_NET_DISCONNECT, WMQ_DONE } MQTTCtxState; typedef struct _MQTTCtx { MQTTCtxState stat; void *app_ctx; /* For storing application specific data */ /* client and net containers */ MqttClient client; MqttNet net; /* temp mqtt containers */ MqttConnect connect; MqttMessage lwt_msg; MqttSubscribe subscribe; MqttUnsubscribe unsubscribe; MqttTopic topics[1], *topic; MqttPublish publish; MqttDisconnect disconnect; #ifdef WOLFMQTT_SN SN_Publish publishSN; #endif /* configuration */ MqttQoS qos; const char *app_name; const char *host; const char *username; const char *password; const char *topic_name; const char *pub_file; const char *client_id; byte *tx_buf, *rx_buf; int return_code; int use_tls; int retain; int enable_lwt; #ifdef WOLFMQTT_V5 int max_packet_size; #endif word32 cmd_timeout_ms; #if defined(WOLFMQTT_NONBLOCK) word32 start_sec; /* used for keep-alive */ #endif word16 keep_alive_sec; word16 port; #ifdef WOLFMQTT_V5 word16 topic_alias; word16 topic_alias_max; /* Server property */ #endif byte clean_session; byte test_mode; #ifdef WOLFMQTT_V5 byte subId_not_avail; /* Server property */ byte enable_eauth; /* Enhanced authentication */ #endif unsigned int dynamicTopic: 1; unsigned int dynamicClientId: 1; #ifdef WOLFMQTT_NONBLOCK unsigned int useNonBlockMode: 1; /* set to use non-blocking mode. network callbacks can return MQTT_CODE_CONTINUE to indicate "would block" */ #endif } MQTTCtx; MQTTCtx mqttCtx; #endif typedef MqttClient Client; typedef MqttNet Network; #include "printf.h" #include "sock_api/sock_api.h" #define DEFAULT_CON_TIMEOUT_MS 5000 typedef void (*messageHandler)(struct MessageData *); void NewNetwork(Network *n); void NetWorkSetTLS(Network *n); void NetWorkSetTLS_key(Network *n, const char *cas_pem, int cas_pem_len, const char *cli_pem, int cli_pem_len, const char *pkey, int pkey_len); void SetNetworkCb(Network *n, int (*cb_func)(enum sock_api_msg_type, void *), void *priv); void SetNetworkRecvTimeout(Network *n, int timeout_ms); void SetNetworkSendTimeout(Network *n, int timeout_ms); int ConnectNetwork(Network *n, char *addr, int port); void MQTTClient(struct _MqttClient *c, Network *network, unsigned int command_timeout_ms, unsigned char *buf, size_t buf_size, unsigned char *readbuf, size_t readbuf_size); int MQTTConnect(struct _MqttClient *c, MQTTPacket_connectData *data); int MQTTDisconnect(struct _MqttClient *c); int MQTTSubscribe(struct _MqttClient *c, const char *topicFilter, enum _MqttQoS qos, messageHandler messageHandler); int MQTTUnsubscribe(struct _MqttClient *c, const char *topicFilter); int MQTTPublish(struct _MqttClient *c, const char *topicName, MQTTMessage *message); int MQTTYield(struct _MqttClient *c, int timeout_ms); /**************************兼容处理END********************************/ #endif /* WOLFMQTT_CLIENT_H */