comparison src/rtcp_rx.c @ 29:3e01a71b7c7c

implement RTCP Rx
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 08 Jul 2024 02:55:32 +0000
parents src/rtp_rx.c@9e477a4b485a
children
comparison
equal deleted inserted replaced
28:defe58aa537c 29:3e01a71b7c7c
1 /*
2 * Here we implement RTCP Rx path via osmo_io callback.
3 */
4
5 #include <stdint.h>
6 #include <stdbool.h>
7 #include <arpa/inet.h> /* for network byte order functions */
8
9 #include <osmocom/core/msgb.h>
10 #include <osmocom/core/osmo_io.h>
11 #include <osmocom/core/socket.h>
12 #include <osmocom/core/timer.h>
13
14 #include <themwi/rtp/endp.h>
15 #include <themwi/rtp/rtcp_defs.h>
16 #include "endp_internal.h"
17
18 static void parse_rtcp(struct twrtp_endp *endp, struct msgb *msg)
19 {
20 struct twrtp_endp_rtcp_rx *rxs = &endp->rtcp_rx;
21 struct rtcp_sr_rr_hdr *base_hdr;
22 struct rtcp_sr_block *sr;
23 struct rtcp_rr_block *rr;
24 unsigned rc, i;
25
26 if (msg->len < sizeof(struct rtcp_sr_rr_hdr)) {
27 invalid: endp->stats.rx_rtcp_invalid++;
28 return;
29 }
30 base_hdr = (struct rtcp_sr_rr_hdr *)
31 msgb_pull(msg, sizeof(struct rtcp_sr_rr_hdr));
32 if ((base_hdr->v_p_rc & 0xC0) != 0x80)
33 goto invalid;
34 switch (base_hdr->pt) {
35 case RTCP_PT_SR:
36 if (msg->len < sizeof(struct rtcp_sr_block))
37 goto invalid;
38 sr = (struct rtcp_sr_block *)
39 msgb_pull(msg, sizeof(struct rtcp_sr_block));
40 rxs->got_sr = true;
41 osmo_clock_gettime(CLOCK_MONOTONIC, &rxs->sr_rx_time);
42 rxs->sr_ssrc = ntohl(base_hdr->ssrc);
43 rxs->sr_ntp_sec = ntohl(sr->ntp_sec);
44 rxs->sr_ntp_fract = ntohl(sr->ntp_fract) >> 16;
45 break;
46 case RTCP_PT_RR:
47 break;
48 default:
49 goto invalid;
50 }
51 rc = base_hdr->v_p_rc & 0x1F;
52 if (msg->len < sizeof(struct rtcp_rr_block) * rc)
53 goto invalid;
54 for (i = 0; i < rc; i++) {
55 rr = (struct rtcp_rr_block *)
56 msgb_pull(msg, sizeof(struct rtcp_rr_block));
57 if (ntohl(rr->ssrc) != endp->tx.ssrc) {
58 endp->stats.rx_rtcp_wrong_ssrc++;
59 continue;
60 }
61 rxs->got_rr = true;
62 rxs->rr_lost_word = ntohl(rr->lost_word);
63 rxs->rr_jitter = ntohl(rr->jitter);
64 }
65 }
66
67 static void rtcp_rx_cb(struct osmo_io_fd *iofd, int res, struct msgb *msg,
68 const struct osmo_sockaddr *saddr)
69 {
70 struct twrtp_endp *endp = osmo_iofd_get_data(iofd);
71
72 if (!msg)
73 return;
74 if (!endp->remote_set) {
75 msgb_free(msg);
76 return;
77 }
78 if (osmo_sockaddr_cmp(saddr, &endp->rtcp_remote)) {
79 endp->stats.rx_rtcp_badsrc++;
80 msgb_free(msg);
81 return;
82 }
83 endp->stats.rx_rtcp_pkt++;
84 parse_rtcp(endp, msg);
85 msgb_free(msg);
86 }
87
88 const struct osmo_io_ops _twrtp_endp_iops_rtcp = {
89 .recvfrom_cb = rtcp_rx_cb,
90 };