Files
svc.ems/plat/sccp/src/sccp_gtt.c
2024-09-27 15:39:34 +08:00

418 lines
12 KiB
C

/****************************************************/
/*Title: gtt.c */
/*Descr: GTT Table Management */
/*Author: Liang Hanxi */
/*Create: 2002-2-19 */
/*Modify: 2003-4-30 */
/****************************************************/
#include "./include/sccp.h"
/*===========export================*/
int BuildRouteIndex ( );
u_short SelectRoute ( BYTE * pDigits, BYTE DigitsLen );
void TranslateGT ( SCCP_ADDR * addr, SCCP_ROUTE * pRoute );
/*===========import================*/
extern void spLog ( char *info );
extern int ParseLine ( char *str, char ( *row )[128], int maxrow );
extern int Digits2Array ( BYTE * pArray, BYTE * pDigits, int DigitsLen );
extern int Bcd2Array ( BYTE * pArray, BYTE * pBcd, int BcdLen );
extern int Array2Digits ( BYTE * pDigits, BYTE * pArray, int ArrayLen );
/* by simon at 23/9/26*/
extern int RelatedSSNNum;
extern RL_SSN RelatedSSN[SCCP_RLSSN_NUM];
extern SCOC_BUF ScocBuf;
extern SCCP_ROUTE RouteList[SCCP_ROUTE_NUM];
extern LOCAL_SSN LocalSSN[256];
extern SCCP_ROUTE RouteList[SCCP_ROUTE_NUM];
extern SCCP_OPT SCCP_Param;
/*===========private================*/
static int AddRoute ( BYTE * pStartDigits, BYTE * pEndDigits, BYTE DigitsLen, u_short index );
static int AddLargerNode ( SCCP_ROUTE_NODE * pNode, BYTE * pDigits, BYTE DigitsLen, u_short index );
static int AddLessNode ( SCCP_ROUTE_NODE * pNode, BYTE * pDigits, BYTE DigitsLen, u_short index );
static SCCP_ROUTE_NODE *NewNode ( );
static SCCP_ROUTE_NODE RouteNode[SCCP_ROUTE_NODE_NUM];
static SCCP_ROUTE_NODE *pHead = &RouteNode[0];
static u_short heap_index = 1, item_index = 0;
int BuildRouteIndex ( )
{
int i;
BYTE StartNum[32], EndNum[32], NumLen;
BYTE TTmod10, TTdiv10, TTdiv100;
BYTE field = 0;
TTmod10 = TTdiv10 = TTdiv100 = 0;
spLog ( "Build GTT Index..." );
memset ( &RouteNode[0], 0, SCCP_ROUTE_NODE_NUM * sizeof ( SCCP_ROUTE_NODE ) );
heap_index = 1;
item_index = 0;
for ( i = 2; i < 256; i++ )
{
field = 0;
if( LocalSSN[i].status[0] == 0 && LocalSSN[i].status[1] == 0 )
continue;
if( LocalSSN[i].msisdn_len < 1 )
continue;
// if (mtp3_ansiFlag(LocalSSN[i].NetID) != 1)/* ITU */
StartNum[field++] = NP_MSISDN;
// else
{ //ANSI
StartNum[field++] = TT_0;
StartNum[field++] = TT_1;
StartNum[field++] = TT_4;
}
NumLen = Bcd2Array ( StartNum + field, LocalSSN[i].msisdn, LocalSSN[i].msisdn_len % MAX_DIGITS ) + field;
if( NumLen < 2 || NumLen > 26 )
continue;
if( StartNum[NumLen - 1] > 9 )
NumLen--;
if( AddRoute ( StartNum, StartNum, NumLen, 1024 + i ) == 0 )
spLog ( "Error: Fail to add local node, resource limit..." );
}
field = 0;
for ( i = 0; i < SCCP_ROUTE_NUM; i++ )
{
if( RouteList[i].avail == 0 )
continue;
TTmod10 = RouteList[i].TT % 10;
TTdiv10 = ( RouteList[i].TT / 10 ) % 10;
TTdiv100 = RouteList[i].TT / 100;
field = 0;
if( RouteList[i].NP != 0 )
StartNum[field++] = RouteList[i].NP;
else
StartNum[field++] = NP_MSISDN;
if( RouteList[i].TT != 0 )
{
StartNum[field++] = TTdiv100;
StartNum[field++] = TTdiv10;
StartNum[field++] = TTmod10;
}
else
{
StartNum[field++] = TT_0;
StartNum[field++] = TT_1;
StartNum[field++] = TT_4;
}
field = 0;
if( RouteList[i].NP != 0 )
EndNum[field++] = RouteList[i].NP;
else
EndNum[field++] = NP_MSISDN;
if( RouteList[i].TT != 0 )
{
EndNum[field++] = TTdiv100;
EndNum[field++] = TTdiv10;
EndNum[field++] = TTmod10;
}
else
{
EndNum[field++] = TT_0;
EndNum[field++] = TT_1;
EndNum[field++] = TT_4;
}
NumLen = Bcd2Array ( StartNum + field, RouteList[i].StartDigits, RouteList[i].len % MAX_DIGITS ) + field;
if( NumLen < 2 || NumLen > 26 )
continue;
if( StartNum[NumLen - 1] > 9 )
NumLen--;
Bcd2Array ( EndNum + field, RouteList[i].EndDigits, RouteList[i].len );
if( AddRoute ( StartNum, EndNum, NumLen, i ) == 0 ){
spLog ( "Error: Fail to add route, resource limit..." );
break;
}
}
return 1;
}
u_short SelectRoute ( BYTE * pDigits, BYTE DigitsLen )
{
SCCP_ROUTE_NODE *pNode = pHead;
int i;
u_short result = 0xFFFF;
BYTE num;
for ( i = 0; i < DigitsLen; i++ )
{
num = pDigits[i];
if( pNode->psub[num] >= &RouteNode[0] && pNode->psub[num] <= &RouteNode[SCCP_ROUTE_NODE_NUM-1] )
{
pNode = pNode->psub[num];
if( pNode->nItem != 0xFFFF )
result = pNode->nItem;
}
else
{
return result;
}
}
return result;
}
int GetACNInfo ( SCCP_ADDR * pAddr, BYTE ** pAcnInfo )
{
DWORD spc;
u_short nRoute = 0xFFFF;
BYTE Num[MAX_DIGITS * 2], NumLen;
BYTE NetID;
BYTE field = 0;
if( pAddr->NP > 0 )
Num[field++] = pAddr->NP;
else
Num[field++] = NP_MSISDN;
if( pAddr->TT > 0 )
{
Num[field++] = pAddr->TT / 100;
Num[field++] = ( pAddr->TT / 10 ) % 10;
Num[field++] = pAddr->TT % 10;
}
else
{
Num[field++] = TT_0;
Num[field++] = TT_1;
Num[field++] = TT_4;
}
NumLen = pAddr->len % ( MAX_DIGITS * 2 );
Digits2Array ( Num + field, pAddr->GTAI, ( NumLen + 1 ) / 2 );
if( pAddr->GTI )
{
nRoute = SelectRoute ( Num, NumLen + field );
if( nRoute < SCCP_ROUTE_NUM )
{
if( pAddr->NetID > 3 )
NetID = RouteList[nRoute].NetID;
else
NetID = pAddr->NetID;
spc = RouteList[nRoute].DPC[0] * 0x10000 + RouteList[nRoute].DPC[1] * 0x100 + RouteList[nRoute].DPC[2];
}
else if( nRoute >= 1024 && nRoute < 1024 + 256 )
{
if( pAddr->NetID > 3 )
NetID = LocalSSN[nRoute - 1024].NetID % 4;
else
NetID = pAddr->NetID;
spc = SCCP_Param.spc[NetID];
}
else
return 0;
}
else
{
NetID = pAddr->NetID;
spc = pAddr->DPC;
}
*pAcnInfo = spc_to_acn ( NetID, spc );
if( *pAcnInfo == NULL )
return 0;
return 36;
}
void TranslateGT ( SCCP_ADDR * pAddr, SCCP_ROUTE * pRoute )
{
BYTE swap[MAX_DIGITS * 2], temp[MAX_DIGITS * 2];
BYTE ReplaceNum[MAX_DIGITS * 2], len;
BYTE ReplaceEnd;
len = Bcd2Array ( ReplaceNum, pRoute->ReplaceDigits, pRoute->replace_len % MAX_DIGITS );
Digits2Array ( temp, pAddr->GTAI, ( ( pAddr->len + 1 ) / 2 ) % MAX_DIGITS );
pAddr->NP = NP_GT;
if( pRoute->ReplaceStart > 1 )
{
memcpy ( swap, temp, pRoute->ReplaceStart - 1 );
}
memcpy ( swap + pRoute->ReplaceStart - 1, ReplaceNum, len );
ReplaceEnd = pRoute->ReplaceEnd;
if( pAddr->len < ReplaceEnd )
ReplaceEnd = pAddr->len;
memcpy ( swap + pRoute->ReplaceStart - 1 + len, temp + ReplaceEnd, ( pAddr->len - ReplaceEnd ) % 16 );
pAddr->len = pRoute->ReplaceStart - 1 + len + pAddr->len - ReplaceEnd;
pAddr->NP = pRoute->OutNP;
Array2Digits ( pAddr->GTAI, swap, pAddr->len );
}
int AddRoute ( BYTE * pStartDigits, BYTE * pEndDigits, BYTE DigitsLen, u_short index )
{
SCCP_ROUTE_NODE *pNode = pHead;
int i, j;
BYTE startNum, endNum;
for ( i = 0; i < DigitsLen; i++ )
{
startNum = pStartDigits[i] % 10;
endNum = pEndDigits[i] % 10;
if( startNum < endNum )
{
for ( j = startNum + 1; j < endNum; j++ )
{
if( pNode->psub[j] == NULL && ( pNode->psub[j] = NewNode ( ) ) == NULL )
return 0;
/* add by daniel on 2006-5-15 */
if( pNode->psub[j]->nItem == 0xFFFF ) //if this node has empty index then mark it with the new index, else do nothing
/* add by daniel on 2006-5-15 */
pNode->psub[j]->nItem = index;
}
if( pNode->psub[startNum] == NULL && ( pNode->psub[startNum] = NewNode ( ) ) == NULL )
return 0;
if( pNode->psub[endNum] == NULL && ( pNode->psub[endNum] = NewNode ( ) ) == NULL )
return 0;
if( AddLargerNode ( pNode->psub[startNum], pStartDigits + i + 1, DigitsLen - i - 1, index ) == 0 )
return 0;
if( AddLessNode ( pNode->psub[endNum], pEndDigits + i + 1, DigitsLen - i - 1, index ) == 0 )
return 0;
return 1;
}
else if( startNum == endNum )
{
if( pNode->psub[startNum] == NULL && ( pNode->psub[startNum] = NewNode ( ) ) == NULL )
{
//send alarm here
pNode = NULL;
return 0;
}
pNode = pNode->psub[startNum];
if( i >= DigitsLen - 1 )
{
pNode->nItem = index;
return 1;
}
continue;
}
else if( startNum > endNum )
return 0;
}
return 1;
}
int AddLargerNode ( SCCP_ROUTE_NODE * pNode, BYTE * pDigits, BYTE DigitsLen, u_short index )
{
int i, j;
BYTE startNum;
for ( i = 0; i < DigitsLen; i++ )
{
startNum = pDigits[i] % 10;
for ( j = startNum + 1; j <= 9; j++ )
{
if( pNode->psub[j] == NULL && ( pNode->psub[j] = NewNode ( ) ) == NULL )
return 0;
/* add by daniel on 2006-5-15 */
if( pNode->psub[j]->nItem == 0xFFFF ) //if this node has empty index then mark it with the new index, else do nothing
/* add by daniel on 2006-5-15 */
pNode->psub[j]->nItem = index;
}
if( pNode->psub[startNum] == NULL && ( pNode->psub[startNum] = NewNode ( ) ) == NULL )
return 0;
pNode = pNode->psub[startNum];
}
pNode->nItem = index;
return 1;
}
int AddLessNode ( SCCP_ROUTE_NODE * pNode, BYTE * pDigits, BYTE DigitsLen, u_short index )
{
int i, j;
BYTE endNum;
for ( i = 0; i < DigitsLen; i++ )
{
endNum = pDigits[i] % 10;
for ( j = 0; j < endNum; j++ )
{
if( pNode->psub[j] == NULL && ( pNode->psub[j] = NewNode ( ) ) == NULL )
return 0;
/* add by daniel on 2006-5-15 */
if( pNode->psub[j]->nItem == 0xFFFF ) //if this node has empty index then mark it with the new index, else do nothing
/* add by daniel on 2006-5-15 */
pNode->psub[j]->nItem = index;
}
if( pNode->psub[endNum] == NULL && ( pNode->psub[endNum] = NewNode ( ) ) == NULL )
return 0;
pNode = pNode->psub[endNum];
}
pNode->nItem = index;
return 1;
}
SCCP_ROUTE_NODE *NewNode ( )
{
if( heap_index >= SCCP_ROUTE_NODE_NUM ){
spLog ( "Fatal Error: Fail to add GT node, no resource" );
return NULL;
}
RouteNode[heap_index].nItem = 0xFFFF;
return &RouteNode[heap_index++];
}
/*
*Purpose: check whether a GT is in the SCCP GT table
*Param: np: Number Plan
* tt: Translation Type
* gt: Global title
* gt_len: length of gt
*Return: 0 - the GT is not in SCCP GTT
* 1 - the GT is in SCCP GTT
*/
int CheckGT(BYTE np, BYTE tt, BYTE *gt, BYTE gt_len)
{
BYTE Num[32], NumLen;
BYTE field = 0;
int nRoute;
assert(gt_len < 32);
assert(gt != NULL);
if( np > 0 )
Num[field++] = np;
else
Num[field++] = NP_MSISDN;
if( tt > 0 )
{
Num[field++] = tt / 100;
Num[field++] = ( tt / 10 ) % 10;
Num[field++] = tt % 10;
}
else
{
Num[field++] = TT_0;
Num[field++] = TT_1;
Num[field++] = TT_4;
}
NumLen = gt_len % ( MAX_DIGITS * 2 );
Digits2Array ( Num + field, gt, ( NumLen + 1 ) / 2 );
nRoute = SelectRoute ( Num, NumLen + field );
if( nRoute < SCCP_ROUTE_NUM )
return 1;
else
return 0;
}