* the GNU General Public License.
*
* Copyright 2004, 2005, 2006, 2007 Develer S.r.l. (http://www.develer.com/)
- * Copyright 1999, 2001 Bernardo Innocenti <bernie@develer.com>
+ * Copyright 1999, 2001 Bernie Innocenti <bernie@codewiz.org>
*
* -->
*
*
* \todo Break xmodem_send() and xmodem_recv() in smaller functions.
*
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
+ * \author Bernie Innocenti <bernie@codewiz.org>
* \author Francesco Sacchi <batt@develer.com>
*/
#include "xmodem.h"
+#include "cfg/cfg_xmodem.h"
+
#include <cfg/debug.h>
-#include <cfg/cfg_xmodem.h>
+// Define log settings for cfg/log.h
+#define LOG_LEVEL CONFIG_XMODEM_LOG_LEVEL
+#define LOG_FORMAT CONFIG_XMODEM_LOG_FORMAT
+#include <cfg/log.h>
-#include <drv/ser.h>
#include <algo/crc.h>
#define XM_CAN 0x18 /**< CANcel transmission */
/*\}*/
-#define XM_MAXRETRIES 15 /**< Max retries before giving up */
-#define XM_MAXCRCRETRIES 7 /**< Max retries before switching to BCC */
-
#if CONFIG_XMODEM_1KCRC == 1
#define XM_BUFSIZE 1024 /**< 1024 bytes of block buffer */
#else
/**
* \brief Receive a file using the XModem protocol.
*
- * \param port Serial port to use for transfer
+ * \param ch Channel to use for transfer
* \param fd Destination file
*
* \note This function allocates a large amount of stack (\see XM_BUFSIZE).
*/
-bool xmodem_recv(struct KFileSerial *port, KFile *fd)
+bool xmodem_recv(KFile *ch, KFile *fd)
{
char block_buffer[XM_BUFSIZE]; /* Buffer to hold a block of data */
int c, i, blocksize;
bool usecrc = true;
- XMODEM_PROGRESS("Starting Transfer...\n");
+ LOG_INFO("Starting Transfer...\n");
purge = true;
- kfile_clearerr(&port->fd);
+ kfile_clearerr(ch);
/* Send initial NAK to start transmission */
for(;;)
{
if (XMODEM_CHECK_ABORT)
{
- kfile_putc(XM_CAN, &port->fd);
- kfile_putc(XM_CAN, &port->fd);
- XMODEM_PROGRESS("Transfer aborted\n");
+ kfile_putc(XM_CAN, ch);
+ kfile_putc(XM_CAN, ch);
+ LOG_INFO("Transfer aborted\n");
return false;
}
{
purge = false;
- if (kfile_error(&port->fd))
- XMODEM_PROGRESS("Retries %d\n", retries);
+ if (kfile_error(ch))
+ {
+ LOG_ERR("Retries %d\n", retries);
+ }
- ser_resync(port, 200);
+ kfile_resync(ch, 200);
retries++;
- if (retries >= XM_MAXRETRIES)
+ if (retries >= CONFIG_XMODEM_MAXRETRIES)
{
- kfile_putc(XM_CAN, &port->fd);
- kfile_putc(XM_CAN, &port->fd);
- XMODEM_PROGRESS("Transfer aborted\n");
+ kfile_putc(XM_CAN, ch);
+ kfile_putc(XM_CAN, ch);
+ LOG_INFO("Transfer aborted\n");
return false;
}
/* Transmission start? */
if (blocknr == 0)
{
- if (retries < XM_MAXCRCRETRIES)
+ if (retries < CONFIG_XMODEM_MAXCRCRETRIES)
{
- XMODEM_PROGRESS("Request Tx (CRC)\n");
- kfile_putc(XM_C, &port->fd);
+ LOG_INFO("Request Tx (CRC)\n");
+ kfile_putc(XM_C, ch);
}
else
{
/* Give up with CRC and fall back to checksum */
usecrc = false;
- XMODEM_PROGRESS("Request Tx (BCC)\n");
- kfile_putc(XM_NAK, &port->fd);
+ LOG_INFO("Request Tx (BCC)\n");
+ kfile_putc(XM_NAK, ch);
}
}
else
- kfile_putc(XM_NAK, &port->fd);
+ kfile_putc(XM_NAK, ch);
}
- switch (kfile_getc(&port->fd))
+ switch (kfile_getc(ch))
{
#if XM_BUFSIZE >= 1024
case XM_STX: /* Start of header (1024-byte block) */
getblock:
/* Get block number */
- c = kfile_getc(&port->fd);
+ c = kfile_getc(ch);
/* Check complemented block number */
- if ((~c & 0xff) != kfile_getc(&port->fd))
+ if ((~c & 0xff) != kfile_getc(ch))
{
- XMODEM_PROGRESS("Bad blk (%d)\n", c);
+ LOG_WARN("Bad blk (%d)\n", c);
purge = true;
break;
}
/* Determine which block is being sent */
if (c == (blocknr & 0xff))
+ {
/* Last block repeated */
- XMODEM_PROGRESS("Repeat blk %d\n", blocknr);
+ LOG_INFO("Repeat blk %d\n", blocknr);
+ }
else if (c == ((blocknr + 1) & 0xff))
+ {
/* Next block */
- XMODEM_PROGRESS("Recv blk %d\n", ++blocknr);
+ LOG_INFO("Recv blk %d\n", ++blocknr);
+ }
else
{
/* Sync lost */
- XMODEM_PROGRESS("Sync lost (%d/%d)\n", c, blocknr);
+ LOG_WARN("Sync lost (%d/%d)\n", c, blocknr);
purge = true;
break;
}
crc = 0;
for (i = 0; i < blocksize; i++)
{
- if ((c = kfile_getc(&port->fd)) == EOF)
+ if ((c = kfile_getc(ch)) == EOF)
{
purge = true;
break;
break;
/* Get the checksum byte or the CRC-16 MSB */
- if ((c = kfile_getc(&port->fd)) == EOF)
+ if ((c = kfile_getc(ch)) == EOF)
{
purge = true;
break;
crc = UPDCRC16(c, crc);
/* Get CRC-16 LSB */
- if ((c = kfile_getc(&port->fd)) == EOF)
+ if ((c = kfile_getc(ch)) == EOF)
{
purge = true;
break;
if (crc)
{
- XMODEM_PROGRESS("Bad CRC: %04x\n", crc);
+ LOG_ERR("Bad CRC: %04x\n", crc);
purge = true;
break;
}
/* Compare the checksum */
else if (c != checksum)
{
- XMODEM_PROGRESS("Bad sum: %04x/%04x\n", checksum, c);
+ LOG_ERR("Bad sum: %04x/%04x\n", checksum, c);
purge = true;
break;
}
if (last_block_done < blocknr)
{
/* Call user function to flush the buffer */
- if (kfile_write(fd, block_buffer, blocksize))
+ if (kfile_write(fd, block_buffer, blocksize) == (size_t)blocksize)
{
/* Acknowledge block and clear error counter */
- kfile_putc(XM_ACK, &port->fd);
+ kfile_putc(XM_ACK, ch);
retries = 0;
last_block_done = blocknr;
}
else
{
/* User callback failed: abort transfer immediately */
- retries = XM_MAXRETRIES;
+ retries = CONFIG_XMODEM_MAXRETRIES;
purge = true;
}
}
break;
case XM_EOT: /* End of transmission */
- kfile_putc(XM_ACK, &port->fd);
- XMODEM_PROGRESS("Transfer completed\n");
+ kfile_putc(XM_ACK, ch);
+ LOG_INFO("Transfer completed\n");
return true;
case EOF: /* Timeout or serial error */
break;
default:
- XMODEM_PROGRESS("Skipping garbage\n");
+ LOG_INFO("Skipping garbage\n");
purge = true;
break;
}
/**
* \brief Transmit some data using the XModem protocol.
*
- * \param port Serial port to use for transfer
+ * \param ch Channel to use for transfer
* \param fd Source file
*
* \note This function allocates a large amount of stack for
* the XModem transfer buffer (\see XM_BUFSIZE).
*/
-bool xmodem_send(struct KFileSerial *port, KFile *fd)
+bool xmodem_send(KFile *ch, KFile *fd)
{
char block_buffer[XM_BUFSIZE]; /* Buffer to hold a block of data */
size_t size = -1;
*/
size = kfile_read(fd, block_buffer, XM_BUFSIZE);
- kfile_clearerr(&port->fd);
- ser_purge(port);
- XMODEM_PROGRESS("Wait remote host\n");
+ kfile_clearerr(ch);
+ LOG_INFO("Wait remote host\n");
for(;;)
{
if (XMODEM_CHECK_ABORT)
return false;
- switch (c = kfile_getc(&port->fd))
+ switch (c = kfile_getc(ch))
{
case XM_NAK:
- XMODEM_PROGRESS("Resend blk %d\n", blocknr);
+ LOG_INFO("Resend blk %d\n", blocknr);
proceed = true;
break;
case XM_C:
if (c == XM_C)
{
- XMODEM_PROGRESS("Tx start (CRC)\n");
+ LOG_INFO("Tx start (CRC)\n");
usecrc = true;
}
else
- XMODEM_PROGRESS("Tx start (BCC)\n");
+ {
+ LOG_INFO("Tx start (BCC)\n");
+ }
proceed = true;
break;
/* Call user function to read in one block */
size = kfile_read(fd, block_buffer, XM_BUFSIZE);
- XMODEM_PROGRESS("Send blk %d\n", blocknr);
+ LOG_INFO("Send blk %d\n", blocknr);
blocknr++;
retries = 0;
proceed = true;
break;
case EOF:
- kfile_clearerr(&port->fd);
+ kfile_clearerr(ch);
retries++;
- XMODEM_PROGRESS("Retries %d\n", retries);
- if (retries <= XM_MAXRETRIES)
+ LOG_INFO("Retries %d\n", retries);
+ if (retries <= CONFIG_XMODEM_MAXRETRIES)
break;
/* falling through! */
case XM_CAN:
- XMODEM_PROGRESS("Transfer aborted\n");
+ LOG_INFO("Transfer aborted\n");
return false;
default:
- XMODEM_PROGRESS("Skipping garbage\n");
+ LOG_INFO("Skipping garbage\n");
break;
}
}
if (!size)
{
- kfile_putc(XM_EOT, &port->fd);
+ kfile_putc(XM_EOT, ch);
continue;
}
/* Send block header (STX, blocknr, ~blocknr) */
#if XM_BUFSIZE == 128
- kfile_putc(XM_SOH, &port->fd);
+ kfile_putc(XM_SOH, ch);
#else
- kfile_putc(XM_STX, &port->fd);
+ kfile_putc(XM_STX, ch);
#endif
- kfile_putc(blocknr & 0xFF, &port->fd);
- kfile_putc(~blocknr & 0xFF, &port->fd);
+ kfile_putc(blocknr & 0xFF, ch);
+ kfile_putc(~blocknr & 0xFF, ch);
/* Send block and compute its CRC/checksum */
sum = 0;
crc = 0;
for (i = 0; i < XM_BUFSIZE; i++)
{
- kfile_putc(block_buffer[i], &port->fd);
+ kfile_putc(block_buffer[i], ch);
crc = UPDCRC16(block_buffer[i], crc);
sum += block_buffer[i];
}
/* Send CRC/Checksum */
if (usecrc)
{
- crc = UPDCRC16(0, crc);
- crc = UPDCRC16(0, crc);
- kfile_putc(crc >> 8, &port->fd);
- kfile_putc(crc & 0xFF, &port->fd);
+ kfile_putc(crc >> 8, ch);
+ kfile_putc(crc & 0xFF, ch);
}
else
- kfile_putc(sum, &port->fd);
+ kfile_putc(sum, ch);
}
}
#endif