diff options
author | Holger Hans Peter Freyther <holger@moiji-mobile.com> | 2015-05-24 12:32:36 +0800 |
---|---|---|
committer | Holger Hans Peter Freyther <holger@moiji-mobile.com> | 2015-05-24 12:32:36 +0800 |
commit | 5e4b88cbb2d754d691a858a3ff99bcdc7ed9c7ce (patch) | |
tree | ce3115b6ade0d7ced838163efa5b9e9f2627378b | |
parent | 0f7a279a06bf10e83b8f5fbadb6871eebabc7dc1 (diff) | |
parent | 8ee13e293739870364e83ea54d61818fb5e44381 (diff) |
Merge branch 'zecke/features/sgsn-hlr-number'
Store the hlr-Number for purgeMS and CDR handling
-rw-r--r-- | openbsc/doc/sgsn-remote-protocol.txt | 24 | ||||
-rw-r--r-- | openbsc/include/openbsc/gprs_gsup_messages.h | 3 | ||||
-rw-r--r-- | openbsc/include/openbsc/gprs_sgsn.h | 6 | ||||
-rw-r--r-- | openbsc/src/gprs/gprs_gmm.c | 38 | ||||
-rw-r--r-- | openbsc/src/gprs/gprs_gsup_messages.c | 8 | ||||
-rw-r--r-- | openbsc/src/gprs/gprs_subscriber.c | 18 | ||||
-rw-r--r-- | openbsc/src/gprs/sgsn_cdr.c | 8 | ||||
-rw-r--r-- | openbsc/src/gprs/sgsn_vty.c | 4 | ||||
-rw-r--r-- | openbsc/tests/gprs/gprs_test.c | 2 | ||||
-rw-r--r-- | openbsc/tests/sgsn/sgsn_test.c | 2 |
10 files changed, 108 insertions, 5 deletions
diff --git a/openbsc/doc/sgsn-remote-protocol.txt b/openbsc/doc/sgsn-remote-protocol.txt index acb24a5ef..6591d638e 100644 --- a/openbsc/doc/sgsn-remote-protocol.txt +++ b/openbsc/doc/sgsn-remote-protocol.txt @@ -120,6 +120,7 @@ Network peer -> SGSN Message type 4.2.1 M V 1 01 IMSI 4.2.9 M TLV 2-10 08 MSISDN 4.2.10 O TLV 0-9 + 09 HLR Number 4.2.12 O TLV 0-9 04 PDP info complete 4.2.8 O TLV 2 05 PDP info 4.2.3 1-10 TLV @@ -149,6 +150,7 @@ SGSN -> Network peer IEI Info Element Type Pres. Format Length Message type 4.2.1 M V 1 01 IMSI 4.2.9 M TLV 2-10 + 09 HLR Number 4.2.12 M TLV 0-9 3.2.10. Purge MS Error @@ -357,6 +359,7 @@ IEI that shall be used for the encoding. | 0x06 Cancel type 4.2.6 | | 0x07 Freeze P-TMSI 4.2.8 | | 0x08 MSISDN ISDN-AddressString/octet, 4.2.10 | + | 0x09 HLR Number 4.2.12 | | 0x10 PDP context id big endian int | | 0x11 PDP type 4.2.4 | | 0x12 APN 04.08, 10.5.6.1 | @@ -442,3 +445,24 @@ Priority and the reset are encoded as octets 3-N of 24.008. +-----------------------------------------------------+ : : : +-----------------------------------------------------+ + +4.2.12. HLR Number encoded as GSM 09.02 ISDN-AddressString + +The HLR Number is encoded as an ISDN-AddressString in GSM 09.02. It +will be stored by the SGSN can be used by the CDR module to keep a +record. + + 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 + +-----------------------------------------------------+ + : : : + +-----------------------------------------------------+ diff --git a/openbsc/include/openbsc/gprs_gsup_messages.h b/openbsc/include/openbsc/gprs_gsup_messages.h index 123e1fc05..8cbc809f7 100644 --- a/openbsc/include/openbsc/gprs_gsup_messages.h +++ b/openbsc/include/openbsc/gprs_gsup_messages.h @@ -42,6 +42,7 @@ enum gprs_gsup_iei { GPRS_GSUP_CANCEL_TYPE_IE = 0x06, GPRS_GSUP_FREEZE_PTMSI_IE = 0x07, GPRS_GSUP_MSISDN_IE = 0x08, + GPRS_GSUP_HLR_NUMBER_IE = 0x09, GPRS_GSUP_PDP_CONTEXT_ID_IE = 0x10, GPRS_GSUP_PDP_TYPE_IE = 0x11, GPRS_GSUP_ACCESS_POINT_NAME_IE = 0x12, @@ -109,6 +110,8 @@ struct gprs_gsup_message { size_t num_pdp_infos; const uint8_t *msisdn_enc; size_t msisdn_enc_len; + const uint8_t *hlr_enc; + size_t hlr_enc_len; }; int gprs_gsup_decode(const uint8_t *data, size_t data_len, diff --git a/openbsc/include/openbsc/gprs_sgsn.h b/openbsc/include/openbsc/gprs_sgsn.h index 4bbde9c44..8abe97c51 100644 --- a/openbsc/include/openbsc/gprs_sgsn.h +++ b/openbsc/include/openbsc/gprs_sgsn.h @@ -136,6 +136,9 @@ struct sgsn_mm_ctx { enum sgsn_auth_state auth_state; int is_authenticated; + /* the string representation of the current hlr */ + char hlr[GSM_EXTENSION_LENGTH]; + struct gsm_subscriber *subscr; }; @@ -312,6 +315,9 @@ struct sgsn_subscriber_data { uint8_t msisdn[9]; size_t msisdn_len; + + uint8_t hlr[9]; + size_t hlr_len; }; #define SGSN_ERROR_CAUSE_NONE (-1) diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c index 8ada3d41b..b17873e89 100644 --- a/openbsc/src/gprs/gprs_gmm.c +++ b/openbsc/src/gprs/gprs_gmm.c @@ -578,6 +578,43 @@ static void extract_subscr_msisdn(struct sgsn_mm_ctx *ctx) } } +static void extract_subscr_hlr(struct sgsn_mm_ctx *ctx) +{ + struct gsm_mncc_number called; + uint8_t hlr_number[sizeof(ctx->subscr->sgsn_data->hlr) + 1]; + + if (!ctx->subscr) + return; + + if (ctx->subscr->sgsn_data->hlr_len < 1) + return; + + /* prepare the data for the decoder */ + memset(&called, 0, sizeof(called)); + hlr_number[0] = ctx->subscr->sgsn_data->hlr_len; + memcpy(&hlr_number[1], ctx->subscr->sgsn_data->hlr, + ctx->subscr->sgsn_data->hlr_len); + + /* decode the string now */ + gsm48_decode_called(&called, hlr_number); + + if (called.plan != 1) { + LOGMMCTXP(LOGL_ERROR, ctx, + "Numbering plan(%d) not allowed\n", + called.plan); + return; + } + + if (called.type != 1) { + LOGMMCTXP(LOGL_ERROR, ctx, + "Numbering type(%d) not allowed\n", + called.type); + return; + } + + strncpy(&ctx->hlr[0], called.number, sizeof(ctx->hlr) - 1); +} + /* Check if we can already authorize a subscriber */ static int gsm48_gmm_authorize(struct sgsn_mm_ctx *ctx) { @@ -643,6 +680,7 @@ static int gsm48_gmm_authorize(struct sgsn_mm_ctx *ctx) case GSM48_MT_GMM_ATTACH_REQ: extract_subscr_msisdn(ctx); + extract_subscr_hlr(ctx); #ifdef PTMSI_ALLOC /* Start T3350 and re-transmit up to 5 times until ATTACH COMPLETE */ mmctx_timer_start(ctx, 3350, GSM0408_T3350_SECS); diff --git a/openbsc/src/gprs/gprs_gsup_messages.c b/openbsc/src/gprs/gprs_gsup_messages.c index cb14fa114..bdcff5f69 100644 --- a/openbsc/src/gprs/gprs_gsup_messages.c +++ b/openbsc/src/gprs/gprs_gsup_messages.c @@ -303,6 +303,11 @@ int gprs_gsup_decode(const uint8_t *const_data, size_t data_len, gsup_msg->msisdn_enc_len = value_len; break; + case GPRS_GSUP_HLR_NUMBER_IE: + gsup_msg->hlr_enc = value; + gsup_msg->hlr_enc_len = value_len; + break; + default: LOGP(DGPRS, LOGL_NOTICE, "GSUP IE type %d unknown\n", iei); @@ -394,6 +399,9 @@ void gprs_gsup_encode(struct msgb *msg, const struct gprs_gsup_message *gsup_msg if (gsup_msg->msisdn_enc) msgb_tlv_put(msg, GPRS_GSUP_MSISDN_IE, gsup_msg->msisdn_enc_len, gsup_msg->msisdn_enc); + if (gsup_msg->hlr_enc) + msgb_tlv_put(msg, GPRS_GSUP_HLR_NUMBER_IE, + gsup_msg->hlr_enc_len, gsup_msg->hlr_enc); if ((u8 = gsup_msg->cause)) msgb_tlv_put(msg, GPRS_GSUP_CAUSE_IE, sizeof(u8), &u8); diff --git a/openbsc/src/gprs/gprs_subscriber.c b/openbsc/src/gprs/gprs_subscriber.c index c2a3ae184..8231e8cd8 100644 --- a/openbsc/src/gprs/gprs_subscriber.c +++ b/openbsc/src/gprs/gprs_subscriber.c @@ -276,6 +276,18 @@ static void gprs_subscr_gsup_insert_data(struct gsm_subscriber *subscr, } } + if (gsup_msg->hlr_enc) { + if (gsup_msg->hlr_enc_len > sizeof(sdata->hlr)) { + LOGP(DGPRS, LOGL_ERROR, "HLR-Number too long (%zu)\n", + gsup_msg->hlr_enc_len); + sdata->hlr_len = 0; + } else { + memcpy(sdata->hlr, gsup_msg->hlr_enc, + gsup_msg->hlr_enc_len); + sdata->hlr_len = gsup_msg->hlr_enc_len; + } + } + if (gsup_msg->pdp_info_compl) { rc = gprs_subscr_pdp_data_clear(subscr); if (rc > 0) @@ -666,11 +678,17 @@ int gprs_subscr_rx_gsup_message(struct msgb *msg) int gprs_subscr_purge(struct gsm_subscriber *subscr) { + struct sgsn_subscriber_data *sdata = subscr->sgsn_data; struct gprs_gsup_message gsup_msg = {0}; LOGGSUBSCRP(LOGL_INFO, subscr, "purging MS subscriber\n"); gsup_msg.message_type = GPRS_GSUP_MSGT_PURGE_MS_REQUEST; + + /* Provide the HLR number in case it is known */ + gsup_msg.hlr_enc_len = sdata->hlr_len; + gsup_msg.hlr_enc = sdata->hlr; + return gprs_subscr_tx_gsup_message(subscr, &gsup_msg); } diff --git a/openbsc/src/gprs/sgsn_cdr.c b/openbsc/src/gprs/sgsn_cdr.c index 04084f5b2..d0cb71235 100644 --- a/openbsc/src/gprs/sgsn_cdr.c +++ b/openbsc/src/gprs/sgsn_cdr.c @@ -64,7 +64,7 @@ static void maybe_print_header(FILE *cdr_file) if (ftell(cdr_file) != 0) return; - fprintf(cdr_file, "timestamp,imsi,imei,msisdn,cell_id,lac,event,pdp_duration,ggsn_addr,sgsn_addr,apni,eua_addr,vol_in,vol_out,charging_id\n"); + fprintf(cdr_file, "timestamp,imsi,imei,msisdn,cell_id,lac,hlr,event,pdp_duration,ggsn_addr,sgsn_addr,apni,eua_addr,vol_in,vol_out,charging_id\n"); } static void cdr_log_mm(struct sgsn_instance *inst, const char *ev, @@ -87,7 +87,7 @@ static void cdr_log_mm(struct sgsn_instance *inst, const char *ev, maybe_print_header(cdr_file); gettimeofday(&tv, NULL); gmtime_r(&tv.tv_sec, &tm); - fprintf(cdr_file, "%04d%02d%02d%02d%02d%02d%03d,%s,%s,%s,%d,%d,%s\n", + fprintf(cdr_file, "%04d%02d%02d%02d%02d%02d%03d,%s,%s,%s,%d,%d,%s,%s\n", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, (int)(tv.tv_usec / 1000), @@ -96,6 +96,7 @@ static void cdr_log_mm(struct sgsn_instance *inst, const char *ev, mmctx->msisdn, mmctx->cell_id, mmctx->ra.lac, + mmctx->hlr, ev); fclose(cdr_file); @@ -171,7 +172,7 @@ static void cdr_log_pdp(struct sgsn_instance *inst, const char *ev, duration = tp.tv_sec - pdp->cdr_start.tv_sec; fprintf(cdr_file, - "%04d%02d%02d%02d%02d%02d%03d,%s,%s,%s,%d,%d,%s,%ld,%s,%s,%s,%s,%" PRIu64 ",%" PRIu64 ",%u\n", + "%04d%02d%02d%02d%02d%02d%03d,%s,%s,%s,%d,%d,%s,%s,%ld,%s,%s,%s,%s,%" PRIu64 ",%" PRIu64 ",%u\n", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, (int)(tv.tv_usec / 1000), @@ -180,6 +181,7 @@ static void cdr_log_pdp(struct sgsn_instance *inst, const char *ev, pdp->mm ? pdp->mm->msisdn : "N/A", pdp->mm ? pdp->mm->cell_id : -1, pdp->mm ? pdp->mm->ra.lac : -1, + pdp->mm ? pdp->mm->hlr : "N/A", ev, (unsigned long ) duration, ggsn_addr, diff --git a/openbsc/src/gprs/sgsn_vty.c b/openbsc/src/gprs/sgsn_vty.c index 8b6e3ec29..b7023adb2 100644 --- a/openbsc/src/gprs/sgsn_vty.c +++ b/openbsc/src/gprs/sgsn_vty.c @@ -315,8 +315,8 @@ static void vty_dump_mmctx(struct vty *vty, const char *pfx, { vty_out(vty, "%sMM Context for IMSI %s, IMEI %s, P-TMSI %08x%s", pfx, mm->imsi, mm->imei, mm->p_tmsi, VTY_NEWLINE); - vty_out(vty, "%s MSISDN: %s, TLLI: %08x%s", pfx, mm->msisdn, - mm->tlli, VTY_NEWLINE); + vty_out(vty, "%s MSISDN: %s, TLLI: %08x%s HLR: %s", + pfx, mm->msisdn, mm->tlli, mm->hlr, VTY_NEWLINE); vty_out(vty, "%s MM State: %s, Routeing Area: %u-%u-%u-%u, " "Cell ID: %u%s", pfx, get_value_string(gprs_mm_st_strs, mm->mm_state), diff --git a/openbsc/tests/gprs/gprs_test.c b/openbsc/tests/gprs/gprs_test.c index bbd1d8ab3..c78b98ab5 100644 --- a/openbsc/tests/gprs/gprs_test.c +++ b/openbsc/tests/gprs/gprs_test.c @@ -445,6 +445,8 @@ static void test_gsup_messages_dec_enc(void) TEST_IMSI_IE, 0x08, 0x07, /* MSISDN of the subscriber */ 0x91, 0x94, 0x61, 0x46, 0x32, 0x24, 0x43, + 0x09, 0x07, /* HLR-Number of the subscriber */ + 0x91, 0x83, 0x52, 0x38, 0x48, 0x83, 0x93, 0x04, 0x00, /* PDP info complete */ 0x05, 0x15, 0x10, 0x01, 0x01, diff --git a/openbsc/tests/sgsn/sgsn_test.c b/openbsc/tests/sgsn/sgsn_test.c index 879dfe36e..a06c1532a 100644 --- a/openbsc/tests/sgsn/sgsn_test.c +++ b/openbsc/tests/sgsn/sgsn_test.c @@ -1155,6 +1155,8 @@ int my_subscr_request_update_gsup_auth(struct sgsn_mm_ctx *mmctx) { 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n', 0x08, 0x07, /* MSISDN 49166213323 encoded */ 0x91, 0x94, 0x61, 0x26, 0x31, 0x23, 0xF3, + 0x09, 0x07, /* MSISDN 38166213323 encoded */ + 0x91, 0x83, 0x61, 0x26, 0x31, 0x23, 0xF3, }; OSMO_ASSERT(!mmctx || mmctx->subscr); |