1 /*
2  * Copyright (c) 2020 InnBlue
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /** @file tftp.h
8  *
9  * @brief TFTP Client Implementation
10  *
11  * @defgroup tftp_client TFTP Client library
12  * @since 2.3
13  * @version 0.1.0
14  * @ingroup networking
15  * @{
16  */
17 
18 #ifndef ZEPHYR_INCLUDE_NET_TFTP_H_
19 #define ZEPHYR_INCLUDE_NET_TFTP_H_
20 
21 #include <zephyr/kernel.h>
22 #include <zephyr/net/socket.h>
23 
24 #ifdef __cplusplus
25 extern "C" {
26 #endif
27 
28 /**
29  * RFC1350: the file is sent in fixed length blocks of 512 bytes.
30  * Each data packet contains one block of data, and must be acknowledged
31  * by an acknowledgment packet before the next packet can be sent.
32  * A data packet of less than 512 bytes signals termination of a transfer.
33  */
34 #define TFTP_BLOCK_SIZE          512
35 
36 /**
37  * RFC1350: For non-request TFTP message, the header contains 2-byte operation
38  * code plus 2-byte block number or error code.
39  */
40 #define TFTP_HEADER_SIZE         4
41 
42 /** Maximum amount of data that can be sent or received */
43 #define TFTPC_MAX_BUF_SIZE       (TFTP_BLOCK_SIZE + TFTP_HEADER_SIZE)
44 
45 /**
46  * @name TFTP client error codes.
47  * @{
48  */
49 #define TFTPC_SUCCESS             0 /**< Success. */
50 #define TFTPC_DUPLICATE_DATA     -1 /**< Duplicate data received. */
51 #define TFTPC_BUFFER_OVERFLOW    -2 /**< User buffer is too small. */
52 #define TFTPC_UNKNOWN_FAILURE    -3 /**< Unknown failure. */
53 #define TFTPC_REMOTE_ERROR       -4 /**< Remote server error. */
54 #define TFTPC_RETRIES_EXHAUSTED  -5 /**< Retries exhausted. */
55 /**
56  * @}
57  */
58 
59 /**
60  * @brief TFTP Asynchronous Events notified to the application from the module
61  *        through the callback registered by the application.
62  */
63 enum tftp_evt_type {
64 	/**
65 	 * DATA event when data is received from remote server.
66 	 *
67 	 * @note DATA event structure contains payload data and size.
68 	 */
69 	TFTP_EVT_DATA,
70 
71 	/**
72 	 * ERROR event when error is received from remote server.
73 	 *
74 	 * @note ERROR event structure contains error code and message.
75 	 */
76 	TFTP_EVT_ERROR
77 };
78 
79 /** @brief Parameters for data event. */
80 struct tftp_data_param {
81 	uint8_t *data_ptr;         /**< Pointer to binary data. */
82 	uint32_t len;              /**< Length of binary data. */
83 };
84 
85 /** @brief Parameters for error event. */
86 struct tftp_error_param {
87 	char *msg;                 /**< Error message. */
88 	int code;                  /**< Error code. */
89 };
90 
91 /**
92  * @brief Defines event parameters notified along with asynchronous events
93  *        to the application.
94  */
95 union tftp_evt_param {
96 	/** Parameters accompanying TFTP_EVT_DATA event. */
97 	struct tftp_data_param data;
98 
99 	/** Parameters accompanying TFTP_EVT_ERROR event. */
100 	struct tftp_error_param error;
101 };
102 
103 /** @brief Defines TFTP asynchronous event notified to the application. */
104 struct tftp_evt {
105 	/** Identifies the event. */
106 	enum tftp_evt_type type;
107 
108 	/** Contains parameters (if any) accompanying the event. */
109 	union tftp_evt_param param;
110 };
111 
112 /**
113  * @typedef tftp_callback_t
114  *
115  * @brief TFTP event notification callback registered by the application.
116  *
117  * @param[in] evt Event description along with result and associated
118  *                parameters (if any).
119  */
120 typedef void (*tftp_callback_t)(const struct tftp_evt *evt);
121 
122 /**
123  * @brief TFTP client definition to maintain information relevant to the
124  *        client.
125  *
126  * @note Application must initialize `server` and `callback` before calling
127  *       GET or PUT API with the `tftpc` structure.
128  */
129 struct tftpc {
130 	/** Socket address pointing to the remote TFTP server */
131 	struct sockaddr server;
132 
133 	/** Event notification callback. No notification if NULL */
134 	tftp_callback_t callback;
135 
136 	/** Buffer for internal usage */
137 	uint8_t tftp_buf[TFTPC_MAX_BUF_SIZE];
138 };
139 
140 /**
141  * @brief This function gets data from a "file" on the remote server.
142  *
143  * @param client      Client information of type @ref tftpc.
144  * @param remote_file Name of the remote file to get.
145  * @param mode        TFTP Client "mode" setting.
146  *
147  * @retval The size of data being received if the operation completed successfully.
148  * @retval TFTPC_BUFFER_OVERFLOW if the file is larger than the user buffer.
149  * @retval TFTPC_REMOTE_ERROR if the server failed to process our request.
150  * @retval TFTPC_RETRIES_EXHAUSTED if the client timed out waiting for server.
151  * @retval -EINVAL if `client` is NULL.
152  *
153  * @note This function blocks until the transfer is completed or network error happens. The
154  *       integrity of the `client` structure must be ensured until the function returns.
155  */
156 int tftp_get(struct tftpc *client,
157 	     const char *remote_file, const char *mode);
158 
159 /**
160  * @brief This function puts data to a "file" on the remote server.
161  *
162  * @param client      Client information of type @ref tftpc.
163  * @param remote_file Name of the remote file to put.
164  * @param mode        TFTP Client "mode" setting.
165  * @param user_buf    Data buffer containing the data to put.
166  * @param user_buf_size Length of the data to put.
167  *
168  * @retval The size of data being sent if the operation completed successfully.
169  * @retval TFTPC_REMOTE_ERROR if the server failed to process our request.
170  * @retval TFTPC_RETRIES_EXHAUSTED if the client timed out waiting for server.
171  * @retval -EINVAL if `client` or `user_buf` is NULL or if `user_buf_size` is zero.
172  *
173  * @note This function blocks until the transfer is completed or network error happens. The
174  *       integrity of the `client` structure must be ensured until the function returns.
175  */
176 int tftp_put(struct tftpc *client,
177 	     const char *remote_file, const char *mode,
178 	     const uint8_t *user_buf, uint32_t user_buf_size);
179 
180 #ifdef __cplusplus
181 }
182 #endif
183 
184 #endif /* ZEPHYR_INCLUDE_NET_TFTP_H_ */
185 
186 /** @} */
187