Преглед изворни кода

Merge pull request #93 from tsearle/master

modules/sipt: added the ability to modify the first byte of Backwards Call Indication Parameters
tsearle пре 10 година
родитељ
комит
1dbcc93952
5 измењених фајлова са 154 додато и 20 уклоњено
  1. 43 18
      modules/sipt/README
  2. 18 0
      modules/sipt/doc/sipt_admin.xml
  3. 69 1
      modules/sipt/sipt.c
  4. 1 0
      modules/sipt/ss7.h
  5. 23 1
      modules/sipt/ss7_parser.c

+ 43 - 18
modules/sipt/README

@@ -17,7 +17,10 @@ Torrey Searle
         3. Functions
 
               3.1. sipt_destination(destination, hops, nai)
-              3.2. sipt_set_calling(origin, nai, presentation, screening)
+              3.2. sipt_set_bci_1(charge_indicator, called_status,
+                      called_category, e2e_indicator)
+
+              3.3. sipt_set_calling(origin, nai, presentation, screening)
 
         4. Exported pseudo-variables
 
@@ -48,13 +51,14 @@ Torrey Searle
    List of Examples
 
    1.1. sipt_destination(destination, hops, nai) usage
-   1.2. sipt_set_calling(origin, nai, presentation, screening) usage
-   1.3. sipt_presentation pseudo-variable usage
-   1.4. sipt_screening pseudo-variable usage
-   1.5. sipt_hop_counter pseudo-variable usage
-   1.6. sipt_cpc pseudo-variable usage
-   1.7. sipt_calling_party_nai pseudo-variable usage
-   1.8. sipt_called_party_nai pseudo-variable usage
+   1.2. sipt_destination(destination, hops, nai) usage
+   1.3. sipt_set_calling(origin, nai, presentation, screening) usage
+   1.4. sipt_presentation pseudo-variable usage
+   1.5. sipt_screening pseudo-variable usage
+   1.6. sipt_hop_counter pseudo-variable usage
+   1.7. sipt_cpc pseudo-variable usage
+   1.8. sipt_calling_party_nai pseudo-variable usage
+   1.9. sipt_called_party_nai pseudo-variable usage
 
 Chapter 1. Admin Guide
 
@@ -65,7 +69,10 @@ Chapter 1. Admin Guide
    3. Functions
 
         3.1. sipt_destination(destination, hops, nai)
-        3.2. sipt_set_calling(origin, nai, presentation, screening)
+        3.2. sipt_set_bci_1(charge_indicator, called_status,
+                called_category, e2e_indicator)
+
+        3.3. sipt_set_calling(origin, nai, presentation, screening)
 
    4. Exported pseudo-variables
 
@@ -97,7 +104,10 @@ Chapter 1. Admin Guide
 3. Functions
 
    3.1. sipt_destination(destination, hops, nai)
-   3.2. sipt_set_calling(origin, nai, presentation, screening)
+   3.2. sipt_set_bci_1(charge_indicator, called_status, called_category,
+          e2e_indicator)
+
+   3.3. sipt_set_calling(origin, nai, presentation, screening)
 
 3.1. sipt_destination(destination, hops, nai)
 
@@ -114,14 +124,29 @@ $rU = "19495551234";
 sipt_destination($rU, 31, 4);
 ...
 
-3.2. sipt_set_calling(origin, nai, presentation, screening)
+3.2. sipt_set_bci_1(charge_indicator, called_status, called_category,
+e2e_indicator)
+
+   updates the first byte of the backward call indicator in the ACM or COT
+   in the body if setting the Charge Indicator to “charge_indicator”, the
+   Called party's status indicator in “called_status”, the Called party's
+   category indicator in “called_category” and the End to End Method
+   Indicator with the value of the value of “e2e_indicator”.
+
+   Example 1.2. sipt_destination(destination, hops, nai) usage
+...
+# set bci for charging, subscriber free, ordinary, no e2e available
+sipt_set_bci_1("2", "1", "1", "0");
+...
+
+3.3. sipt_set_calling(origin, nai, presentation, screening)
 
    updates the IAM in the body if it exists, setting (or adding) the
    calling party number to “origin” with the nature address specified in
    “nai” and setting the presentation and screening values to
    “presentation” and “screening”.
 
-   Example 1.2. sipt_set_calling(origin, nai, presentation, screening)
+   Example 1.3. sipt_set_calling(origin, nai, presentation, screening)
    usage
 ...
 # update the calling party to the value in the from header
@@ -154,7 +179,7 @@ sipt_set_calling($fU, 4, 0, 3);
    2 address not avail (national use)
    3 spare
 
-   Example 1.3. sipt_presentation pseudo-variable usage
+   Example 1.4. sipt_presentation pseudo-variable usage
 ...
 # add privacy header if restriction is requested
 if($sipt(calling_party_number.presentation) == 1)
