# Handover between cells, intra-BSC
msc {
	hscale=2;
	ms [label="MS via BTS"], lchan[label="BSC lchan FSM"], ho[label="BSC Handover FSM"],
	gscon[label="BSC conn FSM"], msc_[label="MSC"];

	ms note msc_ [label="intra-BSC Handover"];

	gscon abox gscon [label="ST_ACTIVE"];

	ms => ho [label="Measurement Report"];
	ho box ho [label="Handover Decision"];
	ho box ho [label="handover_request\n(struct handover_out_req)"];
	ho note gscon [label="To make sure the conn FSM permits a handover, trigger an event:"];
	ho -> gscon [label="GSCON_EV_HANDOVER_START\ndata=handover_out_req"];
	gscon abox gscon [label="ST_HANDOVER"];
	ho <- gscon [label="handover_start\n(handover_out_req)"];
	ho box ho [label="handover_start_intra_bsc()"];
	ho abox ho [label="allocate\nHO_ST_NOT_STARTED"];

	...;
	...;
	--- [label="On any error or timeout"];
	ho box ho [label="handover_end(fail)"];
	ho -> gscon [label="GSCON_EV_HANDOVER_END"];
	gscon abox gscon [label="ST_ACTIVE"];
	ms note gscon [label="MS happily continues on the old lchan."];
	--- [label="END: 'On any error or timeout'"];
	...;
	...;

	ho box ho [label="lchan_select_by_type()"];
	ho abox ho [label="HO_ST_WAIT_\nLCHAN_ACTIVE"];
	lchan <- ho [label="lchan_activate(ACTIVATE_FOR_HANDOVER)"];
	lchan rbox lchan [label="(most details omitted, see lchan_fsm diagrams)"];

	...;
	...;
	--- [label="On lchan error or timeout"];
	lchan -> ho [label="HO_EV_LCHAN_ERROR"];
	ho rbox gscon [label="same as above"];
	--- [label="END: 'On lchan error or timeout'"];
	...;
	...;

	lchan abox lchan [label="LCHAN_ST_WAIT_ACTIV_ACK"];
	ms <= lchan [label="RSL Chan Activ"];
	...;
	ms => lchan [label="RSL Chan Activ ACK"];
	lchan -> ho [label="HO_EV_LCHAN_ACTIVE"];
	ho abox ho [label="HO_ST_WAIT_\nRR_HO_DETECT"];
	...;
	ms => ho [label="RR Handover Detect\nHO_EV_RR_HO_DETECT"];
	lchan note ho [label="At this point we should start to switch the MGW over to the new lchan.
		But this is not implemented yet, as was not before introducing these FSMs."];
	ho abox ho [label="HO_ST_WAIT_\nRR_HO_COMPLETE"];
	...;
	lchan note ho [label="The lchan FSM will continue with RSL and RTP while the HO FSM waits.
		HO_EV_LCHAN_ESTABLISHED means that both RSL and RTP are established.
		Usually, RTP will be done first, and the HO_EV_LCHAN_ESTABLISHED may be
		received even before HO_EV_RR_HO_COMPLETE.
		ho_fsm_wait_lchan_established_onenter() decides whether to wait or not."];
	...;
	ms => lchan [label="RSL EST IND"];
	lchan -> ho [label="HO_EV_LCHAN_ESTABLISHED",ID="(may come as early as this, or...)"];
	ms => ho [label="RR Handover Complete (from EST IND)\n HO_EV_RR_HO_COMPLETE"];
	ho abox ho [label="HO_ST_WAIT_\nLCHAN_ESTABLISHED"];
	...;
	lchan rbox lchan [label="when lchan FSM is done with setting up RTP"];
	lchan -> ho [label="HO_EV_LCHAN_ESTABLISHED",ID="(...may come only now)"];
	ho abox ho [label="HO_ST_WAIT_\nMGW_ENDPOINT_TO_MSC"];
	ho -> gscon [label="gscon_connect_mgw_to_msc()"];
	...;
	ho <- gscon [label="HO_EV_MSC_MGW_OK"];
	ho box ho [label="handover_end(OK)"];
	ho -> gscon [label="gscon_change_primary_lchan()"];
	lchan <- gscon [label="LCHAN_RTP_EV_ESTABLISHED"];
	ho -> gscon [label="GSCON_EV_HANDOVER_END"];
	gscon abox gscon [label="ST_ACTIVE"];
	ho box ho [label="detach from parent to not fire another meaningless GSCON_EV_HANDOVER_END"];
	ho abox ho [label="terminate"];
}
