aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/osmocom/gsm/gsm_utils.h3
-rw-r--r--src/gsm/gsm_utils.c71
-rw-r--r--src/gsm/libosmogsm.map1
-rw-r--r--utils/osmo-arfcn.c8
4 files changed, 58 insertions, 25 deletions
diff --git a/include/osmocom/gsm/gsm_utils.h b/include/osmocom/gsm/gsm_utils.h
index 7eda5b9f..fe5903db 100644
--- a/include/osmocom/gsm/gsm_utils.h
+++ b/include/osmocom/gsm/gsm_utils.h
@@ -161,7 +161,8 @@ static inline int rach_max_trans_raw2val(int raw) {
#define ARFCN_UPLINK 0x4000
#define ARFCN_FLAG_MASK 0xf000 /* Reserve the upper 5 bits for flags */
-enum gsm_band gsm_arfcn2band(uint16_t arfcn);
+int gsm_arfcn2band_rc(uint16_t arfcn, enum gsm_band *band);
+enum gsm_band gsm_arfcn2band(uint16_t arfcn) OSMO_DEPRECATED("Use gsm_arfcn2band_rc() instead");
/* Convert an ARFCN to the frequency in MHz * 10 */
uint16_t gsm_arfcn2freq10(uint16_t arfcn, int uplink);
diff --git a/src/gsm/gsm_utils.c b/src/gsm/gsm_utils.c
index 7e6c7947..8b4b5586 100644
--- a/src/gsm/gsm_utils.c
+++ b/src/gsm/gsm_utils.c
@@ -706,36 +706,61 @@ enum gsm_band gsm_band_parse(const char* mhz)
}
}
-/*! Resolve GSM band from ARFCN
+/*! Resolve GSM band from ARFCN.
* In Osmocom, we use the highest bit of the \a arfcn to indicate PCS
* \param[in] arfcn Osmocom ARFCN, highest bit determines PCS mode
- * \returns GSM Band */
-enum gsm_band gsm_arfcn2band(uint16_t arfcn)
+ * \param[out] band GSM Band containing \arfcn if arfcn is valid, undetermined otherwise
+ * \returns 0 if arfcn is valid and \a band was set, negative on error */
+int gsm_arfcn2band_rc(uint16_t arfcn, enum gsm_band *band)
{
int is_pcs = arfcn & ARFCN_PCS;
arfcn &= ~ARFCN_FLAG_MASK;
- if (is_pcs)
- return GSM_BAND_1900;
- else if (arfcn <= 124)
- return GSM_BAND_900;
- else if (arfcn >= 955 && arfcn <= 1023)
- return GSM_BAND_900;
- else if (arfcn >= 128 && arfcn <= 251)
- return GSM_BAND_850;
- else if (arfcn >= 512 && arfcn <= 885)
- return GSM_BAND_1800;
- else if (arfcn >= 259 && arfcn <= 293)
- return GSM_BAND_450;
- else if (arfcn >= 306 && arfcn <= 340)
- return GSM_BAND_480;
- else if (arfcn >= 350 && arfcn <= 425)
- return GSM_BAND_810;
- else if (arfcn >= 438 && arfcn <= 511)
- return GSM_BAND_750;
- else
- return GSM_BAND_1800;
+ if (is_pcs) {
+ *band = GSM_BAND_1900;
+ return 0;
+ } else if (arfcn <= 124) {
+ *band = GSM_BAND_900;
+ return 0;
+ } else if (arfcn >= 955 && arfcn <= 1023) {
+ *band = GSM_BAND_900;
+ return 0;
+ } else if (arfcn >= 128 && arfcn <= 251) {
+ *band = GSM_BAND_850;
+ return 0;
+ } else if (arfcn >= 512 && arfcn <= 885) {
+ *band = GSM_BAND_1800;
+ return 0;
+ } else if (arfcn >= 259 && arfcn <= 293) {
+ *band = GSM_BAND_450;
+ return 0;
+ } else if (arfcn >= 306 && arfcn <= 340) {
+ *band = GSM_BAND_480;
+ return 0;
+ } else if (arfcn >= 350 && arfcn <= 425) {
+ *band = GSM_BAND_810;
+ return 0;
+ } else if (arfcn >= 438 && arfcn <= 511) {
+ *band = GSM_BAND_750;
+ return 0;
+ }
+ return -1;
+}
+
+/*! Resolve GSM band from ARFCN, aborts process on invalid ARFCN.
+ * In Osmocom, we use the highest bit of the \a arfcn to indicate PCS.
+ * DEPRECATED: Use gsm_arfcn2band_rc instead.
+ * \param[in] arfcn Osmocom ARFCN, highest bit determines PCS mode
+ * \returns GSM Band if ARFCN is valid (part of any valid band), aborts otherwise */
+enum gsm_band gsm_arfcn2band(uint16_t arfcn)
+{
+ enum gsm_band band;
+ if (gsm_arfcn2band_rc(arfcn, &band) == 0)
+ return band;
+
+ osmo_panic("%s:%d Invalid arfcn %" PRIu16 " passed to gsm_arfcn2band\n",
+ __FILE__, __LINE__, arfcn);
}
struct gsm_freq_range {
diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map
index 217dcc39..3fe9dfcf 100644
--- a/src/gsm/libosmogsm.map
+++ b/src/gsm/libosmogsm.map
@@ -349,6 +349,7 @@ gsm_7bit_decode_n_hdr;
gsm_7bit_encode_n;
gsm_7bit_encode_n_ussd;
+gsm_arfcn2band_rc;
gsm_arfcn2band;
gsm_arfcn2freq10;
gsm_freq102arfcn;
diff --git a/utils/osmo-arfcn.c b/utils/osmo-arfcn.c
index 61108f8d..aee132c7 100644
--- a/utils/osmo-arfcn.c
+++ b/utils/osmo-arfcn.c
@@ -62,6 +62,7 @@ static int arfcn2freq(int arfcn)
static int freq2arfcn(int freq10, int uplink)
{
uint16_t arfcn;
+ enum gsm_band band;
if (uplink != 0 && uplink != 1) {
fprintf(stderr, "Need to specify uplink or downlink\n");
@@ -75,8 +76,13 @@ static int freq2arfcn(int freq10, int uplink)
return -EINVAL;
}
+ if (gsm_arfcn2band_rc(arfcn, &band) < 0) {
+ fprintf(stderr, "ARFCN contains no valid band\n");
+ return -EINVAL;
+ }
+
printf("%s: ARFCN %4d\n",
- gsm_band_name(gsm_arfcn2band(arfcn)),
+ gsm_band_name(band),
arfcn & ~ARFCN_FLAG_MASK);
return 0;
}