blob: fe0002e5a7dcd7d814d16d9992edb31e983d5e8c [file] [log] [blame]
Piotr Krysik902f4eb2017-09-19 08:04:33 +02001#!/usr/bin/env python2
2# -*- coding: utf-8 -*-
3
4# GR-GSM based transceiver
5# CTRL interface for OsmocomBB
6#
7# (C) 2016-2017 by Vadim Yanitskiy <axilirator@gmail.com>
8#
9# All Rights Reserved
10#
11# This program is free software; you can redistribute it and/or modify
12# it under the terms of the GNU General Public License as published by
13# the Free Software Foundation; either version 2 of the License, or
14# (at your option) any later version.
15#
16# This program is distributed in the hope that it will be useful,
17# but WITHOUT ANY WARRANTY; without even the implied warranty of
18# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19# GNU General Public License for more details.
20#
21# You should have received a copy of the GNU General Public License along
22# with this program; if not, write to the Free Software Foundation, Inc.,
23# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24
Vadim Yanitskiy962e2d82017-10-17 09:24:55 +070025import grgsm
Vadim Yanitskiy873e44e2017-10-17 06:52:01 +070026from ctrl_if import ctrl_if
Piotr Krysik902f4eb2017-09-19 08:04:33 +020027
Vadim Yanitskiy873e44e2017-10-17 06:52:01 +070028class ctrl_if_bb(ctrl_if):
Vadim Yanitskiy473b35b2018-08-10 00:20:03 +070029 def __init__(self, remote_addr, remote_port, bind_addr, bind_port, tb, pm):
Vadim Yanitskiy473b35b2018-08-10 00:20:03 +070030 ctrl_if.__init__(self, remote_addr, remote_port,
31 bind_addr, bind_port)
Piotr Krysik902f4eb2017-09-19 08:04:33 +020032
Vadim Yanitskiy2adbee42018-08-10 00:51:36 +070033 print("[i] Init CTRL interface (%s)" % self.desc_link())
34
Piotr Krysik902f4eb2017-09-19 08:04:33 +020035 # Set link to the follow graph (top block)
36 self.tb = tb
37 # Power measurement
38 self.pm = pm
39
Piotr Krysik902f4eb2017-09-19 08:04:33 +020040 def parse_cmd(self, request):
41 # Power control
42 if self.verify_cmd(request, "POWERON", 0):
43 print("[i] Recv POWERON CMD")
44
45 # Ensure transceiver isn't working
46 if self.tb.trx_started:
47 print("[!] Transceiver already started")
48 return -1
49
Piotr Krysik902f4eb2017-09-19 08:04:33 +020050 print("[i] Starting transceiver...")
51 self.tb.trx_started = True
52 self.tb.start()
53
54 return 0
55
56 elif self.verify_cmd(request, "POWEROFF", 0):
57 print("[i] Recv POWEROFF cmd")
58
59 # TODO: flush all buffers between blocks
60 if self.tb.trx_started:
61 print("[i] Stopping transceiver...")
62 self.tb.trx_started = False
Vadim Yanitskiy34266e72017-12-05 01:01:43 +070063 self.tb.set_ta(0)
Piotr Krysik902f4eb2017-09-19 08:04:33 +020064 self.tb.stop()
65 self.tb.wait()
66
67 return 0
68
Vadim Yanitskiy01c6afd2017-10-19 01:14:24 +070069 # Gain control
Piotr Krysik902f4eb2017-09-19 08:04:33 +020070 elif self.verify_cmd(request, "SETRXGAIN", 1):
71 print("[i] Recv SETRXGAIN cmd")
72
73 # TODO: check gain value
74 gain = int(request[1])
Vadim Yanitskiy01c6afd2017-10-19 01:14:24 +070075 self.tb.set_rx_gain(gain)
76
77 return 0
78
79 elif self.verify_cmd(request, "SETTXGAIN", 1):
80 print("[i] Recv SETTXGAIN cmd")
81
82 # TODO: check gain value
83 gain = int(request[1])
84 self.tb.set_tx_gain(gain)
Piotr Krysik902f4eb2017-09-19 08:04:33 +020085
86 return 0
87
88 # Tuning Control
89 elif self.verify_cmd(request, "RXTUNE", 1):
90 print("[i] Recv RXTUNE cmd")
91
92 # TODO: check freq range
93 freq = int(request[1]) * 1000
Vadim Yanitskiy89aa4692017-11-14 00:15:20 +070094 self.tb.set_rx_freq(freq)
Piotr Krysik902f4eb2017-09-19 08:04:33 +020095
96 return 0
97
98 elif self.verify_cmd(request, "TXTUNE", 1):
99 print("[i] Recv TXTUNE cmd")
100
Vadim Yanitskiy89aa4692017-11-14 00:15:20 +0700101 # TODO: check freq range
102 freq = int(request[1]) * 1000
103 self.tb.set_tx_freq(freq)
104
Piotr Krysik902f4eb2017-09-19 08:04:33 +0200105 return 0
106
107 # Timeslot management
108 elif self.verify_cmd(request, "SETSLOT", 2):
109 print("[i] Recv SETSLOT cmd")
110
111 # Obtain TS index
112 tn = int(request[1])
113 if tn not in range(0, 8):
114 print("[!] TS index should be in range: 0..7")
115 return -1
116
117 # Ignore timeslot type for now
Vadim Yanitskiy962e2d82017-10-17 09:24:55 +0700118 config = int(request[2])
Piotr Krysik902f4eb2017-09-19 08:04:33 +0200119 print("[i] Configure timeslot filter to: %s"
Vadim Yanitskiy962e2d82017-10-17 09:24:55 +0700120 % ("drop all" if config == 0 else "TS %d" % tn))
Piotr Krysik902f4eb2017-09-19 08:04:33 +0200121
Vadim Yanitskiy962e2d82017-10-17 09:24:55 +0700122 if config == 0:
123 # Value 0 means 'drop all'
Vadim Yanitskiy89aa4692017-11-14 00:15:20 +0700124 self.tb.ts_filter.set_policy(
Vadim Yanitskiy962e2d82017-10-17 09:24:55 +0700125 grgsm.FILTER_POLICY_DROP_ALL)
126 else:
Vadim Yanitskiy89aa4692017-11-14 00:15:20 +0700127 self.tb.ts_filter.set_policy(
Vadim Yanitskiy962e2d82017-10-17 09:24:55 +0700128 grgsm.FILTER_POLICY_DEFAULT)
Vadim Yanitskiy89aa4692017-11-14 00:15:20 +0700129 self.tb.ts_filter.set_tn(tn)
Piotr Krysik902f4eb2017-09-19 08:04:33 +0200130
131 return 0
132
133 # Power measurement
134 elif self.verify_cmd(request, "MEASURE", 1):
135 print("[i] Recv MEASURE cmd")
136
137 # TODO: check freq range
138 meas_freq = int(request[1]) * 1000
139
140 # HACK: send fake low power values
141 # until actual power measurement is implemented
142 meas_dbm = str(self.pm.measure(meas_freq))
143
144 return (0, [meas_dbm])
145
Vadim Yanitskiy34266e72017-12-05 01:01:43 +0700146 # Timing Advance control
147 elif self.verify_cmd(request, "SETTA", 1):
148 print("[i] Recv SETTA cmd")
149
150 # Check TA range
151 ta = int(request[1])
152 if ta < 0 or ta > 63:
153 print("[!] TA value must be in range: 0..63")
154 return -1
155
156 self.tb.set_ta(ta)
157 return 0
158
Piotr Krysik902f4eb2017-09-19 08:04:33 +0200159 # Misc
160 elif self.verify_cmd(request, "ECHO", 0):
161 print("[i] Recv ECHO cmd")
162 return 0
163
164 # Wrong / unknown command
165 else:
166 print("[!] Wrong request on CTRL interface")
167 return -1