Elevator/ymodem-master/ymodem_test.cpp

480 lines
13 KiB
C++

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <strings.h>
#include <iostream>
#include <vector>
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <curl/curl.h>
#include <iostream>
#include <fstream>
#include <cstring>
#include <vector>
#include <iomanip>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <termios.h>
#include <getopt.h>
#include "ymodem.h"
#include "serial_port.h"
#include "download.h"
#include "checkversion.h"
#include <curl/curl.h>
#include <semaphore.h>
#define DEV_PATH_DEF "/dev/ttyUSB0"
#define BAUDRATE_DEF 115200
#define TIMEOUT_DEF 20 //10*100ms
double processvalue = 0;
#define short_wait_time 30
#define long_wait_time 3600
static int g_fd;
static struct ymodem ymodem;
static FILE* g_fp;
sem_t *my_semaphore;
int is_insem = 0;
void signal_handler(int signo) {
if (signo == SIGINT || signo == SIGTERM) {
// 在这里执行你的操作
sleep(1);
printf("Received termination signal. Performing cleanup...\n");
unsigned char stop_data[] = {0x18, 0x18, 0x18, 0x18, 0x18, 0x08, 0x08, 0x08, 0x08, 0x08};
write(g_fd, stop_data, sizeof(stop_data));
sleep(1);
// system("/demo/bin/testprogram &");
if(is_insem == 1){
sem_post(my_semaphore);
is_insem = 0;
printf("%d\n",is_insem);
printf("出锁\n");
}
exit(0);
}
}
//输入进入ota的命令
void put_start_char(){
unsigned char start_data[] = {0xac,0x53,0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x11,0x22,0x33,0x44,0x85,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x01,0x00,0x84,0x09};
write(g_fd, start_data, sizeof(start_data));
}
//清空串口缓存
int flush_serial_input() {
int result = tcflush(g_fd, TCIFLUSH);
if (result == -1) {
perror("tcflush");
}
return result;
}
int _putchar(unsigned char ch)
{
return write(g_fd, &ch, 1);
}
int _getchar(void)
{
ssize_t size;
unsigned char ch;
size = read(g_fd, &ch, 1);
if (size == 1)
return ch;
else
return -1;
}
int get_result(void)
{
ssize_t size;
unsigned char ch;
char buffer[255];
size = read(g_fd, buffer, sizeof(buffer));
if (size > 0){
char hexData[1024];
std::vector<unsigned char> byteArray;
int i;
for (i = 0; i < size; i++) {
snprintf(&hexData[i * 2], sizeof(hexData) - i * 2, "%02X", buffer[i]);
byteArray.push_back(static_cast<unsigned char>(buffer[i]));
}
printf("Received result: %s\n", hexData);
for (unsigned char c : byteArray) {
std::cout << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(c) << " ";
}
std::cout << std::endl;
//解析部分
if (byteArray.size() >= 16 && byteArray[15] == 0x04) {
// 第15个字节是1
// 在这里编写处理逻辑
std::cout << "功能码为0x04 OTA升级时状态码上报" <<std::endl;
if(byteArray.size() >= 23 && byteArray[22] == 0x01){
std::cout << "升级包过大,取消升级" <<std::endl;
}
if(byteArray.size() >= 23 && byteArray[22] == 0x02){
std::cout << "写入闪存错误" <<std::endl;
}
if(byteArray.size() >= 23 && byteArray[22] == 0x03){
std::cout << "用户取消升级" <<std::endl;
}
if(byteArray.size() >= 23 && byteArray[22] == 0x04){
std::cout << "获取包错误" <<std::endl;
}
if(byteArray.size() >= 23 && byteArray[22] == 0x05){
std::cout << " 升级超时" <<std::endl;
}
if(byteArray.size() >= 23 && byteArray[22] == 0x06){
std::cout << "升级成功!" <<std::endl;
}
if(byteArray.size() >= 23 && byteArray[22] == 0x07){
std::cout << "错误太多" <<std::endl;
}
if(byteArray.size() >= 23 && byteArray[22] == 0x08){
std::cout << "包名错误" <<std::endl;
}
if(byteArray.size() >= 23 && byteArray[22] == 0x09){
std::cout << "包名相同" <<std::endl;
}
return 0;
}else
{
std::cout << "功能码错误" <<std::endl;
return -1;
}
}else{
return -1;
}
}
int recv_file_size = 0;
int begin_packet_callback(const unsigned char *buf, unsigned long len)
{
recv_file_size = 0;
g_fp = fopen(ymodem.file_name,"wb+");
if(g_fp == NULL) {
printf("open %s error\r\n", ymodem.file_name);
return -1;
}
return 0;
}
int data_packet_callback(const unsigned char *buf, unsigned long len)
{
int invalid = 0;
//由于我传入data_packet_cb(&packet[PACKET_HEADER], packet_size)的
//是&packet[PACKET_HEADER], 是不带index的, 如果需要, 可以将整个包传入(ymodem.c line:273),
//再在这里判断index,避免出现重复写入或丢数据
recv_file_size += len;
if (recv_file_size > ymodem.file_size) {
invalid = recv_file_size - ymodem.file_size;
}
fwrite(buf, 1, len - invalid, g_fp);
return 0;
}
int end_packet_callback(const unsigned char *buf, unsigned long len)
{
fclose(g_fp);
return 0;
}
int recevice(void)
{
int ret;
printf("Receice Ymodem!\r\n");
ret = ymodem_receive(&ymodem);
//需要再发送两个0x4F,xshell/secureCRT才会提示传送完成
sleep(1);
ymodem.putchar(0x4F);
ymodem.putchar(0x4F);
return ret;
}
int send_begin_packet_callback(const unsigned char *buf, unsigned long len)
{
return 0;
}
int send_data_packet_callback(const unsigned char *buf, unsigned long len)
{
return 0;
}
int send_end_packet_callback(const unsigned char *buf, unsigned long len)
{
return 0;
}
int send_file(const char* file_name)
{
int ret, fd, index, size;
printf("Send Ymodem! file: %s\r\n", file_name);
strcpy(ymodem.file_name, file_name);
fd = open(file_name, O_RDONLY);
if (fd <= 0)
return -1;
//get file data
index = 0;
ymodem.data = (unsigned char *)malloc(300*1024);
do {
size = read(fd, &ymodem.data[index], 1024);
if (size)
index += size;
} while(size > 0);
close(fd);
ymodem.file_size = index;
ret = ymodem_send(&ymodem);
free(ymodem.data);
return ret;
}
void ymodem_help(void)
{
printf("Usage : ./ymodem [options]\n");
printf("options:\r\n");
printf("eg send Ymodem: ./ymodem -d /dev/ttyUSB0 -s /sdcard/test.txt\r\n");
printf("eg receive Ymodem: ./ymodem -d /dev/ttyUSB0\r\n");
printf("\t -d <device name> device path.设置设备名,默认/dev/ttyUSB0.\r\n");
printf("\t -s <file name> send Ymodem, receiving mode if not set.发送文件,如果不选,默认为接收文件\r\n");
printf("\t -t <timeout> Set getchar timeout,def:10(1s), 1=100ms.设置getchar超时,1为100毫秒,默认10=>1s.\r\n");
printf("\t --help display specific types of command line options.\r\n\r\n");
}
int main(int argc, char *argv[])
{
// 注册信号处理函数
signal(SIGINT, signal_handler); // SIGINT 对应Ctrl+C
signal(SIGTERM, signal_handler); // SIGTERM 对应kill或pkill
my_semaphore = sem_open("/my_semaphore", O_CREAT, 0644, 1);
int this_option_optind = optind ? optind : 1;
int option_index = 0;
int c = -1;
int timeout = TIMEOUT_DEF;
char dev_path[128] = DEV_PATH_DEF;
int is_send = 0;
char g_file_name[256] = {0};
int putchar_flag = 0;
int putchar_value = 0;
char url_download[256] = "";
char url_check[256] = "";
int res = -1;
while (1) {
struct option long_options[] = {
{"help", no_argument, 0, 'h' },
{"url_download", required_argument, 0, 'u'},
{"url_check", required_argument, 0, 'w'},
{0, 0, 0, 0 }
};
c = getopt_long_only(argc, argv, "c:s:d:t:u:w:h",
long_options, &option_index);
if (c == -1)
break;
switch (c) {
case 0:
break;
case 'c':
putchar_flag = 1;
putchar_value = optarg[0];
printf("putchar value: %c\r\n", putchar_value);
break;
case 'd':
strcpy(dev_path, optarg);
printf("dev path: %s\r\n", dev_path);
break;
case 's':
strcpy(g_file_name, optarg);
printf("send file: %s.\r\n", g_file_name);
is_send = 1;
break;
case 't':
timeout = atoi(optarg);
printf("timeout: %d*100ms.\r\n", timeout);
break;
case 'u':
strcpy(url_download, optarg);
printf("URL_downlaod: %s\r\n", url_download);
break;
case 'w':
strcpy(url_check, optarg);
printf("URL_check: %s\r\n", url_check);
break;
case 'h':
case '?':
ymodem_help();
return 0;
// break;
default:
break;
}
}
if (optind < argc) {
printf("non-option ARGV-elements: ");
while (optind < argc)
printf("%s ", argv[optind++]);
printf("\n");
ymodem_help();
return 0;
}
while(1){
char local_SE_APP_version[50] = {0};
char download_SE_APP_version[50] = {0};
char download_SE_APP_url[255] = {0};
if(check_version(local_SE_APP_version,download_SE_APP_version,download_SE_APP_url,
sizeof(local_SE_APP_version),sizeof(download_SE_APP_version),sizeof(download_SE_APP_url))){
printf("_save_APP_path = %s\n",_save_APP_path);
//获取文件
int res = download_file(download_SE_APP_url, _save_APP_path);
if (res == -1) {
printf("download_file error.\n");
sleep(long_wait_time);
continue;
}
strcpy(g_file_name, _save_APP_path);
is_send = 1;
// init serial
printf("open dev: %s\r\n", dev_path);
g_fd = open(dev_path, O_RDWR);
if (g_fd <= 0) {
printf("open %s failed!\r\n", dev_path);
sleep(long_wait_time);
continue;
}
serial_set(g_fd, BAUDRATE_DEF, 8, 'N', 1, timeout, 0); //1vtime = 100ms, 10=1000ms=1s
ymodem.putchar = _putchar;
ymodem.getchar = _getchar;
if (putchar_flag) {
ymodem.putchar(putchar_value);
printf("putchar: %c/%d\r\n", putchar_value,putchar_value);
sleep(30);
continue;
}
if (is_send) {
// system("pkill testprogram");
printf("等锁\n");
sem_wait(my_semaphore);
is_insem = 1;
printf("入锁\n");
sleep(1);
ymodem.begin_packet_cb = send_begin_packet_callback;
ymodem.data_packet_cb = send_data_packet_callback;
ymodem.end_packet_cb = send_end_packet_callback;
if (send_file(g_file_name) == 0) {
printf("Transfer complete!\r\n");
// int i = 0;
// do {
// res = get_result();
// i++;
// printf("res: %d i=%d\n",res,i);
// } while ((res != 0) && (i < 3));
sem_post(my_semaphore);
is_insem = 0;
printf("出锁\n");
// system("/demo/bin/testprogram &");
} else {
printf("Send Ymodem err!\r\n");
printf("stage: %d\r\n", ymodem.stage);
// int i = 0;
// do {
// res = get_result();
// i++;
// printf("res: %d i=%d\n",res,i);
// } while ((res != 0) && (i < 3));
sem_post(my_semaphore);
is_insem = 0;
printf("出锁\n");
// system("/demo/bin/testprogram &");
}
} else {
ymodem.begin_packet_cb = begin_packet_callback;
ymodem.data_packet_cb = data_packet_callback;
ymodem.end_packet_cb = end_packet_callback;
if (recevice() == 0) {
printf("Recevice complete!\r\n");
printf("file: %s, size: %d\r\n", ymodem.file_name, ymodem.file_size);
} else {
printf("Recevice Ymodem err!\r\n");
printf("stage: %d\r\n", ymodem.stage);
}
}
close(g_fd);
sleep(long_wait_time);
continue;
}else{
sleep(long_wait_time);
continue;
}
}
}