comparison mgw/gsm2pstn.c @ 205:0047c4c08d9e

mgw: accept the new TRAUlike RTP format in addition to standard, old BFI and zero-length payload formats
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 06 Apr 2023 19:50:09 -0800
parents e6c7ced3c031
children
comparison
equal deleted inserted replaced
204:de7c64c4d6fd 205:0047c4c08d9e
15 #include <syslog.h> 15 #include <syslog.h>
16 #include <unistd.h> 16 #include <unistd.h>
17 #include <gsm.h> /* libgsm dependency */ 17 #include <gsm.h> /* libgsm dependency */
18 #include <gsm_fr_preproc.h> 18 #include <gsm_fr_preproc.h>
19 #include <gsm_efr.h> 19 #include <gsm_efr.h>
20 #include "../include/codec_defs.h"
20 #include "../include/rtp_defs.h" 21 #include "../include/rtp_defs.h"
21 #include "../include/tmgw_ctrl.h" 22 #include "../include/tmgw_ctrl.h"
22 #include "../include/tmgw_const.h" 23 #include "../include/tmgw_const.h"
23 #include "struct.h" 24 #include "struct.h"
24 #include "select.h" 25 #include "select.h"
39 struct sockaddr_in sin_from; 40 struct sockaddr_in sin_from;
40 socklen_t addrlen; 41 socklen_t addrlen;
41 unsigned pktsize; 42 unsigned pktsize;
42 int16_t seq_delta; 43 int16_t seq_delta;
43 int32_t ts_delta; 44 int32_t ts_delta;
45 uint8_t codec_frame[GSM_FR_BYTES];
44 int16_t pcm_samples[SAMPLES_PER_FRAME]; 46 int16_t pcm_samples[SAMPLES_PER_FRAME];
45 int rc, bfi, taf, m_out; 47 int rc, bfi, bfi_nodata, taf, m_out;
46 48
47 addrlen = sizeof(struct sockaddr_in); 49 addrlen = sizeof(struct sockaddr_in);
48 rc = recvfrom(in_fd, &pkt, sizeof pkt, 0, 50 rc = recvfrom(in_fd, &pkt, sizeof pkt, 0,
49 (struct sockaddr *) &sin_from, &addrlen); 51 (struct sockaddr *) &sin_from, &addrlen);
50 if (rc < 0) 52 if (rc < 0)
68 } 70 }
69 if (pkt.v_p_x_cc != 0x80) 71 if (pkt.v_p_x_cc != 0x80)
70 goto bad_rtp_pkt; 72 goto bad_rtp_pkt;
71 if ((pkt.m_pt & 0x7F) != ep->gsm_payload_type) 73 if ((pkt.m_pt & 0x7F) != ep->gsm_payload_type)
72 goto bad_rtp_pkt; 74 goto bad_rtp_pkt;
73 if (pktsize == ep->gsm_rtp_pkt_size && 75 pktsize -= RTP_PACKET_HDR_SIZE;
74 (pkt.payload[0] & 0xF0) == ep->gsm_payload_magic) { 76 if (!pktsize) {
75 bfi = 0; 77 /* zero length payload */
78 bfi = bfi_nodata = 1;
76 taf = 0; 79 taf = 0;
77 } else if (pktsize == RTP_PACKET_SIZE_BFI && pkt.payload[0] == 0xBF) { 80 } else if (pktsize == ep->gsm_payload_len &&
78 bfi = 1; 81 (pkt.payload[0] & 0xF0) == ep->gsm_payload_magic) {
82 /* standard RFC 3551 or TS 101 318 payload */
83 bfi = bfi_nodata = 0;
84 taf = 0;
85 bcopy(pkt.payload, codec_frame, pktsize);
86 } else if (pktsize == 2 && pkt.payload[0] == 0xBF) {
87 /* old BFI marker */
88 bfi = bfi_nodata = 1;
79 taf = pkt.payload[1] & 1; 89 taf = pkt.payload[1] & 1;
80 } else if (pktsize == RTP_PACKET_HDR_SIZE) { 90 } else if ((pkt.payload[0] & 0xF0) == 0xE0) {
81 bfi = 1; 91 /* new TRAUlike RTP payload format */
82 taf = 0; 92 bfi_nodata = (pkt.payload[0] & 0x04) >> 2;
93 bfi = (pkt.payload[0] & 0x02) >> 1;
94 taf = pkt.payload[0] & 0x01;
95 if (bfi_nodata) {
96 if (!bfi)
97 goto bad_rtp_pkt;
98 if (pktsize != 1)
99 goto bad_rtp_pkt;
100 } else {
101 if (pktsize != ep->gsm_payload_len + 1)
102 goto bad_rtp_pkt;
103 if ((pkt.payload[1] & 0xF0) != ep->gsm_payload_magic)
104 goto bad_rtp_pkt;
105 bcopy(pkt.payload+1, codec_frame, ep->gsm_payload_len);
106 }
83 } else 107 } else
84 goto bad_rtp_pkt; 108 goto bad_rtp_pkt;
85 if (ep->g2p_state && pkt.ssrc != ep->g2p_ssrc) { 109 if (ep->g2p_state && pkt.ssrc != ep->g2p_ssrc) {
86 if (!(ep->g2p_err_flags & ERR_SSRC_CHANGE)) { 110 if (!(ep->g2p_err_flags & ERR_SSRC_CHANGE)) {
87 syslog(LOG_ERR, "GSM RTP stream changed SSRC"); 111 syslog(LOG_ERR, "GSM RTP stream changed SSRC");
125 } 149 }
126 switch (ep->gsm_payload_msg_type) { 150 switch (ep->gsm_payload_msg_type) {
127 case GSM_TCHF_FRAME: 151 case GSM_TCHF_FRAME:
128 if (bfi) 152 if (bfi)
129 gsmfr_preproc_bfi(ep->gsm_decoder_extra_state, taf, 153 gsmfr_preproc_bfi(ep->gsm_decoder_extra_state, taf,
130 pkt.payload); 154 codec_frame);
131 else 155 else
132 gsmfr_preproc_good_frame(ep->gsm_decoder_extra_state, 156 gsmfr_preproc_good_frame(ep->gsm_decoder_extra_state,
133 pkt.payload); 157 codec_frame);
134 gsm_decode(ep->gsm_decoder_state, pkt.payload, pcm_samples); 158 gsm_decode(ep->gsm_decoder_state, codec_frame, pcm_samples);
135 break; 159 break;
136 case GSM_TCHF_FRAME_EFR: 160 case GSM_TCHF_FRAME_EFR:
137 if (bfi) 161 if (bfi_nodata)
138 EFR_decode_bfi_nodata(ep->gsm_decoder_state, taf, 162 EFR_decode_bfi_nodata(ep->gsm_decoder_state, taf,
139 pcm_samples); 163 pcm_samples);
140 else 164 else
141 EFR_decode_frame(ep->gsm_decoder_state, pkt.payload, 165 EFR_decode_frame(ep->gsm_decoder_state, codec_frame,
142 0, 0, pcm_samples); 166 bfi, taf, pcm_samples);
143 break; 167 break;
144 } 168 }
145 if (ep->dtmf_sample_ptr) { 169 if (ep->dtmf_sample_ptr) {
146 bcopy(ep->dtmf_sample_ptr, pcm_samples, SAMPLES_PER_FRAME*2); 170 bcopy(ep->dtmf_sample_ptr, pcm_samples, SAMPLES_PER_FRAME*2);
147 ep->dtmf_sample_ptr += SAMPLES_PER_FRAME; 171 ep->dtmf_sample_ptr += SAMPLES_PER_FRAME;