encoding: Redesign Encoding::write_immediate_assignment API

The EGPRS support will need more information to encode the IMMEDIATE
ASSIGMENT. Instead of adding more parameters pass a pointer to the
TBF unless an SBA shall be done (indicated by tbf == NULL). All
values that can be derived from the TBF and are not needed for an SBA
are removed from the parameter list.

Return a negative value on error.

Sponsored-by: On-Waves ehf
This commit is contained in:
Jacob Erlbeck 2016-02-01 16:13:38 +01:00
parent 3739905f49
commit 62a04dac0b
3 changed files with 55 additions and 35 deletions

View File

@ -466,8 +466,7 @@ int BTS::rcv_rach(uint8_t ra, uint32_t Fn, int16_t qta)
uint8_t sb = 0; uint8_t sb = 0;
uint32_t sb_fn = 0; uint32_t sb_fn = 0;
int rc; int rc;
uint8_t plen; int plen;
uint8_t tfi = 0;
uint8_t usf = 7; uint8_t usf = 7;
uint8_t tsc; uint8_t tsc;
uint16_t ta; uint16_t ta;
@ -528,7 +527,6 @@ int BTS::rcv_rach(uint8_t ra, uint32_t Fn, int16_t qta)
"Assignment Uplink (AGCH)\n", tbf_name(tbf)); "Assignment Uplink (AGCH)\n", tbf_name(tbf));
trx_no = tbf->trx->trx_no; trx_no = tbf->trx->trx_no;
ts_no = tbf->first_control_ts(); ts_no = tbf->first_control_ts();
tfi = tbf->tfi();
usf = tbf->m_usf[ts_no]; usf = tbf->m_usf[ts_no];
tsc = tbf->tsc(); tsc = tbf->tsc();
} }
@ -538,14 +536,17 @@ int BTS::rcv_rach(uint8_t ra, uint32_t Fn, int16_t qta)
LOGP(DRLCMAC, LOGL_DEBUG, LOGP(DRLCMAC, LOGL_DEBUG,
" - TRX=%d (%d) TS=%d TA=%d TSC=%d TFI=%d USF=%d\n", " - TRX=%d (%d) TS=%d TA=%d TSC=%d TFI=%d USF=%d\n",
trx_no, m_bts.trx[trx_no].arfcn, ts_no, ta, tsc, tfi, usf); trx_no, m_bts.trx[trx_no].arfcn, ts_no, ta, tsc,
tbf ? tbf->tfi() : -1, usf);
plen = Encoding::write_immediate_assignment( plen = Encoding::write_immediate_assignment(
&m_bts, immediate_assignment, 0, ra, Fn, ta, tbf, immediate_assignment, 0, ra, Fn, ta,
m_bts.trx[trx_no].arfcn, ts_no, tsc, tfi, usf, 0, 0, sb_fn, sb, m_bts.trx[trx_no].arfcn, ts_no, tsc, usf, 0, sb_fn,
m_bts.alpha, m_bts.gamma, -1); m_bts.alpha, m_bts.gamma, -1);
pcu_l1if_tx_agch(immediate_assignment, plen); if (plen >= 0)
pcu_l1if_tx_agch(immediate_assignment, plen);
bitvec_free(immediate_assignment); bitvec_free(immediate_assignment);
return 0; return 0;
@ -598,11 +599,12 @@ void BTS::snd_dl_ass(gprs_rlcmac_tbf *tbf, uint8_t poll, const char *imsi)
LOGP(DRLCMAC, LOGL_DEBUG, " - TRX=%d (%d) TS=%d TA=%d pollFN=%d\n", LOGP(DRLCMAC, LOGL_DEBUG, " - TRX=%d (%d) TS=%d TA=%d pollFN=%d\n",
tbf->trx->trx_no, tbf->trx->arfcn, tbf->trx->trx_no, tbf->trx->arfcn,
ts, tbf->ta(), poll ? tbf->poll_fn : -1); ts, tbf->ta(), poll ? tbf->poll_fn : -1);
plen = Encoding::write_immediate_assignment(&m_bts, immediate_assignment, 1, 125, plen = Encoding::write_immediate_assignment(tbf, immediate_assignment, 1, 125,
(tbf->pdch[ts]->last_rts_fn + 21216) % 2715648, tbf->ta(), (tbf->pdch[ts]->last_rts_fn + 21216) % 2715648, tbf->ta(),
tbf->trx->arfcn, ts, tbf->tsc(), tbf->tfi(), 7, tbf->tlli(), poll, tbf->trx->arfcn, ts, tbf->tsc(), 7, poll,
tbf->poll_fn, 0, m_bts.alpha, m_bts.gamma, -1); tbf->poll_fn, m_bts.alpha, m_bts.gamma, -1);
pcu_l1if_tx_pch(immediate_assignment, plen, imsi); if (plen >= 0)
pcu_l1if_tx_pch(immediate_assignment, plen, imsi);
bitvec_free(immediate_assignment); bitvec_free(immediate_assignment);
} }

View File

