Pau Espin Pedrol | 4ff118a | 2022-07-28 17:37:47 +0200 | [diff] [blame] | 1 | /* BSC (CBSP) Connection Handler of CBC test suite in TTCN-3 |
| 2 | * (C) 2022 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> |
| 3 | * All rights reserved. |
| 4 | * |
| 5 | * Author: Pau Espin Pedrol <pespin@sysmocom.de> |
| 6 | * |
| 7 | * Released under the terms of GNU General Public License, Version 2 or |
| 8 | * (at your option) any later version. |
| 9 | * |
| 10 | * SPDX-License-Identifier: GPL-2.0-or-later |
| 11 | */ |
| 12 | |
| 13 | module BSC_ConnectionHandler { |
| 14 | |
| 15 | import from Osmocom_Types all; |
| 16 | |
| 17 | import from BSSAP_Types all; |
| 18 | import from BSSMAP_Templates all; |
| 19 | import from CBSP_Types all; |
| 20 | import from CBSP_Templates all; |
| 21 | import from CBSP_Adapter all; |
| 22 | import from CBSP_CodecPort all; |
| 23 | |
| 24 | import from CBS_Message all; |
| 25 | |
| 26 | type function void_fn() runs on BSC_ConnHdlr; |
| 27 | |
Pau Espin Pedrol | db247f8 | 2022-08-01 17:55:22 +0200 | [diff] [blame] | 28 | /* Coordinate with test_CT: */ |
| 29 | type port BSC_ConnHdlr_Coord_PT message { |
| 30 | inout charstring; |
| 31 | } with { extension "internal" }; |
| 32 | |
Pau Espin Pedrol | 4ff118a | 2022-07-28 17:37:47 +0200 | [diff] [blame] | 33 | /* this component represents a single subscriber connection */ |
| 34 | type component BSC_ConnHdlr extends CBSP_Adapter_CT { |
| 35 | var BSC_ConnHdlrPars g_pars; |
Pau Espin Pedrol | db247f8 | 2022-08-01 17:55:22 +0200 | [diff] [blame] | 36 | port BSC_ConnHdlr_Coord_PT COORD; |
Pau Espin Pedrol | 4ff118a | 2022-07-28 17:37:47 +0200 | [diff] [blame] | 37 | } |
| 38 | |
| 39 | type record BSC_ConnHdlrPars { |
Pau Espin Pedrol | db247f8 | 2022-08-01 17:55:22 +0200 | [diff] [blame] | 40 | charstring bsc_host, |
Pau Espin Pedrol | 4ff118a | 2022-07-28 17:37:47 +0200 | [diff] [blame] | 41 | integer bsc_cbsp_port, |
| 42 | charstring cbc_host, |
| 43 | integer cbc_cbsp_port, |
Pau Espin Pedrol | db247f8 | 2022-08-01 17:55:22 +0200 | [diff] [blame] | 44 | boolean tcp_is_client, |
Pau Espin Pedrol | 4ff118a | 2022-07-28 17:37:47 +0200 | [diff] [blame] | 45 | void_fn start_fn, |
| 46 | CBS_Message exp_cbs_msg optional, |
| 47 | BSSMAP_FIELD_CellIdentificationList cell_list_success optional |
| 48 | }; |
| 49 | |
| 50 | function f_BSC_ConnHdlr_main(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr { |
| 51 | g_pars := pars; |
Pau Espin Pedrol | db247f8 | 2022-08-01 17:55:22 +0200 | [diff] [blame] | 52 | if (g_pars.tcp_is_client) { |
| 53 | CBSP_Adapter.f_connect(g_pars.cbc_host, g_pars.cbc_cbsp_port, |
| 54 | g_pars.bsc_host, g_pars.bsc_cbsp_port); |
| 55 | } else { |
| 56 | CBSP_Adapter.f_bind(g_pars.bsc_host, g_pars.bsc_cbsp_port); |
| 57 | CBSP_Adapter.f_wait_client_connect(); |
| 58 | } |
Pau Espin Pedrol | 4ff118a | 2022-07-28 17:37:47 +0200 | [diff] [blame] | 59 | |
| 60 | var BSSMAP_FIELD_CellIdentificationList cell_list := { |
| 61 | cIl_allInBSS := ''O |
| 62 | }; |
| 63 | activate(as_cbsp_keepalive_ack(0)); |
| 64 | activate(as_cbsp_restart(0)); |
| 65 | f_cbsp_send(ts_CBSP_RESTART(cell_list, CBSP_BC_MSGT_CBS, CBSP_RI_DATA_LOST)); |
| 66 | f_cbsp_send(ts_CBSP_RESTART(cell_list, CBSP_BC_MSGT_EMERG, CBSP_RI_DATA_LOST)); |
| 67 | as_cbsp_reset(0); |
Pau Espin Pedrol | db247f8 | 2022-08-01 17:55:22 +0200 | [diff] [blame] | 68 | COORD.send(COORD_MSG_CONNECTED); |
Pau Espin Pedrol | 4ff118a | 2022-07-28 17:37:47 +0200 | [diff] [blame] | 69 | |
| 70 | g_pars.start_fn.apply(); |
| 71 | } |
| 72 | |
| 73 | altstep as_cbsp_reset(integer idx) runs on CBSP_Adapter_CT { |
| 74 | var CBSP_RecvFrom rf; |
| 75 | [] CBSP[idx].receive(tr_CBSP_Recv(g_cbsp_conn_id[idx], tr_CBSP_RESET)) -> value rf { |
| 76 | var CBSP_IE ie; |
| 77 | f_cbsp_find_ie(rf.msg, CBSP_IEI_CELL_LIST, ie); |
| 78 | CBSP[idx].send(ts_CBSP_Send(g_cbsp_conn_id[idx], |
| 79 | ts_CBSP_RESET_COMPL(ie.body.cell_list.cell_id))); |
| 80 | } |
| 81 | } |
| 82 | |
| 83 | /* receive + acknowledge KEEP-ALIVE */ |
| 84 | altstep as_cbsp_keepalive_ack(integer idx) runs on CBSP_Adapter_CT { |
| 85 | [] CBSP[idx].receive(tr_CBSP_Recv(g_cbsp_conn_id[idx], tr_CBSP_KEEP_ALIVE)) { |
| 86 | CBSP[idx].send(ts_CBSP_Send(g_cbsp_conn_id[idx], ts_CBSP_KEEP_ALIVE_COMPL)); |
| 87 | } |
| 88 | } |
| 89 | |
| 90 | /* receive + ignore RESTART */ |
| 91 | altstep as_cbsp_restart(integer idx) runs on CBSP_Adapter_CT { |
| 92 | [] CBSP[idx].receive(tr_CBSP_Recv(g_cbsp_conn_id[idx], tr_CBSP_RESTART)); |
| 93 | } |
| 94 | |
| 95 | function f_cbsp_tx_write_compl(CBS_Message msg, integer idx := 0, |
| 96 | template (omit) BSSMAP_FIELD_CellIdentificationList tx_cell_list := omit, |
| 97 | template (omit) CBSP_IE_NumBcastComplList tx_compl_list := omit) |
| 98 | runs on BSC_ConnHdlr { |
| 99 | var template (value) CBSP_PDU tx; |
| 100 | var template (value) BSSMAP_FIELD_CellIdentificationList tx_list; |
| 101 | if (istemplatekind(tx_cell_list, "omit")) { |
| 102 | /* use the "expected list" when confirming the write-replace */ |
| 103 | tx_list := msg.cell_list; |
| 104 | } else { |
| 105 | /* use an user-provided different list of cells */ |
| 106 | tx_list := valueof(tx_cell_list); |
| 107 | } |
| 108 | if (istemplatekind(tx_compl_list, "omit")) { |
| 109 | tx := ts_CBSP_WRITE_CBS_COMPL(msg.msg_id, msg.ser_nr, tx_list, msg.channel_ind); |
| 110 | } else { |
| 111 | tx := ts_CBSP_REPLACE_CBS_COMPL(msg.msg_id, msg.ser_nr, msg.old_ser_nr, |
| 112 | valueof(tx_compl_list), tx_list, |
| 113 | msg.channel_ind); |
| 114 | } |
| 115 | CBSP[idx].send(ts_CBSP_Send(g_cbsp_conn_id[idx], tx)); |
| 116 | } |
| 117 | |
| 118 | function f_cbsp_tx_write_fail(CBS_Message msg, integer idx := 0, |
| 119 | template (omit) BSSMAP_FIELD_CellIdentificationList tx_cell_list := omit, |
| 120 | template (omit) CBSP_FailureListItems tx_fail_list := omit) |
| 121 | runs on BSC_ConnHdlr { |
| 122 | var template (value) CBSP_PDU tx; |
| 123 | tx := ts_CBSP_WRITE_CBS_FAIL(msg.msg_id, msg.ser_nr, valueof(tx_fail_list), |
| 124 | omit, tx_cell_list, msg.channel_ind); |
| 125 | CBSP[idx].send(ts_CBSP_Send(g_cbsp_conn_id[idx], tx)); |
| 126 | } |
| 127 | |
| 128 | /* handle a CBSP-WRITE-REPLACE and respond to it with COMPLETE or FAILURE depending on arguments */ |
| 129 | function f_cbsp_handle_write(CBS_Message msg, integer idx := 0, |
| 130 | template (omit) BSSMAP_FIELD_CellIdentificationList tx_cell_list := omit, |
| 131 | template (omit) CBSP_FailureListItems tx_fail_list := omit, |
| 132 | template (omit) CBSP_IE_NumBcastComplList tx_compl_list := omit) |
| 133 | runs on BSC_ConnHdlr { |
| 134 | var template CBSP_IEs content_ies := {}; |
| 135 | var template (present) CBSP_PDU rx_templ; |
| 136 | var CBSP_RecvFrom rf; |
| 137 | for (var integer i := 0; i < lengthof(msg.content); i := i+1) { |
| 138 | //content_ies[i] := tr_CbspMsgContent(msg.content[i].payload, msg.content[i].user_len); |
| 139 | content_ies[i] := tr_CbspMsgContent(?, ?); |
| 140 | } |
| 141 | rx_templ := tr_CBSP_WRITE_CBS(msg.msg_id, msg.ser_nr, msg.cell_list, msg.channel_ind, |
| 142 | msg.category, msg.rep_period, msg.num_bcast_req, msg.dcs, |
| 143 | content_ies); |
| 144 | alt { |
| 145 | [] CBSP[idx].receive(tr_CBSP_Recv(g_cbsp_conn_id[idx], rx_templ)) -> value rf { |
| 146 | var template (value) CBSP_PDU tx; |
| 147 | if (istemplatekind(tx_fail_list, "omit")) { |
| 148 | f_cbsp_tx_write_compl(msg, idx, tx_cell_list, tx_compl_list); |
| 149 | } else { |
| 150 | f_cbsp_tx_write_fail(msg, idx, tx_cell_list, tx_fail_list); |
| 151 | } |
| 152 | } |
| 153 | [] as_cbsp_keepalive_ack(idx) { repeat; } |
| 154 | [] CBSP[idx].receive { |
| 155 | setverdict(fail, "Received unexpected CBSP in index ", idx); |
| 156 | } |
| 157 | } |
| 158 | } |
| 159 | |
| 160 | /* handle a CBSP-KILL and respond to it with COMPLETE or FAILURE depending on arguments */ |
| 161 | function f_cbsp_handle_kill(integer idx, uint16_t msg_id, uint16_t ser_nr, |
| 162 | template BSSMAP_FIELD_CellIdentificationList exp_list, |
| 163 | template (omit) BSSMAP_FIELD_CellIdentificationList tx_list, |
| 164 | template (omit) CBSP_FailureListItems tx_fail_list := omit, |
| 165 | template (omit) CBSP_IE_NumBcastComplList tx_compl_list := omit, |
| 166 | template (omit) uint8_t channel_ind := omit) |
| 167 | runs on BSC_ConnHdlr { |
| 168 | var template (present) CBSP_PDU rx_templ; |
| 169 | var CBSP_RecvFrom rf; |
| 170 | |
| 171 | rx_templ := tr_CBSP_KILL(msg_id, ser_nr, exp_list, channel_ind); |
| 172 | alt { |
| 173 | [] CBSP[idx].receive(tr_CBSP_Recv(g_cbsp_conn_id[idx], rx_templ)) -> value rf { |
| 174 | var template (value) CBSP_PDU tx; |
| 175 | if (istemplatekind(tx_fail_list, "omit")) { |
| 176 | tx := ts_CBSP_KILL_COMPL(msg_id, ser_nr, tx_compl_list, tx_list, channel_ind); |
| 177 | } else { |
| 178 | tx := ts_CBSP_KILL_FAIL(msg_id, ser_nr, valueof(tx_fail_list), tx_compl_list, |
| 179 | tx_list, channel_ind); |
| 180 | } |
| 181 | CBSP[idx].send(ts_CBSP_Send(g_cbsp_conn_id[idx], tx)); |
| 182 | } |
| 183 | [] as_cbsp_keepalive_ack(idx) { repeat; } |
| 184 | [] CBSP[idx].receive { |
| 185 | setverdict(fail, "Received unexpected CBSP in index ", idx); |
| 186 | } |
| 187 | } |
| 188 | } |
| 189 | |
| 190 | } |