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.

778 lines
21 KiB

  1. /***********************************************************************
  2. * *
  3. * Filename: openu.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: OPENU.C $
  17. * $Revision: 1.5 $
  18. * $Modtime: 09 Dec 1996 13:36:34 $
  19. * $Log: S:/STURGEON/SRC/H245/SRC/VCS/OPENU.C_v $
  20. *
  21. * Rev 1.5 09 Dec 1996 13:36:50 EHOWARDX
  22. * Updated copyright notice.
  23. *
  24. * Rev 1.4 19 Jul 1996 12:12:02 EHOWARDX
  25. *
  26. * Changed to use API events defined in H245API.H instead of FSM events
  27. * which are no longer defined in FSMEXPOR.H.
  28. *
  29. * Rev 1.3 04 Jun 1996 13:56:52 EHOWARDX
  30. * Fixed Release build warnings.
  31. *
  32. * Rev 1.2 30 May 1996 23:39:20 EHOWARDX
  33. * Cleanup.
  34. *
  35. * Rev 1.1 28 May 1996 14:25:24 EHOWARDX
  36. * Tel Aviv update.
  37. *
  38. * Rev 1.0 09 May 1996 21:06:36 EHOWARDX
  39. * Initial revision.
  40. *
  41. * Rev 1.13.1.2 09 May 1996 19:48:32 EHOWARDX
  42. * Change TimerExpiryF function arguements.
  43. *
  44. * Rev 1.13.1.1 15 Apr 1996 10:45:26 EHOWARDX
  45. * Update.
  46. *
  47. * Rev 1.13.1.0 10 Apr 1996 21:14:06 EHOWARDX
  48. * Branched.
  49. * *
  50. ***********************************************************************/
  51. #include "precomp.h"
  52. #include "h245api.h"
  53. #include "h245com.h"
  54. #include "h245fsm.h"
  55. #include "openu.h"
  56. #include "pdu.x"
  57. // Open Uni-directional Logical Channel Out-going states
  58. #define OpenOutUReleased 0
  59. #define OpenOutUAwaitingEstablishment 1
  60. #define OpenOutUEstablished 2
  61. #define OpenOutUAwaitingRelease 3
  62. // Open Uni-directional Logical Channel In-coming states
  63. #define OpenInUReleased 0
  64. #define OpenInUAwaitingEstablishment 1
  65. #define OpenInUEstablished 2
  66. extern unsigned int uT103;
  67. /***********************************************************************
  68. *
  69. * LOCAL FUNCTIONS
  70. *
  71. ***********************************************************************/
  72. /*
  73. * NAME
  74. * T103ExpiryF - Callback function called by the timer
  75. *
  76. *
  77. * PARAMETERS
  78. * INPUT dwInst current instance of H245
  79. * INPUT id timer id
  80. * INPUT pObject pointer to a State Entity
  81. *
  82. *
  83. * RETURN VALUE
  84. * OK
  85. */
  86. int T103ExpiryF(struct InstanceStruct *pInstance, DWORD_PTR dwTimerId, void *pObject)
  87. {
  88. return FsmTimerEvent(pInstance, dwTimerId, pObject, T103Expiry);
  89. } // T103ExpiryF()
  90. /***********************************************************************
  91. *
  92. * OUT-GOING FINITE STATE MACHINE FUNCTIONS
  93. *
  94. ***********************************************************************/
  95. /*
  96. * NAME
  97. * establishReleased - request for open unidirectional channel from API in idle state
  98. *
  99. *
  100. * PARAMETERS
  101. * INPUT pObject pointer to a State Entity
  102. *
  103. * RETURN VALUE
  104. * error return codes defined in h245com.h
  105. */
  106. HRESULT establishReleased(Object_t *pObject, PDU_t *pPdu)
  107. {
  108. HRESULT lError;
  109. ASSERT(pObject->Entity == LCSE_OUT);
  110. ASSERT(pObject->State == OpenOutUReleased);
  111. H245TRACE(pObject->dwInst, 2, "Sending open logical channel to ASN; Channel=%d",
  112. pObject->Key);
  113. /* Send Open Logical Channel to remote peer */
  114. lError = sendPDU(pObject->pInstance, pPdu);
  115. /* set timer T103 */
  116. pObject->State = OpenOutUAwaitingEstablishment;
  117. FsmStartTimer(pObject, T103ExpiryF, uT103);
  118. return lError;
  119. }
  120. /*
  121. * NAME
  122. * openAckAwaitingE - received open unidirectional channel Ack in Awaiting Establishment state
  123. *
  124. *
  125. * PARAMETERS
  126. * INPUT pObject pointer to a State Entity
  127. *
  128. * RETURN VALUE
  129. * error return codes defined in h245com.h
  130. */
  131. HRESULT openAckAwaitingE(Object_t *pObject, PDU_t *pPdu)
  132. {
  133. ASSERT(pObject->Entity == LCSE_OUT);
  134. ASSERT(pObject->State == OpenOutUAwaitingEstablishment);
  135. /* reset timer T103 */
  136. FsmStopTimer(pObject);
  137. /* Send ESTABLISH.confirm (SOURCE:=USER) to client */
  138. pObject->State = OpenOutUEstablished;
  139. H245FsmConfirm(pPdu, H245_CONF_OPEN, pObject->pInstance, pObject->dwTransId, FSM_OK);
  140. return 0;
  141. }
  142. /*
  143. * NAME
  144. * openRejAwaitingE - received open unidirectional channel reject in Awaiting Establishment state
  145. *
  146. *
  147. * PARAMETERS
  148. * INPUT pObject pointer to a State Entity
  149. *
  150. * RETURN VALUE
  151. * error return codes defined in h245com.h
  152. */
  153. HRESULT openRejAwaitingE(Object_t *pObject, PDU_t *pPdu)
  154. {
  155. ASSERT(pObject->Entity == LCSE_OUT);
  156. ASSERT(pObject->State == OpenOutUAwaitingEstablishment);
  157. H245TRACE(pObject->dwInst, 2, "H245_CONF_OPEN with REJECT to API; Channel=%d",
  158. pObject->Key);
  159. /* reset timer T103 */
  160. FsmStopTimer(pObject);
  161. pObject->State = OpenOutUReleased;
  162. H245FsmConfirm(pPdu, H245_CONF_OPEN, pObject->pInstance, pObject->dwTransId, REJECT);
  163. return 0;
  164. }
  165. /*
  166. * NAME
  167. * releaseAwaitingE - close unidirectional channel in Awaiting Establishment state
  168. *
  169. *
  170. * PARAMETERS
  171. * INPUT pObject pointer to a State Entity
  172. *
  173. * RETURN VALUE
  174. * error return codes defined in h245com.h
  175. */
  176. HRESULT releaseAwaitingE(Object_t *pObject, PDU_t *pPdu)
  177. {
  178. HRESULT lError;
  179. ASSERT(pObject->Entity == LCSE_OUT);
  180. ASSERT(pObject->State == OpenOutUAwaitingEstablishment);
  181. H245TRACE(pObject->dwInst, 2, "Close message to ASN; Channel=%d",
  182. pObject->Key);
  183. /* reset timer T103 */
  184. FsmStopTimer(pObject);
  185. /* Send Close Logical Channel to remote peer */
  186. lError = sendPDU(pObject->pInstance, pPdu);
  187. /* set timer T103 */
  188. pObject->State = OpenOutUAwaitingRelease;
  189. FsmStartTimer(pObject, T103ExpiryF, uT103);
  190. return lError;
  191. }
  192. /*
  193. * NAME
  194. * t103AwaitingE - handle timer T103 expiry
  195. *
  196. *
  197. * PARAMETERS
  198. * INPUT pObject pointer to a State Entity
  199. *
  200. * RETURN VALUE
  201. * error return codes defined in h245com.h
  202. */
  203. HRESULT t103AwaitingE(Object_t *pObject, PDU_t *pPdu)
  204. {
  205. PDU_t * pOut;
  206. HRESULT lError;
  207. ASSERT(pObject->Entity == LCSE_OUT);
  208. ASSERT(pObject->State == OpenOutUAwaitingEstablishment);
  209. H245TRACE(pObject->dwInst, 2,
  210. "H245_CONF_OPEN with a timer expiry to API; Channel=%d",
  211. pObject->Key);
  212. pOut = MemAlloc(sizeof(PDU_t ));
  213. if (pOut == NULL)
  214. {
  215. H245TRACE(pObject->dwInst, 2,
  216. "t103AwaitingE: memory allocation failed");
  217. return H245_ERROR_NOMEM;
  218. }
  219. /* Send Close Logical Channel (source:=lcse) to remote peer */
  220. pdu_req_close_logical_channel(pOut, (WORD)pObject->Key, 1);
  221. lError = sendPDU(pObject->pInstance,pOut);
  222. MemFree(pOut);
  223. /* Send RELEASE.indication (SOURCE:=LCSE) to client */
  224. pObject->State = OpenOutUReleased;
  225. H245FsmConfirm(pPdu, H245_CONF_OPEN, pObject->pInstance, pObject->dwTransId, ERROR_D_TIMEOUT);
  226. return lError;
  227. }
  228. /*
  229. * NAME
  230. * releaseEstablished - send close channel while in the Established state
  231. *
  232. *
  233. * PARAMETERS
  234. * INPUT pObject pointer to a State Entity
  235. *
  236. * RETURN VALUE
  237. * error return codes defined in h245com.h
  238. */
  239. HRESULT releaseEstablished(Object_t *pObject, PDU_t *pPdu)
  240. {
  241. HRESULT lError;
  242. ASSERT(pObject->Entity == LCSE_OUT);
  243. ASSERT(pObject->State == OpenOutUEstablished);
  244. H245TRACE(pObject->dwInst, 2, "Send a Close Logical Channel to ASN; Channel=%d",
  245. pObject->Key);
  246. /* Send Close Logical Channel to remote peer */
  247. lError = sendPDU(pObject->pInstance, pPdu);
  248. /* set timer T103 */
  249. pObject->State = OpenOutUAwaitingRelease;
  250. FsmStartTimer(pObject, T103ExpiryF, uT103);
  251. return lError;
  252. }
  253. /*
  254. * NAME
  255. * openRejEstablished - received open unidirectional channel reject in Establish state
  256. *
  257. *
  258. * PARAMETERS
  259. * INPUT pObject pointer to a State Entity
  260. *
  261. * RETURN VALUE
  262. * error return codes defined in h245com.h
  263. */
  264. HRESULT openRejEstablished(Object_t *pObject, PDU_t *pPdu)
  265. {
  266. ASSERT(pObject->Entity == LCSE_OUT);
  267. ASSERT(pObject->State == OpenOutUEstablished);
  268. H245TRACE(pObject->dwInst, 2,
  269. "H245_CONF_OPEN with error B then with REJECT to API; Channel=%d",
  270. pObject->Key);
  271. pObject->State = OpenOutUReleased;
  272. #if defined(SDL_COMPLIANT)
  273. /* Send ERROR.indication(B) to client - not necessary */
  274. H245FsmConfirm(pPdu, H245_CONF_OPEN, pObject->pInstance, pObject->dwTransId, ERROR_B_INAPPROPRIATE);
  275. #endif
  276. /* Send RELEASE.indication (SOURCE:=LCSE) to client */
  277. H245FsmConfirm(pPdu, H245_CONF_OPEN, pObject->pInstance, pObject->dwTransId, REJECT);
  278. return 0;
  279. }
  280. /*
  281. * NAME
  282. * closeAckEstablished - received close unidirectional channel Ack in Established state
  283. *
  284. *
  285. * PARAMETERS
  286. * INPUT pObject pointer to a State Entity
  287. *
  288. * RETURN VALUE
  289. * error return codes defined in h245com.h
  290. */
  291. HRESULT closeAckEstablished(Object_t *pObject, PDU_t *pPdu)
  292. {
  293. ASSERT(pObject->Entity == LCSE_OUT);
  294. ASSERT(pObject->State == OpenOutUEstablished);
  295. H245TRACE(pObject->dwInst, 2, "H245_CONF_OPEN with error C then with REJECT to API->channel:%d", pObject->Key);
  296. pObject->State = OpenOutUReleased;
  297. #if defined(SDL_COMPLIANT)
  298. /* Send ERROR.indication(C) to client - not necessary */
  299. H245FsmConfirm(pPdu, H245_CONF_OPEN, pObject->pInstance, pObject->dwTransId, ERROR_C_INAPPROPRIATE);
  300. #endif
  301. /* Send RELEASE.indication (SOURCE:=LCSE) to client */
  302. H245FsmConfirm(pPdu, H245_CONF_OPEN, pObject->pInstance, pObject->dwTransId, REJECT);
  303. return 0;
  304. }
  305. /*
  306. * NAME
  307. * closeAckAwaitingR - received CloseAck/OpenReject in Awaiting Release state
  308. *
  309. *
  310. * PARAMETERS
  311. * INPUT pObject pointer to a State Entity
  312. *
  313. * RETURN VALUE
  314. * error return codes defined in h245com.h
  315. */
  316. HRESULT closeAckAwaitingR(Object_t *pObject, PDU_t *pPdu)
  317. {
  318. ASSERT(pObject->Entity == LCSE_OUT);
  319. ASSERT(pObject->State == OpenOutUAwaitingRelease);
  320. H245TRACE(pObject->dwInst, 2,
  321. "H245_CONF_CLOSE with no error to API; Channel=%d",
  322. pObject->Key);
  323. /* reset timer T103 */
  324. FsmStopTimer(pObject);
  325. /* Send RELEASE.confirm to client */
  326. pObject->State = OpenOutUReleased;
  327. H245FsmConfirm(pPdu, H245_CONF_CLOSE, pObject->pInstance, pObject->dwTransId, FSM_OK);
  328. return 0;
  329. }
  330. /*
  331. * NAME
  332. * openRejAwaitingR - received open unidirectional channel Reject in Awaiting Release state
  333. *
  334. *
  335. * PARAMETERS
  336. * INPUT pObject pointer to a State Entity
  337. *
  338. * RETURN VALUE
  339. * error return codes defined in h245com.h
  340. */
  341. HRESULT openRejAwaitingR(Object_t *pObject, PDU_t *pPdu)
  342. {
  343. return closeAckAwaitingR(pObject, pPdu);
  344. }
  345. /*
  346. * NAME
  347. * t103AwaitingR - handle timer expiry for close channel
  348. *
  349. * PARAMETERS
  350. * INPUT pObject pointer to a State Entity
  351. *
  352. * RETURN VALUE
  353. * error return codes defined in h245com.h
  354. */
  355. HRESULT t103AwaitingR(Object_t *pObject, PDU_t *pPdu)
  356. {
  357. ASSERT(pObject->Entity == LCSE_OUT);
  358. ASSERT(pObject->State == OpenOutUAwaitingRelease);
  359. ASSERT(pPdu == NULL);
  360. H245TRACE(pObject->dwInst, 2,
  361. "H245_CONF_CLOSE with timer expiry to API; Channel=%d",
  362. pObject->Key);
  363. /* Send ERROR.indication(D) to client */
  364. pObject->State = OpenOutUReleased;
  365. H245FsmConfirm(NULL, H245_CONF_CLOSE, pObject->pInstance, pObject->dwTransId, ERROR_D_TIMEOUT);
  366. #if defined(SDL_COMPLIANT)
  367. /* Send RELEASE.confirm to client - not necessary */
  368. H245FsmConfirm(NULL, H245_CONF_OPEN, pObject->pInstance, pObject->dwTransId, REJECT);
  369. #endif
  370. return 0;
  371. }
  372. /*
  373. * NAME
  374. * establishAwaitingR - open unidirectional channel request from API in Awaiting Release state
  375. *
  376. *
  377. * PARAMETERS
  378. * INPUT pObject pointer to a State Entity
  379. *
  380. * RETURN VALUE
  381. * error return codes defined in h245com.h
  382. */
  383. HRESULT establishAwaitingR(Object_t *pObject, PDU_t *pPdu)
  384. {
  385. HRESULT lError;
  386. ASSERT(pObject->Entity == LCSE_OUT);
  387. ASSERT(pObject->State == OpenOutUAwaitingRelease);
  388. H245TRACE(pObject->dwInst, 2, "send a (re) Open Channel to ASN; Channel=%d",
  389. pObject->Key);
  390. /* reset timer T103 */
  391. FsmStopTimer(pObject);
  392. /* Send Open Logical Channel to remote peer */
  393. lError = sendPDU(pObject->pInstance,pPdu);
  394. /* set timer T103 */
  395. pObject->State = OpenOutUAwaitingEstablishment;
  396. FsmStartTimer(pObject, T103ExpiryF, uT103);
  397. return lError;
  398. }
  399. /***********************************************************************
  400. *
  401. * IN-COMING FINITE STATE MACHINE FUNCTIONS
  402. *
  403. ***********************************************************************/
  404. HRESULT openReleased(Object_t *pObject, PDU_t *pPdu)
  405. {
  406. ASSERT(pObject->Entity == LCSE_IN);
  407. ASSERT(pObject->State == OpenInUReleased);
  408. H245TRACE(pObject->dwInst, 2,
  409. "H245_IND_OPEN with no error to API; Channel=%d",
  410. pObject->Key);
  411. /* Send ESTABLISH.indication to client */
  412. pObject->State = OpenInUAwaitingEstablishment;
  413. H245FsmIndication(pPdu, H245_IND_OPEN, pObject->pInstance, 0, FSM_OK);
  414. return 0;
  415. }
  416. /*
  417. * NAME
  418. * closeReleased - received close unidirectional channel in Idle state
  419. *
  420. *
  421. * PARAMETERS
  422. * INPUT pObject pointer to a State Entity
  423. *
  424. * RETURN VALUE
  425. * error return codes defined in h245com.h
  426. */
  427. HRESULT closeReleased(Object_t *pObject, PDU_t *pPdu)
  428. {
  429. PDU_t * pOut;
  430. HRESULT lError;
  431. ASSERT(pObject->Entity == LCSE_IN);
  432. ASSERT(pObject->State == OpenInUReleased);
  433. ASSERT(pObject->Key == pPdu->u.MltmdSystmCntrlMssg_rqst.u.closeLogicalChannel.forwardLogicalChannelNumber);
  434. H245TRACE(pObject->dwInst, 2, "Close Channel received while in Released state; Channel=%d",
  435. pObject->Key);
  436. H245TRACE(pObject->dwInst, 2, "Send Close Ack; Channel=%d",
  437. pObject->Key);
  438. pOut = MemAlloc(sizeof(PDU_t));
  439. if (pOut == NULL)
  440. {
  441. H245TRACE(pObject->dwInst, 2,
  442. "closeReleased: memory allocation failed");
  443. return H245_ERROR_NOMEM;
  444. }
  445. /* Send Close Logical Channel Ack to remote peer */
  446. pdu_rsp_close_logical_channel_ack(pOut,(WORD)pObject->Key);
  447. lError = sendPDU(pObject->pInstance, pOut);
  448. MemFree(pOut);
  449. return lError;
  450. }
  451. /*
  452. * NAME
  453. * responseAwaiting - response to an open in Awaiting Establishment state
  454. *
  455. *
  456. * PARAMETERS
  457. * INPUT pObject pointer to a State Entity
  458. *
  459. * RETURN VALUE
  460. * error return codes defined in h245com.h
  461. */
  462. HRESULT responseAwaiting(Object_t *pObject, PDU_t *pPdu)
  463. {
  464. ASSERT(pObject->Entity == LCSE_IN);
  465. ASSERT(pObject->State == OpenInUAwaitingEstablishment);
  466. H245TRACE(pObject->dwInst, 2,
  467. "Send OpenAck to ASN; Channel=%d",
  468. pObject->Key);
  469. /* Send Open Logical Channel Ack to remote peer */
  470. pObject->State = OpenInUEstablished;
  471. return sendPDU(pObject->pInstance, pPdu);
  472. }
  473. /*
  474. * NAME
  475. * releaseAwaiting - response to open with open reject
  476. *
  477. *
  478. * PARAMETERS
  479. * INPUT pObject pointer to a State Entity
  480. *
  481. * RETURN VALUE
  482. * error return codes defined in h245com.h
  483. */
  484. HRESULT releaseAwaiting(Object_t *pObject, PDU_t *pPdu)
  485. {
  486. ASSERT(pObject->Entity == LCSE_IN);
  487. ASSERT(pObject->State == OpenInUAwaitingEstablishment);
  488. H245TRACE(pObject->dwInst, 2,
  489. "Send OpenReject to ASN; Channel=%d",
  490. pObject->Key);
  491. /* Send Open Logical Channel Reject to remote peer */
  492. pObject->State = OpenInUReleased;
  493. return sendPDU(pObject->pInstance, pPdu);
  494. }
  495. /*
  496. * NAME
  497. * closeAwaiting - received close unidirectional channel in Awaiting state
  498. *
  499. *
  500. * PARAMETERS
  501. * INPUT pObject pointer to a State Entity
  502. *
  503. * RETURN VALUE
  504. * error return codes defined in h245com.h
  505. */
  506. HRESULT closeAwaiting(Object_t *pObject, PDU_t *pPdu)
  507. {
  508. PDU_t * pOut;
  509. HRESULT lError;
  510. ASSERT(pObject->Entity == LCSE_IN);
  511. ASSERT(pObject->State == OpenInUAwaitingEstablishment);
  512. H245TRACE(pObject->dwInst, 2,
  513. "H245_IND_CLOSE with no error to API; Channel=%d",
  514. pObject->Key);
  515. pOut = (PDU_t *) MemAlloc(sizeof(PDU_t));
  516. if (pOut == NULL)
  517. {
  518. H245TRACE(pObject->dwInst, 2,
  519. "closeAwaiting: memory allocation failed");
  520. return H245_ERROR_NOMEM;
  521. }
  522. /* Send Close Logical Channel Ack to remote peer */
  523. pdu_rsp_close_logical_channel_ack(pOut,(WORD)pObject->Key);
  524. lError = sendPDU(pObject->pInstance, pOut);
  525. MemFree(pOut);
  526. /* Send RELEASE.indication to client */
  527. pObject->State = OpenInUReleased;
  528. H245FsmIndication(pPdu, H245_IND_CLOSE, pObject->pInstance, 0, FSM_OK);
  529. return lError;
  530. }
  531. /*
  532. * NAME
  533. * openAwaiting - received an overriding open unidirectional channel while Awaiting establishment
  534. *
  535. *
  536. * PARAMETERS
  537. * INPUT pObject pointer to a State Entity
  538. *
  539. * RETURN VALUE
  540. * error return codes defined in h245com.h
  541. */
  542. HRESULT openAwaiting(Object_t *pObject, PDU_t *pPdu)
  543. {
  544. ASSERT(pObject->Entity == LCSE_IN);
  545. ASSERT(pObject->State == OpenInUAwaitingEstablishment);
  546. H245TRACE(pObject->dwInst, 2,
  547. "H245_IND_CLOSE, then H245_IND_OPEN to API; Channel=%d",
  548. pObject->Key);
  549. pObject->State = OpenInUReleased;
  550. #if defined(SDL_COMPLIANT)
  551. /* Send RELEASE.indication (SOURCE:=USER) to client */
  552. H245FsmIndication( NULL, H245_IND_CLOSE, pObject->pInstance, 0, FSM_OK);
  553. #endif
  554. /* Send ESTABLISH.indication to client */
  555. H245FsmIndication(pPdu, H245_IND_OPEN, pObject->pInstance, 0, FSM_OK);
  556. return 0;
  557. }
  558. /*
  559. * NAME
  560. * closeEstablished - received close unidirectional channel in Established state
  561. *
  562. *
  563. * PARAMETERS
  564. * INPUT pObject pointer to a State Entity
  565. *
  566. * RETURN VALUE
  567. * error return codes defined in h245com.h
  568. */
  569. HRESULT closeEstablished(Object_t *pObject, PDU_t *pPdu)
  570. {
  571. PDU_t * pOut;
  572. HRESULT lError;
  573. ASSERT(pObject->Entity == LCSE_IN);
  574. ASSERT(pObject->State == OpenInUEstablished);
  575. H245TRACE(pObject->dwInst, 2,
  576. "H245_IND_CLOSE with no error to API; Channel=%d",
  577. pObject->Key);
  578. pOut = (PDU_t *) MemAlloc(sizeof(PDU_t ));
  579. if (pOut == NULL)
  580. {
  581. H245TRACE(pObject->dwInst, 2,
  582. "closeEstablished: memory allocation failed");
  583. return H245_ERROR_NOMEM;
  584. }
  585. /* Send Close Logical Channel Ack to remote peer */
  586. pdu_rsp_close_logical_channel_ack(pOut,(WORD)pObject->Key);
  587. lError = sendPDU(pObject->pInstance, pOut);
  588. MemFree(pOut);
  589. /* Send RELEASE.indication to clietn */
  590. pObject->State = OpenInUReleased;
  591. H245FsmIndication(pPdu, H245_IND_CLOSE, pObject->pInstance, 0, FSM_OK);
  592. return lError;
  593. }
  594. /*
  595. * NAME
  596. * openEstablished - received overriding open unidirectional channel in Established state
  597. *
  598. *
  599. * PARAMETERS
  600. * INPUT pObject pointer to a State Entity
  601. *
  602. * RETURN VALUE
  603. * error return codes defined in h245com.h
  604. */
  605. HRESULT openEstablished(Object_t *pObject, PDU_t *pPdu)
  606. {
  607. ASSERT(pObject->Entity == LCSE_IN);
  608. ASSERT(pObject->State == OpenInUEstablished);
  609. H245TRACE(pObject->dwInst, 2,
  610. "H245_IND_CLOSE followed by H245_IND_OPEN to API; Channel=%d",
  611. pObject->Key);
  612. #if defined(SDL_COMPLIANT)
  613. /* Send RELEASE.indication (SOURCE:=USER) to client - not necessary */
  614. H245FsmIndication( NULL, H245_IND_CLOSE, pObject->pInstance, 0, FSM_OK);
  615. #endif
  616. /* Send ESTABLISH.indication to client */
  617. H245FsmIndication( pPdu, H245_IND_OPEN, pObject->pInstance, 0, FSM_OK);
  618. return 0;
  619. }
  620.