#ifndef _MGC_H
#define _MGC_H

#define MGC_MAX_NUM_OF_SAP          5
#define MGC_MAX_USER_NAME_LEN       32
#define MGC_MAX_DOMAIN_LEN          64

#define MGC_MAX_PHY_PORT_PER_MG     32
#define MGC_MAX_CHNL_NUM_PER_PHY    1024
#define MGC_MAX_NUM_OF_CHNL_CON          512
#define MGC_MAX_NUM_OF_CON        8192

#define MGC_MAX_OPER_STEPS_NUM		15


#define MGC_MAX_NUM_OF_MG           1024
#define MGC_MAX_NUM_OF_PHY_PORT     1024
#define MGC_MAX_NUM_OF_CHNL         9424
#define MGC_MAX_NUM_OF_PORT         8192
#define MGC_MAX_NUM_OF_SESS         1024
#define MGC_MAX_NUM_OF_RTP_PROXY_SESS 4096



#define MGC_MGCF_TIMER_50MS			5
#define MGC_MGCF_TIMER_20MS			2
#define MGC_MGCF_TIMER_1S			100
#define MGC_MGCF_TIMER_10S			10 * MGC_MGCF_TIMER_1S
#define MGC_MGCF_TIMER_20S			20 * MGC_MGCF_TIMER_1S
#define MGC_MGCF_TIMER_1H           3600 * MGC_MGCF_TIMER_1S


#define MGC_CHNL_NUM_INTERNAL_PER_PORT	1024
#define MGC_CHNL_NUM_AALN_PER_PORT		1
#define MGC_CHNL_NUM_ANN_PER_TYPE	    200
#define MGC_CHNL_NUM_DS_PER_PORT		32
#define MGC_CHNL_NUM_TANDEM_PER_TYPE		1024
#define MGC_CHNL_NUM_SERVEILLANCE_PER_TYPE 1024

#define MGC_HOLD_MUSIC              7
#define MGC_TONE_RING               8
#define MGC_TONE_BUSY               9
#define MGC_TONE_WARN               10



#define MGC_MGCP_MGC_PORT			2727
#define MGC_MGCP_MG_PORT			2427

#define MGC_MG_NETWORK_PORT         4967
#define MGC_MGC_NETWORK_PORT        4966

#define MGC_OPERA_NO_DELAY  0
#define MGC_CONNECT_SILENT_TONE     0x01


#define MGC_MAX_NUM_OF_TANDEM 4096
#define MGC_MAX_NUM_OF_RTP_PROXY_NUM 2

#define MGC_MAX_NUM_OF_TANDEM_CONN (MGC_MAX_NUM_OF_TANDEM*2)
#define MGC_MAX_NUM_OF_TANDEM_CHNL (MGC_MAX_NUM_OF_TANDEM)
#define MGC_TANDEM_CONN_STAR_ID (MGC_MAX_NUM_OF_CON)
#define MGC_TANDEM_CHNL_STAR_ID (MGC_MAX_NUM_OF_CHNL)
#define MGC_TANDEM_PHY_PORT_STAR_ID (MGC_MAX_NUM_OF_PHY_PORT)


#define MGC_MAX_NUM_OF_SURVEILLANCE_NUM 2
#define MGC_MAX_NUM_OF_SURVEILLANCE_CONN 1024
#define MGC_MAX_NUM_OF_SURVEILLANCE_NODE (MGC_MAX_NUM_OF_SURVEILLANCE_CONN)
#define MGC_MAX_NUM_OF_SURVEILLIANCE_CHNL (MGC_MAX_NUM_OF_SURVEILLANCE_CONN)
#define MGC_SURVEILLIANCE_CONN_STAR_ID (MGC_TANDEM_CONN_STAR_ID+MGC_MAX_NUM_OF_TANDEM_CONN)
#define MGC_SURVEILLIANCE_CHNL_STAR_ID (MGC_TANDEM_CHNL_STAR_ID+MGC_MAX_NUM_OF_TANDEM_CHNL)
#define MGC_SURVEILLIANCE_PHY_PORT_STAR_ID (MGC_TANDEM_PHY_PORT_STAR_ID+ MGC_MAX_NUM_OF_RTP_PROXY_NUM)