@@ -177,7 +202,7 @@ if($sipt(calling_party_number.presentation) == 1)
    2 Reserved (user provided, verified and failed)
    3 Network provided
 
-   Example 1.4. sipt_screening pseudo-variable usage
+   Example 1.5. sipt_screening pseudo-variable usage
 ...
 
 # remove P-Asserted-Identity header if the screening isn't verified
@@ -195,7 +220,7 @@ if($avp(s:screening) != 1 && $avp(s:screening) != 3)
    Returns the value of the Hop Counter for the IAM message if it exists.
    Returns -1 if there isn't a hop counter.
 
-   Example 1.5. sipt_hop_counter pseudo-variable usage
+   Example 1.6. sipt_hop_counter pseudo-variable usage
 ...
 # get the hop counter and update the Max-Forwards header if it exists
 $avp(s:hop) = $sipt(hop_counter);
@@ -212,7 +237,7 @@ if($avp(s:hop) > 0)
    Returns the value of the Calling Party Category for the IAM message.
    Returns -1 if there is a parsing error.
 
-   Example 1.6. sipt_cpc pseudo-variable usage
+   Example 1.7. sipt_cpc pseudo-variable usage
 ...
 # get the Cpc code and set put it in a custom sip header
 append_hf("X-CPC: $sipt(cpc)\r\n");
@@ -233,7 +258,7 @@ $sipt.(calling_party_number.nai) / $sipt_calling_party_nai
    3 National (significant) number (national use)
    4 International use
 
-   Example 1.7. sipt_calling_party_nai pseudo-variable usage
+   Example 1.8. sipt_calling_party_nai pseudo-variable usage
 ...
 # get the Calling Nai and add country code if national
 if($sipt(calling_party_number.nai) == 3)
@@ -257,7 +282,7 @@ $sipt(called_party_number.nai) / $sipt_called_party_nai
    4 International use
    5 Network-specific number (national use)
 
-   Example 1.8. sipt_called_party_nai pseudo-variable usage
+   Example 1.9. sipt_called_party_nai pseudo-variable usage
 ...
 # get the Called Nai and add country code if national
 if($sipt(called_party_number.nai) == 3)

+ 18 - 0
modules/sipt/doc/sipt_admin.xml

@@ -53,6 +53,24 @@
 $rU = "19495551234";
 sipt_destination($rU, 31, 4);
 ...
+</programlisting>
+		</example>
+	</section>
+	<section id="sipt.f.sipt_set_bci_1">
+		<title><function moreinfo="none">sipt_set_bci_1(charge_indicator, called_status, called_category, e2e_indicator)</function></title>
+		<para>
+			updates the first byte of the backward call indicator in the ACM or COT in the body if setting the 
+			Charge Indicator to <quote>charge_indicator</quote>, the Called party's status indicator in <quote>called_status</quote>, 
+			the Called party's category indicator in <quote>called_category</quote> and the End to End Method Indicator
+			with the value of the value of <quote>e2e_indicator</quote>.
+		</para>
+		<example>
+			<title><function moreinfo="none">sipt_destination(destination, hops, nai)</function> usage</title>
+			<programlisting format="linespecific">
+...
+# set bci for charging, subscriber free, ordinary, no e2e available
+sipt_set_bci_1("2", "1", "1", "0");
+...
 </programlisting>
 		</example>
 	</section>

+ 69 - 1
modules/sipt/sipt.c

@@ -1,6 +1,6 @@
 /*
  *
- * Copyright (C) 2013 Voxbone SA
+ * Copyright (C) 2015 Voxbone SA
  *
  * This file is part of SIP-Router, a free SIP server.
  *
@@ -39,6 +39,7 @@
 
 MODULE_VERSION
 
+static int sipt_set_bci_1(struct sip_msg *msg, char *_charge_indicator, char *_called_status, char * _called_category, char * _e2e_indicator);
 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);
@@ -133,6 +134,12 @@ static cmd_export_t cmds[]={
 		fixup_str_str_str, fixup_free_str_str_str,         /* */
 		/* can be applied to original requests */
 		REQUEST_ROUTE|BRANCH_ROUTE}, 
+	{"sipt_set_bci_1", /* action name as in scripts */
+		(cmd_function)sipt_set_bci_1,  /* C function name */
+		4,          /* number of parameters */
+		fixup_str_str_str, fixup_free_str_str_str,         /* */
+		/* can be applied to original requests */
+		ONREPLY_ROUTE}, 
 	{0, 0, 0, 0, 0, 0}
 };
 
@@ -469,6 +476,67 @@ static int sipt_get_pv(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
 	return -1;
 }
 
