2009-08-01 05:26:59 +00:00
|
|
|
/* GSM Mobile Radio Interface Layer 3 messages on the A-bis interface
|
|
|
|
* 3GPP TS 04.08 version 7.21.0 Release 1998 / ETSI TS 100 940 V7.21.0
|
|
|
|
* utility functions
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* (C) 2008-2009 by Harald Welte <laforge@gnumonks.org>
|
|
|
|
* (C) 2008, 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
|
|
|
|
*
|
|
|
|
* 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
|
2009-08-01 05:26:59 +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.
|
2009-08-01 05:26:59 +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/>.
|
2009-08-01 05:26:59 +00:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
2009-08-21 02:57:35 +00:00
|
|
|
#include <errno.h>
|
2009-08-01 05:26:59 +00:00
|
|
|
#include <netinet/in.h>
|
|
|
|
|
2011-03-22 15:47:59 +00:00
|
|
|
#include <osmocom/core/msgb.h>
|
2019-02-03 11:11:12 +00:00
|
|
|
#include <osmocom/core/bitvec.h>
|
2011-03-22 15:47:59 +00:00
|
|
|
#include <osmocom/gsm/gsm48.h>
|
2019-02-03 11:11:12 +00:00
|
|
|
#include <osmocom/gsm/sysinfo.h>
|
2010-12-22 11:32:56 +00:00
|
|
|
|
2017-09-04 13:15:32 +00:00
|
|
|
#include <osmocom/bsc/abis_rsl.h>
|
|
|
|
#include <osmocom/bsc/debug.h>
|
|
|
|
#include <osmocom/bsc/paging.h>
|
|
|
|
#include <osmocom/bsc/signal.h>
|
2018-06-16 15:20:13 +00:00
|
|
|
#include <osmocom/bsc/bsc_subscr_conn_fsm.h>
|
2018-07-24 14:18:15 +00:00
|
|
|
#include <osmocom/bsc/gsm_04_08_rr.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/lchan_fsm.h>
|
|
|
|
#include <osmocom/bsc/assignment_fsm.h>
|
|
|
|
#include <osmocom/bsc/handover_fsm.h>
|
2018-07-24 16:10:05 +00:00
|
|
|
#include <osmocom/bsc/gsm_08_08.h>
|
2019-02-03 11:11:12 +00:00
|
|
|
#include <osmocom/bsc/gsm_data.h>
|
2020-07-16 15:02:54 +00:00
|
|
|
#include <osmocom/bsc/bsc_msc_data.h>
|
gsm_04_08_rr: fix hopping parameters in RR Assignment Command
According to 3GPP TS 44.018, section 9.1.2.4, if at least one of
the Channel Description IEs indicates frequency hopping, one and
only one of the following IEs shall be present:
- Mobile Allocation, after time (see 10.5.2.21);
- Frequency List, after time (see 10.5.2.13).
For some reason, osmo-bsc includes the GSM48_IE_MA_BEFORE instead
of GSM48_IE_MA_AFTER - fix this.
According to section 9.1.2.6 of the same document, if any of the
Mobile Allocation IEs (before/after time) is present, then the
network must ensure that either the MS has already received the
the proper reference cell frequency list (CA), or that the Cell
Channel Description IE (see 10.5.2.1b) is present.
Without this IE, the phone I was using in my testing setup sends
RR Status message with cause #100 "conditional IE error".
Fortunately, we already have generate_cell_chan_list(), since we
also need to include the Cell Channel Description in SI Type 1.
Change-Id: I43ef66c109b107ebcaa1cb6197637701b13b3787
Related: SYS#4868, OS#4545, OS#4546
2020-06-30 10:40:20 +00:00
|
|
|
#include <osmocom/bsc/system_information.h>
|
2020-07-15 18:53:16 +00:00
|
|
|
#include <osmocom/bsc/bts.h>
|
2019-02-03 11:11:12 +00:00
|
|
|
|
2009-08-01 05:26:59 +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
|
|
|
int gsm48_sendmsg(struct msgb *msg)
|
2009-08-01 05:26:59 +00:00
|
|
|
{
|
2010-06-15 05:57:40 +00:00
|
|
|
if (msg->lchan)
|
2021-04-12 12:43:10 +00:00
|
|
|
msg->dst = rsl_chan_link(msg->lchan);
|
2009-08-01 05:26:59 +00:00
|
|
|
|
|
|
|
msg->l3h = msg->data;
|
|
|
|
return rsl_data_request(msg, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Section 9.1.8 / Table 9.9 */
|
|
|
|
struct chreq {
|
2011-04-18 15:04:00 +00:00
|
|
|
uint8_t val;
|
|
|
|
uint8_t mask;
|
2009-08-01 05:26:59 +00:00
|
|
|
enum chreq_type type;
|
|
|
|
};
|
|
|
|
|
|
|
|
/* If SYSTEM INFORMATION TYPE 4 NECI bit == 1 */
|
|
|
|
static const struct chreq chreq_type_neci1[] = {
|
|
|
|
{ 0xa0, 0xe0, CHREQ_T_EMERG_CALL },
|
|
|
|
{ 0xc0, 0xe0, CHREQ_T_CALL_REEST_TCH_F },
|
|
|
|
{ 0x68, 0xfc, CHREQ_T_CALL_REEST_TCH_H },
|
|
|
|
{ 0x6c, 0xfc, CHREQ_T_CALL_REEST_TCH_H_DBL },
|
2010-12-26 23:59:23 +00:00
|
|
|
{ 0xe0, 0xe0, CHREQ_T_TCH_F },
|
2009-08-01 05:26:59 +00:00
|
|
|
{ 0x40, 0xf0, CHREQ_T_VOICE_CALL_TCH_H },
|
|
|
|
{ 0x50, 0xf0, CHREQ_T_DATA_CALL_TCH_H },
|
|
|
|
{ 0x00, 0xf0, CHREQ_T_LOCATION_UPD },
|
|
|
|
{ 0x10, 0xf0, CHREQ_T_SDCCH },
|
2009-11-17 15:46:46 +00:00
|
|
|
{ 0x80, 0xe0, CHREQ_T_PAG_R_ANY_NECI1 },
|
2009-08-01 05:26:59 +00:00
|
|
|
{ 0x20, 0xf0, CHREQ_T_PAG_R_TCH_F },
|
|
|
|
{ 0x30, 0xf0, CHREQ_T_PAG_R_TCH_FH },
|
2009-11-21 19:20:43 +00:00
|
|
|
{ 0x67, 0xff, CHREQ_T_LMU },
|
|
|
|
{ 0x60, 0xf9, CHREQ_T_RESERVED_SDCCH },
|
|
|
|
{ 0x61, 0xfb, CHREQ_T_RESERVED_SDCCH },
|
2016-11-28 22:26:50 +00:00
|
|
|
{ 0x63, 0xff, CHREQ_T_RESERVED_SDCCH },
|
|
|
|
{ 0x70, 0xf8, CHREQ_T_PDCH_TWO_PHASE },
|
|
|
|
{ 0x78, 0xfc, CHREQ_T_PDCH_ONE_PHASE },
|
|
|
|
{ 0x78, 0xfa, CHREQ_T_PDCH_ONE_PHASE },
|
|
|
|
{ 0x78, 0xf9, CHREQ_T_PDCH_ONE_PHASE },
|
2009-11-21 19:20:43 +00:00
|
|
|
{ 0x7f, 0xff, CHREQ_T_RESERVED_IGNORE },
|
2009-08-01 05:26:59 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/* If SYSTEM INFORMATION TYPE 4 NECI bit == 0 */
|
|
|
|
static const struct chreq chreq_type_neci0[] = {
|
|
|
|
{ 0xa0, 0xe0, CHREQ_T_EMERG_CALL },
|
|
|
|
{ 0xc0, 0xe0, CHREQ_T_CALL_REEST_TCH_H },
|
|
|
|
{ 0xe0, 0xe0, CHREQ_T_TCH_F },
|
|
|
|
{ 0x50, 0xf0, CHREQ_T_DATA_CALL_TCH_H },
|
|
|
|
{ 0x00, 0xe0, CHREQ_T_LOCATION_UPD },
|
2009-11-17 15:46:46 +00:00
|
|
|
{ 0x80, 0xe0, CHREQ_T_PAG_R_ANY_NECI0 },
|
2009-08-01 05:26:59 +00:00
|
|
|
{ 0x20, 0xf0, CHREQ_T_PAG_R_TCH_F },
|
|
|
|
{ 0x30, 0xf0, CHREQ_T_PAG_R_TCH_FH },
|
2009-11-21 19:20:43 +00:00
|
|
|
{ 0x67, 0xff, CHREQ_T_LMU },
|
|
|
|
{ 0x60, 0xf9, CHREQ_T_RESERVED_SDCCH },
|
|
|
|
{ 0x61, 0xfb, CHREQ_T_RESERVED_SDCCH },
|
2016-11-28 22:26:50 +00:00
|
|
|
{ 0x63, 0xff, CHREQ_T_RESERVED_SDCCH },
|
|
|
|
{ 0x70, 0xf8, CHREQ_T_PDCH_TWO_PHASE },
|
|
|
|
{ 0x78, 0xfc, CHREQ_T_PDCH_ONE_PHASE },
|
|
|
|
{ 0x78, 0xfa, CHREQ_T_PDCH_ONE_PHASE },
|
|
|
|
{ 0x78, 0xf9, CHREQ_T_PDCH_ONE_PHASE },
|
2009-11-21 19:20:43 +00:00
|
|
|
{ 0x7f, 0xff, CHREQ_T_RESERVED_IGNORE },
|
2009-08-01 05:26:59 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static const enum gsm_chan_t ctype_by_chreq[] = {
|
|
|
|
[CHREQ_T_EMERG_CALL] = GSM_LCHAN_TCH_F,
|
|
|
|
[CHREQ_T_CALL_REEST_TCH_F] = GSM_LCHAN_TCH_F,
|
|
|
|
[CHREQ_T_CALL_REEST_TCH_H] = GSM_LCHAN_TCH_H,
|
|
|
|
[CHREQ_T_CALL_REEST_TCH_H_DBL] = GSM_LCHAN_TCH_H,
|
|
|
|
[CHREQ_T_SDCCH] = GSM_LCHAN_SDCCH,
|
|
|
|
[CHREQ_T_TCH_F] = GSM_LCHAN_TCH_F,
|
|
|
|
[CHREQ_T_VOICE_CALL_TCH_H] = GSM_LCHAN_TCH_H,
|
|
|
|
[CHREQ_T_DATA_CALL_TCH_H] = GSM_LCHAN_TCH_H,
|
|
|
|
[CHREQ_T_LOCATION_UPD] = GSM_LCHAN_SDCCH,
|
2009-11-17 15:46:46 +00:00
|
|
|
[CHREQ_T_PAG_R_ANY_NECI1] = GSM_LCHAN_SDCCH,
|
|
|
|
[CHREQ_T_PAG_R_ANY_NECI0] = GSM_LCHAN_SDCCH,
|
2009-08-01 05:26:59 +00:00
|
|
|
[CHREQ_T_PAG_R_TCH_F] = GSM_LCHAN_TCH_F,
|
2013-03-31 09:44:34 +00:00
|
|
|
[CHREQ_T_PAG_R_TCH_FH] = GSM_LCHAN_TCH_H,
|
2009-11-21 19:20:43 +00:00
|
|
|
[CHREQ_T_LMU] = GSM_LCHAN_SDCCH,
|
|
|
|
[CHREQ_T_RESERVED_SDCCH] = GSM_LCHAN_SDCCH,
|
2016-11-28 22:26:50 +00:00
|
|
|
[CHREQ_T_PDCH_ONE_PHASE] = GSM_LCHAN_PDTCH,
|
|
|
|
[CHREQ_T_PDCH_TWO_PHASE] = GSM_LCHAN_PDTCH,
|
2009-11-21 19:20:43 +00:00
|
|
|
[CHREQ_T_RESERVED_IGNORE] = GSM_LCHAN_UNKNOWN,
|
2009-08-01 05:26:59 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static const enum gsm_chreq_reason_t reason_by_chreq[] = {
|
|
|
|
[CHREQ_T_EMERG_CALL] = GSM_CHREQ_REASON_EMERG,
|
|
|
|
[CHREQ_T_CALL_REEST_TCH_F] = GSM_CHREQ_REASON_CALL,
|
|
|
|
[CHREQ_T_CALL_REEST_TCH_H] = GSM_CHREQ_REASON_CALL,
|
|
|
|
[CHREQ_T_CALL_REEST_TCH_H_DBL] = GSM_CHREQ_REASON_CALL,
|
|
|
|
[CHREQ_T_SDCCH] = GSM_CHREQ_REASON_OTHER,
|
|
|
|
[CHREQ_T_TCH_F] = GSM_CHREQ_REASON_OTHER,
|
2009-12-12 19:57:52 +00:00
|
|
|
[CHREQ_T_VOICE_CALL_TCH_H] = GSM_CHREQ_REASON_CALL,
|
2009-08-01 05:26:59 +00:00
|
|
|
[CHREQ_T_DATA_CALL_TCH_H] = GSM_CHREQ_REASON_OTHER,
|
|
|
|
[CHREQ_T_LOCATION_UPD] = GSM_CHREQ_REASON_LOCATION_UPD,
|
2009-11-17 15:46:46 +00:00
|
|
|
[CHREQ_T_PAG_R_ANY_NECI1] = GSM_CHREQ_REASON_PAG,
|
|
|
|
[CHREQ_T_PAG_R_ANY_NECI0] = GSM_CHREQ_REASON_PAG,
|
2009-08-01 05:26:59 +00:00
|
|
|
[CHREQ_T_PAG_R_TCH_F] = GSM_CHREQ_REASON_PAG,
|
|
|
|
[CHREQ_T_PAG_R_TCH_FH] = GSM_CHREQ_REASON_PAG,
|
2009-11-21 19:20:43 +00:00
|
|
|
[CHREQ_T_LMU] = GSM_CHREQ_REASON_OTHER,
|
2016-11-28 22:26:50 +00:00
|
|
|
[CHREQ_T_PDCH_ONE_PHASE] = GSM_CHREQ_REASON_PDCH,
|
|
|
|
[CHREQ_T_PDCH_TWO_PHASE] = GSM_CHREQ_REASON_PDCH,
|
2009-11-21 19:20:43 +00:00
|
|
|
[CHREQ_T_RESERVED_SDCCH] = GSM_CHREQ_REASON_OTHER,
|
|
|
|
[CHREQ_T_RESERVED_IGNORE] = GSM_CHREQ_REASON_OTHER,
|
2009-08-01 05:26:59 +00:00
|
|
|
};
|
|
|
|
|
2010-09-06 01:36:02 +00:00
|
|
|
/* verify that the two tables match */
|
2011-05-07 10:12:48 +00:00
|
|
|
osmo_static_assert(sizeof(ctype_by_chreq) ==
|
2010-09-06 01:36:02 +00:00
|
|
|
sizeof(((struct gsm_network *) NULL)->ctype_by_chreq), assert_size);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Update channel types for request based on policy. E.g. in the
|
|
|
|
* case of a TCH/H network/bsc use TCH/H for the emergency calls,
|
|
|
|
* for early assignment assign a SDCCH and some other options.
|
|
|
|
*/
|
|
|
|
void gsm_net_update_ctype(struct gsm_network *network)
|
|
|
|
{
|
|
|
|
/* copy over the data */
|
|
|
|
memcpy(network->ctype_by_chreq, ctype_by_chreq, sizeof(ctype_by_chreq));
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Use TCH/H for emergency calls when this cell allows TCH/H. Maybe it
|
|
|
|
* is better to iterate over the BTS/TRX and check if no TCH/F is available
|
|
|
|
* and then set it to TCH/H.
|
|
|
|
*/
|
|
|
|
if (network->neci)
|
|
|
|
network->ctype_by_chreq[CHREQ_T_EMERG_CALL] = GSM_LCHAN_TCH_H;
|
2010-09-06 01:41:50 +00:00
|
|
|
|
|
|
|
if (network->pag_any_tch) {
|
|
|
|
if (network->neci) {
|
|
|
|
network->ctype_by_chreq[CHREQ_T_PAG_R_ANY_NECI0] = GSM_LCHAN_TCH_H;
|
|
|
|
network->ctype_by_chreq[CHREQ_T_PAG_R_ANY_NECI1] = GSM_LCHAN_TCH_H;
|
|
|
|
} else {
|
|
|
|
network->ctype_by_chreq[CHREQ_T_PAG_R_ANY_NECI0] = GSM_LCHAN_TCH_F;
|
|
|
|
network->ctype_by_chreq[CHREQ_T_PAG_R_ANY_NECI1] = GSM_LCHAN_TCH_F;
|
|
|
|
}
|
|
|
|
}
|
2010-09-06 01:36:02 +00:00
|
|
|
}
|
|
|
|
|
2011-04-18 15:04:00 +00:00
|
|
|
enum gsm_chan_t get_ctype_by_chreq(struct gsm_network *network, uint8_t ra)
|
2009-08-01 05:26:59 +00:00
|
|
|
{
|
|
|
|
int i;
|
2009-11-17 15:38:25 +00:00
|
|
|
int length;
|
|
|
|
const struct chreq *chreq;
|
|
|
|
|
2010-09-06 01:36:02 +00:00
|
|
|
if (network->neci) {
|
2009-11-17 15:38:25 +00:00
|
|
|
chreq = chreq_type_neci1;
|
|
|
|
length = ARRAY_SIZE(chreq_type_neci1);
|
|
|
|
} else {
|
|
|
|
chreq = chreq_type_neci0;
|
|
|
|
length = ARRAY_SIZE(chreq_type_neci0);
|
|
|
|
}
|
|
|
|
|
2009-08-01 05:26:59 +00:00
|
|
|
|
2009-11-17 15:38:25 +00:00
|
|
|
for (i = 0; i < length; i++) {
|
|
|
|
const struct chreq *chr = &chreq[i];
|
2009-08-01 05:26:59 +00:00
|
|
|
if ((ra & chr->mask) == chr->val)
|
2010-09-06 01:36:02 +00:00
|
|
|
return network->ctype_by_chreq[chr->type];
|
2009-08-01 05:26:59 +00:00
|
|
|
}
|
2009-12-24 10:50:20 +00:00
|
|
|
LOGP(DRR, LOGL_ERROR, "Unknown CHANNEL REQUEST RQD 0x%02x\n", ra);
|
2009-08-01 05:26:59 +00:00
|
|
|
return GSM_LCHAN_SDCCH;
|
|
|
|
}
|
|
|
|
|
2011-07-23 08:53:30 +00:00
|
|
|
int get_reason_by_chreq(uint8_t ra, int neci)
|
2009-08-01 05:26:59 +00:00
|
|
|
{
|
|
|
|
int i;
|
2009-11-17 15:38:25 +00:00
|
|
|
int length;
|
|
|
|
const struct chreq *chreq;
|
|
|
|
|
|
|
|
if (neci) {
|
|
|
|
chreq = chreq_type_neci1;
|
|
|
|
length = ARRAY_SIZE(chreq_type_neci1);
|
|
|
|
} else {
|
|
|
|
chreq = chreq_type_neci0;
|
|
|
|
length = ARRAY_SIZE(chreq_type_neci0);
|
|
|
|
}
|
2009-08-01 05:26:59 +00:00
|
|
|
|
2009-11-17 15:38:25 +00:00
|
|
|
for (i = 0; i < length; i++) {
|
|
|
|
const struct chreq *chr = &chreq[i];
|
2009-08-01 05:26:59 +00:00
|
|
|
if ((ra & chr->mask) == chr->val)
|
|
|
|
return reason_by_chreq[chr->type];
|
|
|
|
}
|
2009-12-24 10:50:20 +00:00
|
|
|
LOGP(DRR, LOGL_ERROR, "Unknown CHANNEL REQUEST REASON 0x%02x\n", ra);
|
2009-08-01 05:26:59 +00:00
|
|
|
return GSM_CHREQ_REASON_OTHER;
|
|
|
|
}
|
|
|
|
|
AMR config cleanup step 3: generate AMR LV on msg composition
Firstly, do not store the encoded AMR length-value bits in gsm_lchan->*
before an activation/modify has actually succeeded.
And secondly, do not store the AMR LV structure in struct gsm_lchan at
all, but only generate the TLV exactly when a message is being composed.
In gsm48_multirate_config(), generate the LV directly to a msgb instead
of a static buffer first. gsm0408_test.c expected output verifies that
the generated LV bytes remain unchanged.
In lchan_mr_config(), introduce a target mr_conf argument, so that Chan
Act and Mode Modify may generate the filtered AMR config to different
locations (lchan->{activate,modify}.mr_conf_filtered).
Only after receiving an ACK for Activate/Modify, set
lchan->current_mr_conf from lchan->{activate,modify}.mr_conf_filtered.
Use the properly scoped lchan->activate.mr_conf_filtered for Chan Act,
lchan->modify.mr_conf_filtered for Mode Modify and
new_lchan->current_mr_conf for Handover Command as appropriate.
Related: SYS#5315 OS#4940 OS#3787 OS#3833
Change-Id: Ie57f9d0e3912632903d9740291225bfd1634ed47
2021-04-29 17:58:52 +00:00
|
|
|
static int put_mr_config_for_ms(struct msgb *msg, const struct gsm48_multi_rate_conf *mr_conf_filtered,
|
|
|
|
const struct amr_multirate_conf *mr_modes)
|
2015-08-20 17:32:46 +00:00
|
|
|
{
|
AMR config cleanup step 3: generate AMR LV on msg composition
Firstly, do not store the encoded AMR length-value bits in gsm_lchan->*
before an activation/modify has actually succeeded.
And secondly, do not store the AMR LV structure in struct gsm_lchan at
all, but only generate the TLV exactly when a message is being composed.
In gsm48_multirate_config(), generate the LV directly to a msgb instead
of a static buffer first. gsm0408_test.c expected output verifies that
the generated LV bytes remain unchanged.
In lchan_mr_config(), introduce a target mr_conf argument, so that Chan
Act and Mode Modify may generate the filtered AMR config to different
locations (lchan->{activate,modify}.mr_conf_filtered).
Only after receiving an ACK for Activate/Modify, set
lchan->current_mr_conf from lchan->{activate,modify}.mr_conf_filtered.
Use the properly scoped lchan->activate.mr_conf_filtered for Chan Act,
lchan->modify.mr_conf_filtered for Mode Modify and
new_lchan->current_mr_conf for Handover Command as appropriate.
Related: SYS#5315 OS#4940 OS#3787 OS#3833
Change-Id: Ie57f9d0e3912632903d9740291225bfd1634ed47
2021-04-29 17:58:52 +00:00
|
|
|
msgb_put_u8(msg, GSM48_IE_MUL_RATE_CFG);
|
|
|
|
return gsm48_multirate_config(msg, mr_conf_filtered, mr_modes->ms_mode, mr_modes->num_modes);
|
2015-08-20 17:32:46 +00:00
|
|
|
}
|
|
|
|
|
2020-09-15 09:41:47 +00:00
|
|
|
#define CELL_SEL_IND_AFTER_REL_EARCFN_ENTRY (1+16+4+1+1)
|
|
|
|
#define CELL_SEL_IND_AFTER_REL_MAX_BITS (3+MAX_EARFCN_LIST*CELL_SEL_IND_AFTER_REL_EARCFN_ENTRY+1)
|
2020-07-10 08:41:59 +00:00
|
|
|
#define CELL_SEL_IND_AFTER_REL_MAX_BYTES OSMO_BYTES_FOR_BITS(CELL_SEL_IND_AFTER_REL_MAX_BITS)
|
2019-02-03 11:11:12 +00:00
|
|
|
|
|
|
|
/* Generate a CSN.1 encoded "Cell Selection Indicator after release of all TCH and SDCCH"
|
2021-04-14 15:48:19 +00:00
|
|
|
* as per TS 44.018 version 15.3.0 Table 10.5.2.1e.1. This only generates the "value"
|
2019-02-03 11:11:12 +00:00
|
|
|
* part of the IE, not the tag+length wrapper */
|
|
|
|
static int generate_cell_sel_ind_after_rel(uint8_t *out, unsigned int out_len, const struct gsm_bts *bts)
|
|
|
|
{
|
|
|
|
struct bitvec bv;
|
|
|
|
unsigned int i, rc;
|
|
|
|
|
|
|
|
bv.data = out;
|
|
|
|
bv.data_len = out_len;
|
|
|
|
bitvec_zero(&bv);
|
|
|
|
|
|
|
|
/* E-UTRAN Description */
|
|
|
|
bitvec_set_uint(&bv, 3, 3);
|
|
|
|
|
|
|
|
for (i = 0; i < MAX_EARFCN_LIST; i++) {
|
|
|
|
const struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list;
|
|
|
|
if (e->arfcn[i] == OSMO_EARFCN_INVALID)
|
|
|
|
continue;
|
|
|
|
|
2020-09-15 09:41:47 +00:00
|
|
|
/* tailroom must fit one more EARFCN plus the final list term bit. */
|
|
|
|
if (bitvec_tailroom_bits(&bv) < CELL_SEL_IND_AFTER_REL_EARCFN_ENTRY + 1) {
|
2019-02-03 11:11:12 +00:00
|
|
|
LOGP(DRR, LOGL_NOTICE, "%s: Not enough room to store EARFCN %u in the "
|
|
|
|
"Cell Selection Indicator IE\n", gsm_bts_name(bts), e->arfcn[i]);
|
|
|
|
} else {
|
2020-07-10 08:41:59 +00:00
|
|
|
bitvec_set_bit(&bv, 1);
|
2019-02-03 11:11:12 +00:00
|
|
|
bitvec_set_uint(&bv, e->arfcn[i], 16);
|
2020-09-09 01:23:30 +00:00
|
|
|
|
|
|
|
/* Measurement Bandwidth: 9.1.54 */
|
|
|
|
if (OSMO_EARFCN_MEAS_INVALID == e->meas_bw[i])
|
|
|
|
bitvec_set_bit(&bv, 0);
|
|
|
|
else {
|
|
|
|
bitvec_set_bit(&bv, 1);
|
|
|
|
bitvec_set_uint(&bv, e->meas_bw[i], 3);
|
|
|
|
}
|
2019-02-03 11:11:12 +00:00
|
|
|
/* No "Not Allowed Cells" */
|
|
|
|
bitvec_set_bit(&bv, 0);
|
|
|
|
/* No "TARGET_PCID" */
|
|
|
|
bitvec_set_bit(&bv, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-10 08:41:59 +00:00
|
|
|
/* list term */
|
|
|
|
bitvec_set_bit(&bv, 0);
|
|
|
|
|
2019-02-03 11:11:12 +00:00
|
|
|
rc = bitvec_used_bytes(&bv);
|
|
|
|
|
|
|
|
if (rc == 1) {
|
|
|
|
/* only the header was written to the bitvec, no actual EARFCNs were present */
|
|
|
|
return 0;
|
|
|
|
} else {
|
|
|
|
/* return the number of bytes used */
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-08-01 05:26:59 +00:00
|
|
|
/* 7.1.7 and 9.1.7: RR CHANnel RELease */
|
|
|
|
int gsm48_send_rr_release(struct gsm_lchan *lchan)
|
|
|
|
{
|
2016-01-25 21:03:25 +00:00
|
|
|
struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 RR REL");
|
2009-08-01 05:26:59 +00:00
|
|
|
struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
|
2011-04-18 15:04:00 +00:00
|
|
|
uint8_t *cause;
|
2009-08-01 05:26:59 +00:00
|
|
|
|
|
|
|
msg->lchan = lchan;
|
|
|
|
gh->proto_discr = GSM48_PDISC_RR;
|
|
|
|
gh->msg_type = GSM48_MT_RR_CHAN_REL;
|
|
|
|
|
|
|
|
cause = msgb_put(msg, 1);
|
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
|
|
|
cause[0] = lchan->release.rr_cause;
|
2009-08-01 05:26:59 +00:00
|
|
|
|
2021-04-12 18:19:30 +00:00
|
|
|
if (lchan->release.last_eutran_plmn_valid) {
|
2019-02-03 11:11:12 +00:00
|
|
|
uint8_t buf[CELL_SEL_IND_AFTER_REL_MAX_BYTES];
|
|
|
|
int len;
|
2021-04-12 18:19:30 +00:00
|
|
|
/* FIXME: so far we assume all configured neigbhors match last_eutran_plmn */
|
2019-02-03 11:11:12 +00:00
|
|
|
len = generate_cell_sel_ind_after_rel(buf, sizeof(buf), lchan->ts->trx->bts);
|
|
|
|
if (len == 0) {
|
|
|
|
LOGPLCHAN(lchan, DRR, LOGL_NOTICE, "MSC indicated CSFB Fast Return, but "
|
|
|
|
"BTS has no EARFCN configured!\n");
|
|
|
|
} else
|
|
|
|
msgb_tlv_put(msg, GSM48_IE_CELL_SEL_IND_AFTER_REL, len, buf);
|
|
|
|
}
|
|
|
|
|
2020-08-13 12:53:49 +00:00
|
|
|
DEBUGP(DRR, "Sending Channel Release: Chan: Number: %d Type: %d RR-Cause: 0x%x '%s'\n",
|
|
|
|
lchan->nr, lchan->type, lchan->release.rr_cause, rr_cause_name(lchan->release.rr_cause));
|
2009-08-01 05:26:59 +00:00
|
|
|
|
|
|
|
/* Send actual release request to MS */
|
2011-12-28 15:21:05 +00:00
|
|
|
return gsm48_sendmsg(msg);
|
2009-08-01 05:26:59 +00:00
|
|
|
}
|
|
|
|
|
2009-08-21 02:57:35 +00:00
|
|
|
int send_siemens_mrpci(struct gsm_lchan *lchan,
|
2011-04-18 15:04:00 +00:00
|
|
|
uint8_t *classmark2_lv)
|
2009-08-21 02:57:35 +00:00
|
|
|
{
|
|
|
|
struct rsl_mrpci mrpci;
|
|
|
|
|
|
|
|
if (classmark2_lv[0] < 2)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
mrpci.power_class = classmark2_lv[1] & 0x7;
|
|
|
|
mrpci.vgcs_capable = classmark2_lv[2] & (1 << 1);
|
|
|
|
mrpci.vbs_capable = classmark2_lv[2] & (1 <<2);
|
|
|
|
mrpci.gsm_phase = (classmark2_lv[1]) >> 5 & 0x3;
|
|
|
|
|
|
|
|
return rsl_siemens_mrpci(lchan, &mrpci);
|
|
|
|
}
|
|
|
|
|
2018-09-13 03:19:32 +00:00
|
|
|
/* 3GPP 44.018 9.1.12 Classmark Enquiry */
|
|
|
|
int gsm48_send_rr_classmark_enquiry(struct gsm_lchan *lchan)
|
|
|
|
{
|
|
|
|
struct msgb *msg = gsm48_msgb_alloc_name("GSM 44.018 Classmark Enquiry");
|
|
|
|
struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
|
|
|
|
|
|
|
|
msg->lchan = lchan;
|
|
|
|
gh->proto_discr = GSM48_PDISC_RR;
|
|
|
|
gh->msg_type = GSM48_MT_RR_CLSM_ENQ;
|
|
|
|
|
|
|
|
DEBUGP(DRR, "%s TX CLASSMARK ENQUIRY %u\n", gsm_lchan_name(lchan), msgb_length(msg));
|
|
|
|
|
|
|
|
return gsm48_sendmsg(msg);
|
|
|
|
}
|
|
|
|
|
2009-10-05 11:25:06 +00:00
|
|
|
/* Chapter 9.1.9: Ciphering Mode Command */
|
2009-10-05 12:00:14 +00:00
|
|
|
int gsm48_send_rr_ciph_mode(struct gsm_lchan *lchan, int want_imeisv)
|
2009-10-05 11:25:06 +00:00
|
|
|
{
|
2016-01-25 21:03:25 +00:00
|
|
|
struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CIPH");
|
2009-10-05 11:25:06 +00:00
|
|
|
struct gsm48_hdr *gh;
|
2011-04-18 15:04:00 +00:00
|
|
|
uint8_t ciph_mod_set;
|
2009-10-05 11:25:06 +00:00
|
|
|
|
|
|
|
msg->lchan = lchan;
|
|
|
|
|
|
|
|
DEBUGP(DRR, "TX CIPHERING MODE CMD\n");
|
|
|
|
|
|
|
|
if (lchan->encr.alg_id <= RSL_ENC_ALG_A5(0))
|
|
|
|
ciph_mod_set = 0;
|
|
|
|
else
|
|
|
|
ciph_mod_set = (lchan->encr.alg_id-2)<<1 | 1;
|
|
|
|
|
|
|
|
gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 1);
|
|
|
|
gh->proto_discr = GSM48_PDISC_RR;
|
|
|
|
gh->msg_type = GSM48_MT_RR_CIPH_M_CMD;
|
2009-10-05 12:00:14 +00:00
|
|
|
gh->data[0] = (want_imeisv & 0x1) << 4 | (ciph_mod_set & 0xf);
|
2009-10-05 11:25:06 +00:00
|
|
|
|
|
|
|
return rsl_encryption_cmd(msg);
|
|
|
|
}
|
|
|
|
|
2009-11-29 19:02:53 +00:00
|
|
|
static void gsm48_cell_desc(struct gsm48_cell_desc *cd,
|
|
|
|
const struct gsm_bts *bts)
|
|
|
|
{
|
|
|
|
cd->ncc = (bts->bsic >> 3 & 0x7);
|
|
|
|
cd->bcc = (bts->bsic & 0x7);
|
|
|
|
cd->arfcn_hi = bts->c0->arfcn >> 8;
|
|
|
|
cd->arfcn_lo = bts->c0->arfcn & 0xff;
|
|
|
|
}
|
|
|
|
|
2018-10-22 12:21:57 +00:00
|
|
|
/*! \brief Encode a TS 04.08 multirate config LV according to 10.5.2.21aa.
|
AMR config cleanup step 3: generate AMR LV on msg composition
Firstly, do not store the encoded AMR length-value bits in gsm_lchan->*
before an activation/modify has actually succeeded.
And secondly, do not store the AMR LV structure in struct gsm_lchan at
all, but only generate the TLV exactly when a message is being composed.
In gsm48_multirate_config(), generate the LV directly to a msgb instead
of a static buffer first. gsm0408_test.c expected output verifies that
the generated LV bytes remain unchanged.
In lchan_mr_config(), introduce a target mr_conf argument, so that Chan
Act and Mode Modify may generate the filtered AMR config to different
locations (lchan->{activate,modify}.mr_conf_filtered).
Only after receiving an ACK for Activate/Modify, set
lchan->current_mr_conf from lchan->{activate,modify}.mr_conf_filtered.
Use the properly scoped lchan->activate.mr_conf_filtered for Chan Act,
lchan->modify.mr_conf_filtered for Mode Modify and
new_lchan->current_mr_conf for Handover Command as appropriate.
Related: SYS#5315 OS#4940 OS#3787 OS#3833
Change-Id: Ie57f9d0e3912632903d9740291225bfd1634ed47
2021-04-29 17:58:52 +00:00
|
|
|
* \param[out] msg msgb to append to.
|
2018-10-22 12:21:57 +00:00
|
|
|
* \param[in] mr_conf multi-rate configuration to encode (selected modes).
|
|
|
|
* \param[in] modes array describing the AMR modes.
|
|
|
|
* \param[in] num_modes length of the modes array.
|
|
|
|
* \returns 0 on success, -EINVAL on failure. */
|
AMR config cleanup step 3: generate AMR LV on msg composition
Firstly, do not store the encoded AMR length-value bits in gsm_lchan->*
before an activation/modify has actually succeeded.
And secondly, do not store the AMR LV structure in struct gsm_lchan at
all, but only generate the TLV exactly when a message is being composed.
In gsm48_multirate_config(), generate the LV directly to a msgb instead
of a static buffer first. gsm0408_test.c expected output verifies that
the generated LV bytes remain unchanged.
In lchan_mr_config(), introduce a target mr_conf argument, so that Chan
Act and Mode Modify may generate the filtered AMR config to different
locations (lchan->{activate,modify}.mr_conf_filtered).
Only after receiving an ACK for Activate/Modify, set
lchan->current_mr_conf from lchan->{activate,modify}.mr_conf_filtered.
Use the properly scoped lchan->activate.mr_conf_filtered for Chan Act,
lchan->modify.mr_conf_filtered for Mode Modify and
new_lchan->current_mr_conf for Handover Command as appropriate.
Related: SYS#5315 OS#4940 OS#3787 OS#3833
Change-Id: Ie57f9d0e3912632903d9740291225bfd1634ed47
2021-04-29 17:58:52 +00:00
|
|
|
int gsm48_multirate_config(struct msgb *msg,
|
2018-10-22 12:21:57 +00:00
|
|
|
const struct gsm48_multi_rate_conf *mr_conf,
|
|
|
|
const struct amr_mode *modes, unsigned int num_modes)
|
2014-01-19 10:47:44 +00:00
|
|
|
{
|
2018-10-22 12:21:57 +00:00
|
|
|
int num = 0;
|
|
|
|
unsigned int i;
|
|
|
|
unsigned int k;
|
|
|
|
unsigned int m = 0;
|
|
|
|
bool mode_valid;
|
|
|
|
uint8_t *gsm48_ie = (uint8_t *) mr_conf;
|
|
|
|
const struct amr_mode *modes_selected[4];
|
AMR config cleanup step 3: generate AMR LV on msg composition
Firstly, do not store the encoded AMR length-value bits in gsm_lchan->*
before an activation/modify has actually succeeded.
And secondly, do not store the AMR LV structure in struct gsm_lchan at
all, but only generate the TLV exactly when a message is being composed.
In gsm48_multirate_config(), generate the LV directly to a msgb instead
of a static buffer first. gsm0408_test.c expected output verifies that
the generated LV bytes remain unchanged.
In lchan_mr_config(), introduce a target mr_conf argument, so that Chan
Act and Mode Modify may generate the filtered AMR config to different
locations (lchan->{activate,modify}.mr_conf_filtered).
Only after receiving an ACK for Activate/Modify, set
lchan->current_mr_conf from lchan->{activate,modify}.mr_conf_filtered.
Use the properly scoped lchan->activate.mr_conf_filtered for Chan Act,
lchan->modify.mr_conf_filtered for Mode Modify and
new_lchan->current_mr_conf for Handover Command as appropriate.
Related: SYS#5315 OS#4940 OS#3787 OS#3833
Change-Id: Ie57f9d0e3912632903d9740291225bfd1634ed47
2021-04-29 17:58:52 +00:00
|
|
|
uint8_t *len;
|
|
|
|
uint8_t *data;
|
2018-10-22 12:21:57 +00:00
|
|
|
|
|
|
|
/* Check if modes for consistency (order and duplicates) */
|
|
|
|
for (i = 0; i < num_modes; i++) {
|
|
|
|
if (i > 0 && modes[i - 1].mode > modes[i].mode) {
|
|
|
|
LOGP(DRR, LOGL_ERROR,
|
2019-11-13 21:10:41 +00:00
|
|
|
"BUG: Multirate codec with inconsistent config (mode order).\n");
|
2018-10-22 12:21:57 +00:00
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
if (i > 0 && modes[i - 1].mode == modes[i].mode) {
|
|
|
|
LOGP(DRR, LOGL_ERROR,
|
2019-11-13 21:10:41 +00:00
|
|
|
"BUG: Multirate codec with inconsistent config (duplicate modes).\n");
|
2018-10-22 12:21:57 +00:00
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
}
|
2014-01-19 10:47:44 +00:00
|
|
|
|
2018-10-22 12:21:57 +00:00
|
|
|
/* Check if the active set that is defined in mr_conf has at least one
|
|
|
|
* mode but not more than 4 modes set */
|
2014-01-19 10:47:44 +00:00
|
|
|
for (i = 0; i < 8; i++) {
|
2018-10-22 12:21:57 +00:00
|
|
|
if (((gsm48_ie[1] >> i) & 1))
|
2014-01-19 10:47:44 +00:00
|
|
|
num++;
|
|
|
|
}
|
|
|
|
if (num > 4) {
|
2018-10-22 12:21:57 +00:00
|
|
|
LOGP(DRR, LOGL_ERROR,
|
|
|
|
"BUG: Multirate codec with too many modes in config.\n");
|
|
|
|
return -EINVAL;
|
2014-01-19 10:47:44 +00:00
|
|
|
}
|
|
|
|
if (num < 1) {
|
2018-10-22 12:21:57 +00:00
|
|
|
LOGP(DRR, LOGL_ERROR,
|
|
|
|
"BUG: Multirate codec with no mode in config.\n");
|
|
|
|
return -EINVAL;
|
2014-01-19 10:47:44 +00:00
|
|
|
}
|
|
|
|
|
2018-10-22 12:21:57 +00:00
|
|
|
/* Do not accept excess hysteresis or threshold values */
|
|
|
|
for (i = 0; i < num_modes; i++) {
|
|
|
|
if (modes[i].threshold >= 64) {
|
|
|
|
LOGP(DRR, LOGL_ERROR,
|
|
|
|
"BUG: Multirate codec with excessive threshold values.\n");
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
if (modes[i].hysteresis >= 16) {
|
|
|
|
LOGP(DRR, LOGL_ERROR,
|
|
|
|
"BUG: Multirate codec with excessive hysteresis values.\n");
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Scan through the selected modes and find a matching threshold/
|
|
|
|
* hysteresis value for that mode. */
|
|
|
|
for (i = 0; i < 8; i++) {
|
|
|
|
if (((gsm48_ie[1] >> i) & 1)) {
|
|
|
|
mode_valid = false;
|
|
|
|
for (k = 0; k < num_modes; k++) {
|
|
|
|
if (modes[k].mode == i) {
|
|
|
|
mode_valid = true;
|
|
|
|
modes_selected[m] = &modes[k];
|
|
|
|
m++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!mode_valid) {
|
|
|
|
LOGP(DRR, LOGL_ERROR,
|
2019-11-13 21:10:41 +00:00
|
|
|
"BUG: Multirate codec with inconsistent config (no mode defined).\n");
|
2018-10-22 12:21:57 +00:00
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
OSMO_ASSERT(m <= 4);
|
|
|
|
|
|
|
|
/* When the caller is not interested in any result, skip the actual
|
|
|
|
* composition of the IE (dry run) */
|
AMR config cleanup step 3: generate AMR LV on msg composition
Firstly, do not store the encoded AMR length-value bits in gsm_lchan->*
before an activation/modify has actually succeeded.
And secondly, do not store the AMR LV structure in struct gsm_lchan at
all, but only generate the TLV exactly when a message is being composed.
In gsm48_multirate_config(), generate the LV directly to a msgb instead
of a static buffer first. gsm0408_test.c expected output verifies that
the generated LV bytes remain unchanged.
In lchan_mr_config(), introduce a target mr_conf argument, so that Chan
Act and Mode Modify may generate the filtered AMR config to different
locations (lchan->{activate,modify}.mr_conf_filtered).
Only after receiving an ACK for Activate/Modify, set
lchan->current_mr_conf from lchan->{activate,modify}.mr_conf_filtered.
Use the properly scoped lchan->activate.mr_conf_filtered for Chan Act,
lchan->modify.mr_conf_filtered for Mode Modify and
new_lchan->current_mr_conf for Handover Command as appropriate.
Related: SYS#5315 OS#4940 OS#3787 OS#3833
Change-Id: Ie57f9d0e3912632903d9740291225bfd1634ed47
2021-04-29 17:58:52 +00:00
|
|
|
if (!msg)
|
2018-10-22 12:21:57 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
/* Compose output buffer */
|
AMR config cleanup step 3: generate AMR LV on msg composition
Firstly, do not store the encoded AMR length-value bits in gsm_lchan->*
before an activation/modify has actually succeeded.
And secondly, do not store the AMR LV structure in struct gsm_lchan at
all, but only generate the TLV exactly when a message is being composed.
In gsm48_multirate_config(), generate the LV directly to a msgb instead
of a static buffer first. gsm0408_test.c expected output verifies that
the generated LV bytes remain unchanged.
In lchan_mr_config(), introduce a target mr_conf argument, so that Chan
Act and Mode Modify may generate the filtered AMR config to different
locations (lchan->{activate,modify}.mr_conf_filtered).
Only after receiving an ACK for Activate/Modify, set
lchan->current_mr_conf from lchan->{activate,modify}.mr_conf_filtered.
Use the properly scoped lchan->activate.mr_conf_filtered for Chan Act,
lchan->modify.mr_conf_filtered for Mode Modify and
new_lchan->current_mr_conf for Handover Command as appropriate.
Related: SYS#5315 OS#4940 OS#3787 OS#3833
Change-Id: Ie57f9d0e3912632903d9740291225bfd1634ed47
2021-04-29 17:58:52 +00:00
|
|
|
/* length */
|
|
|
|
len = msgb_put(msg, 1);
|
|
|
|
|
|
|
|
/* Write octet 3 (Multirate speech version, NSCB, ICMI, spare, Start mode)
|
|
|
|
* and octet 4 (Set of AMR codec modes) */
|
|
|
|
data = msgb_put(msg, 2);
|
|
|
|
memcpy(data, gsm48_ie, 2);
|
2014-01-19 10:47:44 +00:00
|
|
|
if (num == 1)
|
AMR config cleanup step 3: generate AMR LV on msg composition
Firstly, do not store the encoded AMR length-value bits in gsm_lchan->*
before an activation/modify has actually succeeded.
And secondly, do not store the AMR LV structure in struct gsm_lchan at
all, but only generate the TLV exactly when a message is being composed.
In gsm48_multirate_config(), generate the LV directly to a msgb instead
of a static buffer first. gsm0408_test.c expected output verifies that
the generated LV bytes remain unchanged.
In lchan_mr_config(), introduce a target mr_conf argument, so that Chan
Act and Mode Modify may generate the filtered AMR config to different
locations (lchan->{activate,modify}.mr_conf_filtered).
Only after receiving an ACK for Activate/Modify, set
lchan->current_mr_conf from lchan->{activate,modify}.mr_conf_filtered.
Use the properly scoped lchan->activate.mr_conf_filtered for Chan Act,
lchan->modify.mr_conf_filtered for Mode Modify and
new_lchan->current_mr_conf for Handover Command as appropriate.
Related: SYS#5315 OS#4940 OS#3787 OS#3833
Change-Id: Ie57f9d0e3912632903d9740291225bfd1634ed47
2021-04-29 17:58:52 +00:00
|
|
|
goto return_msg;
|
2015-09-24 09:30:58 +00:00
|
|
|
|
AMR config cleanup step 3: generate AMR LV on msg composition
Firstly, do not store the encoded AMR length-value bits in gsm_lchan->*
before an activation/modify has actually succeeded.
And secondly, do not store the AMR LV structure in struct gsm_lchan at
all, but only generate the TLV exactly when a message is being composed.
In gsm48_multirate_config(), generate the LV directly to a msgb instead
of a static buffer first. gsm0408_test.c expected output verifies that
the generated LV bytes remain unchanged.
In lchan_mr_config(), introduce a target mr_conf argument, so that Chan
Act and Mode Modify may generate the filtered AMR config to different
locations (lchan->{activate,modify}.mr_conf_filtered).
Only after receiving an ACK for Activate/Modify, set
lchan->current_mr_conf from lchan->{activate,modify}.mr_conf_filtered.
Use the properly scoped lchan->activate.mr_conf_filtered for Chan Act,
lchan->modify.mr_conf_filtered for Mode Modify and
new_lchan->current_mr_conf for Handover Command as appropriate.
Related: SYS#5315 OS#4940 OS#3787 OS#3833
Change-Id: Ie57f9d0e3912632903d9740291225bfd1634ed47
2021-04-29 17:58:52 +00:00
|
|
|
/* more than 1 mode: write octet 5 and 6: threshold 1 and hysteresis 1 */
|
|
|
|
data = msgb_put(msg, 2);
|
|
|
|
data[0] = modes_selected[0]->threshold & 0x3f;
|
|
|
|
data[1] = modes_selected[0]->hysteresis << 4;
|
2015-09-24 09:30:58 +00:00
|
|
|
if (num == 2)
|
AMR config cleanup step 3: generate AMR LV on msg composition
Firstly, do not store the encoded AMR length-value bits in gsm_lchan->*
before an activation/modify has actually succeeded.
And secondly, do not store the AMR LV structure in struct gsm_lchan at
all, but only generate the TLV exactly when a message is being composed.
In gsm48_multirate_config(), generate the LV directly to a msgb instead
of a static buffer first. gsm0408_test.c expected output verifies that
the generated LV bytes remain unchanged.
In lchan_mr_config(), introduce a target mr_conf argument, so that Chan
Act and Mode Modify may generate the filtered AMR config to different
locations (lchan->{activate,modify}.mr_conf_filtered).
Only after receiving an ACK for Activate/Modify, set
lchan->current_mr_conf from lchan->{activate,modify}.mr_conf_filtered.
Use the properly scoped lchan->activate.mr_conf_filtered for Chan Act,
lchan->modify.mr_conf_filtered for Mode Modify and
new_lchan->current_mr_conf for Handover Command as appropriate.
Related: SYS#5315 OS#4940 OS#3787 OS#3833
Change-Id: Ie57f9d0e3912632903d9740291225bfd1634ed47
2021-04-29 17:58:52 +00:00
|
|
|
goto return_msg;
|
|
|
|
|
|
|
|
/* more than 2 modes: complete octet 6 and add octet 7: threshold 2 and hysteresis 2.
|
|
|
|
* Threshold 2 starts in octet 6. */
|
|
|
|
data[1] |= (modes_selected[1]->threshold & 0x3f) >> 2;
|
|
|
|
/* octet 7 */
|
|
|
|
data = msgb_put(msg, 1);
|
|
|
|
data[0] = modes_selected[1]->threshold << 6;
|
|
|
|
data[0] |= (modes_selected[1]->hysteresis & 0x0f) << 2;
|
2015-09-24 09:30:58 +00:00
|
|
|
if (num == 3)
|
AMR config cleanup step 3: generate AMR LV on msg composition
Firstly, do not store the encoded AMR length-value bits in gsm_lchan->*
before an activation/modify has actually succeeded.
And secondly, do not store the AMR LV structure in struct gsm_lchan at
all, but only generate the TLV exactly when a message is being composed.
In gsm48_multirate_config(), generate the LV directly to a msgb instead
of a static buffer first. gsm0408_test.c expected output verifies that
the generated LV bytes remain unchanged.
In lchan_mr_config(), introduce a target mr_conf argument, so that Chan
Act and Mode Modify may generate the filtered AMR config to different
locations (lchan->{activate,modify}.mr_conf_filtered).
Only after receiving an ACK for Activate/Modify, set
lchan->current_mr_conf from lchan->{activate,modify}.mr_conf_filtered.
Use the properly scoped lchan->activate.mr_conf_filtered for Chan Act,
lchan->modify.mr_conf_filtered for Mode Modify and
new_lchan->current_mr_conf for Handover Command as appropriate.
Related: SYS#5315 OS#4940 OS#3787 OS#3833
Change-Id: Ie57f9d0e3912632903d9740291225bfd1634ed47
2021-04-29 17:58:52 +00:00
|
|
|
goto return_msg;
|
|
|
|
|
|
|
|
/* four modes: complete octet 7 and add octet 8: threshold 3 and hysteresis 3.
|
|
|
|
* Threshold 3 starts in octet 7. */
|
|
|
|
data[0] |= (modes_selected[2]->threshold & 0x3f) >> 4;
|
|
|
|
/* octet 8 */
|
|
|
|
data = msgb_put(msg, 1);
|
|
|
|
data[0] = modes_selected[2]->threshold << 4;
|
|
|
|
data[0] |= modes_selected[2]->hysteresis & 0x0f;
|
|
|
|
|
|
|
|
return_msg:
|
|
|
|
/* Place written len in the IE length field. msg->tail points one byte after the last data octet, len points at
|
|
|
|
* the L octet of the TLV. */
|
|
|
|
*len = (msg->tail - 1) - len;
|
2014-01-19 10:47:44 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-06-15 14:45:51 +00:00
|
|
|
#define GSM48_HOCMD_CCHDESC_LEN 16
|
|
|
|
|
2009-11-29 19:02:53 +00:00
|
|
|
/* Chapter 9.1.15: Handover Command */
|
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
|
|
|
struct msgb *gsm48_make_ho_cmd(struct gsm_lchan *new_lchan, uint8_t power_command, uint8_t ho_ref)
|
2009-11-29 19:02:53 +00:00
|
|
|
{
|
2016-01-25 21:03:25 +00:00
|
|
|
struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 HO CMD");
|
2009-11-29 19:02:53 +00:00
|
|
|
struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
|
|
|
|
struct gsm48_ho_cmd *ho =
|
|
|
|
(struct gsm48_ho_cmd *) msgb_put(msg, sizeof(*ho));
|
AMR config cleanup step 3: generate AMR LV on msg composition
Firstly, do not store the encoded AMR length-value bits in gsm_lchan->*
before an activation/modify has actually succeeded.
And secondly, do not store the AMR LV structure in struct gsm_lchan at
all, but only generate the TLV exactly when a message is being composed.
In gsm48_multirate_config(), generate the LV directly to a msgb instead
of a static buffer first. gsm0408_test.c expected output verifies that
the generated LV bytes remain unchanged.
In lchan_mr_config(), introduce a target mr_conf argument, so that Chan
Act and Mode Modify may generate the filtered AMR config to different
locations (lchan->{activate,modify}.mr_conf_filtered).
Only after receiving an ACK for Activate/Modify, set
lchan->current_mr_conf from lchan->{activate,modify}.mr_conf_filtered.
Use the properly scoped lchan->activate.mr_conf_filtered for Chan Act,
lchan->modify.mr_conf_filtered for Mode Modify and
new_lchan->current_mr_conf for Handover Command as appropriate.
Related: SYS#5315 OS#4940 OS#3787 OS#3833
Change-Id: Ie57f9d0e3912632903d9740291225bfd1634ed47
2021-04-29 17:58:52 +00:00
|
|
|
struct gsm_bts *bts = new_lchan->ts->trx->bts;
|
2009-11-29 19:02:53 +00:00
|
|
|
|
2009-12-16 23:25:18 +00:00
|
|
|
gh->proto_discr = GSM48_PDISC_RR;
|
|
|
|
gh->msg_type = GSM48_MT_RR_HANDO_CMD;
|
2009-11-29 19:02:53 +00:00
|
|
|
|
|
|
|
/* mandatory bits */
|
|
|
|
gsm48_cell_desc(&ho->cell_desc, new_lchan->ts->trx->bts);
|
2021-05-19 00:29:53 +00:00
|
|
|
gsm48_lchan2chan_desc(&ho->chan_desc, new_lchan, gsm_ts_tsc(new_lchan->ts));
|
2009-12-16 23:25:18 +00:00
|
|
|
ho->ho_ref = ho_ref;
|
2009-11-29 19:02:53 +00:00
|
|
|
ho->power_command = power_command;
|
|
|
|
|
2010-06-15 14:45:51 +00:00
|
|
|
if (new_lchan->ts->hopping.enabled) {
|
|
|
|
struct gsm_bts *bts = new_lchan->ts->trx->bts;
|
|
|
|
struct gsm48_system_information_type_1 *si1;
|
|
|
|
|
|
|
|
si1 = GSM_BTS_SI(bts, SYSINFO_TYPE_1);
|
|
|
|
/* Copy the Cell Chan Desc (ARFCNS in this cell) */
|
2020-09-02 11:29:17 +00:00
|
|
|
msgb_tv_fixed_put(msg, GSM48_IE_CELL_CH_DESC,
|
|
|
|
GSM48_HOCMD_CCHDESC_LEN,
|
|
|
|
si1->cell_channel_description);
|
2010-06-15 14:45:51 +00:00
|
|
|
}
|
2009-11-29 19:02:53 +00:00
|
|
|
/* FIXME: optional bits for type of synchronization? */
|
|
|
|
|
2021-04-27 23:17:14 +00:00
|
|
|
msgb_tv_put(msg, GSM48_IE_CHANMODE_1, new_lchan->current_ch_mode_rate.chan_mode);
|
2013-05-30 07:57:55 +00:00
|
|
|
|
2020-09-02 11:29:17 +00:00
|
|
|
/* Mobile Allocation (after time), TLV (see 3GPP TS 44.018, 10.5.2.21) */
|
|
|
|
if (new_lchan->ts->hopping.enabled) {
|
|
|
|
msgb_tlv_put(msg, GSM48_IE_MA_AFTER,
|
|
|
|
new_lchan->ts->hopping.ma_len,
|
|
|
|
new_lchan->ts->hopping.ma_data);
|
|
|
|
}
|
|
|
|
|
2013-05-30 07:57:55 +00:00
|
|
|
/* in case of multi rate we need to attach a config */
|
2021-05-28 17:18:11 +00:00
|
|
|
if (gsm48_chan_mode_to_non_vamos(new_lchan->current_ch_mode_rate.chan_mode) == GSM48_CMODE_SPEECH_AMR) {
|
AMR config cleanup step 3: generate AMR LV on msg composition
Firstly, do not store the encoded AMR length-value bits in gsm_lchan->*
before an activation/modify has actually succeeded.
And secondly, do not store the AMR LV structure in struct gsm_lchan at
all, but only generate the TLV exactly when a message is being composed.
In gsm48_multirate_config(), generate the LV directly to a msgb instead
of a static buffer first. gsm0408_test.c expected output verifies that
the generated LV bytes remain unchanged.
In lchan_mr_config(), introduce a target mr_conf argument, so that Chan
Act and Mode Modify may generate the filtered AMR config to different
locations (lchan->{activate,modify}.mr_conf_filtered).
Only after receiving an ACK for Activate/Modify, set
lchan->current_mr_conf from lchan->{activate,modify}.mr_conf_filtered.
Use the properly scoped lchan->activate.mr_conf_filtered for Chan Act,
lchan->modify.mr_conf_filtered for Mode Modify and
new_lchan->current_mr_conf for Handover Command as appropriate.
Related: SYS#5315 OS#4940 OS#3787 OS#3833
Change-Id: Ie57f9d0e3912632903d9740291225bfd1634ed47
2021-04-29 17:58:52 +00:00
|
|
|
if (put_mr_config_for_ms(msg, &new_lchan->current_mr_conf,
|
|
|
|
(new_lchan->type == GSM_LCHAN_TCH_F) ? &bts->mr_full : &bts->mr_half)) {
|
|
|
|
LOG_LCHAN(new_lchan, LOGL_ERROR, "Cannot encode MultiRate Configuration IE\n");
|
|
|
|
msgb_free(msg);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
2013-05-30 07:57:55 +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
|
|
|
return msg;
|
|
|
|
}
|
|
|
|
|
|
|
|
int gsm48_send_ho_cmd(struct gsm_lchan *old_lchan, struct gsm_lchan *new_lchan,
|
|
|
|
uint8_t power_command, uint8_t ho_ref)
|
|
|
|
{
|
|
|
|
struct msgb *msg = gsm48_make_ho_cmd(new_lchan, power_command, ho_ref);
|
|
|
|
if (!msg)
|
|
|
|
return -EINVAL;
|
|
|
|
msg->lchan = old_lchan;
|
2010-06-15 05:57:40 +00:00
|
|
|
return gsm48_sendmsg(msg);
|
2009-11-29 19:02:53 +00:00
|
|
|
}
|
|
|
|
|
2009-10-22 09:47:45 +00:00
|
|
|
/* Chapter 9.1.2: Assignment Command */
|
2021-04-14 17:45:00 +00:00
|
|
|
int gsm48_send_rr_ass_cmd(struct gsm_lchan *current_lchan, struct gsm_lchan *new_lchan, uint8_t power_command)
|
2009-10-22 09:47:45 +00:00
|
|
|
{
|
2016-01-25 21:03:25 +00:00
|
|
|
struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 ASS CMD");
|
2009-10-22 09:47:45 +00:00
|
|
|
struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
|
|
|
|
struct gsm48_ass_cmd *ass =
|
|
|
|
(struct gsm48_ass_cmd *) msgb_put(msg, sizeof(*ass));
|
AMR config cleanup step 3: generate AMR LV on msg composition
Firstly, do not store the encoded AMR length-value bits in gsm_lchan->*
before an activation/modify has actually succeeded.
And secondly, do not store the AMR LV structure in struct gsm_lchan at
all, but only generate the TLV exactly when a message is being composed.
In gsm48_multirate_config(), generate the LV directly to a msgb instead
of a static buffer first. gsm0408_test.c expected output verifies that
the generated LV bytes remain unchanged.
In lchan_mr_config(), introduce a target mr_conf argument, so that Chan
Act and Mode Modify may generate the filtered AMR config to different
locations (lchan->{activate,modify}.mr_conf_filtered).
Only after receiving an ACK for Activate/Modify, set
lchan->current_mr_conf from lchan->{activate,modify}.mr_conf_filtered.
Use the properly scoped lchan->activate.mr_conf_filtered for Chan Act,
lchan->modify.mr_conf_filtered for Mode Modify and
new_lchan->current_mr_conf for Handover Command as appropriate.
Related: SYS#5315 OS#4940 OS#3787 OS#3833
Change-Id: Ie57f9d0e3912632903d9740291225bfd1634ed47
2021-04-29 17:58:52 +00:00
|
|
|
struct gsm_bts *bts = new_lchan->ts->trx->bts;
|
2009-10-22 09:47:45 +00:00
|
|
|
|
2021-04-27 23:17:14 +00:00
|
|
|
DEBUGP(DRR, "-> ASSIGNMENT COMMAND tch_mode=0x%02x\n",
|
AMR config cleanup step 3: generate AMR LV on msg composition
Firstly, do not store the encoded AMR length-value bits in gsm_lchan->*
before an activation/modify has actually succeeded.
And secondly, do not store the AMR LV structure in struct gsm_lchan at
all, but only generate the TLV exactly when a message is being composed.
In gsm48_multirate_config(), generate the LV directly to a msgb instead
of a static buffer first. gsm0408_test.c expected output verifies that
the generated LV bytes remain unchanged.
In lchan_mr_config(), introduce a target mr_conf argument, so that Chan
Act and Mode Modify may generate the filtered AMR config to different
locations (lchan->{activate,modify}.mr_conf_filtered).
Only after receiving an ACK for Activate/Modify, set
lchan->current_mr_conf from lchan->{activate,modify}.mr_conf_filtered.
Use the properly scoped lchan->activate.mr_conf_filtered for Chan Act,
lchan->modify.mr_conf_filtered for Mode Modify and
new_lchan->current_mr_conf for Handover Command as appropriate.
Related: SYS#5315 OS#4940 OS#3787 OS#3833
Change-Id: Ie57f9d0e3912632903d9740291225bfd1634ed47
2021-04-29 17:58:52 +00:00
|
|
|
new_lchan->current_ch_mode_rate.chan_mode);
|
2009-10-22 09:47:45 +00:00
|
|
|
|
2021-04-14 17:42:44 +00:00
|
|
|
msg->lchan = current_lchan;
|
2009-10-22 09:47:45 +00:00
|
|
|
gh->proto_discr = GSM48_PDISC_RR;
|
|
|
|
gh->msg_type = GSM48_MT_RR_ASS_CMD;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* fill the channel information element, this code
|
|
|
|
* should probably be shared with rsl_rx_chan_rqd(),
|
2016-04-07 09:38:52 +00:00
|
|
|
* gsm48_lchan_modify(). But beware that 10.5.2.5
|
2009-10-22 09:47:45 +00:00
|
|
|
* 10.5.2.5.a have slightly different semantic for
|
|
|
|
* the chan_desc. But as long as multi-slot configurations
|
|
|
|
* are not used we seem to be fine.
|
|
|
|
*/
|
allow explixit TSC Set and TSC on chan activ / modif / assignment
Activating / modifying to a VAMOS mode will require picking specific TSC
Set / TSC. It is a bad idea to pick the TSC in each message encoding
function, rather make this choice centrally.
So far we pick the training sequence code to use based on the timeslot
configuration, and this TSC is determined only upon encoding the RSL
messages.
Instead, pick the TSC to use upon the initial lchan activation /
modification request; store this in the request structs and pass through
the activation / modification code paths.
For VAMOS modes, we also need to pick a TSC Set. Do so also upon activ /
modif request. Note that the TSC Set is not yet applied in this patch,
it will be applied in upcoming VAMOS patches.
The activ / modif request may pass -1 for tsc_set and/or tsc to indicate
no specific choice of TSC Set and TSC, resulting in the same behavior as
before this patch.
For example, lchan->activate.info.tsc* may be passed as -1. The exact
choice for tsc_set and tsc is then stored in lchan->activate.tsc*, i.e.
one level up (the .info sub-struct is considered as immutable input
args). The lchan->activate.tsc* are the values actually encoded in RSL
messages. After the ACK, the lchan->activate.tsc* is stored in
lchan->tsc* to indicate the TSC actually in use. Same for modif.
Note that in 3GPP TS 45.002, the TSC Set are numbered 1 to 4, while the
TSC are numbered 0 to 7. On the wire, though, TSC Set is sent as 0 to 3
value. This is a weird discrepancy, odd choice made by the spec authors.
For conformance with the spec wording, I decided to pass the TSC Set
number as a 1-4 ranged value, and only convert it to the 0-3 on-the-wire
format upon message encoding. So log messages and VTY output will
indicate the first TSC Set as "1", but the first TSC as "0", as defined
in 3GPP TS 45.002, even if that is somewhat weird.
Related: SYS#5315 OS#4940
Change-Id: Ic665125255d7354f5499d10dda1dd866ab243d24
2021-05-22 14:29:35 +00:00
|
|
|
gsm48_lchan2chan_desc(&ass->chan_desc, new_lchan, new_lchan->tsc);
|
2009-10-22 09:47:45 +00:00
|
|
|
ass->power_command = power_command;
|
|
|
|
|
gsm_04_08_rr: fix hopping parameters in RR Assignment Command
According to 3GPP TS 44.018, section 9.1.2.4, if at least one of
the Channel Description IEs indicates frequency hopping, one and
only one of the following IEs shall be present:
- Mobile Allocation, after time (see 10.5.2.21);
- Frequency List, after time (see 10.5.2.13).
For some reason, osmo-bsc includes the GSM48_IE_MA_BEFORE instead
of GSM48_IE_MA_AFTER - fix this.
According to section 9.1.2.6 of the same document, if any of the
Mobile Allocation IEs (before/after time) is present, then the
network must ensure that either the MS has already received the
the proper reference cell frequency list (CA), or that the Cell
Channel Description IE (see 10.5.2.1b) is present.
Without this IE, the phone I was using in my testing setup sends
RR Status message with cause #100 "conditional IE error".
Fortunately, we already have generate_cell_chan_list(), since we
also need to include the Cell Channel Description in SI Type 1.
Change-Id: I43ef66c109b107ebcaa1cb6197637701b13b3787
Related: SYS#4868, OS#4545, OS#4546
2020-06-30 10:40:20 +00:00
|
|
|
/* Cell Channel Description (freq. hopping), TV (see 3GPP TS 44.018, 10.5.2.1b) */
|
2021-04-14 17:45:00 +00:00
|
|
|
if (new_lchan->ts->hopping.enabled) {
|
AMR config cleanup step 3: generate AMR LV on msg composition
Firstly, do not store the encoded AMR length-value bits in gsm_lchan->*
before an activation/modify has actually succeeded.
And secondly, do not store the AMR LV structure in struct gsm_lchan at
all, but only generate the TLV exactly when a message is being composed.
In gsm48_multirate_config(), generate the LV directly to a msgb instead
of a static buffer first. gsm0408_test.c expected output verifies that
the generated LV bytes remain unchanged.
In lchan_mr_config(), introduce a target mr_conf argument, so that Chan
Act and Mode Modify may generate the filtered AMR config to different
locations (lchan->{activate,modify}.mr_conf_filtered).
Only after receiving an ACK for Activate/Modify, set
lchan->current_mr_conf from lchan->{activate,modify}.mr_conf_filtered.
Use the properly scoped lchan->activate.mr_conf_filtered for Chan Act,
lchan->modify.mr_conf_filtered for Mode Modify and
new_lchan->current_mr_conf for Handover Command as appropriate.
Related: SYS#5315 OS#4940 OS#3787 OS#3833
Change-Id: Ie57f9d0e3912632903d9740291225bfd1634ed47
2021-04-29 17:58:52 +00:00
|
|
|
const struct gsm48_system_information_type_1 *si1 = GSM_BTS_SI(bts, 1);
|
2021-04-06 00:06:23 +00:00
|
|
|
msgb_tv_fixed_put(msg, GSM48_IE_CELL_CH_DESC,
|
|
|
|
sizeof(si1->cell_channel_description),
|
|
|
|
si1->cell_channel_description);
|
gsm_04_08_rr: fix hopping parameters in RR Assignment Command
According to 3GPP TS 44.018, section 9.1.2.4, if at least one of
the Channel Description IEs indicates frequency hopping, one and
only one of the following IEs shall be present:
- Mobile Allocation, after time (see 10.5.2.21);
- Frequency List, after time (see 10.5.2.13).
For some reason, osmo-bsc includes the GSM48_IE_MA_BEFORE instead
of GSM48_IE_MA_AFTER - fix this.
According to section 9.1.2.6 of the same document, if any of the
Mobile Allocation IEs (before/after time) is present, then the
network must ensure that either the MS has already received the
the proper reference cell frequency list (CA), or that the Cell
Channel Description IE (see 10.5.2.1b) is present.
Without this IE, the phone I was using in my testing setup sends
RR Status message with cause #100 "conditional IE error".
Fortunately, we already have generate_cell_chan_list(), since we
also need to include the Cell Channel Description in SI Type 1.
Change-Id: I43ef66c109b107ebcaa1cb6197637701b13b3787
Related: SYS#4868, OS#4545, OS#4546
2020-06-30 10:40:20 +00:00
|
|
|
}
|
2010-06-15 14:45:51 +00:00
|
|
|
|
AMR config cleanup step 3: generate AMR LV on msg composition
Firstly, do not store the encoded AMR length-value bits in gsm_lchan->*
before an activation/modify has actually succeeded.
And secondly, do not store the AMR LV structure in struct gsm_lchan at
all, but only generate the TLV exactly when a message is being composed.
In gsm48_multirate_config(), generate the LV directly to a msgb instead
of a static buffer first. gsm0408_test.c expected output verifies that
the generated LV bytes remain unchanged.
In lchan_mr_config(), introduce a target mr_conf argument, so that Chan
Act and Mode Modify may generate the filtered AMR config to different
locations (lchan->{activate,modify}.mr_conf_filtered).
Only after receiving an ACK for Activate/Modify, set
lchan->current_mr_conf from lchan->{activate,modify}.mr_conf_filtered.
Use the properly scoped lchan->activate.mr_conf_filtered for Chan Act,
lchan->modify.mr_conf_filtered for Mode Modify and
new_lchan->current_mr_conf for Handover Command as appropriate.
Related: SYS#5315 OS#4940 OS#3787 OS#3833
Change-Id: Ie57f9d0e3912632903d9740291225bfd1634ed47
2021-04-29 17:58:52 +00:00
|
|
|
msgb_tv_put(msg, GSM48_IE_CHANMODE_1, new_lchan->current_ch_mode_rate.chan_mode);
|
2010-01-28 10:51:24 +00:00
|
|
|
|
gsm_04_08_rr: fix hopping parameters in RR Assignment Command
According to 3GPP TS 44.018, section 9.1.2.4, if at least one of
the Channel Description IEs indicates frequency hopping, one and
only one of the following IEs shall be present:
- Mobile Allocation, after time (see 10.5.2.21);
- Frequency List, after time (see 10.5.2.13).
For some reason, osmo-bsc includes the GSM48_IE_MA_BEFORE instead
of GSM48_IE_MA_AFTER - fix this.
According to section 9.1.2.6 of the same document, if any of the
Mobile Allocation IEs (before/after time) is present, then the
network must ensure that either the MS has already received the
the proper reference cell frequency list (CA), or that the Cell
Channel Description IE (see 10.5.2.1b) is present.
Without this IE, the phone I was using in my testing setup sends
RR Status message with cause #100 "conditional IE error".
Fortunately, we already have generate_cell_chan_list(), since we
also need to include the Cell Channel Description in SI Type 1.
Change-Id: I43ef66c109b107ebcaa1cb6197637701b13b3787
Related: SYS#4868, OS#4545, OS#4546
2020-06-30 10:40:20 +00:00
|
|
|
/* Mobile Allocation (freq. hopping), TLV (see 3GPP TS 44.018, 10.5.2.21) */
|
2021-04-14 17:45:00 +00:00
|
|
|
if (new_lchan->ts->hopping.enabled) {
|
|
|
|
msgb_tlv_put(msg, GSM48_IE_MA_AFTER, new_lchan->ts->hopping.ma_len,
|
|
|
|
new_lchan->ts->hopping.ma_data);
|
2010-06-15 14:45:51 +00:00
|
|
|
}
|
|
|
|
|
2009-11-16 21:49:24 +00:00
|
|
|
/* in case of multi rate we need to attach a config */
|
2021-05-28 17:18:11 +00:00
|
|
|
if (gsm48_chan_mode_to_non_vamos(new_lchan->current_ch_mode_rate.chan_mode) == GSM48_CMODE_SPEECH_AMR) {
|
AMR config cleanup step 3: generate AMR LV on msg composition
Firstly, do not store the encoded AMR length-value bits in gsm_lchan->*
before an activation/modify has actually succeeded.
And secondly, do not store the AMR LV structure in struct gsm_lchan at
all, but only generate the TLV exactly when a message is being composed.
In gsm48_multirate_config(), generate the LV directly to a msgb instead
of a static buffer first. gsm0408_test.c expected output verifies that
the generated LV bytes remain unchanged.
In lchan_mr_config(), introduce a target mr_conf argument, so that Chan
Act and Mode Modify may generate the filtered AMR config to different
locations (lchan->{activate,modify}.mr_conf_filtered).
Only after receiving an ACK for Activate/Modify, set
lchan->current_mr_conf from lchan->{activate,modify}.mr_conf_filtered.
Use the properly scoped lchan->activate.mr_conf_filtered for Chan Act,
lchan->modify.mr_conf_filtered for Mode Modify and
new_lchan->current_mr_conf for Handover Command as appropriate.
Related: SYS#5315 OS#4940 OS#3787 OS#3833
Change-Id: Ie57f9d0e3912632903d9740291225bfd1634ed47
2021-04-29 17:58:52 +00:00
|
|
|
int rc = put_mr_config_for_ms(msg, &new_lchan->current_mr_conf,
|
|
|
|
(new_lchan->type == GSM_LCHAN_TCH_F) ? &bts->mr_full : &bts->mr_half);
|
|
|
|
if (rc) {
|
|
|
|
LOG_LCHAN(current_lchan, LOGL_ERROR, "Cannot encode MultiRate Configuration IE\n");
|
|
|
|
msgb_free(msg);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
}
|
2009-11-16 21:49:24 +00:00
|
|
|
|
2010-06-15 05:57:40 +00:00
|
|
|
return gsm48_sendmsg(msg);
|
2009-10-22 09:47:45 +00:00
|
|
|
}
|
2009-10-22 13:13:00 +00:00
|
|
|
|
2019-09-02 12:13:51 +00:00
|
|
|
/* TS 44.018 section 9.1.53 */
|
|
|
|
int gsm48_send_rr_app_info(struct gsm_lchan *lchan, uint8_t apdu_id, uint8_t apdu_flags,
|
|
|
|
const uint8_t *apdu_data, ssize_t apdu_data_len)
|
|
|
|
{
|
|
|
|
struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 APP INFO");
|
|
|
|
struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
|
|
|
|
|
|
|
|
if ((apdu_id & 0xF0) || (apdu_flags & 0xF0)) {
|
|
|
|
msgb_free(msg);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
msg->lchan = lchan;
|
|
|
|
gh->proto_discr = GSM48_PDISC_RR;
|
|
|
|
gh->msg_type = GSM48_MT_RR_APP_INFO;
|
|
|
|
|
|
|
|
msgb_put_u8(msg, (apdu_flags << 4) | apdu_id);
|
|
|
|
msgb_lv_put(msg, apdu_data_len, apdu_data);
|
|
|
|
|
|
|
|
return gsm48_sendmsg(msg);
|
|
|
|
}
|
|
|
|
|
2009-10-22 13:13:00 +00:00
|
|
|
/* 9.1.5 Channel mode modify: Modify the mode on the MS side */
|
2016-04-07 09:38:52 +00:00
|
|
|
int gsm48_lchan_modify(struct gsm_lchan *lchan, uint8_t mode)
|
2009-10-22 13:13:00 +00:00
|
|
|
{
|
2016-01-25 21:03:25 +00:00
|
|
|
struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CHN MOD");
|
2009-10-22 13:13:00 +00:00
|
|
|
struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
|
|
|
|
struct gsm48_chan_mode_modify *cmm =
|
|
|
|
(struct gsm48_chan_mode_modify *) msgb_put(msg, sizeof(*cmm));
|
AMR config cleanup step 3: generate AMR LV on msg composition
Firstly, do not store the encoded AMR length-value bits in gsm_lchan->*
before an activation/modify has actually succeeded.
And secondly, do not store the AMR LV structure in struct gsm_lchan at
all, but only generate the TLV exactly when a message is being composed.
In gsm48_multirate_config(), generate the LV directly to a msgb instead
of a static buffer first. gsm0408_test.c expected output verifies that
the generated LV bytes remain unchanged.
In lchan_mr_config(), introduce a target mr_conf argument, so that Chan
Act and Mode Modify may generate the filtered AMR config to different
locations (lchan->{activate,modify}.mr_conf_filtered).
Only after receiving an ACK for Activate/Modify, set
lchan->current_mr_conf from lchan->{activate,modify}.mr_conf_filtered.
Use the properly scoped lchan->activate.mr_conf_filtered for Chan Act,
lchan->modify.mr_conf_filtered for Mode Modify and
new_lchan->current_mr_conf for Handover Command as appropriate.
Related: SYS#5315 OS#4940 OS#3787 OS#3833
Change-Id: Ie57f9d0e3912632903d9740291225bfd1634ed47
2021-04-29 17:58:52 +00:00
|
|
|
struct gsm_bts *bts = lchan->ts->trx->bts;
|
2009-10-22 13:13:00 +00:00
|
|
|
|
|
|
|
DEBUGP(DRR, "-> CHANNEL MODE MODIFY mode=0x%02x\n", mode);
|
|
|
|
|
|
|
|
msg->lchan = lchan;
|
|
|
|
gh->proto_discr = GSM48_PDISC_RR;
|
|
|
|
gh->msg_type = GSM48_MT_RR_CHAN_MODE_MODIF;
|
|
|
|
|
2021-06-02 18:20:03 +00:00
|
|
|
gsm48_lchan2chan_desc(&cmm->chan_desc, lchan, lchan->modify.tsc);
|
2009-10-22 13:13:00 +00:00
|
|
|
cmm->mode = mode;
|
|
|
|
|
2009-11-16 21:49:24 +00:00
|
|
|
/* in case of multi rate we need to attach a config */
|
2021-05-28 17:03:08 +00:00
|
|
|
if (gsm48_chan_mode_to_non_vamos(lchan->modify.ch_mode_rate.chan_mode) == GSM48_CMODE_SPEECH_AMR) {
|
AMR config cleanup step 3: generate AMR LV on msg composition
Firstly, do not store the encoded AMR length-value bits in gsm_lchan->*
before an activation/modify has actually succeeded.
And secondly, do not store the AMR LV structure in struct gsm_lchan at
all, but only generate the TLV exactly when a message is being composed.
In gsm48_multirate_config(), generate the LV directly to a msgb instead
of a static buffer first. gsm0408_test.c expected output verifies that
the generated LV bytes remain unchanged.
In lchan_mr_config(), introduce a target mr_conf argument, so that Chan
Act and Mode Modify may generate the filtered AMR config to different
locations (lchan->{activate,modify}.mr_conf_filtered).
Only after receiving an ACK for Activate/Modify, set
lchan->current_mr_conf from lchan->{activate,modify}.mr_conf_filtered.
Use the properly scoped lchan->activate.mr_conf_filtered for Chan Act,
lchan->modify.mr_conf_filtered for Mode Modify and
new_lchan->current_mr_conf for Handover Command as appropriate.
Related: SYS#5315 OS#4940 OS#3787 OS#3833
Change-Id: Ie57f9d0e3912632903d9740291225bfd1634ed47
2021-04-29 17:58:52 +00:00
|
|
|
int rc = put_mr_config_for_ms(msg, &lchan->modify.mr_conf_filtered,
|
|
|
|
(lchan->type == GSM_LCHAN_TCH_F) ? &bts->mr_full : &bts->mr_half);
|
|
|
|
if (rc) {
|
|
|
|
LOG_LCHAN(lchan, LOGL_ERROR, "Cannot encode MultiRate Configuration IE\n");
|
|
|
|
msgb_free(msg);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
}
|
2009-11-16 21:49:24 +00:00
|
|
|
|
2021-04-19 22:01:14 +00:00
|
|
|
if (lchan->modify.info.vamos && lchan->modify.tsc_set > 0) {
|
|
|
|
/* Add the Extended TSC Set IE. So far we only need a TSC Set sent for VAMOS.
|
|
|
|
* Convert from spec conforming "human readable" TSC Set 1-4 to 0-3 on the wire */
|
|
|
|
msgb_tv_put(msg, GSM48_IE_EXTENDED_TSC_SET, (lchan->modify.tsc_set - 1) & 0x3);
|
|
|
|
}
|
|
|
|
|
2010-06-15 05:57:40 +00:00
|
|
|
return gsm48_sendmsg(msg);
|
2009-10-22 13:13:00 +00:00
|
|
|
}
|
|
|
|
|
2009-10-22 13:23:11 +00:00
|
|
|
int gsm48_rx_rr_modif_ack(struct msgb *msg)
|
|
|
|
{
|
|
|
|
struct gsm48_hdr *gh = msgb_l3(msg);
|
|
|
|
struct gsm48_chan_mode_modify *mod =
|
|
|
|
(struct gsm48_chan_mode_modify *) gh->data;
|
|
|
|
|
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
|
|
|
LOG_LCHAN(msg->lchan, LOGL_DEBUG, "CHANNEL MODE MODIFY ACK for %s\n",
|
|
|
|
gsm48_chan_mode_name(mod->mode));
|
2009-10-22 13:23:11 +00:00
|
|
|
|
2021-05-28 17:03:08 +00:00
|
|
|
if (mod->mode != msg->lchan->modify.ch_mode_rate.chan_mode) {
|
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
|
|
|
LOG_LCHAN(msg->lchan, LOGL_ERROR,
|
|
|
|
"CHANNEL MODE MODIFY ACK has wrong mode: Wanted: %s Got: %s\n",
|
2021-05-28 17:03:08 +00:00
|
|
|
gsm48_chan_mode_name(msg->lchan->modify.ch_mode_rate.chan_mode),
|
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
|
|
|
gsm48_chan_mode_name(mod->mode));
|
2009-10-22 13:23:11 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2020-08-21 18:47:49 +00:00
|
|
|
return 0;
|
2009-10-22 13:23:11 +00:00
|
|
|
}
|
2009-12-22 06:45:17 +00:00
|
|
|
|
|
|
|
int gsm48_parse_meas_rep(struct gsm_meas_rep *rep, struct msgb *msg)
|
|
|
|
{
|
|
|
|
struct gsm48_hdr *gh = msgb_l3(msg);
|
2011-04-18 15:04:00 +00:00
|
|
|
uint8_t *data = gh->data;
|
2009-12-22 06:45:17 +00:00
|
|
|
struct gsm_bts *bts = msg->lchan->ts->trx->bts;
|
|
|
|
struct bitvec *nbv = &bts->si_common.neigh_list;
|
2009-12-25 21:46:25 +00:00
|
|
|
struct gsm_meas_rep_cell *mrc;
|
2009-12-22 06:45:17 +00:00
|
|
|
|
|
|
|
if (gh->msg_type != GSM48_MT_RR_MEAS_REP)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
if (data[0] & 0x80)
|
|
|
|
rep->flags |= MEAS_REP_F_BA1;
|
|
|
|
if (data[0] & 0x40)
|
|
|
|
rep->flags |= MEAS_REP_F_UL_DTX;
|
|
|
|
if ((data[1] & 0x40) == 0x00)
|
|
|
|
rep->flags |= MEAS_REP_F_DL_VALID;
|
|
|
|
|
|
|
|
rep->dl.full.rx_lev = data[0] & 0x3f;
|
|
|
|
rep->dl.sub.rx_lev = data[1] & 0x3f;
|
2012-12-25 12:06:27 +00:00
|
|
|
rep->dl.full.rx_qual = (data[2] >> 4) & 0x7;
|
|
|
|
rep->dl.sub.rx_qual = (data[2] >> 1) & 0x7;
|
2009-12-22 06:45:17 +00:00
|
|
|
|
|
|
|
rep->num_cell = ((data[3] >> 6) & 0x3) | ((data[2] & 0x01) << 2);
|
2018-03-08 02:17:48 +00:00
|
|
|
if (rep->num_cell < 1 || rep->num_cell > 6) {
|
|
|
|
/* There are no neighbor cell reports present. */
|
|
|
|
rep->num_cell = 0;
|
2009-12-22 06:45:17 +00:00
|
|
|
return 0;
|
2018-03-08 02:17:48 +00:00
|
|
|
}
|
2009-12-22 06:45:17 +00:00
|
|
|
|
|
|
|
/* an encoding nightmare in perfection */
|
2009-12-25 21:46:25 +00:00
|
|
|
mrc = &rep->cell[0];
|
|
|
|
mrc->rxlev = data[3] & 0x3f;
|
2009-12-25 21:49:34 +00:00
|
|
|
mrc->neigh_idx = data[4] >> 3;
|
2009-12-25 22:01:54 +00:00
|
|
|
mrc->arfcn = bitvec_get_nth_set_bit(nbv, mrc->neigh_idx + 1);
|
2009-12-25 21:46:25 +00:00
|
|
|
mrc->bsic = ((data[4] & 0x07) << 3) | (data[5] >> 5);
|
2009-12-22 06:45:17 +00:00
|
|
|
if (rep->num_cell < 2)
|
|
|
|
return 0;
|
|
|
|
|
2009-12-25 21:46:25 +00:00
|
|
|
mrc = &rep->cell[1];
|
|
|
|
mrc->rxlev = ((data[5] & 0x1f) << 1) | (data[6] >> 7);
|
2009-12-25 21:49:34 +00:00
|
|
|
mrc->neigh_idx = (data[6] >> 2) & 0x1f;
|
2009-12-25 22:01:54 +00:00
|
|
|
mrc->arfcn = bitvec_get_nth_set_bit(nbv, mrc->neigh_idx + 1);
|
2009-12-25 21:46:25 +00:00
|
|
|
mrc->bsic = ((data[6] & 0x03) << 4) | (data[7] >> 4);
|
2009-12-22 06:45:17 +00:00
|
|
|
if (rep->num_cell < 3)
|
|
|
|
return 0;
|
|
|
|
|
2009-12-25 21:46:25 +00:00
|
|
|
mrc = &rep->cell[2];
|
|
|
|
mrc->rxlev = ((data[7] & 0x0f) << 2) | (data[8] >> 6);
|
2009-12-25 21:49:34 +00:00
|
|
|
mrc->neigh_idx = (data[8] >> 1) & 0x1f;
|
2009-12-25 22:01:54 +00:00
|
|
|
mrc->arfcn = bitvec_get_nth_set_bit(nbv, mrc->neigh_idx + 1);
|
2009-12-26 13:12:43 +00:00
|
|
|
mrc->bsic = ((data[8] & 0x01) << 5) | (data[9] >> 3);
|
2009-12-22 06:45:17 +00:00
|
|
|
if (rep->num_cell < 4)
|
|
|
|
return 0;
|
|
|
|
|
2009-12-25 21:46:25 +00:00
|
|
|
mrc = &rep->cell[3];
|
|
|
|
mrc->rxlev = ((data[9] & 0x07) << 3) | (data[10] >> 5);
|
2009-12-25 21:49:34 +00:00
|
|
|
mrc->neigh_idx = data[10] & 0x1f;
|
2009-12-25 22:01:54 +00:00
|
|
|
mrc->arfcn = bitvec_get_nth_set_bit(nbv, mrc->neigh_idx + 1);
|
2009-12-25 21:46:25 +00:00
|
|
|
mrc->bsic = data[11] >> 2;
|
2009-12-22 06:45:17 +00:00
|
|
|
if (rep->num_cell < 5)
|
|
|
|
return 0;
|
|
|
|
|
2009-12-25 21:46:25 +00:00
|
|
|
mrc = &rep->cell[4];
|
|
|
|
mrc->rxlev = ((data[11] & 0x03) << 4) | (data[12] >> 4);
|
2009-12-25 21:49:34 +00:00
|
|
|
mrc->neigh_idx = ((data[12] & 0xf) << 1) | (data[13] >> 7);
|
2009-12-25 22:01:54 +00:00
|
|
|
mrc->arfcn = bitvec_get_nth_set_bit(nbv, mrc->neigh_idx + 1);
|
2009-12-25 21:46:25 +00:00
|
|
|
mrc->bsic = (data[13] >> 1) & 0x3f;
|
2009-12-22 06:45:17 +00:00
|
|
|
if (rep->num_cell < 6)
|
|
|
|
return 0;
|
|
|
|
|
2009-12-25 21:46:25 +00:00
|
|
|
mrc = &rep->cell[5];
|
2009-12-25 21:49:34 +00:00
|
|
|
mrc->rxlev = ((data[13] & 0x01) << 5) | (data[14] >> 3);
|
|
|
|
mrc->neigh_idx = ((data[14] & 0x07) << 2) | (data[15] >> 6);
|
2009-12-25 22:01:54 +00:00
|
|
|
mrc->arfcn = bitvec_get_nth_set_bit(nbv, mrc->neigh_idx + 1);
|
2009-12-25 21:46:25 +00:00
|
|
|
mrc->bsic = data[15] & 0x3f;
|
2009-12-22 06:45:17 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2010-06-15 11:39:27 +00:00
|
|
|
|
2018-03-17 20:40:32 +00:00
|
|
|
/* 9.1.29 RR Status */
|
|
|
|
struct msgb *gsm48_create_rr_status(uint8_t cause)
|
|
|
|
{
|
|
|
|
struct msgb *msg;
|
|
|
|
struct gsm48_hdr *gh;
|
|
|
|
|
|
|
|
msg = gsm48_msgb_alloc_name("GSM 04.08 RR STATUS");
|
|
|
|
if (!msg)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 1);
|
|
|
|
gh->proto_discr = GSM48_PDISC_RR;
|
|
|
|
gh->msg_type = GSM48_MT_RR_STATUS;
|
|
|
|
gh->data[0] = cause;
|
|
|
|
|
|
|
|
return msg;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* 9.1.29 RR Status */
|
|
|
|
int gsm48_tx_rr_status(struct gsm_subscriber_connection *conn, uint8_t cause)
|
|
|
|
{
|
|
|
|
struct msgb *msg = gsm48_create_rr_status(cause);
|
|
|
|
if (!msg)
|
|
|
|
return -1;
|
2018-06-16 15:20:13 +00:00
|
|
|
gscon_submit_rsl_dtap(conn, msg, 0, 0);
|
|
|
|
return 0;
|
2018-03-17 20:40:32 +00:00
|
|
|
}
|
|
|
|
|
2018-02-13 22:48:24 +00:00
|
|
|
struct msgb *gsm48_create_mm_serv_rej(enum gsm48_reject_value value)
|
|
|
|
{
|
|
|
|
struct msgb *msg;
|
|
|
|
struct gsm48_hdr *gh;
|
|
|
|
|
|
|
|
msg = gsm48_msgb_alloc_name("GSM 04.08 SERV REJ");
|
|
|
|
if (!msg)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 1);
|
|
|
|
gh->proto_discr = GSM48_PDISC_MM;
|
|
|
|
gh->msg_type = GSM48_MT_MM_CM_SERV_REJ;
|
|
|
|
gh->data[0] = value;
|
|
|
|
|
|
|
|
return msg;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct msgb *gsm48_create_loc_upd_rej(uint8_t cause)
|
|
|
|
{
|
|
|
|
struct gsm48_hdr *gh;
|
|
|
|
struct msgb *msg;
|
|
|
|
|
|
|
|
msg = gsm48_msgb_alloc_name("GSM 04.08 LOC UPD REJ");
|
|
|
|
if (!msg)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 1);
|
|
|
|
gh->proto_discr = GSM48_PDISC_MM;
|
|
|
|
gh->msg_type = GSM48_MT_MM_LOC_UPD_REJECT;
|
|
|
|
gh->data[0] = cause;
|
|
|
|
return msg;
|
|
|
|
}
|
|
|
|
|
2018-06-08 16:46:04 +00:00
|
|
|
/* As per TS 03.03 Section 2.2, the IMSI has 'not more than 15 digits' */
|
|
|
|
uint64_t str_to_imsi(const char *imsi_str)
|
|
|
|
{
|
|
|
|
uint64_t ret;
|
|
|
|
|
|
|
|
ret = strtoull(imsi_str, NULL, 10);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
2018-07-24 14:12:45 +00:00
|
|
|
|
|
|
|
static void handle_classmark_chg(struct gsm_subscriber_connection *conn,
|
|
|
|
struct msgb *msg)
|
|
|
|
{
|
|
|
|
struct gsm48_hdr *gh = msgb_l3(msg);
|
|
|
|
unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
|
|
|
|
uint8_t cm2_len, cm3_len = 0;
|
|
|
|
uint8_t *cm2, *cm3 = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
/* classmark 2 */
|
|
|
|
cm2_len = gh->data[0];
|
|
|
|
cm2 = &gh->data[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
|
|
|
|
|
|
|
if (cm2_len > 3) {
|
|
|
|
LOG_LCHAN(msg->lchan, LOGL_ERROR, "CLASSMARK CHANGE: CM2 too long: %u\n", cm2_len);
|
|
|
|
return;
|
|
|
|
}
|
2018-07-24 14:12:45 +00:00
|
|
|
|
|
|
|
if (payload_len > cm2_len + 1) {
|
|
|
|
/* we must have a classmark3 */
|
|
|
|
if (gh->data[cm2_len+1] != 0x20) {
|
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
|
|
|
LOG_LCHAN(msg->lchan, LOGL_ERROR, "CLASSMARK CHANGE: invalid CM3 TAG\n");
|
2018-07-24 14:12:45 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
cm3_len = gh->data[cm2_len+2];
|
|
|
|
cm3 = &gh->data[cm2_len+3];
|
|
|
|
if (cm3_len > 14) {
|
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
|
|
|
LOG_LCHAN(msg->lchan, LOGL_ERROR, "CLASSMARK CHANGE: CM3 too long: %u\n",
|
|
|
|
cm3_len);
|
2018-07-24 14:12:45 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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
|
|
|
LOG_LCHAN(msg->lchan, LOGL_DEBUG, "CLASSMARK CHANGE CM2(len=%u) CM3(len=%u)\n",
|
|
|
|
cm2_len, cm3_len);
|
|
|
|
bsc_cm_update(conn, cm2, cm2_len, cm3, cm3_len);
|
2018-07-24 14:12:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void dispatch_dtap(struct gsm_subscriber_connection *conn,
|
|
|
|
uint8_t link_id, struct msgb *msg)
|
|
|
|
{
|
|
|
|
struct gsm48_hdr *gh;
|
|
|
|
uint8_t pdisc;
|
|
|
|
uint8_t msg_type;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
if (msgb_l3len(msg) < sizeof(*gh)) {
|
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
|
|
|
LOG_LCHAN(msg->lchan, LOGL_ERROR,
|
|
|
|
"Message too short for a GSM48 header (%u)\n", msgb_l3len(msg));
|
2018-07-24 14:12:45 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
gh = msgb_l3(msg);
|
|
|
|
pdisc = gsm48_hdr_pdisc(gh);
|
|
|
|
msg_type = gsm48_hdr_msg_type(gh);
|
|
|
|
|
|
|
|
/* the idea is to handle all RR messages here, and only hand
|
|
|
|
* MM/CC/SMS-CP/LCS up to the MSC. Some messages like PAGING
|
|
|
|
* RESPONSE or CM SERVICE REQUEST will not be covered here, as
|
|
|
|
* they are only possible in the first L3 message of each L2
|
|
|
|
* channel, i.e. 'conn' will not exist and gsm0408_rcvmsg()
|
|
|
|
* will call api->compl_l3() for it */
|
|
|
|
switch (pdisc) {
|
|
|
|
case GSM48_PDISC_RR:
|
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
|
|
|
LOG_LCHAN(msg->lchan, LOGL_DEBUG, "Rx %s\n", gsm48_rr_msg_name(msg_type));
|
2018-07-24 14:12:45 +00:00
|
|
|
switch (msg_type) {
|
|
|
|
case GSM48_MT_RR_GPRS_SUSP_REQ:
|
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
|
|
|
/* do something? */
|
2018-07-24 14:12:45 +00:00
|
|
|
break;
|
|
|
|
case GSM48_MT_RR_STATUS:
|
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
|
|
|
LOG_LCHAN(msg->lchan, LOGL_NOTICE, "RR Status: %s\n", rr_cause_name(gh->data[0]));
|
|
|
|
/* do something? */
|
2018-07-24 14:12:45 +00:00
|
|
|
break;
|
|
|
|
case GSM48_MT_RR_MEAS_REP:
|
|
|
|
/* This shouldn't actually end up here, as RSL treats
|
|
|
|
* L3 Info of 08.58 MEASUREMENT REPORT different by calling
|
|
|
|
* directly into gsm48_parse_meas_rep */
|
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
|
|
|
LOG_LCHAN(msg->lchan, LOGL_ERROR, "DIRECT GSM48 MEASUREMENT REPORT ?!?\n");
|
2018-07-24 14:12:45 +00:00
|
|
|
gsm48_tx_rr_status(conn, GSM48_RR_CAUSE_MSG_TYPE_N_COMPAT);
|
|
|
|
break;
|
|
|
|
case GSM48_MT_RR_HANDO_COMPL:
|
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
|
|
|
/* Chapter 9.1.16 Handover complete */
|
|
|
|
if (!conn->ho.fi)
|
|
|
|
LOG_LCHAN(msg->lchan, LOGL_ERROR,
|
|
|
|
"Rx RR Handover Complete, but no handover is ongoing\n");
|
|
|
|
else
|
|
|
|
osmo_fsm_inst_dispatch(conn->ho.fi, HO_EV_RR_HO_COMPLETE, msg);
|
2018-07-24 14:12:45 +00:00
|
|
|
break;
|
|
|
|
case GSM48_MT_RR_HANDO_FAIL:
|
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
|
|
|
/* Chapter 9.1.17 Handover Failure */
|
|
|
|
if (!conn->ho.fi)
|
|
|
|
LOG_LCHAN(msg->lchan, LOGL_ERROR,
|
|
|
|
"Rx RR Handover Fail, but no handover is ongoing\n");
|
|
|
|
else
|
|
|
|
osmo_fsm_inst_dispatch(conn->ho.fi, HO_EV_RR_HO_FAIL, msg);
|
2018-07-24 14:12:45 +00:00
|
|
|
break;
|
|
|
|
case GSM48_MT_RR_CIPH_M_COMPL:
|
|
|
|
bsc_cipher_mode_compl(conn, msg, conn->lchan->encr.alg_id);
|
|
|
|
break;
|
|
|
|
case GSM48_MT_RR_ASS_COMPL:
|
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 (conn->assignment.fi)
|
|
|
|
osmo_fsm_inst_dispatch(conn->assignment.fi,
|
|
|
|
ASSIGNMENT_EV_RR_ASSIGNMENT_COMPLETE, msg);
|
|
|
|
else
|
|
|
|
LOGPLCHAN(msg->lchan, DRR, LOGL_ERROR,
|
|
|
|
"Rx RR Assignment Complete, but no assignment is ongoing\n");
|
2018-07-24 14:12:45 +00:00
|
|
|
break;
|
|
|
|
case GSM48_MT_RR_ASS_FAIL:
|
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 (conn->assignment.fi)
|
|
|
|
osmo_fsm_inst_dispatch(conn->assignment.fi,
|
|
|
|
ASSIGNMENT_EV_RR_ASSIGNMENT_FAIL, msg);
|
|
|
|
else
|
|
|
|
LOGPLCHAN(msg->lchan, DRR, LOGL_ERROR,
|
|
|
|
"Rx RR Assignment Failure, but no assignment is ongoing\n");
|
2018-07-24 14:12:45 +00:00
|
|
|
break;
|
|
|
|
case GSM48_MT_RR_CHAN_MODE_MODIF_ACK:
|
|
|
|
rc = gsm48_rx_rr_modif_ack(msg);
|
|
|
|
if (rc < 0)
|
2020-08-21 18:47:49 +00:00
|
|
|
osmo_fsm_inst_dispatch(msg->lchan->fi, LCHAN_EV_RR_CHAN_MODE_MODIFY_ERROR, &rc);
|
2018-07-24 14:12:45 +00:00
|
|
|
else
|
2020-08-21 18:47:49 +00:00
|
|
|
osmo_fsm_inst_dispatch(msg->lchan->fi, LCHAN_EV_RR_CHAN_MODE_MODIFY_ACK, msg);
|
2018-07-24 14:12:45 +00:00
|
|
|
break;
|
|
|
|
case GSM48_MT_RR_CLSM_CHG:
|
|
|
|
handle_classmark_chg(conn, msg);
|
|
|
|
break;
|
|
|
|
case GSM48_MT_RR_APP_INFO:
|
|
|
|
/* Passing RR APP INFO to MSC, not quite
|
|
|
|
* according to spec */
|
|
|
|
bsc_dtap(conn, link_id, msg);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
/* Drop unknown RR message */
|
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
|
|
|
LOG_LCHAN(msg->lchan, LOGL_NOTICE, "Unknown RR message: %s\n",
|
|
|
|
gsm48_rr_msg_name(msg_type));
|
2018-07-24 14:12:45 +00:00
|
|
|
gsm48_tx_rr_status(conn, GSM48_RR_CAUSE_MSG_TYPE_N);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
2020-07-16 15:02:54 +00:00
|
|
|
case GSM48_PDISC_CC:
|
|
|
|
/* Make sure that EMERGENCY CALLS can not be made if the
|
|
|
|
* VTY configuration does not permit. */
|
|
|
|
if (msg_type == GSM48_MT_CC_EMERG_SETUP) {
|
|
|
|
if (msg->lchan->ts->trx->bts->si_common.rach_control.t2 & 0x4) {
|
|
|
|
LOG_LCHAN(msg->lchan, LOGL_NOTICE, "MS attempts EMERGENCY SETUP although EMERGENCY CALLS"
|
|
|
|
" are not allowed in sysinfo (spec violation by MS!)\n");
|
2021-04-12 18:19:30 +00:00
|
|
|
lchan_release(msg->lchan, true, true, GSM48_RR_CAUSE_PREMPTIVE_REL,
|
|
|
|
gscon_last_eutran_plmn(msg->lchan->conn));
|
2020-07-16 15:02:54 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (!conn->sccp.msc->allow_emerg) {
|
|
|
|
LOG_LCHAN(msg->lchan, LOGL_NOTICE, "MS attempts EMERGENCY SETUP, but EMERGENCY CALLS are"
|
|
|
|
" denied on this BSC (check BTS config!)\n");
|
2021-04-12 18:19:30 +00:00
|
|
|
lchan_release(msg->lchan, true, true, GSM48_RR_CAUSE_PREMPTIVE_REL,
|
|
|
|
gscon_last_eutran_plmn(msg->lchan->conn));
|
2020-07-16 15:02:54 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* fall through */
|
2018-07-24 14:12:45 +00:00
|
|
|
default:
|
|
|
|
bsc_dtap(conn, link_id, msg);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*! \brief RSL has received a DATA INDICATION with L3 from MS */
|
|
|
|
int gsm0408_rcvmsg(struct msgb *msg, uint8_t link_id)
|
|
|
|
{
|
|
|
|
struct gsm_lchan *lchan;
|
|
|
|
|
|
|
|
lchan = msg->lchan;
|
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 (!lchan_may_receive_data(lchan)) {
|
|
|
|
LOG_LCHAN(msg->lchan, LOGL_INFO, "Got data in non active state, discarding.\n");
|
2020-05-24 18:32:57 +00:00
|
|
|
return 0;
|
2018-07-24 14:12:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (lchan->conn) {
|
|
|
|
/* if we already have a connection, forward via DTAP to
|
|
|
|
* MSC */
|
|
|
|
dispatch_dtap(lchan->conn, link_id, msg);
|
|
|
|
} else {
|
2020-09-11 23:35:28 +00:00
|
|
|
return bsc_compl_l3(lchan, msg, 0);
|
2018-07-24 14:12:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|