-
Notifications
You must be signed in to change notification settings - Fork 12
/
ymodem_test.c
273 lines (215 loc) · 6.23 KB
/
ymodem_test.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <strings.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"
#define DEV_PATH_DEF "/dev/ttyUSB0"
#define BAUDRATE_DEF 115200
#define TIMEOUT_DEF 20 //10*100ms
static int g_fd;
static struct ymodem ymodem;
static FILE* g_fp;
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 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(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[])
{
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;
while (1) {
struct option long_options[] = {
{"help", no_argument, 0, 'h' },
{0, 0, 0, 0 }
};
c = getopt_long_only(argc, argv, "c:s:d:t: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 '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;
}
//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);
return -1;
}
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);
return 0;
}
if (is_send) {
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(g_file_name) == 0) {
printf("Transfer complete!\r\n");
} else {
printf("Send Ymodem err!\r\n");
printf("stage: %d\r\n", ymodem.stage);
}
} 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);
return 0;
}