diff --git a/system/readline/readline_common.c b/system/readline/readline_common.c index 92a98c53837..21c9217ac66 100644 --- a/system/readline/readline_common.c +++ b/system/readline/readline_common.c @@ -144,6 +144,7 @@ static int count_builtin_matches(FAR char *buf, FAR int *matches, int namelen) * vtbl - vtbl used to access implementation specific interface * buf - The user allocated buffer to be filled. * buflen - the size of the buffer. + * nch - the number of characters. * * Returned Value: * None. @@ -152,7 +153,7 @@ static int count_builtin_matches(FAR char *buf, FAR int *matches, int namelen) #ifdef CONFIG_READLINE_TABCOMPLETION static void tab_completion(FAR struct rl_common_s *vtbl, char *buf, - int *nch) + int buflen, int *nch) { FAR const char *name = NULL; char tmp_name[CONFIG_TASK_NAME_SIZE + 1]; @@ -271,7 +272,7 @@ static void tab_completion(FAR struct rl_common_s *vtbl, char *buf, if (tmp_name[0] == '\0') { - strcpy(tmp_name, name); + strncpy(tmp_name, name, sizeof(tmp_name) - 1); } RL_PUTC(vtbl, ' '); @@ -306,7 +307,7 @@ static void tab_completion(FAR struct rl_common_s *vtbl, char *buf, if (tmp_name[0] == '\0') { - strcpy(tmp_name, name); + strncpy(tmp_name, name, sizeof(tmp_name) - 1); } RL_PUTC(vtbl, ' '); @@ -329,7 +330,7 @@ static void tab_completion(FAR struct rl_common_s *vtbl, char *buf, RL_PUTC(vtbl, '\n'); } #endif - strcpy(buf, tmp_name); + strncpy(buf, tmp_name, buflen - 1); name_len = strlen(tmp_name); @@ -729,7 +730,7 @@ ssize_t readline_common(FAR struct rl_common_s *vtbl, FAR char *buf, int buflen) #ifdef CONFIG_READLINE_TABCOMPLETION else if (ch == '\t') /* Nghia - TAB character */ { - tab_completion(vtbl, buf, &nch); + tab_completion(vtbl, buf, buflen, &nch); } #endif } diff --git a/system/zmodem/Kconfig b/system/zmodem/Kconfig index 2841751046c..21caa36bc83 100644 --- a/system/zmodem/Kconfig +++ b/system/zmodem/Kconfig @@ -62,6 +62,15 @@ config SYSTEM_ZMODEM_SNDBUFSIZE The size of one transmit buffer used for composing messages sent to the remote peer. +config SYSTEM_ZMODEM_SNDFILEBUF + bool "Use cache buffer for file send" + default n + ---help--- + Read multiple bytes of file at once and store into a temporal buffer + which size is the same as SYSTEM_ZMODEM_SNDBUFSIZE. This is option + to improve the performance of file send, especially when the single + read of file is very slow. + config SYSTEM_ZMODEM_MOUNTPOINT string "Zmodem sandbox" default "/tmp" diff --git a/system/zmodem/Makefile.host b/system/zmodem/Makefile.host index 968ae925d76..6e870eea8c6 100644 --- a/system/zmodem/Makefile.host +++ b/system/zmodem/Makefile.host @@ -43,7 +43,7 @@ # make -f Makefile.host TOPDIR=/home/me/projects/nuttx # APPDIR=/home/me/projects/apps # -# 2. Add CONFIG_DEBUG_FEATURES=1 to the make command line to enable debug output +# 2. Add CONFIG_DEBUG_FEATURES=y to the make command line to enable debug output # 3. Make sure to clean old target .o files before making new host .o # files. # @@ -62,14 +62,14 @@ HOSTAPPS = $(ZMODEM)/host/apps HOSTCFLAGS += -isystem $(HOSTDIR) -I $(ZMODEM) -I $(HOSTAPPS) HOSTCFLAGS += -Dsz_main=main -Drz_main=main ifeq ($(CONFIG_DEBUG_FEATURES),y) -HOSTCFLAGS += -DCONFIG_DEBUG_ZMODEM=1 -DCONFIG_SYSTEM_ZMODEM_DUMPBUFFER=1 +HOSTCFLAGS += -DCONFIG_DEBUG_ZMODEM=1 endif # Zmodem sz and rz commands SZSRCS = sz_main.c zm_send.c RZSRCS = rz_main.c zm_receive.c -CMNSRCS = zm_state.c zm_proto.c zm_watchdog.c zm_utils.c zm_dumpbuffer.c +CMNSRCS = zm_state.c zm_proto.c zm_watchdog.c zm_utils.c CMNSRCS += crc16.c crc32.c SRCS = $(SZSRCS) $(RZSRCS) $(CMNSRCS) diff --git a/system/zmodem/zm.h b/system/zmodem/zm.h index 6e888d0f493..d393b7780b3 100644 --- a/system/zmodem/zm.h +++ b/system/zmodem/zm.h @@ -49,6 +49,7 @@ #include #include +#include #include #include @@ -357,6 +358,9 @@ struct zm_state_s uint8_t rcvbuf[CONFIG_SYSTEM_ZMODEM_RCVBUFSIZE]; uint8_t pktbuf[ZM_PKTBUFSIZE]; uint8_t scratch[CONFIG_SYSTEM_ZMODEM_SNDBUFSIZE]; +#ifdef CONFIG_SYSTEM_ZMODEM_SNDFILEBUF + uint8_t filebuf[CONFIG_SYSTEM_ZMODEM_SNDBUFSIZE]; +#endif }; /* Receive state information */ diff --git a/system/zmodem/zm_send.c b/system/zmodem/zm_send.c index 24fb60581ce..a12abe1ee54 100644 --- a/system/zmodem/zm_send.c +++ b/system/zmodem/zm_send.c @@ -872,7 +872,6 @@ static int zms_sendpacket(FAR struct zm_state_s *pzm) bool wait = false; int sndsize; int pktsize; - int ret; int i; /* Loop, sending packets while we can if the receiver supports streaming @@ -977,12 +976,24 @@ static int zms_sendpacket(FAR struct zm_state_s *pzm) ptr = pzm->scratch; pktsize = 0; +#ifdef CONFIG_SYSTEM_ZMODEM_SNDFILEBUF + /* Read multiple bytes of file and store into the temporal buffer */ + + zm_read(pzms->infd, pzm->filebuf, CONFIG_SYSTEM_ZMODEM_SNDBUFSIZE); + + i = 0; +#endif + while (pktsize <= (CONFIG_SYSTEM_ZMODEM_SNDBUFSIZE - 10) && - (ret = zm_getc(pzms->infd)) != EOF) + (pzms->offset < pzms->filesize)) { /* Add the new value to the accumulated CRC */ - uint8_t ch = (uint8_t)ret; +#ifdef CONFIG_SYSTEM_ZMODEM_SNDFILEBUF + uint8_t ch = pzm->filebuf[i++]; +#else + uint8_t ch = zm_getc(pzms->infd); +#endif if (!bcrc32) { crc = (uint32_t)crc16part(&ch, 1, (uint16_t)crc); @@ -1007,6 +1018,12 @@ static int zms_sendpacket(FAR struct zm_state_s *pzm) pzms->offset++; } +#ifdef CONFIG_SYSTEM_ZMODEM_SNDFILEBUF + /* Restore file position to be read next time */ + + lseek(pzms->infd, pzms->offset, SEEK_SET); +#endif + /* If we've reached file end, a ZEOF header will follow. If there's * room in the outgoing buffer for it, end the packet with ZCRCE and * append the ZEOF header. If there isn't room, we'll have to do a @@ -1014,7 +1031,7 @@ static int zms_sendpacket(FAR struct zm_state_s *pzm) */ pzm->flags &= ~ZM_FLAG_EOF; - if (ret == EOF) + if (pzms->offset == pzms->filesize) { pzm->flags |= ZM_FLAG_EOF; if (wait || (pzms->rcvmax != 0 && pktsize < 24)) diff --git a/system/zmodem/zm_state.c b/system/zmodem/zm_state.c index 75844719ae8..a646bd371ad 100644 --- a/system/zmodem/zm_state.c +++ b/system/zmodem/zm_state.c @@ -755,7 +755,7 @@ static int zm_parse(FAR struct zm_state_s *pzm, size_t rcvlen) uint8_t ch; int ret; - DEBUGASSERT(pzm && rcvlen < CONFIG_SYSTEM_ZMODEM_RCVBUFSIZE); + DEBUGASSERT(pzm && rcvlen <= CONFIG_SYSTEM_ZMODEM_RCVBUFSIZE); zm_dumpbuffer("Received", pzm->rcvbuf, rcvlen); /* We keep a copy of the length and buffer index in the state structure.