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 (bool finish_file_transmissions=false)
 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 41 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 384 of file Transmitter.h.

◆ FdtNamespace

FDT namespace enumeration.

Definition at line 46 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 475 of file Transmitter.cpp.

481  : _endpoint(boost::asio::ip::make_address(destination_address), port)
482  , _source_address()
483  , _socket(io_context, _endpoint.protocol())
484  , _io_context(io_context)
485  , _send_timer(io_context)
486  , _fdt_timer(io_context)
487  , _tsi(tsi)
488  , _mtu(mtu)
489  , _files()
490  , _files_mutex()
491  , _mcast_address(destination_address)
492  , _rate_limit(rate_limit)
493  , _tunnel_endpoint(tunnel_endpoint)
494  , _tunnel_local_address()
495  , _active(active)
496 {
497  if (source_address) {
498  _source_address = boost::asio::ip::make_address(source_address.value());
499  }
500  _max_payload = mtu -
501  20 - // IPv4 header
502  8 - // UDP header
503  32 - // ALC Header with EXT_FDT and EXT_FTI
504  4; // SBN and ESI for compact no-code FEC
505  if (_tunnel_endpoint.has_value()) {
506  // Remove extra overhead for UDP tunnelling, if set
507  _max_payload -= 20 + // IPv4 header
508  8; // UDP header
509  boost::asio::ip::udp::socket local_socket(_io_context, _tunnel_endpoint.value().protocol());
510  local_socket.connect(_tunnel_endpoint.value());
511  _tunnel_local_address = local_socket.local_endpoint().address();
512  }
513  uint32_t max_source_block_length = 64;
514 
515  _socket.set_option(boost::asio::ip::multicast::enable_loopback(true));
516  _socket.set_option(boost::asio::ip::udp::socket::reuse_address(true));
517 
518  if (_source_address && !_tunnel_endpoint) {
519  _socket.bind(boost::asio::ip::udp::endpoint(_source_address.value(),0));
520  }
521 
522  _fec_oti = FecOti{
524  .encoding_symbol_length = _max_payload,
525  .max_source_block_length = max_source_block_length};
526  _fdt = std::make_unique<FileDeliveryTable>(1, _fec_oti, fdt_namespace);
527 
528  if (_active) {
529  start_fdt_repeat_timer();
530  send_next_packet();
531  }
532 }
const std::optional< boost::asio::ip::address > & source_address() const
Get the optional source address for the FLUTE session.
Definition: Transmitter.h:550
uint32_t rate_limit() const
Get Maximum Bit Rate.
Definition: Transmitter.h:493
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 858 of file Transmitter.cpp.

859 {
860  if (!_active) {
861  _deactivate_when_all_files_sent = false;
862  _active = true;
863  start_fdt_repeat_timer();
864  send_next_packet();
865  }
866 }

◆ deactivate()

auto LibFlute::Transmitter::deactivate ( bool  finish_file_transmissions = false)

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.

When finish_file_transmissions is true the Transmitter will remain active until the queued transmissions have completed and will then become inactive. This allows applications to request deactivation without waiting for completion callbacks and checking number_of_files().

Parameters
finish_file_transmissionsIf true, defer deactivation until all queued transmissions complete. If false (default), halt transmission immediately.

Definition at line 868 of file Transmitter.cpp.

869 {
870  if (_active) {
871  if (finish_file_transmissions) {
872  std::lock_guard<std::mutex> guard(_files_mutex);
873  if (!_files.empty()) {
874  _deactivate_when_all_files_sent = true;
875  return;
876  }
877 
878  _complete_deactivation();
879  return;
880  }
881 
882  _complete_deactivation();
883  }
884 }

◆ 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 616 of file Transmitter.cpp.

617 {
618  IpSec::enable_esp(spi, _mcast_address, IpSec::Direction::Out, key);
619 }
void enable_esp(uint32_t spi, const std::string &dest_address, Direction direction, const std::string &key)
Definition: IpSec.cpp:122

◆ 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 513 of file Transmitter.h.

513 { return _endpoint; };

◆ endpoint() [2/4]

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

Definition at line 592 of file Transmitter.cpp.

593 {
594  _endpoint = std::move(destination);
595  return *this;
596 }

◆ 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 586 of file Transmitter.cpp.

