blob: afe8ab630632c160ab6abe510acb2067710dc64b [file] [log] [blame]
Roman Khassraf91448612015-08-21 11:14:51 +02001#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3# @file
4# @author Roman Khassraf <rkhassraf@gmail.com>
5# @section LICENSE
6#
7# Gr-gsm is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation; either version 3, or (at your option)
10# any later version.
11#
12# Gr-gsm is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with gr-gsm; see the file COPYING. If not, write to
19# the Free Software Foundation, Inc., 51 Franklin Street,
20# Boston, MA 02110-1301, USA.
21#
22#
23
Roman Khassrafe7e75f02015-08-22 19:26:12 +020024import collections
25
26
Roman Khassraf91448612015-08-21 11:14:51 +020027# first uplink freq, first arfcn, last arfcn, downlink frequence distance
Roman Khassrafe7e75f02015-08-22 19:26:12 +020028# entries are ordered by relevance
29__band_conf = collections.OrderedDict([
30 ('P-GSM', {'first_freq': 890.2e6, 'first_arfcn': 1, 'last_arfcn': 124, 'downlink_dist': 45e6}),
31 ('DCS1800', {'first_freq': 1710.2e6, 'first_arfcn': 512, 'last_arfcn': 885, 'downlink_dist': 95e6}),
32 ('PCS1900', {'first_freq': 1850.2e6, 'first_arfcn': 512, 'last_arfcn': 810, 'downlink_dist': 80e6}),
33 ('E-GSM', {'first_freq': 880.2e6, 'first_arfcn': 975, 'last_arfcn': 1023, 'downlink_dist': 45e6}),
34 ('R-GSM', {'first_freq': 876.2e6, 'first_arfcn': 955, 'last_arfcn': 1023, 'downlink_dist': 45e6}),
35 ('GSM450',{'first_freq': 450.6e6, 'first_arfcn': 259, 'last_arfcn': 293, 'downlink_dist': 10e6}),
36 ('GSM480', {'first_freq': 479e6, 'first_arfcn': 306, 'last_arfcn': 340, 'downlink_dist': 10e6}),
37 ('GSM850', {'first_freq': 824.2e6, 'first_arfcn': 128, 'last_arfcn': 251, 'downlink_dist': 45e6})
38 ])
Roman Khassraf91448612015-08-21 11:14:51 +020039
40__chan_spacing = 2e5
41
42
43def get_bands():
44 return __band_conf.keys()
45
46
47def is_valid_arfcn(arfcn, band):
48 """
49 Returns True if arfcn is valid in the given band, else False
50 """
51 if band in __band_conf:
52 conf = __band_conf.get(band)
53 first_arfcn = conf['first_arfcn']
54 last_arfcn = conf['last_arfcn']
55 if first_arfcn <= arfcn <= last_arfcn:
56 return True
57 return False
58
59
60def is_valid_uplink(freq, band):
61 """
62 Returns True if the given frequency is a valid uplink frequency in the given band
63 """
64 if band in __band_conf:
65 conf = __band_conf.get(band)
66 first_freq = arfcn2uplink(conf['first_arfcn'], band)
67 last_freq = arfcn2uplink(conf['last_arfcn'], band)
68 if first_freq is None or last_freq is None:
69 return False
70 if first_freq <= freq <= last_freq:
71 return True
72 return False
73
74
75def is_valid_downlink(freq, band):
76 """
77 Returns True if the given frequency is a valid downlink frequency in the given band
78 """
79 if band in __band_conf:
80 conf = __band_conf.get(band)
81 first_freq = arfcn2downlink(conf['first_arfcn'], band)
82 last_freq = arfcn2downlink(conf['last_arfcn'], band)
83 if first_freq is None or last_freq is None:
84 return False
85 if first_freq <= freq <= last_freq:
86 return True
87 return False
88
89
90def arfcn2uplink(arfcn, band):
91 if band in __band_conf and is_valid_arfcn(arfcn, band):
92
93 conf = __band_conf.get(band)
94 freq_start = conf['first_freq']
95 offset = conf['first_arfcn']
96 # if (band == 'E-GSM' or band == 'R-GSM') and arfcn > 124:
97 # offset = 1024
98 f = freq_start + (__chan_spacing * (arfcn - offset))
99 return round(f, 1)
100 return None
101
102
103def arfcn2downlink(arfcn, band):
104 if band in __band_conf and is_valid_arfcn(arfcn, band):
105 conf = __band_conf.get(band)
106 distance = conf['downlink_dist']
107 return round(arfcn2uplink(arfcn, band) + distance, 1)
108 return None
109
110
111def uplink2arfcn(freq, band):
112 if band in __band_conf and is_valid_uplink(freq, band):
113 conf = __band_conf.get(band)
114 freq_start = conf['first_freq']
115 offset = conf['first_arfcn']
116 return int(round(offset + ((freq - freq_start) / __chan_spacing), 0))
117 return None
118
119
120def downlink2arfcn(freq, band):
121 if band in __band_conf and is_valid_downlink(freq, band):
122 conf = __band_conf.get(band)
123 distance = conf['downlink_dist']
124 freq_uplink = freq - distance
125 return int(round(uplink2arfcn(freq_uplink, band), 0))
126 return None