Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sipt: Add functions to work with forwarding info #1498

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
72 changes: 72 additions & 0 deletions src/modules/sipt/doc/sipt_admin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,22 @@ sipt_set_bci_1("2", "1", "1", "0");
# update the calling party to the value in the from header
sipt_set_calling($fU, 4, 0, 3);
...
</programlisting>
</example>
</section>
<section id="sipt.f.sipt_forwarding">
<title><function moreinfo="none">sipt_forwarding(origin, nai)</function></title>
<para>
updates the IAM in the body if it exists, setting (or adding) the forwarding number to <quote>origin</quote>
with the nature address specified in <quote>nai</quote>.
</para>
<example>
<title><function moreinfo="none">sipt_set_calling(origin, nai)</function> usage</title>
<programlisting format="linespecific">
...
# update the forwarding number to the value in the from header
sipt_forwarfing($avp(s:forwarding_number), 3);
...
</programlisting>
</example>
</section>
Expand Down Expand Up @@ -313,7 +329,63 @@ if($sipt(called_party_number.nai) == 3)
</tgroup>
</table>
</section>
<section id="sipt.v.sipt_redirection_info">
<title><varname>$sipt(redirection_info) / $sipt_redirection_info</varname></title>
<para>
Returns redirection info header from ISUP
Returns "Redirecting reason" or -1 if no redirection info found.
</para>
<table>
<title>Redirecting reason Values</title>
<tgroup cols="2">
<tbody>
<row><entry>0</entry><entry>Unknown</entry></row>
<row><entry>1</entry><entry>User busy</entry></row>
<row><entry>2</entry><entry>PROGRESS</entry></row>
<row><entry>3</entry><entry>no reply</entry></row>
<row><entry>4</entry><entry>deflection during alerting</entry></row>
<row><entry>5</entry><entry>deflection immediate response</entry></row>
<row><entry>6</entry><entry>mobile subscriber not reachable</entry></row>
</tbody>
</tgroup>
</table>
</section>
<section id="sipt.v.sipt_redirection_number">
<title><varname>$sipt(redirection_number) / $sipt_redirection_number</varname></title>
<para>
Returns number to which redirection will trigered
Returns -1 if there is a parsing error.
</para>
<example>
<title><function moreinfo="none">sipt_redirection_number</function> usage</title>
<programlisting format="linespecific">
...
# get the redirection number
$avp(s:redir_num) = $sipt(redirection_number);

...
</programlisting>
</example>
</section>
<section id="sipt.v.sipt_redirection_number_nai">
<title><varname>$sipt(redirection_number.nai) / $sipt_redirection_number_nai</varname></title>
<para>
Returns NAI for redirection number from ISUP
Returns NAI for redirection number or -1 if no info found.
</para>
<table>
<title>Redirecting number NAI Values</title>
<tgroup cols="2">
<tbody>
<row><entry>0</entry><entry>Spare</entry></row>
<row><entry>1</entry><entry>Subscriber Number (national use)</entry></row>
<row><entry>2</entry><entry>Unknown (national use)</entry></row>
<row><entry>3</entry><entry>National (significant) number (national use)</entry></row>
<row><entry>4</entry><entry>International use</entry></row>
</tbody>
</tgroup>
</table>
</section>
</section>
</chapter>

164 changes: 163 additions & 1 deletion src/modules/sipt/sipt.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,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_destination2(struct sip_msg *msg, char *_destination, char *_hops, char * _nai, char * _terminator);
static int sipt_forwarding(struct sip_msg *msg, char *_fwdnumber, 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);
Expand All @@ -51,6 +52,10 @@ static int sipt_get_screening(struct sip_msg *msg, pv_param_t *param, pv_value_t
static int sipt_get_called_party_nai(struct sip_msg *msg, pv_param_t *param, pv_value_t *res);
static int sipt_get_charge_indicator(struct sip_msg *msg, pv_param_t *param, pv_value_t *res);

static int sipt_get_redirection_info(struct sip_msg *msg, pv_param_t *param, pv_value_t *res);
static int sipt_get_redirection_number_nai(struct sip_msg *msg, pv_param_t *param, pv_value_t *res);
static int sipt_get_redirection_number(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);
Expand Down Expand Up @@ -97,6 +102,13 @@ static sipt_header_map_t sipt_header_mapping[] =
{{"CHARGE_INDICATOR", 1},
{NULL, 0}
}},
{"REDIRECTION_INFO", ISUP_PARM_REDIRECTION_INFO,
{{NULL, 0}} },
{"REDIRECTION_NUMBER", ISUP_PARM_REDIRECTION_NUMBER,
{{"NATURE_OF_ADDRESS", 1},
{"NAI", 1},
{NULL, 0}
}},
{ NULL, 0, {}}
};

