From f59139f78e7f8d30b3f5555b6640aae55f9fb454 Mon Sep 17 00:00:00 2001 From: wgzAIIT <820906721@qq.com> Date: Fri, 26 May 2023 11:23:12 +0800 Subject: [PATCH 01/23] send bin file by 4g --- .../XiZi_IIoT/tool/bootloader/ota/ota.c | 227 +++++++++- .../XiZi_IIoT/tool/bootloader/ota/ota.h | 53 ++- .../tool/bootloader/ota/server_tcp.c | 417 ++++++++++++++++++ 3 files changed, 668 insertions(+), 29 deletions(-) create mode 100644 Ubiquitous/XiZi_IIoT/tool/bootloader/ota/server_tcp.c diff --git a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c index 4e0416e19..f86bec672 100644 --- a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c +++ b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c @@ -1,23 +1,34 @@ /* - * Copyright 2018-2020 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/** -* @file ota.c -* @brief file ota.c -* @version 2.0 -* @author AIIT XUOS Lab -* @date 2023-04-03 +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. */ + +/** +* @file: ota.c +* @brief: file ota.c +* @version: 1.0 +* @author: AIIT XUOS Lab +* @date: 2023/4/23 +* +*/ +#include #include "shell.h" #include "xsconfig.h" #include "mcuboot.h" #include "ymodem.h" #include "ota.h" +#ifdef CONNECTION_ADAPTER_4G +#include +#endif + /**************************************************************************** * Private Function Prototypes ****************************************************************************/ @@ -110,6 +121,29 @@ static uint32_t calculate_crc32(uint32_t addr, uint32_t len) } +/******************************************************************************* +* 函 数 名: calculate_crc16 +* 功能描述: 计算给定长度的数据的crc16的值,用于OTA传输过程中数据帧的校验 +* 形 参: data:数据buffer + len:表示需要计算CRC16的数据长度 +* 返 回 值: 计算得到的CRC16值 +*******************************************************************************/ +static uint16_t calculate_crc16(uint8_t * data, uint32_t len) +{ + uint16_t reg_crc=0xFFFF; + while(len--) { + reg_crc ^= *data++; + for (int j=0;j<8;j++) { + if(reg_crc & 0x01) + reg_crc=reg_crc >>1 ^ 0xA001; + else + reg_crc=reg_crc >>1; + } + } + printf(" crc = [0x%x]\n",reg_crc); + return reg_crc; +} + /******************************************************************************* * 函 数 名: UpdateApplication * 功能描述: 在bootloader里进行调用,根据Flash中Flag分区中的信息决定是否进行版本更新 @@ -305,13 +339,13 @@ static status_t UpdateOTAFlag(ota_info_t *ptr) } -/******************************************************************************* -* 函 数 名: app_ota -* 功能描述: 在app中通过命令来进行ota升级,该函数与升级的命令关联 +/********************************************************************************* +* 函 数 名: app_ota_by_iap +* 功能描述: 通过命令来进行ota升级,该函数与升级的命令关联,通过串口iap方式传输bin文件 * 形 参: 无 * 返 回 值: 无 -*******************************************************************************/ -static void app_ota(void) +*********************************************************************************/ +static void app_ota_by_iap(void) { int32_t size; ota_info_t ota_info; @@ -344,7 +378,7 @@ static void app_ota(void) mcuboot.flash_deinit(); mcuboot.op_reset(); } -SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0),ota, app_ota, ota function); +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0),ota, app_ota_by_iap, ota by iap function); /******************************************************************************* @@ -439,3 +473,160 @@ void ota_entry(void) } } } + + +#ifdef CONNECTION_ADAPTER_4G +/******************************************************************************* +* 函 数 名: ota_data_recv +* 功能描述: 通过4G方式从服务端接收数据 +* 形 参: adapter:Adapter指针,指向注册的4G设备 +* 返 回 值: 0:传输成功,-1:传输失败 +*******************************************************************************/ +static int ota_data_recv(struct Adapter* adapter) +{ + struct ota_data recv_msg; + char reply[16] = {0}; + int ret = 0; + int try_times = 10; + int frame_cnt = 0; + + while(1) { + memset(&recv_msg, 0, sizeof(struct ota_data)); + ret = AdapterDeviceRecv(adapter, &recv_msg, sizeof(struct ota_data)); + if(ret >= 0 && recv_msg.header.frame_flag == 0x5A5A) + { + if(0 == strncmp("aiit_ota_end",recv_msg.frame.frame_data, strlen("aiit_ota_end"))) //说明当前是结束帧 + { + printf("total [%d]frames [%d]Bytes crc[%x],receive successful,\n",frame_cnt,recv_msg.header.total_len,recv_msg.frame.crc); + memset(reply, 0, 16); + memcpy(reply, "ok", strlen("ok")); + + AdapterDeviceSend(adapter, reply, strlen(reply)); + ret = 0; + break; + } + frame_cnt = recv_msg.frame.frame_id; + + if (recv_msg.frame.crc == calculate_crc16(recv_msg.frame.frame_data,recv_msg.frame.frame_len)) + { + printf("current [%d] frame,length[%d] Bytes.\n",frame_cnt,recv_msg.frame.frame_len); + /*写入flash待实现*/ + } + else + { + printf("current [%d] frame crc check failed,try again!\n",frame_cnt); + goto try_again; + } + +send_ok_again: + memset(reply, 0, 16); + memcpy(reply, "ok", strlen("ok")); + + ret = AdapterDeviceSend(adapter, reply, strlen(reply)); + if(ret < 0){ + printf("send ok failed.\n"); + goto send_ok_again; + } + printf("send reply[%s] done.\n",reply); + //send ok后把try_times重置为10 + try_times = 10; + continue; + } + + //没有接收到数据或者接收到的数据帧frame_flag不等于0x5A5A,需要发个retry的命令告诉服务器需要重传 + else + { +try_again: + if(try_times == 0) + { + printf("current [%d] frame try 10 times failed,break out!\n",frame_cnt); + ret = -1; + break; + } + memset(reply, 0, 16); + memcpy(reply, "retry", strlen("retry")); + printf("[%d] frame receive failed. retry\n",frame_cnt); + AdapterDeviceSend(adapter, reply, strlen(reply)); + try_times--; + continue; + } + } + + if(0 == ret) { + printf("ota file done,start application.\n"); + //传输完成需要干什么; + } + return ret; +} + + +/******************************************************************************* +* 函 数 名: OtaKTaskEntry +* 功能描述: 通过命令来进行ota升级,该函数与升级的命令关联,通过4g方式传输bin文件 +* 形 参: adapter:Adapter指针,指向注册的4G设备 +* 返 回 值: 0:传输成功,-1:传输失败 +*******************************************************************************/ +void app_ota_by_4g(void) +{ + struct ota_data recv_msg; + char reply[16] = {0}; + int baud_rate = BAUD_RATE_115200; + int len = 0; + int ret = 0; + + struct Adapter* adapter = AdapterDeviceFindByName(ADAPTER_4G_NAME); + uint8 server_addr[64] = "115.238.53.60"; + uint8 server_port[64] = "7777"; + + adapter->socket.socket_id = 0; + + AdapterDeviceOpen(adapter); + AdapterDeviceControl(adapter, OPE_INT, &baud_rate); + AdapterDeviceConnect(adapter, CLIENT, server_addr, server_port, IPV4); + PrivTaskDelay(100); + while(1) + { + memset(&recv_msg, 0, sizeof(struct ota_data)); + /* step1: Confirm the start signal of transmission*/ + printf("waiting for start msg...\n"); + ret = AdapterDeviceRecv(adapter, &recv_msg, sizeof(struct ota_data)); + if(ret >= 0 && recv_msg.header.frame_flag == 0x5A5A) + { + if (0 == strncmp("aiit_ota_start",recv_msg.frame.frame_data, strlen("aiit_ota_start"))) + { + memset(reply, 0, 16); + memcpy(reply, "ready", strlen("ready")); + printf("receive start signal,send [ready] signal to server\n"); +send_ready_again: + ret = AdapterDeviceSend(adapter, reply, strlen(reply)); + if(ret < 0) + { + goto send_ready_again; + } + printf("start receive ota file.\n"); + /* step2: start receive bin file */ + ret = ota_data_recv(adapter); + if (0 != ret) + { + memset(reply, 0, 16); + memcpy(reply, "ota_restart", strlen("ota_restart")); + AdapterDeviceSend(adapter, reply, strlen(reply)); + continue; + } + else + { + break; + } + } + } + else + { + memset(reply, 0, 16); + memcpy(reply, "notready", strlen("notready")); + ret = AdapterDeviceSend(adapter, reply, strlen(reply)); + } + } +} + +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0),ota4g, app_ota_by_4g, ota by 4g function); +#endif \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.h b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.h index 1eab71bdb..4303b0bf7 100644 --- a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.h +++ b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.h @@ -1,16 +1,22 @@ /* - * Copyright 2018-2020 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + /** -* @file ota.h -* @brief file ota.h -* @version 2.0 -* @author AIIT XUOS Lab -* @date 2023-04-03 +* @file: ota.h +* @brief: file ota.h +* @version: 1.0 +* @author: AIIT XUOS Lab +* @date: 2023/4/23 +* */ #ifndef __OTA_DEF_H__ #define __OTA_DEF_H__ @@ -19,6 +25,7 @@ #define JUMP_FAILED_FLAG 0XABABABAB #define JUMP_SUCCESS_FLAG 0XCDCDCDCD +#define LENGTH 64 //每帧数据的数据包长度 typedef enum { OTA_STATUS_IDLE = 0, // 空闲状态,没有进行OTA升级 @@ -52,6 +59,30 @@ typedef struct { uint8_t error_message[128]; // 错误信息,最多128个字符 } ota_info_t; + +/*bin包传输过程中的数据帧相关的结构体*/ +struct ota_header_t +{ + uint16_t frame_flag; // frame start flag 2 Bytes + uint16_t dev_sid; // device software version + uint32_t total_len; // send data total length caculated from each frame_len +}; + +struct ota_frame_t +{ + uint32_t frame_id; // Current frame id + uint8_t frame_data[LENGTH]; // Current frame data,max length 256 + uint16_t frame_len; // Current frame data length + uint16_t crc; // Current frame data crc +}; + +struct ota_data +{ + struct ota_header_t header; + struct ota_frame_t frame; +}; + + void app_clear_jumpflag(void); void ota_entry(void); #endif diff --git a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/server_tcp.c b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/server_tcp.c new file mode 100644 index 000000000..56534ec73 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/server_tcp.c @@ -0,0 +1,417 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file: ota_server.c +* @brief: a application ota task of system running in Linux +* @version: 1.0 +* @author: AIIT XUOS Lab +* @date: 2023/5/26 +* +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define PORT 7777 //socket端口号 +#define SIZE 100 //socket链接限制为100 +#define LENGTH 64 //每帧数据的数据包长度 +#define BIN_PATH "/home/aep05/wgz/XiZi-xidatong-arm32-app.bin" //bin包的路径 + +struct ota_header_t +{ + uint16_t frame_flag; // frame start flag 2 Bytes + uint16_t dev_sid; // device software version + uint32_t total_len; // send data total length caculated from each frame_len +}; + +struct ota_frame_t +{ + uint32_t frame_id; // Current frame id + uint8_t frame_data[LENGTH]; // Current frame data,max length 256 + uint16_t frame_len; // Current frame data length + uint16_t crc; // Current frame data crc +}; + +struct ota_data +{ + struct ota_header_t header; + struct ota_frame_t frame; +}; + + +static int serverfd; // 服务器socket +static int clientfd[SIZE] = {0}; // 客户端的socketfd,100个元素,clientfd[0]~clientfd[99] + + +/******************************************************************************* +* 函 数 名: calculate_crc16 +* 功能描述: 计算给定长度的数据的crc16的值,用于OTA传输过程中数据帧的校验 +* 形 参: data:数据buffer + len:表示需要计算CRC16的数据长度 +* 返 回 值: 计算得到的CRC16值 +*******************************************************************************/ +static uint16_t calculate_crc16(uint8_t * data, uint32_t len) +{ + uint16_t reg_crc=0xFFFF; + while(len--) { + reg_crc ^= *data++; + for (int j=0;j<8;j++) { + if(reg_crc & 0x01) + reg_crc=reg_crc >>1 ^ 0xA001; + else + reg_crc=reg_crc >>1; + } + } + printf(" crc = [0x%x]\n",reg_crc); + return reg_crc; +} + + +/******************************************************************************* +* 函 数 名: sockt_init +* 功能描述: 用于在TCP Server上创建socet监听 +* 形 参: data:数据buffer + len:表示需要计算CRC16的数据长度 +* 返 回 值: 计算得到的CRC16值 +*******************************************************************************/ +void sockt_init(void) +{ + struct sockaddr_in addr, *sa;//存储套接字的信息 + struct ifaddrs *ifap, *ifa; + char *ipaddr; + + serverfd = socket(AF_INET,SOCK_STREAM,0); + + if (serverfd == -1) + { + perror("创建socket失败"); + exit(-1); + } + + //为套接字设置ip协议 设置端口号并自动获取本机ip转化为网络ip + addr.sin_family = AF_INET;//地址族 + addr.sin_port = htons(PORT);//设置server端端口号,随便设置,当sin_port = 0时,系统随机选择一个未被使用的端口号 + addr.sin_addr.s_addr = htons(INADDR_ANY);//当sin_addr=INADDR_ANY时表示从本机的任一网卡接收数据 + + /*显示当前TCP server的*/ + getifaddrs(&ifap); + for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) { + if (ifa->ifa_addr->sa_family == AF_INET) { + sa = (struct sockaddr_in *) ifa->ifa_addr; + ipaddr = inet_ntoa(sa->sin_addr); + printf("Interface: %s\tAddress: %s\n", ifa->ifa_name, ipaddr); + } + } + freeifaddrs(ifap); + + //绑定套接字 + struct timeval timeout; + timeout.tv_sec = 5; + timeout.tv_usec = 0; + if(setsockopt(serverfd, SOL_SOCKET, SO_REUSEADDR, &timeout, sizeof(struct timeval)) < 0) + { + perror("端口设置失败"); + exit(-1); + } + + if (bind(serverfd,(struct sockaddr*)&addr,sizeof(addr)) == -1) + { + perror("绑定失败"); + exit(-1); + } + + //监听最大连接数 + if (listen(serverfd,SIZE) == -1) + { + perror("设置监听失败"); + exit(-1); + } +} + + +/******************************************************************************* +* 函 数 名: ota_file_send +* 功能描述: 用于在TCP Server发送bin文件 +* 形 参: fd:监听的客户端连接的fd +* 返 回 值: 发送成功返回0,失败返回-1 +*******************************************************************************/ +int ota_file_send(int fd) +{ + unsigned char buf[32] = { 0 }; + struct ota_data data; + FILE *file_fd; + int length = 0; + int try_times; + int recv_end_times = 3; + int ret = 0; + int frame_cnt = 0; + int file_length = 0; + char * file_buf = NULL; + + file_fd = fopen(BIN_PATH, "r"); + if (NULL == file_fd){ + printf("open file failed.\n"); + return -1; + } + fseek(file_fd, 0, SEEK_SET); + printf("start send file.\n"); + + + while(!feof(file_fd)) + { + memset(&data, 0, sizeof(data)); + + data.header.frame_flag = 0x5A5A; + length = fread(data.frame.frame_data, 1, LENGTH, file_fd); + if(length > 0) + { + printf("read %d Bytes\n",length); + data.frame.frame_id = frame_cnt; + data.frame.frame_len = length; + data.frame.crc = calculate_crc16(data.frame.frame_data, length); + file_length += length; + } + +send_again: + printf("ota send current[%d] frame.\n",frame_cnt); + length = send(fd, &data, sizeof(data), MSG_NOSIGNAL); + if(length < 0){ + printf("send [%d] frame faile.go to send again\n",frame_cnt); + goto send_again; + } + +recv_again: + memset(buf, 0, 32); + length = recv(fd, buf, sizeof(buf), 0); + if(length < 0 ){ + printf("[%d] frame waiting for ok timeout,receive again.\n",frame_cnt); + goto recv_again; + } + + //接收到的回复不是ok,说明刚发的包有问题,需要再发一次 + printf("receive buf[%s] length = %d\n",buf, length); + if(0 == strncmp(buf, "ok", length)) + { + try_times = 10; + printf("[%d]frame data send done.\n",frame_cnt); + frame_cnt++; + continue; + } + else + { + if(try_times > 0) + { + try_times--; + goto send_again; + } + else + { + printf("send frame[%d] 10 times failed.\n",frame_cnt); + ret = -1; + break; + } + } + } + + /* finally,crc check total bin file.*/ + if (ret == 0) + { + printf("total send file length[%d] Bytes [%d] frames.\n",file_length,frame_cnt); + printf("now crc check total bin file.\n"); + file_buf = malloc(file_length); + memset(file_buf, 0, file_length); + memset(&data, 0, sizeof(data)); + + data.header.frame_flag = 0x5A5A; + + file_fd = fopen(BIN_PATH, "r"); + if (NULL == file_fd){ + printf("open file failed.\n"); + return -1; + } + fseek(file_fd, 0, SEEK_SET); + length = fread(file_buf,1, file_length, file_fd); + printf("read file length = %d\n",length); + if(length > 0) { + data.frame.frame_id = frame_cnt; + data.header.total_len = file_length; + data.frame.frame_len = strlen("aiit_ota_end"); + data.frame.crc = calculate_crc16(file_buf, length); + memcpy(data.frame.frame_data,"aiit_ota_end",strlen("aiit_ota_end")); + } + +send_end_signal: + printf("send aiit_ota_end signal.\n"); + length = send(fd, &data, sizeof(data), MSG_NOSIGNAL); + if(length < 0){ + printf("send end signal faile,send end signal again\n"); + goto send_end_signal; + } + +recv_end_signal: + memset(buf, 0, 32); + length = recv(fd, buf, sizeof(buf), 0); + if(length < 0 ) + { + recv_end_times--; + printf("end signal waiting for ok timeout,receive again.\n"); + if(recv_end_times > 0) + { + goto recv_end_signal; + } + else + { + ret = -1; + } + } + + if(0 != strncmp(buf, "ok", length)) + { + printf("error end !!!\n"); + ret = -1; + } + + free(file_buf); + } + + fclose(file_fd); + return ret; +} + + +/******************************************************************************* +* 函 数 名: server_thread +* 功能描述: TCP Server的服务线程入口函数 +* 形 参: p:入口函数的参数 +* 返 回 值: 无 +*******************************************************************************/ +void* server_thread(void* p) +{ + int fd = *(int*)p; + unsigned char buf[32] = { 0 }; + struct ota_data data; + int ret = 0; + int length = 0; + + printf("pthread = %d\n",fd); + sleep(8); + while(1) + { + memset(&data, 0x0 , sizeof(struct ota_data)); + data.header.frame_flag = 0x5A5A; + memcpy(data.frame.frame_data,"aiit_ota_start",strlen("aiit_ota_start")); + data.frame.frame_len = strlen("aiit_ota_start"); + + printf("send start signal.\n"); + ret = send(fd, &data, sizeof(data), MSG_NOSIGNAL); + if (ret > 0){ + printf("send %s[%d] Bytes\n",data.frame.frame_data,ret); + } + + memset(buf, 0, 32); + length = recv(fd, buf, sizeof(buf), 0); + if (length <= 0) + { + continue; + } + else + { + printf("recv buf %s length %d\n",buf,length); + if(0 == strncmp(buf, "ready", length)) + { + ret = ota_file_send(fd); + if (ret == 0) { + printf("ota file send successful.\n"); + break; + } else { + /* ota failed then restart the ota process */ + continue; + } + } + } + } + printf("exit fd = %d\n",fd); + close(fd); + pthread_exit(0); +} + + +/******************************************************************************* +* 函 数 名: server +* 功能描述: TCP Server的服务函数 +* 形 参: 无 +* 返 回 值: 无 +*******************************************************************************/ +void server(void) +{ + int i = 0; + printf("ota Server startup\n"); + while(1) + { + struct sockaddr_in fromaddr; + socklen_t len = sizeof(fromaddr); + int fd = accept(serverfd,(struct sockaddr*)&fromaddr,&len);//调用accept进入堵塞状态,等待客户端的连接 + + if (fd == -1) + { + printf("The client connection is wrong...\n"); + continue; + } + + for (i = 0;i < SIZE;i++) + { + if(clientfd[i] == 0) + { + //记录客户端的socket + clientfd[i] = fd; + + //有客户端连接之后,启动线程给此客户服务 + pthread_t tid; + pthread_create(&tid,0,server_thread,&fd); + break; + } + + if (SIZE == i) + { + //发送给客户端聊天室满了 + char* str = "Devices full"; + printf("%s", str); + send(fd,str,strlen(str),0); + close(fd); + } + } + } +} + +int main(void) +{ + sockt_init(); + server(); +} + From 7ba883affe6ff286b65d8028e3a380bae29c281b Mon Sep 17 00:00:00 2001 From: wgzAIIT <820906721@qq.com> Date: Mon, 29 May 2023 10:04:45 +0800 Subject: [PATCH 02/23] modify data length for 4g translation --- .../Framework/connection/4g/ec200t/Kconfig | 2 +- APP_Framework/Framework/connection/at_agent.h | 7 +- .../XiZi_IIoT/board/xidatong-arm32/.defconfig | 8 +- Ubiquitous/XiZi_IIoT/tool/bootloader/Kconfig | 2 + .../XiZi_IIoT/tool/bootloader/ota/ota.h | 2 +- .../tool/bootloader/ota/server_tcp.c | 97 ++++++++++++------- 6 files changed, 81 insertions(+), 37 deletions(-) diff --git a/APP_Framework/Framework/connection/4g/ec200t/Kconfig b/APP_Framework/Framework/connection/4g/ec200t/Kconfig index 01ecea76e..f97268782 100644 --- a/APP_Framework/Framework/connection/4g/ec200t/Kconfig +++ b/APP_Framework/Framework/connection/4g/ec200t/Kconfig @@ -23,7 +23,7 @@ if ADD_XIZI_FETURES config ADAPTER_EC200T_DRIVER string "EC200T device uart driver path" - default "/dev/usart2_dev2" + default "/dev/uart8_dev8" depends on !ADAPTER_EC200T_DRIVER_EXTUART if ADAPTER_EC200T_DRIVER_EXTUART diff --git a/APP_Framework/Framework/connection/at_agent.h b/APP_Framework/Framework/connection/at_agent.h index 42d589a0c..573ed1f9c 100755 --- a/APP_Framework/Framework/connection/at_agent.h +++ b/APP_Framework/Framework/connection/at_agent.h @@ -26,6 +26,12 @@ #include #include +#if defined(CONNECTION_ADAPTER_4G) && defined(TOOL_USING_OTA) +#define ENTM_RECV_MAX 1024 +#else +#define ENTM_RECV_MAX 256 +#endif + #define REPLY_TIME_OUT 10 enum ReceiveMode @@ -70,7 +76,6 @@ struct ATAgent #endif pthread_t at_handler; - #define ENTM_RECV_MAX 256 char entm_recv_buf[ENTM_RECV_MAX]; uint32 entm_recv_len; enum ReceiveMode receive_mode; diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/.defconfig b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/.defconfig index ad4f5b2b4..95c11b65a 100644 --- a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/.defconfig +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/.defconfig @@ -21,8 +21,12 @@ CONFIG_BSP_USING_LPUART3=y CONFIG_SERIAL_BUS_NAME_3="uart3" CONFIG_SERIAL_DRV_NAME_3="uart3_drv" CONFIG_SERIAL_3_DEVICE_NAME_0="uart3_dev3" + # CONFIG_BSP_USING_LPUART4 is not set -# CONFIG_BSP_USING_LPUART8 is not set +CONFIG_BSP_USING_LPUART8=y +CONFIG_SERIAL_BUS_NAME_8="uart8" +CONFIG_SERIAL_DRV_NAME_8="uart8_drv" +CONFIG_SERIAL_8_DEVICE_NAME_0="uart8_dev8" # CONFIG_BSP_USING_CH438 is not set CONFIG_BSP_USING_GPIO=y CONFIG_PIN_BUS_NAME="pin" @@ -230,6 +234,8 @@ CONFIG_ADD_XIZI_FETURES=y # CONFIG_SUPPORT_CONNECTION_FRAMEWORK is not set # CONFIG_SUPPORT_KNOWING_FRAMEWORK is not set # CONFIG_SUPPORT_CONTROL_FRAMEWORK is not set +CONFIG_CONNECTION_FRAMEWORK_DEBUG=n + # # Security diff --git a/Ubiquitous/XiZi_IIoT/tool/bootloader/Kconfig b/Ubiquitous/XiZi_IIoT/tool/bootloader/Kconfig index f5213d718..cb66fafd6 100644 --- a/Ubiquitous/XiZi_IIoT/tool/bootloader/Kconfig +++ b/Ubiquitous/XiZi_IIoT/tool/bootloader/Kconfig @@ -14,6 +14,8 @@ menu "OTA function" config MCUBOOT_APPLICATION bool "Config as application." + select SUPPORT_CONNECTION_FRAMEWORK + select CONNECTION_ADAPTER_4G endchoice diff --git a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.h b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.h index 4303b0bf7..b257dd3ae 100644 --- a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.h +++ b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.h @@ -25,7 +25,7 @@ #define JUMP_FAILED_FLAG 0XABABABAB #define JUMP_SUCCESS_FLAG 0XCDCDCDCD -#define LENGTH 64 //每帧数据的数据包长度 +#define LENGTH 256 //每帧数据的数据包长度 typedef enum { OTA_STATUS_IDLE = 0, // 空闲状态,没有进行OTA升级 diff --git a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/server_tcp.c b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/server_tcp.c index 56534ec73..d74701723 100644 --- a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/server_tcp.c +++ b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/server_tcp.c @@ -40,7 +40,7 @@ #define PORT 7777 //socket端口号 #define SIZE 100 //socket链接限制为100 -#define LENGTH 64 //每帧数据的数据包长度 +#define LENGTH 256 //每帧数据的数据包长度 #define BIN_PATH "/home/aep05/wgz/XiZi-xidatong-arm32-app.bin" //bin包的路径 struct ota_header_t @@ -155,6 +155,50 @@ void sockt_init(void) } +/******************************************************************************* +* 函 数 名: ota_start_signal +* 功能描述: 发送开始信号,等待接收端回应ready +* 形 参: fd:监听的客户端连接的fd +* 返 回 值: 0:成功,-1:失败 +*******************************************************************************/ +void ota_start_signal(int fd) +{ + struct ota_data data; + uint8_t buf[32]; + int ret; + int length = 0; + + while(1) + { + memset(&data, 0x0 , sizeof(struct ota_data)); + data.header.frame_flag = 0x5A5A; + memcpy(data.frame.frame_data,"aiit_ota_start",strlen("aiit_ota_start")); + data.frame.frame_len = strlen("aiit_ota_start"); + + printf("send start signal.\n"); + ret = send(fd, &data, sizeof(data), MSG_NOSIGNAL); + if (ret > 0){ + printf("send %s[%d] Bytes\n",data.frame.frame_data,ret); + } + + memset(buf, 0, 32); + length = recv(fd, buf, sizeof(buf), 0); + if (length > 0 && (0 == strncmp(buf, "ready", length))) + { + printf("recv buf %s length %d\n",buf,length); + break; + } + + else + { + continue; + } + + } + +} + + /******************************************************************************* * 函 数 名: ota_file_send * 功能描述: 用于在TCP Server发送bin文件 @@ -165,15 +209,25 @@ int ota_file_send(int fd) { unsigned char buf[32] = { 0 }; struct ota_data data; + struct stat st; FILE *file_fd; int length = 0; int try_times; int recv_end_times = 3; int ret = 0; - int frame_cnt = 0; + int file_frame_cnt, frame_cnt = 0; int file_length = 0; char * file_buf = NULL; + if (stat(BIN_PATH, &st) == 0) { + //获取文件大小(以字节为单位) + file_frame_cnt = (st.st_size%LENGTH != 0)? (st.st_size/LENGTH + 1):(st.st_size/LENGTH); + printf("File size is %ld bytes,file frame count is %d!\n", st.st_size, file_frame_cnt); + }else{ + printf("get file size failed.\n"); + return -1; + } + file_fd = fopen(BIN_PATH, "r"); if (NULL == file_fd){ printf("open file failed.\n"); @@ -320,41 +374,18 @@ void* server_thread(void* p) int length = 0; printf("pthread = %d\n",fd); - sleep(8); + sleep(5); + ota_start_signal(fd); while(1) { - memset(&data, 0x0 , sizeof(struct ota_data)); - data.header.frame_flag = 0x5A5A; - memcpy(data.frame.frame_data,"aiit_ota_start",strlen("aiit_ota_start")); - data.frame.frame_len = strlen("aiit_ota_start"); - - printf("send start signal.\n"); - ret = send(fd, &data, sizeof(data), MSG_NOSIGNAL); - if (ret > 0){ - printf("send %s[%d] Bytes\n",data.frame.frame_data,ret); - } - - memset(buf, 0, 32); - length = recv(fd, buf, sizeof(buf), 0); - if (length <= 0) - { + ret = ota_file_send(fd); + if (ret == 0) { + printf("ota file send successful.\n"); + break; + } else { + /* ota failed then restart the ota process */ continue; } - else - { - printf("recv buf %s length %d\n",buf,length); - if(0 == strncmp(buf, "ready", length)) - { - ret = ota_file_send(fd); - if (ret == 0) { - printf("ota file send successful.\n"); - break; - } else { - /* ota failed then restart the ota process */ - continue; - } - } - } } printf("exit fd = %d\n",fd); close(fd); From 788eb53f399cda1d73c952a2a2d95500796d4611 Mon Sep 17 00:00:00 2001 From: wgzAIIT <820906721@qq.com> Date: Mon, 29 May 2023 19:47:06 +0800 Subject: [PATCH 03/23] discard invalid data frames --- Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c index f86bec672..2d4634cb9 100644 --- a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c +++ b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c @@ -495,6 +495,12 @@ static int ota_data_recv(struct Adapter* adapter) ret = AdapterDeviceRecv(adapter, &recv_msg, sizeof(struct ota_data)); if(ret >= 0 && recv_msg.header.frame_flag == 0x5A5A) { + if(0 == strncmp("aiit_ota_start",recv_msg.frame.frame_data, strlen("aiit_ota_start"))) + { + //这里不应该再出现开始信号,丢弃当前数据继续接收 + continue; + } + if(0 == strncmp("aiit_ota_end",recv_msg.frame.frame_data, strlen("aiit_ota_end"))) //说明当前是结束帧 { printf("total [%d]frames [%d]Bytes crc[%x],receive successful,\n",frame_cnt,recv_msg.header.total_len,recv_msg.frame.crc); From c6af847c7325f7c605115d6776368d3b0fb44ea9 Mon Sep 17 00:00:00 2001 From: wgzAIIT <820906721@qq.com> Date: Tue, 30 May 2023 20:11:43 +0800 Subject: [PATCH 04/23] Improve the speed of 4G transmission bin package --- Ubiquitous/XiZi_IIoT/resources/serial/dev_serial.c | 2 ++ Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c | 3 ++- Ubiquitous/XiZi_IIoT/tool/bootloader/ota/server_tcp.c | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Ubiquitous/XiZi_IIoT/resources/serial/dev_serial.c b/Ubiquitous/XiZi_IIoT/resources/serial/dev_serial.c index 428e1c935..fcd9aeefd 100644 --- a/Ubiquitous/XiZi_IIoT/resources/serial/dev_serial.c +++ b/Ubiquitous/XiZi_IIoT/resources/serial/dev_serial.c @@ -154,7 +154,9 @@ static inline int SerialDevIntRead(struct SerialHardwareDevice *serial_dev, stru CriticalAreaUnLock(lock); +#ifndef TOOL_USING_OTA MdelayKTask(20); +#endif *read_data = get_char; read_data++; diff --git a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c index 2d4634cb9..0c26a69a1 100644 --- a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c +++ b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c @@ -610,7 +610,8 @@ send_ready_again: goto send_ready_again; } printf("start receive ota file.\n"); - /* step2: start receive bin file */ + /* step2: start receive bin file,first wait for 5s*/ + PrivTaskDelay(5000); ret = ota_data_recv(adapter); if (0 != ret) { diff --git a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/server_tcp.c b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/server_tcp.c index d74701723..108e9e896 100644 --- a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/server_tcp.c +++ b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/server_tcp.c @@ -376,6 +376,7 @@ void* server_thread(void* p) printf("pthread = %d\n",fd); sleep(5); ota_start_signal(fd); + sleep(5); while(1) { ret = ota_file_send(fd); From 938d46d5d981ec82c7c248aff3e86709ba658b91 Mon Sep 17 00:00:00 2001 From: wgzAIIT <820906721@qq.com> Date: Wed, 31 May 2023 14:07:45 +0800 Subject: [PATCH 05/23] Modify the tcp server to send 1024 bytes each time --- APP_Framework/Framework/connection/at_agent.h | 7 +- .../XiZi_IIoT/board/xidatong-arm32/.defconfig | 2 +- .../XiZi_IIoT/tool/bootloader/ota/ota.c | 30 ++++---- .../XiZi_IIoT/tool/bootloader/ota/ota.h | 2 +- .../tool/bootloader/ota/server_tcp.c | 73 ++++++++++++------- 5 files changed, 65 insertions(+), 49 deletions(-) diff --git a/APP_Framework/Framework/connection/at_agent.h b/APP_Framework/Framework/connection/at_agent.h index 573ed1f9c..2455146e4 100755 --- a/APP_Framework/Framework/connection/at_agent.h +++ b/APP_Framework/Framework/connection/at_agent.h @@ -26,12 +26,6 @@ #include #include -#if defined(CONNECTION_ADAPTER_4G) && defined(TOOL_USING_OTA) -#define ENTM_RECV_MAX 1024 -#else -#define ENTM_RECV_MAX 256 -#endif - #define REPLY_TIME_OUT 10 enum ReceiveMode @@ -76,6 +70,7 @@ struct ATAgent #endif pthread_t at_handler; + #define ENTM_RECV_MAX 2048 char entm_recv_buf[ENTM_RECV_MAX]; uint32 entm_recv_len; enum ReceiveMode receive_mode; diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/.defconfig b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/.defconfig index 95c11b65a..7d4fa4771 100644 --- a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/.defconfig +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/.defconfig @@ -67,7 +67,7 @@ CONFIG___STACKSIZE__=4096 # CONFIG_RESOURCES_SERIAL=y CONFIG_SERIAL_USING_DMA=y -CONFIG_SERIAL_RB_BUFSZ=128 +CONFIG_SERIAL_RB_BUFSZ=256 CONFIG_RESOURCES_PIN=y # diff --git a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c index 0c26a69a1..9bf31420b 100644 --- a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c +++ b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c @@ -131,16 +131,18 @@ static uint32_t calculate_crc32(uint32_t addr, uint32_t len) static uint16_t calculate_crc16(uint8_t * data, uint32_t len) { uint16_t reg_crc=0xFFFF; - while(len--) { + while(len--) + { reg_crc ^= *data++; - for (int j=0;j<8;j++) { + for(int j=0;j<8;j++) + { if(reg_crc & 0x01) reg_crc=reg_crc >>1 ^ 0xA001; else reg_crc=reg_crc >>1; } } - printf(" crc = [0x%x]\n",reg_crc); + printf("crc = [0x%x]\n",reg_crc); return reg_crc; } @@ -490,7 +492,8 @@ static int ota_data_recv(struct Adapter* adapter) int try_times = 10; int frame_cnt = 0; - while(1) { + while(1) + { memset(&recv_msg, 0, sizeof(struct ota_data)); ret = AdapterDeviceRecv(adapter, &recv_msg, sizeof(struct ota_data)); if(ret >= 0 && recv_msg.header.frame_flag == 0x5A5A) @@ -506,14 +509,13 @@ static int ota_data_recv(struct Adapter* adapter) printf("total [%d]frames [%d]Bytes crc[%x],receive successful,\n",frame_cnt,recv_msg.header.total_len,recv_msg.frame.crc); memset(reply, 0, 16); memcpy(reply, "ok", strlen("ok")); - AdapterDeviceSend(adapter, reply, strlen(reply)); ret = 0; break; } frame_cnt = recv_msg.frame.frame_id; - if (recv_msg.frame.crc == calculate_crc16(recv_msg.frame.frame_data,recv_msg.frame.frame_len)) + if(recv_msg.frame.crc == calculate_crc16(recv_msg.frame.frame_data,recv_msg.frame.frame_len)) { printf("current [%d] frame,length[%d] Bytes.\n",frame_cnt,recv_msg.frame.frame_len); /*写入flash待实现*/ @@ -529,7 +531,8 @@ send_ok_again: memcpy(reply, "ok", strlen("ok")); ret = AdapterDeviceSend(adapter, reply, strlen(reply)); - if(ret < 0){ + if(ret < 0) + { printf("send ok failed.\n"); goto send_ok_again; } @@ -558,7 +561,8 @@ try_again: } } - if(0 == ret) { + if(0 == ret) + { printf("ota file done,start application.\n"); //传输完成需要干什么; } @@ -593,12 +597,12 @@ void app_ota_by_4g(void) while(1) { memset(&recv_msg, 0, sizeof(struct ota_data)); - /* step1: Confirm the start signal of transmission*/ + /* step1:Confirm the start signal of transmission. */ printf("waiting for start msg...\n"); ret = AdapterDeviceRecv(adapter, &recv_msg, sizeof(struct ota_data)); if(ret >= 0 && recv_msg.header.frame_flag == 0x5A5A) { - if (0 == strncmp("aiit_ota_start",recv_msg.frame.frame_data, strlen("aiit_ota_start"))) + if(0 == strncmp("aiit_ota_start",recv_msg.frame.frame_data, strlen("aiit_ota_start"))) { memset(reply, 0, 16); memcpy(reply, "ready", strlen("ready")); @@ -610,10 +614,10 @@ send_ready_again: goto send_ready_again; } printf("start receive ota file.\n"); - /* step2: start receive bin file,first wait for 5s*/ - PrivTaskDelay(5000); + /* step2:start receive bin file,first wait for 4s. */ + PrivTaskDelay(4000); ret = ota_data_recv(adapter); - if (0 != ret) + if(0 != ret) { memset(reply, 0, 16); memcpy(reply, "ota_restart", strlen("ota_restart")); diff --git a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.h b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.h index b257dd3ae..46b63d56b 100644 --- a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.h +++ b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.h @@ -25,7 +25,7 @@ #define JUMP_FAILED_FLAG 0XABABABAB #define JUMP_SUCCESS_FLAG 0XCDCDCDCD -#define LENGTH 256 //每帧数据的数据包长度 +#define LENGTH 1024 //每帧数据的数据包长度 typedef enum { OTA_STATUS_IDLE = 0, // 空闲状态,没有进行OTA升级 diff --git a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/server_tcp.c b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/server_tcp.c index 108e9e896..0dbca44b7 100644 --- a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/server_tcp.c +++ b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/server_tcp.c @@ -38,9 +38,9 @@ #include -#define PORT 7777 //socket端口号 -#define SIZE 100 //socket链接限制为100 -#define LENGTH 256 //每帧数据的数据包长度 +#define PORT 7777 //socket端口号 +#define SIZE 100 //socket链接限制为100 +#define LENGTH 1024 //每帧数据的数据包长度 #define BIN_PATH "/home/aep05/wgz/XiZi-xidatong-arm32-app.bin" //bin包的路径 struct ota_header_t @@ -79,16 +79,18 @@ static int clientfd[SIZE] = {0}; // 客户端的socketfd,100个元素,clientfd static uint16_t calculate_crc16(uint8_t * data, uint32_t len) { uint16_t reg_crc=0xFFFF; - while(len--) { + while(len--) + { reg_crc ^= *data++; - for (int j=0;j<8;j++) { + for(int j=0;j<8;j++) + { if(reg_crc & 0x01) reg_crc=reg_crc >>1 ^ 0xA001; else reg_crc=reg_crc >>1; } } - printf(" crc = [0x%x]\n",reg_crc); + printf("crc = [0x%x]\n",reg_crc); return reg_crc; } @@ -108,7 +110,7 @@ void sockt_init(void) serverfd = socket(AF_INET,SOCK_STREAM,0); - if (serverfd == -1) + if(serverfd == -1) { perror("创建socket失败"); exit(-1); @@ -121,8 +123,10 @@ void sockt_init(void) /*显示当前TCP server的*/ getifaddrs(&ifap); - for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) { - if (ifa->ifa_addr->sa_family == AF_INET) { + for(ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) + { + if(ifa->ifa_addr->sa_family == AF_INET) + { sa = (struct sockaddr_in *) ifa->ifa_addr; ipaddr = inet_ntoa(sa->sin_addr); printf("Interface: %s\tAddress: %s\n", ifa->ifa_name, ipaddr); @@ -140,14 +144,14 @@ void sockt_init(void) exit(-1); } - if (bind(serverfd,(struct sockaddr*)&addr,sizeof(addr)) == -1) + if(bind(serverfd,(struct sockaddr*)&addr,sizeof(addr)) == -1) { perror("绑定失败"); exit(-1); } //监听最大连接数 - if (listen(serverfd,SIZE) == -1) + if(listen(serverfd,SIZE) == -1) { perror("设置监听失败"); exit(-1); @@ -177,13 +181,14 @@ void ota_start_signal(int fd) printf("send start signal.\n"); ret = send(fd, &data, sizeof(data), MSG_NOSIGNAL); - if (ret > 0){ + if(ret > 0) + { printf("send %s[%d] Bytes\n",data.frame.frame_data,ret); } memset(buf, 0, 32); length = recv(fd, buf, sizeof(buf), 0); - if (length > 0 && (0 == strncmp(buf, "ready", length))) + if(length > 0 && (0 == strncmp(buf, "ready", length))) { printf("recv buf %s length %d\n",buf,length); break; @@ -219,17 +224,21 @@ int ota_file_send(int fd) int file_length = 0; char * file_buf = NULL; - if (stat(BIN_PATH, &st) == 0) { + if(stat(BIN_PATH, &st) == 0) + { //获取文件大小(以字节为单位) file_frame_cnt = (st.st_size%LENGTH != 0)? (st.st_size/LENGTH + 1):(st.st_size/LENGTH); printf("File size is %ld bytes,file frame count is %d!\n", st.st_size, file_frame_cnt); - }else{ + } + else + { printf("get file size failed.\n"); return -1; } file_fd = fopen(BIN_PATH, "r"); - if (NULL == file_fd){ + if(NULL == file_fd) + { printf("open file failed.\n"); return -1; } @@ -255,7 +264,8 @@ int ota_file_send(int fd) send_again: printf("ota send current[%d] frame.\n",frame_cnt); length = send(fd, &data, sizeof(data), MSG_NOSIGNAL); - if(length < 0){ + if(length < 0) + { printf("send [%d] frame faile.go to send again\n",frame_cnt); goto send_again; } @@ -263,7 +273,8 @@ send_again: recv_again: memset(buf, 0, 32); length = recv(fd, buf, sizeof(buf), 0); - if(length < 0 ){ + if(length < 0 ) + { printf("[%d] frame waiting for ok timeout,receive again.\n",frame_cnt); goto recv_again; } @@ -294,7 +305,7 @@ recv_again: } /* finally,crc check total bin file.*/ - if (ret == 0) + if(ret == 0) { printf("total send file length[%d] Bytes [%d] frames.\n",file_length,frame_cnt); printf("now crc check total bin file.\n"); @@ -305,14 +316,16 @@ recv_again: data.header.frame_flag = 0x5A5A; file_fd = fopen(BIN_PATH, "r"); - if (NULL == file_fd){ + if(NULL == file_fd) + { printf("open file failed.\n"); return -1; } fseek(file_fd, 0, SEEK_SET); length = fread(file_buf,1, file_length, file_fd); printf("read file length = %d\n",length); - if(length > 0) { + if(length > 0) + { data.frame.frame_id = frame_cnt; data.header.total_len = file_length; data.frame.frame_len = strlen("aiit_ota_end"); @@ -323,7 +336,8 @@ recv_again: send_end_signal: printf("send aiit_ota_end signal.\n"); length = send(fd, &data, sizeof(data), MSG_NOSIGNAL); - if(length < 0){ + if(length < 0) + { printf("send end signal faile,send end signal again\n"); goto send_end_signal; } @@ -374,16 +388,19 @@ void* server_thread(void* p) int length = 0; printf("pthread = %d\n",fd); - sleep(5); + sleep(3); ota_start_signal(fd); sleep(5); while(1) { ret = ota_file_send(fd); - if (ret == 0) { + if(ret == 0) + { printf("ota file send successful.\n"); break; - } else { + } + else + { /* ota failed then restart the ota process */ continue; } @@ -410,13 +427,13 @@ void server(void) socklen_t len = sizeof(fromaddr); int fd = accept(serverfd,(struct sockaddr*)&fromaddr,&len);//调用accept进入堵塞状态,等待客户端的连接 - if (fd == -1) + if(fd == -1) { printf("The client connection is wrong...\n"); continue; } - for (i = 0;i < SIZE;i++) + for(i = 0;i < SIZE;i++) { if(clientfd[i] == 0) { @@ -429,7 +446,7 @@ void server(void) break; } - if (SIZE == i) + if(SIZE == i) { //发送给客户端聊天室满了 char* str = "Devices full"; From 5faa3e7b5a55d78952ac6487076c170d086285a0 Mon Sep 17 00:00:00 2001 From: wgzAIIT <820906721@qq.com> Date: Wed, 31 May 2023 18:11:57 +0800 Subject: [PATCH 06/23] Optimize functions related to flash operation --- .../third_party_driver/common/flash.c | 398 +++++++++--------- .../third_party_driver/common/ymodem.c | 11 +- .../third_party_driver/include/flash.h | 20 +- .../tool/bootloader/flash/flash_ops.h | 4 +- .../XiZi_IIoT/tool/bootloader/ota/ota.c | 13 +- 5 files changed, 214 insertions(+), 232 deletions(-) diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/common/flash.c b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/common/flash.c index b10baee6b..a1d77d816 100644 --- a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/common/flash.c +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/common/flash.c @@ -507,7 +507,7 @@ static status_t flexspi_config_mcr1(uint32_t instance, flexspi_mem_config_t *con // Configure MCR1 FLEXSPI->MCR1 = FLEXSPI_MCR1_SEQWAIT(seqWaitTicks) | FLEXSPI_MCR1_AHBBUSWAIT(ahbBusWaitTicks); - return kStatus_Success; + return (status_t)kStatus_Success; } @@ -647,14 +647,14 @@ uint8_t FLASH_WritePage(uint32_t addr, const uint32_t *buf, uint32_t len) /******************************************************************************* -* 函 数 名: FLASH_Read +* 函 数 名: FLASH_ReadBuf * 功能描述: 读Flash内容 * 形 参: addr:读取区域起始地址 buf:数据存储区 len:要读取的字节数 * 返 回 值: 如果函数执行成功,状态值为 kStatus_Success,否则状态值为其他错误码 *******************************************************************************/ -status_t FLASH_Read(uint32_t addr, uint32_t *buf, uint32_t len) +status_t FLASH_ReadBuf(uint32_t addr, uint32_t *buf, uint32_t len) { status_t status; flexspi_xfer_t flashXfer; @@ -678,206 +678,28 @@ status_t FLASH_Read(uint32_t addr, uint32_t *buf, uint32_t len) } -/******************************************************************************* -* 函 数 名: flash_erase -* 功能描述: 擦除Flash指定长度的空间 -* 形 参: addr:擦除区域起始地址 - byte_cnt:要擦除的字节数,以4k字节为最小擦除单位 -* 返 回 值: 如果函数执行成功,状态值为 kStatus_Success,否则状态值为其他错误码 -* 注 释: 不满4k字节的,也需要擦除掉4k字节 -*******************************************************************************/ -status_t flash_erase(uint32_t start_addr, uint32_t byte_cnt) -{ - uint32_t addr; - status_t status; - - addr = start_addr; - while(addr < (byte_cnt + start_addr)) - { - status = FLASH_EraseSector(addr); - if(status != kStatus_Success) - { - return status; - } - addr += FLASH_GetSectorSize(); - } - return status; -} - - -/******************************************************************************* -* 函 数 名: flash_write -* 功能描述: 在指定的flash起始地址写入指定长度的数据 -* 形 参: addr:写入区域起始地址 - buf:数据存储区 - byte_cnt:要写入的字节数 -* 返 回 值: 如果函数执行成功,状态值为 kStatus_Success,否则状态值为其他错误码 -*******************************************************************************/ -status_t flash_write(uint32_t start_addr, uint8_t *buf, uint32_t byte_cnt) -{ - uint32_t size; - status_t status; - while(byte_cnt > 0) - { - size = byte_cnt > FLASH_PAGE_SIZE ? FLASH_PAGE_SIZE : byte_cnt; - status = FLASH_WritePage(start_addr, (void *)buf, size); - if(status != kStatus_Success) - { - return status; - } - start_addr += size; - buf += size; - byte_cnt -= size; - } - - return kStatus_Success; -} - - -/******************************************************************************* -* 函 数 名: flash_read -* 功能描述: 读Flash内容 -* 形 参: addr:读取区域起始地址 - buf:数据存储区 - len:要读取的字节数 -* 返 回 值: 如果函数执行成功,状态值为 kStatus_Success,否则状态值为其他错误码 -*******************************************************************************/ -status_t flash_read(uint32_t addr, uint8_t *buf, uint32_t len) -{ - /* For FlexSPI Memory ReadBack, use IP Command instead of AXI command for security */ - if((addr >= 0x60000000) && (addr < 0x61000000)) - { - return FLASH_Read(addr, (void *)buf, len); - } - - else - { - void* result = memcpy(buf, (void*)addr, len); - if(result == NULL) - { - return (status_t)kStatus_Fail; - } - else - { - return (status_t)kStatus_Success; - } - - } -} - - -/******************************************************************************* -* 函 数 名: flash_copy -* 功能描述: 实现flash数据在分区之间的拷贝 -* 形 参: srcAddr:源flash的起始地址 - dstAddr:目标flash的起始地址; - imageSize:要拷贝的flash空间大小,单位为字节 -* 返 回 值: 如果函数执行成功,状态值为 kStatus_Success,否则状态值为其他错误码 -*******************************************************************************/ -status_t flash_copy(uint32_t srcAddr,uint32_t dstAddr, uint32_t imageSize) -{ - uint32_t PageNum, Remain, i; - status_t status; - - if((srcAddr == dstAddr) || imageSize > APP_FLASH_SIZE) - { - return (status_t)kStatus_Fail; - } - - status = flash_erase(dstAddr,imageSize); - if(status != kStatus_Success) - { - KPrintf("Erase flash 0x%08x failure !\r\n",dstAddr); - return status; - } - - PageNum = imageSize/FLASH_PAGE_SIZE; - Remain = imageSize%FLASH_PAGE_SIZE; - - for(i=0;i= 0x60000000) && (addr < 0x61000000)) + { + return FLASH_ReadBuf(addr, (void *)buf, len); + } + + else + { + void* result = memcpy(buf, (void*)addr, len); + if(result == NULL) + { + return (status_t)kStatus_Fail; + } + else + { + return (status_t)kStatus_Success; + } + + } +} + + +/******************************************************************************* +* 函 数 名: Flash_Copy +* 功能描述: 实现flash数据在分区之间的拷贝 +* 形 参: srcAddr:源flash的起始地址 + dstAddr:目标flash的起始地址; + imageSize:要拷贝的flash空间大小,单位为字节 +* 返 回 值: 如果函数执行成功,状态值为 kStatus_Success,否则状态值为其他错误码 +*******************************************************************************/ +status_t Flash_Copy(uint32_t srcAddr,uint32_t dstAddr, uint32_t imageSize) +{ + uint32_t PageNum, Remain, i; + status_t status; + + if((srcAddr == dstAddr) || imageSize > APP_FLASH_SIZE) + { + return (status_t)kStatus_Fail; + } + + status = Flash_Erase(dstAddr,imageSize); + if(status != kStatus_Success) + { + KPrintf("Erase flash 0x%08x failure !\r\n",dstAddr); + return status; + } + + PageNum = imageSize/FLASH_PAGE_SIZE; + Remain = imageSize%FLASH_PAGE_SIZE; + + for(i=0;i=SECTOR_SIZE) { - NorFlash_Write(dataBuff,WriteAddr,dataLen); + status = Flash_Write(WriteAddr,dataBuff,dataLen); + if (status != kStatus_Success) + { + return status; + } packetNum = 0; dataLen = 0; } @@ -1050,10 +1032,14 @@ uint32_t NOR_FLASH_Write(uint32_t* FlashAddress, uint8_t* Data ,uint16_t DataLen } else { - NorFlash_Write(dataBuff,WriteAddr,dataLen); + status = Flash_Write(WriteAddr,dataBuff,dataLen); + if (status != kStatus_Success) + { + return status; + } packetNum = 0; dataLen = 0; } - return (0); + return (status_t)kStatus_Success;; } #endif diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/common/ymodem.c b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/common/ymodem.c index 661f6e81c..f443f60a8 100644 --- a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/common/ymodem.c +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/common/ymodem.c @@ -280,7 +280,7 @@ int32_t Ymodem_Receive(uint8_t *buf, const uint32_t addr) } /* erase user application area */ - NOR_FLASH_Erase(addr,size); + Flash_Erase(addr,size); Send_Byte(ACK); Send_Byte(CRC16); } @@ -300,9 +300,9 @@ int32_t Ymodem_Receive(uint8_t *buf, const uint32_t addr) /* Write received data in Flash */ #ifndef USE_HIGHT_SPEED_TRANS - if(NOR_FLASH_Write(&flashdestination, buf, (uint16_t)packet_length) == 0) + if(NOR_FLASH_Write(&flashdestination, buf, (uint16_t)packet_length) == kStatus_Success) #else - if(NOR_FLASH_Write(&flashdestination, buf, (uint16_t)packet_length, 0) == 0) + if(NOR_FLASH_Write(&flashdestination, buf, (uint16_t)packet_length, 0) == kStatus_Success) #endif { Send_Byte(ACK); @@ -349,7 +349,10 @@ int32_t Ymodem_Receive(uint8_t *buf, const uint32_t addr) } } #ifdef USE_HIGHT_SPEED_TRANS - NOR_FLASH_Write(&flashdestination, buf, (uint16_t) packet_length,1); + if(NOR_FLASH_Write(&flashdestination, buf, (uint16_t) packet_length,1) != kStatus_Success) + { + return -4; + } #endif return (int32_t)size; } diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/include/flash.h b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/include/flash.h index fd59738cb..a71feeceb 100644 --- a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/include/flash.h +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/include/flash.h @@ -63,21 +63,19 @@ void FLASH_Init(void); void FLASH_DeInit(void); uint8_t FLASH_EraseSector(uint32_t addr); uint8_t FLASH_WritePage(uint32_t addr, const uint32_t *buf, uint32_t len); -status_t FLASH_Read(uint32_t addr, uint32_t *buf, uint32_t len); -status_t flash_erase(uint32_t start_addr, uint32_t byte_cnt); -status_t flash_write(uint32_t start_addr, uint8_t *buf, uint32_t byte_cnt); -status_t flash_read(uint32_t addr, uint8_t *buf, uint32_t len); -status_t flash_copy(uint32_t srcAddr,uint32_t dstAddr, uint32_t imageSize); +status_t FLASH_ReadBuf(uint32_t addr, uint32_t *buf, uint32_t len); +status_t NorFlash_Write_PageProgram(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite); +status_t NorFlash_Write_NoCheck(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite); -status_t NOR_FLASH_Erase(uint32_t app_base_addr,uint32_t imageSize); -void NorFlash_Write_PageProgram(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite); -void NorFlash_Write_NoCheck(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite); -void NorFlash_Write(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite); +status_t Flash_Erase(uint32_t start_addr, uint32_t imageSize); +status_t Flash_Write(uint32_t WriteAddr, uint8_t *pBuffer, uint32_t NumByteToWrite); +status_t Flash_Read(uint32_t addr, uint8_t *buf, uint32_t len); +status_t Flash_Copy(uint32_t srcAddr,uint32_t dstAddr, uint32_t imageSize); #ifndef USE_HIGHT_SPEED_TRANS -uint32_t NOR_FLASH_Write(uint32_t* FlashAddress, uint8_t* Data ,uint16_t DataLength); +status_t NOR_FLASH_Write(uint32_t* FlashAddress, uint8_t* Data ,uint16_t DataLength); #else -uint32_t NOR_FLASH_Write(uint32_t* FlashAddress, uint8_t* Data ,uint16_t DataLength,uint8_t doneFlag); +status_t NOR_FLASH_Write(uint32_t* FlashAddress, uint8_t* Data ,uint16_t DataLength,uint8_t doneFlag); #endif #endif diff --git a/Ubiquitous/XiZi_IIoT/tool/bootloader/flash/flash_ops.h b/Ubiquitous/XiZi_IIoT/tool/bootloader/flash/flash_ops.h index b0ff530f0..e75abcd2e 100644 --- a/Ubiquitous/XiZi_IIoT/tool/bootloader/flash/flash_ops.h +++ b/Ubiquitous/XiZi_IIoT/tool/bootloader/flash/flash_ops.h @@ -30,8 +30,8 @@ typedef struct void (*flash_deinit)(void); /* flash operation */ - status_t (*op_flash_erase)(uint32_t start_addr, uint32_t byte_cnt); - status_t (*op_flash_write)(uint32_t start_addr, uint8_t *buf, uint32_t byte_cnt); + status_t (*op_flash_erase)(uint32_t start_addr, uint32_t imageSize); + status_t (*op_flash_write)(uint32_t WriteAddr, uint8_t *pBuffer, uint32_t NumByteToWrite); status_t (*op_flash_read)(uint32_t addr, uint8_t *buf, uint32_t len); status_t (*op_flash_copy)(uint32_t srcAddr,uint32_t dstAddr, uint32_t imageSize); diff --git a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c index 9bf31420b..28f412d93 100644 --- a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c +++ b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c @@ -39,11 +39,6 @@ static void BackupVersion(void); static void BootLoaderJumpApp(void); static status_t UpdateOTAFlag(ota_info_t *ptr); -#ifdef MCUBOOT_APPLICATION -static void app_ota(void); -#endif - - /**************************************************************************** * Private Data ****************************************************************************/ @@ -54,10 +49,10 @@ static const mcuboot_t mcuboot = Serial_PutString, FLASH_Init, FLASH_DeInit, - flash_erase, - flash_write, - flash_read, - flash_copy, + Flash_Erase, + Flash_Write, + Flash_Read, + Flash_Copy, SerialDownload, mcuboot_reset, mcuboot_jump, From 8ecb3a880420481d4170bce89832165336ce2bc2 Mon Sep 17 00:00:00 2001 From: wgzAIIT <820906721@qq.com> Date: Thu, 1 Jun 2023 11:14:24 +0800 Subject: [PATCH 07/23] OTA upgrade through 4G is successful --- .../XiZi_IIoT/tool/bootloader/ota/ota.c | 82 ++++++++++++++----- .../tool/bootloader/ota/server_tcp.c | 63 ++++++++------ 2 files changed, 100 insertions(+), 45 deletions(-) diff --git a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c index 28f412d93..9a234d0a1 100644 --- a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c +++ b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c @@ -375,7 +375,7 @@ static void app_ota_by_iap(void) mcuboot.flash_deinit(); mcuboot.op_reset(); } -SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0),ota, app_ota_by_iap, ota by iap function); +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0),iap, app_ota_by_iap, ota by iap function); /******************************************************************************* @@ -482,11 +482,16 @@ void ota_entry(void) static int ota_data_recv(struct Adapter* adapter) { struct ota_data recv_msg; + ota_info_t ota_info; char reply[16] = {0}; - int ret = 0; - int try_times = 10; - int frame_cnt = 0; + int ret = 0, try_times = 10, frame_cnt = 0; + uint32_t file_size = 0; + uint32_t flashdestination = DOWN_FLAH_ADDRESS; + mcuboot.op_flash_read(FLAG_FLAH_ADDRESS, (void*)&ota_info, sizeof(ota_info_t)); + ota_info.status = OTA_STATUS_DOWNLOADING; + UpdateOTAFlag(&ota_info); + while(1) { memset(&recv_msg, 0, sizeof(struct ota_data)); @@ -501,23 +506,37 @@ static int ota_data_recv(struct Adapter* adapter) if(0 == strncmp("aiit_ota_end",recv_msg.frame.frame_data, strlen("aiit_ota_end"))) //说明当前是结束帧 { - printf("total [%d]frames [%d]Bytes crc[%x],receive successful,\n",frame_cnt,recv_msg.header.total_len,recv_msg.frame.crc); + printf("total %d frames %d bytes crc[0x%x],receive successful,\n",frame_cnt,recv_msg.header.total_len,recv_msg.frame.crc); memset(reply, 0, 16); memcpy(reply, "ok", strlen("ok")); AdapterDeviceSend(adapter, reply, strlen(reply)); + + ota_info.status = OTA_STATUS_DOWNLOADED; + UpdateOTAFlag(&ota_info); + + file_size = recv_msg.header.total_len; ret = 0; break; } frame_cnt = recv_msg.frame.frame_id; - if(recv_msg.frame.crc == calculate_crc16(recv_msg.frame.frame_data,recv_msg.frame.frame_len)) { - printf("current [%d] frame,length[%d] Bytes.\n",frame_cnt,recv_msg.frame.frame_len); - /*写入flash待实现*/ + printf("current[%d] frame,length %d bytes.\n",frame_cnt,recv_msg.frame.frame_len); + if(mcuboot.op_flash_write(flashdestination, recv_msg.frame.frame_data, recv_msg.frame.frame_len) != kStatus_Success) + { + printf("current[%d] frame flash failed.\n",frame_cnt); + ret = -1; + break; + } + else + { + printf("current[%d] frame is written to flash 0x%x address successful.\n", frame_cnt, flashdestination); + flashdestination += recv_msg.frame.frame_len; + } } else { - printf("current [%d] frame crc check failed,try again!\n",frame_cnt); + printf("current[%d] frame crc check failed,try again!\n",frame_cnt); goto try_again; } @@ -543,7 +562,7 @@ send_ok_again: try_again: if(try_times == 0) { - printf("current [%d] frame try 10 times failed,break out!\n",frame_cnt); + printf("current[%d] frame try 10 times failed,break out!\n",frame_cnt); ret = -1; break; } @@ -556,10 +575,22 @@ try_again: } } - if(0 == ret) - { - printf("ota file done,start application.\n"); - //传输完成需要干什么; + //download分区固件下载成功,更新Flag分区 + if(0 == ret) + { + ota_info.down.size = file_size; + ota_info.down.crc32= calculate_crc32(DOWN_FLAH_ADDRESS, file_size); + ota_info.down.version = ota_info.os.version + 1; + strncpy(ota_info.down.description, "4G OTA bin package !",sizeof(ota_info.down.description)); + ota_info.status = OTA_STATUS_READY; + strncpy(ota_info.error_message, "No error message!",sizeof(ota_info.error_message)); + UpdateOTAFlag(&ota_info); + } + else + { + ota_info.status = OTA_STATUS_ERROR; + strncpy(ota_info.error_message, "Failed to download firmware to download partition!",sizeof(ota_info.error_message)); + UpdateOTAFlag(&ota_info); } return ret; } @@ -575,14 +606,14 @@ void app_ota_by_4g(void) { struct ota_data recv_msg; char reply[16] = {0}; - int baud_rate = BAUD_RATE_115200; - int len = 0; + uint32_t baud_rate = BAUD_RATE_115200; int ret = 0; - - struct Adapter* adapter = AdapterDeviceFindByName(ADAPTER_4G_NAME); uint8 server_addr[64] = "115.238.53.60"; uint8 server_port[64] = "7777"; + mcuboot.flash_init(); + + struct Adapter* adapter = AdapterDeviceFindByName(ADAPTER_4G_NAME); adapter->socket.socket_id = 0; AdapterDeviceOpen(adapter); @@ -599,6 +630,13 @@ void app_ota_by_4g(void) { if(0 == strncmp("aiit_ota_start",recv_msg.frame.frame_data, strlen("aiit_ota_start"))) { + if(mcuboot.op_flash_erase(DOWN_FLAH_ADDRESS,recv_msg.header.total_len) != kStatus_Success) + { + printf("Failed to erase target fash!\n"); + break; + } else { + printf("Erase flash successful,Erase length is %d bytes.\n",recv_msg.header.total_len); + } memset(reply, 0, 16); memcpy(reply, "ready", strlen("ready")); printf("receive start signal,send [ready] signal to server\n"); @@ -608,7 +646,7 @@ send_ready_again: { goto send_ready_again; } - printf("start receive ota file.\n"); + printf("start receive ota bin file.\n"); /* step2:start receive bin file,first wait for 4s. */ PrivTaskDelay(4000); ret = ota_data_recv(adapter); @@ -632,7 +670,11 @@ send_ready_again: ret = AdapterDeviceSend(adapter, reply, strlen(reply)); } } + mcuboot.flash_deinit(); + PrivTaskDelay(2000); + printf("ota file done,start reboot.\n"); + mcuboot.op_reset(); } -SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0),ota4g, app_ota_by_4g, ota by 4g function); +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0),ota, app_ota_by_4g, ota by 4g function); #endif \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/server_tcp.c b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/server_tcp.c index 0dbca44b7..c256bf5aa 100644 --- a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/server_tcp.c +++ b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/server_tcp.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -112,7 +113,7 @@ void sockt_init(void) if(serverfd == -1) { - perror("创建socket失败"); + perror("Failed to create socket"); exit(-1); } @@ -140,20 +141,20 @@ void sockt_init(void) timeout.tv_usec = 0; if(setsockopt(serverfd, SOL_SOCKET, SO_REUSEADDR, &timeout, sizeof(struct timeval)) < 0) { - perror("端口设置失败"); + perror("Failed to set setsock option"); exit(-1); } if(bind(serverfd,(struct sockaddr*)&addr,sizeof(addr)) == -1) { - perror("绑定失败"); + perror("Failed to bind socket port"); exit(-1); } //监听最大连接数 if(listen(serverfd,SIZE) == -1) { - perror("设置监听失败"); + perror("Failed to set socket listening"); exit(-1); } } @@ -168,14 +169,39 @@ void sockt_init(void) void ota_start_signal(int fd) { struct ota_data data; + struct stat st; uint8_t buf[32]; - int ret; - int length = 0; + int ret, length = 0, file_size = 0, file_frame_cnt = 0; + + if (access(BIN_PATH, F_OK) == 0) + { + printf("%s exists\n", basename(BIN_PATH)); + } + else + { + printf("%s does not exist,please cheack!\n", BIN_PATH); + return; + } + + //获取文件大小(以字节为单位) + if(stat(BIN_PATH, &st) == 0) + { + file_size = st.st_size; + file_frame_cnt = ((file_size%LENGTH) != 0)? (file_size/LENGTH + 1):(file_size/LENGTH); + printf("%s size is %d bytes,frame count is %d!\n",basename(BIN_PATH), file_size, file_frame_cnt); + } + else + { + printf("Failed to get file size\n"); + return; + } while(1) { memset(&data, 0x0 , sizeof(struct ota_data)); data.header.frame_flag = 0x5A5A; + //发送起始帧时把bin文件的大小一并发送出去 + data.header.total_len = file_size; memcpy(data.frame.frame_data,"aiit_ota_start",strlen("aiit_ota_start")); data.frame.frame_len = strlen("aiit_ota_start"); @@ -183,14 +209,14 @@ void ota_start_signal(int fd) ret = send(fd, &data, sizeof(data), MSG_NOSIGNAL); if(ret > 0) { - printf("send %s[%d] Bytes\n",data.frame.frame_data,ret); + printf("send %s %d bytes\n",data.frame.frame_data,ret); } memset(buf, 0, 32); length = recv(fd, buf, sizeof(buf), 0); if(length > 0 && (0 == strncmp(buf, "ready", length))) { - printf("recv buf %s length %d\n",buf,length); + printf("recv buf %s length %d.\n",buf,length); break; } @@ -214,28 +240,15 @@ int ota_file_send(int fd) { unsigned char buf[32] = { 0 }; struct ota_data data; - struct stat st; FILE *file_fd; int length = 0; int try_times; int recv_end_times = 3; int ret = 0; - int file_frame_cnt, frame_cnt = 0; + int frame_cnt = 0; int file_length = 0; char * file_buf = NULL; - if(stat(BIN_PATH, &st) == 0) - { - //获取文件大小(以字节为单位) - file_frame_cnt = (st.st_size%LENGTH != 0)? (st.st_size/LENGTH + 1):(st.st_size/LENGTH); - printf("File size is %ld bytes,file frame count is %d!\n", st.st_size, file_frame_cnt); - } - else - { - printf("get file size failed.\n"); - return -1; - } - file_fd = fopen(BIN_PATH, "r"); if(NULL == file_fd) { @@ -254,7 +267,7 @@ int ota_file_send(int fd) length = fread(data.frame.frame_data, 1, LENGTH, file_fd); if(length > 0) { - printf("read %d Bytes\n",length); + printf("read %d bytes\n",length); data.frame.frame_id = frame_cnt; data.frame.frame_len = length; data.frame.crc = calculate_crc16(data.frame.frame_data, length); @@ -280,7 +293,7 @@ recv_again: } //接收到的回复不是ok,说明刚发的包有问题,需要再发一次 - printf("receive buf[%s] length = %d\n",buf, length); + printf("receive buf[%s] length %d.\n",buf, length); if(0 == strncmp(buf, "ok", length)) { try_times = 10; @@ -307,7 +320,7 @@ recv_again: /* finally,crc check total bin file.*/ if(ret == 0) { - printf("total send file length[%d] Bytes [%d] frames.\n",file_length,frame_cnt); + printf("total send file length %d bytes, %d frames.\n",file_length,frame_cnt); printf("now crc check total bin file.\n"); file_buf = malloc(file_length); memset(file_buf, 0, file_length); From f2b64e4306c7a49afe125a03b1f90068b14cc616 Mon Sep 17 00:00:00 2001 From: wgzAIIT <820906721@qq.com> Date: Thu, 1 Jun 2023 17:56:12 +0800 Subject: [PATCH 08/23] fix OTA upgrade through 4G --- .../XiZi_IIoT/tool/bootloader/ota/ota.c | 6 +- .../tool/bootloader/ota/server_tcp.c | 86 +++++++++++-------- 2 files changed, 55 insertions(+), 37 deletions(-) diff --git a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c index 9a234d0a1..b822b953d 100644 --- a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c +++ b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c @@ -498,13 +498,13 @@ static int ota_data_recv(struct Adapter* adapter) ret = AdapterDeviceRecv(adapter, &recv_msg, sizeof(struct ota_data)); if(ret >= 0 && recv_msg.header.frame_flag == 0x5A5A) { - if(0 == strncmp("aiit_ota_start",recv_msg.frame.frame_data, strlen("aiit_ota_start"))) + if(0 == strncmp("ota_start_signal",recv_msg.frame.frame_data, strlen("ota_start_signal"))) { //这里不应该再出现开始信号,丢弃当前数据继续接收 continue; } - if(0 == strncmp("aiit_ota_end",recv_msg.frame.frame_data, strlen("aiit_ota_end"))) //说明当前是结束帧 + if(0 == strncmp("ota_end_signal",recv_msg.frame.frame_data, strlen("ota_end_signal"))) //说明当前是结束帧 { printf("total %d frames %d bytes crc[0x%x],receive successful,\n",frame_cnt,recv_msg.header.total_len,recv_msg.frame.crc); memset(reply, 0, 16); @@ -628,7 +628,7 @@ void app_ota_by_4g(void) ret = AdapterDeviceRecv(adapter, &recv_msg, sizeof(struct ota_data)); if(ret >= 0 && recv_msg.header.frame_flag == 0x5A5A) { - if(0 == strncmp("aiit_ota_start",recv_msg.frame.frame_data, strlen("aiit_ota_start"))) + if(0 == strncmp("ota_start_signal",recv_msg.frame.frame_data, strlen("ota_start_signal"))) { if(mcuboot.op_flash_erase(DOWN_FLAH_ADDRESS,recv_msg.header.total_len) != kStatus_Success) { diff --git a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/server_tcp.c b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/server_tcp.c index c256bf5aa..f4bd1b934 100644 --- a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/server_tcp.c +++ b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/server_tcp.c @@ -130,7 +130,7 @@ void sockt_init(void) { sa = (struct sockaddr_in *) ifa->ifa_addr; ipaddr = inet_ntoa(sa->sin_addr); - printf("Interface: %s\tAddress: %s\n", ifa->ifa_name, ipaddr); + printf("Interface:%-16s Address:%-16s\n", ifa->ifa_name, ipaddr); } } freeifaddrs(ifap); @@ -202,24 +202,29 @@ void ota_start_signal(int fd) data.header.frame_flag = 0x5A5A; //发送起始帧时把bin文件的大小一并发送出去 data.header.total_len = file_size; - memcpy(data.frame.frame_data,"aiit_ota_start",strlen("aiit_ota_start")); - data.frame.frame_len = strlen("aiit_ota_start"); + memcpy(data.frame.frame_data,"ota_start_signal",strlen("ota_start_signal")); + data.frame.frame_len = strlen("ota_start_signal"); - printf("send start signal.\n"); + printf("send start signal to client %d.\n", fd); ret = send(fd, &data, sizeof(data), MSG_NOSIGNAL); if(ret > 0) { - printf("send %s %d bytes\n",data.frame.frame_data,ret); + printf("send %s %d bytes to client %d\n", data.frame.frame_data, ret, fd); } memset(buf, 0, 32); length = recv(fd, buf, sizeof(buf), 0); - if(length > 0 && (0 == strncmp(buf, "ready", length))) + if(length == 0) { - printf("recv buf %s length %d.\n",buf,length); + printf("The current socket %d is disconnected,please check it!\n",fd); + close(fd); + pthread_exit(0); + } + else if(length > 0 && (0 == strncmp(buf, "ready", length))) + { + printf("recv buf %s length %d from client %d.\n", buf, length, fd); break; } - else { continue; @@ -256,7 +261,7 @@ int ota_file_send(int fd) return -1; } fseek(file_fd, 0, SEEK_SET); - printf("start send file.\n"); + printf("start send bin file to client %d.\n", fd); while(!feof(file_fd)) @@ -275,32 +280,40 @@ int ota_file_send(int fd) } send_again: - printf("ota send current[%d] frame.\n",frame_cnt); + printf("send frame[%d] to client %d.\n", frame_cnt, fd); length = send(fd, &data, sizeof(data), MSG_NOSIGNAL); if(length < 0) { - printf("send [%d] frame faile.go to send again\n",frame_cnt); + printf("send frame[%d] to client %d failed,send again\n", frame_cnt, fd); goto send_again; } recv_again: memset(buf, 0, 32); length = recv(fd, buf, sizeof(buf), 0); - if(length < 0 ) + if(length == 0) { - printf("[%d] frame waiting for ok timeout,receive again.\n",frame_cnt); + printf("current socket %d is disconnected,please check it!\n", fd); + ret = -1; + close(fd); + pthread_exit(0); + break; + } + else if(length < 0 ) + { + printf("send frame[%d] to client %d waiting for ok timeout,receive again.\n", frame_cnt, fd); goto recv_again; } - - //接收到的回复不是ok,说明刚发的包有问题,需要再发一次 - printf("receive buf[%s] length %d.\n",buf, length); - if(0 == strncmp(buf, "ok", length)) + else if(0 == strncmp(buf, "ok", length)) { + printf("receive buf[%s] length %d from client %d.\n", buf, length, fd); try_times = 10; - printf("[%d]frame data send done.\n",frame_cnt); + printf("send to client %d frame[%d] data send done.\n",fd, frame_cnt); frame_cnt++; continue; - } + } + + //接收到的回复不是ok,说明刚发的包有问题,需要再发一次 else { if(try_times > 0) @@ -310,7 +323,7 @@ recv_again: } else { - printf("send frame[%d] 10 times failed.\n",frame_cnt); + printf("send to client %d frame[%d] 10 times failed.\n",fd, frame_cnt); ret = -1; break; } @@ -320,7 +333,7 @@ recv_again: /* finally,crc check total bin file.*/ if(ret == 0) { - printf("total send file length %d bytes, %d frames.\n",file_length,frame_cnt); + printf("total send file length %d bytes, %d frames to client %d.\n", file_length, frame_cnt, fd); printf("now crc check total bin file.\n"); file_buf = malloc(file_length); memset(file_buf, 0, file_length); @@ -341,43 +354,48 @@ recv_again: { data.frame.frame_id = frame_cnt; data.header.total_len = file_length; - data.frame.frame_len = strlen("aiit_ota_end"); + data.frame.frame_len = strlen("ota_end_signal"); data.frame.crc = calculate_crc16(file_buf, length); - memcpy(data.frame.frame_data,"aiit_ota_end",strlen("aiit_ota_end")); + memcpy(data.frame.frame_data,"ota_end_signal",strlen("ota_end_signal")); } send_end_signal: - printf("send aiit_ota_end signal.\n"); + printf("send ota end signal to client %d.\n", fd); length = send(fd, &data, sizeof(data), MSG_NOSIGNAL); if(length < 0) { - printf("send end signal faile,send end signal again\n"); + printf("send to client %d ota end signal faile,send again\n",fd); goto send_end_signal; } recv_end_signal: memset(buf, 0, 32); length = recv(fd, buf, sizeof(buf), 0); - if(length < 0 ) + if(length == 0) + { + printf("current socket %d is disconnected,please check it!\n",fd); + ret = -1; + free(file_buf); + fclose(file_fd); + close(fd); + pthread_exit(0); + + } + if(length < 0 || (0 != strncmp(buf, "ok", length))) { recv_end_times--; - printf("end signal waiting for ok timeout,receive again.\n"); + printf("from client %d end signal waiting for ok timeout,receive again.\n", fd); if(recv_end_times > 0) { goto recv_end_signal; } else { + printf("client %d error end !!!\n", fd); ret = -1; } } - if(0 != strncmp(buf, "ok", length)) - { - printf("error end !!!\n"); - ret = -1; - } - free(file_buf); } @@ -409,7 +427,7 @@ void* server_thread(void* p) ret = ota_file_send(fd); if(ret == 0) { - printf("ota file send successful.\n"); + printf("ota file send to client %d successful.\n", fd); break; } else From e48bd6fd67d97b287261aefe02e57a9170df0c01 Mon Sep 17 00:00:00 2001 From: wgzAIIT <820906721@qq.com> Date: Fri, 2 Jun 2023 11:08:17 +0800 Subject: [PATCH 09/23] =?UTF-8?q?1=E3=80=81OTA=20supports=204g=20retransmi?= =?UTF-8?q?ssion=20after=20file=20sending=20failure=202=E3=80=81Optimize?= =?UTF-8?q?=20the=20startup=20process=20of=20OTA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../third_party_driver/common/ymodem.c | 5 +- .../XiZi_IIoT/tool/bootloader/ota/ota.c | 188 ++++++++++-------- .../tool/bootloader/ota/server_tcp.c | 39 ++-- 3 files changed, 123 insertions(+), 109 deletions(-) diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/common/ymodem.c b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/common/ymodem.c index f443f60a8..5eb8b728a 100644 --- a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/common/ymodem.c +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/common/ymodem.c @@ -373,13 +373,12 @@ int32_t SerialDownload(const uint32_t addr) Size = Ymodem_Receive(&tab_1024[0], addr); if(Size > 0) { - Serial_PutString("\n\n\r Programming Completed Successfully!\n\r--------------------------------\r\n Name: "); + Serial_PutString("\n\n\rProgramming Completed Successfully!\n\r\r\nName: "); Serial_PutString(FileName); Int2Str(Number, Size); - Serial_PutString("\n\r Size: "); + Serial_PutString("\n\rSize: "); Serial_PutString(Number); Serial_PutString(" Bytes\r\n"); - Serial_PutString("-------------------\n"); } else if(Size == -1) { diff --git a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c index b822b953d..56fcbc74f 100644 --- a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c +++ b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c @@ -33,11 +33,12 @@ * Private Function Prototypes ****************************************************************************/ static uint32_t calculate_crc32(uint32_t addr, uint32_t len); -static void UpdateApplication(void); +static void UpdateNewApplication(void); static void InitialVersion(void); static void BackupVersion(void); static void BootLoaderJumpApp(void); static status_t UpdateOTAFlag(ota_info_t *ptr); +static void Update(void); /**************************************************************************** * Private Data @@ -142,13 +143,13 @@ static uint16_t calculate_crc16(uint8_t * data, uint32_t len) } /******************************************************************************* -* 函 数 名: UpdateApplication +* 函 数 名: UpdateNewApplication * 功能描述: 在bootloader里进行调用,根据Flash中Flag分区中的信息决定是否进行版本更新 * 形 参: 无 * 返 回 值: 无 -* 注 释: 该函数调用后无论结果如何都将跳转到app分区 +* 注 释: 该函数调用后如果不需要升级APP分区保持不变,否则APP分区的版本为新版本 *******************************************************************************/ -static void UpdateApplication(void) +static void UpdateNewApplication(void) { status_t status; ota_info_t ota_info; // 定义OTA信息结构体 @@ -395,6 +396,29 @@ void app_clear_jumpflag(void) mcuboot.flash_deinit(); } +/******************************************************************************* +* 函 数 名: Update +* 功能描述: 根据实际情况进行初始化版本的烧录或者新版本的升级 +* 形 参: 无 +* 返 回 值: 无 +*******************************************************************************/ +void Update(void) +{ + ota_info_t ota_info; + mcuboot.flash_init(); + mcuboot.op_flash_read(FLAG_FLAH_ADDRESS, (void*)&ota_info, sizeof(ota_info_t)); + /* 此时APP分区还没有有效的固件,需要在bootloader下通过iap烧写出厂固件 */ + if((ota_info.os.size > APP_FLASH_SIZE) || (calculate_crc32(XIUOS_FLAH_ADDRESS, ota_info.os.size) != ota_info.os.crc32)) + { + mcuboot.print_string("\r\nNeed to flash initial firmware!\r\n"); + InitialVersion(); + } + else + { + UpdateNewApplication(); + } + mcuboot.flash_deinit(); +} /******************************************************************************* * 函 数 名: ota_entry @@ -441,20 +465,7 @@ void ota_entry(void) break; case 0x32: - mcuboot.flash_init(); - mcuboot.op_flash_read(FLAG_FLAH_ADDRESS, (void*)&ota_info, sizeof(ota_info_t)); - /* 此时APP分区还没有有效的固件,需要在bootloader下通过iap烧写出厂固件 */ - if((ota_info.os.size > APP_FLASH_SIZE) || (calculate_crc32(XIUOS_FLAH_ADDRESS, ota_info.os.size) != ota_info.os.crc32)) - { - mcuboot.print_string("\r\nNeed to flash initial firmware!\r\n"); - InitialVersion(); - } - else - { - UpdateApplication(); - } - - mcuboot.flash_deinit(); + Update(); BootLoaderJumpApp(); break; @@ -464,8 +475,10 @@ void ota_entry(void) break; } } + //10s内不按下空格键默然进行升级,升级完成后跳转 else { + Update(); BootLoaderJumpApp(); } } @@ -473,6 +486,59 @@ void ota_entry(void) #ifdef CONNECTION_ADAPTER_4G +/******************************************************************************* +* 函 数 名: ota_data_recv +* 功能描述: 通过4G方式从服务端接收开始信号 +* 形 参: adapter:Adapter指针,指向注册的4G设备 +* 返 回 值: 0:传输成功,-1:传输失败 +*******************************************************************************/ +static void get_start_signal(struct Adapter* adapter) +{ + struct ota_data recv_msg; + ota_info_t ota_info; + char reply[16] = {0}; + uint32_t flashdestination = DOWN_FLAH_ADDRESS; + + mcuboot.op_flash_read(FLAG_FLAH_ADDRESS, (void*)&ota_info, sizeof(ota_info_t)); + ota_info.status = OTA_STATUS_DOWNLOADING; + UpdateOTAFlag(&ota_info); + while(1) + { + memset(&recv_msg, 0, sizeof(recv_msg)); + /* step1:Confirm the start signal of transmission. */ + printf("waiting for start msg...\n"); + if(AdapterDeviceRecv(adapter, &recv_msg, sizeof(recv_msg)) >= 0 && recv_msg.header.frame_flag == 0x5A5A) + { + if(0 == strncmp("ota_start_signal",recv_msg.frame.frame_data, strlen("ota_start_signal"))) + { + if(mcuboot.op_flash_erase(DOWN_FLAH_ADDRESS,recv_msg.header.total_len) != kStatus_Success) + { + printf("Failed to erase target fash!\n"); + break; + } + else + { + printf("Erase flash successful,erase length is %d bytes.\n",recv_msg.header.total_len); + } + memset(reply, 0, sizeof(reply)); + memcpy(reply, "ready", strlen("ready")); + printf("receive start signal,send [ready] signal to server\n"); + while(AdapterDeviceSend(adapter, reply, strlen(reply)) < 0); + break; + } + } + else + { + memset(reply, 0, sizeof(reply)); + memcpy(reply, "notready", strlen("notready")); + printf("not receive start signal,send [notready] signal to server\n"); + while(AdapterDeviceSend(adapter, reply, strlen(reply)) < 0); + continue; + } + } +} + + /******************************************************************************* * 函 数 名: ota_data_recv * 功能描述: 通过4G方式从服务端接收数据 @@ -484,7 +550,7 @@ static int ota_data_recv(struct Adapter* adapter) struct ota_data recv_msg; ota_info_t ota_info; char reply[16] = {0}; - int ret = 0, try_times = 10, frame_cnt = 0; + int ret = 0, frame_cnt = 0, try_times = 5; uint32_t file_size = 0; uint32_t flashdestination = DOWN_FLAH_ADDRESS; @@ -494,9 +560,8 @@ static int ota_data_recv(struct Adapter* adapter) while(1) { - memset(&recv_msg, 0, sizeof(struct ota_data)); - ret = AdapterDeviceRecv(adapter, &recv_msg, sizeof(struct ota_data)); - if(ret >= 0 && recv_msg.header.frame_flag == 0x5A5A) + memset(&recv_msg, 0, sizeof(recv_msg)); + if(AdapterDeviceRecv(adapter, &recv_msg, sizeof(recv_msg)) >= 0 && recv_msg.header.frame_flag == 0x5A5A) { if(0 == strncmp("ota_start_signal",recv_msg.frame.frame_data, strlen("ota_start_signal"))) { @@ -506,8 +571,8 @@ static int ota_data_recv(struct Adapter* adapter) if(0 == strncmp("ota_end_signal",recv_msg.frame.frame_data, strlen("ota_end_signal"))) //说明当前是结束帧 { - printf("total %d frames %d bytes crc[0x%x],receive successful,\n",frame_cnt,recv_msg.header.total_len,recv_msg.frame.crc); - memset(reply, 0, 16); + printf("total %d frames %d bytes crc[0x%x],receive successful.\n",frame_cnt,recv_msg.header.total_len,recv_msg.frame.crc); + memset(reply, 0, sizeof(reply)); memcpy(reply, "ok", strlen("ok")); AdapterDeviceSend(adapter, reply, strlen(reply)); @@ -521,27 +586,27 @@ static int ota_data_recv(struct Adapter* adapter) frame_cnt = recv_msg.frame.frame_id; if(recv_msg.frame.crc == calculate_crc16(recv_msg.frame.frame_data,recv_msg.frame.frame_len)) { - printf("current[%d] frame,length %d bytes.\n",frame_cnt,recv_msg.frame.frame_len); + printf("current frame[%d],length %d bytes.\n",frame_cnt,recv_msg.frame.frame_len); if(mcuboot.op_flash_write(flashdestination, recv_msg.frame.frame_data, recv_msg.frame.frame_len) != kStatus_Success) { - printf("current[%d] frame flash failed.\n",frame_cnt); + printf("current frame[%d] flash failed.\n",frame_cnt); ret = -1; break; } else { - printf("current[%d] frame is written to flash 0x%x address successful.\n", frame_cnt, flashdestination); + printf("current frame[%d] is written to flash 0x%x address successful.\n", frame_cnt, flashdestination); flashdestination += recv_msg.frame.frame_len; } } else { - printf("current[%d] frame crc check failed,try again!\n",frame_cnt); + printf("current frame[%d] crc check failed,try again!\n",frame_cnt); goto try_again; } send_ok_again: - memset(reply, 0, 16); + memset(reply, 0, sizeof(reply)); memcpy(reply, "ok", strlen("ok")); ret = AdapterDeviceSend(adapter, reply, strlen(reply)); @@ -551,8 +616,8 @@ send_ok_again: goto send_ok_again; } printf("send reply[%s] done.\n",reply); - //send ok后把try_times重置为10 - try_times = 10; + //send ok后把try_times重置为5 + try_times = 5; continue; } @@ -562,13 +627,13 @@ send_ok_again: try_again: if(try_times == 0) { - printf("current[%d] frame try 10 times failed,break out!\n",frame_cnt); + printf("current frame[%d] try 5 times failed,break out!\n",frame_cnt); ret = -1; break; } - memset(reply, 0, 16); + memset(reply, 0, sizeof(reply)); memcpy(reply, "retry", strlen("retry")); - printf("[%d] frame receive failed. retry\n",frame_cnt); + printf("current frame[%d] receive failed. retry\n",frame_cnt); AdapterDeviceSend(adapter, reply, strlen(reply)); try_times--; continue; @@ -607,7 +672,6 @@ void app_ota_by_4g(void) struct ota_data recv_msg; char reply[16] = {0}; uint32_t baud_rate = BAUD_RATE_115200; - int ret = 0; uint8 server_addr[64] = "115.238.53.60"; uint8 server_port[64] = "7777"; @@ -622,57 +686,19 @@ void app_ota_by_4g(void) PrivTaskDelay(100); while(1) { - memset(&recv_msg, 0, sizeof(struct ota_data)); /* step1:Confirm the start signal of transmission. */ - printf("waiting for start msg...\n"); - ret = AdapterDeviceRecv(adapter, &recv_msg, sizeof(struct ota_data)); - if(ret >= 0 && recv_msg.header.frame_flag == 0x5A5A) + get_start_signal(adapter); + printf("start receive ota bin file.\n"); + /* step2:start receive bin file,first wait for 4s. */ + PrivTaskDelay(4000); + if(0 == ota_data_recv(adapter)) { - if(0 == strncmp("ota_start_signal",recv_msg.frame.frame_data, strlen("ota_start_signal"))) - { - if(mcuboot.op_flash_erase(DOWN_FLAH_ADDRESS,recv_msg.header.total_len) != kStatus_Success) - { - printf("Failed to erase target fash!\n"); - break; - } else { - printf("Erase flash successful,Erase length is %d bytes.\n",recv_msg.header.total_len); - } - memset(reply, 0, 16); - memcpy(reply, "ready", strlen("ready")); - printf("receive start signal,send [ready] signal to server\n"); -send_ready_again: - ret = AdapterDeviceSend(adapter, reply, strlen(reply)); - if(ret < 0) - { - goto send_ready_again; - } - printf("start receive ota bin file.\n"); - /* step2:start receive bin file,first wait for 4s. */ - PrivTaskDelay(4000); - ret = ota_data_recv(adapter); - if(0 != ret) - { - memset(reply, 0, 16); - memcpy(reply, "ota_restart", strlen("ota_restart")); - AdapterDeviceSend(adapter, reply, strlen(reply)); - continue; - } - else - { - break; - } - } - } - else - { - memset(reply, 0, 16); - memcpy(reply, "notready", strlen("notready")); - ret = AdapterDeviceSend(adapter, reply, strlen(reply)); - } + break; + } } mcuboot.flash_deinit(); - PrivTaskDelay(2000); printf("ota file done,start reboot.\n"); + PrivTaskDelay(2000); mcuboot.op_reset(); } diff --git a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/server_tcp.c b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/server_tcp.c index f4bd1b934..08353e6b7 100644 --- a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/server_tcp.c +++ b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/server_tcp.c @@ -171,16 +171,16 @@ void ota_start_signal(int fd) struct ota_data data; struct stat st; uint8_t buf[32]; - int ret, length = 0, file_size = 0, file_frame_cnt = 0; + int file_size = 0, file_frame_cnt = 0, length = 0; if (access(BIN_PATH, F_OK) == 0) { - printf("%s exists\n", basename(BIN_PATH)); + printf("%s exists.\n", basename(BIN_PATH)); } else { printf("%s does not exist,please cheack!\n", BIN_PATH); - return; + exit(-1); } //获取文件大小(以字节为单位) @@ -193,26 +193,22 @@ void ota_start_signal(int fd) else { printf("Failed to get file size\n"); - return; + exit(-1); } while(1) { - memset(&data, 0x0 , sizeof(struct ota_data)); + memset(&data, 0x0, sizeof(struct ota_data)); data.header.frame_flag = 0x5A5A; //发送起始帧时把bin文件的大小一并发送出去 data.header.total_len = file_size; memcpy(data.frame.frame_data,"ota_start_signal",strlen("ota_start_signal")); data.frame.frame_len = strlen("ota_start_signal"); + while(send(fd, &data, sizeof(data), MSG_NOSIGNAL) <= 0); printf("send start signal to client %d.\n", fd); - ret = send(fd, &data, sizeof(data), MSG_NOSIGNAL); - if(ret > 0) - { - printf("send %s %d bytes to client %d\n", data.frame.frame_data, ret, fd); - } - memset(buf, 0, 32); + memset(buf, 0, sizeof(buf)); length = recv(fd, buf, sizeof(buf), 0); if(length == 0) { @@ -289,7 +285,7 @@ send_again: } recv_again: - memset(buf, 0, 32); + memset(buf, 0, sizeof(buf)); length = recv(fd, buf, sizeof(buf), 0); if(length == 0) { @@ -313,7 +309,7 @@ recv_again: continue; } - //接收到的回复不是ok,说明刚发的包有问题,需要再发一次 + //接收到的回复不是ok,说明刚发的包有问题,需要再发一次 else { if(try_times > 0) @@ -369,7 +365,7 @@ send_end_signal: } recv_end_signal: - memset(buf, 0, 32); + memset(buf, 0, sizeof(buf)); length = recv(fd, buf, sizeof(buf), 0); if(length == 0) { @@ -415,25 +411,18 @@ void* server_thread(void* p) int fd = *(int*)p; unsigned char buf[32] = { 0 }; struct ota_data data; - int ret = 0; - int length = 0; printf("pthread = %d\n",fd); sleep(3); - ota_start_signal(fd); - sleep(5); while(1) { - ret = ota_file_send(fd); - if(ret == 0) + /* if ota failed then restart the ota process */ + ota_start_signal(fd); + sleep(5); + if(0 == ota_file_send(fd)) { printf("ota file send to client %d successful.\n", fd); break; - } - else - { - /* ota failed then restart the ota process */ - continue; } } printf("exit fd = %d\n",fd); From 5a1fe0be3b3c38f0932e39a78f59af7cdccb87c6 Mon Sep 17 00:00:00 2001 From: wgzAIIT <820906721@qq.com> Date: Fri, 2 Jun 2023 19:52:39 +0800 Subject: [PATCH 10/23] =?UTF-8?q?1=E3=80=81Optimize=20the=20tcp=20server?= =?UTF-8?q?=20file=20reading=20operation=20during=20the=20OTA=20process?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2、Optimize the ota.c file 3、revert dev_serial.c --- .../XiZi_IIoT/resources/serial/dev_serial.c | 2 -- .../XiZi_IIoT/tool/bootloader/ota/ota.c | 17 +++++++++-- .../tool/bootloader/ota/server_tcp.c | 30 +++++++++++++++++-- 3 files changed, 42 insertions(+), 7 deletions(-) diff --git a/Ubiquitous/XiZi_IIoT/resources/serial/dev_serial.c b/Ubiquitous/XiZi_IIoT/resources/serial/dev_serial.c index fcd9aeefd..428e1c935 100644 --- a/Ubiquitous/XiZi_IIoT/resources/serial/dev_serial.c +++ b/Ubiquitous/XiZi_IIoT/resources/serial/dev_serial.c @@ -154,9 +154,7 @@ static inline int SerialDevIntRead(struct SerialHardwareDevice *serial_dev, stru CriticalAreaUnLock(lock); -#ifndef TOOL_USING_OTA MdelayKTask(20); -#endif *read_data = get_char; read_data++; diff --git a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c index 56fcbc74f..1e83b0a36 100644 --- a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c +++ b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c @@ -33,13 +33,21 @@ * Private Function Prototypes ****************************************************************************/ static uint32_t calculate_crc32(uint32_t addr, uint32_t len); +static uint16_t calculate_crc16(uint8_t * data, uint32_t len); static void UpdateNewApplication(void); static void InitialVersion(void); static void BackupVersion(void); static void BootLoaderJumpApp(void); static status_t UpdateOTAFlag(ota_info_t *ptr); +static void app_ota_by_iap(void); static void Update(void); +#ifdef CONNECTION_ADAPTER_4G +static void get_start_signal(struct Adapter* adapter); +static int ota_data_recv(struct Adapter* adapter); +static void app_ota_by_4g(void); +#endif + /**************************************************************************** * Private Data ****************************************************************************/ @@ -60,6 +68,7 @@ static const mcuboot_t mcuboot = mcuboot_delay }; + static const uint32_t crc32tab[] = { 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, @@ -142,6 +151,7 @@ static uint16_t calculate_crc16(uint8_t * data, uint32_t len) return reg_crc; } + /******************************************************************************* * 函 数 名: UpdateNewApplication * 功能描述: 在bootloader里进行调用,根据Flash中Flag分区中的信息决定是否进行版本更新 @@ -255,6 +265,7 @@ static void InitialVersion(void) } } + /******************************************************************************* * 函 数 名: BackupVersion * 功能描述: 版本回退函数,如果升级的APP存在bug导致无法跳转需调用此函数进行版本回退 @@ -396,13 +407,14 @@ void app_clear_jumpflag(void) mcuboot.flash_deinit(); } + /******************************************************************************* * 函 数 名: Update * 功能描述: 根据实际情况进行初始化版本的烧录或者新版本的升级 * 形 参: 无 * 返 回 值: 无 *******************************************************************************/ -void Update(void) +static void Update(void) { ota_info_t ota_info; mcuboot.flash_init(); @@ -420,6 +432,7 @@ void Update(void) mcuboot.flash_deinit(); } + /******************************************************************************* * 函 数 名: ota_entry * 功能描述: bootloader的入口函数 @@ -667,7 +680,7 @@ try_again: * 形 参: adapter:Adapter指针,指向注册的4G设备 * 返 回 值: 0:传输成功,-1:传输失败 *******************************************************************************/ -void app_ota_by_4g(void) +static void app_ota_by_4g(void) { struct ota_data recv_msg; char reply[16] = {0}; diff --git a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/server_tcp.c b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/server_tcp.c index 08353e6b7..88871782e 100644 --- a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/server_tcp.c +++ b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/server_tcp.c @@ -254,6 +254,7 @@ int ota_file_send(int fd) if(NULL == file_fd) { printf("open file failed.\n"); + fclose(file_fd); return -1; } fseek(file_fd, 0, SEEK_SET); @@ -266,7 +267,7 @@ int ota_file_send(int fd) data.header.frame_flag = 0x5A5A; length = fread(data.frame.frame_data, 1, LENGTH, file_fd); - if(length > 0) + if(length == LENGTH) { printf("read %d bytes\n",length); data.frame.frame_id = frame_cnt; @@ -274,6 +275,29 @@ int ota_file_send(int fd) data.frame.crc = calculate_crc16(data.frame.frame_data, length); file_length += length; } + else if(length > 0 && length < LENGTH) + { + if(ferror(file_fd)) + { + printf("read %s file error!\n", basename(BIN_PATH)); + ret = -1; + break; + } + else + { + printf("read %d bytes\n",length); + data.frame.frame_id = frame_cnt; + data.frame.frame_len = length; + data.frame.crc = calculate_crc16(data.frame.frame_data, length); + file_length += length; + } + } + //fread返回值为0,此时是个空包,不需要再发送了否则是冗余数据 + else + { + printf("read %s file done!\n", basename(BIN_PATH)); + break; + } send_again: printf("send frame[%d] to client %d.\n", frame_cnt, fd); @@ -303,7 +327,7 @@ recv_again: else if(0 == strncmp(buf, "ok", length)) { printf("receive buf[%s] length %d from client %d.\n", buf, length, fd); - try_times = 10; + try_times = 5; printf("send to client %d frame[%d] data send done.\n",fd, frame_cnt); frame_cnt++; continue; @@ -319,7 +343,7 @@ recv_again: } else { - printf("send to client %d frame[%d] 10 times failed.\n",fd, frame_cnt); + printf("send to client %d frame[%d] 5 times failed.\n",fd, frame_cnt); ret = -1; break; } From fb9250181fd8355fadcb060009d8ef1f95b1c0ce Mon Sep 17 00:00:00 2001 From: wgzAIIT <820906721@qq.com> Date: Tue, 6 Jun 2023 16:48:18 +0800 Subject: [PATCH 11/23] =?UTF-8?q?1=E3=80=81Increase=20the=20size=20of=20th?= =?UTF-8?q?e=20EntmSend=20function=20send=5Fbuff=202=E3=80=81Optimize=20ot?= =?UTF-8?q?a.c=E3=80=81ota.h=20and=20server=5Ftcp.c=20files?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Framework/connection/adapter_agent.c | 18 ++- .../XiZi_IIoT/tool/bootloader/ota/ota.c | 147 ++++++++++-------- .../XiZi_IIoT/tool/bootloader/ota/ota.h | 29 ++-- .../tool/bootloader/ota/server_tcp.c | 48 +++--- 4 files changed, 127 insertions(+), 115 deletions(-) diff --git a/APP_Framework/Framework/connection/adapter_agent.c b/APP_Framework/Framework/connection/adapter_agent.c index 344674bfb..4ffb2de1a 100755 --- a/APP_Framework/Framework/connection/adapter_agent.c +++ b/APP_Framework/Framework/connection/adapter_agent.c @@ -264,23 +264,25 @@ int AtSetReplyCharNum(ATAgentType agent, unsigned int num) int EntmSend(ATAgentType agent, const char *data, int len) { - char send_buf[128]; - if(len > 128){ - printf("send length %d more then max 128 Bytes.\n",len); + if(len > 256){ + printf("send length %d more then max 256 Bytes.\n",len); return -1; } + char *send_buff = (char *)PrivMalloc(256); PrivMutexObtain(&agent->lock); - memset(send_buf, 0, 128); + memset(send_buff, 0, 256); agent->receive_mode = ENTM_MODE; - memcpy(send_buf, data, len); - // memcpy(send_buf + len, "!@", 2); + memcpy(send_buff, data, len); - PrivWrite(agent->fd, send_buf, len); + PrivWrite(agent->fd, send_buff, len); PrivMutexAbandon(&agent->lock); - printf("entm send %s length %d\n",send_buf, len); + printf("entm send length %d\n", len); + + PrivFree(send_buff); + return 0; } diff --git a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c index 1e83b0a36..df515a230 100644 --- a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c +++ b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c @@ -104,6 +104,10 @@ static const uint32_t crc32tab[] = { 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d }; +#ifdef CONNECTION_ADAPTER_4G +static ota_data start_msg; +static ota_data recv_msg; +#endif /******************************************************************************* * 函 数 名: calculate_crc32 @@ -147,7 +151,7 @@ static uint16_t calculate_crc16(uint8_t * data, uint32_t len) reg_crc=reg_crc >>1; } } - printf("crc = [0x%x]\n",reg_crc); + KPrintf("crc = [0x%x]\n",reg_crc); return reg_crc; } @@ -163,7 +167,8 @@ static void UpdateNewApplication(void) { status_t status; ota_info_t ota_info; // 定义OTA信息结构体 - + + memset(&ota_info, 0, sizeof(ota_info_t)); // 从Flash中读取OTA信息 mcuboot.op_flash_read(FLAG_FLAH_ADDRESS, (void*)&ota_info, sizeof(ota_info_t)); @@ -260,7 +265,7 @@ static void InitialVersion(void) ota_info.os.size = size; ota_info.os.crc32 = calculate_crc32(XIUOS_FLAH_ADDRESS, size); ota_info.os.version = 0x1; - strncpy(ota_info.os.description, "This is the initial firmware for the device!", sizeof(ota_info.os.description)); + strncpy(ota_info.os.description, "The initial firmware.", sizeof(ota_info.os.description)); UpdateOTAFlag(&ota_info); } } @@ -275,7 +280,9 @@ static void InitialVersion(void) static void BackupVersion(void) { status_t status; - ota_info_t ota_info; + + ota_info_t ota_info; + 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_BACKUP; @@ -309,7 +316,9 @@ static void BackupVersion(void) static void BootLoaderJumpApp(void) { ota_info_t ota_info; + 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)); if(ota_info.lastjumpflag == JUMP_FAILED_FLAG) @@ -361,7 +370,7 @@ static void app_ota_by_iap(void) mcuboot.flash_init(); mcuboot.serial_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); @@ -373,7 +382,7 @@ static void app_ota_by_iap(void) ota_info.down.size = size; ota_info.down.crc32= calculate_crc32(DOWN_FLAH_ADDRESS, size); ota_info.down.version = ota_info.os.version + 1; - strncpy(ota_info.down.description, "OTA Test!",sizeof(ota_info.down.description)); + strncpy(ota_info.down.description, "OTA Test bin.",sizeof(ota_info.down.description)); ota_info.status = OTA_STATUS_READY; strncpy(ota_info.error_message, "No error message!",sizeof(ota_info.error_message)); UpdateOTAFlag(&ota_info); @@ -398,9 +407,10 @@ SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHE *******************************************************************************/ void app_clear_jumpflag(void) { - mcuboot.flash_init(); + ota_info_t ota_info; + mcuboot.flash_init(); //跳转成功设置lastjumpflag为JUMP_SUCCESS_FLAG - ota_info_t ota_info; + memset(&ota_info, 0, sizeof(ota_info_t)); mcuboot.op_flash_read(FLAG_FLAH_ADDRESS, (void*)&ota_info, sizeof(ota_info_t)); ota_info.lastjumpflag = JUMP_SUCCESS_FLAG; UpdateOTAFlag(&ota_info); @@ -418,6 +428,7 @@ static void Update(void) { ota_info_t ota_info; 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)); /* 此时APP分区还没有有效的固件,需要在bootloader下通过iap烧写出厂固件 */ if((ota_info.os.size > APP_FLASH_SIZE) || (calculate_crc32(XIUOS_FLAH_ADDRESS, ota_info.os.size) != ota_info.os.crc32)) @@ -443,7 +454,6 @@ void ota_entry(void) { uint8_t ch1, ch2; uint32_t ret; - ota_info_t ota_info; uint32_t timeout = 1000; mcuboot.board_init(); @@ -500,51 +510,48 @@ void ota_entry(void) #ifdef CONNECTION_ADAPTER_4G /******************************************************************************* -* 函 数 名: ota_data_recv +* 函 数 名: get_start_signal * 功能描述: 通过4G方式从服务端接收开始信号 * 形 参: adapter:Adapter指针,指向注册的4G设备 * 返 回 值: 0:传输成功,-1:传输失败 *******************************************************************************/ static void get_start_signal(struct Adapter* adapter) { - struct ota_data recv_msg; ota_info_t ota_info; char reply[16] = {0}; uint32_t flashdestination = DOWN_FLAH_ADDRESS; + 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); while(1) { - memset(&recv_msg, 0, sizeof(recv_msg)); + memset(&start_msg, 0, sizeof(ota_data)); /* step1:Confirm the start signal of transmission. */ - printf("waiting for start msg...\n"); - if(AdapterDeviceRecv(adapter, &recv_msg, sizeof(recv_msg)) >= 0 && recv_msg.header.frame_flag == 0x5A5A) + KPrintf("waiting for start msg...\n"); + if(AdapterDeviceRecv(adapter, &start_msg, sizeof(start_msg)) >= 0 && start_msg.header.frame_flag == STARTFLAG) { - if(0 == strncmp("ota_start_signal",recv_msg.frame.frame_data, strlen("ota_start_signal"))) + if(mcuboot.op_flash_erase(DOWN_FLAH_ADDRESS,start_msg.header.total_len) != kStatus_Success) { - if(mcuboot.op_flash_erase(DOWN_FLAH_ADDRESS,recv_msg.header.total_len) != kStatus_Success) - { - printf("Failed to erase target fash!\n"); - break; - } - else - { - printf("Erase flash successful,erase length is %d bytes.\n",recv_msg.header.total_len); - } - memset(reply, 0, sizeof(reply)); - memcpy(reply, "ready", strlen("ready")); - printf("receive start signal,send [ready] signal to server\n"); - while(AdapterDeviceSend(adapter, reply, strlen(reply)) < 0); + KPrintf("Failed to erase target fash!\n"); break; + } + else + { + KPrintf("Erase flash successful,erase length is %d bytes.\n",start_msg.header.total_len); } + memset(reply, 0, sizeof(reply)); + memcpy(reply, "ready", strlen("ready")); + KPrintf("receive start signal,send [ready] signal to server\n"); + while(AdapterDeviceSend(adapter, reply, strlen(reply)) < 0); + break; } else { memset(reply, 0, sizeof(reply)); memcpy(reply, "notready", strlen("notready")); - printf("not receive start signal,send [notready] signal to server\n"); + KPrintf("not receive start signal,send [notready] signal to server\n"); while(AdapterDeviceSend(adapter, reply, strlen(reply)) < 0); continue; } @@ -560,31 +567,53 @@ static void get_start_signal(struct Adapter* adapter) *******************************************************************************/ static int ota_data_recv(struct Adapter* adapter) { - struct ota_data recv_msg; ota_info_t ota_info; char reply[16] = {0}; int ret = 0, frame_cnt = 0, try_times = 5; uint32_t file_size = 0; uint32_t flashdestination = DOWN_FLAH_ADDRESS; + 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); while(1) { - memset(&recv_msg, 0, sizeof(recv_msg)); - if(AdapterDeviceRecv(adapter, &recv_msg, sizeof(recv_msg)) >= 0 && recv_msg.header.frame_flag == 0x5A5A) + memset(&recv_msg, 0, sizeof(ota_data)); + if(AdapterDeviceRecv(adapter, &recv_msg, sizeof(recv_msg)) >= 0) { - if(0 == strncmp("ota_start_signal",recv_msg.frame.frame_data, strlen("ota_start_signal"))) + if(recv_msg.header.frame_flag == STARTFLAG) //这里不应该再出现开始帧,丢弃当前数据继续接收 { - //这里不应该再出现开始信号,丢弃当前数据继续接收 continue; - } - - if(0 == strncmp("ota_end_signal",recv_msg.frame.frame_data, strlen("ota_end_signal"))) //说明当前是结束帧 + } + else if(recv_msg.header.frame_flag == DATAFLAG) //说明当前是bin包里数据封装成的数据帧 { - printf("total %d frames %d bytes crc[0x%x],receive successful.\n",frame_cnt,recv_msg.header.total_len,recv_msg.frame.crc); + frame_cnt = recv_msg.frame.frame_id; + if(recv_msg.frame.crc == calculate_crc16(recv_msg.frame.frame_data,recv_msg.frame.frame_len)) + { + KPrintf("current frame[%d],length %d bytes.\n",frame_cnt,recv_msg.frame.frame_len); + if(mcuboot.op_flash_write(flashdestination, recv_msg.frame.frame_data, recv_msg.frame.frame_len) != kStatus_Success) + { + KPrintf("current frame[%d] flash failed.\n",frame_cnt); + ret = -1; + break; + } + else + { + KPrintf("current frame[%d] is written to flash 0x%x address successful.\n", frame_cnt, flashdestination); + flashdestination += recv_msg.frame.frame_len; + } + } + else + { + KPrintf("current frame[%d] crc check failed,try again!\n",frame_cnt); + goto try_again; + } + } + else if(recv_msg.header.frame_flag == ENDTFLAG) //说明当前是结束帧 + { + KPrintf("total %d frames %d bytes crc[0x%x],receive successful.\n",frame_cnt,recv_msg.header.total_len,recv_msg.frame.crc); memset(reply, 0, sizeof(reply)); memcpy(reply, "ok", strlen("ok")); AdapterDeviceSend(adapter, reply, strlen(reply)); @@ -596,25 +625,8 @@ static int ota_data_recv(struct Adapter* adapter) ret = 0; break; } - frame_cnt = recv_msg.frame.frame_id; - if(recv_msg.frame.crc == calculate_crc16(recv_msg.frame.frame_data,recv_msg.frame.frame_len)) + else //说明当前接收的数据帧不是上述三种数据帧的任意一种 { - printf("current frame[%d],length %d bytes.\n",frame_cnt,recv_msg.frame.frame_len); - if(mcuboot.op_flash_write(flashdestination, recv_msg.frame.frame_data, recv_msg.frame.frame_len) != kStatus_Success) - { - printf("current frame[%d] flash failed.\n",frame_cnt); - ret = -1; - break; - } - else - { - printf("current frame[%d] is written to flash 0x%x address successful.\n", frame_cnt, flashdestination); - flashdestination += recv_msg.frame.frame_len; - } - } - else - { - printf("current frame[%d] crc check failed,try again!\n",frame_cnt); goto try_again; } @@ -625,28 +637,28 @@ send_ok_again: ret = AdapterDeviceSend(adapter, reply, strlen(reply)); if(ret < 0) { - printf("send ok failed.\n"); + KPrintf("send ok failed.\n"); goto send_ok_again; } - printf("send reply[%s] done.\n",reply); + KPrintf("send reply[%s] done.\n",reply); //send ok后把try_times重置为5 try_times = 5; continue; } - //没有接收到数据或者接收到的数据帧frame_flag不等于0x5A5A,需要发个retry的命令告诉服务器需要重传 + //没有接收到数据或者接收到的数据帧不满足条件,需要发个retry的命令告诉服务器需要重传 else { try_again: if(try_times == 0) { - printf("current frame[%d] try 5 times failed,break out!\n",frame_cnt); + KPrintf("current frame[%d] try 5 times failed,break out!\n",frame_cnt); ret = -1; break; } memset(reply, 0, sizeof(reply)); memcpy(reply, "retry", strlen("retry")); - printf("current frame[%d] receive failed. retry\n",frame_cnt); + KPrintf("current frame[%d] receive failed. retry\n",frame_cnt); AdapterDeviceSend(adapter, reply, strlen(reply)); try_times--; continue; @@ -659,7 +671,7 @@ try_again: ota_info.down.size = file_size; ota_info.down.crc32= calculate_crc32(DOWN_FLAH_ADDRESS, file_size); ota_info.down.version = ota_info.os.version + 1; - strncpy(ota_info.down.description, "4G OTA bin package !",sizeof(ota_info.down.description)); + strncpy(ota_info.down.description, "4G OTA bin.",sizeof(ota_info.down.description)); ota_info.status = OTA_STATUS_READY; strncpy(ota_info.error_message, "No error message!",sizeof(ota_info.error_message)); UpdateOTAFlag(&ota_info); @@ -675,18 +687,17 @@ try_again: /******************************************************************************* -* 函 数 名: OtaKTaskEntry +* 函 数 名: app_ota_by_4g * 功能描述: 通过命令来进行ota升级,该函数与升级的命令关联,通过4g方式传输bin文件 * 形 参: adapter:Adapter指针,指向注册的4G设备 * 返 回 值: 0:传输成功,-1:传输失败 *******************************************************************************/ static void app_ota_by_4g(void) { - struct ota_data recv_msg; char reply[16] = {0}; uint32_t baud_rate = BAUD_RATE_115200; - uint8 server_addr[64] = "115.238.53.60"; - uint8 server_port[64] = "7777"; + uint8_t server_addr[16] = "115.238.53.60"; + uint8_t server_port[8] = "7777"; mcuboot.flash_init(); @@ -701,7 +712,7 @@ static void app_ota_by_4g(void) { /* step1:Confirm the start signal of transmission. */ get_start_signal(adapter); - printf("start receive ota bin file.\n"); + KPrintf("start receive ota bin file.\n"); /* step2:start receive bin file,first wait for 4s. */ PrivTaskDelay(4000); if(0 == ota_data_recv(adapter)) @@ -710,7 +721,7 @@ static void app_ota_by_4g(void) } } mcuboot.flash_deinit(); - printf("ota file done,start reboot.\n"); + KPrintf("ota file done,start reboot.\n"); PrivTaskDelay(2000); mcuboot.op_reset(); } diff --git a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.h b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.h index 46b63d56b..3c8142007 100644 --- a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.h +++ b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.h @@ -25,7 +25,10 @@ #define JUMP_FAILED_FLAG 0XABABABAB #define JUMP_SUCCESS_FLAG 0XCDCDCDCD -#define LENGTH 1024 //每帧数据的数据包长度 +#define STARTFLAG 0x1A2B //数据帧开始信号标记 +#define DATAFLAG 0x3C4D //数据帧数据信号标记 +#define ENDTFLAG 0x5E6F //数据帧结束信号标记 +#define LENGTH 1024 //每帧数据的数据包长度 typedef enum { OTA_STATUS_IDLE = 0, // 空闲状态,没有进行OTA升级 @@ -43,8 +46,7 @@ typedef struct { uint32_t size; // 应用程序大小,记录分区固件的大小 uint32_t crc32; // 应用程序CRC32校验值,记录分区固件的crc32值 uint32_t version; // 应用程序版本号,记录分区固件的版本号 - uint32_t reserve; // 保留字段 - uint8_t description[128]; // 固件的描述信息,最多128个字符 + uint8_t description[32]; // 固件的描述信息,最多32个字符 } firmware_t; @@ -55,32 +57,31 @@ typedef struct { firmware_t down; // Download分区属性信息 uint32_t status; // 升级状态,取值来自于ota_status_t类型 uint32_t lastjumpflag; // bootloaer跳转失败的标志,bootloader里置0xABABABAB,跳转成功后在应用里置0xCDCDCDCD - uint32_t reserve[2]; // 保留字段 - uint8_t error_message[128]; // 错误信息,最多128个字符 + uint8_t error_message[64]; // 错误信息,最多64个字符 } ota_info_t; /*bin包传输过程中的数据帧相关的结构体*/ -struct ota_header_t +typedef struct { uint16_t frame_flag; // frame start flag 2 Bytes uint16_t dev_sid; // device software version uint32_t total_len; // send data total length caculated from each frame_len -}; +} ota_header_t; -struct ota_frame_t +typedef struct { uint32_t frame_id; // Current frame id - uint8_t frame_data[LENGTH]; // Current frame data,max length 256 + uint8_t frame_data[LENGTH]; // Current frame data uint16_t frame_len; // Current frame data length uint16_t crc; // Current frame data crc -}; +} ota_frame_t; -struct ota_data +typedef struct { - struct ota_header_t header; - struct ota_frame_t frame; -}; + ota_header_t header; + ota_frame_t frame; +} ota_data; void app_clear_jumpflag(void); diff --git a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/server_tcp.c b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/server_tcp.c index 88871782e..d1833b824 100644 --- a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/server_tcp.c +++ b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/server_tcp.c @@ -38,32 +38,34 @@ #include #include +#define STARTFLAG 0x1A2B //数据帧开始信号标记 +#define DATAFLAG 0x3C4D //数据帧数据信号标记 +#define ENDTFLAG 0x5E6F //数据帧结束信号标记 +#define PORT 7777 //socket端口号 +#define SIZE 100 //socket链接限制为100 +#define LENGTH 1024 //每帧数据的数据包长度 +#define BIN_PATH "/home/aep05/wgz/XiZi-xidatong-arm32-app.bin" //bin包的路径 -#define PORT 7777 //socket端口号 -#define SIZE 100 //socket链接限制为100 -#define LENGTH 1024 //每帧数据的数据包长度 -#define BIN_PATH "/home/aep05/wgz/XiZi-xidatong-arm32-app.bin" //bin包的路径 - -struct ota_header_t +typedef struct { uint16_t frame_flag; // frame start flag 2 Bytes uint16_t dev_sid; // device software version uint32_t total_len; // send data total length caculated from each frame_len -}; +} ota_header_t; -struct ota_frame_t +typedef struct { uint32_t frame_id; // Current frame id - uint8_t frame_data[LENGTH]; // Current frame data,max length 256 + uint8_t frame_data[LENGTH]; // Current frame data uint16_t frame_len; // Current frame data length uint16_t crc; // Current frame data crc -}; +} ota_frame_t; -struct ota_data +typedef struct { - struct ota_header_t header; - struct ota_frame_t frame; -}; + ota_header_t header; + ota_frame_t frame; +} ota_data; static int serverfd; // 服务器socket @@ -168,7 +170,7 @@ void sockt_init(void) *******************************************************************************/ void ota_start_signal(int fd) { - struct ota_data data; + ota_data data; struct stat st; uint8_t buf[32]; int file_size = 0, file_frame_cnt = 0, length = 0; @@ -198,12 +200,10 @@ void ota_start_signal(int fd) while(1) { - memset(&data, 0x0, sizeof(struct ota_data)); - data.header.frame_flag = 0x5A5A; + memset(&data, 0x0, sizeof(ota_data)); + data.header.frame_flag = STARTFLAG; //发送起始帧时把bin文件的大小一并发送出去 data.header.total_len = file_size; - memcpy(data.frame.frame_data,"ota_start_signal",strlen("ota_start_signal")); - data.frame.frame_len = strlen("ota_start_signal"); while(send(fd, &data, sizeof(data), MSG_NOSIGNAL) <= 0); printf("send start signal to client %d.\n", fd); @@ -240,7 +240,7 @@ void ota_start_signal(int fd) int ota_file_send(int fd) { unsigned char buf[32] = { 0 }; - struct ota_data data; + ota_data data; FILE *file_fd; int length = 0; int try_times; @@ -265,7 +265,7 @@ int ota_file_send(int fd) { memset(&data, 0, sizeof(data)); - data.header.frame_flag = 0x5A5A; + data.header.frame_flag = DATAFLAG; length = fread(data.frame.frame_data, 1, LENGTH, file_fd); if(length == LENGTH) { @@ -359,7 +359,7 @@ recv_again: memset(file_buf, 0, file_length); memset(&data, 0, sizeof(data)); - data.header.frame_flag = 0x5A5A; + data.header.frame_flag = ENDTFLAG; file_fd = fopen(BIN_PATH, "r"); if(NULL == file_fd) @@ -374,9 +374,7 @@ recv_again: { data.frame.frame_id = frame_cnt; data.header.total_len = file_length; - data.frame.frame_len = strlen("ota_end_signal"); data.frame.crc = calculate_crc16(file_buf, length); - memcpy(data.frame.frame_data,"ota_end_signal",strlen("ota_end_signal")); } send_end_signal: @@ -434,7 +432,7 @@ void* server_thread(void* p) { int fd = *(int*)p; unsigned char buf[32] = { 0 }; - struct ota_data data; + ota_data data; printf("pthread = %d\n",fd); sleep(3); From ed1c5eea1f2b2059dff3c1fb8a5109440f0222e9 Mon Sep 17 00:00:00 2001 From: wgzAIIT <820906721@qq.com> Date: Thu, 15 Jun 2023 16:43:02 +0800 Subject: [PATCH 12/23] Optimize ota function --- Ubiquitous/XiZi_IIoT/tool/bootloader/Kconfig | 20 +- .../XiZi_IIoT/tool/bootloader/ota/ota.c | 400 +++++++++--------- 2 files changed, 218 insertions(+), 202 deletions(-) diff --git a/Ubiquitous/XiZi_IIoT/tool/bootloader/Kconfig b/Ubiquitous/XiZi_IIoT/tool/bootloader/Kconfig index cb66fafd6..adca101fd 100644 --- a/Ubiquitous/XiZi_IIoT/tool/bootloader/Kconfig +++ b/Ubiquitous/XiZi_IIoT/tool/bootloader/Kconfig @@ -14,9 +14,27 @@ menu "OTA function" config MCUBOOT_APPLICATION bool "Config as application." + endchoice + + if MCUBOOT_APPLICATION + menu "The way of OTA firmware upgrade." + config OTA_BY_IAP + bool "Through serial port IAP." + default y + + config OTA_BY_TCPSERVER + bool "Through the public network TCP server." + default n select SUPPORT_CONNECTION_FRAMEWORK select CONNECTION_ADAPTER_4G - endchoice + + config OTA_BY_PLATFORM + bool "Through IoT management platform." + default n + select SUPPORT_CONNECTION_FRAMEWORK + select CONNECTION_ADAPTER_4G + endmenu + endif menu "Flash area address and size configuration." diff --git a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c index df515a230..309cb2941 100644 --- a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c +++ b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c @@ -33,20 +33,12 @@ * Private Function Prototypes ****************************************************************************/ static uint32_t calculate_crc32(uint32_t addr, uint32_t len); -static uint16_t calculate_crc16(uint8_t * data, uint32_t len); -static void UpdateNewApplication(void); +static status_t UpdateOTAFlag(ota_info_t *ptr); static void InitialVersion(void); static void BackupVersion(void); -static void BootLoaderJumpApp(void); -static status_t UpdateOTAFlag(ota_info_t *ptr); -static void app_ota_by_iap(void); +static void UpdateNewApplication(void); static void Update(void); - -#ifdef CONNECTION_ADAPTER_4G -static void get_start_signal(struct Adapter* adapter); -static int ota_data_recv(struct Adapter* adapter); -static void app_ota_by_4g(void); -#endif +static void BootLoaderJumpApp(void); /**************************************************************************** * Private Data @@ -67,8 +59,6 @@ static const mcuboot_t mcuboot = mcuboot_jump, mcuboot_delay }; - - static const uint32_t crc32tab[] = { 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, @@ -104,10 +94,6 @@ static const uint32_t crc32tab[] = { 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d }; -#ifdef CONNECTION_ADAPTER_4G -static ota_data start_msg; -static ota_data recv_msg; -#endif /******************************************************************************* * 函 数 名: calculate_crc32 @@ -131,28 +117,83 @@ static uint32_t calculate_crc32(uint32_t addr, uint32_t len) /******************************************************************************* -* 函 数 名: calculate_crc16 -* 功能描述: 计算给定长度的数据的crc16的值,用于OTA传输过程中数据帧的校验 -* 形 参: data:数据buffer - len:表示需要计算CRC16的数据长度 -* 返 回 值: 计算得到的CRC16值 +* 函 数 名: UpdateOTAFlag +* 功能描述: 更新OTA Flag区域的信息,版本完成下载后在app里进行调用 +* 形 参: ptr:ota_info_t结构体指针,描述OTA升级相关信息 +* 返 回 值: 如果函数执行成功,状态值为 kStatus_Success,否则状态值为其他错误码 *******************************************************************************/ -static uint16_t calculate_crc16(uint8_t * data, uint32_t len) +static status_t UpdateOTAFlag(ota_info_t *ptr) { - uint16_t reg_crc=0xFFFF; - while(len--) + status_t status; + + status = mcuboot.op_flash_erase(FLAG_FLAH_ADDRESS,sizeof(ota_info_t)); + if(status != kStatus_Success) { - reg_crc ^= *data++; - for(int j=0;j<8;j++) - { - if(reg_crc & 0x01) - reg_crc=reg_crc >>1 ^ 0xA001; - else - reg_crc=reg_crc >>1; - } + return status; + } + status = mcuboot.op_flash_write(FLAG_FLAH_ADDRESS,(void *)ptr,sizeof(ota_info_t)); + + return status; +} + + +/******************************************************************************* +* 函 数 名: InitialVersion +* 功能描述: 该函数可以烧写APP分区的初始化版本,初始化版本的版本号为0x1 +* 形 参: 无 +* 返 回 值: 无 +*******************************************************************************/ +static void InitialVersion(void) +{ + int32_t size; + ota_info_t ota_info; + + memset(&ota_info, 0, sizeof(ota_info_t)); + size = mcuboot.download_by_serial(XIUOS_FLAH_ADDRESS); + if(size > 0) + { + ota_info.os.size = size; + ota_info.os.crc32 = calculate_crc32(XIUOS_FLAH_ADDRESS, size); + ota_info.os.version = 0x1; + strncpy(ota_info.os.description, "The initial firmware.", sizeof(ota_info.os.description)); + UpdateOTAFlag(&ota_info); + } +} + + +/******************************************************************************* +* 函 数 名: BackupVersion +* 功能描述: 版本回退函数,如果升级的APP存在bug导致无法跳转需调用此函数进行版本回退 +* 形 参: 无 +* 返 回 值: 无 +*******************************************************************************/ +static void BackupVersion(void) +{ + status_t status; + + ota_info_t ota_info; + 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_BACKUP; + UpdateOTAFlag(&ota_info); + status = mcuboot.op_flash_copy(BAKUP_FLAH_ADDRESS, XIUOS_FLAH_ADDRESS, ota_info.bak.size); + if((status == kStatus_Success) &&(calculate_crc32(XIUOS_FLAH_ADDRESS, ota_info.bak.size) == ota_info.bak.crc32)) + { + mcuboot.print_string("\r\n------Backup app version success!------\r\n"); + ota_info.os.size = ota_info.bak.size; + ota_info.os.crc32 = ota_info.bak.crc32; + ota_info.os.version = ota_info.bak.version; + strncpy(ota_info.os.description, ota_info.bak.description, sizeof(ota_info.bak.description)); + UpdateOTAFlag(&ota_info); + } + else + { + mcuboot.print_string("\r\n------Backup app version failed!------\r\n"); + ota_info.status = OTA_STATUS_ERROR; + strncpy(ota_info.error_message, "Backup app version failed!",sizeof(ota_info.error_message)); + UpdateOTAFlag(&ota_info); } - KPrintf("crc = [0x%x]\n",reg_crc); - return reg_crc; } @@ -248,62 +289,28 @@ finish: /******************************************************************************* -* 函 数 名: InitialVersion -* 功能描述: 该函数可以烧写APP分区的初始化版本,初始化版本的版本号为0x1 +* 函 数 名: Update +* 功能描述: 根据实际情况进行初始化版本的烧录或者新版本的升级 * 形 参: 无 * 返 回 值: 无 *******************************************************************************/ -static void InitialVersion(void) +static void Update(void) { - int32_t size; ota_info_t ota_info; - - memset(&ota_info, 0, sizeof(ota_info_t)); - size = mcuboot.download_by_serial(XIUOS_FLAH_ADDRESS); - if(size > 0) - { - ota_info.os.size = size; - ota_info.os.crc32 = calculate_crc32(XIUOS_FLAH_ADDRESS, size); - ota_info.os.version = 0x1; - strncpy(ota_info.os.description, "The initial firmware.", sizeof(ota_info.os.description)); - UpdateOTAFlag(&ota_info); - } -} - - -/******************************************************************************* -* 函 数 名: BackupVersion -* 功能描述: 版本回退函数,如果升级的APP存在bug导致无法跳转需调用此函数进行版本回退 -* 形 参: 无 -* 返 回 值: 无 -*******************************************************************************/ -static void BackupVersion(void) -{ - status_t status; - - ota_info_t ota_info; + 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_BACKUP; - UpdateOTAFlag(&ota_info); - status = mcuboot.op_flash_copy(BAKUP_FLAH_ADDRESS, XIUOS_FLAH_ADDRESS, ota_info.bak.size); - if((status == kStatus_Success) &&(calculate_crc32(XIUOS_FLAH_ADDRESS, ota_info.bak.size) == ota_info.bak.crc32)) + /* 此时APP分区还没有有效的固件,需要在bootloader下通过iap烧写出厂固件 */ + if((ota_info.os.size > APP_FLASH_SIZE) || (calculate_crc32(XIUOS_FLAH_ADDRESS, ota_info.os.size) != ota_info.os.crc32)) { - mcuboot.print_string("\r\n------Backup app version success!------\r\n"); - ota_info.os.size = ota_info.bak.size; - ota_info.os.crc32 = ota_info.bak.crc32; - ota_info.os.version = ota_info.bak.version; - strncpy(ota_info.os.description, ota_info.bak.description, sizeof(ota_info.bak.description)); - UpdateOTAFlag(&ota_info); + mcuboot.print_string("\r\nNeed to flash initial firmware!\r\n"); + InitialVersion(); } else { - mcuboot.print_string("\r\n------Backup app version failed!------\r\n"); - ota_info.status = OTA_STATUS_ERROR; - strncpy(ota_info.error_message, "Backup app version failed!",sizeof(ota_info.error_message)); - UpdateOTAFlag(&ota_info); + UpdateNewApplication(); } + mcuboot.flash_deinit(); } @@ -336,27 +343,7 @@ static void BootLoaderJumpApp(void) } -/******************************************************************************* -* 函 数 名: UpdateOTAFlag -* 功能描述: 更新OTA Flag区域的信息,版本完成下载后在app里进行调用 -* 形 参: ptr:ota_info_t结构体指针,描述OTA升级相关信息 -* 返 回 值: 如果函数执行成功,状态值为 kStatus_Success,否则状态值为其他错误码 -*******************************************************************************/ -static status_t UpdateOTAFlag(ota_info_t *ptr) -{ - status_t status; - - status = mcuboot.op_flash_erase(FLAG_FLAH_ADDRESS,sizeof(ota_info_t)); - if(status != kStatus_Success) - { - return status; - } - status = mcuboot.op_flash_write(FLAG_FLAH_ADDRESS,(void *)ptr,sizeof(ota_info_t)); - - return status; -} - - +#ifdef OTA_BY_IAP /********************************************************************************* * 函 数 名: app_ota_by_iap * 功能描述: 通过命令来进行ota升级,该函数与升级的命令关联,通过串口iap方式传输bin文件 @@ -397,118 +384,42 @@ static void app_ota_by_iap(void) mcuboot.op_reset(); } SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0),iap, app_ota_by_iap, ota by iap function); +#endif +#ifdef OTA_BY_TCPSERVER +static uint16_t calculate_crc16(uint8_t * data, uint32_t len); +static void get_start_signal(struct Adapter* adapter); +static int ota_data_recv(struct Adapter* adapter); +static ota_data start_msg; +static ota_data recv_msg; + /******************************************************************************* -* 函 数 名: app_clear_jumpflag -* 功能描述: 跳转app成功后,在app中调用将lastjumpflag重置为0XCDCDCDCD -* 形 参: 无 -* 返 回 值: 无 +* 函 数 名: calculate_crc16 +* 功能描述: 计算给定长度的数据的crc16的值,用于OTA传输过程中数据帧的校验 +* 形 参: data:数据buffer + len:表示需要计算CRC16的数据长度 +* 返 回 值: 计算得到的CRC16值 *******************************************************************************/ -void app_clear_jumpflag(void) +static uint16_t calculate_crc16(uint8_t * data, uint32_t len) { - ota_info_t ota_info; - mcuboot.flash_init(); - //跳转成功设置lastjumpflag为JUMP_SUCCESS_FLAG - memset(&ota_info, 0, sizeof(ota_info_t)); - mcuboot.op_flash_read(FLAG_FLAH_ADDRESS, (void*)&ota_info, sizeof(ota_info_t)); - ota_info.lastjumpflag = JUMP_SUCCESS_FLAG; - UpdateOTAFlag(&ota_info); - mcuboot.flash_deinit(); -} - - -/******************************************************************************* -* 函 数 名: Update -* 功能描述: 根据实际情况进行初始化版本的烧录或者新版本的升级 -* 形 参: 无 -* 返 回 值: 无 -*******************************************************************************/ -static void Update(void) -{ - ota_info_t ota_info; - 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)); - /* 此时APP分区还没有有效的固件,需要在bootloader下通过iap烧写出厂固件 */ - if((ota_info.os.size > APP_FLASH_SIZE) || (calculate_crc32(XIUOS_FLAH_ADDRESS, ota_info.os.size) != ota_info.os.crc32)) + uint16_t reg_crc=0xFFFF; + while(len--) { - mcuboot.print_string("\r\nNeed to flash initial firmware!\r\n"); - InitialVersion(); - } - else - { - UpdateNewApplication(); - } - mcuboot.flash_deinit(); -} - - -/******************************************************************************* -* 函 数 名: ota_entry -* 功能描述: bootloader的入口函数 -* 形 参: 无 -* 返 回 值: 无 -*******************************************************************************/ -void ota_entry(void) -{ - uint8_t ch1, ch2; - uint32_t ret; - uint32_t timeout = 1000; - - mcuboot.board_init(); - - mcuboot.print_string("Please press 'space' key into menu in 10s !!!\r\n"); - - while(timeout) - { - ret = (SerialKeyPressed((uint8_t*)&ch1)); - if(ret) break; - timeout--; - mcuboot.op_delay(10); - } - - while(1) - { - - if((ret)&&(ch1 == 0x20)) + reg_crc ^= *data++; + for(int j=0;j<8;j++) { - mcuboot.print_string("\r\nPlease slecet:"); - - mcuboot.print_string("\r\n 1:run app"); - mcuboot.print_string("\r\n 2:update app"); - mcuboot.print_string("\r\n 3:reboot \r\n"); - - - ch2 = GetKey(); - switch(ch2) - { - case 0x31: - BootLoaderJumpApp(); - break; - - case 0x32: - Update(); - BootLoaderJumpApp(); - break; - - case 0x33: - mcuboot.op_reset(); - default: - break; - } + if(reg_crc & 0x01) + reg_crc=reg_crc >>1 ^ 0xA001; + else + reg_crc=reg_crc >>1; } - //10s内不按下空格键默然进行升级,升级完成后跳转 - else - { - Update(); - BootLoaderJumpApp(); - } } + KPrintf("crc = [0x%x]\n",reg_crc); + return reg_crc; } -#ifdef CONNECTION_ADAPTER_4G /******************************************************************************* * 函 数 名: get_start_signal * 功能描述: 通过4G方式从服务端接收开始信号 @@ -727,4 +638,91 @@ static void app_ota_by_4g(void) } SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0),ota, app_ota_by_4g, ota by 4g function); -#endif \ No newline at end of file +#endif + + +#ifdef OTA_BY_PLATFORM +#endif + + +/******************************************************************************* +* 函 数 名: app_clear_jumpflag +* 功能描述: 跳转app成功后,在app中调用将lastjumpflag重置为0XCDCDCDCD +* 形 参: 无 +* 返 回 值: 无 +*******************************************************************************/ +void app_clear_jumpflag(void) +{ + ota_info_t ota_info; + mcuboot.flash_init(); + //跳转成功设置lastjumpflag为JUMP_SUCCESS_FLAG + memset(&ota_info, 0, sizeof(ota_info_t)); + mcuboot.op_flash_read(FLAG_FLAH_ADDRESS, (void*)&ota_info, sizeof(ota_info_t)); + ota_info.lastjumpflag = JUMP_SUCCESS_FLAG; + UpdateOTAFlag(&ota_info); + mcuboot.flash_deinit(); +} + + +/******************************************************************************* +* 函 数 名: ota_entry +* 功能描述: bootloader的入口函数 +* 形 参: 无 +* 返 回 值: 无 +*******************************************************************************/ +void ota_entry(void) +{ + uint8_t ch1, ch2; + uint32_t ret; + uint32_t timeout = 1000; + + mcuboot.board_init(); + + mcuboot.print_string("Please press 'space' key into menu in 10s !!!\r\n"); + + while(timeout) + { + ret = (SerialKeyPressed((uint8_t*)&ch1)); + if(ret) break; + timeout--; + mcuboot.op_delay(10); + } + + while(1) + { + + if((ret)&&(ch1 == 0x20)) + { + mcuboot.print_string("\r\nPlease slecet:"); + + mcuboot.print_string("\r\n 1:run app"); + mcuboot.print_string("\r\n 2:update app"); + mcuboot.print_string("\r\n 3:reboot \r\n"); + + + ch2 = GetKey(); + switch(ch2) + { + case 0x31: + BootLoaderJumpApp(); + break; + + case 0x32: + Update(); + BootLoaderJumpApp(); + break; + + case 0x33: + mcuboot.op_reset(); + default: + break; + } + } + //10s内不按下空格键默然进行升级,升级完成后跳转 + else + { + Update(); + BootLoaderJumpApp(); + } + } +} \ No newline at end of file From 9995980a1ad3bf7d49c978a12f42b033f8c4abc5 Mon Sep 17 00:00:00 2001 From: wgzAIIT <820906721@qq.com> Date: Thu, 15 Jun 2023 16:52:52 +0800 Subject: [PATCH 13/23] 1.fix AT cmd framework bug 2.add mqtt support in the tool directory --- .../Framework/connection/adapter_agent.c | 13 +- .../XiZi_IIoT/board/xidatong-arm32/.defconfig | 2 +- Ubiquitous/XiZi_IIoT/tool/Kconfig | 1 + Ubiquitous/XiZi_IIoT/tool/Makefile | 4 + Ubiquitous/XiZi_IIoT/tool/mqtt/Kconfig | 12 + Ubiquitous/XiZi_IIoT/tool/mqtt/Makefile | 3 + Ubiquitous/XiZi_IIoT/tool/mqtt/aliyun_mqtt.c | 404 ++++++++++++++++++ Ubiquitous/XiZi_IIoT/tool/mqtt/aliyun_mqtt.h | 55 +++ 8 files changed, 491 insertions(+), 3 deletions(-) create mode 100644 Ubiquitous/XiZi_IIoT/tool/mqtt/Kconfig create mode 100644 Ubiquitous/XiZi_IIoT/tool/mqtt/Makefile create mode 100644 Ubiquitous/XiZi_IIoT/tool/mqtt/aliyun_mqtt.c create mode 100644 Ubiquitous/XiZi_IIoT/tool/mqtt/aliyun_mqtt.h diff --git a/APP_Framework/Framework/connection/adapter_agent.c b/APP_Framework/Framework/connection/adapter_agent.c index 4ffb2de1a..0dc75b52c 100755 --- a/APP_Framework/Framework/connection/adapter_agent.c +++ b/APP_Framework/Framework/connection/adapter_agent.c @@ -124,7 +124,9 @@ int ParseATReply(char *str, const char *format, ...) void ATSprintf(int fd, const char *format, va_list params) { last_cmd_len = vsnprintf(send_buf, sizeof(send_buf), format, params); +#ifdef CONNECTION_FRAMEWORK_DEBUG printf("AT send %s len %u\n",send_buf, last_cmd_len); +#endif PrivWrite(fd, send_buf, last_cmd_len); } @@ -279,7 +281,9 @@ int EntmSend(ATAgentType agent, const char *data, int len) PrivWrite(agent->fd, send_buff, len); PrivMutexAbandon(&agent->lock); +#ifdef CONNECTION_FRAMEWORK_DEBUG printf("entm send length %d\n", len); +#endif PrivFree(send_buff); @@ -301,13 +305,16 @@ int EntmRecv(ATAgentType agent, char *rev_buffer, int buffer_len, int timeout_s) PrivMutexAbandon(&agent->lock); //PrivTaskDelay(1000); if (PrivSemaphoreObtainWait(&agent->entm_rx_notice, &abstime)) { +#ifdef CONNECTION_FRAMEWORK_DEBUG printf("wait sem[%d] timeout\n",agent->entm_rx_notice); +#endif + agent->entm_recv_len = 0; return -1; } PrivMutexObtain(&agent->lock); - +#ifdef CONNECTION_FRAMEWORK_DEBUG 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); @@ -352,7 +359,9 @@ static int GetCompleteATReply(ATAgentType agent) PrivMutexAbandon(&agent->lock); continue; } else { +#ifdef CONNECTION_FRAMEWORK_DEBUG printf("ENTM_MODE recv %d Bytes done.\n",agent->entm_recv_len); +#endif agent->receive_mode = DEFAULT_MODE; PrivSemaphoreAbandon(&agent->entm_rx_notice); } diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/.defconfig b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/.defconfig index 7d4fa4771..5717d7a8f 100644 --- a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/.defconfig +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/.defconfig @@ -129,7 +129,7 @@ CONFIG_ZOMBIE_KTASK_STACKSIZE=2048 # CONFIG_KERNEL_CONSOLE=y CONFIG_KERNEL_BANNER=y -CONFIG_KERNEL_CONSOLEBUF_SIZE=128 +CONFIG_KERNEL_CONSOLEBUF_SIZE=256 # # Kernel Hook diff --git a/Ubiquitous/XiZi_IIoT/tool/Kconfig b/Ubiquitous/XiZi_IIoT/tool/Kconfig index 1989064ce..0c3aa9494 100644 --- a/Ubiquitous/XiZi_IIoT/tool/Kconfig +++ b/Ubiquitous/XiZi_IIoT/tool/Kconfig @@ -1,5 +1,6 @@ menu "Tool feature" source "$KERNEL_DIR/tool/bootloader/Kconfig" + source "$KERNEL_DIR/tool/mqtt/Kconfig" endmenu diff --git a/Ubiquitous/XiZi_IIoT/tool/Makefile b/Ubiquitous/XiZi_IIoT/tool/Makefile index cd148dd4f..e18b07080 100644 --- a/Ubiquitous/XiZi_IIoT/tool/Makefile +++ b/Ubiquitous/XiZi_IIoT/tool/Makefile @@ -8,4 +8,8 @@ ifeq ($(CONFIG_TOOL_USING_OTA),y) SRC_DIR += bootloader endif +ifeq ($(CONFIG_TOOL_USING_MQTT),y) + SRC_DIR += mqtt +endif + include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/tool/mqtt/Kconfig b/Ubiquitous/XiZi_IIoT/tool/mqtt/Kconfig new file mode 100644 index 000000000..f8c512ab7 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/tool/mqtt/Kconfig @@ -0,0 +1,12 @@ +menu "MQTT function" + + menuconfig TOOL_USING_MQTT + bool "Enable support MQTT function" + default n + select SUPPORT_CONNECTION_FRAMEWORK + select CONNECTION_ADAPTER_4G + + if TOOL_USING_MQTT + endif + +endmenu diff --git a/Ubiquitous/XiZi_IIoT/tool/mqtt/Makefile b/Ubiquitous/XiZi_IIoT/tool/mqtt/Makefile new file mode 100644 index 000000000..e181150ae --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/tool/mqtt/Makefile @@ -0,0 +1,3 @@ +SRC_FILES := aliyun_mqtt.c + +include $(KERNEL_ROOT)/compiler.mk \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/tool/mqtt/aliyun_mqtt.c b/Ubiquitous/XiZi_IIoT/tool/mqtt/aliyun_mqtt.c new file mode 100644 index 000000000..4d5f38148 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/tool/mqtt/aliyun_mqtt.c @@ -0,0 +1,404 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file: aliyun_mqtt.c +* @brief: connect aliyun mqtt +* @version: 1.0 +* @author: AIIT XUOS Lab +* @date: 2023/6/14 +* +*/ + +#include +#include +#include +#include +#include "shell.h" +#include "xsconfig.h" +#include +#include "aliyun_mqtt.h" + + +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]; + + +/******************************************************************************* +* 函 数 名: AdapterNetActive +* 功能描述: 使能设备的网络模块连接,连接TCP服务器并进入透传模式,当前使用4G方式 +* 形 参: 无 +* 返 回 值: 0表示成功,其他值表示失败 +*******************************************************************************/ +int AdapterNetActive(void) +{ + int ret = 0; + uint32_t baud_rate = BAUD_RATE_115200; + adapter = AdapterDeviceFindByName(ADAPTER_4G_NAME); + adapter->socket.socket_id = 0; + + ret = AdapterDeviceOpen(adapter); + if (ret < 0) + { + goto out; + } + + ret = AdapterDeviceControl(adapter, OPE_INT, &baud_rate); + if (ret < 0) + { + goto out; + } + + ret = AdapterDeviceConnect(adapter, CLIENT, SERVERIP, SERVERPORT, IPV4); + if (ret < 0) + { + goto out; + } + +out: + if (ret < 0) + { + AdapterDeviceClose(adapter); + } + + return ret; +} + + +/******************************************************************************* +* 函 数 名: MQTT_Connect +* 功能描述: 登录MQTT服务器 +* 形 参: 无 +* 返 回 值: 0表示成功,1表示失败 +*******************************************************************************/ +int MQTT_Connect(void) +{ + uint8_t TryConnect_time = 10; //尝试登录次数 + + Aliyun_mqtt.MessageID = 0; //报文标识符清零,CONNECT报文虽然不需要添加报文标识符,但是CONNECT报文是第一个发送的报文,在此清零报文标识符为后续报文做准备 + Aliyun_mqtt.Fixed_len = 1; //CONNECT报文固定报头长度暂定为1 + Aliyun_mqtt.Variable_len = 10; //CONNECT报文可变报头长度为10 + Aliyun_mqtt.Payload_len = (2+strlen(CLIENTID)) + (2+strlen(USERNAME)) + (2+strlen(PASSWORD)); //CONNECT报文中负载长度 + Aliyun_mqtt.Remaining_len = Aliyun_mqtt.Variable_len + Aliyun_mqtt.Payload_len; //剩余长度=可变报头长度+负载长度 + memset(Aliyun_mqtt.Pack_buff,0,sizeof(Aliyun_mqtt.Pack_buff)); + + Aliyun_mqtt.Pack_buff[0] = 0x10; //CONNECT报文 固定报头第1个字节0x10 + do{ + if((Aliyun_mqtt.Remaining_len/128) == 0) + { + Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len] = Aliyun_mqtt.Remaining_len; + } + else + { + Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len] = (Aliyun_mqtt.Remaining_len%128)|0x80; + } + Aliyun_mqtt.Fixed_len++; + Aliyun_mqtt.Remaining_len = Aliyun_mqtt.Remaining_len/128; + }while(Aliyun_mqtt.Remaining_len); + + Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+0] = 0x00; //CONNECT报文,可变报头第1个字节:固定0x00 + Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+1] = 0x04; //CONNECT报文,可变报头第2个字节:固定0x04 + Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+2] = 0x4D; //CONNECT报文,可变报头第3个字节:固定0x4D,大写字母M + Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+3] = 0x51; //CONNECT报文,可变报头第4个字节:固定0x51,大写字母Q + Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+4] = 0x54; //CONNECT报文,可变报头第5个字节:固定0x54,大写字母T + Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+5] = 0x54; //CONNECT报文,可变报头第6个字节:固定0x54,大写字母T + Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+6] = 0x04; //CONNECT报文,可变报头第7个字节:固定0x04 + Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+7] = 0xC2; //CONNECT报文,可变报头第8个字节:使能用户名和密码校验,不使用遗嘱功能,不保留会话功能 + Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+8] = 0x00; //CONNECT报文,可变报头第9个字节:保活时间高字节 + Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+9] = 0x64; //CONNECT报文,可变报头第10个字节:保活时间高字节 + + /* CLIENT_ID */ + Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+10] = strlen(CLIENTID)/256; //客户端ID长度高字节 + Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+11] = strlen(CLIENTID)%256; //客户端ID长度低字节 + memcpy(&Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+12],CLIENTID,strlen(CLIENTID)); //复制过来客户端ID字串 + /* USER_NAME */ + Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+12+strlen(CLIENTID)] = strlen(USERNAME)/256; //用户名长度高字节 + Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+13+strlen(CLIENTID)] = strlen(USERNAME)%256; //用户名长度低字节 + memcpy(&Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+14+strlen(CLIENTID)],USERNAME,strlen(USERNAME)); //复制过来用户名字串 + /* PASSWARD */ + Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+14+strlen(CLIENTID)+strlen(USERNAME)] = strlen(PASSWORD)/256; //密码长度高字节 + Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+15+strlen(CLIENTID)+strlen(USERNAME)] = strlen(PASSWORD)%256; //密码长度低字节 + memcpy(&Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+16+strlen(CLIENTID)+strlen(USERNAME)],PASSWORD,strlen(PASSWORD)); //复制过来密码字串 + + while(TryConnect_time > 0) + { + memset(mqtt_rxbuf,0,sizeof(mqtt_rxbuf)); + AdapterDeviceSend(adapter,Aliyun_mqtt.Pack_buff,Aliyun_mqtt.Fixed_len + Aliyun_mqtt.Variable_len + Aliyun_mqtt.Payload_len); + PrivTaskDelay(50); + AdapterDeviceRecv(adapter, mqtt_rxbuf, 4); + if(mqtt_rxbuf[0] == parket_connetAck[0] && mqtt_rxbuf[1] == parket_connetAck[1]) //连接成功 + { + return 0; + } + TryConnect_time--; + } + return 1; +} + + +/******************************************************************************* +* 函 数 名: MQTT_Disconnect +* 功能描述: 断开与MQTT服务器的连接 +* 形 参: 无 +* 返 回 值: 无 +*******************************************************************************/ +void MQTT_Disconnect(void) +{ + while(AdapterDeviceSend(adapter,parket_disconnet,sizeof(parket_disconnet)) < 0); +} + + +/******************************************************************************* +* 函 数 名: MQTT_SubscribeTopic +* 功能描述: MQTT订阅单个主题 +* 形 参: topic_name:要订阅的主题 +* 返 回 值: 0表示订阅成功,1表示订阅失败 +*******************************************************************************/ +int MQTT_SubscribeTopic(uint8_t *topic_name) +{ + uint8_t TrySub_time = 10; //尝试订阅次数 + + Aliyun_mqtt.Fixed_len = 1; //SUBSCRIBE报文,固定报头长度暂定为1 + Aliyun_mqtt.Variable_len = 2;//SUBSCRIBE报文,可变报头长度=2,2为字节报文标识符 + Aliyun_mqtt.Payload_len = 0; //SUBSCRIBE报文,负载数据长度暂定为0 + + Aliyun_mqtt.Payload_len = strlen(topic_name) + 2 + 1; //每个需要订阅的topic除了本身的字符串长度,还包含表示topic字符串长度的2字节,以及订阅等级1字节 + Aliyun_mqtt.Remaining_len = Aliyun_mqtt.Variable_len + Aliyun_mqtt.Payload_len; //计算剩余长度=可变报头长度+负载长度 + memset(Aliyun_mqtt.Pack_buff,0,sizeof(Aliyun_mqtt.Pack_buff)); + + Aliyun_mqtt.Pack_buff[0]=0x82; //SUBSCRIBE报文,固定报头第1个字节0x82 + do{ + if((Aliyun_mqtt.Remaining_len/128) == 0) + { + Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len] = Aliyun_mqtt.Remaining_len; + } + else + { + Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len] = (Aliyun_mqtt.Remaining_len%128)|0x80; + } + Aliyun_mqtt.Fixed_len++; + Aliyun_mqtt.Remaining_len = Aliyun_mqtt.Remaining_len/128; + }while(Aliyun_mqtt.Remaining_len); + + Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+0] = Aliyun_mqtt.MessageID/256; //报文标识符高字节 + Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+1] = Aliyun_mqtt.MessageID%256; //报文标识符低字节 + Aliyun_mqtt.MessageID++; //每用一次MessageID加1 + + Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+2] = strlen(topic_name)/256; //主题长度高字节 + Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+3] = strlen(topic_name)%256; //主题长度低字节 + memcpy(&Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+4],topic_name,strlen(topic_name)); //复制主题字串 + Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+4+strlen(topic_name)] = 0; //QOS等级设置为0 + + while(TrySub_time > 0) + { + memset(mqtt_rxbuf,0,sizeof(mqtt_rxbuf)); + AdapterDeviceSend(adapter,Aliyun_mqtt.Pack_buff,Aliyun_mqtt.Fixed_len + Aliyun_mqtt.Variable_len + Aliyun_mqtt.Payload_len); + PrivTaskDelay(50); + AdapterDeviceRecv(adapter, mqtt_rxbuf, 5); + if(mqtt_rxbuf[0] == parket_subAck[0] && mqtt_rxbuf[1] == parket_subAck[1]) //订阅成功 + { + return 0; + } + TrySub_time--; + } + return 1; +} + + +/******************************************************************************* +* 函 数 名: MQTT_UnSubscribeTopic +* 功能描述: MQTT取消订阅单个主题 +* 形 参: topic_name:要取消订阅的主题 +* 返 回 值: 0表示订阅成功,1表示订阅失败 +*******************************************************************************/ +int MQTT_UnSubscribeTopic(uint8_t *topic_name) +{ + uint8_t TryUnSub_time = 10; //尝试取消订阅次数 + + Aliyun_mqtt.Fixed_len = 1; //UNSUBSCRIBE报文,固定报头长度暂定为1 + Aliyun_mqtt.Variable_len = 2;//UNSUBSCRIBE报文,可变报头长度=2,2为字节报文标识符 + Aliyun_mqtt.Payload_len = strlen(topic_name) + 2; //每个需要取消的订阅topic除了本身的字符串长度,还包含表示topic字符串长度的2字节 + Aliyun_mqtt.Remaining_len = Aliyun_mqtt.Variable_len + Aliyun_mqtt.Payload_len; //计算剩余长度=可变报头长度+负载长度 + memset(Aliyun_mqtt.Pack_buff,0,sizeof(Aliyun_mqtt.Pack_buff)); + + Aliyun_mqtt.Pack_buff[0]=0xA0; //UNSUBSCRIBE报文,固定报头第1个字节0xA0 + do{ + if((Aliyun_mqtt.Remaining_len/128) == 0) + { + Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len] = Aliyun_mqtt.Remaining_len; + } + else + { + Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len] = (Aliyun_mqtt.Remaining_len%128)|0x80; + } + Aliyun_mqtt.Fixed_len++; + Aliyun_mqtt.Remaining_len = Aliyun_mqtt.Remaining_len/128; + }while(Aliyun_mqtt.Remaining_len); + + Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+0] = Aliyun_mqtt.MessageID/256; //报文标识符高字节 + Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+1] = Aliyun_mqtt.MessageID%256; //报文标识符低字节 + Aliyun_mqtt.MessageID++; //每用一次MessageID加1 + + Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+2] = strlen(topic_name)/256; //主题长度高字节 + Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+3] = strlen(topic_name)%256; //主题长度低字节 + memcpy(&Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+4],topic_name,strlen(topic_name)); //复制主题字串 + + while(TryUnSub_time > 0) + { + memset(mqtt_rxbuf,0,sizeof(mqtt_rxbuf)); + AdapterDeviceSend(adapter,Aliyun_mqtt.Pack_buff,Aliyun_mqtt.Fixed_len + Aliyun_mqtt.Variable_len + Aliyun_mqtt.Payload_len); + PrivTaskDelay(50); + AdapterDeviceRecv(adapter, mqtt_rxbuf, 4); + if(mqtt_rxbuf[0] == parket_unsubAck[0] && mqtt_rxbuf[1] == parket_unsubAck[1]) //取消订阅成功 + { + return 0; + } + TryUnSub_time--; + } + return 1; +} + + +/******************************************************************************* +* 函 数 名: MQTT_PublishQs0 +* 功能描述: MQTT发布QS0的主题 +* 形 参: topic_name:主题名称 + data:数据buffer + data_len:数据长度 +* 返 回 值: 发布Qs=0的消息服务器不返回确认消息 +*******************************************************************************/ +void MQTT_PublishQs0(uint8_t *topic_name,uint8_t *data, uint16_t data_len) +{ + Aliyun_mqtt.Fixed_len = 1; //PUBLISH等级0报文固定报头长度暂定为1 + Aliyun_mqtt.Variable_len = 2 + strlen(topic_name); //PUBLISH等级0报文,可变报头长度=2字节(topic长度)标识字节+topic字符串的长度 + Aliyun_mqtt.Payload_len = data_len; //PUBLISH等级0报文,负载数据长度=data_len + Aliyun_mqtt.Remaining_len = Aliyun_mqtt.Variable_len + Aliyun_mqtt.Payload_len; //计算剩余长度=可变报头长度+负载长度 + memset(Aliyun_mqtt.Pack_buff,0,sizeof(Aliyun_mqtt.Pack_buff)); + + Aliyun_mqtt.Pack_buff[0]=0x30; //PUBLISH等级0报文固定报头第1个字节0x30 + do{ + if((Aliyun_mqtt.Remaining_len/128) == 0) + { + Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len] = Aliyun_mqtt.Remaining_len; + } + else + { + Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len] = (Aliyun_mqtt.Remaining_len%128)|0x80; + } + Aliyun_mqtt.Fixed_len++; + Aliyun_mqtt.Remaining_len = Aliyun_mqtt.Remaining_len/128; + }while(Aliyun_mqtt.Remaining_len); + + Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+0]=strlen(topic_name)/256; //主题长度高字节 + Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+1]=strlen(topic_name)%256; //主题长度低字节 + memcpy(&Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+2],topic_name,strlen(topic_name)); //复制主题字串 + memcpy(&Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+2+strlen(topic_name)],data,data_len); //复制data数据 + + AdapterDeviceSend(adapter,Aliyun_mqtt.Pack_buff, Aliyun_mqtt.Fixed_len + Aliyun_mqtt.Variable_len + Aliyun_mqtt.Payload_len);//整个报文数据直到发送成功 +} + + +/******************************************************************************* +* 函 数 名: MQTT_SendHeart +* 功能描述: 发送心跳保活包 +* 形 参: 无 +* 返 回 值: 0表示发送成功,其他值表示发送失败 +*******************************************************************************/ +int MQTT_SendHeart(void) +{ + uint8_t TrySentHeart_time = 10; //尝试发送心跳保活次数 + while(TrySentHeart_time > 0) + { + memset(mqtt_rxbuf,0,sizeof(mqtt_rxbuf)); + AdapterDeviceSend(adapter,parket_heart,sizeof(parket_heart)); + PrivTaskDelay(50); + AdapterDeviceRecv(adapter, mqtt_rxbuf, 2); + if(mqtt_rxbuf[0] == 0xD0 && mqtt_rxbuf[1] == 0x00) + { + return 0; + } + TrySentHeart_time--; + } + return 1; +} + + +/******************************************************************************* +* 函 数 名: MQTT_DealPublishData +* 功能描述: 处理服务器发来的等级0的推送数据,附带topic信息 +* 形 参: redata:接收的数据,data_len:要处理的数据长度 +* 返 回 值: 无 +*******************************************************************************/ +void MQTT_DealPublishData(uint8_t *data, uint16_t data_len) +{ + uint8_t i; + uint16_t cmdpos,cmdlen; + + for(i = 1;i < 5;i++) + { + if((data[i] & 0x80) == 0) + break; + } + + cmdpos = 1+i+2; + cmdlen = data_len-(1+i+2); + + if(data_len <= CMD_SIZE) + { + memset(Aliyun_mqtt.cmdbuff, 0, CMD_SIZE); + 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"); + } + PrivTaskDelay(2000); + ret = MQTT_SubscribeTopic(TOPIC); + if(ret == 0) + { + KPrintf("mqtt sub successfully.\n"); + } + while(1) + { + memset(mqtt_rxbuf,0,sizeof(mqtt_rxbuf)); + len = AdapterDeviceRecv(adapter, mqtt_rxbuf, 256); + if(len > 0 && (mqtt_rxbuf[0] == 0x30)) + { + MQTT_DealPublishData(mqtt_rxbuf, len); + KPrintf("%s",Aliyun_mqtt.cmdbuff); + KPrintf("\r\n"); + } + PrivTaskDelay(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 new file mode 100644 index 000000000..b04fb57a5 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/tool/mqtt/aliyun_mqtt.h @@ -0,0 +1,55 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file: aliyun_mqtt.h +* @brief: connect aliyun mqtt +* @version: 1.0 +* @author: AIIT XUOS Lab +* @date: 2023/6/14 +* +*/ + +#ifndef _ALIYUN_MQTT_H_ +#define _ALIYUN_MQTT_H_ + +#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 TOPIC "/sys/iv74JbFgzhv/D001/thing/service/property/set" + +#define PACK_SIZE 512 //存放报文数据缓冲区大小 +#define CMD_SIZE 512 //保存推送的PUBLISH报文中的数据缓冲区大小 + +typedef struct{ + uint8_t Pack_buff[PACK_SIZE]; //存放发送报文数据缓冲区 + uint16_t MessageID; //记录报文标识符 + uint16_t Fixed_len; //固定报头长度 + uint16_t Variable_len; //可变报头长度 + uint16_t Payload_len; //有效负荷长度 + uint16_t Remaining_len; //保存报文剩余长度字节 + uint8_t cmdbuff[CMD_SIZE]; //保存推送的PUBLISH报文中的数据缓冲区 +}MQTT_TCB; + +int AdapterNetActive(void); +int MQTT_Connect(void); +void MQTT_Disconnect(void); +int MQTT_SubscribeTopic(uint8_t *topic_name); +int MQTT_UnSubscribeTopic(uint8_t *topic_name); +void MQTT_PublishQs0(uint8_t *topic_name,uint8_t *data, uint16_t data_len); +int MQTT_SendHeart(void); +void MQTT_DealPublishData(uint8_t *data, uint16_t data_len); +#endif \ No newline at end of file From 555b014bc9769482ac9bd14c22c274d185dc3b37 Mon Sep 17 00:00:00 2001 From: wgzAIIT <820906721@qq.com> Date: Thu, 15 Jun 2023 18:32:12 +0800 Subject: [PATCH 14/23] Optimize mqtt function add MQTT_PublishDataQs1 function --- Ubiquitous/XiZi_IIoT/tool/mqtt/aliyun_mqtt.c | 121 ++++++++++++++----- Ubiquitous/XiZi_IIoT/tool/mqtt/aliyun_mqtt.h | 5 +- 2 files changed, 98 insertions(+), 28 deletions(-) diff --git a/Ubiquitous/XiZi_IIoT/tool/mqtt/aliyun_mqtt.c b/Ubiquitous/XiZi_IIoT/tool/mqtt/aliyun_mqtt.c index 4d5f38148..735e35dfa 100644 --- a/Ubiquitous/XiZi_IIoT/tool/mqtt/aliyun_mqtt.c +++ b/Ubiquitous/XiZi_IIoT/tool/mqtt/aliyun_mqtt.c @@ -21,7 +21,6 @@ #include #include -#include #include #include "shell.h" #include "xsconfig.h" @@ -80,6 +79,31 @@ out: } + +/******************************************************************************* +* 函 数 名: MQTT_Send +* 功能描述: MQTT client数据发送函数 +* 形 参: buf:要发送的数据,buflen:要发送的数据长度 +* 返 回 值: 发送成功为0,发送失败为-1 +*******************************************************************************/ +int MQTT_Send(const uint8_t* buf, int buflen) +{ + return AdapterDeviceSend(adapter, buf, buflen) ; +} + + +/******************************************************************************* +* 函 数 名: MQTT_Recv +* 功能描述: MQTT client数据接收函数 +* 形 参: buf:数据缓冲区,buflen:期望接收的数据长度 +* 返 回 值: 实际接收到的数据长度,接收失败为-1 +*******************************************************************************/ +int MQTT_Recv(uint8_t* buf, int buflen) +{ + return AdapterDeviceRecv(adapter, buf, buflen) ; +} + + /******************************************************************************* * 函 数 名: MQTT_Connect * 功能描述: 登录MQTT服务器 @@ -138,9 +162,9 @@ int MQTT_Connect(void) while(TryConnect_time > 0) { memset(mqtt_rxbuf,0,sizeof(mqtt_rxbuf)); - AdapterDeviceSend(adapter,Aliyun_mqtt.Pack_buff,Aliyun_mqtt.Fixed_len + Aliyun_mqtt.Variable_len + Aliyun_mqtt.Payload_len); - PrivTaskDelay(50); - AdapterDeviceRecv(adapter, mqtt_rxbuf, 4); + MQTT_Send(Aliyun_mqtt.Pack_buff,Aliyun_mqtt.Fixed_len + Aliyun_mqtt.Variable_len + Aliyun_mqtt.Payload_len); + MdelayKTask(50); + MQTT_Recv(mqtt_rxbuf, 4); if(mqtt_rxbuf[0] == parket_connetAck[0] && mqtt_rxbuf[1] == parket_connetAck[1]) //连接成功 { return 0; @@ -159,7 +183,7 @@ int MQTT_Connect(void) *******************************************************************************/ void MQTT_Disconnect(void) { - while(AdapterDeviceSend(adapter,parket_disconnet,sizeof(parket_disconnet)) < 0); + while(MQTT_Send(parket_disconnet,sizeof(parket_disconnet)) < 0); } @@ -207,9 +231,9 @@ int MQTT_SubscribeTopic(uint8_t *topic_name) while(TrySub_time > 0) { memset(mqtt_rxbuf,0,sizeof(mqtt_rxbuf)); - AdapterDeviceSend(adapter,Aliyun_mqtt.Pack_buff,Aliyun_mqtt.Fixed_len + Aliyun_mqtt.Variable_len + Aliyun_mqtt.Payload_len); - PrivTaskDelay(50); - AdapterDeviceRecv(adapter, mqtt_rxbuf, 5); + MQTT_Send(Aliyun_mqtt.Pack_buff,Aliyun_mqtt.Fixed_len + Aliyun_mqtt.Variable_len + Aliyun_mqtt.Payload_len); + MdelayKTask(50); + MQTT_Recv(mqtt_rxbuf, 5); if(mqtt_rxbuf[0] == parket_subAck[0] && mqtt_rxbuf[1] == parket_subAck[1]) //订阅成功 { return 0; @@ -230,8 +254,8 @@ int MQTT_UnSubscribeTopic(uint8_t *topic_name) { uint8_t TryUnSub_time = 10; //尝试取消订阅次数 - Aliyun_mqtt.Fixed_len = 1; //UNSUBSCRIBE报文,固定报头长度暂定为1 - Aliyun_mqtt.Variable_len = 2;//UNSUBSCRIBE报文,可变报头长度=2,2为字节报文标识符 + Aliyun_mqtt.Fixed_len = 1; //UNSUBSCRIBE报文,固定报头长度暂定为1 + Aliyun_mqtt.Variable_len = 2; //UNSUBSCRIBE报文,可变报头长度=2,2为字节报文标识符 Aliyun_mqtt.Payload_len = strlen(topic_name) + 2; //每个需要取消的订阅topic除了本身的字符串长度,还包含表示topic字符串长度的2字节 Aliyun_mqtt.Remaining_len = Aliyun_mqtt.Variable_len + Aliyun_mqtt.Payload_len; //计算剩余长度=可变报头长度+负载长度 memset(Aliyun_mqtt.Pack_buff,0,sizeof(Aliyun_mqtt.Pack_buff)); @@ -261,10 +285,10 @@ int MQTT_UnSubscribeTopic(uint8_t *topic_name) while(TryUnSub_time > 0) { memset(mqtt_rxbuf,0,sizeof(mqtt_rxbuf)); - AdapterDeviceSend(adapter,Aliyun_mqtt.Pack_buff,Aliyun_mqtt.Fixed_len + Aliyun_mqtt.Variable_len + Aliyun_mqtt.Payload_len); - PrivTaskDelay(50); - AdapterDeviceRecv(adapter, mqtt_rxbuf, 4); - if(mqtt_rxbuf[0] == parket_unsubAck[0] && mqtt_rxbuf[1] == parket_unsubAck[1]) //取消订阅成功 + MQTT_Send(Aliyun_mqtt.Pack_buff,Aliyun_mqtt.Fixed_len + Aliyun_mqtt.Variable_len + Aliyun_mqtt.Payload_len); + MdelayKTask(50); + MQTT_Recv(mqtt_rxbuf, 4); + if(mqtt_rxbuf[0] == parket_unsubAck[0] && mqtt_rxbuf[1] == parket_unsubAck[1]) //取消订阅成功 { return 0; } @@ -275,17 +299,17 @@ int MQTT_UnSubscribeTopic(uint8_t *topic_name) /******************************************************************************* -* 函 数 名: MQTT_PublishQs0 -* 功能描述: MQTT发布QS0的主题 +* 函 数 名: MQTT_PublishDataQs0 +* 功能描述: 向服务器发送等级0的Publish报文 * 形 参: topic_name:主题名称 - data:数据buffer + data:数据缓存 data_len:数据长度 * 返 回 值: 发布Qs=0的消息服务器不返回确认消息 *******************************************************************************/ -void MQTT_PublishQs0(uint8_t *topic_name,uint8_t *data, uint16_t data_len) +void MQTT_PublishDataQs0(uint8_t *topic_name,uint8_t *data, uint16_t data_len) { Aliyun_mqtt.Fixed_len = 1; //PUBLISH等级0报文固定报头长度暂定为1 - Aliyun_mqtt.Variable_len = 2 + strlen(topic_name); //PUBLISH等级0报文,可变报头长度=2字节(topic长度)标识字节+topic字符串的长度 + Aliyun_mqtt.Variable_len = 2 + strlen(topic_name); //PUBLISH等级0报文,可变报头长度=2字节topic长度标识字节+topic字符串的长度 Aliyun_mqtt.Payload_len = data_len; //PUBLISH等级0报文,负载数据长度=data_len Aliyun_mqtt.Remaining_len = Aliyun_mqtt.Variable_len + Aliyun_mqtt.Payload_len; //计算剩余长度=可变报头长度+负载长度 memset(Aliyun_mqtt.Pack_buff,0,sizeof(Aliyun_mqtt.Pack_buff)); @@ -309,7 +333,50 @@ void MQTT_PublishQs0(uint8_t *topic_name,uint8_t *data, uint16_t data_len) memcpy(&Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+2],topic_name,strlen(topic_name)); //复制主题字串 memcpy(&Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+2+strlen(topic_name)],data,data_len); //复制data数据 - AdapterDeviceSend(adapter,Aliyun_mqtt.Pack_buff, Aliyun_mqtt.Fixed_len + Aliyun_mqtt.Variable_len + Aliyun_mqtt.Payload_len);//整个报文数据直到发送成功 + MQTT_Send(Aliyun_mqtt.Pack_buff, Aliyun_mqtt.Fixed_len + Aliyun_mqtt.Variable_len + Aliyun_mqtt.Payload_len); +} + + +/******************************************************************************* +* 函 数 名: MQTT_PublishDataQs1 +* 功能描述: 向服务器发送等级1的Publish报文 +* 形 参: topic_name:主题名称 + data:数据缓存 + data_len:数据长度 +* 返 回 值: 无 +*******************************************************************************/ +void MQTT_PublishDataQs1(uint8_t *topic_name,uint8_t *data, uint16_t data_len) +{ + Aliyun_mqtt.Fixed_len = 1; //PUBLISH等级1报文固定报头长度暂定为1 + Aliyun_mqtt.Variable_len = 2 + 2 + strlen(topic_name); //PUBLISH等级1报文,可变报头长度=2字节消息标识符+2字节topic长度标识字节+topic字符串的长度 + Aliyun_mqtt.Payload_len = data_len; //PUBLISH等级1报文,负载数据长度=data_len + Aliyun_mqtt.Remaining_len = Aliyun_mqtt.Variable_len + Aliyun_mqtt.Payload_len; //计算剩余长度=可变报头长度+负载长度 + + Aliyun_mqtt.Pack_buff[0] = 0x32; //等级1的Publish报文固定报头第1个字节,0x32 + do{ + if(Aliyun_mqtt.Remaining_len/128 == 0) + { + Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len] = Aliyun_mqtt.Remaining_len; + } + else + { + Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len] = (Aliyun_mqtt.Remaining_len%128)|0x80; + } + Aliyun_mqtt.Fixed_len++; + Aliyun_mqtt.Remaining_len = Aliyun_mqtt.Remaining_len/128; + }while(Aliyun_mqtt.Remaining_len); + + Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+0] = strlen(topic_name)/256; //主题长度高字节 + Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+1] = strlen(topic_name)%256; //主题长度低字节 + memcpy(&Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+2],topic_name,strlen(topic_name)); //复制主题字串 + + Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+2+strlen(topic_name)] = Aliyun_mqtt.MessageID/256; //报文标识符高字节 + Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+3+strlen(topic_name)] = Aliyun_mqtt.MessageID%256; //报文标识符低字节 + Aliyun_mqtt.MessageID++; //每用一次MessageID加1 + + memcpy(&Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+4+strlen(topic_name)],data,strlen(data)); //复制data数据 + + MQTT_Send(Aliyun_mqtt.Pack_buff,Aliyun_mqtt.Fixed_len + Aliyun_mqtt.Variable_len + Aliyun_mqtt.Payload_len); } @@ -325,10 +392,10 @@ int MQTT_SendHeart(void) while(TrySentHeart_time > 0) { memset(mqtt_rxbuf,0,sizeof(mqtt_rxbuf)); - AdapterDeviceSend(adapter,parket_heart,sizeof(parket_heart)); - PrivTaskDelay(50); - AdapterDeviceRecv(adapter, mqtt_rxbuf, 2); - if(mqtt_rxbuf[0] == 0xD0 && mqtt_rxbuf[1] == 0x00) + MQTT_Send(parket_heart,sizeof(parket_heart)); + MdelayKTask(50); + MQTT_Recv(mqtt_rxbuf, 2); + if(mqtt_rxbuf[0] == 0xD0 && mqtt_rxbuf[1] == 0x00) { return 0; } @@ -380,7 +447,7 @@ void testmqtt(void) { KPrintf("Log in to aliyun mqtt successfully.\n"); } - PrivTaskDelay(2000); + MdelayKTask(2000); ret = MQTT_SubscribeTopic(TOPIC); if(ret == 0) { @@ -389,14 +456,14 @@ void testmqtt(void) while(1) { memset(mqtt_rxbuf,0,sizeof(mqtt_rxbuf)); - len = AdapterDeviceRecv(adapter, mqtt_rxbuf, 256); + 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"); } - PrivTaskDelay(200); + MdelayKTask(200); MQTT_SendHeart(); } } diff --git a/Ubiquitous/XiZi_IIoT/tool/mqtt/aliyun_mqtt.h b/Ubiquitous/XiZi_IIoT/tool/mqtt/aliyun_mqtt.h index b04fb57a5..9a03b7448 100644 --- a/Ubiquitous/XiZi_IIoT/tool/mqtt/aliyun_mqtt.h +++ b/Ubiquitous/XiZi_IIoT/tool/mqtt/aliyun_mqtt.h @@ -45,11 +45,14 @@ typedef struct{ }MQTT_TCB; int AdapterNetActive(void); +int MQTT_Send(const uint8_t* buf, int buflen); +int MQTT_Recv(uint8_t* buf, int buflen); int MQTT_Connect(void); void MQTT_Disconnect(void); int MQTT_SubscribeTopic(uint8_t *topic_name); int MQTT_UnSubscribeTopic(uint8_t *topic_name); -void MQTT_PublishQs0(uint8_t *topic_name,uint8_t *data, uint16_t data_len); +void MQTT_PublishDataQs0(uint8_t *topic_name,uint8_t *data, uint16_t data_len); +void MQTT_PublishDataQs1(uint8_t *topic_name,uint8_t *data, uint16_t data_len); int MQTT_SendHeart(void); void MQTT_DealPublishData(uint8_t *data, uint16_t data_len); #endif \ No newline at end of file From dd43dd6d170f85d1afb4c4a98c44bd3400c18a30 Mon Sep 17 00:00:00 2001 From: wgzAIIT <820906721@qq.com> Date: Fri, 16 Jun 2023 17:40:00 +0800 Subject: [PATCH 15/23] Optimize ota function:changge ota version type --- .../XiZi_IIoT/tool/bootloader/ota/ota.c | 125 +++++++++++++++--- .../XiZi_IIoT/tool/bootloader/ota/ota.h | 9 +- 2 files changed, 114 insertions(+), 20 deletions(-) diff --git a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c index 309cb2941..702cf9506 100644 --- a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c +++ b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c @@ -18,6 +18,7 @@ * @date: 2023/4/23 * */ +#include #include #include "shell.h" #include "xsconfig.h" @@ -33,6 +34,7 @@ * Private Function Prototypes ****************************************************************************/ static uint32_t calculate_crc32(uint32_t addr, uint32_t len); +static int create_version(uint8_t* cur_version, uint8_t* new_version); static status_t UpdateOTAFlag(ota_info_t *ptr); static void InitialVersion(void); static void BackupVersion(void); @@ -116,6 +118,44 @@ static uint32_t calculate_crc32(uint32_t addr, uint32_t len) } +/******************************************************************************* +* 函 数 名: create_version +* 功能描述: 根据当前版本号生成新的三段式版本号,适用于iap方式和TCPSERVER +* 形 参: cur_version:当前版本号,new_version:生成的新版本号 +* 返 回 值: 0:生成成功,-1:生成失败 +* 说 明: 为保持一致,平台通过OTA传输而来的版本号也要保持这样三段式的形式 + 版本形式为major.minor.patch,如1.2.3 +*******************************************************************************/ +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) { + return -1; + } + + //将当前版本号加1 + patch++; + if(patch > MAX_PATCH) { + minor++; + patch = 0; + if (minor > MAX_MINOR) { + major++; + minor = 0; + patch = 0; + if (major > MAX_MAJOR) { + return -1; + } + } + } + + //更新版本号 + sprintf(new_version, "%d.%d.%d", major, minor, patch); + return 0; +} + + /******************************************************************************* * 函 数 名: UpdateOTAFlag * 功能描述: 更新OTA Flag区域的信息,版本完成下载后在app里进行调用 @@ -154,8 +194,10 @@ static void InitialVersion(void) { ota_info.os.size = size; ota_info.os.crc32 = calculate_crc32(XIUOS_FLAH_ADDRESS, size); - ota_info.os.version = 0x1; + + strncpy(ota_info.os.version,"1.0.0",sizeof(ota_info.os.version)); strncpy(ota_info.os.description, "The initial firmware.", sizeof(ota_info.os.description)); + UpdateOTAFlag(&ota_info); } } @@ -171,7 +213,7 @@ static void BackupVersion(void) { status_t status; - ota_info_t ota_info; + ota_info_t ota_info; memset(&ota_info, 0, sizeof(ota_info_t)); mcuboot.op_flash_read(FLAG_FLAH_ADDRESS, (void*)&ota_info, sizeof(ota_info_t)); @@ -183,15 +225,23 @@ static void BackupVersion(void) mcuboot.print_string("\r\n------Backup app version success!------\r\n"); ota_info.os.size = ota_info.bak.size; ota_info.os.crc32 = ota_info.bak.crc32; - ota_info.os.version = ota_info.bak.version; + + memset(ota_info.os.version,0,sizeof(ota_info.os.version)); + strncpy(ota_info.os.version, ota_info.bak.version, sizeof(ota_info.bak.version)); + + memset(ota_info.os.description,0,sizeof(ota_info.os.description)); strncpy(ota_info.os.description, ota_info.bak.description, sizeof(ota_info.bak.description)); + UpdateOTAFlag(&ota_info); } else { mcuboot.print_string("\r\n------Backup app version failed!------\r\n"); ota_info.status = OTA_STATUS_ERROR; + + memset(ota_info.error_message,0,sizeof(ota_info.error_message)); strncpy(ota_info.error_message, "Backup app version failed!",sizeof(ota_info.error_message)); + UpdateOTAFlag(&ota_info); } } @@ -208,8 +258,8 @@ static void UpdateNewApplication(void) { status_t status; ota_info_t ota_info; // 定义OTA信息结构体 - - memset(&ota_info, 0, sizeof(ota_info_t)); + + memset(&ota_info, 0, sizeof(ota_info_t)); // 从Flash中读取OTA信息 mcuboot.op_flash_read(FLAG_FLAH_ADDRESS, (void*)&ota_info, sizeof(ota_info_t)); @@ -230,15 +280,23 @@ static void UpdateNewApplication(void) mcuboot.print_string("\r\n------Backup app success!------\r\n"); ota_info.bak.size = ota_info.os.size; ota_info.bak.crc32 = ota_info.os.crc32; - ota_info.bak.version = ota_info.os.version; + + memset(ota_info.bak.version,0,sizeof(ota_info.bak.version)); + strncpy(ota_info.bak.version, ota_info.os.version, sizeof(ota_info.os.version)); + + memset(ota_info.bak.description,0,sizeof(ota_info.bak.description)); strncpy(ota_info.bak.description, ota_info.os.description, sizeof(ota_info.os.description)); + UpdateOTAFlag(&ota_info);; } else { mcuboot.print_string("\r\n------Backup app failed!------\r\n"); ota_info.status = OTA_STATUS_ERROR; + + memset(ota_info.error_message,0,sizeof(ota_info.error_message)); strncpy(ota_info.error_message, "Backup app failed!",sizeof(ota_info.error_message)); + UpdateOTAFlag(&ota_info);; goto finish; } @@ -251,8 +309,13 @@ static void UpdateNewApplication(void) ota_info.os.size = ota_info.down.size; ota_info.os.crc32 = ota_info.down.crc32; - ota_info.os.version = ota_info.down.version; + + memset(ota_info.os.version,0,sizeof(ota_info.os.version)); + strncpy(ota_info.os.version, ota_info.down.version, sizeof(ota_info.down.version)); + + memset(ota_info.os.description,0,sizeof(ota_info.os.description)); strncpy(ota_info.os.description, ota_info.down.description, sizeof(ota_info.down.description)); + ota_info.status == OTA_STATUS_IDLE; // 拷贝download分区到XiUOS System分区成功,将OTA升级状态设置为IDLE UpdateOTAFlag(&ota_info);; } @@ -260,7 +323,10 @@ static void UpdateNewApplication(void) { mcuboot.print_string("\r\n------The download partition copy failed!------\r\n"); ota_info.status = OTA_STATUS_ERROR; + + memset(ota_info.error_message,0,sizeof(ota_info.error_message)); strncpy(ota_info.error_message, "The download partition copy failed!",sizeof(ota_info.error_message)); + UpdateOTAFlag(&ota_info);; goto finish; } @@ -273,7 +339,10 @@ static void UpdateNewApplication(void) // 如果download分区CRC校验失败,升级失败 mcuboot.print_string("\r\n------Download Firmware CRC check failed!------\r\n"); ota_info.status = OTA_STATUS_ERROR; + + memset(ota_info.error_message,0,sizeof(ota_info.error_message)); strncpy(ota_info.error_message, "Download Firmware CRC check failed!",sizeof(ota_info.error_message)); + UpdateOTAFlag(&ota_info);; goto finish; } @@ -368,16 +437,26 @@ static void app_ota_by_iap(void) { ota_info.down.size = size; ota_info.down.crc32= calculate_crc32(DOWN_FLAH_ADDRESS, size); - ota_info.down.version = ota_info.os.version + 1; + + 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, "OTA Test 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(); @@ -429,7 +508,7 @@ static uint16_t calculate_crc16(uint8_t * data, uint32_t len) static void get_start_signal(struct Adapter* adapter) { ota_info_t ota_info; - char reply[16] = {0}; + uint8_t reply[16] = {0}; uint32_t flashdestination = DOWN_FLAH_ADDRESS; memset(&ota_info, 0, sizeof(ota_info_t)); @@ -462,7 +541,7 @@ static void get_start_signal(struct Adapter* adapter) { memset(reply, 0, sizeof(reply)); memcpy(reply, "notready", strlen("notready")); - KPrintf("not receive start signal,send [notready] signal to server\n"); + KPrintf("not receive start signal,send [notready] signal to server\n"); while(AdapterDeviceSend(adapter, reply, strlen(reply)) < 0); continue; } @@ -479,7 +558,7 @@ static void get_start_signal(struct Adapter* adapter) static int ota_data_recv(struct Adapter* adapter) { ota_info_t ota_info; - char reply[16] = {0}; + uint8_t reply[16] = {0}; int ret = 0, frame_cnt = 0, try_times = 5; uint32_t file_size = 0; uint32_t flashdestination = DOWN_FLAH_ADDRESS; @@ -581,16 +660,27 @@ try_again: { ota_info.down.size = file_size; ota_info.down.crc32= calculate_crc32(DOWN_FLAH_ADDRESS, file_size); - ota_info.down.version = ota_info.os.version + 1; + + 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, "4G 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); } return ret; @@ -605,7 +695,6 @@ try_again: *******************************************************************************/ static void app_ota_by_4g(void) { - char reply[16] = {0}; uint32_t baud_rate = BAUD_RATE_115200; uint8_t server_addr[16] = "115.238.53.60"; uint8_t server_port[8] = "7777"; @@ -618,14 +707,14 @@ static void app_ota_by_4g(void) AdapterDeviceOpen(adapter); AdapterDeviceControl(adapter, OPE_INT, &baud_rate); AdapterDeviceConnect(adapter, CLIENT, server_addr, server_port, IPV4); - PrivTaskDelay(100); + MdelayKTask(100); while(1) { /* step1:Confirm the start signal of transmission. */ get_start_signal(adapter); KPrintf("start receive ota bin file.\n"); /* step2:start receive bin file,first wait for 4s. */ - PrivTaskDelay(4000); + MdelayKTask(4000); if(0 == ota_data_recv(adapter)) { break; @@ -633,7 +722,7 @@ static void app_ota_by_4g(void) } mcuboot.flash_deinit(); KPrintf("ota file done,start reboot.\n"); - PrivTaskDelay(2000); + MdelayKTask(2000); mcuboot.op_reset(); } @@ -653,8 +742,8 @@ SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHE *******************************************************************************/ void app_clear_jumpflag(void) { - ota_info_t ota_info; - mcuboot.flash_init(); + ota_info_t ota_info; + mcuboot.flash_init(); //跳转成功设置lastjumpflag为JUMP_SUCCESS_FLAG memset(&ota_info, 0, sizeof(ota_info_t)); mcuboot.op_flash_read(FLAG_FLAH_ADDRESS, (void*)&ota_info, sizeof(ota_info_t)); diff --git a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.h b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.h index 3c8142007..71c6ec95e 100644 --- a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.h +++ b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.h @@ -23,6 +23,11 @@ #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 //数据帧开始信号标记 @@ -45,8 +50,8 @@ typedef enum { typedef struct { uint32_t size; // 应用程序大小,记录分区固件的大小 uint32_t crc32; // 应用程序CRC32校验值,记录分区固件的crc32值 - uint32_t version; // 应用程序版本号,记录分区固件的版本号 - uint8_t description[32]; // 固件的描述信息,最多32个字符 + uint8_t version[32]; // 应用程序版本号,记录分区固件的版本 + uint8_t description[32]; // 固件的描述信息,最多32个字符 } firmware_t; From 87921c4212611f440c23fc8f3035863b1fc14fe8 Mon Sep 17 00:00:00 2001 From: wgzAIIT <820906721@qq.com> Date: Mon, 19 Jun 2023 10:18:50 +0800 Subject: [PATCH 16/23] Support OTA upgrade by MQTT --- .../Framework/connection/4g/ec200t/ec200t.c | 4 +- .../Framework/connection/adapter_agent.c | 20 +- Ubiquitous/XiZi_IIoT/path_kernel.mk | 4 + .../XiZi_IIoT/tool/bootloader/ota/ota.c | 192 +++++++++++++++++- .../XiZi_IIoT/tool/bootloader/ota/ota.h | 17 +- Ubiquitous/XiZi_IIoT/tool/mqtt/aliyun_mqtt.c | 43 +--- Ubiquitous/XiZi_IIoT/tool/mqtt/aliyun_mqtt.h | 3 +- 7 files changed, 217 insertions(+), 66 deletions(-) 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); From 6f3d3b886255b43d080b18f3156a36c3269dd8cd Mon Sep 17 00:00:00 2001 From: wgzAIIT <820906721@qq.com> Date: Wed, 21 Jun 2023 13:52:40 +0800 Subject: [PATCH 17/23] improving MQTT transmission speed --- APP_Framework/Framework/connection/4g/ec200t/ec200t.c | 4 ++-- Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c | 8 ++++---- Ubiquitous/XiZi_IIoT/tool/mqtt/aliyun_mqtt.h | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/APP_Framework/Framework/connection/4g/ec200t/ec200t.c b/APP_Framework/Framework/connection/4g/ec200t/ec200t.c index 7f9ba7132..47e0ff525 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 1s - serial_cfg.serial_timeout = 1000; + //serial receive timeout 0.6s + serial_cfg.serial_timeout = 600; serial_cfg.is_ext_uart = 0; #ifdef ADAPTER_EC200T_DRIVER_EXT_PORT serial_cfg.is_ext_uart = 1; diff --git a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c index e8a9d0ad2..e3d68c643 100644 --- a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c +++ b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c @@ -738,8 +738,8 @@ 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]; +#define FRAME_LEN 1024 //每帧数据的数据包长度 +static uint8_t MqttRxbuf[2048]; static uint8_t FrameBuf[FRAME_LEN]; static OTA_TCB AliOTA; /******************************************************************************* @@ -806,7 +806,7 @@ static void app_ota_by_platform(void) while(1) { memset(MqttRxbuf,0,sizeof(MqttRxbuf)); - datalen = MQTT_Recv(MqttRxbuf, 512); + datalen = MQTT_Recv(MqttRxbuf, sizeof(MqttRxbuf)); if(datalen > 0 && (MqttRxbuf[0] == 0x30)) { MQTT_DealPublishData(MqttRxbuf, datalen); @@ -879,7 +879,7 @@ static void app_ota_by_platform(void) 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); + strncpy(ota_info.down.version, AliOTA.version, sizeof(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)); diff --git a/Ubiquitous/XiZi_IIoT/tool/mqtt/aliyun_mqtt.h b/Ubiquitous/XiZi_IIoT/tool/mqtt/aliyun_mqtt.h index baad5e4a6..f44517c90 100644 --- a/Ubiquitous/XiZi_IIoT/tool/mqtt/aliyun_mqtt.h +++ b/Ubiquitous/XiZi_IIoT/tool/mqtt/aliyun_mqtt.h @@ -30,8 +30,8 @@ #define SERVERIP "101.133.196.127" #define SERVERPORT "1883" -#define PACK_SIZE 512 //存放报文数据缓冲区大小 -#define CMD_SIZE 512 //保存推送的PUBLISH报文中的数据缓冲区大小 +#define PACK_SIZE 512 //存放报文数据缓冲区大小 +#define CMD_SIZE 2048 //保存推送的PUBLISH报文中的数据缓冲区大小 typedef struct{ uint8_t Pack_buff[PACK_SIZE]; //存放发送报文数据缓冲区 From 5900b504e3afdf9507f5aff59b0db2d0b8a71d35 Mon Sep 17 00:00:00 2001 From: wgzAIIT <820906721@qq.com> Date: Wed, 21 Jun 2023 18:59:04 +0800 Subject: [PATCH 18/23] =?UTF-8?q?1=E3=80=81improving=20MQTT=20transmission?= =?UTF-8?q?=20speed=202K=20Bytes=20per=20package=202=E3=80=81rename=20mqtt?= =?UTF-8?q?=20file=20name?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- APP_Framework/Applications/main.c | 15 +- .../Framework/connection/4g/ec200t/ec200t.c | 8 +- .../Framework/connection/adapter_agent.c | 17 +- APP_Framework/Framework/connection/at_agent.h | 7 +- Ubiquitous/XiZi_IIoT/tool/bootloader/Kconfig | 33 +- .../XiZi_IIoT/tool/bootloader/ota/ota.c | 35 +- Ubiquitous/XiZi_IIoT/tool/mqtt/Makefile | 2 +- Ubiquitous/XiZi_IIoT/tool/mqtt/aliyun_mqtt.c | 432 ------------------ .../XiZi_IIoT/tool/mqtt/platform_mqtt.c | 432 ++++++++++++++++++ .../mqtt/{aliyun_mqtt.h => platform_mqtt.h} | 12 +- 10 files changed, 520 insertions(+), 473 deletions(-) delete mode 100644 Ubiquitous/XiZi_IIoT/tool/mqtt/aliyun_mqtt.c create mode 100644 Ubiquitous/XiZi_IIoT/tool/mqtt/platform_mqtt.c rename Ubiquitous/XiZi_IIoT/tool/mqtt/{aliyun_mqtt.h => platform_mqtt.h} (89%) diff --git a/APP_Framework/Applications/main.c b/APP_Framework/Applications/main.c index e1de024b5..53de5ed34 100644 --- a/APP_Framework/Applications/main.c +++ b/APP_Framework/Applications/main.c @@ -18,12 +18,21 @@ extern int FrameworkInit(); extern void ApplicationOtaTaskInit(void); + +#ifdef OTA_BY_PLATFORM +extern int OtaTask(void); +#endif + int main(void) { - printf("Hello, world! \n"); - FrameworkInit(); + printf("Hello, world! \n"); + FrameworkInit(); #ifdef APPLICATION_OTA - ApplicationOtaTaskInit(); + ApplicationOtaTaskInit(); +#endif + +#ifdef OTA_BY_PLATFORM + OtaTask(); #endif return 0; } diff --git a/APP_Framework/Framework/connection/4g/ec200t/ec200t.c b/APP_Framework/Framework/connection/4g/ec200t/ec200t.c index 47e0ff525..6fd36e9b9 100644 --- a/APP_Framework/Framework/connection/4g/ec200t/ec200t.c +++ b/APP_Framework/Framework/connection/4g/ec200t/ec200t.c @@ -163,8 +163,12 @@ 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 0.6s - serial_cfg.serial_timeout = 600; +#ifdef TOOL_USING_OTA + serial_cfg.serial_timeout = OTA_RX_TIMEOUT; +#else + //serial receive timeout 10s + serial_cfg.serial_timeout = 100000; +#endif 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 969da816f..dd77eb3de 100755 --- a/APP_Framework/Framework/connection/adapter_agent.c +++ b/APP_Framework/Framework/connection/adapter_agent.c @@ -355,12 +355,25 @@ static int GetCompleteATReply(ATAgentType agent) PrivMutexObtain(&agent->lock); if (agent->receive_mode == ENTM_MODE) { if (agent->entm_recv_len < ENTM_RECV_MAX) { - if((res == 1) && (agent->entm_recv_len < agent->read_len)) { +#ifdef TOOL_USING_MQTT + 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 { + } +#else + agent->entm_recv_buf[agent->entm_recv_len] = ch; + agent->entm_recv_len++; + if(agent->entm_recv_len < agent->read_len) + { + PrivMutexAbandon(&agent->lock); + continue; + } +#endif + else + { #ifdef CONNECTION_FRAMEWORK_DEBUG printf("ENTM_MODE recv %d Bytes done.\n",agent->entm_recv_len); #endif diff --git a/APP_Framework/Framework/connection/at_agent.h b/APP_Framework/Framework/connection/at_agent.h index 2455146e4..b1255c51e 100755 --- a/APP_Framework/Framework/connection/at_agent.h +++ b/APP_Framework/Framework/connection/at_agent.h @@ -28,6 +28,12 @@ #define REPLY_TIME_OUT 10 +#ifdef TOOL_USING_OTA +#define ENTM_RECV_MAX OTA_RX_BUFFERSIZE +#else +#define ENTM_RECV_MAX 256 +#endif + enum ReceiveMode { DEFAULT_MODE = 0, @@ -70,7 +76,6 @@ struct ATAgent #endif pthread_t at_handler; - #define ENTM_RECV_MAX 2048 char entm_recv_buf[ENTM_RECV_MAX]; uint32 entm_recv_len; enum ReceiveMode receive_mode; diff --git a/Ubiquitous/XiZi_IIoT/tool/bootloader/Kconfig b/Ubiquitous/XiZi_IIoT/tool/bootloader/Kconfig index adca101fd..c826295d4 100644 --- a/Ubiquitous/XiZi_IIoT/tool/bootloader/Kconfig +++ b/Ubiquitous/XiZi_IIoT/tool/bootloader/Kconfig @@ -17,23 +17,19 @@ menu "OTA function" endchoice if MCUBOOT_APPLICATION - menu "The way of OTA firmware upgrade." - config OTA_BY_IAP - bool "Through serial port IAP." - default y - - config OTA_BY_TCPSERVER - bool "Through the public network TCP server." - default n - select SUPPORT_CONNECTION_FRAMEWORK - select CONNECTION_ADAPTER_4G + choice + prompt "The way of OTA firmware upgrade." + default OTA_BY_PLATFORM config OTA_BY_PLATFORM bool "Through IoT management platform." - default n + select TOOL_USING_MQTT + + config OTA_BY_TCPSERVER + bool "Through the public network TCP server." select SUPPORT_CONNECTION_FRAMEWORK select CONNECTION_ADAPTER_4G - endmenu + endchoice endif @@ -62,7 +58,18 @@ menu "OTA function" hex "Application package size,the default size is limited to 1M." default 0x00100000 endmenu - + + config OTA_RX_TIMEOUT + int "OTA receive data timeout(ms)." + default 600 if OTA_BY_PLATFORM + default 10000 if OTA_BY_TCPSERVER + default 10000 if MCUBOOT_BOOTLOADER + + config OTA_RX_BUFFERSIZE + int "OTA receive data buffer size." + default 3072 if OTA_BY_PLATFORM + default 2048 if OTA_BY_TCPSERVER + default 256 if MCUBOOT_BOOTLOADER endif endmenu diff --git a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c index e3d68c643..da5203b9d 100644 --- a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c +++ b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c @@ -31,7 +31,7 @@ #endif #ifdef OTA_BY_PLATFORM -#include "aliyun_mqtt.h" +#include "platform_mqtt.h" #endif /**************************************************************************** @@ -159,7 +159,7 @@ static int create_version(uint8_t* cur_version, uint8_t* new_version) //更新版本号 sprintf(new_version, "%03d.%03d.%03d", major, minor, patch); - return 0; + return 0; } @@ -419,7 +419,6 @@ static void BootLoaderJumpApp(void) } -#ifdef OTA_BY_IAP /********************************************************************************* * 函 数 名: app_ota_by_iap * 功能描述: 通过命令来进行ota升级,该函数与升级的命令关联,通过串口iap方式传输bin文件 @@ -470,7 +469,6 @@ static void app_ota_by_iap(void) mcuboot.op_reset(); } SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0),iap, app_ota_by_iap, ota by iap function); -#endif #ifdef OTA_BY_TCPSERVER @@ -738,8 +736,8 @@ SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHE #ifdef OTA_BY_PLATFORM -#define FRAME_LEN 1024 //每帧数据的数据包长度 -static uint8_t MqttRxbuf[2048]; +#define FRAME_LEN 2048 //每帧数据的数据包长度 +static uint8_t MqttRxbuf[3072]; static uint8_t FrameBuf[FRAME_LEN]; static OTA_TCB AliOTA; /******************************************************************************* @@ -783,7 +781,7 @@ void OTA_Download(int size, int offset) * 形 参: 无 * 返 回 值: 无 *******************************************************************************/ -static void app_ota_by_platform(void) +static void app_ota_by_platform(void* parameter) { int datalen; int ret = 0; @@ -810,7 +808,7 @@ static void app_ota_by_platform(void) 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) + 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) { KPrintf("ota file size:%d\r\n",AliOTA.size); KPrintf("ota file id:%d\r\n",AliOTA.streamId); @@ -822,12 +820,12 @@ static void app_ota_by_platform(void) 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); //发送要下载的数据信息给服务器 + 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")) + if(strstr((char *)Platform_mqtt.cmdbuff,"download_reply")) { memset(FrameBuf,0,sizeof(FrameBuf)); memcpy(FrameBuf, &MqttRxbuf[datalen-AliOTA.downlen-2], AliOTA.downlen); @@ -906,7 +904,18 @@ static void app_ota_by_platform(void) 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); +int OtaTask(void) +{ + int32 ota_task = 0; + ota_task = KTaskCreate("ota_platform", app_ota_by_platform, NULL,8192, 10); + if(ota_task < 0) { + KPrintf("ota_task create failed ...%s %d.\n", __FUNCTION__,__LINE__); + return ERROR; + } + + StartupKTask(ota_task); + return 0; +} #endif diff --git a/Ubiquitous/XiZi_IIoT/tool/mqtt/Makefile b/Ubiquitous/XiZi_IIoT/tool/mqtt/Makefile index e181150ae..93fa24fb1 100644 --- a/Ubiquitous/XiZi_IIoT/tool/mqtt/Makefile +++ b/Ubiquitous/XiZi_IIoT/tool/mqtt/Makefile @@ -1,3 +1,3 @@ -SRC_FILES := aliyun_mqtt.c +SRC_FILES := platform_mqtt.c include $(KERNEL_ROOT)/compiler.mk \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/tool/mqtt/aliyun_mqtt.c b/Ubiquitous/XiZi_IIoT/tool/mqtt/aliyun_mqtt.c deleted file mode 100644 index 048681371..000000000 --- a/Ubiquitous/XiZi_IIoT/tool/mqtt/aliyun_mqtt.c +++ /dev/null @@ -1,432 +0,0 @@ -/* -* Copyright (c) 2020 AIIT XUOS Lab -* XiUOS is licensed under Mulan PSL v2. -* You can use this software according to the terms and conditions of the Mulan PSL v2. -* You may obtain a copy of Mulan PSL v2 at: -* http://license.coscl.org.cn/MulanPSL2 -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, -* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, -* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -* See the Mulan PSL v2 for more details. -*/ - -/** -* @file: aliyun_mqtt.c -* @brief: connect aliyun mqtt -* @version: 1.0 -* @author: AIIT XUOS Lab -* @date: 2023/6/14 -* -*/ - -#include -#include -#include -#include "shell.h" -#include "xsconfig.h" -#include -#include "aliyun_mqtt.h" - -MQTT_TCB Aliyun_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_subAck[] = {0x90,0x03,0x00,0x0A,0x01}; //订阅成功服务器回应报文 -static const uint8_t parket_unsubAck[] = {0xB0,0x02,0x00,0x0A}; //取消订阅成功服务器回应报文 -static uint8_t mqtt_rxbuf[16]; - - -/******************************************************************************* -* 函 数 名: AdapterNetActive -* 功能描述: 使能设备的网络模块连接,连接TCP服务器并进入透传模式,当前使用4G方式 -* 形 参: 无 -* 返 回 值: 0表示成功,其他值表示失败 -*******************************************************************************/ -int AdapterNetActive(void) -{ - int ret = 0; - uint32_t baud_rate = BAUD_RATE_115200; - adapter = AdapterDeviceFindByName(ADAPTER_4G_NAME); - adapter->socket.socket_id = 0; - - ret = AdapterDeviceOpen(adapter); - if (ret < 0) - { - goto out; - } - - ret = AdapterDeviceControl(adapter, OPE_INT, &baud_rate); - if (ret < 0) - { - goto out; - } - - ret = AdapterDeviceConnect(adapter, CLIENT, SERVERIP, SERVERPORT, IPV4); - if (ret < 0) - { - goto out; - } - -out: - if (ret < 0) - { - AdapterDeviceClose(adapter); - } - - return ret; -} - - - -/******************************************************************************* -* 函 数 名: MQTT_Send -* 功能描述: MQTT client数据发送函数 -* 形 参: buf:要发送的数据,buflen:要发送的数据长度 -* 返 回 值: 发送成功为0,发送失败为-1 -*******************************************************************************/ -int MQTT_Send(const uint8_t* buf, int buflen) -{ - return AdapterDeviceSend(adapter, buf, buflen) ; -} - - -/******************************************************************************* -* 函 数 名: MQTT_Recv -* 功能描述: MQTT client数据接收函数 -* 形 参: buf:数据缓冲区,buflen:期望接收的数据长度 -* 返 回 值: 实际接收到的数据长度,接收失败为-1 -*******************************************************************************/ -int MQTT_Recv(uint8_t* buf, int buflen) -{ - return AdapterDeviceRecv(adapter, buf, buflen) ; -} - - -/******************************************************************************* -* 函 数 名: MQTT_Connect -* 功能描述: 登录MQTT服务器 -* 形 参: 无 -* 返 回 值: 0表示成功,1表示失败 -*******************************************************************************/ -int MQTT_Connect(void) -{ - uint8_t TryConnect_time = 10; //尝试登录次数 - - Aliyun_mqtt.MessageID = 0; //报文标识符清零,CONNECT报文虽然不需要添加报文标识符,但是CONNECT报文是第一个发送的报文,在此清零报文标识符为后续报文做准备 - Aliyun_mqtt.Fixed_len = 1; //CONNECT报文固定报头长度暂定为1 - Aliyun_mqtt.Variable_len = 10; //CONNECT报文可变报头长度为10 - Aliyun_mqtt.Payload_len = (2+strlen(CLIENTID)) + (2+strlen(USERNAME)) + (2+strlen(PASSWORD)); //CONNECT报文中负载长度 - Aliyun_mqtt.Remaining_len = Aliyun_mqtt.Variable_len + Aliyun_mqtt.Payload_len; //剩余长度=可变报头长度+负载长度 - memset(Aliyun_mqtt.Pack_buff,0,sizeof(Aliyun_mqtt.Pack_buff)); - - Aliyun_mqtt.Pack_buff[0] = 0x10; //CONNECT报文 固定报头第1个字节0x10 - do{ - if((Aliyun_mqtt.Remaining_len/128) == 0) - { - Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len] = Aliyun_mqtt.Remaining_len; - } - else - { - Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len] = (Aliyun_mqtt.Remaining_len%128)|0x80; - } - Aliyun_mqtt.Fixed_len++; - Aliyun_mqtt.Remaining_len = Aliyun_mqtt.Remaining_len/128; - }while(Aliyun_mqtt.Remaining_len); - - Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+0] = 0x00; //CONNECT报文,可变报头第1个字节:固定0x00 - Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+1] = 0x04; //CONNECT报文,可变报头第2个字节:固定0x04 - Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+2] = 0x4D; //CONNECT报文,可变报头第3个字节:固定0x4D,大写字母M - Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+3] = 0x51; //CONNECT报文,可变报头第4个字节:固定0x51,大写字母Q - Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+4] = 0x54; //CONNECT报文,可变报头第5个字节:固定0x54,大写字母T - Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+5] = 0x54; //CONNECT报文,可变报头第6个字节:固定0x54,大写字母T - Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+6] = 0x04; //CONNECT报文,可变报头第7个字节:固定0x04 - Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+7] = 0xC2; //CONNECT报文,可变报头第8个字节:使能用户名和密码校验,不使用遗嘱功能,不保留会话功能 - Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+8] = 0x00; //CONNECT报文,可变报头第9个字节:保活时间高字节 - Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+9] = 0x64; //CONNECT报文,可变报头第10个字节:保活时间高字节 - - /* CLIENT_ID */ - Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+10] = strlen(CLIENTID)/256; //客户端ID长度高字节 - Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+11] = strlen(CLIENTID)%256; //客户端ID长度低字节 - memcpy(&Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+12],CLIENTID,strlen(CLIENTID)); //复制过来客户端ID字串 - /* USER_NAME */ - Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+12+strlen(CLIENTID)] = strlen(USERNAME)/256; //用户名长度高字节 - Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+13+strlen(CLIENTID)] = strlen(USERNAME)%256; //用户名长度低字节 - memcpy(&Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+14+strlen(CLIENTID)],USERNAME,strlen(USERNAME)); //复制过来用户名字串 - /* PASSWARD */ - Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+14+strlen(CLIENTID)+strlen(USERNAME)] = strlen(PASSWORD)/256; //密码长度高字节 - Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+15+strlen(CLIENTID)+strlen(USERNAME)] = strlen(PASSWORD)%256; //密码长度低字节 - memcpy(&Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+16+strlen(CLIENTID)+strlen(USERNAME)],PASSWORD,strlen(PASSWORD)); //复制过来密码字串 - - while(TryConnect_time > 0) - { - memset(mqtt_rxbuf,0,sizeof(mqtt_rxbuf)); - MQTT_Send(Aliyun_mqtt.Pack_buff,Aliyun_mqtt.Fixed_len + Aliyun_mqtt.Variable_len + Aliyun_mqtt.Payload_len); - MdelayKTask(50); - MQTT_Recv(mqtt_rxbuf, 4); - if(mqtt_rxbuf[0] == parket_connetAck[0] && mqtt_rxbuf[1] == parket_connetAck[1]) //连接成功 - { - return 0; - } - TryConnect_time--; - } - return 1; -} - - -/******************************************************************************* -* 函 数 名: MQTT_Disconnect -* 功能描述: 断开与MQTT服务器的连接 -* 形 参: 无 -* 返 回 值: 无 -*******************************************************************************/ -void MQTT_Disconnect(void) -{ - while(MQTT_Send(parket_disconnet,sizeof(parket_disconnet)) < 0); -} - - -/******************************************************************************* -* 函 数 名: MQTT_SubscribeTopic -* 功能描述: MQTT订阅单个主题 -* 形 参: topic_name:要订阅的主题 -* 返 回 值: 0表示订阅成功,1表示订阅失败 -*******************************************************************************/ -int MQTT_SubscribeTopic(uint8_t *topic_name) -{ - uint8_t TrySub_time = 10; //尝试订阅次数 - - Aliyun_mqtt.Fixed_len = 1; //SUBSCRIBE报文,固定报头长度暂定为1 - Aliyun_mqtt.Variable_len = 2;//SUBSCRIBE报文,可变报头长度=2,2为字节报文标识符 - Aliyun_mqtt.Payload_len = 0; //SUBSCRIBE报文,负载数据长度暂定为0 - - Aliyun_mqtt.Payload_len = strlen(topic_name) + 2 + 1; //每个需要订阅的topic除了本身的字符串长度,还包含表示topic字符串长度的2字节,以及订阅等级1字节 - Aliyun_mqtt.Remaining_len = Aliyun_mqtt.Variable_len + Aliyun_mqtt.Payload_len; //计算剩余长度=可变报头长度+负载长度 - memset(Aliyun_mqtt.Pack_buff,0,sizeof(Aliyun_mqtt.Pack_buff)); - - Aliyun_mqtt.Pack_buff[0]=0x82; //SUBSCRIBE报文,固定报头第1个字节0x82 - do{ - if((Aliyun_mqtt.Remaining_len/128) == 0) - { - Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len] = Aliyun_mqtt.Remaining_len; - } - else - { - Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len] = (Aliyun_mqtt.Remaining_len%128)|0x80; - } - Aliyun_mqtt.Fixed_len++; - Aliyun_mqtt.Remaining_len = Aliyun_mqtt.Remaining_len/128; - }while(Aliyun_mqtt.Remaining_len); - - Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+0] = Aliyun_mqtt.MessageID/256; //报文标识符高字节 - Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+1] = Aliyun_mqtt.MessageID%256; //报文标识符低字节 - Aliyun_mqtt.MessageID++; //每用一次MessageID加1 - - Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+2] = strlen(topic_name)/256; //主题长度高字节 - Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+3] = strlen(topic_name)%256; //主题长度低字节 - memcpy(&Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+4],topic_name,strlen(topic_name)); //复制主题字串 - Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+4+strlen(topic_name)] = 0; //QOS等级设置为0 - - while(TrySub_time > 0) - { - memset(mqtt_rxbuf,0,sizeof(mqtt_rxbuf)); - MQTT_Send(Aliyun_mqtt.Pack_buff,Aliyun_mqtt.Fixed_len + Aliyun_mqtt.Variable_len + Aliyun_mqtt.Payload_len); - MdelayKTask(50); - MQTT_Recv(mqtt_rxbuf, 5); - if(mqtt_rxbuf[0] == parket_subAck[0] && mqtt_rxbuf[1] == parket_subAck[1]) //订阅成功 - { - return 0; - } - TrySub_time--; - } - return 1; -} - - -/******************************************************************************* -* 函 数 名: MQTT_UnSubscribeTopic -* 功能描述: MQTT取消订阅单个主题 -* 形 参: topic_name:要取消订阅的主题 -* 返 回 值: 0表示订阅成功,1表示订阅失败 -*******************************************************************************/ -int MQTT_UnSubscribeTopic(uint8_t *topic_name) -{ - uint8_t TryUnSub_time = 10; //尝试取消订阅次数 - - Aliyun_mqtt.Fixed_len = 1; //UNSUBSCRIBE报文,固定报头长度暂定为1 - Aliyun_mqtt.Variable_len = 2; //UNSUBSCRIBE报文,可变报头长度=2,2为字节报文标识符 - Aliyun_mqtt.Payload_len = strlen(topic_name) + 2; //每个需要取消的订阅topic除了本身的字符串长度,还包含表示topic字符串长度的2字节 - Aliyun_mqtt.Remaining_len = Aliyun_mqtt.Variable_len + Aliyun_mqtt.Payload_len; //计算剩余长度=可变报头长度+负载长度 - memset(Aliyun_mqtt.Pack_buff,0,sizeof(Aliyun_mqtt.Pack_buff)); - - Aliyun_mqtt.Pack_buff[0]=0xA0; //UNSUBSCRIBE报文,固定报头第1个字节0xA0 - do{ - if((Aliyun_mqtt.Remaining_len/128) == 0) - { - Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len] = Aliyun_mqtt.Remaining_len; - } - else - { - Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len] = (Aliyun_mqtt.Remaining_len%128)|0x80; - } - Aliyun_mqtt.Fixed_len++; - Aliyun_mqtt.Remaining_len = Aliyun_mqtt.Remaining_len/128; - }while(Aliyun_mqtt.Remaining_len); - - Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+0] = Aliyun_mqtt.MessageID/256; //报文标识符高字节 - Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+1] = Aliyun_mqtt.MessageID%256; //报文标识符低字节 - Aliyun_mqtt.MessageID++; //每用一次MessageID加1 - - Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+2] = strlen(topic_name)/256; //主题长度高字节 - Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+3] = strlen(topic_name)%256; //主题长度低字节 - memcpy(&Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+4],topic_name,strlen(topic_name)); //复制主题字串 - - while(TryUnSub_time > 0) - { - memset(mqtt_rxbuf,0,sizeof(mqtt_rxbuf)); - MQTT_Send(Aliyun_mqtt.Pack_buff,Aliyun_mqtt.Fixed_len + Aliyun_mqtt.Variable_len + Aliyun_mqtt.Payload_len); - MdelayKTask(50); - MQTT_Recv(mqtt_rxbuf, 4); - if(mqtt_rxbuf[0] == parket_unsubAck[0] && mqtt_rxbuf[1] == parket_unsubAck[1]) //取消订阅成功 - { - return 0; - } - TryUnSub_time--; - } - return 1; -} - - -/******************************************************************************* -* 函 数 名: MQTT_PublishDataQs0 -* 功能描述: 向服务器发送等级0的Publish报文 -* 形 参: topic_name:主题名称 - data:数据缓存 - data_len:数据长度 -* 返 回 值: 发布Qs=0的消息服务器不返回确认消息 -*******************************************************************************/ -void MQTT_PublishDataQs0(uint8_t *topic_name,uint8_t *data, uint16_t data_len) -{ - Aliyun_mqtt.Fixed_len = 1; //PUBLISH等级0报文固定报头长度暂定为1 - Aliyun_mqtt.Variable_len = 2 + strlen(topic_name); //PUBLISH等级0报文,可变报头长度=2字节topic长度标识字节+topic字符串的长度 - Aliyun_mqtt.Payload_len = data_len; //PUBLISH等级0报文,负载数据长度=data_len - Aliyun_mqtt.Remaining_len = Aliyun_mqtt.Variable_len + Aliyun_mqtt.Payload_len; //计算剩余长度=可变报头长度+负载长度 - memset(Aliyun_mqtt.Pack_buff,0,sizeof(Aliyun_mqtt.Pack_buff)); - - Aliyun_mqtt.Pack_buff[0]=0x30; //PUBLISH等级0报文固定报头第1个字节0x30 - do{ - if((Aliyun_mqtt.Remaining_len/128) == 0) - { - Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len] = Aliyun_mqtt.Remaining_len; - } - else - { - Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len] = (Aliyun_mqtt.Remaining_len%128)|0x80; - } - Aliyun_mqtt.Fixed_len++; - Aliyun_mqtt.Remaining_len = Aliyun_mqtt.Remaining_len/128; - }while(Aliyun_mqtt.Remaining_len); - - Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+0]=strlen(topic_name)/256; //主题长度高字节 - Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+1]=strlen(topic_name)%256; //主题长度低字节 - memcpy(&Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+2],topic_name,strlen(topic_name)); //复制主题字串 - memcpy(&Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+2+strlen(topic_name)],data,data_len); //复制data数据 - - MQTT_Send(Aliyun_mqtt.Pack_buff, Aliyun_mqtt.Fixed_len + Aliyun_mqtt.Variable_len + Aliyun_mqtt.Payload_len); -} - - -/******************************************************************************* -* 函 数 名: MQTT_PublishDataQs1 -* 功能描述: 向服务器发送等级1的Publish报文 -* 形 参: topic_name:主题名称 - data:数据缓存 - data_len:数据长度 -* 返 回 值: 无 -*******************************************************************************/ -void MQTT_PublishDataQs1(uint8_t *topic_name,uint8_t *data, uint16_t data_len) -{ - Aliyun_mqtt.Fixed_len = 1; //PUBLISH等级1报文固定报头长度暂定为1 - Aliyun_mqtt.Variable_len = 2 + 2 + strlen(topic_name); //PUBLISH等级1报文,可变报头长度=2字节消息标识符+2字节topic长度标识字节+topic字符串的长度 - Aliyun_mqtt.Payload_len = data_len; //PUBLISH等级1报文,负载数据长度=data_len - Aliyun_mqtt.Remaining_len = Aliyun_mqtt.Variable_len + Aliyun_mqtt.Payload_len; //计算剩余长度=可变报头长度+负载长度 - - Aliyun_mqtt.Pack_buff[0] = 0x32; //等级1的Publish报文固定报头第1个字节,0x32 - do{ - if(Aliyun_mqtt.Remaining_len/128 == 0) - { - Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len] = Aliyun_mqtt.Remaining_len; - } - else - { - Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len] = (Aliyun_mqtt.Remaining_len%128)|0x80; - } - Aliyun_mqtt.Fixed_len++; - Aliyun_mqtt.Remaining_len = Aliyun_mqtt.Remaining_len/128; - }while(Aliyun_mqtt.Remaining_len); - - Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+0] = strlen(topic_name)/256; //主题长度高字节 - Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+1] = strlen(topic_name)%256; //主题长度低字节 - memcpy(&Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+2],topic_name,strlen(topic_name)); //复制主题字串 - - Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+2+strlen(topic_name)] = Aliyun_mqtt.MessageID/256; //报文标识符高字节 - Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+3+strlen(topic_name)] = Aliyun_mqtt.MessageID%256; //报文标识符低字节 - Aliyun_mqtt.MessageID++; //每用一次MessageID加1 - - memcpy(&Aliyun_mqtt.Pack_buff[Aliyun_mqtt.Fixed_len+4+strlen(topic_name)],data,strlen(data)); //复制data数据 - - MQTT_Send(Aliyun_mqtt.Pack_buff,Aliyun_mqtt.Fixed_len + Aliyun_mqtt.Variable_len + Aliyun_mqtt.Payload_len); -} - - -/******************************************************************************* -* 函 数 名: MQTT_SendHeart -* 功能描述: 发送心跳保活包 -* 形 参: 无 -* 返 回 值: 0表示发送成功,其他值表示发送失败 -*******************************************************************************/ -int MQTT_SendHeart(void) -{ - uint8_t TrySentHeart_time = 10; //尝试发送心跳保活次数 - while(TrySentHeart_time > 0) - { - memset(mqtt_rxbuf,0,sizeof(mqtt_rxbuf)); - MQTT_Send(parket_heart,sizeof(parket_heart)); - MdelayKTask(50); - MQTT_Recv(mqtt_rxbuf, 2); - if(mqtt_rxbuf[0] == 0xD0 && mqtt_rxbuf[1] == 0x00) - { - return 0; - } - TrySentHeart_time--; - } - return 1; -} - - -/******************************************************************************* -* 函 数 名: MQTT_DealPublishData -* 功能描述: 处理服务器发来的等级0的推送数据,附带topic信息 -* 形 参: redata:接收的数据,data_len:要处理的数据长度 -* 返 回 值: 无 -*******************************************************************************/ -void MQTT_DealPublishData(uint8_t *data, uint16_t data_len) -{ - uint8_t i; - uint16_t cmdpos,cmdlen; - - for(i = 1;i < 5;i++) - { - if((data[i] & 0x80) == 0) - break; - } - - cmdpos = 1+i+2; - cmdlen = data_len-(1+i+2); - - if(data_len <= CMD_SIZE) - { - memset(Aliyun_mqtt.cmdbuff, 0, CMD_SIZE); - memcpy(Aliyun_mqtt.cmdbuff, &data[cmdpos], cmdlen); - } -} diff --git a/Ubiquitous/XiZi_IIoT/tool/mqtt/platform_mqtt.c b/Ubiquitous/XiZi_IIoT/tool/mqtt/platform_mqtt.c new file mode 100644 index 000000000..6513f3c6e --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/tool/mqtt/platform_mqtt.c @@ -0,0 +1,432 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file: platform_mqtt.c +* @brief: platform_mqtt.c file +* @version: 1.0 +* @author: AIIT XUOS Lab +* @date: 2023/6/14 +* +*/ + +#include +#include +#include +#include "shell.h" +#include "xsconfig.h" +#include +#include "platform_mqtt.h" + +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_subAck[] = {0x90,0x03,0x00,0x0A,0x01}; //订阅成功服务器回应报文 +static const uint8_t parket_unsubAck[] = {0xB0,0x02,0x00,0x0A}; //取消订阅成功服务器回应报文 +static uint8_t mqtt_rxbuf[16]; + + +/******************************************************************************* +* 函 数 名: AdapterNetActive +* 功能描述: 使能设备的网络模块连接,连接TCP服务器并进入透传模式,当前使用4G方式 +* 形 参: 无 +* 返 回 值: 0表示成功,其他值表示失败 +*******************************************************************************/ +int AdapterNetActive(void) +{ + int ret = 0; + uint32_t baud_rate = BAUD_RATE_115200; + adapter = AdapterDeviceFindByName(ADAPTER_4G_NAME); + adapter->socket.socket_id = 0; + + ret = AdapterDeviceOpen(adapter); + if (ret < 0) + { + goto out; + } + + ret = AdapterDeviceControl(adapter, OPE_INT, &baud_rate); + if (ret < 0) + { + goto out; + } + + ret = AdapterDeviceConnect(adapter, CLIENT, SERVERIP, SERVERPORT, IPV4); + if (ret < 0) + { + goto out; + } + +out: + if (ret < 0) + { + AdapterDeviceClose(adapter); + } + + return ret; +} + + + +/******************************************************************************* +* 函 数 名: MQTT_Send +* 功能描述: MQTT client数据发送函数 +* 形 参: buf:要发送的数据,buflen:要发送的数据长度 +* 返 回 值: 发送成功为0,发送失败为-1 +*******************************************************************************/ +int MQTT_Send(const uint8_t* buf, int buflen) +{ + return AdapterDeviceSend(adapter, buf, buflen) ; +} + + +/******************************************************************************* +* 函 数 名: MQTT_Recv +* 功能描述: MQTT client数据接收函数 +* 形 参: buf:数据缓冲区,buflen:期望接收的数据长度 +* 返 回 值: 实际接收到的数据长度,接收失败为-1 +*******************************************************************************/ +int MQTT_Recv(uint8_t* buf, int buflen) +{ + return AdapterDeviceRecv(adapter, buf, buflen) ; +} + + +/******************************************************************************* +* 函 数 名: MQTT_Connect +* 功能描述: 登录MQTT服务器 +* 形 参: 无 +* 返 回 值: 0表示成功,1表示失败 +*******************************************************************************/ +int MQTT_Connect(void) +{ + uint8_t TryConnect_time = 10; //尝试登录次数 + + Platform_mqtt.MessageID = 0; //报文标识符清零,CONNECT报文虽然不需要添加报文标识符,但是CONNECT报文是第一个发送的报文,在此清零报文标识符为后续报文做准备 + Platform_mqtt.Fixed_len = 1; //CONNECT报文固定报头长度暂定为1 + Platform_mqtt.Variable_len = 10; //CONNECT报文可变报头长度为10 + Platform_mqtt.Payload_len = (2+strlen(CLIENTID)) + (2+strlen(USERNAME)) + (2+strlen(PASSWORD)); //CONNECT报文中负载长度 + Platform_mqtt.Remaining_len = Platform_mqtt.Variable_len + Platform_mqtt.Payload_len; //剩余长度=可变报头长度+负载长度 + memset(Platform_mqtt.Pack_buff,0,sizeof(Platform_mqtt.Pack_buff)); + + Platform_mqtt.Pack_buff[0] = 0x10; //CONNECT报文 固定报头第1个字节0x10 + do{ + if((Platform_mqtt.Remaining_len/128) == 0) + { + Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len] = Platform_mqtt.Remaining_len; + } + else + { + Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len] = (Platform_mqtt.Remaining_len%128)|0x80; + } + Platform_mqtt.Fixed_len++; + Platform_mqtt.Remaining_len = Platform_mqtt.Remaining_len/128; + }while(Platform_mqtt.Remaining_len); + + Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+0] = 0x00; //CONNECT报文,可变报头第1个字节:固定0x00 + Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+1] = 0x04; //CONNECT报文,可变报头第2个字节:固定0x04 + Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+2] = 0x4D; //CONNECT报文,可变报头第3个字节:固定0x4D,大写字母M + Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+3] = 0x51; //CONNECT报文,可变报头第4个字节:固定0x51,大写字母Q + Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+4] = 0x54; //CONNECT报文,可变报头第5个字节:固定0x54,大写字母T + 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个字节:保活时间高字节 + + /* CLIENT_ID */ + Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+10] = strlen(CLIENTID)/256; //客户端ID长度高字节 + Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+11] = strlen(CLIENTID)%256; //客户端ID长度低字节 + memcpy(&Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+12],CLIENTID,strlen(CLIENTID)); //复制过来客户端ID字串 + /* USER_NAME */ + Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+12+strlen(CLIENTID)] = strlen(USERNAME)/256; //用户名长度高字节 + Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+13+strlen(CLIENTID)] = strlen(USERNAME)%256; //用户名长度低字节 + memcpy(&Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+14+strlen(CLIENTID)],USERNAME,strlen(USERNAME)); //复制过来用户名字串 + /* PASSWARD */ + Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+14+strlen(CLIENTID)+strlen(USERNAME)] = strlen(PASSWORD)/256; //密码长度高字节 + Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+15+strlen(CLIENTID)+strlen(USERNAME)] = strlen(PASSWORD)%256; //密码长度低字节 + memcpy(&Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+16+strlen(CLIENTID)+strlen(USERNAME)],PASSWORD,strlen(PASSWORD)); //复制过来密码字串 + + while(TryConnect_time > 0) + { + memset(mqtt_rxbuf,0,sizeof(mqtt_rxbuf)); + MQTT_Send(Platform_mqtt.Pack_buff,Platform_mqtt.Fixed_len + Platform_mqtt.Variable_len + Platform_mqtt.Payload_len); + MdelayKTask(50); + MQTT_Recv(mqtt_rxbuf, 4); + if(mqtt_rxbuf[0] == parket_connetAck[0] && mqtt_rxbuf[1] == parket_connetAck[1]) //连接成功 + { + return 0; + } + TryConnect_time--; + } + return 1; +} + + +/******************************************************************************* +* 函 数 名: MQTT_Disconnect +* 功能描述: 断开与MQTT服务器的连接 +* 形 参: 无 +* 返 回 值: 无 +*******************************************************************************/ +void MQTT_Disconnect(void) +{ + while(MQTT_Send(parket_disconnet,sizeof(parket_disconnet)) < 0); +} + + +/******************************************************************************* +* 函 数 名: MQTT_SubscribeTopic +* 功能描述: MQTT订阅单个主题 +* 形 参: topic_name:要订阅的主题 +* 返 回 值: 0表示订阅成功,1表示订阅失败 +*******************************************************************************/ +int MQTT_SubscribeTopic(uint8_t *topic_name) +{ + uint8_t TrySub_time = 10; //尝试订阅次数 + + Platform_mqtt.Fixed_len = 1; //SUBSCRIBE报文,固定报头长度暂定为1 + Platform_mqtt.Variable_len = 2;//SUBSCRIBE报文,可变报头长度=2,2为字节报文标识符 + Platform_mqtt.Payload_len = 0; //SUBSCRIBE报文,负载数据长度暂定为0 + + Platform_mqtt.Payload_len = strlen(topic_name) + 2 + 1; //每个需要订阅的topic除了本身的字符串长度,还包含表示topic字符串长度的2字节,以及订阅等级1字节 + Platform_mqtt.Remaining_len = Platform_mqtt.Variable_len + Platform_mqtt.Payload_len; //计算剩余长度=可变报头长度+负载长度 + memset(Platform_mqtt.Pack_buff,0,sizeof(Platform_mqtt.Pack_buff)); + + Platform_mqtt.Pack_buff[0]=0x82; //SUBSCRIBE报文,固定报头第1个字节0x82 + do{ + if((Platform_mqtt.Remaining_len/128) == 0) + { + Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len] = Platform_mqtt.Remaining_len; + } + else + { + Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len] = (Platform_mqtt.Remaining_len%128)|0x80; + } + Platform_mqtt.Fixed_len++; + Platform_mqtt.Remaining_len = Platform_mqtt.Remaining_len/128; + }while(Platform_mqtt.Remaining_len); + + Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+0] = Platform_mqtt.MessageID/256; //报文标识符高字节 + Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+1] = Platform_mqtt.MessageID%256; //报文标识符低字节 + Platform_mqtt.MessageID++; //每用一次MessageID加1 + + Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+2] = strlen(topic_name)/256; //主题长度高字节 + Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+3] = strlen(topic_name)%256; //主题长度低字节 + memcpy(&Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+4],topic_name,strlen(topic_name)); //复制主题字串 + Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+4+strlen(topic_name)] = 0; //QOS等级设置为0 + + while(TrySub_time > 0) + { + memset(mqtt_rxbuf,0,sizeof(mqtt_rxbuf)); + MQTT_Send(Platform_mqtt.Pack_buff,Platform_mqtt.Fixed_len + Platform_mqtt.Variable_len + Platform_mqtt.Payload_len); + MdelayKTask(50); + MQTT_Recv(mqtt_rxbuf, 5); + if(mqtt_rxbuf[0] == parket_subAck[0] && mqtt_rxbuf[1] == parket_subAck[1]) //订阅成功 + { + return 0; + } + TrySub_time--; + } + return 1; +} + + +/******************************************************************************* +* 函 数 名: MQTT_UnSubscribeTopic +* 功能描述: MQTT取消订阅单个主题 +* 形 参: topic_name:要取消订阅的主题 +* 返 回 值: 0表示订阅成功,1表示订阅失败 +*******************************************************************************/ +int MQTT_UnSubscribeTopic(uint8_t *topic_name) +{ + uint8_t TryUnSub_time = 10; //尝试取消订阅次数 + + Platform_mqtt.Fixed_len = 1; //UNSUBSCRIBE报文,固定报头长度暂定为1 + Platform_mqtt.Variable_len = 2; //UNSUBSCRIBE报文,可变报头长度=2,2为字节报文标识符 + Platform_mqtt.Payload_len = strlen(topic_name) + 2; //每个需要取消的订阅topic除了本身的字符串长度,还包含表示topic字符串长度的2字节 + Platform_mqtt.Remaining_len = Platform_mqtt.Variable_len + Platform_mqtt.Payload_len; //计算剩余长度=可变报头长度+负载长度 + memset(Platform_mqtt.Pack_buff,0,sizeof(Platform_mqtt.Pack_buff)); + + Platform_mqtt.Pack_buff[0]=0xA0; //UNSUBSCRIBE报文,固定报头第1个字节0xA0 + do{ + if((Platform_mqtt.Remaining_len/128) == 0) + { + Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len] = Platform_mqtt.Remaining_len; + } + else + { + Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len] = (Platform_mqtt.Remaining_len%128)|0x80; + } + Platform_mqtt.Fixed_len++; + Platform_mqtt.Remaining_len = Platform_mqtt.Remaining_len/128; + }while(Platform_mqtt.Remaining_len); + + Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+0] = Platform_mqtt.MessageID/256; //报文标识符高字节 + Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+1] = Platform_mqtt.MessageID%256; //报文标识符低字节 + Platform_mqtt.MessageID++; //每用一次MessageID加1 + + Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+2] = strlen(topic_name)/256; //主题长度高字节 + Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+3] = strlen(topic_name)%256; //主题长度低字节 + memcpy(&Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+4],topic_name,strlen(topic_name)); //复制主题字串 + + while(TryUnSub_time > 0) + { + memset(mqtt_rxbuf,0,sizeof(mqtt_rxbuf)); + MQTT_Send(Platform_mqtt.Pack_buff,Platform_mqtt.Fixed_len + Platform_mqtt.Variable_len + Platform_mqtt.Payload_len); + MdelayKTask(50); + MQTT_Recv(mqtt_rxbuf, 4); + if(mqtt_rxbuf[0] == parket_unsubAck[0] && mqtt_rxbuf[1] == parket_unsubAck[1]) //取消订阅成功 + { + return 0; + } + TryUnSub_time--; + } + return 1; +} + + +/******************************************************************************* +* 函 数 名: MQTT_PublishDataQs0 +* 功能描述: 向服务器发送等级0的Publish报文 +* 形 参: topic_name:主题名称 + data:数据缓存 + data_len:数据长度 +* 返 回 值: 发布Qs=0的消息服务器不返回确认消息 +*******************************************************************************/ +void MQTT_PublishDataQs0(uint8_t *topic_name,uint8_t *data, uint16_t data_len) +{ + Platform_mqtt.Fixed_len = 1; //PUBLISH等级0报文固定报头长度暂定为1 + Platform_mqtt.Variable_len = 2 + strlen(topic_name); //PUBLISH等级0报文,可变报头长度=2字节topic长度标识字节+topic字符串的长度 + Platform_mqtt.Payload_len = data_len; //PUBLISH等级0报文,负载数据长度=data_len + Platform_mqtt.Remaining_len = Platform_mqtt.Variable_len + Platform_mqtt.Payload_len; //计算剩余长度=可变报头长度+负载长度 + memset(Platform_mqtt.Pack_buff,0,sizeof(Platform_mqtt.Pack_buff)); + + Platform_mqtt.Pack_buff[0]=0x30; //PUBLISH等级0报文固定报头第1个字节0x30 + do{ + if((Platform_mqtt.Remaining_len/128) == 0) + { + Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len] = Platform_mqtt.Remaining_len; + } + else + { + Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len] = (Platform_mqtt.Remaining_len%128)|0x80; + } + Platform_mqtt.Fixed_len++; + Platform_mqtt.Remaining_len = Platform_mqtt.Remaining_len/128; + }while(Platform_mqtt.Remaining_len); + + Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+0]=strlen(topic_name)/256; //主题长度高字节 + Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+1]=strlen(topic_name)%256; //主题长度低字节 + memcpy(&Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+2],topic_name,strlen(topic_name)); //复制主题字串 + memcpy(&Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+2+strlen(topic_name)],data,data_len); //复制data数据 + + MQTT_Send(Platform_mqtt.Pack_buff, Platform_mqtt.Fixed_len + Platform_mqtt.Variable_len + Platform_mqtt.Payload_len); +} + + +/******************************************************************************* +* 函 数 名: MQTT_PublishDataQs1 +* 功能描述: 向服务器发送等级1的Publish报文 +* 形 参: topic_name:主题名称 + data:数据缓存 + data_len:数据长度 +* 返 回 值: 无 +*******************************************************************************/ +void MQTT_PublishDataQs1(uint8_t *topic_name,uint8_t *data, uint16_t data_len) +{ + Platform_mqtt.Fixed_len = 1; //PUBLISH等级1报文固定报头长度暂定为1 + Platform_mqtt.Variable_len = 2 + 2 + strlen(topic_name); //PUBLISH等级1报文,可变报头长度=2字节消息标识符+2字节topic长度标识字节+topic字符串的长度 + Platform_mqtt.Payload_len = data_len; //PUBLISH等级1报文,负载数据长度=data_len + Platform_mqtt.Remaining_len = Platform_mqtt.Variable_len + Platform_mqtt.Payload_len; //计算剩余长度=可变报头长度+负载长度 + + Platform_mqtt.Pack_buff[0] = 0x32; //等级1的Publish报文固定报头第1个字节,0x32 + do{ + if(Platform_mqtt.Remaining_len/128 == 0) + { + Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len] = Platform_mqtt.Remaining_len; + } + else + { + Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len] = (Platform_mqtt.Remaining_len%128)|0x80; + } + Platform_mqtt.Fixed_len++; + Platform_mqtt.Remaining_len = Platform_mqtt.Remaining_len/128; + }while(Platform_mqtt.Remaining_len); + + Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+0] = strlen(topic_name)/256; //主题长度高字节 + Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+1] = strlen(topic_name)%256; //主题长度低字节 + memcpy(&Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+2],topic_name,strlen(topic_name)); //复制主题字串 + + Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+2+strlen(topic_name)] = Platform_mqtt.MessageID/256; //报文标识符高字节 + Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+3+strlen(topic_name)] = Platform_mqtt.MessageID%256; //报文标识符低字节 + Platform_mqtt.MessageID++; //每用一次MessageID加1 + + memcpy(&Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+4+strlen(topic_name)],data,strlen(data)); //复制data数据 + + MQTT_Send(Platform_mqtt.Pack_buff,Platform_mqtt.Fixed_len + Platform_mqtt.Variable_len + Platform_mqtt.Payload_len); +} + + +/******************************************************************************* +* 函 数 名: MQTT_SendHeart +* 功能描述: 发送心跳保活包 +* 形 参: 无 +* 返 回 值: 0表示发送成功,其他值表示发送失败 +*******************************************************************************/ +int MQTT_SendHeart(void) +{ + uint8_t TrySentHeart_time = 10; //尝试发送心跳保活次数 + while(TrySentHeart_time > 0) + { + memset(mqtt_rxbuf,0,sizeof(mqtt_rxbuf)); + MQTT_Send(parket_heart,sizeof(parket_heart)); + MdelayKTask(50); + MQTT_Recv(mqtt_rxbuf, 2); + if(mqtt_rxbuf[0] == 0xD0 && mqtt_rxbuf[1] == 0x00) + { + return 0; + } + TrySentHeart_time--; + } + return 1; +} + + +/******************************************************************************* +* 函 数 名: MQTT_DealPublishData +* 功能描述: 处理服务器发来的等级0的推送数据,附带topic信息 +* 形 参: redata:接收的数据,data_len:要处理的数据长度 +* 返 回 值: 无 +*******************************************************************************/ +void MQTT_DealPublishData(uint8_t *data, uint16_t data_len) +{ + uint8_t i; + uint16_t cmdpos,cmdlen; + + for(i = 1;i < 5;i++) + { + if((data[i] & 0x80) == 0) + break; + } + + cmdpos = 1+i+2; + cmdlen = data_len-(1+i+2); + + if(data_len <= CMD_SIZE) + { + memset(Platform_mqtt.cmdbuff, 0, CMD_SIZE); + memcpy(Platform_mqtt.cmdbuff, &data[cmdpos], cmdlen); + } +} diff --git a/Ubiquitous/XiZi_IIoT/tool/mqtt/aliyun_mqtt.h b/Ubiquitous/XiZi_IIoT/tool/mqtt/platform_mqtt.h similarity index 89% rename from Ubiquitous/XiZi_IIoT/tool/mqtt/aliyun_mqtt.h rename to Ubiquitous/XiZi_IIoT/tool/mqtt/platform_mqtt.h index f44517c90..eec68ec09 100644 --- a/Ubiquitous/XiZi_IIoT/tool/mqtt/aliyun_mqtt.h +++ b/Ubiquitous/XiZi_IIoT/tool/mqtt/platform_mqtt.h @@ -11,16 +11,16 @@ */ /** -* @file: aliyun_mqtt.h -* @brief: connect aliyun mqtt +* @file: platform_mqtt.h +* @brief: platform_mqtt.h file * @version: 1.0 * @author: AIIT XUOS Lab * @date: 2023/6/14 * */ -#ifndef _ALIYUN_MQTT_H_ -#define _ALIYUN_MQTT_H_ +#ifndef _PLATFORM_MQTT_H_ +#define _PLATFORM_MQTT_H_ #include @@ -31,7 +31,7 @@ #define SERVERPORT "1883" #define PACK_SIZE 512 //存放报文数据缓冲区大小 -#define CMD_SIZE 2048 //保存推送的PUBLISH报文中的数据缓冲区大小 +#define CMD_SIZE 3072 //保存推送的PUBLISH报文中的数据缓冲区大小 typedef struct{ uint8_t Pack_buff[PACK_SIZE]; //存放发送报文数据缓冲区 @@ -43,7 +43,7 @@ typedef struct{ uint8_t cmdbuff[CMD_SIZE]; //保存推送的PUBLISH报文中的数据缓冲区 }MQTT_TCB; -extern MQTT_TCB Aliyun_mqtt; //外部变量声明 +extern MQTT_TCB Platform_mqtt; //外部变量声明 int AdapterNetActive(void); int MQTT_Send(const uint8_t* buf, int buflen); From 3c179e78796182d3b59d17daab8230b227467239 Mon Sep 17 00:00:00 2001 From: wgzAIIT <820906721@qq.com> Date: Mon, 26 Jun 2023 16:50:29 +0800 Subject: [PATCH 19/23] =?UTF-8?q?1=E3=80=81add=20MQTT=20connection=20param?= =?UTF-8?q?eter=20configuration=20by=20Kconfig=202=E3=80=81Send=20a=20hear?= =?UTF-8?q?tbeat=20packet=20every=201=20minute=20during=20idle=20time=20to?= =?UTF-8?q?=20keep=20alive?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../XiZi_IIoT/tool/bootloader/ota/ota.c | 110 ++++++++++++------ Ubiquitous/XiZi_IIoT/tool/mqtt/Kconfig | 33 ++++++ .../XiZi_IIoT/tool/mqtt/platform_mqtt.c | 10 +- .../XiZi_IIoT/tool/mqtt/platform_mqtt.h | 12 +- 4 files changed, 116 insertions(+), 49 deletions(-) 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]; //存放发送报文数据缓冲区 From b9e5e97741fb53884d41c321c6d99bd09fd4d2b0 Mon Sep 17 00:00:00 2001 From: wgzAIIT <820906721@qq.com> Date: Thu, 29 Jun 2023 15:48:35 +0800 Subject: [PATCH 20/23] The password for logging in to the mqtt server is generated using a function --- .../XiZi_IIoT/tool/bootloader/ota/ota.c | 24 +- Ubiquitous/XiZi_IIoT/tool/mqtt/Kconfig | 12 - Ubiquitous/XiZi_IIoT/tool/mqtt/Makefile | 2 +- .../XiZi_IIoT/tool/mqtt/platform_mqtt.c | 28 +- .../XiZi_IIoT/tool/mqtt/platform_mqtt.h | 23 +- .../XiZi_IIoT/tool/mqtt/utils_hmacsha1.c | 399 ++++++++++++++++++ .../XiZi_IIoT/tool/mqtt/utils_hmacsha1.h | 41 ++ 7 files changed, 495 insertions(+), 34 deletions(-) create mode 100644 Ubiquitous/XiZi_IIoT/tool/mqtt/utils_hmacsha1.c create mode 100644 Ubiquitous/XiZi_IIoT/tool/mqtt/utils_hmacsha1.h diff --git a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c index 9cc091aa8..3aedba32d 100644 --- a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c +++ b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c @@ -796,6 +796,7 @@ static void app_ota_by_platform(void* parameter) { int datalen; int ret = 0; + int freecnt = 0; ota_info_t ota_info; uint32_t heart_time = 0; uint32_t flashdestination = DOWN_FLAH_ADDRESS; @@ -816,13 +817,23 @@ reconnect: KPrintf("Log in to the cloud platform and subscribe to the topic successfully.\n"); PropertyVersion(); } + else + { + KPrintf("Log in to the cloud platform failed, retry!\n"); + goto reconnect; + } while(1) { memset(MqttRxbuf,0,sizeof(MqttRxbuf)); datalen = MQTT_Recv(MqttRxbuf, sizeof(MqttRxbuf)); - if(MqttRxbuf[0] == 0x30) + if(datalen <= 0) { + freecnt++; + } + else if(MqttRxbuf[0] == 0x30) + { + freecnt = 0; MQTT_DealPublishData(MqttRxbuf, datalen); ptr = strstr((char *)Platform_mqtt.cmdbuff,"{\"code\":\"1000\""); if(ptr != NULL) @@ -896,16 +907,23 @@ reconnect: } } + else + { + freecnt = 0; + continue; + } - if((datalen <= 0) && (CalculateTimeMsFromTick(CurrentTicksGain()) - heart_time >= HEART_TIME)) //空闲状态下每隔一段时间发送需要发送心跳包保活 + if((freecnt >= 10) && (CalculateTimeMsFromTick(CurrentTicksGain()) - heart_time >= HEART_TIME)) //连续10次未收到数据默认为为空闲状态,需每隔一段时间发送需要发送心跳包保活 { heart_time = CalculateTimeMsFromTick(CurrentTicksGain()); - KPrintf("Send heartbeat packet!\n"); if(MQTT_SendHeart() != 0) //发送心跳包失败可能连接断开,需要重连 { + KPrintf("The connection has been disconnected, reconnecting!\n"); + freecnt = 0; heart_time = 0; goto reconnect; } + KPrintf("Send heartbeat packet successful!\n"); } } diff --git a/Ubiquitous/XiZi_IIoT/tool/mqtt/Kconfig b/Ubiquitous/XiZi_IIoT/tool/mqtt/Kconfig index 4024bfdb7..609b0dc78 100644 --- a/Ubiquitous/XiZi_IIoT/tool/mqtt/Kconfig +++ b/Ubiquitous/XiZi_IIoT/tool/mqtt/Kconfig @@ -19,18 +19,6 @@ menu "MQTT function" 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." diff --git a/Ubiquitous/XiZi_IIoT/tool/mqtt/Makefile b/Ubiquitous/XiZi_IIoT/tool/mqtt/Makefile index 93fa24fb1..b924f47d1 100644 --- a/Ubiquitous/XiZi_IIoT/tool/mqtt/Makefile +++ b/Ubiquitous/XiZi_IIoT/tool/mqtt/Makefile @@ -1,3 +1,3 @@ -SRC_FILES := platform_mqtt.c +SRC_FILES := platform_mqtt.c utils_hmacsha1.c include $(KERNEL_ROOT)/compiler.mk \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/tool/mqtt/platform_mqtt.c b/Ubiquitous/XiZi_IIoT/tool/mqtt/platform_mqtt.c index ec051655e..b26e2aa61 100644 --- a/Ubiquitous/XiZi_IIoT/tool/mqtt/platform_mqtt.c +++ b/Ubiquitous/XiZi_IIoT/tool/mqtt/platform_mqtt.c @@ -112,11 +112,19 @@ int MQTT_Recv(uint8_t* buf, int buflen) int MQTT_Connect(void) { uint8_t TryConnect_time = 10; //尝试登录次数 + uint8_t passwdtemp[PASSWARD_SIZE]; + + memset(&Platform_mqtt,0,sizeof(Platform_mqtt)); + sprintf(Platform_mqtt.ClientID,"%s|securemode=3,signmethod=hmacsha1|",CLIENT_DEVICENAME); //构建客户端ID并存入缓冲区 + sprintf(Platform_mqtt.Username,"%s&%s",CLIENT_DEVICENAME,PLATFORM_PRODUCTKEY); //构建用户名并存入缓冲区 + memset(passwdtemp,0,sizeof(passwdtemp)); + sprintf(passwdtemp,"clientId%sdeviceName%sproductKey%s",CLIENT_DEVICENAME,CLIENT_DEVICENAME,PLATFORM_PRODUCTKEY); //构建加密时的明文 + utils_hmac_sha1(passwdtemp,strlen(passwdtemp),Platform_mqtt.Passward,(char *)CLIENT_DEVICESECRET,strlen(CLIENT_DEVICESECRET)); //以DeviceSecret为秘钥对temp中的明文进行hmacsha1加密即为密码 Platform_mqtt.MessageID = 0; //报文标识符清零,CONNECT报文虽然不需要添加报文标识符,但是CONNECT报文是第一个发送的报文,在此清零报文标识符为后续报文做准备 Platform_mqtt.Fixed_len = 1; //CONNECT报文固定报头长度暂定为1 Platform_mqtt.Variable_len = 10; //CONNECT报文可变报头长度为10 - Platform_mqtt.Payload_len = (2+strlen(CLIENTID)) + (2+strlen(USERNAME)) + (2+strlen(PASSWORD)); //CONNECT报文中负载长度 + Platform_mqtt.Payload_len = (2+strlen(Platform_mqtt.ClientID)) + (2+strlen(Platform_mqtt.Username)) + (2+strlen(Platform_mqtt.Passward)); //CONNECT报文中负载长度 Platform_mqtt.Remaining_len = Platform_mqtt.Variable_len + Platform_mqtt.Payload_len; //剩余长度=可变报头长度+负载长度 memset(Platform_mqtt.Pack_buff,0,sizeof(Platform_mqtt.Pack_buff)); @@ -146,17 +154,17 @@ int MQTT_Connect(void) 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长度高字节 - Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+11] = strlen(CLIENTID)%256; //客户端ID长度低字节 - memcpy(&Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+12],CLIENTID,strlen(CLIENTID)); //复制过来客户端ID字串 + Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+10] = strlen(Platform_mqtt.ClientID)/256; //客户端ID长度高字节 + Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+11] = strlen(Platform_mqtt.ClientID)%256; //客户端ID长度低字节 + memcpy(&Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+12],Platform_mqtt.ClientID,strlen(Platform_mqtt.ClientID)); //复制过来客户端ID字串 /* USER_NAME */ - Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+12+strlen(CLIENTID)] = strlen(USERNAME)/256; //用户名长度高字节 - Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+13+strlen(CLIENTID)] = strlen(USERNAME)%256; //用户名长度低字节 - memcpy(&Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+14+strlen(CLIENTID)],USERNAME,strlen(USERNAME)); //复制过来用户名字串 + Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+12+strlen(Platform_mqtt.ClientID)] = strlen(Platform_mqtt.Username)/256; //用户名长度高字节 + Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+13+strlen(Platform_mqtt.ClientID)] = strlen(Platform_mqtt.Username)%256; //用户名长度低字节 + memcpy(&Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+14+strlen(Platform_mqtt.ClientID)],Platform_mqtt.Username,strlen(Platform_mqtt.Username)); //复制过来用户名字串 /* PASSWARD */ - Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+14+strlen(CLIENTID)+strlen(USERNAME)] = strlen(PASSWORD)/256; //密码长度高字节 - Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+15+strlen(CLIENTID)+strlen(USERNAME)] = strlen(PASSWORD)%256; //密码长度低字节 - memcpy(&Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+16+strlen(CLIENTID)+strlen(USERNAME)],PASSWORD,strlen(PASSWORD)); //复制过来密码字串 + Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+14+strlen(Platform_mqtt.ClientID)+strlen(Platform_mqtt.Username)] = strlen(Platform_mqtt.Passward)/256; //密码长度高字节 + Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+15+strlen(Platform_mqtt.ClientID)+strlen(Platform_mqtt.Username)] = strlen(Platform_mqtt.Passward)%256; //密码长度低字节 + memcpy(&Platform_mqtt.Pack_buff[Platform_mqtt.Fixed_len+16+strlen(Platform_mqtt.ClientID)+strlen(Platform_mqtt.Username)],Platform_mqtt.Passward,strlen(Platform_mqtt.Passward)); //复制过来密码字串 while(TryConnect_time > 0) { diff --git a/Ubiquitous/XiZi_IIoT/tool/mqtt/platform_mqtt.h b/Ubiquitous/XiZi_IIoT/tool/mqtt/platform_mqtt.h index f6ec30783..a7331ffed 100644 --- a/Ubiquitous/XiZi_IIoT/tool/mqtt/platform_mqtt.h +++ b/Ubiquitous/XiZi_IIoT/tool/mqtt/platform_mqtt.h @@ -23,20 +23,27 @@ #define _PLATFORM_MQTT_H_ #include +#include "utils_hmacsha1.h" #define KEEPALIVE_TIME 300 //保活时间(单位s),300s -#define HEART_TIME 60000 //空闲时发送心跳包的时间间隔(单位ms),60s +#define HEART_TIME 120000 //空闲时发送心跳包的时间间隔(单位ms),120s #define PACK_SIZE 512 //存放报文数据缓冲区大小 #define CMD_SIZE 3072 //保存推送的PUBLISH报文中的数据缓冲区大小 +#define CLIENTID_SIZE 64 //存放客户端ID的缓冲区大小 +#define USERNAME_SIZE 64 //存放用户名的缓冲区大小 +#define PASSWARD_SIZE 64 //存放密码的缓冲区大小 typedef struct{ - uint8_t Pack_buff[PACK_SIZE]; //存放发送报文数据缓冲区 - uint16_t MessageID; //记录报文标识符 - uint16_t Fixed_len; //固定报头长度 - uint16_t Variable_len; //可变报头长度 - uint16_t Payload_len; //有效负荷长度 - uint16_t Remaining_len; //保存报文剩余长度字节 - uint8_t cmdbuff[CMD_SIZE]; //保存推送的PUBLISH报文中的数据缓冲区 + uint8_t ClientID[CLIENTID_SIZE]; //存放客户端ID的缓冲区 + uint8_t Username[USERNAME_SIZE]; //存放用户名的缓冲区 + uint8_t Passward[PASSWARD_SIZE]; //存放密码的缓冲区 + uint8_t Pack_buff[PACK_SIZE]; //存放发送报文数据缓冲区 + uint16_t MessageID; //记录报文标识符 + uint16_t Fixed_len; //固定报头长度 + uint16_t Variable_len; //可变报头长度 + uint16_t Payload_len; //有效负荷长度 + uint16_t Remaining_len; //保存报文剩余长度字节 + uint8_t cmdbuff[CMD_SIZE]; //保存推送的PUBLISH报文中的数据缓冲区 }MQTT_TCB; extern MQTT_TCB Platform_mqtt; //外部变量声明 diff --git a/Ubiquitous/XiZi_IIoT/tool/mqtt/utils_hmacsha1.c b/Ubiquitous/XiZi_IIoT/tool/mqtt/utils_hmacsha1.c new file mode 100644 index 000000000..41b63e6e0 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/tool/mqtt/utils_hmacsha1.c @@ -0,0 +1,399 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file: utils_hmacsha1.c +* @brief: utils_hmacsha1.c file +* @version: 1.0 +* @author: AIIT XUOS Lab +* @date: 2023/6/29 +* +*/ + +#include "utils_hmacsha1.h" + +#define KEY_IOPAD_SIZE 64 +#define SHA1_DIGEST_SIZE 20 + +static void utils_sha1_zeroize(void *v, size_t n); +static void utils_sha1_init(iot_sha1_context *ctx); +static void utils_sha1_free(iot_sha1_context *ctx); +static void utils_sha1_clone(iot_sha1_context *dst, const iot_sha1_context *src); +static void utils_sha1_starts(iot_sha1_context *ctx); +static void utils_sha1_process(iot_sha1_context *ctx, const unsigned char data[64]); +static void utils_sha1_update(iot_sha1_context *ctx, const unsigned char *input, size_t ilen); +static void utils_sha1_finish(iot_sha1_context *ctx, unsigned char output[20]); +static void utils_sha1(const unsigned char *input, size_t ilen, unsigned char output[20]); +static int8_t utils_hb2hex(uint8_t hb); + +const char * base64char = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +/* Implementation that should never be optimized out by the compiler */ +static void utils_sha1_zeroize(void *v, size_t n) +{ + volatile unsigned char *p = v; + while(n--) { + *p++ = 0; + } +} + +/* 32-bit integer manipulation macros (big endian) */ +#ifndef IOT_SHA1_GET_UINT32_BE +#define IOT_SHA1_GET_UINT32_BE(n,b,i) \ + { \ + (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ + | ( (uint32_t) (b)[(i) + 1] << 16 ) \ + | ( (uint32_t) (b)[(i) + 2] << 8 ) \ + | ( (uint32_t) (b)[(i) + 3] ); \ + } +#endif + +#ifndef IOT_SHA1_PUT_UINT32_BE +#define IOT_SHA1_PUT_UINT32_BE(n,b,i) \ + { \ + (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) ); \ + } +#endif + +void utils_sha1_init(iot_sha1_context *ctx) +{ + memset(ctx, 0, sizeof(iot_sha1_context)); +} + +void utils_sha1_free(iot_sha1_context *ctx) +{ + if(ctx == NULL) { + return; + } + + utils_sha1_zeroize(ctx, sizeof(iot_sha1_context)); +} + +void utils_sha1_clone(iot_sha1_context *dst, + const iot_sha1_context *src) +{ + *dst = *src; +} + +/* SHA-1 context setup */ +void utils_sha1_starts(iot_sha1_context *ctx) +{ + ctx->total[0] = 0; + ctx->total[1] = 0; + + ctx->state[0] = 0x67452301; + ctx->state[1] = 0xEFCDAB89; + ctx->state[2] = 0x98BADCFE; + ctx->state[3] = 0x10325476; + ctx->state[4] = 0xC3D2E1F0; +} + +void utils_sha1_process(iot_sha1_context *ctx, const unsigned char data[64]) +{ + uint32_t temp, W[16], A, B, C, D, E; + + IOT_SHA1_GET_UINT32_BE(W[ 0], data, 0); + IOT_SHA1_GET_UINT32_BE(W[ 1], data, 4); + IOT_SHA1_GET_UINT32_BE(W[ 2], data, 8); + IOT_SHA1_GET_UINT32_BE(W[ 3], data, 12); + IOT_SHA1_GET_UINT32_BE(W[ 4], data, 16); + IOT_SHA1_GET_UINT32_BE(W[ 5], data, 20); + IOT_SHA1_GET_UINT32_BE(W[ 6], data, 24); + IOT_SHA1_GET_UINT32_BE(W[ 7], data, 28); + IOT_SHA1_GET_UINT32_BE(W[ 8], data, 32); + IOT_SHA1_GET_UINT32_BE(W[ 9], data, 36); + IOT_SHA1_GET_UINT32_BE(W[10], data, 40); + IOT_SHA1_GET_UINT32_BE(W[11], data, 44); + IOT_SHA1_GET_UINT32_BE(W[12], data, 48); + IOT_SHA1_GET_UINT32_BE(W[13], data, 52); + IOT_SHA1_GET_UINT32_BE(W[14], data, 56); + IOT_SHA1_GET_UINT32_BE(W[15], data, 60); + +#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) + +#define R(t) \ + ( \ + temp = W[( t - 3 ) & 0x0F] ^ W[( t - 8 ) & 0x0F] ^ \ + W[( t - 14 ) & 0x0F] ^ W[ t & 0x0F], \ + ( W[t & 0x0F] = S(temp,1) ) \ + ) + +#define P(a,b,c,d,e,x) \ + { \ + e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \ + } + + A = ctx->state[0]; + B = ctx->state[1]; + C = ctx->state[2]; + D = ctx->state[3]; + E = ctx->state[4]; + +#define F(x,y,z) (z ^ (x & (y ^ z))) +#define K 0x5A827999 + + P(A, B, C, D, E, W[0]); + P(E, A, B, C, D, W[1]); + P(D, E, A, B, C, W[2]); + P(C, D, E, A, B, W[3]); + P(B, C, D, E, A, W[4]); + P(A, B, C, D, E, W[5]); + P(E, A, B, C, D, W[6]); + P(D, E, A, B, C, W[7]); + P(C, D, E, A, B, W[8]); + P(B, C, D, E, A, W[9]); + P(A, B, C, D, E, W[10]); + P(E, A, B, C, D, W[11]); + P(D, E, A, B, C, W[12]); + P(C, D, E, A, B, W[13]); + P(B, C, D, E, A, W[14]); + P(A, B, C, D, E, W[15]); + P(E, A, B, C, D, R(16)); + P(D, E, A, B, C, R(17)); + P(C, D, E, A, B, R(18)); + P(B, C, D, E, A, R(19)); + +#undef K +#undef F + +#define F(x,y,z) (x ^ y ^ z) +#define K 0x6ED9EBA1 + + P(A, B, C, D, E, R(20)); + P(E, A, B, C, D, R(21)); + P(D, E, A, B, C, R(22)); + P(C, D, E, A, B, R(23)); + P(B, C, D, E, A, R(24)); + P(A, B, C, D, E, R(25)); + P(E, A, B, C, D, R(26)); + P(D, E, A, B, C, R(27)); + P(C, D, E, A, B, R(28)); + P(B, C, D, E, A, R(29)); + P(A, B, C, D, E, R(30)); + P(E, A, B, C, D, R(31)); + P(D, E, A, B, C, R(32)); + P(C, D, E, A, B, R(33)); + P(B, C, D, E, A, R(34)); + P(A, B, C, D, E, R(35)); + P(E, A, B, C, D, R(36)); + P(D, E, A, B, C, R(37)); + P(C, D, E, A, B, R(38)); + P(B, C, D, E, A, R(39)); + +#undef K +#undef F + +#define F(x,y,z) ((x & y) | (z & (x | y))) +#define K 0x8F1BBCDC + + P(A, B, C, D, E, R(40)); + P(E, A, B, C, D, R(41)); + P(D, E, A, B, C, R(42)); + P(C, D, E, A, B, R(43)); + P(B, C, D, E, A, R(44)); + P(A, B, C, D, E, R(45)); + P(E, A, B, C, D, R(46)); + P(D, E, A, B, C, R(47)); + P(C, D, E, A, B, R(48)); + P(B, C, D, E, A, R(49)); + P(A, B, C, D, E, R(50)); + P(E, A, B, C, D, R(51)); + P(D, E, A, B, C, R(52)); + P(C, D, E, A, B, R(53)); + P(B, C, D, E, A, R(54)); + P(A, B, C, D, E, R(55)); + P(E, A, B, C, D, R(56)); + P(D, E, A, B, C, R(57)); + P(C, D, E, A, B, R(58)); + P(B, C, D, E, A, R(59)); + +#undef K +#undef F + +#define F(x,y,z) (x ^ y ^ z) +#define K 0xCA62C1D6 + + P(A, B, C, D, E, R(60)); + P(E, A, B, C, D, R(61)); + P(D, E, A, B, C, R(62)); + P(C, D, E, A, B, R(63)); + P(B, C, D, E, A, R(64)); + P(A, B, C, D, E, R(65)); + P(E, A, B, C, D, R(66)); + P(D, E, A, B, C, R(67)); + P(C, D, E, A, B, R(68)); + P(B, C, D, E, A, R(69)); + P(A, B, C, D, E, R(70)); + P(E, A, B, C, D, R(71)); + P(D, E, A, B, C, R(72)); + P(C, D, E, A, B, R(73)); + P(B, C, D, E, A, R(74)); + P(A, B, C, D, E, R(75)); + P(E, A, B, C, D, R(76)); + P(D, E, A, B, C, R(77)); + P(C, D, E, A, B, R(78)); + P(B, C, D, E, A, R(79)); + +#undef K +#undef F + + ctx->state[0] += A; + ctx->state[1] += B; + ctx->state[2] += C; + ctx->state[3] += D; + ctx->state[4] += E; +} + +/* SHA-1 process buffer */ +void utils_sha1_update(iot_sha1_context *ctx, const unsigned char *input, size_t ilen) +{ + size_t fill; + uint32_t left; + + if(ilen == 0) { + return; + } + + left = ctx->total[0] & 0x3F; + fill = 64 - left; + + ctx->total[0] += (uint32_t) ilen; + ctx->total[0] &= 0xFFFFFFFF; + + if(ctx->total[0] < (uint32_t) ilen) { + ctx->total[1]++; + } + + if(left && ilen >= fill) { + memcpy((void *)(ctx->buffer + left), input, fill); + utils_sha1_process(ctx, ctx->buffer); + input += fill; + ilen -= fill; + left = 0; + } + + while(ilen >= 64) { + utils_sha1_process(ctx, input); + input += 64; + ilen -= 64; + } + + if(ilen > 0) { + memcpy((void *)(ctx->buffer + left), input, ilen); + } +} + +static const unsigned char iot_sha1_padding[64] = { + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* SHA-1 final digest */ +void utils_sha1_finish(iot_sha1_context *ctx, unsigned char output[20]) +{ + uint32_t last, padn; + uint32_t high, low; + unsigned char msglen[8]; + + high = (ctx->total[0] >> 29) + | (ctx->total[1] << 3); + low = (ctx->total[0] << 3); + + IOT_SHA1_PUT_UINT32_BE(high, msglen, 0); + IOT_SHA1_PUT_UINT32_BE(low, msglen, 4); + + last = ctx->total[0] & 0x3F; + padn = (last < 56) ? (56 - last) : (120 - last); + + utils_sha1_update(ctx, iot_sha1_padding, padn); + utils_sha1_update(ctx, msglen, 8); + + IOT_SHA1_PUT_UINT32_BE(ctx->state[0], output, 0); + IOT_SHA1_PUT_UINT32_BE(ctx->state[1], output, 4); + IOT_SHA1_PUT_UINT32_BE(ctx->state[2], output, 8); + IOT_SHA1_PUT_UINT32_BE(ctx->state[3], output, 12); + IOT_SHA1_PUT_UINT32_BE(ctx->state[4], output, 16); +} + + +/* output = SHA-1(input buffer) */ +void utils_sha1(const unsigned char *input, size_t ilen, unsigned char output[20]) +{ + iot_sha1_context ctx; + + utils_sha1_init(&ctx); + utils_sha1_starts(&ctx); + utils_sha1_update(&ctx, input, ilen); + utils_sha1_finish(&ctx, output); + utils_sha1_free(&ctx); +} + + +inline int8_t utils_hb2hex(uint8_t hb) +{ + hb = hb & 0xF; + return (int8_t)(hb < 10 ? '0' + hb : hb - 10 + 'a'); +} + + +void utils_hmac_sha1(const char *msg, int msg_len, char *digest, const char *key, int key_len) +{ + iot_sha1_context context; + unsigned char k_ipad[KEY_IOPAD_SIZE]; /* inner padding - key XORd with ipad */ + unsigned char k_opad[KEY_IOPAD_SIZE]; /* outer padding - key XORd with opad */ + unsigned char out[SHA1_DIGEST_SIZE]; + int i; + + if((NULL == msg) || (NULL == digest) || (NULL == key)) { + return; + } + + if(key_len > KEY_IOPAD_SIZE) { + return; + } + + /* start out by storing key in pads */ + memset(k_ipad, 0, sizeof(k_ipad)); + memset(k_opad, 0, sizeof(k_opad)); + memcpy(k_ipad, key, key_len); + memcpy(k_opad, key, key_len); + + /* XOR key with ipad and opad values */ + for(i = 0; i < KEY_IOPAD_SIZE; i++) { + k_ipad[i] ^= 0x36; + k_opad[i] ^= 0x5c; + } + + /* perform inner SHA */ + utils_sha1_init(&context); /* init context for 1st pass */ + utils_sha1_starts(&context); /* setup context for 1st pass */ + utils_sha1_update(&context, k_ipad, KEY_IOPAD_SIZE); /* start with inner pad */ + utils_sha1_update(&context, (unsigned char *) msg, msg_len); /* then text of datagram */ + utils_sha1_finish(&context, out); /* finish up 1st pass */ + + /* perform outer SHA */ + utils_sha1_init(&context); /* init context for 2nd pass */ + utils_sha1_starts(&context); /* setup context for 2nd pass */ + utils_sha1_update(&context, k_opad, KEY_IOPAD_SIZE); /* start with outer pad */ + utils_sha1_update(&context, out, SHA1_DIGEST_SIZE); /* then results of 1st hash */ + utils_sha1_finish(&context, out); /* finish up 2nd pass */ + + for(i = 0; i < SHA1_DIGEST_SIZE; ++i) { + digest[i * 2] = utils_hb2hex(out[i] >> 4); + digest[i * 2 + 1] = utils_hb2hex(out[i]); + } +} \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/tool/mqtt/utils_hmacsha1.h b/Ubiquitous/XiZi_IIoT/tool/mqtt/utils_hmacsha1.h new file mode 100644 index 000000000..da56792a4 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/tool/mqtt/utils_hmacsha1.h @@ -0,0 +1,41 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file: utils_hmacsha1.h +* @brief: utils_hmacsha1.h file +* @version: 1.0 +* @author: AIIT XUOS Lab +* @date: 2023/6/29 +* +*/ + +#ifndef UTILS_HMACSHA1_H_ +#define UTILS_HMACSHA1_H_ + +#include "stdio.h" +#include "stdint.h" +#include "stdlib.h" +#include "string.h" + +/* SHA-1 context structure */ +typedef struct { + uint32_t total[2]; /* number of bytes processed */ + uint32_t state[5]; /* intermediate digest state */ + unsigned char buffer[64]; /* data block being processed */ +} iot_sha1_context; + + +void utils_hmac_sha1(const char *msg, int msg_len, char *digest, const char *key, int key_len); + +#endif + From 7740e3c5eff3798529c77d104a18b34c26abd15b Mon Sep 17 00:00:00 2001 From: wgzAIIT <820906721@qq.com> Date: Fri, 21 Jul 2023 08:27:54 +0800 Subject: [PATCH 21/23] change CONNECTION_FRAMEWORK_DEBUG default n --- APP_Framework/Framework/connection/Kconfig | 2 +- Ubiquitous/XiZi_IIoT/board/xidatong-arm32/.defconfig | 1 - Ubiquitous/XiZi_IIoT/tool/mqtt/Kconfig | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/APP_Framework/Framework/connection/Kconfig b/APP_Framework/Framework/connection/Kconfig index b6613f2a3..6e0fd4dd0 100644 --- a/APP_Framework/Framework/connection/Kconfig +++ b/APP_Framework/Framework/connection/Kconfig @@ -6,7 +6,7 @@ menuconfig SUPPORT_CONNECTION_FRAMEWORK if SUPPORT_CONNECTION_FRAMEWORK config CONNECTION_FRAMEWORK_DEBUG bool "Using connection framework debug log function" - default y + default n menuconfig CONNECTION_INDUSTRIAL_NETWORK bool "Using industrial network" diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/.defconfig b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/.defconfig index 18029b242..5e2b9c4fd 100644 --- a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/.defconfig +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/.defconfig @@ -234,7 +234,6 @@ CONFIG_ADD_XIZI_FEATURES=y # CONFIG_SUPPORT_CONNECTION_FRAMEWORK is not set # CONFIG_SUPPORT_KNOWING_FRAMEWORK is not set # CONFIG_SUPPORT_CONTROL_FRAMEWORK is not set -CONFIG_CONNECTION_FRAMEWORK_DEBUG=n # diff --git a/Ubiquitous/XiZi_IIoT/tool/mqtt/Kconfig b/Ubiquitous/XiZi_IIoT/tool/mqtt/Kconfig index 609b0dc78..09aa3e87e 100644 --- a/Ubiquitous/XiZi_IIoT/tool/mqtt/Kconfig +++ b/Ubiquitous/XiZi_IIoT/tool/mqtt/Kconfig @@ -18,7 +18,7 @@ menu "MQTT function" config CLIENT_DEVICESECRET string "Device secret, used for device authentication and data encryption." - default "43b3c332233e2204a0612bfbfe21bb67" + default "c9a4ce03e9382065fc089e9ff54b771d" config PLATFORM_SERVERIP string "mqtt platform server ip." From 02089a48eee06918353be941c5db4df023ae6ef0 Mon Sep 17 00:00:00 2001 From: wgzAIIT <820906721@qq.com> Date: Thu, 27 Jul 2023 10:58:14 +0800 Subject: [PATCH 22/23] move mqtt to APP_Framework/lib dir for ota --- APP_Framework/lib/Kconfig | 1 + APP_Framework/lib/Makefile | 4 ++++ .../XiZi_IIoT/tool => APP_Framework/lib}/mqtt/Kconfig | 2 +- .../XiZi_IIoT/tool => APP_Framework/lib}/mqtt/Makefile | 0 .../tool => APP_Framework/lib}/mqtt/platform_mqtt.c | 6 ++---- .../tool => APP_Framework/lib}/mqtt/platform_mqtt.h | 2 +- .../tool => APP_Framework/lib}/mqtt/utils_hmacsha1.c | 2 +- .../tool => APP_Framework/lib}/mqtt/utils_hmacsha1.h | 2 +- Ubiquitous/XiZi_IIoT/path_kernel.mk | 2 +- Ubiquitous/XiZi_IIoT/tool/Kconfig | 1 - Ubiquitous/XiZi_IIoT/tool/Makefile | 4 ---- 11 files changed, 12 insertions(+), 14 deletions(-) rename {Ubiquitous/XiZi_IIoT/tool => APP_Framework/lib}/mqtt/Kconfig (97%) rename {Ubiquitous/XiZi_IIoT/tool => APP_Framework/lib}/mqtt/Makefile (100%) rename {Ubiquitous/XiZi_IIoT/tool => APP_Framework/lib}/mqtt/platform_mqtt.c (99%) rename {Ubiquitous/XiZi_IIoT/tool => APP_Framework/lib}/mqtt/platform_mqtt.h (99%) rename {Ubiquitous/XiZi_IIoT/tool => APP_Framework/lib}/mqtt/utils_hmacsha1.c (99%) rename {Ubiquitous/XiZi_IIoT/tool => APP_Framework/lib}/mqtt/utils_hmacsha1.h (98%) diff --git a/APP_Framework/lib/Kconfig b/APP_Framework/lib/Kconfig index c13ad7a4c..8f9b35eda 100755 --- a/APP_Framework/lib/Kconfig +++ b/APP_Framework/lib/Kconfig @@ -14,4 +14,5 @@ menu "app lib" source "$APP_DIR/lib/lvgl/Kconfig" source "$APP_DIR/lib/embedded_database/Kconfig" source "$APP_DIR/lib/lorawan/Kconfig" + source "$APP_DIR/lib/mqtt/Kconfig" endmenu diff --git a/APP_Framework/lib/Makefile b/APP_Framework/lib/Makefile index 327c69ef2..5877462e4 100644 --- a/APP_Framework/lib/Makefile +++ b/APP_Framework/lib/Makefile @@ -18,4 +18,8 @@ ifeq ($(CONFIG_LIB_USING_LORAWAN),y) SRC_DIR += lorawan endif +ifeq ($(CONFIG_TOOL_USING_MQTT),y) + SRC_DIR += mqtt +endif + include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/tool/mqtt/Kconfig b/APP_Framework/lib/mqtt/Kconfig similarity index 97% rename from Ubiquitous/XiZi_IIoT/tool/mqtt/Kconfig rename to APP_Framework/lib/mqtt/Kconfig index 09aa3e87e..00be02038 100644 --- a/Ubiquitous/XiZi_IIoT/tool/mqtt/Kconfig +++ b/APP_Framework/lib/mqtt/Kconfig @@ -1,4 +1,4 @@ -menu "MQTT function" +menu "lib using MQTT" menuconfig TOOL_USING_MQTT bool "Enable support MQTT function" diff --git a/Ubiquitous/XiZi_IIoT/tool/mqtt/Makefile b/APP_Framework/lib/mqtt/Makefile similarity index 100% rename from Ubiquitous/XiZi_IIoT/tool/mqtt/Makefile rename to APP_Framework/lib/mqtt/Makefile diff --git a/Ubiquitous/XiZi_IIoT/tool/mqtt/platform_mqtt.c b/APP_Framework/lib/mqtt/platform_mqtt.c similarity index 99% rename from Ubiquitous/XiZi_IIoT/tool/mqtt/platform_mqtt.c rename to APP_Framework/lib/mqtt/platform_mqtt.c index b26e2aa61..91689d280 100644 --- a/Ubiquitous/XiZi_IIoT/tool/mqtt/platform_mqtt.c +++ b/APP_Framework/lib/mqtt/platform_mqtt.c @@ -15,16 +15,14 @@ * @brief: platform_mqtt.c file * @version: 1.0 * @author: AIIT XUOS Lab -* @date: 2023/6/14 +* @date: 2023/7/27 * */ #include #include #include -#include "shell.h" -#include "xsconfig.h" -#include +#include #include "platform_mqtt.h" MQTT_TCB Platform_mqtt; //创建一个用于连接云平台mqtt的结构体 diff --git a/Ubiquitous/XiZi_IIoT/tool/mqtt/platform_mqtt.h b/APP_Framework/lib/mqtt/platform_mqtt.h similarity index 99% rename from Ubiquitous/XiZi_IIoT/tool/mqtt/platform_mqtt.h rename to APP_Framework/lib/mqtt/platform_mqtt.h index a7331ffed..92333e9b1 100644 --- a/Ubiquitous/XiZi_IIoT/tool/mqtt/platform_mqtt.h +++ b/APP_Framework/lib/mqtt/platform_mqtt.h @@ -15,7 +15,7 @@ * @brief: platform_mqtt.h file * @version: 1.0 * @author: AIIT XUOS Lab -* @date: 2023/6/14 +* @date: 2023/7/27 * */ diff --git a/Ubiquitous/XiZi_IIoT/tool/mqtt/utils_hmacsha1.c b/APP_Framework/lib/mqtt/utils_hmacsha1.c similarity index 99% rename from Ubiquitous/XiZi_IIoT/tool/mqtt/utils_hmacsha1.c rename to APP_Framework/lib/mqtt/utils_hmacsha1.c index 41b63e6e0..8ed6670ed 100644 --- a/Ubiquitous/XiZi_IIoT/tool/mqtt/utils_hmacsha1.c +++ b/APP_Framework/lib/mqtt/utils_hmacsha1.c @@ -15,7 +15,7 @@ * @brief: utils_hmacsha1.c file * @version: 1.0 * @author: AIIT XUOS Lab -* @date: 2023/6/29 +* @date: 2023/7/27 * */ diff --git a/Ubiquitous/XiZi_IIoT/tool/mqtt/utils_hmacsha1.h b/APP_Framework/lib/mqtt/utils_hmacsha1.h similarity index 98% rename from Ubiquitous/XiZi_IIoT/tool/mqtt/utils_hmacsha1.h rename to APP_Framework/lib/mqtt/utils_hmacsha1.h index da56792a4..0ddbe377b 100644 --- a/Ubiquitous/XiZi_IIoT/tool/mqtt/utils_hmacsha1.h +++ b/APP_Framework/lib/mqtt/utils_hmacsha1.h @@ -15,7 +15,7 @@ * @brief: utils_hmacsha1.h file * @version: 1.0 * @author: AIIT XUOS Lab -* @date: 2023/6/29 +* @date: 2023/7/27 * */ diff --git a/Ubiquitous/XiZi_IIoT/path_kernel.mk b/Ubiquitous/XiZi_IIoT/path_kernel.mk index e02ab827b..0fa334129 100755 --- a/Ubiquitous/XiZi_IIoT/path_kernel.mk +++ b/Ubiquitous/XiZi_IIoT/path_kernel.mk @@ -565,7 +565,7 @@ KERNELPATHS +=-I$(KERNEL_ROOT)/tool/bootloader/flash \ endif ifeq ($(CONFIG_TOOL_USING_MQTT), y) -KERNELPATHS +=-I$(KERNEL_ROOT)/tool/mqtt +KERNELPATHS +=-I$(KERNEL_ROOT)/../../APP_Framework/lib/mqtt endif ifeq ($(CONFIG_FS_LWEXT4),y) diff --git a/Ubiquitous/XiZi_IIoT/tool/Kconfig b/Ubiquitous/XiZi_IIoT/tool/Kconfig index 0c3aa9494..1989064ce 100644 --- a/Ubiquitous/XiZi_IIoT/tool/Kconfig +++ b/Ubiquitous/XiZi_IIoT/tool/Kconfig @@ -1,6 +1,5 @@ menu "Tool feature" source "$KERNEL_DIR/tool/bootloader/Kconfig" - source "$KERNEL_DIR/tool/mqtt/Kconfig" endmenu diff --git a/Ubiquitous/XiZi_IIoT/tool/Makefile b/Ubiquitous/XiZi_IIoT/tool/Makefile index e18b07080..cd148dd4f 100644 --- a/Ubiquitous/XiZi_IIoT/tool/Makefile +++ b/Ubiquitous/XiZi_IIoT/tool/Makefile @@ -8,8 +8,4 @@ ifeq ($(CONFIG_TOOL_USING_OTA),y) SRC_DIR += bootloader endif -ifeq ($(CONFIG_TOOL_USING_MQTT),y) - SRC_DIR += mqtt -endif - include $(KERNEL_ROOT)/compiler.mk From 488419a6d06655e7aeb80536c3a25e829cce7d17 Mon Sep 17 00:00:00 2001 From: wgzAIIT <820906721@qq.com> Date: Wed, 30 Aug 2023 09:35:50 +0800 Subject: [PATCH 23/23] update MQTT connection parameter configuration --- APP_Framework/lib/mqtt/Kconfig | 4 ++-- Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/APP_Framework/lib/mqtt/Kconfig b/APP_Framework/lib/mqtt/Kconfig index 00be02038..1084f4f4a 100644 --- a/APP_Framework/lib/mqtt/Kconfig +++ b/APP_Framework/lib/mqtt/Kconfig @@ -10,7 +10,7 @@ menu "lib using MQTT" menu "MQTT connection parameter configuration." config PLATFORM_PRODUCTKEY string "Product Key, used to identify a product." - default "iywhcgnuezz" + default "iv74vebCdJC" config CLIENT_DEVICENAME string "Device name, used to identify a client device." @@ -18,7 +18,7 @@ menu "lib using MQTT" config CLIENT_DEVICESECRET string "Device secret, used for device authentication and data encryption." - default "c9a4ce03e9382065fc089e9ff54b771d" + default "d2e613c4f714b6b0774bd7b68eeceae3" config PLATFORM_SERVERIP string "mqtt platform server ip." diff --git a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c index 3aedba32d..e132346e3 100644 --- a/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c +++ b/Ubiquitous/XiZi_IIoT/tool/bootloader/ota/ota.c @@ -788,7 +788,7 @@ void OTA_Download(int size, int offset) /******************************************************************************* * 函 数 名: app_ota_by_platform -* 功能描述: 通过命令来进行ota升级,该函数与升级的命令关联,通过云平台MQTT进行升级 +* 功能描述: 通过云平台MQTT进行升级 * 形 参: 无 * 返 回 值: 无 *******************************************************************************/