summaryrefslogtreecommitdiff
path: root/addons/ooh323c/src
diff options
context:
space:
mode:
authorAlexandr Anikin <may@telecom-service.ru>2012-07-04 21:42:05 +0000
committerAlexandr Anikin <may@telecom-service.ru>2012-07-04 21:42:05 +0000
commitfa10f3f8a8b727887ffd7857cd7eef222cb24efd (patch)
treeb84e871dbf3e36a4a35c0d550198c7b051936539 /addons/ooh323c/src
parent50765000e619349e6492238197ffa854128b9329 (diff)
Added direct media support to ooh323 channel driver
options are documented in config sample sample config rename to proper name - ooh323.conf To change media address ooh323 send empty TCS if there was completed TCS exchange or send facility forwardedelements with new fast start proposal if not. Then close transmit logical channels and renew TCS exchange. If new fast start proposal is received then ooh323 stack call back channel driver routine to change rtp address in the rtp instance. If empty TCS is received then close transmit logical channels and renew TCS exchange Review: https://reviewboard.asterisk.org/r/1607/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@369613 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'addons/ooh323c/src')
-rw-r--r--addons/ooh323c/src/ooCalls.h7
-rw-r--r--addons/ooh323c/src/ooCmdChannel.c20
-rw-r--r--addons/ooh323c/src/ooLogChan.c29
-rw-r--r--addons/ooh323c/src/ooLogChan.h4
-rw-r--r--addons/ooh323c/src/ooStackCmds.c63
-rw-r--r--addons/ooh323c/src/ooStackCmds.h4
-rw-r--r--addons/ooh323c/src/ooh245.c199
-rw-r--r--addons/ooh323c/src/ooh245.h3
-rw-r--r--addons/ooh323c/src/ooh323.c65
-rw-r--r--addons/ooh323c/src/ooh323ep.c1
-rw-r--r--addons/ooh323c/src/ooq931.c185
-rw-r--r--addons/ooh323c/src/ooq931.h2
12 files changed, 533 insertions, 49 deletions
diff --git a/addons/ooh323c/src/ooCalls.h b/addons/ooh323c/src/ooCalls.h
index a81f536f4..8321d342a 100644
--- a/addons/ooh323c/src/ooCalls.h
+++ b/addons/ooh323c/src/ooCalls.h
@@ -97,6 +97,8 @@ typedef struct OOMediaInfo{
int cap;
int lMediaPort;
int lMediaCntrlPort;
+ int lMediaRedirPort;
+ int lMediaRedirCPort;
char lMediaIP[2+8*4+7];
struct OOMediaInfo *next;
} OOMediaInfo;
@@ -197,6 +199,7 @@ typedef struct OOH323CallData {
ASN1UINT statusDeterminationNumber;
OOCapExchangeState localTermCapState;
OOCapExchangeState remoteTermCapState;
+ OOBOOL TCSPending;
struct ooH323EpCapability* ourCaps;
struct ooH323EpCapability* remoteCaps; /* TODO: once we start using jointCaps, get rid of remoteCaps*/
struct ooH323EpCapability* jointCaps;
@@ -325,6 +328,9 @@ typedef int (*cb_OnReceivedDTMF)
typedef void (*cb_OnModeChanged)
(struct OOH323CallData *call, int isT38Mode);
+typedef void (*cb_OnMediaChanged)
+ (struct OOH323CallData *call, char* remoteIP, int remotePort);
+
/**
* This structure holds all of the H.323 signaling callback function
* addresses.
@@ -342,6 +348,7 @@ typedef struct OOH323CALLBACKS {
cb_OpenLogicalChannels openLogicalChannels;
cb_OnReceivedDTMF onReceivedDTMF;
cb_OnModeChanged onModeChanged;
+ cb_OnMediaChanged onMediaChanged;
} OOH323CALLBACKS;
/**
diff --git a/addons/ooh323c/src/ooCmdChannel.c b/addons/ooh323c/src/ooCmdChannel.c
index 8737e6504..17e9e9ae3 100644
--- a/addons/ooh323c/src/ooCmdChannel.c
+++ b/addons/ooh323c/src/ooCmdChannel.c
@@ -411,12 +411,26 @@ int ooReadAndProcessCallStackCommand(OOH323CallData* call)
}
break;
+ case OO_CMD_UPDLC:
+ OOTRACEINFO4("Processing UpdLC command %s, localIP is %s, port is %d\n",
+ (char *)cmd.param1, (char *)cmd.param2, *(int *)cmd.param3);
+ if (cmd.param2) {
+ ooUpdateAllLogicalChannels(call, (char *)cmd.param2, *(int *)cmd.param3);
+ }
+ break;
+
default: OOTRACEERR1("ERROR:Unknown command\n");
}
}
- if(cmd.param1) free(cmd.param1);
- if(cmd.param2) free(cmd.param2);
- if(cmd.param3) free(cmd.param3);
+ if (cmd.param1) {
+ ast_free(cmd.param1);
+ }
+ if (cmd.param2) {
+ ast_free(cmd.param2);
+ }
+ if (cmd.param3) {
+ ast_free(cmd.param3);
+ }
}
diff --git a/addons/ooh323c/src/ooLogChan.c b/addons/ooh323c/src/ooLogChan.c
index d5e8db178..bafb315e6 100644
--- a/addons/ooh323c/src/ooLogChan.c
+++ b/addons/ooh323c/src/ooLogChan.c
@@ -77,8 +77,9 @@ OOLogicalChannel* ooAddNewLogicalChannel(OOH323CallData *call, int channelNo,
{
OOTRACEDBGC3("Using configured media info (%s, %s)\n", call->callType,
call->callToken);
- pNewChannel->localRtpPort = pMediaInfo->lMediaPort;
- pNewChannel->localRtcpPort = pMediaInfo->lMediaCntrlPort;
+ pNewChannel->localRtpPort = pMediaInfo->lMediaRedirPort ? pMediaInfo->lMediaRedirPort : pMediaInfo->lMediaPort;
+ /* check MediaRedirPort here because RedirCPort is ReditPort + 1 and can't be 0 ;) */
+ pNewChannel->localRtcpPort = pMediaInfo->lMediaRedirPort ? pMediaInfo->lMediaRedirCPort : pMediaInfo->lMediaCntrlPort;
/* If user application has not specified a specific ip and is using
multihomed mode, substitute appropriate ip.
*/
@@ -86,6 +87,8 @@ OOLogicalChannel* ooAddNewLogicalChannel(OOH323CallData *call, int channelNo,
strcpy(pNewChannel->localIP, call->localIP);
else
strcpy(pNewChannel->localIP, pMediaInfo->lMediaIP);
+
+ OOTRACEDBGC5("Configured media info (%s, %s) %s:%d\n", call->callType, call->callToken, pNewChannel->localIP, pNewChannel->localRtcpPort);
}
else{
OOTRACEDBGC3("Using default media info (%s, %s)\n", call->callType,
@@ -254,6 +257,26 @@ OOLogicalChannel* ooGetTransmitLogicalChannel
return NULL;
}
+
+OOLogicalChannel* ooGetReceiveLogicalChannel
+ (OOH323CallData *call)
+{
+ OOLogicalChannel * pChannel = NULL;
+ pChannel = call->logicalChans;
+ while (pChannel) {
+ OOTRACEINFO6("Listing logical channel %d cap %d state %d for (%s, %s)\n",
+ pChannel->channelNo, pChannel->chanCap->cap, pChannel->state,
+ call->callType, call->callToken);
+ if (!strcmp(pChannel->dir, "receive") && pChannel->state != OO_LOGICALCHAN_IDLE &&
+ pChannel->state != OO_LOGICALCHAN_PROPOSEDFS) {
+ return pChannel;
+ } else {
+ pChannel = pChannel->next;
+ }
+ }
+ return NULL;
+}
+
int ooClearAllLogicalChannels(OOH323CallData *call)
{
OOLogicalChannel * temp = NULL, *prev = NULL;
@@ -326,7 +349,7 @@ int ooClearLogicalChannel(OOH323CallData *call, int channelNo)
ooRemoveLogicalChannel(call, channelNo);/* TODO: efficiency - This causes re-search of
of logical channel in the list. Can be
easily improved.*/
- } while ((pLogicalChannel = ooFindLogicalChannelByLogicalChannelNo(call,channelNo)));
+ } while ((pLogicalChannel = ooFindLogicalChannelByLogicalChannelNo(call, channelNo)));
return OO_OK;
}
diff --git a/addons/ooh323c/src/ooLogChan.h b/addons/ooh323c/src/ooLogChan.h
index 183eb1445..c52e9a73d 100644
--- a/addons/ooh323c/src/ooLogChan.h
+++ b/addons/ooh323c/src/ooLogChan.h
@@ -42,7 +42,8 @@ typedef enum {
OO_LOGICALCHAN_IDLE,
OO_LOGICALCHAN_PROPOSED,
OO_LOGICALCHAN_ESTABLISHED,
- OO_LOGICALCHAN_PROPOSEDFS
+ OO_LOGICALCHAN_PROPOSEDFS,
+ OO_LOGICALCHAN_CLOSEPENDING
} OOLogicalChannelState;
/**
@@ -181,6 +182,7 @@ EXTERN OOLogicalChannel * ooFindLogicalChannel
(struct OOH323CallData* call, int sessionID, char *dir, H245DataType* dataType);
EXTERN OOLogicalChannel* ooGetTransmitLogicalChannel(struct OOH323CallData *call);
+EXTERN OOLogicalChannel* ooGetReceiveLogicalChannel(struct OOH323CallData *call);
/**
* @}
diff --git a/addons/ooh323c/src/ooStackCmds.c b/addons/ooh323c/src/ooStackCmds.c
index 2cb1902be..8513e44b7 100644
--- a/addons/ooh323c/src/ooStackCmds.c
+++ b/addons/ooh323c/src/ooStackCmds.c
@@ -545,6 +545,68 @@ OOStkCmdStat ooSetANI(const char *callToken, const char* ani)
return OO_STKCMD_SUCCESS;
}
+OOStkCmdStat ooUpdateLogChannels(const char *callToken, const char* localIP, int port)
+{
+ OOStackCommand cmd;
+ OOH323CallData *call;
+
+ if (!callToken) {
+ return OO_STKCMD_INVALIDPARAM;
+ }
+
+ if (!(call = ooFindCallByToken(callToken))) {
+ return OO_STKCMD_INVALIDPARAM;
+ }
+
+ if (localIP == NULL) {
+ return OO_STKCMD_INVALIDPARAM;
+ }
+
+ if (call->CmdChan == 0) {
+ if (ooCreateCallCmdConnection(call) != OO_OK) {
+ return OO_STKCMD_CONNECTIONERR;
+ }
+ }
+
+ memset(&cmd, 0, sizeof(OOStackCommand));
+ cmd.type = OO_CMD_UPDLC;
+
+ cmd.param1 = ast_malloc(strlen(callToken) + 1);
+ cmd.param2 = ast_malloc(strlen(localIP) + 1);
+ cmd.param3 = ast_malloc(sizeof(int) + 1);
+ if (!cmd.param1 || !cmd.param2 || !cmd.param3) {
+ if (cmd.param1) {
+ ast_free(cmd.param1); /* Release memory */
+ }
+ if (cmd.param2) {
+ ast_free(cmd.param2);
+ }
+ if (cmd.param3) {
+ ast_free(cmd.param3);
+ }
+ return OO_STKCMD_MEMERR;
+ }
+ strcpy((char*)cmd.param1, callToken);
+ cmd.plen1 = strlen(callToken);
+ strcpy((char*)cmd.param2, localIP);
+ cmd.plen2 = strlen(localIP);
+ *((int *)cmd.param3) = port;
+ cmd.plen3 = sizeof(int) + 1;
+
+ if (ooWriteCallStackCommand(call, &cmd) != OO_OK) {
+ ast_free(cmd.param1);
+ ast_free(cmd.param2);
+ ast_free(cmd.param3);
+ return OO_STKCMD_WRITEERR;
+ }
+
+ ast_free(cmd.param1);
+ ast_free(cmd.param2);
+ ast_free(cmd.param3);
+
+ return OO_STKCMD_SUCCESS;
+}
+
OOStkCmdStat ooRequestChangeMode(const char *callToken, int isT38Mode)
{
OOStackCommand cmd;
@@ -593,7 +655,6 @@ OOStkCmdStat ooRequestChangeMode(const char *callToken, int isT38Mode)
return OO_STKCMD_SUCCESS;
}
-
const char* ooGetStkCmdStatusCodeTxt(OOStkCmdStat stat)
{
switch(stat)
diff --git a/addons/ooh323c/src/ooStackCmds.h b/addons/ooh323c/src/ooStackCmds.h
index dc6a2128e..df7767ce9 100644
--- a/addons/ooh323c/src/ooStackCmds.h
+++ b/addons/ooh323c/src/ooStackCmds.h
@@ -68,7 +68,8 @@ typedef enum OOStackCmdID {
OO_CMD_MANUALPROGRESS, /*!< Send progress */
OO_CMD_STOPMONITOR, /*!< Stop the event monitor */
OO_CMD_REQMODE, /*!< Request new mode */
- OO_CMD_SETANI /*! <Set conncted info */
+ OO_CMD_SETANI, /*! <Set conncted info */
+ OO_CMD_UPDLC /*! <Update Logical channels */
} OOStackCmdID;
@@ -178,6 +179,7 @@ EXTERN OOStkCmdStat ooRunCall(const char* dest, char* callToken, size_t bufsiz,
int ooGenerateOutgoingCallToken (char *callToken, size_t size);
EXTERN OOStkCmdStat ooSetANI(const char *callToken, const char* ani);
+EXTERN OOStkCmdStat ooUpdateLogChannels(const char *callToken, const char* localIP, const int port);
#ifdef __cplusplus
}
diff --git a/addons/ooh323c/src/ooh245.c b/addons/ooh323c/src/ooh245.c
index 4176b2a42..ff4fa07c8 100644
--- a/addons/ooh323c/src/ooh245.c
+++ b/addons/ooh323c/src/ooh245.c
@@ -817,6 +817,51 @@ int ooSendTermCapMsg(OOH323CallData *call)
return ret;
}
+int ooSendEmptyTermCapMsg(OOH323CallData *call)
+{
+ int ret;
+ H245RequestMessage *request = NULL;
+ OOCTXT *pctxt = NULL;
+ H245TerminalCapabilitySet *termCap = NULL;
+ H245Message *ph245msg = NULL;
+
+ ret = ooCreateH245Message(call, &ph245msg,
+ T_H245MultimediaSystemControlMessage_request);
+
+ if (ret == OO_FAILED) {
+ OOTRACEERR3("Error:Failed to create H245 message for Terminal "
+ "CapabilitySet (%s, %s)\n", call->callType, call->callToken);
+ return OO_FAILED;
+ }
+
+ /* Set request type as TerminalCapabilitySet */
+ request = ph245msg->h245Msg.u.request;
+ pctxt = call->msgctxt;
+ ph245msg->msgType = OOTerminalCapabilitySet;
+ memset(request, 0, sizeof(H245RequestMessage));
+
+ request->t = T_H245RequestMessage_terminalCapabilitySet;
+ request->u.terminalCapabilitySet = (H245TerminalCapabilitySet*)
+ memAlloc(pctxt, sizeof(H245TerminalCapabilitySet));
+ termCap = request->u.terminalCapabilitySet;
+ memset(termCap, 0, sizeof(H245TerminalCapabilitySet));
+ termCap->m.multiplexCapabilityPresent = 0;
+ termCap->m.capabilityTablePresent = 0;
+ termCap->m.capabilityDescriptorsPresent = 0;
+ termCap->sequenceNumber = ++(call->localTermCapSeqNo);
+ termCap->protocolIdentifier = gh245ProtocolID; /* protocol id */
+
+ OOTRACEDBGA3("Built empty terminal capability set message (%s, %s)\n",
+ call->callType, call->callToken);
+ ret = ooSendH245Msg(call, ph245msg);
+ if (ret != OO_OK) {
+ OOTRACEERR3("Error:Failed to enqueue empty TCS message to outbound queue. "
+ "(%s, %s)\n", call->callType, call->callToken);
+ }
+ ooFreeH245Message(call, ph245msg);
+
+ return ret;
+}
ASN1UINT ooGenerateStatusDeterminationNumber()
@@ -1668,11 +1713,11 @@ int ooHandleOpenLogicalChannel_helper(OOH323CallData *call,
}
if (call->versionIP == 6) {
- inet_pton(AF_INET6, call->localIP, iP6Address->network.data);
+ inet_pton(AF_INET6, pLogicalChannel->localIP, iP6Address->network.data);
iP6Address->network.numocts = 16;
iP6Address->tsapIdentifier = pLogicalChannel->localRtpPort;
} else {
- inet_pton(AF_INET, call->localIP, iPAddress->network.data);
+ inet_pton(AF_INET, pLogicalChannel->localIP, iPAddress->network.data);
iPAddress->network.numocts = 4;
iPAddress->tsapIdentifier = pLogicalChannel->localRtpPort;
}
@@ -1692,7 +1737,7 @@ int ooHandleOpenLogicalChannel_helper(OOH323CallData *call,
memAlloc(pctxt, sizeof(H245UnicastAddress_iP6Address));
iP6Address1 = unicastAddrs1->u.iP6Address;
memset(iP6Address1, 0, sizeof(H245UnicastAddress_iP6Address));
- inet_pton(AF_INET6, call->localIP, iP6Address1->network.data);
+ inet_pton(AF_INET6, pLogicalChannel->localIP, iP6Address1->network.data);
iP6Address1->network.numocts = 16;
iP6Address1->tsapIdentifier = pLogicalChannel->localRtcpPort;
} else {
@@ -1702,7 +1747,7 @@ int ooHandleOpenLogicalChannel_helper(OOH323CallData *call,
iPAddress1 = unicastAddrs1->u.iPAddress;
memset(iPAddress1, 0, sizeof(H245UnicastAddress_iPAddress));
- inet_pton(AF_INET, call->localIP, iPAddress1->network.data);
+ inet_pton(AF_INET, pLogicalChannel->localIP, iPAddress1->network.data);
iPAddress1->network.numocts = 4;
iPAddress1->tsapIdentifier = pLogicalChannel->localRtcpPort;
}
@@ -1723,7 +1768,7 @@ int ooHandleOpenLogicalChannel_helper(OOH323CallData *call,
{
epCap->startReceiveChannel(call, pLogicalChannel);
OOTRACEINFO6("Receive channel of type %s started at %s:%d(%s, %s)\n",
- ooGetCapTypeText(epCap->cap), call->localIP,
+ ooGetCapTypeText(epCap->cap), pLogicalChannel->localIP,
pLogicalChannel->localRtpPort, call->callType,
call->callToken);
}
@@ -2219,6 +2264,63 @@ int ooCloseAllLogicalChannels(OOH323CallData *call, char* dir)
return OO_OK;
}
+int ooUpdateAllLogicalChannels(OOH323CallData *call, char* localIP, int port)
+{
+ ooLogicalChannel *temp;
+ OOMediaInfo *pMediaInfo = NULL;
+ char *lIP = localIP;
+ OOBOOL eTCS = FALSE;
+
+ if (!lIP || !lIP[0]) {
+ lIP = call->localIP;
+ }
+
+/* close all log chans */
+
+ temp = call->logicalChans;
+ while (temp) {
+ if (temp->state == OO_LOGICALCHAN_ESTABLISHED) {
+ /* Sending closelogicalchannel only for outgoing channels */
+ if (!strcmp(temp->dir, "transmit")) {
+ if (call->h245SessionState != OO_H245SESSION_IDLE) {
+ ooSendCloseLogicalChannel(call, temp);
+ } else {
+ ooClearLogicalChannel(call, temp->channelNo);
+ }
+ } else if (!eTCS && call->h245SessionState != OO_H245SESSION_IDLE) {
+ ooSendEmptyTermCapMsg(call);
+ eTCS = TRUE;
+ }
+ }
+ temp = temp->next;
+ }
+
+/* change media address for all caps */
+
+ if (call->mediaInfo) {
+ pMediaInfo = call->mediaInfo;
+ while (pMediaInfo) {
+ strcpy(pMediaInfo->lMediaIP, lIP);
+ pMediaInfo->lMediaRedirPort = port;
+ pMediaInfo->lMediaRedirCPort = port + 1;
+ pMediaInfo = pMediaInfo->next;
+ }
+ }
+
+ if (call->h245SessionState == OO_H245SESSION_IDLE) {
+ if (call->fsSent) {
+ ooSendFSUpdate(call);
+ }
+ } else {
+ call->TCSPending = TRUE;
+ }
+
+/* Restart TCS exchange proc - Paul Cadah do it in chan_h323_exts native bridge code */
+/* We must do it after all log channels are closed */
+
+ return OO_OK;
+}
+
int ooSendCloseLogicalChannel(OOH323CallData *call, ooLogicalChannel *logicalChan)
{
int ret = OO_OK, error=0;
@@ -2271,17 +2373,11 @@ int ooSendCloseLogicalChannel(OOH323CallData *call, ooLogicalChannel *logicalCha
ooFreeH245Message(call, ph245msg);
/* Stop the media transmission */
- OOTRACEINFO4("Closing logical channel %d (%s, %s)\n",
- clc->forwardLogicalChannelNumber, call->callType,
- call->callToken);
- ret = ooClearLogicalChannel(call, clc->forwardLogicalChannelNumber);
- if(ret != OO_OK)
- {
- OOTRACEERR4("ERROR:Failed to close logical channel %d (%s, %s)\n",
- clc->forwardLogicalChannelNumber, call->callType, call->callToken);
- return OO_FAILED;
+ /* Moved to OnReceivedClosedChannelAck */
+ logicalChan->state = OO_LOGICALCHAN_CLOSEPENDING;
+ if (error) {
+ return OO_FAILED;
}
- if(error) return OO_FAILED;
return ret;
}
@@ -2459,17 +2555,18 @@ int ooOnReceivedRequestChannelClose(OOH323CallData *call,
ooFreeH245Message(call, ph245msg);
- /* Send Close Logical Channel*/
- ret = ooSendCloseLogicalChannel(call, lChannel);
- if(ret != OO_OK)
- {
+ /* Send Close Logical Channel if LogChan is established */
+ if (lChannel->state == OO_LOGICALCHAN_ESTABLISHED) {
+ ret = ooSendCloseLogicalChannel(call, lChannel);
+ if (ret != OO_OK) {
OOTRACEERR3("ERROR:Failed to build CloseLgicalChannel message(%s, %s)\n",
call->callType, call->callToken);
return OO_FAILED;
+ }
+ }
+ if (error) {
+ return OO_FAILED;
}
-
- if(error) return OO_FAILED;
-
return ret;
}
@@ -2677,8 +2774,7 @@ int ooOnReceivedCloseLogicalChannel(OOH323CallData *call,
clc->forwardLogicalChannelNumber, call->callType, call->callToken);
ret = ooClearLogicalChannel(call, clc->forwardLogicalChannelNumber);
- if(ret != OO_OK)
- {
+ if (ret != OO_OK) {
OOTRACEERR4("ERROR:Failed to close logical channel %d (%s, %s)\n",
clc->forwardLogicalChannelNumber, call->callType, call->callToken);
return OO_FAILED;
@@ -2728,6 +2824,16 @@ int ooOnReceivedCloseChannelAck(OOH323CallData* call,
H245CloseLogicalChannelAck* clcAck)
{
int ret = OO_OK;
+ /* Stop the media transmission */
+ OOTRACEINFO4("Closing logical channel %d (%s, %s)\n",
+ clcAck->forwardLogicalChannelNumber, call->callType,
+ call->callToken);
+ ret = ooClearLogicalChannel(call, clcAck->forwardLogicalChannelNumber);
+ if (ret != OO_OK) {
+ OOTRACEERR4("ERROR:Failed to close logical channel %d (%s, %s)\n",
+ clcAck->forwardLogicalChannelNumber, call->callType, call->callToken);
+ return OO_FAILED;
+ }
return ret;
}
@@ -2789,7 +2895,13 @@ int ooHandleH245Message(OOH323CallData *call, H245Message * pmsg)
call->callType, call->callToken);
if (ooOnReceivedCloseLogicalChannel(call,
request->u.closeLogicalChannel) == OO_OK) {
+ if (call->TCSPending && !ooGetTransmitLogicalChannel(call)) {
+ call->TCSPending = FALSE;
+ call->localTermCapState = OO_LocalTermCapExchange_Idle;
+ ooSendTermCapMsg(call);
+ } else if (!call->TCSPending) {
ooCloseAllLogicalChannels(call, NULL);
+ }
}
break;
case T_H245RequestMessage_requestChannelClose:
@@ -2979,8 +3091,13 @@ int ooHandleH245Message(OOH323CallData *call, H245Message * pmsg)
}
ooOnReceivedCloseChannelAck(call,
response->u.closeLogicalChannelAck);
- if(!ooGetTransmitLogicalChannel(call))
+ if (call->TCSPending && !ooGetReceiveLogicalChannel(call)) {
+ call->TCSPending = FALSE;
+ call->localTermCapState = OO_LocalTermCapExchange_Idle;
+ ooSendTermCapMsg(call);
+ } else if (!ooGetTransmitLogicalChannel(call)) {
ooOpenLogicalChannels(call);
+ }
break;
case T_H245ResponseMessage_requestChannelCloseAck:
OOTRACEINFO4("RequestChannelCloseAck received - %d (%s, %s)\n",
@@ -3002,8 +3119,7 @@ int ooHandleH245Message(OOH323CallData *call, H245Message * pmsg)
break;
}
}
- ooOnReceivedRequestChannelCloseAck(call,
- response->u.requestChannelCloseAck);
+ /* Do nothing by receive reqChanCloseAck */
break;
case T_H245ResponseMessage_requestChannelCloseReject:
OOTRACEINFO4("RequestChannelCloseReject received - %d (%s, %s)\n",
@@ -3110,6 +3226,7 @@ int ooOnReceivedTerminalCapabilitySet(OOH323CallData *call, H245Message *pmsg)
H245TerminalCapabilitySet *tcs=NULL;
DListNode *pNode=NULL;
H245CapabilityTableEntry *capEntry = NULL;
+ ooLogicalChannel *temp = NULL;
tcs = pmsg->h245Msg.u.request->u.terminalCapabilitySet;
if(call->remoteTermCapSeqNo > tcs->sequenceNumber)
@@ -3136,16 +3253,30 @@ int ooOnReceivedTerminalCapabilitySet(OOH323CallData *call, H245Message *pmsg)
if(call->remoteTermCapSeqNo && call->remoteTermCapSeqNo == tcs->sequenceNumber)
call->localTermCapState = OO_LocalTermCapExchange_Idle;
}
-
+/* empty tcs - renegotiate logical channels */
if(!tcs->m.capabilityTablePresent)
{
- // OOTRACEWARN3("Warn:Ignoring TCS as no capability table present(%s, %s)\n",
- OOTRACEWARN3("Empty TCS found. Pausing call...(%s, %s)\n",
+ OOTRACEDBGC3("Empty TCS found. (%s, %s)\n",
call->callType, call->callToken);
- call->h245SessionState = OO_H245SESSION_PAUSED;
- //ooSendTerminalCapabilitySetReject(call, tcs->sequenceNumber,
- // T_H245TerminalCapabilitySetReject_cause_unspecified);
- //return OO_OK;
+
+ ooH245AcknowledgeTerminalCapabilitySet(call);
+ call->remoteTermCapSeqNo = tcs->sequenceNumber;
+
+/* close all transmit chans */
+
+ temp = call->logicalChans;
+ while (temp) {
+ if (temp->state == OO_LOGICALCHAN_ESTABLISHED) {
+ /* Sending closelogicalchannel only for outgoing channels */
+ if (!strcmp(temp->dir, "transmit")) {
+ ooSendCloseLogicalChannel(call, temp);
+ }
+ }
+ temp = temp->next;
+ }
+
+ call->TCSPending = TRUE;
+ return OO_OK;
}
call->remoteTermCapSeqNo = tcs->sequenceNumber;
diff --git a/addons/ooh323c/src/ooh245.h b/addons/ooh323c/src/ooh245.h
index e8bce3fb9..a2df67056 100644
--- a/addons/ooh323c/src/ooh245.h
+++ b/addons/ooh323c/src/ooh245.h
@@ -116,6 +116,7 @@ EXTERN int ooGetOutgoingH245Msgbuf(struct OOH323CallData *call,
* @return OO_OK, on success. OO_FAILED, on failure.
*/
EXTERN int ooSendTermCapMsg(struct OOH323CallData *call);
+EXTERN int ooSendEmptyTermCapMsg(struct OOH323CallData *call);
/**
* This function is used to generate a random status determination number
@@ -290,6 +291,8 @@ EXTERN int ooOnReceivedTerminalCapabilitySetAck(struct OOH323CallData* call);
*/
EXTERN int ooCloseAllLogicalChannels(struct OOH323CallData *call, char* dir);
+EXTERN int ooUpdateAllLogicalChannels(struct OOH323CallData *call, char* localIP, int port);
+
/**
* This function is used to send out a CloseLogicalChannel message for a particular
diff --git a/addons/ooh323c/src/ooh323.c b/addons/ooh323c/src/ooh323.c
index cdf187dad..e7708af4a 100644
--- a/addons/ooh323c/src/ooh323.c
+++ b/addons/ooh323c/src/ooh323.c
@@ -104,6 +104,8 @@ int ooHandleFastStart(OOH323CallData *call, H225Facility_UUIE *facility)
call->callEndReason = OO_REASON_LOCAL_CLEARED;
call->callState = OO_CALL_CLEAR;
}
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
memset(olc, 0, sizeof(H245OpenLogicalChannel));
@@ -122,6 +124,8 @@ int ooHandleFastStart(OOH323CallData *call, H225Facility_UUIE *facility)
call->callEndReason = OO_REASON_INVALIDMESSAGE;
call->callState = OO_CALL_CLEAR;
}
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
@@ -134,6 +138,8 @@ int ooHandleFastStart(OOH323CallData *call, H225Facility_UUIE *facility)
"(%s, %s)\n",
olc->forwardLogicalChannelNumber, call->callType,
call->callToken);
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
if(pChannel->channelNo != olc->forwardLogicalChannelNumber)
@@ -165,6 +171,8 @@ int ooHandleFastStart(OOH323CallData *call, H225Facility_UUIE *facility)
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)
@@ -187,6 +195,8 @@ int ooHandleFastStart(OOH323CallData *call, H225Facility_UUIE *facility)
}
OOTRACEERR3("ERROR:Unsupported media channel address type "
"(%s, %s)\n", call->callType, call->callToken);
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
@@ -579,6 +589,8 @@ int ooOnReceivedSetup(OOH323CallData *call, Q931Message *q931Msg)
call->callEndReason = OO_REASON_LOCAL_CLEARED;
call->callState = OO_CALL_CLEAR;
}
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
memset(olc, 0, sizeof(H245OpenLogicalChannel));
@@ -598,7 +610,9 @@ int ooOnReceivedSetup(OOH323CallData *call, Q931Message *q931Msg)
call->callEndReason = OO_REASON_INVALIDMESSAGE;
call->callState = OO_CALL_CLEAR;
}
- return OO_FAILED;
+ finishPrint();
+ removeEventHandler(call->pctxt);
+ 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. */
@@ -672,6 +686,8 @@ int ooOnReceivedCallProceeding(OOH323CallData *call, Q931Message *q931Msg)
call->callEndReason = OO_REASON_LOCAL_CLEARED;
call->callState = OO_CALL_CLEAR;
}
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
memset(olc, 0, sizeof(H245OpenLogicalChannel));
@@ -690,6 +706,8 @@ int ooOnReceivedCallProceeding(OOH323CallData *call, Q931Message *q931Msg)
call->callEndReason = OO_REASON_INVALIDMESSAGE;
call->callState = OO_CALL_CLEAR;
}
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
@@ -702,6 +720,8 @@ int ooOnReceivedCallProceeding(OOH323CallData *call, Q931Message *q931Msg)
"(%s, %s)\n",
olc->forwardLogicalChannelNumber, call->callType,
call->callToken);
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
if(pChannel->channelNo != olc->forwardLogicalChannelNumber)
@@ -732,6 +752,8 @@ int ooOnReceivedCallProceeding(OOH323CallData *call, Q931Message *q931Msg)
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)
@@ -739,6 +761,8 @@ int ooOnReceivedCallProceeding(OOH323CallData *call, Q931Message *q931Msg)
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,
@@ -754,6 +778,8 @@ int ooOnReceivedCallProceeding(OOH323CallData *call, Q931Message *q931Msg)
}
OOTRACEERR3("ERROR:Unsupported media channel address type "
"(%s, %s)\n", call->callType, call->callToken);
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
@@ -762,6 +788,8 @@ int ooOnReceivedCallProceeding(OOH323CallData *call, Q931Message *q931Msg)
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);
@@ -902,6 +930,8 @@ int ooOnReceivedAlerting(OOH323CallData *call, Q931Message *q931Msg)
call->callEndReason = OO_REASON_LOCAL_CLEARED;
call->callState = OO_CALL_CLEAR;
}
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
memset(olc, 0, sizeof(H245OpenLogicalChannel));
@@ -920,6 +950,8 @@ int ooOnReceivedAlerting(OOH323CallData *call, Q931Message *q931Msg)
call->callEndReason = OO_REASON_INVALIDMESSAGE;
call->callState = OO_CALL_CLEAR;
}
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
@@ -932,6 +964,8 @@ int ooOnReceivedAlerting(OOH323CallData *call, Q931Message *q931Msg)
"(%s, %s)\n",
olc->forwardLogicalChannelNumber, call->callType,
call->callToken);
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
if(pChannel->channelNo != olc->forwardLogicalChannelNumber)
@@ -962,6 +996,8 @@ int ooOnReceivedAlerting(OOH323CallData *call, Q931Message *q931Msg)
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)
@@ -969,6 +1005,8 @@ int ooOnReceivedAlerting(OOH323CallData *call, Q931Message *q931Msg)
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,
@@ -992,6 +1030,8 @@ int ooOnReceivedAlerting(OOH323CallData *call, Q931Message *q931Msg)
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);
@@ -1139,6 +1179,8 @@ int ooOnReceivedProgress(OOH323CallData *call, Q931Message *q931Msg)
call->callEndReason = OO_REASON_LOCAL_CLEARED;
call->callState = OO_CALL_CLEAR;
}
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
memset(olc, 0, sizeof(H245OpenLogicalChannel));
@@ -1157,6 +1199,8 @@ int ooOnReceivedProgress(OOH323CallData *call, Q931Message *q931Msg)
call->callEndReason = OO_REASON_INVALIDMESSAGE;
call->callState = OO_CALL_CLEAR;
}
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
@@ -1169,6 +1213,8 @@ int ooOnReceivedProgress(OOH323CallData *call, Q931Message *q931Msg)
"(%s, %s)\n",
olc->forwardLogicalChannelNumber, call->callType,
call->callToken);
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
if(pChannel->channelNo != olc->forwardLogicalChannelNumber)
@@ -1199,6 +1245,8 @@ int ooOnReceivedProgress(OOH323CallData *call, Q931Message *q931Msg)
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)
@@ -1206,6 +1254,8 @@ int ooOnReceivedProgress(OOH323CallData *call, Q931Message *q931Msg)
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,
@@ -1221,6 +1271,8 @@ int ooOnReceivedProgress(OOH323CallData *call, Q931Message *q931Msg)
}
OOTRACEERR3("ERROR:Unsupported media channel address type "
"(%s, %s)\n", call->callType, call->callToken);
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
@@ -1229,6 +1281,8 @@ int ooOnReceivedProgress(OOH323CallData *call, Q931Message *q931Msg)
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);
@@ -1363,8 +1417,6 @@ int ooOnReceivedSignalConnect(OOH323CallData* call, Q931Message *q931Msg)
{
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);
}
}
@@ -1686,11 +1738,12 @@ int ooHandleH2250Message(OOH323CallData *call, Q931Message *q931Msg)
}
}
if (call->callState < OO_CALL_CLEAR) {
- ooSendCallProceeding(call);/* Send call proceeding message*/
- ret = ooH323CallAdmitted (call);
+ ooHandleFastStartChannels(call);
+ ooSendCallProceeding(call);/* Send call proceeding message*/
+ ret = ooH323CallAdmitted (call);
+ call->callState = OO_CALL_CONNECTING;
}
- call->callState = OO_CALL_CONNECTING;
} /* end ret == OO_OK */
break;
diff --git a/addons/ooh323c/src/ooh323ep.c b/addons/ooh323c/src/ooh323ep.c
index 1d5d9579e..868d31af2 100644
--- a/addons/ooh323c/src/ooh323ep.c
+++ b/addons/ooh323c/src/ooh323ep.c
@@ -346,6 +346,7 @@ int ooH323EpSetH323Callbacks(OOH323CALLBACKS h323Callbacks)
gH323ep.h323Callbacks.openLogicalChannels = h323Callbacks.openLogicalChannels;
gH323ep.h323Callbacks.onReceivedDTMF = h323Callbacks.onReceivedDTMF;
gH323ep.h323Callbacks.onModeChanged = h323Callbacks.onModeChanged;
+ gH323ep.h323Callbacks.onMediaChanged = h323Callbacks.onMediaChanged;
return OO_OK;
}
diff --git a/addons/ooh323c/src/ooq931.c b/addons/ooh323c/src/ooq931.c
index d4cfb6544..d67299d96 100644
--- a/addons/ooh323c/src/ooq931.c
+++ b/addons/ooh323c/src/ooq931.c
@@ -871,6 +871,112 @@ int ooEncodeH225Message(OOH323CallData *call, Q931Message *pq931Msg,
return OO_OK;
}
+/* Handle FS receive channels for early media */
+
+int ooHandleFastStartChannels(OOH323CallData *pCall)
+{
+ int i = 0, j = 0, remoteMediaControlPort = 0, dir = 0;
+ char remoteMediaControlIP[2 + 8 * 4 + 7];
+ DListNode *pNode = NULL;
+ H245OpenLogicalChannel *olc = NULL;
+ ooH323EpCapability *epCap = NULL;
+ H245H2250LogicalChannelParameters *h2250lcp = NULL;
+
+
+ /* If fast start supported and remote endpoint has sent faststart element */
+ if (OO_TESTFLAG(pCall->flags, OO_M_FASTSTART) &&
+ pCall->remoteFastStartOLCs.count>0) {
+
+ /* Go though all the proposed channels */
+
+ for (i = 0, j = 0; i < (int)pCall->remoteFastStartOLCs.count; i++) {
+
+ pNode = dListFindByIndex(&pCall->remoteFastStartOLCs, i);
+ olc = (H245OpenLogicalChannel*)pNode->data;
+
+ /* Don't support both direction channel */
+ if (olc->forwardLogicalChannelParameters.dataType.t !=
+ T_H245DataType_nullData &&
+ olc->m.reverseLogicalChannelParametersPresent) {
+ continue;
+ }
+
+ /* Check forward logic channel */
+ if (olc->forwardLogicalChannelParameters.dataType.t !=
+ T_H245DataType_nullData) {
+ /* Forward Channel - remote transmits - local receives */
+ OOTRACEDBGC4("Processing received forward olc %d (%s, %s)\n",
+ olc->forwardLogicalChannelNumber, pCall->callType,
+ pCall->callToken);
+ dir = OORX;
+ epCap = ooIsDataTypeSupported(pCall,
+ &olc->forwardLogicalChannelParameters.dataType,
+ OORX);
+
+ if (!epCap) {
+ continue; /* Not Supported Channel */
+ }
+
+ OOTRACEINFO1("Receive Channel data type supported\n");
+ if (olc->forwardLogicalChannelParameters.multiplexParameters.t !=
+ T_H245OpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters_h2250LogicalChannelParameters) {
+ OOTRACEERR4("ERROR:Unknown multiplex parameter type for "
+ "channel %d (%s, %s)\n",
+ olc->forwardLogicalChannelNumber,
+ pCall->callType, pCall->callToken);
+ memFreePtr(pCall->pctxt, epCap);
+ epCap = NULL;
+ continue;
+ }
+ h2250lcp = olc->forwardLogicalChannelParameters.multiplexParameters.u.h2250LogicalChannelParameters;
+
+ /* Check session is Not already established */
+ if (ooIsSessionEstablished(pCall, olc->forwardLogicalChannelParameters.multiplexParameters.u.h2250LogicalChannelParameters->sessionID, "receive")) {
+
+ OOTRACEINFO4("Receive channel with sessionID %d already "
+ "established.(%s, %s)\n", olc->forwardLogicalChannelParameters.multiplexParameters.u.h2250LogicalChannelParameters->sessionID,
+ pCall->callType, pCall->callToken);
+ memFreePtr(pCall->pctxt, epCap);
+ epCap = NULL;
+ continue;
+ }
+
+ /* Extract mediaControlChannel info, if supplied */
+ if (h2250lcp->m.mediaControlChannelPresent) {
+ if (OO_OK != ooGetIpPortFromH245TransportAddress(pCall,
+ &h2250lcp->mediaControlChannel,
+ remoteMediaControlIP, &remoteMediaControlPort)) {
+ OOTRACEERR3("Error: Invalid media control channel address "
+ "(%s, %s)\n", pCall->callType, pCall->callToken);
+ memFreePtr(pCall->pctxt, epCap);
+ epCap = NULL;
+ continue;
+ }
+ } else {
+ continue;
+ }
+ } else {
+ /* Don't check reverse channels */
+ continue;
+ }
+
+ if (dir & OORX) {
+ remoteMediaControlPort--;
+ if (gH323ep.h323Callbacks.onMediaChanged &&
+ pCall->callState < OO_CALL_CLEAR) {
+ gH323ep.h323Callbacks.onMediaChanged(pCall, remoteMediaControlIP,
+ remoteMediaControlPort);
+ }
+ }
+
+
+ }
+
+ }
+ return ASN_OK;
+}
+
+
int ooSetFastStartResponse(OOH323CallData *pCall, Q931Message *pQ931msg,
ASN1UINT *fsCount, ASN1DynOctStr **fsElem)
{
@@ -1648,6 +1754,85 @@ int ooSendProgress(OOH323CallData *call)
}
+int ooSendFSUpdate(OOH323CallData *call)
+{
+ int ret = 0;
+ Q931Message *pQ931Msg = NULL;
+ H225Facility_UUIE *facility = NULL;
+ OOCTXT *pctxt = call->msgctxt;
+
+ OOTRACEDBGA3("Building FS update message (%s, %s)\n", call->callType,
+ call->callToken);
+ ret = ooCreateQ931Message(pctxt, &pQ931Msg, Q931FacilityMsg);
+ if (ret != OO_OK) {
+ OOTRACEERR3("ERROR: In allocating memory for facility message (%s, %s)\n",
+ call->callType, call->callToken);
+ return OO_FAILED;
+ }
+
+ pQ931Msg->callReference = call->callReference;
+
+ pQ931Msg->userInfo = (H225H323_UserInformation*)memAlloc(pctxt,
+ sizeof(H225H323_UserInformation));
+ if (!pQ931Msg->userInfo) {
+ OOTRACEERR3("ERROR:Memory - ooSendFSUpdate - userInfo(%s, %s)\n",
+ call->callType, call->callToken);
+ return OO_FAILED;
+ }
+ memset(pQ931Msg->userInfo, 0, sizeof(H225H323_UserInformation));
+ pQ931Msg->userInfo->h323_uu_pdu.m.h245TunnelingPresent = 1;
+
+ pQ931Msg->userInfo->h323_uu_pdu.h245Tunneling =
+ OO_TESTFLAG (call->flags, OO_M_TUNNELING);
+
+ pQ931Msg->userInfo->h323_uu_pdu.h323_message_body.t =
+ T_H225H323_UU_PDU_h323_message_body_facility;
+
+ facility = (H225Facility_UUIE*)
+ memAllocZ (pctxt, sizeof(H225Facility_UUIE));
+
+ if (!facility) {
+ OOTRACEERR3("ERROR:Memory - ooSendFS Update - facility (%s, %s)\n",
+ call->callType, call->callToken);
+ return OO_FAILED;
+ }
+
+ pQ931Msg->userInfo->h323_uu_pdu.h323_message_body.u.facility = facility;
+
+ /* Populate Facility UUIE */
+ facility->protocolIdentifier = gProtocolID;
+ facility->m.callIdentifierPresent = 1;
+ facility->callIdentifier.guid.numocts =
+ call->callIdentifier.guid.numocts;
+ memcpy(facility->callIdentifier.guid.data,
+ call->callIdentifier.guid.data,
+ call->callIdentifier.guid.numocts);
+ facility->reason.t = T_H225FacilityReason_forwardedElements;
+
+ ret = ooSetFastStartResponse(call, pQ931Msg,
+ &facility->fastStart.n, &facility->fastStart.elem);
+ if (ret != ASN_OK) {
+ return ret;
+ }
+ if (facility->fastStart.n > 0) {
+ facility->m.fastStartPresent = TRUE;
+ call->fsSent = TRUE;
+ } else {
+ facility->m.fastStartPresent = FALSE;
+ }
+
+ OOTRACEDBGA3("Built Facility message to send (%s, %s)\n", call->callType,
+ call->callToken);
+
+ ret = ooSendH225Msg(call, pQ931Msg);
+ if (ret != OO_OK) {
+ OOTRACEERR3("Error:Failed to enqueue Facility message to outbound "
+ "queue.(%s, %s)\n", call->callType, call->callToken);
+ }
+ memReset(call->msgctxt);
+ return ret;
+}
+
int ooSendStartH245Facility(OOH323CallData *call)
{
int ret=0;
diff --git a/addons/ooh323c/src/ooq931.h b/addons/ooh323c/src/ooq931.h
index 047c7959e..8da389328 100644
--- a/addons/ooh323c/src/ooq931.h
+++ b/addons/ooh323c/src/ooq931.h
@@ -772,6 +772,8 @@ EXTERN char* ooQ931GetMessageTypeName(int messageType, char* buf);
EXTERN char* ooQ931GetIEName(int number, char* buf);
EXTERN int ooSendTCSandMSD(struct OOH323CallData *call);
EXTERN int ooSendStartH245Facility(struct OOH323CallData *call);
+EXTERN int ooSendFSUpdate(struct OOH323CallData *call);
+EXTERN int ooHandleFastStartChannels(struct OOH323CallData *pCall);
/**
* @}