/***************************************************************/ /*Title: scrc.c */ /*Descr: SCCP Routing Control Procedure */ /*Author: Liang Hanxi */ /*Create: 2002-2-19 */ /*Modify: 2003-5-9 */ /***************************************************************/ #include "./include/sccp.h" #include "./include/sccp_pub.h" #include "../../public/src/include/pub_netcap.h" extern int sccp_send_netcap ; /*===========export================*/ void scrc_timer ( ); int scrc_route ( Intra_Msg * pIntraMsg, BOOL ForceAnsi ); int scrc_mnp_route ( Intra_Msg * pIntraMsg, BOOL ForceAnsi ); int send_msg ( Intra_Msg * pIntraMsg, BYTE ansi_flag ); int scrc_rf ( Intra_Msg * pIntraMsg, BYTE AnsiFlag ); DWORD SelectIPOfSSN ( BYTE ssn, BYTE sls, BOOL from_mtp ); /*===========import================*/ extern int SegmentingMsg ( Intra_Msg * pIntraMsg ); //sclc.c extern int build_msg ( BYTE * buf, Intra_Msg * intramsg, BYTE NetID, BYTE ansi_flag ); extern int parse_msg ( BYTE * buf, Intra_Msg * intramsg, int len, BYTE NetID, BYTE ansi_flag ); //sccpmsg.c extern int scrc2scoc ( Intra_Msg * intramsg, BYTE AnsiFlag ); extern int scoc_store ( up_message * sccpmsg ); extern int Digits2Array ( BYTE * pArray, BYTE * pDigits, int DigitsLen ); extern u_short SelectRoute ( BYTE * pDigits, BYTE DigitsLen ); extern void TranslateGT ( SCCP_ADDR * addr, SCCP_ROUTE * pRoute ); extern int sclc2scmg ( Intra_Msg * intramsg ); extern BOOL CheckAvail ( SCCP_ADDR * addr ); extern int scrc2sclc ( Intra_Msg * pIntraMsg ); extern int sclc_rf ( Intra_Msg * pIntraMsg ); extern BOOL isco ( Intra_Msg * intramsg ); extern void snmpLogInfo ( char *logInfo ); /* by simon at 23/9/26 */ extern SCCP_CSTA SccpCsta[96]; extern DWORD SccpCstaInd; extern LOCAL_SSN LocalSSN[256]; extern 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 struct _dpc2sls { int dpc; u8 sls; } dpc2sls[256]; // used for sequence control, add by Roy Jiang, 2007-09-17 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]; /*===========private================*/ static int mtp2scrc ( up_message * pMsgFromMTP ); void sccp_put_capture_logs ( BYTE person, BYTE * pictures, int len ); int get_sls(int dpc); /******************************************************************/ /*==================Interface function----->================*/ /******************************************************************/ void scrc_timer ( ) //called per 20ms //read messge from mtp buffer { up_message MsgFromMTP3; BYTE loop = 128; while ( loop-- > 0 ) { if( sccp_GetMsg ( &MsgFromMTP3 ) > 0 ) mtp2scrc ( &MsgFromMTP3 ); else break; } } u32 dAlterIpBackup; //for protection int mtp2scrc ( up_message * pMsgFromMTP ) { Intra_Msg msgin; BOOL ForceAnsi = 0; int mask; char *pStr; SccpCsta[SccpCstaInd].utilization[0]++; memset ( &msgin, 0, sizeof ( Intra_Msg ) ); msgin.NetID = msgin.CGA.NetID = msgin.CDA.NetID = pMsgFromMTP->sio >> 6; msgin.DPC = pMsgFromMTP->dpc; msgin.OPC = pMsgFromMTP->opc; msgin.SLS = pMsgFromMTP->cic[0] & 0x0F; msgin.link = pMsgFromMTP->link; ForceAnsi = ( pMsgFromMTP->sio >> 4 ) & 1; parse_msg ( pMsgFromMTP->msgList, &msgin, pMsgFromMTP->len, msgin.NetID, ForceAnsi ); if( msgin.CDA.len > ( MAX_DIGITS * 2 ) ) { SCCPCapBuf.watch_dog[14]++; sccp_put_capture_logs ( 03, ( BYTE * ) pMsgFromMTP, sizeof ( up_message ) ); spLogDebug ( SCCPDB_ERR, "SCCP RV Invalid Message from MTP3,CDA.len=%d, len is over range, the Message was captured", msgin.CDA.len ); } msgin.msgsource = FROM_MTP; if( msgin.CGA.DPC == SCCP_Param.spc[msgin.NetID] ) msgin.CGA.ip = pMsgFromMTP->dest_ip; else msgin.CGA.ip = INADDR_NONE; msgin.CDA.ip = INADDR_NONE; switch ( msgin.msgtype ) { case UDT_MSG: SccpCsta[SccpCstaInd].quality[2]++; spShowMsg ( SCCPDB_MTP3, "SCCP <== MTP3. UDT Message", &msgin ); return scrc_route ( &msgin, ForceAnsi ); case UDTS_MSG: SccpCsta[SccpCstaInd].quality[3]++; spShowMsg ( SCCPDB_MTP3, "SCCP <== MTP3. UDTS Message", &msgin ); return scrc_route ( &msgin, ForceAnsi ); case XUDT_MSG: //SccpCsta[SccpCstaInd].quality[3]++; mask = 0; if( msgin.SegPresent == 1 ) { mask |= SCCPDB_XUDT; } spShowMsg ( SCCPDB_MTP3 | mask, "SCCP_RegProc <== SCCP <== MTP3. XUDT Message", &msgin ); return scrc_route ( &msgin, ForceAnsi ); case XUDTS_MSG: //SccpCsta[SccpCstaInd].quality[3]++; spShowMsg ( SCCPDB_MTP3, "SCCP <== MTP3. XUDTS Message", &msgin ); return scrc_route ( &msgin, ForceAnsi ); case CR_MSG: SccpCsta[SccpCstaInd].quality[6]++; spShowMsg ( SCCPDB_AIF, "SCCP <== MTP3. CR Message", &msgin ); return scrc_route ( &msgin, ForceAnsi ); case DT1_MSG: case CC_MSG: case DT2_MSG: case RLSD_MSG: case RLC_MSG: case CREF_MSG: case AK_MSG: case IT_MSG: //message redirect, add by Roy Jiang if (msgin.aDLR[0] != pSp->dSysID //not local system && msgin.aDLR[0] <= 2 && msgin.aDLR[0] != 0) //only system 1 & system 2 { //dual server mode and the message is to the other server if(pSp->dAlterIP == 0) { if (dAlterIpBackup != 0){ spLogDebug ( SCCPDB_ERR, "Fatal error, memory corrupted, pSp->dAlterIp = 0."); pSp->dAlterIP = dAlterIpBackup; } else return 0; } msgin.CDA.ip = pSp->dAlterIP; msgin.msgsource = FROM_MTP; msgin.redirectFlag = 1; //send_msg ( &msgin, 0 ); //uAnsiFlag = 0; pMsgFromMTP->dest_ip = pSp->dAlterIP; pMsgFromMTP->link = 0xff; sccp_redirect(pMsgFromMTP); spGetMsgStr ( msgin.msgtype, pStr ); spShowMsg(SCCPDB_MTP3, "Message redirected. SCCP ==> MTP3.", &msgin); // spLogDebug ( SCCPDB_AIF, "Message redirected. CO-%s, NetID=%d, msglen=%d", pStr, msgin.NetID, msgin.msglen ); return 0; } if( msgin.msgtype == DT1_MSG ) SccpCsta[SccpCstaInd].utilization[9 - 3]++; else if( msgin.msgtype == DT1_MSG ) SccpCsta[SccpCstaInd].utilization[11 - 3]++; spGetMsgStr ( msgin.msgtype, pStr ); spLogDebug ( SCCPDB_AIF, "SCCP <== MTP3. CO-%s, NetID=%d, msglen=%d ", pStr, msgin.NetID, msgin.msglen ); { char digits1[24], digits2[24]; //, info[256]; BcdToAscii ( digits1, msgin.aSLR, 6 ); digits1[6] = 0; BcdToAscii ( digits2, msgin.aDLR, 6 ); digits2[6] = 0; spLogDebug ( SCCPDB_AIF,"SLR = %s DLR = %s ", digits1, digits2 ); } spShowBCD ( SCCPDB_AIF, ( BYTE * ) pMsgFromMTP, ( pMsgFromMTP->len + 17 ) % 256 ); #ifndef _WXC_TEST /* if( SCCP_Param.CO_SSN <= 1 ) return scrc_rf ( &msgin, ForceAnsi ); msgin.CDA.ip = SelectIPOfSSN ( SCCP_Param.CO_SSN, msgin.SLS, 1 ); if( msgin.CDA.ip == SCCP_Param.ip ) { return scoc_store ( pMsgFromMTP ); } else if( msgin.CDA.ip == 0 ) return scrc_rf ( &msgin, ForceAnsi ); else return send_msg ( &msgin, ForceAnsi ); */ #endif //need to modify cr2co ( &msgin, ForceAnsi ); return 1; //break; default: spLogDebug ( SCCPDB_ERR, "SCCP <== MTP3. Not support Message(type=%02x), NetID=%d, msglen=%d", msgin.msgtype, msgin.NetID, msgin.msglen ); spShowBCD ( SCCPDB_ERR, ( BYTE * ) pMsgFromMTP, ( pMsgFromMTP->len + 17 ) % 256 ); SCCPCapBuf.watch_dog[12]++; //invalid message SCCPCapBuf.watch_dog[13] = msgin.msgtype; //invalid message } return 0; } /******************************************************************/ /*========== Routing Control Procedure-----> ===========*/ /******************************************************************/ int scrc_route ( Intra_Msg * pIntraMsg, BOOL ForceAnsi ) { SCCP_ADDR *pAddr = NULL, DstAddr; SCCP_ROUTE *pRoute = NULL; int LocalSPC; u_short nRoute = 0xFFFF; BYTE Num[32], NumLen; BYTE routeAI; BYTE field = 0; SccpCsta[SccpCstaInd].utilization[0]++; pIntraMsg->msgMNP = 0; pAddr = &pIntraMsg->CDA; /* daniel */ pAddr->AI = 1; //default to include DPC pIntraMsg->CGA.AI = 1; //default to include DPC /* daniel */ memcpy ( &DstAddr, pAddr, sizeof ( SCCP_ADDR ) ); if( pAddr->RI == RI_SSN && pAddr->DPC == 0 ) { if( pAddr->NetID > 3 ) { spLogDebug ( SCCPDB_ERR, "<011>SCCP Translation:SPC not available" ); SccpCsta[SccpCstaInd].error[0]++; return -1; } DstAddr.DPC = SCCP_Param.spc[pAddr->NetID]; } //Route On GT if( DstAddr.RI == RI_GT || DstAddr.DPC == 0 || DstAddr.SSN == 0 || DstAddr.NetID > 3 ) { SccpCsta[SccpCstaInd].utilization[5 - 3]++; if( pIntraMsg->CDA.GTI == 0 ) { pIntraMsg->cause = RT_NTFN; spLogDebug ( SCCPDB_ERR, "<011>SCCP Translation:GTI == 0 (4 is recommended)" ); SccpCsta[SccpCstaInd].error[1]++; return -1; } /* if(pIntraMsg->CDA.TT != 0) { spLogDebug(SCCPDB_ERR, "<012>SCCP Translation:no translation for an address of such nature(TT=%d)", pIntraMsg->CDA.TT); pIntraMsg->cause = RT_NTFN; SccpCsta[SccpCstaInd].error[0] ++; return -1; } */ if( pAddr->len > ( MAX_DIGITS * 2 ) ) { SCCPCapBuf.watch_dog[0]++; sccp_put_capture_logs ( 01, ( BYTE * ) pIntraMsg, sizeof ( Intra_Msg ) ); spLogDebug ( SCCPDB_ERR, "<014>SCCP Receive Invalid Message,GTT len=%d, the Message was discarded and captured", pAddr->len ); return -2; } 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 ); nRoute = SelectRoute ( Num, NumLen + field ); if( nRoute < SCCP_ROUTE_NUM ) { pRoute = &RouteList[nRoute]; if( DstAddr.NetID != pRoute->NetID ) pIntraMsg->CGA.RI = RI_GT; /* daniel */ else if( pIntraMsg->msgsource != FROM_MTP ) pIntraMsg->CGA.RI = pRoute->RI; /* daniel */ DstAddr.NetID = pRoute->NetID; if( pRoute->SSN > 0 ) pAddr->SSN = DstAddr.SSN = pRoute->SSN; pAddr->RI = pRoute->RI; DstAddr.DPC = pRoute->DPC[0] * 0x10000 + pRoute->DPC[1] * 0x100 + pRoute->DPC[2]; if(( pIntraMsg->CGA.SSN != 10 ) && ( DstAddr.SSN == 6 && DstAddr.NP == 1 && pIntraMsg->data[0] == 0x62 ) && (MNP_Flag[0] != 0)) {// MNP neednot convert GT if(!((pRoute->ReplaceStart == 1) && (pRoute->ReplaceEnd == pAddr->len))) { if( pRoute->convert ) { DstAddr.RI = pAddr->RI; TranslateGT ( &DstAddr, pRoute ); memcpy ( pAddr, &DstAddr, sizeof ( SCCP_ADDR ) ); } } } else if( pRoute->convert ) { DstAddr.RI = pAddr->RI; TranslateGT ( &DstAddr, pRoute ); memcpy ( pAddr, &DstAddr, sizeof ( SCCP_ADDR ) ); } /* daniel */ routeAI = pRoute->AI; //set calling address if( pIntraMsg->CGA.RI == 0 ) //route on GT { if( ( routeAI & 1 ) == 0 ) //point code no need pIntraMsg->CGA.AI &= ~1; //set dpc=0 } else //route on DPC+SSN { if( ( routeAI & 4 ) == 0 ) //GT no need pIntraMsg->CGA.GTI = 0; //set GT=0 } //set called address if( pAddr->RI == 0 ) //route on GT { if( ( routeAI & 1 ) == 0 ) //point code no need pAddr->AI &= ~1; //set dpc=0 } else //route on DPC+SSN { if( ( routeAI & 4 ) == 0 ) //GT no need pAddr->GTI = 0; //set GTI=0 } /* daniel */ } else if( nRoute >= 1024 && nRoute < 1024 + 256 ) //local Node { pAddr->SSN = DstAddr.SSN = nRoute - 1024; if( DstAddr.NetID > 3 ) DstAddr.NetID = LocalSSN[DstAddr.SSN].NetID; pAddr->RI = RI_SSN; DstAddr.DPC = SCCP_Param.spc[DstAddr.NetID & 3]; } else { pIntraMsg->cause = RT_NTFA; SccpCsta[SccpCstaInd].avail[1]++; if( ForceAnsi ) return scrc_rf ( pIntraMsg, 1 ); else return scrc_rf ( pIntraMsg, mtp3_ansiFlag ( DstAddr.NetID ) ); } } if( !CheckAvail ( &DstAddr ) ) { pIntraMsg->cause = RT_SF; if( ForceAnsi ) return scrc_rf ( pIntraMsg, 1 ); else return scrc_rf ( pIntraMsg, mtp3_ansiFlag ( DstAddr.NetID ) ); } pIntraMsg->NetID = DstAddr.NetID % 4; //0~3 pIntraMsg->DPC = pAddr->DPC = DstAddr.DPC; LocalSPC = SCCP_Param.spc[pIntraMsg->NetID]; if (pIntraMsg->CGA.RI == RI_SSN) { if (pIntraMsg->CGA.DPC == 0) { pIntraMsg->CGA.DPC = pIntraMsg->OPC; } } if (pIntraMsg->CGA.RI == RI_SSN) { if (pIntraMsg->CGA.DPC == 0) { pIntraMsg->CGA.DPC = pIntraMsg->OPC; } } if( DstAddr.DPC != LocalSPC ) { snmpLogInfo ( "scrc_route(): start.... 266" ); if (pIntraMsg->sequenceFlag == 1 && pIntraMsg->msgtype == UDT_MSG){ pIntraMsg->SLS = get_sls(pIntraMsg->DPC); //in-sequence delivery, add by Roy Jiang, 07-09-26 pIntraMsg->msgclass = 1; } if( ForceAnsi ) return send_msg ( pIntraMsg, 1 ); else return send_msg ( pIntraMsg, mtp3_ansiFlag ( DstAddr.NetID ) ); } else if( pIntraMsg->msgtype == UDTS_MSG && pIntraMsg->msgsource == FROM_MTP) //discast UDTS message to local node return 1; if( DstAddr.SSN == 0 ) { pIntraMsg->cause = RT_UU; spLogDebug ( SCCPDB_ERR, "<013>Invalid SSN(0)" ); SccpCsta[SccpCstaInd].error[2]++; if( ForceAnsi ) return scrc_rf ( pIntraMsg, 1 ); else return scrc_rf ( pIntraMsg, mtp3_ansiFlag ( DstAddr.NetID ) ); } if( DstAddr.SSN == 1 ) //scmg message return sclc2scmg ( pIntraMsg ); #ifdef _WXC_SPTEST_TEMP //just for test , delete it for normal if( pAddr->ip == INADDR_NONE && pIntraMsg->msgsource == FROM_MTP ) { if( ( pIntraMsg->msgtype >= CR_MSG && pIntraMsg->msgtype <= AK_MSG ) ) { if( ForceAnsi ) return cr2co ( pIntraMsg, 1 ); else return cr2co ( pIntraMsg, mtp3_ansiFlag ( DstAddr.NetID ) ); } else { if( MNP_Flag[0] == 0 || pIntraMsg->msgsource != FROM_MTP ) /* MNP not supported */ return scrc2sclc ( pIntraMsg ); /* SCCP Steering Function */ /* message received or sent */ /* MNP supported */ /* routing method */ pIntraMsg->msgMNP = 0; if( DstAddr.SSN == 6 && DstAddr.NP == 1 && pIntraMsg->data[0] == 0x62 ) { /* IN_Based and SRI for voice call */ if( MNP_Flag[0] == 1 && DstAddr.TT != 0 ) { pIntraMsg->msgMNP = 0; } else if( pIntraMsg->CGA.SSN != 10 ) { pIntraMsg->msgMNP = 1; } return scrc2sclc ( pIntraMsg ); } else { return scrc2sclc ( pIntraMsg ); } } } #endif pAddr->ip = SelectIPOfSSN ( DstAddr.SSN, pIntraMsg->SLS, ( pIntraMsg->msgsource == FROM_MTP ) ); if( pAddr->ip == SCCP_Param.ip ) //local Node { if( ( pIntraMsg->msgtype >= CR_MSG && pIntraMsg->msgtype <= AK_MSG ) ) { if( ForceAnsi ) return cr2co ( pIntraMsg, 1 ); else return cr2co ( pIntraMsg, mtp3_ansiFlag ( DstAddr.NetID ) ); } else { if( sccp_send_netcap) { int len; up_message MsgToMTP; int ansi_flag ; if( ForceAnsi ) ansi_flag = 1; else ansi_flag = mtp3_ansiFlag(DstAddr.NetID); len = build_msg ( MsgToMTP.msgList, pIntraMsg, pIntraMsg->NetID ,ansi_flag ); MsgToMTP.len = len%256; NcSccpSend( MsgToMTP.msgList , MsgToMTP.len , (u8 *)pIntraMsg , ansi_flag); } if( MNP_Flag[0] == 0 || pIntraMsg->msgsource != FROM_MTP ) /* MNP not supported */ return scrc2sclc ( pIntraMsg ); /* SCCP Steering Function */ /* message received or sent */ /* MNP supported */ /* routing method */ pIntraMsg->msgMNP = 0; if( DstAddr.SSN == 6 && DstAddr.NP == 1 && pIntraMsg->data[0] == 0x62 ) { /* IN_Based and SRI for voice call */ if( MNP_Flag[0] == 1 && DstAddr.TT != 0 ) { pIntraMsg->msgMNP = 0; } else if( pIntraMsg->CGA.SSN != 10 ) { pIntraMsg->msgMNP = 1; } return scrc2sclc ( pIntraMsg ); } else { return scrc2sclc ( pIntraMsg ); } } } else if( pAddr->ip == 0 ) //none subsystem is reachable { pIntraMsg->cause = RT_SF; SccpCsta[SccpCstaInd].error[3]++; if( ForceAnsi ) return scrc_rf ( pIntraMsg, 1 ); else return scrc_rf ( pIntraMsg, mtp3_ansiFlag ( DstAddr.NetID ) ); } else //relay to specify subsystem { snmpLogInfo ( "scrc_route(): start... 327" ); if( ForceAnsi ) return send_msg ( pIntraMsg, 1 ); else return send_msg ( pIntraMsg, mtp3_ansiFlag ( DstAddr.NetID ) ); } } int scrc_mnp_route ( Intra_Msg * pIntraMsg, BOOL ForceAnsi ) { SCCP_ADDR *pAddr = NULL, DstAddr; SCCP_ROUTE *pRoute = NULL; int LocalSPC; u_short nRoute = 0xFFFF; BYTE Num[32], NumLen; BYTE routeAI; BYTE field = 0; SccpCsta[SccpCstaInd].utilization[0]++; pAddr = &pIntraMsg->CDA; /* daniel */ pAddr->AI = 1; //default to include DPC pIntraMsg->CGA.AI = 1; //default to include DPC /* daniel */ memcpy ( &DstAddr, pAddr, sizeof ( SCCP_ADDR ) ); if( pAddr->RI == RI_SSN && pAddr->DPC == 0 ) { if( pAddr->NetID > 3 ) { spLogDebug ( SCCPDB_ERR, "<021>SCCP Translation:SPC not available" ); SccpCsta[SccpCstaInd].error[0]++; return -1; } DstAddr.DPC = SCCP_Param.spc[pAddr->NetID]; } //Route On GT if( DstAddr.RI == RI_GT || DstAddr.DPC == 0 || DstAddr.SSN == 0 || DstAddr.NetID > 3 ) { SccpCsta[SccpCstaInd].utilization[5 - 3]++; if( pIntraMsg->CDA.GTI == 0 ) { pIntraMsg->cause = RT_NTFN; spLogDebug ( SCCPDB_ERR, "<021>SCCP Translation:GTI == 0 (4 is recommended)" ); SccpCsta[SccpCstaInd].error[1]++; return -1; } /* if(pIntraMsg->CDA.TT != 0) { spLogDebug(SCCPDB_ERR, "<012>SCCP Translation:no translation for an address of such nature(TT=%d)", pIntraMsg->CDA.TT); pIntraMsg->cause = RT_NTFN; SccpCsta[SccpCstaInd].error[0] ++; return -1; } */ if( pAddr->len > ( MAX_DIGITS * 2 ) ) { SCCPCapBuf.watch_dog[0]++; sccp_put_capture_logs ( 01, ( BYTE * ) pIntraMsg, sizeof ( Intra_Msg ) ); spLogDebug ( SCCPDB_ERR, "<024>SCCP Receive Invalid Message,GTT len=%d, the Message was discarded and captured", pAddr->len ); return -2; } 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 ); nRoute = SelectRoute ( Num, NumLen + field ); if( nRoute < SCCP_ROUTE_NUM ) { pRoute = &RouteList[nRoute]; if( DstAddr.NetID != pRoute->NetID ) pIntraMsg->CGA.RI = RI_GT; /* daniel */ else if( pIntraMsg->msgsource != FROM_MTP ) pIntraMsg->CGA.RI = pRoute->RI; /* daniel */ DstAddr.NetID = pRoute->NetID; if( pRoute->SSN > 0 ) pAddr->SSN = DstAddr.SSN = pRoute->SSN; pAddr->RI = pRoute->RI; DstAddr.DPC = pRoute->DPC[0] * 0x10000 + pRoute->DPC[1] * 0x100 + pRoute->DPC[2]; if( pRoute->convert ) { DstAddr.RI = pAddr->RI; TranslateGT ( &DstAddr, pRoute ); memcpy ( pAddr, &DstAddr, sizeof ( SCCP_ADDR ) ); } /* daniel */ routeAI = pRoute->AI; //set calling address if( pIntraMsg->CGA.RI == 0 ) //route on GT { if( ( routeAI & 1 ) == 0 ) //point code no need pIntraMsg->CGA.AI &= ~1; //set dpc=0 } else //route on DPC+SSN { if( ( routeAI & 4 ) == 0 ) //GT no need pIntraMsg->CGA.GTI = 0; //set GT=0 } //set called address if( pAddr->RI == 0 ) //route on GT { if( ( routeAI & 1 ) == 0 ) //point code no need pAddr->AI &= ~1; //set dpc=0 } else //route on DPC+SSN { if( ( routeAI & 4 ) == 0 ) //GT no need pAddr->GTI = 0; //set GTI=0 } /* daniel */ } else if( nRoute >= 1024 && nRoute < 1024 + 256 ) //local Node { pAddr->SSN = DstAddr.SSN = nRoute - 1024; if( DstAddr.NetID > 3 ) DstAddr.NetID = LocalSSN[DstAddr.SSN].NetID; pAddr->RI = RI_SSN; DstAddr.DPC = SCCP_Param.spc[DstAddr.NetID & 3]; } else { pIntraMsg->cause = RT_NTFA; SccpCsta[SccpCstaInd].avail[1]++; if( ForceAnsi ) return scrc_rf ( pIntraMsg, 1 ); else return scrc_rf ( pIntraMsg, mtp3_ansiFlag ( DstAddr.NetID ) ); } } if( !CheckAvail ( &DstAddr ) ) { pIntraMsg->cause = RT_SF; if( ForceAnsi ) return scrc_rf ( pIntraMsg, 1 ); else return scrc_rf ( pIntraMsg, mtp3_ansiFlag ( DstAddr.NetID ) ); } pIntraMsg->NetID = DstAddr.NetID % 4; //0~3 pIntraMsg->DPC = pAddr->DPC = DstAddr.DPC; LocalSPC = SCCP_Param.spc[pIntraMsg->NetID]; if( DstAddr.DPC != LocalSPC ) { snmpLogInfo ( "mnp_scrc_route(): start... 471" ); if (pIntraMsg->sequenceFlag == 1 && pIntraMsg->msgtype == UDT_MSG){ pIntraMsg->SLS = get_sls(pIntraMsg->DPC); //in-sequence delivery, add by Roy Jiang, 07-09-26 } if( ForceAnsi ) return send_msg ( pIntraMsg, 1 ); else return send_msg ( pIntraMsg, mtp3_ansiFlag ( DstAddr.NetID ) ); //snmpLogInfo ( "mnp_scrc_route(): end... 471" ); } else if( pIntraMsg->msgtype == UDTS_MSG ) //discast UDTS message to local node return 1; if( DstAddr.SSN == 0 ) { pIntraMsg->cause = RT_UU; spLogDebug ( SCCPDB_ERR, "<023>Invalid SSN(0)" ); SccpCsta[SccpCstaInd].error[2]++; if( ForceAnsi ) return scrc_rf ( pIntraMsg, 1 ); else return scrc_rf ( pIntraMsg, mtp3_ansiFlag ( DstAddr.NetID ) ); } if( DstAddr.SSN == 1 ) //scmg message return sclc2scmg ( pIntraMsg ); pAddr->ip = SelectIPOfSSN ( DstAddr.SSN, pIntraMsg->SLS, ( pIntraMsg->msgsource == FROM_MTP ) ); pIntraMsg->msgMNP = 0; if( pAddr->ip == 0 ) //none subsystem is reachable { pIntraMsg->cause = RT_SF; SccpCsta[SccpCstaInd].error[3]++; if( ForceAnsi ) return scrc_rf ( pIntraMsg, 1 ); else return scrc_rf ( pIntraMsg, mtp3_ansiFlag ( DstAddr.NetID ) ); } else if( pAddr->ip == SCCP_Param.ip ) //local Node { if( pIntraMsg->msgtype == CR_MSG || ( DstAddr.SSN == SCCP_Param.CO_SSN && SCCP_Param.CO_SSN > 1 ) ) { if( ForceAnsi ) return cr2co ( pIntraMsg, 1 ); else return cr2co ( pIntraMsg, mtp3_ansiFlag ( DstAddr.NetID ) ); } else return scrc2sclc ( pIntraMsg ); } else //relay to specify subsystem { snmpLogInfo ( "scrc_route(): start... 327" ); if( ForceAnsi ) return send_msg ( pIntraMsg, 1 ); else return send_msg ( pIntraMsg, mtp3_ansiFlag ( DstAddr.NetID ) ); } } int send_msg ( Intra_Msg * pIntraMsg, BYTE ansi_flag ) //pass message to mtp module { int retval = 0; int len = 0; up_message MsgToMTP; pIntraMsg->DPC = pIntraMsg->CDA.DPC; if( pIntraMsg->msgsource != FROM_MTP && ( pIntraMsg->SLS & 0x80 ) == 0 ) { if( pIntraMsg->NetID > 3 ) { return 0; } pIntraMsg->CGA.DPC = SCCP_Param.spc[pIntraMsg->NetID]; pIntraMsg->OPC = SCCP_Param.spc[pIntraMsg->NetID]; } snmpLogInfo ( "send_msg(), build_msg: start..." ); if( pIntraMsg->msglen > 256 ) return 0; len = build_msg ( MsgToMTP.msgList, pIntraMsg, pIntraMsg->NetID, ansi_flag ); /* MsgToMTP.len = build_msg ( MsgToMTP.msgList, pIntraMsg, pIntraMsg->NetID ); if( MsgToMTP.len > 256 ) MsgToMTP.len is a BYTE { return 0; //added by Pierre, 01-19-05 for core at following line } */ //add for UDT SegmentingMsg to XUDT if( len < 272 && ( len + 8 ) > 0xfd && pIntraMsg->msgtype == UDT_MSG && pIntraMsg->msgsource == FROM_SCLC && pIntraMsg->CDA.ip != 0 && pIntraMsg->CDA.ip != SCCP_Param.ip && pIntraMsg->CDA.ip != INADDR_NONE ) { //relay to special system msg too long ,need cut to segment -- add by lw 2007/03/20 spLogDebug ( SCCPDB_UDT, "UDT Message form upper layer is too long, [ %d Bytes(len=%d if include MTP3)]! " "Need to be segmented!\r\n ", pIntraMsg->msglen, len ); retval = SegmentingMsg ( pIntraMsg ); return retval; } if( len >= 256 ) { spLogDebug ( SCCPDB_ERR, "Build SCCP Message too long! " ); return 0; } MsgToMTP.len = len % 256; snmpLogInfo ( "send_msg(), type message: start..." ); switch ( pIntraMsg->msgsource ) { case FROM_MTP: spShowMsg ( SCCPDB_STP, "SCCP ==> MTP3: STP", pIntraMsg ); break; case FROM_SCLC: switch ( pIntraMsg->msgtype ) { case UDT_MSG: SccpCsta[SccpCstaInd].quality[0]++; spShowMsg ( SCCPDB_UDT, "SCCP ==> MTP3:", pIntraMsg ); break; case UDTS_MSG: SccpCsta[SccpCstaInd].quality[1]++; spShowMsg ( SCCPDB_UDT, "SCCP ==> MTP3:", pIntraMsg ); break; case XUDT_MSG: //add for UDT SegmentingMsg to XUDT spShowMsg ( SCCPDB_XUDT, "SCCP ==> MTP3:", pIntraMsg ); break; case XUDTS_MSG: //add for UDT SegmentingMsg to XUDT spShowMsg ( SCCPDB_XUDT, "SCCP ==> MTP3:", pIntraMsg ); break; } break; case FROM_SCOC: spShowMsg ( SCCPDB_AIF, "SCCP ==> MTP3: AIF", pIntraMsg ); break; case FROM_SCMG: spShowMsg ( SCCPDB_SCMG, "SCCP ==> MTP3: SCMG", pIntraMsg ); break; } MsgToMTP.dest_ip = pIntraMsg->CDA.ip; MsgToMTP.dpc = pIntraMsg->DPC; MsgToMTP.opc = pIntraMsg->OPC; MsgToMTP.sio = pIntraMsg->NetID * 0x40 + 3; MsgToMTP.cic[0] = pIntraMsg->SLS & 0x0F; MsgToMTP.link = 0xff; if(pIntraMsg->redirectFlag == 1 && pIntraMsg->CDA.ip != 0xFFFFFFFF) //add by Roy to support sccp dual server message redirect, 07-09-12 retval = sccp_redirect ( &MsgToMTP ); else retval = sccp_to_mtp3 ( &MsgToMTP ); if( sccp_send_netcap) { NcSccpSend( MsgToMTP.msgList , MsgToMTP.len , (u8 *)pIntraMsg , ansi_flag ); } return retval; // return sccp_to_mtp3(&MsgToMTP); //depend on mtp module } int scrc_rf ( Intra_Msg * pIntraMsg, BYTE AnsiFlag ) { #ifdef _WXC_TEST WxcAssert ( 0, "routing fail" ); #endif if( isco ( pIntraMsg ) ) { pIntraMsg->msgtype = SP_MSG_RF; cr2co ( pIntraMsg, AnsiFlag ); spShowMsg ( SCCPDB_ERR, "<006>Route Failure", pIntraMsg ); return -1; } else return sclc_rf ( pIntraMsg ); } DWORD SelectIPOfSSN ( BYTE ssn, BYTE sls, BOOL from_mtp ) { LOCAL_SSN *pssn = &LocalSSN[ssn]; switch ( pssn->status[0] ) { case ST_Enable: switch ( pssn->status[1] ) { case ST_Enable: if( pssn->local == 0 ) return pssn->ip[sls & 0x01]; else if( from_mtp ) return pssn->ip[( pssn->local - 1 ) & 0x01]; else if( ( sls & 0x80 ) == 0x80 ) return pssn->ip[pssn->local & 0x01]; else return pssn->ip[sls & 0x01]; //break; default: if( ( sls & 0x80 ) == 0x80 && pssn->local == 1 ) { spLogDebug ( SCCPDB_ERR, "<014>Message was refused by subsystem_%d_0 and subsystem_%d_1 inaccessible", ssn, ssn ); return 0; } else return pssn->ip[0]; //break; } //break; default: switch ( pssn->status[1] ) { case ST_Enable: if( ( sls & 0x80 ) == 0x80 && pssn->local == 2 ) { spLogDebug ( SCCPDB_ERR, "<015>Message was refused by subsystem_%d_1 and subsystem_%d_0 inaccessible", ssn, ssn ); return 0; } else return pssn->ip[1]; //break; default: spLogDebug ( SCCPDB_ERR, "<016>Subsystem_%d is inaccessible", ssn ); } } return 0; } //sequence control functions -- add by Roy Jiang 2007-09-17 int get_sls(int dpc) { static int pos = 0; //end position of dpc2sls array static u8 next_sls = 0; //sls for new dpc int i; for(i=0; i= 256) return next_sls; dpc2sls[i].dpc = dpc; dpc2sls[i].sls = next_sls; next_sls = (next_sls + 1) & 0x0F; pos++; return dpc2sls[i].sls; } //end of sequence control functions -- add by Roy Jiang 2007-09-17