libosmo-netif: Themyscira Wireless RTP endpoint implementation

libosmo-netif 1.7.0.15-fe2d Osmocom network interface library

Data Structures | Typedefs | Functions
Themyscira Wireless RTP endpoint implementation

osmo_twrtp is a complete RTP endpoint. More...

## Data Structures
struct | osmo_twrtp_stats
| Stats collected during the lifetime of a twrtp instance. More...

## Typedefs
typedef bool(* | osmo_twrtp_raw_rx_cb) (struct osmo_twrtp *endp, void *user_data, struct msgb *msg)

## Functions
struct osmo_twrtp * | osmo_twrtp_create (void *ctx, uint16_t clock_khz, uint16_t quantum_ms, bool random_ts_seq, const struct osmo_twjit_config *twjit_config)
| \addgroup twrtp More...
void | osmo_twrtp_destroy (struct osmo_twrtp *endp)
| Destroy a twrtp endpoint. More...
int | osmo_twrtp_supply_fds (struct osmo_twrtp *endp, int rtp_fd, int rtcp_fd)
| Equip twrtp endpoint with RTP and RTCP sockets (supplied file descriptors) More...
int | osmo_twrtp_bind_local (struct osmo_twrtp *endp, const struct osmo_sockaddr *rtp_addr, bool bind_rtcp)
| Equip twrtp endpoint with locally bound RTP and RTCP sockets. More...
int | osmo_twrtp_set_remote (struct osmo_twrtp *endp, const struct osmo_sockaddr *rtp_addr)
| Set RTP remote address. More...
void | osmo_twrtp_twjit_rx_ctrl (struct osmo_twrtp *endp, bool rx_enable)
| Enable or disable Rx via twjit. More...
struct msgb * | osmo_twrtp_twjit_rx_poll (struct osmo_twrtp *endp)
| Fixed-timing output poll from the twrtp endpoint's twjit buffer. More...
void | osmo_twrtp_set_raw_rx_cb (struct osmo_twrtp *endp, osmo_twrtp_raw_rx_cb cb, void *user_data)
| Set callback function for unbuffered/non-delayed Rx path. More...
int | osmo_twrtp_tx_quantum (struct osmo_twrtp *endp, const uint8_t *payload, unsigned payload_len, uint8_t payload_type, bool marker, bool auto_marker, bool send_rtcp)
| Emit RTP packet carrying a locally sourced quantum of speech/data. More...
void | osmo_twrtp_tx_skip (struct osmo_twrtp *endp)
| Incur an intentional gap in the emitted RTP stream. More...
void | osmo_twrtp_tx_restart (struct osmo_twrtp *endp)
| Reset output stream cadence. More...
int | osmo_twrtp_tx_forward (struct osmo_twrtp *endp, struct msgb *msg)
| Forward RTP packet between endpoints. More...
int | osmo_twrtp_set_sdes (struct osmo_twrtp *endp, const char *cname, const char *name, const char *email, const char *phone, const char *loc, const char *tool, const char *note)
| Set SDES strings for RTCP SR and RR packet generation. More...
void | osmo_twrtp_set_auto_rtcp_interval (struct osmo_twrtp *endp, uint16_t interval)
| Configure automatic emission of periodic RTCP SR packets. More...
int | osmo_twrtp_send_rtcp_rr (struct osmo_twrtp *endp)
| Emit RTCP RR packet. More...
struct osmo_twjit * | osmo_twrtp_get_twjit (struct osmo_twrtp *endp)
| Get twjit from twrtp. More...
const struct osmo_twrtp_stats * | osmo_twrtp_get_stats (struct osmo_twrtp *endp)
| Retrieve lifetime stats from twrtp instance. More...
bool | osmo_twrtp_got_rtcp_rr (struct osmo_twrtp *endp)
| Have we received any RTCP RR? More...
uint32_t | osmo_twrtp_rr_lost_word (struct osmo_twrtp *endp)
| Info from received RTCP RR: lost packets word. More...
int32_t | osmo_twrtp_rr_lost_cumulative (struct osmo_twrtp *endp)
| Info from received RTCP RR: cumulative number of packets lost. More...
uint32_t | osmo_twrtp_rr_jitter_last (struct osmo_twrtp *endp)
| Info from received RTCP RR: interarrival jitter, most recent. More...
uint32_t | osmo_twrtp_rr_jitter_max (struct osmo_twrtp *endp)
| Info from received RTCP RR: interarrival jitter, highest received. More...
int | osmo_twrtp_get_rtp_fd (struct osmo_twrtp *endp)
| Retrieve file descriptor for RTP UDP socket. More...
int | osmo_twrtp_get_rtcp_fd (struct osmo_twrtp *endp)
| Retrieve file descriptor for RTCP UDP socket. More...
int | osmo_twrtp_set_dscp (struct osmo_twrtp *endp, uint8_t dscp)
| Set DSCP (Differentiated Services Code Point) for emitted RTP and RTCP packets. More...
int | osmo_twrtp_set_socket_prio (struct osmo_twrtp *endp, int prio)
| Set socket priority for emitted RTP and RTCP packets. More...

