Module: sip-router
Branch: master
Commit: 2639e3ddcb82434544012b537d2ca72264a5c9ee
URL:    
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=2639e3ddcb82434544012b537d2ca72264a5c9ee

Author: Torrey Searle <tsea...@gmail.com>
Committer: Torrey Searle <tsea...@gmail.com>
Date:   Mon Apr  7 09:23:16 2014 +0200

modules/sipt: initial support for parsing CPG and ACM messages

---

 modules/sipt/sipt.c       |   24 +++++++++++++++++++
 modules/sipt/ss7.h        |   23 ++++++++++++++++++-
 modules/sipt/ss7_parser.c |   55 +++++++++++++++++++++++++++++++++++++-------
 3 files changed, 92 insertions(+), 10 deletions(-)

diff --git a/modules/sipt/sipt.c b/modules/sipt/sipt.c
index 8b712e7..5a979c0 100644
--- a/modules/sipt/sipt.c
+++ b/modules/sipt/sipt.c
@@ -42,6 +42,7 @@ MODULE_VERSION
 static int sipt_destination(struct sip_msg *msg, char *_destination, char 
*_hops, char * _nai);
 static int sipt_set_calling(struct sip_msg *msg, char *_origin, char *_nai, 
char *_pres, char * _screen);
 static int sipt_get_hop_counter(struct sip_msg *msg, pv_param_t *param, 
pv_value_t *res);
+static int sipt_get_event_info(struct sip_msg *msg, pv_param_t *param, 
pv_value_t *res);
 static int sipt_get_cpc(struct sip_msg *msg, pv_param_t *param, pv_value_t 
*res);
 static int sipt_get_calling_party_nai(struct sip_msg *msg, pv_param_t *param, 
pv_value_t *res);
 static int sipt_get_presentation(struct sip_msg *msg, pv_param_t *param, 
pv_value_t *res);
@@ -103,6 +104,8 @@ static pv_export_t mod_items[] = {
                 0, 0, 0, 0 },
         { {"sipt_hop_counter",  sizeof("sipt_hop_counter")-1}, PVT_OTHER,  
sipt_get_hop_counter,    0,
                 0, 0, 0, 0 },
