Esempio n. 1
0
def bandwidth(bandwidth_rbs: Union[str, int, float]) -> float:
    """
    Map bandwidth in number of RBs to MHz
    TODO: TR-196 spec says this should be '6' rather than 'n6', but
    BaiCells eNodeB uses 'n6'. Need to resolve this.

    Args:
        bandwidth_rbs (str): Bandwidth in number of RBs
    Returns:
        str: Bandwidth in MHz
    """
    if bandwidth_rbs in BANDWIDTH_RBS_TO_MHZ_MAP:
        return BANDWIDTH_RBS_TO_MHZ_MAP[bandwidth_rbs]

    logger.warning('Unknown bandwidth_rbs (%s)', str(bandwidth_rbs))
    if bandwidth_rbs in BANDWIDTH_MHZ_LIST:
        return bandwidth_rbs
    elif isinstance(bandwidth_rbs, str):
        mhz = None
        if bandwidth_rbs.isdigit():
            mhz = int(bandwidth_rbs)
        elif bandwidth_rbs.replace('.', '', 1).isdigit():
            mhz = float(bandwidth_rbs)
        if mhz in BANDWIDTH_MHZ_LIST:
            return mhz
    raise ConfigurationError('Unknown bandwidth specification (%s)' %
                             str(bandwidth_rbs))
Esempio n. 2
0
 def _assert_param_in_model(self, param_name: ParameterName) -> None:
     trparam_model = self.data_model
     tr_param = trparam_model.get_parameter(param_name)
     if tr_param is None:
         logger.warning('Parameter <%s> not defined in model', param_name)
         raise ConfigurationError(
             f"Parameter not defined in model: {param_name}")
Esempio n. 3
0
def bandwidth(bandwidth_mhz):
    """
    Map bandwidth in MHz to number of RBs
    TODO: TR-196 spec says this should be '6' rather than 'n6', but
    BaiCells eNodeB uses 'n6'. Need to resolve this.

    Args:
        bandwidth_mhz (int): Bandwidth in MHz
    Returns:
        str: Bandwidth in RBS
    """
    if bandwidth_mhz == 1.4:
        bandwidth_rbs = 'n6'
    elif bandwidth_mhz == 3:
        bandwidth_rbs = 'n15'
    elif bandwidth_mhz == 5:
        bandwidth_rbs = 'n25'
    elif bandwidth_mhz == 10:
        bandwidth_rbs = 'n50'
    elif bandwidth_mhz == 15:
        bandwidth_rbs = 'n75'
    elif bandwidth_mhz == 20:
        bandwidth_rbs = 'n100'
    else:
        raise ConfigurationError('Unknown bandwidth_mhz (%s)' %
                                 str(bandwidth_mhz))
    return bandwidth_rbs
Esempio n. 4
0
    def read_msg(self, message: Any) -> Optional[str]:
        """
        In this case, we assume that we already know things such as the
        manufacturer OUI, and also the SW-version of the eNodeB which is
        sending the Inform message, so we don't process the message. We just
        check that we're getting the right message type that we expect.

        Returns:
            InformResponse
        """
        if type(message) == models.Fault:
            raise Tr069Error(
                'ACS in WaitInform state. Received a Fault message. '
                '(faultstring = %s)' % message.FaultString)
        elif not isinstance(message, models.Inform):
            raise ConfigurationError(
                'ACS in WaitInform state. Expected an Inform message. ' +
                'Received a %s message.' % type(message))

        is_correct_event = False
        for event in message.Event.EventStruct:
            logging.debug('Inform event: %s', event.EventCode)
            if event.EventCode == self.INFORM_EVENT_CODE:
                # Mark eNodeB as unconfigured, since some config params
                # are reset on reboot (e.g. perf mgmt enable)
                logging.info('eNodeB booting - reconfig required')
                self.acs.device_cfg = EnodebConfiguration(self.acs.data_model)
                is_correct_event = True
        if not is_correct_event:
            raise Tr069Error('Did not receive 1 BOOT event code in ' 'Inform')
        process_inform_message(message, self.acs.device_name,
                               self.acs.data_model, self.acs.device_cfg)
        return None
Esempio n. 5
0
 def _assert_param_in_model(self, param_name: ParameterName) -> None:
     trparam_model = self.data_model
     tr_param = trparam_model.get_parameter(param_name)
     if tr_param is None:
         logging.error('%s: Parameter <%s> not defined in model',
                       self.data_model.__name__, param_name)
         raise ConfigurationError("Parameter not defined in model.")
Esempio n. 6
0
def _calc_psd(eirp: float) -> int:
    psd = int(eirp)
    if not SAS_MIN_POWER_SPECTRAL_DENSITY <= psd <= SAS_MAX_POWER_SPECTRAL_DENSITY:  # noqa: WPS508
        raise ConfigurationError(
            'Power Spectral Density %d exceeds allowed range [%d, %d]' %
            (psd, SAS_MIN_POWER_SPECTRAL_DENSITY, SAS_MAX_POWER_SPECTRAL_DENSITY),
        )
    return psd
Esempio n. 7
0
 def read_msg(self, message: Any) -> AcsReadMsgResult:
     """
     Args: message: tr069 message
     Returns: name of the next state, if transition required
     """
     raise ConfigurationError(
         '%s should implement read_msg() if it '
         'needs to handle message reading' % self.__class__.__name__, )
Esempio n. 8
0
 def _get_param_value_from_path_suffix(
     suffix: str,
     path_list: List[str],
     param_values_by_path: Dict[str, Any],
 ) -> Any:
     for path in path_list:
         if path.endswith(suffix):
             return param_values_by_path[path]
     raise ConfigurationError('Did not receive expected info in Inform')
Esempio n. 9
0
def _get_param_values_by_path(inform: models.Inform, ) -> Dict[str, Any]:
    if not hasattr(inform, 'ParameterList') or \
            not hasattr(inform.ParameterList, 'ParameterValueStruct'):
        raise ConfigurationError('Did not receive ParamterList in Inform')
    param_values_by_path = {}
    for param_value in inform.ParameterList.ParameterValueStruct:
        path = param_value.Name
        value = param_value.Value.Data
        logger.debug('(Inform msg) Received parameter: %s = %s', path, value)
        param_values_by_path[path] = value
    return param_values_by_path
Esempio n. 10
0
def _set_pci(
    cfg: EnodebConfiguration,
    pci: Any,
) -> None:
    """
    Set the following parameters:
     - PCI
    """
    if pci not in range(0, 504 + 1):
        raise ConfigurationError('Invalid PCI (%d)' % pci)
    cfg.set_parameter(ParameterName.PCI, pci)
Esempio n. 11
0
    def get_msg(self, message: Any) -> AcsMsgAndTransition:
        """
        Produce a message to send back to the eNB.

        Args:
            message: TR-069 message which was already processed by read_msg

        Returns: Message and possible transition
        """
        raise ConfigurationError(
            '%s should implement get_msg() if it '
            'needs to produce messages' % self.__class__.__name__, )
Esempio n. 12
0
 def read_msg(self, message: Any) -> Optional[str]:
     """
     Args:
         message: models.Inform Tr069 Inform message
     """
     if not isinstance(message, models.Inform):
         raise ConfigurationError(
             'ACS in Disconnected state. Expected an Inform message. ' +
             'Received a %s message.' % type(message))
     process_inform_message(message, self.acs.device_name,
                            self.acs.data_model, self.acs.device_cfg)
     return None
Esempio n. 13
0
    def read_msg(self, message: Any) -> Optional[str]:
        """
        It's expected that we transition into this state right after receiving
        an Inform message and replying with an InformResponse. At that point,
        the eNB sends an empty HTTP request (aka DummyInput) to initiate the
        rest of the provisioning process
        """
        if not isinstance(message, models.DummyInput):
            raise ConfigurationError(
                'ACS in GetParameters state. Expected an Empty message. ' +
                'Received a %s message.' % type(message))

        return None
Esempio n. 14
0
def bandwidth(bandwidth_rbs: str) -> float:
    """

    Map bandwidth in number of RBs to MHz
    TODO: TR-196 spec says this should be '6' rather than 'n6', but
    BaiCells eNodeB uses 'n6'. Need to resolve this.

    Args:
        bandwidth_rbs (str): Bandwidth in number of RBs
    Returns:
        str: Bandwidth in MHz
    """
    if bandwidth_rbs not in BANDWIDTH_RBS_TO_MHZ_MAP:
        raise ConfigurationError('Unknown bandwidth_rbs (%s)' %
                                 str(bandwidth_rbs))
    return BANDWIDTH_RBS_TO_MHZ_MAP[bandwidth_rbs]
