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.

577 lines
17 KiB

  1. /***********************************************************************
  2. * *
  3. * Filename: mlse.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: MLSE.C $
  17. * $Revision: 1.4 $
  18. * $Modtime: 09 Dec 1996 13:34:24 $
  19. * $Log: S:/STURGEON/SRC/H245/SRC/VCS/MLSE.C_v $
  20. *
  21. * Rev 1.4 09 Dec 1996 13:34:46 EHOWARDX
  22. * Updated copyright notice.
  23. *
  24. * Rev 1.3 04 Jun 1996 13:57:24 EHOWARDX
  25. * Fixed Release build warnings.
  26. *
  27. * Rev 1.2 30 May 1996 23:39:14 EHOWARDX
  28. * Cleanup.
  29. *
  30. * Rev 1.1 28 May 1996 14:25:42 EHOWARDX
  31. * Tel Aviv update.
  32. *
  33. * Rev 1.0 09 May 1996 21:06:30 EHOWARDX
  34. * Initial revision.
  35. *
  36. * Rev 1.1 09 May 1996 19:48:26 EHOWARDX
  37. * Change TimerExpiryF function arguements.
  38. *
  39. * Rev 1.0 15 Apr 1996 10:46:58 EHOWARDX
  40. * Initial revision.
  41. * *
  42. ***********************************************************************/
  43. #include "precomp.h"
  44. #include "h245api.h"
  45. #include "h245com.h"
  46. #include "h245fsm.h"
  47. #include "mlse.h"
  48. // Out-going/In-coming MLSE states
  49. #define MLSE_NOT_LOOPED 0 // NOT LOOPED
  50. #define MLSE_WAIT 1 // AWAITING RESPONSE
  51. #define MLSE_LOOPED 1 // LOOPED
  52. extern unsigned int uT102;
  53. /***********************************************************************
  54. *
  55. * LOCAL FUNCTIONS
  56. *
  57. ***********************************************************************/
  58. /*
  59. * NAME
  60. * T102ExpiryF - Callback function called by the timer
  61. *
  62. *
  63. * PARAMETERS
  64. * INPUT dwInst current instance of H245
  65. * INPUT id timer id
  66. * INPUT pObject pointer to a State Entity
  67. *
  68. *
  69. * RETURN VALUE
  70. * OK
  71. */
  72. int T102ExpiryF(struct InstanceStruct *pInstance, DWORD_PTR dwTimerId, void *pObject)
  73. {
  74. return FsmTimerEvent(pInstance, dwTimerId, pObject, T102Expiry);
  75. } // T102ExpiryF()
  76. static void BuildMaintenanceLoopOffCommand(PDU_t *pPdu)
  77. {
  78. pPdu->choice = MSCMg_cmmnd_chosen;
  79. pPdu->u.MSCMg_cmmnd.choice = mntnncLpOffCmmnd_chosen;
  80. } // BuildMaintenanceLoopOffCommand()
  81. /***********************************************************************
  82. *
  83. * OUT-GOING FINITE STATE MACHINE FUNCTIONS
  84. *
  85. ***********************************************************************/
  86. /*
  87. * NAME
  88. * MLSE0_LOOP_requestF - LOOP.request from API in NOT LOOPED state
  89. *
  90. *
  91. * PARAMETERS
  92. * INPUT pObject pointer to State Entity
  93. * INPUT pPdu pointer to PDU
  94. *
  95. * RETURN VALUE
  96. * Error return codes defined in h245com.h
  97. */
  98. HRESULT MLSE0_LOOP_requestF (Object_t *pObject, PDU_t *pPdu)
  99. {
  100. HRESULT lError;
  101. ASSERT(pObject->Entity == MLSE_OUT);
  102. ASSERT(pObject->State == MLSE_NOT_LOOPED);
  103. H245TRACE(pObject->dwInst, 2, "MLSE0_LOOP_request:%d", pObject->Key);
  104. // Save type from PDU
  105. pObject->u.mlse.wLoopType =
  106. pPdu->u.MltmdSystmCntrlMssg_rqst.u.maintenanceLoopRequest.type.choice;
  107. // Send Maintenance Loop Request PDU to remote peer
  108. lError = sendPDU(pObject->pInstance, pPdu);
  109. // Set timer T102
  110. pObject->State = MLSE_WAIT;
  111. FsmStartTimer(pObject, T102ExpiryF, uT102);
  112. return lError;
  113. } // MLSE0_LOOP_request
  114. /*
  115. * NAME
  116. * MLSE1_MaintenanceLoopAckF - MaintenanceLoopAck in AWAITING RESPONSE state
  117. *
  118. *
  119. * PARAMETERS
  120. * INPUT pObject pointer to State Entity
  121. * INPUT pPdu pointer to PDU
  122. *
  123. * RETURN VALUE
  124. * Error return codes defined in h245com.h
  125. */
  126. HRESULT MLSE1_MaintenanceLoopAckF (Object_t *pObject, PDU_t *pPdu)
  127. {
  128. ASSERT(pObject->Entity == MLSE_OUT);
  129. ASSERT(pObject->State == MLSE_WAIT);
  130. H245TRACE(pObject->dwInst, 2, "MLSE1_MaintenanceLoopAck:%d", pObject->Key);
  131. // Reset timer T102
  132. FsmStopTimer(pObject);
  133. // Send LOOP.confirm to client
  134. pObject->State = MLSE_LOOPED;
  135. H245FsmConfirm(pPdu, H245_CONF_MLSE, pObject->pInstance, pObject->dwTransId, FSM_OK);
  136. return 0;
  137. } // MLSE1_MaintenanceLoopAck
  138. /*
  139. * NAME
  140. * MLSE1_MaintenanceLoopRejF - MaintenanceLoopReject in AWAITING RESPONSE state
  141. *
  142. *
  143. * PARAMETERS
  144. * INPUT pObject pointer to State Entity
  145. * INPUT pPdu pointer to PDU
  146. *
  147. * RETURN VALUE
  148. * Error return codes defined in h245com.h
  149. */
  150. HRESULT MLSE1_MaintenanceLoopRejF (Object_t *pObject, PDU_t *pPdu)
  151. {
  152. ASSERT(pObject->Entity == MLSE_OUT);
  153. ASSERT(pObject->State == MLSE_WAIT);
  154. H245TRACE(pObject->dwInst, 2, "MLSE1_MaintenanceLoopRej:%d", pObject->Key);
  155. // Reset timer T102
  156. FsmStopTimer(pObject);
  157. // Send RELEASE.indication to client
  158. pObject->State = MLSE_NOT_LOOPED;
  159. H245FsmConfirm(pPdu, H245_CONF_MLSE_REJECT, pObject->pInstance, pObject->dwTransId, FSM_OK);
  160. return 0;
  161. } // MLSE1_MaintenanceLoopRej
  162. /*
  163. * NAME
  164. * MLSE1_OUT_RELEASE_requestF - RELEASE.request from API in AWAITING RESPONSE state
  165. *
  166. *
  167. * PARAMETERS
  168. * INPUT pObject pointer to State Entity
  169. * INPUT pPdu pointer to PDU
  170. *
  171. * RETURN VALUE
  172. * Error return codes defined in h245com.h
  173. */
  174. HRESULT MLSE1_OUT_RELEASE_requestF (Object_t *pObject, PDU_t *pPdu)
  175. {
  176. ASSERT(pObject->Entity == MLSE_OUT);
  177. ASSERT(pObject->State == MLSE_WAIT);
  178. H245TRACE(pObject->dwInst, 2, "MLSE1_OUT_RELEASE_request:%d", pObject->Key);
  179. // Send MaintenanceLoopOffCommand PDU to remote peer
  180. pObject->State = MLSE_NOT_LOOPED;
  181. BuildMaintenanceLoopOffCommand(pPdu);
  182. return sendPDU(pObject->pInstance, pPdu);
  183. } // MLSE1_OUT_RELEASE_request
  184. /*
  185. * NAME
  186. * MLSE1_T102ExpiryF - timer T102 Expiry in AWAITING RESPONSE state
  187. *
  188. *
  189. * PARAMETERS
  190. * INPUT pObject pointer to State Entity
  191. * INPUT pPdu pointer to PDU
  192. *
  193. * RETURN VALUE
  194. * Error return codes defined in h245com.h
  195. */
  196. HRESULT MLSE1_T102ExpiryF (Object_t *pObject, PDU_t *pPdu)
  197. {
  198. PDU_t * pOut;
  199. HRESULT lError;
  200. ASSERT(pObject->Entity == MLSE_OUT);
  201. ASSERT(pObject->State == MLSE_WAIT);
  202. ASSERT(pPdu == NULL);
  203. H245TRACE(pObject->dwInst, 2, "MLSE1_T102Expiry:%d", pObject->Key);
  204. // Send MaintenanceLoopOffCommand PDU to remote peer
  205. pOut = MemAlloc(sizeof(*pOut));
  206. if (pOut == NULL)
  207. {
  208. H245TRACE(pObject->dwInst, 2,
  209. "MLSE1_T102ExpiryF: memory allocation failed");
  210. return H245_ERROR_NOMEM;
  211. }
  212. BuildMaintenanceLoopOffCommand(pOut);
  213. lError = sendPDU(pObject->pInstance, pOut);
  214. MemFree(pOut);
  215. // Send RELEASE.indication to client
  216. // SOURCE := MLSE
  217. pObject->State = MLSE_NOT_LOOPED;
  218. H245FsmConfirm(NULL, H245_CONF_MLSE_EXPIRED, pObject->pInstance, pObject->dwTransId, FSM_OK);
  219. return lError;
  220. } // MLSE1_T102Expiry
  221. /*
  222. * NAME
  223. * MLSE2_MaintenanceLoopRejF - MaintenanceLoopReject in LOOPED state
  224. *
  225. *
  226. * PARAMETERS
  227. * INPUT pObject pointer to State Entity
  228. * INPUT pPdu pointer to PDU
  229. *
  230. * RETURN VALUE
  231. * Error return codes defined in h245com.h
  232. */
  233. HRESULT MLSE2_MaintenanceLoopRejF (Object_t *pObject, PDU_t *pPdu)
  234. {
  235. ASSERT(pObject->Entity == MLSE_OUT);
  236. ASSERT(pObject->State == MLSE_WAIT);
  237. H245TRACE(pObject->dwInst, 2, "MLSE2_MaintenanceLoopRej:%d", pObject->Key);
  238. pObject->State = MLSE_NOT_LOOPED;
  239. #if defined(SDL_COMPLIANT)
  240. // Send ERROR.indication(B) to client
  241. // TBD
  242. #endif
  243. // Send RELEASE.indication to client
  244. // SOURCE := MLSE
  245. H245FsmConfirm(pPdu, H245_CONF_MLSE_REJECT, pObject->pInstance, pObject->dwTransId, FSM_OK);
  246. return 0;
  247. } // MLSE2_MaintenanceLoopRej
  248. /*
  249. * NAME
  250. * MLSE2_OUT_RELEASE_requestF - RELEASE.request from API in LOOPED state
  251. *
  252. *
  253. * PARAMETERS
  254. * INPUT pObject pointer to State Entity
  255. * INPUT pPdu pointer to PDU
  256. *
  257. * RETURN VALUE
  258. * Error return codes defined in h245com.h
  259. */
  260. HRESULT MLSE2_OUT_RELEASE_requestF (Object_t *pObject, PDU_t *pPdu)
  261. {
  262. ASSERT(pObject->Entity == MLSE_OUT);
  263. ASSERT(pObject->State == MLSE_WAIT);
  264. H245TRACE(pObject->dwInst, 2, "MLSE2_OUT_RELEASE_request:%d", pObject->Key);
  265. // Send MaintenanceLoopOffCommand PDU to remote peer
  266. pObject->State = MLSE_NOT_LOOPED;
  267. BuildMaintenanceLoopOffCommand(pPdu);
  268. return sendPDU(pObject->pInstance, pPdu);
  269. } // MLSE2_OUT_RELEASE_request
  270. /***********************************************************************
  271. *
  272. * IN-COMING FINITE STATE MACHINE FUNCTIONS
  273. *
  274. ***********************************************************************/
  275. /*
  276. * NAME
  277. * MLSE0_MaintenanceLoopRequestF - MaintenanceLoopRequest received in NOT LOOPED state
  278. *
  279. *
  280. * PARAMETERS
  281. * INPUT pObject pointer to State Entity
  282. * INPUT pPdu pointer to PDU
  283. *
  284. * RETURN VALUE
  285. * Error return codes defined in h245com.h
  286. */
  287. HRESULT MLSE0_MaintenanceLoopRequestF (Object_t *pObject, PDU_t *pPdu)
  288. {
  289. ASSERT(pObject->Entity == MLSE_IN);
  290. ASSERT(pObject->State == MLSE_NOT_LOOPED);
  291. H245TRACE(pObject->dwInst, 2, "MLSE0_MaintenanceLoopRequest:%d", pObject->Key);
  292. // Save type from PDU
  293. pObject->u.mlse.wLoopType =
  294. pPdu->u.MltmdSystmCntrlMssg_rqst.u.maintenanceLoopRequest.type.choice;
  295. // Send LOOP.indication to client
  296. pObject->State = MLSE_WAIT;
  297. H245FsmIndication(pPdu, H245_IND_MLSE, pObject->pInstance, pObject->dwTransId, FSM_OK);
  298. return 0;
  299. } // MLSE0_MaintenanceLoopRequest
  300. /*
  301. * NAME
  302. * MLSE1_MaintenanceLoopRequestF - MaintenanceLoopRequest received in AWAITING RESPONSE state
  303. *
  304. *
  305. * PARAMETERS
  306. * INPUT pObject pointer to State Entity
  307. * INPUT pPdu pointer to PDU
  308. *
  309. * RETURN VALUE
  310. * Error return codes defined in h245com.h
  311. */
  312. HRESULT MLSE1_MaintenanceLoopRequestF (Object_t *pObject, PDU_t *pPdu)
  313. {
  314. ASSERT(pObject->Entity == MLSE_IN);
  315. ASSERT(pObject->State == MLSE_WAIT);
  316. H245TRACE(pObject->dwInst, 2, "MLSE1_MaintenanceLoopRequest:%d", pObject->Key);
  317. // Save type from PDU
  318. pObject->u.mlse.wLoopType =
  319. pPdu->u.MltmdSystmCntrlMssg_rqst.u.maintenanceLoopRequest.type.choice;
  320. #if defined(SDL_COMPLIANT)
  321. // Send RELEASE.indication to client
  322. H245FsmIndication(pPdu, H245_IND_MLSE_RELEASE, pObject->pInstance, pObject->dwTransId, FSM_OK);
  323. #endif
  324. // Send LOOP.indication to client
  325. H245FsmIndication(pPdu, H245_IND_MLSE, pObject->pInstance, pObject->dwTransId, FSM_OK);
  326. return 0;
  327. } // MLSE1_MaintenanceLoopRequest
  328. /*
  329. * NAME
  330. * MLSE1_MaintenanceLoopReleaseF - MaintenanceLoopOffCommand received in AWAITING RESPONSE state
  331. *
  332. *
  333. * PARAMETERS
  334. * INPUT pObject pointer to State Entity
  335. * INPUT pPdu pointer to PDU
  336. *
  337. * RETURN VALUE
  338. * Error return codes defined in h245com.h
  339. */
  340. HRESULT MLSE1_MaintenanceLoopOffCommandF(Object_t *pObject, PDU_t *pPdu)
  341. {
  342. ASSERT(pObject->Entity == MLSE_IN);
  343. ASSERT(pObject->State == MLSE_WAIT);
  344. H245TRACE(pObject->dwInst, 2, "MLSE1_MaintenanceLoopOffCommand:%d", pObject->Key);
  345. // Send RELEASE.indication to client
  346. pObject->State = MLSE_NOT_LOOPED;
  347. H245FsmIndication(pPdu, H245_IND_MLSE_RELEASE, pObject->pInstance, pObject->dwTransId, FSM_OK);
  348. return 0;
  349. } // MLSE1_MaintenanceLoopOffCommand
  350. /*
  351. * NAME
  352. * MLSE1_LOOP_responseF - LOOP.response from API in AWAITING RESPONSE state
  353. *
  354. *
  355. * PARAMETERS
  356. * INPUT pObject pointer to State Entity
  357. * INPUT pPdu pointer to PDU
  358. *
  359. * RETURN VALUE
  360. * Error return codes defined in h245com.h
  361. */
  362. HRESULT MLSE1_LOOP_responseF (Object_t *pObject, PDU_t *pPdu)
  363. {
  364. ASSERT(pObject->Entity == MLSE_IN);
  365. ASSERT(pObject->State == MLSE_WAIT);
  366. H245TRACE(pObject->dwInst, 2, "MLSE1_LOOP_response:%d", pObject->Key);
  367. // Send MaintenanceLoopAck PDU to remote peer
  368. pPdu->u.MSCMg_rspns.u.maintenanceLoopAck.type.choice = pObject->u.mlse.wLoopType;
  369. switch (pObject->u.mlse.wLoopType)
  370. {
  371. case systemLoop_chosen:
  372. break;
  373. case mediaLoop_chosen:
  374. pPdu->u.MSCMg_rspns.u.maintenanceLoopAck.type.u.mediaLoop = (WORD)pObject->Key;
  375. break;
  376. case logicalChannelLoop_chosen:
  377. pPdu->u.MSCMg_rspns.u.maintenanceLoopAck.type.u.logicalChannelLoop = (WORD)pObject->Key;
  378. break;
  379. default:
  380. H245TRACE(pObject->dwInst, 1, "Invalid loop type %d", pObject->u.mlse.wLoopType);
  381. } // switch
  382. pObject->State = MLSE_LOOPED;
  383. return sendPDU(pObject->pInstance, pPdu);
  384. } // MLSE1_LOOP_response
  385. /*
  386. * NAME
  387. * MLSE1_IN_RELEASE_requestF - RELEASE.request from API in AWAITING RESPONSE state
  388. *
  389. *
  390. * PARAMETERS
  391. * INPUT pObject pointer to State Entity
  392. * INPUT pPdu pointer to PDU
  393. *
  394. * RETURN VALUE
  395. * Error return codes defined in h245com.h
  396. */
  397. HRESULT MLSE1_IN_RELEASE_requestF (Object_t *pObject, PDU_t *pPdu)
  398. {
  399. ASSERT(pObject->Entity == MLSE_IN);
  400. ASSERT(pObject->State == MLSE_WAIT);
  401. H245TRACE(pObject->dwInst, 2, "MLSE1_IN_RELEASE_request:%d", pObject->Key);
  402. // Send MaintenanceLoopReject PDU to remote peer
  403. pPdu->u.MSCMg_rspns.u.maintenanceLoopReject.type.choice = pObject->u.mlse.wLoopType;
  404. switch (pObject->u.mlse.wLoopType)
  405. {
  406. case systemLoop_chosen:
  407. break;
  408. case mediaLoop_chosen:
  409. pPdu->u.MSCMg_rspns.u.maintenanceLoopReject.type.u.mediaLoop = (WORD)pObject->Key;
  410. break;
  411. case logicalChannelLoop_chosen:
  412. pPdu->u.MSCMg_rspns.u.maintenanceLoopReject.type.u.logicalChannelLoop = (WORD)pObject->Key;
  413. break;
  414. default:
  415. H245TRACE(pObject->dwInst, 1, "Invalid loop type %d", pObject->u.mlse.wLoopType);
  416. } // switch
  417. pObject->State = MLSE_NOT_LOOPED;
  418. return sendPDU(pObject->pInstance, pPdu);
  419. } // MLSE1_IN_RELEASE_request
  420. /*
  421. * NAME
  422. * MLSE2_MaintenanceLoopRequestF - MaintenanceLoopRequest received in LOOPED state
  423. *
  424. *
  425. * PARAMETERS
  426. * INPUT pObject pointer to State Entity
  427. * INPUT pPdu pointer to PDU
  428. *
  429. * RETURN VALUE
  430. * Error return codes defined in h245com.h
  431. */
  432. HRESULT MLSE2_MaintenanceLoopRequestF (Object_t *pObject, PDU_t *pPdu)
  433. {
  434. ASSERT(pObject->Entity == MLSE_IN);
  435. ASSERT(pObject->State == MLSE_LOOPED);
  436. H245TRACE(pObject->dwInst, 2, "MLSE2_MaintenanceLoopRequest:%d", pObject->Key);
  437. // Save type from PDU
  438. pObject->u.mlse.wLoopType =
  439. pPdu->u.MltmdSystmCntrlMssg_rqst.u.maintenanceLoopRequest.type.choice;
  440. pObject->State = MLSE_WAIT;
  441. #if defined(SDL_COMPLIANT)
  442. // Send RELEASE.indication to client
  443. H245FsmIndication(pPdu, H245_IND_MLSE_RELEASE, pObject->pInstance, pObject->dwTransId, FSM_OK);
  444. #endif
  445. // Send LOOP.indication to client
  446. H245FsmIndication(pPdu, H245_IND_MLSE, pObject->pInstance, pObject->dwTransId, FSM_OK);
  447. return 0;
  448. } // MLSE2_MaintenanceLoopRequest
  449. /*
  450. * NAME
  451. * MLSE2_MaintenanceLoopReleaseF - MaintenanceLoopOffCommand received in LOOPED state
  452. *
  453. *
  454. * PARAMETERS
  455. * INPUT pObject pointer to State Entity
  456. * INPUT pPdu pointer to PDU
  457. *
  458. * RETURN VALUE
  459. * Error return codes defined in h245com.h
  460. */
  461. HRESULT MLSE2_MaintenanceLoopOffCommandF(Object_t *pObject, PDU_t *pPdu)
  462. {
  463. ASSERT(pObject->Entity == MLSE_IN);
  464. ASSERT(pObject->State == MLSE_LOOPED);
  465. H245TRACE(pObject->dwInst, 2, "MLSE2_MaintenanceLoopOffCommand:%d", pObject->Key);
  466. // Send RELEASE.indication to client
  467. pObject->State = MLSE_NOT_LOOPED;
  468. H245FsmIndication(pPdu, H245_IND_MLSE_RELEASE, pObject->pInstance, pObject->dwTransId, FSM_OK);
  469. return 0;
  470. } // MLSE2_MaintenanceLoopOffCommand
  471.