gsup: Deprecate field pdp_type in favour of pdp_type_nr and pdp_type_org

Having both fields in an uin16_t integer makes it difficult and
confusing for users for no good reason. Let's have separate fields for
each of them.

The new fields are defined so that they are ABI compatible with previous
uin16 field.

Change-Id: Ie31c6080c90e468c01186259f2c42621e39b5cc6
diff --git a/TODO-RELEASE b/TODO-RELEASE
index e1d365e..3a0c80c 100644
--- a/TODO-RELEASE
+++ b/TODO-RELEASE
@@ -16,3 +16,4 @@
 isdn      ADD				initial implementation of the V.110 Terminal Adapter
 gsm		ABI change		add T200 timer states to lapdm_datalink
 gsm		ABI change		add UI queue to struct lapdm_datalink
+gsm		ADD			gsup.h: struct osmo_gsup_pdp_info fields pdp_type_nr, pdp_type_org, deprecate pdp_type.
diff --git a/include/osmocom/gsm/gsup.h b/include/osmocom/gsm/gsup.h
index 6c23297..49d1264 100644
--- a/include/osmocom/gsm/gsup.h
+++ b/include/osmocom/gsm/gsup.h
@@ -40,6 +40,8 @@
 
 #include <stdint.h>
 #include <osmocom/core/msgb.h>
+#include <osmocom/core/defs.h>
+#include <osmocom/core/endian.h>
 #include <osmocom/gsm/gsup_sms.h>
 #include <osmocom/gsm/protocol/gsm_23_003.h>
 #include <osmocom/gsm/protocol/gsm_03_40.h>
@@ -260,8 +262,19 @@
 struct osmo_gsup_pdp_info {
 	unsigned int			context_id;
 	int				have_info;
-	/*! Type of PDP context */
-	uint16_t			pdp_type;
+	/*! Type of PDP context, 3GPP TS 29.060, 7.7.27 */
+	union {
+		uint16_t pdp_type OSMO_DEPRECATED("use pdp_type_org and pdp_type_nr instead");
+		struct {
+#if OSMO_IS_LITTLE_ENDIAN
+			uint8_t	pdp_type_nr; /* enum gsm48_pdp_type_nr */
+			uint8_t	pdp_type_org; /* enum gsm48_pdp_type_org */
+#elif OSMO_IS_BIG_ENDIAN
+			uint8_t	pdp_type_org; /* enum gsm48_pdp_type_org */
+			uint8_t	pdp_type_nr; /* enum gsm48_pdp_type_nr */
+#endif
+		};
+	};
 	/*! APN information, still in encoded form. Can be NULL if no
 	 * APN information included */
 	const uint8_t			*apn_enc;
diff --git a/src/gsm/gsup.c b/src/gsm/gsup.c
index 2beff4a..00a9a60 100644
--- a/src/gsm/gsup.c
+++ b/src/gsm/gsup.c
@@ -152,8 +152,8 @@
 		case OSMO_GSUP_PDP_TYPE_IE:
 			if (value_len < 2)
 				return -GMM_CAUSE_PROTO_ERR_UNSPEC;
-			pdp_info->pdp_type =
-				osmo_decode_big_endian(value, value_len) & 0x0fff;
+			pdp_info->pdp_type_org = value[0] & 0x0f;
+			pdp_info->pdp_type_nr = value[1];
 			break;
 
 		case OSMO_GSUP_ACCESS_POINT_NAME_IE:
@@ -603,11 +603,15 @@
 	u8 = pdp_info->context_id;
 	msgb_tlv_put(msg, OSMO_GSUP_PDP_CONTEXT_ID_IE, sizeof(u8), &u8);
 
-	if (pdp_info->pdp_type) {
+	if (pdp_info->pdp_type_org == PDP_TYPE_ORG_IETF) {
+		struct gsm48_pdp_address pdp_addr;
+		pdp_addr.spare = 0x0f;
+		pdp_addr.organization = pdp_info->pdp_type_org;
+		pdp_addr.type = pdp_info->pdp_type_nr;
+
 		msgb_tlv_put(msg, OSMO_GSUP_PDP_TYPE_IE,
 			     OSMO_GSUP_PDP_TYPE_SIZE,
-			     osmo_encode_big_endian(pdp_info->pdp_type | 0xf000,
-					       OSMO_GSUP_PDP_TYPE_SIZE));
+			     (const uint8_t *)&pdp_addr);
 	}
 
 	if (pdp_info->apn_enc) {