gr-gsm/python/misc_utils/arfcn.py

127 lines
4.3 KiB
Python

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @file
# @author Roman Khassraf <rkhassraf@gmail.com>
# @section LICENSE
#
# Gr-gsm is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# Gr-gsm is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with gr-gsm; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
#
#
import collections
# first uplink freq, first arfcn, last arfcn, downlink frequence distance
# 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})
])
__chan_spacing = 2e5
def get_bands():
return __band_conf.keys()
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
return False
def is_valid_uplink(freq, band):
"""
Returns True if the given frequency is a valid uplink frequency in the given band
"""
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
def is_valid_downlink(freq, band):
"""
Returns True if the given frequency is a valid downlink frequency in the given band
"""
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
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)
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']
return round(arfcn2uplink(arfcn, band) + distance, 1)
return None
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))
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']
freq_uplink = freq - distance
return int(round(uplink2arfcn(freq_uplink, band), 0))
return None