Skip to content
Snippets Groups Projects
Commit 7576163f authored by Gregory Nutt's avatar Gregory Nutt
Browse files

More Zmodem bugfixes and new files

parent ac1efbab
No related branches found
No related tags found
No related merge requests found
......@@ -53,6 +53,15 @@
* Pre-processor Definitions
****************************************************************************/
/* Configuration ************************************************************/
/* The default device used by the Zmodem commands if the -d option is not
* provided on the sz or rz command line.
*/
#ifndef CONFIG_SYSTEM_ZMODEM_DEVNAME
# define CONFIG_SYSTEM_ZMODEM_DEVNAME "/dev/console"
#endif
/* The size of one buffer used to read data from the remote peer */
#ifndef CONFIG_SYSTEM_ZMODEM_RCVBUFSIZE
......@@ -165,16 +174,41 @@ extern "C"
* remfd - The R/W file/socket descriptor to use for communication with the
* remote peer.
*
* Returned Value:
* An opaque handle that can be use with zmr_receive() and zmr_release().
*
****************************************************************************/
ZMRHANDLE zmr_initialize(int remfd);
/****************************************************************************
* Name: zmr_receive
*
* Description:
* Receive file(s) sent from the remote peer.
*
* Input Parameters:
* handle - The handler created by zmr_initialize().
*
* Returned Value:
* Zero on success; a negated errno value on failure.
*
****************************************************************************/
int zmr_receive(ZMRHANDLE handle);
/****************************************************************************
* Name: zmr_release
*
* Description:
* Called by the user when there are no more files to receive.
*
* Input Parameters:
* handle - The handler created by zmr_initialize().
*
* Returned Value:
* Zero on success; a negated errno value on failure.
*
****************************************************************************/
int zmr_release(ZMRHANDLE);
......@@ -198,6 +232,9 @@ int zmr_release(ZMRHANDLE);
* remfd - The R/W file/socket descriptor to use for communication with the
* remote peer.
*
* Returned Value:
* An opaque handle that can be use with zmx_send() and zms_release()
*
****************************************************************************/
ZMSHANDLE zms_initialize(int remfd);
......@@ -209,12 +246,15 @@ ZMSHANDLE zms_initialize(int remfd);
* Send a file.
*
* Input Parameters:
* handle - Handle previoulsy returned by xms_initialize()
* filename - The name of the local file to transfer
* handle - Handle previoulsy returned by xms_initialize()
* filename - The name of the local file to transfer
* rfilename - The name of the remote file name to create
* option - Describes optional transfer behavior
* f1 - The F1 transfer flags
* skip - True: Skip if file not present at receiving end.
* option - Describes optional transfer behavior
* f1 - The F1 transfer flags
* skip - True: Skip if file not present at receiving end.
*
* Returned Value:
* Zero on success; a negated errno value on failure.
*
****************************************************************************/
......@@ -228,6 +268,12 @@ int zms_send(ZMSHANDLE handle, FAR const char *filename,
* Description:
* Called by the user when there are no more files to send.
*
* Input Parameters:
* handle - The handler created by zms_initialize().
*
* Returned Value:
* Zero on success; a negated errno value on failure.
*
****************************************************************************/
int zms_release(ZMSHANDLE handle);
......@@ -240,6 +286,9 @@ int zms_release(ZMSHANDLE handle);
* must provide the following interface in order to enable/disable hardware
* flow control on the device used to communicate with the remote peer.
*
* Returned Value:
* Zero on success; a negated errno value on failure.
*
****************************************************************************/
#ifdef CONFIG_SYSTEM_ZMODEM_FULLSTREAMING
......
......@@ -11,6 +11,13 @@ config SYSTEM_ZMODEM
if SYSTEM_ZMODEM
config SYSTEM_ZMODEM_DEVNAME
string "Default Zmodem device"
default "/dev/console"
---help--
The default device used by the Zmodem commands if the -d option is
not provided on the sz or rz command line. Default: "/dev/console".
config SYSTEM_ZMODEM_RCVBUFSIZE
int "Receive buffer size"
default 512
......@@ -36,9 +43,12 @@ config SYSTEM_ZMODEM_MOUNTPOINT
string "Zmodem sandbox"
default "/tmp"
---help---
Absolute pathes are not accepted. This configuration value must be
set to provide the path to the file storage directory (such as a
mountpoint directory).
Absolute pathes in received file names are not accepted. This
configuration value must be set to provide the path to the file
storage directory (such as a mountpoint directory).
Names of file send by the sz commond, on the other hand, must be
absolute paths beginning with '/'.
config SYSTEM_ZMODEM_SENDSAMPLE
bool "Reverse channel"
......
......@@ -44,13 +44,13 @@ endif
# Zmodem sz and rz commands
PRIORITY = SCHED_PRIORITY_DEFAULT
STACKSIZE = 768
STACKSIZE = 1536
ASRCS =
CSRCS = sz_main.c
CSRCS = sz_main.c zm_send.c
CSRCS += rz_main.c
CSRCS += zm_proto.c zm_watchdog.c zm_utils.c zm_dumpbuffer.c
CSRCS += zm_state.c zm_proto.c zm_watchdog.c zm_utils.c zm_dumpbuffer.c
AOBJS = $(ASRCS:.S=$(OBJEXT))
COBJS = $(CSRCS:.c=$(OBJEXT))
......
README
======
Using NuttX Zmodem with a Linux Host
====================================
The NuttX Zmodem commands have been verified against the rzsz programs
running on a Linux PC. To send a file to the PC, first make sure that
the serial port is configured to work with the board:
$ sudo stty -F /dev/ttyS0 57600
$ sudo stty -F /dev/ttyS0
start rz on the Linux host:
$ sudo rz </dev/ttyS0 >/dev/ttyS0
You can add the rz -v option multiple times, each increases the level
of debug output. If you want to capture the Linux rz output, then
re-direct stderr to a log file by adding 2>rz.log to the end of the
rz command.
NOTE: The NuttX Zmodem does sends rz\n when it starts in compliance with
the Zmodem specification. On Linux this, however, seems to start some
other, incompatible version of rz. You need to start rz manually to
make sure that the correct version is selected. You can tell when this
evil rz/sz has inserted itself because you will see the '^' (0x5e)
character replacing the standard Zmodem ZDLE character (0x19) in the
binary data stream.
If you don't have the rz command on your Linux box, the package to
install rzsz (or possibily lrzsz).
Then on the target:
> sz -d /dev/ttyS1 <filename>
Where filename is the full path to the file to send (i.e., it begins
with the '/' character).
\ No newline at end of file
......@@ -42,8 +42,10 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <fcntl.h>
#include <libgen.h>
#include <time.h>
#include <errno.h>
......@@ -55,11 +57,13 @@
static void show_usage(FAR const char *progname, int errcode)
{
fprintf(stderr, "USAGE: %s [OPTIONS] <lname> [<lname> [<lname> ...]]\n", progname);
fprintf(stderr, "USAGE: %s [OPTIONS] <lname> [<lname> [<lname> ...]]\n",
progname);
fprintf(stderr, "\nWhere:\n");
fprintf(stderr, "\t<lname> is the local file name\n");
fprintf(stderr, "\nand OPTIONS include the following:\n");
fprintf(stderr, "\t-d <device>: Communication device to use. Default /dev/console\n");
fprintf(stderr, "\t-d <device>: Communication device to use. Default: %s\n",
CONFIG_SYSTEM_ZMODEM_DEVNAME);
fprintf(stderr, "\t-r <rname>: Remote file name. Default <lname>\n");
fprintf(stderr, "\t-x <mode>: Transfer type\n");
fprintf(stderr, "\t\t0: Normal file (default)\n");
......@@ -91,7 +95,7 @@ int sz_main(int argc, FAR char **argv)
enum zm_option_e xfroption = XM_OPTION_REPLACE;
ZMSHANDLE handle;
FAR const char *rname = NULL;
FAR const char *devname = "/dev/console";
FAR const char *devname = CONFIG_SYSTEM_ZMODEM_DEVNAME;
FAR char *endptr;
bool skip = false;
long tmp;
......@@ -197,11 +201,44 @@ int sz_main(int argc, FAR char **argv)
*/
FAR const char *nextlname = argv[optind];
FAR const char *nextrname = rname ? rname : nextlname;
FAR const char *nextrname;
FAR char *ralloc;
/* Get the next remote file name */
nextrname = rname;
ralloc = NULL;
if (!nextrname)
{
/* No remote filename, use the basename of the local filename.
* NOTE: that we have to duplicate the local filename to do this
* because basename() modifies the original string.
*/
ralloc = strdup(nextlname);
if (!ralloc)
{
fprintf(stderr, "ERROR: Out-of-memory\n");
goto errout_with_device;
}
nextrname = basename(ralloc);
}
/* Transfer the file */
ret = zms_send(handle, nextlname, nextrname, xfrtype, xfroption, skip);
/* Free any allocations made for the remote file name */
if (ralloc)
{
free(ralloc);
}
/* Check if the transfer was successful */
if (ret < 0)
{
fprintf(stderr, "ERROR: Transfer of %s failed: %d\n",
......
......@@ -200,7 +200,7 @@
#define ZM_FLAG_APPEND (1 << 8) /* Append to the existing file */
#define ZM_FLAG_TIMEOUT (1 << 9) /* A timeout has been detected */
/* zm_parse() success/error return code definitions:
/* The Zmodem parser success/error return code definitions:
*
* < 0 : Transfer terminated due to an error
* = 0 : Transfer still in progress
......@@ -694,19 +694,17 @@ int zm_sendbinhdr(FAR struct zm_state_s *pzm, int type,
FAR const uint8_t *buffer);
/****************************************************************************
* Name: zm_parse
* Name: zm_datapump
*
* Description:
* New data from the remote peer is available in pzm->rcvbuf. The number
* number of bytes of new data is given by rcvlen.
*
* This function will parse the data in the buffer and, based on the
* current state and the contents of the buffer, will drive the Zmodem
* state machine.
* Drive the Zmodem state machine by reading data from the remote peer and
* providing that data to the parser. This loop runs until a fatal error
* is detected or until the state machine reports that the transfer has
* completed successfully.
*
****************************************************************************/
int zm_parse(FAR struct zm_state_s *pzm, size_t rcvlen);
int zm_datapump(FAR struct zm_state_s *pzm);
/****************************************************************************
* Name: zm_readstate
......
......@@ -199,7 +199,8 @@ int zm_senddata(FAR struct zm_state_s *pzm, FAR const uint8_t *buffer,
}
term = ZCRCW;
zmdbg("zbin=%c, buflen=%d, term=%c\n", zbin, buflen, term);
zmdbg("zbin=%c, buflen=%d, term=%c flags=%04x\n",
zbin, buflen, term, pzm->flags);
/* Transfer the data to the I/O buffer, accumulating the CRC */
......@@ -496,6 +497,6 @@ int zm_sendbinhdr(FAR struct zm_state_s *pzm, int type,
}
else
{
return zm_sendbin16hdr(pzm, type, buffer);
return zm_sendbin32hdr(pzm, type, buffer);
}
}
This diff is collapsed.
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment