2018-02-13 22:22:03 +00:00
|
|
|
/* (C) 2008-2018 by Harald Welte <laforge@gnumonks.org>
|
2008-12-25 23:28:35 +00:00
|
|
|
*
|
2008-12-23 20:25:15 +00:00
|
|
|
* All Rights Reserved
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
2011-01-01 14:25:50 +00:00
|
|
|
* it under the terms of the GNU Affero General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 3 of the License, or
|
2008-12-23 20:25:15 +00:00
|
|
|
* (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
|
2011-01-01 14:25:50 +00:00
|
|
|
* GNU Affero General Public License for more details.
|
2008-12-23 20:25:15 +00:00
|
|
|
*
|
2011-01-01 14:25:50 +00:00
|
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
2008-12-23 20:25:15 +00:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
2009-02-24 22:36:40 +00:00
|
|
|
#include <stdio.h>
|
2008-12-23 20:25:15 +00:00
|
|
|
#include <string.h>
|
2009-06-20 16:15:19 +00:00
|
|
|
#include <errno.h>
|
2009-08-08 14:12:58 +00:00
|
|
|
#include <ctype.h>
|
2016-05-11 10:45:13 +00:00
|
|
|
#include <stdbool.h>
|
2019-10-31 14:59:49 +00:00
|
|
|
#include <inttypes.h>
|
2010-03-14 07:37:43 +00:00
|
|
|
#include <netinet/in.h>
|
large refactoring: use FSMs for lchans; add inter-BSC HO
Add FSMs:
- timeslot_fsm: handle dynamic timeslots and OML+RSL availability.
- lchan_fsm: handle an individual lchan activation, RTP stream and release,
signal the appropriate calling FSMs on success, failure, release.
- mgw_endpoint_fsm: handle one entire endpoint with several CI.
- assignment_fsm: BSSMAP Assignment Request.
- handover_fsm: all of intra, inter-MO and inter-MT handover.
Above FSMs absorb large parts of the gscon FSM. The gscon FSM was surpassing
the maximum amount events (32), and it is more logical to treat assignment,
handover and MGW procedures in separate FSMs.
- Add logging macros for each FSM type:
- LOG_TS()
- LOG_LCHAN()
- LOG_MGWEP(), LOG_CI()
- LOG_ASSIGNMENT()
- LOG_HO()
These log with the osmo_fsm_inst where present.
New style decision: logging without a final newline char is awkward,
especially for gsmtap logging and when other logs interleave LOGPC() calls;
we have various cases where the final \n goes missing, and also this invokes
the log category checking N times instead of once.
So I decided to make these macros *always* append a newline, but only if
there is no final newline yet. I hope that the compiler optimizes the
strlen() of the constant format strings away. Thus I can log with or without
typing "\n" and always get an \n termination anyway.
General:
- replace osmo_timers, state enums and program-wide osmo_signal_dispatch()
with dedicated FSM timeouts, states and events.
- introduce a common way to handle Tnnn timers: gsm_timers.h/.c: struct T_def.
These can be used (with some macro magic) to define a state's timeout once,
and not make mistakes for each osmo_fsm_inst_state_chg().
Details:
bsc_subscr_conn_fsm.c:
- move most states of this FSM to lchan_fsm, assignment_fsm, handover_fsm and
mgw_endpoint_fsm.
- There is exactly one state for an ongoing Assignment, with all details
handled in conn->assignment.fi. The state relies on the assignment_fsm's
timeout.
- There is one state for an ongoing Handover; except for an incoming Handover
from a remote BSS, the gscon remains in ST_INIT until the new lchan and conn
are both established.
- move bssmap_add_lcls_status() to osmo_bsc_lcls.c
abis_rsl.c:
- move all dynamic timeslot logic away into timeslot_fsm. Only keep plain send/receive functions in
abis_rsl.c
- reduce some rsl functions to merely send a message, rename to "_tx_".
- rsl_ipacc_mdcx(): add '_tx_' in the name; move parts that change the lchan state out into the
lchan_fsm, the lchan->abis_ip.* are now set there prior to invoking this function.
- move all timers and error/release handling away into various FSMs.
- tweak ipa_smod_s_for_lchan() and ipa_rtp_pt_for_lchan() to not require an
lchan passed, but just mode,type that they require. Rename to
ipacc_speech_mode*() and ipacc_payload_type().
- add rsl_forward_layer3_info, used for inter-BSC HO MO, to just send the RR
message received during BSSMAP Handover Command.
- move various logging to LOG_LCHAN() in order to log with the lchan FSM instance.
One drawback is that the lchan FSM is limited to one logging category, i.e. this moves some logging
from DRR to DRSL. It might actually make sense to combine those categories.
- lose LOGP...LOGPC logging cascades: they are bad for gsmtap logging and for performance.
- handle_classmark_chg(): change logging, move cm2 len check out of the cm3 condition (I hope that's
correct).
- gsm48_send_ho_cmd(): split off gsm48_make_ho_cmd() which doesn't send right away, so that during
inter-bsc HO we can make an RR Handover Command to send via the MSC to the remote BSS.
assignment_fsm.c:
- the Chan Mode Modify in case of re-using the same lchan is not implemented
yet, because this was also missing in the previous implementation (OS#3357).
osmo_bsc_api.c:
- simplify bsc_mr_config() and move to lchan_fsm.c, the only caller; rename to
lchan_mr_config(). (bsc_mr_config() used to copy the values to mr_bts_lv
twice, once by member assignment and then again with a memcpy.)
- During handover, we used to copy the MR config from the old lchan. Since we
may handover between FR and HR, rather set the MR Config anew every time, so
that FR rates are always available on FR lchans, and never on HR lchans.
Depends: I03ee7ce840ecfa0b6a33358e7385528aabd4873f (libosmocore),
I1f2918418c38918c5ac70acaa51a47adfca12b5e (libosmocore)
Change-Id: I82e3f918295daa83274a4cf803f046979f284366
2018-05-14 16:14:15 +00:00
|
|
|
#include <talloc.h>
|
2010-03-14 07:37:43 +00:00
|
|
|
|
2011-03-22 15:47:59 +00:00
|
|
|
#include <osmocom/core/linuxlist.h>
|
large refactoring: use FSMs for lchans; add inter-BSC HO
Add FSMs:
- timeslot_fsm: handle dynamic timeslots and OML+RSL availability.
- lchan_fsm: handle an individual lchan activation, RTP stream and release,
signal the appropriate calling FSMs on success, failure, release.
- mgw_endpoint_fsm: handle one entire endpoint with several CI.
- assignment_fsm: BSSMAP Assignment Request.
- handover_fsm: all of intra, inter-MO and inter-MT handover.
Above FSMs absorb large parts of the gscon FSM. The gscon FSM was surpassing
the maximum amount events (32), and it is more logical to treat assignment,
handover and MGW procedures in separate FSMs.
- Add logging macros for each FSM type:
- LOG_TS()
- LOG_LCHAN()
- LOG_MGWEP(), LOG_CI()
- LOG_ASSIGNMENT()
- LOG_HO()
These log with the osmo_fsm_inst where present.
New style decision: logging without a final newline char is awkward,
especially for gsmtap logging and when other logs interleave LOGPC() calls;
we have various cases where the final \n goes missing, and also this invokes
the log category checking N times instead of once.
So I decided to make these macros *always* append a newline, but only if
there is no final newline yet. I hope that the compiler optimizes the
strlen() of the constant format strings away. Thus I can log with or without
typing "\n" and always get an \n termination anyway.
General:
- replace osmo_timers, state enums and program-wide osmo_signal_dispatch()
with dedicated FSM timeouts, states and events.
- introduce a common way to handle Tnnn timers: gsm_timers.h/.c: struct T_def.
These can be used (with some macro magic) to define a state's timeout once,
and not make mistakes for each osmo_fsm_inst_state_chg().
Details:
bsc_subscr_conn_fsm.c:
- move most states of this FSM to lchan_fsm, assignment_fsm, handover_fsm and
mgw_endpoint_fsm.
- There is exactly one state for an ongoing Assignment, with all details
handled in conn->assignment.fi. The state relies on the assignment_fsm's
timeout.
- There is one state for an ongoing Handover; except for an incoming Handover
from a remote BSS, the gscon remains in ST_INIT until the new lchan and conn
are both established.
- move bssmap_add_lcls_status() to osmo_bsc_lcls.c
abis_rsl.c:
- move all dynamic timeslot logic away into timeslot_fsm. Only keep plain send/receive functions in
abis_rsl.c
- reduce some rsl functions to merely send a message, rename to "_tx_".
- rsl_ipacc_mdcx(): add '_tx_' in the name; move parts that change the lchan state out into the
lchan_fsm, the lchan->abis_ip.* are now set there prior to invoking this function.
- move all timers and error/release handling away into various FSMs.
- tweak ipa_smod_s_for_lchan() and ipa_rtp_pt_for_lchan() to not require an
lchan passed, but just mode,type that they require. Rename to
ipacc_speech_mode*() and ipacc_payload_type().
- add rsl_forward_layer3_info, used for inter-BSC HO MO, to just send the RR
message received during BSSMAP Handover Command.
- move various logging to LOG_LCHAN() in order to log with the lchan FSM instance.
One drawback is that the lchan FSM is limited to one logging category, i.e. this moves some logging
from DRR to DRSL. It might actually make sense to combine those categories.
- lose LOGP...LOGPC logging cascades: they are bad for gsmtap logging and for performance.
- handle_classmark_chg(): change logging, move cm2 len check out of the cm3 condition (I hope that's
correct).
- gsm48_send_ho_cmd(): split off gsm48_make_ho_cmd() which doesn't send right away, so that during
inter-bsc HO we can make an RR Handover Command to send via the MSC to the remote BSS.
assignment_fsm.c:
- the Chan Mode Modify in case of re-using the same lchan is not implemented
yet, because this was also missing in the previous implementation (OS#3357).
osmo_bsc_api.c:
- simplify bsc_mr_config() and move to lchan_fsm.c, the only caller; rename to
lchan_mr_config(). (bsc_mr_config() used to copy the values to mr_bts_lv
twice, once by member assignment and then again with a memcpy.)
- During handover, we used to copy the MR config from the old lchan. Since we
may handover between FR and HR, rather set the MR Config anew every time, so
that FR rates are always available on FR lchans, and never on HR lchans.
Depends: I03ee7ce840ecfa0b6a33358e7385528aabd4873f (libosmocore),
I1f2918418c38918c5ac70acaa51a47adfca12b5e (libosmocore)
Change-Id: I82e3f918295daa83274a4cf803f046979f284366
2018-05-14 16:14:15 +00:00
|
|
|
#include <osmocom/core/byteswap.h>
|
2011-03-22 15:47:59 +00:00
|
|
|
#include <osmocom/gsm/gsm_utils.h>
|
2011-05-23 18:30:39 +00:00
|
|
|
#include <osmocom/gsm/abis_nm.h>
|
2011-03-22 15:47:59 +00:00
|
|
|
#include <osmocom/core/statistics.h>
|
2016-05-11 10:45:13 +00:00
|
|
|
#include <osmocom/gsm/protocol/gsm_04_08.h>
|
2017-07-09 20:09:18 +00:00
|
|
|
#include <osmocom/gsm/gsm48.h>
|
2018-03-22 03:54:57 +00:00
|
|
|
#include <osmocom/gsm/gsm0808_utils.h>
|
2008-12-23 20:25:15 +00:00
|
|
|
|
2017-09-04 13:15:32 +00:00
|
|
|
#include <osmocom/bsc/gsm_data.h>
|
2019-03-12 17:53:26 +00:00
|
|
|
#include <osmocom/bsc/osmo_bsc_lcls.h>
|
2019-11-12 15:30:30 +00:00
|
|
|
#include <osmocom/bsc/abis_rsl.h>
|
2017-09-04 13:15:32 +00:00
|
|
|
#include <osmocom/bsc/abis_nm.h>
|
HO prep: introduce per-BTS handover config, with defaults on net node
It is desirable to allow configuring handover for each individual network cell.
At the same time, it is desirable to set global defaults.
Treat the 'network' node handover parameters as global defaults, add another
set of parameters for each individual BTS.
This raises questions on how the 'network' node should affect the individual
BTS. The simplistic solution would have been: on creating a BTS in the config,
just copy the current defaults; with serious drawbacks:
- tweaking any parameter in the telnet VTY on network node will never affect
any running BTS.
- network node defaults *must* be issued before the bts sections in the config
file.
- when writing a config back to file, we would copy all net node defaults to
each BTS node, making the network node configs pointless.
Instead, add a handover_cfg API that tracks whether a given node has a value
set or not. A bts node ho_cfg gets a pointer to the network node config and
returns those values if locally unset. If no value is set on any node, use the
"factory" defaults, which are hardcoded in the API. Only write back exactly
those config items that were actually issued in a config file / on the telnet
VTY. (ho_cfg API wise, we could trivially add another ho_cfg level per TRX if
we so desire in the future.)
Implement ho parameters as an opaque config struct with getters and setters to
ensure the tracking is always heeded. Opaqueness dictates allocating instead of
direct embedding in gsm_network and gsm_bts structs, ctx is gsm_net / bts.
This is 100% backwards compatible to
old configs.
- No VTY command syntax changes (only the online help).
- If a 'bts' sets nothing, it will use the 'network' defaults.
- The 'show network' output only changes in presence of individual BTS configs.
On 'show network', say "Handover: On|Off" as before, iff all BTS reflect
identical behavior. Otherwise, output BTS counts of handover being enabled or
not.
Use the same set of VTY commands (same VTY cmd syntax as before) on network and
BTS nodes, i.e. don't duplicate VTY code. From the current vty->node, figure
out which ho_cfg to modify.
For linking, add handover_cfg.c (the value API) in libcommon, while the
handover_vty.c is in libbsc. This is mainly because some utility programs use
gsm_network and hence suck in the ho stuff, but don't need the VTY commands.
Review the VTY online help strings.
Add VTY transcript test for handover options, testing config propagation from
network to bts nodes, 'show network' output and VTY online help strings.
(Needs recent addition of '... !' wildcard to osmo_interact_common.py.)
I considered leaving parts of this more readable, but in the end decided for
heavy use of macros to define and declare the API, because more values will be
added in upcoming patches and I want to prevent myself from messing them up.
Inspired-by: jolly/new_handover branch, which moves the config to 'bts' level
Depends: I7c1ebb2e7f059047903a53de26a0ec1ce7fa9b98 (osmo-python-tests)
Change-Id: I79d35f6d3c0fbee67904378ad7f216df34fde79a
2017-11-27 20:29:33 +00:00
|
|
|
#include <osmocom/bsc/handover_cfg.h>
|
large refactoring: use FSMs for lchans; add inter-BSC HO
Add FSMs:
- timeslot_fsm: handle dynamic timeslots and OML+RSL availability.
- lchan_fsm: handle an individual lchan activation, RTP stream and release,
signal the appropriate calling FSMs on success, failure, release.
- mgw_endpoint_fsm: handle one entire endpoint with several CI.
- assignment_fsm: BSSMAP Assignment Request.
- handover_fsm: all of intra, inter-MO and inter-MT handover.
Above FSMs absorb large parts of the gscon FSM. The gscon FSM was surpassing
the maximum amount events (32), and it is more logical to treat assignment,
handover and MGW procedures in separate FSMs.
- Add logging macros for each FSM type:
- LOG_TS()
- LOG_LCHAN()
- LOG_MGWEP(), LOG_CI()
- LOG_ASSIGNMENT()
- LOG_HO()
These log with the osmo_fsm_inst where present.
New style decision: logging without a final newline char is awkward,
especially for gsmtap logging and when other logs interleave LOGPC() calls;
we have various cases where the final \n goes missing, and also this invokes
the log category checking N times instead of once.
So I decided to make these macros *always* append a newline, but only if
there is no final newline yet. I hope that the compiler optimizes the
strlen() of the constant format strings away. Thus I can log with or without
typing "\n" and always get an \n termination anyway.
General:
- replace osmo_timers, state enums and program-wide osmo_signal_dispatch()
with dedicated FSM timeouts, states and events.
- introduce a common way to handle Tnnn timers: gsm_timers.h/.c: struct T_def.
These can be used (with some macro magic) to define a state's timeout once,
and not make mistakes for each osmo_fsm_inst_state_chg().
Details:
bsc_subscr_conn_fsm.c:
- move most states of this FSM to lchan_fsm, assignment_fsm, handover_fsm and
mgw_endpoint_fsm.
- There is exactly one state for an ongoing Assignment, with all details
handled in conn->assignment.fi. The state relies on the assignment_fsm's
timeout.
- There is one state for an ongoing Handover; except for an incoming Handover
from a remote BSS, the gscon remains in ST_INIT until the new lchan and conn
are both established.
- move bssmap_add_lcls_status() to osmo_bsc_lcls.c
abis_rsl.c:
- move all dynamic timeslot logic away into timeslot_fsm. Only keep plain send/receive functions in
abis_rsl.c
- reduce some rsl functions to merely send a message, rename to "_tx_".
- rsl_ipacc_mdcx(): add '_tx_' in the name; move parts that change the lchan state out into the
lchan_fsm, the lchan->abis_ip.* are now set there prior to invoking this function.
- move all timers and error/release handling away into various FSMs.
- tweak ipa_smod_s_for_lchan() and ipa_rtp_pt_for_lchan() to not require an
lchan passed, but just mode,type that they require. Rename to
ipacc_speech_mode*() and ipacc_payload_type().
- add rsl_forward_layer3_info, used for inter-BSC HO MO, to just send the RR
message received during BSSMAP Handover Command.
- move various logging to LOG_LCHAN() in order to log with the lchan FSM instance.
One drawback is that the lchan FSM is limited to one logging category, i.e. this moves some logging
from DRR to DRSL. It might actually make sense to combine those categories.
- lose LOGP...LOGPC logging cascades: they are bad for gsmtap logging and for performance.
- handle_classmark_chg(): change logging, move cm2 len check out of the cm3 condition (I hope that's
correct).
- gsm48_send_ho_cmd(): split off gsm48_make_ho_cmd() which doesn't send right away, so that during
inter-bsc HO we can make an RR Handover Command to send via the MSC to the remote BSS.
assignment_fsm.c:
- the Chan Mode Modify in case of re-using the same lchan is not implemented
yet, because this was also missing in the previous implementation (OS#3357).
osmo_bsc_api.c:
- simplify bsc_mr_config() and move to lchan_fsm.c, the only caller; rename to
lchan_mr_config(). (bsc_mr_config() used to copy the values to mr_bts_lv
twice, once by member assignment and then again with a memcpy.)
- During handover, we used to copy the MR config from the old lchan. Since we
may handover between FR and HR, rather set the MR Config anew every time, so
that FR rates are always available on FR lchans, and never on HR lchans.
Depends: I03ee7ce840ecfa0b6a33358e7385528aabd4873f (libosmocore),
I1f2918418c38918c5ac70acaa51a47adfca12b5e (libosmocore)
Change-Id: I82e3f918295daa83274a4cf803f046979f284366
2018-05-14 16:14:15 +00:00
|
|
|
#include <osmocom/bsc/timeslot_fsm.h>
|
|
|
|
#include <osmocom/bsc/lchan_fsm.h>
|
2020-07-15 18:53:16 +00:00
|
|
|
#include <osmocom/bsc/bts.h>
|
2020-09-17 15:54:39 +00:00
|
|
|
#include <osmocom/bsc/bsc_msc_data.h>
|
2010-06-28 10:20:22 +00:00
|
|
|
|
2018-02-13 20:21:42 +00:00
|
|
|
void *tall_bsc_ctx = NULL;
|
2009-06-29 13:19:38 +00:00
|
|
|
|
2011-04-18 15:04:00 +00:00
|
|
|
void set_ts_e1link(struct gsm_bts_trx_ts *ts, uint8_t e1_nr,
|
|
|
|
uint8_t e1_ts, uint8_t e1_ts_ss)
|
2009-02-10 17:33:56 +00:00
|
|
|
{
|
|
|
|
ts->e1_link.e1_nr = e1_nr;
|
|
|
|
ts->e1_link.e1_ts = e1_ts;
|
|
|
|
ts->e1_link.e1_ts_ss = e1_ts_ss;
|
|
|
|
}
|
|
|
|
|
2009-05-23 13:56:40 +00:00
|
|
|
/* Search for a BTS in the given Location Area; optionally start searching
|
|
|
|
* with start_bts (for continuing to search after the first result) */
|
|
|
|
struct gsm_bts *gsm_bts_by_lac(struct gsm_network *net, unsigned int lac,
|
|
|
|
struct gsm_bts *start_bts)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
struct gsm_bts *bts;
|
|
|
|
int skip = 0;
|
|
|
|
|
|
|
|
if (start_bts)
|
|
|
|
skip = 1;
|
|
|
|
|
|
|
|
for (i = 0; i < net->num_bts; i++) {
|
2009-06-21 14:17:15 +00:00
|
|
|
bts = gsm_bts_num(net, i);
|
2009-05-23 13:56:40 +00:00
|
|
|
|
|
|
|
if (skip) {
|
|
|
|
if (start_bts == bts)
|
|
|
|
skip = 0;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2009-10-01 02:07:15 +00:00
|
|
|
if (lac == GSM_LAC_RESERVED_ALL_BTS || bts->location_area_code == lac)
|
2009-05-23 13:56:40 +00:00
|
|
|
return bts;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
2009-06-20 16:15:19 +00:00
|
|
|
|
2010-04-18 13:51:20 +00:00
|
|
|
static const struct value_string bts_gprs_mode_names[] = {
|
|
|
|
{ BTS_GPRS_NONE, "none" },
|
|
|
|
{ BTS_GPRS_GPRS, "gprs" },
|
|
|
|
{ BTS_GPRS_EGPRS, "egprs" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
2015-01-31 21:16:00 +00:00
|
|
|
enum bts_gprs_mode bts_gprs_mode_parse(const char *arg, int *valid)
|
2010-04-18 13:51:20 +00:00
|
|
|
{
|
2015-01-31 21:16:00 +00:00
|
|
|
int rc;
|
|
|
|
|
|
|
|
rc = get_string_value(bts_gprs_mode_names, arg);
|
|
|
|
if (valid)
|
|
|
|
*valid = rc != -EINVAL;
|
|
|
|
return rc;
|
2010-04-18 13:51:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const char *bts_gprs_mode_name(enum bts_gprs_mode mode)
|
|
|
|
{
|
|
|
|
return get_value_string(bts_gprs_mode_names, mode);
|
|
|
|
}
|
|
|
|
|
2011-06-05 11:31:33 +00:00
|
|
|
struct gsm_bts *gsm_bts_alloc_register(struct gsm_network *net, enum gsm_bts_type type,
|
2015-11-20 09:43:31 +00:00
|
|
|
uint8_t bsic)
|
2011-06-05 11:31:33 +00:00
|
|
|
{
|
|
|
|
struct gsm_bts_model *model = bts_model_find(type);
|
2020-12-01 16:25:28 +00:00
|
|
|
struct gsm_bts_sm *bts_sm;
|
2011-06-05 11:31:33 +00:00
|
|
|
struct gsm_bts *bts;
|
|
|
|
|
2011-06-06 15:52:56 +00:00
|
|
|
if (!model && type != GSM_BTS_TYPE_UNKNOWN)
|
2011-06-05 11:31:33 +00:00
|
|
|
return NULL;
|
|
|
|
|
2020-12-01 16:25:28 +00:00
|
|
|
bts_sm = gsm_bts_sm_alloc(net, net->num_bts);
|
|
|
|
if (!bts_sm)
|
2011-06-05 11:31:33 +00:00
|
|
|
return NULL;
|
2020-12-01 16:25:28 +00:00
|
|
|
bts = bts_sm->bts[0];
|
2011-06-05 11:31:33 +00:00
|
|
|
|
2017-07-10 19:12:41 +00:00
|
|
|
net->num_bts++;
|
|
|
|
|
2011-06-05 11:31:33 +00:00
|
|
|
bts->type = type;
|
|
|
|
bts->model = model;
|
|
|
|
bts->bsic = bsic;
|
|
|
|
|
|
|
|
llist_add_tail(&bts->list, &net->bts_list);
|
|
|
|
|
|
|
|
return bts;
|
|
|
|
}
|
|
|
|
|
|
|
|
void gprs_ra_id_by_bts(struct gprs_ra_id *raid, struct gsm_bts *bts)
|
|
|
|
{
|
2018-03-01 18:48:54 +00:00
|
|
|
*raid = (struct gprs_ra_id){
|
2018-03-05 01:09:40 +00:00
|
|
|
.mcc = bts->network->plmn.mcc,
|
|
|
|
.mnc = bts->network->plmn.mnc,
|
|
|
|
.mnc_3_digits = bts->network->plmn.mnc_3_digits,
|
2018-03-01 18:48:54 +00:00
|
|
|
.lac = bts->location_area_code,
|
|
|
|
.rac = bts->gprs.rac,
|
|
|
|
};
|
2011-06-05 11:31:33 +00:00
|
|
|
}
|
|
|
|
|
2018-02-22 02:19:05 +00:00
|
|
|
void gsm48_ra_id_by_bts(struct gsm48_ra_id *buf, struct gsm_bts *bts)
|
2011-06-05 11:31:33 +00:00
|
|
|
{
|
|
|
|
struct gprs_ra_id raid;
|
|
|
|
|
|
|
|
gprs_ra_id_by_bts(&raid, bts);
|
2018-02-22 02:19:05 +00:00
|
|
|
gsm48_encode_ra(buf, &raid);
|
2011-06-05 11:31:33 +00:00
|
|
|
}
|
2011-06-09 19:48:49 +00:00
|
|
|
|
2018-02-13 22:22:03 +00:00
|
|
|
void gsm_abis_mo_reset(struct gsm_abis_mo *mo)
|
|
|
|
{
|
|
|
|
mo->nm_state.operational = NM_OPSTATE_NULL;
|
|
|
|
mo->nm_state.availability = NM_AVSTATE_POWER_OFF;
|
2020-10-01 14:14:44 +00:00
|
|
|
mo->nm_state.administrative = NM_STATE_LOCKED;
|
2018-02-13 22:22:03 +00:00
|
|
|
}
|
|
|
|
|
2020-07-15 18:53:16 +00:00
|
|
|
void gsm_mo_init(struct gsm_abis_mo *mo, struct gsm_bts *bts,
|
|
|
|
uint8_t obj_class, uint8_t p1, uint8_t p2, uint8_t p3)
|
2018-02-13 22:22:03 +00:00
|
|
|
{
|
|
|
|
mo->bts = bts;
|
|
|
|
mo->obj_class = obj_class;
|
|
|
|
mo->obj_inst.bts_nr = p1;
|
|
|
|
mo->obj_inst.trx_nr = p2;
|
|
|
|
mo->obj_inst.ts_nr = p3;
|
|
|
|
gsm_abis_mo_reset(mo);
|
|
|
|
}
|
|
|
|
|
|
|
|
const struct value_string gsm_chreq_descs[] = {
|
|
|
|
{ GSM_CHREQ_REASON_EMERG, "emergency call" },
|
|
|
|
{ GSM_CHREQ_REASON_PAG, "answer to paging" },
|
|
|
|
{ GSM_CHREQ_REASON_CALL, "call re-establishment" },
|
|
|
|
{ GSM_CHREQ_REASON_LOCATION_UPD,"Location updating" },
|
|
|
|
{ GSM_CHREQ_REASON_PDCH, "one phase packet access" },
|
|
|
|
{ GSM_CHREQ_REASON_OTHER, "other" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
large refactoring: use FSMs for lchans; add inter-BSC HO
Add FSMs:
- timeslot_fsm: handle dynamic timeslots and OML+RSL availability.
- lchan_fsm: handle an individual lchan activation, RTP stream and release,
signal the appropriate calling FSMs on success, failure, release.
- mgw_endpoint_fsm: handle one entire endpoint with several CI.
- assignment_fsm: BSSMAP Assignment Request.
- handover_fsm: all of intra, inter-MO and inter-MT handover.
Above FSMs absorb large parts of the gscon FSM. The gscon FSM was surpassing
the maximum amount events (32), and it is more logical to treat assignment,
handover and MGW procedures in separate FSMs.
- Add logging macros for each FSM type:
- LOG_TS()
- LOG_LCHAN()
- LOG_MGWEP(), LOG_CI()
- LOG_ASSIGNMENT()
- LOG_HO()
These log with the osmo_fsm_inst where present.
New style decision: logging without a final newline char is awkward,
especially for gsmtap logging and when other logs interleave LOGPC() calls;
we have various cases where the final \n goes missing, and also this invokes
the log category checking N times instead of once.
So I decided to make these macros *always* append a newline, but only if
there is no final newline yet. I hope that the compiler optimizes the
strlen() of the constant format strings away. Thus I can log with or without
typing "\n" and always get an \n termination anyway.
General:
- replace osmo_timers, state enums and program-wide osmo_signal_dispatch()
with dedicated FSM timeouts, states and events.
- introduce a common way to handle Tnnn timers: gsm_timers.h/.c: struct T_def.
These can be used (with some macro magic) to define a state's timeout once,
and not make mistakes for each osmo_fsm_inst_state_chg().
Details:
bsc_subscr_conn_fsm.c:
- move most states of this FSM to lchan_fsm, assignment_fsm, handover_fsm and
mgw_endpoint_fsm.
- There is exactly one state for an ongoing Assignment, with all details
handled in conn->assignment.fi. The state relies on the assignment_fsm's
timeout.
- There is one state for an ongoing Handover; except for an incoming Handover
from a remote BSS, the gscon remains in ST_INIT until the new lchan and conn
are both established.
- move bssmap_add_lcls_status() to osmo_bsc_lcls.c
abis_rsl.c:
- move all dynamic timeslot logic away into timeslot_fsm. Only keep plain send/receive functions in
abis_rsl.c
- reduce some rsl functions to merely send a message, rename to "_tx_".
- rsl_ipacc_mdcx(): add '_tx_' in the name; move parts that change the lchan state out into the
lchan_fsm, the lchan->abis_ip.* are now set there prior to invoking this function.
- move all timers and error/release handling away into various FSMs.
- tweak ipa_smod_s_for_lchan() and ipa_rtp_pt_for_lchan() to not require an
lchan passed, but just mode,type that they require. Rename to
ipacc_speech_mode*() and ipacc_payload_type().
- add rsl_forward_layer3_info, used for inter-BSC HO MO, to just send the RR
message received during BSSMAP Handover Command.
- move various logging to LOG_LCHAN() in order to log with the lchan FSM instance.
One drawback is that the lchan FSM is limited to one logging category, i.e. this moves some logging
from DRR to DRSL. It might actually make sense to combine those categories.
- lose LOGP...LOGPC logging cascades: they are bad for gsmtap logging and for performance.
- handle_classmark_chg(): change logging, move cm2 len check out of the cm3 condition (I hope that's
correct).
- gsm48_send_ho_cmd(): split off gsm48_make_ho_cmd() which doesn't send right away, so that during
inter-bsc HO we can make an RR Handover Command to send via the MSC to the remote BSS.
assignment_fsm.c:
- the Chan Mode Modify in case of re-using the same lchan is not implemented
yet, because this was also missing in the previous implementation (OS#3357).
osmo_bsc_api.c:
- simplify bsc_mr_config() and move to lchan_fsm.c, the only caller; rename to
lchan_mr_config(). (bsc_mr_config() used to copy the values to mr_bts_lv
twice, once by member assignment and then again with a memcpy.)
- During handover, we used to copy the MR config from the old lchan. Since we
may handover between FR and HR, rather set the MR Config anew every time, so
that FR rates are always available on FR lchans, and never on HR lchans.
Depends: I03ee7ce840ecfa0b6a33358e7385528aabd4873f (libosmocore),
I1f2918418c38918c5ac70acaa51a47adfca12b5e (libosmocore)
Change-Id: I82e3f918295daa83274a4cf803f046979f284366
2018-05-14 16:14:15 +00:00
|
|
|
const struct value_string gsm_pchant_names[] = {
|
2018-02-13 22:22:03 +00:00
|
|
|
{ GSM_PCHAN_NONE, "NONE" },
|
|
|
|
{ GSM_PCHAN_CCCH, "CCCH" },
|
|
|
|
{ GSM_PCHAN_CCCH_SDCCH4,"CCCH+SDCCH4" },
|
|
|
|
{ GSM_PCHAN_TCH_F, "TCH/F" },
|
|
|
|
{ GSM_PCHAN_TCH_H, "TCH/H" },
|
|
|
|
{ GSM_PCHAN_SDCCH8_SACCH8C, "SDCCH8" },
|
|
|
|
{ GSM_PCHAN_PDCH, "PDCH" },
|
|
|
|
{ GSM_PCHAN_TCH_F_PDCH, "TCH/F_PDCH" },
|
|
|
|
{ GSM_PCHAN_UNKNOWN, "UNKNOWN" },
|
|
|
|
{ GSM_PCHAN_CCCH_SDCCH4_CBCH, "CCCH+SDCCH4+CBCH" },
|
|
|
|
{ GSM_PCHAN_SDCCH8_SACCH8C_CBCH, "SDCCH8+CBCH" },
|
|
|
|
{ GSM_PCHAN_TCH_F_TCH_H_PDCH, "TCH/F_TCH/H_PDCH" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
large refactoring: use FSMs for lchans; add inter-BSC HO
Add FSMs:
- timeslot_fsm: handle dynamic timeslots and OML+RSL availability.
- lchan_fsm: handle an individual lchan activation, RTP stream and release,
signal the appropriate calling FSMs on success, failure, release.
- mgw_endpoint_fsm: handle one entire endpoint with several CI.
- assignment_fsm: BSSMAP Assignment Request.
- handover_fsm: all of intra, inter-MO and inter-MT handover.
Above FSMs absorb large parts of the gscon FSM. The gscon FSM was surpassing
the maximum amount events (32), and it is more logical to treat assignment,
handover and MGW procedures in separate FSMs.
- Add logging macros for each FSM type:
- LOG_TS()
- LOG_LCHAN()
- LOG_MGWEP(), LOG_CI()
- LOG_ASSIGNMENT()
- LOG_HO()
These log with the osmo_fsm_inst where present.
New style decision: logging without a final newline char is awkward,
especially for gsmtap logging and when other logs interleave LOGPC() calls;
we have various cases where the final \n goes missing, and also this invokes
the log category checking N times instead of once.
So I decided to make these macros *always* append a newline, but only if
there is no final newline yet. I hope that the compiler optimizes the
strlen() of the constant format strings away. Thus I can log with or without
typing "\n" and always get an \n termination anyway.
General:
- replace osmo_timers, state enums and program-wide osmo_signal_dispatch()
with dedicated FSM timeouts, states and events.
- introduce a common way to handle Tnnn timers: gsm_timers.h/.c: struct T_def.
These can be used (with some macro magic) to define a state's timeout once,
and not make mistakes for each osmo_fsm_inst_state_chg().
Details:
bsc_subscr_conn_fsm.c:
- move most states of this FSM to lchan_fsm, assignment_fsm, handover_fsm and
mgw_endpoint_fsm.
- There is exactly one state for an ongoing Assignment, with all details
handled in conn->assignment.fi. The state relies on the assignment_fsm's
timeout.
- There is one state for an ongoing Handover; except for an incoming Handover
from a remote BSS, the gscon remains in ST_INIT until the new lchan and conn
are both established.
- move bssmap_add_lcls_status() to osmo_bsc_lcls.c
abis_rsl.c:
- move all dynamic timeslot logic away into timeslot_fsm. Only keep plain send/receive functions in
abis_rsl.c
- reduce some rsl functions to merely send a message, rename to "_tx_".
- rsl_ipacc_mdcx(): add '_tx_' in the name; move parts that change the lchan state out into the
lchan_fsm, the lchan->abis_ip.* are now set there prior to invoking this function.
- move all timers and error/release handling away into various FSMs.
- tweak ipa_smod_s_for_lchan() and ipa_rtp_pt_for_lchan() to not require an
lchan passed, but just mode,type that they require. Rename to
ipacc_speech_mode*() and ipacc_payload_type().
- add rsl_forward_layer3_info, used for inter-BSC HO MO, to just send the RR
message received during BSSMAP Handover Command.
- move various logging to LOG_LCHAN() in order to log with the lchan FSM instance.
One drawback is that the lchan FSM is limited to one logging category, i.e. this moves some logging
from DRR to DRSL. It might actually make sense to combine those categories.
- lose LOGP...LOGPC logging cascades: they are bad for gsmtap logging and for performance.
- handle_classmark_chg(): change logging, move cm2 len check out of the cm3 condition (I hope that's
correct).
- gsm48_send_ho_cmd(): split off gsm48_make_ho_cmd() which doesn't send right away, so that during
inter-bsc HO we can make an RR Handover Command to send via the MSC to the remote BSS.
assignment_fsm.c:
- the Chan Mode Modify in case of re-using the same lchan is not implemented
yet, because this was also missing in the previous implementation (OS#3357).
osmo_bsc_api.c:
- simplify bsc_mr_config() and move to lchan_fsm.c, the only caller; rename to
lchan_mr_config(). (bsc_mr_config() used to copy the values to mr_bts_lv
twice, once by member assignment and then again with a memcpy.)
- During handover, we used to copy the MR config from the old lchan. Since we
may handover between FR and HR, rather set the MR Config anew every time, so
that FR rates are always available on FR lchans, and never on HR lchans.
Depends: I03ee7ce840ecfa0b6a33358e7385528aabd4873f (libosmocore),
I1f2918418c38918c5ac70acaa51a47adfca12b5e (libosmocore)
Change-Id: I82e3f918295daa83274a4cf803f046979f284366
2018-05-14 16:14:15 +00:00
|
|
|
const struct value_string gsm_pchan_ids[] = {
|
|
|
|
{ GSM_PCHAN_NONE, "NONE" },
|
|
|
|
{ GSM_PCHAN_CCCH, "CCCH" },
|
|
|
|
{ GSM_PCHAN_CCCH_SDCCH4,"CCCH_SDCCH4" },
|
|
|
|
{ GSM_PCHAN_TCH_F, "TCH_F" },
|
|
|
|
{ GSM_PCHAN_TCH_H, "TCH_H" },
|
|
|
|
{ GSM_PCHAN_SDCCH8_SACCH8C, "SDCCH8" },
|
|
|
|
{ GSM_PCHAN_PDCH, "PDCH" },
|
|
|
|
{ GSM_PCHAN_TCH_F_PDCH, "TCH_F_PDCH" },
|
|
|
|
{ GSM_PCHAN_UNKNOWN, "UNKNOWN" },
|
|
|
|
{ GSM_PCHAN_CCCH_SDCCH4_CBCH, "CCCH_SDCCH4_CBCH" },
|
|
|
|
{ GSM_PCHAN_SDCCH8_SACCH8C_CBCH, "SDCCH8_CBCH" },
|
|
|
|
{ GSM_PCHAN_TCH_F_TCH_H_PDCH, "TCH_F_TCH_H_PDCH" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
2018-02-13 22:22:03 +00:00
|
|
|
const struct value_string gsm_pchant_descs[13] = {
|
|
|
|
{ GSM_PCHAN_NONE, "Physical Channel not configured" },
|
|
|
|
{ GSM_PCHAN_CCCH, "FCCH + SCH + BCCH + CCCH (Comb. IV)" },
|
|
|
|
{ GSM_PCHAN_CCCH_SDCCH4,
|
|
|
|
"FCCH + SCH + BCCH + CCCH + 4 SDCCH + 2 SACCH (Comb. V)" },
|
|
|
|
{ GSM_PCHAN_TCH_F, "TCH/F + FACCH/F + SACCH (Comb. I)" },
|
|
|
|
{ GSM_PCHAN_TCH_H, "2 TCH/H + 2 FACCH/H + 2 SACCH (Comb. II)" },
|
|
|
|
{ GSM_PCHAN_SDCCH8_SACCH8C, "8 SDCCH + 4 SACCH (Comb. VII)" },
|
|
|
|
{ GSM_PCHAN_PDCH, "Packet Data Channel for GPRS/EDGE" },
|
|
|
|
{ GSM_PCHAN_TCH_F_PDCH, "Dynamic TCH/F or GPRS PDCH" },
|
|
|
|
{ GSM_PCHAN_UNKNOWN, "Unknown / Unsupported channel combination" },
|
|
|
|
{ GSM_PCHAN_CCCH_SDCCH4_CBCH, "FCCH + SCH + BCCH + CCCH + CBCH + 3 SDCCH + 2 SACCH (Comb. V)" },
|
|
|
|
{ GSM_PCHAN_SDCCH8_SACCH8C_CBCH, "7 SDCCH + 4 SACCH + CBCH (Comb. VII)" },
|
|
|
|
{ GSM_PCHAN_TCH_F_TCH_H_PDCH, "Dynamic TCH/F or TCH/H or GPRS PDCH" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
const char *gsm_pchan_name(enum gsm_phys_chan_config c)
|
|
|
|
{
|
|
|
|
return get_value_string(gsm_pchant_names, c);
|
|
|
|
}
|
|
|
|
|
|
|
|
enum gsm_phys_chan_config gsm_pchan_parse(const char *name)
|
|
|
|
{
|
|
|
|
return get_string_value(gsm_pchant_names, name);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* TODO: move to libosmocore, next to gsm_chan_t_names? */
|
|
|
|
const char *gsm_lchant_name(enum gsm_chan_t c)
|
|
|
|
{
|
|
|
|
return get_value_string(gsm_chan_t_names, c);
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct value_string chreq_names[] = {
|
|
|
|
{ GSM_CHREQ_REASON_EMERG, "EMERGENCY" },
|
|
|
|
{ GSM_CHREQ_REASON_PAG, "PAGING" },
|
|
|
|
{ GSM_CHREQ_REASON_CALL, "CALL" },
|
|
|
|
{ GSM_CHREQ_REASON_LOCATION_UPD,"LOCATION_UPDATE" },
|
|
|
|
{ GSM_CHREQ_REASON_OTHER, "OTHER" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
const char *gsm_chreq_name(enum gsm_chreq_reason_t c)
|
|
|
|
{
|
|
|
|
return get_value_string(chreq_names, c);
|
|
|
|
}
|
|
|
|
|
2018-07-09 14:49:18 +00:00
|
|
|
struct gsm_bts *gsm_bts_num(const struct gsm_network *net, int num)
|
2018-02-13 22:22:03 +00:00
|
|
|
{
|
|
|
|
struct gsm_bts *bts;
|
|
|
|
|
|
|
|
if (num >= net->num_bts)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
llist_for_each_entry(bts, &net->bts_list, list) {
|
|
|
|
if (bts->nr == num)
|
|
|
|
return bts;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2018-03-22 03:54:57 +00:00
|
|
|
/* From a list of local BTSes that match the cell_id, return the Nth one, or NULL if there is no such
|
|
|
|
* match. */
|
|
|
|
struct gsm_bts *gsm_bts_by_cell_id(const struct gsm_network *net,
|
|
|
|
const struct gsm0808_cell_id *cell_id,
|
|
|
|
int match_idx)
|
|
|
|
{
|
|
|
|
struct gsm_bts *bts;
|
|
|
|
int i = 0;
|
|
|
|
llist_for_each_entry(bts, &net->bts_list, list) {
|
|
|
|
if (!gsm_bts_matches_cell_id(bts, cell_id))
|
|
|
|
continue;
|
|
|
|
if (i < match_idx) {
|
|
|
|
/* this is only the i'th match, we're looking for a later one... */
|
|
|
|
i++;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
return bts;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2018-02-13 22:22:03 +00:00
|
|
|
static char ts2str[255];
|
|
|
|
|
|
|
|
char *gsm_ts_name(const struct gsm_bts_trx_ts *ts)
|
|
|
|
{
|
|
|
|
snprintf(ts2str, sizeof(ts2str), "(bts=%d,trx=%d,ts=%d)",
|
|
|
|
ts->trx->bts->nr, ts->trx->nr, ts->nr);
|
|
|
|
|
|
|
|
return ts2str;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*! Log timeslot number with full pchan information */
|
|
|
|
char *gsm_ts_and_pchan_name(const struct gsm_bts_trx_ts *ts)
|
|
|
|
{
|
large refactoring: use FSMs for lchans; add inter-BSC HO
Add FSMs:
- timeslot_fsm: handle dynamic timeslots and OML+RSL availability.
- lchan_fsm: handle an individual lchan activation, RTP stream and release,
signal the appropriate calling FSMs on success, failure, release.
- mgw_endpoint_fsm: handle one entire endpoint with several CI.
- assignment_fsm: BSSMAP Assignment Request.
- handover_fsm: all of intra, inter-MO and inter-MT handover.
Above FSMs absorb large parts of the gscon FSM. The gscon FSM was surpassing
the maximum amount events (32), and it is more logical to treat assignment,
handover and MGW procedures in separate FSMs.
- Add logging macros for each FSM type:
- LOG_TS()
- LOG_LCHAN()
- LOG_MGWEP(), LOG_CI()
- LOG_ASSIGNMENT()
- LOG_HO()
These log with the osmo_fsm_inst where present.
New style decision: logging without a final newline char is awkward,
especially for gsmtap logging and when other logs interleave LOGPC() calls;
we have various cases where the final \n goes missing, and also this invokes
the log category checking N times instead of once.
So I decided to make these macros *always* append a newline, but only if
there is no final newline yet. I hope that the compiler optimizes the
strlen() of the constant format strings away. Thus I can log with or without
typing "\n" and always get an \n termination anyway.
General:
- replace osmo_timers, state enums and program-wide osmo_signal_dispatch()
with dedicated FSM timeouts, states and events.
- introduce a common way to handle Tnnn timers: gsm_timers.h/.c: struct T_def.
These can be used (with some macro magic) to define a state's timeout once,
and not make mistakes for each osmo_fsm_inst_state_chg().
Details:
bsc_subscr_conn_fsm.c:
- move most states of this FSM to lchan_fsm, assignment_fsm, handover_fsm and
mgw_endpoint_fsm.
- There is exactly one state for an ongoing Assignment, with all details
handled in conn->assignment.fi. The state relies on the assignment_fsm's
timeout.
- There is one state for an ongoing Handover; except for an incoming Handover
from a remote BSS, the gscon remains in ST_INIT until the new lchan and conn
are both established.
- move bssmap_add_lcls_status() to osmo_bsc_lcls.c
abis_rsl.c:
- move all dynamic timeslot logic away into timeslot_fsm. Only keep plain send/receive functions in
abis_rsl.c
- reduce some rsl functions to merely send a message, rename to "_tx_".
- rsl_ipacc_mdcx(): add '_tx_' in the name; move parts that change the lchan state out into the
lchan_fsm, the lchan->abis_ip.* are now set there prior to invoking this function.
- move all timers and error/release handling away into various FSMs.
- tweak ipa_smod_s_for_lchan() and ipa_rtp_pt_for_lchan() to not require an
lchan passed, but just mode,type that they require. Rename to
ipacc_speech_mode*() and ipacc_payload_type().
- add rsl_forward_layer3_info, used for inter-BSC HO MO, to just send the RR
message received during BSSMAP Handover Command.
- move various logging to LOG_LCHAN() in order to log with the lchan FSM instance.
One drawback is that the lchan FSM is limited to one logging category, i.e. this moves some logging
from DRR to DRSL. It might actually make sense to combine those categories.
- lose LOGP...LOGPC logging cascades: they are bad for gsmtap logging and for performance.
- handle_classmark_chg(): change logging, move cm2 len check out of the cm3 condition (I hope that's
correct).
- gsm48_send_ho_cmd(): split off gsm48_make_ho_cmd() which doesn't send right away, so that during
inter-bsc HO we can make an RR Handover Command to send via the MSC to the remote BSS.
assignment_fsm.c:
- the Chan Mode Modify in case of re-using the same lchan is not implemented
yet, because this was also missing in the previous implementation (OS#3357).
osmo_bsc_api.c:
- simplify bsc_mr_config() and move to lchan_fsm.c, the only caller; rename to
lchan_mr_config(). (bsc_mr_config() used to copy the values to mr_bts_lv
twice, once by member assignment and then again with a memcpy.)
- During handover, we used to copy the MR config from the old lchan. Since we
may handover between FR and HR, rather set the MR Config anew every time, so
that FR rates are always available on FR lchans, and never on HR lchans.
Depends: I03ee7ce840ecfa0b6a33358e7385528aabd4873f (libosmocore),
I1f2918418c38918c5ac70acaa51a47adfca12b5e (libosmocore)
Change-Id: I82e3f918295daa83274a4cf803f046979f284366
2018-05-14 16:14:15 +00:00
|
|
|
if (!ts->fi)
|
|
|
|
snprintf(ts2str, sizeof(ts2str),
|
|
|
|
"(bts=%d,trx=%d,ts=%d,pchan_from_config=%s, not allocated)",
|
2018-02-13 22:22:03 +00:00
|
|
|
ts->trx->bts->nr, ts->trx->nr, ts->nr,
|
large refactoring: use FSMs for lchans; add inter-BSC HO
Add FSMs:
- timeslot_fsm: handle dynamic timeslots and OML+RSL availability.
- lchan_fsm: handle an individual lchan activation, RTP stream and release,
signal the appropriate calling FSMs on success, failure, release.
- mgw_endpoint_fsm: handle one entire endpoint with several CI.
- assignment_fsm: BSSMAP Assignment Request.
- handover_fsm: all of intra, inter-MO and inter-MT handover.
Above FSMs absorb large parts of the gscon FSM. The gscon FSM was surpassing
the maximum amount events (32), and it is more logical to treat assignment,
handover and MGW procedures in separate FSMs.
- Add logging macros for each FSM type:
- LOG_TS()
- LOG_LCHAN()
- LOG_MGWEP(), LOG_CI()
- LOG_ASSIGNMENT()
- LOG_HO()
These log with the osmo_fsm_inst where present.
New style decision: logging without a final newline char is awkward,
especially for gsmtap logging and when other logs interleave LOGPC() calls;
we have various cases where the final \n goes missing, and also this invokes
the log category checking N times instead of once.
So I decided to make these macros *always* append a newline, but only if
there is no final newline yet. I hope that the compiler optimizes the
strlen() of the constant format strings away. Thus I can log with or without
typing "\n" and always get an \n termination anyway.
General:
- replace osmo_timers, state enums and program-wide osmo_signal_dispatch()
with dedicated FSM timeouts, states and events.
- introduce a common way to handle Tnnn timers: gsm_timers.h/.c: struct T_def.
These can be used (with some macro magic) to define a state's timeout once,
and not make mistakes for each osmo_fsm_inst_state_chg().
Details:
bsc_subscr_conn_fsm.c:
- move most states of this FSM to lchan_fsm, assignment_fsm, handover_fsm and
mgw_endpoint_fsm.
- There is exactly one state for an ongoing Assignment, with all details
handled in conn->assignment.fi. The state relies on the assignment_fsm's
timeout.
- There is one state for an ongoing Handover; except for an incoming Handover
from a remote BSS, the gscon remains in ST_INIT until the new lchan and conn
are both established.
- move bssmap_add_lcls_status() to osmo_bsc_lcls.c
abis_rsl.c:
- move all dynamic timeslot logic away into timeslot_fsm. Only keep plain send/receive functions in
abis_rsl.c
- reduce some rsl functions to merely send a message, rename to "_tx_".
- rsl_ipacc_mdcx(): add '_tx_' in the name; move parts that change the lchan state out into the
lchan_fsm, the lchan->abis_ip.* are now set there prior to invoking this function.
- move all timers and error/release handling away into various FSMs.
- tweak ipa_smod_s_for_lchan() and ipa_rtp_pt_for_lchan() to not require an
lchan passed, but just mode,type that they require. Rename to
ipacc_speech_mode*() and ipacc_payload_type().
- add rsl_forward_layer3_info, used for inter-BSC HO MO, to just send the RR
message received during BSSMAP Handover Command.
- move various logging to LOG_LCHAN() in order to log with the lchan FSM instance.
One drawback is that the lchan FSM is limited to one logging category, i.e. this moves some logging
from DRR to DRSL. It might actually make sense to combine those categories.
- lose LOGP...LOGPC logging cascades: they are bad for gsmtap logging and for performance.
- handle_classmark_chg(): change logging, move cm2 len check out of the cm3 condition (I hope that's
correct).
- gsm48_send_ho_cmd(): split off gsm48_make_ho_cmd() which doesn't send right away, so that during
inter-bsc HO we can make an RR Handover Command to send via the MSC to the remote BSS.
assignment_fsm.c:
- the Chan Mode Modify in case of re-using the same lchan is not implemented
yet, because this was also missing in the previous implementation (OS#3357).
osmo_bsc_api.c:
- simplify bsc_mr_config() and move to lchan_fsm.c, the only caller; rename to
lchan_mr_config(). (bsc_mr_config() used to copy the values to mr_bts_lv
twice, once by member assignment and then again with a memcpy.)
- During handover, we used to copy the MR config from the old lchan. Since we
may handover between FR and HR, rather set the MR Config anew every time, so
that FR rates are always available on FR lchans, and never on HR lchans.
Depends: I03ee7ce840ecfa0b6a33358e7385528aabd4873f (libosmocore),
I1f2918418c38918c5ac70acaa51a47adfca12b5e (libosmocore)
Change-Id: I82e3f918295daa83274a4cf803f046979f284366
2018-05-14 16:14:15 +00:00
|
|
|
gsm_pchan_name(ts->pchan_from_config));
|
|
|
|
else if (ts->fi->state == TS_ST_NOT_INITIALIZED)
|
|
|
|
snprintf(ts2str, sizeof(ts2str),
|
|
|
|
"(bts=%d,trx=%d,ts=%d,pchan_from_config=%s,state=%s)",
|
|
|
|
ts->trx->bts->nr, ts->trx->nr, ts->nr,
|
|
|
|
gsm_pchan_name(ts->pchan_from_config),
|
|
|
|
osmo_fsm_inst_state_name(ts->fi));
|
|
|
|
else if (ts->pchan_is == ts->pchan_on_init)
|
|
|
|
snprintf(ts2str, sizeof(ts2str),
|
|
|
|
"(bts=%d,trx=%d,ts=%d,pchan=%s,state=%s)",
|
|
|
|
ts->trx->bts->nr, ts->trx->nr, ts->nr,
|
|
|
|
gsm_pchan_name(ts->pchan_is),
|
|
|
|
osmo_fsm_inst_state_name(ts->fi));
|
|
|
|
else
|
|
|
|
snprintf(ts2str, sizeof(ts2str),
|
|
|
|
"(bts=%d,trx=%d,ts=%d,pchan_on_init=%s,pchan=%s,state=%s)",
|
|
|
|
ts->trx->bts->nr, ts->trx->nr, ts->nr,
|
|
|
|
gsm_pchan_name(ts->pchan_on_init),
|
|
|
|
gsm_pchan_name(ts->pchan_is),
|
|
|
|
osmo_fsm_inst_state_name(ts->fi));
|
2018-02-13 22:22:03 +00:00
|
|
|
return ts2str;
|
|
|
|
}
|
|
|
|
|
2021-05-29 23:08:22 +00:00
|
|
|
void lchan_update_name(struct gsm_lchan *lchan)
|
2018-02-13 22:22:03 +00:00
|
|
|
{
|
|
|
|
struct gsm_bts_trx_ts *ts = lchan->ts;
|
2021-05-29 23:08:22 +00:00
|
|
|
if (lchan->name)
|
|
|
|
talloc_free(lchan->name);
|
|
|
|
lchan->name = talloc_asprintf(ts->trx, "(bts=%d,trx=%d,ts=%d,ss=%s%d)",
|
|
|
|
ts->trx->bts->nr, ts->trx->nr, ts->nr,
|
|
|
|
lchan->vamos.is_secondary ? "shadow" : "",
|
|
|
|
lchan->nr - (lchan->vamos.is_secondary ? ts->max_primary_lchans : 0));
|
2018-02-13 22:22:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* obtain the MO structure for a given object instance */
|
|
|
|
static inline struct gsm_abis_mo *
|
|
|
|
gsm_objclass2mo(struct gsm_bts *bts, uint8_t obj_class,
|
|
|
|
const struct abis_om_obj_inst *obj_inst)
|
|
|
|
{
|
|
|
|
struct gsm_bts_trx *trx;
|
|
|
|
struct gsm_abis_mo *mo = NULL;
|
|
|
|
|
|
|
|
switch (obj_class) {
|
|
|
|
case NM_OC_BTS:
|
|
|
|
mo = &bts->mo;
|
|
|
|
break;
|
|
|
|
case NM_OC_RADIO_CARRIER:
|
|
|
|
if (obj_inst->trx_nr >= bts->num_trx) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
trx = gsm_bts_trx_num(bts, obj_inst->trx_nr);
|
|
|
|
mo = &trx->mo;
|
|
|
|
break;
|
|
|
|
case NM_OC_BASEB_TRANSC:
|
|
|
|
if (obj_inst->trx_nr >= bts->num_trx) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
trx = gsm_bts_trx_num(bts, obj_inst->trx_nr);
|
|
|
|
mo = &trx->bb_transc.mo;
|
|
|
|
break;
|
|
|
|
case NM_OC_CHANNEL:
|
|
|
|
if (obj_inst->trx_nr >= bts->num_trx) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
trx = gsm_bts_trx_num(bts, obj_inst->trx_nr);
|
|
|
|
if (obj_inst->ts_nr >= TRX_NR_TS)
|
|
|
|
return NULL;
|
|
|
|
mo = &trx->ts[obj_inst->ts_nr].mo;
|
|
|
|
break;
|
|
|
|
case NM_OC_SITE_MANAGER:
|
2020-12-01 16:25:28 +00:00
|
|
|
mo = &bts->site_mgr->mo;
|
2018-02-13 22:22:03 +00:00
|
|
|
break;
|
|
|
|
case NM_OC_BS11:
|
|
|
|
switch (obj_inst->bts_nr) {
|
|
|
|
case BS11_OBJ_CCLK:
|
|
|
|
mo = &bts->bs11.cclk.mo;
|
|
|
|
break;
|
|
|
|
case BS11_OBJ_BBSIG:
|
|
|
|
if (obj_inst->ts_nr > bts->num_trx)
|
|
|
|
return NULL;
|
|
|
|
trx = gsm_bts_trx_num(bts, obj_inst->trx_nr);
|
|
|
|
mo = &trx->bs11.bbsig.mo;
|
|
|
|
break;
|
|
|
|
case BS11_OBJ_PA:
|
|
|
|
if (obj_inst->ts_nr > bts->num_trx)
|
|
|
|
return NULL;
|
|
|
|
trx = gsm_bts_trx_num(bts, obj_inst->trx_nr);
|
|
|
|
mo = &trx->bs11.pa.mo;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case NM_OC_BS11_RACK:
|
|
|
|
mo = &bts->bs11.rack.mo;
|
|
|
|
break;
|
|
|
|
case NM_OC_BS11_ENVABTSE:
|
|
|
|
if (obj_inst->trx_nr >= ARRAY_SIZE(bts->bs11.envabtse))
|
|
|
|
return NULL;
|
|
|
|
mo = &bts->bs11.envabtse[obj_inst->trx_nr].mo;
|
|
|
|
break;
|
|
|
|
case NM_OC_GPRS_NSE:
|
2020-12-01 16:25:28 +00:00
|
|
|
mo = &bts->site_mgr->gprs.nse.mo;
|
2018-02-13 22:22:03 +00:00
|
|
|
break;
|
|
|
|
case NM_OC_GPRS_CELL:
|
|
|
|
mo = &bts->gprs.cell.mo;
|
|
|
|
break;
|
|
|
|
case NM_OC_GPRS_NSVC:
|
2020-12-01 16:25:28 +00:00
|
|
|
if (obj_inst->trx_nr >= ARRAY_SIZE(bts->site_mgr->gprs.nsvc))
|
2018-02-13 22:22:03 +00:00
|
|
|
return NULL;
|
2020-12-01 16:25:28 +00:00
|
|
|
mo = &bts->site_mgr->gprs.nsvc[obj_inst->trx_nr].mo;
|
2018-02-13 22:22:03 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
return mo;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* obtain the gsm_nm_state data structure for a given object instance */
|
|
|
|
struct gsm_nm_state *
|
|
|
|
gsm_objclass2nmstate(struct gsm_bts *bts, uint8_t obj_class,
|
|
|
|
const struct abis_om_obj_inst *obj_inst)
|
|
|
|
{
|
|
|
|
struct gsm_abis_mo *mo;
|
|
|
|
|
|
|
|
mo = gsm_objclass2mo(bts, obj_class, obj_inst);
|
|
|
|
if (!mo)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
return &mo->nm_state;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* obtain the in-memory data structure of a given object instance */
|
|
|
|
void *
|
|
|
|
gsm_objclass2obj(struct gsm_bts *bts, uint8_t obj_class,
|
|
|
|
const struct abis_om_obj_inst *obj_inst)
|
|
|
|
{
|
|
|
|
struct gsm_bts_trx *trx;
|
|
|
|
void *obj = NULL;
|
|
|
|
|
|
|
|
switch (obj_class) {
|
|
|
|
case NM_OC_BTS:
|
|
|
|
obj = bts;
|
|
|
|
break;
|
|
|
|
case NM_OC_RADIO_CARRIER:
|
|
|
|
if (obj_inst->trx_nr >= bts->num_trx) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
trx = gsm_bts_trx_num(bts, obj_inst->trx_nr);
|
|
|
|
obj = trx;
|
|
|
|
break;
|
|
|
|
case NM_OC_BASEB_TRANSC:
|
|
|
|
if (obj_inst->trx_nr >= bts->num_trx) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
trx = gsm_bts_trx_num(bts, obj_inst->trx_nr);
|
|
|
|
obj = &trx->bb_transc;
|
|
|
|
break;
|
|
|
|
case NM_OC_CHANNEL:
|
|
|
|
if (obj_inst->trx_nr >= bts->num_trx) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
trx = gsm_bts_trx_num(bts, obj_inst->trx_nr);
|
|
|
|
if (obj_inst->ts_nr >= TRX_NR_TS)
|
|
|
|
return NULL;
|
|
|
|
obj = &trx->ts[obj_inst->ts_nr];
|
|
|
|
break;
|
|
|
|
case NM_OC_SITE_MANAGER:
|
2020-12-01 16:25:28 +00:00
|
|
|
obj = bts->site_mgr;
|
2018-02-13 22:22:03 +00:00
|
|
|
break;
|
|
|
|
case NM_OC_GPRS_NSE:
|
2020-12-01 16:25:28 +00:00
|
|
|
obj = &bts->site_mgr->gprs.nse;
|
2018-02-13 22:22:03 +00:00
|
|
|
break;
|
|
|
|
case NM_OC_GPRS_CELL:
|
|
|
|
obj = &bts->gprs.cell;
|
|
|
|
break;
|
|
|
|
case NM_OC_GPRS_NSVC:
|
2020-12-01 16:25:28 +00:00
|
|
|
if (obj_inst->trx_nr >= ARRAY_SIZE(bts->site_mgr->gprs.nsvc))
|
2018-02-13 22:22:03 +00:00
|
|
|
return NULL;
|
2020-12-01 16:25:28 +00:00
|
|
|
obj = &bts->site_mgr->gprs.nsvc[obj_inst->trx_nr];
|
2018-02-13 22:22:03 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* See Table 10.5.25 of GSM04.08 */
|
2021-06-02 20:13:39 +00:00
|
|
|
int gsm_pchan2chan_nr(enum gsm_phys_chan_config pchan,
|
2021-05-26 21:59:09 +00:00
|
|
|
uint8_t ts_nr, uint8_t lchan_nr, bool vamos_is_secondary)
|
2018-02-13 22:22:03 +00:00
|
|
|
{
|
|
|
|
uint8_t cbits, chan_nr;
|
|
|
|
|
|
|
|
switch (pchan) {
|
|
|
|
case GSM_PCHAN_TCH_F:
|
|
|
|
case GSM_PCHAN_TCH_F_PDCH:
|
2021-06-02 20:13:39 +00:00
|
|
|
if (lchan_nr != 0)
|
|
|
|
return -EINVAL;
|
2021-05-26 21:59:09 +00:00
|
|
|
if (vamos_is_secondary)
|
|
|
|
cbits = ABIS_RSL_CHAN_NR_CBITS_OSMO_VAMOS_Bm_ACCHs;
|
|
|
|
else
|
|
|
|
cbits = 0x01;
|
2018-02-13 22:22:03 +00:00
|
|
|
break;
|
|
|
|
case GSM_PCHAN_PDCH:
|
2021-06-02 20:13:39 +00:00
|
|
|
if (lchan_nr != 0)
|
|
|
|
return -EINVAL;
|
2018-02-13 22:22:03 +00:00
|
|
|
cbits = RSL_CHAN_OSMO_PDCH >> 3;
|
|
|
|
break;
|
|
|
|
case GSM_PCHAN_TCH_H:
|
2021-05-26 21:59:09 +00:00
|
|
|
if (lchan_nr >= 2)
|
2021-06-02 20:13:39 +00:00
|
|
|
return -EINVAL;
|
2021-05-26 21:59:09 +00:00
|
|
|
if (vamos_is_secondary)
|
|
|
|
cbits = ABIS_RSL_CHAN_NR_CBITS_OSMO_VAMOS_Lm_ACCHs(lchan_nr);
|
|
|
|
else {
|
|
|
|
cbits = 0x02;
|
|
|
|
cbits += lchan_nr;
|
|
|
|
}
|
2018-02-13 22:22:03 +00:00
|
|
|
break;
|
|
|
|
case GSM_PCHAN_CCCH_SDCCH4:
|
|
|
|
case GSM_PCHAN_CCCH_SDCCH4_CBCH:
|
|
|
|
/*
|
|
|
|
* As a special hack for BCCH, lchan_nr == 4 may be passed
|
|
|
|
* here. This should never be sent in an RSL message.
|
|
|
|
* See osmo-bts-xxx/oml.c:opstart_compl().
|
|
|
|
*/
|
|
|
|
if (lchan_nr == CCCH_LCHAN)
|
|
|
|
chan_nr = 0;
|
2021-05-26 21:59:09 +00:00
|
|
|
else if (lchan_nr >= 4)
|
2021-06-02 20:13:39 +00:00
|
|
|
return -EINVAL;
|
2018-02-13 22:22:03 +00:00
|
|
|
cbits = 0x04;
|
|
|
|
cbits += lchan_nr;
|
|
|
|
break;
|
|
|
|
case GSM_PCHAN_SDCCH8_SACCH8C:
|
|
|
|
case GSM_PCHAN_SDCCH8_SACCH8C_CBCH:
|
2021-05-26 21:59:09 +00:00
|
|
|
if (lchan_nr >= 8)
|
2021-06-02 20:13:39 +00:00
|
|
|
return -EINVAL;
|
2018-02-13 22:22:03 +00:00
|
|
|
cbits = 0x08;
|
|
|
|
cbits += lchan_nr;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
case GSM_PCHAN_CCCH:
|
2021-06-02 20:13:39 +00:00
|
|
|
if (lchan_nr != 0)
|
|
|
|
return -EINVAL;
|
2018-02-13 22:22:03 +00:00
|
|
|
cbits = 0x10;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
chan_nr = (cbits << 3) | (ts_nr & 0x7);
|
|
|
|
|
|
|
|
return chan_nr;
|
|
|
|
}
|
|
|
|
|
2021-05-26 21:59:09 +00:00
|
|
|
/* For RSL, to talk to osmo-bts, we introduce Osmocom specific channel number cbits to indicate VAMOS secondary lchans.
|
|
|
|
* However, in RR, which is sent to the MS, these special cbits must not be sent, but their "normal" equivalent; for RR
|
|
|
|
* messages, pass allow_osmo_cbits = false. */
|
|
|
|
int gsm_lchan2chan_nr(const struct gsm_lchan *lchan, bool allow_osmo_cbits)
|
2018-02-13 22:22:03 +00:00
|
|
|
{
|
2021-06-02 20:13:39 +00:00
|
|
|
int rc;
|
2021-04-24 12:48:19 +00:00
|
|
|
uint8_t lchan_nr = lchan->nr;
|
2021-05-26 21:59:09 +00:00
|
|
|
|
|
|
|
/* Take care that we never send Osmocom specific cbits to non-Osmo BTS. */
|
|
|
|
if (allow_osmo_cbits && lchan->vamos.is_secondary
|
|
|
|
&& lchan->ts->trx->bts->model->type != GSM_BTS_TYPE_OSMOBTS) {
|
|
|
|
LOG_LCHAN(lchan, LOGL_ERROR, "Cannot address VAMOS shadow lchan on this BTS type: %s\n",
|
|
|
|
get_value_string(bts_type_names, lchan->ts->trx->bts->model->type));
|
|
|
|
return -ENOTSUP;
|
|
|
|
}
|
|
|
|
if (allow_osmo_cbits && lchan->ts->trx->bts->model->type != GSM_BTS_TYPE_OSMOBTS)
|
|
|
|
allow_osmo_cbits = false;
|
|
|
|
|
2021-04-24 12:48:19 +00:00
|
|
|
/* The VAMOS lchans are behind the primary ones in the ts->lchan[] array. They keep their lchan->nr as in the
|
|
|
|
* array, but on the wire they are the "shadow" lchans for the primary lchans. For example, for TCH/F, there is
|
|
|
|
* a primary ts->lchan[0] and a VAMOS ts->lchan[1]. Still, the VAMOS lchan should send chan_nr = 0. */
|
|
|
|
if (lchan->vamos.is_secondary)
|
|
|
|
lchan_nr -= lchan->ts->max_primary_lchans;
|
2021-05-26 21:59:09 +00:00
|
|
|
rc = gsm_pchan2chan_nr(lchan->ts->pchan_is, lchan->ts->nr, lchan_nr,
|
|
|
|
allow_osmo_cbits ? lchan->vamos.is_secondary : false);
|
2021-06-02 20:13:39 +00:00
|
|
|
/* Log an error so that we don't need to add logging to each caller of this function */
|
|
|
|
if (rc < 0)
|
|
|
|
LOG_LCHAN(lchan, LOGL_ERROR,
|
|
|
|
"Error encoding Channel Number: pchan %s ts %u ss %u%s\n",
|
|
|
|
gsm_pchan_name(lchan->ts->pchan_from_config), lchan->ts->nr, lchan->nr,
|
|
|
|
lchan->vamos.is_secondary ? " (VAMOS shadow)" : "");
|
|
|
|
return rc;
|
2018-02-13 22:22:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static const uint8_t subslots_per_pchan[] = {
|
|
|
|
[GSM_PCHAN_NONE] = 0,
|
|
|
|
[GSM_PCHAN_CCCH] = 0,
|
|
|
|
[GSM_PCHAN_PDCH] = 0,
|
|
|
|
[GSM_PCHAN_CCCH_SDCCH4] = 4,
|
|
|
|
[GSM_PCHAN_TCH_F] = 1,
|
|
|
|
[GSM_PCHAN_TCH_H] = 2,
|
|
|
|
[GSM_PCHAN_SDCCH8_SACCH8C] = 8,
|
|
|
|
[GSM_PCHAN_CCCH_SDCCH4_CBCH] = 4,
|
|
|
|
[GSM_PCHAN_SDCCH8_SACCH8C_CBCH] = 8,
|
large refactoring: use FSMs for lchans; add inter-BSC HO
Add FSMs:
- timeslot_fsm: handle dynamic timeslots and OML+RSL availability.
- lchan_fsm: handle an individual lchan activation, RTP stream and release,
signal the appropriate calling FSMs on success, failure, release.
- mgw_endpoint_fsm: handle one entire endpoint with several CI.
- assignment_fsm: BSSMAP Assignment Request.
- handover_fsm: all of intra, inter-MO and inter-MT handover.
Above FSMs absorb large parts of the gscon FSM. The gscon FSM was surpassing
the maximum amount events (32), and it is more logical to treat assignment,
handover and MGW procedures in separate FSMs.
- Add logging macros for each FSM type:
- LOG_TS()
- LOG_LCHAN()
- LOG_MGWEP(), LOG_CI()
- LOG_ASSIGNMENT()
- LOG_HO()
These log with the osmo_fsm_inst where present.
New style decision: logging without a final newline char is awkward,
especially for gsmtap logging and when other logs interleave LOGPC() calls;
we have various cases where the final \n goes missing, and also this invokes
the log category checking N times instead of once.
So I decided to make these macros *always* append a newline, but only if
there is no final newline yet. I hope that the compiler optimizes the
strlen() of the constant format strings away. Thus I can log with or without
typing "\n" and always get an \n termination anyway.
General:
- replace osmo_timers, state enums and program-wide osmo_signal_dispatch()
with dedicated FSM timeouts, states and events.
- introduce a common way to handle Tnnn timers: gsm_timers.h/.c: struct T_def.
These can be used (with some macro magic) to define a state's timeout once,
and not make mistakes for each osmo_fsm_inst_state_chg().
Details:
bsc_subscr_conn_fsm.c:
- move most states of this FSM to lchan_fsm, assignment_fsm, handover_fsm and
mgw_endpoint_fsm.
- There is exactly one state for an ongoing Assignment, with all details
handled in conn->assignment.fi. The state relies on the assignment_fsm's
timeout.
- There is one state for an ongoing Handover; except for an incoming Handover
from a remote BSS, the gscon remains in ST_INIT until the new lchan and conn
are both established.
- move bssmap_add_lcls_status() to osmo_bsc_lcls.c
abis_rsl.c:
- move all dynamic timeslot logic away into timeslot_fsm. Only keep plain send/receive functions in
abis_rsl.c
- reduce some rsl functions to merely send a message, rename to "_tx_".
- rsl_ipacc_mdcx(): add '_tx_' in the name; move parts that change the lchan state out into the
lchan_fsm, the lchan->abis_ip.* are now set there prior to invoking this function.
- move all timers and error/release handling away into various FSMs.
- tweak ipa_smod_s_for_lchan() and ipa_rtp_pt_for_lchan() to not require an
lchan passed, but just mode,type that they require. Rename to
ipacc_speech_mode*() and ipacc_payload_type().
- add rsl_forward_layer3_info, used for inter-BSC HO MO, to just send the RR
message received during BSSMAP Handover Command.
- move various logging to LOG_LCHAN() in order to log with the lchan FSM instance.
One drawback is that the lchan FSM is limited to one logging category, i.e. this moves some logging
from DRR to DRSL. It might actually make sense to combine those categories.
- lose LOGP...LOGPC logging cascades: they are bad for gsmtap logging and for performance.
- handle_classmark_chg(): change logging, move cm2 len check out of the cm3 condition (I hope that's
correct).
- gsm48_send_ho_cmd(): split off gsm48_make_ho_cmd() which doesn't send right away, so that during
inter-bsc HO we can make an RR Handover Command to send via the MSC to the remote BSS.
assignment_fsm.c:
- the Chan Mode Modify in case of re-using the same lchan is not implemented
yet, because this was also missing in the previous implementation (OS#3357).
osmo_bsc_api.c:
- simplify bsc_mr_config() and move to lchan_fsm.c, the only caller; rename to
lchan_mr_config(). (bsc_mr_config() used to copy the values to mr_bts_lv
twice, once by member assignment and then again with a memcpy.)
- During handover, we used to copy the MR config from the old lchan. Since we
may handover between FR and HR, rather set the MR Config anew every time, so
that FR rates are always available on FR lchans, and never on HR lchans.
Depends: I03ee7ce840ecfa0b6a33358e7385528aabd4873f (libosmocore),
I1f2918418c38918c5ac70acaa51a47adfca12b5e (libosmocore)
Change-Id: I82e3f918295daa83274a4cf803f046979f284366
2018-05-14 16:14:15 +00:00
|
|
|
/* Dyn TS: maximum allowed subslots */
|
|
|
|
[GSM_PCHAN_TCH_F_TCH_H_PDCH] = 2,
|
|
|
|
[GSM_PCHAN_TCH_F_PDCH] = 1,
|
2018-02-13 22:22:03 +00:00
|
|
|
};
|
|
|
|
|
2021-04-24 13:07:06 +00:00
|
|
|
/*! Return the maximum number of logical channels that may be used in a timeslot of the given physical channel
|
|
|
|
* configuration. */
|
large refactoring: use FSMs for lchans; add inter-BSC HO
Add FSMs:
- timeslot_fsm: handle dynamic timeslots and OML+RSL availability.
- lchan_fsm: handle an individual lchan activation, RTP stream and release,
signal the appropriate calling FSMs on success, failure, release.
- mgw_endpoint_fsm: handle one entire endpoint with several CI.
- assignment_fsm: BSSMAP Assignment Request.
- handover_fsm: all of intra, inter-MO and inter-MT handover.
Above FSMs absorb large parts of the gscon FSM. The gscon FSM was surpassing
the maximum amount events (32), and it is more logical to treat assignment,
handover and MGW procedures in separate FSMs.
- Add logging macros for each FSM type:
- LOG_TS()
- LOG_LCHAN()
- LOG_MGWEP(), LOG_CI()
- LOG_ASSIGNMENT()
- LOG_HO()
These log with the osmo_fsm_inst where present.
New style decision: logging without a final newline char is awkward,
especially for gsmtap logging and when other logs interleave LOGPC() calls;
we have various cases where the final \n goes missing, and also this invokes
the log category checking N times instead of once.
So I decided to make these macros *always* append a newline, but only if
there is no final newline yet. I hope that the compiler optimizes the
strlen() of the constant format strings away. Thus I can log with or without
typing "\n" and always get an \n termination anyway.
General:
- replace osmo_timers, state enums and program-wide osmo_signal_dispatch()
with dedicated FSM timeouts, states and events.
- introduce a common way to handle Tnnn timers: gsm_timers.h/.c: struct T_def.
These can be used (with some macro magic) to define a state's timeout once,
and not make mistakes for each osmo_fsm_inst_state_chg().
Details:
bsc_subscr_conn_fsm.c:
- move most states of this FSM to lchan_fsm, assignment_fsm, handover_fsm and
mgw_endpoint_fsm.
- There is exactly one state for an ongoing Assignment, with all details
handled in conn->assignment.fi. The state relies on the assignment_fsm's
timeout.
- There is one state for an ongoing Handover; except for an incoming Handover
from a remote BSS, the gscon remains in ST_INIT until the new lchan and conn
are both established.
- move bssmap_add_lcls_status() to osmo_bsc_lcls.c
abis_rsl.c:
- move all dynamic timeslot logic away into timeslot_fsm. Only keep plain send/receive functions in
abis_rsl.c
- reduce some rsl functions to merely send a message, rename to "_tx_".
- rsl_ipacc_mdcx(): add '_tx_' in the name; move parts that change the lchan state out into the
lchan_fsm, the lchan->abis_ip.* are now set there prior to invoking this function.
- move all timers and error/release handling away into various FSMs.
- tweak ipa_smod_s_for_lchan() and ipa_rtp_pt_for_lchan() to not require an
lchan passed, but just mode,type that they require. Rename to
ipacc_speech_mode*() and ipacc_payload_type().
- add rsl_forward_layer3_info, used for inter-BSC HO MO, to just send the RR
message received during BSSMAP Handover Command.
- move various logging to LOG_LCHAN() in order to log with the lchan FSM instance.
One drawback is that the lchan FSM is limited to one logging category, i.e. this moves some logging
from DRR to DRSL. It might actually make sense to combine those categories.
- lose LOGP...LOGPC logging cascades: they are bad for gsmtap logging and for performance.
- handle_classmark_chg(): change logging, move cm2 len check out of the cm3 condition (I hope that's
correct).
- gsm48_send_ho_cmd(): split off gsm48_make_ho_cmd() which doesn't send right away, so that during
inter-bsc HO we can make an RR Handover Command to send via the MSC to the remote BSS.
assignment_fsm.c:
- the Chan Mode Modify in case of re-using the same lchan is not implemented
yet, because this was also missing in the previous implementation (OS#3357).
osmo_bsc_api.c:
- simplify bsc_mr_config() and move to lchan_fsm.c, the only caller; rename to
lchan_mr_config(). (bsc_mr_config() used to copy the values to mr_bts_lv
twice, once by member assignment and then again with a memcpy.)
- During handover, we used to copy the MR config from the old lchan. Since we
may handover between FR and HR, rather set the MR Config anew every time, so
that FR rates are always available on FR lchans, and never on HR lchans.
Depends: I03ee7ce840ecfa0b6a33358e7385528aabd4873f (libosmocore),
I1f2918418c38918c5ac70acaa51a47adfca12b5e (libosmocore)
Change-Id: I82e3f918295daa83274a4cf803f046979f284366
2018-05-14 16:14:15 +00:00
|
|
|
uint8_t pchan_subslots(enum gsm_phys_chan_config pchan)
|
2018-02-13 22:22:03 +00:00
|
|
|
{
|
large refactoring: use FSMs for lchans; add inter-BSC HO
Add FSMs:
- timeslot_fsm: handle dynamic timeslots and OML+RSL availability.
- lchan_fsm: handle an individual lchan activation, RTP stream and release,
signal the appropriate calling FSMs on success, failure, release.
- mgw_endpoint_fsm: handle one entire endpoint with several CI.
- assignment_fsm: BSSMAP Assignment Request.
- handover_fsm: all of intra, inter-MO and inter-MT handover.
Above FSMs absorb large parts of the gscon FSM. The gscon FSM was surpassing
the maximum amount events (32), and it is more logical to treat assignment,
handover and MGW procedures in separate FSMs.
- Add logging macros for each FSM type:
- LOG_TS()
- LOG_LCHAN()
- LOG_MGWEP(), LOG_CI()
- LOG_ASSIGNMENT()
- LOG_HO()
These log with the osmo_fsm_inst where present.
New style decision: logging without a final newline char is awkward,
especially for gsmtap logging and when other logs interleave LOGPC() calls;
we have various cases where the final \n goes missing, and also this invokes
the log category checking N times instead of once.
So I decided to make these macros *always* append a newline, but only if
there is no final newline yet. I hope that the compiler optimizes the
strlen() of the constant format strings away. Thus I can log with or without
typing "\n" and always get an \n termination anyway.
General:
- replace osmo_timers, state enums and program-wide osmo_signal_dispatch()
with dedicated FSM timeouts, states and events.
- introduce a common way to handle Tnnn timers: gsm_timers.h/.c: struct T_def.
These can be used (with some macro magic) to define a state's timeout once,
and not make mistakes for each osmo_fsm_inst_state_chg().
Details:
bsc_subscr_conn_fsm.c:
- move most states of this FSM to lchan_fsm, assignment_fsm, handover_fsm and
mgw_endpoint_fsm.
- There is exactly one state for an ongoing Assignment, with all details
handled in conn->assignment.fi. The state relies on the assignment_fsm's
timeout.
- There is one state for an ongoing Handover; except for an incoming Handover
from a remote BSS, the gscon remains in ST_INIT until the new lchan and conn
are both established.
- move bssmap_add_lcls_status() to osmo_bsc_lcls.c
abis_rsl.c:
- move all dynamic timeslot logic away into timeslot_fsm. Only keep plain send/receive functions in
abis_rsl.c
- reduce some rsl functions to merely send a message, rename to "_tx_".
- rsl_ipacc_mdcx(): add '_tx_' in the name; move parts that change the lchan state out into the
lchan_fsm, the lchan->abis_ip.* are now set there prior to invoking this function.
- move all timers and error/release handling away into various FSMs.
- tweak ipa_smod_s_for_lchan() and ipa_rtp_pt_for_lchan() to not require an
lchan passed, but just mode,type that they require. Rename to
ipacc_speech_mode*() and ipacc_payload_type().
- add rsl_forward_layer3_info, used for inter-BSC HO MO, to just send the RR
message received during BSSMAP Handover Command.
- move various logging to LOG_LCHAN() in order to log with the lchan FSM instance.
One drawback is that the lchan FSM is limited to one logging category, i.e. this moves some logging
from DRR to DRSL. It might actually make sense to combine those categories.
- lose LOGP...LOGPC logging cascades: they are bad for gsmtap logging and for performance.
- handle_classmark_chg(): change logging, move cm2 len check out of the cm3 condition (I hope that's
correct).
- gsm48_send_ho_cmd(): split off gsm48_make_ho_cmd() which doesn't send right away, so that during
inter-bsc HO we can make an RR Handover Command to send via the MSC to the remote BSS.
assignment_fsm.c:
- the Chan Mode Modify in case of re-using the same lchan is not implemented
yet, because this was also missing in the previous implementation (OS#3357).
osmo_bsc_api.c:
- simplify bsc_mr_config() and move to lchan_fsm.c, the only caller; rename to
lchan_mr_config(). (bsc_mr_config() used to copy the values to mr_bts_lv
twice, once by member assignment and then again with a memcpy.)
- During handover, we used to copy the MR config from the old lchan. Since we
may handover between FR and HR, rather set the MR Config anew every time, so
that FR rates are always available on FR lchans, and never on HR lchans.
Depends: I03ee7ce840ecfa0b6a33358e7385528aabd4873f (libosmocore),
I1f2918418c38918c5ac70acaa51a47adfca12b5e (libosmocore)
Change-Id: I82e3f918295daa83274a4cf803f046979f284366
2018-05-14 16:14:15 +00:00
|
|
|
if (pchan < 0 || pchan >= ARRAY_SIZE(subslots_per_pchan))
|
|
|
|
return 0;
|
|
|
|
return subslots_per_pchan[pchan];
|
2018-02-13 22:22:03 +00:00
|
|
|
}
|
|
|
|
|
2021-04-24 12:48:19 +00:00
|
|
|
static const uint8_t subslots_per_pchan_vamos[] = {
|
|
|
|
[GSM_PCHAN_NONE] = 0,
|
|
|
|
[GSM_PCHAN_CCCH] = 0,
|
|
|
|
[GSM_PCHAN_PDCH] = 0,
|
|
|
|
[GSM_PCHAN_CCCH_SDCCH4] = 0,
|
|
|
|
/* VAMOS: on a TCH/F, there may be a TCH/H shadow */
|
|
|
|
[GSM_PCHAN_TCH_F] = 2,
|
|
|
|
[GSM_PCHAN_TCH_H] = 2,
|
|
|
|
[GSM_PCHAN_SDCCH8_SACCH8C] = 0,
|
|
|
|
[GSM_PCHAN_CCCH_SDCCH4_CBCH] = 0,
|
|
|
|
[GSM_PCHAN_SDCCH8_SACCH8C_CBCH] = 0,
|
|
|
|
[GSM_PCHAN_TCH_F_TCH_H_PDCH] = 2,
|
|
|
|
[GSM_PCHAN_TCH_F_PDCH] = 2,
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Return the maximum number of VAMOS secondary lchans that may be used in a timeslot of the given physical channel
|
|
|
|
* configuration. */
|
|
|
|
uint8_t pchan_subslots_vamos(enum gsm_phys_chan_config pchan)
|
|
|
|
{
|
|
|
|
if (pchan < 0 || pchan >= ARRAY_SIZE(subslots_per_pchan_vamos))
|
|
|
|
return 0;
|
|
|
|
return subslots_per_pchan_vamos[pchan];
|
|
|
|
}
|
|
|
|
|
2018-02-13 22:22:03 +00:00
|
|
|
static bool pchan_is_tch(enum gsm_phys_chan_config pchan)
|
|
|
|
{
|
|
|
|
switch (pchan) {
|
|
|
|
case GSM_PCHAN_TCH_F:
|
|
|
|
case GSM_PCHAN_TCH_H:
|
|
|
|
return true;
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ts_is_tch(struct gsm_bts_trx_ts *ts)
|
|
|
|
{
|
large refactoring: use FSMs for lchans; add inter-BSC HO
Add FSMs:
- timeslot_fsm: handle dynamic timeslots and OML+RSL availability.
- lchan_fsm: handle an individual lchan activation, RTP stream and release,
signal the appropriate calling FSMs on success, failure, release.
- mgw_endpoint_fsm: handle one entire endpoint with several CI.
- assignment_fsm: BSSMAP Assignment Request.
- handover_fsm: all of intra, inter-MO and inter-MT handover.
Above FSMs absorb large parts of the gscon FSM. The gscon FSM was surpassing
the maximum amount events (32), and it is more logical to treat assignment,
handover and MGW procedures in separate FSMs.
- Add logging macros for each FSM type:
- LOG_TS()
- LOG_LCHAN()
- LOG_MGWEP(), LOG_CI()
- LOG_ASSIGNMENT()
- LOG_HO()
These log with the osmo_fsm_inst where present.
New style decision: logging without a final newline char is awkward,
especially for gsmtap logging and when other logs interleave LOGPC() calls;
we have various cases where the final \n goes missing, and also this invokes
the log category checking N times instead of once.
So I decided to make these macros *always* append a newline, but only if
there is no final newline yet. I hope that the compiler optimizes the
strlen() of the constant format strings away. Thus I can log with or without
typing "\n" and always get an \n termination anyway.
General:
- replace osmo_timers, state enums and program-wide osmo_signal_dispatch()
with dedicated FSM timeouts, states and events.
- introduce a common way to handle Tnnn timers: gsm_timers.h/.c: struct T_def.
These can be used (with some macro magic) to define a state's timeout once,
and not make mistakes for each osmo_fsm_inst_state_chg().
Details:
bsc_subscr_conn_fsm.c:
- move most states of this FSM to lchan_fsm, assignment_fsm, handover_fsm and
mgw_endpoint_fsm.
- There is exactly one state for an ongoing Assignment, with all details
handled in conn->assignment.fi. The state relies on the assignment_fsm's
timeout.
- There is one state for an ongoing Handover; except for an incoming Handover
from a remote BSS, the gscon remains in ST_INIT until the new lchan and conn
are both established.
- move bssmap_add_lcls_status() to osmo_bsc_lcls.c
abis_rsl.c:
- move all dynamic timeslot logic away into timeslot_fsm. Only keep plain send/receive functions in
abis_rsl.c
- reduce some rsl functions to merely send a message, rename to "_tx_".
- rsl_ipacc_mdcx(): add '_tx_' in the name; move parts that change the lchan state out into the
lchan_fsm, the lchan->abis_ip.* are now set there prior to invoking this function.
- move all timers and error/release handling away into various FSMs.
- tweak ipa_smod_s_for_lchan() and ipa_rtp_pt_for_lchan() to not require an
lchan passed, but just mode,type that they require. Rename to
ipacc_speech_mode*() and ipacc_payload_type().
- add rsl_forward_layer3_info, used for inter-BSC HO MO, to just send the RR
message received during BSSMAP Handover Command.
- move various logging to LOG_LCHAN() in order to log with the lchan FSM instance.
One drawback is that the lchan FSM is limited to one logging category, i.e. this moves some logging
from DRR to DRSL. It might actually make sense to combine those categories.
- lose LOGP...LOGPC logging cascades: they are bad for gsmtap logging and for performance.
- handle_classmark_chg(): change logging, move cm2 len check out of the cm3 condition (I hope that's
correct).
- gsm48_send_ho_cmd(): split off gsm48_make_ho_cmd() which doesn't send right away, so that during
inter-bsc HO we can make an RR Handover Command to send via the MSC to the remote BSS.
assignment_fsm.c:
- the Chan Mode Modify in case of re-using the same lchan is not implemented
yet, because this was also missing in the previous implementation (OS#3357).
osmo_bsc_api.c:
- simplify bsc_mr_config() and move to lchan_fsm.c, the only caller; rename to
lchan_mr_config(). (bsc_mr_config() used to copy the values to mr_bts_lv
twice, once by member assignment and then again with a memcpy.)
- During handover, we used to copy the MR config from the old lchan. Since we
may handover between FR and HR, rather set the MR Config anew every time, so
that FR rates are always available on FR lchans, and never on HR lchans.
Depends: I03ee7ce840ecfa0b6a33358e7385528aabd4873f (libosmocore),
I1f2918418c38918c5ac70acaa51a47adfca12b5e (libosmocore)
Change-Id: I82e3f918295daa83274a4cf803f046979f284366
2018-05-14 16:14:15 +00:00
|
|
|
return pchan_is_tch(ts->pchan_is);
|
2018-02-13 22:22:03 +00:00
|
|
|
}
|
dissolve libbsc: move all to src/osmo-bsc, link .o files
Move all of libbsc/ into osmo-bsc/, and separate/move some implementations to
allow linking from utils/* and ipaccess/* without pulling in unccessary
dependencies.
Some utilities use gsm_network and gsm_bts structs, which already include data
structures for fairly advanced uses. Move initialization that only osmo-bsc
needs into new bsc_network_init() and bsc_bts_alloc_register() functions, so
that the leaner tools can use the old gsm_* versions without the need to link
everything (e.g. handover and lchan alloc code).
In some instances, there need to be stubs if to cut off linking "just before
the RSL level" and prevent dependencies from creeping in.
- abis_rsl_rcvmsg(): the only program currently interpreting RSL messages is
osmo-bsc, the utils are merely concerned with OML, if at all.
- paging_flush_bts(): ip.access nanobts models call this when the RSL link is
dropped. Only osmo-bsc actually needs to do anything there.
- on_gsm_ts_init(): the mechanism to trigger timeslot initialization is related
to OML, while this action to take on init would pull in RSL dependencies.
utils/ and ipaccess/ each have a stubs.c file to implement these stubs. Tests
implement stubs inline where required.
From src/utils/, src/ipaccess/ and tests/*/, link in .o files from osmo-bsc/.
In order for this to work, the osmo-bsc subdir must be built before the other
source trees. (An alternative would be to include the .c files as sources, but
that would re-compile them in every source tree. Not a large burden really, but
unless linking .o files gives problems, let's have the quicker build.)
Minor obvious cleanups creep in with this patch, I will not bother to name them
individually now unless code review asks me to.
Rationale:
1) libbsc has been separate to use it for osmo-nitb and osmo-bsc in the old
openbsc.git. This is no longer required, and spreading over libbsc and osmo-bsc
is distracting.
2) Recently, ridiculous linking requirements have made adding new functions
cumbersome, because libbsc has started depending on osmo-bsc/*.c
implementations: on gscon FSM and bssap functions. For example, neither
bs11_config nor ipaccess-config nor bts_test need handover_cfg or BSSMAP
message composition. It makes no sense to link the entire osmo-bsc to it, nor
do we want to keep adding stubs to each linking realm.
Change-Id: I36a586726f5818121abe54d25654819fc451d3bf
2018-05-26 23:26:31 +00:00
|
|
|
|
2021-04-24 12:48:19 +00:00
|
|
|
/* For a VAMOS secondary shadow lchan, return its primary lchan. If the lchan is not a secondary lchan, return NULL. */
|
|
|
|
struct gsm_lchan *gsm_lchan_vamos_to_primary(const struct gsm_lchan *lchan_vamos)
|
|
|
|
{
|
|
|
|
struct gsm_lchan *lchan_primary;
|
|
|
|
if (!lchan_vamos || !lchan_vamos->vamos.is_secondary)
|
|
|
|
return NULL;
|
|
|
|
/* OsmoBSC currently does not support mixed TCH/F + TCH/H VAMOS multiplexes. Hence the primary <-> secondary
|
|
|
|
* relation is a simple index shift in the lchan array. If mixed multiplexes were allowed, a TCH/F primary might
|
|
|
|
* have two TCH/H VAMOS secondary lchans, etc. Fortunately, we don't need to care about that. */
|
|
|
|
lchan_primary = (struct gsm_lchan*)lchan_vamos - lchan_vamos->ts->max_primary_lchans;
|
|
|
|
if (!lchan_primary->fi)
|
|
|
|
return NULL;
|
|
|
|
return lchan_primary;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* For a primary lchan, return its VAMOS secondary shadow lchan. If the lchan is not a primary lchan, return NULL. */
|
|
|
|
struct gsm_lchan *gsm_lchan_primary_to_vamos(const struct gsm_lchan *lchan_primary)
|
|
|
|
{
|
|
|
|
struct gsm_lchan *lchan_vamos;
|
|
|
|
if (!lchan_primary || lchan_primary->vamos.is_secondary)
|
|
|
|
return NULL;
|
|
|
|
/* OsmoBSC currently does not support mixed TCH/F + TCH/H VAMOS multiplexes. Hence the primary <-> secondary
|
|
|
|
* relation is a simple index shift in the lchan array. If mixed multiplexes were allowed, a TCH/F primary might
|
|
|
|
* have two TCH/H VAMOS secondary lchans, etc. Fortunately, we don't need to care about that. */
|
|
|
|
lchan_vamos = (struct gsm_lchan*)lchan_primary + lchan_primary->ts->max_primary_lchans;
|
|
|
|
if (!lchan_vamos->fi)
|
|
|
|
return NULL;
|
|
|
|
return lchan_vamos;
|
|
|
|
}
|
|
|
|
|
2020-07-15 18:53:16 +00:00
|
|
|
struct gsm_bts *conn_get_bts(struct gsm_subscriber_connection *conn) {
|
|
|
|
if (!conn || !conn->lchan)
|
|
|
|
return NULL;
|
|
|
|
return conn->lchan->ts->trx->bts;
|
|
|
|
}
|
|
|
|
|
2021-05-19 00:29:53 +00:00
|
|
|
static void _chan_desc_fill_tail(struct gsm48_chan_desc *cd, const struct gsm_lchan *lchan,
|
|
|
|
uint8_t tsc)
|
dissolve libbsc: move all to src/osmo-bsc, link .o files
Move all of libbsc/ into osmo-bsc/, and separate/move some implementations to
allow linking from utils/* and ipaccess/* without pulling in unccessary
dependencies.
Some utilities use gsm_network and gsm_bts structs, which already include data
structures for fairly advanced uses. Move initialization that only osmo-bsc
needs into new bsc_network_init() and bsc_bts_alloc_register() functions, so
that the leaner tools can use the old gsm_* versions without the need to link
everything (e.g. handover and lchan alloc code).
In some instances, there need to be stubs if to cut off linking "just before
the RSL level" and prevent dependencies from creeping in.
- abis_rsl_rcvmsg(): the only program currently interpreting RSL messages is
osmo-bsc, the utils are merely concerned with OML, if at all.
- paging_flush_bts(): ip.access nanobts models call this when the RSL link is
dropped. Only osmo-bsc actually needs to do anything there.
- on_gsm_ts_init(): the mechanism to trigger timeslot initialization is related
to OML, while this action to take on init would pull in RSL dependencies.
utils/ and ipaccess/ each have a stubs.c file to implement these stubs. Tests
implement stubs inline where required.
From src/utils/, src/ipaccess/ and tests/*/, link in .o files from osmo-bsc/.
In order for this to work, the osmo-bsc subdir must be built before the other
source trees. (An alternative would be to include the .c files as sources, but
that would re-compile them in every source tree. Not a large burden really, but
unless linking .o files gives problems, let's have the quicker build.)
Minor obvious cleanups creep in with this patch, I will not bother to name them
individually now unless code review asks me to.
Rationale:
1) libbsc has been separate to use it for osmo-nitb and osmo-bsc in the old
openbsc.git. This is no longer required, and spreading over libbsc and osmo-bsc
is distracting.
2) Recently, ridiculous linking requirements have made adding new functions
cumbersome, because libbsc has started depending on osmo-bsc/*.c
implementations: on gscon FSM and bssap functions. For example, neither
bs11_config nor ipaccess-config nor bts_test need handover_cfg or BSSMAP
message composition. It makes no sense to link the entire osmo-bsc to it, nor
do we want to keep adding stubs to each linking realm.
Change-Id: I36a586726f5818121abe54d25654819fc451d3bf
2018-05-26 23:26:31 +00:00
|
|
|
{
|
|
|
|
if (!lchan->ts->hopping.enabled) {
|
2018-09-09 15:17:44 +00:00
|
|
|
uint16_t arfcn = lchan->ts->trx->arfcn & 0x3ff;
|
2021-05-19 00:29:53 +00:00
|
|
|
cd->h0.tsc = tsc;
|
dissolve libbsc: move all to src/osmo-bsc, link .o files
Move all of libbsc/ into osmo-bsc/, and separate/move some implementations to
allow linking from utils/* and ipaccess/* without pulling in unccessary
dependencies.
Some utilities use gsm_network and gsm_bts structs, which already include data
structures for fairly advanced uses. Move initialization that only osmo-bsc
needs into new bsc_network_init() and bsc_bts_alloc_register() functions, so
that the leaner tools can use the old gsm_* versions without the need to link
everything (e.g. handover and lchan alloc code).
In some instances, there need to be stubs if to cut off linking "just before
the RSL level" and prevent dependencies from creeping in.
- abis_rsl_rcvmsg(): the only program currently interpreting RSL messages is
osmo-bsc, the utils are merely concerned with OML, if at all.
- paging_flush_bts(): ip.access nanobts models call this when the RSL link is
dropped. Only osmo-bsc actually needs to do anything there.
- on_gsm_ts_init(): the mechanism to trigger timeslot initialization is related
to OML, while this action to take on init would pull in RSL dependencies.
utils/ and ipaccess/ each have a stubs.c file to implement these stubs. Tests
implement stubs inline where required.
From src/utils/, src/ipaccess/ and tests/*/, link in .o files from osmo-bsc/.
In order for this to work, the osmo-bsc subdir must be built before the other
source trees. (An alternative would be to include the .c files as sources, but
that would re-compile them in every source tree. Not a large burden really, but
unless linking .o files gives problems, let's have the quicker build.)
Minor obvious cleanups creep in with this patch, I will not bother to name them
individually now unless code review asks me to.
Rationale:
1) libbsc has been separate to use it for osmo-nitb and osmo-bsc in the old
openbsc.git. This is no longer required, and spreading over libbsc and osmo-bsc
is distracting.
2) Recently, ridiculous linking requirements have made adding new functions
cumbersome, because libbsc has started depending on osmo-bsc/*.c
implementations: on gscon FSM and bssap functions. For example, neither
bs11_config nor ipaccess-config nor bts_test need handover_cfg or BSSMAP
message composition. It makes no sense to link the entire osmo-bsc to it, nor
do we want to keep adding stubs to each linking realm.
Change-Id: I36a586726f5818121abe54d25654819fc451d3bf
2018-05-26 23:26:31 +00:00
|
|
|
cd->h0.h = 0;
|
2020-09-09 21:00:20 +00:00
|
|
|
cd->h0.spare = 0;
|
dissolve libbsc: move all to src/osmo-bsc, link .o files
Move all of libbsc/ into osmo-bsc/, and separate/move some implementations to
allow linking from utils/* and ipaccess/* without pulling in unccessary
dependencies.
Some utilities use gsm_network and gsm_bts structs, which already include data
structures for fairly advanced uses. Move initialization that only osmo-bsc
needs into new bsc_network_init() and bsc_bts_alloc_register() functions, so
that the leaner tools can use the old gsm_* versions without the need to link
everything (e.g. handover and lchan alloc code).
In some instances, there need to be stubs if to cut off linking "just before
the RSL level" and prevent dependencies from creeping in.
- abis_rsl_rcvmsg(): the only program currently interpreting RSL messages is
osmo-bsc, the utils are merely concerned with OML, if at all.
- paging_flush_bts(): ip.access nanobts models call this when the RSL link is
dropped. Only osmo-bsc actually needs to do anything there.
- on_gsm_ts_init(): the mechanism to trigger timeslot initialization is related
to OML, while this action to take on init would pull in RSL dependencies.
utils/ and ipaccess/ each have a stubs.c file to implement these stubs. Tests
implement stubs inline where required.
From src/utils/, src/ipaccess/ and tests/*/, link in .o files from osmo-bsc/.
In order for this to work, the osmo-bsc subdir must be built before the other
source trees. (An alternative would be to include the .c files as sources, but
that would re-compile them in every source tree. Not a large burden really, but
unless linking .o files gives problems, let's have the quicker build.)
Minor obvious cleanups creep in with this patch, I will not bother to name them
individually now unless code review asks me to.
Rationale:
1) libbsc has been separate to use it for osmo-nitb and osmo-bsc in the old
openbsc.git. This is no longer required, and spreading over libbsc and osmo-bsc
is distracting.
2) Recently, ridiculous linking requirements have made adding new functions
cumbersome, because libbsc has started depending on osmo-bsc/*.c
implementations: on gscon FSM and bssap functions. For example, neither
bs11_config nor ipaccess-config nor bts_test need handover_cfg or BSSMAP
message composition. It makes no sense to link the entire osmo-bsc to it, nor
do we want to keep adding stubs to each linking realm.
Change-Id: I36a586726f5818121abe54d25654819fc451d3bf
2018-05-26 23:26:31 +00:00
|
|
|
cd->h0.arfcn_high = arfcn >> 8;
|
|
|
|
cd->h0.arfcn_low = arfcn & 0xff;
|
|
|
|
} else {
|
2021-05-19 00:29:53 +00:00
|
|
|
cd->h1.tsc = tsc;
|
dissolve libbsc: move all to src/osmo-bsc, link .o files
Move all of libbsc/ into osmo-bsc/, and separate/move some implementations to
allow linking from utils/* and ipaccess/* without pulling in unccessary
dependencies.
Some utilities use gsm_network and gsm_bts structs, which already include data
structures for fairly advanced uses. Move initialization that only osmo-bsc
needs into new bsc_network_init() and bsc_bts_alloc_register() functions, so
that the leaner tools can use the old gsm_* versions without the need to link
everything (e.g. handover and lchan alloc code).
In some instances, there need to be stubs if to cut off linking "just before
the RSL level" and prevent dependencies from creeping in.
- abis_rsl_rcvmsg(): the only program currently interpreting RSL messages is
osmo-bsc, the utils are merely concerned with OML, if at all.
- paging_flush_bts(): ip.access nanobts models call this when the RSL link is
dropped. Only osmo-bsc actually needs to do anything there.
- on_gsm_ts_init(): the mechanism to trigger timeslot initialization is related
to OML, while this action to take on init would pull in RSL dependencies.
utils/ and ipaccess/ each have a stubs.c file to implement these stubs. Tests
implement stubs inline where required.
From src/utils/, src/ipaccess/ and tests/*/, link in .o files from osmo-bsc/.
In order for this to work, the osmo-bsc subdir must be built before the other
source trees. (An alternative would be to include the .c files as sources, but
that would re-compile them in every source tree. Not a large burden really, but
unless linking .o files gives problems, let's have the quicker build.)
Minor obvious cleanups creep in with this patch, I will not bother to name them
individually now unless code review asks me to.
Rationale:
1) libbsc has been separate to use it for osmo-nitb and osmo-bsc in the old
openbsc.git. This is no longer required, and spreading over libbsc and osmo-bsc
is distracting.
2) Recently, ridiculous linking requirements have made adding new functions
cumbersome, because libbsc has started depending on osmo-bsc/*.c
implementations: on gscon FSM and bssap functions. For example, neither
bs11_config nor ipaccess-config nor bts_test need handover_cfg or BSSMAP
message composition. It makes no sense to link the entire osmo-bsc to it, nor
do we want to keep adding stubs to each linking realm.
Change-Id: I36a586726f5818121abe54d25654819fc451d3bf
2018-05-26 23:26:31 +00:00
|
|
|
cd->h1.h = 1;
|
|
|
|
cd->h1.maio_high = lchan->ts->hopping.maio >> 2;
|
|
|
|
cd->h1.maio_low = lchan->ts->hopping.maio & 0x03;
|
|
|
|
cd->h1.hsn = lchan->ts->hopping.hsn;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-06-02 20:13:39 +00:00
|
|
|
int gsm48_lchan2chan_desc(struct gsm48_chan_desc *cd,
|
|
|
|
const struct gsm_lchan *lchan,
|
2021-05-26 21:59:09 +00:00
|
|
|
uint8_t tsc, bool allow_osmo_cbits)
|
2018-09-09 15:17:44 +00:00
|
|
|
{
|
2021-05-26 21:59:09 +00:00
|
|
|
int chan_nr = gsm_lchan2chan_nr(lchan, allow_osmo_cbits);
|
2021-06-02 20:13:39 +00:00
|
|
|
if (chan_nr < 0) {
|
|
|
|
/* Log an error so that we don't need to add logging to each caller of this function */
|
|
|
|
LOG_LCHAN(lchan, LOGL_ERROR, "Error encoding Channel Number\n");
|
|
|
|
return chan_nr;
|
|
|
|
}
|
|
|
|
cd->chan_nr = chan_nr;
|
2021-05-19 00:29:53 +00:00
|
|
|
_chan_desc_fill_tail(cd, lchan, tsc);
|
2021-06-02 20:13:39 +00:00
|
|
|
return 0;
|
2018-09-09 15:17:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* like gsm48_lchan2chan_desc() above, but use ts->pchan_from_config to
|
|
|
|
* return a channel description based on what is configured, rather than
|
|
|
|
* what the current state of the pchan type is */
|
2021-06-02 20:13:39 +00:00
|
|
|
int gsm48_lchan2chan_desc_as_configured(struct gsm48_chan_desc *cd,
|
|
|
|
const struct gsm_lchan *lchan,
|
|
|
|
uint8_t tsc)
|
|
|
|
{
|
2021-05-26 21:59:09 +00:00
|
|
|
int chan_nr = gsm_pchan2chan_nr(lchan->ts->pchan_from_config, lchan->ts->nr, lchan->nr,
|
|
|
|
lchan->vamos.is_secondary);
|
2021-06-02 20:13:39 +00:00
|
|
|
if (chan_nr < 0) {
|
|
|
|
/* Log an error so that we don't need to add logging to each caller of this function */
|
|
|
|
LOG_LCHAN(lchan, LOGL_ERROR,
|
|
|
|
"Error encoding Channel Number: pchan %s ts %u ss %u%s (rc = %d)\n",
|
|
|
|
gsm_pchan_name(lchan->ts->pchan_from_config), lchan->ts->nr, lchan->nr,
|
|
|
|
lchan->vamos.is_secondary ? " (VAMOS shadow)" : "", chan_nr);
|
|
|
|
return chan_nr;
|
|
|
|
}
|
|
|
|
cd->chan_nr = chan_nr;
|
2021-05-19 00:29:53 +00:00
|
|
|
_chan_desc_fill_tail(cd, lchan, tsc);
|
2021-06-02 20:13:39 +00:00
|
|
|
return 0;
|
2018-09-09 15:17:44 +00:00
|
|
|
}
|
|
|
|
|
2020-07-15 18:53:16 +00:00
|
|
|
uint8_t gsm_ts_tsc(const struct gsm_bts_trx_ts *ts)
|
|
|
|
{
|
|
|
|
if (ts->tsc != -1)
|
|
|
|
return ts->tsc;
|
|
|
|
else
|
|
|
|
return ts->trx->bts->bsic & 7;
|
|
|
|
}
|
|
|
|
|
dissolve libbsc: move all to src/osmo-bsc, link .o files
Move all of libbsc/ into osmo-bsc/, and separate/move some implementations to
allow linking from utils/* and ipaccess/* without pulling in unccessary
dependencies.
Some utilities use gsm_network and gsm_bts structs, which already include data
structures for fairly advanced uses. Move initialization that only osmo-bsc
needs into new bsc_network_init() and bsc_bts_alloc_register() functions, so
that the leaner tools can use the old gsm_* versions without the need to link
everything (e.g. handover and lchan alloc code).
In some instances, there need to be stubs if to cut off linking "just before
the RSL level" and prevent dependencies from creeping in.
- abis_rsl_rcvmsg(): the only program currently interpreting RSL messages is
osmo-bsc, the utils are merely concerned with OML, if at all.
- paging_flush_bts(): ip.access nanobts models call this when the RSL link is
dropped. Only osmo-bsc actually needs to do anything there.
- on_gsm_ts_init(): the mechanism to trigger timeslot initialization is related
to OML, while this action to take on init would pull in RSL dependencies.
utils/ and ipaccess/ each have a stubs.c file to implement these stubs. Tests
implement stubs inline where required.
From src/utils/, src/ipaccess/ and tests/*/, link in .o files from osmo-bsc/.
In order for this to work, the osmo-bsc subdir must be built before the other
source trees. (An alternative would be to include the .c files as sources, but
that would re-compile them in every source tree. Not a large burden really, but
unless linking .o files gives problems, let's have the quicker build.)
Minor obvious cleanups creep in with this patch, I will not bother to name them
individually now unless code review asks me to.
Rationale:
1) libbsc has been separate to use it for osmo-nitb and osmo-bsc in the old
openbsc.git. This is no longer required, and spreading over libbsc and osmo-bsc
is distracting.
2) Recently, ridiculous linking requirements have made adding new functions
cumbersome, because libbsc has started depending on osmo-bsc/*.c
implementations: on gscon FSM and bssap functions. For example, neither
bs11_config nor ipaccess-config nor bts_test need handover_cfg or BSSMAP
message composition. It makes no sense to link the entire osmo-bsc to it, nor
do we want to keep adding stubs to each linking realm.
Change-Id: I36a586726f5818121abe54d25654819fc451d3bf
2018-05-26 23:26:31 +00:00
|
|
|
bool nm_is_running(const struct gsm_nm_state *s) {
|
2020-06-22 15:57:01 +00:00
|
|
|
if (s->operational != NM_OPSTATE_ENABLED)
|
|
|
|
return false;
|
|
|
|
if ((s->availability != NM_AVSTATE_OK) && (s->availability != 0xff))
|
|
|
|
return false;
|
|
|
|
if (s->administrative != NM_STATE_UNLOCKED)
|
|
|
|
return false;
|
|
|
|
return true;
|
dissolve libbsc: move all to src/osmo-bsc, link .o files
Move all of libbsc/ into osmo-bsc/, and separate/move some implementations to
allow linking from utils/* and ipaccess/* without pulling in unccessary
dependencies.
Some utilities use gsm_network and gsm_bts structs, which already include data
structures for fairly advanced uses. Move initialization that only osmo-bsc
needs into new bsc_network_init() and bsc_bts_alloc_register() functions, so
that the leaner tools can use the old gsm_* versions without the need to link
everything (e.g. handover and lchan alloc code).
In some instances, there need to be stubs if to cut off linking "just before
the RSL level" and prevent dependencies from creeping in.
- abis_rsl_rcvmsg(): the only program currently interpreting RSL messages is
osmo-bsc, the utils are merely concerned with OML, if at all.
- paging_flush_bts(): ip.access nanobts models call this when the RSL link is
dropped. Only osmo-bsc actually needs to do anything there.
- on_gsm_ts_init(): the mechanism to trigger timeslot initialization is related
to OML, while this action to take on init would pull in RSL dependencies.
utils/ and ipaccess/ each have a stubs.c file to implement these stubs. Tests
implement stubs inline where required.
From src/utils/, src/ipaccess/ and tests/*/, link in .o files from osmo-bsc/.
In order for this to work, the osmo-bsc subdir must be built before the other
source trees. (An alternative would be to include the .c files as sources, but
that would re-compile them in every source tree. Not a large burden really, but
unless linking .o files gives problems, let's have the quicker build.)
Minor obvious cleanups creep in with this patch, I will not bother to name them
individually now unless code review asks me to.
Rationale:
1) libbsc has been separate to use it for osmo-nitb and osmo-bsc in the old
openbsc.git. This is no longer required, and spreading over libbsc and osmo-bsc
is distracting.
2) Recently, ridiculous linking requirements have made adding new functions
cumbersome, because libbsc has started depending on osmo-bsc/*.c
implementations: on gscon FSM and bssap functions. For example, neither
bs11_config nor ipaccess-config nor bts_test need handover_cfg or BSSMAP
message composition. It makes no sense to link the entire osmo-bsc to it, nor
do we want to keep adding stubs to each linking realm.
Change-Id: I36a586726f5818121abe54d25654819fc451d3bf
2018-05-26 23:26:31 +00:00
|
|
|
}
|
large refactoring: use FSMs for lchans; add inter-BSC HO
Add FSMs:
- timeslot_fsm: handle dynamic timeslots and OML+RSL availability.
- lchan_fsm: handle an individual lchan activation, RTP stream and release,
signal the appropriate calling FSMs on success, failure, release.
- mgw_endpoint_fsm: handle one entire endpoint with several CI.
- assignment_fsm: BSSMAP Assignment Request.
- handover_fsm: all of intra, inter-MO and inter-MT handover.
Above FSMs absorb large parts of the gscon FSM. The gscon FSM was surpassing
the maximum amount events (32), and it is more logical to treat assignment,
handover and MGW procedures in separate FSMs.
- Add logging macros for each FSM type:
- LOG_TS()
- LOG_LCHAN()
- LOG_MGWEP(), LOG_CI()
- LOG_ASSIGNMENT()
- LOG_HO()
These log with the osmo_fsm_inst where present.
New style decision: logging without a final newline char is awkward,
especially for gsmtap logging and when other logs interleave LOGPC() calls;
we have various cases where the final \n goes missing, and also this invokes
the log category checking N times instead of once.
So I decided to make these macros *always* append a newline, but only if
there is no final newline yet. I hope that the compiler optimizes the
strlen() of the constant format strings away. Thus I can log with or without
typing "\n" and always get an \n termination anyway.
General:
- replace osmo_timers, state enums and program-wide osmo_signal_dispatch()
with dedicated FSM timeouts, states and events.
- introduce a common way to handle Tnnn timers: gsm_timers.h/.c: struct T_def.
These can be used (with some macro magic) to define a state's timeout once,
and not make mistakes for each osmo_fsm_inst_state_chg().
Details:
bsc_subscr_conn_fsm.c:
- move most states of this FSM to lchan_fsm, assignment_fsm, handover_fsm and
mgw_endpoint_fsm.
- There is exactly one state for an ongoing Assignment, with all details
handled in conn->assignment.fi. The state relies on the assignment_fsm's
timeout.
- There is one state for an ongoing Handover; except for an incoming Handover
from a remote BSS, the gscon remains in ST_INIT until the new lchan and conn
are both established.
- move bssmap_add_lcls_status() to osmo_bsc_lcls.c
abis_rsl.c:
- move all dynamic timeslot logic away into timeslot_fsm. Only keep plain send/receive functions in
abis_rsl.c
- reduce some rsl functions to merely send a message, rename to "_tx_".
- rsl_ipacc_mdcx(): add '_tx_' in the name; move parts that change the lchan state out into the
lchan_fsm, the lchan->abis_ip.* are now set there prior to invoking this function.
- move all timers and error/release handling away into various FSMs.
- tweak ipa_smod_s_for_lchan() and ipa_rtp_pt_for_lchan() to not require an
lchan passed, but just mode,type that they require. Rename to
ipacc_speech_mode*() and ipacc_payload_type().
- add rsl_forward_layer3_info, used for inter-BSC HO MO, to just send the RR
message received during BSSMAP Handover Command.
- move various logging to LOG_LCHAN() in order to log with the lchan FSM instance.
One drawback is that the lchan FSM is limited to one logging category, i.e. this moves some logging
from DRR to DRSL. It might actually make sense to combine those categories.
- lose LOGP...LOGPC logging cascades: they are bad for gsmtap logging and for performance.
- handle_classmark_chg(): change logging, move cm2 len check out of the cm3 condition (I hope that's
correct).
- gsm48_send_ho_cmd(): split off gsm48_make_ho_cmd() which doesn't send right away, so that during
inter-bsc HO we can make an RR Handover Command to send via the MSC to the remote BSS.
assignment_fsm.c:
- the Chan Mode Modify in case of re-using the same lchan is not implemented
yet, because this was also missing in the previous implementation (OS#3357).
osmo_bsc_api.c:
- simplify bsc_mr_config() and move to lchan_fsm.c, the only caller; rename to
lchan_mr_config(). (bsc_mr_config() used to copy the values to mr_bts_lv
twice, once by member assignment and then again with a memcpy.)
- During handover, we used to copy the MR config from the old lchan. Since we
may handover between FR and HR, rather set the MR Config anew every time, so
that FR rates are always available on FR lchans, and never on HR lchans.
Depends: I03ee7ce840ecfa0b6a33358e7385528aabd4873f (libosmocore),
I1f2918418c38918c5ac70acaa51a47adfca12b5e (libosmocore)
Change-Id: I82e3f918295daa83274a4cf803f046979f284366
2018-05-14 16:14:15 +00:00
|
|
|
|
|
|
|
/* determine the logical channel type based on the physical channel type */
|
|
|
|
int gsm_lchan_type_by_pchan(enum gsm_phys_chan_config pchan)
|
|
|
|
{
|
|
|
|
switch (pchan) {
|
|
|
|
case GSM_PCHAN_TCH_F:
|
|
|
|
return GSM_LCHAN_TCH_F;
|
|
|
|
case GSM_PCHAN_TCH_H:
|
|
|
|
return GSM_LCHAN_TCH_H;
|
|
|
|
case GSM_PCHAN_SDCCH8_SACCH8C:
|
|
|
|
case GSM_PCHAN_SDCCH8_SACCH8C_CBCH:
|
|
|
|
case GSM_PCHAN_CCCH_SDCCH4:
|
|
|
|
case GSM_PCHAN_CCCH_SDCCH4_CBCH:
|
|
|
|
return GSM_LCHAN_SDCCH;
|
|
|
|
default:
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
enum gsm_phys_chan_config gsm_pchan_by_lchan_type(enum gsm_chan_t type)
|
|
|
|
{
|
|
|
|
switch (type) {
|
|
|
|
case GSM_LCHAN_TCH_F:
|
|
|
|
return GSM_PCHAN_TCH_F;
|
|
|
|
case GSM_LCHAN_TCH_H:
|
|
|
|
return GSM_PCHAN_TCH_H;
|
|
|
|
case GSM_LCHAN_NONE:
|
|
|
|
case GSM_LCHAN_PDTCH:
|
|
|
|
/* TODO: so far lchan->type is NONE in PDCH mode. PDTCH is only
|
|
|
|
* used in osmo-bts. Maybe set PDTCH and drop the NONE case
|
|
|
|
* here. */
|
|
|
|
return GSM_PCHAN_PDCH;
|
|
|
|
default:
|
|
|
|
return GSM_PCHAN_UNKNOWN;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-27 23:17:14 +00:00
|
|
|
enum channel_rate chan_t_to_chan_rate(enum gsm_chan_t chan_t)
|
|
|
|
{
|
|
|
|
switch (chan_t) {
|
|
|
|
case GSM_LCHAN_SDCCH:
|
|
|
|
return CH_RATE_SDCCH;
|
|
|
|
case GSM_LCHAN_TCH_F:
|
|
|
|
return CH_RATE_FULL;
|
|
|
|
case GSM_LCHAN_TCH_H:
|
|
|
|
return CH_RATE_HALF;
|
|
|
|
default:
|
|
|
|
/* For other channel types, the channel_rate value is never used. It is fine to return an invalid value,
|
|
|
|
* and callers don't actually need to check for this. */
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
large refactoring: use FSMs for lchans; add inter-BSC HO
Add FSMs:
- timeslot_fsm: handle dynamic timeslots and OML+RSL availability.
- lchan_fsm: handle an individual lchan activation, RTP stream and release,
signal the appropriate calling FSMs on success, failure, release.
- mgw_endpoint_fsm: handle one entire endpoint with several CI.
- assignment_fsm: BSSMAP Assignment Request.
- handover_fsm: all of intra, inter-MO and inter-MT handover.
Above FSMs absorb large parts of the gscon FSM. The gscon FSM was surpassing
the maximum amount events (32), and it is more logical to treat assignment,
handover and MGW procedures in separate FSMs.
- Add logging macros for each FSM type:
- LOG_TS()
- LOG_LCHAN()
- LOG_MGWEP(), LOG_CI()
- LOG_ASSIGNMENT()
- LOG_HO()
These log with the osmo_fsm_inst where present.
New style decision: logging without a final newline char is awkward,
especially for gsmtap logging and when other logs interleave LOGPC() calls;
we have various cases where the final \n goes missing, and also this invokes
the log category checking N times instead of once.
So I decided to make these macros *always* append a newline, but only if
there is no final newline yet. I hope that the compiler optimizes the
strlen() of the constant format strings away. Thus I can log with or without
typing "\n" and always get an \n termination anyway.
General:
- replace osmo_timers, state enums and program-wide osmo_signal_dispatch()
with dedicated FSM timeouts, states and events.
- introduce a common way to handle Tnnn timers: gsm_timers.h/.c: struct T_def.
These can be used (with some macro magic) to define a state's timeout once,
and not make mistakes for each osmo_fsm_inst_state_chg().
Details:
bsc_subscr_conn_fsm.c:
- move most states of this FSM to lchan_fsm, assignment_fsm, handover_fsm and
mgw_endpoint_fsm.
- There is exactly one state for an ongoing Assignment, with all details
handled in conn->assignment.fi. The state relies on the assignment_fsm's
timeout.
- There is one state for an ongoing Handover; except for an incoming Handover
from a remote BSS, the gscon remains in ST_INIT until the new lchan and conn
are both established.
- move bssmap_add_lcls_status() to osmo_bsc_lcls.c
abis_rsl.c:
- move all dynamic timeslot logic away into timeslot_fsm. Only keep plain send/receive functions in
abis_rsl.c
- reduce some rsl functions to merely send a message, rename to "_tx_".
- rsl_ipacc_mdcx(): add '_tx_' in the name; move parts that change the lchan state out into the
lchan_fsm, the lchan->abis_ip.* are now set there prior to invoking this function.
- move all timers and error/release handling away into various FSMs.
- tweak ipa_smod_s_for_lchan() and ipa_rtp_pt_for_lchan() to not require an
lchan passed, but just mode,type that they require. Rename to
ipacc_speech_mode*() and ipacc_payload_type().
- add rsl_forward_layer3_info, used for inter-BSC HO MO, to just send the RR
message received during BSSMAP Handover Command.
- move various logging to LOG_LCHAN() in order to log with the lchan FSM instance.
One drawback is that the lchan FSM is limited to one logging category, i.e. this moves some logging
from DRR to DRSL. It might actually make sense to combine those categories.
- lose LOGP...LOGPC logging cascades: they are bad for gsmtap logging and for performance.
- handle_classmark_chg(): change logging, move cm2 len check out of the cm3 condition (I hope that's
correct).
- gsm48_send_ho_cmd(): split off gsm48_make_ho_cmd() which doesn't send right away, so that during
inter-bsc HO we can make an RR Handover Command to send via the MSC to the remote BSS.
assignment_fsm.c:
- the Chan Mode Modify in case of re-using the same lchan is not implemented
yet, because this was also missing in the previous implementation (OS#3357).
osmo_bsc_api.c:
- simplify bsc_mr_config() and move to lchan_fsm.c, the only caller; rename to
lchan_mr_config(). (bsc_mr_config() used to copy the values to mr_bts_lv
twice, once by member assignment and then again with a memcpy.)
- During handover, we used to copy the MR config from the old lchan. Since we
may handover between FR and HR, rather set the MR Config anew every time, so
that FR rates are always available on FR lchans, and never on HR lchans.
Depends: I03ee7ce840ecfa0b6a33358e7385528aabd4873f (libosmocore),
I1f2918418c38918c5ac70acaa51a47adfca12b5e (libosmocore)
Change-Id: I82e3f918295daa83274a4cf803f046979f284366
2018-05-14 16:14:15 +00:00
|
|
|
/* Can the timeslot in principle be used as this PCHAN kind? */
|
|
|
|
bool ts_is_capable_of_pchan(struct gsm_bts_trx_ts *ts, enum gsm_phys_chan_config pchan)
|
|
|
|
{
|
|
|
|
switch (ts->pchan_on_init) {
|
|
|
|
case GSM_PCHAN_TCH_F_PDCH:
|
|
|
|
switch (pchan) {
|
|
|
|
case GSM_PCHAN_TCH_F:
|
|
|
|
case GSM_PCHAN_PDCH:
|
|
|
|
return true;
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
case GSM_PCHAN_TCH_F_TCH_H_PDCH:
|
|
|
|
switch (pchan) {
|
|
|
|
case GSM_PCHAN_TCH_F:
|
|
|
|
case GSM_PCHAN_TCH_H:
|
|
|
|
case GSM_PCHAN_PDCH:
|
|
|
|
return true;
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
case GSM_PCHAN_CCCH_SDCCH4_CBCH:
|
|
|
|
switch (pchan) {
|
|
|
|
case GSM_PCHAN_CCCH_SDCCH4_CBCH:
|
|
|
|
case GSM_PCHAN_CCCH_SDCCH4:
|
|
|
|
case GSM_PCHAN_CCCH:
|
|
|
|
return true;
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
case GSM_PCHAN_CCCH_SDCCH4:
|
|
|
|
switch (pchan) {
|
|
|
|
case GSM_PCHAN_CCCH_SDCCH4:
|
|
|
|
case GSM_PCHAN_CCCH:
|
|
|
|
return true;
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
case GSM_PCHAN_SDCCH8_SACCH8C_CBCH:
|
|
|
|
switch (pchan) {
|
|
|
|
case GSM_PCHAN_SDCCH8_SACCH8C_CBCH:
|
|
|
|
case GSM_PCHAN_SDCCH8_SACCH8C:
|
|
|
|
return true;
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
default:
|
|
|
|
return ts->pchan_on_init == pchan;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ts_is_capable_of_lchant(struct gsm_bts_trx_ts *ts, enum gsm_chan_t type)
|
|
|
|
{
|
|
|
|
switch (ts->pchan_on_init) {
|
|
|
|
|
|
|
|
case GSM_PCHAN_TCH_F:
|
|
|
|
switch (type) {
|
|
|
|
case GSM_LCHAN_TCH_F:
|
|
|
|
return true;
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
case GSM_PCHAN_TCH_H:
|
|
|
|
switch (type) {
|
|
|
|
case GSM_LCHAN_TCH_H:
|
|
|
|
return true;
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
case GSM_PCHAN_TCH_F_PDCH:
|
|
|
|
switch (type) {
|
|
|
|
case GSM_LCHAN_TCH_F:
|
|
|
|
case GSM_LCHAN_PDTCH:
|
|
|
|
return true;
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
case GSM_PCHAN_TCH_F_TCH_H_PDCH:
|
|
|
|
switch (type) {
|
|
|
|
case GSM_LCHAN_TCH_F:
|
|
|
|
case GSM_LCHAN_TCH_H:
|
|
|
|
case GSM_LCHAN_PDTCH:
|
|
|
|
return true;
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
case GSM_PCHAN_PDCH:
|
|
|
|
switch (type) {
|
|
|
|
case GSM_LCHAN_PDTCH:
|
|
|
|
return true;
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
case GSM_PCHAN_CCCH:
|
|
|
|
switch (type) {
|
|
|
|
case GSM_LCHAN_CCCH:
|
|
|
|
return true;
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case GSM_PCHAN_CCCH_SDCCH4_CBCH:
|
|
|
|
case GSM_PCHAN_CCCH_SDCCH4:
|
|
|
|
case GSM_PCHAN_SDCCH8_SACCH8C:
|
|
|
|
case GSM_PCHAN_SDCCH8_SACCH8C_CBCH:
|
|
|
|
switch (type) {
|
|
|
|
case GSM_LCHAN_CCCH:
|
|
|
|
case GSM_LCHAN_SDCCH:
|
|
|
|
return true;
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ts_is_usable(const struct gsm_bts_trx_ts *ts)
|
|
|
|
{
|
|
|
|
if (!trx_is_usable(ts->trx)) {
|
|
|
|
LOGP(DRLL, LOGL_DEBUG, "%s not usable\n", gsm_trx_name(ts->trx));
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!ts->fi)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
switch (ts->fi->state) {
|
|
|
|
case TS_ST_NOT_INITIALIZED:
|
|
|
|
case TS_ST_BORKEN:
|
|
|
|
return false;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2019-10-31 14:59:49 +00:00
|
|
|
void conn_update_ms_power_class(struct gsm_subscriber_connection *conn, uint8_t power_class)
|
|
|
|
{
|
|
|
|
struct gsm_bts *bts = conn_get_bts(conn);
|
2021-01-15 20:43:26 +00:00
|
|
|
|
|
|
|
/* MS Power class remains the same => do nothing */
|
|
|
|
if (power_class == conn->ms_power_class)
|
|
|
|
return;
|
|
|
|
|
2019-10-31 14:59:49 +00:00
|
|
|
LOGP(DRLL, LOGL_DEBUG, "MS Power class update: %" PRIu8 " -> %" PRIu8 "\n",
|
|
|
|
conn->ms_power_class, power_class);
|
|
|
|
|
|
|
|
conn->ms_power_class = power_class;
|
|
|
|
|
|
|
|
/* If there's an associated lchan, attempt to update its max power to be
|
|
|
|
on track with band maximum values */
|
2020-06-18 15:29:56 +00:00
|
|
|
if (bts && conn->lchan)
|
2019-10-31 14:59:49 +00:00
|
|
|
lchan_update_ms_power_ctrl_level(conn->lchan, bts->ms_max_power);
|
|
|
|
}
|
|
|
|
|
|
|
|
void lchan_update_ms_power_ctrl_level(struct gsm_lchan *lchan, int ms_power_dbm)
|
|
|
|
{
|
|
|
|
struct gsm_bts *bts = lchan->ts->trx->bts;
|
|
|
|
struct gsm_subscriber_connection *conn = lchan->conn;
|
|
|
|
int max_pwr_dbm_pwclass, new_pwr;
|
2019-11-12 15:30:30 +00:00
|
|
|
bool send_pwr_ctrl_msg = false;
|
2019-10-31 14:59:49 +00:00
|
|
|
|
|
|
|
LOG_LCHAN(lchan, LOGL_DEBUG,
|
|
|
|
"MS Power level update requested: %d dBm\n", ms_power_dbm);
|
|
|
|
|
|
|
|
if (!conn)
|
|
|
|
goto ms_power_default;
|
|
|
|
|
|
|
|
if (conn->ms_power_class == 0)
|
|
|
|
goto ms_power_default;
|
|
|
|
|
|
|
|
if ((max_pwr_dbm_pwclass = (int)ms_class_gmsk_dbm(bts->band, conn->ms_power_class)) < 0) {
|
|
|
|
LOG_LCHAN(lchan, LOGL_INFO,
|
|
|
|
"Failed getting max ms power for power class %" PRIu8
|
|
|
|
" on band %s, providing default max ms power\n",
|
|
|
|
conn->ms_power_class, gsm_band_name(bts->band));
|
|
|
|
goto ms_power_default;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Current configured max pwr is above maximum one allowed on
|
|
|
|
current band + ms power class, so use that one. */
|
|
|
|
if (ms_power_dbm > max_pwr_dbm_pwclass)
|
|
|
|
ms_power_dbm = max_pwr_dbm_pwclass;
|
|
|
|
|
|
|
|
ms_power_default:
|
|
|
|
if ((new_pwr = ms_pwr_ctl_lvl(bts->band, ms_power_dbm)) < 0) {
|
|
|
|
LOG_LCHAN(lchan, LOGL_INFO,
|
|
|
|
"Failed getting max ms power level %d on band %s,"
|
|
|
|
" providing default max ms power\n",
|
|
|
|
ms_power_dbm, gsm_band_name(bts->band));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
LOG_LCHAN(lchan, LOGL_DEBUG,
|
|
|
|
"MS Power level update (power class %" PRIu8 "): %" PRIu8 " -> %d\n",
|
|
|
|
conn ? conn->ms_power_class : 0, lchan->ms_power, new_pwr);
|
|
|
|
|
2019-11-12 15:30:30 +00:00
|
|
|
/* If chan was already activated and max ms_power changes (due to power
|
|
|
|
classmark received), send an MS Power Control message */
|
|
|
|
if (lchan->activate.activ_ack && new_pwr != lchan->ms_power)
|
|
|
|
send_pwr_ctrl_msg = true;
|
|
|
|
|
2019-10-31 14:59:49 +00:00
|
|
|
lchan->ms_power = new_pwr;
|
2019-11-12 15:30:30 +00:00
|
|
|
|
|
|
|
if (send_pwr_ctrl_msg)
|
|
|
|
rsl_chan_ms_power_ctrl(lchan);
|
2019-10-31 14:59:49 +00:00
|
|
|
}
|
|
|
|
|
large refactoring: use FSMs for lchans; add inter-BSC HO
Add FSMs:
- timeslot_fsm: handle dynamic timeslots and OML+RSL availability.
- lchan_fsm: handle an individual lchan activation, RTP stream and release,
signal the appropriate calling FSMs on success, failure, release.
- mgw_endpoint_fsm: handle one entire endpoint with several CI.
- assignment_fsm: BSSMAP Assignment Request.
- handover_fsm: all of intra, inter-MO and inter-MT handover.
Above FSMs absorb large parts of the gscon FSM. The gscon FSM was surpassing
the maximum amount events (32), and it is more logical to treat assignment,
handover and MGW procedures in separate FSMs.
- Add logging macros for each FSM type:
- LOG_TS()
- LOG_LCHAN()
- LOG_MGWEP(), LOG_CI()
- LOG_ASSIGNMENT()
- LOG_HO()
These log with the osmo_fsm_inst where present.
New style decision: logging without a final newline char is awkward,
especially for gsmtap logging and when other logs interleave LOGPC() calls;
we have various cases where the final \n goes missing, and also this invokes
the log category checking N times instead of once.
So I decided to make these macros *always* append a newline, but only if
there is no final newline yet. I hope that the compiler optimizes the
strlen() of the constant format strings away. Thus I can log with or without
typing "\n" and always get an \n termination anyway.
General:
- replace osmo_timers, state enums and program-wide osmo_signal_dispatch()
with dedicated FSM timeouts, states and events.
- introduce a common way to handle Tnnn timers: gsm_timers.h/.c: struct T_def.
These can be used (with some macro magic) to define a state's timeout once,
and not make mistakes for each osmo_fsm_inst_state_chg().
Details:
bsc_subscr_conn_fsm.c:
- move most states of this FSM to lchan_fsm, assignment_fsm, handover_fsm and
mgw_endpoint_fsm.
- There is exactly one state for an ongoing Assignment, with all details
handled in conn->assignment.fi. The state relies on the assignment_fsm's
timeout.
- There is one state for an ongoing Handover; except for an incoming Handover
from a remote BSS, the gscon remains in ST_INIT until the new lchan and conn
are both established.
- move bssmap_add_lcls_status() to osmo_bsc_lcls.c
abis_rsl.c:
- move all dynamic timeslot logic away into timeslot_fsm. Only keep plain send/receive functions in
abis_rsl.c
- reduce some rsl functions to merely send a message, rename to "_tx_".
- rsl_ipacc_mdcx(): add '_tx_' in the name; move parts that change the lchan state out into the
lchan_fsm, the lchan->abis_ip.* are now set there prior to invoking this function.
- move all timers and error/release handling away into various FSMs.
- tweak ipa_smod_s_for_lchan() and ipa_rtp_pt_for_lchan() to not require an
lchan passed, but just mode,type that they require. Rename to
ipacc_speech_mode*() and ipacc_payload_type().
- add rsl_forward_layer3_info, used for inter-BSC HO MO, to just send the RR
message received during BSSMAP Handover Command.
- move various logging to LOG_LCHAN() in order to log with the lchan FSM instance.
One drawback is that the lchan FSM is limited to one logging category, i.e. this moves some logging
from DRR to DRSL. It might actually make sense to combine those categories.
- lose LOGP...LOGPC logging cascades: they are bad for gsmtap logging and for performance.
- handle_classmark_chg(): change logging, move cm2 len check out of the cm3 condition (I hope that's
correct).
- gsm48_send_ho_cmd(): split off gsm48_make_ho_cmd() which doesn't send right away, so that during
inter-bsc HO we can make an RR Handover Command to send via the MSC to the remote BSS.
assignment_fsm.c:
- the Chan Mode Modify in case of re-using the same lchan is not implemented
yet, because this was also missing in the previous implementation (OS#3357).
osmo_bsc_api.c:
- simplify bsc_mr_config() and move to lchan_fsm.c, the only caller; rename to
lchan_mr_config(). (bsc_mr_config() used to copy the values to mr_bts_lv
twice, once by member assignment and then again with a memcpy.)
- During handover, we used to copy the MR config from the old lchan. Since we
may handover between FR and HR, rather set the MR Config anew every time, so
that FR rates are always available on FR lchans, and never on HR lchans.
Depends: I03ee7ce840ecfa0b6a33358e7385528aabd4873f (libosmocore),
I1f2918418c38918c5ac70acaa51a47adfca12b5e (libosmocore)
Change-Id: I82e3f918295daa83274a4cf803f046979f284366
2018-05-14 16:14:15 +00:00
|
|
|
const struct value_string lchan_activate_mode_names[] = {
|
2021-05-10 15:47:46 +00:00
|
|
|
OSMO_VALUE_STRING(ACTIVATE_FOR_NONE),
|
|
|
|
OSMO_VALUE_STRING(ACTIVATE_FOR_MS_CHANNEL_REQUEST),
|
|
|
|
OSMO_VALUE_STRING(ACTIVATE_FOR_ASSIGNMENT),
|
|
|
|
OSMO_VALUE_STRING(ACTIVATE_FOR_HANDOVER),
|
|
|
|
OSMO_VALUE_STRING(ACTIVATE_FOR_VTY),
|
large refactoring: use FSMs for lchans; add inter-BSC HO
Add FSMs:
- timeslot_fsm: handle dynamic timeslots and OML+RSL availability.
- lchan_fsm: handle an individual lchan activation, RTP stream and release,
signal the appropriate calling FSMs on success, failure, release.
- mgw_endpoint_fsm: handle one entire endpoint with several CI.
- assignment_fsm: BSSMAP Assignment Request.
- handover_fsm: all of intra, inter-MO and inter-MT handover.
Above FSMs absorb large parts of the gscon FSM. The gscon FSM was surpassing
the maximum amount events (32), and it is more logical to treat assignment,
handover and MGW procedures in separate FSMs.
- Add logging macros for each FSM type:
- LOG_TS()
- LOG_LCHAN()
- LOG_MGWEP(), LOG_CI()
- LOG_ASSIGNMENT()
- LOG_HO()
These log with the osmo_fsm_inst where present.
New style decision: logging without a final newline char is awkward,
especially for gsmtap logging and when other logs interleave LOGPC() calls;
we have various cases where the final \n goes missing, and also this invokes
the log category checking N times instead of once.
So I decided to make these macros *always* append a newline, but only if
there is no final newline yet. I hope that the compiler optimizes the
strlen() of the constant format strings away. Thus I can log with or without
typing "\n" and always get an \n termination anyway.
General:
- replace osmo_timers, state enums and program-wide osmo_signal_dispatch()
with dedicated FSM timeouts, states and events.
- introduce a common way to handle Tnnn timers: gsm_timers.h/.c: struct T_def.
These can be used (with some macro magic) to define a state's timeout once,
and not make mistakes for each osmo_fsm_inst_state_chg().
Details:
bsc_subscr_conn_fsm.c:
- move most states of this FSM to lchan_fsm, assignment_fsm, handover_fsm and
mgw_endpoint_fsm.
- There is exactly one state for an ongoing Assignment, with all details
handled in conn->assignment.fi. The state relies on the assignment_fsm's
timeout.
- There is one state for an ongoing Handover; except for an incoming Handover
from a remote BSS, the gscon remains in ST_INIT until the new lchan and conn
are both established.
- move bssmap_add_lcls_status() to osmo_bsc_lcls.c
abis_rsl.c:
- move all dynamic timeslot logic away into timeslot_fsm. Only keep plain send/receive functions in
abis_rsl.c
- reduce some rsl functions to merely send a message, rename to "_tx_".
- rsl_ipacc_mdcx(): add '_tx_' in the name; move parts that change the lchan state out into the
lchan_fsm, the lchan->abis_ip.* are now set there prior to invoking this function.
- move all timers and error/release handling away into various FSMs.
- tweak ipa_smod_s_for_lchan() and ipa_rtp_pt_for_lchan() to not require an
lchan passed, but just mode,type that they require. Rename to
ipacc_speech_mode*() and ipacc_payload_type().
- add rsl_forward_layer3_info, used for inter-BSC HO MO, to just send the RR
message received during BSSMAP Handover Command.
- move various logging to LOG_LCHAN() in order to log with the lchan FSM instance.
One drawback is that the lchan FSM is limited to one logging category, i.e. this moves some logging
from DRR to DRSL. It might actually make sense to combine those categories.
- lose LOGP...LOGPC logging cascades: they are bad for gsmtap logging and for performance.
- handle_classmark_chg(): change logging, move cm2 len check out of the cm3 condition (I hope that's
correct).
- gsm48_send_ho_cmd(): split off gsm48_make_ho_cmd() which doesn't send right away, so that during
inter-bsc HO we can make an RR Handover Command to send via the MSC to the remote BSS.
assignment_fsm.c:
- the Chan Mode Modify in case of re-using the same lchan is not implemented
yet, because this was also missing in the previous implementation (OS#3357).
osmo_bsc_api.c:
- simplify bsc_mr_config() and move to lchan_fsm.c, the only caller; rename to
lchan_mr_config(). (bsc_mr_config() used to copy the values to mr_bts_lv
twice, once by member assignment and then again with a memcpy.)
- During handover, we used to copy the MR config from the old lchan. Since we
may handover between FR and HR, rather set the MR Config anew every time, so
that FR rates are always available on FR lchans, and never on HR lchans.
Depends: I03ee7ce840ecfa0b6a33358e7385528aabd4873f (libosmocore),
I1f2918418c38918c5ac70acaa51a47adfca12b5e (libosmocore)
Change-Id: I82e3f918295daa83274a4cf803f046979f284366
2018-05-14 16:14:15 +00:00
|
|
|
{}
|
|
|
|
};
|
2019-11-01 17:57:23 +00:00
|
|
|
|
lchan and assignment FSMs: make Channel Mode Modify more sane
The Channel Mode Modify procedure is currently implemented for changing
a TCH lchan from signalling to voice mode. For that, however, it is
re-using (abusing) the channel activation structs and state transitions,
and thus always implies activating a voice stream when the mode
modification is done.
I will add a Channel Mode Modify to enable VAMOS mode soon, so I require
separate structs and state transitions which also work on an lchan that
already has a voice stream established: a struct lchan_modify_info and
LCHAN_EV_REQUEST_MODE_MODIFY, and dedicated assignment FSM state
ASSIGNMENT_ST_WAIT_LCHAN_MODIFIED.
For the part where a Channel Mode Modify enables a voice stream after
switching from signalling to speech mode, still use the channel
activation code path, but only once the mode modification is done.
General improvements:
- To ask for a mode modification, emit an FSM event that ensures a mode
modify only happens when the lchan state allows it.
- The new lchan_modify_info struct reflects only those parts that have
an effect during a mode modification (before the lchan_activate_info
was fully populated, many values not having an effect).
- More accurate logging, indicating "Mode Modify" instead of "Channel
Activation"
A TTCN3 test for the Channel Mode Modify procedure is added in
Idf4efaed986de0bbd2b663313e837352cc139f0f, and the test passes both
before and after this patch is applied.
Related: SYS#4895
Change-Id: I4986844f839b1c9672c61d916eb3d33d0042d747
2021-04-14 17:39:01 +00:00
|
|
|
const struct value_string lchan_modify_for_names[] = {
|
|
|
|
OSMO_VALUE_STRING(MODIFY_FOR_NONE),
|
|
|
|
OSMO_VALUE_STRING(MODIFY_FOR_ASSIGNMENT),
|
|
|
|
OSMO_VALUE_STRING(MODIFY_FOR_VTY),
|
|
|
|
{}
|
|
|
|
};
|
|
|
|
|
2021-05-01 02:52:05 +00:00
|
|
|
const struct value_string assign_for_names[] = {
|
|
|
|
OSMO_VALUE_STRING(ASSIGN_FOR_NONE),
|
|
|
|
OSMO_VALUE_STRING(ASSIGN_FOR_BSSMAP_REQ),
|
2021-05-11 15:21:30 +00:00
|
|
|
OSMO_VALUE_STRING(ASSIGN_FOR_CONGESTION_RESOLUTION),
|
2021-05-01 02:52:05 +00:00
|
|
|
{}
|
|
|
|
};
|
|
|
|
|
RR Channel Release: pass Cause code from BSSMAP Clear to the BTS
In lchan.release, add 'cause_rr', and set RR Channel Release message's cause
value to lchan.release.cause_rr.
In lchan_release(), do not set lchan.release.rsl_error_cause to the RR cause
value, these are unrelated. Store in new lchan.release.cause_rr instead. The
rsl_error_cause is apparently only used for logging, except for one place in
lchan_fsm_wait_activ_ack() that compares it to RSL_ERR_RCH_ALR_ACTV_ALLOC, so
there should not be a functional difference by this fix.
Propagate the BSSMAP Clear Command cause to the RR Channel Release:
Add struct gscon_clear_cmd_data as event data for GSCON_EV_A_CLEAR_CMD -- so
far it sent the is_csfb flag, add the gsm0808_cause; invoking the event happens
in bssmap_handle_clear_cmd().
Adjust event handling in gscon_fsm_allstate(); there, pass the cause to
gscon_release_lchans(). In gscon_release_lchans(), pass the cause to
gscon_release_lchan(), and then lchan_release(), which sets the new
lchan.release.cause_rr to the passed cause value.
As soon as the lchan FSM enters the proper state, it calls
gsm48_send_rr_release(). There, set the cause value in the encoded message to
lchan.release.cause_rr.
Interworking with osmo-msc: so far, osmo-msc fails to set the Clear Command
cause code for normal release, it just passes 0 which amounts to
GSM0808_CAUSE_RADIO_INTERFACE_MESSAGE_FAILURE. Before this patch, osmo-bsc
always sent GSM48_RR_CAUSE_NORMAL in the RR Channel Release, and after this
patch it will receive 0 == GSM0808_CAUSE_RADIO_INTERFACE_MESSAGE_FAILURE from
osmo-msc and more accurately translate that to GSM48_RR_CAUSE_PROT_ERROR_UNSPC.
This means in practice that we will now see an error cause in RR Channel
Release instead of GSM48_RR_CAUSE_NORMAL when working with osmo-msc. For
changing osmo-msc to send GSM0808_CAUSE_CALL_CONTROL instead (which translates
to GSM48_RR_CAUSE_NORMAL), see OS#4664 and change-id
I1347ed72ae7d7ea73a557b866e764819c5ef8c42 (osmo-msc).
A test for this is in Ie6c99f28b610a67f2d59ec00b3541940e882251b
(osmo-ttcn3-hacks).
Related: SYS#4872
Change-Id: I734cc55c501d61bbdadee81a223b26f9df57f959
2020-07-09 13:54:40 +00:00
|
|
|
/* This may be specific to RR Channel Release, and the mappings were chosen by pure naive guessing without a proper
|
|
|
|
* specification available. */
|
|
|
|
enum gsm48_rr_cause bsc_gsm48_rr_cause_from_gsm0808_cause(enum gsm0808_cause c)
|
|
|
|
{
|
|
|
|
switch (c) {
|
|
|
|
case GSM0808_CAUSE_PREEMPTION:
|
|
|
|
return GSM48_RR_CAUSE_PREMPTIVE_REL;
|
|
|
|
case GSM0808_CAUSE_RADIO_INTERFACE_MESSAGE_FAILURE:
|
|
|
|
case GSM0808_CAUSE_INVALID_MESSAGE_CONTENTS:
|
|
|
|
case GSM0808_CAUSE_INFORMATION_ELEMENT_OR_FIELD_MISSING:
|
|
|
|
case GSM0808_CAUSE_INCORRECT_VALUE:
|
|
|
|
case GSM0808_CAUSE_UNKNOWN_MESSAGE_TYPE:
|
|
|
|
case GSM0808_CAUSE_UNKNOWN_INFORMATION_ELEMENT:
|
|
|
|
return GSM48_RR_CAUSE_PROT_ERROR_UNSPC;
|
|
|
|
case GSM0808_CAUSE_CALL_CONTROL:
|
|
|
|
case GSM0808_CAUSE_HANDOVER_SUCCESSFUL:
|
|
|
|
case GSM0808_CAUSE_BETTER_CELL:
|
|
|
|
case GSM0808_CAUSE_DIRECTED_RETRY:
|
|
|
|
case GSM0808_CAUSE_REDUCE_LOAD_IN_SERVING_CELL:
|
|
|
|
case GSM0808_CAUSE_RELOCATION_TRIGGERED:
|
|
|
|
case GSM0808_CAUSE_ALT_CHAN_CONFIG_REQUESTED:
|
|
|
|
return GSM48_RR_CAUSE_NORMAL;
|
|
|
|
default:
|
|
|
|
return GSM48_RR_CAUSE_ABNORMAL_UNSPEC;
|
|
|
|
}
|
|
|
|
}
|
2020-07-10 23:44:08 +00:00
|
|
|
|
|
|
|
/* Map RSL_ERR_* cause codes to gsm48_rr_cause codes.
|
|
|
|
* The mappings were chosen by naive guessing without a proper specification available. */
|
|
|
|
enum gsm48_rr_cause bsc_gsm48_rr_cause_from_rsl_cause(uint8_t c)
|
|
|
|
{
|
|
|
|
switch (c) {
|
|
|
|
case RSL_ERR_NORMAL_UNSPEC:
|
|
|
|
return GSM48_RR_CAUSE_NORMAL;
|
|
|
|
case RSL_ERR_MAND_IE_ERROR:
|
|
|
|
return GSM48_RR_CAUSE_INVALID_MAND_INF;
|
|
|
|
case RSL_ERR_OPT_IE_ERROR:
|
|
|
|
return GSM48_RR_CAUSE_COND_IE_ERROR;
|
|
|
|
case RSL_ERR_INVALID_MESSAGE:
|
|
|
|
case RSL_ERR_MSG_DISCR:
|
|
|
|
case RSL_ERR_MSG_TYPE:
|
|
|
|
case RSL_ERR_MSG_SEQ:
|
|
|
|
case RSL_ERR_IE_ERROR:
|
|
|
|
case RSL_ERR_IE_NONEXIST:
|
|
|
|
case RSL_ERR_IE_LENGTH:
|
|
|
|
case RSL_ERR_IE_CONTENT:
|
|
|
|
case RSL_ERR_PROTO:
|
|
|
|
return GSM48_RR_CAUSE_PROT_ERROR_UNSPC;
|
|
|
|
default:
|
|
|
|
return GSM48_RR_CAUSE_ABNORMAL_UNSPEC;
|
|
|
|
}
|
|
|
|
}
|
2020-12-16 22:20:34 +00:00
|
|
|
|
2021-06-03 20:27:51 +00:00
|
|
|
/* Default Interference Measurement Parameters */
|
|
|
|
const struct gsm_interf_meas_params interf_meas_params_def = {
|
|
|
|
.avg_period = 6, /* 6 SACCH periods */
|
|
|
|
.bounds_dbm = {
|
|
|
|
85, /* 0: -85 dBm */
|
|
|
|
91, /* X1: -91 dBm */
|
|
|
|
97, /* X2: -97 dBm */
|
|
|
|
103, /* X3: -103 dBm */
|
|
|
|
109, /* X4: -109 dBm */
|
|
|
|
115, /* X5: -115 dBm */
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2020-12-16 22:20:34 +00:00
|
|
|
/* Default MS/BS Power Control parameters (see 3GPP TS 45.008, table A.1) */
|
|
|
|
const struct gsm_power_ctrl_params power_ctrl_params_def = {
|
|
|
|
/* Static Power Control is the safe default */
|
|
|
|
.mode = GSM_PWR_CTRL_MODE_STATIC,
|
|
|
|
|
2020-12-20 22:23:21 +00:00
|
|
|
/* BS Power reduction value / maximum (in dB) */
|
|
|
|
.bs_power_val_db = 0, /* no attenuation in static mode */
|
|
|
|
.bs_power_max_db = 12, /* up to 12 dB in dynamic mode */
|
|
|
|
|
2020-12-16 22:20:34 +00:00
|
|
|
/* Power increasing/reducing step size */
|
|
|
|
.inc_step_size_db = 4, /* 2, 4, or 6 dB */
|
|
|
|
.red_step_size_db = 2, /* 2 or 4 dB */
|
|
|
|
|
|
|
|
/* RxLev measurement parameters */
|
|
|
|
.rxlev_meas = {
|
|
|
|
/* Thresholds for RxLev (see 3GPP TS 45.008, A.3.2.1) */
|
|
|
|
.lower_thresh = 32, /* L_RXLEV_XX_P (-78 dBm) */
|
|
|
|
.upper_thresh = 38, /* U_RXLEV_XX_P (-72 dBm) */
|
|
|
|
|
|
|
|
/* Increase {UL,DL}_TXPWR if at least LOWER_CMP_P averages
|
|
|
|
* out of LOWER_CMP_N averages are lower than L_RXLEV_XX_P */
|
|
|
|
.lower_cmp_p = 10, /* P1 as in 3GPP TS 45.008, A.3.2.1 (case a) */
|
|
|
|
.lower_cmp_n = 12, /* N1 as in 3GPP TS 45.008, A.3.2.1 (case a) */
|
|
|
|
/* Decrease {UL,DL}_TXPWR if at least UPPER_CMP_P averages
|
|
|
|
* out of UPPER_CMP_N averages are greater than L_RXLEV_XX_P */
|
|
|
|
.upper_cmp_p = 19, /* P2 as in 3GPP TS 45.008, A.3.2.1 (case b) */
|
|
|
|
.upper_cmp_n = 20, /* N2 as in 3GPP TS 45.008, A.3.2.1 (case b) */
|
|
|
|
|
|
|
|
/* No averaging (filtering) by default */
|
|
|
|
.algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE,
|
|
|
|
|
|
|
|
/* Hreqave: the period over which an average is produced */
|
|
|
|
.h_reqave = 4, /* TODO: investigate a reasonable default value */
|
|
|
|
/* Hreqt: the number of averaged results maintained */
|
|
|
|
.h_reqt = 6, /* TODO: investigate a reasonable default value */
|
|
|
|
},
|
|
|
|
|
|
|
|
/* RxQual measurement parameters */
|
|
|
|
.rxqual_meas = {
|
|
|
|
/* Thresholds for RxQual (see 3GPP TS 45.008, A.3.2.1) */
|
2020-12-23 23:54:41 +00:00
|
|
|
.lower_thresh = 3, /* L_RXQUAL_XX_P (0.8% <= BER < 1.6%) */
|
|
|
|
.upper_thresh = 0, /* U_RXQUAL_XX_P (BER < 0.2%) */
|
2020-12-16 22:20:34 +00:00
|
|
|
|
|
|
|
/* Increase {UL,DL}_TXPWR if at least LOWER_CMP_P averages
|
|
|
|
* out of LOWER_CMP_N averages are lower than L_RXLEV_XX_P */
|
|
|
|
.lower_cmp_p = 5, /* P3 as in 3GPP TS 45.008, A.3.2.1 (case c) */
|
|
|
|
.lower_cmp_n = 7, /* N3 as in 3GPP TS 45.008, A.3.2.1 (case c) */
|
|
|
|
/* Decrease {UL,DL}_TXPWR if at least UPPER_CMP_P averages
|
|
|
|
* out of UPPER_CMP_N averages are greater than L_RXLEV_XX_P */
|
|
|
|
.upper_cmp_p = 15, /* P4 as in 3GPP TS 45.008, A.3.2.1 (case d) */
|
|
|
|
.upper_cmp_n = 18, /* N4 as in 3GPP TS 45.008, A.3.2.1 (case d) */
|
|
|
|
|
|
|
|
/* No averaging (filtering) by default */
|
|
|
|
.algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE,
|
|
|
|
|
|
|
|
/* Hreqave: the period over which an average is produced */
|
|
|
|
.h_reqave = 4, /* TODO: investigate a reasonable default value */
|
|
|
|
/* Hreqt: the number of averaged results maintained */
|
|
|
|
.h_reqt = 6, /* TODO: investigate a reasonable default value */
|
|
|
|
},
|
|
|
|
};
|
2021-04-29 12:47:19 +00:00
|
|
|
|
|
|
|
enum rsl_cmod_spd chan_mode_to_rsl_cmod_spd(enum gsm48_chan_mode chan_mode)
|
|
|
|
{
|
2021-05-28 17:18:11 +00:00
|
|
|
switch (gsm48_chan_mode_to_non_vamos(chan_mode)) {
|
2021-04-29 12:47:19 +00:00
|
|
|
case GSM48_CMODE_SIGN:
|
|
|
|
return RSL_CMOD_SPD_SIGN;
|
|
|
|
case GSM48_CMODE_SPEECH_V1:
|
|
|
|
case GSM48_CMODE_SPEECH_EFR:
|
|
|
|
case GSM48_CMODE_SPEECH_AMR:
|
|
|
|
return RSL_CMOD_SPD_SPEECH;
|
|
|
|
case GSM48_CMODE_DATA_14k5:
|
|
|
|
case GSM48_CMODE_DATA_12k0:
|
|
|
|
case GSM48_CMODE_DATA_6k0:
|
|
|
|
case GSM48_CMODE_DATA_3k6:
|
|
|
|
return RSL_CMOD_SPD_DATA;
|
|
|
|
default:
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
}
|