Esempio n. 15
0
 def _transition_for_unexpected_msg(self, message: Any) -> None:
     """
     eNB devices may send an Inform message in the middle of a provisioning
     session. To deal with this, transition to a state that expects an
     Inform message, but also track the status of the eNB as not having
     been disconnected.
     """
     if isinstance(message, models.Inform):
         logger.debug('ACS in (%s) state. Received an Inform message',
                      self.state.state_description())
         self._reset_state_machine(self.service)
     elif isinstance(message, models.Fault):
         logger.debug('ACS in (%s) state. Received a Fault <%s>',
                      self.state.state_description(), message.FaultString)
         self.transition(self.unexpected_fault_state_name)
     else:
         raise ConfigurationError('Cannot handle unexpected TR069 msg')
Esempio n. 16
0
def calc_bandwidth_mhz(low_freq_hz: int, high_freq_hz: int) -> float:
    """
    Calculate bandwidth in mhz for CBRS

    Args:
        low_freq_hz: int, Low frequency limit taken from available channel
        high_freq_hz: int, High frequency limit taken from available channel

    Returns:
        Bandwidth in mhz

    Raises:
        ConfigurationError: if bandwidth is not supported by the device
    """
    bandwidth_mhz = (high_freq_hz - low_freq_hz) / 1e6
    i = bisect_right(SAS_BANDWIDTHS, bandwidth_mhz)
    if not i:
        raise ConfigurationError('Unknown/unsupported bandwidth specification (%f)' % bandwidth_mhz)
    return SAS_BANDWIDTHS[i - 1]
Esempio n. 17
0
def _get_enb_config(
    mconfig: mconfigs_pb2.EnodebD,
    device_config: EnodebConfiguration,
) -> SingleEnodebConfig:
    # For fields that are specified per eNB
    if mconfig.enb_configs_by_serial is not None and \
            len(mconfig.enb_configs_by_serial) > 0:
        enb_serial = \
            device_config.get_parameter(ParameterName.SERIAL_NUMBER)
        if enb_serial in mconfig.enb_configs_by_serial:
            enb_config = mconfig.enb_configs_by_serial[enb_serial]
            earfcndl = enb_config.earfcndl
            pci = enb_config.pci
            allow_enodeb_transmit = enb_config.transmit_enabled
            tac = enb_config.tac
            bandwidth_mhz = enb_config.bandwidth_mhz
            cell_id = enb_config.cell_id
            duplex_mode = map_earfcndl_to_duplex_mode(earfcndl)
            subframe_assignment = None
            special_subframe_pattern = None
            if duplex_mode == DuplexMode.TDD:
                subframe_assignment = enb_config.subframe_assignment
                special_subframe_pattern = \
                    enb_config.special_subframe_pattern
        else:
            raise ConfigurationError('Could not construct desired config '
                                     'for eNB')
    else:
        pci = mconfig.pci
        allow_enodeb_transmit = mconfig.allow_enodeb_transmit
        tac = mconfig.tac
        bandwidth_mhz = mconfig.bandwidth_mhz
        cell_id = DEFAULT_CELL_IDENTITY
        if mconfig.tdd_config is not None and str(mconfig.tdd_config) != '':
            earfcndl = mconfig.tdd_config.earfcndl
            subframe_assignment = mconfig.tdd_config.subframe_assignment
            special_subframe_pattern = \
                mconfig.tdd_config.special_subframe_pattern
        elif mconfig.fdd_config is not None and str(mconfig.fdd_config) != '':
            earfcndl = mconfig.fdd_config.earfcndl
            subframe_assignment = None
            special_subframe_pattern = None
        else:
            earfcndl = mconfig.earfcndl
            subframe_assignment = mconfig.subframe_assignment
            special_subframe_pattern = mconfig.special_subframe_pattern

    # And now the rest of the fields
    plmnid_list = mconfig.plmnid_list

    single_enodeb_config = SingleEnodebConfig(
        earfcndl=earfcndl,
        subframe_assignment=subframe_assignment,
        special_subframe_pattern=special_subframe_pattern,
        pci=pci,
        plmnid_list=plmnid_list,
        tac=tac,
        bandwidth_mhz=bandwidth_mhz,
        cell_id=cell_id,
        allow_enodeb_transmit=allow_enodeb_transmit,
        mme_address=None,
        mme_port=None)
    return single_enodeb_config
