FreeCalypso > hg > themwi-system-sw
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; |