msc {
	hscale=2;
	ms [label="MS/BTS"], lchan[label="BSC lchan FSM"], ass[label="BSC Assignment FSM"],
	gscon[label="BSC conn FSM"], msc_[label="MSC"];

	ms note msc_ [label="lchan allocation sequence for BSSMAP Assignment Request"];

	gscon <= msc_ [label="BSSMAP Assignment Request"];
	gscon note gscon [label="GSCON_EV_ASSIGNMENT_START\n data=struct assignment_request"];
	gscon abox gscon [label="ST_ASSIGNMENT"];
	ass <- gscon [label="assignment_fsm_start()"];
	|||;
	--- [label="IF current lchan supports requested channel mode (re-use)"];
	lchan <- ass [label="LCHAN_EV_REQUEST_MODE_MODIFY"];
	ass abox ass [label="ASSIGNMENT_ST_\nWAIT_LCHAN_ESTABLISHED"];
	ass rbox ass [label="see below"];

	|||;
	--- [label="ELSE: if current lchan does not support requested channel mode (establish new lchan)"];
	ass abox ass [label="ASSIGNMENT_ST_\nWAIT_LCHAN_ACTIVE"];

	|||;
	--- [label="On any error (no lchan, etc.)"];
	ass box ass [label="on_assignment_failure()"];
	ass => msc_ [label="BSSMAP Assignment Failure"];
	ass abox ass [label="terminate"];
	ass -> gscon [label="GSCON_EV_ASSIGNMENT_END"];
	gscon abox gscon [label="ST_ACTIVE"];
	---;
	|||;
	lchan abox lchan [label="UNUSED"];
	ass box ass [label="conn->assignment.new_lchan = lchan_select_by_chan_mode()"];
	lchan <- ass [label="lchan_activate(ACTIVATE_FOR_ASSIGNMENT)"];
	lchan abox lchan [label="WAIT_TS_READY"];
	lchan rbox lchan [label="most details omitted, see lchan_fsm and lchan_rtp_fsm diagrams"];
	...;
	|||;
	--- [label="on lchan FSM error or timeout"];
	lchan -> ass [label="ASSIGNMENT_EV_LCHAN_ERROR"];
	ass box ass [label="on_assignment_failure()"];
	ass rbox gscon [label="See 'On any error' above"];
	--- [label="END: 'on error'"];
	...;
	...;

	lchan abox lchan [label="LCHAN_ST_WAIT_ACTIV_ACK"];
	ms <= lchan [label="RSL Chan Activ"];
	...;
	ms => lchan [label="RSL Chan Activ ACK"];
	lchan -> ass [label="ASSIGNMENT_EV_LCHAN_ACTIVE"];
	ass abox ass [label="ASSIGNMENT_ST_\nWAIT_RR_ASS_COMPLETE"];
	ms <= ass [label="RR Assignment Command"];
	lchan note ass [label="The lchan FSM will continue with RSL and RTP while the Assignment FSM waits.
		ASSIGNMENT_EV_LCHAN_ESTABLISHED means that both RSL and RTP are established.
		Usually, RTP will be done first, and the ASSIGNMENT_EV_LCHAN_ESTABLISHED may be
		received even before ASSIGNMENT_EV_RR_ASSIGNMENT_COMPLETE.
		assignment_fsm_wait_lchan_established_onenter() decides whether to wait or not."];
	...;
	ms => lchan [label="RSL EST IND"];
	lchan -> ass [label="ASSIGNMENT_EV_LCHAN_ESTABLISHED",ID="(may come as early as this, or...)"];
	ms => ass [label="RR Assignment Complete (came with EST IND)"];
	ass abox ass [label="ASSIGNMENT_ST_\nWAIT_LCHAN_ESTABLISHED"];
	--- [label="IF lchan is not in LCHAN_ST_ESTABLISHED yet (waiting for RTP)"];
	...;
	lchan rbox lchan [label="when lchan RTP FSM is done with setting up RTP"];
	lchan -> ass [label="ASSIGNMENT_EV_LCHAN_ESTABLISHED",ID="(...may come only now)"];
	---;
	ass abox ass [label="ASSIGNMENT_ST_WAIT_\nMGW_ENDPOINT_TO_MSC"];
	ass -> gscon [label="gscon_connect_mgw_to_msc()"];
	...;
	ass <- gscon [label="ASSIGNMENT_EV_MSC_MGW_OK"];
	ass box ass [label="assignment_success()"];
	ass => msc_ [label="BSSMAP Assignment Complete"];
	ass -> gscon [label="gscon_change_primary_lchan()"];
	lchan <- gscon [label="LCHAN_RTP_EV_ESTABLISHED"];
	ass abox ass [label="terminate"];
	ass -> gscon [label="GSCON_EV_ASSIGNMENT_END"];
	gscon abox gscon [label="ST_ACTIVE"];

}
