#154: fix for arfcn conversion
diff --git a/python/misc_utils/arfcn.py b/python/misc_utils/arfcn.py
index e7edfb5..8836501 100644
--- a/python/misc_utils/arfcn.py
+++ b/python/misc_utils/arfcn.py
@@ -23,19 +23,19 @@
 
 import collections
 
-
-# first uplink freq, first arfcn, last arfcn, downlink frequence distance
+# first uplink freq, distance between uplink/downlink frequency, list of range tuple
+# each tuple in a range tuple contains: first arfcn of the range, last arfcn of the range, offset of the range
 # entries are ordered by relevance
 __band_conf = collections.OrderedDict([
-    ('P-GSM', {'first_freq': 890.2e6, 'first_arfcn': 1, 'last_arfcn': 124, 'downlink_dist': 45e6}),
-    ('DCS1800', {'first_freq': 1710.2e6, 'first_arfcn': 512, 'last_arfcn': 885, 'downlink_dist': 95e6}),
-    ('PCS1900', {'first_freq': 1850.2e6, 'first_arfcn': 512, 'last_arfcn': 810, 'downlink_dist': 80e6}),
-    ('E-GSM', {'first_freq': 880.2e6, 'first_arfcn': 975, 'last_arfcn': 1023, 'downlink_dist': 45e6}),           
-    ('R-GSM', {'first_freq': 876.2e6, 'first_arfcn': 955, 'last_arfcn': 1023, 'downlink_dist': 45e6}),
-    ('GSM450',{'first_freq': 450.6e6, 'first_arfcn': 259, 'last_arfcn': 293, 'downlink_dist': 10e6}),
-    ('GSM480', {'first_freq': 479e6, 'first_arfcn': 306, 'last_arfcn': 340, 'downlink_dist': 10e6}),
-    ('GSM850', {'first_freq': 824.2e6, 'first_arfcn': 128, 'last_arfcn': 251, 'downlink_dist': 45e6})
-    ])
+    ('P-GSM', {'f_start': 890.0e6, 'distance': 45e6, 'ranges': [(1, 124, 0)]}),
+    ('DCS1800', {'f_start': 1710.2e6, 'distance': 95e6, 'ranges': [(512, 885, 512)]}),
+    ('PCS1900', {'f_start': 1850.2e6, 'distance': 80e6, 'ranges': [(512, 810, 512)]}),
+    ('E-GSM', {'f_start': 890.0e6, 'distance': 45e6, 'ranges': [(0, 124, 0), (975, 1023, 1024)]}),
+    ('R-GSM', {'f_start': 890.0e6, 'distance': 45e6, 'ranges': [(0, 124, 0), (955, 1023, 1024)]}),
+    ('GSM450', {'f_start': 450.6e6, 'distance': 10e6, 'ranges': [(259, 293, 259)]}),
+    ('GSM480', {'f_start': 479e6, 'distance': 10e6, 'ranges': [(306, 340, 306)]}),
+    ('GSM850', {'f_start': 824.2e6, 'distance': 45e6, 'ranges': [(128, 251, 128)]}),
+])
 
 __chan_spacing = 2e5
 
@@ -44,34 +44,17 @@
     return __band_conf.keys()
 
 
-def get_first_arfcn(band):
-    """
-    Returns the first arfcn (i.e. the one with the lowest number) in the given band.
-    """
-    if band in __band_conf:
-        conf = __band_conf.get(band)
-        return conf['first_arfcn']
-
-
-def get_last_arfcn(band):
-    """
-    Returns the last arfcn (i.e. the one with the highest number) in the given band
-    """
-    if band in __band_conf:
-        conf = __band_conf.get(band)
-        return conf['last_arfcn']
-    
-    
 def is_valid_arfcn(arfcn, band):
     """
     Returns True if arfcn is valid in the given band, else False
     """
     if band in __band_conf:
         conf = __band_conf.get(band)
-        first_arfcn = conf['first_arfcn']
-        last_arfcn = conf['last_arfcn']
-        if first_arfcn <= arfcn <= last_arfcn:
-            return True
+        for arfcn_range in conf['ranges']:
+            arfcn_start = arfcn_range[0]
+            arfcn_end = arfcn_range[1]
+            if arfcn_start <= arfcn <= arfcn_end:
+                return True
     return False
 
 
@@ -79,49 +62,63 @@
     """
     Returns True if the given frequency is a valid uplink frequency in the given band
     """
