[MME] Dictionary Updates and IDR Support (#1714)

* Add Diameter Dictionary Elements

* Initial IDR Framework

* Resolve Compile Issues

* Moving Closer

* Compile error

* Somewhat Working stuffing Code

* Add Timestamp Changes

* Cleanup some of this code.  mme_s6a_handle_idr in s6a-handler.c removed for now, since it will only come in handy when IDR flag is set to request current location, which would involve breaking out into paging.  I think there's a few other things we can do just within fd-path first.

* further removal of mme_s6a_handle_idr
This commit is contained in:
jmasterfunk84 2022-08-25 00:43:21 -06:00 committed by GitHub
parent def99aff7f
commit 49349cdb75
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 343 additions and 1 deletions

View File

@ -583,6 +583,71 @@ int ogs_dict_s6a_entry(char *conffile)
PARSE_loc_rules( rules, cmd );
}
/* Insert-Subscriber-Data-Request (IDR) Command - 3GPP TS 29.272 #7.2.9 */
{
struct dict_object * cmd;
struct dict_cmd_data data = {
319, /* Code */
"Insert-Subscriber-Data-Request", /* Name */
CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_ERROR, /* Fixed flags */
CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE /* Fixed flag values */
};
struct local_rules_definition rules[] =
{
{ { .avp_name = "Session-Id" }, RULE_FIXED_HEAD, -1, 1 },
{ { .avp_name = "Vendor-Specific-Application-Id" }, RULE_OPTIONAL, -1, 1 },
{ { .avp_name = "Auth-Session-State" }, RULE_REQUIRED, -1, 1 },
{ { .avp_name = "Origin-Host" }, RULE_REQUIRED, -1, 1 },
{ { .avp_name = "Origin-Realm" }, RULE_REQUIRED, -1, 1 },
{ { .avp_name = "Destination-Host" }, RULE_OPTIONAL, -1, 1 },
{ { .avp_name = "Destination-Realm" }, RULE_REQUIRED, -1, 1 },
{ { .avp_name = "User-Name" }, RULE_REQUIRED, -1, 1 },
{ { .avp_vendor = 10415, .avp_name = "Supported-Features" }, RULE_OPTIONAL, -1, -1 },
{ { .avp_vendor = 10415, .avp_name = "Subscription-Data" }, RULE_REQUIRED, -1, 1 },
{ { .avp_vendor = 10415, .avp_name = "IDR-Flags" }, RULE_OPTIONAL, -1, 1 },
{ { .avp_name = "Proxy-Info" }, RULE_OPTIONAL, -1, -1 },
{ { .avp_name = "Route-Record" }, RULE_OPTIONAL, -1, -1 },
};
CHECK_dict_new( DICT_COMMAND, &data, s6a, &cmd);
PARSE_loc_rules( rules, cmd );
}
/* Insert-Subscriber-Data-Answer (IDA) Command - 3GPP TS 29.272 #7.2.10 */
{
struct dict_object * cmd;
struct dict_cmd_data data = {
319, /* Code */
"Insert-Subscriber-Data-Answer", /* Name */
CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_ERROR, /* Fixed flags */
CMD_FLAG_PROXIABLE /* Fixed flag values */
};
struct local_rules_definition rules[] =
{
{ { .avp_name = "Session-Id" }, RULE_FIXED_HEAD, -1, 1 },
{ { .avp_name = "Vendor-Specific-Application-Id" }, RULE_OPTIONAL, -1, 1 },
{ { .avp_name = "Result-Code" }, RULE_OPTIONAL, -1, 1 },
{ { .avp_name = "Experimental-Result" }, RULE_OPTIONAL, -1, 1 },
{ { .avp_name = "Auth-Session-State" }, RULE_REQUIRED, -1, 1 },
{ { .avp_name = "Origin-Host" }, RULE_REQUIRED, -1, 1 },
{ { .avp_name = "Origin-Realm" }, RULE_REQUIRED, -1, 1 },
{ { .avp_vendor = 10415, .avp_name = "IMS-Voice-Over-PS-Sessions-Supported" }, RULE_OPTIONAL, -1, 1 },
{ { .avp_vendor = 10415, .avp_name = "Last-UE-Activity-Time" }, RULE_OPTIONAL, -1, 1 },
{ { .avp_vendor = 10415, .avp_name = "RAT-Type" }, RULE_OPTIONAL, -1, 1 },
{ { .avp_vendor = 10415, .avp_name = "IDA-Flags" }, RULE_OPTIONAL, -1, 1 },
{ { .avp_vendor = 10415, .avp_name = "EPS-User-State" }, RULE_OPTIONAL, -1, 1 },
{ { .avp_vendor = 10415, .avp_name = "EPS-Location-Information" }, RULE_OPTIONAL, -1, 1 },
{ { .avp_vendor = 10415, .avp_name = "Local-Time-Zone" }, RULE_OPTIONAL, -1, 1 },
{ { .avp_vendor = 10415, .avp_name = "Supported-Services" }, RULE_OPTIONAL, -1, 1 },
{ { .avp_name = "Failed-AVP" }, RULE_OPTIONAL, -1, -1 },
{ { .avp_name = "Proxy-Info" }, RULE_OPTIONAL, -1, -1 },
{ { .avp_name = "Route-Record" }, RULE_OPTIONAL, -1, -1 },
};
CHECK_dict_new( DICT_COMMAND, &data, s6a, &cmd);
PARSE_loc_rules( rules, cmd );
}
}
LOG_D( "Extension 'Dictionary definitions for DCCA 3GPP S6A' initialized");