+static int sipt_set_bci_1(struct sip_msg *msg, char *_charge_indicator, char *_called_status, char * _called_category, char * _e2e_indicator)
+{
+	str * str_charge_indicator = (str*)_charge_indicator;
+	unsigned int charge_indicator = 0;
+	str2int(str_charge_indicator, &charge_indicator);
+	str * str_called_status = (str*)_called_status;
+	unsigned int called_status = 0;
+	str2int(str_called_status, &called_status);
+	str * str_called_category = (str*)_called_category;
+	unsigned int called_category = 0;
+	str2int(str_called_category, &called_category);
+	str * str_e2e_indicator = (str*)_e2e_indicator;
+	unsigned int e2e_indicator = 0;
+	str2int(str_e2e_indicator, &e2e_indicator);
+	struct sdp_mangler mangle;
+
+	// update forwarded iam
+	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;
+	}
+	str sdp;
+	sdp.s = get_body_part(msg, TYPE_APPLICATION, SUBTYPE_SDP, &sdp.len);
+	
+	unsigned char newbuf[1024];
+	memset(newbuf, 0, 1024);
+	if (body.s==0) {
+		LM_ERR("failed to get the message body\n");
+		return -1;
+	}
+	body.len = msg->len -(int)(body.s-msg->buf);
+	if (body.len==0) {
+		LM_DBG("message body has zero length\n");
+		return -1;
+	}
+
+	if(body.s[0] != ISUP_ACM && body.s[0] != ISUP_COT)
+	{
+		LM_DBG("message not an ACM or COT\n");
+		return -1;
+	}
+
+	mangle.msg = msg;
+	mangle.body_offset = (int)(body.s - msg->buf);
+
+
+
+	int res = isup_update_bci_1(&mangle, charge_indicator, called_status, called_category, e2e_indicator, (unsigned char*)body.s, body.len);
+	if(res < 0)
+	{
+		LM_DBG("error updating ACM\n");
+		return -1;
+	}
+
+	return 1;
+}
+
 static int sipt_destination(struct sip_msg *msg, char *_destination, char *_hops, char * _nai)
 {
 	str * str_hops = (str*)_hops;

+ 1 - 0
modules/sipt/ss7.h

@@ -203,6 +203,7 @@ int isup_get_called_party_nai(unsigned char *buf, int len);
 int isup_get_screening(unsigned char *buf, int len);
 int isup_get_presentation(unsigned char *buf, int len);
 int isup_update_destination(struct sdp_mangler * mangle, char * dest, int hops, int nai, unsigned char *buf, int len);
+int isup_update_bci_1(struct sdp_mangler * mangle, int charge_indicator, int called_status, int called_category, int e2e_indicator, unsigned char *buf, int len);
 int isup_update_calling(struct sdp_mangler * mangle, char * origin, int nai, int presentation, int screening, unsigned char * buf, int len);
 
 

+ 23 - 1
modules/sipt/ss7_parser.c

@@ -158,7 +158,7 @@ static int get_optional_header(unsigned char header, unsigned char *buf, int len
 		offset += offsetof(struct isup_iam_fixed, optional_pointer);
 		optional_pointer = message->iam.optional_pointer;
 	}
-	else if(message->type == ISUP_ACM)
+	else if(message->type == ISUP_ACM || message->type == ISUP_COT)
 	{
 		len -= offsetof(struct isup_acm_fixed, optional_pointer);
 		offset += offsetof(struct isup_acm_fixed, optional_pointer);
@@ -305,6 +305,28 @@ int isup_get_called_party_nai(unsigned char *buf, int len)
 	return message->called_party_number[1]&0x7F;
 }
 
+int isup_update_bci_1(struct sdp_mangler * mangle, int charge_indicator, int called_status, int called_category, int e2e_indicator, unsigned char *buf, int len)
+{
+	struct isup_acm_fixed * orig_message = (struct isup_acm_fixed*)buf;
+	unsigned char bci;
+
+	// not an acm or cot? do nothing
+	if(orig_message->type != ISUP_ACM && orig_message->type != ISUP_COT)
+	{
+		return 1;
+	}
+
+	if (len < sizeof(struct isup_acm_fixed))
+		return -1;
+
+	bci = (charge_indicator & 0x3) | ((called_status & 0x3)<<2) |
+		((called_category & 0x3)<<4) | ((e2e_indicator & 0x3)<<6);
+
+	add_body_segment(mangle, offsetof(struct isup_acm_fixed, backwards_call_ind), &bci, 1);
+
+	return sizeof(struct isup_acm_fixed);
+}
+
 int isup_update_destination(struct sdp_mangler * mangle, char * dest, int hops, int nai, unsigned char *buf, int len)
 {
 	int offset = 0;