update it

This commit is contained in:
Sukchan Lee 2017-08-18 20:43:28 +09:00
parent aa40eb24a0
commit 94c8c66fe3
10 changed files with 477 additions and 162 deletions

View File

@ -316,6 +316,7 @@ AC_CONFIG_FILES([lib/s1ap/asn1c/Makefile])
AC_CONFIG_FILES([lib/s1ap/Makefile])
AC_CONFIG_FILES([lib/nas/Makefile])
AC_CONFIG_FILES([lib/fd/extensions/dbg_msg_dumps/Makefile])
#AC_CONFIG_FILES([lib/fd/extensions/dict_legacy_xml/Makefile])
AC_CONFIG_FILES([lib/fd/extensions/dict_rfc5777/Makefile])
AC_CONFIG_FILES([lib/fd/extensions/dict_mip6i/Makefile])
AC_CONFIG_FILES([lib/fd/extensions/dict_nasreq/Makefile])

View File

@ -13,6 +13,7 @@ struct dict_object *fd_destination_host = NULL;
struct dict_object *fd_destination_realm = NULL;
struct dict_object *fd_user_name = NULL;
struct dict_object *fd_auth_session_state = NULL;
struct dict_object *fd_auth_application_id = NULL;
struct dict_object *fd_result_code = NULL;
struct dict_object *fd_experimental_result = NULL;
struct dict_object *fd_experimental_result_code = NULL;
@ -33,6 +34,7 @@ int fd_message_init()
CHECK_dict_search( DICT_AVP, AVP_BY_NAME, "Destination-Realm", &fd_destination_realm);
CHECK_dict_search( DICT_AVP, AVP_BY_NAME, "User-Name", &fd_user_name);
CHECK_dict_search( DICT_AVP, AVP_BY_NAME, "Auth-Session-State", &fd_auth_session_state);
CHECK_dict_search( DICT_AVP, AVP_BY_NAME, "Auth-Application-Id", &fd_auth_application_id);
CHECK_dict_search( DICT_AVP, AVP_BY_NAME, "Result-Code", &fd_result_code);
CHECK_dict_search( DICT_AVP, AVP_BY_NAME, "Experimental-Result", &fd_experimental_result);
CHECK_dict_search( DICT_AVP, AVP_BY_NAME, "Experimental-Result-Code", &fd_experimental_result_code);

View File

@ -16,6 +16,7 @@ extern struct dict_object *fd_destination_host;
extern struct dict_object *fd_destination_realm;
extern struct dict_object *fd_user_name;
extern struct dict_object *fd_auth_session_state;
extern struct dict_object *fd_auth_application_id;
extern struct dict_object *fd_result_code;
extern struct dict_object *fd_experimental_result;
extern struct dict_object *fd_experimental_result_code;

View File

@ -8,14 +8,70 @@ struct dict_object *gx_application = NULL;
struct dict_object *gx_cmd_ccr = NULL;
struct dict_object *gx_cmd_cca = NULL;
struct dict_object *gx_cc_request_type = NULL;
struct dict_object *gx_cc_request_number = NULL;
struct dict_object *gx_network_request_support = NULL;
struct dict_object *gx_subscription_id = NULL;
struct dict_object *gx_supported_features = NULL;
struct dict_object *gx_framed_ip_address = NULL;
struct dict_object *gx_framed_ipv6_prefix = NULL;
struct dict_object *gx_ip_can_type = NULL;
struct dict_object *gx_rat_type = NULL;
struct dict_object *gx_qos_information = NULL;
struct dict_object *gx_3gpp_user_location_info = NULL;
struct dict_object *gx_called_station_id = NULL;
struct dict_object *gx_default_eps_bearer_qos = NULL;
struct dict_object *gx_3gpp_ms_timezone = NULL;
struct dict_object *gx_event_trigger = NULL;
struct dict_object *gx_bearer_control_mode = NULL;
struct dict_object *gx_charging_rule_install = NULL;
struct dict_object *gx_charging_rule_definition = NULL;
struct dict_object *gx_charging_rule_base_name = NULL;
struct dict_object *gx_charging_rule_name = NULL;
struct dict_object *gx_flow_information = NULL;
struct dict_object *gx_flow_direction = NULL;
struct dict_object *gx_flow_description = NULL;
struct dict_object *gx_flow_status = NULL;
struct dict_object *gx_precedence = NULL;
struct dict_object *gx_flows = NULL;
int gx_dict_init(void)
{
application_id_t id = 16777238;
application_id_t id = GX_APPLICATION_ID;
CHECK_dict_search( DICT_APPLICATION, APPLICATION_BY_ID, (void *)&id, &gx_application);
CHECK_dict_search(DICT_APPLICATION, APPLICATION_BY_ID, (void *)&id, &gx_application);
CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Credit-Control-Request", &gx_cmd_ccr);
CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Credit-Control-Answer", &gx_cmd_cca);
CHECK_dict_search(DICT_COMMAND, CMD_BY_NAME, "Credit-Control-Request", &gx_cmd_ccr);
CHECK_dict_search(DICT_COMMAND, CMD_BY_NAME, "Credit-Control-Answer", &gx_cmd_cca);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "CC-Request-Type", &gx_cc_request_type);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "CC-Request-Number", &gx_cc_request_number);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Network-Request-Support", &gx_network_request_support);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Subscription-Id", &gx_subscription_id);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Supported-Features", &gx_supported_features);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Framed-IP-Address", &gx_framed_ip_address);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Framed-IPv6-Prefix", &gx_framed_ipv6_prefix);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "IP-CAN-Type", &gx_ip_can_type);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "RAT-Type", &gx_rat_type);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "QoS-Information", &gx_qos_information);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "3GPP-User-Location-Info", &gx_3gpp_user_location_info);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Called-Station-Id", &gx_called_station_id);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Default-EPS-Bearer-QoS", &gx_default_eps_bearer_qos);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "3GPP-MS-TimeZone", &gx_3gpp_ms_timezone);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Event-Trigger", &gx_event_trigger);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Bearer-Control-Mode", &gx_bearer_control_mode);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Charging-Rule-Install", &gx_charging_rule_install);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Charging-Rule-Definition", &gx_charging_rule_definition);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Charging-Rule-Base-Name", &gx_charging_rule_base_name);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Charging-Rule-Name", &gx_charging_rule_name);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Flow-Information", &gx_flow_information);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Flow-Direction", &gx_flow_direction);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Flow-Description", &gx_flow_description);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Flow-Status", &gx_flow_status);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Precedence", &gx_precedence);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Flows", &gx_flows);
return 0;
}

