Restructure SI2quater generation
In preparation for extended SI2q messages: * add SI2q-specific accessor macro * add *_offset variables to gsm_bts struct * internalize memory check while generating rest octets - introduce budget concept (number of bits available in a given message) * internalize *arfcn_size() functions as they are not needed outside of si2q_num() anymore * change rest octets generation to work with gsm_bts struct directly * do not generate rest octets if no SI2q is necessary * adjust unit tests accordingly (cosmetic changes only to avoid regressions) Requires: I92e12e91605bdab9916a3f665705287572434f74 in libosmocore Change-Id: Ib554cf7ffc949a321571e1ae2ada1160e1b35fa6 Related: RT#8792
This commit is contained in:
parent
1ebf23b7fe
commit
f39d03ad21
|
@ -25,6 +25,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <openbsc/common_cs.h>
|
#include <openbsc/common_cs.h>
|
||||||
|
#include <openbsc/rest_octets.h>
|
||||||
|
|
||||||
struct osmo_bsc_data;
|
struct osmo_bsc_data;
|
||||||
|
|
||||||
|
@ -485,6 +486,7 @@ struct gsm_bts_trx {
|
||||||
struct gsm_bts_trx_ts ts[TRX_NR_TS];
|
struct gsm_bts_trx_ts ts[TRX_NR_TS];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define GSM_BTS_SI2Q(bts) (struct gsm48_system_information_type_2quater *)((bts)->si_buf[SYSINFO_TYPE_2quater])
|
||||||
#define GSM_BTS_SI(bts, i) (void *)((bts)->si_buf[i])
|
#define GSM_BTS_SI(bts, i) (void *)((bts)->si_buf[i])
|
||||||
#define GSM_LCHAN_SI(lchan, i) (void *)((lchan)->si.buf[i])
|
#define GSM_LCHAN_SI(lchan, i) (void *)((lchan)->si.buf[i])
|
||||||
|
|
||||||
|
@ -717,10 +719,13 @@ struct gsm_bts {
|
||||||
/* bitmask of all SI that are present/valid in si_buf */
|
/* bitmask of all SI that are present/valid in si_buf */
|
||||||
uint32_t si_valid;
|
uint32_t si_valid;
|
||||||
/* 3GPP TS 44.018 Table 10.5.2.33b.1 INDEX and COUNT for SI2quater */
|
/* 3GPP TS 44.018 Table 10.5.2.33b.1 INDEX and COUNT for SI2quater */
|
||||||
uint8_t si2q_index;
|
uint8_t si2q_index; /* distinguish individual SI2quater messages */
|
||||||
uint8_t si2q_count;
|
uint8_t si2q_count; /* si2q_index for the last (highest indexed) individual SI2quater message */
|
||||||
/* buffers where we put the pre-computed SI */
|
/* buffers where we put the pre-computed SI */
|
||||||
sysinfo_buf_t si_buf[_MAX_SYSINFO_TYPE];
|
sysinfo_buf_t si_buf[_MAX_SYSINFO_TYPE];
|
||||||
|
/* offsets used while generating SI2quater */
|
||||||
|
size_t e_offset;
|
||||||
|
size_t u_offset;
|
||||||
|
|
||||||
/* ip.accesss Unit ID's have Site/BTS/TRX layout */
|
/* ip.accesss Unit ID's have Site/BTS/TRX layout */
|
||||||
union {
|
union {
|
||||||
|
|
|
@ -13,8 +13,7 @@
|
||||||
|
|
||||||
/* generate SI1 rest octets */
|
/* generate SI1 rest octets */
|
||||||
int rest_octets_si1(uint8_t *data, uint8_t *nch_pos, int is1800_net);
|
int rest_octets_si1(uint8_t *data, uint8_t *nch_pos, int is1800_net);
|
||||||
int rest_octets_si2quater(uint8_t *data, uint8_t index, uint8_t count, const struct osmo_earfcn_si2q *e,
|
int rest_octets_si2quater(uint8_t *data, struct gsm_bts *bts);
|
||||||
const uint16_t *u, const uint16_t *sc, size_t u_len);
|
|
||||||
int rest_octets_si6(uint8_t *data, bool is1800_net);
|
int rest_octets_si6(uint8_t *data, bool is1800_net);
|
||||||
|
|
||||||
struct gsm48_si_selection_params {
|
struct gsm48_si_selection_params {
|
||||||
|
|
|
@ -8,13 +8,12 @@
|
||||||
struct gsm_bts;
|
struct gsm_bts;
|
||||||
|
|
||||||
int gsm_generate_si(struct gsm_bts *bts, enum osmo_sysinfo_type type);
|
int gsm_generate_si(struct gsm_bts *bts, enum osmo_sysinfo_type type);
|
||||||
unsigned uarfcn_size(const uint16_t *u, const uint16_t *sc, size_t u_len);
|
size_t si2q_earfcn_count(const struct osmo_earfcn_si2q *e);
|
||||||
unsigned earfcn_size(const struct osmo_earfcn_si2q *e);
|
|
||||||
unsigned range1024_p(unsigned n);
|
unsigned range1024_p(unsigned n);
|
||||||
unsigned range512_q(unsigned m);
|
unsigned range512_q(unsigned m);
|
||||||
int range_encode(enum gsm48_range r, int *arfcns, int arfcns_used, int *w,
|
int range_encode(enum gsm48_range r, int *arfcns, int arfcns_used, int *w,
|
||||||
int f0, uint8_t *chan_list);
|
int f0, uint8_t *chan_list);
|
||||||
uint8_t si2q_num(const struct gsm_bts *bts);
|
uint8_t si2q_num(struct gsm_bts *bts);
|
||||||
int bts_uarfcn_del(struct gsm_bts *bts, uint16_t arfcn, uint16_t scramble);
|
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);
|
||||||
|
|
|
@ -2829,11 +2829,11 @@ DEFUN(cfg_bts_si2quater_neigh_add, cfg_bts_si2quater_neigh_add_cmd,
|
||||||
e->prio_valid = true;
|
e->prio_valid = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (si2q_num(bts) < 2)
|
if (si2q_num(bts) < 2) /* FIXME: use SI2Q_MAX_NUM */
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
|
|
||||||
vty_out(vty, "Warning: not enough space in SI2quater for a given EARFCN "
|
vty_out(vty, "Warning: not enough space in SI2quater (%u/%u used) for a given EARFCN %u%s",
|
||||||
"%u%s", arfcn, VTY_NEWLINE);
|
bts->si2q_count, 2, arfcn, VTY_NEWLINE); /* FIXME: use SI2Q_MAX_NUM */
|
||||||
osmo_earfcn_del(e, arfcn);
|
osmo_earfcn_del(e, arfcn);
|
||||||
|
|
||||||
return CMD_WARNING;
|
return CMD_WARNING;
|
||||||
|
|
|
@ -58,31 +58,64 @@ int rest_octets_si1(uint8_t *data, uint8_t *nch_pos, int is1800_net)
|
||||||
return bv.data_len;
|
return bv.data_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Append Repeated E-UTRAN Neighbour Cell to bitvec:
|
/* Append Repeated E-UTRAN Neighbour Cell to bitvec: see 3GPP TS 44.018 Table 10.5.2.33b.1 */
|
||||||
* see 3GPP TS 44.018 Table 10.5.2.33b.1
|
static inline void append_eutran_neib_cell(struct bitvec *bv, struct gsm_bts *bts, uint8_t budget)
|
||||||
*/
|
|
||||||
static inline void append_eutran_neib_cell(struct bitvec *bv,
|
|
||||||
const struct osmo_earfcn_si2q *e)
|
|
||||||
{
|
{
|
||||||
unsigned i;
|
const struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list;
|
||||||
|
unsigned i, skip = 0;
|
||||||
|
size_t offset = bts->e_offset;
|
||||||
|
uint8_t rem = budget - 6, earfcn_budget; /* account for mandatory stop bit and THRESH_E-UTRAN_high */
|
||||||
|
/* first we have to properly adjust budget requirements */
|
||||||
|
if (e->prio_valid) /* E-UTRAN_PRIORITY: 3GPP TS 45.008*/
|
||||||
|
rem -= 4;
|
||||||
|
else
|
||||||
|
rem--;
|
||||||
|
|
||||||
|
if (e->thresh_lo_valid) /* THRESH_E-UTRAN_low: */
|
||||||
|
rem -= 6;
|
||||||
|
else
|
||||||
|
rem--;
|
||||||
|
|
||||||
|
if (e->qrxlm_valid) /* E-UTRAN_QRXLEVMIN: */
|
||||||
|
rem -= 6;
|
||||||
|
else
|
||||||
|
rem--;
|
||||||
|
|
||||||
|
/* now we can proceed with actually adding EARFCNs within adjusted budget limit */
|
||||||
for (i = 0; i < e->length; i++) {
|
for (i = 0; i < e->length; i++) {
|
||||||
if (e->arfcn[i] != OSMO_EARFCN_INVALID) {
|
if (e->arfcn[i] != OSMO_EARFCN_INVALID) {
|
||||||
|
if (skip < offset) {
|
||||||
|
skip++; /* ignore EARFCNs added on previous calls */
|
||||||
|
} else {
|
||||||
|
earfcn_budget = 17; /* computer budget per-EARFCN */
|
||||||
|
if (OSMO_EARFCN_MEAS_INVALID == e->meas_bw[i])
|
||||||
|
earfcn_budget++;
|
||||||
|
else
|
||||||
|
earfcn_budget += 4;
|
||||||
|
|
||||||
|
if (rem - earfcn_budget < 0) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
bts->e_offset++;
|
||||||
bitvec_set_bit(bv, 1); /* EARFCN: */
|
bitvec_set_bit(bv, 1); /* EARFCN: */
|
||||||
bitvec_set_uint(bv, e->arfcn[i], 16);
|
bitvec_set_uint(bv, e->arfcn[i], 16);
|
||||||
|
|
||||||
if (OSMO_EARFCN_MEAS_INVALID == e->meas_bw[i])
|
if (OSMO_EARFCN_MEAS_INVALID == e->meas_bw[i])
|
||||||
bitvec_set_bit(bv, 0);
|
bitvec_set_bit(bv, 0);
|
||||||
else {
|
else { /* Measurement Bandwidth: 9.1.54 */
|
||||||
/* Measurement Bandwidth: 9.1.54 */
|
|
||||||
bitvec_set_bit(bv, 1);
|
bitvec_set_bit(bv, 1);
|
||||||
bitvec_set_uint(bv, e->meas_bw[i], 3);
|
bitvec_set_uint(bv, e->meas_bw[i], 3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* stop bit - end of EARFCN + Measurement Bandwidth sequence */
|
/* stop bit - end of EARFCN + Measurement Bandwidth sequence */
|
||||||
bitvec_set_bit(bv, 0);
|
bitvec_set_bit(bv, 0);
|
||||||
|
|
||||||
|
/* Note: we don't support different EARFCN arrays each with different priority, threshold etc. */
|
||||||
|
|
||||||
if (e->prio_valid) {
|
if (e->prio_valid) {
|
||||||
/* E-UTRAN_PRIORITY: 3GPP TS 45.008*/
|
/* E-UTRAN_PRIORITY: 3GPP TS 45.008*/
|
||||||
bitvec_set_bit(bv, 1);
|
bitvec_set_bit(bv, 1);
|
||||||
|
@ -108,8 +141,7 @@ static inline void append_eutran_neib_cell(struct bitvec *bv,
|
||||||
bitvec_set_bit(bv, 0);
|
bitvec_set_bit(bv, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void append_earfcn(struct bitvec *bv,
|
static inline void append_earfcn(struct bitvec *bv, struct gsm_bts *bts, uint8_t budget)
|
||||||
const struct osmo_earfcn_si2q *e)
|
|
||||||
{
|
{
|
||||||
/* Additions in Rel-5: */
|
/* Additions in Rel-5: */
|
||||||
bitvec_set_bit(bv, H);
|
bitvec_set_bit(bv, H);
|
||||||
|
@ -158,9 +190,8 @@ static inline void append_earfcn(struct bitvec *bv,
|
||||||
/* Repeated E-UTRAN Neighbour Cells */
|
/* Repeated E-UTRAN Neighbour Cells */
|
||||||
bitvec_set_bit(bv, 1);
|
bitvec_set_bit(bv, 1);
|
||||||
|
|
||||||
/* Note: we don't support different EARFCN arrays each with different
|
/* N. B: 25 bits are set in append_earfcn() - keep it in sync with budget adjustment below: */
|
||||||
priority, threshold etc. */
|
append_eutran_neib_cell(bv, bts, budget - 25);
|
||||||
append_eutran_neib_cell(bv, e);
|
|
||||||
|
|
||||||
/* stop bit - end of Repeated E-UTRAN Neighbour Cells sequence: */
|
/* stop bit - end of Repeated E-UTRAN Neighbour Cells sequence: */
|
||||||
bitvec_set_bit(bv, 0);
|
bitvec_set_bit(bv, 0);
|
||||||
|
@ -180,12 +211,37 @@ static inline void append_earfcn(struct bitvec *bv,
|
||||||
bitvec_set_bit(bv, L);
|
bitvec_set_bit(bv, L);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Append single FDD UARFCN */
|
static inline int f0_helper(int *sc, size_t length, uint8_t *chan_list)
|
||||||
static inline int append_utran_fdd(struct bitvec *bv, uint16_t u, int *sc,
|
{
|
||||||
size_t length)
|
int w[RANGE_ENC_MAX_ARFCNS] = { 0 };
|
||||||
|
|
||||||
|
return range_encode(ARFCN_RANGE_1024, sc, length, w, 0, chan_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Estimate how many bits it'll take to append single FDD UARFCN */
|
||||||
|
static inline int append_utran_fdd_length(uint16_t u, int *sc, size_t sc_len, size_t length)
|
||||||
{
|
{
|
||||||
int f0, w[RANGE_ENC_MAX_ARFCNS] = { 0 };
|
|
||||||
uint8_t chan_list[16] = { 0 };
|
uint8_t chan_list[16] = { 0 };
|
||||||
|
int tmp[sc_len], f0;
|
||||||
|
|
||||||
|
memcpy(tmp, sc, sizeof(tmp));
|
||||||
|
|
||||||
|
f0 = f0_helper(tmp, length, chan_list);
|
||||||
|
if (f0 < 0)
|
||||||
|
return f0;
|
||||||
|
|
||||||
|
return 21 + range1024_p(length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Append single FDD UARFCN */
|
||||||
|
static inline int append_utran_fdd(struct bitvec *bv, uint16_t u, int *sc, size_t length)
|
||||||
|
{
|
||||||
|
uint8_t chan_list[16] = { 0 };
|
||||||
|
int f0 = f0_helper(sc, length, chan_list);
|
||||||
|
|
||||||
|
if (f0 < 0)
|
||||||
|
return f0;
|
||||||
|
|
||||||
/* Repeated UTRAN FDD Neighbour Cells */
|
/* Repeated UTRAN FDD Neighbour Cells */
|
||||||
bitvec_set_bit(bv, 1);
|
bitvec_set_bit(bv, 1);
|
||||||
|
|
||||||
|
@ -193,10 +249,6 @@ static inline int append_utran_fdd(struct bitvec *bv, uint16_t u, int *sc,
|
||||||
bitvec_set_bit(bv, 0);
|
bitvec_set_bit(bv, 0);
|
||||||
bitvec_set_uint(bv, u, 14);
|
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? */
|
/* FDD_Indic0: parameter value '0000000000' is a member of the set? */
|
||||||
bitvec_set_bit(bv, f0);
|
bitvec_set_bit(bv, f0);
|
||||||
/* NR_OF_FDD_CELLS */
|
/* NR_OF_FDD_CELLS */
|
||||||
|
@ -205,15 +257,17 @@ static inline int append_utran_fdd(struct bitvec *bv, uint16_t u, int *sc,
|
||||||
f0 = bv->cur_bit;
|
f0 = bv->cur_bit;
|
||||||
bitvec_add_range1024(bv, (struct gsm48_range_1024 *)chan_list);
|
bitvec_add_range1024(bv, (struct gsm48_range_1024 *)chan_list);
|
||||||
bv->cur_bit = f0 + range1024_p(length);
|
bv->cur_bit = f0 + range1024_p(length);
|
||||||
return 0;
|
|
||||||
|
return 21 + range1024_p(length);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Append multiple FDD UARFCNs */
|
/* Append multiple FDD UARFCNs */
|
||||||
static inline int append_uarfcns(struct bitvec *bv, const uint16_t *u,
|
static inline int append_uarfcns(struct bitvec *bv, struct gsm_bts *bts, uint8_t budget)
|
||||||
const uint16_t *sc, size_t length)
|
|
||||||
{
|
{
|
||||||
int i, j, k, rc, st = 0, a[length];
|
const uint16_t *u = bts->si_common.data.uarfcn_list, *sc = bts->si_common.data.scramble_list;
|
||||||
uint16_t cu = u[0]; /* caller ensures that length is positive */
|
int i, j, k, rc, st = 0, a[bts->si_common.uarfcn_length];
|
||||||
|
uint16_t cu = u[bts->u_offset]; /* caller ensures that length is positive */
|
||||||
|
uint8_t rem = budget - 7; /* account for constant bits right away */
|
||||||
|
|
||||||
/* 3G Neighbour Cell Description */
|
/* 3G Neighbour Cell Description */
|
||||||
bitvec_set_bit(bv, 1);
|
bitvec_set_bit(bv, 1);
|
||||||
|
@ -227,24 +281,41 @@ static inline int append_uarfcns(struct bitvec *bv, const uint16_t *u,
|
||||||
/* No Bandwidth_FDD */
|
/* No Bandwidth_FDD */
|
||||||
bitvec_set_bit(bv, 0);
|
bitvec_set_bit(bv, 0);
|
||||||
|
|
||||||
for (i = 0; i < length; i++) {
|
for (i = bts->u_offset; i < bts->si_common.uarfcn_length; i++) {
|
||||||
for (j = st, k = 0; j < i; j++)
|
for (j = st, k = 0; j < i; j++)
|
||||||
a[k++] = sc[j]; /* copy corresponding SCs */
|
a[k++] = sc[j]; /* copy corresponding SCs */
|
||||||
|
|
||||||
if (u[i] != cu) { /* we've reached new UARFCN */
|
if (u[i] != cu) { /* we've reached new UARFCN */
|
||||||
rc = append_utran_fdd(bv, cu, a, k);
|
rc = append_utran_fdd_length(cu, a, bts->si_common.uarfcn_length, k);
|
||||||
if (rc < 0)
|
if (rc < 0) { /* estimate bit length requirements */
|
||||||
return rc;
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rem - rc < 0) {
|
||||||
|
break; /* we have ran out of budget in current SI2q */
|
||||||
|
} else {
|
||||||
|
rem -= append_utran_fdd(bv, cu, a, k);
|
||||||
|
bts->u_offset++;
|
||||||
|
}
|
||||||
cu = u[i];
|
cu = u[i];
|
||||||
st = i; /* update start position */
|
st = i; /* update start position */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add last UARFCN not covered by previous cycle */
|
if (rem > 22) { /* add last UARFCN not covered by previous cycle if it could possibly fit into budget */
|
||||||
for (i = st, k = 0; i < length; i++)
|
for (i = st, k = 0; i < bts->si_common.uarfcn_length; i++)
|
||||||
a[k++] = sc[i];
|
a[k++] = sc[i];
|
||||||
rc = append_utran_fdd(bv, cu, a, k);
|
|
||||||
if (rc < 0)
|
rc = append_utran_fdd_length(cu, a, bts->si_common.uarfcn_length, k);
|
||||||
|
if (rc < 0) {
|
||||||
return rc;
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rem - rc >= 0) {
|
||||||
|
rem -= append_utran_fdd(bv, cu, a, k);
|
||||||
|
bts->u_offset++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* 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);
|
||||||
|
@ -256,11 +327,9 @@ static inline int append_uarfcns(struct bitvec *bv, const uint16_t *u,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* generate SI2quater rest octets: 3GPP TS 44.018 § 10.5.2.33b */
|
/* generate SI2quater rest octets: 3GPP TS 44.018 § 10.5.2.33b */
|
||||||
int rest_octets_si2quater(uint8_t *data, uint8_t index, uint8_t count, const struct osmo_earfcn_si2q *e,
|
int rest_octets_si2quater(uint8_t *data, struct gsm_bts *bts)
|
||||||
const uint16_t *u, const uint16_t *sc, size_t u_len)
|
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
unsigned sz;
|
|
||||||
struct bitvec bv;
|
struct bitvec bv;
|
||||||
bv.data = data;
|
bv.data = data;
|
||||||
bv.data_len = 20;
|
bv.data_len = 20;
|
||||||
|
@ -273,11 +342,10 @@ int rest_octets_si2quater(uint8_t *data, uint8_t index, uint8_t count, const str
|
||||||
/* MP_CHANGE_MARK */
|
/* MP_CHANGE_MARK */
|
||||||
bitvec_set_bit(&bv, 0);
|
bitvec_set_bit(&bv, 0);
|
||||||
|
|
||||||
/* we do not support multiple si2quater messages at the moment: */
|
|
||||||
/* SI2quater_INDEX */
|
/* SI2quater_INDEX */
|
||||||
bitvec_set_uint(&bv, index, 4);
|
bitvec_set_uint(&bv, bts->si2q_index, 4);
|
||||||
/* SI2quater_COUNT */
|
/* SI2quater_COUNT */
|
||||||
bitvec_set_uint(&bv, count, 4);
|
bitvec_set_uint(&bv, bts->si2q_count, 4);
|
||||||
|
|
||||||
/* No Measurement_Parameters Description */
|
/* No Measurement_Parameters Description */
|
||||||
bitvec_set_bit(&bv, 0);
|
bitvec_set_bit(&bv, 0);
|
||||||
|
@ -294,22 +362,12 @@ int rest_octets_si2quater(uint8_t *data, uint8_t index, uint8_t count, const str
|
||||||
/* No extension (length) */
|
/* No extension (length) */
|
||||||
bitvec_set_bit(&bv, 0);
|
bitvec_set_bit(&bv, 0);
|
||||||
|
|
||||||
if (u_len) {
|
if (bts->si_common.uarfcn_length) {
|
||||||
sz = uarfcn_size(u, sc, u_len);
|
|
||||||
/* Even if we do not append EARFCN we still need to set 3 bits */
|
/* Even if we do not append EARFCN we still need to set 3 bits */
|
||||||
if (sz + bv.cur_bit + 3 > SI2Q_MAX_LEN) {
|
rc = append_uarfcns(&bv, bts, SI2Q_MAX_LEN - (bv.cur_bit + 3));
|
||||||
LOGP(DRR, LOGL_ERROR, "SI2quater: not enough memory to "
|
|
||||||
"add UARFCNs bits, current %u + required %u + "
|
|
||||||
"reminder %u > max %u\n", bv.cur_bit, sz, 3,
|
|
||||||
SI2Q_MAX_LEN);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
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",
|
bts->si_common.uarfcn_length, strerror(-rc));
|
||||||
u_len, strerror(-rc));
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
} else { /* No 3G Neighbour Cell Description */
|
} else { /* No 3G Neighbour Cell Description */
|
||||||
|
@ -321,15 +379,14 @@ int rest_octets_si2quater(uint8_t *data, uint8_t index, uint8_t count, const str
|
||||||
/* No GPRS_3G_MEASUREMENT Parameters Descr. */
|
/* No GPRS_3G_MEASUREMENT Parameters Descr. */
|
||||||
bitvec_set_bit(&bv, 0);
|
bitvec_set_bit(&bv, 0);
|
||||||
|
|
||||||
if (e) {
|
if (&bts->si_common.si2quater_neigh_list) { /* FIXME: use si2q_earfcn_count() in if */
|
||||||
sz = earfcn_size(e);
|
append_earfcn(&bv, bts, SI2Q_MAX_LEN - bv.cur_bit);
|
||||||
if (sz + bv.cur_bit > SI2Q_MAX_LEN) {
|
|
||||||
LOGP(DRR, LOGL_ERROR, "SI2quater: not enough memory to "
|
/* FIXME: remove following check once multiple SI2q are properly supported */
|
||||||
"add EARFCNs bits, current %u + required %u > max "
|
if ((bts->e_offset != si2q_earfcn_count(&bts->si_common.si2quater_neigh_list)) ||
|
||||||
"%u\n", bv.cur_bit, sz, SI2Q_MAX_LEN);
|
si2q_earfcn_count(&bts->si_common.si2quater_neigh_list) > 5)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
|
||||||
append_earfcn(&bv, e);
|
|
||||||
} else {
|
} else {
|
||||||
/* No Additions in Rel-5: */
|
/* No Additions in Rel-5: */
|
||||||
bitvec_set_bit(&bv, L);
|
bitvec_set_bit(&bv, L);
|
||||||
|
|
|
@ -122,19 +122,22 @@ unsigned range512_q(unsigned m)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned earfcn_size(const struct osmo_earfcn_si2q *e)
|
static inline unsigned earfcn_size(const struct gsm_bts *bts)
|
||||||
{
|
{
|
||||||
|
const struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list; /* EARFCN */
|
||||||
|
|
||||||
/* account for all the constant bits in append_earfcn() */
|
/* account for all the constant bits in append_earfcn() */
|
||||||
return 25 + osmo_earfcn_bit_size(e);
|
return 25 + osmo_earfcn_bit_size_ext(e, bts->e_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned uarfcn_size(const uint16_t *u, const uint16_t *sc, size_t u_len)
|
static inline unsigned uarfcn_size(const struct gsm_bts *bts)
|
||||||
{
|
{
|
||||||
|
const uint16_t *u = bts->si_common.data.uarfcn_list;
|
||||||
|
uint16_t cu = u[bts->u_offset]; /* UARFCN */
|
||||||
/* account for all the constant bits in append_uarfcns() */
|
/* account for all the constant bits in append_uarfcns() */
|
||||||
unsigned s = 7, append = 22, r = 0, i, st = 0, j, k;
|
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 (i = bts->u_offset; i < bts->si_common.uarfcn_length; i++) {
|
||||||
for (j = st, k = 0; j < i; j++, k++);
|
for (j = st, k = 0; j < i; j++, k++);
|
||||||
if (u[i] != cu) { /* we've reached new UARFCN */
|
if (u[i] != cu) { /* we've reached new UARFCN */
|
||||||
r += (append + range1024_p(k));
|
r += (append + range1024_p(k));
|
||||||
|
@ -144,18 +147,25 @@ unsigned uarfcn_size(const uint16_t *u, const uint16_t *sc, size_t u_len)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add last UARFCN not covered by previous cycle */
|
/* add last UARFCN not covered by previous cycle */
|
||||||
for (i = st, k = 0; i < u_len; i++, k++);
|
for (i = st, k = 0; i < bts->si_common.uarfcn_length; i++, k++);
|
||||||
|
|
||||||
return s + r + append + range1024_p(k);
|
return s + r + append + range1024_p(k);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t si2q_num(const struct gsm_bts *bts)
|
uint8_t si2q_num(struct gsm_bts *bts)
|
||||||
{
|
{
|
||||||
const struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list; /* EARFCN */
|
size_t est, e_sz = 1, u_sz = 1;
|
||||||
const uint16_t *u = bts->si_common.data.uarfcn_list, *sc = bts->si_common.data.scramble_list; /* UARFCN */
|
|
||||||
size_t l = bts->si_common.uarfcn_length, e_sz = e ? earfcn_size(e) : 1, u_sz = l ? uarfcn_size(u, sc, l) : 1;
|
if (&bts->si_common.si2quater_neigh_list) /* EARFCN */
|
||||||
|
e_sz = earfcn_size(bts);
|
||||||
|
|
||||||
|
if (bts->si_common.uarfcn_length) /* UARFCN */
|
||||||
|
u_sz = uarfcn_size(bts);
|
||||||
|
|
||||||
/* 2 bits are used in between UARFCN and EARFCN structs */
|
/* 2 bits are used in between UARFCN and EARFCN structs */
|
||||||
return 1 + (e_sz + u_sz) / (SI2Q_MAX_LEN - (SI2Q_MIN_LEN + 2));
|
est = 1 + (e_sz + u_sz) / (SI2Q_MAX_LEN - (SI2Q_MIN_LEN + 2));
|
||||||
|
|
||||||
|
return est;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 3GPP TS 44.018, Table 9.1.54.1 - prepend diversity bit to scrambling code */
|
/* 3GPP TS 44.018, Table 9.1.54.1 - prepend diversity bit to scrambling code */
|
||||||
|
@ -191,8 +201,7 @@ int bts_uarfcn_del(struct gsm_bts *bts, uint16_t arfcn, uint16_t scramble)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
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 = 0;
|
size_t len = bts->si_common.uarfcn_length, i, k = 0;
|
||||||
uint16_t scr, chk,
|
uint16_t scr, chk,
|
||||||
|
@ -228,7 +237,7 @@ int bts_uarfcn_add(struct gsm_bts *bts, uint16_t arfcn, uint16_t scramble,
|
||||||
scl[k] = scr;
|
scl[k] = scr;
|
||||||
bts->si_common.uarfcn_length++;
|
bts->si_common.uarfcn_length++;
|
||||||
|
|
||||||
if (si2q_num(bts) < 2)
|
if (si2q_num(bts) < 2) /* FIXME: use SI2Q_MAX_NUM */
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
bts_uarfcn_del(bts, arfcn, scramble);
|
bts_uarfcn_del(bts, arfcn, scramble);
|
||||||
|
@ -662,11 +671,41 @@ static int generate_si2ter(enum osmo_sysinfo_type t, struct gsm_bts *bts)
|
||||||
return sizeof(*si2t);
|
return sizeof(*si2t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* SI2quater messages are optional - we only generate them when neighbor UARFCNs or EARFCNs are configured */
|
||||||
|
static inline bool si2quater_not_needed(struct gsm_bts *bts)
|
||||||
|
{
|
||||||
|
unsigned i = MAX_EARFCN_LIST;
|
||||||
|
|
||||||
|
if (bts->si_common.si2quater_neigh_list.arfcn)
|
||||||
|
for (i = 0; i < MAX_EARFCN_LIST; i++)
|
||||||
|
if (bts->si_common.si2quater_neigh_list.arfcn[i] != OSMO_EARFCN_INVALID)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (!bts->si_common.uarfcn_length && i == MAX_EARFCN_LIST) {
|
||||||
|
bts->si_valid &= ~(1 << SYSINFO_TYPE_2quater); /* mark SI2q as invalid if no (E|U)ARFCNs are present */
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t si2q_earfcn_count(const struct osmo_earfcn_si2q *e)
|
||||||
|
{
|
||||||
|
unsigned i, ret = 0;
|
||||||
|
for (i = 0; i < e->length; i++)
|
||||||
|
if (e->arfcn[i] != OSMO_EARFCN_INVALID)
|
||||||
|
ret++;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int generate_si2quater(enum osmo_sysinfo_type t, struct gsm_bts *bts)
|
static int generate_si2quater(enum osmo_sysinfo_type t, struct gsm_bts *bts)
|
||||||
{
|
{
|
||||||
int rc, i = MAX_EARFCN_LIST;
|
int rc;
|
||||||
struct gsm48_system_information_type_2quater *si2q =
|
struct gsm48_system_information_type_2quater *si2q = GSM_BTS_SI2Q(bts);
|
||||||
(struct gsm48_system_information_type_2quater *) GSM_BTS_SI(bts, t);
|
|
||||||
|
if (si2quater_not_needed(bts)) /* generate rest_octets for SI2q only when necessary */
|
||||||
|
return GSM_MACBLOCK_LEN;
|
||||||
|
|
||||||
memset(si2q, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN);
|
memset(si2q, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN);
|
||||||
|
|
||||||
|
@ -675,22 +714,10 @@ static int generate_si2quater(enum osmo_sysinfo_type t, struct gsm_bts *bts)
|
||||||
si2q->header.skip_indicator = 0;
|
si2q->header.skip_indicator = 0;
|
||||||
si2q->header.system_information = GSM48_MT_RR_SYSINFO_2quater;
|
si2q->header.system_information = GSM48_MT_RR_SYSINFO_2quater;
|
||||||
|
|
||||||
rc = rest_octets_si2quater(si2q->rest_octets, bts->si2q_index, bts->si2q_count,
|
rc = rest_octets_si2quater(si2q->rest_octets, bts);
|
||||||
&bts->si_common.si2quater_neigh_list,
|
|
||||||
bts->si_common.data.uarfcn_list,
|
|
||||||
bts->si_common.data.scramble_list,
|
|
||||||
bts->si_common.uarfcn_length);
|
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
if (bts->si_common.si2quater_neigh_list.arfcn)
|
|
||||||
for (i = 0; i < MAX_EARFCN_LIST; i++)
|
|
||||||
if (bts->si_common.si2quater_neigh_list.arfcn[i] !=
|
|
||||||
OSMO_EARFCN_INVALID)
|
|
||||||
break;
|
|
||||||
if (!bts->si_common.uarfcn_length && i == MAX_EARFCN_LIST)
|
|
||||||
bts->si_valid &= ~(1 << SYSINFO_TYPE_2quater);
|
|
||||||
|
|
||||||
return sizeof(*si2q) + rc;
|
return sizeof(*si2q) + rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -84,18 +84,12 @@ static void test_location_area_identifier(void)
|
||||||
COMPARE(lai48.lac, ==, htons(0x000f));
|
COMPARE(lai48.lac, ==, htons(0x000f));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void add_arfcn_b(struct osmo_earfcn_si2q *e, uint16_t earfcn,
|
static inline void gen(struct gsm_bts *bts, const char *s)
|
||||||
uint8_t bw)
|
|
||||||
{
|
|
||||||
int r = osmo_earfcn_add(e, earfcn, bw);
|
|
||||||
if (r)
|
|
||||||
printf("failed to add EARFCN %u: %s\n", earfcn, strerror(-r));
|
|
||||||
else
|
|
||||||
printf("added EARFCN %u - ", earfcn);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void gen(struct gsm_bts *bts)
|
|
||||||
{
|
{
|
||||||
|
bts->u_offset = 0;
|
||||||
|
bts->e_offset = 0;
|
||||||
|
bts->si2q_index = 0;
|
||||||
|
bts->si2q_count = 0;
|
||||||
bts->si_valid = 0;
|
bts->si_valid = 0;
|
||||||
bts->si_valid |= (1 << SYSINFO_TYPE_2quater);
|
bts->si_valid |= (1 << SYSINFO_TYPE_2quater);
|
||||||
/* should be no-op as entire buffer is filled with padding: */
|
/* should be no-op as entire buffer is filled with padding: */
|
||||||
|
@ -106,17 +100,32 @@ static inline void gen(struct gsm_bts *bts)
|
||||||
printf("generated %s SI2quater: [%d] %s\n",
|
printf("generated %s SI2quater: [%d] %s\n",
|
||||||
v ? "valid" : "invalid", r, osmo_hexdump(GSM_BTS_SI(bts, SYSINFO_TYPE_2quater), r));
|
v ? "valid" : "invalid", r, osmo_hexdump(GSM_BTS_SI(bts, SYSINFO_TYPE_2quater), r));
|
||||||
else
|
else
|
||||||
printf("failed to generate SI2quater: %s\n", strerror(-r));
|
printf("%s() failed to generate SI2quater: %s\n", s, strerror(-r));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void _bts_uarfcn_add(struct gsm_bts *bts, uint16_t arfcn,
|
static inline void add_earfcn_b(struct gsm_bts *bts, uint16_t earfcn, uint8_t bw)
|
||||||
uint16_t scramble, bool diversity)
|
|
||||||
{
|
{
|
||||||
int r = bts_uarfcn_add(bts, arfcn, scramble, diversity);
|
struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list;
|
||||||
|
int r = osmo_earfcn_add(e, earfcn, bw);
|
||||||
|
if (r)
|
||||||
|
printf("failed to add EARFCN %u: %s\n", earfcn, strerror(-r));
|
||||||
|
else
|
||||||
|
printf("added EARFCN %u - ", earfcn);
|
||||||
|
|
||||||
|
gen(bts, __func__);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void _bts_uarfcn_add(struct gsm_bts *bts, uint16_t arfcn, uint16_t scramble, bool diversity)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
|
||||||
|
bts->u_offset = 0;
|
||||||
|
|
||||||
|
r = bts_uarfcn_add(bts, arfcn, scramble, diversity);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
printf("failed to add UARFCN to SI2quater: %s\n", strerror(-r));
|
printf("failed to add UARFCN to SI2quater: %s\n", strerror(-r));
|
||||||
else
|
else
|
||||||
gen(bts);
|
gen(bts, __func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void test_si2q_segfault(void)
|
static inline void test_si2q_segfault(void)
|
||||||
|
@ -131,7 +140,7 @@ static inline void test_si2q_segfault(void)
|
||||||
|
|
||||||
_bts_uarfcn_add(bts, 10564, 319, 0);
|
_bts_uarfcn_add(bts, 10564, 319, 0);
|
||||||
_bts_uarfcn_add(bts, 10612, 319, 0);
|
_bts_uarfcn_add(bts, 10612, 319, 0);
|
||||||
gen(bts);
|
gen(bts, __func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void test_si2q_mu(void)
|
static inline void test_si2q_mu(void)
|
||||||
|
@ -151,7 +160,7 @@ static inline void test_si2q_mu(void)
|
||||||
_bts_uarfcn_add(bts, 10613, 64, 0);
|
_bts_uarfcn_add(bts, 10613, 64, 0);
|
||||||
_bts_uarfcn_add(bts, 10613, 164, 0);
|
_bts_uarfcn_add(bts, 10613, 164, 0);
|
||||||
_bts_uarfcn_add(bts, 10613, 14, 0);
|
_bts_uarfcn_add(bts, 10613, 14, 0);
|
||||||
gen(bts);
|
gen(bts, __func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void test_si2q_u(void)
|
static inline void test_si2q_u(void)
|
||||||
|
@ -165,7 +174,7 @@ static inline void test_si2q_u(void)
|
||||||
bts = gsm_bts_alloc(network);
|
bts = gsm_bts_alloc(network);
|
||||||
|
|
||||||
/* first generate invalid SI as no UARFCN added */
|
/* first generate invalid SI as no UARFCN added */
|
||||||
gen(bts);
|
gen(bts, __func__);
|
||||||
/* subsequent calls should produce valid SI if there's enough memory */
|
/* subsequent calls should produce valid SI if there's enough memory */
|
||||||
_bts_uarfcn_add(bts, 1982, 13, 1);
|
_bts_uarfcn_add(bts, 1982, 13, 1);
|
||||||
_bts_uarfcn_add(bts, 1982, 44, 0);
|
_bts_uarfcn_add(bts, 1982, 44, 0);
|
||||||
|
@ -178,7 +187,7 @@ static inline void test_si2q_u(void)
|
||||||
_bts_uarfcn_add(bts, 1982, 223, 1);
|
_bts_uarfcn_add(bts, 1982, 223, 1);
|
||||||
_bts_uarfcn_add(bts, 1982, 14, 0);
|
_bts_uarfcn_add(bts, 1982, 14, 0);
|
||||||
_bts_uarfcn_add(bts, 1982, 88, 0);
|
_bts_uarfcn_add(bts, 1982, 88, 0);
|
||||||
gen(bts);
|
gen(bts, __func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void test_si2q_e(void)
|
static inline void test_si2q_e(void)
|
||||||
|
@ -191,40 +200,22 @@ static inline void test_si2q_e(void)
|
||||||
exit(1);
|
exit(1);
|
||||||
bts = gsm_bts_alloc(network);
|
bts = gsm_bts_alloc(network);
|
||||||
|
|
||||||
bts->si_common.si2quater_neigh_list.arfcn =
|
bts->si_common.si2quater_neigh_list.arfcn = bts->si_common.data.earfcn_list;
|
||||||
bts->si_common.data.earfcn_list;
|
bts->si_common.si2quater_neigh_list.meas_bw = bts->si_common.data.meas_bw_list;
|
||||||
bts->si_common.si2quater_neigh_list.meas_bw =
|
|
||||||
bts->si_common.data.meas_bw_list;
|
|
||||||
bts->si_common.si2quater_neigh_list.length = MAX_EARFCN_LIST;
|
bts->si_common.si2quater_neigh_list.length = MAX_EARFCN_LIST;
|
||||||
bts->si_common.si2quater_neigh_list.thresh_hi = 5;
|
bts->si_common.si2quater_neigh_list.thresh_hi = 5;
|
||||||
|
|
||||||
osmo_earfcn_init(&bts->si_common.si2quater_neigh_list);
|
osmo_earfcn_init(&bts->si_common.si2quater_neigh_list);
|
||||||
/* first generate invalid SI as no EARFCN added */
|
/* first generate invalid SI as no EARFCN added */
|
||||||
gen(bts);
|
gen(bts, __func__);
|
||||||
/* subsequent calls should produce valid SI if there's enough memory */
|
/* subsequent calls should produce valid SI if there's enough memory */
|
||||||
add_arfcn_b(&bts->si_common.si2quater_neigh_list, 1917, 1);
|
add_earfcn_b(bts, 1917, 1);
|
||||||
gen(bts);
|
add_earfcn_b(bts, 1932, OSMO_EARFCN_MEAS_INVALID);
|
||||||
|
add_earfcn_b(bts, 1937, 2);
|
||||||
add_arfcn_b(&bts->si_common.si2quater_neigh_list, 1932,
|
add_earfcn_b(bts, 1945, OSMO_EARFCN_MEAS_INVALID);
|
||||||
OSMO_EARFCN_MEAS_INVALID);
|
add_earfcn_b(bts, 1965, OSMO_EARFCN_MEAS_INVALID);
|
||||||
gen(bts);
|
add_earfcn_b(bts, 1967, 4);
|
||||||
|
add_earfcn_b(bts, 1982, 3);
|
||||||
add_arfcn_b(&bts->si_common.si2quater_neigh_list, 1937, 2);
|
|
||||||
gen(bts);
|
|
||||||
|
|
||||||
add_arfcn_b(&bts->si_common.si2quater_neigh_list, 1945,
|
|
||||||
OSMO_EARFCN_MEAS_INVALID);
|
|
||||||
gen(bts);
|
|
||||||
|
|
||||||
add_arfcn_b(&bts->si_common.si2quater_neigh_list, 1965,
|
|
||||||
OSMO_EARFCN_MEAS_INVALID);
|
|
||||||
gen(bts);
|
|
||||||
|
|
||||||
add_arfcn_b(&bts->si_common.si2quater_neigh_list, 1967, 4);
|
|
||||||
gen(bts);
|
|
||||||
|
|
||||||
add_arfcn_b(&bts->si_common.si2quater_neigh_list, 1982, 3);
|
|
||||||
gen(bts);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_mi_functionality(void)
|
static void test_mi_functionality(void)
|
||||||
|
|
|
@ -67,16 +67,16 @@ generated valid SI2quater: [23] 59 06 07 c0 00 25 52 88 0a 7e 10 99 64 00 0b 2b
|
||||||
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
|
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
|
||||||
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
|
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] ae ae ae ae ae ae ae ae ae ae ae ae ae ae ae ae ae ae ae ae ae ae ae
|
||||||
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
|
||||||
added EARFCN 1932 - generated valid SI2quater: [23] 59 06 07 c0 00 04 86 59 83 be cc 1e 30 14 03 2b 2b 2b 2b 2b 2b 2b 2b
|
added EARFCN 1932 - generated valid SI2quater: [23] 59 06 07 c0 00 04 86 59 83 be cc 1e 30 14 03 2b 2b 2b 2b 2b 2b 2b 2b
|
||||||
added EARFCN 1937 - generated valid SI2quater: [23] 59 06 07 c0 00 04 86 59 83 be cc 1e 31 07 91 a0 a0 2b 2b 2b 2b 2b 2b
|
added EARFCN 1937 - generated valid SI2quater: [23] 59 06 07 c0 00 04 86 59 83 be cc 1e 31 07 91 a0 a0 2b 2b 2b 2b 2b 2b
|
||||||
added EARFCN 1945 - generated valid SI2quater: [23] 59 06 07 c0 00 04 86 59 83 be cc 1e 31 07 91 a8 3c c8 28 0b 2b 2b 2b
|
added EARFCN 1945 - generated valid SI2quater: [23] 59 06 07 c0 00 04 86 59 83 be cc 1e 31 07 91 a8 3c c8 28 0b 2b 2b 2b
|
||||||
added EARFCN 1965 - generated valid SI2quater: [23] 59 06 07 c0 00 04 86 59 83 be cc 1e 31 07 91 a8 3c ca 0f 5a 0a 03 2b
|
added EARFCN 1965 - generated valid SI2quater: [23] 59 06 07 c0 00 04 86 59 83 be cc 1e 31 07 91 a8 3c ca 0f 5a 0a 03 2b
|
||||||
added EARFCN 1967 - failed to generate SI2quater: Cannot allocate memory
|
added EARFCN 1967 - add_earfcn_b() failed to generate SI2quater: Cannot allocate memory
|
||||||
added EARFCN 1982 - failed to generate SI2quater: Cannot allocate memory
|
added EARFCN 1982 - add_earfcn_b() failed to generate SI2quater: Cannot allocate memory
|
||||||
Testing SYSINFO_TYPE_2quater UARFCN generation:
|
Testing SYSINFO_TYPE_2quater UARFCN generation:
|
||||||
generated invalid SI2quater: [23] 59 06 07 c0 00 04 86 59 00 03 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b
|
generated invalid SI2quater: [23] ae ae ae ae ae ae ae ae ae ae ae ae ae ae ae ae ae ae ae ae ae ae ae
|
||||||
generated valid SI2quater: [23] 59 06 07 c0 00 25 0f 7c 0c 1a 10 99 64 00 0b 2b 2b 2b 2b 2b 2b 2b 2b
|
generated valid SI2quater: [23] 59 06 07 c0 00 25 0f 7c 0c 1a 10 99 64 00 0b 2b 2b 2b 2b 2b 2b 2b 2b
|
||||||
generated valid SI2quater: [23] 59 06 07 c0 00 25 0f 7c 14 1a 1f 00 44 b2 00 03 2b 2b 2b 2b 2b 2b 2b
|
generated valid SI2quater: [23] 59 06 07 c0 00 25 0f 7c 14 1a 1f 00 44 b2 00 03 2b 2b 2b 2b 2b 2b 2b
|
||||||
generated valid SI2quater: [23] 59 06 07 c0 00 25 0f 7c 18 58 12 f0 84 86 59 00 03 2b 2b 2b 2b 2b 2b
|
generated valid SI2quater: [23] 59 06 07 c0 00 25 0f 7c 18 58 12 f0 84 86 59 00 03 2b 2b 2b 2b 2b 2b
|
||||||
|
|
Loading…
Reference in New Issue