This is merely a historical archive of years 2008-2021, before the migration to mailman3.
A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/OpenBSC@lists.osmocom.org/.
Max gerrit-no-reply at lists.osmocom.orgReview at https://gerrit.osmocom.org/160 Add functions to detect HR/FR SID frames Add functions which check if given FR or HR frame (packed in RTP) contains SID (SIlence Descriptor) and corresponding tests. Related: OS#22 Change-Id: I4051e3c0d4fb9ee93d7e9e0ef4abaf9f18e227ca --- M include/osmocom/codec/codec.h M src/codec/gsm610.c M src/codec/gsm620.c M tests/codec/codec_test.c M tests/codec/codec_test.ok 5 files changed, 314 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/60/160/1 diff --git a/include/osmocom/codec/codec.h b/include/osmocom/codec/codec.h index b7bcc78..23c5e20 100644 --- a/include/osmocom/codec/codec.h +++ b/include/osmocom/codec/codec.h @@ -1,6 +1,7 @@ #pragma once #include <stdint.h> +#include <stdbool.h> #include <osmocom/core/utils.h> @@ -41,6 +42,8 @@ AMR_GOOD = 1 }; +bool osmo_check_sid_fr(uint8_t *rtp_payload, size_t payload_len); +bool osmo_check_sid_hr(uint8_t *rtp_payload, size_t payload_len); int osmo_amr_rtp_enc(uint8_t *payload, uint8_t cmr, enum osmo_amr_type ft, enum osmo_amr_quality bfi); int osmo_amr_rtp_dec(const uint8_t *payload, int payload_len, uint8_t *cmr, diff --git a/src/codec/gsm610.c b/src/codec/gsm610.c index 35f6011..8699253 100644 --- a/src/codec/gsm610.c +++ b/src/codec/gsm610.c @@ -22,6 +22,9 @@ */ #include <stdint.h> +#include <stdbool.h> + +#include <osmocom/core/bitvec.h> /* GSM FR - subjective importance bit ordering */ /* This array encodes GSM 05.03 Table 2. @@ -292,3 +295,215 @@ 11, /* LARc1:0 */ 29, /* LARc5:0 */ }; + +/*! \brief Check whether RTP frame contains FR SID code word according to + * TS 101 318 §5.1.2 + * \param[in] rtp_payload Buffer with RTP payload + * \param[in] payload_len Length of payload + * \returns true if code word is found, false otherwise + */ +bool osmo_check_sid_fr(uint8_t *rtp_payload, size_t payload_len) +{ + struct bitvec bv; + + /* signature does not match Full Rate SID */ + if ((rtp_payload[0] >> 4) != 0xD) + return false; + + bv.data = rtp_payload; + bv.data_len = payload_len; + + /* code word is all 0 at given bits, numbered from 1 */ + if (bitvec_get_bit_pos(&bv, 59) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 60) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 62) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 63) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 65) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 66) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 68) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 69) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 71) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 72) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 74) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 75) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 77) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 78) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 80) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 81) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 83) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 84) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 86) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 87) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 89) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 90) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 92) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 93) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 95) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 96) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 115) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 116) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 118) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 119) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 121) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 122) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 124) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 125) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 127) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 128) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 130) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 131) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 133) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 134) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 136) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 137) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 139) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 140) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 142) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 143) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 145) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 146) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 148) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 149) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 151) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 152) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 171) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 172) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 174) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 175) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 177) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 178) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 180) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 181) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 183) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 184) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 186) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 187) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 189) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 190) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 192) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 193) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 195) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 196) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 198) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 199) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 201) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 202) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 204) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 205) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 207) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 208) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 227) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 228) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 230) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 231) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 233) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 234) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 236) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 237) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 239) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 242) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 245) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 248) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 251) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 254) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 257) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 260) != ZERO) + return false; + if (bitvec_get_bit_pos(&bv, 263) != ZERO) + return false; + + return true; +} diff --git a/src/codec/gsm620.c b/src/codec/gsm620.c index f4ac9ad..873913d 100644 --- a/src/codec/gsm620.c +++ b/src/codec/gsm620.c @@ -22,6 +22,9 @@ */ #include <stdint.h> +#include <stdbool.h> + +#include <osmocom/core/bitvec.h> /* GSM HR unvoiced (mode=0) frames - subjective importance bit ordering */ /* This array encode mapping between GSM 05.03 Table 3a (bits @@ -260,3 +263,62 @@ 82, /* Code 3:6 */ 81, /* Code 3:7 */ }; + +/*! \brief 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 + * \param[in] payload_len Length of payload + * \returns true if code word is found, false otherwise + */ +bool osmo_check_sid_hr(uint8_t *rtp_payload, size_t payload_len) +{ + struct bitvec bv; + bv.data = rtp_payload; + bv.data_len = payload_len; + + /* code word is all 1 at given bits, numbered from 1, MODE is always 3 */ + bv.cur_bit = 33; + if (bitvec_get_uint(&bv, 1) != 0x1) + return false; + + if (bitvec_get_uint(&bv, 2) != 0x3) + return false; + + if (bitvec_get_uint(&bv, 8) != 0xFF) + return false; + + if (bitvec_get_uint(&bv, 9) != 0x1FF) + return false; + + if (bitvec_get_uint(&bv, 5) != 0x1F) + return false; + + if (bitvec_get_uint(&bv, 4) != 0xF) + return false; + + if (bitvec_get_uint(&bv, 9) != 0x1FF) + return false; + + if (bitvec_get_uint(&bv, 5) != 0x1F) + return false; + + if (bitvec_get_uint(&bv, 4) != 0xF) + return false; + + if (bitvec_get_uint(&bv, 9) != 0x1FF) + return false; + + if (bitvec_get_uint(&bv, 5) != 0x1F) + return false; + + if (bitvec_get_uint(&bv, 4) != 0xF) + return false; + + if (bitvec_get_uint(&bv, 9) != 0x1FF) + return false; + + if (bitvec_get_uint(&bv, 5) != 0x1F) + return false; + + return true; +} diff --git a/tests/codec/codec_test.c b/tests/codec/codec_test.c index 4905dd3..1b278cb 100644 --- a/tests/codec/codec_test.c +++ b/tests/codec/codec_test.c @@ -20,6 +20,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <stdbool.h> #include <osmocom/core/utils.h> #include <osmocom/codec/codec.h> @@ -68,6 +69,26 @@ cmpr(_cmr, cmr), cmpr(_ft, ft), cmpr(_bfi, bfi), cmi, sti); } +uint8_t fr[] = {0xd8, 0xa9, 0xb5, 0x1d, 0xda, 0xa8, 0x82, 0xcc, 0xec, 0x52, + 0x29, 0x05, 0xa8, 0xc3, 0xe3, 0x0e, 0xb0, 0x89, 0x7a, 0xee, + 0x42, 0xca, 0xc4, 0x97, 0x22, 0xe6, 0x9e, 0xa8, 0xb8, 0xec, + 0x52, 0x26, 0xbd}; +uint8_t sid_fr[] = {0xd7, 0x27, 0x93, 0xe5, 0xe3, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + +uint8_t hr[] = {0x06, 0x46, 0x76, 0xb1, 0x8e, 0x48, 0x9a, 0x2f, 0x5e, 0x4c, + 0x22, 0x2b, 0x62, 0x25}; +uint8_t sid_hr[] = {0x03, 0x8e, 0xb6, 0xcb, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff}; + +static void test_sid_xr(uint8_t *t, size_t len, bool hr) +{ + printf("%s SID ? %s:: %d\n", hr ? "HR" : "FR", osmo_hexdump(t, len), + hr ? osmo_check_sid_hr(t, len) : osmo_check_sid_fr(t, len)); +} + int main(int argc, char **argv) { printf("AMR RTP payload decoder test:\n"); @@ -79,6 +100,13 @@ test_amr_rt(AMR_12_2, AMR_12_2, AMR_GOOD); test_amr_rt(AMR_7_40, AMR_7_40, AMR_BAD); test_amr_rt(AMR_7_40, AMR_7_40, AMR_GOOD); + printf("FR RTP payload SID test:\n"); + test_sid_xr(sid_fr, 33, false); + test_sid_xr(fr, 33, false); + + printf("HR RTP payload SID test:\n"); + test_sid_xr(sid_hr, 14, true); + test_sid_xr(hr, 14, true); return 0; } diff --git a/tests/codec/codec_test.ok b/tests/codec/codec_test.ok index 0f76fef..2af7cc7 100644 --- a/tests/codec/codec_test.ok +++ b/tests/codec/codec_test.ok @@ -7,3 +7,9 @@ [33/33] AMR 12,2 kbit/s (GSM-EFR), CMR: OK, FT: OK, BFI: OK, CMI: -1, STI: -1 [21/21] AMR 7,40 kbit/s (TDMA-EFR), CMR: OK, FT: OK, BFI: OK, CMI: -1, STI: -1 [21/21] AMR 7,40 kbit/s (TDMA-EFR), CMR: OK, FT: OK, BFI: OK, CMI: -1, STI: -1 +FR RTP payload SID test: +FR SID ? d7 27 93 e5 e3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 :: 1 +FR SID ? d8 a9 b5 1d da a8 82 cc ec 52 29 05 a8 c3 e3 0e b0 89 7a ee 42 ca c4 97 22 e6 9e a8 b8 ec 52 26 bd :: 0 +HR RTP payload SID test: +HR SID ? 03 8e b6 cb ff ff ff ff ff ff ff ff ff ff :: 1 +HR SID ? 06 46 76 b1 8e 48 9a 2f 5e 4c 22 2b 62 25 :: 0 -- To view, visit https://gerrit.osmocom.org/160 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I4051e3c0d4fb9ee93d7e9e0ef4abaf9f18e227ca Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Max <msuraev at sysmocom.de>