ipa: First version that emulates both MSC and BSC up to ASSIGNMENT REQ
diff --git a/library/BSSMAP_Emulation.ttcn b/library/BSSMAP_Emulation.ttcn
index bcc0e11..9e4d5c3 100644
--- a/library/BSSMAP_Emulation.ttcn
+++ b/library/BSSMAP_Emulation.ttcn
@@ -1,5 +1,6 @@
module BSSMAP_Emulation {
+import from SCCP_Emulation all;
import from SCCPasp_Types all;
import from BSSAP_Types all;
import from BSSMAP_Templates all;
@@ -20,10 +21,15 @@
MSC_CONN_PRIM_DISC_REQ
}
+type record BSSAP_Conn_Req {
+ SCCP_PAR_Address addr_peer,
+ SCCP_PAR_Address addr_own,
+ PDU_BSSAP bssap
+}
+
/* port between individual per-connection components and this dispatcher */
type port BSSAP_Conn_PT message {
- inout PDU_BSSAP;
- inout BSSAP_Conn_Prim;
+ inout PDU_BSSAP, BSSAP_Conn_Prim, BSSAP_Conn_Req;
} with { extension "internal" };
@@ -44,6 +50,27 @@
var ConnectionData ConnectionTable[16];
};
+private function f_conn_id_known(integer sccp_conn_id)
+runs on BSSMAP_Emulation_CT return boolean {
+ var integer i;
+ for (i := 0; i < sizeof(ConnectionTable); i := i+1) {
+ if (ConnectionTable[i].sccp_conn_id == sccp_conn_id){
+ return true;
+ }
+ }
+ return false;
+}
+
+private function f_comp_known(BSSAP_ConnHdlr client)
+runs on BSSMAP_Emulation_CT return boolean {
+ var integer i;
+ for (i := 0; i < sizeof(ConnectionTable); i := i+1) {
+ if (ConnectionTable[i].comp_ref == client) {
+ return true;
+ }
+ }
+ return false;
+}
/* resolve component reference by connection ID */
private function f_comp_by_conn_id(integer sccp_conn_id)
@@ -70,6 +97,17 @@
self.stop;
}
+private function f_gen_conn_id()
+runs on BSSMAP_Emulation_CT return integer {
+ var integer conn_id;
+
+ do {
+ conn_id := float2int(rnd()*SCCP_Emulation.tsp_max_ConnectionId);
+ } while (f_conn_id_known(conn_id) == true);
+
+ return conn_id;
+}
+
private function f_conn_table_init()
runs on BSSMAP_Emulation_CT {
for (var integer i := 0; i < sizeof(ConnectionTable); i := i+1) {
@@ -84,6 +122,7 @@
if (ConnectionTable[i].sccp_conn_id == -1) {
ConnectionTable[i].comp_ref := comp_ref;
ConnectionTable[i].sccp_conn_id := sccp_conn_id;
+ log("Added conn table entry ", i, comp_ref, sccp_conn_id);
return;
}
}
@@ -95,6 +134,8 @@
runs on BSSMAP_Emulation_CT {
for (var integer i := 0; i < sizeof(ConnectionTable); i := i+1) {
if (ConnectionTable[i].sccp_conn_id == sccp_conn_id) {
+ log("Deleted conn table entry ", i,
+ ConnectionTable[i].comp_ref, sccp_conn_id);
ConnectionTable[i].sccp_conn_id := -1;
ConnectionTable[i].comp_ref := null;
}
@@ -135,8 +176,10 @@
while (true) {
var ASP_SCCP_N_UNITDATA_ind ud_ind;
var ASP_SCCP_N_CONNECT_ind conn_ind;
+ var ASP_SCCP_N_CONNECT_cfm conn_cfm;
var ASP_SCCP_N_DATA_ind data_ind;
var ASP_SCCP_N_DISCONNECT_ind disc_ind;
+ var BSSAP_Conn_Req creq;
var BSSAP_ConnHdlr vc_conn;
var PDU_BSSAP bssap;
@@ -183,6 +226,12 @@
/* TOOD: return confirm to other side? */
}
+ /* SCCP -> Client: connection confirm for outbound connection */
+ [] SCCP.receive(ASP_SCCP_N_CONNECT_cfm:?) -> value conn_cfm {
+ /* handle user payload */
+ f_handle_userData(vc_conn, conn_cfm.userData);
+ }
+
/* Disconnect request client -> SCCP */
[] CLIENT.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_REQ) -> sender vc_conn {
var integer conn_id := f_conn_id_by_comp(vc_conn);
@@ -191,9 +240,31 @@
}
/* BSSAP from client -> SCCP */
+ [] CLIENT.receive(BSSAP_Conn_Req:?) -> value creq sender vc_conn {
+ var integer conn_id;
+ /* encode + send to dispatcher */
+ var octetstring userdata := enc_PDU_BSSAP(creq.bssap);
+
+ if (f_comp_known(vc_conn) == false) {
+ /* unknown client, create new connection */
+ conn_id := f_gen_conn_id();
+
+ /* store mapping between client components and SCCP connectionId */
+ f_conn_table_add(vc_conn, conn_id);
+
+ SCCP.send(t_ASP_N_CONNECT_req(creq.addr_peer, creq.addr_own, omit, omit,
+ userdata, conn_id, omit));
+ } else {
+ /* known client, send via existing connection */
+ conn_id := f_conn_id_by_comp(vc_conn);
+ SCCP.send(t_ASP_N_DATA_req(userdata, conn_id, omit));
+ }
+
+ }
+
[] CLIENT.receive(PDU_BSSAP:?) -> value bssap sender vc_conn {
var integer conn_id := f_conn_id_by_comp(vc_conn);
- /* encode + send to dispatcher */
+ /* encode + send it to dispatcher */
var octetstring userdata := enc_PDU_BSSAP(bssap);
SCCP.send(t_ASP_N_DATA_req(userdata, conn_id, omit));
}