Change in osmo-bsc[master]: doc: add msc charts on Assignment/Handover internals

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

Neels Hofmeyr gerrit-no-reply at lists.osmocom.org
Mon May 28 16:00:48 UTC 2018


Neels Hofmeyr has submitted this change and it was merged. ( https://gerrit.osmocom.org/9350 )

Change subject: doc: add msc charts on Assignment/Handover internals
......................................................................

doc: add msc charts on Assignment/Handover internals

In doc/, add two message sequence charts with lots of implementation specifics,
to clarify the current code state. Mark various problems in red notes.

This chart and others should help to illustrate future code changes as I go
along refactoring handover, lchan allocation and adding inter-BSC handover.

Change-Id: I20999e938441d4fed2d37462b262b74a696f616d
---
M doc/Makefile.am
A doc/assignment.msc
A doc/handover.msc
3 files changed, 357 insertions(+), 0 deletions(-)

Approvals:
  Jenkins Builder: Verified
  Harald Welte: Looks good to me, approved



diff --git a/doc/Makefile.am b/doc/Makefile.am
index 5a23107..cc2e277 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -1,3 +1,15 @@
 SUBDIRS = \
 	examples \
 	$(NULL)
+
+msc: \
+	$(builddir)/handover.png \
+	$(builddir)/assignment.png \
+	$(NULL)
+
+$(builddir)/%.png: $(srcdir)/%.msc
+	mscgen -T png -o $@ $<
+
+.PHONY: poll
+poll:
+	while true; do $(MAKE) msc; sleep 1; done
diff --git a/doc/assignment.msc b/doc/assignment.msc
new file mode 100644
index 0000000..e2bdf84
--- /dev/null
+++ b/doc/assignment.msc
@@ -0,0 +1,181 @@
+msc {
+	hscale=3;
+	ms [label="MS"], bts [label="BTS"], bsc[label="BSC"], bsc_gscon[label="BSC conn FSM"], bsc_mgcp[label="BSC mgcp FSM"], mgw[label="MGW"], msc_[label="MSC"];
+
+	ms note msc_ [label="lchan allocation sequence for BSSMAP Assignment Request"];
+
+	bsc <= msc_ [label="BSSMAP Assignment Request"];
+	bsc box bsc [label="bssmap_handle_assignm_req()"];
+	bsc -> bsc_gscon [label="GSCON_EV_A_ASSIGNMENT_CMD"];
+
+	--- [label="is the chan_mode a speech mode?"];
+
+	bsc_gscon abox bsc_gscon [label="ST_WAIT_CRCX_BTS (MGCP_MGW_TIMEOUT = 4s)"];
+	bsc_gscon -> bsc_mgcp [label="mgcp_conn_create()"];
+	bsc_mgcp => mgw [label="CRCX (for BTS)"];
+	bsc_mgcp abox bsc_mgcp [label="ST_CRCX (MGCP_MGW_TIMEOUT = 4s)"];
+	bsc_gscon note bsc_mgcp [label="two timeouts running in parallel"];
+	bsc_gscon note bsc_mgcp [label="note: #define MGCP_MGW_TIMEOUT exists twice,
+				       once in libosmo-mgcp-client,
+				       once in bsc_subscr_conn_fsm.c"];
+	bsc_mgcp -> bsc_gscon [label="mgcp_conn_create() exits"];
+	bsc_gscon -> bsc [label="bssmap_handle_assignm_req() exits"];
+	...;
+	--- [label="On Timeout"];
+	bsc_gscon note bsc_gscon [label="The conn FSM likely timeouts first"];
+	bsc_gscon => msc_ [label="BSSMAP Assignment Failure"];
+	bsc_gscon abox bsc_gscon [label="ST_ACTIVE"];
+	bsc_mgcp note bsc_mgcp [label="The MGCP FSM will timeout right after that, and terminate itself,
+				      emitting the parent_term event set upon mgcp_conn_create():"];
+	bsc_mgcp -> bsc_gscon [label="GSCON_EV_MGW_FAIL_BTS"];
+	bsc_gscon note bsc_gscon [label="GSCON_EV_MGW_FAIL_BTS is handled by the conn FSM allstate
+					handler. It sets conn->user_plane.fi_bts = NULL. There is code
+					that would emit a BSSMAP Assignment Failure, but not in
+					ST_ACTIVE"];
+	--- [label="end: 'On Timeout'"];
+	...;
+
+	bsc_mgcp <= mgw [label="CRCX OK (for BTS)"];
+	bsc_mgcp box bsc_mgcp [label="libosmo-mgcp-client fsm_crcx_resp_cb()"];
+	bsc_mgcp -> bsc_gscon [label="GSCON_EV_MGW_CRCX_RESP_BTS"];
+	--- [label="end: 'is the chan_mode a speech mode?'"];
+
+	bsc_gscon note bsc_gscon [label="for mode=sign, we're still handling GSCON_EV_A_ASSIGNMENT_CMD;
+					 for speech mode, we're handling GSCON_EV_MGW_CRCX_RESP_BTS"];
+	bsc <- bsc_gscon [label="gsm0808_assign_req()"];
+
+	bsc box bsc [label="lchan_alloc(): pick available lchan"];
+	bsc box bsc [label="rsl_chan_activate_lchan()"];
+
+	--- [label="is the chosen lchan on dynamic timeslot that is currently used as PDCH?"];
+	bts <= bsc [label="i) RSL RF Chan Release of PDCH (Osmocom dyn TS)"];
+	bts <= bsc [label="OR ii) RSL PDCH Deact (ip.access dyn TS)"];
+	bsc -> bsc_gscon [label="gsm0808_assign_req() returns early"];
+	bsc_gscon abox bsc_gscon [label="ST_WAIT_ASS_COMPL (GSM0808_T10_VALUE=6s)"];
+	...;
+	bts note bsc_gscon [linecolor="red",
+	  label="There seems to be no timer watching over Chan Release nor dyn TS switchover!"];
+	...;
+	bts => bsc [label="i) RSL RF Chan Release ACK (Osmocom dyn TS)"];
+	bts => bsc [label="OR ii) RSL PDCH Deact ACK (ip.access dyn TS)"];
+	bsc box bsc [label="rsl_chan_activate_lchan() re-invoked"];
+	bts <= bsc [label="RSL Chan Activ"];
+	--- [label="else (no dyn TS switchover)"];
+
+	bts <= bsc [label="RSL Chan Activ"];
+	bsc -> bsc_gscon [label="gsm0808_assign_req() returns"];
+	bsc_gscon abox bsc_gscon [label="ST_WAIT_ASS_COMPL (GSM0808_T10_VALUE=6s)"];
+	---;
+
+	...;
+	--- [label="On Timeout"];
+	bsc_gscon => msc_ [label="BSSMAP Assignment Failure"];
+	bsc_gscon abox bsc_gscon [label="ST_ACTIVE"];
+	bsc_gscon note bsc_mgcp [linecolor="red",
+	  label="The mgcp FSM from CRCX above apparently lacks a cleanup action for this case.
+	         It should be cleaned up eventually when the conn is torn down, but we should
+		 release RTP endpoints as soon as possible."];
+	--- [label="end: 'On Timeout'"];
+	...;
+
+	bts => bsc [label="RSL Chan Activ ACK"];
+	bsc box bsc [label="bsc_api.c handle_chan_ack()"];
+	ms <= bsc [label="RR Assignment Command"];
+
+	...;
+	ms note bsc_gscon [label="We rely on the overall conn FSM ST_WAIT_ASS_COMPL timeout."];
+	...;
+
+	ms => bsc [label="RR Assignment Complete"];
+	bsc box bsc [label="handle_ass_compl()"];
+	--- [label="Release old lchan"];
+	bsc box bsc [label="_lchan_handle_release(sacch_deact=0)"];
+	bsc box bsc [label="rsl_release_sapis_from(start=1)"];
+	bts <= bsc [label="RSL Release Request (Local End)..."];
+	bts <= bsc [label="...for each SAPI except link_id=0"];
+	bsc box bsc [label="rsl_release_request(link_id=0)"];
+	bts <= bsc [label="RSL Release Request (Local End) for link_id=0"];
+	bsc box bsc [label="_lchan_handle_release() returns here, the remaining release is asynchronous;
+	                    see `End: 'Release old lchan'` below."];
+	...;
+	bts note bsc_gscon [linecolor="red",
+	  label="There seems to be no timer watching over RSL Release Request!"];
+	...;
+	bts => bsc [label="RSL Release Confirm..."];
+	bts => bsc [label="...for each SAPI and link_id=0"];
+	bsc abox bsc [label="start T3111"];
+	...;
+	bsc box bsc [label="T3111 expires"];
+	bsc abox bsc [label="Start lchan->act_timer with lchan_deact_tmr_cb"];
+	bts <= bsc [label="RSL RF Channel Release"];
+	...;
+	--- [label="On timeout"];
+	bsc box bsc [label="lchan_deact_tmr_cb()"];
+	bsc box bsc [label="rsl_lchan_mark_broken(): state=LCHAN_S_BROKEN"];
+	bsc box bsc [label="lchan_free()"];
+	bsc -> bsc [label="S_LCHAN_UNEXPECTED_RELEASE"];
+	bsc box bsc [label="bsc_api.c handle_release()"];
+	bsc box bsc [label="bsc->assign_fail()"];
+	bsc -> bsc_gscon [label="GSCON_EV_RR_ASS_FAIL"];
+	bsc note bsc_gscon [linecolor="orange",
+	  label="The name 'RR_ASS_FAIL' might suggest the event means an actual RR Assignment
+		 Failure message being received. Maybe this should be called GSCON_EV_ASSIGNMENT_ERROR."];
+	...;
+	bsc box bsc [label="bsc->clear_request()"];
+	bsc box bsc [label="bsc_clear_request encodes a BSSMAP Clear Request message and passes it on
+	                    to the conn FSM as data argument via:"];
+	bsc -> bsc_gscon [label="GSCON_EV_TX_SCCP"];
+	bsc_gscon => msc_ [label="BSSMAP Clear Request"];
+	bsc note bsc_gscon [linecolor="red",
+	  label="Instead of sending an arbitrary message, the conn FSM should
+		 be explicitly instructed to clear the connection, to be able
+		 to notice if the MSC failed to respond to the Clear Request.
+		 Currently, this relies on the MSC responding with a Clear
+		 Command, hopefully, some time later."];
+	--- [label="End: 'On timeout'"];
+	...;
+	bts => bsc [label="RSL RF Channel Release Ack"];
+	--- [label="End: 'Release old lchan'"];
+	bsc box bsc [label="still in handle_ass_compl()"];
+	bsc note bsc [label="officially take over new lchan: conn->lchan = conn->secondary_lchan"];
+	--- [label="is BTS using IPA Abis? (osmo-bts, ip.access)"];
+	bts <= bsc [label="IPACC CRCX"];
+	---;
+	bsc -> bsc [label="handle_ass_compl() calls bsc_api->assign_compl()"];
+	--- [label="is BTS using IPA Abis? (osmo-bts, ip.access) && conn->user_plane.rtp_ip"];
+	bsc box bsc [label="bsc_assign_compl()"];
+	bsc note bsc [label="set ass_compl.valid = true,
+			    postponing GSCON_EV_RR_ASS_COMPL until after the
+			    IPACC MDCX ACK received in osmo_bsc_audio.c"];
+	bsc box bsc [label="exit early: bsc_assign_compl()"];
+	bsc box bsc [label="exit early: handle_ass_compl()"];
+	bsc box bsc [label="osmo_bsc_audio.c"];
+	bts => bsc [label="IPACC CRCX ACK"];
+	bts <= bsc [label="IPACC MDCX"];
+	bts => bsc [label="IPACC MDCX ACK"];
+	bsc box bsc [label="handle_abisip_signal()"];
+	bsc -> bsc_gscon [label="GSCON_EV_RR_ASS_COMPL"];
+	--- [label="else"];
+	bsc box bsc [label="bsc_assign_compl()"];
+	bsc -> bsc_gscon [label="GSCON_EV_RR_ASS_COMPL"];
+	--- ;
+
+	--- [label="is chan_mode a speech mode?"];
+	bsc_gscon abox bsc_gscon [label="ST_WAIT_MDCX_BTS"];
+	bsc_gscon -> bsc_mgcp [label="mgcp_conn_modify()"];
+	bsc_mgcp note bsc_mgcp [label="same mgcp FSM as above, for BTS side"];
+	bsc_mgcp => mgw [label="MDCX (for BTS)"];
+	bsc_mgcp <= mgw [label="MDCX OK"];
+	bsc_mgcp -> bsc_gscon [label="GSCON_EV_MGW_MDCX_RESP_BTS"];
+	bsc_gscon abox bsc_gscon [label="ST_WAIT_CRCX_MSC"];
+	bsc_gscon -> bsc_mgcp [label="mgcp_conn_create()"];
+	bsc_mgcp note bsc_mgcp [label="second mgcp FSM for MSC side"];
+	bsc_mgcp => mgw [label="CRCX (for MSC)"];
+	bsc_mgcp <= mgw [label="CRCX OK (for MSC)"];
+	bsc_gscon <- bsc_mgcp [label="GSCON_EV_MGW_CRCX_RESP_MSC"];
+	---;
+
+	bsc_gscon => msc_ [label="BSSMAP Assignment Complete"];
+
+	bsc_gscon abox bsc_gscon [label="ST_ACTIVE"];
+}
diff --git a/doc/handover.msc b/doc/handover.msc
new file mode 100644
index 0000000..e5e787c
--- /dev/null
+++ b/doc/handover.msc
@@ -0,0 +1,164 @@
+# Handover between cells, intra-BSC
+msc {
+	hscale=3;
+	ms [label="MS"], bts [label="BTS"], bsc[label="BSC"], bsc_gscon[label="BSC conn FSM"], bsc_mgcp[label="BSC mgcp FSM"], mgw[label="MGW"];
+
+	ms note mgw [label="intra-BSC Handover sequence"];
+
+	bsc_gscon abox bsc_gscon [label="ST_ACTIVE"];
+	bsc box bsc [label="bsc_handover_start(): init conn->ho"];
+	bsc -> bsc_gscon [label="GSCON_EV_HO_START"];
+	bsc <- bsc_gscon [label="bsc_handover_start_gscon()"];
+
+	bsc box bsc [label="lchan_alloc(): pick available lchan"];
+	bsc box bsc [label="rsl_chan_activate_lchan()"];
+
+	--- [label="is the chosen lchan on dynamic timeslot that is currently used as PDCH?"];
+	bts <= bsc [label="i) RSL RF Chan Release of PDCH (Osmocom dyn TS)"];
+	bts <= bsc [label="OR ii) RSL PDCH Deact (ip.access dyn TS)"];
+	bsc -> bsc_gscon [label="bsc_handover_start_gscon() returns early"];
+	bsc_gscon abox bsc_gscon [label="ST_WAIT_HO_COMPL (no timeout, relies on T3103 below)"];
+	...;
+	bts note bsc_gscon [linecolor="red",
+	  label="There seems to be no timer watching over Chan Release nor dyn TS switchover!"];
+	...;
+	bts => bsc [label="i) RSL RF Chan Release ACK (Osmocom dyn TS)"];
+	bts => bsc [label="OR ii) RSL PDCH Deact ACK (ip.access dyn TS)"];
+	bsc box bsc [label="rsl_chan_activate_lchan() re-invoked"];
+	bts <= bsc [label="RSL Chan Activ"];
+	--- [label="else (no dyn TS switchover)"];
+
+	bts <= bsc [label="RSL Chan Activ"];
+	bsc -> bsc_gscon [label="bsc_handover_start_gscon() returns"];
+	---;
+	bsc_gscon abox bsc_gscon [label="ST_WAIT_HO_COMPL (no timeout, relies on T3103 below)"];
+
+	...;
+	bts note bsc_gscon [linecolor="red",
+	  label="There seems to be no timer watching out for RSL Chan Activ ACK/NACK!"];
+	...;
+	bts => bsc [label="RSL Chan Activ ACK"];
+	bsc -> bsc [label="S_LCHAN_ACTIVATE_ACK"];
+	bsc box bsc [label="handover_logic.c ho_logic_sig_cb()"];
+	bsc box bsc [label="ho_chan_activ_ack()"];
+	bsc note bsc [label="gsm48_send_ho_cmd()"];
+	ms <= bsc [label="RR Handover Command"];
+	bsc abox bsc [label="start T3103"];
+	--- [label="is BTS using IPA Abis? (osmo-bts, ip.access)"];
+	bts <= bsc [label="IPACC CRCX"];
+	bsc -> bsc [label="ho_chan_activ_ack() returns"];
+	bts note bsc [linecolor="red",
+	  label="There seems to be no timer watching over IPACC CRCX ACK/NACK!
+	         If no response is received, we simply ignore that fact and carry on as if
+		 everything was fine."];
+	...;
+	bts note bsc [label="The IPACC CRCX and MDCX ACKs may come back at any time:
+			     before or after the Handover Detect, before or after Handover Complete."];
+	bts note bsc_mgcp [linecolor="red",
+	  label="The CRCX ACK contains vital information for routing the RTP stream.
+	         If the CRCX ACK were very slow, we would not know which RTP/RTPC ports
+		 to point the MGW at, below at mgcp_conn_modify()!
+		 Even though this being unrealistic, we must make sure to receive a CRCX ACK."];
+	...;
+	bsc box bsc [label="osmo_bsc_audio.c"];
+	bts => bsc [label="IPACC CRCX ACK"];
+	bts <= bsc [label="IPACC MDCX"];
+	...;
+	bts note bsc [linecolor="red",
+	  label="There seems to be no timer watching over IPACC MDCX ACK/NACK!
+	         If no response is received, we simply ignore that fact and carry on as if
+		 everything was fine."];
+	...;
+	bts => bsc [label="IPACC MDCX ACK"];
+	bts note bsc [label="IPACC MDCX ACK triggers no events or actions"];
+	---;
+
+	...;
+	ms => bsc [label="RR Handover Detect"];
+	bsc -> bsc [label="S_LCHAN_HANDOVER_DETECT"];
+	bsc box bsc [label="ho_rsl_detect(): no action, only logging"];
+	bsc note bsc_gscon [label="Handover Detect triggers no events or actions"];
+	bsc note bsc_gscon [linecolor="red",
+	  label="upon Handover Detect, we should already start re-routing the RTP!
+	         Instead we wait for Handover Complete."];
+
+	...;
+	ms => bsc [label="RR Handover Complete"];
+	bsc -> bsc [label="S_LCHAN_HANDOVER_COMPL"];
+	bsc box bsc [label="handover_logic.c ho_logic_sig_cb()"];
+	bsc box bsc [label="ho_gsm48_ho_compl()"];
+	bsc box bsc [label="stop T3103"];
+	bts note bsc_gscon [label="If anything goes wrong from this point on, we will not move back
+	                           to the old lchan: would be pointless after Handover Complete."];
+	bsc note bsc [label="officially take over new lchan: conn->lchan = ho->new_lchan"];
+
+	--- [label="Release old lchan"];
+	bsc box bsc [label="_lchan_handle_release(sacch_deact=0)"];
+	bsc box bsc [label="rsl_release_sapis_from(start=1)"];
+	bts <= bsc [label="RSL Release Request (Local End)..."];
+	bts <= bsc [label="...for each SAPI except link_id=0"];
+	bsc box bsc [label="rsl_release_request(link_id=0)"];
+	bts <= bsc [label="RSL Release Request (Local End) for link_id=0"];
+	bsc box bsc [label="_lchan_handle_release() returns here, the remaining release is asynchronous;
+	                    see `End: 'Release old lchan'` below."];
+	...;
+	bts note bsc_gscon [linecolor="red",
+	  label="There seems to be no timer watching over RSL Release Request!"];
+	...;
+	bts => bsc [label="RSL Release Confirm..."];
+	bts => bsc [label="...for each SAPI and link_id=0"];
+	bsc abox bsc [label="start T3111"];
+	...;
+	bsc box bsc [label="T3111 expires"];
+	bsc abox bsc [label="Start lchan->act_timer with lchan_deact_tmr_cb"];
+	bts <= bsc [label="RSL RF Channel Release"];
+	...;
+	--- [label="On timeout"];
+	bsc box bsc [label="lchan_deact_tmr_cb()"];
+	bsc box bsc [label="rsl_lchan_mark_broken(): state=LCHAN_S_BROKEN"];
+	bsc box bsc [label="lchan_free()"];
+	bsc -> bsc [label="S_LCHAN_UNEXPECTED_RELEASE"];
+	bsc box bsc [label="bsc_api.c handle_release()"];
+	bsc box bsc [label="bsc->clear_request()"];
+	bsc box bsc [label="bsc_clear_request encodes a BSSMAP Clear Request message and passes it on
+	                    to the conn FSM as data argument via:"];
+	bsc -> bsc_gscon [label="GSCON_EV_TX_SCCP"];
+	bsc_gscon rbox bsc_gscon [label="BSSMAP Clear Request to MSC"];
+	bsc note bsc_gscon [linecolor="red",
+	  label="During Handover, we actually release the entire conn just because we failed to
+	         gracefully release the old lchan. That is obviously nonsense."];
+	bsc note bsc [label="Stop T3101 (but was not active in this code path)"];
+	bsc -> bsc [label="S_CHALLOC_FREED"];
+	--- [label="End: 'On timeout'"];
+	...;
+	bts => bsc [label="RSL RF Channel Release Ack"];
+	---;
+
+	bsc box bsc [label="still in ho_gsm48_ho_compl()"];
+	bsc note bsc [label="handover_free(), conn->ho = NULL"];
+	bsc -> bsc_gscon [label="GSCON_EV_HO_COMPL"];
+	bsc note bsc_gscon [linecolor="orange",
+	  label="Handover information is cleared before signalling the conn FSM.
+	         That means the conn FSM cannot possibly log sensible information about exactly
+		 which Handover has just completed."];
+
+	bsc_gscon abox bsc_gscon [label="ST_WAIT_MDCX_BTS_HO
+					 (MGCP_MGW_TIMEOUT=4s with MGCP_MGW_HO_TIMEOUT_TIMER_NR)"];
+
+	bsc_gscon -> bsc_mgcp [label="mgcp_conn_modify()"];
+	bsc_mgcp note bsc_mgcp [label="mgcp FSM that was established for old lchan, for BTS side"];
+	bsc_mgcp => mgw [label="MDCX (for BTS)"];
+	...;
+	bsc_gscon note mgw [
+	  label="If we get no MDCX ACK, the MGCP FSM terminates, and emits GSCON_EV_MGW_FAIL_BTS.
+		 Besides invalidating the MGCP FSM pointer, this event has no
+		 effect in ST_WAIT_MDCX_BTS_HO, and we rely on above conn FSM
+		 timeout instead."];
+	bsc_gscon note bsc_gscon [linecolor="red",
+	  label="A timeout of ST_WAIT_MDCX_BTS_HO simply transitions back to ST_ACTIVE!
+	         Even though the MGW failed, we carry on as if everything were fine."];
+	...;
+	bsc_mgcp <= mgw [label="MDCX OK"];
+	bsc_mgcp -> bsc_gscon [label="GSCON_EV_MGW_MDCX_RESP_BTS"];
+	bsc_gscon abox bsc_gscon [label="ST_ACTIVE"];
+}

-- 
To view, visit https://gerrit.osmocom.org/9350
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-bsc
Gerrit-Branch: master
Gerrit-MessageType: merged
Gerrit-Change-Id: I20999e938441d4fed2d37462b262b74a696f616d
Gerrit-Change-Number: 9350
Gerrit-PatchSet: 3
Gerrit-Owner: Neels Hofmeyr <nhofmeyr at sysmocom.de>
Gerrit-Reviewer: Harald Welte <laforge at gnumonks.org>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: Neels Hofmeyr <nhofmeyr at sysmocom.de>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20180528/d4397ff2/attachment.htm>


More information about the gerrit-log mailing list