#include	<stdio.h>
#include	<stdlib.h>
#include	<errno.h>
#include	<stdarg.h>
#include	<string.h>
#include	<ctype.h>
#include	<sys/types.h>
#include	<sys/time.h>
#include	<time.h>
#include	<sys/ipc.h>
#include	<sys/shm.h>
#include 	<arpa/inet.h>
#include	<sys/socket.h>
#include	<sys/io.h>
#include	<netdb.h>
#include    "scoc_if.h"
#include    "../../../public/src/include/includes.h"  

#ifndef _SCCP_CONST_DEF
#define _SCCP_CONST_DEF

#define SCCP_CONF_FILE	    "./conf/sccp.conf"
#define SINGLE_MODE			1
#define spLogDebug_MASK		0xFFFFFFFF


#define GetValueString(i,p,Maxtrix,IdMax)                      \
        {                                                        \
            if( (i) >= (IdMax) )                                 \
            {                                                    \
        	    (p) = (u8 *)Maxtrix[(IdMax)].pStr;                     \
        	}                                                    \
            else                                                 \
            {                                                    \
        	    (p) = (u8 *)Maxtrix[(i)].pStr;                         \
        	}                                                    \
        }


typedef enum SCCP_WATCH_DOG
{
	WDS_RECV_PRI,
	
}
SP_WatchDog;

#define SCCP_SHM_KEY		0x00116688
#define SCCP_SHM_PERM		0666
//#define SCCP_OID			{1,3,6,1,4,1,1373,1,3,2,2,3}
#define SCCP_OID			{1,3,6,1,4,1,1373,2,3,2,3}
#define SCCP_OIDLEN			11
#define SCCP_SERNUM_LEN		4

/*Message type-----> */
#define CR_MSG			1
#define CC_MSG			2
#define CREF_MSG		3
#define RLSD_MSG		4
#define RLC_MSG			5
#define DT1_MSG			6
#define DT2_MSG			7
#define AK_MSG			8
#define UDT_MSG			9
#define UDTS_MSG		10
#define ED_MSG			11
#define EA_MSG			12
#define RSR_MSG			13
#define RSC_MSG			14
#define ERR_MSG			15
#define IT_MSG			16
#define XUDT_MSG		17
#define XUDTS_MSG		18
#define LUDT_MSG		19
#define LUDTS_MSG		20
//Intra message type
#define RF_MSG			100
/*SCMG Message */
#define SSA_MSG		1       //subsystem allowed
#define SSP_MSG		2       //subsystem prohibited
#define SST_MSG		3       //subsystem status test
#define SOR_MSG		4       //subsystem out of service request
#define SOG_MSG		5       //subsystem out of service grant
#define SSC_MSG		6       //SCCP/subsystem congested
/*SCCP parameter name codes */
#define P_EOP		0
#define	P_DLR		1
#define P_SLR		2
#define P_CDA		3
#define P_CGA		4
#define P_PLC		5
#define P_EOD		6
#define P_PR		7
#define P_SEQ		8
#define P_Credit	9
#define P_RLC		10
#define P_RTC		11
#define P_RSC		12
#define P_ERC		13
#define P_RFC				14
#define P_Data				15
#define P_SEG				16
#define P_HC				17
#define P_Importance		18
#define P_Ldata				19
//////////////////////////////////////////////////
#define SCCP_SSN_NUM		256
#define SCCP_RLSSN_NUM		128
#define SCCP_RLSPC_NUM		64
#define SCCP_ROUTE_NUM		1024
#define SCCP_ROUTE_NODE_NUM	65535

#define LR_NUM			1024
#define LR_MSG_NUM		50
#define	SS_MSG_NUM		1024
#define SLS_NUM			16
#define SCCP_MSG_MAXLEN	256
#define MAX_HC			15
#define SCOC_SSN		10

#define Unrestricted	1
#define Restricted		0

#define RI_GT	0               //Route on GT
#define RI_SSN	1               //Route on SSN

#define NP_IMSI		6
#define NP_MSISDN	1
#define NP_GT		7

#define TT_0		0
#define TT_1		1
#define TT_4		4
//message source---->
#define FROM_MTP	1
#define FROM_SCLC	2
#define FROM_SCOC	3
#define FROM_SCMG	4
//subsystem number
#define SSN_NOTUSE	0
#define SSN_SCMG	1
#define SSN_ITU		2       //reserved for ITU-T allocation
#define SSN_ISUP	3
#define SSN_OMC		4
#define SSN_MAP		5
#define SSN_HLR		6
#define SSN_VLR		7
#define SSN_MSC		8
#define SSN_EIC		9       //Equipment Identifier Certer
#define SSN_RANAP 142
#define SSN_AIF   254

