libflute
Classes | Public Types | Public Member Functions | List of all members
LibFlute::Transmitter Class Reference

FLUTE transmitter class. More...

#include <Transmitter.h>

Classes

class  FileDescription
 File Description object. More...
 

Public Types

using FdtNamespace = FileDeliveryTable::FdtNamespace
 FDT namespace enumeration. More...
 
typedef std::function< void(uint32_t)> completion_callback_t
 Definition of a file transmission completion callback function that can be registered through ::register_completion_callback. More...
 

Public Member Functions

 Transmitter (const std::string &destination_address, short port, uint64_t tsi, unsigned short mtu, uint32_t rate_limit, boost::asio::io_context &io_context, const std::optional< boost::asio::ip::udp::endpoint > &tunnel_endpoint=std::nullopt, FdtNamespace fdt_namespace=FileDeliveryTable::FDT_NS_NONE, bool active=true, const std::optional< std::string > &source_address=std::nullopt)
 Constructor. More...
 
virtual ~Transmitter ()
 Default destructor. More...
 
const std::optional< boost::asio::ip::udp::endpoint > & udp_tunnel_address () const
 Get UDP Tunnel Address. More...
 
Transmitterudp_tunnel_address (const boost::asio::ip::udp::endpoint &new_tunnel_endpoint)
 Set UDP Tunnel Address. More...
 
Transmitterudp_tunnel_address (boost::asio::ip::udp::endpoint &&new_tunnel_endpoint)
 Set UDP Tunnel Address. More...
 
Transmitterudp_tunnel_address (const std::optional< boost::asio::ip::udp::endpoint > &new_tunnel_endpoint)
 Set UDP Tunnel Address. More...
 
Transmitterudp_tunnel_address (std::optional< boost::asio::ip::udp::endpoint > &&new_tunnel_endpoint)
 Set UDP Tunnel Address. More...
 
Transmitterudp_tunnel_address (const std::nullopt_t &)
 Unset UDP Tunnel Address. More...
 
uint32_t rate_limit () const
 Get Maximum Bit Rate. More...
 
Transmitterrate_limit (uint32_t limit)
 Set Maximum Bit Rate. More...
 
const boost::asio::ip::udp::endpoint & endpoint () const
 Get UDP Address for FLUTE session. More...
 
Transmitterendpoint (const std::string &address, uint32_t port)
 Set UDP Address for FLUTE session. More...
 
const std::optional< boost::asio::ip::address > & source_address () const
 Get the optional source address for the FLUTE session. More...
 
void enable_ipsec (uint32_t spi, const std::string &aes_key)
 Enable IPSEC ESP encryption of FLUTE payloads. More...
 
uint16_t send (const std::string &content_location, const std::string &content_type, uint32_t expires, char *data, size_t length)
 Transmit a file (deprecated). More...
 
uint16_t send (const std::shared_ptr< FileDescription > &file_description)
 Transmit a file. More...
 
uint64_t seconds_since_epoch ()
 Convenience function to get the current timestamp for expiry calculation. More...
 
void register_completion_callback (completion_callback_t cb)
 Register a callback for file transmission completion notifications. More...
 
void activate ()
 Activate the FLUTE session. More...
 
void deactivate ()
 Deactivate the FLUTE session. More...
 
size_t number_of_files ()
 Get number of files currently in queue for sending. More...
 
Transmitterendpoint (const boost::asio::ip::udp::endpoint &destination)
 Set UDP Address for FLUTE session. More...
 
Transmitterendpoint (boost::asio::ip::udp::endpoint &&destination)
 
Transmittersource_address (const std::optional< boost::asio::ip::address > &source)
 Set the source address for FLUTE session. More...
 
Transmittersource_address (std::optional< boost::asio::ip::address > &&source)
 

Detailed Description

FLUTE transmitter class.

Construct an instance of this to send data through a FLUTE/ALC session.

The session can be active (sending packets) or inactive (sending of packets paused). This allows the FLUTE session to be suspended using the deactivate() method and later resumed using activate().

Definition at line 40 of file Transmitter.h.

Member Typedef Documentation

◆ completion_callback_t

typedef std::function<void(uint32_t)> LibFlute::Transmitter::completion_callback_t

Definition of a file transmission completion callback function that can be registered through ::register_completion_callback.

Parameters
toiTOI of the file that has completed transmission

Definition at line 365 of file Transmitter.h.

◆ FdtNamespace

FDT namespace enumeration.

Definition at line 45 of file Transmitter.h.

Constructor & Destructor Documentation

◆ Transmitter()

