module SIMTRACE_Templates {

import from SIMTRACE_Types all;
import from General_Types all;
import from Osmocom_Types all;

/* TTCN-3 templates Osmocom SIMTRACE2
 * as found in simtrace2.git/host/include/osmocom/simtrace2/simtrace_prot.h
 *
 * (C) 2020 by Harald Welte <laforge@gnumonks.org>
 */


/***********************************************************************
 * GENERAL
 ***********************************************************************/

template (value) SIMTRACE_PDU
ts_SIMTRACE(template (value) SIMTRACE_MsgClassType msg_type,
	    template (value) SIMTRACE_Payload payload) := {
	msg_type := msg_type,
	seq_nr := 0,
	slot_nr := 0,
	reserved := '0000'O,
	msg_len := 0, /* overwritten */
	payload := payload
}
template (present) SIMTRACE_PDU
tr_SIMTRACE(template (present) SIMTRACE_MsgClassType msg_type,
	    template (present) SIMTRACE_Payload payload) := {
	msg_type := msg_type,
	seq_nr := ?,
	slot_nr := ?,
	reserved := '0000'O,
	msg_len := ?,
	payload := payload
}

template (value) SIMTRACE_PDU ts_SIMTRACE_BOARD_INFO :=
	ts_SIMTRACE(SIMTRACE_CMD_BD_BOARD_INFO,
		{ gen_bd_board_info := {
			hardware := {
				manufacturer := "",
				model := "",
				version := ""
				},
			software := {
				provider := "",
				name := "",
				version := "",
				buildhost := "",
				crc := '00000000'O
				},
			max_baud_rate := 0,
			cap_generic_bytes := 0,
			cap_vendor_bytes := 0,
			cap_generic := omit,
			cap_vendor := omit
			}
		});
template (present) SIMTRACE_PDU
tr_SIMTRACE_BOARD_INFO(template (present) Board_Info_Hardware hw := ?,
		       template (present) Board_Info_Software sw := ?,
		       template Generic_Capability cap_gen := *,
		       template Generic_Capability_Vendor cap_vend := *) :=
	tr_SIMTRACE(SIMTRACE_CMD_BD_BOARD_INFO,
		{ gen_bd_board_info := {
			hardware := hw,
			software := sw,
			max_baud_rate := ?,
			cap_generic_bytes := ?,
			cap_vendor_bytes := ?,
			cap_generic := cap_gen,
			cap_vendor := cap_vend
			}
		});


/***********************************************************************
 * CARD EMULATION
 ***********************************************************************/

/* dummy flags for BD_STATUS [request] */
template (value) CardEmu_StatusFlags ts_CardEmu_StatusFlags := {
	reserved := '000'B,
	reset_active := false,
	card_insert := false,
	rcemu_active := false,
	clk_active := false,
	vcc_present := false,
	reserved2 := '000000000000000000000000'B
};
template (present) CardEmu_StatusFlags
tr_CardEmu_StatusFlags(template (present) boolean reset_active := ?,
		 	template (present) boolean card_insert := ?,
			template (present) boolean clk_active := ?,
			template (present) boolean vcc_present := ?,
			template (present) boolean rcemu_active := ?) := {
	reserved := ?,
	reset_active := reset_active,
	card_insert := card_insert,
	rcemu_active := rcemu_active,
	clk_active := clk_active,
	vcc_present := vcc_present,
	reserved2 := ?
};

template (value) CardEmu_DataFlags
ts_CardEmu_DataFlags(template (value) boolean pb_and_rx := false,
		     template (value) boolean pb_and_tx := false,
		     template (value) boolean final := false,
		     template (value) boolean tpdu_hdr := false) := {
	reserved := '0000'B,
	pb_and_rx := pb_and_rx,
	pb_and_tx := pb_and_tx,
	final := final,
	tpdu_hdr := tpdu_hdr,
	reserved2 := '000000000000000000000000'B
};
template (present) CardEmu_DataFlags
tr_CardEmu_DataFlags(template (present) boolean pb_and_rx := ?,
		     template (present) boolean pb_and_tx := ?,
		     template (present) boolean final := ?,
		     template (present) boolean tpdu_hdr := ?) := {
	reserved := ?,
	pb_and_rx := pb_and_rx,
	pb_and_tx := pb_and_tx,
	final := final,
	tpdu_hdr := tpdu_hdr,
	reserved2 := ?
};


template (value) SIMTRACE_PDU
	ts_SIMTRACE_CEMU_TX_DATA(template (value) CardEmu_DataFlags flags,
			   template (value) octetstring data) :=
ts_SIMTRACE(SIMTRACE_MSGT_DT_CEMU_TX_DATA,
	    { cardem_dt_txdata := {
		flags := flags,
		data_len := 0, /* overwritten */
		data := data }
	    });


template (value) SIMTRACE_PDU
ts_SIMTRACE_CEMU_SET_ATR(template (value) octetstring atr) :=
	ts_SIMTRACE(SIMTRACE_MSGT_DT_CEMU_SET_ATR,
		{ cardem_dt_setatr := { atr_len := 0 /* overwritten */, atr := atr } });


template (value) SIMTRACE_PDU
ts_SIMTRACE_CEMU_STATUS :=
	ts_SIMTRACE(SIMTRACE_MSGT_BD_CEMU_STATUS,
		{ cardem_bd_status := {
			flags := ts_CardEmu_StatusFlags,
			voltage_mv := 0, fi := 0, di := 0, wi := 0, waiting_time := 0
			}
		});

template (present) SIMTRACE_PDU
tr_SIMTRACE_CEMU_STATUS(template (present) CardEmu_StatusFlags flags := ?,
			template (present) uint16_t voltage_mv := ?,
			template (present) uint8_t fi := ?,
			template (present) uint8_t di := ?,
			template (present) uint8_t wi := ?,
			template (present) uint32_t waiting_time := ?) :=
	tr_SIMTRACE(SIMTRACE_MSGT_BD_CEMU_STATUS,
		{ cardem_bd_status := {
			flags := flags,
			voltage_mv := voltage_mv,
			fi := fi,
			di := di,
			wi := wi,
			waiting_time := waiting_time
		}});


template (value) SIMTRACE_PDU
ts_SIMTRACE_CEMU_CARDINSERT(uint8_t insert) :=
	ts_SIMTRACE(SIMTRACE_MSGT_DT_CEMU_CARDINSERT,
		{ cardem_dt_cardinsert := { card_insert := insert } });


template (present) SIMTRACE_PDU
tr_SIMTRACE_CEMU_RX_DATA(template (present) CardEmu_DataFlags flags,
			 template (present) octetstring data) :=
	tr_SIMTRACE(SIMTRACE_MSGT_DO_CEMU_RX_DATA,
		{ cardem_do_rxdata := {
			flags := flags,
			data_len := ?,
			data := data
			}
		});

template (present) SIMTRACE_PDU
tr_SIMTRACE_CEMU_PTS(template (present) octetstring req, template (present) octetstring resp) :=
	tr_SIMTRACE(SIMTRACE_MSGT_DO_CEMU_PTS,
		{ cardem_do_pts := {
			pts_len := ?,
			req := req,
			resp := resp
			}
		});

template (value) CardEmu_FeatureFlags ts_FeatureFlags(boolean status_irq) := {
	reserved := '0000000'B,
	status_irq := status_irq,
	reserved2 := '000000000000000000000000'B
}
template (present) CardEmu_FeatureFlags tr_FeatureFlags(template (present) boolean status_irq := ?) := {
	reserved := '0000000'B,
	status_irq := status_irq,
	reserved2 := '000000000000000000000000'B
}


template (value) SIMTRACE_PDU
ts_SIMTRACE_CEMU_CONFIG(template (value) CardEmu_FeatureFlags flags) :=
	ts_SIMTRACE(SIMTRACE_MSGT_BD_CEMU_CONFIG, { cardem_bd_config := { features := flags,
									  slot_mux_nr := 0} });

template (present) SIMTRACE_PDU
tr_SIMTRACE_CEMU_CONFIG(template (present) CardEmu_FeatureFlags flags) :=
	tr_SIMTRACE(SIMTRACE_MSGT_BD_CEMU_CONFIG, { cardem_bd_config := { features := flags,
									  slot_mux_nr := * } });


/***********************************************************************
 * MODEM CONTROL
 ***********************************************************************/

template (value) Modem_Status ts_ModemStatus(boolean card_inserted, boolean wwan_led) := {
	reserved := '000000'B,
	card_inserted := card_inserted,
	wwan_led := wwan_led
}
template (present) Modem_Status tr_ModemStatus(template (present) boolean card_inserted,
					       template (present) boolean wwan_led) := {
	reserved := ?,
	card_inserted := card_inserted,
	wwan_led := wwan_led
}



template (value) SIMTRACE_PDU
ts_SIMTRACE_MODEM_RESET(ModemResetType rst_type := MODEM_RESET_PULSE,
			uint16_t duration_msec := 400) :=
	ts_SIMTRACE(SIMTRACE_MSGT_DT_MODEM_RESET,
		{ modem_dt_reset := {
			asserted := rst_type,
			pulse_duration_msec := duration_msec
			}
		});

template (value) SIMTRACE_PDU
ts_SIMTRACE_MODEM_SIM_SELECT(SimSelect sim_sel) :=
	ts_SIMTRACE(SIMTRACE_MSGT_DT_MODEM_SIM_SELECT,
		{ modem_dt_sim_select := {
			sim_select := sim_sel
			}
		});

template (value) SIMTRACE_PDU
ts_SIMTRACE_MODEM_STATUS :=
	ts_SIMTRACE(SIMTRACE_MSGT_BD_MODEM_STATUS,
		{ modem_bd_status := {
			supported := ts_ModemStatus(false, false),
			status := ts_ModemStatus(false, false),
			changed := ts_ModemStatus(false, false)
			}
		});
template (present) SIMTRACE_PDU
tr_SIMTRACE_MODEM_STATUS(template (present) Modem_Status supported := ?,
			 template (present) Modem_Status status := ?,
			 template (present) Modem_Status changed := ?) :=
	tr_SIMTRACE(SIMTRACE_MSGT_BD_MODEM_STATUS,
		{ modem_bd_status := {
			supported := supported,
			status := status,
			changed := changed
			}
		});


/***********************************************************************
 * SNIFFER
 ***********************************************************************/

template (present) SIMTRACE_PDU
tr_SIMTRACE_SNIFF_CHANGE(template (present) Sniff_Flags flags) :=
	tr_SIMTRACE(SIMTRACE_MSGT_SNIFF_CHANGE,
		{ sniff_do_change := { flags := flags } });

template (present) SIMTRACE_PDU
tr_SIMTRACE_SNIFF_FIDI(template (present) uint8_t fidi := ?) :=
	tr_SIMTRACE(SIMTRACE_MSGT_SNIFF_FIDI,
		{ sniff_do_fidi := { fidi := fidi } });

template (present) SIMTRACE_PDU
tr_SIMTRACE_SNIFF_ATR(template (present) octetstring data,
		      template (present) Sniff_Flags flags := ?) :=
	tr_SIMTRACE(SIMTRACE_MSGT_SNIFF_FIDI,
		{ sniff_do_atr := {
			flags := flags,
			data_len := ?,
			data := data
			}
		});

template (present) SIMTRACE_PDU
tr_SIMTRACE_SNIFF_PPS(template (present) octetstring data,
		      template (present) Sniff_Flags flags := ?) :=
	tr_SIMTRACE(SIMTRACE_MSGT_SNIFF_PPS,
		{ sniff_do_atr := {
			flags := flags,
			data_len := ?,
			data := data
			}
		});

template (present) SIMTRACE_PDU
tr_SIMTRACE_SNIFF_TPDU(template (present) octetstring data,
		       template (present) Sniff_Flags flags := ?) :=
	tr_SIMTRACE(SIMTRACE_MSGT_SNIFF_TPDU,
		{ sniff_do_atr := {
			flags := flags,
			data_len := ?,
			data := data
			}
		});



}