587 {
588  _endpoint = destination;
589  return *this;
590 }

◆ 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 581 of file Transmitter.cpp.

582 {
583  return endpoint(boost::asio::ip::udp::endpoint(boost::asio::ip::make_address(address), port));
584 }
const boost::asio::ip::udp::endpoint & endpoint() const
Get UDP Address for FLUTE session.
Definition: Transmitter.h:513

◆ 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 659 of file Transmitter.h.

659 { 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 493 of file Transmitter.h.

493 { 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 503 of file Transmitter.h.

503 { _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 628 of file Transmitter.h.

628 { _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 627 of file Transmitter.cpp.

628 {
629  return std::chrono::duration_cast<std::chrono::seconds>(
630  std::chrono::system_clock::now().time_since_epoch()).count() +
631  2'208'988'800; /* add the difference in seconds between the Unix epoch (1 January 1970, 00:00:00 UTC)
632  and the NTP epoch (1 January 1900, 00:00:00 UTC) */
633 }

◆ 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 659 of file Transmitter.cpp.

665 {
666  auto toi = _toi;
667  _toi++;
668  if (_toi == 0) _toi = 1; // clamp to >= 1 in case it wraps
669 
670  auto file = std::make_shared<File>(
671  toi,
672  _fec_oti,
673  content_location,
674  content_type,
675  expires,
676  data,
677  length);
678 
679  _fdt->add(file->meta());
680  send_fdt();
681  {
682  std::lock_guard<std::mutex> guard(_files_mutex);
683  _files.insert({toi, file});
684  }
685  return toi;
686 }

◆ 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 550 of file Transmitter.h.

550 { 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 598 of file Transmitter.cpp.

599 {
600  _source_address = source_address;
601  if (_source_address && !_tunnel_endpoint) {
602  _socket.bind(boost::asio::ip::udp::endpoint(_source_address.value(),0));
603  }
604  return *this;
605 }

◆ source_address() [3/3]

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

Definition at line 607 of file Transmitter.cpp.

608 {
609  _source_address = std::move(source_address);
610  if (_source_address && !_tunnel_endpoint) {
611  _socket.bind(boost::asio::ip::udp::endpoint(_source_address.value(),0));
612  }
613  return *this;
614 }

◆ 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 435 of file Transmitter.h.

435 { 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 541 of file Transmitter.cpp.

542 {
543  return udp_tunnel_address(std::optional<boost::asio::ip::udp::endpoint>(std::move(new_tunnel_endpoint)));
544 }
const std::optional< boost::asio::ip::udp::endpoint > & udp_tunnel_address() const
Get UDP Tunnel Address.
Definition: Transmitter.h:435

◆ 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 536 of file Transmitter.cpp.

537 {
538  return udp_tunnel_address(std::optional<boost::asio::ip::udp::endpoint>(new_tunnel_endpoint));
539 }

◆ 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 576 of file Transmitter.cpp.

577 {
578  return udp_tunnel_address(std::optional<boost::asio::ip::udp::endpoint>(std::nullopt));
579 }

◆ 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 546 of file Transmitter.cpp.

547 {
548  return udp_tunnel_address(std::move(std::optional<boost::asio::ip::udp::endpoint>(new_tunnel_endpoint)));
549 }

◆ 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 551 of file Transmitter.cpp.

552 {
553  if (!!_tunnel_endpoint == !!new_tunnel_endpoint) {
554  /* change existing tunnel */
555  if (_tunnel_endpoint) _tunnel_endpoint = new_tunnel_endpoint;
556  } else if (_tunnel_endpoint) {
557  /* removing tunnel */
558  _max_payload += 20 + // IPv4 header
559  8; // UDP header
560  _tunnel_endpoint = std::nullopt;
561  } else {
562  /* new tunnel */
563  _tunnel_endpoint = std::move(new_tunnel_endpoint);
564  _max_payload -= 20 + // IPv4 header
565  8; // UDP header
566  }
567 
568  if (_tunnel_endpoint) {
569  boost::asio::ip::udp::socket local_socket(_io_context, _tunnel_endpoint.value().protocol());
570  local_socket.connect(_tunnel_endpoint.value());
571  _tunnel_local_address = local_socket.local_endpoint().address();
572  }
573  return *this;
574 }

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