Module: sip-router Branch: tmp/ims_charging Commit: 639ce584258f2c2ad4331bbd9ae2599a86edc80b URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=639ce584...
Author: Carlos Ruiz Diaz carlos.ruizdiaz@gmail.com Committer: Carlos Ruiz Diaz carlos.ruizdiaz@gmail.com Date: Thu Oct 3 11:56:13 2013 -0400
ims_charging: read diameter AVP MAC value dynamically from $avp
- $avp(ro_mac_value) can be either present or not. In case it is not, default value is used - $avp(cca_result_code) now supports interpolation
---
modules/ims_charging/ims_ro.c | 47 ++++++++++++++++++++----------- modules/ims_charging/mod.h | 3 ++ modules/ims_charging/ro_session_hash.c | 11 ++++++- modules/ims_charging/ro_session_hash.h | 8 +++++- 4 files changed, 49 insertions(+), 20 deletions(-)
diff --git a/modules/ims_charging/ims_ro.c b/modules/ims_charging/ims_ro.c index 1df9537..9cd2c08 100644 --- a/modules/ims_charging/ims_ro.c +++ b/modules/ims_charging/ims_ro.c @@ -53,6 +53,7 @@ static int create_cca_return_code(int result); static void resume_on_initial_ccr(int is_timeout, void *param, AAAMessage *cca, long elapsed_msecs); static void resume_on_interim_ccr(int is_timeout, void *param, AAAMessage *cca, long elapsed_msecs); static void resume_on_termination_ccr(int is_timeout, void *param, AAAMessage *cca, long elapsed_msecs); +static int get_mac_avp_value(struct sip_msg *msg, str *value);
void credit_control_session_callback(int event, void* session) { switch (event) { @@ -602,11 +603,8 @@ void send_ccr_interim(struct ro_session* ro_session, unsigned int used, unsigned if (!Ro_add_event_timestamp(ccr, time(NULL))) { LM_ERR("Problem adding Event-Timestamp data\n"); } - str mac; - mac.s = "00:00:00:00:00:00"; - mac.len = strlen(mac.s); //TODO - this is terrible
- if (!Ro_add_user_equipment_info(ccr, AVP_EPC_User_Equipment_Info_Type_MAC, mac)) { + if (!Ro_add_user_equipment_info(ccr, AVP_EPC_User_Equipment_Info_Type_MAC, ro_session->avp_value.mac)) { LM_ERR("Problem adding User-Equipment data\n"); }
@@ -787,12 +785,8 @@ void send_ccr_stop(struct ro_session *ro_session) { if (!Ro_add_event_timestamp(ccr, time(NULL))) { LM_ERR("Problem adding Event-Timestamp data\n"); } - - str mac; - mac.s = "00:00:00:00:00:00"; /*TODO: this is just a hack becuase we dont use this avp right now - if yuo like you can get the mac or some other info */ - mac.len = strlen(mac.s);
- if (!Ro_add_user_equipment_info(ccr, AVP_EPC_User_Equipment_Info_Type_MAC, mac)) { + if (!Ro_add_user_equipment_info(ccr, AVP_EPC_User_Equipment_Info_Type_MAC, ro_session->avp_value.mac)) { LM_ERR("Problem adding User-Equipment data\n"); }
@@ -910,9 +904,13 @@ int Ro_Send_CCR(struct sip_msg *msg, str* direction, str* charge_type, str* unit
dir = get_direction_as_int(direction);
+ str mac = {0,0}; + if (get_mac_avp_value(msg, &mac) != 0) + LM_DBG(RO_MAC_AVP_NAME" was not set. Using default."); + //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_id_uri, &msg->first_line.u.request.uri, dlg->h_entry, dlg->h_id, + &asserted_id_uri, &msg->first_line.u.request.uri, &mac, dlg->h_entry, dlg->h_id, reservation_units, 0);
if (!new_session) { @@ -952,10 +950,6 @@ int Ro_Send_CCR(struct sip_msg *msg, str* direction, str* charge_type, str* unit goto error; }
- str mac; //TODO - this is terrible - mac.s = "00:00:00:00:00:00"; - mac.len = strlen(mac.s); - if (!Ro_add_user_equipment_info(ccr, AVP_EPC_User_Equipment_Info_Type_MAC, mac)) { LM_ERR("Problem adding User-Equipment data\n"); goto error; @@ -1137,7 +1131,7 @@ static int create_cca_return_code(int result) {
avp_val.n = result;
- /*switch(result) { + switch(result) { case RO_RETURN_FALSE: avp_val.s.s = RO_RETURN_FALSE_STR; break; @@ -1148,12 +1142,14 @@ static int create_cca_return_code(int result) { if (result >= 0) break;
+ LM_ERR("Unknown result code: %d", result); avp_val.s.s = "??"; }
- avp_val.s.len = 2; */ + if (result < 0) + avp_val.s.len = 2;
- rc = add_avp(AVP_NAME_STR/*|AVP_VAL_STR*/, avp_name, avp_val); + rc = add_avp(AVP_NAME_STR|AVP_VAL_STR, avp_name, avp_val);
if (rc < 0) LM_ERR("Couldn't create ["RO_AVP_CCA_RETURN_CODE"] AVP\n"); @@ -1162,3 +1158,20 @@ static int create_cca_return_code(int result) {
return 1; } + +static int get_mac_avp_value(struct sip_msg *msg, str *value) { + str mac_avp_name_str = str_init(RO_MAC_AVP_NAME); + pv_spec_t avp_spec; + pv_value_t val; + + pv_parse_spec2(&mac_avp_name_str, &avp_spec, 1); + if (pv_get_spec_value(msg, &avp_spec, &val) != 0 || val.rs.len == 0) { + + value->s = "00:00:00:00:00:00"; + value->len = sizeof("00:00:00:00:00:00") - 1; + return -1; + } + + *value = val.rs; + return 0; +} diff --git a/modules/ims_charging/mod.h b/modules/ims_charging/mod.h index 50c8bc1..9c445f2 100644 --- a/modules/ims_charging/mod.h +++ b/modules/ims_charging/mod.h @@ -31,4 +31,7 @@
#define RO_AVP_CCA_RETURN_CODE "cca_return_code" #define RO_AVP_CCA_RETURN_CODE_LENGTH 15 + +#define RO_MAC_AVP_NAME "$avp(ro_mac_value)" + #endif /* MOD_H_ */ diff --git a/modules/ims_charging/ro_session_hash.c b/modules/ims_charging/ro_session_hash.c index 56ed5d9..c79d3b2 100644 --- a/modules/ims_charging/ro_session_hash.c +++ b/modules/ims_charging/ro_session_hash.c @@ -138,6 +138,8 @@ inline void destroy_ro_session(struct ro_session *ro_session) { if (ro_session->ro_session_id.s && (ro_session->ro_session_id.len > 0)) { shm_free(ro_session->ro_session_id.s); } + + shm_free(ro_session); }
@@ -172,10 +174,10 @@ void destroy_dlg_table(void) { return; }
-struct ro_session* build_new_ro_session(int direction, int auth_appid, int auth_session_type, str *session_id, str *callid, str *from_uri, str* to_uri, unsigned int dlg_h_entry, unsigned int dlg_h_id, unsigned int requested_secs, unsigned int validity_timeout){ +struct ro_session* build_new_ro_session(int direction, int auth_appid, int auth_session_type, str *session_id, str *callid, str *from_uri, str* to_uri, str* mac, unsigned int dlg_h_entry, unsigned int dlg_h_id, unsigned int requested_secs, unsigned int validity_timeout){ LM_DBG("Building Ro Session **********"); char *p; - unsigned int len = session_id->len + callid->len + from_uri->len + to_uri->len + sizeof (struct ro_session); + unsigned int len = session_id->len + callid->len + from_uri->len + to_uri->len + mac->len + sizeof (struct ro_session); struct ro_session *new_ro_session = (struct ro_session*) shm_malloc(len);
if (!new_ro_session) { @@ -228,6 +230,11 @@ struct ro_session* build_new_ro_session(int direction, int auth_appid, int auth_ memcpy(p, to_uri->s, to_uri->len); p += to_uri->len;
+ new_ro_session->avp_value.mac.s = p; + new_ro_session->avp_value.mac.len = mac->len; + memcpy(p, mac->s, mac->len); + + p += mac->len;
if (p != (((char*) new_ro_session) + len)) { LM_ERR("buffer overflow\n"); diff --git a/modules/ims_charging/ro_session_hash.h b/modules/ims_charging/ro_session_hash.h index f91f23a..d57ef28 100644 --- a/modules/ims_charging/ro_session_hash.h +++ b/modules/ims_charging/ro_session_hash.h @@ -19,6 +19,10 @@ enum ro_session_event_type { unknown_error };
+struct diameter_avp_value { + str mac; +}; + struct ro_session { str cdp_session_id; volatile int ref; @@ -43,6 +47,8 @@ struct ro_session { int auth_appid; int auth_session_type; int active; + + struct diameter_avp_value avp_value; };
/*! entries in the main ro_session table */ @@ -164,7 +170,7 @@ void link_ro_session(struct ro_session *ro_session, int n);
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 *from_uri, str* to_uri, unsigned int dlg_h_entry, unsigned int dlg_h_id, unsigned int requested_secs, unsigned int validity_timeout); +struct ro_session* build_new_ro_session(int direction, int auth_appid, int auth_session_type, str *session_id, str *callid, str *from_uri, str* to_uri, str* mac, unsigned int dlg_h_entry, unsigned int dlg_h_id, unsigned int requested_secs, unsigned int validity_timeout);
/*! * \brief Refefence a ro_session with locking