1 /*
2 * Copyright (c) 2023 Kickmaker
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #define LOG_MODULE_NAME net_tftp_client_app
8 #define LOG_LEVEL LOG_LEVEL_DBG
9
10 #include <zephyr/logging/log.h>
11 LOG_MODULE_REGISTER(LOG_MODULE_NAME);
12
13 #include <zephyr/net/tftp.h>
14
15 #define APP_BANNER "Run TFTP client"
16 #define TFTP_SAMPLE_DATA "Lorem ipsum dolor sit amet, consectetur adipiscing elit"
17
18 static struct tftpc client;
19
tftp_event_callback(const struct tftp_evt * evt)20 static void tftp_event_callback(const struct tftp_evt *evt)
21 {
22 switch (evt->type) {
23 case TFTP_EVT_DATA:
24 LOG_HEXDUMP_INF(evt->param.data.data_ptr,
25 evt->param.data.len,
26 "Received data: ");
27 break;
28 case TFTP_EVT_ERROR:
29 LOG_ERR("Error code %d msg: %s",
30 evt->param.error.code,
31 evt->param.error.msg);
32 default:
33 break;
34 }
35 }
36
tftp_init(const char * hostname)37 static int tftp_init(const char *hostname)
38 {
39 struct sockaddr remote_addr;
40 struct addrinfo *res, hints = {0};
41 int ret;
42
43 /* Setup TFTP server address */
44 hints.ai_socktype = SOCK_DGRAM;
45
46 ret = getaddrinfo(hostname, CONFIG_TFTP_APP_PORT, &hints, &res);
47 if (ret != 0) {
48 LOG_ERR("Unable to resolve address");
49 /* DNS error codes don't align with normal errors */
50 return -ENOENT;
51 }
52
53 memcpy(&remote_addr, res->ai_addr, sizeof(remote_addr));
54 freeaddrinfo(res);
55
56 /* Save sockaddr into TFTP client handler */
57 memcpy(&client.server, &remote_addr, sizeof(client.server));
58 /* Register TFTP client callback */
59 client.callback = tftp_event_callback;
60
61 return 0;
62 }
63
main(void)64 int main(void)
65 {
66 int ret;
67
68 LOG_INF(APP_BANNER);
69
70 ret = tftp_init(CONFIG_TFTP_APP_SERVER);
71 if (ret < 0) {
72 LOG_ERR("Unable to initialize TFTP client");
73 return ret;
74 }
75
76 /* Get file1.bin in octet mode */
77 ret = tftp_get(&client, "file1.bin", "octet");
78 if (ret < 0) {
79 LOG_ERR("Error while getting file (%d)", ret);
80 return ret;
81 }
82
83 LOG_INF("TFTP client get done");
84
85 /* Put TFTP sample data into newfile.bin to server in octet mode */
86 ret = tftp_put(&client, "newfile.bin", "octet",
87 TFTP_SAMPLE_DATA, sizeof(TFTP_SAMPLE_DATA));
88 if (ret < 0 || ret != sizeof(TFTP_SAMPLE_DATA)) {
89 LOG_ERR("Error while putting file (%d)", ret);
90 return ret;
91 }
92
93 LOG_INF("TFTP client put done");
94
95 return 0;
96 }
97