diff --git a/lib/dbi/subscription.c b/lib/dbi/subscription.c index e4e9bfa36..670279176 100644 --- a/lib/dbi/subscription.c +++ b/lib/dbi/subscription.c @@ -148,6 +148,46 @@ int ogs_dbi_update_sqn(char *supi, uint64_t sqn) return rv; } +int ogs_dbi_update_imei(char *supi, char *imei) +{ + int rv = OGS_OK; + bson_t *query = NULL; + bson_t *update = NULL; + bson_error_t error; + + char *supi_type = NULL; + char *supi_id = NULL; + + ogs_assert(supi); + + supi_type = ogs_id_get_type(supi); + ogs_assert(supi_type); + supi_id = ogs_id_get_value(supi); + ogs_assert(supi_id); + + ogs_debug("SUPI type: %s, SUPI id: %s, imei: %s", supi_type, supi_id, imei); + + query = BCON_NEW(supi_type, BCON_UTF8(supi_id)); + update = BCON_NEW("$set", + "{", + "imei", BCON_UTF8(imei), + "}"); + if (!mongoc_collection_update(ogs_mongoc()->collection.subscriber, + MONGOC_UPDATE_UPSERT, query, update, NULL, &error)) { + ogs_error("mongoc_collection_update() failure: %s", error.message); + + rv = OGS_ERROR; + } + + if (query) bson_destroy(query); + if (update) bson_destroy(update); + + ogs_free(supi_type); + ogs_free(supi_id); + + return rv; +} + int ogs_dbi_increment_sqn(char *supi) { int rv = OGS_OK; diff --git a/lib/dbi/subscription.h b/lib/dbi/subscription.h index 0cd3eeff9..e6da36cea 100644 --- a/lib/dbi/subscription.h +++ b/lib/dbi/subscription.h @@ -41,6 +41,7 @@ typedef struct ogs_dbi_auth_info_s { int ogs_dbi_auth_info(char *supi, ogs_dbi_auth_info_t *auth_info); int ogs_dbi_update_sqn(char *supi, uint64_t sqn); int ogs_dbi_increment_sqn(char *supi); +int ogs_dbi_update_imei(char *supi, char *imei); int ogs_dbi_subscription_data(char *supi, ogs_subscription_data_t *subscription_data); diff --git a/src/hss/hss-context.c b/src/hss/hss-context.c index 9f5f2e756..6be690ff3 100644 --- a/src/hss/hss-context.c +++ b/src/hss/hss-context.c @@ -374,6 +374,25 @@ int hss_db_update_sqn(char *imsi_bcd, uint8_t *rand, uint64_t sqn) return rv; } +int hss_db_update_imei(char *imsi_bcd, char *imei) +{ + int rv; + char *supi = NULL; + + ogs_assert(imsi_bcd); + + ogs_thread_mutex_lock(&self.db_lock); + supi = ogs_msprintf("%s-%s", OGS_ID_SUPI_TYPE_IMSI, imsi_bcd); + ogs_assert(supi); + + rv = ogs_dbi_update_imei(supi, imei); + + ogs_free(supi); + ogs_thread_mutex_unlock(&self.db_lock); + + return rv; +} + int hss_db_increment_sqn(char *imsi_bcd) { int rv; diff --git a/src/hss/hss-context.h b/src/hss/hss-context.h index f4cadf29d..3cc04c110 100644 --- a/src/hss/hss-context.h +++ b/src/hss/hss-context.h @@ -61,6 +61,7 @@ int hss_context_parse_config(void); int hss_db_auth_info(char *imsi_bcd, ogs_dbi_auth_info_t *auth_info); int hss_db_update_sqn(char *imsi_bcd, uint8_t *rand, uint64_t sqn); int hss_db_increment_sqn(char *imsi_bcd); +int hss_db_update_imei(char *imsi_bcd, char *imei); int hss_db_subscription_data( char *imsi_bcd, ogs_subscription_data_t *subscription_data); diff --git a/src/hss/hss-s6a-path.c b/src/hss/hss-s6a-path.c index e3ce47c3e..394d9fe29 100644 --- a/src/hss/hss-s6a-path.c +++ b/src/hss/hss-s6a-path.c @@ -45,7 +45,7 @@ static int hss_ogs_diam_s6a_air_cb( struct msg **msg, struct avp *avp, { int ret; - struct msg *ans, *qry; + struct msg *ans, *qry; struct avp *avpch; struct avp *avp_e_utran_vector, *avp_xres, *avp_kasme, *avp_rand, *avp_autn; struct avp_hdr *hdr; @@ -271,12 +271,14 @@ static int hss_ogs_diam_s6a_ulr_cb( struct msg **msg, struct avp *avp, struct session *session, void *opaque, enum disp_action *act) { int ret; - struct msg *ans, *qry; + struct msg *ans, *qry; struct avp_hdr *hdr; + struct avp *avpch1; union avp_value val; char imsi_bcd[OGS_MAX_IMSI_BCD_LEN+1]; + char imeisv_bcd[OGS_MAX_IMEISV_BCD_LEN+1]; int rv; uint32_t result_code = 0; @@ -293,9 +295,9 @@ static int hss_ogs_diam_s6a_ulr_cb( struct msg **msg, struct avp *avp, memset(&subscription_data, 0, sizeof(ogs_subscription_data_t)); - /* Create answer header */ - qry = *msg; - ret = fd_msg_new_answer_from_req(fd_g_config->cnf_dict, msg, 0); + /* Create answer header */ + qry = *msg; + ret = fd_msg_new_answer_from_req(fd_g_config->cnf_dict, msg, 0); ogs_assert(ret == 0); ans = *msg; @@ -313,14 +315,30 @@ static int hss_ogs_diam_s6a_ulr_cb( struct msg **msg, struct avp *avp, goto out; } + ret = fd_msg_search_avp(qry, ogs_diam_s6a_terminal_information, &avp); + ogs_assert(ret == 0); + if (avp) { + ret = fd_avp_search_avp(avp, ogs_diam_s6a_imei, &avpch1); + ogs_assert(ret == 0); + if (avpch1) { + ret = fd_msg_avp_hdr(avpch1, &hdr); + ogs_assert(ret == 0); + if (hdr->avp_value->os.len) { + ogs_cpystrn(imeisv_bcd, (char*)hdr->avp_value->os.data, + ogs_min(hdr->avp_value->os.len, OGS_MAX_IMEISV_BCD_LEN)+1); + hss_db_update_imei(imsi_bcd, imeisv_bcd); + } + } + } + ret = fd_msg_search_avp(qry, ogs_diam_visited_plmn_id, &avp); ogs_assert(ret == 0); ret = fd_msg_avp_hdr(avp, &hdr); ogs_assert(ret == 0); memcpy(&visited_plmn_id, hdr->avp_value->os.data, hdr->avp_value->os.len); - /* Set the Origin-Host, Origin-Realm, andResult-Code AVPs */ - ret = fd_msg_rescode_set(ans, (char*)"DIAMETER_SUCCESS", NULL, NULL, 1); + /* Set the Origin-Host, Origin-Realm, andResult-Code AVPs */ + ret = fd_msg_rescode_set(ans, (char*)"DIAMETER_SUCCESS", NULL, NULL, 1); ogs_assert(ret == 0); /* Set the Auth-Session-State AVP */ @@ -763,20 +781,20 @@ static int hss_ogs_diam_s6a_ulr_cb( struct msg **msg, struct avp *avp, ans, OGS_DIAM_S6A_APPLICATION_ID); ogs_assert(ret == 0); - /* Send the answer */ - ret = fd_msg_send(msg, NULL, NULL); + /* Send the answer */ + ret = fd_msg_send(msg, NULL, NULL); ogs_assert(ret == 0); ogs_debug("Update-Location-Answer"); - - /* Add this value to the stats */ - ogs_assert( pthread_mutex_lock(&ogs_diam_logger_self()->stats_lock) == 0); - ogs_diam_logger_self()->stats.nb_echoed++; - ogs_assert( pthread_mutex_unlock(&ogs_diam_logger_self()->stats_lock) == 0); + + /* Add this value to the stats */ + ogs_assert( pthread_mutex_lock(&ogs_diam_logger_self()->stats_lock) == 0); + ogs_diam_logger_self()->stats.nb_echoed++; + ogs_assert( pthread_mutex_unlock(&ogs_diam_logger_self()->stats_lock) == 0); ogs_subscription_data_free(&subscription_data); - return 0; + return 0; out: ret = ogs_diam_message_experimental_rescode_set(ans, result_code); @@ -796,7 +814,7 @@ out: ans, OGS_DIAM_S6A_APPLICATION_ID); ogs_assert(ret == 0); - ret = fd_msg_send(msg, NULL, NULL); + ret = fd_msg_send(msg, NULL, NULL); ogs_assert(ret == 0); ogs_subscription_data_free(&subscription_data);