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.

793 lines
23 KiB

  1. /***********************************************************************
  2. * *
  3. * Filename: mstrslv.c *
  4. * Module: H245 Finite State Machine Subsystem *
  5. * *
  6. ***********************************************************************
  7. * INTEL Corporation Proprietary Information *
  8. * *
  9. * This listing is supplied under the terms of a license agreement *
  10. * with INTEL Corporation and may not be copied nor disclosed except *
  11. * in accordance with the terms of that agreement. *
  12. * *
  13. * Copyright (c) 1996 Intel Corporation. All rights reserved. *
  14. ***********************************************************************
  15. * *
  16. * $Workfile: mstrslv.c $
  17. * $Revision: 1.12 $
  18. * $Modtime: 12 Dec 1996 14:37:12 $
  19. * $Log: S:/STURGEON/SRC/H245/SRC/VCS/mstrslv.c_v $
  20. *
  21. * Rev 1.12 12 Dec 1996 15:52:50 EHOWARDX
  22. * Master Slave Determination kludge.
  23. *
  24. * Rev 1.11 11 Dec 1996 16:50:50 EHOWARDX
  25. * Went back to original Master/Slave determination algorithm.
  26. *
  27. * Rev 1.10 09 Dec 1996 13:34:48 EHOWARDX
  28. * Updated copyright notice.
  29. *
  30. * Rev 1.9 26 Nov 1996 17:06:02 EHOWARDX
  31. * Reversed order of subtraction for DetermineMasterSlave.
  32. *
  33. * Rev 1.8 08 Aug 1996 16:03:40 EHOWARDX
  34. *
  35. * Fixed master slave determinate bug (hopefully the last one!)
  36. *
  37. * Rev 1.7 19 Jul 1996 12:12:44 EHOWARDX
  38. *
  39. * Changed to use API events defined in H245API.H instead of FSM events
  40. * which are no longer defined in FSMEXPOR.H.
  41. *
  42. * Rev 1.6 01 Jul 1996 23:35:48 EHOWARDX
  43. * MSDetAckIncoming bug - was sending indication instead of confirm.
  44. *
  45. * Rev 1.5 01 Jul 1996 23:14:20 EHOWARDX
  46. * Fixed bug in MSDetOutgoing -- state change was ifdefed out.
  47. *
  48. * Rev 1.4 07 Jun 1996 16:00:26 EHOWARDX
  49. * Fixed bug with pOut not getting freed in msDetOutgoing.
  50. *
  51. * Rev 1.3 07 Jun 1996 15:40:20 EHOWARDX
  52. * Fixed bug in msDetRejOutgoing; pOut was not freed if N100 count exceeded.
  53. *
  54. * Rev 1.2 04 Jun 1996 13:57:54 EHOWARDX
  55. * Fixed Release build warnings.
  56. *
  57. * Rev 1.1 30 May 1996 23:39:16 EHOWARDX
  58. * Cleanup.
  59. *
  60. * Rev 1.0 09 May 1996 21:06:32 EHOWARDX
  61. * Initial revision.
  62. *
  63. * Rev 1.11.1.4 09 May 1996 19:48:48 EHOWARDX
  64. * Change TimerExpiryF function arguements.
  65. *
  66. * Rev 1.11.1.3 25 Apr 1996 17:00:22 EHOWARDX
  67. * Minor fixes.
  68. *
  69. * Rev 1.11.1.2 15 Apr 1996 10:45:46 EHOWARDX
  70. * Update.
  71. *
  72. * Rev 1.11.1.1 10 Apr 1996 21:15:46 EHOWARDX
  73. * Check-in for safety in middle of re-design.
  74. * *
  75. ***********************************************************************/
  76. #include "precomp.h"
  77. #include "h245api.h"
  78. #include "h245com.h"
  79. #include "h245fsm.h"
  80. #include "mstrslv.h"
  81. #include "pdu.x"
  82. // Master Slave Determination states
  83. #define MSIDLE 0
  84. #define MSOutgoingAwaiting 1
  85. #define MSIncomingAwaiting 2
  86. #define MAX_RAND 0x00FFFFFF
  87. extern unsigned int uN100;
  88. extern unsigned int uT106;
  89. /***********************************************************************
  90. *
  91. * LOCAL FUNCTIONS
  92. *
  93. ***********************************************************************/
  94. /*
  95. * NAME
  96. * T106ExpiryF - Callback function called by the timer.
  97. *
  98. *
  99. * PARAMETERS
  100. * INPUT dwInst current instance of H245
  101. * INPUT id timer id
  102. * INPUT pObject pointer to a State Entity
  103. *
  104. *
  105. * RETURN VALUE
  106. * OK
  107. */
  108. int T106ExpiryF(struct InstanceStruct *pInstance, DWORD_PTR dwTimerId, void *pObject)
  109. {
  110. return FsmTimerEvent(pInstance, dwTimerId, pObject, T106Expiry);
  111. } // T106ExpiryF()
  112. #define GetTerminal(pObject) (pObject)->pInstance->StateMachine.sv_TT
  113. #define GetStatus(pObject) (pObject)->pInstance->StateMachine.sv_STATUS
  114. #define SetStatus(pObject, Status) (pObject)->pInstance->StateMachine.sv_STATUS = (Status)
  115. #define GetRandomNumber(pObject) (pObject)->u.msdse.sv_SDNUM
  116. #define SetRandomNumber(pObject, uRandom) (pObject)->u.msdse.sv_SDNUM = (uRandom)
  117. #define GetCount(pObject) (pObject)->u.msdse.sv_NCOUNT
  118. #define SetCount(pObject, uCount) (pObject)->u.msdse.sv_NCOUNT = (uCount)
  119. /*
  120. * NAME
  121. * DetermineStatus - determines whether the terminal is a master or a slave or neither
  122. *
  123. *
  124. * PARAMETERS
  125. * INPUT pdu pointer to a PDU structure
  126. *
  127. * RETURN VALUE
  128. * terminal status
  129. */
  130. static MS_Status_t DetermineStatus(Object_t *pObject, PDU_t *pPdu)
  131. {
  132. unsigned int uTemp;
  133. unsigned char sv_TT = GetTerminal(pObject);
  134. if (pPdu->u.MltmdSystmCntrlMssg_rqst.u.masterSlaveDetermination.terminalType < sv_TT)
  135. return pObject->pInstance->StateMachine.sv_STATUS = MASTER;
  136. if (pPdu->u.MltmdSystmCntrlMssg_rqst.u.masterSlaveDetermination.terminalType > sv_TT)
  137. return pObject->pInstance->StateMachine.sv_STATUS = SLAVE;
  138. uTemp = (pPdu->u.MltmdSystmCntrlMssg_rqst.u.masterSlaveDetermination.statusDeterminationNumber - GetRandomNumber(pObject)) & 0xFFFFFF;
  139. if (uTemp > 0x800000)
  140. return pObject->pInstance->StateMachine.sv_STATUS = SLAVE;
  141. if (uTemp < 0x800000 && uTemp != 0)
  142. return pObject->pInstance->StateMachine.sv_STATUS = MASTER;
  143. return pObject->pInstance->StateMachine.sv_STATUS = INDETERMINATE;
  144. }
  145. /***********************************************************************
  146. *
  147. * FINITE STATE MACHINE FUNCTIONS
  148. *
  149. ***********************************************************************/
  150. /*
  151. * NAME
  152. * detRequestIdle - request Master/Slave Determination from API in idle state
  153. *
  154. *
  155. * PARAMETERS
  156. * INPUT pObject pointer to a State Entity
  157. *
  158. * RETURN VALUE
  159. * error return codes defined in h245com.h
  160. */
  161. HRESULT detRequestIdle(Object_t *pObject, PDU_t *pPdu)
  162. {
  163. HRESULT lError;
  164. ASSERT(pObject->Entity == MSDSE);
  165. ASSERT(pObject->State == MSIDLE);
  166. SetRandomNumber(pObject, GetTickCount() & MAX_RAND);
  167. SetCount(pObject, 1); // Initialize retry counter
  168. SetStatus(pObject, INDETERMINATE);
  169. H245TRACE( pObject->dwInst, 2,
  170. "detRequestIdle: TerminalType=%d StatusDeterminationNumber=%d",
  171. GetTerminal(pObject), GetRandomNumber(pObject));
  172. /* Send a Master/Slave determination PDU */
  173. H245TRACE(pObject->dwInst, 2, "Master/Slave Determination to Send/Rec module");
  174. pdu_req_mstslv (pPdu, GetTerminal(pObject), GetRandomNumber(pObject));
  175. lError = sendPDU(pObject->pInstance, pPdu);
  176. /* set timer T106 */
  177. pObject->State = MSOutgoingAwaiting;
  178. FsmStartTimer(pObject, T106ExpiryF, uT106);
  179. return lError;
  180. } // detRequestIdle()
  181. /*
  182. * NAME
  183. * msDetIdle - received Master/Slave Determination PDU in idle state
  184. *
  185. *
  186. * PARAMETERS
  187. * INPUT pObject pointer to a State Entity
  188. *
  189. * RETURN VALUE
  190. * error return codes defined in h245com.h
  191. */
  192. HRESULT msDetIdle(Object_t *pObject, PDU_t *pPdu)
  193. {
  194. PDU_t * pOut;
  195. HRESULT lError;
  196. ASSERT(pObject->Entity == MSDSE);
  197. ASSERT(pObject->State == MSIDLE);
  198. pOut = (PDU_t *) MemAlloc(sizeof(PDU_t));
  199. if (pOut == NULL)
  200. {
  201. DetermineStatus(pObject, pPdu);
  202. return H245_ERROR_NOMEM;
  203. }
  204. SetRandomNumber(pObject, GetTickCount() & MAX_RAND);
  205. switch (DetermineStatus(pObject, pPdu))
  206. {
  207. case MASTER:
  208. /* Build MasterSlave Determination Ack */
  209. H245TRACE(pObject->dwInst, 2, "msDetIdle: sending Ack: SLAVE");
  210. pdu_rsp_mstslv_ack(pOut, slave_chosen);
  211. break;
  212. case SLAVE:
  213. /* Build MasterSlave Determination Ack */
  214. H245TRACE(pObject->dwInst, 2, "msDetIdle: sending Ack: MASTER");
  215. pdu_rsp_mstslv_ack(pOut, master_chosen);
  216. break;
  217. default:
  218. /* Send a masterSlaveDet Reject */
  219. pdu_rsp_mstslv_rej(pOut);
  220. lError = sendPDU(pObject->pInstance, pOut);
  221. MemFree(pOut);
  222. return lError;
  223. } // switch
  224. /* Send MasterSlave Determination Ack to remote */
  225. lError = sendPDU(pObject->pInstance, pOut);
  226. MemFree(pOut);
  227. pObject->State = MSIncomingAwaiting;
  228. #if defined(SDL_COMPLIANT)
  229. /* Send DETERMINE indication to client - unnecessary */
  230. H245FsmIndication(pPdu, H245_IND_MSTSLV, pObject->pInstance, pObject->dwTransId, FSM_OK);
  231. #endif
  232. /* set timer T106 */
  233. FsmStartTimer(pObject, T106ExpiryF, uT106);
  234. return lError;
  235. }
  236. /*
  237. * NAME
  238. * msDetAckOutgoing - received Master/Slave Determination Ack pdu in outgoing state
  239. *
  240. *
  241. * PARAMETERS
  242. * INPUT pObject pointer to a State Entity
  243. *
  244. * RETURN VALUE
  245. * error return codes defined in h245com.h
  246. */
  247. HRESULT msDetAckOutgoing(Object_t *pObject, PDU_t *pPdu)
  248. {
  249. PDU_t * pOut;
  250. HRESULT lError;
  251. ASSERT(pObject->Entity == MSDSE);
  252. ASSERT(pObject->State == MSOutgoingAwaiting);
  253. pOut = (PDU_t *) MemAlloc(sizeof(PDU_t));
  254. if (pOut == NULL)
  255. {
  256. return H245_ERROR_NOMEM;
  257. }
  258. /* reset timer */
  259. FsmStopTimer(pObject);
  260. /* Decision is opposite of MasterSlaveDeterminationAck.decision */
  261. switch(pPdu->u.MSCMg_rspns.u.mstrSlvDtrmntnAck.decision.choice)
  262. {
  263. case master_chosen:
  264. pObject->pInstance->StateMachine.sv_STATUS = MASTER;
  265. H245TRACE(pObject->dwInst, 2, "msDetAckOutgoing: sending Ack: SLAVE");
  266. pdu_rsp_mstslv_ack(pOut, slave_chosen);
  267. break;
  268. case slave_chosen:
  269. pObject->pInstance->StateMachine.sv_STATUS = SLAVE;
  270. H245TRACE(pObject->dwInst, 2, "msDetAckOutgoing: sending Ack: MASTER");
  271. pdu_rsp_mstslv_ack(pOut, master_chosen);
  272. break;
  273. default:
  274. H245TRACE(pObject->dwInst, 1, "msDetAckOutgoing: Invalid Master Slave Determination Ack received");
  275. return H245_ERROR_PARAM;
  276. }
  277. /* Send MasterSlave Determination Ack to remote */
  278. lError = sendPDU(pObject->pInstance, pOut);
  279. MemFree(pOut);
  280. /* Send DETERMINE confirm to client */
  281. pObject->State = MSIDLE;
  282. H245FsmConfirm(pPdu, H245_CONF_INIT_MSTSLV, pObject->pInstance, pObject->dwTransId, FSM_OK);
  283. return lError;
  284. }
  285. /*
  286. * NAME
  287. * msDetOutgoing- received Master/Slave Determination pdu in outgoing state
  288. *
  289. *
  290. * PARAMETERS
  291. * INPUT pObject pointer to a State Entity
  292. *
  293. * RETURN VALUE
  294. * error return codes defined in h245com.h
  295. */
  296. HRESULT msDetOutgoing(Object_t *pObject, PDU_t *pPdu)
  297. {
  298. PDU_t * pOut;
  299. HRESULT lError;
  300. ASSERT(pObject->Entity == MSDSE);
  301. ASSERT(pObject->State == MSOutgoingAwaiting);
  302. if (pObject->pInstance->bMasterSlaveKludge == 0)
  303. {
  304. // Ignore this message
  305. return NOERROR;
  306. }
  307. pOut = (PDU_t *) MemAlloc(sizeof(PDU_t));
  308. if (pOut == NULL)
  309. {
  310. return H245_ERROR_NOMEM;
  311. }
  312. /* reset timer T106 */
  313. FsmStopTimer(pObject);
  314. switch (DetermineStatus(pObject, pPdu))
  315. {
  316. case MASTER:
  317. H245TRACE(pObject->dwInst, 2, "msDetOutgoing: sending Ack: SLAVE");
  318. pdu_rsp_mstslv_ack(pOut, slave_chosen);
  319. break;
  320. case SLAVE:
  321. H245TRACE(pObject->dwInst, 2, "msDetOutgoing: sending Ack: MASTER");
  322. pdu_rsp_mstslv_ack(pOut, master_chosen);
  323. break;
  324. default:
  325. if (GetCount(pObject) >= uN100)
  326. {
  327. MemFree(pOut);
  328. /* Send ERROR.indication(F) to client */
  329. H245TRACE(pObject->dwInst, 2, "msDetOutgoing: Counter expired; Session Failed");
  330. H245FsmConfirm(NULL,H245_CONF_INIT_MSTSLV, pObject->pInstance, pObject->dwTransId, MS_FAILED);
  331. /* Send REJECT.indication to client - unnecessary */
  332. pObject->State = MSIDLE;
  333. lError = 0;
  334. }
  335. else
  336. {
  337. /* generate a new random number */
  338. H245TRACE(pObject->dwInst, 2, "Resending MasterSlaveDetermination");
  339. SetRandomNumber(pObject, GetTickCount() & MAX_RAND);
  340. SetCount(pObject, GetCount(pObject) + 1);
  341. /* Send MasterSlave Determination PDU to remote */
  342. pdu_req_mstslv (pOut, GetTerminal(pObject), GetRandomNumber(pObject));
  343. lError = sendPDU(pObject->pInstance, pOut);
  344. MemFree(pOut);
  345. /* set timer T106 */
  346. pObject->State = MSOutgoingAwaiting;
  347. FsmStartTimer(pObject, T106ExpiryF, uT106);
  348. }
  349. return lError;
  350. } // switch
  351. /* Send MasterSlave Determination Ack to remote */
  352. lError = sendPDU(pObject->pInstance, pOut);
  353. MemFree(pOut);
  354. pObject->State = MSIncomingAwaiting;
  355. #if defined(SDL_COMPLIANT)
  356. /* Send DETERMINE indication to client */
  357. H245FsmIndication(pPdu, H245_IND_MSTSLV, pObject->pInstance, pObject->dwTransId, FSM_OK);
  358. #endif
  359. /* set timer T106 */
  360. FsmStartTimer(pObject, T106ExpiryF, uT106);
  361. return lError;
  362. }
  363. /*
  364. * NAME
  365. * msDetRejOutgoing- received Master/Slave Determination Reject pdu in outgoing state
  366. *
  367. *
  368. * PARAMETERS
  369. * INPUT pObject pointer to a State Entity
  370. *
  371. * RETURN VALUE
  372. * error return codes defined in h245com.h
  373. */
  374. HRESULT msDetRejOutgoing(Object_t *pObject, PDU_t *pPdu)
  375. {
  376. PDU_t * pOut;
  377. HRESULT lError;
  378. ASSERT(pObject->Entity == MSDSE);
  379. ASSERT(pObject->State == MSOutgoingAwaiting);
  380. pOut = (PDU_t *) MemAlloc(sizeof(PDU_t));
  381. if (pOut == NULL)
  382. {
  383. return H245_ERROR_NOMEM;
  384. }
  385. /* reset timer T106 */
  386. FsmStopTimer(pObject);
  387. if (GetCount(pObject) >= uN100)
  388. {
  389. MemFree(pOut);
  390. H245TRACE(pObject->dwInst, 2, "msDetRejOutgoing: Counter expired; Session Failed");
  391. pObject->State = MSIDLE;
  392. /* Send ERROR.indication(f) to client */
  393. H245FsmConfirm(pPdu,H245_CONF_INIT_MSTSLV, pObject->pInstance, pObject->dwTransId, MS_FAILED);
  394. #if defined(SDL_COMPLIANT)
  395. /* Send REJECT.indication to client - not necessary */
  396. H245FsmIndication(NULL, H245_IND_MSTSLV, pObject->pInstance, pObject->dwTransId, REJECT);
  397. #endif
  398. lError = 0;
  399. }
  400. else
  401. {
  402. H245TRACE(pObject->dwInst, 2, "msDetRejOutgoint: Re-sending a MasterSlaveDetermination");
  403. /* generate a new random number */
  404. SetRandomNumber(pObject, GetTickCount() & MAX_RAND);
  405. SetCount(pObject, GetCount(pObject) + 1);
  406. /* Send MasterSlave Determination PDU to remote */
  407. pdu_req_mstslv (pOut, GetTerminal(pObject), GetRandomNumber(pObject));
  408. lError = sendPDU(pObject->pInstance,pOut);
  409. MemFree(pOut);
  410. /* set timer T106 */
  411. FsmStartTimer(pObject, T106ExpiryF, uT106);
  412. }
  413. return lError;
  414. }
  415. /*
  416. * NAME
  417. * msDetReleaseOutgoing- received Master/Slave Determination release pdu in outgoing state
  418. *
  419. *
  420. * PARAMETERS
  421. * INPUT pObject pointer to a State Entity
  422. *
  423. * RETURN VALUE
  424. * error return codes defined in h245com.h
  425. */
  426. HRESULT msDetReleaseOutgoing(Object_t *pObject, PDU_t *pPdu)
  427. {
  428. ASSERT(pObject->Entity == MSDSE);
  429. ASSERT(pObject->State == MSOutgoingAwaiting);
  430. H245TRACE(pObject->dwInst, 2, "msDetReleaseOutgoing: Master/Slave Determination Release received; session failed");
  431. /* reset timer T106 */
  432. FsmStopTimer(pObject);
  433. /* Send ERROR.indication(B) to client */
  434. pObject->State = MSIDLE;
  435. H245FsmConfirm(pPdu, H245_CONF_INIT_MSTSLV, pObject->pInstance, pObject->dwTransId, MS_FAILED);
  436. #if defined(SDL_COMPLIANT)
  437. /* Send REJECT.indication to client - not necessary */
  438. H245FsmIndication(NULL, H245_IND_MSTSLV, pObject->pInstance, pObject->dwTransId, REJECT);
  439. #endif
  440. return 0;
  441. }
  442. /*
  443. * NAME
  444. * t106ExpiryOutgoing- timer expired for an outgoing M/S determination pdu
  445. *
  446. *
  447. * PARAMETERS
  448. * INPUT pObject pointer to a State Entity
  449. *
  450. * RETURN VALUE
  451. * error return codes defined in h245com.h
  452. */
  453. HRESULT t106ExpiryOutgoing(Object_t *pObject, PDU_t *pPdu)
  454. {
  455. PDU_t * pOut;
  456. HRESULT lError;
  457. ASSERT(pObject->Entity == MSDSE);
  458. ASSERT(pObject->State == MSOutgoingAwaiting);
  459. ASSERT(pPdu == NULL);
  460. H245TRACE(pObject->dwInst, 2, "t106ExpiryOutgoing: Timer expired before receiving Ack; session failed");
  461. pOut = (PDU_t *) MemAlloc(sizeof(PDU_t));
  462. if (pOut == NULL)
  463. {
  464. return H245_ERROR_NOMEM;
  465. }
  466. /* Send MasterSlave Determination Release to remote */
  467. pOut->choice = indication_chosen;
  468. pOut->u.indication.choice = mstrSlvDtrmntnRls_chosen;
  469. lError = sendPDU(pObject->pInstance, pOut);
  470. MemFree(pOut);
  471. /* Send ERROR.indication(A) to client */
  472. pObject->State = MSIDLE;
  473. H245FsmConfirm(NULL,H245_CONF_INIT_MSTSLV, pObject->pInstance, pObject->dwTransId, TIMER_EXPIRY);
  474. #if defined(SDL_COMPLIANT)
  475. /* Send REJECT.indication to client - not necessary */
  476. H245FsmIndication(NULL, H245_IND_MSTSLV, pObject->pInstance, pObject->dwTransId, REJECT);
  477. #endif
  478. return lError;
  479. }
  480. /*
  481. * NAME
  482. * msDetAckIncoming- received Master/Slave Determination Ack pdu in incoming state
  483. *
  484. *
  485. * PARAMETERS
  486. * INPUT pObject pointer to a State Entity
  487. *
  488. * RETURN VALUE
  489. * error return codes defined in h245com.h
  490. */
  491. HRESULT msDetAckIncoming(Object_t *pObject, PDU_t *pPdu)
  492. {
  493. ASSERT(pObject->Entity == MSDSE);
  494. ASSERT(pObject->State == MSIncomingAwaiting);
  495. /* reset timer T106 */
  496. FsmStopTimer(pObject);
  497. switch (GetStatus(pObject))
  498. {
  499. case master_chosen:
  500. if (pPdu->u.MSCMg_rspns.u.mstrSlvDtrmntnAck.decision.choice == master_chosen)
  501. {
  502. H245TRACE(pObject->dwInst, 2, "msDetAckIncoming: Terminal is a MASTER");
  503. /* Send DETERMINE.confirm to client */
  504. pObject->State = MSIDLE;
  505. H245FsmConfirm(pPdu, H245_CONF_INIT_MSTSLV, pObject->pInstance, pObject->dwTransId, FSM_OK);
  506. return 0;
  507. }
  508. break;
  509. case slave_chosen:
  510. if (pPdu->u.MSCMg_rspns.u.mstrSlvDtrmntnAck.decision.choice == slave_chosen)
  511. {
  512. H245TRACE(pObject->dwInst, 2, "msDetAckIncoming: Terminal is a SLAVE");
  513. /* Send DETERMINE.confirm to client */
  514. pObject->State = MSIDLE;
  515. H245FsmConfirm(pPdu, H245_CONF_INIT_MSTSLV, pObject->pInstance, pObject->dwTransId, FSM_OK);
  516. return 0;
  517. }
  518. break;
  519. default:
  520. H245TRACE(pObject->dwInst, 2, "msDetAckIncoming: Invalid MasterSlave Determination Ack received");
  521. return H245_ERROR_PARAM;
  522. } // switch
  523. H245TRACE(pObject->dwInst, 2, "msDetAckIncoming: bad decision in MasterSlave Determination Ack; Session failed");
  524. /* Send ERROR.indication(E) to client */
  525. pObject->State = MSIDLE;
  526. H245FsmConfirm(pPdu, H245_CONF_INIT_MSTSLV, pObject->pInstance, pObject->dwTransId, SESSION_FAILED);
  527. #if defined(SDL_COMPLIANT)
  528. /* Send REJECT.indication to client - not necessary */
  529. H245FsmIndication(NULL, H245_IND_MSTSLV, pObject->pInstance, pObject->dwTransId, REJECT);
  530. #endif
  531. return 0;
  532. }
  533. /*
  534. * NAME
  535. * msDetIncoming- received Master/Slave Determination pdu in incoming state
  536. *
  537. *
  538. * PARAMETERS
  539. * INPUT pObject pointer to a State Entity
  540. *
  541. * RETURN VALUE
  542. * error return codes defined in h245com.h
  543. */
  544. HRESULT msDetIncoming(Object_t *pObject, PDU_t *pPdu)
  545. {
  546. ASSERT(pObject->Entity == MSDSE);
  547. ASSERT(pObject->State == MSIncomingAwaiting);
  548. H245TRACE(pObject->dwInst, 2, "msDetIncoming: received MasterSlave Determination in INCOMING state; Session failed");
  549. /* reset timer T106 */
  550. FsmStopTimer(pObject);
  551. /* Send ERROR.indication(C) to client */
  552. pObject->State = MSIDLE;
  553. H245FsmIndication(pPdu,H245_IND_MSTSLV, pObject->pInstance, pObject->dwTransId, MS_FAILED);
  554. #if defined(SDL_COMPLIANT)
  555. /* Send REJECT.indication to client - not necessary */
  556. H245FsmIndication(NULL, H245_IND_MSTSLV, pObject->pInstance, pObject->dwTransId, REJECT);
  557. #endif
  558. return 0;
  559. }
  560. /*
  561. * NAME
  562. * msDetRejIncoming- received Master/Slave Determination Reject pdu in incoming state
  563. *
  564. *
  565. * PARAMETERS
  566. * INPUT pObject pointer to a State Entity
  567. *
  568. * RETURN VALUE
  569. * error return codes defined in h245com.h
  570. */
  571. HRESULT msDetRejIncoming(Object_t *pObject, PDU_t *pPdu)
  572. {
  573. ASSERT(pObject->Entity == MSDSE);
  574. ASSERT(pObject->State == MSIncomingAwaiting);
  575. H245TRACE(pObject->dwInst, 2, "msDetRejIncoming: received MasterSlave Reject: Session Failed");
  576. /* reset timer T106 */
  577. FsmStopTimer(pObject);
  578. /* Send ERROR.indication(D) to client */
  579. pObject->State = MSIDLE;
  580. H245FsmIndication(pPdu,H245_IND_MSTSLV, pObject->pInstance, pObject->dwTransId, MS_FAILED);
  581. #if defined(SDL_COMPLIANT)
  582. /* Send REJECT.indication to client - not necessary */
  583. H245FsmIndication(NULL, H245_IND_MSTSLV, pObject->pInstance, pObject->dwTransId, REJECT);
  584. #endif
  585. return 0;
  586. }
  587. /*
  588. * NAME
  589. * msDetReleaseIncoming- received Master/Slave Determination Release pdu in incoming state
  590. *
  591. *
  592. * PARAMETERS
  593. * INPUT pObject pointer to a State Entity
  594. *
  595. * RETURN VALUE
  596. * error return codes defined in h245com.h
  597. */
  598. HRESULT msDetReleaseIncoming(Object_t *pObject, PDU_t *pPdu)
  599. {
  600. ASSERT(pObject->Entity == MSDSE);
  601. ASSERT(pObject->State == MSIncomingAwaiting);
  602. H245TRACE(pObject->dwInst, 2, "msDetReleaseIncoming: received MasterSlave Release; Session Failed");
  603. /* reset timer T106 */
  604. FsmStopTimer(pObject);
  605. /* Send ERROR.indication(B) to client */
  606. pObject->State = MSIDLE;
  607. H245FsmIndication(pPdu,H245_IND_MSTSLV, pObject->pInstance, pObject->dwTransId, MS_FAILED);
  608. #if defined(SDL_COMPLIANT)
  609. /* Send REJECT.indication to client - not necessary */
  610. H245FsmIndication(NULL, H245_IND_MSTSLV, pObject->pInstance, pObject->dwTransId, REJECT);
  611. #endif
  612. return 0;
  613. }
  614. /*
  615. * NAME
  616. * t106ExpiryIncoming - timer expired while waiting for second Ack
  617. *
  618. *
  619. * PARAMETERS
  620. * INPUT pObject pointer to a State Entity
  621. *
  622. * RETURN VALUE
  623. * error return codes defined in h245com.h
  624. */
  625. HRESULT t106ExpiryIncoming(Object_t *pObject, PDU_t *pPdu)
  626. {
  627. ASSERT(pObject->Entity == MSDSE);
  628. ASSERT(pObject->State == MSIncomingAwaiting);
  629. ASSERT(pPdu == NULL);
  630. H245TRACE(pObject->dwInst, 2, "t106ExpiryIncoming: timer expired waiting for Ack; Session failed");
  631. /* Send ERROR.indication(A) to client */
  632. pObject->State = MSIDLE;
  633. H245FsmIndication(NULL, H245_IND_MSTSLV, pObject->pInstance, pObject->dwTransId, TIMER_EXPIRY);
  634. #if defined(SDL_COMPLIANT)
  635. /* Send REJECT.indication to client - not necessary */
  636. H245FsmIndication(NULL, H245_IND_MSTSLV, pObject->pInstance, pObject->dwTransId, REJECT);
  637. #endif
  638. return 0;
  639. }
  640.