From 79feba5ed43f98b3be2a2e0b8f77ad69ec8c3c50 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Sat, 25 Nov 2017 02:32:50 +0100 Subject: rename 'ipa' directory to 'bsc-nat' --- bsc-nat/BSC_MS_ConnectionHandler.ttcn | 162 ++++++++++++++++++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 bsc-nat/BSC_MS_ConnectionHandler.ttcn (limited to 'bsc-nat/BSC_MS_ConnectionHandler.ttcn') diff --git a/bsc-nat/BSC_MS_ConnectionHandler.ttcn b/bsc-nat/BSC_MS_ConnectionHandler.ttcn new file mode 100644 index 00000000..ee564013 --- /dev/null +++ b/bsc-nat/BSC_MS_ConnectionHandler.ttcn @@ -0,0 +1,162 @@ +module BSC_MS_ConnectionHandler { + +import from General_Types all; +import from Osmocom_Types all; +import from SCCPasp_Types all; +import from BSSAP_Types all; +import from BSSMAP_Emulation all; +import from BSSMAP_Templates all; + +import from MobileL3_Types all; +import from MobileL3_CommonIE_Types all; +import from L3_Templates all; + +import from MGCP_Types all; +import from MGCP_Templates all; +import from SDP_Types all; + +/* this component represents a single subscriber connection at the MSC. + * There is a 1:1 mapping between SCCP connections and BSSAP_ConnHdlr components. + * We inherit all component variables, ports, functions, ... from BSSAP_ConnHdlr */ +type component BSC_MS_ConnHdlr extends BSSAP_ConnHdlr { + /* SCCP Connecction Identifier for the underlying SCCP connection */ + var integer g_sccp_conn_id; + var MgcpConnectionId g_mgcp_conn_id; + var SDP_Message g_sdp; + var BSC_State g_state; +} + +/* Callback function from general BSSMAP_Emulation whenever a new incoming + * SCCP connection arrivces. Must create + start a new component */ +private function CreateCallback(ASP_SCCP_N_CONNECT_ind conn_ind, charstring id) +runs on BSSMAP_Emulation_CT return BSSAP_ConnHdlr { + log("Incoming SCCP Connection on BSC ?!?"); + self.stop; +} + +/* Callback function from general BSSMAP_Emulation whenever a connectionless + * BSSMAP message arrives. Can retunr a PDU_BSSAP that should be sent in return */ +private function UnitdataCallback(PDU_BSSAP bssap) +runs on BSSMAP_Emulation_CT return template PDU_BSSAP { + var template PDU_BSSAP resp := omit; + + if (match(bssap, tr_BSSMAP_Reset)) { + resp := ts_BSSMAP_ResetAck; + } + + return resp; +} + +const BssmapOps BSC_MS_BssmapOps := { + create_cb := refers(CreateCallback), + unitdata_cb := refers(UnitdataCallback) +} + + +function f_gen_cl3(hexstring imsi) return PDU_BSSAP { + var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(imsi)); + var PDU_ML3_MS_NW l3 := valueof(ts_CM_SERV_REQ('0001'B, mi)); + var BSSMAP_IE_CellIdentifier cell_id := valueof(ts_CellID_LAC_CI(23, 42)); + var PDU_BSSAP bssap := valueof(ts_BSSMAP_ComplL3(cell_id, enc_PDU_ML3_MS_NW(l3))); + return bssap; +} + +type enumerated BSC_State { + BSC_STATE_NONE, + BSC_STATE_WAIT_ASS_REQ, + BSC_STATE_WAIT_CRCX, + BSC_STATE_WAIT_MDCX, + BSC_STATE_WAIT_CLEAR_CMD, + BSC_STATE_WAIT_DLCX, + BSC_STATE_WAIT_DISC_IND +} + +/* main function processing various incoming events */ +function main(SCCP_PAR_Address sccp_addr_own, SCCP_PAR_Address sccp_addr_remote) +runs on BSC_MS_ConnHdlr { + var PDU_BSSAP bssap; + var MgcpCommand mgcp_cmd; + var MgcpResponse mgcp_resp; + + log("Starting main of BSC_MS_ConnHdlr"); + + g_mgcp_conn_id := f_mgcp_alloc_conn_id(); + + /* generate and send the Complete Layer3 Info */ + bssap := f_gen_cl3('901770123456789'H); + var BSSAP_Conn_Req creq := { + addr_peer := sccp_addr_remote, + addr_own := sccp_addr_own, + bssap := bssap + } + g_state := BSC_STATE_WAIT_ASS_REQ; + BSSAP.send(creq); + + while (true) { + alt { + /* new SCCP-level connection indication from BSC */ + [g_state == BSC_STATE_WAIT_ASS_REQ] BSSAP.receive(tr_BSSMAP_AssignmentReq) -> value bssap { + /* FIXME: Read CIC */ + /* respond with ASSIGNMENT COMPL */ + g_state := BSC_STATE_WAIT_CRCX; + BSSAP.send(ts_BSSMAP_AssignmentComplete(bssap.pdu.bssmap.assignmentRequest.circuitIdentityCode)); + } + + /* CRCX -> OK */ + [g_state == BSC_STATE_WAIT_CRCX] BSSAP.receive(tr_CRCX) -> value mgcp_cmd { + /* FIXME: proper SDP parameters */ + g_sdp := valueof(ts_SDP("127.0.0.1", "127.0.0.1", "foo", "21", 1000, { "98" }, + { valueof(ts_SDP_rtpmap(98, "AMR/8000")), + valueof(ts_SDP_ptime(20)) })); + /* respond with CRCX_ACK */ + g_state := BSC_STATE_WAIT_MDCX; + BSSAP.send(ts_CRCX_ACK(mgcp_cmd.line.trans_id, g_mgcp_conn_id, g_sdp)); + } + + /* MDCX -> OK */ + [g_state == BSC_STATE_WAIT_MDCX] BSSAP.receive(tr_MDCX) -> value mgcp_cmd { + /* FIXME: verify if local part of endpoint name matches CIC */ + /* respond with CRCX_ACK */ + g_state := BSC_STATE_WAIT_CLEAR_CMD; + BSSAP.send(ts_MDCX_ACK(mgcp_cmd.line.trans_id, g_mgcp_conn_id, g_sdp)); + } + + /* CLEAR COMMAND from MSC; respond with CLEAR COMPLETE) */ + [g_state == BSC_STATE_WAIT_CLEAR_CMD] BSSAP.receive(tr_BSSMAP_ClearCommand) -> value bssap { + g_state := BSC_STATE_WAIT_DLCX; + BSSAP.send(ts_BSSMAP_ClearComplete); + } + + /* DLCX -> OK */ + [g_state == BSC_STATE_WAIT_DLCX] BSSAP.receive(tr_DLCX) -> value mgcp_cmd { + /* FIXME: verify if local part of endpoint name matches CIC */ + g_state := BSC_STATE_WAIT_DISC_IND; + BSSAP.send(ts_DLCX_ACK(mgcp_cmd.line.trans_id, g_mgcp_conn_id)); + } + + [] BSSAP.receive(tr_BSSAP_DTAP) -> value bssap { + /* FIXME: verify if local part of endpoint name matches CIC */ + var PDU_ML3_MS_NW l3 := dec_PDU_ML3_MS_NW(bssap.pdu.dtap); + log("Unhandled DTAP ", l3); + } + + [g_state == BSC_STATE_WAIT_DISC_IND] BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND) { + setverdict(pass); + self.stop; + } + + /* disconnect in invalid state */ + [] BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND) { + setverdict(fail); + self.stop; + } + + + [] BSSAP.receive(PDU_BSSAP:?) -> value bssap { + log("Received unhandled SCCP-CO: ", bssap); + } + } + } +} + +} -- cgit v1.2.3