View File

@ -8,11 +8,40 @@
extern "C" {
#endif /* __cplusplus */
#define GX_APPLICATION_ID 16777238
extern struct dict_object *gx_application;
extern struct dict_object *gx_cmd_ccr;
extern struct dict_object *gx_cmd_cca;
extern struct dict_object *gx_cc_request_typeg;
extern struct dict_object *gx_cc_request_numberg;
extern struct dict_object *gx_network_request_supportg;
extern struct dict_object *gx_subscription_idg;
extern struct dict_object *gx_supported_featuresg;
extern struct dict_object *gx_framed_ip_addressg;
extern struct dict_object *gx_framed_ipv6_prefixg;
extern struct dict_object *gx_ip_can_typeg;
extern struct dict_object *gx_rat_typeg;
extern struct dict_object *gx_qos_informationg;
extern struct dict_object *gx_3gpp_user_location_infog;
extern struct dict_object *gx_called_station_idg;
extern struct dict_object *gx_default_eps_bearer_qosg;
extern struct dict_object *gx_3gpp_ms_timezoneg;
extern struct dict_object *gx_event_triggerg;
extern struct dict_object *gx_bearer_control_modeg;
extern struct dict_object *gx_charging_rule_installg;
extern struct dict_object *gx_charging_rule_definitiong;
extern struct dict_object *gx_charging_rule_base_nameg;
extern struct dict_object *gx_charging_rule_nameg;
extern struct dict_object *gx_flow_informationg;
extern struct dict_object *gx_flow_directiong;
extern struct dict_object *gx_flow_descriptiong;
extern struct dict_object *gx_flow_statusg;
extern struct dict_object *gx_precedenceg;
extern struct dict_object *gx_flowsg;
int gx_dict_init(void);
#ifdef __cplusplus

View File

@ -50,16 +50,16 @@ struct dict_object *s6a_pre_emption_vulnerability = NULL;
int s6a_dict_init(void)
{
application_id_t id = 16777251;
application_id_t id = S6A_APPLICATION_ID;
CHECK_dict_search( DICT_APPLICATION, APPLICATION_BY_ID, (void *)&id, &s6a_application);
CHECK_dict_search(DICT_APPLICATION, APPLICATION_BY_ID, (void *)&id, &s6a_application);
CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Authentication-Information-Request", &s6a_cmd_air);
CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Authentication-Information-Answer", &s6a_cmd_aia);
CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Update-Location-Request", &s6a_cmd_ulr);
CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Update-Location-Answer", &s6a_cmd_ula);
CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Purge-UE-Request", &s6a_cmd_pur);
CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Purge-UE-Answer", &s6a_cmd_pua);
CHECK_dict_search(DICT_COMMAND, CMD_BY_NAME, "Authentication-Information-Request", &s6a_cmd_air);
CHECK_dict_search(DICT_COMMAND, CMD_BY_NAME, "Authentication-Information-Answer", &s6a_cmd_aia);
CHECK_dict_search(DICT_COMMAND, CMD_BY_NAME, "Update-Location-Request", &s6a_cmd_ulr);
CHECK_dict_search(DICT_COMMAND, CMD_BY_NAME, "Update-Location-Answer", &s6a_cmd_ula);
CHECK_dict_search(DICT_COMMAND, CMD_BY_NAME, "Purge-UE-Request", &s6a_cmd_pur);
CHECK_dict_search(DICT_COMMAND, CMD_BY_NAME, "Purge-UE-Answer", &s6a_cmd_pua);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Visited-PLMN-Id", &s6a_visited_plmn_id);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "RAT-Type", &s6a_rat_type);

View File

@ -8,6 +8,8 @@
extern "C" {
#endif /* __cplusplus */
#define S6A_APPLICATION_ID 16777251
#define S6A_DIAMETER_AUTHENTICATION_DATA_UNAVAILABLE 4181
#define S6A_DIAMETER_ERROR_USER_UNKNOWN 5001
#define S6A_DIAMETER_ERROR_ROAMING_NOT_ALLOWED 5004

View File

@ -23,7 +23,7 @@ static struct disp_hdl *hdl_ulr = NULL;
/* Default callback for the application. */
static int hss_fb_cb(struct msg **msg, struct avp *avp,
struct session *sess, void *opaque, enum disp_action *act)
struct session *session, void *opaque, enum disp_action *act)
{
/* This CB should never be called */
d_warn("Unexpected message received!");
@ -33,7 +33,7 @@ static int hss_fb_cb(struct msg **msg, struct avp *avp,
/* Callback for incoming Authentication-Information-Request messages */
static int hss_air_cb( struct msg **msg, struct avp *avp,
struct session *sess, void *opaque, enum disp_action *act)
struct session *session, void *opaque, enum disp_action *act)
{
struct msg *ans, *qry;
struct avp *avp_e_utran_vector, *avp_xres, *avp_kasme, *avp_rand, *avp_autn;
@ -183,7 +183,7 @@ out:
/* Callback for incoming Update-Location-Request messages */
static int hss_ulr_cb( struct msg **msg, struct avp *avp,
struct session *sess, void *opaque, enum disp_action *act)
struct session *session, void *opaque, enum disp_action *act)
{
struct msg *ans, *qry;

View File

@ -20,12 +20,117 @@ struct sess_state {
pool_declare(mme_s6a_sess_pool, struct sess_state, MAX_NUM_SESSION_STATE);
static void mme_s6a_aia_cb(void *data, struct msg **msg);
static void mme_s6a_ula_cb(void *data, struct msg **msg);
/* MME Sends Authentication Information Request to HSS */
void mme_s6a_send_air(mme_ue_t *mme_ue)
{
struct msg *req = NULL;
struct avp *avp;
struct avp *avpch;
union avp_value val;
struct sess_state *mi = NULL, *svg;
struct session *session = NULL;
d_assert(mme_ue, return, "Null Param");
/* Clear Security Context */
CLEAR_SECURITY_CONTEXT(mme_ue);
/* Create the random value to store with the session */
pool_alloc_node(&mme_s6a_sess_pool, &mi);
d_assert(mi, return, "malloc failed: %s", strerror(errno));
mi->mme_ue = mme_ue;
/* Create the request */
CHECK_FCT_DO( fd_msg_new(s6a_cmd_air, MSGFL_ALLOC_ETEID, &req), goto out );
/* Create a new session */
#define S6A_APP_SID_OPT "app_s6a"
CHECK_FCT_DO( fd_msg_new_session(req, (os0_t)S6A_APP_SID_OPT,
CONSTSTRLEN(S6A_APP_SID_OPT)), goto out );
CHECK_FCT_DO( fd_msg_sess_get(fd_g_config->cnf_dict, req, &session, NULL),
goto out );
/* Set the Auth-Session-State AVP */
CHECK_FCT_DO( fd_msg_avp_new(fd_auth_session_state, 0, &avp), goto out );
val.i32 = 1;
CHECK_FCT_DO( fd_msg_avp_setvalue(avp, &val), goto out );
CHECK_FCT_DO( fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp), goto out );
/* Set Origin-Host & Origin-Realm */
CHECK_FCT_DO( fd_msg_add_origin(req, 0), goto out );
/* Set the Destination-Realm AVP */
CHECK_FCT_DO( fd_msg_avp_new(fd_destination_realm, 0, &avp), goto out );
val.os.data = (unsigned char *)(fd_g_config->cnf_diamrlm);
val.os.len = strlen(fd_g_config->cnf_diamrlm);
CHECK_FCT_DO( fd_msg_avp_setvalue(avp, &val), goto out );
CHECK_FCT_DO( fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp), goto out );
/* Set the User-Name AVP */
CHECK_FCT_DO( fd_msg_avp_new(fd_user_name, 0, &avp), goto out );
val.os.data = (c_uint8_t *)mme_ue->imsi_bcd;
val.os.len = strlen(mme_ue->imsi_bcd);
CHECK_FCT_DO( fd_msg_avp_setvalue(avp, &val), goto out );
CHECK_FCT_DO( fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp), goto out );
/* Add the Authentication-Info */
CHECK_FCT_DO( fd_msg_avp_new(s6a_req_eutran_auth_info, 0, &avp), goto out );
CHECK_FCT_DO( fd_msg_avp_new(s6a_number_of_requested_vectors, 0, &avpch),
goto out );
val.u32 = 1;
CHECK_FCT_DO( fd_msg_avp_setvalue (avpch, &val), goto out );
CHECK_FCT_DO( fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, avpch), goto out );
CHECK_FCT_DO( fd_msg_avp_new(s6a_immediate_response_preferred, 0, &avpch),
goto out );
val.u32 = 1;
CHECK_FCT_DO( fd_msg_avp_setvalue(avpch, &val), goto out );
CHECK_FCT_DO( fd_msg_avp_add(avp, MSG_BRW_LAST_CHILD, avpch), goto out );
CHECK_FCT_DO( fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp), goto out );
/* Set the Visited-PLMN-Id AVP */
CHECK_FCT_DO( fd_msg_avp_new(s6a_visited_plmn_id, 0, &avp), goto out );
val.os.data = (c_uint8_t *)&mme_ue->visited_plmn_id;
val.os.len = PLMN_ID_LEN;
CHECK_FCT_DO( fd_msg_avp_setvalue(avp, &val), goto out );
CHECK_FCT_DO( fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp), goto out );
CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &mi->ts), goto out );
/* Keep a pointer to the session data for debug purpose,
* in real life we would not need it */
svg = mi;
/* Store this value in the session */
CHECK_FCT_DO( fd_sess_state_store(mme_s6a_reg, session, &mi), goto out );
/* Send the request */
CHECK_FCT_DO( fd_msg_send(&req, mme_s6a_aia_cb, svg), goto out );
/* Increment the counter */
CHECK_POSIX_DO( pthread_mutex_lock(&fd_logger_self()->stats_lock), );
fd_logger_self()->stats.nb_sent++;
CHECK_POSIX_DO( pthread_mutex_unlock(&fd_logger_self()->stats_lock), );
d_trace(3, "[S6A] Authentication-Information-Request : UE[%s] --> HSS\n",
mme_ue->imsi_bcd);
out:
pool_free_node(&mme_s6a_sess_pool, mi);
return;
}
/* MME received Authentication Information Answer from HSS */
static void mme_s6a_aia_cb(void *data, struct msg **msg)
{
struct sess_state *mi = NULL;
struct timespec ts;
struct session *sess;
struct session *session;
struct avp *avp, *avpch;
struct avp *avp_e_utran_vector, *avp_xres, *avp_kasme, *avp_rand, *avp_autn;
struct avp_hdr *hdr;
@ -40,17 +145,17 @@ static void mme_s6a_aia_cb(void *data, struct msg **msg)
CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &ts), return );
/* Search the session, retrieve its data */
CHECK_FCT_DO( fd_msg_sess_get(fd_g_config->cnf_dict, *msg, &sess, &new),
CHECK_FCT_DO( fd_msg_sess_get(fd_g_config->cnf_dict, *msg, &session, &new),
return );
d_assert(new == 0, return, );
CHECK_FCT_DO( fd_sess_state_retrieve(mme_s6a_reg, sess, &mi), return );
CHECK_FCT_DO( fd_sess_state_retrieve(mme_s6a_reg, session, &mi), return );
d_assert(mi && (void *)mi == data, return, );
mme_ue = mi->mme_ue;
d_assert(mme_ue, return, );
d_trace(3, "[S6A] Authentication-Information-Response : UE[%s] <-- HSS\n",
d_trace(3, "[S6A] Authentication-Information-Answer : UE[%s] <-- HSS\n",
mme_ue->imsi_bcd);
/* Value of Result Code */
@ -232,23 +337,16 @@ out:
return;
}
/* MME Sends Authentication Information Request to HSS */
void mme_s6a_send_air(mme_ue_t *mme_ue)
/* MME Sends Update Location Request to HSS */
void mme_s6a_send_ulr(mme_ue_t *mme_ue)
{
struct msg *req = NULL;
struct avp *avp;
struct avp *avpch;
union avp_value val;
struct sess_state *mi = NULL, *svg;
struct session *sess = NULL;
enb_ue_t *enb_ue = NULL;
struct session *session = NULL;
d_assert(mme_ue, return, "Null Param");
enb_ue = mme_ue->enb_ue;
d_assert(enb_ue, return, "Null Param");
/* Clear Security Context */
CLEAR_SECURITY_CONTEXT(mme_ue);
/* Create the random value to store with the session */
pool_alloc_node(&mme_s6a_sess_pool, &mi);
@ -257,13 +355,13 @@ void mme_s6a_send_air(mme_ue_t *mme_ue)
mi->mme_ue = mme_ue;
/* Create the request */
CHECK_FCT_DO( fd_msg_new(s6a_cmd_air, MSGFL_ALLOC_ETEID, &req), goto out );
CHECK_FCT_DO( fd_msg_new(s6a_cmd_ulr, MSGFL_ALLOC_ETEID, &req), goto out );
/* Create a new session */
#define S6A_APP_SID_OPT "app_s6a"
CHECK_FCT_DO( fd_msg_new_session(req, (os0_t)S6A_APP_SID_OPT,
CONSTSTRLEN(S6A_APP_SID_OPT)), goto out );
CHECK_FCT_DO( fd_msg_sess_get(fd_g_config->cnf_dict, req, &sess, NULL),
CHECK_FCT_DO( fd_msg_sess_get(fd_g_config->cnf_dict, req, &session, NULL),
goto out );
/* Set the Auth-Session-State AVP */
@ -273,45 +371,47 @@ void mme_s6a_send_air(mme_ue_t *mme_ue)
CHECK_FCT_DO( fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp), goto out );
/* Set Origin-Host & Origin-Realm */
CHECK_FCT_DO( fd_msg_add_origin(req, 0), goto out );
CHECK_FCT_DO( fd_msg_add_origin(req, 0), goto out );
/* Set the Destination-Realm AVP */
CHECK_FCT_DO( fd_msg_avp_new(fd_destination_realm, 0, &avp), goto out );
val.os.data = (unsigned char *)(fd_g_config->cnf_diamrlm);
val.os.len = strlen(fd_g_config->cnf_diamrlm);
CHECK_FCT_DO( fd_msg_avp_setvalue(avp, &val), goto out );
CHECK_FCT_DO( fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp), goto out );
CHECK_FCT_DO( fd_msg_avp_setvalue(avp, &val), goto out );
CHECK_FCT_DO( fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp), goto out );
/* Set the User-Name AVP */
CHECK_FCT_DO( fd_msg_avp_new(fd_user_name, 0, &avp), goto out );
val.os.data = (c_uint8_t *)mme_ue->imsi_bcd;
val.os.len = strlen(mme_ue->imsi_bcd);
CHECK_FCT_DO( fd_msg_avp_setvalue(avp, &val), goto out );
CHECK_FCT_DO( fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp), goto out );
/* Set the RAT-Type */
CHECK_FCT_DO( fd_msg_avp_new(s6a_rat_type, 0, &avp), goto out );
val.u32 = S6A_RAT_TYPE_EUTRAN;
CHECK_FCT_DO( fd_msg_avp_setvalue(avp, &val), goto out );
CHECK_FCT_DO( fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp), goto out );
/* Add the Authentication-Info */
CHECK_FCT_DO( fd_msg_avp_new(s6a_req_eutran_auth_info, 0, &avp), goto out );
CHECK_FCT_DO( fd_msg_avp_new(s6a_number_of_requested_vectors, 0, &avpch),
goto out );
val.u32 = 1;
CHECK_FCT_DO( fd_msg_avp_setvalue (avpch, &val), goto out );
CHECK_FCT_DO( fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, avpch), goto out );
CHECK_FCT_DO( fd_msg_avp_new(s6a_immediate_response_preferred, 0, &avpch),
goto out );
val.u32 = 1;
CHECK_FCT_DO( fd_msg_avp_setvalue(avpch, &val), goto out );
CHECK_FCT_DO( fd_msg_avp_add(avp, MSG_BRW_LAST_CHILD, avpch), goto out );
/* Set the ULR-Flags */
CHECK_FCT_DO( fd_msg_avp_new(s6a_ulr_flags, 0, &avp), goto out );
val.u32 = S6A_ULR_S6A_S6D_INDICATOR;
CHECK_FCT_DO( fd_msg_avp_setvalue(avp, &val), goto out );
CHECK_FCT_DO( fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp), goto out );
/* Set the Visited-PLMN-Id AVP */
/* Set the Visited-PLMN-Id */
CHECK_FCT_DO( fd_msg_avp_new(s6a_visited_plmn_id, 0, &avp), goto out );
val.os.data = (c_uint8_t *)&mme_ue->visited_plmn_id;
val.os.len = PLMN_ID_LEN;
CHECK_FCT_DO( fd_msg_avp_setvalue(avp, &val), goto out );
CHECK_FCT_DO( fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp), goto out );
/* Set the UE-SRVCC Capability */
CHECK_FCT_DO( fd_msg_avp_new(s6a_ue_srvcc_capability, 0, &avp), goto out );
val.u32 = S6A_UE_SRVCC_NOT_SUPPORTED;
CHECK_FCT_DO( fd_msg_avp_setvalue(avp, &val), goto out );
CHECK_FCT_DO( fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp), goto out );
CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &mi->ts), goto out );
/* Keep a pointer to the session data for debug purpose,
@ -319,17 +419,17 @@ void mme_s6a_send_air(mme_ue_t *mme_ue)
svg = mi;
/* Store this value in the session */
CHECK_FCT_DO( fd_sess_state_store(mme_s6a_reg, sess, &mi), goto out );
CHECK_FCT_DO( fd_sess_state_store(mme_s6a_reg, session, &mi), goto out );
/* Send the request */
CHECK_FCT_DO( fd_msg_send(&req, mme_s6a_aia_cb, svg), goto out );
CHECK_FCT_DO( fd_msg_send(&req, mme_s6a_ula_cb, svg), goto out );
/* Increment the counter */
CHECK_POSIX_DO( pthread_mutex_lock(&fd_logger_self()->stats_lock), );
fd_logger_self()->stats.nb_sent++;
CHECK_POSIX_DO( pthread_mutex_unlock(&fd_logger_self()->stats_lock), );
d_trace(3, "[S6A] Authentication-Information-Request : UE[%s] --> HSS\n",
d_trace(3, "[S6A] Update-Location-Request : UE[%s] --> HSS\n",
mme_ue->imsi_bcd);
out:
@ -342,7 +442,7 @@ static void mme_s6a_ula_cb(void *data, struct msg **msg)
{
struct sess_state *mi = NULL;
struct timespec ts;
struct session *sess;
struct session *session;
struct avp *avp, *avpch;
struct avp *avpch1, *avpch2, *avpch3, *avpch4, *avpch5;
struct avp_hdr *hdr;
@ -358,17 +458,17 @@ static void mme_s6a_ula_cb(void *data, struct msg **msg)
CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &ts), return );
/* Search the session, retrieve its data */
CHECK_FCT_DO( fd_msg_sess_get(fd_g_config->cnf_dict, *msg, &sess, &new),
CHECK_FCT_DO( fd_msg_sess_get(fd_g_config->cnf_dict, *msg, &session, &new),
return );
d_assert(new == 0, return, );
CHECK_FCT_DO( fd_sess_state_retrieve(mme_s6a_reg, sess, &mi), return );
CHECK_FCT_DO( fd_sess_state_retrieve(mme_s6a_reg, session, &mi), return );
d_assert(mi && (void *)mi == data, return, );
mme_ue = mi->mme_ue;
d_assert(mme_ue, return, );
d_trace(3, "[S6A] Update-Location-Response : UE[%s] <-- HSS\n",
d_trace(3, "[S6A] Update-Location-Answer : UE[%s] <-- HSS\n",
mme_ue->imsi_bcd);
/* Value of Result Code */
@ -705,105 +805,6 @@ static void mme_s6a_ula_cb(void *data, struct msg **msg)
return;
}
/* MME Sends Update Location Request to HSS */
void mme_s6a_send_ulr(mme_ue_t *mme_ue)
{
struct msg *req = NULL;
struct avp *avp;
union avp_value val;
struct sess_state *mi = NULL, *svg;
struct session *sess = NULL;
d_assert(mme_ue, return, "Null Param");
/* Create the random value to store with the session */
pool_alloc_node(&mme_s6a_sess_pool, &mi);
d_assert(mi, return, "malloc failed: %s", strerror(errno));
mi->mme_ue = mme_ue;
/* Create the request */
CHECK_FCT_DO( fd_msg_new(s6a_cmd_ulr, MSGFL_ALLOC_ETEID, &req), goto out );
/* Create a new session */
#define S6A_APP_SID_OPT "app_s6a"
CHECK_FCT_DO( fd_msg_new_session(req, (os0_t)S6A_APP_SID_OPT,
CONSTSTRLEN(S6A_APP_SID_OPT)), goto out );
CHECK_FCT_DO( fd_msg_sess_get(fd_g_config->cnf_dict, req, &sess, NULL),
goto out );
/* Set the Auth-Session-State AVP */
CHECK_FCT_DO( fd_msg_avp_new(fd_auth_session_state, 0, &avp), goto out );
val.i32 = 1;
CHECK_FCT_DO( fd_msg_avp_setvalue(avp, &val), goto out );
CHECK_FCT_DO( fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp), goto out );
/* Set Origin-Host & Origin-Realm */
CHECK_FCT_DO( fd_msg_add_origin(req, 0), goto out );
/* Set the Destination-Realm AVP */
CHECK_FCT_DO( fd_msg_avp_new(fd_destination_realm, 0, &avp), goto out );
val.os.data = (unsigned char *)(fd_g_config->cnf_diamrlm);
val.os.len = strlen(fd_g_config->cnf_diamrlm);
CHECK_FCT_DO( fd_msg_avp_setvalue(avp, &val), goto out );
CHECK_FCT_DO( fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp), goto out );
/* Set the User-Name AVP */
CHECK_FCT_DO( fd_msg_avp_new(fd_user_name, 0, &avp), goto out );
val.os.data = (c_uint8_t *)mme_ue->imsi_bcd;
val.os.len = strlen(mme_ue->imsi_bcd);
CHECK_FCT_DO( fd_msg_avp_setvalue(avp, &val), goto out );
CHECK_FCT_DO( fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp), goto out );
/* Set the RAT-Type */
CHECK_FCT_DO( fd_msg_avp_new(s6a_rat_type, 0, &avp), goto out );
val.u32 = S6A_RAT_TYPE_EUTRAN;
CHECK_FCT_DO( fd_msg_avp_setvalue(avp, &val), goto out );
CHECK_FCT_DO( fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp), goto out );
/* Set the ULR-Flags */
CHECK_FCT_DO( fd_msg_avp_new(s6a_ulr_flags, 0, &avp), goto out );
val.u32 = S6A_ULR_S6A_S6D_INDICATOR;
CHECK_FCT_DO( fd_msg_avp_setvalue(avp, &val), goto out );
CHECK_FCT_DO( fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp), goto out );
/* Set the Visited-PLMN-Id */
CHECK_FCT_DO( fd_msg_avp_new(s6a_visited_plmn_id, 0, &avp), goto out );
val.os.data = (c_uint8_t *)&mme_ue->visited_plmn_id;
val.os.len = PLMN_ID_LEN;
CHECK_FCT_DO( fd_msg_avp_setvalue(avp, &val), goto out );
CHECK_FCT_DO( fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp), goto out );
/* Set the UE-SRVCC Capability */
CHECK_FCT_DO( fd_msg_avp_new(s6a_ue_srvcc_capability, 0, &avp), goto out );
val.u32 = S6A_UE_SRVCC_NOT_SUPPORTED;
CHECK_FCT_DO( fd_msg_avp_setvalue(avp, &val), goto out );
CHECK_FCT_DO( fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp), goto out );
CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &mi->ts), goto out );
/* Keep a pointer to the session data for debug purpose,
* in real life we would not need it */
svg = mi;
/* Store this value in the session */
CHECK_FCT_DO( fd_sess_state_store(mme_s6a_reg, sess, &mi), goto out );
/* Send the request */
CHECK_FCT_DO( fd_msg_send(&req, mme_s6a_ula_cb, svg), goto out );
/* Increment the counter */
CHECK_POSIX_DO( pthread_mutex_lock(&fd_logger_self()->stats_lock), );
fd_logger_self()->stats.nb_sent++;
CHECK_POSIX_DO( pthread_mutex_unlock(&fd_logger_self()->stats_lock), );
d_trace(3, "[S6A] Update-Location-Request : UE[%s] --> HSS\n",
mme_ue->imsi_bcd);
out:
pool_free_node(&mme_s6a_sess_pool, mi);
return;
}
int mme_s6a_init(void)
{

View File

@ -13,21 +13,244 @@
static struct session_handler *pgw_gx_reg = NULL;
struct sess_state {
#if 0 /* FIXME */
mme_ue_t *mme_ue;
#endif
pgw_sess_t *sess;
struct timespec ts; /* Time of sending the message */
};
pool_declare(pgw_gx_sess_pool, struct sess_state, MAX_NUM_SESSION_STATE);
/* PGW Sends Credit Control Request to PCRF */
#if 0
void pgw_gx_send_air(mme_ue_t *mme_ue)
static void pgw_gx_cca_cb(void *data, struct msg **msg);
void pgw_gx_send_ccr(pgw_sess_t *sess)
{
struct msg *req = NULL;
struct avp *avp;
#if 0
struct avp *avpch;
#endif
union avp_value val;
struct sess_state *mi = NULL, *svg;
struct session *session = NULL;
d_assert(sess, return, "Null Param");
/* Create the random value to store with the session */
pool_alloc_node(&pgw_gx_sess_pool, &mi);
d_assert(mi, return, "malloc failed: %s", strerror(errno));
mi->sess = sess;
/* Create the request */
CHECK_FCT_DO( fd_msg_new(gx_cmd_ccr, MSGFL_ALLOC_ETEID, &req), goto out );
/* Create a new session */
#define GX_APP_SID_OPT "app_gx"
CHECK_FCT_DO( fd_msg_new_session(req, (os0_t)GX_APP_SID_OPT,
CONSTSTRLEN(GX_APP_SID_OPT)), goto out );
CHECK_FCT_DO( fd_msg_sess_get(fd_g_config->cnf_dict, req, &session, NULL),
goto out );
/* Set Origin-Host & Origin-Realm */
CHECK_FCT_DO( fd_msg_add_origin(req, 0), goto out );
/* Set the Destination-Realm AVP */
CHECK_FCT_DO( fd_msg_avp_new(fd_destination_realm, 0, &avp), goto out );
val.os.data = (unsigned char *)(fd_g_config->cnf_diamrlm);
val.os.len = strlen(fd_g_config->cnf_diamrlm);
CHECK_FCT_DO( fd_msg_avp_setvalue(avp, &val), goto out );
CHECK_FCT_DO( fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp), goto out );
/* Set the Auth-Application-Id AVP */
CHECK_FCT_DO( fd_msg_avp_new(fd_auth_application_id, 0, &avp), goto out );
val.i32 = GX_APPLICATION_ID;
CHECK_FCT_DO( fd_msg_avp_setvalue(avp, &val), goto out );
CHECK_FCT_DO( fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp), goto out );
CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &mi->ts), goto out );
/* Keep a pointer to the session data for debug purpose,
* in real life we would not need it */
svg = mi;
/* Store this value in the session */
CHECK_FCT_DO( fd_sess_state_store(pgw_gx_reg, session, &mi), goto out );
/* Send the request */
CHECK_FCT_DO( fd_msg_send(&req, pgw_gx_cca_cb, svg), goto out );
/* Increment the counter */
CHECK_POSIX_DO( pthread_mutex_lock(&fd_logger_self()->stats_lock), );
fd_logger_self()->stats.nb_sent++;
CHECK_POSIX_DO( pthread_mutex_unlock(&fd_logger_self()->stats_lock), );
#if 0
d_trace(3, "[S6A] Authentication-Information-Request : UE[%s] --> HSS\n",
mme_ue->imsi_bcd);
#endif
out:
pool_free_node(&pgw_gx_sess_pool, mi);
return;
}
static void pgw_gx_cca_cb(void *data, struct msg **msg)
{
struct sess_state *mi = NULL;
struct timespec ts;
struct session *session;
struct avp *avp, *avpch;
#if 0
struct avp *avp_e_utran_vector, *avp_xres, *avp_kasme, *avp_rand, *avp_autn;
#endif
struct avp_hdr *hdr;
unsigned long dur;
int error = 0;
c_uint32_t result_code = 0;
int new;
#if 0
event_t e;
#endif
pgw_sess_t *sess = NULL;
CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &ts), return );
/* Search the session, retrieve its data */
CHECK_FCT_DO( fd_msg_sess_get(fd_g_config->cnf_dict, *msg, &session, &new),
return );
d_assert(new == 0, return, );
CHECK_FCT_DO( fd_sess_state_retrieve(pgw_gx_reg, session, &mi), return );
d_assert(mi && (void *)mi == data, return, );
sess = mi->sess;
d_assert(sess, return, );
#if 0
d_trace(3, "[Gx] Credit-Information-Answer : UE[%s] <-- HSS\n",
mme_ue->imsi_bcd);
#endif
/* Value of Result Code */
CHECK_FCT_DO( fd_msg_search_avp(*msg, fd_result_code, &avp), return );
if (avp)
{
CHECK_FCT_DO( fd_msg_avp_hdr(avp, &hdr), return);
result_code = hdr->avp_value->i32;
d_trace(3, "Result Code: %d\n", hdr->avp_value->i32);
}
else
{
CHECK_FCT_DO( fd_msg_search_avp(*msg,
fd_experimental_result, &avp), return );
if (avp)
{
CHECK_FCT_DO( fd_avp_search_avp(avp,
fd_experimental_result_code, &avpch), return );
if (avpch)
{
CHECK_FCT_DO( fd_msg_avp_hdr(avpch, &hdr), return);
result_code = hdr->avp_value->i32;
d_trace(3, "Experimental Result Code: %d\n", result_code);
}
}
else
{
d_error("no Result-Code");
error++;
}
}
/* Value of Origin-Host */
CHECK_FCT_DO( fd_msg_search_avp(*msg, fd_origin_host, &avp), return );
if (avp)
{
CHECK_FCT_DO( fd_msg_avp_hdr(avp, &hdr), return );
d_trace(3, "From '%.*s' ",
(int)hdr->avp_value->os.len, hdr->avp_value->os.data);
}
else
{
d_error("no_Origin-Host ");
error++;
}
/* Value of Origin-Realm */
CHECK_FCT_DO( fd_msg_search_avp(*msg, fd_origin_realm, &avp), return );
if (avp)
{
CHECK_FCT_DO( fd_msg_avp_hdr(avp, &hdr), return );
d_trace(3, "('%.*s') ",
(int)hdr->avp_value->os.len, hdr->avp_value->os.data);
}
else
{
d_error("no_Origin-Realm ");
error++;
}
if (result_code != ER_DIAMETER_SUCCESS)
{
d_warn("ERROR DIAMETER Result Code(%d)", result_code);
error++;
goto out;
}
out:
#if 0
event_set(&e, MME_EVT_EMM_UE_FROM_S6A);
event_set_param1(&e, (c_uintptr_t)mme_ue->index);
event_set_param2(&e, (c_uintptr_t)S6A_CMD_AUTHENTICATION_INFORMATION);
event_set_param3(&e, (c_uintptr_t)result_code);
mme_event_send(&e);
#endif
/* Free the message */
CHECK_POSIX_DO( pthread_mutex_lock(&fd_logger_self()->stats_lock), );
dur = ((ts.tv_sec - mi->ts.tv_sec) * 1000000) +
((ts.tv_nsec - mi->ts.tv_nsec) / 1000);
if (fd_logger_self()->stats.nb_recv)
{
/* Ponderate in the avg */
fd_logger_self()->stats.avg = (fd_logger_self()->stats.avg *
fd_logger_self()->stats.nb_recv + dur) /
(fd_logger_self()->stats.nb_recv + 1);
/* Min, max */
if (dur < fd_logger_self()->stats.shortest)
fd_logger_self()->stats.shortest = dur;
if (dur > fd_logger_self()->stats.longest)
fd_logger_self()->stats.longest = dur;
}
else
{
fd_logger_self()->stats.shortest = dur;
fd_logger_self()->stats.longest = dur;
fd_logger_self()->stats.avg = dur;
}
if (error)
fd_logger_self()->stats.nb_errs++;
else
fd_logger_self()->stats.nb_recv++;
CHECK_POSIX_DO( pthread_mutex_unlock(&fd_logger_self()->stats_lock), );
/* Display how long it took */
if (ts.tv_nsec > mi->ts.tv_nsec)
d_trace(3, "in %d.%06ld sec\n",
(int)(ts.tv_sec - mi->ts.tv_sec),
(long)(ts.tv_nsec - mi->ts.tv_nsec) / 1000);
else
d_trace(3, "in %d.%06ld sec\n",
(int)(ts.tv_sec + 1 - mi->ts.tv_sec),
(long)(1000000000 + ts.tv_nsec - mi->ts.tv_nsec) / 1000);
CHECK_FCT_DO( fd_msg_free(*msg), return );
*msg = NULL;
pool_free_node(&pgw_gx_sess_pool, mi);
return;
}
int pgw_gx_init(void)
{