nRF5 IoT SDK  v0.9.0
 All Data Structures Functions Variables Typedefs Enumerations Enumerator Groups Pages
Trivial File Transfer Protocol (TFTP)

The TFTP client module provides the functionality for both sending and retrieving files from the file server using Trivial File Transfer Protocol which uses UDP as a transport layer. The module sends requests to the server and manages file transfers using File abstraction.

This module supports several extensions like negotiating connection parameters, informing about file size, and setting a retransmission interval. These features enable files to be downloaded/uploaded in blocks with negotiated size and to control transmission speed.

For more information see the References section.

Note
The TFTP module is implemented on top of the User Datagram Protocol (UDP) module. Therefore, an additional UDP socket has to be allocated for each TFTP instance to work.
The retry mechanism requires the IoT Timer module to be present.
The application has to use at least one IoT File port to be able to use this module.

TFTP transfers

The following sections describe TFTP transactions and show how to use this module.

Negotiation of connection parameters

Figure 1 shows the negotiation procedure between the TFTP client and TFTP server.

msc_tftp_request_flow
Figure 1. Negotiation procedure

The client sends a read or write request (RRQ/WRQ) to the server. If the client supports some of the TFTP extensions, it appends parameter names and its values to the packet.

Note
Requests are variable in length, encoded in ASCII. The password option isn't officially supported, but some vendors add it as a last string in the list of options, without an option name. If the server understands the received options, it answers with an option acknowledgement (OACK) packet. This packet contains values which are aligned due to received request or just send first data block (read request) or an acknowledgement (ACK) of packet zero. The client can drop the connection by sending an error packet or starting a file transfer.

The following piece of code will initialize the TFTP client and send a request to the server:

// Create TFT instance when UDP sockets are ready.
static void ip_stack_init(void)
{
iot_tftp_init_t tftp_init_params;
...
// Set basic parameters.
tftp_init_params.p_ipv6_addr = &m_peer_addr; // IPv6 address of the server.
tftp_init_params.src_port = 100; // Local port from which all packets will be sent.
tftp_init_params.dst_port = 69; // Initial server port, where requests will be sent.
tftp_init_params.callback = app_tftp_handler; // Application callback in order to handle errors and transfer completion.
// Initialize instance.
err_code = iot_tftp_init(&m_tftp, &tftp_init_params);
APP_ERROR_CHECK(err_code);
...
}

File transfer

Figure 2 shows the file transfer from the server.

msc_tftp_transfer_flow
Figure 2. File transfer.

File transfers in TFTP are controlled by ACK packets. Each data chunk has to be acknowledged by the other side. The first data packet, which is smaller, marks the end of a file transfer. If the file size is a multiple of a block size, the last data packet contains the block ID and a zero-length payload.

Controlling transmission

To provide better control over the transmission speed, the server will always wait for ACK or next DATA packet. The following figure shows the flow inside the application.

msc_tftp_transfer_control_flow
Figure 3. Flow control.

The TFTP module calls the user callback only on events like error or transfer complete, but if it sees that the passed file instance has assigned a callback, it holds transmission on every packet. By doing that, the application can release the transfer by calling iot_tftp_resume() or wait to slow the transmission. It also allows data transfer onto devices with longer access time.

The following code presents the easiest, fast release policy:

static void app_iot_file_cb(iot_file_t * p_file, iot_file_evt_t event, uint32_t result, void * p_data, uint32_t size)
{
switch(event)
{
iot_tftp_resume(&m_tftp);
break;
iot_tftp_abort(&m_tftp);
break;
default:
break;
}
}
int main(void)
{
...
trans_params.block_size = 16; // Block size of a single data chunk. Could be reduced by a negotiating procedure.
trans_params.next_retr = 3; // Time in seconds between retransmitted packets. Could be reduced by a negotiating procedure.
iot_tftp_get(&m_tftp, &m_file);
...
}

Disconnecting

Connections finish when one side sends an error packet or if the last data packet was received. To stop transfer, send an error packet and drop into idle state. The TFTP module provides the iot_tftp_abort() function and the iot_tftp_uninit call to close the connection and release UDP sockets.

msc_tftp_transfer_abort
Figure 4. Cancelling file transfers.

Configuration parameters

The following configuration parameters should be defined in sdk_config.h.

TFTP_DISABLE_LOGS

Disables debug tracing in the module. To enable tracing, this flag must be set to 0 and ENABLE_DEBUG_LOG_SUPPORT must be set to 1.

Description Value
Enable debug trace 0
Disable debug trace 1
Dependencies ENABLE_DEBUG_LOG_SUPPORT

TFTP_DISABLE_API_PARAM_CHECK

Disables API parameter checks in the module. Set this define to 1 to disable checks on API parameters in the module.

API parameter checks are added to ensure that the correct parameters are passed to the module. These checks are useful during development phase, but they might be redundant when the application is finalized. Disabling these checks might improve performance.

Description Value
Enable API parameters check 0
Disable API parameters check 1
Dependencies None

TFTP_MAX_RETRANSMISSION_COUNT

Maximum number of retransmitted packets.

Restriction Value
Minimum value 0
Maximum value 255
Recommended value 3
Dependencies None

TFTP_MAX_INSTANCES

Maximum number of TFTP client instances.

Restriction Value
Minimum value 1
Maximum value 255
Dependencies None

Specifics and limitations

The following sections describe the specifics and limitations to the current implementation.

Implemented features

  • TFTP client which supports option extension and octet transmission mode.
  • Supported options:
    • blocksize
    • timeout
    • file size (tsize)
    • password
  • TFTP file transfers with flow control.
  • Asynchronous API for background file download/upload.

Limitations

  • No TFTP Server implementation.
  • No encryption.
  • Currently only 'octet' mode of transfering files to TFTP server is supported.

References