From: Holger Hans Peter Freyther holger@moiji-mobile.com
--- openbsc/doc/sgsn-remote-protocol.txt | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
diff --git a/openbsc/doc/sgsn-remote-protocol.txt b/openbsc/doc/sgsn-remote-protocol.txt index 3369d19..88a384e 100644 --- a/openbsc/doc/sgsn-remote-protocol.txt +++ b/openbsc/doc/sgsn-remote-protocol.txt @@ -121,6 +121,7 @@ Network peer -> SGSN 01 IMSI 4.2.9 M TLV 2-10 04 PDP info complete 4.2.8 O TLV 2 05 PDP info 4.2.3 1-10 TLV + 13 MSISDN 4.2.10 O TLV 0-9
If the PDP info complete IE is present, the old PDP info list shall be cleared.
@@ -357,6 +358,7 @@ IEI that shall be used for the encoding. | 0x10 PDP context id big endian int | | 0x11 PDP type 4.2.4 | | 0x12 APN 04.08, 10.5.6.1 | + | 0x13 MSISDN ISDN-AddressString/octet | | 0x20 RAND octet string | | 0x21 SRES octet string | | 0x22 Kc octet string | @@ -397,3 +399,24 @@ The IMSI is encoded like in octet 4-N of the Called Party BCD Number defined in Note 1) Either '1 1 1 1 | Number digit N' (N odd) or 'Number digit N | Number digit N-1' (N even), where N is the number of digits. + +4.2.10. ISDN-AddressString / MSISDN /Called Party BCD Number + + +MSISDN. ISDN-AddressString in GSM 09.02 and Called Party +BCD Number in GSM 04.08. + + 8 7 6 5 4 3 2 1 + +-----------------------------------------------------+ + | | IEI | octet 1 + +-----------------------------------------------------+ + | Length of IE contents | octet 2 + +-----------------------------------------------------+ + | ext | Type of num | Numbering plan | octet 2 + +-----------------------------------------------------+ + | Number digit 2 | Number digit 1 | octet 3 + +-----------------------------------------------------+ + | Number digit 4 | Number digit 3 | octet 4 + +-----------------------------------------------------+ + : : : + +-----------------------------------------------------+
From: Holger Hans Peter Freyther holger@moiji-mobile.com
--- openbsc/doc/sgsn-remote-protocol.txt | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
diff --git a/openbsc/doc/sgsn-remote-protocol.txt b/openbsc/doc/sgsn-remote-protocol.txt index 88a384e..6a93169 100644 --- a/openbsc/doc/sgsn-remote-protocol.txt +++ b/openbsc/doc/sgsn-remote-protocol.txt @@ -280,6 +280,7 @@ This is a container for information elements describing a single PDP. 10 PDP context id big endian int, 1-N C TLV 3 11 PDP type 4.2.4 C TLV 4 12 Access point name 04.08, 10.5.6.1 C TLV 3-102 + 14 Quality Of Service ?? O TLV 1-20
The conditional IE are mandantory unless mentioned otherwise.
@@ -359,6 +360,7 @@ IEI that shall be used for the encoding. | 0x11 PDP type 4.2.4 | | 0x12 APN 04.08, 10.5.6.1 | | 0x13 MSISDN ISDN-AddressString/octet | + | 0x14 QoS octet string | | 0x20 RAND octet string | | 0x21 SRES octet string | | 0x22 Kc octet string | @@ -420,3 +422,19 @@ BCD Number in GSM 04.08. +-----------------------------------------------------+ : : : +-----------------------------------------------------+ + + +4.2.11 Quality of Service Subscribed Service + +QoS for the PDP context to be used by the SGSN/GGSN +communication. + + + 8 7 6 5 4 3 2 1 + +-----------------------------------------------------+ + | | IEI | octet 1 + +-----------------------------------------------------+ + | Length of IE contents | octet 2 + +-----------------------------------------------------+ + : : : + +-----------------------------------------------------+
From: Holger Hans Peter Freyther holger@moiji-mobile.com
--- openbsc/include/openbsc/gprs_gsup_messages.h | 4 ++++ openbsc/src/gprs/gprs_gsup_messages.c | 10 ++++++++++ openbsc/tests/gprs/gprs_test.c | 2 ++ 3 files changed, 16 insertions(+)
diff --git a/openbsc/include/openbsc/gprs_gsup_messages.h b/openbsc/include/openbsc/gprs_gsup_messages.h index 9857b97..937733f 100644 --- a/openbsc/include/openbsc/gprs_gsup_messages.h +++ b/openbsc/include/openbsc/gprs_gsup_messages.h @@ -29,6 +29,7 @@
#define GPRS_GSUP_MAX_NUM_PDP_INFO 10 /* GSM 09.02 limits this to 50 */ #define GPRS_GSUP_MAX_NUM_AUTH_INFO 5 +#define GPRS_GSUP_MAX_MSISDN_LEN 9
#define GPRS_GSUP_PDP_TYPE_SIZE 2
@@ -43,6 +44,7 @@ enum gprs_gsup_iei { GPRS_GSUP_PDP_CONTEXT_ID_IE = 0x10, GPRS_GSUP_PDP_TYPE_IE = 0x11, GPRS_GSUP_ACCESS_POINT_NAME_IE = 0x12, + GPRS_GSUP_MSISDN_IE = 0x13, GPRS_GSUP_RAND_IE = 0x20, GPRS_GSUP_SRES_IE = 0x21, GPRS_GSUP_KC_IE = 0x22 @@ -102,6 +104,8 @@ struct gprs_gsup_message { size_t num_auth_tuples; struct gprs_gsup_pdp_info pdp_infos[GPRS_GSUP_MAX_NUM_PDP_INFO]; size_t num_pdp_infos; + const uint8_t *msisdn_enc; + size_t msisdn_enc_len; };
int gprs_gsup_decode(const uint8_t *data, size_t data_len, diff --git a/openbsc/src/gprs/gprs_gsup_messages.c b/openbsc/src/gprs/gprs_gsup_messages.c index 9d9b6be..be8e823 100644 --- a/openbsc/src/gprs/gprs_gsup_messages.c +++ b/openbsc/src/gprs/gprs_gsup_messages.c @@ -2,6 +2,7 @@
/* * (C) 2014 by Sysmocom s.f.m.c. GmbH + * (C) 2015 by Holger Hans Peter Freyther * All Rights Reserved * * Author: Jacob Erlbeck @@ -291,6 +292,10 @@ int gprs_gsup_decode(const uint8_t *const_data, size_t data_len, gsup_msg->auth_tuples[gsup_msg->num_auth_tuples++] = auth_info; break; + case GPRS_GSUP_MSISDN_IE: + gsup_msg->msisdn_enc = value; + gsup_msg->msisdn_enc_len = value_len; + break; default: LOGP(DGPRS, LOGL_NOTICE, "GSUP IE type %d unknown\n", iei); @@ -415,4 +420,9 @@ void gprs_gsup_encode(struct msgb *msg, const struct gprs_gsup_message *gsup_msg
encode_auth_info(msg, GPRS_GSUP_AUTH_TUPLE_IE, auth_info); } + + if (gsup_msg->msisdn_enc) + msgb_tlv_put(msg, GPRS_GSUP_MSISDN_IE, + gsup_msg->msisdn_enc_len, gsup_msg->msisdn_enc); + } diff --git a/openbsc/tests/gprs/gprs_test.c b/openbsc/tests/gprs/gprs_test.c index 0ae06e7..555d657 100644 --- a/openbsc/tests/gprs/gprs_test.c +++ b/openbsc/tests/gprs/gprs_test.c @@ -452,6 +452,8 @@ static void test_gsup_messages_dec_enc(void) 0x10, 0x01, 0x02, 0x11, 0x02, 0xf1, 0x21, /* IPv4 */ 0x12, 0x08, 0x03, 'f', 'o', 'o', 0x03, 'a', 'p', 'n', + 0x13, 0x07, /* MSISDN of the subscriber */ + 0x91, 0x94, 0x61, 0x46, 0x32, 0x24, 0x43, };
static const uint8_t location_cancellation_req[] = {
From: Holger Hans Peter Freyther holger@moiji-mobile.com
--- openbsc/include/openbsc/gprs_gsup_messages.h | 3 +++ openbsc/src/gprs/gprs_gsup_messages.c | 10 ++++++++++ openbsc/tests/gprs/gprs_test.c | 3 ++- 3 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/openbsc/include/openbsc/gprs_gsup_messages.h b/openbsc/include/openbsc/gprs_gsup_messages.h index 937733f..701070a 100644 --- a/openbsc/include/openbsc/gprs_gsup_messages.h +++ b/openbsc/include/openbsc/gprs_gsup_messages.h @@ -45,6 +45,7 @@ enum gprs_gsup_iei { GPRS_GSUP_PDP_TYPE_IE = 0x11, GPRS_GSUP_ACCESS_POINT_NAME_IE = 0x12, GPRS_GSUP_MSISDN_IE = 0x13, + GPRS_GSUP_PDP_QOS_IE = 0x14, GPRS_GSUP_RAND_IE = 0x20, GPRS_GSUP_SRES_IE = 0x21, GPRS_GSUP_KC_IE = 0x22 @@ -91,6 +92,8 @@ struct gprs_gsup_pdp_info { uint16_t pdp_type; const uint8_t *apn_enc; size_t apn_enc_len; + const uint8_t *qos_enc; + size_t qos_enc_len; };
struct gprs_gsup_message { diff --git a/openbsc/src/gprs/gprs_gsup_messages.c b/openbsc/src/gprs/gprs_gsup_messages.c index be8e823..a4b0617 100644 --- a/openbsc/src/gprs/gprs_gsup_messages.c +++ b/openbsc/src/gprs/gprs_gsup_messages.c @@ -94,6 +94,11 @@ static int decode_pdp_info(uint8_t *data, size_t data_len, pdp_info->apn_enc_len = value_len; break;
+ case GPRS_GSUP_PDP_QOS_IE: + pdp_info->qos_enc = value; + pdp_info->qos_enc_len = value_len; + break; + default: LOGP(DGPRS, LOGL_ERROR, "GSUP IE type %d not expected in PDP info\n", iei); @@ -331,6 +336,11 @@ static void encode_pdp_info(struct msgb *msg, enum gprs_gsup_iei iei, pdp_info->apn_enc_len, pdp_info->apn_enc); }
+ if (pdp_info->qos_enc) { + msgb_tlv_put(msg, GPRS_GSUP_PDP_QOS_IE, + pdp_info->qos_enc_len, pdp_info->qos_enc); + } + /* Update length field */ *len_field = msgb_length(msg) - old_len; } diff --git a/openbsc/tests/gprs/gprs_test.c b/openbsc/tests/gprs/gprs_test.c index 555d657..ffe0220 100644 --- a/openbsc/tests/gprs/gprs_test.c +++ b/openbsc/tests/gprs/gprs_test.c @@ -444,10 +444,11 @@ static void test_gsup_messages_dec_enc(void) 0x06, TEST_IMSI_IE, 0x04, 0x00, /* PDP info complete */ - 0x05, 0x12, + 0x05, 0x15, 0x10, 0x01, 0x01, 0x11, 0x02, 0xf1, 0x21, /* IPv4 */ 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n', + 0x14, 0x01, 0x02, 0x05, 0x11, 0x10, 0x01, 0x02, 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
From: Holger Hans Peter Freyther holger@moiji-mobile.com
The MSISDN should be present for "security" reasons in the first activation of a PDP context. Take the encoded MSISDN, store it for future use and then put it into the PDP activation request. --- openbsc/include/openbsc/gprs_sgsn.h | 3 +++ openbsc/src/gprs/gprs_subscriber.c | 14 ++++++++++++++ openbsc/src/gprs/sgsn_libgtp.c | 12 ++++++++++-- openbsc/tests/sgsn/sgsn_test.c | 9 +++++++++ 4 files changed, 36 insertions(+), 2 deletions(-)
diff --git a/openbsc/include/openbsc/gprs_sgsn.h b/openbsc/include/openbsc/gprs_sgsn.h index 2572ead..baa2d78 100644 --- a/openbsc/include/openbsc/gprs_sgsn.h +++ b/openbsc/include/openbsc/gprs_sgsn.h @@ -302,6 +302,9 @@ struct sgsn_subscriber_data { int auth_triplets_updated; struct llist_head pdp_list; int error_cause; + + uint8_t msisdn[9]; + size_t msisdn_len; };
#define SGSN_ERROR_CAUSE_NONE (-1) diff --git a/openbsc/src/gprs/gprs_subscriber.c b/openbsc/src/gprs/gprs_subscriber.c index 60f223a..52e7ba7 100644 --- a/openbsc/src/gprs/gprs_subscriber.c +++ b/openbsc/src/gprs/gprs_subscriber.c @@ -1,6 +1,7 @@ /* MS subscriber data handling */
/* (C) 2014 by sysmocom s.f.m.c. GmbH + * (C) 2015 by Holger Hans Peter Freyther * * All Rights Reserved * @@ -259,9 +260,22 @@ static struct sgsn_subscriber_pdp_data *gprs_subscr_pdp_data_get_by_id( static void gprs_subscr_gsup_insert_data(struct gsm_subscriber *subscr, struct gprs_gsup_message *gsup_msg) { + struct sgsn_subscriber_data *sdata = subscr->sgsn_data; unsigned idx; int rc;
+ if (gsup_msg->msisdn_enc) { + if (gsup_msg->msisdn_enc_len > sizeof(sdata->msisdn)) { + LOGP(DGPRS, LOGL_ERROR, "MSISDN too long (%zu)\n", + gsup_msg->msisdn_enc_len); + sdata->msisdn_len = 0; + } else { + memcpy(sdata->msisdn, gsup_msg->msisdn_enc, + gsup_msg->msisdn_enc_len); + sdata->msisdn_len = gsup_msg->msisdn_enc_len; + } + } + if (gsup_msg->pdp_info_compl) { rc = gprs_subscr_pdp_data_clear(subscr); if (rc > 0) diff --git a/openbsc/src/gprs/sgsn_libgtp.c b/openbsc/src/gprs/sgsn_libgtp.c index 455e8af..25b30d0 100644 --- a/openbsc/src/gprs/sgsn_libgtp.c +++ b/openbsc/src/gprs/sgsn_libgtp.c @@ -3,6 +3,7 @@
/* (C) 2010 by Harald Welte laforge@gnumonks.org * (C) 2010 by On-Waves + * (C) 2015 by Holger Hans Peter Freyther * All Rights Reserved * * This program is free software; you can redistribute it and/or modify @@ -45,6 +46,7 @@ #include <openbsc/gprs_llc.h> #include <openbsc/gprs_sgsn.h> #include <openbsc/gprs_gmm.h> +#include <openbsc/gsm_subscriber.h>
#include <gtp.h> #include <pdp.h> @@ -153,8 +155,14 @@ struct sgsn_pdp_ctx *sgsn_create_pdp_ctx(struct sgsn_ggsn_ctx *ggsn,
/* IMSI, TEID/TEIC, FLLU/FLLC, TID, NSAPI set in pdp_newpdp */
- /* FIXME: MSISDN in BCD format from mmctx */ - //pdp->msisdn.l/.v + /* Put the MSISDN in case we have it */ + if (mmctx->subscr) { + pdp->msisdn.l = mmctx->subscr->sgsn_data->msisdn_len; + if (pdp->msisdn.l > sizeof(pdp->msisdn.v)) + pdp->msisdn.l = sizeof(pdp->msisdn.l); + memcpy(pdp->msisdn.v, mmctx->subscr->sgsn_data->msisdn, + pdp->msisdn.l); + }
/* End User Address from GMM requested PDP address */ pdp->eua.l = TLVP_LEN(tp, OSMO_IE_GSM_REQ_PDP_ADDR); diff --git a/openbsc/tests/sgsn/sgsn_test.c b/openbsc/tests/sgsn/sgsn_test.c index 197be9d..f6f8cd6 100644 --- a/openbsc/tests/sgsn/sgsn_test.c +++ b/openbsc/tests/sgsn/sgsn_test.c @@ -414,6 +414,10 @@ static void test_subscriber_gsup(void) 0x02, 0x01, 0x07 /* GPRS not allowed */ };
+#define MSISDN 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 + + static const uint8_t s1_msisdn[] = { MSISDN }; + static const uint8_t update_location_res[] = { 0x06, TEST_GSUP_IMSI1_IE, @@ -426,8 +430,11 @@ static void test_subscriber_gsup(void) 0x10, 0x01, 0x02, 0x11, 0x02, 0xf1, 0x21, /* IPv4 */ 0x12, 0x08, 0x03, 'f', 'o', 'o', 0x03, 'a', 'p', 'n', + 0x13, 0x09, MSISDN, };
+#undef MSISDN + static const uint8_t update_location_err[] = { 0x05, TEST_GSUP_IMSI1_IE, @@ -534,6 +541,8 @@ static void test_subscriber_gsup(void) OSMO_ASSERT(last_updated_subscr == s1); OSMO_ASSERT(s1->flags & GPRS_SUBSCRIBER_ENABLE_PURGE); OSMO_ASSERT(s1->sgsn_data->error_cause == SGSN_ERROR_CAUSE_NONE); + OSMO_ASSERT(s1->sgsn_data->msisdn_len == sizeof(s1_msisdn)); + OSMO_ASSERT(memcmp(s1->sgsn_data->msisdn, s1_msisdn, sizeof(s1_msisdn)) == 0); OSMO_ASSERT(!llist_empty(&s1->sgsn_data->pdp_list)); pdpd = llist_entry(s1->sgsn_data->pdp_list.next, struct sgsn_subscriber_pdp_data, list);
From: Holger Hans Peter Freyther holger@moiji-mobile.com
* Fix QoS encoding as it forgot the Allocation/Retention policy * Use the qos_req as it is the only one encoded for GTPv1 and as 7.7.34 --- openbsc/include/openbsc/gprs_sgsn.h | 2 ++ openbsc/include/openbsc/gsm_04_08_gprs.h | 1 + openbsc/src/gprs/gprs_sgsn.c | 15 +++++++++++++++ openbsc/src/gprs/gprs_subscriber.c | 9 +++++++++ openbsc/src/gprs/sgsn_libgtp.c | 18 ++++++++++++++---- 5 files changed, 41 insertions(+), 4 deletions(-)
diff --git a/openbsc/include/openbsc/gprs_sgsn.h b/openbsc/include/openbsc/gprs_sgsn.h index baa2d78..7a429cd 100644 --- a/openbsc/include/openbsc/gprs_sgsn.h +++ b/openbsc/include/openbsc/gprs_sgsn.h @@ -294,6 +294,8 @@ struct sgsn_subscriber_pdp_data { unsigned int context_id; uint16_t pdp_type; char apn_str[GSM_APN_LENGTH]; + uint8_t qos_subscribed[20]; + size_t qos_subscribed_len; };
struct sgsn_subscriber_data { diff --git a/openbsc/include/openbsc/gsm_04_08_gprs.h b/openbsc/include/openbsc/gsm_04_08_gprs.h index 3eec983..f35d11b 100644 --- a/openbsc/include/openbsc/gsm_04_08_gprs.h +++ b/openbsc/include/openbsc/gsm_04_08_gprs.h @@ -100,6 +100,7 @@ enum gsm48_gprs_ie_sm { * but which we use to simplify internal APIs */ OSMO_IE_GSM_REQ_QOS = 0xfd, OSMO_IE_GSM_REQ_PDP_ADDR = 0xfe, + OSMO_IE_GSM_SUB_QOS = 0xff, };
/* Chapter 9.4.15 / Table 9.4.15 */ diff --git a/openbsc/src/gprs/gprs_sgsn.c b/openbsc/src/gprs/gprs_sgsn.c index 94c2b6f..711540e 100644 --- a/openbsc/src/gprs/gprs_sgsn.c +++ b/openbsc/src/gprs/gprs_sgsn.c @@ -582,6 +582,17 @@ void sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx) sgsn_auth_update(mmctx); }
+static void insert_qos(struct tlv_parsed *tp, struct sgsn_subscriber_pdp_data *pdp) +{ + tp->lv[OSMO_IE_GSM_SUB_QOS].len = pdp->qos_subscribed_len; + tp->lv[OSMO_IE_GSM_SUB_QOS].val = pdp->qos_subscribed; +} + +/** + * The tlv_parsed tp parameter will be modified to insert a + * OSMO_IE_GSM_SUB_QOS in case the data is available in the + * PDP context handling. + */ struct sgsn_ggsn_ctx *sgsn_mm_ctx_find_ggsn_ctx(struct sgsn_mm_ctx *mmctx, struct tlv_parsed *tp, enum gsm48_gsm_cause *gsm_cause) @@ -621,6 +632,7 @@ struct sgsn_ggsn_ctx *sgsn_mm_ctx_find_ggsn_ctx(struct sgsn_mm_ctx *mmctx, { allow_any_apn = 1; selected_apn_str = ""; + insert_qos(tp, pdp); continue; } if (!llist_empty(&sgsn_apn_ctxts)) { @@ -629,6 +641,7 @@ struct sgsn_ggsn_ctx *sgsn_mm_ctx_find_ggsn_ctx(struct sgsn_mm_ctx *mmctx, if (apn_ctx == NULL) continue; } + insert_qos(tp, pdp); selected_apn_str = pdp->apn_str; break; } @@ -636,11 +649,13 @@ struct sgsn_ggsn_ctx *sgsn_mm_ctx_find_ggsn_ctx(struct sgsn_mm_ctx *mmctx, /* Check whether the given APN is granted */ llist_for_each_entry(pdp, &mmctx->subscr->sgsn_data->pdp_list, list) { if (strcmp(pdp->apn_str, "*") == 0) { + insert_qos(tp, pdp); selected_apn_str = req_apn_str; allow_any_apn = 1; continue; } if (strcasecmp(pdp->apn_str, req_apn_str) == 0) { + insert_qos(tp, pdp); selected_apn_str = req_apn_str; break; } diff --git a/openbsc/src/gprs/gprs_subscriber.c b/openbsc/src/gprs/gprs_subscriber.c index 52e7ba7..c2a3ae1 100644 --- a/openbsc/src/gprs/gprs_subscriber.c +++ b/openbsc/src/gprs/gprs_subscriber.c @@ -295,6 +295,13 @@ static void gprs_subscr_gsup_insert_data(struct gsm_subscriber *subscr, continue; }
+ if (pdp_info->qos_enc_len > sizeof(pdp_data->qos_subscribed)) { + LOGGSUBSCRP(LOGL_ERROR, subscr, + "QoS info too long (%zu)\n", + pdp_info->qos_enc_len); + continue; + } + LOGGSUBSCRP(LOGL_INFO, subscr, "Will set PDP info, context id = %zu, APN = %s\n", ctx_id, osmo_hexdump(pdp_info->apn_enc, pdp_info->apn_enc_len)); @@ -310,6 +317,8 @@ static void gprs_subscr_gsup_insert_data(struct gsm_subscriber *subscr, pdp_data->pdp_type = pdp_info->pdp_type; gprs_apn_to_str(pdp_data->apn_str, pdp_info->apn_enc, pdp_info->apn_enc_len); + memcpy(pdp_data->qos_subscribed, pdp_info->qos_enc, pdp_info->qos_enc_len); + pdp_data->qos_subscribed_len = pdp_info->qos_enc_len; } }
diff --git a/openbsc/src/gprs/sgsn_libgtp.c b/openbsc/src/gprs/sgsn_libgtp.c index 25b30d0..dd02457 100644 --- a/openbsc/src/gprs/sgsn_libgtp.c +++ b/openbsc/src/gprs/sgsn_libgtp.c @@ -123,6 +123,8 @@ struct sgsn_pdp_ctx *sgsn_create_pdp_ctx(struct sgsn_ggsn_ctx *ggsn, struct sgsn_pdp_ctx *pctx; struct pdp_t *pdp; uint64_t imsi_ui64; + size_t qos_len; + const uint8_t *qos; int rc;
LOGP(DGPRS, LOGL_ERROR, "Create PDP Context\n"); @@ -188,12 +190,20 @@ struct sgsn_pdp_ctx *sgsn_create_pdp_ctx(struct sgsn_ggsn_ctx *ggsn, memcpy(pdp->pco_req.v, TLVP_VAL(tp, GSM48_IE_GSM_PROTO_CONF_OPT), pdp->pco_req.l);
- /* QoS options from GMM */ - pdp->qos_req.l = TLVP_LEN(tp, OSMO_IE_GSM_REQ_QOS); + /* QoS options from GMM or remote */ + if (TLVP_LEN(tp, OSMO_IE_GSM_SUB_QOS) > 0) { + qos_len = TLVP_LEN(tp, OSMO_IE_GSM_SUB_QOS); + qos = TLVP_VAL(tp, OSMO_IE_GSM_SUB_QOS); + } else { + qos_len = TLVP_LEN(tp, OSMO_IE_GSM_REQ_QOS); + qos = TLVP_VAL(tp, OSMO_IE_GSM_REQ_QOS); + } + + pdp->qos_req.l = qos_len + 1; if (pdp->qos_req.l > sizeof(pdp->qos_req.v)) pdp->qos_req.l = sizeof(pdp->qos_req.v); - memcpy(pdp->qos_req.v, TLVP_VAL(tp, OSMO_IE_GSM_REQ_QOS), - pdp->qos_req.l); + pdp->qos_req.v[0] = 0; /* Allocation/Retention policy */ + memcpy(&pdp->qos_req.v[1], qos, pdp->qos_req.l - 1);
/* SGSN address for control plane */ pdp->gsnlc.l = sizeof(sgsn->cfg.gtp_listenaddr.sin_addr);
From: Holger Hans Peter Freyther holger@moiji-mobile.com
If QoS is only three bytes it does not include the allocation/ retention policy. Otherwise it does. Copy it depending on that. We should have a macro for the clamping to reduce code duplication.
The insanity does come from the MAP data and this seems to be the easiest in terms of complexity. It is an array of bytes that is transported from MAPProxy to the SGSN and then simply forwarded. --- openbsc/src/gprs/sgsn_libgtp.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/openbsc/src/gprs/sgsn_libgtp.c b/openbsc/src/gprs/sgsn_libgtp.c index dd02457..5c0a0fd 100644 --- a/openbsc/src/gprs/sgsn_libgtp.c +++ b/openbsc/src/gprs/sgsn_libgtp.c @@ -199,11 +199,18 @@ struct sgsn_pdp_ctx *sgsn_create_pdp_ctx(struct sgsn_ggsn_ctx *ggsn, qos = TLVP_VAL(tp, OSMO_IE_GSM_REQ_QOS); }
- pdp->qos_req.l = qos_len + 1; - if (pdp->qos_req.l > sizeof(pdp->qos_req.v)) - pdp->qos_req.l = sizeof(pdp->qos_req.v); - pdp->qos_req.v[0] = 0; /* Allocation/Retention policy */ - memcpy(&pdp->qos_req.v[1], qos, pdp->qos_req.l - 1); + if (qos_len <= 3) { + pdp->qos_req.l = qos_len + 1; + if (pdp->qos_req.l > sizeof(pdp->qos_req.v)) + pdp->qos_req.l = sizeof(pdp->qos_req.v); + pdp->qos_req.v[0] = 0; /* Allocation/Retention policy */ + memcpy(&pdp->qos_req.v[1], qos, pdp->qos_req.l - 1); + } else { + pdp->qos_req.l = qos_len; + if (pdp->qos_req.l > sizeof(pdp->qos_req.v)) + pdp->qos_req.l = sizeof(pdp->qos_req.v); + memcpy(&pdp->qos_req, qos, pdp->qos_req.l); + }
/* SGSN address for control plane */ pdp->gsnlc.l = sizeof(sgsn->cfg.gtp_listenaddr.sin_addr);
From: Holger Hans Peter Freyther holger@moiji-mobile.com
--- openbsc/src/gprs/sgsn_vty.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/openbsc/src/gprs/sgsn_vty.c b/openbsc/src/gprs/sgsn_vty.c index 684204a..7ea8890 100644 --- a/openbsc/src/gprs/sgsn_vty.c +++ b/openbsc/src/gprs/sgsn_vty.c @@ -471,6 +471,11 @@ static void subscr_dump_full_vty(struct vty *vty, struct gsm_subscriber *subscr, if (subscr->tmsi != GSM_RESERVED_TMSI) vty_out(vty, " TMSI: %08X%s", subscr->tmsi, VTY_NEWLINE); + if (subscr->sgsn_data->msisdn_len > 0) + vty_out(vty, " MSISDN (BCD): %s%s", + osmo_hexdump(subscr->sgsn_data->msisdn, + subscr->sgsn_data->msisdn_len), + VTY_NEWLINE);
if (strlen(subscr->equipment.imei) > 0) vty_out(vty, " IMEI: %s%s", subscr->equipment.imei, VTY_NEWLINE);
From: Holger Hans Peter Freyther holger@moiji-mobile.com
--- openbsc/src/gprs/sgsn_vty.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/openbsc/src/gprs/sgsn_vty.c b/openbsc/src/gprs/sgsn_vty.c index 7ea8890..be575d3 100644 --- a/openbsc/src/gprs/sgsn_vty.c +++ b/openbsc/src/gprs/sgsn_vty.c @@ -500,8 +500,9 @@ static void subscr_dump_full_vty(struct vty *vty, struct gsm_subscriber *subscr, }
llist_for_each_entry(pdp, &subscr->sgsn_data->pdp_list, list) { - vty_out(vty, " PDP info: Id: %d, Type: 0x%04x, APN: '%s'%s", + vty_out(vty, " PDP info: Id: %d, Type: 0x%04x, APN: '%s' QoS: %s%s", pdp->context_id, pdp->pdp_type, pdp->apn_str, + osmo_hexdump(pdp->qos_subscribed, pdp->qos_subscribed_len), VTY_NEWLINE); }