//pool size
#define SP_POOL_SIZE 3

//scoc state
#define	SCOC_IDLE		0
#define	SCOC_CPO		1       //connection pending outgoing
#define SCOC_CPI		2       //connection pending incoming
#define SCOC_CPMID		3       //connection pending(intermediate node)
#define SCOC_WCC		4       //Wait connection confirm
#define	SCOC_ACTIVE		5       //Active
#define SCOC_MID		6       //Active(intermediate node)
#define	SCOC_DP			7       //disconnect pending
#define	SCOC_DPMID		8       //disconnect pending(intermediate node)

#define SCOC_Interval	20*1000 //20ms
//Timer (SCMG)
#define T_idle		30      //(s)
#define T_sst		2       //20s interval = 10s
#define T_hbrecv	3       //30s interval = 10s

//#define SST_Start     0
//#define SST_Pend      1
//#define SST_Stop      2

//SP/SCCP/SS status
#define ST_Disable		1
#define ST_Congest		2
#define ST_Enable		3

#define SCCPDB_TCAP		0x01
#define SCCPDB_UDT		0x02
#define SCCPDB_AIF		0x04
#define SCCPDB_ERR		0x08
#define SCCPDB_SCMG		0x10
#define	SCCPDB_TIME		0x20
#define SCCPDB_SNMP		0x40
#define SCCPDB_MSG		0x80
#define SCCPDB_ADDR		0x100
#define	SCCPDB_STP		0x1000
#define SCCPDB_USER		0x2000
#define SCCPDB_MTP3		0x4000
#define SCCPDB_XUDT   0x8000

/*******************Release cause*******************/
#define RL_EUO	0               //end user originated
#define RL_EUC	1               //end user congestion
#define RL_EUF	2               //end user failure
#define RL_SUO	3               //SCCP user originated
#define RL_RPL	4               //remote procedure error
#define RL_ICD	5               //inconsistent connection data
#define RL_AF	6               //access failure
#define RL_AC	7               //access congestion
#define RL_SF	8               //subsystem failure
#define RL_SC	9               //subsystem congestion
#define RL_MF	10              //MTP failure
#define RL_NC	11              //network congestion
#define RL_EORT	12              //expiration of reset timer
#define RL_EORIT	13      //expriation of receive inactivity timer
#define RL_R		14      //reserved
#define RL_U		15      //unqualified
#define RL_SCCPF	16      //SCCP failure

/*******************return cause*******************/
#define RT_NTFN		0       //no translation for an address of such nature
#define RT_NTFA		1       //no translation for this specific address
#define RT_SC		2       //subsystem congestion
#define RT_SF		3       //subsystem failure
#define RT_UU		4       //unequipped user
#define RT_MF		5       //MTP failure
#define RT_NF		6       //network congestion
#define RT_U		7       //unqulified
#define RT_EIMT		8       //error in message transport
#define RT_EILP		9       //error in local processing
#define RT_DCPR		10      //destination cannot perform reassembly
#define RT_SCCPF	11      //SCCP failure
#define RT_HCV		12      //hop counter violation
#define RT_SNS		13      //segmentation not supported
#define RT_SMTF		14      //segmentation failure

/*******************reset cause*******************/
#define RS_EUO	0           //end user originated
#define RS_SUO	1           //SCCP user originated
#define RS_IPS	2           //incorrect P(S)
#define RS_IPR	3           //incorrect P(R)
#define RS_OFW	4           //remote procedure error-message out of window
#define RS_IPSAI	5       //remote procedure error-incorrect P(S) after initialization
#define RS_G		6       //remote procedure error-general
#define RS_REUO		7       //remote end user operational
#define RS_NO		8       //network operational
#define RS_AO		9       //access operational
#define RS_NC		10      //network congestion
#define RS_R		11      //reserved
#define RS_U		12      //unqualified

#endif

