diff options
Diffstat (limited to 'addons/ooh323c/src/ooLogChan.c')
-rw-r--r-- | addons/ooh323c/src/ooLogChan.c | 372 |
1 files changed, 372 insertions, 0 deletions
diff --git a/addons/ooh323c/src/ooLogChan.c b/addons/ooh323c/src/ooLogChan.c new file mode 100644 index 000000000..86c8844c7 --- /dev/null +++ b/addons/ooh323c/src/ooLogChan.c @@ -0,0 +1,372 @@ +/* + * 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 "ooCalls.h" +#include "ooh323ep.h" + +/** Global endpoint structure */ +extern OOH323EndPoint gH323ep; + +OOLogicalChannel* ooAddNewLogicalChannel(OOH323CallData *call, int channelNo, + int sessionID, char *dir, + ooH323EpCapability *epCap) +{ + OOLogicalChannel *pNewChannel=NULL, *pChannel=NULL; + OOMediaInfo *pMediaInfo = NULL; + OOTRACEDBGC5("Adding new media channel for cap %d dir %s (%s, %s)\n", + epCap->cap, dir, call->callType, call->callToken); + /* Create a new logical channel entry */ + pNewChannel = (OOLogicalChannel*)memAlloc(call->pctxt, + sizeof(OOLogicalChannel)); + if(!pNewChannel) + { + OOTRACEERR3("ERROR:Memory - ooAddNewLogicalChannel - pNewChannel " + "(%s, %s)\n", call->callType, call->callToken); + return NULL; + } + + memset(pNewChannel, 0, sizeof(OOLogicalChannel)); + pNewChannel->channelNo = channelNo; + pNewChannel->sessionID = sessionID; + pNewChannel->state = OO_LOGICALCHAN_IDLE; + pNewChannel->type = epCap->capType; + /* strcpy(pNewChannel->type, type);*/ + strcpy(pNewChannel->dir, dir); + + pNewChannel->chanCap = epCap; + OOTRACEDBGC4("Adding new channel with cap %d (%s, %s)\n", epCap->cap, + call->callType, call->callToken); + /* As per standards, media control port should be same for all + proposed channels with same session ID. However, most applications + use same media port for transmit and receive of audio streams. Infact, + testing of OpenH323 based asterisk assumed that same ports are used. + Hence we first search for existing media ports for same session and use + them. This should take care of all cases. + */ + if(call->mediaInfo) + { + pMediaInfo = call->mediaInfo; + while(pMediaInfo) + { + if(!strcmp(pMediaInfo->dir, dir) && + (pMediaInfo->cap == epCap->cap)) + { + break; + } + pMediaInfo = pMediaInfo->next; + } + } + + if(pMediaInfo) + { + OOTRACEDBGC3("Using configured media info (%s, %s)\n", call->callType, + call->callToken); + pNewChannel->localRtpPort = pMediaInfo->lMediaPort; + pNewChannel->localRtcpPort = pMediaInfo->lMediaCntrlPort; + /* If user application has not specified a specific ip and is using + multihomed mode, substitute appropriate ip. + */ + if(!strcmp(pMediaInfo->lMediaIP, "0.0.0.0")) + strcpy(pNewChannel->localIP, call->localIP); + else + strcpy(pNewChannel->localIP, pMediaInfo->lMediaIP); + } + else{ + OOTRACEDBGC3("Using default media info (%s, %s)\n", call->callType, + call->callToken); + pNewChannel->localRtpPort = ooGetNextPort (OORTP); + + /* Ensures that RTP port is an even one */ + if((pNewChannel->localRtpPort & 1) == 1) + pNewChannel->localRtpPort = ooGetNextPort (OORTP); + + pNewChannel->localRtcpPort = ooGetNextPort (OORTP); + strcpy(pNewChannel->localIP, call->localIP); + } + + /* Add new channel to the list */ + pNewChannel->next = NULL; + if(!call->logicalChans) { + call->logicalChans = pNewChannel; + } + else{ + pChannel = call->logicalChans; + while(pChannel->next) pChannel = pChannel->next; + pChannel->next = pNewChannel; + } + + /* increment logical channels */ + call->noOfLogicalChannels++; + OOTRACEINFO3("Created new logical channel entry (%s, %s)\n", call->callType, + call->callToken); + return pNewChannel; +} + +OOLogicalChannel* ooFindLogicalChannelByLogicalChannelNo(OOH323CallData *call, + int ChannelNo) +{ + OOLogicalChannel *pLogicalChannel=NULL; + if(!call->logicalChans) + { + OOTRACEERR3("ERROR: No Open LogicalChannels - Failed " + "FindLogicalChannelByChannelNo (%s, %s\n", call->callType, + call->callToken); + return NULL; + } + pLogicalChannel = call->logicalChans; + while(pLogicalChannel) + { + if(pLogicalChannel->channelNo == ChannelNo) + break; + else + pLogicalChannel = pLogicalChannel->next; + } + + return pLogicalChannel; +} + +OOLogicalChannel * ooFindLogicalChannelByOLC(OOH323CallData *call, + H245OpenLogicalChannel *olc) +{ + H245DataType * psDataType=NULL; + H245H2250LogicalChannelParameters * pslcp=NULL; + OOTRACEDBGC4("ooFindLogicalChannel by olc %d (%s, %s)\n", + olc->forwardLogicalChannelNumber, call->callType, call->callToken); + if(olc->m.reverseLogicalChannelParametersPresent) + { + OOTRACEDBGC3("Finding receive channel (%s,%s)\n", call->callType, + call->callToken); + psDataType = &olc->reverseLogicalChannelParameters.dataType; + /* Only H2250LogicalChannelParameters are supported */ + if(olc->reverseLogicalChannelParameters.multiplexParameters.t != + T_H245OpenLogicalChannel_reverseLogicalChannelParameters_multiplexParameters_h2250LogicalChannelParameters){ + OOTRACEERR4("Error:Invalid olc %d received (%s, %s)\n", + olc->forwardLogicalChannelNumber, call->callType, call->callToken); + return NULL; + } + pslcp = olc->reverseLogicalChannelParameters.multiplexParameters.u.h2250LogicalChannelParameters; + + return ooFindLogicalChannel(call, pslcp->sessionID, "receive", psDataType); + } + else{ + OOTRACEDBGC3("Finding transmit channel (%s, %s)\n", call->callType, + call->callToken); + psDataType = &olc->forwardLogicalChannelParameters.dataType; + /* Only H2250LogicalChannelParameters are supported */ + if(olc->forwardLogicalChannelParameters.multiplexParameters.t != + T_H245OpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters_h2250LogicalChannelParameters) + { + OOTRACEERR4("Error:Invalid olc %d received (%s, %s)\n", + olc->forwardLogicalChannelNumber, call->callType, call->callToken); + return NULL; + } + pslcp = olc->forwardLogicalChannelParameters.multiplexParameters.u.h2250LogicalChannelParameters; + return ooFindLogicalChannel(call, pslcp->sessionID, "transmit", psDataType); + } +} + +OOLogicalChannel * ooFindLogicalChannel(OOH323CallData *call, int sessionID, + char *dir, H245DataType * dataType) +{ + OOLogicalChannel * pChannel = NULL; + pChannel = call->logicalChans; + while(pChannel) + { + OOTRACEDBGC3("ooFindLogicalChannel, checking channel: %d:%s\n", + pChannel->sessionID, pChannel->dir); + if(pChannel->sessionID == sessionID) + { + if(!strcmp(pChannel->dir, dir)) + { + OOTRACEDBGC3("ooFindLogicalChannel, comparing channel: %d:%s\n", + pChannel->channelNo, pChannel->dir); + if(!strcmp(dir, "receive")) + { + if(ooCapabilityCheckCompatibility(call, pChannel->chanCap, + dataType, OORX)) { + return pChannel; + } + } + else if(!strcmp(dir, "transmit")) + { + if(ooCapabilityCheckCompatibility(call, pChannel->chanCap, + dataType, OOTX)) { + return pChannel; + } + } + } + } + pChannel = pChannel->next; + } + return NULL; +} + +/* This function is used to get a logical channel with a particular session ID */ +OOLogicalChannel* ooGetLogicalChannel + (OOH323CallData *call, int sessionID, char *dir) +{ + OOLogicalChannel * pChannel = NULL; + pChannel = call->logicalChans; + while(pChannel) + { + if(pChannel->sessionID == sessionID && !strcmp(pChannel->dir, dir)) + return pChannel; + else + pChannel = pChannel->next; + } + return NULL; +} + +int ooClearAllLogicalChannels(OOH323CallData *call) +{ + OOLogicalChannel * temp = NULL, *prev = NULL; + + OOTRACEINFO3("Clearing all logical channels (%s, %s)\n", call->callType, + call->callToken); + + temp = call->logicalChans; + while(temp) + { + prev = temp; + temp = temp->next; + ooClearLogicalChannel(call, prev->channelNo);/* TODO: efficiency - This causes re-search + of of logical channel in the list. Can be + easily improved.*/ + } + call->logicalChans = NULL; + return OO_OK; +} + +int ooClearLogicalChannel(OOH323CallData *call, int channelNo) +{ + + OOLogicalChannel *pLogicalChannel = NULL; + ooH323EpCapability *epCap=NULL; + + OOTRACEDBGC4("Clearing logical channel number %d. (%s, %s)\n", channelNo, + call->callType, call->callToken); + + pLogicalChannel = ooFindLogicalChannelByLogicalChannelNo(call,channelNo); + if(!pLogicalChannel) + { + OOTRACEWARN4("Logical Channel %d doesn't exist, in clearLogicalChannel." + " (%s, %s)\n", + channelNo, call->callType, call->callToken); + return OO_OK; + } + + epCap = (ooH323EpCapability*) pLogicalChannel->chanCap; + if(!strcmp(pLogicalChannel->dir, "receive")) + { + if(epCap->stopReceiveChannel) + { + epCap->stopReceiveChannel(call, pLogicalChannel); + OOTRACEINFO4("Stopped Receive channel %d (%s, %s)\n", + channelNo, call->callType, call->callToken); + } + else{ + OOTRACEERR4("ERROR:No callback registered for stopReceiveChannel %d " + "(%s, %s)\n", channelNo, call->callType, call->callToken); + } + } + else + { + if(pLogicalChannel->state == OO_LOGICALCHAN_ESTABLISHED) + { + if(epCap->stopTransmitChannel) + { + epCap->stopTransmitChannel(call, pLogicalChannel); + OOTRACEINFO4("Stopped Transmit channel %d (%s, %s)\n", + channelNo, call->callType, call->callToken); + } + else{ + OOTRACEERR4("ERROR:No callback registered for stopTransmitChannel" + " %d (%s, %s)\n", channelNo, call->callType, + call->callToken); + } + } + } + ooRemoveLogicalChannel(call, channelNo);/* TODO: efficiency - This causes re-search of + of logical channel in the list. Can be + easily improved.*/ + return OO_OK; +} + +int ooRemoveLogicalChannel(OOH323CallData *call, int ChannelNo) +{ + OOLogicalChannel * temp = NULL, *prev=NULL; + if(!call->logicalChans) + { + OOTRACEERR4("ERROR:Remove Logical Channel - Channel %d not found " + "Empty channel List(%s, %s)\n", ChannelNo, call->callType, + call->callToken); + return OO_FAILED; + } + + temp = call->logicalChans; + while(temp) + { + if(temp->channelNo == ChannelNo) + { + if(!prev) call->logicalChans = temp->next; + else prev->next = temp->next; + memFreePtr(call->pctxt, temp->chanCap); + memFreePtr(call->pctxt, temp); + OOTRACEDBGC4("Removed logical channel %d (%s, %s)\n", ChannelNo, + call->callType, call->callToken); + call->noOfLogicalChannels--; + return OO_OK; + } + prev = temp; + temp = temp->next; + } + + OOTRACEERR4("ERROR:Remove Logical Channel - Channel %d not found " + "(%s, %s)\n", ChannelNo, call->callType, call->callToken); + return OO_FAILED; +} + +/* +Change the state of the channel as established and close all other +channels with same session IDs. This is useful for handling fastStart, +as the endpoint can open multiple logical channels for same sessionID. +Once the remote endpoint confirms it's selection, all other channels for +the same sessionID must be closed. +*/ +int ooOnLogicalChannelEstablished + (OOH323CallData *call, OOLogicalChannel * pChannel) +{ + OOLogicalChannel * temp = NULL, *prev=NULL; + OOTRACEDBGC3("In ooOnLogicalChannelEstablished (%s, %s)\n", + call->callType, call->callToken); + pChannel->state = OO_LOGICALCHAN_ESTABLISHED; + temp = call->logicalChans; + while(temp) + { + if(temp->channelNo != pChannel->channelNo && + temp->sessionID == pChannel->sessionID && + !strcmp(temp->dir, pChannel->dir) ) + { + prev = temp; + temp = temp->next; + ooClearLogicalChannel(call, prev->channelNo); + } + else + temp = temp->next; + } + return OO_OK; +} + |