## Detailed Description

osmo_twrtp is a complete RTP endpoint.

It is primarily designed to be used together with twjit to build a bidirectional interface between an RTP stream and a fixed timing system such as GSM Um TCH or T1/E1 Abis, but it also has limited support for endpoints without twjit. A twrtp endpoint without twjit is either an output-only endpoint (playout of in-band tones and announcements etc), or one side of a pair of endpoints that forward RTP packets to each other without delay.

The basic workflow is:

1. Create a twrtp instance with osmo_twrtp_create(). The decision to use or not use twjit is fixed at this time; if twjit is to be used, struct osmo_twjit_config needs to be provided.
2. Create and bind a pair of local UDP sockets for RTP and RTCP, or supply osmo_twrtp with an already-obtained pair of file descriptors for the same. Most users will find the high-level API osmo_twrtp_bind_local() most suitable, but some applications may prefer to use the low-level API osmo_twrtp_supply_fds() instead.
3. Set the IP:port address of the remote RTP end with osmo_twrtp_set_remote().
4. Traffic can now be sent and received as detailed below.

Receiving RTP traffic, interworking to a fixed timing system:

1. Provide struct osmo_twjit_config to osmo_twrtp_create(), so the twrtp instance will be created with twjit included.
2. When you are ready to start receiving traffic, call osmo_twrtp_twjit_rx_ctrl() with rx_enable argument set to true.
3. Once you've made the above call, commit to calling osmo_twrtp_twjit_rx_poll() every 20 ms (or whatever your quantum duration is) as timed by your GSM Um TCH or TDM system, every tick without fail.
4. You can pause operation by calling osmo_twrtp_twjit_rx_ctrl() with rx_enable argument set to false, and then later restart by returning to step 2 above. When you pause, the Rx jitter buffer will be flushed, and when you restart Rx, twjit will restart from empty state.

Sending RTP traffic, coming from a fixed timing system:

1. Make the first call to osmo_twrtp_tx_quantum() whenever you are ready to send out the first quantum.
2. Once you've made that first call, commit to sending either another quantum or an intentional gap (osmo_twrtp_tx_skip()) every 20 ms without fail, as timed by your GSM Um TCH, T1/E1 TDM or other fixed timing system.
3. If you need to pause Tx output and restart later, or if some discontinuity occurs in your fixed timing system where you know that your interval between quantum sends is not the proper 20 ms or whatever your quantum duration is, call osmo_twrtp_tx_restart(), telling the library to reset the RTP timescale in its subsequent output.

No-delay forwarding operation from one twrtp endpoint to another:

1. On the receiving side, call osmo_twrtp_set_raw_rx_cb() to set up an unbuffered/non-delayed Rx callback function.
2. In that Rx callback function, forward the packet to the other endpoint with osmo_twrtp_tx_forward().
3. If you are building an MGW that mostly does forwarding as described here, but occasionally inserts its own in-band tones or announcements, you can switch in real time between just-described forwarding and "native" osmo_twrtp_tx_quantum() output. The receiving RTP end will see "handover" events as SSRC switches between the one emitted by twrtp and the one coming from the other remote party. Actual timing will also switch, as there is no realistic way your own 20 ms timing for announcement playout will exactly match the timing of the RTP stream switched from the other remote party.

