--- ../../asterisk-addons-1.6.1.0/channels/chan_ooh323.c 2009-06-15 00:26:49.000000000 +0400 +++ channels/chan_ooh323.c 2009-06-17 18:44:42.000000000 +0400 @@ -204,6 +204,7 @@ /* stack callbacks */ int onAlerting(ooCallData *call); +int onProgress(ooCallData *call); int onNewCallCreated(ooCallData *call); int onCallEstablished(ooCallData *call); int onCallCleared(ooCallData *call); @@ -222,6 +223,7 @@ static int gIsGateway = 0; static int gFastStart = 1; static int gTunneling = 1; +static int gBeMaster = 0; static int gMediaWaitForConnect = 0; static int gTOS = 0; static int gRTPTimeout = 60; @@ -1268,7 +1270,9 @@ return 0; } c = p->owner; - ast_setstate(c, AST_STATE_RINGING); + if (c->_state != AST_STATE_UP) + ast_setstate(c, AST_STATE_RINGING); + ast_queue_control(c, AST_CONTROL_RINGING); ast_channel_unlock(c); ast_mutex_unlock(&p->lock); @@ -1279,6 +1283,51 @@ return OO_OK; } +int onProgress(ooCallData *call) +{ + struct ooh323_pvt *p = NULL; + struct ast_channel *c = NULL; + + if (gH323Debug) + ast_verbose("--- onProgress %s\n", call->callToken); + + p = find_call(call); + + if(!p) { + ast_log(LOG_ERROR, "No matching call found\n"); + return -1; + } + ast_mutex_lock(&p->lock); + if (!p->owner) { + ast_mutex_unlock(&p->lock); + ast_log(LOG_ERROR, "Channel has no owner\n"); + return 0; + } + while (p->owner && ast_channel_trylock(p->owner)) { + ast_debug(1,"Failed to grab lock, trying again\n"); + ast_mutex_unlock(&p->lock); + usleep(1); + ast_mutex_lock(&p->lock); + } + if (!p->owner) { + ast_mutex_unlock(&p->lock); + ast_log(LOG_ERROR, "Channel has no owner\n"); + return 0; + } + c = p->owner; + if (c->_state != AST_STATE_UP) + ast_setstate(c, AST_STATE_RINGING); + + ast_queue_control(c, AST_CONTROL_PROGRESS); + ast_channel_unlock(c); + ast_mutex_unlock(&p->lock); + + if (gH323Debug) + ast_verbose("+++ onProgress %s\n", call->callToken); + + return OO_OK; +} + /** * Callback for sending digits from H.323 up to asterisk * @@ -2057,6 +2106,12 @@ ooH323EpEnableH245Tunneling(); else ooH323EpDisableH245Tunneling(); + } else if (!strcasecmp(v->name, "trybemaster")) { + gBeMaster = ast_true(v->value); + if (gBeMaster) + ooH323EpTryBeMaster(1); + else + ooH323EpTryBeMaster(0); } else if (!strcasecmp(v->name, "h323id")) { pNewAlias = malloc(sizeof(struct ooAliases)); if (!pNewAlias) { @@ -2607,6 +2662,7 @@ OOH323CALLBACKS h323Callbacks = { .onNewCallCreated = onNewCallCreated, .onAlerting = onAlerting, + .onProgress = onProgress, .onIncomingCall = NULL, .onOutgoingCall = NULL, .onCallEstablished = onCallEstablished, @@ -2718,7 +2774,10 @@ if (!gTunneling) ooH323EpDisableH245Tunneling(); - ooH323EpEnableManualRingback(); + if (gBeMaster) + ooH323EpTryBeMaster(1); + + ooH323EpEnableManualRingback(); /* Gatekeeper */ if (gRasGkMode == RasUseSpecificGatekeeper) @@ -3406,6 +3465,9 @@ ast_set_read_format(p->owner, p->owner->readformat); ast_set_write_format(p->owner, p->owner->writeformat); } + if (!p->owner->readformat) + p->owner->readformat = p->owner->nativeformats; + if ((p->dtmfmode & H323_DTMF_INBAND) && p->vad) { f = ast_dsp_process(p->owner, p->vad, f); if (f && (f->frametype == AST_FRAME_DTMF)) --- ../../asterisk-addons-1.6.1.0/channels/ooh323c/src/ooh323ep.c 2009-06-15 00:26:49.000000000 +0400 +++ channels/ooh323c/src/ooh323ep.c 2009-06-17 18:50:28.000000000 +0400 @@ -337,6 +337,7 @@ { gH323ep.h323Callbacks.onNewCallCreated = h323Callbacks.onNewCallCreated; gH323ep.h323Callbacks.onAlerting = h323Callbacks.onAlerting; + gH323ep.h323Callbacks.onProgress = h323Callbacks.onProgress; gH323ep.h323Callbacks.onIncomingCall = h323Callbacks.onIncomingCall; gH323ep.h323Callbacks.onOutgoingCall = h323Callbacks.onOutgoingCall; gH323ep.h323Callbacks.onCallEstablished = h323Callbacks.onCallEstablished; @@ -465,6 +466,15 @@ return OO_OK; } +int ooH323EpTryBeMaster(int m) +{ + if (m) + OO_SETFLAG(gH323ep.flags, OO_M_TRYBEMASTER); + else + OO_CLRFLAG(gH323ep.flags, OO_M_TRYBEMASTER); + return OO_OK; +} + int ooH323EpSetTermType(int value) { gH323ep.termType = value; --- ../../asterisk-addons-1.6.1.0/channels/ooh323c/src/ooh323.c 2009-05-31 00:22:42.000000000 +0400 +++ channels/ooh323c/src/ooh323.c 2009-06-17 00:57:20.000000000 +0400 @@ -764,6 +764,202 @@ } return OO_OK; } + +int ooOnReceivedProgress(OOH323CallData *call, Q931Message *q931Msg) +{ + H225Progress_UUIE *progress=NULL; + H245OpenLogicalChannel* olc; + ASN1OCTET msgbuf[MAXMSGLEN]; + ooLogicalChannel * pChannel = NULL; + H245H2250LogicalChannelParameters * h2250lcp = NULL; + int i=0, ret=0; + + + if(!q931Msg->userInfo) + { + OOTRACEERR3("ERROR:No User-User IE in received Progress message." + " (%s, %s)\n", call->callType, call->callToken); + return OO_FAILED; + } + progress = q931Msg->userInfo->h323_uu_pdu.h323_message_body.u.progress; + if(progress == NULL) + { + OOTRACEERR3("Error: Received Progress message does not have " + "progress UUIE (%s, %s)\n", call->callType, + call->callToken); + /* Mark call for clearing */ + if(call->callState < OO_CALL_CLEAR) + { + call->callEndReason = OO_REASON_INVALIDMESSAGE; + call->callState = OO_CALL_CLEAR; + } + return OO_FAILED; + } + /*Handle fast-start */ + if(OO_TESTFLAG (call->flags, OO_M_FASTSTART) && + !OO_TESTFLAG(call->flags, OO_M_FASTSTARTANSWERED)) + { + if(progress->m.fastStartPresent) + { + /* For printing the decoded message to log, initialize handler. */ + initializePrintHandler(&printHandler, "FastStart Elements"); + + /* Set print handler */ + setEventHandler (call->pctxt, &printHandler); + + for(i=0; i<(int)progress->fastStart.n; i++) + { + olc = NULL; + + olc = (H245OpenLogicalChannel*)memAlloc(call->pctxt, + sizeof(H245OpenLogicalChannel)); + if(!olc) + { + OOTRACEERR3("ERROR:Memory - ooOnReceivedProgress - olc" + "(%s, %s)\n", call->callType, call->callToken); + /*Mark call for clearing */ + if(call->callState < OO_CALL_CLEAR) + { + call->callEndReason = OO_REASON_LOCAL_CLEARED; + call->callState = OO_CALL_CLEAR; + } + return OO_FAILED; + } + memset(olc, 0, sizeof(H245OpenLogicalChannel)); + memcpy(msgbuf, progress->fastStart.elem[i].data, + progress->fastStart.elem[i].numocts); + setPERBuffer(call->pctxt, msgbuf, + progress->fastStart.elem[i].numocts, 1); + ret = asn1PD_H245OpenLogicalChannel(call->pctxt, olc); + if(ret != ASN_OK) + { + OOTRACEERR3("ERROR:Failed to decode fast start olc element " + "(%s, %s)\n", call->callType, call->callToken); + /* Mark call for clearing */ + if(call->callState < OO_CALL_CLEAR) + { + call->callEndReason = OO_REASON_INVALIDMESSAGE; + call->callState = OO_CALL_CLEAR; + } + return OO_FAILED; + } + + dListAppend(call->pctxt, &call->remoteFastStartOLCs, olc); + + pChannel = ooFindLogicalChannelByOLC(call, olc); + if(!pChannel) + { + OOTRACEERR4("ERROR: Logical Channel %d not found, fast start. " + "(%s, %s)\n", + olc->forwardLogicalChannelNumber, call->callType, + call->callToken); + return OO_FAILED; + } + if(pChannel->channelNo != olc->forwardLogicalChannelNumber) + { + OOTRACEINFO5("Remote endpoint changed forwardLogicalChannel" + "Number from %d to %d (%s, %s)\n", + pChannel->channelNo, + olc->forwardLogicalChannelNumber, call->callType, + call->callToken); + pChannel->channelNo = olc->forwardLogicalChannelNumber; + } + if(!strcmp(pChannel->dir, "transmit")) + { + if(olc->forwardLogicalChannelParameters.multiplexParameters.t != + T_H245OpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters_h2250LogicalChannelParameters) + { + OOTRACEERR4("ERROR:Unknown multiplex parameter type for " + "channel %d (%s, %s)\n", + olc->forwardLogicalChannelNumber, call->callType, + call->callToken); + continue; + } + + /* Extract the remote media endpoint address */ + h2250lcp = olc->forwardLogicalChannelParameters.multiplexParameters.u.h2250LogicalChannelParameters; + if(!h2250lcp) + { + OOTRACEERR3("ERROR:Invalid OLC received in fast start. No " + "forward Logical Channel Parameters found. " + "(%s, %s)\n", call->callType, call->callToken); + return OO_FAILED; + } + if(!h2250lcp->m.mediaChannelPresent) + { + OOTRACEERR3("ERROR:Invalid OLC received in fast start. No " + "reverse media channel information found." + "(%s, %s)\n", call->callType, call->callToken); + return OO_FAILED; + } + ret = ooGetIpPortFromH245TransportAddress(call, + &h2250lcp->mediaChannel, pChannel->remoteIP, + &pChannel->remoteMediaPort); + + if(ret != OO_OK) + { + OOTRACEERR3("ERROR:Unsupported media channel address type " + "(%s, %s)\n", call->callType, call->callToken); + return OO_FAILED; + } + + if(!pChannel->chanCap->startTransmitChannel) + { + OOTRACEERR3("ERROR:No callback registered to start transmit " + "channel (%s, %s)\n",call->callType, + call->callToken); + return OO_FAILED; + } + pChannel->chanCap->startTransmitChannel(call, pChannel); + } + /* Mark the current channel as established and close all other + logical channels with same session id and in same direction. + */ + ooOnLogicalChannelEstablished(call, pChannel); + } + finishPrint(); + removeEventHandler(call->pctxt); + OO_SETFLAG(call->flags, OO_M_FASTSTARTANSWERED); + } + + } + + /* Retrieve the H.245 control channel address from the connect msg */ + if(q931Msg->userInfo->h323_uu_pdu.m.h245TunnelingPresent && + q931Msg->userInfo->h323_uu_pdu.h245Tunneling && + progress->m.h245AddressPresent) { + OOTRACEINFO3("Tunneling and h245address provided." + "Giving preference to Tunneling (%s, %s)\n", + call->callType, call->callToken); + } + else if(progress->m.h245AddressPresent) + { + if (OO_TESTFLAG (call->flags, OO_M_TUNNELING)) + { + OO_CLRFLAG (call->flags, OO_M_TUNNELING); + OOTRACEINFO3("Tunneling is disabled for call as H245 address is " + "provided in Progress message (%s, %s)\n", + call->callType, call->callToken); + } + ret = ooH323GetIpPortFromH225TransportAddress(call, + &progress->h245Address, call->remoteIP, + &call->remoteH245Port); + if(ret != OO_OK) + { + OOTRACEERR3("Error: Unknown H245 address type in received " + "Progress message (%s, %s)", call->callType, + call->callToken); + /* Mark call for clearing */ + if(call->callState < OO_CALL_CLEAR) + { + call->callEndReason = OO_REASON_INVALIDMESSAGE; + call->callState = OO_CALL_CLEAR; + } + return OO_FAILED; + } + } + return OO_OK; +} int ooOnReceivedSignalConnect(OOH323CallData* call, Q931Message *q931Msg) @@ -1127,6 +1323,18 @@ break; + case Q931ProgressMsg:/* PROGRESS message received */ + OOTRACEINFO3("H.225 Progress message received (%s, %s)\n", + call->callType, call->callToken); + + ooOnReceivedProgress(call, q931Msg); + + if(gH323ep.h323Callbacks.onProgress && call->callStatemsgctxt, q931Msg); + break; + + case Q931ConnectMsg:/* CONNECT message received */ OOTRACEINFO3("H.225 Connect message received (%s, %s)\n", call->callType, call->callToken); @@ -1182,11 +1390,6 @@ ooOnReceivedFacility(call, q931Msg); ooFreeQ931Message(call->msgctxt, q931Msg); break; - case Q931ProgressMsg: - OOTRACEINFO3("H.225 Progress message received (%s, %s)\n", - call->callType, call->callToken); - ooFreeQ931Message(call->msgctxt, q931Msg); - break; case Q931StatusMsg: OOTRACEINFO3("H.225 Status message received (%s, %s)\n", call->callType, call->callToken); --- ../../asterisk-addons-1.6.1.0/channels/ooh323c/src/ooCalls.h 2009-05-30 06:40:48.000000000 +0400 +++ channels/ooh323c/src/ooCalls.h 2009-06-17 18:48:41.000000000 +0400 @@ -54,6 +54,7 @@ #define OO_M_DISABLEGK ASN1UINTCNT(0x01000000) #define OO_M_MANUALRINGBACK ASN1UINTCNT(0x10000000) +#define OO_M_TRYBEMASTER ASN1UINTCNT(0x00000010) /** * Call states. @@ -295,6 +296,7 @@ typedef struct OOH323CALLBACKS { cb_OnAlerting onNewCallCreated; cb_OnAlerting onAlerting; + cb_OnAlerting onProgress; cb_OnIncomingCall onIncomingCall; cb_OnOutgoingCall onOutgoingCall; cb_OnCallEstablished onCallEstablished; --- ../../asterisk-addons-1.6.1.0/channels/ooh323c/src/ooh245.c 2009-06-16 15:46:37.000000000 +0400 +++ channels/ooh323c/src/ooh245.c 2009-06-17 19:07:57.000000000 +0400 @@ -702,7 +702,7 @@ { H245MasterSlaveDetermination *masterSlave; H245MasterSlaveDeterminationAck *masterSlaveAck; - ASN1UINT statusDeterminationNumber; + ASN1UINT statusDeterminationNumber, moduloDiff; switch(msgType) { @@ -711,7 +711,16 @@ call->callType, call->callToken); masterSlave = (H245MasterSlaveDetermination*)pmsg; - + + if(call->masterSlaveState != OO_MasterSlave_DetermineSent && + OO_TESTFLAG(gH323ep.flags, OO_M_TRYBEMASTER)) + { + ooSendMasterSlaveDeterminationAck(call, "slave"); + call->masterSlaveState = OO_MasterSlave_Master; + OOTRACEINFO3("MasterSlaveDetermination done - Master(%s, %s)\n", + call->callType, call->callToken); + return OO_OK; + } if(masterSlave->terminalType < gH323ep.termType) { ooSendMasterSlaveDeterminationAck(call, "slave"); @@ -737,10 +746,17 @@ if(call->masterSlaveState == OO_MasterSlave_DetermineSent) statusDeterminationNumber = call->statusDeterminationNumber; else - statusDeterminationNumber = ooGenerateStatusDeterminationNumber(); + if (OO_TESTFLAG(gH323ep.flags, OO_M_TRYBEMASTER)) + statusDeterminationNumber = masterSlave->statusDeterminationNumber - 1; + else + statusDeterminationNumber = ooGenerateStatusDeterminationNumber(); + + moduloDiff = (masterSlave->statusDeterminationNumber - statusDeterminationNumber) + &0xffffff; - if(masterSlave->statusDeterminationNumber > - statusDeterminationNumber) + /* if(masterSlave->statusDeterminationNumber > + statusDeterminationNumber) */ + if (moduloDiff < 0x800000 && moduloDiff != 0) { ooSendMasterSlaveDeterminationAck(call, "slave"); call->masterSlaveState = OO_MasterSlave_Master; @@ -748,8 +764,9 @@ call->callType, call->callToken); return OO_OK; } - if(masterSlave->statusDeterminationNumber < - statusDeterminationNumber) + /* if(masterSlave->statusDeterminationNumber < + statusDeterminationNumber) */ + if (moduloDiff > 0x800000) { ooSendMasterSlaveDeterminationAck(call, "master"); call->masterSlaveState = OO_MasterSlave_Slave; @@ -757,8 +774,9 @@ call->callType, call->callToken); return OO_OK; } - if(masterSlave->statusDeterminationNumber == - statusDeterminationNumber) + /* if(masterSlave->statusDeterminationNumber == + statusDeterminationNumber) */ + if (moduloDiff == 0 || moduloDiff == 0x800000) { ooSendMasterSlaveDeterminationReject (call); --- ../../asterisk-addons-1.6.1.0/channels/ooh323c/src/ooh323ep.h 2009-05-30 06:40:48.000000000 +0400 +++ channels/ooh323c/src/ooh323ep.h 2009-06-17 18:46:00.000000000 +0400 @@ -381,6 +381,13 @@ EXTERN int ooH323EpDisableH245Tunneling(void); /** + * This function is used to setup/clear TryBeMaster flag + * + * @return OO_OK, on success. OO_FAILED, on failure. + */ +EXTERN int ooH323EpTryBeMaster(int); + +/** * This function is used to enable GkRouted calls. * * @return OO_OK, on success. OO_FAILED, on failure.