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
This commit is contained in:
Philipp Maier 2021-08-26 13:55:27 +02:00 committed by laforge
parent ca41f091fc
commit a65cf63619
9 changed files with 416 additions and 11 deletions

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -23,6 +23,8 @@
#include <stdint.h>
#include <errno.h>
#include <stdbool.h>
#include <osmo-bts/scheduler.h>
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;
}
}

View File

@ -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

11
tests/amr/Makefile.am Normal file
View File

@ -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)

151
tests/amr/amr_test.c Normal file
View File

@ -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 <http://www.gnu.org/licenses/>.
*
*/
#include <osmo-bts/logging.h>
#include <osmocom/core/utils.h>
#include <stdlib.h>
#include <stdio.h>
#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;
}

152
tests/amr/amr_test.ok Normal file
View File

@ -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

View File

@ -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