瀏覽代碼

modules: ims_registrar_scscf: Added support to receive RTR on Cx/Dx interface

Richard Good 10 年之前
父節點
當前提交
3b8aa15602

+ 83 - 0
modules/ims_registrar_scscf/cxdx_callbacks.c

@@ -23,6 +23,12 @@
 #include "cxdx_callbacks.h"
 #include "../../str.h"
 #include "../../dprint.h"
+#include "../ims_usrloc_scscf/usrloc.h"
+#include "cxdx_avp.h"
+
+
+extern struct cdp_binds cdpb;
+extern usrloc_api_t ul;
 
 /*int PPR_RTR_Event(void *parsed_message, int type, void *param) {
 	if (type & CXDX_PPR_RECEIVED) {
@@ -35,3 +41,80 @@
 	}
 	return 0;
 }*/
+
+AAAMessage* cxdx_process_rtr(AAAMessage *rtr) {
+    LM_DBG("Processing RTR");
+    
+    AAAMessage *rta_msg;
+    AAA_AVP* avp;
+    str public_id;
+    impurecord_t* r;
+    int i = 0;
+    int res = 0;
+    udomain_t* udomain;
+    
+    rta_msg = cdpb.AAACreateResponse(rtr);//session ID?
+    if (!rta_msg) return 0;
+
+    avp = cxdx_get_next_public_identity(rtr,0,AVP_IMS_Public_Identity,IMS_vendor_id_3GPP,__FUNCTION__);	
+    if(avp==0){
+	    LM_WARN("RTR received with only IMPI (username AVP) - currently S-CSCF does not support this kind of RTR\n");
+	    return 0;
+	    //TODO add support for receiving RTR with IMPI
+	    //get all impus related to this impu
+	    //get all contacts related to each impu
+	    //set the contact expire for each contact to now
+    }else{
+	    public_id=avp->data;
+	    LM_DBG("RTR received with IMPU [%.*s] in public identity AVP - this is supported\n", public_id.len, public_id.s);
+
+	    //TODO this should be a configurable module param
+	    ul.register_udomain("location", &udomain);
+	    
+	    ul.lock_udomain(udomain, &public_id);
+            res = ul.get_impurecord(udomain, &public_id, &r);
+            if (res != 0) {
+                LM_WARN("Strange, '%.*s' Not found in usrloc\n", public_id.len, public_id.s);
+                ul.unlock_udomain(udomain, &public_id);
+                //no point in continuing
+                return 0;
+            }
+	    
+	    for(i = 0; i < r->num_contacts; i++) {
+		LM_DBG("Expiring contact with AOR [%.*s]\n", r->newcontacts[i]->aor.len, r->newcontacts[i]->aor.s);
+		ul.expire_ucontact(r, r->newcontacts[i]);
+	    }
+	    
+	    ul.unlock_udomain(udomain, &public_id);
+	    
+	    while(cdpb.AAAGetNextAVP(avp) && (avp=cxdx_get_next_public_identity(rtr,cdpb.AAAGetNextAVP(avp),AVP_IMS_Public_Identity,IMS_vendor_id_3GPP,__FUNCTION__))!=0){
+		    public_id=avp->data;
+		    LM_DBG("RTR also has public id [%.*s]\n", public_id.len, public_id.s);
+		    ul.lock_udomain(udomain, &public_id);
+		    res = ul.get_impurecord(udomain, &public_id, &r);
+		    if (res != 0) {
+			LM_WARN("Strange, '%.*s' Not found in usrloc\n", public_id.len, public_id.s);
+			ul.unlock_udomain(udomain, &public_id);
+			//no point in continuing
+			return 0;
+		    }
+
+		    for(i = 0; i < r->num_contacts; i++) {
+			LM_DBG("Expiring contact with AOR [%.*s]\n", r->newcontacts[i]->aor.len, r->newcontacts[i]->aor.s);
+			ul.expire_ucontact(r, r->newcontacts[i]);
+		    }
+
+		    ul.unlock_udomain(udomain, &public_id);
+		}		
+    }
+    cxdx_add_vendor_specific_appid(rta_msg,IMS_vendor_id_3GPP,IMS_Cx,0 /*IMS_Cx*/);
+    
+    cxdx_add_auth_session_state(rta_msg,1);		
+
+    /* send an RTA back to the HSS */
+    cxdx_add_result_code(rta_msg,DIAMETER_SUCCESS);
+    
+    return rta_msg;
+    
+    
+}

