1、add MQTT connection parameter configuration by Kconfig

2、Send a heartbeat packet every 1 minute during idle time to keep alive
This commit is contained in:
wgzAIIT 2023-06-26 16:50:29 +08:00
parent 5900b504e3
commit 3c179e7879
4 changed files with 116 additions and 49 deletions

View File

@ -202,7 +202,7 @@ static void InitialVersion(void)
ota_info.os.size = size;
ota_info.os.crc32 = calculate_crc32(XIUOS_FLAH_ADDRESS, size);
strncpy(ota_info.os.version,"1.0.0",sizeof(ota_info.os.version));
strncpy(ota_info.os.version,"001.000.000",sizeof(ota_info.os.version));
strncpy(ota_info.os.description, "The initial firmware.", sizeof(ota_info.os.description));
UpdateOTAFlag(&ota_info);
@ -726,7 +726,7 @@ static void app_ota_by_4g(void)
}
}
mcuboot.flash_deinit();
KPrintf("ota file done,start reboot.\n");
KPrintf("ota file transfer complete,start reboot!\n");
MdelayKTask(2000);
mcuboot.op_reset();
}
@ -740,6 +740,7 @@ SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHE
static uint8_t MqttRxbuf[3072];
static uint8_t FrameBuf[FRAME_LEN];
static OTA_TCB AliOTA;
/*******************************************************************************
* : PropertyVersion
* :
@ -748,16 +749,20 @@ static OTA_TCB AliOTA;
*******************************************************************************/
static void PropertyVersion(void)
{
uint8_t tempbuff[128];
uint8_t topicdatabuff[64];
uint8_t tempdatabuff[128];
ota_info_t ota_info;
memset(tempbuff,0,128);
memset(topicdatabuff,0,64);
sprintf(topicdatabuff,"/ota/device/inform/%s/%s", PLATFORM_PRODUCTKEY, CLIENT_DEVICENAME);
memset(&ota_info, 0, sizeof(ota_info_t));
mcuboot.op_flash_read(FLAG_FLAH_ADDRESS, (void*)&ota_info, sizeof(ota_info_t));
memset(tempdatabuff,0,128);
sprintf(tempdatabuff,"{\"id\": \"1\",\"params\": {\"version\": \"%s\"}}",ota_info.os.version);
mcuboot.op_flash_read(FLAG_FLAH_ADDRESS, (void*)&ota_info, sizeof(ota_info_t)); //清空临时缓冲区
sprintf(tempbuff,"{\"id\": \"1\",\"params\": {\"version\": \"%s\"}}",ota_info.os.version);
MQTT_PublishDataQs1("/ota/device/inform/iv74JbFgzhv/D001",tempbuff,strlen(tempbuff)); //发送等级QS=1的PUBLISH报文
MQTT_PublishDataQs1(topicdatabuff,tempdatabuff,strlen(tempdatabuff)); //发送等级QS=1的PUBLISH报文
}
@ -769,10 +774,16 @@ static void PropertyVersion(void)
/*-------------------------------------------------*/
void OTA_Download(int size, int offset)
{
uint8_t temp[256];
memset(temp,0,256);
sprintf(temp,"{\"id\": \"1\",\"params\": {\"fileInfo\":{\"streamId\":%d,\"fileId\":1},\"fileBlock\":{\"size\":%d,\"offset\":%d}}}",AliOTA.streamId,size,offset);
MQTT_PublishDataQs0("/sys/iv74JbFgzhv/D001/thing/file/download",temp,strlen(temp));
uint8_t topicdatabuff[64];
uint8_t tempdatabuff[128];
memset(topicdatabuff,0,64);
sprintf(topicdatabuff,"/sys/%s/%s/thing/file/download",PLATFORM_PRODUCTKEY,CLIENT_DEVICENAME);
memset(tempdatabuff,0,128);
sprintf(tempdatabuff,"{\"id\": \"1\",\"params\": {\"fileInfo\":{\"streamId\":%d,\"fileId\":1},\"fileBlock\":{\"size\":%d,\"offset\":%d}}}",AliOTA.streamId,size,offset);
MQTT_PublishDataQs0(topicdatabuff, tempdatabuff, strlen(tempdatabuff));
}
/*******************************************************************************
@ -786,43 +797,58 @@ static void app_ota_by_platform(void* parameter)
int datalen;
int ret = 0;
ota_info_t ota_info;
uint32_t heart_time = 0;
uint32_t flashdestination = DOWN_FLAH_ADDRESS;
uint8_t topicdatabuff[64];
char *ptr;
mcuboot.flash_init();
memset(&ota_info, 0, sizeof(ota_info_t));
mcuboot.op_flash_read(FLAG_FLAH_ADDRESS, (void*)&ota_info, sizeof(ota_info_t));
ota_info.status = OTA_STATUS_DOWNLOADING;
UpdateOTAFlag(&ota_info);
memset(topicdatabuff,0,64);
sprintf(topicdatabuff,"/sys/%s/%s/thing/file/download_reply",PLATFORM_PRODUCTKEY,CLIENT_DEVICENAME);
if((AdapterNetActive() == 0) && (MQTT_Connect() == 0))
reconnect:
if((AdapterNetActive() == 0) && (MQTT_Connect() == 0) && MQTT_SubscribeTopic(topicdatabuff) == 0)
{
KPrintf("Log in to aliyun mqtt successfully.\n");
MQTT_SubscribeTopic("/sys/iv74JbFgzhv/D001/thing/service/property/set"); //发送订阅Topic报文
MQTT_SubscribeTopic("/sys/iv74JbFgzhv/D001/thing/file/download_reply"); //发送订阅Topic报文
KPrintf("Log in to the cloud platform and subscribe to the topic successfully.\n");
PropertyVersion();
}
}
while(1)
{
memset(MqttRxbuf,0,sizeof(MqttRxbuf));
datalen = MQTT_Recv(MqttRxbuf, sizeof(MqttRxbuf));
if(datalen > 0 && (MqttRxbuf[0] == 0x30))
if(MqttRxbuf[0] == 0x30)
{
MQTT_DealPublishData(MqttRxbuf, datalen);
if(sscanf((char *)Platform_mqtt.cmdbuff,"/ota/device/upgrade/iv74JbFgzhv/D001{\"code\":\"1000\",\"data\":{\"size\":%d,\"streamId\":%d,\"sign\":\"%*32s\",\"dProtocol\":\"mqtt\",\"version\":\"%11s\"",&AliOTA.size,&AliOTA.streamId,AliOTA.version)==3)
ptr = strstr((char *)Platform_mqtt.cmdbuff,"{\"code\":\"1000\"");
if(ptr != NULL)
{
KPrintf("ota file size:%d\r\n",AliOTA.size);
KPrintf("ota file id:%d\r\n",AliOTA.streamId);
KPrintf("ota file version:%s\r\n",AliOTA.version);
if(mcuboot.op_flash_erase(DOWN_FLAH_ADDRESS,AliOTA.size != kStatus_Success))
if(sscanf(ptr,"{\"code\":\"1000\",\"data\":{\"size\":%d,\"streamId\":%d,\"sign\":\"%*32s\",\"dProtocol\":\"mqtt\",\"version\":\"%11s\"",&AliOTA.size,&AliOTA.streamId,AliOTA.version)==3)
{
KPrintf("Failed to erase target fash!\n");
ret = -1;
break;
KPrintf("ota file size:%d\r\n",AliOTA.size);
KPrintf("ota file id:%d\r\n",AliOTA.streamId);
KPrintf("ota file version:%s\r\n",AliOTA.version);
if(mcuboot.op_flash_erase(DOWN_FLAH_ADDRESS,AliOTA.size != kStatus_Success))
{
KPrintf("Failed to erase target fash!\n");
ret = -1;
break;
}
AliOTA.counter = (AliOTA.size%FRAME_LEN != 0)? (AliOTA.size/FRAME_LEN + 1):(AliOTA.size/FRAME_LEN);
AliOTA.num = 1; //下载次数,初始值为1
AliOTA.downlen = FRAME_LEN; //记录本次下载量
OTA_Download(AliOTA.downlen,(AliOTA.num - 1)*FRAME_LEN); //发送要下载的数据信息给服务器
}
else
{
KPrintf("Failed to get ota information!\n");
ret = -1;
break;
}
AliOTA.counter = (AliOTA.size%FRAME_LEN != 0)? (AliOTA.size/FRAME_LEN + 1):(AliOTA.size/FRAME_LEN);
AliOTA.num = 1; //下载次数,初始值为1
AliOTA.downlen = FRAME_LEN; //记录本次下载量
OTA_Download(AliOTA.downlen,(AliOTA.num - 1)*FRAME_LEN); //发送要下载的数据信息给服务器
}
if(strstr((char *)Platform_mqtt.cmdbuff,"download_reply"))
@ -844,7 +870,7 @@ static void app_ota_by_platform(void* parameter)
}
if(AliOTA.num < AliOTA.counter) //如果小于总下载次数
{
{
AliOTA.downlen = FRAME_LEN; //记录本次下载量
OTA_Download(AliOTA.downlen,(AliOTA.num - 1)*FRAME_LEN); //发送要下载的数据信息给服务器
}
@ -870,8 +896,20 @@ static void app_ota_by_platform(void* parameter)
}
}
if((datalen <= 0) && (CalculateTimeMsFromTick(CurrentTicksGain()) - heart_time >= HEART_TIME)) //空闲状态下每隔一段时间发送需要发送心跳包保活
{
heart_time = CalculateTimeMsFromTick(CurrentTicksGain());
KPrintf("Send heartbeat packet!\n");
if(MQTT_SendHeart() != 0) //发送心跳包失败可能连接断开,需要重连
{
heart_time = 0;
goto reconnect;
}
}
}
if(0 == ret)
if(0 == ret)
{
ota_info.down.size = AliOTA.size;
ota_info.down.crc32= calculate_crc32(DOWN_FLAH_ADDRESS, AliOTA.size);
@ -889,17 +927,17 @@ static void app_ota_by_platform(void* parameter)
UpdateOTAFlag(&ota_info);
}
else
else
{
ota_info.status = OTA_STATUS_ERROR;
memset(ota_info.error_message,0,sizeof(ota_info.error_message));
strncpy(ota_info.error_message, "Failed to download firmware to download partition!",sizeof(ota_info.error_message));
UpdateOTAFlag(&ota_info);
}
MQTT_UnSubscribeTopic(topicdatabuff);
MQTT_Disconnect();
mcuboot.flash_deinit();
KPrintf("ota file done,start reboot.\n");
KPrintf("ota file transfer complete,start reboot!\n");
MdelayKTask(2000);
mcuboot.op_reset();
}

View File

@ -7,6 +7,39 @@ menu "MQTT function"
select CONNECTION_ADAPTER_4G
if TOOL_USING_MQTT
menu "MQTT connection parameter configuration."
config PLATFORM_PRODUCTKEY
string "Product Key, used to identify a product."
default "iywhcgnuezz"
config CLIENT_DEVICENAME
string "Device name, used to identify a client device."
default "D001"
config CLIENT_DEVICESECRET
string "Device secret, used for device authentication and data encryption."
default "43b3c332233e2204a0612bfbfe21bb67"
config CLIENTID
string "mqtt client id."
default "iywhcgnuezz.D001|securemode=2,signmethod=hmacsha256,timestamp=1687917392547|"
config USERNAME
string "mqtt client username."
default "D001&iywhcgnuezz"
config PASSWORD
string "mqtt client login passwd."
default "2af06ed86b9f6cbeb66beff402e3e882d41a838180695fced70edcf568052857"
config PLATFORM_SERVERIP
string "mqtt platform server ip."
default "101.133.196.127"
config PLATFORM_SERVERPORT
string "mqtt platform server port."
default "1883"
endmenu
endif
endmenu

View File

@ -30,8 +30,8 @@
MQTT_TCB Platform_mqtt; //创建一个用于连接云平台mqtt的结构体
static struct Adapter *adapter;
static const uint8_t parket_connetAck[] = {0x20,0x02,0x00,0x00}; //连接成功服务器回应报文
static const uint8_t parket_disconnet[] = {0xe0,0x00}; //客户端主动断开连接发送报文
static const uint8_t parket_heart[] = {0xc0,0x00}; //客户端发送保活心跳包
static const uint8_t parket_disconnet[] = {0xE0,0x00}; //客户端主动断开连接发送报文
static const uint8_t parket_heart[] = {0xC0,0x00}; //客户端发送保活心跳包
static const uint8_t parket_subAck[] = {0x90,0x03,0x00,0x0A,0x01}; //订阅成功服务器回应报文
static const uint8_t parket_unsubAck[] = {0xB0,0x02,0x00,0x0A}; //取消订阅成功服务器回应报文
static uint8_t mqtt_rxbuf[16];
@ -62,7 +62,7 @@ int AdapterNetActive(void)
goto out;
}
ret = AdapterDeviceConnect(adapter, CLIENT, SERVERIP, SERVERPORT, IPV4);
ret = AdapterDeviceConnect(adapter, CLIENT, PLATFORM_SERVERIP, PLATFORM_SERVERPORT, IPV4);
if (ret < 0)
{
goto out;
@ -142,8 +142,8 @@ int MQTT_Connect(void)
Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+5] = 0x54; //CONNECT报文,可变报头第6个字节:固定0x54,大写字母T
Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+6] = 0x04; //CONNECT报文,可变报头第7个字节:固定0x04
Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+7] = 0xC2; //CONNECT报文,可变报头第8个字节:使能用户名和密码校验,不使用遗嘱功能,不保留会话功能
Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+8] = 0x00; //CONNECT报文,可变报头第9个字节:保活时间高字节
Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+9] = 0x64; //CONNECT报文,可变报头第10个字节:保活时间高字节
Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+8] = KEEPALIVE_TIME/256; //CONNECT报文,可变报头第9个字节:保活时间高字节
Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+9] = KEEPALIVE_TIME%256; //CONNECT报文,可变报头第10个字节:保活时间低字节,单位s
/* CLIENT_ID */
Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+10] = strlen(CLIENTID)/256; //客户端ID长度高字节

View File

@ -24,14 +24,10 @@
#include <stdint.h>
#define CLIENTID "iv74JbFgzhv.D001|securemode=2,signmethod=hmacsha256,timestamp=1686617772433|"
#define USERNAME "D001&iv74JbFgzhv"
#define PASSWORD "2e5e585ec5fc8665dd8bc1a17444fc8ffcb07ed515b220785883d478e49666e5"
#define SERVERIP "101.133.196.127"
#define SERVERPORT "1883"
#define PACK_SIZE 512 //存放报文数据缓冲区大小
#define CMD_SIZE 3072 //保存推送的PUBLISH报文中的数据缓冲区大小
#define KEEPALIVE_TIME 300 //保活时间(单位s),300s
#define HEART_TIME 60000 //空闲时发送心跳包的时间间隔(单位ms),60s
#define PACK_SIZE 512 //存放报文数据缓冲区大小
#define CMD_SIZE 3072 //保存推送的PUBLISH报文中的数据缓冲区大小
typedef struct{
uint8_t Pack_buff[PACK_SIZE]; //存放发送报文数据缓冲区