SI2q: add support for multiple UARFCNs
Support multiple UARFCNs with the same Scrambler Code. Fixes: RT#7379 Change-Id: If1c32e8b547a28325180faaaddd21f80c37f7337
This commit is contained in:
parent
881064e9b8
commit
e610e700da
|
@ -180,11 +180,40 @@ static inline void append_earfcn(struct bitvec *bv,
|
||||||
bitvec_set_bit(bv, L);
|
bitvec_set_bit(bv, L);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int append_uarfcn(struct bitvec *bv, const uint16_t *u,
|
/* Append single FDD UARFCN */
|
||||||
|
static inline int append_utran_fdd(struct bitvec *bv, uint16_t u, int *sc,
|
||||||
|
size_t length)
|
||||||
|
{
|
||||||
|
int f0, w[RANGE_ENC_MAX_ARFCNS] = { 0 };
|
||||||
|
uint8_t chan_list[16] = {0};
|
||||||
|
/* Repeated UTRAN FDD Neighbour Cells */
|
||||||
|
bitvec_set_bit(bv, 1);
|
||||||
|
|
||||||
|
/* FDD-ARFCN */
|
||||||
|
bitvec_set_bit(bv, 0);
|
||||||
|
bitvec_set_uint(bv, u, 14);
|
||||||
|
|
||||||
|
f0 = range_encode(ARFCN_RANGE_1024, sc, length, w, 0, chan_list);
|
||||||
|
if (f0 < 0)
|
||||||
|
return f0;
|
||||||
|
|
||||||
|
/* FDD_Indic0: parameter value '0000000000' is a member of the set? */
|
||||||
|
bitvec_set_bit(bv, f0);
|
||||||
|
/* NR_OF_FDD_CELLS */
|
||||||
|
bitvec_set_uint(bv, length, 5);
|
||||||
|
|
||||||
|
f0 = bv->cur_bit;
|
||||||
|
bitvec_add_range1024(bv, (struct gsm48_range_1024 *)chan_list);
|
||||||
|
bv->cur_bit = f0 + range1024_p(length);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Append multiple FDD UARFCNs */
|
||||||
|
static inline int append_uarfcns(struct bitvec *bv, const uint16_t *u,
|
||||||
const uint16_t *sc, size_t length)
|
const uint16_t *sc, size_t length)
|
||||||
{
|
{
|
||||||
int f0_inc, i, w[RANGE_ENC_MAX_ARFCNS] = { 0 }, a[length];
|
int i, j, k, rc, st = 0, a[length];
|
||||||
uint8_t chan_list[16] = {0};
|
uint16_t cu = u[0]; /* caller ensures that length is positive */
|
||||||
|
|
||||||
/* 3G Neighbour Cell Description */
|
/* 3G Neighbour Cell Description */
|
||||||
bitvec_set_bit(bv, 1);
|
bitvec_set_bit(bv, 1);
|
||||||
|
@ -198,31 +227,24 @@ static inline int append_uarfcn(struct bitvec *bv, const uint16_t *u,
|
||||||
/* No Bandwidth_FDD */
|
/* No Bandwidth_FDD */
|
||||||
bitvec_set_bit(bv, 0);
|
bitvec_set_bit(bv, 0);
|
||||||
|
|
||||||
memset(w, 0, sizeof(w));
|
for (i = 0; i < length; i++) {
|
||||||
for (i = 0; i < length; i++)
|
for (j = st, k = 0; j < i; j++)
|
||||||
a[i] = sc[i];
|
a[k++] = sc[j]; /* copy corresponding SCs */
|
||||||
|
if (u[i] != cu) { /* we've reached new UARFCN */
|
||||||
|
rc = append_utran_fdd(bv, cu, a, k);
|
||||||
|
if (rc < 0)
|
||||||
|
return rc;
|
||||||
|
cu = u[i];
|
||||||
|
st = i; /* update start position */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Note: we do not support repeating Neighbour Cells ATM */
|
/* add last UARFCN not covered by previous cycle */
|
||||||
/* Repeated UTRAN FDD Neighbour Cells */
|
for (i = st, k = 0; i < length; i++)
|
||||||
bitvec_set_bit(bv, 1);
|
a[k++] = sc[i];
|
||||||
|
rc = append_utran_fdd(bv, cu, a, k);
|
||||||
/* FDD-ARFCN */
|
if (rc < 0)
|
||||||
bitvec_set_bit(bv, 0);
|
return rc;
|
||||||
/* Note: we do not support multiple UARFCN values ATM: */
|
|
||||||
bitvec_set_uint(bv, u[0], 14);
|
|
||||||
|
|
||||||
f0_inc = range_encode(ARFCN_RANGE_1024, a, length, w, 0, chan_list);
|
|
||||||
if (f0_inc < 0)
|
|
||||||
return f0_inc;
|
|
||||||
|
|
||||||
/* FDD_Indic0: parameter value '0000000000' is not a member of the set */
|
|
||||||
bitvec_set_bit(bv, f0_inc);
|
|
||||||
/* NR_OF_FDD_CELLS */
|
|
||||||
bitvec_set_uint(bv, length, 5);
|
|
||||||
|
|
||||||
i = bv->cur_bit;
|
|
||||||
bitvec_add_range1024(bv, (struct gsm48_range_1024 *)chan_list);
|
|
||||||
bv->cur_bit = i + range1024_p(length);
|
|
||||||
|
|
||||||
/* stop bit - end of Repeated UTRAN FDD Neighbour Cells */
|
/* stop bit - end of Repeated UTRAN FDD Neighbour Cells */
|
||||||
bitvec_set_bit(bv, 0);
|
bitvec_set_bit(bv, 0);
|
||||||
|
@ -282,7 +304,8 @@ int rest_octets_si2quater(uint8_t *data, const struct osmo_earfcn_si2q *e,
|
||||||
SI2Q_MAX_LEN);
|
SI2Q_MAX_LEN);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
rc = append_uarfcn(&bv, u, sc, u_len);
|
|
||||||
|
rc = append_uarfcns(&bv, u, sc, u_len);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
LOGP(DRR, LOGL_ERROR, "SI2quater: failed to append %zu "
|
LOGP(DRR, LOGL_ERROR, "SI2quater: failed to append %zu "
|
||||||
"UARFCNs due to range encoding failure: %s\n",
|
"UARFCNs due to range encoding failure: %s\n",
|
||||||
|
|
|
@ -130,8 +130,23 @@ unsigned earfcn_size(const struct osmo_earfcn_si2q *e)
|
||||||
|
|
||||||
unsigned uarfcn_size(const uint16_t *u, const uint16_t *sc, size_t u_len)
|
unsigned uarfcn_size(const uint16_t *u, const uint16_t *sc, size_t u_len)
|
||||||
{
|
{
|
||||||
/*account for all the constant bits in append_uarfcn() */
|
/*account for all the constant bits in append_uarfcns() */
|
||||||
return 29 + range1024_p(u_len);
|
unsigned s = 7, append = 22, r = 0, i, st = 0, j, k;
|
||||||
|
uint16_t cu = u[0];
|
||||||
|
|
||||||
|
for (i = 0; i < u_len; i++) {
|
||||||
|
for (j = st, k = 0; j < i; j++, k++);
|
||||||
|
if (u[i] != cu) { /* we've reached new UARFCN */
|
||||||
|
r += (append + range1024_p(k));
|
||||||
|
cu = u[i];
|
||||||
|
st = i; /* update start position */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* add last UARFCN not covered by previous cycle */
|
||||||
|
for (i = st, k = 0; i < u_len; i++, k++);
|
||||||
|
|
||||||
|
return s + r + append + range1024_p(k);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool si2q_size_check(const struct gsm_bts *bts)
|
bool si2q_size_check(const struct gsm_bts *bts)
|
||||||
|
@ -184,7 +199,7 @@ int bts_uarfcn_del(struct gsm_bts *bts, uint16_t arfcn, uint16_t scramble)
|
||||||
int bts_uarfcn_add(struct gsm_bts *bts, uint16_t arfcn, uint16_t scramble,
|
int bts_uarfcn_add(struct gsm_bts *bts, uint16_t arfcn, uint16_t scramble,
|
||||||
bool diversity)
|
bool diversity)
|
||||||
{
|
{
|
||||||
size_t len = bts->si_common.uarfcn_length, i, k;
|
size_t len = bts->si_common.uarfcn_length, i, k = 0;
|
||||||
uint16_t scr, chk,
|
uint16_t scr, chk,
|
||||||
*ual = bts->si_common.data.uarfcn_list,
|
*ual = bts->si_common.data.uarfcn_list,
|
||||||
*scl = bts->si_common.data.scramble_list,
|
*scl = bts->si_common.data.scramble_list,
|
||||||
|
@ -197,7 +212,11 @@ int bts_uarfcn_add(struct gsm_bts *bts, uint16_t arfcn, uint16_t scramble,
|
||||||
if (len == MAX_EARFCN_LIST)
|
if (len == MAX_EARFCN_LIST)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
for (i = 0, k = 0; i < len; i++) {
|
for (i = 0; i < len; i++) /* find the position of arfcn if any */
|
||||||
|
if (arfcn == ual[i])
|
||||||
|
break;
|
||||||
|
|
||||||
|
for (k = 0; i < len; i++) {
|
||||||
if (arfcn == ual[i] && (scr == scl[i] || chk == scl[i]))
|
if (arfcn == ual[i] && (scr == scl[i] || chk == scl[i]))
|
||||||
return -EADDRINUSE;
|
return -EADDRINUSE;
|
||||||
if (scr > scl[i])
|
if (scr > scl[i])
|
||||||
|
@ -209,6 +228,7 @@ int bts_uarfcn_add(struct gsm_bts *bts, uint16_t arfcn, uint16_t scramble,
|
||||||
memmove(ual + k + 1, ual + k, (len - k) * 2);
|
memmove(ual + k + 1, ual + k, (len - k) * 2);
|
||||||
memmove(scl + k + 1, scl + k, (len - k) * 2);
|
memmove(scl + k + 1, scl + k, (len - k) * 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
ual[k] = arfcn;
|
ual[k] = arfcn;
|
||||||
scl[k] = scr;
|
scl[k] = scr;
|
||||||
bts->si_common.uarfcn_length++;
|
bts->si_common.uarfcn_length++;
|
||||||
|
|
|
@ -135,6 +135,26 @@ static inline void test_si2q_segfault(void)
|
||||||
gen(bts);
|
gen(bts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void test_si2q_mu(void)
|
||||||
|
{
|
||||||
|
struct gsm_bts *bts;
|
||||||
|
struct gsm_network *network = bsc_network_init(tall_bsc_ctx, 1, 1, NULL);
|
||||||
|
printf("Test SI2quater multiple UARFCNs:\n");
|
||||||
|
|
||||||
|
if (!network)
|
||||||
|
exit(1);
|
||||||
|
bts = gsm_bts_alloc(network);
|
||||||
|
|
||||||
|
_bts_uarfcn_add(bts, 10564, 318, 0);
|
||||||
|
_bts_uarfcn_add(bts, 10612, 319, 0);
|
||||||
|
_bts_uarfcn_add(bts, 10612, 31, 0);
|
||||||
|
_bts_uarfcn_add(bts, 10612, 19, 0);
|
||||||
|
_bts_uarfcn_add(bts, 10613, 64, 0);
|
||||||
|
_bts_uarfcn_add(bts, 10613, 164, 0);
|
||||||
|
_bts_uarfcn_add(bts, 10613, 14, 0);
|
||||||
|
gen(bts);
|
||||||
|
}
|
||||||
|
|
||||||
static inline void test_si2q_u(void)
|
static inline void test_si2q_u(void)
|
||||||
{
|
{
|
||||||
struct gsm_bts *bts;
|
struct gsm_bts *bts;
|
||||||
|
@ -608,6 +628,7 @@ int main(int argc, char **argv)
|
||||||
test_si2q_segfault();
|
test_si2q_segfault();
|
||||||
test_si2q_e();
|
test_si2q_e();
|
||||||
test_si2q_u();
|
test_si2q_u();
|
||||||
|
test_si2q_mu();
|
||||||
printf("Done.\n");
|
printf("Done.\n");
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,8 +64,8 @@ Allocated reference: 0
|
||||||
Allocated reference: 1
|
Allocated reference: 1
|
||||||
Test SI2quater UARFCN (same scrambling code and diversity):
|
Test SI2quater UARFCN (same scrambling code and diversity):
|
||||||
generated valid SI2quater: [23] 59 06 07 c0 00 25 52 88 0a 7e 10 99 64 00 0b 2b 2b 2b 2b 2b 2b 2b 2b
|
generated valid SI2quater: [23] 59 06 07 c0 00 25 52 88 0a 7e 10 99 64 00 0b 2b 2b 2b 2b 2b 2b 2b 2b
|
||||||
failed to generate SI2quater: Invalid argument
|
generated valid SI2quater: [23] 59 06 07 c0 00 25 52 e8 0a 7f 52 88 0a 7e 10 99 64 00 0b 2b 2b 2b 2b
|
||||||
failed to generate SI2quater: Invalid argument
|
generated valid SI2quater: [23] 59 06 07 c0 00 25 52 e8 0a 7f 52 88 0a 7e 10 99 64 00 0b 2b 2b 2b 2b
|
||||||
Testing SYSINFO_TYPE_2quater EARFCN generation:
|
Testing SYSINFO_TYPE_2quater EARFCN generation:
|
||||||
generated invalid SI2quater: [23] 59 06 07 c0 00 04 86 59 0a 03 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b
|
generated invalid SI2quater: [23] 59 06 07 c0 00 04 86 59 0a 03 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b
|
||||||
added EARFCN 1917 - generated valid SI2quater: [23] 59 06 07 c0 00 04 86 59 83 be c8 50 0b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b
|
added EARFCN 1917 - generated valid SI2quater: [23] 59 06 07 c0 00 04 86 59 83 be c8 50 0b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b
|
||||||
|
@ -89,4 +89,13 @@ generated valid SI2quater: [23] 59 06 07 c0 00 25 0f 7c 4c 7a 34 0e 64 77 85 43
|
||||||
failed to add UARFCN to SI2quater: No space left on device
|
failed to add UARFCN to SI2quater: No space left on device
|
||||||
failed to add UARFCN to SI2quater: No space left on device
|
failed to add UARFCN to SI2quater: No space left on device
|
||||||
generated valid SI2quater: [23] 59 06 07 c0 00 25 0f 7c 4c 7a 34 0e 64 77 85 43 55 c8 10 99 64 00 0b
|
generated valid SI2quater: [23] 59 06 07 c0 00 25 0f 7c 4c 7a 34 0e 64 77 85 43 55 c8 10 99 64 00 0b
|
||||||
|
Test SI2quater multiple UARFCNs:
|
||||||
|
generated valid SI2quater: [23] 59 06 07 c0 00 25 52 88 0a 7c 10 99 64 00 0b 2b 2b 2b 2b 2b 2b 2b 2b
|
||||||
|
generated valid SI2quater: [23] 59 06 07 c0 00 25 52 e8 0a 7f 52 88 0a 7c 10 99 64 00 0b 2b 2b 2b 2b
|
||||||
|
generated valid SI2quater: [23] 59 06 07 c0 00 25 52 e8 12 7e e0 a9 44 05 3e 00 44 b2 00 03 2b 2b 2b
|
||||||
|
generated valid SI2quater: [23] 59 06 07 c0 00 25 52 e8 18 3f f4 90 54 a2 02 9f 04 86 59 00 03 2b 2b
|
||||||
|
failed to add UARFCN to SI2quater: No space left on device
|
||||||
|
failed to add UARFCN to SI2quater: No space left on device
|
||||||
|
failed to add UARFCN to SI2quater: No space left on device
|
||||||
|
generated valid SI2quater: [23] 59 06 07 c0 00 25 52 e8 18 3f f4 90 54 a2 02 9f 04 86 59 00 03 2b 2b
|
||||||
Done.
|
Done.
|
||||||
|
|
Loading…
Reference in New Issue