RTCP handling is mostly internal to the library - as a user, you don't need to concern yourself with it. More precisely, incoming RTCP packets are always handled internally; if you wish to send out RTCP, you have to set SDES and decide if you wish to send out SR or RR packets. Automatic emission of an SR packet after every so many RTP packets, with an RR block included in that SR, is the most common and most useful mode. OTOH, if your RTP application does not use RTCP, you don't need to concern yourself with RTCP at all: don't configure or enable RTCP sending, and ignore the existence of the built-in RTCP receiver. Any received RTCP packets will still be parsed, but you can ignore the data that result from this parsing.

For a more detailed description, please consult the full twrtp guide document that can be found in doc/twrtp directory. This document is required reading for anyone seeking to properly understand twrtp, its domain of application and all of its capabilities, beyond the brief summary given above. Specific section references to this document will be made in subsequent comments.

## Function Documentation

## ◆ osmo_twrtp_bind_local()

int osmo_twrtp_bind_local | ( | struct osmo_twrtp * | endp,
|  | const struct osmo_sockaddr * | rtp_addr,
|  | bool | bind_rtcp
| ) |  |

Equip twrtp endpoint with locally bound RTP and RTCP sockets.

Parameters

  [in] | endp | Endpoint to operate on
  [in] | rtp_addr | IP:port address to be bound locally for RTP socket; the corresponding address for RTCP (port increment by 1) will be derived internally.
  [in] | bind_rtcp | Create and bind sockets for both RTP and RTCP if true, or for RTP only if false.

Returns
  0 if successful, negative on errors

This function creates a pair of UDP sockets of the right address family (IPv4 or IPv6) for RTP and RTCP, binds them locally and installs them in the twrtp endpoint. (Or just one UDP socket for RTP, if bind_rtcp is false.) Either the present API or the lower-level alternative osmo_twrtp_supply_fds() must be called after osmo_twrtp_create() in order for the endpoint to become functional, but neither function can be used again once this step is done.

References osmo_twrtp_supply_fds().

## ◆ osmo_twrtp_create()

struct osmo_twrtp * osmo_twrtp_create | ( | void * | ctx,
|  | uint16_t | clock_khz,
|  | uint16_t | quantum_ms,
|  | bool | random_ts_seq,
|  | const struct osmo_twjit_config * | twjit_config
| ) |  |

\addgroup twrtp

Create a twrtp endpoint

Parameters

  [in] | ctx | Parent talloc context under which struct osmo_twrtp should be allocated.
  [in] | clock_khz | RTP clock rate in kHz, i.e., number of RTP timestamp units per millisecond. The most common value is 8.
  [in] | quantum_ms | Duration of a single quantum (unit of speech or data carried in one RTP packet) in milliseconds. The most common value is 20.
  [in] | random_ts_seq | For RTP packets we generate and emit, randomize not only SSRC for this session, but also the starting timestamp and the starting sequence number. Pass true to satisfy the SHOULD directive in RFC 3550 and for feature parity with ortp, or false for ease of debugging.
  [in] | twjit_config | If this RTP endpoint is to be equipped with twjit, pass twjit config structure with tunable parameters here. If a sans-twjit RTP endpoint is to be created, pass NULL here.

Returns
  pointer to the newly created twrtp instance, or NULL on errors.

Every twrtp endpoint is always capable of sending and receiving RTP and RTCP packets on the IP network, but it may be either twjit-equipped or sans-twjit. The decision to have or not have a twjit instance as part of a newly created twrtp instance must be made at the time of creation with this function, by passing either a valid twjit config structure or NULL as twjit_config.

Parameters clock_khz and quantum_ms are passed through to twjit if a twjit instance is created inside the new twrtp instance, but they are mandatory even if no twjit instance is to be created. With or without twjit, these parameters are used for locally generated RTP packets, i.e., those emitted via osmo_twrtp_tx_quantum() as opposed to osmo_twrtp_tx_forward().

References osmo_twjit_create().

## ◆ osmo_twrtp_destroy()

void osmo_twrtp_destroy | ( | struct osmo_twrtp * | endp | ) |

Destroy a twrtp endpoint.

Parameters

  [in] | endp | Instance (endpoint) to be freed

References osmo_twjit_destroy().

## ◆ osmo_twrtp_get_rtcp_fd()

int osmo_twrtp_get_rtcp_fd | ( | struct osmo_twrtp * | endp | ) |