+        { {"sipt_event_info",  sizeof("sipt_cpc")-1}, PVT_OTHER,  
sipt_get_event_info,    0,
+                0, 0, 0, 0 },
         { {"sipt_cpc",  sizeof("sipt_cpc")-1}, PVT_OTHER,  sipt_get_cpc,    0,
                 0, 0, 0, 0 },
         { {"sipt_calling_party_nai",  sizeof("sipt_calling_party_nai")-1}, 
PVT_OTHER,  sipt_get_calling_party_nai,    0,
@@ -148,6 +151,27 @@ static int sipt_get_hop_counter(struct sip_msg *msg, 
pv_param_t *param, pv_value
        return 0;
 }
 
+static int sipt_get_event_info(struct sip_msg *msg, pv_param_t *param, 
pv_value_t *res)
+{
+       str body;
+       body.s = get_body_part(msg, TYPE_APPLICATION,SUBTYPE_ISUP,&body.len);
+
+       if(body.s == NULL)
+       {
+               LM_INFO("No ISUP Message Found");
+               return -1;
+       }
+
+       if(body.s[0] != ISUP_CPG)
+       {
+               LM_DBG("message not an CPG\n");
+               return -1;
+       }
+       
+       pv_get_sintval(msg, param, res, isup_get_event_info((unsigned 
char*)body.s, body.len));
+       return 0;
+}
+
 static int sipt_get_cpc(struct sip_msg *msg, pv_param_t *param, pv_value_t 
*res)
 {
        str body;
diff --git a/modules/sipt/ss7.h b/modules/sipt/ss7.h
index 24127fc..610db23 100644
--- a/modules/sipt/ss7.h
+++ b/modules/sipt/ss7.h
@@ -163,7 +163,6 @@ struct isup_parm_opt {
        unsigned char data[0];
 };
 
-
 struct isup_iam_fixed {
        unsigned char type;
        unsigned char nature_of_connection;
@@ -175,7 +174,29 @@ struct isup_iam_fixed {
        unsigned char called_party_number[0];
 };
 
+struct isup_acm_fixed {
+       unsigned char type;
+       unsigned char backwards_call_ind[2];
+       unsigned char fixed_pointer;
+       unsigned char optional_pointer;
+};
+
+struct isup_cpg_fixed {
+       unsigned char type;
+       unsigned char event_info;
+       unsigned char fixed_pointer;
+       unsigned char optional_pointer;
+};
+
+union isup_msg {
+       unsigned char type;
+       struct isup_iam_fixed iam;
+       struct isup_acm_fixed acm;
+       struct isup_cpg_fixed cpg;
+};
+
 int isup_get_hop_counter(unsigned char *buf, int len);
+int isup_get_event_info(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);
diff --git a/modules/sipt/ss7_parser.c b/modules/sipt/ss7_parser.c
index 3c6d8ff..b80ebcc 100644
--- a/modules/sipt/ss7_parser.c
+++ b/modules/sipt/ss7_parser.c
@@ -143,33 +143,51 @@ static int encode_calling_party(char * number, int nai, 
int presentation, int sc
         return datalen + 2;
 }
 
-// returns start of specified optional header of IAM, otherwise return -1
+// returns start of specified optional header of IAM or CPG, 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;
+       union isup_msg * message = (union isup_msg*)buf;
+       unsigned char optional_pointer = 0;
 
-       // not an iam? do nothing
-       if(message->type != ISUP_IAM)
+
+       if(message->type == ISUP_IAM)
+       {
+               len -= offsetof(struct isup_iam_fixed, optional_pointer);
+               offset += offsetof(struct isup_iam_fixed, optional_pointer);
+               optional_pointer = message->iam.optional_pointer;
+       }
+       else if(message->type == ISUP_ACM)
        {
+               len -= offsetof(struct isup_acm_fixed, optional_pointer);
+               offset += offsetof(struct isup_acm_fixed, optional_pointer);
+               optional_pointer = message->acm.optional_pointer;
+       }
+       else if(message->type == ISUP_CPG)
+       {
+               len -= offsetof(struct isup_cpg_fixed, optional_pointer);
+               offset += offsetof(struct isup_cpg_fixed, optional_pointer);
+               optional_pointer = message->cpg.optional_pointer;
+       }
+       else
+       {
+               // don't recognize the type? do nothing
                return -1;
        }
 
-       len -= offsetof(struct isup_iam_fixed, optional_pointer);
-       offset += offsetof(struct isup_iam_fixed, optional_pointer);
 
        if (len < 1)
                return -1;
 
-       offset += message->optional_pointer;
-       len -= message->optional_pointer;
+       offset += optional_pointer;
+       len -= optional_pointer;
 
        if (len < 1 )
                return -1;
 
        /* Optional paramter parsing code */
-       if (message->optional_pointer) {
+       if (optional_pointer) {
                while ((len > 0) && (buf[offset] != 0)) {
                        struct isup_parm_opt *optparm = (struct isup_parm_opt 
*)(buf + offset);
 
@@ -197,6 +215,25 @@ int isup_get_hop_counter(unsigned char *buf, int len)
        return -1;
 }
 
+int isup_get_event_info(unsigned char *buf, int len)
+{
+       struct isup_cpg_fixed * message = (struct isup_cpg_fixed*)buf;
+
+       // not a CPG? do nothing
+       if(message->type != ISUP_CPG)
+       {
+               return -1;
+       }
+
+       /* Message Type = 1 */
+       len -= offsetof(struct isup_cpg_fixed, event_info);
+
+       if (len < 1)
+               return -1;
+
+       return (int)message->event_info;
+}
+
 int isup_get_cpc(unsigned char *buf, int len)
 {
        struct isup_iam_fixed * message = (struct isup_iam_fixed*)buf;


_______________________________________________
sr-dev mailing list
sr-dev@lists.sip-router.org
http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev

Reply via email to