GSUP: implement TCAP-like session management

Unlike TCAP/MAP, GSUP is just a transport layer without the
dialogue/context. This prevents us from having session based
communication, required e.g. for USSD. But we can emulate
TCAP dialogue by adding additional IEs, which would allow
to relate each message to a particular session.

This change introduces the following IEs:

  - OSMO_GSUP_SESSION_ID_IE,
  - OSMO_GSUP_SESSION_STATE_IE,

which optionally can be used to indicate that the message is
related to a session with given ID, and to manage session
state, i.e. initiate, continue, and finish.

Change-Id: I1cee271fed0284a134ffed103c0d4bebbcfde2a8
Related: OS#1597
diff --git a/src/gsm/gsup.c b/src/gsm/gsup.c
index b6ac56d..8663f44 100644
--- a/src/gsm/gsup.c
+++ b/src/gsm/gsup.c
@@ -385,6 +385,14 @@
 			gsup_msg->pdp_charg_enc_len = value_len;
 			break;
 
+		case OSMO_GSUP_SESSION_ID_IE:
+			gsup_msg->session_id = osmo_decode_big_endian(value, value_len);
+			break;
+
+		case OSMO_GSUP_SESSION_STATE_IE:
+			gsup_msg->session_state = *value;
+			break;
+
 		default:
 			LOGP(DLGSUP, LOGL_NOTICE,
 			     "GSUP IE type %d unknown\n", iei);
@@ -564,6 +572,14 @@
 				gsup_msg->pdp_charg_enc_len, gsup_msg->pdp_charg_enc);
 	}
 
+	if ((u8 = gsup_msg->session_state)) {
+		size_t len = sizeof(gsup_msg->session_id);
+		uint8_t *sid = osmo_encode_big_endian(gsup_msg->session_id, len);
+
+		msgb_tlv_put(msg, OSMO_GSUP_SESSION_ID_IE, len, sid);
+		msgb_tlv_put(msg, OSMO_GSUP_SESSION_STATE_IE, sizeof(u8), &u8);
+	}
+
 	return 0;
 }