1*10465441SEvalZero /*
2*10465441SEvalZero * File : rz.c
3*10465441SEvalZero * the core functions of implementing zmodem protocol
4*10465441SEvalZero * Change Logs:
5*10465441SEvalZero * Date Author Notes
6*10465441SEvalZero * 2011-03-29 itspy
7*10465441SEvalZero */
8*10465441SEvalZero
9*10465441SEvalZero #include <rtthread.h>
10*10465441SEvalZero #include <finsh.h>
11*10465441SEvalZero #include <shell.h>
12*10465441SEvalZero #include <rtdef.h>
13*10465441SEvalZero #include <dfs.h>
14*10465441SEvalZero #include <dfs_file.h>
15*10465441SEvalZero #include <dfs_posix.h>
16*10465441SEvalZero #include <stdio.h>
17*10465441SEvalZero #include "zdef.h"
18*10465441SEvalZero
19*10465441SEvalZero char ZF0_CMD; /* file conversion request */
20*10465441SEvalZero char ZF1_CMD; /* file management request */
21*10465441SEvalZero char ZF2_CMD; /* file transport request */
22*10465441SEvalZero char ZF3_CMD;
23*10465441SEvalZero rt_uint8_t Rxframeind; /* ZBIN ZBIN32, or ZHEX type of frame */
24*10465441SEvalZero rt_uint16_t Rxcount; /* received count*/
25*10465441SEvalZero char header_type; /* header type */
26*10465441SEvalZero rt_uint8_t rx_header[4]; /* received header */
27*10465441SEvalZero rt_uint8_t tx_header[4]; /* transmitted header */
28*10465441SEvalZero rt_uint32_t Rxpos; /* received file position */
29*10465441SEvalZero rt_uint32_t Txpos; /* transmitted file position */
30*10465441SEvalZero rt_uint8_t Txfcs32; /* TURE means send binary frames with 32 bit FCS */
31*10465441SEvalZero rt_uint8_t TxCRC; /* controls 32 bit CRC being sent */
32*10465441SEvalZero rt_uint8_t RxCRC; /* indicates/controls 32 bit CRC being received */
33*10465441SEvalZero /* 0 == CRC16, 1 == CRC32, 2 == CRC32 + RLE */
34*10465441SEvalZero char Attn[ZATTNLEN+1]; /* attention string rx sends to tx on err */
35*10465441SEvalZero
36*10465441SEvalZero void zinit_parameter(void);
37*10465441SEvalZero void zsend_bin_header(rt_uint8_t type, rt_uint8_t *hdr);
38*10465441SEvalZero void zsend_hex_header(rt_uint8_t type, rt_uint8_t *hdr);
39*10465441SEvalZero void zsend_bin_data(rt_uint8_t *buf, rt_int16_t len, rt_uint8_t frameend);
40*10465441SEvalZero static rt_int16_t zrec_data16(rt_uint8_t *buf, rt_uint16_t len);
41*10465441SEvalZero static rt_int16_t zrec_data32(rt_uint8_t *buf, rt_int16_t len);
42*10465441SEvalZero static rt_int16_t zrec_data32r(rt_uint8_t *buf, rt_int16_t len);
43*10465441SEvalZero rt_int16_t zget_data(rt_uint8_t *buf, rt_uint16_t len);
44*10465441SEvalZero rt_int16_t zget_header(rt_uint8_t *hdr);
45*10465441SEvalZero static rt_int16_t zget_bin_header(rt_uint8_t *hdr);
46*10465441SEvalZero static rt_int16_t zget_bin_fcs(rt_uint8_t *hdr);
47*10465441SEvalZero rt_int16_t zget_hex_header(rt_uint8_t *hdr);
48*10465441SEvalZero static void zsend_ascii(rt_uint8_t c);
49*10465441SEvalZero void zsend_zdle_char(rt_uint16_t ch);
50*10465441SEvalZero static rt_int16_t zget_hex(void);
51*10465441SEvalZero rt_int16_t zread_byte(void);
52*10465441SEvalZero rt_int16_t zxor_read(void);
53*10465441SEvalZero void zput_pos(rt_uint32_t pos);
54*10465441SEvalZero void zget_pos(rt_uint32_t pos);
55*10465441SEvalZero
56*10465441SEvalZero
57*10465441SEvalZero
58*10465441SEvalZero
zinit_parameter(void)59*10465441SEvalZero void zinit_parameter(void)
60*10465441SEvalZero {
61*10465441SEvalZero rt_uint8_t i;
62*10465441SEvalZero
63*10465441SEvalZero ZF0_CMD = CANFC32|CANFDX|CANOVIO; /* not chose CANFC32,CANRLE,although it have been supported */
64*10465441SEvalZero ZF1_CMD = 0; /* fix header length,not support CANVHDR */
65*10465441SEvalZero ZF2_CMD = 0;
66*10465441SEvalZero ZF3_CMD = 0;
67*10465441SEvalZero Rxframeind =0;
68*10465441SEvalZero header_type = 0;
69*10465441SEvalZero Rxcount = 0;
70*10465441SEvalZero for (i=0;i<4;i++) rx_header[i] = tx_header[i] = 0;
71*10465441SEvalZero Rxpos = Txpos = 0;
72*10465441SEvalZero RxCRC = 0;
73*10465441SEvalZero Txfcs32 = 0;
74*10465441SEvalZero
75*10465441SEvalZero return ;
76*10465441SEvalZero }
77*10465441SEvalZero
78*10465441SEvalZero /* send binary header */
zsend_bin_header(rt_uint8_t type,rt_uint8_t * hdr)79*10465441SEvalZero void zsend_bin_header(rt_uint8_t type, rt_uint8_t *hdr)
80*10465441SEvalZero {
81*10465441SEvalZero rt_uint8_t i;
82*10465441SEvalZero rt_uint32_t crc;
83*10465441SEvalZero
84*10465441SEvalZero zsend_byte(ZPAD);
85*10465441SEvalZero zsend_byte(ZDLE);
86*10465441SEvalZero TxCRC = Txfcs32;
87*10465441SEvalZero if (TxCRC == 0)
88*10465441SEvalZero {
89*10465441SEvalZero zsend_byte(ZBIN);
90*10465441SEvalZero zsend_zdle_char(type);
91*10465441SEvalZero /* add 16bits crc */
92*10465441SEvalZero crc = 0L;
93*10465441SEvalZero crc = updcrc16(type, 0);
94*10465441SEvalZero for (i=0;i<4;i++)
95*10465441SEvalZero {
96*10465441SEvalZero zsend_zdle_char(*hdr);
97*10465441SEvalZero crc = updcrc16((0377 & *hdr++),crc);
98*10465441SEvalZero }
99*10465441SEvalZero crc = updcrc16(0,updcrc16(0,crc));
100*10465441SEvalZero zsend_zdle_char(((int)(crc>>8)));
101*10465441SEvalZero zsend_zdle_char(crc);
102*10465441SEvalZero }
103*10465441SEvalZero else if(TxCRC == 1)
104*10465441SEvalZero {
105*10465441SEvalZero zsend_byte(ZBIN32);
106*10465441SEvalZero zsend_zdle_char(type);
107*10465441SEvalZero /* add 32bits crc */
108*10465441SEvalZero crc = 0xffffffffL;
109*10465441SEvalZero crc = updcrc32(type, crc);
110*10465441SEvalZero for (i=0;i<4;i++)
111*10465441SEvalZero {
112*10465441SEvalZero zsend_zdle_char(*hdr);
113*10465441SEvalZero crc = updcrc32((0377 & *hdr++), crc);
114*10465441SEvalZero }
115*10465441SEvalZero crc = ~crc;
116*10465441SEvalZero for (i=0; i<4;i++)
117*10465441SEvalZero {
118*10465441SEvalZero zsend_zdle_char(crc);
119*10465441SEvalZero crc >>= 8;
120*10465441SEvalZero }
121*10465441SEvalZero }
122*10465441SEvalZero else if (TxCRC == 2)
123*10465441SEvalZero {
124*10465441SEvalZero zsend_byte(ZBINR32);
125*10465441SEvalZero zsend_zdle_char(type);
126*10465441SEvalZero /* add 32bits crc */
127*10465441SEvalZero crc = 0xffffffffL;
128*10465441SEvalZero crc = updcrc32(type, crc);
129*10465441SEvalZero for (i=0;i<4;i++)
130*10465441SEvalZero {
131*10465441SEvalZero zsend_zdle_char(*hdr);
132*10465441SEvalZero crc = updcrc32((0377 & *hdr++), crc);
133*10465441SEvalZero }
134*10465441SEvalZero crc = ~crc;
135*10465441SEvalZero for (i=0; i<4;i++)
136*10465441SEvalZero {
137*10465441SEvalZero zsend_zdle_char(crc);
138*10465441SEvalZero crc >>= 8;
139*10465441SEvalZero }
140*10465441SEvalZero }
141*10465441SEvalZero
142*10465441SEvalZero return;
143*10465441SEvalZero }
144*10465441SEvalZero
145*10465441SEvalZero /* send hex header */
zsend_hex_header(rt_uint8_t type,rt_uint8_t * hdr)146*10465441SEvalZero void zsend_hex_header(rt_uint8_t type, rt_uint8_t *hdr)
147*10465441SEvalZero {
148*10465441SEvalZero rt_uint8_t i;
149*10465441SEvalZero rt_uint16_t crc;
150*10465441SEvalZero
151*10465441SEvalZero zsend_line(ZPAD); zsend_line(ZPAD); zsend_line(ZDLE);
152*10465441SEvalZero zsend_line(ZHEX);
153*10465441SEvalZero zsend_ascii(type);
154*10465441SEvalZero crc = updcrc16(type, 0);
155*10465441SEvalZero for (i=0; i<4; i++)
156*10465441SEvalZero {
157*10465441SEvalZero zsend_ascii(*hdr);
158*10465441SEvalZero crc = updcrc16((0377 & *hdr++), crc);
159*10465441SEvalZero }
160*10465441SEvalZero crc = updcrc16(0,updcrc16(0,crc));
161*10465441SEvalZero zsend_ascii(crc>>8);
162*10465441SEvalZero zsend_ascii(crc);
163*10465441SEvalZero /* send display control cmd */
164*10465441SEvalZero zsend_line(015); zsend_line(0212);
165*10465441SEvalZero if (type != ZFIN && type != ZACK)
166*10465441SEvalZero zsend_line(021);
167*10465441SEvalZero TxCRC = 0; /* clear tx crc type */
168*10465441SEvalZero
169*10465441SEvalZero return;
170*10465441SEvalZero }
171*10465441SEvalZero
172*10465441SEvalZero /* send binary data,with frameend */
zsend_bin_data(rt_uint8_t * buf,rt_int16_t len,rt_uint8_t frameend)173*10465441SEvalZero void zsend_bin_data(rt_uint8_t *buf, rt_int16_t len, rt_uint8_t frameend)
174*10465441SEvalZero {
175*10465441SEvalZero rt_int16_t i,c,tmp;
176*10465441SEvalZero rt_uint32_t crc;
177*10465441SEvalZero
178*10465441SEvalZero if (TxCRC == 0) /* send binary data with 16bits crc check */
179*10465441SEvalZero {
180*10465441SEvalZero crc = 0x0L;
181*10465441SEvalZero for (i=0;i<len;i++)
182*10465441SEvalZero {
183*10465441SEvalZero zsend_zdle_char(*buf);
184*10465441SEvalZero crc = updcrc16((0377 & *buf++), crc);
185*10465441SEvalZero }
186*10465441SEvalZero zsend_byte(ZDLE); zsend_byte(frameend);
187*10465441SEvalZero crc = updcrc16(frameend, crc);
188*10465441SEvalZero crc = updcrc16(0,updcrc16(0,crc));
189*10465441SEvalZero zsend_zdle_char(crc>>8);
190*10465441SEvalZero zsend_zdle_char(crc);
191*10465441SEvalZero }
192*10465441SEvalZero else if (TxCRC == 1) /* send binary data with 32 bits crc check */
193*10465441SEvalZero {
194*10465441SEvalZero crc = 0xffffffffL;
195*10465441SEvalZero for (i=0;i<len;i++)
196*10465441SEvalZero {
197*10465441SEvalZero c = *buf++ & 0377;
198*10465441SEvalZero zsend_zdle_char(c);
199*10465441SEvalZero crc = updcrc32(c, crc);
200*10465441SEvalZero }
201*10465441SEvalZero zsend_byte(ZDLE); zsend_byte(frameend);
202*10465441SEvalZero crc = updcrc32(frameend, crc);
203*10465441SEvalZero crc = ~crc;
204*10465441SEvalZero for (i=0;i<4;i++)
205*10465441SEvalZero {
206*10465441SEvalZero zsend_zdle_char((int)crc); crc >>= 8;
207*10465441SEvalZero }
208*10465441SEvalZero }
209*10465441SEvalZero else if (TxCRC == 2) /* send binary data with 32bits crc check,RLE encode */
210*10465441SEvalZero {
211*10465441SEvalZero crc = 0xffffffffL;
212*10465441SEvalZero tmp = *buf++ & 0377;
213*10465441SEvalZero for (i = 0; --len >= 0; ++buf)
214*10465441SEvalZero {
215*10465441SEvalZero if ((c = *buf & 0377) == tmp && i < 126 && len>0)
216*10465441SEvalZero {
217*10465441SEvalZero ++i; continue;
218*10465441SEvalZero }
219*10465441SEvalZero if (i==0)
220*10465441SEvalZero {
221*10465441SEvalZero zsend_zdle_char(tmp);
222*10465441SEvalZero crc = updcrc32(tmp, crc);
223*10465441SEvalZero if (tmp == ZRESC)
224*10465441SEvalZero {
225*10465441SEvalZero zsend_zdle_char(0100); crc = updcrc32(0100, crc);
226*10465441SEvalZero }
227*10465441SEvalZero tmp = c;
228*10465441SEvalZero }
229*10465441SEvalZero else if (i == 1)
230*10465441SEvalZero {
231*10465441SEvalZero if (tmp != ZRESC)
232*10465441SEvalZero {
233*10465441SEvalZero zsend_zdle_char(tmp); zsend_zdle_char(tmp);
234*10465441SEvalZero crc = updcrc32(tmp, crc);
235*10465441SEvalZero crc = updcrc32(tmp, crc);
236*10465441SEvalZero i = 0; tmp = c;
237*10465441SEvalZero }
238*10465441SEvalZero
239*10465441SEvalZero }
240*10465441SEvalZero else
241*10465441SEvalZero {
242*10465441SEvalZero zsend_zdle_char(ZRESC); crc = updcrc32(ZRESC, crc);
243*10465441SEvalZero if (tmp == 040 && i < 34)
244*10465441SEvalZero {
245*10465441SEvalZero i += 036;
246*10465441SEvalZero zsend_zdle_char(i);
247*10465441SEvalZero crc = updcrc32(i, crc);
248*10465441SEvalZero }
249*10465441SEvalZero else
250*10465441SEvalZero {
251*10465441SEvalZero i += 0101;
252*10465441SEvalZero zsend_zdle_char(i); crc = updcrc32(i, crc);
253*10465441SEvalZero zsend_zdle_char(tmp); crc = updcrc32(tmp, crc);
254*10465441SEvalZero }
255*10465441SEvalZero i = 0; tmp = c;
256*10465441SEvalZero }
257*10465441SEvalZero }
258*10465441SEvalZero zsend_byte(ZDLE); zsend_byte(frameend);
259*10465441SEvalZero crc = updcrc32(frameend, crc);
260*10465441SEvalZero crc = ~crc;
261*10465441SEvalZero for (i=0;i<4;i++)
262*10465441SEvalZero {
263*10465441SEvalZero zsend_zdle_char(crc);
264*10465441SEvalZero crc >>= 8;
265*10465441SEvalZero }
266*10465441SEvalZero }
267*10465441SEvalZero if (frameend == ZCRCW)
268*10465441SEvalZero zsend_byte(XON);
269*10465441SEvalZero
270*10465441SEvalZero return;
271*10465441SEvalZero }
272*10465441SEvalZero
273*10465441SEvalZero /* receive data,with 16bits CRC check */
zrec_data16(rt_uint8_t * buf,rt_uint16_t len)274*10465441SEvalZero static rt_int16_t zrec_data16(rt_uint8_t *buf, rt_uint16_t len)
275*10465441SEvalZero {
276*10465441SEvalZero rt_int16_t c,crc_cnt;
277*10465441SEvalZero rt_uint16_t crc;
278*10465441SEvalZero rt_err_t res = -RT_ERROR;
279*10465441SEvalZero rt_uint8_t *p,flag = 0;
280*10465441SEvalZero
281*10465441SEvalZero p = buf;
282*10465441SEvalZero crc_cnt = 0; crc = 0L;
283*10465441SEvalZero Rxcount = 0;
284*10465441SEvalZero while(buf <= p+len)
285*10465441SEvalZero {
286*10465441SEvalZero if ((res = zread_byte()) & ~0377)
287*10465441SEvalZero {
288*10465441SEvalZero if (res == GOTCRCE || res == GOTCRCG ||
289*10465441SEvalZero res == GOTCRCQ || res == GOTCRCW)
290*10465441SEvalZero {
291*10465441SEvalZero c = res;
292*10465441SEvalZero c = res;
293*10465441SEvalZero crc = updcrc16(res&0377, crc);
294*10465441SEvalZero flag = 1;
295*10465441SEvalZero continue;
296*10465441SEvalZero }
297*10465441SEvalZero else if (res == GOTCAN) return ZCAN;
298*10465441SEvalZero else if (res == TIMEOUT) return TIMEOUT;
299*10465441SEvalZero else return res;
300*10465441SEvalZero
301*10465441SEvalZero }
302*10465441SEvalZero else
303*10465441SEvalZero {
304*10465441SEvalZero if (flag)
305*10465441SEvalZero {
306*10465441SEvalZero crc = updcrc16(res, crc);
307*10465441SEvalZero crc_cnt++;
308*10465441SEvalZero if (crc_cnt < 2) continue;
309*10465441SEvalZero if ((crc & 0xffff))
310*10465441SEvalZero {
311*10465441SEvalZero #ifdef ZDEBUG
312*10465441SEvalZero rt_kprintf("error code: CRC16 error \r\n");
313*10465441SEvalZero #endif
314*10465441SEvalZero return -RT_ERROR;
315*10465441SEvalZero }
316*10465441SEvalZero return c;
317*10465441SEvalZero }
318*10465441SEvalZero else
319*10465441SEvalZero {
320*10465441SEvalZero *buf++ = res;
321*10465441SEvalZero Rxcount++;
322*10465441SEvalZero crc = updcrc16(res, crc);
323*10465441SEvalZero }
324*10465441SEvalZero }
325*10465441SEvalZero }
326*10465441SEvalZero
327*10465441SEvalZero return -RT_ERROR;
328*10465441SEvalZero }
329*10465441SEvalZero
330*10465441SEvalZero /* receive data,with 32bits CRC check */
zrec_data32(rt_uint8_t * buf,rt_int16_t len)331*10465441SEvalZero static rt_int16_t zrec_data32(rt_uint8_t *buf, rt_int16_t len)
332*10465441SEvalZero {
333*10465441SEvalZero rt_int16_t c,crc_cnt;
334*10465441SEvalZero rt_uint32_t crc;
335*10465441SEvalZero rt_err_t res = -RT_ERROR;
336*10465441SEvalZero rt_uint8_t *p,flag = 0;
337*10465441SEvalZero
338*10465441SEvalZero crc_cnt = 0; crc = 0xffffffffL;
339*10465441SEvalZero Rxcount = 0;
340*10465441SEvalZero while (buf <= p+len)
341*10465441SEvalZero {
342*10465441SEvalZero if ((res = zread_byte()) & ~0377)
343*10465441SEvalZero {
344*10465441SEvalZero if (res == GOTCRCE || res == GOTCRCG ||
345*10465441SEvalZero res == GOTCRCQ || res == GOTCRCW)
346*10465441SEvalZero {
347*10465441SEvalZero c = res;
348*10465441SEvalZero crc = updcrc32(res&0377, crc);
349*10465441SEvalZero flag = 1;
350*10465441SEvalZero continue;
351*10465441SEvalZero }
352*10465441SEvalZero else if (res == GOTCAN) return ZCAN;
353*10465441SEvalZero else if (res == TIMEOUT) return TIMEOUT;
354*10465441SEvalZero else return res;
355*10465441SEvalZero
356*10465441SEvalZero }
357*10465441SEvalZero else
358*10465441SEvalZero {
359*10465441SEvalZero if (flag)
360*10465441SEvalZero {
361*10465441SEvalZero crc = updcrc32(res, crc);
362*10465441SEvalZero crc_cnt++;
363*10465441SEvalZero if (crc_cnt < 4) continue;
364*10465441SEvalZero if ((crc & 0xDEBB20E3))
365*10465441SEvalZero {
366*10465441SEvalZero #ifdef ZDEBUG
367*10465441SEvalZero rt_kprintf("error code: CRC32 error \r\n");
368*10465441SEvalZero #endif
369*10465441SEvalZero return -RT_ERROR;
370*10465441SEvalZero }
371*10465441SEvalZero return c;
372*10465441SEvalZero }
373*10465441SEvalZero else
374*10465441SEvalZero {
375*10465441SEvalZero *buf++ = res;
376*10465441SEvalZero Rxcount++;
377*10465441SEvalZero crc = updcrc32(res, crc);
378*10465441SEvalZero }
379*10465441SEvalZero }
380*10465441SEvalZero }
381*10465441SEvalZero
382*10465441SEvalZero return -RT_ERROR;
383*10465441SEvalZero }
384*10465441SEvalZero /* receive data,with RLE encoded,32bits CRC check */
zrec_data32r(rt_uint8_t * buf,rt_int16_t len)385*10465441SEvalZero static rt_int16_t zrec_data32r(rt_uint8_t *buf, rt_int16_t len)
386*10465441SEvalZero {
387*10465441SEvalZero rt_int16_t c,crc_cnt;
388*10465441SEvalZero rt_uint32_t crc;
389*10465441SEvalZero rt_err_t res = -RT_ERROR;
390*10465441SEvalZero rt_uint8_t *p,flag = 0;
391*10465441SEvalZero
392*10465441SEvalZero crc_cnt = 0; crc = 0xffffffffL;
393*10465441SEvalZero Rxcount = 0;
394*10465441SEvalZero p = buf;
395*10465441SEvalZero while (buf <= p+len)
396*10465441SEvalZero {
397*10465441SEvalZero if ((res = zread_byte()) & ~0377)
398*10465441SEvalZero {
399*10465441SEvalZero if (res == GOTCRCE || res == GOTCRCG ||
400*10465441SEvalZero res == GOTCRCQ || res == GOTCRCW)
401*10465441SEvalZero {
402*10465441SEvalZero c = res;
403*10465441SEvalZero crc = updcrc32(res&0377, crc);
404*10465441SEvalZero flag = 1;
405*10465441SEvalZero continue;
406*10465441SEvalZero }
407*10465441SEvalZero else if (res == GOTCAN) return ZCAN;
408*10465441SEvalZero else if (res == TIMEOUT) return TIMEOUT;
409*10465441SEvalZero else return res;
410*10465441SEvalZero
411*10465441SEvalZero }
412*10465441SEvalZero else
413*10465441SEvalZero {
414*10465441SEvalZero if (flag)
415*10465441SEvalZero {
416*10465441SEvalZero crc = updcrc32(res, crc);
417*10465441SEvalZero crc_cnt++;
418*10465441SEvalZero if (crc_cnt < 4) continue;
419*10465441SEvalZero if ((crc & 0xDEBB20E3))
420*10465441SEvalZero {
421*10465441SEvalZero #ifdef ZDEBUG
422*10465441SEvalZero rt_kprintf("error code: CRC32 error \r\n");
423*10465441SEvalZero #endif
424*10465441SEvalZero return -RT_ERROR;
425*10465441SEvalZero }
426*10465441SEvalZero return c;
427*10465441SEvalZero }
428*10465441SEvalZero else
429*10465441SEvalZero {
430*10465441SEvalZero crc = updcrc32(res, crc);
431*10465441SEvalZero switch (c)
432*10465441SEvalZero {
433*10465441SEvalZero case 0:
434*10465441SEvalZero if (res == ZRESC)
435*10465441SEvalZero {
436*10465441SEvalZero c = -1; continue;
437*10465441SEvalZero }
438*10465441SEvalZero *buf++ = res;
439*10465441SEvalZero Rxcount++;
440*10465441SEvalZero continue;
441*10465441SEvalZero case -1:
442*10465441SEvalZero if (res >= 040 && res < 0100)
443*10465441SEvalZero {
444*10465441SEvalZero c = res - 035; res = 040;
445*10465441SEvalZero goto spaces;
446*10465441SEvalZero }
447*10465441SEvalZero if (res == 0100)
448*10465441SEvalZero {
449*10465441SEvalZero c = 0;
450*10465441SEvalZero *buf++ = ZRESC;
451*10465441SEvalZero Rxcount++;
452*10465441SEvalZero continue;
453*10465441SEvalZero }
454*10465441SEvalZero c = res; continue;
455*10465441SEvalZero default:
456*10465441SEvalZero c -= 0100;
457*10465441SEvalZero if (c < 1)
458*10465441SEvalZero goto end;
459*10465441SEvalZero spaces:
460*10465441SEvalZero if ((buf + c) > p+len)
461*10465441SEvalZero goto end;
462*10465441SEvalZero while ( --res >= 0)
463*10465441SEvalZero {
464*10465441SEvalZero *buf++ = res;
465*10465441SEvalZero Rxcount++;
466*10465441SEvalZero }
467*10465441SEvalZero c = 0; continue;
468*10465441SEvalZero }
469*10465441SEvalZero }
470*10465441SEvalZero } // if -else
471*10465441SEvalZero
472*10465441SEvalZero }
473*10465441SEvalZero end:
474*10465441SEvalZero return -RT_ERROR;
475*10465441SEvalZero }
zget_data(rt_uint8_t * buf,rt_uint16_t len)476*10465441SEvalZero rt_int16_t zget_data(rt_uint8_t *buf, rt_uint16_t len)
477*10465441SEvalZero {
478*10465441SEvalZero rt_int16_t res = -RT_ERROR;
479*10465441SEvalZero
480*10465441SEvalZero if (RxCRC == 0)
481*10465441SEvalZero {
482*10465441SEvalZero res = zrec_data16(buf,len);
483*10465441SEvalZero }
484*10465441SEvalZero else if (RxCRC == 1)
485*10465441SEvalZero {
486*10465441SEvalZero res = zrec_data32(buf, len);
487*10465441SEvalZero }
488*10465441SEvalZero else if (RxCRC == 2)
489*10465441SEvalZero {
490*10465441SEvalZero res = zrec_data32r(buf, len);
491*10465441SEvalZero }
492*10465441SEvalZero
493*10465441SEvalZero return res;
494*10465441SEvalZero }
495*10465441SEvalZero /* get type and cmd of header, fix lenght */
zget_header(rt_uint8_t * hdr)496*10465441SEvalZero rt_int16_t zget_header(rt_uint8_t *hdr)
497*10465441SEvalZero {
498*10465441SEvalZero rt_int16_t c,prev_char;
499*10465441SEvalZero rt_uint32_t bit;
500*10465441SEvalZero rt_uint16_t get_can,step_out;
501*10465441SEvalZero
502*10465441SEvalZero bit = get_device_baud(); /* get console baud rate */
503*10465441SEvalZero Rxframeind = header_type = 0;
504*10465441SEvalZero step_out = 0;
505*10465441SEvalZero prev_char = 0xff;
506*10465441SEvalZero for (;;)
507*10465441SEvalZero {
508*10465441SEvalZero c = zread_line(100);
509*10465441SEvalZero switch(c)
510*10465441SEvalZero {
511*10465441SEvalZero case 021:
512*10465441SEvalZero case 0221:
513*10465441SEvalZero if (prev_char == CAN) break;
514*10465441SEvalZero if (prev_char == ZCRCW) goto start_again;
515*10465441SEvalZero break;
516*10465441SEvalZero case RCDO:
517*10465441SEvalZero goto end;
518*10465441SEvalZero case TIMEOUT:
519*10465441SEvalZero if (prev_char == CAN) break;
520*10465441SEvalZero if (prev_char == ZCRCW)
521*10465441SEvalZero {
522*10465441SEvalZero c = -RT_ERROR; goto end;
523*10465441SEvalZero }
524*10465441SEvalZero goto end;
525*10465441SEvalZero case ZCRCW:
526*10465441SEvalZero if (prev_char == CAN) goto start_again;
527*10465441SEvalZero break;
528*10465441SEvalZero case CAN:
529*10465441SEvalZero get_can:
530*10465441SEvalZero if (++get_can > 5)
531*10465441SEvalZero {
532*10465441SEvalZero c = ZCAN; goto end;
533*10465441SEvalZero }
534*10465441SEvalZero break;
535*10465441SEvalZero case ZPAD:
536*10465441SEvalZero if (prev_char == CAN) break;
537*10465441SEvalZero if (prev_char == ZCRCW) goto start_again;
538*10465441SEvalZero step_out = 1;
539*10465441SEvalZero break;
540*10465441SEvalZero default:
541*10465441SEvalZero if (prev_char == CAN) break;
542*10465441SEvalZero if (prev_char == ZCRCW) goto start_again;
543*10465441SEvalZero start_again:
544*10465441SEvalZero if (--bit == 0)
545*10465441SEvalZero {
546*10465441SEvalZero c = GCOUNT; goto end;
547*10465441SEvalZero }
548*10465441SEvalZero get_can = 0;
549*10465441SEvalZero break;
550*10465441SEvalZero }
551*10465441SEvalZero prev_char = c;
552*10465441SEvalZero if (step_out) break; /* exit loop */
553*10465441SEvalZero }
554*10465441SEvalZero step_out = get_can = 0;
555*10465441SEvalZero for (;;)
556*10465441SEvalZero {
557*10465441SEvalZero c = zxor_read();
558*10465441SEvalZero switch(c)
559*10465441SEvalZero {
560*10465441SEvalZero case ZPAD:
561*10465441SEvalZero break;
562*10465441SEvalZero case RCDO:
563*10465441SEvalZero case TIMEOUT:
564*10465441SEvalZero goto end;
565*10465441SEvalZero case ZDLE:
566*10465441SEvalZero step_out = 1;
567*10465441SEvalZero break;
568*10465441SEvalZero default:
569*10465441SEvalZero goto start_again;
570*10465441SEvalZero }
571*10465441SEvalZero if (step_out) break;
572*10465441SEvalZero }
573*10465441SEvalZero
574*10465441SEvalZero Rxframeind = c = zxor_read();
575*10465441SEvalZero switch (c)
576*10465441SEvalZero {
577*10465441SEvalZero case ZBIN32:
578*10465441SEvalZero RxCRC = 1; c = zget_bin_fcs(hdr); break;
579*10465441SEvalZero case ZBINR32:
580*10465441SEvalZero RxCRC = 2; c = zget_bin_fcs(hdr); break;
581*10465441SEvalZero case ZBIN:
582*10465441SEvalZero RxCRC = 0; c = zget_bin_header(hdr); break;
583*10465441SEvalZero case ZHEX:
584*10465441SEvalZero RxCRC = 0; c = zget_hex_header(hdr); break;
585*10465441SEvalZero case CAN:
586*10465441SEvalZero goto get_can;
587*10465441SEvalZero case RCDO:
588*10465441SEvalZero case TIMEOUT:
589*10465441SEvalZero goto end;
590*10465441SEvalZero default:
591*10465441SEvalZero goto start_again;
592*10465441SEvalZero }
593*10465441SEvalZero end:
594*10465441SEvalZero return c;
595*10465441SEvalZero }
596*10465441SEvalZero
597*10465441SEvalZero /* receive a binary header */
zget_bin_header(rt_uint8_t * hdr)598*10465441SEvalZero static rt_int16_t zget_bin_header(rt_uint8_t *hdr)
599*10465441SEvalZero {
600*10465441SEvalZero rt_int16_t res, i;
601*10465441SEvalZero rt_uint16_t crc;
602*10465441SEvalZero
603*10465441SEvalZero if ((res = zread_byte()) & ~0377)
604*10465441SEvalZero return res;
605*10465441SEvalZero header_type = res;
606*10465441SEvalZero crc = updcrc16(res, 0);
607*10465441SEvalZero
608*10465441SEvalZero for (i=0;i<4;i++)
609*10465441SEvalZero {
610*10465441SEvalZero if ((res = zread_byte()) & ~0377)
611*10465441SEvalZero return res;
612*10465441SEvalZero crc = updcrc16(res, crc);
613*10465441SEvalZero *hdr++ = res;
614*10465441SEvalZero }
615*10465441SEvalZero if ((res = zread_byte()) & ~0377)
616*10465441SEvalZero return res;
617*10465441SEvalZero crc = updcrc16(res, crc);
618*10465441SEvalZero if ((res = zread_byte()) & ~0377)
619*10465441SEvalZero return res;
620*10465441SEvalZero crc = updcrc16(res, crc);
621*10465441SEvalZero if (crc & 0xFFFF)
622*10465441SEvalZero {
623*10465441SEvalZero rt_kprintf("CRC error\n");
624*10465441SEvalZero return -RT_ERROR;
625*10465441SEvalZero }
626*10465441SEvalZero
627*10465441SEvalZero return header_type;
628*10465441SEvalZero }
629*10465441SEvalZero
630*10465441SEvalZero /* receive a binary header,with 32bits FCS */
zget_bin_fcs(rt_uint8_t * hdr)631*10465441SEvalZero static rt_int16_t zget_bin_fcs(rt_uint8_t *hdr)
632*10465441SEvalZero {
633*10465441SEvalZero rt_int16_t res, i;
634*10465441SEvalZero rt_uint32_t crc;
635*10465441SEvalZero
636*10465441SEvalZero if ((res = zread_byte()) & ~0377)
637*10465441SEvalZero return res;
638*10465441SEvalZero header_type = res;
639*10465441SEvalZero crc = 0xFFFFFFFFL;
640*10465441SEvalZero crc = updcrc32(res, crc);
641*10465441SEvalZero
642*10465441SEvalZero for (i=0;i<4;i++) /* 4headers */
643*10465441SEvalZero {
644*10465441SEvalZero if ((res = zread_byte()) & ~0377)
645*10465441SEvalZero return res;
646*10465441SEvalZero crc = updcrc32(res, crc);
647*10465441SEvalZero *hdr++ = res;
648*10465441SEvalZero
649*10465441SEvalZero }
650*10465441SEvalZero for (i=0;i<4;i++) /* 4bytes crc */
651*10465441SEvalZero {
652*10465441SEvalZero if ((res = zread_byte()) & ~0377)
653*10465441SEvalZero return res;
654*10465441SEvalZero crc = updcrc32(res, crc);
655*10465441SEvalZero
656*10465441SEvalZero }
657*10465441SEvalZero if (crc != 0xDEBB20E3)
658*10465441SEvalZero {
659*10465441SEvalZero #ifdef ZDEBUG
660*10465441SEvalZero rt_kprintf("CRC error\n");
661*10465441SEvalZero #endif
662*10465441SEvalZero return -RT_ERROR;
663*10465441SEvalZero }
664*10465441SEvalZero
665*10465441SEvalZero return header_type;
666*10465441SEvalZero }
667*10465441SEvalZero
668*10465441SEvalZero
669*10465441SEvalZero /* receive a hex style header (type and position) */
zget_hex_header(rt_uint8_t * hdr)670*10465441SEvalZero rt_int16_t zget_hex_header(rt_uint8_t *hdr)
671*10465441SEvalZero {
672*10465441SEvalZero rt_int16_t res,i;
673*10465441SEvalZero rt_uint16_t crc;
674*10465441SEvalZero
675*10465441SEvalZero if ((res = zget_hex()) < 0)
676*10465441SEvalZero return res;
677*10465441SEvalZero header_type = res;
678*10465441SEvalZero crc = updcrc16(res, 0);
679*10465441SEvalZero
680*10465441SEvalZero for (i=0;i<4;i++)
681*10465441SEvalZero {
682*10465441SEvalZero if ((res = zget_hex()) < 0)
683*10465441SEvalZero return res;
684*10465441SEvalZero crc = updcrc16(res, crc);
685*10465441SEvalZero *hdr++ = res;
686*10465441SEvalZero }
687*10465441SEvalZero if ((res = zget_hex()) < 0)
688*10465441SEvalZero return res;
689*10465441SEvalZero crc = updcrc16(res, crc);
690*10465441SEvalZero if ((res = zget_hex()) < 0)
691*10465441SEvalZero return res;
692*10465441SEvalZero crc = updcrc16(res, crc);
693*10465441SEvalZero if (crc & 0xFFFF)
694*10465441SEvalZero {
695*10465441SEvalZero #ifdef ZDEBUG
696*10465441SEvalZero rt_kprintf("error code : CRC error\r\n");
697*10465441SEvalZero #endif
698*10465441SEvalZero return -RT_ERROR;
699*10465441SEvalZero }
700*10465441SEvalZero res = zread_line(100);
701*10465441SEvalZero if (res < 0)
702*10465441SEvalZero return res;
703*10465441SEvalZero res = zread_line(100);
704*10465441SEvalZero if (res < 0)
705*10465441SEvalZero return res;
706*10465441SEvalZero
707*10465441SEvalZero return header_type;
708*10465441SEvalZero }
709*10465441SEvalZero
710*10465441SEvalZero /* convert to ascii */
zsend_ascii(rt_uint8_t c)711*10465441SEvalZero static void zsend_ascii(rt_uint8_t c)
712*10465441SEvalZero {
713*10465441SEvalZero const char hex[] = "0123456789abcdef";
714*10465441SEvalZero
715*10465441SEvalZero zsend_line(hex[(c&0xF0)>>4]);
716*10465441SEvalZero zsend_line(hex[(c)&0xF]);
717*10465441SEvalZero
718*10465441SEvalZero return;
719*10465441SEvalZero }
720*10465441SEvalZero
721*10465441SEvalZero /*
722*10465441SEvalZero * aend character c with ZMODEM escape sequence encoding.
723*10465441SEvalZero */
zsend_zdle_char(rt_uint16_t ch)724*10465441SEvalZero void zsend_zdle_char(rt_uint16_t ch)
725*10465441SEvalZero {
726*10465441SEvalZero rt_uint16_t res;
727*10465441SEvalZero
728*10465441SEvalZero res = ch & 0377;
729*10465441SEvalZero switch (res)
730*10465441SEvalZero {
731*10465441SEvalZero case 0377:
732*10465441SEvalZero zsend_byte(res);
733*10465441SEvalZero break;
734*10465441SEvalZero case ZDLE:
735*10465441SEvalZero zsend_byte(ZDLE);
736*10465441SEvalZero res ^= 0100;
737*10465441SEvalZero zsend_byte(res);
738*10465441SEvalZero break;
739*10465441SEvalZero case 021:
740*10465441SEvalZero case 023:
741*10465441SEvalZero case 0221:
742*10465441SEvalZero case 0223:
743*10465441SEvalZero zsend_byte(ZDLE);
744*10465441SEvalZero res ^= 0100;
745*10465441SEvalZero zsend_byte(res);
746*10465441SEvalZero break;
747*10465441SEvalZero default:
748*10465441SEvalZero zsend_byte(res);
749*10465441SEvalZero }
750*10465441SEvalZero }
751*10465441SEvalZero
752*10465441SEvalZero /* decode two lower case hex digits into an 8 bit byte value */
zget_hex(void)753*10465441SEvalZero static rt_int16_t zget_hex(void)
754*10465441SEvalZero {
755*10465441SEvalZero rt_int16_t res,n;
756*10465441SEvalZero
757*10465441SEvalZero if ((res = zxor_read()) < 0)
758*10465441SEvalZero return res;
759*10465441SEvalZero n = res - '0';
760*10465441SEvalZero if (n > 9)
761*10465441SEvalZero n -= ('a' - ':');
762*10465441SEvalZero if (n & ~0x0f)
763*10465441SEvalZero return -RT_ERROR;
764*10465441SEvalZero if ((res = zxor_read()) < 0)
765*10465441SEvalZero return res;
766*10465441SEvalZero res -= '0';
767*10465441SEvalZero if (res > 9)
768*10465441SEvalZero res -= ('a' - ':');
769*10465441SEvalZero if (res & ~0x0f)
770*10465441SEvalZero return -RT_ERROR;
771*10465441SEvalZero res += (n<<4);
772*10465441SEvalZero
773*10465441SEvalZero return res;
774*10465441SEvalZero }
775*10465441SEvalZero
776*10465441SEvalZero
777*10465441SEvalZero /*
778*10465441SEvalZero * read a byte, checking for ZMODEM escape encoding
779*10465441SEvalZero * including CAN*5 which represents a quick abort
780*10465441SEvalZero */
zread_byte(void)781*10465441SEvalZero rt_int16_t zread_byte(void)
782*10465441SEvalZero {
783*10465441SEvalZero register int res;
784*10465441SEvalZero
785*10465441SEvalZero again:
786*10465441SEvalZero /* Quick check for non control characters */
787*10465441SEvalZero if ((res = zread_line(100)) & 0140)
788*10465441SEvalZero return res;
789*10465441SEvalZero switch (res)
790*10465441SEvalZero {
791*10465441SEvalZero case ZDLE:
792*10465441SEvalZero break;
793*10465441SEvalZero case 023:
794*10465441SEvalZero case 0223:
795*10465441SEvalZero case 021:
796*10465441SEvalZero case 0221:
797*10465441SEvalZero goto again;
798*10465441SEvalZero default:
799*10465441SEvalZero return res;
800*10465441SEvalZero }
801*10465441SEvalZero again2:
802*10465441SEvalZero if ((res = zread_line(100)) < 0)
803*10465441SEvalZero return res;
804*10465441SEvalZero if (res == CAN && (res = zread_line(100)) < 0)
805*10465441SEvalZero return res;
806*10465441SEvalZero if (res == CAN && (res = zread_line(100)) < 0)
807*10465441SEvalZero return res;
808*10465441SEvalZero if (res == CAN && (res = zread_line(100)) < 0)
809*10465441SEvalZero return res;
810*10465441SEvalZero switch (res)
811*10465441SEvalZero {
812*10465441SEvalZero case CAN:
813*10465441SEvalZero return GOTCAN;
814*10465441SEvalZero case ZCRCE:
815*10465441SEvalZero case ZCRCG:
816*10465441SEvalZero case ZCRCQ:
817*10465441SEvalZero case ZCRCW:
818*10465441SEvalZero return (res | GOTOR);
819*10465441SEvalZero case ZRUB0:
820*10465441SEvalZero return 0177;
821*10465441SEvalZero case ZRUB1:
822*10465441SEvalZero return 0377;
823*10465441SEvalZero case 023:
824*10465441SEvalZero case 0223:
825*10465441SEvalZero case 021:
826*10465441SEvalZero case 0221:
827*10465441SEvalZero goto again2;
828*10465441SEvalZero default:
829*10465441SEvalZero if ((res & 0140) == 0100)
830*10465441SEvalZero return (res ^ 0100);
831*10465441SEvalZero break;
832*10465441SEvalZero }
833*10465441SEvalZero
834*10465441SEvalZero return -RT_ERROR;
835*10465441SEvalZero }
836*10465441SEvalZero
837*10465441SEvalZero /*
838*10465441SEvalZero * @read a character from the modem line with timeout.
839*10465441SEvalZero * @eat parity, XON and XOFF characters.
840*10465441SEvalZero */
zxor_read(void)841*10465441SEvalZero rt_int16_t zxor_read(void)
842*10465441SEvalZero {
843*10465441SEvalZero rt_int16_t res;
844*10465441SEvalZero
845*10465441SEvalZero for (;;)
846*10465441SEvalZero {
847*10465441SEvalZero if ((res = zread_line(100)) < 0)
848*10465441SEvalZero return res;
849*10465441SEvalZero switch (res &= 0177) {
850*10465441SEvalZero case XON:
851*10465441SEvalZero case XOFF:
852*10465441SEvalZero continue;
853*10465441SEvalZero case '\r':
854*10465441SEvalZero case '\n':
855*10465441SEvalZero case ZDLE:
856*10465441SEvalZero default:
857*10465441SEvalZero return res;
858*10465441SEvalZero }
859*10465441SEvalZero }
860*10465441SEvalZero
861*10465441SEvalZero }
862*10465441SEvalZero
863*10465441SEvalZero /* put file posistion into the header*/
zput_pos(rt_uint32_t pos)864*10465441SEvalZero void zput_pos(rt_uint32_t pos)
865*10465441SEvalZero {
866*10465441SEvalZero tx_header[ZP0] = pos;
867*10465441SEvalZero tx_header[ZP1] = pos>>8;
868*10465441SEvalZero tx_header[ZP2] = pos>>16;
869*10465441SEvalZero tx_header[ZP3] = pos>>24;
870*10465441SEvalZero
871*10465441SEvalZero return;
872*10465441SEvalZero }
873*10465441SEvalZero
874*10465441SEvalZero /* Recover a long integer from a header */
zget_pos(rt_uint32_t pos)875*10465441SEvalZero void zget_pos(rt_uint32_t pos)
876*10465441SEvalZero {
877*10465441SEvalZero Rxpos = (rx_header[ZP3] & 0377);
878*10465441SEvalZero Rxpos = (Rxpos << 8) | (rx_header[ZP2] & 0377);
879*10465441SEvalZero Rxpos = (Rxpos << 8) | (rx_header[ZP1] & 0377);
880*10465441SEvalZero Rxpos = (Rxpos << 8) | (rx_header[ZP0] & 0377);
881*10465441SEvalZero
882*10465441SEvalZero return;
883*10465441SEvalZero }
884*10465441SEvalZero
885*10465441SEvalZero /* end of zcore.c */
886