[sr-dev] git:master: modules/sipt: initial support for parsing CPG and ACM messages

Torrey Searle tsearle at gmail.com
Mon Apr 7 09:44:01 CEST 2014


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 <tsearle at gmail.com>
Committer: Torrey Searle <tsearle at 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;




More information about the sr-dev mailing list