aboutsummaryrefslogtreecommitdiffstats
path: root/doc/lchan-release.msc
blob: f75b559c1987e947872e28e054272f65d4e49cda (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
msc {
	hscale=2;
	ms [label="MS"], bts [label="BTS"], bsc[label="BSC"], bsc_gscon[label="BSC conn FSM"];

	ms note bsc_gscon [label="various lchan release scenarios"];
	

	ms rbox bsc_gscon [label="IF BSC releases, from BSSMAP Clear Request"];
	bsc note bsc [label="lchan_release() may be called with sacch_deact=true or false.
		Currently, the only time lchan_release(sacch_deact=true) is invoked is upon BSSMAP Clear
		Command, i.e. when the MSC instructs to stop using an active lchan.
		Some error handling code paths however directly invoke
		rsl_rf_chan_release(error=1, SACCH_DEACTIVATE)."];

	---;
	bsc_gscon note bsc_gscon [label="Rx: BSSMAP Clear Request from MSC"];
	bsc <- bsc_gscon [label="gsm0808_clear()"];
	bsc box bsc [label="lchan_release(sacch_deact=1)"];
	bsc box bsc [label="lchan->state = LCHAN_S_REL_REQ"];
	bsc box bsc [label="_lchan_handle_release(sacch_deact=1)"];
	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"];
	ms <= bsc [label="RR Channel Release"];
	ms note bsc [label="There is no ACK for RR Channel Release"];
	bsc box bsc [label="rsl_deact_sacch()"];
	bts <= bsc [label="RSL Deactivate SACCH"];
	bsc abox bsc [label="Start T3109 (net->T3109, t3109_expired())"];
	...;
	--- [label="If T3109 expires"];
	bsc box bsc [label="t3109_expired()"];
	bsc box bsc [label="rsl_rf_chan_release(error=1)"];
	bts <= bsc [label="RSL Release Request (Local End)..."];
	bts <= bsc [label="...for each SAPI, except link_id=0"];
	bsc box bsc [label="lchan->state = LCHAN_S_REL_REQ"];
	bts <= bsc [label="RSL RF Channel Release"];
	---;
	...;
	bsc rbox bsc [label="continue in the 'Common' part"];
	--- [label="END: 'BSSMAP Clear Request'"];
	...;
	...;

	ms rbox bsc_gscon [label="IF BSC releases, from implicitly unused lchan"];
	bsc note bsc [label="The BSC may release old unused lchans after Handover, or release lchans
		after some error condition."];
	bsc note bsc [label="BSC decides to release an unused lchan"];
	bsc box bsc [label="lchan_release(sacch_deact=0)"];
	bsc box bsc [label="lchan->state = LCHAN_S_REL_REQ"];
	bsc box bsc [label="_lchan_handle_release(sacch_deact=0)"];
	bts <= bsc [label="RSL Release Request (Local End)..."];
	bts <= bsc [label="...for all SAPIs"];
	...;
	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 all SAPIs"];
	bsc rbox bsc [label="continue in the 'Common' part"];
	---;
	...;
	...;

	ms rbox bsc_gscon [label="IF MS releases"];
	ms => bts [label="DISC"];
	bts => bsc [label="RLL Release Ind..."];
	bts => bsc [label="...for each SAPI"];
	bsc rbox bsc [label="continue in the 'Common' part"];
	---;
	...;
	...;
	ms rbox bsc_gscon [label="Common"];
	--- [label="for each SAPI (?)"];
	bts => bsc [label="RLL Release Confirm / RLL Release Ind"];
	bsc box bsc [label="abis_rsl_rx_rll()"];
	bsc box bsc [label="mark lchan->sapis[link_id] = LCHAN_SAPI_UNUSED"];
	bsc box bsc [label="rll_indication()"];
	bsc box bsc [label="for each bsc_rll_req matching this link_id:
		disable timer, call cb(BSC_RLLR_IND_REL_IND)"];
	bsc box bsc [label="rsl_handle_release()"];
	--- [label="IF all SAPIs are unused"];
	bsc box bsc [label="Stop T3109"];
	bsc note bsc [label="T3109 was started if the MSC requested the release"];
	bsc abox bsc [label="Start T3111 (net->T3111 value, t3111_expired())"];
	--- [label="END: all SAPIs are unused"];
	bsc -> bsc_gscon [label="GSCON_EV_RLL_REL_IND (only if RLL Release Ind)"];
	--- [label="END: for each SAPI"];

	...;
	bsc box bsc [label="T3111 expires"];
	bsc box bsc [label="rsl_rf_chan_release()"];
	bsc box bsc [label="Stop T3109"];
	bsc note bsc [label="[If lchan->state is LCHAN_S_REL_ERR, don't do anything]"];
	bsc abox bsc [label="Start lchan->act_timer (4s, lchan_deact_tmr_cb())"];
	bts <= bsc [label="RSL RF Channel Release"];

	...;
	--- [label="IF lchan->act_timer expires"];
	bsc box bsc [label="lchan_deact_tmr_cb()"];
	bsc box bsc [label="rsl_lchan_mark_broken(): lchan->state = LCHAN_S_BROKEN"];
	bsc box bsc [label="lchan_free() (see below)"];
	--- [label="END: 'lchan->act_timer expires'"];
	...;

	bts => bsc [label="RSL RF Channel Release ACK"];
	bsc box bsc [label="rsl_rx_rf_chan_rel_ack()"];
	bsc box bsc [label="Stop lchan->act_timer"];
	bsc box bsc [label="Stop T3111"];

	--- [label="IF lchan->state == LCHAN_S_BROKEN"];
	bsc note bsc [label="If an ACK comes in late, for specific BTS models, we may choose to 'repair'
		the lchan so that it is usable again, by calling do_lchan_free() directly (see below)."];
	bsc box bsc [label="rsl_rx_rf_chan_rel_ack() exits here and none of below actions happen.
		The lchan remains LCHAN_S_BROKEN indefinitely."];
	--- [label="END: lchan->state == LCHAN_S_BROKEN"];
	bsc box bsc [label="do_lchan_free()"];
	--- [label="IF lchan->state == LCHAN_S_REL_ERR"];
	bsc note bsc [label="If release failed, we take the lchan back into operation after due
		timeout"];
	bsc abox bsc [label="Start lchan->error_timer (T3111+2, error_timeout_cb())"];
	bsc note bsc [label="do_lchan_free() continues, async:"];
	...;
	bsc box bsc [label="error_timeout_cb()"];
	bsc box bsc [label="lchan->state = LCHAN_S_NONE"];
	bsc box bsc [label="dyn TS: activate PDCH..."];
	--- [label="ELSE"];
	bsc box bsc [label="lchan->state = LCHAN_S_NONE"];
	--- [label="END: lchan->state == LCHAN_S_REL_ERR"];
	bsc box bsc [label="lchan_free()"];
	--- [label="IF conn is still associated (and not dyn TS in switchover)"];
	bsc -> bsc [label="S_LCHAN_UNEXPECTED_RELEASE"];
	bsc box bsc [label="handle_release()"];
	bsc box bsc [label="Stop T10"];
	bsc note bsc [linecolor=orange,label="conn->T10 is actually dead code, it is never started.
		Instead, the conn FSM starts ST_WAIT_ASS_COMPL with a T10 value."];
	bsc -> bsc_gscon [label="GSCON_EV_RR_ASS_FAIL"];
	bsc -> bsc_gscon [label="GSCON_EV_TX_SCCP: BSSMAP Clear Request"];
	bsc box bsc [label="bsc_clear_handover()"];
	bsc box bsc [label="Stop T3103"];
	bsc box bsc [label="free handover struct"];
	bsc box bsc [label="lchan->conn = NULL"];
	--- [label="END: 'conn is still associated'"];
	bsc box bsc [label="Stop T3101"];
	bsc note bsc [label="T3101 is started when sending an RR Immediate Assignment"];
	bsc -> bsc [label="S_CHALLOC_FREED"];
	bsc -> bsc [label="rll_lchan_signal()"];
	bsc box bsc [label="for each bsc_rll_req matching this lchan:
		disable timer, call cb(BSC_RLLR_IND_REL_IND)"];
}