module L1CTL_Test { import from GSM_Types all; import from Osmocom_Types all; import from L1CTL_Types all; import from L1CTL_PortType all; import from LAPDm_Types all; const octetstring c_ul_param_req := '1300000000000000001d0000'O; const octetstring c_ul_data_req := '060a0128284018001d000103490615004001c0000000000000000000000000'O; const octetstring c_ul_ccch_mode_req := '1000000002000000'O; const octetstring c_ul_reset_req := '0d00000002000000'O; const octetstring c_ul_dm_est_req := '050000002800000007000367000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005'O; const octetstring c_ul_rach_req := '040000000000000012010008'O; const octetstring c_dl_data_ind := '03000000900003670015f5613f3f00002d063f0328e36712ead000002b2b2b2b2b2b2b2b2b2b2b'O; type component dummy_CT { var charstring l1ctl_sock_path := "/tmp/osmocom_l2"; port L1CTL_PT L1CTL; var ChannelDescription chan_desc; }; function f_init() runs on dummy_CT { map(self:L1CTL, system:L1CTL); L1CTL.send(L1CTL_connect:{path:=l1ctl_sock_path}); L1CTL.receive(L1CTL_connect_result:{result_code := SUCCESS, err:=omit}); L1CTL.send(t_L1ctlResetReq(L1CTL_RES_T_SCHED)); L1CTL.receive; } /* a very ppor man's job to check if we can actually still decode the L1CTL binary messages */ testcase TC_selftest() runs on dummy_CT { log("L1CTL_PARAM_REQ: ", dec_L1ctlUlMessage(c_ul_param_req)); log("L1CTL_DATA_REQ: ", dec_L1ctlUlMessage(c_ul_data_req)); log("L1CTL_CCCH_MODE_REQ: ", dec_L1ctlUlMessage(c_ul_ccch_mode_req)); log("L1CTL_RESET_REQ: ", dec_L1ctlUlMessage(c_ul_reset_req)); log("L1CTL_DM_EST_REQ: ", dec_L1ctlUlMessage(c_ul_dm_est_req)); log("L1CTL_RACH_REQ: ", dec_L1ctlUlMessage(c_ul_rach_req)); log("L1CTL_DATA_IND: ", dec_L1ctlDlMessage(c_dl_data_ind)); setverdict(pass); } /* master function establishing a dedicated radio channel */ function f_establish_dcch() runs on dummy_CT { var ImmediateAssignment imm_ass; var GsmFrameNumber rach_fn; var uint8_t ra := 23; /* send FB/SB req to sync to cell */ f_L1CTL_FBSB(L1CTL, { false, 871 }, CCCH_MODE_COMBINED); /* send RACH request and obtain FN at which it was sent */ rach_fn := f_L1CTL_RACH(L1CTL, ra); /* wait for receiving matching IMM ASS */ imm_ass := f_L1CTL_WAIT_IMM_ASS(L1CTL, ra, rach_fn) /* send DM_EST_REQ */ f_L1CTL_DM_EST_REQ_IA(L1CTL, imm_ass); chan_desc := imm_ass.chan_desc; } /* send some data over an established dedicated radio channel */ function f_send_l2(template RslLinkId link_id, octetstring l2_data) runs on dummy_CT { L1CTL.send(t_L1CTL_DATA_REQ(chan_desc.chan_nr, link_id, l2_data)); } /* send some data over an established dedicated radio channel */ function f_send_l2_lapdm_b(template RslLinkId link_id, template LapdmFrameB b) runs on dummy_CT { var octetstring l2_data := enc_LapdmFrameB(valueof(b)); L1CTL.send(t_L1CTL_DATA_REQ(chan_desc.chan_nr, link_id, l2_data)); } function f_recv_l2() runs on dummy_CT return octetstring { var L1ctlDlMessage dl; var octetstring l2_data; timer T := 5.0; T.start alt { [] L1CTL.receive(t_L1CTL_DATA_IND(chan_desc.chan_nr)) -> value dl { l2_data := dl.payload.data_ind.payload }; [] L1CTL.receive { repeat; }; [] T.timeout { setverdict(fail, "Timeout waiting for DL data"); }; } return l2_data; } /* release the dedicated radio channel */ function f_release_dcch() runs on dummy_CT { L1CTL.send(t_L1CTL_DM_REL_REQ(chan_desc.chan_nr)); } template LapdmFrameB LAPDm_SABM(template GsmSapi sapi, template octetstring payload) := { addr := tr_LapdmAddr(sapi, false), ctrl := t_LapdmCtrlSABM(true), len := t_LapdmLengthIndicator(lengthof(payload)), payload := payload } testcase TC_l1ctl() runs on dummy_CT { f_init(); f_establish_dcch(); f_send_l2_lapdm_b(ts_RslLinkID_DCCH(0), LAPDm_SABM(0, 'FEFE'O)); f_recv_l2(); //f_send_l2(ts_RslLinkID_DCCH(0), '000102030405060708090a0b0c0d0e0f10111213141516'O); f_release_dcch(); setverdict(pass); } control { execute(TC_selftest()); execute(TC_l1ctl()); } }