diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gprs_rlcmac.cpp | 48 | ||||
-rw-r--r-- | src/gprs_rlcmac.h | 9 | ||||
-rw-r--r-- | src/gprs_rlcmac_data.cpp | 21 | ||||
-rw-r--r-- | src/pcu_main.cpp | 1 | ||||
-rw-r--r-- | src/pcu_vty.c | 35 |
5 files changed, 90 insertions, 24 deletions
diff --git a/src/gprs_rlcmac.cpp b/src/gprs_rlcmac.cpp index f7ec8477..64bbe75f 100644 --- a/src/gprs_rlcmac.cpp +++ b/src/gprs_rlcmac.cpp @@ -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 { diff --git a/src/gprs_rlcmac.h b/src/gprs_rlcmac.h index e7a68a4f..46439911 100644 --- a/src/gprs_rlcmac.h +++ b/src/gprs_rlcmac.h @@ -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); diff --git a/src/gprs_rlcmac_data.cpp b/src/gprs_rlcmac_data.cpp index 8bb1df65..b6d50622 100644 --- a/src/gprs_rlcmac_data.cpp +++ b/src/gprs_rlcmac_data.cpp @@ -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); } diff --git a/src/pcu_main.cpp b/src/pcu_main.cpp index 2392152a..ba31ca7e 100644 --- a/src/pcu_main.cpp +++ b/src/pcu_main.cpp @@ -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); diff --git a/src/pcu_vty.c b/src/pcu_vty.c index 8d5b47b1..d7c2c2cd 100644 --- a/src/pcu_vty.c +++ b/src/pcu_vty.c @@ -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; |