| # Handover between cells, intra-BSC |
| msc { |
| hscale=3; |
| ms [label="MS via BTS"], bsc_lchan[label="BSC lchan FSM"], bsc_gscon[label="BSC conn FSM"], |
| bsc_mgcp[label="BSC mgcp FSM"], mgw_msc[label="MGW/MSC"]; |
| |
| ms note mgw_msc [label="intra-BSC Handover sequence"]; |
| |
| bsc_gscon abox bsc_gscon [label="ST_ACTIVE"]; |
| bsc_gscon box bsc_gscon [label="bsc_handover_start(): init conn->ho"]; |
| bsc_gscon -> bsc_gscon [label="GSCON_EV_HO_START (intra-BSC)"]; |
| bsc_gscon abox bsc_gscon [label="ST_HANDOVER_\nWAIT_LCHAN"]; |
| bsc_lchan <- bsc_gscon [label="lchan_activate(lchan, FOR_HANDOVER)"]; |
| ...; |
| --- [label="on lchan FSM error or timeout"]; |
| bsc_lchan -> bsc_gscon [label="GSCON_EV_LCHAN_ALLOC_ERROR"]; |
| bsc_gscon box bsc_gscon [label="handover_end(fail)"]; |
| ms note bsc_gscon [label="MS happily continues on the old lchan."]; |
| bsc_gscon abox bsc_gscon [label="ST_ACTIVE"]; |
| --- [label="END: 'on error'"]; |
| ...; |
| ...; |
| |
| --- [label="IF lchan FSM decides that it is an lchan for speech"]; |
| bsc_lchan -> bsc_gscon [label="GSCON_EV_ENSURE_MGW_ENDPOINT"]; |
| --- [label="IF there is an MGW endpoint for the BTS already (conn->user_plane.fi_bts)"]; |
| bsc_gscon box bsc_gscon [label="handover_created_mgw_endpoint = false"]; |
| bsc_gscon -> bsc_lchan [label="LCHAN_EV_MGW_ENDPOINT_AVAILABLE"]; |
| --- [label="ELSE: no MGW endpoint for the BTS side yet"]; |
| bsc_gscon abox bsc_gscon [label="ST_HANDOVER_\nWAIT_CRCX_BTS"]; |
| bsc_gscon box bsc_gscon [label="handover_created_mgw_endpoint = true"]; |
| bsc_gscon -> bsc_mgcp [label="mgcp_conn_create()"]; |
| bsc_mgcp => mgw_msc [label="CRCX (for BTS)"]; |
| bsc_mgcp abox bsc_mgcp [label="ST_CRCX_RESP (MGCP_MGW_TIMEOUT = 4s)"]; |
| bsc_gscon note bsc_mgcp [label="conn FSM relies on mgcp FSM timeout"]; |
| ...; |
| --- [label="On Timeout"]; |
| bsc_mgcp note bsc_mgcp [label="On timeout, the MGCP FSM will terminate, emitting the parent_term |
| event set upon mgcp_conn_create():"]; |
| bsc_mgcp -> bsc_gscon [label="GSCON_EV_MGW_FAIL_BTS"]; |
| bsc_gscon note bsc_gscon [label="GSCON_EV_MGW_FAIL_BTS is handled by the conn FSM allstate |
| handler. It sets conn->user_plane.fi_bts = NULL."]; |
| bsc_gscon -> bsc_lchan [label="LCHAN_EV_MGW_ENDPOINT_ERROR"]; |
| bsc_lchan note bsc_gscon [label="conn FSM error handler exits and relies on the lchan FSM |
| signalling error, which should actually happen immediately:"]; |
| bsc_gscon <- bsc_lchan [label="GSCON_EV_LCHAN_ALLOC_ERROR"]; |
| bsc_gscon box bsc_gscon [label="handover_end(fail)"]; |
| --- [label="IF handover_created_mgw_endpoint == true"]; |
| bsc_gscon -> bsc_mgcp [label="mgcp_conn_delete()"]; |
| ---; |
| ms note bsc_gscon [label="MS happily continues on the old lchan."]; |
| bsc_gscon abox bsc_gscon [label="ST_ACTIVE"]; |
| --- [label="END: 'On Timeout'"]; |
| ...; |
| |
| bsc_mgcp <= mgw_msc [label="CRCX OK (for BTS)"]; |
| bsc_mgcp box bsc_mgcp [label="libosmo-mgcp-client fsm_crcx_resp_cb()"]; |
| bsc_mgcp abox bsc_mgcp [label="ST_READY"]; |
| bsc_mgcp -> bsc_gscon [label="GSCON_EV_MGW_CRCX_RESP_BTS"]; |
| bsc_gscon abox bsc_gscon [label="ST_HANDOVER_\nWAIT_LCHAN"]; |
| bsc_gscon -> bsc_lchan [label="LCHAN_EV_MGW_ENDPOINT_AVAILABLE"]; |
| --- [label="END: lchan FSM decides that it is an lchan for speech"]; |
| ...; |
| ...; |
| |
| bsc_lchan -> bsc_gscon [label="GSCON_EV_LCHAN_ACTIVE"]; |
| bsc_gscon abox bsc_gscon [label="ST_HANDOVER_\nWAIT_DETECT\nT3103"]; |
| bsc_gscon box bsc_gscon [label="gsm48_send_ho_cmd()"]; |
| ms <= bsc_gscon [label="RR Handover Command"]; |
| |
| ...; |
| --- [label="On timeout"]; |
| bsc_lchan <- bsc_gscon [label="NEW lchan: LCHAN_EV_RELEASE"]; |
| ms <=> bsc_lchan [label="release procedure (async)"]; |
| bsc_gscon box bsc_gscon [label="handover_end(fail)"]; |
| --- [label="IF handover_created_mgw_endpoint == true"]; |
| bsc_gscon -> bsc_mgcp [label="mgcp_conn_delete()"]; |
| ---; |
| ms note bsc_gscon [label="MS happily continues on the old lchan."]; |
| bsc_gscon abox bsc_gscon [label="ST_ACTIVE"]; |
| --- [label="END: On timeout"]; |
| ...; |
| ms => bsc_gscon [label="RR Handover Detect"]; |
| |
| bsc_gscon abox bsc_gscon [label="ST_HANDOVER_\nWAIT_MDCX_BTS\ncontinue T3103"]; |
| bsc_gscon -> bsc_lchan [label="OLD lchan: LCHAN_EV_RELEASE"]; |
| ms <=> bsc_lchan [label="release procedure (async)"]; |
| bsc_lchan note bsc_gscon [label="officially take over new lchan: conn->lchan = ho->new_lchan"]; |
| bsc_gscon -> bsc_mgcp [label="mgcp_conn_modify()"]; |
| bsc_mgcp note bsc_mgcp [label="mgcp FSM that was established for old lchan, for BTS side"]; |
| bsc_mgcp abox bsc_mgcp [label="ST_MDCX_RESP"]; |
| bsc_mgcp => mgw_msc [label="MDCX (for BTS)"]; |
| ...; |
| --- [label="Should the Handover Complete arrive early"]; |
| ms => bsc_gscon [label="RR Handover Complete"]; |
| bsc_gscon box bsc_gscon [label="handover_complete_received = true"]; |
| ---; |
| ...; |
| --- [label="On timeout of the mgcp FSM"]; |
| bsc_gscon note mgw_msc [label="MGCP FSM terminates"]; |
| bsc_gscon <- bsc_mgcp [label="GSCON_EV_MGW_FAIL_BTS"]; |
| bsc_lchan note bsc_gscon [label="The phone has already taken on the new lchan, but now we happen |
| to not be able to use it. The only sensible thing is to end the conn."]; |
| bsc_gscon abox bsc_gscon [label="ST_WAIT_CLEAR_CMD"]; |
| bsc_gscon => mgw_msc [label="BSSMAP Clear Request\n(Equipment Failure)"]; |
| bsc_lchan <- bsc_gscon [label="NEW lchan: LCHAN_EV_RELEASE"]; |
| ms <=> bsc_lchan [label="release procedure (async)"]; |
| bsc_gscon -> bsc_mgcp [label="mgcp_conn_delete()"]; |
| ...; |
| bsc_mgcp <= mgw_msc [label="MDCX OK"]; |
| bsc_mgcp abox bsc_mgcp [label="ST_READY"]; |
| bsc_mgcp -> bsc_gscon [label="GSCON_EV_MGW_MDCX_RESP_BTS"]; |
| --- [label="IF !handover_complete_received"]; |
| bsc_gscon abox bsc_gscon [label="ST_HANDOVER_\nWAIT_COMPLETE\ncontinue T3103"]; |
| --- [label="ELSE"]; |
| bsc_gscon -> bsc_gscon [label="gscon_handover_post_complete()"]; |
| ---; |
| ...; |
| ms => bsc_gscon [label="RR Handover Complete"]; |
| bsc_gscon box bsc_gscon [label="gscon_handover_post_complete()"]; |
| bsc_gscon note bsc_gscon [label="handover_end(success), conn->ho = NULL"]; |
| bsc_gscon abox bsc_gscon [label="ST_ACTIVE"]; |
| } |