This is merely a historical archive of years 2008-2021, before the migration to mailman3.
A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.
Harald Welte gerrit-no-reply at lists.osmocom.orgHarald Welte has submitted this change and it was merged. Change subject: BSSMAP: Add IMSI/TMSI mapping table to dispatch incoming paging ...................................................................... BSSMAP: Add IMSI/TMSI mapping table to dispatch incoming paging If we're emulating BSC/BTS/MS, then we must be able to dispatch incoming paging requests based on their IMSI or TMSI to the right ConnHdlr component. This introduces a new table to facilitate that dispatch. Change-Id: I85c1ea3bcf8fb4a100f20cffdc991826b58e290b --- M library/BSSMAP_Emulation.ttcn M library/BSSMAP_Templates.ttcn 2 files changed, 120 insertions(+), 3 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/library/BSSMAP_Emulation.ttcn b/library/BSSMAP_Emulation.ttcn index e7a432c..ca5afb9 100644 --- a/library/BSSMAP_Emulation.ttcn +++ b/library/BSSMAP_Emulation.ttcn @@ -116,6 +116,12 @@ integer cic optional } +type record ImsiMapping { + BSSAP_ConnHdlr comp_ref, + hexstring imsi optional, + OCT4 tmsi +} + type component BSSMAP_Emulation_CT { /* SCCP port on the bottom side, using ASP primitives */ port BSSAP_CODEC_PT BSSAP; @@ -129,6 +135,10 @@ /* pending expected incoming connections */ var ExpectData ExpectTable[8]; + + /* tables for mapping inbound unitdata (like paging) */ + var ImsiMapping ImsiTable[16]; + /* procedure based port to register for incoming connections */ port BSSMAPEM_PROC_PT PROC; @@ -270,6 +280,11 @@ ConnectionTable[i].mgcp_trans_id := omit; ConnectionTable[i].cic := omit; } + for (var integer i := 0; i < sizeof(ImsiTable); i := i+1) { + ImsiTable[i].comp_ref := null; + ImsiTable[i].imsi := omit; + ImsiTable[i].tmsi := 'FFFFFFFF'O; + } } private function f_conn_table_add(BSSAP_ConnHdlr comp_ref, integer sccp_conn_id) @@ -301,6 +316,17 @@ log("BSSMAP Connection table attempt to delete non-existant ", sccp_conn_id); setverdict(fail); self.stop; +} + +private function f_imsi_table_find(hexstring imsi, template OCT4 tmsi) +runs on BSSMAP_Emulation_CT return BSSAP_ConnHdlr { + for (var integer i := 0; i < sizeof(ImsiTable); i := i+1) { + if (ImsiTable[i].imsi == imsi or + isvalue(tmsi) and match(ImsiTable[i].tmsi, tmsi)) { + return ImsiTable[i].comp_ref; + } + } + return null; } /* handle (optional) userData portion of various primitives and dispatch it to the client */ @@ -346,6 +372,27 @@ type function BssmapUnitdataCallback(PDU_BSSAP bssap) runs on BSSMAP_Emulation_CT return template PDU_BSSAP; +/* handle common Unitdata such as Paging */ +private function CommonBssmapUnitdataCallback(PDU_BSSAP bssap) +runs on BSSMAP_Emulation_CT return template PDU_BSSAP { + if (match(bssap, tr_BSSMAP_Paging)) { + var BSSAP_ConnHdlr client := null; + client := f_imsi_table_find(bssap.pdu.bssmap.paging.iMSI.digits, + bssap.pdu.bssmap.paging.tMSI.tmsiOctets); + if (isvalue(client)) { + log("CommonBssmapUnitdataCallback: IMSI/TMSI found in table, dispatching to ", + client); + CLIENT.send(bssap) to client; + return omit; + } + log("CommonBssmapUnitdataCallback: IMSI/TMSI not found in table"); + } else { + log("CommonBssmapUnitdataCallback: Not a paging message"); + } + /* ELSE: handle in user callback */ + return g_bssmap_ops.unitdata_cb.apply(bssap); +} + type record BssmapOps { BssmapCreateCallback create_cb, BssmapUnitdataCallback unitdata_cb, @@ -375,13 +422,15 @@ var MgcpResponse mgcp_resp; var BSSAP_ConnHdlr vc_hdlr; var octetstring l3_info; + var hexstring imsi; + var OCT4 tmsi; alt { /* SCCP -> Client: UNIT-DATA (connectionless SCCP) from a BSC */ [] BSSAP.receive(BSSAP_N_UNITDATA_ind:?) -> value ud_ind { /* Connectionless Procedures like RESET */ var template PDU_BSSAP resp; - resp := ops.unitdata_cb.apply(ud_ind.userData); + resp := CommonBssmapUnitdataCallback(ud_ind.userData); if (isvalue(resp)) { BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress, resp)); @@ -528,6 +577,12 @@ PROC.reply(BSSMAPEM_register:{l3_info, vc_hdlr}); } + [] PROC.getcall(BSSMAPEM_register_imsi:{?,?,?}) -> param(imsi, tmsi, vc_hdlr) { + f_create_imsi(imsi, tmsi, vc_hdlr); + PROC.reply(BSSMAPEM_register_imsi:{imsi, tmsi, vc_hdlr}); + } + + } } } @@ -553,8 +608,11 @@ /* procedure based port to register for incoming connections */ signature BSSMAPEM_register(in octetstring l3, in BSSAP_ConnHdlr hdlr); +/* procedure based port to register for incoming IMSI/TMSI */ +signature BSSMAPEM_register_imsi(in hexstring imsi, in OCT4 tmsi, in BSSAP_ConnHdlr hdlr); + type port BSSMAPEM_PROC_PT procedure { - inout BSSMAPEM_register; + inout BSSMAPEM_register, BSSMAPEM_register_imsi; } with { extension "internal" }; /* CreateCallback that can be used as create_cb and will use the expectation table */ @@ -602,6 +660,22 @@ setverdict(fail, "No space left in ExpectTable"); } +private function f_create_imsi(hexstring imsi, OCT4 tmsi, BSSAP_ConnHdlr hdlr) +runs on BSSMAP_Emulation_CT { + for (var integer i := 0; i < sizeof(ImsiTable); i := i+1) { + if (not ispresent(ImsiTable[i].imsi)) { + ImsiTable[i].imsi := imsi; + ImsiTable[i].tmsi := tmsi; + ImsiTable[i].comp_ref := hdlr; + log("Created IMSI[", i, "] for ", imsi, tmsi, " to be handled at ", hdlr); + return; + } + } + setverdict(fail, "No space left in ImsiTable"); + self.stop; +} + + private function f_expect_table_init() runs on BSSMAP_Emulation_CT { for (var integer i := 0; i < sizeof(ExpectTable); i := i+1) { @@ -609,4 +683,13 @@ } } +/* helper function for clients to register their IMSI/TMSI */ +function f_bssmap_register_imsi(hexstring imsi, OCT4 tmsi) +runs on BSSAP_ConnHdlr { + BSSAP_PROC.call(BSSMAPEM_register_imsi:{imsi, tmsi, self}) { + [] BSSAP_PROC.getreply(BSSMAPEM_register_imsi:{?,?,?}) {}; + } +} + + } diff --git a/library/BSSMAP_Templates.ttcn b/library/BSSMAP_Templates.ttcn index 075dab7..c98f5eb 100644 --- a/library/BSSMAP_Templates.ttcn +++ b/library/BSSMAP_Templates.ttcn @@ -660,6 +660,14 @@ digits := imsi_digits } +template BSSMAP_IE_IMSI tr_BSSMAP_Imsi(template hexstring imsi_digits) := { + elementIdentifier := '08'O, + lengthIndicator := ?, /* overwritten */ + typeOfIdentity := '001'B, /* IMSI */ + oddEvenIndicator := ?, + digits := imsi_digits +} + template BSSMAP_FIELD_CellIdentificationList ts_BSSMAP_CIL_noCell := { cIl_noCell := ''O } @@ -699,6 +707,12 @@ tmsiOctets := tmsi }; +template BSSMAP_IE_TMSI tr_BSSMAP_IE_TMSI(template OCT4 tmsi) := { + elementIdentifier := '09'O, + lengthIndicator := 4, + tmsiOctets := tmsi +}; + private function f_tmsi_or_omit(template OCT4 tmsi) return template BSSMAP_IE_TMSI { var template BSSMAP_IE_TMSI ret; if (ispresent(tmsi)) { @@ -717,7 +731,7 @@ pdu := { bssmap := { paging := { - messageType := '51'O, + messageType := '52'O, iMSI := ts_BSSMAP_Imsi(imsi_digits), tMSI := f_tmsi_or_omit(tmsi), cellIdentifierList := ts_BSSMAP_IE_CidList(valueof(cid_list)), @@ -729,6 +743,26 @@ } } +template PDU_BSSAP tr_BSSMAP_Paging(template hexstring imsi_digits := ?, + template OCT4 tmsi := *, + template BSSMAP_IE_ChannelNeeded chneed := *) +modifies tr_BSSAP_BSSMAP := { + pdu := { + bssmap := { + paging := { + messageType := '52'O, + iMSI := tr_BSSMAP_Imsi(imsi_digits), + tMSI := tr_BSSMAP_IE_TMSI(tmsi) ifpresent, + cellIdentifierList := ?, + channelNeeded := chneed, + eMLPP_Priority := omit, + pagingInformation := omit /* only VGCS/VBS flag */ + } + } + } +} + + template PDU_BSSAP ts_BSSMAP_CipherModeCmd(OCT1 alg, OCT8 key) modifies ts_BSSAP_BSSMAP := { pdu := { -- To view, visit https://gerrit.osmocom.org/6121 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I85c1ea3bcf8fb4a100f20cffdc991826b58e290b Gerrit-PatchSet: 1 Gerrit-Project: osmo-ttcn3-hacks Gerrit-Branch: master Gerrit-Owner: Harald Welte <laforge at gnumonks.org> Gerrit-Reviewer: Harald Welte <laforge at gnumonks.org> Gerrit-Reviewer: Jenkins Builder