[sr-dev] git:tmp/ims_charging: ims_charging: read diameter AVP MAC value dynamically from $avp

Carlos Ruiz Diaz carlos.ruizdiaz at gmail.com
Thu Oct 3 18:02:50 CEST 2013


Module: sip-router
Branch: tmp/ims_charging
Commit: 639ce584258f2c2ad4331bbd9ae2599a86edc80b
URL:    http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=639ce584258f2c2ad4331bbd9ae2599a86edc80b

Author: Carlos Ruiz Diaz <carlos.ruizdiaz at gmail.com>
Committer: Carlos Ruiz Diaz <carlos.ruizdiaz at 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




More information about the sr-dev mailing list