diff options
Diffstat (limited to 'src/codec/gsm620.c')
-rw-r--r-- | src/codec/gsm620.c | 55 |
1 files changed, 37 insertions, 18 deletions
diff --git a/src/codec/gsm620.c b/src/codec/gsm620.c index 282781fd..ef1d3b9b 100644 --- a/src/codec/gsm620.c +++ b/src/codec/gsm620.c @@ -17,14 +17,11 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * */ #include <stdint.h> #include <stdbool.h> +#include <string.h> #include <osmocom/core/bitvec.h> #include <osmocom/core/utils.h> @@ -268,12 +265,6 @@ const uint16_t gsm620_voiced_bitorder[112] = { 81, /* Code 3:7 */ }; -static inline uint16_t mask(const uint8_t msb) -{ - const uint16_t m = (uint16_t)1 << (msb - 1); - return (m - 1) ^ m; -} - /*! Check whether RTP frame contains HR SID code word according to * TS 101 318 ยง5.2.2 * \param[in] rtp_payload Buffer with RTP payload @@ -282,16 +273,44 @@ static inline uint16_t mask(const uint8_t msb) */ bool osmo_hr_check_sid(const uint8_t *rtp_payload, size_t payload_len) { - uint8_t i, bits[] = { 1, 2, 8, 9, 5, 4, 9, 5, 4, 9, 5, 4, 9, 5 }; - struct bitvec bv; - bv.data = (uint8_t *) rtp_payload; - bv.data_len = payload_len; - bv.cur_bit = 33; + struct bitvec bv = { + .data = (uint8_t *)rtp_payload, + .data_len = payload_len, + }; - /* code word is all 1 at given bits, numbered from 1, MODE is always 3 */ - for (i = 0; i < ARRAY_SIZE(bits); i++) - if (bitvec_get_uint(&bv, bits[i]) != mask(bits[i])) + /* A SID frame is identified by a SID codeword consisting of 79 bits which are all 1, + * so we basically check if all bits in range r34..r112 (inclusive) are 1. */ + for (bv.cur_bit = 33; bv.cur_bit < bv.data_len * 8; bv.cur_bit++) + if (bitvec_get_bit_pos(&bv, bv.cur_bit) != ONE) return false; return true; } + +/*! Reset the SID field of a potentially corrupted, but still valid GSM-HR + * SID frame in TS 101 318 format to its pristine state (full SID codeword). + * \param[in] rtp_payload Buffer with RTP payload - must be writable! + * + * Per GSM 06.22 section 5.3, a freshly minted SID frame consists of 33 bits + * of comfort noise parameters and 79 bits of SID codeword (all 1s). Network + * elements that receive SID frames from call leg A uplink and need to + * retransmit them on leg B downlink should "rejuvenate" received SID frames + * prior to retransmission by resetting the SID field to its pristine state + * of all 1s; this function does the job. + * + * Important note: because of HR-specific quirks (lack of exact bit counting + * rules in GSM 06.41 spec compared to 06.31 & 06.81, plus the fact that such + * bit counting can only be done efficiently in the GSM 05.03 channel decoder + * prior to bit reordering based on voiced or unvoiced mode), a generic + * (usable from any network element) SID classification function similar to + * osmo_{fr,efr}_sid_classify() unfortunately cannot exist for HR. Therefore, + * the triggering condition for invoking this SID rejuvenation/reset function + * can only be an out-of-band SID indication, as in GSM 08.61 TRAU frames + * or RFC 5993 ToC octet. + */ +void osmo_hr_sid_reset(uint8_t *rtp_payload) +{ + /* set all 79 SID codeword bits to 1 */ + rtp_payload[4] |= 0x7F; + memset(rtp_payload + 5, 0xFF, 9); +} |