diff options
Diffstat (limited to 'addons/ooh323c/src/ooh245.c')
-rw-r--r-- | addons/ooh323c/src/ooh245.c | 786 |
1 files changed, 665 insertions, 121 deletions
diff --git a/addons/ooh323c/src/ooh245.c b/addons/ooh323c/src/ooh245.c index 35d1fe1b0..034c3dd02 100644 --- a/addons/ooh323c/src/ooh245.c +++ b/addons/ooh323c/src/ooh245.c @@ -13,7 +13,8 @@ * maintain this copyright notice. * *****************************************************************************/ - +#include <asterisk.h> +#include <asterisk/lock.h> #include "ooh245.h" #include "ooCalls.h" #include "printHandler.h" @@ -34,9 +35,10 @@ static ASN1OBJID gh245ProtocolID = { 6, { 0, 0, 8, 245, 0, 8 } }; -int ooCreateH245Message(H245Message **pph245msg, int type) +int ooCreateH245Message(OOH323CallData* call, H245Message **pph245msg, int type) { - OOCTXT* pctxt = &gH323ep.msgctxt; + /* OOCTXT* pctxt = &gH323ep.msgctxt; */ + OOCTXT* pctxt = call->msgctxt; *pph245msg = (H245Message*) memAlloc (pctxt, sizeof(H245Message)); @@ -121,7 +123,8 @@ int ooFreeH245Message(OOH323CallData *call, H245Message *pmsg) OOTRACEDBGC1("msgCtxt Reset?"); if (0 != pmsg) { if(!OO_TESTFLAG (call->flags, OO_M_TUNNELING)){ - memReset (&gH323ep.msgctxt); + /* memReset (&gH323ep.msgctxt); */ + memReset (call->msgctxt); OOTRACEDBGC3(" Done (%s, %s)\n", call->callType, call->callToken); return OO_OK; } @@ -166,7 +169,8 @@ int ooEncodeH245Message int stat=0; ASN1OCTET* encodePtr=NULL; H245MultimediaSystemControlMessage *multimediaMsg; - OOCTXT *pctxt = &gH323ep.msgctxt; + /* OOCTXT *pctxt = &gH323ep.msgctxt; */ + OOCTXT *pctxt = call->msgctxt; multimediaMsg = &(ph245Msg->h245Msg); if(!msgbuf || size<200) @@ -196,15 +200,17 @@ int ooEncodeH245Message msgbuf[i++] = 0; } - setPERBuffer (pctxt, msgbuf+i, (size-i), TRUE); + setPERBuffer (pctxt, (unsigned char*) msgbuf+i, (size-i), TRUE); - stat = asn1PE_H245MultimediaSystemControlMessage (&gH323ep.msgctxt, + /* stat = asn1PE_H245MultimediaSystemControlMessage (&gH323ep.msgctxt, */ + stat = asn1PE_H245MultimediaSystemControlMessage (call->msgctxt, multimediaMsg); if (stat != ASN_OK) { OOTRACEERR3 ("ERROR: H245 Message encoding failed (%s, %s)\n", call->callType, call->callToken); - OOTRACEERR1 (errGetText (&gH323ep.msgctxt)); + /* OOTRACEERR1 (errGetText (&gH323ep.msgctxt)); */ + OOTRACEERR1 (errGetText (call->msgctxt)); return OO_FAILED; } @@ -239,7 +245,7 @@ int ooSendH245Msg(OOH323CallData *call, H245Message *msg) "message(%s, %s)\n", call->callType, call->callToken); return OO_FAILED; } - iRet = ooEncodeH245Message(call, msg, encodebuf, MAXMSGLEN); + iRet = ooEncodeH245Message(call, msg, (char*) encodebuf, MAXMSGLEN); if(iRet != OO_OK) { @@ -317,15 +323,16 @@ int ooSendTermCapMsg(OOH323CallData *call) ooH323EpCapability *epCap=NULL; H245TerminalCapabilitySet *termCap=NULL; H245AudioCapability *audioCap=NULL; + H245DataApplicationCapability *t38Cap, *rtdCap = NULL; H245AudioTelephonyEventCapability *ateCap=NULL; H245UserInputCapability *userInputCap = NULL; H245CapabilityTableEntry *entry=NULL; - H245AlternativeCapabilitySet *altSet=NULL; + H245AlternativeCapabilitySet *altSetAudio=NULL, *altSetVideo=NULL, *altSetDtmf=NULL; H245CapabilityDescriptor *capDesc=NULL; H245Message *ph245msg=NULL; H245VideoCapability *videoCap=NULL; - int i=0, j=0, k=0; + int i=0,k=0; if(call->localTermCapState == OO_LocalTermCapSetSent) { OOTRACEINFO3("TerminalCapabilitySet exchange procedure already in " @@ -333,7 +340,7 @@ int ooSendTermCapMsg(OOH323CallData *call) return OO_OK; } - ret = ooCreateH245Message(&ph245msg, + ret = ooCreateH245Message(call, &ph245msg, T_H245MultimediaSystemControlMessage_request); if(ret == OO_FAILED) @@ -345,7 +352,8 @@ int ooSendTermCapMsg(OOH323CallData *call) /* Set request type as TerminalCapabilitySet */ request = ph245msg->h245Msg.u.request; - pctxt = &gH323ep.msgctxt; + /* pctxt = &gH323ep.msgctxt; */ + pctxt = call->msgctxt; ph245msg->msgType = OOTerminalCapabilitySet; memset(request, 0, sizeof(H245RequestMessage)); if(request == NULL) @@ -366,6 +374,24 @@ int ooSendTermCapMsg(OOH323CallData *call) termCap->sequenceNumber = ++(call->localTermCapSeqNo); termCap->protocolIdentifier = gh245ProtocolID; /* protocol id */ + /* Initialize alternate sets */ + altSetAudio = (H245AlternativeCapabilitySet*) + memAlloc(pctxt, sizeof(H245AlternativeCapabilitySet)); + altSetVideo = (H245AlternativeCapabilitySet*) + memAlloc(pctxt, sizeof(H245AlternativeCapabilitySet)); + altSetDtmf = (H245AlternativeCapabilitySet*) + memAlloc(pctxt, sizeof(H245AlternativeCapabilitySet)); + if(!altSetAudio || !altSetVideo || !altSetDtmf) + { + OOTRACEERR3("Error:Memory - ooSendTermCapMsg - altSet." + "(%s, %s)\n", call->callType, call->callToken); + return OO_FAILED; + } + memset(altSetDtmf, 0, sizeof(H245AlternativeCapabilitySet)); + memset(altSetVideo, 0, sizeof(H245AlternativeCapabilitySet)); + memset(altSetAudio, 0, sizeof(H245AlternativeCapabilitySet)); + + /* Add audio Capabilities */ dListInit(&(termCap->capabilityTable)); @@ -450,6 +476,82 @@ int ooSendTermCapMsg(OOH323CallData *call) } entry->capabilityTableEntryNumber = i+1; dListAppend(pctxt , &(termCap->capabilityTable), entry); + altSetAudio->elem[altSetAudio->n] = i+1; + altSetAudio->n++; + i++; + } + else if(epCap->capType == OO_CAP_TYPE_DATA) + { + + /* Create t.38 capability. If capability supports receive, we only + add it as receive capability in TCS. However, if it supports only + transmit, we add it as transmit capability in TCS. + */ + if((epCap->dir & OORX) && !(epCap->dir & OOTX)) + { + + OOTRACEDBGC3("Sending receive capability t38 in TCS.(%s, %s)\n", + call->callType, call->callToken); + + t38Cap = ooCapabilityCreateT38Capability(epCap, pctxt, OORX); + if(!t38Cap) + { + OOTRACEWARN3("WARN:Failed to create t38 capability for" + "%s, %s\n", + call->callType, call->callToken); + continue; + } + } + else if((epCap->dir & OOTX) && !(epCap->dir & OORX)) + { + OOTRACEDBGC3("Sending transmit capability t38 in TCS.(%s, %s)\n", + call->callType, call->callToken); + t38Cap = ooCapabilityCreateT38Capability(epCap, pctxt, OOTX); + if(!t38Cap) + { + OOTRACEWARN3("WARN:Failed to create capability t38 " + "(%s, %s)\n", + call->callType, call->callToken); + continue; + } + } + else{ + OOTRACEDBGC3("Sending transmit&recevie capability t38 in TCS.(%s, %s)\n", + call->callType, call->callToken); + t38Cap = ooCapabilityCreateT38Capability(epCap, pctxt, OOTX&OORX); + if(!t38Cap) + { + OOTRACEWARN3("WARN:Failed to create capability t38 " + "(%s, %s)\n", + call->callType, call->callToken); + continue; + } + } + /* Add Capabilities to Capability Table */ + entry = (H245CapabilityTableEntry*) memAlloc(pctxt, + sizeof(H245CapabilityTableEntry)); + if(!entry) + { + OOTRACEERR3("Error:Memory - ooSendTermCapMsg - entry(audio Cap)." + "(%s, %s)\n", call->callType, call->callToken); + return OO_FAILED; + } + memset(entry, 0, sizeof(H245CapabilityTableEntry)); + entry->m.capabilityPresent = 1; + if((epCap->dir & OORX) && (epCap->dir & OOTX)) { + entry->capability.t = T_H245Capability_receiveAndTransmitDataApplicationCapability; + entry->capability.u.receiveAndTransmitDataApplicationCapability = t38Cap; + } else if((epCap->dir & OORX)) { + entry->capability.t = T_H245Capability_receiveDataApplicationCapability; + entry->capability.u.receiveDataApplicationCapability = t38Cap; + }else{ + entry->capability.t = T_H245Capability_transmitDataApplicationCapability; + entry->capability.u.transmitDataApplicationCapability = t38Cap; + } + entry->capabilityTableEntryNumber = i+1; + dListAppend(pctxt , &(termCap->capabilityTable), entry); + altSetAudio->elem[altSetAudio->n] = i+1; + altSetAudio->n++; i++; } else if(epCap->capType == OO_CAP_TYPE_VIDEO) @@ -508,6 +610,8 @@ int ooSendTermCapMsg(OOH323CallData *call) } entry->capabilityTableEntryNumber = i+1; dListAppend(pctxt , &(termCap->capabilityTable), entry); + altSetVideo->elem[altSetVideo->n] = i+1; + altSetVideo->n++; i++; } } @@ -515,7 +619,7 @@ int ooSendTermCapMsg(OOH323CallData *call) if(call->dtmfmode & OO_CAP_DTMF_RFC2833) { ateCap = (H245AudioTelephonyEventCapability*) - ooCapabilityCreateDTMFCapability(OO_CAP_DTMF_RFC2833, pctxt); + ooCapabilityCreateDTMFCapability(OO_CAP_DTMF_RFC2833, call->dtmfcodec, pctxt); if(!ateCap) { OOTRACEWARN3("WARN:Failed to add RFC2833 cap to TCS(%s, %s)\n", @@ -541,6 +645,44 @@ int ooSendTermCapMsg(OOH323CallData *call) entry->capabilityTableEntryNumber = i+1; dListAppend(pctxt , &(termCap->capabilityTable), entry); + altSetDtmf->elem[altSetDtmf->n] = i+1; + altSetDtmf->n++; + + i++; + } + } + + if(call->dtmfmode & OO_CAP_DTMF_CISCO) + { + rtdCap = (H245DataApplicationCapability*) + ooCapabilityCreateDTMFCapability(OO_CAP_DTMF_CISCO, call->dtmfcodec, pctxt); + if(!rtdCap) + { + OOTRACEWARN3("WARN:Failed to add RTP/CISCO DTMF cap to TCS(%s, %s)\n", + call->callType, call->callToken); + } + else { + entry = (H245CapabilityTableEntry*) memAlloc(pctxt, + sizeof(H245CapabilityTableEntry)); + if(!entry) + { + OOTRACEERR3("Error:Failed to allocate memory for new capability " + "table entry. (%s, %s)\n", call->callType, + call->callToken); + ooFreeH245Message(call, ph245msg); + return OO_FAILED; + } + + memset(entry, 0, sizeof(H245CapabilityTableEntry)); + entry->m.capabilityPresent = 1; + + entry->capability.t = T_H245Capability_receiveDataApplicationCapability; + entry->capability.u.receiveDataApplicationCapability = rtdCap; + + entry->capabilityTableEntryNumber = i+1; + dListAppend(pctxt , &(termCap->capabilityTable), entry); + altSetDtmf->elem[altSetDtmf->n] = i+1; + altSetDtmf->n++; i++; } @@ -549,7 +691,7 @@ int ooSendTermCapMsg(OOH323CallData *call) if(call->dtmfmode & OO_CAP_DTMF_H245_alphanumeric) { userInputCap = (H245UserInputCapability*)ooCapabilityCreateDTMFCapability - (OO_CAP_DTMF_H245_alphanumeric, pctxt); + (OO_CAP_DTMF_H245_alphanumeric, 0, pctxt); if(!userInputCap) { OOTRACEWARN3("WARN:Failed to add H245(alphanumeric) cap to " @@ -575,6 +717,8 @@ int ooSendTermCapMsg(OOH323CallData *call) entry->capabilityTableEntryNumber = i+1; dListAppend(pctxt , &(termCap->capabilityTable), entry); + altSetDtmf->elem[altSetDtmf->n] = i+1; + altSetDtmf->n++; i++; } @@ -583,7 +727,7 @@ int ooSendTermCapMsg(OOH323CallData *call) if(call->dtmfmode & OO_CAP_DTMF_H245_signal) { userInputCap = (H245UserInputCapability*)ooCapabilityCreateDTMFCapability - (OO_CAP_DTMF_H245_signal, pctxt); + (OO_CAP_DTMF_H245_signal, 0, pctxt); if(!userInputCap) { OOTRACEWARN3("WARN:Failed to add H245(signal) cap to " @@ -609,6 +753,8 @@ int ooSendTermCapMsg(OOH323CallData *call) entry->capabilityTableEntryNumber = i+1; dListAppend(pctxt , &(termCap->capabilityTable), entry); + altSetDtmf->elem[altSetDtmf->n] = i+1; + altSetDtmf->n++; i++; } @@ -636,7 +782,7 @@ int ooSendTermCapMsg(OOH323CallData *call) alternate capabilities set. Need a way for application developer to specify the alternative capability sets. */ - for(j=0; j<i; j++) + /* for(j=0; j<i; j++) { altSet = (H245AlternativeCapabilitySet*) memAlloc(pctxt, sizeof(H245AlternativeCapabilitySet)); @@ -645,7 +791,11 @@ int ooSendTermCapMsg(OOH323CallData *call) altSet->elem[0] = j+1; dListAppend(pctxt, &(capDesc->simultaneousCapabilities), altSet); - } + } */ + + if (altSetAudio->n) dListAppend(pctxt, &(capDesc->simultaneousCapabilities), altSetAudio); + if (altSetVideo->n) dListAppend(pctxt, &(capDesc->simultaneousCapabilities), altSetVideo); + if (altSetDtmf->n) dListAppend(pctxt, &(capDesc->simultaneousCapabilities), altSetDtmf); dListInit(&(termCap->capabilityDescriptors)); dListAppend(pctxt, &(termCap->capabilityDescriptors), capDesc); @@ -695,7 +845,7 @@ int ooHandleMasterSlave(OOH323CallData *call, void * pmsg, { H245MasterSlaveDetermination *masterSlave; H245MasterSlaveDeterminationAck *masterSlaveAck; - ASN1UINT statusDeterminationNumber; + ASN1UINT statusDeterminationNumber, moduloDiff; switch(msgType) { @@ -704,7 +854,16 @@ int ooHandleMasterSlave(OOH323CallData *call, void * pmsg, 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"); @@ -730,10 +889,17 @@ int ooHandleMasterSlave(OOH323CallData *call, void * pmsg, 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; @@ -741,8 +907,9 @@ int ooHandleMasterSlave(OOH323CallData *call, void * pmsg, 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; @@ -750,8 +917,9 @@ int ooHandleMasterSlave(OOH323CallData *call, void * pmsg, call->callType, call->callToken); return OO_OK; } - if(masterSlave->statusDeterminationNumber == - statusDeterminationNumber) + /* if(masterSlave->statusDeterminationNumber == + statusDeterminationNumber) */ + if (moduloDiff == 0 || moduloDiff == 0x800000) { ooSendMasterSlaveDeterminationReject (call); @@ -780,6 +948,8 @@ int ooHandleMasterSlave(OOH323CallData *call, void * pmsg, call->callType, call->callToken); } } + + call->msAckStatus = OO_msAck_remoteReceived; if(call->localTermCapState == OO_LocalTermCapSetAckRecvd && call->remoteTermCapState == OO_RemoteTermCapSetAckSent) @@ -788,7 +958,7 @@ int ooHandleMasterSlave(OOH323CallData *call, void * pmsg, if(gH323ep.h323Callbacks.openLogicalChannels) gH323ep.h323Callbacks.openLogicalChannels(call); else{ - if(!call->logicalChans) + if(!ooGetTransmitLogicalChannel(call)) ooOpenLogicalChannels(call); } #if 0 @@ -816,7 +986,8 @@ int ooSendMasterSlaveDetermination(OOH323CallData *call) int ret; H245Message* ph245msg=NULL; H245RequestMessage *request; - OOCTXT *pctxt=&gH323ep.msgctxt; + /* OOCTXT *pctxt=&gH323ep.msgctxt; */ + OOCTXT *pctxt=call->msgctxt; H245MasterSlaveDetermination* pMasterSlave; /* Check whether Master Slave Determination already in progress */ @@ -827,7 +998,7 @@ int ooSendMasterSlaveDetermination(OOH323CallData *call) return OO_OK; } - ret = ooCreateH245Message(&ph245msg, + ret = ooCreateH245Message(call, &ph245msg, T_H245MultimediaSystemControlMessage_request); if(ret != OO_OK) { @@ -873,9 +1044,10 @@ int ooSendMasterSlaveDeterminationAck(OOH323CallData* call, int ret=0; H245ResponseMessage * response=NULL; H245Message *ph245msg=NULL; - OOCTXT *pctxt=&gH323ep.msgctxt; + /* OOCTXT *pctxt=&gH323ep.msgctxt; */ + OOCTXT *pctxt=call->msgctxt; - ret = ooCreateH245Message(&ph245msg, + ret = ooCreateH245Message(call, &ph245msg, T_H245MultimediaSystemControlMessage_response); if(ret != OO_OK) { @@ -910,6 +1082,7 @@ int ooSendMasterSlaveDeterminationAck(OOH323CallData* call, } ooFreeH245Message(call, ph245msg); + call->msAckStatus = OO_msAck_localSent; return ret; } @@ -918,10 +1091,11 @@ int ooSendMasterSlaveDeterminationReject (OOH323CallData* call) int ret=0; H245ResponseMessage* response=NULL; H245Message *ph245msg=NULL; - OOCTXT *pctxt=&gH323ep.msgctxt; + /* OOCTXT *pctxt=&gH323ep.msgctxt; */ + OOCTXT *pctxt=call->msgctxt; ret = ooCreateH245Message - (&ph245msg, T_H245MultimediaSystemControlMessage_response); + (call, &ph245msg, T_H245MultimediaSystemControlMessage_response); if (ret != OO_OK) { OOTRACEERR3("Error:H245 message creation failed for - MasterSlave " @@ -963,10 +1137,11 @@ int ooSendMasterSlaveDeterminationRelease(OOH323CallData * call) int ret=0; H245IndicationMessage* indication=NULL; H245Message *ph245msg=NULL; - OOCTXT *pctxt=&gH323ep.msgctxt; + /* OOCTXT *pctxt=&gH323ep.msgctxt; */ + OOCTXT *pctxt=call->msgctxt; ret = ooCreateH245Message - (&ph245msg, T_H245MultimediaSystemControlMessage_indication); + (call, &ph245msg, T_H245MultimediaSystemControlMessage_indication); if (ret != OO_OK) { OOTRACEERR3("Error:H245 message creation failed for - MasterSlave " @@ -1028,6 +1203,257 @@ int ooHandleMasterSlaveReject return OO_OK; } +/* handling requestmode routines */ + +int ooSendRequestModeAck(OOH323CallData* call, + H245SequenceNumber sequenceNumber) +{ + int ret=0; + H245ResponseMessage* response=NULL; + H245Message *ph245msg=NULL; + OOCTXT *pctxt=call->msgctxt; + + ret = ooCreateH245Message(call, &ph245msg, + T_H245MultimediaSystemControlMessage_response); + if(ret != OO_OK) + { + OOTRACEERR3("Error:H245 message creation failed for - RequestMode " + "Ack (%s, %s)\n",call->callType, + call->callToken); + return OO_FAILED; + } + ph245msg->msgType = OORequestModeAck; + response = ph245msg->h245Msg.u.response; + memset(response, 0, sizeof(H245ResponseMessage)); + response->t = T_H245ResponseMessage_requestModeAck; + response->u.requestModeAck = (H245RequestModeAck *) + ASN1MALLOC(pctxt, sizeof(H245RequestModeAck)); + memset(response->u.requestModeAck, 0, + sizeof(H245RequestModeAck)); + + response->u.requestModeAck->sequenceNumber = sequenceNumber; + response->u.requestModeAck->response.t = + T_H245RequestModeAck_response_willTransmitMostPreferredMode; + + OOTRACEDBGA3("Built RequestModeAck (%s, %s)\n", + call->callType, call->callToken); + ret = ooSendH245Msg(call, ph245msg); + if(ret != OO_OK) + { + OOTRACEERR3("Error:Failed to enqueue RequestModeAck message" + " to outbound queue. (%s, %s)\n", call->callType, + call->callToken); + } + + ooFreeH245Message(call, ph245msg); + return ret; +} + +int ooSendRequestModeReject(OOH323CallData* call, + H245SequenceNumber sequenceNumber) +{ + int ret=0; + H245ResponseMessage* response=NULL; + H245Message *ph245msg=NULL; + OOCTXT *pctxt=call->msgctxt; + + ret = ooCreateH245Message(call, &ph245msg, + T_H245MultimediaSystemControlMessage_response); + if(ret != OO_OK) + { + OOTRACEERR3("Error:H245 message creation failed for - RequstMode " + "Reject (%s, %s)\n",call->callType, + call->callToken); + return OO_FAILED; + } + ph245msg->msgType = OORequestModeReject; + response = ph245msg->h245Msg.u.response; + memset(response, 0, sizeof(H245ResponseMessage)); + response->t = T_H245ResponseMessage_requestModeReject; + response->u.requestModeReject = (H245RequestModeReject *) + ASN1MALLOC(pctxt, sizeof(H245RequestModeReject)); + memset(response->u.requestModeReject, 0, + sizeof(H245RequestModeReject)); + + response->u.requestModeReject->sequenceNumber = sequenceNumber; + response->u.requestModeReject->cause.t = + T_H245RequestModeReject_cause_modeUnavailable; + + OOTRACEDBGA3("Built RequestModeReject (%s, %s)\n", + call->callType, call->callToken); + ret = ooSendH245Msg(call, ph245msg); + if(ret != OO_OK) + { + OOTRACEERR3("Error:Failed to enqueue RequestModeReject message" + " to outbound queue. (%s, %s)\n", call->callType, + call->callToken); + } + + ooFreeH245Message(call, ph245msg); + return ret; +} + +int ooSendRequestMode(OOH323CallData* call, + int isT38Mode) +{ + int ret=0; + H245RequestMessage *request; + H245Message *ph245msg=NULL; + OOCTXT *pctxt=call->msgctxt; + + + H245ModeDescription pModeDesc; + H245ModeElement pModeElem; + + if (isT38Mode && !OO_TESTFLAG(call->flags, OO_M_T38SUPPORTED)) /* t38 req but we dont support */ + return OO_OK; + + ret = ooCreateH245Message(call, &ph245msg, + T_H245MultimediaSystemControlMessage_request); + if(ret != OO_OK) + { + OOTRACEERR3("Error:H245 message creation failed for - RequstMode " + "(%s, %s)\n",call->callType, + call->callToken); + return OO_FAILED; + } + ph245msg->msgType = OORequestMode; + request = ph245msg->h245Msg.u.request; + memset(request, 0, sizeof(H245RequestMessage)); + request->t = T_H245RequestMessage_requestMode; + + request->u.requestMode = (H245RequestMode *) + ASN1MALLOC(pctxt, sizeof(H245RequestMode)); + memset(request->u.requestMode, 0, + sizeof(H245RequestMode)); + + call->requestSequence++; + call->reqFlags = (isT38Mode) ? OO_M_DATASESSION : OO_M_AUDIOSESSION; + + request->u.requestMode->sequenceNumber = call->requestSequence; + memset(&pModeElem, 0, sizeof(pModeElem)); + memset(&pModeDesc, 0, sizeof(pModeDesc)); + dListInit(&(request->u.requestMode->requestedModes)); + dListInit(&pModeDesc); + + if (isT38Mode) { + + pModeElem.type.t = T_H245ModeElementType_dataMode; + pModeElem.type.u.dataMode = (H245DataMode *) memAllocZ(pctxt, sizeof(H245DataMode)); + pModeElem.type.u.dataMode->bitRate = 144; + if (!ooCreateT38ApplicationData(pctxt,&(pModeElem.type.u.dataMode->application))) { + OOTRACEERR3("Error:Memory - ooCapabilityCreateT38Capability - (%s, %s)\n", + call->callType, + call->callToken); + } + } else { + pModeElem.type.t = T_H245ModeElementType_audioMode; + pModeElem.type.u.audioMode = (H245AudioMode *) memAllocZ(pctxt, sizeof(H245AudioMode)); + pModeElem.type.u.audioMode->t = T_H245AudioMode_genericAudioMode; + pModeElem.type.u.audioMode->u.genericAudioMode = (H245GenericCapability *) + memAllocZ(pctxt, sizeof(H245GenericCapability)); + pModeElem.type.u.audioMode->u.genericAudioMode->capabilityIdentifier.t = + T_H245CapabilityIdentifier_domainBased; + pModeElem.type.u.audioMode->u.genericAudioMode->capabilityIdentifier.u.domainBased = + "H.323"; + pModeElem.type.u.audioMode->u.genericAudioMode->m.maxBitRatePresent = TRUE; + pModeElem.type.u.audioMode->u.genericAudioMode->maxBitRate = 144; + } + + dListAppend(pctxt, &pModeDesc, &pModeElem); + dListAppend(pctxt, &(request->u.requestMode->requestedModes), &pModeDesc); + + ret = ooSendH245Msg(call, ph245msg); + if(ret != OO_OK) + { + OOTRACEERR3("Error:Failed to enqueue RequestMode message" + " to outbound queue. (%s, %s)\n", call->callType, + call->callToken); + } + + ooFreeH245Message(call, ph245msg); + return ret; +} + +void ooOnReceivedRequestModeAck(OOH323CallData* call, H245RequestModeAck * requestModeAck) +{ + int t38mode; + + if (!call->reqFlags) return; + + if (OO_TESTFLAG(call->reqFlags, OO_M_AUDIOSESSION)) { + OO_SETFLAG(call->flags, OO_M_AUDIOSESSION); + OO_CLRFLAG(call->flags, OO_M_DATASESSION); + t38mode = 0; + } else { + OO_CLRFLAG(call->flags, OO_M_AUDIOSESSION); + OO_SETFLAG(call->flags, OO_M_DATASESSION); + t38mode = 1; + } + + call->reqFlags = 0; /* don't handle duplicate ack packet */ + + ooCloseAllLogicalChannels(call, "transmit"); + if(gH323ep.h323Callbacks.onModeChanged) { + OOTRACEDBGA3("Handle RequestModeAck: (%s, %s), calling " + "callback onModeChanged\n", call->callType, call->callToken); + gH323ep.h323Callbacks.onModeChanged(call, t38mode); + } +} + +int ooHandleRequestMode(OOH323CallData* call, + H245RequestMode *requestMode) +{ + + H245ModeDescription** pModeRef; + H245ModeElement** pModeElem; + H245ModeElementType* pMode; + + pModeRef = (H245ModeDescription**)dListFindByIndex(&requestMode->requestedModes, 0); + pModeElem = (H245ModeElement **) dListFindByIndex(*pModeRef, 0); + pMode = &((*pModeElem)->type); + OOTRACEDBGA5("Handle RequestMode: " + " modetype: %d/%d for (%s, %s)\n", pMode->t, pMode->u.dataMode->application.t, + call->callType, + call->callToken); + switch (pMode->t) { + case T_H245ModeElementType_dataMode: + if (pMode->u.dataMode->application.t == T_H245DataMode_application_t38fax && + OO_TESTFLAG(call->flags, OO_M_T38SUPPORTED)) { + if (ooSendRequestModeAck(call, requestMode->sequenceNumber) == OO_OK && + OO_TESTFLAG(call->flags, OO_M_AUDIOSESSION)) { + + OO_CLRFLAG(call->flags, OO_M_AUDIOSESSION); + OO_SETFLAG(call->flags, OO_M_DATASESSION); + if(gH323ep.h323Callbacks.onModeChanged) { + OOTRACEDBGA3("Handle RequestMode: (%s, %s), calling " + "callback onModeChanged\n", call->callType, call->callToken); + gH323ep.h323Callbacks.onModeChanged(call, 1); + } + } + } else { + ooSendRequestModeReject(call, requestMode->sequenceNumber); + } + break; + case T_H245ModeElementType_audioMode: + if (ooSendRequestModeAck(call, requestMode->sequenceNumber) == OO_OK && + OO_TESTFLAG(call->flags, OO_M_DATASESSION)) { + + OO_CLRFLAG(call->flags, OO_M_DATASESSION); + OO_SETFLAG(call->flags, OO_M_AUDIOSESSION); + if(gH323ep.h323Callbacks.onModeChanged) { + OOTRACEDBGA3("Handle RequestMode: (%s, %s), calling " + "callback onModeChanged\n", call->callType, call->callToken); + gH323ep.h323Callbacks.onModeChanged(call, 0); + } + } + break; + default: + ; + } + return OO_OK; + +} int ooHandleOpenLogicalChannel(OOH323CallData* call, H245OpenLogicalChannel *olc) @@ -1062,14 +1488,8 @@ int ooHandleOpenLogicalChannel(OOH323CallData* call, break; case T_H245DataType_videoData: case T_H245DataType_audioData: - ooHandleOpenLogicalChannel_helper(call, olc); - break; case T_H245DataType_data: - OOTRACEWARN3("Warn:Media channel data type " - "'T_H245DataType_data' not supported (%s, %s)\n", - call->callType, call->callToken); - ooSendOpenLogicalChannelReject(call, olc->forwardLogicalChannelNumber, - T_H245OpenLogicalChannelReject_cause_dataTypeNotSupported); + ooHandleOpenLogicalChannel_helper(call, olc); break; case T_H245DataType_encryptionData: OOTRACEWARN3("Warn:Media channel data type " @@ -1168,7 +1588,7 @@ int ooHandleOpenLogicalChannel_helper(OOH323CallData *call, return OO_FAILED; } /* Generate an Ack for the open channel request */ - ret = ooCreateH245Message(&ph245msg, + ret = ooCreateH245Message(call, &ph245msg, T_H245MultimediaSystemControlMessage_response); if(ret != OO_OK) { @@ -1183,7 +1603,8 @@ int ooHandleOpenLogicalChannel_helper(OOH323CallData *call, ph245msg->msgType = OOOpenLogicalChannelAck; ph245msg->logicalChannelNo = olc->forwardLogicalChannelNumber; response = ph245msg->h245Msg.u.response; - pctxt = &gH323ep.msgctxt; + /* pctxt = &gH323ep.msgctxt; */ + pctxt = call->msgctxt; memset(response, 0, sizeof(H245ResponseMessage)); response->t = T_H245ResponseMessage_openLogicalChannelAck; response->u.openLogicalChannelAck = (H245OpenLogicalChannelAck*) @@ -1292,10 +1713,11 @@ int ooSendOpenLogicalChannelReject int ret=0; H245ResponseMessage* response=NULL; H245Message *ph245msg=NULL; - OOCTXT *pctxt=&gH323ep.msgctxt; + /* OOCTXT *pctxt=&gH323ep.msgctxt; */ + OOCTXT *pctxt=call->msgctxt; ret = ooCreateH245Message - (&ph245msg, T_H245MultimediaSystemControlMessage_response); + (call, &ph245msg, T_H245MultimediaSystemControlMessage_response); if (ret != OO_OK) { OOTRACEERR3("Error:H245 message creation failed for - OpenLogicalChannel" @@ -1346,12 +1768,13 @@ int ooOnReceivedOpenLogicalChannelAck(OOH323CallData *call, H245OpenLogicalChannelAck *olcAck) { char remoteip[20]; + regmatch_t pmatch[1]; ooLogicalChannel *pLogicalChannel; H245H2250LogicalChannelAckParameters *h2250lcap; H245UnicastAddress *unicastAddr; H245UnicastAddress_iPAddress *iPAddress; H245UnicastAddress *unicastAddr1; - H245UnicastAddress_iPAddress *iPAddress1; + H245UnicastAddress_iPAddress *iPAddress1 = NULL; if(!((olcAck->m.forwardMultiplexAckParametersPresent == 1) && (olcAck->forwardMultiplexAckParameters.t == @@ -1396,30 +1819,29 @@ int ooOnReceivedOpenLogicalChannelAck(OOH323CallData *call, iPAddress->network.data[3]); /* Extract media control channel address */ - if(h2250lcap->m.mediaControlChannelPresent != 1) - { - OOTRACEERR3("Error: Processing OpenLogicalChannelAck - Missing media " - "control channel (%s, %s)\n", call->callType, call->callToken); - return OO_FAILED; - } - if(h2250lcap->mediaControlChannel.t != + if(h2250lcap->m.mediaControlChannelPresent == 1) { + if(h2250lcap->mediaControlChannel.t != T_H245TransportAddress_unicastAddress) - { - OOTRACEERR3("Error: Processing OpenLogicalChannelAck - media control " + { + OOTRACEERR3("Error: Processing OpenLogicalChannelAck - media control " "channel addres type is not unicast (%s, %s)\n", call->callType, call->callToken); - return OO_FAILED; - } + return OO_FAILED; + } - unicastAddr1 = h2250lcap->mediaControlChannel.u.unicastAddress; - if(unicastAddr1->t != T_H245UnicastAddress_iPAddress) - { - OOTRACEERR3("Error: Processing OpenLogicalChannelAck - media control " + unicastAddr1 = h2250lcap->mediaControlChannel.u.unicastAddress; + if(unicastAddr1->t != T_H245UnicastAddress_iPAddress) { + OOTRACEERR3("Error: Processing OpenLogicalChannelAck - media control " "channel address type is not IP (%s, %s)\n", call->callType, call->callToken); - return OO_FAILED; + return OO_FAILED; + } + + iPAddress1 = unicastAddr1->u.iPAddress; + } else { + OOTRACEDBGA3("Warning: Processing OpenLogicalChannelAck - Missing media " + "control channel (%s, %s)\n", call->callType, call->callToken); } - iPAddress1 = unicastAddr1->u.iPAddress; /* Set remote destination address for rtp session */ // strcpy(call->remoteIP, remoteip); @@ -1440,9 +1862,19 @@ int ooOnReceivedOpenLogicalChannelAck(OOH323CallData *call, pLogicalChannel->sessionID = h2250lcap->sessionID; /* Populate ports &ip for channel */ + + if (call->rtpMaskStr[0]) { + if (regexec(&call->rtpMask->regex, remoteip, 1, pmatch, 0)) { + OOTRACEERR5("ERROR:H245 Address is not matched with filter %s/%s" + "(%s, %s)\n", remoteip, call->rtpMaskStr, call->callType, call->callToken); + return OO_FAILED; + } + } + strcpy(pLogicalChannel->remoteIP, remoteip); pLogicalChannel->remoteMediaPort = iPAddress->tsapIdentifier; - pLogicalChannel->remoteMediaControlPort = iPAddress1->tsapIdentifier; + if (iPAddress1) + pLogicalChannel->remoteMediaControlPort = iPAddress1->tsapIdentifier; if(pLogicalChannel->chanCap->startTransmitChannel) { @@ -1567,7 +1999,7 @@ int ooSendEndSessionCommand(OOH323CallData *call) H245CommandMessage * command; OOCTXT *pctxt; H245Message *ph245msg=NULL; - ret = ooCreateH245Message(&ph245msg, + ret = ooCreateH245Message(call, &ph245msg, T_H245MultimediaSystemControlMessage_command); if(ret != OO_OK) { @@ -1578,7 +2010,8 @@ int ooSendEndSessionCommand(OOH323CallData *call) ph245msg->msgType = OOEndSessionCommand; command = ph245msg->h245Msg.u.command; - pctxt = &gH323ep.msgctxt; + /* pctxt = &gH323ep.msgctxt; */ + pctxt = call->msgctxt; memset(command, 0, sizeof(H245CommandMessage)); command->t = T_H245CommandMessage_endSessionCommand; command->u.endSessionCommand = (H245EndSessionCommand*) ASN1MALLOC(pctxt, @@ -1675,13 +2108,14 @@ int ooOnReceivedTerminalCapabilitySetAck(OOH323CallData* call) if(call->remoteTermCapState != OO_RemoteTermCapSetAckSent) return OO_OK; - if(call->masterSlaveState == OO_MasterSlave_Master || - call->masterSlaveState == OO_MasterSlave_Slave) + if((call->masterSlaveState == OO_MasterSlave_Master || + call->masterSlaveState == OO_MasterSlave_Slave) && + (call->msAckStatus == OO_msAck_remoteReceived)) { if(gH323ep.h323Callbacks.openLogicalChannels) gH323ep.h323Callbacks.openLogicalChannels(call); else{ - if(!call->logicalChans) + if(!ooGetTransmitLogicalChannel(call)) ooOpenLogicalChannels(call); } #if 0 @@ -1697,14 +2131,15 @@ int ooOnReceivedTerminalCapabilitySetAck(OOH323CallData* call) return OO_OK; } -int ooCloseAllLogicalChannels(OOH323CallData *call) +int ooCloseAllLogicalChannels(OOH323CallData *call, char* dir) { ooLogicalChannel *temp; temp = call->logicalChans; while(temp) { - if(temp->state == OO_LOGICALCHAN_ESTABLISHED) + if(temp->state == OO_LOGICALCHAN_ESTABLISHED && + (dir == NULL || !strcmp(temp->dir,dir))) { /* Sending closelogicalchannel only for outgoing channels*/ if(!strcmp(temp->dir, "transmit")) @@ -1728,7 +2163,7 @@ int ooSendCloseLogicalChannel(OOH323CallData *call, ooLogicalChannel *logicalCha H245RequestMessage *request; H245CloseLogicalChannel* clc; - ret = ooCreateH245Message(&ph245msg, + ret = ooCreateH245Message(call, &ph245msg, T_H245MultimediaSystemControlMessage_request); if(ret != OO_OK) { @@ -1738,7 +2173,8 @@ int ooSendCloseLogicalChannel(OOH323CallData *call, ooLogicalChannel *logicalCha } ph245msg->msgType = OOCloseLogicalChannel; ph245msg->logicalChannelNo = logicalChan->channelNo; - pctxt = &gH323ep.msgctxt; + /* pctxt = &gH323ep.msgctxt; */ + pctxt = call->msgctxt; request = ph245msg->h245Msg.u.request; request->t = T_H245RequestMessage_closeLogicalChannel; @@ -1795,7 +2231,7 @@ int ooSendRequestCloseLogicalChannel(OOH323CallData *call, H245RequestMessage *request; H245RequestChannelClose *rclc; - ret = ooCreateH245Message(&ph245msg, + ret = ooCreateH245Message(call, &ph245msg, T_H245MultimediaSystemControlMessage_request); if(ret != OO_OK) { @@ -1806,7 +2242,8 @@ int ooSendRequestCloseLogicalChannel(OOH323CallData *call, } ph245msg->msgType = OORequestChannelClose; ph245msg->logicalChannelNo = logicalChan->channelNo; - pctxt = &gH323ep.msgctxt; + /* pctxt = &gH323ep.msgctxt; */ + pctxt = call->msgctxt; request = ph245msg->h245Msg.u.request; request->t = T_H245RequestMessage_requestChannelClose; @@ -1848,7 +2285,7 @@ int ooSendRequestChannelCloseRelease(OOH323CallData *call, int channelNum) OOCTXT *pctxt; H245IndicationMessage *indication; - ret = ooCreateH245Message(&ph245msg, + ret = ooCreateH245Message(call, &ph245msg, T_H245MultimediaSystemControlMessage_indication); if(ret != OO_OK) { @@ -1859,7 +2296,8 @@ int ooSendRequestChannelCloseRelease(OOH323CallData *call, int channelNum) } ph245msg->msgType = OORequestChannelCloseRelease; ph245msg->logicalChannelNo = channelNum; - pctxt = &gH323ep.msgctxt; + /* pctxt = &gH323ep.msgctxt; */ + pctxt = call->msgctxt; indication = ph245msg->h245Msg.u.indication; indication->t = T_H245IndicationMessage_requestChannelCloseRelease; indication->u.requestChannelCloseRelease = (H245RequestChannelCloseRelease*) @@ -1919,7 +2357,7 @@ int ooOnReceivedRequestChannelClose(OOH323CallData *call, return OO_FAILED; } } - ret = ooCreateH245Message(&ph245msg, + ret = ooCreateH245Message(call, &ph245msg, T_H245MultimediaSystemControlMessage_response); if(ret != OO_OK) { @@ -1927,7 +2365,8 @@ int ooOnReceivedRequestChannelClose(OOH323CallData *call, "failed (%s, %s)\n", call->callType, call->callToken); return OO_FAILED; } - pctxt = &gH323ep.msgctxt; + /* pctxt = &gH323ep.msgctxt; */ + pctxt = call->msgctxt; ph245msg->msgType = OORequestChannelCloseAck; ph245msg->logicalChannelNo = rclc->forwardLogicalChannelNumber; response = ph245msg->h245Msg.u.response; @@ -2055,7 +2494,7 @@ int ooOnReceivedCloseLogicalChannel(OOH323CallData *call, return OO_FAILED; } - ret = ooCreateH245Message(&ph245msg, + ret = ooCreateH245Message(call, &ph245msg, T_H245MultimediaSystemControlMessage_response); if(ret != OO_OK) { @@ -2064,7 +2503,8 @@ int ooOnReceivedCloseLogicalChannel(OOH323CallData *call, call->callToken); return OO_FAILED; } - pctxt = &gH323ep.msgctxt; + /* pctxt = &gH323ep.msgctxt; */ + pctxt = call->msgctxt; ph245msg->msgType = OOCloseLogicalChannelAck; ph245msg->logicalChannelNo = clc->forwardLogicalChannelNumber; response = ph245msg->h245Msg.u.response; @@ -2144,13 +2584,23 @@ int ooHandleH245Message(OOH323CallData *call, H245Message * pmsg) case T_H245RequestMessage_openLogicalChannel: ooHandleOpenLogicalChannel(call, request->u.openLogicalChannel); + if(!ooGetTransmitLogicalChannel(call)) + ooOpenLogicalChannels(call); break; + case T_H245RequestMessage_requestMode: + OOTRACEINFO4("Received request mode - %d (%s, %s)\n", + request->u.requestMode->sequenceNumber, call->callType, call->callToken); + ooHandleRequestMode(call, + request->u.requestMode); + break; case T_H245RequestMessage_closeLogicalChannel: OOTRACEINFO4("Received close logical Channel - %d (%s, %s)\n", request->u.closeLogicalChannel->forwardLogicalChannelNumber, call->callType, call->callToken); - ooOnReceivedCloseLogicalChannel(call, - request->u.closeLogicalChannel); + if (ooOnReceivedCloseLogicalChannel(call, + request->u.closeLogicalChannel) == OO_OK) { + ooCloseAllLogicalChannels(call, NULL); + } break; case T_H245RequestMessage_requestChannelClose: OOTRACEINFO4("Received RequestChannelClose - %d (%s, %s)\n", @@ -2255,6 +2705,21 @@ int ooHandleH245Message(OOH323CallData *call, H245Message * pmsg) call->callEndReason = OO_REASON_NOCOMMON_CAPABILITIES; } break; + case T_H245ResponseMessage_requestModeAck: + if (call->requestSequence == response->u.requestModeAck->sequenceNumber) { + /* response to our last request, process it */ + ooOnReceivedRequestModeAck(call, response->u.requestModeAck); + } + break; + case T_H245ResponseMessage_requestModeReject: + OOTRACEDBGC3("Received requestModeReject, clearing call (%s, %s)\n", + call->callType, call->callToken); + if(call->callState < OO_CALL_CLEAR) + { + call->callState = OO_CALL_CLEAR; + call->callEndReason = OO_REASON_REMOTE_REJECTED; + } + break; case T_H245ResponseMessage_openLogicalChannelAck: for(i = 0; i<call->timerList.count; i++) { @@ -2319,6 +2784,8 @@ int ooHandleH245Message(OOH323CallData *call, H245Message * pmsg) } ooOnReceivedCloseChannelAck(call, response->u.closeLogicalChannelAck); + if(!ooGetTransmitLogicalChannel(call)) + ooOpenLogicalChannels(call); break; case T_H245ResponseMessage_requestChannelCloseAck: OOTRACEINFO4("RequestChannelCloseAck received - %d (%s, %s)\n", @@ -2408,6 +2875,24 @@ int ooOnReceivedUserInputIndication } else if((indication->t == T_H245UserInputIndication_signal) && (call->dtmfmode & OO_CAP_DTMF_H245_signal)) { + if(call->lastDTMF && indication->u.signal->signalType[0] == call->lastDTMF && + call->nextDTMFstamp && indication->u.signal->m.rtpPresent && + indication->u.signal->rtp.m.timestampPresent) { + if(call->nextDTMFstamp > indication->u.signal->rtp.timestamp) { + OOTRACEERR4("ERROR:Duplicate dtmf %c on ((%s, %s)\n", call->lastDTMF, call->callType, + call->callToken); + return OO_OK; + } + } + if (indication->u.signal->m.rtpPresent && indication->u.signal->rtp.m.timestampPresent && + indication->u.signal->m.durationPresent) { + call->nextDTMFstamp = indication->u.signal->rtp.timestamp + + indication->u.signal->duration; + call->lastDTMF = indication->u.signal->signalType[0]; + } else { + call->nextDTMFstamp = 0; + call->lastDTMF = 0; + } if(gH323ep.h323Callbacks.onReceivedDTMF) gH323ep.h323Callbacks.onReceivedDTMF(call, indication->u.signal->signalType); @@ -2427,7 +2912,7 @@ int ooOnReceivedTerminalCapabilitySet(OOH323CallData *call, H245Message *pmsg) H245CapabilityTableEntry *capEntry = NULL; tcs = pmsg->h245Msg.u.request->u.terminalCapabilitySet; - if(call->remoteTermCapSeqNo >= tcs->sequenceNumber) + if(call->remoteTermCapSeqNo > tcs->sequenceNumber) { OOTRACEINFO4("Rejecting TermCapSet message with SeqNo %d, as already " "acknowledged message with this SeqNo (%s, %s)\n", @@ -2435,6 +2920,16 @@ int ooOnReceivedTerminalCapabilitySet(OOH323CallData *call, H245Message *pmsg) ooSendTerminalCapabilitySetReject(call, tcs->sequenceNumber, T_H245TerminalCapabilitySetReject_cause_unspecified); return OO_OK; + + } else { +/* 20090924 */ +/* bogus soft-switch can send more than one request with cap set + if it goto to next choice. Right swith don't send but not all are right ;( + we can accept new capability set only. We must remember also that new join caps + will be previously joined caps with new cap set. + */ + if(call->remoteTermCapSeqNo == tcs->sequenceNumber) + call->localTermCapState = OO_LocalTermCapExchange_Idle; } if(!tcs->m.capabilityTablePresent) @@ -2474,6 +2969,10 @@ int ooOnReceivedTerminalCapabilitySet(OOH323CallData *call, H245Message *pmsg) } } + if (call->t38sides == 3) /* both side support t.38 */ + OO_SETFLAG(call->flags, OO_M_T38SUPPORTED); + else + OO_CLRFLAG(call->flags, OO_M_T38SUPPORTED); /* Update remoteTermCapSetState */ call->remoteTermCapState = OO_RemoteTermCapSetRecvd; @@ -2507,7 +3006,7 @@ int ooOnReceivedTerminalCapabilitySet(OOH323CallData *call, H245Message *pmsg) if(gH323ep.h323Callbacks.openLogicalChannels) gH323ep.h323Callbacks.openLogicalChannels(call); else{ - if(!call->logicalChans) + if(!ooGetTransmitLogicalChannel(call)) ooOpenLogicalChannels(call); } #if 0 @@ -2527,7 +3026,7 @@ int ooSendTerminalCapabilitySetReject H245Message *ph245msg=NULL; H245ResponseMessage * response=NULL; OOCTXT *pctxt=NULL; - int ret = ooCreateH245Message(&ph245msg, + int ret = ooCreateH245Message(call, &ph245msg, T_H245MultimediaSystemControlMessage_response); if(ret != OO_OK) { @@ -2538,7 +3037,8 @@ int ooSendTerminalCapabilitySetReject ph245msg->msgType = OOTerminalCapabilitySetReject; response = ph245msg->h245Msg.u.response; memset(response, 0, sizeof(H245ResponseMessage)); - pctxt = &gH323ep.msgctxt; + /* pctxt = &gH323ep.msgctxt; */ + pctxt = call->msgctxt; response->t = T_H245ResponseMessage_terminalCapabilitySetReject; response->u.terminalCapabilitySetReject = (H245TerminalCapabilitySetReject*) @@ -2570,7 +3070,7 @@ int ooH245AcknowledgeTerminalCapabilitySet(OOH323CallData *call) H245Message *ph245msg=NULL; H245ResponseMessage * response=NULL; OOCTXT *pctxt=NULL; - int ret = ooCreateH245Message(&ph245msg, + int ret = ooCreateH245Message(call, &ph245msg, T_H245MultimediaSystemControlMessage_response); if(ret != OO_OK) { @@ -2581,7 +3081,8 @@ int ooH245AcknowledgeTerminalCapabilitySet(OOH323CallData *call) ph245msg->msgType = OOTerminalCapabilitySetAck; response = ph245msg->h245Msg.u.response; memset(response, 0, sizeof(H245ResponseMessage)); - pctxt = &gH323ep.msgctxt; + /* pctxt = &gH323ep.msgctxt; */ + pctxt = call->msgctxt; response->t = T_H245ResponseMessage_terminalCapabilitySetAck; response->u.terminalCapabilitySetAck = (H245TerminalCapabilitySetAck*) @@ -2612,10 +3113,11 @@ int ooSendTerminalCapabilitySetRelease(OOH323CallData * call) int ret=0; H245IndicationMessage* indication=NULL; H245Message *ph245msg=NULL; - OOCTXT *pctxt=&gH323ep.msgctxt; + /* OOCTXT *pctxt=&gH323ep.msgctxt; */ + OOCTXT *pctxt=call->msgctxt; ret = ooCreateH245Message - (&ph245msg, T_H245MultimediaSystemControlMessage_indication); + (call, &ph245msg, T_H245MultimediaSystemControlMessage_indication); if (ret != OO_OK) { OOTRACEERR3("Error:H245 message creation failed for - Terminal" @@ -2662,10 +3164,11 @@ int ooSendH245UserInputIndication_alphanumeric int ret=0; H245IndicationMessage* indication=NULL; H245Message *ph245msg=NULL; - OOCTXT *pctxt=&gH323ep.msgctxt; + /* OOCTXT *pctxt=&gH323ep.msgctxt; */ + OOCTXT *pctxt=call->msgctxt; ret = ooCreateH245Message - (&ph245msg, T_H245MultimediaSystemControlMessage_indication); + (call, &ph245msg, T_H245MultimediaSystemControlMessage_indication); if (ret != OO_OK) { OOTRACEERR3("Error:H245 message creation failed for - H245UserInput" @@ -2721,10 +3224,11 @@ int ooSendH245UserInputIndication_signal int ret=0; H245IndicationMessage* indication=NULL; H245Message *ph245msg=NULL; - OOCTXT *pctxt=&gH323ep.msgctxt; + /* OOCTXT *pctxt=&gH323ep.msgctxt; */ + OOCTXT *pctxt=call->msgctxt; ret = ooCreateH245Message - (&ph245msg, T_H245MultimediaSystemControlMessage_indication); + (call, &ph245msg, T_H245MultimediaSystemControlMessage_indication); if (ret != OO_OK) { OOTRACEERR3("Error:H245 message creation failed for - H245UserInput" @@ -2788,21 +3292,20 @@ int ooOpenLogicalChannels(OOH323CallData *call) if(gH323ep.callMode == OO_CALLMODE_AUDIOCALL || gH323ep.callMode == OO_CALLMODE_AUDIOTX) { - //if (!OO_TESTFLAG (call->flags, OO_M_AUDIOSESSION)) - //{ + if (OO_TESTFLAG (call->flags, OO_M_AUDIOSESSION)) { ret = ooOpenLogicalChannel(call, OO_CAP_TYPE_AUDIO); - if(ret != OO_OK) - { - OOTRACEERR3("ERROR:Failed to open audio channels. Clearing call." - "(%s, %s)\n", call->callType, call->callToken); - if(call->callState < OO_CALL_CLEAR) - { - call->callEndReason = OO_REASON_LOCAL_CLEARED; - call->callState = OO_CALL_CLEAR; - } - return ret; - } - // } + } else if (OO_TESTFLAG (call->flags, OO_M_DATASESSION)) { + ret = ooOpenLogicalChannel(call, OO_CAP_TYPE_DATA); + } + if(ret != OO_OK) { + OOTRACEERR3("ERROR:Failed to open audio/data channels. Clearing call." + "(%s, %s)\n", call->callType, call->callToken); + if (call->callState < OO_CALL_CLEAR) { + call->callEndReason = OO_REASON_LOCAL_CLEARED; + call->callState = OO_CALL_CLEAR; + } + return ret; + } } if(gH323ep.callMode == OO_CALLMODE_VIDEOCALL) @@ -2860,6 +3363,7 @@ int ooOpenLogicalChannel(OOH323CallData *call, enum OOCapType capType ) */ OOTRACEINFO3("Looking for matching capabilities. (%s, %s)\n", call->callType, call->callToken); +/* May */ if(call->masterSlaveState == OO_MasterSlave_Master) { for(k=0; k<call->capPrefs.index; k++) @@ -2899,7 +3403,7 @@ int ooOpenLogicalChannel(OOH323CallData *call, enum OOCapType capType ) } } - else if(call->masterSlaveState == OO_MasterSlave_Slave) + else { epCap = call->jointCaps; @@ -2924,17 +3428,22 @@ int ooOpenLogicalChannel(OOH323CallData *call, enum OOCapType capType ) case OO_G711ALAW56K: case OO_G711ULAW64K: case OO_G711ULAW56K: - /*case OO_G726:*/ + case OO_G726: + case OO_G726AAL2: + case OO_AMRNB: + case OO_SPEEX: case OO_G728: case OO_G729: case OO_G729A: + case OO_G729B: case OO_G7231: case OO_GSMFULLRATE: + case OO_GSMHALFRATE: + case OO_GSMENHANCEDFULLRATE: case OO_H263VIDEO: + case OO_T38: ooOpenChannel(call, epCap); break; - case OO_GSMHALFRATE: - case OO_GSMENHANCEDFULLRATE: default: @@ -2953,6 +3462,7 @@ int ooOpenChannel(OOH323CallData* call, ooH323EpCapability *epCap) H245OpenLogicalChannel_forwardLogicalChannelParameters *flcp = NULL; H245AudioCapability *audioCap = NULL; H245VideoCapability *videoCap = NULL; + H245DataApplicationCapability *t38Cap = NULL; H245H2250LogicalChannelParameters *h2250lcp = NULL; H245UnicastAddress *unicastAddrs = NULL; H245UnicastAddress_iPAddress *iPAddress = NULL; @@ -2963,7 +3473,7 @@ int ooOpenChannel(OOH323CallData* call, ooH323EpCapability *epCap) ooGetCapTypeText(epCap->cap), call->callType, call->callToken); - ret = ooCreateH245Message(&ph245msg, + ret = ooCreateH245Message(call, &ph245msg, T_H245MultimediaSystemControlMessage_request); if(ret != OO_OK) { @@ -2980,7 +3490,8 @@ int ooOpenChannel(OOH323CallData* call, ooH323EpCapability *epCap) call->logicalChanNoCur = call->logicalChanNoBase; request = ph245msg->h245Msg.u.request; - pctxt = &gH323ep.msgctxt; + /* pctxt = &gH323ep.msgctxt; */ + pctxt = call->msgctxt; memset(request, 0, sizeof(H245RequestMessage)); request->t = T_H245RequestMessage_openLogicalChannel; @@ -3053,6 +3564,23 @@ int ooOpenChannel(OOH323CallData* call, ooH323EpCapability *epCap) flcp->dataType.u.videoData = videoCap; } + else if(epCap->capType == OO_CAP_TYPE_DATA) + { + flcp->dataType.t = T_H245DataType_data; + /* set audio capability for channel */ + t38Cap = ooCapabilityCreateT38Capability(epCap,pctxt, OOTX); + if(!t38Cap) + { + OOTRACEERR4("Error:Failed to create duplicate T38 capability in " + "ooOpenChannel- %s (%s, %s)\n", + ooGetCapTypeText(epCap->cap), call->callType, + call->callToken); + ooFreeH245Message(call, ph245msg); + return OO_FAILED; + } + + flcp->dataType.u.data = t38Cap; + } else{ OOTRACEERR1("Error: Unhandled media type in ooOpenChannel\n"); return OO_FAILED; @@ -3104,7 +3632,7 @@ int ooOpenChannel(OOH323CallData* call, ooH323EpCapability *epCap) } ooFreeH245Message(call, ph245msg); - return ret; + return ret; } @@ -3362,7 +3890,7 @@ int ooBuildFastStartOLC else { /* Calling other ep, with SETUP message */ /* Call is "outgoing */ - pLogicalChannel->state = OO_LOGICALCHAN_PROPOSED; + pLogicalChannel->state = OO_LOGICALCHAN_PROPOSEDFS; } return OO_OK; @@ -3447,13 +3975,20 @@ int ooCloseLogicalChannelTimerExpired(void *pdata) int ooRequestChannelCloseTimerExpired(void *pdata) { int ret = 0; + ooLogicalChannel *pChannel = NULL; ooTimerCallback *cbData = (ooTimerCallback*)pdata; OOH323CallData *call = cbData->call; - OOTRACEINFO3("OpenLogicalChannelTimer expired. (%s, %s)\n", call->callType, + OOTRACEINFO3("CloseLogicalChannelTimer expired. (%s, %s)\n", call->callType, call->callToken); - ooSendRequestChannelCloseRelease(call, cbData->channelNumber); + pChannel = ooFindLogicalChannelByLogicalChannelNo(call, + cbData->channelNumber); + if(pChannel) + ooSendRequestChannelCloseRelease(call, cbData->channelNumber); + else + return OO_OK; + ret = ooClearLogicalChannel(call, cbData->channelNumber); if(ret != OO_OK) @@ -3507,6 +4042,7 @@ int ooGetIpPortFromH245TransportAddress { H245UnicastAddress *unicastAddress = NULL; H245UnicastAddress_iPAddress *ipAddress = NULL; + regmatch_t pmatch[1]; if(h245Address->t != T_H245TransportAddress_unicastAddress) { @@ -3530,6 +4066,14 @@ int ooGetIpPortFromH245TransportAddress ipAddress->network.data[1], ipAddress->network.data[2], ipAddress->network.data[3]); + if (call->rtpMaskStr[0]) { + if (regexec(&call->rtpMask->regex, ip, 1, pmatch, 0)) { + OOTRACEERR5("ERROR:H245 Address is not matched with filter %s/%s" + "(%s, %s)\n", ip, call->rtpMaskStr, call->callType, call->callToken); + return OO_FAILED; + } + } + return OO_OK; } |