aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/Makefile.am12
-rw-r--r--doc/assignment.msc181
-rw-r--r--doc/handover.msc164
3 files changed, 357 insertions, 0 deletions
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 5a231074c..cc2e277b5 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 000000000..e2bdf845d
--- /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 000000000..e5e787c0e
--- /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"];
+}