aboutsummaryrefslogtreecommitdiffstats
path: root/doc/handover.msc
blob: 8862dd97b98de0680eea7ed85f761d96358cc0b7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# 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="Osmocom style dyn TS use lchan->act_timer to watch over RF Chan Release, but there
		seems to be no timer watching over PDCH Deact!"];
	...;
	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 box bsc [label="rsl_rx_chan_act_ack()"];
	bsc box bsc [label="Stop lchan->act_timer"];
	bsc box bsc [label="lchan->state = LCHAN_S_ACTIVE"];
	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="Stop lchan->act_timer"];
	bsc box bsc [label="Stop lchan->T3111"];
	---;

	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"];
}