📄 megacomgc.c
字号:
/* filename megacomgc.c */
/* */
/* Sample application level protocol where, if profile ResGW/1 is used in */
/* service change request, than */
/* 2 MGs will be communicating controlled by a single MGC using underlying */
/* MEGACO protocol. This code illustrates the flow example given in the */
/* appendix A of RFC3015 */
/* If you use profile IPPhoneGW/1 in service change request than the IP Phone */
/* functionality will be allowed between the connected devices as well */
/* */
/* For illustration purposes the application uses only one thread */
/* */
/* */
/* Usage: megacomgc mgcIp configFile [codecFile] */
/* mgcIp MGC IP address */
/* configFile Contains the configuration of all */
/* terminations on this MGC */
/* codecFile Contains */
/* <packetization> {<codecNumber> [<codecName>]}... */
/* If parameter is not present codecNumber = 0 */
/* */
/* */
/* Author T.Gindis */
/* 2/16/2001 TG Initial version passed interoperability test*/
/******************************************************************************/
#include "megacomgc.h"
#define APP_FILELOGLISTENER_ENTRIES 5000
#define APP_MAX_CODECS 10
static RvStdioLogListener stdioListener;
static RvFileLogListener fileListener;
static int inLoop;
static const char empty_str[] = "";
static const char* resProfile = "Analog_Line_Interoperability_Test_Profile";
static char dispBuf[200];
static int termInd = 0, retTermInd; /* Index into applInfo */
static char *mgcId; /* Stores MGC id string, for this */
/* application we use default port*/
/* so mgcId contains only address */
static int codecRate = 8000;
static char ptime[4] = "";
typedef struct CODEC_INFO
{
int number;
char name[16];
} codecInfo;
codecInfo codecsInfo[APP_MAX_CODECS];
int rootRequest;
int numTerminations; /* Number of configured terminat. */
RvHost localHost; /* IP Address */
RvMegacoEntityAddress mgcAddr;
RvMegacoEntity mgcTcpText, mgcUdpText, mgcTcpBin, mgcUdpBin;
int stackPriority, threadPriority;
RvMegacoStack mgc;
RvMegacoTcb *savedTcb;
const RvMegacoTransaction *savedTrans;
const RvMegacoTerminationId *termIdPtr;
RvMutex termMutex; /* lock for termInd and structures */
int timersDestroyed; /* flag to insure timers don't run after death */
static struct APPL_INFO /* One instance of a struct per */
{ /* each termination */
int inUse; /* rvTrue if this termination is */
/* involved in call */
int inService; /* rvTrue if this termination is */
/* active */
int mgUp; /* rvTrue if this mg is */
/* active */
int event; /* Current event */
int markedAction; /* Event executed prior to current*/
int timerEvent; /* Event to perform if timer */
/* expired */
int nextEvent; /* Event to perform on request */
/* confirmation by MG */
int newState; /* Next state to go into */
int currentState; /* Current State */
int action;
char localPhone[32]; /* Phone number on the termination*/
int remoteTermInd; /* termInd of a remote party when */
/* connected, 0 if no connection */
int connectInitiatorInd; /* Initiating term. */
int discInitiatorInd; /* Disconnecting term */
int callInProgress; /* Set when off hook condition is */
/* detected */
RvMegacoTransactionId requestTranId;
RvMegacoTransactionId replyTranId;
char profile[50];/* Allow for the largest profile*/
RvMegacoStreamId streamId;
unsigned int requestId;
RvInetPort mgPort;
char *mgAddress;
RvTimer timer;
int contextType;
RvMegacoContextId contextId;
RvMegacoEntity *remoteEntity;
const RvMegacoCommand *commandPtr; /* For incoming commands */
RvMegacoModifyCommand *modifyCommandPtr; /* For outgoing command */
RvMegacoAddCommand *addCommandPtr; /* For outgoing command */
RvMegacoAction *actionOutPtr; /* For outgoing action */
const RvMegacoAction *actionInPtr; /* For incoming action */
RvMegacoTerminationId terminationId;
RvMegacoTerminationId rtpTerminationId;
const char *rtpLocalAddress;
RvInetPort rtpLocalPort;
char *rtpRemoteAddress;
RvInetPort rtpRemotePort;
RvMegacoCommandType commandType;
const RvMegacoCommandReply *commandReplyInPtr; /* For incoming replies */
RvMegacoCommandReply *commandReplyOutPtr;/* For outgoing replies */
codecInfo sdpRemoteCodec;
codecInfo sdpLocalCodec;
const RvMegacoObservedEvent *observedEvent; /* For incoming events */
const RvSdpMsg *sdpMsgPtr; /* For incoming sdp msg */
unsigned int error; /* Last sent/received err.*/
const char *description; /* Error text */
} applInfo[MAX_TERMINATIONS];
static int phoneNumIdx[MAX_TERMINATIONS];
static int applInfoMgIdx[MAX_MGS];
static int mgNum;
static struct
{
struct
{
int action;
int newState;
} event[MAX_APPL_EVENTS];
} applStateTable[MAX_APPL_STATES] = {
/******************************************************************************/
/* This is the initial state for MGC. The first event is the ServiceChange */
/* command from MG announcong that a specified termination is going into */
/* service */
/******************************************************************************/
/* State 1 - S_IDLE_DISCONNECTED */
/* 1 E_SERVICE_CHANGE_IND */ A_SERVICE_CHANGE_IND , S_IDLE_DISCONNECTED ,
/* 2 E_ON_HOOK_LISTEN_REQ */ A_IMPOSSIBLE , S_IDLE_DISCONNECTED ,
/* 3 E_OFF_HOOK_LISTEN_REQ, */ A_OFF_HOOK_LISTEN_REQ , S_WAITING_FOR_LOCAL_SETUP ,
/* 4 E_DIAL_NUMBER_IND */ A_IMPOSSIBLE , S_IDLE_DISCONNECTED ,
/* 5 E_RING_SIGNAL_REQ */ A_IMPOSSIBLE , S_IDLE_DISCONNECTED ,
/* 6 E_RING_SIGNAL_RESP */ A_IMPOSSIBLE , S_IDLE_DISCONNECTED ,
/* 7 E_BUSY_SIGNAL_RESP */ A_IMPOSSIBLE , S_IDLE_DISCONNECTED ,
/* 8 E_ERROR_MSG_RESP */ A_ERROR_MSG_RESP , S_IDLE_DISCONNECTED ,
/* 9 E_STOP_RING_SIGNAL_REQ */ A_STOP_RING_SIGNAL_REQ2 , S_IDLE_DISCONNECTED ,
/*10 E_STOP_RING_TONE_REQ */ A_IMPOSSIBLE , S_IDLE_DISCONNECTED ,
/*11 E_ON_HOOK_DISC_IND */ A_IMPOSSIBLE , S_IDLE_DISCONNECTED ,
/*12 E_TIMEOUT */ A_TIMEOUT , S_IDLE_DISCONNECTED ,
/*13 E_ILLEGAL */ A_ILLEGAL1 , S_IDLE_DISCONNECTED ,
/*13 E_IMPOSSIBLE */ A_IMPOSSIBLE , S_IDLE_DISCONNECTED ,
/*15 E_RECEIVE_REQUEST */ A_RECEIVE_REQUEST1 , S_IDLE_DISCONNECTED ,
/*16 E_RECEIVE_REPLY */ A_RECEIVE_REPLY , S_IDLE_DISCONNECTED ,
/*17 E_GO_IN_SERVICE */ A_GO_IN_SERVICE , S_IDLE_DISCONNECTED ,
/*18 E_GO_OUT_OF_SERVICE */ A_GO_OUT_OF_SERVICE , S_IDLE_DISCONNECTED ,
/*19 E_LOCAL_CONNECT */ A_IMPOSSIBLE , S_IDLE_DISCONNECTED ,
/*20 E_REMOTE_CONNECT */ A_IMPOSSIBLE , S_IDLE_DISCONNECTED ,
/*21 E_APPL_SPECIAL */ A_DO_NOTHING , S_IDLE_DISCONNECTED ,
/*22 E_SWITCH_TERMINATION */ A_IMPOSSIBLE , S_IDLE_DISCONNECTED ,
/*23 E_SEND_REPLY */ A_SEND_REPLY , S_IDLE_DISCONNECTED ,
/*24 E_WRONG_NUMBER_REQ */ A_IMPOSSIBLE , S_IDLE_DISCONNECTED ,
/*25 E_DO_CLEANUP */ A_IMPOSSIBLE , S_IDLE_DISCONNECTED ,
/******************************************************************************/
/* We come here when a telephone goes in service. We wait for the off-hook */
/* notification from it and stay in this state until the calling telephone */
/* sends us collected digits of the dialed phone number and confirmes that it */
/* added 2 terminations to a new constext */
/******************************************************************************/
/* State 2 - S_WAITING_FOR_LOCAL_SETUP */
/* 1 E_SERVICE_CHANGE_IND */ A_SERVICE_CHANGE_IND , S_WAITING_FOR_LOCAL_SETUP ,
/* 2 E_ON_HOOK_LISTEN_REQ */ A_ON_HOOK_LISTEN_REQ , S_WAITING_FOR_LOCAL_SETUP ,
/* 3 E_OFF_HOOK_LISTEN_REQ */ A_IMPOSSIBLE , S_WAITING_FOR_LOCAL_SETUP ,
/* 4 E_DIAL_NUMBER_IND */ A_DIAL_NUMBER_IND , S_WAITING_FOR_LOCAL_SETUP ,
/* 5 E_RING_SIGNAL_REQ */ A_RING_SIGNAL_REQ , S_WAITING_FOR_REMOTE_SETUP,
/* 6 E_RING_SIGNAL_RESP */ A_IMPOSSIBLE , S_WAITING_FOR_LOCAL_SETUP ,
/* 7 E_BUSY_SIGNAL_RESP */ A_BUSY_SIGNAL_RESP2 , S_WAITING_FOR_LOCAL_SETUP ,
/* 8 E_ERROR_MSG_RESP */ A_ERROR_MSG_RESP , S_WAITING_FOR_LOCAL_SETUP ,
/* 9 E_STOP_RING_SIGNAL_REQ */ A_STOP_RING_SIGNAL_REQ2 , S_IDLE_DISCONNECTED ,
/*10 E_STOP_RING_TONE_REQ */ A_IMPOSSIBLE , S_WAITING_FOR_LOCAL_SETUP ,
/*11 E_ON_HOOK_DISC_IND */ A_ON_HOOK_DISC_IND2 , S_IDLE_DISCONNECTED ,
/*12 E_TIMEOUT */ A_TIMEOUT , S_WAITING_FOR_LOCAL_SETUP ,
/*13 E_ILLEGAL */ A_ILLEGAL , S_WAITING_FOR_LOCAL_SETUP ,
/*14 E_IMPOSSIBLE */ A_IMPOSSIBLE , S_WAITING_FOR_LOCAL_SETUP ,
/*15 E_RECEIVE_REQUEST */ A_RECEIVE_REQUEST2 , S_WAITING_FOR_LOCAL_SETUP ,
/*16 E_RECEIVE_REPLY */ A_RECEIVE_REPLY , S_WAITING_FOR_LOCAL_SETUP ,
/*17 E_GO_IN_SERVICE */ A_GO_IN_SERVICE , S_IDLE_DISCONNECTED ,
/*18 E_GO_OUT_OF_SERVICE */ A_GO_OUT_OF_SERVICE , S_IDLE_DISCONNECTED ,
/*19 E_LOCAL_CONNECT */ A_LOCAL_CONNECT , S_WAITING_FOR_LOCAL_SETUP ,
/*20 E_REMOTE_CONNECT */ A_IMPOSSIBLE , S_WAITING_FOR_LOCAL_SETUP ,
/*21 E_APPL_SPECIAL */ A_SET_RTP_TERMINATION , S_WAITING_FOR_LOCAL_SETUP ,
/*22 E_SWITCH_TERMINATION */ A_SWITCH_TERMINATION2 , S_WAITING_FOR_REMOTE_SETUP,
/*23 E_SEND_REPLY */ A_SEND_REPLY , S_WAITING_FOR_LOCAL_SETUP ,
/*24 E_WRONG_NUMBER_REQ */ A_WRONG_NUMBER_REQ , S_WAITING_FOR_LOCAL_SETUP ,
/*25 E_DO_CLEANUP */ A_DO_CLEANUP , S_WAITING_FOR_LOCAL_SETUP ,
/******************************************************************************/
/* The calling termination comes here after E_SWITCH_TERMINATION event, the */
/* called termination comes here after E_RING_SIGNAL_REQ event. All the work */
/* to get the called termination ready is done here */
/******************************************************************************/
/* State 3 - S_WAITING_FOR_REMOTE_SETUP */
/* 1 E_SERVICE_CHANGE_IND */ A_SERVICE_CHANGE_IND , S_WAITING_FOR_REMOTE_SETUP,
/* 2 E_ON_HOOK_LISTEN_REQ */ A_IMPOSSIBLE , S_WAITING_FOR_REMOTE_SETUP,
/* 3 E_OFF_HOOK_LISTEN_REQ */ A_IMPOSSIBLE , S_WAITING_FOR_REMOTE_SETUP,
/* 4 E_DIAL_NUMBER_IND */ A_IMPOSSIBLE , S_WAITING_FOR_REMOTE_SETUP,
/* 5 E_RING_SIGNAL_REQ */ A_RING_SIGNAL_REQ , S_WAITING_FOR_REMOTE_SETUP,
/* 6 E_RING_SIGNAL_RESP */ A_RING_SIGNAL_RESP , S_WAITING_FOR_REMOTE_SETUP,
/* 7 E_BUSY_SIGNAL_RESP */ A_BUSY_SIGNAL_RESP3 , S_WAITING_FOR_REMOTE_SETUP,
/* 8 E_ERROR_MSG_RESP */ A_ERROR_MSG_RESP , S_WAITING_FOR_REMOTE_SETUP,
/* 9 E_STOP_RING_SIGNAL_REQ */ A_STOP_RING_SIGNAL_REQ , S_CONNECTED ,
/*10 E_STOP_RING_TONE_REQ */ A_IMPOSSIBLE , S_WAITING_FOR_REMOTE_SETUP,
/*11 E_ON_HOOK_DISC_IND */ A_ON_HOOK_DISC_IND4 , S_IDLE_DISCONNECTED ,
/*12 E_TIMEOUT */ A_TIMEOUT , S_WAITING_FOR_REMOTE_SETUP,
/*13 E_ILLEGAL */ A_ILLEGAL , S_WAITING_FOR_REMOTE_SETUP,
/*14 E_IMPOSSIBLE */ A_IMPOSSIBLE , S_WAITING_FOR_REMOTE_SETUP,
/*15 E_RECEIVE_REQUEST */ A_RECEIVE_REQUEST3 , S_WAITING_FOR_REMOTE_SETUP,
/*16 E_RECEIVE_REPLY */ A_RECEIVE_REPLY3 , S_WAITING_FOR_REMOTE_SETUP,
/*17 E_GO_IN_SERVICE */ A_GO_IN_SERVICE , S_IDLE_DISCONNECTED ,
/*18 E_GO_OUT_OF_SERVICE */ A_GO_OUT_OF_SERVICE , S_IDLE_DISCONNECTED ,
/*19 E_LOCAL_CONNECT */ A_IMPOSSIBLE , S_WAITING_FOR_REMOTE_SETUP,
/*20 E_REMOTE_CONNECT */ A_REMOTE_CONNECT , S_CONNECTED ,
/*21 E_APPL_SPECIAL */ A_APPL_SPECIAL , S_WAITING_FOR_REMOTE_SETUP,
/*22 E_SWITCH_TERMINATION */ A_SWITCH_TERMINATION3 , S_WAITING_FOR_REMOTE_SETUP,
/*23 E_SEND_REPLY */ A_SEND_REPLY , S_WAITING_FOR_REMOTE_SETUP,
/*24 E_WRONG_NUMBER_REQ */ A_IMPOSSIBLE , S_WAITING_FOR_REMOTE_SETUP,
/*25 E_DO_CLEANUP */ A_DO_CLEANUP , S_WAITING_FOR_REMOTE_SETUP,
/******************************************************************************/
/* We stay in this state until on of the terminations completes the call. The*/
/* first detected off_hook event will cause the terminations being subtracted */
/* from the context. After this both terminations go back to state 1 and */
/* listen for the off_hook events */
/******************************************************************************/
/* State 4 - S_CONNECTED */
/* 1 E_SERVICE_CHANGE_IND */ A_SERVICE_CHANGE_IND , S_CONNECTED ,
/* 2 E_ON_HOOK_LISTEN_REQ */ A_IMPOSSIBLE , S_CONNECTED ,
/* 3 E_OFF_HOOK_LISTEN_REQ */ A_IMPOSSIBLE , S_CONNECTED ,
/* 4 E_DIAL_NUMBER_IND */ A_IMPOSSIBLE , S_CONNECTED ,
/* 5 E_RING_SIGNAL_REQ */ A_IMPOSSIBLE , S_CONNECTED ,
/* 6 E_RING_SIGNAL_RESP */ A_IMPOSSIBLE , S_CONNECTED ,
/* 7 E_BUSY_SIGNAL_RESP */ A_BUSY_SIGNAL_RESP3 , S_IDLE_DISCONNECTED ,
/* 8 E_ERROR_MSG_RESP */ A_ERROR_MSG_RESP , S_CONNECTED ,
/* 9 E_STOP_RING_SIGNAL_REQ */ A_STOP_RING_SIGNAL_REQ , S_CONNECTED ,
/*10 E_STOP_RING_TONE_REQ */ A_STOP_RING_TONE_REQ , S_CONNECTED ,
/*11 E_ON_HOOK_DISC_IND */ A_ON_HOOK_DISC_IND4 , S_IDLE_DISCONNECTED ,
/*12 E_TIMEOUT */ A_TIMEOUT , S_CONNECTED ,
/*13 E_ILLEGAL */ A_ILLEGAL , S_CONNECTED ,
/*14 E_IMPOSSIBLE */ A_IMPOSSIBLE , S_CONNECTED ,
/*15 E_RECEIVE_REQUEST */ A_RECEIVE_REQUEST4 , S_CONNECTED ,
/*16 E_RECEIVE_REPLY */ A_RECEIVE_REPLY , S_CONNECTED ,
/*17 E_GO_IN_SERVICE */ A_GO_IN_SERVICE , S_IDLE_DISCONNECTED ,
/*18 E_GO_OUT_OF_SERVICE */ A_GO_OUT_OF_SERVICE , S_IDLE_DISCONNECTED ,
/*19 E_LOCAL_CONNECT */ A_IMPOSSIBLE , S_CONNECTED ,
/*20 E_REMOTE_CONNECT */ A_IMPOSSIBLE , S_CONNECTED ,
/*21 E_APPL_SPECIAL */ A_IMPOSSIBLE , S_CONNECTED ,
/*22 E_SWITCH_TERMINATION */ A_SWITCH_TERMINATION4 , S_CONNECTED ,
/*23 E_SEND_REPLY */ A_SEND_REPLY , S_CONNECTED ,
/*24 E_WRONG_NUMBER_REQ */ A_IMPOSSIBLE , S_CONNECTED ,
/*25 E_DO_CLEANUP */ A_DO_CLEANUP , S_CONNECTED ,
};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -