aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/bts.cpp6
-rw-r--r--tests/tbf/TbfTest.cpp142
-rw-r--r--tests/tbf/TbfTest.err96
-rw-r--r--tests/tbf/TbfTest.ok4
4 files changed, 246 insertions, 2 deletions
diff --git a/src/bts.cpp b/src/bts.cpp
index c7daf8e..6bcfea0 100644
--- a/src/bts.cpp
+++ b/src/bts.cpp
@@ -416,8 +416,10 @@ int BTS::rcv_rach(uint8_t ra, uint32_t Fn, int16_t qta)
if (rc < 0)
return rc;
LOGP(DRLCMAC, LOGL_DEBUG, "RX: [PCU <- BTS] RACH qbit-ta=%d "
- "ra=0x%02x, Fn=%d (%d,%d,%d)\n", qta, ra, Fn,
- (Fn / (26 * 51)) % 32, Fn % 51, Fn % 26);
+ "ra=0x%02x, Fn=%d (%d,%d,%d), SBFn=%d\n",
+ qta, ra,
+ Fn, (Fn / (26 * 51)) % 32, Fn % 51, Fn % 26,
+ sb_fn);
LOGP(DRLCMAC, LOGL_INFO, "TX: Immediate Assignment Uplink "
"(AGCH)\n");
} else {
diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp
index 84ecb97..e25f344 100644
--- a/tests/tbf/TbfTest.cpp
+++ b/tests/tbf/TbfTest.cpp
@@ -25,6 +25,7 @@
#include "gprs_debug.h"
#include "pcu_utils.h"
#include "gprs_bssgp_pcu.h"
+#include "pcu_l1_if.h"
extern "C" {
#include "pcu_vty.h"
@@ -46,6 +47,20 @@ static void check_tbf(gprs_rlcmac_tbf *tbf)
OSMO_ASSERT(tbf);
}
+/*
+static unsigned inc_fn(fn)
+{
+ unsigned next_fn;
+
+ next_fn = fn + 4;
+ if ((block_nr % 3) == 2)
+ next_fn ++;
+ next_fn = next_fn % 2715648;
+
+ return next_fn;
+}
+*/
+
static void test_tbf_tlli_update()
{
BTS the_bts;
@@ -401,6 +416,131 @@ static void test_tbf_exhaustion()
gprs_bssgp_destroy();
}
+static void test_tbf_single_phase()
+{
+ BTS the_bts;
+ GprsMs *ms;
+ int ts_no = 7;
+ uint32_t fn = 2654167; /* 17,25,9 */
+ uint16_t qta = 31;
+ uint8_t trx_no = 0;
+ int tfi = 0;
+ gprs_rlcmac_ul_tbf *ul_tbf;
+ struct gprs_rlcmac_pdch *pdch;
+
+ printf("=== start %s ===\n", __func__);
+
+ setup_bts(&the_bts, ts_no);
+ tfi = the_bts.tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
+
+ the_bts.rcv_rach(0x03, fn, qta);
+
+ ul_tbf = the_bts.ul_tbf_by_tfi(tfi, trx_no);
+ OSMO_ASSERT(ul_tbf != NULL);
+
+ fprintf(stderr, "Got '%s', TA=%d\n",
+ ul_tbf->name(), ul_tbf->ta);
+
+ OSMO_ASSERT(ul_tbf->ta == qta / 4);
+
+ uint8_t data_msg[23] = {
+ 0x00, /* GPRS_RLCMAC_DATA_BLOCK << 6 */
+ uint8_t(1 | (tfi << 2)),
+ uint8_t(1), /* BSN:7, E:1 */
+ 0xf1, 0x22, 0x33, 0x44, /* TLLI */
+ };
+
+ pdch = &the_bts.bts_data()->trx[trx_no].pdch[ts_no];
+ pdch->rcv_block(&data_msg[0], sizeof(data_msg), fn, 0);
+
+ ms = the_bts.ms_by_tlli(0xf1223344);
+ OSMO_ASSERT(ms != NULL);
+ fprintf(stderr, "Got MS: TLLI = 0x%08x\n", ms->tlli());
+
+ printf("=== end %s ===\n", __func__);
+}
+
+static void test_tbf_two_phase()
+{
+ BTS the_bts;
+ GprsMs *ms;
+ int ts_no = 7;
+ uint32_t rach_fn = 2654167; /* 17,25,9 */
+ uint32_t rts_fn = 2654218;
+ uint8_t rts_bn = 8;
+ uint16_t qta = 31;
+ uint8_t trx_no = 0;
+ int tfi = 0;
+ const uint32_t tlli = 0xf1223344;
+ gprs_rlcmac_ul_tbf *ul_tbf;
+ struct gprs_rlcmac_pdch *pdch;
+ gprs_rlcmac_bts *bts;
+ RlcMacUplink_t ulreq = {0};
+ bitvec *rlc_block;
+ uint8_t buf[64];
+ int num_bytes;
+
+ printf("=== start %s ===\n", __func__);
+
+ setup_bts(&the_bts, ts_no);
+ bts = the_bts.bts_data();
+
+ /* needed to set last_rts_fn in the PDCH object */
+ send_rlc_block(bts, trx_no, ts_no, 0, &rts_fn, &rts_bn);
+
+ /* simulate RACH, this sends an Immediate Assignment Uplink on the AGCH */
+ the_bts.rcv_rach(0x73, rach_fn, qta);
+
+ /* get next free TFI */
+ tfi = the_bts.tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
+
+ /* fake a resource request */
+ rlc_block = bitvec_alloc(23);
+
+ ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
+ ulreq.u.Packet_Resource_Request.PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
+ ulreq.u.Packet_Resource_Request.ID.UnionType = 1; /* != 0 */
+ ulreq.u.Packet_Resource_Request.ID.u.TLLI = tlli;
+
+ encode_gsm_rlcmac_uplink(rlc_block, &ulreq);
+ num_bytes = bitvec_pack(rlc_block, &buf[0]);
+ OSMO_ASSERT(size_t(num_bytes) < sizeof(buf));
+ bitvec_free(rlc_block);
+
+ pdch = &the_bts.bts_data()->trx[trx_no].pdch[ts_no];
+ pdch->rcv_block(&buf[0], num_bytes, 2654270, 31);
+
+ /* check the TBF */
+ ul_tbf = the_bts.ul_tbf_by_tfi(tfi, trx_no);
+ OSMO_ASSERT(ul_tbf != NULL);
+
+ fprintf(stderr, "Got '%s', TA=%d\n",
+ ul_tbf->name(), ul_tbf->ta);
+
+ OSMO_ASSERT(ul_tbf->ta == qta / 4);
+
+ /* send packet uplink assignment */
+ rts_fn += 52;
+ rts_bn += 12;
+ send_rlc_block(bts, trx_no, ts_no, 0, &rts_fn, &rts_bn);
+
+ /* send fake data */
+ uint8_t data_msg[23] = {
+ 0x00, /* GPRS_RLCMAC_DATA_BLOCK << 6 */
+ uint8_t(0 | (tfi << 2)),
+ uint8_t(1), /* BSN:7, E:1 */
+ };
+
+ pdch->rcv_block(&data_msg[0], sizeof(data_msg), rts_fn, 31);
+
+ ms = the_bts.ms_by_tlli(0xf1223344);
+ OSMO_ASSERT(ms != NULL);
+ fprintf(stderr, "Got MS: TLLI = 0x%08x\n", ms->tlli());
+
+ printf("=== end %s ===\n", __func__);
+}
+
+
static const struct log_info_cat default_categories[] = {
{"DCSN1", "\033[1;31m", "Concrete Syntax Notation One (CSN1)", LOGL_INFO, 0},
{"DL1IF", "\033[1;32m", "GPRS PCU L1 interface (L1IF)", LOGL_DEBUG, 1},
@@ -449,6 +589,8 @@ int main(int argc, char **argv)
test_tbf_delayed_release();
test_tbf_imsi();
test_tbf_exhaustion();
+ test_tbf_single_phase();
+ test_tbf_two_phase();
if (getenv("TALLOC_REPORT_FULL"))
talloc_report_full(tall_pcu_ctx, stderr);
diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err
index 03921c5..20b1a72 100644
--- a/tests/tbf/TbfTest.err
+++ b/tests/tbf/TbfTest.err
@@ -1102,3 +1102,99 @@ Searching for first unallocated TFI: TRX=0 first TS=4
No TFI available.
No PDCH resource
BSSGP (BVCI=1234) Tx LLC-DISCARDED TLLI=0xc0000020, FRAMES=1, OCTETS=256
+Searching for first unallocated TFI: TRX=0 first TS=7
+ Found TFI=0.
+MS requests UL TBF on RACH, so we provide one:
+Searching for first unallocated TFI: TRX=0 first TS=7
+ Found TFI=0.
+********** TBF starts here **********
+Allocating UL TBF: TFI=0 TRX=0 MS_CLASS=0
+Slot Allocation (Algorithm A) for class 0
+- Skipping TS 0, because not enabled
+- Skipping TS 1, because not enabled
+- Skipping TS 2, because not enabled
+- Skipping TS 3, because not enabled
+- Skipping TS 4, because not enabled
+- Skipping TS 5, because not enabled
+- Skipping TS 6, because not enabled
+- Assign uplink TS=7 USF=0
+- Setting Control TS 7
+TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL) changes state from NULL to FLOW
+TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=FLOW) starting timer 3169.
+TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=FLOW) [UPLINK] START
+TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=FLOW) RX: [PCU <- BTS] RACH qbit-ta=31 ra=0x03, Fn=2654167 (17,25,9)
+TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=FLOW) TX: START Immediate Assignment Uplink (AGCH)
+Sending data request: trx=0 ts=0 sapi=2 arfcn=0 fn=0 block=0 data=2d 06 3f 10 0f 00 00 03 8b 29 07 00 c8 00 70 0b 2b 2b 2b 2b 2b 2b 2b
+Got 'TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=FLOW)', TA=7
+UL DATA TFI=0 received (V(Q)=0 .. V(R)=0)
+Creating MS object, TLLI = 0x00000000
+Modifying MS object, UL TLLI: 0x00000000 -> 0xf1223344, not yet confirmed
+Attaching TBF to MS object, TLLI = 0xf1223344, TBF = TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW)
+Decoded premier TLLI=0xf1223344 of UL DATA TFI=0.
+TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW) restarting timer 3169 while old timer 3169 pending
+- BSN 0 storing in window (0..63)
+- Raising V(R) to 1
+- Taking block 0 out, raising V(Q) to 1
+- Assembling frames: (len=23)
+-- Frame 1 starts at offset 0
+- Data length after length fields: 20
+- Length after skipping TLLI: 16
+TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW) complete UL frame that fits precisely in last block: len=16
+LLC [PCU -> SGSN] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW) len=16
+No bctx
+- No gaps in received block, last block: BSN=0 CV=0
+- Finished with UL TBF
+TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW) changes state from FLOW to FINISHED
+- Scheduling Ack/Nack, because TLLI is included.
+- Scheduling Ack/Nack, because last block has CV==0.
+Got MS: TLLI = 0xf1223344
+Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654218 block=8 data=47 94 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b
+MS requests UL TBF on RACH, so we provide one:
+MS requests single block allocation
+RX: [PCU <- BTS] RACH qbit-ta=31 ra=0x73, Fn=2654167 (17,25,9), SBFn=2654270
+TX: Immediate Assignment Uplink (AGCH)
+Sending data request: trx=0 ts=0 sapi=2 arfcn=0 fn=0 block=0 data=2d 06 3f 10 0f 00 00 73 8b 29 07 00 c0 0c 5a 43 2b 2b 2b 2b 2b 2b 2b
+Searching for first unallocated TFI: TRX=0 first TS=7
+ Found TFI=0.
++++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++
+------------------------- RX : Uplink Control Block -------------------------
+MS requests UL TBF in packet resource request of single block, so we provide one:
+MS does not give us a class.
+Searching for first unallocated TFI: TRX=0 first TS=7
+ Found TFI=0.
+********** TBF starts here **********
+Allocating UL TBF: TFI=0 TRX=0 MS_CLASS=0
+Slot Allocation (Algorithm A) for class 0
+- Skipping TS 0, because not enabled
+- Skipping TS 1, because not enabled
+- Skipping TS 2, because not enabled
+- Skipping TS 3, because not enabled
+- Skipping TS 4, because not enabled
+- Skipping TS 5, because not enabled
+- Skipping TS 6, because not enabled
+- Assign uplink TS=7 USF=0
+- Setting Control TS 7
+TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL) changes state from NULL to ASSIGN
+TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=ASSIGN) starting timer 3169.
+Creating MS object, TLLI = 0x00000000
+Modifying MS object, UL TLLI: 0x00000000 -> 0xf1223344, not yet confirmed
+Attaching TBF to MS object, TLLI = 0xf1223344, TBF = TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN)
+Change control TS to 7 until assinment is complete.
+Got 'TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN)', TA=7
+TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN)s start Packet Uplink Assignment (PACCH)
++++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++
+------------------------- TX : Packet Uplink Assignment -------------------------
+Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) (TRX=0, TS=7)
+Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654275 block=21 data=4f 28 5e 24 46 68 8f 1d 00 00 88 00 08 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b
+UL DATA TFI=0 received (V(Q)=0 .. V(R)=0)
+TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) restarting timer 3169 while old timer 3169 pending
+- BSN 0 storing in window (0..63)
+- Raising V(R) to 1
+- Taking block 0 out, raising V(Q) to 1
+- Assembling frames: (len=23)
+-- Frame 1 starts at offset 0
+- Data length after length fields: 20
+TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) complete UL frame that fits precisely in last block: len=20
+LLC [PCU -> SGSN] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) len=20
+No bctx
+Got MS: TLLI = 0xf1223344
diff --git a/tests/tbf/TbfTest.ok b/tests/tbf/TbfTest.ok
index 984e735..831a3dd 100644
--- a/tests/tbf/TbfTest.ok
+++ b/tests/tbf/TbfTest.ok
@@ -4,3 +4,7 @@
=== end test_tbf_imsi ===
=== start test_tbf_exhaustion ===
=== end test_tbf_exhaustion ===
+=== start test_tbf_single_phase ===
+=== end test_tbf_single_phase ===
+=== start test_tbf_two_phase ===
+=== end test_tbf_two_phase ===