From 5fd0a0984950604f8ba4de39d9c560cc19340a2d Mon Sep 17 00:00:00 2001 From: Jason Penton Date: Thu, 26 Feb 2015 21:57:33 +0200 Subject: [PATCH] modules/ims_charging: added access-network-information data to CCR -allows OCS to know location of UE when charge was made -tested with 3GPP EUTRAN FDD using utran-cell-id-3gpp as base station id --- modules/ims_charging/Ro_data.c | 7 ++++++- modules/ims_charging/Ro_data.h | 6 ++++-- modules/ims_charging/ccr.c | 4 ++++ modules/ims_charging/ims_ro.c | 20 ++++++++++---------- modules/ims_charging/ims_ro.h | 2 +- modules/ims_charging/mod.c | 4 +++- modules/ims_charging/ro_session_hash.c | 7 ++++++- modules/ims_charging/ro_session_hash.h | 5 ++++- 8 files changed, 38 insertions(+), 17 deletions(-) diff --git a/modules/ims_charging/Ro_data.c b/modules/ims_charging/Ro_data.c index f53fec8e0c8..88e4755546c 100644 --- a/modules/ims_charging/Ro_data.c +++ b/modules/ims_charging/Ro_data.c @@ -87,7 +87,7 @@ time_stamps_t * new_time_stamps(time_t *sip_request_timestamp, uint32_t *sip_req } ims_information_t * new_ims_information(event_type_t * event_type, time_stamps_t * time_stamps, str * user_session_id, str * outgoing_session_id, str * calling_party, - str * called_party, str * icid, str * orig_ioi, str * term_ioi, int node_role, str *incoming_trunk_id, str *outgoing_trunk_id) { + str * called_party, str * icid, str * orig_ioi, str * term_ioi, int node_role, str *incoming_trunk_id, str *outgoing_trunk_id, str* pani) { str_list_slot_t *sl = 0; ims_information_t *x = 0; @@ -123,6 +123,10 @@ ims_information_t * new_ims_information(event_type_t * event_type, time_stamps_t if (outgoing_trunk_id && outgoing_trunk_id->s) str_dup_ptr(x->outgoing_trunk_id, *outgoing_trunk_id, pkg); + + if (pani && pani->s) { + str_dup_ptr(x->access_network_info, *pani, pkg); + } //WL_FREE_ALL(&(x->called_asserted_identity),str_list_t,pkg); //str_free_ptr(x->requested_party_address,pkg); @@ -239,6 +243,7 @@ void ims_information_free(ims_information_t *x) { str_free_ptr(x->incoming_trunk_id, pkg); str_free_ptr(x->outgoing_trunk_id, pkg); + str_free_ptr(x->access_network_info, pkg); time_stamps_free(x->time_stamps); diff --git a/modules/ims_charging/Ro_data.h b/modules/ims_charging/Ro_data.h index e68d4b7ba0d..26dd0dc327f 100644 --- a/modules/ims_charging/Ro_data.h +++ b/modules/ims_charging/Ro_data.h @@ -271,7 +271,8 @@ typedef struct { str_list_t calling_party_address; str *called_party_address; str_list_t called_asserted_identity; - str * requested_party_address; + str *requested_party_address; + str *access_network_info; time_stamps_t *time_stamps; @@ -398,7 +399,8 @@ ims_information_t * new_ims_information(event_type_t * event_type, str * term_ioi, int node_role, str *incoming_trunk_id, - str *outgoing_trunk_id); + str *outgoing_trunk_id, + str *pani); void event_type_free(event_type_t *x); void time_stamps_free(time_stamps_t *x); diff --git a/modules/ims_charging/ccr.c b/modules/ims_charging/ccr.c index a315f872b6d..140d1c1d325 100644 --- a/modules/ims_charging/ccr.c +++ b/modules/ims_charging/ccr.c @@ -108,6 +108,10 @@ int Ro_write_ims_information_avps(AAA_AVP_LIST * avp_list, ims_information_t* x) cdp_avp->cdp->AAAFreeAVPList(&aList); aList.head = aList.tail = 0; } + + if (x->access_network_info) { + cdp_avp->imsapp.add_Access_Network_Information(&aList2, *(x->access_network_info), 0); + } for (sl = x->called_asserted_identity.head; sl; sl = sl->next) { if (!cdp_avp->epcapp.add_Called_Asserted_Identity(&aList2, sl->data, 0)) diff --git a/modules/ims_charging/ims_ro.c b/modules/ims_charging/ims_ro.c index 80090c92dd6..b2d46cfe9d2 100644 --- a/modules/ims_charging/ims_ro.c +++ b/modules/ims_charging/ims_ro.c @@ -380,7 +380,7 @@ int get_timestamps(struct sip_msg * req, struct sip_msg * reply, time_t * req_ti */ Ro_CCR_t * dlg_create_ro_session(struct sip_msg * req, struct sip_msg * reply, AAASession ** authp, int dir, str asserted_identity, - str called_asserted_identity, str subscription_id, int subscription_id_type, str* incoming_trunk_id, str *outgoing_trunk_id) { + str called_asserted_identity, str subscription_id, int subscription_id_type, str* incoming_trunk_id, str *outgoing_trunk_id, str* pani) { Ro_CCR_t * ro_ccr_data = 0; AAASession * auth = NULL; @@ -419,7 +419,7 @@ Ro_CCR_t * dlg_create_ro_session(struct sip_msg * req, struct sip_msg * reply, A goto error; if (!(ims_info = new_ims_information(event_type, time_stamps, &callid, &callid, &asserted_identity, &called_asserted_identity, &icid, - &orig_ioi, &term_ioi, dir, incoming_trunk_id, outgoing_trunk_id))) + &orig_ioi, &term_ioi, dir, incoming_trunk_id, outgoing_trunk_id, pani))) goto error; event_type = 0; time_stamps = 0; @@ -467,13 +467,13 @@ Ro_CCR_t * dlg_create_ro_session(struct sip_msg * req, struct sip_msg * reply, A } int sip_create_ro_ccr_data(struct sip_msg * msg, int dir, Ro_CCR_t ** ro_ccr_data, AAASession ** auth, str asserted_identity, str called_asserted_identity, - str subscription_id, int subscription_id_type, str* incoming_trunk_id, str* outgoing_trunk_id) { + str subscription_id, int subscription_id_type, str* incoming_trunk_id, str* outgoing_trunk_id, str* pani) { if (msg->first_line.type == SIP_REQUEST) { /*end of session*/ if (strncmp(msg->first_line.u.request.method.s, "INVITE", 6) == 0) { if (!(*ro_ccr_data = dlg_create_ro_session(msg, NULL, auth, dir, asserted_identity, called_asserted_identity, subscription_id, - subscription_id_type, incoming_trunk_id, outgoing_trunk_id))) + subscription_id_type, incoming_trunk_id, outgoing_trunk_id, pani))) goto error; } } else { @@ -526,7 +526,7 @@ void send_ccr_interim(struct ro_session* ro_session, unsigned int used, unsigned goto error; if (!(ims_info = new_ims_information(event_type, time_stamps, &ro_session->callid, &ro_session->callid, &ro_session->asserted_identity, - &ro_session->called_asserted_identity, 0, 0, 0, ro_session->direction, &ro_session->incoming_trunk_id, &ro_session->outgoing_trunk_id))) + &ro_session->called_asserted_identity, 0, 0, 0, ro_session->direction, &ro_session->incoming_trunk_id, &ro_session->outgoing_trunk_id, 0))) goto error; LM_DBG("Created IMS information\n"); @@ -760,7 +760,7 @@ void send_ccr_stop(struct ro_session *ro_session) { goto error0; if (!(ims_info = new_ims_information(event_type, time_stamps, &ro_session->callid, &ro_session->callid, &ro_session->asserted_identity, - &ro_session->called_asserted_identity, 0, 0, 0, ro_session->direction, &ro_session->incoming_trunk_id, &ro_session->outgoing_trunk_id))) + &ro_session->called_asserted_identity, 0, 0, 0, ro_session->direction, &ro_session->incoming_trunk_id, &ro_session->outgoing_trunk_id, 0))) goto error0; event_type = 0; @@ -926,7 +926,7 @@ static void resume_on_termination_ccr(int is_timeout, void *param, AAAMessage *c * @returns #CSCF_RETURN_BREAK if OK, #CSCF_RETURN_ERROR on error */ int Ro_Send_CCR(struct sip_msg *msg, struct dlg_cell *dlg, int dir, int reservation_units, str* incoming_trunk_id, str* outgoing_trunk_id, - cfg_action_t* action, unsigned int tindex, unsigned int tlabel) { + str* pani, cfg_action_t* action, unsigned int tindex, unsigned int tlabel) { str session_id = {0, 0}, called_asserted_identity = {0, 0}, subscription_id = {0, 0}, @@ -1044,7 +1044,7 @@ int Ro_Send_CCR(struct sip_msg *msg, struct dlg_cell *dlg, int dir, int reservat //create a session object without auth and diameter session id - we will add this later. new_session = build_new_ro_session(dir, 0, 0, &session_id, &dlg->callid, &asserted_identity, &called_asserted_identity, &mac, dlg->h_entry, dlg->h_id, - reservation_units, 0, active_rating_group, active_service_identifier, incoming_trunk_id, outgoing_trunk_id); + reservation_units, 0, active_rating_group, active_service_identifier, incoming_trunk_id, outgoing_trunk_id, pani); if (!new_session) { LM_ERR("Couldn't create new Ro Session - this is BAD!\n"); @@ -1056,7 +1056,7 @@ int Ro_Send_CCR(struct sip_msg *msg, struct dlg_cell *dlg, int dir, int reservat ssd->tlabel = tlabel; ssd->ro_session = new_session; - if (!sip_create_ro_ccr_data(msg, dir, &ro_ccr_data, &cc_acc_session, asserted_identity, called_asserted_identity, subscription_id, subscription_id_type, incoming_trunk_id, outgoing_trunk_id)) + if (!sip_create_ro_ccr_data(msg, dir, &ro_ccr_data, &cc_acc_session, asserted_identity, called_asserted_identity, subscription_id, subscription_id_type, incoming_trunk_id, outgoing_trunk_id, pani)) goto error; if (!ro_ccr_data) @@ -1096,7 +1096,7 @@ int Ro_Send_CCR(struct sip_msg *msg, struct dlg_cell *dlg, int dir, int reservat LM_ERR("Problem adding Multiple Service Credit Control data\n"); goto error; } - + /* before we send, update our session object with CC App session ID and data */ new_session->auth_appid = cc_acc_session->application_id; new_session->auth_session_type = cc_acc_session->type; diff --git a/modules/ims_charging/ims_ro.h b/modules/ims_charging/ims_ro.h index b6087b8cac9..b18d0f8f93b 100644 --- a/modules/ims_charging/ims_ro.h +++ b/modules/ims_charging/ims_ro.h @@ -15,7 +15,7 @@ struct interim_ccr { void credit_control_session_callback(int event, void* session); void remove_aaa_session(str *session_id); int Ro_Send_CCR(struct sip_msg *msg, struct dlg_cell *dlg, int dir, int reservation_units, - str *incoming_trunk_id, str *outgoing_trunk_id, cfg_action_t* action, unsigned int tindex, unsigned int tlabel); + str *incoming_trunk_id, str *outgoing_trunk_id, str *enb_cell_id, cfg_action_t* action, unsigned int tindex, unsigned int tlabel); void send_ccr_interim(struct ro_session* ro_session, unsigned int used, unsigned int reserve); void send_ccr_stop(struct ro_session *ro_session); int get_direction_as_int(str* direction); diff --git a/modules/ims_charging/mod.c b/modules/ims_charging/mod.c index b406348c420..2b45f72e359 100644 --- a/modules/ims_charging/mod.c +++ b/modules/ims_charging/mod.c @@ -325,6 +325,7 @@ static int w_ro_ccr(struct sip_msg *msg, char* c_route_name, char* c_direction, int ret = RO_RETURN_TRUE; int dir = 0; str identity = {0, 0}, + pani = {0,0}, contact = {0, 0}; struct hdr_field *h=0; @@ -393,6 +394,7 @@ static int w_ro_ccr(struct sip_msg *msg, char* c_route_name, char* c_direction, goto send_ccr; } + pani = cscf_get_access_network_info(msg, &h); } else if (dir == RO_TERM_DIRECTION){ //get callee IMPU from called part id - if not present then skip this if ((identity = cscf_get_public_identity_from_called_party_id(msg, &h)).len == 0) { @@ -503,7 +505,7 @@ static int w_ro_ccr(struct sip_msg *msg, char* c_route_name, char* c_direction, goto done; } - ret = Ro_Send_CCR(msg, dlg, dir, reservation_units, &s_incoming_trunk_id, &s_outgoing_trunk_id, cfg_action, tindex, tlabel); + ret = Ro_Send_CCR(msg, dlg, dir, reservation_units, &s_incoming_trunk_id, &s_outgoing_trunk_id, &pani, cfg_action, tindex, tlabel); if(ret < 0){ LM_ERR("Failed to send CCR\n"); diff --git a/modules/ims_charging/ro_session_hash.c b/modules/ims_charging/ro_session_hash.c index 543009bbcdc..f2e6ab6c4c7 100644 --- a/modules/ims_charging/ro_session_hash.c +++ b/modules/ims_charging/ro_session_hash.c @@ -177,7 +177,7 @@ void destroy_dlg_table(void) { struct ro_session* build_new_ro_session(int direction, int auth_appid, int auth_session_type, str *session_id, str *callid, str *asserted_identity, str* called_asserted_identity, str* mac, unsigned int dlg_h_entry, unsigned int dlg_h_id, unsigned int requested_secs, unsigned int validity_timeout, - int active_rating_group, int active_service_identifier, str *incoming_trunk_id, str *outgoing_trunk_id){ + int active_rating_group, int active_service_identifier, str *incoming_trunk_id, str *outgoing_trunk_id, str *pani){ LM_DBG("Building Ro Session **********"); char *p; unsigned int len = session_id->len + callid->len + asserted_identity->len + called_asserted_identity->len + mac->len + incoming_trunk_id->len + outgoing_trunk_id->len + sizeof (struct ro_session); @@ -192,6 +192,11 @@ struct ro_session* build_new_ro_session(int direction, int auth_appid, int auth_ LM_DBG("New Ro Session given memory at address [%p]\n", new_ro_session); memset(new_ro_session, 0, len); + + if (pani->len < MAX_PANI_LEN) { + p = new_ro_session->pani; + memcpy(p, pani->s, pani->len); + } new_ro_session->direction = direction; new_ro_session->auth_appid = auth_appid; diff --git a/modules/ims_charging/ro_session_hash.h b/modules/ims_charging/ro_session_hash.h index 3ba0e5ec015..83aa7a32747 100644 --- a/modules/ims_charging/ro_session_hash.h +++ b/modules/ims_charging/ro_session_hash.h @@ -20,6 +20,8 @@ #define RO_SESSION_FLAG_CHANGED (1<<2) /*!< ro session has been updated */ #define RO_SESSION_FLAG_DELETED (1<<3) /*!< ro session has been deleted */ +#define MAX_PANI_LEN 100 + enum ro_session_event_type { pending, answered, @@ -50,6 +52,7 @@ struct ro_session { str called_asserted_identity; str incoming_trunk_id; str outgoing_trunk_id; + char pani[MAX_PANI_LEN]; unsigned int hop_by_hop; struct ro_tl ro_tl; unsigned int reserved_secs; @@ -191,7 +194,7 @@ void remove_aaa_session(str *session_id); struct ro_session* build_new_ro_session(int direction, int auth_appid, int auth_session_type, str *session_id, str *callid, str *asserted_identity, str* called_asserted_identity, str* mac, unsigned int dlg_h_entry, unsigned int dlg_h_id, unsigned int requested_secs, unsigned int validity_timeout, - int active_rating_group, int active_service_identifier, str *incoming_trunk_id, str *outgoing_trunk_id); + int active_rating_group, int active_service_identifier, str *incoming_trunk_id, str *outgoing_trunk_id, str *pani); /*! * \brief Refefence a ro_session with locking