Browse Source

ims_charging: Merge branch 'ims_charging' into master

Carsten Bock 12 years ago
parent
commit
cc8bc36c67
3 changed files with 41 additions and 20 deletions
  1. 26 13
      modules/ims_charging/dialog.c
  2. 2 2
      modules/ims_charging/ims_ro.c
  3. 13 5
      modules/ims_charging/ro_timer.c

+ 26 - 13
modules/ims_charging/dialog.c

@@ -42,12 +42,17 @@ void dlg_reply(struct dlg_cell *dlg, int type, struct dlg_cb_params *_params) {
 		ro_session_entry = &(ro_session_table->entries[session->h_entry]);
 		ro_session_lock(ro_session_table, ro_session_entry);
 
+		if (session->active) {
+			LM_CRIT("Why the heck am i receiving a double confirmation of the dialog? Ignoring... ");
+			ro_session_unlock(ro_session_table, ro_session_entry);
+			return;
+		}
+	
 		time_since_last_event = now - session->last_event_timestamp;
 		session->start_time = session->last_event_timestamp = now;
 		session->event_type = answered;
 		session->active = 1;
 		
-		ro_session_unlock(ro_session_table, ro_session_entry);
 
 		/* check to make sure that the validity of the credit is enough for the bundle */
 		int ret = 0;
@@ -64,12 +69,16 @@ void dlg_reply(struct dlg_cell *dlg, int type, struct dlg_cb_params *_params) {
 				ret = insert_ro_timer(&session->ro_tl, session->valid_for);
 			}
 		}
+
+
 		if (ret != 0) {
 			LM_CRIT("unable to insert timer for Ro Session [%.*s]\n", session->ro_session_id.len, session->ro_session_id.s); 
 		} else {
-			ref_ro_session(session, 1);
+			ref_ro_session_unsafe(session, 1); // lock already acquired
 		}
 				
+		ro_session_unlock(ro_session_table, ro_session_entry);
+
 		AAASession* cdp_session = cdpb.AAAGetCCAccSession(session->ro_session_id);
 		if (!cdp_session) {
 			LM_ERR("could not find find CC App CDP session for session [%.*s]\n", session->ro_session_id.len, session->ro_session_id.s);
@@ -121,25 +130,29 @@ void dlg_terminated(struct dlg_cell *dlg, int type, struct dlg_cb_params *_param
 					LM_ERR("Ro Session is not active, but may have been answered [%d]\n", (int)ro_session->start_time);
 					continue;
 				}
-				
+			
+	
 				ro_session_lock(ro_session_table, ro_session_entry);
-				int ret = remove_ro_timer(&ro_session->ro_tl);
-				if (ret < 0) {
-					LM_CRIT("unable to unlink the timer on ro_session %p [%.*s]\n", 
-						ro_session, ro_session->cdp_session_id.len, ro_session->cdp_session_id.s);
-				} else if (ret > 0) {
-					LM_WARN("inconsistent ro timer data on ro_session %p [%.*s]\n",
-						ro_session, ro_session->cdp_session_id.len, ro_session->cdp_session_id.s);						
-				} else {
-					unref++;
+
+				if (ro_session->active) { // if the call was never activated, there's no timer to remove
+					int ret = remove_ro_timer(&ro_session->ro_tl);
+					if (ret < 0) {
+						LM_CRIT("unable to unlink the timer on ro_session %p [%.*s]\n", 
+							ro_session, ro_session->cdp_session_id.len, ro_session->cdp_session_id.s);
+					} else if (ret > 0) {
+						LM_WARN("inconsistent ro timer data on ro_session %p [%.*s]\n",
+							ro_session, ro_session->cdp_session_id.len, ro_session->cdp_session_id.s);						
+					} else {
+						unref++;
+					}
 				}
 
 				LM_DBG("Sending CCR STOP on Ro_Session [%p]\n", ro_session);
 				send_ccr_stop(ro_session);
 				ro_session->active = 0;
 				//ro_session->start_time;
+				unref_ro_session_unsafe(ro_session, 2+unref, ro_session_entry); //lock already acquired
 				ro_session_unlock(ro_session_table, ro_session_entry);
-				unref_ro_session(ro_session, 2+unref);
 			}
 		}
 	}

