diff --git a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c index da5203b9d..9cc091aa8 100644 --- a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c +++ b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c @@ -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(); } diff --git a/Ubiquitous/XiZi_IIoT/tool/mqtt/Kconfig b/Ubiquitous/XiZi_IIoT/tool/mqtt/Kconfig index f8c512ab7..4024bfdb7 100644 --- a/Ubiquitous/XiZi_IIoT/tool/mqtt/Kconfig +++ b/Ubiquitous/XiZi_IIoT/tool/mqtt/Kconfig @@ -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 diff --git a/Ubiquitous/XiZi_IIoT/tool/mqtt/platform_mqtt.c b/Ubiquitous/XiZi_IIoT/tool/mqtt/platform_mqtt.c index 6513f3c6e..ec051655e 100644 --- a/Ubiquitous/XiZi_IIoT/tool/mqtt/platform_mqtt.c +++ b/Ubiquitous/XiZi_IIoT/tool/mqtt/platform_mqtt.c @@ -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长度高字节 diff --git a/Ubiquitous/XiZi_IIoT/tool/mqtt/platform_mqtt.h b/Ubiquitous/XiZi_IIoT/tool/mqtt/platform_mqtt.h index eec68ec09..f6ec30783 100644 --- a/Ubiquitous/XiZi_IIoT/tool/mqtt/platform_mqtt.h +++ b/Ubiquitous/XiZi_IIoT/tool/mqtt/platform_mqtt.h @@ -24,14 +24,10 @@ #include -#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]; //存放发送报文数据缓冲区