xref: /nrf52832-nimble/rt-thread/components/utilities/zmodem/zcore.c (revision 104654410c56c573564690304ae786df310c91fc)
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