Esempio n. 18
0
 def get_msg(self) -> AcsMsgAndTransition:
     raise ConfigurationError('%s should implement get_msg() if it '
                              'needs to produce messages' %
                              self.__class__.__name__)
Esempio n. 19
0
 def read_msg(self, message: Any) -> Optional[str]:
     if not isinstance(message, models.DummyInput):
         raise ConfigurationError(
             'ACS in SendGetTransientParameters state. Expected an ' +
             'Empty message. ' + 'Received a %s message.' % type(message))
     return None
Esempio n. 20
0
 def add_object(self, param_name: ParameterName) -> None:
     if param_name in self._numbered_objects:
         raise ConfigurationError("Configuration already has object")
     self._numbered_objects[param_name] = {}
Esempio n. 21
0
 def delete_object(self, param_name: ParameterName) -> None:
     if param_name not in self._numbered_objects:
         raise ConfigurationError("Configuration does not have object")
     del self._numbered_objects[param_name]
Esempio n. 22
0
def _set_earfcn_freq_band_mode(
    device_cfg: EnodebConfiguration,
    cfg: EnodebConfiguration,
    data_model: DataModel,
    earfcndl: int,
) -> None:
    """
    Set the following parameters:
     - EARFCNDL
     - EARFCNUL
     - Band
    """
    # Note: validation of EARFCNDL done by mapping function. If invalid
    # EARFCN, raise ConfigurationError
    try:
        band, duplex_mode, earfcnul = map_earfcndl_to_band_earfcnul_mode(
            earfcndl)
    except ValueError as err:
        raise ConfigurationError(err)

    # Verify capabilities
    duplex_capability =\
        device_cfg.get_parameter(ParameterName.DUPLEX_MODE_CAPABILITY)
    if duplex_mode == DuplexMode.TDD and duplex_capability != 'TDDMode':
        raise ConfigurationError(
            ('eNodeB duplex mode capability is <{0}>, '
             'but earfcndl is <{1}>, giving duplex '
             'mode <{2}> instead').format(duplex_capability, str(earfcndl),
                                          str(duplex_mode)))
    elif duplex_mode == DuplexMode.FDD and duplex_capability != 'FDDMode':
        raise ConfigurationError(
            ('eNodeB duplex mode capability is <{0}>, '
             'but earfcndl is <{1}>, giving duplex '
             'mode <{2}> instead').format(duplex_capability, str(earfcndl),
                                          str(duplex_mode)))
    elif duplex_mode not in [DuplexMode.TDD, DuplexMode.FDD]:
        raise ConfigurationError('Invalid duplex mode (%s)' % str(duplex_mode))

    # Baicells indicated that they no longer use the band capability list,
    # so it may not be populated correctly
    band_capability_list = device_cfg.get_parameter(
        ParameterName.BAND_CAPABILITY)
    band_capabilities = band_capability_list.split(',')
    if str(band) not in band_capabilities:
        logging.warning(
            'Band %d not in capabilities list (%s). Continuing'
            ' with config because capabilities list may not be'
            ' correct', band, band_capabilities)

    cfg.set_parameter(ParameterName.EARFCNDL, earfcndl)
    if duplex_mode == DuplexMode.FDD:
        cfg.set_parameter(ParameterName.EARFCNUL, earfcnul)
    else:
        logging.debug('Not setting EARFCNUL - duplex mode is not FDD')

    _set_param_if_present(cfg, data_model, ParameterName.BAND, band)

    if duplex_mode == DuplexMode.TDD:
        logging.debug('Set EARFCNDL=%d, Band=%d', earfcndl, band)
    else:
        logging.debug('Set EARFCNDL=%d, EARFCNUL=%d, Band=%d', earfcndl,
                      earfcnul, band)
Esempio n. 23
0
def config_assert(condition: bool, message: str = None) -> None:
    """ To be used in place of 'assert' so that ConfigurationError is raised
        for all config-related exceptions. """
    if not condition:
        raise ConfigurationError(message)
Esempio n. 24
0
 def read_msg(self, message: Any) -> Optional[str]:
     if not isinstance(message, models.DummyInput):
         raise ConfigurationError(
             'ACS in EnableAdmin state. Expected an Empty message. '
             'Received a %s message.' % type(message))
     return None