annotate src/rtcp_tx.c @ 32:aa97e77e7de6

implement RTCP Tx
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 08 Jul 2024 07:17:38 +0000
parents
children fc77c3482084
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
32
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
1 /*
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
2 * Here we implement RTCP Tx functionality.
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
3 */
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
4
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
5 #include <stdint.h>
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
6 #include <stdbool.h>
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
7 #include <string.h>
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
8 #include <errno.h>
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
9 #include <arpa/inet.h> /* for network byte order functions */
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
10
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
11 #include <osmocom/core/msgb.h>
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
12 #include <osmocom/core/osmo_io.h>
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
13 #include <osmocom/core/timer.h>
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
14
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
15 #include <themwi/rtp/endp.h>
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
16 #include <themwi/rtp/rtcp_defs.h>
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
17 #include <themwi/rtp/twjit.h>
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
18 #include "endp_internal.h"
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
19
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
20 #define NTP_EPOCH_MJD 15020
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
21 #define UNIX_EPOCH_MJD 40587
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
22
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
23 #define NTP_UNIX_EPOCH_DIFF ((UNIX_EPOCH_MJD-NTP_EPOCH_MJD) * 86400UL)
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
24 #define TWO_TO_32_DOUBLE 4294967296.0
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
25
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
26 static void fill_rr_block(struct twrtp_endp *endp, struct rtcp_rr_block *rr)
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
27 {
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
28 struct twrtp_jibuf_inst *twjit = endp->twjit;
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
29 struct twrtp_jibuf_rr_info *rri = &twjit->rr_info;
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
30 struct twrtp_endp_rtcp_rx *rxs = &endp->rtcp_rx;
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
31 struct twrtp_endp_rtcp_tx *txs = &endp->rtcp_tx;
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
32 uint32_t delta_expect, delta_rcvd;
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
33 int32_t cumulative_lost, newly_lost;
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
34 uint32_t lost_fract, lost_word;
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
35 struct timespec now, time_delta;
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
36
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
37 cumulative_lost = (int32_t)(rri->expected_pkt - rri->rx_packets);
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
38 if (cumulative_lost > 0x7FFFFF)
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
39 cumulative_lost = 0x7FFFFF;
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
40 else if (cumulative_lost < -0x800000)
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
41 cumulative_lost = -0x800000;
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
42 delta_expect = rri->expected_pkt - txs->last_expected;
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
43 txs->last_expected = rri->expected_pkt;
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
44 delta_rcvd = rri->rx_packets - txs->last_received;
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
45 txs->last_received = rri->rx_packets;
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
46 newly_lost = (int32_t)(delta_expect - delta_rcvd);
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
47 if (delta_expect == 0 || newly_lost <= 0)
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
48 lost_fract = 0;
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
49 else
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
50 lost_fract = (newly_lost << 8) / delta_expect;
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
51 lost_word = (lost_fract << 8) | (cumulative_lost & 0xFFFFFF);
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
52
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
53 rr->ssrc = htonl(twjit->last_ssrc);
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
54 rr->lost_word = htonl(lost_word);
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
55 rr->max_seq_ext = htonl(rri->max_seq_ext);
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
56 rr->jitter = htonl(rri->jitter_accum >> 4);
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
57
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
58 if (rxs->got_sr && rxs->sr_ssrc == twjit->last_ssrc) {
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
59 osmo_clock_gettime(CLOCK_MONOTONIC, &now);
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
60 time_delta.tv_sec = now.tv_sec - rxs->sr_rx_time.tv_sec;
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
61 time_delta.tv_nsec = now.tv_nsec - rxs->sr_rx_time.tv_nsec;
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
62 if (time_delta.tv_nsec < 0) {
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
63 time_delta.tv_sec--;
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
64 time_delta.tv_nsec += 1000000000;
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
65 }
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
66 rr->lsr_sec = htons(rxs->sr_ntp_sec);
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
67 rr->lsr_fract = htons(rxs->sr_ntp_fract);
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
68 rr->dlsr_sec = htons(time_delta.tv_sec);
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
69 rr->dlsr_fract = htons(time_delta.tv_nsec / 1000000000.0f *
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
70 65536.0f);
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
71 } else {
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
72 rr->lsr_sec = 0;
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
73 rr->lsr_fract = 0;
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
74 rr->dlsr_sec = 0;
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
75 rr->dlsr_fract = 0;
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
76 }
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
77 }
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
78
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
79 int _twrtp_endp_send_rtcp(struct twrtp_endp *endp, bool send_sr,
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
80 const struct timespec *utc, uint32_t rtp_ts)
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
81 {
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
82 bool send_rr = endp->twjit->got_first_packet;
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
83 struct msgb *msg;
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
84 struct rtcp_sr_rr_hdr *hdr;
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
85 struct rtcp_sr_block *sr;
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
86 struct rtcp_rr_block *rr;
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
87 uint8_t *sdes_out;
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
88 int rc;
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
89
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
90 if (!endp->register_done || !endp->remote_set || !endp->sdes_buf)
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
91 return -EINVAL;
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
92 if (!send_sr && !send_rr)
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
93 return -ENODATA; /* nothing to send, neither SR nor RR */
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
94 msg = msgb_alloc_c(endp, sizeof(struct rtcp_sr_rr_hdr) +
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
95 sizeof(struct rtcp_sr_block) +
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
96 sizeof(struct rtcp_rr_block) + endp->sdes_len,
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
97 "ThemWi-RTCP-Tx");
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
98 if (!msg)
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
99 return -ENOMEM;
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
100
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
101 hdr = (struct rtcp_sr_rr_hdr *)
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
102 msgb_put(msg, sizeof(struct rtcp_sr_rr_hdr));
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
103 hdr->v_p_rc = send_rr ? 0x81 : 0x80;
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
104 if (send_sr) {
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
105 hdr->pt = RTCP_PT_SR;
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
106 hdr->len = htons(send_rr ? 12 : 6);
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
107 } else {
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
108 hdr->pt = RTCP_PT_RR;
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
109 hdr->len = htons(7);
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
110 }
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
111 hdr->ssrc = htonl(endp->tx.ssrc);
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
112 if (send_sr) {
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
113 sr = (struct rtcp_sr_block *)
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
114 msgb_put(msg, sizeof(struct rtcp_sr_block));
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
115 sr->ntp_sec = htonl(utc->tv_sec + NTP_UNIX_EPOCH_DIFF);
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
116 sr->ntp_fract = htonl(utc->tv_nsec / 1000000000.0 *
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
117 TWO_TO_32_DOUBLE);
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
118 sr->rtp_ts = htonl(rtp_ts);
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
119 sr->pkt_count = htonl(endp->stats.tx_rtp_pkt);
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
120 sr->octet_count = htonl(endp->stats.tx_rtp_bytes);
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
121 }
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
122 if (send_rr) {
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
123 rr = (struct rtcp_rr_block *)
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
124 msgb_put(msg, sizeof(struct rtcp_rr_block));
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
125 fill_rr_block(endp, rr);
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
126 }
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
127 sdes_out = msgb_put(msg, endp->sdes_len);
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
128 memcpy(sdes_out, endp->sdes_buf, endp->sdes_len);
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
129
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
130 rc = osmo_iofd_sendto_msgb(endp->iofd_rtcp, msg, 0, &endp->rtcp_remote);
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
131 if (rc < 0) {
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
132 msgb_free(msg);
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
133 return rc;
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
134 }
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
135 endp->stats.tx_rtcp_pkt++;
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
136 return 0;
aa97e77e7de6 implement RTCP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
137 }