#include #include #include "FreeRTOS.h" #include "task.h" #include "queue.h" #include "board.h" #include "chip.h" #include "animation.h" #include "sfud.h" #include "romfile.h" #include "updatefile.h" #include "sysinfo.h" #include "mmcsd_core.h" #include "ff_stdio.h" #include "ota_update.h" #include "md5.h" #include "unzip.h" #include "ff_sddisk.h" #include "FreeRTOS_Sockets.h" #include "FreeRTOS_IP.h" #include "FreeRTOS_DHCP.h" #include "iperf_task.h" #include "iot_wifi.h" #include "FreeRTOS_DHCP_Server.h" #include "sockets.h" uint8_t wifi_ota_state = 0; extern int timeout; typedef enum { UART_FILE_NORMAL, UART_FILE_TYPE, UART_FILE_START, UART_FILE_FILEXFER, UART_FILE_FINISH, } eWifiFileStatus; typedef enum { UART_FILE_AMT630H, UART_FILE_BOOTANIM, UART_FILE_ROM, UART_FILE_UPDATE, UART_FILE_SPILEDR, UART_FILE_STEPLDR, } eWifiFileType; static uint8_t file_state = UART_FILE_NORMAL;//文件接收状态 static uint8_t uup_file_type = UART_FILE_NORMAL;//文件接收状态 uint8_t wifi_file_state = UART_FILE_NORMAL;//文件接收状态 #define BYTESPERPAGE 256 #define PAGESPERSECTORS 32//32//16 #define UUP_BUF_SIZE (BYTESPERPAGE * PAGESPERSECTORS) #define NEW_APPLDR_CHECKSUM_OFFSET 0x14 static unsigned int checksum = 0,calc_checksum = 0xffffffff,test_checksum = 0xffffffff; #define NEW_APPFOOSET 0x17F0000 #define AMT630_BIN_MAX_SIZE 0x700000 static uint32_t uup_burn_offset; // static unsigned char uup_buf[4096]; static unsigned char uup_buf[8192]; static unsigned int uup_buf_len = 0; static unsigned int uup_buf_len_detection = 0; static uint8_t checksum_flag = 0; static int test_flag = 0; // static int number = 0; static void ota_update(char *framebuf, size_t len) { unsigned int framelen; framelen = len; sfud_flash *sflash = sfud_get_device(0); if(strcmp(framebuf, "AT_OTA_FINISH") == 0){ if(file_state == UART_FILE_FILEXFER) file_state = UART_FILE_FINISH; } switch(file_state){ case UART_FILE_NORMAL://检测是否是升级 if(strcmp(framebuf, "AT_OTA_START") == 0) file_state = UART_FILE_TYPE; break; case UART_FILE_TYPE://检测传输文件类型 if(strncmp(framebuf, "AT_OTA_TYPE=",12) == 0 && (framelen == 13)){ uup_file_type = framebuf[12] - '0'; printf("uup_file_type = %d .\r\n",uup_file_type); if(uup_file_type<6){ //擦除flash uup_burn_offset = NEW_APPFOOSET; printf("start erase add %X , size %X .\r\n",uup_burn_offset,AMT630_BIN_MAX_SIZE); if(sfud_erase(sflash, uup_burn_offset, AMT630_BIN_MAX_SIZE)==SFUD_SUCCESS){ vTaskDelay(100); printf("UART_FRAME_START sfud erase ok.\n"); }else{ vTaskDelay(100); printf("UART_FRAME_START sfud erase fail.\n"); } checksum_flag = 1; calc_checksum = 0xffffffff; test_checksum = 0xffffffff; test_flag = 0; uup_buf_len =0; checksum = 0; // number = 0; file_state = UART_FILE_START; }else file_state = UART_FILE_NORMAL; }else{ file_state = UART_FILE_NORMAL; } break; case UART_FILE_START://第一包数据 用于获取当前数据包的校验和 if (uup_file_type == UART_FILE_AMT630H) {//代码文件 unsigned int magic = framebuf[0] | (framebuf[1] << 8) | (framebuf[2] << 16) | (framebuf[3] << 24); if (magic != UPFILE_APP_MAGIC) { printf("Wrong app file magic. 0x%08X\n",magic); file_state = UART_FILE_NORMAL; break; } unsigned char *tmp = framebuf + NEW_APPLDR_CHECKSUM_OFFSET; checksum = tmp[0] | (tmp[1] <<8) | (tmp[2] << 16) | (tmp[3] << 24); }else if (uup_file_type == UART_FILE_BOOTANIM) {//动画文件 BANIHEADER *header = (BANIHEADER *)&framebuf[0]; if (header->magic != MKTAG('B', 'A', 'N', 'I')) { printf("Wrong animation file magic.\n"); file_state = UART_FILE_NORMAL; break; } checksum = header->checksum; }else if (uup_file_type == UART_FILE_ROM) {//资源文件 RomHeader *header = (RomHeader *)&framebuf[0]; if (header->magic != MKTAG('R', 'O', 'M', 'A')) { printf("Wrong resource file magic.\n"); file_state = UART_FILE_NORMAL; break; } checksum = header->checksum; } printf("uup_file_type = %d ,No1.checksum = 0x%X\n",uup_file_type,checksum); uup_buf_len_detection = (uup_buf_len + framelen)>UUP_BUF_SIZE?(UUP_BUF_SIZE-uup_buf_len):0; // printf("1-- framelen = %d uup_buf_len_detection = %d .\r\n",framelen,uup_buf_len_detection); if(!uup_buf_len_detection){ memcpy(uup_buf + uup_buf_len, framebuf, framelen); uup_buf_len += framelen; if (uup_buf_len == UUP_BUF_SIZE) { if(!checksum_flag) test_checksum = xcrc32(uup_buf, UUP_BUF_SIZE, test_checksum);//计算校验和 sfud_write(sflash, uup_burn_offset, UUP_BUF_SIZE, uup_buf); if(checksum_flag){ if (uup_file_type == UART_FILE_AMT630H) {//代码文件 unsigned int *tmp = (unsigned int *)(uup_buf + NEW_APPLDR_CHECKSUM_OFFSET); *tmp = 0; }else if (uup_file_type == UART_FILE_BOOTANIM) {//动画文件 BANIHEADER *pheader = (BANIHEADER *)uup_buf; pheader->checksum = 0; }else if (uup_file_type == UART_FILE_ROM) {//资源文件 RomHeader *pheader = (RomHeader *)uup_buf; pheader->checksum = 0; } checksum_flag = 0; test_flag = 1; } calc_checksum = xcrc32(uup_buf, UUP_BUF_SIZE, calc_checksum);//计算校验和 if(test_flag){ test_checksum = calc_checksum; printf("test_checksum == calc_checksum 0x%08X.\r\n",test_checksum); test_flag = 0; } if(calc_checksum != test_checksum){ printf("error!!!test_checksum=0x%08X,calc_checksum=0x%08X.\r\n",test_checksum,calc_checksum); } uup_buf_len =0; uup_burn_offset += UUP_BUF_SIZE; //number++; //printf("number =%d,checksum = 0x%08X.\n",number,calc_checksum,checksum); } }else{ memcpy(uup_buf + uup_buf_len, framebuf, uup_buf_len_detection); uup_buf_len += uup_buf_len_detection; if (uup_buf_len == UUP_BUF_SIZE) { if(!checksum_flag) test_checksum = xcrc32(uup_buf, UUP_BUF_SIZE, test_checksum);//计算校验和 sfud_write(sflash, uup_burn_offset, UUP_BUF_SIZE, uup_buf); if(checksum_flag){ if (uup_file_type == UART_FILE_AMT630H) {//代码文件 unsigned int *tmp = (unsigned int *)(uup_buf + NEW_APPLDR_CHECKSUM_OFFSET); *tmp = 0; }else if (uup_file_type == UART_FILE_BOOTANIM) {//动画文件 BANIHEADER *pheader = (BANIHEADER *)uup_buf; pheader->checksum = 0; }else if (uup_file_type == UART_FILE_ROM) {//资源文件 RomHeader *pheader = (RomHeader *)uup_buf; pheader->checksum = 0; unsigned int *tmp = (unsigned int *)(uup_buf + 0x0F); } checksum_flag = 0; test_flag = 1; } calc_checksum = xcrc32(uup_buf, UUP_BUF_SIZE, calc_checksum);//计算校验和 if(test_flag){ test_checksum = calc_checksum; printf("test_checksum == calc_checksum 0x%08X.\r\n",test_checksum); test_flag = 0; } if(calc_checksum != test_checksum){ printf("error!!!test_checksum=0x%08X,calc_checksum=0x%08X.\r\n",test_checksum,calc_checksum); } uup_buf_len =0; uup_burn_offset += UUP_BUF_SIZE; //number++; //printf("number =%d,checksum = 0x%08X.\n",number,calc_checksum,checksum); } // printf("2-- (framelen - uup_buf_len_detection) = %d .\r\n",(framelen - uup_buf_len_detection)); memcpy(uup_buf + uup_buf_len, framebuf, (framelen - uup_buf_len_detection)); uup_buf_len += (framelen - uup_buf_len_detection); } // printf(">>UART_FILE_FILEXFER.\r\n"); file_state = UART_FILE_FILEXFER; break; case UART_FILE_FILEXFER://传输过程中 uup_buf_len_detection = (uup_buf_len + framelen)>UUP_BUF_SIZE?(UUP_BUF_SIZE-uup_buf_len):0; // printf("uup_buf_len_detection=%d.\r\n",uup_buf_len_detection); if(!uup_buf_len_detection){ memcpy(uup_buf + uup_buf_len, framebuf, framelen); uup_buf_len += framelen; // printf("uup_buf_len = %d .\r\n",uup_buf_len); if (uup_buf_len == UUP_BUF_SIZE) { if(!checksum_flag) test_checksum = xcrc32(uup_buf, UUP_BUF_SIZE, test_checksum);//计算校验和 sfud_write(sflash, uup_burn_offset, UUP_BUF_SIZE, uup_buf); if(checksum_flag){ if (uup_file_type == UART_FILE_AMT630H) {//代码文件 unsigned int *tmp = (unsigned int *)(uup_buf + NEW_APPLDR_CHECKSUM_OFFSET); *tmp = 0; }else if (uup_file_type == UART_FILE_BOOTANIM) {//动画文件 BANIHEADER *pheader = (BANIHEADER *)uup_buf; pheader->checksum = 0; }else if (uup_file_type == UART_FILE_ROM) {//资源文件 RomHeader *pheader = (RomHeader *)uup_buf; pheader->checksum = 0; unsigned int *tmp = (unsigned int *)(uup_buf + 0x0F); } checksum_flag = 0; test_flag = 1; } calc_checksum = xcrc32(uup_buf, UUP_BUF_SIZE, calc_checksum);//计算校验和 if(test_flag){ test_checksum = calc_checksum; printf("test_checksum == calc_checksum 0x%08X.\r\n",test_checksum); test_flag = 0; } if(calc_checksum != test_checksum){ printf("error!!!test_checksum=0x%08X,calc_checksum=0x%08X.\r\n",test_checksum,calc_checksum); } uup_buf_len =0; uup_burn_offset += UUP_BUF_SIZE; //number++; //printf("number =%d,checksum = 0x%08X.\n",number,calc_checksum,checksum); } }else{ memcpy(uup_buf + uup_buf_len, framebuf, uup_buf_len_detection); uup_buf_len += uup_buf_len_detection; // printf("2---------------- uup_buf_len = %d .\r\n",uup_buf_len); if (uup_buf_len == UUP_BUF_SIZE) { if(!checksum_flag) test_checksum = xcrc32(uup_buf, UUP_BUF_SIZE, test_checksum);//计算校验和 sfud_write(sflash, uup_burn_offset, UUP_BUF_SIZE, uup_buf); if(checksum_flag){ if (uup_file_type == UART_FILE_AMT630H) {//代码文件 unsigned int *tmp = (unsigned int *)(uup_buf + NEW_APPLDR_CHECKSUM_OFFSET); *tmp = 0; }else if (uup_file_type == UART_FILE_BOOTANIM) {//动画文件 BANIHEADER *pheader = (BANIHEADER *)uup_buf; pheader->checksum = 0; }else if (uup_file_type == UART_FILE_ROM) {//资源文件 RomHeader *pheader = (RomHeader *)uup_buf; pheader->checksum = 0; unsigned int *tmp = (unsigned int *)(uup_buf + 0x0F); } checksum_flag = 0; test_flag = 1; } calc_checksum = xcrc32(uup_buf, UUP_BUF_SIZE, calc_checksum);//计算校验和 if(test_flag){ test_checksum = calc_checksum; printf("test_checksum == calc_checksum 0x%08X.\r\n",test_checksum); test_flag = 0; } if(calc_checksum != test_checksum){ printf("error!!!test_checksum=0x%08X,calc_checksum=0x%08X.\r\n",test_checksum,calc_checksum); } uup_buf_len =0; uup_burn_offset += UUP_BUF_SIZE; // number++; // printf("number =%d,checksum = 0x%08X.\n",number,calc_checksum,checksum); } memcpy(uup_buf + uup_buf_len, framebuf, (framelen - uup_buf_len_detection)); uup_buf_len += (framelen - uup_buf_len_detection); // printf("2----uup_buf_len = %d .\r\n",uup_buf_len); } // file_state = UART_FILE_FILEXFER; break; case UART_FILE_FINISH://传输完成 if(uup_buf_len){//若最后一包数据不为0 则存数据并且继续计算校验和 sfud_write(sflash, uup_burn_offset, uup_buf_len, uup_buf); test_checksum = xcrc32(uup_buf, uup_buf_len, test_checksum);//计算校验和 calc_checksum = xcrc32(uup_buf, uup_buf_len, calc_checksum); printf("enter2 uup_buf_len =%d calc_checksum================0x%08X,test_checksum=0x%08X\n",uup_buf_len,calc_checksum,test_checksum); } printf("calc_checksum = 0x%08X,checksum = 0x%08X.\n",calc_checksum,checksum); printf("test_checksum=0x%08X.\r\n",test_checksum); if (calc_checksum != checksum) { printf("fail !!!!!!!!!!!!\n"); }else printf("whole crc check after burn ok!\n"); file_state = UART_FILE_NORMAL; break; default: break; } if(file_state != UART_FILE_FILEXFER) printf("now > file_state = %d .\r\n",file_state); } static int uup_rx_state = 0; #define UUP_PACKET_SIZE 128 #define UUP_MAX_FRAME_LEN (UUP_PACKET_SIZE + 16) #define UUP_PACKET_A27_SIZE 4096 #define UUP_MAX_FRAME_A27_LEN (UUP_PACKET_A27_SIZE + 16) #define UUP_RX_FRAME_NUM 16 #define BYTESPERPAGE 256 #define PAGESPERSECTORS 16 #define UUP_BUF_SIZE (BYTESPERPAGE * PAGESPERSECTORS) static unsigned char uup_rx_buf[UUP_RX_FRAME_NUM][4096]; static unsigned char *uup_rx_ptr; static int uup_rx_rev_len = 0; static int uup_rx_head = 0; static int uup_rx_tail = 0; static int uup_rx_data_len = 0; unsigned char wifi_ota_request[8] = {0x7e,0x01,0x05,0x02,0x03,0x01,0x00,0x01}; int serverSock = -1, clientSock = -1; // 函数定义:发送数据给客户端 void sendDataToClient(int clientSock, const char* data, int length) { int ret = send(clientSock, data, length, 0); if (ret <= 0) { close(clientSock); clientSock = -1; printf("Failed to send data to client.\r\n"); } } void wifi_uup_send_ack(int type, int ret) { unsigned char buf[8] = {0x55, 0x80, 0xc5, 0x02, 0x00, 0x00, 0x00, 0x00}; int i; buf[5] = type; buf[6] = ret; if(ret == 0){ wifi_ota_state = 0; timeout = 0; wifi_file_state = 0; Set_sys_power_on_self_test(100); Set_sys_return_demo(2); Set_sys_plan(0); Set_sys_pace(0); } for (i = 1; i < 7; i++) buf[7] ^= buf[i]; sendDataToClient(clientSock,buf,8); } static void wifi_update_judge(char *uartrx, size_t len){ uint8_t data = 0; for(int i=0;i UUP_PACKET_A27_SIZE + 2)) { //4096 + 2 printf("Invalid uup_rx_data_len %d\n", uup_rx_data_len); uup_rx_state = 0; } else { uup_rx_state++; *uup_rx_ptr++ = data; } break; case 5: data = *(uartrx++); *uup_rx_ptr++ = data; if (++uup_rx_rev_len == uup_rx_data_len) uup_rx_state++; break; case 6: data = *(uartrx++); *uup_rx_ptr++ = data; uup_rx_head = (uup_rx_head + 1) % UUP_RX_FRAME_NUM; // printf("1--- uup_rx_head=%d,uup_rx_tail=%d.\r\n",uup_rx_head,uup_rx_tail); uup_rx_state = 0; break; } } while (uup_rx_tail != uup_rx_head) { unsigned char *buf; unsigned char checksum = 0; buf = &uup_rx_buf[uup_rx_tail][0]; len = buf[2]; len = buf[3]<<8 | len; for (int i = 0; i < len + 4; i++) checksum ^= buf[i]; if (checksum == buf[len + 4]) { // printf("2--- uup_rx_head=%d,uup_rx_tail=%d.\r\n",uup_rx_head,uup_rx_tail); wifi_uup_ota_update(buf + 4, len); } else { printf("rev frame checksum err.\r\n"); } uup_rx_tail = (uup_rx_tail + 1) % UUP_RX_FRAME_NUM; } #endif } static void wifi_ota_update(char *framebuf, size_t len) { unsigned int framelen; framelen = len; sfud_flash *sflash = sfud_get_device(0); // printf("wifi_file_state > %d.\r\n",wifi_file_state); switch(wifi_file_state){ case UART_FILE_NORMAL://检测是否是升级 wifi_update_judge(framebuf,len);//升级判断 printf("wifi_file_state > %d.\r\n",wifi_file_state); break; // case UART_FILE_TYPE://检测传输文件类型 // break; case UART_FILE_START://升级流程 wifi_update_technological_process(framebuf,len);//升级流程 break; // case UART_FILE_FILEXFER://传输过程中 // break; // case UART_FILE_FINISH://传输完成 // break; default: break; } } extern char strQrText[200]; extern char strCarplayText[200]; //TCP接收函数 void app_wifi_update_demo(void) { printf("app_wifi_update_demo init.\r\n"); strcpy(strCarplayText, strQrText); Send_wifi_name(); int err; int testPort, max_fd, ret; fd_set xFD_Set; char buf[4096] = {0}; uint8_t data[32] = "Hello, server!"; #if 0 err = ServerSocketOpen( AF_INET, SOCK_STREAM, IPPROTO_TCP, 8000, &testPort, kSocketBufferSize_DontSet, &serverSock ); require_noerr(err, exit); #else struct sockaddr_in sin; socklen_t len; // serverSock = socket(AF_INET, SOCK_DGRAM, 0); serverSock = socket(AF_INET, SOCK_STREAM, 0); if(serverSock < 0) { printf("client socket create failed.\r\n"); goto exit; } memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_port = htons(10003); sin.sin_addr.s_addr = htonl(INADDR_ANY);//任何ip地址的client都可以连到这个server len = sizeof(struct sockaddr_in); int flag = 1; if (-1 == setsockopt(serverSock, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag))) { printf("setsockopt SO_REUSEADDR fail"); } flag = 1; if (-1 == setsockopt(serverSock, SOL_SOCKET, SO_REUSEPORT, &flag, sizeof(flag))) { printf("setsockopt SO_REUSEPORT fail"); } ret = bind(serverSock, (struct sockaddr*)&sin, len); if (ret == -1) goto exit; ret = listen(serverSock, 1);//设置最多连5个client if (ret == -1) goto exit; #endif max_fd = (int)serverSock; while (1) { FD_ZERO(&xFD_Set); if (serverSock != -1) FD_SET(serverSock, &xFD_Set); if (clientSock != -1) FD_SET(clientSock, &xFD_Set); ret = select( max_fd + 1, &xFD_Set, NULL, NULL, NULL); if (ret < 0) { break; } if (ret == 0) { continue; } if( FD_ISSET ( serverSock, &xFD_Set ) ) { printf("%s:%d\r\n", __func__, __LINE__); // clientSock = accept(serverSock, NULL, NULL); clientSock = accept(serverSock, NULL, NULL); printf("%s:%d\r\n", __func__, __LINE__); if (clientSock != -1) { if (clientSock > max_fd) max_fd = (int)clientSock; } continue; } if( FD_ISSET ( clientSock, &xFD_Set ) ) { ret = recv(clientSock, buf, sizeof(buf), 0); if (ret <= 0) { close(clientSock); clientSock = -1; printf("client is disconnected\r\n"); continue; } // printf("recv len:%d.\r\n", ret); if(timeout) timeout = 0; // if(ret<100) // printf("recv len:%d %s\r\n", ret, buf); // else // printf("recv len:%d.\r\n", ret); wifi_ota_update(buf,ret); memset(buf, 0, sizeof(buf)); } } exit: return; } static void wifi_update_rx_thread(void *param) { // vTaskDelay(7000); // while(1){ app_wifi_update_demo(); // vTaskDelay(3000); // } } int wifi_update_init(void){ /* Create a task to process uart rx data */ if (xTaskCreate(wifi_update_rx_thread, "wifi_update_rx_thread", configMINIMAL_STACK_SIZE*20, NULL, configMAX_PRIORITIES / 3, NULL) != pdPASS) { return -1; } return 0; } #if 0 int test_udp_client(const char *ip_str, int port) { /* socket文件描述符 */ int sock_fd = -1; /* 建立udp socket */ sock_fd = socket(AF_INET, SOCK_DGRAM, 0); if(sock_fd < 0) { printf("client socket create failed.\r\n"); goto exit; } /* 设置address */ struct sockaddr_in addr_serv; int len; memset(&addr_serv, 0, sizeof(addr_serv)); addr_serv.sin_family = AF_INET; addr_serv.sin_addr.s_addr = inet_addr(ip_str); addr_serv.sin_port = htons(port); len = sizeof(addr_serv); int send_num; int recv_num; char send_buf[20] = "hey, who are you?"; char recv_buf[20]; printf("###client send: %s\n", send_buf); send_num = sendto(sock_fd, send_buf, strlen(send_buf), 0, (struct sockaddr *)&addr_serv, len); if(send_num < 0) { printf("sendto erro\r\n"); goto exit; } recv_num = recvfrom(sock_fd, recv_buf, sizeof(recv_buf), 0, (struct sockaddr *)&addr_serv, (socklen_t *)&len); if(recv_num <= 0) { printf("socket recv failed\r\n"); goto exit; } recv_buf[recv_num] = '\0'; printf("client receive %d bytes: %s\n", recv_num, recv_buf); exit: if (-1 != sock_fd) close(sock_fd); return 0; } int test_udp_server(int port) { int sock_fd = socket(AF_INET, SOCK_DGRAM, 0); if(sock_fd < 0) { printf("server socket create failed.\r\n"); goto exit; } struct sockaddr_in addr_serv; int len; memset(&addr_serv, 0, sizeof(struct sockaddr_in)); addr_serv.sin_family = AF_INET; addr_serv.sin_port = htons(port); addr_serv.sin_addr.s_addr = htonl(INADDR_ANY); len = sizeof(addr_serv); if(bind(sock_fd, (struct sockaddr *)&addr_serv, sizeof(addr_serv)) < 0) { printf("bind error\r\n"); goto exit; } int recv_num; int send_num; char send_buf[20] = "i am server!"; char recv_buf[20]; struct sockaddr_in addr_client; while(1) { printf("server wait:\n"); recv_num = recvfrom(sock_fd, recv_buf, sizeof(recv_buf), 0, (struct sockaddr *)&addr_client, (socklen_t *)&len); if(recv_num < 0) { printf("recvfrom error:\r\n"); goto exit; } recv_buf[recv_num] = '\0'; printf("server receive %d bytes: %s\n", recv_num, recv_buf); send_num = sendto(sock_fd, send_buf, recv_num, 0, (struct sockaddr *)&addr_client, len); if(send_num <= 0) { printf("sendto error:"); break; } } exit: if (-1 != sock_fd) close(sock_fd); return 0; } #endif