summaryrefslogtreecommitdiff
path: root/addons/ooh323c
diff options
context:
space:
mode:
Diffstat (limited to 'addons/ooh323c')
-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);
/**
* @}