Skip to content

Commit f75671d

Browse files
committed
samples: net: Add FTP client sample
Add a minimal FTP client sample, exposing FTP operations via network shell. Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
1 parent b825cd6 commit f75671d

File tree

5 files changed

+251
-0
lines changed

5 files changed

+251
-0
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
3+
cmake_minimum_required(VERSION 3.20.0)
4+
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
5+
project(ftp_client)
6+
7+
target_sources(app PRIVATE src/main.c)
8+
9+
include(${ZEPHYR_BASE}/samples/net/common/common.cmake)

‎samples/net/ftp_client/README.rst‎

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
.. zephyr:code-sample:: ftp-client
2+
:name: FTP client shell sample
3+
:relevant-api: ftp_client
4+
5+
FTP client sample interacting with FTP server over Zephyr shell.
6+
7+
Overview
8+
********
9+
10+
This sample demonstrates the use of the FTP client library to interact with a
11+
FTP server running on a host. The FTP commands are exposed via FTP shell module
12+
provided by Zephyr.
13+
14+
Requirements
15+
************
16+
17+
- :ref:`networking_with_eth_qemu`, :ref:`networking_with_qemu` or :ref:`networking_with_native_sim`
18+
- Linux machine
19+
20+
Building and Running
21+
********************
22+
23+
Build the Zephyr version of the application like this:
24+
25+
.. zephyr-app-commands::
26+
:zephyr-app: samples/net/ftp_client
27+
:board: <board_to_use>
28+
:goals: build
29+
:compact:
30+
31+
The sample requires a running FTP server to interact with. This for example can
32+
be achieved by running the Python `pyftpdlib`_ module, which provides built-in
33+
FTP server functionality:
34+
35+
.. code-block:: bash
36+
37+
pip install pyftpdlib
38+
mkdir file_root
39+
echo "some test data" > file_root/test_file.txt
40+
python3 -m pyftpdlib -p 2121 --write --directory=file_root
41+
42+
This installs the required Python package, creates a root that the FTP server
43+
will expose and creates a dummy test file. Note, that the server will run in a
44+
write-mode, allowing to create, delete and overwrite files and directories - be
45+
careful when using other root locations than the test directory.
46+
47+
Launch :command:`net-setup.sh` in net-tools:
48+
49+
.. code-block:: bash
50+
51+
./net-setup.sh
52+
53+
Build and run the FTP client sample application for native_sim:
54+
55+
.. zephyr-app-commands::
56+
:zephyr-app: samples/net/ftp_client
57+
:host-os: unix
58+
:board: native_sim
59+
:goals: run
60+
:compact:
61+
62+
The sample prints the greeting and exposes the network shell module to interact with:
63+
64+
.. code-block:: console
65+
66+
[00:00:00.000,000] <inf> net_config: Initializing network
67+
[00:00:00.000,000] <inf> net_config: IPv4 address: 192.0.2.1
68+
[00:00:00.110,000] <inf> net_config: IPv6 address: 2001:db8::1
69+
[00:00:00.110,000] <inf> net_config: IPv6 address: 2001:db8::1
70+
[00:00:00.110,000] <inf> ftp_client_sample: Starting FTP client sample
71+
[00:00:00.110,000] <inf> ftp_client_sample: Network connectivity established.
72+
[00:00:00.110,000] <inf> ftp_client_sample: You can interact with FTP server via shell.
73+
74+
Connect to the FTP server with ``net ftp connect`` command. The server by default
75+
exposes ``anonymous`` user with dummy password:
76+
77+
.. code-block:: console
78+
79+
uart:~$ net ftp connect anonymous null 192.0.2.2 2121
80+
220 pyftpdlib 2.1.0 ready.
81+
530 Log in with USER and PASS first.
82+
331 Username ok, send password.
83+
230 Login successful.
84+
85+
Once successfully connected, a various FTP commands can be executed to interact
86+
with the file system on the host.
87+
88+
List directory contents:
89+
90+
.. code-block:: console
91+
92+
uart:~$ net ftp ls
93+
227 Entering passive mode (192,0,2,2,146,7).
94+
150 File status okay. About to open data connection.
95+
-rw-r--r-- 1 user domain users 15 Feb 20 11:16 test_file.txt
96+
226 Transfer complete.
97+
98+
Read file content:
99+
100+
.. code-block:: console
101+
102+
uart:~$ net ftp get test_file.txt
103+
227 Entering passive mode (192,0,2,2,222,177).
104+
150 File status okay. About to open data connection.
105+
some test data
106+
226 Transfer complete.
107+
108+
Create a new directory, change working directory and print the current working directory:
109+
110+
.. code-block:: console
111+
112+
uart:~$ net ftp mkdir test_dir
113+
257 "/test_dir" directory created.
114+
uart:~$ net ftp cd test_dir
115+
250 "/test_dir" is the current directory.
116+
uart:~$ net ftp pwd
117+
257 "/test_dir" is the current directory.
118+
119+
Create a new file, print it's content and then remove it:
120+
121+
.. code-block:: console
122+
123+
uart:~$ net ftp put new_file.txt
124+
Input mode (max 2048 characters). End the line with \ to start a new one:
125+
New file content\
126+
127+
227 Entering passive mode (192,0,2,2,131,169).
128+
150 File status okay. About to open data connection.
129+
226 Transfer complete.
130+
uart:~$ net ftp get new_file.txt
131+
227 Entering passive mode (192,0,2,2,140,157).
132+
150 File status okay. About to open data connection.
133+
New file content
134+
226 Transfer complete.
135+
uart:~$ net ftp rm new_file.txt
136+
250 File removed.
137+
138+
Disconnect from the server:
139+
140+
.. code-block:: console
141+
142+
uart:~$ net ftp disconnect
143+
221 Goodbye.
144+
145+
A complete list of supported FTP commands can be listed with ``--help`` parameter:
146+
147+
.. code-block:: console
148+
149+
uart:~$ net ftp --help
150+
ftp - FTP client commands
151+
Subcommands:
152+
connect : Connect to FTP server.
153+
Usage: connect <username> <password> <hostname> [<port> <sec_tag>]
154+
disconnect : Disconnect from FTP server.
155+
Usage: disconnect
156+
status : Print connection status.
157+
Usage: status
158+
pwd : Print working directory.
159+
Usage: pwd
160+
ls : List information about folder or file.
161+
Usage: ls [<options> <path>]
162+
cd : Change working directory.
163+
Usage: cd <path>
164+
mkdir : Create directory.
165+
Usage: mkdir <dir_name>
166+
rmdir : Delete directory.
167+
Usage: rmdir <dir_name>
168+
rename : Rename a file.
169+
Usage: rename <old_name> <new_name>
170+
rm : Delete a file.
171+
Usage: rm <file_name>
172+
get : Read file content.
173+
Usage: get <file_name>
174+
put : Write to a file.
175+
Usage: put <file_name> [<data>]
176+
append : Append a file.
177+
Usage: append <file_name> <data>
178+
mode : Select transfer type.
179+
Usage: mode <ascii/binary>
180+
181+
.. _pyftpdlib: https://github.com/giampaolo/pyftpdlib