#include "../../../public/src/include/includes.h"
#include "../../../public/src/include/public.h"
#include "../../../public/src/include/license_id.h"
#include "../../../public/src/include/pub_sdp.h"
//#include "../../../mgcp/src/include/mgcp.h"


typedef enum
{	
    MGC_RESULT_LACK_PARA = -4,
    MGC_RESULT_NO_RES = -3 ,	
	MGC_RESULT_INPUT_ILLEGAL = -2,	
	MGC_RESULT_FAILURE = -1,
	MGC_RESULT_OK = 0,
	MGC_RESULT_8ECP_OK = 1
}MGC_RESULT;

typedef enum{
    MGC_DTMF_1 = 1,
	MGC_DTMF_2 = 2,	
    MGC_DTMF_3 = 3,
	MGC_DTMF_4 = 4,
    MGC_DTMF_5 = 5,
	MGC_DTMF_6 = 6,
    MGC_DTMF_7 = 7,
	MGC_DTMF_8 = 8,
    MGC_DTMF_9 = 9,
	MGC_DTMF_0 = 10,
    MGC_DTMF_START = 11,
	MGC_DTMF_POUND = 12	
}MGC_DTMF_DEF;

typedef enum{
    MGC_PKG_L = 0,
	MGC_PKG_D = 1,
	MGC_PKG_G = 2
}MGC_PKG_TYPE;


typedef enum
{
    MGC_USER_TYPE_UNDEF = -1,
    MGC_USER_TYPE_MGC = 0,
    MGC_USER_TYPE_MG = 1
}MGC_USER_TYPE;

typedef enum
{
    MGC_CONNECT_STATUS_UNDEF = -1,
    MGC_CONNECT_STATUS_IDLE ,
    MGC_CONNECT_STATUS_CREATING ,
    MGC_CONNECT_STATUS_CREATE,
    MGC_CONNECT_STATUS_CREATED
}MGC_CONNECT_STATUS;

typedef enum
{
    MGC_CON_MODE_UNDEF = -1,
    MGC_CON_MODE_INACTIVE ,
    MGC_CON_MODE_RECVONLY ,
    MGC_CON_MODE_SENDONLY ,
    MGC_CON_MODE_SENDRECV ,
    MGC_CON_MODE_OWN
}MGC_CON_MODE;

typedef enum
{
    MGC_CHNL_INFO_STATUS_UNDEF = -1,
	MGC_CHNL_INFO_STATUS_IDLE,
	MGC_CHNL_INFO_STATUS_USED
}MGC_CHNL_INFO_STATUS;


typedef enum
{
    MGC_PHY_PORT_STATUS_UNDEF = -1,
	MGC_PHY_PORT_STATUS_OFF_LINE,
	MGC_PHY_PORT_STATUS_ON_LINE
}MGC_PHY_PORT_STATUS;


typedef enum
{
    MGC_PHY_PORT_TYPE_UNDEF = -1,
    MGC_PHY_PORT_TYPE_E1 = 1 ,
    MGC_PHY_PORT_TYPE_T1 = 2 ,
    MGC_PHY_PORT_TYPE_ANALOG ,
    MGC_PHY_VIRTUAL_TYPE_ANN,
    MGC_PHY_VIRTUAL_TYPE_INTERNAL,
    MGC_PHY_VIRTUAL_TYPE_TANDEM,
    MGC_PHY_VIRTUAL_TYPE_SURVEILLANCE
}MGC_PHY_PORT_TYPE;


typedef enum
{
    MGC_MG_CTRL_TYPE_UNDEF = -1,
	MGC_MG_CTRL_TYPE_MGCP,
	MGC_MG_CTRL_TYPE_8ECP
}MGC_MG_CTRL_TYPE;


