aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax <msuraev@sysmocom.de>2016-02-11 13:57:46 +0100
committerMax <msuraev@sysmocom.de>2016-02-11 13:57:46 +0100
commitd28403cfebee4196b6f757846acd6a656b68cdc6 (patch)
tree47cc70818f5e7849f096081328cf451157eee2da
parent7f28c97fcc87d2ce773a2ae91579a84b40d12539 (diff)
P.TS.R. WIP
Signed-off-by: Max <msuraev@sysmocom.de>
-rw-r--r--src/bts.cpp21
-rw-r--r--src/bts.h1
-rw-r--r--src/encoding.cpp229
-rw-r--r--src/encoding.h4
-rw-r--r--src/gprs_rlcmac_sched.cpp6
-rw-r--r--src/gprs_rlcmac_ts_alloc.cpp6
-rw-r--r--src/gsm_rlcmac.cpp2
-rw-r--r--src/tbf.cpp56
-rw-r--r--src/tbf.h6
9 files changed, 320 insertions, 11 deletions
diff --git a/src/bts.cpp b/src/bts.cpp
index 715fb51..4f4a086 100644
--- a/src/bts.cpp
+++ b/src/bts.cpp
@@ -196,13 +196,13 @@ void BTS::set_current_block_frame_number(int fn, unsigned max_delay)
if (current_frame_number() != 0)
delay = (fn + 2715648 * 3 / 2 - current_frame_number()) % 2715648
- 2715648/2;
- if (delay <= -late_block_delay_thresh) {
+/* if (delay <= -late_block_delay_thresh) {
LOGP(DRLCMAC, LOGL_NOTICE,
"Late RLC block, FN delta: %d FN: %d curFN: %d\n",
delay, fn, current_frame_number());
rlc_late_block();
}
-
+FIXME - enable back before committing*/
m_cur_blk_fn = fn;
if (delay < fn_update_ok_min_delay || delay > fn_update_ok_max_delay ||
current_frame_number() == 0)
@@ -555,6 +555,20 @@ int BTS::rcv_rach(uint8_t ra, uint32_t Fn, int16_t qta)
return 0;
}
+void BTS::trigger_dl_ts_recon(gprs_rlcmac_dl_tbf *dl_tbf)//FIXME: no actual sending, just schedule trigger via state change
+{
+ /* stop pending timer */
+ dl_tbf->stop_timer();
+
+ LOGP(DRLCMAC, LOGL_DEBUG, "Send TS RECONFIGURE for %s on PCH (IMSI=%s)\n", tbf_name(dl_tbf), dl_tbf->imsi());
+
+ /* change state */
+ dl_tbf->set_state(GPRS_RLCMAC_RECONFIGURING); // FIXME - more flags?
+
+ /* "send" PACKET TS RECON. */
+ dl_tbf->m_wait_confirm = 1; // FIXME - do we have to wait for ACK from phone?
+}
+
/* depending on the current TBF, we assign on PACCH or AGCH */
void BTS::trigger_dl_ass(
struct gprs_rlcmac_dl_tbf *dl_tbf,
@@ -577,6 +591,9 @@ void BTS::trigger_dl_ass(
dl_tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_PACCH);
/* start timer */
tbf_timer_start(dl_tbf, 0, Tassign_pacch);
+
+ // actual assignment creation happens in the scheduler code
+
} else {
LOGP(DRLCMAC, LOGL_DEBUG, "Send dowlink assignment for %s on PCH, no TBF exist (IMSI=%s)\n", tbf_name(dl_tbf), dl_tbf->imsi());
dl_tbf->was_releasing = dl_tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE);
diff --git a/src/bts.h b/src/bts.h
index 119f6b2..6eddf66 100644
--- a/src/bts.h
+++ b/src/bts.h
@@ -276,6 +276,7 @@ public:
int rcv_rach(uint8_t ra, uint32_t Fn, int16_t qta);
void trigger_dl_ass(gprs_rlcmac_dl_tbf *tbf, gprs_rlcmac_tbf *old_tbf);
+ void trigger_dl_ts_recon(gprs_rlcmac_dl_tbf *tbf);
void snd_dl_ass(gprs_rlcmac_tbf *tbf, uint8_t poll, const char *imsi);
GprsMsStorage &ms_store();
diff --git a/src/encoding.cpp b/src/encoding.cpp
index 6c50abe..06ba337 100644
--- a/src/encoding.cpp
+++ b/src/encoding.cpp
@@ -333,7 +333,236 @@ void Encoding::write_packet_uplink_assignment(
// bitvec_write_field(dest, wp,0x0,1); // Measurement Mapping struct not present
}
+/*
+CSN_DESCR_BEGIN(Packet_Timeslot_Reconfigure_t)
+ M_UINT (Packet_Timeslot_Reconfigure_t, MESSAGE_TYPE, 6),
+ M_UINT (Packet_Timeslot_Reconfigure_t, PAGE_MODE, 2),
+
+ M_FIXED (Packet_Timeslot_Reconfigure_t, 1, 0x00),
+ M_TYPE (Packet_Timeslot_Reconfigure_t, Global_TFI, Global_TFI_t),
+
+ M_UNION (Packet_Timeslot_Reconfigure_t, 2),
+ M_TYPE (Packet_Timeslot_Reconfigure_t, u.PTR_GPRS_Struct, PTR_GPRS_t),
+ M_TYPE (Packet_Timeslot_Reconfigure_t, u.PTR_EGPRS_Struct, PTR_EGPRS_t),
+
+ M_PADDING_BITS(Packet_Timeslot_Reconfigure_t),
+CSN_DESCR_END (Packet_Timeslot_Reconfigure_t)
+
+CSN_DESCR_BEGIN (PTR_GPRS_t)
+ M_UINT (PTR_GPRS_t, CHANNEL_CODING_COMMAND, 2),
+ M_TYPE (PTR_GPRS_t, Common_Timeslot_Reconfigure_Data.Global_Packet_Timing_Advance, Global_Packet_Timing_Advance_t),
+ M_UINT (PTR_GPRS_t, Common_Timeslot_Reconfigure_Data.DOWNLINK_RLC_MODE, 1),
+ M_UINT (PTR_GPRS_t, Common_Timeslot_Reconfigure_Data.CONTROL_ACK, 1),
+
+ M_NEXT_EXIST (PTR_GPRS_t, Common_Timeslot_Reconfigure_Data.Exist_DOWNLINK_TFI_ASSIGNMENT, 1),
+ M_UINT (PTR_GPRS_t, Common_Timeslot_Reconfigure_Data.DOWNLINK_TFI_ASSIGNMENT, 5),
+
+ M_NEXT_EXIST (PTR_GPRS_t, Common_Timeslot_Reconfigure_Data.Exist_UPLINK_TFI_ASSIGNMENT, 1),
+ M_UINT (PTR_GPRS_t, Common_Timeslot_Reconfigure_Data.UPLINK_TFI_ASSIGNMENT, 5),
+
+ M_UINT (PTR_GPRS_t, Common_Timeslot_Reconfigure_Data.DOWNLINK_TIMESLOT_ALLOCATION, 8),
+
+ M_NEXT_EXIST (PTR_GPRS_t, Common_Timeslot_Reconfigure_Data.Exist_Frequency_Parameters, 1),
+ M_TYPE (PTR_GPRS_t, Common_Timeslot_Reconfigure_Data.Frequency_Parameters, Frequency_Parameters_t),
+
+ M_UNION (PTR_GPRS_t, 2),
+ M_TYPE (PTR_GPRS_t, u.Dynamic_Allocation, TRDynamic_Allocation_t),
+ CSN_ERROR (PTR_GPRS_t, "1 - Fixed Allocation was removed", CSN_ERROR_STREAM_NOT_SUPPORTED),
+
+ M_NEXT_EXIST_OR_NULL(PTR_GPRS_t, Exist_AdditionsR99, 1),
+ M_TYPE (PTR_GPRS_t, AdditionsR99, PTR_GPRS_AdditionsR99_t),
+CSN_DESCR_END (PTR_GPRS_t)
+
+CSN_DESCR_BEGIN(PTR_EGPRS_t)
+ M_UNION (PTR_EGPRS_t, 4),
+ M_TYPE (PTR_EGPRS_t, u.PTR_EGPRS_00, PTR_EGPRS_00_t), // COMPACT reduced MA, sub-clause 12.29
+ CSN_ERROR (PTR_EGPRS_t, "01 <PTR_EGPRS>", CSN_ERROR_STREAM_NOT_SUPPORTED),
+ CSN_ERROR (PTR_EGPRS_t, "10 <PTR_EGPRS>", CSN_ERROR_STREAM_NOT_SUPPORTED),
+ CSN_ERROR (PTR_EGPRS_t, "11 <PTR_EGPRS>", CSN_ERROR_STREAM_NOT_SUPPORTED),
+CSN_DESCR_END (PTR_EGPRS_t)
+
+CSN_DESCR_BEGIN(PTR_EGPRS_00_t)
+ M_NEXT_EXIST (PTR_EGPRS_00_t, Exist_COMPACT_ReducedMA, 1),
+ M_TYPE (PTR_EGPRS_00_t, COMPACT_ReducedMA, COMPACT_ReducedMA_t),
+
+ M_UINT (PTR_EGPRS_00_t, EGPRS_ChannelCodingCommand, 4),
+ M_UINT (PTR_EGPRS_00_t, RESEGMENT, 1),
+
+ M_NEXT_EXIST (PTR_EGPRS_00_t, Exist_DOWNLINK_EGPRS_WindowSize, 1),
+ M_UINT (PTR_EGPRS_00_t, DOWNLINK_EGPRS_WindowSize, 5),
+
+ M_NEXT_EXIST (PTR_EGPRS_00_t, Exist_UPLINK_EGPRS_WindowSize, 1),
+ M_UINT (PTR_EGPRS_00_t, UPLINK_EGPRS_WindowSize, 5),
+
+ M_UINT (PTR_EGPRS_00_t, LINK_QUALITY_MEASUREMENT_MODE, 2), // BEP_PERIOD?
+
+ M_TYPE (PTR_EGPRS_00_t, Common_Timeslot_Reconfigure_Data.Global_Packet_Timing_Advance, Global_Packet_Timing_Advance_t),
+
+ M_NEXT_EXIST (PTR_EGPRS_00_t, Exist_Packet_Extended_Timing_Advance, 1),
+ M_UINT (PTR_EGPRS_00_t, Packet_Extended_Timing_Advance, 2),
+
+ M_UINT (PTR_EGPRS_00_t, Common_Timeslot_Reconfigure_Data.DOWNLINK_RLC_MODE, 1),
+ M_UINT (PTR_EGPRS_00_t, Common_Timeslot_Reconfigure_Data.CONTROL_ACK, 1),
+
+ M_NEXT_EXIST (PTR_EGPRS_00_t, Common_Timeslot_Reconfigure_Data.Exist_DOWNLINK_TFI_ASSIGNMENT, 1),
+ M_UINT (PTR_EGPRS_00_t, Common_Timeslot_Reconfigure_Data.DOWNLINK_TFI_ASSIGNMENT, 5),
+
+ M_NEXT_EXIST (PTR_EGPRS_00_t, Common_Timeslot_Reconfigure_Data.Exist_UPLINK_TFI_ASSIGNMENT, 1),
+ M_UINT (PTR_EGPRS_00_t, Common_Timeslot_Reconfigure_Data.UPLINK_TFI_ASSIGNMENT, 5),
+
+ M_UINT (PTR_EGPRS_00_t, Common_Timeslot_Reconfigure_Data.DOWNLINK_TIMESLOT_ALLOCATION, 8),
+
+ M_NEXT_EXIST (PTR_EGPRS_00_t, Common_Timeslot_Reconfigure_Data.Exist_Frequency_Parameters, 1),
+ M_TYPE (PTR_EGPRS_00_t, Common_Timeslot_Reconfigure_Data.Frequency_Parameters, Frequency_Parameters_t),
+
+ M_UNION (PTR_EGPRS_00_t, 2),
+ M_TYPE (PTR_EGPRS_00_t, u.Dynamic_Allocation, TRDynamic_Allocation_t),
+ CSN_ERROR (PTR_EGPRS_00_t, "1 <Fixed Allocation>", CSN_ERROR_STREAM_NOT_SUPPORTED),
+CSN_DESCR_END (PTR_EGPRS_00_t)
+
+CSN_DESCR_BEGIN(TRDynamic_Allocation_t)
+ M_UINT (TRDynamic_Allocation_t, Extended_Dynamic_Allocation, 1),
+
+ M_NEXT_EXIST (TRDynamic_Allocation_t, Exist_P0, 2),
+ M_UINT (TRDynamic_Allocation_t, P0, 4),
+ M_UINT (TRDynamic_Allocation_t, PR_MODE, 1),
+
+ M_UINT (TRDynamic_Allocation_t, USF_GRANULARITY, 1),
+
+ M_NEXT_EXIST (TRDynamic_Allocation_t, Exist_RLC_DATA_BLOCKS_GRANTED, 1),
+ M_UINT (TRDynamic_Allocation_t, RLC_DATA_BLOCKS_GRANTED, 8),
+
+ M_NEXT_EXIST (TRDynamic_Allocation_t, Exist_TBF_Starting_Time, 1),
+ M_TYPE (TRDynamic_Allocation_t, TBF_Starting_Time, Starting_Frame_Number_t),
+
+ M_UNION (TRDynamic_Allocation_t, 2),
+ M_TYPE_ARRAY (TRDynamic_Allocation_t, u.Timeslot_Allocation, Timeslot_Allocation_t, 8),
+ M_TYPE (TRDynamic_Allocation_t, u.Timeslot_Allocation_Power_Ctrl_Param, Timeslot_Allocation_Power_Ctrl_Param_t),
+CSN_DESCR_END (TRDynamic_Allocation_t)
+*/
+/*
+ * PACKET TIMESLOT RECONFIGURE, sent on PACCH
+ * see TS 04 60, 11.2.31 and Table 9.1.9.2.1 (for WS coding)
+ */
+void Encoding::write_packet_ts_reconfigure(RlcMacDownlink_t * block,
+ struct gprs_rlcmac_tbf *tbf, uint8_t poll, uint8_t rrbp,
+ uint8_t alpha, uint8_t gamma, bool use_egprs)
+{
+ block->PAYLOAD_TYPE = 1; // RLC/MAC control block that does not include the optional octets of the RLC/MAC control header
+ block->RRBP = rrbp; // 0: N + 13
+ block->SP = poll;// RRBP field is valid
+ block->USF = 0; // Uplink state flag
+
+ block->u.Packet_Timeslot_Reconfigure.MESSAGE_TYPE = 6; // PTR
+ block->u.Packet_Timeslot_Reconfigure.PAGE_MODE = 2;
+
+ if (GPRS_RLCMAC_UL_TBF == tbf->direction) {
+ block->u.Packet_Timeslot_Reconfigure.Global_TFI.u.UPLINK_TFI = tbf->tfi();
+ }
+ else {
+ block->u.Packet_Timeslot_Reconfigure.Global_TFI.u.DOWNLINK_TFI = tbf->tfi();
+ }
+
+ if (use_egprs) {
+ PTR_EGPRS_t *e;
+ e = &block->u.Packet_Timeslot_Reconfigure.u.PTR_EGPRS_Struct;
+ PTR_EGPRS_00_t *e00 = &e->u.PTR_EGPRS_00; // 01-11 variants are not implemented in CSN
+ e00->Exist_COMPACT_ReducedMA = 0; // no compact reducedMA
+ e00->EGPRS_ChannelCodingCommand = tbf->current_cs().to_num() - 1; // coding scheme
+ e00->RESEGMENT = 0; // no resegment
+ e00->Exist_DOWNLINK_EGPRS_WindowSize = 0;
+ e00->Exist_UPLINK_EGPRS_WindowSize = 0;
+ e00->LINK_QUALITY_MEASUREMENT_MODE = 0; /* no meas, see TS 44.060, table 11.2.7.2 */
+
+ Global_Packet_Timing_Advance_t *gta = &e00->Common_Timeslot_Reconfigure_Data.Global_Packet_Timing_Advance;
+ gta->Exist_TIMING_ADVANCE_VALUE = 1;
+ gta->TIMING_ADVANCE_VALUE = tbf->ta();
+ gta->Exist_UPLINK_TIMING_ADVANCE = 0;
+ gta->Exist_DOWNLINK_TIMING_ADVANCE = 0;
+
+ e00->Exist_Packet_Extended_Timing_Advance = 0; // no extended TA
+ e00->Common_Timeslot_Reconfigure_Data.DOWNLINK_RLC_MODE = 0; //RLC acknowledged mode
+ e00->Common_Timeslot_Reconfigure_Data.CONTROL_ACK = 0; // not a new TBF
+ e00->Common_Timeslot_Reconfigure_Data.Exist_DOWNLINK_TFI_ASSIGNMENT = 0; // no DL. TFI ASS.
+ e00->Common_Timeslot_Reconfigure_Data.Exist_UPLINK_TFI_ASSIGNMENT = 0; // no UL. TFI ASS.
+ e00->Common_Timeslot_Reconfigure_Data.DOWNLINK_TIMESLOT_ALLOCATION = 0;
+ uint8_t tn;
+ for (tn = 0; tn < 8; tn++) { // FIXME: factor into separate function for both reconf. and dl_ass packets
+ if (tbf->pdch[tn])
+ block->u.Packet_Downlink_Assignment.TIMESLOT_ALLOCATION |= 0x80 >> tn; // timeslot(s)
+ }
+
+ e00->Common_Timeslot_Reconfigure_Data.Exist_Frequency_Parameters = 0; // no Freq. Param.
+
+ TRDynamic_Allocation_t *da = &e00->u.Dynamic_Allocation; // fixed alloc. not supported in CSN
+ da->Extended_Dynamic_Allocation = 0; // no extended DA
+ da->Exist_P0 = 0;
+ da->USF_GRANULARITY = 0; // 1 RLC/MAC block instead of 4 consecutive
+ da->Exist_RLC_DATA_BLOCKS_GRANTED = 0;
+ da->Exist_TBF_Starting_Time = 0;
+ Timeslot_Allocation_Power_Ctrl_Param_t *pp = &da->u.Timeslot_Allocation_Power_Ctrl_Param;
+ pp->ALPHA = alpha;
+ for (tn = 0; tn < 8; tn++) // FIXME: factor into separate function for both reconf. and dl_ass packets
+ {
+ if (tbf->pdch[tn]) {
+ pp->Slot[tn].Exist = 1; // Slot[i] = on
+ pp->Slot[tn].USF_TN = tbf->pdch[tn]->assigned_usf(); // tbf->m_usf[tn] - for uplink only
+ pp->Slot[tn].GAMMA_TN = gamma; // GAMMA_TN
+ }
+ else {
+ pp->Slot[tn].Exist = 0; // Slot[i] = off
+ }
+ }
+ } else {
+ PTR_GPRS_t *g;
+ g = &block->u.Packet_Timeslot_Reconfigure.u.PTR_GPRS_Struct;
+
+ }
+}
+/*
+CSN_DESCR_BEGIN (Packet_Downlink_Assignment_t)
+ M_UINT (Packet_Downlink_Assignment_t, MESSAGE_TYPE, 6),
+ M_UINT (Packet_Downlink_Assignment_t, PAGE_MODE, 2),
+
+ M_NEXT_EXIST (Packet_Downlink_Assignment_t, Exist_PERSISTENCE_LEVEL, 1),
+ M_UINT_ARRAY (Packet_Downlink_Assignment_t, PERSISTENCE_LEVEL, 4, 4),
+
+ M_TYPE (Packet_Downlink_Assignment_t, ID, PacketDownlinkID_t),
+
+ M_FIXED (Packet_Downlink_Assignment_t, 1, 0x00),//-- Message escape
+
+ M_UINT (Packet_Downlink_Assignment_t, MAC_MODE, 2),
+ M_BIT (Packet_Downlink_Assignment_t, RLC_MODE),
+ M_BIT (Packet_Downlink_Assignment_t, CONTROL_ACK),
+ M_UINT (Packet_Downlink_Assignment_t, TIMESLOT_ALLOCATION, 8),
+ M_TYPE (Packet_Downlink_Assignment_t, Packet_Timing_Advance, Packet_Timing_Advance_t),
+
+ M_NEXT_EXIST (Packet_Downlink_Assignment_t, Exist_P0_and_BTS_PWR_CTRL_MODE, 3),
+ M_UINT (Packet_Downlink_Assignment_t, P0, 4),
+ M_BIT (Packet_Downlink_Assignment_t, BTS_PWR_CTRL_MODE),
+ M_UINT (Packet_Downlink_Assignment_t, PR_MODE, 1),
+
+ M_NEXT_EXIST (Packet_Downlink_Assignment_t, Exist_Frequency_Parameters, 1),
+ M_TYPE (Packet_Downlink_Assignment_t, Frequency_Parameters, Frequency_Parameters_t),
+
+ M_NEXT_EXIST (Packet_Downlink_Assignment_t, Exist_DOWNLINK_TFI_ASSIGNMENT, 1),
+ M_UINT (Packet_Downlink_Assignment_t, DOWNLINK_TFI_ASSIGNMENT, 5),
+
+ M_NEXT_EXIST (Packet_Downlink_Assignment_t, Exist_Power_Control_Parameters, 1),
+ M_TYPE (Packet_Downlink_Assignment_t, Power_Control_Parameters, Power_Control_Parameters_t),
+
+ M_NEXT_EXIST (Packet_Downlink_Assignment_t, Exist_TBF_Starting_Time, 1),
+ M_TYPE (Packet_Downlink_Assignment_t, TBF_Starting_Time, Starting_Frame_Number_t),
+
+ M_NEXT_EXIST (Packet_Downlink_Assignment_t, Exist_Measurement_Mapping, 1),
+ M_TYPE (Packet_Downlink_Assignment_t, Measurement_Mapping, Measurement_Mapping_struct_t),
+
+ M_NEXT_EXIST_OR_NULL(Packet_Downlink_Assignment_t, Exist_AdditionsR99, 1),
+ M_TYPE (Packet_Downlink_Assignment_t, AdditionsR99, PDA_AdditionsR99_t),
+ M_PADDING_BITS (Packet_Downlink_Assignment_t),
+CSN_DESCR_END (Packet_Downlink_Assignment_t)
+*/
/* generate downlink assignment */
void Encoding::write_packet_downlink_assignment(RlcMacDownlink_t * block,
bool old_tfi_is_valid, uint8_t old_tfi, uint8_t old_downlink,
diff --git a/src/encoding.h b/src/encoding.h
index 94e9a02..7d807f5 100644
--- a/src/encoding.h
+++ b/src/encoding.h
@@ -60,6 +60,10 @@ public:
uint8_t alpha, uint8_t gamma,
int8_t ta_idx, uint8_t ta_ts, bool use_egprs);
+ static void write_packet_ts_reconfigure(RlcMacDownlink_t * block,
+ struct gprs_rlcmac_tbf *tbf, uint8_t poll, uint8_t rrbp,
+ uint8_t alpha, uint8_t gamma, bool use_egprs);
+
static void encode_rbb(const char *show_rbb, uint8_t *rbb);
static void write_packet_uplink_ack(
diff --git a/src/gprs_rlcmac_sched.cpp b/src/gprs_rlcmac_sched.cpp
index 313e23f..ede0442 100644
--- a/src/gprs_rlcmac_sched.cpp
+++ b/src/gprs_rlcmac_sched.cpp
@@ -168,6 +168,12 @@ static struct msgb *sched_select_ctrl_msg(
}
}
+ if (!msg) {
+ // create PACKET RS RECONFIGURE (check for state)
+ tbf = dl_ass_tbf;
+ msg = dl_ass_tbf->create_dl_ts_recon(fn, ts);
+ }
+
/* any message */
if (msg) {
tbf->rotate_in_list();
diff --git a/src/gprs_rlcmac_ts_alloc.cpp b/src/gprs_rlcmac_ts_alloc.cpp
index 57197b2..8d6c2a9 100644
--- a/src/gprs_rlcmac_ts_alloc.cpp
+++ b/src/gprs_rlcmac_ts_alloc.cpp
@@ -961,12 +961,12 @@ int alloc_algorithm_b(struct gprs_rlcmac_bts *bts,
if (single && slotcount) {
tbf_->upgrade_to_multislot = (avail_count > slotcount);
- LOGP(DRLCMAC, LOGL_INFO, "Using single slot at TS %d for %s\n",
+ LOGP(DRLCMAC, LOGL_INFO, "Using single slot at TS %d for %s, multislot = %d\n",
first_ts,
- (tbf->direction == GPRS_RLCMAC_DL_TBF) ? "DL" : "UL");
+ (tbf->direction == GPRS_RLCMAC_DL_TBF) ? "DL" : "UL", tbf_->upgrade_to_multislot);
} else {
tbf_->upgrade_to_multislot = 0;
- LOGP(DRLCMAC, LOGL_INFO, "Using %d slots for %s\n", slotcount,
+ LOGP(DRLCMAC, LOGL_INFO, "Using %d slots for %s, multislot = 0\n", slotcount,
(tbf->direction == GPRS_RLCMAC_DL_TBF) ? "DL" : "UL");
}
diff --git a/src/gsm_rlcmac.cpp b/src/gsm_rlcmac.cpp
index 6b43aa6..aaa0e49 100644
--- a/src/gsm_rlcmac.cpp
+++ b/src/gsm_rlcmac.cpp
@@ -2261,7 +2261,7 @@ CSN_DESCR_BEGIN(Packet_Timeslot_Reconfigure_t)
M_UINT (Packet_Timeslot_Reconfigure_t, MESSAGE_TYPE, 6),
M_UINT (Packet_Timeslot_Reconfigure_t, PAGE_MODE, 2),
- M_FIXED (Packet_Timeslot_Reconfigure_t, 1, 0x00),
+ M_FIXED (Packet_Timeslot_Reconfigure_t, 1, 0x00), // BUG? escaping should be after TFI according to spec
M_TYPE (Packet_Timeslot_Reconfigure_t, Global_TFI, Global_TFI_t),
M_UNION (Packet_Timeslot_Reconfigure_t, 2),
diff --git a/src/tbf.cpp b/src/tbf.cpp
index 69b9e3a..8e14d3d 100644
--- a/src/tbf.cpp
+++ b/src/tbf.cpp
@@ -859,9 +859,14 @@ void gprs_rlcmac_tbf::handle_timeout()
/* keep to flags */
dl_tbf->state_flags &= GPRS_RLCMAC_FLAG_TO_MASK;
- dl_tbf->update();
-
- dl_tbf->bts->trigger_dl_ass(dl_tbf, dl_tbf);
+ dl_tbf->update(); // do the MSLOT assignment
+
+// dl_tbf->bts->trigger_dl_ass(dl_tbf, dl_tbf); // FIXME: use write_packet_ts_reconfigure()
+ // [state/flags change] ->
+ //LOGP(DRLCMAC, LOGL_NOTICE, "DL. ASS. for multislot\n");
+ LOGP(DRLCMAC, LOGL_NOTICE, "P. TS. R. for multislot\n");
+ dl_tbf->bts->trigger_dl_ts_recon(dl_tbf);
+// abort(); // CRASH!
} else
LOGP(DRLCMAC, LOGL_NOTICE, "%s Continue flow after "
"IMM.ASS confirm\n", tbf_name(dl_tbf));
@@ -905,6 +910,51 @@ int gprs_rlcmac_tbf::rlcmac_diag()
return 0;
}
+struct msgb *gprs_rlcmac_tbf::create_dl_ts_recon(uint32_t fn, uint8_t ts)
+{
+ // FIXME - check appropriate flags
+ if (this->state_is_not(GPRS_RLCMAC_RECONFIGURING)) {
+// LOGP(DRLCMAC, LOGL_NOTICE, "TS. R. -- ignoring due to incompatible state\n");
+ return NULL;
+ }
+ LOGP(DRLCMAC, LOGL_NOTICE, "TS. R. -- GPRS_RLCMAC_RECONFIGURING: preparing msg\n");
+ unsigned int rrbp = 0;
+ uint32_t new_poll_fn = 0;
+ struct msgb *msg;
+
+ int rc = this->check_polling(fn, ts, &new_poll_fn, &rrbp);
+ if (rc < 0) {
+ LOGP(DRLCMAC, LOGL_ERROR, "check polling failed!\n");
+ return NULL;
+ }
+
+ msg = msgb_alloc(23, "rlcmac_pack_ts_recon");
+ if (!msg) {
+ LOGP(DRLCMAC, LOGL_NOTICE, "TS. R. -- msg alloc failed\n");
+ return NULL;
+ }
+ bitvec *recon_vec = bitvec_alloc(123);
+ if (!recon_vec) {
+ msgb_free(msg);
+ LOGP(DRLCMAC, LOGL_NOTICE, "TS. R. -- bitvec alloc failed\n");
+ return NULL;
+ }
+
+ bitvec_unhex(recon_vec, "2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b");
+
+ LOGP(DRLCMAC, LOGL_INFO, "%s start Packet TS Reconfigure (PACCH)\n", tbf_name(this));
+ RlcMacDownlink_t * mac_control_block = (RlcMacDownlink_t *)talloc_zero(tall_pcu_ctx, RlcMacDownlink_t);
+ Encoding::write_packet_ts_reconfigure(mac_control_block, this, new_poll_fn, rrbp, bts_data()->alpha, bts_data()->gamma, this->is_egprs_enabled());
+ LOGP(DRLCMAC, LOGL_DEBUG, "+++++++++++++++++++++++++ TX : Packet TS Reconfigure +++++++++++++++++++++++++\n");
+ encode_gsm_rlcmac_downlink(recon_vec, mac_control_block);
+ LOGPC(DCSN1, LOGL_NOTICE, "\n");
+ LOGP(DRLCMAC, LOGL_DEBUG, "_________________________ TX : Packet TS Reconfigure _________________________\n");
+ bitvec_pack(recon_vec, msgb_put(msg, 23)); // FIXME - size?
+ bitvec_free(recon_vec);
+ talloc_free(mac_control_block);
+ return msg;
+}
+
struct msgb *gprs_rlcmac_tbf::create_dl_ass(uint32_t fn, uint8_t ts)
{
struct msgb *msg;
diff --git a/src/tbf.h b/src/tbf.h
index ad8ad4c..b5426d9 100644
--- a/src/tbf.h
+++ b/src/tbf.h
@@ -49,6 +49,7 @@ enum gprs_rlcmac_tbf_state {
GPRS_RLCMAC_FINISHED, /* flow finished, wait for release */
GPRS_RLCMAC_WAIT_RELEASE,/* wait for release or restart of DL TBF */
GPRS_RLCMAC_RELEASING, /* releasing, wait to free TBI/USF */
+ GPRS_RLCMAC_RECONFIGURING, // TS RECON. scheduled
};
enum gprs_rlcmac_tbf_poll_state {
@@ -103,8 +104,9 @@ struct gprs_rlcmac_tbf {
const char *name() const;
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_ul_ass(uint32_t fn, uint8_t ts);
+ struct msgb *create_dl_ts_recon(uint32_t fn, uint8_t ts);
+
GprsMs *ms() const;
void set_ms(GprsMs *ms);