‎samples/net/ftp_client/prj.conf‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
CONFIG_ENTROPY_GENERATOR=y
2+
CONFIG_TEST_RANDOM_GENERATOR=y
3+
CONFIG_INIT_STACKS=y
4+
5+
CONFIG_NETWORKING=y
6+
CONFIG_NET_TCP=y
7+
CONFIG_NET_IPV6=y
8+
CONFIG_NET_IPV4=y
9+
CONFIG_NET_LOG=y
10+
CONFIG_NET_SHELL=y
11+
12+
CONFIG_NET_PKT_RX_COUNT=16
13+
CONFIG_NET_PKT_TX_COUNT=16
14+
CONFIG_NET_BUF_RX_COUNT=64
15+
CONFIG_NET_BUF_TX_COUNT=64
16+
17+
CONFIG_NET_CONFIG_SETTINGS=y
18+
CONFIG_NET_CONFIG_NEED_IPV6=y
19+
CONFIG_NET_CONFIG_NEED_IPV4=y
20+
CONFIG_NET_CONFIG_MY_IPV6_ADDR="2001:db8::1"
21+
CONFIG_NET_CONFIG_PEER_IPV6_ADDR="2001:db8::2"
22+
CONFIG_NET_CONFIG_MY_IPV4_ADDR="192.0.2.1"
23+
CONFIG_NET_CONFIG_PEER_IPV4_ADDR="192.0.2.2"
24+
25+
CONFIG_FTP_CLIENT=y
26+
CONFIG_DNS_RESOLVER=y

‎samples/net/ftp_client/sample.yaml‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
common:
2+
harness: net
3+
depends_on: netif
4+
tags:
5+
- net
6+
sample:
7+
name: FTP client
8+
tests:
9+
sample.net.ftp_client: {}

‎samples/net/ftp_client/src/main.c‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* Copyright (c) 2026 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <zephyr/logging/log.h>
8+
LOG_MODULE_REGISTER(ftp_client_sample, LOG_LEVEL_DBG);
9+
10+
#include <zephyr/kernel.h>
11+
12+
#include "net_sample_common.h"
13+
14+
int main(void)
15+
{
16+
LOG_INF("Starting FTP client sample");
17+
18+
wait_for_network();
19+
20+
LOG_INF("Network connectivity established.");
21+
LOG_INF("You can interact with FTP server via shell.");
22+
23+
k_sleep(K_FOREVER);
24+
25+
return 0;
26+
}

0 commit comments

Comments
 (0)