mirror of
https://gitee.com/beecue/fastbee.git
synced 2025-12-18 00:45:55 +08:00
连接服务器
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
#include "basic_data.h"
|
||||
|
||||
uint8_t UART1ReadBuf[100] = {0};
|
||||
uint8_t UART1ReadBuf[500] = {0};
|
||||
uint16_t UART1ReadFlag = 0;
|
||||
|
||||
uint8_t UART2ReadBuf[100] = {0};
|
||||
uint8_t UART2ReadBuf[500] = {0};
|
||||
uint16_t UART2ReadFlag = 0;
|
||||
|
||||
uint8_t UART3ReadBuf[100] = {0};
|
||||
uint8_t UART3ReadBuf[500] = {0};
|
||||
uint16_t UART3ReadFlag = 0;
|
||||
|
||||
DevParam_t DevParam = {0};
|
||||
|
||||
@@ -6,15 +6,15 @@
|
||||
#define Device_LCD 1
|
||||
|
||||
#define MQTT_SCode 1
|
||||
#define MQTT_AT 1
|
||||
//#define MQTT_AT 1
|
||||
|
||||
extern uint8_t UART1ReadBuf[100];
|
||||
extern uint8_t UART1ReadBuf[500];
|
||||
extern uint16_t UART1ReadFlag;
|
||||
|
||||
extern uint8_t UART2ReadBuf[100];
|
||||
extern uint8_t UART2ReadBuf[500];
|
||||
extern uint16_t UART2ReadFlag;
|
||||
|
||||
extern uint8_t UART3ReadBuf[100];
|
||||
extern uint8_t UART3ReadBuf[500];
|
||||
extern uint16_t UART3ReadFlag;
|
||||
|
||||
typedef enum
|
||||
@@ -39,7 +39,11 @@ typedef struct
|
||||
|
||||
uint16_t AirInforGetTime; // 空气信息获取时间
|
||||
|
||||
uint8_t ServerRelay; // 服务器继电器
|
||||
uint8_t ServerRed;
|
||||
|
||||
uint16_t ESP8266SendTime;
|
||||
uint16_t MQTTSendTime;
|
||||
|
||||
// 运行阶段
|
||||
RunPhase_E RunPhase;
|
||||
@@ -58,6 +62,8 @@ typedef struct
|
||||
uint16_t PM1_0;
|
||||
uint16_t PM2_5;
|
||||
uint16_t PM10;
|
||||
|
||||
uint16_t tes;
|
||||
}DevParam_t;
|
||||
extern DevParam_t DevParam;
|
||||
|
||||
|
||||
@@ -72,8 +72,8 @@ void TIM3_IRQHandler(void) //TIM3中断服务程序
|
||||
if(UART3Count == UART3ReadFlag)
|
||||
{
|
||||
UART3ReadFlag |= (1 << 15);
|
||||
UART3Count = 0;
|
||||
UART3RecTime = 0;
|
||||
UART3Count = 0;
|
||||
UART3RecTime = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -101,7 +101,10 @@ void TIM3_IRQHandler(void) //TIM3中断服务程序
|
||||
DevParam.ServerUpdateTime++;
|
||||
// 发送时间
|
||||
if(DevParam.ESP8266SendTime<65000)
|
||||
DevParam.ESP8266SendTime++;
|
||||
DevParam.ESP8266SendTime++;
|
||||
// 发送时间
|
||||
if(DevParam.MQTTSendTime<65000)
|
||||
DevParam.MQTTSendTime++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,24 +1,27 @@
|
||||
#include "bsp_uart2.h"
|
||||
|
||||
// 串口2 PA2 TX PA3 RX
|
||||
void Dev_UART2SendStr(char* fmt,...){
|
||||
uint8_t tbuf[200] = {0};
|
||||
void Dev_UART2SendStr(uint8_t* tbuf, uint16_t tlen, uint8_t tByte){
|
||||
uint16_t i = 0,j = 0;
|
||||
|
||||
va_list ap;
|
||||
va_start(ap,fmt);
|
||||
vsprintf((char*)tbuf, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
j = strlen((const char*)tbuf);
|
||||
|
||||
if(tlen > 0)
|
||||
j = tlen;
|
||||
else
|
||||
j = strlen((const char*)tbuf);
|
||||
|
||||
for( i = 0; i < j; i++)
|
||||
{
|
||||
if((tByte>0)&&(i==2))
|
||||
{
|
||||
while(USART_GetFlagStatus(USART2, USART_FLAG_TC)==RESET){};
|
||||
USART_SendData(USART2, tByte);
|
||||
}
|
||||
while(USART_GetFlagStatus(USART2, USART_FLAG_TC)==RESET){};
|
||||
USART_SendData(USART2, tbuf[i]);
|
||||
}
|
||||
while(USART_GetFlagStatus(USART2, USART_FLAG_TC)==RESET);
|
||||
}
|
||||
|
||||
// 发送数据
|
||||
void Dev_UART2SendData(uint8_t *ch,uint16_t len){
|
||||
uint16_t i = 0;
|
||||
@@ -80,10 +83,10 @@ void USART2_IRQHandler(void)
|
||||
res = USART_ReceiveData(USART2);
|
||||
|
||||
// 是否存在数据没有处理
|
||||
if( (UART2ReadFlag&0x8000)==0 )
|
||||
if((UART2ReadFlag&0x8000)==0)
|
||||
{
|
||||
UART2ReadBuf[UART2ReadFlag++] = res;
|
||||
if(UART2ReadFlag>=90)
|
||||
if(UART2ReadFlag>=480)
|
||||
{
|
||||
UART2ReadFlag |= (1 << 15);
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
#include "basic_data.h"
|
||||
|
||||
void Dev_UART2SendStr(char* fmt,...);
|
||||
void Dev_UART2SendStr(uint8_t* tbuf, uint16_t tlen, uint8_t tByte);
|
||||
void Dev_UART2SendData(uint8_t *ch, uint16_t len);
|
||||
void BSP_UART2Init(uint32_t bound);
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ int main()
|
||||
{
|
||||
// 显示部分,侧边跳动
|
||||
Show_BroadSideBeat();
|
||||
//
|
||||
|
||||
// PMD4,获取空气信息
|
||||
PMD4_GetAirInfor();
|
||||
}
|
||||
|
||||
@@ -1,126 +0,0 @@
|
||||
#ifndef _MQTTCONNECT_H_
|
||||
#define _MQTTCONNECT_H_
|
||||
|
||||
#include "MQTTPacket.h"
|
||||
|
||||
enum connack_return_codes
|
||||
{
|
||||
MQTT_CONNECTION_ACCEPTED = 0,
|
||||
MQTT_UNNACCEPTABLE_PROTOCOL = 1,
|
||||
MQTT_CLIENTID_REJECTED = 2,
|
||||
MQTT_SERVER_UNAVAILABLE = 3,
|
||||
MQTT_BAD_USERNAME_OR_PASSWORD = 4,
|
||||
MQTT_NOT_AUTHORIZED = 5,
|
||||
};
|
||||
|
||||
#if !defined(DLLImport)
|
||||
#define DLLImport
|
||||
#endif
|
||||
#if !defined(DLLExport)
|
||||
#define DLLExport
|
||||
#endif
|
||||
|
||||
typedef union
|
||||
{
|
||||
unsigned char all; /**< all connect flags */
|
||||
#if defined(REVERSED)
|
||||
struct
|
||||
{
|
||||
unsigned int username : 1; /**< 3.1 user name */
|
||||
unsigned int password : 1; /**< 3.1 password */
|
||||
unsigned int willRetain : 1; /**< will retain setting */
|
||||
unsigned int willQoS : 2; /**< will QoS value */
|
||||
unsigned int will : 1; /**< will flag */
|
||||
unsigned int cleansession : 1; /**< clean session flag */
|
||||
unsigned int : 1; /**< unused */
|
||||
} bits;
|
||||
#else
|
||||
struct
|
||||
{
|
||||
unsigned int : 1; /**< unused */
|
||||
unsigned int cleansession : 1; /**< cleansession flag */
|
||||
unsigned int will : 1; /**< will flag */
|
||||
unsigned int willQoS : 2; /**< will QoS value */
|
||||
unsigned int willRetain : 1; /**< will retain setting */
|
||||
unsigned int password : 1; /**< 3.1 password */
|
||||
unsigned int username : 1; /**< 3.1 user name */
|
||||
} bits;
|
||||
#endif
|
||||
} MQTTConnectFlags; /**< connect flags byte */
|
||||
|
||||
/**
|
||||
* Defines the MQTT "Last Will and Testament" (LWT) settings for
|
||||
* the connect packet.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
/** The eyecatcher for this structure. must be MQTW. */
|
||||
char struct_id[4];
|
||||
/** The version number of this structure. Must be 0 */
|
||||
int struct_version;
|
||||
/** The LWT topic to which the LWT message will be published. */
|
||||
MQTTString topicName;
|
||||
/** The LWT payload. */
|
||||
MQTTString message;
|
||||
/**
|
||||
* The retained flag for the LWT message (see MQTTAsync_message.retained).
|
||||
*/
|
||||
unsigned char retained;
|
||||
/**
|
||||
* The quality of service setting for the LWT message (see
|
||||
* MQTTAsync_message.qos and @ref qos).
|
||||
*/
|
||||
char qos;
|
||||
} MQTTPacket_willOptions;
|
||||
|
||||
#define MQTTPacket_willOptions_initializer { {'M', 'Q', 'T', 'W'}, 0, {NULL, {0, NULL}}, {NULL, {0, NULL}}, 0, 0 }
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/** The eyecatcher for this structure. must be MQTC. */
|
||||
char struct_id[4];
|
||||
/** The version number of this structure. Must be 0 */
|
||||
int struct_version;
|
||||
/** Version of MQTT to be used. 3 = 3.1 4 = 3.1.1
|
||||
*/
|
||||
unsigned char MQTTVersion;
|
||||
MQTTString clientID;
|
||||
unsigned short keepAliveInterval;
|
||||
unsigned char cleansession;
|
||||
unsigned char willFlag;
|
||||
MQTTPacket_willOptions will;
|
||||
MQTTString username;
|
||||
MQTTString password;
|
||||
} MQTTPacket_connectData;
|
||||
|
||||
typedef union
|
||||
{
|
||||
unsigned char all; /**< all connack flags */
|
||||
#if defined(REVERSED)
|
||||
struct
|
||||
{
|
||||
unsigned int reserved : 7; /**< unused */
|
||||
unsigned int sessionpresent : 1; /**< session present flag */
|
||||
} bits;
|
||||
#else
|
||||
struct
|
||||
{
|
||||
unsigned int sessionpresent : 1; /**< session present flag */
|
||||
unsigned int reserved: 7; /**< unused */
|
||||
} bits;
|
||||
#endif
|
||||
} MQTTConnackFlags; /**< connack flags byte */
|
||||
|
||||
#define MQTTPacket_connectData_initializer { {'M', 'Q', 'T', 'C'}, 0, 4, {NULL, {0, NULL}}, 60, 1, 0, \
|
||||
MQTTPacket_willOptions_initializer, {NULL, {0, NULL}}, {NULL, {0, NULL}} }
|
||||
|
||||
DLLExport int MQTTSerialize_connect(unsigned char* buf, int buflen, MQTTPacket_connectData* options);
|
||||
DLLExport int MQTTDeserialize_connect(MQTTPacket_connectData* data, unsigned char* buf, int len);
|
||||
|
||||
DLLExport int MQTTSerialize_connack(unsigned char* buf, int buflen, unsigned char connack_rc, unsigned char sessionPresent);
|
||||
DLLExport int MQTTDeserialize_connack(unsigned char* sessionPresent, unsigned char* connack_rc, unsigned char* buf, int buflen);
|
||||
|
||||
DLLExport int MQTTSerialize_disconnect(unsigned char* buf, int buflen);
|
||||
DLLExport int MQTTSerialize_pingreq(unsigned char* buf, int buflen);
|
||||
|
||||
#endif /* MQTTCONNECT_H_ */
|
||||
@@ -1,181 +0,0 @@
|
||||
#include "MQTTPacket.h"
|
||||
#include "StackTrace.h"
|
||||
|
||||
#include <string.h>
|
||||
/**
|
||||
* Determines the length of the MQTT connect packet that would be produced using the supplied connect options.
|
||||
* @param options the options to be used to build the connect packet
|
||||
* @return the length of buffer needed to contain the serialized version of the packet
|
||||
*/
|
||||
int MQTTSerialize_connectLength(MQTTPacket_connectData* options){
|
||||
int len = 0;
|
||||
|
||||
FUNC_ENTRY;
|
||||
|
||||
if (options->MQTTVersion == 3)
|
||||
len = 12; /* variable depending on MQTT or MQIsdp */
|
||||
else if (options->MQTTVersion == 4)
|
||||
len = 10;
|
||||
|
||||
len += MQTTstrlen(options->clientID)+2;
|
||||
if (options->willFlag)
|
||||
len += MQTTstrlen(options->will.topicName)+2 + MQTTstrlen(options->will.message)+2;
|
||||
if (options->username.cstring || options->username.lenstring.data)
|
||||
len += MQTTstrlen(options->username)+2;
|
||||
if (options->password.cstring || options->password.lenstring.data)
|
||||
len += MQTTstrlen(options->password)+2;
|
||||
|
||||
FUNC_EXIT_RC(len);
|
||||
return len;
|
||||
}
|
||||
/**
|
||||
* Serializes the connect options into the buffer.
|
||||
* @param buf the buffer into which the packet will be serialized
|
||||
* @param len the length in bytes of the supplied buffer
|
||||
* @param options the options to be used to build the connect packet
|
||||
* @return serialized length, or error if 0
|
||||
*/
|
||||
int MQTTSerialize_connect(unsigned char* buf, int buflen, MQTTPacket_connectData* options){
|
||||
unsigned char *ptr = buf;
|
||||
MQTTHeader header = {0};
|
||||
MQTTConnectFlags flags = {0};
|
||||
int len = 0;
|
||||
int rc = -1;
|
||||
|
||||
FUNC_ENTRY;
|
||||
if (MQTTPacket_len(len = MQTTSerialize_connectLength(options)) > buflen)
|
||||
{
|
||||
rc = MQTTPACKET_BUFFER_TOO_SHORT;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
header.byte = 0;
|
||||
header.bits.type = CONNECT;
|
||||
writeChar(&ptr, header.byte); /* write header */
|
||||
|
||||
ptr += MQTTPacket_encode(ptr, len); /* write remaining length */
|
||||
|
||||
if (options->MQTTVersion == 4)
|
||||
{
|
||||
writeCString(&ptr, "MQTT");
|
||||
writeChar(&ptr, (char) 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
writeCString(&ptr, "MQIsdp");
|
||||
writeChar(&ptr, (char) 3);
|
||||
}
|
||||
|
||||
flags.all = 0;
|
||||
flags.bits.cleansession = options->cleansession;
|
||||
flags.bits.will = (options->willFlag) ? 1 : 0;
|
||||
if (flags.bits.will)
|
||||
{
|
||||
flags.bits.willQoS = options->will.qos;
|
||||
flags.bits.willRetain = options->will.retained;
|
||||
}
|
||||
|
||||
if (options->username.cstring || options->username.lenstring.data)
|
||||
flags.bits.username = 1;
|
||||
if (options->password.cstring || options->password.lenstring.data)
|
||||
flags.bits.password = 1;
|
||||
|
||||
writeChar(&ptr, flags.all);
|
||||
writeInt(&ptr, options->keepAliveInterval);
|
||||
writeMQTTString(&ptr, options->clientID);
|
||||
if (options->willFlag)
|
||||
{
|
||||
writeMQTTString(&ptr, options->will.topicName);
|
||||
writeMQTTString(&ptr, options->will.message);
|
||||
}
|
||||
if (flags.bits.username)
|
||||
writeMQTTString(&ptr, options->username);
|
||||
if (flags.bits.password)
|
||||
writeMQTTString(&ptr, options->password);
|
||||
|
||||
rc = ptr - buf;
|
||||
|
||||
exit: FUNC_EXIT_RC(rc);
|
||||
return rc;
|
||||
}
|
||||
/**
|
||||
* Deserializes the supplied (wire) buffer into connack data - return code
|
||||
* @param sessionPresent the session present flag returned (only for MQTT 3.1.1)
|
||||
* @param connack_rc returned integer value of the connack return code
|
||||
* @param buf the raw buffer data, of the correct length determined by the remaining length field
|
||||
* @param len the length in bytes of the data in the supplied buffer
|
||||
* @return error code. 1 is success, 0 is failure
|
||||
*/
|
||||
int MQTTDeserialize_connack(unsigned char* sessionPresent, unsigned char* connack_rc, unsigned char* buf, int buflen){
|
||||
MQTTHeader header = {0};
|
||||
unsigned char* curdata = buf;
|
||||
unsigned char* enddata = NULL;
|
||||
int rc = 0;
|
||||
int mylen;
|
||||
MQTTConnackFlags flags = {0};
|
||||
|
||||
FUNC_ENTRY;
|
||||
header.byte = readChar(&curdata);
|
||||
if (header.bits.type != CONNACK)
|
||||
goto exit;
|
||||
|
||||
curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */
|
||||
enddata = curdata + mylen;
|
||||
if (enddata - curdata < 2)
|
||||
goto exit;
|
||||
|
||||
flags.all = readChar(&curdata);
|
||||
*sessionPresent = flags.bits.sessionpresent;
|
||||
*connack_rc = readChar(&curdata);
|
||||
|
||||
rc = 1;
|
||||
exit:
|
||||
FUNC_EXIT_RC(rc);
|
||||
return rc;
|
||||
}
|
||||
/**
|
||||
* Serializes a 0-length packet into the supplied buffer, ready for writing to a socket
|
||||
* @param buf the buffer into which the packet will be serialized
|
||||
* @param buflen the length in bytes of the supplied buffer, to avoid overruns
|
||||
* @param packettype the message type
|
||||
* @return serialized length, or error if 0
|
||||
*/
|
||||
int MQTTSerialize_zero(unsigned char* buf, int buflen, unsigned char packettype){
|
||||
MQTTHeader header = {0};
|
||||
int rc = -1;
|
||||
unsigned char *ptr = buf;
|
||||
|
||||
FUNC_ENTRY;
|
||||
if (buflen < 2)
|
||||
{
|
||||
rc = MQTTPACKET_BUFFER_TOO_SHORT;
|
||||
goto exit;
|
||||
}
|
||||
header.byte = 0;
|
||||
header.bits.type = packettype;
|
||||
writeChar(&ptr, header.byte); /* write header */
|
||||
|
||||
ptr += MQTTPacket_encode(ptr, 0); /* write remaining length */
|
||||
rc = ptr - buf;
|
||||
exit:
|
||||
FUNC_EXIT_RC(rc);
|
||||
return rc;
|
||||
}
|
||||
/**
|
||||
* Serializes a disconnect packet into the supplied buffer, ready for writing to a socket
|
||||
* @param buf the buffer into which the packet will be serialized
|
||||
* @param buflen the length in bytes of the supplied buffer, to avoid overruns
|
||||
* @return serialized length, or error if 0
|
||||
*/
|
||||
int MQTTSerialize_disconnect(unsigned char* buf, int buflen){
|
||||
return MQTTSerialize_zero(buf, buflen, DISCONNECT);
|
||||
}
|
||||
/**
|
||||
* Serializes a disconnect packet into the supplied buffer, ready for writing to a socket
|
||||
* @param buf the buffer into which the packet will be serialized
|
||||
* @param buflen the length in bytes of the supplied buffer, to avoid overruns
|
||||
* @return serialized length, or error if 0
|
||||
*/
|
||||
int MQTTSerialize_pingreq(unsigned char* buf, int buflen){
|
||||
return MQTTSerialize_zero(buf, buflen, PINGREQ);
|
||||
}
|
||||
@@ -1,125 +0,0 @@
|
||||
#include "StackTrace.h"
|
||||
#include "MQTTPacket.h"
|
||||
#include <string.h>
|
||||
|
||||
#define min(a, b) ((a < b) ? a : b)
|
||||
|
||||
/**
|
||||
* Validates MQTT protocol name and version combinations
|
||||
* @param protocol the MQTT protocol name as an MQTTString
|
||||
* @param version the MQTT protocol version number, as in the connect packet
|
||||
* @return correct MQTT combination? 1 is true, 0 is false
|
||||
*/
|
||||
int MQTTPacket_checkVersion(MQTTString* protocol, int version){
|
||||
int rc = 0;
|
||||
if (version == 3 && memcmp(protocol->lenstring.data, "MQIsdp",
|
||||
min(6, protocol->lenstring.len)) == 0)
|
||||
rc = 1;
|
||||
else if (version == 4 && memcmp(protocol->lenstring.data, "MQTT",
|
||||
min(4, protocol->lenstring.len)) == 0)
|
||||
rc = 1;
|
||||
return rc;
|
||||
}
|
||||
/**
|
||||
* Deserializes the supplied (wire) buffer into connect data structure
|
||||
* @param data the connect data structure to be filled out
|
||||
* @param buf the raw buffer data, of the correct length determined by the remaining length field
|
||||
* @param len the length in bytes of the data in the supplied buffer
|
||||
* @return error code. 1 is success, 0 is failure
|
||||
*/
|
||||
int MQTTDeserialize_connect(MQTTPacket_connectData* data, unsigned char* buf, int len){
|
||||
MQTTHeader header = {0};
|
||||
MQTTConnectFlags flags = {0};
|
||||
unsigned char* curdata = buf;
|
||||
unsigned char* enddata = &buf[len];
|
||||
int rc = 0;
|
||||
MQTTString Protocol;
|
||||
int version;
|
||||
int mylen = 0;
|
||||
|
||||
FUNC_ENTRY;
|
||||
header.byte = readChar(&curdata);
|
||||
if (header.bits.type != CONNECT)
|
||||
goto exit;
|
||||
|
||||
curdata += MQTTPacket_decodeBuf(curdata, &mylen); /* read remaining length */
|
||||
|
||||
if (!readMQTTLenString(&Protocol, &curdata, enddata) ||
|
||||
enddata - curdata < 0) /* do we have enough data to read the protocol version byte? */
|
||||
goto exit;
|
||||
|
||||
version = (int)readChar(&curdata); /* Protocol version */
|
||||
/* If we don't recognize the protocol version, we don't parse the connect packet on the
|
||||
* basis that we don't know what the format will be.
|
||||
*/
|
||||
if (MQTTPacket_checkVersion(&Protocol, version))
|
||||
{
|
||||
flags.all = readChar(&curdata);
|
||||
data->cleansession = flags.bits.cleansession;
|
||||
data->keepAliveInterval = readInt(&curdata);
|
||||
if (!readMQTTLenString(&data->clientID, &curdata, enddata))
|
||||
goto exit;
|
||||
data->willFlag = flags.bits.will;
|
||||
if (flags.bits.will)
|
||||
{
|
||||
data->will.qos = flags.bits.willQoS;
|
||||
data->will.retained = flags.bits.willRetain;
|
||||
if (!readMQTTLenString(&data->will.topicName, &curdata, enddata) ||
|
||||
!readMQTTLenString(&data->will.message, &curdata, enddata))
|
||||
goto exit;
|
||||
}
|
||||
if (flags.bits.username)
|
||||
{
|
||||
if (enddata - curdata < 3 || !readMQTTLenString(&data->username, &curdata, enddata))
|
||||
goto exit; /* username flag set, but no username supplied - invalid */
|
||||
if (flags.bits.password &&
|
||||
(enddata - curdata < 3 || !readMQTTLenString(&data->password, &curdata, enddata)))
|
||||
goto exit; /* password flag set, but no password supplied - invalid */
|
||||
}
|
||||
else if (flags.bits.password)
|
||||
goto exit; /* password flag set without username - invalid */
|
||||
rc = 1;
|
||||
}
|
||||
exit:
|
||||
FUNC_EXIT_RC(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Serializes the connack packet into the supplied buffer.
|
||||
* @param buf the buffer into which the packet will be serialized
|
||||
* @param buflen the length in bytes of the supplied buffer
|
||||
* @param connack_rc the integer connack return code to be used
|
||||
* @param sessionPresent the MQTT 3.1.1 sessionPresent flag
|
||||
* @return serialized length, or error if 0
|
||||
*/
|
||||
int MQTTSerialize_connack(unsigned char* buf, int buflen, unsigned char connack_rc, unsigned char sessionPresent){
|
||||
MQTTHeader header = {0};
|
||||
int rc = 0;
|
||||
unsigned char *ptr = buf;
|
||||
MQTTConnackFlags flags = {0};
|
||||
|
||||
FUNC_ENTRY;
|
||||
if (buflen < 2)
|
||||
{
|
||||
rc = MQTTPACKET_BUFFER_TOO_SHORT;
|
||||
goto exit;
|
||||
}
|
||||
header.byte = 0;
|
||||
header.bits.type = CONNACK;
|
||||
writeChar(&ptr, header.byte); /* write header */
|
||||
|
||||
ptr += MQTTPacket_encode(ptr, 2); /* write remaining length */
|
||||
|
||||
flags.all = 0;
|
||||
flags.bits.sessionpresent = sessionPresent;
|
||||
writeChar(&ptr, flags.all);
|
||||
writeChar(&ptr, connack_rc);
|
||||
|
||||
rc = ptr - buf;
|
||||
exit:
|
||||
FUNC_EXIT_RC(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -1,105 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2014 IBM Corp.
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||
*
|
||||
* The Eclipse Public License is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
* and the Eclipse Distribution License is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* Contributors:
|
||||
* Ian Craggs - initial API and implementation and/or initial documentation
|
||||
*******************************************************************************/
|
||||
|
||||
#include "StackTrace.h"
|
||||
#include "MQTTPacket.h"
|
||||
#include <string.h>
|
||||
|
||||
#define min(a, b) ((a < b) ? 1 : 0)
|
||||
|
||||
/**
|
||||
* Deserializes the supplied (wire) buffer into publish data
|
||||
* @param dup returned integer - the MQTT dup flag
|
||||
* @param qos returned integer - the MQTT QoS value
|
||||
* @param retained returned integer - the MQTT retained flag
|
||||
* @param packetid returned integer - the MQTT packet identifier
|
||||
* @param topicName returned MQTTString - the MQTT topic in the publish
|
||||
* @param payload returned byte buffer - the MQTT publish payload
|
||||
* @param payloadlen returned integer - the length of the MQTT payload
|
||||
* @param buf the raw buffer data, of the correct length determined by the remaining length field
|
||||
* @param buflen the length in bytes of the data in the supplied buffer
|
||||
* @return error code. 1 is success
|
||||
*/
|
||||
int MQTTDeserialize_publish(unsigned char* dup, int* qos, unsigned char* retained, unsigned short* packetid, MQTTString* topicName,
|
||||
unsigned char** payload, int* payloadlen, unsigned char* buf, int buflen){
|
||||
MQTTHeader header = {0};
|
||||
unsigned char* curdata = buf;
|
||||
unsigned char* enddata = NULL;
|
||||
int rc = 0;
|
||||
int mylen = 0;
|
||||
|
||||
FUNC_ENTRY;
|
||||
header.byte = readChar(&curdata);
|
||||
if (header.bits.type != PUBLISH)
|
||||
goto exit;
|
||||
*dup = header.bits.dup;
|
||||
*qos = header.bits.qos;
|
||||
*retained = header.bits.retain;
|
||||
|
||||
curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */
|
||||
enddata = curdata + mylen;
|
||||
|
||||
if (!readMQTTLenString(topicName, &curdata, enddata) ||
|
||||
enddata - curdata < 0) /* do we have enough data to read the protocol version byte? */
|
||||
goto exit;
|
||||
|
||||
if (*qos > 0)
|
||||
*packetid = readInt(&curdata);
|
||||
|
||||
*payloadlen = enddata - curdata;
|
||||
*payload = curdata;
|
||||
rc = 1;
|
||||
exit:
|
||||
FUNC_EXIT_RC(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Deserializes the supplied (wire) buffer into an ack
|
||||
* @param packettype returned integer - the MQTT packet type
|
||||
* @param dup returned integer - the MQTT dup flag
|
||||
* @param packetid returned integer - the MQTT packet identifier
|
||||
* @param buf the raw buffer data, of the correct length determined by the remaining length field
|
||||
* @param buflen the length in bytes of the data in the supplied buffer
|
||||
* @return error code. 1 is success, 0 is failure
|
||||
*/
|
||||
int MQTTDeserialize_ack(unsigned char* packettype, unsigned char* dup, unsigned short* packetid, unsigned char* buf, int buflen){
|
||||
MQTTHeader header = {0};
|
||||
unsigned char* curdata = buf;
|
||||
unsigned char* enddata = NULL;
|
||||
int rc = 0;
|
||||
int mylen;
|
||||
|
||||
FUNC_ENTRY;
|
||||
header.byte = readChar(&curdata);
|
||||
*dup = header.bits.dup;
|
||||
*packettype = header.bits.type;
|
||||
|
||||
curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */
|
||||
enddata = curdata + mylen;
|
||||
|
||||
if (enddata - curdata < 2)
|
||||
goto exit;
|
||||
*packetid = readInt(&curdata);
|
||||
|
||||
rc = 1;
|
||||
exit:
|
||||
FUNC_EXIT_RC(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -1,233 +0,0 @@
|
||||
#include "StackTrace.h"
|
||||
#include "MQTTPacket.h"
|
||||
|
||||
#include "string.h"
|
||||
|
||||
const char* MQTTPacket_names[] =
|
||||
{
|
||||
"RESERVED", "CONNECT", "CONNACK", "PUBLISH", "PUBACK", "PUBREC", "PUBREL",
|
||||
"PUBCOMP", "SUBSCRIBE", "SUBACK", "UNSUBSCRIBE", "UNSUBACK",
|
||||
"PINGREQ", "PINGRESP", "DISCONNECT"
|
||||
};
|
||||
|
||||
const char* MQTTPacket_getName(unsigned short packetid) {
|
||||
return MQTTPacket_names[packetid];
|
||||
}
|
||||
|
||||
int MQTTStringFormat_connect(char* strbuf, int strbuflen, MQTTPacket_connectData* data){
|
||||
int strindex = 0;
|
||||
|
||||
strindex = snprintf(strbuf, strbuflen,
|
||||
"CONNECT MQTT version %d, client id %.*s, clean session %d, keep alive %d",
|
||||
(int)data->MQTTVersion, data->clientID.lenstring.len, data->clientID.lenstring.data,
|
||||
(int)data->cleansession, data->keepAliveInterval);
|
||||
if (data->willFlag)
|
||||
strindex += snprintf(&strbuf[strindex], strbuflen - strindex,
|
||||
", will QoS %d, will retain %d, will topic %.*s, will message %.*s",
|
||||
data->will.qos, data->will.retained,
|
||||
data->will.topicName.lenstring.len, data->will.topicName.lenstring.data,
|
||||
data->will.message.lenstring.len, data->will.message.lenstring.data);
|
||||
if (data->username.lenstring.data && data->username.lenstring.len > 0)
|
||||
strindex += snprintf(&strbuf[strindex], strbuflen - strindex,
|
||||
", user name %.*s", data->username.lenstring.len, data->username.lenstring.data);
|
||||
if (data->password.lenstring.data && data->password.lenstring.len > 0)
|
||||
strindex += snprintf(&strbuf[strindex], strbuflen - strindex,
|
||||
", password %.*s", data->password.lenstring.len, data->password.lenstring.data);
|
||||
return strindex;
|
||||
}
|
||||
|
||||
|
||||
int MQTTStringFormat_connack(char* strbuf, int strbuflen, unsigned char connack_rc, unsigned char sessionPresent){
|
||||
int strindex = snprintf(strbuf, strbuflen, "CONNACK session present %d, rc %d", sessionPresent, connack_rc);
|
||||
return strindex;
|
||||
}
|
||||
|
||||
|
||||
int MQTTStringFormat_publish(char* strbuf, int strbuflen, unsigned char dup, int qos, unsigned char retained,
|
||||
unsigned short packetid, MQTTString topicName, unsigned char* payload, int payloadlen){
|
||||
int strindex = snprintf(strbuf, strbuflen,
|
||||
"PUBLISH dup %d, QoS %d, retained %d, packet id %d, topic %.*s, payload length %d, payload %.*s",
|
||||
dup, qos, retained, packetid,
|
||||
(topicName.lenstring.len < 20) ? topicName.lenstring.len : 20, topicName.lenstring.data,
|
||||
payloadlen, (payloadlen < 20) ? payloadlen : 20, payload);
|
||||
return strindex;
|
||||
}
|
||||
|
||||
|
||||
int MQTTStringFormat_ack(char* strbuf, int strbuflen, unsigned char packettype, unsigned char dup, unsigned short packetid){
|
||||
int strindex = snprintf(strbuf, strbuflen, "%s, packet id %d", MQTTPacket_names[packettype], packetid);
|
||||
if (dup)
|
||||
strindex += snprintf(strbuf + strindex, strbuflen - strindex, ", dup %d", dup);
|
||||
return strindex;
|
||||
}
|
||||
|
||||
|
||||
int MQTTStringFormat_subscribe(char* strbuf, int strbuflen, unsigned char dup, unsigned short packetid, int count,
|
||||
MQTTString topicFilters[], int requestedQoSs[]){
|
||||
return snprintf(strbuf, strbuflen,
|
||||
"SUBSCRIBE dup %d, packet id %d count %d topic %.*s qos %d",
|
||||
dup, packetid, count,
|
||||
topicFilters[0].lenstring.len, topicFilters[0].lenstring.data,
|
||||
requestedQoSs[0]);
|
||||
}
|
||||
|
||||
|
||||
int MQTTStringFormat_suback(char* strbuf, int strbuflen, unsigned short packetid, int count, int* grantedQoSs){
|
||||
return snprintf(strbuf, strbuflen,
|
||||
"SUBACK packet id %d count %d granted qos %d", packetid, count, grantedQoSs[0]);
|
||||
}
|
||||
|
||||
|
||||
int MQTTStringFormat_unsubscribe(char* strbuf, int strbuflen, unsigned char dup, unsigned short packetid,
|
||||
int count, MQTTString topicFilters[]){
|
||||
return snprintf(strbuf, strbuflen,
|
||||
"UNSUBSCRIBE dup %d, packet id %d count %d topic %.*s",
|
||||
dup, packetid, count,
|
||||
topicFilters[0].lenstring.len, topicFilters[0].lenstring.data);
|
||||
}
|
||||
|
||||
|
||||
#if defined(MQTT_CLIENT)
|
||||
char* MQTTFormat_toClientString(char* strbuf, int strbuflen, unsigned char* buf, int buflen){
|
||||
int index = 0;
|
||||
int rem_length = 0;
|
||||
MQTTHeader header = {0};
|
||||
int strindex = 0;
|
||||
|
||||
header.byte = buf[index++];
|
||||
index += MQTTPacket_decodeBuf(&buf[index], &rem_length);
|
||||
|
||||
switch (header.bits.type)
|
||||
{
|
||||
|
||||
case CONNACK:
|
||||
{
|
||||
unsigned char sessionPresent, connack_rc;
|
||||
if (MQTTDeserialize_connack(&sessionPresent, &connack_rc, buf, buflen) == 1)
|
||||
strindex = MQTTStringFormat_connack(strbuf, strbuflen, connack_rc, sessionPresent);
|
||||
}
|
||||
break;
|
||||
case PUBLISH:
|
||||
{
|
||||
unsigned char dup, retained, *payload;
|
||||
unsigned short packetid;
|
||||
int qos, payloadlen;
|
||||
MQTTString topicName = MQTTString_initializer;
|
||||
if (MQTTDeserialize_publish(&dup, &qos, &retained, &packetid, &topicName,
|
||||
&payload, &payloadlen, buf, buflen) == 1)
|
||||
strindex = MQTTStringFormat_publish(strbuf, strbuflen, dup, qos, retained, packetid,
|
||||
topicName, payload, payloadlen);
|
||||
}
|
||||
break;
|
||||
case PUBACK:
|
||||
case PUBREC:
|
||||
case PUBREL:
|
||||
case PUBCOMP:
|
||||
{
|
||||
unsigned char packettype, dup;
|
||||
unsigned short packetid;
|
||||
if (MQTTDeserialize_ack(&packettype, &dup, &packetid, buf, buflen) == 1)
|
||||
strindex = MQTTStringFormat_ack(strbuf, strbuflen, packettype, dup, packetid);
|
||||
}
|
||||
break;
|
||||
case SUBACK:
|
||||
{
|
||||
unsigned short packetid;
|
||||
int maxcount = 1, count = 0;
|
||||
int grantedQoSs[1];
|
||||
if (MQTTDeserialize_suback(&packetid, maxcount, &count, grantedQoSs, buf, buflen) == 1)
|
||||
strindex = MQTTStringFormat_suback(strbuf, strbuflen, packetid, count, grantedQoSs);
|
||||
}
|
||||
break;
|
||||
case UNSUBACK:
|
||||
{
|
||||
unsigned short packetid;
|
||||
if (MQTTDeserialize_unsuback(&packetid, buf, buflen) == 1)
|
||||
strindex = MQTTStringFormat_ack(strbuf, strbuflen, UNSUBACK, 0, packetid);
|
||||
}
|
||||
break;
|
||||
case PINGREQ:
|
||||
case PINGRESP:
|
||||
case DISCONNECT:
|
||||
strindex = snprintf(strbuf, strbuflen, "%s", MQTTPacket_names[header.bits.type]);
|
||||
break;
|
||||
}
|
||||
return strbuf;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(MQTT_SERVER)
|
||||
char* MQTTFormat_toServerString(char* strbuf, int strbuflen, unsigned char* buf, int buflen){
|
||||
int index = 0;
|
||||
int rem_length = 0;
|
||||
MQTTHeader header = {0};
|
||||
int strindex = 0;
|
||||
|
||||
header.byte = buf[index++];
|
||||
index += MQTTPacket_decodeBuf(&buf[index], &rem_length);
|
||||
|
||||
switch (header.bits.type)
|
||||
{
|
||||
case CONNECT:
|
||||
{
|
||||
MQTTPacket_connectData data;
|
||||
int rc;
|
||||
if ((rc = MQTTDeserialize_connect(&data, buf, buflen)) == 1)
|
||||
strindex = MQTTStringFormat_connect(strbuf, strbuflen, &data);
|
||||
}
|
||||
break;
|
||||
case PUBLISH:
|
||||
{
|
||||
unsigned char dup, retained, *payload;
|
||||
unsigned short packetid;
|
||||
int qos, payloadlen;
|
||||
MQTTString topicName = MQTTString_initializer;
|
||||
if (MQTTDeserialize_publish(&dup, &qos, &retained, &packetid, &topicName,
|
||||
&payload, &payloadlen, buf, buflen) == 1)
|
||||
strindex = MQTTStringFormat_publish(strbuf, strbuflen, dup, qos, retained, packetid,
|
||||
topicName, payload, payloadlen);
|
||||
}
|
||||
break;
|
||||
case PUBACK:
|
||||
case PUBREC:
|
||||
case PUBREL:
|
||||
case PUBCOMP:
|
||||
{
|
||||
unsigned char packettype, dup;
|
||||
unsigned short packetid;
|
||||
if (MQTTDeserialize_ack(&packettype, &dup, &packetid, buf, buflen) == 1)
|
||||
strindex = MQTTStringFormat_ack(strbuf, strbuflen, packettype, dup, packetid);
|
||||
}
|
||||
break;
|
||||
case SUBSCRIBE:
|
||||
{
|
||||
unsigned char dup;
|
||||
unsigned short packetid;
|
||||
int maxcount = 1, count = 0;
|
||||
MQTTString topicFilters[1];
|
||||
int requestedQoSs[1];
|
||||
if (MQTTDeserialize_subscribe(&dup, &packetid, maxcount, &count,
|
||||
topicFilters, requestedQoSs, buf, buflen) == 1)
|
||||
strindex = MQTTStringFormat_subscribe(strbuf, strbuflen, dup, packetid, count, topicFilters, requestedQoSs);;
|
||||
}
|
||||
break;
|
||||
case UNSUBSCRIBE:
|
||||
{
|
||||
unsigned char dup;
|
||||
unsigned short packetid;
|
||||
int maxcount = 1, count = 0;
|
||||
MQTTString topicFilters[1];
|
||||
if (MQTTDeserialize_unsubscribe(&dup, &packetid, maxcount, &count, topicFilters, buf, buflen) == 1)
|
||||
strindex = MQTTStringFormat_unsubscribe(strbuf, strbuflen, dup, packetid, count, topicFilters);
|
||||
}
|
||||
break;
|
||||
case PINGREQ:
|
||||
case PINGRESP:
|
||||
case DISCONNECT:
|
||||
strindex = snprintf(strbuf, strbuflen, "%s", MQTTPacket_names[header.bits.type]);
|
||||
break;
|
||||
}
|
||||
strbuf[strbuflen] = '\0';
|
||||
return strbuf;
|
||||
}
|
||||
#endif
|
||||
@@ -1,37 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2014 IBM Corp.
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||
*
|
||||
* The Eclipse Public License is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
* and the Eclipse Distribution License is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* Contributors:
|
||||
* Ian Craggs - initial API and implementation and/or initial documentation
|
||||
*******************************************************************************/
|
||||
|
||||
#if !defined(_MQTTFORMAT_H_)
|
||||
#define _MQTTFORMAT_H_
|
||||
|
||||
#include "StackTrace.h"
|
||||
#include "MQTTPacket.h"
|
||||
|
||||
const char* MQTTPacket_getName(unsigned short packetid);
|
||||
int MQTTStringFormat_connect(char* strbuf, int strbuflen, MQTTPacket_connectData* data);
|
||||
int MQTTStringFormat_connack(char* strbuf, int strbuflen, unsigned char connack_rc, unsigned char sessionPresent);
|
||||
int MQTTStringFormat_publish(char* strbuf, int strbuflen, unsigned char dup, int qos, unsigned char retained,
|
||||
unsigned short packetid, MQTTString topicName, unsigned char* payload, int payloadlen);
|
||||
int MQTTStringFormat_ack(char* strbuf, int strbuflen, unsigned char packettype, unsigned char dup, unsigned short packetid);
|
||||
int MQTTStringFormat_subscribe(char* strbuf, int strbuflen, unsigned char dup, unsigned short packetid, int count,
|
||||
MQTTString topicFilters[], int requestedQoSs[]);
|
||||
int MQTTStringFormat_suback(char* strbuf, int strbuflen, unsigned short packetid, int count, int* grantedQoSs);
|
||||
int MQTTStringFormat_unsubscribe(char* strbuf, int strbuflen, unsigned char dup, unsigned short packetid,
|
||||
int count, MQTTString topicFilters[]);
|
||||
char* MQTTFormat_toClientString(char* strbuf, int strbuflen, unsigned char* buf, int buflen);
|
||||
char* MQTTFormat_toServerString(char* strbuf, int strbuflen, unsigned char* buf, int buflen);
|
||||
|
||||
#endif
|
||||
@@ -1,365 +0,0 @@
|
||||
#include "StackTrace.h"
|
||||
#include "MQTTPacket.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* Encodes the message length according to the MQTT algorithm
|
||||
* @param buf the buffer into which the encoded data is written
|
||||
* @param length the length to be encoded
|
||||
* @return the number of bytes written to buffer
|
||||
*/
|
||||
int MQTTPacket_encode(unsigned char* buf, int length){
|
||||
int rc = 0;
|
||||
|
||||
FUNC_ENTRY;
|
||||
do
|
||||
{
|
||||
char d = length % 128;
|
||||
length /= 128;
|
||||
/* if there are more digits to encode, set the top bit of this digit */
|
||||
if (length > 0)
|
||||
d |= 0x80;
|
||||
buf[rc++] = d;
|
||||
} while (length > 0);
|
||||
FUNC_EXIT_RC(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes the message length according to the MQTT algorithm
|
||||
* @param getcharfn pointer to function to read the next character from the data source
|
||||
* @param value the decoded length returned
|
||||
* @return the number of bytes read from the socket
|
||||
*/
|
||||
int MQTTPacket_decode(int (*getcharfn)(unsigned char*, int), int* value){
|
||||
unsigned char c;
|
||||
int multiplier = 1;
|
||||
int len = 0;
|
||||
#define MAX_NO_OF_REMAINING_LENGTH_BYTES 4
|
||||
|
||||
FUNC_ENTRY;
|
||||
*value = 0;
|
||||
do
|
||||
{
|
||||
int rc = MQTTPACKET_READ_ERROR;
|
||||
|
||||
if (++len > MAX_NO_OF_REMAINING_LENGTH_BYTES)
|
||||
{
|
||||
rc = MQTTPACKET_READ_ERROR; /* bad data */
|
||||
goto exit;
|
||||
}
|
||||
rc = (*getcharfn)(&c, 1);
|
||||
if (rc != 1)
|
||||
goto exit;
|
||||
*value += (c & 127) * multiplier;
|
||||
multiplier *= 128;
|
||||
} while ((c & 128) != 0);
|
||||
exit:
|
||||
FUNC_EXIT_RC(len);
|
||||
return len;
|
||||
}
|
||||
|
||||
int MQTTPacket_len(int rem_len){
|
||||
rem_len += 1; /* header byte */
|
||||
|
||||
/* now remaining_length field */
|
||||
if (rem_len < 128)
|
||||
rem_len += 1;
|
||||
else if (rem_len < 16384)
|
||||
rem_len += 2;
|
||||
else if (rem_len < 2097151)
|
||||
rem_len += 3;
|
||||
else
|
||||
rem_len += 4;
|
||||
return rem_len;
|
||||
}
|
||||
|
||||
static unsigned char* bufptr;
|
||||
int bufchar(unsigned char* c, int count){
|
||||
int i;
|
||||
|
||||
for (i = 0; i < count; ++i)
|
||||
*c = *bufptr++;
|
||||
return count;
|
||||
}
|
||||
|
||||
int MQTTPacket_decodeBuf(unsigned char* buf, int* value){
|
||||
bufptr = buf;
|
||||
return MQTTPacket_decode(bufchar, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates an integer from two bytes read from the input buffer
|
||||
* @param pptr pointer to the input buffer - incremented by the number of bytes used & returned
|
||||
* @return the integer value calculated
|
||||
*/
|
||||
int readInt(unsigned char** pptr){
|
||||
unsigned char* ptr = *pptr;
|
||||
int len = 256*(*ptr) + (*(ptr+1));
|
||||
*pptr += 2;
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads one character from the input buffer.
|
||||
* @param pptr pointer to the input buffer - incremented by the number of bytes used & returned
|
||||
* @return the character read
|
||||
*/
|
||||
char readChar(unsigned char** pptr){
|
||||
char c = **pptr;
|
||||
(*pptr)++;
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes one character to an output buffer.
|
||||
* @param pptr pointer to the output buffer - incremented by the number of bytes used & returned
|
||||
* @param c the character to write
|
||||
*/
|
||||
void writeChar(unsigned char** pptr, char c){
|
||||
**pptr = c;
|
||||
(*pptr)++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes an integer as 2 bytes to an output buffer.
|
||||
* @param pptr pointer to the output buffer - incremented by the number of bytes used & returned
|
||||
* @param anInt the integer to write
|
||||
*/
|
||||
void writeInt(unsigned char** pptr, int anInt){
|
||||
**pptr = (unsigned char)(anInt / 256);
|
||||
(*pptr)++;
|
||||
**pptr = (unsigned char)(anInt % 256);
|
||||
(*pptr)++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a "UTF" string to an output buffer. Converts C string to length-delimited.
|
||||
* @param pptr pointer to the output buffer - incremented by the number of bytes used & returned
|
||||
* @param string the C string to write
|
||||
*/
|
||||
void writeCString(unsigned char** pptr, const char* string){
|
||||
int len = strlen(string);
|
||||
writeInt(pptr, len);
|
||||
memcpy(*pptr, string, len);
|
||||
*pptr += len;
|
||||
}
|
||||
|
||||
int getLenStringLen(char* ptr){
|
||||
int len = 256*((unsigned char)(*ptr)) + (unsigned char)(*(ptr+1));
|
||||
return len;
|
||||
}
|
||||
|
||||
void writeMQTTString(unsigned char** pptr, MQTTString mqttstring){
|
||||
if (mqttstring.lenstring.len > 0)
|
||||
{
|
||||
writeInt(pptr, mqttstring.lenstring.len);
|
||||
memcpy(*pptr, mqttstring.lenstring.data, mqttstring.lenstring.len);
|
||||
*pptr += mqttstring.lenstring.len;
|
||||
}
|
||||
else if (mqttstring.cstring)
|
||||
writeCString(pptr, mqttstring.cstring);
|
||||
else
|
||||
writeInt(pptr, 0);
|
||||
}
|
||||
/**
|
||||
* @param mqttstring the MQTTString structure into which the data is to be read
|
||||
* @param pptr pointer to the output buffer - incremented by the number of bytes used & returned
|
||||
* @param enddata pointer to the end of the data: do not read beyond
|
||||
* @return 1 if successful, 0 if not
|
||||
*/
|
||||
int readMQTTLenString(MQTTString* mqttstring, unsigned char** pptr, unsigned char* enddata){
|
||||
int rc = 0;
|
||||
|
||||
FUNC_ENTRY;
|
||||
/* the first two bytes are the length of the string */
|
||||
if (enddata - (*pptr) > 1) /* enough length to read the integer? */
|
||||
{
|
||||
mqttstring->lenstring.len = readInt(pptr); /* increments pptr to point past length */
|
||||
if (&(*pptr)[mqttstring->lenstring.len] <= enddata)
|
||||
{
|
||||
mqttstring->lenstring.data = (char*)*pptr;
|
||||
*pptr += mqttstring->lenstring.len;
|
||||
rc = 1;
|
||||
}
|
||||
}
|
||||
mqttstring->cstring = NULL;
|
||||
FUNC_EXIT_RC(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the length of the MQTTstring - C string if there is one, otherwise the length delimited string
|
||||
* @param mqttstring the string to return the length of
|
||||
* @return the length of the string
|
||||
*/
|
||||
int MQTTstrlen(MQTTString mqttstring){
|
||||
int rc = 0;
|
||||
|
||||
if (mqttstring.cstring)
|
||||
rc = strlen(mqttstring.cstring);
|
||||
else
|
||||
rc = mqttstring.lenstring.len;
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compares an MQTTString to a C string
|
||||
* @param a the MQTTString to compare
|
||||
* @param bptr the C string to compare
|
||||
* @return boolean - equal or not
|
||||
*/
|
||||
int MQTTPacket_equals(MQTTString* a, char* bptr){
|
||||
int alen = 0,
|
||||
blen = 0;
|
||||
char *aptr;
|
||||
|
||||
if (a->cstring)
|
||||
{
|
||||
aptr = a->cstring;
|
||||
alen = strlen(a->cstring);
|
||||
}
|
||||
else
|
||||
{
|
||||
aptr = a->lenstring.data;
|
||||
alen = a->lenstring.len;
|
||||
}
|
||||
blen = strlen(bptr);
|
||||
|
||||
return (alen == blen) && (strncmp(aptr, bptr, alen) == 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper function to read packet data from some source into a buffer
|
||||
* @param buf the buffer into which the packet will be serialized
|
||||
* @param buflen the length in bytes of the supplied buffer
|
||||
* @param getfn pointer to a function which will read any number of bytes from the needed source
|
||||
* @return integer MQTT packet type, or -1 on error
|
||||
* @note the whole message must fit into the caller's buffer
|
||||
*/
|
||||
int MQTTPacket_read(unsigned char* buf, int buflen, int (*getfn)(unsigned char*, int)){
|
||||
int rc = -1;
|
||||
MQTTHeader header = {0};
|
||||
int len = 0;
|
||||
int rem_len = 0;
|
||||
|
||||
/* 1. 读取头字节。这里面有包类型 */
|
||||
if ((*getfn)(buf, 1) != 1)
|
||||
goto exit;
|
||||
|
||||
len = 1;
|
||||
// 解码
|
||||
/* 2. 读剩下的长度。它本身是可变的 */
|
||||
MQTTPacket_decode(getfn, &rem_len);
|
||||
/* 将原始的剩余长度放回缓冲区 */
|
||||
len += MQTTPacket_encode(buf + 1, rem_len);
|
||||
|
||||
/* 3. read the rest of the buffer using a callback to supply the rest of the data */
|
||||
if((rem_len + len) > buflen)
|
||||
goto exit;
|
||||
if (rem_len && ((*getfn)(buf + len, rem_len) != rem_len))
|
||||
goto exit;
|
||||
|
||||
header.byte = buf[0];
|
||||
rc = header.bits.type;
|
||||
exit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes the message length according to the MQTT algorithm, non-blocking
|
||||
* @param trp pointer to a transport structure holding what is needed to solve getting data from it
|
||||
* @param value the decoded length returned
|
||||
* @return integer the number of bytes read from the socket, 0 for call again, or -1 on error
|
||||
*/
|
||||
static int MQTTPacket_decodenb(MQTTTransport *trp){
|
||||
unsigned char c;
|
||||
int rc = MQTTPACKET_READ_ERROR;
|
||||
|
||||
FUNC_ENTRY;
|
||||
if(trp->len == 0){ /* initialize on first call */
|
||||
trp->multiplier = 1;
|
||||
trp->rem_len = 0;
|
||||
}
|
||||
do {
|
||||
int frc;
|
||||
if (trp->len >= MAX_NO_OF_REMAINING_LENGTH_BYTES)
|
||||
goto exit;
|
||||
if ((frc=(*trp->getfn)(trp->sck, &c, 1)) == -1)
|
||||
goto exit;
|
||||
if (frc == 0){
|
||||
rc = 0;
|
||||
goto exit;
|
||||
}
|
||||
++(trp->len);
|
||||
trp->rem_len += (c & 127) * trp->multiplier;
|
||||
trp->multiplier *= 128;
|
||||
} while ((c & 128) != 0);
|
||||
rc = trp->len;
|
||||
exit:
|
||||
FUNC_EXIT_RC(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to read packet data from some source into a buffer, non-blocking
|
||||
* @param buf the buffer into which the packet will be serialized
|
||||
* @param buflen the length in bytes of the supplied buffer
|
||||
* @param trp pointer to a transport structure holding what is needed to solve getting data from it
|
||||
* @return integer MQTT packet type, 0 for call again, or -1 on error
|
||||
* @note the whole message must fit into the caller's buffer
|
||||
*/
|
||||
int MQTTPacket_readnb(unsigned char* buf, int buflen, MQTTTransport *trp){
|
||||
int rc = -1, frc;
|
||||
MQTTHeader header = {0};
|
||||
|
||||
switch(trp->state){
|
||||
default:
|
||||
trp->state = 0;
|
||||
/*FALLTHROUGH*/
|
||||
case 0:
|
||||
/* read the header byte. This has the packet type in it */
|
||||
if ((frc=(*trp->getfn)(trp->sck, buf, 1)) == -1)
|
||||
goto exit;
|
||||
if (frc == 0)
|
||||
return 0;
|
||||
trp->len = 0;
|
||||
++trp->state;
|
||||
/*FALLTHROUGH*/
|
||||
/* read the remaining length. This is variable in itself */
|
||||
case 1:
|
||||
if((frc=MQTTPacket_decodenb(trp)) == MQTTPACKET_READ_ERROR)
|
||||
goto exit;
|
||||
if(frc == 0)
|
||||
return 0;
|
||||
trp->len = 1 + MQTTPacket_encode(buf + 1, trp->rem_len); /* put the original remaining length back into the buffer */
|
||||
if((trp->rem_len + trp->len) > buflen)
|
||||
goto exit;
|
||||
++trp->state;
|
||||
/*FALLTHROUGH*/
|
||||
case 2:
|
||||
if(trp->rem_len){
|
||||
/* read the rest of the buffer using a callback to supply the rest of the data */
|
||||
if ((frc=(*trp->getfn)(trp->sck, buf + trp->len, trp->rem_len)) == -1)
|
||||
goto exit;
|
||||
if (frc == 0)
|
||||
return 0;
|
||||
trp->rem_len -= frc;
|
||||
trp->len += frc;
|
||||
if(trp->rem_len)
|
||||
return 0;
|
||||
}
|
||||
header.byte = buf[0];
|
||||
rc = header.bits.type;
|
||||
break;
|
||||
}
|
||||
|
||||
exit:
|
||||
trp->state = 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -1,116 +0,0 @@
|
||||
#ifndef _MQTTPACKET_H_
|
||||
#define _MQTTPACKET_H_
|
||||
|
||||
#if defined(__cplusplus) /* If this is a C++ compiler, use C linkage */
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(WIN32_DLL) || defined(WIN64_DLL)
|
||||
#define DLLImport __declspec(dllimport)
|
||||
#define DLLExport __declspec(dllexport)
|
||||
#elif defined(LINUX_SO)
|
||||
#define DLLImport extern
|
||||
#define DLLExport __attribute__ ((visibility ("default")))
|
||||
#else
|
||||
#define DLLImport
|
||||
#define DLLExport
|
||||
#endif
|
||||
|
||||
enum errors
|
||||
{
|
||||
MQTTPACKET_BUFFER_TOO_SHORT = -2,
|
||||
MQTTPACKET_READ_ERROR = -1,
|
||||
MQTTPACKET_READ_COMPLETE
|
||||
};
|
||||
|
||||
enum msgTypes
|
||||
{
|
||||
CONNECT = 1, CONNACK, PUBLISH, PUBACK, PUBREC, PUBREL,
|
||||
PUBCOMP, SUBSCRIBE, SUBACK, UNSUBSCRIBE, UNSUBACK,
|
||||
PINGREQ, PINGRESP, DISCONNECT
|
||||
};
|
||||
|
||||
/**
|
||||
* Bitfields for the MQTT header byte.
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
unsigned char byte; /**< the whole byte */
|
||||
#if defined(REVERSED)
|
||||
struct
|
||||
{
|
||||
unsigned int type : 4; /**< message type nibble */
|
||||
unsigned int dup : 1; /**< DUP flag bit */
|
||||
unsigned int qos : 2; /**< QoS value, 0, 1 or 2 */
|
||||
unsigned int retain : 1; /**< retained flag bit */
|
||||
} bits;
|
||||
#else
|
||||
struct
|
||||
{
|
||||
unsigned int retain : 1; /**< retained flag bit */
|
||||
unsigned int qos : 2; /**< QoS value, 0, 1 or 2 */
|
||||
unsigned int dup : 1; /**< DUP flag bit */
|
||||
unsigned int type : 4; /**< message type nibble */
|
||||
} bits;
|
||||
#endif
|
||||
} MQTTHeader;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int len;
|
||||
char* data;
|
||||
} MQTTLenString;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char* cstring;
|
||||
MQTTLenString lenstring;
|
||||
} MQTTString;
|
||||
|
||||
#define MQTTString_initializer {NULL, {0, NULL}}
|
||||
|
||||
int MQTTstrlen(MQTTString mqttstring);
|
||||
|
||||
#include "MQTTConnect.h"
|
||||
#include "MQTTPublish.h"
|
||||
#include "MQTTSubscribe.h"
|
||||
#include "MQTTUnsubscribe.h"
|
||||
#include "MQTTFormat.h"
|
||||
|
||||
DLLExport int MQTTSerialize_ack(unsigned char* buf, int buflen, unsigned char type, unsigned char dup, unsigned short packetid);
|
||||
DLLExport int MQTTDeserialize_ack(unsigned char* packettype, unsigned char* dup, unsigned short* packetid, unsigned char* buf, int buflen);
|
||||
|
||||
int MQTTPacket_len(int rem_len);
|
||||
DLLExport int MQTTPacket_equals(MQTTString* a, char* b);
|
||||
|
||||
DLLExport int MQTTPacket_encode(unsigned char* buf, int length);
|
||||
int MQTTPacket_decode(int (*getcharfn)(unsigned char*, int), int* value);
|
||||
int MQTTPacket_decodeBuf(unsigned char* buf, int* value);
|
||||
|
||||
int readInt(unsigned char** pptr);
|
||||
char readChar(unsigned char** pptr);
|
||||
void writeChar(unsigned char** pptr, char c);
|
||||
void writeInt(unsigned char** pptr, int anInt);
|
||||
int readMQTTLenString(MQTTString* mqttstring, unsigned char** pptr, unsigned char* enddata);
|
||||
void writeCString(unsigned char** pptr, const char* string);
|
||||
void writeMQTTString(unsigned char** pptr, MQTTString mqttstring);
|
||||
|
||||
DLLExport int MQTTPacket_read(unsigned char* buf, int buflen, int (*getfn)(unsigned char*, int));
|
||||
|
||||
typedef struct {
|
||||
int (*getfn)(void *, unsigned char*, int); /* must return -1 for error, 0 for call again, or the number of bytes read */
|
||||
void *sck; /* pointer to whatever the system may use to identify the transport */
|
||||
int multiplier;
|
||||
int rem_len;
|
||||
int len;
|
||||
char state;
|
||||
}MQTTTransport;
|
||||
|
||||
int MQTTPacket_readnb(unsigned char* buf, int buflen, MQTTTransport *trp);
|
||||
|
||||
#ifdef __cplusplus /* If this is a C++ compiler, use C linkage */
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* MQTTPACKET_H_ */
|
||||
@@ -1,38 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2014 IBM Corp.
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||
*
|
||||
* The Eclipse Public License is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
* and the Eclipse Distribution License is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* Contributors:
|
||||
* Ian Craggs - initial API and implementation and/or initial documentation
|
||||
* Xiang Rong - 442039 Add makefile to Embedded C client
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef MQTTPUBLISH_H_
|
||||
#define MQTTPUBLISH_H_
|
||||
|
||||
#if !defined(DLLImport)
|
||||
#define DLLImport
|
||||
#endif
|
||||
#if !defined(DLLExport)
|
||||
#define DLLExport
|
||||
#endif
|
||||
|
||||
DLLExport int MQTTSerialize_publish(unsigned char* buf, int buflen, unsigned char dup, int qos, unsigned char retained, unsigned short packetid,
|
||||
MQTTString topicName, unsigned char* payload, int payloadlen);
|
||||
|
||||
DLLExport int MQTTDeserialize_publish(unsigned char* dup, int* qos, unsigned char* retained, unsigned short* packetid, MQTTString* topicName,
|
||||
unsigned char** payload, int* payloadlen, unsigned char* buf, int len);
|
||||
|
||||
DLLExport int MQTTSerialize_puback(unsigned char* buf, int buflen, unsigned short packetid);
|
||||
DLLExport int MQTTSerialize_pubrel(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid);
|
||||
DLLExport int MQTTSerialize_pubcomp(unsigned char* buf, int buflen, unsigned short packetid);
|
||||
|
||||
#endif /* MQTTPUBLISH_H_ */
|
||||
@@ -1,145 +0,0 @@
|
||||
#include "MQTTPacket.h"
|
||||
#include "StackTrace.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* Determines the length of the MQTT publish packet that would be produced using the supplied parameters
|
||||
* @param qos the MQTT QoS of the publish (packetid is omitted for QoS 0)
|
||||
* @param topicName the topic name to be used in the publish
|
||||
* @param payloadlen the length of the payload to be sent
|
||||
* @return the length of buffer needed to contain the serialized version of the packet
|
||||
*/
|
||||
int MQTTSerialize_publishLength(int qos, MQTTString topicName, int payloadlen){
|
||||
int len = 0;
|
||||
|
||||
len += 2 + MQTTstrlen(topicName) + payloadlen;
|
||||
if (qos > 0)
|
||||
len += 2; /* packetid */
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Serializes the supplied publish data into the supplied buffer, ready for sending
|
||||
* @param buf the buffer into which the packet will be serialized
|
||||
* @param buflen the length in bytes of the supplied buffer
|
||||
* @param dup integer - the MQTT dup flag
|
||||
* @param qos integer - the MQTT QoS value
|
||||
* @param retained integer - the MQTT retained flag
|
||||
* @param packetid integer - the MQTT packet identifier
|
||||
* @param topicName MQTTString - the MQTT topic in the publish
|
||||
* @param payload byte buffer - the MQTT publish payload
|
||||
* @param payloadlen integer - the length of the MQTT payload
|
||||
* @return the length of the serialized data. <= 0 indicates error
|
||||
*/
|
||||
int MQTTSerialize_publish(unsigned char* buf, int buflen, unsigned char dup, int qos, unsigned char retained, unsigned short packetid,
|
||||
MQTTString topicName, unsigned char* payload, int payloadlen){
|
||||
unsigned char *ptr = buf;
|
||||
MQTTHeader header = {0};
|
||||
int rem_len = 0;
|
||||
int rc = 0;
|
||||
|
||||
FUNC_ENTRY;
|
||||
if (MQTTPacket_len(rem_len = MQTTSerialize_publishLength(qos, topicName, payloadlen)) > buflen)
|
||||
{
|
||||
rc = MQTTPACKET_BUFFER_TOO_SHORT;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
header.bits.type = PUBLISH;
|
||||
header.bits.dup = dup;
|
||||
header.bits.qos = qos;
|
||||
header.bits.retain = retained;
|
||||
writeChar(&ptr, header.byte); /* write header */
|
||||
|
||||
ptr += MQTTPacket_encode(ptr, rem_len); /* write remaining length */;
|
||||
|
||||
writeMQTTString(&ptr, topicName);
|
||||
|
||||
if (qos > 0)
|
||||
writeInt(&ptr, packetid);
|
||||
|
||||
memcpy(ptr, payload, payloadlen);
|
||||
ptr += payloadlen;
|
||||
|
||||
rc = ptr - buf;
|
||||
|
||||
exit:
|
||||
FUNC_EXIT_RC(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Serializes the ack packet into the supplied buffer.
|
||||
* @param buf the buffer into which the packet will be serialized
|
||||
* @param buflen the length in bytes of the supplied buffer
|
||||
* @param type the MQTT packet type
|
||||
* @param dup the MQTT dup flag
|
||||
* @param packetid the MQTT packet identifier
|
||||
* @return serialized length, or error if 0
|
||||
*/
|
||||
int MQTTSerialize_ack(unsigned char* buf, int buflen, unsigned char packettype, unsigned char dup, unsigned short packetid){
|
||||
MQTTHeader header = {0};
|
||||
int rc = 0;
|
||||
unsigned char *ptr = buf;
|
||||
|
||||
FUNC_ENTRY;
|
||||
if (buflen < 4)
|
||||
{
|
||||
rc = MQTTPACKET_BUFFER_TOO_SHORT;
|
||||
goto exit;
|
||||
}
|
||||
header.bits.type = packettype;
|
||||
header.bits.dup = dup;
|
||||
header.bits.qos = (packettype == PUBREL) ? 1 : 0;
|
||||
writeChar(&ptr, header.byte); /* write header */
|
||||
|
||||
ptr += MQTTPacket_encode(ptr, 2); /* write remaining length */
|
||||
writeInt(&ptr, packetid);
|
||||
rc = ptr - buf;
|
||||
exit:
|
||||
FUNC_EXIT_RC(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Serializes a puback packet into the supplied buffer.
|
||||
* @param buf the buffer into which the packet will be serialized
|
||||
* @param buflen the length in bytes of the supplied buffer
|
||||
* @param packetid integer - the MQTT packet identifier
|
||||
* @return serialized length, or error if 0
|
||||
*/
|
||||
int MQTTSerialize_puback(unsigned char* buf, int buflen, unsigned short packetid){
|
||||
return MQTTSerialize_ack(buf, buflen, PUBACK, 0, packetid);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Serializes a pubrel packet into the supplied buffer.
|
||||
* @param buf the buffer into which the packet will be serialized
|
||||
* @param buflen the length in bytes of the supplied buffer
|
||||
* @param dup integer - the MQTT dup flag
|
||||
* @param packetid integer - the MQTT packet identifier
|
||||
* @return serialized length, or error if 0
|
||||
*/
|
||||
int MQTTSerialize_pubrel(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid){
|
||||
return MQTTSerialize_ack(buf, buflen, PUBREL, dup, packetid);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Serializes a pubrel packet into the supplied buffer.
|
||||
* @param buf the buffer into which the packet will be serialized
|
||||
* @param buflen the length in bytes of the supplied buffer
|
||||
* @param packetid integer - the MQTT packet identifier
|
||||
* @return serialized length, or error if 0
|
||||
*/
|
||||
int MQTTSerialize_pubcomp(unsigned char* buf, int buflen, unsigned short packetid){
|
||||
return MQTTSerialize_ack(buf, buflen, PUBCOMP, 0, packetid);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2014 IBM Corp.
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||
*
|
||||
* The Eclipse Public License is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
* and the Eclipse Distribution License is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* Contributors:
|
||||
* Ian Craggs - initial API and implementation and/or initial documentation
|
||||
* Xiang Rong - 442039 Add makefile to Embedded C client
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef MQTTSUBSCRIBE_H_
|
||||
#define MQTTSUBSCRIBE_H_
|
||||
|
||||
#if !defined(DLLImport)
|
||||
#define DLLImport
|
||||
#endif
|
||||
#if !defined(DLLExport)
|
||||
#define DLLExport
|
||||
#endif
|
||||
|
||||
DLLExport int MQTTSerialize_subscribe(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid,
|
||||
int count, MQTTString topicFilters[], int requestedQoSs[]);
|
||||
|
||||
DLLExport int MQTTDeserialize_subscribe(unsigned char* dup, unsigned short* packetid,
|
||||
int maxcount, int* count, MQTTString topicFilters[], int requestedQoSs[], unsigned char* buf, int len);
|
||||
|
||||
DLLExport int MQTTSerialize_suback(unsigned char* buf, int buflen, unsigned short packetid, int count, int* grantedQoSs);
|
||||
|
||||
DLLExport int MQTTDeserialize_suback(unsigned short* packetid, int maxcount, int* count, int grantedQoSs[], unsigned char* buf, int len);
|
||||
|
||||
|
||||
#endif /* MQTTSUBSCRIBE_H_ */
|
||||
@@ -1,118 +0,0 @@
|
||||
#include "MQTTPacket.h"
|
||||
#include "StackTrace.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* Determines the length of the MQTT subscribe packet that would be produced using the supplied parameters
|
||||
* @param count the number of topic filter strings in topicFilters
|
||||
* @param topicFilters the array of topic filter strings to be used in the publish
|
||||
* @return the length of buffer needed to contain the serialized version of the packet
|
||||
*/
|
||||
int MQTTSerialize_subscribeLength(int count, MQTTString topicFilters[]){
|
||||
int i;
|
||||
int len = 2; /* packetid */
|
||||
|
||||
for (i = 0; i < count; ++i)
|
||||
len += 2 + MQTTstrlen(topicFilters[i]) + 1; /* length + topic + req_qos */
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Serializes the supplied subscribe data into the supplied buffer, ready for sending
|
||||
* @param buf the buffer into which the packet will be serialized
|
||||
* @param buflen the length in bytes of the supplied bufferr
|
||||
* @param dup integer - the MQTT dup flag
|
||||
* @param packetid integer - the MQTT packet identifier
|
||||
* @param count - number of members in the topicFilters and reqQos arrays
|
||||
* @param topicFilters - array of topic filter names
|
||||
* @param requestedQoSs - array of requested QoS
|
||||
* @return the length of the serialized data. <= 0 indicates error
|
||||
*/
|
||||
int MQTTSerialize_subscribe(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid, int count,
|
||||
MQTTString topicFilters[], int requestedQoSs[]){
|
||||
unsigned char *ptr = buf;
|
||||
MQTTHeader header = {0};
|
||||
int rem_len = 0;
|
||||
int rc = 0;
|
||||
int i = 0;
|
||||
|
||||
FUNC_ENTRY;
|
||||
if (MQTTPacket_len(rem_len = MQTTSerialize_subscribeLength(count, topicFilters)) > buflen)
|
||||
{
|
||||
rc = MQTTPACKET_BUFFER_TOO_SHORT;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
header.byte = 0;
|
||||
header.bits.type = SUBSCRIBE;
|
||||
header.bits.dup = dup;
|
||||
header.bits.qos = 1;
|
||||
writeChar(&ptr, header.byte); /* write header */
|
||||
|
||||
ptr += MQTTPacket_encode(ptr, rem_len); /* write remaining length */;
|
||||
|
||||
writeInt(&ptr, packetid);
|
||||
|
||||
for (i = 0; i < count; ++i)
|
||||
{
|
||||
writeMQTTString(&ptr, topicFilters[i]);
|
||||
writeChar(&ptr, requestedQoSs[i]);
|
||||
}
|
||||
|
||||
rc = ptr - buf;
|
||||
exit:
|
||||
FUNC_EXIT_RC(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Deserializes the supplied (wire) buffer into suback data
|
||||
* @param packetid returned integer - the MQTT packet identifier
|
||||
* @param maxcount - the maximum number of members allowed in the grantedQoSs array
|
||||
* @param count returned integer - number of members in the grantedQoSs array
|
||||
* @param grantedQoSs returned array of integers - the granted qualities of service
|
||||
* @param buf the raw buffer data, of the correct length determined by the remaining length field
|
||||
* @param buflen the length in bytes of the data in the supplied buffer
|
||||
* @return error code. 1 is success, 0 is failure
|
||||
*/
|
||||
int MQTTDeserialize_suback(unsigned short* packetid, int maxcount, int* count, int grantedQoSs[], unsigned char* buf, int buflen){
|
||||
MQTTHeader header = {0};
|
||||
unsigned char* curdata = buf;
|
||||
unsigned char* enddata = NULL;
|
||||
int rc = 0;
|
||||
int mylen;
|
||||
|
||||
FUNC_ENTRY;
|
||||
header.byte = readChar(&curdata);
|
||||
if (header.bits.type != SUBACK)
|
||||
goto exit;
|
||||
|
||||
curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */
|
||||
enddata = curdata + mylen;
|
||||
if (enddata - curdata < 2)
|
||||
goto exit;
|
||||
|
||||
*packetid = readInt(&curdata);
|
||||
|
||||
*count = 0;
|
||||
while (curdata < enddata)
|
||||
{
|
||||
if (*count > maxcount)
|
||||
{
|
||||
rc = -1;
|
||||
goto exit;
|
||||
}
|
||||
grantedQoSs[(*count)++] = readChar(&curdata);
|
||||
}
|
||||
|
||||
rc = 1;
|
||||
exit:
|
||||
FUNC_EXIT_RC(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
#include "MQTTPacket.h"
|
||||
#include "StackTrace.h"
|
||||
|
||||
#include <string.h>
|
||||
/**
|
||||
* Deserializes the supplied (wire) buffer into subscribe data
|
||||
* @param dup integer returned - the MQTT dup flag
|
||||
* @param packetid integer returned - the MQTT packet identifier
|
||||
* @param maxcount - the maximum number of members allowed in the topicFilters and requestedQoSs arrays
|
||||
* @param count - number of members in the topicFilters and requestedQoSs arrays
|
||||
* @param topicFilters - array of topic filter names
|
||||
* @param requestedQoSs - array of requested QoS
|
||||
* @param buf the raw buffer data, of the correct length determined by the remaining length field
|
||||
* @param buflen the length in bytes of the data in the supplied buffer
|
||||
* @return the length of the serialized data. <= 0 indicates error
|
||||
*/
|
||||
int MQTTDeserialize_subscribe(unsigned char* dup, unsigned short* packetid, int maxcount, int* count, MQTTString topicFilters[],
|
||||
int requestedQoSs[], unsigned char* buf, int buflen){
|
||||
MQTTHeader header = {0};
|
||||
unsigned char* curdata = buf;
|
||||
unsigned char* enddata = NULL;
|
||||
int rc = -1;
|
||||
int mylen = 0;
|
||||
|
||||
FUNC_ENTRY;
|
||||
header.byte = readChar(&curdata);
|
||||
if (header.bits.type != SUBSCRIBE)
|
||||
goto exit;
|
||||
*dup = header.bits.dup;
|
||||
|
||||
curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */
|
||||
enddata = curdata + mylen;
|
||||
|
||||
*packetid = readInt(&curdata);
|
||||
|
||||
*count = 0;
|
||||
while (curdata < enddata)
|
||||
{
|
||||
if (!readMQTTLenString(&topicFilters[*count], &curdata, enddata))
|
||||
goto exit;
|
||||
if (curdata >= enddata) /* do we have enough data to read the req_qos version byte? */
|
||||
goto exit;
|
||||
requestedQoSs[*count] = readChar(&curdata);
|
||||
(*count)++;
|
||||
}
|
||||
|
||||
rc = 1;
|
||||
exit:
|
||||
FUNC_EXIT_RC(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Serializes the supplied suback data into the supplied buffer, ready for sending
|
||||
* @param buf the buffer into which the packet will be serialized
|
||||
* @param buflen the length in bytes of the supplied buffer
|
||||
* @param packetid integer - the MQTT packet identifier
|
||||
* @param count - number of members in the grantedQoSs array
|
||||
* @param grantedQoSs - array of granted QoS
|
||||
* @return the length of the serialized data. <= 0 indicates error
|
||||
*/
|
||||
int MQTTSerialize_suback(unsigned char* buf, int buflen, unsigned short packetid, int count, int* grantedQoSs){
|
||||
MQTTHeader header = {0};
|
||||
int rc = -1;
|
||||
unsigned char *ptr = buf;
|
||||
int i;
|
||||
|
||||
FUNC_ENTRY;
|
||||
if (buflen < 2 + count)
|
||||
{
|
||||
rc = MQTTPACKET_BUFFER_TOO_SHORT;
|
||||
goto exit;
|
||||
}
|
||||
header.byte = 0;
|
||||
header.bits.type = SUBACK;
|
||||
writeChar(&ptr, header.byte); /* write header */
|
||||
|
||||
ptr += MQTTPacket_encode(ptr, 2 + count); /* write remaining length */
|
||||
|
||||
writeInt(&ptr, packetid);
|
||||
|
||||
for (i = 0; i < count; ++i)
|
||||
writeChar(&ptr, grantedQoSs[i]);
|
||||
|
||||
rc = ptr - buf;
|
||||
exit:
|
||||
FUNC_EXIT_RC(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2014 IBM Corp.
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||
*
|
||||
* The Eclipse Public License is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
* and the Eclipse Distribution License is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* Contributors:
|
||||
* Ian Craggs - initial API and implementation and/or initial documentation
|
||||
* Xiang Rong - 442039 Add makefile to Embedded C client
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef MQTTUNSUBSCRIBE_H_
|
||||
#define MQTTUNSUBSCRIBE_H_
|
||||
|
||||
#if !defined(DLLImport)
|
||||
#define DLLImport
|
||||
#endif
|
||||
#if !defined(DLLExport)
|
||||
#define DLLExport
|
||||
#endif
|
||||
|
||||
DLLExport int MQTTSerialize_unsubscribe(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid,
|
||||
int count, MQTTString topicFilters[]);
|
||||
|
||||
DLLExport int MQTTDeserialize_unsubscribe(unsigned char* dup, unsigned short* packetid, int max_count, int* count, MQTTString topicFilters[],
|
||||
unsigned char* buf, int len);
|
||||
|
||||
DLLExport int MQTTSerialize_unsuback(unsigned char* buf, int buflen, unsigned short packetid);
|
||||
|
||||
DLLExport int MQTTDeserialize_unsuback(unsigned short* packetid, unsigned char* buf, int len);
|
||||
|
||||
#endif /* MQTTUNSUBSCRIBE_H_ */
|
||||
@@ -1,87 +0,0 @@
|
||||
#include "MQTTPacket.h"
|
||||
#include "StackTrace.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* Determines the length of the MQTT unsubscribe packet that would be produced using the supplied parameters
|
||||
* @param count the number of topic filter strings in topicFilters
|
||||
* @param topicFilters the array of topic filter strings to be used in the publish
|
||||
* @return the length of buffer needed to contain the serialized version of the packet
|
||||
*/
|
||||
int MQTTSerialize_unsubscribeLength(int count, MQTTString topicFilters[]){
|
||||
int i;
|
||||
int len = 2; /* packetid */
|
||||
|
||||
for (i = 0; i < count; ++i)
|
||||
len += 2 + MQTTstrlen(topicFilters[i]); /* length + topic*/
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Serializes the supplied unsubscribe data into the supplied buffer, ready for sending
|
||||
* @param buf the raw buffer data, of the correct length determined by the remaining length field
|
||||
* @param buflen the length in bytes of the data in the supplied buffer
|
||||
* @param dup integer - the MQTT dup flag
|
||||
* @param packetid integer - the MQTT packet identifier
|
||||
* @param count - number of members in the topicFilters array
|
||||
* @param topicFilters - array of topic filter names
|
||||
* @return the length of the serialized data. <= 0 indicates error
|
||||
*/
|
||||
int MQTTSerialize_unsubscribe(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid,
|
||||
int count, MQTTString topicFilters[]){
|
||||
unsigned char *ptr = buf;
|
||||
MQTTHeader header = {0};
|
||||
int rem_len = 0;
|
||||
int rc = -1;
|
||||
int i = 0;
|
||||
|
||||
FUNC_ENTRY;
|
||||
if (MQTTPacket_len(rem_len = MQTTSerialize_unsubscribeLength(count, topicFilters)) > buflen)
|
||||
{
|
||||
rc = MQTTPACKET_BUFFER_TOO_SHORT;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
header.byte = 0;
|
||||
header.bits.type = UNSUBSCRIBE;
|
||||
header.bits.dup = dup;
|
||||
header.bits.qos = 1;
|
||||
writeChar(&ptr, header.byte); /* write header */
|
||||
|
||||
ptr += MQTTPacket_encode(ptr, rem_len); /* write remaining length */;
|
||||
|
||||
writeInt(&ptr, packetid);
|
||||
|
||||
for (i = 0; i < count; ++i)
|
||||
writeMQTTString(&ptr, topicFilters[i]);
|
||||
|
||||
rc = ptr - buf;
|
||||
exit:
|
||||
FUNC_EXIT_RC(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Deserializes the supplied (wire) buffer into unsuback data
|
||||
* @param packetid returned integer - the MQTT packet identifier
|
||||
* @param buf the raw buffer data, of the correct length determined by the remaining length field
|
||||
* @param buflen the length in bytes of the data in the supplied buffer
|
||||
* @return error code. 1 is success, 0 is failure
|
||||
*/
|
||||
int MQTTDeserialize_unsuback(unsigned short* packetid, unsigned char* buf, int buflen){
|
||||
unsigned char type = 0;
|
||||
unsigned char dup = 0;
|
||||
int rc = 0;
|
||||
|
||||
FUNC_ENTRY;
|
||||
rc = MQTTDeserialize_ack(&type, &dup, packetid, buf, buflen);
|
||||
if (type == UNSUBACK)
|
||||
rc = 1;
|
||||
FUNC_EXIT_RC(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
#include "MQTTPacket.h"
|
||||
#include "StackTrace.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* Deserializes the supplied (wire) buffer into unsubscribe data
|
||||
* @param dup integer returned - the MQTT dup flag
|
||||
* @param packetid integer returned - the MQTT packet identifier
|
||||
* @param maxcount - the maximum number of members allowed in the topicFilters and requestedQoSs arrays
|
||||
* @param count - number of members in the topicFilters and requestedQoSs arrays
|
||||
* @param topicFilters - array of topic filter names
|
||||
* @param buf the raw buffer data, of the correct length determined by the remaining length field
|
||||
* @param buflen the length in bytes of the data in the supplied buffer
|
||||
* @return the length of the serialized data. <= 0 indicates error
|
||||
*/
|
||||
int MQTTDeserialize_unsubscribe(unsigned char* dup, unsigned short* packetid, int maxcount, int* count, MQTTString topicFilters[],
|
||||
unsigned char* buf, int len){
|
||||
MQTTHeader header = {0};
|
||||
unsigned char* curdata = buf;
|
||||
unsigned char* enddata = NULL;
|
||||
int rc = 0;
|
||||
int mylen = 0;
|
||||
|
||||
FUNC_ENTRY;
|
||||
header.byte = readChar(&curdata);
|
||||
if (header.bits.type != UNSUBSCRIBE)
|
||||
goto exit;
|
||||
*dup = header.bits.dup;
|
||||
|
||||
curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */
|
||||
enddata = curdata + mylen;
|
||||
|
||||
*packetid = readInt(&curdata);
|
||||
|
||||
*count = 0;
|
||||
while (curdata < enddata)
|
||||
{
|
||||
if (!readMQTTLenString(&topicFilters[*count], &curdata, enddata))
|
||||
goto exit;
|
||||
(*count)++;
|
||||
}
|
||||
|
||||
rc = 1;
|
||||
exit:
|
||||
FUNC_EXIT_RC(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Serializes the supplied unsuback data into the supplied buffer, ready for sending
|
||||
* @param buf the buffer into which the packet will be serialized
|
||||
* @param buflen the length in bytes of the supplied buffer
|
||||
* @param packetid integer - the MQTT packet identifier
|
||||
* @return the length of the serialized data. <= 0 indicates error
|
||||
*/
|
||||
int MQTTSerialize_unsuback(unsigned char* buf, int buflen, unsigned short packetid){
|
||||
MQTTHeader header = {0};
|
||||
int rc = 0;
|
||||
unsigned char *ptr = buf;
|
||||
|
||||
FUNC_ENTRY;
|
||||
if (buflen < 2)
|
||||
{
|
||||
rc = MQTTPACKET_BUFFER_TOO_SHORT;
|
||||
goto exit;
|
||||
}
|
||||
header.byte = 0;
|
||||
header.bits.type = UNSUBACK;
|
||||
writeChar(&ptr, header.byte); /* write header */
|
||||
|
||||
ptr += MQTTPacket_encode(ptr, 2); /* write remaining length */
|
||||
|
||||
writeInt(&ptr, packetid);
|
||||
|
||||
rc = ptr - buf;
|
||||
exit:
|
||||
FUNC_EXIT_RC(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
#ifndef STACKTRACE_H_
|
||||
#define STACKTRACE_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#define NOSTACKTRACE 1
|
||||
|
||||
#if defined(NOSTACKTRACE)
|
||||
#define FUNC_ENTRY
|
||||
#define FUNC_ENTRY_NOLOG
|
||||
#define FUNC_ENTRY_MED
|
||||
#define FUNC_ENTRY_MAX
|
||||
#define FUNC_EXIT
|
||||
#define FUNC_EXIT_NOLOG
|
||||
#define FUNC_EXIT_MED
|
||||
#define FUNC_EXIT_MAX
|
||||
#define FUNC_EXIT_RC(x)
|
||||
#define FUNC_EXIT_MED_RC(x)
|
||||
#define FUNC_EXIT_MAX_RC(x)
|
||||
|
||||
#else
|
||||
|
||||
#if defined(WIN32)
|
||||
#define inline __inline
|
||||
#define FUNC_ENTRY StackTrace_entry(__FUNCTION__, __LINE__, TRACE_MINIMUM)
|
||||
#define FUNC_ENTRY_NOLOG StackTrace_entry(__FUNCTION__, __LINE__, -1)
|
||||
#define FUNC_ENTRY_MED StackTrace_entry(__FUNCTION__, __LINE__, TRACE_MEDIUM)
|
||||
#define FUNC_ENTRY_MAX StackTrace_entry(__FUNCTION__, __LINE__, TRACE_MAXIMUM)
|
||||
#define FUNC_EXIT StackTrace_exit(__FUNCTION__, __LINE__, NULL, TRACE_MINIMUM)
|
||||
#define FUNC_EXIT_NOLOG StackTrace_exit(__FUNCTION__, __LINE__, -1)
|
||||
#define FUNC_EXIT_MED StackTrace_exit(__FUNCTION__, __LINE__, NULL, TRACE_MEDIUM)
|
||||
#define FUNC_EXIT_MAX StackTrace_exit(__FUNCTION__, __LINE__, NULL, TRACE_MAXIMUM)
|
||||
#define FUNC_EXIT_RC(x) StackTrace_exit(__FUNCTION__, __LINE__, &x, TRACE_MINIMUM)
|
||||
#define FUNC_EXIT_MED_RC(x) StackTrace_exit(__FUNCTION__, __LINE__, &x, TRACE_MEDIUM)
|
||||
#define FUNC_EXIT_MAX_RC(x) StackTrace_exit(__FUNCTION__, __LINE__, &x, TRACE_MAXIMUM)
|
||||
#else
|
||||
#define FUNC_ENTRY StackTrace_entry(__func__, __LINE__, TRACE_MINIMUM)
|
||||
#define FUNC_ENTRY_NOLOG StackTrace_entry(__func__, __LINE__, -1)
|
||||
#define FUNC_ENTRY_MED StackTrace_entry(__func__, __LINE__, TRACE_MEDIUM)
|
||||
#define FUNC_ENTRY_MAX StackTrace_entry(__func__, __LINE__, TRACE_MAXIMUM)
|
||||
#define FUNC_EXIT StackTrace_exit(__func__, __LINE__, NULL, TRACE_MINIMUM)
|
||||
#define FUNC_EXIT_NOLOG StackTrace_exit(__func__, __LINE__, NULL, -1)
|
||||
#define FUNC_EXIT_MED StackTrace_exit(__func__, __LINE__, NULL, TRACE_MEDIUM)
|
||||
#define FUNC_EXIT_MAX StackTrace_exit(__func__, __LINE__, NULL, TRACE_MAXIMUM)
|
||||
#define FUNC_EXIT_RC(x) StackTrace_exit(__func__, __LINE__, &x, TRACE_MINIMUM)
|
||||
#define FUNC_EXIT_MED_RC(x) StackTrace_exit(__func__, __LINE__, &x, TRACE_MEDIUM)
|
||||
#define FUNC_EXIT_MAX_RC(x) StackTrace_exit(__func__, __LINE__, &x, TRACE_MAXIMUM)
|
||||
|
||||
void StackTrace_entry(const char* name, int line, int trace);
|
||||
void StackTrace_exit(const char* name, int line, void* return_value, int trace);
|
||||
|
||||
void StackTrace_printStack(FILE* dest);
|
||||
char* StackTrace_get(unsigned long);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* STACKTRACE_H_ */
|
||||
333
firmware/stm32-esp/user/mqtt/mqtt.c
Normal file
333
firmware/stm32-esp/user/mqtt/mqtt.c
Normal file
@@ -0,0 +1,333 @@
|
||||
#include "mqtt.h"
|
||||
|
||||
/* 数据采用大端模式,高字节先发
|
||||
UTF-8 "长度 + 字符串"
|
||||
|
||||
控制报文包含:固定包头+可变包头+有效负载
|
||||
固定包头 byte1(报文类型(bit7-4)+类型标识(bit3-0)) + byte2(剩余长度,包含可变包头和有效负载长度,最大128字节)
|
||||
两个字节的计算方式:
|
||||
两个字节的计算方式:剩余长度=(Byte1-128)+Byte2*128
|
||||
*/
|
||||
/***计算剩余字节数***/
|
||||
uint8_t by[4] = {0};
|
||||
uint8_t MQTTSCode_CalcSurplusByte(uint32_t str){
|
||||
uint8_t i = 0;
|
||||
do
|
||||
{
|
||||
by[i] = str%128;
|
||||
str = str/128;
|
||||
if(str > 0)
|
||||
{
|
||||
by[i] = by[i] | 128;
|
||||
i++;
|
||||
}
|
||||
} while(str > 0);
|
||||
return i;
|
||||
}
|
||||
|
||||
MQTT_ConnectData_t MQTT_ConnectData;
|
||||
static uint8_t StringData[500] = {0};
|
||||
static uint8_t StringLen = 0;
|
||||
static uint16_t waittime = 200;
|
||||
static uint16_t NewSite = 0;
|
||||
// 连接服务器
|
||||
uint8_t MQTTSCode_Connect(void) {
|
||||
waittime = 500;
|
||||
|
||||
memset((void *)StringData, 0, sizeof(StringData));
|
||||
|
||||
/*固定包头*/
|
||||
StringData[0] = (uint8_t)(CONNECT<<4) + 0;// 固定帧头
|
||||
StringData[1] = 0x00;// 剩余长度值
|
||||
/***可变包头***/
|
||||
// 协议名
|
||||
StringData[2] = 0x00;
|
||||
StringData[3] = 0x04;
|
||||
StringData[4] = 'M';
|
||||
StringData[5] = 'Q';
|
||||
StringData[6] = 'T';
|
||||
StringData[7] = 'T';
|
||||
|
||||
// 协议版本V3.1.1
|
||||
StringData[8] = 0x04;
|
||||
|
||||
/* 连接标识 使能用户名和密码校验,不使用遗嘱,不保留会话
|
||||
* 1bit 清理会话
|
||||
* 2bit 遗嘱标识
|
||||
* 3bit 遗嘱QoS
|
||||
* 4bit 遗嘱QoS
|
||||
* 5bit 遗嘱保留
|
||||
* 6bit 用户名标识
|
||||
* 7bit 密码标识
|
||||
*/
|
||||
StringData[9] = 0xC2;
|
||||
|
||||
// 保活时间
|
||||
StringData[10] = (uint8_t)(MQTT_ConnectData.keepAlive>>8);
|
||||
StringData[11] = (uint8_t)(MQTT_ConnectData.keepAlive>>0);
|
||||
|
||||
// 客户端ID
|
||||
NewSite = 12;
|
||||
StringLen = strlen((const char*)MQTT_ConnectData.clientID);
|
||||
StringData[NewSite] = (uint8_t)(StringLen>>8);
|
||||
StringData[NewSite+1] = (uint8_t)(StringLen>>0);
|
||||
memcpy( &StringData[NewSite+2], MQTT_ConnectData.clientID, StringLen);
|
||||
NewSite = NewSite + 2 + StringLen;
|
||||
|
||||
// 用户名
|
||||
StringLen = strlen((const char*)MQTT_ConnectData.username);
|
||||
StringData[NewSite] = (uint8_t)(StringLen>>8);
|
||||
StringData[NewSite+1]= (uint8_t)(StringLen>>0);
|
||||
memcpy( &StringData[NewSite+2], MQTT_ConnectData.username, StringLen);
|
||||
NewSite = NewSite + 2 + StringLen;
|
||||
|
||||
// 密码
|
||||
StringLen = strlen((const char*)MQTT_ConnectData.password);
|
||||
StringData[NewSite] = (uint8_t)(StringLen>>8);
|
||||
StringData[NewSite+1] = (uint8_t)(StringLen>>0);
|
||||
memcpy( &StringData[NewSite+2], MQTT_ConnectData.password, StringLen);
|
||||
NewSite = NewSite + 2 + StringLen;
|
||||
|
||||
// 剩余长度
|
||||
if(NewSite < 127)
|
||||
StringData[1] = NewSite - 2;
|
||||
else
|
||||
return 1;
|
||||
|
||||
UART2ReadFlag = 0;
|
||||
memset((void *)UART2ReadBuf, 0, sizeof(UART2ReadBuf));
|
||||
|
||||
Dev_UART2SendStr(StringData, NewSite, 0);
|
||||
|
||||
// 等待回应
|
||||
if(waittime) {
|
||||
while(--waittime)
|
||||
{
|
||||
Delay_ms(10);
|
||||
if(UART2ReadFlag&0x8000)
|
||||
{
|
||||
if(((UART2ReadBuf[0]>>4)==CONNACK)&&(UART2ReadBuf[1]==2))
|
||||
{
|
||||
if(UART2ReadBuf[3]==0){
|
||||
UART2ReadFlag = 0;
|
||||
return 0;
|
||||
}
|
||||
else{
|
||||
UART2ReadFlag = 0;
|
||||
while(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(waittime==0)
|
||||
return 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
// 订阅 服务质量
|
||||
uint8_t MQTTSCode_Subscribe(char *topic, uint8_t qos, uint8_t bsf) {
|
||||
waittime = 500;
|
||||
|
||||
memset((void *)StringData, 0, sizeof(StringData));
|
||||
|
||||
/*固定包头*/
|
||||
StringData[0] = (uint8_t)(SUBSCRIBE<<4) + (uint8_t)(1<<1);// 固定帧头
|
||||
StringData[1] = 0x00;// 剩余长度值
|
||||
/*可变包头*/
|
||||
// 报文标识符
|
||||
NewSite = 2;
|
||||
StringData[NewSite] = (uint8_t)(bsf>>8);
|
||||
StringData[NewSite+1] = (uint8_t)(bsf>>0);
|
||||
NewSite = NewSite + 2;
|
||||
// 有效负载
|
||||
// 主题
|
||||
StringLen = strlen((const char*)topic);
|
||||
StringData[NewSite] = (uint8_t)(StringLen>>8);
|
||||
StringData[NewSite+1] = (uint8_t)(StringLen>>0);
|
||||
memcpy( &StringData[NewSite+2], topic, StringLen);
|
||||
NewSite = NewSite + 2 + StringLen;
|
||||
// 服务质量
|
||||
StringData[NewSite] = (uint8_t)(qos>>0);
|
||||
NewSite = NewSite + 1;
|
||||
|
||||
// 剩余长度
|
||||
if(NewSite < 127)
|
||||
StringData[1] = NewSite - 2;
|
||||
else
|
||||
return 1;
|
||||
|
||||
UART2ReadFlag = 0;
|
||||
memset((void *)UART2ReadBuf, 0, sizeof(UART2ReadBuf));
|
||||
|
||||
Dev_UART2SendStr(StringData, NewSite, 0);
|
||||
|
||||
if(waittime) {
|
||||
while(--waittime)
|
||||
{
|
||||
Delay_ms(10);
|
||||
if(UART2ReadFlag&0x8000)
|
||||
{
|
||||
if((UART2ReadBuf[0]>>4)==SUBACK)
|
||||
{
|
||||
UART2ReadFlag = 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(waittime==0)
|
||||
return 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
// 发布,暂定负载小于100字节
|
||||
// qos 0最多发送一次,1至少分发一次,2只分发一次
|
||||
uint16_t wait = 0;
|
||||
uint16_t byte1 = 0,byte2 = 0;
|
||||
uint8_t MQTTSCode_Publish(char *topic, char *payload, uint16_t payloadLen, uint8_t dup, uint8_t qos, uint16_t bsf) {
|
||||
waittime = 500;
|
||||
|
||||
memset((void *)StringData, 0, sizeof(StringData));
|
||||
|
||||
/*固定包头*/
|
||||
StringData[0] = (uint8_t)(PUBLISH<<4) + (uint8_t)(dup<<3) + (uint8_t)(qos<<1);// 固定帧头
|
||||
StringData[1] = 0x00;// 剩余长度值
|
||||
/*可变包头*/
|
||||
// 主题名
|
||||
NewSite = 2;
|
||||
StringLen = strlen((const char*)topic);
|
||||
StringData[NewSite] = (uint8_t)(StringLen>>8);
|
||||
StringData[NewSite+1] = (uint8_t)(StringLen>>0);
|
||||
memcpy( &StringData[NewSite+2], topic, StringLen);
|
||||
NewSite = NewSite + 2 + StringLen;
|
||||
|
||||
// 报文标识符
|
||||
if((qos==1) || (qos==2)) {
|
||||
StringData[NewSite] = (uint8_t)(bsf>>8);
|
||||
StringData[NewSite+1] = (uint8_t)(bsf>>0);
|
||||
NewSite = NewSite + 2;
|
||||
}
|
||||
// 有效负载
|
||||
StringLen = payloadLen;
|
||||
if(StringLen > 0) {
|
||||
memcpy( &StringData[NewSite], payload, StringLen);
|
||||
NewSite = NewSite + StringLen;
|
||||
}
|
||||
// 剩余长度
|
||||
byte1 = 0;
|
||||
byte2 = 0;
|
||||
if(NewSite <= 129) {
|
||||
StringData[1] = NewSite - 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
wait = NewSite - 2;
|
||||
byte1 = wait%128;
|
||||
wait = wait/128;
|
||||
if(wait > 0)
|
||||
{
|
||||
byte1 = byte1 | 128;
|
||||
byte2 = wait%128;
|
||||
StringData[1] = byte1;
|
||||
}
|
||||
}
|
||||
UART2ReadFlag = 0;
|
||||
memset((void *)UART2ReadBuf, 0, sizeof(UART2ReadBuf));
|
||||
Dev_UART2SendStr(StringData, NewSite, byte2);
|
||||
|
||||
// 没有回复消息
|
||||
if((qos==1)||(qos==2)) {
|
||||
if(waittime) {
|
||||
while(--waittime)
|
||||
{
|
||||
Delay_ms(10);
|
||||
if(UART2ReadFlag&0x8000)
|
||||
{
|
||||
if(((UART2ReadBuf[0]>>4)==PUBACK)&&(UART2ReadBuf[1]==2)&&(qos==1))
|
||||
{
|
||||
UART2ReadFlag = 0;
|
||||
return 0;
|
||||
}
|
||||
// if(((UART2ReadBuf[0]>>4)==PUBREC)&&(UART2ReadBuf[1]==2)&&(qos==2))
|
||||
// {
|
||||
// UART2ReadFlag = 0;
|
||||
// return 0;
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
if(waittime==0)
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
// 心跳 服务质量
|
||||
uint8_t MQTTSCode_KeepAlive(void) {
|
||||
waittime = 500;
|
||||
|
||||
memset((void *)StringData, 0, sizeof(StringData));
|
||||
|
||||
/*固定包头*/
|
||||
StringData[0] = (uint8_t)(PINGREQ<<4) + 0;// 固定帧头
|
||||
StringData[1] = 0x00;
|
||||
|
||||
NewSite = 2;
|
||||
|
||||
// 剩余长度
|
||||
if(NewSite < 127)
|
||||
StringData[1] = NewSite - 2;
|
||||
else
|
||||
return 1;
|
||||
|
||||
UART2ReadFlag = 0;
|
||||
memset((void *)UART2ReadBuf, 0, sizeof(UART2ReadBuf));
|
||||
|
||||
Dev_UART2SendStr(StringData, NewSite, 0);
|
||||
|
||||
if(waittime) {
|
||||
while(--waittime)
|
||||
{
|
||||
Delay_ms(10);
|
||||
if(UART2ReadFlag&0x8000)
|
||||
{
|
||||
if((UART2ReadBuf[0]>>4)==PINGRESP)
|
||||
{
|
||||
UART2ReadFlag = 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(waittime==0)
|
||||
return 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
// 断开连接
|
||||
uint8_t MQTTSCode_DisConnect(void) {
|
||||
|
||||
memset((void *)StringData, 0, sizeof(StringData));
|
||||
|
||||
/*固定包头*/
|
||||
StringData[0] = (uint8_t)(DISCONNECT<<4) + 0;// 固定帧头
|
||||
StringData[1] = 0x00; // 剩余长度值
|
||||
|
||||
NewSite = 2;
|
||||
|
||||
// 剩余长度
|
||||
if(NewSite < 127)
|
||||
StringData[1] = NewSite - 2;
|
||||
else
|
||||
return 1;
|
||||
|
||||
UART2ReadFlag = 0;
|
||||
memset((void *)UART2ReadBuf, 0, sizeof(UART2ReadBuf));
|
||||
|
||||
Dev_UART2SendStr(StringData, NewSite, 0);
|
||||
|
||||
// 断开网络连接
|
||||
|
||||
return 0;
|
||||
}
|
||||
56
firmware/stm32-esp/user/mqtt/mqtt.h
Normal file
56
firmware/stm32-esp/user/mqtt/mqtt.h
Normal file
@@ -0,0 +1,56 @@
|
||||
#ifndef _MQTT_H_
|
||||
#define _MQTT_H_
|
||||
|
||||
#include "stm32f10x.h"
|
||||
|
||||
#include "esp8266_uart2.h"
|
||||
|
||||
#include "stdio.h"
|
||||
|
||||
#include "string.h"
|
||||
|
||||
#include "stdarg.h"
|
||||
|
||||
#include "cJSON.h"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CONNECT = 1,
|
||||
CONNACK = 2,
|
||||
|
||||
PUBLISH = 3,
|
||||
PUBACK = 4,
|
||||
PUBREC = 5,
|
||||
PUBREL = 6,
|
||||
PUBCOMP = 7,
|
||||
|
||||
SUBSCRIBE = 8,
|
||||
SUBACK = 9,
|
||||
UNSUBSCRIBE = 10,
|
||||
UNSUBACK = 11,
|
||||
|
||||
PINGREQ = 12,
|
||||
PINGRESP = 13,
|
||||
DISCONNECT = 14
|
||||
}msgTypes;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned short keepAlive;
|
||||
|
||||
char clientID[50];
|
||||
char username[50];
|
||||
char password[50];
|
||||
} MQTT_ConnectData_t;
|
||||
extern MQTT_ConnectData_t MQTT_ConnectData;
|
||||
|
||||
uint8_t MQTTSCode_Connect(void);
|
||||
/*订阅 服务质量*/
|
||||
uint8_t MQTTSCode_Subscribe(char *topic, uint8_t qos, uint8_t bsf);
|
||||
/*发布,暂定负载小于100字节*/
|
||||
uint8_t MQTTSCode_Publish(char *topic, char *payload, uint16_t payloadLen, uint8_t dup, uint8_t qos, uint16_t bsf);
|
||||
uint8_t MQTTSCode_KeepAlive(void); // 心跳 服务质量
|
||||
uint8_t MQTTSCode_DisConnect(void);// 断开连接
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include "dev_work.h"
|
||||
|
||||
void Dev_ScanExtIndicate(void)
|
||||
{
|
||||
void Dev_ScanExtIndicate(void) {
|
||||
/*开机检测*/
|
||||
if(DevParam.RunPhase==0)
|
||||
{
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
#include "esp8266_uart2.h"
|
||||
|
||||
//检测应答命令
|
||||
static uint8_t* ESP8266_CheckCmd(uint8_t *str)
|
||||
{
|
||||
static uint8_t* ESP8266_CheckCMD(uint8_t *str){
|
||||
char *strx = 0;
|
||||
if(UART2ReadFlag&0x8000)
|
||||
{
|
||||
@@ -15,19 +14,19 @@ static uint8_t* ESP8266_CheckCmd(uint8_t *str)
|
||||
//cmd:发送的命令字符串
|
||||
//ack:期待的应答结果,如果为空,则表示不需要等待应答
|
||||
//返回值:0,发送成功 1,发送失败
|
||||
static uint8_t ESP8266_SendCmd(uint8_t *cmd,uint8_t *ack,uint16_t waittime) {
|
||||
uint8_t ESP8266_SendCMD(uint8_t *cmd,uint8_t *ack,uint16_t waittime) {
|
||||
UART2ReadFlag = 0;
|
||||
memset((void *)UART2ReadBuf, 0, sizeof(UART2ReadBuf));
|
||||
|
||||
Dev_UART2SendStr("%s\r\n", cmd);//发送命令
|
||||
if(ack&&waittime) //需要等待应答
|
||||
Dev_UART2SendStr(cmd, 0, 0);
|
||||
if(ack&&waittime)
|
||||
{
|
||||
while(--waittime) //等待倒计时
|
||||
while(--waittime)
|
||||
{
|
||||
Delay_ms(10);
|
||||
if(UART2ReadFlag&0x8000)
|
||||
{
|
||||
if(ESP8266_CheckCmd(ack))
|
||||
if(ESP8266_CheckCMD(ack))
|
||||
{
|
||||
UART2ReadFlag = 0;
|
||||
return 0;
|
||||
@@ -46,9 +45,8 @@ static uint8_t ESP8266_SendCmd(uint8_t *cmd,uint8_t *ack,uint16_t waittime) {
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
uint8_t ESP8266_SendStr(char* fmt,...)
|
||||
{
|
||||
uint8_t tbuf[200] = {0};
|
||||
uint8_t ESP8266_SendStr(char* fmt,...){
|
||||
uint8_t tbuf[300] = {0};
|
||||
uint16_t i = 0,j = 0;
|
||||
|
||||
va_list ap;
|
||||
@@ -67,8 +65,7 @@ uint8_t ESP8266_SendStr(char* fmt,...)
|
||||
|
||||
return 0;
|
||||
}
|
||||
uint8_t ESP8266_SendData(uint8_t *tbuf, uint16_t len)
|
||||
{
|
||||
uint8_t ESP8266_SendData(uint8_t *tbuf, uint16_t len){
|
||||
uint16_t i = 0;
|
||||
for( i = 0; i < len; i++)
|
||||
{
|
||||
@@ -82,13 +79,13 @@ uint8_t ESP8266_SendData(uint8_t *tbuf, uint16_t len)
|
||||
void ESP8266_GetLocalIP(uint8_t* ipbuf){
|
||||
uint8_t *p,*p1;
|
||||
|
||||
if(ESP8266_SendCmd( (uint8_t *)"AT+CIFSR", (uint8_t *)"OK", 50))
|
||||
if(ESP8266_SendCMD( (uint8_t *)"AT+CIFSR\r\n", (uint8_t *)"OK", 50))
|
||||
{
|
||||
ipbuf[0] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
p = ESP8266_CheckCmd((uint8_t *)"\"");
|
||||
p = ESP8266_CheckCMD((uint8_t *)"\"");
|
||||
p1 = (uint8_t *)strstr((const char*)(p+1),"\"");
|
||||
*p1=0;
|
||||
sprintf((char*)ipbuf,"%s",p+1);
|
||||
@@ -105,12 +102,12 @@ uint8_t ESP8266_QuitTrans(void){
|
||||
while(USART_GetFlagStatus(USART2,USART_FLAG_TC)==RESET){};
|
||||
USART_SendData(USART2, '+');
|
||||
Delay_ms(500); //等待500ms
|
||||
return ESP8266_SendCmd((uint8_t *)"AT",(uint8_t *)"OK",20);//退出透传判断
|
||||
return ESP8266_SendCMD((uint8_t *)"AT\r\n",(uint8_t *)"OK",20);//退出透传判断
|
||||
}
|
||||
|
||||
//获取连接状态 0,未连接;1,连接成功.
|
||||
uint8_t ESP8266_ConstaCheck(void){
|
||||
while(ESP8266_SendCmd((uint8_t *)"AT+CIPSTATUS",(uint8_t *)"OK",50));
|
||||
while(ESP8266_SendCMD((uint8_t *)"AT+CIPSTATUS\r\n",(uint8_t *)"OK",50));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -123,26 +120,26 @@ uint8_t ESP8266_APInit(char *name, char *password){
|
||||
Delay_ms(1000);
|
||||
Delay_ms(1000);
|
||||
|
||||
while(ESP8266_SendCmd((uint8_t *)"AT",(uint8_t *)"OK",200))
|
||||
while(ESP8266_SendCMD((uint8_t *)"AT\r\n",(uint8_t *)"OK",200))
|
||||
{//退出透传
|
||||
ESP8266_QuitTrans();
|
||||
|
||||
//关闭透传模式
|
||||
ESP8266_SendCmd((uint8_t *)"AT+CIPMODE=0",(uint8_t *)"OK",200);
|
||||
ESP8266_SendCMD((uint8_t *)"AT+CIPMODE=0\r\n",(uint8_t *)"OK",200);
|
||||
Delay_ms(1000);
|
||||
}
|
||||
|
||||
// 关闭回显
|
||||
while(ESP8266_SendCmd((uint8_t *)"ATE0",(uint8_t *)"OK",200));
|
||||
while(ESP8266_SendCMD((uint8_t *)"ATE0\r\n",(uint8_t *)"OK",200));
|
||||
|
||||
// 设置波特率
|
||||
while(ESP8266_SendCmd((uint8_t *)"AT+UART=115200,8,1,0,0",(uint8_t *)"OK",200));
|
||||
while(ESP8266_SendCMD((uint8_t *)"AT+UART=115200,8,1,0,0\r\n",(uint8_t *)"OK",200));
|
||||
|
||||
Delay_ms(10);
|
||||
|
||||
// 设置WIFI AP模式
|
||||
while(ESP8266_SendCmd((uint8_t *)"AT+CWMODE=2",(uint8_t *)"OK",200));
|
||||
while(ESP8266_SendCmd((uint8_t *)"AT+RST",(uint8_t *)"OK",200));
|
||||
while(ESP8266_SendCMD((uint8_t *)"AT+CWMODE=2\r\n",(uint8_t *)"OK",200));
|
||||
while(ESP8266_SendCMD((uint8_t *)"AT+RST\r\n",(uint8_t *)"OK",200));
|
||||
|
||||
// 延时4秒等待重启成功
|
||||
Delay_ms(1000);
|
||||
@@ -151,17 +148,17 @@ uint8_t ESP8266_APInit(char *name, char *password){
|
||||
Delay_ms(1000);
|
||||
|
||||
memset(Sbuf, 0 , sizeof(Sbuf));
|
||||
sprintf((char*)Sbuf, "AT+CWSAP=\"%s\",\"%s\",1,4", name, password);
|
||||
while(ESP8266_SendCmd(Sbuf, (uint8_t *)"OK", 1000));
|
||||
sprintf((char*)Sbuf, "AT+CWSAP=\"%s\",\"%s\",1,4\r\n", name, password);
|
||||
while(ESP8266_SendCMD(Sbuf, (uint8_t *)"OK", 1000));
|
||||
|
||||
#ifdef TCP_Mode
|
||||
|
||||
#endif
|
||||
#ifdef UDP_Mode
|
||||
while(ESP8266_SendCmd((uint8_t *)"AT+CIPMUX=0",(uint8_t *)"OK",200));
|
||||
while(ESP8266_SendCmd((uint8_t *)"AT+CIPSTART=\"UDP\",\"255.255.255.255\",60156,42254,0",(uint8_t *)"OK",500));
|
||||
while(ESP8266_SendCmd((uint8_t *)"AT+CIPMODE=1",(uint8_t *)"OK",300));
|
||||
while(ESP8266_SendCmd((uint8_t *)"AT+CIPSEND",(uint8_t *)"OK",200));
|
||||
while(ESP8266_SendCMD((uint8_t *)"AT+CIPMUX=0\r\n",(uint8_t *)"OK",200));
|
||||
while(ESP8266_SendCMD((uint8_t *)"AT+CIPSTART=\"UDP\",\"255.255.255.255\",60156,42254,0\r\n",(uint8_t *)"OK",500));
|
||||
while(ESP8266_SendCMD((uint8_t *)"AT+CIPMODE=1\r\n",(uint8_t *)"OK",300));
|
||||
while(ESP8266_SendCMD((uint8_t *)"AT+CIPSEND\r\n",(uint8_t *)"OK",200));
|
||||
#endif
|
||||
|
||||
UART2ReadFlag = 0;
|
||||
@@ -172,24 +169,33 @@ uint8_t ESP8266_STAConnect(char *name, char *password){
|
||||
uint8_t Sbuf[60] ={0};
|
||||
|
||||
memset(Sbuf, 0 , sizeof(Sbuf));
|
||||
sprintf((char*)Sbuf,"AT+CWJAP=\"%s\",\"%s\"", name, password);
|
||||
if(ESP8266_SendCmd( Sbuf, (uint8_t *)"WIFI GOT IP", 100)){
|
||||
sprintf((char*)Sbuf,"AT+CWJAP=\"%s\",\"%s\"\r\n", name, password);
|
||||
if(ESP8266_SendCMD( Sbuf, (uint8_t *)"WIFI GOT IP", 100)){
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
#ifdef TCP_Mode
|
||||
while(ESP8266_SendCmd((uint8_t *)"AT+CIPMUX=0",(uint8_t *)"OK",200));
|
||||
while(ESP8266_SendCmd((uint8_t *)"AT+CIPSTART=\"TCP\",\"192.168.0.102\",8086",(uint8_t *)"OK",200));
|
||||
while(ESP8266_SendCmd((uint8_t *)"AT+CIPMODE=1",(uint8_t *)"OK",200));
|
||||
while(ESP8266_SendCmd((uint8_t *)"AT+CIPSEND",(uint8_t *)"OK",20));
|
||||
#endif
|
||||
#ifdef UDP_Mode
|
||||
while(ESP8266_SendCmd((uint8_t *)"AT+CIPMUX=0",(uint8_t *)"OK",200));
|
||||
while(ESP8266_SendCmd((uint8_t *)"AT+CIPSTART=\"UDP\",\"192.168.1.6\",8086,8086,0",(uint8_t *)"OK",200));
|
||||
while(ESP8266_SendCmd((uint8_t *)"AT+CIPMODE=1",(uint8_t *)"OK",200));
|
||||
while(ESP8266_SendCmd((uint8_t *)"AT+CIPSEND",(uint8_t *)"OK",20));
|
||||
#endif
|
||||
|
||||
else
|
||||
{
|
||||
#ifdef MQTT_AT
|
||||
|
||||
#elif MQTT_SCode
|
||||
|
||||
#elif TCP_Mode
|
||||
while(ESP8266_SendCMD((uint8_t *)"AT+CIPMUX=0\r\n",(uint8_t *)"OK",200));
|
||||
while(ESP8266_SendCMD((uint8_t *)"AT+CIPSTART=\"TCP\",\"192.168.0.102\",8086\r\n",(uint8_t *)"OK",200));
|
||||
while(ESP8266_SendCMD((uint8_t *)"AT+CIPMODE=1\r\n",(uint8_t *)"OK",200));
|
||||
while(ESP8266_SendCMD((uint8_t *)"AT+CIPSEND\r\n",(uint8_t *)"OK",20));
|
||||
UART2ReadFlag = 0;
|
||||
memset((void *)UART2ReadBuf, 0, sizeof(UART2ReadBuf));
|
||||
return 0;
|
||||
#elif UDP_Mode
|
||||
while(ESP8266_SendCMD((uint8_t *)"AT+CIPMUX=0\r\n",(uint8_t *)"OK",200));
|
||||
while(ESP8266_SendCMD((uint8_t *)"AT+CIPSTART=\"UDP\",\"192.168.1.6\",8086,8086,0\r\n",(uint8_t *)"OK",200));
|
||||
while(ESP8266_SendCMD((uint8_t *)"AT+CIPMODE=1\r\n",(uint8_t *)"OK",200));
|
||||
while(ESP8266_SendCMD((uint8_t *)"AT+CIPSEND\r\n",(uint8_t *)"OK",20));
|
||||
UART2ReadFlag = 0;
|
||||
memset((void *)UART2ReadBuf, 0, sizeof(UART2ReadBuf));
|
||||
return 0;
|
||||
#endif
|
||||
UART2ReadFlag = 0;
|
||||
memset((void *)UART2ReadBuf, 0, sizeof(UART2ReadBuf));
|
||||
return 0;
|
||||
@@ -202,33 +208,30 @@ uint8_t ESP8266_STAInit(void){
|
||||
// 延时2秒等待串口初始化完成
|
||||
Delay_ms(1000);
|
||||
Delay_ms(1000);
|
||||
while(ESP8266_SendCmd((uint8_t *)"AT",(uint8_t *)"OK",200))
|
||||
while(ESP8266_SendCMD((uint8_t *)"AT\r\n",(uint8_t *)"OK",200))
|
||||
{
|
||||
//退出透传
|
||||
ESP8266_QuitTrans();
|
||||
|
||||
//关闭透传模式
|
||||
ESP8266_SendCmd((uint8_t *)"AT+CIPMODE=0",(uint8_t *)"OK",200);
|
||||
ESP8266_SendCMD((uint8_t *)"AT+CIPMODE=0\r\n",(uint8_t *)"OK",200);
|
||||
Delay_ms(800);
|
||||
}
|
||||
// 关闭回显
|
||||
while(ESP8266_SendCmd((uint8_t *)"ATE0",(uint8_t *)"OK",200));
|
||||
while(ESP8266_SendCMD((uint8_t *)"ATE0\r\n",(uint8_t *)"OK",200));
|
||||
|
||||
// 设置波特率
|
||||
while(ESP8266_SendCmd((uint8_t *)"AT+UART=115200,8,1,0,0",(uint8_t *)"OK",200));
|
||||
while(ESP8266_SendCMD((uint8_t *)"AT+UART=115200,8,1,0,0\r\n",(uint8_t *)"OK",200));
|
||||
|
||||
Delay_ms(10);
|
||||
|
||||
// 设置WIFI STA模式
|
||||
while(ESP8266_SendCmd((uint8_t *)"AT+CWMODE=1",(uint8_t *)"OK",200));
|
||||
while(ESP8266_SendCmd((uint8_t *)"AT+RST",(uint8_t *)"OK",200));
|
||||
while(ESP8266_SendCMD((uint8_t *)"AT+CWMODE=1\r\n",(uint8_t *)"OK",200));
|
||||
while(ESP8266_SendCMD((uint8_t *)"AT+RST\r\n",(uint8_t *)"OK",200));
|
||||
|
||||
Delay_ms(1000);
|
||||
Delay_ms(1000);
|
||||
Delay_ms(1000);
|
||||
Delay_ms(1000);
|
||||
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#define UDP_Mode 1
|
||||
|
||||
uint8_t ESP8266_SendStr(char* fmt,...);
|
||||
uint8_t ESP8266_SendCMD(uint8_t *cmd,uint8_t *ack,uint16_t waittime);
|
||||
uint8_t ESP8266_SendData(uint8_t *tbuf, uint16_t len);
|
||||
uint8_t ESP8266_APInit(char *name, char *password);
|
||||
uint8_t ESP8266_STAInit(void);
|
||||
|
||||
@@ -1,109 +1,42 @@
|
||||
#include "esp8266_work.h"
|
||||
|
||||
/****************************
|
||||
/*************************************************************
|
||||
配网流程
|
||||
1、将无线设备初始化为AP模式,默认设置为
|
||||
2、
|
||||
// 配置 MQTT 用户属性
|
||||
// AT+MQTTUSERCFG=0,1,"8bf209cd00704760b7a60b2f71be9d8c","test","123456",0,0,""\r\n
|
||||
// 配置 MQTT 连接属性
|
||||
// AT+MQTTCONNCFG=0,120,0,"","",0,0\r\n
|
||||
// 连接/查询 MQTT Broker
|
||||
// AT+MQTTCONN=0,"106.12.9.213",1883,0\r\n
|
||||
// 发布主题
|
||||
// {"deviceNum":"7CDFA1049ADA","categoryId":2,"firmwareVersion":"1.0","ownerId":"1"}
|
||||
// AT+MQTTPUB=0,"device_info","{"deviceNum":"E8DB84933050","categoryId":1,"firmwareVersion":"1.0","ownerId":"1"}",0,0\r\n
|
||||
// 订阅/查询主题
|
||||
// AT+MQTTSUB=0,"status/set/E8DB84933050",1\r\n
|
||||
// 取消订阅主题
|
||||
// AT+MQTTUNSUB=0,"status/set/E8DB84933050"
|
||||
// 关闭连接, 释放资源
|
||||
// AT+MQTTCLEAN=0
|
||||
****************************/
|
||||
static uint8_t NetWorkFlow = 1;
|
||||
static uint32_t Nport = 0;
|
||||
static uint8_t Nssid[20] = {0};
|
||||
static uint8_t Npassword[20] = {0};
|
||||
2、AT+CWJAP="CMCC-LI","092413131li"
|
||||
// 配置 MQTT 用户属性
|
||||
// AT+MQTTUSERCFG=0,1,"8bf209cd00704760b7a60b2f71be9d8c","test","12345678",0,0,""
|
||||
// 配置 MQTT 连接属性
|
||||
// AT+MQTTCONNCFG=0,120,0,"","",0,0
|
||||
// 连接/查询 MQTT Broker
|
||||
// AT+MQTTCONN=0,"106.12.9.213",1883,0
|
||||
// 发布主题
|
||||
// {"deviceNum":"E8DB84933056","categoryId":2,"firmwareVersion":"1.0","ownerId":"1"}
|
||||
// AT+MQTTPUB=0,"device_info","{\"deviceNum\":\"E8DB8493312\"\\,\"categoryId\":1\\,\"firmwareVersion\":\"1.0\"\\,\"ownerId\":\"1\"}",0,0
|
||||
// AT+MQTTPUB=0,"device_info","{\"deviceNum\":\"E8DB8493312\"\\,\"categoryId\":1\\,\"firmwareVersion\":\"1.0\"\\,\"ownerId\":\"1\"}",0,0\r\n
|
||||
// 订阅/查询主题
|
||||
// AT+MQTTSUB=0,"status/set/E8DB84933056",0
|
||||
// 取消订阅
|
||||
// AT+MQTTUNSUB=0,"status/set/E8DB84933050"
|
||||
// 关闭连接, 释放资源
|
||||
// AT+MQTTCLEAN=0
|
||||
************************************************************/
|
||||
uint8_t NetWorkFlow = 1;
|
||||
|
||||
#ifdef MQTT_SCode
|
||||
MQTTPacket_connectData MQTT_ConnectData = MQTTPacket_connectData_initializer;
|
||||
char MQTT_ClientId[150] = {0};
|
||||
char MQTT_Username[65] = {0};
|
||||
char MQTT_Password[65] = {0};
|
||||
volatile uint16_t MQTT_ReadBufLen = 0;
|
||||
#endif
|
||||
uint8_t Wssid[20] = "";
|
||||
uint8_t Wpassword[20] = "";
|
||||
|
||||
int ESP8266_WaitData(unsigned char* buf, int count)
|
||||
{
|
||||
while(1)
|
||||
{
|
||||
if(UART2ReadFlag&0x8000)
|
||||
{
|
||||
memcpy(buf, (void*)&UART2ReadBuf[MQTT_ReadBufLen], count);
|
||||
MQTT_ReadBufLen += count;
|
||||
return count;
|
||||
}
|
||||
Delay_ms(10);
|
||||
}
|
||||
}
|
||||
#ifdef MQTT_SCode
|
||||
uint8_t MQTT_UserSubscribe(char *pSubTopic) {
|
||||
uint8_t buf[200] = {0};
|
||||
uint32_t buflen = sizeof(buf);
|
||||
int32_t msgid = 1;
|
||||
int32_t req_qos = 0; // 服务质量
|
||||
char MQTT_ServerIP[20] = "106.12.9.213";
|
||||
uint32_t MQTT_ServerPort = 1883;
|
||||
|
||||
MQTTString topicString = MQTTString_initializer;
|
||||
topicString.cstring = pSubTopic;
|
||||
|
||||
// 订阅格式化
|
||||
MQTTSerialize_subscribe(buf, buflen, 0, msgid, 1, &topicString, &req_qos);
|
||||
|
||||
// 发送订阅
|
||||
UART2ReadFlag = 0;
|
||||
ESP8266_SendStr((char *)buf);
|
||||
if (MQTTPacket_read(buf, buflen, ESP8266_WaitData)==SUBACK) /* wait for suback */
|
||||
{
|
||||
unsigned short submsgid;
|
||||
int subcount;
|
||||
int granted_qos;
|
||||
static char MQTT_DeviceID[20] = "E8DB84933299";
|
||||
static char MQTT_ClientID[100] = "user";
|
||||
static char MQTT_Username[20] = "test";
|
||||
static char MQTT_Password[20] = "123456";
|
||||
|
||||
MQTTDeserialize_suback(&submsgid, 1, &subcount, &granted_qos, buf, buflen);
|
||||
if (granted_qos != 0)
|
||||
{
|
||||
//Sys_SendLog("granted qos != 0, %d\n", granted_qos);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Sys_SendLog("granted qos = 0\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//Sys_SendLog("no suback received!\r\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef MQTT_SCode
|
||||
// MQTT_Publish("/mqtt/topic/0", "hello0");
|
||||
void MQTT_UserPublish(char *pPubTopic, char *payload, int payloadlen) {
|
||||
uint8_t buf[400] = {0};
|
||||
int buflen = sizeof(buf);
|
||||
MQTTString topicString = MQTTString_initializer;
|
||||
int len = 0;
|
||||
|
||||
topicString.cstring = pPubTopic;
|
||||
len += MQTTSerialize_publish((unsigned char *)(buf + len), buflen - len, 0, 0, 0, 0, topicString, (unsigned char *)payload, payloadlen);
|
||||
ESP8266_SendStr((char *)buf);
|
||||
}
|
||||
#endif
|
||||
uint8_t buf[400] = {0};
|
||||
int buflen = 0;
|
||||
void ESP8266_NetWorkFlow(void)
|
||||
{
|
||||
uint8_t PublishData[500] = {0};
|
||||
int len = 0;
|
||||
void ESP8266_NetWorkFlow(void) {
|
||||
// 第一步,初始化为AP
|
||||
if(NetWorkFlow == 1) {
|
||||
ESP8266_APInit("XiaoYi_IOT_AirBox", "asdqwe9867");
|
||||
@@ -113,114 +46,181 @@ void ESP8266_NetWorkFlow(void)
|
||||
else if(NetWorkFlow == 2) {
|
||||
if(DevParam.ESP8266SendTime >= 2000)
|
||||
{
|
||||
ESP8266_SendStr("{\"code\":\"0\",\"msg\":\"start connect\"}");
|
||||
ESP8266_SendStr("{\"code\":0,\"msg\":\"start connect\"}");
|
||||
DevParam.ESP8266SendTime = 0;
|
||||
}
|
||||
}
|
||||
// 第三步,返回接受成功信息
|
||||
else if(NetWorkFlow == 3) {
|
||||
ESP8266_SendStr("{\"code\":\"1\",\"msg\":\"getWifiInfo:success\"}");
|
||||
ESP8266_SendStr("{\"code\":1,\"msg\":\"getWifiInfo:success\"}");
|
||||
NetWorkFlow = 4;
|
||||
}
|
||||
// 第四步,连接家庭无线
|
||||
else if(NetWorkFlow == 4) {
|
||||
ESP8266_STAInit();
|
||||
while(ESP8266_STAConnect((char *)Nssid, (char *)Npassword));
|
||||
while(ESP8266_STAConnect((char *)Wssid, (char *)Wpassword));
|
||||
NetWorkFlow = 5;
|
||||
}
|
||||
// 第五步,配置MQTT
|
||||
else if(NetWorkFlow == 5) {
|
||||
/*********模拟MQTT指令**************/
|
||||
#ifdef MQTT_SCode
|
||||
// MQTT_ConnectData.MQTTVersion = 4; // 3.1.1
|
||||
// MQTT_ConnectData.keepAliveInterval = 60; // 设置心跳包间隔时间
|
||||
// MQTT_ConnectData.clientID.cstring = (char *)MQTT_ClientId;// 客户端ID
|
||||
// MQTT_ConnectData.username.cstring = (char *)MQTT_Username;// 用户名
|
||||
// MQTT_ConnectData.password.cstring = (char *)MQTT_Password;// 密码
|
||||
// MQTT_ConnectData.cleansession = 0; // 清除会话
|
||||
MQTT_ConnectData.keepAlive = 120; // 心跳包,单位秒
|
||||
strcpy( MQTT_ConnectData.clientID, MQTT_ClientID);// 客户端ID
|
||||
strcpy( MQTT_ConnectData.username, MQTT_Username);// 用户名
|
||||
strcpy( MQTT_ConnectData.password, MQTT_Password);// 密码
|
||||
|
||||
//rc = aiotMqttSign(product_key, device_name, device_secret, \
|
||||
//MQTT_ConnectData.clientID.cstring, MQTT_ConnectData.username.cstring, MQTT_ConnectData.password.cstring);
|
||||
//if (rc < 0) {
|
||||
//Sys_SendLog("aiotMqttSign -%0x4x\n", -rc);
|
||||
//return -1;
|
||||
//}
|
||||
/***连接服务器***/
|
||||
while(ESP8266_SendCMD((uint8_t *)"AT+CIPMUX=0\r\n",(uint8_t *)"OK",200));
|
||||
memset((void *)PublishData, 0, sizeof(PublishData));
|
||||
sprintf((char *)PublishData,"AT+CIPSTART=\"TCP\",\"%s\",%d\r\n", MQTT_ServerIP, MQTT_ServerPort);
|
||||
while(ESP8266_SendCMD((uint8_t *)PublishData, (uint8_t *)"OK", 500));
|
||||
while(ESP8266_SendCMD((uint8_t *)"AT+CIPMODE=1\r\n",(uint8_t *)"OK",200));
|
||||
while(ESP8266_SendCMD((uint8_t *)"AT+CIPSEND\r\n",(uint8_t *)"OK",200));
|
||||
|
||||
/***登录服务器***/
|
||||
while(MQTTSCode_Connect());
|
||||
|
||||
// 网络连接
|
||||
//char *host = "a1ykSq0uPgd.iot-as-mqtt.cn-shanghai.aliyuncs.com";
|
||||
//int port = 1883;
|
||||
//transport_open( host, port);
|
||||
|
||||
// 发送 登录数据
|
||||
// 将连接字符串格式化一下,现在还没有发送
|
||||
// memset(buf, 0 ,sizeof(buf));
|
||||
// buflen = sizeof(buf);
|
||||
//
|
||||
// MQTTSerialize_connect( buf, buflen, &MQTT_ConnectData);
|
||||
// UART2ReadFlag = 0;
|
||||
// ESP8266_SendStr((char *)buf);
|
||||
|
||||
// 等待connack
|
||||
// if (MQTTPacket_read(buf, buflen, ESP8266_WaitData) == CONNACK){
|
||||
// unsigned char sessionPresent, connack_rc;
|
||||
// if (MQTTDeserialize_connack(&sessionPresent, &connack_rc, buf, buflen) != 1 || connack_rc != 0)
|
||||
// {
|
||||
// //Sys_SendLog("Unable to connect,return code %d\r\n", connack_rc);
|
||||
// //return -1;
|
||||
// }
|
||||
// }
|
||||
/*订阅*/
|
||||
// MQTT_UserSubscribe("status/set/7CDFA1049ADA"); //更新设备状态
|
||||
// MQTT_UserSubscribe("status/get/7CDFA1049ADA"); //获取设备状态
|
||||
// MQTT_UserSubscribe("setting/set/7CDFA1049ADA");//更新设备配置
|
||||
// MQTT_UserSubscribe("setting/get/7CDFA1049ADA");//获取设备配置
|
||||
/***订阅服务器对状态设置***/
|
||||
memset((void *)PublishData, 0, sizeof(PublishData));
|
||||
sprintf((char *)PublishData,"status/set/%s", MQTT_DeviceID);
|
||||
while(MQTTSCode_Subscribe((char *)PublishData, 0, 12));
|
||||
#endif
|
||||
/********************************/
|
||||
/*********AT指令*****************/
|
||||
#ifdef MQTT_AT
|
||||
|
||||
// 1,配置 MQTT 用户属性
|
||||
memset((void *)PublishData, 0, sizeof(PublishData));
|
||||
sprintf((char *)PublishData,"AT+MQTTUSERCFG=0,1,\"%s\",\"%s\",\"%s\",0,0,\"\"\r\n",\
|
||||
MQTT_ClientID, MQTT_Username, MQTT_Password);
|
||||
while(ESP8266_SendCMD((uint8_t *)PublishData, (uint8_t *)"OK", 500));
|
||||
|
||||
// 2,配置 MQTT 连接属性
|
||||
memset((void *)PublishData, 0, sizeof(PublishData));
|
||||
sprintf((char *)PublishData,"AT+MQTTCONNCFG=0,120,0,\"\",\"\",0,0\r\n");
|
||||
while(ESP8266_SendCMD((uint8_t *)PublishData, (uint8_t *)"OK", 500));
|
||||
|
||||
// 3,连接/查询服务器
|
||||
//memset((void *)PublishData, 0, sizeof(PublishData));
|
||||
//sprintf((char *)PublishData,"AT+MQTTCONN=0,\"%s\",1883,0\r\n",\
|
||||
// MQTT_ServerIP);
|
||||
//while(ESP8266_SendCMD((uint8_t *)"AT+MQTTCONN?\r\n", (uint8_t *)"OK", 500));
|
||||
while(ESP8266_SendCMD((uint8_t *)"AT+MQTTCONN=0,\"106.12.9.213\",1883,0\r\n", (uint8_t *)"OK", 300));
|
||||
|
||||
// 4,发布注册设备信息Publish
|
||||
//memset((void *)PublishData, 0, sizeof(PublishData));
|
||||
//sprintf((char *)PublishData,"AT+MQTTPUB=0,\"%s\",\"{\\\"deviceNum\\\":\\\"%s\\\"\\,\\\"categoryId\\\":1\\,\\\"firmwareVersion\\\":\\\"1.0\\\"\\,\\\"ownerId\\\":\\\"1\\\"}\",0,0\r\n",\
|
||||
// "device_info" ,MQTT_DeviceID);
|
||||
//while(ESP8266_SendCMD(PublishData, (uint8_t *)"OK", 500));
|
||||
|
||||
// 发布设备上线(设备状态)
|
||||
memset((void *)PublishData, 0, sizeof(PublishData));
|
||||
sprintf((char *)PublishData,"AT+MQTTPUB=0,\"%s\",\"{\\\"deviceNum\\\":\\\"%s\\\"\\,\\\"isOnline\\\":1\\,\\\"rssi\\\":-73\\,\\\"airTemperature\\\":%d\\,\\\"remark\\\":\\\"\\\"}\",0,0\r\n",\
|
||||
"status" ,MQTT_DeviceID, DevParam.BatSOC);
|
||||
while(ESP8266_SendCMD(PublishData, (uint8_t *)"OK", 500));
|
||||
|
||||
// 发布设备遗嘱
|
||||
// memset((void *)PublishData, 0, sizeof(PublishData));
|
||||
// sprintf((char *)PublishData,"AT+MQTTPUB=0,\"offline\",\"{\\\"deviceNum\\\":\\\"%s\\\"\\,\\\"isOnline\\\":0\\,\\\"remark\\\":\\\"\\\"}\",0,0\r\n",\
|
||||
// MQTT_DeviceID);
|
||||
// while(ESP8266_SendCMD(PublishData, (uint8_t *)"OK", 500));
|
||||
|
||||
// 发布设备配置
|
||||
memset((void *)PublishData, 0, sizeof(PublishData));
|
||||
sprintf((char *)PublishData,"AT+MQTTPUB=0,\"status\",\"{\\\"deviceNum\\\":\\\"%s\\\"\\,\\\"isReset\\\":0\\,\\\"remark\\\":\\\"\\\"}\",0,0\r\n",\
|
||||
MQTT_DeviceID);
|
||||
while(ESP8266_SendCMD(PublishData, (uint8_t *)"OK", 500));
|
||||
|
||||
// 5,订阅
|
||||
// // 更新设备设置状态
|
||||
// memset((void *)PublishData, 0, sizeof(PublishData));
|
||||
// sprintf((char *)PublishData,"AT+MQTTSUB=0,\"status\\\/set\\\/%s\", MQTT_DeviceID);
|
||||
// while(ESP8266_SendCMD((uint8_t *)PublishData, (uint8_t *)"OK", 500));
|
||||
// 订阅获取设备状态
|
||||
memset((void *)PublishData, 0, sizeof(PublishData));
|
||||
sprintf((char *)PublishData,"AT+MQTTSUB=0,\"status\\/set\\/%s\",0\r\n", MQTT_DeviceID);
|
||||
while(ESP8266_SendCMD((uint8_t *)PublishData, (uint8_t *)"OK", 500));
|
||||
// // 更新设备配置
|
||||
// memset((void *)PublishData, 0, sizeof(PublishData));
|
||||
// sprintf((char *)PublishData,"AT+MQTTSUB=0,\"setting/set/%s\",\"\",0,0\r\n", MQTT_DeviceID);
|
||||
// while(ESP8266_SendCMD((uint8_t *)PublishData, (uint8_t *)"OK", 500));
|
||||
// // 获取设备配置
|
||||
// memset((void *)PublishData, 0, sizeof(PublishData));
|
||||
// sprintf((char *)PublishData,"AT+MQTTSUB=0,\"setting/get/%s\",\"\",0,0\r\n", MQTT_DeviceID);
|
||||
// while(ESP8266_SendCMD((uint8_t *)PublishData, (uint8_t *)"OK", 200));
|
||||
#endif
|
||||
NetWorkFlow = 10;
|
||||
/********************************/
|
||||
}
|
||||
else if(NetWorkFlow == 10)
|
||||
{
|
||||
// 第十步,发布消息
|
||||
else if(NetWorkFlow == 10) {
|
||||
/********************************/
|
||||
#ifdef MQTT_SCode
|
||||
// if(DevParam.ESP8266SendTime >= 2000)
|
||||
// {
|
||||
// MQTTSerialize_pingreq(buf, buflen);// 发送心跳
|
||||
// ESP8266_SendStr((char *)buf);
|
||||
// DevParam.ESP8266SendTime = 0;
|
||||
// }
|
||||
// 发布设备状态
|
||||
// else if(DevParam.ESP8266SendTime>=1500){
|
||||
// // /a1ykSq0uPgd/qmvH76OCy2FeGp9DDMPx/user/update
|
||||
// // 0x00 00000001 0032 0100 001223
|
||||
// char txBuf[30] = {0};
|
||||
// char txLen = 0;
|
||||
// //txBuf[txLen++] = COMMAND_REPORT;// 属性上报
|
||||
// txBuf[txLen++] = 0x00;txBuf[txLen++] = 0x00;txBuf[txLen++] = 0x00;txBuf[txLen++] = 0x01;// ID
|
||||
// //txBuf[txLen++] = (uint8_t)(DeviceData.prop_int16 >> 8);txBuf[txLen++] = (uint8_t)(DeviceData.prop_int16 >> 0); // INT16
|
||||
// //txBuf[txLen++] = DeviceData.prop_bool; // BOOL
|
||||
// //txBuf[txLen++] = (uint8_t)(DeviceData.prop_int16 >> 8);txBuf[txLen++] = (uint8_t)(DeviceData.prop_int16 >> 0);// FLOAT
|
||||
|
||||
// MQTT_UserPublish("device_info", txBuf, txLen);
|
||||
// DevParam.ESP8266SendTime = 0;
|
||||
// }
|
||||
#endif
|
||||
if(DevParam.MQTTSendTime >= 2000)
|
||||
{
|
||||
// 定时发布设备状态
|
||||
memset((void *)PublishData, 0, sizeof(PublishData));
|
||||
len = sprintf((char *)PublishData,"{\"deviceNum\":\"%s\",\"isOnline\":1,\"airTemperature\":%d,\"remark\":\"\"}",\
|
||||
MQTT_DeviceID, DevParam.tes);
|
||||
if(len > 0)
|
||||
{
|
||||
while(MQTTSCode_Publish("status", (char *)PublishData, len, 0, 1, 10));
|
||||
memset((void *)UART2ReadBuf, 0, sizeof(UART2ReadBuf));
|
||||
}
|
||||
DevParam.MQTTSendTime = 0;
|
||||
}
|
||||
#endif
|
||||
/********************************/
|
||||
/********************************/
|
||||
#ifdef MQTT_AT
|
||||
if(DevParam.MQTTSendTime >= 5000)
|
||||
{
|
||||
// 定时发布设备状态
|
||||
memset((void *)PublishData, 0, sizeof(PublishData));
|
||||
sprintf((char *)PublishData,"AT+MQTTPUB=0,\"%s\",\"{\\\"deviceNum\\\":\\\"%s\\\"\\,\\\"isOnline\\\":1\\,\\\"rssi\\\":-73\\,\\\"airTemperature\\\":%d\\,\\\"remark\\\":\\\"\\\"}\",0,0\r\n",\
|
||||
"status" ,MQTT_DeviceID, DevParam.BatSOC);
|
||||
while(ESP8266_SendCMD(PublishData, (uint8_t *)"OK", 500));
|
||||
memset((void *)UART2ReadBuf, 0, sizeof(UART2ReadBuf));
|
||||
DevParam.MQTTSendTime = 0;
|
||||
}
|
||||
#endif
|
||||
/********************************/
|
||||
}
|
||||
}
|
||||
char mystrstr(char *haystack, char *needle) {
|
||||
uint16_t i = 0,j = 0;
|
||||
for(i = 0;;i++)
|
||||
{
|
||||
if(haystack[i]==needle[0])
|
||||
{
|
||||
for(j = 0;;j++)
|
||||
{
|
||||
if(haystack[i+j]==needle[j])
|
||||
{
|
||||
if(needle[j+1] == '\0')
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
if((haystack[i]=='\r') && (haystack[i+1]=='\n'))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cJSON *root = NULL;
|
||||
char JsonString[100] = {0};
|
||||
uint16_t init = 0;
|
||||
uint16_t i = 0;
|
||||
|
||||
uint8_t rbuf[256] = {0};
|
||||
uint8_t rlen = 0;
|
||||
char JsonString[500] = {0};
|
||||
uint16_t i = 0,j = 0,slen = 0;
|
||||
void ESP8266_NetReceiveInfor(void) {
|
||||
if(UART2ReadFlag&0x8000)
|
||||
{
|
||||
// 配网解析
|
||||
if(NetWorkFlow == 2) {
|
||||
// {"port":"60156","ssid":"xxx","password":"xxxx"}
|
||||
if(UART2ReadBuf[0] == '{')
|
||||
{
|
||||
// {"port":60156,"ssid":"xxx","password":"xxxx"}
|
||||
if(UART2ReadBuf[0] == '{') {
|
||||
memset(JsonString, 0, sizeof(JsonString));
|
||||
for(i = 0;;i++)
|
||||
{
|
||||
JsonString[i] = UART2ReadBuf[i];
|
||||
@@ -234,50 +234,105 @@ void ESP8266_NetReceiveInfor(void) {
|
||||
UART3ReadFlag = 0;
|
||||
return;
|
||||
}
|
||||
Nport = cJSON_GetObjectItem(root, "port")->valuedouble;
|
||||
if(Nport==60156)
|
||||
{
|
||||
sprintf((char *)Nssid, "%s",cJSON_GetObjectItem(root, "ssid")->valuestring);
|
||||
sprintf((char *)Npassword,"%s",cJSON_GetObjectItem(root, "password")->valuestring);
|
||||
// Nport = cJSON_GetObjectItem(root, "port")->valuedouble;
|
||||
// if(Nport==60156)
|
||||
// {
|
||||
sprintf((char *)Wssid, "%s",cJSON_GetObjectItem(root, "ssid")->valuestring);
|
||||
sprintf((char *)Wpassword,"%s",cJSON_GetObjectItem(root, "password")->valuestring);
|
||||
// 进入无线第三步
|
||||
NetWorkFlow = 3;
|
||||
}
|
||||
cJSON_Delete(root);
|
||||
memset(JsonString, 0, sizeof(JsonString));
|
||||
// }
|
||||
cJSON_Delete(root);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(NetWorkFlow == 10)
|
||||
{
|
||||
#ifdef MQTT_SCode
|
||||
rlen = UART2ReadFlag&(~(1<<15));
|
||||
memcpy(rbuf, (void*)&UART2ReadBuf, rlen);
|
||||
memset(UART2ReadBuf, 0, sizeof(UART2ReadBuf));
|
||||
UART2ReadFlag = 0;
|
||||
|
||||
if (strstr((char *)rbuf, "CLOSED"))
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (0xD0 == *rbuf)
|
||||
// 服务器解析
|
||||
if(NetWorkFlow == 10) {
|
||||
#ifdef MQTT_SCode
|
||||
slen = UART2ReadFlag&(~(1 << 15));
|
||||
UART2ReadBuf[slen] = 0x0D;
|
||||
UART2ReadBuf[slen+1] = 0x0A;
|
||||
/**********设置状态*********/
|
||||
memset((void *)PublishData, 0, sizeof(PublishData));
|
||||
sprintf((char *)PublishData,"status/set/%s", MQTT_DeviceID);
|
||||
if(mystrstr((char *)UART2ReadBuf, (char *)PublishData)==1) {
|
||||
memset(JsonString, 0, sizeof(JsonString));
|
||||
for(i = 0;;i++)
|
||||
{
|
||||
//Sys_SendLog("MQTT Heart Beat \r\n");
|
||||
}
|
||||
else
|
||||
if(UART2ReadBuf[i]=='{')
|
||||
{
|
||||
for(j = 0;;j++)
|
||||
{
|
||||
JsonString[j] = UART2ReadBuf[j+i];
|
||||
if( (UART2ReadBuf[j+i]=='}') && (UART2ReadBuf[j+i+1]==0x0D) && (UART2ReadBuf[j+i+2]==0x0A))
|
||||
{
|
||||
// 解析数据
|
||||
root = cJSON_Parse((char *)JsonString);
|
||||
if(root == NULL)
|
||||
{
|
||||
memset((void *)UART2ReadBuf, 0, sizeof(UART2ReadBuf));
|
||||
UART3ReadFlag = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
DevParam.ServerRelay= cJSON_GetObjectItem(root, "relayStatus")->valuedouble;
|
||||
DevParam.ServerRed = cJSON_GetObjectItem(root, "red")->valuedouble;
|
||||
|
||||
cJSON_Delete(root);
|
||||
memset((void *)UART2ReadBuf, 0, sizeof(UART2ReadBuf));
|
||||
UART3ReadFlag = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef MQTT_AT
|
||||
// 首先判断
|
||||
if(strstr((const char*)UART2ReadBuf,(const char*)"+MQTTSUBRECV")) {
|
||||
memset((void *)PublishData, 0, sizeof(PublishData));
|
||||
sprintf((char *)PublishData,"status/set/%s", MQTT_DeviceID);
|
||||
if(strstr((const char*)UART2ReadBuf,(const char*)PublishData))
|
||||
{
|
||||
// strncpy(Topic, (void*)(rbuf+4), rbuf[3]);
|
||||
// printf("Topic: %s\r\n", Topic);
|
||||
// strncpy(message,(void*)(rbuf+4+rbuf[3]),rbuf[1]-rbuf[3]-2);
|
||||
// printf("Message: %s\r\n", message);
|
||||
// memset(rbuf, 0, sizeof(rbuf));
|
||||
memset(JsonString, 0, sizeof(JsonString));
|
||||
for(i = 0;;i++)
|
||||
{
|
||||
if(UART2ReadBuf[i]=='{')
|
||||
{
|
||||
for(j = 0;;j++)
|
||||
{
|
||||
JsonString[j] = UART2ReadBuf[j+i];
|
||||
if( (UART2ReadBuf[j+i]=='}') && (UART2ReadBuf[j+i+1]==0x0D) && (UART2ReadBuf[j+i+2]==0x0A))
|
||||
{
|
||||
// 解析数据
|
||||
root = cJSON_Parse((char *)JsonString);
|
||||
if(root == NULL)
|
||||
{
|
||||
memset((void *)UART2ReadBuf, 0, sizeof(UART2ReadBuf));
|
||||
UART3ReadFlag = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
DevParam.ServerRelay= cJSON_GetObjectItem(root, "relayStatus")->valuedouble;
|
||||
DevParam.ServerRed = cJSON_GetObjectItem(root, "red")->valuedouble;
|
||||
|
||||
cJSON_Delete(root);
|
||||
memset((void *)UART2ReadBuf, 0, sizeof(UART2ReadBuf));
|
||||
UART3ReadFlag = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
memset((void *)UART2ReadBuf, 0, sizeof(UART2ReadBuf));
|
||||
UART2ReadFlag = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,11 +5,15 @@
|
||||
|
||||
#include "esp8266_uart2.h"
|
||||
|
||||
#include "stdio.h"
|
||||
|
||||
#include "string.h"
|
||||
|
||||
#include "stdarg.h"
|
||||
|
||||
#include "cJSON.h"
|
||||
|
||||
#include "MQTTPacket.h"
|
||||
|
||||
#include "MQTTConnect.h"
|
||||
#include "mqtt.h"
|
||||
|
||||
void ESP8266_NetWorkFlow(void);
|
||||
void ESP8266_NetReceiveInfor(void);
|
||||
|
||||
Reference in New Issue
Block a user