Files
fastbee/firmware/stm32-esp/user/mqtt/mqtt.c
2021-09-06 00:02:30 +08:00

334 lines
8.9 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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;
}