| module SIMTRACE_Tests { |
| |
| import from General_Types all; |
| import from Osmocom_Types all; |
| import from Misc_Helpers all; |
| |
| import from USB_PortType all; |
| import from USB_Types all; |
| import from USB_Templates all; |
| import from USB_Component all; |
| import from USB_PortTypes all; |
| |
| import from SIMTRACE_Types all; |
| import from SIMTRACE_Templates all; |
| import from SIMTRACE_Emulation all; |
| |
| modulepar { |
| //USB_Device_Match mp_usb_dev_match := { vid_pid := { vid := '1d50'H, pid := '60e3'H} }; |
| USB_Device_Match mp_usb_dev_match := { vid_pid := { vid := '1d50'H, pid := '4004'H} }; |
| charstring mp_usb_path := "1-2.4.4"; |
| integer mp_usb_interface := 0; |
| } |
| |
| //private const integer NR_IF := 2; |
| |
| type component Test_CT { |
| var ST_Emulation_CT vc_ST; |
| port ST_USER_PT ST; |
| port ST_USER_PT ST_IRQ; |
| }; |
| |
| private template (value) USB_IF_Params ts_UsbPars_path(charstring path, uint8_t if_nr) := { |
| usb_dev_match := { |
| path := { |
| path := path |
| } |
| }, |
| usb_if_nr := if_nr |
| } |
| |
| function f_init(USB_IF_Params pars) runs on Test_CT { |
| vc_ST := ST_Emulation_CT.create("ST"); |
| map(vc_ST:USB, system:USB); |
| connect(vc_ST:INOUT, self:ST); |
| connect(vc_ST:IRQ, self:ST_IRQ); |
| vc_ST.start(SIMTRACE_Emulation.main(pars)); |
| } |
| |
| function f_drain() runs on Test_CT { |
| timer T := 0.1; |
| T.start; |
| alt { |
| [] ST.receive { |
| log("Drained msg from INOUT"); |
| repeat; |
| } |
| [] ST_IRQ.receive { |
| log("Drained msg from IRQ"); |
| repeat; |
| } |
| [] T.timeout { } |
| } |
| } |
| |
| |
| function f_xceive(template (value) SIMTRACE_PDU tx, template (present) SIMTRACE_PDU exp_rx) |
| runs on Test_CT return SIMTRACE_PDU { |
| var SIMTRACE_PDU rx; |
| timer T := 5.0; |
| |
| ST.send(tx); |
| T.start; |
| alt { |
| [] ST.receive(exp_rx) -> value rx { |
| T.stop; |
| } |
| [] T.timeout { |
| setverdict(fail, "Timeout waiting for ", exp_rx); |
| mtc.stop; |
| } |
| } |
| return rx; |
| } |
| |
| testcase TC_test() runs on Test_CT { |
| |
| var USB_IF_Params pars := valueof(ts_UsbPars_path(mp_usb_path, mp_usb_interface)); |
| f_init(pars); |
| f_drain(); |
| |
| /* Enable the use of the IRQ endpoint to report status updates */ |
| f_xceive(ts_SIMTRACE_CEMU_CONFIG(ts_FeatureFlags(true)), |
| tr_SIMTRACE_CEMU_CONFIG(tr_FeatureFlags(true))) |
| |
| /* Choose "remote" SIM */ |
| ST.send(ts_SIMTRACE_MODEM_SIM_SELECT(SIM_SELECT_REMOTE)); |
| /* Trigger modem reset pulse */ |
| ST.send(ts_SIMTRACE_MODEM_RESET); |
| |
| f_drain(); |
| |
| var SIMTRACE_PDU rx; |
| while (true) { |
| /* receive TPDU header */ |
| ST.receive(tr_SIMTRACE_CEMU_RX_DATA(tr_CardEmu_DataFlags(tpdu_hdr:=true), ?)) -> value rx; |
| var octetstring apdu_hdr := rx.payload.cardem_do_rxdata.data; |
| /* send PB and request further Rx (command bytes) */ |
| ST.send(ts_SIMTRACE_CEMU_TX_DATA(ts_CardEmu_DataFlags(pb_and_rx:=true), apdu_hdr[1])); |
| /* receive remaining data from reader */ |
| ST.receive(tr_SIMTRACE_CEMU_RX_DATA(tr_CardEmu_DataFlags(final:=true), ?)); |
| ST.send(ts_SIMTRACE_CEMU_TX_DATA(ts_CardEmu_DataFlags(pb_and_tx:=true), '9000'O)); |
| } |
| |
| f_sleep(100.0); |
| |
| |
| } |
| |
| /* Test how firmware reacts on overly-long message (OS#4429, OS#4428) */ |
| testcase TC_long_out() runs on Test_CT { |
| var USB_IF_Params pars := valueof(ts_UsbPars_path(mp_usb_path, mp_usb_interface)); |
| f_init(pars); |
| f_drain(); |
| |
| ST.send(ts_SIMTRACE_CEMU_TX_DATA(ts_CardEmu_DataFlags, f_rnd_octstring(300))); |
| f_sleep(5.0); |
| /* FIXME: how to verify the device did not reset itself? */ |
| } |
| |
| |
| /* flood the OUT endpoint with 1000 messages; much more than the firmware can handle */ |
| testcase TC_flood_out() runs on Test_CT { |
| var USB_IF_Params pars := valueof(ts_UsbPars_path(mp_usb_path, mp_usb_interface)); |
| f_init(pars); |
| f_drain(); |
| |
| var integer i; |
| for (i := 0; i < 1000; i := i+1) { |
| ST.send(ts_SIMTRACE_CEMU_TX_DATA(ts_CardEmu_DataFlags, f_rnd_octstring(10))); |
| } |
| f_sleep(5.0); |
| /* FIXME: how to verify the device is still responsive? */ |
| } |
| |
| |
| testcase TC_selftest() runs on Test_CT { |
| const octetstring c_cemu_sim_rem := '020200000000090001'O; |
| const octetstring c_cemu_rx := '010600000000130001000000050000A4000402'O; |
| /* 0106000000001300 |
| 01000000 |
| 0500 |
| 00A4000402 |
| */ |
| log(dec_SIMTRACE_PDU(c_cemu_rx)); |
| } |
| |
| |
| |
| |
| |
| |
| } |