<p>Neels Hofmeyr <strong>merged</strong> this change.</p><p><a href="https://gerrit.osmocom.org/9667">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Jenkins Builder: Verified
  Harald Welte: Looks good to me, approved

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">doc: update/fix FSM charts<br><br>These reflect the plan for refactoring, and will be implemented by<br>I82e3f918295daa83274a4cf803f046979f284366 and<br>Id7a4407d9b63be05ce63f5f2768b7d7e3d5c86fb<br><br>Change-Id: I29e31b753e23a4207662e0e385a337e7df836f45<br>---<br>M doc/Makefile.am<br>A doc/assignment-fsm.dot<br>M doc/assignment.msc<br>A doc/handover-inter-bsc-in-fsm.dot<br>A doc/handover-inter-bsc-in.msc<br>D doc/handover-inter-bsc-mo.msc<br>D doc/handover-inter-bsc-mt.msc<br>A doc/handover-inter-bsc-out-fsm.dot<br>A doc/handover-inter-bsc-out.msc<br>A doc/handover-intra-bsc-fsm.dot<br>M doc/handover.msc<br>M doc/lchan-fsm.dot<br>D doc/lchan-release.msc<br>A doc/lchan-rtp-fsm.dot<br>M doc/lchan.msc<br>A doc/legend_for_fsm_diagrams.dot<br>A doc/legend_for_ladder_diagrams.msc<br>A doc/mgw-endpoint-fsm.dot<br>A doc/mgw-endpoint.msc<br>D doc/ms-channel-request.msc<br>M doc/timeslot-fsm.dot<br>M doc/timeslot.msc<br>M doc/ts-and-lchan-fsm-lifecycle.msc<br>23 files changed, 833 insertions(+), 865 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/doc/Makefile.am b/doc/Makefile.am</span><br><span>index ca0470d..9b87bf3 100644</span><br><span>--- a/doc/Makefile.am</span><br><span>+++ b/doc/Makefile.am</span><br><span>@@ -3,20 +3,27 @@</span><br><span>   $(NULL)</span><br><span> </span><br><span> msc: \</span><br><span style="color: hsl(120, 100%, 40%);">+ $(builddir)/legend_for_ladder_diagrams.png \</span><br><span>         $(builddir)/handover.png \</span><br><span>   $(builddir)/assignment.png \</span><br><span style="color: hsl(0, 100%, 40%);">-    $(builddir)/lchan-release.png \</span><br><span style="color: hsl(0, 100%, 40%);">- $(builddir)/ms-channel-request.png \</span><br><span>         $(builddir)/timeslot.png \</span><br><span>   $(builddir)/lchan.png \</span><br><span>      $(builddir)/ts-and-lchan-fsm-lifecycle.png \</span><br><span style="color: hsl(0, 100%, 40%);">-    $(builddir)/handover-inter-bsc-mo.png \</span><br><span style="color: hsl(0, 100%, 40%);">- $(builddir)/handover-inter-bsc-mt.png \</span><br><span style="color: hsl(120, 100%, 40%);">+       $(builddir)/handover-inter-bsc-out.png \</span><br><span style="color: hsl(120, 100%, 40%);">+      $(builddir)/handover-inter-bsc-in.png \</span><br><span style="color: hsl(120, 100%, 40%);">+       $(builddir)/mgw-endpoint.png \</span><br><span>       $(NULL)</span><br><span> </span><br><span> dot: \</span><br><span style="color: hsl(120, 100%, 40%);">+ $(builddir)/legend_for_fsm_diagrams.png \</span><br><span style="color: hsl(120, 100%, 40%);">+     $(builddir)/assignment-fsm.png \</span><br><span>     $(builddir)/timeslot-fsm.png \</span><br><span>       $(builddir)/lchan-fsm.png \</span><br><span style="color: hsl(120, 100%, 40%);">+   $(builddir)/lchan-rtp-fsm.png \</span><br><span style="color: hsl(120, 100%, 40%);">+       $(builddir)/mgw-endpoint-fsm.png \</span><br><span style="color: hsl(120, 100%, 40%);">+    $(builddir)/handover-intra-bsc-fsm.png \</span><br><span style="color: hsl(120, 100%, 40%);">+      $(builddir)/handover-inter-bsc-out-fsm.png \</span><br><span style="color: hsl(120, 100%, 40%);">+  $(builddir)/handover-inter-bsc-in-fsm.png \</span><br><span>  $(NULL)</span><br><span> </span><br><span> $(builddir)/%.png: $(srcdir)/%.msc</span><br><span>diff --git a/doc/assignment-fsm.dot b/doc/assignment-fsm.dot</span><br><span>new file mode 100644</span><br><span>index 0000000..5a3a2b9</span><br><span>--- /dev/null</span><br><span>+++ b/doc/assignment-fsm.dot</span><br><span>@@ -0,0 +1,42 @@</span><br><span style="color: hsl(120, 100%, 40%);">+digraph G {</span><br><span style="color: hsl(120, 100%, 40%);">+rankdir=TB</span><br><span style="color: hsl(120, 100%, 40%);">+labelloc=t; label="Assignment FSM"</span><br><span style="color: hsl(120, 100%, 40%);">+     </span><br><span style="color: hsl(120, 100%, 40%);">+      WAIT_LCHAN_ACTIVE</span><br><span style="color: hsl(120, 100%, 40%);">+     WAIT_RR_ASS_COMPLETE</span><br><span style="color: hsl(120, 100%, 40%);">+  WAIT_LCHAN_ESTABLISHED</span><br><span style="color: hsl(120, 100%, 40%);">+        WAIT_MGW_ENDPOINT_TO_MSC</span><br><span style="color: hsl(120, 100%, 40%);">+      terminate [shape=octagon]</span><br><span style="color: hsl(120, 100%, 40%);">+     </span><br><span style="color: hsl(120, 100%, 40%);">+      gscon [label="conn FSM",shape=box3d]</span><br><span style="color: hsl(120, 100%, 40%);">+        gscon2 [label="conn FSM",shape=box3d]</span><br><span style="color: hsl(120, 100%, 40%);">+       lchan [label="lchan FSM\n(new lchan)",shape=box3d]</span><br><span style="color: hsl(120, 100%, 40%);">+  old_lchan [label="old lchan",shape=box3d]</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ bssap [label="osmo_bsc_bssap.c",shape=box]</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        invisible [style="invisible"]</span><br><span style="color: hsl(120, 100%, 40%);">+       invisible -> bssap [label="BSSMAP Assignment Request",style=dotted]</span><br><span style="color: hsl(120, 100%, 40%);">+      invisible -> old_lchan [style=invisible,arrowhead=none]</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  bssap -> gscon [label="GSCON_EV_ASSIGNMENT_START\ndata=struct assignment_request",style=dotted]</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        gscon -> WAIT_LCHAN_ACTIVE [label="assignment_fsm_start()",style=dotted]</span><br><span style="color: hsl(120, 100%, 40%);">+        WAIT_LCHAN_ACTIVE -> lchan [label="lchan_activate()\nFOR_ASSIGNMENT",style=dotted]</span><br><span style="color: hsl(120, 100%, 40%);">+        lchan -> WAIT_LCHAN_ACTIVE [label="ASSIGNMENT_EV_\nLCHAN_\nACTIVE,ERROR",style=dotted]</span><br><span style="color: hsl(120, 100%, 40%);">+   lchan -> WAIT_LCHAN_ESTABLISHED [label="ASSIGNMENT_EV_\nLCHAN_\nESTABLISHED,ERROR",style=dotted]</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       WAIT_LCHAN_ACTIVE -> WAIT_RR_ASS_COMPLETE</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        WAIT_RR_ASS_COMPLETE -> old_lchan [label="RR Assignment\nCommand",style=dotted,constraint=false]</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan -> WAIT_RR_ASS_COMPLETE [label="RR Assignment\nComplete",style=dotted]</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   WAIT_RR_ASS_COMPLETE -> WAIT_LCHAN_ESTABLISHED</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   WAIT_LCHAN_ESTABLISHED -> WAIT_MGW_ENDPOINT_TO_MSC [label="TCH"]</span><br><span style="color: hsl(120, 100%, 40%);">+ WAIT_LCHAN_ESTABLISHED -> terminate [label="non-TCH"]</span><br><span style="color: hsl(120, 100%, 40%);">+    WAIT_MGW_ENDPOINT_TO_MSC -> terminate</span><br><span style="color: hsl(120, 100%, 40%);">+      WAIT_MGW_ENDPOINT_TO_MSC -> gscon2 [label="gscon_connect_\nmgw_to_msc()",style=dotted]</span><br><span style="color: hsl(120, 100%, 40%);">+   gscon2 -> WAIT_MGW_ENDPOINT_TO_MSC [label="ASSIGNMENT_EV_\nMSC_MGW_OK",style=dotted]</span><br><span style="color: hsl(120, 100%, 40%);">+     terminate -> gscon2 [label="GSCON_EV_\nASSIGNMENT_END",style=dotted]</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/doc/assignment.msc b/doc/assignment.msc</span><br><span>index 9f10ea1..4e690a8 100644</span><br><span>--- a/doc/assignment.msc</span><br><span>+++ b/doc/assignment.msc</span><br><span>@@ -1,126 +1,72 @@</span><br><span> msc {</span><br><span style="color: hsl(0, 100%, 40%);">- hscale=3;</span><br><span style="color: hsl(0, 100%, 40%);">-       ms [label="MS/BTS"], bsc_lchan[label="BSC lchan FSM"],</span><br><span style="color: hsl(0, 100%, 40%);">-      bsc_gscon[label="BSC conn FSM"], bsc_mgcp[label="BSC mgcp FSM"], mgw_msc[label="MGW/MSC"];</span><br><span style="color: hsl(120, 100%, 40%);">+      hscale=2;</span><br><span style="color: hsl(120, 100%, 40%);">+     ms [label="MS/BTS"], lchan[label="BSC lchan FSM"], ass[label="BSC Assignment FSM"],</span><br><span style="color: hsl(120, 100%, 40%);">+     gscon[label="BSC conn FSM"], msc_[label="MSC"];</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- ms note mgw_msc [label="lchan allocation sequence for BSSMAP Assignment Request"];</span><br><span style="color: hsl(120, 100%, 40%);">+  ms note msc_ [label="lchan allocation sequence for BSSMAP Assignment Request"];</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   bsc_gscon <= mgw_msc [label="BSSMAP Assignment Request"];</span><br><span style="color: hsl(0, 100%, 40%);">-  bsc_gscon abox bsc_gscon [label="ST_ASSIGNMENT_\nWAIT_LCHAN"];</span><br><span style="color: hsl(120, 100%, 40%);">+      gscon <= msc_ [label="BSSMAP Assignment Request"];</span><br><span style="color: hsl(120, 100%, 40%);">+       gscon note gscon [label="GSCON_EV_ASSIGNMENT_START\n data=struct assignment_request"];</span><br><span style="color: hsl(120, 100%, 40%);">+      gscon abox gscon [label="ST_ASSIGNMENT"];</span><br><span style="color: hsl(120, 100%, 40%);">+   ass <- gscon [label="assignment_fsm_start()"];</span><br><span style="color: hsl(120, 100%, 40%);">+   ass abox ass [label="ASSIGNMENT_ST_\nWAIT_LCHAN_ACTIVE"];</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- bsc_lchan <- bsc_gscon [label="lchan_select_by_chan_mode(chan_mode)"];</span><br><span>  |||;</span><br><span style="color: hsl(0, 100%, 40%);">-    --- [label="IF returned lchan is NULL"];</span><br><span style="color: hsl(0, 100%, 40%);">-      bsc_gscon => mgw_msc [label="BSSMAP Assignment Failure"];</span><br><span style="color: hsl(0, 100%, 40%);">-  bsc_gscon abox bsc_gscon [label="ST_ACTIVE"];</span><br><span style="color: hsl(120, 100%, 40%);">+       --- [label="On any error (no lchan, etc.)"];</span><br><span style="color: hsl(120, 100%, 40%);">+        ass box ass [label="on_assignment_failure()"];</span><br><span style="color: hsl(120, 100%, 40%);">+      ass => msc_ [label="BSSMAP Assignment Failure"];</span><br><span style="color: hsl(120, 100%, 40%);">+ ass abox ass [label="terminate"];</span><br><span style="color: hsl(120, 100%, 40%);">+   ass -> gscon [label="GSCON_EV_ASSIGNMENT_END"];</span><br><span style="color: hsl(120, 100%, 40%);">+  gscon abox gscon [label="ST_ACTIVE"];</span><br><span>      ---;</span><br><span>         |||;</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_gscon box bsc_gscon [label="store lchan pointer in conn->lchan_for_assignment"];</span><br><span style="color: hsl(0, 100%, 40%);">-       bsc_lchan <- bsc_gscon [label="lchan_activate(FOR_ASSIGNMENT)"];</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan abox lchan [label="UNUSED"];</span><br><span style="color: hsl(120, 100%, 40%);">+  ass box ass [label="conn->assignment.new_lchan = lchan_select_by_chan_mode()"];</span><br><span style="color: hsl(120, 100%, 40%);">+  lchan <- ass [label="lchan_activate(FOR_ASSIGNMENT)"];</span><br><span style="color: hsl(120, 100%, 40%);">+   lchan abox lchan [label="WAIT_TS_READY"];</span><br><span style="color: hsl(120, 100%, 40%);">+   lchan rbox lchan [label="most details omitted, see lchan_fsm and lchan_rtp_fsm diagrams"];</span><br><span>         ...;</span><br><span>         |||;</span><br><span>         --- [label="on lchan FSM error or timeout"];</span><br><span style="color: hsl(0, 100%, 40%);">-  bsc_lchan -> bsc_gscon [label="GSCON_EV_LCHAN_ALLOC_ERROR"];</span><br><span style="color: hsl(0, 100%, 40%);">-       bsc_gscon box bsc_gscon [label="'forget' all about conn->lchan_for_assignment"];</span><br><span style="color: hsl(0, 100%, 40%);">-   bsc_gscon => mgw_msc [label="BSSMAP Assignment Failure"];</span><br><span style="color: hsl(0, 100%, 40%);">-  bsc_gscon abox bsc_gscon [label="ST_ACTIVE"];</span><br><span style="color: hsl(120, 100%, 40%);">+       lchan -> ass [label="ASSIGNMENT_EV_LCHAN_ERROR"];</span><br><span style="color: hsl(120, 100%, 40%);">+        ass box ass [label="on_assignment_failure()"];</span><br><span style="color: hsl(120, 100%, 40%);">+      ass rbox gscon [label="See 'On any error' above"];</span><br><span>         --- [label="END: 'on error'"];</span><br><span>     ...;</span><br><span>         ...;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        --- [label="IF lchan FSM decides that it is an lchan for speech"];</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_lchan -> bsc_gscon [label="GSCON_EV_ENSURE_MGW_ENDPOINT"];</span><br><span style="color: hsl(0, 100%, 40%);">-     --- [label="IF there is an MGW endpoint for the BTS already (conn->user_plane.fi_bts)"];</span><br><span style="color: hsl(0, 100%, 40%);">-   bsc_gscon -> bsc_lchan [label="LCHAN_EV_MGW_ENDPOINT_AVAILABLE"];</span><br><span style="color: hsl(0, 100%, 40%);">-  --- [label="ELSE: no MGW endpoint for the BTS side yet"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_gscon abox bsc_gscon [label="ST_ASSIGNMENT_\nWAIT_CRCX_BTS"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_gscon box bsc_gscon [label="assignment_created_mgw_endpoint = true"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_gscon -> bsc_mgcp [label="mgcp_conn_create()"];</span><br><span style="color: hsl(0, 100%, 40%);">-        bsc_mgcp abox bsc_mgcp [label="ST_CRCX_RESP (MGCP_MGW_TIMEOUT = 4s)"];</span><br><span style="color: hsl(0, 100%, 40%);">-        bsc_mgcp => mgw_msc [label="CRCX (for BTS)"];</span><br><span style="color: hsl(0, 100%, 40%);">-      bsc_gscon note bsc_mgcp [label="conn FSM relies on mgcp FSM timeout"];</span><br><span style="color: hsl(120, 100%, 40%);">+      lchan abox lchan [label="LCHAN_ST_WAIT_ACTIV_ACK"];</span><br><span style="color: hsl(120, 100%, 40%);">+ ms <= lchan [label="RSL Chan Activ"];</span><br><span>   ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    --- [label="On Timeout"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_mgcp note bsc_mgcp [label="On timeouit, the MGCP FSM will terminate, emitting the parent_term</span><br><span style="color: hsl(0, 100%, 40%);">-          event set upon mgcp_conn_create():"];</span><br><span style="color: hsl(0, 100%, 40%);">-      bsc_mgcp -> bsc_gscon [label="GSCON_EV_MGW_FAIL_BTS"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_gscon note bsc_gscon [label="GSCON_EV_MGW_FAIL_BTS is handled by the conn FSM allstate</span><br><span style="color: hsl(0, 100%, 40%);">-         handler. It sets conn->user_plane.fi_bts = NULL."];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_gscon -> bsc_lchan [label="LCHAN_EV_MGW_ENDPOINT_ERROR"];</span><br><span style="color: hsl(0, 100%, 40%);">-      bsc_lchan note bsc_gscon [label="conn FSM timeout handler exits and relies on the lchan FSM</span><br><span style="color: hsl(0, 100%, 40%);">-                signalling error, which should actually happen immediately:"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_gscon <- bsc_lchan [label="GSCON_EV_LCHAN_ALLOC_ERROR"];</span><br><span style="color: hsl(0, 100%, 40%);">-       bsc_gscon abox bsc_gscon [label="ST_ACTIVE"];</span><br><span style="color: hsl(0, 100%, 40%);">- bsc_gscon box bsc_gscon [label="'forget' all about conn->lchan_for_assignment"];</span><br><span style="color: hsl(0, 100%, 40%);">-   bsc_gscon => mgw_msc [label="BSSMAP Assignment Failure"];</span><br><span style="color: hsl(0, 100%, 40%);">-  --- [label="END: 'On Timeout'"];</span><br><span style="color: hsl(120, 100%, 40%);">+    ms => lchan [label="RSL Chan Activ ACK"];</span><br><span style="color: hsl(120, 100%, 40%);">+        lchan -> ass [label="ASSIGNMENT_EV_LCHAN_ACTIVE"];</span><br><span style="color: hsl(120, 100%, 40%);">+       ass abox ass [label="ASSIGNMENT_ST_\nWAIT_RR_ASS_COMPLETE"];</span><br><span style="color: hsl(120, 100%, 40%);">+        ms <= ass [label="RR Assignment Command"];</span><br><span style="color: hsl(120, 100%, 40%);">+       lchan note ass [label="The lchan FSM will continue with RSL and RTP while the Assignment FSM waits.</span><br><span style="color: hsl(120, 100%, 40%);">+              ASSIGNMENT_EV_LCHAN_ESTABLISHED means that both RSL and RTP are established.</span><br><span style="color: hsl(120, 100%, 40%);">+          Usually, RTP will be done first, and the ASSIGNMENT_EV_LCHAN_ESTABLISHED may be</span><br><span style="color: hsl(120, 100%, 40%);">+               received even before ASSIGNMENT_EV_RR_ASSIGNMENT_COMPLETE.</span><br><span style="color: hsl(120, 100%, 40%);">+            assignment_fsm_wait_lchan_established_onenter() decides whether to wait or not."];</span><br><span>      ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  ms => lchan [label="RSL EST IND"];</span><br><span style="color: hsl(120, 100%, 40%);">+       lchan -> ass [label="ASSIGNMENT_EV_LCHAN_ESTABLISHED",ID="(may come as early as this, or...)"];</span><br><span style="color: hsl(120, 100%, 40%);">+        ms => ass [label="RR Assignment Complete (came with EST IND)"];</span><br><span style="color: hsl(120, 100%, 40%);">+  ass abox ass [label="ASSIGNMENT_ST_\nWAIT_LCHAN_ESTABLISHED"];</span><br><span style="color: hsl(120, 100%, 40%);">+      --- [label="IF lchan is not in LCHAN_ST_ESTABLISHED yet (waiting for RTP)"];</span><br><span style="color: hsl(120, 100%, 40%);">+        ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  lchan rbox lchan [label="when lchan RTP FSM is done with setting up RTP"];</span><br><span style="color: hsl(120, 100%, 40%);">+  lchan -> ass [label="ASSIGNMENT_EV_LCHAN_ESTABLISHED",ID="(...may come only now)"];</span><br><span style="color: hsl(120, 100%, 40%);">+    ---;</span><br><span style="color: hsl(120, 100%, 40%);">+  ass abox ass [label="ASSIGNMENT_ST_WAIT_\nMGW_ENDPOINT_TO_MSC"];</span><br><span style="color: hsl(120, 100%, 40%);">+    ass -> gscon [label="gscon_connect_mgw_to_msc()"];</span><br><span style="color: hsl(120, 100%, 40%);">+       ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  ass <- gscon [label="ASSIGNMENT_EV_MSC_MGW_OK"];</span><br><span style="color: hsl(120, 100%, 40%);">+ ass box ass [label="assignment_success()"];</span><br><span style="color: hsl(120, 100%, 40%);">+ ass => msc_ [label="BSSMAP Assignment Complete"];</span><br><span style="color: hsl(120, 100%, 40%);">+        ass -> gscon [label="gscon_change_primary_lchan()"];</span><br><span style="color: hsl(120, 100%, 40%);">+     lchan <- gscon [label="LCHAN_RTP_EV_ESTABLISHED"];</span><br><span style="color: hsl(120, 100%, 40%);">+       ass abox ass [label="terminate"];</span><br><span style="color: hsl(120, 100%, 40%);">+   ass -> gscon [label="GSCON_EV_ASSIGNMENT_END"];</span><br><span style="color: hsl(120, 100%, 40%);">+  gscon abox gscon [label="ST_ACTIVE"];</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_mgcp <= mgw_msc [label="CRCX OK (for BTS)"];</span><br><span style="color: hsl(0, 100%, 40%);">-   bsc_mgcp box bsc_mgcp [label="libosmo-mgcp-client fsm_crcx_resp_cb()"];</span><br><span style="color: hsl(0, 100%, 40%);">-       bsc_mgcp abox bsc_mgcp [label="ST_READY"];</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_mgcp -> bsc_gscon [label="GSCON_EV_MGW_CRCX_RESP_BTS"];</span><br><span style="color: hsl(0, 100%, 40%);">-        bsc_gscon abox bsc_gscon [label="ST_ASSIGNMENT_\nWAIT_LCHAN"];</span><br><span style="color: hsl(0, 100%, 40%);">-        bsc_gscon -> bsc_lchan [label="LCHAN_EV_MGW_ENDPOINT_AVAILABLE"];</span><br><span style="color: hsl(0, 100%, 40%);">-  --- [label="END: lchan FSM decides that it is an lchan for speech"];</span><br><span style="color: hsl(0, 100%, 40%);">-  ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    ...;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_lchan -> bsc_gscon [label="GSCON_EV_LCHAN_ACTIVE"];</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_gscon abox bsc_gscon [label="ST_ASSIGNMENT_\nWAIT_COMPLETE\nT10, 6s"];</span><br><span style="color: hsl(0, 100%, 40%);">-    ms <= bsc_gscon [label="RR Assignment"];</span><br><span style="color: hsl(0, 100%, 40%);">-   ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    --- [label="On Timeout"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_gscon => mgw_msc [label="BSSMAP Assignment Failure"];</span><br><span style="color: hsl(0, 100%, 40%);">-  bsc_gscon -> bsc_lchan [label="LCHAN_EV_LCHAN_RELEASE"];</span><br><span style="color: hsl(0, 100%, 40%);">-   bsc_gscon box bsc_gscon [label="'forget' all about conn->lchan_for_assignment"];</span><br><span style="color: hsl(0, 100%, 40%);">-   --- [label="IF assignment_created_mgw_endpoint == true"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_gscon -> bsc_mgcp [label="mgcp_conn_delete()"];</span><br><span style="color: hsl(0, 100%, 40%);">-        bsc_gscon note bsc_mgcp [label="If the MGW endpoint didn't exist before the Assignment, release</span><br><span style="color: hsl(0, 100%, 40%);">-                it now. If there was one before this, it is probably still in use by a previous lchan, so</span><br><span style="color: hsl(0, 100%, 40%);">-               keep it in place."];</span><br><span style="color: hsl(0, 100%, 40%);">-       bsc_gscon abox bsc_gscon [label="ST_ACTIVE"];</span><br><span style="color: hsl(0, 100%, 40%);">- --- [label="END: 'On Timeout'"];</span><br><span style="color: hsl(0, 100%, 40%);">-      ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    ms => bsc_gscon [label="RR Assignment Complete"];</span><br><span style="color: hsl(0, 100%, 40%);">-  bsc_gscon -> bsc_lchan [label="OLD lchan: LCHAN_EV_LCHAN_RELEASE"];</span><br><span style="color: hsl(0, 100%, 40%);">-        bsc_gscon box bsc_gscon [label="conn->lchan = conn->lchan_for_assignment"];</span><br><span style="color: hsl(0, 100%, 40%);">-     --- [label="IF: chan_mode a speech mode?"];</span><br><span style="color: hsl(0, 100%, 40%);">-   bsc_gscon abox bsc_gscon [label="ST_WAIT_MDCX_BTS"];</span><br><span style="color: hsl(0, 100%, 40%);">-  bsc_gscon -> bsc_mgcp [label="mgcp_conn_modify()"];</span><br><span style="color: hsl(0, 100%, 40%);">-        bsc_mgcp note bsc_mgcp [label="same mgcp FSM as above, for BTS side"];</span><br><span style="color: hsl(0, 100%, 40%);">-        bsc_mgcp abox bsc_mgcp [label="ST_MDCX_RESP"];</span><br><span style="color: hsl(0, 100%, 40%);">-        bsc_mgcp => mgw_msc [label="MDCX (for BTS)"];</span><br><span style="color: hsl(0, 100%, 40%);">-      ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    --- [label="On Timeout"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_gscon -> bsc_lchan [label="LCHAN_EV_RELEASE"];</span><br><span style="color: hsl(0, 100%, 40%);">- bsc_gscon -> bsc_mgcp [label="mgcp_conn_delete()"];</span><br><span style="color: hsl(0, 100%, 40%);">-        bsc_gscon => mgw_msc [label="BSSMAP Assignment Failure"];</span><br><span style="color: hsl(0, 100%, 40%);">-  bsc_gscon abox bsc_gscon [label="ST_WAIT_CLEAR_CMD"];</span><br><span style="color: hsl(0, 100%, 40%);">- bsc_gscon => mgw_msc [label="BSSMAP Clear Request"];</span><br><span style="color: hsl(0, 100%, 40%);">-       --- [label="END: 'On Timeout'"];</span><br><span style="color: hsl(0, 100%, 40%);">-      ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_mgcp <= mgw_msc [label="MDCX OK"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_mgcp abox bsc_mgcp [label="ST_READY"];</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_mgcp -> bsc_gscon [label="GSCON_EV_MGW_MDCX_RESP_BTS"];</span><br><span style="color: hsl(0, 100%, 40%);">-        bsc_gscon abox bsc_gscon [label="ST_WAIT_CRCX_MSC"];</span><br><span style="color: hsl(0, 100%, 40%);">-  bsc_gscon -> bsc_mgcp [label="mgcp_conn_create()"];</span><br><span style="color: hsl(0, 100%, 40%);">-        bsc_mgcp note bsc_mgcp [label="second mgcp FSM for MSC side"];</span><br><span style="color: hsl(0, 100%, 40%);">-        bsc_mgcp => mgw_msc [label="CRCX (for MSC)"];</span><br><span style="color: hsl(0, 100%, 40%);">-      ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    --- [label="On Timeout"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_gscon -> bsc_lchan [label="LCHAN_EV_RELEASE"];</span><br><span style="color: hsl(0, 100%, 40%);">- bsc_gscon -> bsc_mgcp [label="mgcp_conn_delete()"];</span><br><span style="color: hsl(0, 100%, 40%);">-        bsc_gscon => mgw_msc [label="BSSMAP Assignment Failure"];</span><br><span style="color: hsl(0, 100%, 40%);">-  bsc_gscon abox bsc_gscon [label="ST_WAIT_CLEAR_CMD"];</span><br><span style="color: hsl(0, 100%, 40%);">- bsc_gscon => mgw_msc [label="BSSMAP Clear Request"];</span><br><span style="color: hsl(0, 100%, 40%);">-       --- [label="END: 'On Timeout'"];</span><br><span style="color: hsl(0, 100%, 40%);">-      ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_mgcp <= mgw_msc [label="CRCX OK (for MSC)"];</span><br><span style="color: hsl(0, 100%, 40%);">-   bsc_gscon <- bsc_mgcp [label="GSCON_EV_MGW_CRCX_RESP_MSC"];</span><br><span style="color: hsl(0, 100%, 40%);">-        --- [label="END: chan_mode a speech mode?"];</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  bsc_gscon => mgw_msc [label="BSSMAP Assignment Complete"];</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- bsc_gscon abox bsc_gscon [label="ST_ACTIVE"];</span><br><span> }</span><br><span>diff --git a/doc/handover-inter-bsc-in-fsm.dot b/doc/handover-inter-bsc-in-fsm.dot</span><br><span>new file mode 100644</span><br><span>index 0000000..b52a16d</span><br><span>--- /dev/null</span><br><span>+++ b/doc/handover-inter-bsc-in-fsm.dot</span><br><span>@@ -0,0 +1,42 @@</span><br><span style="color: hsl(120, 100%, 40%);">+digraph G {</span><br><span style="color: hsl(120, 100%, 40%);">+rankdir=TB</span><br><span style="color: hsl(120, 100%, 40%);">+labelloc=t; label="Handover FSM: Inter-BSC Incoming"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     old_bss [label="old BSS",shape=box3d]</span><br><span style="color: hsl(120, 100%, 40%);">+       msc [label="MSC",shape=box3d]</span><br><span style="color: hsl(120, 100%, 40%);">+       ho_in [label="inter-BSC HO Incoming",shape=box]</span><br><span style="color: hsl(120, 100%, 40%);">+     gscon [label="gscon FSM",shape=box3d]</span><br><span style="color: hsl(120, 100%, 40%);">+       lchan [label="lchan FSM",shape=box3d]</span><br><span style="color: hsl(120, 100%, 40%);">+       msc2 [label="msc",shape=box3d]</span><br><span style="color: hsl(120, 100%, 40%);">+      old_bsc2 [label="old BSC",shape=box3d]</span><br><span style="color: hsl(120, 100%, 40%);">+      old_lchan [label="old lchan",shape=box3d]</span><br><span style="color: hsl(120, 100%, 40%);">+   terminate [shape=octagon]</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   old_bss -> msc [label="BSSMAP Handover Required",style=dotted]</span><br><span style="color: hsl(120, 100%, 40%);">+   msc -> ho_in [label="BSSMAP Handover Request",style=dotted]</span><br><span style="color: hsl(120, 100%, 40%);">+      ho_in -> gscon [label="GSCON_EV_A_CONN_IND\nBSSMAP Handover Request",style=dotted]</span><br><span style="color: hsl(120, 100%, 40%);">+       gscon -> HO_ST_WAIT_LCHAN_ACTIVE [label="handover_start_inter_bsc_in()",style=dotted]</span><br><span style="color: hsl(120, 100%, 40%);">+    HO_ST_WAIT_LCHAN_ACTIVE -> lchan [label="lchan_activate()\nFOR_HANDOVER",style=dotted]</span><br><span style="color: hsl(120, 100%, 40%);">+   lchan -> HO_ST_WAIT_LCHAN_ACTIVE [label="HO_EV_\nLCHAN_ACTIVE,\n_ERROR",style=dotted,constraint=false]</span><br><span style="color: hsl(120, 100%, 40%);">+   HO_ST_WAIT_LCHAN_ACTIVE -> HO_ST_WAIT_RR_HO_DETECT</span><br><span style="color: hsl(120, 100%, 40%);">+ </span><br><span style="color: hsl(120, 100%, 40%);">+      HO_ST_WAIT_RR_HO_DETECT -> msc2 [label="BSSMAP\nHandover\nAccept\nwith\nRR Handover\nCommand",style=dotted]</span><br><span style="color: hsl(120, 100%, 40%);">+      msc2 -> old_bsc2 -> old_lchan [label="RR Handover\nCommand",style=dotted]</span><br><span style="color: hsl(120, 100%, 40%);">+     old_lchan -> lchan [label="MS moves",style=dotted,constraint=false]</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    lchan -> HO_ST_WAIT_RR_HO_DETECT [label="RR Handover\nDetect",style=dotted]</span><br><span style="color: hsl(120, 100%, 40%);">+      HO_ST_WAIT_RR_HO_DETECT -> WAIT_RR_HO_COMPLETE</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   lchan -> WAIT_RR_HO_COMPLETE [label="RR Handover\nComplete",style=dotted]</span><br><span style="color: hsl(120, 100%, 40%);">+        WAIT_RR_HO_COMPLETE -> WAIT_LCHAN_ESTABLISHED</span><br><span style="color: hsl(120, 100%, 40%);">+      lchan -> WAIT_LCHAN_ESTABLISHED [label="HO_EV_LCHAN_\nESTABLISHED",style=dotted]</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       WAIT_LCHAN_ESTABLISHED -> terminate [label="non-TCH"]</span><br><span style="color: hsl(120, 100%, 40%);">+    WAIT_LCHAN_ESTABLISHED -> WAIT_MGW_ENDPOINT_TO_MSC</span><br><span style="color: hsl(120, 100%, 40%);">+ WAIT_MGW_ENDPOINT_TO_MSC -> terminate [label="handover_end()"]</span><br><span style="color: hsl(120, 100%, 40%);">+   terminate -> msc2 [label="BSSMAP Handover\nComplete\n/ Failure",style=dotted,constraint=false]</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ err [label="on error",shape=box,style=dashed]</span><br><span style="color: hsl(120, 100%, 40%);">+       err -> terminate [style=dashed]</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/doc/handover-inter-bsc-in.msc b/doc/handover-inter-bsc-in.msc</span><br><span>new file mode 100644</span><br><span>index 0000000..9534f90</span><br><span>--- /dev/null</span><br><span>+++ b/doc/handover-inter-bsc-in.msc</span><br><span>@@ -0,0 +1,74 @@</span><br><span style="color: hsl(120, 100%, 40%);">+msc {</span><br><span style="color: hsl(120, 100%, 40%);">+  hscale=2;</span><br><span style="color: hsl(120, 100%, 40%);">+     ms [label="MS/BTS"], lchan[label="BSC lchan FSM"], ho[label="BSC Handover FSM"],</span><br><span style="color: hsl(120, 100%, 40%);">+        gscon[label="BSC conn FSM"], msc_[label="MSC"];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ ms note msc_ [label="inter-BSC Handover Incoming"];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       gscon <= msc_ [label="N-Connect: BSSMAP Handover Request"];</span><br><span style="color: hsl(120, 100%, 40%);">+      gscon box gscon [label="bsc_subscr_con_allocate()"];</span><br><span style="color: hsl(120, 100%, 40%);">+        gscon abox gscon [label="ST_INIT"];</span><br><span style="color: hsl(120, 100%, 40%);">+ gscon -> gscon [label="GSCON_EV_A_CONN_IND"];</span><br><span style="color: hsl(120, 100%, 40%);">+    ho <- gscon [label="handover_start_inter_bsc_in()"];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   ho abox ho [label="allocate\nHO_ST_NOT_STARTED"];</span><br><span style="color: hsl(120, 100%, 40%);">+   ho box ho [label="lchan_select_by_chan_mode()"];</span><br><span style="color: hsl(120, 100%, 40%);">+    ho abox ho [label="HO_ST_WAIT_\nLCHAN_ACTIVE"];</span><br><span style="color: hsl(120, 100%, 40%);">+     lchan <- ho [label="lchan_activate(FOR_HANDOVER)"];</span><br><span style="color: hsl(120, 100%, 40%);">+      lchan rbox lchan [label="(most details omitted, see lchan_fsm diagrams)"];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  --- [label="On any error or timeout"];</span><br><span style="color: hsl(120, 100%, 40%);">+      ho box ho [label="handover_end(fail)"];</span><br><span style="color: hsl(120, 100%, 40%);">+     ho -> gscon [label="GSCON_EV_HANDOVER_END"];</span><br><span style="color: hsl(120, 100%, 40%);">+     gscon note msc_ [label="There is no specific BSSMAP Handover Request NACK message."];</span><br><span style="color: hsl(120, 100%, 40%);">+       gscon => msc_ [label="BSSMAP Clear Request"];</span><br><span style="color: hsl(120, 100%, 40%);">+    gscon abox gscon [label="ST_CLEARING"];</span><br><span style="color: hsl(120, 100%, 40%);">+     gscon rbox msc_ [label="the usual disconnect dance"];</span><br><span style="color: hsl(120, 100%, 40%);">+       --- [label="END: 'On any error or timeout'"];</span><br><span style="color: hsl(120, 100%, 40%);">+       ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  ...;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        lchan abox lchan [label="LCHAN_ST_WAIT_\nACTIV_ACK"];</span><br><span style="color: hsl(120, 100%, 40%);">+       ms <= lchan [label="RSL Chan Activ"];</span><br><span style="color: hsl(120, 100%, 40%);">+    ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  ms => lchan [label="RSL Chan Activ ACK"];</span><br><span style="color: hsl(120, 100%, 40%);">+        lchan -> ho [label="HO_EV_LCHAN_ACTIVE"];</span><br><span style="color: hsl(120, 100%, 40%);">+        ho abox ho [label="HO_ST_WAIT_\nRR_HO_DETECT"];</span><br><span style="color: hsl(120, 100%, 40%);">+     ho => msc_ [label="BSSMAP Handover Request Acknowledge\nwith RR Handover Command"];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    ...;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        ms => ho [label="RR Handover Detect\nHO_EV_RR_HO_DETECT"];</span><br><span style="color: hsl(120, 100%, 40%);">+       ho => msc_ [label="BSSMAP Handover Detect"];</span><br><span style="color: hsl(120, 100%, 40%);">+     ho abox ho [label="HO_ST_WAIT_\nRR_HO_COMPLETE"];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  lchan note ho [label="The lchan FSM will continue with RSL and RTP while the HO FSM waits.</span><br><span style="color: hsl(120, 100%, 40%);">+               HO_EV_LCHAN_ESTABLISHED means that both RSL and RTP are established.</span><br><span style="color: hsl(120, 100%, 40%);">+          Usually, RTP will be done first, and the HO_EV_LCHAN_ESTABLISHED may be</span><br><span style="color: hsl(120, 100%, 40%);">+               received even before HO_EV_RR_HO_COMPLETE.</span><br><span style="color: hsl(120, 100%, 40%);">+            ho_fsm_wait_lchan_established_onenter() decides whether to wait or not."];</span><br><span style="color: hsl(120, 100%, 40%);">+       ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  ms => lchan [label="RSL EST IND"];</span><br><span style="color: hsl(120, 100%, 40%);">+       lchan -> ho [label="HO_EV_LCHAN_ESTABLISHED",ID="(may come as early as this, or...)"];</span><br><span style="color: hsl(120, 100%, 40%);">+ ms => ho [label="RR Handover Complete (from EST IND)\n HO_EV_RR_HO_COMPLETE"];</span><br><span style="color: hsl(120, 100%, 40%);">+   ho abox ho [label="HO_ST_WAIT_\nLCHAN_ESTABLISHED"];</span><br><span style="color: hsl(120, 100%, 40%);">+        ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  lchan rbox lchan [label="when lchan FSM is done with setting up RTP"];</span><br><span style="color: hsl(120, 100%, 40%);">+      lchan -> ho [label="HO_EV_LCHAN_ESTABLISHED",ID="(...may come only now)"];</span><br><span style="color: hsl(120, 100%, 40%);">+     ho abox ho [label="HO_ST_WAIT_\nMGW_ENDPOINT_TO_MSC"];</span><br><span style="color: hsl(120, 100%, 40%);">+      ho -> gscon [label="gscon_connect_mgw_to_msc()"];</span><br><span style="color: hsl(120, 100%, 40%);">+        ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  ho <- gscon [label="HO_EV_MSC_MGW_OK"];</span><br><span style="color: hsl(120, 100%, 40%);">+  ho box ho [label="handover_end(OK)"];</span><br><span style="color: hsl(120, 100%, 40%);">+       ho => msc_ [label="BSSMAP Handover Complete"];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ ho -> gscon [label="gscon_change_primary_lchan()"];</span><br><span style="color: hsl(120, 100%, 40%);">+      lchan <- gscon [label="LCHAN_RTP_EV_ESTABLISHED"];</span><br><span style="color: hsl(120, 100%, 40%);">+       ho -> gscon [label="GSCON_EV_HANDOVER_END"];</span><br><span style="color: hsl(120, 100%, 40%);">+     gscon abox gscon [label="ST_ACTIVE"];</span><br><span style="color: hsl(120, 100%, 40%);">+       ho box ho [label="detach from parent to not fire another meaningless GSCON_EV_HANDOVER_END"];</span><br><span style="color: hsl(120, 100%, 40%);">+       ho abox ho [label="terminate"];</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/doc/handover-inter-bsc-mo.msc b/doc/handover-inter-bsc-mo.msc</span><br><span>deleted file mode 100644</span><br><span>index 9aff7a7..0000000</span><br><span>--- a/doc/handover-inter-bsc-mo.msc</span><br><span>+++ /dev/null</span><br><span>@@ -1,37 +0,0 @@</span><br><span style="color: hsl(0, 100%, 40%);">-msc {</span><br><span style="color: hsl(0, 100%, 40%);">-     hscale=2;</span><br><span style="color: hsl(0, 100%, 40%);">-       ms [label="MS via BTS"], bsc_lchan[label="BSC lchan FSM"], bsc_gscon[label="BSC conn FSM"],</span><br><span style="color: hsl(0, 100%, 40%);">-       msc_[label="MSC"];</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    ms note msc_ [label="inter-BSC Handover to another BSS"];</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_gscon abox bsc_gscon [label="ST_ACTIVE"];</span><br><span style="color: hsl(0, 100%, 40%);">- bsc_gscon box bsc_gscon [label="bsc_handover_start(): init conn->ho"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_gscon -> bsc_gscon [label="GSCON_EV_HO_START (inter-BSC MO)"];</span><br><span style="color: hsl(0, 100%, 40%);">- bsc_gscon abox bsc_gscon [label="ST_HANDOVER_MO_\nWAIT_HO_CMD\nT7"];</span><br><span style="color: hsl(0, 100%, 40%);">-  bsc_gscon => msc_ [label="BSSMAP Handover Required"];</span><br><span style="color: hsl(0, 100%, 40%);">-      ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    --- [label="On Timeout"];</span><br><span style="color: hsl(0, 100%, 40%);">-     ms note bsc_gscon [label="MS happily continues on the old lchan."];</span><br><span style="color: hsl(0, 100%, 40%);">-   bsc_gscon abox bsc_gscon [label="ST_ACTIVE"];</span><br><span style="color: hsl(0, 100%, 40%);">- bsc_gscon box bsc_gscon [label="handover_end(fail)"];</span><br><span style="color: hsl(0, 100%, 40%);">- --- [label="END: 'On Timeout'"];</span><br><span style="color: hsl(0, 100%, 40%);">-      ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_gscon <= msc_ [label="BSSMAP Handover Command"];</span><br><span style="color: hsl(0, 100%, 40%);">-       bsc_gscon abox bsc_gscon [label="ST_HANDOVER_MO_\nWAIT_CLEAR_CMD\nT8"];</span><br><span style="color: hsl(0, 100%, 40%);">-       ms <= bsc_gscon [label="RR Handover Command"];</span><br><span style="color: hsl(0, 100%, 40%);">-     ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    --- [label="On Timeout"];</span><br><span style="color: hsl(0, 100%, 40%);">-     ms note bsc_gscon [label="MS happily continues on the old lchan."];</span><br><span style="color: hsl(0, 100%, 40%);">-   bsc_gscon abox bsc_gscon [label="ST_ACTIVE"];</span><br><span style="color: hsl(0, 100%, 40%);">- bsc_gscon box bsc_gscon [label="handover_end(fail)"];</span><br><span style="color: hsl(0, 100%, 40%);">- --- [label="END: 'On Timeout'"];</span><br><span style="color: hsl(0, 100%, 40%);">-      ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    msc_ note msc_ [label="Remote BSS reported Handover Complete to the MSC, this connection has been</span><br><span style="color: hsl(0, 100%, 40%);">-          superseded."];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_gscon <= msc_ [label="BSSMAP Clear Command"];</span><br><span style="color: hsl(0, 100%, 40%);">-  bsc_gscon abox bsc_gscon [label="ST_CLEARING"];</span><br><span style="color: hsl(0, 100%, 40%);">-       bsc_gscon => msc_ [label="BSSMAP Clear Complete"];</span><br><span style="color: hsl(0, 100%, 40%);">- bsc_lchan <- bsc_gscon [label="LCHAN_EV_RELEASE"];</span><br><span style="color: hsl(0, 100%, 40%);">- ms <=> bsc_lchan [label="release procedure (async)"];</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span>diff --git a/doc/handover-inter-bsc-mt.msc b/doc/handover-inter-bsc-mt.msc</span><br><span>deleted file mode 100644</span><br><span>index 88a52da..0000000</span><br><span>--- a/doc/handover-inter-bsc-mt.msc</span><br><span>+++ /dev/null</span><br><span>@@ -1,154 +0,0 @@</span><br><span style="color: hsl(0, 100%, 40%);">-msc {</span><br><span style="color: hsl(0, 100%, 40%);">-  hscale=3;</span><br><span style="color: hsl(0, 100%, 40%);">-       ms [label="MS via BTS"], bsc_lchan[label="BSC lchan FSM"], bsc_gscon[label="BSC conn FSM"],</span><br><span style="color: hsl(0, 100%, 40%);">-       bsc_mgcp[label="BSC mgcp FSM"], mgw_msc[label="MGW/MSC"];</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   ms note mgw_msc [label="inter-BSC Handover, from remote BSS"];</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        bsc_gscon <= mgw_msc [label="N-Connect: BSSMAP Handover Request"];</span><br><span style="color: hsl(0, 100%, 40%);">- bsc_gscon box bsc_gscon [label="bsc_subscr_con_allocate()"];</span><br><span style="color: hsl(0, 100%, 40%);">-  bsc_gscon abox bsc_gscon [label="ST_HANDOVER_MT_WAIT_LCHAN"];</span><br><span style="color: hsl(0, 100%, 40%);">- bsc_gscon box bsc_gscon [label="lchan_select_by_chan_mode()"];</span><br><span style="color: hsl(0, 100%, 40%);">-        bsc_lchan <- bsc_gscon [label="lchan_activate(lchan, FOR_HANDOVER)"];</span><br><span style="color: hsl(0, 100%, 40%);">-      bsc_lchan abox bsc_lchan [label="LCHAN_ST_WAIT_TS_READY"];</span><br><span style="color: hsl(0, 100%, 40%);">-    ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    --- [label="on no lchan, lchan FSM error or timeout"];</span><br><span style="color: hsl(0, 100%, 40%);">-        bsc_lchan -> bsc_gscon [label="GSCON_EV_LCHAN_ALLOC_ERROR"];</span><br><span style="color: hsl(0, 100%, 40%);">-       bsc_gscon box bsc_gscon [label="handover_end(fail)"];</span><br><span style="color: hsl(0, 100%, 40%);">- bsc_gscon => mgw_msc [label="BSSMAP Handover Failure"];</span><br><span style="color: hsl(0, 100%, 40%);">-    ms note bsc_gscon [label="MS happily continues on the old lchan."];</span><br><span style="color: hsl(0, 100%, 40%);">-   --- [label="END: 'on error'"];</span><br><span style="color: hsl(0, 100%, 40%);">-        ...;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    --- [label="IF lchan FSM decides that it is an lchan for speech"];</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_lchan abox bsc_lchan [label="LCHAN_ST_WAIT_MGW_ENDPOINT_AVAILABLE"];</span><br><span style="color: hsl(0, 100%, 40%);">-      bsc_lchan -> bsc_gscon [label="GSCON_EV_ENSURE_MGW_ENDPOINT"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_gscon abox bsc_gscon [label="ST_HANDOVER_\nWAIT_CRCX_BTS"];</span><br><span style="color: hsl(0, 100%, 40%);">-       bsc_gscon box bsc_gscon [label="handover_created_mgw_endpoint = true"];</span><br><span style="color: hsl(0, 100%, 40%);">-       bsc_gscon -> bsc_mgcp [label="mgcp_conn_create()"];</span><br><span style="color: hsl(0, 100%, 40%);">-        bsc_mgcp => mgw_msc [label="CRCX (for BTS)"];</span><br><span style="color: hsl(0, 100%, 40%);">-      bsc_mgcp abox bsc_mgcp [label="ST_CRCX_RESP (MGCP_MGW_TIMEOUT = 4s)"];</span><br><span style="color: hsl(0, 100%, 40%);">-        bsc_gscon note bsc_mgcp [label="conn FSM relies on mgcp FSM timeout"];</span><br><span style="color: hsl(0, 100%, 40%);">-        ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    --- [label="On Timeout"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_mgcp note bsc_mgcp [label="On timeout, the MGCP FSM will terminate, emitting the parent_term</span><br><span style="color: hsl(0, 100%, 40%);">-           event set upon mgcp_conn_create():"];</span><br><span style="color: hsl(0, 100%, 40%);">-      bsc_mgcp -> bsc_gscon [label="GSCON_EV_MGW_FAIL_BTS"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_gscon note bsc_gscon [label="GSCON_EV_MGW_FAIL_BTS is handled by the conn FSM allstate</span><br><span style="color: hsl(0, 100%, 40%);">-         handler. It sets conn->user_plane.fi_bts = NULL."];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_gscon -> bsc_lchan [label="LCHAN_EV_MGW_ENDPOINT_ERROR"];</span><br><span style="color: hsl(0, 100%, 40%);">-      bsc_lchan note bsc_gscon [label="conn FSM error handler exits and relies on the lchan FSM</span><br><span style="color: hsl(0, 100%, 40%);">-          signalling error, which should actually happen immediately:"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_gscon <- bsc_lchan [label="GSCON_EV_LCHAN_ALLOC_ERROR"];</span><br><span style="color: hsl(0, 100%, 40%);">-       bsc_gscon -> bsc_mgcp [label="mgcp_conn_delete()"];</span><br><span style="color: hsl(0, 100%, 40%);">-        bsc_gscon box bsc_gscon [label="handover_end(fail)"];</span><br><span style="color: hsl(0, 100%, 40%);">- bsc_gscon => mgw_msc [label="BSSMAP Handover Failure"];</span><br><span style="color: hsl(0, 100%, 40%);">-    ms note bsc_gscon [label="MS happily continues on the old lchan."];</span><br><span style="color: hsl(0, 100%, 40%);">-   --- [label="END: 'On Timeout'"];</span><br><span style="color: hsl(0, 100%, 40%);">-      ...;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_mgcp <= mgw_msc [label="CRCX OK (for BTS)"];</span><br><span style="color: hsl(0, 100%, 40%);">-   bsc_mgcp box bsc_mgcp [label="libosmo-mgcp-client fsm_crcx_resp_cb()"];</span><br><span style="color: hsl(0, 100%, 40%);">-       bsc_mgcp abox bsc_mgcp [label="ST_READY"];</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_mgcp -> bsc_gscon [label="GSCON_EV_MGW_CRCX_RESP_BTS"];</span><br><span style="color: hsl(0, 100%, 40%);">-        bsc_gscon -> bsc_lchan [label="LCHAN_EV_MGW_ENDPOINT_AVAILABLE"];</span><br><span style="color: hsl(0, 100%, 40%);">-  bsc_lchan abox bsc_lchan [label="LCHAN_ST_WAIT_ACTIV_ACK"];</span><br><span style="color: hsl(0, 100%, 40%);">-   bsc_gscon note bsc_gscon [label="MSC-side CRCX needs from Handover Required the RTP IP address</span><br><span style="color: hsl(0, 100%, 40%);">-             and port of the MSC's MGW; from MGW CRCX ACK (BTS) the conn->user_plane.mgw_endpoint; The</span><br><span style="color: hsl(0, 100%, 40%);">-                Call-ID, which we actually derive from the SCCP connection ID"];</span><br><span style="color: hsl(0, 100%, 40%);">-   bsc_gscon abox bsc_gscon [label="ST_HANDOVER_MT_WAIT_CRCX_MSC"];</span><br><span style="color: hsl(0, 100%, 40%);">-      bsc_gscon -> bsc_mgcp [label="mgcp_conn_create()"];</span><br><span style="color: hsl(0, 100%, 40%);">-        bsc_mgcp note bsc_mgcp [label="second mgcp FSM for MSC side"];</span><br><span style="color: hsl(0, 100%, 40%);">-        bsc_mgcp => mgw_msc [label="CRCX (for MSC)"];</span><br><span style="color: hsl(0, 100%, 40%);">-      ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    --- [label="On Timeout"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_mgcp note bsc_mgcp [label="On timeout, the MGCP FSM will terminate, emitting the parent_term</span><br><span style="color: hsl(0, 100%, 40%);">-           event set upon mgcp_conn_create():"];</span><br><span style="color: hsl(0, 100%, 40%);">-      bsc_mgcp -> bsc_gscon [label="GSCON_EV_MGW_FAIL_MSC"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_gscon note bsc_gscon [label="GSCON_EV_MGW_FAIL_MSC is handled by the conn FSM allstate</span><br><span style="color: hsl(0, 100%, 40%);">-         handler. It sets conn->user_plane.fi_msc = NULL."];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_gscon -> bsc_lchan [label="LCHAN_EV_RELEASE"];</span><br><span style="color: hsl(0, 100%, 40%);">- bsc_gscon -> bsc_mgcp [label="mgcp_conn_delete() (FSM for BTS)"];</span><br><span style="color: hsl(0, 100%, 40%);">-  bsc_gscon box bsc_gscon [label="handover_end(fail)"];</span><br><span style="color: hsl(0, 100%, 40%);">- bsc_gscon => mgw_msc [label="BSSMAP Handover Failure"];</span><br><span style="color: hsl(0, 100%, 40%);">-    ms note bsc_gscon [label="MS happily continues on the old lchan."];</span><br><span style="color: hsl(0, 100%, 40%);">-   --- [label="END: 'On Timeout'"];</span><br><span style="color: hsl(0, 100%, 40%);">-      ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_mgcp <= mgw_msc [label="CRCX OK (for MSC)"];</span><br><span style="color: hsl(0, 100%, 40%);">-   bsc_gscon <- bsc_mgcp [label="GSCON_EV_MGW_CRCX_RESP_MSC"];</span><br><span style="color: hsl(0, 100%, 40%);">-        bsc_gscon abox bsc_gscon [label="ST_HANDOVER_MT_WAIT_LCHAN"];</span><br><span style="color: hsl(0, 100%, 40%);">- --- [label="END: chan_mode a speech mode?"];</span><br><span style="color: hsl(0, 100%, 40%);">-  --- [label="END: lchan FSM decides that it is an lchan for speech"];</span><br><span style="color: hsl(0, 100%, 40%);">-  ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    ...;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_lchan note bsc_lchan [label="TODO: when does the MS send RLL Establish Ind? I guess like</span><br><span style="color: hsl(0, 100%, 40%);">-               this:"];</span><br><span style="color: hsl(0, 100%, 40%);">-   bsc_lchan abox bsc_lchan [label="LCHAN_ST_WAIT_RLL_ESTABLISH"];</span><br><span style="color: hsl(0, 100%, 40%);">-       ms => bsc_lchan [label="RLL Establish Ind"];</span><br><span style="color: hsl(0, 100%, 40%);">-       bsc_lchan abox bsc_lchan [label="LCHAN_ST_ACTIVE"];</span><br><span style="color: hsl(0, 100%, 40%);">-   bsc_lchan -> bsc_gscon [label="GSCON_EV_LCHAN_ACTIVE"];</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_gscon abox bsc_gscon [label="ST_HANDOVER_MT_\nWAIT_HO_ACCEPT\nsanity timer?"];</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_gscon box bsc_gscon [label="Compose RR Handover Command"];</span><br><span style="color: hsl(0, 100%, 40%);">-        bsc_gscon => mgw_msc [label="BSSMAP Handover Request Acknowledge"];</span><br><span style="color: hsl(0, 100%, 40%);">-        mgw_msc note mgw_msc [label="MSC forwards the RR HO Cmd to the remote BSS"];</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    --- [label="On timeout"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_lchan <- bsc_gscon [label="NEW lchan: LCHAN_EV_RELEASE"];</span><br><span style="color: hsl(0, 100%, 40%);">-      ms <=> bsc_lchan [label="release procedure (async)"];</span><br><span style="color: hsl(0, 100%, 40%);">-   bsc_gscon box bsc_gscon [label="handover_end(fail)"];</span><br><span style="color: hsl(0, 100%, 40%);">- bsc_gscon abox bsc_gscon [label="ST_WAIT_CLEAR_CMD"];</span><br><span style="color: hsl(0, 100%, 40%);">- bsc_gscon => mgw_msc [label="BSSMAP Clear Request"];</span><br><span style="color: hsl(0, 100%, 40%);">-       bsc_gscon -> bsc_mgcp [label="mgcp_conn_delete()"];</span><br><span style="color: hsl(0, 100%, 40%);">-        ms note bsc_gscon [label="MS happily continues on the old lchan."];</span><br><span style="color: hsl(0, 100%, 40%);">-   --- [label="END: On timeout"];</span><br><span style="color: hsl(0, 100%, 40%);">-        ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    ms => bsc_gscon [label="RR Handover Accept"];</span><br><span style="color: hsl(0, 100%, 40%);">-      bsc_gscon => mgw_msc [label="BSSMAP Handover Detect"];</span><br><span style="color: hsl(0, 100%, 40%);">-     mgw_msc note mgw_msc [label="MSC switches call to new path"];</span><br><span style="color: hsl(0, 100%, 40%);">- bsc_gscon abox bsc_gscon [label="ST_HANDOVER_MT_WAIT_SABM\nT3105"];</span><br><span style="color: hsl(0, 100%, 40%);">-   ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    ms => bsc_gscon [label="SABM"];</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_lchan note bsc_lchan [label="SABM: Layer 2 message containing ?"];</span><br><span style="color: hsl(0, 100%, 40%);">-        bsc_gscon abox bsc_gscon [label="ST_HANDOVER_MT_\nWAIT_MDCX_BTS\nT?"];</span><br><span style="color: hsl(0, 100%, 40%);">-        bsc_lchan note bsc_lchan [label="TODO: what is UA?"];</span><br><span style="color: hsl(0, 100%, 40%);">- ms <= bsc_gscon [label="RR UA"];</span><br><span style="color: hsl(0, 100%, 40%);">-   bsc_gscon note bsc_gscon [label="TODO: at what point do we know the information needed for BTS</span><br><span style="color: hsl(0, 100%, 40%);">-             MDCX?"];</span><br><span style="color: hsl(0, 100%, 40%);">-   bsc_gscon -> bsc_mgcp [label="mgcp_conn_modify()"];</span><br><span style="color: hsl(0, 100%, 40%);">-        bsc_mgcp abox bsc_mgcp [label="ST_MDCX_RESP"];</span><br><span style="color: hsl(0, 100%, 40%);">-        bsc_mgcp => mgw_msc [label="MDCX (for BTS)"];</span><br><span style="color: hsl(0, 100%, 40%);">-      ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    --- [label="Should the Handover Complete arrive early"];</span><br><span style="color: hsl(0, 100%, 40%);">-      ms => bsc_gscon [label="RR Handover Complete"];</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_gscon box bsc_gscon [label="handover_complete_received = true"];</span><br><span style="color: hsl(0, 100%, 40%);">-  ---;</span><br><span style="color: hsl(0, 100%, 40%);">-    ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    --- [label="On timeout of the mgcp FSM"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_gscon note mgw_msc [label="MGCP FSM terminates"];</span><br><span style="color: hsl(0, 100%, 40%);">- bsc_gscon <- bsc_mgcp [label="GSCON_EV_MGW_FAIL_BTS"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_lchan note bsc_gscon [label="The phone has already taken on the new lchan, but now we happen</span><br><span style="color: hsl(0, 100%, 40%);">-           to not be able to use it. The only sensible thing is to end the conn."];</span><br><span style="color: hsl(0, 100%, 40%);">-   bsc_gscon abox bsc_gscon [label="ST_WAIT_CLEAR_CMD"];</span><br><span style="color: hsl(0, 100%, 40%);">- bsc_gscon => mgw_msc [label="BSSMAP Clear Request\n(Equipment Failure)"];</span><br><span style="color: hsl(0, 100%, 40%);">-  bsc_lchan <- bsc_gscon [label="NEW lchan: LCHAN_EV_RELEASE"];</span><br><span style="color: hsl(0, 100%, 40%);">-      ms <=> bsc_lchan [label="release procedure (async)"];</span><br><span style="color: hsl(0, 100%, 40%);">-   bsc_gscon -> bsc_mgcp [label="mgcp_conn_delete()"];</span><br><span style="color: hsl(0, 100%, 40%);">-        --- [label="END: On timeout of the mgcp FSM"];</span><br><span style="color: hsl(0, 100%, 40%);">-        ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_mgcp <= mgw_msc [label="MDCX OK"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_mgcp abox bsc_mgcp [label="ST_READY"];</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_mgcp -> bsc_gscon [label="GSCON_EV_MGW_MDCX_RESP_BTS"];</span><br><span style="color: hsl(0, 100%, 40%);">-        --- [label="IF !handover_complete_received"];</span><br><span style="color: hsl(0, 100%, 40%);">- bsc_gscon abox bsc_gscon [label="ST_HANDOVER_MT_WAIT_HO_COMPL\nT?"];</span><br><span style="color: hsl(0, 100%, 40%);">-  --- [label="ELSE"];</span><br><span style="color: hsl(0, 100%, 40%);">-   bsc_gscon -> bsc_gscon [label="gscon_handover_post_complete()"];</span><br><span style="color: hsl(0, 100%, 40%);">-   ---;</span><br><span style="color: hsl(0, 100%, 40%);">-    ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    ms => bsc_gscon [label="RR Handover Complete"];</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_gscon box bsc_gscon [label="gscon_handover_post_complete()"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_gscon => mgw_msc [label="BSSMAP Handover Complete"];</span><br><span style="color: hsl(0, 100%, 40%);">-   bsc_gscon note bsc_gscon [label="handover_end(success), conn->ho = NULL"];</span><br><span style="color: hsl(0, 100%, 40%);">- bsc_gscon abox bsc_gscon [label="ST_ACTIVE"];</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span>diff --git a/doc/handover-inter-bsc-out-fsm.dot b/doc/handover-inter-bsc-out-fsm.dot</span><br><span>new file mode 100644</span><br><span>index 0000000..9661b6f</span><br><span>--- /dev/null</span><br><span>+++ b/doc/handover-inter-bsc-out-fsm.dot</span><br><span>@@ -0,0 +1,27 @@</span><br><span style="color: hsl(120, 100%, 40%);">+digraph G {</span><br><span style="color: hsl(120, 100%, 40%);">+rankdir=TB</span><br><span style="color: hsl(120, 100%, 40%);">+labelloc=t; label="Handover FSM: Inter-BSC Outgoing"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      invisible [style=invisible]</span><br><span style="color: hsl(120, 100%, 40%);">+   invisible -> ho_out [label="Measurement Report\nincluding neighbor\nBSS ARFCN",style=dotted]</span><br><span style="color: hsl(120, 100%, 40%);">+        ho_out [label="inter-BSC HO Outgoing",shape=box]</span><br><span style="color: hsl(120, 100%, 40%);">+        msc [label="MSC",shape=box3d]</span><br><span style="color: hsl(120, 100%, 40%);">+        new_bsc [label="new BSC",shape=box3d]</span><br><span style="color: hsl(120, 100%, 40%);">+       lchan [label="lchan",shape=box3d]</span><br><span style="color: hsl(120, 100%, 40%);">+        terminate [shape=octagon]</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      ho_out -> HO_OUT_ST_WAIT_HO_COMMAND [label="handover_start()"]</span><br><span style="color: hsl(120, 100%, 40%);">+   HO_OUT_ST_WAIT_HO_COMMAND -> msc [label="BSSMAP Handover\nRequired",style=dotted]</span><br><span style="color: hsl(120, 100%, 40%);">+        msc -> new_bsc [label="BSSMAP Handover\nRequest",style=dotted]</span><br><span style="color: hsl(120, 100%, 40%);">+   new_bsc -> msc [label="BSSMAP Handover\nRequest Ack",style=dotted]</span><br><span style="color: hsl(120, 100%, 40%);">+       msc -> HO_OUT_ST_WAIT_HO_COMMAND [label="BSSMAP Handover\nCommand",style=dotted]</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       HO_OUT_ST_WAIT_HO_COMMAND -> lchan [label="RR Handover\nCommand\nfrom new BSC",style=dotted]</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   HO_OUT_ST_WAIT_HO_COMMAND -> HO_OUT_ST_WAIT_CLEAR</span><br><span style="color: hsl(120, 100%, 40%);">+  msc -> HO_OUT_ST_WAIT_CLEAR [label="BSSMAP\nClear\nCommand",style=dotted]</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      HO_OUT_ST_WAIT_CLEAR -> terminate</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/doc/handover-inter-bsc-out.msc b/doc/handover-inter-bsc-out.msc</span><br><span>new file mode 100644</span><br><span>index 0000000..733b4da</span><br><span>--- /dev/null</span><br><span>+++ b/doc/handover-inter-bsc-out.msc</span><br><span>@@ -0,0 +1,47 @@</span><br><span style="color: hsl(120, 100%, 40%);">+msc {</span><br><span style="color: hsl(120, 100%, 40%);">+   hscale=2;</span><br><span style="color: hsl(120, 100%, 40%);">+     ms [label="MS/BTS"], ho[label="BSC Handover FSM"], gscon[label="BSC conn FSM"], msc_[label="MSC"];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  ms note msc_ [label="inter-BSC Handover to another BSS"];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ gscon abox gscon [label="ST_ACTIVE"];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     ms => ho [label="Measurement Report"];</span><br><span style="color: hsl(120, 100%, 40%);">+   ho box ho [label="Handover Decision"];</span><br><span style="color: hsl(120, 100%, 40%);">+      ho box ho [label="handover_request\n(struct handover_out_req)"];</span><br><span style="color: hsl(120, 100%, 40%);">+    ho note gscon [label="To make sure the conn FSM permits a handover, trigger an event:"];</span><br><span style="color: hsl(120, 100%, 40%);">+    ho -> gscon [label="GSCON_EV_HANDOVER_START\ndata=handover_out_req"];</span><br><span style="color: hsl(120, 100%, 40%);">+    gscon abox gscon [label="ST_HANDOVER"];</span><br><span style="color: hsl(120, 100%, 40%);">+     ho <- gscon [label="handover_start\n(handover_out_req)"];</span><br><span style="color: hsl(120, 100%, 40%);">+        ho box ho [label="handover_start_inter_bsc_out()"];</span><br><span style="color: hsl(120, 100%, 40%);">+ ho => msc_ [label="BSSMAP Handover Required"];</span><br><span style="color: hsl(120, 100%, 40%);">+   ho abox ho [label="HO_OUT_ST_WAIT_HO_COMMAND"];</span><br><span style="color: hsl(120, 100%, 40%);">+     ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  --- [label="On Timeout"];</span><br><span style="color: hsl(120, 100%, 40%);">+   ho box ho [label="handover_end(fail)"];</span><br><span style="color: hsl(120, 100%, 40%);">+     ho -> gscon [label="GSCON_EV_HANDOVER_END"];</span><br><span style="color: hsl(120, 100%, 40%);">+     gscon abox gscon [label="ST_ACTIVE"];</span><br><span style="color: hsl(120, 100%, 40%);">+       ms note gscon [label="MS happily continues on the old lchan."];</span><br><span style="color: hsl(120, 100%, 40%);">+     --- [label="END: 'On Timeout'"];</span><br><span style="color: hsl(120, 100%, 40%);">+    ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  ho <= msc_ [label="BSSMAP Handover Command\n HO_OUT_EV_BSSMAP_HO_COMMAND"];</span><br><span style="color: hsl(120, 100%, 40%);">+      ms <= ho [label="Forward L3 Info (RR Handover Command from new BSS)"];</span><br><span style="color: hsl(120, 100%, 40%);">+   ho abox ho [label="HO_OUT_ST_WAIT_CLEAR"];</span><br><span style="color: hsl(120, 100%, 40%);">+  ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  gscon abox gscon [label="ST_HANDOVER_MO_\nWAIT_CLEAR_CMD\nT8"];</span><br><span style="color: hsl(120, 100%, 40%);">+     ms <= gscon [label="RR Handover Command"];</span><br><span style="color: hsl(120, 100%, 40%);">+       ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  ho rbox gscon [label="On Timeout: same as above"];</span><br><span style="color: hsl(120, 100%, 40%);">+  ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  msc_ note msc_ [label="Remote BSS reported Handover Complete to the MSC,</span><br><span style="color: hsl(120, 100%, 40%);">+      this connection has been superseded."];</span><br><span style="color: hsl(120, 100%, 40%);">+     gscon <= msc_ [label="BSSMAP Clear Command\n GSCON_EV_A_CLEAR_CMD"];</span><br><span style="color: hsl(120, 100%, 40%);">+     gscon abox gscon [label="ST_CLEARING"];</span><br><span style="color: hsl(120, 100%, 40%);">+     gscon => msc_ [label="BSSMAP Clear Complete"];</span><br><span style="color: hsl(120, 100%, 40%);">+   ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  gscon <= msc_ [label="DISC IND\n GSCON_EV_A_DISC_IND"];</span><br><span style="color: hsl(120, 100%, 40%);">+  ho abox ho [label="terminate\n(child of conn FSM)"];</span><br><span style="color: hsl(120, 100%, 40%);">+        gscon abox gscon [label="terminate"];</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/doc/handover-intra-bsc-fsm.dot b/doc/handover-intra-bsc-fsm.dot</span><br><span>new file mode 100644</span><br><span>index 0000000..7cb0d3c</span><br><span>--- /dev/null</span><br><span>+++ b/doc/handover-intra-bsc-fsm.dot</span><br><span>@@ -0,0 +1,30 @@</span><br><span style="color: hsl(120, 100%, 40%);">+digraph G {</span><br><span style="color: hsl(120, 100%, 40%);">+rankdir=TB</span><br><span style="color: hsl(120, 100%, 40%);">+labelloc=t; label="Handover FSM: Intra-BSC"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        lchan [label="lchan FSM",shape=box3d]</span><br><span style="color: hsl(120, 100%, 40%);">+        intra [label="intra-BSC HO",shape=box]</span><br><span style="color: hsl(120, 100%, 40%);">+        old_lchan [label="old lchan",shape=box3d]</span><br><span style="color: hsl(120, 100%, 40%);">+ terminate [shape=octagon]</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   invisible [style="invisible"]</span><br><span style="color: hsl(120, 100%, 40%);">+       invisible -> intra [label="Measurement Report",style=dotted]</span><br><span style="color: hsl(120, 100%, 40%);">+     invisible -> old_lchan [style=invisible,arrowhead=none]</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  intra -> WAIT_LCHAN_ACTIVE [label="handover_start()",style=dotted]</span><br><span style="color: hsl(120, 100%, 40%);">+        WAIT_LCHAN_ACTIVE -> lchan [label="lchan_activate(FOR_HANDOVER)",style=dotted]</span><br><span style="color: hsl(120, 100%, 40%);">+  lchan -> WAIT_LCHAN_ACTIVE [label="HO_EV_\nLCHAN_\nACTIVE,ERROR",style=dotted,constraint=false]</span><br><span style="color: hsl(120, 100%, 40%);">+        WAIT_LCHAN_ACTIVE -> WAIT_RR_HO_DETECT</span><br><span style="color: hsl(120, 100%, 40%);">+        WAIT_RR_HO_DETECT -> old_lchan [label="RR Handover\nCommand",style=dotted,constraint=false]</span><br><span style="color: hsl(120, 100%, 40%);">+     </span><br><span style="color: hsl(120, 100%, 40%);">+      lchan -> WAIT_RR_HO_DETECT [label="RR Handover\nDetect",style=dotted]</span><br><span style="color: hsl(120, 100%, 40%);">+    WAIT_RR_HO_DETECT -> WAIT_RR_HO_COMPLETE</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan -> WAIT_RR_HO_COMPLETE [label="RR Handover\nComplete",style=dotted]</span><br><span style="color: hsl(120, 100%, 40%);">+        WAIT_RR_HO_COMPLETE -> WAIT_LCHAN_ESTABLISHED</span><br><span style="color: hsl(120, 100%, 40%);">+      lchan -> WAIT_LCHAN_ESTABLISHED [label="HO_EV_LCHAN_\nESTABLISHED",style=dotted]</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       WAIT_LCHAN_ESTABLISHED -> terminate [label="non-TCH"]</span><br><span style="color: hsl(120, 100%, 40%);">+    WAIT_LCHAN_ESTABLISHED -> WAIT_MGW_ENDPOINT_TO_MSC</span><br><span style="color: hsl(120, 100%, 40%);">+ WAIT_MGW_ENDPOINT_TO_MSC -> terminate [label="handover_end()"]</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/doc/handover.msc b/doc/handover.msc</span><br><span>index 7529de6..1a2580a 100644</span><br><span>--- a/doc/handover.msc</span><br><span>+++ b/doc/handover.msc</span><br><span>@@ -1,123 +1,82 @@</span><br><span> # Handover between cells, intra-BSC</span><br><span> msc {</span><br><span style="color: hsl(0, 100%, 40%);">-        hscale=3;</span><br><span style="color: hsl(0, 100%, 40%);">-       ms [label="MS via BTS"], bsc_lchan[label="BSC lchan FSM"], bsc_gscon[label="BSC conn FSM"],</span><br><span style="color: hsl(0, 100%, 40%);">-       bsc_mgcp[label="BSC mgcp FSM"], mgw_msc[label="MGW/MSC"];</span><br><span style="color: hsl(120, 100%, 40%);">+ hscale=2;</span><br><span style="color: hsl(120, 100%, 40%);">+     ms [label="MS via BTS"], lchan[label="BSC lchan FSM"], ho[label="BSC Handover FSM"],</span><br><span style="color: hsl(120, 100%, 40%);">+    gscon[label="BSC conn FSM"], msc_[label="MSC"];</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- ms note mgw_msc [label="intra-BSC Handover sequence"];</span><br><span style="color: hsl(120, 100%, 40%);">+      ms note msc_ [label="intra-BSC Handover"];</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        bsc_gscon abox bsc_gscon [label="ST_ACTIVE"];</span><br><span style="color: hsl(0, 100%, 40%);">- bsc_gscon box bsc_gscon [label="bsc_handover_start(): init conn->ho"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_gscon -> bsc_gscon [label="GSCON_EV_HO_START (intra-BSC)"];</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_gscon abox bsc_gscon [label="ST_HANDOVER_\nWAIT_LCHAN"];</span><br><span style="color: hsl(0, 100%, 40%);">-  bsc_lchan <- bsc_gscon [label="lchan_activate(lchan, FOR_HANDOVER)"];</span><br><span style="color: hsl(120, 100%, 40%);">+    gscon abox gscon [label="ST_ACTIVE"];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     ms => ho [label="Measurement Report"];</span><br><span style="color: hsl(120, 100%, 40%);">+   ho box ho [label="Handover Decision"];</span><br><span style="color: hsl(120, 100%, 40%);">+      ho box ho [label="handover_request\n(struct handover_out_req)"];</span><br><span style="color: hsl(120, 100%, 40%);">+    ho note gscon [label="To make sure the conn FSM permits a handover, trigger an event:"];</span><br><span style="color: hsl(120, 100%, 40%);">+    ho -> gscon [label="GSCON_EV_HANDOVER_START\ndata=handover_out_req"];</span><br><span style="color: hsl(120, 100%, 40%);">+    gscon abox gscon [label="ST_HANDOVER"];</span><br><span style="color: hsl(120, 100%, 40%);">+     ho <- gscon [label="handover_start\n(handover_out_req)"];</span><br><span style="color: hsl(120, 100%, 40%);">+        ho box ho [label="handover_start_intra_bsc()"];</span><br><span style="color: hsl(120, 100%, 40%);">+     ho abox ho [label="allocate\nHO_ST_NOT_STARTED"];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>        ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    --- [label="on lchan FSM error or timeout"];</span><br><span style="color: hsl(0, 100%, 40%);">-  bsc_lchan -> bsc_gscon [label="GSCON_EV_LCHAN_ALLOC_ERROR"];</span><br><span style="color: hsl(0, 100%, 40%);">-       bsc_gscon box bsc_gscon [label="handover_end(fail)"];</span><br><span style="color: hsl(0, 100%, 40%);">- ms note bsc_gscon [label="MS happily continues on the old lchan."];</span><br><span style="color: hsl(0, 100%, 40%);">-   bsc_gscon abox bsc_gscon [label="ST_ACTIVE"];</span><br><span style="color: hsl(0, 100%, 40%);">- --- [label="END: 'on error'"];</span><br><span style="color: hsl(120, 100%, 40%);">+      ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  --- [label="On any error or timeout"];</span><br><span style="color: hsl(120, 100%, 40%);">+      ho box ho [label="handover_end(fail)"];</span><br><span style="color: hsl(120, 100%, 40%);">+     ho -> gscon [label="GSCON_EV_HANDOVER_END"];</span><br><span style="color: hsl(120, 100%, 40%);">+     gscon abox gscon [label="ST_ACTIVE"];</span><br><span style="color: hsl(120, 100%, 40%);">+       ms note gscon [label="MS happily continues on the old lchan."];</span><br><span style="color: hsl(120, 100%, 40%);">+     --- [label="END: 'On any error or timeout'"];</span><br><span>      ...;</span><br><span>         ...;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        --- [label="IF lchan FSM decides that it is an lchan for speech"];</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_lchan -> bsc_gscon [label="GSCON_EV_ENSURE_MGW_ENDPOINT"];</span><br><span style="color: hsl(0, 100%, 40%);">-     --- [label="IF there is an MGW endpoint for the BTS already (conn->user_plane.fi_bts)"];</span><br><span style="color: hsl(0, 100%, 40%);">-   bsc_gscon box bsc_gscon [label="handover_created_mgw_endpoint = false"];</span><br><span style="color: hsl(0, 100%, 40%);">-      bsc_gscon -> bsc_lchan [label="LCHAN_EV_MGW_ENDPOINT_AVAILABLE"];</span><br><span style="color: hsl(0, 100%, 40%);">-  --- [label="ELSE: no MGW endpoint for the BTS side yet"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_gscon abox bsc_gscon [label="ST_HANDOVER_\nWAIT_CRCX_BTS"];</span><br><span style="color: hsl(0, 100%, 40%);">-       bsc_gscon box bsc_gscon [label="handover_created_mgw_endpoint = true"];</span><br><span style="color: hsl(0, 100%, 40%);">-       bsc_gscon -> bsc_mgcp [label="mgcp_conn_create()"];</span><br><span style="color: hsl(0, 100%, 40%);">-        bsc_mgcp => mgw_msc [label="CRCX (for BTS)"];</span><br><span style="color: hsl(0, 100%, 40%);">-      bsc_mgcp abox bsc_mgcp [label="ST_CRCX_RESP (MGCP_MGW_TIMEOUT = 4s)"];</span><br><span style="color: hsl(0, 100%, 40%);">-        bsc_gscon note bsc_mgcp [label="conn FSM relies on mgcp FSM timeout"];</span><br><span style="color: hsl(0, 100%, 40%);">-        ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    --- [label="On Timeout"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_mgcp note bsc_mgcp [label="On timeout, the MGCP FSM will terminate, emitting the parent_term</span><br><span style="color: hsl(0, 100%, 40%);">-           event set upon mgcp_conn_create():"];</span><br><span style="color: hsl(0, 100%, 40%);">-      bsc_mgcp -> bsc_gscon [label="GSCON_EV_MGW_FAIL_BTS"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_gscon note bsc_gscon [label="GSCON_EV_MGW_FAIL_BTS is handled by the conn FSM allstate</span><br><span style="color: hsl(0, 100%, 40%);">-         handler. It sets conn->user_plane.fi_bts = NULL."];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_gscon -> bsc_lchan [label="LCHAN_EV_MGW_ENDPOINT_ERROR"];</span><br><span style="color: hsl(0, 100%, 40%);">-      bsc_lchan note bsc_gscon [label="conn FSM error handler exits and relies on the lchan FSM</span><br><span style="color: hsl(0, 100%, 40%);">-          signalling error, which should actually happen immediately:"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_gscon <- bsc_lchan [label="GSCON_EV_LCHAN_ALLOC_ERROR"];</span><br><span style="color: hsl(0, 100%, 40%);">-       bsc_gscon box bsc_gscon [label="handover_end(fail)"];</span><br><span style="color: hsl(0, 100%, 40%);">- --- [label="IF handover_created_mgw_endpoint == true"];</span><br><span style="color: hsl(0, 100%, 40%);">-       bsc_gscon -> bsc_mgcp [label="mgcp_conn_delete()"];</span><br><span style="color: hsl(0, 100%, 40%);">-        ---;</span><br><span style="color: hsl(0, 100%, 40%);">-    ms note bsc_gscon [label="MS happily continues on the old lchan."];</span><br><span style="color: hsl(0, 100%, 40%);">-   bsc_gscon abox bsc_gscon [label="ST_ACTIVE"];</span><br><span style="color: hsl(0, 100%, 40%);">- --- [label="END: 'On Timeout'"];</span><br><span style="color: hsl(0, 100%, 40%);">-      ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  ho box ho [label="lchan_select_by_type()"];</span><br><span style="color: hsl(120, 100%, 40%);">+ ho abox ho [label="HO_ST_WAIT_\nLCHAN_ACTIVE"];</span><br><span style="color: hsl(120, 100%, 40%);">+     lchan <- ho [label="lchan_activate(FOR_HANDOVER)"];</span><br><span style="color: hsl(120, 100%, 40%);">+      lchan rbox lchan [label="(most details omitted, see lchan_fsm diagrams)"];</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        bsc_mgcp <= mgw_msc [label="CRCX OK (for BTS)"];</span><br><span style="color: hsl(0, 100%, 40%);">-   bsc_mgcp box bsc_mgcp [label="libosmo-mgcp-client fsm_crcx_resp_cb()"];</span><br><span style="color: hsl(0, 100%, 40%);">-       bsc_mgcp abox bsc_mgcp [label="ST_READY"];</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_mgcp -> bsc_gscon [label="GSCON_EV_MGW_CRCX_RESP_BTS"];</span><br><span style="color: hsl(0, 100%, 40%);">-        bsc_gscon abox bsc_gscon [label="ST_HANDOVER_\nWAIT_LCHAN"];</span><br><span style="color: hsl(0, 100%, 40%);">-  bsc_gscon -> bsc_lchan [label="LCHAN_EV_MGW_ENDPOINT_AVAILABLE"];</span><br><span style="color: hsl(0, 100%, 40%);">-  --- [label="END: lchan FSM decides that it is an lchan for speech"];</span><br><span style="color: hsl(120, 100%, 40%);">+        ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  --- [label="On lchan error or timeout"];</span><br><span style="color: hsl(120, 100%, 40%);">+    lchan -> ho [label="HO_EV_LCHAN_ERROR"];</span><br><span style="color: hsl(120, 100%, 40%);">+ ho rbox gscon [label="same as above"];</span><br><span style="color: hsl(120, 100%, 40%);">+      --- [label="END: 'On lchan error or timeout'"];</span><br><span>    ...;</span><br><span>         ...;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        bsc_lchan -> bsc_gscon [label="GSCON_EV_LCHAN_ACTIVE"];</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_gscon abox bsc_gscon [label="ST_HANDOVER_\nWAIT_DETECT\nT3103"];</span><br><span style="color: hsl(0, 100%, 40%);">-  bsc_gscon box bsc_gscon [label="gsm48_send_ho_cmd()"];</span><br><span style="color: hsl(0, 100%, 40%);">-        ms <= bsc_gscon [label="RR Handover Command"];</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(120, 100%, 40%);">+   lchan abox lchan [label="LCHAN_ST_WAIT_ACTIV_ACK"];</span><br><span style="color: hsl(120, 100%, 40%);">+ ms <= lchan [label="RSL Chan Activ"];</span><br><span>   ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    --- [label="On timeout"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_lchan <- bsc_gscon [label="NEW lchan: LCHAN_EV_RELEASE"];</span><br><span style="color: hsl(0, 100%, 40%);">-      ms <=> bsc_lchan [label="release procedure (async)"];</span><br><span style="color: hsl(0, 100%, 40%);">-   bsc_gscon box bsc_gscon [label="handover_end(fail)"];</span><br><span style="color: hsl(0, 100%, 40%);">- --- [label="IF handover_created_mgw_endpoint == true"];</span><br><span style="color: hsl(0, 100%, 40%);">-       bsc_gscon -> bsc_mgcp [label="mgcp_conn_delete()"];</span><br><span style="color: hsl(0, 100%, 40%);">-        ---;</span><br><span style="color: hsl(0, 100%, 40%);">-    ms note bsc_gscon [label="MS happily continues on the old lchan."];</span><br><span style="color: hsl(0, 100%, 40%);">-   bsc_gscon abox bsc_gscon [label="ST_ACTIVE"];</span><br><span style="color: hsl(0, 100%, 40%);">- --- [label="END: On timeout"];</span><br><span style="color: hsl(120, 100%, 40%);">+      ms => lchan [label="RSL Chan Activ ACK"];</span><br><span style="color: hsl(120, 100%, 40%);">+        lchan -> ho [label="HO_EV_LCHAN_ACTIVE"];</span><br><span style="color: hsl(120, 100%, 40%);">+        ho abox ho [label="HO_ST_WAIT_\nRR_HO_DETECT"];</span><br><span>    ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    ms => bsc_gscon [label="RR Handover Detect"];</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      bsc_gscon abox bsc_gscon [label="ST_HANDOVER_\nWAIT_MDCX_BTS\ncontinue T3103"];</span><br><span style="color: hsl(0, 100%, 40%);">-       bsc_gscon -> bsc_lchan [label="OLD lchan: LCHAN_EV_RELEASE"];</span><br><span style="color: hsl(0, 100%, 40%);">-      ms <=> bsc_lchan [label="release procedure (async)"];</span><br><span style="color: hsl(0, 100%, 40%);">-   bsc_lchan note bsc_gscon [label="officially take over new lchan: conn->lchan = ho->new_lchan"];</span><br><span style="color: hsl(0, 100%, 40%);">- bsc_gscon -> bsc_mgcp [label="mgcp_conn_modify()"];</span><br><span style="color: hsl(0, 100%, 40%);">-        bsc_mgcp note bsc_mgcp [label="mgcp FSM that was established for old lchan, for BTS side"];</span><br><span style="color: hsl(0, 100%, 40%);">-   bsc_mgcp abox bsc_mgcp [label="ST_MDCX_RESP"];</span><br><span style="color: hsl(0, 100%, 40%);">-        bsc_mgcp => mgw_msc [label="MDCX (for BTS)"];</span><br><span style="color: hsl(120, 100%, 40%);">+    ms => ho [label="RR Handover Detect\nHO_EV_RR_HO_DETECT"];</span><br><span style="color: hsl(120, 100%, 40%);">+       lchan note ho [label="At this point we should start to switch the MGW over to the new lchan.</span><br><span style="color: hsl(120, 100%, 40%);">+             But this is not implemented yet, as was not before introducing these FSMs."];</span><br><span style="color: hsl(120, 100%, 40%);">+    ho abox ho [label="HO_ST_WAIT_\nRR_HO_COMPLETE"];</span><br><span>  ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    --- [label="Should the Handover Complete arrive early"];</span><br><span style="color: hsl(0, 100%, 40%);">-      ms => bsc_gscon [label="RR Handover Complete"];</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_gscon box bsc_gscon [label="handover_complete_received = true"];</span><br><span style="color: hsl(0, 100%, 40%);">-  ---;</span><br><span style="color: hsl(120, 100%, 40%);">+  lchan note ho [label="The lchan FSM will continue with RSL and RTP while the HO FSM waits.</span><br><span style="color: hsl(120, 100%, 40%);">+               HO_EV_LCHAN_ESTABLISHED means that both RSL and RTP are established.</span><br><span style="color: hsl(120, 100%, 40%);">+          Usually, RTP will be done first, and the HO_EV_LCHAN_ESTABLISHED may be</span><br><span style="color: hsl(120, 100%, 40%);">+               received even before HO_EV_RR_HO_COMPLETE.</span><br><span style="color: hsl(120, 100%, 40%);">+            ho_fsm_wait_lchan_established_onenter() decides whether to wait or not."];</span><br><span>      ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    --- [label="On timeout of the mgcp FSM"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_gscon note mgw_msc [label="MGCP FSM terminates"];</span><br><span style="color: hsl(0, 100%, 40%);">- bsc_gscon <- bsc_mgcp [label="GSCON_EV_MGW_FAIL_BTS"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_lchan note bsc_gscon [label="The phone has already taken on the new lchan, but now we happen</span><br><span style="color: hsl(0, 100%, 40%);">-           to not be able to use it. The only sensible thing is to end the conn."];</span><br><span style="color: hsl(0, 100%, 40%);">-   bsc_gscon abox bsc_gscon [label="ST_WAIT_CLEAR_CMD"];</span><br><span style="color: hsl(0, 100%, 40%);">- bsc_gscon => mgw_msc [label="BSSMAP Clear Request\n(Equipment Failure)"];</span><br><span style="color: hsl(0, 100%, 40%);">-  bsc_lchan <- bsc_gscon [label="NEW lchan: LCHAN_EV_RELEASE"];</span><br><span style="color: hsl(0, 100%, 40%);">-      ms <=> bsc_lchan [label="release procedure (async)"];</span><br><span style="color: hsl(0, 100%, 40%);">-   bsc_gscon -> bsc_mgcp [label="mgcp_conn_delete()"];</span><br><span style="color: hsl(120, 100%, 40%);">+      ms => lchan [label="RSL EST IND"];</span><br><span style="color: hsl(120, 100%, 40%);">+       lchan -> ho [label="HO_EV_LCHAN_ESTABLISHED",ID="(may come as early as this, or...)"];</span><br><span style="color: hsl(120, 100%, 40%);">+ ms => ho [label="RR Handover Complete (from EST IND)\n HO_EV_RR_HO_COMPLETE"];</span><br><span style="color: hsl(120, 100%, 40%);">+   ho abox ho [label="HO_ST_WAIT_\nLCHAN_ESTABLISHED"];</span><br><span>       ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_mgcp <= mgw_msc [label="MDCX OK"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_mgcp abox bsc_mgcp [label="ST_READY"];</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_mgcp -> bsc_gscon [label="GSCON_EV_MGW_MDCX_RESP_BTS"];</span><br><span style="color: hsl(0, 100%, 40%);">-        --- [label="IF !handover_complete_received"];</span><br><span style="color: hsl(0, 100%, 40%);">- bsc_gscon abox bsc_gscon [label="ST_HANDOVER_\nWAIT_COMPLETE\ncontinue T3103"];</span><br><span style="color: hsl(0, 100%, 40%);">-       --- [label="ELSE"];</span><br><span style="color: hsl(0, 100%, 40%);">-   bsc_gscon -> bsc_gscon [label="gscon_handover_post_complete()"];</span><br><span style="color: hsl(0, 100%, 40%);">-   ---;</span><br><span style="color: hsl(120, 100%, 40%);">+  lchan rbox lchan [label="when lchan FSM is done with setting up RTP"];</span><br><span style="color: hsl(120, 100%, 40%);">+      lchan -> ho [label="HO_EV_LCHAN_ESTABLISHED",ID="(...may come only now)"];</span><br><span style="color: hsl(120, 100%, 40%);">+     ho abox ho [label="HO_ST_WAIT_\nMGW_ENDPOINT_TO_MSC"];</span><br><span style="color: hsl(120, 100%, 40%);">+      ho -> gscon [label="gscon_connect_mgw_to_msc()"];</span><br><span>       ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    ms => bsc_gscon [label="RR Handover Complete"];</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_gscon box bsc_gscon [label="gscon_handover_post_complete()"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_gscon note bsc_gscon [label="handover_end(success), conn->ho = NULL"];</span><br><span style="color: hsl(0, 100%, 40%);">- bsc_gscon abox bsc_gscon [label="ST_ACTIVE"];</span><br><span style="color: hsl(120, 100%, 40%);">+       ho <- gscon [label="HO_EV_MSC_MGW_OK"];</span><br><span style="color: hsl(120, 100%, 40%);">+  ho box ho [label="handover_end(OK)"];</span><br><span style="color: hsl(120, 100%, 40%);">+       ho -> gscon [label="gscon_change_primary_lchan()"];</span><br><span style="color: hsl(120, 100%, 40%);">+      lchan <- gscon [label="LCHAN_RTP_EV_ESTABLISHED"];</span><br><span style="color: hsl(120, 100%, 40%);">+       ho -> gscon [label="GSCON_EV_HANDOVER_END"];</span><br><span style="color: hsl(120, 100%, 40%);">+     gscon abox gscon [label="ST_ACTIVE"];</span><br><span style="color: hsl(120, 100%, 40%);">+       ho box ho [label="detach from parent to not fire another meaningless GSCON_EV_HANDOVER_END"];</span><br><span style="color: hsl(120, 100%, 40%);">+       ho abox ho [label="terminate"];</span><br><span> }</span><br><span>diff --git a/doc/lchan-fsm.dot b/doc/lchan-fsm.dot</span><br><span>index dbb283c..b726b0c 100644</span><br><span>--- a/doc/lchan-fsm.dot</span><br><span>+++ b/doc/lchan-fsm.dot</span><br><span>@@ -1,38 +1,22 @@</span><br><span> digraph G {</span><br><span style="color: hsl(0, 100%, 40%);">-rankdir=TB;</span><br><span style="color: hsl(120, 100%, 40%);">+rankdir=TB</span><br><span style="color: hsl(120, 100%, 40%);">+labelloc=t; label="lchan FSM"</span><br><span>   </span><br><span>     invisible [style="invisible"]</span><br><span>      UNUSED [penwidth=3.0]</span><br><span style="color: hsl(0, 100%, 40%);">-   WAIT_TS_READY</span><br><span style="color: hsl(0, 100%, 40%);">-   WAIT_MGW_ENDPOINT_AVAILABLE</span><br><span style="color: hsl(0, 100%, 40%);">-     WAIT_ACTIV_ACK</span><br><span style="color: hsl(0, 100%, 40%);">-  WAIT_IPACC_CRCX_ACK</span><br><span style="color: hsl(0, 100%, 40%);">-     WAIT_IPACC_MDCX_ACK</span><br><span style="color: hsl(0, 100%, 40%);">-     WAIT_RLL_ESTABLISH</span><br><span style="color: hsl(0, 100%, 40%);">-      ACTIVE [penwidth=3.0]</span><br><span style="color: hsl(0, 100%, 40%);">-   WAIT_SAPIS_RELEASED</span><br><span style="color: hsl(0, 100%, 40%);">-     WAIT_BEFORE_RF_RELEASE</span><br><span style="color: hsl(0, 100%, 40%);">-  WAIT_RF_RELEASE_ACK</span><br><span style="color: hsl(0, 100%, 40%);">-     WAIT_AFTER_ERROR</span><br><span style="color: hsl(0, 100%, 40%);">-        BORKEN</span><br><span style="color: hsl(120, 100%, 40%);">+        ESTABLISHED [penwidth=3.0]</span><br><span>   </span><br><span style="color: hsl(0, 100%, 40%);">-        ts [label="timeslot FSM",shape=box3d];</span><br><span style="color: hsl(0, 100%, 40%);">-        gscon [label="conn FSM",shape=box3d];</span><br><span style="color: hsl(120, 100%, 40%);">+       ts [label="timeslot FSM",shape=box3d]</span><br><span style="color: hsl(120, 100%, 40%);">+       rtp [label="lchan_rtp\nFSM",shape=box3d]</span><br><span> </span><br><span>       UNUSED -> WAIT_TS_READY [label="lchan_allocate()"]</span><br><span>      WAIT_TS_READY -> WAIT_ACTIV_ACK</span><br><span style="color: hsl(0, 100%, 40%);">-      WAIT_ACTIV_ACK -> WAIT_RLL_ESTABLISH</span><br><span style="color: hsl(0, 100%, 40%);">- WAIT_RLL_ESTABLISH -> WAIT_MGW_ENDPOINT_AVAILABLE [label="TCH"]</span><br><span style="color: hsl(0, 100%, 40%);">-    WAIT_MGW_ENDPOINT_AVAILABLE -> WAIT_IPACC_CRCX_ACK [label="IPACC BTS"]</span><br><span style="color: hsl(0, 100%, 40%);">-     WAIT_MGW_ENDPOINT_AVAILABLE -> ACTIVE</span><br><span style="color: hsl(0, 100%, 40%);">-        WAIT_IPACC_CRCX_ACK -> WAIT_IPACC_MDCX_ACK</span><br><span style="color: hsl(0, 100%, 40%);">-   WAIT_IPACC_MDCX_ACK -> ACTIVE</span><br><span style="color: hsl(0, 100%, 40%);">-        WAIT_RLL_ESTABLISH -> ACTIVE [label="non-TCH"];</span><br><span style="color: hsl(0, 100%, 40%);">-    WAIT_RLL_ESTABLISH -> WAIT_RF_RELEASE_ACK [label="timeout",style=dashed,constraint=false]</span><br><span style="color: hsl(120, 100%, 40%);">+        WAIT_ACTIV_ACK -> WAIT_RLL_RTP_ESTABLISH</span><br><span style="color: hsl(120, 100%, 40%);">+   WAIT_RLL_RTP_ESTABLISH -> ESTABLISHED</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    ACTIVE -> WAIT_SAPIS_RELEASED [label="LCHAN_EV_\nRELEASE"]</span><br><span style="color: hsl(0, 100%, 40%);">- WAIT_SAPIS_RELEASED -> WAIT_BEFORE_RF_RELEASE</span><br><span style="color: hsl(0, 100%, 40%);">-        WAIT_SAPIS_RELEASED -> WAIT_RF_RELEASE_ACK [label="timeout",style=dashed,constraint=false]</span><br><span style="color: hsl(120, 100%, 40%);">+       ESTABLISHED -> WAIT_RLL_RTP_RELEASED [label="LCHAN_EV_\nRELEASE"]</span><br><span style="color: hsl(120, 100%, 40%);">+        WAIT_RLL_RTP_RELEASED -> WAIT_BEFORE_RF_RELEASE</span><br><span style="color: hsl(120, 100%, 40%);">+    WAIT_RLL_RTP_RELEASED -> WAIT_RF_RELEASE_ACK [label="timeout",style=dashed,constraint=false]</span><br><span> </span><br><span>        WAIT_BEFORE_RF_RELEASE -> WAIT_RF_RELEASE_ACK [label="T3111"]</span><br><span>   WAIT_RF_RELEASE_ACK -> UNUSED</span><br><span>@@ -43,11 +27,15 @@</span><br><span>       UNUSED -> ts [label="TS_EV_\nLCHAN_\nUNUSED",style=dotted,penwidth=3]</span><br><span>   ts -> WAIT_TS_READY [label="LCHAN_EV_\nTS_READY",style=dotted]</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+       WAIT_TS_READY -> rtp [label="TCH",style=dotted]</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>       WAIT_TS_READY -> UNUSED [label="error/timeout",style=dashed,constraint=false]</span><br><span>   {WAIT_ACTIV_ACK,WAIT_RF_RELEASE_ACK} -> BORKEN [label="error/timeout",style=dashed]</span><br><span style="color: hsl(0, 100%, 40%);">-        {WAIT_MGW_ENDPOINT_AVAILABLE,WAIT_IPACC_CRCX_ACK,WAIT_IPACC_MDCX_ACK} -> WAIT_SAPIS_RELEASED [label=error,style=dashed]</span><br><span style="color: hsl(120, 100%, 40%);">+    BORKEN -> WAIT_AFTER_ERROR [label="late RF Release ACK"]</span><br><span style="color: hsl(120, 100%, 40%);">+ WAIT_RLL_RTP_ESTABLISH -> WAIT_RLL_RTP_RELEASED [label=error,style=dashed]</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-       WAIT_TS_READY -> gscon [label="GSCON_EV_\nENSURE_\nMGW_ENDPOINT",style=dotted]</span><br><span style="color: hsl(0, 100%, 40%);">-     gscon -> WAIT_MGW_ENDPOINT_AVAILABLE [label="LCHAN_EV_\nMGW_ENDPOINT_\n{AVAILABLE,ERROR}",style=dotted]</span><br><span style="color: hsl(120, 100%, 40%);">+  WAIT_ACTIV_ACK -> rtp [label="LCHAN_RTP_EV_LCHAN_READY",style=dotted]</span><br><span style="color: hsl(120, 100%, 40%);">+    rtp -> WAIT_RLL_RTP_ESTABLISH [label="LCHAN_EV_RTP_READY",style=dotted]</span><br><span style="color: hsl(120, 100%, 40%);">+  rtp -> ESTABLISHED [label="LCHAN_EV_RTP_RELEASED",style=dotted]</span><br><span> </span><br><span> }</span><br><span>diff --git a/doc/lchan-release.msc b/doc/lchan-release.msc</span><br><span>deleted file mode 100644</span><br><span>index 017c9cf..0000000</span><br><span>--- a/doc/lchan-release.msc</span><br><span>+++ /dev/null</span><br><span>@@ -1,83 +0,0 @@</span><br><span style="color: hsl(0, 100%, 40%);">-msc {</span><br><span style="color: hsl(0, 100%, 40%);">-    hscale=2;</span><br><span style="color: hsl(0, 100%, 40%);">-       ms [label="MS"], bts [label="BTS"], bsc[label="BSC"], bsc_lchan[label="BSC lchan FSM"],</span><br><span style="color: hsl(0, 100%, 40%);">- bsc_gscon[label="BSC conn FSM"], msc_[label="MSC"];</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- ms note bsc_gscon [label="various lchan release scenarios"];</span><br><span style="color: hsl(0, 100%, 40%);">-  </span><br><span style="color: hsl(0, 100%, 40%);">-        ms rbox msc_ [label="MSC releases"];</span><br><span style="color: hsl(0, 100%, 40%);">-  bsc_lchan abox bsc_lchan [label="LCHAN_ST_ACTIVE"];</span><br><span style="color: hsl(0, 100%, 40%);">-   bsc_gscon abox bsc_gscon [label="ST_ACTIVE"];</span><br><span style="color: hsl(0, 100%, 40%);">- bsc_gscon <= msc_ [label="BSSMAP Clear Command"];</span><br><span style="color: hsl(0, 100%, 40%);">-  bsc_gscon abox bsc_gscon [label="ST_CLEARING"];</span><br><span style="color: hsl(0, 100%, 40%);">-       bsc_gscon => msc_ [label="BSSMAP Clear Complete"];</span><br><span style="color: hsl(0, 100%, 40%);">- bsc_gscon -> bsc_lchan [label="LCHAN_EV_RELEASE"];</span><br><span style="color: hsl(0, 100%, 40%);">- --- [label="IF SAPIs besides SAPI[0] are active"];</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_lchan abox bsc_lchan [label="LCHAN_ST_WAIT_\nSAPIS_RELEASED\nT3109"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bts <= bsc_lchan [label="RSL Release Request (Local End)..."];</span><br><span style="color: hsl(0, 100%, 40%);">-     bts <= bsc_lchan [label="...for each SAPI, except link_id=0"];</span><br><span style="color: hsl(0, 100%, 40%);">-     ms <= bsc_lchan [label="RR Channel Release"];</span><br><span style="color: hsl(0, 100%, 40%);">-      bts <= bsc_lchan [label="RSL Deactivate SACCH",ID="if appropriate pchan"];</span><br><span style="color: hsl(0, 100%, 40%);">-       ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    bts => bsc_lchan [label="RSL Release ACKs"];</span><br><span style="color: hsl(0, 100%, 40%);">-       --- [label="END: SAPIs besides SAPI[0] are active"];</span><br><span style="color: hsl(0, 100%, 40%);">-  bsc_lchan abox bsc_lchan [label="LCHAN_ST_WAIT_\nBEFORE_RF_RELEASE\nT3111"];</span><br><span style="color: hsl(0, 100%, 40%);">-  bsc_lchan -> bsc_gscon [label="GSCON_EV_FORGET_LCHAN"];</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_gscon note bsc_gscon [label="has already forgotten the lchan above."];</span><br><span style="color: hsl(0, 100%, 40%);">-    ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_lchan abox bsc_lchan [label="LCHAN_ST_WAIT_\nRF_RELEASE_ACK\n4s"];</span><br><span style="color: hsl(0, 100%, 40%);">-        bts <= bsc_lchan [label="RSL RF Channel Release"];</span><br><span style="color: hsl(0, 100%, 40%);">- ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    bts => bsc_lchan [label="RSL RF Channel Release ACK"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_lchan abox bsc_lchan [label="LCHAN_ST_UNUSED"];</span><br><span style="color: hsl(0, 100%, 40%);">-   ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    ...;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    ms rbox msc_ [label="BSC releases, outside of conn FSM's flow"];</span><br><span style="color: hsl(0, 100%, 40%);">-  bsc -> bsc_lchan [label="LCHAN_EV_RELEASE"];</span><br><span style="color: hsl(0, 100%, 40%);">-       --- [label="IF SAPIs besides SAPI[0] are active"];</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_lchan abox bsc_lchan [label="LCHAN_ST_WAIT_\nSAPIS_RELEASED\nT3109"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bts <= bsc_lchan [label="RSL Release Request (Local End)..."];</span><br><span style="color: hsl(0, 100%, 40%);">-     bts <= bsc_lchan [label="...for each SAPI, except link_id=0"];</span><br><span style="color: hsl(0, 100%, 40%);">-     ms <= bsc_lchan [label="RR Channel Release",ID="if conn is present"];</span><br><span style="color: hsl(0, 100%, 40%);">-    bts <= bsc_lchan [label="RSL Deactivate SACCH",ID="if appropriate pchan"];</span><br><span style="color: hsl(0, 100%, 40%);">-       ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    bts => bsc_lchan [label="RSL Release ACKs"];</span><br><span style="color: hsl(0, 100%, 40%);">-       --- [label="END: SAPIs besides SAPI[0] are active"];</span><br><span style="color: hsl(0, 100%, 40%);">-  bsc_lchan abox bsc_lchan [label="LCHAN_ST_WAIT_\nBEFORE_RF_RELEASE\nT3111"];</span><br><span style="color: hsl(0, 100%, 40%);">-  bsc_lchan -> bsc_gscon [label="GSCON_EV_FORGET_LCHAN"];</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_gscon note bsc_gscon [label="conn FSM notices that its primary lchan is gone"];</span><br><span style="color: hsl(0, 100%, 40%);">-   bsc_gscon => msc_ [label="BSSMAP Clear Request"];</span><br><span style="color: hsl(0, 100%, 40%);">-  bsc_gscon abox bsc_gscon [label="ST_WAIT_CLEAR_CMD"];</span><br><span style="color: hsl(0, 100%, 40%);">- ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_lchan abox bsc_lchan [label="LCHAN_ST_WAIT_\nRF_RELEASE_ACK\n4s"];</span><br><span style="color: hsl(0, 100%, 40%);">-        bts <= bsc_lchan [label="RSL RF Channel Release"];</span><br><span style="color: hsl(0, 100%, 40%);">- ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    bts => bsc_lchan [label="RSL RF Channel Release ACK"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_lchan abox bsc_lchan [label="LCHAN_ST_UNUSED"];</span><br><span style="color: hsl(0, 100%, 40%);">-   ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_gscon <= msc_ [label="BSSMAP Clear Command"];</span><br><span style="color: hsl(0, 100%, 40%);">-  bsc_gscon abox bsc_gscon [label="ST_CLEARING"];</span><br><span style="color: hsl(0, 100%, 40%);">-       bsc_gscon => msc_ [label="BSSMAP Clear Complete"];</span><br><span style="color: hsl(0, 100%, 40%);">- ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    ...;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    ms rbox msc_ [label="MS releases"];</span><br><span style="color: hsl(0, 100%, 40%);">-   ms => bts [label="DISC"];</span><br><span style="color: hsl(0, 100%, 40%);">-  bts => bsc_lchan [label="RLL Release Ind..."];</span><br><span style="color: hsl(0, 100%, 40%);">-     bts => bsc_lchan [label="...for each SAPI"];</span><br><span style="color: hsl(0, 100%, 40%);">-       bsc_lchan note bsc_lchan [label="The lchan FSM notices when all SAPIs have been released"];</span><br><span style="color: hsl(0, 100%, 40%);">-   bsc_lchan abox bsc_lchan [label="LCHAN_ST_WAIT_\nBEFORE_RF_RELEASE\nT3111"];</span><br><span style="color: hsl(0, 100%, 40%);">-  ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_lchan abox bsc_lchan [label="LCHAN_ST_WAIT_\nRF_RELEASE_ACK\n4s"];</span><br><span style="color: hsl(0, 100%, 40%);">-        bts <= bsc_lchan [label="RSL RF Channel Release"];</span><br><span style="color: hsl(0, 100%, 40%);">- bsc_lchan -> bsc_gscon [label="GSCON_EV_FORGET_LCHAN"];</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_gscon note bsc_gscon [label="conn FSM notices that its primary lchan is gone"];</span><br><span style="color: hsl(0, 100%, 40%);">-   bsc_gscon => msc_ [label="BSSMAP Clear Request"];</span><br><span style="color: hsl(0, 100%, 40%);">-  bsc_gscon abox bsc_gscon [label="ST_WAIT_CLEAR_CMD"];</span><br><span style="color: hsl(0, 100%, 40%);">- ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    bts => bsc_lchan [label="RSL RF Channel Release ACK"];</span><br><span style="color: hsl(0, 100%, 40%);">-     ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_gscon <= msc_ [label="BSSMAP Clear Command"];</span><br><span style="color: hsl(0, 100%, 40%);">-  bsc_gscon => msc_ [label="BSSMAP Clear Complete"];</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span>diff --git a/doc/lchan-rtp-fsm.dot b/doc/lchan-rtp-fsm.dot</span><br><span>new file mode 100644</span><br><span>index 0000000..d5df643</span><br><span>--- /dev/null</span><br><span>+++ b/doc/lchan-rtp-fsm.dot</span><br><span>@@ -0,0 +1,44 @@</span><br><span style="color: hsl(120, 100%, 40%);">+digraph G {</span><br><span style="color: hsl(120, 100%, 40%);">+rankdir=TB</span><br><span style="color: hsl(120, 100%, 40%);">+labelloc=t; label="lchan RTP FSM"</span><br><span style="color: hsl(120, 100%, 40%);">+  </span><br><span style="color: hsl(120, 100%, 40%);">+      lchan [label="lchan\nFSM",shape=box3d]</span><br><span style="color: hsl(120, 100%, 40%);">+      lchan2 [label="lchan\nFSM",shape=box3d]</span><br><span style="color: hsl(120, 100%, 40%);">+     ho_as [label="Handover or Assignment FSM",shape=box3d]</span><br><span style="color: hsl(120, 100%, 40%);">+      invisible [style=invisible]</span><br><span style="color: hsl(120, 100%, 40%);">+   ho [label="Handover FSM",shape=box3d]</span><br><span style="color: hsl(120, 100%, 40%);">+       mgwep [label="mgw endpoint\nFSM",shape=box3d]</span><br><span style="color: hsl(120, 100%, 40%);">+       start [label="lchan_rtp_fsm_start()",shape=box]</span><br><span style="color: hsl(120, 100%, 40%);">+     WAIT_READY_TO_SWITCH_RTP [label="WAIT_READY_TO_SWITCH_RTP\nonly if wait_before_switching_rtp"]</span><br><span style="color: hsl(120, 100%, 40%);">+      terminate [shape=octagon]</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   lchan -> start [style=dashed]</span><br><span style="color: hsl(120, 100%, 40%);">+      start -> WAIT_MGW_ENDPOINT_AVAILABLE</span><br><span style="color: hsl(120, 100%, 40%);">+       start -> WAIT_LCHAN_READY [label="re-use existing\nendpoint CI"]</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       WAIT_MGW_ENDPOINT_AVAILABLE -> mgwep [label="gscon_ensure_mgw_endpoint()\nand CRCX to-BTS",style=dashed]</span><br><span style="color: hsl(120, 100%, 40%);">+ mgwep -> WAIT_MGW_ENDPOINT_AVAILABLE [label="LCHAN_RTP_EV_\nMGW_ENDPOINT_\n{AVAILABLE,ERROR}",style=dashed]</span><br><span style="color: hsl(120, 100%, 40%);">+      WAIT_MGW_ENDPOINT_AVAILABLE -> WAIT_LCHAN_READY</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  lchan -> WAIT_LCHAN_READY [label="LCHAN_RTP_EV_LCHAN_READY",style=dashed]</span><br><span style="color: hsl(120, 100%, 40%);">+        WAIT_LCHAN_READY -> WAIT_IPACC_CRCX_ACK [label="IPACC BTS"]</span><br><span style="color: hsl(120, 100%, 40%);">+      WAIT_LCHAN_READY -> WAIT_READY_TO_SWITCH_RTP</span><br><span style="color: hsl(120, 100%, 40%);">+       WAIT_IPACC_CRCX_ACK -> WAIT_IPACC_MDCX_ACK</span><br><span style="color: hsl(120, 100%, 40%);">+ WAIT_IPACC_MDCX_ACK -> WAIT_READY_TO_SWITCH_RTP</span><br><span style="color: hsl(120, 100%, 40%);">+    invisible -> ho [label="HO DETECT",style=dashed]</span><br><span style="color: hsl(120, 100%, 40%);">+ ho -> WAIT_READY_TO_SWITCH_RTP [label="LCHAN_RTP_EV_READY_TO_SWITCH",style=dashed]</span><br><span style="color: hsl(120, 100%, 40%);">+       WAIT_READY_TO_SWITCH_RTP -> WAIT_MGW_ENDPOINT_CONFIGURED</span><br><span style="color: hsl(120, 100%, 40%);">+   WAIT_MGW_ENDPOINT_CONFIGURED -> mgwep [label="MDCX",style=dashed]</span><br><span style="color: hsl(120, 100%, 40%);">+        mgwep -> WAIT_MGW_ENDPOINT_CONFIGURED [label="LCHAN_RTP_EV_\nMGW_ENDPOINT_\nCONFIGURED",style=dashed]</span><br><span style="color: hsl(120, 100%, 40%);">+    WAIT_MGW_ENDPOINT_CONFIGURED -> RTP_READY</span><br><span style="color: hsl(120, 100%, 40%);">+  RTP_READY -> lchan2 [label="LCHAN_EV_\nRTP_READY",style=dashed]</span><br><span style="color: hsl(120, 100%, 40%);">+  RTP_READY -> RTP_ESTABLISHED</span><br><span style="color: hsl(120, 100%, 40%);">+       lchan2 -> RTP_ESTABLISHED [label="LCHAN_RTP_EV_\nRELEASE",style=dashed]</span><br><span style="color: hsl(120, 100%, 40%);">+  RTP_ESTABLISHED -> terminate</span><br><span style="color: hsl(120, 100%, 40%);">+       RTP_READY -> RTP_ROLLBACK</span><br><span style="color: hsl(120, 100%, 40%);">+  RTP_ROLLBACK -> terminate</span><br><span style="color: hsl(120, 100%, 40%);">+  terminate -> lchan2 [label="LCHAN_EV_\nRTP_RELEASED",style=dashed]</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     lchan2 -> ho_as [label="XX_EV_LCHAN_\nESTABLISHED",style=dashed]</span><br><span style="color: hsl(120, 100%, 40%);">+ ho_as -> RTP_READY [label="LCHAN_RTP_EV_\n{ESTABLISHED,\nROLLBACK}",style=dashed]</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/doc/lchan.msc b/doc/lchan.msc</span><br><span>index 9b7d663..e2caa48 100644</span><br><span>--- a/doc/lchan.msc</span><br><span>+++ b/doc/lchan.msc</span><br><span>@@ -1,306 +1,216 @@</span><br><span> msc {</span><br><span>    hscale=2;</span><br><span style="color: hsl(0, 100%, 40%);">-       bts [label="MS/BTS"], bsc[label="BSC"], bsc_ts [label="BSC timeslot FSM"],</span><br><span style="color: hsl(0, 100%, 40%);">-        bsc_lchan[label="BSC lchan FSM"], bsc_gscon[label="BSC conn FSM"],</span><br><span style="color: hsl(0, 100%, 40%);">-  mgw_msc[label="MGW/MSC"];</span><br><span style="color: hsl(120, 100%, 40%);">+   ms [label="MS/BTS"], ts [label="BSC timeslot FSM"],</span><br><span style="color: hsl(120, 100%, 40%);">+       lchan[label="BSC lchan FSM"], rtp[label="BSC lchan RTP FSM"],mgwep[label="BSC MGW endpoint FSM"];</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     bts box mgw_msc [label="lchan allocation sequence"];</span><br><span style="color: hsl(0, 100%, 40%);">-  bsc_lchan abox bsc_lchan [label="LCHAN_ST_UNUSED"];</span><br><span style="color: hsl(120, 100%, 40%);">+ ms box mgwep [label="lchan allocation sequence"];</span><br><span style="color: hsl(120, 100%, 40%);">+   lchan abox lchan [label="LCHAN_ST_UNUSED"];</span><br><span style="color: hsl(120, 100%, 40%);">+ ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  lchan rbox lchan [label="lchan_activate(activate_info)"];</span><br><span style="color: hsl(120, 100%, 40%);">+   lchan note lchan [label="Dispatching event to make sure the lchan FSM permits activation."];</span><br><span style="color: hsl(120, 100%, 40%);">+        lchan -> lchan [label="LCHAN_EV_ACTIVATE\ndata = activate_info"];</span><br><span style="color: hsl(120, 100%, 40%);">+        lchan abox lchan [label="LCHAN_ST_\nWAIT_TS_READY"];</span><br><span style="color: hsl(120, 100%, 40%);">+        ts <- lchan [label="TS_EV_LCHAN_REQUESTED"];</span><br><span style="color: hsl(120, 100%, 40%);">+     ts rbox ts [label="Most details omitted. See timeslot FSM diagrams."];</span><br><span style="color: hsl(120, 100%, 40%);">+      ts note ts [label="A dyn TS may be in PDCH mode and will asynchronously switch off PDCH first. A</span><br><span style="color: hsl(120, 100%, 40%);">+         non-dynamic TS is ready immediately."];</span><br><span style="color: hsl(120, 100%, 40%);">+  |||;</span><br><span style="color: hsl(120, 100%, 40%);">+  --- [label="IF requires_voice_stream"];</span><br><span style="color: hsl(120, 100%, 40%);">+     lchan -> rtp [label="lchan_rtp_fsm_start()"];</span><br><span style="color: hsl(120, 100%, 40%);">+    rtp abox rtp [label="allocate\n LCHAN_RTP_ST_\nWAIT_MGW_ENDPOINT_\nAVAILABLE"];</span><br><span style="color: hsl(120, 100%, 40%);">+     --- [label="IF no endpoint-CI yet"];</span><br><span style="color: hsl(120, 100%, 40%);">+        rtp box rtp [label="gscon_ensure_mgw_endpoint()"];</span><br><span style="color: hsl(120, 100%, 40%);">+  rtp -> mgwep [label="mgw_endpoint_ci_add(to-BTS)"];</span><br><span style="color: hsl(120, 100%, 40%);">+      rtp -> mgwep [label="CRCX to-BTS"];</span><br><span style="color: hsl(120, 100%, 40%);">+      mgwep rbox mgwep [label="MGCP: CRCX"];</span><br><span style="color: hsl(120, 100%, 40%);">+      ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  mgwep rbox mgwep [label="MGCP: CRCX OK"];</span><br><span style="color: hsl(120, 100%, 40%);">+   rtp <- mgwep [label="LCHAN_RTP_EV_MGW_ENDPOINT_AVAILABLE"];</span><br><span style="color: hsl(120, 100%, 40%);">+      rtp note mgwep [label="The CRCX OK has assigned us a new endpoint CI number"];</span><br><span style="color: hsl(120, 100%, 40%);">+      rtp abox rtp [label="LCHAN_RTP_ST_WAIT_LCHAN_READY"];</span><br><span style="color: hsl(120, 100%, 40%);">+       --- [label="END: no endpoint-CI yet"];</span><br><span style="color: hsl(120, 100%, 40%);">+      --- [label="END: requires_voice_stream"];</span><br><span style="color: hsl(120, 100%, 40%);">+   |||;</span><br><span style="color: hsl(120, 100%, 40%);">+  ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  ts -> lchan [label="LCHAN_EV_TS_READY"];</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan abox lchan [label="LCHAN_ST_\nWAIT_ACTIV_ACK"];</span><br><span style="color: hsl(120, 100%, 40%);">+       --- [label="IF FOR_MS_CHANNEL_REQUEST"];</span><br><span style="color: hsl(120, 100%, 40%);">+    ms <= lchan [label="RSL Chan Activ (RSL_ACT_INTRA_IMM_ASS)"];</span><br><span style="color: hsl(120, 100%, 40%);">+    --- [label="ELSE: FOR_ASSIGNMENT"];</span><br><span style="color: hsl(120, 100%, 40%);">+ ms <= lchan [label="RSL Chan Activ (RSL_ACT_INTRA_NORM_ASS)"];</span><br><span style="color: hsl(120, 100%, 40%);">+   --- [label="ELSE: FOR_HANDOVER"];</span><br><span style="color: hsl(120, 100%, 40%);">+   ms <= lchan [label="RSL Chan Activ (RSL_ACT_INTER_ASYNC)"];</span><br><span style="color: hsl(120, 100%, 40%);">+      --- [label="END"];</span><br><span style="color: hsl(120, 100%, 40%);">+  ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  ms rbox lchan [label="On timeout or Chan Activ NACK, see: 'On any error', 'unrecoverable'"];</span><br><span style="color: hsl(120, 100%, 40%);">+        ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  ms => lchan [label="RSL Chan Activ ACK"];</span><br><span style="color: hsl(120, 100%, 40%);">+        lchan box lchan [label="lchan_fsm_post_activ_ack()"];</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     bts rbox mgw_msc [label="Channel Request from MS"];</span><br><span style="color: hsl(0, 100%, 40%);">-   bts => bsc [label="RSL Channel Request"];</span><br><span style="color: hsl(0, 100%, 40%);">-  bsc box bsc [label="lchan_select_by_type(chan_type)"];</span><br><span style="color: hsl(0, 100%, 40%);">-        bsc -> bsc_lchan [label="lchan_activate(lchan, FOR_MS_CHANNEL_REQUEST)"];</span><br><span style="color: hsl(0, 100%, 40%);">-  bsc_lchan rbox bsc_lchan [label="Continue at\nlchan_activate()\n"];</span><br><span style="color: hsl(120, 100%, 40%);">+ --- [label="IF FOR_MS_CHANNEL_REQUEST"];</span><br><span style="color: hsl(120, 100%, 40%);">+    ms <= lchan [label="RR Immediate Assignment"];</span><br><span style="color: hsl(120, 100%, 40%);">+   --- [label="ELSE: FOR_ASSIGNMENT"];</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan rbox lchan [label="dispatch\nASSIGNMENT_EV_\nLCHAN_ACTIVE\n(see Assignment FSM diagrams)"];</span><br><span style="color: hsl(120, 100%, 40%);">+   ms <= lchan [label="RR Assignment Command"];</span><br><span style="color: hsl(120, 100%, 40%);">+     --- [label="ELSE: FOR_HANDOVER"];</span><br><span style="color: hsl(120, 100%, 40%);">+   lchan rbox lchan [label="dispatch\nHO_EV_LCHAN_ACTIVE\n(see Handover FSM diagrams)"];</span><br><span style="color: hsl(120, 100%, 40%);">+       --- [label="END"];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      lchan abox lchan [label="LCHAN_ST_WAIT_\nRLL_RTP_ESTABLISH\nT3101"];</span><br><span style="color: hsl(120, 100%, 40%);">+        |||;</span><br><span style="color: hsl(120, 100%, 40%);">+  |||;</span><br><span style="color: hsl(120, 100%, 40%);">+  --- [label="IF requires_voice_stream"];</span><br><span style="color: hsl(120, 100%, 40%);">+     lchan -> rtp [label="LCHAN_RTP_EV_LCHAN_READY"];</span><br><span style="color: hsl(120, 100%, 40%);">+ |||;</span><br><span style="color: hsl(120, 100%, 40%);">+  --- [label="IF ip.access style BTS"];</span><br><span style="color: hsl(120, 100%, 40%);">+       rtp abox rtp [label="LCHAN_RTP_ST_WAIT_IPACC_CRCX_ACK"];</span><br><span style="color: hsl(120, 100%, 40%);">+    ms <= rtp [label="IPACC CRCX"];</span><br><span style="color: hsl(120, 100%, 40%);">+  ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  ms => rtp [label="IPACC CRCX ACK (BTS RTP port info)"];</span><br><span style="color: hsl(120, 100%, 40%);">+  rtp abox rtp [label="LCHAN_RTP_ST_WAIT_IPACC_MDCX_ACK"];</span><br><span style="color: hsl(120, 100%, 40%);">+    ms <= rtp [label="IPACC MDCX (MGW RTP port info)"];</span><br><span style="color: hsl(120, 100%, 40%);">+      ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  ms => rtp [label="IPACC MDCX ACK"];</span><br><span style="color: hsl(120, 100%, 40%);">+      --- [label="END ip.access style BTS"];</span><br><span style="color: hsl(120, 100%, 40%);">+      |||;</span><br><span style="color: hsl(120, 100%, 40%);">+  rtp box rtp [label="lchan_rtp_fsm_switch_rtp()"];</span><br><span style="color: hsl(120, 100%, 40%);">+   |||;</span><br><span style="color: hsl(120, 100%, 40%);">+  --- [label="IF wait_before_switching_rtp"];</span><br><span style="color: hsl(120, 100%, 40%);">+ rtp note rtp [label="During Handover, wait for HO DETECT before redirecting an existing endpoint</span><br><span style="color: hsl(120, 100%, 40%);">+         CI towards the new lchan."];</span><br><span style="color: hsl(120, 100%, 40%);">+     rtp abox rtp [label="LCHAN_RTP_ST_WAIT_READY_TO_SWITCH_RTP"];</span><br><span style="color: hsl(120, 100%, 40%);">+       ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  ms => rtp [label="HO DETECT (via Handover FSM)"];</span><br><span style="color: hsl(120, 100%, 40%);">+        --- [label="END: wait_before_switching_rtp"];</span><br><span style="color: hsl(120, 100%, 40%);">+       |||;</span><br><span style="color: hsl(120, 100%, 40%);">+  rtp abox rtp [label="LCHAN_RTP_ST_WAIT_MGW_ENDPOINT_CONFIGURED"];</span><br><span style="color: hsl(120, 100%, 40%);">+   rtp box rtp [label="connect_mgw_endpoint_to_lchan()"];</span><br><span style="color: hsl(120, 100%, 40%);">+      rtp -> mgwep [label="MDCX to-BTS"];</span><br><span style="color: hsl(120, 100%, 40%);">+      mgwep rbox mgwep [label="MGCP: MDCX"];</span><br><span style="color: hsl(120, 100%, 40%);">+      ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  mgwep rbox mgwep [label="MGCP: MDCX OK"];</span><br><span style="color: hsl(120, 100%, 40%);">+   rtp <- mgwep [label="LCHAN_RTP_EV_MGW_ENDPOINT_CONFIGURED"];</span><br><span style="color: hsl(120, 100%, 40%);">+     rtp abox rtp [label="LCHAN_RTP_ST_READY"];</span><br><span style="color: hsl(120, 100%, 40%);">+  lchan <- rtp [label="LCHAN_EV_RTP_READY"];</span><br><span style="color: hsl(120, 100%, 40%);">+       rtp note rtp [label="RTP FSM stays ready for Rollback until final establish event"];</span><br><span style="color: hsl(120, 100%, 40%);">+        ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  lchan -> rtp [label="LCHAN_RTP_EV_ESTABLISHED\nvia gscon_change_primary_lchan()"];</span><br><span style="color: hsl(120, 100%, 40%);">+       rtp abox rtp [label="LCHAN_RTP_ST_\nESTABLISHED"];</span><br><span style="color: hsl(120, 100%, 40%);">+  --- [label="END: requires_voice_stream"];</span><br><span>  |||;</span><br><span>         |||;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        bts rbox mgw_msc [label="Channel Request from BSSMAP Assignment"];</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_gscon <= mgw_msc [label="BSSMAP Assignment request"];</span><br><span style="color: hsl(0, 100%, 40%);">-  bsc_gscon box bsc_gscon [label="lchan_select_by_chan_mode(chan_mode)"];</span><br><span style="color: hsl(0, 100%, 40%);">-       bsc_lchan <- bsc_gscon [label="lchan_activate(lchan, FOR_ASSIGNMENT)"];</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_lchan rbox bsc_lchan [label="Continue at\nlchan_activate()\n"];</span><br><span style="color: hsl(0, 100%, 40%);">-   |||;</span><br><span style="color: hsl(0, 100%, 40%);">-    |||;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    bts rbox mgw_msc [label="Channel Request from Handover Decision"];</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc note bsc [label="target lchan typically already chosen by Handover Decision"];</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc -> bsc_gscon [label="GSCON_EV_HO_START (intra-BSC)"];</span><br><span style="color: hsl(0, 100%, 40%);">-  bsc_lchan <- bsc_gscon [label="lchan_activate(lchan, FOR_HANDOVER)"];</span><br><span style="color: hsl(0, 100%, 40%);">-      bsc_lchan rbox bsc_lchan [label="Continue at\nlchan_activate()\n"];</span><br><span style="color: hsl(0, 100%, 40%);">-   |||;</span><br><span style="color: hsl(0, 100%, 40%);">-    |||;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    bts rbox mgw_msc [label="Channel Request from intra-BSC-MT-Handover"];</span><br><span style="color: hsl(0, 100%, 40%);">-        bsc_gscon <- mgw_msc [label="BSSMAP Handover Request"];</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_gscon box bsc_gscon [label="lchan_select_by_chan_mode(chan_mode)"];</span><br><span style="color: hsl(0, 100%, 40%);">-       bsc box bsc [label="lchan_activate(lchan, FOR_HANDOVER)"];</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_lchan rbox bsc_lchan [label="Continue at\nlchan_activate()\n"];</span><br><span style="color: hsl(0, 100%, 40%);">-   |||;</span><br><span style="color: hsl(0, 100%, 40%);">-    |||;</span><br><span style="color: hsl(0, 100%, 40%);">-    bts rbox mgw_msc [label="lchan_activate()"];</span><br><span style="color: hsl(0, 100%, 40%);">-  bsc_lchan abox bsc_lchan [label="LCHAN_ST_\nWAIT_TS_READY\n(timeout: ? s, Tnnnn)"];</span><br><span style="color: hsl(0, 100%, 40%);">-   |||;</span><br><span style="color: hsl(0, 100%, 40%);">-    |||;</span><br><span style="color: hsl(0, 100%, 40%);">-    --- [label="TCH?"];</span><br><span style="color: hsl(0, 100%, 40%);">-   bsc_lchan note bsc_gscon [label="This is skipped when FOR_MS_CHANNEL_REQUEST. If the MS requests</span><br><span style="color: hsl(0, 100%, 40%);">-           a TCH lchan, and we end up actually giving it a TCH because no SDCCH are available, we</span><br><span style="color: hsl(0, 100%, 40%);">-          can not set up an RTP stream because there is not even an L3 conn yet."];</span><br><span style="color: hsl(0, 100%, 40%);">-  bsc_lchan note bsc_gscon [label="The lchan FSM asks the conn FSM to have an MGW endpoint ready as</span><br><span style="color: hsl(0, 100%, 40%);">-          early as possible. Either the conn already has such MGW endpoint from a previous lchan,</span><br><span style="color: hsl(0, 100%, 40%);">-         in which case it immediately replies, or it requests one from the MGW, in which case we</span><br><span style="color: hsl(0, 100%, 40%);">-         wait for a response in 'TCH? (2)' below."];</span><br><span style="color: hsl(0, 100%, 40%);">-        bsc_lchan -> bsc_gscon [label="GSCON_EV_ENSURE_MGW_ENDPOINT"];</span><br><span style="color: hsl(0, 100%, 40%);">-     --- [label="IF conn has user_plane.fi_bts in state ST_READY"];</span><br><span style="color: hsl(0, 100%, 40%);">-        bsc_lchan <- bsc_gscon [label="LCHAN_EV_MGW_ENDPOINT_AVAILABLE"];</span><br><span style="color: hsl(0, 100%, 40%);">-  bsc_lchan box bsc_lchan [label="mgw_endpoint_available = true"];</span><br><span style="color: hsl(0, 100%, 40%);">-      bsc_lchan note bsc_lchan [label="lchan_activate() continues"];</span><br><span style="color: hsl(0, 100%, 40%);">-        --- [label="ELSE (no MGW endpoint available yet)"];</span><br><span style="color: hsl(0, 100%, 40%);">-   bsc_gscon => mgw_msc [label="CRCX (for BTS) via mgcp_conn_create()"];</span><br><span style="color: hsl(0, 100%, 40%);">-      bsc_gscon abox bsc_gscon [label="ST_WAIT_CRCX_BTS\n(timeout: ? s, Tnnnn)"];</span><br><span style="color: hsl(0, 100%, 40%);">-   bsc_lchan <- bsc_gscon [label="(event dispatch returns)"];</span><br><span style="color: hsl(0, 100%, 40%);">- bsc_lchan note bsc_lchan [label="lchan_activate() continues"];</span><br><span>     ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_gscon note bsc_gscon [label="async:"];</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_gscon <= mgw_msc [label="CRCX OK (for BTS)"];</span><br><span style="color: hsl(0, 100%, 40%);">-  bsc_lchan <- bsc_gscon [label="LCHAN_EV_MGW_ENDPOINT_AVAILABLE"];</span><br><span style="color: hsl(0, 100%, 40%);">-  bsc_lchan box bsc_lchan [label="mgw_endpoint_available = true"];</span><br><span style="color: hsl(0, 100%, 40%);">-      bsc_lchan note bsc_lchan [label="As soon as we reach LCHAN_ST_WAIT_MGW_ENDPOINT_AVAILABLE, this triggers</span><br><span style="color: hsl(0, 100%, 40%);">-           immedate action (s.b.), but until then, only the flag gets set to true."];</span><br><span style="color: hsl(120, 100%, 40%);">+       ms => lchan [label="RLL Establish Ind"];</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan abox lchan [label="LCHAN_ST_\nESTABLISHED"];</span><br><span style="color: hsl(120, 100%, 40%);">+  lchan box lchan [label="lchan_on_fully_established()"];</span><br><span style="color: hsl(120, 100%, 40%);">+     --- [label="IF FOR_MS_CHANNEL_REQUEST"];</span><br><span style="color: hsl(120, 100%, 40%);">+    ms note lchan [label="No action required. The MS will have sent an L3 message in the RLL</span><br><span style="color: hsl(120, 100%, 40%);">+         Establish Ind and is then free to dispatch DTAP."];</span><br><span style="color: hsl(120, 100%, 40%);">+      --- [label="ELSE: FOR_ASSIGNMENT"];</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan rbox lchan [label="dispatch\nASSIGNMENT_EV_\nLCHAN_ESTABLISHED\n(see Assignment FSM diagrams)"];</span><br><span style="color: hsl(120, 100%, 40%);">+      --- [label="ELSE: FOR_HANDOVER"];</span><br><span style="color: hsl(120, 100%, 40%);">+   lchan rbox lchan [label="dispatch\nHO_EV_LCHAN_ESTABLISHED\n(see Handover FSM diagrams)"];</span><br><span style="color: hsl(120, 100%, 40%);">+  --- [label="END"];</span><br><span>         ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    --- [label="CRCX timeout"];</span><br><span style="color: hsl(0, 100%, 40%);">-   bsc_gscon note bsc_gscon [label="conn FSM should fire on CRCX timeout"];</span><br><span style="color: hsl(0, 100%, 40%);">-      bsc_lchan <- bsc_gscon [label="LCHAN_EV_MGW_ENDPOINT_ERROR"];</span><br><span style="color: hsl(0, 100%, 40%);">-      bsc_gscon note bsc_gscon [label="conn FSM should not assume anything and wait for</span><br><span style="color: hsl(0, 100%, 40%);">-          GSCON_EV_LCHAN_ALLOC_ERROR"];</span><br><span style="color: hsl(0, 100%, 40%);">-      bsc_lchan rbox bsc_lchan [label="Do 'On any error'"];</span><br><span style="color: hsl(0, 100%, 40%);">- bsc_lchan abox bsc_lchan [label="LCHAN_ST_UNUSED"];</span><br><span style="color: hsl(0, 100%, 40%);">-   bsc_ts <- bsc_lchan [label="TS_EV_LCHAN_UNUSED"];</span><br><span style="color: hsl(0, 100%, 40%);">-  --- [label="END: 'TCH?'"];</span><br><span style="color: hsl(0, 100%, 40%);">-    |||;</span><br><span style="color: hsl(0, 100%, 40%);">-    |||;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_lchan box bsc_lchan [label="lchan_activate() exits"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_lchan note bsc_lchan [label="still in\nlchan_request()\nLCHAN_ST_WAIT_\nTS_READY"];</span><br><span style="color: hsl(0, 100%, 40%);">-       bsc_ts <- bsc_lchan [label="TS_EV_LCHAN_REQUESTED"];</span><br><span style="color: hsl(120, 100%, 40%);">+     --- [label="IF requires_voice_stream"];</span><br><span style="color: hsl(120, 100%, 40%);">+     lchan rbox lchan [label="Assignment or Handover FSM:"];</span><br><span style="color: hsl(120, 100%, 40%);">+     lchan -> mgwep [label="CRCX/MDCX to-MSC"];</span><br><span>      ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    --- [label="on error from TS or timeout:"];</span><br><span style="color: hsl(0, 100%, 40%);">-   bsc_ts -> bsc_lchan [label="LCHAN_EV_TS_ERROR"];</span><br><span style="color: hsl(0, 100%, 40%);">-   bsc_lchan rbox bsc_lchan [label="Do 'On any error'"];</span><br><span style="color: hsl(0, 100%, 40%);">- bsc_lchan abox bsc_lchan [label="LCHAN_ST_UNUSED"];</span><br><span style="color: hsl(0, 100%, 40%);">-   bsc_ts <- bsc_lchan [label="TS_EV_LCHAN_UNUSED"];</span><br><span style="color: hsl(0, 100%, 40%);">-  ---;</span><br><span style="color: hsl(0, 100%, 40%);">-    ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_ts abox bsc_ts [label="TS_ST_IN_USE"];</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_ts -> bsc_lchan [label="LCHAN_EV_TS_READY"];</span><br><span style="color: hsl(0, 100%, 40%);">-   bsc_lchan box bsc_lchan [label="lchan_fsm_\npre_lchan_activ()"];</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      |||;</span><br><span style="color: hsl(0, 100%, 40%);">-    |||;</span><br><span style="color: hsl(0, 100%, 40%);">-    bts rbox mgw_msc [label="mode FOR_MS_CHANNEL_REQUEST"];</span><br><span style="color: hsl(0, 100%, 40%);">-       bts note bsc_lchan [label="This is the simple case where the MS requested a channel, and there is no</span><br><span style="color: hsl(0, 100%, 40%);">-               L3 conn to the MSC; no matter if this is SDDCH or a TCH channel type, we will not prepare</span><br><span style="color: hsl(0, 100%, 40%);">-               an RTP stream."];</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  bsc_lchan note bsc_lchan [label="still in lchan_fsm_\npre_lchan_activ()"];</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_lchan abox bsc_lchan [label="LCHAN_ST_WAIT_\nACTIV_ACK\n(timeout: ? s, Tnnnn)"];</span><br><span style="color: hsl(0, 100%, 40%);">-  bts <= bsc_lchan [label="RSL Chan Activ (RSL_ACT_INTRA_IMM_ASS)"];</span><br><span style="color: hsl(0, 100%, 40%);">- bts note bsc_lchan [label="If any errors occur from now on, we don't want to send an RR Immediate</span><br><span style="color: hsl(0, 100%, 40%);">-              Assignment Reject anymore."];</span><br><span style="color: hsl(0, 100%, 40%);">-      bsc_lchan box bsc_lchan [label="sent_chan_activ = true"];</span><br><span style="color: hsl(0, 100%, 40%);">-     ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    --- [label="on timeout"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_lchan rbox bsc_lchan [label="Continue at: 'On any error', 'unrecoverable'"];</span><br><span style="color: hsl(0, 100%, 40%);">-      ---;</span><br><span style="color: hsl(0, 100%, 40%);">-    ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    bts => bsc_lchan [label="RSL Chan Activ ACK"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_lchan abox bsc_lchan [label="LCHAN_ST_WAIT_\nRLL_ESTABLISH\nT3101"];</span><br><span style="color: hsl(0, 100%, 40%);">-      bsc_lchan note bsc_lchan [label="Now the lchan is assigned, but has no L3 conn yet. On errors,</span><br><span style="color: hsl(0, 100%, 40%);">-             this will either go into graceful release or into broken state, but will not trigger any</span><br><span style="color: hsl(0, 100%, 40%);">-                events to a (non-existing) conn."];</span><br><span style="color: hsl(0, 100%, 40%);">-        ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    --- [label="on timeout"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bts <= bsc_lchan [label="RSL RF Channel Release"];</span><br><span style="color: hsl(0, 100%, 40%);">- bsc_lchan abox bsc_lchan [label="LCHAN_ST_WAIT_RF_RELEASE_ACK\n(T?, 4s)"];</span><br><span style="color: hsl(0, 100%, 40%);">-    ---;</span><br><span style="color: hsl(0, 100%, 40%);">-    ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    bts => bsc_lchan [label="RLL Establish Ind"];</span><br><span style="color: hsl(0, 100%, 40%);">-      bsc_lchan abox bsc_lchan [label="LCHAN_ST_ACTIVE"];</span><br><span style="color: hsl(0, 100%, 40%);">-   |||;</span><br><span style="color: hsl(0, 100%, 40%);">-    |||;</span><br><span style="color: hsl(0, 100%, 40%);">-    bts rbox mgw_msc [label="modes FOR_ASSIGNMENT and FOR_HANDOVER"];</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_lchan note bsc_lchan [label="still in lchan_fsm_\npre_lchan_activ()"];</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_lchan abox bsc_lchan [label="LCHAN_ST_WAIT_\nACTIV_ACK\n(timeout: ? s, Tnnnn)"];</span><br><span style="color: hsl(0, 100%, 40%);">-  bts <= bsc_lchan [label="RSL Chan Activ (RSL_ACT_INTRA_NORM_ASS)",ID=FOR_ASSIGNMENT];</span><br><span style="color: hsl(0, 100%, 40%);">-      bts <= bsc_lchan [label="RSL Chan Activ (RSL_ACT_INTER_ASYNC)",ID=FOR_HANDOVER];</span><br><span style="color: hsl(0, 100%, 40%);">-   ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    --- [label="on timeout"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_lchan rbox bsc_lchan [label="Continue at: 'On any error', 'unrecoverable'"];</span><br><span style="color: hsl(0, 100%, 40%);">-      ---;</span><br><span style="color: hsl(0, 100%, 40%);">-    bts => bsc_lchan [label="RSL Chan Activ ACK"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_lchan abox bsc_lchan [label="LCHAN_ST_WAIT_\nRLL_ESTABLISH\nT3101"];</span><br><span style="color: hsl(0, 100%, 40%);">-      ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    --- [label="on timeout"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_lchan -> bsc_gscon [label="GSCON_EV_LCHAN_ALLOC_ERROR"];</span><br><span style="color: hsl(0, 100%, 40%);">-       bsc_lchan -> bsc_lchan [label="lchan_fsm_pre_rf_release()"];</span><br><span style="color: hsl(0, 100%, 40%);">-       ---;</span><br><span style="color: hsl(0, 100%, 40%);">-    ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    bts => bsc_lchan [label="RLL Establish Indication"];</span><br><span style="color: hsl(0, 100%, 40%);">-       |||;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    --- [label="TCH? (2)"];</span><br><span style="color: hsl(0, 100%, 40%);">-       --- [label="mgw_endpoint_available == false?"];</span><br><span style="color: hsl(0, 100%, 40%);">-       bsc_lchan abox bsc_lchan [label="LCHAN_ST_WAIT_\nMGW_ENDPOINT_\nAVAILABLE"];</span><br><span style="color: hsl(0, 100%, 40%);">-  bsc_lchan note bsc_lchan [label="rely on conn FSM timeout; apply only a long sanity timeout."];</span><br><span style="color: hsl(0, 100%, 40%);">-       ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_gscon <= mgw_msc [label="CRCX OK (for BTS)"];</span><br><span style="color: hsl(0, 100%, 40%);">-  bsc_lchan <- bsc_gscon [label="LCHAN_EV_MGW_ENDPOINT_AVAILABLE"];</span><br><span style="color: hsl(0, 100%, 40%);">-  bsc_lchan box bsc_lchan [label="mgw_endpoint_available = true"];</span><br><span style="color: hsl(0, 100%, 40%);">-      bsc_lchan <- bsc_lchan [label="re-invoke lchan_fsm_pre_lchan_activ()"];</span><br><span style="color: hsl(0, 100%, 40%);">-    --- [label="END: 'TCH? (2)'"];</span><br><span style="color: hsl(0, 100%, 40%);">-        |||;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    --- [label="is BTS using IPA Abis? (osmo-bts, ip.access)"];</span><br><span style="color: hsl(0, 100%, 40%);">-   bsc_lchan abox bsc_lchan [label="LCHAN_ST_WAIT_\nIPACC_CRCX_ACK\n(timeout: ? s, Tnnnn)"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bts <= bsc_lchan [label="IPACC CRCX"];</span><br><span style="color: hsl(0, 100%, 40%);">-     ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    --- [label="on timeout"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_lchan -> bsc_gscon [label="GSCON_EV_LCHAN_ALLOC_ERROR"];</span><br><span style="color: hsl(0, 100%, 40%);">-       bsc_lchan -> bsc_lchan [label="lchan_graceful_release()"];</span><br><span style="color: hsl(0, 100%, 40%);">- ---;</span><br><span style="color: hsl(0, 100%, 40%);">-    ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    bts => bsc_lchan [label="IPACC CRCX ACK"];</span><br><span style="color: hsl(0, 100%, 40%);">- bts note bsc_lchan [label="The IPACC CRCX ACK tells us what port the IPA Abis based BTS has</span><br><span style="color: hsl(0, 100%, 40%);">-                assigned to this lchan. AoIP: we need to forward this to the MGW (BTS side) with an MDCX;</span><br><span style="color: hsl(0, 100%, 40%);">-               SCCPlite: we forward this to the MSC during BSSMAP Assignment Complete (TODO: is this</span><br><span style="color: hsl(0, 100%, 40%);">-           correct??)"];</span><br><span style="color: hsl(0, 100%, 40%);">-      bsc_lchan abox bsc_lchan [label="LCHAN_ST_WAIT_\nIPACC_MDCX_ACK\n(timeout: ? s, Tnnnn)"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bts <= bsc_lchan [label="IPACC MDCX"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bts note bsc_lchan [label="The IPACC MDCX tells IPA Abis based BTSes the IP address and RTP port</span><br><span style="color: hsl(0, 100%, 40%);">-           assigned by the BTS side of the MGW. AoIP: the MGW CRCX (BTS) must thus happen before</span><br><span style="color: hsl(0, 100%, 40%);">-           this; SCCPlite: the RTP port is already known from the timeslot+multiplex information."];</span><br><span style="color: hsl(0, 100%, 40%);">-  ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    --- [label="on timeout"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_lchan -> bsc_gscon [label="GSCON_EV_LCHAN_ALLOC_ERROR"];</span><br><span style="color: hsl(0, 100%, 40%);">-       bsc_lchan -> bsc_lchan [label="lchan_graceful_release()"];</span><br><span style="color: hsl(0, 100%, 40%);">- ---;</span><br><span style="color: hsl(0, 100%, 40%);">-    ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    bts => bsc_lchan [label="IPACC MDCX ACK"];</span><br><span style="color: hsl(0, 100%, 40%);">- --- [label="END: is BTS using IPA Abis? (osmo-bts, ip.access)"];</span><br><span style="color: hsl(0, 100%, 40%);">-      |||;</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_lchan abox bsc_lchan [label="LCHAN_ST_ACTIVE"];</span><br><span style="color: hsl(0, 100%, 40%);">-   bsc_lchan box bsc_lchan [label="lchan_fsm_post_lchan_activ()"];</span><br><span style="color: hsl(0, 100%, 40%);">-       bsc_lchan -> bsc_gscon [label="GSCON_EV_LCHAN_ACTIVE"];</span><br><span style="color: hsl(0, 100%, 40%);">-    bts <= bsc_gscon [label="RR Assignment",ID="BSSMAP Assignment Request"];</span><br><span style="color: hsl(0, 100%, 40%);">- bts <= bsc_gscon [label="RR Handover Command",ID="intra-BSC HO"];</span><br><span style="color: hsl(0, 100%, 40%);">-        bsc_gscon => mgw_msc [label="BSSMAP Handover\nRequest Acknowledge",ID="inter-BSC-MT HO"];</span><br><span style="color: hsl(0, 100%, 40%);">-        ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    ---[label="On error"];</span><br><span style="color: hsl(0, 100%, 40%);">-        bsc_lchan rbox bsc_lchan [label="Continue at 'When the lchan is no longer used'"];</span><br><span style="color: hsl(0, 100%, 40%);">-    ---;</span><br><span style="color: hsl(0, 100%, 40%);">-    ...;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    bts => bsc_gscon [label="RR Assignment Complete",ID="BSSMAP Assignment Request"];</span><br><span style="color: hsl(0, 100%, 40%);">-        bts => bsc_gscon [label="RR Handover Detect",ID="intra-BSC HO"];</span><br><span style="color: hsl(0, 100%, 40%);">- bts => bsc_gscon [label="RR Handover Accept",ID="inter-BSC-MT HO"];</span><br><span style="color: hsl(0, 100%, 40%);">-      bsc_gscon note bsc_gscon [label="conn FSM takes care of MGW endpoints for BTS side (possibly</span><br><span style="color: hsl(0, 100%, 40%);">-               redirect) and MSC side (possibly create). More information in e.g. assignment.msc and</span><br><span style="color: hsl(0, 100%, 40%);">-           handover.msc"];</span><br><span style="color: hsl(120, 100%, 40%);">+  lchan <- mgwep [label="OK"];</span><br><span style="color: hsl(120, 100%, 40%);">+     lchan box lchan [label="gscon_change_primary_lchan()"];</span><br><span style="color: hsl(120, 100%, 40%);">+     lchan -> rtp [label="LCHAN_RTP_EV_ESTABLISHED"];</span><br><span style="color: hsl(120, 100%, 40%);">+ rtp abox rtp [label="LCHAN_RTP_ST_\nESTABLISHED"];</span><br><span style="color: hsl(120, 100%, 40%);">+  rtp box rtp [label="Forget any Rollback info"];</span><br><span style="color: hsl(120, 100%, 40%);">+     --- [label="END: requires_voice_stream"];</span><br><span> </span><br><span>      ...;</span><br><span>         ...;</span><br><span>         ...;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        bts rbox mgw_msc [label="When the lchan is no longer used"];</span><br><span style="color: hsl(0, 100%, 40%);">-  --- [label="IF the MS or BTS release the lchan"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bts -> bsc_lchan [label="RLL Release Ind for SAPI=0"];</span><br><span style="color: hsl(0, 100%, 40%);">-     --- [label="IF the BSC other than the conn FSM decides to release"];</span><br><span style="color: hsl(0, 100%, 40%);">-  bsc -> bsc_lchan [label="LCHAN_EV_RELEASE"];</span><br><span style="color: hsl(0, 100%, 40%);">-       --- [label="IF the MSC or conn FSM release the lchan"];</span><br><span style="color: hsl(0, 100%, 40%);">-       bsc_lchan <- bsc_gscon [label="LCHAN_EV_RELEASE"];</span><br><span style="color: hsl(0, 100%, 40%);">- ---;</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc note bsc_gscon [label="The LCHAN_EV_RELEASE's data pointer possibly indicates an error</span><br><span style="color: hsl(0, 100%, 40%);">-             cause"];</span><br><span style="color: hsl(0, 100%, 40%);">-   bsc_lchan note bsc_gscon [label="If the conn FSM requested a release, it probably has already</span><br><span style="color: hsl(0, 100%, 40%);">-      forgotten about this lchan. However, if the MS/BTS initiated the release, make sure the conn FSM</span><br><span style="color: hsl(0, 100%, 40%);">-        is informed:"];</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_lchan box bsc_lchan [label="lchan_graceful_release()"];</span><br><span style="color: hsl(0, 100%, 40%);">-   bsc_lchan abox bsc_lchan [label="LCHAN_ST_WAIT_\nSAPIS_RELEASED\nT3109"];</span><br><span style="color: hsl(0, 100%, 40%);">-     --- [label="TCH and got as far as Chan Activ Ack?"];</span><br><span style="color: hsl(0, 100%, 40%);">-  bts <= bsc_lchan [label="RSL Deactivate SACCH"];</span><br><span style="color: hsl(0, 100%, 40%);">-   ---;</span><br><span style="color: hsl(0, 100%, 40%);">-    bts <= bsc_lchan [label="RLL Release Request (Local End)..."];</span><br><span style="color: hsl(0, 100%, 40%);">-     bts <= bsc_lchan [label="...for all SAPIs except [0]"];</span><br><span style="color: hsl(0, 100%, 40%);">-    |||;</span><br><span style="color: hsl(0, 100%, 40%);">-    --- [label="SAPI[0] in use?"];</span><br><span style="color: hsl(0, 100%, 40%);">-        bsc_lchan note bsc_lchan [label="for bts->nokia.no_loc_rel_cnf we do not expect Release Confirm</span><br><span style="color: hsl(0, 100%, 40%);">-         messages and this state immediately advances to lchan_fsm_pre_rf_release()"];</span><br><span style="color: hsl(120, 100%, 40%);">+    ms rbox mgwep [label="When the MS or BTS release the lchan"];</span><br><span style="color: hsl(120, 100%, 40%);">+       lchan abox lchan [label="LCHAN_ST_\nESTABLISHED"];</span><br><span style="color: hsl(120, 100%, 40%);">+  ms -> lchan [label="RLL Release Ind for SAPI=0"];</span><br><span style="color: hsl(120, 100%, 40%);">+        lchan abox lchan [label="LCHAN_ST_WAIT_RLL_RTP_RELEASED"];</span><br><span style="color: hsl(120, 100%, 40%);">+  lchan rbox lchan [label="Continue at 'common release' below"];</span><br><span>     ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    --- [label="on timeout"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_lchan box bsc_lchan [label="Anyway try RF Channel Release, continue</span><br><span style="color: hsl(0, 100%, 40%);">-            with lchan_fsm_wait_before_rf_release()"];</span><br><span style="color: hsl(0, 100%, 40%);">- ---;</span><br><span>         ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    bts => bsc_lchan [label="RLL Release Confirm..."];</span><br><span style="color: hsl(0, 100%, 40%);">- bts => bsc_lchan [label="...for each SAPI except [0]"];</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_lchan box bsc_lchan [label="Stay in\nLCHAN_ST_WAIT_\nSAPIS_RELEASED\nuntil only SAPI[0] remains active"];</span><br><span style="color: hsl(0, 100%, 40%);">- --- [label="END: 'SAPI[0] in use?'"];</span><br><span style="color: hsl(0, 100%, 40%);">- |||;</span><br><span style="color: hsl(120, 100%, 40%);">+  ms rbox mgwep [label="When the BSC decides to release the lchan"];</span><br><span style="color: hsl(120, 100%, 40%);">+  lchan box lchan [label="lchan_release()"];</span><br><span style="color: hsl(120, 100%, 40%);">+  lchan abox lchan [label="LCHAN_ST_WAIT_RLL_RTP_RELEASED"];</span><br><span style="color: hsl(120, 100%, 40%);">+  ms <= lchan [label="RR Release"];</span><br><span style="color: hsl(120, 100%, 40%);">+        lchan rbox lchan [label="common release"];</span><br><span style="color: hsl(120, 100%, 40%);">+  --- [label="IF RTP FSM present"];</span><br><span style="color: hsl(120, 100%, 40%);">+   lchan -> rtp [label="LCHAN_RTP_EV_RELEASE"];</span><br><span style="color: hsl(120, 100%, 40%);">+     --- [label="END: RTP FSM present"];</span><br><span style="color: hsl(120, 100%, 40%);">+ ms <= lchan [label="RSL Deactivate SACCH"];</span><br><span style="color: hsl(120, 100%, 40%);">+      ms <= lchan [label="RSL Release Request (Local End)",ID="for each SAPI except [0]"];</span><br><span style="color: hsl(120, 100%, 40%);">+   lchan note lchan [label="for ms->nokia.no_loc_rel_cnf we do not expect Release Confirm</span><br><span style="color: hsl(120, 100%, 40%);">+                messages and immediately mark all SAPIs as released"];</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- bsc_lchan box bsc_lchan [label="lchan_fsm_wait_before_rf_release()"];</span><br><span style="color: hsl(0, 100%, 40%);">- bsc_lchan abox bsc_lchan [label="LCHAN_ST_WAIT_\nBEFORE_RF_RELEASE\nT3111"];</span><br><span style="color: hsl(0, 100%, 40%);">-  bsc_lchan -> bsc_gscon [label="GSCON_EV_FORGET_LCHAN (data=lchan)"];</span><br><span style="color: hsl(0, 100%, 40%);">-       bsc_gscon note bsc_gscon [label="conn FSM immediately forgets about the lchan"];</span><br><span style="color: hsl(0, 100%, 40%);">-      bsc_gscon => mgw_msc [label="BSSMAP Clear Request?"];</span><br><span>   ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_lchan box bsc_lchan [label="T3111 expires"];</span><br><span style="color: hsl(0, 100%, 40%);">-      bsc_lchan box bsc_lchan [label="lchan_fsm_pre_rf_release()"];</span><br><span style="color: hsl(0, 100%, 40%);">- bsc_lchan abox bsc_lchan [label="LCHAN_ST_WAIT_\nRF_RELEASE_ACK\nT3111"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_lchan box bsc_lchan [label="for each bsc_rll_req matching this lchan: disable timer, call</span><br><span style="color: hsl(0, 100%, 40%);">-              cb(BSC_RLLR_IND_REL_IND)"];</span><br><span style="color: hsl(0, 100%, 40%);">-        bts <= bsc_lchan [label="RSL RF Channel Release"];</span><br><span style="color: hsl(120, 100%, 40%);">+       lchan <- rtp [label="LCHAN_EV_RTP_RELEASED"];</span><br><span>   ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    --- [label="on timeout"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_lchan rbox bsc_lchan [label="Continue at: 'On any error', 'unrecoverable'"];</span><br><span style="color: hsl(0, 100%, 40%);">-      ---;</span><br><span style="color: hsl(120, 100%, 40%);">+  ms => lchan [label="RLL Release Confirm",ID="for each SAPI except [0]"];</span><br><span>      ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    bts => bsc_lchan [label="RSL RF Channel Release Ack"];</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_lchan box bsc_lchan [label="lchan_fsm_post_rf_release()"];</span><br><span style="color: hsl(120, 100%, 40%);">+      lchan box lchan [label="Stay in\nLCHAN_ST_WAIT_\nRLL_RTP_RELEASED\nuntil only SAPI[0] remains active"];</span><br><span style="color: hsl(120, 100%, 40%);">+     lchan abox lchan [label="LCHAN_ST_WAIT_\nBEFORE_RF_RELEASE\nT3111"];</span><br><span style="color: hsl(120, 100%, 40%);">+        ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  lchan box lchan [label="T3111 expires"];</span><br><span style="color: hsl(120, 100%, 40%);">+    lchan box lchan [label="lchan_fsm_pre_rf_release()"];</span><br><span style="color: hsl(120, 100%, 40%);">+       lchan abox lchan [label="LCHAN_ST_WAIT_\nRF_RELEASE_ACK\nT3111"];</span><br><span style="color: hsl(120, 100%, 40%);">+   ms <= lchan [label="RSL RF Channel Release"];</span><br><span style="color: hsl(120, 100%, 40%);">+    ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  lchan rbox lchan [label="On timeout, continue at: 'On any error', 'unrecoverable'"];</span><br><span style="color: hsl(120, 100%, 40%);">+        ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  ms => lchan [label="RSL RF Channel Release Ack"];</span><br><span>       |||;</span><br><span style="color: hsl(0, 100%, 40%);">-    --- [label="IF an error cause was indicated on LCHAN_EV_RELEASE"];</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_lchan abox bsc_lchan [label="LCHAN_ST_WAIT_\nAFTER_ERROR\n(timeout: T3111+2 s, T?)"];</span><br><span style="color: hsl(120, 100%, 40%);">+   --- [label="IF release_in_error"];</span><br><span style="color: hsl(120, 100%, 40%);">+  lchan abox lchan [label="LCHAN_ST_WAIT_\nAFTER_ERROR\n(timeout: T3111+2 s, T993111)"];</span><br><span>     ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_lchan box bsc_lchan [label="timer expires"];</span><br><span style="color: hsl(0, 100%, 40%);">-      --- [label="END: 'an error cause was indicated on LCHAN_EV_RELEASE'"];</span><br><span style="color: hsl(120, 100%, 40%);">+      lchan box lchan [label="timer expires"];</span><br><span style="color: hsl(120, 100%, 40%);">+    --- [label="END: release_in_error"];</span><br><span>       |||;</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_lchan box bsc_lchan [label="lchan_fsm_release_complete()"];</span><br><span style="color: hsl(0, 100%, 40%);">-       bsc_lchan abox bsc_lchan [label="LCHAN_ST_UNUSED"];</span><br><span style="color: hsl(0, 100%, 40%);">-   bsc_ts <- bsc_lchan [label="TS_EV_LCHAN_UNUSED"];</span><br><span style="color: hsl(0, 100%, 40%);">-  bsc_ts abox bsc_ts [label="TS_ST_UNUSED"];</span><br><span style="color: hsl(120, 100%, 40%);">+  lchan abox lchan [label="LCHAN_ST_UNUSED"];</span><br><span style="color: hsl(120, 100%, 40%);">+ ts <- lchan [label="TS_EV_LCHAN_UNUSED"];</span><br><span style="color: hsl(120, 100%, 40%);">+        |||;</span><br><span>         |||;</span><br><span>         |||;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        bts rbox mgw_msc [label="On any error"];</span><br><span style="color: hsl(120, 100%, 40%);">+    ms rbox mgwep [label="On any error"];</span><br><span>      |||;</span><br><span style="color: hsl(0, 100%, 40%);">-    --- [label="IF FOR_MS_CHANNEL_REQUEST && !sent_chan_activ"];</span><br><span style="color: hsl(0, 100%, 40%);">-  bts <= bsc_lchan [label="RR Immediate Assign Reject"];</span><br><span style="color: hsl(120, 100%, 40%);">+   --- [label="IF FOR_MS_CHANNEL_REQUEST"];</span><br><span style="color: hsl(120, 100%, 40%);">+    ms <= lchan [label="RR Immediate Assign Reject"];</span><br><span style="color: hsl(120, 100%, 40%);">+        --- [label="ELSE: FOR_ASSIGNMENT"];</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan rbox lchan [label="dispatch\nASSIGNMENT_EV_\nLCHAN_ERROR\n(see Assignment FSM diagrams)"];</span><br><span style="color: hsl(120, 100%, 40%);">+    --- [label="ELSE: FOR_HANDOVER"];</span><br><span style="color: hsl(120, 100%, 40%);">+   lchan rbox lchan [label="dispatch\nHO_EV_LCHAN_ERROR\n(see Handover FSM diagrams)"];</span><br><span style="color: hsl(120, 100%, 40%);">+        --- [label="END"];</span><br><span>         |||;</span><br><span style="color: hsl(0, 100%, 40%);">-    --- [label="IF FOR_ASSIGNMENT or FOR_HANDOVER"];</span><br><span style="color: hsl(0, 100%, 40%);">-      bsc_lchan -> bsc_gscon [label="GSCON_EV_LCHAN_ALLOC_ERROR"];</span><br><span style="color: hsl(0, 100%, 40%);">-       bsc_gscon note bsc_gscon [label="conn FSM shall immediately 'forget' the lchan"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_gscon => mgw_msc [label="BSSMAP\nAssignment Failure",ID=FOR_ASSIGNMENT];</span><br><span style="color: hsl(0, 100%, 40%);">-       bsc_gscon => mgw_msc [label="BSSMAP\nHandover Failure",ID="inter-BSC-MT HO"];</span><br><span style="color: hsl(0, 100%, 40%);">-    ---;</span><br><span style="color: hsl(120, 100%, 40%);">+  --- [label="IF fi_rtp present"];</span><br><span style="color: hsl(120, 100%, 40%);">+    lchan -> rtp [label="LCHAN_RTP_EV_ROLLBACK"];</span><br><span style="color: hsl(120, 100%, 40%);">+    rtp rbox rtp [label="If to-BTS is not established yet, ROLLBACK is synonymous to LCHAN_RTP_EV_RELEASE"];</span><br><span style="color: hsl(120, 100%, 40%);">+    rtp rbox rtp [label="If there is no old_lchan, just DLCX instead"];</span><br><span style="color: hsl(120, 100%, 40%);">+ rtp abox rtp [label="LCHAN_RTP_ST_ROLLBACK"];</span><br><span style="color: hsl(120, 100%, 40%);">+       rtp box rtp [label="connect_mgw_endpoint_to_lchan()\nusing old_lchan"];</span><br><span style="color: hsl(120, 100%, 40%);">+     rtp -> mgwep [label="MDCX to-BTS"];</span><br><span style="color: hsl(120, 100%, 40%);">+      mgwep rbox mgwep [label="MGCP: MDCX"];</span><br><span style="color: hsl(120, 100%, 40%);">+      ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  mgwep rbox mgwep [label="MGCP: MDCX OK"];</span><br><span style="color: hsl(120, 100%, 40%);">+   rtp <- mgwep [label="LCHAN_RTP_EV_MGW_ENDPOINT_CONFIGURED"];</span><br><span style="color: hsl(120, 100%, 40%);">+     rtp abox rtp [label="terminate"];</span><br><span style="color: hsl(120, 100%, 40%);">+   lchan <- rtp [label="LCHAN_EV_RTP_RELEASED"];</span><br><span style="color: hsl(120, 100%, 40%);">+    --- [label="END: fi_rtp present"];</span><br><span style="color: hsl(120, 100%, 40%);">+  |||;</span><br><span>         |||;</span><br><span>         --- [label="IF unrecoverable error"];</span><br><span style="color: hsl(0, 100%, 40%);">- bsc_lchan abox bsc_lchan [label="LCHAN_ST_BORKEN"];</span><br><span style="color: hsl(0, 100%, 40%);">-   bsc_lchan note bsc_lchan [label="The broken state usually stays around</span><br><span style="color: hsl(120, 100%, 40%);">+   lchan abox lchan [label="LCHAN_ST_BORKEN"];</span><br><span style="color: hsl(120, 100%, 40%);">+ ms note lchan [label="The broken state usually stays around</span><br><span>             until the BTS disconnects."];</span><br><span>   ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    bts note bsc_lchan [label="If an ACK comes in late, for specific BTS models, we may choose to</span><br><span style="color: hsl(120, 100%, 40%);">+    ms note lchan [label="If an ACK comes in late, for specific BTS models, we may choose to</span><br><span>                'repair' the lchan so that it is usable again."];</span><br><span style="color: hsl(0, 100%, 40%);">-  bts -> bsc_lchan [label="Chan Release ACK"];</span><br><span style="color: hsl(0, 100%, 40%);">-       bsc_lchan -> bsc_lchan [label="lchan_fsm_post_rf_release()"];</span><br><span style="color: hsl(120, 100%, 40%);">+    ms -> lchan [label="RF Chan Release ACK"];</span><br><span style="color: hsl(120, 100%, 40%);">+       lchan rbox lchan [label="continue above at\nLCHAN_ST_WAIT_\nAFTER_ERROR"];</span><br><span> }</span><br><span>diff --git a/doc/legend_for_fsm_diagrams.dot b/doc/legend_for_fsm_diagrams.dot</span><br><span>new file mode 100644</span><br><span>index 0000000..732a894</span><br><span>--- /dev/null</span><br><span>+++ b/doc/legend_for_fsm_diagrams.dot</span><br><span>@@ -0,0 +1,24 @@</span><br><span style="color: hsl(120, 100%, 40%);">+digraph G {</span><br><span style="color: hsl(120, 100%, 40%);">+rankdir=TB</span><br><span style="color: hsl(120, 100%, 40%);">+labelloc=t; label="LEGEND FOR FSM GRAPHS"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ box [label="function_call()\nputs FSM into state",shape="box"]</span><br><span style="color: hsl(120, 100%, 40%);">+    STATE [label="FSM_STATE"]</span><br><span style="color: hsl(120, 100%, 40%);">+   STATE2 [label="FSM_STATE"]</span><br><span style="color: hsl(120, 100%, 40%);">+  STATE3 [label="FSM_STATE"]</span><br><span style="color: hsl(120, 100%, 40%);">+  box -> STATE</span><br><span style="color: hsl(120, 100%, 40%);">+       STATE -> STATE2 [label="state transition"]</span><br><span style="color: hsl(120, 100%, 40%);">+       STATE2 -> STATE3</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ STATE -> STATE3 [label="transition\non error",style=dashed]</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    other [label="other FSM\ninstance\nor remote program",shape=box3d]</span><br><span style="color: hsl(120, 100%, 40%);">+  STATE2 -> other [label="event",style=dotted]</span><br><span style="color: hsl(120, 100%, 40%);">+     other -> STATE2 [label="event",style=dotted]</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   terminate [shape=octagon]</span><br><span style="color: hsl(120, 100%, 40%);">+     STATE3 -> terminate</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      err [label="common error\ntransition",shape=box,style=dashed]</span><br><span style="color: hsl(120, 100%, 40%);">+       err -> STATE3 [style=dashed]</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/doc/legend_for_ladder_diagrams.msc b/doc/legend_for_ladder_diagrams.msc</span><br><span>new file mode 100644</span><br><span>index 0000000..a581fe4</span><br><span>--- /dev/null</span><br><span>+++ b/doc/legend_for_ladder_diagrams.msc</span><br><span>@@ -0,0 +1,29 @@</span><br><span style="color: hsl(120, 100%, 40%);">+msc {</span><br><span style="color: hsl(120, 100%, 40%);">+        A [label="FSM instance"],B [label="FSM instance"], C [label="remote program"];</span><br><span style="color: hsl(120, 100%, 40%);">+  |||;</span><br><span style="color: hsl(120, 100%, 40%);">+  ||| [label="LADDER DIAGRAM LEGEND"];</span><br><span style="color: hsl(120, 100%, 40%);">+        |||;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        A rbox C [label="Group Heading"];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ A box A [label="function call or action"];</span><br><span style="color: hsl(120, 100%, 40%);">+  A -> B [label="event within program"];</span><br><span style="color: hsl(120, 100%, 40%);">+   B abox B [label="enter FSM state"];</span><br><span style="color: hsl(120, 100%, 40%);">+ B => C [label="network protocol message"];</span><br><span style="color: hsl(120, 100%, 40%);">+       ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  ... [label="asynchronous wait time"];</span><br><span style="color: hsl(120, 100%, 40%);">+       ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  B <= C [label="network protocol message"];</span><br><span style="color: hsl(120, 100%, 40%);">+       |||;</span><br><span style="color: hsl(120, 100%, 40%);">+  ||| [label="continue synchronously"];</span><br><span style="color: hsl(120, 100%, 40%);">+       |||;</span><br><span style="color: hsl(120, 100%, 40%);">+  A <- B [label="event within program"];</span><br><span style="color: hsl(120, 100%, 40%);">+   A rbox A [label="flow detail: 'continue at...'"];</span><br><span style="color: hsl(120, 100%, 40%);">+   ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  --- [label="IF conditional"];</span><br><span style="color: hsl(120, 100%, 40%);">+       ||| [label="..."];</span><br><span style="color: hsl(120, 100%, 40%);">+  --- [label="END: conditional"];</span><br><span style="color: hsl(120, 100%, 40%);">+     ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  B note B [label="arbitrary prose"];</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/doc/mgw-endpoint-fsm.dot b/doc/mgw-endpoint-fsm.dot</span><br><span>new file mode 100644</span><br><span>index 0000000..ac7c2bf</span><br><span>--- /dev/null</span><br><span>+++ b/doc/mgw-endpoint-fsm.dot</span><br><span>@@ -0,0 +1,24 @@</span><br><span style="color: hsl(120, 100%, 40%);">+digraph G {</span><br><span style="color: hsl(120, 100%, 40%);">+rankdir=TB</span><br><span style="color: hsl(120, 100%, 40%);">+labelloc=t; label="MGW Endpoint FSM"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    gscon_ensure_mgw_endpoint [label="gscon_ensure_mgw_endpoint()",shape="box"]</span><br><span style="color: hsl(120, 100%, 40%);">+       UNUSED</span><br><span style="color: hsl(120, 100%, 40%);">+        WAIT_MGW_RESPONSE</span><br><span style="color: hsl(120, 100%, 40%);">+     IN_USE</span><br><span style="color: hsl(120, 100%, 40%);">+        terminate [shape=octagon]</span><br><span style="color: hsl(120, 100%, 40%);">+     mgcp [label="mgcp client FSM\n(libosmo-mgcp-client)",shape=box3d]</span><br><span style="color: hsl(120, 100%, 40%);">+   notify [label="notify target FI",shape=box3d]</span><br><span style="color: hsl(120, 100%, 40%);">+       gscon [label="parent FI\n(gscon)",shape=box3d]</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    gscon_ensure_mgw_endpoint -> UNUSED</span><br><span style="color: hsl(120, 100%, 40%);">+        UNUSED -> WAIT_MGW_RESPONSE [label="first\nmgw_endpoint_ci_request(CRCX)"]</span><br><span style="color: hsl(120, 100%, 40%);">+       WAIT_MGW_RESPONSE -> mgcp [label="mgcp_conn_create()\nmgcp_conn_modify()\nmgcp_conn_delete()",style=dotted]</span><br><span style="color: hsl(120, 100%, 40%);">+      mgcp -> WAIT_MGW_RESPONSE [label="CI[i] event",style=dotted]</span><br><span style="color: hsl(120, 100%, 40%);">+     WAIT_MGW_RESPONSE -> IN_USE</span><br><span style="color: hsl(120, 100%, 40%);">+        IN_USE -> notify [label="notify event for\nindividual CI request",style=dotted]</span><br><span style="color: hsl(120, 100%, 40%);">+  IN_USE -> WAIT_MGW_RESPONSE [label="additional\nmgw_endpoint_ci_request()\nCRCX,MDCX,DLCX"]</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    WAIT_MGW_RESPONSE -> terminate [label="all CI DLCX'd"]</span><br><span style="color: hsl(120, 100%, 40%);">+       terminate -> gscon [label="GSCON_EV_FORGET_MGW_ENDPOINT",style=dotted]</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/doc/mgw-endpoint.msc b/doc/mgw-endpoint.msc</span><br><span>new file mode 100644</span><br><span>index 0000000..7084d1d</span><br><span>--- /dev/null</span><br><span>+++ b/doc/mgw-endpoint.msc</span><br><span>@@ -0,0 +1,105 @@</span><br><span style="color: hsl(120, 100%, 40%);">+msc {</span><br><span style="color: hsl(120, 100%, 40%);">+     hscale=2;</span><br><span style="color: hsl(120, 100%, 40%);">+     notify [label="calling FSM"], mgwep[label="MGW endpoint FSM"], mgcp[label="mgcp client FSM"],</span><br><span style="color: hsl(120, 100%, 40%);">+   mgw[label="MGW"];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ notify note mgw [label="MGW endpoint FSM\nmanages multiple CI for one endpoint"];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ |||;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        notify rbox notify [label="conn FSM"];</span><br><span style="color: hsl(120, 100%, 40%);">+      notify box notify [label="gscon_ensure_mgw_endpoint()"];</span><br><span style="color: hsl(120, 100%, 40%);">+    notify -> mgwep [label="mgw_endpoint_alloc()"];</span><br><span style="color: hsl(120, 100%, 40%);">+  mgwep abox mgwep [label="MGWEP_ST_UNUSED"];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  notify rbox mgw [label="CRCX"];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   notify rbox notify [label="lchan RTP FSM"];</span><br><span style="color: hsl(120, 100%, 40%);">+ notify -> mgwep [label="mgw_endpoint_ci_add()"];</span><br><span style="color: hsl(120, 100%, 40%);">+ mgwep note mgwep [label="Return an unassigned endpoint CI slot in the local array"];</span><br><span style="color: hsl(120, 100%, 40%);">+        ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  mgwep note mgwep [label="First request on a CI must be a CRCX"];</span><br><span style="color: hsl(120, 100%, 40%);">+    notify -> mgwep [label="mgw_endpoint_ci_request(CRCX)"];</span><br><span style="color: hsl(120, 100%, 40%);">+ notify note mgwep [label="verb=CRCX\nverb_info='rtpbridge/*@mgw'\nnotify_event"];</span><br><span style="color: hsl(120, 100%, 40%);">+   mgwep box mgwep [label="CI[x].pending=true"];</span><br><span style="color: hsl(120, 100%, 40%);">+       mgwep abox mgwep [label="MGWEP_ST_WAIT_MGW_RESPONSE"];</span><br><span style="color: hsl(120, 100%, 40%);">+      |||;</span><br><span style="color: hsl(120, 100%, 40%);">+  notify note mgwep [label="If more mgw_endpoint_ci_request() are triggered, they will be set to</span><br><span style="color: hsl(120, 100%, 40%);">+           'pending' and wait until all ongoing requests are through and MGWEP_ST_IN_USE is</span><br><span style="color: hsl(120, 100%, 40%);">+              reached."];</span><br><span style="color: hsl(120, 100%, 40%);">+      |||;</span><br><span style="color: hsl(120, 100%, 40%);">+  mgwep box mgwep [label="for each pending CI:\nsend_verb()"];</span><br><span style="color: hsl(120, 100%, 40%);">+        mgwep -> mgcp [label="CI[x]: mgcp_conn_create()"];</span><br><span style="color: hsl(120, 100%, 40%);">+       mgwep note mgcp [label="Each CI[i] has two events from the FSM instance event range assigned, one</span><br><span style="color: hsl(120, 100%, 40%);">+                for success, one for failure. These are passed to the mgcp client FSM."];</span><br><span style="color: hsl(120, 100%, 40%);">+        mgcp => mgw [label="CRCX"];</span><br><span style="color: hsl(120, 100%, 40%);">+      ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  mgcp <= mgw [label="CRCX OK"];</span><br><span style="color: hsl(120, 100%, 40%);">+   mgcp note mgw [label="MGW returns:\n'rtpbridge/123@mgw',\nnew CI identifier '123abc',\n</span><br><span style="color: hsl(120, 100%, 40%);">+          MGW side RTP IP:port"];</span><br><span style="color: hsl(120, 100%, 40%);">+  mgwep <- mgcp [label="CI[x] success event"];</span><br><span style="color: hsl(120, 100%, 40%);">+     mgwep box mgwep [label="on_success(CI[x])"];</span><br><span style="color: hsl(120, 100%, 40%);">+        mgwep note mgwep [label="CI[x].rtp_info = IP:port\nmgcp_ci_str = '123abc'\n</span><br><span style="color: hsl(120, 100%, 40%);">+              endpoint name = 'rtpbridge/123@mgw'"];</span><br><span style="color: hsl(120, 100%, 40%);">+   notify <- mgwep [label="notify_event from mgw_endpoint_ci_request()"];</span><br><span style="color: hsl(120, 100%, 40%);">+   notify note mgwep [label="notify_event will be one of:\n</span><br><span style="color: hsl(120, 100%, 40%);">+         LCHAN_RTP_EV_MGW_ENDPOINT_AVAILABLE (towards BTS)\n</span><br><span style="color: hsl(120, 100%, 40%);">+           ASSIGNMENT_EV_MSC_MGW_OK (towards MSC)\n</span><br><span style="color: hsl(120, 100%, 40%);">+              HO_EV_MSC_MGW_OK (towards MSC)"];</span><br><span style="color: hsl(120, 100%, 40%);">+        mgwep abox mgwep [label="MGWEP_ST_IN_USE"];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  notify rbox mgw [label="MDCX"];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   mgwep note mgwep [label="Second or later request on a CI must be MDCX or DLCX"];</span><br><span style="color: hsl(120, 100%, 40%);">+    notify -> mgwep [label="mgw_endpoint_ci_request(MDCX)"];</span><br><span style="color: hsl(120, 100%, 40%);">+ notify note mgwep [label="verb=MDCX\nverb_info=BTS RTP IP:port\n</span><br><span style="color: hsl(120, 100%, 40%);">+         automatic: full endpoint name as from CRCX OK\n</span><br><span style="color: hsl(120, 100%, 40%);">+               notify_event\n"];</span><br><span style="color: hsl(120, 100%, 40%);">+        mgwep box mgwep [label="CI[x].pending=true"];</span><br><span style="color: hsl(120, 100%, 40%);">+       mgwep abox mgwep [label="MGWEP_ST_WAIT_MGW_RESPONSE"];</span><br><span style="color: hsl(120, 100%, 40%);">+      mgwep box mgwep [label="for each pending CI:\nsend_verb()"];</span><br><span style="color: hsl(120, 100%, 40%);">+        mgwep -> mgcp [label="CI[x]: mgcp_conn_modify()"];</span><br><span style="color: hsl(120, 100%, 40%);">+       mgcp => mgw [label="MDCX"];</span><br><span style="color: hsl(120, 100%, 40%);">+      ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  mgcp <= mgw [label="MDCX OK"];</span><br><span style="color: hsl(120, 100%, 40%);">+   mgwep <- mgcp [label="CI[x] success event"];</span><br><span style="color: hsl(120, 100%, 40%);">+     mgwep box mgwep [label="on_success(CI[x])"];</span><br><span style="color: hsl(120, 100%, 40%);">+        notify <- mgwep [label="notify_event from mgw_endpoint_ci_request()"];</span><br><span style="color: hsl(120, 100%, 40%);">+   notify note mgwep [label="notify_event will be one of:\n</span><br><span style="color: hsl(120, 100%, 40%);">+         LCHAN_RTP_EV_MGW_ENDPOINT_CONFIGURED (towards BTS)\n</span><br><span style="color: hsl(120, 100%, 40%);">+          ASSIGNMENT_EV_MSC_MGW_OK (towards MSC)\n</span><br><span style="color: hsl(120, 100%, 40%);">+              HO_EV_MSC_MGW_OK (towards MSC)"];</span><br><span style="color: hsl(120, 100%, 40%);">+        mgwep abox mgwep [label="MGWEP_ST_IN_USE"];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  notify rbox mgw [label="DLCX"];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   notify -> mgwep [label="mgw_endpoint_ci_dlcx()"];</span><br><span style="color: hsl(120, 100%, 40%);">+        mgwep box mgwep [label="mgw_endpoint_ci_request(DLCX)"];</span><br><span style="color: hsl(120, 100%, 40%);">+    mgwep box mgwep [label="CI[x].pending=true"];</span><br><span style="color: hsl(120, 100%, 40%);">+       mgwep abox mgwep [label="MGWEP_ST_WAIT_MGW_RESPONSE"];</span><br><span style="color: hsl(120, 100%, 40%);">+      mgwep box mgwep [label="for each pending CI:\nsend_verb()"];</span><br><span style="color: hsl(120, 100%, 40%);">+        mgwep -> mgcp [label="CI[x]: mgcp_conn_delete()"];</span><br><span style="color: hsl(120, 100%, 40%);">+       mgcp => mgw [label="DLCX"];</span><br><span style="color: hsl(120, 100%, 40%);">+      mgcp box mgcp [label="detach from parent fi"];</span><br><span style="color: hsl(120, 100%, 40%);">+      mgwep box mgwep [label="forget and clear CI[x]"];</span><br><span style="color: hsl(120, 100%, 40%);">+   --- [label="IF other CI remain valid"];</span><br><span style="color: hsl(120, 100%, 40%);">+     mgwep abox mgwep [label="MGWEP_ST_IN_USE"];</span><br><span style="color: hsl(120, 100%, 40%);">+ --- [label="IF no CI remain on endpoint"];</span><br><span style="color: hsl(120, 100%, 40%);">+  mgwep abox mgwep [label="terminate"];</span><br><span style="color: hsl(120, 100%, 40%);">+       notify rbox notify [label="conn FSM"];</span><br><span style="color: hsl(120, 100%, 40%);">+      notify <- mgwep [label="GSCON_EV_FORGET_MGW_ENDPOINT"];</span><br><span style="color: hsl(120, 100%, 40%);">+  ---;</span><br><span style="color: hsl(120, 100%, 40%);">+  ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  mgcp <= mgw [label="DLCX OK"];</span><br><span style="color: hsl(120, 100%, 40%);">+   mgcp abox mgcp [label="terminate"];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/doc/ms-channel-request.msc b/doc/ms-channel-request.msc</span><br><span>deleted file mode 100644</span><br><span>index 1c5b4bf..0000000</span><br><span>--- a/doc/ms-channel-request.msc</span><br><span>+++ /dev/null</span><br><span>@@ -1,59 +0,0 @@</span><br><span style="color: hsl(0, 100%, 40%);">-msc {</span><br><span style="color: hsl(0, 100%, 40%);">-        hscale=2;</span><br><span style="color: hsl(0, 100%, 40%);">-       ms [label="MS"], bts [label="BTS"], bsc[label="BSC"], bsc_lchan[label="BSC lchan FSM"];</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- ms note bsc_lchan [label="lchan allocation sequence for RSL Channel Request"];</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        ms => bts [label="RR Channel Request"];</span><br><span style="color: hsl(0, 100%, 40%);">-    bts => bsc [label="RSL Channel Request"];</span><br><span style="color: hsl(0, 100%, 40%);">-  bsc box bsc [label="rsl_rx_chan_rqd()"];</span><br><span style="color: hsl(0, 100%, 40%);">-      bsc note bsc [label="Obtain RACH data from Request: - Reference - Access Delay (TA)</span><br><span style="color: hsl(0, 100%, 40%);">-                - Request Reason - Channel Type"];</span><br><span style="color: hsl(0, 100%, 40%);">- bsc note bsc [label="If the reason is PDCH, the RACH Request is forwarded to PCU and BSC is no</span><br><span style="color: hsl(0, 100%, 40%);">-             longer concerned (rsl_rx_pchan_rqd())."];</span><br><span style="color: hsl(0, 100%, 40%);">-  bsc note bsc [label="Always try to allocate an SDCCH regardless of the requested type, only if no</span><br><span style="color: hsl(0, 100%, 40%);">-          SDCCH is available, look for the actually requested channel type."];</span><br><span style="color: hsl(0, 100%, 40%);">-       bsc box bsc [label="lchan_select_by_type(SDCCH)"];</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    --- [label="IF no lchan is available (neither SDCCH nor requested type)"];</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc note bsc [label="Figure out T3122 value from bts->T3122, network->T3122 or</span><br><span style="color: hsl(0, 100%, 40%);">-               GSM_T3122_DEFAULT"];</span><br><span style="color: hsl(0, 100%, 40%);">-       bsc box bsc [label="rsl_send_imm_ass_rej(wait_ind=T3122)"];</span><br><span style="color: hsl(0, 100%, 40%);">-   bsc note bsc [label="..."];</span><br><span style="color: hsl(0, 100%, 40%);">-   bts <= bsc [label="RR Immediate Assign Reject"];</span><br><span style="color: hsl(0, 100%, 40%);">-   ms <= bts [label="RR Immediate Assign Reject (possibly grouped with up to 4 others)"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc note bsc [label="rsl_rx_pchan_rqd() exits, no channel is allocated."];</span><br><span style="color: hsl(0, 100%, 40%);">-    --- [label="END: no lchan is available"];</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc box bsc [label="Store RACH data in lchan->rqd_ref, rqd_ta"];</span><br><span style="color: hsl(0, 100%, 40%);">-   bsc -> bsc_lchan [label="lchan_allocate(FOR_MS_CHANNEL_REQUEST)"];</span><br><span style="color: hsl(0, 100%, 40%);">- bsc_lchan abox bsc_lchan [label="LCHAN_ST_WAIT_ACTIV_ACK\nT3103"];</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_lchan note bsc_lchan [label="The lchan FSM knows that FOR_MS_CHANNEL_REQUEST is about</span><br><span style="color: hsl(0, 100%, 40%);">-          Immediate Assignment."];</span><br><span style="color: hsl(0, 100%, 40%);">-   bts <= bsc_lchan [label="RSL Chan Activ (Immediate Assignment)"];</span><br><span style="color: hsl(0, 100%, 40%);">-  ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    --- [label="on any error"];</span><br><span style="color: hsl(0, 100%, 40%);">-   bts <= bsc_lchan [label="RR Immediate Assign Reject"];</span><br><span style="color: hsl(0, 100%, 40%);">-     ms <= bts [label="RR Immediate Assign Reject (possibly grouped with up to 4 others)"];</span><br><span style="color: hsl(0, 100%, 40%);">-     ---;</span><br><span style="color: hsl(0, 100%, 40%);">-    ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    bts => bsc_lchan [label="RSL Chan Activ ACK"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_lchan abox bsc_lchan [label="LCHAN_ST_WAIT_\nRLL_ESTABLISH\ncontinue T3103"];</span><br><span style="color: hsl(0, 100%, 40%);">-     ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    --- [label="on timeout"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_lchan box bsc_lchan [label="lchan_error_release(deact_sacch=true)"];</span><br><span style="color: hsl(0, 100%, 40%);">-      bsc_lchan abox bsc_lchan [label="LCHAN_ST_WAIT_RF_RELEASE_ACK"];</span><br><span style="color: hsl(0, 100%, 40%);">-      bts <= bsc_lchan [label="RLL Release Request (Local End)..."];</span><br><span style="color: hsl(0, 100%, 40%);">-     bts <= bsc_lchan [label="...for all SAPIs including [0]"];</span><br><span style="color: hsl(0, 100%, 40%);">- bts <= bsc_lchan [label="RSL Deactivate SACCH"];</span><br><span style="color: hsl(0, 100%, 40%);">-   bts <= bsc_lchan [label="RSL RF Channel Release"];</span><br><span style="color: hsl(0, 100%, 40%);">- ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    bts => bsc_lchan [label="RSL RF Channel Release ACK"];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_lchan abox bsc_lchan [label="LCHAN_ST_WAIT_AFTER_ERROR"];</span><br><span style="color: hsl(0, 100%, 40%);">- ...;</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_lchan abox bsc_lchan [label="LCHAN_ST_UNUSED"];</span><br><span style="color: hsl(0, 100%, 40%);">-   ---;</span><br><span style="color: hsl(0, 100%, 40%);">-    ms => bsc_lchan [label="RLL Establish Ind"];</span><br><span style="color: hsl(0, 100%, 40%);">-       bsc_lchan box bsc_lchan [label="associate lchan FSM with new conn FSM"];</span><br><span style="color: hsl(0, 100%, 40%);">-      bsc_lchan abox bsc_lchan [label="LCHAN_ST_ACTIVE"];</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span>diff --git a/doc/timeslot-fsm.dot b/doc/timeslot-fsm.dot</span><br><span>index 79e56c9..95a4e1f 100644</span><br><span>--- a/doc/timeslot-fsm.dot</span><br><span>+++ b/doc/timeslot-fsm.dot</span><br><span>@@ -1,10 +1,11 @@</span><br><span> digraph G {</span><br><span style="color: hsl(0, 100%, 40%);">-rankdir=TB;</span><br><span style="color: hsl(120, 100%, 40%);">+rankdir=TB</span><br><span style="color: hsl(120, 100%, 40%);">+labelloc=t; label="Timeslot FSM"</span><br><span>    </span><br><span>     invisible [style="invisible"]</span><br><span>      invisible2 [style="invisible"]</span><br><span>     NOT_INITIALIZED</span><br><span style="color: hsl(0, 100%, 40%);">- lchan [label="lchan FSM",shape=box3d];</span><br><span style="color: hsl(120, 100%, 40%);">+      lchan [label="lchan FSM",shape=box3d]</span><br><span>      UNUSED</span><br><span>       IN_USE</span><br><span>       BORKEN</span><br><span>diff --git a/doc/timeslot.msc b/doc/timeslot.msc</span><br><span>index 9a8c360..02e7bb3 100644</span><br><span>--- a/doc/timeslot.msc</span><br><span>+++ b/doc/timeslot.msc</span><br><span>@@ -1,25 +1,24 @@</span><br><span> msc {</span><br><span style="color: hsl(0, 100%, 40%);">-        hscale=2;</span><br><span>    bts [label="MS/BTS"], bsc[label="BSC"], bsc_ts[label="BSC timeslot FSM"], bsc_lchan[label="BSC lchan FSM"];</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- bsc_ts abox bsc_ts [label="NOT_INITIALIZED (no timeout)"];</span><br><span style="color: hsl(120, 100%, 40%);">+  bsc_ts abox bsc_ts [label="NOT_INITIALIZED"];</span><br><span> </span><br><span>  ...;</span><br><span>         bsc note bsc_ts [label="OML and RSL may be established in any order"];</span><br><span>     bts => bsc_ts [label="OML: Channel OPSTART ACK"];</span><br><span>       bsc -> bsc_ts [label="RSL bootstrapped"];</span><br><span style="color: hsl(0, 100%, 40%);">-  bsc_ts abox bsc_ts [label="UNUSED (no timeout)"];</span><br><span style="color: hsl(120, 100%, 40%);">+   bsc_ts abox bsc_ts [label="UNUSED"];</span><br><span> </span><br><span>   |||;</span><br><span>         bts rbox bsc_lchan [label="UNUSED, onenter"];</span><br><span>      bsc_ts abox bsc_ts [label="UNUSED"];</span><br><span>       --- [label="GPRS enabled?"];</span><br><span>       --- [label="IF: dedicated PDCH?"];</span><br><span style="color: hsl(0, 100%, 40%);">-    bsc_ts abox bsc_ts [label="PDCH (no timeout)"];</span><br><span style="color: hsl(120, 100%, 40%);">+     bsc_ts abox bsc_ts [label="PDCH"];</span><br><span> </span><br><span>     |||;</span><br><span>         --- [label="IF: dynamic timeslot"];</span><br><span style="color: hsl(0, 100%, 40%);">-   bsc_ts abox bsc_ts [label="WAIT_PDCH_ACT (?s, Tnnnn)"];</span><br><span style="color: hsl(120, 100%, 40%);">+     bsc_ts abox bsc_ts [label="WAIT_PDCH_ACT (4s, T23001)"];</span><br><span>   bts <= bsc_ts [label="RSL Chan Activ of PDCH",ID="Osmocom style"];</span><br><span>    bts <= bsc_ts [label="RSL PDCH Act",ID="ip.access style"];</span><br><span>    ...;</span><br><span>@@ -29,7 +28,7 @@</span><br><span>     ...;</span><br><span>         bts => bsc_ts [label="RSL RF Chan Activ ACK",ID="Osmocom style"];</span><br><span>     bts => bsc_ts [label="RSL PDCH Act ACK",ID="ip.access style"];</span><br><span style="color: hsl(0, 100%, 40%);">-   bsc_ts abox bsc_ts [label="PDCH (no timeout)"];</span><br><span style="color: hsl(120, 100%, 40%);">+     bsc_ts abox bsc_ts [label="PDCH"];</span><br><span> </span><br><span>     --- [label="END: GPRS enabled?"];</span><br><span>  ...;</span><br><span>@@ -43,12 +42,14 @@</span><br><span>   bts <= bsc_lchan [label="RSL Chan Activ (and so on)"];</span><br><span>  ...;</span><br><span>         bts rbox bsc_lchan [label="IN_USE, second lchan"];</span><br><span style="color: hsl(120, 100%, 40%);">+  bsc_ts abox bsc_ts [label="IN_USE"];</span><br><span>       bsc_ts <- bsc_lchan [label="TS_EV_LCHAN_REQUESTED (data=lchan)"];</span><br><span>       bsc_ts -> bsc_lchan [label="LCHAN_EV_TS_READY"];</span><br><span>        bts <= bsc_lchan [label="RSL Chan Activ (and so on)"];</span><br><span>  ...;</span><br><span>         ...;</span><br><span>         bts rbox bsc_lchan [label="IN_USE, when lchan FSM releases (both regularly, or due to error)"];</span><br><span style="color: hsl(120, 100%, 40%);">+     bsc_ts abox bsc_ts [label="IN_USE"];</span><br><span>       bsc_ts <- bsc_lchan [label="TS_EV_LCHAN_UNUSED (data=lchan)"];</span><br><span>  --- [label="IF all lchan->fi->state == LCHAN_ST_UNUSED"];</span><br><span>    bsc_ts abox bsc_ts [label="UNUSED"];</span><br><span>@@ -57,13 +58,14 @@</span><br><span>         ...;</span><br><span> </span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    bts rbox bsc_lchan [label="PDCH on lchan request"];</span><br><span style="color: hsl(120, 100%, 40%);">+ bts rbox bsc_lchan [label="PDCH, on lchan request"];</span><br><span>       bsc_ts note bsc_lchan [label="TS_EV_LCHAN_REQUESTED should only come in on</span><br><span>              lchans where it makes sense, both from TS kind as well as not</span><br><span>                conflicting with other users of the lchan."];</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+        bsc_ts abox bsc_ts [label="PDCH"];</span><br><span>         bsc_ts <- bsc_lchan [label="TS_EV_LCHAN_REQUESTED"];</span><br><span style="color: hsl(0, 100%, 40%);">-       bsc_ts abox bsc_ts [label="WAIT_PDCH_DEACT (?s, Tnnnn)"];</span><br><span style="color: hsl(120, 100%, 40%);">+   bsc_ts abox bsc_ts [label="WAIT_PDCH_DEACT (4s, T23001)"];</span><br><span>         bts <= bsc_ts [label="RSL RF Chan Release of PDCH",ID="Osmocom style"];</span><br><span>       bts <= bsc_ts [label="RSL PDCH Deact",ID="ip.access style"];</span><br><span>  ...;</span><br><span>diff --git a/doc/ts-and-lchan-fsm-lifecycle.msc b/doc/ts-and-lchan-fsm-lifecycle.msc</span><br><span>index 79d32c5..9275f1f 100644</span><br><span>--- a/doc/ts-and-lchan-fsm-lifecycle.msc</span><br><span>+++ b/doc/ts-and-lchan-fsm-lifecycle.msc</span><br><span>@@ -55,7 +55,7 @@</span><br><span>        --- [label="dyn TS"];</span><br><span>      bsc_ts box bsc_ts [label="onenter of TS_ST_UNUSED:"];</span><br><span>      bsc_ts abox bsc_ts [label="TS_ST_WAIT_PDCH_ACT"];</span><br><span style="color: hsl(0, 100%, 40%);">-     ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  ... [label="..."];</span><br><span>         bsc_ts abox bsc_ts [label="PDCH"];</span><br><span>         --- [label="END: dyn TS"];</span><br><span>         --- [label="END: OML and RSL ready"];</span><br><span>@@ -65,13 +65,13 @@</span><br><span>        bsc_lchan -> bsc_ts [label="TS_EV_LCHAN_REQUESTED"];</span><br><span>    </span><br><span>     --- [label="dyn TS"];</span><br><span style="color: hsl(0, 100%, 40%);">- bsc_ts note bsc_ts [label="possibly switch from PDCH...\n(see timeslot FSM)"];</span><br><span style="color: hsl(120, 100%, 40%);">+      bsc_ts rbox bsc_ts [label="possibly switch from PDCH...\n(see timeslot FSM)"];</span><br><span>     bsc_ts box bsc_ts [label="ts->pchan =\n requested GSM_PCHAN_XXX type"];</span><br><span>         ---;</span><br><span> </span><br><span>     bsc_ts -> bsc_lchan [label="LCHAN_EV_TS_READY"];</span><br><span>        bsc_lchan note bsc_lchan [label="RSL Chan Alloc and so fort..."];</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_lchan abox bsc_lchan [label="LCHAN_ST_ACTIVE"];</span><br><span style="color: hsl(120, 100%, 40%);">+ bsc_lchan abox bsc_lchan [label="LCHAN_ST_ESTABLISHED"];</span><br><span>   ...;</span><br><span>         bsc -> bsc_lchan [label="LCHAN_EV_RELEASE"];</span><br><span>    bsc_lchan note bsc_lchan [label="...RSL RF Chan Release..."];</span><br><span>@@ -79,7 +79,7 @@</span><br><span>  bsc_ts <- bsc_lchan [label="TS_EV_LCHAN_UNUSED"];</span><br><span>       bsc_ts abox bsc_ts [label="TS_ST_UNUSED"];</span><br><span>         --- [label="dyn TS"];</span><br><span style="color: hsl(0, 100%, 40%);">- bsc_ts note bsc_ts [label="possibly switch to PDCH"];</span><br><span style="color: hsl(120, 100%, 40%);">+       bsc_ts rbox bsc_ts [label="possibly switch to PDCH"];</span><br><span>      ---;</span><br><span>         ...;</span><br><span>         ...;</span><br><span>@@ -88,8 +88,8 @@</span><br><span>     bsc -> bsc_ts [label="ts[*]:"];</span><br><span>         bsc_ts abox bsc_ts [label="TS_ST_NOT_INITIALIZED"];</span><br><span>        bsc_ts note bsc_lchan [label="If it's just the RSL being dropped, transition lchan FSMs to</span><br><span style="color: hsl(0, 100%, 40%);">-             LCHAN_ST_UNUSED, but keep them allocated. Unless OML is re-established, any vty pchan</span><br><span style="color: hsl(0, 100%, 40%);">-           modifications must not take effect."];</span><br><span style="color: hsl(120, 100%, 40%);">+           LCHAN_ST_UNUSED, but keep them allocated. Unless OML is re-established, any telnet</span><br><span style="color: hsl(120, 100%, 40%);">+            vty pchan modifications must not take effect."];</span><br><span>        bsc_ts -> bsc_lchan [label="lchan[*]:"];</span><br><span>        bsc_lchan abox bsc_lchan [label="LCHAN_ST_UNUSED"];</span><br><span>        bsc_ts <- bsc_lchan [label="TS_EV_LCHAN_UNUSED (ignored)"];</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/9667">change 9667</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/9667"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-bsc </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: merged </div>
<div style="display:none"> Gerrit-Change-Id: I29e31b753e23a4207662e0e385a337e7df836f45 </div>
<div style="display:none"> Gerrit-Change-Number: 9667 </div>
<div style="display:none"> Gerrit-PatchSet: 15 </div>
<div style="display:none"> Gerrit-Owner: Neels Hofmeyr <nhofmeyr@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Harald Welte <laforge@gnumonks.org> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder </div>
<div style="display:none"> Gerrit-Reviewer: Neels Hofmeyr <nhofmeyr@sysmocom.de> </div>