static const StringVal spUlPrimitiveStr[] = 
{
    {N_UNITDATA_REQ  , "N-Unit Data Request  "},
    {N_UNITDATA_IND  , "N-Unit Data Indicate "},
    {N_NOTICE_IND    , "N-Notice Indicate    "},
    {N_CONNECT_REQ   , "N-Connect Request    "},
    {N_CONNECT_IND   , "N-Connect Indicate   "},
    {N_CONNECT_RSP   , "N-Connect Response   "},
    {N_CONNECT_CFM   , "N-Connect Confirm    "},
    {N_DISCONNECT_REQ, "N-Disconnect Request "},
    {N_DISCONNECT_IND, "N-Disconnect Indicate"},
    {N_DATA_REQ      , "N-DATA Request       "},
    {N_DATA_IND      , "N-DATA Indicate      "},
    {N_DATAAK_REQ    , "N-DataAk Request     "},
    {N_DATAAK_IND    , "N-DataAk Indicate    "},
    {N_EDATA_REQ     , "N-EData Request      "},
    {N_EDATA_IND     , "N-EData Indicate     "},
    {N_RESET_REQ     , "N-Reset Request      "},
    {N_RESET_IND     , "N-Reset Indicate     "},
    {N_RESET_RSP     , "N-Reset Response     "},
    {N_RESET_CFM     , "N-Reset Confirm      "},
    {N_INFORM_REQ    , "N-Inform Request     "},
    {N_INFORM_IND    , "N-Inform Indicate    "},
    {SPUI_PRI_MAX    , "Unknow SCCP Primitive"},
};

#define spGetUlPrimitiveStr(e,p)\
        GetValueString(e,p,spUlPrimitiveStr,SPUI_PRI_MAX)

typedef enum SCOC_MESSAGE_TYPE
{
    SP_MSG0_RESERVED,           /* Reserved                   */
    SP_MSG_CR   = 1,            /* connection request         */
    SP_MSG_CC   = 2,            /* connection confirm         */
    SP_MSG_CREF = 3,            /* connection refused         */
    SP_MSG_RLSD = 4,            /* release request            */
    SP_MSG_RLC  = 5,            /* release confirm            */
    SP_MSG_DT1  = 6,            /* Data Form 1                */
    SP_MSG_DT2  = 7,            /* Data Form 2                */
    SP_MSG_AK   = 8,            /* Data acknowledge           */
    SP_MSG_UDT  = 9,            /* Unit data                  */
    SP_MSG_UDTS = 10,           /* Unit data                  */
    SP_MSG_ED   = 11,           /* Expedited data             */
    SP_MSG_EA   = 12,           /* Expedited data acknowledge */
    SP_MSG_RSR  = 13,           /* Reset request              */
    SP_MSG_RSC  = 14,           /* Reset confirm              */
    SP_MSG_ERR  = 15,           /* PDU error                  */
    SP_MSG_IT   = 16,           /* Inactivity test            */
    SP_MSG_XUDT = 17,           /* XUDT                       */
    SP_MSG_XUDTS= 18,           /* XUDTS                      */
    SP_MSG_LUDT = 19,           /* LUDT                       */
    SP_MSG_LUDTS= 20,           /* LUDTS                      */
    SP_MSG_RF   = 21,           /* Routing Fail               */
    SP_MSG_MAX      ,           /* MAX message type undefine  */
}
CO_MsgType;

static const StringVal sp_messagetype_str[] = 
{
    {SP_MSG0_RESERVED, " Message Reserved"     },  
    {SP_MSG_CR,        " Connection request"   },
    {SP_MSG_CC,        " Connection confirm"   },
    {SP_MSG_CREF,      " Connection refused"   },
    {SP_MSG_RLSD,      " Release request"      },
    {SP_MSG_RLC,       " Release confirm"      },
    {SP_MSG_DT1,       " Data Form 1"          },
    {SP_MSG_DT2,       " Data Form 2"          },
    {SP_MSG_AK,        " Data acknowledge"     },
    {SP_MSG_UDT,       " Unit data"            },
    {SP_MSG_UDTS,      " Unit data service"    },
    {SP_MSG_ED,        " Data acknowledge"     },
    {SP_MSG_EA,        " EData  acknowledge"   },
    {SP_MSG_RSR,       " Reset request"        },
    {SP_MSG_RSC,       " Reset confirm"        },
    {SP_MSG_ERR,       " PDU error"            },
    {SP_MSG_IT,        " Inactivity test"      },
    {SP_MSG_XUDT,      " XUDT"                 },
    {SP_MSG_XUDTS,     " XUDTS"                },
    {SP_MSG_LUDT,      " LUDT"                 },
    {SP_MSG_LUDTS,     " LUDTS"                },
    {SP_MSG_RF ,       " Routing Fail"         },
    {SP_MSG_MAX,       " Undefine"             },
};

#define spGetMsgStr(MsgId,pStr)\
        GetValueString(MsgId,pStr,sp_messagetype_str,SP_MSG_MAX)

//temp define , define in pub_base.h
#define STR(s)                      #s
#define FILL_VALSTR(n)              {n,#n}