@ -28,17 +28,23 @@
#include <errno.h> #include <errno.h>
#include <string.h> #include <string.h>
static void write_ia_rest_downlink( static int write_ia_rest_downlink(
gprs_rlcmac_dl_tbf *tbf,
bitvec * dest, unsigned& wp, bitvec * dest, unsigned& wp,
uint8_t tfi, uint32_t tlli, uint8_t polling, uint8_t polling, uint32_t fn,
uint32_t fn, uint8_t alpha, uint8_t gamma, int8_t ta_idx) uint8_t alpha, uint8_t gamma, int8_t ta_idx)
{ {
if (!tbf) {
LOGP(DRLCMACDL, LOGL_ERROR,
"Cannot encode DL IMMEDIATE ASSIGNMENT without TBF\n");
return -EINVAL;
}
// GSM 04.08 10.5.2.16 IA Rest Octets // GSM 04.08 10.5.2.16 IA Rest Octets
bitvec_write_field_lh(dest, wp, 3, 2); // "HH" bitvec_write_field_lh(dest, wp, 3, 2); // "HH"
bitvec_write_field(dest, wp, 1, 2); // "01" Packet Downlink Assignment bitvec_write_field(dest, wp, 1, 2); // "01" Packet Downlink Assignment
bitvec_write_field(dest, wp,tlli,32); // TLLI bitvec_write_field(dest, wp,tbf->tlli(),32); // TLLI
bitvec_write_field(dest, wp,0x1,1); // switch TFI : on bitvec_write_field(dest, wp,0x1,1); // switch TFI : on
bitvec_write_field(dest, wp,tfi,5); // TFI bitvec_write_field(dest, wp,tbf->tfi(),5); // TFI
bitvec_write_field(dest, wp,0x0,1); // RLC acknowledged mode bitvec_write_field(dest, wp,0x0,1); // RLC acknowledged mode
if (alpha) { if (alpha) {
bitvec_write_field(dest, wp,0x1,1); // ALPHA = present bitvec_write_field(dest, wp,0x1,1); // ALPHA = present
@ -66,17 +72,20 @@ static void write_ia_rest_downlink(
bitvec_write_field(dest, wp,0x0,1); // P0 not present bitvec_write_field(dest, wp,0x0,1); // P0 not present
// bitvec_write_field(dest, wp,0x1,1); // P0 not present // bitvec_write_field(dest, wp,0x1,1); // P0 not present
// bitvec_write_field(dest, wp,0xb,4); // bitvec_write_field(dest, wp,0xb,4);
return 0;
} }
static void write_ia_rest_uplink( static int write_ia_rest_uplink(
struct gprs_rlcmac_bts *bts, bitvec * dest, unsigned& wp, gprs_rlcmac_ul_tbf *tbf,
uint8_t tfi, uint8_t usf, uint32_t fn, uint8_t single_block, bitvec * dest, unsigned& wp,
uint8_t usf, uint32_t fn,
uint8_t alpha, uint8_t gamma, int8_t ta_idx) uint8_t alpha, uint8_t gamma, int8_t ta_idx)
{ {
// GMS 04.08 10.5.2.37b 10.5.2.16 // GMS 04.08 10.5.2.37b 10.5.2.16
bitvec_write_field_lh(dest, wp, 3, 2); // "HH" bitvec_write_field_lh(dest, wp, 3, 2); // "HH"
bitvec_write_field(dest, wp, 0, 2); // "0" Packet Uplink Assignment bitvec_write_field(dest, wp, 0, 2); // "0" Packet Uplink Assignment
if (single_block) { if (tbf == NULL) {
bitvec_write_field(dest, wp, 0, 1); // Block Allocation : Single Block Allocation bitvec_write_field(dest, wp, 0, 1); // Block Allocation : Single Block Allocation
if (alpha) { if (alpha) {
bitvec_write_field(dest, wp,0x1,1); // ALPHA = present bitvec_write_field(dest, wp,0x1,1); // ALPHA = present
@ -96,13 +105,13 @@ static void write_ia_rest_uplink(
bitvec_write_field(dest, wp,fn % 26,5); // T2 bitvec_write_field(dest, wp,fn % 26,5); // T2
} else { } else {
bitvec_write_field(dest, wp, 1, 1); // Block Allocation : Not Single Block Allocation bitvec_write_field(dest, wp, 1, 1); // Block Allocation : Not Single Block Allocation
bitvec_write_field(dest, wp, tfi, 5); // TFI_ASSIGNMENT Temporary Flow Identity bitvec_write_field(dest, wp, tbf->tfi(), 5); // TFI_ASSIGNMENT Temporary Flow Identity
bitvec_write_field(dest, wp, 0, 1); // POLLING bitvec_write_field(dest, wp, 0, 1); // POLLING
bitvec_write_field(dest, wp, 0, 1); // ALLOCATION_TYPE: dynamic bitvec_write_field(dest, wp, 0, 1); // ALLOCATION_TYPE: dynamic
bitvec_write_field(dest, wp, usf, 3); // USF bitvec_write_field(dest, wp, usf, 3); // USF
bitvec_write_field(dest, wp, 0, 1); // USF_GRANULARITY bitvec_write_field(dest, wp, 0, 1); // USF_GRANULARITY
bitvec_write_field(dest, wp, 0, 1); // "0" power control: Not Present bitvec_write_field(dest, wp, 0, 1); // "0" power control: Not Present
bitvec_write_field(dest, wp, bts->initial_cs_ul-1, 2); // CHANNEL_CODING_COMMAND bitvec_write_field(dest, wp, tbf->current_cs().to_num()-1, 2); // CHANNEL_CODING_COMMAND
bitvec_write_field(dest, wp, 1, 1); // TLLI_BLOCK_CHANNEL_CODING bitvec_write_field(dest, wp, 1, 1); // TLLI_BLOCK_CHANNEL_CODING
if (alpha) { if (alpha) {
bitvec_write_field(dest, wp,0x1,1); // ALPHA = present bitvec_write_field(dest, wp,0x1,1); // ALPHA = present
@ -114,6 +123,7 @@ static void write_ia_rest_uplink(
bitvec_write_field(dest, wp, 0, 1); // switch TIMING_ADVANCE_INDEX = off bitvec_write_field(dest, wp, 0, 1); // switch TIMING_ADVANCE_INDEX = off
bitvec_write_field(dest, wp, 0, 1); // TBF_STARTING_TIME_FLAG bitvec_write_field(dest, wp, 0, 1); // TBF_STARTING_TIME_FLAG
} }
return 0;
} }
/* /*
@ -121,15 +131,15 @@ static void write_ia_rest_uplink(
* see GSM 04.08, 9.1.18 and GSM 44.018, 9.1.18 + 10.5.2.16 * see GSM 04.08, 9.1.18 and GSM 44.018, 9.1.18 + 10.5.2.16
*/ */
int Encoding::write_immediate_assignment( int Encoding::write_immediate_assignment(
struct gprs_rlcmac_bts *bts, struct gprs_rlcmac_tbf *tbf,
bitvec * dest, uint8_t downlink, uint8_t ra, bitvec * dest, uint8_t downlink, uint8_t ra,
uint32_t ref_fn, uint8_t ta, uint16_t arfcn, uint8_t ts, uint8_t tsc, 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 usf, uint8_t polling, uint32_t fn, uint8_t alpha,
uint8_t polling, uint32_t fn, uint8_t single_block, uint8_t alpha,
uint8_t gamma, int8_t ta_idx) uint8_t gamma, int8_t ta_idx)
{ {
unsigned wp = 0; unsigned wp = 0;
uint8_t plen; int plen;
int rc;
bitvec_write_field(dest, wp,0x0,4); // Skip Indicator bitvec_write_field(dest, wp,0x0,4); // Skip Indicator
bitvec_write_field(dest, wp,0x6,4); // Protocol Discriminator bitvec_write_field(dest, wp,0x6,4); // Protocol Discriminator
@ -172,14 +182,22 @@ int Encoding::write_immediate_assignment(
plen = wp / 8; plen = wp / 8;
if (downlink) if (downlink)
write_ia_rest_downlink(dest, wp, rc = write_ia_rest_downlink(as_dl_tbf(tbf), dest, wp,
tfi, tlli, polling, fn, polling, fn,
alpha, gamma, ta_idx); alpha, gamma, ta_idx);
else else
write_ia_rest_uplink(bts, dest, wp, rc = write_ia_rest_uplink(as_ul_tbf(tbf), dest, wp,
tfi, usf, fn, single_block, usf, fn,
alpha, gamma, ta_idx); alpha, gamma, ta_idx);
if (rc < 0) {
LOGP(DRLCMAC, LOGL_ERROR,
"Failed to create IMMEDIATE ASSIGMENT (%s) for %s\n",
downlink ? "downlink" : "uplink",
tbf ? tbf->name() : "single block allocation");
return rc;
}
return plen; return plen;
} }

View File

@ -39,11 +39,11 @@ struct gprs_rlc_data_block_info;
class Encoding { class Encoding {
public: public:
static int write_immediate_assignment( static int write_immediate_assignment(
struct gprs_rlcmac_bts *bts, struct gprs_rlcmac_tbf *tbf,
bitvec * dest, uint8_t downlink, uint8_t ra, bitvec * dest, uint8_t downlink, uint8_t ra,
uint32_t ref_fn, uint8_t ta, uint16_t arfcn, uint8_t ts, uint8_t tsc, uint32_t ref_fn, uint8_t ta, uint16_t arfcn, uint8_t ts,
uint8_t tfi, uint8_t usf, uint32_t tlli, uint8_t polling, uint8_t tsc, uint8_t usf, uint8_t polling,
uint32_t fn, uint8_t single_block, uint8_t alpha, uint8_t gamma, uint32_t fn, uint8_t alpha, uint8_t gamma,
int8_t ta_idx); int8_t ta_idx);
static void write_packet_uplink_assignment( static void write_packet_uplink_assignment(