2 * Copyright (C) 2004-2005 by Objective Systems, Inc.
4 * This software is furnished under an open source license and may be
5 * used and copied only in accordance with the terms of this license.
6 * The text of the license may generally be found in the root
7 * directory of this installation in the COPYING file. It
8 * can also be viewed online at the following URL:
10 * http://www.obj-sys.com/open/license.html
12 * Any redistributions of this file including modified versions must
13 * maintain this copyright notice.
15 *****************************************************************************/
17 #include "asterisk/lock.h"
20 #include "oochannels.h"
26 #include "printHandler.h"
27 #include "ooGkClient.h"
31 #include "ooStackCmds.h"
32 #include "ooCmdChannel.h"
36 /** Global endpoint structure */
37 extern OOH323EndPoint gH323ep;
38 extern ast_mutex_t callListLock;
39 extern ast_mutex_t monitorLock;
41 extern DList g_TimerList;
43 static OOBOOL gMonitor = FALSE;
45 int ooSetCmdFDSETs(struct pollfd *pfds, int *nfds);
46 int ooProcessCmdFDSETsAndTimers
47 (struct pollfd *pfds, int nfds, struct timeval *pToMin);
48 int ooSetFDSETs(struct pollfd *pfds, int *nfds);
49 int ooProcessFDSETsAndTimers
50 (struct pollfd* pfds, int nfds, struct timeval *pToMin);
51 int ooProcessCallFDSETsAndTimers
52 (OOH323CallData *call, struct pollfd* pfds, int nfds, struct timeval *pToMin);
53 int ooSetCallFDSETs(OOH323CallData* call, struct pollfd* pfds, int *nfds);
57 int ooCreateH245Listener(OOH323CallData *call)
60 OOSOCKET channelSocket=0;
61 OOTRACEINFO1("Creating H245 listener\n");
62 if((ret=ooSocketCreate (&channelSocket))!=ASN_OK)
64 OOTRACEERR3("ERROR: Failed to create socket for H245 listener "
65 "(%s, %s)\n", call->callType, call->callToken);
68 ret = ooBindPort (OOTCP, channelSocket, call->localIP);
71 OOTRACEERR3("Error:Unable to bind to a TCP port - H245 listener creation"
72 " (%s, %s)\n", call->callType, call->callToken);
75 call->h245listenport = (int*) memAlloc(call->pctxt, sizeof(int));
76 *(call->h245listenport) = ret;
77 call->h245listener = (OOSOCKET*)memAlloc(call->pctxt, sizeof(OOSOCKET));
78 *(call->h245listener) = channelSocket;
79 ret = ooSocketListen(*(call->h245listener), 4096);
82 OOTRACEERR3("Error:Unable to listen on H.245 socket (%s, %s)\n",
83 call->callType, call->callToken);
87 OOTRACEINFO4("H245 listener creation - successful(port %d) (%s, %s)\n",
88 *(call->h245listenport),call->callType, call->callToken);
92 int ooCreateH245Connection(OOH323CallData *call)
95 OOSOCKET channelSocket=0;
96 ooTimerCallback *cbData=NULL;
98 OOTRACEINFO1("Creating H245 Connection\n");
99 if((ret=ooSocketCreate (&channelSocket))!=ASN_OK)
101 OOTRACEERR3("ERROR:Failed to create socket for H245 connection "
102 "(%s, %s)\n", call->callType, call->callToken);
107 if (0 == call->pH245Channel) {
109 (OOH323Channel*) memAllocZ (call->pctxt, sizeof(OOH323Channel));
113 bind socket to a port before connecting. Thus avoiding
114 implicit bind done by a connect call.
116 ret = ooBindPort(OOTCP, channelSocket, call->localIP);
119 OOTRACEERR3("Error:Unable to bind to a TCP port - h245 connection "
120 "(%s, %s)\n", call->callType, call->callToken);
123 call->pH245Channel->port = ret;
124 OOTRACEDBGC4("Local H.245 port is %d (%s, %s)\n",
125 call->pH245Channel->port,
126 call->callType, call->callToken);
127 OOTRACEINFO5("Trying to connect to remote endpoint to setup H245 "
128 "connection %s:%d(%s, %s)\n", call->remoteIP,
129 call->remoteH245Port, call->callType, call->callToken);
131 if((ret=ooSocketConnect(channelSocket, call->remoteIP,
132 call->remoteH245Port))==ASN_OK)
134 call->pH245Channel->sock = channelSocket;
135 call->h245SessionState = OO_H245SESSION_ACTIVE;
137 OOTRACEINFO3("H245 connection creation successful (%s, %s)\n",
138 call->callType, call->callToken);
140 /*Start terminal capability exchange and master slave determination */
141 ret = ooSendTermCapMsg(call);
144 OOTRACEERR3("ERROR:Sending Terminal capability message (%s, %s)\n",
145 call->callType, call->callToken);
148 ret = ooSendMasterSlaveDetermination(call);
151 OOTRACEERR3("ERROR:Sending Master-slave determination message "
152 "(%s, %s)\n", call->callType, call->callToken);
158 if(call->h245ConnectionAttempts >= 3)
160 OOTRACEERR3("Error:Failed to setup an H245 connection with remote "
161 "destination. (%s, %s)\n", call->callType,
163 if(call->callState < OO_CALL_CLEAR)
165 call->callEndReason = OO_REASON_TRANSPORTFAILURE;
166 call->callState = OO_CALL_CLEAR;
171 OOTRACEWARN4("Warn:Failed to connect to remote destination for "
172 "H245 connection - will retry after %d seconds"
173 "(%s, %s)\n", DEFAULT_H245CONNECTION_RETRYTIMEOUT,
174 call->callType, call->callToken);
176 cbData = (ooTimerCallback*) memAlloc(call->pctxt,
177 sizeof(ooTimerCallback));
180 OOTRACEERR3("Error:Unable to allocate memory for timer "
181 "callback.(%s, %s)\n", call->callType,
186 cbData->timerType = OO_H245CONNECT_TIMER;
187 if(!ooTimerCreate(call->pctxt, &call->timerList,
188 &ooCallH245ConnectionRetryTimerExpired,
189 DEFAULT_H245CONNECTION_RETRYTIMEOUT, cbData,
192 OOTRACEERR3("Error:Unable to create H245 connection retry timer"
193 "(%s, %s)\n", call->callType, call->callToken);
194 memFreePtr(call->pctxt, cbData);
204 int ooSendH225Msg(OOH323CallData *call, Q931Message *msg)
207 ASN1OCTET * encodebuf;
211 encodebuf = (ASN1OCTET*) memAlloc (call->pctxt, MAXMSGLEN);
214 OOTRACEERR3("Error:Failed to allocate memory for encoding H225 "
215 "message(%s, %s)\n", call->callType, call->callToken);
218 iRet = ooEncodeH225Message(call, msg, (char *)encodebuf, MAXMSGLEN);
221 OOTRACEERR3("Error:Failed to encode H225 message. (%s, %s)\n",
222 call->callType, call->callToken);
223 memFreePtr (call->pctxt, encodebuf);
227 /* If high priority messages, send immediately.*/
228 if(encodebuf[0] == OOReleaseComplete ||
229 (encodebuf[0]==OOFacility && encodebuf[1]==OOEndSessionCommand))
231 dListFreeAll(call->pctxt, &call->pH225Channel->outQueue);
232 dListAppend (call->pctxt, &call->pH225Channel->outQueue, encodebuf);
233 // ooSendMsg(call, OOQ931MSG);
236 dListAppend (call->pctxt, &call->pH225Channel->outQueue, encodebuf);
238 OOTRACEDBGC4("Queued H225 messages %d. (%s, %s)\n",
239 call->pH225Channel->outQueue.count,
240 call->callType, call->callToken);
245 int ooCreateH225Connection(OOH323CallData *call)
248 OOSOCKET channelSocket=0;
250 if((ret=ooSocketCreate (&channelSocket))!=ASN_OK)
252 OOTRACEERR3("Failed to create socket for transmit H2250 channel (%s, %s)"
253 "\n", call->callType, call->callToken);
254 if(call->callState < OO_CALL_CLEAR)
256 call->callState = OO_CALL_CLEAR;
257 call->callEndReason = OO_REASON_TRANSPORTFAILURE;
264 bind socket to a port before connecting. Thus avoiding
265 implicit bind done by a connect call. Avoided on windows as
266 windows sockets have problem in reusing the addresses even after
267 setting SO_REUSEADDR, hence in windows we just allow os to bind
271 ret = ooBindPort(OOTCP,channelSocket, call->localIP);
273 ret = ooBindOSAllocatedPort(channelSocket, call->localIP);
278 OOTRACEERR3("Error:Unable to bind to a TCP port (%s, %s)\n",
279 call->callType, call->callToken);
280 if(call->callState < OO_CALL_CLEAR)
282 call->callState = OO_CALL_CLEAR;
283 call->callEndReason = OO_REASON_TRANSPORTFAILURE;
288 if (0 == call->pH225Channel) {
290 (OOH323Channel*) memAllocZ (call->pctxt, sizeof(OOH323Channel));
292 call->pH225Channel->port = ret;
294 OOTRACEINFO5("Trying to connect to remote endpoint(%s:%d) to setup "
295 "H2250 channel (%s, %s)\n", call->remoteIP,
296 call->remotePort, call->callType, call->callToken);
298 if((ret=ooSocketConnect(channelSocket, call->remoteIP,
299 call->remotePort))==ASN_OK)
301 call->pH225Channel->sock = channelSocket;
303 OOTRACEINFO3("H2250 transmiter channel creation - successful "
304 "(%s, %s)\n", call->callType, call->callToken);
306 /* If multihomed, get ip from socket */
307 if(!strcmp(call->localIP, "0.0.0.0"))
309 OOTRACEDBGA3("Determining IP address for outgoing call in "
310 "multihomed mode. (%s, %s)\n", call->callType,
312 ret = ooSocketGetIpAndPort(channelSocket, call->localIP, 20,
313 &call->pH225Channel->port);
316 OOTRACEERR3("ERROR:Failed to retrieve local ip and port from "
317 "socket for multihomed mode.(%s, %s)\n",
318 call->callType, call->callToken);
319 if(call->callState < OO_CALL_CLEAR)
320 { /* transport failure */
321 call->callState = OO_CALL_CLEAR;
322 call->callEndReason = OO_REASON_TRANSPORTFAILURE;
326 OOTRACEDBGA4("Using local ip %s for outgoing call(multihomedMode)."
327 " (%s, %s)\n", call->localIP, call->callType,
334 OOTRACEERR5("ERROR:Failed to connect to remote destination for "
335 "transmit H2250 channel(%s, %s, %d, %s)\n",call->callType,
336 call->callToken, channelSocket, call->localIP);
337 close(channelSocket);
339 if(call->callState < OO_CALL_CLEAR)
340 { /* No one is listening at remote end */
341 call->callState = OO_CALL_CLEAR;
342 call->callEndReason = OO_REASON_NOUSER;
344 if (i>=2) return OO_FAILED; else continue;
353 int ooCloseH225Connection (OOH323CallData *call)
355 if (0 != call->pH225Channel)
357 if(call->pH225Channel->sock != 0)
358 ooSocketClose (call->pH225Channel->sock);
359 if (call->pH225Channel->outQueue.count > 0)
361 dListFreeAll (call->pctxt, &(call->pH225Channel->outQueue));
363 memFreePtr (call->pctxt, call->pH225Channel);
364 call->pH225Channel = NULL;
369 int ooCreateH323Listener()
372 OOSOCKET channelSocket=0;
376 if((ret=ooSocketCreate (&channelSocket))!=ASN_OK)
378 OOTRACEERR1("Failed to create socket for H323 Listener\n");
381 ret= ooSocketStrToAddr (gH323ep.signallingIP, &ipaddrs);
382 if((ret=ooSocketBind (channelSocket, ipaddrs,
383 gH323ep.listenPort))==ASN_OK)
385 gH323ep.listener = (OOSOCKET*)memAlloc(&gH323ep.ctxt,sizeof(OOSOCKET));
386 *(gH323ep.listener) = channelSocket;
388 ooSocketListen(channelSocket,2048); /*listen on socket*/
389 OOTRACEINFO1("H323 listener creation - successful\n");
394 OOTRACEERR1("ERROR:Failed to create H323 listener\n");
401 int ooAcceptH225Connection()
403 OOH323CallData * call;
406 OOSOCKET h225Channel=0;
407 ret = ooSocketAccept (*(gH323ep.listener), &h225Channel,
411 OOTRACEERR1("Error:Accepting h225 connection\n");
414 ooGenerateCallToken(callToken, sizeof(callToken));
416 call = ooCreateCall("incoming", callToken);
419 OOTRACEERR1("ERROR:Failed to create an incoming call\n");
423 ast_mutex_lock(&call->Lock);
424 call->pH225Channel = (OOH323Channel*)
425 memAllocZ (call->pctxt, sizeof(OOH323Channel));
427 call->pH225Channel->sock = h225Channel;
429 /* If multihomed, get ip from socket */
430 if(!strcmp(call->localIP, "0.0.0.0"))
432 OOTRACEDBGA3("Determining IP address for incoming call in multihomed "
433 "mode (%s, %s)\n", call->callType, call->callToken);
435 ret = ooSocketGetIpAndPort(h225Channel, call->localIP, 20,
436 &call->pH225Channel->port);
439 OOTRACEERR3("Error:Failed to retrieve local ip and port from "
440 "socket for multihomed mode.(%s, %s)\n",
441 call->callType, call->callToken);
442 if(call->callState < OO_CALL_CLEAR)
443 { /* transport failure */
444 call->callState = OO_CALL_CLEAR;
445 call->callEndReason = OO_REASON_TRANSPORTFAILURE;
447 ast_mutex_unlock(&call->Lock);
450 OOTRACEDBGA4("Using Local IP address %s for incoming call in multihomed "
451 "mode. (%s, %s)\n", call->localIP, call->callType,
455 ast_mutex_unlock(&call->Lock);
459 int ooAcceptH245Connection(OOH323CallData *call)
462 OOSOCKET h245Channel=0;
463 ret = ooSocketAccept (*(call->h245listener), &h245Channel,
467 OOTRACEERR1("Error:Accepting h245 connection\n");
471 if (0 == call->pH245Channel) {
473 (OOH323Channel*) memAllocZ (call->pctxt, sizeof(OOH323Channel));
475 call->pH245Channel->sock = h245Channel;
476 call->h245SessionState = OO_H245SESSION_ACTIVE;
479 OOTRACEINFO3("H.245 connection established (%s, %s)\n",
480 call->callType, call->callToken);
483 /* Start terminal capability exchange and master slave determination */
484 ret = ooSendTermCapMsg(call);
487 OOTRACEERR3("ERROR:Sending Terminal capability message (%s, %s)\n",
488 call->callType, call->callToken);
491 ret = ooSendMasterSlaveDetermination(call);
494 OOTRACEERR3("ERROR:Sending Master-slave determination message "
495 "(%s, %s)\n", call->callType, call->callToken);
502 int ooSetCmdFDSETs(struct pollfd *pfds, int *nfds)
506 pfds[*nfds].fd = gH323ep.cmdSock;
507 pfds[*nfds].events = POLLIN;
515 int ooProcessCmdFDSETsAndTimers
516 (struct pollfd *pfds, int nfds, struct timeval *pToMin)
518 if(gH323ep.cmdSock) {
519 if(ooPDRead(pfds, nfds, gH323ep.cmdSock)) {
520 if(ooReadAndProcessStackCommand() != OO_OK) {
521 /* ooReadAndProcessStackCommand prints an error message */
532 int ooSetFDSETs(struct pollfd *pfds, int *nfds)
534 if(gH323ep.gkClient && gH323ep.gkClient->rasSocket != 0)
536 pfds[*nfds].fd = gH323ep.gkClient->rasSocket;
537 pfds[*nfds].events = POLLIN;
542 pfds[*nfds].fd = *gH323ep.listener;
543 pfds[*nfds].events = POLLIN;
551 int ooSetCallFDSETs(OOH323CallData* call, struct pollfd* pfds, int *nfds)
556 if(call->cmdSock && call->callState < OO_CALL_CLEAR) {
557 pfds[*nfds].fd = call->cmdSock;
558 pfds[*nfds].events = POLLIN;
562 if (0 != call->pH225Channel && 0 != call->pH225Channel->sock) {
563 pfds[*nfds].fd = call->pH225Channel->sock;
564 pfds[*nfds].events = POLLIN;
566 if (call->pH225Channel->outQueue.count > 0 ||
567 (OO_TESTFLAG (call->flags, OO_M_TUNNELING) &&
568 0 != call->pH245Channel &&
569 call->pH245Channel->outQueue.count>0))
570 pfds[*nfds].events |= POLLOUT;
575 if (0 != call->pH245Channel && call->pH245Channel->sock != 0) {
576 pfds[*nfds].fd = call->pH245Channel->sock;
577 pfds[*nfds].events = POLLIN;
578 if (call->pH245Channel->outQueue.count>0)
579 pfds[*nfds].events |= POLLOUT;
582 else if(call->h245listener) {
583 OOTRACEINFO3("H.245 Listerner socket being monitored "
584 "(%s, %s)\n", call->callType, call->callToken);
585 pfds[*nfds].fd = *(call->h245listener);
586 pfds[*nfds].events = POLLIN;
596 int ooProcessFDSETsAndTimers
597 (struct pollfd* pfds, int nfds, struct timeval *pToMin)
599 struct timeval toNext;
601 /* Process gatekeeper client timers */
604 ooTimerFireExpired(&gH323ep.gkClient->ctxt,
605 &gH323ep.gkClient->timerList);
606 if(ooTimerNextTimeout(&gH323ep.gkClient->timerList, &toNext))
608 if(ooCompareTimeouts(pToMin, &toNext)>0)
610 pToMin->tv_sec = toNext.tv_sec;
611 pToMin->tv_usec = toNext.tv_usec;
614 if(gH323ep.gkClient->state == GkClientFailed ||
615 gH323ep.gkClient->state == GkClientGkErr)
617 if(ooGkClientHandleClientOrGkFailure(gH323ep.gkClient)!=OO_OK)
619 //ooStopMonitorCalls(); //Function calling ooProcessFDSETsAndTimers is responsible for this.
625 /* Manage ready descriptors after select */
627 if(0 != gH323ep.gkClient && 0 != gH323ep.gkClient->rasSocket)
629 if(ooPDRead(pfds, nfds, gH323ep.gkClient->rasSocket) )
631 ooGkClientReceive(gH323ep.gkClient);
632 if(gH323ep.gkClient->state == GkClientFailed ||
633 gH323ep.gkClient->state == GkClientGkErr) {
634 ooGkClientHandleClientOrGkFailure(gH323ep.gkClient);
641 if(ooPDRead(pfds, nfds, *(gH323ep.listener)))
643 OOTRACEDBGA1("New connection at H225 receiver\n");
644 ooAcceptH225Connection();
652 int ooProcessCallFDSETsAndTimers
653 (OOH323CallData *call, struct pollfd* pfds, int nfds, struct timeval *pToMin)
655 struct timeval toNext;
661 if(ooPDRead(pfds, nfds, call->cmdSock)) {
662 ast_mutex_lock(&call->Lock);
663 if(ooReadAndProcessCallStackCommand(call) != OO_OK) {
664 /* ooReadAndProcessStackCommand prints an error message */
665 ast_mutex_unlock(&call->Lock);
668 ast_mutex_unlock(&call->Lock);
672 ooTimerFireExpired(call->pctxt, &call->timerList);
673 if (0 != call->pH225Channel && 0 != call->pH225Channel->sock)
675 if(ooPDRead(pfds, nfds, call->pH225Channel->sock))
677 if(ooH2250Receive(call) != OO_OK)
679 OOTRACEERR3("ERROR:Failed ooH2250Receive - Clearing call "
680 "(%s, %s)\n", call->callType, call->callToken);
681 if(call->callState < OO_CALL_CLEAR)
683 call->callEndReason = OO_REASON_INVALIDMESSAGE;
684 call->callState = OO_CALL_CLEAR;
690 if (0 != call->pH245Channel && 0 != call->pH245Channel->sock)
691 if(ooPDRead(pfds, nfds, call->pH245Channel->sock))
694 if (0 != call->pH245Channel && 0 != call->pH245Channel->sock)
696 if(call->pH245Channel->outQueue.count>0)
698 if(ooPDWrite(pfds, nfds, call->pH245Channel->sock))
699 ooSendMsg(call, OOH245MSG);
702 else if(call->h245listener)
704 if(ooPDRead(pfds, nfds, *(call->h245listener)))
706 OOTRACEDBGC3("Incoming H.245 connection (%s, %s)\n",
707 call->callType, call->callToken);
708 ooAcceptH245Connection(call);
712 if (0 != call->pH225Channel && 0 != call->pH225Channel->sock)
714 if(ooPDWrite(pfds, nfds, call->pH225Channel->sock))
716 if(call->pH225Channel->outQueue.count>0)
718 OOTRACEDBGC3("Sending H225 message (%s, %s)\n",
719 call->callType, call->callToken);
720 ooSendMsg(call, OOQ931MSG);
722 if(call->pH245Channel &&
723 call->pH245Channel->outQueue.count>0 &&
724 OO_TESTFLAG (call->flags, OO_M_TUNNELING))
726 OOTRACEDBGC3("H245 message needs to be tunneled. "
727 "(%s, %s)\n", call->callType,
729 ooSendMsg(call, OOH245MSG);
734 if(ooTimerNextTimeout(&call->timerList, &toNext))
736 if(ooCompareTimeouts(pToMin, &toNext) > 0)
738 pToMin->tv_sec = toNext.tv_sec;
739 pToMin->tv_usec = toNext.tv_usec;
743 if(call->callState >= OO_CALL_CLEAR && call->callState < OO_CALL_CLEARED) {
744 ast_mutex_lock(&call->Lock);
746 ast_mutex_unlock(&call->Lock);
747 } else if(call->callState == OO_CALL_CLEARED) {
748 ast_mutex_lock(&call->Lock);
750 ast_mutex_unlock(&call->Lock);
752 if(call->callState >= OO_CALL_CLEARED)
753 ooStopMonitorCallChannels(call);
760 int ooMonitorCmdChannels()
763 struct timeval toMin;
764 struct pollfd pfds[1];
774 ooSetCmdFDSETs(pfds, &nfds);
777 OOTRACEINFO1("Ending Monitor thread\n");
788 toMin.tv_usec = 10000;
789 ooSocketPoll(pfds, nfds, toMin.tv_usec / 1000);
793 ret = ooSocketPoll(pfds, nfds, toMin.tv_sec * 1000 + toMin.tv_usec / 1000);
798 OOTRACEERR1("Error in poll ...exiting\n");
803 toMin.tv_sec = 2; /* 2 sec */
804 toMin.tv_usec = 100000; /* 100ms*/
806 ast_mutex_lock(&monitorLock);
807 if(ooProcessCmdFDSETsAndTimers(pfds, nfds, &toMin) != OO_OK)
809 /* ooStopMonitorCalls(); */
810 ast_mutex_unlock(&monitorLock);
813 ast_mutex_unlock(&monitorLock);
819 int ooMonitorChannels()
822 struct timeval toMin, toNext;
823 struct pollfd pfds[2];
829 ooH323EpPrintConfig();
831 if(gH323ep.gkClient) {
832 ooGkClientPrintConfig(gH323ep.gkClient);
833 if(OO_OK != ooGkClientStart(gH323ep.gkClient))
835 OOTRACEERR1("Error:Failed to start Gatekeeper client\n");
843 ooSetFDSETs(pfds, &nfds);
846 OOTRACEINFO1("Ending Monitor thread\n");
857 toMin.tv_usec = 10000;
858 ooSocketPoll(pfds, nfds, toMin.tv_usec / 1000);
862 ret = ooSocketPoll(pfds, nfds, toMin.tv_sec * 1000 + toMin.tv_usec / 1000);
867 OOTRACEERR1("Error in poll ...exiting\n");
871 toMin.tv_sec = 2; /* 2 sec */
872 toMin.tv_usec = 100000; /* 100ms*/
873 /*This is for test application. Not part of actual stack */
875 ast_mutex_lock(&monitorLock);
876 ooTimerFireExpired(&gH323ep.ctxt, &g_TimerList);
877 if(ooTimerNextTimeout(&g_TimerList, &toNext))
879 if(ooCompareTimeouts(&toMin, &toNext)>0)
881 toMin.tv_sec = toNext.tv_sec;
882 toMin.tv_usec = toNext.tv_usec;
886 if(ooProcessFDSETsAndTimers(pfds, nfds, &toMin) != OO_OK)
888 ast_mutex_unlock(&monitorLock);
889 ooStopMonitorCalls();
893 ast_mutex_unlock(&monitorLock);
897 int ooMonitorCallChannels(OOH323CallData *call)
899 int ret=0, nfds=0, zeroloops = 0;
900 #define MAX_ZERO_LOOP 1020
901 struct timeval toMin;
902 struct pollfd pfds[5];
906 call->Monitor = TRUE;
914 OOTRACEINFO1("Ending Call Monitor thread\n");
919 ooSetCallFDSETs(call, pfds, &nfds);
927 if (zeroloops++ > MAX_ZERO_LOOP) {
929 ooStopMonitorCallChannels(call);
933 toMin.tv_usec = 10000;
934 ooSocketPoll(pfds, nfds, toMin.tv_usec / 1000);
938 ret = ooSocketPoll(pfds, nfds, toMin.tv_sec * 1000 + toMin.tv_usec / 1000);
943 OOTRACEERR2("Error in poll %d ...exiting\n", errno);
944 call->callEndReason = OO_REASON_INVALIDMESSAGE;
945 call->callState = OO_CALL_CLEARED;
947 ooStopMonitorCallChannels(call);
952 toMin.tv_sec = 2; /* 2 sec */
953 toMin.tv_usec = 100000; /* 100ms*/
954 /*This is for test application. Not part of actual stack */
956 if(ooProcessCallFDSETsAndTimers(call, pfds, nfds, &toMin) != OO_OK)
958 ooStopMonitorCallChannels(call);
965 ooCloseCallCmdConnection(call);
967 ast_mutex_lock(&call->Lock);
968 ast_mutex_unlock(&call->Lock);
969 ast_mutex_destroy(&call->Lock);
970 ast_cond_destroy(&call->gkWait);
978 int ooH2250Receive(OOH323CallData *call)
980 int recvLen=0, total=0, ret=0;
981 ASN1OCTET message[MAXMSGLEN], message1[MAXMSGLEN];
984 OOCTXT *pctxt = call->pctxt;
986 struct timeval timeout;
989 pmsg = (Q931Message*)memAlloc(pctxt, sizeof(Q931Message));
992 OOTRACEERR3("ERROR:Failed to allocate memory for incoming H.2250 message"
993 " (%s, %s)\n", call->callType, call->callToken);
994 /* memReset(&gH323ep.msgctxt); */
995 memReset(call->pctxt);
998 memset(pmsg, 0, sizeof(Q931Message));
999 /* First read just TPKT header which is four bytes */
1000 recvLen = ooSocketRecv (call->pH225Channel->sock, message, 4);
1004 OOTRACEWARN3("Warn:RemoteEndpoint closed connection (%s, %s)\n",
1005 call->callType, call->callToken);
1007 OOTRACEERR3("Error:Transport failure while reading Q931 "
1008 "message (%s, %s)\n", call->callType, call->callToken);
1010 ooCloseH225Connection(call);
1011 if(call->callState < OO_CALL_CLEARED)
1013 if(call->callState < OO_CALL_CLEAR)
1014 call->callEndReason = OO_REASON_TRANSPORTFAILURE;
1015 call->callState = OO_CALL_CLEARED;
1018 ooFreeQ931Message(pctxt, pmsg);
1021 OOTRACEDBGC3("Receiving H.2250 message (%s, %s)\n",
1022 call->callType, call->callToken);
1023 /* Since we are working with TCP, need to determine the
1024 message boundary. Has to be done at channel level, as channels
1025 know the message formats and can determine boundaries
1029 OOTRACEERR4("Error: Reading TPKT header for H225 message "
1030 "recvLen= %d (%s, %s)\n", recvLen, call->callType,
1032 ooFreeQ931Message(pctxt, pmsg);
1033 if(call->callState < OO_CALL_CLEAR)
1035 call->callEndReason = OO_REASON_INVALIDMESSAGE;
1036 call->callState = OO_CALL_CLEAR;
1044 len = len | message[3];
1045 /* Remaining message length is length - tpkt length */
1048 if(len > MAXMSGLEN - 4)
1050 OOTRACEERR4("Error: Invalid TPKT header for H225 message "
1051 "Len = %d (%s, %s)\n", len, call->callType,
1053 ooCloseH225Connection(call);
1054 ooFreeQ931Message(pctxt, pmsg);
1055 if(call->callState < OO_CALL_CLEAR)
1057 call->callEndReason = OO_REASON_INVALIDMESSAGE;
1058 call->callState = OO_CALL_CLEAR;
1063 /* Now read actual Q931 message body. We should make sure that we
1064 receive complete message as indicated by len. If we don't then there
1065 is something wrong. The loop below receives message, then checks whether
1066 complete message is received. If not received, then uses select to peek
1067 for remaining bytes of the message. If message is not received in 3
1068 seconds, then we have a problem. Report an error and exit.
1073 recvLen = ooSocketRecv (call->pH225Channel->sock, message1, len-total);
1074 memcpy(message+total, message1, recvLen);
1075 total = total + recvLen;
1077 if(total == len) break; /* Complete message is received */
1079 pfds.fd = call->pH225Channel->sock;
1080 pfds.events = POLLIN;
1082 timeout.tv_usec = 0;
1083 ret = ooSocketPoll(&pfds, 1, timeout.tv_sec * 1000);
1086 OOTRACEERR3("Error in select while receiving H.2250 message - "
1087 "clearing call (%s, %s)\n", call->callType,
1089 ooFreeQ931Message(pctxt, pmsg);
1090 if(call->callState < OO_CALL_CLEAR)
1092 call->callEndReason = OO_REASON_TRANSPORTFAILURE;
1093 call->callState = OO_CALL_CLEAR;
1097 /* If remaining part of the message is not received in 3 seconds
1099 if(!ooPDRead(&pfds, 1, call->pH225Channel->sock))
1101 OOTRACEERR3("Error: Incomplete H.2250 message received - clearing "
1102 "call (%s, %s)\n", call->callType, call->callToken);
1103 ooFreeQ931Message(pctxt, pmsg);
1104 if(call->callState < OO_CALL_CLEAR)
1106 call->callEndReason = OO_REASON_INVALIDMESSAGE;
1107 call->callState = OO_CALL_CLEAR;
1113 OOTRACEDBGC3("Received Q.931 message: (%s, %s)\n",
1114 call->callType, call->callToken);
1116 initializePrintHandler(&printHandler, "Received H.2250 Message");
1117 setEventHandler (pctxt, &printHandler);
1118 ret = ooQ931Decode (call, pmsg, len, message, 1);
1120 OOTRACEERR3("Error:Failed to decode received H.2250 message. (%s, %s)\n",
1121 call->callType, call->callToken);
1123 OOTRACEDBGC3("Decoded Q931 message (%s, %s)\n", call->callType,
1126 removeEventHandler(pctxt);
1128 ret = ooHandleH2250Message(call, pmsg);
1135 int ooH245Receive(OOH323CallData *call)
1137 int recvLen, ret, len, total=0;
1138 ASN1OCTET message[MAXMSGLEN], message1[MAXMSGLEN];
1139 ASN1BOOL aligned = TRUE;
1141 /* OOCTXT *pctxt = &gH323ep.msgctxt; */
1142 OOCTXT *pctxt = call->pctxt;
1143 struct timeval timeout;
1145 pmsg = (H245Message*)memAlloc(pctxt, sizeof(H245Message));
1147 /* First read just TPKT header which is four bytes */
1148 recvLen = ooSocketRecv (call->pH245Channel->sock, message, 4);
1149 /* Since we are working with TCP, need to determine the
1150 message boundary. Has to be done at channel level, as channels
1151 know the message formats and can determine boundaries
1153 if(recvLen<=0 && call->h245SessionState != OO_H245SESSION_PAUSED)
1156 OOTRACEINFO3("Closing H.245 channels as remote end point closed H.245"
1157 " connection (%s, %s)\n", call->callType, call->callToken);
1159 OOTRACEERR3("Error: Transport failure while trying to receive H245"
1160 " message (%s, %s)\n", call->callType, call->callToken);
1162 ooCloseH245Connection(call);
1163 ooFreeH245Message(call, pmsg);
1164 if(call->callState < OO_CALL_CLEAR)
1166 call->callEndReason = OO_REASON_TRANSPORTFAILURE;
1167 call->callState = OO_CALL_CLEAR;
1171 if(call->h245SessionState == OO_H245SESSION_PAUSED)
1173 ooLogicalChannel *temp;
1175 OOTRACEINFO3("Call Paused, closing logical channels"
1176 " (%s, %s)\n", call->callType, call->callToken);
1178 temp = call->logicalChans;
1181 if(temp->state == OO_LOGICALCHAN_ESTABLISHED)
1183 /* Sending closelogicalchannel only for outgoing channels*/
1184 if(!strcmp(temp->dir, "transmit"))
1186 ooSendCloseLogicalChannel(call, temp);
1191 call->masterSlaveState = OO_MasterSlave_Idle;
1192 call->callState = OO_CALL_PAUSED;
1193 call->localTermCapState = OO_LocalTermCapExchange_Idle;
1194 call->remoteTermCapState = OO_RemoteTermCapExchange_Idle;
1195 call->h245SessionState = OO_H245SESSION_IDLE;
1196 call->logicalChans = NULL;
1198 OOTRACEDBGC1("Receiving H245 message\n");
1201 OOTRACEERR3("Error: Reading TPKT header for H245 message (%s, %s)\n",
1202 call->callType, call->callToken);
1203 ooFreeH245Message(call, pmsg);
1204 if(call->callState < OO_CALL_CLEAR)
1206 call->callEndReason = OO_REASON_INVALIDMESSAGE;
1207 call->callState = OO_CALL_CLEAR;
1214 len = (len | message[3]);
1215 /* Remaining message length is length - tpkt length */
1217 /* Now read actual H245 message body. We should make sure that we
1218 receive complete message as indicated by len. If we don't then there
1219 is something wrong. The loop below receives message, then checks whether
1220 complete message is received. If not received, then uses select to peek
1221 for remaining bytes of the message. If message is not received in 3
1222 seconds, then we have a problem. Report an error and exit.
1225 if(len > MAXMSGLEN - 4)
1227 OOTRACEERR4("Error: Invalid TPKT header length %d for H245 message (%s, %s)\n",
1228 len, call->callType, call->callToken);
1229 ooFreeH245Message(call, pmsg);
1230 if(call->callState < OO_CALL_CLEAR)
1232 call->callEndReason = OO_REASON_INVALIDMESSAGE;
1233 call->callState = OO_CALL_CLEAR;
1241 recvLen = ooSocketRecv (call->pH245Channel->sock, message1, len-total);
1242 memcpy(message+total, message1, recvLen);
1243 total = total + recvLen;
1244 if(total == len) break; /* Complete message is received */
1246 pfds.fd = call->pH245Channel->sock;
1247 pfds.events = POLLIN;
1249 timeout.tv_usec = 0;
1250 ret = ooSocketPoll(&pfds, 1, timeout.tv_sec * 1000);
1253 OOTRACEERR3("Error in select...H245 Receive-Clearing call (%s, %s)\n",
1254 call->callType, call->callToken);
1255 ooFreeH245Message(call, pmsg);
1256 if(call->callState < OO_CALL_CLEAR)
1258 call->callEndReason = OO_REASON_TRANSPORTFAILURE;
1259 call->callState = OO_CALL_CLEAR;
1263 /* If remaining part of the message is not received in 3 seconds
1265 if(!ooPDRead(&pfds, 1, call->pH245Channel->sock))
1267 OOTRACEERR3("Error: Incomplete h245 message received (%s, %s)\n",
1268 call->callType, call->callToken);
1269 ooFreeH245Message(call, pmsg);
1270 if(call->callState < OO_CALL_CLEAR)
1272 call->callEndReason = OO_REASON_TRANSPORTFAILURE;
1273 call->callState = OO_CALL_CLEAR;
1279 OOTRACEDBGC3("Complete H245 message received (%s, %s)\n",
1280 call->callType, call->callToken);
1281 setPERBuffer(pctxt, message, recvLen, aligned);
1282 initializePrintHandler(&printHandler, "Received H.245 Message");
1284 /* Set event handler */
1285 setEventHandler (pctxt, &printHandler);
1287 ret = asn1PD_H245MultimediaSystemControlMessage(pctxt, &(pmsg->h245Msg));
1290 OOTRACEERR3("Error decoding H245 message (%s, %s)\n",
1291 call->callType, call->callToken);
1292 ooFreeH245Message(call, pmsg);
1296 removeEventHandler(pctxt);
1297 ooHandleH245Message(call, pmsg);
1301 /* Generic Send Message functionality. Based on type of message to be sent,
1302 it calls the corresponding function to retrieve the message buffer and
1303 then transmits on the associated channel
1304 Interpreting msgptr:
1305 Q931 messages except facility
1306 1st octet - msgType, next 4 octets - tpkt header,
1307 followed by encoded msg
1308 Q931 message facility
1309 1st octect - OOFacility, 2nd octet - tunneled msg
1310 type(in case no tunneled msg - OOFacility),
1311 3rd and 4th octet - associated logical channel
1312 of the tunneled msg(0 when no channel is
1313 associated. ex. in case of MSD, TCS), next
1314 4 octets - tpkt header, followed by encoded
1317 H.245 messages no tunneling
1318 1st octet - msg type, next two octets - logical
1319 channel number(0, when no channel is associated),
1320 next two octets - total length of the message
1321 (including tpkt header)
1323 H.245 messages - tunneling.
1324 1st octet - msg type, next two octets - logical
1325 channel number(0, when no channel is associated),
1326 next two octets - total length of the message.
1327 Note, no tpkt header is present in this case.
1330 int ooSendMsg(OOH323CallData *call, int type)
1333 int len=0, ret=0, msgType=0, tunneledMsgType=0, logicalChannelNo = 0;
1334 DListNode * p_msgNode=NULL;
1335 ASN1OCTET *msgptr, *msgToSend=NULL;
1339 if(call->callState == OO_CALL_CLEARED)
1341 OOTRACEDBGA3("Warning:Call marked for cleanup. Can not send message."
1342 "(%s, %s)\n", call->callType, call->callToken);
1346 if(type == OOQ931MSG)
1348 if(call->pH225Channel->outQueue.count == 0)
1350 OOTRACEWARN3("WARN:No H.2250 message to send. (%s, %s)\n",
1351 call->callType, call->callToken);
1355 OOTRACEDBGA3("Sending Q931 message (%s, %s)\n", call->callType,
1357 p_msgNode = call->pH225Channel->outQueue.head;
1358 msgptr = (ASN1OCTET*) p_msgNode->data;
1359 msgType = msgptr[0];
1361 if(msgType == OOFacility)
1363 tunneledMsgType = msgptr[1];
1364 logicalChannelNo = msgptr[2];
1365 logicalChannelNo = logicalChannelNo << 8;
1366 logicalChannelNo = (logicalChannelNo | msgptr[3]);
1369 len = (len | msgptr[7]);
1370 msgToSend = msgptr+4;
1375 len = (len | msgptr[4]);
1376 msgToSend = msgptr+1;
1379 /* Remove the message from rtdlist pH225Channel->outQueue */
1380 dListRemove(&(call->pH225Channel->outQueue), p_msgNode);
1382 memFreePtr(call->pctxt, p_msgNode);
1384 /*TODO: This is not required ideally. We will see for some time and if
1385 we don't face any problems we will delete this code */
1387 /* Check whether connection with remote is alright */
1388 if(!ooChannelsIsConnectionOK(call, call->pH225Channel->sock))
1390 OOTRACEERR3("Error:Transport failure for signalling channel. "
1391 "Abandoning message send and marking call for cleanup.(%s"
1392 "'%s)\n", call->callType, call->callToken);
1393 if(call->callState < OO_CALL_CLEAR)
1394 call->callEndReason = OO_REASON_TRANSPORTFAILURE;
1395 call->callState = OO_CALL_CLEARED;
1399 /* Send message out via TCP */
1400 ret = ooSocketSend(call->pH225Channel->sock, msgToSend, len);
1403 memFreePtr (call->pctxt, msgptr);
1404 OOTRACEDBGC3("H2250/Q931 Message sent successfully (%s, %s)\n",
1405 call->callType, call->callToken);
1406 ooOnSendMsg(call, msgType, tunneledMsgType, logicalChannelNo);
1410 OOTRACEERR3("H2250Q931 Message send failed (%s, %s)\n",
1411 call->callType, call->callToken);
1412 memFreePtr (call->pctxt, msgptr);
1413 if(call->callState < OO_CALL_CLEAR)
1415 call->callEndReason = OO_REASON_TRANSPORTFAILURE;
1416 call->callState = OO_CALL_CLEAR;
1420 }/* end of type==OOQ931MSG */
1421 if(type == OOH245MSG)
1423 if(call->pH245Channel->outQueue.count == 0)
1425 OOTRACEWARN3("WARN:No H.245 message to send. (%s, %s)\n",
1426 call->callType, call->callToken);
1429 OOTRACEDBGA3("Sending H245 message (%s, %s)\n", call->callType,
1431 p_msgNode = call->pH245Channel->outQueue.head;
1432 msgptr = (ASN1OCTET*) p_msgNode->data;
1433 msgType = msgptr[0];
1435 logicalChannelNo = msgptr[1];
1436 logicalChannelNo = logicalChannelNo << 8;
1437 logicalChannelNo = (logicalChannelNo | msgptr[2]);
1441 len = (len | msgptr[4]);
1442 /* Remove the message from queue */
1443 dListRemove(&(call->pH245Channel->outQueue), p_msgNode);
1445 memFreePtr(call->pctxt, p_msgNode);
1447 /* Send message out */
1448 if (0 == call->pH245Channel && !OO_TESTFLAG(call->flags, OO_M_TUNNELING))
1450 OOTRACEWARN3("Neither H.245 channel nor tunneling active "
1451 "(%s, %s)\n", call->callType, call->callToken);
1452 memFreePtr (call->pctxt, msgptr);
1453 /*ooCloseH245Session(call);*/
1454 if(call->callState < OO_CALL_CLEAR)
1456 call->callEndReason = OO_REASON_TRANSPORTFAILURE;
1457 call->callState = OO_CALL_CLEAR;
1462 if (0 != call->pH245Channel && 0 != call->pH245Channel->sock)
1464 OOTRACEDBGC4("Sending %s H245 message over H.245 channel. "
1465 "(%s, %s)\n", ooGetMsgTypeText(msgType),
1466 call->callType, call->callToken);
1468 ret = ooSocketSend(call->pH245Channel->sock, msgptr+5, len);
1471 memFreePtr (call->pctxt, msgptr);
1472 OOTRACEDBGA3("H245 Message sent successfully (%s, %s)\n",
1473 call->callType, call->callToken);
1474 ooOnSendMsg(call, msgType, tunneledMsgType, logicalChannelNo);
1478 memFreePtr (call->pctxt, msgptr);
1479 OOTRACEERR3("ERROR:H245 Message send failed (%s, %s)\n",
1480 call->callType, call->callToken);
1481 if(call->callState < OO_CALL_CLEAR)
1483 call->callEndReason = OO_REASON_TRANSPORTFAILURE;
1484 call->callState = OO_CALL_CLEAR;
1489 else if(OO_TESTFLAG (call->flags, OO_M_TUNNELING)) {
1490 OOTRACEDBGC4("Sending %s H245 message as a tunneled message."
1491 "(%s, %s)\n", ooGetMsgTypeText(msgType),
1492 call->callType, call->callToken);
1494 ret = ooSendAsTunneledMessage
1495 (call, msgptr+5,len,msgType, logicalChannelNo);
1499 memFreePtr (call->pctxt, msgptr);
1500 OOTRACEERR3("ERROR:Failed to tunnel H.245 message (%s, %s)\n",
1501 call->callType, call->callToken);
1502 if(call->callState < OO_CALL_CLEAR)
1504 call->callEndReason = OO_REASON_INVALIDMESSAGE;
1505 call->callState = OO_CALL_CLEAR;
1509 memFreePtr (call->pctxt, msgptr);
1513 /* Need to add support for other messages such as T38 etc */
1514 OOTRACEWARN3("ERROR:Unknown message type - message not Sent (%s, %s)\n",
1515 call->callType, call->callToken);
1519 int ooCloseH245Connection(OOH323CallData *call)
1521 OOTRACEINFO3("Closing H.245 connection (%s, %s)\n", call->callType,
1524 if (0 != call->pH245Channel)
1526 if(0 != call->pH245Channel->sock)
1527 ooSocketClose (call->pH245Channel->sock);
1528 if (call->pH245Channel->outQueue.count > 0)
1529 dListFreeAll(call->pctxt, &(call->pH245Channel->outQueue));
1530 memFreePtr (call->pctxt, call->pH245Channel);
1531 call->pH245Channel = NULL;
1532 OOTRACEDBGC3("Closed H245 connection. (%s, %s)\n", call->callType,
1535 call->h245SessionState = OO_H245SESSION_CLOSED;
1540 int ooCloseH245Listener(OOH323CallData *call)
1542 OOTRACEINFO3("Closing H.245 Listener (%s, %s)\n", call->callType,
1544 if(call->h245listener)
1546 ooSocketClose(*(call->h245listener));
1547 memFreePtr(call->pctxt, call->h245listener);
1548 call->h245listener = NULL;
1554 (OOH323CallData *call, int msgType, int tunneledMsgType, int associatedChan)
1556 ooTimerCallback *cbData=NULL;
1560 OOTRACEINFO3("Sent Message - Setup (%s, %s)\n", call->callType,
1562 /* Start call establishment timer */
1563 cbData = (ooTimerCallback*) memAlloc(call->pctxt,
1564 sizeof(ooTimerCallback));
1567 OOTRACEERR3("Error:Unable to allocate memory for timer callback."
1568 "(%s, %s)\n", call->callType, call->callToken);
1571 cbData->call = call;
1572 cbData->timerType = OO_CALLESTB_TIMER;
1573 if(!ooTimerCreate(call->pctxt, &call->timerList, &ooCallEstbTimerExpired,
1574 gH323ep.callEstablishmentTimeout, cbData, FALSE))
1576 OOTRACEERR3("Error:Unable to create call establishment timer. "
1577 "(%s, %s)\n", call->callType, call->callToken);
1578 memFreePtr(call->pctxt, cbData);
1582 /* if(gH323ep.h323Callbacks.onOutgoingCall)
1583 gH323ep.h323Callbacks.onOutgoingCall(call); */
1585 case OOCallProceeding:
1586 OOTRACEINFO3("Sent Message - CallProceeding (%s, %s)\n", call->callType,
1590 OOTRACEINFO3("Sent Message - Alerting (%s, %s) \n", call->callType,
1592 /* if(gH323ep.h323Callbacks.onAlerting && call->callState < OO_CALL_CLEAR)
1593 gH323ep.h323Callbacks.onAlerting(call); */
1596 OOTRACEINFO3("Sent Message - Connect (%s, %s)\n", call->callType,
1598 if(gH323ep.h323Callbacks.onCallEstablished)
1599 gH323ep.h323Callbacks.onCallEstablished(call);
1601 case OOReleaseComplete:
1602 OOTRACEINFO3("Sent Message - ReleaseComplete (%s, %s)\n", call->callType,
1605 if(call->callState == OO_CALL_CLEAR_RELEASERECVD)
1606 call->callState = OO_CALL_CLEARED;
1608 call->callState = OO_CALL_CLEAR_RELEASESENT;
1609 if(gH323ep.gkClient && !OO_TESTFLAG(call->flags, OO_M_DISABLEGK) &&
1610 gH323ep.gkClient->state == GkClientRegistered){
1611 OOTRACEDBGA3("Sending DRQ after sending ReleaseComplete."
1612 "(%s, %s)\n", call->callType, call->callToken);
1614 call->endTime = (H235TimeStamp) time(NULL);
1615 ooGkClientSendDisengageRequest(gH323ep.gkClient, call);
1619 if(call->callState == OO_CALL_CLEAR_RELEASESENT &&
1620 call->h245SessionState == OO_H245SESSION_IDLE)
1622 cbData = (ooTimerCallback*) memAlloc(call->pctxt,
1623 sizeof(ooTimerCallback));
1626 OOTRACEERR3("Error:Unable to allocate memory for timer callback "
1627 "data.(%s, %s)\n", call->callType, call->callToken);
1630 cbData->call = call;
1631 cbData->timerType = OO_SESSION_TIMER;
1632 cbData->channelNumber = 0;
1633 if(!ooTimerCreate(call->pctxt, &call->timerList,
1634 &ooSessionTimerExpired, gH323ep.sessionTimeout, cbData, FALSE))
1636 OOTRACEERR3("Error:Unable to create EndSession timer- "
1637 "ReleaseComplete.(%s, %s)\n", call->callType,
1639 memFreePtr(call->pctxt, cbData);
1644 if(call->h245SessionState == OO_H245SESSION_CLOSED)
1646 call->callState = OO_CALL_CLEARED;
1651 if(tunneledMsgType == OOFacility)
1653 OOTRACEINFO3("Sent Message - Facility. (%s, %s)\n",
1654 call->callType, call->callToken);
1657 OOTRACEINFO4("Sent Message - Facility(%s) (%s, %s)\n",
1658 ooGetMsgTypeText(tunneledMsgType),
1659 call->callType, call->callToken);
1661 ooOnSendMsg(call, tunneledMsgType, 0, associatedChan);
1665 case OOMasterSlaveDetermination:
1666 if(OO_TESTFLAG (call->flags, OO_M_TUNNELING))
1667 OOTRACEINFO3("Tunneled Message - MasterSlaveDetermination (%s, %s)\n",
1668 call->callType, call->callToken);
1670 OOTRACEINFO3("Sent Message - MasterSlaveDetermination (%s, %s)\n",
1671 call->callType, call->callToken);
1672 /* Start MSD timer */
1673 cbData = (ooTimerCallback*) memAlloc(call->pctxt,
1674 sizeof(ooTimerCallback));
1677 OOTRACEERR3("Error:Unable to allocate memory for timer callback data."
1678 "(%s, %s)\n", call->callType, call->callToken);
1681 cbData->call = call;
1682 cbData->timerType = OO_MSD_TIMER;
1683 if(!ooTimerCreate(call->pctxt, &call->timerList, &ooMSDTimerExpired,
1684 gH323ep.msdTimeout, cbData, FALSE))
1686 OOTRACEERR3("Error:Unable to create MSD timer. "
1687 "(%s, %s)\n", call->callType, call->callToken);
1688 memFreePtr(call->pctxt, cbData);
1693 case OOMasterSlaveAck:
1694 if(OO_TESTFLAG (call->flags, OO_M_TUNNELING))
1695 OOTRACEINFO3("Tunneled Message - MasterSlaveDeterminationAck (%s, %s)"
1696 "\n", call->callType, call->callToken);
1698 OOTRACEINFO3("Sent Message - MasterSlaveDeterminationAck (%s, %s)\n",
1699 call->callType, call->callToken);
1701 case OOMasterSlaveReject:
1702 if(OO_TESTFLAG (call->flags, OO_M_TUNNELING))
1703 OOTRACEINFO3("Tunneled Message - MasterSlaveDeterminationReject "
1704 "(%s, %s)\n", call->callType, call->callToken);
1706 OOTRACEINFO3("Sent Message - MasterSlaveDeterminationReject(%s, %s)\n",
1707 call->callType, call->callToken);
1709 case OOMasterSlaveRelease:
1710 if(OO_TESTFLAG (call->flags, OO_M_TUNNELING))
1711 OOTRACEINFO3("Tunneled Message - MasterSlaveDeterminationRelease "
1712 "(%s, %s)\n", call->callType, call->callToken);
1714 OOTRACEINFO3("Sent Message - MasterSlaveDeterminationRelease "
1715 "(%s, %s)\n", call->callType, call->callToken);
1717 case OOTerminalCapabilitySet:
1718 if(OO_TESTFLAG (call->flags, OO_M_TUNNELING)) {
1719 /* If session isn't marked active yet, do it. possible in case of
1721 if(call->h245SessionState == OO_H245SESSION_IDLE ||
1722 call->h245SessionState == OO_H245SESSION_PAUSED) {
1723 call->h245SessionState = OO_H245SESSION_ACTIVE;
1725 OOTRACEINFO3("Tunneled Message - TerminalCapabilitySet (%s, %s)\n",
1726 call->callType, call->callToken);
1729 OOTRACEINFO3("Sent Message - TerminalCapabilitySet (%s, %s)\n",
1730 call->callType, call->callToken);
1732 /* Start TCS timer */
1733 cbData = (ooTimerCallback*) memAlloc(call->pctxt,
1734 sizeof(ooTimerCallback));
1737 OOTRACEERR3("Error:Unable to allocate memory for timer callback data."
1738 "(%s, %s)\n", call->callType, call->callToken);
1741 cbData->call = call;
1742 cbData->timerType = OO_TCS_TIMER;
1743 if(!ooTimerCreate(call->pctxt, &call->timerList, &ooTCSTimerExpired,
1744 gH323ep.tcsTimeout, cbData, FALSE))
1746 OOTRACEERR3("Error:Unable to create TCS timer. "
1747 "(%s, %s)\n", call->callType, call->callToken);
1748 memFreePtr(call->pctxt, cbData);
1754 case OOTerminalCapabilitySetAck:
1755 if(OO_TESTFLAG (call->flags, OO_M_TUNNELING))
1756 OOTRACEINFO3("Tunneled Message - TerminalCapabilitySetAck (%s, %s)\n",
1757 call->callType, call->callToken);
1759 OOTRACEINFO3("Sent Message - TerminalCapabilitySetAck (%s, %s)\n",
1760 call->callType, call->callToken);
1762 case OOTerminalCapabilitySetReject:
1763 if(OO_TESTFLAG (call->flags, OO_M_TUNNELING))
1764 OOTRACEINFO3("Tunneled Message - TerminalCapabilitySetReject "
1765 "(%s, %s)\n", call->callType, call->callToken);
1767 OOTRACEINFO3("Sent Message - TerminalCapabilitySetReject (%s, %s)\n",
1768 call->callType, call->callToken);
1770 case OOOpenLogicalChannel:
1771 if(OO_TESTFLAG (call->flags, OO_M_TUNNELING))
1772 OOTRACEINFO4("Tunneled Message - OpenLogicalChannel(%d). (%s, %s)\n",
1773 associatedChan, call->callType, call->callToken);
1775 OOTRACEINFO4("Sent Message - OpenLogicalChannel(%d). (%s, %s)\n",
1776 associatedChan, call->callType, call->callToken);
1777 /* Start LogicalChannel timer */
1778 cbData = (ooTimerCallback*) memAlloc(call->pctxt,
1779 sizeof(ooTimerCallback));
1782 OOTRACEERR3("Error:Unable to allocate memory for timer callback data."
1783 "(%s, %s)\n", call->callType, call->callToken);
1786 cbData->call = call;
1787 cbData->timerType = OO_OLC_TIMER;
1788 cbData->channelNumber = associatedChan;
1789 if(!ooTimerCreate(call->pctxt, &call->timerList,
1790 &ooOpenLogicalChannelTimerExpired, gH323ep.logicalChannelTimeout,
1793 OOTRACEERR3("Error:Unable to create OpenLogicalChannel timer. "
1794 "(%s, %s)\n", call->callType, call->callToken);
1795 memFreePtr(call->pctxt, cbData);
1800 case OOOpenLogicalChannelAck:
1801 if(OO_TESTFLAG (call->flags, OO_M_TUNNELING))
1802 OOTRACEINFO4("Tunneled Message - OpenLogicalChannelAck(%d) (%s,%s)\n",
1803 associatedChan, call->callType, call->callToken);
1805 OOTRACEINFO4("Sent Message - OpenLogicalChannelAck(%d) (%s, %s)\n",
1806 associatedChan, call->callType, call->callToken);
1808 case OOOpenLogicalChannelReject:
1809 if(OO_TESTFLAG (call->flags, OO_M_TUNNELING))
1810 OOTRACEINFO4("Tunneled Message - OpenLogicalChannelReject(%d)"
1811 "(%s, %s)\n", associatedChan, call->callType,
1814 OOTRACEINFO4("Sent Message - OpenLogicalChannelReject(%d) (%s, %s)\n",
1815 associatedChan, call->callType, call->callToken);
1817 case OOEndSessionCommand:
1818 if(OO_TESTFLAG (call->flags, OO_M_TUNNELING))
1819 OOTRACEINFO3("Tunneled Message - EndSessionCommand(%s, %s)\n",
1820 call->callType, call->callToken);
1822 OOTRACEINFO3("Sent Message - EndSessionCommand (%s, %s)\n",
1823 call->callType, call->callToken);
1824 if((call->h245SessionState == OO_H245SESSION_ACTIVE))
1826 /* Start EndSession timer */
1827 call->h245SessionState = OO_H245SESSION_ENDSENT;
1828 cbData = (ooTimerCallback*) memAlloc(call->pctxt,
1829 sizeof(ooTimerCallback));
1832 OOTRACEERR3("Error:Unable to allocate memory for timer callback "
1833 "data.(%s, %s)\n", call->callType, call->callToken);
1836 cbData->call = call;
1837 cbData->timerType = OO_SESSION_TIMER;
1838 cbData->channelNumber = 0;
1839 if(!ooTimerCreate(call->pctxt, &call->timerList,
1840 &ooSessionTimerExpired, gH323ep.sessionTimeout, cbData, FALSE))
1842 OOTRACEERR3("Error:Unable to create EndSession timer. "
1843 "(%s, %s)\n", call->callType, call->callToken);
1844 memFreePtr(call->pctxt, cbData);
1849 ooCloseH245Connection(call);
1852 case OOCloseLogicalChannel:
1853 if(OO_TESTFLAG (call->flags, OO_M_TUNNELING))
1854 OOTRACEINFO3("Tunneled Message - CloseLogicalChannel (%s, %s)\n",
1855 call->callType, call->callToken);
1857 OOTRACEINFO3("Sent Message - CloseLogicalChannel (%s, %s)\n",
1858 call->callType, call->callToken);
1859 /* Start LogicalChannel timer */
1860 cbData = (ooTimerCallback*) memAlloc(call->pctxt,
1861 sizeof(ooTimerCallback));
1864 OOTRACEERR3("Error:Unable to allocate memory for timer callback data."
1865 "(%s, %s)\n", call->callType, call->callToken);
1868 cbData->call = call;
1869 cbData->timerType = OO_CLC_TIMER;
1870 cbData->channelNumber = associatedChan;
1871 if(!ooTimerCreate(call->pctxt, &call->timerList,
1872 &ooCloseLogicalChannelTimerExpired, gH323ep.logicalChannelTimeout,
1875 OOTRACEERR3("Error:Unable to create CloseLogicalChannel timer. "
1876 "(%s, %s)\n", call->callType, call->callToken);
1877 memFreePtr(call->pctxt, cbData);
1882 case OOCloseLogicalChannelAck:
1883 if(OO_TESTFLAG (call->flags, OO_M_TUNNELING))
1884 OOTRACEINFO3("Tunneled Message - CloseLogicalChannelAck (%s, %s)\n",
1885 call->callType, call->callToken);
1887 OOTRACEINFO3("Sent Message - CloseLogicalChannelAck (%s, %s)\n",
1888 call->callType, call->callToken);
1890 case OORequestChannelClose:
1891 if(OO_TESTFLAG (call->flags, OO_M_TUNNELING))
1892 OOTRACEINFO3("Tunneled Message - RequestChannelClose (%s, %s)\n",
1893 call->callType, call->callToken);
1895 OOTRACEINFO3("Sent Message - RequestChannelClose (%s, %s)\n",
1896 call->callType, call->callToken);
1897 /* Start RequestChannelClose timer */
1898 cbData = (ooTimerCallback*) memAlloc(call->pctxt,
1899 sizeof(ooTimerCallback));
1902 OOTRACEERR3("Error:Unable to allocate memory for timer callback data."
1903 "(%s, %s)\n", call->callType, call->callToken);
1906 cbData->call = call;
1907 cbData->timerType = OO_RCC_TIMER;
1908 cbData->channelNumber = associatedChan;
1909 if(!ooTimerCreate(call->pctxt, &call->timerList,
1910 &ooRequestChannelCloseTimerExpired, gH323ep.logicalChannelTimeout,
1913 OOTRACEERR3("Error:Unable to create RequestChannelClose timer. "
1914 "(%s, %s)\n", call->callType, call->callToken);
1915 memFreePtr(call->pctxt, cbData);
1919 case OORequestChannelCloseAck:
1920 if(OO_TESTFLAG (call->flags, OO_M_TUNNELING))
1921 OOTRACEINFO3("Tunneled Message - RequestChannelCloseAck (%s, %s)\n",
1922 call->callType, call->callToken);
1924 OOTRACEINFO3("Sent Message - RequestChannelCloseAck (%s, %s)\n",
1925 call->callType, call->callToken);
1934 void ooStopMonitorCallChannels(OOH323CallData * call) {
1936 call->Monitor = FALSE;
1937 /* if (call->cmdSock)
1938 ooCloseCallCmdConnection(call); */
1941 int ooStopMonitorCalls()
1943 OOH323CallData * call;
1946 OOTRACEINFO1("Doing ooStopMonitorCalls\n");
1949 ooCloseCmdConnection();
1952 if(gH323ep.callList)
1954 OOTRACEWARN1("Warn:Abruptly ending calls as stack going down\n");
1955 call = gH323ep.callList;
1958 OOTRACEWARN3("Clearing call (%s, %s)\n", call->callType,
1960 call->callEndReason = OO_REASON_LOCAL_CLEARED;
1963 call = gH323ep.callList;
1965 gH323ep.callList = NULL;
1967 OOTRACEINFO1("Stopping listener for incoming calls\n");
1968 if(gH323ep.listener)
1970 ooSocketClose(*(gH323ep.listener));
1971 memFreePtr(&gH323ep.ctxt, gH323ep.listener);
1972 gH323ep.listener = NULL;
1976 OOTRACEINFO1("Done ooStopMonitorCalls\n");
1981 OOBOOL ooChannelsIsConnectionOK(OOH323CallData *call, OOSOCKET sock)
1985 int ret = 0, nfds=0;
1991 FD_SET(sock, &readfds);
1992 if(nfds < (int)sock)
1997 ret = ooSocketSelect(nfds, &readfds, NULL, NULL, &to);
2001 OOTRACEERR3("Error in select ...broken pipe check(%s, %s)\n",
2002 call->callType, call->callToken );
2006 if(FD_ISSET(sock, &readfds))
2009 if(ooSocketRecvPeek(sock, (ASN1OCTET*) buf, 2) == 0)
2011 OOTRACEWARN3("Broken pipe detected. (%s, %s)", call->callType,
2013 if(call->callState < OO_CALL_CLEAR)
2014 call->callEndReason = OO_REASON_TRANSPORTFAILURE;
2015 call->callState = OO_CALL_CLEARED;