Module: sip-router
Branch: tmp/ims_charging
Commit: 639ce584258f2c2ad4331bbd9ae2599a86edc80b
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=639ce58…
Author: Carlos Ruiz Diaz <carlos.ruizdiaz(a)gmail.com>
Committer: Carlos Ruiz Diaz <carlos.ruizdiaz(a)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