LibFlute::Transmitter::Transmitter ( const std::string &  destination_address,
short  port,
uint64_t  tsi,
unsigned short  mtu,
uint32_t  rate_limit,
boost::asio::io_context &  io_context,
const std::optional< boost::asio::ip::udp::endpoint > &  tunnel_endpoint = std::nullopt,
Transmitter::FdtNamespace  fdt_namespace = FileDeliveryTable::FDT_NS_NONE,
bool  active = true,
const std::optional< std::string > &  source_address = std::nullopt 
)

Constructor.

Creates a Transmitter object.

If tunnel_endpoint is given a value then:

  • destination_address is the encapsulated destination IP addresses.
  • If source_address has a value then this is used as the encapsulated source IP address, if not then the source address of the connection to tunnel_endpoint is used.

If tunnel_endpoint is not given a value then:

  • destination_address is the destination address for the connection.
  • If source_address has a value then an attempt will be made to bind the local end of the connection to this address. If the attempt is unsuccessful then a std::runtime_error exception will be thrown.
Parameters
destination_addressTarget (multicast) address, if tunnel_endpoint is given then this is the encapsulated destination IP address
portTarget port
tsiTSI value for the session
mtuPath MTU to size FLUTE packets for
rate_limitTransmit rate limit (in kbps)
io_contextBoost io_context to run the socket operations in (must be provided by the caller)
tunnel_endpointTunnelling endpoint address (default: no tunnelling)
fdt_namespaceWhich XML namespace to use for the FDT (default: none)
activeStart as active/inactive FLUTE session (default: active)
source_addressSource address (default: automatically assign source address)
Exceptions
boost::system::system_errorWhen source_address is given a value and tunnel_endpoint has no value and the address in source_address could not be bound as the local end of the connection.

Definition at line 459 of file Transmitter.cpp.

465  : _endpoint(boost::asio::ip::make_address(destination_address), port)
466  , _source_address()
467  , _socket(io_context, _endpoint.protocol())
468  , _io_context(io_context)
469  , _send_timer(io_context)
470  , _fdt_timer(io_context)
471  , _tsi(tsi)
472  , _mtu(mtu)
473  , _files()
474  , _files_mutex()
475  , _mcast_address(destination_address)
476  , _rate_limit(rate_limit)
477  , _tunnel_endpoint(tunnel_endpoint)
478  , _tunnel_local_address()
479  , _active(active)
480 {
481  if (source_address) {
482  _source_address = boost::asio::ip::make_address(source_address.value());
483  }
484  _max_payload = mtu -
485  20 - // IPv4 header
486  8 - // UDP header
487  32 - // ALC Header with EXT_FDT and EXT_FTI
488  4; // SBN and ESI for compact no-code FEC
489  if (_tunnel_endpoint.has_value()) {
490  // Remove extra overhead for UDP tunnelling, if set
491  _max_payload -= 20 + // IPv4 header
492  8; // UDP header
493  boost::asio::ip::udp::socket local_socket(_io_context, _tunnel_endpoint.value().protocol());
494  local_socket.connect(_tunnel_endpoint.value());
495  _tunnel_local_address = local_socket.local_endpoint().address();
496  }
497  uint32_t max_source_block_length = 64;
498 
499  _socket.set_option(boost::asio::ip::multicast::enable_loopback(true));
500  _socket.set_option(boost::asio::ip::udp::socket::reuse_address(true));
501 
502  if (_source_address && !_tunnel_endpoint) {
503  _socket.bind(boost::asio::ip::udp::endpoint(_source_address.value(),0));
504  }
505 
506  _fec_oti = FecOti{
508  .encoding_symbol_length = _max_payload,
509  .max_source_block_length = max_source_block_length};
510  _fdt = std::make_unique<FileDeliveryTable>(1, _fec_oti, fdt_namespace);
511 
512  if (_active) {
513  start_fdt_repeat_timer();
514  send_next_packet();
515  }
516 }
const std::optional< boost::asio::ip::address > & source_address() const
Get the optional source address for the FLUTE session.
Definition: Transmitter.h:531
uint32_t rate_limit() const
Get Maximum Bit Rate.
Definition: Transmitter.h:474
FecScheme encoding_id
Definition: flute_types.h:52

◆ ~Transmitter()

LibFlute::Transmitter::~Transmitter ( )
virtualdefault

Default destructor.

Member Function Documentation

◆ activate()

auto LibFlute::Transmitter::activate ( )

Activate the FLUTE session.

If the Transmitter is currently deactivated then the state is set to active and the FLUTE stream will start transmitting. Sending of packets will start or resume until the deactivate() method is called or this Transmitter is destroyed.

