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