aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2013-01-17 13:49:39 +0100
committerHolger Hans Peter Freyther <zecke@selfish.org>2013-01-17 19:31:49 +0100
commitd4d1d5e7516c6e90668b9b321614d81045a60461 (patch)
tree019aabd8f99c226bd2c9c71ef18bac84e2338db9
parent9e1952a9011dbd81e28c59d4bc986d1344c1bfb0 (diff)
si: Deal with DCS1800 and PCS1900 have overlapping ARFCN ranges
For PCS1900 the SI1 does not contain the ARFCN of the serving cell. This is because the arfcn2band method will return GSM_BAND_1800 and not GSM_BAND_1900. The academic fix would be to set the ARFCN_PCS bit but this would require increasing the bitvector sizes from 1024/8 to (0x8000 + 1024) / 8. This would increase the storage size for each bitvector by three. It is not possible to have DCS1800 and PCS1900 in one network so we can avoid increasing the memory usage and check if the ARFCN resolved to 1800 and then check if the BTS is a 1900 BTS and then claim that this is compatible.
-rw-r--r--openbsc/src/libbsc/system_information.c26
1 files changed, 23 insertions, 3 deletions
diff --git a/openbsc/src/libbsc/system_information.c b/openbsc/src/libbsc/system_information.c
index dbee249e8..41881d9ac 100644
--- a/openbsc/src/libbsc/system_information.c
+++ b/openbsc/src/libbsc/system_information.c
@@ -37,15 +37,35 @@
#include <openbsc/rest_octets.h>
#include <openbsc/arfcn_range_encode.h>
+/*
+ * DCS1800 and PCS1900 have overlapping ARFCNs. We would need to set the
+ * ARFCN_PCS flag on the 1900 ARFCNs but this would increase cell_alloc
+ * and other arrays to make sure (ARFCN_PCS + 1024)/8 ARFCNs fit into the
+ * array. DCS1800 and PCS1900 can not be used at the same time so conserve
+ * memory and do the below.
+ */
+static int band_compatible(const struct gsm_bts *bts, int arfcn)
+{
+ enum gsm_band band = gsm_arfcn2band(arfcn);
+
+ /* normal case */
+ if (band == bts->band)
+ return 1;
+ /* deal with ARFCN_PCS not set */
+ if (band == GSM_BAND_1800 && bts->band == GSM_BAND_1900)
+ return 1;
+
+ return 0;
+}
static int use_arfcn(const struct gsm_bts *bts, const int bis, const int ter,
const int pgsm, const int arfcn)
{
- if (!bis && !ter && gsm_arfcn2band(arfcn) == bts->band)
+ if (!bis && !ter && band_compatible(bts, arfcn))
return 1;
- if (bis && pgsm && gsm_arfcn2band(arfcn) == bts->band && (arfcn < 1 || arfcn > 124))
+ if (bis && pgsm && band_compatible(bts, arfcn) && (arfcn < 1 || arfcn > 124))
return 1;
- if (ter && gsm_arfcn2band(arfcn) != bts->band)
+ if (ter && !band_compatible(bts, arfcn))
return 1;
return 0;
}