libosmo-netif 1.6.0.16-c51c
Osmocom network interface library
|
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... | |
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:
Receiving RTP traffic, interworking to a fixed timing system:
Sending RTP traffic, coming from a fixed timing system:
No-delay forwarding operation from one twrtp endpoint to another:
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.
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.
[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. |
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().
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
[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. |
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().
void osmo_twrtp_destroy | ( | struct osmo_twrtp * | endp | ) |
Destroy a twrtp endpoint.
[in] | endp | Instance (endpoint) to be freed |
References osmo_twjit_destroy().
int osmo_twrtp_get_rtcp_fd | ( | struct osmo_twrtp * | endp | ) |
Retrieve file descriptor for RTCP UDP socket.
[in] | endp | Endpoint to query |
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.
int osmo_twrtp_get_rtp_fd | ( | struct osmo_twrtp * | endp | ) |
Retrieve file descriptor for RTP UDP socket.
[in] | endp | Endpoint to query |
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.
const struct osmo_twrtp_stats * osmo_twrtp_get_stats | ( | struct osmo_twrtp * | endp | ) |
Retrieve lifetime stats from twrtp instance.
[in] | endp | Endpoint to query |
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().
struct osmo_twjit * osmo_twrtp_get_twjit | ( | struct osmo_twrtp * | endp | ) |
Get twjit from twrtp.
[in] | endp | Endpoint to query |
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()
bool osmo_twrtp_got_rtcp_rr | ( | struct osmo_twrtp * | endp | ) |
Have we received any RTCP RR?
[in] | endp | Endpoint to query |
uint32_t osmo_twrtp_rr_jitter_last | ( | struct osmo_twrtp * | endp | ) |
Info from received RTCP RR: interarrival jitter, most recent.
[in] | endp | Endpoint to query |
uint32_t osmo_twrtp_rr_jitter_max | ( | struct osmo_twrtp * | endp | ) |
Info from received RTCP RR: interarrival jitter, highest received.
[in] | endp | Endpoint to query |
int32_t osmo_twrtp_rr_lost_cumulative | ( | struct osmo_twrtp * | endp | ) |
Info from received RTCP RR: cumulative number of packets lost.
[in] | endp | Endpoint to query |
If no RTCP RR has been received, this function returns 0.
uint32_t osmo_twrtp_rr_lost_word | ( | struct osmo_twrtp * | endp | ) |
Info from received RTCP RR: lost packets word.
[in] | endp | Endpoint to query |
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.
int osmo_twrtp_send_rtcp_rr | ( | struct osmo_twrtp * | endp | ) |
Emit RTCP RR packet.
[in] | endp | Endpoint to operate on |
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.
void osmo_twrtp_set_auto_rtcp_interval | ( | struct osmo_twrtp * | endp, |
uint16_t | interval | ||
) |
Configure automatic emission of periodic RTCP SR packets.
[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. |
int osmo_twrtp_set_dscp | ( | struct osmo_twrtp * | endp, |
uint8_t | dscp | ||
) |
Set DSCP (Differentiated Services Code Point) for emitted RTP and RTCP packets.
[in] | endp | Endpoint to operate on |
[in] | dscp | DSCP value |
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().
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.
[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.
int osmo_twrtp_set_remote | ( | struct osmo_twrtp * | endp, |
const struct osmo_sockaddr * | rtp_addr | ||
) |
Set RTP remote address.
[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. |
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.
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.
[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] | 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 |
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.
int osmo_twrtp_set_socket_prio | ( | struct osmo_twrtp * | endp, |
int | prio | ||
) |
Set socket priority for emitted RTP and RTCP packets.
[in] | endp | Endpoint to operate on |
[in] | prio | Socket priority |
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().
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)
[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 |
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().
void osmo_twrtp_twjit_rx_ctrl | ( | struct osmo_twrtp * | endp, |
bool | rx_enable | ||
) |
Enable or disable Rx via twjit.
[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().
struct msgb * osmo_twrtp_twjit_rx_poll | ( | struct osmo_twrtp * | endp | ) |
Fixed-timing output poll from the twrtp endpoint's twjit buffer.
[in] | endp | Endpoint to poll |
This API is valid only for twrtp endpoints that were equipped with twjit at the time of creation.
References osmo_twjit_output().
int osmo_twrtp_tx_forward | ( | struct osmo_twrtp * | endp, |
struct msgb * | msg | ||
) |
Forward RTP packet between endpoints.
[in] | endp | Endpoint on which the packet should be sent out |
[in] | msg | RTP packet received from another endpoint |
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.
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.
[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. |
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().
void osmo_twrtp_tx_restart | ( | struct osmo_twrtp * | endp | ) |
Reset output stream cadence.
[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.
void osmo_twrtp_tx_skip | ( | struct osmo_twrtp * | endp | ) |
Incur an intentional gap in the emitted RTP stream.
[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().