Explorar o código

modules/ims_icscf: Added new module param use_preferred_scscf_uri
This allows ICSCF to have a preferred S-CSCF is HSS returns a list
Usually ICSCF uses SCSCFs in the order in which HSS provides them
This gives another level of priority control to SCSCF selection at the ICSCF

Richard Good %!s(int64=11) %!d(string=hai) anos
pai
achega
15f27e65c9

+ 43 - 2
modules/ims_icscf/doc/ims_icscf_admin.xml

@@ -140,7 +140,7 @@ modparam("ims_icscf", "cxdx_forced_peer", "hss.ims.smilecoms.com")
       <para><emphasis> Default value is "ims.smilecoms.com".</emphasis></para>
 
       <example>
-        <title><varname>version_table</varname> parameter usage</title>
+        <title><varname>cxdx_dest_realm</varname> parameter usage</title>
 
         <programlisting format="linespecific">
 ...
@@ -149,6 +149,47 @@ modparam("ims_icscf", "cxdx_dest_realm", "ims.smilecoms.com")
     </programlisting>
       </example>
     </section>
+    
+    <section>
+      <title><varname>use_preferred_scscf_uri</varname> (int)</title>
+
+      <para>Whether or not this ICSCF has a preferred S-CSCF to use when the
+      HSS returns a list of SCSCFs.  0 means this I-CSCF has no preferred
+      SCSCF.  1 means it has a preferred S-CSCF.</para>
+
+      <para><emphasis> Default value is 0.</emphasis></para>
+
+      <example>
+        <title><varname>use_preferred_scscf_uri</varname> parameter usage</title>
+
+        <programlisting format="linespecific">
+...
+modparam("ims_icscf", "use_preferred_scscf_uri", 1)
+...
+    </programlisting>
+      </example>
+    </section>
+    
+    <section>
+      <title><varname>preferred_scscf_uri</varname> (string)</title>
+
+      <para>If use_preferred_scscf_uri is set then this is the URI of the preferred
+	  SCSCF.</para>
+
+      <para><emphasis> Default value is "".</emphasis></para>
+
+      <example>
+        <title><varname>preferred_scscf_uri</varname> parameter usage</title>
+
+        <programlisting format="linespecific">
+...
+modparam("ims_icscf", "preferred_scscf_uri", "sip:scscf.ims.smilecoms.com:6060")
+...
+    </programlisting>
+      </example>
+    </section>
+    
+    
   </section>
 
   <section>
@@ -299,7 +340,7 @@ route[REG_UAR_REPLY]
       retrieve return value</para>
 
       <example>
-        <title>I_perform_location_information_request()</title>
+        <title>I_perform_location_information_request</title>
 
         <programlisting format="linespecific">
 ...

+ 5 - 0
modules/ims_icscf/mod.c

@@ -76,6 +76,9 @@ int scscf_entry_expiry = 300;
 char* cxdx_dest_realm_s = "ims.smilecoms.com";
 str cxdx_dest_realm;
 
+str preferred_scscf_uri = str_init("sip:scscf.ims.smilecoms.com:4060");
+int use_preferred_scscf_uri = 0;
+
 //Only used if we want to force the Rx peer
 //Usually this is configured at a stack level and the first request uses realm routing
 char* cxdx_forced_peer_s = "";
@@ -123,6 +126,8 @@ static param_export_t params[] = {
     {"db_capabilities_table", 	PARAM_STRING, &ims_icscf_db_capabilities_table},
     {"cxdx_forced_peer", PARAM_STR, &cxdx_forced_peer},
     {"cxdx_dest_realm", PARAM_STR, &cxdx_dest_realm},
+    {"preferred_scscf_uri",	PARAM_STR, &preferred_scscf_uri},
+    {"use_preferred_scscf_uri", INT_PARAM, &use_preferred_scscf_uri},
     {0, 0, 0}
 };
 

+ 44 - 9
modules/ims_icscf/scscf_list.c

@@ -56,6 +56,9 @@ extern int scscf_entry_expiry; //time for scscf entries to remain the scscf_list
 
 extern struct tm_binds tmb; //Structure with pointers to tm funcs
 
+extern int use_preferred_scscf_uri;
+extern str preferred_scscf_uri;
+
 int i_hash_size;
 i_hash_slot *i_hash_table = 0;
 
@@ -427,19 +430,51 @@ out_of_memory:
 str take_scscf_entry(str call_id) {
     str scscf = {0, 0};
     scscf_list *l = 0;
+    scscf_entry *scscf_entry = 0;
     unsigned int hash = get_call_id_hash(call_id, i_hash_size);
 
+    LM_DBG("Getting scscf entry from list\n");
+    
     i_lock(hash);
     l = i_hash_table[hash].head;
-    while (l) {
-        if (l->call_id.len == call_id.len &&
-                strncasecmp(l->call_id.s, call_id.s, call_id.len) == 0) {
-            if (l->list) {
-                scscf = l->list->scscf_name;
-            }
-            break;
-        }
-        l = l->next;
+    
+    //if use_preferred_scscf_uri then check the table for the preferred scscf set
+    if(use_preferred_scscf_uri) {
+	LM_DBG("use_preferred_scscf_uri is set so will check for preferred_scscf_uri first [%.*s]\n", preferred_scscf_uri.len, preferred_scscf_uri.s);
+	while (l) {
+	    if (l->call_id.len == call_id.len &&
+		    strncasecmp(l->call_id.s, call_id.s, call_id.len) == 0) {
+		scscf_entry = l->list;
+		while (scscf_entry) {
+		    LM_DBG("scscf_entry [%.*s]\n", scscf_entry->scscf_name.len, scscf_entry->scscf_name.s);
+		    if (strncasecmp(scscf_entry->scscf_name.s, preferred_scscf_uri.s, preferred_scscf_uri.len) == 0) {
+			LM_DBG("scscf_entry matches\n");
+			scscf = scscf_entry->scscf_name;
+			break;
+		    }
+		    scscf_entry = scscf_entry->next;
+		}
+		
+		break;
+	    }
+	    l = l->next;
+	}
+    }
+    
+    // if scscf has not yet been set then find the first scscf that matches
+    if(scscf.len <= 0 ) {
+	LM_DBG("scscf has not been set so we just look for first match\n");
+	while (l) {
+	    if (l->call_id.len == call_id.len &&
+		    strncasecmp(l->call_id.s, call_id.s, call_id.len) == 0) {
+		if (l->list) {
+		    LM_DBG("scscf_entry [%.*s]\n", l->list->scscf_name.len, l->list->scscf_name.s);
+		    scscf = l->list->scscf_name;
+		}
+		break;
+	    }
+	    l = l->next;
+	}
     }
     i_unlock(hash);
     return scscf;