Set Alpha and Gamma at assingment messages for power control
The initial power control value Alpha must be set in SI13.
This commit is contained in:
parent
df4d20e95b
commit
aafcbbb252
|
@ -1161,7 +1161,8 @@ struct msgb *gprs_rlcmac_send_packet_paging_request(
|
|||
int write_immediate_assignment(bitvec * dest, uint8_t downlink, uint8_t ra,
|
||||
uint32_t ref_fn, uint8_t ta, uint16_t arfcn, uint8_t ts, uint8_t tsc,
|
||||
uint8_t tfi, uint8_t usf, uint32_t tlli,
|
||||
uint8_t polling, uint32_t fn, uint8_t single_block)
|
||||
uint8_t polling, uint32_t fn, uint8_t single_block, uint8_t alpha,
|
||||
uint8_t gamma)
|
||||
{
|
||||
unsigned wp = 0;
|
||||
uint8_t plen;
|
||||
|
@ -1215,8 +1216,13 @@ int write_immediate_assignment(bitvec * dest, uint8_t downlink, uint8_t ra,
|
|||
bitvec_write_field(dest, wp,0x1,1); // switch TFI : on
|
||||
bitvec_write_field(dest, wp,tfi,5); // TFI
|
||||
bitvec_write_field(dest, wp,0x0,1); // RLC acknowledged mode
|
||||
bitvec_write_field(dest, wp,0x0,1); // ALPHA = not present
|
||||
bitvec_write_field(dest, wp,0x0,5); // GAMMA power control parameter
|
||||
if (alpha) {
|
||||
bitvec_write_field(dest, wp,0x1,1); // ALPHA = present
|
||||
bitvec_write_field(dest, wp,alpha,4); // ALPHA
|
||||
} else {
|
||||
bitvec_write_field(dest, wp,0x0,1); // ALPHA = not present
|
||||
}
|
||||
bitvec_write_field(dest, wp,gamma,5); // GAMMA power control parameter
|
||||
bitvec_write_field(dest, wp,polling,1); // Polling Bit
|
||||
bitvec_write_field(dest, wp,!polling,1); // TA_VALID ???
|
||||
bitvec_write_field(dest, wp,0x1,1); // switch TIMING_ADVANCE_INDEX = on
|
||||
|
@ -1241,9 +1247,12 @@ int write_immediate_assignment(bitvec * dest, uint8_t downlink, uint8_t ra,
|
|||
bitvec_write_field(dest, wp, 0, 2); // "0" Packet Uplink Assignment
|
||||
if (single_block) {
|
||||
bitvec_write_field(dest, wp, 0, 1); // Block Allocation : Single Block Allocation
|
||||
bitvec_write_field(dest, wp, 1, 1); // "1" Alpha : Present
|
||||
bitvec_write_field(dest, wp, 0, 4); // Alpha
|
||||
bitvec_write_field(dest, wp, 0, 5); // Gamma
|
||||
if (alpha) {
|
||||
bitvec_write_field(dest, wp,0x1,1); // ALPHA = present
|
||||
bitvec_write_field(dest, wp,alpha,4); // ALPHA = present
|
||||
} else
|
||||
bitvec_write_field(dest, wp,0x0,1); // ALPHA = not present
|
||||
bitvec_write_field(dest, wp,gamma,5); // GAMMA power control parameter
|
||||
bitvec_write_field(dest, wp, 0, 1); // TIMING_ADVANCE_INDEX_FLAG
|
||||
bitvec_write_field(dest, wp, 1, 1); // TBF_STARTING_TIME_FLAG
|
||||
bitvec_write_field(dest, wp,(fn / (26 * 51)) % 32,5); // T1'
|
||||
|
@ -1259,9 +1268,12 @@ int write_immediate_assignment(bitvec * dest, uint8_t downlink, uint8_t ra,
|
|||
bitvec_write_field(dest, wp, 0, 1); // "0" power control: Not Present
|
||||
bitvec_write_field(dest, wp, bts->initial_cs-1, 2); // CHANNEL_CODING_COMMAND
|
||||
bitvec_write_field(dest, wp, 1, 1); // TLLI_BLOCK_CHANNEL_CODING
|
||||
bitvec_write_field(dest, wp, 1, 1); // "1" Alpha : Present
|
||||
bitvec_write_field(dest, wp, 0, 4); // Alpha
|
||||
bitvec_write_field(dest, wp, 0, 5); // Gamma
|
||||
if (alpha) {
|
||||
bitvec_write_field(dest, wp,0x1,1); // ALPHA = present
|
||||
bitvec_write_field(dest, wp,alpha,4); // ALPHA
|
||||
} else
|
||||
bitvec_write_field(dest, wp,0x0,1); // ALPHA = not present
|
||||
bitvec_write_field(dest, wp,gamma,5); // GAMMA power control parameter
|
||||
bitvec_write_field(dest, wp, 0, 1); // TIMING_ADVANCE_INDEX_FLAG
|
||||
bitvec_write_field(dest, wp, 0, 1); // TBF_STARTING_TIME_FLAG
|
||||
}
|
||||
|
@ -1273,7 +1285,8 @@ int write_immediate_assignment(bitvec * dest, uint8_t downlink, uint8_t ra,
|
|||
/* generate uplink assignment */
|
||||
void write_packet_uplink_assignment(bitvec * dest, uint8_t old_tfi,
|
||||
uint8_t old_downlink, uint32_t tlli, uint8_t use_tlli,
|
||||
struct gprs_rlcmac_tbf *tbf, uint8_t poll)
|
||||
struct gprs_rlcmac_tbf *tbf, uint8_t poll, uint8_t alpha,
|
||||
uint8_t gamma)
|
||||
{
|
||||
// TODO We should use our implementation of encode RLC/MAC Control messages.
|
||||
struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts;
|
||||
|
@ -1326,12 +1339,18 @@ void write_packet_uplink_assignment(bitvec * dest, uint8_t old_tfi,
|
|||
|
||||
bitvec_write_field(dest, wp,0x0,1); //
|
||||
bitvec_write_field(dest, wp,0x0,1); // TBF Starting Time = off
|
||||
bitvec_write_field(dest, wp,0x0,1); // Timeslot Allocation
|
||||
if (alpha || gamma) {
|
||||
bitvec_write_field(dest, wp,0x1,1); // Timeslot Allocation with Power Control
|
||||
bitvec_write_field(dest, wp,alpha,4); // ALPHA
|
||||
} else
|
||||
bitvec_write_field(dest, wp,0x0,1); // Timeslot Allocation
|
||||
|
||||
for (ts = 0; ts < 8; ts++) {
|
||||
if (tbf->pdch[ts]) {
|
||||
bitvec_write_field(dest, wp,0x1,1); // USF_TN(i): on
|
||||
bitvec_write_field(dest, wp,tbf->dir.ul.usf[ts],3); // USF_TN(i)
|
||||
if (alpha || gamma)
|
||||
bitvec_write_field(dest, wp,gamma,5); // GAMMA power control parameter
|
||||
} else
|
||||
bitvec_write_field(dest, wp,0x0,1); // USF_TN(i): off
|
||||
}
|
||||
|
@ -1341,7 +1360,8 @@ void write_packet_uplink_assignment(bitvec * dest, uint8_t old_tfi,
|
|||
|
||||
/* generate downlink assignment */
|
||||
void write_packet_downlink_assignment(RlcMacDownlink_t * block, uint8_t old_tfi,
|
||||
uint8_t old_downlink, struct gprs_rlcmac_tbf *tbf, uint8_t poll)
|
||||
uint8_t old_downlink, struct gprs_rlcmac_tbf *tbf, uint8_t poll,
|
||||
uint8_t alpha, uint8_t gamma)
|
||||
{
|
||||
// Packet downlink assignment TS 44.060 11.2.7
|
||||
|
||||
|
@ -1385,14 +1405,14 @@ void write_packet_downlink_assignment(RlcMacDownlink_t * block, uint8_t old_tfi,
|
|||
block->u.Packet_Downlink_Assignment.DOWNLINK_TFI_ASSIGNMENT = tbf->tfi; // TFI
|
||||
|
||||
block->u.Packet_Downlink_Assignment.Exist_Power_Control_Parameters = 0x1; // Power Control Parameters = on
|
||||
block->u.Packet_Downlink_Assignment.Power_Control_Parameters.ALPHA = 0x0; // ALPHA
|
||||
block->u.Packet_Downlink_Assignment.Power_Control_Parameters.ALPHA = alpha; // ALPHA
|
||||
|
||||
for (tn = 0; tn < 8; tn++)
|
||||
{
|
||||
if (tbf->pdch[tn])
|
||||
{
|
||||
block->u.Packet_Downlink_Assignment.Power_Control_Parameters.Slot[tn].Exist = 0x1; // Slot[i] = on
|
||||
block->u.Packet_Downlink_Assignment.Power_Control_Parameters.Slot[tn].GAMMA_TN = 0x0; // GAMMA_TN
|
||||
block->u.Packet_Downlink_Assignment.Power_Control_Parameters.Slot[tn].GAMMA_TN = gamma; // GAMMA_TN
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -83,6 +83,7 @@ struct gprs_rlcmac_bts {
|
|||
struct gprs_rlcmac_tbf *tbf, uint32_t cust);
|
||||
uint32_t alloc_algorithm_curst; /* options to customize algorithm */
|
||||
uint8_t force_two_phase;
|
||||
uint8_t alpha, gamma;
|
||||
};
|
||||
|
||||
extern struct gprs_rlcmac_bts *gprs_rlcmac_bts;
|
||||
|
@ -292,14 +293,16 @@ int gprs_rlcmac_rcv_block(uint8_t trx, uint8_t ts, uint8_t *data, uint8_t len,
|
|||
int write_immediate_assignment(bitvec * dest, uint8_t downlink, uint8_t ra,
|
||||
uint32_t ref_fn, uint8_t ta, uint16_t arfcn, uint8_t ts, uint8_t tsc,
|
||||
uint8_t tfi, uint8_t usf, uint32_t tlli, uint8_t polling,
|
||||
uint32_t fn, uint8_t single_block);
|
||||
uint32_t fn, uint8_t single_block, uint8_t alpha, uint8_t gamma);
|
||||
|
||||
void write_packet_uplink_assignment(bitvec * dest, uint8_t old_tfi,
|
||||
uint8_t old_downlink, uint32_t tlli, uint8_t use_tlli,
|
||||
struct gprs_rlcmac_tbf *tbf, uint8_t poll);
|
||||
struct gprs_rlcmac_tbf *tbf, uint8_t poll, uint8_t alpha,
|
||||
uint8_t gamma);
|
||||
|
||||
void write_packet_downlink_assignment(RlcMacDownlink_t * block, uint8_t old_tfi,
|
||||
uint8_t old_downlink, struct gprs_rlcmac_tbf *tbf, uint8_t poll);
|
||||
uint8_t old_downlink, struct gprs_rlcmac_tbf *tbf, uint8_t poll,
|
||||
uint8_t alpha, uint8_t gamma);
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -946,6 +946,7 @@ int gprs_rlcmac_rcv_data_block_acknowledged(uint8_t trx, uint8_t ts,
|
|||
struct msgb *gprs_rlcmac_send_packet_uplink_assignment(
|
||||
struct gprs_rlcmac_tbf *tbf, uint32_t fn)
|
||||
{
|
||||
struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts;
|
||||
struct msgb *msg;
|
||||
struct gprs_rlcmac_tbf *new_tbf;
|
||||
|
||||
|
@ -990,7 +991,8 @@ struct msgb *gprs_rlcmac_send_packet_uplink_assignment(
|
|||
"2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b");
|
||||
write_packet_uplink_assignment(ass_vec, tbf->tfi,
|
||||
(tbf->direction == GPRS_RLCMAC_DL_TBF), tbf->tlli,
|
||||
tbf->tlli_valid, new_tbf, POLLING_ASSIGNMENT_UL);
|
||||
tbf->tlli_valid, new_tbf, POLLING_ASSIGNMENT_UL, bts->alpha,
|
||||
bts->gamma);
|
||||
bitvec_pack(ass_vec, msgb_put(msg, 23));
|
||||
RlcMacDownlink_t * mac_control_block = (RlcMacDownlink_t *)talloc_zero(tall_pcu_ctx, RlcMacDownlink_t);
|
||||
LOGP(DRLCMAC, LOGL_DEBUG, "+++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++\n");
|
||||
|
@ -1081,11 +1083,13 @@ int gprs_rlcmac_rcv_rach(uint8_t ra, uint32_t Fn, int16_t qta)
|
|||
if (sb)
|
||||
plen = write_immediate_assignment(immediate_assignment, 0, ra,
|
||||
Fn, qta >> 2, bts->trx[trx].arfcn, ts,
|
||||
bts->trx[trx].pdch[ts].tsc, 0, 0, 0, 0, sb_fn, 1);
|
||||
bts->trx[trx].pdch[ts].tsc, 0, 0, 0, 0, sb_fn, 1,
|
||||
bts->alpha, bts->gamma);
|
||||
else
|
||||
plen = write_immediate_assignment(immediate_assignment, 0, ra,
|
||||
Fn, tbf->ta, tbf->arfcn, tbf->first_ts, tbf->tsc,
|
||||
tbf->tfi, tbf->dir.ul.usf[tbf->first_ts], 0, 0, 0, 0);
|
||||
tbf->tfi, tbf->dir.ul.usf[tbf->first_ts], 0, 0, 0, 0,
|
||||
bts->alpha, bts->gamma);
|
||||
pcu_l1if_tx_agch(immediate_assignment, plen);
|
||||
bitvec_free(immediate_assignment);
|
||||
|
||||
|
@ -1611,6 +1615,7 @@ int gprs_rlcmac_downlink_ack(struct gprs_rlcmac_tbf *tbf, uint8_t final,
|
|||
struct msgb *gprs_rlcmac_send_packet_downlink_assignment(
|
||||
struct gprs_rlcmac_tbf *tbf, uint32_t fn)
|
||||
{
|
||||
struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts;
|
||||
struct msgb *msg;
|
||||
struct gprs_rlcmac_tbf *new_tbf;
|
||||
int poll_ass_dl = POLLING_ASSIGNMENT_DL;
|
||||
|
@ -1670,7 +1675,7 @@ struct msgb *gprs_rlcmac_send_packet_downlink_assignment(
|
|||
RlcMacDownlink_t * mac_control_block = (RlcMacDownlink_t *)talloc_zero(tall_pcu_ctx, RlcMacDownlink_t);
|
||||
write_packet_downlink_assignment(mac_control_block, tbf->tfi,
|
||||
(tbf->direction == GPRS_RLCMAC_DL_TBF), new_tbf,
|
||||
poll_ass_dl);
|
||||
poll_ass_dl, bts->alpha, bts->gamma);
|
||||
LOGP(DRLCMAC, LOGL_DEBUG, "+++++++++++++++++++++++++ TX : Packet Downlink Assignment +++++++++++++++++++++++++\n");
|
||||
encode_gsm_rlcmac_downlink(ass_vec, mac_control_block);
|
||||
LOGPC(DCSN1, LOGL_NOTICE, "\n");
|
||||
|
@ -1698,12 +1703,18 @@ struct msgb *gprs_rlcmac_send_packet_downlink_assignment(
|
|||
static void gprs_rlcmac_downlink_assignment(gprs_rlcmac_tbf *tbf, uint8_t poll,
|
||||
char *imsi)
|
||||
{
|
||||
struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts;
|
||||
int plen;
|
||||
|
||||
LOGP(DRLCMAC, LOGL_INFO, "TX: START TFI: %u TLLI: 0x%08x Immediate Assignment Downlink (PCH)\n", tbf->tfi, tbf->tlli);
|
||||
bitvec *immediate_assignment = bitvec_alloc(22); /* without plen */
|
||||
bitvec_unhex(immediate_assignment, "2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b");
|
||||
/* use request reference that has maximum distance to current time,
|
||||
* so the assignment will not conflict with possible RACH requests. */
|
||||
int plen = write_immediate_assignment(immediate_assignment, 1, 125, (tbf->pdch[tbf->first_ts]->last_rts_fn + 21216) % 2715648, tbf->ta, tbf->arfcn, tbf->first_ts, tbf->tsc, tbf->tfi, 0, tbf->tlli, poll, tbf->poll_fn, 0);
|
||||
plen = write_immediate_assignment(immediate_assignment, 1, 125,
|
||||
(tbf->pdch[tbf->first_ts]->last_rts_fn + 21216) % 2715648, tbf->ta,
|
||||
tbf->arfcn, tbf->first_ts, tbf->tsc, tbf->tfi, 0, tbf->tlli, poll,
|
||||
tbf->poll_fn, 0, bts->alpha, bts->gamma);
|
||||
pcu_l1if_tx_pch(immediate_assignment, plen, imsi);
|
||||
bitvec_free(immediate_assignment);
|
||||
}
|
||||
|
|
|
@ -153,6 +153,7 @@ int main(int argc, char *argv[])
|
|||
bts->n3101 = 10;
|
||||
bts->n3103 = 4;
|
||||
bts->n3105 = 8;
|
||||
bts->alpha = 10; /* a = 1.0 */
|
||||
|
||||
msgb_set_talloc_ctx(tall_pcu_ctx);
|
||||
|
||||
|
|
|
@ -94,6 +94,8 @@ static int config_write_pcu(struct vty *vty)
|
|||
vty_out(vty, " alloc-algorithm b%s", VTY_NEWLINE);
|
||||
if (bts->force_two_phase)
|
||||
vty_out(vty, " two-phase-access%s", VTY_NEWLINE);
|
||||
vty_out(vty, " alpha %d%s", bts->alpha, VTY_NEWLINE);
|
||||
vty_out(vty, " gamma %d%s", bts->gamma * 2, VTY_NEWLINE);
|
||||
|
||||
}
|
||||
|
||||
|
@ -110,9 +112,9 @@ DEFUN(cfg_pcu,
|
|||
|
||||
DEFUN(cfg_pcu_fc_interval,
|
||||
cfg_pcu_fc_interval_cmd,
|
||||
"flow-control-interval <1..10>",
|
||||
"flow-control-interval <1-10>",
|
||||
"Interval between sending subsequent Flow Control PDUs\n"
|
||||
"Tiem in seconds\n")
|
||||
"Interval time in seconds\n")
|
||||
{
|
||||
struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts;
|
||||
|
||||
|
@ -234,6 +236,33 @@ DEFUN(cfg_pcu_no_two_phase,
|
|||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(cfg_pcu_alpha,
|
||||
cfg_pcu_alpha_cmd,
|
||||
"alpha <0-10>",
|
||||
"Alpha parameter for MS power control in units of 0.1 (see TS 05.08) "
|
||||
"NOTE: Be sure to set Alpha value at System information 13 too.\n"
|
||||
"Alpha in units of 0.1\n")
|
||||
{
|
||||
struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts;
|
||||
|
||||
bts->alpha = atoi(argv[0]);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(cfg_pcu_gamma,
|
||||
cfg_pcu_gamma_cmd,
|
||||
"gamma <0-62>",
|
||||
"Gamma parameter for MS power control in units of dB (see TS 05.08)\n"
|
||||
"Gamma in even unit of dBs\n")
|
||||
{
|
||||
struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts;
|
||||
|
||||
bts->gamma = atoi(argv[0]) / 2;
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
static const char pcu_copyright[] =
|
||||
"Copyright (C) 2012 by ...\r\n"
|
||||
"License GNU GPL version 2 or later\r\n"
|
||||
|
@ -266,6 +295,8 @@ int pcu_vty_init(const struct log_info *cat)
|
|||
install_element(PCU_NODE, &cfg_pcu_alloc_cmd);
|
||||
install_element(PCU_NODE, &cfg_pcu_two_phase_cmd);
|
||||
install_element(PCU_NODE, &cfg_pcu_fc_interval_cmd);
|
||||
install_element(PCU_NODE, &cfg_pcu_alpha_cmd);
|
||||
install_element(PCU_NODE, &cfg_pcu_gamma_cmd);
|
||||
install_element(PCU_NODE, &ournode_end_cmd);
|
||||
|
||||
return 0;
|
||||
|
|
Loading…
Reference in New Issue