コード例 #1
0
ファイル: CRC16.cpp プロジェクト: dingxinbei/XModem
unsigned int calculate_crc(unsigned char *ptr,unsigned char datacount)
{
  unsigned int crc=0;
  while(datacount--)
	crc=xmodem_crc_check(crc,*ptr++);
  return crc;
}
コード例 #2
0
ファイル: xmodem.c プロジェクト: BackupTheBerlios/elua-svn
long xmodem_receive( char* dest, u32 limit )
{
  unsigned char xmbuf[XMODEM_BUFFER_SIZE+6];
  unsigned char seqnum=1;     // xmodem sequence number starts at 1
  unsigned short pktsize=128;   // default packet size is 128 bytes
  unsigned char response='C';   // solicit a connection with CRC
  char retry=XMODEM_RETRY_LIMIT;
  unsigned char crcflag=0;
  unsigned long totalbytes=0;
  int i,c;

  while(retry > 0)
  {
    // solicit a connection/packet
    xmodem_out_func(response);
    // wait for start of packet
    if( (c = xmodem_in_func(XMODEM_TIMEOUT_DELAY)) >= 0)
    {
      switch(c)
      {
      case SOH:
        pktsize = 128;
        break;
      case EOT:
        xmodem_flush();
        xmodem_out_func(ACK);
        // completed transmission normally
        return totalbytes;
      case CAN:
        if((c = xmodem_in_func(XMODEM_TIMEOUT_DELAY)) == CAN)
        {
          xmodem_flush();
          xmodem_out_func(ACK);
          // transaction cancelled by remote node
          return XMODEM_ERROR_REMOTECANCEL;
        }
      default:
        break;
      }
    }
    else
    {
      // timed out, try again
      // no need to flush because receive buffer is already empty
      retry--;
      //response = NAK;
      continue;
    }

    // check if CRC mode was accepted
    if(response == 'C') crcflag = 1;
    // got SOH/STX, add it to processing buffer
    xmbuf[0] = c;
    // try to get rest of packet
    for(i=0; i<(pktsize+crcflag+4-1); i++)
    {
      if((c = xmodem_in_func(XMODEM_TIMEOUT_DELAY)) >= 0)
      {
        xmbuf[1+i] = c;
      }
      else
      {
        // timed out, try again
        retry--;
        xmodem_flush();
        response = NAK;
        break;
      }
    }
    // packet was too small, retry
    if(i<(pktsize+crcflag+4-1))
      continue;

    // got whole packet
    // check validity of packet
    if(   (xmbuf[1] == (unsigned char)(~xmbuf[2])) &&     // sequence number was transmitted w/o error
      xmodem_crc_check(crcflag, &xmbuf[3], pktsize) ) // packet is not corrupt
    {
      // is this the packet we were waiting for?
      if(xmbuf[1] == seqnum)
      {
        // write/deliver data
        if( totalbytes + pktsize > limit )
        {
          // Cancel transmission
          xmodem_flush();
          xmodem_out_func(CAN);
          xmodem_out_func(CAN);
          xmodem_out_func(CAN);    
          return XMODEM_ERROR_OUTOFMEM;    
        }
        memcpy( dest + totalbytes, xmbuf + 3, pktsize );
        totalbytes += pktsize;
        // next sequence number
        seqnum++;
        // reset retries
        retry = XMODEM_RETRY_LIMIT;
        // reply with ACK
        response = ACK;
        continue;
      }
      else if(xmbuf[1] == (unsigned char)(seqnum-1))
      {
        // this is a retransmission of the last packet
        // ACK and move on
        response = ACK;
        continue;
      }
      else
      {
        // we are completely out of sync
        // cancel transmission
        xmodem_flush();
        xmodem_out_func(CAN);
        xmodem_out_func(CAN);
        xmodem_out_func(CAN);
        return XMODEM_ERROR_OUTOFSYNC;
      }
    }
    else
    {
      // packet was corrupt
      // NAK it and try again
      retry--;
      xmodem_flush();
      response = NAK;
      continue;
    }
  }

  // exceeded retry count
  xmodem_flush();
  xmodem_out_func(CAN);
  xmodem_out_func(CAN);
  xmodem_out_func(CAN);
  return XMODEM_ERROR_RETRYEXCEED;
}