+    result = None
     if band in __band_conf:
         conf = __band_conf.get(band)
-        first_freq = arfcn2uplink(conf['first_arfcn'], band)
-        last_freq = arfcn2uplink(conf['last_arfcn'], band)
-    if first_freq is None or last_freq is None:
-        return False
-    if first_freq <= freq <= last_freq:
-        return True
-    return False
+        result = False
+        for arfcn_range in conf['ranges']:
+            arfcn_start = arfcn_range[0]
+            arfcn_end = arfcn_range[1]
+            first_freq = arfcn2uplink(arfcn_start, band)
+            last_freq = arfcn2uplink(arfcn_end, band)
+            if first_freq is None or last_freq is None:
+                result = False
+            elif first_freq <= freq <= last_freq:
+                result = True
+    return result
 
 
 def is_valid_downlink(freq, band):
     """
     Returns True if the given frequency is a valid downlink frequency in the given band
     """
+    result = None
     if band in __band_conf:
         conf = __band_conf.get(band)
-        first_freq = arfcn2downlink(conf['first_arfcn'], band)
-        last_freq = arfcn2downlink(conf['last_arfcn'], band)
-    if first_freq is None or last_freq is None:
-        return False
-    if first_freq <= freq <= last_freq:
-        return True
-    return False 
+        result = False
+        for arfcn_range in conf['ranges']:
+            arfcn_start = arfcn_range[0]
+            arfcn_end = arfcn_range[1]
+            first_freq = arfcn2downlink(arfcn_start, band)
+            last_freq = arfcn2downlink(arfcn_end, band)
+            if first_freq is None or last_freq is None:
+                result = False
+            elif first_freq <= freq <= last_freq:
+                result = True
+    return result
 
 
 def arfcn2uplink(arfcn, band):
     if band in __band_conf and is_valid_arfcn(arfcn, band):
-
         conf = __band_conf.get(band)
-        freq_start = conf['first_freq']
-        offset = conf['first_arfcn']
-        # if (band == 'E-GSM' or band == 'R-GSM') and arfcn > 124:
-        #     offset = 1024
-        f = freq_start + (__chan_spacing * (arfcn - offset))
-        return round(f, 1)
+        f_start = conf['f_start']
+        offset = None
+        for arfcn_range in conf['ranges']:
+            arfcn_start = arfcn_range[0]
+            arfcn_end = arfcn_range[1]
+            if arfcn_start <= arfcn <= arfcn_end:
+                offset = arfcn_range[2]
+
+        if offset is not None:
+            f = f_start + (__chan_spacing * (arfcn - offset))
+            return round(f, 1)
     return None
 
 
 def arfcn2downlink(arfcn, band):
     if band in __band_conf and is_valid_arfcn(arfcn, band):
         conf = __band_conf.get(band)
-        distance = conf['downlink_dist']
+        distance = conf['distance']
         return round(arfcn2uplink(arfcn, band) + distance, 1)
     return None
 
@@ -129,16 +126,35 @@
 def uplink2arfcn(freq, band):
     if band in __band_conf and is_valid_uplink(freq, band):
         conf = __band_conf.get(band)
-        freq_start = conf['first_freq']
-        offset = conf['first_arfcn']
-        return int(round(offset + ((freq - freq_start) / __chan_spacing), 0))
+        f_start = conf['f_start']
+        offset = None
+        for arfcn_range in conf['ranges']:
+            arfcn_start = arfcn_range[0]
+            arfcn_end = arfcn_range[1]
+            offset = arfcn_range[2]
+            arfcn = int(round(offset + ((freq - f_start) / __chan_spacing), 0))
+            if arfcn_start <= arfcn <= arfcn_end:
+                return arfcn
     return None
 
 
 def downlink2arfcn(freq, band):
     if band in __band_conf and is_valid_downlink(freq, band):
         conf = __band_conf.get(band)
-        distance = conf['downlink_dist']
+        distance = conf['distance']
         freq_uplink = freq - distance
         return int(round(uplink2arfcn(freq_uplink, band), 0))
     return None
+
+
+def get_arfcn_ranges(band):
+    """
+    Returns a list of arfcn tuples, each with first and last arfcn of the range.
+    """
+    result = []
+    if band in __band_conf:
+        conf = __band_conf.get(band)
+        for arfcn_range in conf['ranges']:
+            arfcn_tuple = (arfcn_range[0], arfcn_range[1])
+            result.append(arfcn_tuple)
+    return result