/* uni30 - UNI 3.0 message format decription */

/* Written 1995 by Werner Almesberger, EPFL-LRC */


#define Q2931_PROTO_DSC 9

#define ITU_STD_HDR \
    _ext <1@8,more> = 1; \
    _cs <2@6,more> = 0; \
    _flag <1@5,more> = 0; \
    _action_ind <2@1> = 0; \
    _ie_len <16> = length

#define NET_STD_HDR \
    _ext <1@8,more> = 1; \
    _cs <2@6,more> = 3; \
    _flag <1@5,more> = 0; \
    _action_ind <2@1> = 0; \
    _ie_len <16> = length


def ie_aal = {
    ITU_STD_HDR {
	aal_type <8> = case {
	    5 {
		_id <8> = multi {
		    0x8c {
			fw_max_sdu <16>;
		    }
		    0x81 {
			bw_max_sdu <16>;
		    }
		    0x83 {
			aal_mode <8>;
		    }
		    0x84 {
			sscs_type <8>;
		    }
		}
	    }
	}
    }
}


def ie_ucr = {
    ITU_STD_HDR {
	_id <8> = multi {
	    0x82 {
		fw_pcr_0 <24>;
	    }
	    0x83 {
		bw_pcr_0 <24>;
	    }
	    0x84 {
		fw_pcr_01 <24>;
	    }
	    0x85 {
		bw_pcr_01 <24>;
	    }
	    0x88 {
		fw_scr_0 <24>;
	    }
	    0x89 {
		bw_scr_0 <24>;
	    }
	    0x90 {
		fw_scr_01 <24>;
	    }
	    0x91 {
		bw_scr_01 <24>;
	    }
	    0xa0 {
		fw_mbs_0 <24>;
	    }
	    0xa1 {
		bw_mbs_0 <24>;
	    }
	    0xb0 {
		fw_mbs_01 <24>;
	    }
	    0xb1 {
		bw_mbs_01 <24>;
	    }
	    0xbe {
		best_effort <0>;
	    }
	    0xbf {
		bw_tag <1@2,more>;
		fw_tag <1@1>;
	    }
	}
    }
}


def ie_bbcap = {
    ITU_STD_HDR {
	bearer_class <5@1,more>;
	_ext <1@8> = case {
	    0 {
		_ext <1@8,more> = 1;
		traf_type <3@3,more> = 0;
		tim_req <2@1> = 0;
	    }
	    default 1 {}
	}
	_ext <1@8,more> = 1;
	susc_clip <2@6,more> = 0;
	upcc <2@1> = 0;
    }
}


def ie_bhli = {
    ITU_STD_HDR {
	_ext <1@8,more> = 1;
	hli_type <7@1> = case {
	    0 { # ISO
		iso_hli <56>;
	    }
	    1 { # User Specific
		user_hli <56>;
	    }
	    2 { # High layer profile
		hlp <32>;
	    }
	    3 { # Vendor-Specific Application identifier
		hli_oui <24>;
		app_id <32>;
	    }
	}
    }
}


def ie_blli = {
    ITU_STD_HDR {
	_lid <2@6,more> = multi {
	    1 {
		_ext <1@8,more> = 1;
		uil1_proto <5@1>;
	    }
	    2 {
		uil2_proto <5@1,more> = case {
		    0x0e { # Q.922 - should be list of values or no value
			_ext <1@8> = case {
			    0 {
				l2_mode <2@6,more> = 1;
				q933 <2@1,more> = 0;
				_ext <1@8> = case {
				    0 {
					window_size <7@1,more>;
					_ext <1@8> = 1;
				    }
				    default 1 {}
				}
			    }
			    default 1 {}
			}
		    }
		    0x11 { # User specified
			_ext <1@8> = 1;
			user_l2 <7@1>;
		    }
		    default 0x0c { # LLC
			_ext <1@8> = 1;
		    }
		}
	    }
	    3 {
		uil3_proto <5@1,more> = case {
		    0x06 { # X.25, packet level - should be list
			_ext <1@8> = case {
			    0 {
				l3_mode <2@6,more> = 1;
				_ext <1@8> = case {
				    0 {
					def_pck_size <4@1>;
					_ext <1@8> = case {
					    0 {
						_ext <1@8> = 1;
						pck_win_size <7@1>;
					    }
					    default 1 {}
					}
				    }
				    default 1 {}
				}
			    }
			    default 1 {}
			}
		    }
		    0x0b { # ISO/IEC TR9577
			_ext <1@8> = case {
			    0 {
				_ext <1@8,more> = 0;
				ipi_high <7@1> = case {
				    0x40 { # SNAP hack
					_ext <1@8,more> = 1;
					_ipi_low <1@7> = case { # ugly
					    0 {
						_ext <1@8,more> = 1;
						_snap_id <2@6> = 0;
						oui <24>;
						pid <16>;
					    }
					    default 1 {}
					}
				    }
				    default 0x0 { # ugly
					_ext <1@8,more> = 1;
					ipi_low <1@7>;
				    }
				}
			    }
			    default 1 {}
			}
		    }
		    0x10 { # User specified
			_ext <1@8> = 1;
			user_l3 <7@1>;
		    }
		}
	    }
	}
    }
}