Definition at line 807 of file Transmitter.cpp.

808 {
809  if (!_active) {
810  _active = true;
811  start_fdt_repeat_timer();
812  send_next_packet();
813  }
814 }

◆ deactivate()

auto LibFlute::Transmitter::deactivate ( )

Deactivate the FLUTE session.

If the Transmitter is currently active then the FLUTE stream is halted and the state is changed to deactivated. Sending of packets will be halted until the activate() method is called. Note that this will pause File transmission part way through if a File is currently being transmitted. If the application wishes for deactivation once Files have finished sending then it should only deactivate() when the completion callback is called and number_of_files() equals 0 to ensure all Files have been completely transmitted.

Definition at line 816 of file Transmitter.cpp.

817 {
818  if (_active) {
819  _active = false;
820  _fdt_timer.cancel();
821  _send_timer.cancel();
822  }
823 }

◆ enable_ipsec()

auto LibFlute::Transmitter::enable_ipsec ( uint32_t  spi,
const std::string &  aes_key 
)

Enable IPSEC ESP encryption of FLUTE payloads.

Parameters
spiSecurity Parameter Index value to use
aes_keyAES key as a hex string (without leading 0x). Must be an even number of characters long.

Definition at line 600 of file Transmitter.cpp.

601 {
602  IpSec::enable_esp(spi, _mcast_address, IpSec::Direction::Out, key);
603 }
void enable_esp(uint32_t spi, const std::string &dest_address, Direction direction, const std::string &key)
Definition: IpSec.cpp:124

◆ endpoint() [1/4]

const boost::asio::ip::udp::endpoint& LibFlute::Transmitter::endpoint ( ) const
inline

Get UDP Address for FLUTE session.

Gets the destination address for the FLUTE session packets. If the UDP tunnel address is set then the packets will be tunnelled to the UDP tunnel address, otherwise packets are sent directly to the destination address.

Returns
The current destination address.

Definition at line 494 of file Transmitter.h.

494 { return _endpoint; };

◆ endpoint() [2/4]

auto LibFlute::Transmitter::endpoint ( boost::asio::ip::udp::endpoint &&  destination)

Definition at line 576 of file Transmitter.cpp.

577 {
578  _endpoint = std::move(destination);
579  return *this;
580 }

◆ endpoint() [3/4]

auto LibFlute::Transmitter::endpoint ( const boost::asio::ip::udp::endpoint &  destination)

Set UDP Address for FLUTE session.

Sets the destination address for FLUTE session packets. If the UDP Tunnel Address is not set then FLUTE packets will be sent directly to this UDP endpoint. When a UDP Tunnel Address is set then FLUTE packets with this destination will be tunnelled to the UDP Tunnel Address.

Parameters
destinationThe UDP endpoint to set as the FLUTE packet destination address and port.
Returns
This Transmitter object.

Definition at line 570 of file Transmitter.cpp.

571 {
572  _endpoint = destination;
573  return *this;
574 }

◆ endpoint() [4/4]

auto LibFlute::Transmitter::endpoint ( const std::string &  address,
uint32_t  port 
)

Set UDP Address for FLUTE session.

Sets the destination address for FLUTE session packets. If the UDP Tunnel Address is not set then FLUTE packets will be sent directly to this UDP endpoint. When a UDP Tunnel Address is set then FLUTE packets with this destination will be tunnelled to the UDP Tunnel Address.

Parameters
addressThe IP address or hostname to set as the FLUTE packet destination address.
portThe UDP port number to set as the FLUTE packet destination UDP port.
Returns
This Transmitter object.

Definition at line 565 of file Transmitter.cpp.

566 {
567  return endpoint(boost::asio::ip::udp::endpoint(boost::asio::ip::make_address(address), port));
568 }
const boost::asio::ip::udp::endpoint & endpoint() const
Get UDP Address for FLUTE session.
Definition: Transmitter.h:494

◆ number_of_files()

size_t LibFlute::Transmitter::number_of_files ( )
inline

Get number of files currently in queue for sending.

Returns
The number of files in the queue for sending.

Definition at line 635 of file Transmitter.h.

635 { std::lock_guard<std::mutex> guard(_files_mutex); return _files.size(); };

◆ rate_limit() [1/2]

uint32_t LibFlute::Transmitter::rate_limit ( ) const
inline

Get Maximum Bit Rate.

Returns the maximum bit rate (MBR) value that the Transmitter is using. A 0 MBR means no limit.

Returns
The maximum bit rate.

Definition at line 474 of file Transmitter.h.

474 { return _rate_limit; };

◆ rate_limit() [2/2]

