127 lines
4.3 KiB
Python
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
|