From a65cf63619627b3965c8369cfb571b344447a88f Mon Sep 17 00:00:00 2001 From: Philipp Maier Date: Thu, 26 Aug 2021 13:55:27 +0200 Subject: [PATCH] sched_lchan_tch_x: use functions to determine AMR tranmssion phase The AMR transmission phase directly depends on the frame number. The transmission phase is used to tell if a received AMR frame contains a CMI (frame type that is currently used) or CMR (frame type that the receiver should use) codec identifier. The formulas in the present implementation seem to be correct but they do not reflect the numbers in the spec very well, nor do they have unit-tests. Lets replace them with more readble functions and test those functions with unit-tests. Change-Id: I94a934a6b3b397b4cd0e9da3577325de58814335 Related: SYS#5549 --- configure.ac | 1 + src/osmo-bts-trx/sched_lchan_tchf.c | 11 +- src/osmo-bts-trx/sched_lchan_tchh.c | 17 +++- src/osmo-bts-trx/sched_utils.h | 76 +++++++++++++- tests/Makefile.am | 2 +- tests/amr/Makefile.am | 11 ++ tests/amr/amr_test.c | 151 +++++++++++++++++++++++++++ tests/amr/amr_test.ok | 152 ++++++++++++++++++++++++++++ tests/testsuite.at | 6 ++ 9 files changed, 416 insertions(+), 11 deletions(-) create mode 100644 tests/amr/Makefile.am create mode 100644 tests/amr/amr_test.c create mode 100644 tests/amr/amr_test.ok diff --git a/configure.ac b/configure.ac index 1b4c6e782..4f2e889fd 100644 --- a/configure.ac +++ b/configure.ac @@ -411,6 +411,7 @@ AC_OUTPUT( tests/tx_power/Makefile tests/power/Makefile tests/meas/Makefile + tests/amr/Makefile doc/Makefile doc/examples/Makefile doc/manuals/Makefile diff --git a/src/osmo-bts-trx/sched_lchan_tchf.c b/src/osmo-bts-trx/sched_lchan_tchf.c index 00efcf8a3..c5d60e425 100644 --- a/src/osmo-bts-trx/sched_lchan_tchf.c +++ b/src/osmo-bts-trx/sched_lchan_tchf.c @@ -65,6 +65,7 @@ int rx_tchf_fn(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi) uint16_t ber10k; uint8_t is_sub = 0; uint8_t ft; + bool amr_is_cmr; /* If handover RACH detection is turned on, treat this burst as an Access Burst. * Handle NOPE.ind as usually to ensure proper Uplink measurement reporting. */ @@ -129,6 +130,8 @@ int rx_tchf_fn(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi) * the first FN 4,13,21 defines that CMR is included in frame. * NOTE: A frame ends 7 FN after start. */ + fn_begin = gsm0502_fn_remap(bi->fn, FN_REMAP_TCH_F); + amr_is_cmr = !ul_amr_fn_is_cmi(fn_begin); /* The AFS_ONSET frame itself does not result into an RTP frame * since it only contains a recognition pattern that marks the @@ -144,8 +147,7 @@ int rx_tchf_fn(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi) * know this before we actually decode the frame) */ amr = 2; rc = gsm0503_tch_afs_decode_dtx(tch_data + amr, *bursts_p, - (((bi->fn + 26 - 7) % 26) >> 2) & 1, chan_state->codec, - chan_state->codecs, &chan_state->ul_ft, + amr_is_cmr, chan_state->codec, chan_state->codecs, &chan_state->ul_ft, &chan_state->ul_cmr, &n_errors, &n_bits_total, &chan_state->amr_last_dtx); /* Tag all frames that are not regular AMR voice frames as @@ -419,6 +421,7 @@ inval_mode1: enum osmo_amr_type ft_codec; enum osmo_amr_quality bfi; int8_t sti, cmi; + bool amr_is_cmr = !dl_amr_fn_is_cmi(br->fn); if (rsl_cmode != RSL_CMOD_SPD_SPEECH) { LOGL1SB(DL1P, LOGL_NOTICE, l1ts, br, "Dropping speech frame, " @@ -463,7 +466,7 @@ inval_mode1: "Codec (FT = %d) of RTP frame not in list\n", ft_codec); goto free_bad_msg; } - if (fn_is_codec_mode_request(br->fn) && chan_state->dl_ft != ft) { + if (amr_is_cmr && chan_state->dl_ft != ft) { LOGL1SB(DL1P, LOGL_NOTICE, l1ts, br, "Codec (FT = %d) " " of RTP cannot be changed now, but in next frame\n", ft_codec); goto free_bad_msg; @@ -552,7 +555,7 @@ int tx_tchf_fn(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br) * the first FN 0,8,17 defines that CMR is included in frame. */ gsm0503_tch_afs_encode(*bursts_p, msg_tch->l2h + 2, - msgb_l2len(msg_tch) - 2, fn_is_codec_mode_request(br->fn), + msgb_l2len(msg_tch) - 2, !dl_amr_fn_is_cmi(br->fn), chan_state->codec, chan_state->codecs, chan_state->dl_ft, chan_state->dl_cmr); diff --git a/src/osmo-bts-trx/sched_lchan_tchh.c b/src/osmo-bts-trx/sched_lchan_tchh.c index 940220415..2106a676b 100644 --- a/src/osmo-bts-trx/sched_lchan_tchh.c +++ b/src/osmo-bts-trx/sched_lchan_tchh.c @@ -72,6 +72,7 @@ int rx_tchh_fn(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi) uint8_t is_sub = 0; uint8_t ft; bool mask_stolen_tch_block = false; + bool fn_is_cmi; /* If handover RACH detection is turned on, treat this burst as an Access Burst. * Handle NOPE.ind as usually to ensure proper Uplink measurement reporting. */ @@ -164,10 +165,21 @@ int rx_tchh_fn(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi) break; } + /* Calculate the frame number where the block begins */ + if (bi->fn % 13 < 4) + fn_tch_end = GSM_TDMA_FN_SUB(bi->fn, 5); + else + fn_tch_end = GSM_TDMA_FN_SUB(bi->fn, 4); + if (lchan->nr == 0) + fn_begin = gsm0502_fn_remap(fn_tch_end, FN_REMAP_TCH_H0); + else + fn_begin = gsm0502_fn_remap(fn_tch_end, FN_REMAP_TCH_H1); + fn_is_cmi = ul_amr_fn_is_cmi(fn_begin); + /* See comment in function rx_tchf_fn() */ amr = 2; rc = gsm0503_tch_ahs_decode_dtx(tch_data + amr, *bursts_p, - fn_is_odd, fn_is_odd, chan_state->codec, + fn_is_odd, !fn_is_cmi, chan_state->codec, chan_state->codecs, &chan_state->ul_ft, &chan_state->ul_cmr, &n_errors, &n_bits_total, &chan_state->amr_last_dtx); @@ -343,7 +355,6 @@ compose_l1sap: fn_tch_end = GSM_TDMA_FN_SUB(bi->fn, 5); else fn_tch_end = GSM_TDMA_FN_SUB(bi->fn, 4); - if (lchan->nr == 0) fn_begin = gsm0502_fn_remap(fn_tch_end, FN_REMAP_TCH_H0); else @@ -441,7 +452,7 @@ int tx_tchh_fn(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br) * in frame, the first FN 0,8,17 or 1,9,18 defines that CMR is * included in frame. */ gsm0503_tch_ahs_encode(*bursts_p, msg_tch->l2h + 2, - msgb_l2len(msg_tch) - 2, fn_is_codec_mode_request(br->fn), + msgb_l2len(msg_tch) - 2, !dl_amr_fn_is_cmi(br->fn), chan_state->codec, chan_state->codecs, chan_state->dl_ft, chan_state->dl_cmr); diff --git a/src/osmo-bts-trx/sched_utils.h b/src/osmo-bts-trx/sched_utils.h index 4a1aaf5ff..f76e49bbd 100644 --- a/src/osmo-bts-trx/sched_utils.h +++ b/src/osmo-bts-trx/sched_utils.h @@ -23,6 +23,8 @@ #include #include +#include +#include extern void *tall_bts_ctx; @@ -35,8 +37,76 @@ static inline uint16_t compute_ber10k(int n_bits_total, int n_errors) return 10000 * n_errors / n_bits_total; } -/* determine if the FN is transmitting a CMR (1) or not (0) */ -static inline int fn_is_codec_mode_request(uint32_t fn) +/*! determine whether an uplink AMR block is CMI according to 3GPP TS 45.009. + * \param[in] fn_begin frame number of the beginning of the block. + * \returns true in case of CMI; false otherwise. */ +static inline bool ul_amr_fn_is_cmi(uint32_t fn_begin) { - return (((fn + 4) % 26) >> 2) & 1; + switch (fn_begin % 26) { + /*! See also: 3GPP TS 45.009, section 3.2.1.3 Transmitter/Receiver Synchronisation */ + /* valid for AHS subslot 0 and AFS: */ + case 0: + case 8: + case 17: + /* valid for AHS subslot 1: */ + case 1: + case 9: + case 18: + return true; + break; + /* Complementary values for sanity check */ + /* valid for AHS subslot 0 and AFS: */ + case 4: + case 13: + case 21: + /* valid for AHS subslot 1: */ + case 5: + case 14: + case 22: + return false; + break; + default: + LOGP(DL1P, LOGL_DEBUG, + "uplink frame number fn_begin=%u does not mark the beginning of a voice block!\n", fn_begin); + OSMO_ASSERT(false); + return false; + break; + } +} + +/*! determine the whether a downlink AMR block is CMI according to 3GPP TS 45.009. + * \param[in] fn_begin frame number of the beginning of the block. + * \returns true in case of CMI; false otherwise. */ +static inline bool dl_amr_fn_is_cmi(uint32_t fn_begin) +{ + switch (fn_begin % 26) { + /*! See also: 3GPP TS 45.009, section 3.2.1.3 Transmitter/Receiver Synchronisation */ + /* valid for AHS subslot 0 and AFS: */ + case 4: + case 13: + case 21: + /* valid for AHS subslot 1: */ + case 5: + case 14: + case 22: + return true; + break; + /* Complementary values for sanity check */ + /* valid for AHS subslot 0 and AFS: */ + case 0: + case 8: + case 17: + /* valid for AHS subslot 1: */ + case 1: + case 9: + case 18: + return false; + break; + default: + LOGP(DL1P, LOGL_DEBUG, + "downlink frame number fn_begin=%u does not mark the beginning of a voice block!\n", fn_begin); + OSMO_ASSERT(false); + return false; + break; + } } diff --git a/tests/Makefile.am b/tests/Makefile.am index 8d19e6ee0..a1d04a777 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = paging cipher agch misc handover tx_power power meas ta_control +SUBDIRS = paging cipher agch misc handover tx_power power meas ta_control amr if ENABLE_SYSMOBTS SUBDIRS += sysmobts diff --git a/tests/amr/Makefile.am b/tests/amr/Makefile.am new file mode 100644 index 000000000..dc0f1b81e --- /dev/null +++ b/tests/amr/Makefile.am @@ -0,0 +1,11 @@ +AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include +AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOCODEC_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) $(LIBOSMOTRAU_CFLAGS) +LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOCODEC_LIBS) \ + $(LIBOSMOABIS_LIBS) $(LIBOSMOTRAU_LIBS) +noinst_PROGRAMS = amr_test +EXTRA_DIST = amr_test.ok + +misc_test_SOURCES = amr_test.c +misc_test_LDADD = $(top_builddir)/src/common/libbts.a \ + $(LDADD) diff --git a/tests/amr/amr_test.c b/tests/amr/amr_test.c new file mode 100644 index 000000000..4efbf402a --- /dev/null +++ b/tests/amr/amr_test.c @@ -0,0 +1,151 @@ +/* (C) 2021 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * 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 Affero General Public License + * along with this program. If not, see . + * + */ + +#include +#include +#include +#include +#include "../../src/osmo-bts-trx/sched_utils.h" + +struct amr_cmi_test_data { + /* Frame number that marks the beginning of the voice block */ + uint32_t gsm_fn; + /* In uplink: True, when the voice block is a CMI block, false otherwise. */ + /* In downlink: False, when the voice block is a CMI block, true otherwise. */ + bool is_cmi; +}; + +/* The behavior of AHS in subslot 0 and AFS is the same */ +static const struct amr_cmi_test_data testvec_ahs_h0_and_afs[] = { + { 0, true }, + { 4, false }, + { 8, true }, + { 13, false }, + { 17, true }, + { 21, false }, + { 26, true }, + { 30, false }, + { 34, true }, + { 39, false }, + { 43, true }, + { 47, false }, + { 52, true }, + { 56, false }, + { 60, true }, + { 65, false }, + { 69, true }, + { 73, false }, + { 78, true }, + { 82, false }, + { 86, true }, + { 91, false }, + { 95, true }, + { 99, false }, +}; + +static const struct amr_cmi_test_data testvec_ahs_h1[] = { + { 1, true }, + { 5, false }, + { 9, true }, + { 14, false }, + { 18, true }, + { 22, false }, + { 27, true }, + { 31, false }, + { 35, true }, + { 40, false }, + { 44, true }, + { 48, false }, + { 53, true }, + { 57, false }, + { 61, true }, + { 66, false }, + { 70, true }, + { 74, false }, + { 79, true }, + { 83, false }, + { 87, true }, + { 92, false }, + { 96, true }, + { 100, false }, +}; + +static void test_amr_cmi_sched(void) +{ + unsigned int i; + bool res; + + printf("AMR transmission phase (CMI) in relation to GSM FN:\n"); + + for (i = 0; i < ARRAY_SIZE(testvec_ahs_h0_and_afs); i++) { + res = ul_amr_fn_is_cmi(testvec_ahs_h0_and_afs[i].gsm_fn); + printf("Uplink, AMR AHS on HR subslot 0: fn_begin=%u, CMI=%u\n", testvec_ahs_h0_and_afs[i].gsm_fn, res); + OSMO_ASSERT(res == testvec_ahs_h0_and_afs[i].is_cmi); + } + + printf("\n"); + + for (i = 0; i < ARRAY_SIZE(testvec_ahs_h0_and_afs); i++) { + res = dl_amr_fn_is_cmi(testvec_ahs_h0_and_afs[i].gsm_fn); + printf("Downlink, AMR AHS on HR subslot 0: fn_begin=%u, CMI=%u\n", testvec_ahs_h0_and_afs[i].gsm_fn, res); + OSMO_ASSERT(res == !testvec_ahs_h0_and_afs[i].is_cmi); + } + + printf("\n"); + printf("\n"); + + for (i = 0; i < ARRAY_SIZE(testvec_ahs_h1); i++) { + res = ul_amr_fn_is_cmi(testvec_ahs_h1[i].gsm_fn); + printf("Uplink, AMR AHS on HR subslot 1: fn_begin=%u, CMI=%u\n", testvec_ahs_h1[i].gsm_fn, res); + OSMO_ASSERT(res == testvec_ahs_h1[i].is_cmi); + } + + printf("\n"); + + for (i = 0; i < ARRAY_SIZE(testvec_ahs_h1); i++) { + res = dl_amr_fn_is_cmi(testvec_ahs_h1[i].gsm_fn); + printf("Downlink, AMR AHS on HR subslot 1: fn_begin=%u, CMI=%u\n", testvec_ahs_h1[i].gsm_fn, res); + OSMO_ASSERT(res == !testvec_ahs_h1[i].is_cmi); + } + + printf("\n"); + printf("\n"); + + for (i = 0; i < ARRAY_SIZE(testvec_ahs_h0_and_afs); i++) { + res = ul_amr_fn_is_cmi(testvec_ahs_h0_and_afs[i].gsm_fn); + printf("Uplink, AMR AFS: fn_begin=%u, CMI=%u\n", testvec_ahs_h0_and_afs[i].gsm_fn, res); + OSMO_ASSERT(res == testvec_ahs_h0_and_afs[i].is_cmi); + } + + printf("\n"); + + for (i = 0; i < ARRAY_SIZE(testvec_ahs_h0_and_afs); i++) { + res = dl_amr_fn_is_cmi(testvec_ahs_h0_and_afs[i].gsm_fn); + printf("Downlink, AMR AFS: fn_begin=%u, CMI=%u\n", testvec_ahs_h0_and_afs[i].gsm_fn, res); + OSMO_ASSERT(res == !testvec_ahs_h0_and_afs[i].is_cmi); + } +} + +int main(int argc, char **argv) +{ + + test_amr_cmi_sched(); + return EXIT_SUCCESS; +} diff --git a/tests/amr/amr_test.ok b/tests/amr/amr_test.ok new file mode 100644 index 000000000..ec1d1a08e --- /dev/null +++ b/tests/amr/amr_test.ok @@ -0,0 +1,152 @@ +AMR transmission phase (CMI) in relation to GSM FN: +Uplink, AMR AHS on HR subslot 0: fn_begin=0, CMI=1 +Uplink, AMR AHS on HR subslot 0: fn_begin=4, CMI=0 +Uplink, AMR AHS on HR subslot 0: fn_begin=8, CMI=1 +Uplink, AMR AHS on HR subslot 0: fn_begin=13, CMI=0 +Uplink, AMR AHS on HR subslot 0: fn_begin=17, CMI=1 +Uplink, AMR AHS on HR subslot 0: fn_begin=21, CMI=0 +Uplink, AMR AHS on HR subslot 0: fn_begin=26, CMI=1 +Uplink, AMR AHS on HR subslot 0: fn_begin=30, CMI=0 +Uplink, AMR AHS on HR subslot 0: fn_begin=34, CMI=1 +Uplink, AMR AHS on HR subslot 0: fn_begin=39, CMI=0 +Uplink, AMR AHS on HR subslot 0: fn_begin=43, CMI=1 +Uplink, AMR AHS on HR subslot 0: fn_begin=47, CMI=0 +Uplink, AMR AHS on HR subslot 0: fn_begin=52, CMI=1 +Uplink, AMR AHS on HR subslot 0: fn_begin=56, CMI=0 +Uplink, AMR AHS on HR subslot 0: fn_begin=60, CMI=1 +Uplink, AMR AHS on HR subslot 0: fn_begin=65, CMI=0 +Uplink, AMR AHS on HR subslot 0: fn_begin=69, CMI=1 +Uplink, AMR AHS on HR subslot 0: fn_begin=73, CMI=0 +Uplink, AMR AHS on HR subslot 0: fn_begin=78, CMI=1 +Uplink, AMR AHS on HR subslot 0: fn_begin=82, CMI=0 +Uplink, AMR AHS on HR subslot 0: fn_begin=86, CMI=1 +Uplink, AMR AHS on HR subslot 0: fn_begin=91, CMI=0 +Uplink, AMR AHS on HR subslot 0: fn_begin=95, CMI=1 +Uplink, AMR AHS on HR subslot 0: fn_begin=99, CMI=0 + +Downlink, AMR AHS on HR subslot 0: fn_begin=0, CMI=0 +Downlink, AMR AHS on HR subslot 0: fn_begin=4, CMI=1 +Downlink, AMR AHS on HR subslot 0: fn_begin=8, CMI=0 +Downlink, AMR AHS on HR subslot 0: fn_begin=13, CMI=1 +Downlink, AMR AHS on HR subslot 0: fn_begin=17, CMI=0 +Downlink, AMR AHS on HR subslot 0: fn_begin=21, CMI=1 +Downlink, AMR AHS on HR subslot 0: fn_begin=26, CMI=0 +Downlink, AMR AHS on HR subslot 0: fn_begin=30, CMI=1 +Downlink, AMR AHS on HR subslot 0: fn_begin=34, CMI=0 +Downlink, AMR AHS on HR subslot 0: fn_begin=39, CMI=1 +Downlink, AMR AHS on HR subslot 0: fn_begin=43, CMI=0 +Downlink, AMR AHS on HR subslot 0: fn_begin=47, CMI=1 +Downlink, AMR AHS on HR subslot 0: fn_begin=52, CMI=0 +Downlink, AMR AHS on HR subslot 0: fn_begin=56, CMI=1 +Downlink, AMR AHS on HR subslot 0: fn_begin=60, CMI=0 +Downlink, AMR AHS on HR subslot 0: fn_begin=65, CMI=1 +Downlink, AMR AHS on HR subslot 0: fn_begin=69, CMI=0 +Downlink, AMR AHS on HR subslot 0: fn_begin=73, CMI=1 +Downlink, AMR AHS on HR subslot 0: fn_begin=78, CMI=0 +Downlink, AMR AHS on HR subslot 0: fn_begin=82, CMI=1 +Downlink, AMR AHS on HR subslot 0: fn_begin=86, CMI=0 +Downlink, AMR AHS on HR subslot 0: fn_begin=91, CMI=1 +Downlink, AMR AHS on HR subslot 0: fn_begin=95, CMI=0 +Downlink, AMR AHS on HR subslot 0: fn_begin=99, CMI=1 + + +Uplink, AMR AHS on HR subslot 1: fn_begin=1, CMI=1 +Uplink, AMR AHS on HR subslot 1: fn_begin=5, CMI=0 +Uplink, AMR AHS on HR subslot 1: fn_begin=9, CMI=1 +Uplink, AMR AHS on HR subslot 1: fn_begin=14, CMI=0 +Uplink, AMR AHS on HR subslot 1: fn_begin=18, CMI=1 +Uplink, AMR AHS on HR subslot 1: fn_begin=22, CMI=0 +Uplink, AMR AHS on HR subslot 1: fn_begin=27, CMI=1 +Uplink, AMR AHS on HR subslot 1: fn_begin=31, CMI=0 +Uplink, AMR AHS on HR subslot 1: fn_begin=35, CMI=1 +Uplink, AMR AHS on HR subslot 1: fn_begin=40, CMI=0 +Uplink, AMR AHS on HR subslot 1: fn_begin=44, CMI=1 +Uplink, AMR AHS on HR subslot 1: fn_begin=48, CMI=0 +Uplink, AMR AHS on HR subslot 1: fn_begin=53, CMI=1 +Uplink, AMR AHS on HR subslot 1: fn_begin=57, CMI=0 +Uplink, AMR AHS on HR subslot 1: fn_begin=61, CMI=1 +Uplink, AMR AHS on HR subslot 1: fn_begin=66, CMI=0 +Uplink, AMR AHS on HR subslot 1: fn_begin=70, CMI=1 +Uplink, AMR AHS on HR subslot 1: fn_begin=74, CMI=0 +Uplink, AMR AHS on HR subslot 1: fn_begin=79, CMI=1 +Uplink, AMR AHS on HR subslot 1: fn_begin=83, CMI=0 +Uplink, AMR AHS on HR subslot 1: fn_begin=87, CMI=1 +Uplink, AMR AHS on HR subslot 1: fn_begin=92, CMI=0 +Uplink, AMR AHS on HR subslot 1: fn_begin=96, CMI=1 +Uplink, AMR AHS on HR subslot 1: fn_begin=100, CMI=0 + +Downlink, AMR AHS on HR subslot 1: fn_begin=1, CMI=0 +Downlink, AMR AHS on HR subslot 1: fn_begin=5, CMI=1 +Downlink, AMR AHS on HR subslot 1: fn_begin=9, CMI=0 +Downlink, AMR AHS on HR subslot 1: fn_begin=14, CMI=1 +Downlink, AMR AHS on HR subslot 1: fn_begin=18, CMI=0 +Downlink, AMR AHS on HR subslot 1: fn_begin=22, CMI=1 +Downlink, AMR AHS on HR subslot 1: fn_begin=27, CMI=0 +Downlink, AMR AHS on HR subslot 1: fn_begin=31, CMI=1 +Downlink, AMR AHS on HR subslot 1: fn_begin=35, CMI=0 +Downlink, AMR AHS on HR subslot 1: fn_begin=40, CMI=1 +Downlink, AMR AHS on HR subslot 1: fn_begin=44, CMI=0 +Downlink, AMR AHS on HR subslot 1: fn_begin=48, CMI=1 +Downlink, AMR AHS on HR subslot 1: fn_begin=53, CMI=0 +Downlink, AMR AHS on HR subslot 1: fn_begin=57, CMI=1 +Downlink, AMR AHS on HR subslot 1: fn_begin=61, CMI=0 +Downlink, AMR AHS on HR subslot 1: fn_begin=66, CMI=1 +Downlink, AMR AHS on HR subslot 1: fn_begin=70, CMI=0 +Downlink, AMR AHS on HR subslot 1: fn_begin=74, CMI=1 +Downlink, AMR AHS on HR subslot 1: fn_begin=79, CMI=0 +Downlink, AMR AHS on HR subslot 1: fn_begin=83, CMI=1 +Downlink, AMR AHS on HR subslot 1: fn_begin=87, CMI=0 +Downlink, AMR AHS on HR subslot 1: fn_begin=92, CMI=1 +Downlink, AMR AHS on HR subslot 1: fn_begin=96, CMI=0 +Downlink, AMR AHS on HR subslot 1: fn_begin=100, CMI=1 + + +Uplink, AMR AFS: fn_begin=0, CMI=1 +Uplink, AMR AFS: fn_begin=4, CMI=0 +Uplink, AMR AFS: fn_begin=8, CMI=1 +Uplink, AMR AFS: fn_begin=13, CMI=0 +Uplink, AMR AFS: fn_begin=17, CMI=1 +Uplink, AMR AFS: fn_begin=21, CMI=0 +Uplink, AMR AFS: fn_begin=26, CMI=1 +Uplink, AMR AFS: fn_begin=30, CMI=0 +Uplink, AMR AFS: fn_begin=34, CMI=1 +Uplink, AMR AFS: fn_begin=39, CMI=0 +Uplink, AMR AFS: fn_begin=43, CMI=1 +Uplink, AMR AFS: fn_begin=47, CMI=0 +Uplink, AMR AFS: fn_begin=52, CMI=1 +Uplink, AMR AFS: fn_begin=56, CMI=0 +Uplink, AMR AFS: fn_begin=60, CMI=1 +Uplink, AMR AFS: fn_begin=65, CMI=0 +Uplink, AMR AFS: fn_begin=69, CMI=1 +Uplink, AMR AFS: fn_begin=73, CMI=0 +Uplink, AMR AFS: fn_begin=78, CMI=1 +Uplink, AMR AFS: fn_begin=82, CMI=0 +Uplink, AMR AFS: fn_begin=86, CMI=1 +Uplink, AMR AFS: fn_begin=91, CMI=0 +Uplink, AMR AFS: fn_begin=95, CMI=1 +Uplink, AMR AFS: fn_begin=99, CMI=0 + +Downlink, AMR AFS: fn_begin=0, CMI=0 +Downlink, AMR AFS: fn_begin=4, CMI=1 +Downlink, AMR AFS: fn_begin=8, CMI=0 +Downlink, AMR AFS: fn_begin=13, CMI=1 +Downlink, AMR AFS: fn_begin=17, CMI=0 +Downlink, AMR AFS: fn_begin=21, CMI=1 +Downlink, AMR AFS: fn_begin=26, CMI=0 +Downlink, AMR AFS: fn_begin=30, CMI=1 +Downlink, AMR AFS: fn_begin=34, CMI=0 +Downlink, AMR AFS: fn_begin=39, CMI=1 +Downlink, AMR AFS: fn_begin=43, CMI=0 +Downlink, AMR AFS: fn_begin=47, CMI=1 +Downlink, AMR AFS: fn_begin=52, CMI=0 +Downlink, AMR AFS: fn_begin=56, CMI=1 +Downlink, AMR AFS: fn_begin=60, CMI=0 +Downlink, AMR AFS: fn_begin=65, CMI=1 +Downlink, AMR AFS: fn_begin=69, CMI=0 +Downlink, AMR AFS: fn_begin=73, CMI=1 +Downlink, AMR AFS: fn_begin=78, CMI=0 +Downlink, AMR AFS: fn_begin=82, CMI=1 +Downlink, AMR AFS: fn_begin=86, CMI=0 +Downlink, AMR AFS: fn_begin=91, CMI=1 +Downlink, AMR AFS: fn_begin=95, CMI=0 +Downlink, AMR AFS: fn_begin=99, CMI=1 diff --git a/tests/testsuite.at b/tests/testsuite.at index ba5a409b5..f2d17fbf9 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -63,3 +63,9 @@ AT_KEYWORDS([ta_control]) cat $abs_srcdir/ta_control/ta_control_test.ok > expout AT_CHECK([$abs_top_builddir/tests/ta_control/ta_control_test], [], [expout], [ignore]) AT_CLEANUP + +AT_SETUP([amr]) +AT_KEYWORDS([amr]) +cat $abs_srcdir/amr/amr_test.ok > expout +AT_CHECK([$abs_top_builddir/tests/amr/amr_test], [], [expout], [ignore]) +AT_CLEANUP