//請求連接
void mqtt_connect(char *clientid,char *username,char *passwd)
{
uint32_t clientid_len = strlen(clientid);
uint32_t username_len = strlen(username);
uint32_t passwd_len = strlen(passwd);
//用於存儲剩餘長度 = 可變包頭+有效載荷(客户端id+2+用户名+2+密碼+2);
uint32_t remain_len = 10 + (clientid_len+2)+ (username_len+2)+ (passwd_len+2);
//1 對發送緩衝區進行初始化
memset((char *)sendbuf,0,512);
sendcnt = 0;
//2 固定包頭
sendbuf[sendcnt++] = 0x10;//connect
//3 對剩餘長度進行編碼
do
{
uint8_t encodeByte = remain_len %128;
remain_len = remain_len /128;
if(remain_len >0)
{
encodeByte = encodeByte |128;
}
sendbuf[sendcnt++] = encodeByte;
}
while(remain_len >0);
//4 可變包頭
sendbuf[sendcnt++] = 0;
sendbuf[sendcnt++] = 4;
sendbuf[sendcnt++] = 'M';//協議名稱
sendbuf[sendcnt++] = 'Q';
sendbuf[sendcnt++] = 'T';
sendbuf[sendcnt++] = 'T';
sendbuf[sendcnt++] = 4;//協議版本
sendbuf[sendcnt++] = 0xc2 ;//連接標誌
sendbuf[sendcnt++] = 0 ;//保持連接
sendbuf[sendcnt++] = 120 ;//2分鐘
//5 有效載荷 客户端id 用户名 密碼
sendbuf[sendcnt++] = BYTE1(clientid_len); //msb
sendbuf[sendcnt++] = BYTE0(clientid_len); //lsb
memcpy(&sendbuf[sendcnt] ,clientid,clientid_len);
sendcnt +=clientid_len;
sendbuf[sendcnt++] = BYTE1(username_len); //msb
sendbuf[sendcnt++] = BYTE0(username_len); //lsb
memcpy(&sendbuf[sendcnt] ,username,username_len);
sendcnt +=username_len;
sendbuf[sendcnt++] = BYTE1(passwd_len); //msb
sendbuf[sendcnt++] = BYTE0(passwd_len); //lsb
memcpy(&sendbuf[sendcnt] ,passwd,passwd_len);
sendcnt +=passwd_len;
//6 把connect報文發送出去
Serial_Sendstring(sendbuf,sendcnt);
}
//發佈消息
void mqtt_publish(char *topic,uint8_t Qos,char *databuf)
{
uint32_t remain_len;
uint32_t topic_len = strlen(topic);
uint32_t databuf_len = strlen(databuf);//有效載荷
//用於存儲剩餘長度 = 可變包頭+有效載荷(客户端id+2+用户名+2+密碼+2);
if(Qos == 0)
{
remain_len = (topic_len+2)+(databuf_len);
}
else
{
remain_len = (topic_len+2)+(databuf_len) + 2;
}
//1 對發送緩衝區進行初始化
memset((char *)sendbuf,0,512);
sendcnt = 0;
//2 固定包頭
sendbuf[sendcnt++] = 0x30;//connect
//3 對剩餘長度進行編碼
do
{
uint8_t encodeByte = remain_len %128;
remain_len = remain_len /128;
if(remain_len >0)
{
encodeByte = encodeByte |128;
}
sendbuf[sendcnt++] = encodeByte;
}
while(remain_len >0);
//可變包頭
sendbuf[sendcnt++] = BYTE1(topic_len); //msb
sendbuf[sendcnt++] = BYTE0(topic_len); //lsb
memcpy(&sendbuf[sendcnt] ,topic,topic_len);
sendcnt +=topic_len;
//有效載荷
// sendbuf[sendcnt++] = BYTE1(databuf_len); //msb
// sendbuf[sendcnt++] = BYTE0(databuf_len); //lsb
memcpy(&sendbuf[sendcnt] ,databuf,databuf_len);
sendcnt +=databuf_len;
//6 把connect報文發送出去
Serial_Sendstring(sendbuf,sendcnt);
}
//訂閲消息
void mqtt_subscribe(const char *Filter, uint16_t msg_id, uint8_t qos)
{
char data[256] = {0};
int cnt = 0;
uint32_t remain;
// 固定包頭
data[cnt++] = 0x82; // 訂閲消息類型
// 計算剩餘字節長度
uint32_t Filter_len = strlen(Filter);
remain = 2 + Filter_len + 2 + 1; // 消息 ID (2 字節) + 主題長度 (2 字節) + 主題 (Filter_len 字節) + QoS (1 字節)
// 編碼剩餘字節
do
{
uint8_t encodeByte = remain % 128;
remain = remain / 128;
if (remain > 0)
{
encodeByte |= 128;
}
data[cnt++] = encodeByte;
}
while (remain > 0);
// 可變包頭
data[cnt++] = BYTE1(msg_id); // 消息 ID 高字節
data[cnt++] = BYTE0(msg_id); // 消息 ID 低字節
// 有效載荷
data[cnt++] = BYTE1(Filter_len); // 主題長度高字節
data[cnt++] = BYTE0(Filter_len); // 主題長度低字節
memcpy(&data[cnt], Filter, Filter_len); // 主題
cnt += Filter_len;
data[cnt++] = qos; // QoS 級別
// 發送構建的 MQTT 消息
Serial_Sendstring(data, cnt);
}
//保持心跳請求
void mqtt_keepalive()
{
uint8_t buf[2] = {0xc0,0x00};
}