Module: sip-router Branch: master Commit: 2639e3ddcb82434544012b537d2ca72264a5c9ee URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=2639e3dd...
Author: Torrey Searle tsearle@gmail.com Committer: Torrey Searle tsearle@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;