.. _btp:

==================
BTP Client Library
==================

The Blob Transfer Protocol (BTP) is a lightweight file transfer and remote shell protocol based on CSP. BTP supports upload and download of files, as well as basic file operations such as file listing, delete, copy and move. This document explains the protocol and the client implementation in ``btp-client`` and the ``btp`` command. 

On the Satlab products, BTP is mainly used for downloading payload data and to upload new software images. The remote shell interface can be used for advanced debugging on Linux systems if necessary.

BTP is built around a server task listening on a single port on the subsystem. Please consult the device client library for the BTP port of a specific device.

File Tranfer
============

The main feature of BTP is tranfer of files to and from the device. BTP works by dividing the transferred file into a number of blocks, and maintaining a bitmap of received blocks on the receiving end. The transfer progress is stored in a map-file that is named after the file being transferred. This allows the transfer to be aborted and resumed, e.g. to download a file over multiple passes of the satellite.

The figure below shows the message sequence for a download. A download starts with the client transmitting a download request to the server. This packet contains the filename to download and the size of the transfer blocks. This allows the block size to be adjusted to match the MTU of the connection to the server. A connection timeout value is also specified on the download request. The download request packet also contains fields to specify the *backend* to download from and fields to download only a part of a file from a specific offset. Currently, the "file" backend is implemented and the ``size`` and ``offset`` fields are not honored.

The server will reply with a download reply packet, which contains an error field that is used to report problems in the request, plus fields to return the size and CRC32 checksum of the file to be transferred. 

.. figure:: img/btp.svg
   :align: center
   :width: 55%

Next follows the actual transfer of the file blocks. The client first sends a download status request, that contains sequence number of the last received block and of the block with the largest sequence number received. The status (received or not received) of the blocks between these two sequence numbers are marked in a bitfield. The download status request is acknowledged with a download status reply with a error field. The client should now transmit a block request, that can either request a number of blocks from a specific sequence number or request the next missing blocks as specified by the status packet. The server will then send the requested blocks and go back and wait for a new status request or another block request. This sequence is looped until the file is complete at which point the client should send a complete request to gracefully close the connection.

The file upload sequence is similar to the download sequence, except that some of the packet directions are obviously reversed. Instead of an download request, an upload request should be sent which contains the same fields as the download request plus additional fields to specify the size and CRC32 checksum of the file to be uploaded. An upload request also includes a ``force`` boolean field to command the server to ignore any previous progress of the file, and a ``paranoid`` boolean field which can be used to request all blocks to be flushed to disk as soon as they are received. In order to detect a file that has already been uploaded, the upload reply packet contains the checksum and size of the current file on the server.

The upload request/reply sequence is followed by a upload status request, where the server will reply with a similar sequence number and bitfield packet as in the download case. The client can now transmit block reply packets to the server, while periodically requesting upload status until the file transfer is complete. Again, the transfer is finished with a complete request to close the connection gracefully.

File Operations
===============

In addition to file transfers, BTP also supports basic file operations. The delete, copy and move commands are the simplest and only consists of a single request packet with the backend name, and the filename to be deleted, copied or moved. The server replies with a reply packet that only contains an error code to signal if the file operation was successfully applied or not.

File listing is performed by sending a list request with the backend and path to list, plus the maximum number of file entries to reply with. The server will reply with a list reply packet that includes an error code and the number of file entries found in the path. Next, the server will then send file entry reply packets up to the number requested, or until entry packets have been sent for all files in the path. The client can now request subsequent file entries or retransmission of lost file entry packets by sending a file entry request for a specific sequence number.

Remote Shell
============

For Linux systems, BTP supports a remote shell over CSP similar to the well-known telnet used on TCP/IP networks. The remote shell can either be used to execute a single command or to run in an interactive session.

A remote shell session is initiated by sending a shell request to the server, containing the command to execute or an empty string to start interactive mode. A shell request contains a 16-bit ``count`` field that is used to limit the maximum number of reply packets the server should send, to prevent accidentally blocking the radio link. A single flag byte in the request packet can be used to request a character-delimited session where a packet is sent for every character entered on the client, instead of waiting for a complete line. This can be used to run remote applications that require the terminal to be in cbreak or raw mode.

The server will return output of the executed output in one or more shell reply packets, each containing an error code and up to 80 characters of output. The replies are sequence numbered and an included ``flag`` byte is used to mark when no more packets are to be expected. The client can then transmit another shell request with a new command. Alternatively, the client can send an empty shell request with the ``done`` bit set in the flag field to end the session.

BTP library and tools
=====================

The client BTP protocol as described in the previous sections is implemented in the ``btp-client`` library and used with the ``satctl`` tool. The packet types are all defined in ``include/btp/types.h`` and the client interface is defined in ``include/btp/client.h`` and implemented in ``src/client.c``. The ``btp`` command, implemented in ``src/cmd_btp.c``, is a convenient command line tool that wraps the client library.

The following listing shows the output from the command when run without arguments:

.. code-block:: none

  [satctl] help btp
  usage: btp <command> <remote file> [local file]
  Block Transfer Protocol client
  
  <command> is one of push, pull, list, rm, mv, cp or shell.
  
  Options:
   -n NODE,	Connect to NODE
   -p PORT,	Connect to PORT
   -b BACKEND,	Use BACKEND as backend
   -s BLOCKSIZE,Transfer data in BLOCKSIZE sized blocks
   -c COUNT,	Request COUNT blocks at a time
   -o OFFSET,	Start OFFSET bytes into file
   -z SIZE,	Download only SIZE bytes
   -t TIMEOUT,	Set timeout to TIMEOUT ms
   -a ATTEMPTS,	Retry connection up to ATTEMPTS tries
   -l LIMIT,	Stop after LIMIT bytes downloaded
   -q,		Quiet mode. Do not print progress bar
   -r,		Enable RDP for transfer
   -f,		Delete data and map file before starting transfer
   -d,		Paranoid mode. Always sync blocks to disk
   -j,		Single character terminal mode

The commands ``btp push`` and ``btp pull`` are used to upload and download files. To e.g. download a file called ``1M.bin`` from the root directory of the system on CSP address 22, use:

.. code-block:: none

  [satctl] btp -n22 pull /1M.bin 1M.bin
  100% [########################################] 1048576
  182.3 kbit/s (1048576 bytes in 44.940s)

The ``push`` command works in the same way, except that the local and remote path are swapped. Similarly, to show the contents of the file ``/testfile`` on address 22 using the remote shell interface, use:

.. code-block:: none

  [satctl] btp -n22 shell cat /testfile
  This is the contents of testfile

API Reference
=============

.. doxygenfile:: btp/client.h

.. doxygenfile:: btp/error.h

Protocol Reference
==================

.. doxygenfile:: btp/types.h
