From 42bce2bd5b62eaa656f76a962c895238bc6f148e Mon Sep 17 00:00:00 2001 From: Vadim Yanitskiy Date: Sun, 13 Jan 2019 13:58:41 +0700 Subject: trx_toolkit/transceiver.py: add support for child transceivers A BTS can (optionally) have more than one transceiver. In this case additional (let's say child) transceivers basically share the same clock source of the first transceiver, and being powered on / off as soon as the first transceiver is powered on / off. Change-Id: I7e97b7f32dde7ab74779133e9d7504f1d0fce60c --- src/target/trx_toolkit/transceiver.py | 43 ++++++++++++++++++++---- src/target/trx_toolkit/trx_list.py | 63 +++++++++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+), 6 deletions(-) create mode 100644 src/target/trx_toolkit/trx_list.py (limited to 'src/target') diff --git a/src/target/trx_toolkit/transceiver.py b/src/target/trx_toolkit/transceiver.py index edd4d31f..57ca531d 100644 --- a/src/target/trx_toolkit/transceiver.py +++ b/src/target/trx_toolkit/transceiver.py @@ -4,7 +4,7 @@ # TRX Toolkit # Transceiver implementation # -# (C) 2018 by Vadim Yanitskiy +# (C) 2018-2019 by Vadim Yanitskiy # # All Rights Reserved # @@ -27,6 +27,7 @@ import logging as log from ctrl_if_trx import CTRLInterfaceTRX from data_if import DATAInterface from udp_link import UDPLink +from trx_list import TRXList class Transceiver: """ Base transceiver implementation. @@ -54,6 +55,21 @@ class Transceiver: NOTE: we don't store the associated channel combinations, as they are only useful for burst detection and demodulation. + == Child transceivers + + A BTS can (optionally) have more than one transceiver. In this case + additional (let's say child) transceivers basically share the same + clock source of the first transceiver, so UDP port mapping is a bit + different, for example: + + (trx_0) clck=5700, ctrl=5701, data=5702, + (trx_1) ctrl=5703, data=5704, + (trx_2) ctrl=5705, data=5706. + ... + + As soon as the first transceiver is powered on / off, + all child transceivers are also powered on / off. + == Clock distribution (optional) The clock indications are not expected by L1 when transceiver @@ -75,21 +91,26 @@ class Transceiver: """ def __init__(self, bind_addr, remote_addr, base_port, - clck_gen = None, pwr_meas = None): + child_idx = 0, clck_gen = None, pwr_meas = None): # Connection info self.remote_addr = remote_addr self.bind_addr = bind_addr self.base_port = base_port + self.child_idx = child_idx + + # Child transceiver cannot have its own clock + if clck_gen is not None and child_idx > 0: + raise TypeError("Child transceiver cannot have its own clock") # Init DATA interface self.data_if = DATAInterface( - remote_addr, base_port + 102, - bind_addr, base_port + 2) + remote_addr, base_port + child_idx * 2 + 102, + bind_addr, base_port + child_idx * 2 + 2) # Init CTRL interface self.ctrl_if = CTRLInterfaceTRX(self, - remote_addr, base_port + 101, - bind_addr, base_port + 1) + remote_addr, base_port + child_idx * 2 + 101, + bind_addr, base_port + child_idx * 2 + 1) # Init optional CLCK interface self.clck_gen = clck_gen @@ -111,12 +132,22 @@ class Transceiver: # List of active (configured) timeslots self.ts_list = [] + # List of child transceivers + self.child_trx_list = TRXList() + # To be overwritten if required, # no custom command handlers by default def ctrl_cmd_handler(self, request): return None def power_event_handler(self, event): + # Update child transceivers + for trx in self.child_trx_list.trx_list: + if event == "POWERON": + trx.running = True + else: + trx.running = False + # Trigger clock generator if required if self.clck_gen is not None: clck_links = self.clck_gen.clck_links diff --git a/src/target/trx_toolkit/trx_list.py b/src/target/trx_toolkit/trx_list.py new file mode 100644 index 00000000..7bea5604 --- /dev/null +++ b/src/target/trx_toolkit/trx_list.py @@ -0,0 +1,63 @@ +#!/usr/bin/env python2 +# -*- coding: utf-8 -*- + +# TRX Toolkit +# Transceiver list implementation +# +# (C) 2019 by Vadim Yanitskiy +# +# 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. + +class TRXList: + """ Transceiver list implementation. + + This class is a simple wrapper around generic Python's list. + The aim is to simplify management of multiple Transceiver + instances, e.g. appending, removing and finding them. + + """ + + def __init__(self): + self.trx_list = [] + + def __getitem__(self, i): + return self.trx_list[i] + + def find_trx(self, remote_addr, base_port, child_idx = 0): + for trx in self.trx_list: + if trx.remote_addr != remote_addr: + continue + if trx.base_port != base_port: + continue + if trx.child_idx != child_idx: + continue + return trx + + return None + + def add_trx(self, trx): + if trx in self.trx_list: + raise IndexError("TRX '%s' is already in the list" % trx) + if self.find_trx(trx.remote_addr, trx.base_port, trx.child_idx): + raise IndexError("TRX '%s' has duplicate in the list" % trx) + + self.trx_list.append(trx) + + def del_trx(self, trx): + if trx not in self.trx_list: + raise IndexError("TRX '%s' is not in the list" % trx) + self.trx_list.remove(trx) -- cgit v1.2.3