浏览代码

modules/sipt: refactored pseudovars to be of the form $sipt(header[.field])

Torrey Searle 11 年之前
父节点
当前提交
b0ab6f7083
共有 3 个文件被更改,包括 258 次插入49 次删除
  1. 52 34
      modules/sipt/README
  2. 13 13
      modules/sipt/doc/sipt_admin.xml
  3. 193 2
      modules/sipt/sipt.c

+ 52 - 34
modules/sipt/README

@@ -21,13 +21,21 @@ Torrey Searle
 
         4. Exported pseudo-variables
 
-              4.1. $sipt_presentation
-              4.2. $sipt_screening
-              4.3. $sipt_hop_counter
-              4.4. $sipt_cpc
-              4.5. $sipt_calling_party_nai
-              4.6. $sipt_called_party_nai
-              4.7. $sipt_event_info
+              4.1. $sipt(calling_party_number.presentation) /
+                      $sipt_presentation
+
+              4.2. $sipt(calling_party_number.screening) / $sipt_screening
+              4.3. $sipt(hop_counter) / $sipt_hop_counter
+              4.4. $sipt(calling_party_category) / $sipt(cpc) / $sipt_cpc
+              4.5. $sipt(calling_party_number.nature_of_address) /
+                      $sipt.(calling_party_number.nai) /
+                      $sipt_calling_party_nai
+
+              4.6. $sipt(called_party_number.nature_of_address) /
+                      $sipt(called_party_number.nai) /
+                      $sipt_called_party_nai
+
+              4.7. $sipt(event_info)
 
    List of Tables
 
@@ -61,13 +69,17 @@ Chapter 1. Admin Guide
 
    4. Exported pseudo-variables
 
-        4.1. $sipt_presentation
-        4.2. $sipt_screening
-        4.3. $sipt_hop_counter
-        4.4. $sipt_cpc
-        4.5. $sipt_calling_party_nai
-        4.6. $sipt_called_party_nai
-        4.7. $sipt_event_info
+        4.1. $sipt(calling_party_number.presentation) / $sipt_presentation
+        4.2. $sipt(calling_party_number.screening) / $sipt_screening
+        4.3. $sipt(hop_counter) / $sipt_hop_counter
+        4.4. $sipt(calling_party_category) / $sipt(cpc) / $sipt_cpc
+        4.5. $sipt(calling_party_number.nature_of_address) /
+                $sipt.(calling_party_number.nai) / $sipt_calling_party_nai
+
+        4.6. $sipt(called_party_number.nature_of_address) /
+                $sipt(called_party_number.nai) / $sipt_called_party_nai
+
+        4.7. $sipt(event_info)
 
 1. Overview
 
@@ -118,15 +130,19 @@ sipt_set_calling($fU, 4, 0, 3);
 
 4. Exported pseudo-variables
 
-   4.1. $sipt_presentation
-   4.2. $sipt_screening
-   4.3. $sipt_hop_counter
-   4.4. $sipt_cpc
-   4.5. $sipt_calling_party_nai
-   4.6. $sipt_called_party_nai
-   4.7. $sipt_event_info
+   4.1. $sipt(calling_party_number.presentation) / $sipt_presentation
+   4.2. $sipt(calling_party_number.screening) / $sipt_screening
+   4.3. $sipt(hop_counter) / $sipt_hop_counter
+   4.4. $sipt(calling_party_category) / $sipt(cpc) / $sipt_cpc
+   4.5. $sipt(calling_party_number.nature_of_address) /
+          $sipt.(calling_party_number.nai) / $sipt_calling_party_nai
+
+   4.6. $sipt(called_party_number.nature_of_address) /
+          $sipt(called_party_number.nai) / $sipt_called_party_nai
+
+   4.7. $sipt(event_info)
 
-4.1. $sipt_presentation
+4.1. $sipt(calling_party_number.presentation) / $sipt_presentation
 
    Returns the value of the Address presentation restricted indicator
    contained in the Calling Party Number header of the IAM message if it
@@ -141,7 +157,7 @@ sipt_set_calling($fU, 4, 0, 3);
    Example 1.3. sipt_presentation pseudo-variable usage
 ...
 # add privacy header if restriction is requested
