blob: f9840d4a8e1bb3da859fc20bd14c81fc2a902542 [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
Piotr Krysik902f4eb2017-09-19 08:04:33 +020026
Vadim Yanitskiy44d8c1e2018-12-20 09:49:56 +070027from ctrl_if import CTRLInterface
28
29class CTRLInterfaceBB(CTRLInterface):
Vadim Yanitskiyd54e8fb2019-01-19 09:28:23 +070030 def __init__(self, remote_addr, remote_port, bind_addr, bind_port, tb):
Vadim Yanitskiy44d8c1e2018-12-20 09:49:56 +070031 CTRLInterface.__init__(self, remote_addr, remote_port,
Vadim Yanitskiy21655842018-08-10 00:20:03 +070032 bind_addr, bind_port)
Piotr Krysik902f4eb2017-09-19 08:04:33 +020033
Vadim Yanitskiy641133e2018-08-10 00:51:36 +070034 print("[i] Init CTRL interface (%s)" % self.desc_link())
35
Piotr Krysik902f4eb2017-09-19 08:04:33 +020036 # Set link to the follow graph (top block)
37 self.tb = tb
Piotr Krysik902f4eb2017-09-19 08:04:33 +020038
Piotr Krysik902f4eb2017-09-19 08:04:33 +020039 def parse_cmd(self, request):
40 # Power control
41 if self.verify_cmd(request, "POWERON", 0):
42 print("[i] Recv POWERON CMD")
43
44 # Ensure transceiver isn't working
45 if self.tb.trx_started:
46 print("[!] Transceiver already started")
47 return -1
48
Piotr Krysik902f4eb2017-09-19 08:04:33 +020049 print("[i] Starting transceiver...")
50 self.tb.trx_started = True
51 self.tb.start()
52
53 return 0
54
55 elif self.verify_cmd(request, "POWEROFF", 0):
56 print("[i] Recv POWEROFF cmd")
57
58 # TODO: flush all buffers between blocks
59 if self.tb.trx_started:
60 print("[i] Stopping transceiver...")
61 self.tb.trx_started = False
Vadim Yanitskiy34266e72017-12-05 01:01:43 +070062 self.tb.set_ta(0)
Piotr Krysik902f4eb2017-09-19 08:04:33 +020063 self.tb.stop()
64 self.tb.wait()
65
66 return 0
67
Vadim Yanitskiy01c6afd2017-10-19 01:14:24 +070068 # Gain control
Piotr Krysik902f4eb2017-09-19 08:04:33 +020069 elif self.verify_cmd(request, "SETRXGAIN", 1):
70 print("[i] Recv SETRXGAIN cmd")
71
72 # TODO: check gain value
73 gain = int(request[1])
Vadim Yanitskiy01c6afd2017-10-19 01:14:24 +070074 self.tb.set_rx_gain(gain)
75
76 return 0
77
78 elif self.verify_cmd(request, "SETTXGAIN", 1):
79 print("[i] Recv SETTXGAIN cmd")
80
81 # TODO: check gain value
82 gain = int(request[1])
83 self.tb.set_tx_gain(gain)
Piotr Krysik902f4eb2017-09-19 08:04:33 +020084
85 return 0
86
87 # Tuning Control
88 elif self.verify_cmd(request, "RXTUNE", 1):
89 print("[i] Recv RXTUNE cmd")
90
91 # TODO: check freq range
92 freq = int(request[1]) * 1000
Vadim Yanitskiy89aa4692017-11-14 00:15:20 +070093 self.tb.set_rx_freq(freq)
Piotr Krysik902f4eb2017-09-19 08:04:33 +020094
95 return 0
96
97 elif self.verify_cmd(request, "TXTUNE", 1):
98 print("[i] Recv TXTUNE cmd")
99
Vadim Yanitskiy89aa4692017-11-14 00:15:20 +0700100 # TODO: check freq range
101 freq = int(request[1]) * 1000
102 self.tb.set_tx_freq(freq)
103
Piotr Krysik902f4eb2017-09-19 08:04:33 +0200104 return 0
105
106 # Timeslot management
107 elif self.verify_cmd(request, "SETSLOT", 2):
108 print("[i] Recv SETSLOT cmd")
109
110 # Obtain TS index
111 tn = int(request[1])
112 if tn not in range(0, 8):
113 print("[!] TS index should be in range: 0..7")
114 return -1
115
116 # Ignore timeslot type for now
Vadim Yanitskiy962e2d82017-10-17 09:24:55 +0700117 config = int(request[2])
Piotr Krysik902f4eb2017-09-19 08:04:33 +0200118 print("[i] Configure timeslot filter to: %s"
Vadim Yanitskiy962e2d82017-10-17 09:24:55 +0700119 % ("drop all" if config == 0 else "TS %d" % tn))
Piotr Krysik902f4eb2017-09-19 08:04:33 +0200120
Vadim Yanitskiy962e2d82017-10-17 09:24:55 +0700121 if config == 0:
122 # Value 0 means 'drop all'
Vadim Yanitskiy89aa4692017-11-14 00:15:20 +0700123 self.tb.ts_filter.set_policy(
Vadim Yanitskiy962e2d82017-10-17 09:24:55 +0700124 grgsm.FILTER_POLICY_DROP_ALL)
125 else:
Vadim Yanitskiy89aa4692017-11-14 00:15:20 +0700126 self.tb.ts_filter.set_policy(
Vadim Yanitskiy962e2d82017-10-17 09:24:55 +0700127 grgsm.FILTER_POLICY_DEFAULT)
Vadim Yanitskiy89aa4692017-11-14 00:15:20 +0700128 self.tb.ts_filter.set_tn(tn)
Piotr Krysik902f4eb2017-09-19 08:04:33 +0200129
130 return 0
131
132 # Power measurement
133 elif self.verify_cmd(request, "MEASURE", 1):
134 print("[i] Recv MEASURE cmd")
135
136 # TODO: check freq range
137 meas_freq = int(request[1]) * 1000
Vadim Yanitskiyd54e8fb2019-01-19 09:28:23 +0700138 meas_dbm = str(self.tb.measure(meas_freq))
Piotr Krysik902f4eb2017-09-19 08:04:33 +0200139
140 return (0, [meas_dbm])
141
Vadim Yanitskiy34266e72017-12-05 01:01:43 +0700142 # Timing Advance control
143 elif self.verify_cmd(request, "SETTA", 1):
144 print("[i] Recv SETTA cmd")
145
146 # Check TA range
147 ta = int(request[1])
148 if ta < 0 or ta > 63:
149 print("[!] TA value must be in range: 0..63")
150 return -1
151
152 self.tb.set_ta(ta)
153 return 0
154
Piotr Krysik902f4eb2017-09-19 08:04:33 +0200155 # Misc
156 elif self.verify_cmd(request, "ECHO", 0):
157 print("[i] Recv ECHO cmd")
158 return 0
159
160 # Wrong / unknown command
161 else:
162 print("[!] Wrong request on CTRL interface")
163 return -1