diff options
Diffstat (limited to 'addons/ooh323c/src/ooh323.c')
-rw-r--r-- | addons/ooh323c/src/ooh323.c | 1843 |
1 files changed, 1843 insertions, 0 deletions
diff --git a/addons/ooh323c/src/ooh323.c b/addons/ooh323c/src/ooh323.c new file mode 100644 index 000000000..1cefa1d0b --- /dev/null +++ b/addons/ooh323c/src/ooh323.c @@ -0,0 +1,1843 @@ +/* + * 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; +} |