Harald Welte | f654332 | 2017-07-16 07:35:10 +0200 | [diff] [blame] | 1 | module L1CTL_Test { |
| 2 | import from GSM_Types all; |
| 3 | import from Osmocom_Types all; |
| 4 | import from L1CTL_Types all; |
Harald Welte | 52c713c | 2017-07-16 15:44:44 +0200 | [diff] [blame] | 5 | import from L1CTL_PortType all; |
Harald Welte | f654332 | 2017-07-16 07:35:10 +0200 | [diff] [blame] | 6 | |
| 7 | const octetstring c_ul_param_req := '1300000000000000001d0000'O; |
| 8 | const octetstring c_ul_data_req := '060a0128284018001d000103490615004001c0000000000000000000000000'O; |
| 9 | const octetstring c_ul_ccch_mode_req := '1000000002000000'O; |
| 10 | const octetstring c_ul_reset_req := '0d00000002000000'O; |
| 11 | const octetstring c_ul_dm_est_req := '050000002800000007000367000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005'O; |
| 12 | const octetstring c_ul_rach_req := '040000000000000012010008'O; |
| 13 | |
| 14 | const octetstring c_dl_data_ind := '03000000900003670015f5613f3f00002d063f0328e36712ead000002b2b2b2b2b2b2b2b2b2b2b'O; |
| 15 | |
| 16 | type component dummy_CT { |
Harald Welte | 52c713c | 2017-07-16 15:44:44 +0200 | [diff] [blame] | 17 | var charstring l1ctl_sock_path := "/tmp/osmocom_l2"; |
| 18 | port L1CTL_PT L1CTL; |
Harald Welte | f654332 | 2017-07-16 07:35:10 +0200 | [diff] [blame] | 19 | }; |
| 20 | |
Harald Welte | 66110f0 | 2017-07-16 21:05:18 +0200 | [diff] [blame^] | 21 | /* for generating RESET_REQ */ |
Harald Welte | 52c713c | 2017-07-16 15:44:44 +0200 | [diff] [blame] | 22 | template L1ctlUlMessage t_L1ctlResetReq(template L1ctlResetType rst_type) := { |
| 23 | header := t_L1ctlHeader(L1CTL_RESET_REQ), |
| 24 | ul_info := omit, |
| 25 | payload := { |
| 26 | reset_req := { |
| 27 | reset_type := rst_type, |
| 28 | padding := '000000'O |
| 29 | } |
| 30 | } |
| 31 | }; |
| 32 | |
Harald Welte | 66110f0 | 2017-07-16 21:05:18 +0200 | [diff] [blame^] | 33 | /* for generating FBSB_REQ */ |
| 34 | template L1ctlUlMessage t_L1CTL_FBSB_REQ(template Arfcn arfcn, template L1ctlFbsbFlags flags, uint8_t sync_info_idx, L1ctlCcchMode ccch_mode, GsmRxLev rxlev_exp) := { |
| 35 | header := t_L1ctlHeader(L1CTL_FBSB_REQ), |
| 36 | ul_info := omit, |
| 37 | payload := { |
| 38 | fbsb_req := { |
| 39 | arfcn := arfcn, |
| 40 | timeout_tdma_frames := 10, |
| 41 | freq_err_thresh1 := 10000, |
| 42 | freq_err_thresh2 := 800, |
| 43 | num_freqerr_avg := 3, |
| 44 | flags := flags, |
| 45 | sync_info_idx := sync_info_idx, |
| 46 | ccch_mode := ccch_mode, |
| 47 | rxlev_exp := rxlev_exp |
| 48 | } |
| 49 | } |
| 50 | }; |
| 51 | |
| 52 | /* for matching against incoming FBSB_CONF */ |
| 53 | template L1ctlDlMessage t_L1CTL_FBSB_CONF(template uint8_t result) := { |
| 54 | header := t_L1ctlHeader(L1CTL_FBSB_CONF), |
| 55 | dl_info := ?, |
| 56 | payload := { |
| 57 | fbsb_conf := { |
| 58 | initial_freq_err := ?, |
| 59 | result := result, |
| 60 | bsic := ? |
| 61 | } |
| 62 | } |
| 63 | }; |
| 64 | |
| 65 | template L1ctlUlMessage t_L1CTL_RACH_REQ(uint8_t ra, uint8_t combined, uint16_t offset) := { |
| 66 | header := t_L1ctlHeader(L1CTL_RACH_REQ), |
| 67 | ul_info := { |
| 68 | chan_nr := t_RslChanNr_RACH(0), |
| 69 | link_id := ts_RslLinkID_DCCH(0), |
| 70 | padding := '0000'O |
| 71 | }, |
| 72 | payload := { |
| 73 | rach_req := { |
| 74 | ra := ra, |
| 75 | combined := combined, |
| 76 | offset := offset |
| 77 | } |
| 78 | } |
| 79 | } |
| 80 | |
| 81 | template L1ctlUlMessage t_L1CTL_DM_EST_REQ(Arfcn arfcn, RslChannelNr chan_nr, GsmTsc tsc) := { |
| 82 | header := t_L1ctlHeader(L1CTL_DM_EST_REQ), |
| 83 | ul_info := { |
| 84 | chan_nr := chan_nr, |
| 85 | link_id := ts_RslLinkID_DCCH(0), |
| 86 | padding := '0000'O |
| 87 | }, |
| 88 | payload := { |
| 89 | dm_est_req := { |
| 90 | tsc := tsc, |
| 91 | h := 0, |
| 92 | arfcn := arfcn, |
| 93 | hopping := omit, |
| 94 | tch_mode := 0, |
| 95 | audio_mode := t_L1CTL_AudioModeNone |
| 96 | } |
| 97 | } |
| 98 | } |
| 99 | |
| 100 | template L1ctlUlMessage t_L1CTL_DM_REL_REQ(RslChannelNr chan_nr) := { |
| 101 | header := t_L1ctlHeader(L1CTL_DM_EST_REQ), |
| 102 | ul_info := { |
| 103 | chan_nr := chan_nr, |
| 104 | link_id := ts_RslLinkID_DCCH(0), |
| 105 | padding := '0000'O |
| 106 | }, |
| 107 | payload := { |
| 108 | other := ''O |
| 109 | } |
| 110 | } |
| 111 | |
| 112 | template L1ctlUlMessage t_L1CTL_DATA_REQ(template RslChannelNr chan_nr, template RslLinkId link_id, octetstring l2_data) := { |
| 113 | header := t_L1ctlHeader(L1CTL_DATA_REQ), |
| 114 | ul_info := { |
| 115 | chan_nr := chan_nr, |
| 116 | link_id := link_id, |
| 117 | padding := '0000'O |
| 118 | }, |
| 119 | payload := { |
| 120 | other := l2_data |
| 121 | } |
| 122 | } |
| 123 | |
| 124 | /* for matching against incoming RACH_CONF */ |
| 125 | template L1ctlDlMessage t_L1CTL_RACH_CONF := { |
| 126 | header := t_L1ctlHeader(L1CTL_RACH_CONF), |
| 127 | dl_info := ?, |
| 128 | payload := ? |
| 129 | }; |
| 130 | |
| 131 | /* for matching against incoming RACH_CONF */ |
| 132 | template L1ctlDlMessage t_L1CTL_DATA_IND(template RslChannelNr chan_nr) := { |
| 133 | header := t_L1ctlHeader(L1CTL_DATA_IND), |
| 134 | dl_info := { |
| 135 | chan_nr := chan_nr, |
| 136 | link_id := ?, |
| 137 | arfcn := ?, |
| 138 | frame_nr := ?, |
| 139 | rx_level := ?, |
| 140 | snr := ?, |
| 141 | num_biterr := ?, |
| 142 | fire_crc := ? |
| 143 | }, |
| 144 | payload := { |
| 145 | data_ind := ? |
| 146 | } |
| 147 | }; |
| 148 | |
Harald Welte | 52c713c | 2017-07-16 15:44:44 +0200 | [diff] [blame] | 149 | |
| 150 | function f_init() runs on dummy_CT { |
| 151 | map(self:L1CTL, system:L1CTL); |
| 152 | L1CTL.send(L1CTL_connect:{path:=l1ctl_sock_path}); |
| 153 | L1CTL.receive(L1CTL_connect_result:{result_code := SUCCESS, err:=omit}); |
Harald Welte | 66110f0 | 2017-07-16 21:05:18 +0200 | [diff] [blame^] | 154 | |
| 155 | L1CTL.send(t_L1ctlResetReq(L1CTL_RES_T_SCHED)); |
| 156 | L1CTL.receive; |
Harald Welte | 52c713c | 2017-07-16 15:44:44 +0200 | [diff] [blame] | 157 | } |
| 158 | |
Harald Welte | f654332 | 2017-07-16 07:35:10 +0200 | [diff] [blame] | 159 | testcase TC_si1() runs on dummy_CT { |
| 160 | log("L1CTL_PARAM_REQ: ", dec_L1ctlUlMessage(c_ul_param_req)); |
| 161 | log("L1CTL_DATA_REQ: ", dec_L1ctlUlMessage(c_ul_data_req)); |
| 162 | log("L1CTL_CCCH_MODE_REQ: ", dec_L1ctlUlMessage(c_ul_ccch_mode_req)); |
| 163 | log("L1CTL_RESET_REQ: ", dec_L1ctlUlMessage(c_ul_reset_req)); |
| 164 | log("L1CTL_DM_EST_REQ: ", dec_L1ctlUlMessage(c_ul_dm_est_req)); |
| 165 | log("L1CTL_RACH_REQ: ", dec_L1ctlUlMessage(c_ul_rach_req)); |
| 166 | log("L1CTL_DATA_IND: ", dec_L1ctlDlMessage(c_dl_data_ind)); |
| 167 | setverdict(pass); |
| 168 | } |
Harald Welte | 52c713c | 2017-07-16 15:44:44 +0200 | [diff] [blame] | 169 | |
Harald Welte | 66110f0 | 2017-07-16 21:05:18 +0200 | [diff] [blame^] | 170 | function f_L1CTL_FBSB(L1CTL_PT pt, Arfcn arfcn, L1ctlCcchMode ccch_mode := CCCH_MODE_COMBINED) { |
| 171 | timer T := 5.0; |
| 172 | pt.send(t_L1CTL_FBSB_REQ(arfcn, t_L1CTL_FBSB_F_ALL, 0, ccch_mode, 0)); |
| 173 | T.start |
| 174 | alt { |
| 175 | [] pt.receive(t_L1CTL_FBSB_CONF(0)) {}; |
| 176 | [] pt.receive { repeat; }; |
| 177 | [] T.timeout { setverdict(fail, "Timeout in FBSB") }; |
| 178 | } |
Harald Welte | 52c713c | 2017-07-16 15:44:44 +0200 | [diff] [blame] | 179 | } |
Harald Welte | 66110f0 | 2017-07-16 21:05:18 +0200 | [diff] [blame^] | 180 | |
| 181 | function f_L1CTL_RACH(L1CTL_PT pt, uint8_t ra, uint8_t combined := 1, uint16_t offset := 0) return GsmFrameNumber { |
| 182 | var L1ctlDlMessage rc; |
| 183 | var GsmFrameNumber fn; |
| 184 | timer T := 2.0; |
| 185 | T.start |
| 186 | pt.send(t_L1CTL_RACH_REQ(ra, 0, 0)) |
| 187 | alt { |
| 188 | [] pt.receive(t_L1CTL_RACH_CONF) -> value rc { fn := rc.dl_info.frame_nr }; |
| 189 | [] pt.receive { repeat; }; |
| 190 | [] T.timeout { setverdict(fail, "Timeout in RACH") }; |
| 191 | } |
| 192 | return fn; |
| 193 | } |
| 194 | |
| 195 | template GsmRrMessage t_RR_IMM_ASS(uint8_t ra, uint8_t fn) := { |
| 196 | header := t_RrHeader(IMMEDIATE_ASSIGNMENT, ?), |
| 197 | payload := { |
| 198 | imm_ass := { |
| 199 | ded_or_tbf := ?, |
| 200 | page_mode := ?, |
| 201 | chan_desc := ?, |
| 202 | pkt_chan_desc := omit, |
| 203 | req_ref := f_compute_ReqRef(ra, fn), |
| 204 | timing_advance := ?, |
| 205 | mobile_allocation := ? |
| 206 | } |
| 207 | } |
| 208 | }; |
| 209 | |
| 210 | function f_L1CTL_WAIT_IMM_ASS(L1CTL_PT pt, uint8_t ra, GsmFrameNumber rach_fn) return ImmediateAssignment { |
| 211 | var L1ctlDlMessage dl; |
| 212 | var GsmRrMessage rr; |
| 213 | timer T := 10.0; |
| 214 | T.start; |
| 215 | alt { |
| 216 | [] pt.receive(t_L1CTL_DATA_IND(t_RslChanNr_PCH_AGCH(0))) -> value dl { |
| 217 | rr := dec_GsmRrMessage(dl.payload.data_ind.payload); |
| 218 | log("PCH/AGCN DL RR: ", rr); |
| 219 | if (match(rr, t_RR_IMM_ASS(ra, rach_fn))) { |
| 220 | log("Received IMM.ASS for our RACH!"); |
| 221 | } else { |
| 222 | repeat; |
| 223 | } |
| 224 | }; |
| 225 | [] pt.receive { repeat }; |
| 226 | [] T.timeout { setverdict(fail, "Timeout waiting for IMM ASS") }; |
| 227 | } |
| 228 | T.stop; |
| 229 | return rr.payload.imm_ass; |
| 230 | } |
| 231 | |
| 232 | /* Send DM_EST_REQ from parameters derived from IMM ASS */ |
| 233 | function f_L1CTL_DM_EST_REQ_IA(L1CTL_PT pt, ImmediateAssignment imm_ass) { |
| 234 | pt.send(t_L1CTL_DM_EST_REQ({ false, imm_ass.chan_desc.arfcn }, imm_ass.chan_desc.chan_nr, imm_ass.chan_desc.tsc)); |
| 235 | } |
| 236 | |
| 237 | testcase TC_l1ctl() runs on dummy_CT { |
| 238 | var GsmFrameNumber rach_fn; |
| 239 | var uint8_t ra := 23; |
| 240 | var ImmediateAssignment imm_ass; |
| 241 | |
| 242 | f_init(); |
| 243 | /* send FB/SB req to sync to cell */ |
| 244 | f_L1CTL_FBSB(L1CTL, { false, 871 }, CCCH_MODE_COMBINED); |
| 245 | /* send RACH request and obtain FN at which it was sent */ |
| 246 | rach_fn := f_L1CTL_RACH(L1CTL, ra); |
| 247 | /* wait for receiving matching IMM ASS */ |
| 248 | imm_ass := f_L1CTL_WAIT_IMM_ASS(L1CTL, ra, rach_fn) |
| 249 | /* send DM_EST_REQ */ |
| 250 | f_L1CTL_DM_EST_REQ_IA(L1CTL, imm_ass); |
| 251 | |
| 252 | L1CTL.send(t_L1CTL_DATA_REQ(imm_ass.chan_desc.chan_nr, ts_RslLinkID_DCCH(0), '000102030405060708090a0b0c0d0e0f10111213141516'O)); |
| 253 | L1CTL.send(t_L1CTL_DATA_REQ(imm_ass.chan_desc.chan_nr, ts_RslLinkID_DCCH(0), '000102030405060708090a0b0c0d0e0f10111213141516'O)); |
| 254 | L1CTL.send(t_L1CTL_DATA_REQ(imm_ass.chan_desc.chan_nr, ts_RslLinkID_DCCH(0), '000102030405060708090a0b0c0d0e0f10111213141516'O)); |
| 255 | |
| 256 | L1CTL.send(t_L1CTL_DM_REL_REQ(imm_ass.chan_desc.chan_nr)); |
| 257 | |
| 258 | setverdict(pass); |
| 259 | } |
| 260 | |
Harald Welte | f654332 | 2017-07-16 07:35:10 +0200 | [diff] [blame] | 261 | control { |
| 262 | execute(TC_si1()); |
Harald Welte | 52c713c | 2017-07-16 15:44:44 +0200 | [diff] [blame] | 263 | execute(TC_l1ctl()); |
Harald Welte | f654332 | 2017-07-16 07:35:10 +0200 | [diff] [blame] | 264 | } |
| 265 | } |