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.

1686 lines
56 KiB

  1. #include "precomp.h"
  2. DEBUG_FILEZONE(ZONE_T120_T123PSTN);
  3. /* X224.cpp
  4. *
  5. * Copyright (c) 1994 by DataBeam Corporation, Lexington, KY
  6. *
  7. * Abstract:
  8. *
  9. * Private Instance Variables:
  10. * Default_PDU_Size - Default PDU size, if no arb. is done
  11. * Data_Request_Memory_Manager - Memory manager
  12. * Lower_Layer_Prepend - Number of bytes prepended to packet by
  13. * lower layer
  14. * Lower_Layer_Append - Number of bytes appended to packet byt
  15. * lower layer
  16. * Shutdown_Receiver - TRUE if we aren't to receive any more
  17. * packets from the lower layer
  18. * Shutdown_Transmitter - TRUE if we aren't to transmit any more
  19. * packets
  20. * Data_Request_Queue - Queue that keeps the pending user data
  21. * requests
  22. * Data_Indication_Queue - Queue that holds the pending user data
  23. * indications
  24. * Data_Indication_Memory_Pool - List that holds available data
  25. * indication buffers.
  26. *
  27. * Active_Data_Indication - Address of packet structure. This
  28. * packet holds the current data indication
  29. * that we are reassembling
  30. * m_pT123 - Address of owner object. Used for
  31. * callbacks
  32. * m_pQ922 - Address of lower layer.
  33. * m_nMsgBase - Message base to be used for owner
  34. * callbacks
  35. * Maximum_PDU_Size - Max. PDU size
  36. * Arbitrated_PDU_Size - Max. arbitrated packet size.
  37. * Identifier - Identifier passed to lower layer to
  38. * register ourselves.
  39. * Data_Indication_Queue_Size - Number of data indications we will
  40. * buffer
  41. * Data_Indication_Reassembly_Active - Flag set if we are in the middle
  42. * of a packet reassembly.
  43. * State - Holds the current state of the object
  44. * Packet_Pending - Tells which packet will be sent next.
  45. * Reject_Cause - The reason why the error packet was sent
  46. * Packet_Size_Respond - Set to TRUE if we are to send a TPDU
  47. * size element in the CC packet
  48. * Error_Buffer - Address of error buffer.
  49. * Error_Buffer_Length - Length of error buffer.
  50. *
  51. * m_nLocalLogicalHandle - Local transport connection id.
  52. * m_nRemoteLogicalHandle - Remote transport connection id.
  53. * User_Data_Pending - Set to the size of the last packet that
  54. * the user attempted to pass to us, that
  55. * we couldn't accept because we ran out
  56. * of memory.
  57. *
  58. * Caveats:
  59. * None.
  60. *
  61. * Authors:
  62. * James W. Lawwill
  63. */
  64. #include <windowsx.h>
  65. #include "x224.h"
  66. /*
  67. * CLayerX224::CLayerX224 (
  68. * PTransportResources transport_resources,
  69. * IObject * owner_object,
  70. * IProtocolLayer * lower_layer,
  71. * USHORT message_base,
  72. * USHORT logical_handle,
  73. * USHORT identifier,
  74. * USHORT data_indication_queue_size,
  75. * USHORT default_PDU_size,
  76. * PMemoryManager dr_memory_manager,
  77. * BOOL * initialization_success)
  78. *
  79. * Public
  80. *
  81. * Functional Description:
  82. * This is the Transport constructor. This routine initializes all
  83. * variables and allocates the buffers needed to operate.
  84. */
  85. CLayerX224::CLayerX224
  86. (
  87. T123 *owner_object,
  88. CLayerQ922 *pQ922, // lower layer
  89. USHORT message_base,
  90. LogicalHandle logical_handle,
  91. ULONG identifier,
  92. USHORT data_indication_queue_size,
  93. USHORT default_PDU_size,
  94. PMemoryManager dr_memory_manager,
  95. BOOL *initialization_success
  96. )
  97. :
  98. m_pT123(owner_object),
  99. m_nMsgBase(message_base),
  100. m_pQ922(pQ922)
  101. {
  102. TRACE_OUT(("CLayerX224::CLayerX224"));
  103. ProtocolLayerError error;
  104. m_nLocalLogicalHandle = logical_handle;
  105. Identifier = identifier;
  106. Default_PDU_Size = default_PDU_size;
  107. Data_Request_Memory_Manager = dr_memory_manager;
  108. *initialization_success = TRUE;
  109. Shutdown_Receiver = FALSE;
  110. Shutdown_Transmitter = FALSE;
  111. Reject_Cause = 0;
  112. /*
  113. ** Find the maximum packet size
  114. */
  115. m_pQ922->GetParameters(
  116. &Maximum_PDU_Size,
  117. &Lower_Layer_Prepend,
  118. &Lower_Layer_Append);
  119. Arbitrated_PDU_Size = Default_PDU_Size;
  120. /*
  121. ** Figure out what our largest PDU could be. We will use this value to
  122. ** arbitrate the maximum PDU size.
  123. */
  124. Maximum_PDU_Size = (USHORT)GetMaxTPDUSize (Maximum_PDU_Size);
  125. /*
  126. ** Register with the lower layer, so we can send and receive packets.
  127. */
  128. error = m_pQ922->RegisterHigherLayer(
  129. identifier,
  130. Data_Request_Memory_Manager,
  131. (IProtocolLayer *) this);
  132. if (error != PROTOCOL_LAYER_NO_ERROR)
  133. {
  134. ERROR_OUT(("X224: constructor: Error registering with lower layer"));
  135. *initialization_success = FALSE;
  136. }
  137. /*
  138. ** Prepare for buffer allocation
  139. */
  140. Data_Indication_Queue_Size = data_indication_queue_size;
  141. Error_Buffer = NULL;
  142. /*
  143. ** Set member variables appropriately
  144. */
  145. Active_Data_Indication = NULL;
  146. Data_Indication_Reassembly_Active = FALSE;
  147. Packet_Pending = TRANSPORT_NO_PACKET;
  148. User_Data_Pending = 0;
  149. m_nRemoteLogicalHandle = 0;
  150. Packet_Size_Respond = FALSE;
  151. if (*initialization_success == FALSE)
  152. State = FAILED_TO_INITIALIZE;
  153. else
  154. State = NO_CONNECTION;
  155. }
  156. /*
  157. * CLayerX224::~CLayerX224 (void)
  158. *
  159. * Public
  160. *
  161. * Functional Description:
  162. * This is the Transport destructor. This routine cleans up everything.
  163. */
  164. CLayerX224::~CLayerX224(void)
  165. {
  166. TRACE_OUT(("CLayerX224::~CLayerX224"));
  167. PMemory lpMemory;
  168. PTMemory lptMem;
  169. /*
  170. ** Notify the lower layer that we are terminating
  171. */
  172. m_pQ922->RemoveHigherLayer(Identifier);
  173. /*
  174. ** Go thru the data request queue and delete the structures held in the
  175. ** queue.
  176. */
  177. Data_Request_Queue.reset();
  178. while (Data_Request_Queue.iterate ((PDWORD_PTR) &lpMemory))
  179. {
  180. Data_Request_Memory_Manager-> FreeMemory (lpMemory);
  181. }
  182. /*
  183. ** Go thru the data indication queue and delete the structures held in the
  184. ** queue.
  185. */
  186. Data_Indication_Queue.reset();
  187. while (Data_Indication_Queue.iterate ((PDWORD_PTR) &lptMem))
  188. delete lptMem;
  189. /*
  190. ** Go thru the data request free structure pool and delete the structures
  191. ** held in the pool.
  192. */
  193. Data_Indication_Memory_Pool.reset();
  194. while (Data_Indication_Memory_Pool.iterate ((PDWORD_PTR) &lptMem))
  195. delete lptMem;
  196. /*
  197. ** If there is a data indication active, delete that structure.
  198. */
  199. delete Active_Data_Indication;
  200. /*
  201. ** If the error buffer holds a packet, delete it
  202. */
  203. delete [] Error_Buffer;
  204. return;
  205. }
  206. /*
  207. * TransportError CLayerX224::ConnectRequest (void)
  208. *
  209. * Public
  210. *
  211. * Functional Description:
  212. * This function initiates a connect request.
  213. */
  214. TransportError CLayerX224::ConnectRequest (void)
  215. {
  216. TRACE_OUT(("CLayerX224::ConnectRequest"));
  217. if (State != NO_CONNECTION)
  218. {
  219. ERROR_OUT(("Transport: Illegal ConnectRequest packet"));
  220. return (TRANSPORT_CONNECT_REQUEST_FAILED);
  221. }
  222. Packet_Pending = CONNECTION_REQUEST_PACKET;
  223. return (TRANSPORT_NO_ERROR);
  224. }
  225. /*
  226. * TransportError CLayerX224::ShutdownReceiver (void)
  227. *
  228. * Public
  229. *
  230. * Functional Description:
  231. * This function stops us from receiving any more packets from the lower
  232. * layer
  233. */
  234. void CLayerX224::ShutdownReceiver (void)
  235. {
  236. TRACE_OUT(("CLayerX224::ShutdownReceiver"));
  237. Shutdown_Receiver = TRUE;
  238. }
  239. /*
  240. * TransportError CLayerX224::EnableReceiver (void)
  241. *
  242. * Public
  243. *
  244. * Functional Description:
  245. * This function permits us to send packets to the user application.
  246. */
  247. void CLayerX224::EnableReceiver (void)
  248. {
  249. TRACE_OUT(("CLayerX224::EnableReceiver"));
  250. Shutdown_Receiver = FALSE;
  251. }
  252. /*
  253. * TransportError CLayerX224::ShutdownTransmitter (void)
  254. *
  255. * Public
  256. *
  257. * Functional Description:
  258. * This function keeps us from transmitting any more packets
  259. */
  260. void CLayerX224::ShutdownTransmitter (void)
  261. {
  262. TRACE_OUT(("CLayerX224::ShutdownTransmitter"));
  263. Shutdown_Transmitter = TRUE;
  264. }
  265. /*
  266. * TransportError CLayerX224::PurgeRequest (void)
  267. *
  268. * Public
  269. *
  270. * Functional Description:
  271. * This function removes all packets from out output queue that aren't
  272. * active
  273. */
  274. void CLayerX224::PurgeRequest (void)
  275. {
  276. TRACE_OUT(("CLayerX224::PurgeRequest"));
  277. DWORD entries;
  278. DWORD keep_counter = 0;
  279. PMemory memory;
  280. LPBYTE packet_address;
  281. DWORD i;
  282. if (Data_Request_Queue.isEmpty() == FALSE)
  283. {
  284. entries = Data_Request_Queue.entries ();
  285. /*
  286. ** Go thru packets looking for the last PDU in the SDU
  287. */
  288. Data_Request_Queue.reset();
  289. while (Data_Request_Queue.iterate ((PDWORD_PTR) &memory))
  290. {
  291. keep_counter++;
  292. packet_address = memory -> GetPointer ();
  293. if (*(packet_address + 2) == EOT_BIT)
  294. break;
  295. }
  296. TRACE_OUT(("PurgeRequest: Removing %d packets", entries-keep_counter));
  297. for (i=keep_counter; i<entries; i++)
  298. {
  299. Data_Request_Memory_Manager->FreeMemory ((PMemory) Data_Request_Queue.removeLast ());
  300. }
  301. }
  302. return;
  303. }
  304. /*
  305. * TransportError CLayerX224::ConnectResponse (void)
  306. *
  307. * Public
  308. *
  309. * Functional Description:
  310. * This function initiates a connect response.
  311. */
  312. TransportError CLayerX224::ConnectResponse (void)
  313. {
  314. TRACE_OUT(("CLayerX224::ConnectResponse"));
  315. if (State != RECEIVED_CONNECT_REQUEST_PACKET)
  316. {
  317. ERROR_OUT(("Transport: Illegal ConnectResponse packet"));
  318. return (TRANSPORT_CONNECT_RESPONSE_FAILED);
  319. }
  320. Packet_Pending = CONNECTION_CONFIRM_PACKET;
  321. return (TRANSPORT_NO_ERROR);
  322. }
  323. /*
  324. * TransportError CLayerX224::DisconnectRequest (void)
  325. *
  326. * Public
  327. *
  328. * Functional Description:
  329. * This function initiates a disconnect request.
  330. */
  331. TransportError CLayerX224::DisconnectRequest (void)
  332. {
  333. TRACE_OUT(("CLayerX224::DisconnectRequest"));
  334. if (State == SENT_CONNECT_REQUEST_PACKET)
  335. {
  336. /*
  337. ** The connection is being rejected, send out the DISCONNECT
  338. ** packet and wait for termination
  339. */
  340. Packet_Pending = DISCONNECT_REQUEST_PACKET;
  341. }
  342. else
  343. {
  344. /*
  345. ** Normal disconnects don't send any notification to the remote site.
  346. ** It depends on the Network layer to terminate the link.
  347. */
  348. m_pQ922->RemoveHigherLayer(Identifier);
  349. m_pT123->OwnerCallback(m_nMsgBase + TPRT_DISCONNECT_INDICATION,
  350. (void *) m_nLocalLogicalHandle);
  351. }
  352. return (TRANSPORT_NO_ERROR);
  353. }
  354. /*
  355. * TransportError CLayerX224::DataIndication (
  356. * LPBYTE packet_address,
  357. * ULONG buffer_size,
  358. * PULong packet_length)
  359. *
  360. * Public
  361. *
  362. * Functional Description:
  363. * This function is called by the lower layer when it has a packet for us.
  364. */
  365. ProtocolLayerError CLayerX224::DataIndication (
  366. LPBYTE packet_address,
  367. ULONG packet_length,
  368. PULong bytes_accepted)
  369. {
  370. TRACE_OUT(("CLayerX224::DataIndication"));
  371. ULONG remainder_length;
  372. USHORT class_request;
  373. USHORT packet_type;
  374. USHORT length;
  375. USHORT destination_reference;
  376. LegacyTransportData transport_data;
  377. BOOL packet_accepted;
  378. ULONG user_accepted;
  379. UChar eot;
  380. PTMemory packet;
  381. TMemoryError packet_error;
  382. LPBYTE temp_address;
  383. BOOL use_default_PDU_size;
  384. *bytes_accepted = 0;
  385. packet_accepted = FALSE;
  386. /*
  387. ** If the receiver is shutdown, don't accept any data
  388. */
  389. if (Shutdown_Receiver)
  390. return (PROTOCOL_LAYER_NO_ERROR);
  391. /*
  392. ** The packet must be at least 2 bytes long
  393. */
  394. if (packet_length < 2)
  395. {
  396. ERROR_OUT(("X224: DataIndication: Invalid packet received from lower layer: length = %d", packet_length));
  397. return (PROTOCOL_LAYER_NO_ERROR);
  398. }
  399. remainder_length = packet_length;
  400. temp_address = packet_address;
  401. packet_address++;
  402. packet_type = *(packet_address++) & TPDU_CODE_MASK;
  403. remainder_length -= 2;
  404. switch (packet_type)
  405. {
  406. case CONNECTION_REQUEST_PACKET:
  407. packet_accepted = TRUE;
  408. /*
  409. ** There should be at least 5 bytes remaining in this packet
  410. */
  411. if (remainder_length < 5)
  412. {
  413. ERROR_OUT(("X224: DataIndication: CR: Invalid packet received from lower layer: length = %d", packet_length));
  414. break;
  415. }
  416. /*
  417. ** Increment the packet address by 2 to get past the DST_REF
  418. */
  419. packet_address += 2;
  420. m_nRemoteLogicalHandle = *(packet_address++);
  421. m_nRemoteLogicalHandle <<= 8;
  422. m_nRemoteLogicalHandle |= *(packet_address++);
  423. remainder_length -= 4;
  424. /*
  425. ** Look at the class request to make sure it is 0
  426. */
  427. class_request = *(packet_address++) >> 4;
  428. remainder_length -= 1;
  429. if (class_request != 0)
  430. {
  431. ERROR_OUT(("X224: DataIndication: CR packet: Illegal class request"));
  432. ErrorPacket (
  433. temp_address,
  434. (USHORT) (packet_length - remainder_length));
  435. break;
  436. }
  437. use_default_PDU_size = TRUE;
  438. while (remainder_length != 0)
  439. {
  440. switch (*(packet_address++))
  441. {
  442. case TPDU_SIZE:
  443. length = *(packet_address++);
  444. remainder_length -= 1;
  445. if (length != 1)
  446. {
  447. TRACE_OUT(("X224: DataIndication: CR packet: Illegal TPDU_Size length"));
  448. ErrorPacket (
  449. temp_address,
  450. (USHORT) (packet_length - remainder_length));
  451. break;
  452. }
  453. /*
  454. ** Figure out the actual PDU size
  455. */
  456. Arbitrated_PDU_Size = (1 << *(packet_address++));
  457. remainder_length -= 1;
  458. TRACE_OUT(("X224: CR_Packet: Packet size = %d", Arbitrated_PDU_Size));
  459. if (Arbitrated_PDU_Size > Maximum_PDU_Size)
  460. {
  461. Packet_Size_Respond = TRUE;
  462. Arbitrated_PDU_Size = Maximum_PDU_Size;
  463. }
  464. if (AllocateBuffers() == FALSE)
  465. {
  466. m_pT123->OwnerCallback(m_nMsgBase + TPRT_DISCONNECT_INDICATION,
  467. (void *) m_nLocalLogicalHandle);
  468. }
  469. use_default_PDU_size = FALSE;
  470. break;
  471. default:
  472. ERROR_OUT(("X224: DataIndication: CR packet Unsupported parameter 0x%x", *(packet_address - 1)));
  473. length = *(packet_address++);
  474. remainder_length--;
  475. packet_address += length;
  476. remainder_length -= length;
  477. break;
  478. }
  479. remainder_length--;
  480. }
  481. /*
  482. ** If the initiator wants to use the default PDU size, we need to
  483. ** check the default size with the Max. size to make sure it is
  484. ** valid for us.
  485. */
  486. if (use_default_PDU_size)
  487. {
  488. if (Default_PDU_Size > Maximum_PDU_Size)
  489. {
  490. Packet_Size_Respond = TRUE;
  491. Arbitrated_PDU_Size = Maximum_PDU_Size;
  492. }
  493. if (AllocateBuffers() == FALSE)
  494. {
  495. m_pT123->OwnerCallback(m_nMsgBase + TPRT_DISCONNECT_INDICATION,
  496. (void *) m_nLocalLogicalHandle);
  497. }
  498. }
  499. State = RECEIVED_CONNECT_REQUEST_PACKET;
  500. /*
  501. ** Notify the owner that the remote site wants to start a
  502. ** connection
  503. */
  504. m_pT123->OwnerCallback(m_nMsgBase + TPRT_CONNECT_INDICATION,
  505. (void *) m_nLocalLogicalHandle);
  506. TRACE_OUT(("X224: DataInd: ConnectRequest: max pkt = %d", Arbitrated_PDU_Size));
  507. break;
  508. case CONNECTION_CONFIRM_PACKET:
  509. packet_accepted = TRUE;
  510. /*
  511. ** There should be at least 5 bytes remaining in this packet
  512. */
  513. if (remainder_length < 5)
  514. {
  515. ERROR_OUT(("X224: DataIndication: CC: Invalid packet received from lower layer: length = %d",
  516. packet_length));
  517. break;
  518. }
  519. destination_reference = *(packet_address++);
  520. destination_reference <<= 8;
  521. destination_reference |= *(packet_address++);
  522. remainder_length -= 2;
  523. if (destination_reference != m_nLocalLogicalHandle)
  524. {
  525. ERROR_OUT(("X224: DataIndication: CC packet: DST-REF incorrect"));
  526. ErrorPacket (
  527. temp_address,
  528. (USHORT) (packet_length - remainder_length));
  529. break;
  530. }
  531. m_nRemoteLogicalHandle = *(packet_address++);
  532. m_nRemoteLogicalHandle <<= 8;
  533. m_nRemoteLogicalHandle |= *(packet_address++);
  534. class_request = *(packet_address++) >> 4;
  535. remainder_length -= 3;
  536. if (class_request != 0)
  537. {
  538. ERROR_OUT(("X224: DataIndication: CR packet: Illegal class request"));
  539. ErrorPacket (
  540. temp_address,
  541. (USHORT) (packet_length - remainder_length));
  542. break;
  543. }
  544. use_default_PDU_size = TRUE;
  545. while (remainder_length != 0)
  546. {
  547. switch (*(packet_address++))
  548. {
  549. case TPDU_SIZE:
  550. length = *(packet_address++);
  551. remainder_length -= 1;
  552. if (length != 1)
  553. {
  554. ERROR_OUT(("X224: DataIndication: CR packet: Illegal TPDU_Size length"));
  555. ErrorPacket (
  556. temp_address,
  557. (USHORT) (packet_length - remainder_length));
  558. }
  559. Arbitrated_PDU_Size = (1 << *(packet_address++));
  560. remainder_length -= 1;
  561. TRACE_OUT(("X224: CC_Packet: Packet size = %d", Arbitrated_PDU_Size));
  562. use_default_PDU_size = FALSE;
  563. /*
  564. ** Allocate the buffers
  565. */
  566. if (AllocateBuffers() == FALSE)
  567. {
  568. m_pT123->OwnerCallback(m_nMsgBase + TPRT_DISCONNECT_INDICATION,
  569. (void *) m_nLocalLogicalHandle);
  570. }
  571. break;
  572. default:
  573. ERROR_OUT(("X224: DataIndication: CC packet Unsupported parameter"));
  574. length = *(packet_address++);
  575. remainder_length--;
  576. packet_address += length;
  577. remainder_length -= length;
  578. break;
  579. }
  580. remainder_length--;
  581. }
  582. if (use_default_PDU_size)
  583. {
  584. if (AllocateBuffers () == FALSE)
  585. {
  586. m_pT123->OwnerCallback(m_nMsgBase + TPRT_DISCONNECT_INDICATION,
  587. (void *) m_nLocalLogicalHandle);
  588. }
  589. }
  590. State = CONNECTION_ACTIVE;
  591. /*
  592. ** Notify the owner that the connect request has been confirmed
  593. */
  594. m_pT123->OwnerCallback(m_nMsgBase + TPRT_CONNECT_CONFIRM,
  595. (void *) m_nLocalLogicalHandle);
  596. TRACE_OUT(("X224: DataInd: ConnectConfirm max pkt = %d", Arbitrated_PDU_Size));
  597. break;
  598. case DISCONNECT_REQUEST_PACKET:
  599. TRACE_OUT(("X224: DataIndication: Disconnect req. received"));
  600. /*
  601. ** Notify the owner that a disconnect has been requested. This
  602. ** message is only valid during establishment of the connection.
  603. */
  604. m_pT123->OwnerCallback(m_nMsgBase + TPRT_DISCONNECT_INDICATION,
  605. (void *) m_nLocalLogicalHandle);
  606. packet_accepted = TRUE;
  607. break;
  608. case ERROR_PACKET:
  609. TRACE_OUT(("X224: DataIndication: ERROR REQUEST received"));
  610. /*
  611. ** Notify the owner that the remote site has detected an error in
  612. ** one of our packets.
  613. */
  614. m_pT123->OwnerCallback(m_nMsgBase + TPRT_DISCONNECT_INDICATION,
  615. (void *) m_nLocalLogicalHandle);
  616. packet_accepted = TRUE;
  617. break;
  618. case DATA_PACKET:
  619. if ((Data_Indication_Reassembly_Active == FALSE) &&
  620. Data_Indication_Memory_Pool.isEmpty())
  621. {
  622. break;
  623. }
  624. packet_accepted = TRUE;
  625. /*
  626. ** There should be at least 1 bytes remaining in this packet
  627. */
  628. if (remainder_length < 1)
  629. {
  630. ERROR_OUT(("X224: DataIndication: DATA: Invalid packet "
  631. "received from lower layer: length = %d", packet_length));
  632. break;
  633. }
  634. eot = *(packet_address++);
  635. remainder_length--;
  636. /*
  637. ** The EOT_BIT is set if this is the last TPDU of the TSDU
  638. */
  639. if ((eot & EOT_BIT) == EOT_BIT)
  640. {
  641. if (Data_Indication_Reassembly_Active == FALSE)
  642. {
  643. /*
  644. ** If the remote site has passed us an empty packet,
  645. ** just return
  646. */
  647. if (remainder_length == 0)
  648. break;
  649. /*
  650. ** If this is a single packet and there aren't any
  651. ** other packets preceeding it, try to send it to the
  652. ** user without copying it into our own buffers
  653. */
  654. if (Data_Indication_Queue.isEmpty())
  655. {
  656. transport_data.logical_handle = m_nLocalLogicalHandle;
  657. transport_data.pbData = packet_address;
  658. transport_data.cbDataSize = remainder_length;
  659. /*
  660. ** Issue the user callback to give the user the data.
  661. */
  662. user_accepted = ::NotifyT120(TRANSPORT_DATA_INDICATION, &transport_data);
  663. /*
  664. ** If the user appliction does NOT accept the packet
  665. ** shutdown the receiver and wait for the user
  666. ** to re-enable it.
  667. */
  668. if (user_accepted == TRANSPORT_NO_ERROR)
  669. break;
  670. else
  671. Shutdown_Receiver = TRUE;
  672. }
  673. /*
  674. ** Put the packet into the DataIndication queue
  675. */
  676. packet = (PTMemory) Data_Indication_Memory_Pool.get ();
  677. packet_error = packet->Append (packet_address, remainder_length);
  678. switch (packet_error)
  679. {
  680. case TMEMORY_NO_ERROR:
  681. Data_Indication_Queue.append ((DWORD_PTR) packet);
  682. break;
  683. case TMEMORY_NONFATAL_ERROR:
  684. case TMEMORY_FATAL_ERROR:
  685. packet_accepted = FALSE;
  686. break;
  687. }
  688. }
  689. else
  690. {
  691. /*
  692. ** Add this PDU to the currently active SDU
  693. */
  694. packet_error = Active_Data_Indication -> Append (
  695. packet_address,
  696. remainder_length);
  697. switch (packet_error)
  698. {
  699. case TMEMORY_NO_ERROR:
  700. Data_Indication_Reassembly_Active = FALSE;
  701. Data_Indication_Queue.append ((DWORD_PTR) Active_Data_Indication);
  702. Active_Data_Indication = NULL;
  703. /*
  704. ** Call PollReceiver (), it will attempt to pass
  705. ** the packet on up to the user.
  706. */
  707. PollReceiver();
  708. break;
  709. case TMEMORY_NONFATAL_ERROR:
  710. case TMEMORY_FATAL_ERROR:
  711. packet_accepted = FALSE;
  712. break;
  713. }
  714. }
  715. }
  716. else
  717. {
  718. /*
  719. ** If the remote site is passing us a zero-length packet,
  720. ** just return
  721. */
  722. if (remainder_length == 0)
  723. break;
  724. /*
  725. ** This is NOT the last packet in the incoming SDU, copy it
  726. ** into the data indication buffer and wait for the next packet
  727. */
  728. if (Data_Indication_Reassembly_Active == FALSE)
  729. {
  730. Data_Indication_Reassembly_Active = TRUE;
  731. Active_Data_Indication = (PTMemory) Data_Indication_Memory_Pool.get ();
  732. }
  733. packet_error = Active_Data_Indication -> Append (
  734. packet_address,
  735. remainder_length);
  736. switch (packet_error)
  737. {
  738. case TMEMORY_NO_ERROR:
  739. break;
  740. case TMEMORY_NONFATAL_ERROR:
  741. case TMEMORY_FATAL_ERROR:
  742. packet_accepted = FALSE;
  743. break;
  744. }
  745. }
  746. break;
  747. default:
  748. ERROR_OUT(("X224: Illegal packet"));
  749. break;
  750. }
  751. if (packet_accepted)
  752. *bytes_accepted = packet_length;
  753. return (PROTOCOL_LAYER_NO_ERROR);
  754. }
  755. /*
  756. * ProtocolLayerError CLayerX224::PollTransmitter (
  757. * ULONG,
  758. * USHORT,
  759. * USHORT * pending_data,
  760. * USHORT *)
  761. *
  762. * Public
  763. *
  764. * Functional Description:
  765. * This function is called periodically to give X224 a chance to transmit
  766. * data.
  767. */
  768. ProtocolLayerError CLayerX224::PollTransmitter (
  769. ULONG_PTR,
  770. USHORT,
  771. USHORT * pending_data,
  772. USHORT *)
  773. {
  774. // TRACE_OUT(("CLayerX224::PollTransmitter"));
  775. LPBYTE packet_address;
  776. ULONG bytes_accepted;
  777. USHORT counter;
  778. USHORT packet_size;
  779. ULONG total_length;
  780. USHORT packet_length;
  781. PMemory memory;
  782. BOOL continue_loop = TRUE;
  783. while (continue_loop)
  784. {
  785. switch (Packet_Pending)
  786. {
  787. case CONNECTION_REQUEST_PACKET:
  788. /*
  789. ** Add up the packet length, don't forget the 1 byte
  790. ** for the Length Indicator
  791. */
  792. total_length =
  793. CONNECT_REQUEST_HEADER_SIZE +
  794. TPDU_ARBITRATION_PACKET_SIZE +
  795. 1 +
  796. Lower_Layer_Prepend +
  797. Lower_Layer_Append;
  798. memory = Data_Request_Memory_Manager -> AllocateMemory (
  799. NULL,
  800. total_length);
  801. if (memory == NULL)
  802. {
  803. continue_loop = FALSE;
  804. break;
  805. }
  806. packet_address = memory -> GetPointer ();
  807. packet_address += Lower_Layer_Prepend;
  808. *(packet_address++) =
  809. CONNECT_REQUEST_HEADER_SIZE +
  810. TPDU_ARBITRATION_PACKET_SIZE;
  811. *(packet_address++) = CONNECTION_REQUEST_PACKET;
  812. /*
  813. ** The following 2 bytes are the destination reference
  814. */
  815. *(packet_address++) = 0;
  816. *(packet_address++) = 0;
  817. *(packet_address++) = (BYTE)(m_nLocalLogicalHandle >> 8);
  818. *(packet_address++) = (BYTE)(m_nLocalLogicalHandle & 0xff);
  819. /*
  820. ** The following byte is the Class/Options
  821. */
  822. *(packet_address++) = 0;
  823. /*
  824. ** Add TPDU arbitration data
  825. */
  826. *(packet_address++) = TPDU_SIZE;
  827. *(packet_address++) = 1;
  828. /*
  829. ** Code our maximum PDU size into the X224 scheme
  830. */
  831. Arbitrated_PDU_Size = Maximum_PDU_Size;
  832. packet_size = Arbitrated_PDU_Size;
  833. counter = 0;
  834. while (packet_size > 1)
  835. {
  836. packet_size >>= 1;
  837. counter++;
  838. }
  839. *(packet_address++) = (unsigned char) counter;
  840. /*
  841. ** Attempt to send the packet to the lower layer
  842. */
  843. m_pQ922->DataRequest(Identifier, memory, &bytes_accepted);
  844. /*
  845. ** We assume that the lower layer has a packet input
  846. ** interface, if it does not, there has been a major error.
  847. */
  848. if (bytes_accepted == total_length)
  849. {
  850. Packet_Pending = TRANSPORT_NO_PACKET;
  851. State = SENT_CONNECT_REQUEST_PACKET;
  852. }
  853. else
  854. continue_loop = FALSE;
  855. Data_Request_Memory_Manager -> FreeMemory (memory);
  856. break;
  857. case CONNECTION_CONFIRM_PACKET:
  858. packet_length = CONNECT_CONFIRM_HEADER_SIZE;
  859. if (Packet_Size_Respond)
  860. packet_length += TPDU_ARBITRATION_PACKET_SIZE;
  861. total_length = packet_length +
  862. 1 +
  863. Lower_Layer_Prepend +
  864. Lower_Layer_Append;
  865. memory = Data_Request_Memory_Manager -> AllocateMemory (
  866. NULL,
  867. total_length);
  868. if (memory == NULL)
  869. {
  870. continue_loop = FALSE;
  871. break;
  872. }
  873. packet_address = memory -> GetPointer ();
  874. packet_address += Lower_Layer_Prepend;
  875. /*
  876. ** Build the packet
  877. */
  878. *(packet_address++) = (UChar) packet_length;
  879. *(packet_address++) = CONNECTION_CONFIRM_PACKET;
  880. *(packet_address++) = (BYTE)(m_nRemoteLogicalHandle >> 8);
  881. *(packet_address++) = (BYTE)(m_nRemoteLogicalHandle & 0xff);
  882. *(packet_address++) = (BYTE)(m_nLocalLogicalHandle >> 8);
  883. *(packet_address++) = (BYTE)(m_nLocalLogicalHandle & 0xff);
  884. /*
  885. ** Set the Class/Options to 0
  886. */
  887. *(packet_address++) = 0;
  888. /*
  889. ** Packet_Size_Respond is TRUE if we are suppose to respond
  890. ** to the TPDU element in the Connect Request packet
  891. */
  892. if (Packet_Size_Respond)
  893. {
  894. /*
  895. ** Add TPDU arbitration data
  896. */
  897. *(packet_address++) = TPDU_SIZE;
  898. *(packet_address++) = 1;
  899. packet_size = Arbitrated_PDU_Size;
  900. counter = 0;
  901. while (packet_size > 1)
  902. {
  903. packet_size >>= 1;
  904. counter++;
  905. }
  906. *(packet_address++) = (unsigned char) counter;
  907. }
  908. /*
  909. ** Attempt to send the packet to the lower layer
  910. */
  911. m_pQ922->DataRequest(Identifier, memory, &bytes_accepted);
  912. if (bytes_accepted == total_length)
  913. {
  914. Packet_Pending = TRANSPORT_NO_PACKET;
  915. State = CONNECTION_ACTIVE;
  916. }
  917. else
  918. continue_loop = FALSE;
  919. Data_Request_Memory_Manager -> FreeMemory (memory);
  920. break;
  921. case DISCONNECT_REQUEST_PACKET:
  922. /*
  923. ** Add 1 to the length for the Length Indicator
  924. */
  925. total_length = DISCONNECT_REQUEST_HEADER_SIZE +
  926. 1 +
  927. Lower_Layer_Prepend +
  928. Lower_Layer_Append;
  929. memory = Data_Request_Memory_Manager -> AllocateMemory (
  930. NULL,
  931. total_length);
  932. if (memory == NULL)
  933. {
  934. continue_loop = FALSE;
  935. break;
  936. }
  937. packet_address = memory -> GetPointer ();
  938. packet_address += Lower_Layer_Prepend;
  939. TRACE_OUT(("X224: Sending Disconnect Request Packet"));
  940. *(packet_address++) = DISCONNECT_REQUEST_HEADER_SIZE;
  941. *(packet_address++) = DISCONNECT_REQUEST_PACKET;
  942. *(packet_address++) = (BYTE)(m_nRemoteLogicalHandle >> 8);
  943. *(packet_address++) = (BYTE)(m_nRemoteLogicalHandle & 0xff);
  944. /*
  945. ** Set the source reference to 0, this packet will only
  946. ** be sent as a refusal to a Connect Request, therefore
  947. ** this value should be 0
  948. */
  949. *(packet_address++) = 0;
  950. *(packet_address++) = 0;
  951. *(packet_address++) = DISCONNECT_REASON_NOT_SPECIFIED;
  952. /*
  953. ** Attempt to send packet to lower layer
  954. */
  955. m_pQ922->DataRequest(Identifier, memory, &bytes_accepted);
  956. if (bytes_accepted == total_length)
  957. {
  958. Packet_Pending = TRANSPORT_NO_PACKET;
  959. State = SENT_DISCONNECT_REQUEST_PACKET;
  960. }
  961. continue_loop = FALSE;
  962. Data_Request_Memory_Manager -> FreeMemory (memory);
  963. break;
  964. case ERROR_PACKET:
  965. TRACE_OUT(("X224: Sending Error Packet"));
  966. total_length = ERROR_HEADER_SIZE +
  967. Error_Buffer_Length +
  968. 1 +
  969. 2 +
  970. Lower_Layer_Prepend +
  971. Lower_Layer_Append;
  972. memory = Data_Request_Memory_Manager -> AllocateMemory (
  973. NULL,
  974. total_length);
  975. if (memory == NULL)
  976. {
  977. continue_loop = FALSE;
  978. break;
  979. }
  980. packet_address = memory -> GetPointer ();
  981. packet_address += Lower_Layer_Prepend;
  982. *(packet_address++) =
  983. ERROR_HEADER_SIZE + Error_Buffer_Length;
  984. *(packet_address++) = ERROR_PACKET;
  985. *(packet_address++) = (BYTE)(m_nRemoteLogicalHandle >> 8);
  986. *(packet_address++) = (BYTE)(m_nRemoteLogicalHandle & 0xff);
  987. *(packet_address++) = Reject_Cause;
  988. *(packet_address++) = INVALID_TPDU;
  989. *(packet_address++) = (UChar) Error_Buffer_Length;
  990. memcpy (packet_address, Error_Buffer, Error_Buffer_Length);
  991. /*
  992. ** Attempt to send packet to lower layer
  993. */
  994. m_pQ922->DataRequest(Identifier, memory, &bytes_accepted);
  995. if (bytes_accepted == total_length)
  996. {
  997. delete [] Error_Buffer;
  998. Error_Buffer = NULL;
  999. Packet_Pending = TRANSPORT_NO_PACKET;
  1000. State = SENT_CONNECT_REQUEST_PACKET;
  1001. }
  1002. else
  1003. continue_loop = FALSE;
  1004. Data_Request_Memory_Manager -> FreeMemory (memory);
  1005. break;
  1006. case TRANSPORT_NO_PACKET:
  1007. if (Data_Request_Queue.isEmpty() == FALSE)
  1008. {
  1009. /*
  1010. ** Get the next packet from the queue
  1011. */
  1012. memory = (PMemory) Data_Request_Queue.read ();
  1013. total_length = memory -> GetLength ();
  1014. m_pQ922->DataRequest(Identifier, memory, &bytes_accepted);
  1015. if (bytes_accepted == total_length)
  1016. {
  1017. Data_Request_Queue.get ();
  1018. Data_Request_Memory_Manager -> FreeMemory (memory);
  1019. }
  1020. else
  1021. continue_loop = FALSE;
  1022. }
  1023. else
  1024. continue_loop = FALSE;
  1025. break;
  1026. }
  1027. }
  1028. if (Data_Request_Queue.isEmpty())
  1029. *pending_data = 0;
  1030. else
  1031. *pending_data = PROTOCOL_USER_DATA;
  1032. return (PROTOCOL_LAYER_NO_ERROR);
  1033. }
  1034. /*
  1035. * TransportError CLayerX224::DataRequest (
  1036. * ULONG,
  1037. * LPBYTE packet_address,
  1038. * USHORT packet_length,
  1039. * USHORT * bytes_accepted)
  1040. *
  1041. * Public
  1042. *
  1043. * Functional Description:
  1044. * This function takes a packet from the user and queues it for
  1045. * transmission.
  1046. */
  1047. ProtocolLayerError CLayerX224::DataRequest (
  1048. ULONG_PTR,
  1049. LPBYTE packet_address,
  1050. ULONG packet_length,
  1051. PULong bytes_accepted)
  1052. {
  1053. TRACE_OUT(("CLayerX224::DataRequest"));
  1054. ULONG total_packet_size;
  1055. ULONG packet_size;
  1056. DataRequestQueue temporary_queue;
  1057. PMemory memory;
  1058. BOOL packet_failed = FALSE;
  1059. LPBYTE address;
  1060. *bytes_accepted = 0;
  1061. if (Shutdown_Transmitter)
  1062. return (PROTOCOL_LAYER_NO_ERROR);
  1063. total_packet_size = packet_length;
  1064. /*
  1065. ** Create enough PDUs to hold the packet. We don't actually copy the
  1066. ** packet into the new buffers until we know that we can get enough
  1067. ** space.
  1068. */
  1069. while (total_packet_size != 0)
  1070. {
  1071. if (total_packet_size >
  1072. (ULONG) (Arbitrated_PDU_Size - DATA_PACKET_HEADER_SIZE))
  1073. {
  1074. packet_size = Arbitrated_PDU_Size - DATA_PACKET_HEADER_SIZE;
  1075. }
  1076. else
  1077. packet_size = total_packet_size;
  1078. total_packet_size -= packet_size;
  1079. memory = Data_Request_Memory_Manager -> AllocateMemory (
  1080. NULL,
  1081. packet_size +
  1082. DATA_PACKET_HEADER_SIZE +
  1083. Lower_Layer_Prepend +
  1084. Lower_Layer_Append);
  1085. if (memory == NULL)
  1086. {
  1087. packet_failed = TRUE;
  1088. break;
  1089. }
  1090. temporary_queue.append ((DWORD_PTR) memory);
  1091. }
  1092. /*
  1093. ** If we were unable to allocate memory for the packet, release the memory
  1094. ** that we did allocate.
  1095. */
  1096. if (packet_failed)
  1097. {
  1098. temporary_queue.reset();
  1099. while (temporary_queue.iterate ((PDWORD_PTR) &memory))
  1100. {
  1101. Data_Request_Memory_Manager->FreeMemory (memory);
  1102. }
  1103. /*
  1104. ** Set the User_Data_Pending flag to the packet_length so we can
  1105. ** notify the user when buffer space is available.
  1106. */
  1107. User_Data_Pending = packet_length;
  1108. }
  1109. else
  1110. {
  1111. User_Data_Pending = 0;
  1112. total_packet_size = packet_length;
  1113. /*
  1114. ** Go thru each of the PDUs and actually create them.
  1115. */
  1116. temporary_queue.reset();
  1117. while (temporary_queue.iterate ((PDWORD_PTR) &memory))
  1118. {
  1119. if (total_packet_size >
  1120. (ULONG) (Arbitrated_PDU_Size - DATA_PACKET_HEADER_SIZE))
  1121. {
  1122. packet_size = Arbitrated_PDU_Size - DATA_PACKET_HEADER_SIZE;
  1123. }
  1124. else
  1125. packet_size = total_packet_size;
  1126. address = memory -> GetPointer ();
  1127. memcpy (
  1128. address + DATA_PACKET_HEADER_SIZE + Lower_Layer_Prepend,
  1129. packet_address + (USHORT) (packet_length - total_packet_size),
  1130. packet_size);
  1131. total_packet_size -= packet_size;
  1132. /*
  1133. ** This is the header for a data packet
  1134. */
  1135. address += Lower_Layer_Prepend;
  1136. *address = 2;
  1137. *(address + 1) = DATA_PACKET;
  1138. if (total_packet_size == 0)
  1139. *(address + 2) = EOT_BIT;
  1140. else
  1141. *(address + 2) = 0;
  1142. /*
  1143. ** Load the memory object into the queue
  1144. */
  1145. Data_Request_Queue.append ((DWORD_PTR) memory);
  1146. }
  1147. *bytes_accepted = packet_length;
  1148. }
  1149. return (PROTOCOL_LAYER_NO_ERROR);
  1150. }
  1151. /*
  1152. * ProtocolLayerError CLayerX224::DataRequest (
  1153. * ULONG,
  1154. * PMemory,
  1155. * USHORT * bytes_accepted)
  1156. *
  1157. * Public
  1158. *
  1159. * Functional Description:
  1160. * This function takes a packet from the user and queues it for
  1161. * transmission.
  1162. */
  1163. ProtocolLayerError CLayerX224::DataRequest (
  1164. ULONG_PTR,
  1165. PMemory,
  1166. PULong bytes_accepted)
  1167. {
  1168. *bytes_accepted = 0;
  1169. return (PROTOCOL_LAYER_ERROR);
  1170. }
  1171. /*
  1172. * ProtocolLayerError CLayerX224::PollReceiver (
  1173. * ULONG)
  1174. *
  1175. * Public
  1176. *
  1177. * Functional Description:
  1178. * This function should be called periodically to allow us to send received
  1179. * packets to the user.
  1180. */
  1181. ProtocolLayerError CLayerX224::PollReceiver(void)
  1182. {
  1183. // TRACE_OUT(("CLayerX224::PollReceiver"));
  1184. LegacyTransportData transport_data;
  1185. ULONG packet_accepted;
  1186. PTMemory packet;
  1187. HPUChar packet_address;
  1188. ULONG packet_length;
  1189. if (Shutdown_Receiver)
  1190. return (PROTOCOL_LAYER_NO_ERROR);
  1191. /*
  1192. ** If I have any packets in my receive buffers that
  1193. ** need to go to higher layers, do it now
  1194. */
  1195. while (Data_Indication_Queue.isEmpty () == FALSE)
  1196. {
  1197. packet = (PTMemory) Data_Indication_Queue.read ();
  1198. packet -> GetMemory (
  1199. &packet_address,
  1200. &packet_length);
  1201. transport_data.logical_handle = m_nLocalLogicalHandle;
  1202. transport_data.pbData = (LPBYTE) packet_address;
  1203. transport_data.cbDataSize = packet_length;
  1204. packet_accepted = ::NotifyT120(TRANSPORT_DATA_INDICATION, &transport_data);
  1205. /*
  1206. ** If the user returns anything but TRANSPORT_NO_ERROR, it could not
  1207. ** accept the packet. We will try to send the packet again later.
  1208. */
  1209. if (packet_accepted == TRANSPORT_NO_ERROR)
  1210. {
  1211. Data_Indication_Queue.get ();
  1212. packet -> Reset ();
  1213. Data_Indication_Memory_Pool.append ((DWORD_PTR) packet);
  1214. }
  1215. else
  1216. {
  1217. /*
  1218. ** If the user appliction does NOT accept the packet
  1219. ** shutdown the receiver and wait for the user to re-enable it.
  1220. */
  1221. Shutdown_Receiver = TRUE;
  1222. break;
  1223. }
  1224. }
  1225. return (PROTOCOL_LAYER_NO_ERROR);
  1226. }
  1227. /*
  1228. * ProtocolLayerError CLayerX224::GetParameters (
  1229. * ULONG,
  1230. * USHORT * packet_size)
  1231. *
  1232. * Public
  1233. *
  1234. * Functional Description:
  1235. * This function returns the maximum allowable TSDU.
  1236. */
  1237. ProtocolLayerError CLayerX224::GetParameters (
  1238. USHORT *,
  1239. USHORT *,
  1240. USHORT *)
  1241. {
  1242. return (PROTOCOL_LAYER_NO_ERROR);
  1243. }
  1244. /*
  1245. * ProtocolLayerError CLayerX224::RegisterHigherLayer (
  1246. * ULONG,
  1247. * PMemoryManager,
  1248. * IProtocolLayer *)
  1249. *
  1250. * Public
  1251. *
  1252. * Functional Description:
  1253. * This function does nothing. The only reason it is here is because this
  1254. * class inherits from ProtocolLayer and this function is pure virtual in
  1255. * that class.
  1256. */
  1257. ProtocolLayerError CLayerX224::RegisterHigherLayer (
  1258. ULONG_PTR,
  1259. PMemoryManager,
  1260. IProtocolLayer *)
  1261. {
  1262. return (PROTOCOL_LAYER_REGISTRATION_ERROR);
  1263. }
  1264. /*
  1265. * ProtocolLayerError CLayerX224::RemoveHigherLayer (
  1266. * ULONG)
  1267. *
  1268. * Public
  1269. *
  1270. * Functional Description:
  1271. * This function does nothing. The only reason it is here is because this
  1272. * class inherits from ProtocolLayer and this function is pure virtual in
  1273. * that class.
  1274. */
  1275. ProtocolLayerError CLayerX224::RemoveHigherLayer (
  1276. ULONG_PTR)
  1277. {
  1278. return (PROTOCOL_LAYER_REGISTRATION_ERROR);
  1279. }
  1280. /*
  1281. * BOOL CLayerX224::AllocateBuffers ()
  1282. *
  1283. * Functional Description
  1284. * This function allocates the data request and data indication buffers.
  1285. * and sets up the memory pools necessary. It also sets up the Control
  1286. * buffer for control packets.
  1287. *
  1288. * Formal Parameters
  1289. * None
  1290. *
  1291. * Return Value
  1292. * None.
  1293. *
  1294. * Side Effects
  1295. * None
  1296. *
  1297. * Caveats
  1298. * None
  1299. */
  1300. BOOL CLayerX224::AllocateBuffers ()
  1301. {
  1302. TRACE_OUT(("CLayerX224::AllocateBuffers"));
  1303. PTMemory packet;
  1304. USHORT i;
  1305. ULONG total_packet_size;
  1306. TMemoryError error;
  1307. total_packet_size = MAXIMUM_USER_DATA_SIZE;
  1308. for (i=0; i<Data_Indication_Queue_Size; i++)
  1309. {
  1310. DBG_SAVE_FILE_LINE
  1311. packet = new TMemory (
  1312. total_packet_size,
  1313. 0,
  1314. &error);
  1315. if (error == TMEMORY_NO_ERROR)
  1316. Data_Indication_Memory_Pool.append ((DWORD_PTR) packet);
  1317. else
  1318. {
  1319. delete packet;
  1320. return (FALSE);
  1321. }
  1322. }
  1323. return (TRUE);
  1324. }
  1325. /*
  1326. * void CLayerX224::ErrorPacket (
  1327. * LPBYTE packet_address,
  1328. * USHORT packet_length)
  1329. *
  1330. * Functional Description
  1331. * This function stores the packet into our own error buffer and prepares
  1332. * to send it out
  1333. *
  1334. * Formal Parameters
  1335. * None
  1336. *
  1337. * Return Value
  1338. * None.
  1339. *
  1340. * Side Effects
  1341. * None
  1342. *
  1343. * Caveats
  1344. * None
  1345. */
  1346. void CLayerX224::ErrorPacket (
  1347. LPBYTE packet_address,
  1348. USHORT packet_length)
  1349. {
  1350. TRACE_OUT(("CLayerX224::ErrorPacket"));
  1351. DBG_SAVE_FILE_LINE
  1352. Error_Buffer = new BYTE[packet_length];
  1353. if (NULL != Error_Buffer)
  1354. {
  1355. Error_Buffer_Length = packet_length;
  1356. memcpy (Error_Buffer, packet_address, packet_length);
  1357. Packet_Pending = ERROR_PACKET;
  1358. }
  1359. }
  1360. /*
  1361. * void CLayerX224::CheckUserBuffers ()
  1362. *
  1363. * Public
  1364. *
  1365. * Functional Description:
  1366. * This function issues TRANSPORT_BUFFER_AVAILABLE_INDICATIONs to the
  1367. * user if available.
  1368. */
  1369. void CLayerX224::CheckUserBuffers ()
  1370. {
  1371. // TRACE_OUT(("CLayerX224::CheckUserBuffers"));
  1372. ULONG user_data_size;
  1373. ULONG buffer_size;
  1374. ULONG full_size_buffers_needed;
  1375. ULONG full_size_buffer_count;
  1376. ULONG partial_buffer_size;
  1377. ULONG partial_buffer_count;
  1378. if (User_Data_Pending == 0)
  1379. return;
  1380. /*
  1381. ** Determine the user data size in a packet, then determine
  1382. ** how many buffers will be needed to accept that packet.
  1383. */
  1384. user_data_size = Arbitrated_PDU_Size - DATA_PACKET_HEADER_SIZE;
  1385. full_size_buffers_needed = User_Data_Pending / user_data_size;
  1386. /*
  1387. ** Find out how many full size buffers are available
  1388. */
  1389. if (full_size_buffers_needed != 0)
  1390. {
  1391. /*
  1392. ** Increment full_size_buffers_needed to account for our priority
  1393. ** value.
  1394. */
  1395. buffer_size =
  1396. Arbitrated_PDU_Size + Lower_Layer_Prepend + Lower_Layer_Append;
  1397. full_size_buffer_count = Data_Request_Memory_Manager ->
  1398. GetBufferCount (buffer_size);
  1399. if (full_size_buffer_count < full_size_buffers_needed)
  1400. return;
  1401. }
  1402. partial_buffer_size = User_Data_Pending % user_data_size;
  1403. if (partial_buffer_size != 0)
  1404. {
  1405. if ((full_size_buffers_needed == 0) ||
  1406. (full_size_buffer_count == full_size_buffers_needed))
  1407. {
  1408. buffer_size = partial_buffer_size +
  1409. DATA_PACKET_HEADER_SIZE +
  1410. Lower_Layer_Prepend +
  1411. Lower_Layer_Append;
  1412. partial_buffer_count = Data_Request_Memory_Manager ->
  1413. GetBufferCount (buffer_size);
  1414. if (full_size_buffers_needed == 0)
  1415. {
  1416. if (partial_buffer_count == 0)
  1417. return;
  1418. }
  1419. else
  1420. {
  1421. if ((partial_buffer_count == full_size_buffer_count) ||
  1422. (partial_buffer_count == 0))
  1423. {
  1424. return;
  1425. }
  1426. }
  1427. }
  1428. }
  1429. User_Data_Pending = 0;
  1430. ::NotifyT120(TRANSPORT_BUFFER_EMPTY_INDICATION, (void *) m_nLocalLogicalHandle);
  1431. return;
  1432. }
  1433. /*
  1434. * static ULONG CLayerX224::GetMaxTPDUSize (
  1435. * ULONG max_lower_layer_pdu)
  1436. *
  1437. * Public
  1438. *
  1439. * Functional Description:
  1440. * This function accepts a value for the lower layer max. PDU size
  1441. * and returns the max. PDU size that this Transport can support
  1442. * based on it. X224 only suports max PDU sizes of 128, 256, 512,
  1443. * 1024, and 2048. So, if the max_lower_layer_pdu is 260, the
  1444. * Transport can only have a max pdu size of 256.
  1445. */
  1446. ULONG CLayerX224::GetMaxTPDUSize (
  1447. ULONG max_lower_layer_pdu)
  1448. {
  1449. TRACE_OUT(("CLayerX224::GetMaxTPDUSize"));
  1450. ULONG max_tpdu_size;
  1451. if (max_lower_layer_pdu < 256)
  1452. max_tpdu_size = 128;
  1453. else if (max_lower_layer_pdu < 512)
  1454. max_tpdu_size = 256;
  1455. else if (max_lower_layer_pdu < 1024)
  1456. max_tpdu_size = 512;
  1457. else if (max_lower_layer_pdu < 2048)
  1458. max_tpdu_size = 1024;
  1459. else
  1460. max_tpdu_size = 2048;
  1461. return (max_tpdu_size);
  1462. }
  1463.