FreeCalypso > hg > sipout-test-utils
comparison test-v22/rtp_rx.c @ 10:3c5734b88c20
sipout-test-v22 put together
| author | Mychaela Falconia <falcon@freecalypso.org> |
|---|---|
| date | Thu, 07 Mar 2024 02:33:49 -0800 |
| parents | test-fsk/rtp_rx.c@eaf0e8f81a22 |
| children |
comparison
equal
deleted
inserted
replaced
| 9:ff535725e01f | 10:3c5734b88c20 |
|---|---|
| 1 /* | |
| 2 * In this module we implement our RTP handling: obtaining a PSTN-side | |
| 3 * RTP endpoint from themwi-rtp-mgr, then handling read select on RTP | |
| 4 * and RTCP UDP sockets. | |
| 5 */ | |
| 6 | |
| 7 #include <sys/types.h> | |
| 8 #include <sys/socket.h> | |
| 9 #include <netinet/in.h> | |
| 10 #include <stdio.h> | |
| 11 #include <stdint.h> | |
| 12 #include <stdlib.h> | |
| 13 #include <string.h> | |
| 14 #include <strings.h> | |
| 15 #include "../include/tmgw_const.h" | |
| 16 #include "../include/rtp_defs.h" | |
| 17 #include "../include/pstn_defs.h" | |
| 18 #include "../librtpalloc/rtp_alloc_simple.h" | |
| 19 | |
| 20 extern const uint16_t pcmu_decode_table[256]; | |
| 21 extern const uint16_t pcma_decode_table[256]; | |
| 22 | |
| 23 extern int rtp_out_enable; /* misusing the flag :-( */ | |
| 24 | |
| 25 struct sockaddr_in rtp_local_addr; | |
| 26 int rtp_udp_fd, rtcp_udp_fd; | |
| 27 | |
| 28 static int rtp_start_flag, rtp_bad_flag, rtp_ssrc_chg_flag; | |
| 29 static int rtp_seq_brk_flag, rtp_seq_zero_flag, rtp_seq_neg_flag; | |
| 30 static int rtp_ts_brk_flag; | |
| 31 static uint32_t rtp_ssrc; | |
| 32 static uint32_t rtp_last_ts; | |
| 33 static uint16_t rtp_last_seq; | |
| 34 static int got_some_rtcp; | |
| 35 | |
| 36 void | |
| 37 obtain_rtp_endp() | |
| 38 { | |
| 39 int rc; | |
| 40 struct rtp_alloc_simple res; | |
| 41 | |
| 42 rc = rtp_alloc_simple(TMGW_EP_TYPE_PSTN_ONLY, &res); | |
| 43 if (rc < 0) | |
| 44 exit(1); /* error msg already printed */ | |
| 45 bcopy(&res.pstn_addr, &rtp_local_addr, sizeof(struct sockaddr_in)); | |
| 46 rtp_udp_fd = res.pstn_rtp_fd; | |
| 47 rtcp_udp_fd = res.pstn_rtcp_fd; | |
| 48 } | |
| 49 | |
| 50 void | |
| 51 rtp_rx_select() | |
| 52 { | |
| 53 struct rtp_packet pkt; | |
| 54 struct sockaddr_in sin_from; | |
| 55 socklen_t addrlen; | |
| 56 int16_t seq_delta; | |
| 57 int32_t ts_delta; | |
| 58 const uint16_t *pcm_dec_table; | |
| 59 int16_t pcm_samples[FRAME_20MS]; | |
| 60 unsigned n; | |
| 61 int rc; | |
| 62 | |
| 63 addrlen = sizeof(struct sockaddr_in); | |
| 64 rc = recvfrom(rtp_udp_fd, &pkt, sizeof pkt, 0, | |
| 65 (struct sockaddr *) &sin_from, &addrlen); | |
| 66 if (rc < 0) | |
| 67 return; | |
| 68 if (rc != RTP_PACKET_SIZE_PSTN) { | |
| 69 bad_rtp_pkt: if (!rtp_bad_flag) { | |
| 70 printf("Got a bad RTP packet\n"); | |
| 71 rtp_bad_flag = 1; | |
| 72 } | |
| 73 return; | |
| 74 } | |
| 75 if (pkt.v_p_x_cc != 0x80) | |
| 76 goto bad_rtp_pkt; | |
| 77 switch (pkt.m_pt & 0x7F) { | |
| 78 case PSTN_CODEC_PCMU: | |
| 79 pcm_dec_table = pcmu_decode_table; | |
| 80 break; | |
| 81 case PSTN_CODEC_PCMA: | |
| 82 pcm_dec_table = pcma_decode_table; | |
| 83 break; | |
| 84 default: | |
| 85 goto bad_rtp_pkt; | |
| 86 } | |
| 87 if (rtp_start_flag && pkt.ssrc != rtp_ssrc) { | |
| 88 if (!rtp_ssrc_chg_flag) { | |
| 89 printf("Rx RTP stream changed SSRC\n"); | |
| 90 rtp_ssrc_chg_flag = 1; | |
| 91 } | |
| 92 } else if (rtp_start_flag) { | |
| 93 seq_delta = ntohs(pkt.seq) - rtp_last_seq; | |
| 94 ts_delta = ntohl(pkt.tstamp) - rtp_last_ts; | |
| 95 if (seq_delta == 0) { | |
| 96 if (!rtp_seq_zero_flag) { | |
| 97 printf("Rx RTP seq zero increment\n"); | |
| 98 rtp_seq_zero_flag = 1; | |
| 99 } | |
| 100 return; | |
| 101 } | |
| 102 if (seq_delta < 0) { | |
| 103 if (!rtp_seq_neg_flag) { | |
| 104 printf("Rx RTP seq negative increment\n"); | |
| 105 rtp_seq_neg_flag = 1; | |
| 106 } | |
| 107 return; | |
| 108 } | |
| 109 if (seq_delta != 1) { | |
| 110 if (!rtp_seq_brk_flag) { | |
| 111 printf("Rx RTP stream seq break\n"); | |
| 112 rtp_seq_brk_flag = 1; | |
| 113 } | |
| 114 } else if (ts_delta != 160) { | |
| 115 if (!rtp_ts_brk_flag) { | |
| 116 printf("Rx RTP stream tstamp break\n"); | |
| 117 rtp_ts_brk_flag = 1; | |
| 118 } | |
| 119 } | |
| 120 } | |
| 121 rtp_ssrc = pkt.ssrc; | |
| 122 rtp_last_ts = ntohl(pkt.tstamp); | |
| 123 rtp_last_seq = ntohs(pkt.seq); | |
| 124 if (!rtp_start_flag) { | |
| 125 printf("Rx RTP stream begins with seq=%u ts=%u\n", | |
| 126 rtp_last_seq, rtp_last_ts); | |
| 127 rtp_start_flag = 1; | |
| 128 } | |
| 129 /* ignore early RTP during ringing, before answer supervision */ | |
| 130 if (!rtp_out_enable) | |
| 131 return; | |
| 132 /* feed samples to modem Rx */ | |
| 133 for (n = 0; n < FRAME_20MS; n++) | |
| 134 pcm_samples[n] = pcm_dec_table[pkt.payload[n]]; | |
| 135 process_rx_frame(pcm_samples); | |
| 136 } | |
| 137 | |
| 138 void | |
| 139 rtcp_rx_select() | |
| 140 { | |
| 141 u_char buf[512]; | |
| 142 | |
| 143 recv(rtcp_udp_fd, buf, sizeof buf, 0); | |
| 144 if (!got_some_rtcp) { | |
| 145 printf("Got some RTCP\n"); | |
| 146 got_some_rtcp = 1; | |
| 147 } | |
| 148 } |
