Handle packet access reject during EPDAN/PDAN with channel description
When PDAN/EPDAN with channel description is received, PCU will generate the packet access reject if no resources are present. The encoding is done based on section 7.1.3.2.1 and 8.1.2.5 of 44.060 version 7.27.0 Release 7. This patch also includes the test case to validate the generated packet access reject message. This patch is integration tested on Osmo-trx setup with Ettus B210 board and LG F70 MS with some simulation code changes in Osmo-pcu. Change-Id: I096a3bb44a65533b9e9b091925dd5f70a8696d6
This commit is contained in:
parent
c0c3afd079
commit
ed3413e397
34
src/bts.cpp
34
src/bts.cpp
|
@ -1077,16 +1077,23 @@ void gprs_rlcmac_pdch::rcv_control_dl_ack_nack(Packet_Downlink_Ack_Nack_t *ack_n
|
|||
}
|
||||
/* check for channel request */
|
||||
if (ack_nack->Exist_Channel_Request_Description) {
|
||||
LOGP(DRLCMAC, LOGL_DEBUG, "MS requests UL TBF in ack "
|
||||
"message, so we provide one:\n");
|
||||
|
||||
/* This call will register the new TBF with the MS on success */
|
||||
tbf_alloc_ul(bts_data(), tbf->trx->trx_no,
|
||||
gprs_rlcmac_ul_tbf *ul_tbf = tbf_alloc_ul(bts_data(),
|
||||
tbf->trx->trx_no,
|
||||
tbf->ms_class(), tbf->ms()->egprs_ms_class(),
|
||||
tbf->tlli(), tbf->ta(), tbf->ms());
|
||||
|
||||
/* schedule uplink assignment */
|
||||
tbf->ul_ass_state = GPRS_RLCMAC_UL_ASS_SEND_ASS;
|
||||
/* schedule uplink assignment or reject*/
|
||||
if (ul_tbf) {
|
||||
LOGP(DRLCMAC, LOGL_DEBUG, "MS requests UL TBF in ack "
|
||||
"message, so we provide one:\n");
|
||||
tbf->ul_ass_state = GPRS_RLCMAC_UL_ASS_SEND_ASS;
|
||||
} else {
|
||||
LOGP(DRLCMAC, LOGL_DEBUG, "MS requests UL TBF in ack "
|
||||
"message, so we pacekt access reject:\n");
|
||||
tbf->ul_ass_state = GPRS_RLCMAC_UL_ASS_SEND_ASS_REJ;
|
||||
}
|
||||
}
|
||||
/* get measurements */
|
||||
if (tbf->ms()) {
|
||||
|
@ -1179,16 +1186,23 @@ void gprs_rlcmac_pdch::rcv_control_egprs_dl_ack_nack(EGPRS_PD_AckNack_t *ack_nac
|
|||
|
||||
/* check for channel request */
|
||||
if (ack_nack->Exist_ChannelRequestDescription) {
|
||||
LOGP(DRLCMAC, LOGL_DEBUG, "MS requests UL TBF in ack "
|
||||
"message, so we provide one:\n");
|
||||
|
||||
/* This call will register the new TBF with the MS on success */
|
||||
tbf_alloc_ul(bts_data(), tbf->trx->trx_no,
|
||||
gprs_rlcmac_ul_tbf *ul_tbf = tbf_alloc_ul(bts_data(),
|
||||
tbf->trx->trx_no,
|
||||
tbf->ms_class(), tbf->ms()->egprs_ms_class(),
|
||||
tbf->tlli(), tbf->ta(), tbf->ms());
|
||||
|
||||
/* schedule uplink assignment */
|
||||
tbf->ul_ass_state = GPRS_RLCMAC_UL_ASS_SEND_ASS;
|
||||
/* schedule uplink assignment or reject*/
|
||||
if (ul_tbf) {
|
||||
LOGP(DRLCMAC, LOGL_DEBUG, "MS requests UL TBF in ack "
|
||||
"message, so we provide one:\n");
|
||||
tbf->ul_ass_state = GPRS_RLCMAC_UL_ASS_SEND_ASS;
|
||||
} else {
|
||||
LOGP(DRLCMAC, LOGL_DEBUG, "MS requests UL TBF in ack "
|
||||
"message, so we send packet access reject:\n");
|
||||
tbf->ul_ass_state = GPRS_RLCMAC_UL_ASS_SEND_ASS_REJ;
|
||||
}
|
||||
}
|
||||
|
||||
/* get measurements */
|
||||
|
|
|
@ -1391,3 +1391,28 @@ Encoding::AppendResult Encoding::rlc_data_to_dl_append(
|
|||
|
||||
return AR_NEED_MORE_BLOCKS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Refer 44.060 version 7.27.0 Release 7
|
||||
* section 7.1.3.2.1 On receipt of a PACKET RESOURCE REQUEST message
|
||||
* 8.1.2.5 Establishment of uplink TBF
|
||||
*/
|
||||
void Encoding::write_packet_access_reject(
|
||||
bitvec * dest, uint32_t tlli)
|
||||
{
|
||||
unsigned wp = 0;
|
||||
|
||||
bitvec_write_field(dest, wp, 0x1, 2); // Payload Type
|
||||
bitvec_write_field(dest, wp, 0x0, 2); // Uplink block with TDMA FN
|
||||
bitvec_write_field(dest, wp, 0, 1); // No Polling Bit
|
||||
bitvec_write_field(dest, wp, 0x0, 3); // Uplink state flag
|
||||
bitvec_write_field(dest, wp,
|
||||
MT_PACKET_ACCESS_REJECT, 6); // MESSAGE TYPE
|
||||
bitvec_write_field(dest, wp, 0, 2); // fixed 00
|
||||
bitvec_write_field(dest, wp, 0x0, 1); // TLLI / G-RNTI : bit (32)
|
||||
bitvec_write_field(dest, wp, tlli, 32); // CONTENTION_RESOLUTION_TLLI
|
||||
bitvec_write_field(dest, wp, 1, 1); // WAIT_INDICATION size in seconds
|
||||
/* TODO: make it configurable */
|
||||
bitvec_write_field(dest, wp, 5, 8); // WAIT_INDICATION value
|
||||
bitvec_write_field(dest, wp, 0, 1); // WAIT_INDICATION size in seconds
|
||||
}
|
||||
|
|
|
@ -74,6 +74,9 @@ public:
|
|||
|
||||
static void encode_rbb(const char *show_rbb, uint8_t *rbb);
|
||||
|
||||
static void write_packet_access_reject(
|
||||
bitvec * dest, uint32_t tlli);
|
||||
|
||||
static void write_packet_uplink_ack(
|
||||
struct gprs_rlcmac_bts *bts, bitvec * dest,
|
||||
struct gprs_rlcmac_ul_tbf *tbf, bool is_final,
|
||||
|
|
|
@ -72,7 +72,8 @@ static uint32_t sched_poll(BTS *bts,
|
|||
*poll_tbf = dl_tbf;
|
||||
if (dl_tbf->dl_ass_state == GPRS_RLCMAC_DL_ASS_SEND_ASS)
|
||||
*dl_ass_tbf = dl_tbf;
|
||||
if (dl_tbf->ul_ass_state == GPRS_RLCMAC_UL_ASS_SEND_ASS)
|
||||
if (dl_tbf->ul_ass_state == GPRS_RLCMAC_UL_ASS_SEND_ASS
|
||||
|| dl_tbf->ul_ass_state == GPRS_RLCMAC_UL_ASS_SEND_ASS_REJ)
|
||||
*ul_ass_tbf = dl_tbf;
|
||||
}
|
||||
|
||||
|
@ -137,7 +138,11 @@ static struct msgb *sched_select_ctrl_msg(
|
|||
*/
|
||||
|
||||
if (tbf == ul_ass_tbf && tbf->direction == GPRS_RLCMAC_DL_TBF)
|
||||
msg = ul_ass_tbf->create_ul_ass(fn, ts);
|
||||
if (tbf->ul_ass_state ==
|
||||
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)
|
||||
|
|
23
src/tbf.cpp
23
src/tbf.cpp
|
@ -1013,6 +1013,29 @@ struct msgb *gprs_rlcmac_tbf::create_dl_ass(uint32_t fn, uint8_t ts)
|
|||
return msg;
|
||||
}
|
||||
|
||||
struct msgb *gprs_rlcmac_tbf::create_packet_access_reject()
|
||||
{
|
||||
struct msgb *msg;
|
||||
|
||||
msg = msgb_alloc(23, "rlcmac_ul_ass_rej");
|
||||
|
||||
bitvec *packet_access_rej = bitvec_alloc(23);
|
||||
|
||||
bitvec_unhex(packet_access_rej,
|
||||
"2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b");
|
||||
|
||||
Encoding::write_packet_access_reject(
|
||||
packet_access_rej, tlli());
|
||||
|
||||
bitvec_pack(packet_access_rej, msgb_put(msg, 23));
|
||||
|
||||
bitvec_free(packet_access_rej);
|
||||
ul_ass_state = GPRS_RLCMAC_UL_ASS_NONE;
|
||||
|
||||
return msg;
|
||||
|
||||
}
|
||||
|
||||
struct msgb *gprs_rlcmac_tbf::create_ul_ass(uint32_t fn, uint8_t ts)
|
||||
{
|
||||
struct msgb *msg;
|
||||
|
|
|
@ -64,6 +64,7 @@ enum gprs_rlcmac_tbf_dl_ass_state {
|
|||
enum gprs_rlcmac_tbf_ul_ass_state {
|
||||
GPRS_RLCMAC_UL_ASS_NONE = 0,
|
||||
GPRS_RLCMAC_UL_ASS_SEND_ASS, /* send uplink assignment on next RTS */
|
||||
GPRS_RLCMAC_UL_ASS_SEND_ASS_REJ, /* send assignment reject next RTS */
|
||||
GPRS_RLCMAC_UL_ASS_WAIT_ACK, /* wait for PACKET CONTROL ACK */
|
||||
};
|
||||
|
||||
|
@ -103,6 +104,7 @@ struct gprs_rlcmac_tbf {
|
|||
|
||||
struct msgb *create_dl_ass(uint32_t fn, uint8_t ts);
|
||||
struct msgb *create_ul_ass(uint32_t fn, uint8_t ts);
|
||||
struct msgb *create_packet_access_reject();
|
||||
|
||||
GprsMs *ms() const;
|
||||
void set_ms(GprsMs *ms);
|
||||
|
|
|
@ -2831,6 +2831,29 @@ const struct log_info debug_log_info = {
|
|||
ARRAY_SIZE(default_categories),
|
||||
};
|
||||
|
||||
void test_packet_access_rej_epdan()
|
||||
{
|
||||
BTS the_bts;
|
||||
uint32_t tlli = 0xffeeddcc;
|
||||
|
||||
printf("=== start %s ===\n", __func__);
|
||||
setup_bts(&the_bts, 4);
|
||||
static gprs_rlcmac_dl_tbf *dl_tbf = tbf_init(&the_bts, 1);
|
||||
|
||||
dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
|
||||
|
||||
struct msgb *msg = dl_tbf->create_packet_access_reject();
|
||||
|
||||
printf("packet reject: %s\n",
|
||||
osmo_hexdump(msg->data, 23));
|
||||
|
||||
OSMO_ASSERT(!strcmp(osmo_hexdump(msg->data, 23),
|
||||
"40 84 7f f7 6e e6 41 4b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b "));
|
||||
printf("=== end %s ===\n", __func__);
|
||||
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct vty_app_info pcu_vty_info = {0};
|
||||
|
@ -2874,6 +2897,7 @@ int main(int argc, char **argv)
|
|||
test_tbf_li_decoding();
|
||||
test_tbf_epdan_out_of_rx_window();
|
||||
test_immediate_assign_rej();
|
||||
test_packet_access_rej_epdan();
|
||||
|
||||
if (getenv("TALLOC_REPORT_FULL"))
|
||||
talloc_report_full(tall_pcu_ctx, stderr);
|
||||
|
|
|
@ -6846,3 +6846,27 @@ MS requests single block allocation
|
|||
No PDCH available.
|
||||
No PDCH resource for single block allocation.sending Immediate Assignment Uplink (AGCH) reject
|
||||
Sending data request: trx=0 ts=0 sapi=2 arfcn=0 fn=0 block=0 data=4d 06 3a 10 70 8b 29 14 70 8b 29 14 70 8b 29 14 70 8b 29 14 0b 2b 2b
|
||||
Searching for first unallocated TFI: TRX=0
|
||||
Found TFI=0.
|
||||
********** TBF starts here **********
|
||||
Allocating DL TBF: MS_CLASS=11/11
|
||||
Creating MS object, TLLI = 0x00000000
|
||||
Modifying MS object, TLLI = 0x00000000, MS class 0 -> 11
|
||||
Modifying MS object, TLLI = 0x00000000, EGPRS MS class 0 -> 11
|
||||
Slot Allocation (Algorithm A) for class 11
|
||||
- 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 5, because not enabled
|
||||
- Skipping TS 6, because not enabled
|
||||
- Skipping TS 7, because not enabled
|
||||
- Assign downlink TS=4 TFI=0
|
||||
PDCH(TS 4, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL), 1 TBFs, USFs = 00, TFIs = 00000001.
|
||||
- Setting Control TS 4
|
||||
Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL)
|
||||
Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL): trx = 0, ul_slots = 10, dl_slots = 10
|
||||
Modifying MS object, TLLI = 0x00000000, TA 220 -> 0
|
||||
TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL) changes state from NULL to FLOW
|
||||
The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed
|
||||
TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) append
|
||||
|
|
|
@ -72,3 +72,6 @@ Testing retx for MCS 6 to reseg_mcs 3
|
|||
=== end test_immediate_assign_rej_multi_block ===
|
||||
=== start test_immediate_assign_rej_single_block ===
|
||||
=== end test_immediate_assign_rej_single_block ===
|
||||
=== start test_packet_access_rej_epdan ===
|
||||
packet reject: 40 84 7f f7 6e e6 41 4b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b
|
||||
=== end test_packet_access_rej_epdan ===
|
||||
|
|
Loading…
Reference in New Issue