1786 lines
61 KiB
C
1786 lines
61 KiB
C
/*
|
|
* Copyright (C) 2004-2005 by Objective Systems, Inc.
|
|
*
|
|
* This software is furnished under an open source license and may be
|
|
* used and copied only in accordance with the terms of this license.
|
|
* The text of the license may generally be found in the root
|
|
* directory of this installation in the COPYING file. It
|
|
* can also be viewed online at the following URL:
|
|
*
|
|
* http://www.obj-sys.com/open/license.html
|
|
*
|
|
* Any redistributions of this file including modified versions must
|
|
* maintain this copyright notice.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
#include "ooports.h"
|
|
#include "oochannels.h"
|
|
#include "ootrace.h"
|
|
#include "ooq931.h"
|
|
#include "ooh245.h"
|
|
#include "ooh323.h"
|
|
#include "ooCalls.h"
|
|
#include "printHandler.h"
|
|
#include "ooGkClient.h"
|
|
#include "stdio.h"
|
|
#include "ooTimer.h"
|
|
#include "ooh323ep.h"
|
|
#include "ooStackCmds.h"
|
|
#include "ooCmdChannel.h"
|
|
#include "ootypes.h"
|
|
|
|
/** Global endpoint structure */
|
|
extern OOH323EndPoint gH323ep;
|
|
|
|
extern DList g_TimerList;
|
|
|
|
static OOBOOL gMonitor = FALSE;
|
|
|
|
|
|
int ooCreateH245Listener(OOH323CallData *call)
|
|
{
|
|
int ret=0;
|
|
OOSOCKET channelSocket=0;
|
|
OOTRACEINFO1("Creating H245 listener\n");
|
|
if((ret=ooSocketCreate (&channelSocket))!=ASN_OK)
|
|
{
|
|
OOTRACEERR3("ERROR: Failed to create socket for H245 listener "
|
|
"(%s, %s)\n", call->callType, call->callToken);
|
|
return OO_FAILED;
|
|
}
|
|
ret = ooBindPort (OOTCP, channelSocket, call->localIP);
|
|
if(ret == OO_FAILED)
|
|
{
|
|
OOTRACEERR3("Error:Unable to bind to a TCP port - H245 listener creation"
|
|
" (%s, %s)\n", call->callType, call->callToken);
|
|
return OO_FAILED;
|
|
}
|
|
call->h245listenport = (int*) memAlloc(call->pctxt, sizeof(int));
|
|
*(call->h245listenport) = ret;
|
|
call->h245listener = (OOSOCKET*)memAlloc(call->pctxt, sizeof(OOSOCKET));
|
|
*(call->h245listener) = channelSocket;
|
|
ret = ooSocketListen(*(call->h245listener), 20);
|
|
if(ret != ASN_OK)
|
|
{
|
|
OOTRACEERR3("Error:Unable to listen on H.245 socket (%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
return OO_FAILED;
|
|
}
|
|
|
|
OOTRACEINFO4("H245 listener creation - successful(port %d) (%s, %s)\n",
|
|
*(call->h245listenport),call->callType, call->callToken);
|
|
return OO_OK;
|
|
}
|
|
|
|
int ooCreateH245Connection(OOH323CallData *call)
|
|
{
|
|
int ret=0;
|
|
OOSOCKET channelSocket=0;
|
|
ooTimerCallback *cbData=NULL;
|
|
|
|
OOTRACEINFO1("Creating H245 Connection\n");
|
|
if((ret=ooSocketCreate (&channelSocket))!=ASN_OK)
|
|
{
|
|
OOTRACEERR3("ERROR:Failed to create socket for H245 connection "
|
|
"(%s, %s)\n", call->callType, call->callToken);
|
|
return OO_FAILED;
|
|
}
|
|
else
|
|
{
|
|
if (0 == call->pH245Channel) {
|
|
call->pH245Channel =
|
|
(OOH323Channel*) memAllocZ (call->pctxt, sizeof(OOH323Channel));
|
|
}
|
|
|
|
/*
|
|
bind socket to a port before connecting. Thus avoiding
|
|
implicit bind done by a connect call.
|
|
*/
|
|
ret = ooBindPort(OOTCP, channelSocket, call->localIP);
|
|
if(ret == OO_FAILED)
|
|
{
|
|
OOTRACEERR3("Error:Unable to bind to a TCP port - h245 connection "
|
|
"(%s, %s)\n", call->callType, call->callToken);
|
|
return OO_FAILED;
|
|
}
|
|
call->pH245Channel->port = ret;
|
|
OOTRACEDBGC4("Local H.245 port is %d (%s, %s)\n",
|
|
call->pH245Channel->port,
|
|
call->callType, call->callToken);
|
|
OOTRACEINFO5("Trying to connect to remote endpoint to setup H245 "
|
|
"connection %s:%d(%s, %s)\n", call->remoteIP,
|
|
call->remoteH245Port, call->callType, call->callToken);
|
|
|
|
if((ret=ooSocketConnect(channelSocket, call->remoteIP,
|
|
call->remoteH245Port))==ASN_OK)
|
|
{
|
|
call->pH245Channel->sock = channelSocket;
|
|
call->h245SessionState = OO_H245SESSION_ACTIVE;
|
|
|
|
OOTRACEINFO3("H245 connection creation succesful (%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
|
|
/*Start terminal capability exchange and master slave determination */
|
|
ret = ooSendTermCapMsg(call);
|
|
if(ret != OO_OK)
|
|
{
|
|
OOTRACEERR3("ERROR:Sending Terminal capability message (%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
return ret;
|
|
}
|
|
ret = ooSendMasterSlaveDetermination(call);
|
|
if(ret != OO_OK)
|
|
{
|
|
OOTRACEERR3("ERROR:Sending Master-slave determination message "
|
|
"(%s, %s)\n", call->callType, call->callToken);
|
|
return ret;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(call->h245ConnectionAttempts >= 3)
|
|
{
|
|
OOTRACEERR3("Error:Failed to setup an H245 connection with remote "
|
|
"destination. (%s, %s)\n", call->callType,
|
|
call->callToken);
|
|
if(call->callState < OO_CALL_CLEAR)
|
|
{
|
|
call->callEndReason = OO_REASON_TRANSPORTFAILURE;
|
|
call->callState = OO_CALL_CLEAR;
|
|
}
|
|
return OO_FAILED;
|
|
}
|
|
else{
|
|
OOTRACEWARN4("Warn:Failed to connect to remote destination for "
|
|
"H245 connection - will retry after %d seconds"
|
|
"(%s, %s)\n", DEFAULT_H245CONNECTION_RETRYTIMEOUT,
|
|
call->callType, call->callToken);
|
|
|
|
cbData = (ooTimerCallback*) memAlloc(call->pctxt,
|
|
sizeof(ooTimerCallback));
|
|
if(!cbData)
|
|
{
|
|
OOTRACEERR3("Error:Unable to allocate memory for timer "
|
|
"callback.(%s, %s)\n", call->callType,
|
|
call->callToken);
|
|
return OO_FAILED;
|
|
}
|
|
cbData->call = call;
|
|
cbData->timerType = OO_H245CONNECT_TIMER;
|
|
if(!ooTimerCreate(call->pctxt, &call->timerList,
|
|
&ooCallH245ConnectionRetryTimerExpired,
|
|
DEFAULT_H245CONNECTION_RETRYTIMEOUT, cbData,
|
|
FALSE))
|
|
{
|
|
OOTRACEERR3("Error:Unable to create H245 connection retry timer"
|
|
"(%s, %s)\n", call->callType, call->callToken);
|
|
memFreePtr(call->pctxt, cbData);
|
|
return OO_FAILED;
|
|
}
|
|
return OO_OK;
|
|
}
|
|
}
|
|
}
|
|
return OO_OK;
|
|
}
|
|
|
|
int ooSendH225Msg(OOH323CallData *call, Q931Message *msg)
|
|
{
|
|
int iRet=0;
|
|
ASN1OCTET * encodebuf;
|
|
if(!call)
|
|
return OO_FAILED;
|
|
|
|
encodebuf = (ASN1OCTET*) memAlloc (call->pctxt, MAXMSGLEN);
|
|
if(!encodebuf)
|
|
{
|
|
OOTRACEERR3("Error:Failed to allocate memory for encoding H225 "
|
|
"message(%s, %s)\n", call->callType, call->callToken);
|
|
return OO_FAILED;
|
|
}
|
|
iRet = ooEncodeH225Message(call, msg, encodebuf, MAXMSGLEN);
|
|
if(iRet != OO_OK)
|
|
{
|
|
OOTRACEERR3("Error:Failed to encode H225 message. (%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
memFreePtr (call->pctxt, encodebuf);
|
|
return OO_FAILED;
|
|
}
|
|
|
|
/* If high priority messages, send immediately.*/
|
|
if(encodebuf[0] == OOReleaseComplete ||
|
|
(encodebuf[0]==OOFacility && encodebuf[1]==OOEndSessionCommand))
|
|
{
|
|
dListFreeAll(call->pctxt, &call->pH225Channel->outQueue);
|
|
dListAppend (call->pctxt, &call->pH225Channel->outQueue, encodebuf);
|
|
// ooSendMsg(call, OOQ931MSG);
|
|
}
|
|
else{
|
|
dListAppend (call->pctxt, &call->pH225Channel->outQueue, encodebuf);
|
|
|
|
OOTRACEDBGC4("Queued H225 messages %d. (%s, %s)\n",
|
|
call->pH225Channel->outQueue.count,
|
|
call->callType, call->callToken);
|
|
}
|
|
return OO_OK;
|
|
}
|
|
|
|
int ooCreateH225Connection(OOH323CallData *call)
|
|
{
|
|
int ret=0;
|
|
OOSOCKET channelSocket=0;
|
|
if((ret=ooSocketCreate (&channelSocket))!=ASN_OK)
|
|
{
|
|
OOTRACEERR3("Failed to create socket for transmit H2250 channel (%s, %s)"
|
|
"\n", call->callType, call->callToken);
|
|
if(call->callState < OO_CALL_CLEAR)
|
|
{
|
|
call->callState = OO_CALL_CLEAR;
|
|
call->callEndReason = OO_REASON_TRANSPORTFAILURE;
|
|
}
|
|
return OO_FAILED;
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
bind socket to a port before connecting. Thus avoiding
|
|
implicit bind done by a connect call. Avoided on windows as
|
|
windows sockets have problem in reusing the addresses even after
|
|
setting SO_REUSEADDR, hence in windows we just allow os to bind
|
|
to any random port.
|
|
*/
|
|
#ifndef _WIN32
|
|
ret = ooBindPort(OOTCP,channelSocket, call->localIP);
|
|
#else
|
|
ret = ooBindOSAllocatedPort(channelSocket, call->localIP);
|
|
#endif
|
|
|
|
if(ret == OO_FAILED)
|
|
{
|
|
OOTRACEERR3("Error:Unable to bind to a TCP port (%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
if(call->callState < OO_CALL_CLEAR)
|
|
{
|
|
call->callState = OO_CALL_CLEAR;
|
|
call->callEndReason = OO_REASON_TRANSPORTFAILURE;
|
|
}
|
|
return OO_FAILED;
|
|
}
|
|
|
|
if (0 == call->pH225Channel) {
|
|
call->pH225Channel =
|
|
(OOH323Channel*) memAllocZ (call->pctxt, sizeof(OOH323Channel));
|
|
}
|
|
call->pH225Channel->port = ret;
|
|
|
|
OOTRACEINFO5("Trying to connect to remote endpoint(%s:%d) to setup "
|
|
"H2250 channel (%s, %s)\n", call->remoteIP,
|
|
call->remotePort, call->callType, call->callToken);
|
|
|
|
if((ret=ooSocketConnect(channelSocket, call->remoteIP,
|
|
call->remotePort))==ASN_OK)
|
|
{
|
|
call->pH225Channel->sock = channelSocket;
|
|
|
|
OOTRACEINFO3("H2250 transmiter channel creation - succesful "
|
|
"(%s, %s)\n", call->callType, call->callToken);
|
|
|
|
/* If multihomed, get ip from socket */
|
|
if(!strcmp(call->localIP, "0.0.0.0"))
|
|
{
|
|
OOTRACEDBGA3("Determining IP address for outgoing call in "
|
|
"multihomed mode. (%s, %s)\n", call->callType,
|
|
call->callToken);
|
|
ret = ooSocketGetIpAndPort(channelSocket, call->localIP, 20,
|
|
&call->pH225Channel->port);
|
|
if(ret != ASN_OK)
|
|
{
|
|
OOTRACEERR3("ERROR:Failed to retrieve local ip and port from "
|
|
"socket for multihomed mode.(%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
if(call->callState < OO_CALL_CLEAR)
|
|
{ /* transport failure */
|
|
call->callState = OO_CALL_CLEAR;
|
|
call->callEndReason = OO_REASON_TRANSPORTFAILURE;
|
|
}
|
|
return OO_FAILED;
|
|
}
|
|
OOTRACEDBGA4("Using local ip %s for outgoing call(multihomedMode)."
|
|
" (%s, %s)\n", call->localIP, call->callType,
|
|
call->callToken);
|
|
}
|
|
return OO_OK;
|
|
}
|
|
else
|
|
{
|
|
OOTRACEERR3("ERROR:Failed to connect to remote destination for "
|
|
"transmit H2250 channel(%s, %s)\n",call->callType,
|
|
call->callToken);
|
|
if(call->callState < OO_CALL_CLEAR)
|
|
{ /* No one is listening at remote end */
|
|
call->callState = OO_CALL_CLEAR;
|
|
call->callEndReason = OO_REASON_NOUSER;
|
|
}
|
|
return OO_FAILED;
|
|
}
|
|
|
|
return OO_FAILED;
|
|
}
|
|
}
|
|
|
|
int ooCloseH225Connection (OOH323CallData *call)
|
|
{
|
|
if (0 != call->pH225Channel)
|
|
{
|
|
if(call->pH225Channel->sock != 0)
|
|
ooSocketClose (call->pH225Channel->sock);
|
|
if (call->pH225Channel->outQueue.count > 0)
|
|
{
|
|
dListFreeAll (call->pctxt, &(call->pH225Channel->outQueue));
|
|
}
|
|
memFreePtr (call->pctxt, call->pH225Channel);
|
|
call->pH225Channel = NULL;
|
|
}
|
|
return OO_OK;
|
|
}
|
|
|
|
int ooCreateH323Listener()
|
|
{
|
|
int ret=0;
|
|
OOSOCKET channelSocket=0;
|
|
OOIPADDR ipaddrs;
|
|
|
|
/* Create socket */
|
|
if((ret=ooSocketCreate (&channelSocket))!=ASN_OK)
|
|
{
|
|
OOTRACEERR1("Failed to create socket for H323 Listener\n");
|
|
return OO_FAILED;
|
|
}
|
|
ret= ooSocketStrToAddr (gH323ep.signallingIP, &ipaddrs);
|
|
if((ret=ooSocketBind (channelSocket, ipaddrs,
|
|
gH323ep.listenPort))==ASN_OK)
|
|
{
|
|
gH323ep.listener = (OOSOCKET*)memAlloc(&gH323ep.ctxt,sizeof(OOSOCKET));
|
|
*(gH323ep.listener) = channelSocket;
|
|
|
|
ooSocketListen(channelSocket,20); /*listen on socket*/
|
|
OOTRACEINFO1("H323 listener creation - successful\n");
|
|
return OO_OK;
|
|
}
|
|
else
|
|
{
|
|
OOTRACEERR1("ERROR:Failed to create H323 listener\n");
|
|
return OO_FAILED;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
int ooAcceptH225Connection()
|
|
{
|
|
OOH323CallData * call;
|
|
int ret;
|
|
char callToken[20];
|
|
OOSOCKET h225Channel=0;
|
|
ret = ooSocketAccept (*(gH323ep.listener), &h225Channel,
|
|
NULL, NULL);
|
|
if(ret != ASN_OK)
|
|
{
|
|
OOTRACEERR1("Error:Accepting h225 connection\n");
|
|
return OO_FAILED;
|
|
}
|
|
ooGenerateCallToken(callToken, sizeof(callToken));
|
|
|
|
call = ooCreateCall("incoming", callToken);
|
|
if(!call)
|
|
{
|
|
OOTRACEERR1("ERROR:Failed to create an incoming call\n");
|
|
return OO_FAILED;
|
|
}
|
|
|
|
call->pH225Channel = (OOH323Channel*)
|
|
memAllocZ (call->pctxt, sizeof(OOH323Channel));
|
|
|
|
call->pH225Channel->sock = h225Channel;
|
|
|
|
/* If multihomed, get ip from socket */
|
|
if(!strcmp(call->localIP, "0.0.0.0"))
|
|
{
|
|
OOTRACEDBGA3("Determining IP address for incoming call in multihomed "
|
|
"mode (%s, %s)\n", call->callType, call->callToken);
|
|
|
|
ret = ooSocketGetIpAndPort(h225Channel, call->localIP, 20,
|
|
&call->pH225Channel->port);
|
|
if(ret != ASN_OK)
|
|
{
|
|
OOTRACEERR3("Error:Failed to retrieve local ip and port from "
|
|
"socket for multihomed mode.(%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
if(call->callState < OO_CALL_CLEAR)
|
|
{ /* transport failure */
|
|
call->callState = OO_CALL_CLEAR;
|
|
call->callEndReason = OO_REASON_TRANSPORTFAILURE;
|
|
}
|
|
return OO_FAILED;
|
|
}
|
|
OOTRACEDBGA4("Using Local IP address %s for incoming call in multihomed "
|
|
"mode. (%s, %s)\n", call->localIP, call->callType,
|
|
call->callToken);
|
|
}
|
|
|
|
return OO_OK;
|
|
}
|
|
|
|
int ooAcceptH245Connection(OOH323CallData *call)
|
|
{
|
|
int ret;
|
|
OOSOCKET h245Channel=0;
|
|
ret = ooSocketAccept (*(call->h245listener), &h245Channel,
|
|
NULL, NULL);
|
|
if(ret != ASN_OK)
|
|
{
|
|
OOTRACEERR1("Error:Accepting h245 connection\n");
|
|
return OO_FAILED;
|
|
}
|
|
|
|
if (0 == call->pH245Channel) {
|
|
call->pH245Channel =
|
|
(OOH323Channel*) memAllocZ (call->pctxt, sizeof(OOH323Channel));
|
|
}
|
|
call->pH245Channel->sock = h245Channel;
|
|
call->h245SessionState = OO_H245SESSION_ACTIVE;
|
|
|
|
|
|
OOTRACEINFO3("H.245 connection established (%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
|
|
|
|
/* Start terminal capability exchange and master slave determination */
|
|
ret = ooSendTermCapMsg(call);
|
|
if(ret != OO_OK)
|
|
{
|
|
OOTRACEERR3("ERROR:Sending Terminal capability message (%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
return ret;
|
|
}
|
|
ret = ooSendMasterSlaveDetermination(call);
|
|
if(ret != OO_OK)
|
|
{
|
|
OOTRACEERR3("ERROR:Sending Master-slave determination message "
|
|
"(%s, %s)\n", call->callType, call->callToken);
|
|
return ret;
|
|
}
|
|
return OO_OK;
|
|
}
|
|
|
|
|
|
int ooSetFDSETs(fd_set *pReadfds, fd_set *pWritefds, int *nfds)
|
|
{
|
|
OOH323CallData *call=NULL;
|
|
|
|
if(gH323ep.gkClient && gH323ep.gkClient->rasSocket != 0)
|
|
{
|
|
FD_SET(gH323ep.gkClient->rasSocket, pReadfds );
|
|
if ( *nfds < (int)gH323ep.gkClient->rasSocket)
|
|
*nfds = (int)gH323ep.gkClient->rasSocket;
|
|
}
|
|
if(gH323ep.listener)
|
|
{
|
|
FD_SET(*(gH323ep.listener), pReadfds);
|
|
if(*nfds < (int)*(gH323ep.listener))
|
|
*nfds = *((int*)gH323ep.listener);
|
|
}
|
|
|
|
if(gH323ep.cmdSock)
|
|
{
|
|
FD_SET(gH323ep.cmdSock, pReadfds);
|
|
if(*nfds < (int)gH323ep.cmdSock)
|
|
*nfds = (int)gH323ep.cmdSock;
|
|
}
|
|
|
|
|
|
|
|
if(gH323ep.callList)
|
|
{
|
|
call = gH323ep.callList;
|
|
while(call)
|
|
{
|
|
if (0 != call->pH225Channel && 0 != call->pH225Channel->sock)
|
|
{
|
|
FD_SET (call->pH225Channel->sock, pReadfds);
|
|
if (call->pH225Channel->outQueue.count > 0 ||
|
|
(OO_TESTFLAG (call->flags, OO_M_TUNNELING) &&
|
|
0 != call->pH245Channel &&
|
|
call->pH245Channel->outQueue.count>0))
|
|
FD_SET (call->pH225Channel->sock, pWritefds);
|
|
if(*nfds < (int)call->pH225Channel->sock)
|
|
*nfds = call->pH225Channel->sock;
|
|
}
|
|
|
|
if (0 != call->pH245Channel && call->pH245Channel->sock != 0)
|
|
{
|
|
FD_SET(call->pH245Channel->sock, pReadfds);
|
|
if (call->pH245Channel->outQueue.count>0)
|
|
FD_SET(call->pH245Channel->sock, pWritefds);
|
|
if(*nfds < (int)call->pH245Channel->sock)
|
|
*nfds = call->pH245Channel->sock;
|
|
}
|
|
else if(call->h245listener)
|
|
{
|
|
OOTRACEINFO3("H.245 Listerner socket being monitored "
|
|
"(%s, %s)\n", call->callType, call->callToken);
|
|
FD_SET(*(call->h245listener), pReadfds);
|
|
if(*nfds < (int)*(call->h245listener))
|
|
*nfds = *(call->h245listener);
|
|
}
|
|
call = call->next;
|
|
|
|
}/* while(call) */
|
|
}/*if(gH323ep.callList) */
|
|
|
|
|
|
if(*nfds != 0) *nfds = *nfds+1;
|
|
|
|
return OO_OK;
|
|
|
|
}
|
|
|
|
int ooProcessFDSETsAndTimers
|
|
(fd_set *pReadfds, fd_set *pWritefds, struct timeval *pToMin)
|
|
{
|
|
OOH323CallData *call, *prev=NULL;
|
|
struct timeval toNext;
|
|
|
|
/* Process gatekeeper client timers */
|
|
if(gH323ep.gkClient)
|
|
{
|
|
ooTimerFireExpired(&gH323ep.gkClient->ctxt,
|
|
&gH323ep.gkClient->timerList);
|
|
if(ooTimerNextTimeout(&gH323ep.gkClient->timerList, &toNext))
|
|
{
|
|
if(ooCompareTimeouts(pToMin, &toNext)>0)
|
|
{
|
|
pToMin->tv_sec = toNext.tv_sec;
|
|
pToMin->tv_usec = toNext.tv_usec;
|
|
}
|
|
}
|
|
if(gH323ep.gkClient->state == GkClientFailed ||
|
|
gH323ep.gkClient->state == GkClientGkErr)
|
|
{
|
|
if(ooGkClientHandleClientOrGkFailure(gH323ep.gkClient)!=OO_OK)
|
|
{
|
|
//ooStopMonitorCalls(); //Function calling ooProcessFDSETsAndTimers is responsible for this.
|
|
return OO_FAILED;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(gH323ep.cmdSock) {
|
|
if(FD_ISSET(gH323ep.cmdSock, pReadfds)) {
|
|
if(ooReadAndProcessStackCommand() != OO_OK) {
|
|
/* ooReadAndProcessStackCommand prints an error message */
|
|
return OO_FAILED;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Manage ready descriptors after select */
|
|
|
|
if(0 != gH323ep.gkClient && 0 != gH323ep.gkClient->rasSocket)
|
|
{
|
|
if(FD_ISSET( gH323ep.gkClient->rasSocket, pReadfds) )
|
|
{
|
|
ooGkClientReceive(gH323ep.gkClient);
|
|
if(gH323ep.gkClient->state == GkClientFailed ||
|
|
gH323ep.gkClient->state == GkClientGkErr) {
|
|
ooGkClientHandleClientOrGkFailure(gH323ep.gkClient);
|
|
}
|
|
}
|
|
}
|
|
|
|
if(gH323ep.listener)
|
|
{
|
|
if(FD_ISSET(*(gH323ep.listener), pReadfds))
|
|
{
|
|
OOTRACEDBGA1("New connection at H225 receiver\n");
|
|
ooAcceptH225Connection();
|
|
}
|
|
}
|
|
|
|
|
|
if(gH323ep.callList)
|
|
{
|
|
call = gH323ep.callList;
|
|
while(call)
|
|
{
|
|
ooTimerFireExpired(call->pctxt, &call->timerList);
|
|
if (0 != call->pH225Channel && 0 != call->pH225Channel->sock)
|
|
{
|
|
if(FD_ISSET(call->pH225Channel->sock, pReadfds))
|
|
{
|
|
if(ooH2250Receive(call) != OO_OK)
|
|
{
|
|
OOTRACEERR3("ERROR:Failed ooH2250Receive - Clearing call "
|
|
"(%s, %s)\n", call->callType, call->callToken);
|
|
if(call->callState < OO_CALL_CLEAR)
|
|
{
|
|
call->callEndReason = OO_REASON_INVALIDMESSAGE;
|
|
call->callState = OO_CALL_CLEAR;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
if (0 != call->pH245Channel && 0 != call->pH245Channel->sock)
|
|
{
|
|
if(FD_ISSET(call->pH245Channel->sock, pReadfds))
|
|
{
|
|
ooH245Receive(call);
|
|
}
|
|
}
|
|
|
|
if (0 != call->pH245Channel && 0 != call->pH245Channel->sock)
|
|
{
|
|
if(FD_ISSET(call->pH245Channel->sock, pWritefds))
|
|
{
|
|
if(call->pH245Channel->outQueue.count>0)
|
|
ooSendMsg(call, OOH245MSG);
|
|
}
|
|
}
|
|
else if(call->h245listener)
|
|
{
|
|
if(FD_ISSET(*(call->h245listener), pReadfds))
|
|
{
|
|
OOTRACEDBGC3("Incoming H.245 connection (%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
ooAcceptH245Connection(call);
|
|
}
|
|
}
|
|
|
|
if (0 != call->pH225Channel && 0 != call->pH225Channel->sock)
|
|
{
|
|
if(FD_ISSET(call->pH225Channel->sock, pWritefds))
|
|
{
|
|
if(call->pH225Channel->outQueue.count>0)
|
|
{
|
|
OOTRACEDBGC3("Sending H225 message (%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
ooSendMsg(call, OOQ931MSG);
|
|
}
|
|
if(call->pH245Channel &&
|
|
call->pH245Channel->outQueue.count>0 &&
|
|
OO_TESTFLAG (call->flags, OO_M_TUNNELING))
|
|
{
|
|
OOTRACEDBGC3("H245 message needs to be tunneled. "
|
|
"(%s, %s)\n", call->callType,
|
|
call->callToken);
|
|
ooSendMsg(call, OOH245MSG);
|
|
}
|
|
}
|
|
}
|
|
|
|
if(ooTimerNextTimeout(&call->timerList, &toNext))
|
|
{
|
|
if(ooCompareTimeouts(pToMin, &toNext) > 0)
|
|
{
|
|
pToMin->tv_sec = toNext.tv_sec;
|
|
pToMin->tv_usec = toNext.tv_usec;
|
|
}
|
|
}
|
|
prev = call;
|
|
call = call->next;
|
|
if(prev->callState >= OO_CALL_CLEAR)
|
|
ooEndCall(prev);
|
|
}/* while(call) */
|
|
}/* if(gH323ep.callList) */
|
|
|
|
return OO_OK;
|
|
|
|
}
|
|
|
|
int ooMonitorChannels()
|
|
{
|
|
int ret=0, nfds=0;
|
|
struct timeval toMin, toNext;
|
|
fd_set readfds, writefds;
|
|
|
|
gMonitor = TRUE;
|
|
|
|
toMin.tv_sec = 3;
|
|
toMin.tv_usec = 0;
|
|
ooH323EpPrintConfig();
|
|
|
|
if(gH323ep.gkClient) {
|
|
ooGkClientPrintConfig(gH323ep.gkClient);
|
|
if(OO_OK != ooGkClientStart(gH323ep.gkClient))
|
|
{
|
|
OOTRACEERR1("Error:Failed to start Gatekeeper client\n");
|
|
ooGkClientDestroy();
|
|
}
|
|
}
|
|
|
|
while(1)
|
|
{
|
|
FD_ZERO(&readfds);
|
|
FD_ZERO(&writefds);
|
|
nfds = 0;
|
|
ooSetFDSETs(&readfds, &writefds, &nfds);
|
|
|
|
if(!gMonitor) {
|
|
OOTRACEINFO1("Ending Monitor thread\n");
|
|
break;
|
|
}
|
|
|
|
|
|
if(nfds == 0)
|
|
#ifdef _WIN32
|
|
Sleep(10);
|
|
#else
|
|
{
|
|
toMin.tv_sec = 0;
|
|
toMin.tv_usec = 10000;
|
|
ooSocketSelect(1, 0, 0, 0, &toMin);
|
|
}
|
|
#endif
|
|
else
|
|
ret = ooSocketSelect(nfds, &readfds, &writefds,
|
|
NULL, &toMin);
|
|
|
|
if(ret == -1)
|
|
{
|
|
|
|
OOTRACEERR1("Error in select ...exiting\n");
|
|
exit(-1);
|
|
}
|
|
|
|
toMin.tv_sec = 0;
|
|
toMin.tv_usec = 100000; /* 100ms*/
|
|
/*This is for test application. Not part of actual stack */
|
|
|
|
ooTimerFireExpired(&gH323ep.ctxt, &g_TimerList);
|
|
if(ooTimerNextTimeout(&g_TimerList, &toNext))
|
|
{
|
|
if(ooCompareTimeouts(&toMin, &toNext)>0)
|
|
{
|
|
toMin.tv_sec = toNext.tv_sec;
|
|
toMin.tv_usec = toNext.tv_usec;
|
|
}
|
|
}
|
|
|
|
if(ooProcessFDSETsAndTimers(&readfds, &writefds, &toMin) != OO_OK)
|
|
{
|
|
ooStopMonitorCalls();
|
|
continue;
|
|
}
|
|
|
|
}/* while(1)*/
|
|
return OO_OK;
|
|
}
|
|
|
|
int ooH2250Receive(OOH323CallData *call)
|
|
{
|
|
int recvLen=0, total=0, ret=0;
|
|
ASN1OCTET message[MAXMSGLEN], message1[MAXMSGLEN];
|
|
int len;
|
|
Q931Message *pmsg;
|
|
OOCTXT *pctxt = &gH323ep.msgctxt;
|
|
struct timeval timeout;
|
|
fd_set readfds;
|
|
|
|
|
|
pmsg = (Q931Message*)memAlloc(pctxt, sizeof(Q931Message));
|
|
if(!pmsg)
|
|
{
|
|
OOTRACEERR3("ERROR:Failed to allocate memory for incoming H.2250 message"
|
|
" (%s, %s)\n", call->callType, call->callToken);
|
|
memReset(&gH323ep.msgctxt);
|
|
return OO_FAILED;
|
|
}
|
|
memset(pmsg, 0, sizeof(Q931Message));
|
|
/* First read just TPKT header which is four bytes */
|
|
recvLen = ooSocketRecv (call->pH225Channel->sock, message, 4);
|
|
if(recvLen <= 0)
|
|
{
|
|
if(recvLen == 0)
|
|
OOTRACEWARN3("Warn:RemoteEndpoint closed connection (%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
else
|
|
OOTRACEERR3("Error:Transport failure while reading Q931 "
|
|
"message (%s, %s)\n", call->callType, call->callToken);
|
|
|
|
ooCloseH225Connection(call);
|
|
if(call->callState < OO_CALL_CLEARED)
|
|
{
|
|
if(call->callState < OO_CALL_CLEAR)
|
|
call->callEndReason = OO_REASON_TRANSPORTFAILURE;
|
|
call->callState = OO_CALL_CLEARED;
|
|
|
|
}
|
|
ooFreeQ931Message(pmsg);
|
|
return OO_OK;
|
|
}
|
|
OOTRACEDBGC3("Receiving H.2250 message (%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
/* Since we are working with TCP, need to determine the
|
|
message boundary. Has to be done at channel level, as channels
|
|
know the message formats and can determine boundaries
|
|
*/
|
|
if(recvLen != 4)
|
|
{
|
|
OOTRACEERR4("Error: Reading TPKT header for H225 message "
|
|
"recvLen= %d (%s, %s)\n", recvLen, call->callType,
|
|
call->callToken);
|
|
ooFreeQ931Message(pmsg);
|
|
if(call->callState < OO_CALL_CLEAR)
|
|
{
|
|
call->callEndReason = OO_REASON_INVALIDMESSAGE;
|
|
call->callState = OO_CALL_CLEAR;
|
|
}
|
|
return OO_FAILED;
|
|
}
|
|
|
|
|
|
len = message[2];
|
|
len = len<<8;
|
|
len = len | message[3];
|
|
/* Remaining message length is length - tpkt length */
|
|
len = len - 4;
|
|
|
|
/* Now read actual Q931 message body. We should make sure that we
|
|
receive complete message as indicated by len. If we don't then there
|
|
is something wrong. The loop below receives message, then checks whether
|
|
complete message is received. If not received, then uses select to peek
|
|
for remaining bytes of the message. If message is not received in 3
|
|
seconds, then we have a problem. Report an error and exit.
|
|
*/
|
|
while(total < len)
|
|
{
|
|
recvLen = ooSocketRecv (call->pH225Channel->sock, message1, len-total);
|
|
memcpy(message+total, message1, recvLen);
|
|
total = total + recvLen;
|
|
|
|
if(total == len) break; /* Complete message is received */
|
|
|
|
FD_ZERO(&readfds);
|
|
FD_SET(call->pH225Channel->sock, &readfds);
|
|
timeout.tv_sec = 3;
|
|
timeout.tv_usec = 0;
|
|
ret = ooSocketSelect(call->pH225Channel->sock+1, &readfds, NULL,
|
|
NULL, &timeout);
|
|
if(ret == -1)
|
|
{
|
|
OOTRACEERR3("Error in select while receiving H.2250 message - "
|
|
"clearing call (%s, %s)\n", call->callType,
|
|
call->callToken);
|
|
ooFreeQ931Message(pmsg);
|
|
if(call->callState < OO_CALL_CLEAR)
|
|
{
|
|
call->callEndReason = OO_REASON_TRANSPORTFAILURE;
|
|
call->callState = OO_CALL_CLEAR;
|
|
}
|
|
return OO_FAILED;
|
|
}
|
|
/* If remaining part of the message is not received in 3 seconds
|
|
exit */
|
|
if(!FD_ISSET(call->pH225Channel->sock, &readfds))
|
|
{
|
|
OOTRACEERR3("Error: Incomplete H.2250 message received - clearing "
|
|
"call (%s, %s)\n", call->callType, call->callToken);
|
|
ooFreeQ931Message(pmsg);
|
|
if(call->callState < OO_CALL_CLEAR)
|
|
{
|
|
call->callEndReason = OO_REASON_INVALIDMESSAGE;
|
|
call->callState = OO_CALL_CLEAR;
|
|
}
|
|
return OO_FAILED;
|
|
}
|
|
}
|
|
|
|
OOTRACEDBGC3("Received Q.931 message: (%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
|
|
initializePrintHandler(&printHandler, "Received H.2250 Message");
|
|
setEventHandler (pctxt, &printHandler);
|
|
ret = ooQ931Decode (call, pmsg, len, message);
|
|
if(ret != OO_OK) {
|
|
OOTRACEERR3("Error:Failed to decode received H.2250 message. (%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
}
|
|
OOTRACEDBGC3("Decoded Q931 message (%s, %s)\n", call->callType,
|
|
call->callToken);
|
|
finishPrint();
|
|
removeEventHandler(pctxt);
|
|
if(ret == OO_OK) {
|
|
ooHandleH2250Message(call, pmsg);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
|
|
int ooH245Receive(OOH323CallData *call)
|
|
{
|
|
int recvLen, ret, len, total=0;
|
|
ASN1OCTET message[MAXMSGLEN], message1[MAXMSGLEN];
|
|
ASN1BOOL aligned = TRUE;
|
|
H245Message *pmsg;
|
|
OOCTXT *pctxt = &gH323ep.msgctxt;
|
|
struct timeval timeout;
|
|
fd_set readfds;
|
|
|
|
pmsg = (H245Message*)memAlloc(pctxt, sizeof(H245Message));
|
|
|
|
/* First read just TPKT header which is four bytes */
|
|
recvLen = ooSocketRecv (call->pH245Channel->sock, message, 4);
|
|
/* Since we are working with TCP, need to determine the
|
|
message boundary. Has to be done at channel level, as channels
|
|
know the message formats and can determine boundaries
|
|
*/
|
|
if(recvLen<=0 && call->h245SessionState != OO_H245SESSION_PAUSED)
|
|
{
|
|
if(recvLen == 0)
|
|
OOTRACEINFO3("Closing H.245 channels as remote end point closed H.245"
|
|
" connection (%s, %s)\n", call->callType, call->callToken);
|
|
else
|
|
OOTRACEERR3("Error: Transport failure while trying to receive H245"
|
|
" message (%s, %s)\n", call->callType, call->callToken);
|
|
|
|
ooCloseH245Connection(call);
|
|
ooFreeH245Message(call, pmsg);
|
|
if(call->callState < OO_CALL_CLEAR)
|
|
{
|
|
call->callEndReason = OO_REASON_TRANSPORTFAILURE;
|
|
call->callState = OO_CALL_CLEAR;
|
|
}
|
|
return OO_FAILED;
|
|
}
|
|
if(call->h245SessionState == OO_H245SESSION_PAUSED)
|
|
{
|
|
ooLogicalChannel *temp;
|
|
|
|
OOTRACEINFO3("Call Paused, closing logical channels"
|
|
" (%s, %s)\n", call->callType, call->callToken);
|
|
|
|
temp = call->logicalChans;
|
|
while(temp)
|
|
{
|
|
if(temp->state == OO_LOGICALCHAN_ESTABLISHED)
|
|
{
|
|
/* Sending closelogicalchannel only for outgoing channels*/
|
|
if(!strcmp(temp->dir, "transmit"))
|
|
{
|
|
ooSendCloseLogicalChannel(call, temp);
|
|
}
|
|
}
|
|
temp = temp->next;
|
|
}
|
|
call->masterSlaveState = OO_MasterSlave_Idle;
|
|
call->callState = OO_CALL_PAUSED;
|
|
call->localTermCapState = OO_LocalTermCapExchange_Idle;
|
|
call->remoteTermCapState = OO_RemoteTermCapExchange_Idle;
|
|
call->h245SessionState = OO_H245SESSION_IDLE;
|
|
call->logicalChans = NULL;
|
|
}
|
|
OOTRACEDBGC1("Receiving H245 message\n");
|
|
if(recvLen != 4)
|
|
{
|
|
OOTRACEERR3("Error: Reading TPKT header for H245 message (%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
ooFreeH245Message(call, pmsg);
|
|
if(call->callState < OO_CALL_CLEAR)
|
|
{
|
|
call->callEndReason = OO_REASON_INVALIDMESSAGE;
|
|
call->callState = OO_CALL_CLEAR;
|
|
}
|
|
return OO_FAILED;
|
|
}
|
|
|
|
len = message[2];
|
|
len = len<<8;
|
|
len = (len | message[3]);
|
|
/* Remaining message length is length - tpkt length */
|
|
len = len - 4;
|
|
/* Now read actual H245 message body. We should make sure that we
|
|
receive complete message as indicated by len. If we don't then there
|
|
is something wrong. The loop below receives message, then checks whether
|
|
complete message is received. If not received, then uses select to peek
|
|
for remaining bytes of the message. If message is not received in 3
|
|
seconds, then we have a problem. Report an error and exit.
|
|
*/
|
|
while(total < len)
|
|
{
|
|
recvLen = ooSocketRecv (call->pH245Channel->sock, message1, len-total);
|
|
memcpy(message+total, message1, recvLen);
|
|
total = total + recvLen;
|
|
if(total == len) break; /* Complete message is received */
|
|
FD_ZERO(&readfds);
|
|
FD_SET(call->pH245Channel->sock, &readfds);
|
|
timeout.tv_sec = 3;
|
|
timeout.tv_usec = 0;
|
|
ret = ooSocketSelect(call->pH245Channel->sock+1, &readfds, NULL,
|
|
NULL, &timeout);
|
|
if(ret == -1)
|
|
{
|
|
OOTRACEERR3("Error in select...H245 Receive-Clearing call (%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
ooFreeH245Message(call, pmsg);
|
|
if(call->callState < OO_CALL_CLEAR)
|
|
{
|
|
call->callEndReason = OO_REASON_TRANSPORTFAILURE;
|
|
call->callState = OO_CALL_CLEAR;
|
|
}
|
|
return OO_FAILED;
|
|
}
|
|
/* If remaining part of the message is not received in 3 seconds
|
|
exit */
|
|
if(!FD_ISSET(call->pH245Channel->sock, &readfds))
|
|
{
|
|
OOTRACEERR3("Error: Incomplete h245 message received (%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
ooFreeH245Message(call, pmsg);
|
|
if(call->callState < OO_CALL_CLEAR)
|
|
{
|
|
call->callEndReason = OO_REASON_TRANSPORTFAILURE;
|
|
call->callState = OO_CALL_CLEAR;
|
|
}
|
|
return OO_FAILED;
|
|
}
|
|
}
|
|
|
|
OOTRACEDBGC3("Complete H245 message received (%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
setPERBuffer(pctxt, message, recvLen, aligned);
|
|
initializePrintHandler(&printHandler, "Received H.245 Message");
|
|
|
|
/* Set event handler */
|
|
setEventHandler (pctxt, &printHandler);
|
|
|
|
ret = asn1PD_H245MultimediaSystemControlMessage(pctxt, &(pmsg->h245Msg));
|
|
if(ret != ASN_OK)
|
|
{
|
|
OOTRACEERR3("Error decoding H245 message (%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
ooFreeH245Message(call, pmsg);
|
|
return OO_FAILED;
|
|
}
|
|
finishPrint();
|
|
removeEventHandler(pctxt);
|
|
ooHandleH245Message(call, pmsg);
|
|
return OO_OK;
|
|
}
|
|
|
|
/* Generic Send Message functionality. Based on type of message to be sent,
|
|
it calls the corresponding function to retrieve the message buffer and
|
|
then transmits on the associated channel
|
|
Interpreting msgptr:
|
|
Q931 messages except facility
|
|
1st octet - msgType, next 4 octets - tpkt header,
|
|
followed by encoded msg
|
|
Q931 message facility
|
|
1st octect - OOFacility, 2nd octet - tunneled msg
|
|
type(in case no tunneled msg - OOFacility),
|
|
3rd and 4th octet - associated logical channel
|
|
of the tunneled msg(0 when no channel is
|
|
associated. ex. in case of MSD, TCS), next
|
|
4 octets - tpkt header, followed by encoded
|
|
message.
|
|
|
|
H.245 messages no tunneling
|
|
1st octet - msg type, next two octets - logical
|
|
channel number(0, when no channel is associated),
|
|
next two octets - total length of the message
|
|
(including tpkt header)
|
|
|
|
H.245 messages - tunneling.
|
|
1st octet - msg type, next two octets - logical
|
|
channel number(0, when no channel is associated),
|
|
next two octets - total length of the message.
|
|
Note, no tpkt header is present in this case.
|
|
|
|
*/
|
|
int ooSendMsg(OOH323CallData *call, int type)
|
|
{
|
|
|
|
int len=0, ret=0, msgType=0, tunneledMsgType=0, logicalChannelNo = 0;
|
|
DListNode * p_msgNode=NULL;
|
|
ASN1OCTET *msgptr, *msgToSend=NULL;
|
|
|
|
|
|
|
|
if(call->callState == OO_CALL_CLEARED)
|
|
{
|
|
OOTRACEDBGA3("Warning:Call marked for cleanup. Can not send message."
|
|
"(%s, %s)\n", call->callType, call->callToken);
|
|
return OO_OK;
|
|
}
|
|
|
|
if(type == OOQ931MSG)
|
|
{
|
|
if(call->pH225Channel->outQueue.count == 0)
|
|
{
|
|
OOTRACEWARN3("WARN:No H.2250 message to send. (%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
return OO_FAILED;
|
|
}
|
|
|
|
OOTRACEDBGA3("Sending Q931 message (%s, %s)\n", call->callType,
|
|
call->callToken);
|
|
p_msgNode = call->pH225Channel->outQueue.head;
|
|
msgptr = (ASN1OCTET*) p_msgNode->data;
|
|
msgType = msgptr[0];
|
|
|
|
if(msgType == OOFacility)
|
|
{
|
|
tunneledMsgType = msgptr[1];
|
|
logicalChannelNo = msgptr[2];
|
|
logicalChannelNo = logicalChannelNo << 8;
|
|
logicalChannelNo = (logicalChannelNo | msgptr[3]);
|
|
len = msgptr[6];
|
|
len = len<<8;
|
|
len = (len | msgptr[7]);
|
|
msgToSend = msgptr+4;
|
|
}
|
|
else {
|
|
len = msgptr[3];
|
|
len = len<<8;
|
|
len = (len | msgptr[4]);
|
|
msgToSend = msgptr+1;
|
|
}
|
|
|
|
/* Remove the message from rtdlist pH225Channel->outQueue */
|
|
dListRemove(&(call->pH225Channel->outQueue), p_msgNode);
|
|
if(p_msgNode)
|
|
memFreePtr(call->pctxt, p_msgNode);
|
|
|
|
/*TODO: This is not required ideally. We will see for some time and if
|
|
we don't face any problems we will delete this code */
|
|
#if 0
|
|
/* Check whether connection with remote is alright */
|
|
if(!ooChannelsIsConnectionOK(call, call->pH225Channel->sock))
|
|
{
|
|
OOTRACEERR3("Error:Transport failure for signalling channel. "
|
|
"Abandoning message send and marking call for cleanup.(%s"
|
|
"'%s)\n", call->callType, call->callToken);
|
|
if(call->callState < OO_CALL_CLEAR)
|
|
call->callEndReason = OO_REASON_TRANSPORTFAILURE;
|
|
call->callState = OO_CALL_CLEARED;
|
|
return OO_OK;
|
|
}
|
|
#endif
|
|
/* Send message out via TCP */
|
|
ret = ooSocketSend(call->pH225Channel->sock, msgToSend, len);
|
|
if(ret == ASN_OK)
|
|
{
|
|
memFreePtr (call->pctxt, msgptr);
|
|
OOTRACEDBGC3("H2250/Q931 Message sent successfully (%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
ooOnSendMsg(call, msgType, tunneledMsgType, logicalChannelNo);
|
|
return OO_OK;
|
|
}
|
|
else{
|
|
OOTRACEERR3("H2250Q931 Message send failed (%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
memFreePtr (call->pctxt, msgptr);
|
|
if(call->callState < OO_CALL_CLEAR)
|
|
{
|
|
call->callEndReason = OO_REASON_TRANSPORTFAILURE;
|
|
call->callState = OO_CALL_CLEAR;
|
|
}
|
|
return OO_FAILED;
|
|
}
|
|
}/* end of type==OOQ931MSG */
|
|
if(type == OOH245MSG)
|
|
{
|
|
if(call->pH245Channel->outQueue.count == 0)
|
|
{
|
|
OOTRACEWARN3("WARN:No H.245 message to send. (%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
return OO_FAILED;
|
|
}
|
|
OOTRACEDBGA3("Sending H245 message (%s, %s)\n", call->callType,
|
|
call->callToken);
|
|
p_msgNode = call->pH245Channel->outQueue.head;
|
|
msgptr = (ASN1OCTET*) p_msgNode->data;
|
|
msgType = msgptr[0];
|
|
|
|
logicalChannelNo = msgptr[1];
|
|
logicalChannelNo = logicalChannelNo << 8;
|
|
logicalChannelNo = (logicalChannelNo | msgptr[2]);
|
|
|
|
len = msgptr[3];
|
|
len = len<<8;
|
|
len = (len | msgptr[4]);
|
|
/* Remove the message from queue */
|
|
dListRemove(&(call->pH245Channel->outQueue), p_msgNode);
|
|
if(p_msgNode)
|
|
memFreePtr(call->pctxt, p_msgNode);
|
|
|
|
/* Send message out */
|
|
if (0 == call->pH245Channel && !OO_TESTFLAG(call->flags, OO_M_TUNNELING))
|
|
{
|
|
OOTRACEWARN3("Neither H.245 channel nor tunneling active "
|
|
"(%s, %s)\n", call->callType, call->callToken);
|
|
memFreePtr (call->pctxt, msgptr);
|
|
/*ooCloseH245Session(call);*/
|
|
if(call->callState < OO_CALL_CLEAR)
|
|
{
|
|
call->callEndReason = OO_REASON_TRANSPORTFAILURE;
|
|
call->callState = OO_CALL_CLEAR;
|
|
}
|
|
return OO_OK;
|
|
}
|
|
|
|
if (0 != call->pH245Channel && 0 != call->pH245Channel->sock)
|
|
{
|
|
OOTRACEDBGC4("Sending %s H245 message over H.245 channel. "
|
|
"(%s, %s)\n", ooGetMsgTypeText(msgType),
|
|
call->callType, call->callToken);
|
|
|
|
ret = ooSocketSend(call->pH245Channel->sock, msgptr+5, len);
|
|
if(ret == ASN_OK)
|
|
{
|
|
memFreePtr (call->pctxt, msgptr);
|
|
OOTRACEDBGA3("H245 Message sent successfully (%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
ooOnSendMsg(call, msgType, tunneledMsgType, logicalChannelNo);
|
|
return OO_OK;
|
|
}
|
|
else{
|
|
memFreePtr (call->pctxt, msgptr);
|
|
OOTRACEERR3("ERROR:H245 Message send failed (%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
if(call->callState < OO_CALL_CLEAR)
|
|
{
|
|
call->callEndReason = OO_REASON_TRANSPORTFAILURE;
|
|
call->callState = OO_CALL_CLEAR;
|
|
}
|
|
return OO_FAILED;
|
|
}
|
|
}
|
|
else if(OO_TESTFLAG (call->flags, OO_M_TUNNELING)) {
|
|
OOTRACEDBGC4("Sending %s H245 message as a tunneled message."
|
|
"(%s, %s)\n", ooGetMsgTypeText(msgType),
|
|
call->callType, call->callToken);
|
|
|
|
ret = ooSendAsTunneledMessage
|
|
(call, msgptr+5,len,msgType, logicalChannelNo);
|
|
|
|
if(ret != OO_OK)
|
|
{
|
|
memFreePtr (call->pctxt, msgptr);
|
|
OOTRACEERR3("ERROR:Failed to tunnel H.245 message (%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
if(call->callState < OO_CALL_CLEAR)
|
|
{
|
|
call->callEndReason = OO_REASON_INVALIDMESSAGE;
|
|
call->callState = OO_CALL_CLEAR;
|
|
}
|
|
return OO_FAILED;
|
|
}
|
|
memFreePtr (call->pctxt, msgptr);
|
|
return OO_OK;
|
|
}
|
|
}
|
|
/* Need to add support for other messages such as T38 etc */
|
|
OOTRACEWARN3("ERROR:Unknown message type - message not Sent (%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
return OO_FAILED;
|
|
}
|
|
|
|
int ooCloseH245Connection(OOH323CallData *call)
|
|
{
|
|
OOTRACEINFO3("Closing H.245 connection (%s, %s)\n", call->callType,
|
|
call->callToken);
|
|
|
|
if (0 != call->pH245Channel)
|
|
{
|
|
if(0 != call->pH245Channel->sock)
|
|
ooSocketClose (call->pH245Channel->sock);
|
|
if (call->pH245Channel->outQueue.count > 0)
|
|
dListFreeAll(call->pctxt, &(call->pH245Channel->outQueue));
|
|
memFreePtr (call->pctxt, call->pH245Channel);
|
|
call->pH245Channel = NULL;
|
|
OOTRACEDBGC3("Closed H245 connection. (%s, %s)\n", call->callType,
|
|
call->callToken);
|
|
}
|
|
call->h245SessionState = OO_H245SESSION_CLOSED;
|
|
|
|
return OO_OK;
|
|
}
|
|
|
|
int ooCloseH245Listener(OOH323CallData *call)
|
|
{
|
|
OOTRACEINFO3("Closing H.245 Listener (%s, %s)\n", call->callType,
|
|
call->callToken);
|
|
if(call->h245listener)
|
|
{
|
|
ooSocketClose(*(call->h245listener));
|
|
memFreePtr(call->pctxt, call->h245listener);
|
|
call->h245listener = NULL;
|
|
}
|
|
return OO_OK;
|
|
}
|
|
|
|
int ooOnSendMsg
|
|
(OOH323CallData *call, int msgType, int tunneledMsgType, int associatedChan)
|
|
{
|
|
ooTimerCallback *cbData=NULL;
|
|
switch(msgType)
|
|
{
|
|
case OOSetup:
|
|
OOTRACEINFO3("Sent Message - Setup (%s, %s)\n", call->callType,
|
|
call->callToken);
|
|
/* Start call establishment timer */
|
|
cbData = (ooTimerCallback*) memAlloc(call->pctxt,
|
|
sizeof(ooTimerCallback));
|
|
if(!cbData)
|
|
{
|
|
OOTRACEERR3("Error:Unable to allocate memory for timer callback."
|
|
"(%s, %s)\n", call->callType, call->callToken);
|
|
return OO_FAILED;
|
|
}
|
|
cbData->call = call;
|
|
cbData->timerType = OO_CALLESTB_TIMER;
|
|
if(!ooTimerCreate(call->pctxt, &call->timerList, &ooCallEstbTimerExpired,
|
|
gH323ep.callEstablishmentTimeout, cbData, FALSE))
|
|
{
|
|
OOTRACEERR3("Error:Unable to create call establishment timer. "
|
|
"(%s, %s)\n", call->callType, call->callToken);
|
|
memFreePtr(call->pctxt, cbData);
|
|
return OO_FAILED;
|
|
}
|
|
|
|
if(gH323ep.h323Callbacks.onOutgoingCall)
|
|
gH323ep.h323Callbacks.onOutgoingCall(call);
|
|
break;
|
|
case OOCallProceeding:
|
|
OOTRACEINFO3("Sent Message - CallProceeding (%s, %s)\n", call->callType,
|
|
call->callToken);
|
|
break;
|
|
case OOAlert:
|
|
OOTRACEINFO3("Sent Message - Alerting (%s, %s) \n", call->callType,
|
|
call->callToken);
|
|
if(gH323ep.h323Callbacks.onAlerting && call->callState < OO_CALL_CLEAR)
|
|
gH323ep.h323Callbacks.onAlerting(call);
|
|
break;
|
|
case OOConnect:
|
|
OOTRACEINFO3("Sent Message - Connect (%s, %s)\n", call->callType,
|
|
call->callToken);
|
|
if(gH323ep.h323Callbacks.onCallEstablished)
|
|
gH323ep.h323Callbacks.onCallEstablished(call);
|
|
break;
|
|
case OOReleaseComplete:
|
|
OOTRACEINFO3("Sent Message - ReleaseComplete (%s, %s)\n", call->callType,
|
|
call->callToken);
|
|
|
|
if(call->callState == OO_CALL_CLEAR_RELEASERECVD)
|
|
call->callState = OO_CALL_CLEARED;
|
|
else{
|
|
call->callState = OO_CALL_CLEAR_RELEASESENT;
|
|
if(gH323ep.gkClient && !OO_TESTFLAG(call->flags, OO_M_DISABLEGK) &&
|
|
gH323ep.gkClient->state == GkClientRegistered){
|
|
OOTRACEDBGA3("Sending DRQ after sending ReleaseComplete."
|
|
"(%s, %s)\n", call->callType, call->callToken);
|
|
ooGkClientSendDisengageRequest(gH323ep.gkClient, call);
|
|
}
|
|
}
|
|
|
|
if(call->callState == OO_CALL_CLEAR_RELEASESENT &&
|
|
call->h245SessionState == OO_H245SESSION_IDLE)
|
|
{
|
|
cbData = (ooTimerCallback*) memAlloc(call->pctxt,
|
|
sizeof(ooTimerCallback));
|
|
if(!cbData)
|
|
{
|
|
OOTRACEERR3("Error:Unable to allocate memory for timer callback "
|
|
"data.(%s, %s)\n", call->callType, call->callToken);
|
|
return OO_FAILED;
|
|
}
|
|
cbData->call = call;
|
|
cbData->timerType = OO_SESSION_TIMER;
|
|
cbData->channelNumber = 0;
|
|
if(!ooTimerCreate(call->pctxt, &call->timerList,
|
|
&ooSessionTimerExpired, gH323ep.sessionTimeout, cbData, FALSE))
|
|
{
|
|
OOTRACEERR3("Error:Unable to create EndSession timer- "
|
|
"ReleaseComplete.(%s, %s)\n", call->callType,
|
|
call->callToken);
|
|
memFreePtr(call->pctxt, cbData);
|
|
return OO_FAILED;
|
|
}
|
|
}
|
|
|
|
if(call->h245SessionState == OO_H245SESSION_CLOSED)
|
|
{
|
|
call->callState = OO_CALL_CLEARED;
|
|
}
|
|
break;
|
|
|
|
case OOFacility:
|
|
if(tunneledMsgType == OOFacility)
|
|
{
|
|
OOTRACEINFO3("Sent Message - Facility. (%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
}
|
|
else{
|
|
OOTRACEINFO4("Sent Message - Facility(%s) (%s, %s)\n",
|
|
ooGetMsgTypeText(tunneledMsgType),
|
|
call->callType, call->callToken);
|
|
|
|
ooOnSendMsg(call, tunneledMsgType, 0, associatedChan);
|
|
}
|
|
break;
|
|
|
|
case OOMasterSlaveDetermination:
|
|
if(OO_TESTFLAG (call->flags, OO_M_TUNNELING))
|
|
OOTRACEINFO3("Tunneled Message - MasterSlaveDetermination (%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
else
|
|
OOTRACEINFO3("Sent Message - MasterSlaveDetermination (%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
/* Start MSD timer */
|
|
cbData = (ooTimerCallback*) memAlloc(call->pctxt,
|
|
sizeof(ooTimerCallback));
|
|
if(!cbData)
|
|
{
|
|
OOTRACEERR3("Error:Unable to allocate memory for timer callback data."
|
|
"(%s, %s)\n", call->callType, call->callToken);
|
|
return OO_FAILED;
|
|
}
|
|
cbData->call = call;
|
|
cbData->timerType = OO_MSD_TIMER;
|
|
if(!ooTimerCreate(call->pctxt, &call->timerList, &ooMSDTimerExpired,
|
|
gH323ep.msdTimeout, cbData, FALSE))
|
|
{
|
|
OOTRACEERR3("Error:Unable to create MSD timer. "
|
|
"(%s, %s)\n", call->callType, call->callToken);
|
|
memFreePtr(call->pctxt, cbData);
|
|
return OO_FAILED;
|
|
}
|
|
|
|
break;
|
|
case OOMasterSlaveAck:
|
|
if(OO_TESTFLAG (call->flags, OO_M_TUNNELING))
|
|
OOTRACEINFO3("Tunneled Message - MasterSlaveDeterminationAck (%s, %s)"
|
|
"\n", call->callType, call->callToken);
|
|
else
|
|
OOTRACEINFO3("Sent Message - MasterSlaveDeterminationAck (%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
break;
|
|
case OOMasterSlaveReject:
|
|
if(OO_TESTFLAG (call->flags, OO_M_TUNNELING))
|
|
OOTRACEINFO3("Tunneled Message - MasterSlaveDeterminationReject "
|
|
"(%s, %s)\n", call->callType, call->callToken);
|
|
else
|
|
OOTRACEINFO3("Sent Message - MasterSlaveDeterminationReject(%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
break;
|
|
case OOMasterSlaveRelease:
|
|
if(OO_TESTFLAG (call->flags, OO_M_TUNNELING))
|
|
OOTRACEINFO3("Tunneled Message - MasterSlaveDeterminationRelease "
|
|
"(%s, %s)\n", call->callType, call->callToken);
|
|
else
|
|
OOTRACEINFO3("Sent Message - MasterSlaveDeterminationRelease "
|
|
"(%s, %s)\n", call->callType, call->callToken);
|
|
break;
|
|
case OOTerminalCapabilitySet:
|
|
if(OO_TESTFLAG (call->flags, OO_M_TUNNELING)) {
|
|
/* If session isn't marked active yet, do it. possible in case of
|
|
tunneling */
|
|
if(call->h245SessionState == OO_H245SESSION_IDLE ||
|
|
call->h245SessionState == OO_H245SESSION_PAUSED) {
|
|
call->h245SessionState = OO_H245SESSION_ACTIVE;
|
|
}
|
|
OOTRACEINFO3("Tunneled Message - TerminalCapabilitySet (%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
}
|
|
else {
|
|
OOTRACEINFO3("Sent Message - TerminalCapabilitySet (%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
}
|
|
/* Start TCS timer */
|
|
cbData = (ooTimerCallback*) memAlloc(call->pctxt,
|
|
sizeof(ooTimerCallback));
|
|
if(!cbData)
|
|
{
|
|
OOTRACEERR3("Error:Unable to allocate memory for timer callback data."
|
|
"(%s, %s)\n", call->callType, call->callToken);
|
|
return OO_FAILED;
|
|
}
|
|
cbData->call = call;
|
|
cbData->timerType = OO_TCS_TIMER;
|
|
if(!ooTimerCreate(call->pctxt, &call->timerList, &ooTCSTimerExpired,
|
|
gH323ep.tcsTimeout, cbData, FALSE))
|
|
{
|
|
OOTRACEERR3("Error:Unable to create TCS timer. "
|
|
"(%s, %s)\n", call->callType, call->callToken);
|
|
memFreePtr(call->pctxt, cbData);
|
|
return OO_FAILED;
|
|
}
|
|
break;
|
|
|
|
|
|
case OOTerminalCapabilitySetAck:
|
|
if(OO_TESTFLAG (call->flags, OO_M_TUNNELING))
|
|
OOTRACEINFO3("Tunneled Message - TerminalCapabilitySetAck (%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
else
|
|
OOTRACEINFO3("Sent Message - TerminalCapabilitySetAck (%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
break;
|
|
case OOTerminalCapabilitySetReject:
|
|
if(OO_TESTFLAG (call->flags, OO_M_TUNNELING))
|
|
OOTRACEINFO3("Tunneled Message - TerminalCapabilitySetReject "
|
|
"(%s, %s)\n", call->callType, call->callToken);
|
|
else
|
|
OOTRACEINFO3("Sent Message - TerminalCapabilitySetReject (%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
break;
|
|
case OOOpenLogicalChannel:
|
|
if(OO_TESTFLAG (call->flags, OO_M_TUNNELING))
|
|
OOTRACEINFO4("Tunneled Message - OpenLogicalChannel(%d). (%s, %s)\n",
|
|
associatedChan, call->callType, call->callToken);
|
|
else
|
|
OOTRACEINFO4("Sent Message - OpenLogicalChannel(%d). (%s, %s)\n",
|
|
associatedChan, call->callType, call->callToken);
|
|
/* Start LogicalChannel timer */
|
|
cbData = (ooTimerCallback*) memAlloc(call->pctxt,
|
|
sizeof(ooTimerCallback));
|
|
if(!cbData)
|
|
{
|
|
OOTRACEERR3("Error:Unable to allocate memory for timer callback data."
|
|
"(%s, %s)\n", call->callType, call->callToken);
|
|
return OO_FAILED;
|
|
}
|
|
cbData->call = call;
|
|
cbData->timerType = OO_OLC_TIMER;
|
|
cbData->channelNumber = associatedChan;
|
|
if(!ooTimerCreate(call->pctxt, &call->timerList,
|
|
&ooOpenLogicalChannelTimerExpired, gH323ep.logicalChannelTimeout,
|
|
cbData, FALSE))
|
|
{
|
|
OOTRACEERR3("Error:Unable to create OpenLogicalChannel timer. "
|
|
"(%s, %s)\n", call->callType, call->callToken);
|
|
memFreePtr(call->pctxt, cbData);
|
|
return OO_FAILED;
|
|
}
|
|
|
|
break;
|
|
case OOOpenLogicalChannelAck:
|
|
if(OO_TESTFLAG (call->flags, OO_M_TUNNELING))
|
|
OOTRACEINFO4("Tunneled Message - OpenLogicalChannelAck(%d) (%s,%s)\n",
|
|
associatedChan, call->callType, call->callToken);
|
|
else
|
|
OOTRACEINFO4("Sent Message - OpenLogicalChannelAck(%d) (%s, %s)\n",
|
|
associatedChan, call->callType, call->callToken);
|
|
break;
|
|
case OOOpenLogicalChannelReject:
|
|
if(OO_TESTFLAG (call->flags, OO_M_TUNNELING))
|
|
OOTRACEINFO4("Tunneled Message - OpenLogicalChannelReject(%d)"
|
|
"(%s, %s)\n", associatedChan, call->callType,
|
|
call->callToken);
|
|
else
|
|
OOTRACEINFO4("Sent Message - OpenLogicalChannelReject(%d) (%s, %s)\n",
|
|
associatedChan, call->callType, call->callToken);
|
|
break;
|
|
case OOEndSessionCommand:
|
|
if(OO_TESTFLAG (call->flags, OO_M_TUNNELING))
|
|
OOTRACEINFO3("Tunneled Message - EndSessionCommand(%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
else
|
|
OOTRACEINFO3("Sent Message - EndSessionCommand (%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
if((call->h245SessionState == OO_H245SESSION_ACTIVE))
|
|
{
|
|
/* Start EndSession timer */
|
|
call->h245SessionState = OO_H245SESSION_ENDSENT;
|
|
cbData = (ooTimerCallback*) memAlloc(call->pctxt,
|
|
sizeof(ooTimerCallback));
|
|
if(!cbData)
|
|
{
|
|
OOTRACEERR3("Error:Unable to allocate memory for timer callback "
|
|
"data.(%s, %s)\n", call->callType, call->callToken);
|
|
return OO_FAILED;
|
|
}
|
|
cbData->call = call;
|
|
cbData->timerType = OO_SESSION_TIMER;
|
|
cbData->channelNumber = 0;
|
|
if(!ooTimerCreate(call->pctxt, &call->timerList,
|
|
&ooSessionTimerExpired, gH323ep.sessionTimeout, cbData, FALSE))
|
|
{
|
|
OOTRACEERR3("Error:Unable to create EndSession timer. "
|
|
"(%s, %s)\n", call->callType, call->callToken);
|
|
memFreePtr(call->pctxt, cbData);
|
|
return OO_FAILED;
|
|
}
|
|
}
|
|
else{
|
|
ooCloseH245Connection(call);
|
|
}
|
|
break;
|
|
case OOCloseLogicalChannel:
|
|
if(OO_TESTFLAG (call->flags, OO_M_TUNNELING))
|
|
OOTRACEINFO3("Tunneled Message - CloseLogicalChannel (%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
else
|
|
OOTRACEINFO3("Sent Message - CloseLogicalChannel (%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
/* Start LogicalChannel timer */
|
|
cbData = (ooTimerCallback*) memAlloc(call->pctxt,
|
|
sizeof(ooTimerCallback));
|
|
if(!cbData)
|
|
{
|
|
OOTRACEERR3("Error:Unable to allocate memory for timer callback data."
|
|
"(%s, %s)\n", call->callType, call->callToken);
|
|
return OO_FAILED;
|
|
}
|
|
cbData->call = call;
|
|
cbData->timerType = OO_CLC_TIMER;
|
|
cbData->channelNumber = associatedChan;
|
|
if(!ooTimerCreate(call->pctxt, &call->timerList,
|
|
&ooCloseLogicalChannelTimerExpired, gH323ep.logicalChannelTimeout,
|
|
cbData, FALSE))
|
|
{
|
|
OOTRACEERR3("Error:Unable to create CloseLogicalChannel timer. "
|
|
"(%s, %s)\n", call->callType, call->callToken);
|
|
memFreePtr(call->pctxt, cbData);
|
|
return OO_FAILED;
|
|
}
|
|
|
|
break;
|
|
case OOCloseLogicalChannelAck:
|
|
if(OO_TESTFLAG (call->flags, OO_M_TUNNELING))
|
|
OOTRACEINFO3("Tunneled Message - CloseLogicalChannelAck (%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
else
|
|
OOTRACEINFO3("Sent Message - CloseLogicalChannelAck (%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
break;
|
|
case OORequestChannelClose:
|
|
if(OO_TESTFLAG (call->flags, OO_M_TUNNELING))
|
|
OOTRACEINFO3("Tunneled Message - RequestChannelClose (%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
else
|
|
OOTRACEINFO3("Sent Message - RequestChannelClose (%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
/* Start RequestChannelClose timer */
|
|
cbData = (ooTimerCallback*) memAlloc(call->pctxt,
|
|
sizeof(ooTimerCallback));
|
|
if(!cbData)
|
|
{
|
|
OOTRACEERR3("Error:Unable to allocate memory for timer callback data."
|
|
"(%s, %s)\n", call->callType, call->callToken);
|
|
return OO_FAILED;
|
|
}
|
|
cbData->call = call;
|
|
cbData->timerType = OO_RCC_TIMER;
|
|
cbData->channelNumber = associatedChan;
|
|
if(!ooTimerCreate(call->pctxt, &call->timerList,
|
|
&ooRequestChannelCloseTimerExpired, gH323ep.logicalChannelTimeout,
|
|
cbData, FALSE))
|
|
{
|
|
OOTRACEERR3("Error:Unable to create RequestChannelClose timer. "
|
|
"(%s, %s)\n", call->callType, call->callToken);
|
|
memFreePtr(call->pctxt, cbData);
|
|
return OO_FAILED;
|
|
}
|
|
break;
|
|
case OORequestChannelCloseAck:
|
|
if(OO_TESTFLAG (call->flags, OO_M_TUNNELING))
|
|
OOTRACEINFO3("Tunneled Message - RequestChannelCloseAck (%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
else
|
|
OOTRACEINFO3("Sent Message - RequestChannelCloseAck (%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
break;
|
|
|
|
default:
|
|
;
|
|
}
|
|
return OO_OK;
|
|
}
|
|
|
|
|
|
int ooStopMonitorCalls()
|
|
{
|
|
OOH323CallData * call;
|
|
if(gMonitor)
|
|
{
|
|
OOTRACEINFO1("Doing ooStopMonitorCalls\n");
|
|
if(gH323ep.cmdSock)
|
|
{
|
|
ooCloseCmdConnection();
|
|
}
|
|
|
|
if(gH323ep.callList)
|
|
{
|
|
OOTRACEWARN1("Warn:Abruptly ending calls as stack going down\n");
|
|
call = gH323ep.callList;
|
|
while(call)
|
|
{
|
|
OOTRACEWARN3("Clearing call (%s, %s)\n", call->callType,
|
|
call->callToken);
|
|
call->callEndReason = OO_REASON_LOCAL_CLEARED;
|
|
ooCleanCall(call);
|
|
call = NULL;
|
|
call = gH323ep.callList;
|
|
}
|
|
gH323ep.callList = NULL;
|
|
}
|
|
OOTRACEINFO1("Stopping listener for incoming calls\n");
|
|
if(gH323ep.listener)
|
|
{
|
|
ooSocketClose(*(gH323ep.listener));
|
|
memFreePtr(&gH323ep.ctxt, gH323ep.listener);
|
|
gH323ep.listener = NULL;
|
|
}
|
|
|
|
gMonitor = FALSE;
|
|
OOTRACEINFO1("Done ooStopMonitorCalls\n");
|
|
}
|
|
return OO_OK;
|
|
}
|
|
|
|
OOBOOL ooChannelsIsConnectionOK(OOH323CallData *call, OOSOCKET sock)
|
|
{
|
|
struct timeval to;
|
|
fd_set readfds;
|
|
int ret = 0, nfds=0;
|
|
|
|
to.tv_sec = 0;
|
|
to.tv_usec = 500;
|
|
FD_ZERO(&readfds);
|
|
|
|
FD_SET(sock, &readfds);
|
|
if(nfds < (int)sock)
|
|
nfds = (int)sock;
|
|
|
|
nfds++;
|
|
|
|
ret = ooSocketSelect(nfds, &readfds, NULL, NULL, &to);
|
|
|
|
if(ret == -1)
|
|
{
|
|
OOTRACEERR3("Error in select ...broken pipe check(%s, %s)\n",
|
|
call->callType, call->callToken );
|
|
return FALSE;
|
|
}
|
|
|
|
if(FD_ISSET(sock, &readfds))
|
|
{
|
|
char buf[2];
|
|
if(ooSocketRecvPeek(sock, buf, 2) == 0)
|
|
{
|
|
OOTRACEWARN3("Broken pipe detected. (%s, %s)", call->callType,
|
|
call->callToken);
|
|
if(call->callState < OO_CALL_CLEAR)
|
|
call->callEndReason = OO_REASON_TRANSPORTFAILURE;
|
|
call->callState = OO_CALL_CLEARED;
|
|
return FALSE;
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|