View File

@ -32,10 +32,13 @@ struct dict_object *ogs_diam_s6a_cmd_pur = NULL;
struct dict_object *ogs_diam_s6a_cmd_pua = NULL;
struct dict_object *ogs_diam_s6a_cmd_clr = NULL;
struct dict_object *ogs_diam_s6a_cmd_cla = NULL;
struct dict_object *ogs_diam_s6a_cmd_idr = NULL;
struct dict_object *ogs_diam_s6a_cmd_ida = NULL;
struct dict_object *ogs_diam_s6a_ulr_flags = NULL;
struct dict_object *ogs_diam_s6a_ula_flags = NULL;
struct dict_object *ogs_diam_s6a_clr_flags = NULL;
struct dict_object *ogs_diam_s6a_idr_flags = NULL;
struct dict_object *ogs_diam_s6a_cancellation_type = NULL;
struct dict_object *ogs_diam_s6a_subscription_data = NULL;
struct dict_object *ogs_diam_s6a_req_eutran_auth_info = NULL;
@ -71,6 +74,11 @@ struct dict_object *ogs_diam_s6a_pre_emption_capability = NULL;
struct dict_object *ogs_diam_s6a_pre_emption_vulnerability = NULL;
struct dict_object *ogs_diam_s6a_pdn_gw_allocation_type = NULL;
struct dict_object *ogs_diam_s6a_vplmn_dynamic_address_allowed = NULL;
struct dict_object *ogs_diam_s6a_eps_location_information = NULL;
struct dict_object *ogs_diam_s6a_mme_location_information = NULL;
struct dict_object *ogs_diam_s6a_e_utran_cell_global_identity = NULL;
struct dict_object *ogs_diam_s6a_tracking_area_identity = NULL;
struct dict_object *ogs_diam_s6a_age_of_location_information = NULL;
struct dict_object *ogs_diam_s6a_terminal_information = NULL;
struct dict_object *ogs_diam_s6a_imei = NULL;
@ -96,11 +104,14 @@ int ogs_diam_s6a_init(void)
CHECK_dict_search(DICT_COMMAND, CMD_BY_NAME, "Purge-UE-Request", &ogs_diam_s6a_cmd_pur);
CHECK_dict_search(DICT_COMMAND, CMD_BY_NAME, "Purge-UE-Answer", &ogs_diam_s6a_cmd_pua);
CHECK_dict_search(DICT_COMMAND, CMD_BY_NAME, "Cancel-Location-Request", &ogs_diam_s6a_cmd_clr);
CHECK_dict_search(DICT_COMMAND, CMD_BY_NAME, "Cancel-Location-Answer", &ogs_diam_s6a_cmd_cla);
CHECK_dict_search(DICT_COMMAND, CMD_BY_NAME, "Cancel-Location-Answer", &ogs_diam_s6a_cmd_cla);
CHECK_dict_search(DICT_COMMAND, CMD_BY_NAME, "Insert-Subscriber-Data-Request", &ogs_diam_s6a_cmd_idr);
CHECK_dict_search(DICT_COMMAND, CMD_BY_NAME, "Insert-Subscriber-Data-Answer", &ogs_diam_s6a_cmd_ida);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "ULR-Flags", &ogs_diam_s6a_ulr_flags);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "ULA-Flags", &ogs_diam_s6a_ula_flags);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "CLR-Flags", &ogs_diam_s6a_clr_flags);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "IDR-Flags", &ogs_diam_s6a_idr_flags);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Cancellation-Type", &ogs_diam_s6a_cancellation_type);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "UE-SRVCC-Capability", &ogs_diam_s6a_ue_srvcc_capability);
@ -142,6 +153,12 @@ int ogs_diam_s6a_init(void)
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Access-Restriction-Data", &ogs_diam_s6a_access_restriction_data);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Subscribed-Periodic-RAU-TAU-Timer", &ogs_diam_s6a_subscribed_rau_tau_timer);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "EPS-Location-Information", &ogs_diam_s6a_eps_location_information);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "MME-Location-Information", &ogs_diam_s6a_mme_location_information);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "E-UTRAN-Cell-Global-Identity", &ogs_diam_s6a_e_utran_cell_global_identity);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Tracking-Area-Identity", &ogs_diam_s6a_tracking_area_identity);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Age-Of-Location-Information", &ogs_diam_s6a_age_of_location_information);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Terminal-Information", &ogs_diam_s6a_terminal_information);
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);

