////////////////////////////////////////////////// //Title : fsm_test.c //Auhtor : Liu Wei //Desc : sccp fsm testing //Created : 2007-05-25 //Revision : // //Revision : // ////////////////////////////////////////////////// #include "../../src/include/sccp.h" #include "../../src/include/sccp_pub.h" #include "../../src/include/scoc_if.h" extern unsigned long spLogDebug_mask ; extern BYTE sccpFilterIndex ; extern BYTE mtp_asciin_buf[80]; #ifdef _WXC_FSM_TEST #define spLogFsm printf #else #define spLogFsm #endif typedef enum UL_ORG_STATE { ORG_IDLE = 1, ORG_CR, //CM LU ORG_CC, //CC ORG_LUR, //lu reject ORG_CLCD, //clean command ORG_CLCE, //clean complete ORG_DISCONN, ORG_SEND_UDT, //PRN ORG_RECV_UDT, //PRN ack } UL_OrgState; typedef enum UL_DST_STATE { DST_IDLE = 1, DST_CR, //CM LU DST_CC, //CC DST_LUR, //lu reject DST_CLCD, //clean command DST_CLCE, //clean complete DST_DISCONN, DST_RECV_UDT, //PRN DST_SEND_UDT, //PRN ack } UL_DstState; typedef struct SCCP_UL { u8 uUlSide; u8 uUlState; u32 uUlTestStartTimer; u32 uUlStateInterval; u32 uWaitTimer; u32 wConnId; int nPort; int nRemoteIP; int nSock; } SP_UL; SP_UL tUl; #define aifprn_udt_msg_len 0x52 static u8 aifprn_udt_msg[] = { 0x51, 0x62, 0x4f, 0x48, 0x04, 0x01, 0x62, 0x00, 0x35, 0x6b, 0x1e, 0x28, 0x1c, 0x06, 0x07, 0x00, 0x11, 0x86, 0x05, 0x01, 0x01, 0x01, 0xa0, 0x11, 0x60, 0x0f, 0x80, 0x02, 0x07, 0x80, 0xa1, 0x09, 0x06, 0x07, 0x04, 0x00, 0x00, 0x01, 0x00, 0x03, 0x02, 0x6c, 0x27, 0xa1, 0x25, 0x02, 0x01, 0x80, 0x02, 0x01, 0x04, 0x30, 0x1d, 0x80, 0x08, 0x64, 0x00, 0x92, 0x00, 0x00, 0x00, 0x83, 0xf4, 0x81, 0x08, 0x91, 0x44, 0x57, 0x55, 0x06, 0x00, 0x00, 0xf0, 0x82, 0x07, 0x91, 0x68, 0x57, 0x95, 0x00, 0x83, 0xf4, }; #define aifprnak_udt_msg_len 0x4b static u8 aifprnak_udt_msg[] = { 0x4a, 0x64, 0x48, 0x49, 0x04, 0x01, 0x62, 0x00, 0x35, 0x6b, 0x2a, 0x28, 0x28, 0x06, 0x07, 0x00, 0x11, 0x86, 0x05, 0x01, 0x01, 0x01, 0xa0, 0x1d, 0x61, 0x1b, 0x80, 0x02, 0x07, 0x80, 0xa1, 0x09, 0x06, 0x07, 0x04, 0x00, 0x00, 0x01, 0x00, 0x03, 0x02, 0xa2, 0x03, 0x02, 0x01, 0x00, 0xa3, 0x05, 0xa1, 0x03, 0x02, 0x01, 0x00, 0x6c, 0x14, 0xa2, 0x12, 0x02, 0x01, 0x80, 0x30, 0x0d, 0x02, 0x01, 0x04, 0x04, 0x08, 0x91, 0x44, 0x57, 0x25, 0x31, 0x06, 0x00, 0xf6 }; #define aiflu_cr_msg_len 0x25 static u8 aiflu_cr_msg[] = { 0x0f, 0x23, 0x00, 0x21, 0x57, 0x05, 0x08, 0x00, 0x57, 0xf0, 0x10, 0x0b, 0xb9, 0x0a, 0xfb, 0x17, 0x12, 0x05, 0x08, 0x70, 0x45, 0xf0, 0x10, 0x00, 0x01, 0x30, 0x08, 0x59, 0x04, 0x10, 0x25, 0x00, 0x20, 0x30, 0x62, 0x21, 0x01, }; #define aifcc_dt1_msg_len 0x00 static u8 aifcc_dt1_msg[] = { }; #define aiflurj_dt1_msg_len 0x07 static u8 aiflurj_dt1_msg[] = { 0x06, 0x01, 0x00 , 0x03, 0x05, 0x04, 0x0b }; #define aifclcd_dt1_msg_len 0x07 static u8 aifclcd_dt1_msg[] = { 0x06, 0x00, 0x04 , 0x20, 0x04, 0x01, 0x09 }; #define aifclce_dt1_msg_len 0x05 static u8 aifclce_dt1_msg[] = { 0x03, 0x00, 0x01 , 0x21, 0x00 }; #define aiflu_rlsd_msg_len 0x00 static u8 aiflu_rlsd_msg[] = { }; #define aiflu_rlc_msg_len 0x00 static u8 aiflu_rlc_msg[] = { }; int get_socket(u_int32_t ip, int port) { int sock; int on = 1; DWORD cmdarg = 1; struct sockaddr_in sin_addr; sin_addr.sin_family = AF_INET; sin_addr.sin_port = htons(port); sin_addr.sin_addr.s_addr = htonl(INADDR_ANY); if(!(sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) perror("Get socket"); setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); if(bind(sock, (struct sockaddr *)&sin_addr, sizeof(struct sockaddr_in)) != 0) { perror("bind"); return 0; } ioctl(sock, FIONBIO, &cmdarg); return (sock); } int ulRecv( u8 *pBuff ) { struct sockaddr_in sin_addr; int addr_len; return recvfrom(tUl.nSock, (char *)pBuff, 256, 0, (struct sockaddr *)&sin_addr, &addr_len); } void ulSend( u8 *pBuff , u8 uLen ) { struct sockaddr_in sin_addr; WxcAssert( uLen < 255 , "ulSend too long msg"); sin_addr.sin_family = AF_INET; sin_addr.sin_port = htons(tUl.nPort); sin_addr.sin_addr.s_addr = tUl.nRemoteIP; sendto(tUl.nSock, (char *)pBuff, 256, 0, (struct sockaddr *)&sin_addr, sizeof(struct sockaddr)); } int ulSpecPeer() { char msg[256]; memset(msg, 0, 256); ulRecv(msg); if( msg[0] ) { printf("Recv test msg: %s\r\n", msg); if( !strcmp(msg, "SCCP_TEST") ) { tUl.uUlSide = 0; printf("slave mode\r\n"); ulSend("SCCP_OK" , 7); tUl.uUlStateInterval=0; return 1; } else if( !strcmp(msg, "SCCP_OK") ) { tUl.uUlSide = 1; printf("master mode\r\n"); tUl.uUlStateInterval=0; return 1; } } if( tUl.uUlStateInterval++ % 200 ) { ulSend("SCCP_TEST" , 9); } return 0; } void ulInit() { int ip; struct in_addr sin_addr; sin_addr.s_addr = tUl.nRemoteIP; memset(&tUl, 0, sizeof(SP_UL)); tUl.uUlSide = 1; tUl.nPort = 6999; ip = GetLocalIP(); tUl.nRemoteIP = ( ip ^ 0x00010000 ); tUl.uWaitTimer = 20; memcpy( &sin_addr , &tUl.nRemoteIP , 4); printf("Remote ip : %s Start timer :%d \n" , inet_ntoa(sin_addr) ,tUl.uWaitTimer ); tUl.nSock = get_socket(tUl.nRemoteIP, tUl.nPort); printf("get sock :%d \r\n",tUl.nSock); register_ssn ( 0xfe, 3 ); mtp_asciin_buf[0] = 1; strcpy( &mtp_asciin_buf[1] , "log all" ); printf("sizeof[sizeof(CO_ConnSection)* 4096]=%d\n", sizeof(CO_ConnSection)* 4096); } void ulLogMsg ( SP_UiPriPara * pSpPri, u8 uDirection , SP_UD *pUD ) { char *pStr; spGetUlPrimitiveStr ( pSpPri->uUiPri, pStr ); if( uDirection ) { spLogDebug ( SCCPDB_AIF , "UL=>SP : %s ", pStr ); } else { spLogDebug ( SCCPDB_AIF , "UL<=SP : %s ", pStr ); } if( NULL != pUD ) { spShowBCD ( 1, pUD->aUserData, pUD->uDataLen ); } } extern void spLog ( char *info ); void ulLogState ( u8 uSide , u8 *pStr ) { char aStr[256]; if( uSide ) sprintf(aStr ,"]Org Node[: %s state \n" , pStr); else sprintf(aStr ,"]Dst Node[: %s state \n" , pStr); spLog(aStr); } void ul_sccp_addr( SCCP_ADDR *pAddr ) { memset( pAddr , 0 , sizeof(SCCP_ADDR) ); pAddr->ip = tUl.nRemoteIP; pAddr->DPC = 40; pAddr->NetID = 2; pAddr->SSN = 254; pAddr->RI = RI_SSN; pAddr->GTI = 0; pAddr->AI = 3; return; } void ulSapFsm ( ) { SP_UiPriPara tSpPri; SP_UiPriUnion *pUPri; pUPri = &tSpPri.tPriUnion; if( !tUl.uUlState ) { if( ulSpecPeer() ) { printf("----------------------OK------------------\r\n"); tUl.uUlState++; }else { return; } } sccpFilterIndex = 0; spLogDebug_mask = 0xFFFFFFFF; //printf("Side : %d state : %d \n",tUl.uUlSide ,tUl.uUlState ); if( tUl.uUlSide ) { switch ( tUl.uUlState ) { case ORG_IDLE: break; case ORG_SEND_UDT: //PRN tSpPri.uUiPri = N_UNITDATA_REQ; ul_sccp_addr ( &pUPri->tPriNUDataReq.tCDA ); ul_sccp_addr ( &pUPri->tPriNUDataReq.tCGA ); pUPri->tPriNUDataReq.tRO.uRO = 1; pUPri->tPriNUDataReq.tUD.uDataLen = aifprn_udt_msg_len; memcpy ( &pUPri->tPriNUDataReq.tUD.aUserData, aifprn_udt_msg, pUPri->tPriNUDataReq.tUD.uDataLen ); ulLogMsg ( &tSpPri, 1 , &pUPri->tPriNUDataReq.tUD); WxcAssert ( PostSp ( &tSpPri ), "ul post pri error while ORG_SEND_UDT state" ); ulLogState( tUl.uUlSide ,"ORG_SEND_UDT" ); tUl.uUlState++; tUl.uUlStateInterval = 0; return; case ORG_RECV_UDT: //PRN ack if( SpSubmit ( &tSpPri , 3) ) { WxcAssert ( tSpPri.uUiPri == N_UNITDATA_IND, "ul recv pri error while ORG_RECV_UDT state" ); ulLogMsg ( &tSpPri, 0 , &pUPri->tPriNUDataInd.tUD); tUl.uUlState++; tUl.uUlStateInterval = 0; ulLogState( tUl.uUlSide ,"ORG_RECV_UDT" ); return ; } break; case ORG_CR: //CM LU tSpPri.uUiPri = N_CONNECT_REQ; ul_sccp_addr ( &pUPri->tPriNConnReq.tCDA ); pUPri->tPriNConnReq.uOptFlag = 0x08; pUPri->tPriNConnReq.tUD.uDataLen = aiflu_cr_msg_len; memcpy ( &pUPri->tPriNConnReq.tUD.aUserData, aiflu_cr_msg, pUPri->tPriNConnReq.tUD.uDataLen ); ulLogMsg ( &tSpPri, 1 , &pUPri->tPriNConnReq.tUD); WxcAssert ( PostSp ( &tSpPri ), "ul post pri error while ORG_CR state" ); tUl.wConnId = tSpPri.wConnId; WxcAssert ( tUl.wConnId < CO_CS_MPORT, "wConnId error " ); tUl.uUlState++; tUl.uUlStateInterval = 0; ulLogState( tUl.uUlSide ,"ORG_CR" ); return; case ORG_CC: //CC if( SpSubmit ( &tSpPri , 3) ) { WxcAssert ( tSpPri.uUiPri == N_CONNECT_CFM, "ul recv pri error while ORG_CC state" ); ulLogMsg ( &tSpPri, 0 , &pUPri->tPriNConnCfm.tUD); tUl.uUlState++; tUl.uUlStateInterval = 0; ulLogState( tUl.uUlSide ,"ORG_CC" ); return ; } break; case ORG_LUR: //lu reject if( SpSubmit ( &tSpPri , 3) ) { WxcAssert ( tSpPri.uUiPri == N_DATA_IND, "ul recv pri error while ORG_LUR state" ); ulLogMsg ( &tSpPri, 0 , &pUPri->tPriNDataInd.tUD); tUl.uUlState++; tUl.uUlStateInterval = 0; ulLogState( tUl.uUlSide ,"ORG_LUR" ); return ; } break; case ORG_CLCD: //clean command if( SpSubmit ( &tSpPri , 3) ) { WxcAssert ( tSpPri.uUiPri == N_DATA_IND, "ul recv pri error while ORG_CLCD state" ); ulLogMsg ( &tSpPri, 0 , &pUPri->tPriNDataInd.tUD); tUl.uUlState++; tUl.uUlStateInterval = 0; ulLogState( tUl.uUlSide ,"ORG_CLCD" ); return ; } break; case ORG_CLCE: //clean complete tSpPri.uUiPri = N_DATA_REQ; pUPri->tPriNDataReq.tUD.uDataLen = aifclce_dt1_msg_len; memcpy ( &pUPri->tPriNDataReq.tUD.aUserData, aifclce_dt1_msg, pUPri->tPriNDataReq.tUD.uDataLen ); ulLogMsg ( &tSpPri, 1 , &pUPri->tPriNDataReq.tUD); WxcAssert ( PostSp ( &tSpPri ), "ul post pri error while ORG_CLCE state" ); tUl.uUlState++; tUl.uUlStateInterval = 0; ulLogState( tUl.uUlSide ,"ORG_CLCE" ); return; case ORG_DISCONN: if( SpSubmit ( &tSpPri , 3) ) { WxcAssert ( tSpPri.uUiPri == N_DISCONNECT_IND, "ul recv pri error while ORG_RLSD state" ); ulLogMsg ( &tSpPri, 0 , NULL ); tUl.uUlState++; tUl.uUlStateInterval = 0; ulLogState( tUl.uUlSide ,"ORG_CLCE" ); return ; } break; default: printf ( "\n\n\n======================SP Org Test End=================\n\n\n" ); exit(1); break; } if( ORG_IDLE == tUl.uUlState ) { if( tUl.uUlTestStartTimer++ >= tUl.uWaitTimer ) { printf ( "\n\n\n======================SP Org Test Start=================\n\n\n" ); tUl.uUlState++; } } else { if( tUl.uUlStateInterval++ >= 200 ) { //WxcAssert ( tUl.uUlState != ORG_RECV_UDT, "ORG_RECV_UDT state timer out" ); //WxcAssert ( tUl.uUlState != ORG_CC, "ORG_CC state timer out" ); //WxcAssert ( tUl.uUlState != ORG_LUR, "ORG_LUR state timer out" ); //WxcAssert ( tUl.uUlState != ORG_CLCD, "ORG_CLCD state timer out" ); //WxcAssert ( tUl.uUlState != ORG_DISCONN, "ORG_DISCONN state timer out" ); tUl.uUlStateInterval = 0; } } } else { switch ( tUl.uUlState ) { case DST_IDLE: break; case DST_RECV_UDT: //PRN if( SpSubmit ( &tSpPri , 3) ) { WxcAssert ( tSpPri.uUiPri == N_UNITDATA_IND, "ul recv pri error while DST_RECV_UDT state" ); ulLogMsg ( &tSpPri, 0 ,&pUPri->tPriNUDataInd.tUD); tUl.uUlState++; tUl.uUlStateInterval = 0; ulLogState( tUl.uUlSide ,"DST_RECV_UDT" ); return ; } break; case DST_SEND_UDT: //PRN ack tSpPri.uUiPri = N_UNITDATA_REQ; ul_sccp_addr ( &pUPri->tPriNUDataReq.tCDA ); ul_sccp_addr ( &pUPri->tPriNUDataReq.tCGA ); pUPri->tPriNUDataReq.tRO.uRO = 1; pUPri->tPriNUDataReq.tUD.uDataLen = aifprnak_udt_msg_len; memcpy ( &pUPri->tPriNUDataReq.tUD.aUserData, aifprnak_udt_msg, pUPri->tPriNUDataReq.tUD.uDataLen ); ulLogMsg ( &tSpPri, 1 , &pUPri->tPriNUDataReq.tUD); WxcAssert ( PostSp ( &tSpPri ), "ul post pri error while DST_SEND_UDT state" ); tUl.uUlState++; tUl.uUlStateInterval = 0; ulLogState( tUl.uUlSide ,"DST_SEND_UDT" ); return; case DST_CR: //CM LU if( SpSubmit ( &tSpPri , 3) ) { WxcAssert ( (tSpPri.uUiPri == N_CONNECT_IND), "ul recv pri error while DST_CR state" ); ulLogMsg ( &tSpPri, 0 , &pUPri->tPriNConnInd.tUD); tUl.uUlState++; tUl.uUlStateInterval = 0; ulLogState( tUl.uUlSide ,"DST_CR" ); return ; } break; case DST_CC: //CC tSpPri.uUiPri = N_CONNECT_RSP; tSpPri.wConnId = tUl.wConnId; pUPri->tPriNConnRsp.tUD.uDataLen = aifcc_dt1_msg_len; pUPri->tPriNConnRsp.uOptFlag = 0x00; ulLogMsg ( &tSpPri, 1 , &pUPri->tPriNConnRsp.tUD ); WxcAssert ( PostSp ( &tSpPri ), "ul post pri error while DST_CC state" ); WxcAssert ( tUl.wConnId < CO_CS_MPORT, "wConnId error " ); tUl.uUlState++; tUl.uUlStateInterval = 0; ulLogState( tUl.uUlSide ,"DST_CC" ); return; case DST_LUR: //lu reject tSpPri.uUiPri = N_DATA_REQ; tSpPri.wConnId = tUl.wConnId; pUPri->tPriNDataReq.tUD.uDataLen = aiflurj_dt1_msg_len; memcpy ( &pUPri->tPriNDataReq.tUD.aUserData, aiflurj_dt1_msg, pUPri->tPriNDataReq.tUD.uDataLen ); ulLogMsg ( &tSpPri, 1 , &pUPri->tPriNDataReq.tUD); WxcAssert ( PostSp ( &tSpPri ), "ul post pri error while DST_LUR state" ); tUl.uUlState++; tUl.uUlStateInterval = 0; ulLogState( tUl.uUlSide ,"DST_LUR" ); return; case DST_CLCD: //clean command tSpPri.uUiPri = N_DATA_REQ; tSpPri.wConnId = tUl.wConnId; pUPri->tPriNDataReq.tUD.uDataLen = aifclcd_dt1_msg_len; memcpy ( &pUPri->tPriNDataReq.tUD.aUserData, aifclcd_dt1_msg, pUPri->tPriNDataReq.tUD.uDataLen ); ulLogMsg ( &tSpPri, 1 ,&pUPri->tPriNDataReq.tUD); WxcAssert ( PostSp ( &tSpPri ), "ul post pri error while DST_CLCD state" ); tUl.uUlState++; tUl.uUlStateInterval = 0; ulLogState( tUl.uUlSide ,"DST_CLCD" ); return; case DST_CLCE: //clean complete if( SpSubmit ( &tSpPri , 3) ) { WxcAssert ( tSpPri.uUiPri == N_DATA_IND, "ul recv pri error while DST_CLCE state" ); ulLogMsg ( &tSpPri, 0 , &pUPri->tPriNDataInd.tUD); tUl.uUlState++; tUl.uUlStateInterval = 0; ulLogState( tUl.uUlSide ,"DST_CLCE" ); return ; } break; case DST_DISCONN: tSpPri.uUiPri = N_DISCONNECT_REQ; tSpPri.wConnId = tUl.wConnId; pUPri->tPriNDisconnReq.eREA = REA_UDISC_EUF; pUPri->tPriNDisconnReq.tUD.uDataLen = aiflu_rlsd_msg_len; pUPri->tPriNDisconnReq.uOptFlag = 0x00; ulLogMsg ( &tSpPri, 1 , NULL); WxcAssert ( PostSp ( &tSpPri ), "ul post pri error while DST_DISCONN state" ); tUl.uUlState++; tUl.uUlStateInterval = 0; ulLogState( tUl.uUlSide ,"DST_DISCONN" ); return; default: printf ( "\n\n\n======================SP Dst Test End=================\n\n\n" ); exit(1); break; } if( DST_IDLE == tUl.uUlState ) { if( tUl.uUlTestStartTimer++ >= tUl.uWaitTimer ) { printf ( "\n\n\n======================SP Dst Test Start=================\n\n\n" ); tUl.uUlState++; tUl.uUlStateInterval = 0; } } else { if( tUl.uUlStateInterval++ >= 200 ) { //WxcAssert ( tUl.uUlState != DST_RECV_UDT, "DST_RECV_UDT state timer out" ); //WxcAssert ( tUl.uUlState != DST_CR, "DST_CR state timer out" ); //WxcAssert ( tUl.uUlState != DST_CLCE, "DST_CLCE state timer out" ); tUl.uUlStateInterval = 0; } } } } void ll_cr ( ) { } void ll_cc ( ) { } void ll_cref ( ) { } void ll_rlsd ( ) { } void ll_rlc ( ) { } void ll_udt ( ) { } void ll_dt1 ( ) { } void ll_sap ( ) { }