Forward ETWS Primary Notification to MS

Receive an Application Information Request from the BTS via PCU
interface. Construct a Packet Application Information message from it
(3GPP TS 44.060 11.2.47) and send it to all MS with active TBF.

The TTCN-3 test infrastructure to test this feature is not quite ready
yet, so I've added C unit tests instead.

Related: OS#4048
Change-Id: Ie35959f833f46bde5f2126314b6f96763f863b36
This commit is contained in:
Oliver Smith
2019-09-05 17:13:33 +02:00
committed by laforge
parent 5360ef5447
commit cfb6321b88
15 changed files with 407 additions and 30 deletions

View File

@@ -13,6 +13,7 @@
#define PCU_IF_MSG_DATA_CNF 0x01 /* confirm (e.g. transmission on PCH) */
#define PCU_IF_MSG_DATA_IND 0x02 /* receive data from given channel */
#define PCU_IF_MSG_SUSP_REQ 0x03 /* BTS forwards GPRS SUSP REQ to PCU */
#define PCU_IF_MSG_APP_INFO_REQ 0x04 /* BTS asks PCU to transmit APP INFO via PACCH */
#define PCU_IF_MSG_RTS_REQ 0x10 /* ready to send request */
#define PCU_IF_MSG_DATA_CNF_DT 0x11 /* confirm (with direct tlli) */
#define PCU_IF_MSG_RACH_IND 0x22 /* receive RACH */
@@ -172,6 +173,13 @@ struct gsm_pcu_if_pag_req {
uint8_t identity_lv[9];
} __attribute__ ((packed));
/* BTS tells PCU to [once] send given application data via PACCH to all UE with active TBF */
struct gsm_pcu_if_app_info_req {
uint8_t application_type; /* 4bit field, see TS 44.060 11.2.47 */
uint8_t len; /* length of data */
uint8_t data[162]; /* random size choice; ETWS needs 56 bytes */
} __attribute__ ((packed));
/* BTS tells PCU about a GPRS SUSPENSION REQUEST received on DCCH */
struct gsm_pcu_if_susp_req {
uint32_t tlli;
@@ -198,6 +206,7 @@ struct gsm_pcu_if {
struct gsm_pcu_if_act_req act_req;
struct gsm_pcu_if_time_ind time_ind;
struct gsm_pcu_if_pag_req pag_req;
struct gsm_pcu_if_app_info_req app_info_req;
} u;
} __attribute__ ((packed));

View File

@@ -69,7 +69,8 @@ libgprs_la_SOURCES = \
gprs_codel.c \
coding_scheme.c \
gprs_coding_scheme.cpp \
egprs_rlc_compression.cpp
egprs_rlc_compression.cpp \
gprs_rlcmac_sched.cpp
bin_PROGRAMS = \
osmo-pcu

View File

@@ -231,6 +231,7 @@ BTS::BTS()
{
memset(&m_bts, 0, sizeof(m_bts));
m_bts.bts = this;
m_bts.app_info = NULL;
m_bts.dl_tbf_preemptive_retransmission = true;
m_bts.T_defs_bts = T_defs_bts;
m_bts.T_defs_pcu = T_defs_pcu;
@@ -279,6 +280,11 @@ void BTS::cleanup()
osmo_stat_item_group_free(m_statg);
m_statg = NULL;
}
if (m_bts.app_info) {
msgb_free(m_bts.app_info);
m_bts.app_info = NULL;
}
}
BTS::~BTS()

View File

@@ -164,6 +164,11 @@ struct gprs_rlcmac_bts {
/* Are we talking Gb with IP-SNS (true) or classic Gb? */
bool gb_dialect_sns;
/* Packet Application Information (3GPP TS 44.060 11.2.47, usually ETWS primary message). We don't need to store
* more than one message, because they get sent so rarely. */
struct msgb *app_info;
uint32_t app_info_pending; /* Count of MS with active TBF, to which we did not send app_info yet */
};
#ifdef __cplusplus

View File

@@ -135,6 +135,7 @@ GprsMs::GprsMs(BTS *bts, uint32_t tlli) :
gprs_codel_set_interval(m_codel_state, codel_interval);
}
m_last_cs_not_low = now_msec();
app_info_pending = false;
}
GprsMs::~GprsMs()

View File

