[GPRS] Major LLC / TLLI handling fixes

* separate the LLME and LLE state in the LLC layer
* introduce gprs_llgmm_assign() function for LLGMM-ASSIGN.req primitive
* change QoS profile to match 'real' SGSN
* Update the new TLLI when assigning a P-TMSI

The result now is that the LLC layer is notified of TLLI changes, which in turn
means it doesn't allocate a new LLE structure every TLLI change, which again
in turn means that the UI frame sequence number does not reset to zero.

As a result, MS should no longer ignore frames based on wrong UI sequence number.
diff --git a/openbsc/src/gprs/gprs_llc_vty.c b/openbsc/src/gprs/gprs_llc_vty.c
index 9c7f556..6f0de04 100644
--- a/openbsc/src/gprs/gprs_llc_vty.c
+++ b/openbsc/src/gprs/gprs_llc_vty.c
@@ -41,34 +41,48 @@
 #include <osmocom/vty/command.h>
 
 struct value_string gprs_llc_state_strs[] = {
-	{ GPRS_LLS_UNASSIGNED, 		"TLLI Unassigned" },
-	{ GPRS_LLS_ASSIGNED_ADM,	"Assigned" },
-	{ GPRS_LLS_LOCAL_EST,		"Local Establishment" },
-	{ GPRS_LLS_REMOTE_EST,		"Remote Establishment" },
-	{ GPRS_LLS_ABM,			"Asynchronous Balanced Mode" },
-	{ GPRS_LLS_LOCAL_REL,		"Local Release" },
-	{ GPRS_LLS_TIMER_REC,		"Timer Recovery" },
+	{ GPRS_LLES_UNASSIGNED, 	"TLLI Unassigned" },
+	{ GPRS_LLES_ASSIGNED_ADM,	"TLLI Assigned" },
+	{ GPRS_LLES_LOCAL_EST,		"Local Establishment" },
+	{ GPRS_LLES_REMOTE_EST,		"Remote Establishment" },
+	{ GPRS_LLES_ABM,		"Asynchronous Balanced Mode" },
+	{ GPRS_LLES_LOCAL_REL,		"Local Release" },
+	{ GPRS_LLES_TIMER_REC,		"Timer Recovery" },
 };
 
 static void vty_dump_lle(struct vty *vty, struct gprs_llc_lle *lle)
 {
-	vty_out(vty, "TLLI 0x%08x SAPI %u BVCI=%u NSEI=%u: State %s%s",
-		lle->tlli, lle->sapi, lle->bvci, lle->nsei,
-		get_value_string(gprs_llc_state_strs, lle->state), VTY_NEWLINE);
-	vty_out(vty, " Vsent=%u Vack=%u Vrecv=%u, N200=%u, Retrans Ctr=%u%s",
+	vty_out(vty, " SAPI %2u State %s VUsend=%u, VUrecv=%u", lle->sapi, 
+		get_value_string(gprs_llc_state_strs, lle->state),
+		lle->vu_send, lle->vu_recv);
+	vty_out(vty, " Vsent=%u Vack=%u Vrecv=%u, N200=%u, RetransCtr=%u%s",
 		lle->v_sent, lle->v_ack, lle->v_recv, lle->n200,
 		lle->retrans_ctr, VTY_NEWLINE);
 }
 
+static void vty_dump_llme(struct vty *vty, struct gprs_llc_llme *llme)
+{
+	unsigned int i;
+
+	vty_out(vty, "TLLI %08x (Old TLLI %08x) BVCI=%u NSEI=%u: State %s%s",
+		llme->tlli, llme->old_tlli, llme->bvci, llme->nsei,
+		get_value_string(gprs_llc_state_strs, llme->state), VTY_NEWLINE);
+	for (i = 0; i < ARRAY_SIZE(llme->lle); i++) {
+		struct gprs_llc_lle *lle = &llme->lle[i];
+		vty_dump_lle(vty, lle);
+	}
+}
+
+
 DEFUN(show_llc, show_llc_cmd,
 	"show llc",
 	SHOW_STR "Display information about the LLC protocol")
 {
-	struct gprs_llc_lle *lle;
+	struct gprs_llc_llme *llme;
 
 	vty_out(vty, "State of LLC Entities%s", VTY_NEWLINE);
-	llist_for_each_entry(lle, &gprs_llc_lles, list) {
-		vty_dump_lle(vty, lle);
+	llist_for_each_entry(llme, &gprs_llc_llmes, list) {
+		vty_dump_llme(vty, llme);
 	}
 	return CMD_SUCCESS;
 }