diff --git a/APP_Framework/Framework/connection/4g/ec200t/ec200t.c b/APP_Framework/Framework/connection/4g/ec200t/ec200t.c index 456f05664..7f9ba7132 100644 --- a/APP_Framework/Framework/connection/4g/ec200t/ec200t.c +++ b/APP_Framework/Framework/connection/4g/ec200t/ec200t.c @@ -163,8 +163,8 @@ static int Ec200tIoctl(struct Adapter *adapter, int cmd, void *args) serial_cfg.serial_parity_mode = PARITY_NONE; serial_cfg.serial_bit_order = STOP_BITS_1; serial_cfg.serial_invert_mode = NRZ_NORMAL; - //serial receive timeout 10s - serial_cfg.serial_timeout = 10000; + //serial receive timeout 1s + serial_cfg.serial_timeout = 1000; serial_cfg.is_ext_uart = 0; #ifdef ADAPTER_EC200T_DRIVER_EXT_PORT serial_cfg.is_ext_uart = 1; diff --git a/APP_Framework/Framework/connection/adapter_agent.c b/APP_Framework/Framework/connection/adapter_agent.c index 0dc75b52c..969da816f 100755 --- a/APP_Framework/Framework/connection/adapter_agent.c +++ b/APP_Framework/Framework/connection/adapter_agent.c @@ -293,6 +293,7 @@ int EntmSend(ATAgentType agent, const char *data, int len) int EntmRecv(ATAgentType agent, char *rev_buffer, int buffer_len, int timeout_s) { struct timespec abstime; + uint32 real_recv_len = 0; abstime.tv_sec = timeout_s; if(buffer_len > ENTM_RECV_MAX){ @@ -316,13 +317,14 @@ int EntmRecv(ATAgentType agent, char *rev_buffer, int buffer_len, int timeout_s) printf("EntmRecv once len %d.\n", agent->entm_recv_len); #endif memcpy(rev_buffer, agent->entm_recv_buf, agent->entm_recv_len); - memset(agent->entm_recv_buf, 0, ENTM_RECV_MAX); + + real_recv_len = agent->entm_recv_len; agent->entm_recv_len = 0; agent->read_len = 0; PrivMutexAbandon(&agent->lock); - return buffer_len; + return real_recv_len; } static int GetCompleteATReply(ATAgentType agent) @@ -330,21 +332,22 @@ static int GetCompleteATReply(ATAgentType agent) uint32_t read_len = 0; char ch = 0, last_ch = 0; bool is_full = false; + int res; PrivMutexObtain(&agent->lock); memset(agent->maintain_buffer, 0x00, agent->maintain_max); agent->maintain_len = 0; - memset(agent->entm_recv_buf, 0x00, 256); + memset(agent->entm_recv_buf, 0x00, ENTM_RECV_MAX); agent->entm_recv_len = 0; PrivMutexAbandon(&agent->lock); while (1) { - PrivRead(agent->fd, &ch, 1); + res = PrivRead(agent->fd, &ch, 1); #ifdef CONNECTION_FRAMEWORK_DEBUG - if(ch != 0) { + if((res == 1) && (ch != 0)) { printf(" %c (0x%x)\n", ch, ch); } #endif @@ -352,10 +355,9 @@ static int GetCompleteATReply(ATAgentType agent) PrivMutexObtain(&agent->lock); if (agent->receive_mode == ENTM_MODE) { if (agent->entm_recv_len < ENTM_RECV_MAX) { - agent->entm_recv_buf[agent->entm_recv_len] = ch; - agent->entm_recv_len++; - - if(agent->entm_recv_len < agent->read_len) { + if((res == 1) && (agent->entm_recv_len < agent->read_len)) { + agent->entm_recv_buf[agent->entm_recv_len] = ch; + agent->entm_recv_len++; PrivMutexAbandon(&agent->lock); continue; } else { diff --git a/Ubiquitous/XiZi_IIoT/path_kernel.mk b/Ubiquitous/XiZi_IIoT/path_kernel.mk index 6736938db..0d6b98ffa 100755 --- a/Ubiquitous/XiZi_IIoT/path_kernel.mk +++ b/Ubiquitous/XiZi_IIoT/path_kernel.mk @@ -560,6 +560,10 @@ KERNELPATHS +=-I$(KERNEL_ROOT)/tool/bootloader/flash \ -I$(KERNEL_ROOT)/tool/bootloader/ota # endif +ifeq ($(CONFIG_TOOL_USING_MQTT), y) +KERNELPATHS +=-I$(KERNEL_ROOT)/tool/mqtt +endif + ifeq ($(CONFIG_FS_LWEXT4),y) KERNELPATHS += -I$(KERNEL_ROOT)/fs/lwext4/lwext4_submodule/blockdev/xiuos # KERNELPATHS += -I$(KERNEL_ROOT)/fs/lwext4/lwext4_submodule/include # diff --git a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c index 702cf9506..e8a9d0ad2 100644 --- a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c +++ b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c @@ -30,6 +30,10 @@ #include #endif +#ifdef OTA_BY_PLATFORM +#include "aliyun_mqtt.h" +#endif + /**************************************************************************** * Private Function Prototypes ****************************************************************************/ @@ -124,34 +128,37 @@ static uint32_t calculate_crc32(uint32_t addr, uint32_t len) * 形 参: cur_version:当前版本号,new_version:生成的新版本号 * 返 回 值: 0:生成成功,-1:生成失败 * 说 明: 为保持一致,平台通过OTA传输而来的版本号也要保持这样三段式的形式 - 版本形式为major.minor.patch,如1.2.3 + 版本形式为major.minor.patch,如01.02.03 *******************************************************************************/ static int create_version(uint8_t* cur_version, uint8_t* new_version) { int major, minor, patch; //三段式版本号的各个部分 //解析当前版本号,版本号格式不对直接返回 - if (sscanf(cur_version, "%d.%d.%d", &major, &minor, &patch) != 3) { + if (sscanf(cur_version, "%03d.%03d.%03d", &major, &minor, &patch) != 3) { return -1; } //将当前版本号加1 patch++; - if(patch > MAX_PATCH) { + if(patch > 999) + { minor++; patch = 0; - if (minor > MAX_MINOR) { + if(minor > 999) + { major++; minor = 0; patch = 0; - if (major > MAX_MAJOR) { + if(major > 999) + { return -1; } } } //更新版本号 - sprintf(new_version, "%d.%d.%d", major, minor, patch); + sprintf(new_version, "%03d.%03d.%03d", major, minor, patch); return 0; } @@ -690,8 +697,8 @@ try_again: /******************************************************************************* * 函 数 名: app_ota_by_4g * 功能描述: 通过命令来进行ota升级,该函数与升级的命令关联,通过4g方式传输bin文件 -* 形 参: adapter:Adapter指针,指向注册的4G设备 -* 返 回 值: 0:传输成功,-1:传输失败 +* 形 参: 无 +* 返 回 值: 无 *******************************************************************************/ static void app_ota_by_4g(void) { @@ -731,6 +738,175 @@ SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHE #ifdef OTA_BY_PLATFORM +#define FRAME_LEN 256 //每帧数据的数据包长度 +static uint8_t MqttRxbuf[512]; +static uint8_t FrameBuf[FRAME_LEN]; +static OTA_TCB AliOTA; +/******************************************************************************* +* 函 数 名: PropertyVersion +* 功能描述: 向服务器上传当前设备版本信息 +* 形 参: 无 +* 返 回 值: 无 +*******************************************************************************/ +static void PropertyVersion(void) +{ + uint8_t tempbuff[128]; + ota_info_t ota_info; + + memset(tempbuff,0,128); + memset(&ota_info, 0, sizeof(ota_info_t)); + + 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报文 +} + + +/*-------------------------------------------------*/ +/*函数名:OTA下载数据 */ +/*参 数:size:本次下载量 */ +/*参 数:offset:本次下载偏移量 */ +/*返回值:无 */ +/*-------------------------------------------------*/ +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)); +} + +/******************************************************************************* +* 函 数 名: app_ota_by_platform +* 功能描述: 通过命令来进行ota升级,该函数与升级的命令关联,通过云平台MQTT进行升级 +* 形 参: 无 +* 返 回 值: 无 +*******************************************************************************/ +static void app_ota_by_platform(void) +{ + int datalen; + int ret = 0; + ota_info_t ota_info; + uint32_t flashdestination = DOWN_FLAH_ADDRESS; + + 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); + + if((AdapterNetActive() == 0) && (MQTT_Connect() == 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报文 + PropertyVersion(); + } + while(1) + { + memset(MqttRxbuf,0,sizeof(MqttRxbuf)); + datalen = MQTT_Recv(MqttRxbuf, 512); + if(datalen > 0 && (MqttRxbuf[0] == 0x30)) + { + MQTT_DealPublishData(MqttRxbuf, datalen); + if(sscanf((char *)Aliyun_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) + { + 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); //发送要下载的数据信息给服务器 + } + + if(strstr((char *)Aliyun_mqtt.cmdbuff,"download_reply")) + { + memset(FrameBuf,0,sizeof(FrameBuf)); + memcpy(FrameBuf, &MqttRxbuf[datalen-AliOTA.downlen-2], AliOTA.downlen); + if(mcuboot.op_flash_write(flashdestination,FrameBuf,AliOTA.downlen) != kStatus_Success) + { + KPrintf("current frame[%d] flash failed.\n",AliOTA.num-1); + ret = -1; + break; + } + else + { + KPrintf("current frame[%d] is written to flash 0x%x address successful.\n", AliOTA.num -1, flashdestination); + KPrintf("Current progress is %d/%d\r\n",AliOTA.num,AliOTA.counter); + flashdestination += AliOTA.downlen; + AliOTA.num++; + } + + if(AliOTA.num < AliOTA.counter) //如果小于总下载次数 + { + AliOTA.downlen = FRAME_LEN; //记录本次下载量 + OTA_Download(AliOTA.downlen,(AliOTA.num - 1)*FRAME_LEN); //发送要下载的数据信息给服务器 + } + else if(AliOTA.num == AliOTA.counter) //如果等于总下载次数,说明是最后一次下载 + { + if(AliOTA.size%FRAME_LEN == 0) //判断固件大小是否是FRAME_LEN的整数倍 + { + AliOTA.downlen = FRAME_LEN; //记录本次下载量 + OTA_Download(AliOTA.downlen,(AliOTA.num - 1)*FRAME_LEN); //发送要下载的数据信息给服务器 + } + else + { + AliOTA.downlen = AliOTA.size%FRAME_LEN; //记录本次下载量 + OTA_Download(AliOTA.downlen,(AliOTA.num - 1)*FRAME_LEN); //发送要下载的数据信息给服务器 + } + } + + else //下载完毕 + { + ret = 0; + break; + } + } + + } + } + if(0 == ret) + { + ota_info.down.size = AliOTA.size; + ota_info.down.crc32= calculate_crc32(DOWN_FLAH_ADDRESS, AliOTA.size); + + memset(ota_info.down.version,0,sizeof(ota_info.down.version)); + create_version(ota_info.os.version, ota_info.down.version); + + memset(ota_info.down.description,0,sizeof(ota_info.down.description)); + strncpy(ota_info.down.description, "MQTT OTA bin.",sizeof(ota_info.down.description)); + + ota_info.status = OTA_STATUS_READY; + + memset(ota_info.error_message,0,sizeof(ota_info.error_message)); + strncpy(ota_info.error_message, "No error message!",sizeof(ota_info.error_message)); + + UpdateOTAFlag(&ota_info); + } + 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); + } + mcuboot.flash_deinit(); + KPrintf("ota file done,start reboot.\n"); + MdelayKTask(2000); + mcuboot.op_reset(); +} + +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0),aliyun, app_ota_by_platform, ota by 4g function); #endif diff --git a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.h b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.h index 71c6ec95e..48880a85c 100644 --- a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.h +++ b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.h @@ -23,11 +23,6 @@ #include "flash_ops.h" - -#define MAX_MAJOR 99 //最大主版本号 -#define MAX_MINOR 99 //最大次版本号 -#define MAX_PATCH 99 //最大修订版本号 - #define JUMP_FAILED_FLAG 0XABABABAB #define JUMP_SUCCESS_FLAG 0XCDCDCDCD #define STARTFLAG 0x1A2B //数据帧开始信号标记 @@ -66,6 +61,7 @@ typedef struct { } ota_info_t; +#ifdef OTA_BY_TCPSERVER /*bin包传输过程中的数据帧相关的结构体*/ typedef struct { @@ -87,7 +83,18 @@ typedef struct ota_header_t header; ota_frame_t frame; } ota_data; +#endif +#ifdef OTA_BY_PLATFORM +typedef struct{ + uint32_t size; //OTA固件大小 + uint32_t streamId; //OTA固件下载时ID编号 + uint32_t counter; //OTA总下载次数 + uint32_t num; //OTA当前下载次数 + uint32_t downlen; //OTA当前下载次数的下载量 + uint8_t version[32]; //OTA下载时存储版本号的缓存区 +}OTA_TCB; +#endif void app_clear_jumpflag(void); void ota_entry(void); diff --git a/Ubiquitous/XiZi_IIoT/tool/mqtt/aliyun_mqtt.c b/Ubiquitous/XiZi_IIoT/tool/mqtt/aliyun_mqtt.c index 735e35dfa..048681371 100644 --- a/Ubiquitous/XiZi_IIoT/tool/mqtt/aliyun_mqtt.c +++ b/Ubiquitous/XiZi_IIoT/tool/mqtt/aliyun_mqtt.c @@ -27,15 +27,14 @@ #include #include "aliyun_mqtt.h" - +MQTT_TCB Aliyun_mqtt; //创建一个用于连接阿里云mqtt的结构体 static struct Adapter *adapter; -static MQTT_TCB Aliyun_mqtt; //创建一个用于连接阿里云mqtt的结构体 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_subAck[] = {0x90,0x03,0x00,0x0A,0x01}; //订阅成功服务器回应报文 static const uint8_t parket_unsubAck[] = {0xB0,0x02,0x00,0x0A}; //取消订阅成功服务器回应报文 -static uint8_t mqtt_rxbuf[512]; +static uint8_t mqtt_rxbuf[16]; /******************************************************************************* @@ -431,41 +430,3 @@ void MQTT_DealPublishData(uint8_t *data, uint16_t data_len) memcpy(Aliyun_mqtt.cmdbuff, &data[cmdpos], cmdlen); } } - - -void testmqtt(void) -{ - int ret = 0; - int len; - ret = AdapterNetActive(); - if(ret == 0) - { - KPrintf("The network connection is successful.\n"); - } - ret = MQTT_Connect(); - if(ret == 0) - { - KPrintf("Log in to aliyun mqtt successfully.\n"); - } - MdelayKTask(2000); - ret = MQTT_SubscribeTopic(TOPIC); - if(ret == 0) - { - KPrintf("mqtt sub successfully.\n"); - } - while(1) - { - memset(mqtt_rxbuf,0,sizeof(mqtt_rxbuf)); - len = MQTT_Recv(mqtt_rxbuf, 256); - if(len > 0 && (mqtt_rxbuf[0] == 0x30)) - { - MQTT_DealPublishData(mqtt_rxbuf, len); - KPrintf("%s",Aliyun_mqtt.cmdbuff); - KPrintf("\r\n"); - } - MdelayKTask(200); - MQTT_SendHeart(); - } -} - -SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0),mqtt, testmqtt, test mqtt); \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/tool/mqtt/aliyun_mqtt.h b/Ubiquitous/XiZi_IIoT/tool/mqtt/aliyun_mqtt.h index 9a03b7448..baad5e4a6 100644 --- a/Ubiquitous/XiZi_IIoT/tool/mqtt/aliyun_mqtt.h +++ b/Ubiquitous/XiZi_IIoT/tool/mqtt/aliyun_mqtt.h @@ -29,7 +29,6 @@ #define PASSWORD "2e5e585ec5fc8665dd8bc1a17444fc8ffcb07ed515b220785883d478e49666e5" #define SERVERIP "101.133.196.127" #define SERVERPORT "1883" -#define TOPIC "/sys/iv74JbFgzhv/D001/thing/service/property/set" #define PACK_SIZE 512 //存放报文数据缓冲区大小 #define CMD_SIZE 512 //保存推送的PUBLISH报文中的数据缓冲区大小 @@ -44,6 +43,8 @@ typedef struct{ uint8_t cmdbuff[CMD_SIZE]; //保存推送的PUBLISH报文中的数据缓冲区 }MQTT_TCB; +extern MQTT_TCB Aliyun_mqtt; //外部变量声明 + int AdapterNetActive(void); int MQTT_Send(const uint8_t* buf, int buflen); int MQTT_Recv(uint8_t* buf, int buflen);