Ver código fonte

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

Torrey Searle 11 anos atrás
pai
commit
2639e3ddcb
3 arquivos alterados com 92 adições e 10 exclusões
  1. 24 0
      modules/sipt/sipt.c
  2. 22 1
      modules/sipt/ss7.h
  3. 46 9
      modules/sipt/ss7_parser.c

+ 24 - 0
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_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_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_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_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_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);
 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 },
                 0, 0, 0, 0 },
         { {"sipt_hop_counter",  sizeof("sipt_hop_counter")-1}, PVT_OTHER,  sipt_get_hop_counter,    0,
         { {"sipt_hop_counter",  sizeof("sipt_hop_counter")-1}, PVT_OTHER,  sipt_get_hop_counter,    0,
                 0, 0, 0, 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,
         { {"sipt_cpc",  sizeof("sipt_cpc")-1}, PVT_OTHER,  sipt_get_cpc,    0,
                 0, 0, 0, 0 },
                 0, 0, 0, 0 },
         { {"sipt_calling_party_nai",  sizeof("sipt_calling_party_nai")-1}, PVT_OTHER,  sipt_get_calling_party_nai,    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;
 	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)
 static int sipt_get_cpc(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
 {
 {
 	str body;
 	str body;

+ 22 - 1
modules/sipt/ss7.h

@@ -163,7 +163,6 @@ struct isup_parm_opt {
 	unsigned char data[0];
 	unsigned char data[0];
 };
 };
 
 
-
 struct isup_iam_fixed {
 struct isup_iam_fixed {
 	unsigned char type;
 	unsigned char type;
 	unsigned char nature_of_connection;
 	unsigned char nature_of_connection;
@@ -175,7 +174,29 @@ struct isup_iam_fixed {
 	unsigned char called_party_number[0];
 	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_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_cpc(unsigned char *buf, int len);
 int isup_get_calling_party_nai(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_get_called_party_nai(unsigned char *buf, int len);

+ 46 - 9
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;
         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)
 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 offset = 0;
 	int res;
 	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;
 		return -1;
 	}
 	}
 
 
-	len -= offsetof(struct isup_iam_fixed, optional_pointer);
-	offset += offsetof(struct isup_iam_fixed, optional_pointer);
 
 
 	if (len < 1)
 	if (len < 1)
 		return -1;
 		return -1;
 
 
-	offset += message->optional_pointer;
-	len -= message->optional_pointer;
+	offset += optional_pointer;
+	len -= optional_pointer;
 
 
 	if (len < 1 )
 	if (len < 1 )
 		return -1;
 		return -1;
 
 
 	/* Optional paramter parsing code */
 	/* Optional paramter parsing code */
-	if (message->optional_pointer) {
+	if (optional_pointer) {
 		while ((len > 0) && (buf[offset] != 0)) {
 		while ((len > 0) && (buf[offset] != 0)) {
 			struct isup_parm_opt *optparm = (struct isup_parm_opt *)(buf + offset);
 			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;
 	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)
 int isup_get_cpc(unsigned char *buf, int len)
 {
 {
 	struct isup_iam_fixed * message = (struct isup_iam_fixed*)buf;
 	struct isup_iam_fixed * message = (struct isup_iam_fixed*)buf;