static const StringVal spTimerOutStr[] = 
{
   FILL_VALSTR(T_CONNEST_OUT),
   FILL_VALSTR(T_IAS_OUT),
   FILL_VALSTR(T_IAR_OUT),
   FILL_VALSTR(T_REPEATE_RLS_OUT),
   FILL_VALSTR(T_RLS_OUT),
   FILL_VALSTR(T_RESET_OUT),
   FILL_VALSTR(T_GUARD_OUT),
   FILL_VALSTR(T_INTERNAL_OUT),
   FILL_VALSTR(SPTM_PRI_MAX),  
};

#define spGetTimerOutStr(MsgId,pStr)\
        GetValueString(((MsgId)-SPCR_PRI_MAX-1),pStr,spTimerOutStr,SPTM_PRI_MAX)


#define T_UNDEFINE        100000

#define T_SP_10ms         1
#define T_SP_1s           T_SP_10ms*100
#define T_SP_1MIN         T_SP_1s*60
#define T_CONNEST_MAX     T_SP_1s*2     //1~2   sec
#define T_IAS_MAX         T_SP_1MIN*5   //5~10  mins
#define T_IAR_MAX         T_SP_1MIN*11  //11~21 mins
#define T_RLS_MAX         T_SP_1s*15    //10~20 sec
#define T_REPEATE_RLS_MAX T_SP_1s*15    //10~20 sec
#define T_RESET_MAX       T_SP_1s*15    //10~20 sec
#define T_GUARD_MAX       T_SP_1MIN*24  //23~25 mins
#define T_INTERNAL_MAX    T_SP_1MIN     //1 mins

typedef enum SCOC_TRANSITION_STATUS
{
    CO_STATUS_INIT,             //Transtion initialed
    CO_STATUS_IDLE,             //status Idle
    CO_STATUS_WTCC,             //Wait Connection confirm
    CO_STATUS_ACTV,             //Active
    CO_STATUS_CONP,             //Connection pending 
    CO_STATUS_CPIC,             //Connection pending incoming
    CO_STATUS_CPOG,             //Connection pending outgoing
    CO_STATUS_DSCP,             //Disconnect pending
    CO_STATUS_DPIC,             //Disconnect pending incoming
    CO_STATUS_DPOG,             //Disconnect pending outgoing
    CO_STATUS_DPBH,             //Disconnect pending both
    CO_STATUS_NMOP,             //Normal operation
    CO_STATUS_WSEA,             //Wait for sending EA Message
    CO_STATUS_RSIC,             //Reset outgoing
    CO_STATUS_RSOG,             //Reset incoming
    CO_STATUS_RSBH,             //Reset both
    CO_STATUS_MTBK,             //Maintenance blocking
    CO_STATUS_RSTA,             //Restart 
    CO_STATUS_MAX,
}
CO_Status;

static const StringVal sp_co_state_str[] = 
{
    {CO_STATUS_INIT, "Transtion initialed"        },
    {CO_STATUS_IDLE, "status Idle"                },
    {CO_STATUS_WTCC, "Wait Connection confirm"    },
    {CO_STATUS_ACTV, "Active"                     },
    {CO_STATUS_CONP, "Connection pending "        },
    {CO_STATUS_CPIC, "Connection pending incoming"},
    {CO_STATUS_CPOG, "Connection pending outgoing"},
    {CO_STATUS_DSCP, "Disconnect pending"         },
    {CO_STATUS_DPIC, "Disconnect pending incoming"},
    {CO_STATUS_DPOG, "Disconnect pending outgoing"},
    {CO_STATUS_DPBH, "Disconnect pending both"    },
    {CO_STATUS_NMOP, "Normal operation"           },
    {CO_STATUS_WSEA, "Wait for sending EA Message"},
    {CO_STATUS_RSIC, "Reset outgoing"             },
    {CO_STATUS_RSOG, "Reset incoming"             },
    {CO_STATUS_RSBH, "Reset both"                 },
    {CO_STATUS_MTBK, "Maintenance blocking"       },
    {CO_STATUS_RSTA, "Restart"                    },
    {CO_STATUS_MAX, "Error Transtion state"       },
};

#define spGetCoStateStr(s,p)\
        GetValueString(s,p,sp_co_state_str,CO_STATUS_MAX)

typedef enum CO_INSTANCE_SIDE
{
    CO_INST_SIDE_ORG,
    CO_INST_SIDE_DST,
    CO_INST_SIDE_MID,
    CO_INST_SIDE_MAX,
}
CO_InstSide;

