Module: sip-router
Branch: master
Commit: 59b9208700e578df5000f8ad732c2e444712b0fa
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=59b9208…
Author: Torrey Searle <tsearle(a)gmail.com>
Committer: Torrey Searle <tsearle(a)gmail.com>
Date: Fri Apr 5 18:38:36 2013 +0200
modules/sipt: added some additional getter methods
new functions: sipt_get_cpc() sipt_get_calling_party_nai() sipt_get_called_party_nai()
---
modules/sipt/doc/sipt_admin.xml | 63 ++++++++++++++++++++++++++++++
modules/sipt/sipt.c | 81 +++++++++++++++++++++++++++++++++++++++
modules/sipt/ss7.h | 15 +++++++
modules/sipt/ss7_parser.c | 78 ++++++++++++++++++++++++++-----------
4 files changed, 214 insertions(+), 23 deletions(-)
diff --git a/modules/sipt/doc/sipt_admin.xml b/modules/sipt/doc/sipt_admin.xml
index d8e9fdd..04b9a59 100644
--- a/modules/sipt/doc/sipt_admin.xml
+++ b/modules/sipt/doc/sipt_admin.xml
@@ -78,6 +78,69 @@ if($avp(s:hop) > 0)
</programlisting>
</example>
</section>
+ <section>
+ <title><function
moreinfo="none">sipt_get_cpc()</function></title>
+ <para>
+ Returns the value of the Calling Party Category for the IAM message.
+ Returns -1 if there is a parsing error.
+ </para>
+ <example>
+ <title><function moreinfo="none">sipt_get_cpc()</function>
usage</title>
+ <programlisting format="linespecific">
+...
+# get the Cpc code and set put it in a custom sip header
+$avp(s:cpc) = sipt_get_cpc();
+append_hf("X-CPC: $avp(s:cpc)\r\n");
+
+...
+</programlisting>
+ </example>
+ </section>
+ <section>
+ <title><function
moreinfo="none">sipt_get_calling_party_nai()</function></title>
+ <para>
+ Returns the value of the Nature of Address Indicator
+ of the Calling Party for the IAM message.
+ Returns -1 if there is a parsing error or if
+ the Calling Party Number is not present.
+ </para>
+ <example>
+ <title><function
moreinfo="none">sipt_get_calling_party_nai()</function>
usage</title>
+ <programlisting format="linespecific">
+...
+# get the Calling Nai and add country code if national
+$avp(s:from_nai) = sipt_get_calling_party_nai();
+if($avp(s:from_nai) == 3)
+{
+ $fU = "32" + "$fU";
+}
+
+...
+</programlisting>
+ </example>
+ </section>
+ <section>
+ <title><function
moreinfo="none">sipt_get_called_party_nai()</function></title>
+ <para>
+ Returns the value of the Nature of Address Indicator
+ of the Called Party for the IAM message.
+ Returns -1 if there is a parsing error.
+ </para>
+ <example>
+ <title><function
moreinfo="none">sipt_get_called_party_nai()</function>
usage</title>
+ <programlisting format="linespecific">
+...
+# get the Called Nai and add country code if national
+$avp(s:to_nai) = sipt_get_called_party_nai();
+if($avp(s:from_nai) == 3)
+{
+ $rU = "32" + "$rU";
+}
+
+...
+</programlisting>
+ </example>
+ </section>
</section>
</chapter>
diff --git a/modules/sipt/sipt.c b/modules/sipt/sipt.c
index 7e9e266..8b64b43 100644
--- a/modules/sipt/sipt.c
+++ b/modules/sipt/sipt.c
@@ -41,6 +41,9 @@ MODULE_VERSION
static int sipt_destination(struct sip_msg *msg, char *_destination, char *_hops, char *
_nai);
static int sipt_get_hop_counter(struct sip_msg *msg, char *x, char *y);
+static int sipt_get_cpc(struct sip_msg *msg, char *x, char *y);
+static int sipt_get_calling_party_nai(struct sip_msg *msg, char *x, char *y);
+static int sipt_get_called_party_nai(struct sip_msg *msg, char *x, char *y);
static int mod_init(void);
static void mod_destroy(void);
@@ -79,6 +82,24 @@ static cmd_export_t cmds[]={
0, 0, /* */
/* can be applied to original requests */
REQUEST_ROUTE|BRANCH_ROUTE},
+ {"sipt_get_cpc", /* action name as in scripts */
+ (cmd_function)sipt_get_cpc, /* C function name */
+ 0, /* number of parameters */
+ 0, 0, /* */
+ /* can be applied to original requests */
+ REQUEST_ROUTE|BRANCH_ROUTE},
+ {"sipt_get_calling_party_nai", /* action name as in scripts */
+ (cmd_function)sipt_get_calling_party_nai, /* C function name */
+ 0, /* number of parameters */
+ 0, 0, /* */
+ /* can be applied to original requests */
+ REQUEST_ROUTE|BRANCH_ROUTE},
+ {"sipt_get_called_party_nai", /* action name as in scripts */
+ (cmd_function)sipt_get_called_party_nai, /* C function name */
+ 0, /* number of parameters */
+ 0, 0, /* */
+ /* can be applied to original requests */
+ REQUEST_ROUTE|BRANCH_ROUTE},
{0, 0, 0, 0, 0, 0}
};
@@ -278,6 +299,66 @@ static int sipt_get_hop_counter(struct sip_msg *msg, char *x, char
*y)
return isup_get_hop_counter((unsigned char*)body.s, body.len);
}
+static int sipt_get_cpc(struct sip_msg *msg, char *x, char *y)
+{
+ str body;
+ body.s = get_body_part(msg, TYPE_APPLICATION,SUBTYPE_UNKNOWN,&body.len);
+
+ if(body.s == NULL)
+ {
+ LM_ERR("No ISUP Message Found");
+ return -1;
+ }
+
+ if(body.s[0] != ISUP_IAM)
+ {
+ LM_DBG("message not an IAM\n");
+ return -1;
+ }
+
+ return isup_get_cpc((unsigned char*)body.s, body.len);
+}
+
+static int sipt_get_calling_party_nai(struct sip_msg *msg, char *x, char *y)
+{
+ str body;
+ body.s = get_body_part(msg, TYPE_APPLICATION,SUBTYPE_UNKNOWN,&body.len);
+
+ if(body.s == NULL)
+ {
+ LM_ERR("No ISUP Message Found");
+ return -1;
+ }
+
+ if(body.s[0] != ISUP_IAM)
+ {
+ LM_DBG("message not an IAM\n");
+ return -1;
+ }
+
+ return isup_get_calling_party_nai((unsigned char*)body.s, body.len);
+}
+
+static int sipt_get_called_party_nai(struct sip_msg *msg, char *x, char *y)
+{
+ str body;
+ body.s = get_body_part(msg, TYPE_APPLICATION,SUBTYPE_UNKNOWN,&body.len);
+
+ if(body.s == NULL)
+ {
+ LM_ERR("No ISUP Message Found");
+ return -1;
+ }
+
+ if(body.s[0] != ISUP_IAM)
+ {
+ LM_DBG("message not an IAM\n");
+ return -1;
+ }
+
+ return isup_get_called_party_nai((unsigned char*)body.s, body.len);
+}
+
static int sipt_destination(struct sip_msg *msg, char *_destination, char *_hops, char *
_nai)
{
str * str_hops = (str*)_hops;
diff --git a/modules/sipt/ss7.h b/modules/sipt/ss7.h
index 2599b80..4fe2bfb 100644
--- a/modules/sipt/ss7.h
+++ b/modules/sipt/ss7.h
@@ -148,7 +148,22 @@ struct isup_parm_opt {
unsigned char data[0];
};
+
+struct isup_iam_fixed {
+ unsigned char type;
+ unsigned char nature_of_connection;
+ unsigned char forward_call_indicators[2];
+ unsigned char calling_party_category;
+ unsigned char transmission_medium_req;
+ unsigned char fixed_pointer;
+ unsigned char optional_pointer;
+ unsigned char called_party_number[0];
+};
+
int isup_get_hop_counter(unsigned char *buf, int len);
+int isup_get_cpc(unsigned char *buf, int len);
+int isup_get_calling_party_nai(unsigned char *buf, int len);
+int isup_get_called_party_nai(unsigned char *buf, int len);
int isup_update_destination(char * dest, int hops, int nai, unsigned char *buf, int len,
unsigned char * obuf, int olen);
#endif
diff --git a/modules/sipt/ss7_parser.c b/modules/sipt/ss7_parser.c
index a960212..b4dce39 100644
--- a/modules/sipt/ss7_parser.c
+++ b/modules/sipt/ss7_parser.c
@@ -26,6 +26,7 @@
#include "ss7.h"
#include <string.h>
+#include <stddef.h>
static char char2digit(char localchar)
{
@@ -117,46 +118,30 @@ static int encode_called_party(char * number, unsigned char * flags,
int nai, un
// returns start of specified optional header of IAM, otherwise return -1
static int get_optional_header(unsigned char header, unsigned char *buf, int len)
{
+ struct isup_iam_fixed * message = (struct isup_iam_fixed*)buf;
int offset = 0;
int res;
- char optparams;
// not an iam? do nothing
- if(buf[0] != ISUP_IAM)
+ if(message->type != ISUP_IAM)
{
return -1;
}
- /* Copy the fixed parms */
- len -= 6;
- offset += 6;
+ len -= offsetof(struct isup_iam_fixed, optional_pointer);
+ offset += offsetof(struct isup_iam_fixed, optional_pointer);
if (len < 1)
return -1;
- /* IAM has one Fixed variable param, Called party number */
-
- // pointer to fixed part (2)
- offset++;
- len--;
-
-
- //pointer to optional part
- optparams = buf[offset];
- offset++;
- len--;
-
-
- // add the new mandatory fixed header
- res = buf[offset];
- offset += res+1;
- len -= res+1;
+ offset += message->optional_pointer;
+ len -= message->optional_pointer;
if (len < 1 )
return -1;
/* Optional paramter parsing code */
- if (optparams) {
+ if (message->optional_pointer) {
while ((len > 0) && (buf[offset] != 0)) {
struct isup_parm_opt *optparm = (struct isup_parm_opt *)(buf + offset);
@@ -184,7 +169,54 @@ int isup_get_hop_counter(unsigned char *buf, int len)
return -1;
}
+int isup_get_cpc(unsigned char *buf, int len)
+{
+ struct isup_iam_fixed * message = (struct isup_iam_fixed*)buf;
+
+ // not an iam? do nothing
+ if(message->type != ISUP_IAM)
+ {
+ return -1;
+ }
+ /* Message Type = 1 */
+ len -= offsetof(struct isup_iam_fixed, calling_party_category);
+
+ if (len < 1)
+ return -1;
+
+ return (int)message->calling_party_category;
+}
+
+
+int isup_get_calling_party_nai(unsigned char *buf, int len)
+{
+ int offset = get_optional_header(ISUP_PARM_CALLING_PARTY_NUM, buf, len);
+
+ if(offset != -1 && len-offset-2 > 0)
+ {
+ return buf[offset+2] & 0x7F;
+ }
+ return -1;
+}
+
+int isup_get_called_party_nai(unsigned char *buf, int len)
+{
+ struct isup_iam_fixed * message = (struct isup_iam_fixed*)buf;
+
+ // not an iam? do nothing
+ if(message->type != ISUP_IAM)
+ {
+ return -1;
+ }
+
+ /* Message Type = 1 */
+ len -= offsetof(struct isup_iam_fixed, called_party_number);
+
+ if (len < 1)
+ return -1;
+ return message->called_party_number[1]&0x7F;
+}
int isup_update_destination(char * dest, int hops, int nai, unsigned char *buf, int len,
unsigned char * obuf, int olen)
{