diff options
Diffstat (limited to 'addons/ooh323c')
-rw-r--r-- | addons/ooh323c/src/ooCalls.h | 7 | ||||
-rw-r--r-- | addons/ooh323c/src/ooCmdChannel.c | 20 | ||||
-rw-r--r-- | addons/ooh323c/src/ooLogChan.c | 29 | ||||
-rw-r--r-- | addons/ooh323c/src/ooLogChan.h | 4 | ||||
-rw-r--r-- | addons/ooh323c/src/ooStackCmds.c | 63 | ||||
-rw-r--r-- | addons/ooh323c/src/ooStackCmds.h | 4 | ||||
-rw-r--r-- | addons/ooh323c/src/ooh245.c | 199 | ||||
-rw-r--r-- | addons/ooh323c/src/ooh245.h | 3 | ||||
-rw-r--r-- | addons/ooh323c/src/ooh323.c | 65 | ||||
-rw-r--r-- | addons/ooh323c/src/ooh323ep.c | 1 | ||||
-rw-r--r-- | addons/ooh323c/src/ooq931.c | 185 | ||||
-rw-r--r-- | addons/ooh323c/src/ooq931.h | 2 |
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); /** * @} |