@@ -136,6 +136,8 @@ public:
/* internal use */
static void timeout(void *priv_);
bool app_info_pending;
protected:
void update_status();
GprsMs *ref();

View File

@@ -41,4 +41,25 @@ int gprs_rlcmac_paging_request(uint8_t *ptmsi, uint16_t ptmsi_len,
return 0;
}
/* Encode Application Information Request to Packet Application Information (3GPP TS 44.060 11.2.47) */
struct msgb *gprs_rlcmac_app_info_msg(const struct gsm_pcu_if_app_info_req *req) {
struct msgb *msg;
uint16_t msgb_len = req->len + 1;
struct bitvec bv = {0, msgb_len, NULL};
const enum bit_value page_mode[] = {ZERO, ZERO}; /* Normal Paging (3GPP TS 44.060 12.20) */
if (!req->len) {
LOGP(DRLCMAC, LOGL_ERROR, "Application Information Request with zero length received!\n");
return NULL;
}
msg = msgb_alloc(msgb_len, "app_info_msg");
if (!msg)
return NULL;
bv.data = msgb_put(msg, msgb_len);
bitvec_set_bits(&bv, page_mode, 2);
bitvec_set_uint(&bv, req->application_type, 4);
bitvec_set_bytes(&bv, req->data, req->len);
return msg;
}

View File

@@ -31,6 +31,7 @@ extern "C" {
#include <osmocom/core/linuxlist.h>
#include <osmocom/core/timer.h>
#include <osmocom/core/bitvec.h>
#include <osmocom/pcu/pcuif_proto.h>
}
#endif
@@ -94,6 +95,8 @@ int gprs_rlcmac_tx_ul_ud(gprs_rlcmac_tbf *tbf);
int gprs_rlcmac_paging_request(uint8_t *ptmsi, uint16_t ptmsi_len,
const char *imsi);
struct msgb *gprs_rlcmac_app_info_msg(const struct gsm_pcu_if_app_info_req *req);
int gprs_rlcmac_rcv_rts_block(struct gprs_rlcmac_bts *bts,
uint8_t trx, uint8_t ts,
uint32_t fn, uint8_t block_nr);

View File