Retrieve file descriptor for RTCP UDP socket.

Parameters

  [in] | endp | Endpoint to query

Returns
  OS-level file descriptor of the UDP socket used for RTCP.

The file descriptor made accessible via this function is still owned by the parent twrtp instance - closing it, or otherwise manipulating it too heavily (e.g., doing kernel-level connect on it) will break the library.

## ◆ osmo_twrtp_get_rtp_fd()

int osmo_twrtp_get_rtp_fd | ( | struct osmo_twrtp * | endp | ) |

Retrieve file descriptor for RTP UDP socket.

Parameters

  [in] | endp | Endpoint to query

Returns
  OS-level file descriptor of the UDP socket used for RTP.

The file descriptor made accessible via this function is still owned by the parent twrtp instance - closing it, or otherwise manipulating it too heavily (e.g., doing kernel-level connect on it) will break the library.

## ◆ osmo_twrtp_get_stats()

const struct osmo_twrtp_stats * osmo_twrtp_get_stats | ( | struct osmo_twrtp * | endp | ) |

Retrieve lifetime stats from twrtp instance.

Parameters

  [in] | endp | Endpoint to query

Returns
  pointer to lifetime stats structure

Note that a twrtp endpoint equipped with twjit has two levels of stats: there are stats at twrtp level and at twjit level. The present function retrieves twrtp stats; to get twjit stats, call osmo_twrtp_get_twjit() followed by osmo_twjit_get_stats().

## ◆ osmo_twrtp_get_twjit()

struct osmo_twjit * osmo_twrtp_get_twjit | ( | struct osmo_twrtp * | endp | ) |

Get twjit from twrtp.

Parameters

  [in] | endp | Endpoint to query

Returns
  pointer to twjit instance owned by this twrtp endpoint, or NULL if this twrtp endpoint has no associated twjit.

The twjit instance made accessible via this function is still owned by the parent twrtp instance - calling osmo_twjit_destroy() on it would cause a crash the next time twrtp tries to use it! Safe twjit APIs are as follows, for dynamic reconfiguration and information retrieval:

osmo_twjit_set_config() osmo_twjit_get_stats() osmo_twjit_get_rr_info() osmo_twjit_rr_info_valid()

## ◆ osmo_twrtp_got_rtcp_rr()

bool osmo_twrtp_got_rtcp_rr | ( | struct osmo_twrtp * | endp | ) |

Have we received any RTCP RR?

Parameters

  [in] | endp | Endpoint to query

Returns
  true if at least one reception report block has been received whose SSRC matches that of our locally generated RTP output, false otherwise.

## ◆ osmo_twrtp_rr_jitter_last()

uint32_t osmo_twrtp_rr_jitter_last | ( | struct osmo_twrtp * | endp | ) |

Info from received RTCP RR: interarrival jitter, most recent.

Parameters

  [in] | endp | Endpoint to query

Returns
  "interarrival jitter" value from the most recently received RR block.

## ◆ osmo_twrtp_rr_jitter_max()

uint32_t osmo_twrtp_rr_jitter_max | ( | struct osmo_twrtp * | endp | ) |

Info from received RTCP RR: interarrival jitter, highest received.

Parameters

  [in] | endp | Endpoint to query

Returns
  "interarrival jitter" value from received RR blocks, the highest value that was received in this session.

## ◆ osmo_twrtp_rr_lost_cumulative()

int32_t osmo_twrtp_rr_lost_cumulative | ( | struct osmo_twrtp * | endp | ) |

Info from received RTCP RR: cumulative number of packets lost.

Parameters

  [in] | endp | Endpoint to query

Returns
  "cumulative number of packets lost" value from the most recently received RR block, extracted and converted to a proper signed type. This number can be negative because of the way it is defined in RFC 3550.

If no RTCP RR has been received, this function returns 0.

## ◆ osmo_twrtp_rr_lost_word()

uint32_t osmo_twrtp_rr_lost_word | ( | struct osmo_twrtp * | endp | ) |

Info from received RTCP RR: lost packets word.

Parameters

  [in] | endp | Endpoint to query

Returns
  lost packets word from the most recently received RR block.

This API returns the 32-bit word from received RTCP RR in its raw form, exactly as it appears in RFC 3550 section 6.4.1: fraction lost in the upper 8 bits, cumulative number of packets lost in the lower 24 bits.

