diff options
-rw-r--r-- | src/bts.cpp | 34 | ||||
-rw-r--r-- | src/encoding.cpp | 25 | ||||
-rw-r--r-- | src/encoding.h | 3 | ||||
-rw-r--r-- | src/gprs_rlcmac_sched.cpp | 9 | ||||
-rw-r--r-- | src/tbf.cpp | 23 | ||||
-rw-r--r-- | src/tbf.h | 2 | ||||
-rw-r--r-- | tests/tbf/TbfTest.cpp | 24 | ||||
-rw-r--r-- | tests/tbf/TbfTest.err | 24 | ||||
-rw-r--r-- | tests/tbf/TbfTest.ok | 3 |
9 files changed, 135 insertions, 12 deletions
diff --git a/src/bts.cpp b/src/bts.cpp index 4e6b5e9..0668c2d 100644 --- a/src/bts.cpp +++ b/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 */ diff --git a/src/encoding.cpp b/src/encoding.cpp index ca72b0f..e5a8605 100644 --- a/src/encoding.cpp +++ b/src/encoding.cpp @@ -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 +} diff --git a/src/encoding.h b/src/encoding.h index 79dc32d..6164b89 100644 --- a/src/encoding.h +++ b/src/encoding.h @@ -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, diff --git a/src/gprs_rlcmac_sched.cpp b/src/gprs_rlcmac_sched.cpp index f486075..a3723df 100644 --- a/src/gprs_rlcmac_sched.cpp +++ b/src/gprs_rlcmac_sched.cpp @@ -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) diff --git a/src/tbf.cpp b/src/tbf.cpp index 0ac8ace..2d82727 100644 --- a/src/tbf.cpp +++ b/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); diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp index 339390b..213bd12 100644 --- a/tests/tbf/TbfTest.cpp +++ b/tests/tbf/TbfTest.cpp @@ -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); diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index 627cdc3..a680812 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -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 diff --git a/tests/tbf/TbfTest.ok b/tests/tbf/TbfTest.ok index f921dfc..dc07fc7 100644 --- a/tests/tbf/TbfTest.ok +++ b/tests/tbf/TbfTest.ok @@ -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 === |