1844 lines
68 KiB
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;
|
|
}
|