If no RTCP RR has been received, this function returns 0.

## ◆ osmo_twrtp_send_rtcp_rr()

int osmo_twrtp_send_rtcp_rr | ( | struct osmo_twrtp * | endp | ) |

Emit RTCP RR packet.

Parameters

  [in] | endp | Endpoint to operate on

Returns
  0 if successful, negative on errors

This function is safe to call on any twrtp endpoint, but it will actually result in an RTCP RR packet being emitted only if (1) the twrtp endpoint is equipped with twjit and (2) some RTP data packets have been successfully received and header-decoded. If these conditions aren't met, no RTCP packet will be emitted and the function will return -ENODATA.

This API is rarely needed: in most RTCP-enabled RTP applications, it is more useful to enable automatic SR generation with osmo_twrtp_set_auto_rtcp_interval(), in which case the library will emit RTCP SR packets that also include the same reception report block as those standalone RR packets that are emitted by the present function. However, the present API is provided in case an application receives RTP traffic via twrtp+twjit, but does not emit any RTP traffic of its own - in this case only RTCP RR can be generated, not SR.

## ◆ osmo_twrtp_set_auto_rtcp_interval()

void osmo_twrtp_set_auto_rtcp_interval | ( | struct osmo_twrtp * | endp,
|  | uint16_t | interval
| ) |  |

Configure automatic emission of periodic RTCP SR packets.

Parameters

  [in] | endp | Endpoint to operate on
  [in] | interval | Automatically emit RTCP SR after this many RTP data packets, or 0 to turn off this mechanism.

## ◆ osmo_twrtp_set_dscp()

int osmo_twrtp_set_dscp | ( | struct osmo_twrtp * | endp,
|  | uint8_t | dscp
| ) |  |

Set DSCP (Differentiated Services Code Point) for emitted RTP and RTCP packets.

Parameters

  [in] | endp | Endpoint to operate on
  [in] | dscp | DSCP value

Returns
  0 if successful, negative on errors

This function exists for feature parity with osmo_ortp: when migrating from osmo_ortp to osmo_twrtp, use this function in the place of osmo_rtp_socket_set_dscp().

## ◆ osmo_twrtp_set_raw_rx_cb()

void osmo_twrtp_set_raw_rx_cb | ( | struct osmo_twrtp * | endp,
|  | osmo_twrtp_raw_rx_cb | cb,
|  | void * | user_data
| ) |  |

Set callback function for unbuffered/non-delayed Rx path.

Parameters

  [in] | endp | Endpoint to operate on
  [in] | cb | The callback function, or NULL to cancel this callback mechanism.
  [in] | user_data | Opaque user data for cb function

The callback function set with this API will be called from osmo_io Rx callback path whenever an RTP packet is received. If the callback function consumes (takes ownership of) the msgb passed to it, it must return true, otherwise it must return false. If the callback function returns true, osmo_io Rx processing ends there; if it returns false, twrtp's regular osmo_io Rx callback path passes the msgb to twjit if this endpoint is equipped with such and twjit Rx is enabled, or frees the msgb otherwise.

It is possible to use twjit and this unbuffered/non-delayed Rx path at the same time. Consider a speech transcoder that supports AMR codec on the RAN side: such TC will use twjit to feed the incoming RTP stream to the speech decoder function that runs on fixed timing, but the non-delayed Rx path can also be used to "peek" at received RTP packets as they come in and extract the CMR field - to be fed to the speech encoder element, which is separate from the speech decoder fed via twjit.

## ◆ osmo_twrtp_set_remote()

int osmo_twrtp_set_remote | ( | struct osmo_twrtp * | endp,
|  | const struct osmo_sockaddr * | rtp_addr
| ) |  |

Set RTP remote address.

Parameters

  [in] | endp | Endpoint to operate on
  [in] | rtp_addr | IP:port address to be set as the remote for RTP socket; the corresponding address for RTCP (port increment by 1) will be derived internally.

Returns
  0 if successful, negative on errors

This function needs to be called at some point in order for the endpoint to become functional, but unlike osmo_twrtp_bind_local(), it can be called again to change the remote address as needed.

## ◆ osmo_twrtp_set_sdes()