def ie_call_state = {
    ITU_STD_HDR {
	call_state <6@1>;
    }
}


def ie_cdpn = {
    ITU_STD_HDR {
	_ext <1@8,more> = 1;
	_plan <4@1,more> = case {
	    1 { # E.164
		_type <3@5> = 1;
		cdpn_e164 <-40>; # @@@ fix this
	    }
	    2 { # ATM Forum NSAP
		_type <3@5> = 0;
		cdpn_nsap <-160>;
	    }
	}
    }
}


def ie_cdps = {
    ITU_STD_HDR {
	_ext <1@8,more> = 1;
	_type <3@5,more> = 0;
	_oddeven <1@4> = 0;
	cdps <-160>;
    }
}


def ie_cgpn = { # @@@ extend language to allow same trick as for cdpn
    ITU_STD_HDR {
	cgpn_plan <4@1,more>;
	cgpn_type <2@6,more>;
	_ext <1@8> = case {
	    0 {
		_ext <1@8,more> = 1;
		pres_ind <2@6,more> = 0;
		scr_ind <2@1> = 0;
	    }
	    default 1 {}
	}
	cgpn <-160>;
    }
}


def ie_cgps = {
    ITU_STD_HDR {
	_ext <1@8,more> = 1;
	_type <3@5,more> = 0;
	_oddeven <1@4> = 0;
	cgps <-160>;
    }
}


def ie_cause = {
    ITU_STD_HDR {
	_ext <1@8,more> = 1;
	location <4@1>;
	_ext <1@8,more> = 1;
	cause <7@1>;
	diagnostic <-224>;
    }
}


def ie_conn_id = {
    ITU_STD_HDR {
	_ext <1@8,more> = 1;
	_vp_ass <2@4,more> = 1; /* explicit */
	_pref_exc <3@1> = 0;
	vpi <16>;
	vci <16>;
    }
}


def ie_qos = {
    NET_STD_HDR {
	qos_fw <8> = 0;
	qos_bw <8> = 0;
    }
}


def ie_bbrep = {
    ITU_STD_HDR {
	_ext <1@8,more> = 1;
	rep_ind <4@1> = 2;
    }
}


def ie_restart = {
    ITU_STD_HDR {
	_ext <1@8,more> = 1;
	rst_class <3@1>;
    }
}


def ie_bbs_comp = {
    ITU_STD_HDR {
	_ext <1@8,more> = 1;
	bbsc_ind <7@1> = 0x21;
    }
}


def ie_tns = {
    ITU_STD_HDR {
	_ext <1@8,more> = 1;
	_net_type <3@5,more> = 2;
	_carrier_id <4@1> = 1;
	net_id <-32>; # how many actually ?
    }
}


def ie_ep_ref = {
    ITU_STD_HDR {
	ep_ref <16>;
    }
}


def ie_ep_state = {
    ITU_STD_HDR {
	ep_state <6@1>;
    }
}


{
    _pdsc <8> = Q2931_PROTO_DSC;
    _cr_len <8> = 3;
    call_ref <24>;
    msg_type <8>;
    _ext <1@8,more> = 1;
    _flag <1@5,more> = 0; # Message instruction field not significant
    _action_ind <2@1> = 0;
    msg_len <16> = length {
	_ie_id <8> = multi {
	    aal:	0x58 ie_aal;
	    ucr:	0x59 ie_ucr;
	    bbcap:	0x5e ie_bbcap;
	    bhli:	0x5d ie_bhli;
	    blli:	0x5f ie_blli;
	    call_state:	0x14 ie_call_state;
	    cdpn:	0x70 ie_cdpn;
	    cdps:	0x71 ie_cdps;
	    cgpn:	0x6c ie_cgpn;
	    cgps:	0x6d ie_cgps;
	    cause:	0x08 ie_cause;
	    conn_id:	0x5a ie_conn_id;
	    qos:	0x5c ie_qos;
	    bbrep:	0x63 ie_bbrep;
	    restart:	0x79 ie_restart;
	    bbs_comp:	0x62 ie_bbs_comp;
	    tns:	0x78 ie_tns;
	    ep_ref:	0x58 ie_ep_ref;
	    ep_state:	0x55 ie_ep_state;
	}
    }
}