-if($sipt_presentation == 1)
+if($sipt(calling_party_number.presentation) == 1)
 {
         append_hf("Privacy: id\r\n");
         $fn = "Anonymous";
@@ -149,7 +165,7 @@ if($sipt_presentation == 1)
 
 ...
 
-4.2. $sipt_screening
+4.2. $sipt(calling_party_number.screening) / $sipt_screening
 
    Returns the value of the Screening Indicator contained in the Calling
    Party Number header of the IAM message if it exists. Returns -1 if
@@ -166,7 +182,7 @@ if($sipt_presentation == 1)
 
 # remove P-Asserted-Identity header if the screening isn't verified
 # or network provided
-$avp(s:screening) = $sipt_screening;
+$avp(s:screening) = $sipt(calling_party_number.screening);
 if($avp(s:screening) != 1 && $avp(s:screening) != 3)
 {
         remove_hf("P-Asserted-Id");
@@ -174,7 +190,7 @@ if($avp(s:screening) != 1 && $avp(s:screening) != 3)
 
 ...
 
-4.3. $sipt_hop_counter
+4.3. $sipt(hop_counter) / $sipt_hop_counter
 
    Returns the value of the Hop Counter for the IAM message if it exists.
    Returns -1 if there isn't a hop counter.
@@ -182,7 +198,7 @@ if($avp(s:screening) != 1 && $avp(s:screening) != 3)
    Example 1.5. 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;
+$avp(s:hop) = $sipt(hop_counter);
 if($avp(s:hop) > 0)
 {
         remove_hf("Max-Forwards");
@@ -191,7 +207,7 @@ if($avp(s:hop) > 0)
 
 ...
 
-4.4. $sipt_cpc
+4.4. $sipt(calling_party_category) / $sipt(cpc) / $sipt_cpc
 
    Returns the value of the Calling Party Category for the IAM message.
    Returns -1 if there is a parsing error.
@@ -199,11 +215,12 @@ if($avp(s:hop) > 0)
    Example 1.6. 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");
+append_hf("X-CPC: $sipt(cpc)\r\n");
 
 ...
 
-4.5. $sipt_calling_party_nai
+4.5. $sipt(calling_party_number.nature_of_address) /
+$sipt.(calling_party_number.nai) / $sipt_calling_party_nai
 
    Returns the value of the Nature of Address Indicator of the Calling
    Party for the IAM message. Returns -1 if there is a parsing error or if
@@ -219,14 +236,15 @@ append_hf("X-CPC: $sipt_cpc\r\n");
    Example 1.7. sipt_calling_party_nai pseudo-variable usage
 ...
 # get the Calling Nai and add country code if national
-if($sipt_calling_party_nai == 3)
+if($sipt(calling_party_number.nai) == 3)
 {
         $fU = "32" + "$fU";
 }
 
 ...
 
-4.6. $sipt_called_party_nai
+4.6. $sipt(called_party_number.nature_of_address) /
+$sipt(called_party_number.nai) / $sipt_called_party_nai
 
    Returns the value of the Nature of Address Indicator of the Called
    Party for the IAM message. Returns -1 if there is a parsing error.
@@ -242,14 +260,14 @@ if($sipt_calling_party_nai == 3)
    Example 1.8. sipt_called_party_nai pseudo-variable usage
 ...
 # get the Called Nai and add country code if national
-if($sipt_called_party_nai == 3)
+if($sipt(called_party_number.nai) == 3)
 {
         $rU = "32" + "$rU";
 }
 
 ...
 
-4.7. $sipt_event_info
+4.7. $sipt(event_info)
 
    Returns the value of the Event Info header of the CPG message. Returns
    -1 if there is a parsing error.

+ 13 - 13
modules/sipt/doc/sipt_admin.xml

@@ -77,7 +77,7 @@ sipt_set_calling($fU, 4, 0, 3);
 <section>
         <title>Exported pseudo-variables</title>
 	<section id="sipt.v.sipt_presentation">
-		<title><varname>$sipt_presentation</varname></title>
+		<title><varname>$sipt(calling_party_number.presentation) / $sipt_presentation</varname></title>
 		<para>
 			Returns the value of the Address presentation restricted indicator contained in the
 			Calling Party Number header of the IAM message if it exists.
@@ -99,7 +99,7 @@ sipt_set_calling($fU, 4, 0, 3);
 			<programlisting format="linespecific">
 ...
 # add privacy header if restriction is requested 
-if($sipt_presentation == 1)
+if($sipt(calling_party_number.presentation) == 1)
 {
 	append_hf("Privacy: id\r\n");
 	$fn = "Anonymous";
@@ -110,7 +110,7 @@ if($sipt_presentation == 1)
 		</example>
 	</section>
 	<section id="sipt.v.sipt_screening">
-		<title><varname>$sipt_screening</varname></title>
+		<title><varname>$sipt(calling_party_number.screening) / $sipt_screening</varname></title>
 		<para>
 			Returns the value of the Screening Indicator contained in the
 			Calling Party Number header of the IAM message if it exists.
@@ -134,7 +134,7 @@ if($sipt_presentation == 1)
 
 # remove P-Asserted-Identity header if the screening isn't verified 
 # or network provided
-$avp(s:screening) = $sipt_screening;
+$avp(s:screening) = $sipt(calling_party_number.screening);
 if($avp(s:screening) != 1 &amp;&amp; $avp(s:screening) != 3)
 {
 	remove_hf("P-Asserted-Id");
@@ -145,7 +145,7 @@ if($avp(s:screening) != 1 &amp;&amp; $avp(s:screening) != 3)
 		</example>
 	</section>
 	<section id="sipt.v.sipt_hop_counter">
-		<title><varname>$sipt_hop_counter</varname></title>
+		<title><varname>$sipt(hop_counter) / $sipt_hop_counter</varname></title>
 		<para>
 			Returns the value of the Hop Counter for the IAM message if it exists.
 			Returns -1 if there isn't a hop counter.
@@ -155,7 +155,7 @@ if($avp(s:screening) != 1 &amp;&amp; $avp(s:screening) != 3)
 			<programlisting format="linespecific">
 ...
 # get the hop counter and update the Max-Forwards header if it exists
-$avp(s:hop) = $sipt_hop_counter;
+$avp(s:hop) = $sipt(hop_counter);
 if($avp(s:hop) > 0)
 {
 	remove_hf("Max-Forwards");
@@ -167,7 +167,7 @@ if($avp(s:hop) > 0)
 		</example>
 	</section>
 	<section id="sipt.v.sipt_cpc">
-		<title><varname>$sipt_cpc</varname></title>
+		<title><varname>$sipt(calling_party_category) / $sipt(cpc) / $sipt_cpc</varname></title>
 		<para>
 			Returns the value of the Calling Party Category for the IAM message.
 			Returns -1 if there is a parsing error.
@@ -177,14 +177,14 @@ if($avp(s:hop) > 0)
 			<programlisting format="linespecific">
 ...
 # get the Cpc code and set put it in a custom sip header
-append_hf("X-CPC: $sipt_cpc\r\n");
+append_hf("X-CPC: $sipt(cpc)\r\n");
 
 ...
 </programlisting>
 		</example>
 	</section>
 	<section id="sipt.v.sipt_calling_party_nai">
-		<title><varname>$sipt_calling_party_nai</varname></title>
+		<title><varname>$sipt(calling_party_number.nature_of_address) / $sipt.(calling_party_number.nai) / $sipt_calling_party_nai</varname></title>
 		<para>
 			Returns the value of the Nature of Address Indicator
 			of the Calling Party for the IAM message.
@@ -208,7 +208,7 @@ append_hf("X-CPC: $sipt_cpc\r\n");
 			<programlisting format="linespecific">
 ...
 # get the Calling Nai and add country code if national
-if($sipt_calling_party_nai == 3)
+if($sipt(calling_party_number.nai) == 3)
 {
 	$fU = "32" + "$fU";
 }
@@ -218,7 +218,7 @@ if($sipt_calling_party_nai == 3)
 		</example>
 	</section>
 	<section id="sipt.v.sipt_called_party_nai">
-		<title><varname>$sipt_called_party_nai</varname></title>
+		<title><varname>$sipt(called_party_number.nature_of_address) / $sipt(called_party_number.nai) / $sipt_called_party_nai</varname></title>
 		<para>
 			Returns the value of the Nature of Address Indicator
 			of the Called Party for the IAM message.
@@ -242,7 +242,7 @@ if($sipt_calling_party_nai == 3)
 			<programlisting format="linespecific">
 ...
 # get the Called Nai and add country code if national
-if($sipt_called_party_nai == 3)
+if($sipt(called_party_number.nai) == 3)
 {
 	$rU = "32" + "$rU";
 }
@@ -252,7 +252,7 @@ if($sipt_called_party_nai == 3)
 		</example>
 	</section>
 	<section id="sipt.v.sipt_event_info">
-		<title><varname>$sipt_event_info</varname></title>
+		<title><varname>$sipt(event_info)</varname></title>
 		<para>
 			Returns the value of the Event Info header
 			of the CPG message.

+ 193 - 2
modules/sipt/sipt.c

@@ -49,6 +49,53 @@ static int sipt_get_presentation(struct sip_msg *msg, pv_param_t *param, pv_valu
 static int sipt_get_screening(struct sip_msg *msg, pv_param_t *param, pv_value_t *res);
 static int sipt_get_called_party_nai(struct sip_msg *msg, pv_param_t *param, pv_value_t *res);
 
+/* New API */
+int sipt_parse_pv_name(pv_spec_p sp, str *in);
+static int sipt_get_pv(struct sip_msg *msg, pv_param_t *param, pv_value_t *res);
+
+typedef struct _sipt_pv {
+        int type;
+        int sub_type;
+} sipt_pv_t;
+
+typedef struct sipt_header_map
+{
+	char * name;
+	unsigned int type;
+	struct sipt_subtype_map
+	{
+		char * name;
+		unsigned int type;
+	} subtypes[5];
+} sipt_header_map_t;
+
+static sipt_header_map_t sipt_header_mapping[] =
+{
+	{"CALLING_PARTY_CATEGORY", ISUP_PARM_CALLING_PARTY_CAT, 
+		{{NULL, 0}} },
+	{"CPC", ISUP_PARM_CALLING_PARTY_CAT, 
+		{{NULL, 0}} },
+	{"CALLING_PARTY_NUMBER", ISUP_PARM_CALLING_PARTY_NUM, 
+		{{"NATURE_OF_ADDRESS", 1}, 
+			{"NAI", 1},
+			{"SCREENING", 2},
+			{"PRESENTATION", 3},
+			{NULL, 0}
+		}},
+	{"CALLED_PARTY_NUMBER", ISUP_PARM_CALLED_PARTY_NUM,
+		{{"NATURE_OF_ADDRESS", 1}, 
+			{"NAI", 1},
+			{NULL, 0}
+		}},
+	{"HOP_COUNTER", ISUP_PARM_HOP_COUNTER, 
+		{{NULL, 0}} },
+	{"EVENT_INFO", ISUP_PARM_EVENT_INFO, 
+		{{NULL, 0}} },
+	{ NULL, 0, {}}
+};
+
+
+
 static int mod_init(void);
 static void mod_destroy(void);
 
@@ -104,14 +151,14 @@ 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_event_info")-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,
                 0, 0, 0, 0 },
         { {"sipt_called_party_nai",  sizeof("sipt_called_party_nai")-1}, PVT_OTHER,  sipt_get_called_party_nai,    0,
                 0, 0, 0, 0 },
+        { {"sipt",  sizeof("sipt")-1}, PVT_OTHER,  sipt_get_pv,    0,
+                sipt_parse_pv_name, 0, 0, 0 },
 	{ {0, 0}, 0, 0, 0, 0, 0, 0, 0 }
 };
 
@@ -278,6 +325,150 @@ static int sipt_get_called_party_nai(struct sip_msg *msg, pv_param_t *param, pv_
 	return 0;
 }
 
+int sipt_parse_pv_name(pv_spec_p sp, str *in)
+{
+        sipt_pv_t *spv=NULL;
+        char *p;
+        str pvtype;
+        str pvsubtype;
+        if(sp==NULL || in==NULL || in->len<=0)
+                return -1;
+
+        spv = (sipt_pv_t*)pkg_malloc(sizeof(sipt_pv_t));
+        if(spv==NULL)
+                return -1;
+
+        memset(spv, 0, sizeof(sipt_pv_t));
+
+	p = in->s;
+
+        while(p<in->s+in->len && (*p==' ' || *p=='\t' || *p=='\n' || *p=='\r'))
+                p++;
+        if(p>in->s+in->len || *p=='\0')
+                goto error;
+
+	pvtype.s = p;
+
+        while(p < in->s + in->len)
+        {
+                if(*p=='.' || *p==' ' || *p=='\t' || *p=='\n' || *p=='\r')
+                        break;
+                p++;
+        }
+        pvtype.len = p - pvtype.s;
+        if(p>in->s+in->len || *p=='\0')
+	{
+		// only one parameter stop parsing
+		pvsubtype.len = 0;
+		pvsubtype.s = NULL;
+                goto parse_parameters;
+	}
+
+        if(*p!='.')
+        {
+                while(p<in->s+in->len && (*p==' ' || *p=='\t' || *p=='\n' || *p=='\r'))
+                        p++;
+                if(p>in->s+in->len || *p=='\0' || *p!='.')
+		{
+			// only one parameter w trailing whitespace
+			pvsubtype.len = 0;
+			pvsubtype.s = NULL;
+			goto parse_parameters;
+		}
+        }
+        p++;
+
+        pvsubtype.len = in->len - (int)(p - in->s);
+        pvsubtype.s = p;
+
+ 
+parse_parameters:
+        LM_DBG("sipt type[%.*s] - subtype[%.*s]\n", pvtype.len, pvtype.s,
+                        pvsubtype.len, pvsubtype.s);
+	int i = 0, j=0;
+
+	for(i=0;sipt_header_mapping[i].name != NULL; i++)
+	{
+		if(strncasecmp(pvtype.s, sipt_header_mapping[i].name, pvtype.len) == 0)
+		{
+			spv->type = sipt_header_mapping[i].type;
+
+			if(pvsubtype.len == 0)
+				break;
+
+			for(j=0;sipt_header_mapping[i].subtypes[j].name != NULL;j++)
+			{
+				if(strncasecmp(pvsubtype.s, sipt_header_mapping[i].subtypes[j].name, pvsubtype.len) == 0)
+				spv->sub_type = sipt_header_mapping[i].subtypes[j].type;
+			}
+			if(spv->sub_type == 0)
+			{
+				LM_ERR("Unknown SIPT subtype [%.*s]\n", pvsubtype.len, pvsubtype.s);
+				return -1;
+			}
+			break;
+		}
+	}
+
+	LM_DBG("Type=%d subtype=%d\n",spv->type, spv->sub_type);
+	if(spv->type == 0)
+	{
+		LM_ERR("Unknown SIPT type [%.*s]\n",pvtype.len, pvtype.s);
+		return -1;
+	}
+
+	sp->pvp.pvn.u.dname = (void*)spv;
+	sp->pvp.pvn.type = PV_NAME_OTHER;
+
+	return 0;
+error:
+        LM_ERR("error at PV sipt name: %.*s\n", in->len, in->s);
+        return -1;
+
+}
+
+static int sipt_get_pv(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
+{
+        sipt_pv_t *spv;
+
+        if(msg==NULL || param==NULL)
+                return -1;
+
+        spv = (sipt_pv_t*)param->pvn.u.dname;
+        if(spv==NULL)
+                return -1;
+
+        switch(spv->type)
+        {
+		case ISUP_PARM_CALLING_PARTY_CAT:
+			return sipt_get_cpc(msg, param, res);
+		case ISUP_PARM_CALLING_PARTY_NUM:
+			switch(spv->sub_type)
+			{
+				case 1: /* NAI */
+					return sipt_get_calling_party_nai(msg, param, res);
+				case 2: /* SCREENIG */
+					return sipt_get_screening(msg, param, res);
+				case 3: /* PRESENTATION */
+					return sipt_get_presentation(msg, param, res);
+			}
+			break;
+		case ISUP_PARM_CALLED_PARTY_NUM:
+			switch(spv->sub_type)
+			{
+				case 1: /* NAI */
+					return sipt_get_called_party_nai(msg, param, res);
+			}
+			break;
+		case ISUP_PARM_HOP_COUNTER:
+			return sipt_get_hop_counter(msg, param, res);
+		case ISUP_PARM_EVENT_INFO:
+			return sipt_get_event_info(msg, param, res);
+	}
+
+	return -1;
+}
+
 static int sipt_destination(struct sip_msg *msg, char *_destination, char *_hops, char * _nai)
 {
 	str * str_hops = (str*)_hops;