typedef enum
{
    MGC_MG_TYPE_UNDEF = -1,
	MGC_MG_TYPE_INTERNAL = 0 ,
	MGC_MG_TYPE_AudioCoder = 1 ,
	MGC_MG_TYPE_LGC_MG = 2,
	MGC_MG_TYPE_SSW_CSS = 3 ,
	MGC_MG_TYPE_IPBSS =4 ,	
	MGC_MG_TYPE_ANALOG = 11 ,	
	MGC_MG_TYPE_TANDEM = 20,
	MGC_MG_TYPE_ANN =21 	
}MGC_MG_TYPE;


typedef enum
{
    MGC_OPER_ID_UNDEF =-1,
    MGC_OPER_ID_CONNECT_CHNL = 1,
    MGC_OPER_ID_CONNECT_DTMF = 2,		
    MGC_OPER_ID_CONNECT_TONE =3,
    MGC_OPER_ID_CRCX = 4,
    MGC_OPER_ID_MDCX = 5,
    MGC_OPER_ID_DLCX = 6,
    MGC_OPER_ID_RQNT = 7,
    MGC_OPER_ID_AUEP = 8,
    MGC_OPER_ID_CONNECT_AAS = 9,
    MGC_OPER_ID_TANDEM_CREATE,
    MGC_OPER_ID_TANDEM_SET_TAR,
    MGC_OPER_ID_TANDEM_UNSET_TAR,
    MGC_OPER_ID_TANDEM_CLEAR,
    MGC_OPER_ID_TANDEM_FORK_CHNL,
    MGC_OPER_ID_CREATE_VIRTUAL_CHNL,
    MGC_OPER_ID_RELEASE_VIRTUAL_CHNL,
    MGC_OPER_ID_UPDATE_CHNL_MEDIA,    
    MGC_OPER_ID_IND
}MGC_MG_OPER_ID_TYPE;

typedef enum
{
    MGC_CMD_UNDEF = -1,
    MGC_CMD_CRCX = 1, 
    MGC_CMD_MDCX ,
    MGC_CMD_DLCX ,
    MGC_CMD_RQNT ,
    MGC_CMD_NTFY ,
    MGC_CMD_AUEP ,
    MGC_CMD_RSIP ,
    MGC_CMD_NOP     //do noting 
}MGC_CMD_TYPE;

typedef enum
{
    MGCP_OPER_STEP_UNDEF =-1,
	MGCP_OPER_STEP_REQUEST,
	MGCP_OPER_STEP_REQUEST_SENT,
	MGCP_OPER_STEP_RESPONSE_GET,
/***************************************************
*     up status is used for MGC ,  following status is used for MG
*****************************************************/	
	MGCP_OPER_STEP_IND,
	MGCP_OPER_STEP_IND_SENT,
	MGCP_OPER_STEP_RESPONSE
}MGCP_OPER_STEP_STATUS;


typedef enum
{
	MGC_OPER_FAILURE = 0,
	MGC_OPER_SUCCESS = 1
}MGC_OPER_RESULT;


typedef enum
{
    MGC_VCTYPE_PCMA = 0 ,
	MGC_VCTYPE_PCMU = 1, 
	MGC_VCTYPE_GSM =2 ,
	MGC_VCTYPE_GSM_EFR = 3,
	MGC_VCTYPE_AMR_12_2 = 4,
	MGC_VCTYPE_G729B = 5,
	MGC_VCTYPE_AMR_10_2 = 6,
	MGC_VCTYPE_AMR_7_95 = 7,
	MGC_VCTYPE_AMR_7_4 = 8,
	MGC_VCTYPE_AMR_6_7 = 9,
    MGC_VCTYPE_AMR_5_15 = 10,
    MGC_VCTYPE_AMR_5_9 = 11,
    MGC_VCTYPE_AMR_4_75 = 12,
	MGC_VCTYPE_NUM,
	MGC_VCTYPE_UNSUPPORT
}MGC_VCTYPE;



typedef enum
{
    MGC_TANDEM_STATUS_UNDEF = -1,
	MGC_TANDEM_STATUS_IDLE,
	MGC_TANDEM_STATUS_USED
}MGC_TANDEM_STATUS;

