summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorMarek Vasut <[email protected]>2026-01-29 00:43:45 +0100
committerJerome Forissier <[email protected]>2026-02-06 16:42:37 +0100
commit337f50bad2ac8e1db126e4f6d372a3186bba2893 (patch)
tree893e2b6ce6c75fa1fbf900cb1a1c57c3f03df254 /net
parenta28db0f1ccd6d7f88e9715486376bc039975f72c (diff)
net: lwip: tftp: add support of tsize option to client
The TFTP server can report the size of the entire file that is about to be received in the Transfer Size Option, this is described in RFC 2349. This functionality is optional and the server may not report tsize in case it is not supported. Always send tsize request to the server to query the transfer size, and in case the server does respond, cache that information locally in tftp_state.tsize, otherwise cache size 0. Introduce new function tftp_client_get_tsize() which returns the cached tftp_state.tsize so clients can determine the transfer size and use it. Update net/lwip/tftp.c to make use of tftp_client_get_tsize() and avoid excessive printing of '#' during TFTP transfers in case the transfer size is reported by the server. Submitted upstream: https://savannah.nongnu.org/patch/index.php?item_id=10557 Signed-off-by: Marek Vasut <[email protected]> Acked-by: Jerome Forissier <[email protected]>
Diffstat (limited to 'net')
-rw-r--r--net/lwip/tftp.c35
1 files changed, 31 insertions, 4 deletions
diff --git a/net/lwip/tftp.c b/net/lwip/tftp.c
index 86516e66273..5c3becc68c6 100644
--- a/net/lwip/tftp.c
+++ b/net/lwip/tftp.c
@@ -31,6 +31,7 @@ struct tftp_ctx {
ulong daddr;
ulong size;
ulong block_count;
+ ulong hash_count;
ulong start_time;
enum done_state done;
};
@@ -49,6 +50,8 @@ struct tftp_ctx {
static int store_block(struct tftp_ctx *ctx, void *src, u16_t len)
{
ulong store_addr = ctx->daddr;
+ ulong tftp_tsize;
+ ulong pos;
void *ptr;
if (CONFIG_IS_ENABLED(LMB)) {
@@ -67,10 +70,21 @@ static int store_block(struct tftp_ctx *ctx, void *src, u16_t len)
ctx->daddr += len;
ctx->size += len;
ctx->block_count++;
- if (ctx->block_count % 10 == 0) {
- putc('#');
- if (ctx->block_count % (65 * 10) == 0)
- puts("\n\t ");
+
+ tftp_tsize = tftp_client_get_tsize();
+ if (tftp_tsize) {
+ pos = clamp(ctx->size, 0UL, tftp_tsize);
+
+ while (ctx->hash_count < pos * 50 / tftp_tsize) {
+ putc('#');
+ ctx->hash_count++;
+ }
+ } else {
+ if (ctx->block_count % 10 == 0) {
+ putc('#');
+ if (ctx->block_count % (65 * 10) == 0)
+ puts("\n\t ");
+ }
}
return 0;
@@ -84,6 +98,7 @@ static void *tftp_open(const char *fname, const char *mode, u8_t is_write)
static void tftp_close(void *handle)
{
struct tftp_ctx *ctx = handle;
+ ulong tftp_tsize;
ulong elapsed;
if (ctx->done == FAILURE || ctx->done == ABORTED) {
@@ -92,6 +107,17 @@ static void tftp_close(void *handle)
}
ctx->done = SUCCESS;
+ tftp_tsize = tftp_client_get_tsize();
+ if (tftp_tsize) {
+ /* Print hash marks for the last packet received */
+ while (ctx->hash_count < 49) {
+ putc('#');
+ ctx->hash_count++;
+ }
+ puts(" ");
+ print_size(tftp_tsize, "");
+ }
+
elapsed = get_timer(ctx->start_time);
if (elapsed > 0) {
puts("\n\t "); /* Line up with "Loading: " */
@@ -176,6 +202,7 @@ static int tftp_loop(struct udevice *udev, ulong addr, char *fname,
ctx.done = NOT_DONE;
ctx.size = 0;
ctx.block_count = 0;
+ ctx.hash_count = 0;
ctx.daddr = addr;
printf("Using %s device\n", udev->name);