int
xyzModem_stream_read (char *buf, int size, int *err)
{
  int stat, total, len;
  int retries;

  total = 0;
  stat = xyzModem_cancel;
  /* Try and get 'size' bytes into the buffer */
  while (!xyz.at_eof && (size > 0))
    {
      if (xyz.len == 0)
	{
	  retries = xyzModem_MAX_RETRIES;
	  while (retries-- > 0)
	    {
	      stat = xyzModem_get_hdr ();
	      if (stat == 0)
		{
		  if (xyz.blk == xyz.next_blk)
		    {
		      xyz.tx_ack = true;
		      ZM_DEBUG (zm_dprintf
				("ACK block %d (%d)\n", xyz.blk, __LINE__));
		      xyz.next_blk = (xyz.next_blk + 1) & 0xFF;

#if defined(xyzModem_zmodem) || defined(USE_YMODEM_LENGTH)
		      if (xyz.mode == xyzModem_xmodem || xyz.file_length == 0)
			{
#else
		      if (1)
			{
#endif
			  /* Data blocks can be padded with ^Z (EOF) characters */
			  /* This code tries to detect and remove them */
			  if ((xyz.bufp[xyz.len - 1] == EOF) &&
			      (xyz.bufp[xyz.len - 2] == EOF) &&
			      (xyz.bufp[xyz.len - 3] == EOF))
			    {
			      while (xyz.len
				     && (xyz.bufp[xyz.len - 1] == EOF))
				{
				  xyz.len--;
				}
			    }
			}

#ifdef USE_YMODEM_LENGTH
		      /*
		       * See if accumulated length exceeds that of the file.
		       * If so, reduce size (i.e., cut out pad bytes)
		       * Only do this for Y-modem (and Z-modem should it ever
		       * be supported since it can fall back to Y-modem mode).
		       */
		      if (xyz.mode != xyzModem_xmodem && 0 != xyz.file_length)
			{
			  xyz.read_length += xyz.len;
			  if (xyz.read_length > xyz.file_length)
			    {
			      xyz.len -= (xyz.read_length - xyz.file_length);
			    }
			}
#endif
		      break;
		    }
		  else if (xyz.blk == ((xyz.next_blk - 1) & 0xFF))
		    {
		      /* Just re-ACK this so sender will get on with it */
		      CYGACC_COMM_IF_PUTC (*xyz.__chan, ACK);
		      continue;	/* Need new header */
		    }
		  else
		    {
		      stat = xyzModem_sequence;
		    }
		}
	      if (stat == xyzModem_cancel)
		{
		  break;
		}
	      if (stat == xyzModem_eof)
		{
		  CYGACC_COMM_IF_PUTC (*xyz.__chan, ACK);
		  ZM_DEBUG (zm_dprintf ("ACK (%d)\n", __LINE__));
		  if (xyz.mode == xyzModem_ymodem)
		    {
		      CYGACC_COMM_IF_PUTC (*xyz.__chan,
					   (xyz.crc_mode ? 'C' : NAK));
		      xyz.total_retries++;
		      ZM_DEBUG (zm_dprintf ("Reading Final Header\n"));
		      stat = xyzModem_get_hdr ();
		      CYGACC_COMM_IF_PUTC (*xyz.__chan, ACK);
		      ZM_DEBUG (zm_dprintf ("FINAL ACK (%d)\n", __LINE__));
		    }
		  xyz.at_eof = true;
		  break;
		}
	      CYGACC_COMM_IF_PUTC (*xyz.__chan, (xyz.crc_mode ? 'C' : NAK));
	      xyz.total_retries++;
	      ZM_DEBUG (zm_dprintf ("NAK (%d)\n", __LINE__));
	    }
	  if (stat < 0)
	    {
	      *err = stat;
	      xyz.len = -1;
	      return total;
	    }
	}
      /* Don't "read" data from the EOF protocol package */
      if (!xyz.at_eof)
	{
	  len = xyz.len;
	  if (size < len)
	    len = size;
	  memcpy (buf, xyz.bufp, len);
	  size -= len;
	  buf += len;
	  total += len;
	  xyz.len -= len;
	  xyz.bufp += len;
	}
    }
  return total;
}

void
xyzModem_stream_close (int *err)
{
  diag_printf
    ("xyzModem - %s mode, %d(SOH)/%d(STX)/%d(CAN) packets, %d retries\n",
     xyz.crc_mode ? "CRC" : "Cksum", xyz.total_SOH, xyz.total_STX,
     xyz.total_CAN, xyz.total_retries);
  ZM_DEBUG (zm_flush ());
}
示例#2
0
int
xyzModem_stream_read (char *buf, int size, int *err)
{
    int stat, total, len;
    int retries;

    total = 0;
    stat = xyzModem_cancel;
    /* Try and get 'size' bytes into the buffer */
    while (!xyz.at_eof && (size > 0))
    {
        if (xyz.len == 0)
        {
            retries = xyzModem_MAX_RETRIES;
            while (retries-- > 0)
            {
                stat = xyzModem_get_hdr ();
                if (stat == 0)
                {
                    if (xyz.blk == xyz.next_blk)
                    {
                        xyz.tx_ack = true;
                        ZM_DEBUG (zm_dprintf
                                  ("ACK block %d (%d)\n", xyz.blk, __LINE__));
                        xyz.next_blk = (xyz.next_blk + 1) & 0xFF;

#if defined(xyzModem_zmodem) || defined(USE_YMODEM_LENGTH)
                        if (xyz.mode == xyzModem_xmodem || xyz.file_length == 0)
                        {
#else
                        if (1)
                        {
#endif
                            /* Data blocks can be padded with ^Z (EOF) characters */
                            /* This code tries to detect and remove them */
                            if ((xyz.bufp[xyz.len - 1] == EOF) &&
                                    (xyz.bufp[xyz.len - 2] == EOF) &&
                                    (xyz.bufp[xyz.len - 3] == EOF))
                            {
                                while (xyz.len
                                        && (xyz.bufp[xyz.len - 1] == EOF))
                                {
                                    xyz.len--;
                                }
                            }
                        }

#ifdef USE_YMODEM_LENGTH
                        /*
                         * See if accumulated length exceeds that of the file.
                         * If so, reduce size (i.e., cut out pad bytes)
                         * Only do this for Y-modem (and Z-modem should it ever
                         * be supported since it can fall back to Y-modem mode).
                         */
                        if (xyz.mode != xyzModem_xmodem && 0 != xyz.file_length)
                        {
                            xyz.read_length += xyz.len;
                            if (xyz.read_length > xyz.file_length)
                            {
                                xyz.len -= (xyz.read_length - xyz.file_length);
                            }
                        }
#endif
                        break;
                    }
                    else if (xyz.blk == ((xyz.next_blk - 1) & 0xFF))
                    {
                        /* Just re-ACK this so sender will get on with it */
                        CYGACC_COMM_IF_PUTC (*xyz.__chan, ACK);
                        continue;	/* Need new header */
                    }
                    else
                    {
                        stat = xyzModem_sequence;
                    }
                }
                if (stat == xyzModem_cancel)
                {
                    break;
                }
                if (stat == xyzModem_eof)
                {
                    CYGACC_COMM_IF_PUTC (*xyz.__chan, ACK);
                    ZM_DEBUG (zm_dprintf ("ACK (%d)\n", __LINE__));
                    if (xyz.mode == xyzModem_ymodem)
                    {
                        CYGACC_COMM_IF_PUTC (*xyz.__chan,
                                             (xyz.crc_mode ? 'C' : NAK));
                        xyz.total_retries++;
                        ZM_DEBUG (zm_dprintf ("Reading Final Header\n"));
                        stat = xyzModem_get_hdr ();
                        CYGACC_COMM_IF_PUTC (*xyz.__chan, ACK);
                        ZM_DEBUG (zm_dprintf ("FINAL ACK (%d)\n", __LINE__));
                    }
                    xyz.at_eof = true;
                    break;
                }
                CYGACC_COMM_IF_PUTC (*xyz.__chan, (xyz.crc_mode ? 'C' : NAK));
                xyz.total_retries++;
                ZM_DEBUG (zm_dprintf ("NAK (%d)\n", __LINE__));
            }
            if (stat < 0)
            {
                *err = stat;
                xyz.len = -1;
                return total;
            }
        }
        /* Don't "read" data from the EOF protocol package */
        if (!xyz.at_eof)
        {
            len = xyz.len;
            if (size < len)
                len = size;
            memcpy (buf, xyz.bufp, len);
            size -= len;
            buf += len;
            total += len;
            xyz.len -= len;
            xyz.bufp += len;
        }
    }
    return total;
}

int
xyzModem_stream_write(ulong src,long size)
{
    char c;
    unsigned char  *psrc;
    unsigned short cksum;
    int ultlen = 0;
    int total = 0;
    int retry, i, res;
    int flag_ok = 0;
    int flag_frame = 0;
    psrc =(unsigned char *)src;
    xyz.blk  = 1;
    xyz.cblk = ~xyz.blk;
    xyz.len  = xyzModem_1k;

    for (retry = 0; retry < 300; ++retry) {
        res = CYGACC_COMM_IF_GETC_TIMEOUT (*xyz.__chan, &c);
        if (res) {
            switch (c) {
            case 'C':
                xyz.crc_mode = true;
                flag_ok = 1;
                ZM_DEBUG (zm_dprintf ("Receive char CRC***\n"));
                break;
            case NAK:
                xyz.crc_mode = false;
                flag_ok = 1;
                ZM_DEBUG (zm_dprintf ("Receive char NAK***\n"));
                break;
            case CAN:
                ZM_DEBUG (zm_dprintf ("Receive char cancel***\n"));
                CYGACC_COMM_IF_GETC_TIMEOUT (*xyz.__chan, &c);
                if (c == CAN) {
                    serial_putc_raw(ACK);
                    xyzModem_flush ();
                    return -1;
                }
                break;
            default:
                ZM_DEBUG (zm_dprintf ("Receive  char %x***\n",c));
                break;
            }
        }
        if (flag_ok == 1)
            break;
    }

    if (flag_ok == 0) {
        serial_putc_raw(CAN);
        serial_putc_raw(CAN);
        serial_putc_raw(CAN);
        xyzModem_flush ();
        return -2;
    }

    while(1) {
        flag_frame = 0;
        ultlen = size - total;

        if (ultlen > xyz.len)
            ultlen = xyz.len;

        if (ultlen > 0) {
            memcpy (xyz.pkt, &psrc[total], ultlen);
            if (ultlen < xyz.len) {
                memset (&xyz.pkt[ultlen], EOF, xyz.len-ultlen);
            }

            if (xyz.crc_mode) {
                cksum = cyg_crc16(xyz.pkt, xyz.len);
                xyz.crc1 = (cksum >> 8) & 0xFF;
                xyz.crc2 = cksum & 0xFF;
                ZM_DEBUG (zm_dprintf ("add crc check***\n"));
            } else {
int
xyzModem_stream_open (connection_info_t * info, int *err)
{
#ifdef REDBOOT
  int console_chan;
#endif
  int stat = 0;
  int retries = xyzModem_MAX_RETRIES;
  int crc_retries = xyzModem_MAX_RETRIES_WITH_CRC;

/*    ZM_DEBUG(zm_out = zm_out_start); */
#ifdef xyzModem_zmodem
  if (info->mode == xyzModem_zmodem)
    {
      *err = xyzModem_noZmodem;
      return -1;
    }
#endif

#ifdef REDBOOT
  /* Set up the I/O channel.  Note: this allows for using a different port in the future */
  console_chan =
    CYGACC_CALL_IF_SET_CONSOLE_COMM
    (CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
  if (info->chan >= 0)
    {
      CYGACC_CALL_IF_SET_CONSOLE_COMM (info->chan);
    }
  else
    {
      CYGACC_CALL_IF_SET_CONSOLE_COMM (console_chan);
    }
  xyz.__chan = CYGACC_CALL_IF_CONSOLE_PROCS ();

  CYGACC_CALL_IF_SET_CONSOLE_COMM (console_chan);
  CYGACC_COMM_IF_CONTROL (*xyz.__chan, __COMMCTL_SET_TIMEOUT,
			  xyzModem_CHAR_TIMEOUT);
#else
/* TODO: CHECK ! */
  int dummy;
  xyz.__chan = &dummy;
#endif
  xyz.len = 0;
  xyz.crc_mode = true;
  xyz.at_eof = false;
  xyz.tx_ack = false;
  xyz.mode = info->mode;
  xyz.total_retries = 0;
  xyz.total_SOH = 0;
  xyz.total_STX = 0;
  xyz.total_CAN = 0;
#ifdef USE_YMODEM_LENGTH
  xyz.read_length = 0;
  xyz.file_length = 0;
#endif

  CYGACC_COMM_IF_PUTC (*xyz.__chan, (xyz.crc_mode ? 'C' : NAK));

  if (xyz.mode == xyzModem_xmodem)
    {
      /* X-modem doesn't have an information header - exit here */
      xyz.next_blk = 1;
      return 0;
    }

  while (retries-- > 0)
    {
      stat = xyzModem_get_hdr ();
      if (stat == 0)
	{
	  /* Y-modem file information header */
	  if (xyz.blk == 0)
	    {
#ifdef USE_YMODEM_LENGTH
	      /* skip filename */
	      while (*xyz.bufp++);
	      /* get the length */
	      parse_num ((char *) xyz.bufp, &xyz.file_length, NULL, " ");
#endif
	      /* The rest of the file name data block quietly discarded */
	      xyz.tx_ack = true;
	    }
	  xyz.next_blk = 1;
	  xyz.len = 0;
	  return 0;
	}
      else if (stat == xyzModem_timeout)
	{
	  if (--crc_retries <= 0)
	    xyz.crc_mode = false;
	  CYGACC_CALL_IF_DELAY_US (5 * 100000);	/* Extra delay for startup */
	  CYGACC_COMM_IF_PUTC (*xyz.__chan, (xyz.crc_mode ? 'C' : NAK));
	  xyz.total_retries++;
	  ZM_DEBUG (zm_dprintf ("NAK (%d)\n", __LINE__));
	}
      if (stat == xyzModem_cancel)
	{
	  break;
	}
    }
  *err = stat;
  ZM_DEBUG (zm_flush ());
  return -1;
}
示例#4
0
int xyzModem_stream_open(connection_info_t *info, int *err)
{
	int stat = 0;
	int retries = xyzModem_MAX_RETRIES;
	int crc_retries = xyzModem_MAX_RETRIES_WITH_CRC;

#ifdef xyzModem_zmodem
	if(info->mode == xyzModem_zmodem){
		*err = xyzModem_noZmodem;
		return -1;
	}
#endif

/* TODO: CHECK ! */
	int dummy;
	xyz.__chan=&dummy;
	xyz.len = 0;
	xyz.crc_mode = 1;
	xyz.at_eof = 0;
	xyz.tx_ack = 0;
	xyz.mode = info->mode;
	xyz.total_retries = 0;
	xyz.total_SOH = 0;
	xyz.total_STX = 0;
	xyz.total_CAN = 0;
#ifdef USE_YMODEM_LENGTH
	xyz.read_length = 0;
	xyz.file_length = 0;
#endif

	putc(xyz.crc_mode ? 'C' : NAK);

	if(xyz.mode == xyzModem_xmodem){
		/* X-modem doesn't have an information header - exit here */
		xyz.next_blk = 1;
		return 0;
	}

	while(retries-- > 0){
		stat = xyzModem_get_hdr();
		if(stat == 0){
			/* Y-modem file information header */
			if(xyz.blk == 0){
#ifdef USE_YMODEM_LENGTH
				/* skip filename */
				while(*xyz.bufp++);

				/* get the length */
				parse_num((char *)xyz.bufp, &xyz.file_length, NULL, " ");
#endif
				/* The rest of the file name data block quietly discarded */
				xyz.tx_ack = 1;
			}

			xyz.next_blk = 1;
			xyz.len = 0;

			return 0;
		} else if(stat == xyzModem_timeout){
			if(--crc_retries <= 0)
				xyz.crc_mode = 0;

			/* Extra delay for startup */
			udelay(5*100000);

			putc(xyz.crc_mode ? 'C' : NAK);
			xyz.total_retries++;
		}

		if(stat == xyzModem_cancel){
			break;
		}
	}

	*err = stat;

	return -1;
}