typedef	struct _MGC_ESCCD
{
	char		domain[MGC_MAX_DOMAIN_LEN];
	WORD	port;
}MGC_ESCCD;


typedef struct _OPER_REC
{
    MGC_MG_OPER_ID_TYPE operaId;
    BYTE tone;
	WORD duration;
	WORD times;
}OPER_REC;


typedef struct _CHNL
{
    WORD    mgNo;       // mg No.
    BYTE    portNo;     // local physical port No. of that mg
    WORD    chlNo;      // local channel No. of that trunk
    WORD    connectNo;
}CHNL;

typedef struct _MGC_CODEC_LIST
{
    BYTE    num;                            // num of codecs
    WORD    priority;                       // priority level, used when comparing different codec list
    MGC_VCTYPE    codec[MGC_VCTYPE_NUM];    // codec ID number, high priority codec first
}MGC_CODEC_LIST;

typedef struct _MG_ATTR
{
    BYTE    ptime;      // ptime, in ms
    MGC_MG_TYPE    mgType;     // non-virtual/ann
    MGC_MG_CTRL_TYPE    ctrlType;   // 8ecp or mgcp
    BYTE    epDes;      // endpoint description method: structured or unstructured
    BYTE    toneCap;    // Tone generation capability
    BYTE    maxPorts;   // maximum physical ports of this MG
    WORD    maxChnls;   // maximum channels of this MG, only applicable to virtual MG.
    DWORD   ip;         // IP address of the MG
    char    domain[MGC_MAX_DOMAIN_LEN];     // domain name of the mg
    BYTE    e1cardNo;
    DWORD   auditTimer;
    
    MGC_CODEC_LIST  codecList;              // list of codecs that the MG supports
}MG_ATTR;


typedef struct _PKG_EVENT
{
    BYTE    pkg;        // package name
    BYTE    event;      // event name
}PKG_EVENT;

typedef struct _PKG_SIGNAL
{
    BYTE    pkg;        // package name
    BYTE    signal;     // signal name
}PKG_SIGNAL;

typedef struct _PKG_REQ
{
    BYTE    pkg;        // package name
    BYTE    req;     // request name
}PKG_REQ;


#define MGC_MEDIA_PARA_FLAG_EC      0x0001
#define MGC_MEDIA_PARA_FLAG_SS      0x0002
#define MGC_MEDIA_PARA_FLAG_VT      0x0004
#define MGC_MEDIA_PARA_FLAG_CM      0x0008
#define MGC_MEDIA_PARA_FLAG_PT      0x0010


typedef struct _MEDIA_PARA
{
    WORD    flag;           // which media attribute is affected
    BYTE    ecDisable;      // echo canceller disable or enable
    BYTE    ssDisable;      // silence suppression disable or enable;
    BYTE    conMode;        // connect mode
    BYTE    ptime;          // packetization period
    MGC_CODEC_LIST  vocoderType;    // vocoder type
}MEDIA_PARA;


typedef struct _MEDIA_ATTR
{
    BYTE    ecDisable;      // echo canceller disable or enable
    BYTE    ssDisable;      // silence suppression disable or enable
    MGC_VCTYPE    vocoderType;    // vocoder type
    MGC_CON_MODE    conMode;        // connect mode
    char    callId[33];     // call Id
    char    conId[33];      // connection id
    BYTE    ptime;          // packetization period
    PKG_EVENT pkgEvent;       // package + event
    PKG_SIGNAL pkgSignal;      // package + signal
    PKG_REQ pkgReq;
    PUB_SDP_MSG sdp;        // media info of this channel
}MEDIA_ATTR;



typedef int (*mgc_ind_callback)(CHNL chnl, MGC_CMD_TYPE cmd, WORD *usrPort, WORD mgcPort, MEDIA_ATTR *mediaAttr);
typedef int (*mgc_cnf_callback)(WORD usrPort, WORD mgcPort, MGC_MG_OPER_ID_TYPE operId, MGC_OPER_RESULT success, WORD cause);