Expand Down Expand Up @@ -139,6 +151,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_forwarding", /* action name as in scripts */
(cmd_function)sipt_forwarding, /* C function name */
2, /* number of parameters */
fixup_str_str_str, fixup_free_str_str_str, /* */
/* can be applied to original requests */
REQUEST_ROUTE|BRANCH_ROUTE},
{"sipt_set_calling", /* action name as in scripts */
(cmd_function)sipt_set_calling, /* C function name */
4, /* number of parameters */
Expand Down Expand Up @@ -173,6 +191,12 @@ static pv_export_t mod_items[] = {
0, 0, 0, 0 },
{ {"sipt", sizeof("sipt")-1}, PVT_OTHER, sipt_get_pv, 0,
sipt_parse_pv_name, 0, 0, 0 },
{ {"sipt_redirection_info", sizeof("sipt_redirection_info")-1}, PVT_OTHER, sipt_get_redirection_info, 0,
0, 0, 0, 0 },
{ {"sipt_redirection_number_nai", sizeof("sipt_redirection_number_nai")-1}, PVT_OTHER, sipt_get_redirection_number_nai, 0,
0, 0, 0, 0 },
{ {"sipt_redirection_number", sizeof("sipt_redirection_number")-1}, PVT_OTHER, sipt_get_redirection_number, 0,
0, 0, 0, 0 },
{ {0, 0}, 0, 0, 0, 0, 0, 0, 0 }
};

Expand Down Expand Up @@ -275,6 +299,78 @@ static int sipt_get_calling_party_nai(struct sip_msg *msg, pv_param_t *param, pv
return 0;
}

static int sipt_get_redirection_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_ACM) && (body.s[0] != ISUP_CPG))
{
LM_DBG("message not an ACM or CPG\n");
return -1;
}

pv_get_sintval(msg, param, res, isup_get_redirection_info((unsigned char*)body.s, body.len));
return 0;
}

static int sipt_get_redirection_number_nai(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_ACM) && (body.s[0] != ISUP_CPG))
{
LM_DBG("message not an ACM or CPG\n");
return -1;
}

pv_get_sintval(msg, param, res, isup_get_redirection_number_nai((unsigned char*)body.s, body.len));
return 0;
}

static int sipt_get_redirection_number(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
{
char *sb_s_buf = pkg_malloc(sizeof(char) * (26));
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_ACM) && (body.s[0] != ISUP_CPG))
{
LM_DBG("message not an ACM or CPG\n");
return -1;
}

isup_get_redirection_number((unsigned char*)body.s, body.len, sb_s_buf);

if (strlen(sb_s_buf) > 0)
{
pv_get_strzval(msg, param, res, sb_s_buf);
} else {
pv_get_sintval(msg, param, res, -1);
}
return 0;
}


static int sipt_get_presentation(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
{
str body;
Expand Down Expand Up @@ -508,6 +604,17 @@ static int sipt_get_pv(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
return sipt_get_charge_indicator(msg, param, res);
}
break;
case ISUP_PARM_REDIRECTION_INFO:
return sipt_get_redirection_info(msg, param, res);
case ISUP_PARM_REDIRECTION_NUMBER:
switch(spv->sub_type)
{
case 0: /* NUMBER */
return sipt_get_redirection_number(msg, param, res);
case 1: /* NAI */
return sipt_get_redirection_number_nai(msg, param, res);
}
break;
}

return -1;
Expand Down Expand Up @@ -689,7 +796,7 @@ static int sipt_set_calling(struct sip_msg *msg, char *_origin, char *_nai, char
mangle.msg = msg;
mangle.body_offset = (int)(body.s - msg->buf);

char * digits = calloc(1,origin->len+1);
char * digits = calloc(1,origin->len+2);
memcpy(digits, origin->s, origin->len);

int res = isup_update_calling(&mangle, digits, int_nai, pres, screen, (unsigned char*)body.s, body.len);
Expand All @@ -703,6 +810,61 @@ static int sipt_set_calling(struct sip_msg *msg, char *_origin, char *_nai, char
return 1;
}

static int sipt_forwarding(struct sip_msg *msg, char *_fwdnumber, char * _nai)
{
str * nai = (str*)_nai;
unsigned int int_nai = 0;
str2int(nai, &int_nai);
str * fwdnumber = (str*)_fwdnumber;
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_IAM)
{
LM_DBG("message not an IAM\n");
return -1;
}

mangle.msg = msg;
mangle.body_offset = (int)(body.s - msg->buf);

char * digits = calloc(1,fwdnumber->len+2);
memcpy(digits, fwdnumber->s, fwdnumber->len);

int res = isup_update_forwarding(&mangle, digits, int_nai, (unsigned char*)body.s, body.len);
free(digits);
if(res < 0)
{
LM_DBG("error updating IAM\n");
return -1;
}

return 1;
}


static int mod_init(void)
{
Expand Down
6 changes: 4 additions & 2 deletions src/modules/sipt/ss7.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,14 +177,12 @@ struct isup_iam_fixed {
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;
};

Expand All @@ -206,6 +204,10 @@ int isup_get_charging_indicator(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);
int isup_update_forwarding(struct sdp_mangler * mangle, char * forwardn, int nai, unsigned char *buf, int len);

int isup_get_redirection_info(unsigned char *buf, int len);
int isup_get_redirection_number_nai(unsigned char *buf, int len);
int isup_get_redirection_number(unsigned char *buf, int len, char* sb_buf);

#endif