616 lines
20 KiB
C
616 lines
20 KiB
C
|
|
/*******************************************/
|
|
/*Title: sclc.c */
|
|
/*Descr: SCCP Connectionless Control */
|
|
/*Author: Liang Hanxi */
|
|
/*Create: 2002-2-19 */
|
|
|
|
/*******************************************/
|
|
|
|
#include "./include/sccp.h"
|
|
|
|
/*===========export================*/
|
|
int scrc2sclc ( Intra_Msg * pIntraMsg );
|
|
int sclc_rf ( Intra_Msg * pIntraMsg );
|
|
/* by simon at 23/9/26 */
|
|
extern SCCP_CSTA SccpCsta[96];
|
|
extern DWORD SccpCstaInd;
|
|
extern LOCAL_SSN LocalSSN[256];
|
|
SCCP_SegMsgBuf sccp_segmsgbuf[MAX_SEGMSG_BUF];
|
|
extern struct sccp_msg_statistic
|
|
{
|
|
DWORD msg_mtp_scoc;
|
|
DWORD msg_scoc_up;
|
|
DWORD mnp_send;
|
|
DWORD mnp_route;
|
|
} sccpmsg_st;
|
|
extern SCCP_Capture_Buf SCCPCapBuf;
|
|
extern LOCAL_SSN LocalSSN[256];
|
|
extern int RelatedSSNNum;
|
|
extern RL_SSN RelatedSSN[SCCP_RLSSN_NUM];
|
|
extern SCOC_BUF ScocBuf;
|
|
extern SCCP_ROUTE RouteList[SCCP_ROUTE_NUM];
|
|
extern SCCP_OPT SCCP_Param;
|
|
extern u8 MNP_Flag[2];
|
|
|
|
/*===========import================*/
|
|
extern int sclc2scmg ( Intra_Msg * intramsg ); //scmg.c
|
|
extern int scrc_route ( Intra_Msg * pIntraMsg, BOOL ForceAnsi ); //scrc.c
|
|
extern int scrc_mnp_route ( Intra_Msg * pIntraMsg, BOOL ForceAnsi ); //scrc.c
|
|
extern int send_msg ( Intra_Msg * pIntraMsg ); //scrc.c
|
|
extern void spLogDebug ( DWORD mask, const char *fmt, ... );
|
|
extern void spShowBCD(DWORD mask, BYTE *buf, int len);
|
|
extern void spShowMsg(DWORD mask, const char *pDesc, Intra_Msg *pIntraMsg);
|
|
extern void spLog ( char *info );
|
|
|
|
static SCLC_BUF SCLC_OutBuf;
|
|
static SCLC_BUF SCLC_InBuf[MAX_SCLC_BUF];
|
|
|
|
/* buffer changed from 3 to 4, Pierre , 11-07 */
|
|
|
|
int RecvXUDTMsg ( Intra_Msg * pIntraMsg, BYTE nbuf );
|
|
int CheckSegUnID ( Intra_Msg * pIntraMsg );
|
|
int RsmRegMsg ( SCLC_MSG * pmsg, SCCP_SegMsgBuf * pSegMsgbuf, Intra_Msg * pIntraMsg );
|
|
extern void spLogSeg ( SCCP_SegMsgBuf * pSegMsgbuf );
|
|
|
|
int scrc2sclc ( Intra_Msg * pIntraMsg )
|
|
{
|
|
SCLC_MSG *pmsg;
|
|
short writesub, readsub;
|
|
BYTE nbuf;
|
|
|
|
SccpCsta[SccpCstaInd].utilization[4 - 3]++;
|
|
if( pIntraMsg->msgMNP )
|
|
{
|
|
nbuf = 1;
|
|
sccpmsg_st.mnp_route++;
|
|
if(pIntraMsg->msgsource == FROM_MTP)
|
|
{
|
|
pIntraMsg->SLS = LocalSSN[pIntraMsg->CDA.SSN].local+1;
|
|
}
|
|
} /* added by pierre for MNP , 2005-11-07 */
|
|
else
|
|
{
|
|
nbuf = LocalSSN[pIntraMsg->CDA.SSN].nbuf % 4;
|
|
}
|
|
|
|
switch ( pIntraMsg->msgtype )
|
|
{
|
|
case UDT_MSG:
|
|
break;
|
|
case XUDT_MSG:
|
|
switch ( RecvXUDTMsg ( pIntraMsg, nbuf ) )
|
|
{
|
|
case 0:
|
|
break;
|
|
case 1:
|
|
break;
|
|
case 2:
|
|
break;
|
|
case 3:
|
|
break;
|
|
|
|
}
|
|
return 0;
|
|
case LUDT_MSG:
|
|
spLogDebug ( SCCPDB_UDT | SCCPDB_ERR, "<005>LUDT/XUDT message is not supported" );
|
|
return 0;
|
|
case UDTS_MSG:
|
|
break;
|
|
case XUDTS_MSG:
|
|
case LUDTS_MSG:
|
|
spLogDebug ( SCCPDB_UDT | SCCPDB_ERR, "<005>LUDTS/XUDTS message is not supported" );
|
|
return 0;
|
|
}
|
|
if( pIntraMsg->CDA.SSN == SSN_SCMG )
|
|
return sclc2scmg ( pIntraMsg );
|
|
else
|
|
{
|
|
writesub = SCLC_InBuf[nbuf].writesub;
|
|
readsub = SCLC_InBuf[nbuf].readsub;
|
|
pmsg = &SCLC_InBuf[nbuf].msglist[writesub];
|
|
|
|
pmsg->msglen = pIntraMsg->msglen % SCCP_MSG_MAXLEN;
|
|
memcpy ( pmsg->msg, pIntraMsg->data, pmsg->msglen );
|
|
memcpy ( &( pmsg->src_addr ), &( pIntraMsg->CGA ), sizeof ( SCCP_ADDR ) );
|
|
memcpy ( &( pmsg->dst_addr ), &( pIntraMsg->CDA ), sizeof ( SCCP_ADDR ) );
|
|
pmsg->sls = pIntraMsg->SLS;
|
|
|
|
if( ( SCLC_InBuf[nbuf].writesub + 1 ) == SCLC_InBuf[nbuf].readsub )
|
|
spShowMsg ( SCCPDB_UDT, "USER <== SCCP: buf overflow!!!!!!!", pIntraMsg );
|
|
|
|
SCLC_InBuf[nbuf].writesub = ( writesub + 1 ) % SS_MSG_NUM;
|
|
if( SCLC_InBuf[nbuf].writesub == readsub )
|
|
SCLC_InBuf[nbuf].readsub = ( readsub + 1 ) % SS_MSG_NUM;
|
|
|
|
if (pIntraMsg->msgtype == UDTS_MSG)
|
|
{
|
|
pmsg->primitive = N_NOTICE_IND;
|
|
spShowMsg ( SCCPDB_UDT, "USER <== SCCP: N-NOTICE", pIntraMsg );
|
|
}
|
|
else
|
|
{
|
|
pmsg->primitive = N_UNITDATA_IND;
|
|
spShowMsg ( SCCPDB_UDT, "USER <== SCCP: UDT Message", pIntraMsg );
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int sclc_rf ( Intra_Msg * pIntraMsg )
|
|
{
|
|
SCCP_ADDR swapaddr;
|
|
|
|
spShowMsg ( SCCPDB_UDT | SCCPDB_ERR, "<006>Route Failure", pIntraMsg );
|
|
switch ( pIntraMsg->msgtype )
|
|
{
|
|
case UDT_MSG:
|
|
if( pIntraMsg->msgsource == FROM_MTP || pIntraMsg->msgsource == FROM_SCLC )
|
|
{
|
|
memcpy ( &swapaddr, &( pIntraMsg->CDA ), sizeof ( SCCP_ADDR ) );
|
|
memcpy ( &( pIntraMsg->CDA ), &( pIntraMsg->CGA ), sizeof ( SCCP_ADDR ) );
|
|
memcpy ( &( pIntraMsg->CGA ), &swapaddr, sizeof ( SCCP_ADDR ) );
|
|
pIntraMsg->CDA.ip = 0xFFFFFFFF;
|
|
if( pIntraMsg->CDA.RI == RI_SSN )
|
|
{
|
|
if( pIntraMsg->CDA.DPC == 0 )
|
|
pIntraMsg->CDA.DPC = pIntraMsg->CGA.DPC;
|
|
}
|
|
pIntraMsg->msgsource = FROM_SCLC;
|
|
pIntraMsg->msgtype = UDTS_MSG;
|
|
return scrc_route ( pIntraMsg, 0 );
|
|
}
|
|
break;
|
|
case XUDT_MSG:
|
|
case LUDT_MSG:
|
|
//unsupported now
|
|
break;
|
|
case UDTS_MSG:
|
|
break;
|
|
case XUDTS_MSG:
|
|
case LUDTS_MSG:
|
|
//unsupported now
|
|
break;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
int scmg2sclc ( Intra_Msg * pIntraMsg )
|
|
{
|
|
return scrc_route ( pIntraMsg, 0 );
|
|
}
|
|
|
|
/******************************************************************/
|
|
|
|
/*================== User Interface-----> ================*/
|
|
|
|
/******************************************************************/
|
|
int sclc_send ( SCLC_MSG * pmsg )
|
|
{
|
|
if( pmsg->msglen > 256 )
|
|
{
|
|
spLogDebug ( SCCPDB_ERR | SCCPDB_UDT, "<007>User ==> SCCP: Message's Length exceed 256" );
|
|
spShowBCD ( SCCPDB_ERR, pmsg->msg, pmsg->msglen % 256 );
|
|
return 0;
|
|
}
|
|
SccpCsta[SccpCstaInd].utilization[0]++;
|
|
|
|
memcpy ( &SCLC_OutBuf.msglist[SCLC_OutBuf.writesub], pmsg, sizeof ( SCLC_MSG ) );
|
|
SCLC_OutBuf.writesub = ( SCLC_OutBuf.writesub + 1 ) % SS_MSG_NUM;
|
|
if( SCLC_OutBuf.writesub == SCLC_OutBuf.readsub )
|
|
{
|
|
spLogDebug ( SCCPDB_ERR | SCCPDB_UDT, "<008>SCLC Out Buffer Overflow" );
|
|
SCLC_OutBuf.readsub = ( SCLC_OutBuf.readsub + 1 ) % SS_MSG_NUM;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
int sclc_receive ( SCLC_MSG * pmsg, BYTE usertype )
|
|
{
|
|
short readsub;
|
|
|
|
usertype %= MAX_SCLC_BUF; /* revised by pierre */
|
|
readsub = SCLC_InBuf[usertype].readsub % SS_MSG_NUM;
|
|
if( SCLC_InBuf[usertype].writesub == readsub )
|
|
return 0;
|
|
|
|
memcpy ( pmsg, &SCLC_InBuf[usertype].msglist[readsub], sizeof ( SCLC_MSG ) );
|
|
SCLC_InBuf[usertype].readsub = ( readsub + 1 ) % SS_MSG_NUM;
|
|
|
|
return 1;
|
|
}
|
|
|
|
void sclc_timer ( )
|
|
{
|
|
Intra_Msg outmsg;
|
|
SCLC_MSG *pmsg;
|
|
int loop = 128;
|
|
short readsub;
|
|
|
|
int SegMsgIndex;
|
|
|
|
for ( SegMsgIndex = 0; SegMsgIndex < MAX_SEGMSG_BUF; SegMsgIndex++ )
|
|
{
|
|
if( sccp_segmsgbuf[SegMsgIndex].SegMsgTimer && sccp_segmsgbuf[SegMsgIndex].SegMsgTimer++ > MAX_SEGMSG_TIMER )
|
|
{
|
|
spLogDebug ( SCCPDB_ERR, "SCCP XUDT Msg Timer Out. " );
|
|
spLogSeg ( &sccp_segmsgbuf[SegMsgIndex] );
|
|
memset ( &sccp_segmsgbuf[SegMsgIndex], 0, sizeof ( SCCP_SegMsgBuf ) );
|
|
}
|
|
}
|
|
|
|
while ( loop-- > 0 )
|
|
{
|
|
if( SCLC_OutBuf.readsub == SCLC_OutBuf.writesub )
|
|
return;
|
|
|
|
readsub = SCLC_OutBuf.readsub % SS_MSG_NUM;
|
|
pmsg = &SCLC_OutBuf.msglist[readsub];
|
|
SCLC_OutBuf.readsub = ( readsub + 1 ) % SS_MSG_NUM;
|
|
|
|
outmsg.msgsource = FROM_SCLC;
|
|
outmsg.msgtype = UDT_MSG;
|
|
outmsg.msgclass = 0;
|
|
outmsg.SLS = pmsg->sls;
|
|
outmsg.sequenceFlag = pmsg->sequence_control;
|
|
|
|
memcpy ( &( outmsg.CDA ), &pmsg->dst_addr, sizeof ( SCCP_ADDR ) );
|
|
memcpy ( &( outmsg.CGA ), &pmsg->src_addr, sizeof ( SCCP_ADDR ) );
|
|
|
|
outmsg.NetID = outmsg.CGA.NetID = outmsg.CDA.NetID;
|
|
// outmsg.CDA.TT = 0;
|
|
outmsg.CDA.ip = 0xFFFFFFFF;
|
|
outmsg.msglen = pmsg->msglen % 256;
|
|
memcpy ( outmsg.data, pmsg->msg, pmsg->msglen % 256 );
|
|
|
|
if( MNP_Flag[0] != 0 && outmsg.CDA.NP == 1 && outmsg.CDA.SSN == 6 && pmsg->msg[0] == 0x62 )
|
|
{
|
|
/* MNP supported */
|
|
if( MNP_Flag[1] != 2 ) /* Direct routing */
|
|
{
|
|
if( MNP_Flag[0] == 1 && outmsg.CDA.TT != 0 )
|
|
{
|
|
/* IN_based call related message */
|
|
spLogDebug ( SCCPDB_UDT, "User ==> SCCP: IN_based MNP and Call_related message, routed to HLR" );
|
|
//spShowMsg(SCCPDB_USER, "User ==> SCCP: UDT Message", &outmsg);
|
|
//scrc_route(&outmsg);
|
|
}
|
|
else if( outmsg.CGA.SSN != 10 )
|
|
{
|
|
spShowMsg ( SCCPDB_USER, "User ==> SCCP ==> MNP_SRF : UDT Message", &outmsg );
|
|
|
|
outmsg.msgMNP = 1;
|
|
scrc2sclc ( &outmsg );
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
|
|
spShowMsg ( SCCPDB_USER, "User ==> SCCP: UDT Message", &outmsg );
|
|
scrc_route ( &outmsg, 0 );
|
|
}
|
|
return;
|
|
}
|
|
|
|
/* added by Pierre for MNP, 2005-11-07 */
|
|
int sclc_mnp_send ( SCLC_MSG * pmsg )
|
|
{
|
|
Intra_Msg outmsg;
|
|
|
|
if( pmsg->msglen > 256 )
|
|
{
|
|
spLogDebug ( SCCPDB_ERR | SCCPDB_UDT, "<007>User ==> SCCP: Message's Length exceed 256" );
|
|
spShowBCD ( SCCPDB_ERR, pmsg->msg, pmsg->msglen % 256 );
|
|
return 0;
|
|
}
|
|
SccpCsta[SccpCstaInd].utilization[0]++;
|
|
|
|
sccpmsg_st.mnp_send++;
|
|
outmsg.msgsource = FROM_SCLC;
|
|
outmsg.msgtype = UDT_MSG;
|
|
outmsg.msgclass = 0;
|
|
outmsg.SLS = pmsg->sls;
|
|
|
|
memcpy ( &( outmsg.CDA ), &pmsg->dst_addr, sizeof ( SCCP_ADDR ) );
|
|
memcpy ( &( outmsg.CGA ), &pmsg->src_addr, sizeof ( SCCP_ADDR ) );
|
|
|
|
outmsg.NetID = outmsg.CGA.NetID = outmsg.CDA.NetID;
|
|
//outmsg.CDA.TT = 0;
|
|
outmsg.CDA.ip = 0xFFFFFFFF;
|
|
outmsg.msglen = pmsg->msglen % 256;
|
|
memcpy ( outmsg.data, pmsg->msg, pmsg->msglen % 256 );
|
|
|
|
spShowMsg ( SCCPDB_USER, "User ==> SCCP: UDT Message", &outmsg );
|
|
|
|
return scrc_mnp_route ( &outmsg, 0 );
|
|
|
|
}
|
|
|
|
//add for UDT SegmentingMsg to XUDT --lw 2007/03/20
|
|
int SegmentingMsg ( Intra_Msg * pIntraMsg )
|
|
{
|
|
Intra_Msg pIntraMsgSeg1, pIntraMsgSeg2;
|
|
int ret1, ret2;
|
|
BYTE sSegLR[4];
|
|
|
|
ret1 = ret2 = 0;
|
|
|
|
memcpy ( &pIntraMsgSeg1, pIntraMsg, sizeof ( Intra_Msg ) );
|
|
memcpy ( &pIntraMsgSeg2, pIntraMsg, sizeof ( Intra_Msg ) );
|
|
|
|
pIntraMsgSeg1.msglen = pIntraMsg->msglen / 2;
|
|
pIntraMsgSeg2.msglen = pIntraMsg->msglen - pIntraMsgSeg1.msglen;
|
|
|
|
memset ( &pIntraMsgSeg1.data[pIntraMsgSeg1.msglen], 0, SCCP_MSG_MAXLEN - pIntraMsgSeg1.msglen );
|
|
memcpy ( &pIntraMsgSeg2.data[0], &pIntraMsg->data[pIntraMsgSeg1.msglen], pIntraMsgSeg2.msglen );
|
|
memset ( &pIntraMsgSeg2.data[pIntraMsgSeg2.msglen], 0, SCCP_MSG_MAXLEN - pIntraMsgSeg2.msglen );
|
|
|
|
pIntraMsgSeg1.msgtype = pIntraMsgSeg2.msgtype = XUDT_MSG;
|
|
pIntraMsgSeg1.SegPresent = pIntraMsgSeg2.SegPresent = 1;
|
|
pIntraMsgSeg1.Segmnt.CBit = pIntraMsgSeg2.Segmnt.CBit = 1; //sequence
|
|
pIntraMsgSeg1.Segmnt.FBit = 1;
|
|
pIntraMsgSeg2.Segmnt.FBit = 0;
|
|
pIntraMsgSeg1.Segmnt.RSBits = 1;
|
|
pIntraMsgSeg2.Segmnt.RSBits = 0;
|
|
pIntraMsgSeg1.Hop = pIntraMsgSeg1.Hop = 0;
|
|
sSegLR[0] = ( SCCP_Param.ip >> 16 ) & 0x0001; //plant number
|
|
sSegLR[1] = pIntraMsg->SLS;
|
|
sSegLR[2] = SCCPCapBuf.watch_dog[128]++;
|
|
memcpy ( pIntraMsgSeg1.Segmnt.SegLR, sSegLR, SEG_RS_LEN );
|
|
memcpy ( pIntraMsgSeg2.Segmnt.SegLR, sSegLR, SEG_RS_LEN );
|
|
|
|
spLogDebug ( SCCPDB_UDT, "SCCP =>SCCP_RegProc=> SCCP : Length [%d Bytes] [%d Bytes]\r\n", pIntraMsgSeg1.msglen, pIntraMsgSeg2.msglen );
|
|
|
|
ret1 = send_msg ( &pIntraMsgSeg1 );
|
|
|
|
ret2 = send_msg ( &pIntraMsgSeg2 );
|
|
|
|
return ( ret1 > 0 && ret2 > 0 );
|
|
}
|
|
|
|
int RecvXUDTMsg ( Intra_Msg * pIntraMsg, BYTE nbuf )
|
|
{
|
|
SCLC_MSG *pmsg;
|
|
short writesub, readsub;
|
|
int SegMsgIndex;
|
|
|
|
if( !pIntraMsg->SegPresent ) //Not Include Segmentation Paramenters
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
if( pIntraMsg->Segmnt.FBit == 1 && pIntraMsg->Segmnt.RSBits == 0 ) //Single Segmetaion
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
SegMsgIndex = CheckSegUnID ( pIntraMsg );
|
|
|
|
if( SegMsgIndex == MAX_SEGMSG_BUF + 1 ) //check CGA SLR MTP3 routing lable is idle
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
else if( SegMsgIndex == MAX_SEGMSG_BUF ) //first Segmentation
|
|
{
|
|
if( pIntraMsg->Segmnt.FBit != 1 )
|
|
{
|
|
spLogDebug ( SCCPDB_ERR, "SCCP Recv new XUDT Msg but the Fbit is not 1." );
|
|
return 0;
|
|
}
|
|
|
|
for ( SegMsgIndex = 0; SegMsgIndex < MAX_SEGMSG_BUF; SegMsgIndex++ )
|
|
{
|
|
if( sccp_segmsgbuf[SegMsgIndex].MsgState == SEGSTREAM_IDLE )
|
|
{
|
|
int SegBlockIndex;
|
|
SCCP_SegStream *pSegStream;
|
|
SCCP_SegMsgBuf *pSegMsgbuf = &sccp_segmsgbuf[SegMsgIndex];
|
|
|
|
pSegMsgbuf->MsgClass = pIntraMsg->Segmnt.CBit;
|
|
pSegMsgbuf->MsgTotal = pIntraMsg->Segmnt.RSBits + 1;
|
|
pSegMsgbuf->RSE = pIntraMsg->Segmnt.RSBits - 1;
|
|
|
|
pSegMsgbuf->SegID.DPC = pIntraMsg->DPC;
|
|
pSegMsgbuf->SegID.OPC = pIntraMsg->OPC;
|
|
pSegMsgbuf->SegID.SLS = pIntraMsg->SLS;
|
|
memcpy ( &pSegMsgbuf->SegID.CGA, &pIntraMsg->CGA, sizeof ( SCCP_ADDR ) );
|
|
memcpy ( &pSegMsgbuf->SegID.SegLR, &pIntraMsg->Segmnt.SegLR, SEG_RS_LEN );
|
|
|
|
SegBlockIndex = pSegMsgbuf->MsgTotal - ( pIntraMsg->Segmnt.RSBits + 1 );
|
|
pSegStream = &pSegMsgbuf->SegStream[SegBlockIndex];
|
|
pSegStream->SegDataLen = pIntraMsg->msglen;
|
|
memcpy ( &pSegStream->SegDataBlock, &pIntraMsg->data, pIntraMsg->msglen );
|
|
|
|
pSegMsgbuf->SegMsgTimer = 1;
|
|
pSegMsgbuf->MsgState = SEGSTREAM_BUSY;
|
|
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
if( SegMsgIndex == MAX_SEGMSG_BUF )
|
|
{
|
|
spLogDebug ( SCCPDB_ERR, "SCCP Recv new XUDT but SCCP SegMsg buf is not enough" );
|
|
return 0;
|
|
}
|
|
}
|
|
else //not first Segmentation
|
|
{
|
|
int SegBlockIndex;
|
|
int i, j, linemax;
|
|
char info[2560 * 3 + 512], temp_str[128];
|
|
SCCP_SegStream *pSegStream;
|
|
SCCP_SegMsgBuf *pSegMsgbuf = &sccp_segmsgbuf[SegMsgIndex];
|
|
|
|
if( pIntraMsg->Segmnt.RSBits != pSegMsgbuf->RSE )
|
|
{
|
|
spLogDebug ( SCCPDB_ERR, "SCCP Recv unexpect RS XUDT Msg , discard it" );
|
|
return 0;
|
|
}
|
|
|
|
if( pIntraMsg->Segmnt.FBit == 1 )
|
|
{
|
|
spLogDebug ( SCCPDB_ERR, "SCCP Recv XUDT Msg dupulicate first segment. discard it" );
|
|
return 0;
|
|
}
|
|
|
|
SegBlockIndex = pSegMsgbuf->MsgTotal - ( pIntraMsg->Segmnt.RSBits + 1 );
|
|
pSegStream = &pSegMsgbuf->SegStream[SegBlockIndex];
|
|
|
|
if( pSegStream->SegDataLen )
|
|
{
|
|
spLogDebug ( SCCPDB_ERR, "SCCP Recv XUDT Msg dupulicate segment, discard it[RS :%d]", pIntraMsg->Segmnt.RSBits );
|
|
return 0;
|
|
}
|
|
pSegStream->SegDataLen = pIntraMsg->msglen;
|
|
memcpy ( &pSegStream->SegDataBlock, &pIntraMsg->data, pIntraMsg->msglen );
|
|
|
|
if( pSegMsgbuf->RSE )
|
|
{
|
|
pSegMsgbuf->RSE--;
|
|
return 1;
|
|
}
|
|
|
|
//last segment
|
|
pSegMsgbuf->SegMsgTimer = 0;
|
|
writesub = SCLC_InBuf[nbuf].writesub;
|
|
readsub = SCLC_InBuf[nbuf].readsub;
|
|
pmsg = &SCLC_InBuf[nbuf].msglist[writesub];
|
|
|
|
if( !RsmRegMsg ( pmsg, pSegMsgbuf, pIntraMsg ) )
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
if( ( SCLC_InBuf[nbuf].writesub + 1 ) == SCLC_InBuf[nbuf].readsub )
|
|
spShowMsg ( SCCPDB_UDT, "USER <== SCCP: buf overflow!!!!!!!", pIntraMsg );
|
|
|
|
SCLC_InBuf[nbuf].writesub = ( writesub + 1 ) % SS_MSG_NUM;
|
|
if( SCLC_InBuf[nbuf].writesub == readsub )
|
|
SCLC_InBuf[nbuf].readsub = ( readsub + 1 ) % SS_MSG_NUM;
|
|
|
|
spLog ( "\r\n\r\nUser <== SCCP_RegProc. XUDT Message" );
|
|
spLogSeg ( pSegMsgbuf );
|
|
info[0] = '\0';
|
|
sprintf ( temp_str, "Segmentaion Length info: \r\n" );
|
|
strcat ( info, temp_str );
|
|
for ( i = 0; i < pSegMsgbuf->MsgTotal; i++ )
|
|
{
|
|
sprintf ( temp_str, "[%02d]:%d ", i, pSegMsgbuf->SegStream[i].SegDataLen );
|
|
strcat ( info, temp_str );
|
|
if( i == 7 )
|
|
{
|
|
strcat ( info, "\r\n" );
|
|
}
|
|
}
|
|
spLog ( info );
|
|
|
|
memset ( info, 0, 2560 * 3 + 512 );
|
|
i = j = linemax = 0;
|
|
while ( i * 16 < pmsg->msglen )
|
|
{
|
|
if( ( linemax = pmsg->msglen - 16 * i ) > 16 )
|
|
linemax = 16;
|
|
for ( j = 0; j < linemax; j++ )
|
|
{
|
|
sprintf ( info + 3 * j + ( j > 7 ? 1 : 0 ), "%02X ", pmsg->msg[16 * i + j] );
|
|
if( j == 7 )
|
|
{
|
|
sprintf ( info + 3 * 8, " " );
|
|
}
|
|
}
|
|
spLog ( info );
|
|
i++;
|
|
}
|
|
|
|
memset ( pSegMsgbuf, 0, sizeof ( SCCP_SegMsgBuf ) );
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int CheckSegUnID ( Intra_Msg * pIntraMsg )
|
|
{
|
|
int SegMsgIndex, nCheckFlag;
|
|
SCCP_SegUnID *pSegId;
|
|
|
|
nCheckFlag = 0;
|
|
for ( SegMsgIndex = 0; SegMsgIndex < MAX_SEGMSG_BUF; SegMsgIndex++ )
|
|
{
|
|
pSegId = &sccp_segmsgbuf[SegMsgIndex].SegID;
|
|
if( memcmp ( &pSegId->SegLR, &pIntraMsg->Segmnt.SegLR, SEG_RS_LEN ) )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if( pSegId->DPC != pIntraMsg->DPC ) //have routed , equal of course
|
|
{
|
|
spLogDebug ( SCCPDB_ERR, "SCCP XUDT Msg check MTP3 routing lable fail , DPC is not matched!" );
|
|
nCheckFlag = 1;;
|
|
}
|
|
if( pSegId->OPC != pIntraMsg->OPC )
|
|
{
|
|
spLogDebug ( SCCPDB_ERR, "SCCP XUDT Msg check MTP3 routing lable fail , OPC is not matched!" );
|
|
nCheckFlag = 1;
|
|
}
|
|
if( pSegId->SLS != pIntraMsg->SLS )
|
|
{
|
|
spLogDebug ( SCCPDB_ERR, "SCCP XUDT Msg check MTP3 routing lable fail , SLS is not matched!" );
|
|
nCheckFlag = 1;
|
|
}
|
|
if( memcmp ( &pSegId->CGA, &pIntraMsg->CGA, sizeof ( SCCP_ADDR ) ) )
|
|
{
|
|
spLogDebug ( SCCPDB_ERR, "SCCP XUDT Msg check MTP3 routing lable fail , CGA is not matched!" );
|
|
nCheckFlag = 1;
|
|
}
|
|
|
|
if( nCheckFlag ) //act as a new segmention start
|
|
{
|
|
if( pIntraMsg->Segmnt.FBit == 1 && pIntraMsg->Segmnt.RSBits != 0 )
|
|
{
|
|
return MAX_SEGMSG_BUF;
|
|
}
|
|
return MAX_SEGMSG_BUF + 1;
|
|
}
|
|
|
|
return SegMsgIndex;
|
|
}
|
|
return SegMsgIndex;
|
|
}
|
|
|
|
int RsmRegMsg ( SCLC_MSG * pmsg, SCCP_SegMsgBuf * pSegMsgbuf, Intra_Msg * pIntraMsg )
|
|
{
|
|
int SegBlockIndex, XUDTMsgLen;
|
|
SCCP_SegStream *pSegStream;
|
|
|
|
XUDTMsgLen = 0;
|
|
for ( SegBlockIndex = 0; SegBlockIndex < pSegMsgbuf->MsgTotal; SegBlockIndex++ )
|
|
{
|
|
pSegStream = &pSegMsgbuf->SegStream[SegBlockIndex];
|
|
XUDTMsgLen += pSegStream->SegDataLen;
|
|
}
|
|
|
|
if( XUDTMsgLen > MAX_SCLCMSG_LEN )
|
|
{
|
|
spLogDebug ( SCCPDB_ERR, "SCCP Reassemble XUDT Msg is too long ,discard it" );
|
|
return 0;
|
|
}
|
|
|
|
XUDTMsgLen = 0;
|
|
for ( SegBlockIndex = 0; SegBlockIndex < pSegMsgbuf->MsgTotal; SegBlockIndex++ )
|
|
{
|
|
pSegStream = &pSegMsgbuf->SegStream[SegBlockIndex];
|
|
memcpy ( pmsg->msg + XUDTMsgLen, pSegStream->SegDataBlock, pSegStream->SegDataLen );
|
|
XUDTMsgLen += pSegStream->SegDataLen;
|
|
}
|
|
pmsg->msglen = XUDTMsgLen;
|
|
memcpy ( &( pmsg->src_addr ), &( pIntraMsg->CGA ), sizeof ( SCCP_ADDR ) );
|
|
memcpy ( &( pmsg->dst_addr ), &( pIntraMsg->CDA ), sizeof ( SCCP_ADDR ) );
|
|
|
|
return 1;
|
|
}
|
|
|