794 lines
22 KiB
C
794 lines
22 KiB
C
/***********************************************************************
|
||
* *
|
||
* 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;
|
||
}
|
||
|