int osmo_twrtp_set_sdes | ( | struct osmo_twrtp * | endp,
|  | const char * | cname,
|  | const char * | name,
|  | const char * | email,
|  | const char * | phone,
|  | const char * | loc,
|  | const char * | tool,
|  | const char * | note
| ) |  |

Set SDES strings for RTCP SR and RR packet generation.

Parameters

  [in] | endp | Endpoint to operate on
  [in] | cname | Per RFC 3550 section 6.5.1
  [in] | name | Per RFC 3550 section 6.5.2
  [in] | email | Per RFC 3550 section 6.5.3
  [in] | phone | Per RFC 3550 section 6.5.4
  [in] | loc | Per RFC 3550 section 6.5.5
  [in] | tool | Per RFC 3550 section 6.5.6
  [in] | note | Per RFC 3550 section 6.5.7

Returns
  0 if successful, negative on errors

RFC 3550 section 6.1 stipulates that every RTCP SR or RR packet also needs to include an SDES block, containing at least a CNAME string. The present function sets the full complement of SDES strings: the mandatory CNAME string and 6 optional ones per RFC 3550. This function must be called successfully before any RTCP SR or RR packets will be emitted.

## ◆ osmo_twrtp_set_socket_prio()

int osmo_twrtp_set_socket_prio | ( | struct osmo_twrtp * | endp,
|  | int | prio
| ) |  |

Set socket priority for emitted RTP and RTCP packets.

Parameters

  [in] | endp | Endpoint to operate on
  [in] | prio | Socket priority

Returns
  0 if successful, negative on errors

This function exists for feature parity with osmo_ortp: when migrating from osmo_ortp to osmo_twrtp, use this function in the place of osmo_rtp_socket_set_priority().

## ◆ osmo_twrtp_supply_fds()

int osmo_twrtp_supply_fds | ( | struct osmo_twrtp * | endp,
|  | int | rtp_fd,
|  | int | rtcp_fd
| ) |  |

Equip twrtp endpoint with RTP and RTCP sockets (supplied file descriptors)

Parameters

  [in] | endp | Endpoint to operate on
  [in] | rtp_fd | OS file descriptor for UDP socket for RTP
  [in] | rtcp_fd | OS file descriptor for UDP socket for RTCP

Returns
  0 if successful, negative on errors

This function equips a newly created twrtp endpoint with file descriptors for RTP and RTCP sockets. Most applications will use the high-level API osmo_twrtp_bind_local() that creates and binds the right type of sockets, then calls the present function - however, some applications may call this function directly. In Themyscira Wireless CN environment, there is a separate daemon process that manages the pool of local UDP ports for RTP+RTCP pairs, and that daemon passes allocated sockets to its clients via UNIX domain socket file descriptor passing mechanism - hence twrtp layer must have a public API that takes in already-bound file descriptor pairs.

This function always "consumes" the two file descriptors that are passed to it. If the operation succeeds, each of these fds becomes wrapped in an osmo_io_fd subordinate to struct osmo_twrtp, and both will eventually be closed upon osmo_twrtp_destroy(). OTOH, if the present function fails, it closes both fds before returning its error indication. The latter behavior may seem wrong, but it is more convenient for all current users, and consistent with twrtp-native and twrtp-proto versions. If we get a user application that prefers the other alternative (keeping the fds intact on EBUSY or if osmo_iofd_setup() or osmo_iofd_register() operations fail), we can create another variant of this API with that alternative behavior.

It is also possible to pass -1 as rtcp_fd - in this case the twrtp endpoint will operate with only an RTP socket, and no ability to send or receive RTCP.

Referenced by osmo_twrtp_bind_local().

## ◆ osmo_twrtp_twjit_rx_ctrl()

void osmo_twrtp_twjit_rx_ctrl | ( | struct osmo_twrtp * | endp,
|  | bool | rx_enable
| ) |  |

Enable or disable Rx via twjit.

Parameters

  [in] | endp | Endpoint to operate on
  [in] | rx_enable | Self-explanatory Boolean flag

This API is valid only for twrtp endpoints that were equipped with twjit at the time of creation.

References osmo_twjit_reset().

## ◆ osmo_twrtp_twjit_rx_poll()

struct msgb * osmo_twrtp_twjit_rx_poll | ( | struct osmo_twrtp * | endp | ) |

