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