Transmitter& LibFlute::Transmitter::rate_limit ( uint32_t  limit)
inline

Set Maximum Bit Rate.

Sets the MBR for transmission. A value of 0 indicates no rate limit.

Parameters
limitThe new MBR to set.
Returns
This Transmitter object.

Definition at line 484 of file Transmitter.h.

484 { _rate_limit = limit; return *this; };

◆ register_completion_callback()

void LibFlute::Transmitter::register_completion_callback ( completion_callback_t  cb)
inline

Register a callback for file transmission completion notifications.

Parameters
cbFunction to call on file completion

Definition at line 609 of file Transmitter.h.

609 { _completion_cb = cb; };

◆ seconds_since_epoch()

auto LibFlute::Transmitter::seconds_since_epoch ( )

Convenience function to get the current timestamp for expiry calculation.

Returns
seconds since the NTP epoch

Definition at line 611 of file Transmitter.cpp.

612 {
613  return std::chrono::duration_cast<std::chrono::seconds>(
614  std::chrono::system_clock::now().time_since_epoch()).count() +
615  2'208'988'800; /* add the difference in seconds between the Unix epoch (1 January 1970, 00:00:00 UTC)
616  and the NTP epoch (1 January 1900, 00:00:00 UTC) */
617 }

◆ send() [1/2]

uint16_t LibFlute::Transmitter::send ( const std::shared_ptr< FileDescription > &  file_description)

Transmit a file.

The caller must ensure the file description passed here remains valid until the completion callback for this file description is called.

The file description object passed in file_description may be updated by the Transmitter until the completion callback for this file description is called.

If a file description is reused then the TOI of the previous use is reused. This allows resends or updates to existing files to be transmitted.

Parameters
file_descriptionThe file description object for the file to send
Returns
TOI of the file.

◆ send() [2/2]

auto LibFlute::Transmitter::send ( const std::string &  content_location,
const std::string &  content_type,
uint32_t  expires,
char *  data,
size_t  length 
)

Transmit a file (deprecated).

Deprecated:
send(FileDescription*) should be used instead.

The caller must ensure the data buffer passed here remains valid until the completion callback for this file is called.

Parameters
content_locationURI to set in the content location field of the generated FDT entry
content_typeMIME type to set in the content type field of the generated FDT entry
expiresExpiry timestamp (based on NTP epoch)
dataPointer to the data buffer (managed by caller)
lengthLength of the data buffer (in bytes)
Returns
TOI of the file

Definition at line 643 of file Transmitter.cpp.

649 {
650  auto toi = _toi;
651  _toi++;
652  if (_toi == 0) _toi = 1; // clamp to >= 1 in case it wraps
653 
654  auto file = std::make_shared<File>(
655  toi,
656  _fec_oti,
657  content_location,
658  content_type,
659  expires,
660  data,
661  length);
662 
663  _fdt->add(file->meta());
664  send_fdt();
665  {
666  std::lock_guard<std::mutex> guard(_files_mutex);
667  _files.insert({toi, file});
668  }
669  return toi;
670 }

◆ source_address() [1/3]

const std::optional<boost::asio::ip::address>& LibFlute::Transmitter::source_address ( ) const
inline

Get the optional source address for the FLUTE session.

Returns
The optional source address being used.

Definition at line 531 of file Transmitter.h.

531 { return _source_address; };

◆ source_address() [2/3]

auto LibFlute::Transmitter::source_address ( const std::optional< boost::asio::ip::address > &  source)

Set the source address for FLUTE session.

Sets the optional source address to use for FLUTE session packets. If the UDP Tunnel Address is not set then the outgoing socket will be bound to this address, if set. When a UDP Tunnel Address is set then this provides the source address for encapsulated packets. If the source address is not set then a local address will be selected automatically.

Parameters
sourceThe IP source address to use for FLUTE packets.
Returns
This Transmitter object.
Exceptions
boost::system::system_errorIf UDP tunnel is not used and the UDP socket cannot be bound to source.

Definition at line 582 of file Transmitter.cpp.

583 {
584  _source_address = source_address;
585  if (_source_address && !_tunnel_endpoint) {
586  _socket.bind(boost::asio::ip::udp::endpoint(_source_address.value(),0));
587  }
588  return *this;
589 }

◆ source_address() [3/3]

auto LibFlute::Transmitter::source_address ( std::optional< boost::asio::ip::address > &&  source)

Definition at line 591 of file Transmitter.cpp.

592 {
593  _source_address = std::move(source_address);
594  if (_source_address && !_tunnel_endpoint) {
595  _socket.bind(boost::asio::ip::udp::endpoint(_source_address.value(),0));
596  }
597  return *this;
598 }

