forked from ptrkrysik/gr-gsm
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'fixeria/trx' into development
# Conflicts: # swig/grgsm_swig.i
- Loading branch information
Showing
18 changed files
with
1,377 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
#!/usr/bin/env python2 | ||
# -*- coding: utf-8 -*- | ||
|
||
# GR-GSM based transceiver | ||
# CTRL interface implementation | ||
# | ||
# (C) 2016-2017 by Vadim Yanitskiy <[email protected]> | ||
# | ||
# All Rights Reserved | ||
# | ||
# This program 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 2 of the License, or | ||
# (at your option) any later version. | ||
# | ||
# This program 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 this program; if not, write to the Free Software Foundation, Inc., | ||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
|
||
from udp_link import UDPLink | ||
|
||
class CTRLInterface(UDPLink): | ||
def handle_rx(self, data): | ||
if self.verify_req(data): | ||
request = self.prepare_req(data) | ||
rc = self.parse_cmd(request) | ||
|
||
if type(rc) is tuple: | ||
self.send_response(request, rc[0], rc[1]) | ||
else: | ||
self.send_response(request, rc) | ||
else: | ||
print("[!] Wrong data on CTRL interface") | ||
|
||
def verify_req(self, data): | ||
# Verify command signature | ||
return data.startswith("CMD") | ||
|
||
def prepare_req(self, data): | ||
# Strip signature, paddings and \0 | ||
request = data[4:].strip().strip("\0") | ||
# Split into a command and arguments | ||
request = request.split(" ") | ||
# Now we have something like ["TXTUNE", "941600"] | ||
return request | ||
|
||
def verify_cmd(self, request, cmd, argc): | ||
# Check if requested command matches | ||
if request[0] != cmd: | ||
return False | ||
|
||
# And has enough arguments | ||
if len(request) - 1 != argc: | ||
return False | ||
|
||
# Check if all arguments are numeric | ||
for v in request[1:]: | ||
if not v.isdigit(): | ||
return False | ||
|
||
return True | ||
|
||
def send_response(self, request, response_code, params = None): | ||
# Include status code, for example ["TXTUNE", "0", "941600"] | ||
request.insert(1, str(response_code)) | ||
|
||
# Optionally append command specific parameters | ||
if params is not None: | ||
request += params | ||
|
||
# Add the response signature, and join back to string | ||
response = "RSP " + " ".join(request) + "\0" | ||
# Now we have something like "RSP TXTUNE 0 941600" | ||
self.send(response) | ||
|
||
def parse_cmd(self, request): | ||
raise NotImplementedError |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
#!/usr/bin/env python2 | ||
# -*- coding: utf-8 -*- | ||
|
||
# GR-GSM based transceiver | ||
# CTRL interface for OsmocomBB | ||
# | ||
# (C) 2016-2017 by Vadim Yanitskiy <[email protected]> | ||
# | ||
# All Rights Reserved | ||
# | ||
# This program 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 2 of the License, or | ||
# (at your option) any later version. | ||
# | ||
# This program 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 this program; if not, write to the Free Software Foundation, Inc., | ||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
|
||
from ctrl_if import CTRLInterface | ||
|
||
class CTRLInterfaceBB(CTRLInterface): | ||
def __init__(self, remote_addr, remote_port, bind_port, tb, pm): | ||
print("[i] Init CTRL interface") | ||
CTRLInterface.__init__(self, remote_addr, remote_port, bind_port) | ||
|
||
# Set link to the follow graph (top block) | ||
self.tb = tb | ||
# Power measurement | ||
self.pm = pm | ||
|
||
def shutdown(self): | ||
print("[i] Shutdown CTRL interface") | ||
CTRLInterface.shutdown(self) | ||
|
||
def parse_cmd(self, request): | ||
# Power control | ||
if self.verify_cmd(request, "POWERON", 0): | ||
print("[i] Recv POWERON CMD") | ||
|
||
# Ensure transceiver isn't working | ||
if self.tb.trx_started: | ||
print("[!] Transceiver already started") | ||
return -1 | ||
|
||
# Ensure transceiver is ready to start | ||
if not self.tb.check_available(): | ||
print("[!] Transceiver isn't ready to start") | ||
return -1 | ||
|
||
print("[i] Starting transceiver...") | ||
self.tb.trx_started = True | ||
self.tb.start() | ||
|
||
return 0 | ||
|
||
elif self.verify_cmd(request, "POWEROFF", 0): | ||
print("[i] Recv POWEROFF cmd") | ||
|
||
# TODO: flush all buffers between blocks | ||
if self.tb.trx_started: | ||
print("[i] Stopping transceiver...") | ||
self.tb.trx_started = False | ||
self.tb.stop() | ||
self.tb.wait() | ||
|
||
return 0 | ||
|
||
elif self.verify_cmd(request, "SETRXGAIN", 1): | ||
print("[i] Recv SETRXGAIN cmd") | ||
|
||
# TODO: check gain value | ||
gain = int(request[1]) | ||
self.tb.set_gain(gain) | ||
|
||
return 0 | ||
|
||
# Tuning Control | ||
elif self.verify_cmd(request, "RXTUNE", 1): | ||
print("[i] Recv RXTUNE cmd") | ||
|
||
# TODO: check freq range | ||
freq = int(request[1]) * 1000 | ||
self.tb.set_fc(freq) | ||
|
||
return 0 | ||
|
||
elif self.verify_cmd(request, "TXTUNE", 1): | ||
print("[i] Recv TXTUNE cmd") | ||
|
||
# TODO: is not implemented yet | ||
return 0 | ||
|
||
# Timeslot management | ||
elif self.verify_cmd(request, "SETSLOT", 2): | ||
print("[i] Recv SETSLOT cmd") | ||
|
||
# Obtain TS index | ||
tn = int(request[1]) | ||
if tn not in range(0, 8): | ||
print("[!] TS index should be in range: 0..7") | ||
return -1 | ||
|
||
# Ignore timeslot type for now | ||
# Value 0 means 'drop all' | ||
config = -1 if int(request[2]) == 0 else tn | ||
|
||
print("[i] Configure timeslot filter to: %s" | ||
% ("drop all" if config == -1 else "TS %d" % tn)) | ||
|
||
# HACK: configure built-in timeslot filter | ||
self.tb.gsm_trx_if.ts_filter_set_tn(config) | ||
|
||
return 0 | ||
|
||
# Power measurement | ||
elif self.verify_cmd(request, "MEASURE", 1): | ||
print("[i] Recv MEASURE cmd") | ||
|
||
# TODO: check freq range | ||
meas_freq = int(request[1]) * 1000 | ||
|
||
# HACK: send fake low power values | ||
# until actual power measurement is implemented | ||
meas_dbm = str(self.pm.measure(meas_freq)) | ||
|
||
return (0, [meas_dbm]) | ||
|
||
# Misc | ||
elif self.verify_cmd(request, "ECHO", 0): | ||
print("[i] Recv ECHO cmd") | ||
return 0 | ||
|
||
# Wrong / unknown command | ||
else: | ||
print("[!] Wrong request on CTRL interface") | ||
return -1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
#!/usr/bin/env python2 | ||
# -*- coding: utf-8 -*- | ||
|
||
# Virtual Um-interface (fake transceiver) | ||
# Power measurement emulation for BB | ||
# | ||
# (C) 2017 by Vadim Yanitskiy <[email protected]> | ||
# | ||
# All Rights Reserved | ||
# | ||
# This program 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 2 of the License, or | ||
# (at your option) any later version. | ||
# | ||
# This program 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 this program; if not, write to the Free Software Foundation, Inc., | ||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
|
||
from random import randint | ||
|
||
class FakePM: | ||
# Freq. list for good power level | ||
bts_list = [] | ||
|
||
def __init__(self, noise_min, noise_max, bts_min, bts_max): | ||
# Save power level ranges | ||
self.noise_min = noise_min | ||
self.noise_max = noise_max | ||
self.bts_min = bts_min | ||
self.bts_max = bts_max | ||
|
||
def measure(self, bts): | ||
if bts in self.bts_list: | ||
return randint(self.bts_min, self.bts_max) | ||
else: | ||
return randint(self.noise_min, self.noise_max) | ||
|
||
def update_bts_list(self, new_list): | ||
self.bts_list = new_list | ||
|
||
def add_bts_list(self, add_list): | ||
self.bts_list += add_list | ||
|
||
def del_bts_list(self, del_list): | ||
for item in del_list: | ||
if item in self.bts_list: | ||
self.bts_list.remove(item) |
Oops, something went wrong.