dect
/
asterisk
Archived
13
0
Fork 0
This repository has been archived on 2022-02-17. You can view files and clone it, but cannot push or open issues or pull requests.
asterisk/addons/ooh323c/src/ooh323.c

1844 lines
68 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 "ootypes.h"
#include "ooq931.h"
#include "ootrace.h"
#include "oochannels.h"
#include "ooh245.h"
#include "ooCalls.h"
#include "printHandler.h"
#include "ooh323.h"
#include "ooh323ep.h"
#include "ooGkClient.h"
#include "ooTimer.h"
/** Global endpoint structure */
extern OOH323EndPoint gH323ep;
int ooOnReceivedReleaseComplete(OOH323CallData *call, Q931Message *q931Msg)
{
int ret = OO_OK;
H225ReleaseComplete_UUIE * releaseComplete = NULL;
ASN1UINT i;
DListNode *pNode = NULL;
OOTimer *pTimer = NULL;
unsigned reasonCode=T_H225ReleaseCompleteReason_undefinedReason;
enum Q931CauseValues cause= Q931ErrorInCauseIE;
if(q931Msg->causeIE)
{
cause = q931Msg->causeIE->data[1];
/* Get rid of the extension bit.For more info, check ooQ931SetCauseIE */
cause = cause & 0x7f;
OOTRACEDBGA4("Cause of Release Complete is %x. (%s, %s)\n", cause,
call->callType, call->callToken);
}
/* Remove session timer, if active*/
for(i = 0; i<call->timerList.count; i++)
{
pNode = dListFindByIndex(&call->timerList, i);
pTimer = (OOTimer*)pNode->data;
if(((ooTimerCallback*)pTimer->cbData)->timerType &
OO_SESSION_TIMER)
{
memFreePtr(call->pctxt, pTimer->cbData);
ooTimerDelete(call->pctxt, &call->timerList, pTimer);
OOTRACEDBGC3("Deleted Session Timer. (%s, %s)\n",
call->callType, call->callToken);
break;
}
}
if(!q931Msg->userInfo)
{
OOTRACEERR3("ERROR:No User-User IE in received ReleaseComplete message "
"(%s, %s)\n", call->callType, call->callToken);
return OO_FAILED;
}
releaseComplete = q931Msg->userInfo->h323_uu_pdu.h323_message_body.u.releaseComplete;
if(!releaseComplete)
{
OOTRACEWARN3("WARN: ReleaseComplete UUIE not found in received "
"ReleaseComplete message - %s "
"%s\n", call->callType, call->callToken);
}
else{
if(releaseComplete->m.reasonPresent)
{
OOTRACEINFO4("Release complete reason code %d. (%s, %s)\n",
releaseComplete->reason.t, call->callType, call->callToken);
reasonCode = releaseComplete->reason.t;
}
}
if(call->callEndReason == OO_REASON_UNKNOWN)
call->callEndReason = ooGetCallClearReasonFromCauseAndReasonCode(cause,
reasonCode);
#if 0
if (q931Msg->userInfo->h323_uu_pdu.m.h245TunnelingPresent &&
q931Msg->userInfo->h323_uu_pdu.h245Tunneling &&
OO_TESTFLAG (call->flags, OO_M_TUNNELING) )
{
OOTRACEDBGB3("Handling tunneled messages in ReleaseComplete. (%s, %s)\n",
call->callType, call->callToken);
ret = ooHandleTunneledH245Messages
(call, &q931Msg->userInfo->h323_uu_pdu);
OOTRACEDBGB3("Finished handling tunneled messages in ReleaseComplete."
" (%s, %s)\n", call->callType, call->callToken);
}
#endif
if(call->h245SessionState != OO_H245SESSION_IDLE &&
call->h245SessionState != OO_H245SESSION_CLOSED)
{
ooCloseH245Connection(call);
}
if(call->callState != OO_CALL_CLEAR_RELEASESENT)
{
if(gH323ep.gkClient && !OO_TESTFLAG(call->flags, OO_M_DISABLEGK))
{
if(gH323ep.gkClient->state == GkClientRegistered){
OOTRACEDBGA3("Sending DRQ after received ReleaseComplete."
"(%s, %s)\n", call->callType, call->callToken);
ooGkClientSendDisengageRequest(gH323ep.gkClient, call);
}
}
}
call->callState = OO_CALL_CLEARED;
return ret;
}
int ooOnReceivedSetup(OOH323CallData *call, Q931Message *q931Msg)
{
H225Setup_UUIE *setup=NULL;
int i=0, ret=0;
H245OpenLogicalChannel* olc;
ASN1OCTET msgbuf[MAXMSGLEN];
H225TransportAddress_ipAddress_ip *ip = NULL;
Q931InformationElement* pDisplayIE=NULL;
OOAliases *pAlias=NULL;
call->callReference = q931Msg->callReference;
if(!q931Msg->userInfo)
{
OOTRACEERR3("ERROR:No User-User IE in received SETUP message (%s, %s)\n",
call->callType, call->callToken);
return OO_FAILED;
}
setup = q931Msg->userInfo->h323_uu_pdu.h323_message_body.u.setup;
if(!setup)
{
OOTRACEERR3("Error: Setup UUIE not found in received setup message - %s "
"%s\n", call->callType, call->callToken);
return OO_FAILED;
}
memcpy(call->callIdentifier.guid.data, setup->callIdentifier.guid.data,
setup->callIdentifier.guid.numocts);
call->callIdentifier.guid.numocts = setup->callIdentifier.guid.numocts;
memcpy(call->confIdentifier.data, setup->conferenceID.data,
setup->conferenceID.numocts);
call->confIdentifier.numocts = setup->conferenceID.numocts;
/* check for display ie */
pDisplayIE = ooQ931GetIE(q931Msg, Q931DisplayIE);
if(pDisplayIE)
{
call->remoteDisplayName = (ASN1OCTET*) memAlloc(call->pctxt,
pDisplayIE->length*sizeof(ASN1OCTET)+1);
strcpy(call->remoteDisplayName, pDisplayIE->data);
}
/*Extract Remote Aliases, if present*/
if(setup->m.sourceAddressPresent)
{
if(setup->sourceAddress.count>0)
{
ooH323RetrieveAliases(call, &setup->sourceAddress,
&call->remoteAliases);
pAlias = call->remoteAliases;
while(pAlias)
{
if(pAlias->type == T_H225AliasAddress_dialedDigits)
{
if(!call->callingPartyNumber)
{
call->callingPartyNumber = (char*)memAlloc(call->pctxt,
strlen(pAlias->value)*+1);
if(call->callingPartyNumber)
{
strcpy(call->callingPartyNumber, pAlias->value);
}
}
break;
}
pAlias = pAlias->next;
}
}
}
/* Extract, aliases used for us, if present. Also,
Populate calledPartyNumber from dialedDigits, if not yet populated using
calledPartyNumber Q931 IE.
*/
if(setup->m.destinationAddressPresent)
{
if(setup->destinationAddress.count>0)
{
ooH323RetrieveAliases(call, &setup->destinationAddress,
&call->ourAliases);
pAlias = call->ourAliases;
while(pAlias)
{
if(pAlias->type == T_H225AliasAddress_dialedDigits)
{
if(!call->calledPartyNumber)
{
call->calledPartyNumber = (char*)memAlloc(call->pctxt,
strlen(pAlias->value)*+1);
if(call->calledPartyNumber)
{
strcpy(call->calledPartyNumber, pAlias->value);
}
}
break;
}
pAlias = pAlias->next;
}
}
}
/* Check for tunneling */
if(q931Msg->userInfo->h323_uu_pdu.m.h245TunnelingPresent)
{
/* Tunneling enabled only when tunneling is set to true and h245
address is absent. In the presence of H.245 address in received
SETUP message, tunneling is disabled, irrespective of tunneling
flag in the setup message*/
if(q931Msg->userInfo->h323_uu_pdu.h245Tunneling &&
!setup->m.h245AddressPresent)
{
if(OO_TESTFLAG(gH323ep.flags, OO_M_TUNNELING))
{
OO_SETFLAG (call->flags, OO_M_TUNNELING);
OOTRACEINFO3("Call has tunneling active (%s,%s)\n", call->callType,
call->callToken);
}
else
OOTRACEINFO3("ERROR:Remote endpoint wants to use h245Tunneling, "
"local endpoint has it disabled (%s,%s)\n",
call->callType, call->callToken);
}
else {
if(OO_TESTFLAG(gH323ep.flags, OO_M_TUNNELING))
{
OOTRACEINFO3("Tunneling disabled by remote endpoint. (%s, %s)\n",
call->callType, call->callToken);
}
OO_CLRFLAG (call->flags, OO_M_TUNNELING);
}
}
else {
if(OO_TESTFLAG(gH323ep.flags, OO_M_TUNNELING))
{
OOTRACEINFO3("Tunneling disabled by remote endpoint. (%s, %s)\n",
call->callType, call->callToken);
}
OO_CLRFLAG (call->flags, OO_M_TUNNELING);
}
/* Extract Remote IP address */
if(!setup->m.sourceCallSignalAddressPresent)
{
OOTRACEWARN3("WARNING:Missing source call signal address in received "
"setup (%s, %s)\n", call->callType, call->callToken);
}
else{
if(setup->sourceCallSignalAddress.t != T_H225TransportAddress_ipAddress)
{
OOTRACEERR3("ERROR: Source call signalling address type not ip "
"(%s, %s)\n", call->callType, call->callToken);
return OO_FAILED;
}
ip = &setup->sourceCallSignalAddress.u.ipAddress->ip;
sprintf(call->remoteIP, "%d.%d.%d.%d", ip->data[0], ip->data[1],
ip->data[2], ip->data[3]);
call->remotePort = setup->sourceCallSignalAddress.u.ipAddress->port;
}
/* check for fast start */
if(setup->m.fastStartPresent)
{
if(!OO_TESTFLAG(gH323ep.flags, OO_M_FASTSTART))
{
OOTRACEINFO3("Local endpoint does not support fastStart. Ignoring "
"fastStart. (%s, %s)\n", call->callType, call->callToken);
OO_CLRFLAG (call->flags, OO_M_FASTSTART);
}
else if(setup->fastStart.n == 0)
{
OOTRACEINFO3("Empty faststart element received. Ignoring fast start. "
"(%s, %s)\n", call->callType, call->callToken);
OO_CLRFLAG (call->flags, OO_M_FASTSTART);
}
else{
OO_SETFLAG (call->flags, OO_M_FASTSTART);
OOTRACEINFO3("FastStart enabled for call(%s, %s)\n", call->callType,
call->callToken);
}
}
if (OO_TESTFLAG (call->flags, OO_M_FASTSTART))
{
/* For printing the decoded message to log, initialize handler. */
initializePrintHandler(&printHandler, "FastStart Elements");
/* Set print handler */
setEventHandler (call->pctxt, &printHandler);
for(i=0; i<(int)setup->fastStart.n; i++)
{
olc = NULL;
/* memset(msgbuf, 0, sizeof(msgbuf));*/
olc = (H245OpenLogicalChannel*)memAlloc(call->pctxt,
sizeof(H245OpenLogicalChannel));
if(!olc)
{
OOTRACEERR3("ERROR:Memory - ooOnReceivedSetup - olc (%s, %s)\n",
call->callType, call->callToken);
/*Mark call for clearing */
if(call->callState < OO_CALL_CLEAR)
{
call->callEndReason = OO_REASON_LOCAL_CLEARED;
call->callState = OO_CALL_CLEAR;
}
return OO_FAILED;
}
memset(olc, 0, sizeof(H245OpenLogicalChannel));
memcpy(msgbuf, setup->fastStart.elem[i].data,
setup->fastStart.elem[i].numocts);
setPERBuffer(call->pctxt, msgbuf,
setup->fastStart.elem[i].numocts, 1);
ret = asn1PD_H245OpenLogicalChannel(call->pctxt, olc);
if(ret != ASN_OK)
{
OOTRACEERR3("ERROR:Failed to decode fast start olc element "
"(%s, %s)\n", call->callType, call->callToken);
/* Mark call for clearing */
if(call->callState < OO_CALL_CLEAR)
{
call->callEndReason = OO_REASON_INVALIDMESSAGE;
call->callState = OO_CALL_CLEAR;
}
return OO_FAILED;
}
/* For now, just add decoded fast start elemts to list. This list
will be processed at the time of sending CONNECT message. */
dListAppend(call->pctxt, &call->remoteFastStartOLCs, olc);
}
finishPrint();
removeEventHandler(call->pctxt);
}
return OO_OK;
}
int ooOnReceivedCallProceeding(OOH323CallData *call, Q931Message *q931Msg)
{
H225CallProceeding_UUIE *callProceeding=NULL;
H245OpenLogicalChannel* olc;
ASN1OCTET msgbuf[MAXMSGLEN];
ooLogicalChannel * pChannel = NULL;
H245H2250LogicalChannelParameters * h2250lcp = NULL;
int i=0, ret=0;
if(!q931Msg->userInfo)
{
OOTRACEERR3("ERROR:No User-User IE in received CallProceeding message."
" (%s, %s)\n", call->callType, call->callToken);
return OO_FAILED;
}
callProceeding =
q931Msg->userInfo->h323_uu_pdu.h323_message_body.u.callProceeding;
if(callProceeding == NULL)
{
OOTRACEERR3("Error: Received CallProceeding message does not have "
"CallProceeding UUIE (%s, %s)\n", call->callType,
call->callToken);
/* Mark call for clearing */
if(call->callState < OO_CALL_CLEAR)
{
call->callEndReason = OO_REASON_INVALIDMESSAGE;
call->callState = OO_CALL_CLEAR;
}
return OO_FAILED;
}
/* Handle fast-start */
if(OO_TESTFLAG (call->flags, OO_M_FASTSTART))
{
if(callProceeding->m.fastStartPresent)
{
/* For printing the decoded message to log, initialize handler. */
initializePrintHandler(&printHandler, "FastStart Elements");
/* Set print handler */
setEventHandler (call->pctxt, &printHandler);
for(i=0; i<(int)callProceeding->fastStart.n; i++)
{
olc = NULL;
olc = (H245OpenLogicalChannel*)memAlloc(call->pctxt,
sizeof(H245OpenLogicalChannel));
if(!olc)
{
OOTRACEERR3("ERROR:Memory - ooOnReceivedCallProceeding - olc"
"(%s, %s)\n", call->callType, call->callToken);
/*Mark call for clearing */
if(call->callState < OO_CALL_CLEAR)
{
call->callEndReason = OO_REASON_LOCAL_CLEARED;
call->callState = OO_CALL_CLEAR;
}
return OO_FAILED;
}
memset(olc, 0, sizeof(H245OpenLogicalChannel));
memcpy(msgbuf, callProceeding->fastStart.elem[i].data,
callProceeding->fastStart.elem[i].numocts);
setPERBuffer(call->pctxt, msgbuf,
callProceeding->fastStart.elem[i].numocts, 1);
ret = asn1PD_H245OpenLogicalChannel(call->pctxt, olc);
if(ret != ASN_OK)
{
OOTRACEERR3("ERROR:Failed to decode fast start olc element "
"(%s, %s)\n", call->callType, call->callToken);
/* Mark call for clearing */
if(call->callState < OO_CALL_CLEAR)
{
call->callEndReason = OO_REASON_INVALIDMESSAGE;
call->callState = OO_CALL_CLEAR;
}
return OO_FAILED;
}
dListAppend(call->pctxt, &call->remoteFastStartOLCs, olc);
pChannel = ooFindLogicalChannelByOLC(call, olc);
if(!pChannel)
{
OOTRACEERR4("ERROR: Logical Channel %d not found, fast start. "
"(%s, %s)\n",
olc->forwardLogicalChannelNumber, call->callType,
call->callToken);
return OO_FAILED;
}
if(pChannel->channelNo != olc->forwardLogicalChannelNumber)
{
OOTRACEINFO5("Remote endpoint changed forwardLogicalChannel"
"Number from %d to %d (%s, %s)\n",
pChannel->channelNo,
olc->forwardLogicalChannelNumber, call->callType,
call->callToken);
pChannel->channelNo = olc->forwardLogicalChannelNumber;
}
if(!strcmp(pChannel->dir, "transmit"))
{
if(olc->forwardLogicalChannelParameters.multiplexParameters.t !=
T_H245OpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters_h2250LogicalChannelParameters)
{
OOTRACEERR4("ERROR:Unknown multiplex parameter type for "
"channel %d (%s, %s)\n",
olc->forwardLogicalChannelNumber, call->callType,
call->callToken);
continue;
}
/* Extract the remote media endpoint address */
h2250lcp = olc->forwardLogicalChannelParameters.multiplexParameters.u.h2250LogicalChannelParameters;
if(!h2250lcp)
{
OOTRACEERR3("ERROR:Invalid OLC received in fast start. No "
"forward Logical Channel Parameters found. "
"(%s, %s)\n", call->callType, call->callToken);
return OO_FAILED;
}
if(!h2250lcp->m.mediaChannelPresent)
{
OOTRACEERR3("ERROR:Invalid OLC received in fast start. No "
"reverse media channel information found."
"(%s, %s)\n", call->callType, call->callToken);
return OO_FAILED;
}
ret = ooGetIpPortFromH245TransportAddress(call,
&h2250lcp->mediaChannel, pChannel->remoteIP,
&pChannel->remoteMediaPort);
if(ret != OO_OK)
{
OOTRACEERR3("ERROR:Unsupported media channel address type "
"(%s, %s)\n", call->callType, call->callToken);
return OO_FAILED;
}
if(!pChannel->chanCap->startTransmitChannel)
{
OOTRACEERR3("ERROR:No callback registered to start transmit "
"channel (%s, %s)\n",call->callType,
call->callToken);
return OO_FAILED;
}
pChannel->chanCap->startTransmitChannel(call, pChannel);
}
/* Mark the current channel as established and close all other
logical channels with same session id and in same direction.
*/
ooOnLogicalChannelEstablished(call, pChannel);
}
finishPrint();
removeEventHandler(call->pctxt);
OO_SETFLAG(call->flags, OO_M_FASTSTARTANSWERED);
}
}
/* Retrieve the H.245 control channel address from the connect msg */
if(q931Msg->userInfo->h323_uu_pdu.m.h245TunnelingPresent &&
q931Msg->userInfo->h323_uu_pdu.h245Tunneling &&
callProceeding->m.h245AddressPresent) {
OOTRACEINFO3("Tunneling and h245address provided."
"Using Tunneling for H.245 messages (%s, %s)\n",
call->callType, call->callToken);
}
else if(callProceeding->m.h245AddressPresent)
{
if (OO_TESTFLAG (call->flags, OO_M_TUNNELING))
{
OO_CLRFLAG (call->flags, OO_M_TUNNELING);
OOTRACEINFO3("Tunneling is disabled for call as H245 address is "
"provided in callProceeding message (%s, %s)\n",
call->callType, call->callToken);
}
ret = ooH323GetIpPortFromH225TransportAddress(call,
&callProceeding->h245Address, call->remoteIP,
&call->remoteH245Port);
if(ret != OO_OK)
{
OOTRACEERR3("Error: Unknown H245 address type in received "
"CallProceeding message (%s, %s)", call->callType,
call->callToken);
/* Mark call for clearing */
if(call->callState < OO_CALL_CLEAR)
{
call->callEndReason = OO_REASON_INVALIDMESSAGE;
call->callState = OO_CALL_CLEAR;
}
return OO_FAILED;
}
}
return OO_OK;
}
int ooOnReceivedAlerting(OOH323CallData *call, Q931Message *q931Msg)
{
H225Alerting_UUIE *alerting=NULL;
H245OpenLogicalChannel* olc;
ASN1OCTET msgbuf[MAXMSGLEN];
ooLogicalChannel * pChannel = NULL;
H245H2250LogicalChannelParameters * h2250lcp = NULL;
int i=0, ret=0;
if(!q931Msg->userInfo)
{
OOTRACEERR3("ERROR:No User-User IE in received Alerting message."
" (%s, %s)\n", call->callType, call->callToken);
return OO_FAILED;
}
alerting = q931Msg->userInfo->h323_uu_pdu.h323_message_body.u.alerting;
if(alerting == NULL)
{
OOTRACEERR3("Error: Received Alerting message does not have "
"alerting UUIE (%s, %s)\n", call->callType,
call->callToken);
/* Mark call for clearing */
if(call->callState < OO_CALL_CLEAR)
{
call->callEndReason = OO_REASON_INVALIDMESSAGE;
call->callState = OO_CALL_CLEAR;
}
return OO_FAILED;
}
/*Handle fast-start */
if(OO_TESTFLAG (call->flags, OO_M_FASTSTART) &&
!OO_TESTFLAG(call->flags, OO_M_FASTSTARTANSWERED))
{
if(alerting->m.fastStartPresent)
{
/* For printing the decoded message to log, initialize handler. */
initializePrintHandler(&printHandler, "FastStart Elements");
/* Set print handler */
setEventHandler (call->pctxt, &printHandler);
for(i=0; i<(int)alerting->fastStart.n; i++)
{
olc = NULL;
olc = (H245OpenLogicalChannel*)memAlloc(call->pctxt,
sizeof(H245OpenLogicalChannel));
if(!olc)
{
OOTRACEERR3("ERROR:Memory - ooOnReceivedAlerting - olc"
"(%s, %s)\n", call->callType, call->callToken);
/*Mark call for clearing */
if(call->callState < OO_CALL_CLEAR)
{
call->callEndReason = OO_REASON_LOCAL_CLEARED;
call->callState = OO_CALL_CLEAR;
}
return OO_FAILED;
}
memset(olc, 0, sizeof(H245OpenLogicalChannel));
memcpy(msgbuf, alerting->fastStart.elem[i].data,
alerting->fastStart.elem[i].numocts);
setPERBuffer(call->pctxt, msgbuf,
alerting->fastStart.elem[i].numocts, 1);
ret = asn1PD_H245OpenLogicalChannel(call->pctxt, olc);
if(ret != ASN_OK)
{
OOTRACEERR3("ERROR:Failed to decode fast start olc element "
"(%s, %s)\n", call->callType, call->callToken);
/* Mark call for clearing */
if(call->callState < OO_CALL_CLEAR)
{
call->callEndReason = OO_REASON_INVALIDMESSAGE;
call->callState = OO_CALL_CLEAR;
}
return OO_FAILED;
}
dListAppend(call->pctxt, &call->remoteFastStartOLCs, olc);
pChannel = ooFindLogicalChannelByOLC(call, olc);
if(!pChannel)
{
OOTRACEERR4("ERROR: Logical Channel %d not found, fast start. "
"(%s, %s)\n",
olc->forwardLogicalChannelNumber, call->callType,
call->callToken);
return OO_FAILED;
}
if(pChannel->channelNo != olc->forwardLogicalChannelNumber)
{
OOTRACEINFO5("Remote endpoint changed forwardLogicalChannel"
"Number from %d to %d (%s, %s)\n",
pChannel->channelNo,
olc->forwardLogicalChannelNumber, call->callType,
call->callToken);
pChannel->channelNo = olc->forwardLogicalChannelNumber;
}
if(!strcmp(pChannel->dir, "transmit"))
{
if(olc->forwardLogicalChannelParameters.multiplexParameters.t !=
T_H245OpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters_h2250LogicalChannelParameters)
{
OOTRACEERR4("ERROR:Unknown multiplex parameter type for "
"channel %d (%s, %s)\n",
olc->forwardLogicalChannelNumber, call->callType,
call->callToken);
continue;
}
/* Extract the remote media endpoint address */
h2250lcp = olc->forwardLogicalChannelParameters.multiplexParameters.u.h2250LogicalChannelParameters;
if(!h2250lcp)
{
OOTRACEERR3("ERROR:Invalid OLC received in fast start. No "
"forward Logical Channel Parameters found. "
"(%s, %s)\n", call->callType, call->callToken);
return OO_FAILED;
}
if(!h2250lcp->m.mediaChannelPresent)
{
OOTRACEERR3("ERROR:Invalid OLC received in fast start. No "
"reverse media channel information found."
"(%s, %s)\n", call->callType, call->callToken);
return OO_FAILED;
}
ret = ooGetIpPortFromH245TransportAddress(call,
&h2250lcp->mediaChannel, pChannel->remoteIP,
&pChannel->remoteMediaPort);
if(ret != OO_OK)
{
OOTRACEERR3("ERROR:Unsupported media channel address type "
"(%s, %s)\n", call->callType, call->callToken);
return OO_FAILED;
}
if(!pChannel->chanCap->startTransmitChannel)
{
OOTRACEERR3("ERROR:No callback registered to start transmit "
"channel (%s, %s)\n",call->callType,
call->callToken);
return OO_FAILED;
}
pChannel->chanCap->startTransmitChannel(call, pChannel);
}
/* Mark the current channel as established and close all other
logical channels with same session id and in same direction.
*/
ooOnLogicalChannelEstablished(call, pChannel);
}
finishPrint();
removeEventHandler(call->pctxt);
OO_SETFLAG(call->flags, OO_M_FASTSTARTANSWERED);
}
}
/* Retrieve the H.245 control channel address from the connect msg */
if(q931Msg->userInfo->h323_uu_pdu.m.h245TunnelingPresent &&
q931Msg->userInfo->h323_uu_pdu.h245Tunneling &&
alerting->m.h245AddressPresent) {
OOTRACEINFO3("Tunneling and h245address provided."
"Giving preference to Tunneling (%s, %s)\n",
call->callType, call->callToken);
}
else if(alerting->m.h245AddressPresent)
{
if (OO_TESTFLAG (call->flags, OO_M_TUNNELING))
{
OO_CLRFLAG (call->flags, OO_M_TUNNELING);
OOTRACEINFO3("Tunneling is disabled for call as H245 address is "
"provided in Alerting message (%s, %s)\n",
call->callType, call->callToken);
}
ret = ooH323GetIpPortFromH225TransportAddress(call,
&alerting->h245Address, call->remoteIP,
&call->remoteH245Port);
if(ret != OO_OK)
{
OOTRACEERR3("Error: Unknown H245 address type in received "
"Alerting message (%s, %s)", call->callType,
call->callToken);
/* Mark call for clearing */
if(call->callState < OO_CALL_CLEAR)
{
call->callEndReason = OO_REASON_INVALIDMESSAGE;
call->callState = OO_CALL_CLEAR;
}
return OO_FAILED;
}
}
return OO_OK;
}
int ooOnReceivedSignalConnect(OOH323CallData* call, Q931Message *q931Msg)
{
int ret, i;
H225Connect_UUIE *connect;
H245OpenLogicalChannel* olc;
ASN1OCTET msgbuf[MAXMSGLEN];
ooLogicalChannel * pChannel = NULL;
H245H2250LogicalChannelParameters * h2250lcp = NULL;
if(!q931Msg->userInfo)
{
OOTRACEERR3("Error: UUIE not found in received H.225 Connect message"
" (%s, %s)\n", call->callType, call->callToken);
/* Mark call for clearing */
if(call->callState < OO_CALL_CLEAR)
{
call->callEndReason = OO_REASON_INVALIDMESSAGE;
call->callState = OO_CALL_CLEAR;
}
return OO_FAILED;
}
/* Retrieve the connect message from the user-user IE & Q.931 header */
connect = q931Msg->userInfo->h323_uu_pdu.h323_message_body.u.connect;
if(connect == NULL)
{
OOTRACEERR3("Error: Received Connect message does not have Connect UUIE"
" (%s, %s)\n", call->callType, call->callToken);
/* Mark call for clearing */
if(call->callState < OO_CALL_CLEAR)
{
call->callEndReason = OO_REASON_INVALIDMESSAGE;
call->callState = OO_CALL_CLEAR;
}
return OO_FAILED;
}
/*Handle fast-start */
if(OO_TESTFLAG (call->flags, OO_M_FASTSTART) &&
!OO_TESTFLAG (call->flags, OO_M_FASTSTARTANSWERED))
{
if(!connect->m.fastStartPresent)
{
OOTRACEINFO3("Remote endpoint has rejected fastStart. (%s, %s)\n",
call->callType, call->callToken);
/* Clear all channels we might have created */
ooClearAllLogicalChannels(call);
OO_CLRFLAG (call->flags, OO_M_FASTSTART);
}
}
if (connect->m.fastStartPresent &&
!OO_TESTFLAG(call->flags, OO_M_FASTSTARTANSWERED))
{
/* For printing the decoded message to log, initialize handler. */
initializePrintHandler(&printHandler, "FastStart Elements");
/* Set print handler */
setEventHandler (call->pctxt, &printHandler);
for(i=0; i<(int)connect->fastStart.n; i++)
{
olc = NULL;
/* memset(msgbuf, 0, sizeof(msgbuf));*/
olc = (H245OpenLogicalChannel*)memAlloc(call->pctxt,
sizeof(H245OpenLogicalChannel));
if(!olc)
{
OOTRACEERR3("ERROR:Memory - ooOnReceivedSignalConnect - olc"
"(%s, %s)\n", call->callType, call->callToken);
/*Mark call for clearing */
if(call->callState < OO_CALL_CLEAR)
{
call->callEndReason = OO_REASON_LOCAL_CLEARED;
call->callState = OO_CALL_CLEAR;
}
finishPrint();
removeEventHandler(call->pctxt);
return OO_FAILED;
}
memset(olc, 0, sizeof(H245OpenLogicalChannel));
memcpy(msgbuf, connect->fastStart.elem[i].data,
connect->fastStart.elem[i].numocts);
setPERBuffer(call->pctxt, msgbuf,
connect->fastStart.elem[i].numocts, 1);
ret = asn1PD_H245OpenLogicalChannel(call->pctxt, olc);
if(ret != ASN_OK)
{
OOTRACEERR3("ERROR:Failed to decode fast start olc element "
"(%s, %s)\n", call->callType, call->callToken);
/* Mark call for clearing */
if(call->callState < OO_CALL_CLEAR)
{
call->callEndReason = OO_REASON_INVALIDMESSAGE;
call->callState = OO_CALL_CLEAR;
}
finishPrint();
removeEventHandler(call->pctxt);
return OO_FAILED;
}
dListAppend(call->pctxt, &call->remoteFastStartOLCs, olc);
pChannel = ooFindLogicalChannelByOLC(call, olc);
if(!pChannel)
{
OOTRACEERR4("ERROR: Logical Channel %d not found, fasts start "
"answered. (%s, %s)\n",
olc->forwardLogicalChannelNumber, call->callType,
call->callToken);
finishPrint();
removeEventHandler(call->pctxt);
return OO_FAILED;
}
if(pChannel->channelNo != olc->forwardLogicalChannelNumber)
{
OOTRACEINFO5("Remote endpoint changed forwardLogicalChannelNumber"
"from %d to %d (%s, %s)\n", pChannel->channelNo,
olc->forwardLogicalChannelNumber, call->callType,
call->callToken);
pChannel->channelNo = olc->forwardLogicalChannelNumber;
}
if(!strcmp(pChannel->dir, "transmit"))
{
if(olc->forwardLogicalChannelParameters.multiplexParameters.t !=
T_H245OpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters_h2250LogicalChannelParameters)
{
OOTRACEERR4("ERROR:Unknown multiplex parameter type for channel"
" %d (%s, %s)\n", olc->forwardLogicalChannelNumber,
call->callType, call->callToken);
continue;
}
/* Extract the remote media endpoint address */
h2250lcp = olc->forwardLogicalChannelParameters.multiplexParameters.u.h2250LogicalChannelParameters;
if(!h2250lcp)
{
OOTRACEERR3("ERROR:Invalid OLC received in fast start. No "
"forward Logical Channel Parameters found. (%s, %s)"
"\n", call->callType, call->callToken);
finishPrint();
removeEventHandler(call->pctxt);
return OO_FAILED;
}
if(!h2250lcp->m.mediaChannelPresent)
{
OOTRACEERR3("ERROR:Invalid OLC received in fast start. No "
"reverse media channel information found. (%s, %s)"
"\n", call->callType, call->callToken);
finishPrint();
removeEventHandler(call->pctxt);
return OO_FAILED;
}
ret = ooGetIpPortFromH245TransportAddress(call,
&h2250lcp->mediaChannel, pChannel->remoteIP,
&pChannel->remoteMediaPort);
if(ret != OO_OK)
{
OOTRACEERR3("ERROR:Unsupported media channel address type "
"(%s, %s)\n", call->callType, call->callToken);
finishPrint();
removeEventHandler(call->pctxt);
return OO_FAILED;
}
if(!pChannel->chanCap->startTransmitChannel)
{
OOTRACEERR3("ERROR:No callback registered to start transmit "
"channel (%s, %s)\n",call->callType, call->callToken);
finishPrint();
removeEventHandler(call->pctxt);
return OO_FAILED;
}
pChannel->chanCap->startTransmitChannel(call, pChannel);
}
/* Mark the current channel as established and close all other
logical channels with same session id and in same direction.
*/
ooOnLogicalChannelEstablished(call, pChannel);
}
finishPrint();
removeEventHandler(call->pctxt);
OO_SETFLAG(call->flags, OO_M_FASTSTARTANSWERED);
}
/* Retrieve the H.245 control channel address from the CONNECT msg */
if(q931Msg->userInfo->h323_uu_pdu.m.h245TunnelingPresent &&
q931Msg->userInfo->h323_uu_pdu.h245Tunneling &&
connect->m.h245AddressPresent) {
OOTRACEINFO3("Tunneling and h245address provided."
"Giving preference to Tunneling (%s, %s)\n",
call->callType, call->callToken);
}
else if(connect->m.h245AddressPresent)
{
if (OO_TESTFLAG (call->flags, OO_M_TUNNELING))
{
OO_CLRFLAG (call->flags, OO_M_TUNNELING);
OOTRACEINFO3("Tunneling is disabled for call as H245 address is "
"provided in connect message (%s, %s)\n",
call->callType, call->callToken);
}
ret = ooH323GetIpPortFromH225TransportAddress(call,
&connect->h245Address, call->remoteIP, &call->remoteH245Port);
if(ret != OO_OK)
{
OOTRACEERR3("Error: Unknown H245 address type in received Connect "
"message (%s, %s)", call->callType, call->callToken);
/* Mark call for clearing */
if(call->callState < OO_CALL_CLEAR)
{
call->callEndReason = OO_REASON_INVALIDMESSAGE;
call->callState = OO_CALL_CLEAR;
}
return OO_FAILED;
}
}
if(call->remoteH245Port != 0)
{
/* Create an H.245 connection.
*/
if(ooCreateH245Connection(call)== OO_FAILED)
{
OOTRACEERR3("Error: H.245 channel creation 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;
}
}
if(q931Msg->userInfo->h323_uu_pdu.m.h245TunnelingPresent)
{
if (!q931Msg->userInfo->h323_uu_pdu.h245Tunneling)
{
if (OO_TESTFLAG (call->flags, OO_M_TUNNELING))
{
OO_CLRFLAG (call->flags, OO_M_TUNNELING);
OOTRACEINFO3("Tunneling is disabled by remote endpoint.(%s, %s)\n",
call->callType, call->callToken);
}
}
}
if (OO_TESTFLAG(call->flags, OO_M_TUNNELING))
{
OOTRACEDBGB3("Handling tunneled messages in CONNECT. (%s, %s)\n",
call->callType, call->callToken);
ret = ooHandleTunneledH245Messages
(call, &q931Msg->userInfo->h323_uu_pdu);
OOTRACEDBGB3("Finished tunneled messages in Connect. (%s, %s)\n",
call->callType, call->callToken);
/*
Send TCS as call established and no capability exchange has yet
started. This will be true only when separate h245 connection is not
established and tunneling is being used.
*/
if(call->localTermCapState == OO_LocalTermCapExchange_Idle)
{
/*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;
}
}
if(call->masterSlaveState == OO_MasterSlave_Idle)
{
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 ooHandleH2250Message(OOH323CallData *call, Q931Message *q931Msg)
{
int ret=OO_OK;
ASN1UINT i;
DListNode *pNode = NULL;
OOTimer *pTimer=NULL;
int type = q931Msg->messageType;
switch(type)
{
case Q931SetupMsg: /* SETUP message is received */
OOTRACEINFO3("Received SETUP message (%s, %s)\n", call->callType,
call->callToken);
ooOnReceivedSetup(call, q931Msg);
/* H225 message callback */
if(gH323ep.h225Callbacks.onReceivedSetup)
gH323ep.h225Callbacks.onReceivedSetup(call, q931Msg);
/* Free up the mem used by the received message, as it's processing
is done.
*/
ooFreeQ931Message(q931Msg);
ooSendCallProceeding(call);/* Send call proceeding message*/
/* DISABLEGK is used to selectively disable gatekeeper use. For
incoming calls DISABLEGK can be set in onReceivedSetup callback by
application. Very useful in pbx applications where gk is used only
when call is to or from outside pbx domian
*/
if(gH323ep.gkClient && !OO_TESTFLAG(call->flags, OO_M_DISABLEGK))
{
if(gH323ep.gkClient->state == GkClientRegistered)
{
ret = ooGkClientSendAdmissionRequest(gH323ep.gkClient, call,
FALSE);
call->callState = OO_CALL_WAITING_ADMISSION;
}
else{
/* TODO: Should send Release complete with reject reason */
OOTRACEERR1("Error:Ignoring incoming call as not yet"
"registered with Gk\n");
}
}
else {
ret = ooH323CallAdmitted (call);
}
break;
case Q931CallProceedingMsg: /* CALL PROCEEDING message is received */
OOTRACEINFO3("H.225 Call Proceeding message received (%s, %s)\n",
call->callType, call->callToken);
ooOnReceivedCallProceeding(call, q931Msg);
ooFreeQ931Message(q931Msg);
break;
case Q931AlertingMsg:/* ALERTING message received */
OOTRACEINFO3("H.225 Alerting message received (%s, %s)\n",
call->callType, call->callToken);
ooOnReceivedAlerting(call, q931Msg);
if(gH323ep.h323Callbacks.onAlerting && call->callState<OO_CALL_CLEAR)
gH323ep.h323Callbacks.onAlerting(call);
ooFreeQ931Message(q931Msg);
break;
case Q931ConnectMsg:/* CONNECT message received */
OOTRACEINFO3("H.225 Connect message received (%s, %s)\n",
call->callType, call->callToken);
/* Disable call establishment timer */
for(i = 0; i<call->timerList.count; i++)
{
pNode = dListFindByIndex(&call->timerList, i);
pTimer = (OOTimer*)pNode->data;
if(((ooTimerCallback*)pTimer->cbData)->timerType &
OO_CALLESTB_TIMER)
{
memFreePtr(call->pctxt, pTimer->cbData);
ooTimerDelete(call->pctxt, &call->timerList, pTimer);
OOTRACEDBGC3("Deleted CallESTB timer. (%s, %s)\n",
call->callType, call->callToken);
break;
}
}
ret = ooOnReceivedSignalConnect(call, q931Msg);
if(ret != OO_OK)
OOTRACEERR3("Error:Invalid Connect message received. (%s, %s)\n",
call->callType, call->callToken);
else{
/* H225 message callback */
if(gH323ep.h225Callbacks.onReceivedConnect)
gH323ep.h225Callbacks.onReceivedConnect(call, q931Msg);
if(gH323ep.h323Callbacks.onCallEstablished)
gH323ep.h323Callbacks.onCallEstablished(call);
}
ooFreeQ931Message(q931Msg);
break;
case Q931InformationMsg:
OOTRACEINFO3("H.225 Information msg received (%s, %s)\n",
call->callType, call->callToken);
ooFreeQ931Message(q931Msg);
break;
case Q931ReleaseCompleteMsg:/* RELEASE COMPLETE message received */
OOTRACEINFO3("H.225 Release Complete message received (%s, %s)\n",
call->callType, call->callToken);
ooOnReceivedReleaseComplete(call, q931Msg);
ooFreeQ931Message(q931Msg);
break;
case Q931FacilityMsg:
OOTRACEINFO3("H.225 Facility message Received (%s, %s)\n",
call->callType, call->callToken);
ooOnReceivedFacility(call, q931Msg);
ooFreeQ931Message(q931Msg);
break;
case Q931ProgressMsg:
OOTRACEINFO3("H.225 Progress message received (%s, %s)\n",
call->callType, call->callToken);
ooFreeQ931Message(q931Msg);
break;
case Q931StatusMsg:
OOTRACEINFO3("H.225 Status message received (%s, %s)\n",
call->callType, call->callToken);
ooFreeQ931Message(q931Msg);
break;
case Q931StatusEnquiryMsg:
OOTRACEINFO3("H.225 Status Inquiry message Received (%s, %s)\n",
call->callType, call->callToken);
ooFreeQ931Message(q931Msg);
break;
case Q931SetupAckMsg:
OOTRACEINFO3("H.225 Setup Ack message received (%s, %s)\n",
call->callType, call->callToken);
ooFreeQ931Message(q931Msg);
break;
case Q931NotifyMsg:
OOTRACEINFO3("H.225 Notify message Received (%s, %s)\n",
call->callType, call->callToken);
ooFreeQ931Message(q931Msg);
break;
default:
OOTRACEWARN3("Invalid H.225 message type received (%s, %s)\n",
call->callType, call->callToken);
ooFreeQ931Message(q931Msg);
}
return ret;
}
int ooOnReceivedFacility(OOH323CallData *call, Q931Message * pQ931Msg)
{
H225H323_UU_PDU * pH323UUPdu = NULL;
H225Facility_UUIE * facility = NULL;
int ret;
H225TransportAddress_ipAddress_ip *ip = NULL;
OOTRACEDBGC3("Received Facility Message.(%s, %s)\n", call->callType,
call->callToken);
/* Get Reference to H323_UU_PDU */
if(!pQ931Msg->userInfo)
{
OOTRACEERR3("Error: UserInfo not found in received H.225 Facility "
"message (%s, %s)\n", call->callType, call->callToken);
return OO_FAILED;
}
pH323UUPdu = &pQ931Msg->userInfo->h323_uu_pdu;
if(!pH323UUPdu)
{
OOTRACEERR1("ERROR: H225H323_UU_PDU absent in incoming facility "
"message\n");
return OO_FAILED;
}
facility = pH323UUPdu->h323_message_body.u.facility;
if(facility)
{
/* Depending on the reason of facility message handle the message */
if(facility->reason.t == T_H225FacilityReason_transportedInformation)
{
if(OO_TESTFLAG (call->flags, OO_M_TUNNELING))
{
OOTRACEDBGB3("Handling tunneled messages in Facility. (%s, %s)\n",
call->callType, call->callToken);
ooHandleTunneledH245Messages(call, pH323UUPdu);
OOTRACEDBGB3("Finished handling tunneled messages in Facility."
"(%s, %s)\n",call->callType, call->callToken);
}
else
{
OOTRACEERR3("ERROR:Tunneled H.245 message received in facility. "
"Tunneling is disabled at local for this call (%s, %s)\n",
call->callType, call->callToken);
return OO_FAILED;
}
}
else if(facility->reason.t == T_H225FacilityReason_startH245)
{
OOTRACEINFO3("Remote wants to start a separate H.245 Channel "
"(%s, %s)\n", call->callType, call->callToken);
/*start H.245 channel*/
ret = ooHandleStartH245FacilityMessage(call, facility);
if(ret != OO_OK)
{
OOTRACEERR3("ERROR: Handling startH245 facility message "
"(%s, %s)\n", call->callType, call->callToken);
return ret;
}
}
else if(facility->reason.t == T_H225FacilityReason_callForwarded)
{
OOTRACEINFO3("Call Forward Facility message received. (%s, %s)\n",
call->callType, call->callToken);
if(!facility->m.alternativeAddressPresent &&
!facility->m.alternativeAliasAddressPresent)
{
OOTRACEERR3("Error:No alternative address provided in call forward"
"facility message.(%s, %s)\n", call->callType,
call->callToken);
if(call->callState < OO_CALL_CLEAR)
{
call->callState = OO_CALL_CLEAR;
call->callEndReason = OO_REASON_INVALIDMESSAGE;
}
return OO_OK;
}
call->pCallFwdData = (OOCallFwdData *) memAlloc(call->pctxt,
sizeof(OOCallFwdData));
if(!call->pCallFwdData)
{
OOTRACEERR3("Error:Memory - ooOnReceivedFacility - pCallFwdData "
"(%s, %s)\n", call->callType, call->callToken);
return OO_FAILED;
}
call->pCallFwdData->fwdedByRemote = TRUE;
call->pCallFwdData->ip[0]='\0';
call->pCallFwdData->aliases = NULL;
if(facility->m.alternativeAddressPresent)
{
if(facility->alternativeAddress.t !=
T_H225TransportAddress_ipAddress)
{
OOTRACEERR3("ERROR: Source call signalling address type not ip "
"(%s, %s)\n", call->callType, call->callToken);
return OO_FAILED;
}
ip = &facility->alternativeAddress.u.ipAddress->ip;
sprintf(call->pCallFwdData->ip, "%d.%d.%d.%d", ip->data[0],
ip->data[1], ip->data[2], ip->data[3]);
call->pCallFwdData->port =
facility->alternativeAddress.u.ipAddress->port;
}
if(facility->m.alternativeAliasAddressPresent)
{
ooH323RetrieveAliases(call, &facility->alternativeAliasAddress,
&call->pCallFwdData->aliases);
}
/* Now we have to clear the current call and make a new call to
fwded location*/
if(call->callState < OO_CALL_CLEAR)
{
call->callState = OO_CALL_CLEAR;
call->callEndReason = OO_REASON_REMOTE_FWDED;
}
else{
OOTRACEERR3("Error:Can't forward call as it is being cleared."
" (%s, %s)\n", call->callType, call->callToken);
return OO_OK;
}
}
else{
OOTRACEINFO3("Unhandled Facility reason type received (%s, %s)\n",
call->callType, call->callToken);
}
}
else{ /* Empty facility message Check for tunneling */
OOTRACEDBGB3("Handling tunneled messages in empty Facility message."
" (%s, %s)\n", call->callType, call->callToken);
ooHandleTunneledH245Messages(call, pH323UUPdu);
OOTRACEDBGB3("Finished handling tunneled messages in empty Facility "
"message. (%s, %s)\n", call->callType, call->callToken);
}
return OO_OK;
}
int ooHandleStartH245FacilityMessage
(OOH323CallData *call, H225Facility_UUIE *facility)
{
H225TransportAddress_ipAddress *ipAddress = NULL;
int ret;
/* Extract H245 address */
if(!facility->m.h245AddressPresent)
{
OOTRACEERR3("ERROR: startH245 facility message received with no h245 "
"address (%s, %s)\n", call->callType, call->callToken);
return OO_FAILED;
}
if(facility->h245Address.t != T_H225TransportAddress_ipAddress)
{
OOTRACEERR3("ERROR:Unknown H245 address type in received startH245 "
"facility message (%s, %s)\n", call->callType, call->callToken);
return OO_FAILED;
}
ipAddress = facility->h245Address.u.ipAddress;
if(!ipAddress)
{
OOTRACEERR3("ERROR:Invalid startH245 facility message. No H245 ip "
"address found. (%s, %s)\n", call->callType, call->callToken);
return OO_FAILED;
}
sprintf(call->remoteIP, "%d.%d.%d.%d", ipAddress->ip.data[0],
ipAddress->ip.data[1],
ipAddress->ip.data[2],
ipAddress->ip.data[3]);
call->remoteH245Port = ipAddress->port;
/* disable tunneling for this call */
OO_CLRFLAG (call->flags, OO_M_TUNNELING);
/*Establish an H.245 connection */
ret = ooCreateH245Connection(call);
if(ret != OO_OK)
{
OOTRACEERR3("ERROR: Failed to establish an H.245 connection with remote"
" endpoint (%s, %s)\n", call->callType, call->callToken);
return ret;
}
return OO_OK;
}
int ooHandleTunneledH245Messages
(OOH323CallData *call, H225H323_UU_PDU * pH323UUPdu)
{
H245Message *pmsg;
OOCTXT *pctxt = &gH323ep.msgctxt;
int ret=0,i=0;
OOTRACEDBGC3("Checking for tunneled H.245 messages (%s, %s)\n",
call->callType, call->callToken);
/* Check whether there are tunneled messages */
if(pH323UUPdu->m.h245TunnelingPresent)
{
if(pH323UUPdu->h245Tunneling)
{
OOTRACEDBGB4("Total number of tunneled H245 messages are %d.(%s, %s)"
"\n", (int)pH323UUPdu->h245Control.n, call->callType,
call->callToken);
for(i=0; i< (int)pH323UUPdu->h245Control.n; i++)
{
OOTRACEDBGC5("Retrieving %d of %d tunneled H.245 messages."
"(%s, %s)\n",i+1, pH323UUPdu->h245Control.n,
call->callType, call->callToken);
pmsg = (H245Message*)memAlloc(pctxt, sizeof(H245Message));
if(!pmsg)
{
OOTRACEERR3("Error:Memory - ooHandleH245TunneledMessages - pmsg"
"(%s, %s)\n", call->callType, call->callToken);
return OO_FAILED;
}
setPERBuffer(pctxt,
(ASN1OCTET*)pH323UUPdu->h245Control.elem[i].data,
pH323UUPdu->h245Control.elem[i].numocts, 1);
initializePrintHandler(&printHandler, "Tunneled H.245 Message");
memset(pmsg, 0, sizeof(H245Message));
/* Set event handler */
setEventHandler (pctxt, &printHandler);
OOTRACEDBGC4("Decoding %d tunneled H245 message. (%s, %s)\n",
i+1, call->callType, call->callToken);
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);
memFreePtr(pctxt, pmsg);
pmsg = NULL;
}/* End of For loop */
}/* End of if(h245Tunneling) */
}
return OO_OK;
}
int ooH323RetrieveAliases
(OOH323CallData *call, H225_SeqOfH225AliasAddress *pAddresses,
OOAliases **aliasList)
{
int i=0,j=0,k=0;
DListNode* pNode=NULL;
H225AliasAddress *pAliasAddress=NULL;
OOAliases *newAlias=NULL;
H225TransportAddress *pTransportAddrss=NULL;
if(!pAddresses)
{
OOTRACEWARN3("Warn:No Aliases present (%s, %s)\n", call->callType,
call->callToken);
return OO_OK;
}
/* check for aliases */
if(pAddresses->count<=0)
return OO_OK;
for(i=0; i<(int)pAddresses->count; i++)
{
pNode = dListFindByIndex (pAddresses, i);
if(!pNode)
continue;
pAliasAddress = (H225AliasAddress*)pNode->data;
if(!pAliasAddress)
continue;
newAlias = (OOAliases*)memAlloc(call->pctxt, sizeof(OOAliases));
if(!newAlias)
{
OOTRACEERR3("ERROR:Memory - ooH323RetrieveAliases - newAlias "
"(%s, %s)\n", call->callType, call->callToken);
return OO_FAILED;
}
memset(newAlias, 0, sizeof(OOAliases));
switch(pAliasAddress->t)
{
case T_H225AliasAddress_dialedDigits:
newAlias->type = T_H225AliasAddress_dialedDigits;
newAlias->value = (char*) memAlloc(call->pctxt,
strlen(pAliasAddress->u.dialedDigits)*sizeof(char)+1);
if(!newAlias->value)
{
OOTRACEERR3("ERROR:Memory - ooH323RetrieveAliases - "
"newAlias->value(dialedDigits) (%s, %s)\n",
call->callType, call->callToken);
memFreePtr(call->pctxt, newAlias);
return OO_FAILED;
}
memcpy(newAlias->value, pAliasAddress->u.dialedDigits,
strlen(pAliasAddress->u.dialedDigits)*sizeof(char));
newAlias->value[strlen(pAliasAddress->u.dialedDigits)*sizeof(char)]='\0';
break;
case T_H225AliasAddress_h323_ID:
newAlias->type = T_H225AliasAddress_h323_ID;
newAlias->value = (char*)memAlloc(call->pctxt,
(pAliasAddress->u.h323_ID.nchars+1)*sizeof(char)+1);
if(!newAlias->value)
{
OOTRACEERR3("ERROR:Memory - ooH323RetrieveAliases - "
"newAlias->value(h323id) (%s, %s)\n", call->callType,
call->callToken);
memFreePtr(call->pctxt, newAlias);
return OO_FAILED;
}
for(j=0, k=0; j<(int)pAliasAddress->u.h323_ID.nchars; j++)
{
if(pAliasAddress->u.h323_ID.data[j] < 256)
{
newAlias->value[k++] = (char) pAliasAddress->u.h323_ID.data[j];
}
}
newAlias->value[k] = '\0';
break;
case T_H225AliasAddress_url_ID:
newAlias->type = T_H225AliasAddress_url_ID;
newAlias->value = (char*)memAlloc(call->pctxt,
strlen(pAliasAddress->u.url_ID)*sizeof(char)+1);
if(!newAlias->value)
{
OOTRACEERR3("ERROR:Memory - ooH323RetrieveAliases - "
"newAlias->value(urlid) (%s, %s)\n", call->callType,
call->callToken);
memFreePtr(call->pctxt, newAlias);
return OO_FAILED;
}
memcpy(newAlias->value, pAliasAddress->u.url_ID,
strlen(pAliasAddress->u.url_ID)*sizeof(char));
newAlias->value[strlen(pAliasAddress->u.url_ID)*sizeof(char)]='\0';
break;
case T_H225AliasAddress_transportID:
newAlias->type = T_H225AliasAddress_transportID;
pTransportAddrss = pAliasAddress->u.transportID;
if(pTransportAddrss->t != T_H225TransportAddress_ipAddress)
{
OOTRACEERR3("Error:Alias transportID not an IP address"
"(%s, %s)\n", call->callType, call->callToken);
memFreePtr(call->pctxt, newAlias);
break;
}
/* hopefully ip:port value can't exceed more than 30
characters */
newAlias->value = (char*)memAlloc(call->pctxt,
30*sizeof(char));
sprintf(newAlias->value, "%d.%d.%d.%d:%d",
pTransportAddrss->u.ipAddress->ip.data[0],
pTransportAddrss->u.ipAddress->ip.data[1],
pTransportAddrss->u.ipAddress->ip.data[2],
pTransportAddrss->u.ipAddress->ip.data[3],
pTransportAddrss->u.ipAddress->port);
break;
case T_H225AliasAddress_email_ID:
newAlias->type = T_H225AliasAddress_email_ID;
newAlias->value = (char*)memAlloc(call->pctxt,
strlen(pAliasAddress->u.email_ID)*sizeof(char)+1);
if(!newAlias->value)
{
OOTRACEERR3("ERROR:Memory - ooH323RetrieveAliases - "
"newAlias->value(emailid) (%s, %s)\n", call->callType,
call->callToken);
memFreePtr(call->pctxt, newAlias);
return OO_FAILED;
}
memcpy(newAlias->value, pAliasAddress->u.email_ID,
strlen(pAliasAddress->u.email_ID)*sizeof(char));
newAlias->value[strlen(pAliasAddress->u.email_ID)*sizeof(char)]='\0';
break;
default:
OOTRACEERR3("Error:Unhandled Alias type (%s, %s)\n",
call->callType, call->callToken);
memFreePtr(call->pctxt, newAlias);
continue;
}
newAlias->next = *aliasList;
*aliasList = newAlias;
newAlias = NULL;
pAliasAddress = NULL;
pNode = NULL;
}/* endof: for */
return OO_OK;
}
int ooPopulateAliasList(OOCTXT *pctxt, OOAliases *pAliases,
H225_SeqOfH225AliasAddress *pAliasList )
{
H225AliasAddress *pAliasEntry=NULL;
OOAliases * pAlias=NULL;
ASN1BOOL bValid=FALSE;
int i = 0;
dListInit(pAliasList);
if(pAliases)
{
pAlias = pAliases;
while(pAlias)
{
pAliasEntry = (H225AliasAddress*)memAlloc(pctxt,
sizeof(H225AliasAddress));
if(!pAliasEntry)
{
OOTRACEERR1("ERROR:Memory - ooPopulateAliasList - pAliasEntry\n");
return OO_FAILED;
}
switch(pAlias->type)
{
case T_H225AliasAddress_dialedDigits:
pAliasEntry->t = T_H225AliasAddress_dialedDigits;
pAliasEntry->u.dialedDigits = (ASN1IA5String)memAlloc(pctxt,
strlen(pAlias->value)+1);
if(!pAliasEntry->u.dialedDigits)
{
OOTRACEERR1("ERROR:Memory - ooPopulateAliasList - "
"dialedDigits\n");
memFreePtr(pctxt, pAliasEntry);
return OO_FAILED;
}
strcpy((char*)pAliasEntry->u.dialedDigits, pAlias->value);
bValid = TRUE;
break;
case T_H225AliasAddress_h323_ID:
pAliasEntry->t = T_H225AliasAddress_h323_ID;
pAliasEntry->u.h323_ID.nchars = strlen(pAlias->value);
pAliasEntry->u.h323_ID.data = (ASN116BITCHAR*)memAllocZ
(pctxt, strlen(pAlias->value)*sizeof(ASN116BITCHAR));
if(!pAliasEntry->u.h323_ID.data)
{
OOTRACEERR1("ERROR:Memory - ooPopulateAliasList - h323_id\n");
memFreePtr(pctxt, pAliasEntry);
return OO_FAILED;
}
for(i=0; *(pAlias->value+i) != '\0'; i++)
pAliasEntry->u.h323_ID.data[i] =(ASN116BITCHAR)pAlias->value[i];
bValid = TRUE;
break;
case T_H225AliasAddress_url_ID:
pAliasEntry->t = T_H225AliasAddress_url_ID;
pAliasEntry->u.url_ID = (ASN1IA5String)memAlloc(pctxt,
strlen(pAlias->value)+1);
if(!pAliasEntry->u.url_ID)
{
OOTRACEERR1("ERROR:Memory - ooPopulateAliasList - url_id\n");
memFreePtr(pctxt, pAliasEntry);
return OO_FAILED;
}
strcpy((char*)pAliasEntry->u.url_ID, pAlias->value);
bValid = TRUE;
break;
case T_H225AliasAddress_email_ID:
pAliasEntry->t = T_H225AliasAddress_email_ID;
pAliasEntry->u.email_ID = (ASN1IA5String)memAlloc(pctxt,
strlen(pAlias->value)+1);
if(!pAliasEntry->u.email_ID)
{
OOTRACEERR1("ERROR: Failed to allocate memory for EmailID "
"alias entry \n");
return OO_FAILED;
}
strcpy((char*)pAliasEntry->u.email_ID, pAlias->value);
bValid = TRUE;
break;
default:
OOTRACEERR1("ERROR: Unhandled alias type\n");
bValid = FALSE;
}
if(bValid)
dListAppend( pctxt, pAliasList, (void*)pAliasEntry );
else
memFreePtr(pctxt, pAliasEntry);
pAlias = pAlias->next;
}
}
return OO_OK;
}
OOAliases* ooH323GetAliasFromList(OOAliases *aliasList, int type, char *value)
{
OOAliases *pAlias = NULL;
if(!aliasList)
{
OOTRACEDBGC1("No alias List to search\n");
return NULL;
}
pAlias = aliasList;
while(pAlias)
{
if(type != 0 && value) { /* Search by type and value */
if(pAlias->type == type && !strcmp(pAlias->value, value))
{
return pAlias;
}
}
else if(type != 0 && !value) {/* search by type */
if(pAlias->type == type)
return pAlias;
}
else if(type == 0 && value) {/* search by value */
if(!strcmp(pAlias->value, value))
return pAlias;
}
else {
OOTRACEDBGC1("No criteria to search the alias list\n");
return NULL;
}
pAlias = pAlias->next;
}
return NULL;
}
OOAliases* ooH323AddAliasToList
(OOAliases **pAliasList, OOCTXT *pctxt, H225AliasAddress *pAliasAddress)
{
int j=0,k=0;
OOAliases *newAlias=NULL;
H225TransportAddress *pTransportAddrss=NULL;
newAlias = (OOAliases*) memAlloc(pctxt, sizeof(OOAliases));
if(!newAlias)
{
OOTRACEERR1("Error: Failed to allocate memory for new alias to be added to the alias list\n");
return NULL;
}
memset(newAlias, 0, sizeof(OOAliases));
switch(pAliasAddress->t)
{
case T_H225AliasAddress_dialedDigits:
newAlias->type = T_H225AliasAddress_dialedDigits;
newAlias->value = (char*) memAlloc(pctxt, strlen(pAliasAddress->u.dialedDigits)*sizeof(char)+1);
strcpy(newAlias->value, pAliasAddress->u.dialedDigits);
break;
case T_H225AliasAddress_h323_ID:
newAlias->type = T_H225AliasAddress_h323_ID;
newAlias->value = (char*)memAlloc(pctxt,
(pAliasAddress->u.h323_ID.nchars+1)*sizeof(char)+1);
for(j=0, k=0; j<(int)pAliasAddress->u.h323_ID.nchars; j++)
{
if(pAliasAddress->u.h323_ID.data[j] < 256)
{
newAlias->value[k++] = (char) pAliasAddress->u.h323_ID.data[j];
}
}
newAlias->value[k] = '\0';
break;
case T_H225AliasAddress_url_ID:
newAlias->type = T_H225AliasAddress_url_ID;
newAlias->value = (char*)memAlloc(pctxt,
strlen(pAliasAddress->u.url_ID)*sizeof(char)+1);
strcpy(newAlias->value, pAliasAddress->u.url_ID);
break;
case T_H225AliasAddress_transportID:
newAlias->type = T_H225AliasAddress_transportID;
pTransportAddrss = pAliasAddress->u.transportID;
if(pTransportAddrss->t != T_H225TransportAddress_ipAddress)
{
OOTRACEERR1("Error:Alias transportID not an IP address\n");
memFreePtr(pctxt, newAlias);
return NULL;
}
/* hopefully ip:port value can't exceed more than 30
characters */
newAlias->value = (char*)memAlloc(pctxt,
30*sizeof(char));
sprintf(newAlias->value, "%d.%d.%d.%d:%d",
pTransportAddrss->u.ipAddress->ip.data[0],
pTransportAddrss->u.ipAddress->ip.data[1],
pTransportAddrss->u.ipAddress->ip.data[2],
pTransportAddrss->u.ipAddress->ip.data[3],
pTransportAddrss->u.ipAddress->port);
break;
case T_H225AliasAddress_email_ID:
newAlias->type = T_H225AliasAddress_email_ID;
newAlias->value = (char*)memAlloc(pctxt,
strlen(pAliasAddress->u.email_ID)*sizeof(char)+1);
strcpy(newAlias->value, pAliasAddress->u.email_ID);
break;
default:
OOTRACEERR1("Error:Unhandled Alias type \n");
memFreePtr(pctxt, newAlias);
return NULL;
}
newAlias->next = *pAliasList;
*pAliasList= newAlias;
return newAlias;
}
int ooH323GetIpPortFromH225TransportAddress(struct OOH323CallData *call,
H225TransportAddress *h225Address, char *ip, int *port)
{
if(h225Address->t != T_H225TransportAddress_ipAddress)
{
OOTRACEERR3("Error: Unknown H225 address type. (%s, %s)", call->callType,
call->callToken);
return OO_FAILED;
}
sprintf(ip, "%d.%d.%d.%d",
h225Address->u.ipAddress->ip.data[0],
h225Address->u.ipAddress->ip.data[1],
h225Address->u.ipAddress->ip.data[2],
h225Address->u.ipAddress->ip.data[3]);
*port = h225Address->u.ipAddress->port;
return OO_OK;
}