View File

@ -78,10 +78,13 @@ extern struct dict_object *ogs_diam_s6a_cmd_pur;
extern struct dict_object *ogs_diam_s6a_cmd_pua;
extern struct dict_object *ogs_diam_s6a_cmd_clr;
extern struct dict_object *ogs_diam_s6a_cmd_cla;
extern struct dict_object *ogs_diam_s6a_cmd_idr;
extern struct dict_object *ogs_diam_s6a_cmd_ida;
extern struct dict_object *ogs_diam_s6a_ulr_flags;
extern struct dict_object *ogs_diam_s6a_ula_flags;
extern struct dict_object *ogs_diam_s6a_clr_flags;
extern struct dict_object *ogs_diam_s6a_idr_flags;
extern struct dict_object *ogs_diam_s6a_cancellation_type;
extern struct dict_object *ogs_diam_s6a_subscription_data;
extern struct dict_object *ogs_diam_s6a_req_eutran_auth_info;
@ -117,6 +120,11 @@ extern struct dict_object *ogs_diam_s6a_pre_emption_capability;
extern struct dict_object *ogs_diam_s6a_pre_emption_vulnerability;
extern struct dict_object *ogs_diam_s6a_pdn_gw_allocation_type;
extern struct dict_object *ogs_diam_s6a_vplmn_dynamic_address_allowed;
extern struct dict_object *ogs_diam_s6a_eps_location_information;
extern struct dict_object *ogs_diam_s6a_mme_location_information;
extern struct dict_object *ogs_diam_s6a_e_utran_cell_global_identity;
extern struct dict_object *ogs_diam_s6a_tracking_area_identity;
extern struct dict_object *ogs_diam_s6a_age_of_location_information;
extern struct dict_object *ogs_diam_s6a_terminal_information;
extern struct dict_object *ogs_diam_s6a_imei;
@ -150,10 +158,27 @@ typedef struct ogs_diam_s6a_clr_message_s {
uint32_t clr_flags;
} ogs_diam_s6a_clr_message_t;
typedef struct ogs_diam_s6a_idr_message_s {
#define OGS_DIAM_S6A_IDR_FLAGS_UE_REACHABILITY (1)
#define OGS_DIAM_S6A_IDR_FLAGS_TADS_DATA (1 << 1)
#define OGS_DIAM_S6A_IDR_FLAGS_EPS_USER_STATE (1 << 2)
#define OGS_DIAM_S6A_IDR_FLAGS_EPS_LOCATION_INFO (1 << 3)
#define OGS_DIAM_S6A_IDR_FLAGS_CURRENT_LOCATION (1 << 4)
#define OGS_DIAM_S6A_IDR_FLAGS_LOCAL_TZ (1 << 5)
#define OGS_DIAM_S6A_IDR_FLAGS_REMOVE_SMS_REG (1 << 6)
#define OGS_DIAM_S6A_IDR_FLAGS_RAT_TYPE (1 << 7)
#define OGS_DIAM_S6A_IDR_FLAGS_PCSCF_Restoration (1 << 8)
uint32_t idr_flags;
ogs_subscription_data_t subscription_data;
} ogs_diam_s6a_idr_message_t;
typedef struct ogs_diam_s6a_message_s {
#define OGS_DIAM_S6A_CMD_CODE_UPDATE_LOCATION 316
#define OGS_DIAM_S6A_CMD_CODE_CANCEL_LOCATION 317
#define OGS_DIAM_S6A_CMD_CODE_AUTHENTICATION_INFORMATION 318
#define OGS_DIAM_S6A_CMD_CODE_INSERT_SUBSCRIBER_DATA 319
#define OGS_DIAM_S6A_CMD_CODE_PURGE_UE 321
uint16_t cmd_code;
/* Experimental Result Code */
@ -168,6 +193,7 @@ typedef struct ogs_diam_s6a_message_s {
uint32_t *err;
uint32_t *exp_err;
ogs_diam_s6a_idr_message_t idr_message;
ogs_diam_s6a_clr_message_t clr_message;
ogs_diam_s6a_aia_message_t aia_message;
ogs_diam_s6a_ula_message_t ula_message;

View File

@ -121,6 +121,7 @@ int emm_handle_attach_request(mme_ue_t *mme_ue,
mme_ue->enb_ostream_id = enb_ue->enb_ostream_id;
memcpy(&mme_ue->tai, &enb_ue->saved.tai, sizeof(ogs_eps_tai_t));
memcpy(&mme_ue->e_cgi, &enb_ue->saved.e_cgi, sizeof(ogs_e_cgi_t));
mme_ue->ue_location_timestamp = ogs_time_now();
/* Check TAI */
served_tai_index = mme_find_served_tai(&mme_ue->tai);
@ -538,6 +539,7 @@ int emm_handle_tau_request(mme_ue_t *mme_ue,
mme_ue->enb_ostream_id = enb_ue->enb_ostream_id;
memcpy(&mme_ue->tai, &enb_ue->saved.tai, sizeof(ogs_eps_tai_t));
memcpy(&mme_ue->e_cgi, &enb_ue->saved.e_cgi, sizeof(ogs_e_cgi_t));
mme_ue->ue_location_timestamp = ogs_time_now();
/* Check TAI */
served_tai_index = mme_find_served_tai(&mme_ue->tai);
@ -655,6 +657,7 @@ int emm_handle_extended_service_request(mme_ue_t *mme_ue,
mme_ue->enb_ostream_id = enb_ue->enb_ostream_id;
memcpy(&mme_ue->tai, &enb_ue->saved.tai, sizeof(ogs_eps_tai_t));
memcpy(&mme_ue->e_cgi, &enb_ue->saved.e_cgi, sizeof(ogs_e_cgi_t));
mme_ue->ue_location_timestamp = ogs_time_now();
/* Check TAI */
served_tai_index = mme_find_served_tai(&mme_ue->tai);

View File

@ -368,6 +368,7 @@ struct mme_ue_s {
uint16_t enb_ostream_id;
ogs_eps_tai_t tai;
ogs_e_cgi_t e_cgi;
ogs_time_t ue_location_timestamp;
ogs_plmn_id_t last_visited_plmn_id;
#define SECURITY_CONTEXT_IS_VALID(__mME) \

View File

@ -23,6 +23,9 @@
/* handler for Cancel-Location-Request cb */
static struct disp_hdl *hdl_s6a_clr = NULL;
/* handler for Insert-Subscriber-Data-Request cb */
static struct disp_hdl *hdl_s6a_idr = NULL;
static struct session_handler *mme_s6a_reg = NULL;
struct sess_state {
@ -1541,6 +1544,219 @@ out:
return 0;
}
/* Callback for incoming Insert-Subscriber-Data-Request messages 29.272 5.2.2.1.2 */
static int mme_ogs_diam_s6a_idr_cb( struct msg **msg, struct avp *avp,
struct session *session, void *opaque, enum disp_action *act)
{
int ret;
mme_ue_t *mme_ue = NULL;
struct msg *ans, *qry;
ogs_diam_s6a_idr_message_t *idr_message = NULL;
struct avp_hdr *hdr;
union avp_value val;
char imsi_bcd[OGS_MAX_IMSI_BCD_LEN+1];
uint32_t result_code = 0;
ogs_assert(msg);
ogs_diam_s6a_message_t *s6a_message = NULL;
ogs_debug("Insert-Subscriber-Data-Request");
s6a_message = ogs_calloc(1, sizeof(ogs_diam_s6a_message_t));
ogs_assert(s6a_message);
s6a_message->cmd_code = OGS_DIAM_S6A_CMD_CODE_INSERT_SUBSCRIBER_DATA;
idr_message = &s6a_message->idr_message;
ogs_assert(idr_message);
/* 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;
ret = fd_msg_search_avp(qry, ogs_diam_user_name, &avp);
ogs_assert(ret == 0);
ret = fd_msg_avp_hdr(avp, &hdr);
ogs_assert(ret == 0);
ogs_cpystrn(imsi_bcd, (char*)hdr->avp_value->os.data,
ogs_min(hdr->avp_value->os.len, OGS_MAX_IMSI_BCD_LEN)+1);
mme_ue = mme_ue_find_by_imsi_bcd(imsi_bcd);
if (!mme_ue) {
ogs_error("Insert Subscriber Data for Unknown IMSI[%s]", imsi_bcd);
result_code = OGS_DIAM_S6A_ERROR_USER_UNKNOWN;
goto out;
}
/* AVP: 'Subscription-Data'(1400)
* The Subscription-Data AVP contains the information related to the user
* profile relevant for EPS and GERAN/UTRAN.
* Reference: 3GPP TS 29.272-f70
*/
ret = fd_msg_search_avp(*msg, ogs_diam_s6a_subscription_data, &avp);
ogs_assert(ret == 0);
if (avp) {
ret = fd_msg_avp_hdr(avp, &hdr);
ogs_assert(ret == 0);
if (hdr->avp_value->os.len) {
ogs_debug("WIP: Process New Subscription Data");
} else {
ogs_debug("No Sub Data, ok to check IDR Flags");
}
}
ret = fd_msg_search_avp(qry, ogs_diam_s6a_idr_flags, &avp);
ogs_assert(ret == 0);
if (avp) {
ret = fd_msg_avp_hdr(avp, &hdr);
ogs_assert(ret == 0);
idr_message->idr_flags = hdr->avp_value->i32;
} else {
ogs_error("Insert Subscriber Data does not contain any IDR Flags for IMSI[%s]", imsi_bcd);
/* Set the Origin-Host, Origin-Realm, and Result-Code AVPs */
ret = fd_msg_rescode_set(ans, (char*)"DIAMETER_UNABLE_TO_COMPLY", NULL, NULL, 1);
ogs_assert(ret == 0);
goto outnoexp;
}
if (idr_message->idr_flags & OGS_DIAM_S6A_IDR_FLAGS_EPS_LOCATION_INFO) {
char buf[8];
uint8_t ida_ecgi[7];
uint8_t ida_tai[5];
ogs_time_t ida_age;
ogs_nas_plmn_id_t ida_plmn_buf;
char ida_cell_id_hex[9];
char ida_tac_hex[5];
uint32_t ida_cell_id = mme_ue->e_cgi.cell_id;
uint16_t ida_tac = mme_ue->tai.tac;
sprintf(ida_cell_id_hex, "%08x", ida_cell_id);
memcpy(ida_ecgi, ogs_nas_from_plmn_id(&ida_plmn_buf, &mme_ue->e_cgi.plmn_id), 3);
memcpy(ida_ecgi + 3, OGS_HEX(ida_cell_id_hex,sizeof(ida_cell_id_hex),buf), 5);
sprintf(ida_tac_hex, "%04x", ida_tac);
memcpy(ida_tai, ogs_nas_from_plmn_id(&ida_plmn_buf, &mme_ue->tai.plmn_id), 3);
memcpy(ida_tai + 3, OGS_HEX(ida_tac_hex,sizeof(ida_tac_hex),buf), 2);
ida_age = (ogs_time_now() - mme_ue->ue_location_timestamp) / 1000000 / 60;
struct avp *avp_mme_location_information;
struct avp *avp_e_utran_cell_global_identity;
struct avp *avp_tracking_area_identity;
struct avp *avp_age_of_location_information;
/* Set the EPS-Location-Information AVP */
ret = fd_msg_avp_new(ogs_diam_s6a_eps_location_information, 0, &avp);
ogs_assert(ret == 0);
ret = fd_msg_avp_new(ogs_diam_s6a_mme_location_information, 0, &avp_mme_location_information);
ogs_assert(ret == 0);
ret = fd_msg_avp_new(ogs_diam_s6a_e_utran_cell_global_identity, 0, &avp_e_utran_cell_global_identity);
ogs_assert(ret == 0);
val.os.data = ida_ecgi;
val.os.len = 7;
ret = fd_msg_avp_setvalue(avp_e_utran_cell_global_identity, &val);
ogs_assert(ret == 0);
ret = fd_msg_avp_add(avp_mme_location_information, MSG_BRW_LAST_CHILD, avp_e_utran_cell_global_identity);
ogs_assert(ret == 0);
ret = fd_msg_avp_new(ogs_diam_s6a_tracking_area_identity, 0, &avp_tracking_area_identity);
ogs_assert(ret == 0);
val.os.data = ida_tai;
val.os.len = 5;
ret = fd_msg_avp_setvalue(avp_tracking_area_identity, &val);
ogs_assert(ret == 0);
ret = fd_msg_avp_add(avp_mme_location_information, MSG_BRW_LAST_CHILD, avp_tracking_area_identity);
ogs_assert(ret == 0);
ret = fd_msg_avp_new(ogs_diam_s6a_age_of_location_information, 0, &avp_age_of_location_information);
ogs_assert(ret == 0);
val.i32 = ida_age;
ret = fd_msg_avp_setvalue(avp_age_of_location_information, &val);
ogs_assert(ret == 0);
ret = fd_msg_avp_add(avp_mme_location_information, MSG_BRW_LAST_CHILD, avp_age_of_location_information);
ogs_assert(ret == 0);
ret = fd_msg_avp_add(avp, MSG_BRW_LAST_CHILD, avp_mme_location_information);
ogs_assert(ret == 0);
ret = fd_msg_avp_add(ans, MSG_BRW_LAST_CHILD, avp);
ogs_assert(ret == 0);
} else {
ogs_error("Insert Subscriber Data with unsupported IDR Flags for IMSI[%s]", imsi_bcd);
/* Set the Origin-Host, Origin-Realm, and Result-Code AVPs */
ret = fd_msg_rescode_set(ans, (char*)"DIAMETER_UNABLE_TO_COMPLY", NULL, NULL, 1);
ogs_assert(ret == 0);
goto outnoexp;
}
/* 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 */
ret = fd_msg_avp_new(ogs_diam_auth_session_state, 0, &avp);
ogs_assert(ret == 0);
val.i32 = OGS_DIAM_AUTH_SESSION_NO_STATE_MAINTAINED;
ret = fd_msg_avp_setvalue(avp, &val);
ogs_assert(ret == 0);
ret = fd_msg_avp_add(ans, MSG_BRW_LAST_CHILD, avp);
ogs_assert(ret == 0);
/* Set Vendor-Specific-Application-Id AVP */
ret = ogs_diam_message_vendor_specific_appid_set(
ans, OGS_DIAM_S6A_APPLICATION_ID);
ogs_assert(ret == 0);
/* Send the answer */
ret = fd_msg_send(msg, NULL, NULL);
ogs_assert(ret == 0);
ogs_debug("Insert-Subscriber-Data-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);
return 0;
out:
ret = ogs_diam_message_experimental_rescode_set(ans, result_code);
ogs_assert(ret == 0);
outnoexp:
/* Set the Auth-Session-State AVP */
ret = fd_msg_avp_new(ogs_diam_auth_session_state, 0, &avp);
ogs_assert(ret == 0);
val.i32 = OGS_DIAM_AUTH_SESSION_NO_STATE_MAINTAINED;
ret = fd_msg_avp_setvalue(avp, &val);
ogs_assert(ret == 0);
ret = fd_msg_avp_add(ans, MSG_BRW_LAST_CHILD, avp);
ogs_assert(ret == 0);
/* Set Vendor-Specific-Application-Id AVP */
ret = ogs_diam_message_vendor_specific_appid_set(
ans, OGS_DIAM_S6A_APPLICATION_ID);
ogs_assert(ret == 0);
/* Send the answer */
ret = fd_msg_send(msg, NULL, NULL);
ogs_assert(ret == 0);
return 0;
}
int mme_fd_init(void)
{
int ret;
@ -1562,6 +1778,12 @@ int mme_fd_init(void)
data.command = ogs_diam_s6a_cmd_clr;
ret = fd_disp_register(mme_ogs_diam_s6a_clr_cb, DISP_HOW_CC, &data, NULL,
&hdl_s6a_clr);
ogs_assert(ret == 0);
/* Specific handler for Insert-Subscriber-Data-Request */
data.command = ogs_diam_s6a_cmd_idr;
ret = fd_disp_register(mme_ogs_diam_s6a_idr_cb, DISP_HOW_CC, &data, NULL,
&hdl_s6a_idr);
ogs_assert(ret == 0);
/* Advertise the support for the application in the peer */
@ -1584,5 +1806,8 @@ void mme_fd_final(void)
if (hdl_s6a_clr)
(void) fd_disp_unregister(&hdl_s6a_clr, NULL);
if (hdl_s6a_idr)
(void) fd_disp_unregister(&hdl_s6a_idr, NULL);
ogs_diam_final();
}

View File

@ -434,6 +434,8 @@ void mme_state_operational(ogs_fsm_t *s, mme_event_t *e)
case OGS_DIAM_S6A_CMD_CODE_CANCEL_LOCATION:
mme_s6a_handle_clr(mme_ue, &s6a_message->clr_message);
break;
case OGS_DIAM_S6A_CMD_CODE_INSERT_SUBSCRIBER_DATA:
break;
default:
ogs_error("Invalid Type[%d]", s6a_message->cmd_code);
break;

View File

@ -511,6 +511,7 @@ void s1ap_handle_uplink_nas_transport(
memcpy(&mme_ue->tai, &enb_ue->saved.tai, sizeof(ogs_eps_tai_t));
memcpy(&mme_ue->e_cgi, &enb_ue->saved.e_cgi, sizeof(ogs_e_cgi_t));
mme_ue->ue_location_timestamp = ogs_time_now();
} else {
ogs_fatal("No UE Context in UplinkNASTransport");
ogs_assert_if_reached();
@ -1897,6 +1898,7 @@ void s1ap_handle_path_switch_request(
mme_ue->enb_ostream_id = enb_ue->enb_ostream_id;
memcpy(&mme_ue->tai, &enb_ue->saved.tai, sizeof(ogs_eps_tai_t));
memcpy(&mme_ue->e_cgi, &enb_ue->saved.e_cgi, sizeof(ogs_e_cgi_t));
mme_ue->ue_location_timestamp = ogs_time_now();
ogs_assert(UESecurityCapabilities);
encryptionAlgorithms =
@ -2939,6 +2941,7 @@ void s1ap_handle_handover_notification(
mme_ue->enb_ostream_id = target_ue->enb_ostream_id;
memcpy(&mme_ue->tai, &target_ue->saved.tai, sizeof(ogs_eps_tai_t));
memcpy(&mme_ue->e_cgi, &target_ue->saved.e_cgi, sizeof(ogs_e_cgi_t));
mme_ue->ue_location_timestamp = ogs_time_now();
ogs_assert(OGS_OK ==
s1ap_send_ue_context_release_command(source_ue,