Module: sip-router
Branch: master
Commit: 15f27e65c9bd4ac50c91672d1b355d9e75f8972f
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=15f27e6…
Author: Richard Good <richard.good(a)smilecoms.com>
Committer: Richard Good <richard.good(a)smilecoms.com>
Date: Thu Oct 9 11:48:04 2014 +0200
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
---
modules/ims_icscf/doc/ims_icscf_admin.xml | 45 +++++++++++++++++++++++-
modules/ims_icscf/mod.c | 5 +++
modules/ims_icscf/scscf_list.c | 53 ++++++++++++++++++++++++-----
3 files changed, 92 insertions(+), 11 deletions(-)
diff --git a/modules/ims_icscf/doc/ims_icscf_admin.xml
b/modules/ims_icscf/doc/ims_icscf_admin.xml
index 4712bbb..dfd9a9c 100644
--- a/modules/ims_icscf/doc/ims_icscf_admin.xml
+++ b/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">
...
diff --git a/modules/ims_icscf/mod.c b/modules/ims_icscf/mod.c
index ce67903..04ccd19 100644
--- a/modules/ims_icscf/mod.c
+++ b/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}
};
diff --git a/modules/ims_icscf/scscf_list.c b/modules/ims_icscf/scscf_list.c
index f5655c5..1d21ba3 100644
--- a/modules/ims_icscf/scscf_list.c
+++ b/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;