|
@@ -1,865 +0,0 @@
|
|
|
-/*
|
|
|
- * File : rz.c
|
|
|
- * the core functions of implementing zmodem proctocol
|
|
|
- * Change Logs:
|
|
|
- * Date Author Notes
|
|
|
- * 2011-03-29 itspy
|
|
|
- */
|
|
|
-
|
|
|
-#include <rtthread.h>
|
|
|
-#include <finsh.h>
|
|
|
-#include <shell.h>
|
|
|
-#include <rtdef.h>
|
|
|
-#include <dfs.h>
|
|
|
-#include <dfs_file.h>
|
|
|
-#include <dfs_posix.h>
|
|
|
-#include <stdio.h>
|
|
|
-#include "zdef.h"
|
|
|
-
|
|
|
-char ZF0_CMD; /* file conversion request */
|
|
|
-char ZF1_CMD; /* file management request */
|
|
|
-char ZF2_CMD; /* file transport request */
|
|
|
-char ZF3_CMD;
|
|
|
-rt_uint8_t Rxframeind; /* ZBIN ZBIN32, or ZHEX type of frame */
|
|
|
-rt_uint16_t Rxcount; /* received count*/
|
|
|
-char header_type; /* header type */
|
|
|
-rt_uint8_t rx_header[4]; /* received header */
|
|
|
-rt_uint8_t tx_header[4]; /* transmitted header */
|
|
|
-rt_uint32_t Rxpos; /* received file position */
|
|
|
-rt_uint32_t Txpos; /* transmitted file position */
|
|
|
-rt_uint8_t Txfcs32; /* TURE means send binary frames with 32 bit FCS */
|
|
|
-rt_uint8_t TxCRC; /* controls 32 bit CRC being sent */
|
|
|
-rt_uint8_t RxCRC; /* indicates/controls 32 bit CRC being received */ /* 0 == CRC16, 1 == CRC32, 2 == CRC32 + RLE */
|
|
|
-char Attn[ZATTNLEN+1]; /* attention string rx sends to tx on err */
|
|
|
-
|
|
|
-void zinit_parameter(void);
|
|
|
-void zsend_bin_header(rt_uint8_t type, rt_uint8_t *hdr);
|
|
|
-void zsend_hex_header(rt_uint8_t type, rt_uint8_t *hdr);
|
|
|
-void zsend_bin_data(rt_uint8_t *buf, rt_int16_t len, rt_uint8_t frameend);
|
|
|
-static rt_int16_t zrec_data16(rt_uint8_t *buf,rt_uint16_t len);
|
|
|
-static rt_int16_t zrec_data32(rt_uint8_t *buf,rt_int16_t len);
|
|
|
-static rt_int16_t zrec_data32r(rt_uint8_t *buf, rt_int16_t len);
|
|
|
-rt_int16_t zget_data(rt_uint8_t *buf, rt_uint16_t len);
|
|
|
-rt_int16_t zget_header(rt_uint8_t *hdr);
|
|
|
-static rt_int16_t zget_bin_header(rt_uint8_t *hdr);
|
|
|
-static rt_int16_t zget_bin_fcs(rt_uint8_t *hdr);
|
|
|
-rt_int16_t zget_hex_header(rt_uint8_t *hdr);
|
|
|
-static void zsend_ascii(rt_uint8_t c);
|
|
|
-void zsend_zdle_char(rt_uint16_t ch);
|
|
|
-static rt_int16_t zget_hex(void);
|
|
|
-rt_int16_t zread_byte(void);
|
|
|
-rt_int16_t zxor_read(void);
|
|
|
-void zput_pos(rt_uint32_t pos);
|
|
|
-void zget_pos(rt_uint32_t pos);
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-void zinit_parameter(void)
|
|
|
-{
|
|
|
- rt_uint8_t i;
|
|
|
-
|
|
|
- ZF0_CMD = /*CANFC32|*/CANFDX|CANOVIO; /* not chose CANFC32,CANRLE,although it have been supported */
|
|
|
- ZF1_CMD = 0; /* fix header length,not support CANVHDR */
|
|
|
- ZF2_CMD = 0;
|
|
|
- ZF3_CMD = 0;
|
|
|
- Rxframeind =0;
|
|
|
- header_type = 0;
|
|
|
- Rxcount = 0;
|
|
|
- for (i=0;i<4;i++) rx_header[i] = tx_header[i] = 0;
|
|
|
- Rxpos = Txpos = 0;
|
|
|
- RxCRC = 0;
|
|
|
- Txfcs32 = 0;
|
|
|
- return ;
|
|
|
-}
|
|
|
-
|
|
|
-/* send binary header */
|
|
|
-void zsend_bin_header(rt_uint8_t type, rt_uint8_t *hdr)
|
|
|
-{
|
|
|
- rt_uint8_t i;
|
|
|
- rt_uint32_t crc;
|
|
|
-
|
|
|
- zsend_byte(ZPAD);
|
|
|
- zsend_byte(ZDLE);
|
|
|
- TxCRC = Txfcs32;
|
|
|
- if (TxCRC == 0)
|
|
|
- {
|
|
|
- zsend_byte(ZBIN);
|
|
|
- zsend_zdle_char(type);
|
|
|
- /* add 16bits crc */
|
|
|
- crc = 0L;
|
|
|
- crc = updcrc16(type, 0);
|
|
|
- for (i=0;i<4;i++)
|
|
|
- {
|
|
|
- zsend_zdle_char(*hdr);
|
|
|
- crc = updcrc16((0377 & *hdr++),crc);
|
|
|
- }
|
|
|
- crc = updcrc16(0,updcrc16(0,crc));
|
|
|
- zsend_zdle_char(((int)(crc>>8)));
|
|
|
- zsend_zdle_char(crc);
|
|
|
- }
|
|
|
- else if(TxCRC == 1)
|
|
|
- {
|
|
|
- zsend_byte(ZBIN32);
|
|
|
- zsend_zdle_char(type);
|
|
|
- /* add 32bits crc */
|
|
|
- crc = 0xffffffffL;
|
|
|
- crc = updcrc32(type, crc);
|
|
|
- for (i=0;i<4;i++)
|
|
|
- {
|
|
|
- zsend_zdle_char(*hdr);
|
|
|
- crc = updcrc32((0377 & *hdr++), crc);
|
|
|
- }
|
|
|
- crc = ~crc;
|
|
|
- for (i=0; i<4;i++)
|
|
|
- {
|
|
|
- zsend_zdle_char(crc);
|
|
|
- crc >>= 8;
|
|
|
- }
|
|
|
- }
|
|
|
- else if (TxCRC == 2)
|
|
|
- {
|
|
|
- zsend_byte(ZBINR32);
|
|
|
- zsend_zdle_char(type);
|
|
|
- /* add 32bits crc */
|
|
|
- crc = 0xffffffffL;
|
|
|
- crc = updcrc32(type, crc);
|
|
|
- for (i=0;i<4;i++)
|
|
|
- {
|
|
|
- zsend_zdle_char(*hdr);
|
|
|
- crc = updcrc32((0377 & *hdr++), crc);
|
|
|
- }
|
|
|
- crc = ~crc;
|
|
|
- for (i=0; i<4;i++)
|
|
|
- {
|
|
|
- zsend_zdle_char(crc);
|
|
|
- crc >>= 8;
|
|
|
- }
|
|
|
- }
|
|
|
- return;
|
|
|
-}
|
|
|
-
|
|
|
-/* send hex header */
|
|
|
-void zsend_hex_header(rt_uint8_t type, rt_uint8_t *hdr)
|
|
|
-{
|
|
|
- rt_uint8_t i;
|
|
|
- rt_uint16_t crc;
|
|
|
-
|
|
|
- zsend_line(ZPAD); zsend_line(ZPAD); zsend_line(ZDLE);
|
|
|
- zsend_line(ZHEX);
|
|
|
- zsend_ascii(type);
|
|
|
- crc = updcrc16(type, 0);
|
|
|
- for (i=0; i<4; i++)
|
|
|
- {
|
|
|
- zsend_ascii(*hdr);
|
|
|
- crc = updcrc16((0377 & *hdr++), crc);
|
|
|
- }
|
|
|
- crc = updcrc16(0,updcrc16(0,crc));
|
|
|
- zsend_ascii(crc>>8);
|
|
|
- zsend_ascii(crc);
|
|
|
- /* send display control cmd */
|
|
|
- zsend_line(015); zsend_line(0212);
|
|
|
- if (type != ZFIN && type != ZACK)
|
|
|
- zsend_line(021);
|
|
|
- TxCRC = 0; /* clear tx crc type */
|
|
|
- return;
|
|
|
-}
|
|
|
-
|
|
|
-/* send binary data,with frameend */
|
|
|
-void zsend_bin_data(rt_uint8_t *buf, rt_int16_t len, rt_uint8_t frameend)
|
|
|
-{
|
|
|
- rt_int16_t i,c,tmp;
|
|
|
- rt_uint32_t crc;
|
|
|
-
|
|
|
- if (TxCRC == 0) /* send binary data with 16bits crc check */
|
|
|
- {
|
|
|
- crc = 0x0L;
|
|
|
- for (i=0;i<len;i++)
|
|
|
- {
|
|
|
- zsend_zdle_char(*buf);
|
|
|
- crc = updcrc16((0377 & *buf++), crc);
|
|
|
- }
|
|
|
- zsend_byte(ZDLE); zsend_byte(frameend);
|
|
|
- crc = updcrc16(frameend, crc);
|
|
|
- crc = updcrc16(0,updcrc16(0,crc));
|
|
|
- zsend_zdle_char(crc>>8);
|
|
|
- zsend_zdle_char(crc);
|
|
|
- }
|
|
|
- else if (TxCRC == 1) /* send binary data with 32 bits crc check */
|
|
|
- {
|
|
|
- crc = 0xffffffffL;
|
|
|
- for (i=0;i<len;i++)
|
|
|
- {
|
|
|
- c = *buf++ & 0377;
|
|
|
- zsend_zdle_char(c);
|
|
|
- crc = updcrc32(c, crc);
|
|
|
- }
|
|
|
- zsend_byte(ZDLE); zsend_byte(frameend);
|
|
|
- crc = updcrc32(frameend, crc);
|
|
|
- crc = ~crc;
|
|
|
- for (i=0;i<4;i++)
|
|
|
- {
|
|
|
- zsend_zdle_char((int)crc); crc >>= 8;
|
|
|
- }
|
|
|
- }
|
|
|
- else if (TxCRC == 2) /* send binary data with 32bits crc check,RLE encode */
|
|
|
- {
|
|
|
- crc = 0xffffffffL;
|
|
|
- tmp = *buf++ & 0377;
|
|
|
- for (i = 0; --len >= 0; ++buf)
|
|
|
- {
|
|
|
- if ((c = *buf & 0377) == tmp && i < 126 && len>0)
|
|
|
- {
|
|
|
- ++i; continue;
|
|
|
- }
|
|
|
- if (i==0)
|
|
|
- {
|
|
|
- zsend_zdle_char(tmp);
|
|
|
- crc = updcrc32(tmp, crc);
|
|
|
- if (tmp == ZRESC)
|
|
|
- {
|
|
|
- zsend_zdle_char(0100); crc = updcrc32(0100, crc);
|
|
|
- }
|
|
|
- tmp = c;
|
|
|
- }
|
|
|
- else if (i == 1)
|
|
|
- {
|
|
|
- if (tmp != ZRESC)
|
|
|
- {
|
|
|
- zsend_zdle_char(tmp); zsend_zdle_char(tmp);
|
|
|
- crc = updcrc32(tmp, crc);
|
|
|
- crc = updcrc32(tmp, crc);
|
|
|
- i = 0; tmp = c;
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- zsend_zdle_char(ZRESC); crc = updcrc32(ZRESC, crc);
|
|
|
- if (tmp == 040 && i < 34)
|
|
|
- {
|
|
|
- i += 036;
|
|
|
- zsend_zdle_char(i);
|
|
|
- crc = updcrc32(i, crc);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- i += 0101;
|
|
|
- zsend_zdle_char(i); crc = updcrc32(i, crc);
|
|
|
- zsend_zdle_char(tmp); crc = updcrc32(tmp, crc);
|
|
|
- }
|
|
|
- i = 0; tmp = c;
|
|
|
- }
|
|
|
- }
|
|
|
- zsend_byte(ZDLE); zsend_byte(frameend);
|
|
|
- crc = updcrc32(frameend, crc);
|
|
|
- crc = ~crc;
|
|
|
- for (i=0;i<4;i++)
|
|
|
- {
|
|
|
- zsend_zdle_char(crc);
|
|
|
- crc >>= 8;
|
|
|
- }
|
|
|
- }
|
|
|
- if (frameend == ZCRCW)
|
|
|
- zsend_byte(XON);
|
|
|
- return;
|
|
|
-}
|
|
|
-
|
|
|
-/* receive data,with 16bits CRC check */
|
|
|
-static rt_int16_t zrec_data16(rt_uint8_t *buf,rt_uint16_t len)
|
|
|
-{
|
|
|
- rt_int16_t c,crc_cnt;
|
|
|
- rt_uint16_t crc;
|
|
|
- rt_err_t res = -RT_ERROR;
|
|
|
- rt_uint8_t *p,flag = 0;
|
|
|
- p = buf;
|
|
|
- crc = 0L;
|
|
|
- Rxcount = 0;
|
|
|
- while(buf <= p+len)
|
|
|
- {
|
|
|
- if ((res = zread_byte()) & ~0377)
|
|
|
- {
|
|
|
- if (res == GOTCRCE || res == GOTCRCG ||
|
|
|
- res == GOTCRCQ || res == GOTCRCW)
|
|
|
- {
|
|
|
- c = res;
|
|
|
- crc = updcrc16(res&0377, crc);
|
|
|
- flag = 1;
|
|
|
- continue;
|
|
|
- }
|
|
|
- else if (res == GOTCAN) return ZCAN;
|
|
|
- else if (res == TIMEOUT) return TIMEOUT;
|
|
|
- else return res;
|
|
|
-
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- if (flag)
|
|
|
- {
|
|
|
- crc = updcrc16(res, crc);
|
|
|
- crc_cnt++;
|
|
|
- if (crc_cnt < 2) continue;
|
|
|
- if ((crc & 0xffff))
|
|
|
- {
|
|
|
-#ifdef ZDEBUG
|
|
|
- rt_kprintf("error code: CRC16 error \r\n");
|
|
|
-#endif
|
|
|
- return -RT_ERROR;
|
|
|
- }
|
|
|
- return c;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- *buf++ = res;
|
|
|
- Rxcount++;
|
|
|
- crc = updcrc16(res, crc);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- return -RT_ERROR;
|
|
|
-}
|
|
|
-
|
|
|
-/* receive data,with 32bits CRC check */
|
|
|
-static rt_int16_t zrec_data32(rt_uint8_t *buf,rt_int16_t len)
|
|
|
-{
|
|
|
- rt_int16_t c,crc_cnt = 0;
|
|
|
- rt_uint32_t crc;
|
|
|
- rt_err_t res = -RT_ERROR;
|
|
|
- rt_uint8_t *p,flag = 0;
|
|
|
-
|
|
|
- crc = 0xffffffffL;
|
|
|
- Rxcount = 0;
|
|
|
- while (buf <= p+len)
|
|
|
- {
|
|
|
- if ((res = zread_byte()) & ~0377)
|
|
|
- {
|
|
|
- if (res == GOTCRCE || res == GOTCRCG ||
|
|
|
- res == GOTCRCQ || res == GOTCRCW)
|
|
|
- {
|
|
|
- c = res;
|
|
|
- crc = updcrc32(res&0377, crc);
|
|
|
- flag = 1;
|
|
|
- continue;
|
|
|
- }
|
|
|
- else if (res == GOTCAN) return ZCAN;
|
|
|
- else if (res == TIMEOUT) return TIMEOUT;
|
|
|
- else return res;
|
|
|
-
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- if (flag)
|
|
|
- {
|
|
|
- crc = updcrc32(res, crc);
|
|
|
- crc_cnt++;
|
|
|
- if (crc_cnt < 4) continue;
|
|
|
- if ((crc & 0xDEBB20E3))
|
|
|
- {
|
|
|
-#ifdef ZDEBUG
|
|
|
- rt_kprintf("error code: CRC32 error \r\n");
|
|
|
-#endif
|
|
|
- return -RT_ERROR;
|
|
|
- }
|
|
|
- return c;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- *buf++ = res;
|
|
|
- Rxcount++;
|
|
|
- crc = updcrc32(res, crc);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- return -RT_ERROR;
|
|
|
-}
|
|
|
-/* receive data,with RLE encoded,32bits CRC check */
|
|
|
-static rt_int16_t zrec_data32r(rt_uint8_t *buf, rt_int16_t len)
|
|
|
-{
|
|
|
- rt_int16_t c,crc_cnt = 0;
|
|
|
- rt_uint32_t crc;
|
|
|
- rt_err_t res = -RT_ERROR;
|
|
|
- rt_uint8_t *p,flag = 0;
|
|
|
-
|
|
|
- crc = 0xffffffffL;
|
|
|
- Rxcount = 0;
|
|
|
- p = buf;
|
|
|
- while (buf <= p+len)
|
|
|
- {
|
|
|
- if ((res = zread_byte()) & ~0377)
|
|
|
- {
|
|
|
- if (res == GOTCRCE || res == GOTCRCG ||
|
|
|
- res == GOTCRCQ || res == GOTCRCW)
|
|
|
- {
|
|
|
- c = res;
|
|
|
- crc = updcrc32(res&0377, crc);
|
|
|
- flag = 1;
|
|
|
- continue;
|
|
|
- }
|
|
|
- else if (res == GOTCAN) return ZCAN;
|
|
|
- else if (res == TIMEOUT) return TIMEOUT;
|
|
|
- else return res;
|
|
|
-
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- if (flag)
|
|
|
- {
|
|
|
- crc = updcrc32(res, crc);
|
|
|
- crc_cnt++;
|
|
|
- if (crc_cnt < 4) continue;
|
|
|
- if ((crc & 0xDEBB20E3))
|
|
|
- {
|
|
|
-#ifdef ZDEBUG
|
|
|
- rt_kprintf("error code: CRC32 error \r\n");
|
|
|
-#endif
|
|
|
- return -RT_ERROR;
|
|
|
- }
|
|
|
- return c;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- crc = updcrc32(res, crc);
|
|
|
- switch (c)
|
|
|
- {
|
|
|
- case 0:
|
|
|
- if (res == ZRESC)
|
|
|
- {
|
|
|
- c = -1; continue;
|
|
|
- }
|
|
|
- *buf++ = res;
|
|
|
- Rxcount++;
|
|
|
- continue;
|
|
|
- case -1:
|
|
|
- if (res >= 040 && res < 0100)
|
|
|
- {
|
|
|
- c = res - 035; res = 040;
|
|
|
- goto spaces;
|
|
|
- }
|
|
|
- if (res == 0100)
|
|
|
- {
|
|
|
- c = 0;
|
|
|
- *buf++ = ZRESC;
|
|
|
- Rxcount++;
|
|
|
- continue;
|
|
|
- }
|
|
|
- c = res; continue;
|
|
|
- default:
|
|
|
- c -= 0100;
|
|
|
- if (c < 1)
|
|
|
- goto end;
|
|
|
-spaces:
|
|
|
- if ((buf + c) > p+len)
|
|
|
- goto end;
|
|
|
- while ( --res >= 0)
|
|
|
- {
|
|
|
- *buf++ = res;
|
|
|
- Rxcount++;
|
|
|
- }
|
|
|
- c = 0; continue;
|
|
|
- }
|
|
|
- }
|
|
|
- } // if -else
|
|
|
-
|
|
|
- }
|
|
|
-end:
|
|
|
- return -RT_ERROR;
|
|
|
-}
|
|
|
-rt_int16_t zget_data(rt_uint8_t *buf, rt_uint16_t len)
|
|
|
-{
|
|
|
- rt_int16_t res = -RT_ERROR;
|
|
|
-
|
|
|
- if (RxCRC == 0)
|
|
|
- {
|
|
|
- res = zrec_data16(buf,len);
|
|
|
- }
|
|
|
- else if (RxCRC == 1)
|
|
|
- {
|
|
|
- res = zrec_data32(buf, len);
|
|
|
- }
|
|
|
- else if (RxCRC == 2)
|
|
|
- {
|
|
|
- res = zrec_data32r(buf, len);
|
|
|
- }
|
|
|
- return res;
|
|
|
-}
|
|
|
-/* get type and cmd of header, fix lenght */
|
|
|
-rt_int16_t zget_header(rt_uint8_t *hdr)
|
|
|
-{
|
|
|
- rt_int16_t c,prev_char;
|
|
|
- rt_uint32_t bit;
|
|
|
- rt_uint16_t get_can,step_out;
|
|
|
-
|
|
|
- bit = get_device_speed(); /* getbaudrate */
|
|
|
- Rxframeind = header_type = 0;
|
|
|
- step_out = 0;
|
|
|
- prev_char = 0xff;
|
|
|
- for (;;)
|
|
|
- {
|
|
|
- c = zread_line(100);
|
|
|
- switch(c)
|
|
|
- {
|
|
|
- case 021:
|
|
|
- case 0221:
|
|
|
- if (prev_char == CAN) break;
|
|
|
- if (prev_char == ZCRCW) goto start_again;
|
|
|
- break;
|
|
|
- case RCDO:
|
|
|
- goto end;
|
|
|
- case TIMEOUT:
|
|
|
- if (prev_char == CAN) break;
|
|
|
- if (prev_char == ZCRCW)
|
|
|
- {
|
|
|
- c = -RT_ERROR; goto end;
|
|
|
- }
|
|
|
- goto end;
|
|
|
- case ZCRCW:
|
|
|
- if (prev_char == CAN) goto start_again;
|
|
|
- break;
|
|
|
- case CAN:
|
|
|
-get_can:
|
|
|
- if (++get_can > 5)
|
|
|
- {
|
|
|
- c = ZCAN; goto end;
|
|
|
- }
|
|
|
- break;
|
|
|
- case ZPAD:
|
|
|
- if (prev_char == CAN) break;
|
|
|
- if (prev_char == ZCRCW) goto start_again;
|
|
|
- step_out = 1;
|
|
|
- break;
|
|
|
- default:
|
|
|
- if (prev_char == CAN) break;
|
|
|
- if (prev_char == ZCRCW) goto start_again;
|
|
|
-start_again:
|
|
|
- if (--bit == 0)
|
|
|
- {
|
|
|
- c = GCOUNT; goto end;
|
|
|
- }
|
|
|
- get_can = 0;
|
|
|
- break;
|
|
|
- }
|
|
|
- prev_char = c;
|
|
|
- if (step_out) break; /* exit loop */
|
|
|
- }
|
|
|
- step_out = get_can = 0;
|
|
|
- for (;;)
|
|
|
- {
|
|
|
- c = zxor_read();
|
|
|
- switch(c)
|
|
|
- {
|
|
|
- case ZPAD:
|
|
|
- break;
|
|
|
- case RCDO:
|
|
|
- case TIMEOUT:
|
|
|
- goto end;
|
|
|
- case ZDLE:
|
|
|
- step_out = 1;
|
|
|
- break;
|
|
|
- default:
|
|
|
- goto start_again;
|
|
|
- }
|
|
|
- if (step_out) break;
|
|
|
- }
|
|
|
-
|
|
|
- Rxframeind = c = zxor_read();
|
|
|
- switch (c)
|
|
|
- {
|
|
|
- case ZBIN32:
|
|
|
- RxCRC = 1; c = zget_bin_fcs(hdr); break;
|
|
|
- case ZBINR32:
|
|
|
- RxCRC = 2; c = zget_bin_fcs(hdr); break;
|
|
|
- case ZBIN:
|
|
|
- RxCRC = 0; c = zget_bin_header(hdr); break;
|
|
|
- case ZHEX:
|
|
|
- RxCRC = 0; c = zget_hex_header(hdr); break;
|
|
|
- case CAN:
|
|
|
- goto get_can;
|
|
|
- case RCDO:
|
|
|
- case TIMEOUT:
|
|
|
- goto end;
|
|
|
- default:
|
|
|
- goto start_again;
|
|
|
- }
|
|
|
-end:
|
|
|
- return c;
|
|
|
-}
|
|
|
-
|
|
|
-/* receive a binary header */
|
|
|
-static rt_int16_t zget_bin_header(rt_uint8_t *hdr)
|
|
|
-{
|
|
|
- rt_int16_t res, i;
|
|
|
- rt_uint16_t crc;
|
|
|
-
|
|
|
- if ((res = zread_byte()) & ~0377)
|
|
|
- return res;
|
|
|
- header_type = res;
|
|
|
- crc = updcrc16(res, 0);
|
|
|
-
|
|
|
- for (i=0;i<4;i++)
|
|
|
- {
|
|
|
- if ((res = zread_byte()) & ~0377)
|
|
|
- return res;
|
|
|
- crc = updcrc16(res, crc);
|
|
|
- *hdr++ = res;
|
|
|
- }
|
|
|
- if ((res = zread_byte()) & ~0377)
|
|
|
- return res;
|
|
|
- crc = updcrc16(res, crc);
|
|
|
- if ((res = zread_byte()) & ~0377)
|
|
|
- return res;
|
|
|
- crc = updcrc16(res, crc);
|
|
|
- if (crc & 0xFFFF)
|
|
|
- {
|
|
|
- rt_kprintf("CRC error\n");
|
|
|
- return -RT_ERROR;
|
|
|
- }
|
|
|
- return header_type;
|
|
|
-}
|
|
|
-
|
|
|
-/* receive a binary header,with 32bits FCS */
|
|
|
-static rt_int16_t zget_bin_fcs(rt_uint8_t *hdr)
|
|
|
-{
|
|
|
- rt_int16_t res, i;
|
|
|
- rt_uint32_t crc;
|
|
|
-
|
|
|
- if ((res = zread_byte()) & ~0377)
|
|
|
- return res;
|
|
|
- header_type = res;
|
|
|
- crc = 0xFFFFFFFFL; crc = updcrc32(res, crc);
|
|
|
-
|
|
|
- for (i=0;i<4;i++) /* 4headers */
|
|
|
- {
|
|
|
- if ((res = zread_byte()) & ~0377)
|
|
|
- return res;
|
|
|
- crc = updcrc32(res, crc);
|
|
|
- *hdr++ = res;
|
|
|
-
|
|
|
- }
|
|
|
- for (i=0;i<4;i++) /* 4bytes crc */
|
|
|
- {
|
|
|
- if ((res = zread_byte()) & ~0377)
|
|
|
- return res;
|
|
|
- crc = updcrc32(res, crc);
|
|
|
-
|
|
|
- }
|
|
|
- if (crc != 0xDEBB20E3)
|
|
|
- {
|
|
|
-#ifdef ZDEBUG
|
|
|
- rt_kprintf("CRC error\n");
|
|
|
-#endif
|
|
|
- return -RT_ERROR;
|
|
|
- }
|
|
|
- return header_type;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-/* receive a hex style header (type and position) */
|
|
|
-rt_int16_t zget_hex_header(rt_uint8_t *hdr)
|
|
|
-{
|
|
|
- rt_int16_t res,i;
|
|
|
- rt_uint16_t crc;
|
|
|
-
|
|
|
- if ((res = zget_hex()) < 0)
|
|
|
- return res;
|
|
|
- header_type = res;
|
|
|
- crc = updcrc16(res, 0);
|
|
|
-
|
|
|
- for (i=0;i<4;i++)
|
|
|
- {
|
|
|
- if ((res = zget_hex()) < 0)
|
|
|
- return res;
|
|
|
- crc = updcrc16(res, crc);
|
|
|
- *hdr++ = res;
|
|
|
- }
|
|
|
- if ((res = zget_hex()) < 0)
|
|
|
- return res;
|
|
|
- crc = updcrc16(res, crc);
|
|
|
- if ((res = zget_hex()) < 0)
|
|
|
- return res;
|
|
|
- crc = updcrc16(res, crc);
|
|
|
- if (crc & 0xFFFF)
|
|
|
- {
|
|
|
-#ifdef ZDEBUG
|
|
|
- rt_kprintf("error code : CRC error\r\n");
|
|
|
-#endif
|
|
|
- return -RT_ERROR;
|
|
|
- }
|
|
|
- res = zread_line(100);
|
|
|
- if (res < 0)
|
|
|
- return res;
|
|
|
- res = zread_line(100);
|
|
|
- if (res < 0)
|
|
|
- return res;
|
|
|
- return header_type;
|
|
|
-}
|
|
|
-
|
|
|
-/* convert to ascii */
|
|
|
-static void zsend_ascii(rt_uint8_t c)
|
|
|
-{
|
|
|
- const char hex[] = "0123456789abcdef";
|
|
|
-
|
|
|
- zsend_line(hex[(c&0xF0)>>4]);
|
|
|
- zsend_line(hex[(c)&0xF]);
|
|
|
- return;
|
|
|
-}
|
|
|
-
|
|
|
-/*
|
|
|
- * aend character c with ZMODEM escape sequence encoding.
|
|
|
- */
|
|
|
-void zsend_zdle_char(rt_uint16_t ch)
|
|
|
-{
|
|
|
- rt_uint16_t res;
|
|
|
-
|
|
|
- res = ch & 0377;
|
|
|
- switch (res)
|
|
|
- {
|
|
|
- case 0377:
|
|
|
- zsend_byte(res);
|
|
|
- break;
|
|
|
- case ZDLE:
|
|
|
- zsend_byte(ZDLE);
|
|
|
- res ^= 0100;
|
|
|
- zsend_byte(res);
|
|
|
- break;
|
|
|
- case 021:
|
|
|
- case 023:
|
|
|
- case 0221:
|
|
|
- case 0223:
|
|
|
- zsend_byte(ZDLE);
|
|
|
- res ^= 0100;
|
|
|
- zsend_byte(res);
|
|
|
- break;
|
|
|
- default:
|
|
|
- zsend_byte(res);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-/* decode two lower case hex digits into an 8 bit byte value */
|
|
|
-static rt_int16_t zget_hex(void)
|
|
|
-{
|
|
|
- rt_int16_t res,n;
|
|
|
-
|
|
|
- if ((res = zxor_read()) < 0)
|
|
|
- return res;
|
|
|
- n = res - '0';
|
|
|
- if (n > 9)
|
|
|
- n -= ('a' - ':');
|
|
|
- if (n & ~0x0f)
|
|
|
- return -RT_ERROR;
|
|
|
- if ((res = zxor_read()) < 0)
|
|
|
- return res;
|
|
|
- res -= '0';
|
|
|
- if (res > 9)
|
|
|
- res -= ('a' - ':');
|
|
|
- if (res & ~0x0f)
|
|
|
- return -RT_ERROR;
|
|
|
- res += (n<<4);
|
|
|
- return res;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-/*
|
|
|
- * read a byte, checking for ZMODEM escape encoding
|
|
|
- * including CAN*5 which represents a quick abort
|
|
|
- */
|
|
|
-rt_int16_t zread_byte(void)
|
|
|
-{
|
|
|
- register int res;
|
|
|
-
|
|
|
-again:
|
|
|
- /* Quick check for non control characters */
|
|
|
- if ((res = zread_line(100)) & 0140)
|
|
|
- return res;
|
|
|
- switch (res)
|
|
|
- {
|
|
|
- case ZDLE:
|
|
|
- break;
|
|
|
- case 023:
|
|
|
- case 0223:
|
|
|
- case 021:
|
|
|
- case 0221:
|
|
|
- goto again;
|
|
|
- default:
|
|
|
- return res;
|
|
|
- }
|
|
|
-again2:
|
|
|
- if ((res = zread_line(100)) < 0)
|
|
|
- return res;
|
|
|
- if (res == CAN && (res = zread_line(100)) < 0)
|
|
|
- return res;
|
|
|
- if (res == CAN && (res = zread_line(100)) < 0)
|
|
|
- return res;
|
|
|
- if (res == CAN && (res = zread_line(100)) < 0)
|
|
|
- return res;
|
|
|
- switch (res)
|
|
|
- {
|
|
|
- case CAN:
|
|
|
- return GOTCAN;
|
|
|
- case ZCRCE:
|
|
|
- case ZCRCG:
|
|
|
- case ZCRCQ:
|
|
|
- case ZCRCW:
|
|
|
- return (res | GOTOR);
|
|
|
- case ZRUB0:
|
|
|
- return 0177;
|
|
|
- case ZRUB1:
|
|
|
- return 0377;
|
|
|
- case 023:
|
|
|
- case 0223:
|
|
|
- case 021:
|
|
|
- case 0221:
|
|
|
- goto again2;
|
|
|
- default:
|
|
|
- if ((res & 0140) == 0100)
|
|
|
- return (res ^ 0100);
|
|
|
- break;
|
|
|
- }
|
|
|
- return -RT_ERROR;
|
|
|
-}
|
|
|
-
|
|
|
-/*
|
|
|
- * @read a character from the modem line with timeout.
|
|
|
- * @eat parity, XON and XOFF characters.
|
|
|
- */
|
|
|
-rt_int16_t zxor_read(void)
|
|
|
-{
|
|
|
- rt_int16_t res;
|
|
|
-
|
|
|
- for (;;)
|
|
|
- {
|
|
|
- if ((res = zread_line(100)) < 0)
|
|
|
- return res;
|
|
|
- switch (res &= 0177) {
|
|
|
- case XON:
|
|
|
- case XOFF:
|
|
|
- continue;
|
|
|
- case '\r':
|
|
|
- case '\n':
|
|
|
- case ZDLE:
|
|
|
- default:
|
|
|
- return res;
|
|
|
- }
|
|
|
- }
|
|
|
- /* NOTREACHED */
|
|
|
-}
|
|
|
-
|
|
|
-/* put file posistion into the header*/
|
|
|
-void zput_pos(rt_uint32_t pos)
|
|
|
-{
|
|
|
- tx_header[ZP0] = pos;
|
|
|
- tx_header[ZP1] = pos>>8;
|
|
|
- tx_header[ZP2] = pos>>16;
|
|
|
- tx_header[ZP3] = pos>>24;
|
|
|
- return;
|
|
|
-}
|
|
|
-
|
|
|
-/* Recover a long integer from a header */
|
|
|
-void zget_pos(rt_uint32_t pos)
|
|
|
-{
|
|
|
- Rxpos = (rx_header[ZP3] & 0377);
|
|
|
- Rxpos = (Rxpos << 8) | (rx_header[ZP2] & 0377);
|
|
|
- Rxpos = (Rxpos << 8) | (rx_header[ZP1] & 0377);
|
|
|
- Rxpos = (Rxpos << 8) | (rx_header[ZP0] & 0377);
|
|
|
-}
|
|
|
-
|
|
|
-/* End of zm.c */
|