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

561 lines
16 KiB
C

/************************************************************/
/*Title: scmg.c */
/*Descr: SCCP Management */
/*Author: Liang Hanxi */
/*Create: 2002-2-19 */
/*Modify: 2002-5-7 */
/************************************************************/
#include "./include/sccp.h"
/*===========export================*/
void localssn_timer ( );
void sst_timer ( );
int sclc2scmg ( Intra_Msg * intramsg );
BOOL CheckAvail ( SCCP_ADDR * addr );
/*===========import================*/
extern int scrc_route ( Intra_Msg * pIntraMsg, BOOL ForceAnsi );
extern int send_msg ( Intra_Msg * pIntraMsg, BYTE ansi_flag );
extern void sccp_sethb ( );
extern int CollectLocalInfo ( );
extern int AddToIpList ( DWORD ip, BYTE ssn );
extern void snmpLogInfo ( char *logInfo );
extern void spLogDebug ( DWORD mask, const char *fmt, ... );
/*===========private================*/
static BYTE ssn_status ( int spc, BYTE ssn, BYTE NetID );
void spac ( int spc, BYTE NetID );
void sppc ( int spc, BYTE NetID );
void spcc ( int spc, BYTE NetID );
static void ssac ( int spc, BYTE ssn, BYTE NetID, BOOL relay );
static void sscc ( int spc, BYTE ssn, BYTE NetID );
static void sspc ( int spc, BYTE ssn, BYTE NetID, BOOL relay );
static void lcst ( int spc, BYTE ssn, BYTE ntype, BYTE NetID );
static void bcst ( BYTE ssn, BYTE ntype );
static void bcst_relay ( int spc, BYTE ssn, BYTE ntype, BYTE NetID );
static int build_scmgmsg ( BYTE * intramsg, BYTE type, int spc, BYTE ssn, BYTE NetID );
static int parse_scmgmsg ( BYTE * data, BYTE * type, int *spc, BYTE * ssn, BYTE NetID );
/* by simon at 23/9/25 */
extern DWORD ExistIP[64];
extern DWORD ExistIPNum;
extern SCOC_BUF ScocBuf;
extern LOCAL_SSN LocalSSN[256];
extern u8 ExistSSN[64];
extern u8 ExistSSNNum;
extern struct _dpc2sls
{
int dpc;
u8 sls;
} dpc2sls[256]; // used for sequence control, add by Roy Jiang, 2007-09-17
extern SCCP_OPT SCCP_Param;
extern u8 MNP_Flag[2];
extern SCCP_ROUTE RouteList[SCCP_ROUTE_NUM];
extern int RelatedSSNNum;
extern RL_SSN RelatedSSN[SCCP_RLSSN_NUM];
extern int RelatedSPCNum;
extern RL_SPC RelatedSPC[SCCP_RLSPC_NUM];
extern GTTATT_OMC GTTAttribute[SCCP_ROUTE_NUM];
extern SCCP_CSTA SccpCsta[96];
extern DWORD SccpCstaInd;
extern SCCP_Capture_Buf SCCPCapBuf;
void localssn_timer ( ) //called per 1s
{
int i;
LOCAL_SSN *pSSN;
for ( i = 0; i < ExistSSNNum; i++ )
{
pSSN = &LocalSSN[ExistSSN[i]];
if( pSSN->status[0] == ST_Enable && pSSN->local != 1 && pSSN->timeout[0]-- <= 0 )
pSSN->status[0] = ST_Disable;
if( pSSN->status[1] == ST_Enable && pSSN->local != 2 && pSSN->timeout[1]-- <= 0 )
pSSN->status[1] = ST_Disable;
}
}
int sclc2scmg ( Intra_Msg * intramsg )
{
BYTE *pmsg;
BYTE ntype, ssn;
int spc;
BOOL relay = 0;
intramsg->msgsource = FROM_SCMG;
pmsg = intramsg->data;
parse_scmgmsg ( intramsg->data, &ntype, &spc, &ssn, intramsg->NetID );
snmpLogInfo ( "sclc2scmg (): start..." );
spLogDebug ( SCCPDB_SCMG, "Receive %s Message.ssn=%d,src_spc=%X", ntype == SSA_MSG ? "SSA" : ( ntype == SSP_MSG ? "SSP" : ( ntype == SST_MSG ? "SST" : "SCMG" ) ), ssn, spc );
switch ( ntype )
{
case SSA_MSG:
//to enable subsystem
SccpCsta[SccpCstaInd].avail[11]++;
if( intramsg->OPC != SCCP_Param.spc[intramsg->NetID] && intramsg->CGA.DPC != SCCP_Param.spc[intramsg->NetID] )
{
lcst ( spc, ssn, SSA_MSG, intramsg->NetID );
if( spc == intramsg->CGA.DPC )
relay = 1;
}
ssac ( spc, ssn, intramsg->NetID, relay );
break;
case SSC_MSG:
SccpCsta[SccpCstaInd].avail[7]++;
sscc ( spc, ssn, intramsg->NetID );
break;
case SSP_MSG:
SccpCsta[SccpCstaInd].avail[10]++;
if( intramsg->OPC != SCCP_Param.spc[intramsg->NetID] && intramsg->CGA.DPC != SCCP_Param.spc[intramsg->NetID] )
{
lcst ( spc, ssn, SSP_MSG, intramsg->NetID );
if( spc == intramsg->CGA.DPC )
relay = 1;
}
sspc ( spc, ssn, intramsg->NetID, relay );
break;
case SST_MSG:
if( LocalSSN[ssn].status[0] == ST_Enable || LocalSSN[ssn].status[1] == ST_Enable )
pmsg[0] = SSA_MSG;
else
return 1;
memcpy ( &intramsg->CDA, &intramsg->CGA, sizeof ( SCCP_ADDR ) );
intramsg->CGA.DPC = SCCP_Param.spc[intramsg->NetID];
intramsg->CGA.GTI = 0;
intramsg->CGA.SSN = 1;
intramsg->CGA.RI = RI_SSN;
intramsg->CGA.len = 0;
spLogDebug ( SCCPDB_SCMG, "Send %s Message.ssn=%d,dst_spc=%X", ( pmsg[0] == SSA_MSG ) ? "SSA" : ( ( pmsg[0] == SSP_MSG ) ? "SSP" : "SSC" ), ssn, intramsg->CDA.DPC );
send_msg ( intramsg, mtp3_ansiFlag ( intramsg->NetID ) );
break;
case SOR_MSG:
//to send SOG
pmsg[0] = SOG_MSG; //to send SOG
memcpy ( &intramsg->CDA, &intramsg->CGA, sizeof ( SCCP_ADDR ) );
scrc_route ( intramsg, 0 );
break;
case SOG_MSG:
//to disable local subsystem
break;
}
snmpLogInfo ( "sclc2scmg (): end..." );
return 1;
}
BOOL CheckAvail ( SCCP_ADDR * addr )
{
BYTE status;
status = ssn_status ( addr->DPC, addr->SSN, addr->NetID );
if( status == ST_Disable )
{
spLogDebug ( SCCPDB_ERR, "<009>Subsystem Failure.NetID=%d,SPC=%x,SSN=%d", addr->NetID, addr->DPC, addr->SSN );
SccpCsta[SccpCstaInd].error[4]++;
return 0;
}
else if( status == ST_Congest )
{
spLogDebug ( SCCPDB_ERR, "<010>Subsystem Congest.NetID=%d,SPC=%x,SSN=%d", addr->NetID, addr->DPC, addr->SSN );
SccpCsta[SccpCstaInd].error[5]++;
return 0;
}
//else if(sccp_status(addr->DPC,addr->NetID)==ST_Disable)
// return 0;
else
return 1;
}
BYTE ssn_status ( int spc, BYTE ssn, BYTE NetID )
//related subsystem
{
int i;
for ( i = 0; i < RelatedSSNNum; i++ )
{
if( RelatedSSN[i].status == 0 )
continue;
if( RelatedSSN[i].DPC != spc || RelatedSSN[i].SSN != ssn || RelatedSSN[i].NetID != NetID )
continue;
return RelatedSSN[i].status;
}
return ST_Enable;
}
/////////////////////////
/*SPAC Module----------> */
/////////////////////////
void spac ( int spc, BYTE NetID )
{
int i, j;
for ( i = 0; i < RelatedSPCNum; i++ )
{
if( spc == RelatedSPC[i].DPC && NetID == RelatedSPC[i].NetID )
{
RelatedSPC[i].status = ST_Enable;
for ( j = 0; j < RelatedSSNNum; j++ )
{
if( RelatedSSN[j].status == 0 )
continue;
if( spc == RelatedSSN[j].DPC && NetID == RelatedSSN[j].NetID )
{
if( RelatedSPC[i].status == ST_Disable )
RelatedSSN[j].SST = 1;
RelatedSSN[j].status = ST_Enable;
}
}
}
}
}
/////////////////////////
/*SPPC Module----------> */
/////////////////////////
void sppc ( int spc, BYTE NetID )
{
int i, j;
for ( i = 0; i < RelatedSPCNum; i++ )
{
if( spc == RelatedSPC[i].DPC && NetID == RelatedSPC[i].NetID )
{
RelatedSPC[i].status = ST_Disable;
for ( j = 0; j < RelatedSSNNum; j++ )
{
if( RelatedSSN[j].status == 0 )
continue;
if( spc == RelatedSSN[j].DPC && NetID == RelatedSSN[j].NetID )
{
RelatedSSN[j].SST = 0;
RelatedSSN[j].status = ST_Disable;
}
}
}
}
}
/////////////////////////
/*SPCC Module----------> */
/////////////////////////
void spcc ( int spc, BYTE NetID )
{
int i;
for ( i = 0; i < RelatedSPCNum; i++ )
{
if( spc == RelatedSSN[i].DPC && NetID == RelatedSSN[i].NetID )
RelatedSSN[i].status = ST_Congest;
}
}
/////////////////////////
/*SSAC Module----------> */
/////////////////////////
int register_ssn ( BYTE ssn, BYTE usertype ) //enable local subsystem
{
BYTE localindex = LocalSSN[ssn].local % 3;
LocalSSN[ssn].RegFlag = 1;
if( localindex > 0 )
{
CollectLocalInfo ( );
LocalSSN[ssn].status[localindex - 1] = ST_Enable;
}
else
{
printf ( "Subsystem %d not equiped.check your GTT Table.\n", ssn );
return 0;
}
if( usertype == 3 )
SCCP_Param.CO_SSN = ssn;
SccpCsta[SccpCstaInd].avail[8]++;
LocalSSN[ssn].nbuf = usertype % 4;
if( LocalSSN[ssn].nbuf == 3 )
SCCP_Param.CO_SSN = ssn;
bcst ( ssn, SSA_MSG );
return 1;
}
void ssac ( int spc, BYTE ssn, BYTE NetID, BOOL relay ) //enable remote subsystem
{
int i;
for ( i = 0; i < RelatedSSNNum; i++ )
{
if( RelatedSSN[i].status == 0 )
continue;
if( RelatedSSN[i].DPC != spc || RelatedSSN[i].SSN != ssn || RelatedSSN[i].NetID != NetID )
continue;
if( RelatedSSN[i].status == ST_Disable && relay ) //Disable->Enable
bcst_relay ( spc, ssn, SSA_MSG, NetID );
RelatedSSN[i].SST = 0;
RelatedSSN[i].status = ST_Enable;
}
}
void sscc ( int spc, BYTE ssn, BYTE NetID ) //enable remote subsystem
{
int i;
for ( i = 0; i < RelatedSSNNum; i++ )
{
if( RelatedSSN[i].status == 0 )
continue;
if( RelatedSSN[i].DPC != spc || RelatedSSN[i].SSN != ssn || RelatedSSN[i].NetID != NetID )
continue;
RelatedSSN[i].status = ST_Congest;
}
}
/////////////////////////
/*SSPC Module----------> */
/////////////////////////
int stop_ssn ( BYTE ssn ) //disable local subsystem
{
BYTE localindex = LocalSSN[ssn].local % 3;
int i;
LocalSSN[ssn].RegFlag = 0;
spLogDebug ( SCCPDB_SCMG, "Disable local subsystem. ssn=%d", ssn );
if( localindex > 0 )
{
CollectLocalInfo ( );
/* add by daniel on 2005-9-15 */
for ( i = 0; i <= 1; i++ )
{
if( SCCP_Param.OMCIP[i] > 0 )
AddToIpList ( SCCP_Param.OMCIP[i], ssn );
}
/* add by daniel on 2005-9-15 */
LocalSSN[ssn].status[localindex - 1] = ST_Disable;
}
else
return -1;
sccp_sethb ( );
SccpCsta[SccpCstaInd].avail[9]++;
bcst ( ssn, SSP_MSG );
return 1;
}
void sspc ( int spc, BYTE ssn, BYTE NetID, BOOL relay ) //disable remote subsystem
{
int i;
for ( i = 0; i < RelatedSSNNum; i++ )
{
if( RelatedSSN[i].status == 0 )
continue;
if( RelatedSSN[i].DPC != spc || RelatedSSN[i].SSN != ssn || RelatedSSN[i].NetID != NetID )
continue;
if( RelatedSSN[i].status == ST_Enable ) //Enable->Disable
{
RelatedSSN[i].timeout = T_sst;
RelatedSSN[i].SST = 1;
if( relay )
bcst_relay ( spc, ssn, SSP_MSG, NetID );
}
RelatedSSN[i].status = ST_Disable;
}
}
/////////////////////////
/*SSTC Module----------> */
/////////////////////////
void sst_timer ( )
{
Intra_Msg outmsg;
RL_SSN *pSSN;
int i;
for ( i = 0; i < RelatedSSNNum; i++ )
{
pSSN = &RelatedSSN[i];
if( !pSSN->SST )
continue;
if( pSSN->timeout-- > 0 )
continue;
if( pSSN->DPC == SCCP_Param.spc[pSSN->NetID] )
continue;
outmsg.msgtype = UDT_MSG;
outmsg.msgsource = FROM_SCMG;
outmsg.CGA.DPC = SCCP_Param.spc[pSSN->NetID];
outmsg.CGA.SSN = 1;
outmsg.CGA.GTI = 0;
outmsg.CGA.RI = RI_SSN;
outmsg.CGA.len = 0;
outmsg.CDA.DPC = pSSN->DPC;
outmsg.CDA.SSN = 1; //SCMG
outmsg.CDA.GTI = 0; //No GT
outmsg.CDA.RI = 1;
outmsg.CDA.len = 0;
outmsg.NetID = pSSN->NetID;
outmsg.CDA.ip = INADDR_NONE;
outmsg.msglen = build_scmgmsg ( outmsg.data, SST_MSG, pSSN->DPC, pSSN->SSN, pSSN->NetID );
spLogDebug ( SCCPDB_SCMG, "SST spc=%X,ssn=%d", pSSN->DPC, pSSN->SSN );
send_msg ( &outmsg, mtp3_ansiFlag ( pSSN->NetID ) );
pSSN->timeout = T_sst;
}
}
/////////////////////////
/*LCST Module----------> */
/////////////////////////
void lcst ( int spc, BYTE ssn, BYTE ntype, BYTE NetID )
{
Intra_Msg outmsg;
int i;
spLogDebug ( SCCPDB_SCMG, "Start Local Broatcast.spc=%X,ssn=%d,ntype=%d", spc, ssn, ntype );
outmsg.msgtype = UDT_MSG;
outmsg.msgsource = FROM_SCMG;
outmsg.CGA.SSN = 1;
outmsg.CGA.GTI = 0;
outmsg.CGA.len = 0;
outmsg.CGA.RI = 1;
outmsg.CGA.DPC = SCCP_Param.spc[NetID];
outmsg.CDA.GTI = 0;
outmsg.NetID = outmsg.CDA.NetID = outmsg.CGA.NetID = NetID;
outmsg.CDA.DPC = SCCP_Param.spc[NetID];
outmsg.CDA.SSN = 1;
outmsg.CDA.RI = 1;
outmsg.CDA.len = 0;
outmsg.msglen = build_scmgmsg ( outmsg.data, ntype, spc, ssn, NetID );
for ( i = 2; i < 256; i++ )
{
if( LocalSSN[i].status[0] > 0 && LocalSSN[i].local != 1 )
{
outmsg.CDA.ip = LocalSSN[i].ip[0];
send_msg ( &outmsg, mtp3_ansiFlag ( NetID ) );
}
if( LocalSSN[i].status[1] > 0 && LocalSSN[i].local != 2 )
{
outmsg.CDA.ip = LocalSSN[i].ip[1];
send_msg ( &outmsg, mtp3_ansiFlag ( NetID ) );
}
}
}
/////////////////////////
/*BCST Module----------> */
/////////////////////////
void bcst ( BYTE ssn, BYTE ntype )
{
Intra_Msg outmsg;
int i;
spLogDebug ( SCCPDB_SCMG, "Start Remote Broadcase ssn=%d,ntype=%d", ssn, ntype );
outmsg.msgtype = UDT_MSG;
outmsg.msgsource = FROM_SCMG;
outmsg.CDA.GTI = 0;
for ( i = 0; i < RelatedSPCNum; i++ )
{
if( RelatedSPC[i].status != ST_Enable )
continue;
outmsg.CGA.SSN = 1;
outmsg.CGA.GTI = 0;
outmsg.CGA.len = 0;
outmsg.CGA.RI = 1;
outmsg.CGA.DPC = SCCP_Param.spc[RelatedSPC[i].NetID];
outmsg.CDA.ip = INADDR_NONE;
outmsg.CDA.DPC = RelatedSPC[i].DPC;
outmsg.CDA.SSN = 1;
outmsg.CDA.RI = 1;
outmsg.CDA.len = 0;
outmsg.NetID = outmsg.CDA.NetID = outmsg.CGA.NetID = RelatedSPC[i].NetID;
outmsg.msglen = build_scmgmsg ( outmsg.data, ntype, SCCP_Param.spc[outmsg.NetID], ssn, outmsg.NetID );
send_msg ( &outmsg, mtp3_ansiFlag ( outmsg.NetID ) );
}
}
void bcst_relay ( int spc, BYTE ssn, BYTE ntype, BYTE NetID )
{
Intra_Msg outmsg;
int i;
spLogDebug ( SCCPDB_SCMG, "relay Broadcase spc:%X,ssn%d,ntype:%d", spc, ssn, ntype );
outmsg.msgtype = UDT_MSG;
outmsg.msgsource = FROM_SCMG;
outmsg.CDA.GTI = 0;
outmsg.CGA.SSN = 1;
outmsg.CGA.GTI = 0;
outmsg.CGA.len = 0;
outmsg.CGA.RI = 1;
outmsg.NetID = outmsg.CGA.NetID = outmsg.CDA.NetID = NetID;
for ( i = 0; i < RelatedSPCNum; i++ )
{
if( NetID != RelatedSPC[i].NetID )
return;
if( RelatedSPC[i].status == ST_Disable || spc == RelatedSPC[i].DPC )
continue;
outmsg.CGA.DPC = SCCP_Param.spc[RelatedSPC[i].NetID];
outmsg.CDA.ip = INADDR_NONE;
outmsg.CDA.DPC = RelatedSPC[i].DPC;
outmsg.CDA.SSN = 1;
outmsg.CDA.RI = 1;
outmsg.CDA.len = 0;
outmsg.msglen = build_scmgmsg ( outmsg.data, ntype, spc, ssn, NetID );
send_msg ( &outmsg, mtp3_ansiFlag ( NetID ) );
}
}
int build_scmgmsg ( BYTE * data, BYTE type, int spc, BYTE ssn, BYTE NetID )
{
int pos = 0;
data[pos++] = type;
data[pos++] = ssn;
memcpy ( data + pos, ( BYTE * ) & spc, SCCP_Param.spclen[NetID] );
pos += SCCP_Param.spclen[NetID];
data[pos++] = 0;
if( type == SSC_MSG )
data[pos++] = 0;
return pos;
}
int parse_scmgmsg ( BYTE * data, BYTE * type, int *spc, BYTE * ssn, BYTE NetID )
{
int pos = 0;
*type = data[pos++];
*ssn = data[pos++];
*spc = 0;
memcpy ( ( BYTE * ) spc, data + pos, SCCP_Param.spclen[NetID] );
pos += SCCP_Param.spclen[NetID];
return 1;
}