mirror of
				https://github.com/nextepc/nextepc-oss.git
				synced 2025-11-04 05:43:13 +00:00 
			
		
		
		
	If HSS/UDR gets MSISDN, AMF/MME -> SMF/SGW [#464]
This commit is contained in:
		@@ -233,14 +233,14 @@ char *ogs_supi_from_suci(char *suci)
 | 
				
			|||||||
    return supi;
 | 
					    return supi;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
char *ogs_supi_get_type(char *supi)
 | 
					char *ogs_id_get_type(char *str)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    char *saveptr = NULL;
 | 
					    char *saveptr = NULL;
 | 
				
			||||||
    char *p, *tmp;
 | 
					    char *p, *tmp;
 | 
				
			||||||
    char *type = NULL;
 | 
					    char *type = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ogs_assert(supi);
 | 
					    ogs_assert(str);
 | 
				
			||||||
    tmp = ogs_strdup(supi);
 | 
					    tmp = ogs_strdup(str);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    p = strtok_r(tmp, "-", &saveptr);
 | 
					    p = strtok_r(tmp, "-", &saveptr);
 | 
				
			||||||
    ogs_assert(p);
 | 
					    ogs_assert(p);
 | 
				
			||||||
@@ -250,14 +250,14 @@ char *ogs_supi_get_type(char *supi)
 | 
				
			|||||||
    return type;
 | 
					    return type;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
char *ogs_supi_get_id(char *supi)
 | 
					char *ogs_id_get_value(char *str)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    char *saveptr = NULL;
 | 
					    char *saveptr = NULL;
 | 
				
			||||||
    char *p, *tmp;
 | 
					    char *p, *tmp;
 | 
				
			||||||
    char *ueid = NULL;
 | 
					    char *ueid = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ogs_assert(supi);
 | 
					    ogs_assert(str);
 | 
				
			||||||
    tmp = ogs_strdup(supi);
 | 
					    tmp = ogs_strdup(str);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    p = strtok_r(tmp, "-", &saveptr);
 | 
					    p = strtok_r(tmp, "-", &saveptr);
 | 
				
			||||||
    ogs_assert(p);
 | 
					    ogs_assert(p);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -47,6 +47,10 @@ extern "C" {
 | 
				
			|||||||
#define OGS_MAX_IMEISV_LEN              \
 | 
					#define OGS_MAX_IMEISV_LEN              \
 | 
				
			||||||
    OGS_BCD_TO_BUFFER_LEN(OGS_MAX_IMEISV_BCD_LEN)
 | 
					    OGS_BCD_TO_BUFFER_LEN(OGS_MAX_IMEISV_BCD_LEN)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define OGS_MAX_MSISDN_BCD_LEN          15
 | 
				
			||||||
 | 
					#define OGS_MAX_MSISDN_LEN              \
 | 
				
			||||||
 | 
					    OGS_BCD_TO_BUFFER_LEN(OGS_MAX_MSISDN_BCD_LEN)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define OGS_MAX_NUM_OF_ENB_ID           16
 | 
					#define OGS_MAX_NUM_OF_ENB_ID           16
 | 
				
			||||||
#define OGS_MAX_NUM_OF_APN              16
 | 
					#define OGS_MAX_NUM_OF_APN              16
 | 
				
			||||||
#define OGS_MAX_NUM_OF_HOSTNAME         16
 | 
					#define OGS_MAX_NUM_OF_HOSTNAME         16
 | 
				
			||||||
@@ -169,8 +173,13 @@ ogs_amf_id_t *ogs_amf_id_build(ogs_amf_id_t *amf_id,
 | 
				
			|||||||
/************************************
 | 
					/************************************
 | 
				
			||||||
 * SUPI/SUCI                       */
 | 
					 * SUPI/SUCI                       */
 | 
				
			||||||
char *ogs_supi_from_suci(char *suci);
 | 
					char *ogs_supi_from_suci(char *suci);
 | 
				
			||||||
char *ogs_supi_get_type(char *supi);
 | 
					
 | 
				
			||||||
char *ogs_supi_get_id(char *supi);
 | 
					/************************************
 | 
				
			||||||
 | 
					 * SUPI/GPSI                       */
 | 
				
			||||||
 | 
					#define OGS_ID_SUPI_TYPE_IMSI "imsi"
 | 
				
			||||||
 | 
					#define OGS_ID_GPSI_TYPE_MSISDN "msisdn"
 | 
				
			||||||
 | 
					char *ogs_id_get_type(char *str);
 | 
				
			||||||
 | 
					char *ogs_id_get_value(char *str);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/************************************
 | 
					/************************************
 | 
				
			||||||
 * TAI Structure                    */
 | 
					 * TAI Structure                    */
 | 
				
			||||||
@@ -507,6 +516,14 @@ typedef struct ogs_subscription_data_s {
 | 
				
			|||||||
    uint32_t                context_identifier;             /* default APN */
 | 
					    uint32_t                context_identifier;             /* default APN */
 | 
				
			||||||
    ogs_pdn_t               pdn[OGS_MAX_NUM_OF_SESS];
 | 
					    ogs_pdn_t               pdn[OGS_MAX_NUM_OF_SESS];
 | 
				
			||||||
    int                     num_of_pdn;
 | 
					    int                     num_of_pdn;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define OGS_MAX_NUM_OF_MSISDN                                   4
 | 
				
			||||||
 | 
					    int num_of_msisdn;
 | 
				
			||||||
 | 
					    struct {
 | 
				
			||||||
 | 
					        uint8_t buf[OGS_MAX_MSISDN_LEN];
 | 
				
			||||||
 | 
					        int len;
 | 
				
			||||||
 | 
					        char bcd[OGS_MAX_MSISDN_BCD_LEN+1];
 | 
				
			||||||
 | 
					    } msisdn[OGS_MAX_NUM_OF_MSISDN];
 | 
				
			||||||
} ogs_subscription_data_t;
 | 
					} ogs_subscription_data_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -192,7 +192,7 @@ void ogs_kdf_kamf(char *supi, uint8_t *abba, uint8_t abba_len,
 | 
				
			|||||||
    ogs_assert(kamf);
 | 
					    ogs_assert(kamf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    memset(param, 0, sizeof(param));
 | 
					    memset(param, 0, sizeof(param));
 | 
				
			||||||
    param[0].buf = (uint8_t *)ogs_supi_get_id(supi);
 | 
					    param[0].buf = (uint8_t *)ogs_id_get_value(supi);
 | 
				
			||||||
    ogs_assert(param[0].buf);
 | 
					    ogs_assert(param[0].buf);
 | 
				
			||||||
    param[0].len = strlen((char *)param[0].buf);
 | 
					    param[0].len = strlen((char *)param[0].buf);
 | 
				
			||||||
    param[1].buf = abba;
 | 
					    param[1].buf = abba;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -38,9 +38,9 @@ int ogs_dbi_auth_info(char *supi, ogs_dbi_auth_info_t *auth_info)
 | 
				
			|||||||
    ogs_assert(supi);
 | 
					    ogs_assert(supi);
 | 
				
			||||||
    ogs_assert(auth_info);
 | 
					    ogs_assert(auth_info);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    supi_type = ogs_supi_get_type(supi);
 | 
					    supi_type = ogs_id_get_type(supi);
 | 
				
			||||||
    ogs_assert(supi_type);
 | 
					    ogs_assert(supi_type);
 | 
				
			||||||
    supi_id = ogs_supi_get_id(supi);
 | 
					    supi_id = ogs_id_get_value(supi);
 | 
				
			||||||
    ogs_assert(supi_id);
 | 
					    ogs_assert(supi_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    query = BCON_NEW(supi_type, BCON_UTF8(supi_id));
 | 
					    query = BCON_NEW(supi_type, BCON_UTF8(supi_id));
 | 
				
			||||||
@@ -121,9 +121,9 @@ int ogs_dbi_update_sqn(char *supi, uint64_t sqn)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    ogs_assert(supi);
 | 
					    ogs_assert(supi);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    supi_type = ogs_supi_get_type(supi);
 | 
					    supi_type = ogs_id_get_type(supi);
 | 
				
			||||||
    ogs_assert(supi_type);
 | 
					    ogs_assert(supi_type);
 | 
				
			||||||
    supi_id = ogs_supi_get_id(supi);
 | 
					    supi_id = ogs_id_get_value(supi);
 | 
				
			||||||
    ogs_assert(supi_id);
 | 
					    ogs_assert(supi_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    query = BCON_NEW(supi_type, BCON_UTF8(supi_id));
 | 
					    query = BCON_NEW(supi_type, BCON_UTF8(supi_id));
 | 
				
			||||||
@@ -161,9 +161,9 @@ int ogs_dbi_increment_sqn(char *supi)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    ogs_assert(supi);
 | 
					    ogs_assert(supi);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    supi_type = ogs_supi_get_type(supi);
 | 
					    supi_type = ogs_id_get_type(supi);
 | 
				
			||||||
    ogs_assert(supi_type);
 | 
					    ogs_assert(supi_type);
 | 
				
			||||||
    supi_id = ogs_supi_get_id(supi);
 | 
					    supi_id = ogs_id_get_value(supi);
 | 
				
			||||||
    ogs_assert(supi_id);
 | 
					    ogs_assert(supi_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    query = BCON_NEW(supi_type, BCON_UTF8(supi_id));
 | 
					    query = BCON_NEW(supi_type, BCON_UTF8(supi_id));
 | 
				
			||||||
@@ -221,9 +221,9 @@ int ogs_dbi_subscription_data(char *supi,
 | 
				
			|||||||
    ogs_assert(subscription_data);
 | 
					    ogs_assert(subscription_data);
 | 
				
			||||||
    ogs_assert(supi);
 | 
					    ogs_assert(supi);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    supi_type = ogs_supi_get_type(supi);
 | 
					    supi_type = ogs_id_get_type(supi);
 | 
				
			||||||
    ogs_assert(supi_type);
 | 
					    ogs_assert(supi_type);
 | 
				
			||||||
    supi_id = ogs_supi_get_id(supi);
 | 
					    supi_id = ogs_id_get_value(supi);
 | 
				
			||||||
    ogs_assert(supi_id);
 | 
					    ogs_assert(supi_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    query = BCON_NEW(supi_type, BCON_UTF8(supi_id));
 | 
					    query = BCON_NEW(supi_type, BCON_UTF8(supi_id));
 | 
				
			||||||
@@ -259,11 +259,36 @@ int ogs_dbi_subscription_data(char *supi,
 | 
				
			|||||||
    memset(subscription_data, 0, sizeof(ogs_subscription_data_t));
 | 
					    memset(subscription_data, 0, sizeof(ogs_subscription_data_t));
 | 
				
			||||||
    while (bson_iter_next(&iter)) {
 | 
					    while (bson_iter_next(&iter)) {
 | 
				
			||||||
        const char *key = bson_iter_key(&iter);
 | 
					        const char *key = bson_iter_key(&iter);
 | 
				
			||||||
        if (!strcmp(key, "access_restriction_data") &&
 | 
					        if (!strcmp(key, "msisdn") &&
 | 
				
			||||||
 | 
					            BSON_ITER_HOLDS_ARRAY(&iter)) {
 | 
				
			||||||
 | 
					            int msisdn_index = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            bson_iter_recurse(&iter, &child1_iter);
 | 
				
			||||||
 | 
					            while (bson_iter_next(&child1_iter)) {
 | 
				
			||||||
 | 
					                const char *child1_key = bson_iter_key(&child1_iter);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                ogs_assert(child1_key);
 | 
				
			||||||
 | 
					                msisdn_index = atoi(child1_key);
 | 
				
			||||||
 | 
					                ogs_assert(msisdn_index < OGS_MAX_NUM_OF_MSISDN);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (BSON_ITER_HOLDS_UTF8(&child1_iter)) {
 | 
				
			||||||
 | 
					                    utf8 = bson_iter_utf8(&child1_iter, &length);
 | 
				
			||||||
 | 
					                    ogs_cpystrn(subscription_data->msisdn[msisdn_index].bcd,
 | 
				
			||||||
 | 
					                            utf8, ogs_min(length, OGS_MAX_MSISDN_BCD_LEN)+1);
 | 
				
			||||||
 | 
					                    ogs_bcd_to_buffer(
 | 
				
			||||||
 | 
					                            subscription_data->msisdn[msisdn_index].bcd,
 | 
				
			||||||
 | 
					                            subscription_data->msisdn[msisdn_index].buf,
 | 
				
			||||||
 | 
					                            &subscription_data->msisdn[msisdn_index].len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    msisdn_index++;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            subscription_data->num_of_msisdn = msisdn_index;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        } else if (!strcmp(key, "access_restriction_data") &&
 | 
				
			||||||
            BSON_ITER_HOLDS_INT32(&iter)) {
 | 
					            BSON_ITER_HOLDS_INT32(&iter)) {
 | 
				
			||||||
            subscription_data->access_restriction_data =
 | 
					            subscription_data->access_restriction_data =
 | 
				
			||||||
                bson_iter_int32(&iter);
 | 
					                bson_iter_int32(&iter);
 | 
				
			||||||
 | 
					 | 
				
			||||||
        } else if (!strcmp(key, "subscriber_status") &&
 | 
					        } else if (!strcmp(key, "subscriber_status") &&
 | 
				
			||||||
            BSON_ITER_HOLDS_INT32(&iter)) {
 | 
					            BSON_ITER_HOLDS_INT32(&iter)) {
 | 
				
			||||||
            subscription_data->subscriber_status =
 | 
					            subscription_data->subscriber_status =
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,8 +28,6 @@
 | 
				
			|||||||
extern "C" {
 | 
					extern "C" {
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define OGS_DBI_SUPI_TYPE_IMSI  "imsi"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef struct ogs_dbi_auth_info_s {
 | 
					typedef struct ogs_dbi_auth_info_s {
 | 
				
			||||||
    uint8_t       k[OGS_KEY_LEN];
 | 
					    uint8_t       k[OGS_KEY_LEN];
 | 
				
			||||||
    uint8_t       use_opc;
 | 
					    uint8_t       use_opc;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -72,6 +72,9 @@ struct dict_object *ogs_diam_s6a_terminal_information = NULL;
 | 
				
			|||||||
struct dict_object *ogs_diam_s6a_imei = NULL;
 | 
					struct dict_object *ogs_diam_s6a_imei = NULL;
 | 
				
			||||||
struct dict_object *ogs_diam_s6a_software_version = NULL;
 | 
					struct dict_object *ogs_diam_s6a_software_version = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dict_object *ogs_diam_s6a_msisdn = NULL;
 | 
				
			||||||
 | 
					struct dict_object *ogs_diam_s6a_a_msisdn = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern int ogs_dict_s6a_entry(char *conffile);
 | 
					extern int ogs_dict_s6a_entry(char *conffile);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int ogs_diam_s6a_init(void)
 | 
					int ogs_diam_s6a_init(void)
 | 
				
			||||||
@@ -135,5 +138,8 @@ int ogs_diam_s6a_init(void)
 | 
				
			|||||||
    CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "IMEI", &ogs_diam_s6a_imei);
 | 
					    CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "IMEI", &ogs_diam_s6a_imei);
 | 
				
			||||||
    CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Software-Version", &ogs_diam_s6a_software_version);
 | 
					    CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Software-Version", &ogs_diam_s6a_software_version);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "MSISDN", &ogs_diam_s6a_msisdn);
 | 
				
			||||||
 | 
					    CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "A-MSISDN", &ogs_diam_s6a_a_msisdn);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -112,6 +112,9 @@ extern struct dict_object *ogs_diam_s6a_terminal_information;
 | 
				
			|||||||
extern struct dict_object *ogs_diam_s6a_imei;
 | 
					extern struct dict_object *ogs_diam_s6a_imei;
 | 
				
			||||||
extern struct dict_object *ogs_diam_s6a_software_version;
 | 
					extern struct dict_object *ogs_diam_s6a_software_version;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern struct dict_object *ogs_diam_s6a_msisdn;
 | 
				
			||||||
 | 
					extern struct dict_object *ogs_diam_s6a_a_msisdn;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct ogs_diam_e_utran_vector_s {
 | 
					typedef struct ogs_diam_e_utran_vector_s {
 | 
				
			||||||
    uint8_t                 xres[OGS_MAX_RES_LEN];
 | 
					    uint8_t                 xres[OGS_MAX_RES_LEN];
 | 
				
			||||||
    uint8_t                 xres_len;
 | 
					    uint8_t                 xres_len;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1139,6 +1139,7 @@ amf_ue_t *amf_ue_add(ran_ue_t *ran_ue)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void amf_ue_remove(amf_ue_t *amf_ue)
 | 
					void amf_ue_remove(amf_ue_t *amf_ue)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
    amf_event_t e;
 | 
					    amf_event_t e;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ogs_assert(amf_ue);
 | 
					    ogs_assert(amf_ue);
 | 
				
			||||||
@@ -1168,6 +1169,11 @@ void amf_ue_remove(amf_ue_t *amf_ue)
 | 
				
			|||||||
    if (amf_ue->pei)
 | 
					    if (amf_ue->pei)
 | 
				
			||||||
        ogs_free(amf_ue->pei);
 | 
					        ogs_free(amf_ue->pei);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (i = 0; i < amf_ue->num_of_msisdn; i++) {
 | 
				
			||||||
 | 
					        ogs_assert(amf_ue->msisdn[i]);
 | 
				
			||||||
 | 
					        ogs_free(amf_ue->msisdn[i]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (amf_ue->confirmation_url_for_5g_aka)
 | 
					    if (amf_ue->confirmation_url_for_5g_aka)
 | 
				
			||||||
        ogs_free(amf_ue->confirmation_url_for_5g_aka);
 | 
					        ogs_free(amf_ue->confirmation_url_for_5g_aka);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -257,6 +257,9 @@ struct amf_ue_s {
 | 
				
			|||||||
    char            imeisv_bcd[OGS_MAX_IMEISV_BCD_LEN+1];
 | 
					    char            imeisv_bcd[OGS_MAX_IMEISV_BCD_LEN+1];
 | 
				
			||||||
    ogs_nas_mobile_identity_imeisv_t nas_mobile_identity_imeisv;
 | 
					    ogs_nas_mobile_identity_imeisv_t nas_mobile_identity_imeisv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int             num_of_msisdn;
 | 
				
			||||||
 | 
					    char            *msisdn[OGS_MAX_NUM_OF_MSISDN];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    amf_m_tmsi_t    *m_tmsi;
 | 
					    amf_m_tmsi_t    *m_tmsi;
 | 
				
			||||||
    ogs_nas_5gs_guti_t guti;
 | 
					    ogs_nas_5gs_guti_t guti;
 | 
				
			||||||
    int             guti_present;
 | 
					    int             guti_present;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -25,6 +25,7 @@
 | 
				
			|||||||
#include "ngap-path.h"
 | 
					#include "ngap-path.h"
 | 
				
			||||||
#include "nausf-handler.h"
 | 
					#include "nausf-handler.h"
 | 
				
			||||||
#include "nsmf-handler.h"
 | 
					#include "nsmf-handler.h"
 | 
				
			||||||
 | 
					#include "nudm-handler.h"
 | 
				
			||||||
#include "sbi-path.h"
 | 
					#include "sbi-path.h"
 | 
				
			||||||
#include "amf-sm.h"
 | 
					#include "amf-sm.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -851,39 +852,7 @@ void gmm_state_initial_context_setup(ogs_fsm_t *s, amf_event_t *e)
 | 
				
			|||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                SWITCH(sbi_message->h.resource.component[1])
 | 
					                amf_nudm_sdm_handle_provisioned(amf_ue, sbi_message);
 | 
				
			||||||
                CASE(OGS_SBI_RESOURCE_NAME_AM_DATA)
 | 
					 | 
				
			||||||
                    if (sbi_message->AccessAndMobilitySubscriptionData) {
 | 
					 | 
				
			||||||
                        OpenAPI_ambr_rm_t *subscribed_ue_ambr =
 | 
					 | 
				
			||||||
                            sbi_message->AccessAndMobilitySubscriptionData->
 | 
					 | 
				
			||||||
                                subscribed_ue_ambr;
 | 
					 | 
				
			||||||
                        if (subscribed_ue_ambr) {
 | 
					 | 
				
			||||||
                            amf_ue->subscribed_ue_ambr.uplink =
 | 
					 | 
				
			||||||
                                ogs_sbi_bitrate_from_string(
 | 
					 | 
				
			||||||
                                        subscribed_ue_ambr->uplink);
 | 
					 | 
				
			||||||
                            amf_ue->subscribed_ue_ambr.downlink =
 | 
					 | 
				
			||||||
                                ogs_sbi_bitrate_from_string(
 | 
					 | 
				
			||||||
                                        subscribed_ue_ambr->downlink);
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    amf_ue_sbi_discover_and_send(OpenAPI_nf_type_UDM, amf_ue,
 | 
					 | 
				
			||||||
                        (char *)OGS_SBI_RESOURCE_NAME_SMF_SELECT_DATA,
 | 
					 | 
				
			||||||
                        amf_nudm_sdm_build_get);
 | 
					 | 
				
			||||||
                    break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                CASE(OGS_SBI_RESOURCE_NAME_SMF_SELECT_DATA)
 | 
					 | 
				
			||||||
                    amf_ue_sbi_discover_and_send(OpenAPI_nf_type_UDM, amf_ue,
 | 
					 | 
				
			||||||
                        (char *)OGS_SBI_RESOURCE_NAME_UE_CONTEXT_IN_SMF_DATA,
 | 
					 | 
				
			||||||
                        amf_nudm_sdm_build_get);
 | 
					 | 
				
			||||||
                    break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                CASE(OGS_SBI_RESOURCE_NAME_UE_CONTEXT_IN_SMF_DATA)
 | 
					 | 
				
			||||||
                    nas_5gs_send_accept(amf_ue);
 | 
					 | 
				
			||||||
                    break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                DEFAULT
 | 
					 | 
				
			||||||
                END
 | 
					 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            DEFAULT
 | 
					            DEFAULT
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,6 +24,7 @@ libamf_sources = files('''
 | 
				
			|||||||
    nausf-handler.c
 | 
					    nausf-handler.c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    nudm-build.c
 | 
					    nudm-build.c
 | 
				
			||||||
 | 
					    nudm-handler.c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    nsmf-build.c
 | 
					    nsmf-build.c
 | 
				
			||||||
    nsmf-handler.c
 | 
					    nsmf-handler.c
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -60,6 +60,12 @@ ogs_sbi_request_t *amf_nsmf_pdu_session_build_create_sm_context(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    SmContextCreateData.supi = amf_ue->supi;
 | 
					    SmContextCreateData.supi = amf_ue->supi;
 | 
				
			||||||
    SmContextCreateData.pei = amf_ue->pei;
 | 
					    SmContextCreateData.pei = amf_ue->pei;
 | 
				
			||||||
 | 
					    if (amf_ue->num_of_msisdn) {
 | 
				
			||||||
 | 
					        if (amf_ue->msisdn[0]) {
 | 
				
			||||||
 | 
					            SmContextCreateData.gpsi = ogs_msprintf("%s-%s",
 | 
				
			||||||
 | 
					                        OGS_ID_GPSI_TYPE_MSISDN, amf_ue->msisdn[0]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    SmContextCreateData.pdu_session_id = sess->psi;
 | 
					    SmContextCreateData.pdu_session_id = sess->psi;
 | 
				
			||||||
    SmContextCreateData.dnn = sess->dnn;
 | 
					    SmContextCreateData.dnn = sess->dnn;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -114,6 +120,8 @@ ogs_sbi_request_t *amf_nsmf_pdu_session_build_create_sm_context(
 | 
				
			|||||||
    ogs_free(header.resource.component[2]);
 | 
					    ogs_free(header.resource.component[2]);
 | 
				
			||||||
    if (s_nssai.sd)
 | 
					    if (s_nssai.sd)
 | 
				
			||||||
        ogs_free(s_nssai.sd);
 | 
					        ogs_free(s_nssai.sd);
 | 
				
			||||||
 | 
					    if (SmContextCreateData.gpsi)
 | 
				
			||||||
 | 
					        ogs_free(SmContextCreateData.gpsi);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return request;
 | 
					    return request;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										96
									
								
								src/amf/nudm-handler.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								src/amf/nudm-handler.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,96 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This file is part of Open5GS.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					 * it under the terms of the GNU Affero General Public License as published by
 | 
				
			||||||
 | 
					 * the Free Software Foundation, either version 3 of the License, or
 | 
				
			||||||
 | 
					 * (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 * GNU General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "nudm-handler.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "sbi-path.h"
 | 
				
			||||||
 | 
					#include "nas-path.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int amf_nudm_sdm_handle_provisioned(
 | 
				
			||||||
 | 
					        amf_ue_t *amf_ue, ogs_sbi_message_t *recvmsg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    ogs_assert(amf_ue);
 | 
				
			||||||
 | 
					    ogs_assert(recvmsg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    SWITCH(recvmsg->h.resource.component[1])
 | 
				
			||||||
 | 
					    CASE(OGS_SBI_RESOURCE_NAME_AM_DATA)
 | 
				
			||||||
 | 
					        if (recvmsg->AccessAndMobilitySubscriptionData) {
 | 
				
			||||||
 | 
					            OpenAPI_ambr_rm_t *subscribed_ue_ambr =
 | 
				
			||||||
 | 
					                recvmsg->AccessAndMobilitySubscriptionData->
 | 
				
			||||||
 | 
					                    subscribed_ue_ambr;
 | 
				
			||||||
 | 
					            OpenAPI_list_t *gpsiList =
 | 
				
			||||||
 | 
					                recvmsg->AccessAndMobilitySubscriptionData->gpsis;
 | 
				
			||||||
 | 
					            OpenAPI_lnode_t *node = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (subscribed_ue_ambr) {
 | 
				
			||||||
 | 
					                amf_ue->subscribed_ue_ambr.uplink =
 | 
				
			||||||
 | 
					                    ogs_sbi_bitrate_from_string(
 | 
				
			||||||
 | 
					                            subscribed_ue_ambr->uplink);
 | 
				
			||||||
 | 
					                amf_ue->subscribed_ue_ambr.downlink =
 | 
				
			||||||
 | 
					                    ogs_sbi_bitrate_from_string(
 | 
				
			||||||
 | 
					                            subscribed_ue_ambr->downlink);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (gpsiList) {
 | 
				
			||||||
 | 
					                amf_ue->num_of_msisdn = 0;
 | 
				
			||||||
 | 
					                OpenAPI_list_for_each(gpsiList, node) {
 | 
				
			||||||
 | 
					                    if (node->data) {
 | 
				
			||||||
 | 
					                        char *gpsi = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        gpsi = ogs_id_get_type(node->data);
 | 
				
			||||||
 | 
					                        ogs_assert(gpsi);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        if (strncmp(gpsi, OGS_ID_GPSI_TYPE_MSISDN,
 | 
				
			||||||
 | 
					                                    strlen(OGS_ID_GPSI_TYPE_MSISDN)) != 0) {
 | 
				
			||||||
 | 
					                            ogs_error("Unknown GPSI Type [%s]", gpsi);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        } else {
 | 
				
			||||||
 | 
					                            amf_ue->msisdn[amf_ue->num_of_msisdn] =
 | 
				
			||||||
 | 
					                                ogs_id_get_value(node->data);
 | 
				
			||||||
 | 
					                            ogs_assert(amf_ue->msisdn[amf_ue->num_of_msisdn]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                            amf_ue->num_of_msisdn++;
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        ogs_free(gpsi);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        amf_ue_sbi_discover_and_send(OpenAPI_nf_type_UDM, amf_ue,
 | 
				
			||||||
 | 
					            (char *)OGS_SBI_RESOURCE_NAME_SMF_SELECT_DATA,
 | 
				
			||||||
 | 
					            amf_nudm_sdm_build_get);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    CASE(OGS_SBI_RESOURCE_NAME_SMF_SELECT_DATA)
 | 
				
			||||||
 | 
					        amf_ue_sbi_discover_and_send(OpenAPI_nf_type_UDM, amf_ue,
 | 
				
			||||||
 | 
					            (char *)OGS_SBI_RESOURCE_NAME_UE_CONTEXT_IN_SMF_DATA,
 | 
				
			||||||
 | 
					            amf_nudm_sdm_build_get);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    CASE(OGS_SBI_RESOURCE_NAME_UE_CONTEXT_IN_SMF_DATA)
 | 
				
			||||||
 | 
					        nas_5gs_send_accept(amf_ue);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    DEFAULT
 | 
				
			||||||
 | 
					    END
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return OGS_OK;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										36
									
								
								src/amf/nudm-handler.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								src/amf/nudm-handler.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,36 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This file is part of Open5GS.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					 * it under the terms of the GNU Affero General Public License as published by
 | 
				
			||||||
 | 
					 * the Free Software Foundation, either version 3 of the License, or
 | 
				
			||||||
 | 
					 * (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 * GNU General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef AMF_NUDM_HANDLER_H
 | 
				
			||||||
 | 
					#define AMF_NUDM_HANDLER_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 | 
					extern "C" {
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "context.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int amf_nudm_sdm_handle_provisioned(
 | 
				
			||||||
 | 
					        amf_ue_t *amf_ue, ogs_sbi_message_t *message);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* AMF_NUDM_HANDLER_H */
 | 
				
			||||||
@@ -265,7 +265,7 @@ int hss_db_auth_info(char *imsi_bcd, ogs_dbi_auth_info_t *auth_info)
 | 
				
			|||||||
    ogs_assert(auth_info);
 | 
					    ogs_assert(auth_info);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ogs_thread_mutex_lock(&self.db_lock);
 | 
					    ogs_thread_mutex_lock(&self.db_lock);
 | 
				
			||||||
    supi = ogs_msprintf("%s-%s", OGS_DBI_SUPI_TYPE_IMSI, imsi_bcd);
 | 
					    supi = ogs_msprintf("%s-%s", OGS_ID_SUPI_TYPE_IMSI, imsi_bcd);
 | 
				
			||||||
    ogs_assert(supi);
 | 
					    ogs_assert(supi);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    rv = ogs_dbi_auth_info(supi, auth_info);
 | 
					    rv = ogs_dbi_auth_info(supi, auth_info);
 | 
				
			||||||
@@ -285,7 +285,7 @@ int hss_db_update_rand_and_sqn(
 | 
				
			|||||||
    ogs_assert(imsi_bcd);
 | 
					    ogs_assert(imsi_bcd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ogs_thread_mutex_lock(&self.db_lock);
 | 
					    ogs_thread_mutex_lock(&self.db_lock);
 | 
				
			||||||
    supi = ogs_msprintf("%s-%s", OGS_DBI_SUPI_TYPE_IMSI, imsi_bcd);
 | 
					    supi = ogs_msprintf("%s-%s", OGS_ID_SUPI_TYPE_IMSI, imsi_bcd);
 | 
				
			||||||
    ogs_assert(supi);
 | 
					    ogs_assert(supi);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    rv = ogs_dbi_update_sqn(supi, sqn);
 | 
					    rv = ogs_dbi_update_sqn(supi, sqn);
 | 
				
			||||||
@@ -304,7 +304,7 @@ int hss_db_increment_sqn(char *imsi_bcd)
 | 
				
			|||||||
    ogs_assert(imsi_bcd);
 | 
					    ogs_assert(imsi_bcd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ogs_thread_mutex_lock(&self.db_lock);
 | 
					    ogs_thread_mutex_lock(&self.db_lock);
 | 
				
			||||||
    supi = ogs_msprintf("%s-%s", OGS_DBI_SUPI_TYPE_IMSI, imsi_bcd);
 | 
					    supi = ogs_msprintf("%s-%s", OGS_ID_SUPI_TYPE_IMSI, imsi_bcd);
 | 
				
			||||||
    ogs_assert(supi);
 | 
					    ogs_assert(supi);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    rv = ogs_dbi_increment_sqn(supi);
 | 
					    rv = ogs_dbi_increment_sqn(supi);
 | 
				
			||||||
@@ -325,7 +325,7 @@ int hss_db_subscription_data(
 | 
				
			|||||||
    ogs_assert(subscription_data);
 | 
					    ogs_assert(subscription_data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ogs_thread_mutex_lock(&self.db_lock);
 | 
					    ogs_thread_mutex_lock(&self.db_lock);
 | 
				
			||||||
    supi = ogs_msprintf("%s-%s", OGS_DBI_SUPI_TYPE_IMSI, imsi_bcd);
 | 
					    supi = ogs_msprintf("%s-%s", OGS_ID_SUPI_TYPE_IMSI, imsi_bcd);
 | 
				
			||||||
    ogs_assert(supi);
 | 
					    ogs_assert(supi);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    rv = ogs_dbi_subscription_data(supi, subscription_data);
 | 
					    rv = ogs_dbi_subscription_data(supi, subscription_data);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -344,6 +344,7 @@ static int hss_ogs_diam_s6a_ulr_cb( struct msg **msg, struct avp *avp,
 | 
				
			|||||||
    ret = fd_msg_avp_hdr(avp, &hdr);
 | 
					    ret = fd_msg_avp_hdr(avp, &hdr);
 | 
				
			||||||
    ogs_assert(ret == 0);
 | 
					    ogs_assert(ret == 0);
 | 
				
			||||||
    if (!(hdr->avp_value->u32 & OGS_DIAM_S6A_ULR_SKIP_SUBSCRIBER_DATA)) {
 | 
					    if (!(hdr->avp_value->u32 & OGS_DIAM_S6A_ULR_SKIP_SUBSCRIBER_DATA)) {
 | 
				
			||||||
 | 
					        struct avp *avp_msisdn, *avp_a_msisdn;
 | 
				
			||||||
        struct avp *avp_access_restriction_data;
 | 
					        struct avp *avp_access_restriction_data;
 | 
				
			||||||
        struct avp *avp_subscriber_status, *avp_network_access_mode;
 | 
					        struct avp *avp_subscriber_status, *avp_network_access_mode;
 | 
				
			||||||
        struct avp *avp_ambr, *avp_max_bandwidth_ul, *avp_max_bandwidth_dl;
 | 
					        struct avp *avp_ambr, *avp_max_bandwidth_ul, *avp_max_bandwidth_dl;
 | 
				
			||||||
@@ -351,9 +352,44 @@ static int hss_ogs_diam_s6a_ulr_cb( struct msg **msg, struct avp *avp,
 | 
				
			|||||||
        int i;
 | 
					        int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* Set the Subscription Data */
 | 
					        /* Set the Subscription Data */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ret = fd_msg_avp_new(ogs_diam_s6a_subscription_data, 0, &avp);
 | 
					        ret = fd_msg_avp_new(ogs_diam_s6a_subscription_data, 0, &avp);
 | 
				
			||||||
        ogs_assert(ret == 0);
 | 
					        ogs_assert(ret == 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /*
 | 
				
			||||||
 | 
					         * TS29.328
 | 
				
			||||||
 | 
					         * 6.3.2 MSISDN AVP
 | 
				
			||||||
 | 
					         *
 | 
				
			||||||
 | 
					         * The MSISDN AVP is of type OctetString.
 | 
				
			||||||
 | 
					         * This AVP contains an MSISDN, in international number format
 | 
				
			||||||
 | 
					         * as described in ITU-T Rec E.164 [8], encoded as a TBCD-string,
 | 
				
			||||||
 | 
					         * i.e. digits from 0 through 9 are encoded 0000 to 1001;
 | 
				
			||||||
 | 
					         * 1111 is used as a filler when there is an odd number of digits;
 | 
				
			||||||
 | 
					         * bits 8 to 5 of octet n encode digit 2n;
 | 
				
			||||||
 | 
					         * bits 4 to 1 of octet n encode digit 2(n-1)+1.
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        if (subscription_data.num_of_msisdn >= 1)  {
 | 
				
			||||||
 | 
					            ret = fd_msg_avp_new(ogs_diam_s6a_msisdn, 0, &avp_msisdn);
 | 
				
			||||||
 | 
					            ogs_assert(ret == 0);
 | 
				
			||||||
 | 
					            val.os.data = subscription_data.msisdn[0].buf;
 | 
				
			||||||
 | 
					            val.os.len = subscription_data.msisdn[0].len;
 | 
				
			||||||
 | 
					            ret = fd_msg_avp_setvalue(avp_msisdn, &val);
 | 
				
			||||||
 | 
					            ogs_assert(ret == 0);
 | 
				
			||||||
 | 
					            ret = fd_msg_avp_add(avp, MSG_BRW_LAST_CHILD, avp_msisdn);
 | 
				
			||||||
 | 
					            ogs_assert(ret == 0);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (subscription_data.num_of_msisdn >= 2)  {
 | 
				
			||||||
 | 
					            ret = fd_msg_avp_new(ogs_diam_s6a_a_msisdn, 0, &avp_a_msisdn);
 | 
				
			||||||
 | 
					            ogs_assert(ret == 0);
 | 
				
			||||||
 | 
					            val.os.data = subscription_data.msisdn[1].buf;
 | 
				
			||||||
 | 
					            val.os.len = subscription_data.msisdn[1].len;
 | 
				
			||||||
 | 
					            ret = fd_msg_avp_setvalue(avp_a_msisdn, &val);
 | 
				
			||||||
 | 
					            ogs_assert(ret == 0);
 | 
				
			||||||
 | 
					            ret = fd_msg_avp_add(avp, MSG_BRW_LAST_CHILD, avp_a_msisdn);
 | 
				
			||||||
 | 
					            ogs_assert(ret == 0);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (subscription_data.access_restriction_data) {
 | 
					        if (subscription_data.access_restriction_data) {
 | 
				
			||||||
            ret = fd_msg_avp_new(ogs_diam_s6a_access_restriction_data, 0,
 | 
					            ret = fd_msg_avp_new(ogs_diam_s6a_access_restriction_data, 0,
 | 
				
			||||||
                    &avp_access_restriction_data);
 | 
					                    &avp_access_restriction_data);
 | 
				
			||||||
@@ -384,7 +420,7 @@ static int hss_ogs_diam_s6a_ulr_cb( struct msg **msg, struct avp *avp,
 | 
				
			|||||||
        ret = fd_msg_avp_add(avp, MSG_BRW_LAST_CHILD, avp_network_access_mode);
 | 
					        ret = fd_msg_avp_add(avp, MSG_BRW_LAST_CHILD, avp_network_access_mode);
 | 
				
			||||||
        ogs_assert(ret == 0);
 | 
					        ogs_assert(ret == 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            /* Set the AMBR */
 | 
					        /* Set the AMBR */
 | 
				
			||||||
        ret = fd_msg_avp_new(ogs_diam_s6a_ambr, 0, &avp_ambr);
 | 
					        ret = fd_msg_avp_new(ogs_diam_s6a_ambr, 0, &avp_ambr);
 | 
				
			||||||
        ogs_assert(ret == 0);
 | 
					        ogs_assert(ret == 0);
 | 
				
			||||||
        ret = fd_msg_avp_new(
 | 
					        ret = fd_msg_avp_new(
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -317,6 +317,14 @@ struct mme_ue_s {
 | 
				
			|||||||
    char            imeisv_bcd[OGS_MAX_IMEISV_BCD_LEN+1];
 | 
					    char            imeisv_bcd[OGS_MAX_IMEISV_BCD_LEN+1];
 | 
				
			||||||
    ogs_nas_mobile_identity_imeisv_t nas_mobile_identity_imeisv;
 | 
					    ogs_nas_mobile_identity_imeisv_t nas_mobile_identity_imeisv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uint8_t         msisdn[OGS_MAX_MSISDN_LEN];
 | 
				
			||||||
 | 
					    int             msisdn_len;
 | 
				
			||||||
 | 
					    char            msisdn_bcd[OGS_MAX_MSISDN_BCD_LEN+1];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uint8_t         a_msisdn[OGS_MAX_MSISDN_LEN];
 | 
				
			||||||
 | 
					    int             a_msisdn_len;
 | 
				
			||||||
 | 
					    char            a_msisdn_bcd[OGS_MAX_MSISDN_BCD_LEN+1];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    mme_m_tmsi_t    *m_tmsi;
 | 
					    mme_m_tmsi_t    *m_tmsi;
 | 
				
			||||||
    mme_p_tmsi_t    p_tmsi;
 | 
					    mme_p_tmsi_t    p_tmsi;
 | 
				
			||||||
    ogs_nas_eps_guti_t guti;
 | 
					    ogs_nas_eps_guti_t guti;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -711,10 +711,51 @@ static void mme_s6a_ula_cb(void *data, struct msg **msg)
 | 
				
			|||||||
    ret = fd_msg_search_avp(*msg, ogs_diam_s6a_subscription_data, &avp);
 | 
					    ret = fd_msg_search_avp(*msg, ogs_diam_s6a_subscription_data, &avp);
 | 
				
			||||||
    ogs_assert(ret == 0);
 | 
					    ogs_assert(ret == 0);
 | 
				
			||||||
    if (avp) {
 | 
					    if (avp) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /*
 | 
				
			||||||
 | 
					         * TS29.328
 | 
				
			||||||
 | 
					         * 6.3.2 MSISDN AVP
 | 
				
			||||||
 | 
					         *
 | 
				
			||||||
 | 
					         * The MSISDN AVP is of type OctetString.
 | 
				
			||||||
 | 
					         * This AVP contains an MSISDN, in international number format
 | 
				
			||||||
 | 
					         * as described in ITU-T Rec E.164 [8], encoded as a TBCD-string,
 | 
				
			||||||
 | 
					         * i.e. digits from 0 through 9 are encoded 0000 to 1001;
 | 
				
			||||||
 | 
					         * 1111 is used as a filler when there is an odd number of digits;
 | 
				
			||||||
 | 
					         * bits 8 to 5 of octet n encode digit 2n;
 | 
				
			||||||
 | 
					         * bits 4 to 1 of octet n encode digit 2(n-1)+1.
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        ret = fd_avp_search_avp(avp, ogs_diam_s6a_msisdn, &avpch1);
 | 
				
			||||||
 | 
					        ogs_assert(ret == 0);
 | 
				
			||||||
 | 
					        if (avpch1) {
 | 
				
			||||||
 | 
					            ret = fd_msg_avp_hdr(avpch1, &hdr);
 | 
				
			||||||
 | 
					            ogs_assert(ret == 0);
 | 
				
			||||||
 | 
					            if (hdr->avp_value->os.len) {
 | 
				
			||||||
 | 
					                mme_ue->msisdn_len = hdr->avp_value->os.len;
 | 
				
			||||||
 | 
					                memcpy(mme_ue->msisdn,
 | 
				
			||||||
 | 
					                    hdr->avp_value->os.data, mme_ue->msisdn_len);
 | 
				
			||||||
 | 
					                ogs_buffer_to_bcd(mme_ue->msisdn,
 | 
				
			||||||
 | 
					                        mme_ue->msisdn_len, mme_ue->msisdn_bcd);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        ret = fd_avp_search_avp(avp, ogs_diam_s6a_a_msisdn, &avpch1);
 | 
				
			||||||
 | 
					        ogs_assert(ret == 0);
 | 
				
			||||||
 | 
					        if (avpch1) {
 | 
				
			||||||
 | 
					            ret = fd_msg_avp_hdr(avpch1, &hdr);
 | 
				
			||||||
 | 
					            ogs_assert(ret == 0);
 | 
				
			||||||
 | 
					            if (hdr->avp_value->os.len) {
 | 
				
			||||||
 | 
					                mme_ue->a_msisdn_len = hdr->avp_value->os.len;
 | 
				
			||||||
 | 
					                memcpy(mme_ue->a_msisdn,
 | 
				
			||||||
 | 
					                    hdr->avp_value->os.data, mme_ue->a_msisdn_len);
 | 
				
			||||||
 | 
					                ogs_buffer_to_bcd(mme_ue->a_msisdn,
 | 
				
			||||||
 | 
					                        mme_ue->a_msisdn_len, mme_ue->a_msisdn_bcd);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ret = fd_avp_search_avp(avp, ogs_diam_s6a_ambr, &avpch1);
 | 
					        ret = fd_avp_search_avp(avp, ogs_diam_s6a_ambr, &avpch1);
 | 
				
			||||||
        ogs_assert(ret == 0);
 | 
					        ogs_assert(ret == 0);
 | 
				
			||||||
        if (avpch1) {
 | 
					        if (avpch1) {
 | 
				
			||||||
            ret = fd_avp_search_avp( avpch1,
 | 
					            ret = fd_avp_search_avp(avpch1,
 | 
				
			||||||
                    ogs_diam_s6a_max_bandwidth_ul, &avpch2);
 | 
					                    ogs_diam_s6a_max_bandwidth_ul, &avpch2);
 | 
				
			||||||
            ogs_assert(ret == 0);
 | 
					            ogs_assert(ret == 0);
 | 
				
			||||||
            if (avpch2) {
 | 
					            if (avpch2) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -67,6 +67,12 @@ ogs_pkbuf_t *mme_s11_build_create_session_request(
 | 
				
			|||||||
        req->me_identity.len = mme_ue->imeisv_len;
 | 
					        req->me_identity.len = mme_ue->imeisv_len;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (mme_ue->msisdn_len) {
 | 
				
			||||||
 | 
					        req->msisdn.presence = 1;
 | 
				
			||||||
 | 
					        req->msisdn.data = mme_ue->msisdn;
 | 
				
			||||||
 | 
					        req->msisdn.len = mme_ue->msisdn_len;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    memset(&uli, 0, sizeof(ogs_gtp_uli_t));
 | 
					    memset(&uli, 0, sizeof(ogs_gtp_uli_t));
 | 
				
			||||||
    uli.flags.e_cgi = 1;
 | 
					    uli.flags.e_cgi = 1;
 | 
				
			||||||
    uli.flags.tai = 1;
 | 
					    uli.flags.tai = 1;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -56,7 +56,7 @@ bool udr_nudr_dr_handle_subscription_authentication(
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (strncmp(supi,
 | 
					    if (strncmp(supi,
 | 
				
			||||||
            OGS_DBI_SUPI_TYPE_IMSI, strlen(OGS_DBI_SUPI_TYPE_IMSI)) != 0) {
 | 
					            OGS_ID_SUPI_TYPE_IMSI, strlen(OGS_ID_SUPI_TYPE_IMSI)) != 0) {
 | 
				
			||||||
        ogs_error("[%s] Unknown SUPI Type", supi);
 | 
					        ogs_error("[%s] Unknown SUPI Type", supi);
 | 
				
			||||||
        ogs_sbi_server_send_error(session, OGS_SBI_HTTP_STATUS_FORBIDDEN,
 | 
					        ogs_sbi_server_send_error(session, OGS_SBI_HTTP_STATUS_FORBIDDEN,
 | 
				
			||||||
                recvmsg, "Unknwon SUPI Type", supi);
 | 
					                recvmsg, "Unknwon SUPI Type", supi);
 | 
				
			||||||
@@ -252,7 +252,7 @@ bool udr_nudr_dr_handle_subscription_context(
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (strncmp(supi,
 | 
					    if (strncmp(supi,
 | 
				
			||||||
            OGS_DBI_SUPI_TYPE_IMSI, strlen(OGS_DBI_SUPI_TYPE_IMSI)) != 0) {
 | 
					            OGS_ID_SUPI_TYPE_IMSI, strlen(OGS_ID_SUPI_TYPE_IMSI)) != 0) {
 | 
				
			||||||
        ogs_error("[%s] Unknown SUPI Type", supi);
 | 
					        ogs_error("[%s] Unknown SUPI Type", supi);
 | 
				
			||||||
        ogs_sbi_server_send_error(session, OGS_SBI_HTTP_STATUS_FORBIDDEN,
 | 
					        ogs_sbi_server_send_error(session, OGS_SBI_HTTP_STATUS_FORBIDDEN,
 | 
				
			||||||
                recvmsg, "Unknwon SUPI Type", supi);
 | 
					                recvmsg, "Unknwon SUPI Type", supi);
 | 
				
			||||||
@@ -329,7 +329,7 @@ bool udr_nudr_dr_handle_subscription_provisioned(
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (strncmp(supi,
 | 
					    if (strncmp(supi,
 | 
				
			||||||
            OGS_DBI_SUPI_TYPE_IMSI, strlen(OGS_DBI_SUPI_TYPE_IMSI)) != 0) {
 | 
					            OGS_ID_SUPI_TYPE_IMSI, strlen(OGS_ID_SUPI_TYPE_IMSI)) != 0) {
 | 
				
			||||||
        ogs_error("[%s] Unknown SUPI Type", supi);
 | 
					        ogs_error("[%s] Unknown SUPI Type", supi);
 | 
				
			||||||
        ogs_sbi_server_send_error(session, OGS_SBI_HTTP_STATUS_FORBIDDEN,
 | 
					        ogs_sbi_server_send_error(session, OGS_SBI_HTTP_STATUS_FORBIDDEN,
 | 
				
			||||||
                recvmsg, "Unknwon SUPI Type", supi);
 | 
					                recvmsg, "Unknwon SUPI Type", supi);
 | 
				
			||||||
@@ -357,12 +357,23 @@ bool udr_nudr_dr_handle_subscription_provisioned(
 | 
				
			|||||||
        OpenAPI_access_and_mobility_subscription_data_t
 | 
					        OpenAPI_access_and_mobility_subscription_data_t
 | 
				
			||||||
            AccessAndMobilitySubscriptionData;
 | 
					            AccessAndMobilitySubscriptionData;
 | 
				
			||||||
        OpenAPI_ambr_rm_t subscribed_ue_ambr;
 | 
					        OpenAPI_ambr_rm_t subscribed_ue_ambr;
 | 
				
			||||||
 | 
					        OpenAPI_list_t *gpsiList = NULL;
 | 
				
			||||||
 | 
					        OpenAPI_lnode_t *node = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        subscribed_ue_ambr.uplink = ogs_sbi_bitrate_to_string(
 | 
					        subscribed_ue_ambr.uplink = ogs_sbi_bitrate_to_string(
 | 
				
			||||||
                subscription_data.ambr.uplink, OGS_SBI_BITRATE_KBPS);
 | 
					                subscription_data.ambr.uplink, OGS_SBI_BITRATE_KBPS);
 | 
				
			||||||
        subscribed_ue_ambr.downlink = ogs_sbi_bitrate_to_string(
 | 
					        subscribed_ue_ambr.downlink = ogs_sbi_bitrate_to_string(
 | 
				
			||||||
                subscription_data.ambr.downlink, OGS_SBI_BITRATE_KBPS);
 | 
					                subscription_data.ambr.downlink, OGS_SBI_BITRATE_KBPS);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        gpsiList = OpenAPI_list_create();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (i = 0; i < subscription_data.num_of_msisdn; i++) {
 | 
				
			||||||
 | 
					            char *gpsi = ogs_msprintf("%s-%s",
 | 
				
			||||||
 | 
					                    OGS_ID_GPSI_TYPE_MSISDN, subscription_data.msisdn[i].bcd);
 | 
				
			||||||
 | 
					            ogs_assert(gpsi);
 | 
				
			||||||
 | 
					            OpenAPI_list_add(gpsiList, gpsi);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        memset(&AccessAndMobilitySubscriptionData, 0,
 | 
					        memset(&AccessAndMobilitySubscriptionData, 0,
 | 
				
			||||||
                sizeof(AccessAndMobilitySubscriptionData));
 | 
					                sizeof(AccessAndMobilitySubscriptionData));
 | 
				
			||||||
        AccessAndMobilitySubscriptionData.subscribed_ue_ambr =
 | 
					        AccessAndMobilitySubscriptionData.subscribed_ue_ambr =
 | 
				
			||||||
@@ -372,12 +383,19 @@ bool udr_nudr_dr_handle_subscription_provisioned(
 | 
				
			|||||||
        sendmsg.AccessAndMobilitySubscriptionData =
 | 
					        sendmsg.AccessAndMobilitySubscriptionData =
 | 
				
			||||||
            &AccessAndMobilitySubscriptionData;
 | 
					            &AccessAndMobilitySubscriptionData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (gpsiList->count)
 | 
				
			||||||
 | 
					            AccessAndMobilitySubscriptionData.gpsis = gpsiList;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        response = ogs_sbi_build_response(&sendmsg, OGS_SBI_HTTP_STATUS_OK);
 | 
					        response = ogs_sbi_build_response(&sendmsg, OGS_SBI_HTTP_STATUS_OK);
 | 
				
			||||||
        ogs_assert(response);
 | 
					        ogs_assert(response);
 | 
				
			||||||
        ogs_sbi_server_send_response(session, response);
 | 
					        ogs_sbi_server_send_response(session, response);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ogs_free(subscribed_ue_ambr.uplink);
 | 
					        ogs_free(subscribed_ue_ambr.uplink);
 | 
				
			||||||
        ogs_free(subscribed_ue_ambr.downlink);
 | 
					        ogs_free(subscribed_ue_ambr.downlink);
 | 
				
			||||||
 | 
					        OpenAPI_list_for_each(gpsiList, node) {
 | 
				
			||||||
 | 
					            if (node->data) ogs_free(node->data);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        OpenAPI_list_free(gpsiList);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -477,7 +477,7 @@ void test_ue_set_mobile_identity(test_ue_t *test_ue,
 | 
				
			|||||||
    test_ue->supi = ogs_supi_from_suci(test_ue->suci);
 | 
					    test_ue->supi = ogs_supi_from_suci(test_ue->suci);
 | 
				
			||||||
    if (test_ue->imsi)
 | 
					    if (test_ue->imsi)
 | 
				
			||||||
        ogs_free(test_ue->imsi);
 | 
					        ogs_free(test_ue->imsi);
 | 
				
			||||||
    test_ue->imsi = ogs_supi_get_id(test_ue->supi);
 | 
					    test_ue->imsi = ogs_id_get_value(test_ue->supi);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void test_ue_set_mobile_identity_suci(test_ue_t *test_ue,
 | 
					void test_ue_set_mobile_identity_suci(test_ue_t *test_ue,
 | 
				
			||||||
@@ -505,7 +505,7 @@ void test_ue_set_mobile_identity_suci(test_ue_t *test_ue,
 | 
				
			|||||||
    test_ue->supi = ogs_supi_from_suci(test_ue->suci);
 | 
					    test_ue->supi = ogs_supi_from_suci(test_ue->suci);
 | 
				
			||||||
    if (test_ue->imsi)
 | 
					    if (test_ue->imsi)
 | 
				
			||||||
        ogs_free(test_ue->imsi);
 | 
					        ogs_free(test_ue->imsi);
 | 
				
			||||||
    test_ue->imsi = ogs_supi_get_id(test_ue->supi);
 | 
					    test_ue->imsi = ogs_id_get_value(test_ue->supi);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void test_ue_remove(test_ue_t *test_ue)
 | 
					void test_ue_remove(test_ue_t *test_ue)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -52,14 +52,14 @@ static void test1_func(abts_case *tc, void *data)
 | 
				
			|||||||
        "6d6503657063066d 6e63303730066d63 633930310b336770 706e6574776f726b"
 | 
					        "6d6503657063066d 6e63303730066d63 633930310b336770 706e6574776f726b"
 | 
				
			||||||
        "036f72670a010104 0509f1070926";
 | 
					        "036f72670a010104 0509f1070926";
 | 
				
			||||||
    const char *_initial_context_setup_request = 
 | 
					    const char *_initial_context_setup_request = 
 | 
				
			||||||
        "00090080dc000006 0000000200010008 000200010042000a 183d090000603d09"
 | 
					        "00090080e8000007 0000000200010008 000200010042000a 183d090000603d09"
 | 
				
			||||||
        "0000001800808d00 0034008087450009 230f807f00000200 000001782756d7d9"
 | 
					        "0000001800808d00 0034008087450009 230f807f00000200 00000178270d3fa3"
 | 
				
			||||||
        "8002074202490620 09f1070007004652 34c101090908696e 7465726e65740501"
 | 
					        "8402074202490620 09f1070007004652 34c101090908696e 7465726e65740501"
 | 
				
			||||||
        "0a2d00025e06fefe e2e2030327278080 2110020000108106 0808080883060808"
 | 
					        "0a2d00025e06fefe e2e2030327278080 2110020000108106 0808080883060808"
 | 
				
			||||||
        "0404000d04080808 08000d0408080404 0010020578500bf6 09f107000201ea00"
 | 
					        "0404000d04080808 08000d0408080404 0010020578500bf6 09f107000201f500"
 | 
				
			||||||
        "1d661309f1070926 2305f49ee88e6459 49640101006b0005 1c000e0000004900"
 | 
					        "22811309f1070926 2305f49ee88e6459 49640101006b0005 1c000e0000004900"
 | 
				
			||||||
        "20f9f4f80b206c33 ae286c6daff4c253 585174c3a0a12a66 1967f5e1ba0a686c"
 | 
					        "20f9f4f80b206c33 ae286c6daff4c253 585174c3a0a12a66 1967f5e1ba0a686c"
 | 
				
			||||||
        "8c";
 | 
					        "8c00c04008357220 0924ffff14";
 | 
				
			||||||
    const char *_emm_information = 
 | 
					    const char *_emm_information = 
 | 
				
			||||||
        "000b403800000300 0000020001000800 020001001a002524 2751034124030761"
 | 
					        "000b403800000300 0000020001000800 020001001a002524 2751034124030761"
 | 
				
			||||||
        "430f10004f007000 65006e0035004700 5347916051216124 63490100";
 | 
					        "430f10004f007000 65006e0035004700 5347916051216124 63490100";
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -65,6 +65,10 @@ static void test1_func(abts_case *tc, void *data)
 | 
				
			|||||||
      "{"
 | 
					      "{"
 | 
				
			||||||
        "\"_id\" : { \"$oid\" : \"310014158b8861d7605378c6\" }, "
 | 
					        "\"_id\" : { \"$oid\" : \"310014158b8861d7605378c6\" }, "
 | 
				
			||||||
        "\"imsi\" : \"310014987654004\", "
 | 
					        "\"imsi\" : \"310014987654004\", "
 | 
				
			||||||
 | 
					#if 0
 | 
				
			||||||
 | 
					        "\"msisdn\" : [\"821012345678\", \"82107654321\" ], "
 | 
				
			||||||
 | 
					        "\"msisdn\" : [\"82107654321\", \"821012345678\" ], "
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
        "\"pdn\" : ["
 | 
					        "\"pdn\" : ["
 | 
				
			||||||
          "{"
 | 
					          "{"
 | 
				
			||||||
            "\"apn\" : \"starent.com\", "
 | 
					            "\"apn\" : \"starent.com\", "
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -52,6 +52,10 @@ static void test1_func(abts_case *tc, void *data)
 | 
				
			|||||||
      "{"
 | 
					      "{"
 | 
				
			||||||
        "\"_id\" : { \"$oid\" : \"597223158b8861d7605378c6\" }, "
 | 
					        "\"_id\" : { \"$oid\" : \"597223158b8861d7605378c6\" }, "
 | 
				
			||||||
        "\"imsi\" : \"901700000021309\","
 | 
					        "\"imsi\" : \"901700000021309\","
 | 
				
			||||||
 | 
					#if 0
 | 
				
			||||||
 | 
					        "\"msisdn\" : [\"821012345678\", \"82107654321\" ], "
 | 
				
			||||||
 | 
					        "\"msisdn\" : [\"82107654321\", \"821012345678\" ], "
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
        "\"ambr\" : { "
 | 
					        "\"ambr\" : { "
 | 
				
			||||||
          "\"uplink\" : { \"$numberLong\" : \"1024000\" }, "
 | 
					          "\"uplink\" : { \"$numberLong\" : \"1024000\" }, "
 | 
				
			||||||
          "\"downlink\" : { \"$numberLong\" : \"1024000\" } "
 | 
					          "\"downlink\" : { \"$numberLong\" : \"1024000\" } "
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user