We have Implemented RLT features by adding the below patches.
Asterisk Patches :-
chan_dahdi.c :
a703 1
char redirect_value[50];
a3257 1
ast_log(LOG_WARNING, “Orig Called Num 1 : %s\n”, p->origcid_num);
d3408 1
a3408 2
const char *cause = NULL;
cause = pbx_builtin_getvar_helper(ast,“SS7_CAUSE”);
d3410 1
d3415 1
a3415 29
if(icause == 23)
{
const char *redirection_number = NULL;
const char *redirection_counter;
const char *redirect_info_ind;
const char *redirect_info_orig_areas;
const char *redirect_info_counter;
const char *redirect_info_reas;
redirect_info_ind = pbx_builtin_getvar_helper(ast, "SS7_REL_REDIRECT_INFO_IND");
redirect_info_orig_areas = pbx_builtin_getvar_helper(ast, "SS7_REL_REDIRECT_INFO_ORIG_REAS");
redirect_info_counter = pbx_builtin_getvar_helper(ast, "SS7_REL_REDIRECT_INFO_COUNTER");
redirect_info_reas = pbx_builtin_getvar_helper(ast, "SS7_REL_REDIRECT_INFO_REAS");
ast_log(LOG_WARNING, "Redirect Info Value : %s\n", redirect_info_ind);
ast_log(LOG_WARNING, "Redirect Info Orginal Value : %s\n", redirect_info_orig_areas);
ast_log(LOG_WARNING, "Redirect Info Counter Value : %s\n", redirect_info_counter);
ast_log(LOG_WARNING, "Redirect Info Reason Value : %s\n", redirect_info_reas);
isup_set_redirectiong_info_reason(p->ss7->ss7, p->ss7call, atoi(redirect_info_ind), atoi(redirect_info_orig_areas), atoi(redirect_info_counter), atoi(redirect_info_reas));
redirection_counter = pbx_builtin_getvar_helper(ast, "SS7_REL_REDIRECTION_COUNTER");
isup_set_redirection_counter(p->ss7->ss7, p->ss7call, atoi(redirection_counter));
redirection_number = pbx_builtin_getvar_helper(ast, "SS7_REL_REDIRECTION_NUMBER");
isup_set_redirection_number(p->ss7->ss7, p->ss7call, redirection_number);
}
else if(icause > 255)
{
a3416 2
}
LibSS7 Patches:-
isup.c :
d88 1
a88 1
static int rel_params[] = { ISUP_PARM_CAUSE, ISUP_PARM_REDIRECTION_INFO, ISUP_PARM_REDIRECTION_NUMBER, ISUP_PARM_REDIRECT_COUNTER, -1};
a800 2
//int oddeven = (parm[0] >> 7) & 0x1;
//int redirnum;
d804 1
a804 1
//redirnum = ((parm[2] & 0x60) >> 5);
a809 2
//int oddeven, datalen;
//int redirnum;
a811 1
//parm[2] = 0x80 | redirnum;
a817 1
//int redirnum;
d918 1
a1613 113
static FUNC_DUMP(redirection_reas_info_dump)
{
char *redirect_ind, *orig_redir_reas, *redir_reas;
switch (parm[0] & 0x7) {
case 0:
redirect_ind = "No Redirection (national use)";
break;
case 1:
redirect_ind = "Call rerouted (national use)";
break;
case 2:
redirect_ind = "Call rerouted, all rediection information presentation restricted (national use)";
break;
case 3:
redirect_ind = "Call diverted";
break;
case 4:
redirect_ind = "Call diverted, all redirection information presentation restricted";
break;
case 5:
redirect_ind = "Call rerouted, redirection number presentation restricted (national use)";
break;
case 6:
redirect_ind = "Call diversion, redirection number presentation restricted (national use)";
break;
case 7:
redirect_ind = "spare";
break;
default:
redirect_ind = "Unknown";
break;
}
ss7_message(ss7, "\t\t\tRedirecting indicator: %s (%d)\n", redirect_ind, parm[0] & 0x7);
switch ((parm[0] >> 4) & 0xf) {
case 0:
orig_redir_reas = "Unknown/not available";
break;
case 1:
orig_redir_reas = "User busy (national use)";
break;
case 2:
orig_redir_reas = "No reply (national use)";
break;
case 3:
orig_redir_reas = "Unconditional (national use)";
break;
default:
orig_redir_reas = "spare";
break;
}
ss7_message(ss7, "\t\t\tOriginal redirection reason: %s (%d)\n", orig_redir_reas, (parm[0] >> 4) & 0xf);
ss7_message(ss7, "\t\t\tRedirection counter: %d\n", parm[1] & 0x7);
switch ((parm[1] >> 4) & 0xf) {
case 0:
redir_reas = "Unknown/not available";
break;
case 1:
redir_reas = "User busy";
break;
case 2:
redir_reas = "No reply";
break;
case 3:
redir_reas = "Unconditional";
break;
case 4:
redir_reas = "Deflection during alerting";
break;
case 5:
redir_reas = "Deflection immediate response";
break;
case 6:
redir_reas = "Mobile subscriber not reachable";
break;
default:
redir_reas = "spare";
break;
}
ss7_message(ss7, "\t\t\tRedirecting reason: %s (%d)\n", redir_reas, (parm[1] >> 4) & 0xf);
return 2;
}
static FUNC_RECV(redirection_reas_info_receive)
{
c->redirect_info = 1;
c->redirect_info_ind = parm[0] & 0x7;
c->redirect_info_orig_reas = (parm[0] >> 4) & 0xf;
c->redirect_info_counter = parm[1] & 0x7;
c->redirect_info_reas = (parm[1] >> 4) & 0xf;
return 2;
}
static FUNC_SEND(redirection_reas_info_transmit)
{
if (!c->redirect_info)
return 0;
parm[0] = (c->redirect_info_ind & 0x7) | ((c->redirect_info_orig_reas << 4) & 0xf0);
parm[1] = (c->redirect_info_counter & 0x7) | ((c->redirect_info_reas << 4) & 0xf0);
return 2;
}
a2205 48
static FUNC_DUMP(redirection_number_dump)
{
int oddeven = (parm[0] >> 7) & 0x1;
char numbuf[64] = “”;
isup_get_number(numbuf, &parm[2], len - 2, oddeven);
ss7_message(ss7, "\t\t\tNature of address: %x\n", parm[0] & 0x7f);
ss7_message(ss7, "\t\t\tNI: %x\n", (parm[1] >> 7) & 0x1);
ss7_message(ss7, "\t\t\tNumbering plan: %x\n", (parm[1] >> 4) & 0x7);
ss7_message(ss7, "\t\t\tPresentation: %x\n", (parm[1] >> 2) & 0x3);
ss7_message(ss7, "\t\t\tScreening: %x\n", parm[1] & 0x3);
ss7_message(ss7, "\t\t\tRedirection Number : %s\n", numbuf);
return len;
}
static FUNC_RECV(redirection_number_receive)
{
int oddeven = (parm[0] >> 7) & 0x1;
isup_get_number(c->redirecting_num, &parm[2], len - 2, oddeven);
c->redirecting_num_nai = parm[0] & 0x7f; /* Nature of Address Indicator */
c->redirecting_num_presentation_ind = (parm[1] >> 2) & 0x3;
c->redirecting_num_screening_ind = parm[1] & 0x3;
return len;
}
static FUNC_SEND(redirection_number_transmit)
{
int oddeven, datalen;
if (!c->redirecting_num[0])
return 0;
isup_put_number(&parm[2], c->redirecting_num, &datalen, &oddeven);
parm[0] = (oddeven << 7) | c->redirecting_num_nai; /* Nature of Address Indicator */
parm[1] = (1 << 4) | /* Assume E.164 ISDN numbering plan, calling number complete */
((c->redirecting_num_presentation_ind & 0x3) << 2) |
(c->redirecting_num_screening_ind & 0x3);
return datalen + 2;
}
a2223 2
a2274 21
static FUNC_DUMP(redirection_counter_dump)
{
ss7_message(ss7, “\t\t\tRedirection count : %i\n”, parm[0] & 0x1f);
return 1;
}
static FUNC_RECV(redirection_counter_receive)
{
c->redirect_counter = parm[0] & 0x1f;
return 1;
}
static FUNC_SEND(redirection_counter_transmit)
{
if (!c->redirect_counter)
return 0;
parm[0] = c->redirect_counter & 0x1f;
return 1;
}
a2468 1
{ISUP_PARM_REDIRECTION_INFO_REASON, “Redirection Information Reason”, redirection_reas_info_dump, redirection_reas_info_receive, redirection_reas_info_transmit},
a2476 1
{ISUP_PARM_REDIRECTION_NUMBER, “Redirection Number”, redirection_number_dump, redirection_number_receive, redirection_number_transmit},
a2478 1
{ISUP_PARM_REDIRECTION_COUNTER, “Redirection Counter”, redirection_counter_dump, redirection_counter_receive, redirection_counter_transmit},
a2588 16
void isup_set_redirection_number(struct ss7 *ss7, struct isup_call *c, const char *redirecting_number)
{
if (redirecting_number && redirecting_number[0]) {
strncpy(c->redirecting_num, redirecting_number, sizeof(c->redirecting_num));
ss7_message(ss7, “\t\tRedirecting NUmber Value (%s):\n”, c->redirecting_num);
c->redirecting_num_nai = 3;
c->redirecting_num_presentation_ind = 1;
c->redirecting_num_screening_ind = 3;
ss7_message(ss7, “\t\tRedirecting Nature of Address (%d):\n”, c->redirecting_num_nai);
ss7_message(ss7, “\t\tRedirecting Presentation Value (%d):\n”, c->redirecting_num_presentation_ind);
ss7_message(ss7, “\t\tRedirecting Screening Value (%d):\n”, c->redirecting_num_screening_ind);
}
}
a2598 12
void isup_set_redirectiong_info_reason(struct ss7 *ss7, struct isup_call *c, unsigned char redirect_info_ind, unsigned char redirect_info_orig_reas,
unsigned char redirect_info_counter, unsigned char redirect_info_reas)
{
c->redirect_info = 1;
c->redirect_info_ind = redirect_info_ind;
c->redirect_info_orig_reas = redirect_info_orig_reas;
c->redirect_info_counter = redirect_info_counter;
c->redirect_info_reas = redirect_info_reas;
}
a2603 5
void isup_set_redirection_counter(struct ss7 *ss7, struct isup_call *c, unsigned char redirect_counter)
{
c->redirect_counter = redirect_counter;
}
a3421 1
//return isup_event_iam(ss7, c, opc);
a3438 2
//e->rel.redirnum = c->redirecting_num;
//strncpy(e->rel.redirnum, c->redirecting_num, sizeof(e->rel.redirnum));
a4340 2
//int redirnum;
a4346 1
//ss7_message(ss7, “\t\tSS7 Cause Value For REL %s:\n”, cause);
a4349 1
//redirnum = cause;
a4350 1
//ss7_message(ss7, “\t\tRidirect number on REL (%s):\n”, redirnum);
isup.h
a125 1
#define ISUP_PARM_REDIRECTION_INFO_REASON 0x14
a134 1
#define ISUP_PARM_REDIRECTION_NUMBER 0x0c
a136 1
#define ISUP_PARM_REDIRECTION_COUNTER 0x78
a221 3
unsigned char rel_redirection_nai;
unsigned char rel_redirecting_num_nai;
char rel_redirecting_num[ISUP_MAX_NUM];
a246 1
int redirnum;
libss7.h
a215 2
unsigned char rel_redirection_nai;
unsigned char rel_redirecting_num_nai;
a241 1
char redirnum[50];
a577 2
void isup_set_redirection_number(struct ss7 *ss7, struct isup_call *c, const char *redirecting_number);
a580 3
void isup_set_redirectiong_info_reason(struct ss7 *ss7, struct isup_call *c, unsigned char redirect_info_ind, unsigned char redirect_info_orig_reas,
unsigned char redirect_info_counter, unsigned char redirect_info_reas);
a582 2
void isup_set_redirection_counter(struct ss7 *ss7, struct isup_call *c, unsigned char redirect_counter);
After Adding Patches recompile the both libss7 and asterisk.
Set the following Variables in Asterisk Dialplan as below.
exten => s,1,Set(_SS7_LSPI_IDENT=ON)
exten => s,2,Set(_SS7_SEND_FAR=1)
exten => s,3,Set(_SS7_RLT_ON=YES)
exten => s,4,Set(_SS7_REL_REDIRECTION_NUMBER=XXXXXXXXXXXX)
exten => s,5,set(_SS7_REL_REDIRECTION_COUNTER=1)
exten => s,6,set(_SS7_REL_REDIRECT_INFO_IND=1)
exten => s,7,set(_SS7_REL_REDIRECT_INFO_ORIG_REAS=0)
exten => s,8,set(_SS7_REL_REDIRECT_INFO_COUNTER=1)
exten => s,9,set(_SS7_REL_REDIRECT_INFO_REAS=0)
exten => s,10,set(_SS7_CAUSE=23)
exten => s,11,WaitExten(1)
exten => s,12,Hangup(23)