+ 3 - 0
modules/ims_registrar_scscf/cxdx_callbacks.h

@@ -23,9 +23,12 @@
 #ifndef CXDX_CALLBACKS_H
 #define CXDX_CALLBACKS_H
 
+#include "../cdp/cdp_load.h"
 /**
  * Check, if a user-agent follows the indicated service-routes
  */
 int PPR_RTR_Event(void *parsed_message, int type, void *param);
 
+AAAMessage* cxdx_process_rtr(AAAMessage *request);
+
 #endif /* CXDX_CALLBACKS_H */

+ 2 - 0
modules/ims_registrar_scscf/cxdx_sar.c

@@ -64,6 +64,8 @@
 #include "../../parser/hf.h"
 #include "../../lib/ims/ims_getters.h"
 
+extern struct cdp_binds cdpb;
+
 int create_return_code(int result) {
     int rc;
     int_str avp_val, avp_name;

+ 50 - 0
modules/ims_registrar_scscf/reg_mod.c

@@ -70,11 +70,14 @@
 #include "usrloc_cb.h"
 #include "userdata_parser.h"
 #include "cxdx_sar.h"
+#include "cxdx_callbacks.h"
 #include "registrar_notify.h"
 #include "../cdp_avp/mod_export.h"
 
 MODULE_VERSION
 
+extern gen_lock_t* process_lock; /* lock on the process table */
+
 int * callback_singleton; /**< Cx callback singleton 								*/
 
 
@@ -123,6 +126,8 @@ static int fetchc_fixup(void** param, int param_no);
 /*! \brief Functions */
 static int add_sock_hdr(struct sip_msg* msg, char *str, char *foo);
 
+AAAMessage* callback_cdp_request(AAAMessage *request, void *param);
+
 int tcp_persistent_flag = -1; /*!< if the TCP connection should be kept open */
 int method_filtering = 0; /*!< if the looked up contacts should be filtered based on supported methods */
 int path_enabled = 0; /*!< if the Path HF should be handled */
@@ -301,6 +306,9 @@ static int mod_init(void) {
     str s;
     bind_usrloc_t bind_usrloc;
     qvalue_t dq;
+    
+    callback_singleton = shm_malloc(sizeof (int));
+    *callback_singleton = 0;
 
     /*build the required strings */
     scscf_serviceroute_uri_str.s =
@@ -519,10 +527,52 @@ static int child_init(int rank) {
     /* Init the user data parser */
     if (!parser_init(scscf_user_data_dtd, scscf_user_data_xsd))
         return -1;
+    
+    
+    lock_get(process_lock);
+    if ((*callback_singleton) == 0) {
+        *callback_singleton = 1;
+        cdpb.AAAAddRequestHandler(callback_cdp_request, NULL);
+    }
+    lock_release(process_lock);
+
+    return 0;
+}
 
+
+/**
+ * Handler for incoming Diameter requests.
+ * @param request - the received request
+ * @param param - generic pointer
+ * @returns the answer to this request
+ */
+AAAMessage* callback_cdp_request(AAAMessage *request, void *param) {
+    if (is_req(request)) {
+
+        switch (request->applicationId) {
+            case IMS_Cx:
+            //case IMS_Dx:  IMS_Cx is same as IMS_Dx 16777216
+                switch (request->commandCode) {
+                    case IMS_RTR:
+                        LM_INFO("Cx/Dx request handler():- Received an IMS_RTR \n");
+                        return cxdx_process_rtr(request);
+                        break;
+                    default:
+                        LM_ERR("Cx/Dx request handler(): - Received unknown request for Cx/Dx command %d, flags %#1x endtoend %u hopbyhop %u\n", request->commandCode, request->flags, request->endtoendId, request->hopbyhopId);
+                        return 0;
+                        break;
+                }
+                break;
+            default:
+                LM_ERR("Cx/Dx request handler(): - Received unknown request for app %d command %d\n", request->applicationId, request->commandCode);
+                return 0;
+                break;
+        }
+    }
     return 0;
 }
 
+
 /*! \brief
  * Wrapper to save(location)
  */