Source code of Windows XP (NT5)
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.

3131 lines
99 KiB

  1. #include "precomp.h"
  2. DEBUG_FILEZONE(ZONE_T120_T123PSTN);
  3. /* Q922.cpp
  4. *
  5. * Copyright (c) 1993-1995 by DataBeam Corporation, Lexington, KY
  6. *
  7. * Abstract:
  8. * This is the implementation file for the Q.922 Data Link protocol.
  9. * Before diving into the code, it is recommended that you read the
  10. * Q.922 protocol.
  11. *
  12. * Private Instance Variables:
  13. * m_pT123 - Address of the owner of this object. Used for
  14. * owner callbacks.
  15. * m_pMultiplexer - Address of ProtocolLayer below Q922 in the
  16. * stack.
  17. * Higher_Layer - Address of ProtocolLayer above Q922 in the
  18. * stack.
  19. * m_nMsgBase - Message base used in owner callbacks.
  20. * DLCI - DLCI used to identfy Q922 entities.
  21. * Link_Originator - TRUE if we are the link originators. If we are,
  22. * we sent out the first SABME packet.
  23. * Maximum_Information_Size-
  24. * Holds the maximum packet size that we support.
  25. * SABME_Pending - TRUE if we need to initiate the link.
  26. * Unnumbered_Acknowledge_Pending - TRUE if we need to send out an
  27. * Unnumbered Ack. packet. This is
  28. * done in response to a SABME or DISC.
  29. * DISC_Pending - TRUE if we need to send out a DISConnect packet.
  30. * Unnumbered_PF_State - Holds the Poll/Final state of an unnumbered
  31. * packet.
  32. * Final_Packet - TRUE if the next Unnumbered Ack. sent out is
  33. * our final packet to transmit before notifying
  34. * the owner that the link is broken.
  35. * Data_Indication_Size- Number of data indication buffers available
  36. * Data_Indication - Base address of data indication buffers
  37. * Data_Indication_Head- Head of data indication queue
  38. * Data_Indication_Tail- Tail of read data indication queue
  39. * Data_Indication_Count- Number of data indication buffers in use
  40. *
  41. * Data_Request_Size - Number of data request buffers
  42. * Data_Request_Total_Size - Number of data request buffers + maximum
  43. * number of outstanding packets
  44. * Data_Request - Base address of data request buffers
  45. * Data_Request_Head - Head of data request queue
  46. * Data_Request_Tail - Tail of data request queue
  47. * Data_Request_Count - Number of data request buffers in use
  48. * Data_Request_Acknowledge_Tail- Tail of the queue referring to packets
  49. * that have been acknowledged
  50. *
  51. * Supervisory_Write_Struct - Buffer used for supervisory packets
  52. * Send_State_Variable - This is the sequence number that will
  53. * be sent in the next information packet
  54. * to uniquely identify the packet. The
  55. * number is between 0 and 127.
  56. * Receive_State_Variable - Receive Sequence Number. The expected
  57. * sequence number of the next Information
  58. * packet we receive
  59. * Acknowledge_State_Variable - This is the sequence number that the
  60. * remote site is expecting in our next
  61. * information packet
  62. * Own_Receiver_Busy - If our read buffers are full, we set
  63. * this flag so that we send a Receiver
  64. * Not Ready packet to the remote site
  65. * Peer_Receiver_Busy - Remote site is not ready to receive
  66. * Information packets
  67. *
  68. * Command_Pending - When this flag is set to TRUE, we send
  69. * a Supervisory/Command packet to the
  70. * remote site.
  71. *
  72. * We need to send a Supervisory/Command
  73. * packet when our receiver is no longer
  74. * busy. This tells the remote site to
  75. * resume sending Information packets to
  76. * us.
  77. * Poll_Pending - This flag tells us to send a Supervisory
  78. * command to the remote location with the
  79. * Poll flag set. This tells the remote
  80. * site to reply to this command
  81. * Final_Pending - This flag is set when we need to reply
  82. * to a remote command
  83. * Acknowledge_Pending - This flag signals us to send a
  84. * Supervisory/Response packet to the
  85. * remote site.
  86. * Reject_Pending - Signals us to send a Supervisory/
  87. * Response packet to the remote site
  88. * indicating that we missed a packet.
  89. * Reject_Outstanding - Internal flag telling us that our Reject
  90. * packet has been sent and don't send
  91. * another one
  92. * T200_Timeout - Timeout value. If we send out a packet
  93. * and expect a response, and T200_Timeout
  94. * expires, we enter the TIMER_RECOVERY
  95. * mode.
  96. * T200_Handle - Handle to timer event.
  97. * T200_Active - Flag that signals if T200 is running
  98. * N200_Count - Number of times T200 expires in a row
  99. * without a response from the remote site.
  100. *
  101. * T203_Timeout - Timeout value. If we don't receive a
  102. * packet from the remote site in T203
  103. * time, we enter the TIMER_RECOVERY mode.
  104. * T203_Handle - Handle to timer event
  105. * T203_Active - Flag that signals if T203 is running.
  106. * Maximum_T200_Timeouts - Maximum number of T200 timeouts before
  107. * we consider the link unstable.
  108. * Data_Link_Mode - Our mode of operation.
  109. * MULTIPLE_FRAME_ESTABLISHED
  110. * TIMER_RECOVERY
  111. * Link_Stable - Flag that indicates if our current
  112. * connection is stable. FALSE if the
  113. * N200_Count == Maximum number of T200
  114. * timeouts
  115. * Receive_Sequence_Exception - Set if we receive an ILLEGAL sequence
  116. * number
  117. * Maximum_Outstanding_Packets - Maximum number of packets that we can
  118. * have out on the line at a time.
  119. * Outstanding_Packets - Actual number of packets outstanding
  120. * Maximum_Outstanding_Bytes - Maximum number of bytes that can be
  121. * on the line at any one time. It is VERY
  122. * important to note that using this as a
  123. * limiting factor on transmission is NOT
  124. * a protocol defined limit. This was
  125. * added to our Q922 because we had
  126. * problems with some modems that were
  127. * buffering our Tx data. Some modems
  128. * would buffer up to 4K of data. This is
  129. * unacceptable to us because our timeouts
  130. * would expire before the data left the
  131. * modem. Using this parameter as a
  132. * limiting factor validates our timer
  133. * values.
  134. * Outstanding_Bytes - Actual number of bytes on the line at
  135. * the current time.
  136. * Total_Retransmitted - Number of packets that have been
  137. * retransmitted.
  138. * Data_Request_Memory_Manager - Memory manager used for all DataRequests
  139. * Lower_Layer_Prepend - Number of bytes prepended to each packet
  140. * by the lower layer
  141. * Lower_Layer_Append - Number of bytes appended to packet by
  142. * the lower layer.
  143. *
  144. * Caveats:
  145. * None.
  146. *
  147. * Authors:
  148. * James P. Galvin
  149. * James W. Lawwill
  150. */
  151. #include "q922.h"
  152. /*
  153. * CLayerQ922::CLayerQ922 (
  154. * PTransportResources transport_resources,
  155. * IObject * owner_object,
  156. * IProtocolLayer * lower_layer,
  157. * USHORT message_base,
  158. * USHORT identifier,
  159. * BOOL link_originator,
  160. * USHORT data_indication_queue_siz,
  161. * USHORT data_request_queue_size,
  162. * USHORT k_factor,
  163. * USHORT max_information_size,
  164. * USHORT t200,
  165. * USHORT call_control_type,
  166. * USHORT max_outstanding_bytes,
  167. * PMemoryManager memory_manager,
  168. * BOOL * initialized)
  169. *
  170. * Public
  171. *
  172. * Functional Description:
  173. * This is the CLayerQ922 constructor. This routine initializes all
  174. * variables and allocates buffer space.
  175. */
  176. CLayerQ922::CLayerQ922
  177. (
  178. T123 *owner_object,
  179. Multiplexer *pMux, // lower layer
  180. USHORT message_base,
  181. USHORT identifier,
  182. BOOL link_originator,
  183. USHORT data_indication_queue_size,
  184. USHORT data_request_queue_size,
  185. USHORT k_factor,
  186. USHORT max_information_size,
  187. USHORT t200,
  188. USHORT max_outstanding_bytes,
  189. PMemoryManager memory_manager,
  190. PLUGXPRT_PSTN_CALL_CONTROL call_control_type,
  191. PLUGXPRT_PARAMETERS *pParams,
  192. BOOL * initialized
  193. )
  194. :
  195. m_pT123(owner_object),
  196. m_nMsgBase(message_base),
  197. m_pMultiplexer(pMux)
  198. {
  199. TRACE_OUT(("CLayerQ922::CLayerQ922"));
  200. ProtocolLayerError error;
  201. USHORT packet_size;
  202. USHORT i;
  203. DLCI = identifier;
  204. Link_Originator = link_originator;
  205. Maximum_Outstanding_Packets = k_factor;
  206. T200_Timeout = t200;
  207. Maximum_Information_Size = max_information_size;
  208. Maximum_Outstanding_Bytes = max_outstanding_bytes;
  209. Data_Request_Memory_Manager = memory_manager;
  210. Higher_Layer = NULL;
  211. Data_Request = NULL;
  212. Data_Indication = NULL;
  213. Data_Indication_Buffer = NULL;
  214. *initialized = TRUE;
  215. /*
  216. ** Find the maximum packet size supported by the lower layer
  217. */
  218. m_pMultiplexer->GetParameters(
  219. &packet_size,
  220. &Lower_Layer_Prepend,
  221. &Lower_Layer_Append);
  222. if (Maximum_Information_Size > packet_size)
  223. Maximum_Information_Size = packet_size;
  224. TRACE_OUT(("Q922: DLCI %d: Max information Size = %d", DLCI, Maximum_Information_Size));
  225. /*
  226. ** Register with the lower layer
  227. */
  228. error = m_pMultiplexer->RegisterHigherLayer(
  229. identifier,
  230. Data_Request_Memory_Manager,
  231. (IProtocolLayer *) this);
  232. if (error != PROTOCOL_LAYER_NO_ERROR)
  233. {
  234. *initialized = FALSE;
  235. ERROR_OUT(("Q922: DLCI %d: constructor: Error registering with lower layer", DLCI));
  236. }
  237. /*
  238. ** Allocation of data indication buffers. Allocate the prescribed number
  239. */
  240. Data_Indication_Size = data_indication_queue_size;
  241. Data_Indication =
  242. (PDataQueue) LocalAlloc (LMEM_FIXED, (sizeof (DataQueue) * Data_Indication_Size));
  243. if (Data_Indication != NULL)
  244. {
  245. Data_Indication_Buffer = (LPBYTE)
  246. LocalAlloc (LMEM_FIXED, Maximum_Information_Size * Data_Indication_Size);
  247. if (Data_Indication_Buffer != NULL)
  248. {
  249. for (i=0; i<Data_Indication_Size; i++)
  250. {
  251. (Data_Indication + i) -> buffer_address =
  252. Data_Indication_Buffer + (i * Maximum_Information_Size);
  253. (Data_Indication + i) -> length = 0;
  254. }
  255. }
  256. else
  257. *initialized = FALSE;
  258. }
  259. else
  260. *initialized = FALSE;
  261. /*
  262. ** Allocation of data request buffers. Allocate enough buffers for
  263. ** outstanding buffers as well as the buffers queued for delivery.
  264. */
  265. Data_Request_Size = data_request_queue_size;
  266. Data_Request_Total_Size = Data_Request_Size + Maximum_Outstanding_Packets;
  267. Data_Request = (PMemory *)
  268. LocalAlloc (LMEM_FIXED, (sizeof (PMemory) * Data_Request_Total_Size));
  269. if (Data_Request == NULL)
  270. *initialized = FALSE;
  271. /*
  272. ** Allocate one buffer for Supervisory data
  273. */
  274. T200_Active = FALSE;
  275. T203_Active = FALSE;
  276. /*
  277. ** These veriables need to be set to 0 before we call Reset(). Reset()
  278. ** will attempt to free any memory block that are in the Data_Request
  279. ** list. Since we are just initializing and there aren't any memory
  280. ** blocks in the array, there aren't any to release.
  281. */
  282. Data_Request_Head = 0;
  283. Data_Request_Tail = 0;
  284. Data_Request_Count = 0;
  285. Data_Request_Acknowledge_Tail = 0;
  286. Reset ();
  287. T203_Timeout = (call_control_type == PLUGXPRT_PSTN_CALL_CONTROL_MANUAL) ?
  288. DEFAULT_T203_COMM_TIMEOUT : DEFAULT_T203_TIMEOUT;
  289. Startup_Maximum_T200_Timeouts = DEFAULT_MAXIMUM_T200_TIMEOUTS;
  290. if (NULL != pParams)
  291. {
  292. if (PSTN_PARAM__MAX_T200_TIMEOUT_COUNT_IN_Q922 & pParams->dwFlags)
  293. {
  294. if (Startup_Maximum_T200_Timeouts <= pParams->cMaximumT200TimeoutsInQ922)
  295. {
  296. Startup_Maximum_T200_Timeouts = pParams->cMaximumT200TimeoutsInQ922;
  297. }
  298. }
  299. if (PSTN_PARAM__T203_TIMEOUT_IN_Q922 & pParams->dwFlags)
  300. {
  301. if (T203_Timeout <= pParams->nT203TimeoutInQ922)
  302. {
  303. T203_Timeout = pParams->nT203TimeoutInQ922;
  304. }
  305. }
  306. }
  307. #if 0
  308. DWORD dwSiz = 4;
  309. DWORD valType = 0;
  310. HKEY hkey;
  311. // If we are using null modem.
  312. if(call_control_type == PLUGXPRT_PSTN_CALL_CONTROL_MANUAL)
  313. {
  314. //
  315. // Open the registry key that contains the configuration info for number of timeouts
  316. //
  317. if (RegOpenKey( HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Conferencing\\Transports\\DIRCB\0", &hkey) == ERROR_SUCCESS)
  318. {
  319. if (RegQueryValueEx(hkey, "nTimeouts\0", 0, &valType,
  320. (LPBYTE)&Startup_Maximum_T200_Timeouts, &dwSiz) != ERROR_SUCCESS || Startup_Maximum_T200_Timeouts < DEFAULT_MAXIMUM_T200_TIMEOUTS)
  321. {
  322. Startup_Maximum_T200_Timeouts = DEFAULT_MAXIMUM_T200_TIMEOUTS;
  323. }
  324. RegCloseKey(hkey);
  325. }
  326. }
  327. #endif
  328. Link_Maximum_T200_Timeouts = Startup_Maximum_T200_Timeouts;
  329. Maximum_T200_Timeouts = Startup_Maximum_T200_Timeouts;
  330. /*
  331. ** If I am the link originator, enter the AWAITING_ESTABLISHMENT mode and
  332. ** send out the SABME packet.
  333. */
  334. if (Link_Originator)
  335. {
  336. SABME_Pending = TRUE;
  337. Unnumbered_PF_State = UNNUMBERED_PF_SET;
  338. Data_Link_Mode = AWAITING_ESTABLISHMENT;
  339. }
  340. else
  341. {
  342. /*
  343. ** If we are not the link originator, enter the TEI_ASSIGNED mode and
  344. ** start the T203 timer, if we don't receive a packet in X seconds,
  345. ** abort the operation
  346. */
  347. Data_Link_Mode = TEI_ASSIGNED;
  348. SABME_Pending = FALSE;
  349. StartTimerT203 ();
  350. }
  351. if (*initialized == FALSE)
  352. {
  353. ERROR_OUT(("Q922: DLCI %d: Init failed", DLCI));
  354. }
  355. }
  356. /*
  357. * CLayerQ922::~CLayerQ922 (void)
  358. *
  359. * Public
  360. *
  361. * Functional Description:
  362. * This is the CLayerQ922 destructor. This routine cleans up the mess.
  363. */
  364. CLayerQ922::~CLayerQ922(void)
  365. {
  366. TRACE_OUT(("CLayerQ922::~CLayerQ922"));
  367. BOOL queue_full;
  368. PMemory memory;
  369. TRACE_OUT(("Q922: Destructor: DLCI = %d Receive_Sequence_Exception = %d",
  370. DLCI, Receive_Sequence_Exception));
  371. TRACE_OUT(("Q922: Destructor: DLCI = %d Receive_Sequence_Recovery = %d",
  372. DLCI, Receive_Sequence_Recovery));
  373. m_pMultiplexer->RemoveHigherLayer (DLCI);
  374. StopTimerT200 ();
  375. StopTimerT203 ();
  376. if (Data_Indication != NULL)
  377. LocalFree ((HLOCAL) Data_Indication);
  378. if (Data_Indication_Buffer != NULL)
  379. LocalFree ((HLOCAL) Data_Indication_Buffer);
  380. if (Data_Request != NULL)
  381. {
  382. /*
  383. ** Data_Request_Head is the head of the list,
  384. ** Data_Request_Acknowledge_Tail is the absolute tail of the list.
  385. ** If the list is full, Data_Request_Head equals
  386. ** Data_Request_Acknowledge_Tail. Therefore, we have to check
  387. ** Data_Request_Count to see if it is full or empty.
  388. */
  389. if ((Data_Request_Head == Data_Request_Acknowledge_Tail) &&
  390. (Data_Request_Count != 0))
  391. {
  392. queue_full = TRUE;
  393. }
  394. else
  395. queue_full = FALSE;
  396. /*
  397. ** We have to unlock any memory blocks that are in use
  398. */
  399. while ((Data_Request_Head != Data_Request_Acknowledge_Tail) || queue_full)
  400. {
  401. memory = *(Data_Request + Data_Request_Acknowledge_Tail);
  402. Data_Request_Memory_Manager -> UnlockMemory (memory);
  403. if (++Data_Request_Acknowledge_Tail == Data_Request_Total_Size)
  404. {
  405. Data_Request_Acknowledge_Tail = 0;
  406. }
  407. if (queue_full)
  408. {
  409. queue_full = FALSE;
  410. }
  411. }
  412. LocalFree ((HLOCAL) Data_Request);
  413. }
  414. }
  415. /*
  416. * CLayerQ922::Reset (void)
  417. *
  418. * Functional Description:
  419. * This function resets the link state variables.
  420. *
  421. * Formal Parameters
  422. * None
  423. *
  424. * Return Value
  425. * None
  426. *
  427. * Side Effects
  428. * None
  429. *
  430. * Caveats
  431. * None
  432. */
  433. void CLayerQ922::Reset (void)
  434. {
  435. TRACE_OUT(("CLayerQ922::Reset"));
  436. BOOL queue_full;
  437. PMemory memory;
  438. Data_Indication_Head = 0;
  439. Data_Indication_Tail = 0;
  440. Data_Indication_Count = 0;
  441. /*
  442. ** Data_Request_Head is the head of the list,
  443. ** Data_Request_Acknowledge_Tail is the absolute tail of the list.
  444. ** If the list is full, Data_Request_Head equals
  445. ** Data_Request_Acknowledge_Tail. Therefore, we have to check
  446. ** Data_Request_Count to see if it is full or empty.
  447. */
  448. if ((Data_Request_Head == Data_Request_Acknowledge_Tail) &&
  449. (Data_Request_Count != 0))
  450. {
  451. queue_full = TRUE;
  452. }
  453. else
  454. queue_full = FALSE;
  455. /*
  456. ** We have to unlock any memory blocks that are in use
  457. */
  458. while ((Data_Request_Head != Data_Request_Acknowledge_Tail) || queue_full)
  459. {
  460. memory = *(Data_Request + Data_Request_Acknowledge_Tail);
  461. Data_Request_Memory_Manager -> UnlockMemory (memory);
  462. if (++Data_Request_Acknowledge_Tail == Data_Request_Total_Size)
  463. Data_Request_Acknowledge_Tail = 0;
  464. if (queue_full)
  465. {
  466. queue_full = FALSE;
  467. }
  468. }
  469. Data_Request_Head = 0;
  470. Data_Request_Tail = 0;
  471. Data_Request_Count = 0;
  472. Data_Request_Acknowledge_Tail = 0;
  473. Outstanding_Packets = 0;
  474. Outstanding_Bytes = 0;
  475. Total_Retransmitted = 0;
  476. Send_State_Variable = 0;
  477. Receive_State_Variable = 0;
  478. Acknowledge_State_Variable = 0;
  479. Own_Receiver_Busy = FALSE;
  480. Peer_Receiver_Busy = FALSE;
  481. Command_Pending = FALSE;
  482. Poll_Pending = FALSE;
  483. Final_Pending = FALSE;
  484. Acknowledge_Pending = FALSE;
  485. Reject_Pending = FALSE;
  486. Reject_Outstanding = FALSE;
  487. SABME_Pending = FALSE;
  488. Frame_Reject_Pending = FALSE;
  489. Unnumbered_Acknowledge_Pending = FALSE;
  490. DISC_Pending = FALSE;
  491. Final_Packet = FALSE;
  492. Disconnected_Mode_Pending = FALSE;
  493. N200_Count = 0;
  494. Link_Stable = TRUE;
  495. Receive_Sequence_Exception = 0;
  496. Receive_Sequence_Recovery = 0;
  497. StopTimerT200 ();
  498. StopTimerT203 ();
  499. }
  500. /*
  501. * DataLinkError CLayerQ922::ReleaseRequest (void)
  502. *
  503. * Public
  504. *
  505. * Functional Description:
  506. * This function sets the necessary flags to terminate the link
  507. */
  508. DataLinkError CLayerQ922::ReleaseRequest (void)
  509. {
  510. TRACE_OUT(("CLayerQ922::ReleaseRequest"));
  511. if ((Data_Link_Mode == MULTIPLE_FRAME_ESTABLISHED) ||
  512. (Data_Link_Mode == TIMER_RECOVERY))
  513. {
  514. /*
  515. ** Queue up the DISC_Pending flag to send out a DISC packet
  516. */
  517. DISC_Pending = TRUE;
  518. Unnumbered_PF_State = UNNUMBERED_PF_SET;
  519. Data_Link_Mode = AWAITING_RELEASE;
  520. StopTimerT200 ();
  521. StopTimerT203 ();
  522. }
  523. else
  524. {
  525. m_pT123->OwnerCallback(m_nMsgBase + DATALINK_RELEASE_CONFIRM,
  526. (void *) DLCI, (void *) DATALINK_NORMAL_DISCONNECT);
  527. }
  528. return (DATALINK_NO_ERROR);
  529. }
  530. /*
  531. * DataLinkError CLayerQ922::DataIndication (
  532. * LPBYTE packet_address,
  533. * ULONG buffer_size,
  534. * PULong packet_length)
  535. *
  536. * Public
  537. *
  538. * Functional Description:
  539. * This function is called by the lower layer when it has a packet to
  540. * pass to us.
  541. */
  542. ProtocolLayerError CLayerQ922::DataIndication (
  543. LPBYTE packet_address,
  544. ULONG packet_length,
  545. PULong bytes_accepted)
  546. {
  547. TRACE_OUT(("CLayerQ922::DataIndication"));
  548. BOOL packet_processed = TRUE;
  549. /*
  550. ** The packet MUST be at least UNNUMBERED_HEADER_SIZE or it is
  551. ** invalid
  552. */
  553. if (packet_length < UNNUMBERED_HEADER_SIZE)
  554. {
  555. *bytes_accepted = packet_length;
  556. return (PROTOCOL_LAYER_NO_ERROR);
  557. }
  558. if (*(packet_address + CONTROL_BYTE_HIGH) & SUPERVISORY_FRAME_BIT)
  559. {
  560. if (*(packet_address + CONTROL_BYTE_HIGH) & UNNUMBERED_FRAME_BIT)
  561. {
  562. /*
  563. ** This packet is an unnumbered packet
  564. */
  565. switch (*(packet_address + CONTROL_BYTE_HIGH) &
  566. UNNUMBERED_COMMAND_MASK)
  567. {
  568. case SABME:
  569. ProcessSABME (
  570. packet_address,
  571. (USHORT) packet_length);
  572. break;
  573. case UNNUMBERED_ACKNOWLEDGE:
  574. ProcessUnnumberedAcknowledge (
  575. packet_address,
  576. (USHORT) packet_length);
  577. break;
  578. case FRAME_REJECT:
  579. ProcessFrameReject (
  580. packet_address,
  581. (USHORT) packet_length);
  582. break;
  583. case DISCONNECTED_MODE:
  584. ProcessDisconnectMode (
  585. packet_address,
  586. (USHORT) packet_length);
  587. break;
  588. case DISC:
  589. ProcessDISC (
  590. packet_address,
  591. (USHORT) packet_length);
  592. break;
  593. default:
  594. ERROR_OUT(("Q922: DLCI %d: DataIndication: Illegal Packet: = %d",
  595. DLCI, (*(packet_address + CONTROL_BYTE_HIGH) & UNNUMBERED_COMMAND_MASK)));
  596. break;
  597. }
  598. }
  599. else
  600. {
  601. /*
  602. ** It is only legal to process supervisory frames if we
  603. ** are in the MULTIPLE_FRAME_ESTABLISHED or TIMER_RECOVERY
  604. ** modes
  605. */
  606. if ((Data_Link_Mode == MULTIPLE_FRAME_ESTABLISHED) ||
  607. (Data_Link_Mode == TIMER_RECOVERY))
  608. {
  609. switch (*(packet_address + CONTROL_BYTE_HIGH) &
  610. SUPERVISORY_COMMAND_MASK)
  611. {
  612. case RECEIVER_READY:
  613. ProcessReceiverReady (
  614. packet_address,
  615. (USHORT) packet_length);
  616. break;
  617. case RECEIVER_NOT_READY:
  618. ProcessReceiverNotReady (
  619. packet_address,
  620. (USHORT) packet_length);
  621. break;
  622. case REJECT:
  623. ProcessReject (
  624. packet_address,
  625. (USHORT) packet_length);
  626. break;
  627. }
  628. }
  629. else
  630. {
  631. ERROR_OUT(("Q922: DLCI %d: Supervisory packet received in illegal DataLink Mode", DLCI));
  632. #ifdef _MCATIPX
  633. if (Data_Link_Mode != AWAITING_RELEASE)
  634. {
  635. /*
  636. ** This is necessary on an IPX network to notify the remote
  637. ** site that this unit is no longer in the conference. If
  638. ** the previous conference ended without going through the
  639. ** proper disconnect sequence, the remote site may continue
  640. ** to send frames to this site. In which case, we need to
  641. ** notify the remote site that the conference is no longer
  642. ** active. We are doing this by sending out a DISC frame.
  643. ** The Q.921 specification does not address this situation.
  644. */
  645. DISC_Pending = TRUE;
  646. Unnumbered_PF_State = UNNUMBERED_PF_RESET;
  647. }
  648. #endif
  649. }
  650. }
  651. }
  652. else
  653. {
  654. /*
  655. ** It is only legal to process Information frames if we
  656. ** are in the MULTIPLE_FRAME_ESTABLISHED or TIMER_RECOVERY
  657. ** modes
  658. */
  659. if ((Data_Link_Mode == MULTIPLE_FRAME_ESTABLISHED) ||
  660. (Data_Link_Mode == TIMER_RECOVERY))
  661. {
  662. packet_processed = ProcessInformationFrame (
  663. packet_address,
  664. (USHORT) packet_length);
  665. }
  666. else
  667. {
  668. ERROR_OUT(("Q922: DLCI %d: Information packet received in illegal DataLink Mode", DLCI));
  669. #ifdef _MCATIPX
  670. if (Data_Link_Mode != AWAITING_RELEASE)
  671. {
  672. /*
  673. ** This is necessary on an IPX network to notify the remote
  674. ** site that this unit is no longer in the conference. If
  675. ** the previous conference ended without going through the
  676. ** proper disconnect sequence, the remote site may continue
  677. ** to send frames to this site. In which case, we need to
  678. ** notify the remote site that the conference is no longer
  679. ** active. We are doing this by sending out a DISC frame.
  680. ** The Q.921 specification does not address this situation.
  681. */
  682. DISC_Pending = TRUE;
  683. Unnumbered_PF_State = UNNUMBERED_PF_RESET;
  684. }
  685. #endif
  686. }
  687. }
  688. /*
  689. ** After we receive a packet we should start the T203 timer
  690. ** unless the T200 timer was started during the processing of
  691. ** the packet
  692. */
  693. if (((Data_Link_Mode == MULTIPLE_FRAME_ESTABLISHED) ||
  694. (Data_Link_Mode == TIMER_RECOVERY)) &&
  695. (T200_Active == FALSE) &&
  696. (DLCI == 0))
  697. {
  698. StartTimerT203 ();
  699. }
  700. if (packet_processed)
  701. {
  702. if ((Data_Link_Mode == MULTIPLE_FRAME_ESTABLISHED) ||
  703. (Data_Link_Mode == TIMER_RECOVERY))
  704. {
  705. N200_Count = 0;
  706. }
  707. *bytes_accepted = packet_length;
  708. }
  709. else
  710. *bytes_accepted = 0;
  711. return (PROTOCOL_LAYER_NO_ERROR);
  712. }
  713. /*
  714. * ProtocolLayerError CLayerQ922::PollTransmitter (
  715. * ULONG,
  716. * USHORT data_to_transmit,
  717. * USHORT * pending_data,
  718. * USHORT * holding_data);
  719. *
  720. * Public
  721. *
  722. * Functional Description:
  723. * This function is called to give us a chance to transmit packets.
  724. * The data_to_transmit mask tells us which data to transmit, either
  725. * control or user data.
  726. */
  727. ProtocolLayerError CLayerQ922::PollTransmitter (
  728. ULONG_PTR,
  729. USHORT data_to_transmit,
  730. USHORT * pending_data,
  731. USHORT * holding_data)
  732. {
  733. // TRACE_OUT(("CLayerQ922::PollTransmitter"));
  734. *pending_data = 0;
  735. /*
  736. ** If we are permitted to transmit data, call ProcessWriteQueue ()
  737. */
  738. if ((data_to_transmit & PROTOCOL_CONTROL_DATA) ||
  739. (data_to_transmit & PROTOCOL_USER_DATA))
  740. {
  741. ProcessWriteQueue (data_to_transmit);
  742. }
  743. /*
  744. ** We have to set the pending data variable to reflect which data
  745. ** we still need to send out
  746. */
  747. if (Data_Request_Count != 0)
  748. *pending_data |= PROTOCOL_USER_DATA;
  749. if (Poll_Pending || Final_Pending || Command_Pending ||
  750. (Reject_Pending && (Own_Receiver_Busy == FALSE)) ||
  751. Acknowledge_Pending || SABME_Pending ||
  752. Unnumbered_Acknowledge_Pending || Frame_Reject_Pending ||
  753. DISC_Pending)
  754. {
  755. *pending_data |= PROTOCOL_CONTROL_DATA;
  756. }
  757. *holding_data = Outstanding_Packets;
  758. return (PROTOCOL_LAYER_NO_ERROR);
  759. }
  760. /*
  761. * DataLinkError CLayerQ922::DataRequest (
  762. * ULONG,
  763. * PMemory memory,
  764. * PULong bytes_accepted)
  765. *
  766. * Public
  767. *
  768. * Functional Description:
  769. * This function is called by the higher layer to send a packet to the
  770. * remote site.
  771. */
  772. ProtocolLayerError CLayerQ922::DataRequest (
  773. ULONG_PTR,
  774. PMemory memory,
  775. PULong bytes_accepted)
  776. {
  777. TRACE_OUT(("CLayerQ922::DataRequest"));
  778. PMemory * data_request;
  779. USHORT trash_word;
  780. ULONG packet_length;
  781. ULONG information_size;
  782. *bytes_accepted = 0;
  783. packet_length = memory -> GetLength ();
  784. /*
  785. ** Determine the actual information length
  786. */
  787. information_size =
  788. packet_length - Lower_Layer_Prepend -
  789. Lower_Layer_Append - DATALINK_PACKET_OVERHEAD;
  790. /*
  791. ** See if the information content is too big.
  792. */
  793. if (information_size > Maximum_Information_Size)
  794. {
  795. TRACE_OUT(("Q922: DLCI %d: DataRequest: Requested packet = %d, max = %d",
  796. DLCI, information_size, Maximum_Information_Size));
  797. return (PROTOCOL_LAYER_PACKET_TOO_BIG);
  798. }
  799. if (Data_Request_Count < Data_Request_Size)
  800. {
  801. /*
  802. ** Set write_queue to the correct location
  803. */
  804. data_request = Data_Request + Data_Request_Head;
  805. *data_request = memory;
  806. /*
  807. ** Lock the memory object so that it won't be released
  808. */
  809. Data_Request_Memory_Manager -> LockMemory (memory);
  810. if (++Data_Request_Head == Data_Request_Total_Size)
  811. Data_Request_Head = 0;
  812. Data_Request_Count++;
  813. *bytes_accepted = packet_length;
  814. /*
  815. ** If the higher layer got permission to send data to me, I will
  816. ** attempt to send it on out
  817. */
  818. PollTransmitter (
  819. 0,
  820. PROTOCOL_USER_DATA | PROTOCOL_CONTROL_DATA,
  821. &trash_word,
  822. &trash_word);
  823. }
  824. return (PROTOCOL_LAYER_NO_ERROR);
  825. }
  826. /*
  827. * DataLinkError CLayerQ922::DataRequest (
  828. * ULONG,
  829. * PMemory memory,
  830. * PULong bytes_accepted)
  831. *
  832. * Public
  833. *
  834. * Functional Description:
  835. * This function is called by the higher layer to send a packet to the
  836. * remote site. This type of data passing is NOT supported by this
  837. * layer.
  838. */
  839. ProtocolLayerError CLayerQ922::DataRequest (
  840. ULONG_PTR,
  841. LPBYTE,
  842. ULONG,
  843. PULong bytes_accepted)
  844. {
  845. *bytes_accepted = 0;
  846. return (PROTOCOL_LAYER_ERROR);
  847. }
  848. /*
  849. * ProtocolLayerError CLayerQ922::PollReceiver (
  850. * ULONG)
  851. *
  852. * Public
  853. *
  854. * Functional Description
  855. * This function is called to give us a chance to send packets to the
  856. * higher layer
  857. */
  858. ProtocolLayerError CLayerQ922::PollReceiver(void)
  859. {
  860. ULONG bytes_accepted;
  861. PDataQueue data_indication;
  862. /*
  863. ** If I have any packet in my receive buffers that
  864. ** need to go to higher layers, send them now
  865. */
  866. while (Data_Indication_Count != 0)
  867. {
  868. data_indication = Data_Indication + Data_Indication_Tail;
  869. if (Higher_Layer == NULL)
  870. break;
  871. Higher_Layer -> DataIndication (
  872. data_indication -> buffer_address,
  873. data_indication -> length,
  874. &bytes_accepted);
  875. if (bytes_accepted == (data_indication -> length))
  876. {
  877. if (++Data_Indication_Tail == Data_Indication_Size)
  878. Data_Indication_Tail = 0;
  879. Data_Indication_Count--;
  880. /*
  881. ** If we had been in a Receiver Busy mode, exit it
  882. */
  883. if (Own_Receiver_Busy)
  884. {
  885. Own_Receiver_Busy = FALSE;
  886. Command_Pending = TRUE;
  887. }
  888. }
  889. else
  890. break;
  891. }
  892. return (PROTOCOL_LAYER_NO_ERROR);
  893. }
  894. /*
  895. * void CLayerQ922::ProcessWriteQueue (
  896. * USHORT data_to_transmit)
  897. *
  898. * Functional Description
  899. * This function determines which type of data needs to be sent out, and
  900. * sends it.
  901. *
  902. * Formal Parameters
  903. * data_to_transmit (i) - Mask telling us which data is allowed to be
  904. * transmitted
  905. *
  906. * Return Value
  907. * None
  908. *
  909. * Side Effects
  910. * None
  911. *
  912. * Caveats
  913. * None
  914. */
  915. void CLayerQ922::ProcessWriteQueue (
  916. USHORT data_to_transmit)
  917. {
  918. // TRACE_OUT(("CLayerQ922::ProcessWriteQueue"));
  919. BOOL continue_loop = TRUE;
  920. while (continue_loop)
  921. {
  922. switch (Data_Link_Mode)
  923. {
  924. case AWAITING_RELEASE:
  925. case TEI_ASSIGNED:
  926. case AWAITING_ESTABLISHMENT:
  927. if (SABME_Pending || DISC_Pending || Unnumbered_Acknowledge_Pending ||
  928. Disconnected_Mode_Pending || Frame_Reject_Pending)
  929. {
  930. continue_loop = TransmitUnnumberedFrame ();
  931. }
  932. else
  933. {
  934. continue_loop = FALSE;
  935. }
  936. break;
  937. default:
  938. if (Poll_Pending)
  939. {
  940. continue_loop = TransmitSupervisoryFrame (COMMAND_FRAME, PF_SET);
  941. }
  942. else if (Final_Pending)
  943. {
  944. continue_loop = TransmitSupervisoryFrame (RESPONSE_FRAME, PF_SET);
  945. }
  946. else if (Command_Pending)
  947. {
  948. continue_loop = TransmitSupervisoryFrame (COMMAND_FRAME, PF_RESET);
  949. }
  950. else if (Reject_Pending && (Own_Receiver_Busy == FALSE))
  951. {
  952. continue_loop = TransmitSupervisoryFrame (RESPONSE_FRAME, PF_RESET);
  953. }
  954. else if (Unnumbered_Acknowledge_Pending || Frame_Reject_Pending)
  955. {
  956. continue_loop = TransmitUnnumberedFrame ();
  957. }
  958. else if ((data_to_transmit & PROTOCOL_USER_DATA) &&
  959. (Data_Link_Mode == MULTIPLE_FRAME_ESTABLISHED) &&
  960. (Data_Request_Count != 0) &&
  961. (Outstanding_Packets < Maximum_Outstanding_Packets) &&
  962. (Outstanding_Bytes < Maximum_Outstanding_Bytes) &&
  963. (Peer_Receiver_Busy == FALSE))
  964. {
  965. continue_loop = TransmitInformationFrame ();
  966. }
  967. else if (Acknowledge_Pending)
  968. {
  969. continue_loop = TransmitSupervisoryFrame (RESPONSE_FRAME, PF_RESET);
  970. }
  971. else
  972. {
  973. continue_loop = FALSE;
  974. }
  975. if (continue_loop)
  976. {
  977. if ((T200_Active == FALSE) && (DLCI == 0))
  978. StartTimerT203 ();
  979. }
  980. break;
  981. }
  982. }
  983. }
  984. /*
  985. * BOOL CLayerQ922::TransmitUnnumberedFrame ()
  986. *
  987. * Functional Description
  988. * This function builds an unnumbered packet and attempts to send it out.
  989. * The only packets that can be sent by this function are SABME, DISC, and
  990. * an Unnumbered Acknowledge.
  991. *
  992. * Formal Parameters
  993. * None
  994. *
  995. * Return Value
  996. * TRUE - If a packet was transmitted
  997. * FALSE - If a packet was not transmitted
  998. *
  999. * Side Effects
  1000. * None
  1001. *
  1002. * Caveats
  1003. * None
  1004. */
  1005. BOOL CLayerQ922::TransmitUnnumberedFrame ()
  1006. {
  1007. TRACE_OUT(("CLayerQ922::TransmitUnnumberedFrame"));
  1008. LPBYTE packet_address;
  1009. UChar command;
  1010. ULONG bytes_written;
  1011. PMemory memory;
  1012. USHORT total_length;
  1013. UChar frame_type;
  1014. /*
  1015. ** Use the Supervisory Buffer to transmit the packet
  1016. */
  1017. total_length = UNNUMBERED_HEADER_SIZE + Lower_Layer_Prepend +
  1018. Lower_Layer_Append;
  1019. memory = Data_Request_Memory_Manager -> AllocateMemory (
  1020. NULL,
  1021. total_length);
  1022. if (memory == NULL)
  1023. return (FALSE);
  1024. packet_address = memory -> GetPointer ();
  1025. packet_address += Lower_Layer_Prepend;
  1026. if (SABME_Pending)
  1027. {
  1028. TRACE_OUT(("Q922: DLCI %d: TransmitUnnumberedFrame: Transmitting SABME", DLCI));
  1029. command = SABME;
  1030. frame_type = COMMAND_FRAME;
  1031. }
  1032. else if (DISC_Pending)
  1033. {
  1034. TRACE_OUT(("Q922: DLCI %d: TransmitUnnumberedFrame: Transmitting DISC", DLCI));
  1035. command = DISC;
  1036. frame_type = COMMAND_FRAME;
  1037. }
  1038. else if (Unnumbered_Acknowledge_Pending)
  1039. {
  1040. TRACE_OUT(("Q922: DLCI %d: TransmitUnnumberedFrame: Transmitting UNNUMBERED_ACKNOWLEDGE", DLCI));
  1041. command = UNNUMBERED_ACKNOWLEDGE;
  1042. frame_type = RESPONSE_FRAME;
  1043. }
  1044. else if (Disconnected_Mode_Pending)
  1045. {
  1046. TRACE_OUT(("Q922: DLCI %d: TransmitUnnumberedFrame: Transmitting DISCONNECTED_MODE", DLCI));
  1047. command = DISCONNECTED_MODE;
  1048. frame_type = RESPONSE_FRAME;
  1049. }
  1050. else if (Frame_Reject_Pending)
  1051. {
  1052. TRACE_OUT(("Q922: DLCI %d: TransmitUnnumberedFrame: Transmitting FRAME_REJECT", DLCI));
  1053. command = FRAME_REJECT;
  1054. frame_type = RESPONSE_FRAME;
  1055. }
  1056. else
  1057. {
  1058. ERROR_OUT(("Q922: DLCI %d: TransmitUnnumberedFrame: Illegally called function", DLCI));
  1059. }
  1060. /*
  1061. ** Assemble the packet for transmission
  1062. */
  1063. *(packet_address + ADDRESS_BYTE_HIGH) =
  1064. (ADDRESS_HIGH(DLCI)) | frame_type | ADDRESS_MSB;
  1065. *(packet_address + ADDRESS_BYTE_LOW) = (ADDRESS_LOW(DLCI)) | ADDRESS_LSB;
  1066. *(packet_address + CONTROL_BYTE_HIGH) =
  1067. command | Unnumbered_PF_State | 0x03;
  1068. /*
  1069. ** Attempt to send the packet to the lower layer
  1070. */
  1071. m_pMultiplexer->DataRequest(DLCI, memory, (PULong) &bytes_written);
  1072. Data_Request_Memory_Manager -> FreeMemory (memory);
  1073. if (bytes_written == total_length)
  1074. {
  1075. if (SABME_Pending)
  1076. {
  1077. /*
  1078. ** Start the T200 timer after the SABME has been sent
  1079. */
  1080. StartTimerT200 ();
  1081. SABME_Pending = FALSE;
  1082. }
  1083. else if (DISC_Pending)
  1084. {
  1085. TRACE_OUT(("Q922: DLCI %d: TransmitUnnumberedPacket DISC sent", DLCI));
  1086. /*
  1087. ** Start the T200 timer after the DISC has been sent
  1088. */
  1089. DISC_Pending = FALSE;
  1090. StartTimerT200 ();
  1091. Data_Link_Mode = AWAITING_RELEASE;
  1092. }
  1093. else if (Unnumbered_Acknowledge_Pending)
  1094. {
  1095. Unnumbered_Acknowledge_Pending = FALSE;
  1096. TRACE_OUT(("Q922: DLCI %d: TransmitUnnumberedAck ack sent", DLCI));
  1097. /*
  1098. ** An Unnumbered Ack packet can be sent in response to two packets,
  1099. ** the SABME or DISC. If it is in response to a DISC, the
  1100. ** Final_Packet flag is set to TRUE. Therefore, we need to notify
  1101. ** the owner that the link is terminated.
  1102. */
  1103. if (Final_Packet)
  1104. {
  1105. Final_Packet = FALSE;
  1106. TRACE_OUT(("Q922: DLCI %d: TransmitUnnumberedAck: Issuing Release Indication", DLCI));
  1107. m_pT123->OwnerCallback(m_nMsgBase + DATALINK_RELEASE_INDICATION,
  1108. (void *) DLCI, (void *) DATALINK_NORMAL_DISCONNECT);
  1109. }
  1110. else
  1111. {
  1112. /*
  1113. ** Callback to the controller to let it know that the link is
  1114. ** established
  1115. */
  1116. if ((Data_Link_Mode == TEI_ASSIGNED) ||
  1117. (Data_Link_Mode == AWAITING_ESTABLISHMENT))
  1118. {
  1119. Data_Link_Mode = MULTIPLE_FRAME_ESTABLISHED;
  1120. m_pT123->OwnerCallback(m_nMsgBase + DATALINK_ESTABLISH_INDICATION,
  1121. (void *) DLCI);
  1122. Maximum_T200_Timeouts = Link_Maximum_T200_Timeouts;
  1123. if (DLCI == 0)
  1124. StartTimerT203 ();
  1125. }
  1126. else if ((Data_Link_Mode == MULTIPLE_FRAME_ESTABLISHED) ||
  1127. (Data_Link_Mode == TIMER_RECOVERY))
  1128. {
  1129. if (DLCI == 0)
  1130. StartTimerT203 ();
  1131. }
  1132. }
  1133. }
  1134. else if (Disconnected_Mode_Pending)
  1135. {
  1136. TRACE_OUT(("Q922: DLCI %d: TransmitUnnumberedPacket Disconnected Mode sent", DLCI));
  1137. Disconnected_Mode_Pending = FALSE;
  1138. }
  1139. else if (Frame_Reject_Pending)
  1140. {
  1141. TRACE_OUT(("Q922: DLCI %d: TransmitUnnumberedPacket Frame Reject sent", DLCI));
  1142. Frame_Reject_Pending = FALSE;
  1143. m_pT123->OwnerCallback(m_nMsgBase + DATALINK_RELEASE_INDICATION,
  1144. (void *) DLCI, (void *) DATALINK_RECEIVE_SEQUENCE_EXCEPTION);
  1145. }
  1146. return (TRUE);
  1147. }
  1148. else
  1149. return (FALSE);
  1150. }
  1151. /*
  1152. * void CLayerQ922::TransmitSupervisoryFrame (
  1153. * UChar frame_type,
  1154. * UChar poll_final_bit)
  1155. *
  1156. * Functional Description
  1157. * This function builds a Supervisory frame based on the
  1158. * current state of the protocol and the passed-in parameters.
  1159. *
  1160. * Formal Parameters
  1161. * frame_type - (i) The frame type can be either COMMAND_FRAME
  1162. * or RESPONSE_FRAME
  1163. * poll_final_bit - (i) This flag is set in the packet to signal
  1164. * the remote site to respond to this packet.
  1165. *
  1166. * Return Value
  1167. * TRUE - If a packet was actually transmitted
  1168. * FALSE - If a packet was not transmitted
  1169. *
  1170. * Side Effects
  1171. * None
  1172. *
  1173. * Caveats
  1174. * None
  1175. */
  1176. BOOL CLayerQ922::TransmitSupervisoryFrame (
  1177. UChar frame_type,
  1178. UChar poll_final_bit)
  1179. {
  1180. TRACE_OUT(("CLayerQ922::TransmitSupervisoryFrame"));
  1181. LPBYTE packet_address;
  1182. UChar command;
  1183. ULONG bytes_written;
  1184. USHORT total_length;
  1185. PMemory memory;
  1186. /*
  1187. ** Transmit the packet using the Supervisory buffer
  1188. */
  1189. total_length = DATALINK_PACKET_OVERHEAD + Lower_Layer_Prepend +
  1190. Lower_Layer_Append;
  1191. /*
  1192. ** Get a memory object from the memory manager
  1193. */
  1194. memory = Data_Request_Memory_Manager -> AllocateMemory (
  1195. NULL,
  1196. total_length);
  1197. if (memory == NULL)
  1198. return (FALSE);
  1199. packet_address = memory -> GetPointer ();
  1200. packet_address += Lower_Layer_Prepend;
  1201. if (Own_Receiver_Busy)
  1202. {
  1203. TRACE_OUT(("CLayerQ922::TransmitSupervisoryFrame: RECEIVER_NOT_READY"));
  1204. command = RECEIVER_NOT_READY;
  1205. }
  1206. else if (Reject_Pending)
  1207. {
  1208. TRACE_OUT(("CLayerQ922::TransmitSupervisoryFrame: REJECT"));
  1209. command = REJECT;
  1210. }
  1211. else
  1212. {
  1213. TRACE_OUT(("CLayerQ922::TransmitSupervisoryFrame: RECEIVER_READY"));
  1214. command = RECEIVER_READY;
  1215. }
  1216. /*
  1217. ** Set up the header including the Receive_State_Variable which
  1218. ** indicates the next packet we expect to receive.
  1219. */
  1220. *(packet_address + ADDRESS_BYTE_HIGH) =
  1221. (ADDRESS_HIGH(DLCI)) | frame_type | ADDRESS_MSB;
  1222. *(packet_address + ADDRESS_BYTE_LOW) = (ADDRESS_LOW(DLCI)) | ADDRESS_LSB;
  1223. *(packet_address + CONTROL_BYTE_HIGH) = CONTROL_MSB | command;
  1224. *(packet_address + CONTROL_BYTE_LOW) =
  1225. (Receive_State_Variable << 1) | poll_final_bit;
  1226. /*
  1227. ** Send the packet to the lower layer
  1228. */
  1229. m_pMultiplexer->DataRequest(DLCI, memory, (PULong) &bytes_written);
  1230. Data_Request_Memory_Manager -> FreeMemory (memory);
  1231. if (bytes_written == total_length)
  1232. {
  1233. if (command == REJECT)
  1234. Reject_Pending = FALSE;
  1235. if (frame_type == COMMAND_FRAME)
  1236. {
  1237. Command_Pending = FALSE;
  1238. if (poll_final_bit == PF_SET)
  1239. {
  1240. Poll_Pending = FALSE;
  1241. /*
  1242. ** If we are currently in a TIMER_RECOVERY mode, we
  1243. ** need to continue to set the T200 timer to make sure
  1244. ** that they receive this packet.
  1245. */
  1246. if (Data_Link_Mode == TIMER_RECOVERY)
  1247. StartTimerT200 ();
  1248. }
  1249. }
  1250. else
  1251. {
  1252. if (poll_final_bit == PF_SET)
  1253. Final_Pending = FALSE;
  1254. }
  1255. Acknowledge_Pending = FALSE;
  1256. return (TRUE);
  1257. }
  1258. else
  1259. return (FALSE);
  1260. }
  1261. /*
  1262. * void CLayerQ922::TransmitInformationFrame (void)
  1263. *
  1264. * Functional Description
  1265. * This function builds an Information frame from its data request buffer.
  1266. * If applicable, it starts the T200 timer.
  1267. *
  1268. * Formal Parameters
  1269. * None
  1270. *
  1271. * Return Value
  1272. * TRUE - If a packet was actually transmitted
  1273. * FALSE - If a packet was not transmitted
  1274. *
  1275. * Side Effects
  1276. * None
  1277. *
  1278. * Caveats
  1279. * None
  1280. */
  1281. BOOL CLayerQ922::TransmitInformationFrame (void)
  1282. {
  1283. TRACE_OUT(("CLayerQ922::TransmitInformationFrame"));
  1284. PMemory * data_request;
  1285. LPBYTE packet_address;
  1286. ULONG total_length;
  1287. PMemory memory;
  1288. ULONG bytes_written;
  1289. /*
  1290. ** Get the address of the next memory object
  1291. */
  1292. data_request = Data_Request + Data_Request_Tail;
  1293. memory = *data_request;
  1294. packet_address = memory -> GetPointer ();
  1295. total_length = memory -> GetLength ();
  1296. packet_address += Lower_Layer_Prepend;
  1297. /*
  1298. ** Set up the packet header
  1299. */
  1300. *(packet_address + ADDRESS_BYTE_HIGH) =
  1301. (ADDRESS_HIGH(DLCI)) | COMMAND_FRAME | ADDRESS_MSB;
  1302. *(packet_address + ADDRESS_BYTE_LOW) = (ADDRESS_LOW(DLCI)) | ADDRESS_LSB;
  1303. *(packet_address + CONTROL_BYTE_HIGH) = (Send_State_Variable << 1);
  1304. *(packet_address + CONTROL_BYTE_LOW) = (Receive_State_Variable << 1);
  1305. /*
  1306. ** Send packet to lower layer
  1307. */
  1308. m_pMultiplexer->DataRequest(DLCI, memory, (PULong) &bytes_written);
  1309. if (bytes_written == total_length)
  1310. {
  1311. if (++Data_Request_Tail == Data_Request_Total_Size)
  1312. Data_Request_Tail = 0;
  1313. Data_Request_Count--;
  1314. Outstanding_Packets++;
  1315. Outstanding_Bytes += (USHORT) total_length;
  1316. /*
  1317. ** If this is the packet that the remote site is expecting,
  1318. ** start the T200 timeout.
  1319. */
  1320. if (Send_State_Variable == Acknowledge_State_Variable)
  1321. StartTimerT200 ();
  1322. Send_State_Variable = ((Send_State_Variable + 1) % SEQUENCE_MODULUS);
  1323. Acknowledge_Pending = FALSE;
  1324. return (TRUE);
  1325. }
  1326. else
  1327. return (FALSE);
  1328. }
  1329. /*
  1330. * void CLayerQ922::ProcessSABME (
  1331. * LPBYTE packet_address,
  1332. * USHORT packet_length);
  1333. *
  1334. * Functional Description
  1335. * This function decodes the SABME packet received from the remote
  1336. * site.
  1337. *
  1338. * Formal Parameters
  1339. * packet_address (i) - Address of packet
  1340. * packet_length (i) - Length of packet
  1341. *
  1342. * Return Value
  1343. * None
  1344. *
  1345. * Side Effects
  1346. * Puts us in AWAITING_ESTABLISHMENT mode
  1347. *
  1348. * Caveats
  1349. * None
  1350. */
  1351. void CLayerQ922::ProcessSABME (
  1352. LPBYTE packet_address,
  1353. USHORT packet_length)
  1354. {
  1355. TRACE_OUT(("CLayerQ922::ProcessSABME"));
  1356. BOOL command_frame;
  1357. BOOL poll_final_bit;
  1358. USHORT status;
  1359. if (packet_length != UNNUMBERED_HEADER_SIZE)
  1360. {
  1361. TRACE_OUT(("Q922: DLCI %d: SABME received: Illegal packet length = %d", DLCI, packet_length));
  1362. return;
  1363. }
  1364. status = ParseUnnumberedPacketHeader (
  1365. packet_address,
  1366. &command_frame,
  1367. &poll_final_bit);
  1368. /*
  1369. ** The SABME packet can ONLY be a COMMAND, it can not be a RESPONSE
  1370. */
  1371. if (command_frame == FALSE)
  1372. {
  1373. TRACE_OUT(("Q922: DLCI %d: SABME RESPONSE received: Illegal packet", DLCI));
  1374. return;
  1375. }
  1376. if (status == DATALINK_NO_ERROR)
  1377. {
  1378. switch (Data_Link_Mode)
  1379. {
  1380. case TEI_ASSIGNED:
  1381. case AWAITING_ESTABLISHMENT:
  1382. /*
  1383. ** If we are already in this mode, remain here and respond with
  1384. ** an unnumbered ack packet.
  1385. */
  1386. Reset ();
  1387. Unnumbered_Acknowledge_Pending = TRUE;
  1388. if (poll_final_bit)
  1389. Unnumbered_PF_State = UNNUMBERED_PF_SET;
  1390. else
  1391. Unnumbered_PF_State = UNNUMBERED_PF_RESET;
  1392. break;
  1393. case MULTIPLE_FRAME_ESTABLISHED:
  1394. case TIMER_RECOVERY:
  1395. if (Send_State_Variable == Acknowledge_State_Variable)
  1396. {
  1397. TRACE_OUT(("Q922: DLCI %d: ProcessSABME: in MULTIPLE_FRAME mode: Able to recover", DLCI));
  1398. Send_State_Variable = 0;
  1399. Receive_State_Variable = 0;
  1400. Acknowledge_State_Variable = 0;
  1401. StopTimerT200 ();
  1402. Unnumbered_Acknowledge_Pending = TRUE;
  1403. if (poll_final_bit)
  1404. Unnumbered_PF_State = UNNUMBERED_PF_SET;
  1405. else
  1406. Unnumbered_PF_State = UNNUMBERED_PF_RESET;
  1407. }
  1408. else
  1409. {
  1410. TRACE_OUT(("Q922: DLCI %d: ProcessSABME: Illegal packet mode = %d", DLCI, Data_Link_Mode));
  1411. Data_Link_Mode = TEI_ASSIGNED;
  1412. m_pT123->OwnerCallback(m_nMsgBase + DATALINK_RELEASE_INDICATION,
  1413. (void *) DLCI, (void *) DATALINK_ILLEGAL_PACKET_RECEIVED);
  1414. }
  1415. break;
  1416. case AWAITING_RELEASE:
  1417. Disconnected_Mode_Pending = TRUE;
  1418. if (poll_final_bit)
  1419. Unnumbered_PF_State = UNNUMBERED_PF_SET;
  1420. else
  1421. Unnumbered_PF_State = UNNUMBERED_PF_RESET;
  1422. break;
  1423. }
  1424. }
  1425. }
  1426. /*
  1427. * void CLayerQ922::ProcessUnnumberAcknowledge (
  1428. * LPBYTE packet_address,
  1429. * USHORT packet_length);
  1430. *
  1431. * Functional Description
  1432. * This function decodes an unnumbered acknowledge packet. This packet is
  1433. * received in response to a SABME or DISC packet that we sent out.
  1434. *
  1435. * Formal Parameters
  1436. * packet_address (i) - Address of packet
  1437. * packet_length (i) - Length of packet
  1438. *
  1439. * Return Value
  1440. * None
  1441. *
  1442. * Side Effects
  1443. * None
  1444. *
  1445. * Caveats
  1446. * None
  1447. */
  1448. void CLayerQ922::ProcessUnnumberedAcknowledge (
  1449. LPBYTE packet_address,
  1450. USHORT packet_length)
  1451. {
  1452. TRACE_OUT(("CLayerQ922::ProcessUnnumberedAcknowledge"));
  1453. BOOL command_frame;
  1454. BOOL poll_final_bit;
  1455. ULONG_PTR disconnect_reason;
  1456. USHORT status;
  1457. /*
  1458. ** This packet MUST be the correct length or it is an error
  1459. */
  1460. if (packet_length != UNNUMBERED_HEADER_SIZE)
  1461. {
  1462. ERROR_OUT(("Q922: DLCI %d: Unnumbered ACK received: Illegal packet length = %d", DLCI, packet_length));
  1463. return;
  1464. }
  1465. status = ParseUnnumberedPacketHeader (
  1466. packet_address,
  1467. &command_frame,
  1468. &poll_final_bit);
  1469. /*
  1470. ** Unnumbered Ack packet can ONLY be a RESPONSE, it can not be a COMMAND
  1471. */
  1472. if (command_frame)
  1473. {
  1474. ERROR_OUT(("Q922: DLCI %d: Unnumbered Ack COMMAND received: Illegal packet", DLCI));
  1475. return;
  1476. }
  1477. if (status == DATALINK_NO_ERROR)
  1478. {
  1479. switch (Data_Link_Mode)
  1480. {
  1481. case AWAITING_ESTABLISHMENT:
  1482. if (poll_final_bit)
  1483. {
  1484. /*
  1485. ** If we are awaiting establishment and we receive a UA
  1486. ** to our SABME, enter the MULTIPLE_FRAME_ESTABLISHED mode.
  1487. */
  1488. Reset ();
  1489. Data_Link_Mode = MULTIPLE_FRAME_ESTABLISHED;
  1490. Maximum_T200_Timeouts = Link_Maximum_T200_Timeouts;
  1491. StopTimerT200 ();
  1492. if (DLCI == 0)
  1493. StartTimerT203 ();
  1494. /*
  1495. ** Callback to the controller
  1496. */
  1497. m_pT123->OwnerCallback(m_nMsgBase + DATALINK_ESTABLISH_CONFIRM,
  1498. (void *) DLCI);
  1499. }
  1500. break;
  1501. case AWAITING_RELEASE:
  1502. if (Unnumbered_Acknowledge_Pending == FALSE)
  1503. {
  1504. TRACE_OUT(("Q922: DLCI %d: ProcessUnnumberedAck: Issuing Release Indication", DLCI));
  1505. if (Receive_Sequence_Exception != 0)
  1506. disconnect_reason = DATALINK_RECEIVE_SEQUENCE_EXCEPTION;
  1507. else
  1508. disconnect_reason = DATALINK_NORMAL_DISCONNECT;
  1509. m_pT123->OwnerCallback(m_nMsgBase + DATALINK_RELEASE_CONFIRM,
  1510. (void *) DLCI, (void *) disconnect_reason);
  1511. }
  1512. StopTimerT200 ();
  1513. break;
  1514. case TEI_ASSIGNED:
  1515. TRACE_OUT(("Q922: DLCI %d: Illegal Unnumbered Ack", DLCI));
  1516. m_pT123->OwnerCallback(m_nMsgBase + DATALINK_RELEASE_INDICATION,
  1517. (void *) DLCI, (void *) DATALINK_ILLEGAL_PACKET_RECEIVED);
  1518. break;
  1519. case MULTIPLE_FRAME_ESTABLISHED:
  1520. case TIMER_RECOVERY:
  1521. WARNING_OUT(("Q922: DLCI %d: ProcessUnnumberedAcknowledge: Illegal packet", DLCI));
  1522. break;
  1523. }
  1524. }
  1525. }
  1526. /*
  1527. * void CLayerQ922::ProcessDisconnectMode (
  1528. * LPBYTE packet_address,
  1529. * USHORT packet_length);
  1530. *
  1531. * Functional Description
  1532. * This function decodes a Disconnect Mode packet.
  1533. *
  1534. * Formal Parameters
  1535. * packet_address (i) - Address of packet
  1536. * packet_length (i) - Length of packet
  1537. *
  1538. * Return Value
  1539. * None
  1540. *
  1541. * Side Effects
  1542. * None
  1543. *
  1544. * Caveats
  1545. * None
  1546. */
  1547. void CLayerQ922::ProcessDisconnectMode (
  1548. LPBYTE packet_address,
  1549. USHORT packet_length)
  1550. {
  1551. TRACE_OUT(("CLayerQ922::ProcessDisconnectMode"));
  1552. BOOL command_frame;
  1553. BOOL poll_final_bit;
  1554. USHORT status;
  1555. if (packet_length != UNNUMBERED_HEADER_SIZE)
  1556. {
  1557. TRACE_OUT(("Q922: DLCI %d: Unnumbered ACK received: Illegal packet length = %d", DLCI, packet_length));
  1558. return;
  1559. }
  1560. status = ParseUnnumberedPacketHeader (
  1561. packet_address, &command_frame, &poll_final_bit);
  1562. /*
  1563. ** DM packet can ONLY be a RESPONSE, it can not be a COMMAND
  1564. */
  1565. if (command_frame)
  1566. {
  1567. TRACE_OUT(("Q922: DLCI %d: DM COMMAND received: Illegal packet", DLCI));
  1568. return;
  1569. }
  1570. if (status == DATALINK_NO_ERROR)
  1571. {
  1572. switch (Data_Link_Mode)
  1573. {
  1574. case AWAITING_ESTABLISHMENT:
  1575. if (poll_final_bit && Link_Originator)
  1576. {
  1577. Reset ();
  1578. Data_Link_Mode = TEI_ASSIGNED;
  1579. StopTimerT200 ();
  1580. /*
  1581. ** Callback to the controller
  1582. */
  1583. TRACE_OUT(("Q922: DLCI %d: ProcessDisconnectMode: Releasing connection", DLCI));
  1584. m_pT123->OwnerCallback(m_nMsgBase + DATALINK_RELEASE_INDICATION,
  1585. (void *) DLCI, (void *) DATALINK_NORMAL_DISCONNECT);
  1586. }
  1587. break;
  1588. case AWAITING_RELEASE:
  1589. if (poll_final_bit)
  1590. {
  1591. Reset ();
  1592. Data_Link_Mode = TEI_ASSIGNED;
  1593. StopTimerT200 ();
  1594. /*
  1595. ** Callback to the controller
  1596. */
  1597. TRACE_OUT(("Q922: DLCI %d: ProcessDisconnectMode: A_R: Releasing connection", DLCI));
  1598. m_pT123->OwnerCallback(m_nMsgBase + DATALINK_RELEASE_CONFIRM,
  1599. (void *) DLCI, (void *) DATALINK_NORMAL_DISCONNECT);
  1600. }
  1601. break;
  1602. case TEI_ASSIGNED:
  1603. break;
  1604. case MULTIPLE_FRAME_ESTABLISHED:
  1605. case TIMER_RECOVERY:
  1606. TRACE_OUT(("Q922: DLCI %d: ProcessDM: Illegal packet", DLCI));
  1607. m_pT123->OwnerCallback(m_nMsgBase + DATALINK_RELEASE_INDICATION,
  1608. (void *) DLCI, (void *) DATALINK_ILLEGAL_PACKET_RECEIVED);
  1609. break;
  1610. }
  1611. }
  1612. }
  1613. /*
  1614. * void CLayerQ922::ProcessDISC (
  1615. * LPBYTE packet_address,
  1616. * USHORT packet_length);
  1617. *
  1618. * Functional Description
  1619. * This function decodes a DISC packet. We respond to this packet with
  1620. * an Unnumbered Ack packet.
  1621. *
  1622. * Formal Parameters
  1623. * packet_address (i) - Address of packet
  1624. * packet_length (i) - Length of packet
  1625. *
  1626. * Return Value
  1627. * None
  1628. *
  1629. * Side Effects
  1630. * None
  1631. *
  1632. * Caveats
  1633. * None
  1634. */
  1635. void CLayerQ922::ProcessDISC (
  1636. LPBYTE packet_address,
  1637. USHORT packet_length)
  1638. {
  1639. TRACE_OUT(("CLayerQ922::ProcessDISC"));
  1640. BOOL command_frame;
  1641. BOOL poll_final_bit;
  1642. USHORT status;
  1643. /*
  1644. ** This packet MUST be the correct length or it is an error
  1645. */
  1646. if (packet_length != UNNUMBERED_HEADER_SIZE)
  1647. {
  1648. TRACE_OUT(("Q922: DLCI %d: DISC received: Illegal packet length = %d", DLCI, packet_length));
  1649. return;
  1650. }
  1651. TRACE_OUT(("Q922: DLCI %d: DISCONNECT received", DLCI));
  1652. status = ParseUnnumberedPacketHeader (
  1653. packet_address, &command_frame, &poll_final_bit);
  1654. /*
  1655. ** The DISC packet can ONLY be a COMMAND, it can not be a RESPONSE
  1656. */
  1657. if (command_frame == FALSE)
  1658. {
  1659. TRACE_OUT(("Q922: DLCI %d: DISC RESPONSE received: Illegal packet", DLCI));
  1660. return;
  1661. }
  1662. if (status == DATALINK_NO_ERROR)
  1663. {
  1664. switch (Data_Link_Mode)
  1665. {
  1666. case TEI_ASSIGNED:
  1667. case AWAITING_ESTABLISHMENT:
  1668. Disconnected_Mode_Pending = TRUE;
  1669. if (poll_final_bit)
  1670. Unnumbered_PF_State = UNNUMBERED_PF_SET;
  1671. else
  1672. Unnumbered_PF_State = UNNUMBERED_PF_RESET;
  1673. break;
  1674. case AWAITING_RELEASE:
  1675. Unnumbered_Acknowledge_Pending = TRUE;
  1676. Final_Packet = TRUE;
  1677. Unnumbered_PF_State = UNNUMBERED_PF_RESET;
  1678. break;
  1679. case MULTIPLE_FRAME_ESTABLISHED:
  1680. case TIMER_RECOVERY:
  1681. Unnumbered_Acknowledge_Pending = TRUE;
  1682. Final_Packet = TRUE;
  1683. Unnumbered_PF_State = UNNUMBERED_PF_RESET;
  1684. break;
  1685. }
  1686. }
  1687. }
  1688. /*
  1689. * void CLayerQ922::ProcessFrameReject (
  1690. * LPBYTE packet_address,
  1691. * USHORT packet_length);
  1692. *
  1693. * Functional Description
  1694. * This function decodes the Frame Reject packet. We currently don't fully
  1695. * support this packet.
  1696. *
  1697. * Formal Parameters
  1698. * packet_address (i) - Address of packet
  1699. * packet_length (i) - Length of packet
  1700. *
  1701. * Return Value
  1702. * None
  1703. *
  1704. * Side Effects
  1705. * None
  1706. *
  1707. * Caveats
  1708. * None
  1709. */
  1710. void CLayerQ922::ProcessFrameReject (
  1711. LPBYTE packet_address,
  1712. USHORT packet_length)
  1713. {
  1714. TRACE_OUT(("CLayerQ922::ProcessFrameReject"));
  1715. BOOL command_frame;
  1716. BOOL poll_final_bit;
  1717. USHORT status;
  1718. /*
  1719. ** This packet MUST be the correct length or it is an error
  1720. */
  1721. if (packet_length < UNNUMBERED_HEADER_SIZE)
  1722. {
  1723. ERROR_OUT(("Q922: DLCI %d: Frame Reject received: Illegal packet length = %d", DLCI, packet_length));
  1724. return;
  1725. }
  1726. status = ParseUnnumberedPacketHeader (
  1727. packet_address, &command_frame, &poll_final_bit);
  1728. /*
  1729. ** The FRMR packet can ONLY be a RESPONSE, it can not be a COMMAND
  1730. */
  1731. if (command_frame)
  1732. {
  1733. ERROR_OUT(("Q922: DLCI %d: FRMR COMMAND received: Illegal packet", DLCI));
  1734. return;
  1735. }
  1736. if (status == DATALINK_NO_ERROR)
  1737. {
  1738. switch (Data_Link_Mode)
  1739. {
  1740. case TEI_ASSIGNED:
  1741. case AWAITING_ESTABLISHMENT:
  1742. case AWAITING_RELEASE:
  1743. case MULTIPLE_FRAME_ESTABLISHED:
  1744. case TIMER_RECOVERY:
  1745. ERROR_OUT(("Q922: DLCI %d ProcessFrameReject: Illegal packet", DLCI));
  1746. m_pT123->OwnerCallback(m_nMsgBase + DATALINK_RELEASE_INDICATION,
  1747. (void *) DLCI, (void *) DATALINK_ILLEGAL_PACKET_RECEIVED);
  1748. break;
  1749. }
  1750. }
  1751. }
  1752. /*
  1753. * void CLayerQ922::ProcessReceiverReady (
  1754. * LPBYTE packet_address,
  1755. * USHORT packet_length)
  1756. *
  1757. * Functional Description
  1758. * This function decodes the Receiver Ready packet that is in the
  1759. * input buffer. From the packet, we get the packet sequence
  1760. * number that the remote site is expecting.
  1761. *
  1762. * Formal Parameters
  1763. * packet_address (i) - Address of packet
  1764. * packet_length (i) - Length of packet
  1765. *
  1766. * Return Value
  1767. * None
  1768. *
  1769. * Side Effects
  1770. * None
  1771. *
  1772. * Caveats
  1773. * None
  1774. */
  1775. void CLayerQ922::ProcessReceiverReady (
  1776. LPBYTE packet_address,
  1777. USHORT packet_length)
  1778. {
  1779. TRACE_OUT(("CLayerQ922::ProcessReceiverReady"));
  1780. BOOL command_frame;
  1781. UChar receive_sequence_number;
  1782. BOOL poll_final_bit;
  1783. USHORT status;
  1784. /*
  1785. ** This packet MUST be the correct length or it is an error
  1786. */
  1787. if (packet_length != DATALINK_PACKET_OVERHEAD)
  1788. {
  1789. ERROR_OUT(("Q922: DLCI %d: Receiver Ready received: Illegal packet length = %d", DLCI, packet_length));
  1790. return;
  1791. }
  1792. status = ParsePacketHeader (
  1793. packet_address,
  1794. packet_length,
  1795. &command_frame,
  1796. &receive_sequence_number,
  1797. &poll_final_bit);
  1798. if (status == DATALINK_NO_ERROR)
  1799. {
  1800. if (command_frame && poll_final_bit)
  1801. {
  1802. Final_Pending = TRUE;
  1803. }
  1804. Peer_Receiver_Busy = FALSE;
  1805. /*
  1806. ** If the remote site is expecting a packet sequence number
  1807. ** that is not equal to our Acknowledge_State_Variable,
  1808. ** update it
  1809. */
  1810. if (Data_Link_Mode == MULTIPLE_FRAME_ESTABLISHED)
  1811. {
  1812. if (Acknowledge_State_Variable != receive_sequence_number)
  1813. {
  1814. UpdateAcknowledgeState (receive_sequence_number);
  1815. /*
  1816. ** If we have received the last acknowledge,
  1817. ** stop the T200 timer
  1818. */
  1819. if (Acknowledge_State_Variable == Send_State_Variable)
  1820. StopTimerT200 ();
  1821. else
  1822. StartTimerT200 ();
  1823. }
  1824. }
  1825. else
  1826. {
  1827. /*
  1828. ** If we are in TIMER_RECOVERY mode, update the
  1829. ** Acknowledge_State_Variable and resend the packets
  1830. ** that need to be sent.
  1831. */
  1832. UpdateAcknowledgeState (receive_sequence_number);
  1833. if ((command_frame == FALSE) && poll_final_bit)
  1834. {
  1835. ResetSendState ();
  1836. StopTimerT200 ();
  1837. if (Data_Link_Mode != AWAITING_RELEASE)
  1838. Data_Link_Mode = MULTIPLE_FRAME_ESTABLISHED;
  1839. }
  1840. }
  1841. }
  1842. else
  1843. {
  1844. ERROR_OUT(("Q922: DLCI %d: ProcessReceiverReady: Error Processing packet", DLCI));
  1845. }
  1846. }
  1847. /*
  1848. * void CLayerQ922::ProcessReceiverNotReady (
  1849. * LPBYTE packet_address,
  1850. * USHORT packet_length)
  1851. *
  1852. * Functional Description
  1853. * This function decodes the Receiver Not Ready packet that
  1854. * is in the input buffer. This packet notifies us that the
  1855. * remote site does not have room for Information packets.
  1856. * As a result of this packet, we won't send any more packets
  1857. * until the remote site sends us a Receiver Ready packet.
  1858. *
  1859. * Formal Parameters
  1860. * packet_address (i) - Address of packet
  1861. * packet_length (i) - Length of packet
  1862. *
  1863. * Return Value
  1864. * None
  1865. *
  1866. * Side Effects
  1867. * None
  1868. *
  1869. * Caveats
  1870. * None
  1871. */
  1872. void CLayerQ922::ProcessReceiverNotReady (
  1873. LPBYTE packet_address,
  1874. USHORT packet_length)
  1875. {
  1876. TRACE_OUT(("CLayerQ922::ProcessReceiverNotReady"));
  1877. BOOL command_frame;
  1878. UChar receive_sequence_number;
  1879. BOOL poll_final_bit;
  1880. USHORT status;
  1881. /*
  1882. ** This packet MUST be the correct length or it is an error
  1883. */
  1884. if (packet_length != DATALINK_PACKET_OVERHEAD)
  1885. {
  1886. TRACE_OUT(("Q922: DLCI %d: Receiver Not Ready received: Illegal packet length = %d", DLCI, packet_length));
  1887. return;
  1888. }
  1889. status = ParsePacketHeader (
  1890. packet_address,
  1891. packet_length,
  1892. &command_frame,
  1893. &receive_sequence_number,
  1894. &poll_final_bit);
  1895. if (status == DATALINK_NO_ERROR)
  1896. {
  1897. if (command_frame && poll_final_bit)
  1898. {
  1899. Final_Pending = TRUE;
  1900. }
  1901. /*
  1902. ** Set the Peer_Receiver_Busy flag so that we don't send
  1903. ** out any information packets.
  1904. */
  1905. Peer_Receiver_Busy = TRUE;
  1906. UpdateAcknowledgeState (receive_sequence_number);
  1907. if (Data_Link_Mode == MULTIPLE_FRAME_ESTABLISHED)
  1908. StartTimerT200 ();
  1909. else
  1910. {
  1911. /*
  1912. ** If we are in TIMER_RECOVERY state, exit TIMER_RECOVERY
  1913. ** state and update the acknowledge state.
  1914. */
  1915. if ((command_frame == FALSE) && poll_final_bit)
  1916. {
  1917. ResetSendState ();
  1918. StartTimerT200 ();
  1919. if (Data_Link_Mode != AWAITING_RELEASE)
  1920. Data_Link_Mode = MULTIPLE_FRAME_ESTABLISHED;
  1921. }
  1922. }
  1923. }
  1924. else
  1925. {
  1926. ERROR_OUT(("Q922: DLCI %d: ProcessNotReceiverReady: Error Processing packet", DLCI));
  1927. }
  1928. }
  1929. /*
  1930. * void CLayerQ922::ProcessReject (
  1931. * LPBYTE packet_address,
  1932. * USHORT packet_length)
  1933. *
  1934. * Functional Description
  1935. * This function decodes the Receiver Reject packet that
  1936. * is in the input buffer. This packet indicates that the
  1937. * remote site needs us to retransmit some packets. It sends
  1938. * the next packet sequence number that it expects.
  1939. *
  1940. * Formal Parameters
  1941. * packet_address (i) - Address of packet
  1942. * packet_length (i) - Length of packet
  1943. *
  1944. * Return Value
  1945. * None
  1946. *
  1947. * Side Effects
  1948. * None
  1949. *
  1950. * Caveats
  1951. * None
  1952. */
  1953. void CLayerQ922::ProcessReject (
  1954. LPBYTE packet_address,
  1955. USHORT packet_length)
  1956. {
  1957. TRACE_OUT(("CLayerQ922::ProcessReject"));
  1958. BOOL command_frame;
  1959. UChar receive_sequence_number;
  1960. BOOL poll_final_bit;
  1961. USHORT status;
  1962. /*
  1963. ** This packet MUST be the correct length or it is an error
  1964. */
  1965. if (packet_length != DATALINK_PACKET_OVERHEAD)
  1966. {
  1967. ERROR_OUT(("Q922: DLCI %d: REJECT received: Illegal packet length = %d", DLCI, packet_length));
  1968. return;
  1969. }
  1970. status = ParsePacketHeader (
  1971. packet_address,
  1972. packet_length,
  1973. &command_frame,
  1974. &receive_sequence_number,
  1975. &poll_final_bit);
  1976. if (status == DATALINK_NO_ERROR)
  1977. {
  1978. if (command_frame && poll_final_bit)
  1979. {
  1980. Final_Pending = TRUE;
  1981. }
  1982. Peer_Receiver_Busy = FALSE;
  1983. /*
  1984. ** Update the Acknowledge_State_Variable and prepare to
  1985. ** resend the packets that weren't acknowledged.
  1986. */
  1987. UpdateAcknowledgeState (receive_sequence_number);
  1988. if (Data_Link_Mode == MULTIPLE_FRAME_ESTABLISHED)
  1989. {
  1990. ResetSendState ();
  1991. StopTimerT200 ();
  1992. }
  1993. else
  1994. {
  1995. if ((command_frame == FALSE) && poll_final_bit)
  1996. {
  1997. ResetSendState ();
  1998. StopTimerT200 ();
  1999. if (Data_Link_Mode != AWAITING_RELEASE)
  2000. Data_Link_Mode = MULTIPLE_FRAME_ESTABLISHED;
  2001. }
  2002. }
  2003. }
  2004. else
  2005. {
  2006. ERROR_OUT(("Q922: DLCI %d: ProcessReject: Error Processing packet", DLCI));
  2007. }
  2008. }
  2009. /*
  2010. * BOOL CLayerQ922::ProcessInformationFrame (
  2011. * LPBYTE packet_address,
  2012. * USHORT packet_length)
  2013. *
  2014. * Functional Description
  2015. * This function processes the information packet. It checks
  2016. * to see if it has the expected sequence number. If it does,
  2017. * it puts it into the queue which will be read by the user.
  2018. *
  2019. * Formal Parameters
  2020. * packet_address (i) - Address of packet
  2021. * packet_length (i) - Length of packet
  2022. *
  2023. * Return Value
  2024. * TRUE - If the packet was processed
  2025. * FALSE - If the packet was not processed
  2026. *
  2027. * Side Effects
  2028. * None
  2029. *
  2030. * Caveats
  2031. * None
  2032. */
  2033. BOOL CLayerQ922::ProcessInformationFrame (
  2034. LPBYTE packet_address,
  2035. USHORT packet_length)
  2036. {
  2037. TRACE_OUT(("CLayerQ922::ProcessInformationFrame"));
  2038. BOOL command_frame;
  2039. UChar receive_sequence_number;
  2040. BOOL poll_final_bit;
  2041. USHORT status;
  2042. PDataQueue read_queue;
  2043. UChar send_sequence_number;
  2044. BOOL packet_accepted;
  2045. ULONG bytes_accepted;
  2046. if (packet_length < DATALINK_PACKET_OVERHEAD)
  2047. {
  2048. ERROR_OUT(("Q922: DLCI %d: ProcessInformationFrame: Invalid packet length = %d",
  2049. DLCI, packet_length-DATALINK_PACKET_OVERHEAD));
  2050. return (FALSE);
  2051. }
  2052. if (packet_length > (DATALINK_PACKET_OVERHEAD + Maximum_Information_Size))
  2053. {
  2054. ERROR_OUT(("Q922: DLCI %d: ProcessInformationFrame: Invalid information length = %d",
  2055. DLCI, packet_length - DATALINK_PACKET_OVERHEAD));
  2056. return (FALSE);
  2057. }
  2058. /*
  2059. ** If there isn't a place to put the packet, return FALSE
  2060. */
  2061. if ((Data_Indication_Count == Data_Indication_Size) ||
  2062. Own_Receiver_Busy || (Higher_Layer == NULL))
  2063. {
  2064. return (FALSE);
  2065. }
  2066. status = ParsePacketHeader (
  2067. packet_address,
  2068. packet_length,
  2069. &command_frame,
  2070. &receive_sequence_number,
  2071. &poll_final_bit);
  2072. if (status == DATALINK_NO_ERROR)
  2073. {
  2074. if (poll_final_bit && command_frame)
  2075. {
  2076. Final_Pending = TRUE;
  2077. }
  2078. if ((Data_Link_Mode == MULTIPLE_FRAME_ESTABLISHED) &&
  2079. (Peer_Receiver_Busy == FALSE))
  2080. {
  2081. /*
  2082. ** If the remote site does NOT acknowledge the last packet
  2083. ** that we sent out, Update the Acknowledge State variable
  2084. ** by calling UpdateAcknowledgeState()
  2085. */
  2086. if (Acknowledge_State_Variable != receive_sequence_number)
  2087. {
  2088. UpdateAcknowledgeState (receive_sequence_number);
  2089. /*
  2090. ** If the received acknowledge, reflects the last
  2091. ** packet transmitted, stop the T200 timer.
  2092. */
  2093. if (Acknowledge_State_Variable == Send_State_Variable)
  2094. StopTimerT200 ();
  2095. else
  2096. StartTimerT200 ();
  2097. }
  2098. }
  2099. else
  2100. {
  2101. /*
  2102. ** If this is an I-Frame RESPONSE, exit the TIMER_RECOVERY
  2103. ** state
  2104. */
  2105. UpdateAcknowledgeState (receive_sequence_number);
  2106. if ((Data_Link_Mode == TIMER_RECOVERY) && (command_frame == FALSE)
  2107. && poll_final_bit)
  2108. {
  2109. ResetSendState();
  2110. Data_Link_Mode = MULTIPLE_FRAME_ESTABLISHED;
  2111. StopTimerT200 ();
  2112. }
  2113. }
  2114. send_sequence_number = (*(packet_address + CONTROL_BYTE_HIGH) >> 1);
  2115. /*
  2116. ** If this is the packet that we are waiting for,
  2117. ** give it to the Transport Layer.
  2118. */
  2119. if (send_sequence_number == Receive_State_Variable)
  2120. {
  2121. /*
  2122. ** Try to send the packet to the higher layer,
  2123. ** if it accepts it, we won't have to copy it.
  2124. */
  2125. packet_accepted = FALSE;
  2126. if (Data_Indication_Count == 0)
  2127. {
  2128. Higher_Layer -> DataIndication (
  2129. packet_address + DATALINK_PACKET_OVERHEAD,
  2130. packet_length - DATALINK_PACKET_OVERHEAD,
  2131. &bytes_accepted);
  2132. if (bytes_accepted ==
  2133. (ULONG) (packet_length - DATALINK_PACKET_OVERHEAD))
  2134. {
  2135. packet_accepted = TRUE;
  2136. }
  2137. }
  2138. /*
  2139. ** If the higher layer did not accept it, copy it into our
  2140. ** Data Indication queue.
  2141. */
  2142. if (packet_accepted == FALSE)
  2143. {
  2144. read_queue = Data_Indication + Data_Indication_Head;
  2145. memcpy ((PVoid) read_queue->buffer_address,
  2146. (PVoid) (packet_address + DATALINK_PACKET_OVERHEAD),
  2147. packet_length - DATALINK_PACKET_OVERHEAD);
  2148. read_queue->length = packet_length-DATALINK_PACKET_OVERHEAD;
  2149. if (++Data_Indication_Head == Data_Indication_Size)
  2150. Data_Indication_Head = 0;
  2151. if (++Data_Indication_Count == Data_Indication_Size)
  2152. {
  2153. Own_Receiver_Busy = TRUE;
  2154. TRACE_OUT(("Q922: DLCI %d: Own Receiver Busy", DLCI));
  2155. }
  2156. }
  2157. Receive_State_Variable =
  2158. ((Receive_State_Variable + 1) % SEQUENCE_MODULUS);
  2159. Acknowledge_Pending = TRUE;
  2160. Reject_Outstanding = FALSE;
  2161. }
  2162. else
  2163. {
  2164. /*
  2165. ** If we were not expecting this packet, send a REJECT
  2166. ** packet to the remote site.
  2167. */
  2168. if (Reject_Outstanding == FALSE)
  2169. {
  2170. Reject_Pending = TRUE;
  2171. Reject_Outstanding = TRUE;
  2172. }
  2173. }
  2174. }
  2175. else
  2176. {
  2177. ERROR_OUT(("Q922: DLCI %d: ProcessInformation: Error Processing packet", DLCI));
  2178. }
  2179. return (TRUE);
  2180. }
  2181. /*
  2182. * DataLinkError CLayerQ922::ParsePacketHeader (
  2183. * LPBYTE packet_address,
  2184. * USHORT packet_length,
  2185. * BOOL * command_frame,
  2186. * LPBYTE receive_sequence_number,
  2187. * BOOL * poll_final_bit)
  2188. *
  2189. * Functional Description
  2190. * This function decodes the packet header looking for three
  2191. * things:
  2192. *
  2193. * 1. Is the packet a command frame?
  2194. * 2. What is the sequence number in the packet?
  2195. * 3. Does the packet require a respones?
  2196. *
  2197. * Formal Parameters
  2198. * packet_address - (i) Address of the new packet
  2199. * packet_length - (i) Length of the new packet
  2200. * command_frame - (o) Address of variable, it is set to TRUE
  2201. * if it is a COMMAND frame and FALSE if
  2202. * it is a RESPONSE frame
  2203. * receive_sequence_number - (o) Address of variable, it holds the
  2204. * sequence number in the packet
  2205. * poll_final_bit - (o) Address of variable, it is set to TRUE
  2206. * if we need to respond to the packet and
  2207. * FALSE if we don't
  2208. *
  2209. * Return Value
  2210. * DATALINK_RECEIVE_SEQUENCE_VIOLATION -
  2211. * DATALINK_NO_ERROR -
  2212. *
  2213. * Side Effects
  2214. * None
  2215. *
  2216. * Caveats
  2217. * None
  2218. */
  2219. DataLinkError CLayerQ922::ParsePacketHeader (
  2220. LPBYTE packet_address,
  2221. #ifdef _DEBUG
  2222. USHORT packet_length,
  2223. #else
  2224. USHORT,
  2225. #endif
  2226. BOOL * command_frame,
  2227. LPBYTE receive_sequence_number,
  2228. BOOL * poll_final_bit)
  2229. {
  2230. TRACE_OUT(("CLayerQ922::ParsePacketHeader"));
  2231. DataLinkError return_value = DATALINK_NO_ERROR;
  2232. UChar receive_sequence;
  2233. UChar send_state_sequence;
  2234. if (*(packet_address + ADDRESS_BYTE_HIGH) & COMMAND_BIT)
  2235. *command_frame = FALSE;
  2236. else
  2237. *command_frame = TRUE;
  2238. *receive_sequence_number = (*(packet_address + CONTROL_BYTE_LOW) >> 1);
  2239. if (*(packet_address + CONTROL_BYTE_LOW) & POLL_FINAL_BIT)
  2240. *poll_final_bit = TRUE;
  2241. else
  2242. *poll_final_bit = FALSE;
  2243. if (*receive_sequence_number < Acknowledge_State_Variable)
  2244. receive_sequence = *receive_sequence_number + SEQUENCE_MODULUS;
  2245. else
  2246. receive_sequence = *receive_sequence_number;
  2247. if (Send_State_Variable < Acknowledge_State_Variable)
  2248. send_state_sequence = Send_State_Variable + SEQUENCE_MODULUS;
  2249. else
  2250. send_state_sequence = Send_State_Variable;
  2251. /*
  2252. ** Illegal Condition: The remote site is acknowledging a
  2253. ** packet that is not in the range of transmitted packets
  2254. */
  2255. if (receive_sequence > send_state_sequence)
  2256. {
  2257. TRACE_OUT(("Q922: DLCI %d: ParsePacketHeader: Receive Sequence Exception: length = %d", DLCI, packet_length));
  2258. TRACE_OUT(("Q922: ParsePacketHeader: receive_sequence = %d", receive_sequence));
  2259. TRACE_OUT(("Q922: ParsePacketHeader: send_state_sequence = %d", send_state_sequence));
  2260. TRACE_OUT(("Q922: ParsePacketHeader: Acknowledge_State_Var = %d", Acknowledge_State_Variable));
  2261. TRACE_OUT(("Q922: ParsePacketHeader: Send_State_Variable = %d", Send_State_Variable));
  2262. TRACE_OUT(("Q922: ParsePacketHeader: in-packet receive_sequence = %d", *receive_sequence_number));
  2263. TRACE_OUT(("Q922: ParsePacketHeader: Data_Request_Count = %d", Data_Request_Count));
  2264. /*
  2265. ** The following piece of code checks the receive sequence number
  2266. ** against our send state sequence number + the number of packets
  2267. ** queued for transmission. We are doing this to recover from one
  2268. ** of two things:
  2269. **
  2270. ** 1. The T200 timeout value is not long enough.
  2271. ** 2. This Q922 object is not able to check its input
  2272. ** buffers quickly enough to respond to the remote site's
  2273. ** command. If the machine is overloaded with work to
  2274. ** process, this error can occur.
  2275. **
  2276. ** We are checking to see if we are receiving an acknowledge
  2277. ** for a packet that we have already transmitted once. When we
  2278. ** are in this out-of-sync state, it is possible to transmit an
  2279. ** information packet, timeout, and receive a supervisory packet
  2280. ** that does not acknowledge the last packet. As a consequence,
  2281. ** we reset our Send_State_Variable, so that we have no knowledge
  2282. ** of transmitting the information packet. We then may receive
  2283. ** an acknowledge for the information packet, but we don't realize
  2284. ** that we ever transmitted it. This results in a Receive Sequence
  2285. ** Exception.
  2286. **
  2287. ** To guard against this, we are checking to see if this acknowledge
  2288. ** COULD be valid. If it could be valid, we are processing it
  2289. ** normally except for the receive sequence value. We are setting
  2290. ** the receive_sequence_number to that last good acknowledgement and
  2291. ** we will eventually re-transmit the packet. We also send up a
  2292. ** warning to the node controller.
  2293. **
  2294. ** If the acknowledge is not possibly in our range of packets, we
  2295. ** treat it as a real Receive Sequence Exception and break the link.
  2296. */
  2297. if (receive_sequence <= (send_state_sequence + Data_Request_Count))
  2298. {
  2299. *receive_sequence_number = Acknowledge_State_Variable;
  2300. Receive_Sequence_Recovery++;
  2301. TRACE_OUT(("Q922: ParsePacketHeader: Attempting recovery from this exception"));
  2302. TRACE_OUT(("Q922: ParsePacketHeader: Recovery = %d", Receive_Sequence_Recovery));
  2303. /*
  2304. ** Let the user know that there is a problem
  2305. */
  2306. m_pT123->OwnerCallback(m_nMsgBase + T123_STATUS_MESSAGE,
  2307. (void *) DLCI, (void *) DATALINK_TIMING_ERROR);
  2308. }
  2309. else
  2310. {
  2311. TRACE_OUT(("Q922: ParsePacketHeader: CAN NOT recover from this exception"));
  2312. Receive_Sequence_Exception++;
  2313. DISC_Pending = TRUE;
  2314. Unnumbered_PF_State = UNNUMBERED_PF_RESET;
  2315. return_value = DATALINK_RECEIVE_SEQUENCE_VIOLATION;
  2316. }
  2317. }
  2318. return (return_value);
  2319. }
  2320. /*
  2321. * DataLinkError CLayerQ922::ParseUnnumberedPacketHeader (
  2322. * BOOL * command_frame,
  2323. * LPBYTE receive_sequence_number,
  2324. * BOOL * poll_final_bit)
  2325. *
  2326. * Functional Description
  2327. * This function decodes the packet header looking for three
  2328. * things:
  2329. *
  2330. * 1. Is the packet a command frame?
  2331. * 2. What is the sequence number in the packet?
  2332. * 3. Does the packet require a respone?
  2333. *
  2334. * Formal Parameters
  2335. * command_frame - (o) Address of variable, it is set to TRUE
  2336. * if it is a COMMAND frame and FALSE if
  2337. * it is a RESPONSE frame
  2338. * receive_sequence_number - (o) Address of variable, it holds the
  2339. * sequence number in the packet
  2340. * poll_final_bit - (o) Address of variable, it is set to TRUE
  2341. * if we need to respond to the packet and
  2342. * FALSE if we don't
  2343. *
  2344. * Return Value
  2345. * DATALINK_RECEIVE_SEQUENCE_VIOLATION -
  2346. * DATALINK_NO_ERROR -
  2347. *
  2348. * Side Effects
  2349. * None
  2350. *
  2351. * Caveats
  2352. * None
  2353. */
  2354. DataLinkError CLayerQ922::ParseUnnumberedPacketHeader (
  2355. LPBYTE packet_address,
  2356. BOOL * command_frame,
  2357. BOOL * poll_final_bit)
  2358. {
  2359. TRACE_OUT(("CLayerQ922::ParseUnnumberedPacketHeader"));
  2360. if (*(packet_address + ADDRESS_BYTE_HIGH) & COMMAND_BIT)
  2361. *command_frame = FALSE;
  2362. else
  2363. *command_frame = TRUE;
  2364. if (*(packet_address + CONTROL_BYTE_HIGH) & UNNUMBERED_PF_SET)
  2365. *poll_final_bit = TRUE;
  2366. else
  2367. *poll_final_bit = FALSE;
  2368. return (DATALINK_NO_ERROR);
  2369. }
  2370. /*
  2371. * void CLayerQ922::UpdateAcknowledgeState (
  2372. * UChar sequence_number)
  2373. *
  2374. * Functional Description
  2375. * This function updates Acknowledge_State_Variable. The parameter
  2376. * passed in is the sequence number of a packet that the remote site has
  2377. * successfully received. By receiving this sequence number, we can
  2378. * remove the packet from our write queue as well as any packet that
  2379. * was transmitted before that packet.
  2380. *
  2381. * Formal Parameters
  2382. * sequence_number - (i) Sequence number of packet successfully
  2383. * received by the remote site.
  2384. *
  2385. * Return Value
  2386. * None
  2387. *
  2388. * Side Effects
  2389. * None
  2390. *
  2391. * Caveats
  2392. * None
  2393. */
  2394. void CLayerQ922::UpdateAcknowledgeState (
  2395. UChar sequence_number)
  2396. {
  2397. TRACE_OUT(("CLayerQ922::UpdateAcknowledgeState"));
  2398. UChar packets_acknowledged;
  2399. USHORT count;
  2400. PMemory memory;
  2401. ULONG total_length;
  2402. if (Acknowledge_State_Variable != sequence_number)
  2403. {
  2404. /*
  2405. ** Find the number of packets acknowledged by this sequence
  2406. ** number. If the remote site receives X packets successfully,
  2407. ** the next time the remote site transmits, it will send out an
  2408. ** acknowledge for the LAST packet received. All packets
  2409. ** received before it are acknowledged by default.
  2410. */
  2411. if (sequence_number < Acknowledge_State_Variable)
  2412. {
  2413. packets_acknowledged = ((sequence_number + SEQUENCE_MODULUS) -
  2414. Acknowledge_State_Variable);
  2415. }
  2416. else
  2417. {
  2418. packets_acknowledged =
  2419. (sequence_number - Acknowledge_State_Variable);
  2420. }
  2421. /*
  2422. ** Go thru each of the packets acknowledged and Unlock the memory
  2423. ** object associated with it. This will free the memory.
  2424. */
  2425. for (count=0; count < packets_acknowledged; count++)
  2426. {
  2427. memory = *(Data_Request + Data_Request_Acknowledge_Tail);
  2428. total_length = memory -> GetLength ();
  2429. Outstanding_Packets--;
  2430. Outstanding_Bytes -= (USHORT) total_length;
  2431. Data_Request_Memory_Manager -> UnlockMemory (memory);
  2432. if (++Data_Request_Acknowledge_Tail == Data_Request_Total_Size)
  2433. Data_Request_Acknowledge_Tail = 0;
  2434. }
  2435. Acknowledge_State_Variable = sequence_number;
  2436. }
  2437. }
  2438. /*
  2439. * void CLayerQ922::ResetSendState (void)
  2440. *
  2441. * Functional Description
  2442. * This function is called when we need to retransmit packets.
  2443. * The Send_State_Variable is reset to equal the
  2444. * Acknowledge_State_Variable.
  2445. *
  2446. * Formal Parameters
  2447. * None.
  2448. *
  2449. * Return Value
  2450. * None.
  2451. *
  2452. * Side Effects
  2453. * None
  2454. *
  2455. * Caveats
  2456. * None
  2457. */
  2458. void CLayerQ922::ResetSendState (void)
  2459. {
  2460. TRACE_OUT(("CLayerQ922::ResetSendState"));
  2461. /*
  2462. ** Reset the Send_State_Variable so that we resend packets.
  2463. */
  2464. if (Send_State_Variable != Acknowledge_State_Variable)
  2465. {
  2466. Total_Retransmitted += (DWORD) Outstanding_Packets;
  2467. TRACE_OUT(("Q922: DLCI %d: retransmitting %d packets -- Total = %ld",
  2468. DLCI, Outstanding_Packets, Total_Retransmitted));
  2469. Data_Request_Tail = Data_Request_Acknowledge_Tail;
  2470. Data_Request_Count += Outstanding_Packets;
  2471. Outstanding_Packets = 0;
  2472. Outstanding_Bytes = 0;
  2473. Send_State_Variable = Acknowledge_State_Variable;
  2474. }
  2475. }
  2476. /*
  2477. * void CLayerQ922::StartTimerT200 (void)
  2478. *
  2479. * Functional Description
  2480. * This function starts the T200 timer. This timer us started when
  2481. * we send a packet and expect a response. If the response is not
  2482. * received within the T200 time span. The timer expires and we
  2483. * enter a TIMER_RECOVERY state.
  2484. *
  2485. * Formal Parameters
  2486. * None.
  2487. *
  2488. * Return Value
  2489. * None.
  2490. *
  2491. * Side Effects
  2492. * None
  2493. *
  2494. * Caveats
  2495. * None
  2496. */
  2497. void CLayerQ922::StartTimerT200 (void)
  2498. {
  2499. TRACE_OUT(("CLayerQ922::StartTimerT200"));
  2500. if (T200_Active)
  2501. {
  2502. StopTimerT200 ();
  2503. }
  2504. if (T203_Active)
  2505. {
  2506. StopTimerT203 ();
  2507. }
  2508. T200_Handle = g_pSystemTimer->CreateTimerEvent(T200_Timeout,
  2509. TIMER_EVENT_ONE_SHOT,
  2510. this,
  2511. (PTimerFunction) &CLayerQ922::T200Timeout);
  2512. T200_Active = TRUE;
  2513. }
  2514. /*
  2515. * void CLayerQ922::StopTimerT200 (void)
  2516. *
  2517. * Functional Description
  2518. * This function stops the T200 timer. If we receive a response
  2519. * to a packet before the T200 timer expires, this function is
  2520. * called.
  2521. *
  2522. * Formal Parameters
  2523. * None.
  2524. *
  2525. * Return Value
  2526. * None.
  2527. *
  2528. * Side Effects
  2529. * None
  2530. *
  2531. * Caveats
  2532. * None
  2533. */
  2534. void CLayerQ922::StopTimerT200 (void)
  2535. {
  2536. TRACE_OUT(("CLayerQ922::StopTimerT200"));
  2537. if (T200_Active)
  2538. {
  2539. if (g_pSystemTimer->DeleteTimerEvent(T200_Handle) != TIMER_NO_ERROR)
  2540. {
  2541. TRACE_OUT(("Q922: StopTimerT200: DLCI %d: Illegal Timer handle = %d", DLCI, T200_Handle));
  2542. }
  2543. T200_Active = FALSE;
  2544. }
  2545. }
  2546. /*
  2547. * void CLayerQ922::T200Timeout (
  2548. * TimerEventHandle)
  2549. *
  2550. * Functional Description
  2551. * This function is called by the timer class when the T200
  2552. * timer expires.
  2553. *
  2554. * Formal Parameters
  2555. * None.
  2556. *
  2557. * Return Value
  2558. * None.
  2559. *
  2560. * Side Effects
  2561. * None
  2562. *
  2563. * Caveats
  2564. * None
  2565. */
  2566. void CLayerQ922::T200Timeout(TimerEventHandle)
  2567. {
  2568. TRACE_OUT(("CLayerQ922::T200Timeout"));
  2569. BOOL send_disconnect = FALSE;
  2570. T200_Active = FALSE;
  2571. N200_Count++;
  2572. TRACE_OUT(("Q922::T200Timeout: %d DLCI: Timer Recovery: N200_Count = %x", DLCI, N200_Count));
  2573. if ((Maximum_T200_Timeouts != 0xffff) &&
  2574. (N200_Count >= Maximum_T200_Timeouts))
  2575. {
  2576. Link_Stable = FALSE;
  2577. send_disconnect = TRUE;
  2578. }
  2579. switch (Data_Link_Mode)
  2580. {
  2581. case TEI_ASSIGNED:
  2582. break;
  2583. case AWAITING_ESTABLISHMENT:
  2584. if (! Link_Stable)
  2585. {
  2586. break;
  2587. }
  2588. if (Link_Originator)
  2589. {
  2590. SABME_Pending = TRUE;
  2591. Unnumbered_PF_State = UNNUMBERED_PF_SET;
  2592. }
  2593. break;
  2594. case AWAITING_RELEASE:
  2595. if (Final_Packet)
  2596. {
  2597. send_disconnect = TRUE;
  2598. }
  2599. else
  2600. {
  2601. if (! Link_Stable)
  2602. {
  2603. send_disconnect = TRUE;
  2604. }
  2605. else
  2606. {
  2607. DISC_Pending = TRUE;
  2608. Unnumbered_PF_State = UNNUMBERED_PF_SET;
  2609. }
  2610. }
  2611. break;
  2612. default:
  2613. if (! Link_Stable)
  2614. {
  2615. TRACE_OUT(("Q922: DLCI %d T200 Timeout: Broken Connection", DLCI));
  2616. Reset ();
  2617. Data_Link_Mode = TEI_ASSIGNED;
  2618. }
  2619. else
  2620. {
  2621. Data_Link_Mode = TIMER_RECOVERY;
  2622. Poll_Pending = TRUE;
  2623. StartTimerT200 ();
  2624. }
  2625. }
  2626. /*
  2627. ** Notify the owner that the link is unstable
  2628. */
  2629. if (send_disconnect)
  2630. {
  2631. m_pT123->OwnerCallback(m_nMsgBase + DATALINK_RELEASE_INDICATION,
  2632. (void *) DLCI, (void *) DATALINK_REMOTE_SITE_TIMED_OUT);
  2633. }
  2634. }
  2635. /*
  2636. * void CLayerQ922::StartTimerT203 (void)
  2637. *
  2638. * Functional Description
  2639. * This function starts the T203 timer. This function is called
  2640. * when the T200 timer is not active. The T203 timer expires
  2641. * when we don't receive a packet from the remote site in T203
  2642. * seconds.
  2643. *
  2644. * Formal Parameters
  2645. * None.
  2646. *
  2647. * Return Value
  2648. * None.
  2649. *
  2650. * Side Effects
  2651. * None
  2652. *
  2653. * Caveats
  2654. * None
  2655. */
  2656. void CLayerQ922::StartTimerT203 (void)
  2657. {
  2658. TRACE_OUT(("CLayerQ922::StartTimerT203"));
  2659. if (T203_Timeout == 0)
  2660. {
  2661. return;
  2662. }
  2663. if (T203_Active)
  2664. {
  2665. StopTimerT203 ();
  2666. }
  2667. T203_Handle = g_pSystemTimer->CreateTimerEvent(
  2668. T203_Timeout, TIMER_EVENT_ONE_SHOT, this,
  2669. (PTimerFunction) &CLayerQ922::T203Timeout);
  2670. T203_Active = TRUE;
  2671. }
  2672. /*
  2673. * void CLayerQ922::StopTimerT203 (void)
  2674. *
  2675. * Functional Description
  2676. * This function stops the T203 timer. If we receive a packet
  2677. * while the T203 packet is active, this function is called.
  2678. *
  2679. * Formal Parameters
  2680. * None.
  2681. *
  2682. * Return Value
  2683. * None.
  2684. *
  2685. * Side Effects
  2686. * None
  2687. *
  2688. * Caveats
  2689. * None
  2690. */
  2691. void CLayerQ922::StopTimerT203 (void)
  2692. {
  2693. TRACE_OUT(("CLayerQ922::StopTimerT203"));
  2694. if (T203_Active)
  2695. {
  2696. g_pSystemTimer->DeleteTimerEvent(T203_Handle);
  2697. T203_Active = FALSE;
  2698. }
  2699. }
  2700. /*
  2701. * void CLayerQ922::T203Timeout (
  2702. * TimerEventHandle)
  2703. *
  2704. * Functional Description
  2705. * This function is called by the timer class when the T203
  2706. * timer expires.
  2707. *
  2708. * Formal Parameters
  2709. * None.
  2710. *
  2711. * Return Value
  2712. * None.
  2713. *
  2714. * Side Effects
  2715. * None
  2716. *
  2717. * Caveats
  2718. * None
  2719. */
  2720. void CLayerQ922::T203Timeout (TimerEventHandle)
  2721. {
  2722. TRACE_OUT(("CLayerQ922::T203Timeout"));
  2723. T203_Active = FALSE;
  2724. if (Data_Link_Mode == TEI_ASSIGNED)
  2725. {
  2726. TRACE_OUT(("Q922: DLCI %d: T203 Timeout: Releasing connection", DLCI));
  2727. m_pT123->OwnerCallback(m_nMsgBase + DATALINK_RELEASE_INDICATION,
  2728. (void *) DLCI, (void *) DATALINK_REMOTE_SITE_TIMED_OUT);
  2729. return;
  2730. }
  2731. StartTimerT200 ();
  2732. Data_Link_Mode = TIMER_RECOVERY;
  2733. Poll_Pending = TRUE;
  2734. }
  2735. /*
  2736. * ProtocolLayerError CLayerQ922::GetParameters (
  2737. * USHORT,
  2738. * USHORT * max_packet_size,
  2739. * USHORT * prepend,
  2740. * USHORT * append)
  2741. *
  2742. * Public
  2743. *
  2744. * Functional Description:
  2745. * This function returns the maximum packet size permitted by
  2746. * the higher layer.
  2747. */
  2748. ProtocolLayerError CLayerQ922::GetParameters (
  2749. USHORT * packet_size,
  2750. USHORT * prepend,
  2751. USHORT * append)
  2752. {
  2753. TRACE_OUT(("CLayerQ922::GetParameters"));
  2754. *prepend = DATALINK_PACKET_OVERHEAD + Lower_Layer_Prepend;
  2755. *append = Lower_Layer_Append;
  2756. *packet_size = Maximum_Information_Size;
  2757. return (PROTOCOL_LAYER_NO_ERROR);
  2758. }
  2759. /*
  2760. * ProtocolLayerError CLayerQ922::RegisterHigherLayer (
  2761. * USHORT,
  2762. * PMemoryManager,
  2763. * IProtocolLayer * higher_layer);
  2764. *
  2765. * Public
  2766. *
  2767. * Functional Description:
  2768. * This function is called to register an identifier with a higher
  2769. * layer address.
  2770. */
  2771. ProtocolLayerError CLayerQ922::RegisterHigherLayer (
  2772. ULONG_PTR,
  2773. PMemoryManager,
  2774. IProtocolLayer * higher_layer)
  2775. {
  2776. TRACE_OUT(("CLayerQ922::RegisterHigherLayer"));
  2777. Higher_Layer = higher_layer; // CLayerSCF or CLayerX224
  2778. return (PROTOCOL_LAYER_NO_ERROR);
  2779. }
  2780. /*
  2781. * ProtocolLayerError CLayerQ922::RemoveHigherLayer (
  2782. * USHORT);
  2783. *
  2784. * Public
  2785. *
  2786. * Functional Description:
  2787. * This function removes the higher layer from our list
  2788. */
  2789. ProtocolLayerError CLayerQ922::RemoveHigherLayer (
  2790. ULONG_PTR)
  2791. {
  2792. TRACE_OUT(("CLayerQ922::RemoveHigherLayer"));
  2793. Higher_Layer = NULL;
  2794. return (PROTOCOL_LAYER_NO_ERROR);
  2795. }
  2796.