module PCU_Tests_RAW_SNS { import from Osmocom_Types all; import from PCU_Tests all; import from PCU_Tests_RAW all; import from Osmocom_Gb_Types all; import from NS_CodecPort all; import from NS_Types all; /********************************************************************************** * Modern Gb/IP bring-up test cases using IP Sub-Network Service (SNS) **********************************************************************************/ /* perform inbound SNS-SIZE procedure */ function f_incoming_sns_size(template (omit) NsCause cause := omit, integer idx := 0) runs on RAW_NS_CT { log("f_incoming_sns_size(idx=", idx, ")"); var PDU_NS rx; /* expect one single SNS-SIZE with RESET flag; one remote v4 EP; no v6 EP */ rx := f_ns_exp(tr_SNS_SIZE(g_nsconfig[idx].nsei, rst_flag := true, max_nsvcs := 8, num_v4 := 4, num_v6 := omit), idx); NSCP[idx].send(t_NS_Send(g_ns_conn_id[idx], ts_SNS_SIZE_ACK(g_nsconfig[idx].nsei, cause))); } /* perform outbound SNS-SIZE procedure */ function f_outgoing_sns_size(template (omit) NsCause cause := omit, integer idx:= 0) runs on RAW_NS_CT { log("f_outgoing_sns_size(idx=", idx, ")"); var PDU_NS rx; NSCP[idx].send(t_NS_Send(g_ns_conn_id[idx], ts_SNS_SIZE(g_nsconfig[idx].nsei, rst_flag := true, max_nsvcs := 1, num_v4 := 1, num_v6 := omit) )); /* expect one single SNS-SIZE with RESET flag; one remote v4 EP; no v6 EP */ rx := f_ns_exp(tr_SNS_SIZE_ACK(g_nsconfig[idx].nsei, cause), idx); } /* perform inbound SNS-CONFIG procedure */ function f_incoming_sns_config(template (omit) NsCause cause := omit, integer idx := 0) runs on RAW_NS_CT { log("f_incoming_sns_config(idx=", idx, ")"); var PDU_NS rx; rx := f_ns_exp(tr_SNS_CONFIG(g_nsconfig[idx].nsei, end_flag := true, v4 := ?), idx); NSCP[idx].send(t_NS_Send(g_ns_conn_id[idx], ts_SNS_CONFIG_ACK(g_nsconfig[idx].nsei, cause))); } /* perform outbound SNS-CONFIG procedure */ function f_outgoing_sns_config(template (omit) NsCause cause := omit, integer idx := 0) runs on RAW_NS_CT { log("f_outgoing_sns_config(idx=", idx, ")"); var PDU_NS rx; var template (omit) IP4_Elements v4 := { ts_SNS_IPv4(g_nsconfig[idx].local_ip, g_nsconfig[idx].local_udp_port) } NSCP[idx].send(t_NS_Send(g_ns_conn_id[idx], ts_SNS_CONFIG(g_nsconfig[idx].nsei, true, v4))); rx := f_ns_exp(tr_SNS_CONFIG_ACK(g_nsconfig[idx].nsei, cause), idx); } /* perform outbound SNS-CONFIG procedure (separate endpoints: 1 for control, 1 for user */ function f_outgoing_sns_config_1c1u(template (omit) NsCause cause := omit, integer idx := 0) runs on RAW_NS_CT { log("f_outgoing_sns_config_1c1u(idx=", idx, ")"); var PDU_NS rx; var template (omit) IP4_Elements v4 := { ts_SNS_IPv4(g_nsconfig[0].local_ip, g_nsconfig[0].local_udp_port, 1, 0), ts_SNS_IPv4(g_nsconfig[1].local_ip, g_nsconfig[1].local_udp_port, 0, 1) }; NSCP[idx].send(t_NS_Send(g_ns_conn_id[idx], ts_SNS_CONFIG(g_nsconfig[idx].nsei, true, v4))); rx := f_ns_exp(tr_SNS_CONFIG_ACK(g_nsconfig[idx].nsei, cause), idx); } function f_outgoing_sns_add(integer idx_add, uint8_t w_sig := 1, uint8_t w_user := 1, integer idx := 0) runs on RAW_NS_CT { log("f_outgoing_sns_add(idx_add=", idx_add, ")"); var PDU_NS rx; var template (omit) IP4_Elements v4 := { ts_SNS_IPv4(g_nsconfig[idx_add].local_ip, g_nsconfig[idx_add].local_udp_port, w_sig, w_user) }; NSCP[idx].send(t_NS_Send(g_ns_conn_id[idx], ts_SNS_ADD(g_nsconfig[idx].nsei, 23, v4))); rx := f_ns_exp(tr_SNS_ACK(g_nsconfig[idx].nsei, 23, omit, v4)); } function f_outgoing_sns_del(integer idx_del, uint8_t w_sig := 1, uint8_t w_user := 1, integer idx := 0) runs on RAW_NS_CT { log("f_outgoing_sns_del(idx_del=", idx_del, ")"); var PDU_NS rx; var template (omit) IP4_Elements v4 := { ts_SNS_IPv4(g_nsconfig[idx_del].local_ip, g_nsconfig[idx_del].local_udp_port, w_sig, w_user) }; NSCP[idx].send(t_NS_Send(g_ns_conn_id[idx], ts_SNS_DEL(g_nsconfig[idx].nsei, 24, omit, v4))); rx := f_ns_exp(tr_SNS_ACK(g_nsconfig[idx].nsei, 24, omit, v4)); } function f_outgoing_sns_chg_weight(integer idx_chg, uint8_t w_sig, uint8_t w_user, integer idx := 0) runs on RAW_NS_CT { log("f_outgoing_sns_chg_weight(idx_chg=", idx_chg, ")"); var PDU_NS rx; var template (omit) IP4_Elements v4 := { ts_SNS_IPv4(g_nsconfig[idx_chg].local_ip, g_nsconfig[idx_chg].local_udp_port, w_sig, w_user) }; NSCP[idx].send(t_NS_Send(g_ns_conn_id[idx], ts_SNS_CHG_WEIGHT(g_nsconfig[idx].nsei, 25, v4))); rx := f_ns_exp(tr_SNS_ACK(g_nsconfig[idx].nsei, 25, omit, v4)); } /* PCU-originated SNS-SIZE: successful case */ testcase TC_sns_po_size_success() runs on RAW_Test_CT { f_init_ns_codec(); f_init_pcuif(); f_incoming_sns_size(); f_sleep(1.0); setverdict(pass); } /* PCU-originated SNS-SIZE: NACK from our side */ testcase TC_sns_po_size_nack() runs on RAW_Test_CT { f_init_ns_codec(); f_init_pcuif(); f_incoming_sns_size(NS_CAUSE_PROTOCOL_ERROR_UNSPEIFIED); /* FIXME: ensure we don't get a SNS-CONFIG */ /* FIXME: ensure we get re-transmitted SNS-SIZE attempts */ f_sleep(10.0); setverdict(pass); } /* PCU-originated SNS-CONFIG: successful case */ testcase TC_sns_po_config_success() runs on RAW_Test_CT { f_init_ns_codec(); f_init_pcuif(); f_incoming_sns_size(); f_incoming_sns_config(); f_sleep(1.0); setverdict(pass); } /* PCU-originated SNS-CONFIG: successful case */ testcase TC_sns_po_config_nack() runs on RAW_Test_CT { f_init_ns_codec(); f_init_pcuif(); f_incoming_sns_size(); f_incoming_sns_config(NS_CAUSE_PROTOCOL_ERROR_UNSPEIFIED); /* FIXME: ensure we get re-transmitted SNS-CONFIG attempts */ f_sleep(10.0); setverdict(pass); } /* SGSN-originated SNS-SIZE: successful case */ testcase TC_sns_so_config_success() runs on RAW_Test_CT { f_init_ns_codec(); f_init_pcuif(); f_incoming_sns_size(); f_incoming_sns_config(); f_outgoing_sns_config(); /* wait for one ALIVE cycle, then ACK any further ALIVE in the background */ as_rx_alive_tx_ack(oneshot := true); activate(as_rx_alive_tx_ack()); f_outgoing_ns_alive(); /* Expect BVC-RESET for signaling (0) and ptp BVCI */ as_rx_bvc_reset_tx_ack(0, oneshot := true); as_rx_bvc_reset_tx_ack(mp_gb_cfg.bvci, oneshot := true); as_rx_bvc_unblock_tx_ack(mp_gb_cfg.bvci, oneshot := true); /* wait for one FLOW-CONTROL BVC and then ACK any further in the future */ as_rx_bvc_fc_tx_ack(mp_gb_cfg.bvci, oneshot := true, idx := 1); activate(as_rx_bvc_fc_tx_ack(mp_gb_cfg.bvci, idx := 1)); setverdict(pass); } private function f_sns_bringup_1c1u() runs on RAW_Test_CT { /* Activate two NS codec ports */ f_init_ns_codec(); f_init_ns_codec(1); f_init_pcuif(); /* Perform Size + BSS-originated config */ f_incoming_sns_size(); f_incoming_sns_config(); /* perform SGSN-originated config using idx==0 for signalling and idx==1 for user traffic */ f_outgoing_sns_config_1c1u(); /* wait for one ALIVE cycle, then ACK any further ALIVE in the background * for both NS-VCs */ as_rx_alive_tx_ack(oneshot := true, idx := 0); activate(as_rx_alive_tx_ack(idx := 0)); as_rx_alive_tx_ack(oneshot := true, idx := 1); activate(as_rx_alive_tx_ack(idx := 1)); /* perform outgoing ALIVE procedure for both NS-VCs */ f_outgoing_ns_alive(0); f_outgoing_ns_alive(1); /* Expect BVC-RESET for signaling (0) and ptp BVCI */ as_rx_bvc_reset_tx_ack(0, oneshot := true); as_rx_bvc_reset_tx_ack(mp_gb_cfg.bvci, oneshot := true); /* Expect UNBLOCK for ptp BVCI on signaling NS-VC (idx==0) */ as_rx_bvc_unblock_tx_ack(mp_gb_cfg.bvci, oneshot := true); /* wait for one FLOW-CONTROL BVC and then ACK any further in the future. Flow * control happens on the p-t-p BVCI and hence on index 1 */ as_rx_bvc_fc_tx_ack(mp_gb_cfg.bvci, oneshot := true, idx := 1); activate(as_rx_bvc_fc_tx_ack(mp_gb_cfg.bvci, idx := 1)); } /* Test full IP-SNS bring-up with two NS-VCs, one sig-only and one user-only */ testcase TC_sns_1c1u() runs on RAW_Test_CT { f_sns_bringup_1c1u(); setverdict(pass); } /* Test adding new IP endpoints at runtime */ testcase TC_sns_add() runs on RAW_Test_CT { f_sns_bringup_1c1u(); /* crate another NS codec port on the tester side */ f_init_ns_codec(2); f_outgoing_sns_add(idx_add := 2, w_sig := 0, w_user := 1, idx := 0); /* wait for one ALIVE cycle, then ACK any further ALIVE in the background */ as_rx_alive_tx_ack(oneshot := true, idx := 2); activate(as_rx_alive_tx_ack(idx := 2)); f_outgoing_ns_alive(2); /* TODO: Should we expect FLOW-CONTROL BVC here too? */ setverdict(pass); } /* Test deleting IP endpoints at runtime */ testcase TC_sns_del() runs on RAW_Test_CT { f_sns_bringup_1c1u(); f_outgoing_sns_del(idx_del := 1, w_sig := 0, w_user := 1, idx := 0); /* FIXME: ensure we don't receive anything on just-deleted NS-VC anymore */ setverdict(pass); } /* Test changing weights at runtime */ testcase TC_sns_chg_weight() runs on RAW_Test_CT { f_sns_bringup_1c1u(); /* change w_user from 1 to 200 */ f_outgoing_sns_chg_weight(idx_chg := 1, w_sig := 0, w_user := 200, idx := 0); setverdict(pass); } control { execute( TC_sns_po_size_success() ); execute( TC_sns_po_size_nack() ); execute( TC_sns_po_config_success() ); execute( TC_sns_po_config_nack() ); execute( TC_sns_so_config_success() ); execute( TC_sns_1c1u() ); execute( TC_sns_add() ); execute( TC_sns_del() ); execute( TC_sns_chg_weight() ); } }