typedef struct _MGC_SAP
{
    int id;   //internal used , should not be modified by up layer
    char    usrName[MGC_MAX_USER_NAME_LEN]; // user name
    MGC_USER_TYPE    usrType;    // user acts as a mg or mgc
    
    mgc_ind_callback ind_func;
    mgc_cnf_callback cnf_func;
}MGC_SAP;


void mgc_init(DWORD systemId, DWORD localIp, DWORD peerIp);
int mgc_bind(MGC_SAP *pSap);
int mgc_unbind(MGC_SAP *pSap, BYTE sapIndex);
void mgc_timer(void);


int mgc_create_MG(BYTE sapIndex, MG_ATTR *pMgAttr);
int mgc_delete_MG(BYTE sapIndex, WORD mgNo);
int mgc_modify_MG(BYTE sapIndex, WORD mgNo, MG_ATTR *pMgAttr);

int mgc_add_port(BYTE sapIndex, WORD mgNo, BYTE portNo, MGC_PHY_PORT_TYPE portType);
int mgc_delete_port(BYTE sapIndex, WORD mgNo, BYTE portNo);

int mgc_crcx_chnl(WORD usrPort, CHNL chnl);
int mgc_mdcx_chnl(WORD usrPort, CHNL chnl, MEDIA_PARA *pMediaPara);
int mgc_dlcx_chnl(WORD usrPort, CHNL chnl);
int mgc_rqnt_chnl(WORD usrPort, CHNL chnl, PKG_EVENT *pPkgEvent, PKG_SIGNAL *pPkgSig);


int mgc_connect_chnl(WORD usrPort, CHNL orgChnl, CHNL destChnl, BYTE flag);
int mgc_connect_dtmf(WORD usrPort, CHNL chnl,CHNL dstChnl, BYTE dtmfNo);
int mgc_recvonly_chnl(WORD usrPort, CHNL orgChnl, CHNL destChnl);
int mgc_connect_AAS(WORD usrPort, CHNL orgChnl, CHNL destChnl, BYTE toneNo, WORD duration, WORD times);
int mgc_connect_tone(WORD usrPort, CHNL orgChnl, CHNL destChnl, BYTE toneNo, WORD duration);


int mgc_query_mg_status(WORD mgNo);
int mgc_query_port_status(WORD mgNo, BYTE portNo);
int mgc_query_channel_status(CHNL chnl);

int mgc_create_virtual_chnl(WORD usrPort, CHNL *pChnl);
int mgc_release_virtual_chnl(WORD usrPort,CHNL chnl);

int mgc_query_chnl_media(WORD usrPort, CHNL chnl, PUB_SDP_MSG **ppMediaInfo, BYTE *pMgPayloads, BYTE *pMgPlNum);
int mgc_update_chnl_media(WORD usrPort, CHNL chnl, PUB_SDP_MSG *pMediaInfo);
int mgc_chnl_codec_update(CHNL chnl , MGC_CODEC_LIST codecList);


OPER_REC *mgc_query_chnl_oper_rec(CHNL chnl);
int mgc_license_ctrl(WORD maxMgNum, WORD maxChnlNum);

int mgc_rsp(BYTE cmd, WORD usrPort, WORD port, WORD retCode, MEDIA_ATTR *pMediaAttr);

int mgc_get_idle_tandem_id(void);
int mgc_bind_chnl_to_tandem(WORD usrPort , CHNL tarChnl , DWORD tandId);
int mgc_create_tandem(WORD usrPort , DWORD tandId);
int mgc_unbind_chnl_from_tandem(WORD usrPort , CHNL tarChnl , DWORD tandId);
int mgc_delete_tandem(WORD usrPort , DWORD tandemId);
int mgc_get_tandem_near_end(DWORD tandem_id, CHNL *pChnl);
int mgc_get_tandem_far_end(DWORD tandem_id, CHNL *pChnl);
int mgc_fork_chnl(WORD usrPort , CHNL parent, CHNL *pChild);

char *mgc_print_failure_reason(int ret);

#endif