Fixed-timing output poll from the twrtp endpoint's twjit buffer.

Parameters

  [in] | endp | Endpoint to poll

Returns
  pointer to msgb holding a previously received RTP packet that was successfully mapped to the present quantum in the fixed-timing output, or NULL if no such packet is available.

This API is valid only for twrtp endpoints that were equipped with twjit at the time of creation.

References osmo_twjit_output().

## ◆ osmo_twrtp_tx_forward()

int osmo_twrtp_tx_forward | ( | struct osmo_twrtp * | endp,
|  | struct msgb * | msg
| ) |  |

Forward RTP packet between endpoints.

Parameters

  [in] | endp | Endpoint on which the packet should be sent out
  [in] | msg | RTP packet received from another endpoint

Returns
  0 if successful, negative on errors

If an application needs to forward RTP packets from one endpoint to another without buffering delay, it should call the present function from the callback registered on the other endpoint with osmo_twrtp_set_raw_rx_cb().

This function always consumes the msgb passed to it - if the sending operation fails, the msgb is freed here.

## ◆ osmo_twrtp_tx_quantum()

int osmo_twrtp_tx_quantum | ( | struct osmo_twrtp * | endp,
|  | const uint8_t * | payload,
|  | unsigned | payload_len,
|  | uint8_t | payload_type,
|  | bool | marker,
|  | bool | auto_marker,
|  | bool | send_rtcp
| ) |  |

Emit RTP packet carrying a locally sourced quantum of speech/data.

Parameters

  [in] | endp | Endpoint to operate on
  [in] | payload | The payload to emit in RTP, can be NULL iff payload_len == 0.
  [in] | payload_len | The length of payload in bytes.
  [in] | payload_type | The payload type number to be emitted in the generated RTP packet.
  [in] | marker | Value of the M bit to be emitted.
  [in] | auto_marker | Automatically set the M bit if the packet we are emitting is our very first or follows osmo_twrtp_tx_restart().
  [in] | send_rtcp | Emit RTCP SR along with this RTP data packet.

Returns
  0 if successful, negative on errors.

The design of the library assumes that RTP payloads sent out via this API originate from a fixed timing system such as GSM Um TCH, T1/E1 TDM or a software application driven by a CLOCK_MONOTONIC timerfd, such that once the application calls the present function, subsequent calls to the same will follow every 20 ms (or whatever other quantum duration is set at the time of osmo_twrtp_create()) without fail.

The M bit will be set in the generated RTP packet if marker argument is true OR if auto_marker is true and the conditions for automatic marker setting are met.

RTCP SR packets are emitted by the endpoint only as a result of this function being called, and not along any other path. An RTCP SR will be emitted if send_rtcp argument is true OR if automatic RTCP SR generation was enabled with osmo_twrtp_set_auto_rtcp_interval() and it is time to emit RTCP SR per the count of emitted RTP data packets.

References osmo_twrtp_tx_skip().

## ◆ osmo_twrtp_tx_restart()

void osmo_twrtp_tx_restart | ( | struct osmo_twrtp * | endp | ) |

Reset output stream cadence.

Parameters

  [in] | endp | Endpoint to operate on

This function needs to be called if the application wishes to restart or resume output after it previously stopped calling osmo_twrtp_tx_quantum() or osmo_twrtp_tx_skip() every 20 ms, and it should also be called if the cadence of quantum-sized timestamp increments needs to be broken for some reason.

## ◆ osmo_twrtp_tx_skip()

void osmo_twrtp_tx_skip | ( | struct osmo_twrtp * | endp | ) |

Incur an intentional gap in the emitted RTP stream.

Parameters

  [in] | endp | Endpoint to operate on

Many RTP profiles call for behavior where a stream sender incurs an intentional gap in its output (does not emit the otherwise-expected RTP packet for a given timestamp in the expected cadence of timestamp quantum increments) if the corresponding quantum carries speech silence, or if the data source has errors. Such operation is non-native to twrtp and generally recommended against (it creates an adverse condition for twjit on the receiving end), but the library provides mechanism rather than policy, hence the ability to incur intentional gaps is supported. This function advances the output timestamp by one quantum, thereby creating the requested intentional gap.

Referenced by osmo_twrtp_tx_quantum().