Harald Welte | 0ee2297 | 2020-02-29 11:32:50 +0100 | [diff] [blame] | 1 | module SIMTRACE_Tests { |
| 2 | |
| 3 | import from General_Types all; |
| 4 | import from Osmocom_Types all; |
| 5 | import from Misc_Helpers all; |
| 6 | |
| 7 | import from USB_PortType all; |
| 8 | import from USB_Types all; |
| 9 | import from USB_Templates all; |
| 10 | import from USB_Component all; |
| 11 | import from USB_PortTypes all; |
| 12 | |
| 13 | import from SIMTRACE_Types all; |
| 14 | import from SIMTRACE_Templates all; |
| 15 | import from SIMTRACE_Emulation all; |
| 16 | |
| 17 | modulepar { |
| 18 | //USB_Device_Match mp_usb_dev_match := { vid_pid := { vid := '1d50'H, pid := '60e3'H} }; |
| 19 | USB_Device_Match mp_usb_dev_match := { vid_pid := { vid := '1d50'H, pid := '4004'H} }; |
| 20 | charstring mp_usb_path := "1-2.4.4"; |
| 21 | integer mp_usb_interface := 0; |
| 22 | } |
| 23 | |
| 24 | //private const integer NR_IF := 2; |
| 25 | |
| 26 | type component Test_CT { |
| 27 | var ST_Emulation_CT vc_ST; |
| 28 | port ST_USER_PT ST; |
| 29 | port ST_USER_PT ST_IRQ; |
| 30 | }; |
| 31 | |
| 32 | private template (value) USB_IF_Params ts_UsbPars_path(charstring path, uint8_t if_nr) := { |
| 33 | usb_dev_match := { |
| 34 | path := { |
| 35 | path := path |
| 36 | } |
| 37 | }, |
| 38 | usb_if_nr := if_nr |
| 39 | } |
| 40 | |
| 41 | function f_init(USB_IF_Params pars) runs on Test_CT { |
| 42 | vc_ST := ST_Emulation_CT.create("ST"); |
| 43 | map(vc_ST:USB, system:USB); |
| 44 | connect(vc_ST:INOUT, self:ST); |
| 45 | connect(vc_ST:IRQ, self:ST_IRQ); |
| 46 | vc_ST.start(SIMTRACE_Emulation.main(pars)); |
| 47 | } |
| 48 | |
| 49 | function f_drain() runs on Test_CT { |
| 50 | timer T := 0.1; |
| 51 | T.start; |
| 52 | alt { |
| 53 | [] ST.receive { |
| 54 | log("Drained msg from INOUT"); |
| 55 | repeat; |
| 56 | } |
| 57 | [] ST_IRQ.receive { |
| 58 | log("Drained msg from IRQ"); |
| 59 | repeat; |
| 60 | } |
| 61 | [] T.timeout { } |
| 62 | } |
| 63 | } |
| 64 | |
| 65 | |
| 66 | function f_xceive(template (value) SIMTRACE_PDU tx, template (present) SIMTRACE_PDU exp_rx) |
| 67 | runs on Test_CT return SIMTRACE_PDU { |
| 68 | var SIMTRACE_PDU rx; |
| 69 | timer T := 5.0; |
| 70 | |
| 71 | ST.send(tx); |
| 72 | T.start; |
| 73 | alt { |
| 74 | [] ST.receive(exp_rx) -> value rx { |
| 75 | T.stop; |
| 76 | } |
| 77 | [] T.timeout { |
| 78 | setverdict(fail, "Timeout waiting for ", exp_rx); |
| 79 | mtc.stop; |
| 80 | } |
| 81 | } |
| 82 | return rx; |
| 83 | } |
| 84 | |
| 85 | testcase TC_test() runs on Test_CT { |
| 86 | |
| 87 | var USB_IF_Params pars := valueof(ts_UsbPars_path(mp_usb_path, mp_usb_interface)); |
| 88 | f_init(pars); |
| 89 | f_drain(); |
| 90 | |
| 91 | /* Enable the use of the IRQ endpoint to report status updates */ |
| 92 | f_xceive(ts_SIMTRACE_CEMU_CONFIG(ts_FeatureFlags(true)), |
| 93 | tr_SIMTRACE_CEMU_CONFIG(tr_FeatureFlags(true))) |
| 94 | |
| 95 | /* Choose "remote" SIM */ |
| 96 | ST.send(ts_SIMTRACE_MODEM_SIM_SELECT(SIM_SELECT_REMOTE)); |
| 97 | /* Trigger modem reset pulse */ |
| 98 | ST.send(ts_SIMTRACE_MODEM_RESET); |
| 99 | |
| 100 | f_drain(); |
| 101 | |
| 102 | var SIMTRACE_PDU rx; |
| 103 | while (true) { |
| 104 | /* receive TPDU header */ |
| 105 | ST.receive(tr_SIMTRACE_CEMU_RX_DATA(tr_CardEmu_DataFlags(tpdu_hdr:=true), ?)) -> value rx; |
| 106 | var octetstring apdu_hdr := rx.payload.cardem_do_rxdata.data; |
| 107 | /* send PB and request further Rx (command bytes) */ |
| 108 | ST.send(ts_SIMTRACE_CEMU_TX_DATA(ts_CardEmu_DataFlags(pb_and_rx:=true), apdu_hdr[1])); |
| 109 | /* receive remaining data from reader */ |
| 110 | ST.receive(tr_SIMTRACE_CEMU_RX_DATA(tr_CardEmu_DataFlags(final:=true), ?)); |
| 111 | ST.send(ts_SIMTRACE_CEMU_TX_DATA(ts_CardEmu_DataFlags(pb_and_tx:=true), '9000'O)); |
| 112 | } |
| 113 | |
| 114 | f_sleep(100.0); |
| 115 | |
| 116 | |
| 117 | } |
| 118 | |
| 119 | /* Test how firmware reacts on overly-long message (OS#4429, OS#4428) */ |
| 120 | testcase TC_long_out() runs on Test_CT { |
| 121 | var USB_IF_Params pars := valueof(ts_UsbPars_path(mp_usb_path, mp_usb_interface)); |
| 122 | f_init(pars); |
| 123 | f_drain(); |
| 124 | |
| 125 | ST.send(ts_SIMTRACE_CEMU_TX_DATA(ts_CardEmu_DataFlags, f_rnd_octstring(300))); |
| 126 | f_sleep(5.0); |
| 127 | /* FIXME: how to verify the device did not reset itself? */ |
| 128 | } |
| 129 | |
| 130 | |
| 131 | /* flood the OUT endpoint with 1000 messages; much more than the firmware can handle */ |
| 132 | testcase TC_flood_out() runs on Test_CT { |
| 133 | var USB_IF_Params pars := valueof(ts_UsbPars_path(mp_usb_path, mp_usb_interface)); |
| 134 | f_init(pars); |
| 135 | f_drain(); |
| 136 | |
| 137 | var integer i; |
| 138 | for (i := 0; i < 1000; i := i+1) { |
| 139 | ST.send(ts_SIMTRACE_CEMU_TX_DATA(ts_CardEmu_DataFlags, f_rnd_octstring(10))); |
| 140 | } |
| 141 | f_sleep(5.0); |
| 142 | /* FIXME: how to verify the device is still responsive? */ |
| 143 | } |
| 144 | |
| 145 | |
| 146 | testcase TC_selftest() runs on Test_CT { |
| 147 | const octetstring c_cemu_sim_rem := '020200000000090001'O; |
| 148 | const octetstring c_cemu_rx := '010600000000130001000000050000A4000402'O; |
| 149 | /* 0106000000001300 |
| 150 | 01000000 |
| 151 | 0500 |
| 152 | 00A4000402 |
| 153 | */ |
| 154 | log(dec_SIMTRACE_PDU(c_cemu_rx)); |
| 155 | } |
| 156 | |
| 157 | |
| 158 | |
| 159 | |
| 160 | |
| 161 | |
| 162 | } |