Corrections for properly work with H.323v2 (older) endpoints and other

small fixes.

Interpret remote side H.225 version.

Corrections for H.323v2 endpoints: 
don't start TCS and MSD before connect,
don't start TCS and MSD by accepting H.245 connection,
start TCS and MSD by StartH245 facility message.

Other fixes:
fix non zeroended remoteDisplayName issue, small fixes in call clearing
by closing H.245 connection, tcp keepalive introduced on TCP
connections (now is hardcoded, will be configurable in the future), 
don't force H.245tunneling if FastStart is active, don't send Alerting 
singal more than once per call.

(closes issue #18542)
Reported by: vmikhelson
Patches: 
      issue18542-final-3.patch uploaded by may213 (license 454)
Tested by: vmikhelson


git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@307396 65c4cc65-6c06-0410-ace0-fbb531ad65f3
10-digiumphones
Alexandr Anikin 15 years ago
parent 8f7982f280
commit 707cf78c5a

@ -183,6 +183,7 @@ static struct ooh323_pvt {
int nat; int nat;
int amaflags; int amaflags;
int progsent; /* progress is sent */ int progsent; /* progress is sent */
int alertsent; /* alerting is sent */
struct ast_dsp *vad; struct ast_dsp *vad;
struct OOH323Regex *rtpmask; /* rtp ip regexp */ struct OOH323Regex *rtpmask; /* rtp ip regexp */
char rtpmaskstr[120]; char rtpmaskstr[120];
@ -1236,6 +1237,7 @@ static int ooh323_indicate(struct ast_channel *ast, int condition, const void *d
break; break;
case AST_CONTROL_RINGING: case AST_CONTROL_RINGING:
if (ast->_state == AST_STATE_RING || ast->_state == AST_STATE_RINGING) { if (ast->_state == AST_STATE_RING || ast->_state == AST_STATE_RINGING) {
if (!p->alertsent) {
if (gH323Debug) { if (gH323Debug) {
ast_debug(1, "Sending manual ringback for %s, res = %d\n", ast_debug(1, "Sending manual ringback for %s, res = %d\n",
callToken, callToken,
@ -1243,6 +1245,7 @@ static int ooh323_indicate(struct ast_channel *ast, int condition, const void *d
} else { } else {
ooManualRingback(callToken); ooManualRingback(callToken);
} }
p->alertsent = 1;
} }
break; break;
case AST_CONTROL_SRCUPDATE: case AST_CONTROL_SRCUPDATE:

@ -172,6 +172,7 @@ typedef struct OOH323CallData {
OOCallState callState; OOCallState callState;
OOCallClearReason callEndReason; OOCallClearReason callEndReason;
int q931cause; int q931cause;
ASN1UINT h225version;
unsigned h245ConnectionAttempts; unsigned h245ConnectionAttempts;
OOH245SessionState h245SessionState; OOH245SessionState h245SessionState;
int dtmfmode; int dtmfmode;

@ -191,7 +191,7 @@ typedef socklen_t OOSOCKLEN;
int ooSocketCreate (OOSOCKET* psocket) int ooSocketCreate (OOSOCKET* psocket)
{ {
int on; int on;
int keepalive = 1, keepcnt = 24, keepidle = 120, keepintvl = 30;
struct linger linger; struct linger linger;
OOSOCKET sock = socket (AF_INET, OOSOCKET sock = socket (AF_INET,
SOCK_STREAM, SOCK_STREAM,
@ -217,6 +217,11 @@ int ooSocketCreate (OOSOCKET* psocket)
OOTRACEERR1("Error:Failed to set socket option linger\n"); OOTRACEERR1("Error:Failed to set socket option linger\n");
return ASN_E_INVSOCKET; return ASN_E_INVSOCKET;
} }
setsockopt (sock, SOL_SOCKET, SO_KEEPALIVE, (const char *)&keepalive,
sizeof(keepalive));
setsockopt (sock, SOL_TCP, TCP_KEEPCNT, &keepcnt, sizeof(keepcnt));
setsockopt (sock, SOL_TCP, TCP_KEEPIDLE, &keepidle, sizeof(keepidle));
setsockopt (sock, SOL_TCP, TCP_KEEPINTVL, &keepintvl, sizeof(keepintvl));
*psocket = sock; *psocket = sock;
return ASN_OK; return ASN_OK;
} }

@ -261,6 +261,9 @@ OOStkCmdStat ooManualProgress(const char *callToken)
return OO_STKCMD_CONNECTIONERR; return OO_STKCMD_CONNECTIONERR;
} }
if (call->h225version < 4)
return OO_STKCMD_SUCCESS;
memset(&cmd, 0, sizeof(OOStackCommand)); memset(&cmd, 0, sizeof(OOStackCommand));
cmd.type = OO_CMD_MANUALPROGRESS; cmd.type = OO_CMD_MANUALPROGRESS;
cmd.param1 = (void*) malloc(strlen(callToken)+1); cmd.param1 = (void*) malloc(strlen(callToken)+1);

@ -473,15 +473,6 @@ int ooAcceptH245Connection(OOH323CallData *call)
OOTRACEINFO3("H.245 connection established (%s, %s)\n", OOTRACEINFO3("H.245 connection established (%s, %s)\n",
call->callType, call->callToken); call->callType, call->callToken);
/* Start terminal capability exchange and master slave determination */
ret = ooSendTermCapMsg(call);
if(ret != OO_OK)
{
OOTRACEERR3("ERROR:Sending Terminal capability message (%s, %s)\n",
call->callType, call->callToken);
return ret;
}
return OO_OK; return OO_OK;
} }
@ -1835,6 +1826,8 @@ int ooOnSendMsg
} }
else{ else{
ooCloseH245Connection(call); ooCloseH245Connection(call);
if(call->callState < OO_CALL_CLEAR)
call->callState = OO_CALL_CLEAR;
} }
break; break;
case OOCloseLogicalChannel: case OOCloseLogicalChannel:

@ -2060,14 +2060,12 @@ int ooHandleH245Command(OOH323CallData *call,
} }
} }
ooCloseH245Connection(call); ooCloseH245Connection(call);
if (call->callState < OO_CALL_CLEAR)
call->callState = OO_CALL_CLEAR;
} }
else{ else{
call->h245SessionState = OO_H245SESSION_ENDRECVD; call->h245SessionState = OO_H245SESSION_ENDRECVD;
#if 0
if(call->callState < OO_CALL_CLEAR)
call->callState = OO_CALL_CLEAR;
#else
if(call->logicalChans) if(call->logicalChans)
{ {
OOTRACEINFO3("In response to received EndSessionCommand - " OOTRACEINFO3("In response to received EndSessionCommand - "
@ -2076,7 +2074,6 @@ int ooHandleH245Command(OOH323CallData *call,
ooClearAllLogicalChannels(call); ooClearAllLogicalChannels(call);
} }
ooSendEndSessionCommand(call); ooSendEndSessionCommand(call);
#endif
} }

@ -40,6 +40,7 @@ int ooOnReceivedCallProceeding(OOH323CallData *call, Q931Message *q931Msg);
int ooOnReceivedAlerting(OOH323CallData *call, Q931Message *q931Msg); int ooOnReceivedAlerting(OOH323CallData *call, Q931Message *q931Msg);
int ooOnReceivedProgress(OOH323CallData *call, Q931Message *q931Msg); int ooOnReceivedProgress(OOH323CallData *call, Q931Message *q931Msg);
int ooHandleDisplayIE(OOH323CallData *call, Q931Message *q931Msg); int ooHandleDisplayIE(OOH323CallData *call, Q931Message *q931Msg);
int ooHandleH2250ID (OOH323CallData *call, H225ProtocolIdentifier protocolIdentifier);
int ooHandleDisplayIE(OOH323CallData *call, Q931Message *q931Msg) { int ooHandleDisplayIE(OOH323CallData *call, Q931Message *q931Msg) {
Q931InformationElement* pDisplayIE; Q931InformationElement* pDisplayIE;
@ -57,6 +58,17 @@ int ooHandleDisplayIE(OOH323CallData *call, Q931Message *q931Msg) {
return OO_OK; return OO_OK;
} }
int ooHandleH2250ID (OOH323CallData *call, H225ProtocolIdentifier protocolIdentifier) {
if (!call->h225version && (protocolIdentifier.numids >= 6) &&
(protocolIdentifier.subid[3] == 2250)) {
call->h225version = protocolIdentifier.subid[5];
OOTRACEDBGC4("Extract H.225 remote version, it's %d, (%s, %s)\n", call->h225version,
call->callType, call->callToken);
}
return OO_OK;
}
int ooHandleFastStart(OOH323CallData *call, H225Facility_UUIE *facility) int ooHandleFastStart(OOH323CallData *call, H225Facility_UUIE *facility)
{ {
H245OpenLogicalChannel* olc; H245OpenLogicalChannel* olc;
@ -241,7 +253,9 @@ int ooHandleFastStart(OOH323CallData *call, H225Facility_UUIE *facility)
} }
} }
} else if (OO_TESTFLAG (call->flags, OO_M_TUNNELING)) { } else if (OO_TESTFLAG (call->flags, OO_M_TUNNELING)) {
if (call->h225version >= 4) {
ret =ooSendTCSandMSD(call); ret =ooSendTCSandMSD(call);
}
if (ret != OO_OK) if (ret != OO_OK)
return ret; return ret;
} }
@ -372,6 +386,7 @@ int ooOnReceivedSetup(OOH323CallData *call, Q931Message *q931Msg)
"%s\n", call->callType, call->callToken); "%s\n", call->callType, call->callToken);
return OO_FAILED; return OO_FAILED;
} }
ooHandleH2250ID(call, setup->protocolIdentifier);
memcpy(call->callIdentifier.guid.data, setup->callIdentifier.guid.data, memcpy(call->callIdentifier.guid.data, setup->callIdentifier.guid.data,
setup->callIdentifier.guid.numocts); setup->callIdentifier.guid.numocts);
call->callIdentifier.guid.numocts = setup->callIdentifier.guid.numocts; call->callIdentifier.guid.numocts = setup->callIdentifier.guid.numocts;
@ -384,9 +399,9 @@ int ooOnReceivedSetup(OOH323CallData *call, Q931Message *q931Msg)
pDisplayIE = ooQ931GetIE(q931Msg, Q931DisplayIE); pDisplayIE = ooQ931GetIE(q931Msg, Q931DisplayIE);
if(pDisplayIE) if(pDisplayIE)
{ {
call->remoteDisplayName = (char *) memAlloc(call->pctxt, call->remoteDisplayName = (char *) memAllocZ(call->pctxt,
pDisplayIE->length*sizeof(ASN1OCTET)+1); pDisplayIE->length*sizeof(ASN1OCTET)+1);
strcpy(call->remoteDisplayName, (char *)pDisplayIE->data); strncpy(call->remoteDisplayName, (char *)pDisplayIE->data, pDisplayIE->length*sizeof(ASN1OCTET));
} }
/*Extract Remote Aliases, if present*/ /*Extract Remote Aliases, if present*/
if(setup->m.sourceAddressPresent) if(setup->m.sourceAddressPresent)
@ -618,6 +633,7 @@ int ooOnReceivedCallProceeding(OOH323CallData *call, Q931Message *q931Msg)
return OO_FAILED; return OO_FAILED;
} }
ooHandleH2250ID(call, callProceeding->protocolIdentifier);
/* Handle fast-start */ /* Handle fast-start */
if(OO_TESTFLAG (call->flags, OO_M_FASTSTART)) if(OO_TESTFLAG (call->flags, OO_M_FASTSTART))
{ {
@ -846,6 +862,7 @@ int ooOnReceivedAlerting(OOH323CallData *call, Q931Message *q931Msg)
} }
return OO_FAILED; return OO_FAILED;
} }
ooHandleH2250ID(call, alerting->protocolIdentifier);
/*Handle fast-start */ /*Handle fast-start */
if(OO_TESTFLAG (call->flags, OO_M_FASTSTART) && if(OO_TESTFLAG (call->flags, OO_M_FASTSTART) &&
!OO_TESTFLAG(call->flags, OO_M_FASTSTARTANSWERED)) !OO_TESTFLAG(call->flags, OO_M_FASTSTARTANSWERED))
@ -996,7 +1013,9 @@ int ooOnReceivedAlerting(OOH323CallData *call, Q931Message *q931Msg)
OOTRACEINFO3("Tunneling and h245address provided." OOTRACEINFO3("Tunneling and h245address provided."
"Giving preference to Tunneling (%s, %s)\n", "Giving preference to Tunneling (%s, %s)\n",
call->callType, call->callToken); call->callType, call->callToken);
if (call->h225version >= 4) {
ret =ooSendTCSandMSD(call); ret =ooSendTCSandMSD(call);
}
if (ret != OO_OK) if (ret != OO_OK)
return ret; return ret;
@ -1038,6 +1057,10 @@ int ooOnReceivedAlerting(OOH323CallData *call, Q931Message *q931Msg)
call->callState = OO_CALL_CLEAR; call->callState = OO_CALL_CLEAR;
} }
return OO_FAILED; return OO_FAILED;
} else {
if (call->h225version >= 4) {
ret =ooSendTCSandMSD(call);
}
} }
} }
} }
@ -1076,6 +1099,7 @@ int ooOnReceivedProgress(OOH323CallData *call, Q931Message *q931Msg)
} }
return OO_FAILED; return OO_FAILED;
} }
ooHandleH2250ID(call, progress->protocolIdentifier);
/*Handle fast-start */ /*Handle fast-start */
if(OO_TESTFLAG (call->flags, OO_M_FASTSTART) && if(OO_TESTFLAG (call->flags, OO_M_FASTSTART) &&
!OO_TESTFLAG(call->flags, OO_M_FASTSTARTANSWERED)) !OO_TESTFLAG(call->flags, OO_M_FASTSTARTANSWERED))
@ -1227,7 +1251,9 @@ int ooOnReceivedProgress(OOH323CallData *call, Q931Message *q931Msg)
OOTRACEINFO3("Tunneling and h245address provided." OOTRACEINFO3("Tunneling and h245address provided."
"Giving preference to Tunneling (%s, %s)\n", "Giving preference to Tunneling (%s, %s)\n",
call->callType, call->callToken); call->callType, call->callToken);
if (call->h225version >= 4) {
ret =ooSendTCSandMSD(call); ret =ooSendTCSandMSD(call);
}
if (ret != OO_OK) if (ret != OO_OK)
return ret; return ret;
} else if(progress->m.h245AddressPresent) { } else if(progress->m.h245AddressPresent) {
@ -1268,6 +1294,10 @@ int ooOnReceivedProgress(OOH323CallData *call, Q931Message *q931Msg)
call->callState = OO_CALL_CLEAR; call->callState = OO_CALL_CLEAR;
} }
return OO_FAILED; return OO_FAILED;
} else {
if (call->h225version >= 4) {
ret =ooSendTCSandMSD(call);
}
} }
} }
} }
@ -1313,7 +1343,7 @@ int ooOnReceivedSignalConnect(OOH323CallData* call, Q931Message *q931Msg)
} }
return OO_FAILED; return OO_FAILED;
} }
ooHandleH2250ID(call, connect->protocolIdentifier);
/*Handle fast-start */ /*Handle fast-start */
if(OO_TESTFLAG (call->flags, OO_M_FASTSTART) && if(OO_TESTFLAG (call->flags, OO_M_FASTSTART) &&
!OO_TESTFLAG (call->flags, OO_M_FASTSTARTANSWERED)) !OO_TESTFLAG (call->flags, OO_M_FASTSTARTANSWERED))
@ -1548,6 +1578,7 @@ int ooOnReceivedSignalConnect(OOH323CallData* call, Q931Message *q931Msg)
OOTRACEDBGB3("Finished tunneled messages in Connect. (%s, %s)\n", OOTRACEDBGB3("Finished tunneled messages in Connect. (%s, %s)\n",
call->callType, call->callToken); call->callType, call->callToken);
}
/* /*
Send TCS as call established and no capability exchange has yet Send TCS as call established and no capability exchange has yet
started. This will be true only when separate h245 connection is not started. This will be true only when separate h245 connection is not
@ -1565,7 +1596,6 @@ int ooOnReceivedSignalConnect(OOH323CallData* call, Q931Message *q931Msg)
} }
} }
}
call->callState = OO_CALL_CONNECTED; call->callState = OO_CALL_CONNECTED;
if (call->rtdrCount > 0 && call->rtdrInterval > 0) { if (call->rtdrCount > 0 && call->rtdrInterval > 0) {
return ooSendRoundTripDelayRequest(call); return ooSendRoundTripDelayRequest(call);
@ -1786,6 +1816,9 @@ int ooOnReceivedFacility(OOH323CallData *call, Q931Message * pQ931Msg)
H225TransportAddress_ipAddress_ip *ip = NULL; H225TransportAddress_ipAddress_ip *ip = NULL;
OOTRACEDBGC3("Received Facility Message.(%s, %s)\n", call->callType, OOTRACEDBGC3("Received Facility Message.(%s, %s)\n", call->callType,
call->callToken); call->callToken);
ooHandleDisplayIE(call, pQ931Msg);
/* Get Reference to H323_UU_PDU */ /* Get Reference to H323_UU_PDU */
if(!pQ931Msg->userInfo) if(!pQ931Msg->userInfo)
{ {
@ -1803,6 +1836,7 @@ int ooOnReceivedFacility(OOH323CallData *call, Q931Message * pQ931Msg)
facility = pH323UUPdu->h323_message_body.u.facility; facility = pH323UUPdu->h323_message_body.u.facility;
if(facility) if(facility)
{ {
ooHandleH2250ID(call, facility->protocolIdentifier);
/* Depending on the reason of facility message handle the message */ /* Depending on the reason of facility message handle the message */
if(facility->reason.t == T_H225FacilityReason_transportedInformation) if(facility->reason.t == T_H225FacilityReason_transportedInformation)
{ {
@ -1980,6 +2014,7 @@ int ooHandleStartH245FacilityMessage
OOTRACEINFO3("INFO: H.245 connection already established with remote" OOTRACEINFO3("INFO: H.245 connection already established with remote"
" endpoint (%s, %s)\n", call->callType, call->callToken); " endpoint (%s, %s)\n", call->callType, call->callToken);
} }
ooSendTCSandMSD(call);
return OO_OK; return OO_OK;
} }

@ -53,6 +53,7 @@ EXTERN int ooQ931Decode
int offset, x; int offset, x;
int rv = ASN_OK; int rv = ASN_OK;
char number[128]; char number[128];
char *display = NULL;
/* OOCTXT *pctxt = &gH323ep.msgctxt; */ /* OOCTXT *pctxt = &gH323ep.msgctxt; */
OOCTXT *pctxt = call->msgctxt; OOCTXT *pctxt = call->msgctxt;
@ -164,10 +165,16 @@ EXTERN int ooQ931Decode
} }
if(ie->discriminator == Q931DisplayIE) if(ie->discriminator == Q931DisplayIE)
{ {
if (!(display = memAllocZ(pctxt, ie->length + 1))) {
OOTRACEERR4("Can't alloc DisplayIE buffer for %n bytes, (%s, %s)\n", ie->length,
call->callType, call->callToken);
} else {
memcpy(display, ie->data,ie->length);
OOTRACEDBGB1(" Display IE = {\n"); OOTRACEDBGB1(" Display IE = {\n");
OOTRACEDBGB2(" %s\n", ie->data); OOTRACEDBGB2(" %s\n", display);
OOTRACEDBGB1(" }\n"); OOTRACEDBGB1(" }\n");
} }
}
if(ie->discriminator == Q931KeypadIE) if(ie->discriminator == Q931KeypadIE)
{ {
@ -1451,7 +1458,9 @@ int ooSendAlerting(OOH323CallData *call)
OOTRACEERR3("Error: Failed to enqueue Alerting message to outbound queue. (%s, %s)\n", call->callType, call->callToken); OOTRACEERR3("Error: Failed to enqueue Alerting message to outbound queue. (%s, %s)\n", call->callType, call->callToken);
} }
if (call->h225version >= 4) {
ooSendTCSandMSD(call); ooSendTCSandMSD(call);
}
memReset (call->msgctxt); memReset (call->msgctxt);
return ret; return ret;
@ -1588,7 +1597,9 @@ int ooSendProgress(OOH323CallData *call)
if (!OO_TESTFLAG(call->flags, OO_M_TUNNELING) && call->h245listener) if (!OO_TESTFLAG(call->flags, OO_M_TUNNELING) && call->h245listener)
ooSendStartH245Facility(call); ooSendStartH245Facility(call);
if (call->h225version >= 4) {
ooSendTCSandMSD(call); ooSendTCSandMSD(call);
}
memReset (call->msgctxt); memReset (call->msgctxt);
return ret; return ret;
@ -1957,12 +1968,16 @@ int ooAcceptCall(OOH323CallData *call)
} }
/* Add h245 listener address. Do not add H245 listener address in case /* Add h245 listener address. */
of fast-start. */ /* Do not add H245 listener address in case
of fast-start. why? */
/* May 20110205 */
/* Send h245 listener addr any case if H245 connection isn't established */
if (/* (!OO_TESTFLAG(call->flags, OO_M_FASTSTART) || if (/* (!OO_TESTFLAG(call->flags, OO_M_FASTSTART) ||
call->remoteFastStartOLCs.count == 0) && */ call->remoteFastStartOLCs.count == 0) && */
!OO_TESTFLAG (call->flags, OO_M_TUNNELING) && !OO_TESTFLAG (call->flags, OO_M_TUNNELING) &&
!call->h245listener && ooCreateH245Listener(call) == OO_OK) ( (!call->h245listener && ooCreateH245Listener(call) == OO_OK) ||
!call->pH245Channel))
{ {
connect->m.h245AddressPresent = TRUE; connect->m.h245AddressPresent = TRUE;
connect->h245Address.t = T_H225TransportAddress_ipAddress; connect->h245Address.t = T_H225TransportAddress_ipAddress;
@ -1997,6 +2012,7 @@ int ooAcceptCall(OOH323CallData *call)
return OO_FAILED; return OO_FAILED;
} }
/* memReset(&gH323ep.msgctxt); */ /* memReset(&gH323ep.msgctxt); */
ooSendTCSandMSD(call);
memReset(call->msgctxt); memReset(call->msgctxt);
call->callState = OO_CALL_CONNECTED; call->callState = OO_CALL_CONNECTED;
@ -2721,11 +2737,8 @@ int ooH323MakeCall_helper(OOH323CallData *call)
/* For H.323 version 4 and higher, if fast connect, tunneling should be /* For H.323 version 4 and higher, if fast connect, tunneling should be
supported. supported.
why?
*/ */
if(OO_TESTFLAG(call->flags, OO_M_FASTSTART)) {
q931msg->userInfo->h323_uu_pdu.h245Tunneling = TRUE;
OO_SETFLAG(call->flags, OO_M_TUNNELING);
}
OOTRACEDBGA3("Built SETUP message (%s, %s)\n", call->callType, OOTRACEDBGA3("Built SETUP message (%s, %s)\n", call->callType,
call->callToken); call->callToken);

Loading…
Cancel
Save