Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

794 lines
23 KiB

/***********************************************************************
* *
* Filename: mstrslv.c *
* Module: H245 Finite State Machine Subsystem *
* *
***********************************************************************
* INTEL Corporation Proprietary Information *
* *
* This listing is supplied under the terms of a license agreement *
* with INTEL Corporation and may not be copied nor disclosed except *
* in accordance with the terms of that agreement. *
* *
* Copyright (c) 1996 Intel Corporation. All rights reserved. *
***********************************************************************
* *
* $Workfile: mstrslv.c $
* $Revision: 1.12 $
* $Modtime: 12 Dec 1996 14:37:12 $
* $Log: S:/STURGEON/SRC/H245/SRC/VCS/mstrslv.c_v $
*
* Rev 1.12 12 Dec 1996 15:52:50 EHOWARDX
* Master Slave Determination kludge.
*
* Rev 1.11 11 Dec 1996 16:50:50 EHOWARDX
* Went back to original Master/Slave determination algorithm.
*
* Rev 1.10 09 Dec 1996 13:34:48 EHOWARDX
* Updated copyright notice.
*
* Rev 1.9 26 Nov 1996 17:06:02 EHOWARDX
* Reversed order of subtraction for DetermineMasterSlave.
*
* Rev 1.8 08 Aug 1996 16:03:40 EHOWARDX
*
* Fixed master slave determinate bug (hopefully the last one!)
*
* Rev 1.7 19 Jul 1996 12:12:44 EHOWARDX
*
* Changed to use API events defined in H245API.H instead of FSM events
* which are no longer defined in FSMEXPOR.H.
*
* Rev 1.6 01 Jul 1996 23:35:48 EHOWARDX
* MSDetAckIncoming bug - was sending indication instead of confirm.
*
* Rev 1.5 01 Jul 1996 23:14:20 EHOWARDX
* Fixed bug in MSDetOutgoing -- state change was ifdefed out.
*
* Rev 1.4 07 Jun 1996 16:00:26 EHOWARDX
* Fixed bug with pOut not getting freed in msDetOutgoing.
*
* Rev 1.3 07 Jun 1996 15:40:20 EHOWARDX
* Fixed bug in msDetRejOutgoing; pOut was not freed if N100 count exceeded.
*
* Rev 1.2 04 Jun 1996 13:57:54 EHOWARDX
* Fixed Release build warnings.
*
* Rev 1.1 30 May 1996 23:39:16 EHOWARDX
* Cleanup.
*
* Rev 1.0 09 May 1996 21:06:32 EHOWARDX
* Initial revision.
*
* Rev 1.11.1.4 09 May 1996 19:48:48 EHOWARDX
* Change TimerExpiryF function arguements.
*
* Rev 1.11.1.3 25 Apr 1996 17:00:22 EHOWARDX
* Minor fixes.
*
* Rev 1.11.1.2 15 Apr 1996 10:45:46 EHOWARDX
* Update.
*
* Rev 1.11.1.1 10 Apr 1996 21:15:46 EHOWARDX
* Check-in for safety in middle of re-design.
* *
***********************************************************************/
#include "precomp.h"
#include "h245api.h"
#include "h245com.h"
#include "h245fsm.h"
#include "mstrslv.h"
#include "pdu.x"
// Master Slave Determination states
#define MSIDLE 0
#define MSOutgoingAwaiting 1
#define MSIncomingAwaiting 2
#define MAX_RAND 0x00FFFFFF
extern unsigned int uN100;
extern unsigned int uT106;
/***********************************************************************
*
* LOCAL FUNCTIONS
*
***********************************************************************/
/*
* NAME
* T106ExpiryF - Callback function called by the timer.
*
*
* PARAMETERS
* INPUT dwInst current instance of H245
* INPUT id timer id
* INPUT pObject pointer to a State Entity
*
*
* RETURN VALUE
* OK
*/
int T106ExpiryF(struct InstanceStruct *pInstance, DWORD_PTR dwTimerId, void *pObject)
{
return FsmTimerEvent(pInstance, dwTimerId, pObject, T106Expiry);
} // T106ExpiryF()
#define GetTerminal(pObject) (pObject)->pInstance->StateMachine.sv_TT
#define GetStatus(pObject) (pObject)->pInstance->StateMachine.sv_STATUS
#define SetStatus(pObject, Status) (pObject)->pInstance->StateMachine.sv_STATUS = (Status)
#define GetRandomNumber(pObject) (pObject)->u.msdse.sv_SDNUM
#define SetRandomNumber(pObject, uRandom) (pObject)->u.msdse.sv_SDNUM = (uRandom)
#define GetCount(pObject) (pObject)->u.msdse.sv_NCOUNT
#define SetCount(pObject, uCount) (pObject)->u.msdse.sv_NCOUNT = (uCount)
/*
* NAME
* DetermineStatus - determines whether the terminal is a master or a slave or neither
*
*
* PARAMETERS
* INPUT pdu pointer to a PDU structure
*
* RETURN VALUE
* terminal status
*/
static MS_Status_t DetermineStatus(Object_t *pObject, PDU_t *pPdu)
{
unsigned int uTemp;
unsigned char sv_TT = GetTerminal(pObject);
if (pPdu->u.MltmdSystmCntrlMssg_rqst.u.masterSlaveDetermination.terminalType < sv_TT)
return pObject->pInstance->StateMachine.sv_STATUS = MASTER;
if (pPdu->u.MltmdSystmCntrlMssg_rqst.u.masterSlaveDetermination.terminalType > sv_TT)
return pObject->pInstance->StateMachine.sv_STATUS = SLAVE;
uTemp = (pPdu->u.MltmdSystmCntrlMssg_rqst.u.masterSlaveDetermination.statusDeterminationNumber - GetRandomNumber(pObject)) & 0xFFFFFF;
if (uTemp > 0x800000)
return pObject->pInstance->StateMachine.sv_STATUS = SLAVE;
if (uTemp < 0x800000 && uTemp != 0)
return pObject->pInstance->StateMachine.sv_STATUS = MASTER;
return pObject->pInstance->StateMachine.sv_STATUS = INDETERMINATE;
}
/***********************************************************************
*
* FINITE STATE MACHINE FUNCTIONS
*
***********************************************************************/
/*
* NAME
* detRequestIdle - request Master/Slave Determination from API in idle state
*
*
* PARAMETERS
* INPUT pObject pointer to a State Entity
*
* RETURN VALUE
* error return codes defined in h245com.h
*/
HRESULT detRequestIdle(Object_t *pObject, PDU_t *pPdu)
{
HRESULT lError;
ASSERT(pObject->Entity == MSDSE);
ASSERT(pObject->State == MSIDLE);
SetRandomNumber(pObject, GetTickCount() & MAX_RAND);
SetCount(pObject, 1); // Initialize retry counter
SetStatus(pObject, INDETERMINATE);
H245TRACE( pObject->dwInst, 2,
"detRequestIdle: TerminalType=%d StatusDeterminationNumber=%d",
GetTerminal(pObject), GetRandomNumber(pObject));
/* Send a Master/Slave determination PDU */
H245TRACE(pObject->dwInst, 2, "Master/Slave Determination to Send/Rec module");
pdu_req_mstslv (pPdu, GetTerminal(pObject), GetRandomNumber(pObject));
lError = sendPDU(pObject->pInstance, pPdu);
/* set timer T106 */
pObject->State = MSOutgoingAwaiting;
FsmStartTimer(pObject, T106ExpiryF, uT106);
return lError;
} // detRequestIdle()
/*
* NAME
* msDetIdle - received Master/Slave Determination PDU in idle state
*
*
* PARAMETERS
* INPUT pObject pointer to a State Entity
*
* RETURN VALUE
* error return codes defined in h245com.h
*/
HRESULT msDetIdle(Object_t *pObject, PDU_t *pPdu)
{
PDU_t * pOut;
HRESULT lError;
ASSERT(pObject->Entity == MSDSE);
ASSERT(pObject->State == MSIDLE);
pOut = (PDU_t *) MemAlloc(sizeof(PDU_t));
if (pOut == NULL)
{
DetermineStatus(pObject, pPdu);
return H245_ERROR_NOMEM;
}
SetRandomNumber(pObject, GetTickCount() & MAX_RAND);
switch (DetermineStatus(pObject, pPdu))
{
case MASTER:
/* Build MasterSlave Determination Ack */
H245TRACE(pObject->dwInst, 2, "msDetIdle: sending Ack: SLAVE");
pdu_rsp_mstslv_ack(pOut, slave_chosen);
break;
case SLAVE:
/* Build MasterSlave Determination Ack */
H245TRACE(pObject->dwInst, 2, "msDetIdle: sending Ack: MASTER");
pdu_rsp_mstslv_ack(pOut, master_chosen);
break;
default:
/* Send a masterSlaveDet Reject */
pdu_rsp_mstslv_rej(pOut);
lError = sendPDU(pObject->pInstance, pOut);
MemFree(pOut);
return lError;
} // switch
/* Send MasterSlave Determination Ack to remote */
lError = sendPDU(pObject->pInstance, pOut);
MemFree(pOut);
pObject->State = MSIncomingAwaiting;
#if defined(SDL_COMPLIANT)
/* Send DETERMINE indication to client - unnecessary */
H245FsmIndication(pPdu, H245_IND_MSTSLV, pObject->pInstance, pObject->dwTransId, FSM_OK);
#endif
/* set timer T106 */
FsmStartTimer(pObject, T106ExpiryF, uT106);
return lError;
}
/*
* NAME
* msDetAckOutgoing - received Master/Slave Determination Ack pdu in outgoing state
*
*
* PARAMETERS
* INPUT pObject pointer to a State Entity
*
* RETURN VALUE
* error return codes defined in h245com.h
*/
HRESULT msDetAckOutgoing(Object_t *pObject, PDU_t *pPdu)
{
PDU_t * pOut;
HRESULT lError;
ASSERT(pObject->Entity == MSDSE);
ASSERT(pObject->State == MSOutgoingAwaiting);
pOut = (PDU_t *) MemAlloc(sizeof(PDU_t));
if (pOut == NULL)
{
return H245_ERROR_NOMEM;
}
/* reset timer */
FsmStopTimer(pObject);
/* Decision is opposite of MasterSlaveDeterminationAck.decision */
switch(pPdu->u.MSCMg_rspns.u.mstrSlvDtrmntnAck.decision.choice)
{
case master_chosen:
pObject->pInstance->StateMachine.sv_STATUS = MASTER;
H245TRACE(pObject->dwInst, 2, "msDetAckOutgoing: sending Ack: SLAVE");
pdu_rsp_mstslv_ack(pOut, slave_chosen);
break;
case slave_chosen:
pObject->pInstance->StateMachine.sv_STATUS = SLAVE;
H245TRACE(pObject->dwInst, 2, "msDetAckOutgoing: sending Ack: MASTER");
pdu_rsp_mstslv_ack(pOut, master_chosen);
break;
default:
H245TRACE(pObject->dwInst, 1, "msDetAckOutgoing: Invalid Master Slave Determination Ack received");
return H245_ERROR_PARAM;
}
/* Send MasterSlave Determination Ack to remote */
lError = sendPDU(pObject->pInstance, pOut);
MemFree(pOut);
/* Send DETERMINE confirm to client */
pObject->State = MSIDLE;
H245FsmConfirm(pPdu, H245_CONF_INIT_MSTSLV, pObject->pInstance, pObject->dwTransId, FSM_OK);
return lError;
}
/*
* NAME
* msDetOutgoing- received Master/Slave Determination pdu in outgoing state
*
*
* PARAMETERS
* INPUT pObject pointer to a State Entity
*
* RETURN VALUE
* error return codes defined in h245com.h
*/
HRESULT msDetOutgoing(Object_t *pObject, PDU_t *pPdu)
{
PDU_t * pOut;
HRESULT lError;
ASSERT(pObject->Entity == MSDSE);
ASSERT(pObject->State == MSOutgoingAwaiting);
if (pObject->pInstance->bMasterSlaveKludge == 0)
{
// Ignore this message
return NOERROR;
}
pOut = (PDU_t *) MemAlloc(sizeof(PDU_t));
if (pOut == NULL)
{
return H245_ERROR_NOMEM;
}
/* reset timer T106 */
FsmStopTimer(pObject);
switch (DetermineStatus(pObject, pPdu))
{
case MASTER:
H245TRACE(pObject->dwInst, 2, "msDetOutgoing: sending Ack: SLAVE");
pdu_rsp_mstslv_ack(pOut, slave_chosen);
break;
case SLAVE:
H245TRACE(pObject->dwInst, 2, "msDetOutgoing: sending Ack: MASTER");
pdu_rsp_mstslv_ack(pOut, master_chosen);
break;
default:
if (GetCount(pObject) >= uN100)
{
MemFree(pOut);
/* Send ERROR.indication(F) to client */
H245TRACE(pObject->dwInst, 2, "msDetOutgoing: Counter expired; Session Failed");
H245FsmConfirm(NULL,H245_CONF_INIT_MSTSLV, pObject->pInstance, pObject->dwTransId, MS_FAILED);
/* Send REJECT.indication to client - unnecessary */
pObject->State = MSIDLE;
lError = 0;
}
else
{
/* generate a new random number */
H245TRACE(pObject->dwInst, 2, "Resending MasterSlaveDetermination");
SetRandomNumber(pObject, GetTickCount() & MAX_RAND);
SetCount(pObject, GetCount(pObject) + 1);
/* Send MasterSlave Determination PDU to remote */
pdu_req_mstslv (pOut, GetTerminal(pObject), GetRandomNumber(pObject));
lError = sendPDU(pObject->pInstance, pOut);
MemFree(pOut);
/* set timer T106 */
pObject->State = MSOutgoingAwaiting;
FsmStartTimer(pObject, T106ExpiryF, uT106);
}
return lError;
} // switch
/* Send MasterSlave Determination Ack to remote */
lError = sendPDU(pObject->pInstance, pOut);
MemFree(pOut);
pObject->State = MSIncomingAwaiting;
#if defined(SDL_COMPLIANT)
/* Send DETERMINE indication to client */
H245FsmIndication(pPdu, H245_IND_MSTSLV, pObject->pInstance, pObject->dwTransId, FSM_OK);
#endif
/* set timer T106 */
FsmStartTimer(pObject, T106ExpiryF, uT106);
return lError;
}
/*
* NAME
* msDetRejOutgoing- received Master/Slave Determination Reject pdu in outgoing state
*
*
* PARAMETERS
* INPUT pObject pointer to a State Entity
*
* RETURN VALUE
* error return codes defined in h245com.h
*/
HRESULT msDetRejOutgoing(Object_t *pObject, PDU_t *pPdu)
{
PDU_t * pOut;
HRESULT lError;
ASSERT(pObject->Entity == MSDSE);
ASSERT(pObject->State == MSOutgoingAwaiting);
pOut = (PDU_t *) MemAlloc(sizeof(PDU_t));
if (pOut == NULL)
{
return H245_ERROR_NOMEM;
}
/* reset timer T106 */
FsmStopTimer(pObject);
if (GetCount(pObject) >= uN100)
{
MemFree(pOut);
H245TRACE(pObject->dwInst, 2, "msDetRejOutgoing: Counter expired; Session Failed");
pObject->State = MSIDLE;
/* Send ERROR.indication(f) to client */
H245FsmConfirm(pPdu,H245_CONF_INIT_MSTSLV, pObject->pInstance, pObject->dwTransId, MS_FAILED);
#if defined(SDL_COMPLIANT)
/* Send REJECT.indication to client - not necessary */
H245FsmIndication(NULL, H245_IND_MSTSLV, pObject->pInstance, pObject->dwTransId, REJECT);
#endif
lError = 0;
}
else
{
H245TRACE(pObject->dwInst, 2, "msDetRejOutgoint: Re-sending a MasterSlaveDetermination");
/* generate a new random number */
SetRandomNumber(pObject, GetTickCount() & MAX_RAND);
SetCount(pObject, GetCount(pObject) + 1);
/* Send MasterSlave Determination PDU to remote */
pdu_req_mstslv (pOut, GetTerminal(pObject), GetRandomNumber(pObject));
lError = sendPDU(pObject->pInstance,pOut);
MemFree(pOut);
/* set timer T106 */
FsmStartTimer(pObject, T106ExpiryF, uT106);
}
return lError;
}
/*
* NAME
* msDetReleaseOutgoing- received Master/Slave Determination release pdu in outgoing state
*
*
* PARAMETERS
* INPUT pObject pointer to a State Entity
*
* RETURN VALUE
* error return codes defined in h245com.h
*/
HRESULT msDetReleaseOutgoing(Object_t *pObject, PDU_t *pPdu)
{
ASSERT(pObject->Entity == MSDSE);
ASSERT(pObject->State == MSOutgoingAwaiting);
H245TRACE(pObject->dwInst, 2, "msDetReleaseOutgoing: Master/Slave Determination Release received; session failed");
/* reset timer T106 */
FsmStopTimer(pObject);
/* Send ERROR.indication(B) to client */
pObject->State = MSIDLE;
H245FsmConfirm(pPdu, H245_CONF_INIT_MSTSLV, pObject->pInstance, pObject->dwTransId, MS_FAILED);
#if defined(SDL_COMPLIANT)
/* Send REJECT.indication to client - not necessary */
H245FsmIndication(NULL, H245_IND_MSTSLV, pObject->pInstance, pObject->dwTransId, REJECT);
#endif
return 0;
}
/*
* NAME
* t106ExpiryOutgoing- timer expired for an outgoing M/S determination pdu
*
*
* PARAMETERS
* INPUT pObject pointer to a State Entity
*
* RETURN VALUE
* error return codes defined in h245com.h
*/
HRESULT t106ExpiryOutgoing(Object_t *pObject, PDU_t *pPdu)
{
PDU_t * pOut;
HRESULT lError;
ASSERT(pObject->Entity == MSDSE);
ASSERT(pObject->State == MSOutgoingAwaiting);
ASSERT(pPdu == NULL);
H245TRACE(pObject->dwInst, 2, "t106ExpiryOutgoing: Timer expired before receiving Ack; session failed");
pOut = (PDU_t *) MemAlloc(sizeof(PDU_t));
if (pOut == NULL)
{
return H245_ERROR_NOMEM;
}
/* Send MasterSlave Determination Release to remote */
pOut->choice = indication_chosen;
pOut->u.indication.choice = mstrSlvDtrmntnRls_chosen;
lError = sendPDU(pObject->pInstance, pOut);
MemFree(pOut);
/* Send ERROR.indication(A) to client */
pObject->State = MSIDLE;
H245FsmConfirm(NULL,H245_CONF_INIT_MSTSLV, pObject->pInstance, pObject->dwTransId, TIMER_EXPIRY);
#if defined(SDL_COMPLIANT)
/* Send REJECT.indication to client - not necessary */
H245FsmIndication(NULL, H245_IND_MSTSLV, pObject->pInstance, pObject->dwTransId, REJECT);
#endif
return lError;
}
/*
* NAME
* msDetAckIncoming- received Master/Slave Determination Ack pdu in incoming state
*
*
* PARAMETERS
* INPUT pObject pointer to a State Entity
*
* RETURN VALUE
* error return codes defined in h245com.h
*/
HRESULT msDetAckIncoming(Object_t *pObject, PDU_t *pPdu)
{
ASSERT(pObject->Entity == MSDSE);
ASSERT(pObject->State == MSIncomingAwaiting);
/* reset timer T106 */
FsmStopTimer(pObject);
switch (GetStatus(pObject))
{
case master_chosen:
if (pPdu->u.MSCMg_rspns.u.mstrSlvDtrmntnAck.decision.choice == master_chosen)
{
H245TRACE(pObject->dwInst, 2, "msDetAckIncoming: Terminal is a MASTER");
/* Send DETERMINE.confirm to client */
pObject->State = MSIDLE;
H245FsmConfirm(pPdu, H245_CONF_INIT_MSTSLV, pObject->pInstance, pObject->dwTransId, FSM_OK);
return 0;
}
break;
case slave_chosen:
if (pPdu->u.MSCMg_rspns.u.mstrSlvDtrmntnAck.decision.choice == slave_chosen)
{
H245TRACE(pObject->dwInst, 2, "msDetAckIncoming: Terminal is a SLAVE");
/* Send DETERMINE.confirm to client */
pObject->State = MSIDLE;
H245FsmConfirm(pPdu, H245_CONF_INIT_MSTSLV, pObject->pInstance, pObject->dwTransId, FSM_OK);
return 0;
}
break;
default:
H245TRACE(pObject->dwInst, 2, "msDetAckIncoming: Invalid MasterSlave Determination Ack received");
return H245_ERROR_PARAM;
} // switch
H245TRACE(pObject->dwInst, 2, "msDetAckIncoming: bad decision in MasterSlave Determination Ack; Session failed");
/* Send ERROR.indication(E) to client */
pObject->State = MSIDLE;
H245FsmConfirm(pPdu, H245_CONF_INIT_MSTSLV, pObject->pInstance, pObject->dwTransId, SESSION_FAILED);
#if defined(SDL_COMPLIANT)
/* Send REJECT.indication to client - not necessary */
H245FsmIndication(NULL, H245_IND_MSTSLV, pObject->pInstance, pObject->dwTransId, REJECT);
#endif
return 0;
}
/*
* NAME
* msDetIncoming- received Master/Slave Determination pdu in incoming state
*
*
* PARAMETERS
* INPUT pObject pointer to a State Entity
*
* RETURN VALUE
* error return codes defined in h245com.h
*/
HRESULT msDetIncoming(Object_t *pObject, PDU_t *pPdu)
{
ASSERT(pObject->Entity == MSDSE);
ASSERT(pObject->State == MSIncomingAwaiting);
H245TRACE(pObject->dwInst, 2, "msDetIncoming: received MasterSlave Determination in INCOMING state; Session failed");
/* reset timer T106 */
FsmStopTimer(pObject);
/* Send ERROR.indication(C) to client */
pObject->State = MSIDLE;
H245FsmIndication(pPdu,H245_IND_MSTSLV, pObject->pInstance, pObject->dwTransId, MS_FAILED);
#if defined(SDL_COMPLIANT)
/* Send REJECT.indication to client - not necessary */
H245FsmIndication(NULL, H245_IND_MSTSLV, pObject->pInstance, pObject->dwTransId, REJECT);
#endif
return 0;
}
/*
* NAME
* msDetRejIncoming- received Master/Slave Determination Reject pdu in incoming state
*
*
* PARAMETERS
* INPUT pObject pointer to a State Entity
*
* RETURN VALUE
* error return codes defined in h245com.h
*/
HRESULT msDetRejIncoming(Object_t *pObject, PDU_t *pPdu)
{
ASSERT(pObject->Entity == MSDSE);
ASSERT(pObject->State == MSIncomingAwaiting);
H245TRACE(pObject->dwInst, 2, "msDetRejIncoming: received MasterSlave Reject: Session Failed");
/* reset timer T106 */
FsmStopTimer(pObject);
/* Send ERROR.indication(D) to client */
pObject->State = MSIDLE;
H245FsmIndication(pPdu,H245_IND_MSTSLV, pObject->pInstance, pObject->dwTransId, MS_FAILED);
#if defined(SDL_COMPLIANT)
/* Send REJECT.indication to client - not necessary */
H245FsmIndication(NULL, H245_IND_MSTSLV, pObject->pInstance, pObject->dwTransId, REJECT);
#endif
return 0;
}
/*
* NAME
* msDetReleaseIncoming- received Master/Slave Determination Release pdu in incoming state
*
*
* PARAMETERS
* INPUT pObject pointer to a State Entity
*
* RETURN VALUE
* error return codes defined in h245com.h
*/
HRESULT msDetReleaseIncoming(Object_t *pObject, PDU_t *pPdu)
{
ASSERT(pObject->Entity == MSDSE);
ASSERT(pObject->State == MSIncomingAwaiting);
H245TRACE(pObject->dwInst, 2, "msDetReleaseIncoming: received MasterSlave Release; Session Failed");
/* reset timer T106 */
FsmStopTimer(pObject);
/* Send ERROR.indication(B) to client */
pObject->State = MSIDLE;
H245FsmIndication(pPdu,H245_IND_MSTSLV, pObject->pInstance, pObject->dwTransId, MS_FAILED);
#if defined(SDL_COMPLIANT)
/* Send REJECT.indication to client - not necessary */
H245FsmIndication(NULL, H245_IND_MSTSLV, pObject->pInstance, pObject->dwTransId, REJECT);
#endif
return 0;
}
/*
* NAME
* t106ExpiryIncoming - timer expired while waiting for second Ack
*
*
* PARAMETERS
* INPUT pObject pointer to a State Entity
*
* RETURN VALUE
* error return codes defined in h245com.h
*/
HRESULT t106ExpiryIncoming(Object_t *pObject, PDU_t *pPdu)
{
ASSERT(pObject->Entity == MSDSE);
ASSERT(pObject->State == MSIncomingAwaiting);
ASSERT(pPdu == NULL);
H245TRACE(pObject->dwInst, 2, "t106ExpiryIncoming: timer expired waiting for Ack; Session failed");
/* Send ERROR.indication(A) to client */
pObject->State = MSIDLE;
H245FsmIndication(NULL, H245_IND_MSTSLV, pObject->pInstance, pObject->dwTransId, TIMER_EXPIRY);
#if defined(SDL_COMPLIANT)
/* Send REJECT.indication to client - not necessary */
H245FsmIndication(NULL, H245_IND_MSTSLV, pObject->pInstance, pObject->dwTransId, REJECT);
#endif
return 0;
}