/*********************************************************************** * * * Filename: mrse.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: mrse.c $ * $Revision: 1.5 $ * $Modtime: 13 Feb 1997 19:25:48 $ * $Log: S:/STURGEON/SRC/H245/SRC/VCS/mrse.c_v $ * * Rev 1.5 13 Feb 1997 19:31:20 MANDREWS * Fixed bug in generation of request mode ack and request mode reject; * the sequence number was not being copied into the pdu. * * Rev 1.4 09 Dec 1996 13:34:46 EHOWARDX * Updated copyright notice. * * Rev 1.3 04 Jun 1996 14:01:06 EHOWARDX * Fixed Release build warnings. * * Rev 1.2 30 May 1996 23:39:16 EHOWARDX * Cleanup. * * Rev 1.1 28 May 1996 14:25:44 EHOWARDX * Tel Aviv update. * * Rev 1.0 09 May 1996 21:06:32 EHOWARDX * Initial revision. * * Rev 1.1 09 May 1996 19:48:08 EHOWARDX * Change TimerExpiryF function arguements. * * Rev 1.0 15 Apr 1996 10:44:52 EHOWARDX * Initial revision. * * ***********************************************************************/ #include "precomp.h" #include "h245api.h" #include "h245com.h" #include "h245fsm.h" #include "mrse.h" // Out-going/In-coming MRSE states #define MRSE_IDLE 0 // IDLE #define MRSE_WAIT 1 // AWAITING_RESPONSE extern unsigned int uT109; /*********************************************************************** * * LOCAL FUNCTIONS * ***********************************************************************/ /* * NAME * T109ExpiryF - 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 T109ExpiryF(struct InstanceStruct *pInstance, DWORD_PTR dwTimerId, void *pObject) { return FsmTimerEvent(pInstance, dwTimerId, pObject, T109Expiry); } // T109ExpiryF() /*********************************************************************** * * OUT-GOING FINITE STATE MACHINE FUNCTIONS * ***********************************************************************/ /* * NAME * MRSE0_TRANSFER_requestF - TRANSFER.request from API in IDLE state * * * PARAMETERS * INPUT pObject pointer to State Entity * INPUT pPdu pointer to PDU * * RETURN VALUE * Error return codes defined in h245com.h */ HRESULT MRSE0_TRANSFER_requestF (Object_t *pObject, PDU_t *pPdu) { HRESULT lError; ASSERT(pObject->Entity == MRSE_OUT); ASSERT(pObject->State == MRSE_IDLE); H245TRACE(pObject->dwInst, 2, "MRSE0_TRANSFER_request:%d", pObject->Key); pObject->pInstance->StateMachine.byMrseOutSequence++; pPdu->u.MltmdSystmCntrlMssg_rqst.u.requestMode.sequenceNumber = pObject->pInstance->StateMachine.byMrseOutSequence; // Send Request Mode PDU to remote lError = sendPDU(pObject->pInstance, pPdu); // Set timer T109 pObject->State = MRSE_WAIT; FsmStartTimer(pObject, T109ExpiryF, uT109); return lError; } // MRSE0_TRANSFER_request /* * NAME * MRSE1_TRANSFER_requestF - TRANSFER.request from API in AWAITING RESPONSE state * * * PARAMETERS * INPUT pObject pointer to State Entity * INPUT pPdu pointer to PDU * * RETURN VALUE * Error return codes defined in h245com.h */ HRESULT MRSE1_TRANSFER_requestF (Object_t *pObject, PDU_t *pPdu) { HRESULT lError; ASSERT(pObject->Entity == MRSE_OUT); ASSERT(pObject->State == MRSE_WAIT); H245TRACE(pObject->dwInst, 2, "MRSE1_TRANSFER_request:%d", pObject->Key); // Reset timer T109 FsmStopTimer(pObject); pObject->pInstance->StateMachine.byMrseOutSequence++; pPdu->u.MltmdSystmCntrlMssg_rqst.u.requestMode.sequenceNumber = pObject->pInstance->StateMachine.byMrseOutSequence; // Send Request Mode PDU to remote lError = sendPDU(pObject->pInstance, pPdu); // Set timer T109 FsmStartTimer(pObject, T109ExpiryF, uT109); return lError; } // MRSE1_TRANSFER_request /* * NAME * MRSE1_RequestModeAckF - RequestModeAck in AWAITING RESPONSE state * * * PARAMETERS * INPUT pObject pointer to State Entity * INPUT pPdu pointer to PDU * * RETURN VALUE * Error return codes defined in h245com.h */ HRESULT MRSE1_RequestModeAckF (Object_t *pObject, PDU_t *pPdu) { ASSERT(pObject->Entity == MRSE_OUT); ASSERT(pObject->State == MRSE_WAIT); H245TRACE(pObject->dwInst, 2, "MRSE1_RequestModeAck:%d", pObject->Key); if (pPdu->u.MSCMg_rspns.u.requestModeAck.sequenceNumber == pObject->pInstance->StateMachine.byMrseOutSequence) { // Reset timer T109 FsmStopTimer(pObject); // Send TRANSFER.confirm to H.245 user pObject->State = MRSE_IDLE; H245FsmConfirm(pPdu, H245_CONF_MRSE, pObject->pInstance, pObject->dwTransId, FSM_OK); } return 0; } // MRSE1_RequestModeAck /* * NAME * MRSE1_RequestModeRejF - RequestModeReject in AWAITING RESPONSE state * * * PARAMETERS * INPUT pObject pointer to State Entity * INPUT pPdu pointer to PDU * * RETURN VALUE * Error return codes defined in h245com.h */ HRESULT MRSE1_RequestModeRejF (Object_t *pObject, PDU_t *pPdu) { ASSERT(pObject->Entity == MRSE_OUT); ASSERT(pObject->State == MRSE_WAIT); H245TRACE(pObject->dwInst, 2, "MRSE0_RequestModeRej:%d", pObject->Key); if (pPdu->u.MSCMg_rspns.u.requestModeReject.sequenceNumber == pObject->pInstance->StateMachine.byMrseOutSequence) { // Reset timer T109 FsmStopTimer(pObject); // Send REJECT.indication to H.245 user // CAUSE = RequestModeReject.cause pObject->State = MRSE_IDLE; H245FsmConfirm(pPdu, H245_CONF_MRSE_REJECT, pObject->pInstance, pObject->dwTransId, FSM_OK); } return 0; } // MRSE1_RequestModeRej /* * NAME * MRSE1_T109ExpiryF - timer T109 Expiry * * * PARAMETERS * INPUT pObject pointer to State Entity * INPUT pPdu pointer to PDU * * RETURN VALUE * Error return codes defined in h245com.h */ HRESULT MRSE1_T109ExpiryF (Object_t *pObject, PDU_t *pPdu) { HRESULT lError; PDU_t * pOut; unsigned short wNumber = (unsigned short) pObject->Key; ASSERT(pObject->Entity == MRSE_OUT); ASSERT(pObject->State == MRSE_WAIT); ASSERT(pPdu == NULL); H245TRACE(pObject->dwInst, 2, "MRSE1_T109Expiry:%d", pObject->Key); // Send RequestModeRelease PDU to remote peer pOut = MemAlloc(sizeof(*pOut)); if (pOut == NULL) { H245TRACE(pObject->dwInst, 2, "MRSE1_T109ExpiryF: memory allocation failed"); return H245_ERROR_NOMEM; } pOut->choice = indication_chosen; pOut->u.indication.choice = requestModeRelease_chosen; lError = sendPDU(pObject->pInstance, pOut); MemFree(pOut); // Send REJECT.indication to H.245 user // SOURCE := PROTOCOL pObject->State = MRSE_IDLE; H245FsmConfirm(NULL, H245_CONF_MRSE_EXPIRED, pObject->pInstance, pObject->dwTransId, FSM_OK); return lError; } // MRSE1_T109Expiry /*********************************************************************** * * IN-COMING FINITE STATE MACHINE FUNCTIONS * ***********************************************************************/ /* * NAME * MRSE0_RequestModeF - RequestMode received in IDLE state * * * PARAMETERS * INPUT pObject pointer to State Entity * INPUT pPdu pointer to PDU * * RETURN VALUE * Error return codes defined in h245com.h */ HRESULT MRSE0_RequestModeF (Object_t *pObject, PDU_t *pPdu) { ASSERT(pObject->Entity == MRSE_IN); ASSERT(pObject->State == MRSE_IDLE); H245TRACE(pObject->dwInst, 2, "MRSE0_RequestMode:%d", pObject->Key); pObject->byInSequence = (unsigned char) pPdu->u.MltmdSystmCntrlMssg_rqst.u.requestMode.sequenceNumber; // Send TRANSFER.indication to H.245 user pObject->State = MRSE_WAIT; H245FsmIndication(pPdu, H245_IND_MRSE, pObject->pInstance, pObject->dwTransId, FSM_OK); return 0; } // MRSE0_RequestMode /* * NAME * MRSE1_RequestModeF - RequestMode received in AWAITING RESPONSE state * * * PARAMETERS * INPUT pObject pointer to State Entity * INPUT pPdu pointer to PDU * * RETURN VALUE * Error return codes defined in h245com.h */ HRESULT MRSE1_RequestModeF (Object_t *pObject, PDU_t *pPdu) { ASSERT(pObject->Entity == MRSE_IN); ASSERT(pObject->State == MRSE_WAIT); H245TRACE(pObject->dwInst, 2, "MRSE1_RequestMode:%d", pObject->Key); pObject->byInSequence = (unsigned char) pPdu->u.MltmdSystmCntrlMssg_rqst.u.requestMode.sequenceNumber; #if defined(SDL_COMPLIANT) // Send REJECT.indication to H.245 user H245FsmIndication(pPdu, H245_IND_MRSE_RELEASE, pObject->pInstance, pObject->dwTransId, FSM_OK); #endif // Send TRANSFER.indication to H.245 user H245FsmIndication(pPdu, H245_IND_MRSE, pObject->pInstance, pObject->dwTransId, FSM_OK); return 0; } // MRSE1_RequestMode /* * NAME * MRSE1_RequestModeReleaseF - RequestModeRelease received in AWAITING RESPONSE state * * * PARAMETERS * INPUT pObject pointer to State Entity * INPUT pPdu pointer to PDU * * RETURN VALUE * Error return codes defined in h245com.h */ HRESULT MRSE1_RequestModeReleaseF (Object_t *pObject, PDU_t *pPdu) { ASSERT(pObject->Entity == MRSE_IN); ASSERT(pObject->State == MRSE_WAIT); H245TRACE(pObject->dwInst, 2, "MRSE1_RequestModeRelease:%d", pObject->Key); // Send REJECT.indication to H.245 user // SOURCE:=PROTOCOL pObject->State = MRSE_IDLE; H245FsmIndication(pPdu, H245_IND_MRSE_RELEASE, pObject->pInstance, pObject->dwTransId, FSM_OK); return 0; } // MRSE1_RequestModeRelease /* * NAME * MRSE1_TRANSFER_responseF - TRANSFER.response from API in AWAITING RESPONSE state * * * PARAMETERS * INPUT pObject pointer to State Entity * INPUT pPdu pointer to PDU * * RETURN VALUE * Error return codes defined in h245com.h */ HRESULT MRSE1_TRANSFER_responseF (Object_t *pObject, PDU_t *pPdu) { ASSERT(pObject->Entity == MRSE_IN); ASSERT(pObject->State == MRSE_WAIT); H245TRACE(pObject->dwInst, 2, "MRSE1_TRANSFER_response:%d", pObject->Key); // Send RequestModeAck PDU to remote peer pObject->State = MRSE_IDLE; pPdu->u.MSCMg_rspns.u.requestModeAck.sequenceNumber = pObject->byInSequence; return sendPDU(pObject->pInstance, pPdu); } // MRSE1_TRANSFER_response /* * NAME * MRSE1_REJECT_requestF - REJECT.request from API in AWAITING RESPONSE state * * * PARAMETERS * INPUT pObject pointer to State Entity * INPUT pPdu pointer to PDU * * RETURN VALUE * Error return codes defined in h245com.h */ HRESULT MRSE1_REJECT_requestF (Object_t *pObject, PDU_t *pPdu) { ASSERT(pObject->Entity == MRSE_IN); ASSERT(pObject->State == MRSE_WAIT); H245TRACE(pObject->dwInst, 2, "MRSE1_REJECT_request:%d", pObject->Key); // Send RequestModeReject PDU to remote pObject->State = MRSE_IDLE; pPdu->u.MSCMg_rspns.u.requestModeReject.sequenceNumber = pObject->byInSequence; return sendPDU(pObject->pInstance, pPdu); } // MRSE1_REJECT_request