| module BSSAP_Adapter { |
| |
| /* This module implements a 'dumb' BSSAP adapter. It creates the M3UA and SCCP components and stacks a BSSAP |
| * codec port on top. As a result, it provides the ability to transceive SCCP-User-SAP primitives with |
| * deoded BSSAP payload. Use this if you want to have full control about what you transmit or receive, |
| * without any automatisms in place. Allows you to refuse connections or other abnormal behavior. */ |
| |
| import from General_Types all; |
| import from Osmocom_Types all; |
| |
| import from M3UA_Types all; |
| import from M3UA_Emulation all; |
| import from MTP3asp_Types all; |
| import from MTP3asp_PortType all; |
| |
| import from SCCP_Types all; |
| import from SCCPasp_Types all; |
| import from SCCP_Emulation all; |
| |
| import from SCTPasp_Types all; |
| import from SCTPasp_PortType all; |
| |
| import from BSSAP_CodecPort all; |
| import from BSSMAP_Templates all; |
| |
| type component BSSAP_Adapter_CT { |
| /* component references */ |
| var M3UA_CT vc_M3UA; |
| var SCCP_CT vc_SCCP; |
| /* test port to SCCP emulation */ |
| port BSSAP_CODEC_PT BSSAP; |
| |
| var octetstring g_sio; |
| var MSC_SCCP_MTP3_parameters g_sccp_pars; |
| var SCCP_PAR_Address g_sccp_addr_own, g_sccp_addr_peer; |
| } |
| |
| modulepar { |
| charstring mp_sccp_service_type := "mtp3_itu"; |
| |
| SCTP_Association_Address mp_sctp_addr := { 23905, "127.0.0.1", 2905, "127.0.0.1" }; |
| integer mp_own_pc := 185; /* 0.23.1 */ |
| integer mp_own_ssn := 254; |
| |
| integer mp_peer_pc := 187; |
| integer mp_peer_ssn := 254; |
| } |
| |
| /* construct a SCCP_PAR_Address with just PC + SSN and no GT */ |
| template (value) SCCP_PAR_Address ts_SccpAddr_PC_SSN(integer pc, integer ssn) := { |
| addressIndicator := { |
| pointCodeIndic := '1'B, |
| ssnIndicator := '1'B, |
| globalTitleIndic := '0000'B, |
| routingIndicator := '1'B |
| }, |
| signPointCode := SCCP_SPC_int2bit(pc, mp_sccp_service_type, '83'O), |
| //signPointCode := SCCP_SPC_int2bit(pc, mp_sccp_service_type, g_sio), |
| subsystemNumber := ssn, |
| globalTitle := omit |
| } |
| |
| private function init_pars() runs on BSSAP_Adapter_CT { |
| g_sio := '83'O; |
| g_sccp_pars := { |
| sio := { |
| ni := substr(oct2bit(g_sio),0,2), |
| prio := substr(oct2bit(g_sio),2,2), |
| si := substr(oct2bit(g_sio),4,4) |
| }, |
| opc := mp_own_pc, |
| dpc := mp_peer_pc, |
| sls := 0, |
| sccp_serviceType := mp_sccp_service_type, |
| ssn := mp_own_ssn |
| }; |
| g_sccp_addr_own := valueof(ts_SccpAddr_PC_SSN(mp_own_pc, mp_own_ssn)); |
| g_sccp_addr_peer := valueof(ts_SccpAddr_PC_SSN(mp_peer_pc, mp_peer_ssn)); |
| } |
| |
| |
| function f_bssap_init(charstring id) runs on BSSAP_Adapter_CT |
| { |
| init_pars(); |
| |
| /* create components */ |
| vc_M3UA := M3UA_CT.create(id & "-M3UA"); |
| vc_SCCP := SCCP_CT.create(id & "-SCCP"); |
| |
| map(vc_M3UA:SCTP_PORT, system:sctp); |
| |
| /* connect MTP3 service provider (M3UA) to lower side of SCCP */ |
| connect(vc_M3UA:MTP3_SP_PORT, vc_SCCP:MTP3_SCCP_PORT); |
| |
| /* connect BSSNAP dispatcher to upper side of SCCP */ |
| connect(self:BSSAP, vc_SCCP:SCCP_SP_PORT); |
| |
| vc_M3UA.start(f_M3UA_Emulation(mp_sctp_addr)); |
| vc_SCCP.start(SCCPStart(g_sccp_pars)); |
| } |
| |
| private altstep as_reset_ack() runs on BSSAP_Adapter_CT { |
| var BSSAP_N_UNITDATA_ind ud_ind; |
| [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset)) -> value ud_ind { |
| log("Respoding to inbound RESET with RESET-ACK"); |
| BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress, |
| ts_BSSMAP_ResetAck)); |
| } |
| } |
| |
| |
| function f_bssap_wait_for_reset() runs on BSSAP_Adapter_CT { |
| var BSSAP_N_UNITDATA_ind ud_ind; |
| timer T := 20.0; |
| |
| T.start; |
| alt { |
| [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset)) -> value ud_ind { |
| BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress, |
| ts_BSSMAP_ResetAck)); |
| } |
| [] as_reset_ack(); |
| [] BSSAP.receive { |
| repeat; |
| } |
| [] T.timeout { |
| setverdict(fail); |
| } |
| } |
| } |
| |
| function f_bssap_reset() runs on BSSAP_Adapter_CT { |
| timer T := 5.0; |
| |
| BSSAP.send(ts_BSSAP_UNITDATA_req(g_sccp_addr_peer, g_sccp_addr_own, ts_BSSMAP_Reset(0))); |
| T.start; |
| alt { |
| [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(g_sccp_addr_own, g_sccp_addr_peer, tr_BSSMAP_ResetAck)) { |
| log("Received RESET-ACK in response to RESET, we're ready to go!"); |
| } |
| [] as_reset_ack(); |
| [] BSSAP.receive { repeat }; |
| [] T.timeout { setverdict(fail, "Waiting for RESET-ACK after sending RESET"); } |
| } |
| } |
| |
| |
| } |