@@ -123,6 +123,34 @@ static uint8_t sched_select_uplink(uint8_t trx, uint8_t ts, uint32_t fn,
return usf;
}
struct msgb *sched_app_info(struct gprs_rlcmac_tbf *tbf) {
struct gprs_rlcmac_bts *bts_data;
struct msgb *msg = NULL;
if (!tbf || !tbf->ms()->app_info_pending)
return NULL;
bts_data = BTS::main_bts()->bts_data();
if (bts_data->app_info) {
LOGP(DRLCMACSCHED, LOGL_DEBUG, "Sending Packet Application Information message\n");
msg = msgb_copy(bts_data->app_info, "app_info_msg_sched");
} else
LOGP(DRLCMACSCHED, LOGL_ERROR, "MS has app_info_pending flag set, but no Packet Application Information"
" message stored in BTS!\n");
tbf->ms()->app_info_pending = false;
bts_data->app_info_pending--;
if (!bts_data->app_info_pending) {
LOGP(DRLCMACSCHED, LOGL_DEBUG, "Packet Application Information successfully sent to all MS with active"
" TBF\n");
msgb_free(bts_data->app_info);
bts_data->app_info = NULL;
}
return msg;
}
static struct msgb *sched_select_ctrl_msg(
uint8_t trx, uint8_t ts, uint32_t fn,
uint8_t block_nr, struct gprs_rlcmac_pdch *pdch,
@@ -134,37 +162,42 @@ static struct msgb *sched_select_ctrl_msg(
struct gprs_rlcmac_tbf *tbf = NULL;
struct gprs_rlcmac_tbf *next_list[3] = { ul_ass_tbf, dl_ass_tbf, ul_ack_tbf };
for (size_t i = 0; i < ARRAY_SIZE(next_list); ++i) {
tbf = next_list[(pdch->next_ctrl_prio + i) % 3];
if (!tbf)
continue;
/* Send Packet Application Information first (ETWS primary notifications) */
msg = sched_app_info(dl_ass_tbf);
/*
* Assignments for the same direction have lower precedence,
* because they may kill the TBF when the CONTROL ACK is
* received, thus preventing the others from being processed.
*/
if (tbf == ul_ass_tbf && tbf->ul_ass_state_is(GPRS_RLCMAC_UL_ASS_SEND_ASS_REJ))
msg = ul_ass_tbf->create_packet_access_reject();
else if (tbf == ul_ass_tbf && tbf->direction ==
GPRS_RLCMAC_DL_TBF)
if (tbf->ul_ass_state_is(GPRS_RLCMAC_UL_ASS_SEND_ASS_REJ))
if (!msg) {
for (size_t i = 0; i < ARRAY_SIZE(next_list); ++i) {
tbf = next_list[(pdch->next_ctrl_prio + i) % 3];
if (!tbf)
continue;
/*
* Assignments for the same direction have lower precedence,
* because they may kill the TBF when the CONTROL ACK is
* received, thus preventing the others from being processed.
*/
if (tbf == ul_ass_tbf && tbf->ul_ass_state_is(GPRS_RLCMAC_UL_ASS_SEND_ASS_REJ))
msg = ul_ass_tbf->create_packet_access_reject();
else
msg = ul_ass_tbf->create_ul_ass(fn, ts);
else if (tbf == dl_ass_tbf && tbf->direction == GPRS_RLCMAC_UL_TBF)
msg = dl_ass_tbf->create_dl_ass(fn, ts);
else if (tbf == ul_ack_tbf)
msg = ul_ack_tbf->create_ul_ack(fn, ts);
else if (tbf == ul_ass_tbf && tbf->direction ==
GPRS_RLCMAC_DL_TBF)
if (tbf->ul_ass_state_is(GPRS_RLCMAC_UL_ASS_SEND_ASS_REJ))
msg = ul_ass_tbf->create_packet_access_reject();
else
msg = ul_ass_tbf->create_ul_ass(fn, ts);
else if (tbf == dl_ass_tbf && tbf->direction == GPRS_RLCMAC_UL_TBF)
msg = dl_ass_tbf->create_dl_ass(fn, ts);
else if (tbf == ul_ack_tbf)
msg = ul_ack_tbf->create_ul_ack(fn, ts);
if (!msg) {
tbf = NULL;
continue;
if (!msg) {
tbf = NULL;
continue;
}
pdch->next_ctrl_prio += 1;
pdch->next_ctrl_prio %= 3;
break;
}
pdch->next_ctrl_prio += 1;
pdch->next_ctrl_prio %= 3;
break;
}
if (!msg) {

View File

@@ -620,6 +620,42 @@ static int pcu_rx_susp_req(struct gsm_pcu_if_susp_req *susp_req)
return bssgp_tx_suspend(bctx->nsei, susp_req->tlli, &ra_id);
}
static int pcu_rx_app_info_req(struct gsm_pcu_if_app_info_req *app_info_req)
{
LListHead<GprsMs> *ms_iter;
BTS *bts = BTS::main_bts();
struct gprs_rlcmac_bts *bts_data = bts->bts_data();
LOGP(DL1IF, LOGL_DEBUG, "Application Information Request received: type=0x%08x len=%i\n",
app_info_req->application_type, app_info_req->len);
bts_data->app_info_pending = 0;
llist_for_each(ms_iter, &bts->ms_store().ms_list()) {
GprsMs *ms = ms_iter->entry();
if (!ms->dl_tbf())
continue;
bts_data->app_info_pending++;
ms->app_info_pending = true;
}
if (!bts_data->app_info_pending) {
LOGP(DL1IF, LOGL_NOTICE, "Packet Application Information will not be sent, no subscribers with active"
" TBF\n");
return -1;
}
if (bts_data->app_info) {
LOGP(DL1IF, LOGL_NOTICE, "Previous Packet Application Information was not sent to all subscribers,"
" overwriting with new one\n");
msgb_free(bts_data->app_info);
}
LOGP(DL1IF, LOGL_INFO, "Sending Packet Application Information to %i subscribers with active TBF\n",
bts_data->app_info_pending);
bts_data->app_info = gprs_rlcmac_app_info_msg(app_info_req);
return 0;
}
int pcu_rx(uint8_t msg_type, struct gsm_pcu_if *pcu_prim)
{
int rc = 0;
@@ -649,6 +685,9 @@ int pcu_rx(uint8_t msg_type, struct gsm_pcu_if *pcu_prim)
case PCU_IF_MSG_SUSP_REQ:
rc = pcu_rx_susp_req(&pcu_prim->u.susp_req);
break;
case PCU_IF_MSG_APP_INFO_REQ:
rc = pcu_rx_app_info_req(&pcu_prim->u.app_info_req);
break;
default:
LOGP(DL1IF, LOGL_ERROR, "Received unknown PCU msg type %d\n",
msg_type);

View File

@@ -1,7 +1,7 @@
AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES) $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGB_CFLAGS) $(LIBOSMOGSM_CFLAGS) -I$(top_srcdir)/src/ -I$(top_srcdir)/include/
AM_LDFLAGS = -lrt -no-install
check_PROGRAMS = rlcmac/RLCMACTest alloc/AllocTest alloc/MslotTest tbf/TbfTest types/TypesTest ms/MsTest llist/LListTest llc/LlcTest codel/codel_test edge/EdgeTest bitcomp/BitcompTest fn/FnTest
check_PROGRAMS = rlcmac/RLCMACTest alloc/AllocTest alloc/MslotTest tbf/TbfTest types/TypesTest ms/MsTest llist/LListTest llc/LlcTest codel/codel_test edge/EdgeTest bitcomp/BitcompTest fn/FnTest app_info/AppInfoTest
noinst_PROGRAMS = emu/pcu_emu
rlcmac_RLCMACTest_SOURCES = rlcmac/RLCMACTest.cpp
@@ -108,6 +108,14 @@ fn_FnTest_LDADD = \
$(LIBOSMOCORE_LIBS) \
$(COMMON_LA)
app_info_AppInfoTest_SOURCES = app_info/AppInfoTest.cpp
app_info_AppInfoTest_LDADD = \
$(top_builddir)/src/libgprs.la \
$(LIBOSMOGB_LIBS) \
$(LIBOSMOGSM_LIBS) \
$(LIBOSMOCORE_LIBS) \
$(COMMON_LA)
# The `:;' works around a Bash 3.2 bug when the output is not writeable.
$(srcdir)/package.m4: $(top_srcdir)/configure.ac
:;{ \
@@ -138,7 +146,8 @@ EXTRA_DIST = \
llist/LListTest.ok llist/LListTest.err \
codel/codel_test.ok \
edge/EdgeTest.ok \
fn/FnTest.ok
fn/FnTest.ok \
app_info/AppInfoTest.ok app_info/AppInfoTest.err
DISTCLEANFILES = atconfig

View File

@@ -0,0 +1,191 @@
/* Copyright (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* 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 General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <cstdlib>
#include <cstring>
#include <assert.h>
#include "gprs_rlcmac.h"
#include "bts.h"
extern "C" {
#include <osmocom/vty/telnet_interface.h>
#include <osmocom/vty/logging.h>
#include <osmocom/core/utils.h>
#include <osmocom/core/msgb.h>
#include <osmocom/core/application.h>
}
using namespace std;
gprs_rlcmac_dl_tbf *tbf1, *tbf2;
GprsMs *ms1, *ms2;
struct msgb *sched_app_info(struct gprs_rlcmac_tbf *tbf);
/* globals used by the code */
void *tall_pcu_ctx;
int16_t spoof_mnc = 0, spoof_mcc = 0;
bool spoof_mnc_3_digits = false;
void test_enc_zero_len() {
struct gsm_pcu_if_app_info_req req = {0, 0, {0}};
fprintf(stderr, "--- %s ---\n", __func__);
assert(gprs_rlcmac_app_info_msg(&req) == NULL);
fprintf(stderr, "\n");
}
void test_enc() {
struct gsm_pcu_if_app_info_req req = {0, 15, {0xff, 0x00, 0xff}};
const char *exp = "03 fc 03 fc 00 00 00 00 00 00 00 00 00 00 00 00 "; /* shifted by two bits to the right */
struct msgb *msg;
char *msg_dump;
fprintf(stderr, "--- %s ---\n", __func__);
msg = gprs_rlcmac_app_info_msg(&req);
msg_dump = msgb_hexdump_c(tall_pcu_ctx, msg);
fprintf(stderr, "exp: %s\n", exp);
fprintf(stderr, "msg: %s\n", msg_dump);
assert(strcmp(msg_dump, exp) == 0);
msgb_free(msg);
talloc_free(msg_dump);
fprintf(stderr, "\n");
}
void test_pcu_rx_no_subscr_with_active_tbf()
{
struct gsm_pcu_if pcu_prim = {PCU_IF_MSG_APP_INFO_REQ, };
fprintf(stderr, "--- %s ---\n", __func__);
pcu_rx(PCU_IF_MSG_APP_INFO_REQ, &pcu_prim);
fprintf(stderr, "\n");
}
void prepare_bts_with_two_dl_tbf_subscr()
{
BTS *bts = BTS::main_bts();
struct gprs_rlcmac_bts *bts_data;
struct gprs_rlcmac_trx *trx;
fprintf(stderr, "--- %s ---\n", __func__);
bts_data = bts->bts_data();
bts_data->alloc_algorithm = alloc_algorithm_b;
trx = bts_data->trx;
trx->pdch[4].enable();
trx->pdch[5].enable();
trx->pdch[6].enable();
trx->pdch[7].enable();
ms1 = bts->ms_alloc(10, 11);
tbf1 = tbf_alloc_dl_tbf(bts_data, ms1, 0, 10, 11, false);
ms2 = bts->ms_alloc(12, 13);
tbf2 = tbf_alloc_dl_tbf(bts_data, ms2, 0, 12, 13, false);
fprintf(stderr, "\n");
}
void test_sched_app_info_ok()
{
struct gsm_pcu_if pcu_prim = {PCU_IF_MSG_APP_INFO_REQ, };
struct msgb *msg;
fprintf(stderr, "--- %s ---\n", __func__);
pcu_prim.u.app_info_req = {0, 15, {0xff, 0x00, 0xff}};
pcu_rx(PCU_IF_MSG_APP_INFO_REQ, &pcu_prim);
msg = sched_app_info(tbf1);
assert(msg);
msgb_free(msg);
msg = sched_app_info(tbf2);
assert(msg);
msgb_free(msg);
fprintf(stderr, "\n");
}
void test_sched_app_info_missing_app_info_in_bts()
{
struct gprs_rlcmac_bts *bts_data = BTS::main_bts()->bts_data();
struct gsm_pcu_if pcu_prim = {PCU_IF_MSG_APP_INFO_REQ, };
fprintf(stderr, "--- %s ---\n", __func__);
pcu_prim.u.app_info_req = {0, 15, {0xff, 0x00, 0xff}};
pcu_rx(PCU_IF_MSG_APP_INFO_REQ, &pcu_prim);
msgb_free(bts_data->app_info);
bts_data->app_info = NULL;
assert(sched_app_info(tbf1) == NULL);
fprintf(stderr, "\n");
}
void test_pcu_rx_overwrite_app_info()
{
struct gsm_pcu_if pcu_prim = {PCU_IF_MSG_APP_INFO_REQ, };
fprintf(stderr, "--- %s ---\n", __func__);
pcu_prim.u.app_info_req = {0, 15, {0xff, 0x00, 0xff}};
pcu_rx(PCU_IF_MSG_APP_INFO_REQ, &pcu_prim);
pcu_rx(PCU_IF_MSG_APP_INFO_REQ, &pcu_prim);
fprintf(stderr, "\n");
}
void cleanup()
{
fprintf(stderr, "--- %s ---\n", __func__);
BTS::main_bts()->cleanup();
talloc_free(tbf1);
talloc_free(tbf2);
/* FIXME: talloc report disabled, because bts->ms_alloc() in prepare_bts_with_two_dl_tbf_subscr() causes leak */
/* talloc_report_full(tall_pcu_ctx, stderr); */
talloc_free(tall_pcu_ctx);
}
int main(int argc, char *argv[])
{
tall_pcu_ctx = talloc_named_const(NULL, 1, "AppInfoTest");
osmo_init_logging2(tall_pcu_ctx, &gprs_log_info);
log_set_use_color(osmo_stderr_target, 0);
log_set_print_filename(osmo_stderr_target, 0);
log_parse_category_mask(osmo_stderr_target, "DL1IF,1:DRLCMAC,3:DRLCMACSCHED,1");
test_enc_zero_len();
test_enc();
test_pcu_rx_no_subscr_with_active_tbf();
prepare_bts_with_two_dl_tbf_subscr();
test_sched_app_info_ok();
test_sched_app_info_missing_app_info_in_bts();
test_pcu_rx_overwrite_app_info();
cleanup();
}
/*
* stubs that should not be reached
*/
extern "C" {
void l1if_pdch_req() { abort(); }
void l1if_connect_pdch() { abort(); }
void l1if_close_pdch() { abort(); }
void l1if_open_pdch() { abort(); }
}

View File

@@ -0,0 +1,50 @@
--- test_enc_zero_len ---
Application Information Request with zero length received!
--- test_enc ---
exp: 03 fc 03 fc 00 00 00 00 00 00 00 00 00 00 00 00
msg: 03 fc 03 fc 00 00 00 00 00 00 00 00 00 00 00 00
--- test_pcu_rx_no_subscr_with_active_tbf ---
Application Information Request received: type=0x00000000 len=0
Packet Application Information will not be sent, no subscribers with active TBF
--- prepare_bts_with_two_dl_tbf_subscr ---
Creating MS object, TLLI = 0x00000000
Modifying MS object, TLLI = 0x00000000, MS class 0 -> 10
Modifying MS object, TLLI = 0x00000000, EGPRS MS class 0 -> 11
[DL] algo B <multi> (suggested TRX: 0): using 4 slots
PDCH(TS 4, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL), 1 TBFs, USFs = 00, TFIs = 00000001.
PDCH(TS 5, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL), 1 TBFs, USFs = 00, TFIs = 00000001.
PDCH(TS 6, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL), 1 TBFs, USFs = 00, TFIs = 00000001.
PDCH(TS 7, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL), 1 TBFs, USFs = 00, TFIs = 00000001.
Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL)
Creating MS object, TLLI = 0x00000000
Modifying MS object, TLLI = 0x00000000, MS class 0 -> 12
Modifying MS object, TLLI = 0x00000000, EGPRS MS class 0 -> 13
[DL] algo B <multi> (suggested TRX: 0): using 3 slots
PDCH(TS 4, TRX 0): Attaching TBF(TFI=1 TLLI=0x00000000 DIR=DL STATE=NULL), 2 TBFs, USFs = 00, TFIs = 00000003.
PDCH(TS 5, TRX 0): Attaching TBF(TFI=1 TLLI=0x00000000 DIR=DL STATE=NULL), 2 TBFs, USFs = 00, TFIs = 00000003.
PDCH(TS 6, TRX 0): Attaching TBF(TFI=1 TLLI=0x00000000 DIR=DL STATE=NULL), 2 TBFs, USFs = 00, TFIs = 00000003.
Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=1 TLLI=0x00000000 DIR=DL STATE=NULL)
--- test_sched_app_info_ok ---
Application Information Request received: type=0x00000000 len=15
Sending Packet Application Information to 2 subscribers with active TBF
Sending Packet Application Information message
Sending Packet Application Information message
Packet Application Information successfully sent to all MS with active TBF
--- test_sched_app_info_missing_app_info_in_bts ---
Application Information Request received: type=0x00000000 len=15
Sending Packet Application Information to 2 subscribers with active TBF
MS has app_info_pending flag set, but no Packet Application Information message stored in BTS!
--- test_pcu_rx_overwrite_app_info ---
Application Information Request received: type=0x00000000 len=15
Sending Packet Application Information to 2 subscribers with active TBF
Application Information Request received: type=0x00000000 len=15
Previous Packet Application Information was not sent to all subscribers, overwriting with new one
Sending Packet Application Information to 2 subscribers with active TBF
--- cleanup ---

View File

View File

@@ -82,3 +82,10 @@ AT_KEYWORDS([fn])
cat $abs_srcdir/fn/FnTest.ok > expout
AT_CHECK([$OSMO_QEMU $abs_top_builddir/tests/fn/FnTest], [0], [expout], [ignore])
AT_CLEANUP
AT_SETUP([app_info])
AT_KEYWORDS([app_info])
cat $abs_srcdir/app_info/AppInfoTest.ok > expout
cat $abs_srcdir/app_info/AppInfoTest.err > experr
AT_CHECK([$OSMO_QEMU $abs_top_builddir/tests/app_info/AppInfoTest], [0], [expout], [experr])
AT_CLEANUP