blob: e7edfb58b9f83d717ec08357ec051b410cce91c2 [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
Roman Khassraf5ec79872015-09-26 08:29:13 +020047def get_first_arfcn(band):
48 """
49 Returns the first arfcn (i.e. the one with the lowest number) in the given band.
50 """
51 if band in __band_conf:
52 conf = __band_conf.get(band)
53 return conf['first_arfcn']
54
55
56def get_last_arfcn(band):
57 """
58 Returns the last arfcn (i.e. the one with the highest number) in the given band
59 """
60 if band in __band_conf:
61 conf = __band_conf.get(band)
62 return conf['last_arfcn']
63
64
Roman Khassraf91448612015-08-21 11:14:51 +020065def is_valid_arfcn(arfcn, band):
66 """
67 Returns True if arfcn is valid in the given band, else False
68 """
69 if band in __band_conf:
70 conf = __band_conf.get(band)
71 first_arfcn = conf['first_arfcn']
72 last_arfcn = conf['last_arfcn']
73 if first_arfcn <= arfcn <= last_arfcn:
74 return True
75 return False
76
77
78def is_valid_uplink(freq, band):
79 """
80 Returns True if the given frequency is a valid uplink frequency in the given band
81 """
82 if band in __band_conf:
83 conf = __band_conf.get(band)
84 first_freq = arfcn2uplink(conf['first_arfcn'], band)
85 last_freq = arfcn2uplink(conf['last_arfcn'], band)
86 if first_freq is None or last_freq is None:
87 return False
88 if first_freq <= freq <= last_freq:
89 return True
90 return False
91
92
93def is_valid_downlink(freq, band):
94 """
95 Returns True if the given frequency is a valid downlink frequency in the given band
96 """
97 if band in __band_conf:
98 conf = __band_conf.get(band)
99 first_freq = arfcn2downlink(conf['first_arfcn'], band)
100 last_freq = arfcn2downlink(conf['last_arfcn'], band)
101 if first_freq is None or last_freq is None:
102 return False
103 if first_freq <= freq <= last_freq:
104 return True
105 return False
106
107
108def arfcn2uplink(arfcn, band):
109 if band in __band_conf and is_valid_arfcn(arfcn, band):
110
111 conf = __band_conf.get(band)
112 freq_start = conf['first_freq']
113 offset = conf['first_arfcn']
114 # if (band == 'E-GSM' or band == 'R-GSM') and arfcn > 124:
115 # offset = 1024
116 f = freq_start + (__chan_spacing * (arfcn - offset))
117 return round(f, 1)
118 return None
119
120
121def arfcn2downlink(arfcn, band):
122 if band in __band_conf and is_valid_arfcn(arfcn, band):
123 conf = __band_conf.get(band)
124 distance = conf['downlink_dist']
125 return round(arfcn2uplink(arfcn, band) + distance, 1)
126 return None
127
128
129def uplink2arfcn(freq, band):
130 if band in __band_conf and is_valid_uplink(freq, band):
131 conf = __band_conf.get(band)
132 freq_start = conf['first_freq']
133 offset = conf['first_arfcn']
134 return int(round(offset + ((freq - freq_start) / __chan_spacing), 0))
135 return None
136
137
138def downlink2arfcn(freq, band):
139 if band in __band_conf and is_valid_downlink(freq, band):
140 conf = __band_conf.get(band)
141 distance = conf['downlink_dist']
142 freq_uplink = freq - distance
143 return int(round(uplink2arfcn(freq_uplink, band), 0))
144 return None