From patchwork Wed Jun 1 09:47:11 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: gerrit-no-reply@lists.osmocom.org X-Patchwork-Id: 628556 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.osmocom.org (lists.osmocom.org [IPv6:2a01:4f8:191:444b::2:7]) by ozlabs.org (Postfix) with ESMTP id 3rKQW828kcz9t62 for ; Wed, 1 Jun 2016 19:47:16 +1000 (AEST) Received: from lists.osmocom.org (lists.osmocom.org [144.76.43.76]) by lists.osmocom.org (Postfix) with ESMTP id 2CC4122274; Wed, 1 Jun 2016 09:47:13 +0000 (UTC) X-Original-To: openbsc@lists.osmocom.org Delivered-To: openbsc@lists.osmocom.org Received: from 127.0.1.12 (unknown [127.0.1.12]) by lists.osmocom.org (Postfix) with ESMTPA id 3077C2225C; Wed, 1 Jun 2016 09:47:11 +0000 (UTC) Date: Wed, 1 Jun 2016 09:47:11 +0000 From: Max To: Harald Welte X-Gerrit-MessageType: newpatchset Subject: [PATCH] libosmocore[master]: Add functions to detect HR/FR SID frames X-Gerrit-Change-Id: I4051e3c0d4fb9ee93d7e9e0ef4abaf9f18e227ca X-Gerrit-ChangeURL: X-Gerrit-Commit: 636e94e047f3e7bfaddb845c29eb80a075aa5349 In-Reply-To: References: MIME-Version: 1.0 Content-Disposition: inline User-Agent: Gerrit/2.12.2-31-gb331dbd-dirty X-BeenThere: openbsc@lists.osmocom.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: "Development of OpenBSC, OsmoBSC, OsmoNITB, OsmoCSCN" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: msuraev@sysmocom.de Errors-To: openbsc-bounces@lists.osmocom.org Sender: "OpenBSC" Message-Id: <20160601094713.2CC4122274@lists.osmocom.org> Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/160 to look at the new patch set (#2). 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, 108 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/60/160/2 diff --git a/include/osmocom/codec/codec.h b/include/osmocom/codec/codec.h index b7bcc78..f7a8ad9 100644 --- a/include/osmocom/codec/codec.h +++ b/include/osmocom/codec/codec.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include @@ -41,6 +42,8 @@ AMR_GOOD = 1 }; +bool osmo_fr_check_sid(uint8_t *rtp_payload, size_t payload_len); +bool osmo_hr_check_sid(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..47faea2 100644 --- a/src/codec/gsm610.c +++ b/src/codec/gsm610.c @@ -22,6 +22,10 @@ */ #include +#include + +#include +#include /* GSM FR - subjective importance bit ordering */ /* This array encodes GSM 05.03 Table 2. @@ -292,3 +296,38 @@ 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_fr_check_sid(uint8_t *rtp_payload, size_t payload_len) +{ + struct bitvec bv; + uint16_t i, z_bits[] = { 59, 60, 62, 63, 65, 66, 68, 69, 71, 72, 74, 75, + 77, 78, 80, 81, 83, 84, 86, 87, 89, 90, 92, 93, + 95, 96, 115, 116, 118, 119, 121, 122, 124, 125, + 127, 128, 130, 131, 133, 134, 136, 137, 139, + 140, 142, 143, 145, 146, 148, 149, 151, 152, + 171, 172, 174, 175, 177, 178, 180, 181, 183, + 184, 186, 187, 189, 190, 192, 193, 195, 196, + 198, 199, 201, 202, 204, 205, 207, 208, 227, + 228, 230, 231, 233, 234, 236, 237, 239, 242, + 245, 248, 251, 254, 257, 260, 263 }; + + /* 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 */ + for (i = 0; i < ARRAY_SIZE(z_bits); i++) + if (bitvec_get_bit_pos(&bv, z_bits[i]) != ZERO) + return false; + + return true; +} diff --git a/src/codec/gsm620.c b/src/codec/gsm620.c index f4ac9ad..6f1a95b 100644 --- a/src/codec/gsm620.c +++ b/src/codec/gsm620.c @@ -22,6 +22,10 @@ */ #include +#include + +#include +#include /* GSM HR unvoiced (mode=0) frames - subjective importance bit ordering */ /* This array encode mapping between GSM 05.03 Table 3a (bits @@ -260,3 +264,31 @@ 82, /* Code 3:6 */ 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; +} + +/*! \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_hr_check_sid(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 = rtp_payload; + bv.data_len = payload_len; + bv.cur_bit = 33; + + /* 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])) + return false; + + return true; +} diff --git a/tests/codec/codec_test.c b/tests/codec/codec_test.c index 4905dd3..5b934b1 100644 --- a/tests/codec/codec_test.c +++ b/tests/codec/codec_test.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -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_hr_check_sid(t, len) : osmo_fr_check_sid(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