sgsn: Implement TLLI assignment/modification/unassignment

It's important that we implement the proper TLLI handling whenever our
P-TMSI changes.

Change-Id: I5b95b9e49f0a1db9659714c4d01f340fd44fafe8
diff --git a/library/BSSGP_Emulation.ttcn b/library/BSSGP_Emulation.ttcn
index f981adb..fb3f7d4 100644
--- a/library/BSSGP_Emulation.ttcn
+++ b/library/BSSGP_Emulation.ttcn
@@ -63,9 +63,10 @@
 
 signature BSSGP_register_client(hexstring imsi, OCT4 tlli, BssgpCellId cell_id);
 signature BSSGP_unregister_client(hexstring imsi);
+signature BSSGP_llgmm_assign(OCT4 tlli_old, OCT4 tlli);
 
 type port BSSGP_PROC_PT procedure {
-	inout BSSGP_register_client, BSSGP_unregister_client;
+	inout BSSGP_register_client, BSSGP_unregister_client, BSSGP_llgmm_assign;
 } with { extension "internal" };
 
 
@@ -303,6 +304,25 @@
 	self.stop;
 }
 
+/* TS 44.064 7.2.1.1 LLGMM-ASSIGN */
+private function f_tbl_client_llgmm_assign(OCT4 tlli_old, OCT4 tlli_new, BSSGP_Client_CT vc_conn)
+runs on BSSGP_CT {
+	var integer i := f_tbl_idx_by_comp(vc_conn);
+
+	if (tlli_old == 'FFFFFFFF'O and tlli_new != 'FFFFFFFF'O) {
+		/* TLLI assignment */
+		ClientTable[i].tlli := tlli_new;
+		ClientTable[i].tlli_old := omit;
+	} else if (tlli_old != 'FFFFFFFF'O and tlli_new != 'FFFFFFFF'O) {
+		/* TLLI change: both active */
+		ClientTable[i].tlli := tlli_new;
+		ClientTable[i].tlli_old := tlli_old;
+	} else if (tlli_old != 'FFFFFFFF'O and tlli_new == 'FFFFFFFF'O) {
+		/* TLLI unassignment: old shall be unassigned; new stays */
+		ClientTable[i].tlli_old := omit;
+	}
+}
+
 private function f_tbl_comp_by_imsi(hexstring imsi) runs on BSSGP_CT return BSSGP_Client_CT {
 	var integer i;
 	for (i := 0; i < sizeof(ClientTable); i := i+1) {
@@ -357,7 +377,7 @@
 	var NsStatusIndication nsi;
 	var ASP_Event evt;
 	var hexstring imsi;
-	var OCT4 tlli;
+	var OCT4 tlli, tlli_old;
 	var BssgpCellId cell_id;
 
 	/* Respond to BLOCK for wrong NSVCI */
@@ -421,6 +441,11 @@
 		f_tbl_client_del(imsi, vc_conn);
 		BSSGP_PROC.reply(BSSGP_unregister_client:{imsi});
 		}
+	[] BSSGP_PROC.getcall(BSSGP_llgmm_assign:{?,?}) -> param(tlli_old, tlli) sender vc_conn {
+		f_tbl_client_llgmm_assign(tlli_old, tlli, vc_conn);
+		BSSGP_PROC.reply(BSSGP_llgmm_assign:{tlli_old, tlli});
+		}
+
 }
 
 altstep as_blocked() runs on BSSGP_CT {
@@ -620,6 +645,14 @@
 	}
 }
 
+/* TS 44.064 7.2.1.1 LLGMM-ASSIGN */
+function f_bssgp_client_llgmm_assign(OCT4 tlli_old, OCT4 tlli_new, BSSGP_PROC_PT PT := BSSGP_PROC)
+runs on BSSGP_Client_CT {
+	PT.call(BSSGP_llgmm_assign:{tlli_old, tlli_new}) {
+		[] PT.getreply(BSSGP_llgmm_assign:{tlli_old, tlli_new}) {};
+	}
+}
+
 template BssgpDecoded tr_BD_BSSGP(template PDU_BSSGP bg) := {
 	bssgp := bg,
 	llc := *,
@@ -627,7 +660,6 @@
 	l3_mt := *
 }
 
-
 template BssgpDecoded tr_BD_L3_MT(template PDU_L3_SGSN_MS mt) := {
 	bssgp := ?,
 	llc := ?,
@@ -644,5 +676,4 @@
 
 
 
-
 }