+ 2 - 2
modules/ims_charging/ims_ro.c

@@ -991,12 +991,12 @@ int Ro_Send_CCR(struct sip_msg *msg, str* direction, str* charge_type, str* unit
     Ro_free_CCR(ro_ccr_data);
 
     //TODO: if the following fail, we should clean up the Ro session.......
-    if (dlgb.register_dlgcb(dlg, DLGCB_RESPONSE_FWDED, dlg_reply, (void*)new_session ,NULL ) != 0) {
+    if (dlgb.register_dlgcb(dlg, /* DLGCB_RESPONSE_FWDED */ DLGCB_CONFIRMED, dlg_reply, (void*)new_session ,NULL ) != 0) {
     	LM_CRIT("cannot register callback for dialog confirmation\n");
     	goto error;
     }
 
-    if (dlgb.register_dlgcb(dlg, DLGCB_TERMINATED | DLGCB_FAILED | DLGCB_EXPIRED | DLGCB_DESTROY
+    if (dlgb.register_dlgcb(dlg, DLGCB_TERMINATED | DLGCB_FAILED | DLGCB_EXPIRED /*| DLGCB_DESTROY */
     		, dlg_terminated, (void*)new_session, NULL ) != 0) {
     	LM_CRIT("cannot register callback for dialog termination\n");
     	goto error;

+ 13 - 5
modules/ims_charging/ro_timer.c

@@ -118,6 +118,8 @@ int insert_ro_timer(struct ro_tl *tl, int interval) {
     tl->timeout = get_ticks() + interval;
     insert_ro_timer_unsafe(tl);
 
+
+    LM_DBG("TIMER inserted");
     lock_release(roi_timer->lock);
 
     return 0;
@@ -141,7 +143,7 @@ static inline void remove_ro_timer_unsafe(struct ro_tl *tl) {
  */
 int remove_ro_timer(struct ro_tl *tl) {
     lock_get(roi_timer->lock);
-
+	
     if (tl->prev == NULL && tl->timeout == 0) {
         lock_release(roi_timer->lock);
         return 1;
@@ -153,7 +155,7 @@ int remove_ro_timer(struct ro_tl *tl) {
         lock_release(roi_timer->lock);
         return -1;
     }
-
+    LM_DBG("TIMER REMOVED");
     remove_ro_timer_unsafe(tl);
     tl->next = NULL;
     tl->prev = NULL;
@@ -337,8 +339,8 @@ void resume_ro_session_ontimeout(struct interim_ccr *i_req) {
 
 	ro_session_entry = &(ro_session_table->entries[i_req->ro_session->h_entry]);
 
+	unref_ro_session_unsafe(i_req->ro_session, 1, ro_session_entry);//unref from the initial timer that fired this event.
 	ro_session_unlock(ro_session_table, ro_session_entry);
-	unref_ro_session(i_req->ro_session, 1);//unref from the initial timer that fired this event.
 
 	shm_free(i_req);
 	LM_DBG("Exiting async ccr interim nicely");
@@ -370,7 +372,13 @@ void ro_session_ontimeout(struct ro_tl *tl) {
 //	LM_ALERT("LOCKED!");
 	
 	LM_DBG("event-type=%d", ro_session->event_type);
-
+	
+//	if (!ro_session->active) {
+//		LM_ALERT("Looks like this session was terminated while requesting more units");
+//		goto exit;
+//		return;
+//	}
+	
 	switch (ro_session->event_type) {
 	case answered:
 		now = time(0);
@@ -437,8 +445,8 @@ void ro_session_ontimeout(struct ro_tl *tl) {
 
 	update_stat(killed_calls, 1);
 
+	unref_ro_session_unsafe(ro_session, 1, ro_session_entry); //unref from the initial timer that fired this event.
 	ro_session_unlock(ro_session_table, ro_session_entry);
-	unref_ro_session(ro_session, 1); //unref from the initial timer that fired this event.
 
 	return;
 }