static const StringVal sp_co_instanceside_str[] = 
{
    {CO_INST_SIDE_ORG, "Originating node side"   },
    {CO_INST_SIDE_DST, "Destination node side"   },
    {CO_INST_SIDE_MID, "intermidediate node side"},
    {CO_INST_SIDE_MAX, "Undefine Node Side"      },
};

#define spGetCoInstanceSide(s,p)\
        GetValueString(s,p,sp_co_instanceside_str,CO_INST_SIDE_MAX)

static const StringVal co_reason_str[] = {
    //reason : originated network serice provider
    {REA_PDISC_ACNN,
     "disconnection ¨Cabnormal condition(non-transient nature)"               },
    {REA_PDISC_ACTN,  "disconnection ¨Cabnormal condition of transient nature"},
    {REA_PDISC_IS,    "disconnection ¨Cinvalid state1"                        },
    {REA_PDISC_RIP,   "disconnection ¨Crelease in progress1"                  },
    {REA_PCREF_DAU,   "CREF2 ¨Cdestination address unknown "                  },
    {REA_PCREF_DINC,
     "CREF2 ¨Cdestination inaccessible/non-transient condition"               },
    {REA_PCREF_DITCs, "CREF2 ¨Cdestination inaccessible/transient condition"  },
    {REA_PCREF_QNANC, "CREF2 ¨CQOS not available/non-transient condition"     },
    {REA_PCREF_QNATC, "CREF2 ¨CQOS not available/transient condition"         },
    {REA_PCREF_RUNC,  "CREF2 ¨Creason unspecified/non-transient condition"    },
    {REA_PCREF_RUTC,  "CREF2 ¨Creason unspecified/transient condition"        },
    {REA_PCREF_LE,    "CREF2 ¨Clocal error1"                                  },
    {REA_PCREF_IS,    "CREF2 ¨Cinvalid state1"                                },
    {REA_PCREF_NT,    "CREF2 ¨Cno translation1"                               },
    {REA_PCREF_IRP,   "CREF2 ¨Cin restart phase1"                             },
    {REA_PCREF_HCV,   "CREF2 ¨Chop counter violation"                         },

    //reason : originated network serice user
    {REA_UDISC_NC,    "disconnection ¨Cnormal condition"                      },
    {REA_UDISC_ABC,    "disconnection ¨Cabnormal condition"                    },
    {REA_UDISC_EUC,   "disconnection ¨Cend user congestion"                   },
    {REA_UDISC_EUF,   "disconnection ¨Cend user failure"                      },
    {REA_UDISC_SUO,   "disconnection ¨CSCCP user originated"                  },
    {REA_UDISC_ACC,    "disconnection ¨Caccess congestion"                     },
    {REA_UDISC_AF,    "disconnection ¨Caccess failure"                        },
    {REA_UDISC_SC,    "disconnection ¨Csubsystem congestion"                  },
    {REA_UCREF_NTC,   "CREF2¨Cnon-transient condition"                        },
    {REA_UCREF_TC,    "CREF2¨Ctransient condition"                            },
    {REA_UCREF_IIIN,  "CREF2¨Cincompatible information in NSDUs"              },
    {REA_UCREF_EUO,   "CREF2¨Cend user originated"                            },
    {REA_UCREF_EUC,   "CREF2¨Cend user congestion"                            },
    {REA_UCREF_EUF,   "CREF2¨Cend user failure"                               },
    {REA_UCREF_SUO,   "CREF2 ¨CSCCP user originated"                          },
    {REA_UCREF_ACC,    "CREF2 ¨Caccess congestion"                             },
    {REA_UCREF_AF,    "CREF2 ¨Caccess failure"                                },
    {REA_UCREF_SC,    "CREF2 ¨Csubsystem congestion"                          },

    //Notice service reason : N-inform values
    {REA_NINFO_FAIL,  "work service provider failure"                         },
    {REA_NINFO_CONG,  "work service congestion"                               },
    {REA_NINFO_PQC,   "work service provider QOS change"                      },
    {REA_UINFO_FAIL,  "work service user failure"                             },
    {REA_UINFO_CONG,  "work service user congestion"                          },
    {REA_UINFO_PQC,   "work service user QOS change"                          },
    {REA_INFO_USPC,   "reason unspecified"                                    },

    {REA_UNDEFINED, "Undefined"                                             },
};

#define coGetReasonStr(r,p)\
        GetValueString(r,p,co_reason_str,REA_UNDEFINED)


typedef enum SCOC_INTERNAL_ERROR
{
	CO_FATAL_STATE,
	CO_FATAL_SIDE,
}
CO_InterErr;

