apps/system/zmodem:
- fix error "sz_main.o: No such file or directory" - support -p <path> for rz to change the folder for the recevied file - switch debug output from printf to syslog - send the next packet for ZME_ACK in ZMS_SENDING to avoid rz on the host side stuck - make send work reliable even without hardware flow control
This commit is contained in:
parent
bee98898f0
commit
ddd86d31ca
@ -250,14 +250,15 @@ ZMRHANDLE zmr_initialize(int remfd);
|
||||
* Receive file(s) sent from the remote peer.
|
||||
*
|
||||
* Input Parameters:
|
||||
* handle - The handler created by zmr_initialize().
|
||||
* handle - The handler created by zmr_initialize().
|
||||
* pathname - The name of the local path to hold the file
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero on success; a negated errno value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int zmr_receive(ZMRHANDLE handle);
|
||||
int zmr_receive(ZMRHANDLE handle, FAR const char *pathname);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: zmr_release
|
||||
|
@ -56,7 +56,7 @@ STACKSIZE = $(CONFIG_SYSTEM_ZMODEM_STACKSIZE)
|
||||
ASRCS =
|
||||
|
||||
CSRCS = zm_send.c zm_receive.c zm_state.c zm_proto.c zm_watchdog.c
|
||||
CSRCS += zm_utils.c zm_dumpbuffer.c
|
||||
CSRCS += zm_utils.c
|
||||
SZ_MAINSRC = sz_main.c
|
||||
RZ_MAINSRC = rz_main.c
|
||||
|
||||
@ -64,12 +64,13 @@ AOBJS = $(ASRCS:.S=$(OBJEXT))
|
||||
COBJS = $(CSRCS:.c=$(OBJEXT))
|
||||
SZ_MAINOBJ = $(SZ_MAINSRC:.c=$(OBJEXT))
|
||||
RZ_MAINOBJ = $(RZ_MAINSRC:.c=$(OBJEXT))
|
||||
MAINOBJ = $(SZ_MAINOBJ) $(RZ_MAINOBJ)
|
||||
|
||||
SRCS = $(ASRCS) $(CSRCS) $(SZ_MAINSRC) $(RZ_MAINSRC)
|
||||
OBJS = $(AOBJS) $(COBJS)
|
||||
|
||||
ifneq ($(CONFIG_BUILD_KERNEL),y)
|
||||
OBJS += $(SZ_MAINOBJ) $(RZ_MAINOBJ)
|
||||
OBJS += $(MAINOBJ)
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_WINDOWS_NATIVE),y)
|
||||
|
@ -162,10 +162,10 @@ Using NuttX ZModem with a Linux Host
|
||||
|
||||
Then use the sz command on Linux to send the file to the target:
|
||||
|
||||
$ sudo sz <filename> [-l nnnn] </dev/ttyS0 >/dev/ttyS0
|
||||
$ sudo sz <filename> [-l nnnn] [-w nnnn] </dev/ttyS0 >/dev/ttyS0
|
||||
|
||||
Where <filename> is the file that you want to send. If -l nnnn is not
|
||||
specified, then there will likely be packet buffer overflow errors.
|
||||
Where <filename> is the file that you want to send. If -l nnnn and -w nnnn
|
||||
is not specified, then there will likely be packet buffer overflow errors.
|
||||
nnnn should be set to a value less than or equal to
|
||||
CONFIG_SYSTEM_ZMODEM_PKTBUFSIZE
|
||||
|
||||
@ -173,11 +173,11 @@ Using NuttX ZModem with a Linux Host
|
||||
"sandbox" via CONFIG_SYSTEM_ZMODEM_MOUNTPOINT.
|
||||
|
||||
You can add the sz -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>az.log to the end of the
|
||||
rz command.
|
||||
of debug output. If you want to capture the Linux sz output, then
|
||||
re-direct stderr to a log file by adding 2>sz.log to the end of the
|
||||
sz command.
|
||||
|
||||
If you don't have the az command on your Linux box, the package to
|
||||
If you don't have the sz command on your Linux box, the package to
|
||||
install rzsz (or possibily lrzsz).
|
||||
|
||||
Building the ZModem Tools to Run Under Linux
|
||||
@ -214,7 +214,7 @@ Status
|
||||
have been able to send large and small files with the target sz
|
||||
command. I have been able to receive small files, but there are
|
||||
problems receiving large files using the Linux sz command: The
|
||||
Linux SZ does not obey the buffering limits and continues to send
|
||||
Linux sz does not obey the buffering limits and continues to send
|
||||
data while rz is writing the previously received data to the file
|
||||
and the serial driver's RX buffer is overrun by a few bytes while
|
||||
the write is in progress. As a result, when it reads the next
|
||||
@ -265,3 +265,7 @@ Status
|
||||
olimex-stm32-p407/zmodem configuration with target-to-host
|
||||
transfers was verified. Again, there are issues remaining if
|
||||
I tried the NuttX rz utility running on Linux.
|
||||
|
||||
2018-6-26:
|
||||
with -w nnnn option, the host-to-target transfer can work reliably
|
||||
without hardware flow control.
|
||||
|
@ -64,6 +64,8 @@ static void show_usage(FAR const char *progname, int errcode)
|
||||
fprintf(stderr, "\nWhere OPTIONS include the following:\n");
|
||||
fprintf(stderr, "\t-d <device>: Communication device to use. Default: %s\n",
|
||||
CONFIG_SYSTEM_ZMODEM_DEVNAME);
|
||||
fprintf(stderr, "\t-p <path>: Folder to hold the received file. Default: %s\n",
|
||||
CONFIG_SYSTEM_ZMODEM_MOUNTPOINT);
|
||||
fprintf(stderr, "\t-h: Show this text and exit\n");
|
||||
exit(errcode);
|
||||
}
|
||||
@ -80,6 +82,7 @@ int rz_main(int argc, FAR char **argv)
|
||||
{
|
||||
ZMRHANDLE handle;
|
||||
FAR const char *devname = CONFIG_SYSTEM_ZMODEM_DEVNAME;
|
||||
FAR const char *pathname = CONFIG_SYSTEM_ZMODEM_MOUNTPOINT;
|
||||
int exitcode = EXIT_FAILURE;
|
||||
int option;
|
||||
int ret;
|
||||
@ -87,7 +90,7 @@ int rz_main(int argc, FAR char **argv)
|
||||
|
||||
/* Parse input parameters */
|
||||
|
||||
while ((option = getopt(argc, argv, ":d:h")) != ERROR)
|
||||
while ((option = getopt(argc, argv, ":d:hp:")) != ERROR)
|
||||
{
|
||||
switch (option)
|
||||
{
|
||||
@ -99,6 +102,10 @@ int rz_main(int argc, FAR char **argv)
|
||||
show_usage(argv[0], EXIT_SUCCESS);
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
pathname = optarg;
|
||||
break;
|
||||
|
||||
case ':':
|
||||
fprintf(stderr, "ERROR: Missing required argument\n");
|
||||
show_usage(argv[0], EXIT_FAILURE);
|
||||
@ -146,7 +153,7 @@ int rz_main(int argc, FAR char **argv)
|
||||
|
||||
/* And begin reception of files */
|
||||
|
||||
ret = zmr_receive(handle);
|
||||
ret = zmr_receive(handle, pathname);
|
||||
if (ret < 0)
|
||||
{
|
||||
fprintf(stderr, "ERROR: File reception failed: %d\n", ret);
|
||||
|
@ -229,8 +229,8 @@
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_DEBUG_ZMODEM
|
||||
# define zmprintf(format, ...) fprintf(stderr, format, ##__VA_ARGS__)
|
||||
# define zmdbg(format, ...) fprintf(stderr, EXTRA_FMT format EXTRA_ARG, ##__VA_ARGS__)
|
||||
# define zmprintf(format, ...) syslog(LOG_INFO, format, ##__VA_ARGS__)
|
||||
# define zmdbg(format, ...) syslog(LOG_INFO, EXTRA_FMT format EXTRA_ARG, ##__VA_ARGS__)
|
||||
#else
|
||||
# undef CONFIG_SYSTEM_ZMODEM_DUMPBUFFER
|
||||
# ifdef CONFIG_CPP_HAVE_VARARGS
|
||||
@ -379,6 +379,7 @@ struct zmr_state_s
|
||||
#endif
|
||||
uint8_t ntimeouts; /* Number of timeouts */
|
||||
uint32_t crc; /* Remove file CRC */
|
||||
FAR const char *pathname; /* Local pathname */
|
||||
FAR char *filename; /* Local filename */
|
||||
FAR char *attn; /* Attention string received from remote peer */
|
||||
off_t offset; /* Current file offset */
|
||||
@ -804,7 +805,7 @@ int zm_timerrelease(FAR struct zm_state_s *pzm);
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_SYSTEM_ZMODEM_DUMPBUFFER
|
||||
void zm_dumpbuffer(FAR const char *msg, FAR const void *buffer, size_t buflen);
|
||||
# define zm_dumpbuffer(m,b,s) lib_dumpbuffer(m,b,s)
|
||||
#else
|
||||
# define zm_dumpbuffer(m,b,s)
|
||||
#endif
|
||||
|
@ -1,119 +0,0 @@
|
||||
/****************************************************************************
|
||||
* apps/system/zmodem/zm_dumpbuffer.c
|
||||
*
|
||||
* Copyright (C) 2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "zm.h"
|
||||
|
||||
#ifdef CONFIG_SYSTEM_ZMODEM_DUMPBUFFER
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: zm_dumpbuffer
|
||||
*
|
||||
* Description:
|
||||
* Dump a buffer of zmodem data.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void zm_dumpbuffer(FAR const char *msg, FAR const void *buffer, size_t buflen)
|
||||
{
|
||||
FAR const uint8_t *ptr = (FAR const uint8_t *)buffer;
|
||||
size_t i;
|
||||
int j, k;
|
||||
|
||||
zmprintf("%s [%p]:\n", msg, ptr);
|
||||
for (i = 0; i < buflen; i += 32)
|
||||
{
|
||||
zmprintf("%04x: ", i);
|
||||
for (j = 0; j < 32; j++)
|
||||
{
|
||||
k = i + j;
|
||||
|
||||
if (j == 16)
|
||||
{
|
||||
zmprintf(" ");
|
||||
}
|
||||
|
||||
if (k < buflen)
|
||||
{
|
||||
zmprintf("%02x", ptr[k]);
|
||||
}
|
||||
else
|
||||
{
|
||||
zmprintf(" ");
|
||||
}
|
||||
}
|
||||
|
||||
zmprintf(" ");
|
||||
for (j = 0; j < 32; j++)
|
||||
{
|
||||
k = i + j;
|
||||
|
||||
if (j == 16)
|
||||
{
|
||||
zmprintf(" ");
|
||||
}
|
||||
|
||||
if (k < buflen)
|
||||
{
|
||||
if (ptr[k] >= 0x20 && ptr[k] < 0x7f)
|
||||
{
|
||||
zmprintf("%c", ptr[k]);
|
||||
}
|
||||
else
|
||||
{
|
||||
zmprintf(".");
|
||||
}
|
||||
}
|
||||
}
|
||||
zmprintf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CONFIG_SYSTEM_ZMODEM_DUMPBUFFER */
|
@ -381,7 +381,7 @@ static int zmr_startto(FAR struct zm_state_s *pzm)
|
||||
zmdbg("ZMR_STATE %d: %d timeouts waiting for ZSINIT or ZFILE\n",
|
||||
pzm->state, pzmr->ntimeouts);
|
||||
|
||||
if (pzmr->ntimeouts > 4)
|
||||
if (pzmr->ntimeouts < 4)
|
||||
{
|
||||
/* Send ZRINIT again */
|
||||
|
||||
@ -1144,8 +1144,7 @@ static int zmr_parsefilename(FAR struct zmr_state_s *pzmr,
|
||||
|
||||
/* Extend the relative path to the file storage directory */
|
||||
|
||||
asprintf(&pzmr->filename, "%s/%s", CONFIG_SYSTEM_ZMODEM_MOUNTPOINT,
|
||||
namptr);
|
||||
asprintf(&pzmr->filename, "%s/%s", pzmr->pathname, namptr);
|
||||
if (!pzmr->filename)
|
||||
{
|
||||
zmdbg("ERROR: Failed to allocate full path %s/%s\n",
|
||||
@ -1616,6 +1615,7 @@ ZMRHANDLE zmr_initialize(int remfd)
|
||||
pzm->pstate = PSTATE_IDLE;
|
||||
pzm->psubstate = PIDLE_ZPAD;
|
||||
pzm->remfd = remfd;
|
||||
pzmr->rcaps = CANFC32 | CANFDX;
|
||||
pzmr->outfd = -1;
|
||||
|
||||
/* Create a timer to handle timeout events */
|
||||
@ -1645,17 +1645,20 @@ ZMRHANDLE zmr_initialize(int remfd)
|
||||
* Receive file(s) sent from the remote peer.
|
||||
*
|
||||
* Input Parameters:
|
||||
* handle - The handler created by zmr_initialize().
|
||||
* handle - The handler created by zmr_initialize().
|
||||
* pathname - The name of the local path to hold the file
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero on success; a negated errno value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int zmr_receive(ZMRHANDLE handle)
|
||||
int zmr_receive(ZMRHANDLE handle, FAR const char *pathname)
|
||||
{
|
||||
FAR struct zmr_state_s *pzmr = (FAR struct zmr_state_s*)handle;
|
||||
|
||||
pzmr->pathname = pathname;
|
||||
|
||||
/* The first thing that should happen is to receive ZRQINIT from the
|
||||
* remote sender. This could take while so use a long timeout.
|
||||
*/
|
||||
|
@ -148,7 +148,6 @@ static int zms_fileskip(FAR struct zm_state_s *pzm);
|
||||
static int zms_sendfiledata(FAR struct zm_state_s *pzm);
|
||||
static int zms_sendpacket(FAR struct zm_state_s *pzm);
|
||||
static int zms_filecrc(FAR struct zm_state_s *pzm);
|
||||
static int zms_sendack(FAR struct zm_state_s *pzm);
|
||||
static int zms_sendwaitack(FAR struct zm_state_s *pzm);
|
||||
static int zms_sendnak(FAR struct zm_state_s *pzm);
|
||||
static int zms_sendrpos(FAR struct zm_state_s *pzm);
|
||||
@ -258,7 +257,7 @@ static const struct zm_transition_s g_zms_crcwait[] =
|
||||
static const struct zm_transition_s g_zmr_sending[] =
|
||||
{
|
||||
{ZME_SINIT, false, ZMS_START, zms_attention},
|
||||
{ZME_ACK, false, ZMS_SENDING, zms_sendack},
|
||||
{ZME_ACK, false, ZMS_SENDING, zms_sendpacket},
|
||||
{ZME_RPOS, true, ZMS_SENDING, zms_sendrpos},
|
||||
{ZME_SKIP, true, ZMS_FILEWAIT, zms_fileskip},
|
||||
{ZME_NAK, true, ZMS_SENDING, zms_sendnak},
|
||||
@ -422,7 +421,6 @@ static int zms_zrinit(FAR struct zm_state_s *pzm)
|
||||
|
||||
/* Set flags associated with the capabilities */
|
||||
|
||||
rcaps &= ~(ZM_FLAG_CRC32 | ZM_FLAG_ESCCTRL);
|
||||
if ((rcaps & CANFC32) != 0)
|
||||
{
|
||||
pzm->flags |= ZM_FLAG_CRC32;
|
||||
@ -1152,35 +1150,6 @@ static int zms_filecrc(FAR struct zm_state_s *pzm)
|
||||
return zm_sendhexhdr(pzm, ZCRC, by);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: zms_sendack
|
||||
*
|
||||
* Description:
|
||||
* An ACK arrived while transmitting data. Update last known receiver
|
||||
* offset, and try to send more data.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int zms_sendack(FAR struct zm_state_s *pzm)
|
||||
{
|
||||
FAR struct zms_state_s *pzms = (FAR struct zms_state_s *)pzm;
|
||||
off_t offset;
|
||||
|
||||
/* Paragraph 11.4 ZACK. Acknowledgment to a ZSINIT , ..., ZCRCQ or
|
||||
* ZCRCW data subpacket. ZP0 to ZP3 contain file offset.
|
||||
*/
|
||||
|
||||
offset = zm_bytobe32(pzm->hdrdata + 1);
|
||||
|
||||
if (offset > pzms->lastoffs)
|
||||
{
|
||||
pzms->lastoffs = offset;
|
||||
}
|
||||
|
||||
zmdbg("ZMS_STATE %d: offset: %ld\n", pzm->state, (unsigned long)pzms->offset);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: zms_sendwaitack
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user