◆ udp_tunnel_address() [1/6]

const std::optional<boost::asio::ip::udp::endpoint>& LibFlute::Transmitter::udp_tunnel_address ( ) const
inline

Get UDP Tunnel Address.

Returns
The optional UDP Tunnel Address for the Transmitter to use.

Definition at line 416 of file Transmitter.h.

416 { return _tunnel_endpoint; };

◆ udp_tunnel_address() [2/6]

auto LibFlute::Transmitter::udp_tunnel_address ( boost::asio::ip::udp::endpoint &&  new_tunnel_endpoint)

Set UDP Tunnel Address.

Sets the UDP tunnel endpoint to be new_tunnel_endpoint. This moves the value from new_tunnel_endpoint.

Parameters
new_tunnel_endpointThe new UDP tunnel endpoint to set.
Returns
This Transmitter object.

Definition at line 525 of file Transmitter.cpp.

526 {
527  return udp_tunnel_address(std::optional<boost::asio::ip::udp::endpoint>(std::move(new_tunnel_endpoint)));
528 }
const std::optional< boost::asio::ip::udp::endpoint > & udp_tunnel_address() const
Get UDP Tunnel Address.
Definition: Transmitter.h:416

◆ udp_tunnel_address() [3/6]

auto LibFlute::Transmitter::udp_tunnel_address ( const boost::asio::ip::udp::endpoint &  new_tunnel_endpoint)

Set UDP Tunnel Address.

Sets the UDP tunnel endpoint to be a copy of new_tunnel_endpoint.

Parameters
new_tunnel_endpointThe new UDP tunnel endpoint to set.
Returns
This Transmitter object.

Definition at line 520 of file Transmitter.cpp.

521 {
522  return udp_tunnel_address(std::optional<boost::asio::ip::udp::endpoint>(new_tunnel_endpoint));
523 }

◆ udp_tunnel_address() [4/6]

auto LibFlute::Transmitter::udp_tunnel_address ( const std::nullopt_t &  )

Unset UDP Tunnel Address.

Removes the UDP tunnel endpoint. If the stream is active then it will switch back to multicast transmission.

Returns
This Transmitter object.

Definition at line 560 of file Transmitter.cpp.

561 {
562  return udp_tunnel_address(std::optional<boost::asio::ip::udp::endpoint>(std::nullopt));
563 }

◆ udp_tunnel_address() [5/6]

auto LibFlute::Transmitter::udp_tunnel_address ( const std::optional< boost::asio::ip::udp::endpoint > &  new_tunnel_endpoint)

Set UDP Tunnel Address.

Sets the UDP tunnel endpoint to be a copy of the optional new_tunnel_endpoint.

Parameters
new_tunnel_endpointThe optional UDP tunnel endpoint to set.
Returns
This Transmitter object.

Definition at line 530 of file Transmitter.cpp.

531 {
532  return udp_tunnel_address(std::move(std::optional<boost::asio::ip::udp::endpoint>(new_tunnel_endpoint)));
533 }

◆ udp_tunnel_address() [6/6]

auto LibFlute::Transmitter::udp_tunnel_address ( std::optional< boost::asio::ip::udp::endpoint > &&  new_tunnel_endpoint)

Set UDP Tunnel Address.

Sets the UDP tunnel endpoint to be the optional new_tunnel_endpoint. This moves the value from new_tunnel_endpoint.

Parameters
new_tunnel_endpointThe optional UDP tunnel endpoint to set.
Returns
This Transmitter object.

Definition at line 535 of file Transmitter.cpp.

536 {
537  if (!!_tunnel_endpoint == !!new_tunnel_endpoint) {
538  /* change existing tunnel */
539  if (_tunnel_endpoint) _tunnel_endpoint = new_tunnel_endpoint;
540  } else if (_tunnel_endpoint) {
541  /* removing tunnel */
542  _max_payload += 20 + // IPv4 header
543  8; // UDP header
544  _tunnel_endpoint = std::nullopt;
545  } else {
546  /* new tunnel */
547  _tunnel_endpoint = std::move(new_tunnel_endpoint);
548  _max_payload -= 20 + // IPv4 header
549  8; // UDP header
550  }
551 
552  if (_tunnel_endpoint) {
553  boost::asio::ip::udp::socket local_socket(_io_context, _tunnel_endpoint.value().protocol());
554  local_socket.connect(_tunnel_endpoint.value());
555  _tunnel_local_address = local_socket.local_endpoint().address();
556  }
557  return *this;
558 }

The documentation for this class was generated from the following files: