You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ac...@apache.org on 2026/10/08 18:55:53 UTC

(nuttx) branch master updated: Documentation/netutils: add comprehensive guide for tftpc

This is an automated email from the ASF dual-hosted git repository.

acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 5b597668f0a Documentation/netutils: add comprehensive guide for tftpc
5b597668f0a is described below

commit 5b597668f0a6e812977071ff09ac4ca80d12e223
Author: Swatantra Yadav <ma...@gmail.com>
AuthorDate: Wed Oct 7 22:40:12 2026 +0530

    Documentation/netutils: add comprehensive guide for tftpc
    
    Provide a complete documentation guide for the tftpc (TFTP client) network
    utility in Documentation/applications/netutils/tftpc/index.rst, replacing
    the previous 5-line placeholder stub.
    
    Includes:
    - Architecture overview (NSH get/put engine + programmatic C APIs)
    - Key features (RFC 1350, octet/netascii modes, streaming callbacks, dynamic TID port negotiation)
    - Configuration options table and networking prerequisites
    - NSH get and put command synopses, option flags, and terminal examples
    - C API reference for filesystem helpers (tftpget, tftpput) and streaming callbacks (tftpget_cb, tftpput_cb)
    - Complete, runnable C application example demonstrating callback-based streaming downloads
    
    Addresses #11081
    
    Signed-off-by: Swatantra Yadav <ma...@gmail.com>
---
 .../applications/netutils/tftpc/index.rst          | 261 ++++++++++++++++++++-
 1 file changed, 259 insertions(+), 2 deletions(-)

diff --git a/Documentation/applications/netutils/tftpc/index.rst b/Documentation/applications/netutils/tftpc/index.rst
index ce0989569a9..0065c276553 100644
--- a/Documentation/applications/netutils/tftpc/index.rst
+++ b/Documentation/applications/netutils/tftpc/index.rst
@@ -1,5 +1,262 @@
 =====================
-``tftpc`` TFTP client
+``tftpc`` TFTP Client
 =====================
 
