xmodem c实现

来源:互联网 发布:淘宝助理旧版本下载 编辑:程序博客网 时间:2024/06/07 09:25
 

版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
http://coon-en.blogbus.com/logs/2994183.html

static unsigned char xmodem_buff[128+4];
static unsigned char xmodem_block_number;
static int xmodem_index = -1;

static int get_xmodem_frame(void)
{
TIMER timeout;
int index;
int c;

xmodem_index = -1;

set_timer(&timeout, ONE_SECOND*10 );

do {
   c = getchar();
} while(c < 0 && ! timer_expired(&timeout));

if(c < 0) {
   return -1;
}

if(c != XMODEM_SOH && c != XMODEM_EOT && c != XMODEM_CAN) {
   set_timer(&timeout, ONE_SECOND);
   do {
    c = getchar();
    if(c >= 0) {
     set_timer(&timeout, ONE_SECOND);
    }
   } while( ! timer_expired(&timeout));
   return -1;
}

index = 0;
xmodem_buff[index++] = c;

if(c == XMODEM_EOT || c == XMODEM_CAN)
{
   return 0;
}

while(index < sizeof(xmodem_buff)) {

   set_timer(&timeout, ONE_SECOND);

   do {
    c = getchar();
   } while(c < 0 && ! timer_expired(&timeout));

   if(c < 0) {
    return -1;
   }

   xmodem_buff[index++] = c;
}

xmodem_index = 0;
return 0;
}

static int xmodem_verify_frame(void)
{
int i;
unsigned char checksum;

if(xmodem_buff[0] != XMODEM_SOH) {
   return -1;
}
if(xmodem_buff[1] != xmodem_block_number) {
   return -1;
}

if(xmodem_buff[2] != ((~xmodem_block_number) & 0xff)) {
   return -1;
}

checksum = 0;

for(i = 3; i < sizeof(xmodem_buff)-1; i++) {
   checksum += xmodem_buff[i];
}

if(checksum != xmodem_buff[sizeof(xmodem_buff)-1]) {
   return -1;
}

return 0;
}

static int xmodem_get_more(void)
{
int err;
int err_retry_count;

xmodem_block_number++;
err_retry_count = 0;

while(err_retry_count < XMODEM_ERR_RETRY_COUNT)
{
   if(xmodem_index < 0) {
    putchar(XMODEM_NAK);
   }

   err = get_xmodem_frame();

   if(err == 0) {
    if(xmodem_buff[0] == XMODEM_SOH) {
     if( xmodem_verify_frame() == 0) {
      putchar(XMODEM_ACK);//uart_sendchar
      xmodem_index = 3;
      return 0;
     } else if(xmodem_buff[1] == xmodem_block_number -1) {
      putchar(XMODEM_ACK);//uart_sendchar
     } else {
      xmodem_index = -1;
     }
     err_retry_count++;
     continue;
    } else if(xmodem_buff[0] == XMODEM_EOT) {
     putchar(XMODEM_ACK);
     xmodem_index = -1;
     return -1;
    }
   }

   xmodem_index = -1;
   err_retry_count++;
}

xmodem_index = -1;
return -2;
}

static int xmodem_eof(void)
{
int i;

if(xmodem_index < 0) {
   return 1;
}

for( i = xmodem_index; i < sizeof(xmodem_buff) -1; i++) {
   if(xmodem_buff[i] != XMODEM_EOF) {
    return 0;
   }
}

if(peekchar() != XMODEM_EOT) {
   return 0;
}

return 1;
}

int xmodem_start(void)
{
xmodem_index = sizeof(xmodem_buff)-1;
xmodem_block_number = 0;

return 0;
}

int xmodem_finish(void)
{
int c;

do {
   c = xmodem_getchar();
} while(c >= 0);

return 0;
}

int xmodem_abort(void)
{
int i;

for(i=0; i<8; i++) {
   putchar(XMODEM_CAN);
}

xmodem_finish();

return 0;
}

/****************************************************************
* This is the user api call for xmodem transfers.
*
*
*/

int xmodem_getchar(void)
{
int err;
int c;
if(xmodem_index < 0) {
   return -1;
}

if(xmodem_index >= sizeof(xmodem_buff)-1) {
   err = xmodem_get_more();

   if(err < 0) {
    return err;
   }
}

c = xmodem_buff[xmodem_index];
xmodem_index++;

if(c == XMODEM_EOF) {
   if( xmodem_eof() ) {
    xmodem_finish();
    xmodem_index = -1;
    return -1;
   }
}

return c;
}


原创粉丝点击