-TFTP client. See ``apps/include/netutils/tftp.h`` for interface information.
+Overview
+========
+
+``tftpc`` is a lightweight, RFC 1350-compliant Trivial File Transfer Protocol (TFTP)
+client library and utility for Apache NuttX. Designed specifically for resource-constrained
+embedded systems, it facilitates low-overhead file transfers over UDP.
+
+In NuttX environments, ``tftpc`` is widely used for:
+
+- Bootloaders, remote firmware updates, and Over-The-Air (OTA) image transfers.
+- Transferring small configuration files and system logs without requiring a complex
+  TCP stack, TLS handshakes, or HTTP parsers.
+- Interactive file retrieval and upload directly from the NuttShell (NSH).
+
+.. note::
+
+   **Security Consideration**: TFTP provides no authentication, encryption, or
+   access control mechanisms. When performing firmware updates or transferring
+   sensitive binaries over TFTP, operations should be restricted to trusted, isolated
+   networks, and the receiving system must independently verify the image prior to
+   installation using a verified digital signature (or a cryptographic digest received
+   over a trusted out-of-band channel) to guarantee both origin authenticity and integrity.
+
+It serves two primary roles:
+
+1. **Underlying Engine for NSH ``get`` and ``put`` Commands**: Powers interactive
+   terminal file transfer commands in the NuttShell.
+2. **Programmatic C API**: Provides embedded applications with simple synchronous helpers
+   (``tftpget()``, ``tftpput()``) as well as streaming callback interfaces (``tftpget_cb()``,
+   ``tftpput_cb()``) that stream blocks directly into memory, flash partitions, or custom
+   buffers without requiring a temporary local filesystem file.
+
+Key Features
+============
+
+- **RFC 1350 Compliance**: Standard-compliant TFTP client protocol implementation.
+- **Binary and Text Transfer Modes**: Supports both ``octet`` (binary) and ``netascii``
+  (text) transfer modes.
+- **Streaming Callback Architecture**: User-defined ``tftp_callback_t`` handlers process
+  incoming or outgoing chunks on-the-fly, allowing direct flashing of MTD/flash partitions
+  with minimal RAM consumption.
+- **Dynamic Port Negotiation**: Connects to the server's well-known port (typically 69) and
+  seamlessly adapts to the server's negotiated Transfer Identifier (TID) port.
+- **Configurable Retransmission**: Built-in retransmission timeouts and retry counters to
+  tolerate packet loss over wireless or congested networks.
+
+Requirements & Dependencies
+===========================
+
+To use ``tftpc``, the following network subsystem features must be enabled:
+
+- IPv4 Networking: ``CONFIG_NET=y`` and ``CONFIG_NET_IPv4=y``
+- UDP Protocol: ``CONFIG_NET_UDP=y``
+- Enable the Client Library: ``CONFIG_NETUTILS_TFTPC=y``
+- For NSH Commands: ``!CONFIG_NSH_DISABLE_GET`` and ``!CONFIG_NSH_DISABLE_PUT``
+
+Configuration Options
+=====================
+
+The behavior of the TFTP client can be customized via Kconfig and configuration settings:
+
+.. list-table::
+   :widths: 35 15 50
+   :header-rows: 1
+
+   * - Setting
+     - Default
+     - Description
+   * - ``CONFIG_NETUTILS_TFTPC``
+     - ``n``
+     - Enables the TFTP client library in ``apps/netutils/tftpc``.
+   * - ``CONFIG_NETUTILS_TFTP_PORT``
+     - ``69``
+     - Target well-known TFTP server port used for the initial request.
+   * - ``CONFIG_NETUTILS_TFTP_TIMEOUT``
+     - ``10``
+     - Socket receive timeout in deci-seconds (10 = 1 second).
+   * - ``CONFIG_NETUTILS_TFTP_DUMPBUFFERS``
+     - Defined
+     - Debug option to dump transmitted and received packet buffers to stdout.
+
+NSH Usage
+=========
+
+When ``CONFIG_NETUTILS_TFTPC`` is enabled along with NSH UDP network commands, the
+``get`` and ``put`` commands are available directly in the NuttShell.
+
+Downloading Files (``get``)
+---------------------------
+
+The ``get`` command downloads a file from a remote TFTP server:
+
+.. code-block:: console
+
+   get [-b|-n] [-f <local-path>] -h <ip-address> <remote-path>
+
+Options:
+
+- ``-b``: Transfer file in binary (``octet``) mode (default).
+- ``-n``: Transfer file in text (``netascii``) mode.
+- ``-f <local-path>``: Destination path on the local filesystem. If omitted, the file
+  is written to the current directory using ``<remote-path>`` as the filename.
+- ``-h <ip-address>``: IPv4 address of the remote TFTP server.
+- ``<remote-path>``: Path or filename of the file on the remote server.
+
+Example:
+
+.. code-block:: console
+
+   nsh> get -h 192.168.1.100 -f /mnt/sdcard/firmware.bin app_update.bin
+   nsh> ls -l /mnt/sdcard/firmware.bin
+
+Uploading Files (``put``)
+-------------------------
+
+The ``put`` command uploads a local file to a remote TFTP server:
+
+.. code-block:: console
+
+   put [-b|-n] [-f <remote-path>] -h <ip-address> <local-path>
+
+Options:
+
+- ``-b``: Transfer file in binary (``octet``) mode (default).
+- ``-n``: Transfer file in text (``netascii``) mode.
+- ``-f <remote-path>``: Destination filename on the remote TFTP server. If omitted,
+  the file is written with the basename of ``<local-path>``.
+- ``-h <ip-address>``: IPv4 address of the remote TFTP server.
+- ``<local-path>``: Path to the local file to transmit.
+
+Example:
+
+.. code-block:: console
+
+   nsh> put -h 192.168.1.100 -f remote_syslog.txt /var/log/syslog.txt
+
+C API Reference
+===============
+
+The public C interface is declared in ``apps/include/netutils/tftp.h``.
+
+Standard Filesystem APIs
+------------------------
+
+For standard file-to-file transfers using paths in the VFS:
+
+.. code-block:: c
+
+   #include <arpa/inet.h>
+   #include <stdbool.h>
+   #include <netutils/tftp.h>
+
+   int tftpget(FAR const char *remote, FAR const char *local, in_addr_t addr,
+               bool binary);
+
+   int tftpput(FAR const char *local, FAR const char *remote, in_addr_t addr,
+               bool binary);
+
+Parameters:
+
+- ``remote``: Filename on the remote TFTP server.
+- ``local``: Filename in the local NuttX filesystem.
+- ``addr``: IPv4 network address of the TFTP server in network byte order (e.g., from ``inet_addr()``).
+- ``binary``: Pass ``true`` for binary (``octet``) mode, or ``false`` for text (``netascii``) mode.
+
+Return Value:
+
+- Returns ``OK`` (0) on success, or a negated errno value (or ``ERROR``) on failure.
+
+Streaming Callback APIs
+-----------------------
+
+For transfers directly to/from memory, raw flash, or custom sinks:
+
+.. code-block:: c
+
+   typedef ssize_t (*tftp_callback_t)(FAR void *ctx, uint32_t offset,
+                                      FAR uint8_t *buf, size_t len);
+
+   int tftpget_cb(FAR const char *remote, in_addr_t addr, bool binary,
+                  tftp_callback_t cb, FAR void *ctx);
+
+   int tftpput_cb(FAR const char *remote, in_addr_t addr, bool binary,
+                  tftp_callback_t cb, FAR void *ctx);
+
+Callback semantics:
+
+- **GET (Download)**: ``offset`` is zero. ``buf`` points to the received block (up to 512 bytes).
+  ``len`` is the number of received bytes. The callback must return the number of bytes successfully
+  processed, or a negative value to abort the transfer.
+- **PUT (Upload)**: ``offset`` indicates the current stream byte position. ``buf`` points to the destination
+  buffer to populate. ``len`` specifies the buffer size. The callback must return the number of bytes
+  supplied, 0 on end-of-file (EOF), or a negative value to abort the transfer.
+
+Application Example
+===================
+
+Below is a complete example demonstrating how an application can download a remote configuration
+file using the streaming callback API ``tftpget_cb()``:
+
+.. code-block:: c
+
+   #include <nuttx/config.h>
+   #include <stdio.h>
+   #include <string.h>
+   #include <errno.h>
+   #include <arpa/inet.h>
+   #include <netutils/tftp.h>
+
+   struct memory_sink_s
+   {
+     FAR uint8_t *buffer;
+     size_t max_size;
+     size_t total_received;
+   };
+
+   static ssize_t tftp_recv_cb(FAR void *ctx, uint32_t offset,
+                               FAR uint8_t *buf, size_t len)
+   {
+     FAR struct memory_sink_s *sink = (FAR struct memory_sink_s *)ctx;
+
+     if (sink->total_received + len > sink->max_size)
+       {
+         fprintf(stderr, "Buffer overflow: payload exceeds capacity\n");
+         return -ENOMEM;
+       }
+
+     memcpy(sink->buffer + sink->total_received, buf, len);
+     sink->total_received += len;
+
+     return len;
+   }
+
+   int fetch_config(FAR const char *server_ip, FAR const char *filename,
+                    FAR uint8_t *dest_buf, size_t max_len)
+   {
+     struct memory_sink_s sink;
+     in_addr_t server_addr;
+     int ret;
+
+     server_addr = inet_addr(server_ip);
+     if (server_addr == INADDR_NONE)
+       {
+         return -EINVAL;
+       }
+
+     sink.buffer = dest_buf;
+     sink.max_size = max_len;
+     sink.total_received = 0;
+
+     ret = tftpget_cb(filename, server_addr, true, tftp_recv_cb, &sink);
+     if (ret < 0)
+       {
+         return ret;
+       }
+
+     return (int)sink.total_received;
+   }